fact
which takes a single integer argument\r\n(say n
) and returns the factorial of the number. \r\nFor example:fact(3) -> 6
\r\n", "language": "python", "summary": "Factorial", "snippet": "def fact(num):", "active": true, "points": 2.0, "test": "assert fact(0) == 1\r\nassert fact(5) == 120", "type": "code", "options": ""}}, {"pk": 2, "model": "exam.question", "fields": {"ref_code_path": "", "description": "Create a simple function called sqr
which takes a single \r\nargument and returns the square of the argument. For example: sqr(3) -> 9
.", "language": "python", "summary": "Simple function", "snippet": "def sqr(num):", "active": true, "points": 1.0, "test": "import math\r\nassert sqr(3) == 9\r\nassert abs(sqr(math.sqrt(2)) - 2.0) < 1e-14", "type": "code", "options": ""}}, {"pk": 3, "model": "exam.question", "fields": {"ref_code_path": "docs/sample.sh, docs/sample.args", "description": "Write a shell script which takes two arguments on the\r\n command line and prints the sum of the two on the output.", "language": "bash", "summary": "Bash addition", "snippet": "#!/bin/bash", "active": true, "points": 2.0, "test": "", "type": "code", "options": ""}}, {"pk": 4, "model": "exam.question", "fields": {"ref_code_path": "", "description": "What is the largest integer value that can be represented\r\nin Python?", "language": "python", "summary": "Size of integer in Python", "snippet": "", "active": true, "points": 0.5, "test": "No Limit", "type": "mcq", "options": "No Limit\r\n2**32\r\n2**32 - 1\r\nNone of the above\r\n"}}, {"pk": 1, "model": "exam.quiz", "fields": {"description": "Demo Quiz", "language": "C", "time_between_attempts": 0, "pass_criteria": 2.0, "active": true, "attempts_allowed": -1, "duration": 30, "start_date": "2015-06-24", "prerequisite": null}}, {"pk": 1, "model": "exam.questionpaper", "fields": {"shuffle_questions": true, "total_marks": 5.5, "fixed_questions": [1, 2, 3, 4], "random_questions": [], "quiz": 1}}, {"pk": 1, "model": "taggit.tag", "fields": {"name": "Python", "slug": "python"}}, {"pk": 2, "model": "taggit.tag", "fields": {"name": "function", "slug": "function"}}, {"pk": 3, "model": "taggit.tag", "fields": {"name": "factorial", "slug": "factorial"}}, {"pk": 4, "model": "taggit.tag", "fields": {"name": "", "slug": ""}}, {"pk": 5, "model": "taggit.tag", "fields": {"name": "mcq", "slug": "mcq"}}, {"pk": 8, "model": "taggit.taggeditem", "fields": {"tag": 1, "content_type": 8, "object_id": 1}}, {"pk": 9, "model": "taggit.taggeditem", "fields": {"tag": 2, "content_type": 8, "object_id": 1}}, {"pk": 10, "model": "taggit.taggeditem", "fields": {"tag": 3, "content_type": 8, "object_id": 1}}, {"pk": 11, "model": "taggit.taggeditem", "fields": {"tag": 1, "content_type": 8, "object_id": 2}}, {"pk": 12, "model": "taggit.taggeditem", "fields": {"tag": 2, "content_type": 8, "object_id": 2}}, {"pk": 13, "model": "taggit.taggeditem", "fields": {"tag": 5, "content_type": 8, "object_id": 4}}, {"pk": 1, "model": "auth.permission", "fields": {"codename": "add_logentry", "name": "Can add log entry", "content_type": 1}}, {"pk": 2, "model": "auth.permission", "fields": {"codename": "change_logentry", "name": "Can change log entry", "content_type": 1}}, {"pk": 3, "model": "auth.permission", "fields": {"codename": "delete_logentry", "name": "Can delete log entry", "content_type": 1}}, {"pk": 4, "model": "auth.permission", "fields": {"codename": "add_permission", "name": "Can add permission", "content_type": 2}}, {"pk": 5, "model": "auth.permission", "fields": {"codename": "change_permission", "name": "Can change permission", "content_type": 2}}, {"pk": 6, "model": "auth.permission", "fields": {"codename": "delete_permission", "name": "Can delete permission", "content_type": 2}}, {"pk": 7, "model": "auth.permission", "fields": {"codename": "add_group", "name": "Can add group", "content_type": 3}}, {"pk": 8, "model": "auth.permission", "fields": {"codename": "change_group", "name": "Can change group", "content_type": 3}}, {"pk": 9, "model": "auth.permission", "fields": {"codename": "delete_group", "name": "Can delete group", "content_type": 3}}, {"pk": 10, "model": "auth.permission", "fields": {"codename": "add_user", "name": "Can add user", "content_type": 4}}, {"pk": 11, "model": "auth.permission", "fields": {"codename": "change_user", "name": "Can change user", "content_type": 4}}, {"pk": 12, "model": "auth.permission", "fields": {"codename": "delete_user", "name": "Can delete user", "content_type": 4}}, {"pk": 13, "model": "auth.permission", "fields": {"codename": "add_contenttype", "name": "Can add content type", "content_type": 5}}, {"pk": 14, "model": "auth.permission", "fields": {"codename": "change_contenttype", "name": "Can change content type", "content_type": 5}}, {"pk": 15, "model": "auth.permission", "fields": {"codename": "delete_contenttype", "name": "Can delete content type", "content_type": 5}}, {"pk": 16, "model": "auth.permission", "fields": {"codename": "add_session", "name": "Can add session", "content_type": 6}}, {"pk": 17, "model": "auth.permission", "fields": {"codename": "change_session", "name": "Can change session", "content_type": 6}}, {"pk": 18, "model": "auth.permission", "fields": {"codename": "delete_session", "name": "Can delete session", "content_type": 6}}, {"pk": 19, "model": "auth.permission", "fields": {"codename": "add_profile", "name": "Can add profile", "content_type": 7}}, {"pk": 20, "model": "auth.permission", "fields": {"codename": "change_profile", "name": "Can change profile", "content_type": 7}}, {"pk": 21, "model": "auth.permission", "fields": {"codename": "delete_profile", "name": "Can delete profile", "content_type": 7}}, {"pk": 22, "model": "auth.permission", "fields": {"codename": "add_question", "name": "Can add question", "content_type": 8}}, {"pk": 23, "model": "auth.permission", "fields": {"codename": "change_question", "name": "Can change question", "content_type": 8}}, {"pk": 24, "model": "auth.permission", "fields": {"codename": "delete_question", "name": "Can delete question", "content_type": 8}}, {"pk": 25, "model": "auth.permission", "fields": {"codename": "add_answer", "name": "Can add answer", "content_type": 9}}, {"pk": 26, "model": "auth.permission", "fields": {"codename": "change_answer", "name": "Can change answer", "content_type": 9}}, {"pk": 27, "model": "auth.permission", "fields": {"codename": "delete_answer", "name": "Can delete answer", "content_type": 9}}, {"pk": 28, "model": "auth.permission", "fields": {"codename": "add_quiz", "name": "Can add quiz", "content_type": 10}}, {"pk": 29, "model": "auth.permission", "fields": {"codename": "change_quiz", "name": "Can change quiz", "content_type": 10}}, {"pk": 30, "model": "auth.permission", "fields": {"codename": "delete_quiz", "name": "Can delete quiz", "content_type": 10}}, {"pk": 31, "model": "auth.permission", "fields": {"codename": "add_questionpaper", "name": "Can add question paper", "content_type": 11}}, {"pk": 32, "model": "auth.permission", "fields": {"codename": "change_questionpaper", "name": "Can change question paper", "content_type": 11}}, {"pk": 33, "model": "auth.permission", "fields": {"codename": "delete_questionpaper", "name": "Can delete question paper", "content_type": 11}}, {"pk": 34, "model": "auth.permission", "fields": {"codename": "add_questionset", "name": "Can add question set", "content_type": 12}}, {"pk": 35, "model": "auth.permission", "fields": {"codename": "change_questionset", "name": "Can change question set", "content_type": 12}}, {"pk": 36, "model": "auth.permission", "fields": {"codename": "delete_questionset", "name": "Can delete question set", "content_type": 12}}, {"pk": 37, "model": "auth.permission", "fields": {"codename": "add_answerpaper", "name": "Can add answer paper", "content_type": 13}}, {"pk": 38, "model": "auth.permission", "fields": {"codename": "change_answerpaper", "name": "Can change answer paper", "content_type": 13}}, {"pk": 39, "model": "auth.permission", "fields": {"codename": "delete_answerpaper", "name": "Can delete answer paper", "content_type": 13}}, {"pk": 40, "model": "auth.permission", "fields": {"codename": "add_assignmentupload", "name": "Can add assignment upload", "content_type": 14}}, {"pk": 41, "model": "auth.permission", "fields": {"codename": "change_assignmentupload", "name": "Can change assignment upload", "content_type": 14}}, {"pk": 42, "model": "auth.permission", "fields": {"codename": "delete_assignmentupload", "name": "Can delete assignment upload", "content_type": 14}}, {"pk": 43, "model": "auth.permission", "fields": {"codename": "add_testcase", "name": "Can add test case", "content_type": 15}}, {"pk": 44, "model": "auth.permission", "fields": {"codename": "change_testcase", "name": "Can change test case", "content_type": 15}}, {"pk": 45, "model": "auth.permission", "fields": {"codename": "delete_testcase", "name": "Can delete test case", "content_type": 15}}, {"pk": 46, "model": "auth.permission", "fields": {"codename": "add_tag", "name": "Can add Tag", "content_type": 16}}, {"pk": 47, "model": "auth.permission", "fields": {"codename": "change_tag", "name": "Can change Tag", "content_type": 16}}, {"pk": 48, "model": "auth.permission", "fields": {"codename": "delete_tag", "name": "Can delete Tag", "content_type": 16}}, {"pk": 49, "model": "auth.permission", "fields": {"codename": "add_taggeditem", "name": "Can add Tagged Item", "content_type": 17}}, {"pk": 50, "model": "auth.permission", "fields": {"codename": "change_taggeditem", "name": "Can change Tagged Item", "content_type": 17}}, {"pk": 51, "model": "auth.permission", "fields": {"codename": "delete_taggeditem", "name": "Can delete Tagged Item", "content_type": 17}}, {"pk": 1, "model": "auth.group", "fields": {"name": "moderator", "permissions": [25, 26, 27, 37, 38, 39, 40, 41, 42, 19, 20, 21, 22, 23, 24, 31, 32, 33, 34, 35, 36, 28, 29, 30, 43, 44, 45]}}, {"pk": 1, "model": "auth.user", "fields": {"username": "admin", "first_name": "", "last_name": "", "is_active": true, "is_superuser": true, "is_staff": true, "last_login": "2015-06-24T12:52:42.246", "groups": [1], "user_permissions": [], "password": "pbkdf2_sha256$12000$cm9G5GLAN5TA$hmAKSYEUGjgicK/JJPYlB3BiROfv6FLJqhw/slAQIqU=", "email": "admin@admin.com", "date_joined": "2015-06-24T12:47:31"}}, {"pk": 2, "model": "auth.user", "fields": {"username": "teacher", "first_name": "Teacher", "last_name": "Demo", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2015-06-24T12:50:42", "groups": [1], "user_permissions": [], "password": "pbkdf2_sha256$12000$RVSJsXu5jmkK$TfcRzV2LPFpEpv/shnlPG1CxWK6D6HovprqE+1neuqk=", "email": "teacher@teacher.com", "date_joined": "2015-06-24T12:50:40"}}, {"pk": 3, "model": "auth.user", "fields": {"username": "student", "first_name": "Student", "last_name": "Demo", "is_active": true, "is_superuser": false, "is_staff": false, "last_login": "2015-06-24T12:51:41.470", "groups": [], "user_permissions": [], "password": "pbkdf2_sha256$12000$jdwsvOoiB4UH$G+iAJR0nse50jxyNd+V/IATLrTra/FtaL+R1Uat0ewE=", "email": "student@student.com", "date_joined": "2015-06-24T12:51:40.477"}}, {"pk": 1, "model": "exam.profile", "fields": {"institute": "Teacher Institute", "department": "Teacher Department", "roll_number": "12345", "user": 2, "position": "Teacher"}}, {"pk": 2, "model": "exam.profile", "fields": {"institute": "Student Institute", "department": "Student Department", "roll_number": "54321", "user": 3, "position": "Student"}}, {"pk": 1, "model": "admin.logentry", "fields": {"action_flag": 1, "action_time": "2015-06-24T12:49:40.282", "object_repr": "moderator", "object_id": "1", "change_message": "", "user": 1, "content_type": 3}}, {"pk": 2, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2015-06-24T12:52:08.691", "object_repr": "admin", "object_id": "1", "change_message": "Changed groups.", "user": 1, "content_type": 4}}, {"pk": 3, "model": "admin.logentry", "fields": {"action_flag": 2, "action_time": "2015-06-24T12:52:17.144", "object_repr": "teacher", "object_id": "2", "change_message": "Changed groups.", "user": 1, "content_type": 4}}]
\ No newline at end of file
diff --git a/testapp/myauthentication/README b/testapp/myauthentication/README
deleted file mode 100644
index 4aef3c5..0000000
--- a/testapp/myauthentication/README
+++ /dev/null
@@ -1,12 +0,0 @@
-To use authentication from external source, follow the instructions given below:
-
-1. In settings.py,
- Uncomment AUTHENTICATION_BACKENDS = ('myauthentication.backend.MyBackend',)
- Uncomment AUTHENTICATION_BACKENDS = ('myauthentication.backend.MyBackend',)
- Enter database name, username and password for the spoken tutorial database.
-
-2. From login.html template comment 'New User? Sign-Up' link.
- This is to be done so that user will register only from external
- application and their details will be stored in the external database.
-
-3. In urls.py comment 'register' url pattern.
diff --git a/testapp/myauthentication/__init__.py b/testapp/myauthentication/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/testapp/myauthentication/backend.py b/testapp/myauthentication/backend.py
deleted file mode 100644
index 721fe54..0000000
--- a/testapp/myauthentication/backend.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import hashlib
-from django.contrib.auth.models import User, check_password
-from models_spoken_tutorial import MoodleUser
-
-
-class MyBackend:
- supports_object_permissions = False
- supports_anonymous_user = False
- supports_inactive_user = False
-
- def authenticate(self, username=None, password=None):
- '''
- Checks username and password with external User table.
- If valid then adds the user details in django User table
- and authenticates the user.
- '''
- try:
- user = MoodleUser.objects.get(username=username)
- pwd = user.password
- uid = user.id
- firstname = user.firstname
- lastname = user.lastname
- email_id = user.email
- p = hashlib.md5(password)
- pwd_valid = (pwd == p.hexdigest())
- if user and pwd_valid:
- try:
- user = User.objects.get(username=username)
- return user
- except Exception, e:
- user = User(id=uid, username=username, password=pwd,
- first_name=firstname, last_name=lastname,
- email=email_id)
- user.save()
- return user
- except Exception, e:
- return None
-
- def get_user(self, user_id):
- try:
- return User.objects.get(pk=user_id)
- except Exception, e:
- return None
diff --git a/testapp/myauthentication/models_spoken_tutorial.py b/testapp/myauthentication/models_spoken_tutorial.py
deleted file mode 100644
index d333400..0000000
--- a/testapp/myauthentication/models_spoken_tutorial.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# This is an auto-generated Django model module.
-# You'll have to do the following manually to clean this up:
-# * Rearrange models' order
-# * Make sure each model has one field with primary_key=True
-# Feel free to rename the models, but don't rename db_table values or field names.
-#
-# Also note: You'll have to insert the output of 'django-admin.py sqlcustom [appname]'
-# into your database.
-
-from django.db import models
-
-class MoodleUser(models.Model):
- id = models.BigIntegerField(primary_key=True)
- username = models.CharField(unique=True, max_length=300)
- password = models.CharField(max_length=96)
- idnumber = models.CharField(max_length=765)
- firstname = models.CharField(max_length=300)
- lastname = models.CharField(max_length=300)
- email = models.CharField(max_length=300)
- institution = models.CharField(max_length=120)
- department = models.CharField(max_length=90)
- address = models.CharField(max_length=210)
- city = models.CharField(max_length=360)
- country = models.CharField(max_length=6)
- class Meta:
- db_table = u'mdl_user'
diff --git a/testapp/myauthentication/router.py b/testapp/myauthentication/router.py
deleted file mode 100644
index 3d9c330..0000000
--- a/testapp/myauthentication/router.py
+++ /dev/null
@@ -1,12 +0,0 @@
-class MyDatabaseRouter(object):
- """
- A router to manage database operations in the myauthentication app.
- """
- def db_for_read(self, model, **hints):
- """
- Point all read operations on myauthentication app to spoken
- database.
- """
- if model._meta.app_label == 'myauthentication':
- return 'spoken_tutorial'
- return None
diff --git a/testapp/myauthentication/tests.py b/testapp/myauthentication/tests.py
deleted file mode 100644
index 4103038..0000000
--- a/testapp/myauthentication/tests.py
+++ /dev/null
@@ -1,5 +0,0 @@
-#This file demonstrates writing tests using the unittest module. These will pass
-#when you run "manage.py test".
-
-#Write appropriate tests for the application.
-
diff --git a/testapp/myauthentication/urls.py b/testapp/myauthentication/urls.py
deleted file mode 100644
index e69de29..0000000
diff --git a/testapp/myauthentication/views.py b/testapp/myauthentication/views.py
deleted file mode 100644
index 60f00ef..0000000
--- a/testapp/myauthentication/views.py
+++ /dev/null
@@ -1 +0,0 @@
-# Create your views here.
diff --git a/testapp/scripts/__init__.py b/testapp/scripts/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/testapp/scripts/project_detail.py b/testapp/scripts/project_detail.py
deleted file mode 100644
index 583e9f4..0000000
--- a/testapp/scripts/project_detail.py
+++ /dev/null
@@ -1,2 +0,0 @@
-NAME = None
-PATH = None
diff --git a/testapp/scripts/yaksh.py b/testapp/scripts/yaksh.py
deleted file mode 100644
index 8b3e8b7..0000000
--- a/testapp/scripts/yaksh.py
+++ /dev/null
@@ -1,147 +0,0 @@
-from __future__ import print_function
-
-import subprocess
-import contextlib
-import os
-from os import path
-import argparse
-from importlib import import_module
-from django.conf import settings
-from django.core import management
-from django.template import Template, Context, loader
-
-from project_detail import NAME, PATH
-
-CUR_DIR = os.getcwd()
-SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
-PARENT_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir))
-TEMPLATE_DIR = path.join(PARENT_DIR, 'templates')
-
-def main():
- #Parse command-line to obtain the arguments and/or options
- # create top-level parser object
- parser = argparse.ArgumentParser(prog="vimarsh")
- subparser = parser.add_subparsers(dest="subcommand")
-
- # create parser for the "create_demo" subcommand
- create_demo_parser = subparser.add_parser("create_demo",
- help="Create a new demo Django project")
- create_demo_parser.add_argument("project_name", type=str,
- help="name of demo Django project")
- create_demo_parser.add_argument("-p", "--path", type=str,
- help="path of demo Django project")
-
- # create parser for the "run_demo" subcommand
- run_demo_parser = subparser.add_parser("run_demo",
- help="Initialise django server and run the demo project")
-
- # create parser for the "run_code_server" subcommand
- code_server_parser = subparser.add_parser("run_code_server",
- help="Initialise Vimarsh code server")
- code_server_parser.add_argument("-P", "--ports", type=int, nargs='+',
- help="code server ports")
-
- args = parser.parse_args()
-
- if args.subcommand == "create_demo":
- if args.path:
- create_demo(args.project_name, args.path)
- else:
- create_demo(args.project_name)
-
- elif args.subcommand == "run_demo":
- try:
- run_demo(NAME, PATH)
- except Exception as e:
- if not NAME or not PATH:
- print("Error: Unable to find Project Name or Path variables\n")
- else:
- print("Error: {0}\n".format(e))
- subparser.print_help()
-
- elif args.subcommand == "run_code_server":
- if args.ports:
- run_server(args.ports)
- else:
- run_server()
-
-def create_demo(project_name='vimarsh_demo', project_dir=CUR_DIR):
- try:
- management.call_command('startproject', project_name, project_dir)
- print("Demo Django project '{0}' created at '{1}'".format(project_name,
- project_dir))
- except Exception, e:
- print("Error: {0}\nExiting Vimarsh Installer".format(e))
-
- if project_dir is None:
- top_dir = path.join(os.getcwd(), project_name)
- else:
- top_dir = project_dir
-
- project_path = path.join(top_dir, project_name)
- fixture_dir = path.join(PARENT_DIR, 'fixtures')
- # Store project details
- _set_project_details(project_name, top_dir)
-
- with _chdir(project_path):
- root_urlconf = "{0}.{1}".format(project_name, 'demo_urls')
- settings_template_path = path.join(TEMPLATE_DIR, 'demo_settings.py')
- settings_target_path = path.join(project_path, 'demo_settings.py')
- settings_context = Context({'project_name': project_name,
- 'root_urlconf': root_urlconf,
- 'fixture_dir': fixture_dir})
- urls_template_path = path.join(TEMPLATE_DIR, 'demo_urls.py')
- urls_target_path = path.join(project_path, 'demo_urls.py')
- command = ("python ../manage.py syncdb "
- "--noinput --settings={0}.demo_settings").format(project_name)
-
- # Create demo_settings file
- _render_demo_files(settings_template_path, settings_target_path, settings_context)
- # Create demo_urls file
- _render_demo_files(urls_template_path, urls_target_path)
- # Run syncdb
- subprocess.call(command, shell=True)
-
-def run_demo(project_name, top_dir):
- with _chdir(top_dir):
- project_path = path.join(top_dir, 'manage.py')
- command = ("python manage.py runserver "
- "--settings={0}.demo_settings").format(project_name)
- subprocess.call(command, shell=True)
-
-def run_server():
- try:
- from testapp.exam import code_server
- code_server.main()
- except Exception as e:
- print("Error: {0}\nExiting Vimarsh code server".format(e))
-
-def _set_project_details(project_name, top_dir):
- file_path = path.join(SCRIPT_DIR, 'project_detail.py')
- detail = "NAME ='{0}'\nPATH ='{1}'".format(project_name, top_dir)
- with open(file_path, 'w') as data_store:
- data_store.write(detail)
-
-def _render_demo_files(template_path, output_path, context=None):
- with open(template_path, 'r') as template_file:
- content = template_file.read()
- if context:
- content = content.decode('utf-8')
- template = Template(content)
- content = template.render(context)
- content = content.encode('utf-8')
-
- with open(output_path, 'w') as new_file:
- new_file.write(content)
-
-@contextlib.contextmanager
-def _chdir(path):
- starting_directory = os.getcwd()
- try:
- os.chdir(path)
- yield
- finally:
- os.chdir(starting_directory)
-
-if __name__ == '__main__':
- main()
diff --git a/testapp/templates/demo_settings.py b/testapp/templates/demo_settings.py
deleted file mode 100644
index ecc1fe3..0000000
--- a/testapp/templates/demo_settings.py
+++ /dev/null
@@ -1,88 +0,0 @@
-"""
-Django settings for my_demo project.
-
-For more information on this file, see
-https://docs.djangoproject.com/en/1.6/topics/settings/
-
-For the full list of settings and their values, see
-https://docs.djangoproject.com/en/1.6/ref/settings/
-"""
-
-# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
-import os
-BASE_DIR = os.path.dirname(os.path.dirname(__file__))
-
-
-# Quick-start development settings - unsuitable for production
-# See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/
-
-# SECURITY WARNING: keep the secret key used in production secret!
-SECRET_KEY = 'TH!S_!S_@_DUMMY_K3Y'
-
-# SECURITY WARNING: don't run with debug turned on in production!
-DEBUG = True
-
-TEMPLATE_DEBUG = True
-
-ALLOWED_HOSTS = []
-
-
-# Application definition
-
-FIXTURE_DIRS = ('{{ fixture_dir }}')
-
-INSTALLED_APPS = (
- 'django.contrib.admin',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.messages',
- 'django.contrib.staticfiles',
- 'testapp.exam',
- 'taggit',
-)
-
-MIDDLEWARE_CLASSES = (
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.common.CommonMiddleware',
- 'django.middleware.csrf.CsrfViewMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.contrib.messages.middleware.MessageMiddleware',
- 'django.middleware.clickjacking.XFrameOptionsMiddleware',
-)
-
-ROOT_URLCONF = '{{ root_urlconf }}'
-
-WSGI_APPLICATION = '{{ project_name }}.wsgi.application'
-
-
-# Database
-# https://docs.djangoproject.com/en/1.6/ref/settings/#databases
-
-DATABASES = {
- 'default': {
- 'ENGINE': 'django.db.backends.sqlite3',
- 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
- }
-}
-
-# Internationalization
-# https://docs.djangoproject.com/en/1.6/topics/i18n/
-
-LANGUAGE_CODE = 'en-us'
-
-TIME_ZONE = 'UTC'
-
-USE_I18N = True
-
-USE_L10N = True
-
-USE_TZ = False
-
-
-# Static files (CSS, JavaScript, Images)
-# https://docs.djangoproject.com/en/1.6/howto/static-files/
-
-STATIC_URL = '/static/'
-
-AUTH_PROFILE_MODULE = 'exam.Profile'
diff --git a/testapp/templates/demo_urls.py b/testapp/templates/demo_urls.py
deleted file mode 100644
index da8bc2b..0000000
--- a/testapp/templates/demo_urls.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from django.conf.urls import patterns, include, url
-
-from django.contrib import admin
-admin.autodiscover()
-
-urlpatterns = patterns('',
- # Examples:
- # url(r'^$', 'my_demo.views.home', name='home'),
- # url(r'^blog/', include('blog.urls')),
-
- url(r'^admin/', include(admin.site.urls)),
- url(r'^exam/', include('testapp.yaksh.urls')),
-)
diff --git a/testapp/tests/__init__.py b/testapp/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/testapp/tests/test_bash_evaluation.py b/testapp/tests/test_bash_evaluation.py
deleted file mode 100644
index 4f7e4b6..0000000
--- a/testapp/tests/test_bash_evaluation.py
+++ /dev/null
@@ -1,41 +0,0 @@
-import unittest
-import os
-from testapp.yaksh.bash_code_evaluator import BashCodeEvaluator
-from testapp.yaksh.settings import SERVER_TIMEOUT
-
-class BashEvaluationTestCases(unittest.TestCase):
- def setUp(self):
- self.language = "bash"
- self.ref_code_path = "bash_files/sample.sh,bash_files/sample.args"
- self.in_dir = "/tmp"
- self.test_case_data = []
- self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your code.").format(SERVER_TIMEOUT)
- self.test = None
-
- def test_correct_answer(self):
- user_answer = "#!/bin/bash\n[[ $# -eq 2 ]] && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))"
- get_class = BashCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertTrue(result.get("success"))
- self.assertEqual(result.get("error"), "Correct answer")
-
- def test_error(self):
- user_answer = "#!/bin/bash\n[[ $# -eq 2 ]] && echo $(( $1 - $2 )) && exit $(( $1 - $2 ))"
- get_class = BashCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertTrue("Error" in result.get("error"))
-
- def test_infinite_loop(self):
- user_answer = "#!/bin/bash\nwhile [ 1 ] ; do echo "" > /dev/null ; done"
- get_class = BashCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/testapp/tests/test_c_cpp_evaluation.py b/testapp/tests/test_c_cpp_evaluation.py
deleted file mode 100644
index 9cbc013..0000000
--- a/testapp/tests/test_c_cpp_evaluation.py
+++ /dev/null
@@ -1,77 +0,0 @@
-import unittest
-import os
-from testapp.yaksh.cpp_code_evaluator import CppCodeEvaluator
-from testapp.yaksh.settings import SERVER_TIMEOUT
-
-class CEvaluationTestCases(unittest.TestCase):
- def setUp(self):
- self.language = "C"
- self.ref_code_path = "c_cpp_files/main.cpp"
- self.in_dir = "/tmp"
- self.test_case_data = []
- self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your code.").format(SERVER_TIMEOUT)
- self.test = None
-
- def test_correct_answer(self):
- user_answer = "int add(int a, int b)\n{return a+b;}"
- get_class = CppCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertTrue(result.get("success"))
- self.assertEqual(result.get("error"), "Correct answer")
-
- def test_compilation_error(self):
- user_answer = "int add(int a, int b)\n{return a+b}"
- get_class = CppCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertTrue("Compilation Error" in result.get("error"))
-
- def test_infinite_loop(self):
- user_answer = "int add(int a, int b)\n{while(1>0){}}"
- get_class = CppCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
-
-
-###############################################################################
-class CppEvaluationTestCases(unittest.TestCase):
- def setUp(self):
- self.language = "CPP"
- self.ref_code_path = "c_cpp_files/main.cpp"
- self.in_dir = "/tmp"
- self.test_case_data = []
- self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your code.").format(SERVER_TIMEOUT)
- self.test = None
-
- def test_correct_answer(self):
- user_answer = "int add(int a, int b)\n{return a+b;}"
- get_class = CppCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertTrue(result.get("success"))
- self.assertEqual(result.get("error"), "Correct answer")
-
- def test_compilation_error(self):
- user_answer = "int add(int a, int b)\n{return a+b}"
- get_class = CppCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertTrue("Compilation Error" in result.get("error"))
-
- def test_infinite_loop(self):
- user_answer = "int add(int a, int b)\n{while(1>0){}}"
- get_class = CppCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/testapp/tests/test_code_evaluation.py b/testapp/tests/test_code_evaluation.py
deleted file mode 100644
index 10b88b5..0000000
--- a/testapp/tests/test_code_evaluation.py
+++ /dev/null
@@ -1,24 +0,0 @@
-import unittest
-import os
-from testapp.yaksh import python_code_evaluator
-from testapp.yaksh.language_registry import _LanguageRegistry, set_registry, get_registry
-from testapp.yaksh.settings import SERVER_TIMEOUT
-
-
-class RegistryTestCase(unittest.TestCase):
- def setUp(self):
- set_registry()
- self.registry_object = get_registry()
- self.language_registry = _LanguageRegistry()
-
- def test_set_register(self):
- class_name = getattr(python_code_evaluator, 'PythonCodeEvaluator')
- self.registry_object.register("python", "testapp.yaksh.python_code_evaluator.PythonCodeEvaluator")
- self.assertEquals(self.registry_object.get_class("python"), class_name)
-
- def tearDown(self):
- self.registry_object = None
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/testapp/tests/test_java_evaluation.py b/testapp/tests/test_java_evaluation.py
deleted file mode 100644
index 92339e4..0000000
--- a/testapp/tests/test_java_evaluation.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import unittest
-import os
-from testapp.yaksh import code_evaluator as evaluator
-from testapp.yaksh.java_code_evaluator import JavaCodeEvaluator
-
-
-class JavaEvaluationTestCases(unittest.TestCase):
- def setUp(self):
- self.language = "java"
- self.ref_code_path = "java_files/main_square.java"
- self.in_dir = "/tmp"
- self.test_case_data = []
- evaluator.SERVER_TIMEOUT = 9
- self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in "
- "your code.").format(evaluator.SERVER_TIMEOUT)
- self.test = None
-
- def tearDown(self):
- evaluator.SERVER_TIMEOUT = 2
-
- def test_correct_answer(self):
- user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a;\n\t}\n}"
- get_class = JavaCodeEvaluator(self.test_case_data, self.test,
- self.language, user_answer,
- self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertTrue(result.get("success"))
- self.assertEqual(result.get("error"), "Correct answer")
-
- def test_error(self):
- user_answer = "class Test {\n\tint square_num(int a) {\n\treturn a*a"
- get_class = JavaCodeEvaluator(self.test_case_data, self.test,
- self.language, user_answer,
- self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertTrue("Error" in result.get("error"))
-
- def test_infinite_loop(self):
- user_answer = "class Test {\n\tint square_num(int a) {\n\t\twhile(0==0){\n\t\t}\n\t}\n}"
- get_class = JavaCodeEvaluator(self.test_case_data, self.test,
- self.language, user_answer,
- self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/testapp/tests/test_python_evaluation.py b/testapp/tests/test_python_evaluation.py
deleted file mode 100644
index ea01fa8..0000000
--- a/testapp/tests/test_python_evaluation.py
+++ /dev/null
@@ -1,53 +0,0 @@
-import unittest
-import os
-from testapp.yaksh.python_code_evaluator import PythonCodeEvaluator
-from testapp.yaksh.settings import SERVER_TIMEOUT
-
-class PythonEvaluationTestCases(unittest.TestCase):
- def setUp(self):
- self.language = "Python"
- self.test = None
- self.test_case_data = [{"func_name": "add",
- "expected_answer": "5",
- "test_id": u'null',
- "pos_args": ["3", "2"],
- "kw_args": {}
- }]
- self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your code.").format(SERVER_TIMEOUT)
-
- def test_correct_answer(self):
- user_answer = "def add(a, b):\n\treturn a + b"""
- get_class = PythonCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, ref_code_path=None, in_dir=None)
- result = get_class.evaluate()
- self.assertTrue(result.get("success"))
- self.assertEqual(result.get("error"), "Correct answer")
-
- def test_incorrect_answer(self):
- user_answer = "def add(a, b):\n\treturn a - b"
- test_case_data = [{"func_name": "add",
- "expected_answer": "5",
- "test_id": u'null',
- "pos_args": ["3", "2"],
- "kw_args": {}
- }]
- get_class = PythonCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, ref_code_path=None, in_dir=None)
- result = get_class.evaluate()
- self.assertFalse(result.get("success"))
- self.assertEqual(result.get("error"), "AssertionError in: assert add(3, 2) == 5")
-
- def test_infinite_loop(self):
- user_answer = "def add(a, b):\n\twhile True:\n\t\tpass"""
- test_case_data = [{"func_name": "add",
- "expected_answer": "5",
- "test_id": u'null',
- "pos_args": ["3", "2"],
- "kw_args": {}
- }]
- get_class = PythonCodeEvaluator(self.test_case_data, self.test, self.language, user_answer, ref_code_path=None, in_dir=None)
- result = get_class.evaluate()
- self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/testapp/tests/test_scilab_evaluation.py b/testapp/tests/test_scilab_evaluation.py
deleted file mode 100644
index 4d05426..0000000
--- a/testapp/tests/test_scilab_evaluation.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import unittest
-import os
-from testapp.yaksh.scilab_code_evaluator import ScilabCodeEvaluator
-from testapp.yaksh.settings import SERVER_TIMEOUT
-
-class ScilabEvaluationTestCases(unittest.TestCase):
- def setUp(self):
- self.language = "scilab"
- self.ref_code_path = "scilab_files/test_add.sce"
- self.in_dir = "/tmp"
- self.test_case_data = []
- self.timeout_msg = ("Code took more than {0} seconds to run. "
- "You probably have an infinite loop in your code.").format(SERVER_TIMEOUT)
- self.test = None
-
- def test_correct_answer(self):
- user_answer = "funcprot(0)\nfunction[c]=add(a,b)\n\tc=a+b;\nendfunction"
- get_class = ScilabCodeEvaluator(self.test_case_data, self.test,
- self.language, user_answer,
- self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertTrue(result.get("success"))
- self.assertEqual(result.get("error"), "Correct answer")
-
- def test_error(self):
- user_answer = "funcprot(0)\nfunction[c]=add(a,b)\n\tc=a+b;\ndis(\tendfunction"
- get_class = ScilabCodeEvaluator(self.test_case_data, self.test,
- self.language, user_answer,
- self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertTrue("error" in result.get("error"))
-
- def test_infinite_loop(self):
- user_answer = "funcprot(0)\nfunction[c]=add(a,b)\n\tc=a;\nwhile(1==1)\nend\nendfunction"
- get_class = ScilabCodeEvaluator(self.test_case_data, self.test,
- self.language, user_answer,
- self.ref_code_path, self.in_dir)
- result = get_class.evaluate()
-
- self.assertFalse(result.get("success"))
- self.assertEquals(result.get("error"), self.timeout_msg)
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/testapp/urls.py b/testapp/urls.py
deleted file mode 100644
index 7022b0d..0000000
--- a/testapp/urls.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from django.conf.urls import patterns, include, url
-
-# Uncomment the next two lines to enable the admin:
-from django.contrib import admin
-admin.autodiscover()
-
-from settings import URL_ROOT
-
-if URL_ROOT.startswith('/'):
- URL_BASE = r'^%s/exam/'%URL_ROOT[1:]
- ADMIN_BASE = r'^%s/admin/'%URL_ROOT[1:]
-else:
- URL_BASE = r'^exam/'
- ADMIN_BASE = r'^admin/'
-
-urlpatterns = patterns('',
- url(URL_BASE, include('yaksh.urls')),
- #url(r'^admin/', include(admin.site.urls)),
- # Uncomment the admin/doc line below to enable admin documentation:
- # url(r'^admin/doc/', include('django.contrib.admindocs.urls')),
- # Uncomment the next line to enable the admin:
- url(ADMIN_BASE, include(admin.site.urls)),
-
-)
-
-urlpatterns += patterns('',
- url(r'^taggit_autocomplete_modified/', include\
- ('taggit_autocomplete_modified.urls')),
-)
diff --git a/testapp/yaksh/__init__.py b/testapp/yaksh/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/testapp/yaksh/admin.py b/testapp/yaksh/admin.py
deleted file mode 100644
index ed0afde..0000000
--- a/testapp/yaksh/admin.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from testapp.yaksh.models import Question, Quiz, TestCase
-from django.contrib import admin
-
-admin.site.register(Question)
-admin.site.register(TestCase)
-admin.site.register(Quiz)
diff --git a/testapp/yaksh/bash_code_evaluator.py b/testapp/yaksh/bash_code_evaluator.py
deleted file mode 100644
index a468fd7..0000000
--- a/testapp/yaksh/bash_code_evaluator.py
+++ /dev/null
@@ -1,122 +0,0 @@
-#!/usr/bin/env python
-import traceback
-import pwd
-import os
-from os.path import join, isfile
-import subprocess
-import importlib
-
-# local imports
-from code_evaluator import CodeEvaluator
-
-
-class BashCodeEvaluator(CodeEvaluator):
- """Tests the Bash code obtained from Code Server"""
- def __init__(self, test_case_data, test, language, user_answer,
- ref_code_path=None, in_dir=None):
- super(BashCodeEvaluator, self).__init__(test_case_data, test, language, user_answer,
- ref_code_path, in_dir)
- self.test_case_args = self._setup()
-
- # Private Protocol ##########
- def _setup(self):
- super(BashCodeEvaluator, self)._setup()
-
- self.submit_path = self.create_submit_code_file('submit.sh')
- self._set_file_as_executable(self.submit_path)
- get_ref_path, get_test_case_path = self.ref_code_path.strip().split(',')
- get_ref_path = get_ref_path.strip()
- get_test_case_path = get_test_case_path.strip()
- ref_path, test_case_path = self._set_test_code_file_path(get_ref_path,
- get_test_case_path)
-
- return ref_path, self.submit_path, test_case_path
-
- def _teardown(self):
- # Delete the created file.
- super(BashCodeEvaluator, self)._teardown()
- os.remove(self.submit_path)
-
- def _check_code(self, ref_path, submit_path,
- test_case_path=None):
- """ Function validates student script using instructor script as
- reference. Test cases can optionally be provided. The first argument
- ref_path, is the path to instructor script, it is assumed to
- have executable permission. The second argument submit_path, is
- the path to the student script, it is assumed to have executable
- permission. The Third optional argument is the path to test the
- scripts. Each line in this file is a test case and each test case is
- passed to the script as standard arguments.
-
- Returns
- --------
-
- returns (True, "Correct answer") : If the student script passes all
- test cases/have same output, when compared to the instructor script
-
- returns (False, error_msg): If the student script fails a single
- test/have dissimilar output, when compared to the instructor script.
-
- Returns (False, error_msg): If mandatory arguments are not files or if
- the required permissions are not given to the file(s).
-
- """
- if not isfile(ref_path):
- return False, "No file at %s or Incorrect path" % ref_path
- if not isfile(submit_path):
- return False, "No file at %s or Incorrect path" % submit_path
- if not os.access(ref_path, os.X_OK):
- return False, "Script %s is not executable" % ref_path
- if not os.access(submit_path, os.X_OK):
- return False, "Script %s is not executable" % submit_path
-
- success = False
-
- if test_case_path is None or "":
- ret = self._run_command(ref_path, stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- proc, inst_stdout, inst_stderr = ret
- ret = self._run_command(submit_path, stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- proc, stdnt_stdout, stdnt_stderr = ret
- if inst_stdout == stdnt_stdout:
- return True, "Correct answer"
- else:
- err = "Error: expected %s, got %s" % (inst_stderr,
- stdnt_stderr)
- return False, err
- else:
- if not isfile(test_case_path):
- return False, "No test case at %s" % test_case_path
- if not os.access(ref_path, os.R_OK):
- return False, "Test script %s, not readable" % test_case_path
- # valid_answer is True, so that we can stop once a test case fails
- valid_answer = True
- # loop_count has to be greater than or equal to one.
- # Useful for caching things like empty test files,etc.
- loop_count = 0
- test_cases = open(test_case_path).readlines()
- num_lines = len(test_cases)
- for test_case in test_cases:
- loop_count += 1
- if valid_answer:
- args = [ref_path] + [x for x in test_case.split()]
- ret = self._run_command(args, stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- proc, inst_stdout, inst_stderr = ret
- args = [submit_path]+[x for x in test_case.split()]
- ret = self._run_command(args, stdin=None,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- proc, stdnt_stdout, stdnt_stderr = ret
- valid_answer = inst_stdout == stdnt_stdout
- if valid_answer and (num_lines == loop_count):
- return True, "Correct answer"
- else:
- err = "Error:expected %s, got %s" % (inst_stdout+inst_stderr,
- stdnt_stdout+stdnt_stderr)
- return False, err
-
diff --git a/testapp/yaksh/bash_files/sample.args b/testapp/yaksh/bash_files/sample.args
deleted file mode 100644
index 4d9f00d..0000000
--- a/testapp/yaksh/bash_files/sample.args
+++ /dev/null
@@ -1,2 +0,0 @@
-1 2
-2 1
diff --git a/testapp/yaksh/bash_files/sample.sh b/testapp/yaksh/bash_files/sample.sh
deleted file mode 100755
index e935cb3..0000000
--- a/testapp/yaksh/bash_files/sample.sh
+++ /dev/null
@@ -1,2 +0,0 @@
-#!/bin/bash
-[[ $# -eq 2 ]] && echo $(( $1 + $2 )) && exit $(( $1 + $2 ))
diff --git a/testapp/yaksh/c_cpp_files/main.cpp b/testapp/yaksh/c_cpp_files/main.cpp
deleted file mode 100755
index ebe1f08..0000000
--- a/testapp/yaksh/c_cpp_files/main.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include fact
which takes a single integer argument
-(say n
) and returns the factorial of the number.
-For example:fact(3) -> 6
-''',
- test='''
-assert fact(0) == 1
-assert fact(5) == 120
-''',
- snippet="def fact(num):"
- ),
-#Add tags here as a list of string.
-['Python','function','factorial'],
-],
-
-[Question(
- summary='Simple function',
- points=1,
- language='python',
- type='code',
- description='''Create a simple function called sqr
which takes a single
-argument and returns the square of the argument. For example: sqr(3) -> 9
.''',
- test='''
-import math
-assert sqr(3) == 9
-assert abs(sqr(math.sqrt(2)) - 2.0) < 1e-14
- ''',
- snippet="def sqr(num):"
- ),
-#Add tags here as a list of string.
-['Python','function'],
-],
-
-[Question(
- summary='Bash addition',
- points=2,
- language='bash',
- type='code',
- description='''Write a shell script which takes two arguments on the
- command line and prints the sum of the two on the output.''',
- test='''\
-docs/sample.sh
-docs/sample.args
-''',
- snippet="#!/bin/bash"
- ),
-#Add tags here as a list of string.
-[''],
-],
-
-[Question(
- summary='Size of integer in Python',
- points=0.5,
- language='python',
- type='mcq',
- description='''What is the largest integer value that can be represented
-in Python?''',
- options='''No Limit
-2**32
-2**32 - 1
-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,
- description='Basic Python Quiz 1'
- )
diff --git a/testapp/yaksh/docs/sample_questions.xml b/testapp/yaksh/docs/sample_questions.xml
deleted file mode 100644
index 53c76f8..0000000
--- a/testapp/yaksh/docs/sample_questions.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, -CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, -g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, -text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, -setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= -h[3];l=0;for(m=h.length;l =0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== -"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, -h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l ";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& -q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; -if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); -(function(){var g=s.createElement("div");g.innerHTML="";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: -function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q =0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f
0)for(var j=d;j 0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= -{},i;if(f&&a.length){e=0;for(var o=a.length;e -1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== -"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", -d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? -a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== -1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"+d+">"},F={option:[1,""],legend:[1,""],thead:[1," ","
"],tr:[2,"","
"],td:[3,""],col:[2,"
"," "],area:[1,""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
"," ",""];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= -c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, -wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, -prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b, -this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); -return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, -""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); -return this}else{e=0;for(var j=d.length;e 0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", -""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===" "&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= -c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? -c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= -function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= -Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, -"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= -a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= -a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=/ - -{% endblock %} - -{% block onload %} onload='javascript:textareaformat();' {% endblock %} - -{% block manage %} - -{% endblock %} - diff --git a/testapp/yaksh/templates/yaksh/add_questionpaper.html b/testapp/yaksh/templates/yaksh/add_questionpaper.html deleted file mode 100644 index eaa96bc..0000000 --- a/testapp/yaksh/templates/yaksh/add_questionpaper.html +++ /dev/null @@ -1,27 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - -{% endblock %} -{% block script %} - - -{% endblock %} - -{% block manage %} - -
-{% csrf_token %} -Select mode to design Question Paper: - - - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/add_quiz.html b/testapp/yaksh/templates/yaksh/add_quiz.html deleted file mode 100644 index e78023d..0000000 --- a/testapp/yaksh/templates/yaksh/add_quiz.html +++ /dev/null @@ -1,25 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Add Quiz{% endblock %} - -{% block css %} - -{% endblock %} -{% block script %} - -{% endblock %} -{% block onload %} onload="javascript:test();" {% endblock %} -{% block manage %} -- {% csrf_token %} - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/ajax_marks.html b/testapp/yaksh/templates/yaksh/ajax_marks.html deleted file mode 100644 index 716bb88..0000000 --- a/testapp/yaksh/templates/yaksh/ajax_marks.html +++ /dev/null @@ -1,4 +0,0 @@ - -{% for mark in marks %} - -{% endfor %} diff --git a/testapp/yaksh/templates/yaksh/ajax_question_filter.html b/testapp/yaksh/templates/yaksh/ajax_question_filter.html deleted file mode 100644 index 11bf660..0000000 --- a/testapp/yaksh/templates/yaksh/ajax_question_filter.html +++ /dev/null @@ -1,15 +0,0 @@ -- - -- {{ form.as_table }} -
-- -- {% if questions %} -diff --git a/testapp/yaksh/templates/yaksh/ajax_questions.html b/testapp/yaksh/templates/yaksh/ajax_questions.html deleted file mode 100644 index e343f9b..0000000 --- a/testapp/yaksh/templates/yaksh/ajax_questions.html +++ /dev/null @@ -1,31 +0,0 @@ -Select All
- {% endif %} -- - {% for question in questions %} -
-- - -
- {% endfor %} -- {% if questions %} - - Select All - {% endif %} -- -- - {% for question in questions %} -
-- - -
- {% endfor %} -- -diff --git a/testapp/yaksh/templates/yaksh/automatic_questionpaper.html b/testapp/yaksh/templates/yaksh/automatic_questionpaper.html deleted file mode 100644 index b9a4ae0..0000000 --- a/testapp/yaksh/templates/yaksh/automatic_questionpaper.html +++ /dev/null @@ -1,87 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - - -{% endblock %} -{% block script %} - - -{% endblock %} - -{% block manage %} - -Automatic mode to design the Question Paper
-- {% csrf_token %} - - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/complete.html b/testapp/yaksh/templates/yaksh/complete.html deleted file mode 100644 index 08abe76..0000000 --- a/testapp/yaksh/templates/yaksh/complete.html +++ /dev/null @@ -1,33 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Good bye!{% endblock %} - -{% block pagetitle %}Online Test{% endblock %} -{% block content %} -{% csrf_token %} - {% if submitted or unattempted %} -- Tag Conditions: - - - - - - - - - - - -
- -Number of question: - -
-
-Below is the list of Questions fetched according to the given tag conditions
-
--
- {% if data.msg %}Summary - Type - Points - Tags - {% for question in data.questions %} - - - {{ question.summary }} {{ question.type }} {{ question.points }} - {% for tag in question.tags.all %} - {{ tag }} - {% endfor %} -
- {% endfor %} -{{ data.msg }}{% endif %} -- - {% endif %} - -
- Submitted Questions -- {% if submitted %} - {{ submitted|join:", " }} - {% else %} - No Questions have been Submitted
- {% endif %} -- Unattempted Questions -- {% if unattempted %} - {{ unattempted|join:", " }} - {% else %} - All Questions have been Submitted
- {% endif %} -- Good bye!
- {{message}}
You may now close the browser.
-Login Again -{% endblock content %} diff --git a/testapp/yaksh/templates/yaksh/design_questionpaper.html b/testapp/yaksh/templates/yaksh/design_questionpaper.html deleted file mode 100644 index 2aa169b..0000000 --- a/testapp/yaksh/templates/yaksh/design_questionpaper.html +++ /dev/null @@ -1,182 +0,0 @@ -{% extends "manage.html" %} - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - - - - -{% endblock %} -{% block script %} - - - - - - -{% endblock %} - -{% block manage %} - -Manual mode to design the {{lang}} Question Paper
--
- -- - - STEP 1
-
- Add Fixed Questions - -- - - STEP 2
-
- Add Random Questions - -- - - STEP 3
-
- Finish -{% csrf_token %} - ---Total Marks: 0
-- -- ---Please select Question type and Marks
-- {{ form.question_type }} --- {{ form.marks }} --- --
- - - - - - - ---- -Almost finished creating your question paper
-
- - -
-- < Previous --
- - - --- --- --- - - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/edit_question.html b/testapp/yaksh/templates/yaksh/edit_question.html deleted file mode 100644 index 9a66250..0000000 --- a/testapp/yaksh/templates/yaksh/edit_question.html +++ /dev/null @@ -1,61 +0,0 @@ -{% extends "manage.html" %} - -{% block subtitle %}Edit Question{% endblock %} - -{% block css %} - - -{% endblock %} -{% block script %} - - -{% endblock %} - -{% block onload %} onload = 'javascript:textareaformat();' {% endblock %} - -{% block manage %} --- -- {% csrf_token %} - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/edit_quiz.html b/testapp/yaksh/templates/yaksh/edit_quiz.html deleted file mode 100644 index fb7df93..0000000 --- a/testapp/yaksh/templates/yaksh/edit_quiz.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Edit Quiz(zes){% endblock %} - -{% block css %} - -{% endblock %} - -{% block script %} - -{% endblock %} - -{% block onload %} onload = 'javascript:form_load();' {% endblock %} - -{% block manage %} -- - Click on the Question links to edit the question.
- - {% for question, test in data_list %} - -
- - -{% for i in data %} - -{% endfor %} - -{{question.summary.value}} - - - {% endfor %} - - -- {% csrf_token %} - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/editquestionpaper.html b/testapp/yaksh/templates/yaksh/editquestionpaper.html deleted file mode 100644 index 2b7b835..0000000 --- a/testapp/yaksh/templates/yaksh/editquestionpaper.html +++ /dev/null @@ -1,21 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Questions in "{{ papers.quiz.description }}"{% endblock %} - -{% block script %} - -{% endblock %} - -{% block manage %} -- -{% for i in data %} - -{% endfor %} -- {% for form in forms %} -
-Start Date: {{ form.start_date}} - Duration: {{ form.duration }}
{{form.duration.help_text}} -Active: {{ form.active }} - Description: {{ form.description }} - Passing Criteria: {{ form.pass_criteria }}
{{form.pass_criteria.help_text}} -Language: {{ form.language }} - Prerequisite: {{ form.prerequisite }} -
- {% endfor %} -- --{% csrf_token %} - -{% for i in papers.questions %} - {{ i.summary}} -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/grade_user.html b/testapp/yaksh/templates/yaksh/grade_user.html deleted file mode 100644 index 8c094a7..0000000 --- a/testapp/yaksh/templates/yaksh/grade_user.html +++ /dev/null @@ -1,94 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Grading papers for {{ data.user.get_full_name.title }} {% endblock title %} - -{% block subtitle %}Grading papers for {{ data.user.get_full_name.title }}{% endblock %} - -{% block css %} - -{% endblock %} - -{% block script %} - -{% endblock %} -{% block manage %} - -
-{% endfor %} -
- - --Name: {{ data.user.get_full_name.title }} -{% if data.profile %} -(roll number: {{ data.profile.roll_number }})
- -{% if data.papers %} - -{% for paper in data.papers %} - -
-{{ data.profile.position }}, -{{ data.profile.department }}, -{{ data.profile.institute }} -{% endif %} -Quiz: {{ paper.quiz.description }}
- --Questions correctly answered: {{ paper.get_answered_str }}
- -{% if paper.answers.count %} -
-Total attempts at questions: {{ paper.answers.count }}
-Marks obtained: {{ paper.get_total_marks }}
-Start time: {{ paper.start_time }}
-Answers
--{% csrf_token %} -{% for question, answers in paper.get_question_answers.items %} - -{% endif %} {# if paper.answers.count #} - -{% endfor %} {# for paper in data.papers #} - -{% endif %} {# if data.papers #} - -{% endblock%} diff --git a/testapp/yaksh/templates/yaksh/intro.html b/testapp/yaksh/templates/yaksh/intro.html deleted file mode 100644 index 9c5c14d..0000000 --- a/testapp/yaksh/templates/yaksh/intro.html +++ /dev/null @@ -1,53 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Instructions and Rules {% endblock %} -{% block pagetitle %}Online Test {% endblock %} -{% block formtitle %}Important instructions & rules {% endblock %} -{% block content %} - - {% if enable_quiz_time or disable_quiz_time %} - {% if quiz_expired %} ---{% endfor %} {# for question, answers ... #} - - -- Question: {{ question.id }}. {{ question.summary }} (Points: {{ question.points }}) - -Details
--- -- -{% if question.type == "mcq" %} --
-Choices: -{% for option in question.options.strip.splitlines %} {{option}}, {% endfor %} -
-Student answer: {{ answers.0 }}
-{% else %}{# non-mcq questions #} --{% for answer in answers %}################################################################################ -{{ answer.answer.strip }} -# Autocheck: {{ answer.error }} -{% endfor %}-{% endif %} {# if question.type #} -{% with answers|last as answer %} -Marks:
-{% endwith %} -Teacher comments:
- -
-
- -- This Quiz has expired. You can no longer attempt this Quiz. -- {% else %} -
-- You can attempt this Quiz at any time between {{ enable_quiz_time }} and {{ disable_quiz_time }} -- {% endif %} - {% endif %} -
- You are not allowed to attempt the Quiz before or after this duration -
-Welcome {{user.first_name.title}} {{user.last_name.title}}, to the programming quiz!
-- This examination system has been developed with the intention of making you - learn programming and be assessed in an interactive and fun manner. - You will be presented with a series of programming questions and problems that - you will answer online and get immediate feedback for. -
-Here are some important instructions and rules that you should understand carefully.
--
-- For any programming questions, you can submit solutions as many times as you want without a penalty. You may skip questions and solve them later. -
-- You may use your computer's Python/IPython shell or an editor to solve the problem and cut/paste the solution to the web interface. -
-- You are not allowed to use any internet resources, i.e. no google etc.
-- Do not copy or share the questions or answers with anyone until the exam is complete for everyone.
-- All your attempts at the questions are logged. Do not try to outsmart and break the testing system. If you do, we know who you are and we will expell you from the course. You have been warned. -
-We hope you enjoy taking this exam !!!
- -- {% csrf_token %} - - {% if not quiz_expired %} -- - {% csrf_token %} - - {% endif %} -{% endblock content %} diff --git a/testapp/yaksh/templates/yaksh/login.html b/testapp/yaksh/templates/yaksh/login.html deleted file mode 100644 index dfeac1e..0000000 --- a/testapp/yaksh/templates/yaksh/login.html +++ /dev/null @@ -1,22 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Login{% endblock title %} -{% block pagetitle %} Online Test {% endblock %} -{% block formtitle %}Login{% endblock %} -{% block css %} - -{% endblock %} -{% block content %} - -- - {% csrf_token %} - - - -{% endblock content %} diff --git a/testapp/yaksh/templates/yaksh/manual_questionpaper.html b/testapp/yaksh/templates/yaksh/manual_questionpaper.html deleted file mode 100644 index 86bfd67..0000000 --- a/testapp/yaksh/templates/yaksh/manual_questionpaper.html +++ /dev/null @@ -1,79 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}Design Question Paper{% endblock %} - -{% block css %} - - - -{% endblock %} -{% block script %} - - -{% endblock %} - -{% block manage %} - -- - {{ form.as_table }} -
- Forgot Password?
-New User? Sign-Up -Manual mode to design the Question Paper
- -- {% csrf_token %} - - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/monitor.html b/testapp/yaksh/templates/yaksh/monitor.html deleted file mode 100644 index 52695cb..0000000 --- a/testapp/yaksh/templates/yaksh/monitor.html +++ /dev/null @@ -1,69 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Quiz results {% endblock title %} - -{% block meta %} {% endblock meta %} - -{% block css %} - -{% endblock %} -{% block subtitle %} - {% if not quizzes and not quiz %} - Quiz Results - {% endif %} - {% if quizzes %} - Available Quizzes - {% endif %} - {% if quiz %} - {{ quiz.description }} Results - {% endif %} -{% endblock %} -{% block manage %} - {% if not quizzes and not quiz %} -- Tag Conditions: - - - - - - -
-- -
Below is the list of Questions fetched according to the given tag conditions
--
- {% if data.msg %}- Summary - Type - Points - Tags - {% for question in data.questions %} - - {{ question.summary }} {{ question.type }} {{ question.points }} - {% for tag in question.tags.all %} - {{ tag }} - {% endfor %} -
- {% endfor %} -{{ data.msg }}{% endif %} -- - {% endif %} - -{# ############################################################### #} -{# This is rendered when we are just viewing exam/monitor #} -{% if quizzes %} - No quizzes available.
-{% for q in quizzes %} -
-{% endif %} - -{# ############################################################### #} -{# This is rendered when we are just viewing exam/monitor/quiz_num #} -{% if quiz %} - -{% if papers %} -{#- {{ q.quiz.description }}
-{% endfor %} -Quiz: {{ quiz_name }}
#} -Number of papers: {{ papers|length }}
--
-{% else %} -- - {% for paper in papers %} -Name -Username -Roll number -Institute -Questions answered -Marks obtained -Attempts -- - {% endfor %} -{{ paper.user.get_full_name.title }} -{{ paper.user.username }} -{{ paper.profile.roll_number }} -{{ paper.profile.institute }} -{{ paper.get_answered_str }} -{{ paper.marks_obtained }} -{{ paper.answers.count }} -No answer papers so far.
-{% endif %} {# if papers #} -{% endif %} -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/question.html b/testapp/yaksh/templates/yaksh/question.html deleted file mode 100644 index e532513..0000000 --- a/testapp/yaksh/templates/yaksh/question.html +++ /dev/null @@ -1,203 +0,0 @@ -{% extends "base.html" %} - - - -{% block title %} Answer question {% endblock %} - -{% block css %} - - -{% endblock %} - -{% block script %} - - - - - -{% endblock script %} - - - -{% block onload %} onload="update_time();setSnippetHeight()" {% endblock %} - -{% block pagetitle %} - -- -{% endblock %} - -{% block content %} - -
-You have {{ paper.questions_left }} question(s) left in {{ quiz_name }}
- ---- - -{{ question.summary }} (Marks : {{ question.points }})
- {{ question.description|safe }} - {% if error_message %} -- {% for e in error_message.splitlines %} - {{ e|join:"" }} -{% endif %} - - - -
- {% endfor%} -- {% csrf_token %} - - - {% if question.type == "mcq" %} - {% for option in question.options.strip.splitlines %} - {{option}} - - - -
- {% endfor %} - {% endif %} - {% if question.type == "upload" %} -Upload assignment file for the said question
- -
- {% endif %} - {% if question.type == "mcc" %} - {% for option in question.options.strip.splitlines %} - {{ option }} -
- {% endfor %} - {% endif %} - {% if question.type == "code" %} - - - - -
- - - - {% endif %} - - {% if question.type == "mcq" or question.type == "mcc "%} -
- {% elif question.type == "upload" %} -
- {% else %} - - {% endif %} - {% if to_attempt|length != 1 %} - - {% endif %} --- -{% endblock content %} diff --git a/testapp/yaksh/templates/yaksh/quit.html b/testapp/yaksh/templates/yaksh/quit.html deleted file mode 100644 index 91bce64..0000000 --- a/testapp/yaksh/templates/yaksh/quit.html +++ /dev/null @@ -1,35 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Quit exam {% endblock %} -{% block pagetitle %}Online Test {% endblock %} -{% block content %} - {% if submitted or unattempted %} --- -- {% endif %} - - -
- Submitted Questions -- {% if submitted %} - {{ submitted|join:", " }} - {% else %} - No Questions have been Submitted
- {% endif %} -- Unattempted Questions -- {% if unattempted %} - {{ unattempted|join:", " }} - {% else %} - All Questions have been Submitted
- {% endif %} -- Your current answers are saved.
- Are you sure you wish to quit the exam?
- Be sure, as you won't be able to restart this exam.
- {% csrf_token %} - -{% endblock content %} diff --git a/testapp/yaksh/templates/yaksh/quizlist.html b/testapp/yaksh/templates/yaksh/quizlist.html deleted file mode 100644 index 9b1fd73..0000000 --- a/testapp/yaksh/templates/yaksh/quizlist.html +++ /dev/null @@ -1,24 +0,0 @@ -{% extends "base.html" %} - -{% block title %} Quiz List {% endblock title %} - -{% block formtitle %} Quiz List {% endblock %} - -{% block pagetitle %} Online Test {% endblock %} - -{% block content %} -{% if not quizzes and not quiz %} -- -{% endif %} - -{% if quizzes %} - No quizzes available.
-{% csrf_token %} - -{% for quiz in quizzes %} -{{ quiz.description }} -{% endif %} - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/quizzes_user.html b/testapp/yaksh/templates/yaksh/quizzes_user.html deleted file mode 100644 index fbd50ce..0000000 --- a/testapp/yaksh/templates/yaksh/quizzes_user.html +++ /dev/null @@ -1,87 +0,0 @@ -{% extends "user.html" %} - - -{% block subtitle %}Hello {{ user.first_name }}, welcome to your dashboard !{% endblock %} - -{% block css %} - -{% endblock %} - -{% block script %} - - -{% endblock %} - - -{% block manage %} - {% if cannot_attempt %} -
-{% endfor %} -You have not passed the prerequisite & hence you cannot take the quiz.
- {% endif %} -List of quizzes availbale for you
- {% if not quizzes %} -No active quizzes for you
- {% endif %} --
-Quiz -Pre requisite quiz - {% for paper in quizzes %} -- {% if paper in unexpired_quizzes %} - - {% endfor %} -- {{ paper.quiz.description }} - {% else %} -
-- {{ paper.quiz.description }} Expired - {% endif %} -
-- {% if paper.quiz.prerequisite %} - You have to pass {{ paper.quiz.prerequisite.description }} for taking {{ paper.quiz.description }} - {% else %} - No pre requisites for {{ paper.quiz.description }} - {% endif %} - -
-List of quizzes taken by you so far
- {% if quizzes_taken %} --
- {% else %} -Quiz -Result -Mraks Obtained -Total Marks -Percentage - {% for paper in quizzes_taken %} -- - {% endfor %} -- {{ paper.question_paper.quiz.description }} - -- {% if paper.passed %} - -Pass
- {% else %} -Fail
- {% endif %} -- {{ paper.marks_obtained }} - -- {{ paper.question_paper.total_marks }} - -- {{ paper.percent }} - -You have not taken any quiz yet !!
- {% endif %} - - -{% endblock %} - diff --git a/testapp/yaksh/templates/yaksh/register.html b/testapp/yaksh/templates/yaksh/register.html deleted file mode 100644 index 5ff79cc..0000000 --- a/testapp/yaksh/templates/yaksh/register.html +++ /dev/null @@ -1,20 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Registration form {% endblock %} - -{% block pagetitle %}Online Test {% endblock %} -{% block formtitle %}Please fill in the following details {% endblock %} - -{% block content %} - - - -- {% csrf_token %} - - -{% endblock content %} diff --git a/testapp/yaksh/templates/yaksh/results_user.html b/testapp/yaksh/templates/yaksh/results_user.html deleted file mode 100644 index 0f35c0d..0000000 --- a/testapp/yaksh/templates/yaksh/results_user.html +++ /dev/null @@ -1,28 +0,0 @@ -{% extends "user.html" %} - - -{% block subtitle %}Results{% endblock %} - -{% block css %} - -{% endblock %} - -{% block manage %} -- - {{ form.as_table }} -
- - {% csrf_token %} - -{% endblock %} - diff --git a/testapp/yaksh/templates/yaksh/show_quiz.html b/testapp/yaksh/templates/yaksh/show_quiz.html deleted file mode 100644 index 2cd4e11..0000000 --- a/testapp/yaksh/templates/yaksh/show_quiz.html +++ /dev/null @@ -1,33 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Quiz List {% endblock title %} - -{% block script %} - -{% endblock %} - -{% block subtitle %} Quiz List {% endblock %} -{% block manage %} -{% if not quizzes and not quiz %} -- -
Quiz Description - Obtained Marks - Maximum Marks - Percentage - {% for paper in papers %} - - {% for i in paper %} - {{ i }} - {% endfor %} -
- {% endfor %} -- -{% endif %} - -{# ############################################################### #} -{# This is rendered when we are just viewing exam/monitor #} -{% if quizzes %} - No quizzes available.
-{% csrf_token %} - -{% for quiz in quizzes %} - {{ quiz.description }} -{% endif %} - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/showquestionpapers.html b/testapp/yaksh/templates/yaksh/showquestionpapers.html deleted file mode 100644 index e705ce7..0000000 --- a/testapp/yaksh/templates/yaksh/showquestionpapers.html +++ /dev/null @@ -1,23 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}List of Question Papers {% endblock %} - -{% block script %} - -{% endblock %} - -{% block manage %} -{% if papers %} -
-{% endfor %} - -
- - - --{% csrf_token %} -{% for i in papers %} - {{ i.quiz.description }} -{% else %} -
-{% endfor %} -
- --{% endif %} -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/showquestions.html b/testapp/yaksh/templates/yaksh/showquestions.html deleted file mode 100644 index 6222d6d..0000000 --- a/testapp/yaksh/templates/yaksh/showquestions.html +++ /dev/null @@ -1,44 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %}List of Questions {% endblock %} - -{% block script %} - - - -{% endblock %} - -{% block manage %} - No Question Papers available
-{% csrf_token %} - -{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/showusers.html b/testapp/yaksh/templates/yaksh/showusers.html deleted file mode 100644 index ae91076..0000000 --- a/testapp/yaksh/templates/yaksh/showusers.html +++ /dev/null @@ -1,26 +0,0 @@ -{% extends "manage.html" %} - - -{% block subtitle %} -List of Users -{% endblock %} - -{% block css %} - -{% endblock css %} - - -{% block manage %} ---Filters
-- {{ form.question_type }} --- {{ form.language }} --- {{ form.marks }} --
---- --
--{% for i in questions %} - {{ i }}-
-{% endfor %} -
- - - --{% endblock %} diff --git a/testapp/yaksh/templates/yaksh/user_data.html b/testapp/yaksh/templates/yaksh/user_data.html deleted file mode 100644 index 61a3a97..0000000 --- a/testapp/yaksh/templates/yaksh/user_data.html +++ /dev/null @@ -1,80 +0,0 @@ -{% extends "manage.html" %} - -{% block title %} Data for user {{ data.user.get_full_name.title }} {% endblock title %} - -{% block manage %} - -{% block subtitle %}Data for user {{ data.user.get_full_name.title }}{% endblock %} - -
Username - First Name - Last Name - Quiz Description -{% for papers in question %} - {{ papers.user.username }}
-{{ papers.user.first_name.title }} - {{ papers.user.last_name.title }} - {{ papers.question_paper.quiz.description }} -{% endfor %} - - -Name: {{ data.user.get_full_name.title }}
- -{% if data.papers %} - - -{% for paper in data.papers %} - -
-Username: {{ data.user.username }}
-{% if data.profile %} -Roll number: {{ data.profile.roll_number }}
-Position: {{ data.profile.position }}
-Department: {{ data.profile.department }}
-Institute: {{ data.profile.institute }}
-{% endif %} -Email: {{ data.user.email }}
-Date joined: {{ data.user.date_joined }}
-Last login: {{ data.user.last_login }} -Quiz: {{ paper.quiz.description }}
- --Questions correctly answered: {{ paper.get_answered_str }}
- -{% if paper.answers.count %} -
-Total attempts at questions: {{ paper.answers.count }}
-Marks obtained: {{ paper.get_total_marks }}
-Start time: {{ paper.start_time }}
-User IP address: {{ paper.user_ip }} -Answers
-{% for question, answers in paper.get_question_answers.items %} -Question: {{ question.id }}. {{ question.summary }} (Points: {{ question.points }})
-{% if question.type == "mcq" %} -Choices: -{% for option in question.options.strip.splitlines %} {{option}}, {% endfor %} -
-Student answer: {{ answers.0 }}
-{% else %}{# non-mcq questions #} --{% for answer in answers %}################################################################################ -{{ answer.answer.strip }} -# Autocheck: {{ answer.error }} -{% endfor %}-{% endif %} -{% with answers|last as answer %} -Marks: {{answer.marks}}
-{% endwith %} -{% endfor %} {# for question, answers ... #} -Teacher comments:
-{{ paper.comments|default:"None" }} -{% endif %} {# if paper.answers.count #} - -{% endfor %} {# for paper in data.papers #} - -{% endif %} {# if data.papers #} -
-
- - Grade/correct paper -
-{% if data.papers.count > 1 %} -Monitor quiz -{% else %} -{% with data.papers.0 as paper %} -Monitor quiz -{% endwith %} -{% endif %} - -{% endblock %} diff --git a/testapp/yaksh/tests.py b/testapp/yaksh/tests.py deleted file mode 100644 index f1587b7..0000000 --- a/testapp/yaksh/tests.py +++ /dev/null @@ -1,345 +0,0 @@ -from django.utils import unittest -from testapp.yaksh.models import User, Profile, Question, Quiz, QuestionPaper,\ - QuestionSet, AnswerPaper, Answer, TestCase -import datetime, json - -def setUpModule(): - # create user profile - user = User.objects.create_user(username='demo_user', - password='demo', - email='demo@test.com') - User.objects.create_user(username='demo_user2', - password='demo', - email='demo@test.com') - Profile.objects.create(user=user, roll_number=1, institute='IIT', - department='Chemical', position='Student') - - # create 20 questions - for i in range(1, 21): - Question.objects.create(summary='Q%d' % (i), points=1) - - # create a quiz - Quiz.objects.create(start_date='2014-06-16', duration=30, active=False, - attempts_allowed=-1, time_between_attempts=0, - description='demo quiz', pass_criteria=40, - language='Python', prerequisite=None) - - -def tearDownModule(): - User.objects.all().delete() - Question.objects.all().delete() - Quiz.objects.all().delete() - - -############################################################################### -class ProfileTestCases(unittest.TestCase): - def setUp(self): - self.user = User.objects.get(pk=1) - self.profile = Profile.objects.get(pk=1) - - def test_user_profile(self): - """ Test user profile""" - self.assertEqual(self.user.username, 'demo_user') - self.assertEqual(self.profile.user.username, 'demo_user') - self.assertEqual(int(self.profile.roll_number), 1) - self.assertEqual(self.profile.institute, 'IIT') - self.assertEqual(self.profile.department, 'Chemical') - self.assertEqual(self.profile.position, 'Student') - - -############################################################################### -class QuestionTestCases(unittest.TestCase): - def setUp(self): - # Single question details - # self.question = Question(summary='Demo question', language='Python', - # type='Code', active=True, - # description='Write a function', points=1.0, - # test='Test Cases', snippet='def myfunc()') - self.question = Question(summary='Demo question', language='Python', - type='Code', active=True, - description='Write a function', points=1.0, - snippet='def myfunc()') - self.question.save() - self.question.tags.add('python', 'function') - self.testcase = TestCase(question=self.question, - func_name='def myfunc', kw_args='a=10,b=11', - pos_args='12,13', expected_answer='15') - answer_data = { "test": "", - "user_answer": "demo_answer", - "test_parameter": [{"func_name": "def myfunc", - "expected_answer": "15", - "test_id": self.testcase.id, - "pos_args": ["12", "13"], - "kw_args": {"a": "10", - "b": "11"} - }], - "id": self.question.id, - "ref_code_path": "", - } - self.answer_data_json = json.dumps(answer_data) - self.user_answer = "demo_answer" - - def test_question(self): - """ Test question """ - self.assertEqual(self.question.summary, 'Demo question') - self.assertEqual(self.question.language, 'Python') - self.assertEqual(self.question.type, 'Code') - self.assertFalse(self.question.options) - self.assertEqual(self.question.description, 'Write a function') - self.assertEqual(self.question.points, 1.0) - self.assertTrue(self.question.active) - self.assertEqual(self.question.snippet, 'def myfunc()') - tag_list = [] - for tag in self.question.tags.all(): - tag_list.append(tag.name) - self.assertEqual(tag_list, ['python', 'function']) - - def test_consolidate_answer_data(self): - """ Test consolidate_answer_data function """ - result = self.question.consolidate_answer_data([self.testcase], - self.user_answer) - self.assertEqual(result, self.answer_data_json) - - - -############################################################################### -class TestCaseTestCases(unittest.TestCase): - def setUp(self): - self.question = Question(summary='Demo question', language='Python', - type='Code', active=True, - description='Write a function', points=1.0, - snippet='def myfunc()') - self.question.save() - self.testcase = TestCase(question=self.question, - func_name='def myfunc', kw_args='a=10,b=11', - pos_args='12,13', expected_answer='15') - - def test_testcase(self): - """ Test question """ - self.assertEqual(self.testcase.question, self.question) - self.assertEqual(self.testcase.func_name, 'def myfunc') - self.assertEqual(self.testcase.kw_args, 'a=10,b=11') - self.assertEqual(self.testcase.pos_args, '12,13') - self.assertEqual(self.testcase.expected_answer, '15') - - -############################################################################### -class QuizTestCases(unittest.TestCase): - def setUp(self): - self.quiz = Quiz.objects.get(pk=1) - - def test_quiz(self): - """ Test Quiz""" - self.assertEqual((self.quiz.start_date).strftime('%Y-%m-%d'), - '2014-06-16') - self.assertEqual(self.quiz.duration, 30) - self.assertTrue(self.quiz.active is False) - self.assertEqual(self.quiz.description, 'demo quiz') - self.assertEqual(self.quiz.language, 'Python') - self.assertEqual(self.quiz.pass_criteria, 40) - self.assertEqual(self.quiz.prerequisite, None) - - -############################################################################### -class QuestionPaperTestCases(unittest.TestCase): - @classmethod - def setUpClass(self): - # All active questions - self.questions = Question.objects.filter(active=True) - self.quiz = Quiz.objects.get(id=1) - - # create question paper - self.question_paper = QuestionPaper.objects.create(quiz=self.quiz, - total_marks=0.0, shuffle_questions=True) - - # add fixed set of questions to the question paper - self.question_paper.fixed_questions.add(self.questions[3], - self.questions[5]) - # create two QuestionSet for random questions - # QuestionSet 1 - self.question_set_1 = QuestionSet.objects.create(marks=2, - num_questions=2) - - # add pool of questions for random sampling - self.question_set_1.questions.add(self.questions[6], self.questions[7], - self.questions[8], self.questions[9]) - # add question set 1 to random questions in Question Paper - self.question_paper.random_questions.add(self.question_set_1) - - # QuestionSet 2 - self.question_set_2 = QuestionSet.objects.create(marks=3, - num_questions=3) - - # add pool of questions - self.question_set_2.questions.add(self.questions[11], - self.questions[12], - self.questions[13], - self.questions[14]) - # add question set 2 - self.question_paper.random_questions.add(self.question_set_2) - - # ip address for AnswerPaper - self.ip = '127.0.0.1' - - self.user = User.objects.get(pk=1) - - self.attempted_papers = AnswerPaper.objects.filter(question_paper=self.question_paper, - user=self.user) - - def test_questionpaper(self): - """ Test question paper""" - self.assertEqual(self.question_paper.quiz.description, 'demo quiz') - self.assertEqual(list(self.question_paper.fixed_questions.all()), - [self.questions[3], self.questions[5]]) - self.assertTrue(self.question_paper.shuffle_questions) - - def test_update_total_marks(self): - """ Test update_total_marks() method of Question Paper""" - self.assertEqual(self.question_paper.total_marks, 0) - self.question_paper.update_total_marks() - self.assertEqual(self.question_paper.total_marks, 15) - - def test_get_random_questions(self): - """ Test get_random_questions() method of Question Paper""" - random_questions_set_1 = self.question_set_1.get_random_questions() - random_questions_set_2 = self.question_set_2.get_random_questions() - - # To check whether random questions are from random_question_set - questions_set_1 = set(self.question_set_1.questions.all()) - random_set_1 = set(random_questions_set_1) - random_set_2 = set(random_questions_set_2) - boolean = questions_set_1.intersection(random_set_1) == random_set_1 - self.assertTrue(boolean) - self.assertEqual(len(random_set_1), 2) - # To check that the questions are random. - # If incase not random then check that the order is diferent - try: - self.assertFalse(random_set_1 == random_set_2) - except AssertionError: - self.assertTrue(random_questions_set_1 != random_questions_set_2) - - def test_get_questions_for_answerpaper(self): - """ Test get_questions_for_answerpaper() method of Question Paper""" - questions = self.question_paper._get_questions_for_answerpaper() - fixed = list(self.question_paper.fixed_questions.all()) - question_set = self.question_paper.random_questions.all() - total_random_questions = 0 - available_questions = [] - for qs in question_set: - total_random_questions += qs.num_questions - available_questions += qs.questions.all() - self.assertEqual(total_random_questions, 5) - self.assertEqual(len(available_questions), 8) - self.assertEqual(len(questions), 7) - - def test_make_answerpaper(self): - """ Test make_answerpaper() method of Question Paper""" - already_attempted = self.attempted_papers.count() - attempt_num = already_attempted + 1 - answerpaper = self.question_paper.make_answerpaper(self.user, self.ip, - attempt_num) - self.assertIsInstance(answerpaper, AnswerPaper) - paper_questions = set((answerpaper.questions).split('|')) - self.assertEqual(len(paper_questions), 7) - fixed = {'4', '6'} - boolean = fixed.intersection(paper_questions) == fixed - self.assertTrue(boolean) - - -############################################################################### -class AnswerPaperTestCases(unittest.TestCase): - @classmethod - def setUpClass(self): - self.ip = '101.0.0.1' - self.user = User.objects.get(id=1) - self.profile = self.user.profile - self.quiz = Quiz.objects.get(pk=1) - self.question_paper = QuestionPaper(quiz=self.quiz, total_marks=3) - self.question_paper.save() - - # create answerpaper - self.answerpaper = AnswerPaper(user=self.user, - questions='1|2|3', - question_paper=self.question_paper, - start_time='2014-06-13 12:20:19.791297', - end_time='2014-06-13 12:50:19.791297', - user_ip=self.ip) - self.answerpaper.questions_answered = '1' - self.attempted_papers = AnswerPaper.objects.filter(question_paper=self.question_paper, - user=self.user) - already_attempted = self.attempted_papers.count() - self.answerpaper.attempt_number = already_attempted + 1 - self.answerpaper.save() - - # answers for the Answer Paper - self.answer_right = Answer(question=Question.objects.get(id=1), - answer="Demo answer", correct=True, marks=1) - self.answer_wrong = Answer(question=Question.objects.get(id=2), - answer="My answer", correct=False, marks=0) - self.answer_right.save() - self.answer_wrong.save() - self.answerpaper.answers.add(self.answer_right) - self.answerpaper.answers.add(self.answer_wrong) - - def test_answerpaper(self): - """ Test Answer Paper""" - self.assertEqual(self.answerpaper.user.username, 'demo_user') - self.assertEqual(self.answerpaper.user_ip, self.ip) - questions = self.answerpaper.questions - num_questions = len(questions.split('|')) - self.assertEqual(questions, '1|2|3') - self.assertEqual(num_questions, 3) - self.assertEqual(self.answerpaper.question_paper, self.question_paper) - self.assertEqual(self.answerpaper.start_time, - '2014-06-13 12:20:19.791297') - self.assertEqual(self.answerpaper.end_time, - '2014-06-13 12:50:19.791297') - - def test_current_question(self): - """ Test current_question() method of Answer Paper""" - current_question = self.answerpaper.current_question() - self.assertEqual(current_question, '2') - - def test_completed_question(self): - """ Test completed_question() method of Answer Paper""" - question = self.answerpaper.completed_question(1) - self.assertEqual(self.answerpaper.questions_left(), 2) - - def test_questions_left(self): - """ Test questions_left() method of Answer Paper""" - self.assertEqual(self.answerpaper.questions_left(), 2) - - def test_skip(self): - """ Test skip() method of Answer Paper""" - current_question = self.answerpaper.current_question() - next_question_id = self.answerpaper.skip(current_question) - self.assertTrue(next_question_id is not None) - self.assertEqual(next_question_id, '3') - - def test_answered_str(self): - """ Test answered_str() method of Answer Paper""" - answered_question = self.answerpaper.get_answered_str() - self.assertEqual(answered_question, '1') - - def test_update_marks_obtained(self): - """ Test get_marks_obtained() method of Answer Paper""" - self.answerpaper.update_marks_obtained() - self.assertEqual(self.answerpaper.marks_obtained, 1.0) - - def test_update_percent(self): - """ Test update_percent() method of Answerpaper""" - self.answerpaper.update_percent() - self.assertEqual(self.answerpaper.percent, 33.33) - - def test_update_passed(self): - """ Test update_passed method of AnswerPaper""" - self.answerpaper.update_passed() - self.assertFalse(self.answerpaper.passed) - - def test_get_question_answer(self): - """ Test get_question_answer() method of Answer Paper""" - answered = self.answerpaper.get_question_answers() - first_answer = answered.values()[0][0] - self.assertEqual(first_answer.answer, 'Demo answer') - self.assertTrue(first_answer.correct) - self.assertEqual(len(answered), 2) diff --git a/testapp/yaksh/urls.py b/testapp/yaksh/urls.py deleted file mode 100644 index 11e5965..0000000 --- a/testapp/yaksh/urls.py +++ /dev/null @@ -1,52 +0,0 @@ -from django.conf.urls import patterns, url - -urlpatterns = patterns('testapp.yaksh.views', - url(r'^$', 'index'), - url(r'^login/$', 'user_login'), - url(r'^quizzes/$', 'quizlist_user'), - url(r'^results/$', 'results_user'), - url(r'^start/$', 'start'), - url(r'^start/(?P\d+)/(?P \d+)/$', 'start'), - url(r'^quit/(?P \d+)/(?P \d+)/$', 'quit'), - url(r'^intro/(?P \d+)/$', 'intro'), - url(r'^complete/$', 'complete'), - url(r'^complete/(?P \d+)/(?P \d+)/$',\ - 'complete'), - url(r'^register/$', 'user_register'), - url(r'^(?P \d+)/$', 'question'), - url(r'^(?P \d+)/check/$', 'check'), - url(r'^(?P \d+)/check/(?P \d+)/(?P \d+)/$',\ - 'check'), - url(r'^intro/$', 'start'), - url(r'^(?P \d+)/(?P \d+)/(?P \d+)/$', 'show_question'), - - url(r'^manage/$', 'prof_manage'), - url(r'^manage/addquestion/$', 'add_question'), - url(r'^manage/addquestion/(?P \d+)/$', 'add_question'), - url(r'^manage/addquiz/$', 'add_quiz'), - url(r'^manage/editquiz/$', 'edit_quiz'), - url(r'^manage/editquestion/$', 'edit_question'), - url(r'^manage/addquiz/(?P \d+)/$', 'add_quiz'), - url(r'^manage/gradeuser/$', 'show_all_users'), - url(r'^manage/gradeuser/(?P .*)/$', 'grade_user'), - url(r'^manage/questions/$', 'show_all_questions'), - url(r'^manage/showquiz/$', 'show_all_quiz'), - url(r'^manage/monitor/$', 'monitor'), - url(r'^manage/showquestionpapers/$', 'show_all_questionpapers'), - url(r'^manage/showquestionpapers/(?P \d+)/$',\ - 'show_all_questionpapers'), - url(r'^manage/monitor/(?P \d+)/$', 'monitor'), - url(r'^manage/user_data/(?P .*)/$', 'user_data'), - url(r'^manage/designquestionpaper/$', 'design_questionpaper'), - url(r'^manage/designquestionpaper/(?P \d+)/$',\ - 'design_questionpaper'), - url(r'^manage/designquestionpaper/automatic/(?P \d+)/$',\ - 'automatic_questionpaper'), - url(r'^manage/designquestionpaper/automatic$', 'automatic_questionpaper'), - url(r'^manage/designquestionpaper/manual$', 'manual_questionpaper'), - url(r'^manage/designquestionpaper/manual/(?P \d+)/$',\ - 'manual_questionpaper'), - url(r'^ajax/questionpaper/(?P .+)/$', 'ajax_questionpaper'), - url(r'^ajax/questions/filter/$', 'ajax_questions_filter'), ##@@ - -) diff --git a/testapp/yaksh/views.py b/testapp/yaksh/views.py deleted file mode 100644 index d4476b7..0000000 --- a/testapp/yaksh/views.py +++ /dev/null @@ -1,1502 +0,0 @@ -import random -import string -import os -import stat -from os.path import dirname, pardir, abspath, join, exists -import datetime -import collections -from django.http import HttpResponse -from django.contrib.auth import login, logout, authenticate -from django.shortcuts import render_to_response, get_object_or_404, redirect -from django.template import RequestContext -from django.http import Http404 -from django.db.models import Sum -from django.views.decorators.csrf import csrf_exempt -from taggit.models import Tag -from itertools import chain -import json -# Local imports. -from testapp.yaksh.models import Quiz, Question, QuestionPaper, QuestionSet -from testapp.yaksh.models import Profile, Answer, AnswerPaper, User, TestCase -from testapp.yaksh.forms import UserRegisterForm, UserLoginForm, QuizForm,\ - QuestionForm, RandomQuestionForm, TestCaseFormSet,\ - QuestionFilterForm -from testapp.yaksh.xmlrpc_clients import code_server -from settings import URL_ROOT -from testapp.yaksh.models import AssignmentUpload - -# The directory where user data can be saved. -OUTPUT_DIR = abspath(join(dirname(__file__), 'output')) - - -def my_redirect(url): - """An overridden redirect to deal with URL_ROOT-ing. See settings.py - for details.""" - return redirect(URL_ROOT + url) - - -def my_render_to_response(template, context=None, **kwargs): - """Overridden render_to_response. - """ - if context is None: - context = {'URL_ROOT': URL_ROOT} - else: - context['URL_ROOT'] = URL_ROOT - return render_to_response(template, context, **kwargs) - - -def gen_key(no_of_chars): - """Generate a random key of the number of characters.""" - allowed_chars = string.digits+string.uppercase - return ''.join([random.choice(allowed_chars) for i in range(no_of_chars)]) - - -def get_user_dir(user): - """Return the output directory for the 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) - return user_dir - - -def is_moderator(user): - """Check if the user is having moderator rights""" - if user.groups.filter(name='moderator').count() == 1: - return True - - -def fetch_questions(request): - """Fetch questions from database based on the given search conditions & - tags""" - set1 = set() - set2 = set() - first_tag = request.POST.get('first_tag') - first_condition = request.POST.get('first_condition') - second_tag = request.POST.get('second_tag') - second_condition = request.POST.get('second_condition') - third_tag = request.POST.get('third_tag') - question1 = set(Question.objects.filter(tags__name__in=[first_tag])) - question2 = set(Question.objects.filter(tags__name__in=[second_tag])) - question3 = set(Question.objects.filter(tags__name__in=[third_tag])) - if first_condition == 'and': - set1 = question1.intersection(question2) - if second_condition == 'and': - set2 = set1.intersection(question3) - else: - set2 = set1.union(question3) - else: - set1 = question1.union(question2) - if second_condition == 'and': - set2 = set1.intersection(question3) - else: - set2 = set1.union(question3) - return set2 - - -def index(request): - """The start page. - """ - user = request.user - if user.is_authenticated(): - if user.groups.filter(name='moderator').count() > 0: - return my_redirect('/exam/manage/') - return my_redirect("/exam/start/") - - return my_redirect("/exam/login/") - - -def user_register(request): - """ Register a new user. - 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/") - - if request.method == "POST": - form = UserRegisterForm(request.POST) - if form.is_valid(): - data = form.cleaned_data - u_name, pwd = form.save() - new_user = authenticate(username=u_name, password=pwd) - login(request, new_user) - return my_redirect("/exam/start/") - else: - return my_render_to_response('yaksh/register.html', {'form': form}, - context_instance=ci) - else: - form = UserRegisterForm() - return my_render_to_response('yaksh/register.html', {'form': form}, - context_instance=ci) - - -def quizlist_user(request): - """Show All Quizzes that is available to logged-in user.""" - user = request.user - avail_quizzes = list(QuestionPaper.objects.filter(quiz__active=True)) - user_answerpapers = AnswerPaper.objects.filter(user=user) - pre_requisites = [] - enabled_quizzes = [] - disabled_quizzes = [] - unexpired_quizzes = [] - - for paper in avail_quizzes: - quiz_enable_time = paper.quiz.start_date_time - quiz_disable_time = paper.quiz.end_date_time - if quiz_enable_time <= datetime.datetime.now() <= quiz_disable_time: - unexpired_quizzes.append(paper) - - cannot_attempt = True if 'cannot_attempt' in request.GET else False - quizzes_taken = None if user_answerpapers.count() == 0 else user_answerpapers - - context = {'cannot_attempt': cannot_attempt, - 'quizzes': avail_quizzes, - 'user': user, - 'quizzes_taken': quizzes_taken, - 'unexpired_quizzes': unexpired_quizzes - } - - return my_render_to_response("yaksh/quizzes_user.html", context) - - -def intro(request, questionpaper_id): - """Show introduction page before quiz starts""" - user = request.user - ci = RequestContext(request) - quest_paper = QuestionPaper.objects.get(id=questionpaper_id) - attempt_number = quest_paper.quiz.attempts_allowed - time_lag = quest_paper.quiz.time_between_attempts - quiz_enable_time = quest_paper.quiz.start_date_time - quiz_disable_time = quest_paper.quiz.end_date_time - - quiz_expired = False if quiz_enable_time <= datetime.datetime.now() \ - <= quiz_disable_time else True - - if quest_paper.quiz.prerequisite: - try: - pre_quest = QuestionPaper.objects.get( - quiz=quest_paper.quiz.prerequisite) - answer_papers = AnswerPaper.objects.filter( - question_paper=pre_quest, user=user) - answer_papers_failed = AnswerPaper.objects.filter( - question_paper=pre_quest, user=user, passed=False) - if answer_papers.count() == answer_papers_failed.count(): - context = {'user': user, 'cannot_attempt': True} - return my_redirect("/exam/quizzes/?cannot_attempt=True") - except: - context = {'user': user, 'cannot_attempt': True} - return my_redirect("/exam/quizzes/?cannot_attempt=True") - - attempted_papers = AnswerPaper.objects.filter(question_paper=quest_paper, - user=user) - already_attempted = attempted_papers.count() - inprogress, previous_attempt, next_attempt = _check_previous_attempt(attempted_papers, - already_attempted, - attempt_number) - - if previous_attempt: - if inprogress: - return show_question(request, - previous_attempt.current_question(), - previous_attempt.attempt_number, - previous_attempt.question_paper.id) - days_after_attempt = (datetime.datetime.today() - \ - previous_attempt.start_time).days - - if next_attempt: - if days_after_attempt >= time_lag: - context = {'user': user, - 'paper_id': questionpaper_id, - 'attempt_num': already_attempted + 1, - 'enable_quiz_time': quiz_enable_time, - 'disable_quiz_time': quiz_disable_time, - 'quiz_expired': quiz_expired - } - return my_render_to_response('yaksh/intro.html', context, - context_instance=ci) - else: - return my_redirect("/exam/quizzes/") - - else: - context = {'user': user, - 'paper_id': questionpaper_id, - 'attempt_num': already_attempted + 1, - 'enable_quiz_time': quiz_enable_time, - 'disable_quiz_time': quiz_disable_time, - 'quiz_expired': quiz_expired - } - return my_render_to_response('yaksh/intro.html', context, - context_instance=ci) - - -def _check_previous_attempt(attempted_papers, already_attempted, attempt_number): - next_attempt = False if already_attempted == attempt_number else True - if already_attempted == 0: - return False, None, next_attempt - else: - previous_attempt = attempted_papers[already_attempted-1] - previous_attempt_day = previous_attempt.start_time - today = datetime.datetime.today() - if previous_attempt.status == 'inprogress': - end_time = previous_attempt.end_time - quiz_time = previous_attempt.question_paper.quiz.duration*60 - if quiz_time > (today-previous_attempt_day).seconds: - return True, previous_attempt, next_attempt - else: - return False, previous_attempt, next_attempt - else: - return False, previous_attempt, next_attempt - - -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: - marks_obtained = paper.marks_obtained - 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("yaksh/results_user.html", context) - - -def edit_quiz(request): - """Edit the list of quizzes seleted by the user for editing.""" - - user = request.user - if not user.is_authenticated() or not is_moderator(user): - raise Http404('You are not allowed to view this page!') - quiz_list = request.POST.getlist('quizzes') - start_date = request.POST.getlist('start_date') - start_time = request.POST.getlist('start_time') - end_date = request.POST.getlist('end_date') - end_time = request.POST.getlist('end_time') - duration = request.POST.getlist('duration') - active = request.POST.getlist('active') - description = request.POST.getlist('description') - pass_criteria = request.POST.getlist('pass_criteria') - language = request.POST.getlist('language') - prerequisite = request.POST.getlist('prerequisite') - - for j, quiz_id in enumerate(quiz_list): - quiz = Quiz.objects.get(id=quiz_id) - quiz.start_date_time = datetime.datetime.combine(start_date[j], - start_time[j]) - quiz.end_date_time = datetime.datetime.combine(end_date[j], - end_time[j]) - quiz.duration = duration[j] - quiz.active = active[j] - quiz.description = description[j] - quiz.pass_criteria = pass_criteria[j] - quiz.language = language[j] - quiz.prerequisite_id = prerequisite[j] - quiz.save() - return my_redirect("/exam/manage/showquiz/") - - -def edit_question(request): - """Edit the list of questions selected by the user for editing.""" - user = request.user - if not user.is_authenticated() or not is_moderator(user): - raise Http404('You are not allowed to view this page!') - question_list = request.POST.getlist('questions') - summary = request.POST.getlist('summary') - description = request.POST.getlist('description') - points = request.POST.getlist('points') - options = request.POST.getlist('options') - test = request.POST.getlist('test') - type = request.POST.getlist('type') - active = request.POST.getlist('active') - language = request.POST.getlist('language') - snippet = request.POST.getlist('snippet') - for j, question_id in enumerate(question_list): - question = Question.objects.get(id=question_id) - test_case_formset = TestCaseFormSet(request.POST, prefix='test', instance=question) - if test_case_formset.is_valid(): - test_case_instance = test_case_formset.save(commit=False) - for i in test_case_instance: - i.save() - - question.summary = summary[j] - question.description = description[j] - question.points = points[j] - question.options = options[j] - question.active = active[j] - question.language = language[j] - question.snippet = snippet[j] - question.ref_code_path = ref_code_path[j] - question.test = test[j] - question.type = type[j] - question.save() - return my_redirect("/exam/manage/questions") - - -def add_question(request, question_id=None): - """To add a new question in the database. - Create a new question and store it.""" - - def add_or_delete_test_form(post_request, instance): - request_copy = post_request.copy() - if 'add_test' in post_request: - request_copy['test-TOTAL_FORMS'] = int(request_copy['test-TOTAL_FORMS']) + 1 - elif 'delete_test' in post_request: - request_copy['test-TOTAL_FORMS'] = int(request_copy['test-TOTAL_FORMS']) - 1 - test_case_formset = TestCaseFormSet(request_copy, prefix='test', instance=instance) - return test_case_formset - - 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": - form = QuestionForm(request.POST) - if form.is_valid(): - if question_id is None: - test_case_formset = add_or_delete_test_form(request.POST, form.save(commit=False)) - if 'save_question' in request.POST: - qtn = form.save(commit=False) - test_case_formset = TestCaseFormSet(request.POST, prefix='test', instance=qtn) - form.save() - question = Question.objects.order_by("-id")[0] - tags = form['tags'].data.split(',') - for i in range(0, len(tags)-1): - tag = tags[i].strip() - question.tags.add(tag) - if test_case_formset.is_valid(): - test_case_formset.save() - else: - return my_render_to_response('yaksh/add_question.html', - {'form': form, - 'formset': test_case_formset}, - context_instance=ci) - - return my_redirect("/exam/manage/questions") - - return my_render_to_response('yaksh/add_question.html', - {'form': form, - 'formset': test_case_formset}, - context_instance=ci) - - else: - d = Question.objects.get(id=question_id) - test_case_formset = add_or_delete_test_form(request.POST, d) - if 'save_question' in request.POST: - d.summary = form['summary'].data - d.description = form['description'].data - d.points = form['points'].data - d.options = form['options'].data - d.type = form['type'].data - d.active = form['active'].data - d.language = form['language'].data - d.snippet = form['snippet'].data - d.ref_code_path = form['ref_code_path'].data - d.test = form['test'].data - d.save() - question = Question.objects.get(id=question_id) - for tag in question.tags.all(): - question.tags.remove(tag) - tags = form['tags'].data.split(',') - for i in range(0, len(tags)-1): - tag = tags[i].strip() - question.tags.add(tag) - - test_case_formset = TestCaseFormSet(request.POST, prefix='test', instance=question) - if test_case_formset.is_valid(): - test_case_instance = test_case_formset.save(commit=False) - for i in test_case_instance: - i.save() - else: - return my_render_to_response('yaksh/add_question.html', - {'form': form, - 'formset': test_case_formset}, - context_instance=ci) - - - return my_redirect("/exam/manage/questions") - return my_render_to_response('yaksh/add_question.html', - {'form': form, - 'formset': test_case_formset}, - context_instance=ci) - - else: - test_case_formset = add_or_delete_test_form(request.POST, form.save(commit=False)) - return my_render_to_response('yaksh/add_question.html', - {'form': form, - 'formset': test_case_formset}, - context_instance=ci) - else: - form = QuestionForm() - test_case_formset = TestCaseFormSet(prefix='test', instance=Question()) - if question_id is None: - form = QuestionForm() - test_case_formset = TestCaseFormSet(prefix='test', instance=Question()) - return my_render_to_response('yaksh/add_question.html', - {'form': form, - 'formset': test_case_formset}, - context_instance=ci) - else: - d = Question.objects.get(id=question_id) - form = QuestionForm() - form.initial['summary'] = d.summary - form.initial['description'] = d.description - form.initial['points'] = d.points - form.initial['options'] = d.options - form.initial['type'] = d.type - form.initial['active'] = d.active - form.initial['language'] = d.language - form.initial['snippet'] = d.snippet - form.initial['ref_code_path'] = d.ref_code_path - form.initial['test'] = d.test - form_tags = d.tags.all() - form_tags_split = form_tags.values('name') - initial_tags = "" - for tag in form_tags_split: - initial_tags = initial_tags + str(tag['name']).strip() + "," - if (initial_tags == ","): - initial_tags = "" - form.initial['tags'] = initial_tags - - test_case_formset = TestCaseFormSet(prefix='test', - instance=d) - - return my_render_to_response('yaksh/add_question.html', - {'form': form, - 'formset': test_case_formset}, - context_instance=ci) - - -def add_quiz(request, quiz_id=None): - """To add a new quiz in the database. - 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": - form = QuizForm(request.POST) - if form.is_valid(): - data = form.cleaned_data - if quiz_id is None: - form.save() - quiz = Quiz.objects.order_by("-id")[0] - return my_redirect("/exam/manage/designquestionpaper") - else: - d = Quiz.objects.get(id=quiz_id) - sd = datetime.datetime.strptime(form['start_date'].data, '%Y-%m-%d').date() - st = datetime.datetime.strptime(form['start_time'].data, "%H:%M:%S").time() - ed = datetime.datetime.strptime(form['end_date'].data, '%Y-%m-%d').date() - et = datetime.datetime.strptime(form['end_time'].data, "%H:%M:%S").time() - d.start_date_time = datetime.datetime.combine(sd, st) - d.end_date_time = datetime.datetime.combine(ed, et) - d.duration = form['duration'].data - d.active = form['active'].data - d.description = form['description'].data - d.pass_criteria = form['pass_criteria'].data - d.language = form['language'].data - d.prerequisite_id = form['prerequisite'].data - d.attempts_allowed = form['attempts_allowed'].data - d.time_between_attempts = form['time_between_attempts'].data - d.save() - quiz = Quiz.objects.get(id=quiz_id) - return my_redirect("/exam/manage/showquiz") - else: - return my_render_to_response('yaksh/add_quiz.html', - {'form': form}, - context_instance=ci) - else: - if quiz_id is None: - form = QuizForm() - return my_render_to_response('yaksh/add_quiz.html', - {'form': form}, - context_instance=ci) - else: - d = Quiz.objects.get(id=quiz_id) - form = QuizForm() - form.initial['start_date'] = d.start_date_time.date() - form.initial['start_time'] = d.start_date_time.time() - form.initial['end_date'] = d.end_date_time.date() - form.initial['end_time'] = d.end_date_time.time() - form.initial['duration'] = d.duration - form.initial['description'] = d.description - form.initial['active'] = d.active - form.initial['pass_criteria'] = d.pass_criteria - form.initial['language'] = d.language - form.initial['prerequisite'] = d.prerequisite_id - form.initial['attempts_allowed'] = d.attempts_allowed - form.initial['time_between_attempts'] = d.time_between_attempts - return my_render_to_response('yaksh/add_quiz.html', - {'form': form}, - 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) - - if request.method == "POST" and request.POST.get('delete') == "delete": - data = request.POST.getlist('papers') - q_paper = QuestionPaper.objects.get(id=questionpaper_id) - for i in data: - q_paper.questions.remove(Question.objects.get(id=i)) - question_paper = QuestionPaper.objects.all() - context = {'papers': question_paper} - return my_render_to_response('yaksh/showquestionpapers.html', context, - context_instance=ci) - if questionpaper_id is None: - qu_papers = QuestionPaper.objects.all() - context = {'papers': qu_papers} - return my_render_to_response('yaksh/showquestionpapers.html', context, - 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('yaksh/editquestionpaper.html', context, - 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!') - - if questionpaper_id is None: - if request.method == "POST": - 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() - for quest in questions: - q = Question.objects.get(id=quest) - quest_paper.fixed_questions.add(q) - return my_redirect('/exam/manage/showquiz') - else: - no_questions = int(request.POST.get('num_questions')) - fetched_questions = fetch_questions(request) - n = len(fetched_questions) - msg = '' - if (no_questions < n): - i = n - no_questions - for i in range(0, i): - fetched_questions.pop() - elif (no_questions > n): - msg = 'The given Criteria does not satisfy the number\ - of Questions...' - tags = Tag.objects.all() - context = {'data': {'questions': fetched_questions, - 'tags': tags, - 'msg': msg}} - return my_render_to_response( - 'yaksh/automatic_questionpaper.html', context, - context_instance=ci) - else: - tags = Tag.objects.all() - context = {'data': {'tags': tags}} - return my_render_to_response('yaksh/automatic_questionpaper.html', - 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') - 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('/yaksh/manage/showquiz') - else: - no_questions = int(request.POST.get('num_questions')) - fetched_questions = fetch_questions(request) - n = len(fetched_questions) - msg = '' - if(no_questions < n): - i = n - no_questions - for i in range(0, i): - fetched_questions.pop() - elif(no_questions > n): - msg = 'The given Criteria does not satisfy the number of \ - Questions...' - tags = Tag.objects.all() - context = {'data': {'questions': fetched_questions, - 'tags': tags, - 'msg': msg}} - return my_render_to_response( - 'yaksh/automatic_questionpaper.html', context, - context_instance=ci) - else: - tags = Tag.objects.all() - context = {'data': {'tags': tags}} - return my_render_to_response('yaksh/automatic_questionpaper.html', - 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!') - - if questionpaper_id is None: - if request.method == "POST": - if request.POST.get('save') == 'save': - questions = request.POST.getlist('questions') - 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) - quest_paper.questions.add(q) - return my_redirect('/exam/manage/showquiz') - else: - fetched_questions = fetch_questions(request) - n = len(fetched_questions) - msg = '' - if (n == 0): - msg = 'No matching Question found...' - tags = Tag.objects.all() - context = {'data': {'questions': fetched_questions, - 'tags': tags, 'msg': msg}} - return my_render_to_response('yaksh/manual_questionpaper.html', - context, - context_instance=ci) - else: - tags = Tag.objects.all() - context = {'data': {'tags': tags}} - return my_render_to_response('yaksh/manual_questionpaper.html', - 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') - 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) - msg = '' - if (n == 0): - msg = 'No matching Question found...' - tags = Tag.objects.all() - context = {'data': {'questions': fetched_questions, - 'tags': tags, 'msg': msg}} - return my_render_to_response('yaksh/manual_questionpaper.html', - context, - context_instance=ci) - else: - tags = Tag.objects.all() - context = {'data': {'tags': tags}} - return my_render_to_response('yaksh/manual_questionpaper.html', - context, context_instance=ci) - - -def prof_manage(request): - """Take credentials of the user with professor/moderator -rights/permissions and log in.""" - user = request.user - if user.is_authenticated() and is_moderator(user): - question_papers = QuestionPaper.objects.all() - users_per_paper = [] - for paper in question_papers: - answer_papers = AnswerPaper.objects.filter(question_paper=paper) - users_passed = AnswerPaper.objects.filter(question_paper=paper, - passed=True).count() - users_failed = AnswerPaper.objects.filter(question_paper=paper, - passed=False).count() - temp = paper, answer_papers, users_passed, users_failed - users_per_paper.append(temp) - context = {'user': user, 'users_per_paper': users_per_paper} - return my_render_to_response('manage.html', context) - return my_redirect('/exam/login/') - - -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/') - return my_redirect("/exam/intro/") - - if request.method == "POST": - form = UserLoginForm(request.POST) - if form.is_valid(): - user = form.cleaned_data - login(request, user) - if user.groups.filter(name='moderator').count() > 0: - return my_redirect('/exam/manage/') - return my_redirect('/exam/login/') - else: - context = {"form": form} - return my_render_to_response('yaksh/login.html', context, - context_instance=ci) - else: - form = UserLoginForm() - context = {"form": form} - return my_render_to_response('yaksh/login.html', context, - context_instance=ci) - - -def start(request, attempt_num=None, questionpaper_id=None): - """Check the user cedentials and if any quiz is available, - start the exam.""" - user = request.user - if questionpaper_id is None: - return my_redirect('/exam/quizzes/') - try: - """Right now the app is designed so there is only one active quiz - at a particular time.""" - 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, msg, attempt_num, questionpaper_id) - - try: - old_paper = AnswerPaper.objects.get( - question_paper=questionpaper, user=user, attempt_number=attempt_num) - q = old_paper.current_question() - return show_question(request, q, attempt_num, questionpaper_id) - except AnswerPaper.DoesNotExist: - ip = request.META['REMOTE_ADDR'] - key = gen_key(10) - try: - profile = user.get_profile() - except Profile.DoesNotExist: - msg = 'You do not have a profile and cannot take the quiz!' - raise Http404(msg) - - new_paper = questionpaper.make_answerpaper(user, ip, attempt_num) - # Make user directory. - user_dir = get_user_dir(user) - return start(request, attempt_num, questionpaper_id) - -def get_questions(paper): - ''' - Takes answerpaper as an argument. Returns the total questions as - ordered dictionary, the questions yet to attempt and the questions - attempted - ''' - to_attempt = [] - submitted = [] - all_questions = [] - questions = {} - if paper.questions: - all_questions = (paper.questions).split('|') - if paper.questions_answered: - q_answered = (paper.questions_answered).split('|') - q_answered.sort() - submitted = q_answered - if paper.get_unanswered_questions(): - q_unanswered = paper.get_unanswered_questions() - q_unanswered.sort() - to_attempt = q_unanswered - for index, value in enumerate(all_questions, 1): - questions[value] = index - questions = collections.OrderedDict(sorted(questions.items(), key=lambda x:x[1])) - return questions, to_attempt, submitted - - -def question(request, q_id, attempt_num, questionpaper_id, success_msg=None): - """Check the credentials of the user and start the exam.""" - - user = request.user - if not user.is_authenticated(): - return my_redirect('/exam/login/') - 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, attempt_number=attempt_num, 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!' - return complete(request, reason, questionpaper_id) - elif paper.end_time < datetime.datetime.now(): - reason = 'You have already attempted the quiz' - 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 - questions, to_attempt, submitted = get_questions(paper) - if success_msg is None: - context = {'question': q, 'questions': questions, 'paper': paper, - 'user': user, 'quiz_name': quiz_name, 'time_left': time_left, - 'to_attempt': to_attempt, 'submitted': submitted} - else: - context = {'question': q, 'questions': questions, 'paper': paper, - 'user': user, 'quiz_name': quiz_name, 'time_left': time_left, - 'success_msg': success_msg, 'to_attempt': to_attempt, - 'submitted': submitted} - if q.type == 'code': - skipped_answer = paper.answers.filter(question=q, skipped=True) - if skipped_answer: - context['last_attempt'] = skipped_answer[0].answer - ci = RequestContext(request) - return my_render_to_response('yaksh/question.html', context, - context_instance=ci) - - -def show_question(request, q_id, attempt_num, questionpaper_id, success_msg=None): - """Show a question if possible.""" - user = request.user - q_paper = QuestionPaper.objects.get(id=questionpaper_id) - paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_num, - question_paper=q_paper) - if not user.is_authenticated() or paper.end_time < datetime.datetime.now(): - return my_redirect('/exam/login/') - old_qid = request.POST.get('question_id') - if old_qid is not None: - quest = Question.objects.get(pk=old_qid) - user_code = request.POST.get('answer') - if quest.type == 'code': - old_skipped = paper.answers.filter(question=quest, skipped=True) - _save_skipped_answer(old_skipped, user_code, paper, quest) - if len(q_id) == 0: - msg = 'Congratulations! You have successfully completed the quiz.' - return complete(request, msg, attempt_num, questionpaper_id) - else: - return question(request, q_id, attempt_num, questionpaper_id, success_msg) - - -def _save_skipped_answer(old_skipped, user_answer, paper, question): - """ - Saves the answer on skip. Only the code questions are saved. - Snippet is not saved with the answer. - """ - if old_skipped: - skipped_answer = old_skipped[0] - skipped_answer.answer=user_answer - skipped_answer.save() - else: - skipped_answer = Answer(question=question, answer=user_answer, - correct=False, skipped=True) - skipped_answer.save() - paper.answers.add(skipped_answer) - -def check(request, q_id, attempt_num=None, questionpaper_id=None): - """Checks the answers of the user for particular question""" - - user = request.user - q_paper = QuestionPaper.objects.get(id=questionpaper_id) - paper = AnswerPaper.objects.get(user=request.user, attempt_number=attempt_num, - question_paper=q_paper) - if q_id in paper.questions_answered: - next_q = paper.skip(q_id) - return show_question(request, next_q, attempt_num, questionpaper_id) - - if not user.is_authenticated() or paper.end_time < datetime.datetime.now(): - return my_redirect('/exam/login/') - - question = get_object_or_404(Question, pk=q_id) - test_cases = TestCase.objects.filter(question=question) - - snippet_code = request.POST.get('snippet') - user_code = request.POST.get('answer') - skip = request.POST.get('skip', None) - success_msg = False - success = True - if skip is not None: - if question.type == 'code': - old_skipped = paper.answers.filter(question=question, skipped=True) - _save_skipped_answer(old_skipped, user_code, paper, question) - next_q = paper.skip(q_id) - return show_question(request, next_q, attempt_num, questionpaper_id) - - # Add the answer submitted, regardless of it being correct or not. - if question.type == 'mcq': - user_answer = request.POST.get('answer') - elif question.type == 'mcc': - user_answer = request.POST.getlist('answer') - elif question.type == 'upload': - assign = AssignmentUpload() - assign.user = user.profile - assign.assignmentQuestion = question - # if time-up at upload question then the form is submitted without - # validation - if 'assignment' in request.FILES: - assign.assignmentFile = request.FILES['assignment'] - assign.save() - user_answer = 'ASSIGNMENT UPLOADED' - else: - user_code = request.POST.get('answer') - user_answer = snippet_code + "\n" + user_code if snippet_code else user_code - - new_answer = Answer(question=question, answer=user_answer, - correct=False) - 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 not question.type == 'upload': - json_data = question.consolidate_answer_data(test_cases, user_answer) \ - if question.type == 'code' else None - correct, result = validate_answer(user, user_answer, question, json_data) - if correct: - new_answer.correct = correct - new_answer.marks = question.points - new_answer.error = result.get('error') - success_msg = True - else: - new_answer.error = result.get('error') - new_answer.save() - - time_left = paper.time_left() - if not result.get('success'): # Should only happen for non-mcq questions. - if time_left == 0: - reason = 'Your time is up!' - return complete(request, reason, attempt_num, questionpaper_id) - if not paper.question_paper.quiz.active: - reason = 'The quiz has been deactivated!' - return complete(request, reason, attempt_num, questionpaper_id) - if not paper.question_paper.quiz.active: - reason = 'The quiz has been deactivated!' - return complete(request, reason, attempt_num, questionpaper_id) - questions, to_attempt, submitted = get_questions(paper) - old_answer = paper.answers.filter(question=question, skipped=True) - if old_answer: - old_answer[0].answer = user_code - old_answer[0].save() - context = {'question': question, 'error_message': result.get('error'), - 'paper': paper, 'last_attempt': user_code, - 'quiz_name': paper.question_paper.quiz.description, - 'time_left': time_left, 'questions': questions, - 'to_attempt': to_attempt, 'submitted': submitted} - ci = RequestContext(request) - - return my_render_to_response('yaksh/question.html', context, - context_instance=ci) - else: - if time_left <= 0: - reason = 'Your time is up!' - return complete(request, reason, attempt_num, questionpaper_id) - - # Display the same question if user_answer is None - elif not user_answer: - msg = "Please submit a valid option or code" - time_left = paper.time_left() - questions, to_attempt, submitted = get_questions(paper) - context = {'question': question, 'error_message': msg, - 'paper': paper, 'quiz_name': paper.question_paper.quiz.description, - 'time_left': time_left, 'questions': questions, - 'to_attempt': to_attempt, 'submitted': submitted} - ci = RequestContext(request) - - return my_render_to_response('yaksh/question.html', context, - context_instance=ci) - else: - next_q = paper.completed_question(question.id) - return show_question(request, next_q, attempt_num, - questionpaper_id, success_msg) - - -def validate_answer(user, user_answer, question, json_data=None): - """ - Checks whether the answer submitted by the user is right or wrong. - If right then returns correct = True, success and - message = Correct answer. - success is True for MCQ's and multiple correct choices because - only one attempt are allowed for them. - For code questions success is True only if the answer is correct. - """ - - result = {'success': True, 'error': 'Incorrect answer'} - correct = False - - if user_answer is not None: - if question.type == 'mcq': - if user_answer.strip() == question.test.strip(): - correct = True - message = 'Correct answer' - elif question.type == 'mcc': - answers = set(question.test.splitlines()) - if set(user_answer) == answers: - correct = True - message = 'Correct answer' - elif question.type == 'code': - user_dir = get_user_dir(user) - json_result = code_server.run_code(question.language, json_data, user_dir) - result = json.loads(json_result) - if result.get('success'): - correct = True - - return correct, result - -def get_question_labels(request, attempt_num=None, questionpaper_id=None): - """Get the question number show in template for corresponding - question id.""" - unattempted_questions = [] - submitted_questions = [] - try: - q_paper = QuestionPaper.objects.get(id=questionpaper_id) - paper = AnswerPaper.objects.get( - user=request.user, attempt_number=attempt_num, question_paper=q_paper) - except AnswerPaper.DoesNotExist: - return my_redirect('/exam/start/') - questions, to_attempt, submitted = get_questions(paper) - for q_id, question_label in questions.items(): - if q_id in to_attempt: - unattempted_questions.append(question_label) - else: - submitted_questions.append(question_label) - unattempted_questions.sort() - submitted_questions.sort() - return unattempted_questions, submitted_questions - -def quit(request, attempt_num=None, questionpaper_id=None): - """Show the quit page when the user logs out.""" - unattempted_questions, submitted_questions = get_question_labels(request, - attempt_num, questionpaper_id) - context = {'id': questionpaper_id, 'attempt_num': attempt_num, - 'unattempted': unattempted_questions, - 'submitted': submitted_questions} - return my_render_to_response('yaksh/quit.html', context, - context_instance=RequestContext(request)) - - -def complete(request, reason=None, attempt_num=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) - message = reason or "You are successfully logged out." - context = {'message': message} - return my_render_to_response('yaksh/complete.html', context) - else: - unattempted_questions, submitted_questions = get_question_labels(request, - attempt_num, questionpaper_id) - q_paper = QuestionPaper.objects.get(id=questionpaper_id) - paper = AnswerPaper.objects.get(user=user, question_paper=q_paper, - attempt_number=attempt_num) - paper.update_marks_obtained() - paper.update_percent() - paper.update_passed() - paper.end_time = datetime.datetime.now() - paper.update_status() - paper.save() - obt_marks = paper.marks_obtained - 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 !", - 'unattempted': unattempted_questions, - 'submitted': submitted_questions} - return my_render_to_response('yaksh/complete.html', context) - else: - message = reason or "You are successfully logged out" - context = {'message': message, - 'unattempted': unattempted_questions, - 'submitted': submitted_questions} - return my_render_to_response('yaksh/complete.html', context) - no = False - message = reason or 'The quiz has been completed. Thank you.' - if user.groups.filter(name='moderator').count() > 0: - message = 'You are successfully Logged out.' - if request.method == 'POST' and 'no' in request.POST: - no = True - if not no: - # Logout the user and quit with the message given. - answer_paper = AnswerPaper.objects.get(id=answerpaper_id) - answer_paper.end_time = datetime.datetime.now() - answer_paper.save() - return my_redirect('/exam/quizzes/') - else: - return my_redirect('/exam/') - - -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, - 'quizzes': q_paper} - return my_render_to_response('yaksh/monitor.html', context, - context_instance=ci) - # quiz_id is not None. - try: - q_paper = QuestionPaper.objects.get(id=questionpaper_id) - except QuestionPaper.DoesNotExist: - papers = [] - q_paper = None - else: - papers = AnswerPaper.objects.filter(question_paper=q_paper).annotate( - total=Sum('answers__marks')).order_by('-total') - - context = {'papers': papers, 'quiz': q_paper, 'quizzes': None} - return my_render_to_response('yaksh/monitor.html', context, - context_instance=ci) - - -def get_user_data(username): - """For a given username, this returns a dictionary of important data - related to the user including all the user's answers submitted. - """ - user = User.objects.get(username=username) - papers = AnswerPaper.objects.filter(user=user) - - data = {} - try: - profile = user.get_profile() - except Profile.DoesNotExist: - # Admin user may have a paper by accident but no profile. - profile = None - data['user'] = user - data['profile'] = profile - data['papers'] = papers - return data - - -def show_all_users(request): - """Shows all the users who have taken various exams/quiz.""" - - user = request.user - if not user.is_authenticated() or not is_moderator(user): - raise Http404('You are not allowed to view this page !') - user = User.objects.filter(username__contains="") - questionpaper = AnswerPaper.objects.all() - context = {'question': questionpaper} - return my_render_to_response('yaksh/showusers.html', context, - context_instance=RequestContext(request)) - - -def show_all_quiz(request): - """Generates a list of all the quizzes - 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 !') - - if request.method == 'POST' and request.POST.get('delete') == 'delete': - data = request.POST.getlist('quiz') - - if data is None: - quizzes = Quiz.objects.all() - context = {'papers': [], - 'quiz': None, - 'quizzes': quizzes} - return my_render_to_response('yaksh/show_quiz.html', context, - 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} - return my_render_to_response('yaksh/show_quiz.html', context, - context_instance=ci) - - elif request.method == 'POST' and request.POST.get('edit') == 'edit': - data = request.POST.getlist('quiz') - forms = [] - for j in data: - d = Quiz.objects.get(id=j) - form = QuizForm() - form.initial['start_date'] = d.start_date_time.date() - form.initial['start_time'] = d.start_date_time.time() - form.initial['end_date'] = d.end_date_time.date() - form.initial['end_time'] = d.end_date_time.time() - form.initial['duration'] = d.duration - form.initial['active'] = d.active - form.initial['description'] = d.description - form.initial['pass_criteria'] = d.pass_criteria - form.initial['language'] = d.language - form.initial['prerequisite'] = d.prerequisite_id - forms.append(form) - return my_render_to_response('yaksh/edit_quiz.html', - {'forms': forms, 'data': data}, - context_instance=ci) - else: - quizzes = Quiz.objects.all() - context = {'papers': [], - 'quiz': None, - 'quizzes': quizzes} - return my_render_to_response('yaksh/show_quiz.html', context, - context_instance=ci) - - -@csrf_exempt -def ajax_questions_filter(request): - """Ajax call made when filtering displayed questions.""" - - filter_dict = {} - question_type = request.POST.get('question_type') - marks = request.POST.get('marks') - language = request.POST.get('language') - - if question_type != "select": - filter_dict['type'] = str(question_type) - - if marks != "select": - filter_dict['points'] = marks - - if language != "select": - filter_dict['language'] = str(language) - - questions = list(Question.objects.filter(**filter_dict)) - - return my_render_to_response('yaksh/ajax_question_filter.html', - {'questions': questions}) - - -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 !") - - if request.method == 'POST' and request.POST.get('delete') == 'delete': - data = request.POST.getlist('question') - if data is None: - questions = Question.objects.all() - form = QuestionFilterForm() - context = {'papers': [], - 'question': None, - 'questions': questions, - 'form': form - } - return my_render_to_response('yaksh/showquestions.html', context, - context_instance=ci) - else: - for i in data: - question = Question.objects.get(id=i).delete() - questions = Question.objects.all() - form = QuestionFilterForm() - context = {'papers': [], - 'question': None, - 'questions': questions, - 'form': form - } - return my_render_to_response('yaksh/showquestions.html', context, - context_instance=ci) - elif request.method == 'POST' and request.POST.get('edit') == 'edit': - data = request.POST.getlist('question') - - forms = [] - formsets = [] - for j in data: - d = Question.objects.get(id=j) - form = QuestionForm() - form.initial['summary'] = d.summary - form.initial['description'] = d.description - form.initial['points'] = d.points - form.initial['options'] = d.options - form.initial['type'] = d.type - form.initial['active'] = d.active - form.initial['language'] = d.language - form.initial['snippet'] = d.snippet - form.initial['ref_code_path'] = d.ref_code_path - form.initial['test'] = d.test - form_tags = d.tags.all() - form_tags_split = form_tags.values('name') - initial_tags = "" - for tag in form_tags_split: - initial_tags = initial_tags + str(tag['name']).strip() + "," - if (initial_tags == ","): - initial_tags = "" - form.initial['tags'] = initial_tags - forms.append(form) - test_case_formset = TestCaseFormSet(prefix='test', instance=d) - formsets.append(test_case_formset) - data_list = zip(forms, formsets) - - return my_render_to_response('yaksh/edit_question.html', - {'data': data, - 'data_list': data_list}, - context_instance=ci) - else: - questions = Question.objects.all() - form = QuestionFilterForm() - context = {'papers': [], - 'question': None, - 'questions': questions, - 'form': form - } - return my_render_to_response('yaksh/showquestions.html', context, - context_instance=ci) - - -def user_data(request, username): - """Render user data.""" - - current_user = request.user - if not current_user.is_authenticated() or not is_moderator(current_user): - raise Http404('You are not allowed to view this page!') - - data = get_user_data(username) - - context = {'data': data} - return my_render_to_response('yaksh/user_data.html', context, - context_instance=RequestContext(request)) - - -def grade_user(request, username): - """Present an interface with which we can easily grade a user's papers - 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!') - - data = get_user_data(username) - if request.method == 'POST': - papers = data['papers'] - for paper in papers: - for question, answers in paper.get_question_answers().iteritems(): - marks = float(request.POST.get('q%d_marks' % question.id)) - last_ans = answers[-1] - last_ans.marks = marks - last_ans.save() - paper.comments = request.POST.get( - 'comments_%d' % paper.question_paper.id) - paper.save() - - context = {'data': data} - return my_render_to_response('yaksh/user_data.html', context, - context_instance=ci) - else: - context = {'data': data} - return my_render_to_response('yaksh/grade_user.html', context, - context_instance=ci) - - -@csrf_exempt -def ajax_questionpaper(request, query): - """ - During question paper creation, ajax call made to get question details. - """ - if query == 'marks': - question_type = request.POST.get('question_type') - questions = Question.objects.filter(type=question_type) - marks = questions.values_list('points').distinct() - return my_render_to_response('yaksh/ajax_marks.html', {'marks': marks}) - elif query == 'questions': - question_type = request.POST['question_type'] - marks_selected = request.POST['marks'] - fixed_questions = request.POST.getlist('fixed_list[]') - fixed_question_list = ",".join(fixed_questions).split(',') - random_questions = request.POST.getlist('random_list[]') - random_question_list = ",".join(random_questions).split(',') - question_list = fixed_question_list + random_question_list - questions = list(Question.objects.filter(type=question_type, - points=marks_selected)) - questions = [question for question in questions \ - if not str(question.id) in question_list] - return my_render_to_response('yaksh/ajax_questions.html', - {'questions': questions}) - - -def design_questionpaper(request): - 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': - fixed_questions = request.POST.getlist('fixed') - random_questions = request.POST.getlist('random') - random_number = request.POST.getlist('number') - is_shuffle = request.POST.get('shuffle_questions', False) - if is_shuffle == 'on': - is_shuffle = True - - question_paper = QuestionPaper(shuffle_questions=is_shuffle) - quiz = Quiz.objects.order_by("-id")[0] - tot_marks = 0 - question_paper.quiz = quiz - question_paper.total_marks = tot_marks - question_paper.save() - if fixed_questions: - fixed_questions_ids = ",".join(fixed_questions) - fixed_questions_ids_list = fixed_questions_ids.split(',') - for question_id in fixed_questions_ids_list: - question_paper.fixed_questions.add(question_id) - if random_questions: - for random_question, num in zip(random_questions, random_number): - qid = random_question.split(',')[0] - question = Question.objects.get(id=int(qid)) - marks = question.points - question_set = QuestionSet(marks=marks, num_questions=num) - question_set.save() - for question_id in random_question.split(','): - question_set.questions.add(question_id) - question_paper.random_questions.add(question_set) - question_paper.update_total_marks() - question_paper.save() - return my_redirect('/exam/manage/showquiz') - else: - form = RandomQuestionForm() - context = {'form': form} - return my_render_to_response('yaksh/design_questionpaper.html', - context, context_instance=ci) diff --git a/testapp/yaksh/xmlrpc_clients.py b/testapp/yaksh/xmlrpc_clients.py deleted file mode 100644 index 3a3c0c6..0000000 --- a/testapp/yaksh/xmlrpc_clients.py +++ /dev/null @@ -1,80 +0,0 @@ -from xmlrpclib import ServerProxy -import time -import random -import socket -import json - -from settings import SERVER_PORTS, SERVER_POOL_PORT - - -class ConnectionError(Exception): - pass - -############################################################################### -# `CodeServerProxy` class. -############################################################################### - - -class CodeServerProxy(object): - """A class that manages accesing the farm of Python servers and making - calls to them such that no one XMLRPC server is overloaded. - """ - def __init__(self): - pool_url = 'http://localhost:%d' % (SERVER_POOL_PORT) - self.pool_server = ServerProxy(pool_url) - - def run_code(self, language, json_data, user_dir): - """Tests given code (`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). The parameter language specifies which language to use for the - tests. - - Parameters - ---------- - json_data contains; - user_answer : str - The user's answer for the question. - test_code : str - The test code to check the user code with. - language : str - The programming language to use. - - user_dir : str (directory) - The directory to run the tests inside. - - - Returns - ------- - A json string of a dict: {success: success, err: error message}. - """ - - try: - server = self._get_server() - result = server.check_code(language, json_data, user_dir) - except ConnectionError: - result = json.dumps({'success': False, 'error': 'Unable to connect to any code servers!'}) - return result - - def _get_server(self): - # Get a suitable server from our pool of servers. This may block. We - # try about 60 times, essentially waiting at most for about 30 seconds. - done, count = False, 60 - - while not done and count > 0: - try: - port = self.pool_server.get_server_port() - except socket.error: - # Wait a while try again. - time.sleep(random.random()) - count -= 1 - else: - done = True - if not done: - raise ConnectionError("Couldn't connect to a server!") - proxy = ServerProxy('http://localhost:%d' % port) - return proxy - -# views.py calls this Python server which forwards the request to one -# of the running servers. -code_server = CodeServerProxy() -- cgit