.
This commit is contained in:
@@ -936,6 +936,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
user_answers_marks = defaultdict(list)
|
user_answers_marks = defaultdict(list)
|
||||||
user_answers = defaultdict(list)
|
user_answers = defaultdict(list)
|
||||||
user_names = {}
|
user_names = {}
|
||||||
|
cid_passcodes = {}
|
||||||
|
|
||||||
by_question = defaultdict(dict)
|
by_question = defaultdict(dict)
|
||||||
unmarked = set()
|
unmarked = set()
|
||||||
@@ -953,6 +954,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
for cid_user_answer in cid_user_answers:
|
for cid_user_answer in cid_user_answers:
|
||||||
# Convoluted (probably...)
|
# Convoluted (probably...)
|
||||||
cid = cid_user_answer.cid
|
cid = cid_user_answer.cid
|
||||||
|
cid_passcodes[cid] = cid_user_answer.passcode
|
||||||
cids.add(cid)
|
cids.add(cid)
|
||||||
s = cid_user_answer
|
s = cid_user_answer
|
||||||
user_names[cid] = cid
|
user_names[cid] = cid
|
||||||
@@ -1053,6 +1055,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
f"{self.app_name}/exam_scores_new.html",
|
f"{self.app_name}/exam_scores_new.html",
|
||||||
{
|
{
|
||||||
"cids": sorted(cids),
|
"cids": sorted(cids),
|
||||||
|
"cid_passcodes": cid_passcodes,
|
||||||
"exam": exam,
|
"exam": exam,
|
||||||
"unmarked": unmarked,
|
"unmarked": unmarked,
|
||||||
"questions": questions,
|
"questions": questions,
|
||||||
|
|||||||
@@ -37,8 +37,8 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Candidate</th>
|
<th>Candidate</th>
|
||||||
{% for cid in cids %}
|
{% for cid in cids %}
|
||||||
{% comment %} <th><a href="{% url 'sbas:exam_scores_cid_user' exam.pk cid %}">{{cid}}</a></th> {% endcomment %}
|
<th><a href="{% url 'sbas:exam_scores_cid_user' exam.pk cid cid_passcodes|get_item:cid %}">{{cid}}</a></th>
|
||||||
<th><a href="">{{cid}}</a></th>
|
{% comment %} <th><a href="">{{cid}}</a></th> {% endcomment %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
+2
-109
@@ -81,119 +81,12 @@ def active_exams(request):
|
|||||||
return render(request, "sbas/available_exam_list.html", {"exams": active_exams})
|
return render(request, "sbas/available_exam_list.html", {"exams": active_exams})
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def exam_scores_cid(request, pk):
|
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
|
||||||
|
|
||||||
cids = (
|
|
||||||
CidUserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
|
||||||
.order_by("cid")
|
|
||||||
.values_list("cid", flat=True)
|
|
||||||
.distinct()
|
|
||||||
)
|
|
||||||
|
|
||||||
user_answers_and_marks = defaultdict(list)
|
|
||||||
user_answers_marks = defaultdict(list)
|
|
||||||
user_answers = defaultdict(list)
|
|
||||||
user_names = {}
|
|
||||||
|
|
||||||
by_question = defaultdict(list)
|
|
||||||
unmarked = set()
|
|
||||||
|
|
||||||
# Loop through all candidates
|
|
||||||
for cid in cids:
|
|
||||||
# Convoluted (probably...)
|
|
||||||
user_names[cid] = cid
|
|
||||||
for q in questions:
|
|
||||||
# Get user answer
|
|
||||||
s = q.cid_user_answers.filter(cid=cid, exam__id=pk).first()
|
|
||||||
if not s:
|
|
||||||
# skip if no answer
|
|
||||||
user_answers_marks[cid].append((0, 0, 0, 0, 0))
|
|
||||||
user_answers[cid].append(("", "", "", "", ""))
|
|
||||||
by_question[q].append(
|
|
||||||
(
|
|
||||||
("", 0),
|
|
||||||
("", 0),
|
|
||||||
("", 0),
|
|
||||||
("", 0),
|
|
||||||
("", 0),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
continue
|
|
||||||
|
|
||||||
ans = s.get_answer()
|
|
||||||
answer_score = s.get_score()
|
|
||||||
|
|
||||||
user_answers[cid].append(ans)
|
|
||||||
user_answers_marks[cid].append(answer_score)
|
|
||||||
user_answers_and_marks[cid].append((ans, answer_score))
|
|
||||||
|
|
||||||
by_question[q].append((ans, answer_score))
|
|
||||||
|
|
||||||
user_scores = {}
|
|
||||||
for user in user_answers_marks:
|
|
||||||
user_scores[user] = sum(user_answers_marks[user])
|
|
||||||
|
|
||||||
user_scores_list = list(user_scores.values())
|
|
||||||
|
|
||||||
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()
|
|
||||||
|
|
||||||
max_score = len(questions)
|
|
||||||
|
|
||||||
return render(
|
|
||||||
request,
|
|
||||||
"sbas/exam_scores.html",
|
|
||||||
{
|
|
||||||
"cids": cids,
|
|
||||||
"exam": exam,
|
|
||||||
"unmarked": unmarked,
|
|
||||||
"questions": questions,
|
|
||||||
"by_question": by_question,
|
|
||||||
"user_answers": dict(user_answers),
|
|
||||||
"user_answers_marks": dict(user_answers_marks),
|
|
||||||
"user_scores": user_scores,
|
|
||||||
"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_user(request, pk, sk, passcode):
|
def exam_scores_cid_user(request, pk, sk, passcode):
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
exam = get_object_or_404(Exam, pk=pk)
|
||||||
|
|
||||||
# TODO:Need some kind of test for cid
|
|
||||||
cid = sk
|
cid = sk
|
||||||
|
if not exam.check_cid_user(cid, passcode):
|
||||||
|
raise Http404("Error accessing exam")
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.exam_questions.all()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user