Update assess.py

This commit is contained in:
tstaubitz
2015-10-16 15:49:10 +02:00
parent 1551491f16
commit 8d1dd79f9e

View File

@ -1,234 +1 @@
import webpython, contextlib, io, json, sys, turtle, ast
from webpython import shell
turtle_operations = []
bindings = {}
class RecordingPen:
_pen = None
_screen = None
def __init__(self):
self.operations = turtle_operations
self._pos = (0,0)
turtle_operations.append(('__init__',()))
def reset(self):
turtle_operations.clear()
def onclick(self, fun, btn=1, add=None):
self.operations.append(('onclick', (fun,)))
def eventfun(event):
fun(event.x, event.y)
bindings['<Button-1>'] = eventfun
def goto(self, x, y):
self._pos = (x,y)
self.operations.append(('goto', (x,y)))
def pos(self):
self.operations.append(('pos', ()))
return self._pos
def __getattr__(self, method):
def func(*args):
self.operations.append((method, args))
return func
class FakeCanvas(turtle.WebCanvas):
def flushbatch(self):
pass
def get_width(self):
return 400
def get_height(self):
return 400
def delete(self, item):
pass
def css(self, key, value):
pass
fake_events = []
def mainloop():
while fake_events:
e = turtle.Event(fake_events.pop(0))
if e.type in bindings:
bindings[e.type](e)
turtle.Turtle = RecordingPen
turtle.WebCanvas = FakeCanvas
pen = turtle._getpen()
turtle.mainloop = mainloop
def filter_operations(name):
return [o for o in turtle_operations if o[0] == name]
@contextlib.contextmanager
def capture():
global captured_out
import sys
oldout,olderr = sys.stdout, sys.stderr
try:
out=[io.StringIO(), io.StringIO()]
captured_out = out
sys.stdout,sys.stderr = out
yield out
finally:
sys.stdout,sys.stderr = oldout, olderr
out[0] = out[0].getvalue()
out[1] = out[1].getvalue()
def get_source():
message = json.loads(sys.argv[1])
return message['data']
def get_ast():
s = get_source()
return ast.parse(s, "programm.py", "exec")
def has_bare_except():
for node in ast.walk(get_ast()):
if isinstance(node, ast.ExceptHandler):
if node.type is None:
return True
return False
def runcaptured(prefix='', tracing=None, variables=None, source=''):
#message = json.loads(sys.argv[1])
#source = prefix + message['data']
with open("programm.py", "w", encoding='utf-8') as f:
f.write(source)
c = compile(source, "programm.py", 'exec')
with capture() as out, trace(tracing):
if variables is None:
variables = {}
exec(c, variables)
return source, out[0], out[1], variables
def runfunc(func, *args, tracing=None):
with capture() as out, trace(tracing):
res = func(*args)
return out[0], out[1], res
def passed():
msg_in = json.loads(sys.argv[1])
msg_out = {'cmd':'passed'}
msg_out['lis_outcome_service_url'] = msg_in['lis_outcome_service_url']
msg_out['lis_result_sourcedid'] = msg_in['lis_result_sourcedid']
webpython.shell.sendpickle(msg_out)
def failed(msg):
msg_in = json.loads(sys.argv[1])
msg_out = {'cmd':'failed', 'data':'Dein Programm ist leider falsch:\n'+msg}
msg_out['lis_outcome_service_url'] = msg_in['lis_outcome_service_url']
msg_out['lis_result_sourcedid'] = msg_in['lis_result_sourcedid']
webpython.shell.sendpickle(msg_out)
def modified(variables, name, val):
if variables.get(name) != val:
msg_in = json.loads(sys.argv[1])
msg_out = {'cmd':'failed',
'data':('Bitte lösche Deine Zuweisung der Variable %s, '+
'damit wir Dein Programm überprüfen können.') % name}
msg_out['lis_outcome_service_url'] = msg_in['lis_outcome_service_url']
msg_out['lis_result_sourcedid'] = msg_in['lis_result_sourcedid']
webpython.shell.sendpickle(msg_out)
return True
return False
undefined = object()
def getvar(variables, name):
try:
return variables['name']
except KeyError:
name = name.lower()
for k,v in variables.items():
if k.lower() == name:
return v
return undefined
def _match(n1, n2):
if n1 == n2:
return True
if n1 is None or n2 is None:
return False
return n1.lower() == n2.lower()
class Call:
def __init__(self, name, args):
self.name = name
self.args = args
self.calls = []
self.current = None
def findcall(self, f):
if _match(self.name, f):
return self
for c in self.calls:
r = c.findcall(f)
if r:
return r
return None
def calling(self, caller, callee):
if _match(self.name, caller):
for c in self.calls:
if _match(c.name, callee):
return True
for c in self.calls:
if c.calling(caller, callee):
return True
return False
def countcalls(self, caller, callee):
calls = 0
if _match(self.name, caller):
for c in self.calls:
if _match(c.name, callee):
calls += 1
return calls
for c in self.calls:
r = c.countcalls(caller, callee)
if r > 0:
return r
return 0
class Tracing(Call):
def __init__(self):
Call.__init__(self, None, None)
def trace(self, frame, event, arg):
if event == 'call':
c = Call(frame.f_code.co_name, frame.f_locals.copy())
cur = self
while cur.current:
cur = cur.current
cur.calls.append(c)
cur.current = c
return self.trace
elif event in ('return', 'exception'):
cur = self
if not cur.current:
# XXX return without call? happens when invocation of top function fails
return
while cur.current.current:
cur = cur.current
cur.current = None
def start(self):
sys.settrace(self.trace)
def stop(self):
sys.settrace(None)
@contextlib.contextmanager
def trace(t):
try:
if t:
t.start()
yield
finally:
if t:
t.stop()
# moved to dockerfiles/ubuntu-python