Commit 6aed059d by Brian Wilson

Change date and remove filtering by grade. Add check for student_answers.

parent fe044709
...@@ -16,8 +16,7 @@ from capa.correctmap import CorrectMap ...@@ -16,8 +16,7 @@ from capa.correctmap import CorrectMap
# To narrow down the set of problems that might need fixing, the StudentModule # To narrow down the set of problems that might need fixing, the StudentModule
# objects to be checked is filtered down to those: # objects to be checked is filtered down to those:
# #
# grade=0.0 (the grade must have been zeroed out) # created < '2013-03-08 15:45:00' (the problem must have been answered before the fix was installed, on Prod and Edge)
# created < '2013-03-08 05:19:00' (the problem must have been answered before the fix was installed)
# modified > '2013-03-07 20:18:00' (the problem must have been visited after the bug was introduced) # modified > '2013-03-07 20:18:00' (the problem must have been visited after the bug was introduced)
# state like '%"npoints": 0.%' (the problem must have some form of partial credit). # state like '%"npoints": 0.%' (the problem must have some form of partial credit).
# #
...@@ -39,15 +38,16 @@ class Command(BaseCommand): ...@@ -39,15 +38,16 @@ class Command(BaseCommand):
def fix_studentmodules(self, save_changes): def fix_studentmodules(self, save_changes):
modules = StudentModule.objects.filter(# module_type='problem', modules = StudentModule.objects.filter(# module_type='problem',
modified__gt='2013-03-07 20:18:00', modified__gt='2013-03-07 20:18:00',
created__lt='2013-03-08 05:19:00', created__lt='2013-03-08 15:45:00',
state__contains='"npoints": 0.', state__contains='"npoints": 0.')
grade=0.0)
for module in modules: for module in modules:
self.fix_studentmodule(module, save_changes) self.fix_studentmodule_grade(module, save_changes)
def fix_studentmodule(self, module, save_changes): def fix_studentmodule_grade(self, module, save_changes):
module_state = module.state module_state = module.state
if module_state is None: if module_state is None:
# not likely, since we filter on it. But in general...
log.info("No state found for {type} module {id} for student {student} in course {course_id}".format( log.info("No state found for {type} module {id} for student {student} in course {course_id}".format(
**{'type':module.module_type, 'id':module.module_state_key, 'student':module.student.username, 'course_id':module.course_id})) **{'type':module.module_type, 'id':module.module_state_key, 'student':module.student.username, 'course_id':module.course_id}))
return return
...@@ -55,32 +55,50 @@ class Command(BaseCommand): ...@@ -55,32 +55,50 @@ class Command(BaseCommand):
state_dict = json.loads(module_state) state_dict = json.loads(module_state)
self.num_visited += 1 self.num_visited += 1
# LoncapaProblem.get_score() checks student_answers -- if there are none, we will return a grade of 0
# Check that this is the case, but do so sooner, before we do any of the other grading work.
student_answers = state_dict['student_answers']
if (not student_answers) or len(student_answers) == 0:
# we should not have a grade here:
if module.grade != 0:
log.error("No answer found but grade {grade} exists for {type} module {id} for student {student} in course {course_id}".format(grade=module.grade,
type=module.module_type, id=module.module_state_key, student=module.student.username, course_id=module.course_id))
else:
log.debug("No answer and no grade found for {type} module {id} for student {student} in course {course_id}".format(grade=module.grade,
type=module.module_type, id=module.module_state_key, student=module.student.username, course_id=module.course_id))
return
# load into a CorrectMap, as done in LoncapaProblem.__init__():
correct_map = CorrectMap() correct_map = CorrectMap()
if 'correct_map' in state_dict: if 'correct_map' in state_dict:
correct_map.set_dict(state_dict['correct_map']) correct_map.set_dict(state_dict['correct_map'])
# calculate score the way LoncapaProblem.get_score() works, by deferring to CorrectMap's get_npoints implementation.
correct = 0 correct = 0
for key in correct_map: for key in correct_map:
correct += correct_map.get_npoints(key) correct += correct_map.get_npoints(key)
if module.grade == correct: if module.grade == correct:
log.info("Grade matches for {type} module {id} for student {student} in course {course_id}".format( # nothing to change
**{'type':module.module_type, 'id':module.module_state_key, 'student':module.student.username, 'course_id':module.course_id})) log.debug("Grade matches for {type} module {id} for student {student} in course {course_id}".format(
type=module.module_type, id=module.module_state_key, student=module.student.username, course_id=module.course_id))
elif save_changes: elif save_changes:
# make the change
log.info("Grade changing from {0} to {1} for {type} module {id} for student {student} in course {course_id}".format( log.info("Grade changing from {0} to {1} for {type} module {id} for student {student} in course {course_id}".format(
module.grade, correct, module.grade, correct,
**{'type':module.module_type, 'id':module.module_state_key, 'student':module.student.username, 'course_id':module.course_id})) type=module.module_type, id=module.module_state_key, student=module.student.username, course_id=module.course_id))
module.grade = correct module.grade = correct
module.save() module.save()
self.num_changed += 1 self.num_changed += 1
else: else:
# don't make the change, but log that the change would be made
log.info("Grade would change from {0} to {1} for {type} module {id} for student {student} in course {course_id}".format( log.info("Grade would change from {0} to {1} for {type} module {id} for student {student} in course {course_id}".format(
module.grade, correct, module.grade, correct,
**{'type':module.module_type, 'id':module.module_state_key, 'student':module.student.username, 'course_id':module.course_id})) type=module.module_type, id=module.module_state_key, student=module.student.username, course_id=module.course_id))
self.num_changed += 1 self.num_changed += 1
def handle(self, **options): def handle(self, **options):
save_changes = 'save_changes' in options and options['save_changes'] save_changes = options['save_changes']
log.info("Starting run: save_changes = {0}".format(save_changes)) log.info("Starting run: save_changes = {0}".format(save_changes))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment