Skip to content

Commit c5b9fc4

Browse files
committed
Clean up reporting feedback
1 parent 0f227b6 commit c5b9fc4

8 files changed

Lines changed: 62 additions & 87 deletions

File tree

pythonwhat/Feedback.py

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,16 @@
22

33

44
class Feedback(ProtoFeedback):
5-
def __init__(self, message, state=None):
6-
self.message = message
7-
self.highlight = None
8-
self.highlighting_disabled = False
9-
if state is not None:
10-
self.highlight = state.highlight
11-
self.highlighting_disabled = state.highlighting_disabled
12-
13-
def get_line_info(self):
14-
try:
15-
if (
16-
self.highlight is not None
17-
and hasattr(self.highlight, "first_token")
18-
and hasattr(self.highlight, "last_token")
19-
and not self.highlighting_disabled
20-
):
21-
return {
22-
"line_start": self.highlight.first_token.start[0],
23-
"column_start": self.highlight.first_token.start[1],
24-
"line_end": self.highlight.last_token.end[0],
25-
"column_end": self.highlight.last_token.end[1],
26-
}
27-
else:
28-
return {}
29-
except:
30-
return {}
5+
def _line_info(self):
6+
if hasattr(self.highlight, "first_token") and hasattr(
7+
self.highlight, "last_token"
8+
):
9+
return {
10+
"line_start": self.highlight.first_token.start[0],
11+
"column_start": self.highlight.first_token.start[1],
12+
"line_end": self.highlight.last_token.end[0],
13+
"column_end": self.highlight.last_token.end[1],
14+
}
3115

3216
def get_formatted_line_info(self):
3317
formatted_info = self.get_line_info()

