forked from datacamp/pythonwhat
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtest_exercise.py
More file actions
124 lines (102 loc) · 3.87 KB
/
test_exercise.py
File metadata and controls
124 lines (102 loc) · 3.87 KB
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
113
114
115
116
117
118
119
120
121
122
123
124
from pythonwhat.State import State
from pythonwhat.local import run_exercise
from pythonwhat.sct_syntax import Ex
from pythonwhat.utils import check_str, check_process
from pythonwhat.reporter import Reporter
from protowhat.Test import TestFail
from pythonwhat.utils import include_v1
def test_exercise(
sct,
student_code,
solution_code,
pre_exercise_code,
student_process,
solution_process,
raw_student_output,
ex_type,
error,
force_diagnose=False,
):
"""
Point of interaction with the Python backend.
Args:
sct (str): The solution corectness test as a string of code.
student_code (str): The code which is entered by the student.
solution_code (str): The code which is in the solution.
pre_exercise_code (str): The code which is executed pre exercise.
student_process (Process): Process in which the student code was executed.
solution_process (Process): Process in which the solution code was executed.
raw_student_output (str): The output which is given by executing the student's program.
ex_type (str): The type of the exercise.
error (tuple): A tuple with some information on possible errors.
Returns:
dict: Returns dict with correct - whether the SCT passed, message - the feedback message and
tags - the tags belonging to the SCT execution.
"""
try:
state = State(
student_code=check_str(student_code),
solution_code=check_str(solution_code),
pre_exercise_code=check_str(pre_exercise_code),
student_process=check_process(student_process),
solution_process=check_process(solution_process),
raw_student_output=check_str(raw_student_output),
force_diagnose=force_diagnose,
reporter=Reporter(errors=[error] if error else []),
)
State.root_state = state
tree, sct_cntxt = prep_context()
# Actually execute SCTs
exec(sct, sct_cntxt)
# Run remaining nodes on tree (v1 only)
if tree:
for test in tree.crnt_node:
test(state)
except TestFail as e:
return e.payload
return state.reporter.build_final_payload()
# TODO: consistent success_msg
def success_msg(message):
"""
Set the succes message of the sct. This message will be the feedback if all tests pass.
Args:
message (str): A string containing the feedback message.
"""
State.root_state.reporter.success_msg = message
# deprecated
def allow_errors():
State.root_state.reporter.errors_allowed = True
def prep_context():
cntxt = {"success_msg": success_msg}
from pythonwhat.sct_syntax import v2_check_functions
from pythonwhat.probe import build_probe_context
imports = [
"from inspect import Parameter as param",
"from pythonwhat.signatures import sig_from_params, sig_from_obj",
"from pythonwhat.State import set_converter",
"from pythonwhat.sct_syntax import F, Ex",
]
[exec(line, None, cntxt) for line in imports]
# only if PYTHONWHAT_V2_ONLY is not set, support v1
if include_v1():
tree, probe_cntxt = build_probe_context()
cntxt.update(probe_cntxt)
else:
tree = None
cntxt.update(v2_check_functions)
return tree, cntxt
def setup_state(stu_code="", sol_code="", pec="", **kwargs):
sol_process, stu_process, raw_stu_output, error = run_exercise(
pec, sol_code, stu_code, **kwargs
)
state = State(
student_code=stu_code,
solution_code=sol_code,
pre_exercise_code=pec,
student_process=stu_process,
solution_process=sol_process,
raw_student_output=raw_stu_output,
reporter=Reporter(errors=[error] if error else []),
)
State.root_state = state
return Ex(state)