From 51a93b42b1d7b3a94e227796aa8d4f6e97de9929 Mon Sep 17 00:00:00 2001 From: prathamesh Date: Wed, 27 Dec 2017 17:32:21 +0530 Subject: Exercise feature in video lessons Exercise is same as quiz except for following differences: - no time limit - no marks weightage - no instruction page - skip denied for a particular time An attribute 'is_exercise' in Quiz determines whether the quiz is exercise or not. Questions contains 'min_time' attribute. For an exercise a question cannot be skipped for an allotted minimum time, after which either django or JavaScript makes Next button available. Implementation is as such due to complexity of our existing views and templates. Also, after min_time, same question with Next button is available to move on, assuming that solution is present in the video. --- yaksh/forms.py | 8 +- yaksh/models.py | 20 ++++- yaksh/static/yaksh/js/requesthandler.js | 7 ++ yaksh/templates/exam.html | 4 +- yaksh/templates/yaksh/add_exercise.html | 41 ++++++++++ yaksh/templates/yaksh/add_question.html | 1 + yaksh/templates/yaksh/courses.html | 7 +- yaksh/templates/yaksh/question.html | 37 ++++++--- yaksh/test_views.py | 100 ++++++++++++++++++++++++ yaksh/urls.py | 3 + yaksh/views.py | 130 ++++++++++++++++++++++++++------ 11 files changed, 318 insertions(+), 40 deletions(-) create mode 100644 yaksh/templates/yaksh/add_exercise.html 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 @@
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 %} + + +{% endblock %} +{% block script %} + + + +{% endblock %} +{% block onload %} onload="javascript:test();" {% endblock %} +{% block content %} + + + +{% 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 @@