expose attempts to python custom grader
This commit is contained in:
@@ -2057,6 +2057,46 @@ class CustomResponseTest(ResponseTest): # pylint: disable=missing-docstring
|
||||
self.assertEqual(correctness, 'incorrect')
|
||||
self.assertEqual(msg, "Message text")
|
||||
|
||||
def test_function_code_with_attempt_number(self):
|
||||
script = textwrap.dedent("""\
|
||||
def gradeit(expect, ans, **kwargs):
|
||||
attempt = kwargs["attempt"]
|
||||
message = "This is attempt number {}".format(str(attempt))
|
||||
return {
|
||||
'input_list': [
|
||||
{ 'ok': True, 'msg': message},
|
||||
]
|
||||
}
|
||||
""")
|
||||
|
||||
problem = self.build_problem(
|
||||
script=script,
|
||||
cfn="gradeit",
|
||||
expect="42",
|
||||
cfn_extra_args="attempt"
|
||||
)
|
||||
|
||||
# first attempt
|
||||
input_dict = {'1_2_1': '42'}
|
||||
problem.context['attempt'] = 1
|
||||
correct_map = problem.grade_answers(input_dict)
|
||||
|
||||
correctness = correct_map.get_correctness('1_2_1')
|
||||
msg = correct_map.get_msg('1_2_1')
|
||||
|
||||
self.assertEqual(correctness, 'correct')
|
||||
self.assertEqual(msg, "This is attempt number 1")
|
||||
|
||||
# second attempt
|
||||
problem.context['attempt'] = 2
|
||||
correct_map = problem.grade_answers(input_dict)
|
||||
|
||||
correctness = correct_map.get_correctness('1_2_1')
|
||||
msg = correct_map.get_msg('1_2_1')
|
||||
|
||||
self.assertEqual(correctness, 'correct')
|
||||
self.assertEqual(msg, "This is attempt number 2")
|
||||
|
||||
def test_multiple_inputs_return_one_status(self):
|
||||
# When given multiple inputs, the 'answer_given' argument
|
||||
# to the check_func() is a list of inputs
|
||||
|
||||
@@ -1216,6 +1216,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
|
||||
}
|
||||
|
||||
try:
|
||||
self.lcp.context['attempt'] = self.attempts + 1
|
||||
correct_map = self.lcp.grade_answers(answers)
|
||||
self.attempts = self.attempts + 1
|
||||
self.lcp.done = True
|
||||
@@ -1678,6 +1679,7 @@ class CapaMixin(ScorableXBlockMixin, CapaFields):
|
||||
Operates by creating a new correctness map based on the current
|
||||
state of the LCP, and updating the old correctness map of the LCP.
|
||||
"""
|
||||
self.lcp.context['attempt'] = self.attempts
|
||||
new_correct_map = self.lcp.get_grade_from_current_answers(None)
|
||||
self.lcp.correct_map.update(new_correct_map)
|
||||
|
||||
|
||||
@@ -650,6 +650,7 @@ class CapaModuleTest(unittest.TestCase):
|
||||
|
||||
# Expect that the number of attempts is incremented by 1
|
||||
self.assertEqual(module.attempts, 2)
|
||||
self.assertEqual(module.lcp.context['attempt'], 2)
|
||||
|
||||
def test_submit_problem_incorrect(self):
|
||||
|
||||
@@ -668,6 +669,7 @@ class CapaModuleTest(unittest.TestCase):
|
||||
|
||||
# Expect that the number of attempts is incremented by 1
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 1)
|
||||
|
||||
def test_submit_problem_closed(self):
|
||||
module = CapaFactory.create(attempts=3)
|
||||
@@ -717,8 +719,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(result['success'], 'correct')
|
||||
|
||||
# Expect that number of attempts IS incremented
|
||||
# Expect that number of attempts IS incremented, still same attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 1)
|
||||
|
||||
def test_submit_problem_queued(self):
|
||||
module = CapaFactory.create(attempts=1)
|
||||
@@ -852,8 +855,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(expected_msg, result['success'])
|
||||
|
||||
# Expect that the number of attempts is NOT incremented
|
||||
# Expect that the number of attempts is NOT incremented, but it is 2nd attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 2)
|
||||
|
||||
def test_submit_problem_error_with_codejail_exception(self):
|
||||
|
||||
@@ -888,8 +892,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
expected_msg = 'Couldn\'t execute jailed code'
|
||||
self.assertEqual(expected_msg, result['success'])
|
||||
|
||||
# Expect that the number of attempts is NOT incremented
|
||||
# Expect that the number of attempts is NOT incremented, but it is 2nd attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 2)
|
||||
|
||||
def test_submit_problem_other_errors(self):
|
||||
"""
|
||||
@@ -957,8 +962,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
|
||||
self.assertEqual(expected_msg, result['success'])
|
||||
|
||||
# Expect that the number of attempts is NOT incremented
|
||||
# Expect that the number of attempts is NOT incremented, but it is 2nd attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 2)
|
||||
|
||||
def test_submit_problem_error_with_staff_user(self):
|
||||
|
||||
@@ -986,8 +992,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
# We DO include traceback information for staff users
|
||||
self.assertIn('Traceback', result['success'])
|
||||
|
||||
# Expect that the number of attempts is NOT incremented
|
||||
# Expect that the number of attempts is NOT incremented, but it is 2nd attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 2)
|
||||
|
||||
@ddt.data(
|
||||
("never", True, None, 'submitted'),
|
||||
@@ -1018,6 +1025,7 @@ class CapaModuleTest(unittest.TestCase):
|
||||
|
||||
# Expect that the number of attempts is incremented by 1
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 1)
|
||||
|
||||
def test_reset_problem(self):
|
||||
module = CapaFactory.create(done=True)
|
||||
@@ -1093,6 +1101,7 @@ class CapaModuleTest(unittest.TestCase):
|
||||
|
||||
# Expect that the number of attempts is not incremented
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 1)
|
||||
|
||||
def test_rescore_problem_additional_correct(self):
|
||||
# make sure it also works when new correct answer has been added
|
||||
@@ -1107,8 +1116,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
self.assertEqual(result['success'], 'incorrect')
|
||||
self.assertEqual(module.get_score(), (0, 1))
|
||||
self.assertEqual(module.correct_map[answer_id]['correctness'], 'incorrect')
|
||||
# Expect that the number of attempts is incremented
|
||||
# Expect that the number of attempts is incremented, still same attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 1)
|
||||
|
||||
# Simulate that after making an incorrect answer to the correct answer
|
||||
# the new calculated score is (1,1)
|
||||
@@ -1126,8 +1136,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
# Expect that the problem is marked correct and user earned the score
|
||||
self.assertEqual(module.get_score(), (1, 1))
|
||||
self.assertEqual(module.correct_map[answer_id]['correctness'], 'correct')
|
||||
# Expect that the number of attempts is not incremented
|
||||
# Expect that the number of attempts is not incremented, still same attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 1)
|
||||
|
||||
def test_rescore_problem_incorrect(self):
|
||||
# make sure it also works when attempts have been reset,
|
||||
@@ -1143,8 +1154,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
# Expect that the problem is marked incorrect
|
||||
self.assertEqual(module.is_correct(), False)
|
||||
|
||||
# Expect that the number of attempts is not incremented
|
||||
# Expect that the number of attempts is not incremented, still same attempt
|
||||
self.assertEqual(module.attempts, 0)
|
||||
self.assertEqual(module.lcp.context['attempt'], 0)
|
||||
|
||||
def test_rescore_problem_not_done(self):
|
||||
# Simulate that the problem is NOT done
|
||||
@@ -1174,8 +1186,9 @@ class CapaModuleTest(unittest.TestCase):
|
||||
with self.assertRaises(exception_class):
|
||||
module.rescore(only_if_higher=False)
|
||||
|
||||
# Expect that the number of attempts is NOT incremented
|
||||
# Expect that the number of attempts is NOT incremented, still same attempt
|
||||
self.assertEqual(module.attempts, 1)
|
||||
self.assertEqual(module.lcp.context['attempt'], 1)
|
||||
|
||||
def test_rescore_problem_student_input_error(self):
|
||||
self._rescore_problem_error_helper(StudentInputError)
|
||||
|
||||
Reference in New Issue
Block a user