import re from python.util import has_token_sequence, string_almost_equal, \ string_contains_number, get_tokens, get_numbers, get_exception_desc from server.hints import Hint id = 204 number = 20 visible = True solution = '''\ n = int(input('Vnesi število: ')) for i in range(1, n+1): if n % i == 0: print(i) ''' hint_type = { 'input_clause': Hint('input_clause'), 'range_function': Hint('range_function'), 'printing': Hint('printing'), 'divisor': Hint('divisor'), 'final_hint': Hint('final_hint'), 'zero_division': Hint('zero_division'), 'last_number': Hint('last_number'), } def test(python, code, aux_code=''): test_in = [ (None, '8\n'), (None, '6\n'), (None, '5\n'), (None, '2\n'), (None, '15\n'), (None, '20\n'), ] values = [8, 6, 5, 2, 15, 20] # List of outputs: (expression result, stdout, stderr, exception). answers = python(code=aux_code+code, inputs=test_in, timeout=1.0) outputs = [ans[1] for ans in answers] n_correct, tin = 0, None for i, (output, v) in enumerate(zip(outputs, values)): correct = True clist = [] nums = get_numbers(output) for vi in range(1, v+1): if v%vi == 0: clist.append(vi) if v%vi == 0 and vi not in nums: correct = False if v%vi != 0 and vi in nums: correct = False if correct: n_correct += 1 else: tin = test_in[i][1] tout = clist passed = n_correct == len(test_in) hints = [{'id': 'test_results', 'args': {'passed': n_correct, 'total': len(test_in)}}] if tin: hints.append({'id': 'problematic_test_case', 'args': {'testin': str(tin), 'testout': str(tout)}}) if passed: hints.append({'id': 'final_hint'}) return passed, hints def hint(python, code, aux_code=''): # run one test first to see if there are any exceptions answer = python(code=aux_code+code, inputs=[(None, '8\n')], timeout=1.0) exc = get_exception_desc(answer[0][3]) if exc: if 'ZeroDivisionError' in answer[0][3]: return [{'id' : 'zero_division', 'args': {'message': answer[0][3]}}] else: return exc tokens = get_tokens(code) # if has no input, tell him how to ask questions if not has_token_sequence(tokens, ['input']): return [{'id' : 'input_clause'}] # if it has no range, explain how we can create a list (generator) from a number if not has_token_sequence(tokens, ['range']): return [{'id' : 'range_function'}] # if it has no print function, tell him to use print if not has_token_sequence(tokens, ['print']): return [{'id' : 'printing'}] # if it has no divisoin-by-modulo operator, explain that operator if not has_token_sequence(tokens, ['%']): return [{'id' : 'divisor'}] # if the program prints all divisors but 8, # it means that is skips itself nums = get_numbers(answer[0][1]) if 1 in nums and 2 in nums and 4 in nums and 8 not in nums: return [{'id' : 'last_number'}] return None