From 87beec6a0389e35c94fe674627d47e1f3ea1c22e Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Mon, 6 Mar 2017 13:07:46 +0530 Subject: Display full name of course creator & redirect logout correctly --- yaksh/templates/user.html | 2 +- yaksh/templates/yaksh/quizzes_user.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'yaksh') diff --git a/yaksh/templates/user.html b/yaksh/templates/user.html index 0d1f980..b068fae 100644 --- a/yaksh/templates/user.html +++ b/yaksh/templates/user.html @@ -16,7 +16,7 @@ diff --git a/yaksh/templates/yaksh/quizzes_user.html b/yaksh/templates/yaksh/quizzes_user.html index 63f22a1..72fce30 100644 --- a/yaksh/templates/yaksh/quizzes_user.html +++ b/yaksh/templates/yaksh/quizzes_user.html @@ -6,7 +6,7 @@
-

{{ course.name }} by {{ course.creator }}

+

{{ course.name }} by {{ course.creator.get_full_name }}

{% if user in course.requests.all %} Request Pending -- cgit From 9484e8bebcd4363fa3aa1c2fc842de1bdcc25a10 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Thu, 23 Feb 2017 17:33:07 +0530 Subject: Allow revisiting all types of question to resubmit answer --- yaksh/models.py | 3 ++- yaksh/templates/exam.html | 4 +++- yaksh/templates/yaksh/user_data.html | 4 ++-- yaksh/views.py | 21 +++++++++++---------- 4 files changed, 18 insertions(+), 14 deletions(-) (limited to 'yaksh') diff --git a/yaksh/models.py b/yaksh/models.py index 2d84622..61c9059 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -988,7 +988,8 @@ class AnswerPaper(models.Model): questions and returns the next question. """ next_question = self.next_question(question_id) - self.questions_answered.add(question_id) + if question_id not in self.questions_answered.all(): + self.questions_answered.add(question_id) self.questions_unanswered.remove(question_id) if next_question.id == int(question_id): return None diff --git a/yaksh/templates/exam.html b/yaksh/templates/exam.html index b497cc0..02ff70a 100644 --- a/yaksh/templates/exam.html +++ b/yaksh/templates/exam.html @@ -52,7 +52,9 @@ {% endif %} {% endif %} {% if qid in paper.get_questions_answered %} -
  • {{ forloop.counter }}
  • +
  • {{ forloop.counter }}
  • {% endif %} {% else %} {% if qid.id == question.id %} diff --git a/yaksh/templates/yaksh/user_data.html b/yaksh/templates/yaksh/user_data.html index 9be28fb..16707b2 100644 --- a/yaksh/templates/yaksh/user_data.html +++ b/yaksh/templates/yaksh/user_data.html @@ -100,7 +100,7 @@ User IP address: {{ paper.user_ip }} {% else %}
    Student answer:
    {% for answer in answers %} - {% if not answer.skipped %} + {% if answer.answer.correct %}
    Correct answer @@ -116,7 +116,7 @@ User IP address: {{ paper.user_ip }}
    {{ answer.answer.answer.strip }}
    - {% endif %} + {% endfor %} {% endif %}
    diff --git a/yaksh/views.py b/yaksh/views.py index 74c409c..6bd9d67 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -432,9 +432,10 @@ def skip(request, q_id, next_q=None, attempt_num=None, questionpaper_id=None): paper = get_object_or_404(AnswerPaper, user=request.user, attempt_number=attempt_num, question_paper=questionpaper_id) question = get_object_or_404(Question, pk=q_id) - if question in paper.questions_answered.all(): - next_q = paper.next_question(q_id) - return show_question(request, next_q, paper) + print ">>>>>>> Qt", q_id, next_q + # if question in paper.questions_answered.all(): #@@@ + # next_q = paper.next_question(q_id) + # return show_question(request, next_q, paper) if request.method == 'POST' and question.type == 'code': user_code = request.POST.get('answer') @@ -443,10 +444,10 @@ def skip(request, q_id, next_q=None, attempt_num=None, questionpaper_id=None): error=json.dumps([])) new_answer.save() paper.answers.add(new_answer) - if next_q is not None: + if next_q is not None: #@@@ next_q = get_object_or_404(Question, pk=next_q) - if next_q not in paper.questions_unanswered.all(): - return show_question(request, question, paper) + # if next_q not in paper.questions_unanswered.all(): + # return show_question(request, question, paper) else: next_q = paper.next_question(q_id) return show_question(request, next_q, paper) @@ -459,9 +460,9 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): paper = get_object_or_404(AnswerPaper, user=request.user, attempt_number=attempt_num, question_paper=questionpaper_id) current_question = get_object_or_404(Question, pk=q_id) - if current_question in paper.questions_answered.all(): - next_q = paper.next_question(q_id) - return show_question(request, next_q, paper) + # if current_question in paper.questions_answered.all(): #@@@ + # next_q = paper.next_question(q_id) + # return show_question(request, next_q, paper) if request.method == 'POST': snippet_code = request.POST.get('snippet') @@ -513,7 +514,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): error_message = result.get('error') new_answer.error = json.dumps(result.get('error')) next_question = current_question if current_question.type == 'code' \ - else paper.completed_question(current_question.id) + else paper.completed_question(current_question.id) ##@@ new_answer.save() paper.update_marks('inprogress') paper.set_end_time(timezone.now()) -- cgit From 0f730a5adc35e06f22f89fbbaa2d810e57074561 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Thu, 23 Feb 2017 17:44:51 +0530 Subject: Remove commented code --- yaksh/views.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'yaksh') diff --git a/yaksh/views.py b/yaksh/views.py index 6bd9d67..16299a8 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -432,10 +432,6 @@ def skip(request, q_id, next_q=None, attempt_num=None, questionpaper_id=None): paper = get_object_or_404(AnswerPaper, user=request.user, attempt_number=attempt_num, question_paper=questionpaper_id) question = get_object_or_404(Question, pk=q_id) - print ">>>>>>> Qt", q_id, next_q - # if question in paper.questions_answered.all(): #@@@ - # next_q = paper.next_question(q_id) - # return show_question(request, next_q, paper) if request.method == 'POST' and question.type == 'code': user_code = request.POST.get('answer') @@ -444,10 +440,8 @@ def skip(request, q_id, next_q=None, attempt_num=None, questionpaper_id=None): error=json.dumps([])) new_answer.save() paper.answers.add(new_answer) - if next_q is not None: #@@@ + if next_q is not None: next_q = get_object_or_404(Question, pk=next_q) - # if next_q not in paper.questions_unanswered.all(): - # return show_question(request, question, paper) else: next_q = paper.next_question(q_id) return show_question(request, next_q, paper) @@ -460,9 +454,6 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): paper = get_object_or_404(AnswerPaper, user=request.user, attempt_number=attempt_num, question_paper=questionpaper_id) current_question = get_object_or_404(Question, pk=q_id) - # if current_question in paper.questions_answered.all(): #@@@ - # next_q = paper.next_question(q_id) - # return show_question(request, next_q, paper) if request.method == 'POST': snippet_code = request.POST.get('snippet') @@ -514,7 +505,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): error_message = result.get('error') new_answer.error = json.dumps(result.get('error')) next_question = current_question if current_question.type == 'code' \ - else paper.completed_question(current_question.id) ##@@ + else paper.completed_question(current_question.id) new_answer.save() paper.update_marks('inprogress') paper.set_end_time(timezone.now()) -- cgit From 0f2a42799d3140de132c203cc255516caa69d617 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Thu, 2 Mar 2017 10:34:37 +0530 Subject: Rename completed_question model method to add_completed_question --- yaksh/models.py | 2 +- yaksh/test_models.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'yaksh') diff --git a/yaksh/models.py b/yaksh/models.py index 61c9059..b80482c 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -982,7 +982,7 @@ class AnswerPaper(models.Model): """Returns the number of questions left.""" return self.questions_unanswered.count() - def completed_question(self, question_id): + def add_completed_question(self, question_id): """ Adds the completed question to the list of answered questions and returns the next question. diff --git a/yaksh/test_models.py b/yaksh/test_models.py index 91d8806..a8d48e2 100644 --- a/yaksh/test_models.py +++ b/yaksh/test_models.py @@ -662,7 +662,7 @@ class AnswerPaperTestCases(unittest.TestCase): current_question = self.answerpaper.current_question() self.assertEqual(current_question.id, 1) # Test completed_question() method of Answer Paper - question = self.answerpaper.completed_question(1) + question = self.answerpaper.add_completed_question(1) self.assertEqual(self.answerpaper.questions_left(), 2) # Test next_question() method of Answer Paper @@ -724,14 +724,14 @@ class AnswerPaperTestCases(unittest.TestCase): # Test completed_question and next_question # When all questions are answered - current_question = self.answerpaper.completed_question(2) + current_question = self.answerpaper.add_completed_question(2) # Then self.assertEqual(self.answerpaper.questions_left(), 1) self.assertEqual(current_question.id, 3) # When - current_question = self.answerpaper.completed_question(3) + current_question = self.answerpaper.add_completed_question(3) # Then self.assertEqual(self.answerpaper.questions_left(), 0) -- cgit From d0d4c9ab3a409c68766bc044825bf22b0519f6a3 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Fri, 3 Mar 2017 16:35:18 +0530 Subject: Multiple changes: - Fix movement from one question to another in next_question - Fix random display of errors from MCQs - Add Notification display if question has been attempted - Fix test cases for changes made --- yaksh/models.py | 6 +++--- yaksh/templates/yaksh/question.html | 24 +++++++++++++++--------- yaksh/test_models.py | 8 ++++---- yaksh/views.py | 17 ++++++++++------- 4 files changed, 32 insertions(+), 23 deletions(-) (limited to 'yaksh') diff --git a/yaksh/models.py b/yaksh/models.py index b80482c..f0f4ca6 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -1000,8 +1000,8 @@ class AnswerPaper(models.Model): Skips the current question and returns the next sequentially available question. """ - unanswered_questions = self.questions_unanswered.all() - questions = list(unanswered_questions.values_list('id', flat=True)) + all_questions = self.questions.all() + questions = list(all_questions.values_list('id', flat=True)) if len(questions) == 0: return None try: @@ -1009,7 +1009,7 @@ class AnswerPaper(models.Model): next_id = questions[index+1] except (ValueError, IndexError): next_id = questions[0] - return unanswered_questions.get(id=next_id) + return all_questions.get(id=next_id) def time_left(self): """Return the time remaining for the user in seconds.""" diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html index 1f6e67d..f94298e 100644 --- a/yaksh/templates/yaksh/question.html +++ b/yaksh/templates/yaksh/question.html @@ -135,13 +135,19 @@ function call_skip(url) {% block onload %} onload="updateTime();" {% endblock %} {% block main %} -

    -
    - {% csrf_token %} - -
    -
    -

    {{ question.summary }} +

    + {% if notification %} + + {% endif %} + + {% csrf_token %} + +
    +
    +

    + {{ question.summary }} {% if question.type == "mcq" %} (Single Correct Choice Questions) {% elif question.type == "mcc" %} @@ -151,8 +157,8 @@ function call_skip(url) {% elif question.type == "upload" %} (ASSIGNMENT UPLOAD) {% endif %} - - (Marks : {{ question.points }}) + + (Marks : {{ question.points }})

    {{ question.description|safe }} {% if files %} diff --git a/yaksh/test_models.py b/yaksh/test_models.py index a8d48e2..b6934e3 100644 --- a/yaksh/test_models.py +++ b/yaksh/test_models.py @@ -694,7 +694,7 @@ class AnswerPaperTestCases(unittest.TestCase): # Then self.assertTrue(next_question_id is not None) - self.assertEqual(next_question_id.id, 2) + self.assertEqual(next_question_id.id, 1) # Given, last question in the list current_question_id = 3 @@ -704,7 +704,7 @@ class AnswerPaperTestCases(unittest.TestCase): # Then self.assertTrue(next_question_id is not None) - self.assertEqual(next_question_id.id, 2) + self.assertEqual(next_question_id.id, 1) # Test get_questions_answered() method # When @@ -735,13 +735,13 @@ class AnswerPaperTestCases(unittest.TestCase): # Then self.assertEqual(self.answerpaper.questions_left(), 0) - self.assertTrue(current_question is None) + self.assertTrue(current_question is not None) # When next_question_id = self.answerpaper.next_question(current_question_id) # Then - self.assertTrue(next_question_id is None) + self.assertTrue(next_question_id is not None) def test_update_marks(self): """ Test update_marks method of AnswerPaper""" diff --git a/yaksh/views.py b/yaksh/views.py index 16299a8..163c12f 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -400,7 +400,7 @@ def start(request, questionpaper_id=None, attempt_num=None): @login_required -def show_question(request, question, paper, error_message=None): +def show_question(request, question, paper, error_message=None, notification=None): """Show a question if possible.""" user = request.user if not question: @@ -412,10 +412,12 @@ def show_question(request, question, paper, error_message=None): if paper.time_left() <= 0: reason='Your time is up!' return complete(request, reason, paper.attempt_number, paper.question_paper.id) + if question in paper.questions_answered.all(): + notification = 'You have already attempted this question' test_cases = question.get_test_cases() files = FileUpload.objects.filter(question_id=question.id, hide=False) context = {'question': question, 'paper': paper, 'error_message': error_message, - 'test_cases': test_cases, 'files': files, + 'test_cases': test_cases, 'files': files, 'notification': notification, 'last_attempt': question.snippet.encode('unicode-escape')} answers = paper.get_previous_answers(question) if answers: @@ -472,14 +474,14 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): assign.assignmentFile = request.FILES['assignment'] assign.save() user_answer = 'ASSIGNMENT UPLOADED' - next_q = paper.completed_question(current_question.id) + next_q = paper.add_completed_question(current_question.id) return show_question(request, next_q, paper) else: user_code = request.POST.get('answer') user_answer = snippet_code + "\n" + user_code if snippet_code else user_code if not user_answer: msg = ["Please submit a valid option or code"] - return show_question(request, current_question, paper, msg) + return show_question(request, current_question, paper, notification=msg) new_answer = Answer(question=current_question, answer=user_answer, correct=False, error=json.dumps([])) new_answer.save() @@ -497,15 +499,16 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): new_answer.correct = result.get('success') error_message = None new_answer.error = json.dumps(result.get('error')) - next_question = paper.completed_question(current_question.id) + next_question = paper.add_completed_question(current_question.id) else: new_answer.marks = (current_question.points * result['weight'] / current_question.get_maximum_test_case_weight()) \ if current_question.partial_grading and current_question.type == 'code' else 0 - error_message = result.get('error') + error_message = result.get('error') if current_question.type == 'code' \ + else None new_answer.error = json.dumps(result.get('error')) next_question = current_question if current_question.type == 'code' \ - else paper.completed_question(current_question.id) + else paper.add_completed_question(current_question.id) new_answer.save() paper.update_marks('inprogress') paper.set_end_time(timezone.now()) -- cgit From c118c7eff7abaeba18f7c375828d2e022d21cb9f Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Fri, 3 Mar 2017 19:16:46 +0530 Subject: Modify UI for notifications in submitted code questions --- yaksh/templates/yaksh/question.html | 19 +++++++++++++++---- yaksh/views.py | 4 +++- 2 files changed, 18 insertions(+), 5 deletions(-) (limited to 'yaksh') diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html index f94298e..5b5326d 100644 --- a/yaksh/templates/yaksh/question.html +++ b/yaksh/templates/yaksh/question.html @@ -137,9 +137,15 @@ function call_skip(url) {% block main %}

    {% if notification %} - + {% if question.type == "code" %} + + {% else %} + + {% endif %} {% endif %} {% csrf_token %} @@ -204,10 +210,15 @@ function call_skip(url) {% elif question.type == "upload" %}
       {% else %} -    + {% if notification == None %} +    + {% endif %} {% endif %} + {% if paper.question_paper.quiz.allow_skip and not paper.get_questions_unanswered|length_is:"1" %} + {% if notification == None %} + {% endif %}

    diff --git a/yaksh/views.py b/yaksh/views.py index 163c12f..1089067 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -413,7 +413,9 @@ def show_question(request, question, paper, error_message=None, notification=Non reason='Your time is up!' return complete(request, reason, paper.attempt_number, paper.question_paper.id) if question in paper.questions_answered.all(): - notification = 'You have already attempted this question' + notification = 'You have already attempted this question successfully' \ + if question.type == "code" else \ + 'You have already attempted this question' test_cases = question.get_test_cases() files = FileUpload.objects.filter(question_id=question.id, hide=False) context = {'question': question, 'paper': paper, 'error_message': error_message, -- cgit From a53df8040785cffaf46bfc1775c59eed7c4a15c3 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Mon, 6 Mar 2017 19:56:56 +0530 Subject: Multiple fixes: - Add error message details to SeleniumTestError - Fix next question cycling in models - Fix model test cases --- yaksh/live_server_tests/selenium_test.py | 4 ++-- yaksh/models.py | 8 ++++++-- yaksh/test_models.py | 4 ++-- 3 files changed, 10 insertions(+), 6 deletions(-) (limited to 'yaksh') diff --git a/yaksh/live_server_tests/selenium_test.py b/yaksh/live_server_tests/selenium_test.py index d91f3ec..277f08e 100644 --- a/yaksh/live_server_tests/selenium_test.py +++ b/yaksh/live_server_tests/selenium_test.py @@ -29,8 +29,8 @@ class SeleniumTest(): except Exception as e: self.driver.close() msg = ("An Error occurred while running the Selenium load" - " test on Yaksh!" - "Error:\n ".format(e)) + " test on Yaksh!\n" + "Error:\n{0}".format(e)) raise SeleniumTestError(msg) diff --git a/yaksh/models.py b/yaksh/models.py index f0f4ca6..398f508 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -987,11 +987,12 @@ class AnswerPaper(models.Model): Adds the completed question to the list of answered questions and returns the next question. """ - next_question = self.next_question(question_id) if question_id not in self.questions_answered.all(): self.questions_answered.add(question_id) self.questions_unanswered.remove(question_id) - if next_question.id == int(question_id): + + next_question = self.next_question(question_id) + if next_question and next_question.id == int(question_id): return None return next_question @@ -1001,9 +1002,12 @@ class AnswerPaper(models.Model): available question. """ all_questions = self.questions.all() + unanswered_questions = self.questions_unanswered.all() questions = list(all_questions.values_list('id', flat=True)) if len(questions) == 0: return None + if unanswered_questions.count() == 0: + return None try: index = questions.index(int(question_id)) next_id = questions[index+1] diff --git a/yaksh/test_models.py b/yaksh/test_models.py index b6934e3..cd66aed 100644 --- a/yaksh/test_models.py +++ b/yaksh/test_models.py @@ -735,13 +735,13 @@ class AnswerPaperTestCases(unittest.TestCase): # Then self.assertEqual(self.answerpaper.questions_left(), 0) - self.assertTrue(current_question is not None) + self.assertTrue(current_question is None) # When next_question_id = self.answerpaper.next_question(current_question_id) # Then - self.assertTrue(next_question_id is not None) + self.assertTrue(next_question_id is None) def test_update_marks(self): """ Test update_marks method of AnswerPaper""" -- cgit From e231c13eade3afaa8f03a56fb69923b78c7a02d8 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Tue, 7 Mar 2017 11:43:14 +0530 Subject: Add numbering enrolled/requested/rejected students in course details display --- yaksh/templates/yaksh/course_detail.html | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'yaksh') diff --git a/yaksh/templates/yaksh/course_detail.html b/yaksh/templates/yaksh/course_detail.html index dc85080..4b7efaf 100644 --- a/yaksh/templates/yaksh/course_detail.html +++ b/yaksh/templates/yaksh/course_detail.html @@ -31,6 +31,7 @@  Select all
    + @@ -43,6 +44,7 @@ {% for request in course.get_requests %} + @@ -71,6 +73,7 @@  Select all
    Full Name Email
    {{ forloop.counter }}. {{request.get_full_name}} {{request.email}} {{request.profile.roll_number}}
    + @@ -83,6 +86,7 @@ {% csrf_token %} + @@ -107,6 +111,7 @@  Select all
    Full Name Email
    {{ forloop.counter }}. {{ enrolled.get_full_name|title }} {{enrolled.email}} {{enrolled.profile.roll_number}}
    + @@ -119,6 +124,7 @@ {% csrf_token %} + -- cgit From 7f815f58c6af4b5020fba0dc490c8e7f9d328589 Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Tue, 7 Mar 2017 16:05:40 +0530 Subject: Hide inactive/deleted questions in Questionpaper creation and question filter --- yaksh/views.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'yaksh') diff --git a/yaksh/views.py b/yaksh/views.py index 74c409c..4c53d69 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -771,7 +771,7 @@ def ajax_questions_filter(request): """Ajax call made when filtering displayed questions.""" user = request.user - filter_dict = {"user_id": user.id} + filter_dict = {"user_id": user.id, "active": True} question_type = request.POST.get('question_type') marks = request.POST.get('marks') language = request.POST.get('language') @@ -795,7 +795,10 @@ def _get_questions(user, question_type, marks): if question_type is None and marks is None: return None if question_type: - questions = Question.objects.filter(type=question_type, user=user) + questions = Question.objects.filter(type=question_type, + user=user, + active=True + ) if marks: questions = questions.filter(points=marks) return questions -- cgit From f57cfacf41f8a1d72a56ea8c875f906e7db2a15e Mon Sep 17 00:00:00 2001 From: ankitjavalkar Date: Wed, 8 Mar 2017 10:34:12 +0530 Subject: Hide/Disable submit in correct code questions --- yaksh/templates/yaksh/question.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'yaksh') diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html index 5b5326d..9dd0de5 100644 --- a/yaksh/templates/yaksh/question.html +++ b/yaksh/templates/yaksh/question.html @@ -210,13 +210,13 @@ function call_skip(url) {% elif question.type == "upload" %}
       {% else %} - {% if notification == None %} + {% if question in paper.get_questions_unanswered %}    {% endif %} {% endif %} {% if paper.question_paper.quiz.allow_skip and not paper.get_questions_unanswered|length_is:"1" %} - {% if notification == None %} + {% if question in paper.get_questions_unanswered %} {% endif %} -- cgit
    Full Name Email
    {{ forloop.counter }}. {{rejected.get_full_name|title}} {{rejected.email}} {{rejected.profile.roll_number}}