def recalculate_category_grade(category): total_earned = 0 total_possible = 0 # We could more simply sum this value, but we're maintaining a list so we can use it later to calculate the # linear regression grade_series = [] for grade in Homework.objects.for_category( category.pk).graded().values_list('current_grade', flat=True): earned, possible = grade.split('/') total_earned += float(earned) total_possible += float(possible) grade_series.append(total_earned / total_possible) average_grade = (total_earned / total_possible) * 100 if len(grade_series) > 0 else -1 trend = commonutils.calculate_trend(range(len(grade_series)), grade_series) logger.debug( 'Category {} average grade recalculated to {} with {} grade_by_weight for {} homework' .format(category.pk, category.average_grade, category.grade_by_weight, len(grade_series))) # Update the values in the datastore, circumventing signals Category.objects.filter(pk=category.pk).update(average_grade=average_grade, trend=trend)
def recalculate_course_group_grade(course_group): course_grades = Course.objects.for_course_group( course_group.pk).graded().values_list('current_grade', flat=True) total = sum(course_grades) average_grade = total / len(course_grades) if len( course_grades) > 0 else -1 logger.debug( 'Course Group {} average grade recalculated to {} with {} courses'. format(course_group.pk, course_group.average_grade, len(course_grades))) homework_grades = Homework.objects.for_course_group( course_group.pk).graded().values_list('current_grade', flat=True) total_earned = 0 total_possible = 0 # We could more simply sum this value, but we're maintaining a list so we can use it later to calculate the # linear regression grade_series = [] for grade in homework_grades: earned, possible = grade.split('/') total_earned += float(earned) total_possible += float(possible) grade_series.append(total_earned / total_possible) trend = commonutils.calculate_trend(range(len(grade_series)), grade_series) logger.debug('Course Group {} trend recalculated to {}'.format( course_group.pk, course_group.trend)) CourseGroup.objects.filter(pk=course_group.pk).update( average_grade=average_grade, trend=trend)
def recalculate_course_grade(course): course_has_weighted_grading = Course.objects.has_weighted_grading( course.pk) total_earned = 0 total_possible = 0 # Maintain grades by category as we iterate over all homework category_totals = {} # We could more simply sum this value, but we're maintaining a list so we can use it later to calculate the # linear regression; note that this grade series is just for raw grade trend analysis and does not take weight # into account grade_series = [] for category_id, grade in Homework.objects.for_course( course.pk).graded().values_list('category_id', 'current_grade'): # The category may no longer exist by the time a recalculation request is processed, in which case we can simply # and safely skip it try: category = Category.objects.get(pk=category_id) except Category.DoesNotExist: continue earned, possible = grade.split('/') earned = float(earned) possible = float(possible) total_earned += earned total_possible += possible grade_series.append(total_earned / total_possible) if category.pk not in category_totals: category_totals[category.pk] = { 'instance': category, 'total_earned': 0, 'total_possible': 0 } category_totals[category.pk]['total_earned'] += earned category_totals[category.pk]['total_possible'] += possible category_earned = 0 category_possible = 0 for category in category_totals.values(): if course_has_weighted_grading: grade_by_weight = ( ((category['total_earned'] / category['total_possible']) * (float(category['instance'].weight) / 100)) * 100) category_earned += grade_by_weight category_possible += float(category['instance'].weight) logger.debug( 'Course triggered category {} recalculation of grade_by_weight to {}' .format(category['instance'].pk, grade_by_weight)) else: category_earned += total_earned category_possible += total_possible grade_by_weight = 0 # Update the values in the datastore, circumventing signals Category.objects.filter(pk=category['instance'].pk).update( grade_by_weight=grade_by_weight) if len(grade_series) > 0 and category_possible > 0: current_grade = (category_earned / category_possible) * 100 else: current_grade = -1 logger.debug( 'Course {} current grade recalculated to {} with {} homework'.format( course.pk, course.current_grade, course.num_homework)) trend = commonutils.calculate_trend(range(len(grade_series)), grade_series) logger.debug('Course {} trend recalculated to {}'.format( course.pk, course.trend)) Course.objects.filter(pk=course.pk).update(current_grade=current_grade, trend=trend)