From 39d666cd1306aab99735be13847765ecbf5f7fc0 Mon Sep 17 00:00:00 2001 From: Brian Wilson Date: Fri, 29 Mar 2013 01:27:36 -0400 Subject: [PATCH 1/2] modify AssignmentFormatGrader to act like a SingleSectionGrader on single sections --- common/lib/xmodule/xmodule/graders.py | 104 ++++++---- .../lib/xmodule/xmodule/tests/test_graders.py | 192 ++++++++++-------- 2 files changed, 173 insertions(+), 123 deletions(-) diff --git a/common/lib/xmodule/xmodule/graders.py b/common/lib/xmodule/xmodule/graders.py index 35318f4f1e..862da791c0 100644 --- a/common/lib/xmodule/xmodule/graders.py +++ b/common/lib/xmodule/xmodule/graders.py @@ -45,8 +45,9 @@ def invalid_args(func, argdict): Given a function and a dictionary of arguments, returns a set of arguments from argdict that aren't accepted by func """ - args, varargs, keywords, defaults = inspect.getargspec(func) - if keywords: return set() # All accepted + args, _, keywords, _ = inspect.getargspec(func) + if keywords: + return set() # All accepted return set(argdict) - set(args) @@ -119,7 +120,7 @@ class CourseGrader(object): that has the matching section format. The grader outputs a dictionary with the following keys: - - percent: Contaisn a float value, which is the final percentage score for the student. + - percent: Contains a float value, which is the final percentage score for the student. - section_breakdown: This is a list of dictionaries which provide details on sections that were graded. These are used for display in a graph or chart. The format for a section_breakdown dictionary is explained below. @@ -150,6 +151,7 @@ class CourseGrader(object): @abc.abstractmethod def grade(self, grade_sheet, generate_random_scores=False): + '''Given a grade sheet, return a dict containing grading information''' raise NotImplementedError @@ -158,7 +160,10 @@ class WeightedSubsectionsGrader(CourseGrader): This grader takes a list of tuples containing (grader, category_name, weight) and computes a final grade by totalling the contribution of each sub grader and multiplying it by the given weight. For example, the sections may be - [ (homeworkGrader, "Homework", 0.15), (labGrader, "Labs", 0.15), (midtermGrader, "Midterm", 0.30), (finalGrader, "Final", 0.40) ] + + [ (homeworkGrader, "Homework", 0.15), (labGrader, "Labs", 0.15), (midtermGrader, "Midterm", 0.30), + (finalGrader, "Final", 0.40) ] + All items in section_breakdown for each subgrader will be combined. A grade_breakdown will be composed using the score from each grader. @@ -177,12 +182,12 @@ class WeightedSubsectionsGrader(CourseGrader): for subgrader, category, weight in self.sections: 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) + weighted_percent = subgrade_result['percent'] * weight + section_detail = "{0} = {1:.1%} of a possible {2:.0%}".format(category, weighted_percent, weight) - total_percent += weightedPercent + total_percent += weighted_percent section_breakdown += subgrade_result['section_breakdown'] - grade_breakdown.append({'percent': weightedPercent, 'detail': section_detail, 'category': category}) + grade_breakdown.append({'percent': weighted_percent, 'detail': section_detail, 'category': category}) return {'percent': total_percent, 'section_breakdown': section_breakdown, @@ -203,32 +208,33 @@ class SingleSectionGrader(CourseGrader): self.category = category or name def grade(self, grade_sheet, generate_random_scores=False): - foundScore = None + found_score = None if self.type in grade_sheet: for score in grade_sheet[self.type]: if score.section == self.name: - foundScore = score + found_score = score break - if foundScore or generate_random_scores: + if found_score 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 + earned = found_score.earned + possible = found_score.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)) + percent=percent, + earned=float(earned), + possible=float(possible)) else: percent = 0.0 detail = "{name} - 0% (?/?)".format(name=self.name) - breakdown = [{'percent': percent, 'label': self.short_label, 'detail': detail, 'category': self.category, 'prominent': True}] + breakdown = [{'percent': percent, 'label': self.short_label, + 'detail': detail, 'category': self.category, 'prominent': True}] return {'percent': percent, 'section_breakdown': breakdown, @@ -250,6 +256,13 @@ class AssignmentFormatGrader(CourseGrader): 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. + hide_average is to suppress the display of the total score in this grader and instead + only show each assignment in this grader in the breakdown. + + If there is only a single assignment in this grader, then it acts like a SingleSectionGrader + and returns only one entry for the grader. Since the assignment and the total are the same, + the total is returned but is not labeled as an average. + 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). @@ -263,7 +276,8 @@ class AssignmentFormatGrader(CourseGrader): min_count = 2 would produce the labels "Assignment 3", "Assignment 4" """ - def __init__(self, type, min_count, drop_count, category=None, section_type=None, short_label=None, show_only_average=False, hide_average=False, starting_index=1): + def __init__(self, type, min_count, drop_count, category=None, section_type=None, short_label=None, + show_only_average=False, hide_average=False, starting_index=1): self.type = type self.min_count = min_count self.drop_count = drop_count @@ -275,7 +289,8 @@ class AssignmentFormatGrader(CourseGrader): self.hide_average = hide_average def grade(self, grade_sheet, generate_random_scores=False): - def totalWithDrops(breakdown, drop_count): + def total_with_drops(breakdown, drop_count): + '''calculates total score for a section while dropping lowest scores''' #create an array of tuples with (index, mark), sorted by mark['percent'] descending sorted_breakdown = sorted(enumerate(breakdown), key=lambda x: -x[1]['percent']) # A list of the indices of the dropped scores @@ -308,33 +323,50 @@ class AssignmentFormatGrader(CourseGrader): section_name = scores[i].section percentage = earned / float(possible) - summary = "{section_type} {index} - {name} - {percent:.0%} ({earned:.3n}/{possible:.3n})".format(index=i + self.starting_index, - section_type=self.section_type, - name=section_name, - percent=percentage, - earned=float(earned), - possible=float(possible)) + summary_format = "{section_type} {index} - {name} - {percent:.0%} ({earned:.3n}/{possible:.3n})" + summary = summary_format.format(index=i + self.starting_index, + section_type=self.section_type, + name=section_name, + percent=percentage, + earned=float(earned), + possible=float(possible)) else: percentage = 0 - summary = "{section_type} {index} Unreleased - 0% (?/?)".format(index=i + self.starting_index, section_type=self.section_type) + summary = "{section_type} {index} Unreleased - 0% (?/?)".format(index=i + self.starting_index, + section_type=self.section_type) - short_label = "{short_label} {index:02d}".format(index=i + self.starting_index, short_label=self.short_label) + short_label = "{short_label} {index:02d}".format(index=i + self.starting_index, + short_label=self.short_label) - breakdown.append({'percent': percentage, 'label': short_label, 'detail': summary, 'category': self.category}) + breakdown.append({'percent': percentage, 'label': short_label, + 'detail': summary, 'category': self.category}) - total_percent, dropped_indices = totalWithDrops(breakdown, self.drop_count) + total_percent, dropped_indices = total_with_drops(breakdown, self.drop_count) for dropped_index in dropped_indices: - breakdown[dropped_index]['mark'] = {'detail': "The lowest {drop_count} {section_type} scores are dropped.".format(drop_count=self.drop_count, section_type=self.section_type)} + breakdown[dropped_index]['mark'] = {'detail': "The lowest {drop_count} {section_type} scores are dropped." + .format(drop_count=self.drop_count, section_type=self.section_type)} - 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 len(breakdown) == 1: + # if there is only one entry in a section, suppress the existing individual entry and the average, + # and just display a single entry for the section. That way it acts automatically like a + # SingleSectionGrader. + total_detail = "{section_type} = {percent:.0%}".format(percent=total_percent, + section_type=self.section_type) + total_label = "{short_label}".format(short_label=self.short_label) + breakdown = [{'percent': total_percent, 'label': total_label, + 'detail': total_detail, 'category': self.category, 'prominent': True}, ] + else: + 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 = [] + if self.show_only_average: + breakdown = [] - if not self.hide_average: - breakdown.append({'percent': total_percent, 'label': total_label, 'detail': total_detail, 'category': self.category, 'prominent': True}) + if not self.hide_average: + breakdown.append({'percent': total_percent, 'label': total_label, + 'detail': total_detail, 'category': self.category, 'prominent': True}) return {'percent': total_percent, 'section_breakdown': breakdown, diff --git a/common/lib/xmodule/xmodule/tests/test_graders.py b/common/lib/xmodule/xmodule/tests/test_graders.py index 27416b1d5c..1a9ba50dc4 100644 --- a/common/lib/xmodule/xmodule/tests/test_graders.py +++ b/common/lib/xmodule/xmodule/tests/test_graders.py @@ -6,32 +6,34 @@ from xmodule.graders import Score, aggregate_scores class GradesheetTest(unittest.TestCase): + '''Tests the aggregate_scores method''' def test_weighted_grading(self): scores = [] Score.__sub__ = lambda me, other: (me.earned - other.earned) + (me.possible - other.possible) - all, graded = aggregate_scores(scores) - self.assertEqual(all, Score(earned=0, possible=0, graded=False, section="summary")) - self.assertEqual(graded, Score(earned=0, possible=0, graded=True, section="summary")) + all_total, graded_total = aggregate_scores(scores) + self.assertEqual(all_total, Score(earned=0, possible=0, graded=False, section="summary")) + self.assertEqual(graded_total, Score(earned=0, possible=0, graded=True, section="summary")) scores.append(Score(earned=0, possible=5, graded=False, section="summary")) - all, graded = aggregate_scores(scores) - self.assertEqual(all, Score(earned=0, possible=5, graded=False, section="summary")) - self.assertEqual(graded, Score(earned=0, possible=0, graded=True, section="summary")) + all_total, graded_total = aggregate_scores(scores) + self.assertEqual(all_total, Score(earned=0, possible=5, graded=False, section="summary")) + self.assertEqual(graded_total, Score(earned=0, possible=0, graded=True, section="summary")) scores.append(Score(earned=3, possible=5, graded=True, section="summary")) - all, graded = aggregate_scores(scores) - self.assertAlmostEqual(all, Score(earned=3, possible=10, graded=False, section="summary")) - self.assertAlmostEqual(graded, Score(earned=3, possible=5, graded=True, section="summary")) + all_total, graded_total = aggregate_scores(scores) + self.assertAlmostEqual(all_total, Score(earned=3, possible=10, graded=False, section="summary")) + self.assertAlmostEqual(graded_total, Score(earned=3, possible=5, graded=True, section="summary")) scores.append(Score(earned=2, possible=5, graded=True, section="summary")) - all, graded = aggregate_scores(scores) - self.assertAlmostEqual(all, Score(earned=5, possible=15, graded=False, section="summary")) - self.assertAlmostEqual(graded, Score(earned=5, possible=10, graded=True, section="summary")) + all_total, graded_total = aggregate_scores(scores) + self.assertAlmostEqual(all_total, Score(earned=5, possible=15, graded=False, section="summary")) + self.assertAlmostEqual(graded_total, Score(earned=5, possible=10, graded=True, section="summary")) class GraderTest(unittest.TestCase): + '''Tests grader implementations''' empty_gradesheet = { } @@ -44,136 +46,152 @@ class GraderTest(unittest.TestCase): test_gradesheet = { 'Homework': [Score(earned=2, possible=20.0, graded=True, section='hw1'), - Score(earned=16, possible=16.0, graded=True, section='hw2')], - #The dropped scores should be from the assignments that don't exist yet + Score(earned=16, possible=16.0, graded=True, section='hw2')], + # The dropped scores should be from the assignments that don't exist yet 'Lab': [Score(earned=1, possible=2.0, graded=True, section='lab1'), # Dropped - Score(earned=1, possible=1.0, graded=True, section='lab2'), - Score(earned=1, possible=1.0, graded=True, section='lab3'), - Score(earned=5, possible=25.0, graded=True, section='lab4'), # Dropped - Score(earned=3, possible=4.0, graded=True, section='lab5'), # Dropped - Score(earned=6, possible=7.0, graded=True, section='lab6'), - Score(earned=5, possible=6.0, graded=True, section='lab7')], + Score(earned=1, possible=1.0, graded=True, section='lab2'), + Score(earned=1, possible=1.0, graded=True, section='lab3'), + Score(earned=5, possible=25.0, graded=True, section='lab4'), # Dropped + Score(earned=3, possible=4.0, graded=True, section='lab5'), # Dropped + Score(earned=6, possible=7.0, graded=True, section='lab6'), + Score(earned=5, possible=6.0, graded=True, section='lab7')], 'Midterm': [Score(earned=50.5, possible=100, graded=True, section="Midterm Exam"), ], } - def test_SingleSectionGrader(self): - midtermGrader = graders.SingleSectionGrader("Midterm", "Midterm Exam") - lab4Grader = graders.SingleSectionGrader("Lab", "lab4") - badLabGrader = graders.SingleSectionGrader("Lab", "lab42") + def test_single_section_grader(self): + midterm_grader = graders.SingleSectionGrader("Midterm", "Midterm Exam") + lab4_grader = graders.SingleSectionGrader("Lab", "lab4") + bad_lab_grader = graders.SingleSectionGrader("Lab", "lab42") - for graded in [midtermGrader.grade(self.empty_gradesheet), - midtermGrader.grade(self.incomplete_gradesheet), - badLabGrader.grade(self.test_gradesheet)]: + for graded in [midterm_grader.grade(self.empty_gradesheet), + midterm_grader.grade(self.incomplete_gradesheet), + bad_lab_grader.grade(self.test_gradesheet)]: self.assertEqual(len(graded['section_breakdown']), 1) self.assertEqual(graded['percent'], 0.0) - graded = midtermGrader.grade(self.test_gradesheet) + graded = midterm_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.505) self.assertEqual(len(graded['section_breakdown']), 1) - graded = lab4Grader.grade(self.test_gradesheet) + graded = lab4_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.2) self.assertEqual(len(graded['section_breakdown']), 1) - def test_AssignmentFormatGrader(self): - homeworkGrader = graders.AssignmentFormatGrader("Homework", 12, 2) - noDropGrader = graders.AssignmentFormatGrader("Homework", 12, 0) - #Even though the minimum number is 3, this should grade correctly when 7 assignments are found - overflowGrader = graders.AssignmentFormatGrader("Lab", 3, 2) - labGrader = graders.AssignmentFormatGrader("Lab", 7, 3) + def test_assignment_format_grader(self): + homework_grader = graders.AssignmentFormatGrader("Homework", 12, 2) + no_drop_grader = graders.AssignmentFormatGrader("Homework", 12, 0) + # Even though the minimum number is 3, this should grade correctly when 7 assignments are found + overflow_grader = graders.AssignmentFormatGrader("Lab", 3, 2) + lab_grader = graders.AssignmentFormatGrader("Lab", 7, 3) - #Test the grading of an empty gradesheet - for graded in [homeworkGrader.grade(self.empty_gradesheet), - noDropGrader.grade(self.empty_gradesheet), - homeworkGrader.grade(self.incomplete_gradesheet), - noDropGrader.grade(self.incomplete_gradesheet)]: + # Test the grading of an empty gradesheet + for graded in [homework_grader.grade(self.empty_gradesheet), + no_drop_grader.grade(self.empty_gradesheet), + homework_grader.grade(self.incomplete_gradesheet), + no_drop_grader.grade(self.incomplete_gradesheet)]: self.assertAlmostEqual(graded['percent'], 0.0) - #Make sure the breakdown includes 12 sections, plus one summary + # Make sure the breakdown includes 12 sections, plus one summary self.assertEqual(len(graded['section_breakdown']), 12 + 1) - graded = homeworkGrader.grade(self.test_gradesheet) + graded = homework_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.11) # 100% + 10% / 10 assignments self.assertEqual(len(graded['section_breakdown']), 12 + 1) - graded = noDropGrader.grade(self.test_gradesheet) + graded = no_drop_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.0916666666666666) # 100% + 10% / 12 assignments self.assertEqual(len(graded['section_breakdown']), 12 + 1) - graded = overflowGrader.grade(self.test_gradesheet) + graded = overflow_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.8880952380952382) # 100% + 10% / 5 assignments self.assertEqual(len(graded['section_breakdown']), 7 + 1) - graded = labGrader.grade(self.test_gradesheet) + graded = lab_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.9226190476190477) self.assertEqual(len(graded['section_breakdown']), 7 + 1) - def test_WeightedSubsectionsGrader(self): - #First, a few sub graders - homeworkGrader = graders.AssignmentFormatGrader("Homework", 12, 2) - labGrader = graders.AssignmentFormatGrader("Lab", 7, 3) - midtermGrader = graders.SingleSectionGrader("Midterm", "Midterm Exam") + def test_assignment_format_grader_on_single_section_entry(self): + midterm_grader = graders.AssignmentFormatGrader("Midterm", 1, 0) + # Test the grading on a section with one item: + for graded in [midterm_grader.grade(self.empty_gradesheet), + midterm_grader.grade(self.incomplete_gradesheet)]: + self.assertAlmostEqual(graded['percent'], 0.0) + # Make sure the breakdown includes just the one summary + self.assertEqual(len(graded['section_breakdown']), 0 + 1) + self.assertEqual(graded['section_breakdown'][0]['label'], 'Midterm') - weightedGrader = graders.WeightedSubsectionsGrader([(homeworkGrader, homeworkGrader.category, 0.25), - (labGrader, labGrader.category, 0.25), - (midtermGrader, midtermGrader.category, 0.5)]) + graded = midterm_grader.grade(self.test_gradesheet) + self.assertAlmostEqual(graded['percent'], 0.505) + self.assertEqual(len(graded['section_breakdown']), 0 + 1) - overOneWeightsGrader = graders.WeightedSubsectionsGrader([(homeworkGrader, homeworkGrader.category, 0.5), - (labGrader, labGrader.category, 0.5), - (midtermGrader, midtermGrader.category, 0.5)]) + def test_weighted_subsections_grader(self): + # First, a few sub graders + homework_grader = graders.AssignmentFormatGrader("Homework", 12, 2) + lab_grader = graders.AssignmentFormatGrader("Lab", 7, 3) + # phasing out the use of SingleSectionGraders, and instead using AssignmentFormatGraders that + # will act like SingleSectionGraders on single sections. + midterm_grader = graders.AssignmentFormatGrader("Midterm", 1, 0) - #The midterm should have all weight on this one - zeroWeightsGrader = graders.WeightedSubsectionsGrader([(homeworkGrader, homeworkGrader.category, 0.0), - (labGrader, labGrader.category, 0.0), - (midtermGrader, midtermGrader.category, 0.5)]) + weighted_grader = graders.WeightedSubsectionsGrader([(homework_grader, homework_grader.category, 0.25), + (lab_grader, lab_grader.category, 0.25), + (midterm_grader, midterm_grader.category, 0.5)]) - #This should always have a final percent of zero - allZeroWeightsGrader = graders.WeightedSubsectionsGrader([(homeworkGrader, homeworkGrader.category, 0.0), - (labGrader, labGrader.category, 0.0), - (midtermGrader, midtermGrader.category, 0.0)]) + over_one_weights_grader = graders.WeightedSubsectionsGrader([(homework_grader, homework_grader.category, 0.5), + (lab_grader, lab_grader.category, 0.5), + (midterm_grader, midterm_grader.category, 0.5)]) - emptyGrader = graders.WeightedSubsectionsGrader([]) + # The midterm should have all weight on this one + zero_weights_grader = graders.WeightedSubsectionsGrader([(homework_grader, homework_grader.category, 0.0), + (lab_grader, lab_grader.category, 0.0), + (midterm_grader, midterm_grader.category, 0.5)]) - graded = weightedGrader.grade(self.test_gradesheet) + # This should always have a final percent of zero + all_zero_weights_grader = graders.WeightedSubsectionsGrader([(homework_grader, homework_grader.category, 0.0), + (lab_grader, lab_grader.category, 0.0), + (midterm_grader, midterm_grader.category, 0.0)]) + + empty_grader = graders.WeightedSubsectionsGrader([]) + + graded = weighted_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.5106547619047619) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) - graded = overOneWeightsGrader.grade(self.test_gradesheet) + graded = over_one_weights_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.7688095238095238) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) - graded = zeroWeightsGrader.grade(self.test_gradesheet) + graded = zero_weights_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.2525) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) - graded = allZeroWeightsGrader.grade(self.test_gradesheet) + graded = all_zero_weights_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.0) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) - for graded in [weightedGrader.grade(self.empty_gradesheet), - weightedGrader.grade(self.incomplete_gradesheet), - zeroWeightsGrader.grade(self.empty_gradesheet), - allZeroWeightsGrader.grade(self.empty_gradesheet)]: + for graded in [weighted_grader.grade(self.empty_gradesheet), + weighted_grader.grade(self.incomplete_gradesheet), + zero_weights_grader.grade(self.empty_gradesheet), + all_zero_weights_grader.grade(self.empty_gradesheet)]: self.assertAlmostEqual(graded['percent'], 0.0) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) - graded = emptyGrader.grade(self.test_gradesheet) + graded = empty_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.0) self.assertEqual(len(graded['section_breakdown']), 0) self.assertEqual(len(graded['grade_breakdown']), 0) - def test_graderFromConf(self): + def test_grader_from_conf(self): - #Confs always produce a graders.WeightedSubsectionsGrader, so we test this by repeating the test - #in test_graders.WeightedSubsectionsGrader, but generate the graders with confs. + # Confs always produce a graders.WeightedSubsectionsGrader, so we test this by repeating the test + # in test_graders.WeightedSubsectionsGrader, but generate the graders with confs. - weightedGrader = graders.grader_from_conf([ + weighted_grader = graders.grader_from_conf([ { 'type': "Homework", 'min_count': 12, @@ -196,25 +214,25 @@ class GraderTest(unittest.TestCase): }, ]) - emptyGrader = graders.grader_from_conf([]) + empty_grader = graders.grader_from_conf([]) - graded = weightedGrader.grade(self.test_gradesheet) + graded = weighted_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.5106547619047619) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) - graded = emptyGrader.grade(self.test_gradesheet) + graded = empty_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.0) self.assertEqual(len(graded['section_breakdown']), 0) self.assertEqual(len(graded['grade_breakdown']), 0) - #Test that graders can also be used instead of lists of dictionaries - homeworkGrader = graders.AssignmentFormatGrader("Homework", 12, 2) - homeworkGrader2 = graders.grader_from_conf(homeworkGrader) + # Test that graders can also be used instead of lists of dictionaries + homework_grader = graders.AssignmentFormatGrader("Homework", 12, 2) + homework_grader2 = graders.grader_from_conf(homework_grader) - graded = homeworkGrader2.grade(self.test_gradesheet) + graded = homework_grader2.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.11) self.assertEqual(len(graded['section_breakdown']), 12 + 1) - #TODO: How do we test failure cases? The parser only logs an error when - #it can't parse something. Maybe it should throw exceptions? + # TODO: How do we test failure cases? The parser only logs an error when + # it can't parse something. Maybe it should throw exceptions? From 50fd7ee7a49ac9870139b62e242e8962ec90f70d Mon Sep 17 00:00:00 2001 From: Brian Wilson Date: Fri, 29 Mar 2013 12:01:10 -0400 Subject: [PATCH 2/2] fix test --- lms/djangoapps/instructor/tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lms/djangoapps/instructor/tests.py b/lms/djangoapps/instructor/tests.py index 512e81e302..fd8e652997 100644 --- a/lms/djangoapps/instructor/tests.py +++ b/lms/djangoapps/instructor/tests.py @@ -74,8 +74,8 @@ class TestInstructorDashboardGradeDownloadCSV(LoginEnrollmentTestCase): # All the not-actually-in-the-course hw and labs come from the # default grading policy string in graders.py - expected_body = '''"ID","Username","Full Name","edX email","External email","HW 01","HW 02","HW 03","HW 04","HW 05","HW 06","HW 07","HW 08","HW 09","HW 10","HW 11","HW 12","HW Avg","Lab 01","Lab 02","Lab 03","Lab 04","Lab 05","Lab 06","Lab 07","Lab 08","Lab 09","Lab 10","Lab 11","Lab 12","Lab Avg","Midterm 01","Midterm Avg","Final 01","Final Avg" -"2","u2","Fred Weasley","view2@test.com","","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0" + expected_body = '''"ID","Username","Full Name","edX email","External email","HW 01","HW 02","HW 03","HW 04","HW 05","HW 06","HW 07","HW 08","HW 09","HW 10","HW 11","HW 12","HW Avg","Lab 01","Lab 02","Lab 03","Lab 04","Lab 05","Lab 06","Lab 07","Lab 08","Lab 09","Lab 10","Lab 11","Lab 12","Lab Avg","Midterm","Final" +"2","u2","Fred Weasley","view2@test.com","","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0" ''' self.assertEqual(body, expected_body, msg)