From 8ba85044668a02596030aea25a666cc6c5f021ce Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Fri, 28 Sep 2012 12:47:12 -0400 Subject: [PATCH 1/5] Added option to only show average of a section format grader. --- common/lib/xmodule/xmodule/graders.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index 3f0bb63186..d450359b82 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -285,13 +285,14 @@ class AssignmentFormatGrader(CourseGrader): "HW". """ - def __init__(self, type, min_count, drop_count, category=None, section_type=None, short_label=None): + def __init__(self, type, min_count, drop_count, category=None, section_type=None, short_label=None, show_only_average=False): self.type = type self.min_count = min_count self.drop_count = drop_count self.category = category or self.type self.section_type = section_type or self.type self.short_label = short_label or self.type + self.show_only_average = show_only_average def grade(self, grade_sheet): def totalWithDrops(breakdown, drop_count): @@ -328,7 +329,7 @@ class AssignmentFormatGrader(CourseGrader): summary = "{section_type} {index} Unreleased - 0% (?/?)".format(index=i + 1, section_type=self.section_type) short_label = "{short_label} {index:02d}".format(index=i + 1, short_label=self.short_label) - + breakdown.append({'percent': percentage, 'label': short_label, 'detail': summary, 'category': self.category}) total_percent, dropped_indices = totalWithDrops(breakdown, self.drop_count) @@ -338,8 +339,12 @@ class AssignmentFormatGrader(CourseGrader): total_detail = "{section_type} Average = {percent:.0%}".format(percent=total_percent, section_type=self.section_type) total_label = "{short_label} Avg".format(short_label=self.short_label) + + if self.show_only_average: + breakdown = [] + breakdown.append({'percent': total_percent, 'label': total_label, 'detail': total_detail, 'category': self.category, 'prominent': True}) - + return {'percent': total_percent, 'section_breakdown': breakdown, #No grade_breakdown here From a99d7f7c4a1586066feb6cdc3bf37f568d99f062 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Fri, 28 Sep 2012 21:48:41 -0400 Subject: [PATCH 2/5] Fixed settings.GENERATE_PROFILE_SCORES for debugging progress graph. --- common/lib/xmodule/xmodule/graders.py | 28 +++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index d450359b82..291be370d9 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -1,10 +1,13 @@ import abc import json import logging +import random import sys from collections import namedtuple +from django.conf import settings + log = logging.getLogger("mitx.courseware") # This is a tuple for holding scores, either from problems or sections. @@ -245,7 +248,16 @@ class SingleSectionGrader(CourseGrader): foundScore = score break - if foundScore: + if settings.GENERATE_PROFILE_SCORES: # for debugging! + earned = random.randint(2,15) + possible = random.randint(earned, 15) + percent = float(earned) / possible + detail = "{name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(name=self.name, + percent=percent, + earned=float(earned), + possible=float(possible)) + + elif foundScore: percent = foundScore.earned / float(foundScore.possible) detail = "{name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(name=self.name, percent=percent, @@ -316,7 +328,19 @@ class AssignmentFormatGrader(CourseGrader): scores = grade_sheet.get(self.type, []) breakdown = [] for i in range(max(self.min_count, len(scores))): - if i < len(scores): + print "scores" , scores + if settings.GENERATE_PROFILE_SCORES: # for debugging! + earned = random.randint(2,15) + possible = random.randint(earned, 15) + percentage = float(earned) / possible + summary = "{section_type} {index} - {name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(index=i + 1, + section_type=self.section_type, + name="Generated", + percent=percentage, + earned=float(earned), + possible=float(possible)) + + elif i < len(scores): percentage = scores[i].earned / float(scores[i].possible) summary = "{section_type} {index} - {name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(index=i + 1, section_type=self.section_type, From fc73916e054095b8c15667a3e2f7bb7050401b77 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Fri, 28 Sep 2012 23:14:55 -0400 Subject: [PATCH 3/5] Removed django.conf.settings dependency from graders. --- common/lib/xmodule/xmodule/graders.py | 17 +++++++---------- lms/djangoapps/courseware/grades.py | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index 291be370d9..132dd81264 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -6,8 +6,6 @@ import sys from collections import namedtuple -from django.conf import settings - log = logging.getLogger("mitx.courseware") # This is a tuple for holding scores, either from problems or sections. @@ -187,7 +185,7 @@ class CourseGrader(object): __metaclass__ = abc.ABCMeta @abc.abstractmethod - def grade(self, grade_sheet): + def grade(self, grade_sheet, generate_random_scores=False): raise NotImplementedError @@ -207,13 +205,13 @@ class WeightedSubsectionsGrader(CourseGrader): def __init__(self, sections): self.sections = sections - def grade(self, grade_sheet): + def grade(self, grade_sheet, generate_random_scores=False): total_percent = 0.0 section_breakdown = [] grade_breakdown = [] for subgrader, category, weight in self.sections: - subgrade_result = subgrader.grade(grade_sheet) + subgrade_result = subgrader.grade(grade_sheet, generate_random_scores) weightedPercent = subgrade_result['percent'] * weight section_detail = "{0} = {1:.1%} of a possible {2:.0%}".format(category, weightedPercent, weight) @@ -240,7 +238,7 @@ class SingleSectionGrader(CourseGrader): self.short_label = short_label or name self.category = category or name - def grade(self, grade_sheet): + def grade(self, grade_sheet, generate_random_scores=False): foundScore = None if self.type in grade_sheet: for score in grade_sheet[self.type]: @@ -248,7 +246,7 @@ class SingleSectionGrader(CourseGrader): foundScore = score break - if settings.GENERATE_PROFILE_SCORES: # for debugging! + if generate_random_scores: # for debugging! earned = random.randint(2,15) possible = random.randint(earned, 15) percent = float(earned) / possible @@ -306,7 +304,7 @@ class AssignmentFormatGrader(CourseGrader): self.short_label = short_label or self.type self.show_only_average = show_only_average - def grade(self, grade_sheet): + def grade(self, grade_sheet, generate_random_scores=False): def totalWithDrops(breakdown, drop_count): #create an array of tuples with (index, mark), sorted by mark['percent'] descending sorted_breakdown = sorted(enumerate(breakdown), key=lambda x: -x[1]['percent']) @@ -328,8 +326,7 @@ class AssignmentFormatGrader(CourseGrader): scores = grade_sheet.get(self.type, []) breakdown = [] for i in range(max(self.min_count, len(scores))): - print "scores" , scores - if settings.GENERATE_PROFILE_SCORES: # for debugging! + if generate_random_scores: # for debugging! earned = random.randint(2,15) possible = random.randint(earned, 15) percentage = float(earned) / possible diff --git a/lms/djangoapps/courseware/grades.py b/lms/djangoapps/courseware/grades.py index 20eb83dafc..df272d8bbf 100644 --- a/lms/djangoapps/courseware/grades.py +++ b/lms/djangoapps/courseware/grades.py @@ -201,7 +201,7 @@ def grade(student, request, course, student_module_cache=None, keep_raw_scores=F totaled_scores[section_format] = format_scores - grade_summary = course.grader.grade(totaled_scores) + grade_summary = course.grader.grade(totaled_scores, generate_random_scores=settings.GENERATE_PROFILE_SCORES) # We round the grade here, to make sure that the grade is an whole percentage and # doesn't get displayed differently than it gets grades From 2e4ea1d49c5136785a8d831dd2ff4f958d7f7bce Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Fri, 28 Sep 2012 23:19:46 -0400 Subject: [PATCH 4/5] Added docstring for show_only_average parameter. --- common/lib/xmodule/xmodule/graders.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index 132dd81264..54001c8c37 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -284,6 +284,9 @@ class AssignmentFormatGrader(CourseGrader): min_count defines how many assignments are expected throughout the course. Placeholder scores (of 0) will be inserted if the number of matching sections in the course is < min_count. If there number of matching sections in the course is > min_count, min_count will be ignored. + + show_only_average is to suppress the display of each assignment in this grader and instead + only show the total score of this grader in the breakdown. category should be presentable to the user, but may not appear. When the grade breakdown is displayed, scores from the same category will be similar (for example, by color). From 4ee0e258ea1ba609633804bf3b5823a21c3b1d6f Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Sun, 30 Sep 2012 14:48:20 -0400 Subject: [PATCH 5/5] Refactored a bit of the generating scores code. --- common/lib/xmodule/xmodule/graders.py | 47 +++++++++++++-------------- 1 file changed, 22 insertions(+), 25 deletions(-) diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index 54001c8c37..d273cb7d29 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -246,21 +246,19 @@ class SingleSectionGrader(CourseGrader): foundScore = score break - if generate_random_scores: # for debugging! - earned = random.randint(2,15) - possible = random.randint(earned, 15) - percent = float(earned) / possible + if foundScore or generate_random_scores: + if generate_random_scores: # for debugging! + earned = random.randint(2,15) + possible = random.randint(earned, 15) + else: # We found the score + earned = foundScore.earned + possible = foundScore.possible + + percent = earned / float(possible) detail = "{name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(name=self.name, percent=percent, earned=float(earned), possible=float(possible)) - - elif foundScore: - percent = foundScore.earned / float(foundScore.possible) - detail = "{name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(name=self.name, - percent=percent, - earned=float(foundScore.earned), - possible=float(foundScore.possible)) else: percent = 0.0 @@ -329,25 +327,24 @@ class AssignmentFormatGrader(CourseGrader): scores = grade_sheet.get(self.type, []) breakdown = [] for i in range(max(self.min_count, len(scores))): - if generate_random_scores: # for debugging! - earned = random.randint(2,15) - possible = random.randint(earned, 15) - percentage = float(earned) / possible + if i < len(scores) or generate_random_scores: + if generate_random_scores: # for debugging! + earned = random.randint(2,15) + possible = random.randint(earned, 15) + section_name = "Generated" + + else: + earned = scores[i].earned + possible = scores[i].possible + section_name = scores[i].section + + percentage = earned / float(possible) summary = "{section_type} {index} - {name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(index=i + 1, section_type=self.section_type, - name="Generated", + name=section_name, percent=percentage, earned=float(earned), possible=float(possible)) - - elif i < len(scores): - percentage = scores[i].earned / float(scores[i].possible) - summary = "{section_type} {index} - {name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(index=i + 1, - section_type=self.section_type, - name=scores[i].section, - percent=percentage, - earned=float(scores[i].earned), - possible=float(scores[i].possible)) else: percentage = 0 summary = "{section_type} {index} Unreleased - 0% (?/?)".format(index=i + 1, section_type=self.section_type)