# coding=utf-8 from python.util import has_token_sequence from server.hints import Hint, HintSequence id = 180 group = 'introduction' number = 1 visible = True solution = '''\ f = float(input("Temperatura [F]: ")) c = 5/9 * (f – 32) print("Temperatura je", c, "C") ''' hint_type = { 'plan': Hint('plan'), 'no_input_call': Hint('no_input_call'), 'expressions_python': Hint('expressions_python'), 'printing': Hint('printing'), 'name_error': HintSequence('name_error', 4), 'unsupported_operand': HintSequence('unsupported_operand', 4), 'not_callable': HintSequence('not_callable', 4), } def test(python, code): # List of inputs: (expression to eval, stdin). test_in = [ (None, '32\n'), (None, '212\n'), (None, '-459.4\n'), (None, '98.6\n'), (None, '1832\n'), ] test_out = [ '0', '100', '-273', '37', '1000' ] # List of outputs: (expression result, stdout, stderr, exception). answers = python(code=code, inputs=test_in, timeout=1.0) outputs = [ans[1] for ans in answers] n_correct = 0 for output, correct in zip(outputs, test_out): if correct in output: n_correct += 1 return n_correct, len(test_in) def hint(python, code): # run one test first to see if there are any exceptions test_in = [(None, '212\n')] exc = python(code=code, inputs=test_in, timeout=1.0)[0][3] # have an exception! if exc: if 'NameError' in exc: return [{'id':'name_error', 'args': {'message': exc}}] elif 'not callable' in exc: return [{'id':'not_callable', 'args': {'message': exc}}] elif 'unsupported operand' in exc: return [{'id':'unsupported_operand', 'args': {'message': exc}}] elif 'TypeError' in exc: return [{'id':'unsupported_operand', 'args': {'message': exc}}] # the trick is to decide when to show the plan and when the first hint. # I implemented a simple idea: show plan, when code contains something from the # solution, but not input. if len(code.strip()) < 5 or (not has_token_sequence(code, ['input']) and (has_token_sequence(code, ['32']) or has_token_sequence(code, ['=', '5']) or has_token_sequence(code, ['print']))): return [{'id': 'plan'}] # if input is not present in code, student needs to learn about input if not has_token_sequence(code, ['input']): return [{'id': 'no_input_call'}] # if tokens * or / or = are not in code, we have to teach them how to # evaluate expressions. if (not has_token_sequence(code, ['/']) or not has_token_sequence(code, ['*']) or not has_token_sequence(code, ['='])): return [{'id' : 'expressions_python'}] # student is not using print function if not has_token_sequence(code, ['print']): return [{'id' : 'printing'}] return None