fix question ordering through mark systems
This commit is contained in:
+24
-31
@@ -248,7 +248,7 @@ def mark(request, exam_pk, sk, unmarked_exam_answers_only=True, review=False):
|
|||||||
elif not unmarked_exam_answers_only:
|
elif not unmarked_exam_answers_only:
|
||||||
mark_url = "anatomy:mark_all"
|
mark_url = "anatomy:mark_all"
|
||||||
|
|
||||||
questions = exam.exam_questions.all().prefetch_related("answers")
|
questions = exam.get_questions().prefetch_related("answers")
|
||||||
|
|
||||||
n = sk
|
n = sk
|
||||||
|
|
||||||
@@ -383,28 +383,28 @@ def mark(request, exam_pk, sk, unmarked_exam_answers_only=True, review=False):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
#@login_required
|
||||||
def exam_scores_refresh(request, pk):
|
#def exam_scores_refresh(request, pk):
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
# exam = get_object_or_404(Exam, pk=pk)
|
||||||
|
#
|
||||||
if not exam.exam_mode:
|
# if not exam.exam_mode:
|
||||||
raise Http404("Packet not in exam mode")
|
# raise Http404("Packet not in exam mode")
|
||||||
|
#
|
||||||
questions = exam.exam_questions.all()
|
# questions = exam.exam_questions.all() # Don't worry about order here
|
||||||
|
#
|
||||||
cids = UserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
# cids = UserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
||||||
|
#
|
||||||
# Force a score update
|
# # Force a score update
|
||||||
for c in cids:
|
# for c in cids:
|
||||||
c.get_answer_score(cached=False)
|
# c.get_answer_score(cached=False)
|
||||||
|
#
|
||||||
return render(
|
# return render(
|
||||||
request,
|
# request,
|
||||||
"anatomy/base.html",
|
# "anatomy/base.html",
|
||||||
{
|
# {
|
||||||
"simple_content": "Answer scores updated",
|
# "simple_content": "Answer scores updated",
|
||||||
},
|
# },
|
||||||
)
|
# )
|
||||||
|
|
||||||
|
|
||||||
def exam_scores_cid_user(request, pk, cid, passcode):
|
def exam_scores_cid_user(request, pk, cid, passcode):
|
||||||
@@ -416,7 +416,7 @@ def exam_scores_cid_user(request, pk, cid, passcode):
|
|||||||
if not exam.check_cid_user(cid, passcode, request.user):
|
if not exam.check_cid_user(cid, passcode, request.user):
|
||||||
raise Http404("Error accessing exam")
|
raise Http404("Error accessing exam")
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions().prefetch_related("answers")
|
||||||
|
|
||||||
answers_and_marks = []
|
answers_and_marks = []
|
||||||
answers_marks = []
|
answers_marks = []
|
||||||
@@ -615,13 +615,6 @@ class AnatomyQuestionUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateV
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
|
|
||||||
# save exam orders (there must be a better way to do this)
|
|
||||||
#exam_orders = {}
|
|
||||||
#for exam in self.object.exams.all():
|
|
||||||
# exam_orders[exam] = list(exam.exam_questions.all())
|
|
||||||
# print(exam_orders[exam])
|
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
|
|||||||
@@ -759,11 +759,6 @@ class CaseCollectionUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateVi
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
# save exam orders (there must be a better way to do this)
|
|
||||||
# exam_orders = {}
|
|
||||||
# for exam in self.object.exams.all():
|
|
||||||
# exam_orders[exam] = list(exam.exam_questions.all())
|
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
@@ -2407,12 +2402,6 @@ def collection_scores_cid(request, pk):
|
|||||||
|
|
||||||
cid_user_answers = CidReportAnswer.objects.filter(question__in=case_details)
|
cid_user_answers = CidReportAnswer.objects.filter(question__in=case_details)
|
||||||
|
|
||||||
# questions = exam.exam_questions.all().prefetch_related("answers")
|
|
||||||
|
|
||||||
# cid_user_answers = CidReportAnswer.objects.select_related("question").filter(
|
|
||||||
# question__in=questions, exam__id=pk
|
|
||||||
# )
|
|
||||||
|
|
||||||
cids = set()
|
cids = set()
|
||||||
|
|
||||||
case_list = list(cases)
|
case_list = list(cases)
|
||||||
|
|||||||
+4
-1
@@ -886,7 +886,10 @@ class ExamBase(ExamOrCollectionGenericBase):
|
|||||||
# return super().clean(*args, **kwargs)
|
# return super().clean(*args, **kwargs)
|
||||||
|
|
||||||
def get_questions(self):
|
def get_questions(self):
|
||||||
"""Returns a list of questions in the exam in the correct order"""
|
"""Returns a list of questions in the exam in the correct order
|
||||||
|
|
||||||
|
This should be used in preference to exam_questions.all() as it
|
||||||
|
will order the questions correctly"""
|
||||||
return self.exam_questions.all().order_by("examquestiondetail__sort_order")
|
return self.exam_questions.all().order_by("examquestiondetail__sort_order")
|
||||||
|
|
||||||
def order_questions(self):
|
def order_questions(self):
|
||||||
|
|||||||
@@ -6,6 +6,9 @@
|
|||||||
\ <a href="{% url exam.get_app_name|add:':exam_clone' exam.id %}" title="Clone the Exam">Clone</a>
|
\ <a href="{% url exam.get_app_name|add:':exam_clone' exam.id %}" title="Clone the Exam">Clone</a>
|
||||||
\ <a href="{% url exam.get_app_name|add:':exam_authors' exam.id %}" title="Edit Exam Authors">Authors</a>
|
\ <a href="{% url exam.get_app_name|add:':exam_authors' exam.id %}" title="Edit Exam Authors">Authors</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if can_edit and request.user.is_superuser %}
|
||||||
|
\
|
||||||
|
{% endif %}
|
||||||
{% if request.user.is_superuser %}
|
{% if request.user.is_superuser %}
|
||||||
\ <a href="{% url 'admin:'|add:exam.get_app_name|add:'_exam_change' exam.id %}" title="Edit the Exam using the admin interface">Admin Edit</a>
|
<a href="{% url 'admin:'|add:exam.get_app_name|add:'_exam_change' exam.id %}" title="Edit the Exam using the admin interface">Admin Edit</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
+14
-16
@@ -947,6 +947,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
if not exam.exam_mode:
|
if not exam.exam_mode:
|
||||||
raise Http404("Packet not in exam mode")
|
raise Http404("Packet not in exam mode")
|
||||||
|
|
||||||
|
# We don't worry about order here
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.exam_questions.all()
|
||||||
|
|
||||||
cids = self.UserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
cids = self.UserAnswer.objects.filter(question__in=questions, exam__id=pk)
|
||||||
@@ -1304,7 +1305,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
|
|
||||||
@method_decorator(login_required)
|
@method_decorator(login_required)
|
||||||
def mark_overview(self, request, pk):
|
def mark_overview(self, request, pk):
|
||||||
exam = get_object_or_404(self.Exam, pk=pk)
|
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|
||||||
if not exam.exam_mode:
|
if not exam.exam_mode:
|
||||||
raise Http404("Packet not in exam mode")
|
raise Http404("Packet not in exam mode")
|
||||||
@@ -1343,7 +1344,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
|
|
||||||
# Handle exams that require double marking
|
# Handle exams that require double marking
|
||||||
try:
|
try:
|
||||||
@@ -1416,8 +1417,6 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
def exam_question_user_answer(self, request, pk: int, sk: int, c_or_u: str, user_or_cid: str):
|
def exam_question_user_answer(self, request, pk: int, sk: int, c_or_u: str, user_or_cid: str):
|
||||||
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|
||||||
#question = exam.exam_questions.all()[sk]
|
|
||||||
|
|
||||||
if c_or_u == "u":
|
if c_or_u == "u":
|
||||||
user = get_object_or_404(User,pk=user_or_cid)
|
user = get_object_or_404(User,pk=user_or_cid)
|
||||||
answer = exam.get_question_user_user_answer(sk, user)
|
answer = exam.get_question_user_user_answer(sk, user)
|
||||||
@@ -1434,8 +1433,6 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
def exam_question_cid_user_answer(self, request, pk: int, sk: int, cid: str):
|
def exam_question_cid_user_answer(self, request, pk: int, sk: int, cid: str):
|
||||||
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|
||||||
#question = exam.exam_questions.all()[sk]
|
|
||||||
|
|
||||||
cid_user = CidUser.objects.filter(cid=cid)
|
cid_user = CidUser.objects.filter(cid=cid)
|
||||||
answer =exam.get_question_cid_user_answer(sk, cid_user)
|
answer =exam.get_question_cid_user_answer(sk, cid_user)
|
||||||
|
|
||||||
@@ -1443,13 +1440,13 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
|
|
||||||
@method_decorator(login_required)
|
@method_decorator(login_required)
|
||||||
def exam_question_detail(self, request, pk, sk):
|
def exam_question_detail(self, request, pk, sk):
|
||||||
exam = get_object_or_404(self.Exam, pk=pk)
|
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|
||||||
if request.user not in exam.author.all():
|
if request.user not in exam.author.all():
|
||||||
if not self.check_user_access(request.user, pk):
|
if not self.check_user_access(request.user, pk):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
question = exam.exam_questions.all()[sk]
|
question = exam.get_questions()[sk]
|
||||||
|
|
||||||
exam_length = len(exam.exam_questions.all())
|
exam_length = len(exam.exam_questions.all())
|
||||||
|
|
||||||
@@ -1924,7 +1921,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
return self.exam_scores_cid_user(request, pk, cid, user.passcode)
|
return self.exam_scores_cid_user(request, pk, cid, user.passcode)
|
||||||
|
|
||||||
def exam_scores_cid_user(self, request, pk, cid=None, passcode="", user=None):
|
def exam_scores_cid_user(self, request, pk, cid=None, passcode="", user=None):
|
||||||
exam = get_object_or_404(self.Exam, pk=pk)
|
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|
||||||
if not exam.exam_mode:
|
if not exam.exam_mode:
|
||||||
raise Http404("Packet not in exam mode")
|
raise Http404("Packet not in exam mode")
|
||||||
@@ -1936,7 +1933,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
request.user = user
|
request.user = user
|
||||||
|
|
||||||
questions = (
|
questions = (
|
||||||
exam.exam_questions.all()
|
exam.get_questions()
|
||||||
) # .prefetch_related("cid_user_answers", "answers")
|
) # .prefetch_related("cid_user_answers", "answers")
|
||||||
|
|
||||||
# cid_user_answers = list(UserAnswer.objects.filter(cid=cid, exam__id=pk).prefetch_related("question"))
|
# cid_user_answers = list(UserAnswer.objects.filter(cid=cid, exam__id=pk).prefetch_related("question"))
|
||||||
@@ -2080,7 +2077,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
Returns:
|
Returns:
|
||||||
_type_: _description_
|
_type_: _description_
|
||||||
"""
|
"""
|
||||||
exam = get_object_or_404(self.Exam, pk=pk)
|
exam: ExamBase = get_object_or_404(self.Exam, pk=pk)
|
||||||
|
|
||||||
if not exam.exam_mode:
|
if not exam.exam_mode:
|
||||||
raise Http404("Packet not in exam mode")
|
raise Http404("Packet not in exam mode")
|
||||||
@@ -2109,9 +2106,9 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
|
|
||||||
if self.app_name in ("physics", "sbas", "longs"):
|
if self.app_name in ("physics", "sbas", "longs"):
|
||||||
cached_scores = False
|
cached_scores = False
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
else:
|
else:
|
||||||
questions = exam.exam_questions.all().prefetch_related("answers")
|
questions = exam.get_questions().prefetch_related("answers")
|
||||||
|
|
||||||
# We could prefect the UserAnswers.answers here (if we didn't cache them)
|
# We could prefect the UserAnswers.answers here (if we didn't cache them)
|
||||||
cid_user_answers = self.UserAnswer.objects.select_related("question").filter(
|
cid_user_answers = self.UserAnswer.objects.select_related("question").filter(
|
||||||
@@ -2315,6 +2312,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
"mode": mode,
|
"mode": mode,
|
||||||
"plot": fig_html,
|
"plot": fig_html,
|
||||||
"cached_scores": cached_scores,
|
"cached_scores": cached_scores,
|
||||||
|
"can_edit": exam.check_user_can_edit(request.user),
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.app_name == "rapids":
|
if self.app_name == "rapids":
|
||||||
@@ -2329,7 +2327,7 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def exam_stats(self, request, exam_id):
|
def exam_stats(self, request, exam_id):
|
||||||
exam = get_object_or_404(self.Exam, pk=exam_id)
|
exam: ExamBase = get_object_or_404(self.Exam, pk=exam_id)
|
||||||
|
|
||||||
if not exam.exam_mode:
|
if not exam.exam_mode:
|
||||||
raise Http404("Packet not in exam mode")
|
raise Http404("Packet not in exam mode")
|
||||||
@@ -2366,7 +2364,7 @@ class GenericViewBase:
|
|||||||
"""
|
"""
|
||||||
Return a json representation of the question when the exam is published
|
Return a json representation of the question when the exam is published
|
||||||
"""
|
"""
|
||||||
exam = get_object_or_404(self.exam_object, pk=pk)
|
exam: ExamBase = get_object_or_404(self.exam_object, pk=pk)
|
||||||
|
|
||||||
print(request.POST["question_number"])
|
print(request.POST["question_number"])
|
||||||
print(type(request.POST["question_number"]))
|
print(type(request.POST["question_number"]))
|
||||||
@@ -2374,7 +2372,7 @@ class GenericViewBase:
|
|||||||
if not exam.publish_results:
|
if not exam.publish_results:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
question = exam.exam_questions.all()[int(request.POST["question_number"])]
|
question = exam.get_questions()[int(request.POST["question_number"])]
|
||||||
|
|
||||||
question_json = question.get_question_json(based=False, feedback=True)
|
question_json = question.get_question_json(based=False, feedback=True)
|
||||||
return JsonResponse(question_json)
|
return JsonResponse(question_json)
|
||||||
|
|||||||
@@ -1,10 +1,15 @@
|
|||||||
|
|
||||||
{% extends 'generic/exam_scores_base.html' %}
|
{% extends 'generic/exam_scores_base.html' %}
|
||||||
|
|
||||||
|
{% block navigation %}
|
||||||
|
{{ block.super }}
|
||||||
|
{% include 'generic/exam_link_headers.html' %}
|
||||||
|
{% endblock navigation %}
|
||||||
|
|
||||||
{% block table_answers %}
|
{% block table_answers %}
|
||||||
{% for question in questions %}
|
{% for question in questions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{% url 'anatomy:mark' exam_pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a>
|
<td><a href="{% url 'longs:mark' exam_id=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a>
|
||||||
</td>
|
</td>
|
||||||
{% comment %} {% for cid in cids %}
|
{% comment %} {% for cid in cids %}
|
||||||
<td class="anatomy-ans user-answer-score-{{score_by_question|get_item:question|get_item:cid}}" title="answer score: {{score_by_question|get_item:question|get_item:cid}}">{{ans_by_question|get_item:question|get_item:cid}}</td>
|
<td class="anatomy-ans user-answer-score-{{score_by_question|get_item:question|get_item:cid}}" title="answer score: {{score_by_question|get_item:question|get_item:cid}}">{{ans_by_question|get_item:question|get_item:cid}}</td>
|
||||||
|
|||||||
@@ -39,7 +39,12 @@
|
|||||||
|
|
||||||
{% if not next_unmarked_id and not unmarked %}
|
{% if not next_unmarked_id and not unmarked %}
|
||||||
<div class="alert alert-info sticky-alert" role="alert">Success! Marking question complete. <br />
|
<div class="alert alert-info sticky-alert" role="alert">Success! Marking question complete. <br />
|
||||||
|
|
||||||
|
|
||||||
|
{% if exam.double_mark %}
|
||||||
<a href="{% url 'longs:mark_answer_override' exam_id=exam.pk question_number=question_details.current|add:'-1' answer_id=answer.id %}">Set final score</a><br/>
|
<a href="{% url 'longs:mark_answer_override' exam_id=exam.pk question_number=question_details.current|add:'-1' answer_id=answer.id %}">Set final score</a><br/>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
Return to <a href="{% url 'longs:mark' exam.id question_details.current|add:'-1' %}">question
|
Return to <a href="{% url 'longs:mark' exam.id question_details.current|add:'-1' %}">question
|
||||||
overview</a>, <a href="{% url 'longs:mark_overview' pk=exam.pk %}">marking
|
overview</a>, <a href="{% url 'longs:mark_overview' pk=exam.pk %}">marking
|
||||||
overview</a><br />
|
overview</a><br />
|
||||||
|
|||||||
@@ -543,6 +543,7 @@ def test_exams(db, client):
|
|||||||
cid_exam_scores_soup.find("div", {"class": "score-overview"}) is None
|
cid_exam_scores_soup.find("div", {"class": "score-overview"}) is None
|
||||||
) # check we hide the score overview if not published
|
) # check we hide the score overview if not published
|
||||||
|
|
||||||
|
|
||||||
# Add another question to the exam
|
# Add another question to the exam
|
||||||
create_question(exam)
|
create_question(exam)
|
||||||
|
|
||||||
|
|||||||
+5
-204
@@ -526,8 +526,9 @@ class LongUpdate(
|
|||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
# save exam orders (there must be a better way to do this)
|
# save exam orders (there must be a better way to do this)
|
||||||
exam_orders = {}
|
exam_orders = {}
|
||||||
|
exam: Exam
|
||||||
for exam in self.object.exams.all():
|
for exam in self.object.exams.all():
|
||||||
exam_orders[exam] = list(exam.exam_questions.all())
|
exam_orders[exam] = list(exam.get_questions())
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
@@ -650,7 +651,7 @@ def mark_answer_override(request, exam_id, question_number, cid):
|
|||||||
def mark_answer(request, exam_id, question_number, answer_id, override=False):
|
def mark_answer(request, exam_id, question_number, answer_id, override=False):
|
||||||
exam = get_object_or_404(Exam, pk=exam_id)
|
exam = get_object_or_404(Exam, pk=exam_id)
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
|
|
||||||
n = question_number
|
n = question_number
|
||||||
|
|
||||||
@@ -845,7 +846,7 @@ def mark_answer(request, exam_id, question_number, answer_id, override=False):
|
|||||||
def mark(request, exam_id, sk):
|
def mark(request, exam_id, sk):
|
||||||
exam = get_object_or_404(Exam, pk=exam_id)
|
exam = get_object_or_404(Exam, pk=exam_id)
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
|
|
||||||
n = sk
|
n = sk
|
||||||
|
|
||||||
@@ -893,206 +894,6 @@ def mark(request, exam_id, sk):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
# @login_required
|
|
||||||
# @user_is_long_marker
|
|
||||||
# def exam_scores_all(request, pk):
|
|
||||||
# exam = get_object_or_404(Exam, pk=pk)
|
|
||||||
#
|
|
||||||
# questions = exam.exam_questions.all()
|
|
||||||
#
|
|
||||||
# cids = (
|
|
||||||
# UserAnswer.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, (score 4)
|
|
||||||
# user_answers_marks[cid].append(4)
|
|
||||||
# # user_answers[cid].append("")
|
|
||||||
# by_question[q].append(("", 4))
|
|
||||||
# continue
|
|
||||||
# else:
|
|
||||||
# ans = ""
|
|
||||||
# answer_score = s.get_answer_score()
|
|
||||||
# if answer_score == "":
|
|
||||||
# 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))
|
|
||||||
#
|
|
||||||
# by_question[q].append((ans, answer_score))
|
|
||||||
#
|
|
||||||
# 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 != ""])
|
|
||||||
# user_scores_normalised[user] = normaliseScore(
|
|
||||||
# sum([i for i in user_answers_marks[user] if i != ""])
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# 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) * 2
|
|
||||||
#
|
|
||||||
# return render(
|
|
||||||
# request,
|
|
||||||
# "longs/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_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_user(request, pk, cid, passcode):
|
|
||||||
# exam = get_object_or_404(Exam, pk=pk)
|
|
||||||
#
|
|
||||||
# # TODO:Need some kind of test for cid
|
|
||||||
#
|
|
||||||
# if not exam.exam_mode:
|
|
||||||
# raise Http404("Packet not in exam mode")
|
|
||||||
#
|
|
||||||
# if not exam.check_cid_user(cid, passcode, request):
|
|
||||||
# raise Http404("Error accessing exam")
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# questions = exam.exam_questions.all()
|
|
||||||
#
|
|
||||||
# # answers_and_marks = []
|
|
||||||
# answers_marks = []
|
|
||||||
# # answers = []
|
|
||||||
# answer_text = []
|
|
||||||
#
|
|
||||||
# view_all_results = False
|
|
||||||
# if request.user.groups.filter(name="view_all_results").exists():
|
|
||||||
# view_all_results = True
|
|
||||||
#
|
|
||||||
# for q in questions:
|
|
||||||
# # Get user answer
|
|
||||||
# user_answer = q.cid_user_answers.filter(cid=cid, exam__id=pk).first()
|
|
||||||
#
|
|
||||||
# if not user_answer or user_answer is None:
|
|
||||||
# # skip if no answer
|
|
||||||
# # answers_marks.append("")
|
|
||||||
# # answers.append("")
|
|
||||||
# answer_score = 4
|
|
||||||
# # ans = "Not answered"
|
|
||||||
# answer_text.append(
|
|
||||||
# (
|
|
||||||
# ("Not answered"),
|
|
||||||
# ("Not answered"),
|
|
||||||
# ("Not answered"),
|
|
||||||
# ("Not answered"),
|
|
||||||
# ("Not answered"),
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
# else:
|
|
||||||
# answer_score = user_answer.get_answer_score()
|
|
||||||
#
|
|
||||||
# answer_text.append(
|
|
||||||
# (
|
|
||||||
# user_answer.answer_observations,
|
|
||||||
# user_answer.answer_interpretation,
|
|
||||||
# user_answer.answer_principle_diagnosis,
|
|
||||||
# user_answer.answer_differential_diagnosis,
|
|
||||||
# user_answer.answer_management,
|
|
||||||
# )
|
|
||||||
# )
|
|
||||||
#
|
|
||||||
# if not exam.publish_results and not view_all_results:
|
|
||||||
# answer_score = 0
|
|
||||||
# # answers.append(ans)
|
|
||||||
# answers_marks.append(answer_score)
|
|
||||||
# # answers_and_marks.append((ans, answer_score, correct_answer))
|
|
||||||
#
|
|
||||||
# answered = [i for i in answers_marks if i != ""]
|
|
||||||
# if "" in answers_marks:
|
|
||||||
# total_score = sum(answered)
|
|
||||||
# unmarked_number = len(answers_marks) - len(answered)
|
|
||||||
# total_score = "{} ({} unmarked)".format(total_score, unmarked_number)
|
|
||||||
# normalised_score = "Not available"
|
|
||||||
# else:
|
|
||||||
# total_score = sum(answered)
|
|
||||||
# normalised_score = normaliseScore(total_score)
|
|
||||||
#
|
|
||||||
# max_score = len(questions) * 8
|
|
||||||
#
|
|
||||||
# return render(
|
|
||||||
# request,
|
|
||||||
# "longs/exam_scores_user.html",
|
|
||||||
# {
|
|
||||||
# "exam": exam,
|
|
||||||
# "cid": cid,
|
|
||||||
# "passcode": passcode,
|
|
||||||
# "questions": questions,
|
|
||||||
# # "answers": answers,
|
|
||||||
# "answers_marks": answers_marks,
|
|
||||||
# "total_score": total_score,
|
|
||||||
# "normalised_score": normalised_score,
|
|
||||||
# "max_score": max_score,
|
|
||||||
# "answer_text": answer_text,
|
|
||||||
# # "answers_and_marks": answers_and_marks,
|
|
||||||
# "view_all_results": view_all_results,
|
|
||||||
# },
|
|
||||||
# )
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@@ -1288,7 +1089,7 @@ def question_review(request, pk):
|
|||||||
if not exam.publish_results:
|
if not exam.publish_results:
|
||||||
raise Http404
|
raise Http404
|
||||||
|
|
||||||
question = exam.exam_questions.all()[int(request.POST["question_number"])]
|
question = exam.get_questions()[int(request.POST["question_number"])]
|
||||||
|
|
||||||
question_json = question.get_question_json(based=False)
|
question_json = question.get_question_json(based=False)
|
||||||
return JsonResponse(question_json)
|
return JsonResponse(question_json)
|
||||||
|
|||||||
+3
-3
@@ -106,7 +106,7 @@ def exam_take_old(request, pk):
|
|||||||
if not exam.active:
|
if not exam.active:
|
||||||
raise exam_inactive(request)
|
raise exam_inactive(request)
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -141,7 +141,7 @@ def exam_take_overview(request, pk, cid=None, passcode=None):
|
|||||||
|
|
||||||
exam.check_user_can_take(cid, passcode, request.user)
|
exam.check_user_can_take(cid, passcode, request.user)
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
|
|
||||||
if cid is not None:
|
if cid is not None:
|
||||||
answers = UserAnswer.objects.filter(cid=cid, exam=exam)
|
answers = UserAnswer.objects.filter(cid=cid, exam=exam)
|
||||||
@@ -189,7 +189,7 @@ def exam_take(request, pk: int, sk: int, cid: str| None = None, passcode: str| N
|
|||||||
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user)
|
cid_user_exam = exam.get_or_create_cid_user_exam(cid=cid, user_user=request.user)
|
||||||
|
|
||||||
question = exam.exam_questions.all()[sk]
|
question = exam.get_questions()[sk]
|
||||||
|
|
||||||
exam_length = len(exam.exam_questions.all())
|
exam_length = len(exam.exam_questions.all())
|
||||||
|
|
||||||
|
|||||||
@@ -162,7 +162,6 @@ def user_scores(request, user=None):
|
|||||||
user = request.user
|
user = request.user
|
||||||
admin = False
|
admin = False
|
||||||
|
|
||||||
# questions = exam.exam_questions.all()
|
|
||||||
EXAM_ANSWER_MAP = {
|
EXAM_ANSWER_MAP = {
|
||||||
"physics": (PhysicsUserAnswer, PhysicsExam),
|
"physics": (PhysicsUserAnswer, PhysicsExam),
|
||||||
"anatomy": (AnatomyUserAnswer, AnatomyExam),
|
"anatomy": (AnatomyUserAnswer, AnatomyExam),
|
||||||
@@ -229,7 +228,6 @@ def cid_scores(request, cid, passcode):
|
|||||||
raise Http404("CID / Passcode combination not found")
|
raise Http404("CID / Passcode combination not found")
|
||||||
print(cid_user.passcode)
|
print(cid_user.passcode)
|
||||||
|
|
||||||
# questions = exam.exam_questions.all()
|
|
||||||
EXAM_ANSWER_MAP = {
|
EXAM_ANSWER_MAP = {
|
||||||
"physics": (PhysicsUserAnswer, PhysicsExam),
|
"physics": (PhysicsUserAnswer, PhysicsExam),
|
||||||
"anatomy": (AnatomyUserAnswer, AnatomyExam),
|
"anatomy": (AnatomyUserAnswer, AnatomyExam),
|
||||||
|
|||||||
@@ -487,9 +487,7 @@ def test_exams(db, client):
|
|||||||
== "4 (1 unmarked)"
|
== "4 (1 unmarked)"
|
||||||
)
|
)
|
||||||
|
|
||||||
for question in exam.exam_questions.all():
|
for question in exam.get_questions():
|
||||||
print(question)
|
|
||||||
print(question.get_compare_answers())
|
|
||||||
try:
|
try:
|
||||||
new_ans = Answer(
|
new_ans = Answer(
|
||||||
question=question,
|
question=question,
|
||||||
|
|||||||
+1
-6
@@ -402,11 +402,6 @@ class RapidUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
# save exam orders (there must be a better way to do this)
|
|
||||||
# exam_orders = {}
|
|
||||||
# for exam in self.object.exams.all():
|
|
||||||
# exam_orders[exam] = list(exam.exam_questions.all())
|
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
@@ -591,7 +586,7 @@ def mark(request, exam_pk, sk, unmarked_exam_answers_only=True, review=False):
|
|||||||
elif not unmarked_exam_answers_only:
|
elif not unmarked_exam_answers_only:
|
||||||
mark_url = "rapids:mark_all"
|
mark_url = "rapids:mark_all"
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
|
|
||||||
n = sk
|
n = sk
|
||||||
|
|
||||||
|
|||||||
+2
-8
@@ -121,7 +121,7 @@ def exam_take_overview(request, pk, cid=None, passcode=None):
|
|||||||
|
|
||||||
exam.check_user_can_take(cid, passcode, request.user)
|
exam.check_user_can_take(cid, passcode, request.user)
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.get_questions()
|
||||||
|
|
||||||
if cid is not None:
|
if cid is not None:
|
||||||
answers = UserAnswer.objects.filter(cid=cid, exam=exam)
|
answers = UserAnswer.objects.filter(cid=cid, exam=exam)
|
||||||
@@ -168,7 +168,7 @@ def exam_take(request, pk: int, sk: int, cid: int = None, passcode: str = None):
|
|||||||
|
|
||||||
cid_user_exam = exam.get_or_create_cid_user_exam(cid = cid, user_user=request.user)
|
cid_user_exam = exam.get_or_create_cid_user_exam(cid = cid, user_user=request.user)
|
||||||
|
|
||||||
question = exam.exam_questions.all()[sk]
|
question = exam.get_questions()[sk]
|
||||||
|
|
||||||
exam_length = len(exam.exam_questions.all())
|
exam_length = len(exam.exam_questions.all())
|
||||||
|
|
||||||
@@ -328,12 +328,6 @@ class QuestionUpdate(RevisionMixin, AuthorOrCheckerRequiredMixin, UpdateView):
|
|||||||
return context
|
return context
|
||||||
|
|
||||||
def form_valid(self, form):
|
def form_valid(self, form):
|
||||||
# save exam orders (there must be a better way to do this)
|
|
||||||
# exam_orders = {}
|
|
||||||
# for exam in self.object.exams.all():
|
|
||||||
# exam_orders[exam] = list(exam.exam_questions.all())
|
|
||||||
# print(exam_orders[exam])
|
|
||||||
|
|
||||||
self.object = form.save(commit=False)
|
self.object = form.save(commit=False)
|
||||||
self.object.save()
|
self.object.save()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user