diff options
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 f1ef0ba..668eca0 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;"> <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;"> <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() |