opgavemaskine.py
Regne opgaver på samlebånd implementeret i python og cherrypy.
Size 10.4 kB - File type text/python-sourceFile contents
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# copyright Lars Bauer Jørgensen. Bauer Data ApS.
# Licence GPL
import random
import cherrypy
"""
+----------+----------+----------------+-------------+------+
| Addition | Division | Multiplikation | Subtraktion | help |
+----------+----------+----------------+-------------+------+
| |
| 5 + 7 = 12 |
| 6 + 3 = +-log--------------+-+ |
| | 3 + 7 = 10 :-) |R| |
| | 3 + 7 = 10 :-) |U| |
| | 3 + 7 = 10 :-) |L| |
| | 3 * 7 = 10 :-) |L| |
| | 3 + 7 = 10 :-) |E| |
| | 3 - 7 = 10 :-( | | |
| | 3 + 7 = 10 :-) | | |
| +------------------+-+ |
| |
+-----------------------------------------------------------+
"""
happy=" :-)"
surprise=" :-o"
sat=" :-("
help_text={
"Addition":"(Heltal) Læg to tal sammen. Formlen er 'a + b =' ",
"Subtraktion":"(Heltal) Træk to tal fra hinanden. Formlen er 'a - b =' ",
"Multiplikation":"(Heltal) Gang to tal med hinanden. Formlen er 'a * b ='",
"Division":"(Heltal) Divider to tal med hinanden. Formlen er 'a / b ='",
"Ligning":"(Heltal) Løs ligning . Hvad er x. Formlen er 'ax + b = c -> x=",
"Intervaller":"Her angives intervaller for de variable som opgaverne bygges af",
}
conditions={
"Addition":"True",
"Subtraktion":"a > b",
"Multiplikation":"True",
"Division":"b !=0 and a % b == 0",
"Ligning":"a != 0 and b != c and (c - b) % a == 0",
}
expresion={
"Addition":"a+b",
"Subtraktion":"a-b",
"Multiplikation":"a*b",
"Division":"a/b",
"Ligning":"(c -b) / a",
}
representation={
"Addition":"%(a)s+%(b)s =",
"Subtraktion":"%(a)s-%(b)s =",
"Multiplikation":"%(a)s*%(b)s =",
"Division":"%(a)s/%(b)s =",
"Ligning":"%(a)sx+%(b)s=%(c)s -> x =",
}
# ax +b = c"
# ax = c - b
# x = (c -b) / a
buttonlist=[opr for opr in expresion.keys()]
buttonlist.append("Intervaller")
buttonlist.append("help")
interval_defs={\
"Addition" :{ "a": {"min":0,"max":17}, "b": {"min":0,"max":17},},
"Subtraktion" :{ "a": {"min":0,"max":17}, "b": {"min":0,"max":17},},
"Multiplikation":{ "a": {"min":0,"max":17}, "b": {"min":0,"max":11},},
"Division" :{ "a": {"min":0,"max":101}, "b": {"min":2,"max":11},},
"Ligning" :{ "a": {"min":0,"max":101}, "b": {"min":2,"max":11}, "c": {"min":2,"max":11},},
}
intervaller={\
"Addition" :{"a":range(17), "b":range(17) },
"Subtraktion" :{"a":range(17), "b":range(17) },
"Multiplikation":{"a":range(11), "b":range(0,11) },
"Division" :{"a":range(10,101), "b":range(2,11) },
"Ligning" :{"a":range(0,10), "b":range(0,11) , "c":range(0,11) },
}
def get_variable_names(regneArt=""):
set=[x for regneart in intervaller.keys() for x in intervaller[regneart].keys() if regneArt == "" or regneart==regneArt]
for v in set:
while v in set: set.remove(v)
set.append(v)
set.sort()
return set
def init_intervals():
for regneart in interval_defs.keys():
for variable in interval_defs[regneart].keys():
limits= interval_defs[regneart][variable]
intervaller[regneart][variable]=range(limits["min"],limits["max"])
def td(strg):
return "<td>"+strg+"</td>"
def inputHtml(name,value,size="4",maxlength="4"):
a="""<input type="text" name="%s" value="%s" size="%s" maxLength="%s">""" % (name,value,size,maxlength)
return a
def submitHtml(name,value=""):
return '<input type="submit" name="%s" value="%s">' % (name,value)
class Opgave:
def get_random_values(self):
vnames=get_variable_names(regneArt=self.regneart)
while True:
for variable in vnames:
x=self.variable[variable]=random.choice(intervaller[self.regneart][variable])
if variable=="a" : a=x
elif variable=="b" : b=x
elif variable=="c" : c=x
elif variable=="d" : d=x
elif variable=="e" : e=x
if eval(conditions[self.regneart]):
self.result=eval(expresion[self.regneart])
break
def __init__(self,regneart="Addition"):
self.variable={}
self.regneart=regneart
self.get_random_values()
def prt(self,result=""):
return representation[self.regneart] % self.variable + result + self.valid_strg(result)
def valid_strg(self,result):
rigtig,fejl,mangler=self.validate(result)
if result=="":
return ""
if rigtig:
return happy
if fejl:
return sat
if mangler:
return surprise
print "error"
def validate(self,result):
if result=="":
return 0,0,1
try: result=int(result)
except: return 0,0,1
if self.result==result:
return 1,0,0
return 0,1,0
class opgaveMaskine:
def help(self):
ret=['<b>%s : </b>%s <br />' % (issue,help_text[issue]) for issue in help_text.keys() if self.help_issue in ("help","index",issue)]
return "\n".join(ret)
def interval_menu(self):
variabel_names=get_variable_names()
ret=[]
ret.append('<table><form action="set_interval" method="POST">')
ret.append("<thead><th>Regneart</th>")
for variabel_name in variabel_names:
ret.append('<th>min %s</th><th>max %s</th>' % (variabel_name,variabel_name))
ret.append('</tr></thead>')
for regneart in interval_defs.keys():
ret.append('<tr><td>%s </td>' % regneart)
for variabel in variabel_names:
try: ranges=interval_defs[regneart][variabel]
except:
ret.append(td(" "))
continue # variable name not part of this
for limits in ("min","max"):
ret.append(td(inputHtml("%s.%s.%s"% (regneart,variabel,limits),ranges[limits])))
ret.append("</tr>")
ret.append(submitHtml("intervaller",value="Gem intervaller"))
ret.append('</form></table>')
return "\n".join(ret)
interval_menu.exposed = True
def set_interval(self,**pargs):
args=[(x,pargs[x]) for x in pargs.keys()]
ret=""
for key,value in args:
try: regneart,variabel,limit=key.split(".")
except ValueError: continue
try: value=int(value)
except ValueError:
ret='<p color="red">Angiv venligst tal</p>'
return self.kommandos(kommando="Intervaller")+ret
interval_defs[regneart][variabel][limit]=value
return self.kommandos(kommando="Intervaller")
set_interval.exposed = True
def headPart(self):
if self.headpart =="":
self.headpart=open(self.headfilename).read()
return self.headpart
def score(self):
"""Return liste antal (<rigtige>,<fejl>,<mangler>))"""
rigtige=0
fejl=0
mangler=0
for ix in range(len(self.opgaveListe)):
res=self.opgaveListe[ix].validate(self.result[ix])
rigtige= res[0]
fejl= res[1]
mangler= res[2]
return rigtige,fejl,mangler
def get_buttons(self):
if self.buttonlisthtml is None:
Ret=[]
for knap in self.buttonlist:
Ret.append('<input tabindex=0 type="submit" name="kommando" value="%s">' % knap )
self.buttonlisthtml="<table><td>" + "</td><td>".join(Ret) + "</td></table>"
return self.buttonlisthtml
def validate(self):
self.error=False
if self.kommando=="index":
return ""
if self.nykommando:
return ""
opgaveSvar=[self.opgaveListe[ix].prt(result=self.result[ix]) for ix in range(len(self.opgaveListe)) if self.opgaveListe[ix].validate(self.result[ix])[2]==0]
self.log.insert(0,"\n".join(opgaveSvar))
interval=range(len(self.opgaveListe))
interval.reverse()
for ix in interval:
if self.opgaveListe[ix].validate(self.result[ix])[0]==1:
self.opgaveListe.remove(self.opgaveListe[ix])
return ""
def set_opgaver(self,number=-1):
if number==-1:
number=self.antal_opgaver
# print self.kommando
self.opgaveListe=[Opgave(self.kommando) for i in range(number)]
def opgaveHtml(self):
interval=range(len(self.opgaveListe))
a="""<tr><td>%s</td>
<td><input tabindex=%s type="text" name="result" size="4" maxLength="4" alt="Skriv et heltal">
</td></tr>"""
return "".join([a % (self.opgaveListe[ix].prt(result=""),ix+1) for ix in interval])
def generer_opgave(self):
if self.kommando=="index":
return ""
# print self.kommando
if len(self.opgaveListe)==0 or (len(self.result) > 0 and self.score()[1]==0 and self.score()[2]==0):
self.result={}
self.set_opgaver()
self.log.insert(0,"Beregn")
ret=[ '<table><form action="calculate" method="POST">']
ret.append(self.opgaveHtml())
ret.append('<input type="submit" value="Kontrol"></form></td>')
ret.append('</table>')
return "".join(ret)
def header(self):
strg=['<form action="kommandos" id="opgavemaskine" method="POST">']
strg.append(self.get_buttons())
strg.append('</form>')
return strg
def footer( self ):
return '<p><a target="_blank" href="http://www.databassen.dk:8090/bauerdata/diverse-filer-til-download-mm/opgavemaskine.py">Se kildekode</a></p>'
def canvas(self):
canvashtml=self.header()
canvashtml.append('<table border="0">')
canvashtml.append('<td width="65%" valign="top">')
if self.kommando=="help":
canvashtml.append(self.help())
elif self.kommando=="Intervaller":
canvashtml.append(self.interval_menu())
elif self.kommando != "index":
canvashtml.append(self.validate())
canvashtml.append(self.generer_opgave())
canvashtml.append('</td>')
canvashtml.append('<td><textarea readonly="1" cols="20" rows="20">%s</textarea></td>' % "\n".join(self.log))
canvashtml.append('</table>')
return "".join(canvashtml)
def page(self):
return self.headPart()+self.canvas()+self.footer()
def index(self, kommando = "index",result=None, check = ""):
self.antal_opgaver=10
self.opgaveListe=[]
self.opgave={}
self.opgave_art={}
self.log=["velkommen\n"]
self.nykommando=True
self.buttonlisthtml=None
self.buttonlist=buttonlist
self.headpart=""
self.headfilename="sqlhead"
self.kommando=kommando
self.variables={}
self.result={}
self.error=False
init_intervals()
return self.page()+"<br /><a>kommando %s</a>" % self.kommando
index.exposed = True
def calculate(self,result):
self.nykommando=False
self.result=result
return self.page()
calculate.exposed = True
def kommandos(self,kommando="",result=None,check=""):
if kommando=="help":
self.help_issue=self.kommando
self.opgaveListe=[]
self.result={}
self.nykommando=True
self.kommando=kommando
self.log.insert(0,self.kommando)
init_intervals()
return self.page()
kommandos.exposed = True
cherrypy.root = opgaveMaskine()
if __name__ == '__main__':
cherrypy.config.update(file = 'opgavemaskine.conf')
cherrypy.server.start()
Click here to get the file