shorts might now be functional?

This commit is contained in:
Ross
2025-04-28 12:15:31 +01:00
parent 405b17776f
commit 06e66ad52c
18 changed files with 901 additions and 234 deletions
@@ -43,7 +43,7 @@
<h3>Stats</h3>
Candidates: {{cids|length}}<br />
Questions: <span id="question-number">{{question_number}}</span><br />
Available marks: {{max_score}}<br />
<span title="Max score">Available marks: {{max_score}}</span><br />
Mean: {{mean}}, Median {{median}}, Mode {{mode}}<br />
Top score: {{exam.stats_max}}
+73 -35
View File
@@ -571,39 +571,44 @@ class ExamViews(View, LoginRequiredMixin):
if (
self.app_name == "rapids"
and not user.groups.filter(name="rapid_checker").exists()
and user.groups.filter(name="rapid_checker").exists()
):
return False
return True
if (
self.app_name == "shorts"
and user.groups.filter(name="shorts").exists()
):
return True
if (
self.app_name == "anatomy"
and not user.groups.filter(
name__in=("anatomy_checker", "anatomy_marker")
and user.groups.filter(
name__in=("anatomy_checker", "anatomy_marker")
).exists()
):
return False
return True
if (
self.app_name == "longs"
and not user.groups.filter(
name__in=("long_checker", "long_marker")
and user.groups.filter(
name__in=("long_checker", "long_marker")
).exists()
):
return False
return True
if (
self.app_name == "physics"
and not user.groups.filter(name="physics_checker").exists()
and user.groups.filter(name="physics_checker").exists()
):
return False
return True
if (
self.app_name == "sbas"
and not user.groups.filter(name="sba_checker").exists()
and user.groups.filter(name="sba_checker").exists()
):
return False
return True
if (
self.app_name == "atlas"
and not user.groups.filter(name="casecollection_checker").exists()
and user.groups.filter(name="casecollection_checker").exists()
):
return False
return True
return True
return False
def check_user_marker_access(self, user: User, exam_id: int = None):
return self.check_user_access(user, exam_id, marker=True)
@@ -1367,6 +1372,7 @@ class ExamViews(View, LoginRequiredMixin):
app_exam_map = {}
app_exam_map["rapids"] = cid_user.rapid_exams
app_exam_map["shorts"] = cid_user.shorts_exams
app_exam_map["anatomy"] = cid_user.anatomy_exams
app_exam_map["longs"] = cid_user.longs_exams
app_exam_map["physics"] = cid_user.physics_exams
@@ -1849,6 +1855,24 @@ class ExamViews(View, LoginRequiredMixin):
ans.answer = ""
elif answer["qidn"] == "2" and not ans.normal:
ans.answer = posted_answer
case "shorts":
if not existing_answers:
if uid:
ans = self.UserAnswer(
answer=posted_answer, user=User.objects.get(id=uid)
)
else:
ans = self.UserAnswer(answer=posted_answer, cid=cid)
ans.question_id = answer["qid"]
ans.exam_id = eid
ans.score = None
else:
# Update an existing answer
# should never be more than one (famous last words)
ans = existing_answers[0]
ans.answer = posted_answer
ans.score = None
case "anatomy":
if not existing_answers:
if uid:
@@ -2275,15 +2299,7 @@ class ExamViews(View, LoginRequiredMixin):
else:
total_score = sum(answers_marks)
match self.app_name:
case "rapids" | "anatomy":
max_score = len(questions) * 2
case "longs":
max_score = len(questions) * 8
case "physics":
max_score = len(questions) * 5
case _:
max_score = len(questions)
max_score = self.get_max_score(questions)
#cid_user_exam = exam.cid_user_exam.filter(user_user=user).first()
#print(user)
@@ -2314,6 +2330,18 @@ class ExamViews(View, LoginRequiredMixin):
template_context,
)
def get_max_score(self, questions):
match self.app_name:
case "rapids" | "anatomy":
max_score = len(questions) * 2
case "longs":
max_score = len(questions) * 8
case "physics" | "shorts":
max_score = len(questions) * 5
case _:
max_score = len(questions)
return max_score
def exam_scores_all(self, request, pk):
"""The exam scores pages. Displays all user scores in a tabular format.
@@ -2349,13 +2377,14 @@ class ExamViews(View, LoginRequiredMixin):
cached_scores = True
valid_cid_users = set(exam.valid_cid_users.all().values_list("cid", flat=True))
print(valid_cid_users)
valid_user_users = set(exam.valid_user_users.all().values_list("pk", flat=True))
if self.app_name in ("rapids"):
user_answers_callstates = defaultdict(list)
user_answers_callstates_counted = {}
if self.app_name in ("physics", "sbas", "longs"):
if self.app_name in ("physics", "sbas", "longs", "shorts"):
cached_scores = False
questions = exam.get_questions()
else:
@@ -2420,7 +2449,7 @@ class ExamViews(View, LoginRequiredMixin):
callstate = s.get_answer_callstate()
by_question[q][cid] = (ans, answer_score, callstate)
user_answers_callstates[cid].append(callstate)
elif self.app_name in ("anatomy", "sbas", "longs"):
elif self.app_name in ("anatomy", "sbas", "longs", "shorts"):
by_question[q][cid] = (ans, answer_score)
else:
zipped_ans_scores = zip(ans, answer_score)
@@ -2442,13 +2471,13 @@ class ExamViews(View, LoginRequiredMixin):
by_question[question][user] = ("Not answered", 3.0)
user_answers_marks[user].append(3.0)
if self.app_name in ("rapids", "anatomy", "sbas", "longs"):
if self.app_name in ("physics",):
user_scores[user] = sum(
[i for i in user_answers_marks[user] if i != "unmarked"]
[sum(i) for i in user_answers_marks[user] if i != "unmarked"]
)
else:
user_scores[user] = sum(
[sum(i) for i in user_answers_marks[user] if i != "unmarked"]
[i for i in user_answers_marks[user] if i != "unmarked" and i != None]
)
if self.app_name == "rapids":
@@ -2463,12 +2492,7 @@ class ExamViews(View, LoginRequiredMixin):
# ignore scores of 0 for stats
user_scores_list = [i for i in user_scores.values() if i > 0]
if self.app_name in ("rapids", "anatomy"):
max_score = question_number * 2
elif self.app_name == "physics":
max_score = question_number * 5
else:
max_score = question_number
max_score = self.get_max_score(questions)
if len(user_scores_list) < 1:
mean = 0
@@ -2842,6 +2866,7 @@ class CidUserExamView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
physics_exams = [(i.name, i.pk) for i in PhysicsExam.objects.filter(**filters)]
rapid_exams = [(i.name, i.pk) for i in RapidsExam.objects.filter(**filters)]
shorts_exams = [(i.name, i.pk) for i in ShortsExam.objects.filter(**filters)]
sba_exams = [(i.name, i.pk) for i in SbasExam.objects.filter(**filters)]
longs_exams = [(i.name, i.pk) for i in LongsExam.objects.filter(**filters)]
anatomy_exams = [(i.name, i.pk) for i in AnatomyExam.objects.filter(**filters)]
@@ -2856,6 +2881,7 @@ class CidUserExamView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
context["physics_exams"] = physics_exams
context["rapid_exams"] = rapid_exams
context["shorts_exams"] = shorts_exams
context["sba_exams"] = sba_exams
context["longs_exams"] = longs_exams
context["anatomy_exams"] = anatomy_exams
@@ -2880,6 +2906,7 @@ class CidUserView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
physics_exams = [(i.name, i.pk) for i in PhysicsExam.objects.filter(**filters)]
rapid_exams = [(i.name, i.pk) for i in RapidsExam.objects.filter(**filters)]
shorts_exams = [(i.name, i.pk) for i in ShortsExam.objects.filter(**filters)]
sba_exams = [(i.name, i.pk) for i in SbasExam.objects.filter(**filters)]
longs_exams = [(i.name, i.pk) for i in LongsExam.objects.filter(**filters)]
anatomy_exams = [(i.name, i.pk) for i in AnatomyExam.objects.filter(**filters)]
@@ -2890,6 +2917,7 @@ class CidUserView(CidManagerRequiredMixin, SingleTableMixin, FilterView):
context["physics_exams"] = physics_exams
context["rapid_exams"] = rapid_exams
context["shorts_exams"] = shorts_exams
context["sba_exams"] = sba_exams
context["longs_exams"] = longs_exams
context["anatomy_exams"] = anatomy_exams
@@ -3343,6 +3371,7 @@ def manage_cid_users(request):
sba_exams = json.loads(request.POST.get("sba_exams"))
longs_exams = json.loads(request.POST.get("longs_exams"))
anatomy_exams = json.loads(request.POST.get("anatomy_exams"))
shorts_exams = json.loads(request.POST.get("shorts_exams"))
casecollection_exams = json.loads(request.POST.get("casecollection_exams"))
cid_groups = json.loads(request.POST.get("cid_groups"))
@@ -3404,6 +3433,7 @@ def manage_cid_users(request):
c.sba_exams.clear()
c.longs_exams.clear()
c.anatomy_exams.clear()
c.shorts_exams.clear()
c.casecollection_exams.clear()
return JsonResponse({"status": "success"})
@@ -3420,6 +3450,8 @@ def manage_cid_users(request):
c.longs_exams.add(exam)
for exam in anatomy_exams:
c.anatomy_exams.add(exam)
for exam in shorts_exams:
c.shorts_exams.add(exam)
for exam in casecollection_exams:
c.casecollection_exams.add(exam)
c.save()
@@ -3433,6 +3465,7 @@ def manage_cid_users(request):
c.sba_exams.set(sba_exams)
c.longs_exams.set(longs_exams)
c.anatomy_exams.set(anatomy_exams)
c.shorts_exams.set(shorts_exams)
c.casecollection_exams.set(casecollection_exams)
c.save()
return JsonResponse({"status": "success"})
@@ -3479,6 +3512,8 @@ def manage_cid_users(request):
c.longs_exams.set(longs_exams)
if anatomy_exams:
c.anatomy_exams.set(anatomy_exams)
if shorts_exams:
c.shorts_exams.set(shorts_exams)
if casecollection_exams:
c.casecollection_exams.set(casecollection_exams)
c.save()
@@ -3501,6 +3536,8 @@ def manage_cid_users(request):
c.longs_exams.set(longs_exams)
if anatomy_exams:
c.anatomy_exams.set(anatomy_exams)
if shorts_exams:
c.shorts_exams.set(shorts_exams)
if casecollection_exams:
c.casecollection_exams.set(casecollection_exams)
c.save()
@@ -3832,6 +3869,7 @@ class ExamCollectionClone(CreateView, AuthorRequiredMixin):
GROUP_TYPES = (
("Rapid Exams", "rapids_exams", RapidsExam),
("Short Exams", "shorts_exams", ShortsExam),
("Long Exams", "longs_exams", LongsExam),
("SBA Exams", "sbas_exams", SbasExam),
("Physic Exams", "physics_exams", PhysicsExam),