summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--grades/admin.py2
-rw-r--r--grades/forms.py9
-rw-r--r--grades/migrations/0001_initial.py4
-rw-r--r--grades/migrations/default_grading_system.py37
-rw-r--r--grades/models.py3
-rw-r--r--grades/templates/add_grades.html10
-rw-r--r--grades/tests/test_models.py9
-rw-r--r--grades/tests/test_views.py11
-rw-r--r--grades/views.py9
-rw-r--r--yaksh/models.py20
-rw-r--r--yaksh/views.py23
11 files changed, 80 insertions, 57 deletions
diff --git a/grades/admin.py b/grades/admin.py
index ab38f6b..548791e 100644
--- a/grades/admin.py
+++ b/grades/admin.py
@@ -1,7 +1,7 @@
from django.contrib import admin
from grades.models import GradingSystem, GradeRange
-# Register your models here.
+
class GradingSystemAdmin(admin.ModelAdmin):
readonly_fields = ('creator',)
diff --git a/grades/forms.py b/grades/forms.py
index f8c800a..130659d 100644
--- a/grades/forms.py
+++ b/grades/forms.py
@@ -1,13 +1,8 @@
from grades.models import GradingSystem
from django import forms
-class GradingSystemForm(forms.ModelForm):
- def __init__(self, *args, ** kwargs):
- super(GradingSystemForm, self).__init__(*args, **kwargs)
- system = getattr(self, 'instance', None)
- if system.name == 'default':
- self.fields['name'].widget.attrs['readonly'] = True
+class GradingSystemForm(forms.ModelForm):
class Meta:
model = GradingSystem
- fields = ['name', 'description', 'can_be_used']
+ fields = ['name', 'description']
diff --git a/grades/migrations/0001_initial.py b/grades/migrations/0001_initial.py
index 65d711e..04a3006 100644
--- a/grades/migrations/0001_initial.py
+++ b/grades/migrations/0001_initial.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-# Generated by Django 1.9.5 on 2018-02-02 06:20
+# Generated by Django 1.9.5 on 2018-02-12 11:12
from __future__ import unicode_literals
from django.conf import settings
@@ -20,7 +20,6 @@ class Migration(migrations.Migration):
name='GradeRange',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('order', models.IntegerField(default=0)),
('lower_limit', models.FloatField()),
('upper_limit', models.FloatField()),
('grade', models.CharField(max_length=10)),
@@ -33,7 +32,6 @@ class Migration(migrations.Migration):
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=255, unique=True)),
('description', models.TextField(default='About the grading system!')),
- ('can_be_used', models.BooleanField(default=False)),
('creator', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
diff --git a/grades/migrations/default_grading_system.py b/grades/migrations/default_grading_system.py
index 1629d29..85390d6 100644
--- a/grades/migrations/default_grading_system.py
+++ b/grades/migrations/default_grading_system.py
@@ -1,24 +1,28 @@
from django.db import migrations
+
def create_default_system(apps, schema_editor):
GradingSystem = apps.get_model('grades', 'GradingSystem')
GradeRange = apps.get_model('grades', 'GradeRange')
db = schema_editor.connection.alias
- default_system = GradingSystem.objects.using(db).create(name='default',
- can_be_used=True)
- GradeRange.objects.using(db).create(system=default_system, order=1, lower_limit=0,
- upper_limit=40, grade='F', description='Fail')
- GradeRange.objects.using(db).create(system=default_system, order=2, lower_limit=40,
- upper_limit=55, grade='P', description='Pass')
- GradeRange.objects.using(db).create(system=default_system, order=3, lower_limit=55,
- upper_limit=60, grade='C', description='Average')
- GradeRange.objects.using(db).create(system=default_system, order=4, lower_limit=60,
- upper_limit=75, grade='B', description='Satisfactory')
- GradeRange.objects.using(db).create(system=default_system, order=5, lower_limit=75,
- upper_limit=90, grade='A', description='Good')
- GradeRange.objects.using(db).create(system=default_system, order=6, lower_limit=90,
- upper_limit=101, grade='A+', description='Excellent')
+ default_system = GradingSystem.objects.using(db).create(name='default')
+
+ graderanges_objects = [
+ GradeRange(system=default_system, lower_limit=0, upper_limit=40,
+ grade='F', description='Fail'),
+ GradeRange(system=default_system, lower_limit=40, upper_limit=55,
+ grade='P', description='Pass'),
+ GradeRange(system=default_system, lower_limit=55, upper_limit=60,
+ grade='C', description='Average'),
+ GradeRange(system=default_system, lower_limit=60, upper_limit=75,
+ grade='B', description='Satisfactory'),
+ GradeRange(system=default_system, lower_limit=75, upper_limit=90,
+ grade='A', description='Good'),
+ GradeRange(system=default_system, lower_limit=90, upper_limit=101,
+ grade='A+', description='Excellent')
+ ]
+ GradeRange.objects.using(db).bulk_create(graderanges_objects)
def delete_default_system(apps, schema_editor):
@@ -32,5 +36,6 @@ def delete_default_system(apps, schema_editor):
class Migration(migrations.Migration):
- dependencies = [('grades', '0001_initial'),]
- operations = [migrations.RunPython(create_default_system, delete_default_system),]
+ dependencies = [('grades', '0001_initial'), ]
+ operations = [migrations.RunPython(create_default_system,
+ delete_default_system), ]
diff --git a/grades/models.py b/grades/models.py
index 33895bb..fcea510 100644
--- a/grades/models.py
+++ b/grades/models.py
@@ -1,12 +1,10 @@
from django.db import models
from django.contrib.auth.models import User
-# Create your models here.
class GradingSystem(models.Model):
name = models.CharField(max_length=255, unique=True)
description = models.TextField(default='About the grading system!')
- can_be_used = models.BooleanField(default=False)
creator = models.ForeignKey(User, null=True, blank=True)
def get_grade(self, marks):
@@ -42,7 +40,6 @@ class GradingSystem(models.Model):
class GradeRange(models.Model):
system = models.ForeignKey(GradingSystem)
- order = models.IntegerField(default=0)
lower_limit = models.FloatField()
upper_limit = models.FloatField()
grade = models.CharField(max_length=10)
diff --git a/grades/templates/add_grades.html b/grades/templates/add_grades.html
index f2f0051..1e4d29e 100644
--- a/grades/templates/add_grades.html
+++ b/grades/templates/add_grades.html
@@ -20,9 +20,11 @@
</div>
<hr>
{% endfor %}
-
- <input type="submit" id="add" name="add" value="Add">
- <input type="submit" id="save" name="save" value="Save">
-
+ {% if not is_default %}
+ <input type="submit" id="add" name="add" value="Add">
+ <input type="submit" id="save" name="save" value="Save">
+ {% else %}
+ <p><b>Note: This is a default grading system. You cannot change this.</b></p>
+ {% endif %}
</form>
</html>
diff --git a/grades/tests/test_models.py b/grades/tests/test_models.py
index 89708e2..f8d5c5c 100644
--- a/grades/tests/test_models.py
+++ b/grades/tests/test_models.py
@@ -1,7 +1,7 @@
from django.test import TestCase
from grades.models import GradingSystem, GradeRange
-# Create your tests here.
+
class GradingSystemTestCase(TestCase):
def setUp(self):
GradingSystem.objects.create(name='unusable')
@@ -9,8 +9,9 @@ class GradingSystemTestCase(TestCase):
def test_get_grade(self):
# Given
grading_system = GradingSystem.objects.get(name='default')
- expected_grades = {0:'F', 31:'F', 49:'P', 55:'C', 60:'B', 80:'A',
- 95:'A+', 100:'A+', 100.5:'A+', 101:None, 109:None}
+ expected_grades = {0: 'F', 31: 'F', 49: 'P', 55: 'C', 60: 'B', 80: 'A',
+ 95: 'A+', 100: 'A+', 100.5: 'A+', 101: None,
+ 109: None}
for marks in expected_grades.keys():
# When
grade = grading_system.get_grade(marks)
@@ -19,9 +20,9 @@ class GradingSystemTestCase(TestCase):
def test_grade_system_unusable(self):
# Given
+ # System with out ranges
grading_system = GradingSystem.objects.get(name='unusable')
# When
grade = grading_system.get_grade(29)
# Then
self.assertIsNone(grade)
-
diff --git a/grades/tests/test_views.py b/grades/tests/test_views.py
index 2c29ae5..c944f03 100644
--- a/grades/tests/test_views.py
+++ b/grades/tests/test_views.py
@@ -6,7 +6,8 @@ from grades.models import GradingSystem
def setUpModule():
user = User.objects.create_user(username='grades_user',
- password='grades_user')
+ password='grades_user')
+
def tearDownModule():
User.objects.all().delete()
@@ -66,9 +67,9 @@ class AddGradingSystemTest(TestCase):
def test_add_grades_post(self):
# Given
self.client.login(username='grades_user', password='grades_user')
- data = {'name': ['new_sys'], 'description': ['About the grading system!'],
+ data = {'name': ['new_sys'], 'description': ['About grading system!'],
'graderange_set-MIN_NUM_FORMS': ['0'],
- 'graderange_set-TOTAL_FORMS': ['0'], 'can_be_used': ['on'],
+ 'graderange_set-TOTAL_FORMS': ['0'],
'graderange_set-MAX_NUM_FORMS': ['1000'], 'add': ['Add'],
'graderange_set-INITIAL_FORMS': ['0']}
# When
@@ -86,12 +87,11 @@ class AddGradingSystemTest(TestCase):
# Given
data = {'graderange_set-0-upper_limit': ['40'],
- 'graderange_set-0-order': ['0'],
'graderange_set-0-description': ['Fail'],
'graderange_set-0-lower_limit': ['0'],
'graderange_set-0-system': [''], 'name': ['new_sys'],
'graderange_set-MIN_NUM_FORMS': ['0'],
- 'graderange_set-TOTAL_FORMS': ['1'], 'can_be_used': ['on'],
+ 'graderange_set-TOTAL_FORMS': ['1'],
'graderange_set-MAX_NUM_FORMS': ['1000'],
'graderange_set-0-id': [''],
'description': ['About the grading system!'],
@@ -103,4 +103,3 @@ class AddGradingSystemTest(TestCase):
# Then
ranges = grading_system.graderange_set.all()
self.assertEqual(len(ranges), 1)
-
diff --git a/grades/views.py b/grades/views.py
index 86803c9..10f9999 100644
--- a/grades/views.py
+++ b/grades/views.py
@@ -4,13 +4,12 @@ from django.forms import inlineformset_factory
from grades.forms import GradingSystemForm
from grades.models import GradingSystem, GradeRange
-# Create your views here.
+
@login_required
def grading_systems(request):
user = request.user
default_grading_system = GradingSystem.objects.get(name='default')
- grading_systems = GradingSystem.objects.filter(creator=user).exclude(
- name='default')
+ grading_systems = GradingSystem.objects.filter(creator=user)
return render(request, 'grading_systems.html', {'default_grading_system':
default_grading_system, 'grading_systems': grading_systems})
@@ -24,6 +23,7 @@ def add_grading_system(request, system_id=None):
GradeRangeFormSet = inlineformset_factory(GradingSystem, GradeRange,
fields='__all__', extra=0)
grade_form = GradingSystemForm(instance=grading_system)
+ is_default = grading_system is not None and grading_system.name == 'default'
if request.method == 'POST':
formset = GradeRangeFormSet(request.POST, instance=grading_system)
@@ -41,4 +41,5 @@ def add_grading_system(request, system_id=None):
formset = GradeRangeFormSet(instance=grading_system)
return render(request, 'add_grades.html', {'formset': formset,
- 'grade_form': grade_form, "system_id": system_id})
+ 'grade_form': grade_form, "system_id": system_id,
+ 'is_default': is_default})
diff --git a/yaksh/models.py b/yaksh/models.py
index f76feed..1ecb1f8 100644
--- a/yaksh/models.py
+++ b/yaksh/models.py
@@ -738,13 +738,22 @@ class CourseStatus(models.Model):
course = models.ForeignKey(Course)
user = models.ForeignKey(User)
grade = models.CharField(max_length=255, null=True, blank=True)
- total_marks = models.FloatField(default=0.0)
+ percentage = models.FloatField(default=0.0)
+
+ def get_grade(self):
+ return self.grade
def set_grade(self):
- grade = self.course.grading_system.get_grade(self.total_marks)
- self.grade = grade
+ if self.is_course_complete():
+ self.calculate_percentage()
+ if self.course.grading_system is None:
+ grading_system = GradingSystem.objects.get(name='default')
+ else:
+ grading_system = self.course.grading_system
+ grade = grading_system.get_grade(self.percentage)
+ self.grade = grade
- def calculate_total_marks(self):
+ def calculate_percentage(self):
if self.is_course_complete():
quizzes = self.course.get_quizzes()
total_weightage = 0
@@ -755,8 +764,7 @@ class CourseStatus(models.Model):
quiz, self.user.id, self.course.id)
out_of = quiz.questionpaper_set.first().total_marks
sum += (marks/out_of)*quiz.weightage
- self.total_marks = (sum/total_weightage)*100
- self.set_grade()
+ self.percentage = (sum/total_weightage)*100
def is_course_complete(self):
diff --git a/yaksh/views.py b/yaksh/views.py
index 30b454b..356c66e 100644
--- a/yaksh/views.py
+++ b/yaksh/views.py
@@ -1664,6 +1664,10 @@ def grade_user(request, quiz_id=None, user_id=None, attempt_number=None,
'comments_%d' % paper.question_paper.id, 'No comments')
paper.save()
+ course_status = CourseStatus.objects.filter(course=course, user=user)
+ if course_status.exists():
+ course_status.first().set_grade()
+
return my_render_to_response(
'yaksh/grade_user.html', context, context_instance=ci
)
@@ -1919,14 +1923,27 @@ def regrade(request, course_id, question_id=None, answerpaper_id=None,
answerpaper = get_object_or_404(AnswerPaper, pk=answerpaper_id)
for question in answerpaper.questions.all():
details.append(answerpaper.regrade(question.id))
+ course_status = CourseStatus.objects.filter(user=answerpaper.user,
+ course=answerpaper.course)
+ if course_status.exists():
+ course_status.first().set_grade()
if questionpaper_id is not None and question_id is not None:
answerpapers = AnswerPaper.objects.filter(questions=question_id,
question_paper_id=questionpaper_id, course_id=course_id)
for answerpaper in answerpapers:
details.append(answerpaper.regrade(question_id))
+ course_status = CourseStatus.objects.filter(user=answerpaper.user,
+ course=answerpaper.course)
+ if course_status.exists():
+ course_status.first().set_grade()
if answerpaper_id is not None and question_id is not None:
answerpaper = get_object_or_404(AnswerPaper, pk=answerpaper_id)
details.append(answerpaper.regrade(question_id))
+ course_status = CourseStatus.objects.filter(user=answerpaper.user,
+ course=answerpaper.course)
+ if course_status.exists():
+ course_status.first().set_grade()
+
return grader(request, extra_context={'details': details})
@@ -2713,9 +2730,9 @@ def course_modules(request, course_id, msg=None):
course_status = CourseStatus.objects.filter(course=course, user=user)
if course_status.exists():
course_status = course_status.first()
- if course_status.is_course_complete() and not course_status.grade:
- course_status.calculate_total_marks()
- context['grade'] = course_status.grade
+ if not course_status.grade:
+ course_status.set_grade()
+ context['grade'] = course_status.get_grade()
return my_render_to_response('yaksh/course_modules.html', context)