summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Quiz_instructions.txt18
-rw-r--r--yaksh/bash_code_evaluator.py4
-rw-r--r--yaksh/bash_stdio_evaluator.py2
-rw-r--r--yaksh/cpp_code_evaluator.py2
-rw-r--r--yaksh/cpp_stdio_evaluator.py2
-rw-r--r--yaksh/forms.py53
-rw-r--r--yaksh/grader.py6
-rw-r--r--yaksh/java_code_evaluator.py2
-rw-r--r--yaksh/java_stdio_evaluator.py2
-rw-r--r--yaksh/management/commands/add_group.py11
-rw-r--r--yaksh/models.py6
-rw-r--r--yaksh/python_assertion_evaluator.py2
-rw-r--r--yaksh/scilab_code_evaluator.py6
-rw-r--r--yaksh/templates/yaksh/grade_user.html2
-rw-r--r--yaksh/templates/yaksh/monitor.html9
-rw-r--r--yaksh/templates/yaksh/question.html4
-rw-r--r--yaksh/templates/yaksh/user_data.html2
-rw-r--r--yaksh/templates/yaksh/view_answerpaper.html2
-rw-r--r--yaksh/templatetags/custom_filters.py10
-rw-r--r--yaksh/test_views.py11
20 files changed, 100 insertions, 56 deletions
diff --git a/Quiz_instructions.txt b/Quiz_instructions.txt
deleted file mode 100644
index 34e010f..0000000
--- a/Quiz_instructions.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-<p>
-This examination system has been developed with the intention of making you
-learn programming and be assessed in an interactive and fun manner.
-You will be presented with a series of programming questions and problems that
-you will answer online and get immediate feedback for.
-</p>
-<p> Here are some important instructions and rules that you should understand carefully.</p>
-<ul>
-<li>For any programming questions, you can submit solutions as many times as you want without a penalty. You may skip questions and solve them later.
-</li>
-<li> You <strong>may</strong> use your computer's Python/IPython shell or an editor to solve the problem and cut/paste the solution to the web interface.
-</li>
-<li> <strong>You are <strong>not allowed</strong> to use any internet resources, i.e. no google etc.</strong> </li>
-<li> Do not copy or share the questions or answers with anyone until the exam is complete <strong>for everyone</strong>.</li>
-<li> <strong>All</strong> your attempts at the questions are logged. Do not try to outsmart and break the testing system. If you do, we know who you are and we will expel you from the course. You have been warned.
-</li>
-</ul>
-<p> We hope you enjoy taking this exam !!!</p>
diff --git a/yaksh/bash_code_evaluator.py b/yaksh/bash_code_evaluator.py
index 9da404a..a4f1389 100644
--- a/yaksh/bash_code_evaluator.py
+++ b/yaksh/bash_code_evaluator.py
@@ -112,7 +112,7 @@ class BashCodeEvaluator(BaseEvaluator):
)
proc, stdnt_stdout, stdnt_stderr = ret
if inst_stdout == stdnt_stdout:
- mark_fraction = float(self.weight) if self.partial_grading else 0.0
+ mark_fraction = 1.0 if self.partial_grading else 0.0
return True, None, mark_fraction
else:
err = "Error: expected %s, got %s" % (inst_stdout + inst_stderr,
@@ -155,7 +155,7 @@ class BashCodeEvaluator(BaseEvaluator):
proc, stdnt_stdout, stdnt_stderr = ret
valid_answer = inst_stdout == stdnt_stdout
if valid_answer and (num_lines == loop_count):
- mark_fraction = float(self.weight) if self.partial_grading else 0.0
+ mark_fraction = 1.0 if self.partial_grading else 0.0
return True, None, mark_fraction
else:
err = ("Error:expected"
diff --git a/yaksh/bash_stdio_evaluator.py b/yaksh/bash_stdio_evaluator.py
index 50ee0d6..334620d 100644
--- a/yaksh/bash_stdio_evaluator.py
+++ b/yaksh/bash_stdio_evaluator.py
@@ -55,5 +55,5 @@ class BashStdIOEvaluator(StdIOEvaluator):
self.expected_input,
self.expected_output
)
- mark_fraction = float(self.weight) if self.partial_grading and success else 0.0
+ mark_fraction = 1.0 if self.partial_grading and success else 0.0
return success, err, mark_fraction
diff --git a/yaksh/cpp_code_evaluator.py b/yaksh/cpp_code_evaluator.py
index d4e2253..4c8e938 100644
--- a/yaksh/cpp_code_evaluator.py
+++ b/yaksh/cpp_code_evaluator.py
@@ -139,7 +139,7 @@ class CppCodeEvaluator(BaseEvaluator):
proc, stdout, stderr = ret
if proc.returncode == 0:
success, err = True, None
- mark_fraction = float(self.weight) if self.partial_grading else 0.0
+ mark_fraction = 1.0 if self.partial_grading else 0.0
else:
err = "{0} \n {1}".format(stdout, stderr)
else:
diff --git a/yaksh/cpp_stdio_evaluator.py b/yaksh/cpp_stdio_evaluator.py
index d1dcd65..b302fa4 100644
--- a/yaksh/cpp_stdio_evaluator.py
+++ b/yaksh/cpp_stdio_evaluator.py
@@ -112,5 +112,5 @@ class CppStdIOEvaluator(StdIOEvaluator):
err = err + "\n" + e
except:
err = err + "\n" + stdnt_stderr
- mark_fraction = float(self.weight) if self.partial_grading and success else 0.0
+ mark_fraction = 1.0 if self.partial_grading and success else 0.0
return success, err, mark_fraction
diff --git a/yaksh/forms.py b/yaksh/forms.py
index 6fbaf5d..1d18d29 100644
--- a/yaksh/forms.py
+++ b/yaksh/forms.py
@@ -9,6 +9,7 @@ from taggit.managers import TaggableManager
from taggit.forms import TagField
from django.forms.models import inlineformset_factory
from django.db.models import Q
+from textwrap import dedent
try:
from string import letters
except ImportError:
@@ -165,6 +166,58 @@ class QuizForm(forms.ModelForm):
self.fields['prerequisite'].required = False
self.fields['course'] = forms.ModelChoiceField(
queryset=Course.objects.filter(id=course_id), empty_label=None)
+ self.fields["instructions"].initial = dedent("""\
+ <p>
+ This examination system has been
+ developed with the intention of
+ making you learn programming and
+ be assessed in an interactive and
+ fun manner.
+ You will be presented with a
+ series of programming questions
+ and problems that you will answer
+ online and get immediate
+ feedback for.
+ </p>
+ <p>
+ Here are some important
+ instructions and rules that you
+ should understand carefully.</p>
+ <ul>
+ <li>For any programming questions,
+ you can submit solutions as many
+ times as you want without a
+ penalty. You may skip questions
+ and solve them later.</li>
+ <li> You <strong>may</strong>
+ use your computer's Python/IPython
+ shell or an editor to solve the
+ problem and cut/paste the
+ solution to the web interface.
+ </li>
+ <li> <strong>You are not allowed
+ to use any internet resources,
+ i.e. no google etc.</strong>
+ </li>
+ <li> Do not copy or share the
+ questions or answers with anyone
+ until the exam is complete
+ <strong>for everyone</strong>.
+ </li>
+ <li> <strong>All</strong> your
+ attempts at the questions are
+ logged. Do not try to outsmart
+ and break the testing system.
+ If you do, we know who you are
+ and we will expel you from the
+ course. You have been warned.
+ </li>
+ </ul>
+ <p>
+ We hope you enjoy taking this
+ exam !!!
+ </p>
+ """)
class Meta:
model = Quiz
diff --git a/yaksh/grader.py b/yaksh/grader.py
index 0c057c2..086abb7 100644
--- a/yaksh/grader.py
+++ b/yaksh/grader.py
@@ -100,10 +100,10 @@ class Grader(object):
self.setup()
test_case_instances = self.get_evaluator_objects(kwargs)
with change_dir(self.in_dir):
- success, error, mark = self.safe_evaluate(test_case_instances)
+ success, error, weight = self.safe_evaluate(test_case_instances)
self.teardown()
- result = {'success': success, 'error': error, 'weight': mark}
+ result = {'success': success, 'error': error, 'weight': weight}
return result
# Private Protocol ##########
@@ -144,7 +144,7 @@ class Grader(object):
test_case_instance.compile_code()
test_case_success, err, mark_fraction = test_case_instance.check_code()
if test_case_success:
- weight += mark_fraction
+ weight += mark_fraction * test_case_instance.weight
else:
error.append(err)
test_case_success_status[idx] = test_case_success
diff --git a/yaksh/java_code_evaluator.py b/yaksh/java_code_evaluator.py
index df6abf5..e6dc628 100644
--- a/yaksh/java_code_evaluator.py
+++ b/yaksh/java_code_evaluator.py
@@ -147,7 +147,7 @@ class JavaCodeEvaluator(BaseEvaluator):
proc, stdout, stderr = ret
if proc.returncode == 0:
success, err = True, None
- mark_fraction = float(seelf.weight) if self.partial_grading else 0.0
+ mark_fraction = 1.0 if self.partial_grading else 0.0
else:
err = stdout + "\n" + stderr
else:
diff --git a/yaksh/java_stdio_evaluator.py b/yaksh/java_stdio_evaluator.py
index a854847..48f265d 100644
--- a/yaksh/java_stdio_evaluator.py
+++ b/yaksh/java_stdio_evaluator.py
@@ -85,5 +85,5 @@ class JavaStdIOEvaluator(StdIOEvaluator):
err = err + "\n" + e
except:
err = err + "\n" + stdnt_stderr
- mark_fraction = float(self.weight) if self.partial_grading and success else 0.0
+ mark_fraction = 1.0 if self.partial_grading and success else 0.0
return success, err, mark_fraction
diff --git a/yaksh/management/commands/add_group.py b/yaksh/management/commands/add_group.py
index 03ef103..624ff3c 100644
--- a/yaksh/management/commands/add_group.py
+++ b/yaksh/management/commands/add_group.py
@@ -15,7 +15,7 @@ class Command(BaseCommand):
help = 'Adds the moderator group'
def handle(self, *args, **options):
- app = 'yaksh'
+ app_label = 'yaksh'
group = Group(name='moderator')
try:
group.save()
@@ -23,11 +23,10 @@ class Command(BaseCommand):
raise CommandError("The group already exits")
else:
# Get the models for the given app
- content_types = ContentType.objects.filter(app_label=app)
+ content_types = ContentType.objects.filter(app_label=app_label)
# Get list of permissions for the models
- permission_list = Permission.objects.filter(content_type=content_types)
- for permission in permission_list:
- group.permissions.add(permission)
- group.save()
+ permission_list = Permission.objects.filter(content_type__in=content_types)
+ group.permissions.add(*permission_list)
+ group.save()
self.stdout.write('Moderator group added successfully')
diff --git a/yaksh/models.py b/yaksh/models.py
index b54e6a0..d65970b 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -81,10 +81,6 @@ def has_profile(user):
def get_upload_dir(instance, filename):
return "question_%s/%s" % (instance.question.id, filename)
-def get_quiz_instructions_info():
- file_path = os.path.join(os.getcwd(), "Quiz_instructions.txt")
- with open(file_path, 'r') as file:
- return file.read()
###############################################################################
class CourseManager(models.Manager):
@@ -546,7 +542,7 @@ class Quiz(models.Model):
is_trial = models.BooleanField(default=False)
instructions = models.TextField('Instructions for Students',
- default=get_quiz_instructions_info)
+ default=None, blank=True, null=True)
view_answerpaper = models.BooleanField('Allow student to view their answer\
paper', default=False)
diff --git a/yaksh/python_assertion_evaluator.py b/yaksh/python_assertion_evaluator.py
index 749a6ec..ae86c46 100644
--- a/yaksh/python_assertion_evaluator.py
+++ b/yaksh/python_assertion_evaluator.py
@@ -91,6 +91,6 @@ class PythonAssertionEvaluator(BaseEvaluator):
else:
success = True
err = None
- mark_fraction = float(self.weight) if self.partial_grading else 0.0
+ mark_fraction = 1.0 if self.partial_grading else 0.0
del tb
return success, err, mark_fraction
diff --git a/yaksh/scilab_code_evaluator.py b/yaksh/scilab_code_evaluator.py
index 7ffcd2b..f5c81b5 100644
--- a/yaksh/scilab_code_evaluator.py
+++ b/yaksh/scilab_code_evaluator.py
@@ -47,7 +47,7 @@ class ScilabCodeEvaluator(BaseEvaluator):
self._remove_scilab_exit(self.user_answer.lstrip())
success = False
- test_case_weight = 0.0
+ mark_fraction = 0.0
self.write_to_submit_code_file(self.submit_code_path, self.user_answer)
self.write_to_submit_code_file(self.test_code_path, self.test_case)
# Throw message if there are commmands that terminates scilab
@@ -75,13 +75,13 @@ class ScilabCodeEvaluator(BaseEvaluator):
stdout = self._strip_output(stdout)
if proc.returncode == 5:
success, err = True, None
- test_case_weight = float(self.weight) if self.partial_grading else 0.0
+ mark_fraction = 1.0 if self.partial_grading else 0.0
else:
err = add_err + stdout
else:
err = add_err + stderr
- return success, err, test_case_weight
+ return success, err, mark_fraction
def _remove_scilab_exit(self, string):
"""
diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html
index 6fb8187..ec8c244 100644
--- a/yaksh/templates/yaksh/grade_user.html
+++ b/yaksh/templates/yaksh/grade_user.html
@@ -130,7 +130,7 @@ Status : <b style="color: green;"> Passed </b><br/>
{% if question.type == "mcq" or question.type == "mcc" %}
<h5> <u>Choices:</u></h5>
{% for testcase in question.get_test_cases %}
- <br/><strong>{{ forloop.counter }}. {{ testcase.options }}</strong>
+ <br/><strong>{{ forloop.counter }}. {{ testcase.options|safe }}</strong>
{% endfor %}
{% else %}
<h5> <u>Test cases: </u></h5>
diff --git a/yaksh/templates/yaksh/monitor.html b/yaksh/templates/yaksh/monitor.html
index 7a3297b..0ad6401 100644
--- a/yaksh/templates/yaksh/monitor.html
+++ b/yaksh/templates/yaksh/monitor.html
@@ -1,4 +1,5 @@
{% extends "manage.html" %}
+{% load custom_filters %}
{% block pagetitle %} Quiz results {% endblock pagetitle %}
@@ -49,6 +50,14 @@ $(document).ready(function()
{% if papers %}
<p>Number of papers: {{ papers|length }} </p>
+{% completed papers as completed_papers %}
+ {# template tag used to get the count of completed papers #}
+ <p>Papers completed: <b> {{ completed_papers }} </b></p>
+
+{% inprogress papers as inprogress_papers %}
+ {# template tag used to get the count of inprogress papers #}
+ <p>Papers in progress:<b> {{ inprogress_papers }} </b></p>
+
<p><a href="{{URL_ROOT}}/exam/manage/statistics/question/{{papers.0.question_paper.id}}">Question Statisitics</a></p>
<p><a href="{{URL_ROOT}}/exam/manage/monitor/download_csv/{{papers.0.question_paper.id}}">Download CSV</a></p>
<table id="result-table" class="tablesorter table">
diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html
index fe696fe..7cbca57 100644
--- a/yaksh/templates/yaksh/question.html
+++ b/yaksh/templates/yaksh/question.html
@@ -173,7 +173,7 @@ function call_skip(url)
</p>
{% endif %}
{% for test_case in test_cases %}
- <input name="answer" type="radio" value="{{ test_case.options }}" />{{ test_case.options }} <br/>
+ <input name="answer" type="radio" value="{{ test_case.options }}" />{{ test_case.options|safe }} <br/>
{% endfor %}
{% endif %}
{% if question.type == "mcc" %}
@@ -189,7 +189,7 @@ function call_skip(url)
</p>
{% endif %}
{% for test_case in test_cases %}
- <input name="answer" type="checkbox" value="{{ test_case.options }}"> {{ test_case.options }}
+ <input name="answer" type="checkbox" value="{{ test_case.options }}"> {{ test_case.options|safe }}
<br>
{% endfor %}
{% endif %}
diff --git a/yaksh/templates/yaksh/user_data.html b/yaksh/templates/yaksh/user_data.html
index 856433d..9c11dd9 100644
--- a/yaksh/templates/yaksh/user_data.html
+++ b/yaksh/templates/yaksh/user_data.html
@@ -66,7 +66,7 @@ User IP address: {{ paper.user_ip }}
{% if question.type == "mcq" or question.type == "mcc" %}
<h5> <u>Choices:</u></h5>
{% for testcase in question.get_test_cases %}
- <br/><strong>{{ forloop.counter }}. {{ testcase.options }}</strong>
+ <br/><strong>{{ forloop.counter }}. {{ testcase.options|safe }}</strong>
{% endfor %}
{% else %}
<h5> <u>Test cases: </u></h5>
diff --git a/yaksh/templates/yaksh/view_answerpaper.html b/yaksh/templates/yaksh/view_answerpaper.html
index 9dfbda0..8dec5b3 100644
--- a/yaksh/templates/yaksh/view_answerpaper.html
+++ b/yaksh/templates/yaksh/view_answerpaper.html
@@ -42,7 +42,7 @@
{% if question.type == "mcq" or question.type == "mcc" %}
<h5> <u>Choices:</u></h5>
{% for testcase in question.get_test_cases %}
- <br/><strong>{{ forloop.counter }}. {{ testcase.options }}</strong>
+ <br/><strong>{{ forloop.counter }}. {{ testcase.options|safe }}</strong>
{% endfor %}
{%endif%}
diff --git a/yaksh/templatetags/custom_filters.py b/yaksh/templatetags/custom_filters.py
index 9d7b939..f610cc6 100644
--- a/yaksh/templatetags/custom_filters.py
+++ b/yaksh/templatetags/custom_filters.py
@@ -10,4 +10,12 @@ def escape_quotes(value):
escape_single_quotes = value.replace("'", "\\'")
escape_single_and_double_quotes = escape_single_quotes.replace('"', '\\"')
- return escape_single_and_double_quotes \ No newline at end of file
+ return escape_single_and_double_quotes
+
+@register.assignment_tag(name="completed")
+def completed(answerpaper):
+ return answerpaper.filter(status="completed").count()
+
+@register.assignment_tag(name="inprogress")
+def inprogress(answerpaper):
+ return answerpaper.filter(status="inprogress").count()
diff --git a/yaksh/test_views.py b/yaksh/test_views.py
index 2419591..e052441 100644
--- a/yaksh/test_views.py
+++ b/yaksh/test_views.py
@@ -146,9 +146,6 @@ class TestAddQuiz(TestCase):
self.mod_group = Group.objects.create(name='moderator')
tzone = pytz.timezone('UTC')
- file_path = os.path.join(os.getcwd(), "Quiz_instructions.txt")
- with open(file_path, 'r') as file:
- self.file_data = file.read()
# Create Moderator with profile
self.user_plaintext_pass = 'demo'
self.user = User.objects.create_user(
@@ -187,7 +184,7 @@ class TestAddQuiz(TestCase):
self.pre_req_quiz = Quiz.objects.create(
start_date_time=datetime(2014, 2, 1, 5, 8, 15, 0, tzone),
end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone),
- duration=30, active=True, instructions=self.file_data,
+ duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='pre requisite quiz', pass_criteria=40,
language='Python', prerequisite=None,
@@ -197,7 +194,7 @@ class TestAddQuiz(TestCase):
self.quiz = Quiz.objects.create(
start_date_time=datetime(2014, 10, 9, 10, 8, 15, 0, tzone),
end_date_time=datetime(2015, 10, 9, 10, 8, 15, 0, tzone),
- duration=30, active=True, instructions=self.file_data,
+ duration=30, active=True, instructions="Demo Instructions",
attempts_allowed=-1, time_between_attempts=0,
description='demo quiz', pass_criteria=40,
language='Python', prerequisite=self.pre_req_quiz,
@@ -274,7 +271,7 @@ class TestAddQuiz(TestCase):
'description': 'updated demo quiz',
'pass_criteria': 40,
'language': 'java',
- 'instructions': self.file_data,
+ 'instructions': "Demo Instructions",
'prerequisite': self.pre_req_quiz.id,
'course': self.course.id
}
@@ -321,7 +318,7 @@ class TestAddQuiz(TestCase):
'description': 'new demo quiz',
'pass_criteria': 50,
'language': 'python',
- 'instructions': self.file_data,
+ 'instructions': "Demo Instructions",
'prerequisite': self.pre_req_quiz.id,
'course': self.course.id
}