rewrite compare

This commit is contained in:
Ross
2021-01-12 17:23:19 +00:00
parent 065475b716
commit d1be8fd875
4 changed files with 61 additions and 41 deletions
+57 -38
View File
@@ -11,6 +11,8 @@ from django.utils.translation import ugettext_lazy as _
from sortedm2m.fields import SortedManyToManyField from sortedm2m.fields import SortedManyToManyField
import string
image_storage = FileSystemStorage( image_storage = FileSystemStorage(
# Physical file location ROOT # Physical file location ROOT
location=u"{0}/anatomy/".format(settings.MEDIA_ROOT), location=u"{0}/anatomy/".format(settings.MEDIA_ROOT),
@@ -164,7 +166,7 @@ class AnatomyQuestion(models.Model):
def GetUnmarkedAnswers(self): def GetUnmarkedAnswers(self):
user_answers = set( user_answers = set(
[i.get_compare_string() for i in self.cid_user_answers.all()] [i.answer_compare for i in self.cid_user_answers.all()]
) )
unmarked_answers = user_answers - self.GetMarkedAnswers() unmarked_answers = user_answers - self.GetMarkedAnswers()
@@ -176,7 +178,7 @@ class AnatomyQuestion(models.Model):
def GetMarkedAnswers(self): def GetMarkedAnswers(self):
return set( return set(
[ [
i.get_compare_string() i.answer_compare
for i in self.answers.all() for i in self.answers.all()
if i.status != i.MarkOptions.UNMARKED if i.status != i.MarkOptions.UNMARKED
] ]
@@ -200,6 +202,7 @@ class Answer(models.Model):
AnatomyQuestion, related_name="answers", on_delete=models.CASCADE AnatomyQuestion, related_name="answers", on_delete=models.CASCADE
) )
answer = models.TextField(max_length=500) answer = models.TextField(max_length=500)
answer_compare = models.TextField(max_length=500)
class MarkOptions(models.TextChoices): class MarkOptions(models.TextChoices):
UNMARKED = "", _("Unmarked") UNMARKED = "", _("Unmarked")
@@ -218,8 +221,15 @@ class Answer(models.Model):
if self.answer: if self.answer:
self.answer = self.answer.strip() self.answer = self.answer.strip()
def get_compare_string(self): s = self.answer.lower()
return self.answer.lower().strip() s = s.translate(str.maketrans('', '', string.punctuation))
self.answer_compare = s
# def get_compare_string(self):
# s = self.answer.lower().strip()
# s = s.translate(str.maketrans('', '', string.punctuation))
# return s
# class HalfMarkAnswers(models.Model): # class HalfMarkAnswers(models.Model):
@@ -288,39 +298,39 @@ class Exam(models.Model):
return list(self.exam_questions.all()).index(question) return list(self.exam_questions.all()).index(question)
class UserAnswer(models.Model): # class UserAnswer(models.Model):
question = models.ForeignKey( # question = models.ForeignKey(
AnatomyQuestion, related_name="user_answers", on_delete=models.CASCADE # AnatomyQuestion, related_name="user_answers", on_delete=models.CASCADE
) # )
answer = models.TextField(max_length=500, blank=True) # answer = models.TextField(max_length=500, blank=True)
user = models.ForeignKey( # user = models.ForeignKey(
settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL # settings.AUTH_USER_MODEL, null=True, blank=True, on_delete=models.SET_NULL
) # )
cid = models.BigIntegerField(blank=True, null=True, help_text="Candidate ID (limitied by BigIntegerField size)") # cid = models.BigIntegerField(blank=True, null=True, help_text="Candidate ID (limitied by BigIntegerField size)")
# Each user answer is associated with a particular exam # # Each user answer is associated with a particular exam
exam = models.ForeignKey( # exam = models.ForeignKey(
Exam, related_name="exam", on_delete=models.CASCADE, null=True # Exam, related_name="exam", on_delete=models.CASCADE, null=True
) # )
flagged = models.BooleanField(default=False) # flagged = models.BooleanField(default=False)
created = models.DateTimeField(auto_now_add=True) # created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True) # updated = models.DateTimeField(auto_now=True)
def __str__(self): # def __str__(self):
try: # try:
exam = self.exam # exam = self.exam
except (Exam.DoesNotExist, KeyError) as e: # except (Exam.DoesNotExist, KeyError) as e:
exam = "None" # exam = "None"
return "{}/{}/{}: {}".format( # return "{}/{}/{}: {}".format(
exam, self.cid, self.question.GetPrimaryAnswer(), self.answer # exam, self.cid, self.question.GetPrimaryAnswer(), self.answer
) # )
def clean(self): # def clean(self):
if self.answer: # if self.answer:
self.answer = self.answer.strip() # self.answer = self.answer.strip()
class CidUserAnswer(models.Model): class CidUserAnswer(models.Model):
@@ -331,6 +341,8 @@ class CidUserAnswer(models.Model):
) )
answer = models.TextField(max_length=500, blank=True) answer = models.TextField(max_length=500, blank=True)
answer_compare = models.TextField(max_length=500, blank=True)
cid = models.BigIntegerField(blank=True, null=True, help_text="Candidate ID (limitied by BigIntegerField size)") cid = models.BigIntegerField(blank=True, null=True, help_text="Candidate ID (limitied by BigIntegerField size)")
# Each user answer is associated with a particular exam # Each user answer is associated with a particular exam
@@ -354,29 +366,36 @@ class CidUserAnswer(models.Model):
if self.answer: if self.answer:
self.answer = self.answer.strip() self.answer = self.answer.strip()
def get_compare_string(self): s = self.answer.lower()
# strip here should be unneccasry (providing clean is now working) s = s.translate(str.maketrans('', '', string.punctuation))
return self.answer.lower().strip()
self.answer_compare = s
# def get_compare_string(self):
# # strip here should be unneccasry (providing clean is now working)
# s = self.answer.lower().strip()
# s = s.translate(str.maketrans('', '', string.punctuation))
# return s
def get_answer_score(self): def get_answer_score(self):
q = self.question q = self.question
ans = self.answer ans = self.answer_compare
if ( if (
q.answers.filter( q.answers.filter(
answer__iexact=ans, status=Answer.MarkOptions.CORRECT answer_compare__iexact=ans, status=Answer.MarkOptions.CORRECT
).first() ).first()
is not None is not None
): ):
mark = 2 mark = 2
elif ( elif (
q.answers.filter( q.answers.filter(
answer__iexact=ans, status=Answer.MarkOptions.HALF_MARK answer_compare__iexact=ans, status=Answer.MarkOptions.HALF_MARK
).first() ).first()
is not None is not None
): ):
mark = 1 mark = 1
elif q.answers.filter( elif q.answers.filter(
answer__iexact=ans, status=Answer.MarkOptions.INCORRECT answer_compare__iexact=ans, status=Answer.MarkOptions.INCORRECT
).first(): ).first():
mark = 0 mark = 0
else: else:
+2 -2
View File
@@ -32,7 +32,7 @@ from .forms import (
AnatomyQuestionForm, AnatomyQuestionForm,
StructureForm, StructureForm,
) )
from .models import ( # from .models import (
AnatomyQuestion, AnatomyQuestion,
BodyPart, BodyPart,
CidUserAnswer, CidUserAnswer,
@@ -401,7 +401,7 @@ def mark(request, pk, sk):
answers_dict = {} answers_dict = {}
for ans in question.answers.all(): for ans in question.answers.all():
answers_dict[ans.get_compare_string()] = ans answers_dict[ans.answer_compare] = ans
marked_answers_set = set(answers_dict.keys()) marked_answers_set = set(answers_dict.keys())
+1 -1
View File
@@ -14,7 +14,7 @@
Publish results: <input type="checkbox" id="exam-publish-results-switch" {% if exam.publish_results %}checked{% endif %}> <span class="help-text">[When checked the exam results will be available on this site]</span> Publish results: <input type="checkbox" id="exam-publish-results-switch" {% if exam.publish_results %}checked{% endif %}> <span class="help-text">[When checked the exam results will be available on this site]</span>
</div> </div>
<!--<p><button><a href="{% url 'anatomy:exam_take' pk=exam.pk sk=0 %}">Click here to start</a></button></p>--> <!--<p><button><a href="{% url 'anatomy:exam_take' pk=exam.pk sk=0 %}">Click here to start</a></button></p>-->
This exam will be available to take <a href="{% url 'physics:exam_take' pk=exam.pk %}">here</a>. This exam will be available to take <a href="{% url 'physics:exam_take' pk=exam.pk %}">here</a> (when active).
{% autoescape off %} {% autoescape off %}
<ol id="full-question-list"> <ol id="full-question-list">
@@ -7,6 +7,7 @@
</div> </div>
<div id="stats-block"> <div id="stats-block">
<h2>Stats</h2> <h2>Stats</h2>
Candidates: {{cids|length}}<br />
Max score: {{max_score}}<br /> Max score: {{max_score}}<br />
Mean: {{mean}}, Median {{median}}, Mode {{mode}} Mean: {{mean}}, Median {{median}}, Mode {{mode}}