diff options
Diffstat (limited to 'yaksh')
-rw-r--r-- | yaksh/models.py | 24 | ||||
-rw-r--r-- | yaksh/static/yaksh/css/exam.css | 9 | ||||
-rw-r--r-- | yaksh/static/yaksh/css/yakshcustom.css | 2 | ||||
-rw-r--r-- | yaksh/templates/exam.html | 47 | ||||
-rw-r--r-- | yaksh/templatetags/custom_filters.py | 5 | ||||
-rw-r--r-- | yaksh/test_models.py | 58 | ||||
-rw-r--r-- | yaksh/views.py | 8 |
7 files changed, 108 insertions, 45 deletions
diff --git a/yaksh/models.py b/yaksh/models.py index 427b584..cce90e7 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -6,7 +6,8 @@ import ruamel.yaml from ruamel.yaml.scalarstring import PreservedScalarString from ruamel.yaml.comments import CommentedMap from random import sample -from collections import Counter +from collections import Counter, defaultdict + from django.db import models from django.contrib.auth.models import User, Group, Permission from django.contrib.contenttypes.models import ContentType @@ -80,6 +81,17 @@ string_check_type = ( ("exact", "Case Sensitive"), ) +legend_display_types = { + "mcq": {"label": "Objective Type"}, + "mcc": {"label": "Objective Type"}, + "code": {"label": "Programming"}, + "upload": {"label": "Upload"}, + "integer": {"label": "Objective Type"}, + "string": {"label": "Objective Type"}, + "float": {"label": "Objective Type"}, + "arrange": {"label": "Objective Type"}, + } + attempts = [(i, i) for i in range(1, 6)] attempts.append((-1, 'Infinite')) @@ -2091,6 +2103,16 @@ class AnswerPaper(models.Model): def get_previous_answers(self, question): return self.answers.filter(question=question).order_by('-id') + def get_categorized_question_indices(self): + category_question_map = defaultdict(list) + for index, question in enumerate(self.get_all_ordered_questions(), 1): + question_category = legend_display_types.get(question.type) + if question_category: + category_question_map[ + question_category["label"] + ].append(index) + return dict(category_question_map) + def validate_answer(self, user_answer, question, json_data=None, uid=None, server_port=SERVER_POOL_PORT): """ diff --git a/yaksh/static/yaksh/css/exam.css b/yaksh/static/yaksh/css/exam.css index b0bb379..a246141 100644 --- a/yaksh/static/yaksh/css/exam.css +++ b/yaksh/static/yaksh/css/exam.css @@ -1,7 +1,14 @@ -table td, table th { border: #ff8295 solid 1px !important; +#assertion td, #assertion th, #stdio td, #stdio th { border: #ff8295 solid 1px !important; word-wrap: break-word !important; white-space: pre-wrap !important; } #stdio, #assertion { table-layout: fixed } +.legend_table{ + border: 1px solid; + width: 15em; + background-color: white; + border-spacing: 5px; + border-collapse: collapse; +} diff --git a/yaksh/static/yaksh/css/yakshcustom.css b/yaksh/static/yaksh/css/yakshcustom.css index 86403ac..a9b4349 100644 --- a/yaksh/static/yaksh/css/yakshcustom.css +++ b/yaksh/static/yaksh/css/yakshcustom.css @@ -228,5 +228,3 @@ html { overflow-y: auto; -ms-overflow-style: -ms-autohiding-scrollbar; } - -/*---------------------*/
\ No newline at end of file diff --git a/yaksh/templates/exam.html b/yaksh/templates/exam.html index c452929..29ad167 100644 --- a/yaksh/templates/exam.html +++ b/yaksh/templates/exam.html @@ -1,10 +1,5 @@ {% extends "base.html" %} {% load custom_filters %} - - - - -{% load custom_filters %} {% block nav %} <div class="container-fluid yakshnav"> <nav class="navbar fixed-top navbar-expand-lg yakshheading yakshnav"> @@ -83,28 +78,26 @@ <p class="text-center">Question(s) left: <b>{{ paper.questions_left }}</b></p> </div> <br> - <div class=""> - <div class=""> - <div class=""> - {% for types in question_types %} - {% get_questions_by_type paper.get_all_ordered_questions types as questions_by_type %} - {% if types == "mcq" %} Single Correct Choice - {% elif types == "mcc" %} Multiple Correct Choice - {% elif types == "code" %} Programming - {% elif types == "upload" %} Assignment Upload - {% elif types == "integer" %} Integer Blanks - {% elif types == "string" %} String Blanks - {% elif types == "float" %} Float Blanks - {% elif types == "arrange" %} Arranging Options - {% endif %} - ---> - <b> {% for question in questions_by_type %} {{question.id}} {%endfor%} </b> - <br> - {%endfor%} - </div> - </div> - </div> - + <table class = "legend_table table-bordered table-sm"> + <thead> + <tr> + <th>Category</th> + <th>Question No.</th> + </tr> + </thead> + <tbody> + {% for category, question_number in paper.get_categorized_question_indices.items %} + <tr> + <td> + {{category}} + </td> + <td> + {{question_number| join:", "}} + </td> + </tr> + {% endfor %} + </tbody> + </table> </div> <!--end of sidebar --> <a href="#sidebar" data-toggle="collapse" id="sidebaricon"><i class="fa fa-navicon fa-lg"></i></a> diff --git a/yaksh/templatetags/custom_filters.py b/yaksh/templatetags/custom_filters.py index dcae7f9..29f4b59 100644 --- a/yaksh/templatetags/custom_filters.py +++ b/yaksh/templatetags/custom_filters.py @@ -85,10 +85,5 @@ def replace_spaces(name): @register.simple_tag -def get_questions_by_type(all_questions, question_type): - return [question for question in all_questions if question.type == question_type] - - -@register.simple_tag def course_grade(course, user): return course.get_grade(user) diff --git a/yaksh/test_models.py b/yaksh/test_models.py index aea47de..1f38d03 100644 --- a/yaksh/test_models.py +++ b/yaksh/test_models.py @@ -4,7 +4,7 @@ from yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\ QuestionSet, AnswerPaper, Answer, Course, StandardTestCase,\ StdIOBasedTestCase, FileUpload, McqTestCase, AssignmentUpload,\ LearningModule, LearningUnit, Lesson, LessonFile, CourseStatus, \ - create_group + create_group, legend_display_types from yaksh.code_server import ( ServerPool, get_result as get_result_from_code_server ) @@ -21,6 +21,7 @@ import os import shutil import tempfile from threading import Thread +from collections import defaultdict from yaksh import settings @@ -287,9 +288,10 @@ class ProfileTestCases(unittest.TestCase): def setUp(self): self.creator = User.objects.get(username='creator') self.profile = Profile.objects.get(user=self.creator) - self.teacher = User.objects.create_user(username='teacher_profile', - password='teacher_profile', - email='teacher_profile@test.com') + self.teacher = User.objects.create_user( + username='teacher_profile', + password='teacher_profile', + email='teacher_profile@test.com') Profile.objects.create( user=self.teacher, roll_number=123, institute='IIT', is_moderator=True, department='Chemical', position='Teacher' @@ -329,6 +331,7 @@ class ProfileTestCases(unittest.TestCase): self.teacher.delete() self.course.delete() + ############################################################################### class QuestionTestCases(unittest.TestCase): def setUp(self): @@ -988,7 +991,6 @@ class AnswerPaperTestCases(unittest.TestCase): quiz=self.quiz2, total_marks=3 ) self.qtn_paper_with_single_question.save() - all_questions = Question.objects.filter(user=self.user).order_by("id") self.questions = all_questions[0:3] self.start_time = timezone.now() @@ -1021,6 +1023,7 @@ class AnswerPaperTestCases(unittest.TestCase): ) self.answerpaper.questions_unanswered.add(*self.questions) self.answerpaper.save() + # answers for the Answer Paper self.answer_right = Answer( question=self.question1, @@ -1135,6 +1138,33 @@ class AnswerPaperTestCases(unittest.TestCase): self.user2_answerpaper2 = self.question_paper.make_answerpaper( self.user2, self.ip, 1, self.course.id ) + self.questions_list = Question.objects.filter( + summary__in=summary_list[0:5]) + # create question_paper3 + self.question_paper3 = QuestionPaper( + quiz=self.quiz2, total_marks=3, shuffle_questions=True) + self.question_paper3.save() + question_list_with_only_one_category = [ + question for question in self.questions_list + if question.type == 'code'] + self.question_paper3.fixed_questions.add( + *question_list_with_only_one_category + ) + # create anspaper for user1 with questions of only one category + self.user1_answerpaper2 = self.question_paper3.make_answerpaper( + self.user, self.ip, 1, self.course.id + ) + # create question_paper4 + self.question_paper4 = QuestionPaper( + quiz=self.quiz, total_marks=0, shuffle_questions=True + ) + self.question_paper4.save() + + # create anspaper for user1 with no questions + self.user1_answerpaper3 = self.question_paper4.make_answerpaper( + self.user, self.ip, 1, self.course.id + ) + settings.code_evaluators['python']['standardtestcase'] = \ "yaksh.python_assertion_evaluator.PythonAssertionEvaluator" self.SERVER_POOL_PORT = 4000 @@ -1583,6 +1613,24 @@ class AnswerPaperTestCases(unittest.TestCase): course=self.answerpaper.course ) + def test_get_categorized_question_indices_with_multiple_categories(self): + question_indices = {'Programming': [1], 'Objective Type': [2, 3]} + categorized_question_indices = \ + self.answerpaper.get_categorized_question_indices() + self.assertDictEqual(question_indices, categorized_question_indices) + + def test_get_categorized_question_indices_for_only_one_category(self): + question_indices = {'Programming': [1, 2, 3]} + categorized_question_indices = \ + self.user1_answerpaper2.get_categorized_question_indices() + self.assertDictEqual(question_indices, categorized_question_indices) + + def test_get_categorized_question_indices_for_no_questions(self): + question_indices = {} + categorized_question_indices = \ + self.user1_answerpaper3.get_categorized_question_indices() + self.assertDictEqual(question_indices, categorized_question_indices) + ############################################################################### class CourseTestCases(unittest.TestCase): diff --git a/yaksh/views.py b/yaksh/views.py index 0f81931..6c7a12e 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -615,7 +615,6 @@ def show_question(request, question, paper, error_message=None, course = Course.objects.get(id=course_id) module = course.learning_module.get(id=module_id) all_modules = course.get_learning_modules() - all_question_types = [types[0] for types in question_types] context = { 'question': question, 'paper': paper, @@ -631,7 +630,6 @@ def show_question(request, question, paper, error_message=None, 'delay_time': delay_time, 'quiz_type': quiz_type, 'all_modules': all_modules, - "question_types": all_question_types } answers = paper.get_previous_answers(question) if answers: @@ -905,8 +903,10 @@ def complete(request, reason=None, attempt_num=None, questionpaper_id=None, """Show a page to inform user that the quiz has been completed.""" user = request.user if questionpaper_id is None: - message = (reason or "An Unexpected Error occurred. Please contact your" - " instructor/administrator.") + message = ( + reason or "An Unexpected Error occurred." + " Please contact your instructor/administrator." + ) context = {'message': message} return my_render_to_response(request, 'yaksh/complete.html', context) else: |