def init_from_model(self, student, model, course_structure, submissions_scores, csm_scores): """ Load the subsection grade from the persisted model. """ for block in model.visible_blocks.blocks: self._compute_block_score(block.locator, course_structure, submissions_scores, csm_scores, block) self.graded_total = AggregatedScore( tw_earned=model.earned_graded, tw_possible=model.possible_graded, graded=True, display_name=self.display_name, module_id=self.location, ) self.all_total = AggregatedScore( tw_earned=model.earned_all, tw_possible=model.possible_all, graded=False, display_name=self.display_name, module_id=self.location, ) self._log_event(log.debug, u"init_from_model", student) return self
def __init__(self, subsection, course_data): super(ZeroSubsectionGrade, self).__init__(subsection) self.graded_total = AggregatedScore(tw_earned=0, tw_possible=None, graded=False, first_attempted=None) self.all_total = AggregatedScore(tw_earned=0, tw_possible=None, graded=self.graded, first_attempted=None) self.course_data = course_data
def _aggregated_score_from_model(grade_model, is_graded): """ Helper method that returns `AggregatedScore` objects based on the values in the given `grade_model`. If the given model has an associated override, the values from the override are used instead. """ score_type = 'graded' if is_graded else 'all' earned_value = getattr(grade_model, 'earned_{}'.format(score_type)) possible_value = getattr(grade_model, 'possible_{}'.format(score_type)) if hasattr(grade_model, 'override'): score_type = 'graded_override' if is_graded else 'all_override' earned_override = getattr(grade_model.override, 'earned_{}'.format(score_type)) if earned_override is not None: earned_value = earned_override possible_override = getattr(grade_model.override, 'possible_{}'.format(score_type)) if possible_override is not None: possible_value = possible_override return AggregatedScore( tw_earned=earned_value, tw_possible=possible_value, graded=is_graded, first_attempted=grade_model.first_attempted, )
def test_weighted_grading(self): scores = [] agg_fields = dict(first_attempted=None) prob_fields = dict(raw_earned=0, raw_possible=0, weight=0, first_attempted=None) # No scores all_total, graded_total = aggregate_scores(scores) self.assertEqual( all_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=False, **agg_fields), ) self.assertEqual( graded_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields), ) # (0/5 non-graded) scores.append(ProblemScore(weighted_earned=0, weighted_possible=5, graded=False, **prob_fields)) all_total, graded_total = aggregate_scores(scores) self.assertEqual( all_total, AggregatedScore(tw_earned=0, tw_possible=5, graded=False, **agg_fields), ) self.assertEqual( graded_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields), ) # (0/5 non-graded) + (3/5 graded) = 3/10 total, 3/5 graded now = datetime.now() prob_fields['first_attempted'] = now agg_fields['first_attempted'] = now scores.append(ProblemScore(weighted_earned=3, weighted_possible=5, graded=True, **prob_fields)) all_total, graded_total = aggregate_scores(scores) self.assertAlmostEqual( all_total, AggregatedScore(tw_earned=3, tw_possible=10, graded=False, **agg_fields), ) self.assertAlmostEqual( graded_total, AggregatedScore(tw_earned=3, tw_possible=5, graded=True, **agg_fields), ) # (0/5 non-graded) + (3/5 graded) + (2/5 graded) = 5/15 total, 5/10 graded scores.append(ProblemScore(weighted_earned=2, weighted_possible=5, graded=True, **prob_fields)) all_total, graded_total = aggregate_scores(scores) self.assertAlmostEqual( all_total, AggregatedScore(tw_earned=5, tw_possible=15, graded=False, **agg_fields), ) self.assertAlmostEqual( graded_total, AggregatedScore(tw_earned=5, tw_possible=10, graded=True, **agg_fields), )
def __init__(self, subsection, model, factory): all_total = AggregatedScore( tw_earned=model.earned_all, tw_possible=model.possible_all, graded=False, first_attempted=model.first_attempted, ) graded_total = AggregatedScore( tw_earned=model.earned_graded, tw_possible=model.possible_graded, graded=True, first_attempted=model.first_attempted, ) override = model.override if hasattr(model, 'override') else None # save these for later since we compute problem_scores lazily self.model = model self.factory = factory super(ReadSubsectionGrade, self).__init__(subsection, all_total, graded_total, override)
def init_from_model(self, student, model, course_structure, submissions_scores, csm_scores): """ Load the subsection grade from the persisted model. """ for block in model.visible_blocks.blocks: self._compute_block_score(block.locator, course_structure, submissions_scores, csm_scores, block) self.graded_total = AggregatedScore( tw_earned=model.earned_graded, tw_possible=model.possible_graded, graded=True, first_attempted=model.first_attempted, ) self.all_total = AggregatedScore( tw_earned=model.earned_all, tw_possible=model.possible_all, graded=False, first_attempted=model.first_attempted, ) self.override = model.override if hasattr(model, 'override') else None self._log_event(log.debug, u"init_from_model", student) return self
class GraderTest(unittest.TestCase): """ Tests grader implementations """ shard = 1 empty_gradesheet = {} incomplete_gradesheet = { 'Homework': {}, 'Lab': {}, 'Midterm': {}, } class MockGrade(object): """ Mock class for SubsectionGrade object. """ def __init__(self, graded_total, display_name): self.graded_total = graded_total self.display_name = display_name @property def percent_graded(self): return compute_percent(self.graded_total.earned, self.graded_total.possible) common_fields = dict(graded=True, first_attempted=datetime.now()) test_gradesheet = { 'Homework': { 'hw1': MockGrade(AggregatedScore(tw_earned=2, tw_possible=20.0, **common_fields), display_name='hw1'), 'hw2': MockGrade(AggregatedScore(tw_earned=16, tw_possible=16.0, **common_fields), display_name='hw2'), }, # The dropped scores should be from the assignments that don't exist yet 'Lab': { # Dropped 'lab1': MockGrade(AggregatedScore(tw_earned=1, tw_possible=2.0, **common_fields), display_name='lab1'), 'lab2': MockGrade(AggregatedScore(tw_earned=1, tw_possible=1.0, **common_fields), display_name='lab2'), 'lab3': MockGrade(AggregatedScore(tw_earned=1, tw_possible=1.0, **common_fields), display_name='lab3'), # Dropped 'lab4': MockGrade(AggregatedScore(tw_earned=5, tw_possible=25.0, **common_fields), display_name='lab4'), # Dropped 'lab5': MockGrade(AggregatedScore(tw_earned=3, tw_possible=4.0, **common_fields), display_name='lab5'), 'lab6': MockGrade(AggregatedScore(tw_earned=6, tw_possible=7.0, **common_fields), display_name='lab6'), 'lab7': MockGrade(AggregatedScore(tw_earned=5, tw_possible=6.0, **common_fields), display_name='lab7'), }, 'Midterm': { 'midterm': MockGrade( AggregatedScore(tw_earned=50.5, tw_possible=100, **common_fields), display_name="Midterm Exam", ), }, } 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 [ 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 self.assertEqual(len(graded['section_breakdown']), 12 + 1) 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 = 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 = overflow_grader.grade(self.test_gradesheet) self.assertAlmostEqual( graded['percent'], 0.8879999999999999) # 100% + 10% / 5 assignments self.assertEqual(len(graded['section_breakdown']), 7 + 1) graded = lab_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.92249999999999999) self.assertEqual(len(graded['section_breakdown']), 7 + 1) 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') graded = midterm_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.50) self.assertEqual(len(graded['section_breakdown']), 0 + 1) 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) midterm_grader = graders.AssignmentFormatGrader("Midterm", 1, 0) 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), ]) 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), ]) # 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), ]) # 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.50812499999999994) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) graded = over_one_weights_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.76624999999999999) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) graded = zero_weights_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.25) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) 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 [ 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 = 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_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. weighted_grader = graders.grader_from_conf([ { 'type': "Homework", 'min_count': 12, 'drop_count': 2, 'short_label': "HW", 'weight': 0.25, }, { 'type': "Lab", 'min_count': 7, 'drop_count': 3, 'category': "Labs", 'weight': 0.25 }, { 'type': "Midterm", 'min_count': 0, 'drop_count': 0, 'name': "Midterm Exam", 'short_label': "Midterm", 'weight': 0.5, }, ]) empty_grader = graders.grader_from_conf([]) graded = weighted_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.50812499999999994) self.assertEqual(len(graded['section_breakdown']), (12 + 1) + (7 + 1) + 1) self.assertEqual(len(graded['grade_breakdown']), 3) 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 homework_grader = graders.AssignmentFormatGrader("Homework", 12, 2) homework_grader2 = graders.grader_from_conf(homework_grader) graded = homework_grader2.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.11) self.assertEqual(len(graded['section_breakdown']), 12 + 1) @ddt.data( ( # empty {}, u"Configuration has no appropriate grader class."), ( # no min_count { 'type': "Homework", 'drop_count': 0 }, u"Configuration has no appropriate grader class."), ( # no drop_count { 'type': "Homework", 'min_count': 0 }, u"__init__() takes at least 4 arguments (3 given)"), ) @ddt.unpack def test_grader_with_invalid_conf(self, invalid_conf, expected_error_message): with self.assertRaises(ValueError) as error: graders.grader_from_conf([invalid_conf]) self.assertIn(expected_error_message, text_type(error.exception))
def test_weighted_grading(self): scores = [] agg_fields = dict(display_name="aggregated_score", module_id=None) prob_fields = dict(display_name="problem_score", module_id=None, raw_earned=0, raw_possible=0, weight=0) all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertEqual( all_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=False, **agg_fields), ) self.assertEqual( graded_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields), ) scores.append( ProblemScore(weighted_earned=0, weighted_possible=5, graded=False, **prob_fields)) all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertEqual( all_total, AggregatedScore(tw_earned=0, tw_possible=5, graded=False, **agg_fields), ) self.assertEqual( graded_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields), ) scores.append( ProblemScore(weighted_earned=3, weighted_possible=5, graded=True, **prob_fields)) all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertAlmostEqual( all_total, AggregatedScore(tw_earned=3, tw_possible=10, graded=False, **agg_fields), ) self.assertAlmostEqual( graded_total, AggregatedScore(tw_earned=3, tw_possible=5, graded=True, **agg_fields), ) scores.append( ProblemScore(weighted_earned=2, weighted_possible=5, graded=True, **prob_fields)) all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertAlmostEqual( all_total, AggregatedScore(tw_earned=5, tw_possible=15, graded=False, **agg_fields), ) self.assertAlmostEqual( graded_total, AggregatedScore(tw_earned=5, tw_possible=10, graded=True, **agg_fields), )
class GraderTest(unittest.TestCase): """ Tests grader implementations """ empty_gradesheet = {} incomplete_gradesheet = { 'Homework': [], 'Lab': [], 'Midterm': [], } test_gradesheet = { 'Homework': [ AggregatedScore(tw_earned=2, tw_possible=20.0, graded=True, display_name='hw1', module_id=None), AggregatedScore(tw_earned=16, tw_possible=16.0, graded=True, display_name='hw2', module_id=None) ], # The dropped scores should be from the assignments that don't exist yet 'Lab': [ AggregatedScore(tw_earned=1, tw_possible=2.0, graded=True, display_name='lab1', module_id=None), # Dropped AggregatedScore(tw_earned=1, tw_possible=1.0, graded=True, display_name='lab2', module_id=None), AggregatedScore(tw_earned=1, tw_possible=1.0, graded=True, display_name='lab3', module_id=None), AggregatedScore(tw_earned=5, tw_possible=25.0, graded=True, display_name='lab4', module_id=None), # Dropped AggregatedScore(tw_earned=3, tw_possible=4.0, graded=True, display_name='lab5', module_id=None), # Dropped AggregatedScore(tw_earned=6, tw_possible=7.0, graded=True, display_name='lab6', module_id=None), AggregatedScore(tw_earned=5, tw_possible=6.0, graded=True, display_name='lab7', module_id=None), ], 'Midterm': [ AggregatedScore(tw_earned=50.5, tw_possible=100, graded=True, display_name="Midterm Exam", module_id=None), ], } 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 [ 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 = midterm_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.505) self.assertEqual(len(graded['section_breakdown']), 1) graded = lab4_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.2) self.assertEqual(len(graded['section_breakdown']), 1) 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 [ 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 self.assertEqual(len(graded['section_breakdown']), 12 + 1) 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 = 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 = 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 = lab_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.9226190476190477) self.assertEqual(len(graded['section_breakdown']), 7 + 1) 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') graded = midterm_grader.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.505) self.assertEqual(len(graded['section_breakdown']), 0 + 1) 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) 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), ]) 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), ]) # 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), ]) # 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 = 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 = 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 = 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 [ 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 = 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_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. weighted_grader = graders.grader_from_conf([ { 'type': "Homework", 'min_count': 12, 'drop_count': 2, 'short_label': "HW", 'weight': 0.25, }, { 'type': "Lab", 'min_count': 7, 'drop_count': 3, 'category': "Labs", 'weight': 0.25 }, { 'type': "Midterm", 'name': "Midterm Exam", 'short_label': "Midterm", 'weight': 0.5, }, ]) empty_grader = graders.grader_from_conf([]) 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 = 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 homework_grader = graders.AssignmentFormatGrader("Homework", 12, 2) homework_grader2 = graders.grader_from_conf(homework_grader) graded = homework_grader2.grade(self.test_gradesheet) self.assertAlmostEqual(graded['percent'], 0.11) self.assertEqual(len(graded['section_breakdown']), 12 + 1)
def test_weighted_grading(self): scores = [] agg_fields = dict(display_name="aggregated_score", module_id=None, attempted=False) prob_fields = dict( display_name="problem_score", module_id=None, raw_earned=0, raw_possible=0, weight=0, attempted=False, ) # No scores all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertEqual( all_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=False, **agg_fields), ) self.assertEqual( graded_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields), ) # (0/5 non-graded) scores.append( ProblemScore(weighted_earned=0, weighted_possible=5, graded=False, **prob_fields)) all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertEqual( all_total, AggregatedScore(tw_earned=0, tw_possible=5, graded=False, **agg_fields), ) self.assertEqual( graded_total, AggregatedScore(tw_earned=0, tw_possible=0, graded=True, **agg_fields), ) # (0/5 non-graded) + (3/5 graded) = 3/10 total, 3/5 graded prob_fields['attempted'] = True agg_fields['attempted'] = True scores.append( ProblemScore(weighted_earned=3, weighted_possible=5, graded=True, **prob_fields)) all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertAlmostEqual( all_total, AggregatedScore(tw_earned=3, tw_possible=10, graded=False, **agg_fields), ) self.assertAlmostEqual( graded_total, AggregatedScore(tw_earned=3, tw_possible=5, graded=True, **agg_fields), ) # (0/5 non-graded) + (3/5 graded) + (2/5 graded) = 5/15 total, 5/10 graded scores.append( ProblemScore(weighted_earned=2, weighted_possible=5, graded=True, **prob_fields)) all_total, graded_total = aggregate_scores( scores, display_name=agg_fields['display_name']) self.assertAlmostEqual( all_total, AggregatedScore(tw_earned=5, tw_possible=15, graded=False, **agg_fields), ) self.assertAlmostEqual( graded_total, AggregatedScore(tw_earned=5, tw_possible=10, graded=True, **agg_fields), )