summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--online_test/__init__.py1
-rw-r--r--setup.py9
-rw-r--r--yaksh/documentation/moderator_docs/creating_question.rst31
-rw-r--r--yaksh/migrations/0001_initial.py268
-rw-r--r--yaksh/migrations/__init__.py0
-rw-r--r--yaksh/models.py24
-rw-r--r--yaksh/scripts/cli.py28
-rw-r--r--yaksh/stdio_evaluator.py14
-rw-r--r--yaksh/templates/yaksh/add_question.html1
-rw-r--r--yaksh/templates/yaksh/grade_user.html15
-rw-r--r--yaksh/templates/yaksh/question.html1
-rw-r--r--yaksh/templates/yaksh/showquestions.html4
-rw-r--r--yaksh/templates/yaksh/user_data.html20
-rw-r--r--yaksh/templates/yaksh/view_answerpaper.html14
-rw-r--r--yaksh/views.py8
16 files changed, 403 insertions, 36 deletions
diff --git a/.gitignore b/.gitignore
index 38a5ebb..e14b151 100644
--- a/.gitignore
+++ b/.gitignore
@@ -38,7 +38,6 @@ apache/*
*.swo
*.db-journal
*.db
-migrations
wsgi.log
*.sqlite3
data/
diff --git a/online_test/__init__.py b/online_test/__init__.py
index e69de29..ef0b380 100644
--- a/online_test/__init__.py
+++ b/online_test/__init__.py
@@ -0,0 +1 @@
+__version__ = '0.1.3' \ No newline at end of file
diff --git a/setup.py b/setup.py
index 37ed948..c5dd77a 100644
--- a/setup.py
+++ b/setup.py
@@ -6,6 +6,13 @@ README = open(os.path.join(os.path.dirname(__file__), 'README.md')).read()
# allow setup.py to be run from any path
os.chdir(os.path.normpath(os.path.join(os.path.abspath(__file__), os.pardir)))
+def get_version():
+ import os
+ data = {}
+ fname = os.path.join('online_test', '__init__.py')
+ exec(compile(open(fname).read(), fname, 'exec'), data)
+ return data.get('__version__')
+
install_requires = [
'django==1.9.5',
'django-taggit==0.18.1',
@@ -18,7 +25,7 @@ setup(
name='yaksh',
author='Python Team at FOSSEE, IIT Bombay',
author_email='python@fossee.in',
- version='0.1.3',
+ version=get_version(),
packages=find_packages(),
include_package_data=True,
url='https://pypi.python.org/pypi/yaksh/',
diff --git a/yaksh/documentation/moderator_docs/creating_question.rst b/yaksh/documentation/moderator_docs/creating_question.rst
index f99bf7f..94bb95c 100644
--- a/yaksh/documentation/moderator_docs/creating_question.rst
+++ b/yaksh/documentation/moderator_docs/creating_question.rst
@@ -264,6 +264,37 @@ Features in Question
Click on the browse button. This will open up a window. Select the zip file of questions and click Ok and then click on Upload file button, questions will be uploaded and displayed on the Questions page.
+ Zip file should contain **questions_dump.json** from which questions will be loaded.
+ Zip file can contain files related to questions.
+ Sample entry in **questions_dump.json** is as shown below. ::
+ [{
+ "snippet": "",
+ "testcase": [
+ {
+ "test_case_args": "",
+ "test_case_type": "standardtestcase",
+ "weight": 1.0,
+ "test_case": "Test Case here"
+ },
+ ],
+ "points": 2.0,
+ "description": "Question Description here",
+ "language": "python",
+ "active": true,
+ "type": "code",
+ "files": [[demo1.txt, false], [demo2.zip, true]],
+ "summary": "Question Summary here"
+ }]
+
+ .. Note:: 1. In **files** entry in json, the list contains two items which
+ are filename (demo1.txt) and extract status (false) i.e file needs to extracted or not.
+
+ 2. If there are no files then **files** entry can be empty
+ i.e it should be "files": [].
+
+ 3. From sample, zip file should contain demo1.txt and demo2.zip since it is
+ required for question.
+
* **Test Questions**
Select questions from the list of question displayed on the Questions page. Click on Test selected button. This will take you to a quiz with the selected questions.
diff --git a/yaksh/migrations/0001_initial.py b/yaksh/migrations/0001_initial.py
new file mode 100644
index 0000000..8ee8c6a
--- /dev/null
+++ b/yaksh/migrations/0001_initial.py
@@ -0,0 +1,268 @@
+# -*- coding: utf-8 -*-
+# Generated by Django 1.9.5 on 2017-03-14 08:33
+from __future__ import unicode_literals
+
+import datetime
+from django.conf import settings
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+from django.utils.timezone import utc
+import taggit.managers
+import yaksh.models
+
+
+class Migration(migrations.Migration):
+
+ initial = True
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ('taggit', '0002_auto_20150616_2121'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='Answer',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('answer', models.TextField(blank=True, null=True)),
+ ('error', models.TextField()),
+ ('marks', models.FloatField(default=0.0)),
+ ('correct', models.BooleanField(default=False)),
+ ('skipped', models.BooleanField(default=False)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='AnswerPaper',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('attempt_number', models.IntegerField()),
+ ('start_time', models.DateTimeField()),
+ ('end_time', models.DateTimeField()),
+ ('user_ip', models.CharField(max_length=15)),
+ ('comments', models.TextField()),
+ ('marks_obtained', models.FloatField(default=0.0, null=True)),
+ ('percent', models.FloatField(default=0.0, null=True)),
+ ('passed', models.NullBooleanField()),
+ ('status', models.CharField(choices=[('inprogress', 'Inprogress'), ('completed', 'Completed')], default='inprogress', max_length=20)),
+ ('answers', models.ManyToManyField(to='yaksh.Answer')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='AssignmentUpload',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('assignmentFile', models.FileField(upload_to=yaksh.models.get_assignment_dir)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='ConcurrentUser',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('session_key', models.CharField(max_length=40)),
+ ('concurrent_user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Course',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('name', models.CharField(max_length=128)),
+ ('enrollment', models.CharField(choices=[('default', 'Enroll Request'), ('open', 'Open Course')], max_length=32)),
+ ('active', models.BooleanField(default=True)),
+ ('created_on', models.DateTimeField(auto_now_add=True)),
+ ('is_trial', models.BooleanField(default=False)),
+ ('instructions', models.TextField(blank=True, default=None, null=True)),
+ ('creator', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='creator', to=settings.AUTH_USER_MODEL)),
+ ('rejected', models.ManyToManyField(related_name='rejected', to=settings.AUTH_USER_MODEL)),
+ ('requests', models.ManyToManyField(related_name='requests', to=settings.AUTH_USER_MODEL)),
+ ('students', models.ManyToManyField(related_name='students', to=settings.AUTH_USER_MODEL)),
+ ('teachers', models.ManyToManyField(related_name='teachers', to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='FileUpload',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('file', models.FileField(blank=True, upload_to=yaksh.models.get_upload_dir)),
+ ('extract', models.BooleanField(default=False)),
+ ('hide', models.BooleanField(default=False)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Profile',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('roll_number', models.CharField(max_length=20)),
+ ('institute', models.CharField(max_length=128)),
+ ('department', models.CharField(max_length=64)),
+ ('position', models.CharField(max_length=64)),
+ ('timezone', models.CharField(choices=[('Africa/Abidjan', 'Africa/Abidjan'), ('Africa/Accra', 'Africa/Accra'), ('Africa/Addis_Ababa', 'Africa/Addis_Ababa'), ('Africa/Algiers', 'Africa/Algiers'), ('Africa/Asmara', 'Africa/Asmara'), ('Africa/Bamako', 'Africa/Bamako'), ('Africa/Bangui', 'Africa/Bangui'), ('Africa/Banjul', 'Africa/Banjul'), ('Africa/Bissau', 'Africa/Bissau'), ('Africa/Blantyre', 'Africa/Blantyre'), ('Africa/Brazzaville', 'Africa/Brazzaville'), ('Africa/Bujumbura', 'Africa/Bujumbura'), ('Africa/Cairo', 'Africa/Cairo'), ('Africa/Casablanca', 'Africa/Casablanca'), ('Africa/Ceuta', 'Africa/Ceuta'), ('Africa/Conakry', 'Africa/Conakry'), ('Africa/Dakar', 'Africa/Dakar'), ('Africa/Dar_es_Salaam', 'Africa/Dar_es_Salaam'), ('Africa/Djibouti', 'Africa/Djibouti'), ('Africa/Douala', 'Africa/Douala'), ('Africa/El_Aaiun', 'Africa/El_Aaiun'), ('Africa/Freetown', 'Africa/Freetown'), ('Africa/Gaborone', 'Africa/Gaborone'), ('Africa/Harare', 'Africa/Harare'), ('Africa/Johannesburg', 'Africa/Johannesburg'), ('Africa/Juba', 'Africa/Juba'), ('Africa/Kampala', 'Africa/Kampala'), ('Africa/Khartoum', 'Africa/Khartoum'), ('Africa/Kigali', 'Africa/Kigali'), ('Africa/Kinshasa', 'Africa/Kinshasa'), ('Africa/Lagos', 'Africa/Lagos'), ('Africa/Libreville', 'Africa/Libreville'), ('Africa/Lome', 'Africa/Lome'), ('Africa/Luanda', 'Africa/Luanda'), ('Africa/Lubumbashi', 'Africa/Lubumbashi'), ('Africa/Lusaka', 'Africa/Lusaka'), ('Africa/Malabo', 'Africa/Malabo'), ('Africa/Maputo', 'Africa/Maputo'), ('Africa/Maseru', 'Africa/Maseru'), ('Africa/Mbabane', 'Africa/Mbabane'), ('Africa/Mogadishu', 'Africa/Mogadishu'), ('Africa/Monrovia', 'Africa/Monrovia'), ('Africa/Nairobi', 'Africa/Nairobi'), ('Africa/Ndjamena', 'Africa/Ndjamena'), ('Africa/Niamey', 'Africa/Niamey'), ('Africa/Nouakchott', 'Africa/Nouakchott'), ('Africa/Ouagadougou', 'Africa/Ouagadougou'), ('Africa/Porto-Novo', 'Africa/Porto-Novo'), ('Africa/Sao_Tome', 'Africa/Sao_Tome'), ('Africa/Tripoli', 'Africa/Tripoli'), ('Africa/Tunis', 'Africa/Tunis'), ('Africa/Windhoek', 'Africa/Windhoek'), ('America/Adak', 'America/Adak'), ('America/Anchorage', 'America/Anchorage'), ('America/Anguilla', 'America/Anguilla'), ('America/Antigua', 'America/Antigua'), ('America/Araguaina', 'America/Araguaina'), ('America/Argentina/Buenos_Aires', 'America/Argentina/Buenos_Aires'), ('America/Argentina/Catamarca', 'America/Argentina/Catamarca'), ('America/Argentina/Cordoba', 'America/Argentina/Cordoba'), ('America/Argentina/Jujuy', 'America/Argentina/Jujuy'), ('America/Argentina/La_Rioja', 'America/Argentina/La_Rioja'), ('America/Argentina/Mendoza', 'America/Argentina/Mendoza'), ('America/Argentina/Rio_Gallegos', 'America/Argentina/Rio_Gallegos'), ('America/Argentina/Salta', 'America/Argentina/Salta'), ('America/Argentina/San_Juan', 'America/Argentina/San_Juan'), ('America/Argentina/San_Luis', 'America/Argentina/San_Luis'), ('America/Argentina/Tucuman', 'America/Argentina/Tucuman'), ('America/Argentina/Ushuaia', 'America/Argentina/Ushuaia'), ('America/Aruba', 'America/Aruba'), ('America/Asuncion', 'America/Asuncion'), ('America/Atikokan', 'America/Atikokan'), ('America/Bahia', 'America/Bahia'), ('America/Bahia_Banderas', 'America/Bahia_Banderas'), ('America/Barbados', 'America/Barbados'), ('America/Belem', 'America/Belem'), ('America/Belize', 'America/Belize'), ('America/Blanc-Sablon', 'America/Blanc-Sablon'), ('America/Boa_Vista', 'America/Boa_Vista'), ('America/Bogota', 'America/Bogota'), ('America/Boise', 'America/Boise'), ('America/Cambridge_Bay', 'America/Cambridge_Bay'), ('America/Campo_Grande', 'America/Campo_Grande'), ('America/Cancun', 'America/Cancun'), ('America/Caracas', 'America/Caracas'), ('America/Cayenne', 'America/Cayenne'), ('America/Cayman', 'America/Cayman'), ('America/Chicago', 'America/Chicago'), ('America/Chihuahua', 'America/Chihuahua'), ('America/Costa_Rica', 'America/Costa_Rica'), ('America/Creston', 'America/Creston'), ('America/Cuiaba', 'America/Cuiaba'), ('America/Curacao', 'America/Curacao'), ('America/Danmarkshavn', 'America/Danmarkshavn'), ('America/Dawson', 'America/Dawson'), ('America/Dawson_Creek', 'America/Dawson_Creek'), ('America/Denver', 'America/Denver'), ('America/Detroit', 'America/Detroit'), ('America/Dominica', 'America/Dominica'), ('America/Edmonton', 'America/Edmonton'), ('America/Eirunepe', 'America/Eirunepe'), ('America/El_Salvador', 'America/El_Salvador'), ('America/Fort_Nelson', 'America/Fort_Nelson'), ('America/Fortaleza', 'America/Fortaleza'), ('America/Glace_Bay', 'America/Glace_Bay'), ('America/Godthab', 'America/Godthab'), ('America/Goose_Bay', 'America/Goose_Bay'), ('America/Grand_Turk', 'America/Grand_Turk'), ('America/Grenada', 'America/Grenada'), ('America/Guadeloupe', 'America/Guadeloupe'), ('America/Guatemala', 'America/Guatemala'), ('America/Guayaquil', 'America/Guayaquil'), ('America/Guyana', 'America/Guyana'), ('America/Halifax', 'America/Halifax'), ('America/Havana', 'America/Havana'), ('America/Hermosillo', 'America/Hermosillo'), ('America/Indiana/Indianapolis', 'America/Indiana/Indianapolis'), ('America/Indiana/Knox', 'America/Indiana/Knox'), ('America/Indiana/Marengo', 'America/Indiana/Marengo'), ('America/Indiana/Petersburg', 'America/Indiana/Petersburg'), ('America/Indiana/Tell_City', 'America/Indiana/Tell_City'), ('America/Indiana/Vevay', 'America/Indiana/Vevay'), ('America/Indiana/Vincennes', 'America/Indiana/Vincennes'), ('America/Indiana/Winamac', 'America/Indiana/Winamac'), ('America/Inuvik', 'America/Inuvik'), ('America/Iqaluit', 'America/Iqaluit'), ('America/Jamaica', 'America/Jamaica'), ('America/Juneau', 'America/Juneau'), ('America/Kentucky/Louisville', 'America/Kentucky/Louisville'), ('America/Kentucky/Monticello', 'America/Kentucky/Monticello'), ('America/Kralendijk', 'America/Kralendijk'), ('America/La_Paz', 'America/La_Paz'), ('America/Lima', 'America/Lima'), ('America/Los_Angeles', 'America/Los_Angeles'), ('America/Lower_Princes', 'America/Lower_Princes'), ('America/Maceio', 'America/Maceio'), ('America/Managua', 'America/Managua'), ('America/Manaus', 'America/Manaus'), ('America/Marigot', 'America/Marigot'), ('America/Martinique', 'America/Martinique'), ('America/Matamoros', 'America/Matamoros'), ('America/Mazatlan', 'America/Mazatlan'), ('America/Menominee', 'America/Menominee'), ('America/Merida', 'America/Merida'), ('America/Metlakatla', 'America/Metlakatla'), ('America/Mexico_City', 'America/Mexico_City'), ('America/Miquelon', 'America/Miquelon'), ('America/Moncton', 'America/Moncton'), ('America/Monterrey', 'America/Monterrey'), ('America/Montevideo', 'America/Montevideo'), ('America/Montserrat', 'America/Montserrat'), ('America/Nassau', 'America/Nassau'), ('America/New_York', 'America/New_York'), ('America/Nipigon', 'America/Nipigon'), ('America/Nome', 'America/Nome'), ('America/Noronha', 'America/Noronha'), ('America/North_Dakota/Beulah', 'America/North_Dakota/Beulah'), ('America/North_Dakota/Center', 'America/North_Dakota/Center'), ('America/North_Dakota/New_Salem', 'America/North_Dakota/New_Salem'), ('America/Ojinaga', 'America/Ojinaga'), ('America/Panama', 'America/Panama'), ('America/Pangnirtung', 'America/Pangnirtung'), ('America/Paramaribo', 'America/Paramaribo'), ('America/Phoenix', 'America/Phoenix'), ('America/Port-au-Prince', 'America/Port-au-Prince'), ('America/Port_of_Spain', 'America/Port_of_Spain'), ('America/Porto_Velho', 'America/Porto_Velho'), ('America/Puerto_Rico', 'America/Puerto_Rico'), ('America/Rainy_River', 'America/Rainy_River'), ('America/Rankin_Inlet', 'America/Rankin_Inlet'), ('America/Recife', 'America/Recife'), ('America/Regina', 'America/Regina'), ('America/Resolute', 'America/Resolute'), ('America/Rio_Branco', 'America/Rio_Branco'), ('America/Santarem', 'America/Santarem'), ('America/Santiago', 'America/Santiago'), ('America/Santo_Domingo', 'America/Santo_Domingo'), ('America/Sao_Paulo', 'America/Sao_Paulo'), ('America/Scoresbysund', 'America/Scoresbysund'), ('America/Sitka', 'America/Sitka'), ('America/St_Barthelemy', 'America/St_Barthelemy'), ('America/St_Johns', 'America/St_Johns'), ('America/St_Kitts', 'America/St_Kitts'), ('America/St_Lucia', 'America/St_Lucia'), ('America/St_Thomas', 'America/St_Thomas'), ('America/St_Vincent', 'America/St_Vincent'), ('America/Swift_Current', 'America/Swift_Current'), ('America/Tegucigalpa', 'America/Tegucigalpa'), ('America/Thule', 'America/Thule'), ('America/Thunder_Bay', 'America/Thunder_Bay'), ('America/Tijuana', 'America/Tijuana'), ('America/Toronto', 'America/Toronto'), ('America/Tortola', 'America/Tortola'), ('America/Vancouver', 'America/Vancouver'), ('America/Whitehorse', 'America/Whitehorse'), ('America/Winnipeg', 'America/Winnipeg'), ('America/Yakutat', 'America/Yakutat'), ('America/Yellowknife', 'America/Yellowknife'), ('Antarctica/Casey', 'Antarctica/Casey'), ('Antarctica/Davis', 'Antarctica/Davis'), ('Antarctica/DumontDUrville', 'Antarctica/DumontDUrville'), ('Antarctica/Macquarie', 'Antarctica/Macquarie'), ('Antarctica/Mawson', 'Antarctica/Mawson'), ('Antarctica/McMurdo', 'Antarctica/McMurdo'), ('Antarctica/Palmer', 'Antarctica/Palmer'), ('Antarctica/Rothera', 'Antarctica/Rothera'), ('Antarctica/Syowa', 'Antarctica/Syowa'), ('Antarctica/Troll', 'Antarctica/Troll'), ('Antarctica/Vostok', 'Antarctica/Vostok'), ('Arctic/Longyearbyen', 'Arctic/Longyearbyen'), ('Asia/Aden', 'Asia/Aden'), ('Asia/Almaty', 'Asia/Almaty'), ('Asia/Amman', 'Asia/Amman'), ('Asia/Anadyr', 'Asia/Anadyr'), ('Asia/Aqtau', 'Asia/Aqtau'), ('Asia/Aqtobe', 'Asia/Aqtobe'), ('Asia/Ashgabat', 'Asia/Ashgabat'), ('Asia/Baghdad', 'Asia/Baghdad'), ('Asia/Bahrain', 'Asia/Bahrain'), ('Asia/Baku', 'Asia/Baku'), ('Asia/Bangkok', 'Asia/Bangkok'), ('Asia/Barnaul', 'Asia/Barnaul'), ('Asia/Beirut', 'Asia/Beirut'), ('Asia/Bishkek', 'Asia/Bishkek'), ('Asia/Brunei', 'Asia/Brunei'), ('Asia/Chita', 'Asia/Chita'), ('Asia/Choibalsan', 'Asia/Choibalsan'), ('Asia/Colombo', 'Asia/Colombo'), ('Asia/Damascus', 'Asia/Damascus'), ('Asia/Dhaka', 'Asia/Dhaka'), ('Asia/Dili', 'Asia/Dili'), ('Asia/Dubai', 'Asia/Dubai'), ('Asia/Dushanbe', 'Asia/Dushanbe'), ('Asia/Gaza', 'Asia/Gaza'), ('Asia/Hebron', 'Asia/Hebron'), ('Asia/Ho_Chi_Minh', 'Asia/Ho_Chi_Minh'), ('Asia/Hong_Kong', 'Asia/Hong_Kong'), ('Asia/Hovd', 'Asia/Hovd'), ('Asia/Irkutsk', 'Asia/Irkutsk'), ('Asia/Jakarta', 'Asia/Jakarta'), ('Asia/Jayapura', 'Asia/Jayapura'), ('Asia/Jerusalem', 'Asia/Jerusalem'), ('Asia/Kabul', 'Asia/Kabul'), ('Asia/Kamchatka', 'Asia/Kamchatka'), ('Asia/Karachi', 'Asia/Karachi'), ('Asia/Kathmandu', 'Asia/Kathmandu'), ('Asia/Khandyga', 'Asia/Khandyga'), ('Asia/Kolkata', 'Asia/Kolkata'), ('Asia/Krasnoyarsk', 'Asia/Krasnoyarsk'), ('Asia/Kuala_Lumpur', 'Asia/Kuala_Lumpur'), ('Asia/Kuching', 'Asia/Kuching'), ('Asia/Kuwait', 'Asia/Kuwait'), ('Asia/Macau', 'Asia/Macau'), ('Asia/Magadan', 'Asia/Magadan'), ('Asia/Makassar', 'Asia/Makassar'), ('Asia/Manila', 'Asia/Manila'), ('Asia/Muscat', 'Asia/Muscat'), ('Asia/Nicosia', 'Asia/Nicosia'), ('Asia/Novokuznetsk', 'Asia/Novokuznetsk'), ('Asia/Novosibirsk', 'Asia/Novosibirsk'), ('Asia/Omsk', 'Asia/Omsk'), ('Asia/Oral', 'Asia/Oral'), ('Asia/Phnom_Penh', 'Asia/Phnom_Penh'), ('Asia/Pontianak', 'Asia/Pontianak'), ('Asia/Pyongyang', 'Asia/Pyongyang'), ('Asia/Qatar', 'Asia/Qatar'), ('Asia/Qyzylorda', 'Asia/Qyzylorda'), ('Asia/Rangoon', 'Asia/Rangoon'), ('Asia/Riyadh', 'Asia/Riyadh'), ('Asia/Sakhalin', 'Asia/Sakhalin'), ('Asia/Samarkand', 'Asia/Samarkand'), ('Asia/Seoul', 'Asia/Seoul'), ('Asia/Shanghai', 'Asia/Shanghai'), ('Asia/Singapore', 'Asia/Singapore'), ('Asia/Srednekolymsk', 'Asia/Srednekolymsk'), ('Asia/Taipei', 'Asia/Taipei'), ('Asia/Tashkent', 'Asia/Tashkent'), ('Asia/Tbilisi', 'Asia/Tbilisi'), ('Asia/Tehran', 'Asia/Tehran'), ('Asia/Thimphu', 'Asia/Thimphu'), ('Asia/Tokyo', 'Asia/Tokyo'), ('Asia/Tomsk', 'Asia/Tomsk'), ('Asia/Ulaanbaatar', 'Asia/Ulaanbaatar'), ('Asia/Urumqi', 'Asia/Urumqi'), ('Asia/Ust-Nera', 'Asia/Ust-Nera'), ('Asia/Vientiane', 'Asia/Vientiane'), ('Asia/Vladivostok', 'Asia/Vladivostok'), ('Asia/Yakutsk', 'Asia/Yakutsk'), ('Asia/Yekaterinburg', 'Asia/Yekaterinburg'), ('Asia/Yerevan', 'Asia/Yerevan'), ('Atlantic/Azores', 'Atlantic/Azores'), ('Atlantic/Bermuda', 'Atlantic/Bermuda'), ('Atlantic/Canary', 'Atlantic/Canary'), ('Atlantic/Cape_Verde', 'Atlantic/Cape_Verde'), ('Atlantic/Faroe', 'Atlantic/Faroe'), ('Atlantic/Madeira', 'Atlantic/Madeira'), ('Atlantic/Reykjavik', 'Atlantic/Reykjavik'), ('Atlantic/South_Georgia', 'Atlantic/South_Georgia'), ('Atlantic/St_Helena', 'Atlantic/St_Helena'), ('Atlantic/Stanley', 'Atlantic/Stanley'), ('Australia/Adelaide', 'Australia/Adelaide'), ('Australia/Brisbane', 'Australia/Brisbane'), ('Australia/Broken_Hill', 'Australia/Broken_Hill'), ('Australia/Currie', 'Australia/Currie'), ('Australia/Darwin', 'Australia/Darwin'), ('Australia/Eucla', 'Australia/Eucla'), ('Australia/Hobart', 'Australia/Hobart'), ('Australia/Lindeman', 'Australia/Lindeman'), ('Australia/Lord_Howe', 'Australia/Lord_Howe'), ('Australia/Melbourne', 'Australia/Melbourne'), ('Australia/Perth', 'Australia/Perth'), ('Australia/Sydney', 'Australia/Sydney'), ('Canada/Atlantic', 'Canada/Atlantic'), ('Canada/Central', 'Canada/Central'), ('Canada/Eastern', 'Canada/Eastern'), ('Canada/Mountain', 'Canada/Mountain'), ('Canada/Newfoundland', 'Canada/Newfoundland'), ('Canada/Pacific', 'Canada/Pacific'), ('Europe/Amsterdam', 'Europe/Amsterdam'), ('Europe/Andorra', 'Europe/Andorra'), ('Europe/Astrakhan', 'Europe/Astrakhan'), ('Europe/Athens', 'Europe/Athens'), ('Europe/Belgrade', 'Europe/Belgrade'), ('Europe/Berlin', 'Europe/Berlin'), ('Europe/Bratislava', 'Europe/Bratislava'), ('Europe/Brussels', 'Europe/Brussels'), ('Europe/Bucharest', 'Europe/Bucharest'), ('Europe/Budapest', 'Europe/Budapest'), ('Europe/Busingen', 'Europe/Busingen'), ('Europe/Chisinau', 'Europe/Chisinau'), ('Europe/Copenhagen', 'Europe/Copenhagen'), ('Europe/Dublin', 'Europe/Dublin'), ('Europe/Gibraltar', 'Europe/Gibraltar'), ('Europe/Guernsey', 'Europe/Guernsey'), ('Europe/Helsinki', 'Europe/Helsinki'), ('Europe/Isle_of_Man', 'Europe/Isle_of_Man'), ('Europe/Istanbul', 'Europe/Istanbul'), ('Europe/Jersey', 'Europe/Jersey'), ('Europe/Kaliningrad', 'Europe/Kaliningrad'), ('Europe/Kiev', 'Europe/Kiev'), ('Europe/Kirov', 'Europe/Kirov'), ('Europe/Lisbon', 'Europe/Lisbon'), ('Europe/Ljubljana', 'Europe/Ljubljana'), ('Europe/London', 'Europe/London'), ('Europe/Luxembourg', 'Europe/Luxembourg'), ('Europe/Madrid', 'Europe/Madrid'), ('Europe/Malta', 'Europe/Malta'), ('Europe/Mariehamn', 'Europe/Mariehamn'), ('Europe/Minsk', 'Europe/Minsk'), ('Europe/Monaco', 'Europe/Monaco'), ('Europe/Moscow', 'Europe/Moscow'), ('Europe/Oslo', 'Europe/Oslo'), ('Europe/Paris', 'Europe/Paris'), ('Europe/Podgorica', 'Europe/Podgorica'), ('Europe/Prague', 'Europe/Prague'), ('Europe/Riga', 'Europe/Riga'), ('Europe/Rome', 'Europe/Rome'), ('Europe/Samara', 'Europe/Samara'), ('Europe/San_Marino', 'Europe/San_Marino'), ('Europe/Sarajevo', 'Europe/Sarajevo'), ('Europe/Simferopol', 'Europe/Simferopol'), ('Europe/Skopje', 'Europe/Skopje'), ('Europe/Sofia', 'Europe/Sofia'), ('Europe/Stockholm', 'Europe/Stockholm'), ('Europe/Tallinn', 'Europe/Tallinn'), ('Europe/Tirane', 'Europe/Tirane'), ('Europe/Ulyanovsk', 'Europe/Ulyanovsk'), ('Europe/Uzhgorod', 'Europe/Uzhgorod'), ('Europe/Vaduz', 'Europe/Vaduz'), ('Europe/Vatican', 'Europe/Vatican'), ('Europe/Vienna', 'Europe/Vienna'), ('Europe/Vilnius', 'Europe/Vilnius'), ('Europe/Volgograd', 'Europe/Volgograd'), ('Europe/Warsaw', 'Europe/Warsaw'), ('Europe/Zagreb', 'Europe/Zagreb'), ('Europe/Zaporozhye', 'Europe/Zaporozhye'), ('Europe/Zurich', 'Europe/Zurich'), ('GMT', 'GMT'), ('Indian/Antananarivo', 'Indian/Antananarivo'), ('Indian/Chagos', 'Indian/Chagos'), ('Indian/Christmas', 'Indian/Christmas'), ('Indian/Cocos', 'Indian/Cocos'), ('Indian/Comoro', 'Indian/Comoro'), ('Indian/Kerguelen', 'Indian/Kerguelen'), ('Indian/Mahe', 'Indian/Mahe'), ('Indian/Maldives', 'Indian/Maldives'), ('Indian/Mauritius', 'Indian/Mauritius'), ('Indian/Mayotte', 'Indian/Mayotte'), ('Indian/Reunion', 'Indian/Reunion'), ('Pacific/Apia', 'Pacific/Apia'), ('Pacific/Auckland', 'Pacific/Auckland'), ('Pacific/Bougainville', 'Pacific/Bougainville'), ('Pacific/Chatham', 'Pacific/Chatham'), ('Pacific/Chuuk', 'Pacific/Chuuk'), ('Pacific/Easter', 'Pacific/Easter'), ('Pacific/Efate', 'Pacific/Efate'), ('Pacific/Enderbury', 'Pacific/Enderbury'), ('Pacific/Fakaofo', 'Pacific/Fakaofo'), ('Pacific/Fiji', 'Pacific/Fiji'), ('Pacific/Funafuti', 'Pacific/Funafuti'), ('Pacific/Galapagos', 'Pacific/Galapagos'), ('Pacific/Gambier', 'Pacific/Gambier'), ('Pacific/Guadalcanal', 'Pacific/Guadalcanal'), ('Pacific/Guam', 'Pacific/Guam'), ('Pacific/Honolulu', 'Pacific/Honolulu'), ('Pacific/Johnston', 'Pacific/Johnston'), ('Pacific/Kiritimati', 'Pacific/Kiritimati'), ('Pacific/Kosrae', 'Pacific/Kosrae'), ('Pacific/Kwajalein', 'Pacific/Kwajalein'), ('Pacific/Majuro', 'Pacific/Majuro'), ('Pacific/Marquesas', 'Pacific/Marquesas'), ('Pacific/Midway', 'Pacific/Midway'), ('Pacific/Nauru', 'Pacific/Nauru'), ('Pacific/Niue', 'Pacific/Niue'), ('Pacific/Norfolk', 'Pacific/Norfolk'), ('Pacific/Noumea', 'Pacific/Noumea'), ('Pacific/Pago_Pago', 'Pacific/Pago_Pago'), ('Pacific/Palau', 'Pacific/Palau'), ('Pacific/Pitcairn', 'Pacific/Pitcairn'), ('Pacific/Pohnpei', 'Pacific/Pohnpei'), ('Pacific/Port_Moresby', 'Pacific/Port_Moresby'), ('Pacific/Rarotonga', 'Pacific/Rarotonga'), ('Pacific/Saipan', 'Pacific/Saipan'), ('Pacific/Tahiti', 'Pacific/Tahiti'), ('Pacific/Tarawa', 'Pacific/Tarawa'), ('Pacific/Tongatapu', 'Pacific/Tongatapu'), ('Pacific/Wake', 'Pacific/Wake'), ('Pacific/Wallis', 'Pacific/Wallis'), ('US/Alaska', 'US/Alaska'), ('US/Arizona', 'US/Arizona'), ('US/Central', 'US/Central'), ('US/Eastern', 'US/Eastern'), ('US/Hawaii', 'US/Hawaii'), ('US/Mountain', 'US/Mountain'), ('US/Pacific', 'US/Pacific'), ('UTC', 'UTC')], default='UTC', max_length=64)),
+ ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Question',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('summary', models.CharField(max_length=256)),
+ ('description', models.TextField()),
+ ('points', models.FloatField(default=1.0)),
+ ('language', models.CharField(choices=[('python', 'Python'), ('bash', 'Bash'), ('c', 'C Language'), ('cpp', 'C++ Language'), ('java', 'Java Language'), ('scilab', 'Scilab')], max_length=24)),
+ ('type', models.CharField(choices=[('mcq', 'Multiple Choice'), ('mcc', 'Multiple Correct Choices'), ('code', 'Code'), ('upload', 'Assignment Upload')], max_length=24)),
+ ('active', models.BooleanField(default=True)),
+ ('snippet', models.CharField(blank=True, max_length=256)),
+ ('partial_grading', models.BooleanField(default=False)),
+ ('tags', taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
+ ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user', to=settings.AUTH_USER_MODEL)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='QuestionPaper',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('shuffle_questions', models.BooleanField(default=False)),
+ ('total_marks', models.FloatField(blank=True, default=0.0)),
+ ('fixed_questions', models.ManyToManyField(to='yaksh.Question')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='QuestionSet',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('marks', models.FloatField()),
+ ('num_questions', models.IntegerField()),
+ ('questions', models.ManyToManyField(to='yaksh.Question')),
+ ],
+ ),
+ migrations.CreateModel(
+ name='Quiz',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('start_date_time', models.DateTimeField(default=django.utils.timezone.now, null=True, verbose_name='Start Date and Time of the quiz')),
+ ('end_date_time', models.DateTimeField(default=datetime.datetime(2199, 1, 1, 0, 0, tzinfo=utc), null=True, verbose_name='End Date and Time of the quiz')),
+ ('duration', models.IntegerField(default=20, verbose_name='Duration of quiz in minutes')),
+ ('active', models.BooleanField(default=True)),
+ ('description', models.CharField(max_length=256)),
+ ('pass_criteria', models.FloatField(default=40, verbose_name='Passing percentage')),
+ ('language', models.CharField(choices=[('python', 'Python'), ('bash', 'Bash'), ('c', 'C Language'), ('cpp', 'C++ Language'), ('java', 'Java Language'), ('scilab', 'Scilab')], max_length=20)),
+ ('attempts_allowed', models.IntegerField(choices=[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (-1, 'Infinite')], default=1)),
+ ('time_between_attempts', models.IntegerField(choices=[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9), (10, 10), (11, 11), (12, 12), (13, 13), (14, 14), (15, 15), (16, 16), (17, 17), (18, 18), (19, 19), (20, 20), (21, 21), (22, 22), (23, 23), (24, 24), (25, 25), (26, 26), (27, 27), (28, 28), (29, 29), (30, 30), (31, 31), (32, 32), (33, 33), (34, 34), (35, 35), (36, 36), (37, 37), (38, 38), (39, 39), (40, 40), (41, 41), (42, 42), (43, 43), (44, 44), (45, 45), (46, 46), (47, 47), (48, 48), (49, 49), (50, 50), (51, 51), (52, 52), (53, 53), (54, 54), (55, 55), (56, 56), (57, 57), (58, 58), (59, 59), (60, 60), (61, 61), (62, 62), (63, 63), (64, 64), (65, 65), (66, 66), (67, 67), (68, 68), (69, 69), (70, 70), (71, 71), (72, 72), (73, 73), (74, 74), (75, 75), (76, 76), (77, 77), (78, 78), (79, 79), (80, 80), (81, 81), (82, 82), (83, 83), (84, 84), (85, 85), (86, 86), (87, 87), (88, 88), (89, 89), (90, 90), (91, 91), (92, 92), (93, 93), (94, 94), (95, 95), (96, 96), (97, 97), (98, 98), (99, 99), (100, 100), (101, 101), (102, 102), (103, 103), (104, 104), (105, 105), (106, 106), (107, 107), (108, 108), (109, 109), (110, 110), (111, 111), (112, 112), (113, 113), (114, 114), (115, 115), (116, 116), (117, 117), (118, 118), (119, 119), (120, 120), (121, 121), (122, 122), (123, 123), (124, 124), (125, 125), (126, 126), (127, 127), (128, 128), (129, 129), (130, 130), (131, 131), (132, 132), (133, 133), (134, 134), (135, 135), (136, 136), (137, 137), (138, 138), (139, 139), (140, 140), (141, 141), (142, 142), (143, 143), (144, 144), (145, 145), (146, 146), (147, 147), (148, 148), (149, 149), (150, 150), (151, 151), (152, 152), (153, 153), (154, 154), (155, 155), (156, 156), (157, 157), (158, 158), (159, 159), (160, 160), (161, 161), (162, 162), (163, 163), (164, 164), (165, 165), (166, 166), (167, 167), (168, 168), (169, 169), (170, 170), (171, 171), (172, 172), (173, 173), (174, 174), (175, 175), (176, 176), (177, 177), (178, 178), (179, 179), (180, 180), (181, 181), (182, 182), (183, 183), (184, 184), (185, 185), (186, 186), (187, 187), (188, 188), (189, 189), (190, 190), (191, 191), (192, 192), (193, 193), (194, 194), (195, 195), (196, 196), (197, 197), (198, 198), (199, 199), (200, 200), (201, 201), (202, 202), (203, 203), (204, 204), (205, 205), (206, 206), (207, 207), (208, 208), (209, 209), (210, 210), (211, 211), (212, 212), (213, 213), (214, 214), (215, 215), (216, 216), (217, 217), (218, 218), (219, 219), (220, 220), (221, 221), (222, 222), (223, 223), (224, 224), (225, 225), (226, 226), (227, 227), (228, 228), (229, 229), (230, 230), (231, 231), (232, 232), (233, 233), (234, 234), (235, 235), (236, 236), (237, 237), (238, 238), (239, 239), (240, 240), (241, 241), (242, 242), (243, 243), (244, 244), (245, 245), (246, 246), (247, 247), (248, 248), (249, 249), (250, 250), (251, 251), (252, 252), (253, 253), (254, 254), (255, 255), (256, 256), (257, 257), (258, 258), (259, 259), (260, 260), (261, 261), (262, 262), (263, 263), (264, 264), (265, 265), (266, 266), (267, 267), (268, 268), (269, 269), (270, 270), (271, 271), (272, 272), (273, 273), (274, 274), (275, 275), (276, 276), (277, 277), (278, 278), (279, 279), (280, 280), (281, 281), (282, 282), (283, 283), (284, 284), (285, 285), (286, 286), (287, 287), (288, 288), (289, 289), (290, 290), (291, 291), (292, 292), (293, 293), (294, 294), (295, 295), (296, 296), (297, 297), (298, 298), (299, 299), (300, 300), (301, 301), (302, 302), (303, 303), (304, 304), (305, 305), (306, 306), (307, 307), (308, 308), (309, 309), (310, 310), (311, 311), (312, 312), (313, 313), (314, 314), (315, 315), (316, 316), (317, 317), (318, 318), (319, 319), (320, 320), (321, 321), (322, 322), (323, 323), (324, 324), (325, 325), (326, 326), (327, 327), (328, 328), (329, 329), (330, 330), (331, 331), (332, 332), (333, 333), (334, 334), (335, 335), (336, 336), (337, 337), (338, 338), (339, 339), (340, 340), (341, 341), (342, 342), (343, 343), (344, 344), (345, 345), (346, 346), (347, 347), (348, 348), (349, 349), (350, 350), (351, 351), (352, 352), (353, 353), (354, 354), (355, 355), (356, 356), (357, 357), (358, 358), (359, 359), (360, 360), (361, 361), (362, 362), (363, 363), (364, 364), (365, 365), (366, 366), (367, 367), (368, 368), (369, 369), (370, 370), (371, 371), (372, 372), (373, 373), (374, 374), (375, 375), (376, 376), (377, 377), (378, 378), (379, 379), (380, 380), (381, 381), (382, 382), (383, 383), (384, 384), (385, 385), (386, 386), (387, 387), (388, 388), (389, 389), (390, 390), (391, 391), (392, 392), (393, 393), (394, 394), (395, 395), (396, 396), (397, 397), (398, 398), (399, 399), (400, 400)], verbose_name='Number of Days')),
+ ('is_trial', models.BooleanField(default=False)),
+ ('instructions', models.TextField(blank=True, default=None, null=True, verbose_name='Instructions for Students')),
+ ('view_answerpaper', models.BooleanField(default=False, verbose_name='Allow student to view their answer paper')),
+ ('allow_skip', models.BooleanField(default=True, verbose_name='Allow students to skip questions')),
+ ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.Course')),
+ ('prerequisite', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='yaksh.Quiz')),
+ ],
+ options={
+ 'verbose_name_plural': 'Quizzes',
+ },
+ ),
+ migrations.CreateModel(
+ name='TestCase',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('type', models.CharField(choices=[('standardtestcase', 'Standard Testcase'), ('stdiobasedtestcase', 'StdIO Based Testcase'), ('mcqtestcase', 'MCQ Testcase'), ('hooktestcase', 'Hook Testcase')], max_length=24, null=True)),
+ ],
+ ),
+ migrations.CreateModel(
+ name='HookTestCase',
+ fields=[
+ ('testcase_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='yaksh.TestCase')),
+ ('hook_code', models.TextField(default='def check_answer(user_answer):\n \'\'\' Evaluates user answer to return -\n success - Boolean, indicating if code was executed correctly\n mark_fraction - Float, indicating fraction of the\n weight to a test case\n error - String, error message if success is false\'\'\'\n success = False\n err = "Incorrect Answer" # Please make this more specific\n mark_fraction = 0.0\n\n # write your code here\n\n return success, err, mark_fraction\n\n')),
+ ('weight', models.FloatField(default=1.0)),
+ ],
+ bases=('yaksh.testcase',),
+ ),
+ migrations.CreateModel(
+ name='McqTestCase',
+ fields=[
+ ('testcase_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='yaksh.TestCase')),
+ ('options', models.TextField(default=None)),
+ ('correct', models.BooleanField(default=False)),
+ ],
+ bases=('yaksh.testcase',),
+ ),
+ migrations.CreateModel(
+ name='StandardTestCase',
+ fields=[
+ ('testcase_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='yaksh.TestCase')),
+ ('test_case', models.TextField()),
+ ('weight', models.FloatField(default=1.0)),
+ ('test_case_args', models.TextField(blank=True)),
+ ],
+ bases=('yaksh.testcase',),
+ ),
+ migrations.CreateModel(
+ name='StdIOBasedTestCase',
+ fields=[
+ ('testcase_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='yaksh.TestCase')),
+ ('expected_input', models.TextField(blank=True, default=None, null=True)),
+ ('expected_output', models.TextField(default=None)),
+ ('weight', models.IntegerField(default=1.0)),
+ ],
+ bases=('yaksh.testcase',),
+ ),
+ migrations.AddField(
+ model_name='testcase',
+ name='question',
+ field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='yaksh.Question'),
+ ),
+ migrations.AddField(
+ model_name='questionpaper',
+ name='quiz',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.Quiz'),
+ ),
+ migrations.AddField(
+ model_name='questionpaper',
+ name='random_questions',
+ field=models.ManyToManyField(to='yaksh.QuestionSet'),
+ ),
+ migrations.AddField(
+ model_name='fileupload',
+ name='question',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='question', to='yaksh.Question'),
+ ),
+ migrations.AddField(
+ model_name='assignmentupload',
+ name='assignmentQuestion',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.Question'),
+ ),
+ migrations.AddField(
+ model_name='assignmentupload',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.Profile'),
+ ),
+ migrations.AddField(
+ model_name='answerpaper',
+ name='question_paper',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.QuestionPaper'),
+ ),
+ migrations.AddField(
+ model_name='answerpaper',
+ name='questions',
+ field=models.ManyToManyField(related_name='questions', to='yaksh.Question'),
+ ),
+ migrations.AddField(
+ model_name='answerpaper',
+ name='questions_answered',
+ field=models.ManyToManyField(related_name='questions_answered', to='yaksh.Question'),
+ ),
+ migrations.AddField(
+ model_name='answerpaper',
+ name='questions_unanswered',
+ field=models.ManyToManyField(related_name='questions_unanswered', to='yaksh.Question'),
+ ),
+ migrations.AddField(
+ model_name='answerpaper',
+ name='user',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
+ ),
+ migrations.AddField(
+ model_name='answer',
+ name='question',
+ field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='yaksh.Question'),
+ ),
+ ]
diff --git a/yaksh/migrations/__init__.py b/yaksh/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/yaksh/migrations/__init__.py
diff --git a/yaksh/models.py b/yaksh/models.py
index 28af8f6..42e8714 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -15,6 +15,8 @@ except ImportError:
from io import BytesIO as string_io
import pytz
import os
+import sys
+import traceback
import stat
from os.path import join, exists
import shutil
@@ -66,7 +68,7 @@ test_status = (
def get_assignment_dir(instance, filename):
return os.sep.join((
- instance.user.user, instance.assignmentQuestion.id, filename
+ instance.user.user.username, str(instance.assignmentQuestion.id), filename
))
@@ -312,7 +314,11 @@ class Question(models.Model):
def load_questions(self, questions_list, user, file_path=None,
files_list=None):
- questions = json.loads(questions_list)
+ try:
+ questions = json.loads(questions_list)
+ except ValueError as exc_msg:
+ msg = "Error Parsing Json: {0}".format(exc_msg)
+ return msg
for question in questions:
question['user'] = user
file_names = question.pop('files')
@@ -329,8 +335,7 @@ class Question(models.Model):
)
new_test_case.type = test_case_type
new_test_case.save()
- if files_list:
- delete_files(files_list, file_path)
+ return "Questions Uploaded Successfully"
def get_test_cases(self, **kwargs):
tc_list = []
@@ -398,10 +403,17 @@ class Question(models.Model):
def read_json(self, file_path, user, files=None):
json_file = os.path.join(file_path, "questions_dump.json")
+ msg = ""
if os.path.exists(json_file):
with open(json_file, 'r') as q_file:
questions_list = q_file.read()
- self.load_questions(questions_list, user, file_path, files)
+ msg = self.load_questions(questions_list, user, file_path, files)
+ else:
+ msg = "Please upload zip file with questions_dump.json in it."
+
+ if files:
+ delete_files(files, file_path)
+ return msg
def create_demo_questions(self, user):
zip_file_path = os.path.join(
@@ -532,7 +544,7 @@ class Quiz(models.Model):
# The start date of the quiz.
start_date_time = models.DateTimeField(
"Start Date and Time of the quiz",
- default=timezone.now(),
+ default=timezone.now,
null=True
)
diff --git a/yaksh/scripts/cli.py b/yaksh/scripts/cli.py
index 4a58e48..a1a49ee 100644
--- a/yaksh/scripts/cli.py
+++ b/yaksh/scripts/cli.py
@@ -101,10 +101,6 @@ def create_demo(project_name='yaksh_demo', project_dir=CUR_DIR):
'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 migrate --run-syncdb "
- "--noinput --settings={0}.demo_settings").format(
- project_name)
-
loaddata_command = ("python ../manage.py loaddata "
"--settings={0}.demo_settings {1}").format(
project_name, fixture_path)
@@ -115,14 +111,18 @@ def create_demo(project_name='yaksh_demo', project_dir=CUR_DIR):
)
# Create demo_urls file
_render_demo_files(urls_template_path, urls_target_path)
- # Run syncdb
- subprocess.call(
- "{0}; {1}".format(command, loaddata_command), shell=True
- )
+ # Create database and load initial data
+ command_path = path.join(top_dir, 'manage.py')
+ _check_migrations(project_name, command_path)
+ _migrate(project_name, command_path)
+ subprocess.call(loaddata_command, shell=True)
def run_demo(project_name, top_dir):
with _chdir(top_dir):
+ command_path = path.join(top_dir, 'manage.py')
+ _check_migrations(project_name, command_path)
+ _migrate(project_name, command_path)
command = ("python manage.py runserver "
"--settings={0}.demo_settings").format(project_name)
subprocess.call(command, shell=True)
@@ -136,6 +136,18 @@ def run_server(args=None):
print("Error: {0}\nExiting yaksh code server".format(e))
+def _check_migrations(project_name, command_path):
+ migrations = ("python {0} makemigrations --settings={1}.demo_settings"
+ ).format(command_path, project_name)
+ subprocess.call(migrations, shell=True)
+
+
+def _migrate(project_name, command_path):
+ migrate = ("python {0} migrate --settings={1}.demo_settings"
+ ).format(command_path, project_name)
+ subprocess.call(migrate, shell=True)
+
+
def _render_demo_files(template_path, output_path, context=None):
with open(template_path, 'r') as template_file:
content = template_file.read()
diff --git a/yaksh/stdio_evaluator.py b/yaksh/stdio_evaluator.py
index fb9dfb3..fa78a68 100644
--- a/yaksh/stdio_evaluator.py
+++ b/yaksh/stdio_evaluator.py
@@ -14,17 +14,17 @@ class StdIOEvaluator(BaseEvaluator):
output_err = output_err_bytes.decode('utf-8')
expected_output = expected_output.replace("\r", "")
if not expected_input:
- error_msg = "Expected Output is {0} ".\
- format(repr(expected_output))
+ error_msg = "Expected Output is\n{0} ".\
+ format(str(expected_output))
else:
- error_msg = " Given Input is\n {0} \n Expected Output is {1} ".\
- format(expected_input, repr(expected_output))
+ error_msg = "Given Input is\n{0}\nExpected Output is\n{1}".\
+ format(expected_input, str(expected_output))
if output_err == '':
if user_output == expected_output:
success, err = True, None
else:
- err = " Incorrect answer\n" + error_msg +\
- "\n Your output is {0}".format(repr(user_output))
+ err = "Incorrect answer:\n" + error_msg +\
+ "\nYour output is\n{0}".format(str(user_output))
else:
- err = "Error:\n {0}".format(output_err)
+ err = "Error:\n{0}".format(output_err)
return success, err
diff --git a/yaksh/templates/yaksh/add_question.html b/yaksh/templates/yaksh/add_question.html
index 75802b4..b01ddc3 100644
--- a/yaksh/templates/yaksh/add_question.html
+++ b/yaksh/templates/yaksh/add_question.html
@@ -8,6 +8,7 @@
{% block script %}
<script src="{{ URL_ROOT }}/static/yaksh/js/add_question.js"></script>
+<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script>
{% endblock %}
{% block onload %} onload='javascript:textareaformat();' {% endblock %}
diff --git a/yaksh/templates/yaksh/grade_user.html b/yaksh/templates/yaksh/grade_user.html
index 63ff5eb..d20695b 100644
--- a/yaksh/templates/yaksh/grade_user.html
+++ b/yaksh/templates/yaksh/grade_user.html
@@ -4,6 +4,11 @@
{% block content %}
+{% block script %}
+<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script>
+{% endblock script %}
+
+
{% if course_details %}
<table id="course-details" class="table table-bordered">
<tr>
@@ -160,7 +165,15 @@ Status : <b style="color: green;"> Passed </b><br/>
<div><pre>{{ err }}</pre></div>
{% endfor %}
</div>
- <div class="panel-body"><pre><code>{{ ans.answer.answer.strip|safe }}</code></pre></div>
+ <div class="panel-body">
+ {% if question.type != "code" %}
+ <div class="well well-sm">
+ {{ ans.answer.answer.strip|safe }}
+ </div>
+ {% else %}
+ <pre><code>{{ ans.answer.answer.strip|safe }}</code></pre>
+ {% endif %}
+ </div>
</div>
{% endfor %}
{% with answers|last as answer %}
diff --git a/yaksh/templates/yaksh/question.html b/yaksh/templates/yaksh/question.html
index 9dd0de5..eaaacbf 100644
--- a/yaksh/templates/yaksh/question.html
+++ b/yaksh/templates/yaksh/question.html
@@ -19,6 +19,7 @@
<script src="{{ URL_ROOT }}/static/yaksh/js/codemirror/mode/python/python.js"></script>
<script src="{{ URL_ROOT }}/static/yaksh/js/codemirror/mode/clike/clike.js"></script>
<script src="{{ URL_ROOT }}/static/yaksh/js/codemirror/mode/shell/shell.js"></script>
+<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script>
<script>
var time_left = {{ paper.time_left }}
diff --git a/yaksh/templates/yaksh/showquestions.html b/yaksh/templates/yaksh/showquestions.html
index 3668c9e..157b378 100644
--- a/yaksh/templates/yaksh/showquestions.html
+++ b/yaksh/templates/yaksh/showquestions.html
@@ -14,7 +14,8 @@
<form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ upload_form.as_p }}
-<button class="btn btn-primary" type="submit" name="upload" value="upload">Upload File <span class="glyphicon glyphicon-open"></span></button>
+<button class="btn btn-primary" type="submit" name="upload" value="upload">
+Upload File <span class="glyphicon glyphicon-open"></span></button>
</form>
{% if message %}
<h4>{{ message }}</h4>
@@ -22,6 +23,7 @@
{% if msg %}
<h4>{{ msg }}</h4>
{% endif %}
+<br><br>
<form name=frm action="" method="post">
{% csrf_token %}
<div class="row" id="selectors">
diff --git a/yaksh/templates/yaksh/user_data.html b/yaksh/templates/yaksh/user_data.html
index 16707b2..6679599 100644
--- a/yaksh/templates/yaksh/user_data.html
+++ b/yaksh/templates/yaksh/user_data.html
@@ -5,7 +5,8 @@
{% block content %}
{% block script %}
- <script src= "{{ URL_ROOT }}/static/yaksh/js/edit_question.js"></script>
+<script src= "{{ URL_ROOT }}/static/yaksh/js/edit_question.js"></script>
+<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script>
{% endblock %}
<form action="" method="post">
@@ -83,7 +84,7 @@ User IP address: {{ paper.user_ip }}
{%endif%}
</div>
</div>
- {% if question.type == "mcq" or question.type == "mcc" %}
+ {% if question.type != "code" %}
{% if "Correct answer" in answers.0.error_list %}
<div class="panel panel-success">
{% else %}
@@ -94,7 +95,9 @@ User IP address: {{ paper.user_ip }}
</div>
<div class="panel-body">
<h5><u>Student answer:</u></h5>
- <pre><code>{{forloop.counter}}. {{ answers.0.answer|safe }}</code></pre>
+ <div class="well well-sm">
+ {{ answers.0.answer|safe }}
+ </div>
</div>
</div>
{% else %}
@@ -114,7 +117,16 @@ User IP address: {{ paper.user_ip }}
{% endif %}
</div>
- <div class="panel-body"><pre><code>{{ answer.answer.answer.strip }}</code></pre></div>
+ <div class="panel-body">
+ {% if question.type != "code" %}
+ <div class="well well-sg">
+ {{question.type}}
+ {{ answer.answer.answer.strip|safe }}
+ </div>
+ {% else %}
+ <pre><code>{{ answer.answer.answer.strip|safe }}</code></pre>
+ {% endif %}
+ </div>
</div>
{% endfor %}
diff --git a/yaksh/templates/yaksh/view_answerpaper.html b/yaksh/templates/yaksh/view_answerpaper.html
index 5eb55df..f4edf67 100644
--- a/yaksh/templates/yaksh/view_answerpaper.html
+++ b/yaksh/templates/yaksh/view_answerpaper.html
@@ -2,6 +2,10 @@
{% block pagetitle %} Answer Paper for {{ quiz.description }}{% endblock pagetitle %}
+{% block script %}
+<script src="https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML"></script>
+{% endblock script %}
+
{% block main %}
{% if not data.papers %}
@@ -60,7 +64,7 @@
</div>
</div>
- {% if question.type == "mcq" or question.type == "mcc" %}
+ {% if question.type != "code" %}
{% if "Correct answer" in answers.0.error_list %}
<div class="panel panel-success">
{% else %}
@@ -71,7 +75,9 @@
</div>
<div class="panel-body">
<h5><u>Student answer:</u></h5>
- <pre><code>{{forloop.counter}}. {{ answers.0.answer|safe }}</code></pre>
+ <div class="well well-sm">
+ {{ answers.0.answer|safe }}
+ </div>
</div>
</div>
{% else %}
@@ -84,7 +90,9 @@
<div class="panel panel-danger">
{% endif %}
<div class="panel-heading">Autocheck: {{ answer.error }}</div>
- <div class="panel-body"><pre><code>{{ answer.answer.strip }}</code></pre></div>
+ <div class="panel-body">
+ <pre><code>{{ answer.answer.answer.strip }}</code></pre>
+ </div>
</div>
{% endif %}
{% endfor %}
diff --git a/yaksh/views.py b/yaksh/views.py
index 2a93aff..a752ec2 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -20,7 +20,6 @@ import pytz
from taggit.models import Tag
from itertools import chain
import json
-import zipfile
import six
# Local imports.
from yaksh.models import get_model_class, Quiz, Question, QuestionPaper, QuestionSet, Course
@@ -912,7 +911,8 @@ def show_all_questions(request):
if request.POST.get('delete') == 'delete':
data = request.POST.getlist('question')
if data is not None:
- questions = Question.objects.filter(id__in=data, user_id=user.id, active=True)
+ questions = Question.objects.filter(id__in=data, user_id=user.id,
+ active=True)
for question in questions:
question.active = False
question.save()
@@ -925,7 +925,8 @@ def show_all_questions(request):
if file_name[-1] == "zip":
ques = Question()
files, extract_path = extract_files(questions_file)
- ques.read_json(extract_path, user, files)
+ context['message'] = ques.read_json(extract_path, user,
+ files)
else:
message = "Please Upload a ZIP file"
context['message'] = message
@@ -965,7 +966,6 @@ def show_all_questions(request):
return my_render_to_response('yaksh/showquestions.html', context,
context_instance=ci)
-
@login_required
def user_data(request, user_id, questionpaper_id=None):
"""Render user data."""