Commit 0820e752 by Martyn James Committed by Jonathan Piacenti

Addresses problem when too many excluded users were being excluded

parent e6384b92
...@@ -30,7 +30,7 @@ class StudentGradebook(TimeStampedModel): ...@@ -30,7 +30,7 @@ class StudentGradebook(TimeStampedModel):
unique_together = (('user', 'course_id'),) unique_together = (('user', 'course_id'),)
@classmethod @classmethod
def generate_leaderboard(cls, course_key, user_id=None, count=3, exclude_users=None): def generate_leaderboard(cls, course_key, user_id=None, count=3, exclude_users=[]):
""" """
Assembles a data set representing the Top N users, by grade, for a given course. Assembles a data set representing the Top N users, by grade, for a given course.
Optionally provide a user_id to include user-specific info. For example, you Optionally provide a user_id to include user-specific info. For example, you
...@@ -62,59 +62,53 @@ class StudentGradebook(TimeStampedModel): ...@@ -62,59 +62,53 @@ class StudentGradebook(TimeStampedModel):
data['course_count'] = 0 data['course_count'] = 0
data['queryset'] = [] data['queryset'] = []
total_user_count = CourseEnrollment.users_enrolled_in(course_key).count() enrolled_users_not_excluded = CourseEnrollment.users_enrolled_in(course_key).exclude(id__in=exclude_users)
if total_user_count: total_user_count = enrolled_users_not_excluded.count()
if total_user_count:
# Generate the base data set we're going to work with # Generate the base data set we're going to work with
queryset = StudentGradebook.objects.select_related('user')\ queryset = StudentGradebook.objects.select_related('user')\
.filter(course_id__exact=course_key, user__is_active=True) .filter(course_id__exact=course_key, user__is_active=True, user__in=enrolled_users_not_excluded)
gradebook_user_count = len(queryset) gradebook_user_count = len(queryset)
if gradebook_user_count:
# Remove any users who should not be considered for the statistics if gradebook_user_count:
if exclude_users: # Calculate the class average
total_user_count = total_user_count - len(exclude_users) course_avg = queryset.aggregate(Avg('grade'))['grade__avg']
queryset = queryset.exclude(user__in=exclude_users) if course_avg is not None:
gradebook_user_count = len(queryset) # Take into account any ungraded students (assumes zeros for grades...)
course_avg = course_avg / total_user_count * gradebook_user_count
if gradebook_user_count:
# Calculate the class average # Fill up the response container
course_avg = queryset.aggregate(Avg('grade'))['grade__avg'] data['course_avg'] = float("{0:.3f}".format(course_avg))
if course_avg is not None and gradebook_user_count < total_user_count: data['course_max'] = queryset.aggregate(Max('grade'))['grade__max']
# Take into account any ungraded students (assumes zeros for grades...) data['course_min'] = queryset.aggregate(Min('grade'))['grade__min']
course_avg = course_avg / total_user_count * gradebook_user_count data['course_count'] = queryset.aggregate(Count('grade'))['grade__count']
# Fill up the response container # Construct the leaderboard as a queryset
data['course_avg'] = float("{0:.3f}".format(course_avg)) data['queryset'] = queryset.values(
data['course_max'] = queryset.aggregate(Max('grade'))['grade__max'] 'user__id',
data['course_min'] = queryset.aggregate(Min('grade'))['grade__min'] 'user__username',
data['course_count'] = queryset.aggregate(Count('grade'))['grade__count'] 'user__profile__title',
'user__profile__avatar_url',
# Construct the leaderboard as a queryset 'grade',
data['queryset'] = queryset.values( 'modified')\
'user__id', .order_by('-grade', 'modified')[:count]
'user__username', # If a user_id value was provided, we need to provide some additional user-specific data to the caller
'user__profile__title', if user_id:
'user__profile__avatar_url', user_grade = 0
'grade', user_time_scored = timezone.now()
'modified')\ try:
.order_by('-grade', 'modified')[:count] user_queryset = StudentGradebook.objects.get(course_id__exact=course_key, user__id=user_id)
# If a user_id value was provided, we need to provide some additional user-specific data to the caller except StudentGradebook.DoesNotExist:
if user_id: user_queryset = None
user_grade = 0 if user_queryset:
user_time_scored = timezone.now() user_grade = user_queryset.grade
try: user_time_scored = user_queryset.created
user_queryset = StudentGradebook.objects.get(course_id__exact=course_key, user__id=user_id) users_above = queryset.filter(grade__gte=user_grade)\
except StudentGradebook.DoesNotExist: .exclude(user__id=user_id)\
user_queryset = None .exclude(grade=user_grade, modified__gt=user_time_scored)
if user_queryset: data['user_position'] = len(users_above) + 1
user_grade = user_queryset.grade data['user_grade'] = user_grade
user_time_scored = user_queryset.created
users_above = queryset.filter(grade__gte=user_grade)\
.exclude(user__id=user_id)\
.exclude(grade=user_grade, modified__gt=user_time_scored)
data['user_position'] = len(users_above) + 1
data['user_grade'] = user_grade
return data return data
......
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