Merge ssh://penracourses.org.uk:/home/django/rad
This commit is contained in:
+11
-5
@@ -157,8 +157,8 @@ class AnatomyQuestion(models.Model):
|
|||||||
exams = ", ".join(e)
|
exams = ", ".join(e)
|
||||||
return exams
|
return exams
|
||||||
|
|
||||||
def get_unmarked_answer_string(self):
|
def get_unmarked_answer_string(self, exam_pk=None):
|
||||||
unmarked_answers = self.get_unmarked_answers()
|
unmarked_answers = self.get_unmarked_answers(exam_pk)
|
||||||
|
|
||||||
if not unmarked_answers:
|
if not unmarked_answers:
|
||||||
return "No answers to mark"
|
return "No answers to mark"
|
||||||
@@ -168,16 +168,22 @@ class AnatomyQuestion(models.Model):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_unmarked_answers(self):
|
def get_unmarked_answers(self, exam_pk=None):
|
||||||
|
if exam_pk is None:
|
||||||
user_answers = set(
|
user_answers = set(
|
||||||
[i.answer_compare for i in self.cid_user_answers.all()]
|
[i.answer_compare for i in self.cid_user_answers.all()]
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
user_answers = set(
|
||||||
|
[i.answer_compare for i in self.cid_user_answers.filter(exam__id=exam_pk)]
|
||||||
|
)
|
||||||
|
|
||||||
unmarked_answers = user_answers - self.get_marked_answers()
|
unmarked_answers = user_answers - self.get_marked_answers()
|
||||||
|
|
||||||
return unmarked_answers
|
return unmarked_answers
|
||||||
|
|
||||||
def get_unmarked_answer_count(self):
|
def get_unmarked_answer_count(self, exam_pk=None):
|
||||||
return len(self.get_unmarked_answers())
|
return len(self.get_unmarked_answers(exam_pk))
|
||||||
|
|
||||||
def get_marked_answers(self):
|
def get_marked_answers(self):
|
||||||
return set(
|
return set(
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ a:link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.answer-list.rapid .correct::after {
|
.answer-list.rapid .correct::after {
|
||||||
content: " [Score = 1]";
|
content: " [Score = 2]";
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-list .half-correct {
|
.answer-list .half-correct {
|
||||||
@@ -53,7 +53,7 @@ a:link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.answer-list.rapid .half-correct::after {
|
.answer-list.rapid .half-correct::after {
|
||||||
content: " [Score = 0.5]";
|
content: " [Score = 1]";
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-list .incorrect {
|
.answer-list .incorrect {
|
||||||
@@ -377,11 +377,11 @@ img.uploading {
|
|||||||
color: lightblue;
|
color: lightblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rapid-ans.user-answer-score-1 {
|
.rapid-ans.user-answer-score-2 {
|
||||||
color: lightblue;
|
color: lightblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rapid-ans.user-answer-score-0\.5 {
|
.rapid-ans.user-answer-score-1 {
|
||||||
/* color: green; */
|
/* color: green; */
|
||||||
color: yellow;
|
color: yellow;
|
||||||
}
|
}
|
||||||
@@ -402,11 +402,11 @@ td.user-answer-score-2::after {
|
|||||||
content: "✓✓";
|
content: "✓✓";
|
||||||
}
|
}
|
||||||
|
|
||||||
td.user-answer-score-0\.5.rapid-ans::after {
|
td.user-answer-score-1.rapid-ans::after {
|
||||||
content: "✓";
|
content: "✓";
|
||||||
}
|
}
|
||||||
|
|
||||||
td.user-answer-score-1.rapid-ans::after {
|
td.user-answer-score-2.rapid-ans::after {
|
||||||
content: "✓✓";
|
content: "✓✓";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,3 +700,13 @@ input {
|
|||||||
background-color: green;
|
background-color: green;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.id {
|
||||||
|
opacity: 50%;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-alert {
|
||||||
|
position: sticky;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
@@ -59,10 +59,9 @@ $(document).ready(function () {
|
|||||||
$("#question-mark-list li").show();
|
$("#question-mark-list li").show();
|
||||||
});
|
});
|
||||||
$(".show-unmarked-button").click(() => {
|
$(".show-unmarked-button").click(() => {
|
||||||
console.log("TESTIG");
|
|
||||||
$("#question-mark-list li").each((n, el) => {
|
$("#question-mark-list li").each((n, el) => {
|
||||||
console.log(el);
|
// Can't seem to get django to output this as a int....
|
||||||
if (el.dataset.markcount < 1) { $(el).hide(); }
|
if (parseInt(el.dataset.markcount) < 1) { $(el).hide(); }
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@
|
|||||||
{{ question.question_type }}: {{ question.get_primary_answer }}
|
{{ question.question_type }}: {{ question.get_primary_answer }}
|
||||||
<br />
|
<br />
|
||||||
Modality: {{ question.modality }}, <a href="{% url 'anatomy:question_detail' pk=question.pk %}">View</a>, <a href="{% url 'anatomy:mark' pk=exam.pk sk=forloop.counter0 %}">Mark</a>
|
Modality: {{ question.modality }}, <a href="{% url 'anatomy:question_detail' pk=question.pk %}">View</a>, <a href="{% url 'anatomy:mark' pk=exam.pk sk=forloop.counter0 %}">Mark</a>
|
||||||
|
<span class="id">[id: {{question.pk}}]</span>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ol>
|
</ol>
|
||||||
|
|||||||
@@ -20,13 +20,13 @@
|
|||||||
Marked:
|
Marked:
|
||||||
<ul id="marked-answer-list" class="answer-list">
|
<ul id="marked-answer-list" class="answer-list">
|
||||||
{% for answer in correct_answers %}
|
{% for answer in correct_answers %}
|
||||||
<li><pre><span class="answer correct">{{ answer }}</span></pre></li>
|
<li><pre><span class="answer correct" title="{{answer}}">{{ answer }}</span></pre></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for answer in half_mark_answers %}
|
{% for answer in half_mark_answers %}
|
||||||
<li><pre><span class="answer half-correct">{{ answer }}</span></pre></li>
|
<li><pre><span class="answer half-correct" title="{{answer}}">{{ answer }}</span></pre></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for answer in incorrect_answers %}
|
{% for answer in incorrect_answers %}
|
||||||
<li><pre><span class="answer incorrect">{{ answer }}</span></pre></li>
|
<li><pre><span class="answer incorrect" title="{{answer}}">{{ answer }}</span></pre></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="answer-list key">Key: <span class="correct">2 Marks</span>, <span class="half-correct">1
|
<div class="answer-list key">Key: <span class="correct">2 Marks</span>, <span class="half-correct">1
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
<div id="stark-marking-button"><a href="{% url 'anatomy:mark' pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
<div id="stark-marking-button"><a href="{% url 'anatomy:mark' pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
||||||
|
|
||||||
<ul id="question-mark-list">
|
<ul id="question-mark-list">
|
||||||
{% for question in questions.all %}
|
{% for question, unmarked_count in question_unmarked_map %}
|
||||||
<li data-markcount={{question.get_unmarked_answer_count}}><a href="{% url 'anatomy:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
<li data-markcount={{unmarked_count}} {% if unmarked_count %}class="unmarked" {% endif %}><a href="{% url 'anatomy:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||||
{{ question }}</a><br /> {{ question.get_unmarked_answer_string }}</li>
|
{{ question }}</a><br />Unmarked answers: {{ unmarked_count }}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+9
-4
@@ -321,9 +321,10 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(new_order)])
|
preserved = Case(*[When(pk=pk, then=pos) for pos, pk in enumerate(new_order)])
|
||||||
objects = self.Question.objects.filter(pk__in=new_order).order_by(preserved)
|
objects = self.Question.objects.filter(pk__in=new_order).order_by(preserved)
|
||||||
|
|
||||||
if len(objects) != exam.exam_questions.count():
|
# We now allow deleting exam questions
|
||||||
data = {"status": "error, count does not match"}
|
#if len(objects) != exam.exam_questions.count():
|
||||||
return JsonResponse(data, status=400)
|
# data = {"status": "error, count does not match"}
|
||||||
|
# return JsonResponse(data, status=400)
|
||||||
|
|
||||||
exam.exam_questions.set(objects)
|
exam.exam_questions.set(objects)
|
||||||
exam.save()
|
exam.save()
|
||||||
@@ -366,9 +367,13 @@ class ExamViews(View, LoginRequiredMixin):
|
|||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.exam_questions.all()
|
||||||
|
|
||||||
|
question_unmarked_map = []
|
||||||
|
for q in questions:
|
||||||
|
question_unmarked_map.append((q, int(q.get_unmarked_answer_count())))
|
||||||
|
|
||||||
# TODO: fix showing unmarked answer count from other exams...
|
# TODO: fix showing unmarked answer count from other exams...
|
||||||
return render(
|
return render(
|
||||||
request, "{}/mark_overview.html".format(self.app_name), {"exam": exam, "questions": questions}
|
request, "{}/mark_overview.html".format(self.app_name), {"exam": exam, "question_unmarked_map": question_unmarked_map}
|
||||||
)
|
)
|
||||||
|
|
||||||
@method_decorator(login_required)
|
@method_decorator(login_required)
|
||||||
|
|||||||
+10
-2
@@ -175,12 +175,20 @@ class Long(models.Model):
|
|||||||
def get_image_url_array(self):
|
def get_image_url_array(self):
|
||||||
return json.dumps(["https://www.penracourses.org.uk{}".format(i.url) for i in self.get_images()])
|
return json.dumps(["https://www.penracourses.org.uk{}".format(i.url) for i in self.get_images()])
|
||||||
|
|
||||||
def get_unmarked_answer_count(self):
|
def get_unmarked_answer_count(self, exam_pk=None):
|
||||||
|
if exam_pk is None:
|
||||||
answers = self.cid_user_answers.all()
|
answers = self.cid_user_answers.all()
|
||||||
|
else:
|
||||||
|
answers = self.cid_user_answers.filter(exam__id=exam_pk)
|
||||||
|
|
||||||
return len([ans for ans in answers if not ans.is_marked()])
|
return len([ans for ans in answers if not ans.is_marked()])
|
||||||
|
|
||||||
def get_unmarked_answers(self):
|
def get_unmarked_answers(self, exam_pk=None):
|
||||||
|
if exam_pk is None:
|
||||||
answers = self.cid_user_answers.all()
|
answers = self.cid_user_answers.all()
|
||||||
|
else:
|
||||||
|
answers = self.cid_user_answers.filter(exam__id=exam_pk)
|
||||||
|
|
||||||
return [ans for ans in answers if not ans.is_marked()]
|
return [ans for ans in answers if not ans.is_marked()]
|
||||||
|
|
||||||
def get_question_json(self, based=True):
|
def get_question_json(self, based=True):
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ class UserAnswerTable(tables.Table):
|
|||||||
fields = (
|
fields = (
|
||||||
"cid",
|
"cid",
|
||||||
"question",
|
"question",
|
||||||
|
"score",
|
||||||
#"normal",
|
#"normal",
|
||||||
#"answer",
|
#"answer",
|
||||||
#"answer_compare",
|
#"answer_compare",
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
|
{% extends 'longs/base.html' %}
|
||||||
{% extends 'rapids/base.html' %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
CID: {{ciduseranswer.cid}}
|
CID: {{ciduseranswer.cid}}
|
||||||
@@ -8,11 +7,16 @@ CID: {{ciduseranswer.cid}}
|
|||||||
{{ciduseranswer.question}}
|
{{ciduseranswer.question}}
|
||||||
|
|
||||||
<h3>Answers</h3>
|
<h3>Answers</h3>
|
||||||
{{ciduseranswer.model_observations}}<br/>
|
<h4>Observation</h4>
|
||||||
{{ciduseranswer.model_interpretation}}<br/>
|
<pre>{{ciduseranswer.answer_observations}}</pre><br />
|
||||||
{{ciduseranswer.model_principle_diagnosis}}<br/>
|
<h4>Interpretation</h4>
|
||||||
{{ciduseranswer.model_differential_diagnosis}}<br/>
|
<pre>{{ciduseranswer.answer_interpretation}}</pre><br />
|
||||||
{{ciduseranswer.model_management}}<br/>
|
<h4>Principle Diagnosis</h4>
|
||||||
|
<pre>{{ciduseranswer.answer_principle_diagnosis}}</pre><br />
|
||||||
|
<h4>Differential Diagnosis</h4>
|
||||||
|
<pre>{{ciduseranswer.answer_differential_diagnosis}}</pre><br />
|
||||||
|
<h4>Managment</h4>
|
||||||
|
<pre>{{ciduseranswer.answer_management}}</pre><br />
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@
|
|||||||
<a href="{% url 'longs:exam_question_detail' exam.id forloop.counter0 %}"
|
<a href="{% url 'longs:exam_question_detail' exam.id forloop.counter0 %}"
|
||||||
title="View the question">View</a> / <a href="{% url 'longs:long_update' question.id %}"
|
title="View the question">View</a> / <a href="{% url 'longs:long_update' question.id %}"
|
||||||
title="Edit the question">Edit</a>
|
title="Edit the question">Edit</a>
|
||||||
|
<span class="id">[id: {{question.pk}}]</span>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
<span class="flex-col-3">
|
<span class="flex-col-3">
|
||||||
|
|||||||
@@ -44,14 +44,14 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Candidate</th>
|
<th>Candidate</th>
|
||||||
{% for cid in cids %}
|
{% for cid in cids %}
|
||||||
<th>{{cid}}</th>
|
<th><a href="{% url 'longs:exam_scores_cid_user' exam.pk cid %}">{{cid}}</a></th>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{% for question in questions %}
|
{% for question in questions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td>Question {{forloop.counter}}</td>
|
<td><a href="{% url 'longs:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a></td>
|
||||||
{% for ans, score in by_question|get_item:question %}
|
{% for ans, score in by_question|get_item:question %}
|
||||||
<td class="user-answer-score-{{score}}" title="answer score: {{score}}">{{score}}</td>
|
<td class="user-answer-score-{{score}}" title="answer score: {{score}}">{{score}}</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -2,6 +2,9 @@
|
|||||||
<div class="date">
|
<div class="date">
|
||||||
{{ question.created_date|date:"d/m/Y" }}
|
{{ question.created_date|date:"d/m/Y" }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="id">
|
||||||
|
ID: {{ question.id }}
|
||||||
|
</div>
|
||||||
<p class="pre-whitespace"><b>Description:</b> {{ question.description }}</p>
|
<p class="pre-whitespace"><b>Description:</b> {{ question.description }}</p>
|
||||||
|
|
||||||
<p class="pre-whitespace"><b>History:</b> {{ question.history }}</p>
|
<p class="pre-whitespace"><b>History:</b> {{ question.history }}</p>
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
{% extends 'longs/exams.html' %}
|
{% extends 'longs/exams.html' %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<a href="{% url 'longs:exam_question_detail' exam.id question_details.current %}" title="View the Question">View</a>
|
<a href="{% url 'longs:exam_question_detail' exam.id question_details.current|add:'-1' %}"
|
||||||
|
title="View the Question">View</a>
|
||||||
<a href="{% url 'longs:long_update' question.id %}" title="Edit the Question">Edit</a> <a
|
<a href="{% url 'longs:long_update' question.id %}" title="Edit the Question">Edit</a> <a
|
||||||
href="{% url 'admin:longs_long_change' question.id %}" title="Edit the Question using the admin interface">Admin
|
href="{% url 'admin:longs_long_change' question.id %}" title="Edit the Question using the admin interface">Admin
|
||||||
Edit</a>
|
Edit</a>
|
||||||
|
|||||||
@@ -13,9 +13,19 @@
|
|||||||
title="View question answers">{{question_details.current}}</a> of {{question_details.total}}</h2>
|
title="View question answers">{{question_details.current}}</a> of {{question_details.total}}</h2>
|
||||||
|
|
||||||
{% if not next_unmarked_id and not unmarked %}
|
{% if not next_unmarked_id and not unmarked %}
|
||||||
<div class="alert alert-info" role="alert">Success! Marking question complete. <a
|
<div class="alert alert-info sticky-alert" role="alert">Success! Marking question complete. <br />Return to <a
|
||||||
href="{% url 'longs:mark_overview' pk=exam.pk %}">Return to marking
|
href="{% url 'longs:mark' exam.id question_details.current|add:'-1' %}">question
|
||||||
overview</a></div>
|
overview</a>, <a href="{% url 'longs:mark_overview' pk=exam.pk %}">marking
|
||||||
|
overview</a><br />
|
||||||
|
{% if previous_cid %}
|
||||||
|
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=previous_cid %}">Previous
|
||||||
|
candidate</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if next_cid %}
|
||||||
|
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=next_cid %}">Next
|
||||||
|
candidate</a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
<span>Marking CID: {{answer.cid}} ({{unmarked|length}} answer(s) left to mark)</span>
|
<span>Marking CID: {{answer.cid}} ({{unmarked|length}} answer(s) left to mark)</span>
|
||||||
@@ -89,4 +99,11 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
{% if previous_cid %}
|
||||||
|
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=previous_cid %}">Previous
|
||||||
|
candidate</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if next_cid %}
|
||||||
|
<a href="{% url 'longs:mark_answer' pk=exam.pk sk=question_details.current|add:'-1' cid=next_cid %}">Next candidate</a>
|
||||||
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
@@ -8,14 +8,14 @@
|
|||||||
<div>
|
<div>
|
||||||
<button class="show-all-button">Show all</button><button class="show-unmarked-button">Show unmarked</button>
|
<button class="show-all-button">Show all</button><button class="show-unmarked-button">Show unmarked</button>
|
||||||
</div>
|
</div>
|
||||||
<div id="stark-marking-button"><a href="{% url 'longs:mark' pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
<div id="stark-marking-button"><a href="{% url 'longs:mark' pk=exam.pk sk=0 %}"><button>Click here to start
|
||||||
|
marking</button></a></div>
|
||||||
|
|
||||||
<ul id="question-mark-list">
|
<ul id="question-mark-list">
|
||||||
{% for question in questions.all %}
|
{% for question, unmarked_count in question_unmarked_map %}
|
||||||
<li data-markcount={{question.get_unmarked_answer_count}}
|
<li data-markcount={{unmarked_count}} {% if unmarked_count %}class="unmarked" {% endif %}><a
|
||||||
{% if question.get_unmarked_answer_count %}class="unmarked" {% endif %}
|
href="{% url 'longs:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||||
><a href="{% url 'longs:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
{{ question }}</a><br /> Answers to mark: {{unmarked_count}}</li>
|
||||||
{{ question }}</a><br /> Answers to mark: {{question.get_unmarked_answer_count}}</li>
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ urlpatterns = [
|
|||||||
# path("all_questions/", views.all_questions, name="all_questions"),
|
# path("all_questions/", views.all_questions, name="all_questions"),
|
||||||
path("question/<int:pk>/scrap", views.long_scrap, name="long_scrap"),
|
path("question/<int:pk>/scrap", views.long_scrap, name="long_scrap"),
|
||||||
path("question/<int:pk>/delete", views.LongDelete.as_view(), name="long_delete"),
|
path("question/<int:pk>/delete", views.LongDelete.as_view(), name="long_delete"),
|
||||||
path("exam/<int:pk>/<int:sk>/<int:tk>/mark", views.mark_answer, name="mark_answer"),
|
path("exam/<int:pk>/<int:sk>/<int:cid>/mark", views.mark_answer, name="mark_answer"),
|
||||||
path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
path("exam/<int:pk>/<int:sk>/mark", views.mark, name="mark"),
|
||||||
path("exam/<int:pk>/mark", views.LongExamViews.mark_overview, name="mark_overview"),
|
path("exam/<int:pk>/mark", views.LongExamViews.mark_overview, name="mark_overview"),
|
||||||
# path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
# path("exam/<int:pk>/<int:sk>/", views.exam_take, name="exam_take"),
|
||||||
|
|||||||
+33
-6
@@ -468,6 +468,10 @@ class LongUpdate(RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin
|
|||||||
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()
|
||||||
@@ -486,6 +490,14 @@ class LongUpdate(RevisionMixin, LoginRequiredMixin, AuthorOrCheckerRequiredMixin
|
|||||||
response = super().form_valid(form)
|
response = super().form_valid(form)
|
||||||
series_formset.instance = self.object
|
series_formset.instance = self.object
|
||||||
series_formset.save()
|
series_formset.save()
|
||||||
|
|
||||||
|
# restore exam orders
|
||||||
|
for exam in self.object.exams.all():
|
||||||
|
if exam in exam_orders and self.object in exam_orders[exam]:
|
||||||
|
print(exam_orders[exam])
|
||||||
|
exam.exam_questions.set(exam_orders[exam])
|
||||||
|
exam.save()
|
||||||
|
|
||||||
return response
|
return response
|
||||||
else:
|
else:
|
||||||
return super().form_invalid(form)
|
return super().form_invalid(form)
|
||||||
@@ -639,7 +651,7 @@ def loadJsonAnswer(answer):
|
|||||||
@login_required
|
@login_required
|
||||||
@user_is_long_marker
|
@user_is_long_marker
|
||||||
@reversion.create_revision()
|
@reversion.create_revision()
|
||||||
def mark_answer(request, pk, sk, tk):
|
def mark_answer(request, pk, sk, cid):
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
exam = get_object_or_404(Exam, pk=pk)
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.exam_questions.all()
|
||||||
@@ -657,14 +669,27 @@ def mark_answer(request, pk, sk, tk):
|
|||||||
raise Http404("Exam question does not exist")
|
raise Http404("Exam question does not exist")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
answer = question.cid_user_answers.get(cid=tk, exam__id=pk)
|
answer = question.cid_user_answers.get(cid=cid, exam__id=pk)
|
||||||
except ObjectDoesNotExist:
|
except ObjectDoesNotExist:
|
||||||
raise Http404("User answer does not exist")
|
raise Http404("User answer does not exist")
|
||||||
|
|
||||||
|
cid_list = list(question.cid_user_answers.filter(exam__id=pk).values_list("cid", flat=True))
|
||||||
|
|
||||||
|
previous_cid = False
|
||||||
|
next_cid = False
|
||||||
|
|
||||||
|
if cid_list[0] == cid:
|
||||||
|
next_cid = cid_list[1]
|
||||||
|
elif cid_list[-1] == cid:
|
||||||
|
previous_cid = cid_list[-2]
|
||||||
|
else:
|
||||||
|
next_cid = cid_list[cid_list.index(cid)+1]
|
||||||
|
previous_cid = cid_list[cid_list.index(cid)-1]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
unmarked = question.get_unmarked_answers()
|
unmarked = question.get_unmarked_answers()
|
||||||
next_unmarked_id = unmarked[0].cid
|
next_unmarked_id = unmarked[0].cid
|
||||||
if next_unmarked_id == tk:
|
if next_unmarked_id == cid:
|
||||||
next_unmarked_id = unmarked[1].cid
|
next_unmarked_id = unmarked[1].cid
|
||||||
except IndexError:
|
except IndexError:
|
||||||
next_unmarked_id = False
|
next_unmarked_id = False
|
||||||
@@ -677,16 +702,16 @@ def mark_answer(request, pk, sk, tk):
|
|||||||
# If skip button is pressed skip the question without marking
|
# If skip button is pressed skip the question without marking
|
||||||
# Skip is problematic if we skip to the next unmarked answer
|
# Skip is problematic if we skip to the next unmarked answer
|
||||||
#if "skip" in request.POST:
|
#if "skip" in request.POST:
|
||||||
# return redirect("longs:mark_answer", pk=pk, sk=sk, tk=next_unmarked_id)
|
# return redirect("longs:mark_answer", pk=pk, sk=sk, cid=next_unmarked_id)
|
||||||
|
|
||||||
# Extract score from form and save it to the object
|
# Extract score from form and save it to the object
|
||||||
answer.score = form.cleaned_data["score"]
|
answer.score = form.cleaned_data["score"]
|
||||||
answer.save()
|
answer.save()
|
||||||
|
|
||||||
if "next" in request.POST:
|
if "next" in request.POST:
|
||||||
return redirect("longs:mark_answer", pk=pk, sk=sk, tk=next_unmarked_id)
|
return redirect("longs:mark_answer", pk=pk, sk=sk, cid=next_unmarked_id)
|
||||||
if "save" in request.POST:
|
if "save" in request.POST:
|
||||||
return redirect("longs:mark_answer", pk=pk, sk=sk, tk=tk)
|
return redirect("longs:mark_answer", pk=pk, sk=sk, cid=cid)
|
||||||
#elif "previous" in request.POST:
|
#elif "previous" in request.POST:
|
||||||
# return redirect("longs:mark", pk=pk, sk=n - 1)
|
# return redirect("longs:mark", pk=pk, sk=n - 1)
|
||||||
|
|
||||||
@@ -705,6 +730,8 @@ def mark_answer(request, pk, sk, tk):
|
|||||||
"question_details": question_details,
|
"question_details": question_details,
|
||||||
"next_unmarked_id": next_unmarked_id,
|
"next_unmarked_id": next_unmarked_id,
|
||||||
"unmarked": unmarked,
|
"unmarked": unmarked,
|
||||||
|
"previous_cid": previous_cid,
|
||||||
|
"next_cid": next_cid,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
+26
-8
@@ -231,8 +231,8 @@ class Rapid(models.Model):
|
|||||||
exams = ", ".join(e)
|
exams = ", ".join(e)
|
||||||
return exams
|
return exams
|
||||||
|
|
||||||
def get_unmarked_answer_string(self):
|
def get_unmarked_answer_string(self, exam_pk=None):
|
||||||
unmarked_answers = self.get_unmarked_answers()
|
unmarked_answers = self.get_unmarked_answers(exam_pk)
|
||||||
|
|
||||||
if not unmarked_answers:
|
if not unmarked_answers:
|
||||||
return "No answers to mark"
|
return "No answers to mark"
|
||||||
@@ -242,20 +242,38 @@ class Rapid(models.Model):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_unmarked_answers(self):
|
def get_unmarked_answers(self, exam_pk=None):
|
||||||
# If normal no answers to mark
|
# If normal no answers to mark
|
||||||
if self.normal:
|
if self.normal:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
|
if exam_pk is None:
|
||||||
user_answers = set(
|
user_answers = set(
|
||||||
[i.answer_compare for i in self.cid_user_answers.all() if i.normal == False]
|
[i.answer_compare for i in self.cid_user_answers.all() if i.normal == False]
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
user_answers = set(
|
||||||
|
[i.answer_compare for i in self.cid_user_answers.filter(exam__id=exam_pk) if i.normal == False]
|
||||||
|
)
|
||||||
|
|
||||||
unmarked_answers = user_answers - self.get_marked_answers()
|
unmarked_answers = user_answers - self.get_marked_answers()
|
||||||
|
|
||||||
return unmarked_answers
|
return unmarked_answers
|
||||||
|
|
||||||
def get_unmarked_answer_count(self):
|
def get_unmarked_answer_count(self, exam_pk=None):
|
||||||
return len(self.get_unmarked_answers())
|
return len(self.get_unmarked_answers(exam_pk))
|
||||||
|
|
||||||
|
def get_user_answers(self, exam_pk=None):
|
||||||
|
if exam_pk is None:
|
||||||
|
user_answers = set(
|
||||||
|
[i.answer_compare for i in self.cid_user_answers.all()]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
user_answers = set(
|
||||||
|
[i.answer_compare for i in self.cid_user_answers.filter(exam__id=exam_pk)]
|
||||||
|
)
|
||||||
|
|
||||||
|
return user_answers
|
||||||
|
|
||||||
def get_compare_answers(self):
|
def get_compare_answers(self):
|
||||||
return set(
|
return set(
|
||||||
@@ -601,7 +619,7 @@ class CidUserAnswer(models.Model):
|
|||||||
return 0
|
return 0
|
||||||
# If both are normal full marks
|
# If both are normal full marks
|
||||||
elif q.normal and self.normal:
|
elif q.normal and self.normal:
|
||||||
return 1
|
return 2
|
||||||
|
|
||||||
# Then compare answer strings (as per anatomy questions)
|
# Then compare answer strings (as per anatomy questions)
|
||||||
ans = self.answer_compare
|
ans = self.answer_compare
|
||||||
@@ -616,9 +634,9 @@ class CidUserAnswer(models.Model):
|
|||||||
mark = "unmarked"
|
mark = "unmarked"
|
||||||
if marked_ans is not None:
|
if marked_ans is not None:
|
||||||
if marked_ans.status == Answer.MarkOptions.CORRECT:
|
if marked_ans.status == Answer.MarkOptions.CORRECT:
|
||||||
mark = 1
|
mark = 2
|
||||||
elif marked_ans.status == Answer.MarkOptions.HALF_MARK:
|
elif marked_ans.status == Answer.MarkOptions.HALF_MARK:
|
||||||
mark = 0.5
|
mark = 1
|
||||||
elif marked_ans.status == Answer.MarkOptions.INCORRECT:
|
elif marked_ans.status == Answer.MarkOptions.INCORRECT:
|
||||||
mark = 0
|
mark = 0
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,12 @@
|
|||||||
<h1>Exam: {{ exam.name }}</h1>
|
<h1>Exam: {{ exam.name }}</h1>
|
||||||
This exam has {{question_number}} questions. Time limit: {{exam.time_limit}} seconds.<br />
|
This exam has {{question_number}} questions. Time limit: {{exam.time_limit}} seconds.<br />
|
||||||
<div class="parent-help" title="">
|
<div class="parent-help" title="">
|
||||||
Normal count: {{ exam.get_normal_abnormal_breakdown }}<span
|
Normal count: {{ exam.get_normal_abnormal_breakdown }}<span class="help-text">[Number of normal questions within
|
||||||
class="help-text">[Number of normal questions within the exam]</span>
|
the exam]</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="parent-help" title="">
|
<div class="parent-help" title="">
|
||||||
Exam mode: {{ exam.exam_mode }}<span
|
Exam mode: {{ exam.exam_mode }}<span class="help-text">[When true the packet will be taken as an exam (it will
|
||||||
class="help-text">[When true the packet will be taken as an exam (it will not self mark and results will be saved here)]</span>
|
not self mark and results will be saved here)]</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="parent-help" title="Click to enable / disable the exam">
|
<div class="parent-help" title="Click to enable / disable the exam">
|
||||||
@@ -55,6 +55,7 @@
|
|||||||
Examination: {{ question.get_examinations }}, <a
|
Examination: {{ question.get_examinations }}, <a
|
||||||
href="{% url 'rapids:question_detail' pk=question.pk %}">View</a>, <a
|
href="{% url 'rapids:question_detail' pk=question.pk %}">View</a>, <a
|
||||||
href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Mark</a>
|
href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Mark</a>
|
||||||
|
<span class="id">[id: {{question.pk}}]</span>
|
||||||
</span>
|
</span>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
@@ -64,7 +65,7 @@
|
|||||||
{{ author }},
|
{{ author }},
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<p><button id='button-edit-order'>Edit exam order</button></p>
|
<p><button id='button-edit-order' title='click and drag questions to change order'>Edit exam order</button></p>
|
||||||
<div>
|
<div>
|
||||||
JSON creation time: {{exam.json_creation_time}} ({{exam.json_creation_time|date:"c"}}),
|
JSON creation time: {{exam.json_creation_time}} ({{exam.json_creation_time|date:"c"}}),
|
||||||
JSON creation id: {{exam.exam_json_id}}
|
JSON creation id: {{exam.exam_json_id}}
|
||||||
@@ -187,7 +188,15 @@
|
|||||||
$(this).remove();
|
$(this).remove();
|
||||||
sortable('.sortable');
|
sortable('.sortable');
|
||||||
|
|
||||||
$("#full-question-list").append($("<button>Save exam order</button>").click(() => {
|
$("#full-question-list li").each((n, el) => {
|
||||||
|
$(el).append($(
|
||||||
|
"<span class='exam-question-delete flex-col'><button>DELETE</button></span>"
|
||||||
|
).click(() => {
|
||||||
|
el.remove();
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
|
||||||
|
$("#full-question-list").append($("<button title='click and drag questions to change order'>Save exam order</button>").click(() => {
|
||||||
new_order = [];
|
new_order = [];
|
||||||
$("#full-question-list li").each((n, el) => {
|
$("#full-question-list li").each((n, el) => {
|
||||||
new_order.push(el.dataset.question_pk)
|
new_order.push(el.dataset.question_pk)
|
||||||
|
|||||||
@@ -44,14 +44,20 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th>Candidate</th>
|
<th>Candidate</th>
|
||||||
{% for cid in cids %}
|
{% for cid in cids %}
|
||||||
<th>{{cid}}</th>
|
<th><a href="{% url 'rapids:exam_scores_cid_user' exam.pk cid %}">{{cid}}</a></th>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{% for question in questions %}
|
{% for question in questions %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a></td>
|
<td><a href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter}}</a>
|
||||||
|
{% if question.normal %}
|
||||||
|
[N]
|
||||||
|
{% else %}
|
||||||
|
[A]
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
{% for ans, score in by_question|get_item:question %}
|
{% for ans, score in by_question|get_item:question %}
|
||||||
<td class="rapid-ans user-answer-score-{{score}}" title="answer score: {{score}}">{{ans}}</td>
|
<td class="rapid-ans user-answer-score-{{score}}" title="answer score: {{score}}">{{ans}}</td>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -2,15 +2,29 @@
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Marking question {{question_details.current}} of {{question_details.total}}</h2>
|
<h2>Marking question {{question_details.current}} of {{question_details.total}}</h2>
|
||||||
<a href="{% url 'rapids:question_detail' question.id %}" title="View the Question">View</a> <a href="{% url 'rapids:rapid_update' question.id %}" title="Edit the Question">Edit</a> <a
|
<a href="{% url 'rapids:question_detail' question.id %}" title="View the Question">View</a> <a
|
||||||
|
href="{% url 'rapids:rapid_update' question.id %}" title="Edit the Question">Edit</a> <a
|
||||||
href="{% url 'admin:rapids_rapid_change' question.id %}" title="Edit the Question using the admin interface">Admin
|
href="{% url 'admin:rapids_rapid_change' question.id %}" title="Edit the Question using the admin interface">Admin
|
||||||
Edit</a>
|
Edit</a>
|
||||||
{% if question.normal %}
|
{% if question.normal %}
|
||||||
<h3>This question is normal</h3>
|
<h3>This question is normal</h3>
|
||||||
Answers will be automatically marked.
|
Answers will be automatically marked.<br />
|
||||||
|
|
||||||
|
{% if incorrect_answers %}
|
||||||
|
<p>The following answers have been submitted for this question</p>
|
||||||
|
<div class="marking-list">
|
||||||
|
<ul id="new-answer-list" class="answer-list rapid">
|
||||||
|
{% for answer in incorrect_answers %}
|
||||||
|
<li>
|
||||||
|
<pre><span class="answer incorrect" title="{{answer}}">{{ answer }}</span></pre>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<h3>This question is abnormal</h3>
|
<h3>This question is abnormal</h3>
|
||||||
Answers marked as normal will be automatically marked.<br/>
|
Answers marked as normal will be automatically marked.<br />
|
||||||
Region: {{ question.get_regions }}, Abnormalities: {{ question.get_abnormalities }}
|
Region: {{ question.get_regions }}, Abnormalities: {{ question.get_abnormalities }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div id="single-dicom-viewer" class="marking-dicom" data-images="{{question.get_image_url_array}}"
|
<div id="single-dicom-viewer" class="marking-dicom" data-images="{{question.get_image_url_array}}"
|
||||||
@@ -33,21 +47,21 @@ Region: {{ question.get_regions }}, Abnormalities: {{ question.get_abnormalities
|
|||||||
<ul id="marked-answer-list" class="answer-list rapid">
|
<ul id="marked-answer-list" class="answer-list rapid">
|
||||||
{% for answer in correct_answers %}
|
{% for answer in correct_answers %}
|
||||||
<li>
|
<li>
|
||||||
<pre><span class="answer correct">{{ answer }}</span></pre>
|
<pre><span class="answer correct" title="{{answer}}">{{ answer }}</span></pre>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for answer in half_mark_answers %}
|
{% for answer in half_mark_answers %}
|
||||||
<li>
|
<li>
|
||||||
<pre><span class="answer half-correct">{{ answer }}</span></pre>
|
<pre><span class="answer half-correct" title="{{answer}}">{{ answer }}</span></pre>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% for answer in incorrect_answers %}
|
{% for answer in incorrect_answers %}
|
||||||
<li>
|
<li>
|
||||||
<pre><span class="answer incorrect">{{ answer }}</span></pre>
|
<pre><span class="answer incorrect" title="{{answer}}">{{ answer }}</span></pre>
|
||||||
</li>
|
</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="answer-list key">Key: <span class="correct">1 Marks</span>, <span class="half-correct">0.5
|
<div class="answer-list key">Key: <span class="correct">2 Marks</span>, <span class="half-correct">1
|
||||||
Mark</span>, <span class="incorrect">0 Marks</span></div>
|
Mark</span>, <span class="incorrect">0 Marks</span></div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
<div id="stark-marking-button"><a href="{% url 'rapids:mark' pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
<div id="stark-marking-button"><a href="{% url 'rapids:mark' pk=exam.pk sk=0 %}"><button>Click here to start marking</button></a></div>
|
||||||
|
|
||||||
<ul id="question-mark-list">
|
<ul id="question-mark-list">
|
||||||
{% for question in questions.all %}
|
{% for question, unmarked_count in question_unmarked_map %}
|
||||||
<li data-markcount={{question.get_unmarked_answer_count}}><a href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
<li data-markcount={{unmarked_count}} {% if unmarked_count %}class="unmarked" {% endif %}><a href="{% url 'rapids:mark' pk=exam.pk sk=forloop.counter0 %}">Question {{forloop.counter }}:
|
||||||
{{ question }}</a><br /> {{ question.get_unmarked_answer_string }}</li>
|
{{ question }}</a><br />Unmarked answers: {{unmarked_count}}</li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
<div class="rapid {% if question.scrapped %}rapid-scrapped{% endif %}">
|
<div class="rapid {% if question.scrapped %}rapid-scrapped{% endif %}">
|
||||||
|
<button id="edit-button">Inline Edit</button>
|
||||||
<div class="date">
|
<div class="date">
|
||||||
{{ question.created_date|date:"d/m/Y" }}
|
{{ question.created_date|date:"d/m/Y" }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="id">
|
||||||
|
ID: {{ question.id }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<p class="pre-whitespace"><b>Rapid:</b> {{ question }}</p>
|
<p class="pre-whitespace"><b>Rapid:</b> {{ question }}</p>
|
||||||
<p class="pre-whitespace"><b>Normal:</b> {{ question.normal }} <button id="toggle-normal-button"
|
<p class="pre-whitespace"><b>Normal:</b> {{ question.normal }} <button id="toggle-normal-button"
|
||||||
@@ -107,6 +111,11 @@
|
|||||||
</details>
|
</details>
|
||||||
<script>
|
<script>
|
||||||
$(document).ready(function () {
|
$(document).ready(function () {
|
||||||
|
$("#edit-button").click(() => {
|
||||||
|
$(".toggle-button").toggle();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(".toggle-button").hide();
|
||||||
|
|
||||||
// send request to change the is_private state on customSwitches toggle
|
// send request to change the is_private state on customSwitches toggle
|
||||||
$("#save-annotations").click(function () {
|
$("#save-annotations").click(function () {
|
||||||
|
|||||||
+1
-1
@@ -56,7 +56,7 @@ urlpatterns = [
|
|||||||
),
|
),
|
||||||
path("exam/<int:pk>/scores", cache_page(60 * 1)(views.exam_scores_cid), name="exam_scores_cid"),
|
path("exam/<int:pk>/scores", cache_page(60 * 1)(views.exam_scores_cid), name="exam_scores_cid"),
|
||||||
path(
|
path(
|
||||||
"exam/<int:pk>/scores/<int:sk>/",
|
"exam/<int:pk>/scores/<int:cid>/",
|
||||||
views.exam_scores_cid_user,
|
views.exam_scores_cid_user,
|
||||||
name="exam_scores_cid_user",
|
name="exam_scores_cid_user",
|
||||||
),
|
),
|
||||||
|
|||||||
+11
-3
@@ -776,6 +776,14 @@ def mark(request, pk, sk):
|
|||||||
half_mark_answers = question.answers.filter(status=Answer.MarkOptions.HALF_MARK)
|
half_mark_answers = question.answers.filter(status=Answer.MarkOptions.HALF_MARK)
|
||||||
incorrect_answers = question.answers.filter(status=Answer.MarkOptions.INCORRECT)
|
incorrect_answers = question.answers.filter(status=Answer.MarkOptions.INCORRECT)
|
||||||
|
|
||||||
|
# this could be improved
|
||||||
|
if question.normal:
|
||||||
|
incorrect_answers = question.get_user_answers()
|
||||||
|
if "" in incorrect_answers:
|
||||||
|
incorrect_answers.remove("")
|
||||||
|
if "normal" in incorrect_answers:
|
||||||
|
incorrect_answers.remove("normal")
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
"rapids/mark.html",
|
"rapids/mark.html",
|
||||||
@@ -873,7 +881,7 @@ def exam_scores_cid(request, pk):
|
|||||||
)
|
)
|
||||||
fig_html = fig.to_html()
|
fig_html = fig.to_html()
|
||||||
|
|
||||||
max_score = len(questions)
|
max_score = len(questions) * 2
|
||||||
|
|
||||||
return render(
|
return render(
|
||||||
request,
|
request,
|
||||||
@@ -899,11 +907,11 @@ def exam_scores_cid(request, pk):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def exam_scores_cid_user(request, pk, sk):
|
def exam_scores_cid_user(request, pk, cid):
|
||||||
exam = get_object_or_404(Exam, pk=pk)
|
exam = get_object_or_404(Exam, pk=pk)
|
||||||
|
|
||||||
# TODO:Need some kind of test for cid
|
# TODO:Need some kind of test for cid
|
||||||
cid = sk
|
#cid = sk
|
||||||
|
|
||||||
questions = exam.exam_questions.all()
|
questions = exam.exam_questions.all()
|
||||||
|
|
||||||
|
|||||||
+16
-6
@@ -40,7 +40,7 @@ a:link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.answer-list.rapid .correct::after {
|
.answer-list.rapid .correct::after {
|
||||||
content: " [Score = 1]";
|
content: " [Score = 2]";
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-list .half-correct {
|
.answer-list .half-correct {
|
||||||
@@ -53,7 +53,7 @@ a:link {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.answer-list.rapid .half-correct::after {
|
.answer-list.rapid .half-correct::after {
|
||||||
content: " [Score = 0.5]";
|
content: " [Score = 1]";
|
||||||
}
|
}
|
||||||
|
|
||||||
.answer-list .incorrect {
|
.answer-list .incorrect {
|
||||||
@@ -377,11 +377,11 @@ img.uploading {
|
|||||||
color: lightblue;
|
color: lightblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rapid-ans.user-answer-score-1 {
|
.rapid-ans.user-answer-score-2 {
|
||||||
color: lightblue;
|
color: lightblue;
|
||||||
}
|
}
|
||||||
|
|
||||||
.rapid-ans.user-answer-score-0\.5 {
|
.rapid-ans.user-answer-score-1 {
|
||||||
/* color: green; */
|
/* color: green; */
|
||||||
color: yellow;
|
color: yellow;
|
||||||
}
|
}
|
||||||
@@ -402,11 +402,11 @@ td.user-answer-score-2::after {
|
|||||||
content: "✓✓";
|
content: "✓✓";
|
||||||
}
|
}
|
||||||
|
|
||||||
td.user-answer-score-0\.5.rapid-ans::after {
|
td.user-answer-score-1.rapid-ans::after {
|
||||||
content: "✓";
|
content: "✓";
|
||||||
}
|
}
|
||||||
|
|
||||||
td.user-answer-score-1.rapid-ans::after {
|
td.user-answer-score-2.rapid-ans::after {
|
||||||
content: "✓✓";
|
content: "✓✓";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -700,3 +700,13 @@ input {
|
|||||||
background-color: green;
|
background-color: green;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.id {
|
||||||
|
opacity: 50%;
|
||||||
|
font-size: small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-alert {
|
||||||
|
position: sticky;
|
||||||
|
top: 5px;
|
||||||
|
}
|
||||||
@@ -59,10 +59,9 @@ $(document).ready(function () {
|
|||||||
$("#question-mark-list li").show();
|
$("#question-mark-list li").show();
|
||||||
});
|
});
|
||||||
$(".show-unmarked-button").click(() => {
|
$(".show-unmarked-button").click(() => {
|
||||||
console.log("TESTIG");
|
|
||||||
$("#question-mark-list li").each((n, el) => {
|
$("#question-mark-list li").each((n, el) => {
|
||||||
console.log(el);
|
// Can't seem to get django to output this as a int....
|
||||||
if (el.dataset.markcount < 1) { $(el).hide(); }
|
if (parseInt(el.dataset.markcount) < 1) { $(el).hide(); }
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user