many improvement

This commit is contained in:
Ross
2020-10-19 17:05:59 +01:00
parent 55c596006e
commit 9d3957226d
15 changed files with 85 additions and 46 deletions
+2
View File
@@ -1,3 +1,5 @@
media/ media/
static/
__pycache__ __pycache__
.vscode/ .vscode/
+2 -2
View File
@@ -6,7 +6,7 @@ from .models import (
Answers, Answers,
HalfMarkAnswers, HalfMarkAnswers,
IncorrectAnswers, IncorrectAnswers,
UserAnswer, CidUserAnswer,
Exam, Exam,
Modality, Modality,
BodyPart, BodyPart,
@@ -48,7 +48,7 @@ class AnatomyAdmin(VersionAdmin):
admin.site.register(AnatomyQuestion, AnatomyAdmin) admin.site.register(AnatomyQuestion, AnatomyAdmin)
admin.site.register(Examination) admin.site.register(Examination)
admin.site.register(QuestionType) admin.site.register(QuestionType)
admin.site.register(UserAnswer) admin.site.register(CidUserAnswer)
admin.site.register(Exam) admin.site.register(Exam)
admin.site.register(Modality) admin.site.register(Modality)
admin.site.register(BodyPart) admin.site.register(BodyPart)
+2 -2
View File
@@ -1,11 +1,11 @@
from django import forms from django import forms
from .models import UserAnswer, AnatomyQuestion from .models import CidUserAnswer, AnatomyQuestion
class AnatomyAnswerForm(forms.ModelForm): class AnatomyAnswerForm(forms.ModelForm):
class Meta: class Meta:
model = UserAnswer model = CidUserAnswer
fields = ("answer",) fields = ("answer",)
+7 -6
View File
@@ -3,6 +3,7 @@ from django.utils import timezone
from django.core.files.storage import FileSystemStorage from django.core.files.storage import FileSystemStorage
from django.conf import settings from django.conf import settings
from django.utils.html import format_html
from django.urls import reverse from django.urls import reverse
@@ -106,21 +107,21 @@ class AnatomyQuestion(models.Model):
if not unmarked_answers: if not unmarked_answers:
return "No answers to mark" return "No answers to mark"
return "{} answer unmarked: {}".format(len(unmarked_answers), return format_html("<span class='warn'>{} answer unmarked:</span> {}".format(len(unmarked_answers),
", ".join(unmarked_answers)) ", ".join(unmarked_answers)))
def GetUnmarkedAnswers(self): def GetUnmarkedAnswers(self):
user_answers = set([i.answer for i in self.user_answers.all()]) user_answers = set([i.answer.lower() for i in self.cid_user_answers.all()])
unmarked_answers = user_answers - self.GetMarkedAnswers() unmarked_answers = user_answers - self.GetMarkedAnswers()
return unmarked_answers return unmarked_answers
def GetMarkedAnswers(self): def GetMarkedAnswers(self):
correct_answers = set([i.answer for i in self.answers.all()]) correct_answers = set([i.answer.lower() for i in self.answers.all()])
half_mark_answers = set( half_mark_answers = set(
[i.answer for i in self.half_mark_answers.all()]) [i.answer.lower() for i in self.half_mark_answers.all()])
incorrect_answers = set( incorrect_answers = set(
[i.answer for i in self.incorrect_answers.all()]) [i.answer.lower() for i in self.incorrect_answers.all()])
marked_answers = correct_answers | half_mark_answers | incorrect_answers marked_answers = correct_answers | half_mark_answers | incorrect_answers
return marked_answers return marked_answers
+4
View File
@@ -3,6 +3,10 @@ body {
background-color: black; background-color: black;
} }
.warn {
color: red;
}
.answer-list { .answer-list {
font-size: 30px; font-size: 30px;
} }
+1
View File
@@ -18,6 +18,7 @@
href="{% url 'admin:index' %}">Admin</a></span>{% endif %} href="{% url 'admin:index' %}">Admin</a></span>{% endif %}
</div> </div>
<div class="content container"> <div class="content container">
<a href="{% url 'anatomy:exam_list' %}">Exams</a>
{% block navigation %} {% block navigation %}
{% endblock %} {% endblock %}
<div class="row"> <div class="row">
+23 -3
View File
@@ -1,9 +1,29 @@
{% extends 'anatomy/base.html' %} {% extends 'anatomy/base.html' %}
{% block content %} {% block content %}
{% for exam in exams %}
<div class="anatomy"> <div class="anatomy">
<h1><a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">{{exam.name}}</a></h1> Active exams:<br/>
</div> <ul>
{% for exam in exams %}
{% if exam.active %}
<li>
<a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">{{exam.name}}</a> <a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">(mark)</a>
</li>
{% endif %}
{% endfor %} {% endfor %}
</ul>
Inactive exams:<br/>
<ul>
{% for exam in exams %}
{% if not exam.active %}
<li>
<a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">{{exam.name}}</a> <a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">(mark)</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endblock %} {% endblock %}
+11 -3
View File
@@ -1,9 +1,17 @@
{% extends 'anatomy/base.html' %} {% extends 'anatomy/exams.html' %}
{% block content %} {% block content %}
<div class="anatomy"> <div class="anatomy">
<h1>{{ exam.name }}</h1> <h1>Exam: {{ exam.name }}</h1>
This exam has {{question_number}} questions. This exam has {{question_number}} questions.
<p><button><a href="{% url 'anatomy:exam_take' pk=exam.pk sk=0 %}">Click here to start</a></button></p> <p><button><a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">Mark exam</a></button></p>
<!--<p><button><a href="{% url 'anatomy:exam_take' pk=exam.pk sk=0 %}">Click here to start</a></button></p>-->
<ol>
{% for question in questions.all %}
<li>{{ question }}</lid>
{% endfor %}
</ol>
</div> </div>
{% endblock %} {% endblock %}
+1 -6
View File
@@ -1,4 +1,4 @@
{% extends 'anatomy/base.html' %} {% extends 'anatomy/exams.html' %}
{% block content %} {% block content %}
<div class="anatomy"> <div class="anatomy">
@@ -33,8 +33,3 @@
</table> </table>
</div> </div>
{% endblock %} {% endblock %}
{% block navigation %}
<a href="{% url 'anatomy:exam_list' %}">Exams</a> <a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">Marking
overview</a> <a href="{% url 'anatomy:exam_scores_cid' pk=exam.pk %}">Scores</a>
{% endblock %}
+6
View File
@@ -0,0 +1,6 @@
{% extends 'anatomy/base.html' %}
{% block navigation %}
<br/>
{{exam.name}}-> <a href="{% url 'anatomy:exam_overview' pk=exam.pk %}">Overview</a> <a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">Mark</a> <a href="{% url 'anatomy:exam_scores_cid' pk=exam.pk %}">Scores</a>
{% endblock %}
+1 -5
View File
@@ -1,4 +1,4 @@
{% extends 'anatomy/base.html' %} {% extends 'anatomy/exams.html' %}
{% 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>
@@ -41,7 +41,3 @@
<div class=dwv-container data-url="/media/anatomy/{{ question.image}}" /> <div class=dwv-container data-url="/media/anatomy/{{ question.image}}" />
</div> </div>
{% endblock %} {% endblock %}
{% block navigation %}
<a href="{% url 'anatomy:exam_list' %}">Exams</a> <a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">Marking
overview</a> <a href="{% url 'anatomy:exam_scores_cid' pk=exam.pk %}">Scores</a>
{% endblock %}
+3 -7
View File
@@ -1,8 +1,9 @@
{% extends 'anatomy/base.html' %} {% extends 'anatomy/exams.html' %}
{% block content %} {% block content %}
<div class="anatomy"> <div class="anatomy">
<h2>{{ exam.name }}</h2> <h2>Marking exam: {{ exam.name }}</h2>
Question order will be different on the test system (as it is randomly generated)
<ul> <ul>
{% for question in questions.all %} {% for question in questions.all %}
@@ -13,8 +14,3 @@
<p><button><a href="{% url 'anatomy:mark' pk=exam.pk sk=0 %}">Click here to start marking</a></button></p> <p><button><a href="{% url 'anatomy:mark' pk=exam.pk sk=0 %}">Click here to start marking</a></button></p>
</div> </div>
{% endblock %} {% endblock %}
{% block navigation %}
<a href="{% url 'anatomy:exam_list' %}">Exams</a> <a href="{% url 'anatomy:mark_overview' pk=exam.pk %}">Marking
overview</a> <a href="{% url 'anatomy:exam_scores_cid' pk=exam.pk %}">Scores</a>
{% endblock %}
+1 -1
View File
@@ -16,7 +16,7 @@ urlpatterns = [
path("exam/<int:pk>/", views.exam_overview, name="exam_overview"), path("exam/<int:pk>/", views.exam_overview, name="exam_overview"),
path("exam/<int:pk>/scores", views.exam_scores_cid, path("exam/<int:pk>/scores", views.exam_scores_cid,
name="exam_scores_cid"), name="exam_scores_cid"),
path("submit_answers", views.postExamAnswers, name="exam_answers_submit"), path("exam/submit", views.postExamAnswers, name="exam_answers_submit"),
path("exam/", views.exam_list, name="exam_list"), path("exam/", views.exam_list, name="exam_list"),
path("exam/json/", views.active_exams, name="active_exams"), path("exam/json/", views.active_exams, name="active_exams"),
path("exam/json/<int:pk>", views.exam_json, name="exam_json"), path("exam/json/<int:pk>", views.exam_json, name="exam_json"),
+18 -8
View File
@@ -6,6 +6,8 @@ from django import forms
from django.contrib.auth.decorators import login_required, user_passes_test from django.contrib.auth.decorators import login_required, user_passes_test
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.db.models.functions import Lower
from django.http import Http404, JsonResponse from django.http import Http404, JsonResponse
from .forms import AnatomyAnswerForm, MarkAnatomyQuestionForm from .forms import AnatomyAnswerForm, MarkAnatomyQuestionForm
@@ -136,6 +138,11 @@ def exam_overview(request, pk):
@login_required @login_required
def exam_take(request, pk, sk): def exam_take(request, pk, sk):
"""
Allows taking of the exam on the django server (when logged in)
No longer used (deprecated in favour of using RTS)
"""
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()
@@ -298,11 +305,11 @@ def mark(request, pk, sk):
except IndexError: except IndexError:
raise Http404("Exam question does not exist") raise Http404("Exam question does not exist")
correct_answers = [i.answer for i in question.answers.all()] correct_answers = [i.answer.lower() for i in question.answers.all()]
half_correct_answers = [i.answer for i in question.half_mark_answers.all()] half_correct_answers = [i.answer.lower() for i in question.half_mark_answers.all()]
incorrect_answers = [i.answer for i in question.incorrect_answers.all()] incorrect_answers = [i.answer.lower() for i in question.incorrect_answers.all()]
user_answers = (set([i.answer for i in question.user_answers.all()]) - user_answers = (set([i.answer.lower() for i in question.cid_user_answers.all()]) -
set(correct_answers) - set(half_correct_answers) - set(correct_answers) - set(half_correct_answers) -
set(incorrect_answers)) # .filter(user=User) set(incorrect_answers)) # .filter(user=User)
user_answers = set([i for i in user_answers if i.strip() != ""]) user_answers = set([i for i in user_answers if i.strip() != ""])
@@ -402,7 +409,7 @@ def exam_json(request, pk):
for q in questions: for q in questions:
exam_questions[q.id] = { exam_questions[q.id] = {
"title": "{}".format(q.examination), "title": "{}".format(q.description),
"question": str(q.question_type), "question": str(q.question_type),
"images": [image_as_base64(q.image)], "images": [image_as_base64(q.image)],
"type": "anatomy", "type": "anatomy",
@@ -432,20 +439,23 @@ def exam_scores_cid(request, pk):
user_answers = defaultdict(list) user_answers = defaultdict(list)
user_names = {} user_names = {}
# Loop through all candidates
for cid in cids: for cid in cids:
# Convoluted (probably...) # Convoluted (probably...)
user_names[cid] = cid user_names[cid] = cid
for q in questions: for q in questions:
s = q.user_answers.filter(cid=cid) # Get user answer
s = q.cid_user_answers.filter(cid=cid)
if not s: if not s:
# skip if no answer
user_answers_marks[cid].append(0) user_answers_marks[cid].append(0)
user_answers[cid].append("") user_answers[cid].append("")
continue continue
ans = s[0].answer ans = s[0].answer
if ans in q.answers.all().values_list("answer", flat=True): if ans.lower() in q.answers.all().values_list(Lower("answer"), flat=True):
a = 2 a = 2
elif ans in q.half_mark_answers.all().values_list("answer", elif ans.lower() in q.half_mark_answers.all().values_list(Lower("answer"),
flat=True): flat=True):
a = 1 a = 1
else: else:
+3 -3
View File
@@ -143,9 +143,9 @@ STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static/') STATIC_ROOT = os.path.join(BASE_DIR, 'static/')
REMOTE_URL = "http://161.35.163.87/" REMOTE_URL = "http://161.35.163.87/"
#
if DEBUG: #if DEBUG:
STATIC_URL = REMOTE_URL + STATIC_URL # STATIC_URL = REMOTE_URL + STATIC_URL
MEDIA_URL = '/media/' MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/') MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')