summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--yaksh/forms.py8
-rw-r--r--yaksh/models.py20
-rw-r--r--yaksh/static/yaksh/js/requesthandler.js7
-rw-r--r--yaksh/templates/exam.html4
-rw-r--r--yaksh/templates/yaksh/add_exercise.html41
-rw-r--r--yaksh/templates/yaksh/add_question.html1
-rw-r--r--yaksh/templates/yaksh/courses.html7
-rw-r--r--yaksh/templates/yaksh/question.html37
-rw-r--r--yaksh/test_views.py100
-rw-r--r--yaksh/urls.py3
-rw-r--r--yaksh/views.py130
11 files changed, 318 insertions, 40 deletions
diff --git a/yaksh/forms.py b/yaksh/forms.py
index 52e6a12..84db33e 100644
--- a/yaksh/forms.py
+++ b/yaksh/forms.py
@@ -173,6 +173,12 @@ class UserLoginForm(forms.Form):
return user
+class ExerciseForm(forms.ModelForm):
+ class Meta:
+ model = Quiz
+ fields = ['description']
+
+
class QuizForm(forms.ModelForm):
"""Creates a form to add or edit a Quiz.
It has the related fields and functions required."""
@@ -209,7 +215,7 @@ class QuizForm(forms.ModelForm):
class Meta:
model = Quiz
- exclude = ["is_trial", "creator"]
+ exclude = ["is_trial", "creator", "is_exercise"]
class QuestionForm(forms.ModelForm):
diff --git a/yaksh/models.py b/yaksh/models.py
index c65e9ef..839043f 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -308,6 +308,8 @@ class Quiz(models.Model):
weightage = models.FloatField(default=1.0)
+ is_exercise = models.BooleanField(default=False)
+
creator = models.ForeignKey(User, null=True)
objects = QuizManager()
@@ -747,6 +749,8 @@ class Question(models.Model):
# Check assignment upload based question
grade_assignment_upload = models.BooleanField(default=False)
+ min_time = models.IntegerField("time in minutes", default=0)
+
def consolidate_answer_data(self, user_answer, user=None):
question_data = {}
metadata = {}
@@ -1517,15 +1521,25 @@ class AnswerPaper(models.Model):
def time_left(self):
"""Return the time remaining for the user in seconds."""
+ secs = self._get_total_seconds()
+ total = self.question_paper.quiz.duration*60.0
+ remain = max(total - secs, 0)
+ return int(remain)
+
+ def time_left_on_question(self, question):
+ secs = self._get_total_seconds()
+ total = question.min_time*60.0
+ remain = max(total - secs, 0)
+ return int(remain)
+
+ def _get_total_seconds(self):
dt = timezone.now() - self.start_time
try:
secs = dt.total_seconds()
except AttributeError:
# total_seconds is new in Python 2.7. :(
secs = dt.seconds + dt.days*24*3600
- total = self.question_paper.quiz.duration*60.0
- remain = max(total - secs, 0)
- return int(remain)
+ return secs
def _update_marks_obtained(self):
"""Updates the total marks earned by student for this paper."""
diff --git a/yaksh/static/yaksh/js/requesthandler.js b/yaksh/static/yaksh/js/requesthandler.js
index 0663a55..f50570b 100644
--- a/yaksh/static/yaksh/js/requesthandler.js
+++ b/yaksh/static/yaksh/js/requesthandler.js
@@ -36,6 +36,10 @@ function unlock_screen() {
document.getElementById("ontop").style.display = "none";
}
+function show_skip() {
+ document.getElementById("skip_ex").style.visibility = "visible";
+}
+
function get_result(uid){
var url = "/exam/get_result/" + uid + "/" + course_id + "/" + module_id + "/";
ajax_check_code(url, "GET", "html", null, uid)
@@ -104,6 +108,9 @@ function ajax_check_code(url, method_type, data_type, data, uid) {
var global_editor = {};
$(document).ready(function(){
+ if(is_exercise == "True" && can_skip == "False"){
+ setTimeout(function() {show_skip();}, delay_time*1000);
+ }
// Codemirror object, language modes and initial content
// Get the textarea node
var textarea_node = document.querySelector('#answer');
diff --git a/yaksh/templates/exam.html b/yaksh/templates/exam.html
index d0812a4..4fd83dd 100644
--- a/yaksh/templates/exam.html
+++ b/yaksh/templates/exam.html
@@ -20,9 +20,9 @@
<ul class="nav navbar-nav navbar">
<li style="padding: 10px"><button class="btn btn-danger btn-sm" type="submit" name="quit">
{% if paper.questions_unanswered.all %}
- Quit Exam
+ Quit {{ quiz_type }}
{% else %}
- Finish Exam
+ Finish {{ quiz_type }}
{% endif %}
<span class="glyphicon glyphicon-off"></span></button></li>
</ul>
diff --git a/yaksh/templates/yaksh/add_exercise.html b/yaksh/templates/yaksh/add_exercise.html
new file mode 100644
index 0000000..af3e7b4
--- /dev/null
+++ b/yaksh/templates/yaksh/add_exercise.html
@@ -0,0 +1,41 @@
+{% extends "manage.html" %}
+
+
+{% block subtitle %}Add Exercise{% endblock %}
+
+{% block css %}
+<link rel="stylesheet" href="{{ URL_ROOT }}/static/yaksh/css/question_quiz.css" type="text/css" />
+<link rel="stylesheet" href="{{ URL_ROOT }}/static/yaksh/css/jquery.datetimepicker.css" type="text/css" />
+{% endblock %}
+{% block script %}
+<script src="{{ URL_ROOT }}/static/yaksh/js/jquery-1.9.1.min.js"></script>
+<script src="{{ URL_ROOT }}/static/yaksh/js/add_quiz.js"></script>
+<script src="{{ URL_ROOT }}/static/yaksh/js/jquery.datetimepicker.full.min.js"></script>
+{% endblock %}
+{% block onload %} onload="javascript:test();" {% endblock %}
+{% block content %}
+
+<form name=frm id=frm action="" method="post" >
+ {% csrf_token %}
+ <center>
+ <table class="span1 table">
+ {{ form.as_table }}
+ </table>
+ <script type="text/javascript">
+ $("#id_start_date_time").datetimepicker({format: 'Y-m-d H:i:s'});
+ $("#id_end_date_time").datetimepicker({format: 'Y-m-d H:i:s'});
+ </script>
+ <br/><br/>
+ </center>
+
+ <center><button class="btn" type="submit" id="submit" name="questionpaper"> Save
+ </button>
+
+ <button class="btn" type="button" name="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/courses/");'>Cancel</button> </center>
+</form>
+ <style type="text/css">
+ #rendered_text{
+ width: 550px;
+ }
+ </style>
+{% endblock %}
diff --git a/yaksh/templates/yaksh/add_question.html b/yaksh/templates/yaksh/add_question.html
index 6ead019..c294d9a 100644
--- a/yaksh/templates/yaksh/add_question.html
+++ b/yaksh/templates/yaksh/add_question.html
@@ -25,6 +25,7 @@
<tr><td>Description: <td>{{ qform.description}} {{qform.description.errors}}
<tr><td>Tags: <td>{{ qform.tags }}
<tr><td>Snippet: <td>{{ qform.snippet }}
+ <tr><td>Minimum Time(in minutes):<td> {{ qform.min_time }}
<tr><td>Partial Grading: <td>{{ qform.partial_grading }}
<tr><td>Grade Assignment Upload:<td> {{ qform.grade_assignment_upload }}
<tr><td> File: <td> {{ fileform.file_field }}{{ fileform.file_field.errors }}
diff --git a/yaksh/templates/yaksh/courses.html b/yaksh/templates/yaksh/courses.html
index 5daf944..a06ee7e 100644
--- a/yaksh/templates/yaksh/courses.html
+++ b/yaksh/templates/yaksh/courses.html
@@ -290,7 +290,8 @@
<div id="all_quizzes" >
<div class="col-md-offset-2 main">
{% if type == "quiz" %}
- <a href="{{URL_ROOT}}/exam/manage/addquiz/" class="btn btn-primary">Add new Quiz</a>
+ <a href="{{URL_ROOT}}/exam/manage/addquiz/" class="btn btn-primary">Add New Quiz</a>
+ <a href="{{URL_ROOT}}/exam/manage/add_exercise/" class="btn btn-primary">Add New Exercise</a>
{% if not quizzes %}
<center><h4> No new Quiz Added</h4></center>
<br><br>
@@ -308,7 +309,11 @@
<td>{{forloop.counter}}</td>
<td width="30%">
<ul class="list-group">
+ {% if quiz.is_exercise %}
+ <a href="{{URL_ROOT}}/exam/manage/add_exercise/{{quiz.id}}/">{{ quiz.description }}</a>
+ {% else %}
<a href="{{URL_ROOT}}/exam/manage/addquiz/{{quiz.id}}/">{{ quiz.description }}</a>
+ {% endif %}
{% if quiz.active %}
<span class="label label-success">Active</span>
{% else %}
diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html
index 6adda5b..978d226 100644
--- a/yaksh/templates/yaksh/question.html
+++ b/yaksh/templates/yaksh/question.html
@@ -23,7 +23,18 @@
<script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML"></script>
<script>
+init_val = '{{ last_attempt|escape_quotes|safe }}';
+lang = "{{ question.language }}"
+course_id = "{{course.id}}"
+module_id = "{{module.id}}"
+is_exercise = "{{ quiz.is_exercise }}"
+can_skip = "{{ can_skip }}"
+delay_time = new Number("{{ delay_time }}")
+
var time_left = {{ paper.time_left }}
+{% if quiz.is_exercise %}
+ time_left = {{ delay_time }}
+{% endif %}
function getTimeRemaining(endtime){
var t = Date.parse(endtime) - Date.parse(new Date());
@@ -52,13 +63,15 @@ function updateClock(){
var mm = ('0' + t.minutes).slice(-2);
var ss = ('0' + t.seconds).slice(-2);
- if(t.total<0){
-
+ if(t.total<0 && is_exercise=="False"){
document.forms["code"].submit();
clearInterval(timeinterval);
return null;
}
- if (t.total<=300000){
+ if(t.total<=0 && is_exercise=="True"){
+ clearInterval(timeinterval);
+ }
+ if (t.total<=300000 && t.total > 0){
clock.innerHTML = "<blink><center><span style='color:red'><strong>" + hh + ":" + mm + ":" + ss + "</strong></center></span></blink>";
}
if (t.total>=300000) {
@@ -68,6 +81,7 @@ function updateClock(){
var clock = document.getElementById("time_left");
updateClock();
var timeinterval = setInterval(updateClock,1000);
+
}
function validate(){
@@ -85,13 +99,7 @@ function call_skip(url)
form.action = url
form.submit();
}
-init_val = '{{ last_attempt|escape_quotes|safe }}';
-lang = "{{ question.language }}"
-course_id = "{{course.id}}"
-module_id = "{{module.id}}"
-
</script>
-
{% endblock script %}
{% block onload %} onload="updateTime();" {% endblock %}
@@ -253,16 +261,23 @@ module_id = "{{module.id}}"
<br><button class="btn btn-primary" type="submit" name="check" id="check" onClick="return validate();">Upload</button>&nbsp;&nbsp;
{% else %}
- {% if question in paper.get_questions_unanswered %}
+ {% if question in paper.get_questions_unanswered or quiz.is_exercise %}
<button class="btn btn-primary" type="submit" name="check" id="check" >Check Answer <span class="glyphicon glyphicon-cog"></span></button>&nbsp;&nbsp;
{% endif %}
{% endif %}
+ {% if quiz.is_exercise %}
+ {% if can_skip %}
+ <button id="skip_ex" class="btn btn-primary" onclick="call_skip('{{ URL_ROOT }}/exam/{{ question.id }}/skip/{{ paper.attempt_number }}/{{ module.id }}/{{ paper.question_paper.id }}/{{course.id}}/')" name="skip"> Next <span class="glyphicon glyphicon-arrow-right"></span></button>
+ {% else %}
+ <button id="skip_ex" class="btn btn-primary" onclick="call_skip('{{ URL_ROOT }}/exam/{{ question.id }}/skip/{{ paper.attempt_number }}/{{ module.id }}/{{ paper.question_paper.id }}/{{course.id}}/')" name="skip" style="visibility:hidden"> Next <span class="glyphicon glyphicon-arrow-right"></span></button>
+ {% endif %}
+ {% endif %}
{% if paper.question_paper.quiz.allow_skip and not paper.get_questions_unanswered|length_is:"1" %}
{% if question in paper.get_questions_unanswered %}
<button class="btn btn-primary" onclick="call_skip('{{ URL_ROOT }}/exam/{{ question.id }}/skip/{{ paper.attempt_number }}/{{ module.id }}/{{ paper.question_paper.id }}/{{course.id}}/')" name="skip" id="skip">Attempt Later <span class="glyphicon glyphicon-arrow-right"></span></button>
{% endif %}
- {% endif %}
+ {% endif %}
</div>
</form>
</div>
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index d65fe8e..38564a1 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -1042,11 +1042,19 @@ class TestAddQuiz(TestCase):
creator=self.user
)
+ self.exercise = Quiz.objects.create(
+ start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
+ end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone),
+ attempts_allowed=-1, time_between_attempts=0,
+ is_exercise=True, description='demo exercise', creator=self.user
+ )
+
def tearDown(self):
self.client.logout()
self.user.delete()
self.student.delete()
self.quiz.delete()
+ self.exercise.delete()
self.course.delete()
def test_add_quiz_denies_anonymous(self):
@@ -1171,6 +1179,98 @@ class TestAddQuiz(TestCase):
self.assertEqual(response.status_code, 302)
self.assertRedirects(response, '/exam/manage/courses/all_quizzes/')
+ def test_add_exercise_denies_anonymous(self):
+ """
+ If not logged in redirect to login page
+ """
+ response = self.client.get(reverse('yaksh:add_exercise'),
+ follow=True
+ )
+ redirect_destination = '/exam/login/?next=/exam/manage/add_exercise/'
+ self.assertRedirects(response, redirect_destination)
+
+ def test_add_exercise_denies_non_moderator(self):
+ """
+ If not moderator in redirect to login page
+ """
+ self.client.login(
+ username=self.student.username,
+ password=self.student_plaintext_pass
+ )
+ course_id = self.course.id
+ response = self.client.get(reverse('yaksh:add_exercise'),
+ follow=True
+ )
+ self.assertEqual(response.status_code, 404)
+
+ def test_add_exercise_get(self):
+ """
+ GET request to add exercise should display add exercise form
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ response = self.client.get(reverse('yaksh:add_exercise')
+ )
+ self.assertEqual(response.status_code, 200)
+ self.assertTemplateUsed(response, 'yaksh/add_exercise.html')
+ self.assertIsNotNone(response.context['form'])
+
+ def test_add_exercise_post_existing_exercise(self):
+ """
+ POST request to edit exercise
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+ tzone = pytz.timezone('UTC')
+ response = self.client.post(reverse('yaksh:add_exercise',
+ kwargs={'quiz_id': self.exercise.id}),
+ data={
+ 'description': 'updated demo exercise',
+ }
+ )
+
+ updated_exercise = Quiz.objects.get(id=self.exercise.id)
+ self.assertEqual(updated_exercise.active, True)
+ self.assertEqual(updated_exercise.duration, 1000)
+ self.assertEqual(updated_exercise.attempts_allowed, -1)
+ self.assertEqual(updated_exercise.time_between_attempts, 0)
+ self.assertEqual(updated_exercise.description, 'updated demo exercise')
+ self.assertEqual(updated_exercise.pass_criteria, 0)
+ self.assertTrue(updated_exercise.is_exercise)
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, '/exam/manage/courses/all_quizzes/')
+
+ def test_add_exercise_post_new_exercise(self):
+ """
+ POST request to add new exercise
+ """
+ self.client.login(
+ username=self.user.username,
+ password=self.user_plaintext_pass
+ )
+
+ tzone = pytz.timezone('UTC')
+ response = self.client.post(reverse('yaksh:add_exercise'),
+ data={
+ 'description': "Demo Exercise",
+ }
+ )
+ quiz_list = Quiz.objects.all().order_by('-id')
+ new_exercise = quiz_list[0]
+ self.assertEqual(new_exercise.active, True)
+ self.assertEqual(new_exercise.duration, 1000)
+ self.assertEqual(new_exercise.attempts_allowed, -1)
+ self.assertEqual(new_exercise.time_between_attempts, 0)
+ self.assertEqual(new_exercise.description, 'Demo Exercise')
+ self.assertEqual(new_exercise.pass_criteria, 0)
+ self.assertTrue(new_exercise.is_exercise)
+ self.assertEqual(response.status_code, 302)
+ self.assertRedirects(response, '/exam/manage/courses/all_quizzes/')
+
def test_show_all_quizzes(self):
self.client.login(
username=self.user.username,
diff --git a/yaksh/urls.py b/yaksh/urls.py
index 716a7d0..f7df456 100644
--- a/yaksh/urls.py
+++ b/yaksh/urls.py
@@ -49,6 +49,9 @@ urlpatterns = [
url(r'^manage/addquestion/(?P<question_id>\d+)/$', views.add_question,
name="add_question"),
url(r'^manage/addquiz/$', views.add_quiz, name='add_quiz'),
+ url(r'^manage/add_exercise/$', views.add_exercise, name='add_exercise'),
+ url(r'^manage/add_exercise/(?P<quiz_id>\d+)/$', views.add_exercise,
+ name='add_exercise'),
url(r'^manage/addquiz/(?P<quiz_id>\d+)/$',
views.add_quiz, name='edit_quiz'),
url(r'^manage/addquiz/(?P<quiz_id>\d+)/(?P<course_id>\d+)$',
diff --git a/yaksh/views.py b/yaksh/views.py
index 483b87c..302ef9e 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -46,7 +46,7 @@ from yaksh.forms import (
UserRegisterForm, UserLoginForm, QuizForm, QuestionForm,
RandomQuestionForm, QuestionFilterForm, CourseForm, ProfileForm,
UploadFileForm, get_object_form, FileForm, QuestionPaperForm, LessonForm,
- LessonFileForm, LearningModuleForm
+ LessonFileForm, LearningModuleForm, ExerciseForm
)
from .settings import URL_ROOT
from .file_utils import extract_files, is_csv
@@ -327,6 +327,56 @@ def add_quiz(request, quiz_id=None, course_id=None):
@login_required
+@email_verified
+def add_exercise(request, quiz_id=None, course_id=None):
+ user = request.user
+ ci = RequestContext(request)
+ if not is_moderator(user):
+ raise Http404('You are not allowed to view this course !')
+ if quiz_id:
+ quiz = get_object_or_404(Quiz, pk=quiz_id)
+ if quiz.creator != user and not course_id:
+ raise Http404('This quiz does not belong to you')
+ else:
+ quiz = None
+ if course_id:
+ course = get_object_or_404(Course, pk=course_id)
+ if not course.is_creator(user) and not course.is_teacher(user):
+ raise Http404('This quiz does not belong to you')
+
+ context = {}
+ if request.method == "POST":
+ form = ExerciseForm(request.POST, instance=quiz)
+ if form.is_valid():
+ if quiz is None:
+ form.instance.creator = user
+ quiz = form.save(commit=False)
+ quiz.is_exercise = True
+ quiz.time_between_attempts = 0
+ quiz.weightage = 0
+ quiz.allow_skip = False
+ quiz.attempts_allowed = -1
+ quiz.duration = 1000
+ quiz.pass_criteria = 0
+ quiz.save()
+
+ if not course_id:
+ return my_redirect("/exam/manage/courses/all_quizzes/")
+ else:
+ return my_redirect("/exam/manage/courses/")
+
+ else:
+ quiz = Quiz.objects.get(id=quiz_id) if quiz_id else None
+ form = ExerciseForm(instance=quiz)
+ context["quiz_id"] = quiz_id
+ context["course_id"] = course_id
+ context["form"] = form
+ return my_render_to_response(
+ 'yaksh/add_exercise.html', context, context_instance=ci
+ )
+
+
+@login_required
@has_profile
@email_verified
def prof_manage(request, msg=None):
@@ -460,7 +510,8 @@ def start(request, questionpaper_id=None, attempt_num=None, course_id=None,
if last_attempt and last_attempt.is_attempt_inprogress():
return show_question(
request, last_attempt.current_question(), last_attempt,
- course_id=course_id, module_id=module_id
+ course_id=course_id, module_id=module_id,
+ previous_question=last_attempt.current_question()
)
# allowed to start
if not quest_paper.can_attempt_now(user, course_id):
@@ -474,7 +525,7 @@ def start(request, questionpaper_id=None, attempt_num=None, course_id=None,
attempt_number = 1
else:
attempt_number = last_attempt.attempt_number + 1
- if attempt_num is None:
+ if attempt_num is None and not quest_paper.quiz.is_exercise:
context = {
'user': user,
'questionpaper': quest_paper,
@@ -496,7 +547,7 @@ def start(request, questionpaper_id=None, attempt_num=None, course_id=None,
if new_paper.status == 'inprogress':
return show_question(request, new_paper.current_question(),
new_paper, course_id=course_id,
- module_id=module_id
+ module_id=module_id, previous_question=None
)
else:
msg = 'You have already finished the quiz!'
@@ -505,27 +556,42 @@ def start(request, questionpaper_id=None, attempt_num=None, course_id=None,
@login_required
@email_verified
def show_question(request, question, paper, error_message=None, notification=None,
- course_id=None, module_id=None):
+ course_id=None, module_id=None, previous_question=None):
"""Show a question if possible."""
user = request.user
+ quiz = paper.question_paper.quiz
+ quiz_type = 'Exam'
+ can_skip = False
+ if previous_question:
+ delay_time = paper.time_left_on_question(previous_question)
+ else:
+ delay_time = paper.time_left_on_question(question)
+
+ if previous_question and quiz.is_exercise:
+ if delay_time <= 0:
+ can_skip = True
+ question = previous_question
if not question:
msg = 'Congratulations! You have successfully completed the quiz.'
return complete(
request, msg, paper.attempt_number, paper.question_paper.id,
course_id=course_id, module_id=module_id
)
- if not paper.question_paper.quiz.active:
+ if not quiz.active:
reason = 'The quiz has been deactivated!'
return complete(
request, reason, paper.attempt_number, paper.question_paper.id,
module_id=module_id
)
- if paper.time_left() <= 0:
- reason = 'Your time is up!'
- return complete(
- request, reason, paper.attempt_number, paper.question_paper.id,
- course_id, module_id=module_id
- )
+ if not quiz.is_exercise:
+ if paper.time_left() <= 0:
+ reason = 'Your time is up!'
+ return complete(
+ request, reason, paper.attempt_number, paper.question_paper.id,
+ course_id, module_id=module_id
+ )
+ else:
+ quiz_type = 'Exercise'
if question in paper.questions_answered.all():
notification = (
'You have already attempted this question successfully'
@@ -539,13 +605,17 @@ def show_question(request, question, paper, error_message=None, notification=Non
context = {
'question': question,
'paper': paper,
+ 'quiz': quiz,
'error_message': error_message,
'test_cases': test_cases,
'files': files,
'notification': notification,
'last_attempt': question.snippet.encode('unicode-escape'),
'course': course,
- 'module': module
+ 'module': module,
+ 'can_skip': can_skip,
+ 'delay_time': delay_time,
+ 'quiz_type': quiz_type
}
answers = paper.get_previous_answers(question)
if answers:
@@ -568,6 +638,11 @@ def skip(request, q_id, next_q=None, attempt_num=None, questionpaper_id=None,
)
question = get_object_or_404(Question, pk=q_id)
+ if paper.question_paper.quiz.is_exercise:
+ if paper.time_left_on_question(question) <= 0:
+ paper.start_time = timezone.now()
+ paper.save()
+
if request.method == 'POST' and question.type == 'code':
if not paper.answers.filter(question=question, correct=True).exists():
user_code = request.POST.get('answer')
@@ -612,7 +687,8 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
msg = "Please enter an Integer Value"
return show_question(
request, current_question, paper, notification=msg,
- course_id=course_id, module_id=module_id
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question
)
elif current_question.type == 'float':
try:
@@ -621,7 +697,8 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
msg = "Please enter a Float Value"
return show_question(request, current_question,
paper, notification=msg,
- course_id=course_id, module_id=module_id)
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question)
elif current_question.type == 'string':
user_answer = str(request.POST.get('answer'))
@@ -635,7 +712,8 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
msg = "Please upload assignment file"
return show_question(
request, current_question, paper, notification=msg,
- course_id=course_id, module_id=module_id
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question
)
for fname in assignment_filename:
assignment_files = AssignmentUpload.objects.filter(
@@ -663,14 +741,16 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
paper.answers.add(new_answer)
next_q = paper.add_completed_question(current_question.id)
return show_question(request, next_q, paper,
- course_id=course_id, module_id=module_id)
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question)
else:
user_answer = request.POST.get('answer')
if not user_answer:
msg = "Please submit a valid answer."
return show_question(
request, current_question, paper, notification=msg,
- course_id=course_id, module_id=module_id
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question
)
if current_question in paper.get_questions_answered()\
and current_question.type not in ['code', 'upload']:
@@ -703,16 +783,19 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None,
result)
return show_question(request, next_question, paper,
error_message, course_id=course_id,
- module_id=module_id)
+ module_id=module_id,
+ previous_question=current_question)
else:
return JsonResponse(result)
else:
next_question, error_message, paper = _update_paper(request, uid, result)
return show_question(request, next_question, paper, error_message,
- course_id=course_id, module_id=module_id)
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question)
else:
return show_question(request, current_question, paper,
- course_id=course_id, module_id=module_id)
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question)
@csrf_exempt
@@ -731,9 +814,12 @@ def get_result(request, uid, course_id, module_id):
next_question, error_message, paper = _update_paper(request, uid,
result
)
+ answer = Answer.objects.get(id=uid)
+ current_question = answer.question
if result.get('success'):
return show_question(request, next_question, paper, error_message,
- course_id=course_id, module_id=module_id)
+ course_id=course_id, module_id=module_id,
+ previous_question=current_question)
else:
with open(template_path) as f:
template_data = f.read()