summaryrefslogtreecommitdiff
path: root/testapp/exam
diff options
context:
space:
mode:
authorprathamesh2013-05-06 11:56:16 +0530
committerprathamesh2013-05-08 12:21:37 +0530
commit6667efae7acb86f60b0ebd4dabb959bed759bc16 (patch)
treea0d7a22670e91427e82cd6037c8bd29155d38b51 /testapp/exam
parent8b6ac259503323bc3d8333382d3769e5d10f162a (diff)
downloadonline_test-6667efae7acb86f60b0ebd4dabb959bed759bc16.tar.gz
online_test-6667efae7acb86f60b0ebd4dabb959bed759bc16.tar.bz2
online_test-6667efae7acb86f60b0ebd4dabb959bed759bc16.zip
Function to check C-C++ code
Added a function which compiles C and C++ code submitted by the student. 1) If compilation is successful, then the submitted code is tested using test-cases. 2) To test the function written by the student, a C++ file calls the function and passes the argument to the function. Then the function checks for the expected return value. 3) If the return value is as expected, then a different set of arguments are passed, and the output is checked. 4) If for all set of arguments the output is as expected then the student code is graded correct else the error is displayed to the student. Changed the way the code is graded. Previously, the algorithm checked the student code for all test-cases. If all the test-cases were satisfied, the last-line of the program was reached and printed "All Correct". So at any point if a test-case fails, the last line is not reached as the program was terminate. When the string "All Correct" was found in the output, the code was graded as RIGHT else WRONG. This is not a proper way for code checking, as the student code *may* contain a print statement with the string('All Correct'), and thus can get program RIGHT even though it is WRONG. So now the student code is tested as follows: 1) The code checks for all test-cases. 2) If all test-cases are satisfied then it returns 0. 3) If any one of the test-case fails, the program is terminated and will return 1. 4) Now depending on the return status(0 or 1), it will grade the code. a) if 0 then RIGHT b) if 1 then WRONG This ensures, no manipulation from student side.
Diffstat (limited to 'testapp/exam')
-rw-r--r--testapp/exam/forms.py33
-rw-r--r--testapp/exam/models.py5
-rw-r--r--testapp/exam/views.py2
-rw-r--r--testapp/exam/xmlrpc_clients.py20
4 files changed, 34 insertions, 26 deletions
diff --git a/testapp/exam/forms.py b/testapp/exam/forms.py
index 7bbf601..1b60a71 100644
--- a/testapp/exam/forms.py
+++ b/testapp/exam/forms.py
@@ -1,5 +1,5 @@
from django import forms
-from exam.models import Profile,Quiz,Question
+from exam.models import Profile, Quiz, Question
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
@@ -13,14 +13,17 @@ from string import letters, punctuation, digits
import datetime
QUESTION_TYPE_CHOICES = (
- ("python", "Python"),
- ("bash", "Bash"),
- ("mcq", "MCQ"),
- )
+ ("python", "Python"),
+ ("bash", "Bash"),
+ ("mcq", "MCQ"),
+ ("C", "C Language"),
+ ("C++", "C++ Language"),
+ )
UNAME_CHARS = letters + "._" + digits
PWD_CHARS = letters + punctuation + digits
+
class UserRegisterForm(forms.Form):
"""A Class to create new form for User's Registration.
It has the various fields and functions required to register
@@ -28,7 +31,7 @@ class UserRegisterForm(forms.Form):
username = forms.CharField\
(max_length=30, help_text='Letters, digits,\
- period and underscores only.')
+ period and underscores only.')
email = forms.EmailField()
password = forms.CharField(max_length=30, widget=forms.PasswordInput())
confirm_password = forms.CharField\
@@ -114,20 +117,20 @@ class UserLoginForm(forms.Form):
class QuizForm(forms.Form):
"""Creates a form to add or edit a Quiz.
It has the related fields and functions required."""
-
+
start_date = forms.DateField(initial=datetime.date.today)
duration = forms.IntegerField()
- active = forms.BooleanField(required = False)
+ active = forms.BooleanField(required=False)
tags = TagField(widget=TagAutocomplete())
description = forms.CharField(max_length=256, widget=forms.Textarea\
- (attrs={'cols':20,'rows':1}))
+ (attrs={'cols': 20, 'rows': 1}))
def save(self):
start_date = self.cleaned_data["start_date"]
duration = self.cleaned_data["duration"]
active = self.cleaned_data['active']
description = self.cleaned_data["description"]
-
+
new_quiz = Quiz()
new_quiz.start_date = start_date
new_quiz.duration = duration
@@ -136,7 +139,7 @@ class QuizForm(forms.Form):
new_quiz.save()
class QuestionForm(forms.Form):
- """Creates a form to add or edit a Question.
+ """Creates a form to add or edit a Question.
It has the related fields and functions required."""
summary = forms.CharField(widget=forms.Textarea\
@@ -147,13 +150,13 @@ class QuestionForm(forms.Form):
test = forms.CharField(widget=forms.Textarea\
(attrs={'cols': 40, 'rows': 1}))
options = forms.CharField(widget=forms.Textarea\
- (attrs={'cols': 40, 'rows': 1}),required=False)
+ (attrs={'cols': 40, 'rows': 1}), required=False)
type = forms.CharField(max_length=8, widget=forms.Select\
- (choices=QUESTION_TYPE_CHOICES))
+ (choices=QUESTION_TYPE_CHOICES))
active = forms.BooleanField(required=False)
- tags = TagField(widget=TagAutocomplete(),required=False)
+ tags = TagField(widget=TagAutocomplete(), required=False)
snippet = forms.CharField(widget=forms.Textarea\
- (attrs={'cols': 40, 'rows': 1}),required=False)
+ (attrs={'cols': 40, 'rows': 1}), required=False)
def save(self):
summary = self.cleaned_data["summary"]
diff --git a/testapp/exam/models.py b/testapp/exam/models.py
index 00d32e4..fac01ec 100644
--- a/testapp/exam/models.py
+++ b/testapp/exam/models.py
@@ -18,7 +18,9 @@ QUESTION_TYPE_CHOICES = (
("python", "Python"),
("bash", "Bash"),
("mcq", "MultipleChoice"),
- )
+ ("C", "C Language"),
+ ("C++", "C++ Language"),
+ )
################################################################################
class Question(models.Model):
@@ -233,4 +235,3 @@ the next."""
def __unicode__(self):
u = self.user
return u'Question paper for {0} {1}'.format(u.first_name, u.last_name)
-
diff --git a/testapp/exam/views.py b/testapp/exam/views.py
index 5a5f5fe..1d5d6f6 100644
--- a/testapp/exam/views.py
+++ b/testapp/exam/views.py
@@ -476,7 +476,7 @@ def automatic_questionpaper(request, questionpaper_id=None):
context = {'data': {'questions': fetched_questions,
'tags': tags,
'msg': msg}}
- return my_render_to_response\(
+ return my_render_to_response(
'exam/automatic_questionpaper.html', context,
context_instance=RequestContext(request))
else:
diff --git a/testapp/exam/xmlrpc_clients.py b/testapp/exam/xmlrpc_clients.py
index 817e37d..b846212 100644
--- a/testapp/exam/xmlrpc_clients.py
+++ b/testapp/exam/xmlrpc_clients.py
@@ -9,19 +9,24 @@ from settings import SERVER_PORTS, SERVER_POOL_PORT
class ConnectionError(Exception):
pass
-################################################################################
+###############################################################################
# `CodeServerProxy` class.
-################################################################################
+###############################################################################
+
+
class CodeServerProxy(object):
"""A class that manages accesing the farm of Python servers and making
calls to them such that no one XMLRPC server is overloaded.
"""
def __init__(self):
- pool_url = 'http://localhost:%d'%(SERVER_POOL_PORT)
+ pool_url = 'http://localhost:%d' % (SERVER_POOL_PORT)
self.pool_server = ServerProxy(pool_url)
self.methods = {"python": 'run_python_code',
- "bash": 'run_bash_code'}
-
+ "bash": 'run_bash_code',
+ "C": "run_c_code",
+ "C++": "run_cplus_code",
+ }
+
def run_code(self, answer, test_code, user_dir, language):
"""Tests given code (`answer`) with the `test_code` supplied. If the
optional `in_dir` keyword argument is supplied it changes the directory
@@ -68,11 +73,10 @@ class CodeServerProxy(object):
else:
done = True
if not done:
- raise ConnectionError("Couldn't connect to a server!")
- proxy = ServerProxy('http://localhost:%d'%port)
+ raise ConnectionError("Couldn't connect to a server!")
+ proxy = ServerProxy('http://localhost:%d' % port)
return proxy
# views.py calls this Python server which forwards the request to one
# of the running servers.
code_server = CodeServerProxy()
-