diff options
-rw-r--r-- | yaksh/forms.py | 2 | ||||
-rw-r--r-- | yaksh/models.py | 34 | ||||
-rw-r--r-- | yaksh/static/yaksh/css/question.css | 5 | ||||
-rw-r--r-- | yaksh/templates/yaksh/add_question.html | 1 | ||||
-rw-r--r-- | yaksh/templates/yaksh/question.html | 11 | ||||
-rw-r--r-- | yaksh/views.py | 14 |
6 files changed, 59 insertions, 8 deletions
diff --git a/yaksh/forms.py b/yaksh/forms.py index 4bf4fcf..df590de 100644 --- a/yaksh/forms.py +++ b/yaksh/forms.py @@ -1,7 +1,7 @@ from django import forms from yaksh.models import get_model_class, Profile, Quiz, Question, TestCase, Course,\ QuestionPaper, StandardTestCase, StdIOBasedTestCase, \ - HookTestCase, IntegerTestCase + HookTestCase, IntegerTestCase, StringTestCase from django.contrib.auth import authenticate from django.contrib.auth.models import User from django.contrib.contenttypes.models import ContentType diff --git a/yaksh/models.py b/yaksh/models.py index 81b8d7f..6381d4b 100644 --- a/yaksh/models.py +++ b/yaksh/models.py @@ -41,6 +41,7 @@ question_types = ( ("code", "Code"), ("upload", "Assignment Upload"), ("integer", "Answer in Integer"), + ("string", "Answer in String"), ) enrollment_methods = ( @@ -54,6 +55,12 @@ test_case_types = ( ("mcqtestcase", "MCQ Testcase"), ("hooktestcase", "Hook Testcase"), ("integertestcase", "Integer Testcase"), + ("stringtestcase", "String Testcase"), + ) + +string_check_type = ( + ("lower", "Lower case Checking"), + ("exact", "Exact case String Checking"), ) attempts = [(i, i) for i in range(1, 6)] @@ -1135,11 +1142,24 @@ class AnswerPaper(models.Model): if set(user_answer) == set(expected_answers): result['success'] = True result['error'] = ['Correct answer'] + elif question.type == 'integer': expected_answer = question.get_test_case().correct if expected_answer == int(user_answer): result['success'] = True result['error'] = ['Correct answer'] + + elif question.type == 'string': + testcase = question.get_test_case() + if testcase.string_check == "lower": + if testcase.correct.lower() == user_answer.lower(): + result['success'] = True + result['error'] = ['Correct answer'] + else: + if testcase.correct == user_answer: + result['success'] = True + result['error'] = ['Correct answer'] + elif question.type == 'code': user_dir = self.user.profile.get_user_dir() json_result = code_server.run_code( @@ -1289,10 +1309,22 @@ class HookTestCase(TestCase): return u'Hook Testcase | Correct: {0}'.format(self.hook_code) class IntegerTestCase(TestCase): - correct = models.IntegerField(default=False) + correct = models.IntegerField(default=None) def get_field_value(self): return {"test_case_type": "integertestcase", "correct": self.correct} def __str__(self): return u'Integer Testcase | Correct: {0}'.format(self.correct) + + +class StringTestCase(TestCase): + correct = models.TextField(default=None) + string_check = models.CharField(max_length=200,choices=string_check_type) + + def get_field_value(self): + return {"test_case_type": "stringtestcase", "correct": self.correct, + "string_check":self.string_check} + + def __str__(self): + return u'String Testcase | Correct: {0}'.format(self.correct) diff --git a/yaksh/static/yaksh/css/question.css b/yaksh/static/yaksh/css/question.css index 9fb2e1a..fdbe5f2 100644 --- a/yaksh/static/yaksh/css/question.css +++ b/yaksh/static/yaksh/css/question.css @@ -36,3 +36,8 @@ .lineObj{ color: grey; } + +#string{ + width: 60em; + height: 10em; +} diff --git a/yaksh/templates/yaksh/add_question.html b/yaksh/templates/yaksh/add_question.html index a1b5e90..de3ce56 100644 --- a/yaksh/templates/yaksh/add_question.html +++ b/yaksh/templates/yaksh/add_question.html @@ -57,6 +57,7 @@ <option value="mcqtestcase">MCQ/MCC </option> <option value="hooktestcase">Hook </option> <option value="integertestcase">Integer </option> + <option value="stringtestcase"> String </option> </select></p> <center> <button class="btn" type="submit" name="save_question">Save</button> diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html index 35c8052..13726c0 100644 --- a/yaksh/templates/yaksh/question.html +++ b/yaksh/templates/yaksh/question.html @@ -142,15 +142,17 @@ function call_skip(url) <div class="panel-heading"> <h4><u> {{ question.summary }} {% if question.type == "mcq" %} - (Single Correct Choice) + (SINGLE CORRECT CHOICE) {% elif question.type == "mcc" %} - (Multiple Correct Choices) + (MULTIPLE CORRECT CHOICES) {% elif question.type == "code" %} (PROGRAMMING) {% elif question.type == "upload" %} (ASSIGNMENT UPLOAD) {% elif question.type == "integer" %} (ANSWER IN INTEGER) + {% elif question.type == "string" %} + (ANSWER IN STRING) {% endif %} </u> <font class=pull-right>(Marks : {{ question.points }}) </font> @@ -176,6 +178,11 @@ function call_skip(url) <br/> {% endif %} + {% if question.type == "string" %} + Enter Text:<br/> + <textarea name="answer" id="string"></textarea> + <br/><br/> + {% endif %} {% if question.type == "mcc" %} {% for test_case in test_cases %} diff --git a/yaksh/views.py b/yaksh/views.py index 996a3ce..6a19744 100644 --- a/yaksh/views.py +++ b/yaksh/views.py @@ -16,6 +16,7 @@ from django.contrib.auth.decorators import login_required from django.contrib.auth.models import Group from django.forms.models import inlineformset_factory from django.utils import timezone +from django.core.exceptions import MultipleObjectsReturned import pytz from taggit.models import Tag from itertools import chain @@ -469,13 +470,14 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): # Add the answer submitted, regardless of it being correct or not. if current_question.type == 'mcq': user_answer = request.POST.get('answer') - elif current_question.type == 'integer': try: user_answer = int(request.POST.get('answer')) except ValueError: msg = ["Please enter an Integer Value"] return show_question(request, current_question, paper, msg) + elif current_question.type == 'string': + user_answer = str(request.POST.get('answer')) elif current_question.type == 'mcc': user_answer = request.POST.getlist('answer') @@ -504,9 +506,13 @@ def check(request, q_id, attempt_num=None, questionpaper_id=None): # If we were not skipped, we were asked to check. For any non-mcq # questions, we obtain the results via XML-RPC with the code executed # safely in a separate process (the code_server.py) running as nobody. - json_data = current_question.consolidate_answer_data(user_answer) \ - if current_question.type == 'code' else None - result = paper.validate_answer(user_answer, current_question, json_data) + try: + json_data = current_question.consolidate_answer_data(user_answer) \ + if current_question.type == 'code' else None + result = paper.validate_answer(user_answer, current_question, json_data) + except MultipleObjectsReturned: + msg = ["Multiple objects returned. Contact admin."] + return show_question(request, current_question, paper, msg) if result.get('success'): new_answer.marks = (current_question.points * result['weight'] / current_question.get_maximum_test_case_weight()) \ |