def laske(lauseke,m={},funktiot={}): """ Laskee lauseen mikäli se on laskettavissa. Käyttää muuttujista loytyvia arvoja, seka funktioita. """ # Määritetään numeroluokka eli vakiona lasketaan desimaaliluvuilla: f = { "num" : DictDecimal } f.update(funktiot) f.update(pfunktiot) f.update(lfunktiot) f=dictToMathDict(f) log.logString( "<h4> Laskenta: </h4>" ) log.logString( u"Tehtävän lause = " + lauseke ) # Poistetaan välilyonnit ja enterit: lause = lauseke.replace('\n','') lause = lause.replace('\r','') lause = lause.replace(' ','') # Poistetaan "-0" termit lause=re.sub(r"([-][0](?![0-9.]))",r"",lause) # Korvataan funktiot # Vakionumerot numeroinstansseiksi: oper=r"-+*/(,[<>=" num = "-?\d+([.]\d+)?" lause=re.sub(r"((?<![^"+oper+"])"+num+")(?=["+oper+"]|$|\]|\))",r"num('\g<1>')",lause) #lause=re.sub(r"((?<![^-+*/(,[])-?\d+([.]\d+)?)(?![\.0-9])",r"num('\g<1>')",lause) # Korvataan muuttujien nimet oikeilla muuttujilla: lause=re.sub(r"\.([a-zA-Z_]\w*)(?=\.)",r"['\g<1>']",lause) # .x. -> [x]. lause=re.sub(r"\.([a-zA-Z_]+[a-zA-Z_0-9]*)",r"['\g<1>']",lause) # .x -> [x] lause=re.sub(r"\.(\d+)(?=["+oper+"]|$|\]|\))",r"['\g<1>']",lause) # .n -> [n] lause=re.sub(r"(?<=["+oper+r"])([a-zA-Z_0-9]\w*(?=[[]))",r"m['\g<1>']",lause) # x[ -> m[x][ # Korvataan yksinäiset muuttujat (lähinnä funktioita): lause=re.sub(r"([a-zA-Z_][a-zA-Z_0-9]*(?![a-zA-Z_0-9.(]|[[']))",r"m['\g<1>']",lause) # x -> m[x] lause=re.sub(r"([a-zA-Z_][a-zA-Z_0-9]*(?![a-zA-Z_0-9.]|[[']))",r"f['\g<1>']",lause) # x( -> f[x]( tulos=None # lasketaan tulos: if settings.DEBUG: try: tulos = eval(lause) except KeyError : tulos = "S" # Syottämättomiä muuttujia except TypeError : tulos= None else : try: tulos = eval(lause) # Poikkeukset laskuille joita ei pysty laskemaan. # Pyrkii estämaan ettei koko paska kaadu virheissä. except DivisionByZero : tulos= None except KeyError : tulos= "S" # Syottämättomiä muuttujia except TypeError : tulos= None except SyntaxError: tulos= None except NameError : tulos= None except : tulos= None try : log.logString( "laskettu tulos= " + str(tulos.quantize(Decimal('0.1'),rounding=ROUND_HALF_UP )) ) except : log.logString( "laskettu tulos= " + str(tulos) ) if type(tulos)==DictDecimal : tulos= Decimal(tulos) return tulos
def luoOsatehtavanKaava(ot_lause,parametrit): """ paremtrit ovat sanakirja[parametrin nimi]=arvo Luo yhden puhtaan kaavan jolla osatehtävän tulokset lasketaan. -Sijoittaa parametrit -Toteuttaa muk -> ..mukana pikatien -Muuntaa suor pikatien kaikkien vartioiden suorituksiin parametristä vartion_kaava """ ot_lause #=ot.kaava #.lower() log.logString( " kaava = " + ot_lause ) korvautuu=True log.logString( u" Parametrit: " ) for p_nimi,p_arvo in parametrit.items(): log.logString( " " + p_nimi +"= " + p_arvo ) # Korvataan parametrit while korvautuu: korvautuu=False vanha=ot_lause for p_nimi,p_arvo in parametrit.items(): ot_lause=re.sub(p_nimi+r"(?!\w+)",p_arvo,ot_lause) # Pikatie "muk" -> "..mukana" ot_lause=re.sub("muk"+r"(?!\w+)","..mukana",ot_lause) # Muunnos "suor" -> kaikkien vartioiden lasketut suoritukset try: vartion_kaava=parametrit["vartion_kaava"] #.filter(nimi="vartion_kaava")[0].arvo #vartion_kaava=re.sub("vartio"+r"(?!\w+)", str(v.nro) ,vartion_kaava) for p_nimi,p_arvo in parametrit.items() : vartion_kaava=re.sub(p_nimi+r"(?!\w+)",p_arvo,vartion_kaava) ot_lause=re.sub("suor"+r"(?!\w+)",suoritusJoukko(vartion_kaava),ot_lause) except IndexError: pass except KeyError: pass if not ot_lause==vanha : korvautuu=True return ot_lause
def luoOsatehtavanKaava(ot_lause, parametrit): """ paremtrit ovat sanakirja[parametrin nimi]=arvo Luo yhden puhtaan kaavan jolla osatehtävän tulokset lasketaan. -Sijoittaa parametrit -Toteuttaa muk -> ..mukana pikatien -Muuntaa suor pikatien kaikkien vartioiden suorituksiin parametristä vartion_kaava """ ot_lause #=ot.kaava #.lower() log.logString(" kaava = " + ot_lause) korvautuu = True log.logString(u" Parametrit: ") for p_nimi, p_arvo in parametrit.items(): log.logString(" " + p_nimi + "= " + p_arvo) # Korvataan parametrit while korvautuu: korvautuu = False vanha = ot_lause for p_nimi, p_arvo in parametrit.items(): ot_lause = re.sub(p_nimi + r"(?!\w+)", p_arvo, ot_lause) # Pikatie "muk" -> "..mukana" ot_lause = re.sub("muk" + r"(?!\w+)", "..mukana", ot_lause) # Muunnos "suor" -> kaikkien vartioiden lasketut suoritukset try: vartion_kaava = parametrit[ "vartion_kaava"] #.filter(nimi="vartion_kaava")[0].arvo #vartion_kaava=re.sub("vartio"+r"(?!\w+)", str(v.nro) ,vartion_kaava) for p_nimi, p_arvo in parametrit.items(): vartion_kaava = re.sub(p_nimi + r"(?!\w+)", p_arvo, vartion_kaava) ot_lause = re.sub("suor" + r"(?!\w+)", suoritusJoukko(vartion_kaava), ot_lause) except IndexError: pass except KeyError: pass if not ot_lause == vanha: korvautuu = True return ot_lause
def laske(lauseke, m={}, funktiot={}): """ Laskee lauseen mikäli se on laskettavissa. Käyttää muuttujista loytyvia arvoja, seka funktioita. """ # Määritetään numeroluokka eli vakiona lasketaan desimaaliluvuilla: f = {"num": DictDecimal} f.update(funktiot) f.update(pfunktiot) f.update(lfunktiot) f = dictToMathDict(f) log.logString("<h4> Laskenta: </h4>") log.logString(u"Tehtävän lause = " + lauseke) # Poistetaan välilyonnit ja enterit: lause = lauseke.replace('\n', '') lause = lause.replace('\r', '') lause = lause.replace(' ', '') # Poistetaan "-0" termit lause = re.sub(r"([-][0](?![0-9.]))", r"", lause) # Korvataan funktiot # Vakionumerot numeroinstansseiksi: oper = r"-+*/(,[<>=" num = "-?\d+([.]\d+)?" lause = re.sub( r"((?<![^" + oper + "])" + num + ")(?=[" + oper + "]|$|\]|\))", r"num('\g<1>')", lause) #lause=re.sub(r"((?<![^-+*/(,[])-?\d+([.]\d+)?)(?![\.0-9])",r"num('\g<1>')",lause) # Korvataan muuttujien nimet oikeilla muuttujilla: lause = re.sub(r"\.([a-zA-Z_]\w*)(?=\.)", r"['\g<1>']", lause) # .x. -> [x]. lause = re.sub(r"\.([a-zA-Z_]+[a-zA-Z_0-9]*)", r"['\g<1>']", lause) # .x -> [x] lause = re.sub(r"\.(\d+)(?=[" + oper + "]|$|\]|\))", r"['\g<1>']", lause) # .n -> [n] lause = re.sub(r"(?<=[" + oper + r"])([a-zA-Z_0-9]\w*(?=[[]))", r"m['\g<1>']", lause) # x[ -> m[x][ # Korvataan yksinäiset muuttujat (lähinnä funktioita): lause = re.sub(r"([a-zA-Z_][a-zA-Z_0-9]*(?![a-zA-Z_0-9.(]|[[']))", r"m['\g<1>']", lause) # x -> m[x] lause = re.sub(r"([a-zA-Z_][a-zA-Z_0-9]*(?![a-zA-Z_0-9.]|[[']))", r"f['\g<1>']", lause) # x( -> f[x]( tulos = None # lasketaan tulos: if settings.DEBUG: try: tulos = eval(lause) except KeyError: tulos = "S" # Syottämättomiä muuttujia except TypeError: tulos = None else: try: tulos = eval(lause) # Poikkeukset laskuille joita ei pysty laskemaan. # Pyrkii estämaan ettei koko paska kaadu virheissä. except DivisionByZero: tulos = None except KeyError: tulos = "S" # Syottämättomiä muuttujia except TypeError: tulos = None except SyntaxError: tulos = None except NameError: tulos = None except: tulos = None try: log.logString( "laskettu tulos= " + str(tulos.quantize(Decimal('0.1'), rounding=ROUND_HALF_UP))) except: log.logString("laskettu tulos= " + str(tulos)) if type(tulos) == DictDecimal: tulos = Decimal(tulos) return tulos
def laskeSarja(sarja, syotteet, vartiot=None, tehtavat=None): """ Laskee tulokset halutulle sarjalle. Palauttaa kaksiuloitteisen taulukon[vartio][tehtävä] = pisteet. Taulukon ensimmäisissä sarakkeissa on vartio tai tehtävä objekteja muissa pisteitä. Taulukon vasemmassa ylänurkassa on sarjan objekti """ #syotteetr=Syote.objects.all() #(maarite__osa_tehtava__tehtava__sarja=sarja ) if not vartiot: vartiot = sarja.vartio_set.all() if not tehtavat: tehtavat = sarja.tehtava_set.all() if vartiot and tehtavat: jee = 1 # Pakotetaan tietokantahaku. #Lasketaan tulokset: muuttujat = luoMuuttujat(sarja.vartio_set.all(), tehtavat, syotteet) laskut = luoLaskut(vartiot, tehtavat) tulokset = laskeTaulukko(laskut, muuttujat) #Muokataan oikean muotoinen tulostaulukko: siirrettavat = [] for i in range(len(vartiot)): # Merkataan tuloksiin H hylättyihin tehtäviin: for t in range(len(tulokset[i])): hylatty = True tekematta = False tehtSyotteet = syotteet.filter( maarite__osa_tehtava__tehtava=tehtavat[t]).filter( vartio=vartiot[i]) #syotteet= vartiot[i].syote_set.filter(maarite__osa_tehtava__tehtava=tehtavat[t]) for s in tehtSyotteet: if s.arvo == "e": tekematta = True if not s.arvo == "h": hylatty = False if hylatty and len(tehtSyotteet): tulokset[i][t] = "H" if tekematta: tulokset[i][t] = "E" #Merkataan siirrettäviksi ulkopuolella olevat: if not vartiot[i].keskeyttanyt == None or not vartiot[ i].ulkopuolella == None: #Merkataan keskeyttaneille tuloksiin "K" keskeyttämisestä eteenpäin if not vartiot[i].keskeyttanyt == None: kesk = vartiot[i].keskeyttanyt - 1 for t in range(kesk, len(tulokset[i])): tulokset[i][t] = "K" siirrettavat.append(i) #Tuomarineuvosto: vartion_tuomarit = vartiot[i].tuomarineuvostulos_set.all() if len(vartion_tuomarit): for t in range(len(tulokset[i])): tuom = vartion_tuomarit.filter(tehtava=tehtavat[t]) if len(tuom): log.logString(u"Tuomarineuvoston ylimääritys: " + str(tuom[0].pisteet)) try: tulokset[i][t] = Decimal(tuom[0].pisteet) except: tulokset[i][t] = tuom[0].pisteet # Lisää varoitus, jos vartion pisteet ylittävät tehtävän max. pisteet for t in range(len(tulokset[i])): pisteet = tulokset[i][t] # Tarkistetaan, että pisteet on laskettu (numeerinen arvo). # Vartion pisteet voivat olla myös esim. H, E tai K (katso # silmukka vähän ylempää), tällöin tarkistus on turha. if (pisteet and type(pisteet) != str and type(pisteet) != unicode and tehtavat[t].maksimipisteet != ''): # Onko pisteet > max pisteet if pisteet > float(tehtavat[t].maksimipisteet): # Lisää huomautus tulosluetteloon tulokset[i][t] = str(tulokset[i][t]) + " (?)" #Kokonaispisteet: summa = 0 for s in tulokset[i]: if s and type(s) != str and type(s) != unicode: summa += s tulokset[i].insert(0, summa) #Vartio objekti jokaisen rivin alkuun: tulokset[i].insert(0, vartiot[i]) # Kirjataan välivaiheisiin lopputulos try: log.logString("\n<b>TULOS = " + str(tulokset[0][2]) + "</b>") except: pass # Siirretään ulkopuoliset ja mukana olevat omiin taulukkoihinsa mukana = [] ulkona = [] for i, item in enumerate(tulokset): u = False for s in siirrettavat: if s == i: u = True if u: ulkona.append(item) else: mukana.append(item) tulokset = mukana #Lisätään tehtävärivi ylös t_list = [ sarja, "Yht.", ] pisteet_yhteensa = 0 for t in tehtavat: try: if int(t.maksimipisteet): pisteet_yhteensa += int(t.maksimipisteet) except: pass t_list.append(t) t_list[0].maksimipisteet = pisteet_yhteensa #Tasapisteissä määräävät tehtävät tasa1 = 0 tasa2 = 0 tasa3 = 0 if sarja.tasapiste_teht1: tasa1 = sarja.tasapiste_teht1 + 1 if sarja.tasapiste_teht2: tasa2 = sarja.tasapiste_teht2 + 1 if sarja.tasapiste_teht2: tasa3 = sarja.tasapiste_teht3 + 1 tulokset.sort(key=operator.itemgetter(1), reverse=True) ulkona.sort(key=operator.itemgetter(1), reverse=True) #Järjestetään taulukot try: tulokset.sort(key=operator.itemgetter(1, tasa1, tasa2, tasa3), reverse=True) ulkona.sort(key=operator.itemgetter(1, tasa1, tasa2, tasa3), reverse=True) except: # tehtäviä < 3 pass # Etsitään tasapistetulokset : edellinen = None for vi, vartio in enumerate(ulkona): vartio[0].tasa = '' # merkitään tasatulos if edellinen and vartio[1] == edellinen[1]: ulkona[vi][0].tasa = '!' # merkitään tasatulos ulkona[vi - 1][0].tasa = '!' # merkitään tasatulos edellinen = vartio edellinen = None for vi, vartio in enumerate(mukana): vartio[0].tasa = '' # merkitään tasatulos if edellinen and vartio[1] == edellinen[1]: tulokset[vi][0].tasa = '!' # merkitään tasatulos tulokset[vi - 1][0].tasa = '!' # merkitään tasatulos edellinen = vartio #Lisätään tehtävärivi ylos mukana.insert(0, t_list) return (mukana, ulkona)
def luoTehtavanKaava(t, v): pino = [] # Pinoon laitetaan kulloinenkin iterointipolku, #jotta muuttujan nimet voidaan muuttaa suhteellisesta kirjaimesta absoluuttiseen polkuun. t_nimi = t.nimi.replace(" ", "").replace("!", "").lower() pino.append(t_nimi) osatehtavat = t.osatehtava_set.all() ot_lauseet = [] log.logString(u"<h3>Tehtävä: " + t.nimi.upper() + "</h3>") if t.kaava.upper() == "SS": log.logString(u"kaava = ⚡⚡") else: log.logString(u"kaava = " + t.kaava.upper()) for ot in osatehtavat: log.logString(u"\n<b>Osatehtävä: " + ot.nimi.upper() + "</b>") pino.append(ot.nimi) ot_lause = ot.kaava maaritteet = ot.syotemaarite_set.all() # Suora summa syotteiden välillä if ot_lause == "ss" and maaritteet: ot_lause = "" for m in maaritteet: ot_lause = ot_lause + m.nimi + "+" ot_lause = ot_lause[:-1] parametrit = {} for p in ot.parametri_set.all(): parametrit[p.nimi] = p.arvo ot_lause = luoOsatehtavanKaava(ot_lause, parametrit) korvautuu = True while korvautuu: korvautuu = False vanha = ot_lause ot_lasue = re.sub("vartio" + r"(?!\w+)", str(v.nro), ot_lause) if not ot_lause == vanha: korvautuu = True log.logString(" sijoitettu = " + ot_lause) # Muutetaan muuttujien nimet koko polun mittaisiksi: #tehtava(nimi).osatehtava(nimi).syote(nimi).vartio(nro) ot_lause = korvaa(ot_lause, pino, str(v.nro)) # Pikatie vartio -> vartion numero ot_lause = re.sub("vartio" + r"(?!\w+)", str(v.nro), ot_lause) ot_lauseet.append((ot.nimi, ot_lause)) pino.pop() tehtava_lause = "" #Suora summa osatehtavien välillä: if t.kaava.lower() == "ss" and len(ot_lauseet): for l in ot_lauseet: tehtava_lause = tehtava_lause + "max([0," + l[1] + "])+" tehtava_lause = tehtava_lause[:-1] else: tehtava_lause = t.kaava.lower() for l in ot_lauseet: lause = l[1] tehtava_lause = re.sub( r"(?<!\w|[.])" + l[0] + r"(?<![.])(?!\w+)(?![.])", "max([0," + lause + "])", tehtava_lause) return tehtava_lause.lower()
def laskeSarja(sarja,syotteet,vartiot=None,tehtavat=None): """ Laskee tulokset halutulle sarjalle. Palauttaa kaksiuloitteisen taulukon[vartio][tehtävä] = pisteet. Taulukon ensimmäisissä sarakkeissa on vartio tai tehtävä objekteja muissa pisteitä. Taulukon vasemmassa ylänurkassa on sarjan objekti """ #syotteetr=Syote.objects.all() #(maarite__osa_tehtava__tehtava__sarja=sarja ) if not vartiot : vartiot=sarja.vartio_set.all() if not tehtavat: tehtavat=sarja.tehtava_set.all() if vartiot and tehtavat : jee=1 # Pakotetaan tietokantahaku. #Lasketaan tulokset: muuttujat = luoMuuttujat(sarja.vartio_set.all(),tehtavat,syotteet) laskut= luoLaskut(vartiot,tehtavat) tulokset = laskeTaulukko(laskut,muuttujat) #Muokataan oikean muotoinen tulostaulukko: siirrettavat=[] for i in range(len(vartiot)): # Merkataan tuloksiin H hylättyihin tehtäviin: for t in range(len(tulokset[i])) : hylatty=True tekematta=False tehtSyotteet=syotteet.filter(maarite__osa_tehtava__tehtava=tehtavat[t]).filter(vartio=vartiot[i]) #syotteet= vartiot[i].syote_set.filter(maarite__osa_tehtava__tehtava=tehtavat[t]) for s in tehtSyotteet : if s.arvo=="e" : tekematta=True if not s.arvo=="h": hylatty=False if hylatty and len(tehtSyotteet): tulokset[i][t]= "H" if tekematta: tulokset[i][t]= "E" #Merkataan siirrettäviksi ulkopuolella olevat: if not vartiot[i].keskeyttanyt == None or not vartiot[i].ulkopuolella == None : #Merkataan keskeyttaneille tuloksiin "K" keskeyttämisestä eteenpäin if not vartiot[i].keskeyttanyt==None: kesk=vartiot[i].keskeyttanyt-1 for t in range(kesk,len(tulokset[i])) :tulokset[i][t]= "K" siirrettavat.append(i) #Tuomarineuvosto: vartion_tuomarit=vartiot[i].tuomarineuvostulos_set.all() if len( vartion_tuomarit ): for t in range(len(tulokset[i])) : tuom=vartion_tuomarit.filter(tehtava=tehtavat[t]) if len(tuom) : log.logString( u"Tuomarineuvoston ylimääritys: " + str(tuom[0].pisteet) ) try: tulokset[i][t]= Decimal(tuom[0].pisteet) except: tulokset[i][t]= tuom[0].pisteet #Kokonaispisteet: summa=0 for s in tulokset[i] : if s and type(s)!=str and type(s)!=unicode : summa+= s tulokset[i].insert(0,summa) #Vartio objekti jokaisen rivin alkuun: tulokset[i].insert(0,vartiot[i]) # Kirjataan välivaiheisiin lopputulos try: log.logString( "\n<b>TULOS = " + str(tulokset[0][2])+"</b>" ) except: pass # Siirretään ulkopuoliset ja mukana olevat omiin taulukkoihinsa mukana=[] ulkona=[] for i, item in enumerate(tulokset): u=False for s in siirrettavat: if s==i : u=True if u : ulkona.append(item) else : mukana.append(item) tulokset=mukana #Lisätään tehtävärivi ylös t_list=[sarja,"Yht." ,] pisteet_yhteensa=0 for t in tehtavat: try: if int(t.maksimipisteet) : pisteet_yhteensa+=int(t.maksimipisteet) except: pass t_list.append(t) t_list[0].maksimipisteet=pisteet_yhteensa #Tasapisteissä määräävät tehtävät tasa1 = 0 tasa2 = 0 tasa3 = 0 if sarja.tasapiste_teht1 : tasa1 = sarja.tasapiste_teht1+1 if sarja.tasapiste_teht2 : tasa2 = sarja.tasapiste_teht2+1 if sarja.tasapiste_teht2 : tasa3 = sarja.tasapiste_teht3+1 tulokset.sort(key=operator.itemgetter(1) ,reverse=True) ulkona.sort(key=operator.itemgetter(1) ,reverse=True) #Järjestetään taulukot try : tulokset.sort( key=operator.itemgetter(1,tasa1,tasa2,tasa3),reverse=True ) ulkona.sort( key=operator.itemgetter(1,tasa1,tasa2,tasa3),reverse=True ) except : # tehtäviä < 3 pass # Etsitään tasapistetulokset : edellinen=None for vi, vartio in enumerate(ulkona) : vartio[0].tasa='' # merkitään tasatulos if edellinen and vartio[1]==edellinen[1] : ulkona[vi][0].tasa='!' # merkitään tasatulos ulkona[vi-1][0].tasa='!' # merkitään tasatulos edellinen = vartio edellinen=None for vi, vartio in enumerate(mukana) : vartio[0].tasa='' # merkitään tasatulos if edellinen and vartio[1]==edellinen[1] : tulokset[vi][0].tasa='!' # merkitään tasatulos tulokset[vi-1][0].tasa='!' # merkitään tasatulos edellinen = vartio #Lisätään tehtävärivi ylos mukana.insert(0,t_list) return (mukana,ulkona)
def luoTehtavanKaava(t,v): pino=[] # Pinoon laitetaan kulloinenkin iterointipolku, #jotta muuttujan nimet voidaan muuttaa suhteellisesta kirjaimesta absoluuttiseen polkuun. t_nimi= t.nimi.replace(" ","").replace("!","").lower() pino.append(t_nimi) osatehtavat=t.osatehtava_set.all() ot_lauseet=[] log.logString( u"<h3>Tehtävä: " + t.nimi.upper()+"</h3>" ) if t.kaava.upper()=="SS" : log.logString( u"kaava = ⚡⚡" ) else: log.logString( u"kaava = " + t.kaava.upper() ) for ot in osatehtavat: log.logString( u"\n<b>Osatehtävä: " + ot.nimi.upper()+"</b>" ) pino.append(ot.nimi) ot_lause = ot.kaava maaritteet=ot.syotemaarite_set.all() # Suora summa syotteiden välillä if ot_lause =="ss" and maaritteet : ot_lause="" for m in maaritteet: ot_lause=ot_lause+m.nimi+"+" ot_lause=ot_lause[:-1] parametrit={} for p in ot.parametri_set.all(): parametrit[p.nimi]=p.arvo ot_lause=luoOsatehtavanKaava(ot_lause,parametrit) korvautuu=True while korvautuu: korvautuu=False vanha=ot_lause ot_lasue=re.sub("vartio"+r"(?!\w+)", str(v.nro) ,ot_lause) if not ot_lause==vanha : korvautuu=True log.logString( " sijoitettu = " + ot_lause ) # Muutetaan muuttujien nimet koko polun mittaisiksi: #tehtava(nimi).osatehtava(nimi).syote(nimi).vartio(nro) ot_lause=korvaa(ot_lause,pino,str(v.nro)) # Pikatie vartio -> vartion numero ot_lause=re.sub("vartio"+r"(?!\w+)", str(v.nro) ,ot_lause) ot_lauseet.append((ot.nimi,ot_lause)) pino.pop() tehtava_lause="" #Suora summa osatehtavien välillä: if t.kaava.lower()=="ss" and len(ot_lauseet) : for l in ot_lauseet : tehtava_lause=tehtava_lause + "max([0,"+l[1]+"])+" tehtava_lause=tehtava_lause[:-1] else: tehtava_lause=t.kaava.lower() for l in ot_lauseet: lause=l[1] tehtava_lause=re.sub(r"(?<!\w|[.])"+l[0]+r"(?<![.])(?!\w+)(?![.])", "max([0,"+lause+"])", tehtava_lause) return tehtava_lause.lower()