Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

modified regrading script to change raw score, examscore and lateness

  • Loading branch information...
commit 7741c2045e40f506e16b9b3ee47210c66a7fcf22 1 parent 1c84735
Jason Bau authored
View
1  .gitignore
@@ -1,3 +1,4 @@
+db-dumps/
main/database.py
venv_c2g
View
1  main/c2g/models.py
@@ -2374,6 +2374,7 @@ class ExamScore(TimestampMixin, models.Model):
score = models.FloatField(null=True, blank=True) #this is the score over the whole exam, with penalities applied
csv_imported = models.BooleanField(default=False)
#can have subscores corresponding to these, of type ExamScoreField. Creating new class to do notion of list.
+ #TODO: Add ForeignKey to which ExamRecord is responsible for this score, per GHI #2029
def __unicode__(self):
return (self.student.username + ":" + self.course.title + ":" + self.exam.title + ":" + str(self.score))
View
62 main/courses/management/commands/regrade.py
@@ -6,8 +6,9 @@
from django.core.management.base import BaseCommand, CommandError
from django.conf import settings
-from c2g.models import ExamRecord, Exam
+from c2g.models import ExamRecord, Exam, ExamScore
from courses.exams.autograder import *
+from courses.exams.views import compute_penalties
class Command(BaseCommand):
args = "<exam id>"
@@ -37,11 +38,12 @@ def handle(self, *args, **options):
end = parser.parse("1/1/2038") # almost the end of unix time
if 'end_time' in options and options['end_time']:
end = parser.parse(options['end_time'])
-
- exam_rec = Exam.objects.get(id__exact=examid)
- autograder = AutoGrader(exam_rec.xml_metadata)
+ #used to be called exam_rec, which was just to confusing with ExamRecords around
+ exam_obj = Exam.objects.get(id__exact=examid)
+ autograder = AutoGrader(exam_obj.xml_metadata)
examRecords = ExamRecord.objects\
+ .select_related('examrecordscore', 'student')\
.filter(exam_id__exact=examid, complete=True)\
.filter(time_created__gt=start)\
.filter(time_created__lt=end)
@@ -51,13 +53,18 @@ def handle(self, *args, **options):
count = 1
for er in examRecords:
+ ers = er.examrecordscore
print "ExamRecord %d, %d of %d" % (er.id, count, len(examRecords))
count += 1
try:
score_before = er.score
+ rawscore_before = ers.raw_score
if score_before == None: # scores of 0 come back from model as None
score_before = 0.0 # not sure why but they do
+ if rawscore_before == None: # scores of 0 come back from model as None
+ rawscore_before = 0.0 # not sure why but they do
score_after = 0.0
+ rawscore_after = 0.0
submitted = json.loads(er.json_data)
regrade = {}
for prob, v in submitted.iteritems():
@@ -70,22 +77,51 @@ def handle(self, *args, **options):
if 'feedback' in regrade[prob]:
del regrade[prob]['feedback'] # remove giant feedback field
if 'score' in regrade[prob]:
- score_after += float(regrade[prob]['score'])
-
+ rawscore_after += float(regrade[prob]['score'])
+
+ is_late = er.time_created > exam_obj.grace_period
+ score_after = compute_penalties(rawscore_after, er.attempt_number,
+ exam_obj.resubmission_penalty,
+ is_late, exam_obj.late_penalty)
s = er.student
- status_line = "%d, \"%s\", \"%s\", %s, %s, %s, %0.1f, %0.1f" \
+
+ try:
+ es = ExamScore.objects.get(exam=exam_obj, student=s)
+ examscore_before = es.score
+ except ExamScore.DoesNotExist:
+ examscore_before = -1
+ examscore_after = max(examscore_before, score_after)
+
+ #raw = raw score, score = with penalties, agg = exam_score, over all attempts
+ status_line = "%d, \"%s\", \"%s\", %s, %s, %s, raw:%0.1f->%0.1f score:%0.1f->%0.1f agg:%0.1f->%0.1f late:%d->%d" \
% (er.id, s.first_name, s.last_name, s.username, s.email,
- str(er.time_created), score_before, score_after)
- if score_before == score_after:
+ str(er.time_created), rawscore_before, rawscore_after,
+ score_before, score_after, examscore_before, examscore_after,
+ er.late, is_late)
+
+ if score_before == score_after and rawscore_before == rawscore_after \
+ and examscore_before == examscore_after and is_late == er.late :
print "OK: " + status_line
continue
+
regrades += 1
print "REGRADE: " + status_line
+
if not options['dryrun']:
- er.json_score_data = json.dumps(regrade)
- er.score = score_after
- er.save()
- updates += 1
+ if score_before != score_after or is_late != er.late:
+ er.json_score_data = json.dumps(regrade)
+ er.score = score_after
+ er.late = is_late
+ er.save()
+ updates += 1
+ if rawscore_before != rawscore_after:
+ ers.raw_score = rawscore_after
+ ers.save()
+ updates += 1
+ if examscore_before != examscore_after:
+ es.score = examscore_after
+ es.save()
+ updates += 1
# exception handler around big ExamRecords loop -- trust me, it lines up
# this just counts and skips offending rows so we can keep making progress
Please sign in to comment.
Something went wrong with that request. Please try again.