Skip to content

Commit 54b771d

Browse files
Merge pull request #7 from lambda-feedback/tr172-better-feedback-when-answer-or-response-is-not-a-number
Added improved error messages and feedback when response or answer co…
2 parents d15cea5 + e10ce5d commit 54b771d

File tree

3 files changed

+51
-17
lines changed

3 files changed

+51
-17
lines changed

app/docs/user.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This function is used to compare two number arrays/vectors/matrices, provided absolute and/or relative tolerance parameters `rtol` and `atol`. This is carried out using the [numpy.allclose](https://numpy.org/doc/stable/reference/generated/numpy.allclose.html) function.
44

5+
If the answer is not an array of numbers an exception is raised. If the response is not an array of numbers, a feedback message that informs the user that only numbers are accepte will be generated.
6+
57
### Optional parameters
68

79
There is one optional parameter: `feedback_for_incorrect_response`.

app/evaluation.py

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,29 +23,41 @@ def evaluation_function(response, answer, params) -> dict:
2323
to output the grading response.
2424
"""
2525

26-
answer_ok = process_element(answer)
27-
if not answer_ok:
26+
try:
27+
process_element(answer)
28+
except ValueError:
29+
raise Exception("Answer has at least one field that is not a number.")
30+
except Exception:
2831
raise Exception("Answer has empty fields.")
29-
response_ok = process_element(response)
30-
if not response_ok:
32+
return {"is_correct": False}
33+
34+
feedback = ""
35+
try:
36+
process_element(response)
37+
except ValueError:
38+
feedback = "Only numbers are permitted."
39+
except Exception:
40+
feedback = "Response has at least one empty field."
41+
42+
if len(feedback) > 0:
3143
return {
3244
"is_correct": False,
33-
"feedback": "Response has empty fields."
45+
"feedback": feedback,
3446
}
3547

3648
try:
37-
res = np.array(response, dtype=np.float32)
38-
except Exception as e:
49+
ans = np.array(answer, dtype=np.float32)
50+
except ValueError as e:
3951
raise EvaluationException(
40-
f"Failed to parse user response",
52+
f"Failed to parse correct answer",
4153
detail=repr(e)
4254
)
4355

4456
try:
45-
ans = np.array(answer, dtype=np.float32)
46-
except Exception as e:
57+
res = np.array(response, dtype=np.float32)
58+
except ValueError as e:
4759
raise EvaluationException(
48-
f"Failed to parse correct answer",
60+
f"Failed to parse response",
4961
detail=repr(e)
5062
)
5163

@@ -65,14 +77,14 @@ def evaluation_function(response, answer, params) -> dict:
6577

6678
def process_element(element):
6779
is_ok = True
68-
if isinstance(element,list):
80+
if isinstance(element, list):
6981
for e in element:
70-
is_ok = process_element(e)
82+
process_element(e)
7183
else:
72-
if isinstance(element,str):
84+
if isinstance(element, str):
7385
element = element.strip()
7486
if len(element) == 0 or "element" == "undefined":
75-
is_ok = False
87+
raise Exception("Contains an empty element")
7688
else:
7789
element = float(element)
78-
return is_ok
90+
return

app/evaluation_tests.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ def test_2D_empty_string_in_response(self):
4444
response = evaluation_function(response, answer, {})
4545

4646
self.assertEqual(response["is_correct"], False)
47-
self.assertEqual(response["feedback"], "Response has empty fields.")
47+
self.assertEqual(response["feedback"], "Response has at least one empty field.")
4848

4949
def test_no_tolerance_correct(self):
5050
response = [1, 2]
@@ -132,6 +132,26 @@ def test_2D_incorrect_with_custom_feedback(self):
132132
#
133133
# self.assertEqual(response.get("is_correct"), True)
134134

135+
def test_answer_not_array_of_numbers(self):
136+
response = [[1, 1], [1, 1]]
137+
answer = [[1, 1], [1, "a"]]
138+
139+
self.assertRaises(
140+
Exception,
141+
evaluation_function,
142+
response,
143+
answer,
144+
{},
145+
)
146+
147+
def test_response_not_array_of_numbers(self):
148+
response = [[1, 1], [1, "a"]]
149+
answer = [[1, 1], [1, 0]]
150+
151+
response = evaluation_function(response, answer, {})
152+
153+
self.assertEqual(response.get("is_correct"), False)
154+
self.assertEqual(response["feedback"], "Only numbers are permitted.")
135155

136156
if __name__ == "__main__":
137157
unittest.main()

0 commit comments

Comments
 (0)