diff options
33 files changed, 835 insertions, 256 deletions
diff --git a/buildout.cfg b/buildout.cfg index 486e68e..f0cb035 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -10,6 +10,8 @@ eggs = versions = versions [versions] django = 1.3 +django-taggit = 0.10a1 +django-debug-toolbar = 0.8.4 [django] recipe = djangorecipe diff --git a/production.cfg b/production.cfg index 318fb12..d623e80 100644 --- a/production.cfg +++ b/production.cfg @@ -11,6 +11,8 @@ eggs = versions = versions [versions] django = 1.3 +django-taggit = 0.10a1 +django-debug-toolbar = 0.8.4 [django] recipe = djangorecipe diff --git a/testapp/c_cpp_files/main_array_check.cpp b/testapp/c_cpp_files/main_array_check.cpp new file mode 100755 index 0000000..ea34fdd --- /dev/null +++ b/testapp/c_cpp_files/main_array_check.cpp @@ -0,0 +1,34 @@ +#include <stdio.h> +#include <stdlib.h> + +extern bool array_check(int [], int); + +template <class T> + +void check(T expect,T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + bool result; + 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"); + 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"); + 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 new file mode 100755 index 0000000..140578e --- /dev/null +++ b/testapp/c_cpp_files/main_array_check_all.cpp @@ -0,0 +1,34 @@ +#include <stdio.h> +#include <stdlib.h> + +extern bool array_check_all(int []); + +template <class T> + +void check(T expect,T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + bool result; + int a[] = {1,2,3,2,8}; + result = array_check_all(a); + 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}"); + 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 new file mode 100755 index 0000000..cc54e78 --- /dev/null +++ b/testapp/c_cpp_files/main_blackJack.cpp @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> + +extern int blackJack(int, int); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + int result; + result = blackJack(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"); + check(19, result); + result = blackJack(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); + 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 new file mode 100755 index 0000000..d3bf3d6 --- /dev/null +++ b/testapp/c_cpp_files/main_check_digit.cpp @@ -0,0 +1,32 @@ +#include <stdio.h> +#include <stdlib.h> + +extern bool check_digit(int, int); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + bool result; + result = check_digit(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"); + 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 new file mode 100755 index 0000000..f146e8c --- /dev/null +++ b/testapp/c_cpp_files/main_count667.cpp @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <stdlib.h> + +extern int count667(int[]); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + int result; + int arr[5] = {2,6,4,5,6}; + result = count667(arr); + printf("Input submitted to the function: [2, 6, 4, 5,6]"); + check(0, result); + int arr2[5] = {6,6,2,17,9}; + result = count667(arr2); + printf("Input submitted to the function: [6, 6, 2, 17, 9]"); + check(1, result); + int arr3[5] = {6,6,6,7,1}; + result = count667(arr3); + printf("Input submitted to the function: [6, 6, 7, 2, 1]"); + check(3, result); + int arr4[5] = {6,7,7,6,6}; + result = count667(arr4); + printf("Input submitted to the function: [6, 7, 7, 6, 6]"); + check(2, result); + printf("All Correct\n"); + return 0; +} diff --git a/testapp/c_cpp_files/main_count7.cpp b/testapp/c_cpp_files/main_count7.cpp new file mode 100755 index 0000000..982e930 --- /dev/null +++ b/testapp/c_cpp_files/main_count7.cpp @@ -0,0 +1,42 @@ +#include <stdio.h> +#include <stdlib.h> + +extern int count7(int[]); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + int result; + int arr[4] = {2,3,4,5}; + result = count7(arr); + printf("Input submitted to the function: [2, 3, 4, 5]"); + check(0, result); + int arr2[4] = {1,2,17,9}; + result = count7(arr2); + printf("Input submitted to the function: [1, 2, 17, 9]"); + check(0, result); + int arr3[4] = {7,9,2,1}; + result = count7(arr3); + printf("Input submitted to the function: [7, 9, 2, 1]"); + check(1, result); + int arr4[4] = {1,7,7,7}; + result = count7(arr4); + printf("Input submitted to the function: [1, 7, 7, 7]"); + check(3, result); + printf("All Correct\n"); + return 0; +} diff --git a/testapp/c_cpp_files/main_lessThan9.cpp b/testapp/c_cpp_files/main_lessThan9.cpp new file mode 100755 index 0000000..722b4bb --- /dev/null +++ b/testapp/c_cpp_files/main_lessThan9.cpp @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <stdlib.h> + +extern bool lessThan9(int); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + bool result; + result = lessThan9(10); + printf("Input submitted to the function: 10"); + check(false, result); + result = lessThan9(17); + printf("Input submitted to the function: 17"); + check(true, result); + result = lessThan9(16); + printf("Input submitted to the function: 16"); + check(true, result); + result = lessThan9(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 new file mode 100755 index 0000000..21a4b1a --- /dev/null +++ b/testapp/c_cpp_files/main_mean.cpp @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <stdlib.h> + +extern bool mean(int, int , int); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + bool result; + 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"); + check(true, result); + result = mean(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"); + 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 new file mode 100755 index 0000000..12c961d --- /dev/null +++ b/testapp/c_cpp_files/main_roundTo10.cpp @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> + +extern int roundTo10(int,int,int); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + int result; + result = roundTo10(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"); + check(130, result); + 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"); + check(0, result); + result = roundTo10(30, 40, 50); + printf("Input submitted to the function: 30, 40, 50"); + check(120, result); + printf("All Correct\n"); + return 0; +} diff --git a/testapp/c_cpp_files/main_specialSum.cpp b/testapp/c_cpp_files/main_specialSum.cpp new file mode 100755 index 0000000..d614536 --- /dev/null +++ b/testapp/c_cpp_files/main_specialSum.cpp @@ -0,0 +1,41 @@ +#include <stdio.h> +#include <stdlib.h> + +extern int specialSum(int,int,int); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + int result; + result = specialSum(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"); + check(1, result); + 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"); + check(12, result); + result = specialSum(10, 2, 6); + printf("Input submitted to the function: 10, 2, 6"); + check(18, result); + printf("All Correct\n"); + return 0; +} diff --git a/testapp/c_cpp_files/main_within.cpp b/testapp/c_cpp_files/main_within.cpp new file mode 100755 index 0000000..50f9ad0 --- /dev/null +++ b/testapp/c_cpp_files/main_within.cpp @@ -0,0 +1,38 @@ +#include <stdio.h> +#include <stdlib.h> + +extern bool within(int, int, int); + +template <class T> + +void check(T expect, T result) +{ + if (expect == result) + { + printf("\nCorrect:\n Expected %d got %d \n",expect,result); + } + else + { + printf("\nIncorrect:\n Expected %d got %d \n",expect,result); + exit (1); + } +} + +int main(void) +{ + bool result; + result = within(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"); + check(false, result); + 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"); + check(false, result); + printf("All Correct\n"); + return 0; +} diff --git a/testapp/code_server.py b/testapp/code_server.py index 8b3f8f1..88e374c 100755 --- a/testapp/code_server.py +++ b/testapp/code_server.py @@ -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 == '': diff --git a/testapp/exam/forms.py b/testapp/exam/forms.py index 8506de2..d711f6a 100644 --- a/testapp/exam/forms.py +++ b/testapp/exam/forms.py @@ -13,12 +13,12 @@ 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"), ) UNAME_CHARS = letters + "._" + digits @@ -30,8 +30,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()) @@ -167,6 +166,7 @@ class QuestionForm(forms.Form): options = self.cleaned_data['options'] type = self.cleaned_data["type"] active = self.cleaned_data["active"] + snippet = self.cleaned_data["snippet"] new_question = Question() new_question.summary = summary @@ -176,4 +176,5 @@ class QuestionForm(forms.Form): new_question.options = options new_question.type = type new_question.active = active + new_question.snippet = snippet new_question.save() diff --git a/testapp/exam/models.py b/testapp/exam/models.py index 5d6e2cf..713260b 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) @@ -22,8 +24,9 @@ QUESTION_TYPE_CHOICES = ( ("C++", "C++ Language"), ("java", "Java Language"), ) - ################################################################################ + + class Question(models.Model): """A question in the database.""" @@ -32,10 +35,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 +51,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,9 +68,9 @@ 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() + answer = models.TextField(null=True, blank=True) # Error message when auto-checking the answer. error = models.TextField() @@ -75,51 +78,54 @@ 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 question paper for a student -- one per student typically. + """A answer paper for a student -- one per student typically. """ # The user taking this question paper. user = models.ForeignKey(User) @@ -133,25 +139,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('|') @@ -159,7 +165,7 @@ class AnswerPaper(models.Model): return qs[0] else: return '' - + def questions_left(self): """Returns the number of questions left.""" qs = self.questions @@ -167,7 +173,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.""" @@ -197,7 +203,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 @@ -232,7 +238,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/urls.py b/testapp/exam/urls.py index b3cfceb..33b2edf 100644 --- a/testapp/exam/urls.py +++ b/testapp/exam/urls.py @@ -7,15 +7,15 @@ urlpatterns = patterns('exam.views', url(r'^results/$','results_user'), url(r'^start/$', 'start'), url(r'^start/(?P<questionpaper_id>\d+)/$','start'), - url(r'^quit/(?P<answerpaper_id>\d+)/$', 'quit'), - url(r'^intro/$','start'), + url(r'^quit/(?P<questionpaper_id>\d+)/$', 'quit'), + url(r'^intro/(?P<questionpaper_id>\d+)/$','intro'), url(r'^complete/$', 'complete'), - url(r'^complete/(?P<answerpaper_id>\d+)/$', 'complete'), + url(r'^complete/(?P<questionpaper_id>\d+)/$', 'complete'), url(r'^register/$', 'user_register'), url(r'^(?P<q_id>\d+)/$', 'question'), url(r'^(?P<q_id>\d+)/check/$', 'check'), url(r'^(?P<q_id>\d+)/check/(?P<questionpaper_id>\d+)/$', 'check'), - + url(r'^intro/$', 'start'), url(r'^manage/$', 'prof_manage'), url(r'^manage/addquestion/$', 'add_question'), @@ -32,7 +32,7 @@ urlpatterns = patterns('exam.views', url(r'^manage/showquestionpapers/$','show_all_questionpapers'), url(r'^manage/showquestionpapers/(?P<questionpaper_id>\d+)/$',\ 'show_all_questionpapers'), - url(r'^manage/monitor/(?P<quiz_id>\d+)/$', 'monitor'), + url(r'^manage/monitor/(?P<questionpaper_id>\d+)/$', 'monitor'), url(r'^manage/user_data/(?P<username>[a-zA-Z0-9_.]+)/$','user_data'), url(r'^manage/designquestionpaper/$','design_questionpaper'), url(r'^manage/designquestionpaper/(?P<questionpaper_id>\d+)/$',\ diff --git a/testapp/exam/views.py b/testapp/exam/views.py index dd11346..92dd029 100644 --- a/testapp/exam/views.py +++ b/testapp/exam/views.py @@ -26,7 +26,7 @@ OUTPUT_DIR = abspath(join(dirname(__file__), pardir, 'output')) def my_redirect(url): """An overridden redirect to deal with URL_ROOT-ing. See settings.py -for details.""" + for details.""" return redirect(URL_ROOT + url) @@ -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): @@ -145,20 +144,33 @@ def quizlist_user(request): for paper in user_answerpapers: for quiz in avail_quiz: if paper.question_paper.id == quiz.id and \ - paper.end_time != paper.start_time: + paper.end_time != paper.start_time: avail_quiz.remove(quiz) 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} + ci = RequestContext(request) + return my_render_to_response('exam/intro.html', context, + context_instance=ci) + + def results_user(request): """Show list of Results of Quizzes that is taken by logged-in user.""" user = request.user papers = AnswerPaper.objects.filter(user=user) quiz_marks = [] for paper in papers: - temp = paper.question_paper.quiz.description, paper.get_total_marks() + marks_obtained = paper.get_total_marks() + max_marks = paper.question_paper.total_marks + percentage = round((marks_obtained/max_marks)*100, 2) + temp = paper.question_paper.quiz.description, marks_obtained,\ + max_marks, percentage quiz_marks.append(temp) context = {'papers': quiz_marks} return my_render_to_response("exam/results_user.html", context) @@ -218,10 +230,10 @@ def edit_question(request): question.points = points[j] question.test = test[j] question.options = options[j] - question.type = type[j] - edit_tags = tags[j] question.active = active[j] question.snippet = snippet[j] + question.type = type[j] + edit_tags = tags[j] question.save() for tag in question.tags.all(): question.tags.remove(tag) @@ -236,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": @@ -264,19 +277,21 @@ def add_question(request, question_id=None): question = Question.objects.get(id=question_id) for tag in question.tags.all(): question.tags.remove(tag) - tags = form['tags'].data.split(', ') + tags = form['tags'].data.split(',') for i in range(0, len(tags)-1): tag = tags[i].strip() question.tags.add(tag) 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() @@ -297,15 +312,16 @@ def add_question(request, question_id=None): initial_tags = "" form.initial['tags'] = initial_tags return my_render_to_response('exam/add_question.html', - {'form': form}, - context_instance=RequestContext(request)) + {'form': form}, + context_instance=ci) def add_quiz(request, quiz_id=None): """To add a new quiz in the database. - Create a new question and store it.""" + 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": @@ -337,14 +353,14 @@ def add_quiz(request, quiz_id=None): return my_redirect("/exam/manage/showquiz") else: return my_render_to_response('exam/add_quiz.html', - {'form': form}, - context_instance=RequestContext(request)) + {'form': form}, + 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)) + {'form': form}, + context_instance=ci) else: d = Quiz.objects.get(id=quiz_id) form = QuizForm() @@ -361,26 +377,28 @@ def add_quiz(request, quiz_id=None): initial_tags = "" form.initial['tags'] = initial_tags return my_render_to_response('exam/add_quiz.html', - {'form': form}, - context_instance=RequestContext(request)) + {'form': form}, + 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/" + \ - questionpaper_id) + return my_redirect("/exam/manage/designquestionpaper/" + + questionpaper_id) if request.method == "POST" and request.POST.get('delete') == "delete": data = request.POST.getlist('papers') @@ -390,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!') @@ -417,16 +436,20 @@ def automatic_questionpaper(request, questionpaper_id=None): if request.POST.get('save') == 'save': quiz = Quiz.objects.order_by("-id")[0] quest_paper = QuestionPaper() + questions = request.POST.getlist('questions') + tot_marks = 0 + for quest in questions: + q = Question.objects.get(id=quest) + tot_marks += q.points quest_paper.quiz = quiz + quest_paper.total_marks = tot_marks quest_paper.save() - questions = request.POST.getlist('questions') - for i in questions: - if i.isdigit(): - q = Question.objects.get(id=i) - quest_paper.questions.add(q) + for quest in questions: + 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 = '' @@ -439,29 +462,34 @@ def automatic_questionpaper(request, questionpaper_id=None): of Questions...' tags = Tag.objects.all() context = {'data': {'questions': fetched_questions, - 'tags': tags, - 'msg': msg}} - return my_render_to_response(\ - 'exam/automatic_questionpaper.html', context, - context_instance=RequestContext(request)) + 'tags': tags, + 'msg': msg}} + 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) else: if request.method == "POST": if request.POST.get('save') == 'save': quest_paper = QuestionPaper.objects.get(id=questionpaper_id) questions = request.POST.getlist('questions') - for i in questions: - if i.isdigit(): - q = Question.objects.get(id=i) - quest_paper.questions.add(q) + tot_marks = quest_paper.total_marks + for quest in questions: + q = Question.objects.get(id=quest) + tot_marks += q.points + quest_paper.total_marks = tot_marks + quest_paper.save() + for quest in questions: + 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 = '' @@ -477,17 +505,18 @@ def automatic_questionpaper(request, questionpaper_id=None): 'tags': tags, 'msg': msg}} return my_render_to_response( - 'exam/automatic_questionpaper.html', context, - context_instance=RequestContext(request)) + '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!') @@ -495,9 +524,14 @@ def manual_questionpaper(request, questionpaper_id=None): if request.method == "POST": if request.POST.get('save') == 'save': questions = request.POST.getlist('questions') - quiz = Quiz.objects.order_by("-id")[0] quest_paper = QuestionPaper() + quiz = Quiz.objects.order_by("-id")[0] + tot_marks = 0 + for quest in questions: + q = Question.objects.get(id=quest) + tot_marks += q.points quest_paper.quiz = quiz + quest_paper.total_marks = tot_marks quest_paper.save() for i in questions: q = Question.objects.get(id=i) @@ -510,26 +544,32 @@ def manual_questionpaper(request, questionpaper_id=None): if (n == 0): msg = 'No matching Question found...' tags = Tag.objects.all() - context = {'data': {'questions': fetched_questions,\ - 'tags': tags, 'msg': msg}} + context = {'data': {'questions': fetched_questions, + 'tags': tags, 'msg': msg}} return my_render_to_response('exam/manual_questionpaper.html', - context, - context_instance=RequestContext(request)) + context, + 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": if request.POST.get('save') == 'save': quest_paper = QuestionPaper.objects.get(id=questionpaper_id) questions = request.POST.getlist('questions') - for i in questions: - q = Question.objects.get(id=i) - quest_paper.questions.add(q) - return my_redirect('/exam/manage/showquiz') + tot_marks = quest_paper.total_marks + for quest in questions: + q = Question.objects.get(id=quest) + tot_marks += q.points + quest_paper.total_marks = tot_marks + quest_paper.save() + for i in questions: + q = Question.objects.get(id=i) + quest_paper.questions.add(q) + return my_redirect('/exam/manage/showquiz') else: fetched_questions = fetch_questions(request) n = len(fetched_questions) @@ -537,16 +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,\ - 'tags': tags, 'msg': msg}} + context = {'data': {'questions': fetched_questions, + 'tags': tags, 'msg': msg}} return my_render_to_response('exam/manual_questionpaper.html', - context, - context_instance=RequestContext(request)) + context, + 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): @@ -554,7 +594,7 @@ def prof_manage(request): rights/permissions and log in.""" user = request.user if user.is_authenticated()\ - and user.groups.filter(name='moderator').count() > 0: + and user.groups.filter(name='moderator').count() > 0: context = {'user': user} return my_render_to_response('manage.html', context) return my_redirect('/exam/login/') @@ -564,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/') @@ -580,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): @@ -600,11 +641,11 @@ def start(request, questionpaper_id=None): questionpaper = QuestionPaper.objects.get(id=questionpaper_id) except QuestionPaper.DoesNotExist: msg = 'Quiz not found, please contact your '\ - 'instructor/administrator. Please login again thereafter.' - return complete(request, reason=msg) + 'instructor/administrator. Please login again thereafter.' + 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) @@ -618,7 +659,7 @@ def start(request, questionpaper_id=None): raise Http404(msg) new_paper = AnswerPaper(user=user, user_ip=ip, - question_paper=questionpaper, profile=profile) + question_paper=questionpaper, profile=profile) new_paper.start_time = datetime.datetime.now() new_paper.end_time = datetime.datetime.now() # Make user directory. @@ -627,18 +668,12 @@ def start(request, questionpaper_id=None): questions = [str(_.id) for _ in questionpaper.questions.all()] random.shuffle(questions) - #questions = questionpaper.questions - #random.shuffle(questions) new_paper.questions = "|".join(questions) new_paper.save() - # Show the user the intro page. - context = {'user': user, 'paper_id': questionpaper_id} - ci = RequestContext(request) - return my_render_to_response('exam/intro.html', context, - context_instance=ci) + return start(request, questionpaper_id) -def question(request, q_id, questionpaper_id): +def question(request, q_id, questionpaper_id, success_msg=None): """Check the credentials of the user and start the exam.""" user = request.user @@ -647,36 +682,42 @@ def question(request, q_id, questionpaper_id): q = get_object_or_404(Question, pk=q_id) try: q_paper = QuestionPaper.objects.get(id=questionpaper_id) - paper = AnswerPaper.objects.get(\ - user=request.user, question_paper=q_paper) + 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: - return complete(request, reason='The quiz has been deactivated!') - + reason = 'The quiz has been deactivated!' + return complete(request, reason, questionpaper_id) time_left = paper.time_left() if time_left == 0: return complete(request, reason='Your time is up!') quiz_name = paper.question_paper.quiz.description - context = {'question': q, 'paper': paper, 'user': user, - 'quiz_name': quiz_name, - 'time_left': time_left} + if success_msg is None: + context = {'question': q, 'paper': paper, 'user': user, + 'quiz_name': quiz_name, + 'time_left': time_left, } + else: + context = {'question': q, 'paper': paper, 'user': user, + 'quiz_name': quiz_name, + 'time_left': time_left, + 'success_msg': success_msg} ci = RequestContext(request) - return my_render_to_response('exam/question.html', context, - context_instance=ci) + return my_render_to_response('exam/question.html', context, + context_instance=ci) -def show_question(request, q_id, questionpaper_id): +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) + return complete(request, msg, questionpaper_id) else: - return question(request, q_id, questionpaper_id) + 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(): @@ -687,82 +728,114 @@ def check(request, q_id, questionpaper_id=None): snippet_code = request.POST.get('snippet') user_answer = request.POST.get('answer') skip = request.POST.get('skip', None) + success_msg = False + success = True 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. - new_answer = Answer(question=question, answer=user_answer, - correct=False) + if user_answer is not None: + new_answer = Answer(question=question, answer=user_answer, + correct=False) + new_answer.save() + paper.answers.add(new_answer) else: - # Add the answer submitted with the Snippet code (correct or incorrect) + """Add the answer submitted with the Snippet code, + regardless of it being correct or not.""" answer_check = snippet_code + "\n" + user_answer new_answer = Answer(question=question, answer=answer_check, correct=False) - - new_answer.save() - paper.answers.add(new_answer) + new_answer.save() + paper.answers.add(new_answer) # If we were not skipped, we were asked to check. For any non-mcq # questions, we obtain the results via XML-RPC with the code executed # safely in a separate process (the code_server.py) running as nobody. if question.type == 'mcq': - success = True # Only one attempt allowed for MCQ's. - if user_answer.strip() == question.test.strip(): - new_answer.correct = True - new_answer.marks = question.points - new_answer.error = 'Correct answer' - else: - new_answer.error = 'Incorrect answer' + 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 + new_answer.marks = question.points + new_answer.error = 'Correct answer' + success_msg = True + else: + new_answer.error = 'Incorrect answer' + 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: # Note the success and save it along with the marks. new_answer.correct = success new_answer.marks = question.points + success_msg = True + new_answer.save() - new_answer.save() - + time_left = paper.time_left() if not success: # Should only happen for non-mcq questions. - time_left = paper.time_left() if time_left == 0: - return complete(request, reason='Your time is up!') + reason = 'Your time is up!' + return complete(request, reason, questionpaper_id) if not paper.question_paper.quiz.active: - return complete(request, 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, 'quiz_name': paper.question_paper.quiz.description, '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: - next_q = paper.completed_question(question.id) - return show_question(request, next_q, questionpaper_id) + if time_left <= 0: + 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) -def quit(request, answerpaper_id=None): +def quit(request, questionpaper_id=None): """Show the quit page when the user logs out.""" - context = {'id': answerpaper_id} + 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, answerpaper_id=None): +def complete(request, reason=None, questionpaper_id=None): """Show a page to inform user that the quiz has been compeleted.""" user = request.user - - if answerpaper_id is None: + if questionpaper_id is None: logout(request) - context = {'message': "You are successfully Logged out."} + message = reason or "You are successfully logged out." + context = {'message': message} return my_render_to_response('exam/complete.html', context) + else: + q_paper = QuestionPaper.objects.get(id=questionpaper_id) + paper = AnswerPaper.objects.get(user=user, question_paper=q_paper) + obt_marks = paper.get_total_marks() + 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 !"} + logout(request) + return my_render_to_response('exam/complete.html', context) + else: + message = reason or "You are successfully logged out" + context = {'message': message} + logout(request) + 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: @@ -779,33 +852,34 @@ def complete(request, reason=None, answerpaper_id=None): return my_redirect('/exam/') -def monitor(request, quiz_id=None): +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 quiz_id is None: + 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: - quiz = QuestionPaper.objects.get(id=quiz_id) + q_paper = QuestionPaper.objects.get(id=questionpaper_id) except QuestionPaper.DoesNotExist: papers = [] - quiz = None + q_paper = None else: - papers = AnswerPaper.objects.all().annotate( - total=Sum('answers__marks')).order_by('-total') + papers = AnswerPaper.objects.filter(question_paper=q_paper).annotate( + total=Sum('answers__marks')).order_by('-total') - context = {'papers': papers, 'quiz': quiz, 'quizzes': 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): @@ -823,7 +897,7 @@ def get_user_data(username): profile = None data['user'] = user data['profile'] = profile - data['papers'] = papers + data['papers'] = papers return data @@ -837,7 +911,7 @@ def show_all_users(request): questionpaper = AnswerPaper.objects.all() context = {'question': questionpaper} return my_render_to_response('exam/showusers.html', context, - context_instance=RequestContext(request)) + context_instance=RequestContext(request)) def show_all_quiz(request): @@ -845,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 !') @@ -853,20 +928,20 @@ def show_all_quiz(request): if data is None: quizzes = Quiz.objects.all() - context = {'papers': [], - 'quiz': None, - 'quizzes': quizzes} + 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, - 'quizzes': quizzes} + 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') @@ -888,21 +963,22 @@ def show_all_quiz(request): form.initial['tags'] = initial_tags forms.append(form) return my_render_to_response('exam/edit_quiz.html', - {'forms': forms, 'data': data}, - context_instance=RequestContext(request)) + {'forms': forms, 'data': data}, + 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 !") @@ -911,19 +987,19 @@ def show_all_questions(request): if data is None: questions = Question.objects.all() context = {'papers': [], - 'question': None, - 'questions': questions} + '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() questions = Question.objects.all() context = {'papers': [], - 'question': None, - 'questions': questions} + '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') @@ -938,6 +1014,7 @@ def show_all_questions(request): form.initial['options'] = d.options form.initial['type'] = d.type form.initial['active'] = d.active + form.initial['snippet'] = d.snippet form_tags = d.tags.all() form_tags_split = form_tags.values('name') initial_tags = "" @@ -948,15 +1025,15 @@ def show_all_questions(request): form.initial['tags'] = initial_tags forms.append(form) return my_render_to_response('exam/edit_question.html', - {'forms': forms, 'data': data}, - context_instance=RequestContext(request)) + {'forms': forms, 'data': data}, + context_instance=ci) else: questions = Question.objects.all() context = {'papers': [], - 'question': None, - 'questions': questions} + '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): @@ -978,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!') @@ -990,14 +1068,14 @@ def grade_user(request, username): last_ans = answers[-1] last_ans.marks = marks last_ans.save() - paper.comments = request.POST.get(\ - 'comments_%d' % paper.question_paper.id) + 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/java_files/main_lastDigit.java b/testapp/java_files/main_lastDigit.java new file mode 100644 index 0000000..05439e2 --- /dev/null +++ b/testapp/java_files/main_lastDigit.java @@ -0,0 +1,36 @@ +class main_lastDigit +{ + public static <E> void check(E expect, E result) + { + if(result.equals(expect)) + { + System.out.println("Correct:\nOutput expected "+expect+" and got "+result+"\n"); + } + else + { + System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result+"\n"); + System.exit(1); + } + } + public static void main(String arg[]) + { + Test t = new Test(); + boolean result; + result= t.lastDigit(12, 2, 13); + System.out.println("Input submitted to the function: 12, 2, 13"); + check(true, result); + result = t.lastDigit(11, 52, 32); + System.out.println("Input submitted to the function: 11, 52, 32"); + check(true, result); + result = t.lastDigit(6, 34, 22); + System.out.println("Input submitted to the function: 6, 34, 22"); + check(false, result); + result = t.lastDigit(6, 46, 26); + System.out.println("Input submitted to the function: 63"); + check(true, result); + result = t.lastDigit(91, 90, 92); + System.out.println("Input submitted to the function: 91"); + check(false, result); + + } +} diff --git a/testapp/java_files/main_moreThan30.java b/testapp/java_files/main_moreThan30.java new file mode 100644 index 0000000..7da31cb --- /dev/null +++ b/testapp/java_files/main_moreThan30.java @@ -0,0 +1,36 @@ +class main_moreThan30 +{ + public static <E> void check(E expect, E result) + { + if(result.equals(expect)) + { + System.out.println("Correct:\nOutput expected "+expect+" and got "+result+"\n"); + } + else + { + System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result+"\n"); + System.exit(1); + } + } + public static void main(String arg[]) + { + Test t = new Test(); + boolean result; + result= t.moreThan30(30); + System.out.println("Input submitted to the function: 30"); + check(false, result); + result = t.moreThan30(151); + System.out.println("Input submitted to the function: 151"); + check(true, result); + result = t.moreThan30(66); + System.out.println("Input submitted to the function: 66"); + check(false, result); + result = t.moreThan30(63); + System.out.println("Input submitted to the function: 63"); + check(true, result); + result = t.moreThan30(91); + System.out.println("Input submitted to the function: 91"); + check(true, result); + + } +} diff --git a/testapp/java_files/main_palindrome.java b/testapp/java_files/main_palindrome.java index bd463e5..c0745f9 100644 --- a/testapp/java_files/main_palindrome.java +++ b/testapp/java_files/main_palindrome.java @@ -4,11 +4,11 @@ class main_palindrome { if(result.equals(expect)) { - System.out.println("Correct\n:Output expected "+expect+" and got "+result); + System.out.println("Correct:\nOutput expected "+expect+" and got "+result+"\n"); } else { - System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result); + System.out.println("Incorrect:\nOutput expected "+expect+" but got "+result+"\n"); System.exit(1); } } 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/settings.py b/testapp/settings.py index 0002476..6015f0c 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 = '' @@ -35,7 +35,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. @@ -104,7 +104,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. @@ -114,7 +114,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 = ( @@ -127,7 +127,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". @@ -150,7 +150,7 @@ INSTALLED_APPS = ( # 'django.contrib.admindocs', 'exam', 'taggit_autocomplete_modified', - 'debug_toolbar', + 'debug_toolbar', ) # A sample logging configuration. The only tangible logging @@ -170,9 +170,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/add_question.js b/testapp/static/exam/js/add_question.js index d990291..ba17492 100644 --- a/testapp/static/exam/js/add_question.js +++ b/testapp/static/exam/js/add_question.js @@ -77,10 +77,6 @@ function textareaformat() document.getElementById('id_points').setAttribute('class','mini-text'); document.getElementById('id_tags').setAttribute('class','tag-text'); - jQuery().ready(function() - { - $("#id_snippet").val("#To avoid indentation errors use tabs for indentation for Python questions"); - }); $('#id_snippet').bind('keydown', function( event ){ if(navigator.userAgent.match("Gecko")) @@ -135,14 +131,11 @@ function textareaformat() $('#id_snippet').bind('focus', function( event ){ document.getElementById("id_snippet").rows=5; document.getElementById("id_snippet").cols=40; - $('#id_snippet').val(""); }); $('#id_snippet').bind('blur', function( event ){ document.getElementById("id_snippet").rows=1; document.getElementById("id_snippet").cols=40; - $('#id_snippet').val("#To avoid indentation errors use tabs for indentation for Python questions"); - }); - + }); $('#id_type').bind('change',function(event){ var value = document.getElementById('id_type').value; if(value == 'mcq') diff --git a/testapp/static/exam/js/add_quiz.js b/testapp/static/exam/js/add_quiz.js index 56b0e95..d5688a8 100644 --- a/testapp/static/exam/js/add_quiz.js +++ b/testapp/static/exam/js/add_quiz.js @@ -2,7 +2,6 @@ function test() { if (document.getElementById("id_description").value != "") { - alert("reached condition"); document.getElementById("submit").innerHTML = "Save"; } } diff --git a/testapp/static/exam/js/edit_question.js b/testapp/static/exam/js/edit_question.js index 8866b9a..28d95f9 100644 --- a/testapp/static/exam/js/edit_question.js +++ b/testapp/static/exam/js/edit_question.js @@ -152,11 +152,6 @@ function textareaformat() var snippet_id = document.getElementById('id_snippet'+i); $(snippet_id).bind('focus',function(event){ this.rows = 5; - $(snippet_id).val(""); - }); - $(snippet_id).bind('blur',function(event){ - this.rows = 1; - $(snippet_id).val("#To avoid indentation errors use tab for indentation for Python questions"); }); $(snippet_id).bind('keydown', function (event){ catchTab(snippet_id,event); @@ -174,7 +169,6 @@ function textareaformat() jQuery().ready(function() { jQuery("#id_tags" + i).autocomplete("/taggit_autocomplete_modified/json", { multiple: true }); - $(snippet_id).val("#To avoid indentation errors use tab for indentation for Python questions"); }); } } 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/templates/exam/question.html b/testapp/templates/exam/question.html index 1203c0e..529b620 100644 --- a/testapp/templates/exam/question.html +++ b/testapp/templates/exam/question.html @@ -83,6 +83,12 @@ function update_time() <br/> {% endfor%} </div>{% endif %} + + {% if success_msg %} + <script type="text/javascript"> + alert("Congratulations, that's correct. Let's go to next question"); + </script> + {% endif %} <p id="status"></p> <form id="code" action="{{URL_ROOT}}/exam/{{ question.id }}/check/{{ paper.question_paper.id }}/" method="post"> {% csrf_token %} @@ -92,9 +98,9 @@ function update_time() {% endfor %} {% else %} - <textarea tabindex=1 rows="3" style="width:750px;margin-bottom:15px;height:auto;" readonly=yes name="snippet" id="snippet" wrap="off">{% if last_attempt %}{{ question.snippet }}{% else %}{% if question.type == "bash" %} #!/bin/bash{% else %}{% if question.type == "python "%} #To avoid errors use tabs for indentation for Python questions {{ question.snippet }} {% else %} {{ question.snippet }} {% endif %}{% endif %}{% endif %}</textarea> + <textarea tabindex=1 rows="3" style="width:750px;margin-bottom:15px;height:auto;" readonly=yes name="snippet" id="snippet" wrap="off">{% if last_attempt %}{{ question.snippet }}{% else %}{% if question.type == "bash" %} #!/bin/bash {{ question.snippet }}{% else %}{{ question.snippet }}{% endif %}{% endif %}</textarea> - <textarea tabindex=1 rows="10" style="width:750px;margin-bottom:10px;" name="answer" id="answer" wrap="off" onkeydown="return catchTab(this,event)">{% if last_attempt %}{{last_attempt.strip}}{% else %}{% if question.type == "bash" %}{% else %}{% endif %}{% endif %}</textarea> + <textarea tabindex=1 rows="10" style="width:750px;margin-bottom:10px;" name="answer" id="answer" wrap="off" onkeydown="return catchTab(this,event)">{% if last_attempt %}{{last_attempt}}{% else %}{% if question.type == "bash" %}{% else %}{% endif %}{% endif %}</textarea> <br> <script type="text/javascript"> diff --git a/testapp/templates/exam/quizzes_user.html b/testapp/templates/exam/quizzes_user.html index af2d98a..b55d3e5 100644 --- a/testapp/templates/exam/quizzes_user.html +++ b/testapp/templates/exam/quizzes_user.html @@ -12,7 +12,7 @@ <center><h4>No active quizzes for you</h4></center> {% endif %} {% for paper in quizzes %} - <a href="{{ URL_ROOT }}/exam/start/{{paper.id}}">{{ paper.quiz.description }}</a><br> + <a href="{{ URL_ROOT }}/exam/intro/{{paper.id}}">{{ paper.quiz.description }}</a><br> {% endfor %} {% endblock %} diff --git a/testapp/templates/exam/results_user.html b/testapp/templates/exam/results_user.html index bf847c0..2a2a309 100644 --- a/testapp/templates/exam/results_user.html +++ b/testapp/templates/exam/results_user.html @@ -13,6 +13,8 @@ <center><table class="span6"> <th>Quiz Description <th>Obtained Marks + <th>Maximum Marks + <th>Percentage {% for paper in papers %} <tr> {% for i in paper %} diff --git a/testapp/templates/exam/show_quiz.html b/testapp/templates/exam/show_quiz.html index 886a696..cf3f552 100644 --- a/testapp/templates/exam/show_quiz.html +++ b/testapp/templates/exam/show_quiz.html @@ -10,6 +10,7 @@ {% block manage %} {% if not quizzes and not quiz %} <center><h5> No quizzes available. </h5></center> +<button class="btn" type="button" onClick='location.replace("{{URL_ROOT}}/exam/manage/addquiz");'>Add New Quiz</button> {% endif %} {# ############################################################### #} diff --git a/testapp/templates/exam/showquestionpapers.html b/testapp/templates/exam/showquestionpapers.html index 26b756d..e511472 100644 --- a/testapp/templates/exam/showquestionpapers.html +++ b/testapp/templates/exam/showquestionpapers.html @@ -8,6 +8,7 @@ {% endblock %} {% block manage %} +{% if papers %} <form name=frm action="" method="post"> {% csrf_token %} {% for i in papers %} @@ -16,4 +17,7 @@ <br> <button class="btn" type="submit" onClick="return confirm_delete(frm);" name='delete' value='delete'>Delete Selected</button> </form> +{% else %} +<center><h3>No Question Papers available</h3></center> +{% endif %} {% endblock %} diff --git a/testapp/test_server.py b/testapp/test_server.py index 2a17739..95f87ef 100644 --- a/testapp/test_server.py +++ b/testapp/test_server.py @@ -24,16 +24,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,7 +202,6 @@ 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") @@ -215,40 +214,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__': |