expose attempts to python custom grader

This commit is contained in:
Peter Pinch
2018-05-07 11:36:24 -04:00
parent 2892ce6eff
commit ddd8d41906
3 changed files with 64 additions and 9 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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)