Commit c6b72c6e by Matt Drayer Committed by Jonathan Piacenti

mattdrayer/api: Course grades user position fix

parent 350a9c02
......@@ -29,6 +29,7 @@ class CourseLeadersSerializer(serializers.Serializer):
avatar_url = serializers.CharField(source='user__profile__avatar_url')
# Percentage grade (versus letter grade)
grade = serializers.FloatField(source='grade')
created = serializers.DateTimeField()
class CourseCompletionsLeadersSerializer(serializers.Serializer):
......
......@@ -222,7 +222,6 @@ class CoursesApiTests(TestCase):
grade_dict = {'value': points_scored, 'max_value': points_possible, 'user_id': user.id}
module.system.publish(module, 'grade', grade_dict)
for j, user in enumerate(self.users):
StudentModuleFactory.create(
course_id=self.course.id,
module_type='sequential',
......@@ -1603,17 +1602,60 @@ class CoursesApiTests(TestCase):
self.assertEqual(response.data['leaders'][0]['username'], 'testuser4')
self.assertEqual(response.data['course_avg'], expected_course_average)
count_filter_test_uri = '{}?{}'.format(test_uri, 'count=4')
count_filter_test_uri = '{}?count=4'.format(test_uri)
response = self.do_get(count_filter_test_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data['leaders']), 4)
# Filter by user_id
user_filter_uri = '{}?user_id={}'.format(test_uri, self.users[1].id)
# Filter by user_id, include a user with the exact same score
user200 = UserFactory.create(username="testuser200", profile='test')
CourseEnrollmentFactory.create(user=user200, course_id=self.course.id)
self.midterm = ItemFactory.create(
parent_location=self.chapter.location,
category='problem',
data=StringResponseXMLFactory().build_xml(answer='bar'),
display_name='Problem 200',
metadata={'rerandomize': 'always', 'graded': True, 'format': 'Midterm Exam'}
)
points_scored = 100
points_possible = 100
module = self.get_module_for_user(user200, self.course, self.midterm)
grade_dict = {'value': points_scored, 'max_value': points_possible, 'user_id': user200.id}
module.system.publish(module, 'grade', grade_dict)
StudentModuleFactory.create(
course_id=self.course.id,
module_type='sequential',
module_state_key=self.midterm.location,
)
self.final = ItemFactory.create(
parent_location=self.chapter.location,
category='problem',
data=StringResponseXMLFactory().build_xml(answer='bar'),
display_name='Problem 201',
metadata={'rerandomize': 'always', 'graded': True, 'format': 'Final Exam'}
)
points_scored = 100
points_possible = 100
module = self.get_module_for_user(user200, self.course, self.final)
grade_dict = {'value': points_scored, 'max_value': points_possible, 'user_id': user200.id}
module.system.publish(module, 'grade', grade_dict)
StudentModuleFactory.create(
course_id=self.course.id,
module_type='sequential',
module_state_key=self.final.location,
)
points_scored = 50
points_possible = 100
module = self.get_module_for_user(user200, self.course, item)
grade_dict = {'value': points_scored, 'max_value': points_possible, 'user_id': user200.id}
module.system.publish(module, 'grade', grade_dict)
user_filter_uri = '{}?user_id={}&count=10'.format(test_uri, self.users[1].id)
response = self.do_get(user_filter_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(len(response.data['leaders']), 3)
self.assertEqual(response.data['course_avg'], expected_course_average)
self.assertEqual(len(response.data['leaders']), 6)
self.assertEqual(response.data['course_avg'], 0.378)
self.assertEqual(response.data['user_position'], 4)
self.assertEqual(response.data['user_grade'], 0.28)
......@@ -1624,11 +1666,11 @@ class CoursesApiTests(TestCase):
response = self.do_get(user_filter_uri)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data['user_grade'], 0)
self.assertEqual(response.data['user_position'], 6)
self.assertEqual(response.data['user_position'], 7)
# Also, with this new user now added the course average should be different
self.assertNotEqual(response.data['course_avg'], expected_course_average)
rounded_avg = float("{0:.2f}".format(response.data['course_avg']))
self.assertEqual(rounded_avg, 0.33)
self.assertEqual(rounded_avg, 0.32)
# test with bogus course
bogus_test_uri = '{}/{}/metrics/grades/leaders/'.format(self.base_courses_uri, self.test_bogus_course_id)
......
......@@ -84,11 +84,10 @@ class StudentGradebook(TimeStampedModel):
course_avg = course_avg / total_user_count * gradebook_user_count
# Fill up the response container
data['course_avg'] = course_avg
data['course_avg'] = float("{0:.3f}".format(course_avg))
data['course_max'] = queryset.aggregate(Max('grade'))['grade__max']
data['course_min'] = queryset.aggregate(Min('grade'))['grade__min']
data['course_count'] = queryset.aggregate(Count('grade'))['grade__count']
# Construct the leaderboard as a queryset
data['queryset'] = queryset.values(
'user__id',
......@@ -98,7 +97,6 @@ class StudentGradebook(TimeStampedModel):
'grade',
'created')\
.order_by('-grade', 'created')[:count]
# If a user_id value was provided, we need to provide some additional user-specific data to the caller
if user_id:
user_grade = 0
......@@ -112,7 +110,7 @@ class StudentGradebook(TimeStampedModel):
user_time_scored = user_queryset.created
users_above = queryset.filter(grade__gte=user_grade)\
.exclude(user__id=user_id)\
.exclude(grade=user_grade, created__lt=user_time_scored)
.exclude(grade=user_grade, created__gt=user_time_scored)
data['user_position'] = len(users_above) + 1
data['user_grade'] = user_grade
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment