summaryrefslogtreecommitdiff
path: root/yaksh
diff options
context:
space:
mode:
authorprathamesh2016-08-29 15:08:04 +0530
committerprathamesh2016-08-29 15:08:04 +0530
commit95a910aee400c7706ae8f14a94eb3c9ea9289c91 (patch)
tree7ee8fc707bd1e48fd6ce67d0fdea2a1e8f0af650 /yaksh
parente1e299b671a19b65705fb256d282e1e802a4c051 (diff)
downloadonline_test-95a910aee400c7706ae8f14a94eb3c9ea9289c91.tar.gz
online_test-95a910aee400c7706ae8f14a94eb3c9ea9289c91.tar.bz2
online_test-95a910aee400c7706ae8f14a94eb3c9ea9289c91.zip
Views sometimes use cent percent CPU, fixed
After correct submission(POST) of code question, same question is shown for 2 seconds with a message "Correct Output". After 2 seconds, the same correctly answered question is resubmitted(GET) to the server.Since the question is already answered, it skips the question using the skip method of answerpaper. In skip method we have used cycle itertool, which loops in a cyclic manner, never ending. So it is terminated when we get a question match in an unanswered questions list with the submitted question. But the question is already answered so we never get a match and loop runs infinitely. So used list instead of cycle. Also, after correct answer, the user is to always get first question in the answered list of question instead of next question after the answered one. So changed the completed_question method of answerpaper.
Diffstat (limited to 'yaksh')
-rw-r--r--yaksh/models.py23
-rw-r--r--yaksh/test_models.py93
-rw-r--r--yaksh/views.py10
3 files changed, 100 insertions, 26 deletions
diff --git a/yaksh/models.py b/yaksh/models.py
index 73d4b27..6f11c09 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -784,21 +784,28 @@ 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)
self.questions_answered.add(question_id)
self.questions_unanswered.remove(question_id)
+ if next_question.id == int(question_id):
+ return None
+ return next_question
- return self.current_question()
-
- def skip(self, question_id):
+ def next_question(self, question_id):
"""
Skips the current question and returns the next sequentially
available question.
"""
- questions = self.questions_unanswered.all()
- question_cycle = cycle(questions)
- for question in question_cycle:
- if question.id==int(question_id):
- return question_cycle.next()
+ unanswered_questions = self.questions_unanswered.all()
+ questions = list(unanswered_questions.values_list('id', flat=True))
+ if len(questions) == 0:
+ return None
+ try:
+ index = questions.index(int(question_id))
+ next_id = questions[index+1]
+ except (ValueError, IndexError):
+ next_id = questions[0]
+ return unanswered_questions.get(id=next_id)
def time_left(self):
"""Return the time remaining for the user in seconds."""
diff --git a/yaksh/test_models.py b/yaksh/test_models.py
index 8bd2dda..c0721f3 100644
--- a/yaksh/test_models.py
+++ b/yaksh/test_models.py
@@ -424,7 +424,7 @@ class AnswerPaperTestCases(unittest.TestCase):
self.answerpaper.save()
# answers for the Answer Paper
self.answer_right = Answer(question=Question.objects.get(id=1),
- answer="Demo answer",
+ answer="Demo answer",
correct=True, marks=1
)
self.answer_wrong = Answer(question=Question.objects.get(id=2),
@@ -458,20 +458,85 @@ class AnswerPaperTestCases(unittest.TestCase):
# Test completed_question() method of Answer Paper
question = self.answerpaper.completed_question(1)
self.assertEqual(self.answerpaper.questions_left(), 2)
- # Test skip() method of Answer Paper
+
+ # Test next_question() method of Answer Paper
current_question = self.answerpaper.current_question()
self.assertEqual(current_question.id, 2)
- next_question_id = self.answerpaper.skip(current_question.id)
+
+ # When
+ next_question_id = self.answerpaper.next_question(current_question.id)
+
+ # Then
self.assertTrue(next_question_id is not None)
self.assertEqual(next_question_id.id, 3)
+
+ # Given, here question is already answered
+ current_question_id = 1
+
+ # When
+ next_question_id = self.answerpaper.next_question(current_question_id)
+
+ # Then
+ self.assertTrue(next_question_id is not None)
+ self.assertEqual(next_question_id.id, 2)
+
+ # Given, wrong question id
+ current_question_id = 12
+
+ # When
+ next_question_id = self.answerpaper.next_question(current_question_id)
+
+ # Then
+ self.assertTrue(next_question_id is not None)
+ self.assertEqual(next_question_id.id, 2)
+
+ # Given, last question in the list
+ current_question_id = 3
+
+ # When
+ next_question_id = self.answerpaper.next_question(current_question_id)
+
+ # Then
+ self.assertTrue(next_question_id is not None)
+ self.assertEqual(next_question_id.id, 2)
+
+ # Test get_questions_answered() method
+ # When
questions_answered = self.answerpaper.get_questions_answered()
+
+ # Then
self.assertEqual(questions_answered.count(), 1)
self.assertSequenceEqual(questions_answered, [self.questions[0]])
+
+ # When
questions_unanswered = self.answerpaper.get_questions_unanswered()
+
+ # Then
self.assertEqual(questions_unanswered.count(), 2)
self.assertSequenceEqual(questions_unanswered,
[self.questions[1], self.questions[2]])
+ # Test completed_question and next_question
+ # When all questions are answered
+ current_question = self.answerpaper.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)
+
+ # Then
+ self.assertEqual(self.answerpaper.questions_left(), 0)
+ self.assertTrue(current_question is None)
+
+ # When
+ next_question_id = self.answerpaper.next_question(current_question_id)
+
+ # Then
+ self.assertTrue(next_question_id is None)
+
def test_update_marks(self):
""" Test update_marks method of AnswerPaper"""
self.answerpaper.update_marks('inprogress')
@@ -584,7 +649,7 @@ class CourseTestCases(unittest.TestCase):
def test_add_teachers(self):
""" Test to add teachers to a course"""
self.course.add_teachers(self.student1, self.student2)
- self.assertSequenceEqual(self.course.get_teachers(),
+ self.assertSequenceEqual(self.course.get_teachers(),
[self.student1, self.student2])
def test_remove_teachers(self):
@@ -616,23 +681,23 @@ class CourseTestCases(unittest.TestCase):
class TestCaseTestCases(unittest.TestCase):
def setUp(self):
self.user = User.objects.get(pk=1)
- self.question1 = Question(summary='Demo question 1',
+ self.question1 = Question(summary='Demo question 1',
language='Python',
- type='Code',
+ type='Code',
active=True,
- description='Write a function',
+ description='Write a function',
points=1.0,
- test_case_type="standardtestcase",
+ test_case_type="standardtestcase",
user=self.user,
snippet='def myfunc()'
)
- self.question2 = Question(summary='Demo question 2',
+ self.question2 = Question(summary='Demo question 2',
language='Python',
- type='Code',
+ type='Code',
active=True,
- description='Write to standard output',
+ description='Write to standard output',
points=1.0,
- test_case_type="stdoutbasedtestcase",
+ test_case_type="stdoutbasedtestcase",
user=self.user,
snippet='def myfunc()'
)
@@ -658,13 +723,13 @@ class TestCaseTestCases(unittest.TestCase):
def test_assertion_testcase(self):
""" Test question """
self.assertEqual(self.assertion_testcase.question, self.question1)
- self.assertEqual(self.assertion_testcase.test_case,
+ self.assertEqual(self.assertion_testcase.test_case,
'assert myfunc(12, 13) == 15')
def test_stdout_based_testcase(self):
""" Test question """
self.assertEqual(self.stdout_based_testcase.question, self.question2)
- self.assertEqual(self.stdout_based_testcase.expected_output,
+ self.assertEqual(self.stdout_based_testcase.expected_output,
'Hello World'
)
diff --git a/yaksh/views.py b/yaksh/views.py
index e1ec44e..2ee964f 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -460,10 +460,12 @@ def skip(request, q_id, next_q=None, attempt_num=None, questionpaper_id=None):
correct=False, skipped=True)
new_answer.save()
paper.answers.add(new_answer)
- if next_q is None:
- next_q = paper.skip(q_id) if paper.skip(q_id) else question
- else:
+ 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)
@@ -475,7 +477,7 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None):
question_paper=questionpaper_id)
question = get_object_or_404(Question, pk=q_id)
if question in paper.questions_answered.all():
- next_q = paper.skip(q_id)
+ next_q = paper.next_question(q_id)
return show_question(request, next_q, paper)
if request.method == 'POST':