summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtestapp/c_cpp_files/main_array_check.cpp8
-rwxr-xr-xtestapp/c_cpp_files/main_array_check_all.cpp8
-rwxr-xr-xtestapp/c_cpp_files/main_blackJack.cpp18
-rwxr-xr-xtestapp/c_cpp_files/main_check_digit.cpp4
-rwxr-xr-xtestapp/c_cpp_files/main_count667.cpp18
-rwxr-xr-xtestapp/c_cpp_files/main_count7.cpp18
-rwxr-xr-xtestapp/c_cpp_files/main_lessThan9.cpp8
-rwxr-xr-xtestapp/c_cpp_files/main_mean.cpp10
-rwxr-xr-xtestapp/c_cpp_files/main_roundTo10.cpp19
-rwxr-xr-xtestapp/c_cpp_files/main_specialSum.cpp19
-rwxr-xr-xtestapp/c_cpp_files/main_within.cpp14
-rwxr-xr-xtestapp/code_server.py131
-rw-r--r--testapp/docs/sample_questions.py27
-rw-r--r--testapp/exam/forms.py16
-rw-r--r--testapp/exam/management/commands/load_exam.py4
-rw-r--r--testapp/exam/models.py56
-rw-r--r--testapp/exam/views.py230
-rw-r--r--testapp/exam/xmlrpc_clients.py1
-rw-r--r--testapp/production.py4
-rw-r--r--testapp/scilab_files/test_add.sce29
-rw-r--r--testapp/settings.py22
-rw-r--r--testapp/static/exam/js/question.js2
-rw-r--r--testapp/templates/exam/automatic_questionpaper.html2
-rw-r--r--testapp/test_server.py73
24 files changed, 481 insertions, 260 deletions
diff --git a/testapp/c_cpp_files/main_array_check.cpp b/testapp/c_cpp_files/main_array_check.cpp
index 38b9004..ea34fdd 100755
--- a/testapp/c_cpp_files/main_array_check.cpp
+++ b/testapp/c_cpp_files/main_array_check.cpp
@@ -21,13 +21,13 @@ void check(T expect,T result)
int main(void)
{
bool result;
- int a[] = {1,2,3,0,0};
+ int a[] = {1,2,3,0,0};
result = array_check(a, 2);
- printf("Input submitted to the function: {1, 2, 3, 0, 0} and index 2");
+ printf("Input submitted to the function: {1, 2, 3, 0, 0} and index 2");
check(false, result);
int b[] = {1,2,3,4,5};
- result = array_check(b, 3);
- printf("Input submitted to the function: {1, 2, 3, 4, 5} and index 3");
+ result = array_check(b, 3);
+ printf("Input submitted to the function: {1, 2, 3, 4, 5} and index 3");
check(true, result);
printf("All Correct\n");
return 0;
diff --git a/testapp/c_cpp_files/main_array_check_all.cpp b/testapp/c_cpp_files/main_array_check_all.cpp
index fc740a9..140578e 100755
--- a/testapp/c_cpp_files/main_array_check_all.cpp
+++ b/testapp/c_cpp_files/main_array_check_all.cpp
@@ -21,13 +21,13 @@ void check(T expect,T result)
int main(void)
{
bool result;
- int a[] = {1,2,3,2,8};
+ int a[] = {1,2,3,2,8};
result = array_check_all(a);
- printf("Input submitted to the function: {1, 2, 3, 2, 8}");
+ printf("Input submitted to the function: {1, 2, 3, 2, 8}");
check(false, result);
int b[] = {4,2,32,4,56};
- result = array_check_all(b);
- printf("Input submitted to the function: {4, 2, 32, 4, 56}");
+ result = array_check_all(b);
+ printf("Input submitted to the function: {4, 2, 32, 4, 56}");
check(true, result);
printf("All Correct\n");
return 0;
diff --git a/testapp/c_cpp_files/main_blackJack.cpp b/testapp/c_cpp_files/main_blackJack.cpp
index e4f0963..cc54e78 100755
--- a/testapp/c_cpp_files/main_blackJack.cpp
+++ b/testapp/c_cpp_files/main_blackJack.cpp
@@ -22,20 +22,20 @@ int main(void)
{
int result;
result = blackJack(11, 12);
- printf("Input submitted to the function: 11, 12");
+ printf("Input submitted to the function: 11, 12");
check(12, result);
result = blackJack(15, 19);
- printf("Input submitted to the function: 15, 19");
+ printf("Input submitted to the function: 15, 19");
check(19, result);
result = blackJack(10, 21);
- printf("Input submitted to the function: 10, 21");
+ printf("Input submitted to the function: 10, 21");
check(21, result);
- result = blackJack(31, 22);
- printf("Input submitted to the function: 31, 22");
- check(0, result);
- result = blackJack(91, 61);
- printf("Input submitted to the function: 91, 61");
- check(0, result);
+ result = blackJack(31, 22);
+ printf("Input submitted to the function: 31, 22");
+ check(0, result);
+ result = blackJack(91, 61);
+ printf("Input submitted to the function: 91, 61");
+ check(0, result);
printf("All Correct\n");
return 0;
}
diff --git a/testapp/c_cpp_files/main_check_digit.cpp b/testapp/c_cpp_files/main_check_digit.cpp
index 80a92aa..d3bf3d6 100755
--- a/testapp/c_cpp_files/main_check_digit.cpp
+++ b/testapp/c_cpp_files/main_check_digit.cpp
@@ -22,10 +22,10 @@ int main(void)
{
bool result;
result = check_digit(12, 23);
- printf("Input submitted to the function: 12, 23");
+ printf("Input submitted to the function: 12, 23");
check(true, result);
result = check_digit(22, 11);
- printf("Input submitted to the function: 121");
+ printf("Input submitted to the function: 121");
check(false, result);
printf("All Correct\n");
return 0;
diff --git a/testapp/c_cpp_files/main_count667.cpp b/testapp/c_cpp_files/main_count667.cpp
index dc33ede..f146e8c 100755
--- a/testapp/c_cpp_files/main_count667.cpp
+++ b/testapp/c_cpp_files/main_count667.cpp
@@ -21,22 +21,22 @@ void check(T expect, T result)
int main(void)
{
int result;
- int arr[5] = {2,6,4,5,6};
+ int arr[5] = {2,6,4,5,6};
result = count667(arr);
- printf("Input submitted to the function: [2, 6, 4, 5,6]");
+ printf("Input submitted to the function: [2, 6, 4, 5,6]");
check(0, result);
- int arr2[5] = {6,6,2,17,9};
+ int arr2[5] = {6,6,2,17,9};
result = count667(arr2);
- printf("Input submitted to the function: [6, 6, 2, 17, 9]");
+ printf("Input submitted to the function: [6, 6, 2, 17, 9]");
check(1, result);
- int arr3[5] = {6,6,6,7,1};
+ int arr3[5] = {6,6,6,7,1};
result = count667(arr3);
- printf("Input submitted to the function: [6, 6, 7, 2, 1]");
+ printf("Input submitted to the function: [6, 6, 7, 2, 1]");
check(3, result);
- int arr4[5] = {6,7,7,6,6};
+ int arr4[5] = {6,7,7,6,6};
result = count667(arr4);
- printf("Input submitted to the function: [6, 7, 7, 6, 6]");
+ printf("Input submitted to the function: [6, 7, 7, 6, 6]");
check(2, result);
- printf("All Correct\n");
+ printf("All Correct\n");
return 0;
}
diff --git a/testapp/c_cpp_files/main_count7.cpp b/testapp/c_cpp_files/main_count7.cpp
index 92971fd..982e930 100755
--- a/testapp/c_cpp_files/main_count7.cpp
+++ b/testapp/c_cpp_files/main_count7.cpp
@@ -21,22 +21,22 @@ void check(T expect, T result)
int main(void)
{
int result;
- int arr[4] = {2,3,4,5};
+ int arr[4] = {2,3,4,5};
result = count7(arr);
- printf("Input submitted to the function: [2, 3, 4, 5]");
+ printf("Input submitted to the function: [2, 3, 4, 5]");
check(0, result);
- int arr2[4] = {1,2,17,9};
+ int arr2[4] = {1,2,17,9};
result = count7(arr2);
- printf("Input submitted to the function: [1, 2, 17, 9]");
+ printf("Input submitted to the function: [1, 2, 17, 9]");
check(0, result);
- int arr3[4] = {7,9,2,1};
+ int arr3[4] = {7,9,2,1};
result = count7(arr3);
- printf("Input submitted to the function: [7, 9, 2, 1]");
+ printf("Input submitted to the function: [7, 9, 2, 1]");
check(1, result);
- int arr4[4] = {1,7,7,7};
+ int arr4[4] = {1,7,7,7};
result = count7(arr4);
- printf("Input submitted to the function: [1, 7, 7, 7]");
+ printf("Input submitted to the function: [1, 7, 7, 7]");
check(3, result);
- printf("All Correct\n");
+ printf("All Correct\n");
return 0;
}
diff --git a/testapp/c_cpp_files/main_lessThan9.cpp b/testapp/c_cpp_files/main_lessThan9.cpp
index 1a89731..722b4bb 100755
--- a/testapp/c_cpp_files/main_lessThan9.cpp
+++ b/testapp/c_cpp_files/main_lessThan9.cpp
@@ -22,16 +22,16 @@ int main(void)
{
bool result;
result = lessThan9(10);
- printf("Input submitted to the function: 10");
+ printf("Input submitted to the function: 10");
check(false, result);
result = lessThan9(17);
- printf("Input submitted to the function: 17");
+ printf("Input submitted to the function: 17");
check(true, result);
result = lessThan9(16);
- printf("Input submitted to the function: 16");
+ printf("Input submitted to the function: 16");
check(true, result);
result = lessThan9(15);
- printf("Input submitted to the function: 15");
+ printf("Input submitted to the function: 15");
check(false, result);
printf("All Correct\n");
return 0;
diff --git a/testapp/c_cpp_files/main_mean.cpp b/testapp/c_cpp_files/main_mean.cpp
index f23db68..21a4b1a 100755
--- a/testapp/c_cpp_files/main_mean.cpp
+++ b/testapp/c_cpp_files/main_mean.cpp
@@ -21,17 +21,17 @@ void check(T expect, T result)
int main(void)
{
bool result;
- result = mean(11, 11, 11);
- printf("Input submitted to the function: 11, 121, 11");
+ result = mean(11, 11, 11);
+ printf("Input submitted to the function: 11, 121, 11");
check(true, result);
result = mean(16, 12, 9);
- printf("Input submitted to the function: 16, 144, 9");
+ printf("Input submitted to the function: 16, 144, 9");
check(true, result);
result = mean(19, 221, 9);
- printf("Input submitted to the function: 19, 221, 9");
+ printf("Input submitted to the function: 19, 221, 9");
check(false, result);
result = mean(34, 12, 3);
- printf("Input submitted to the function: 11, 121, 11");
+ printf("Input submitted to the function: 11, 121, 11");
check(false, result);
printf("All Correct\n");
return 0;
diff --git a/testapp/c_cpp_files/main_roundTo10.cpp b/testapp/c_cpp_files/main_roundTo10.cpp
index 0a1284e..12c961d 100755
--- a/testapp/c_cpp_files/main_roundTo10.cpp
+++ b/testapp/c_cpp_files/main_roundTo10.cpp
@@ -22,21 +22,20 @@ int main(void)
{
int result;
result = roundTo10(10, 22, 39);
- printf("Input submitted to the function: 10, 22, 39");
+ printf("Input submitted to the function: 10, 22, 39");
check(70, result);
result = roundTo10(45, 42, 39);
- printf("Input submitted to the function: 45, 42, 39");
+ printf("Input submitted to the function: 45, 42, 39");
check(130, result);
- result = roundTo10(7, 3, 9);
- printf("Input submitted to the function: 7, 3, 9");
+ result = roundTo10(7, 3, 9);
+ printf("Input submitted to the function: 7, 3, 9");
check(20, result);
- result = roundTo10(1, 2, 3);
- printf("Input submitted to the function: 1, 2, 3");
+ result = roundTo10(1, 2, 3);
+ printf("Input submitted to the function: 1, 2, 3");
check(0, result);
- result = roundTo10(30, 40, 50);
- printf("Input submitted to the function: 30, 40, 50");
+ result = roundTo10(30, 40, 50);
+ printf("Input submitted to the function: 30, 40, 50");
check(120, result);
-
- printf("All Correct\n");
+ printf("All Correct\n");
return 0;
}
diff --git a/testapp/c_cpp_files/main_specialSum.cpp b/testapp/c_cpp_files/main_specialSum.cpp
index 5d0fcae..d614536 100755
--- a/testapp/c_cpp_files/main_specialSum.cpp
+++ b/testapp/c_cpp_files/main_specialSum.cpp
@@ -22,21 +22,20 @@ int main(void)
{
int result;
result = specialSum(10, 2, 9);
- printf("Input submitted to the function: 10, 2, 9");
+ printf("Input submitted to the function: 10, 2, 9");
check(21, result);
result = specialSum(1, 21, 9);
- printf("Input submitted to the function: 1, 21, 9");
+ printf("Input submitted to the function: 1, 21, 9");
check(1, result);
- result = specialSum(21, 2, 3);
- printf("Input submitted to the function: 21, 2, 3");
+ result = specialSum(21, 2, 3);
+ printf("Input submitted to the function: 21, 2, 3");
check(0, result);
- result = specialSum(10, 2, 21);
- printf("Input submitted to the function: 10, 2, 21");
+ result = specialSum(10, 2, 21);
+ printf("Input submitted to the function: 10, 2, 21");
check(12, result);
- result = specialSum(10, 2, 6);
- printf("Input submitted to the function: 10, 2, 6");
+ result = specialSum(10, 2, 6);
+ printf("Input submitted to the function: 10, 2, 6");
check(18, result);
-
- printf("All Correct\n");
+ printf("All Correct\n");
return 0;
}
diff --git a/testapp/c_cpp_files/main_within.cpp b/testapp/c_cpp_files/main_within.cpp
index d83c50d..50f9ad0 100755
--- a/testapp/c_cpp_files/main_within.cpp
+++ b/testapp/c_cpp_files/main_within.cpp
@@ -22,16 +22,16 @@ int main(void)
{
bool result;
result = within(12, 3, 20);
- printf("Input submitted to the function: 12, 3, 20");
+ printf("Input submitted to the function: 12, 3, 20");
check(true, result);
- result = within(12, 13, 20);
- printf("Input submitted to the function: 12, 13, 20");
+ result = within(12, 13, 20);
+ printf("Input submitted to the function: 12, 13, 20");
check(false, result);
- result = within(29, 13, 120);
- printf("Input submitted to the function: 29, 13, 120");
+ result = within(29, 13, 120);
+ printf("Input submitted to the function: 29, 13, 120");
check(true, result);
- result = within(12, 12, 20);
- printf("Input submitted to the function: 12, 3, 20");
+ result = within(12, 12, 20);
+ printf("Input submitted to the function: 12, 3, 20");
check(false, result);
printf("All Correct\n");
return 0;
diff --git a/testapp/code_server.py b/testapp/code_server.py
index 8b3f8f1..792197d 100755
--- a/testapp/code_server.py
+++ b/testapp/code_server.py
@@ -28,7 +28,7 @@ from os.path import isdir, dirname, abspath, join, isfile
import signal
from multiprocessing import Process, Queue
import subprocess
-
+import re
# Local imports.
from settings import SERVER_PORTS, SERVER_TIMEOUT, SERVER_POOL_PORT
@@ -370,7 +370,6 @@ class CodeServer(object):
raise
return proc_compile, err
-
def _check_c_cpp_code(self, ref_code_path, submit_code_path):
""" Function validates student code using instructor code as
reference.The first argument ref_code_path, is the path to
@@ -608,7 +607,7 @@ class CodeServer(object):
student_directory,
student_directory)
ret = self._compile_command(compile_main)
- proc, main_err = ret
+ proc, main_err = ret
main_err = self._remove_null_substitute_char(main_err)
if main_err == '':
@@ -659,6 +658,132 @@ class CodeServer(object):
if ord(c) is not 26 and ord(c) is not 0:
stripped = stripped + c
return ''.join(stripped)
+
+ def run_scilab_code(self, answer, test_code, in_dir=None):
+ """Tests given Scilab function (`answer`) with the `test_code`
+ supplied. If the optional `in_dir` keyword argument is supplied
+ it changes the directory to that directory (it does not change
+ it back to the original when done). This function also timesout
+ when the function takes more than SERVER_TIMEOUT seconds to run
+ to prevent runaway code.
+
+ The testcode is a path to the reference code.
+ The reference code will call the function submitted by the student.
+ The reference code will check for the expected output.
+
+ If the path's start with a "/" then we assume they are absolute paths.
+ If not, we assume they are relative paths w.r.t. the location of this
+ code_server script.
+
+ Returns
+ -------
+
+ A tuple: (success, error message).
+
+ """
+ if in_dir is not None and isdir(in_dir):
+ os.chdir(in_dir)
+
+ # Removes all the commands that terminates scilab
+ answer,i = self._remove_scilab_exit(answer.lstrip())
+
+ # Throw message if there are commmands that terminates scilab
+ add_err=""
+ if i > 0:
+ add_err = "Please do not use exit, quit and abort commands in your\
+ code.\n Otherwise your code will not be evaluated\
+ correctly.\n"
+
+ # The file extension should be .sci
+ submit_f = open('function.sci','w')
+ submit_f.write(answer)
+ submit_f.close()
+ submit_path = abspath(submit_f.name)
+
+ ref_path = test_code.strip()
+ if not ref_path.startswith('/'):
+ ref_path = join(MY_DIR, ref_path)
+
+ # Add a new signal handler for the execution of this code.
+ old_handler = signal.signal(signal.SIGALRM, timeout_handler)
+ signal.alarm(SERVER_TIMEOUT)
+
+ # Do whatever testing needed.
+ success = False
+ try:
+ cmd = 'printf "lines(0)\nexec(\'{0}\',2);\nquit();"'.format(ref_path)
+ cmd += ' | timeout 8 scilab-cli -nb'
+ ret = self._run_command(cmd,
+ shell=True,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ proc, stdout, stderr = ret
+
+ # Get only the error.
+ stderr = self._get_error(stdout)
+ if stderr is None:
+ # Clean output
+ stdout = self._strip_output(stdout)
+ if proc.returncode == 5:
+ success, err = True, "Correct answer"
+ else:
+ err = add_err + stdout
+ else:
+ err = add_err + stderr
+ except TimeoutException:
+ err = self.timeout_msg
+ except:
+ type, value = sys.exc_info()[:2]
+ err = "Error: {0}".format(repr(value))
+ finally:
+ # Set back any original signal handler.
+ signal.signal(signal.SIGALRM, old_handler)
+
+ # Delete the created file.
+ os.remove(submit_path)
+
+ # Cancel the signal if any, see signal.alarm documentation.
+ signal.alarm(0)
+
+ # Put us back into the server pool queue since we are free now.
+ self.queue.put(self.port)
+
+ return success, err
+
+ def _remove_scilab_exit(self, string):
+ """
+ Removes exit, quit and abort from the scilab code
+ """
+ new_string = ""
+ i=0
+ for line in string.splitlines():
+ new_line = re.sub(r"exit.*$","",line)
+ new_line = re.sub(r"quit.*$","",new_line)
+ new_line = re.sub(r"abort.*$","",new_line)
+ if line != new_line:
+ i=i+1
+ new_string = new_string +'\n'+ new_line
+ return new_string, i
+
+ def _get_error(self, string):
+ """
+ Fetches only the error from the string.
+ Returns None if no error.
+ """
+ obj = re.search("!.+\n.+",string);
+ if obj:
+ return obj.group()
+ return None
+
+ def _strip_output(self, out):
+ """
+ Cleans whitespace from the output
+ """
+ strip_out = "Message"
+ for l in out.split('\n'):
+ if l.strip():
+ strip_out = strip_out+"\n"+l.strip()
+ return strip_out
def run(self):
"""Run XMLRPC server, serving our methods.
diff --git a/testapp/docs/sample_questions.py b/testapp/docs/sample_questions.py
index aa7f239..45bb8a8 100644
--- a/testapp/docs/sample_questions.py
+++ b/testapp/docs/sample_questions.py
@@ -1,7 +1,7 @@
from datetime import date
questions = [
-Question(
+[Question(
summary='Factorial',
points=2,
type="python",
@@ -15,8 +15,11 @@ For example:<br/>
assert fact(0) == 1
assert fact(5) == 120
'''),
-
-Question(
+#Add tags here as a list of string.
+['Python','function','factorial'],
+],
+
+[Question(
summary='Simple function',
points=1,
type="python",
@@ -28,7 +31,11 @@ import math
assert sqr(3) == 9
assert abs(sqr(math.sqrt(2)) - 2.0) < 1e-14
'''),
-Question(
+#Add tags here as a list of string.
+['Python','function'],
+],
+
+[Question(
summary='Bash addition',
points=2,
type="bash",
@@ -38,7 +45,11 @@ Question(
docs/sample.sh
docs/sample.args
'''),
-Question(
+#Add tags here as a list of string.
+[''],
+],
+
+[Question(
summary='Size of integer in Python',
points=0.5,
type="mcq",
@@ -51,7 +62,11 @@ None of the above
''',
test = "No Limit"
),
-]
+#Add tags here as a list of string.
+['mcq'],
+],
+
+] #list of questions ends here
quiz = Quiz(start_date=date.today(),
duration=10,
diff --git a/testapp/exam/forms.py b/testapp/exam/forms.py
index 917bea7..dc19783 100644
--- a/testapp/exam/forms.py
+++ b/testapp/exam/forms.py
@@ -13,12 +13,13 @@ from string import letters, punctuation, digits
import datetime
QUESTION_TYPE_CHOICES = (
- ("python", "Python"),
- ("bash", "Bash"),
- ("mcq", "MCQ"),
- ("C", "C Language"),
- ("C++", "C++ Language"),
- ("java", "Java Language"),
+ ("python", "Python"),
+ ("bash", "Bash"),
+ ("mcq", "MCQ"),
+ ("C", "C Language"),
+ ("C++", "C++ Language"),
+ ("java", "Java Language"),
+ ("scilab", "Scilab"),
)
UNAME_CHARS = letters + "._" + digits
@@ -30,8 +31,7 @@ class UserRegisterForm(forms.Form):
It has the various fields and functions required to register
a new user to the system"""
- username = forms.CharField\
- (max_length=30, help_text='Letters, digits,\
+ username = forms.CharField(max_length=30, help_text='Letters, digits,\
period and underscores only.')
email = forms.EmailField()
password = forms.CharField(max_length=30, widget=forms.PasswordInput())
diff --git a/testapp/exam/management/commands/load_exam.py b/testapp/exam/management/commands/load_exam.py
index 3f247a1..e3f72da 100644
--- a/testapp/exam/management/commands/load_exam.py
+++ b/testapp/exam/management/commands/load_exam.py
@@ -32,7 +32,9 @@ def load_exam(filename):
raise NameError(msg)
for question in questions:
- question.save()
+ question[0].save()
+ for tag in question[1]:
+ question[0].tags.add(tag)
if 'quiz' in locals():
quiz.save()
diff --git a/testapp/exam/models.py b/testapp/exam/models.py
index babde0f..758091f 100644
--- a/testapp/exam/models.py
+++ b/testapp/exam/models.py
@@ -5,6 +5,8 @@ from taggit_autocomplete_modified.managers import TaggableManagerAutocomplete\
as TaggableManager
from django.http import HttpResponse
################################################################################
+
+
class Profile(models.Model):
"""Profile for a user to store roll number and other details."""
user = models.OneToOneField(User)
@@ -21,9 +23,11 @@ QUESTION_TYPE_CHOICES = (
("C", "C Language"),
("C++", "C++ Language"),
("java", "Java Language"),
+ ("scilab", "Scilab"),
)
-
################################################################################
+
+
class Question(models.Model):
"""A question in the database."""
@@ -32,10 +36,10 @@ class Question(models.Model):
# The question text, should be valid HTML.
description = models.TextField()
-
+
# Number of points for the question.
points = models.FloatField(default=1.0)
-
+
# Test cases for the question in the form of code that is run.
test = models.TextField(blank=True)
@@ -48,7 +52,7 @@ class Question(models.Model):
# Is this question active or not. If it is inactive it will not be used
# when creating a QuestionPaper.
active = models.BooleanField(default=True)
-
+
#Code Snippet
snippet = models.CharField(max_length=256)
@@ -65,7 +69,7 @@ class Answer(models.Model):
"""
# The question for which we are an answer.
question = models.ForeignKey(Question)
-
+
# The answer submitted by the user.
answer = models.TextField(null=True, blank=True)
@@ -75,49 +79,51 @@ class Answer(models.Model):
# Marks obtained for the answer. This can be changed by the teacher if the
# grading is manual.
marks = models.FloatField(default=0.0)
-
+
# Is the answer correct.
correct = models.BooleanField(default=False)
-
+
def __unicode__(self):
return self.answer
+
################################################################################
class Quiz(models.Model):
- """A quiz that students will participate in. One can think of this
+ """A quiz that students will participate in. One can think of this
as the "examination" event.
"""
-
+
# The starting/ending date of the quiz.
start_date = models.DateField("Date of the quiz")
-
+
# This is always in minutes.
duration = models.IntegerField("Duration of quiz in minutes", default=20)
-
- # Is the quiz active. The admin should deactivate the quiz once it is
+
+ # Is the quiz active. The admin should deactivate the quiz once it is
# complete.
active = models.BooleanField(default=True)
-
+
# Description of quiz.
description = models.CharField(max_length=256)
#Tags for the Quiz.
tags = TaggableManager()
-
class Meta:
verbose_name_plural = "Quizzes"
-
+
def __unicode__(self):
desc = self.description or 'Quiz'
- return '%s: on %s for %d minutes'%(desc, self.start_date, self.duration)
+ return '%s: on %s for %d minutes' % (desc, self.start_date, self.duration)
+
################################################################################
class QuestionPaper(models.Model):
quiz = models.ForeignKey(Quiz)
questions = models.ManyToManyField(Question)
total_marks = models.FloatField()
-
+
+
################################################################################
class AnswerPaper(models.Model):
"""A answer paper for a student -- one per student typically.
@@ -134,25 +140,25 @@ class AnswerPaper(models.Model):
# The Quiz to which this question paper is attached to.
question_paper = models.ForeignKey(QuestionPaper)
-
+
# The time when this paper was started by the user.
start_time = models.DateTimeField()
# The time when this paper was ended by the user.
end_time = models.DateTimeField()
-
+
# User's IP which is logged.
user_ip = models.CharField(max_length=15)
# The questions successfully answered (a list of ids separated by '|')
questions_answered = models.CharField(max_length=128)
-
+
# All the submitted answers.
answers = models.ManyToManyField(Answer)
# Teacher comments on the question paper.
comments = models.TextField()
-
+
def current_question(self):
"""Returns the current active question to display."""
qs = self.questions.split('|')
@@ -160,7 +166,7 @@ class AnswerPaper(models.Model):
return qs[0]
else:
return ''
-
+
def questions_left(self):
"""Returns the number of questions left."""
qs = self.questions
@@ -168,7 +174,7 @@ class AnswerPaper(models.Model):
return 0
else:
return qs.count('|') + 1
-
+
def completed_question(self, question_id):
"""Removes the question from the list of questions and returns
the next."""
@@ -198,7 +204,7 @@ the next."""
self.questions = '|'.join(qs)
self.save()
return qs[0]
-
+
def time_left(self):
"""Return the time remaining for the user in seconds."""
dt = datetime.datetime.now() - self.start_time
@@ -233,7 +239,7 @@ the next."""
else:
q_a[question] = [answer]
return q_a
-
+
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 f21357e..92dd029 100644
--- a/testapp/exam/views.py
+++ b/testapp/exam/views.py
@@ -52,10 +52,10 @@ def get_user_dir(user):
user_dir = join(OUTPUT_DIR, str(user.username))
if not exists(user_dir):
os.mkdir(user_dir)
- # Make it rwx by others.
- os.chmod(user_dir, stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH\
- | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR\
- | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)
+ # Make it rwx by others.
+ os.chmod(user_dir, stat.S_IROTH | stat.S_IWOTH | stat.S_IXOTH
+ | stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR
+ | stat.S_IRGRP | stat.S_IWGRP | stat.S_IXGRP)
return user_dir
@@ -110,6 +110,7 @@ def user_register(request):
Create a user and corresponding profile and store roll_number also."""
user = request.user
+ ci = RequestContext(request)
if user.is_authenticated():
return my_redirect("/exam/start/")
@@ -122,13 +123,11 @@ def user_register(request):
login(request, new_user)
return my_redirect("/exam/start/")
else:
- return my_render_to_response('exam/register.html',
- {'form': form},
- context_instance=RequestContext(request))
+ return my_render_to_response('exam/register.html', {'form': form},
+ context_instance=ci)
else:
form = UserRegisterForm()
- return my_render_to_response('exam/register.html',
- {'form': form}, context_instance=RequestContext(request))
+ return my_render_to_response('exam/register.html', {'form': form})
def quizlist_user(request):
@@ -151,14 +150,15 @@ def quizlist_user(request):
context = {'quizzes': avail_quiz, 'user': user}
return my_render_to_response("exam/quizzes_user.html", context)
+
def intro(request, questionpaper_id):
"""Show introduction page before quiz starts"""
user = request.user
- context = {'user': user, 'paper_id': questionpaper_id }
+ context = {'user': user, 'paper_id': questionpaper_id}
ci = RequestContext(request)
return my_render_to_response('exam/intro.html', context,
- context_instance=ci)
-
+ context_instance=ci)
+
def results_user(request):
"""Show list of Results of Quizzes that is taken by logged-in user."""
@@ -168,7 +168,7 @@ def results_user(request):
for paper in papers:
marks_obtained = paper.get_total_marks()
max_marks = paper.question_paper.total_marks
- percentage = round((marks_obtained/max_marks)*100,2)
+ percentage = round((marks_obtained/max_marks)*100, 2)
temp = paper.question_paper.quiz.description, marks_obtained,\
max_marks, percentage
quiz_marks.append(temp)
@@ -248,6 +248,7 @@ def add_question(request, question_id=None):
"""To add a new question in the database.
Create a new question and store it."""
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
if request.method == "POST":
@@ -283,12 +284,14 @@ def add_question(request, question_id=None):
return my_redirect("/exam/manage/questions")
else:
return my_render_to_response('exam/add_question.html',
- {'form': form}, context_instance=RequestContext(request))
+ {'form': form},
+ context_instance=ci)
else:
if question_id is None:
form = QuestionForm()
return my_render_to_response('exam/add_question.html',
- {'form': form}, context_instance=RequestContext(request))
+ {'form': form},
+ context_instance=ci)
else:
d = Question.objects.get(id=question_id)
form = QuestionForm()
@@ -310,7 +313,7 @@ def add_question(request, question_id=None):
form.initial['tags'] = initial_tags
return my_render_to_response('exam/add_question.html',
{'form': form},
- context_instance=RequestContext(request))
+ context_instance=ci)
def add_quiz(request, quiz_id=None):
@@ -318,6 +321,7 @@ def add_quiz(request, quiz_id=None):
Create a new quiz and store it."""
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
if request.method == "POST":
@@ -350,13 +354,13 @@ def add_quiz(request, quiz_id=None):
else:
return my_render_to_response('exam/add_quiz.html',
{'form': form},
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
if quiz_id is None:
form = QuizForm()
return my_render_to_response('exam/add_quiz.html',
{'form': form},
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
d = Quiz.objects.get(id=quiz_id)
form = QuizForm()
@@ -374,24 +378,26 @@ def add_quiz(request, quiz_id=None):
form.initial['tags'] = initial_tags
return my_render_to_response('exam/add_quiz.html',
{'form': form},
- context_instance=RequestContext(request))
+ context_instance=ci)
def design_questionpaper(request, questionpaper_id=None):
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
return my_render_to_response('exam/add_questionpaper.html', {},
- context_instance=RequestContext(request))
+ context_instance=ci)
def show_all_questionpapers(request, questionpaper_id=None):
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
if request.method == "POST" and request.POST.get('add') == "add":
- return my_redirect("/exam/manage/designquestionpaper/" + \
+ return my_redirect("/exam/manage/designquestionpaper/" +
questionpaper_id)
if request.method == "POST" and request.POST.get('delete') == "delete":
@@ -402,25 +408,26 @@ def show_all_questionpapers(request, questionpaper_id=None):
question_paper = QuestionPaper.objects.all()
context = {'papers': question_paper}
return my_render_to_response('exam/showquestionpapers.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
if questionpaper_id is None:
qu_papers = QuestionPaper.objects.all()
context = {'papers': qu_papers}
return my_render_to_response('exam/showquestionpapers.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
qu_papers = QuestionPaper.objects.get(id=questionpaper_id)
quiz = qu_papers.quiz
questions = qu_papers.questions.all()
context = {'papers': {'quiz': quiz, 'questions': questions}}
return my_render_to_response('exam/editquestionpaper.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
def automatic_questionpaper(request, questionpaper_id=None):
"""Generate automatic question paper for a particular quiz"""
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
@@ -432,19 +439,17 @@ def automatic_questionpaper(request, questionpaper_id=None):
questions = request.POST.getlist('questions')
tot_marks = 0
for quest in questions:
- if quest.isdigit():
- q = Question.objects.get(id=quest)
- tot_marks += q.points
+ q = Question.objects.get(id=quest)
+ tot_marks += q.points
quest_paper.quiz = quiz
quest_paper.total_marks = tot_marks
quest_paper.save()
for quest in questions:
- if quest.isdigit():
- q = Question.objects.get(id=quest)
- quest_paper.questions.add(q)
+ q = Question.objects.get(id=quest)
+ quest_paper.questions.add(q)
return my_redirect('/exam/manage/showquiz')
else:
- no_questions = int(request.POST.get('questions'))
+ no_questions = int(request.POST.get('num_questions'))
fetched_questions = fetch_questions(request)
n = len(fetched_questions)
msg = ''
@@ -459,14 +464,14 @@ 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))
+ context_instance=ci)
else:
tags = Tag.objects.all()
context = {'data': {'tags': tags}}
return my_render_to_response('exam/automatic_questionpaper.html',
- context, context_instance=RequestContext(request))
+ context, context_instance=ci)
else:
if request.method == "POST":
@@ -475,18 +480,16 @@ def automatic_questionpaper(request, questionpaper_id=None):
questions = request.POST.getlist('questions')
tot_marks = quest_paper.total_marks
for quest in questions:
- if quest.isdigit():
- q = Question.objects.get(id=quest)
- tot_marks += q.points
+ q = Question.objects.get(id=quest)
+ tot_marks += q.points
quest_paper.total_marks = tot_marks
quest_paper.save()
for quest in questions:
- if quest.isdigit():
- q = Question.objects.get(id=quest)
- quest_paper.questions.add(q)
+ q = Question.objects.get(id=quest)
+ quest_paper.questions.add(q)
return my_redirect('/exam/manage/showquiz')
else:
- no_questions = int(request.POST.get('questions'))
+ no_questions = int(request.POST.get('num_questions'))
fetched_questions = fetch_questions(request)
n = len(fetched_questions)
msg = ''
@@ -501,18 +504,19 @@ def automatic_questionpaper(request, questionpaper_id=None):
context = {'data': {'questions': fetched_questions,
'tags': tags,
'msg': msg}}
- return my_render_to_response\
- ('exam/automatic_questionpaper.html', context,
- context_instance=RequestContext(request))
+ return my_render_to_response(
+ 'exam/automatic_questionpaper.html', context,
+ context_instance=ci)
else:
tags = Tag.objects.all()
context = {'data': {'tags': tags}}
return my_render_to_response('exam/automatic_questionpaper.html',
- context, context_instance=RequestContext(request))
+ context, context_instance=ci)
def manual_questionpaper(request, questionpaper_id=None):
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
@@ -524,9 +528,8 @@ def manual_questionpaper(request, questionpaper_id=None):
quiz = Quiz.objects.order_by("-id")[0]
tot_marks = 0
for quest in questions:
- if quest.isdigit():
- q = Question.objects.get(id=quest)
- tot_marks += q.points
+ q = Question.objects.get(id=quest)
+ tot_marks += q.points
quest_paper.quiz = quiz
quest_paper.total_marks = tot_marks
quest_paper.save()
@@ -541,16 +544,16 @@ def manual_questionpaper(request, questionpaper_id=None):
if (n == 0):
msg = 'No matching Question found...'
tags = Tag.objects.all()
- context = {'data': {'questions': fetched_questions,\
+ context = {'data': {'questions': fetched_questions,
'tags': tags, 'msg': msg}}
return my_render_to_response('exam/manual_questionpaper.html',
context,
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
tags = Tag.objects.all()
context = {'data': {'tags': tags}}
return my_render_to_response('exam/manual_questionpaper.html',
- context, context_instance=RequestContext(request))
+ context, context_instance=ci)
else:
if request.method == "POST":
@@ -574,17 +577,16 @@ def manual_questionpaper(request, questionpaper_id=None):
if (n == 0):
msg = 'No matching Question found...'
tags = Tag.objects.all()
- context = {'data': {'questions': fetched_questions,\
+ context = {'data': {'questions': fetched_questions,
'tags': tags, 'msg': msg}}
return my_render_to_response('exam/manual_questionpaper.html',
context,
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
tags = Tag.objects.all()
context = {'data': {'tags': tags}}
return my_render_to_response('exam/manual_questionpaper.html',
- context, context_instance=RequestContext(request))
-
+ context, context_instance=ci)
def prof_manage(request):
@@ -602,6 +604,7 @@ def user_login(request):
"""Take the credentials of the user and log the user in."""
user = request.user
+ ci = RequestContext(request)
if user.is_authenticated():
if user.groups.filter(name='moderator').count() > 0:
return my_redirect('/exam/manage/')
@@ -618,12 +621,12 @@ def user_login(request):
else:
context = {"form": form}
return my_render_to_response('exam/login.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
form = UserLoginForm()
context = {"form": form}
return my_render_to_response('exam/login.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
def start(request, questionpaper_id=None):
@@ -642,7 +645,7 @@ def start(request, questionpaper_id=None):
return complete(request, msg, questionpaper_id)
try:
- old_paper = AnswerPaper.objects.get(\
+ old_paper = AnswerPaper.objects.get(
question_paper=questionpaper, user=user)
q = old_paper.current_question()
return show_question(request, q, questionpaper_id)
@@ -669,7 +672,8 @@ def start(request, questionpaper_id=None):
new_paper.save()
return start(request, questionpaper_id)
-def question(request, q_id, questionpaper_id,success_msg=None):
+
+def question(request, q_id, questionpaper_id, success_msg=None):
"""Check the credentials of the user and start the exam."""
user = request.user
@@ -678,16 +682,13 @@ def question(request, q_id, questionpaper_id,success_msg=None):
q = get_object_or_404(Question, pk=q_id)
try:
q_paper = QuestionPaper.objects.get(id=questionpaper_id)
- paper = AnswerPaper.objects.get(\
+ paper = AnswerPaper.objects.get(
user=request.user, question_paper=q_paper)
except AnswerPaper.DoesNotExist:
return my_redirect('/exam/start/')
if not paper.question_paper.quiz.active:
- reason='The quiz has been deactivated!'
+ reason = 'The quiz has been deactivated!'
return complete(request, reason, questionpaper_id)
- #if new:
- # paper.start_time = datetime.datetime.now()
- # paper.end_time = datetime.datetime.now()
time_left = paper.time_left()
if time_left == 0:
return complete(request, reason='Your time is up!')
@@ -695,30 +696,28 @@ def question(request, q_id, questionpaper_id,success_msg=None):
if success_msg is None:
context = {'question': q, 'paper': paper, 'user': user,
'quiz_name': quiz_name,
- 'time_left': time_left,}
-
+ 'time_left': time_left, }
else:
context = {'question': q, 'paper': paper, 'user': user,
'quiz_name': quiz_name,
'time_left': time_left,
- 'success_msg':success_msg}
-
+ 'success_msg': success_msg}
ci = RequestContext(request)
- return my_render_to_response('exam/question.html', context,
+ return my_render_to_response('exam/question.html', context,
context_instance=ci)
-def show_question(request, q_id, questionpaper_id,success_msg=None):
+def show_question(request, q_id, questionpaper_id, success_msg=None):
"""Show a question if possible."""
if len(q_id) == 0:
msg = 'Congratulations! You have successfully completed the quiz.'
- return complete(request, msg,questionpaper_id)
+ return complete(request, msg, questionpaper_id)
else:
- return question(request, q_id, questionpaper_id,success_msg)
+ return question(request, q_id, questionpaper_id, success_msg)
def check(request, q_id, questionpaper_id=None):
- """Checks the answers of the user for particular question"""
+ """Checks the answers of the user for particular question"""
user = request.user
if not user.is_authenticated():
@@ -734,10 +733,10 @@ def check(request, q_id, questionpaper_id=None):
if skip is not None:
next_q = paper.skip()
return show_question(request, next_q, questionpaper_id)
-
+
if question.type == 'mcq':
# Add the answer submitted, regardless of it being correct or not.
- if user_answer is not None :
+ if user_answer is not None:
new_answer = Answer(question=question, answer=user_answer,
correct=False)
new_answer.save()
@@ -756,7 +755,7 @@ def check(request, q_id, questionpaper_id=None):
# questions, we obtain the results via XML-RPC with the code executed
# safely in a separate process (the code_server.py) running as nobody.
if question.type == 'mcq':
- if user_answer is not None:
+ if user_answer is not None:
success = True # Only one attempt allowed for MCQ's.
if user_answer.strip() == question.test.strip():
new_answer.correct = True
@@ -765,10 +764,10 @@ def check(request, q_id, questionpaper_id=None):
success_msg = True
else:
new_answer.error = 'Incorrect answer'
- new_answer.save()
+ new_answer.save()
else:
user_dir = get_user_dir(user)
- success, err_msg = code_server.run_code(answer_check, question.test,
+ success, err_msg = code_server.run_code(answer_check, question.test,
user_dir, question.type)
new_answer.error = err_msg
if success:
@@ -781,10 +780,10 @@ def check(request, q_id, questionpaper_id=None):
time_left = paper.time_left()
if not success: # Should only happen for non-mcq questions.
if time_left == 0:
- reason='Your time is up!'
+ reason = 'Your time is up!'
return complete(request, reason, questionpaper_id)
if not paper.question_paper.quiz.active:
- reason='The quiz has been deactivated!'
+ reason = 'The quiz has been deactivated!'
return complete(request, reason, questionpaper_id)
context = {'question': question, 'error_message': err_msg,
'paper': paper, 'last_attempt': user_answer,
@@ -792,27 +791,28 @@ def check(request, q_id, questionpaper_id=None):
'time_left': time_left}
ci = RequestContext(request)
- return my_render_to_response('exam/question.html', context,
+ return my_render_to_response('exam/question.html', context,
context_instance=ci)
else:
if time_left <= 0:
- reason='Your time is up!'
+ reason = 'Your time is up!'
return complete(request, reason, questionpaper_id)
else:
next_q = paper.completed_question(question.id)
- return show_question(request, next_q, questionpaper_id,success_msg)
+ return show_question(request, next_q,
+ questionpaper_id, success_msg)
def quit(request, questionpaper_id=None):
"""Show the quit page when the user logs out."""
context = {'id': questionpaper_id}
return my_render_to_response('exam/quit.html', context,
- context_instance=RequestContext(request))
+ context_instance=RequestContext(request))
def complete(request, reason=None, questionpaper_id=None):
"""Show a page to inform user that the quiz has been compeleted."""
-
+
user = request.user
if questionpaper_id is None:
logout(request)
@@ -826,16 +826,16 @@ def complete(request, reason=None, questionpaper_id=None):
tot_marks = paper.question_paper.total_marks
if obt_marks == paper.question_paper.total_marks:
context = {'message': "Hurray ! You did an excellent job.\
- you answered all the questions correctly.\
- You have been logged out successfully,\
- Thank You !"}
+ you answered all the questions correctly.\
+ You have been logged out successfully,\
+ Thank You !"}
logout(request)
- return my_render_to_response('exam/complete.html',context)
+ return my_render_to_response('exam/complete.html', context)
else:
message = reason or "You are successfully logged out"
- context = {'message': message }
+ context = {'message': message}
logout(request)
- return my_render_to_response('exam/complete.html',context)
+ return my_render_to_response('exam/complete.html', context)
no = False
message = reason or 'The quiz has been completed. Thank you.'
if user.groups.filter(name='moderator').count() > 0:
@@ -856,16 +856,17 @@ def monitor(request, questionpaper_id=None):
"""Monitor the progress of the papers taken so far."""
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page!')
if questionpaper_id is None:
q_paper = QuestionPaper.objects.all()
- context = {'papers': [],
- 'quiz': None,
+ context = {'papers': [],
+ 'quiz': None,
'quizzes': q_paper}
return my_render_to_response('exam/monitor.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
# quiz_id is not None.
try:
q_paper = QuestionPaper.objects.get(id=questionpaper_id)
@@ -878,7 +879,7 @@ def monitor(request, questionpaper_id=None):
context = {'papers': papers, 'quiz': q_paper, 'quizzes': None}
return my_render_to_response('exam/monitor.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
def get_user_data(username):
@@ -896,7 +897,7 @@ def get_user_data(username):
profile = None
data['user'] = user
data['profile'] = profile
- data['papers'] = papers
+ data['papers'] = papers
return data
@@ -918,6 +919,7 @@ def show_all_quiz(request):
that are currently in the database."""
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404('You are not allowed to view this page !')
@@ -926,20 +928,20 @@ def show_all_quiz(request):
if data is None:
quizzes = Quiz.objects.all()
- context = {'papers': [],
- 'quiz': None,
+ context = {'papers': [],
+ 'quiz': None,
'quizzes': quizzes}
return my_render_to_response('exam/show_quiz.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
for i in data:
quiz = Quiz.objects.get(id=i).delete()
quizzes = Quiz.objects.all()
- context = {'papers': [],
- 'quiz': None,
+ context = {'papers': [],
+ 'quiz': None,
'quizzes': quizzes}
return my_render_to_response('exam/show_quiz.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
elif request.method == 'POST' and request.POST.get('edit') == 'edit':
data = request.POST.getlist('quiz')
@@ -962,20 +964,21 @@ def show_all_quiz(request):
forms.append(form)
return my_render_to_response('exam/edit_quiz.html',
{'forms': forms, 'data': data},
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
quizzes = Quiz.objects.all()
- context = {'papers': [],
- 'quiz': None,
+ context = {'papers': [],
+ 'quiz': None,
'quizzes': quizzes}
return my_render_to_response('exam/show_quiz.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
def show_all_questions(request):
"""Show a list of all the questions currently in the databse."""
user = request.user
+ ci = RequestContext(request)
if not user.is_authenticated() or not is_moderator(user):
raise Http404("You are not allowed to view this page !")
@@ -987,7 +990,7 @@ def show_all_questions(request):
'question': None,
'questions': questions}
return my_render_to_response('exam/showquestions.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
for i in data:
question = Question.objects.get(id=i).delete()
@@ -996,7 +999,7 @@ def show_all_questions(request):
'question': None,
'questions': questions}
return my_render_to_response('exam/showquestions.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
elif request.method == 'POST' and request.POST.get('edit') == 'edit':
data = request.POST.getlist('question')
@@ -1023,14 +1026,14 @@ def show_all_questions(request):
forms.append(form)
return my_render_to_response('exam/edit_question.html',
{'forms': forms, 'data': data},
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
questions = Question.objects.all()
context = {'papers': [],
'question': None,
'questions': questions}
return my_render_to_response('exam/showquestions.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
def user_data(request, username):
@@ -1052,6 +1055,7 @@ def grade_user(request, username):
and update all their marks and also give comments for each paper.
"""
current_user = request.user
+ ci = RequestContext(request)
if not current_user.is_authenticated() or not is_moderator(current_user):
raise Http404('You are not allowed to view this page!')
@@ -1064,14 +1068,14 @@ def grade_user(request, username):
last_ans = answers[-1]
last_ans.marks = marks
last_ans.save()
- paper.comments = request.POST.get(\
+ paper.comments = request.POST.get(
'comments_%d' % paper.question_paper.id)
paper.save()
context = {'data': data}
return my_render_to_response('exam/user_data.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
else:
context = {'data': data}
return my_render_to_response('exam/grade_user.html', context,
- context_instance=RequestContext(request))
+ context_instance=ci)
diff --git a/testapp/exam/xmlrpc_clients.py b/testapp/exam/xmlrpc_clients.py
index cc21e62..14ebf27 100644
--- a/testapp/exam/xmlrpc_clients.py
+++ b/testapp/exam/xmlrpc_clients.py
@@ -26,6 +26,7 @@ class CodeServerProxy(object):
"C": "run_c_code",
"C++": "run_cplus_code",
"java": "run_java_code",
+ "scilab": "run_scilab_code",
}
def run_code(self, answer, test_code, user_dir, language):
diff --git a/testapp/production.py b/testapp/production.py
index 312e838..8a1da98 100644
--- a/testapp/production.py
+++ b/testapp/production.py
@@ -1,7 +1,7 @@
from testapp.settings import *
-DEBUG=False
-TEMPLATE_DEBUG=DEBUG
+DEBUG = False
+TEMPLATE_DEBUG = DEBUG
from testapp.local import *
DATABASE_ENGINE = 'django.db.backends.mysql'
diff --git a/testapp/scilab_files/test_add.sce b/testapp/scilab_files/test_add.sce
new file mode 100644
index 0000000..a317cdb
--- /dev/null
+++ b/testapp/scilab_files/test_add.sce
@@ -0,0 +1,29 @@
+mode(-1)
+exec("function.sci",-1);
+i = 0
+p = add(3,5);
+correct = (p == 8);
+if correct then
+ i=i+1
+end
+disp("Input submitted 3 and 5")
+disp("Expected output 8 got " + string(p))
+p = add(22,-20);
+correct = (p==2);
+if correct then
+ i=i+1
+end
+disp("Input submitted 22 and -20")
+disp("Expected output 2 got " + string(p))
+p =add(91,0);
+correct = (p==91);
+if correct then
+ i=i+1
+end
+disp("Input submitted 91 and 0")
+disp("Expected output 91 got " + string(p))
+if i==3 then
+ exit(5);
+else
+ exit(3);
+end
diff --git a/testapp/settings.py b/testapp/settings.py
index cc84095..1d1b07d 100644
--- a/testapp/settings.py
+++ b/testapp/settings.py
@@ -5,9 +5,9 @@ from os.path import dirname, join, basename, abspath
DEBUG = True
TEMPLATE_DEBUG = DEBUG
-# The ports the code server should run on. This will run one separate
+# The ports the code server should run on. This will run one separate
# server for each port listed in the following list.
-SERVER_PORTS = [8001] # range(8001, 8026)
+SERVER_PORTS = [8001] # range(8001, 8026)
# The server pool port. This is the server which returns available server
# ports so as to minimize load. This is some random number where no other
@@ -18,7 +18,7 @@ SERVER_POOL_PORT = 53579
SERVER_TIMEOUT = 2
# The root of the URL, for example you might be in the situation where you
-# are not hosted as host.org/exam/ but as host.org/foo/exam/ for whatever
+# are not hosted as host.org/exam/ but as host.org/foo/exam/ for whatever
# reason set this to the root you have to serve at. In the above example
# host.org/foo/exam set URL_ROOT='/foo'
URL_ROOT = ''
@@ -42,7 +42,7 @@ DB_FILE = join(CURDIR, 'exam.db')
DATABASES = {
'default': {
- 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+ 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
'NAME': DB_FILE, # Or path to database file if using sqlite3.
'USER': '', # Not used with sqlite3.
'PASSWORD': '', # Not used with sqlite3.
@@ -119,7 +119,7 @@ STATICFILES_DIRS = (
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
-# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
+ #'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
@@ -129,7 +129,7 @@ SECRET_KEY = '9h*01@*#3ok+lbj5k=ym^eb)e=rf-g70&n0^nb_q6mtk!r(qr)'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
-# 'django.template.loaders.eggs.Loader',
+ #'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
@@ -142,7 +142,7 @@ MIDDLEWARE_CLASSES = (
)
-ROOT_URLCONF = '%s.urls'%(basename(CURDIR))
+ROOT_URLCONF = '%s.urls' % (basename(CURDIR))
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
@@ -165,7 +165,7 @@ INSTALLED_APPS = (
# 'django.contrib.admindocs',
'exam',
'taggit_autocomplete_modified',
- 'debug_toolbar',
+ 'debug_toolbar',
)
# A sample logging configuration. The only tangible logging
@@ -185,9 +185,9 @@ LOGGING = {
},
},
'handlers': {
- 'console':{
- 'level':'DEBUG',
- 'class':'logging.StreamHandler',
+ 'console': {
+ 'level': 'DEBUG',
+ 'class': 'logging.StreamHandler',
'formatter': 'simple'
},
'mail_admins': {
diff --git a/testapp/static/exam/js/question.js b/testapp/static/exam/js/question.js
index 2bf6f60..75baf76 100644
--- a/testapp/static/exam/js/question.js
+++ b/testapp/static/exam/js/question.js
@@ -120,7 +120,6 @@ function addLineNumbers(id)
el.className='AnswerWithLines';
el.id='AnswerWithLines';
el.style.height = (ta.scrollHeight) + 'px';
-
for(var no=split_content.length+1;no<1000;no++)
{
if(string.length>0)string = string + '<br>';
@@ -132,7 +131,6 @@ function addLineNumbers(id)
el.className='SnippetWithLines';
el.id='SnippetWithLines';
el.style.height = (ta.scrollHeight) + 'px';
-
for(var no=1;no<=split_content.length;no++)
{
if(string.length>0)string = string + '<br>';
diff --git a/testapp/templates/exam/automatic_questionpaper.html b/testapp/templates/exam/automatic_questionpaper.html
index 1175f55..fcd3db5 100644
--- a/testapp/templates/exam/automatic_questionpaper.html
+++ b/testapp/templates/exam/automatic_questionpaper.html
@@ -60,7 +60,7 @@ select
<br>
- <center>Number of question: <input type=text id=questions name='questions' style="width:25px;">&nbsp;<button class=btn type=submit name='fetch' value='fetch'>Fetch Questions</button><br></center>
+ <center>Number of question: <input type=text id=num_questions name='num_questions' style="width:25px;">&nbsp;<button class=btn type=submit name='fetch' value='fetch'>Fetch Questions</button><br></center>
<br>
<br>
diff --git a/testapp/test_server.py b/testapp/test_server.py
index 2a17739..d22a022 100644
--- a/testapp/test_server.py
+++ b/testapp/test_server.py
@@ -16,7 +16,6 @@ def check_result(result, check='correct answer'):
assert result[0], result[1]
assert check in result[1].lower(), result[1]
-
def test_python():
"""Test if server runs Python code as expected."""
src = 'while True: pass'
@@ -24,16 +23,16 @@ def test_python():
check_result(result, 'more than ')
src = 'x = 1'
result = code_server.run_code(src, 'assert x == 1', '/tmp',
- language="python")
+ language="python")
check_result(result, 'correct answer')
result = code_server.run_code(src, 'assert x == 0', '/tmp',
- language="python")
+ language="python")
check_result(result, 'assertionerror')
src = 'abracadabra'
result = code_server.run_code(src, 'assert x == 0', '/tmp',
- language="python")
+ language="python")
check_result(result, 'nameerror')
@@ -202,12 +201,55 @@ def test_java():
int square_num(int a)
{
return a+b
-
"""
result = code_server.run_code(src, 'java_files/main_square.java',
'/tmp', language="java")
check_result(result, 'error')
+def test_scilab():
+ """Test if server runs scilab code as expected."""
+ src = """
+ funcprot(0)
+function[c]=add(a,b)
+ c=a+b;
+endfunction
+ """
+ result = code_server.run_code(src, 'scilab_files/test_add.sce',
+ '/tmp', language="scilab")
+ check_result(result, 'correct answer')
+
+ src = """
+ funcprot(0)
+function[c]=add(a,b)
+ c=a-b;
+endfunction
+ """
+ result = code_server.run_code(src, 'scilab_files/test_add.sce',
+ '/tmp', language="scilab")
+ check_result(result, 'correct answer')
+
+ src = """
+ funcprot(0)
+function[c]=add(a,b)
+ c=a+b;
+dis(
+endfunction
+ """
+ result = code_server.run_code(src, 'scilab_files/test_add.sce',
+ '/tmp', language="scilab")
+ check_result(result, 'error')
+
+ src = """
+ funcprot(0)
+function[c]=add(a,b)
+ c=a
+ while(1==1)
+ end
+endfunction
+ """
+ result = code_server.run_code(src, 'scilab_files/test_add.sce',
+ '/tmp', language="scilab")
+ check_result(result, 'error')
def test_bash():
"""Test if server runs Bash code as expected."""
@@ -215,40 +257,40 @@ def test_bash():
#!/bin/bash
[[ $# -eq 2 ]] && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))
"""
- result = code_server.run_code(src,
- 'docs/sample.sh\ndocs/sample.args', '/tmp', language="bash")
+ result = code_server.run_code(src, 'docs/sample.sh\ndocs/sample.args',
+ '/tmp', language="bash")
check_result(result)
src = """
#!/bin/bash
[[ $# -eq 2 ]] && echo $(( $1 - $2 )) && exit $(( $1 - $2 ))
"""
- result = code_server.run_code(src,
- 'docs/sample.sh\ndocs/sample.args', '/tmp', language="bash")
+ result = code_server.run_code(src, 'docs/sample.sh\ndocs/sample.args',
+ '/tmp', language="bash")
check_result(result, 'error')
src = """\
#!/bin/bash
while [ 1 ] ; do echo "" > /dev/null ; done
"""
- result = code_server.run_code(src,
- 'docs/sample.sh\ndocs/sample.args', '/tmp', language="bash")
+ result = code_server.run_code(src, 'docs/sample.sh\ndocs/sample.args',
+ '/tmp', language="bash")
check_result(result, 'more than ')
src = '''
#!/bin/bash
while [ 1 ] ; do echo "" > /dev/null
'''
- result = code_server.run_code(src,
- 'docs/sample.sh\ndocs/sample.args', '/tmp', language="bash")
+ result = code_server.run_code(src, 'docs/sample.sh\ndocs/sample.args',
+ '/tmp', language="bash")
check_result(result, 'error')
src = '''# Enter your code here.
#!/bin/bash
while [ 1 ] ; do echo "" > /dev/null
'''
- result = code_server.run_code(src,
- 'docs/sample.sh\ndocs/sample.args', '/tmp', language="bash")
+ result = code_server.run_code(src, 'docs/sample.sh\ndocs/sample.args',
+ '/tmp', language="bash")
check_result(result, 'oserror')
if __name__ == '__main__':
@@ -257,3 +299,4 @@ if __name__ == '__main__':
test_c()
test_cpp()
test_java()
+ test_scilab()