-
Notifications
You must be signed in to change notification settings - Fork 0
/
api.py
112 lines (92 loc) · 3.95 KB
/
api.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
from os import error
from flask import Flask, jsonify, request
from flask import Response
from flask_cors import CORS
import sys
from io import StringIO
import contextlib
import traceback
class InterpreterError(Exception): pass
app = Flask(__name__)
cors = CORS(app, resources={r"/tester": {"origins": "*"}})
app.config['CORS_HEADERS'] = 'Content-Type'
def execute_code(code, inputs, solutions):
res = ""
cons = ""
print_output = ""
res_list = []
te = 1
correct, wrong, tot = 0, 0, len(solutions)
for index in range(len(inputs)):
i = inputs[index]
sol = solutions[index]
if te != 1: res += "\n"
res += "------------------ TEST #" + str(te) + ": input = " + str(i) + " --------------------"
print_output = ""
try:
codeObejct = compile("inp = " + str(i) + "\n" + code, 'sumstring', 'exec')
loc = {}
exec(codeObejct, globals(), loc)
return_workaround = loc['output']
to_print = loc['to_print']
for printer in to_print:
print_output += "> "+str(printer) + "\n"
res += "\nExpected output to be: " + str(sol) + ".\nYour code returned: " + str(return_workaround)
failed = str(sol) != str(return_workaround)
if failed:
if index != (len(inputs)-1):
cons += "Failed Test #" + str(te) + "\n"
else:
cons += "Failed Test #" + str(te)
res += "\nTEST FAILED.\n\n" if failed else "\nTEST PASSED.\n\n"
res += "Print Output:\n" + print_output
wrong += 1 if failed else 0
correct += 1 if not failed else 0
res_list.append(return_workaround)
res = res.replace("to_print.append", "print")
except SyntaxError as err:
error_class = err.__class__.__name__
line_number = err.lineno
detail = err.args[0]
if str("'return' outside function") in str(detail):
res += "\nERROR: Extra 'return' statement on line %s.\n>>> Don't include a return statement in your code. The statement'return output' is given." % str(line_number-2)
else:
res += "\nERROR: %s on line %d.\n>>> %s" % (error_class, line_number-2, detail)
break
except Exception as err:
error_class = err.__class__.__name__
detail = err.args[0]
cl, exc, tb = sys.exc_info()
line_number = traceback.extract_tb(tb)[-1][1]
if str("'return' outside function") in str(detail):
res += "\nERROR: Unexpected 'return' statement.\n>>> Don't include a return statement in your code. The statement'return output' is given."
elif (str(detail) == "output"): #KeyError
res += "\nERROR: %s\nMake sure you are asigning a value to `output`." % (str(error_class))
else:
res = res + "\nERROR: %s on line %d.\n>>> %s ." % (str(error_class), line_number-2,detail)
break
te += 1
return (res, res_list, cons, correct, wrong, tot)
@app.route('/', methods=['GET'])
def getDefault():
return jsonify({'Asli says hello!': 'This is my python interpreter API. I use it for a pair programming platform I am working on.'})
@app.route('/tester', methods=['POST'])
def tester():
inputs = request.json['inputs']
solutions = request.json['solutions']
code = request.json['code']
"""
Example
{
"inputs": [0,1,2,3],
"solutions": [0,2,4,6],
"code": "output = input*2"
}
"""
var = execute_code("to_print = []\n" + code.replace("print", "to_print.append"), inputs, solutions)
equal = True
if var[1] != solutions and var[3]!=var[5]:
equal = False
return jsonify({'prints': var[2], 'console':var[0], 'result':equal, 'solution': var[1], 'correct':var[3], 'wrong':var[4], 'tot':var[5] })
if __name__ == '__main__':
app.run(debug=True, port=8000)