try to improve the scores pages
This commit is contained in:
+89
-37
@@ -141,7 +141,30 @@ class Answer(models.Model):
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.clean()
|
||||
return super(Answer, self).save(*args, **kwargs)
|
||||
res = super(Answer, self).save(*args, **kwargs)
|
||||
# Update matching UserAnswer objects in real-time
|
||||
status = self.status
|
||||
callstate = UserAnswer.CallStateOptions.INCORRECTCALL
|
||||
if status == Answer.MarkOptions.CORRECT:
|
||||
callstate = UserAnswer.CallStateOptions.CORRECT
|
||||
elif status == Answer.MarkOptions.HALF_MARK:
|
||||
callstate = UserAnswer.CallStateOptions.PARTIALCALL
|
||||
|
||||
UserAnswer.objects.filter(
|
||||
question=self.question,
|
||||
normal=False,
|
||||
answer_compare__iexact=self.answer_compare
|
||||
).update(score=status, callstate=callstate)
|
||||
return res
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
# Update matching UserAnswer objects back to UNMARKED in real-time
|
||||
UserAnswer.objects.filter(
|
||||
question=self.question,
|
||||
normal=False,
|
||||
answer_compare__iexact=self.answer_compare
|
||||
).update(score=Answer.MarkOptions.UNMARKED, callstate=None)
|
||||
return super(Answer, self).delete(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
if self.answer:
|
||||
@@ -823,10 +846,38 @@ class UserAnswer(UserAnswerBase):
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.clean()
|
||||
|
||||
# Auto-mark on save based on existing template answers
|
||||
q = self.question
|
||||
if q.normal != self.normal:
|
||||
self.callstate = UserAnswer.CallStateOptions.OVERCALL if q.normal else UserAnswer.CallStateOptions.UNDERCALL
|
||||
self.score = Answer.MarkOptions.INCORRECT
|
||||
elif q.normal and self.normal:
|
||||
self.callstate = UserAnswer.CallStateOptions.CORRECT
|
||||
self.score = Answer.MarkOptions.CORRECT
|
||||
else:
|
||||
ans = self.answer_compare
|
||||
if ans == "":
|
||||
self.score = Answer.MarkOptions.INCORRECT
|
||||
self.callstate = UserAnswer.CallStateOptions.INCORRECTCALL
|
||||
else:
|
||||
marked_ans = Answer.objects.filter(question_id=self.question_id, answer_compare__iexact=ans).first()
|
||||
if marked_ans is not None:
|
||||
self.score = marked_ans.status
|
||||
if marked_ans.status == Answer.MarkOptions.CORRECT:
|
||||
self.callstate = UserAnswer.CallStateOptions.CORRECT
|
||||
elif marked_ans.status == Answer.MarkOptions.HALF_MARK:
|
||||
self.callstate = UserAnswer.CallStateOptions.PARTIALCALL
|
||||
elif marked_ans.status == Answer.MarkOptions.INCORRECT:
|
||||
self.callstate = UserAnswer.CallStateOptions.INCORRECTCALL
|
||||
else:
|
||||
self.score = Answer.MarkOptions.UNMARKED
|
||||
self.callstate = None
|
||||
return super(UserAnswer, self).save(*args, **kwargs)
|
||||
|
||||
def clean(self):
|
||||
self.score = Answer.MarkOptions.UNMARKED
|
||||
if not self.score:
|
||||
self.score = Answer.MarkOptions.UNMARKED
|
||||
if self.answer:
|
||||
self.answer = self.answer.strip()
|
||||
self.answer_compare = get_answer_compare(self.answer)
|
||||
@@ -855,66 +906,67 @@ class UserAnswer(UserAnswerBase):
|
||||
return self.callstate
|
||||
|
||||
def get_answer_score(self, cached=True):
|
||||
if cached and self.score:
|
||||
print("CACHED")
|
||||
if cached and self.score and self.score != Answer.MarkOptions.UNMARKED:
|
||||
if self.score == Answer.MarkOptions.CORRECT:
|
||||
mark = 2
|
||||
return 2
|
||||
elif self.score == Answer.MarkOptions.HALF_MARK:
|
||||
mark = 1
|
||||
return 1
|
||||
elif self.score == Answer.MarkOptions.INCORRECT:
|
||||
mark = 0
|
||||
|
||||
return mark
|
||||
print("NOT CACHED")
|
||||
return 0
|
||||
|
||||
q = self.question
|
||||
|
||||
# First step we check that the normal/abnormal states match
|
||||
if q.normal != self.normal:
|
||||
if q.normal:
|
||||
self.callstate = UserAnswer.CallStateOptions.OVERCALL
|
||||
else:
|
||||
self.callstate = UserAnswer.CallStateOptions.UNDERCALL
|
||||
|
||||
self.score = Answer.MarkOptions.INCORRECT
|
||||
self.save()
|
||||
# If they don't match the answer is wrong (score is 0)
|
||||
new_callstate = UserAnswer.CallStateOptions.OVERCALL if q.normal else UserAnswer.CallStateOptions.UNDERCALL
|
||||
if self.score != Answer.MarkOptions.INCORRECT or self.callstate != new_callstate:
|
||||
self.score = Answer.MarkOptions.INCORRECT
|
||||
self.callstate = new_callstate
|
||||
self.save()
|
||||
return 0
|
||||
# If both are normal full marks
|
||||
elif q.normal and self.normal:
|
||||
self.callstate = UserAnswer.CallStateOptions.CORRECT
|
||||
self.score = Answer.MarkOptions.CORRECT
|
||||
self.save()
|
||||
if self.score != Answer.MarkOptions.CORRECT or self.callstate != UserAnswer.CallStateOptions.CORRECT:
|
||||
self.score = Answer.MarkOptions.CORRECT
|
||||
self.callstate = UserAnswer.CallStateOptions.CORRECT
|
||||
self.save()
|
||||
return 2
|
||||
|
||||
# Then compare answer strings (as per anatomy questions)
|
||||
ans = self.answer_compare
|
||||
|
||||
if ans == "":
|
||||
self.score == Answer.MarkOptions.INCORRECT
|
||||
self.save()
|
||||
if self.score != Answer.MarkOptions.INCORRECT or self.callstate != UserAnswer.CallStateOptions.INCORRECTCALL:
|
||||
self.score = Answer.MarkOptions.INCORRECT
|
||||
self.callstate = UserAnswer.CallStateOptions.INCORRECTCALL
|
||||
self.save()
|
||||
return 0
|
||||
|
||||
# TODO: this should be cleaned up as we don't want duplicates...
|
||||
# try:
|
||||
# marked_ans = q.answers.get(answer_compare__iexact=ans)
|
||||
# except Answer.DoesNotExist:
|
||||
# marked_ans = None
|
||||
marked_ans = q.answers.filter(answer_compare__iexact=ans).first()
|
||||
marked_ans = None
|
||||
for a in q.answers.all():
|
||||
if a.answer_compare.lower() == ans.lower():
|
||||
marked_ans = a
|
||||
break
|
||||
|
||||
mark = "unmarked"
|
||||
if marked_ans is not None:
|
||||
self.score = marked_ans.status
|
||||
|
||||
new_callstate = UserAnswer.CallStateOptions.INCORRECTCALL
|
||||
if marked_ans.status == Answer.MarkOptions.CORRECT:
|
||||
self.callstate = UserAnswer.CallStateOptions.CORRECT
|
||||
new_callstate = UserAnswer.CallStateOptions.CORRECT
|
||||
mark = 2
|
||||
elif marked_ans.status == Answer.MarkOptions.HALF_MARK:
|
||||
self.callstate = UserAnswer.CallStateOptions.PARTIALCALL
|
||||
new_callstate = UserAnswer.CallStateOptions.PARTIALCALL
|
||||
mark = 1
|
||||
elif marked_ans.status == Answer.MarkOptions.INCORRECT:
|
||||
self.callstate = UserAnswer.CallStateOptions.INCORRECTCALL
|
||||
new_callstate = UserAnswer.CallStateOptions.INCORRECTCALL
|
||||
mark = 0
|
||||
self.save()
|
||||
|
||||
if self.score != marked_ans.status or self.callstate != new_callstate:
|
||||
self.score = marked_ans.status
|
||||
self.callstate = new_callstate
|
||||
self.save()
|
||||
else:
|
||||
if self.score != Answer.MarkOptions.UNMARKED or self.callstate is not None:
|
||||
self.score = Answer.MarkOptions.UNMARKED
|
||||
self.callstate = None
|
||||
self.save()
|
||||
|
||||
return mark
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{% extends 'generic/exam_scores_base.html' %}
|
||||
{% extends base_template|default:'generic/exam_scores_base.html' %}
|
||||
|
||||
{% block table_answers %}
|
||||
{% for question in questions %}
|
||||
|
||||
Reference in New Issue
Block a user