start combining answers

This commit is contained in:
Ross
2020-11-06 17:30:07 +00:00
parent 71dc80e9d2
commit bcb289efdd
3 changed files with 109 additions and 72 deletions
+12 -14
View File
@@ -3,9 +3,7 @@ from .models import (
AnatomyQuestion, AnatomyQuestion,
Examination, Examination,
QuestionType, QuestionType,
Answers, Answer,
HalfMarkAnswers,
IncorrectAnswers,
CidUserAnswer, CidUserAnswer,
Exam, Exam,
Modality, Modality,
@@ -17,18 +15,18 @@ from reversion.admin import VersionAdmin
# Register your models here. # Register your models here.
class AnatomyAnswersInline(admin.TabularInline): class AnatomyAnswersInline(admin.TabularInline):
model = Answers model = Answer
extra = 1 extra = 1
class HalfMarkAnatomyAnswersInline(admin.TabularInline): #class HalfMarkAnatomyAnswersInline(admin.TabularInline):
model = HalfMarkAnswers # model = HalfMarkAnswers
extra = 1 # extra = 1
#
#
class IncorrectAnatomyAnswersInline(admin.TabularInline): #class IncorrectAnatomyAnswersInline(admin.TabularInline):
model = IncorrectAnswers # model = IncorrectAnswers
extra = 1 # extra = 1
class ExamInline(admin.TabularInline): class ExamInline(admin.TabularInline):
@@ -39,8 +37,8 @@ class ExamInline(admin.TabularInline):
class AnatomyAdmin(VersionAdmin): class AnatomyAdmin(VersionAdmin):
inlines = [ inlines = [
AnatomyAnswersInline, AnatomyAnswersInline,
HalfMarkAnatomyAnswersInline, #HalfMarkAnatomyAnswersInline,
IncorrectAnatomyAnswersInline, #IncorrectAnatomyAnswersInline,
ExamInline, ExamInline,
] ]
+50 -30
View File
@@ -74,10 +74,12 @@ class AnatomyQuestion(models.Model):
examination = models.ForeignKey(Examination, examination = models.ForeignKey(Examination,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, blank=True) null=True,
blank=True)
modality = models.ForeignKey(Modality, modality = models.ForeignKey(Modality,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, help_text="Modality of the image") null=True,
help_text="Modality of the image")
body_part = models.ForeignKey(BodyPart, body_part = models.ForeignKey(BodyPart,
on_delete=models.SET_NULL, on_delete=models.SET_NULL,
null=True, null=True,
@@ -107,16 +109,19 @@ class AnatomyQuestion(models.Model):
if not unmarked_answers: if not unmarked_answers:
return "No answers to mark" return "No answers to mark"
return format_html("<span class='warn'>{} answer unmarked:</span> {}".format(len(unmarked_answers), return format_html(
", ".join(unmarked_answers))) "<span class='warn'>{} answer unmarked:</span> {}".format(
len(unmarked_answers), ", ".join(unmarked_answers)))
def GetUnmarkedAnswers(self): def GetUnmarkedAnswers(self):
user_answers = set([i.answer.lower() for i in self.cid_user_answers.all()]) user_answers = set(
[i.get_compare_string() for i in self.cid_user_answers.all()])
unmarked_answers = user_answers - self.GetMarkedAnswers() unmarked_answers = user_answers - self.GetMarkedAnswers()
return unmarked_answers return unmarked_answers
def GetMarkedAnswers(self): def GetMarkedAnswers(self):
return set([i.get_compare_string() for i in self.answers.all() if i.status != i.MarkOptions.UNMARKED])
correct_answers = set([i.answer.lower() for i in self.answers.all()]) correct_answers = set([i.answer.lower() for i in self.answers.all()])
half_mark_answers = set( half_mark_answers = set(
[i.answer.lower() for i in self.half_mark_answers.all()]) [i.answer.lower() for i in self.half_mark_answers.all()])
@@ -127,25 +132,19 @@ class AnatomyQuestion(models.Model):
return marked_answers return marked_answers
class Answers(models.Model): class Answer(models.Model):
question = models.ForeignKey(AnatomyQuestion, question = models.ForeignKey(AnatomyQuestion,
related_name="answers", related_name="answers",
on_delete=models.CASCADE) on_delete=models.CASCADE)
answer = models.CharField(max_length=500) answer = models.CharField(max_length=500)
def __str__(self): class MarkOptions(models.TextChoices):
return self.answer UNMARKED = '', _('Unmarked')
INCORRECT = '0', _('Incorrect')
HALF_MARK = '1', _('Half mark')
CORRECT = '2', _('Correct')
def clean(self): status = models.CharField(max_length=1, choices=MarkOptions.choices, default=MarkOptions.UNMARKED)
if self.answer:
self.answer.strip()
class HalfMarkAnswers(models.Model):
question = models.ForeignKey(AnatomyQuestion,
related_name="half_mark_answers",
on_delete=models.CASCADE)
answer = models.CharField(max_length=500)
def __str__(self): def __str__(self):
return self.answer return self.answer
@@ -154,19 +153,36 @@ class HalfMarkAnswers(models.Model):
if self.answer: if self.answer:
self.answer.strip() self.answer.strip()
def get_compare_string(self):
return self.answer.lower()
class IncorrectAnswers(models.Model):
question = models.ForeignKey(AnatomyQuestion,
related_name="incorrect_answers",
on_delete=models.CASCADE)
answer = models.CharField(max_length=500)
def __str__(self): #class HalfMarkAnswers(models.Model):
return self.answer # question = models.ForeignKey(AnatomyQuestion,
# related_name="half_mark_answers",
def clean(self): # on_delete=models.CASCADE)
if self.answer: # answer = models.CharField(max_length=500)
self.answer.strip() #
# def __str__(self):
# return self.answer
#
# def clean(self):
# if self.answer:
# self.answer.strip()
#
#
#class IncorrectAnswers(models.Model):
# question = models.ForeignKey(AnatomyQuestion,
# related_name="incorrect_answers",
# on_delete=models.CASCADE)
# answer = models.CharField(max_length=500)
#
# def __str__(self):
# return self.answer
#
# def clean(self):
# if self.answer:
# self.answer.strip()
class Exam(models.Model): class Exam(models.Model):
@@ -174,7 +190,8 @@ class Exam(models.Model):
exam_questions = models.ManyToManyField(AnatomyQuestion, exam_questions = models.ManyToManyField(AnatomyQuestion,
related_name="exams") related_name="exams")
active = models.BooleanField(help_text="If an exam should be available", default=True) active = models.BooleanField(help_text="If an exam should be available",
default=True)
def __str__(self): def __str__(self):
return self.name return self.name
@@ -251,3 +268,6 @@ class CidUserAnswer(models.Model):
def clean(self): def clean(self):
if self.answer: if self.answer:
self.answer.strip() self.answer.strip()
def get_compare_string(self):
return self.answer.lower()
+44 -25
View File
@@ -16,9 +16,9 @@ from .models import (
CidUserAnswer, CidUserAnswer,
UserAnswer, UserAnswer,
Exam, Exam,
Answers, Answer,
HalfMarkAnswers, #HalfMarkAnswers,
IncorrectAnswers, #IncorrectAnswers,
) )
from collections import defaultdict from collections import defaultdict
@@ -235,14 +235,13 @@ def loadJsonAnswer(answer):
if not exam.active: if not exam.active:
return JsonResponse({ return JsonResponse({
"success": "success": False,
False, "error": "No active exam: {}".format(answer["eid"])
"error":
"No active exam: {}".format(answer["eid"])
}) })
exiting_answers = CidUserAnswer.objects.filter( exiting_answers = CidUserAnswer.objects.filter(question__id=answer["qid"],
question__id=answer["qid"], exam__id=answer["eid"], cid=answer["cid"]) exam__id=answer["eid"],
cid=answer["cid"])
if not exiting_answers: if not exiting_answers:
ans = CidUserAnswer(answer=answer["ans"], cid=answer["cid"]) ans = CidUserAnswer(answer=answer["ans"], cid=answer["cid"])
@@ -311,18 +310,35 @@ def mark(request, pk, sk):
except IndexError: except IndexError:
raise Http404("Exam question does not exist") raise Http404("Exam question does not exist")
correct_answers = [i.answer.lower() for i in question.answers.all()] answers_dict = {}
half_correct_answers = [i.answer.lower() for i in question.half_mark_answers.all()]
incorrect_answers = [i.answer.lower() for i in question.incorrect_answers.all()] for ans in question.answer.all():
answers_dict[ans.get_compare_string()] = ans
marked_answers_set = set(answers_dict.keys())
#correct_answers = [i.answer.lower() for i in question.answers.all()]
#half_correct_answers = [
# i.answer.lower() for i in question.half_mark_answers.all()
#]
#incorrect_answers = [
# i.answer.lower() for i in question.incorrect_answers.all()
#]
# It's probably better to do some processing/checking in the model
user_answers = (set([
i.answer.lower()
for i in question.cid_user_answers.all() if i.strip() != ""
]) - marked_answers_set) # .filter(user=User)
user_answers = (set([i.answer.lower() for i in question.cid_user_answers.all()]) -
set(correct_answers) - set(half_correct_answers) -
set(incorrect_answers)) # .filter(user=User)
user_answers = set([i for i in user_answers if i.strip() != ""])
if request.method == "POST": if request.method == "POST":
form = MarkAnatomyQuestionForm(request.POST) form = MarkAnatomyQuestionForm(request.POST)
# *******************************
# TODO: convert to JSON request
# *******************************
if form.is_valid(): if form.is_valid():
cd = form.cleaned_data cd = form.cleaned_data
# correct = cd.get("correct") # correct = cd.get("correct")
@@ -389,23 +405,25 @@ def mark(request, pk, sk):
}, },
) )
def active_exams(request): def active_exams(request):
exams = Exam.objects.all() exams = Exam.objects.all()
print(exams) print(exams)
active_exams = { active_exams = {"exams": []}
"exams" : []
}
for exam in exams: for exam in exams:
if exam.active: if exam.active:
active_exams["exams"].append({ active_exams["exams"].append({
"name": exam.get_exam_name(), "name":
"url": request.build_absolute_uri(exam.get_json_url()), exam.get_exam_name(),
"url":
request.build_absolute_uri(exam.get_json_url()),
}) })
return JsonResponse(active_exams) return JsonResponse(active_exams)
def exam_json(request, pk): def exam_json(request, pk):
exam = get_object_or_404(Exam, pk=pk) exam = get_object_or_404(Exam, pk=pk)
@@ -462,10 +480,11 @@ def exam_scores_cid(request, pk):
continue continue
ans = s[0].answer ans = s[0].answer
if ans.lower() in q.answers.all().values_list(Lower("answer"), flat=True): if ans.lower() in q.answers.all().values_list(Lower("answer"),
a = 2
elif ans.lower() in q.half_mark_answers.all().values_list(Lower("answer"),
flat=True): flat=True):
a = 2
elif ans.lower() in q.half_mark_answers.all().values_list(
Lower("answer"), flat=True):
a = 1 a = 1
else: else:
a = 0 a = 0