start physics...

This commit is contained in:
Ross
2020-12-15 23:07:06 +00:00
parent fc098f681c
commit 90f69c2c14
26 changed files with 1301 additions and 1 deletions
+59
View File
@@ -0,0 +1,59 @@
{% load static %}
<html>
<head>
<title>Anatomy Quiz</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" />
<link rel="stylesheet" href="{% static 'tagulous/lib/select2-3/select2.css' %}">
<link rel="stylesheet" href="{% static 'css/anatomy.css' %}">
<link rel="stylesheet" href="{% static 'css/toastr.min.css' %}">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="{% static 'js/toastr.min.js' %}"></script>
<script src="{% static 'js/cornerstone/hammer.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstone.min.js' %}"></script>
<script src="{% static 'js/cornerstone/dicomParser.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneMath.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneTools.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneWebImageLoader.min.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstoneWADOImageLoader.js' %}"></script>
<script src="{% static 'js/cornerstone/cornerstone-base64-image-loader.umd.js' %}"></script>
<script src="{% static 'js/anatomy.js' %}" defer="defer"></script>
{% block js %}
{% endblock %}
</head>
<body>
<div class="page-header">
{% if request.user.is_authenticated %}
<span id="anatomy-link">
<a href="{% url 'anatomy:index' %}">Anatomy</a>
</span>
<span id="logout-link">
<a href="{% url 'logout' %}">Logout</a>
</span>
<span id="profile-link">
<a href="{% url 'profile' %}">Profile</a>
</span>
{% endif %}
{% if request.user.is_staff %}
<span id="admin-link">
<a href="{% url 'admin:index' %}">Admin</a>
</span>
{% endif %}
</div>
<div class="content container">
{% if request.user.is_authenticated %}
<a href="{% url 'physics:exam_list' %}">Exams</a> /
{% endif %}
{% block navigation %}
{% endblock %}
<div class="row">
<div class="col-md-8">
{% block content %}
{% endblock %}
</div>
</div>
</div>
</body>
</html>
+13
View File
@@ -0,0 +1,13 @@
{% extends 'physics/base.html' %}
{% block content %}
<div class="physics">
<h2>CID: {{ cid }}</h2>
The following exams have been found (click to view answers and scores):
<ul>
{% for exam in exams %}
<li><a href="{% url 'physics:exam_scores_cid_user' pk=exam.pk sk=cid %}">{{exam.name}}</a></li>
{% endfor %}
</ul>
</div>
{% endblock %}
@@ -0,0 +1,18 @@
{% extends 'physics/base.html' %}
{% block content %}
<div class="physics">
<h2>Please enter your CID</h2>
<p>CID: <input type="text" name="cid" id="cid-input"></p>
<button id="cid-selector-go-button">Go...</button>
</div>
<script>
$(document).ready(function () {
$("#cid-selector-go-button").click(() => {
cid = document.getElementById("cid-input").value;
window.location = window.location + cid;
})
})
</script>
{% endblock %}
+30
View File
@@ -0,0 +1,30 @@
{% extends 'physics/base.html' %}
{% block content %}
<h1>Examinations</h1>
<div class="physics">
Active exams:<br/>
<ul>
{% for exam in exams %}
{% if exam.active %}
<li>
<a href="{% url 'physics:exam_overview' pk=exam.pk %}">{{exam.name}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
Inactive exams:<br/>
<ul>
{% for exam in exams %}
{% if not exam.active %}
<li>
<a href="{% url 'physics:exam_overview' pk=exam.pk %}">{{exam.name}}</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endblock %}
@@ -0,0 +1,99 @@
{% extends 'physics/exams.html' %}
{% block content %}
{% load thumbnail %}
<div class="physics">
<h1>Exam: {{ exam.name }}</h1>
This exam has {{question_number}} questions.
<div class="parent-help" title="Click to enable / disable the exam">
Exam active: <input type="checkbox" id="exam-active-switch" {% if exam.active %}checked{% endif %}> <span class="help-text">[When checked the exam will be available to take in the test system]</span>
</div>
<div class="parent-help" title="Click to enable / disable the exam results">
Publish results: <input type="checkbox" id="exam-publish-results-switch" {% if exam.publish_results %}checked{% endif %}> <span class="help-text">[When checked the exam results will be available on this site]</span>
</div>
<!--<p><button><a href="{% url 'anatomy:exam_take' pk=exam.pk sk=0 %}">Click here to start</a></button></p>-->
<ol id="full-question-list">
{% for question in questions.all %}
<li>
{{ question.stem }}
<ol type="a" class="abcde">
<li>
{{ question.a }}: {{ question.a_answer }}
</li>
<li>
{{ question.b }}: {{ question.b_answer }}
</li>
<li>
{{ question.c }}: {{ question.c_answer }}
</li>
<li>
{{ question.d }}: {{ question.d_answer }}
</li>
<li>
{{ question.e }}: {{ question.e_answer }}
</li>
</ol>
Category: {{ question.category }}, <a href="{% url 'physics:question_detail' pk=question.pk %}">View</a>
</li>
{% endfor %}
</ol>
</div>
<script type="text/javascript">
$(document).ready(function () {
// send request to change the is_private state on customSwitches toggle
$("#exam-active-switch").on("change", function () {
$.ajax({
url: "{% url 'anatomy:exam_toggle_active' pk=exam.pk %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
active: this.checked // true if checked else false
},
type: "POST",
dataType: "json",
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
if (data.status == "success") {
toastr.info('Exam state changed.')
}
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
.always(function () {
console.log('[Done]');
})
})
$("#exam-publish-results-switch").on("change", function () {
$.ajax({
url: "{% url 'physics:exam_toggle_results_published' pk=exam.pk %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
publish_results: this.checked // true if checked else false
},
type: "POST",
dataType: "json",
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
if (data.status == "success") {
toastr.info('Publish results state changed.')
}
// show some message according to the response.
// For eg. A message box showing that the status has been changed
})
.always(function () {
console.log('[Done]');
})
})
});
</script>
{% endblock %}
@@ -0,0 +1,36 @@
{% extends 'physics/exams.html' %}
{% block content %}
<div class="physics">
<h2>{{ exam.name }}</h2>
{% for user, value in user_answers_marks.items %}
<h3>Candidate: <a href="{% url 'physics:cid_scores' user %}">{{ user_names|get_item:user }}</a></h3>
<!-- Answers: {{ user_answers_and_marks|get_item:user }}-->
Answers: {% for ans, score in user_answers_and_marks|get_item:user %}
{{ans}} ({{score}}),
{% endfor %}
<br /> Total mark: {{ user_scores|get_item:user }}
{% endfor %}
</div>
<div id="stats-block">
<h2>Stats</h2>
Mean: {{mean}}, Median {{median}}, Mode {{mode}}
<h3>Distribution of results</h3>
<div id="stats-plot">{{plot|safe}}</div>
</div>
<div>
<table>
<tr>
<th>Candidate ID</th>
<th>Score</th>
</tr>
{% for user, value in user_answers_marks.items %}
<tr>
<td>{{user}}</td>
<td>{{user_scores|get_item:user}}</td>
</tr>
{% endfor %}
</table>
</div>
{% endblock %}
+222
View File
@@ -0,0 +1,222 @@
{% extends 'physics/base.html' %}
{% block content %}
<div class="physics">
<h1>Exam: {{ exam.name }}</h1>
<div>
Candidate number: <input type="number" id="cid" name="cid" title="please enter your candidate number">
</div>
<p>
Please make sure you submit answers before closing or navigating from this page (as otherwise they will not be
saved)
</p>
<ol id="full-question-list-physics">
{% for question in questions.all %}
<li>
{{ question.stem }}
<ol type="a" class="abcde">
<li>
<span class="question-text">{{ question.a }}:</span> <label class="truefalse-switch"> <input
type="checkbox" class="question" id="{{question.pk}}-a-checkbox" data-q="{{question.pk}}" data-a="a">
<div class="slider round"></div>
</label>
</li>
<li>
<span class="question-text">{{ question.b }}:</span> <label class="truefalse-switch"> <input
type="checkbox" class="question" id="{{question.pk}}-b-checkbox" data-q="{{question.pk}}" data-a="b">
<div class="slider round"></div>
</label>
</li>
<li>
<span class="question-text">{{ question.c }}:</span> <label class="truefalse-switch"> <input
type="checkbox" class="question" id="{{question.pk}}-c-checkbox" data-q="{{question.pk}}" data-a="c">
<div class="slider round"></div>
</label>
</li>
<li>
<span class="question-text">{{ question.d }}:</span> <label class="truefalse-switch"> <input
type="checkbox" class="question" id="{{question.pk}}-d-checkbox" data-q="{{question.pk}}" data-a="d">
<div class="slider round"></div>
</label>
</li>
<li>
<span class="question-text">{{ question.e }}:</span> <label class="truefalse-switch"> <input
type="checkbox" class="question" id="{{question.pk}}-e-checkbox" data-q="{{question.pk}}" data-a="e">
<div class="slider round"></div>
</label>
</li>
</ol>
</li>
{% endfor %}
</ol>
<button id="submit">Submit answers</button>
</div>
<script type="text/javascript">
window.answers_submitted = true;
$(document).ready(function () {
console.log($(".question-text"));
$(".question-text").click(function (evt) {
$(evt.target).parent().find("input").click();
});
$("#submit").click(() =>{
let cid = $("#cid").val()
if (cid == "") {
alert("You need to enter a valid candidate number.");
$("#cid").focus();
return
}
answers = [];
$("input.question").each((n, el) => {
answers.push([el.dataset.q, el.dataset.a, el.checked]);
})
ans = {
cid: parseInt(cid),
eid: {{exam.pk}},
ans: answers
}
postAnswers(ans);
})
});
window.onbeforeunload = confirmExit;
function confirmExit() {
if (!window.answers_submitted) {
return "You have attempted to leave this page. Are you sure?";
}
}
function postAnswers(ans) {
console.log(ans);
$.post("{% url 'physics:exam_answers_submit' %}", JSON.stringify(ans)).done((data) => {
console.log(data);
if (data.success) {
if (data.question_count == window.number_of_questions) {
let ret = confirm(
`${data.question_count} answers sucessfully submitted. Click OK to finish the exam.`
window.answers_submitted = true;
);
if (ret) {
window.saveSession();
if (config.exam_results_url != "") {
let url = config.exam_results_url;
if (window.cid != "") {
url = url + window.cid;
}
$("#options-link")
.empty()
.append(
`<a href="${url}" target="_blank"><div class="packet-button">Results and answers</div></a>`
);
}
$("#options-panel").show();
} else {
}
} else {
alert(`Answers sucessfully submitted.`);
}
} else {
alert(`Error submitting answers: ${data.error}`);
}
});
// $.post( "http://localhost:8000/submit_answers", JSON.stringify(ans));
}
</script>
<style>
.truefalse-switch {
position: relative;
display: inline-block;
width: 90px;
height: 20px;
margin: 0px;
margin-bottom: -5px;
}
.truefalse-switch input {
display: none;
}
.slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 0, 0, 0.5);
-webkit-transition: .4s;
transition: .4s;
border-radius: 20px;
}
.slider:before {
position: absolute;
content: "";
height: 16px;
width: 16px;
left: 4px;
bottom: 2px;
background-color: white;
-webkit-transition: .4s;
transition: .4s;
border-radius: 50%;
}
input:checked+.slider {
background-color: rgba(0, 255, 0, 0.5);
}
input:focus+.slider {
box-shadow: 0 0 1px #2196F3;
}
input:checked+.slider:before {
-webkit-transform: translateX(26px);
-ms-transform: translateX(26px);
transform: translateX(68px);
}
/*------ ADDED CSS ---------*/
.slider:after {
content: 'FALSE';
color: white;
display: block;
position: absolute;
transform: translate(-50%, -50%);
top: 50%;
left: 50%;
font-size: 10px;
font-family: Verdana, sans-serif;
}
input:checked+.slider:after {
content: 'TRUE';
}
.question-text {
display: inline-block;
}
</style>
{% endblock %}
+6
View File
@@ -0,0 +1,6 @@
{% extends 'physics/base.html' %}
{% block navigation %}
<br/>
{{exam.name}}-> <a href="{% url 'physics:exam_overview' pk=exam.pk %}">Overview</a> / <a href="{% url 'physics:exam_scores_cid' pk=exam.pk %}">Scores</a>
{% endblock %}
+10
View File
@@ -0,0 +1,10 @@
{% extends 'physics/base.html' %}
{% block content %}
{% for exam in exams %}
<div class="physics">
<h1><a href="{% url 'physics:exam_overview' pk=exam.pk %}">Exam: {{ exam.name }} </a></h1>
{% if request.user.is_staff %}<a href="{% url 'physics:exam_scores_cid' pk=exam.pk %}">Scores</a>{% endif %}
</div>
{% endfor %}
{% endblock %}
@@ -0,0 +1,69 @@
{% extends 'physics/base.html' %}
{% block content %}
{% load static %}
<div class="question">
<a href="{% url 'admin:physics_question_change' question.id %}" title="Edit the Question using the admin interface">Admin Edit</a>
<div class="date">
Created: {{ question.created_date }}
</div>
<h2>{{question.stem}}</h2>
<div>
<ol>
<li>{{ question.a }}: {{ question.a_answer }}</li>
<li>{{ question.b }}: {{ question.b_answer }}</li>
<li>{{ question.c }}: {{ question.c_answer }}</li>
<li>{{ question.d }}: {{ question.d_answer }}</li>
<li>{{ question.e }}: {{ question.e_answer }}</li>
</ol>
</div>
<div>
Examinations: {% for exam in question.exams.all %}
<a href="{% url 'physics:exam_overview' pk=exam.pk %}">{{ exam.name }}</a>
{% endfor %}
</div>
<div>
Category: {{ question.category }}
</div>
<div>
Author: {% for user in question.author.all %}
{{ author }},
{% endfor %}
</div>
</div>
<script type="text/javascript">
$(document).ready(function () {
$("#annotation-json-toggle").click(() => { $("#annotation-json-content").toggle() });
// send request to change the is_private state on customSwitches toggle
$("#save-annotations").click(function () {
json = getJsonToolStateNoId();
$.ajax({
url: "{% url 'anatomy:question_save_annotation' pk=question.pk %}",
data: {
csrfmiddlewaretoken: "{{ csrf_token }}",
annotation: json,
},
type: "POST",
dataType: "json",
})
// $.ajax().done(), $.ajax().fail(), $ajax().always() are upto you. Add/change accordingly
.done(function (data) {
console.log(data);
// show some message according to the response.
// For eg. A message box showing that the status has been changed
if (data.status == "success") {
toastr.info('Annotations saved')
} else {
toastr.warning('Error saving annotations')
}
})
.always(function () {
console.log('[Done]');
})
})
});
</script>
{% endblock %}
@@ -0,0 +1,20 @@
{% extends 'anatomy/base.html' %}
{% block content %}
{% for question in questions %}
<div class="anatomy">
<div class="date">
{{ question.created_date }}
</div>
<h1><a href="{% url 'anatomy:question_detail' pk=question.pk %}">{% for answer in question.answers.all %}
{{ answer }},
{% endfor %}
</a></h1>
<p>{{ question.question_type.first|linebreaksbr }}</p>
<img src="/media/anatomy/{{ question.image|linebreaksbr }}" />
<a href="{% url 'anatomy:answer_question' pk=question.pk %}">ANSWER</a>
</div>
{% endfor %}
{% endblock %}
{$ black navigation %}