.
This commit is contained in:
@@ -82,6 +82,12 @@ urlpatterns = [
|
|||||||
# cache_page(60 * 1)(views.exam_scores_cid),
|
# cache_page(60 * 1)(views.exam_scores_cid),
|
||||||
name="exam_scores_cid",
|
name="exam_scores_cid",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"exam/<int:pk>/scores2",
|
||||||
|
views.AnatomyExamViews.exam_scores_cid2,
|
||||||
|
# cache_page(60 * 1)(views.exam_scores_cid),
|
||||||
|
name="exam_scores_cid",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"exam/<int:pk>/scores/refresh",
|
"exam/<int:pk>/scores/refresh",
|
||||||
views.AnatomyExamViews.exam_scores_refresh,
|
views.AnatomyExamViews.exam_scores_refresh,
|
||||||
|
|||||||
@@ -61,6 +61,27 @@ import plotly.express as px
|
|||||||
# from rad.views import get_question_and_content_type
|
# from rad.views import get_question_and_content_type
|
||||||
|
|
||||||
|
|
||||||
|
def normaliseRapidsScore(score):
|
||||||
|
if score == 49:
|
||||||
|
return 4.5
|
||||||
|
elif score in [50, 51]:
|
||||||
|
return 5
|
||||||
|
elif score in [52, 53]:
|
||||||
|
return 5.5
|
||||||
|
elif score in [54]:
|
||||||
|
return 6
|
||||||
|
elif score in [55, 56]:
|
||||||
|
return 6.5
|
||||||
|
elif score in [57, 58]:
|
||||||
|
return 7
|
||||||
|
elif score in [59]:
|
||||||
|
return 7.5
|
||||||
|
elif score in [60]:
|
||||||
|
return 8
|
||||||
|
|
||||||
|
return 4
|
||||||
|
|
||||||
|
|
||||||
def get_question_and_content_type(question_type):
|
def get_question_and_content_type(question_type):
|
||||||
if question_type == "rapid":
|
if question_type == "rapid":
|
||||||
question = RapidQuestion
|
question = RapidQuestion
|
||||||
@@ -835,6 +856,134 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
cache.set("{}_question_json_{}".format(self.app_name, sk), question_json, 3600)
|
cache.set("{}_question_json_{}".format(self.app_name, sk), question_json, 3600)
|
||||||
|
|
||||||
return JsonResponse(question_json)
|
return JsonResponse(question_json)
|
||||||
|
def exam_scores_cid2(self, request, pk):
|
||||||
|
exam = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|
||||||
|
if not exam.exam_mode:
|
||||||
|
raise Http404("Packet not in exam mode")
|
||||||
|
|
||||||
|
user_answers_and_marks = defaultdict(list)
|
||||||
|
user_answers_marks = defaultdict(list)
|
||||||
|
user_answers = defaultdict(list)
|
||||||
|
user_names = {}
|
||||||
|
|
||||||
|
score_by_question = defaultdict(dict)
|
||||||
|
ans_by_question = defaultdict(dict)
|
||||||
|
unmarked = set()
|
||||||
|
|
||||||
|
questions = exam.exam_questions.all()
|
||||||
|
|
||||||
|
cid_user_answers = self.CidUserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
||||||
|
|
||||||
|
cids = set()
|
||||||
|
|
||||||
|
# Loop through all candidates
|
||||||
|
for cid_user_answer in cid_user_answers:
|
||||||
|
# Convoluted (probably...)
|
||||||
|
cid = cid_user_answer.cid
|
||||||
|
cids.add(cid)
|
||||||
|
s = cid_user_answer
|
||||||
|
user_names[cid] = cid
|
||||||
|
|
||||||
|
q = cid_user_answer.question
|
||||||
|
|
||||||
|
# if not s:
|
||||||
|
# # skip if no answer
|
||||||
|
# user_answers_marks[cid].append(0)
|
||||||
|
# user_answers[cid].append("")
|
||||||
|
# by_question[q].append(("", 0))
|
||||||
|
# continue
|
||||||
|
if s.normal:
|
||||||
|
ans = "Normal"
|
||||||
|
else:
|
||||||
|
ans = s.answer
|
||||||
|
answer_score = s.get_answer_score()
|
||||||
|
if answer_score == "unmarked":
|
||||||
|
index = exam.get_question_index(q)
|
||||||
|
unmarked.add(index)
|
||||||
|
user_answers[cid].append(ans)
|
||||||
|
user_answers_marks[cid].append(answer_score)
|
||||||
|
user_answers_and_marks[cid].append((ans, answer_score))
|
||||||
|
|
||||||
|
score_by_question[q][cid] = answer_score
|
||||||
|
ans_by_question[q][cid] = ans
|
||||||
|
|
||||||
|
user_scores = {}
|
||||||
|
user_scores_normalised = {}
|
||||||
|
for user in user_answers_marks:
|
||||||
|
user_scores[user] = sum(
|
||||||
|
[i for i in user_answers_marks[user] if i != "unmarked"]
|
||||||
|
)
|
||||||
|
user_scores_normalised[user] = normaliseRapidsScore(
|
||||||
|
sum([i for i in user_answers_marks[user] if i != "unmarked"])
|
||||||
|
)
|
||||||
|
|
||||||
|
user_scores_list = list(user_scores.values())
|
||||||
|
|
||||||
|
max_score = len(questions) * 2
|
||||||
|
|
||||||
|
if len(user_scores_list) < 1:
|
||||||
|
mean = 0
|
||||||
|
median = 0
|
||||||
|
mode = 0
|
||||||
|
fig_html = ""
|
||||||
|
else:
|
||||||
|
mean = statistics.mean(user_scores_list)
|
||||||
|
median = statistics.median(user_scores_list)
|
||||||
|
try:
|
||||||
|
mode = statistics.mode(user_scores_list)
|
||||||
|
except statistics.StatisticsError:
|
||||||
|
mode = "No unique mode"
|
||||||
|
|
||||||
|
df = user_scores_list
|
||||||
|
fig = px.histogram(
|
||||||
|
df,
|
||||||
|
x=0,
|
||||||
|
title="{}: distribution of scores".format(exam),
|
||||||
|
labels={"0": "Score"},
|
||||||
|
height=400,
|
||||||
|
width=600,
|
||||||
|
)
|
||||||
|
fig_html = fig.to_html()
|
||||||
|
|
||||||
|
exam.stats_mean = mean
|
||||||
|
exam.stats_median = median
|
||||||
|
exam.stats_mode = mode
|
||||||
|
|
||||||
|
exam.stats_candidates = len(user_scores_list)
|
||||||
|
exam.stats_max_possible = max_score
|
||||||
|
|
||||||
|
exam.stats_min = min(user_scores_list)
|
||||||
|
exam.stats_max = max(user_scores_list)
|
||||||
|
|
||||||
|
exam.stats_graph = fig_html
|
||||||
|
exam.save()
|
||||||
|
|
||||||
|
|
||||||
|
return render(
|
||||||
|
request,
|
||||||
|
f"{self.app_name}/exam_scores_new.html",
|
||||||
|
{
|
||||||
|
"cids": sorted(cids),
|
||||||
|
"exam": exam,
|
||||||
|
"unmarked": unmarked,
|
||||||
|
"questions": questions,
|
||||||
|
"score_by_question": score_by_question,
|
||||||
|
"ans_by_question": ans_by_question,
|
||||||
|
"user_answers": dict(user_answers),
|
||||||
|
"user_answers_marks": dict(user_answers_marks),
|
||||||
|
"user_scores": user_scores,
|
||||||
|
"user_scores_normalised": user_scores_normalised,
|
||||||
|
"user_scores_list": user_scores_list,
|
||||||
|
"user_names": user_names,
|
||||||
|
"user_answers_and_marks": user_answers_and_marks,
|
||||||
|
"max_score": max_score,
|
||||||
|
"mean": mean,
|
||||||
|
"median": median,
|
||||||
|
"mode": mode,
|
||||||
|
"plot": fig_html,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
def exam_scores_cid(self, request, pk):
|
def exam_scores_cid(self, request, pk):
|
||||||
exam = get_object_or_404(self.Exam, pk=pk)
|
exam = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|||||||
Reference in New Issue
Block a user