pythonwhat/State.py

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import inspect
2-
from copy import copy
31
from functools import partialmethod
42
from pythonwhat.parsing import (
53
TargetVars,
@@ -10,7 +8,6 @@
108
from protowhat.State import State as ProtoState
119
from protowhat.Feedback import InstructorError
1210
from pythonwhat.Feedback import Feedback
13-
from protowhat.Test import Fail
1411
from pythonwhat import signatures
1512
from pythonwhat.converters import get_manual_converters
1613
from collections.abc import Mapping
@@ -120,7 +117,11 @@ def to_child(self, append_message="", node_name="", **kwargs):
120117
student tree and solution tree. This is necessary when testing if statements or
121118
for loops for example.
122119
"""
123-
base_kwargs = {attr: getattr(self, attr) for attr in self.params if attr not in ['highlight']}
120+
base_kwargs = {
121+
attr: getattr(self, attr)
122+
for attr in self.params
123+
if attr not in ["highlight"]
124+
}
124125

125126
if not isinstance(append_message, dict):
126127
append_message = {"msg": append_message, "kwargs": {}}
@@ -202,33 +203,27 @@ def parse_external(self, code):
202203
except IndentationError as e:
203204
e.filename = "script.py"
204205
# no line info for now
205-
self.do_test(
206-
Fail(
207-
Feedback(
208-
"Your code could not be parsed due to an error in the indentation:<br>`%s.`"
209-
% str(e)
210-
)
206+
self.report(
207+
Feedback(
208+
"Your code could not be parsed due to an error in the indentation:<br>`%s.`"
209+
% str(e)
211210
)
212211
)
213212

214213
except SyntaxError as e:
215214
e.filename = "script.py"
216215
# no line info for now
217-
self.do_test(
218-
Fail(
219-
Feedback(
220-
"Your code can not be executed due to a syntax error:<br>`%s.`"
221-
% str(e)
222-
)
216+
self.report(
217+
Feedback(
218+
"Your code can not be executed due to a syntax error:<br>`%s.`"
219+
% str(e)
223220
)
224221
)
225222

226223
# Can happen, can't catch this earlier because we can't differentiate between
227224
# TypeError in parsing or TypeError within code (at runtime).
228225
except:
229-
self.do_test(
230-
Fail(Feedback("Something went wrong while parsing your code."))
231-
)
226+
self.report(Feedback("Something went wrong while parsing your code."))
232227

233228
return res
234229

@@ -244,10 +239,10 @@ def parse_internal(code):
244239
def parse(self, text, test=True):
245240
if test:
246241
parse_method = self.parse_external
247-
token_attr = 'student_ast_tokens'
242+
token_attr = "student_ast_tokens"
248243
else:
249244
parse_method = self.parse_internal
250-
token_attr = 'solution_ast_tokens'
245+
token_attr = "solution_ast_tokens"
251246

252247
tokens, ast = parse_method(text)
253248
setattr(self, token_attr, tokens)

pythonwhat/Test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import numpy as np
33
import pandas as pd
44
from pythonwhat.tasks import *
5-
from protowhat.Test import TestFail, Test
5+
from protowhat.Test import Test
66

77
"""
88
This file contains all tests that can be done on specific objects. All tests are represented as

pythonwhat/checks/check_funcs.py

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ def check_node(
139139
stu_out[index]
140140
except (KeyError, IndexError): # TODO comment errors
141141
_msg = state.build_message(missing_msg, fmt_kwargs)
142-
state.do_test(Test(Feedback(_msg, state)))
142+
state.report(Feedback(_msg, state))
143143

144144
# get node at index
145145
stu_part = stu_out[index]
@@ -167,23 +167,19 @@ def with_context(state, *args, child=None):
167167
process=state.student_process, context=state.student_parts["with_items"]
168168
)
169169
if isinstance(student_res, AttributeError):
170-
state.do_test(
171-
Test(
172-
Feedback(
173-
"In your `with` statement, you're not using a correct context manager.",
174-
child.highlight, # TODO
175-
)
170+
state.report(
171+
Feedback(
172+
"In your `with` statement, you're not using a correct context manager.",
173+
child.highlight, # TODO
176174
)
177175
)
178176

179177
if isinstance(student_res, (AssertionError, ValueError, TypeError)):
180-
state.do_test(
181-
Test(
182-
Feedback(
183-
"In your `with` statement, the number of values in your context manager "
184-
"doesn't correspond to the number of variables you're trying to assign it to.",
185-
child.highlight,
186-
)
178+
state.report(
179+
Feedback(
180+
"In your `with` statement, the number of values in your context manager "
181+
"doesn't correspond to the number of variables you're trying to assign it to.",
182+
child.highlight,
187183
)
188184
)
189185

@@ -203,13 +199,11 @@ def with_context(state, *args, child=None):
203199

204200
close_student_context = breakDownNewEnvInProcess(process=state.student_process)
205201
if isinstance(close_student_context, Exception):
206-
state.do_test(
207-
Test(
208-
Feedback(
209-
"Your `with` statement can not be closed off correctly, you're "
210-
+ "not using the context manager correctly.",
211-
state,
212-
)
202+
state.report(
203+
Feedback(
204+
"Your `with` statement can not be closed off correctly, you're "
205+
+ "not using the context manager correctly.",
206+
state,
213207
)
214208
)
215209
return state

pythonwhat/checks/check_function.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def check_function(
131131
stu_parts = {**stu_out[name][index]}
132132
except (KeyError, IndexError):
133133
_msg = state.build_message(missing_msg, fmt_kwargs, append=append_missing)
134-
state.do_test(Test(Feedback(_msg, state)))
134+
state.report(Feedback(_msg, state))
135135

136136
# Signatures -----
137137
if signature:
@@ -163,11 +163,9 @@ def check_function(
163163
_msg = state.build_message(
164164
params_not_matched_msg, fmt_kwargs, append=append_params_not_matched
165165
)
166-
state.do_test(
167-
Test(
168-
Feedback(
169-
_msg, StubState(stu_parts["node"], state.highlighting_disabled)
170-
)
166+
state.report(
167+
Feedback(
168+
_msg, StubState(stu_parts["node"], state.highlighting_disabled)
171169
)
172170
)
173171

pythonwhat/checks/check_logic.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from protowhat.checks.check_logic import multi, check_not, check_or, check_correct, disable_highlighting, fail
2-
from protowhat.Test import Fail
32
from protowhat.Feedback import InstructorError
4-
from pythonwhat.Feedback import Feedback
53
import ast
64

75

pythonwhat/checks/has_funcs.py

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def verify(part, index):
5353
try:
5454
verify(state.student_parts[name], index)
5555
except (KeyError, IndexError):
56-
state.do_test(Test(Feedback(_msg, state)))
56+
state.report(Feedback(_msg, state))
5757

5858
return state
5959

@@ -101,7 +101,7 @@ def shout(word):
101101

102102
if d["stu_len"] != d["sol_len"]:
103103
_msg = state.build_message(unequal_msg, d)
104-
state.do_test(Test(Feedback(_msg, state)))
104+
state.report(Feedback(_msg, state))
105105

106106
return state
107107

@@ -195,7 +195,7 @@ def parse_tree(tree):
195195
if exact and not code:
196196
state.do_test(EqualTest(stu_rep, sol_rep, Feedback(_msg, state)))
197197
elif not sol_rep in stu_rep:
198-
state.do_test(Test(Feedback(_msg, state)))
198+
state.report(Feedback(_msg, state))
199199

200200
return state
201201

@@ -348,12 +348,12 @@ def has_expr(
348348
fmt_kwargs["stu_str"] = str_stu
349349
_msg = state.build_message(error_msg, fmt_kwargs, append=append)
350350
feedback = Feedback(_msg, state)
351-
state.do_test(Test(feedback))
351+
state.report(feedback)
352352

353353
# name is undefined after running expression
354354
if isinstance(eval_stu, UndefinedValue):
355355
_msg = state.build_message(undefined_msg, fmt_kwargs, append=append)
356-
state.do_test(Test(Feedback(_msg, state)))
356+
state.report(Feedback(_msg, state))
357357

358358
# test equality of results
359359
_msg = state.build_message(incorrect_msg, fmt_kwargs, append=append)
@@ -449,7 +449,9 @@ def has_code(state, text, pattern=True, not_typed_msg=None):
449449
student_code = state.student_code
450450

451451
_msg = state.build_message(not_typed_msg)
452-
state.do_test(StringContainsTest(student_code, text, pattern, Feedback(_msg, state)))
452+
state.do_test(
453+
StringContainsTest(student_code, text, pattern, Feedback(_msg, state))
454+
)
453455

454456
return state
455457

@@ -660,7 +662,9 @@ def has_printout(
660662
)
661663

662664
try:
663-
sol_call_ast = state.ast_dispatcher("function_calls", state.solution_ast)["print"][index]["node"]
665+
sol_call_ast = state.ast_dispatcher("function_calls", state.solution_ast)[
666+
"print"
667+
][index]["node"]
664668
except (KeyError, IndexError):
665669
raise InstructorError(
666670
"`has_printout({})` couldn't find the {} print call in your solution.".format(
@@ -748,8 +752,10 @@ def has_no_error(
748752
state.assert_root("has_no_error")
749753

750754
if state.reporter.errors:
751-
_msg = state.build_message(incorrect_msg, {"error": str(state.reporter.errors[0])})
752-
state.do_test(Test(Feedback(_msg, state)))
755+
_msg = state.build_message(
756+
incorrect_msg, {"error": str(state.reporter.errors[0])}
757+
)
758+
state.report(Feedback(_msg, state))
753759

754760
return state
755761

pythonwhat/test_funcs/utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ def call(
134134
stu_state = StubState(stu_node, state.highlighting_disabled)
135135
if (test == "error") ^ isinstance(eval_stu, Exception):
136136
_msg = state.build_message(error_msg, fmt_kwargs)
137-
state.do_test(Test(Feedback(_msg, stu_state)))
137+
state.report(Feedback(_msg, stu_state))
138138

139139
# incorrect result
140140
_msg = state.build_message(incorrect_msg, fmt_kwargs)

0 commit comments

Comments
 (0)