From e3b397870f0c7d73a6023d385e53bdb37fbaf6a1 Mon Sep 17 00:00:00 2001 From: Bridger Maxwell Date: Mon, 16 Apr 2012 16:57:24 -0400 Subject: [PATCH] Moved the weighting of problems to when problem scores are retrieved. --- djangoapps/courseware/grades.py | 38 ++++++++++++------------ djangoapps/courseware/tests.py | 52 ++++++++++++++++----------------- templates/profile.html | 4 +-- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/djangoapps/courseware/grades.py b/djangoapps/courseware/grades.py index cf675a7b02..359fe91588 100644 --- a/djangoapps/courseware/grades.py +++ b/djangoapps/courseware/grades.py @@ -12,7 +12,7 @@ from student.models import UserProfile log = logging.getLogger("mitx.courseware") -Score = namedtuple("Score", "earned possible weight graded section") +Score = namedtuple("Score", "earned possible graded section") SectionPercentage = namedtuple("SectionPercentage", "percentage label summary") @@ -273,7 +273,7 @@ class AssignmentFormatGrader(CourseGrader): def get_score(user, problem, cache): ## HACK: assumes max score is fixed per problem id = problem.get('id') - correct = 0 + correct = 0.0 # If the ID is not in the cache, add the item if id not in cache: @@ -290,15 +290,22 @@ def get_score(user, problem, cache): if id in cache: response = cache[id] if response.grade!=None: - correct=response.grade + correct=float(response.grade) # Grab max grade from cache, or if it doesn't exist, compute and save to DB if id in cache and response.max_grade != None: total = response.max_grade else: - total=courseware.modules.capa_module.Module(etree.tostring(problem), "id").max_score() + total=float(courseware.modules.capa_module.Module(etree.tostring(problem), "id").max_score()) response.max_grade = total response.save() + + #Now we re-weight the problem, if specified + weight = problem.get("weight", None) + if weight: + weight = float(weight) + correct = correct * weight / total + total = weight return (correct, total) @@ -348,12 +355,12 @@ def grade_sheet(student): correct = random.randrange( max(total-2, 1) , total + 1 ) else: correct = total - scores.append( Score(int(correct),total, float(p.get("weight", total)), graded, p.get("name")) ) + scores.append( Score(correct,total, graded, p.get("name")) ) - section_total, graded_total = aggregate_scores(scores, s.get("name"), s.get("weight", 1)) + section_total, graded_total = aggregate_scores(scores, s.get("name")) #Add the graded total to totaled_scores - format = s.get('format') if s.get('format') else "" - subtitle = s.get('subtitle') if s.get('subtitle') else format + format = s.get('format', "") + subtitle = s.get('subtitle', format) if format and graded_total[1] > 0: format_scores = totaled_scores.get(format, []) format_scores.append( graded_total ) @@ -387,26 +394,21 @@ def grade_sheet(student): return {'courseware_summary' : chapters, 'grade_summary' : grade_summary} -def aggregate_scores(scores, section_name = "summary", section_weight = 1): - #TODO: What does a possible score of zero mean? We need to think what extra credit is - scores = filter( lambda score: score.possible > 0, scores ) +def aggregate_scores(scores, section_name = "summary"): + total_correct_graded = sum(score.earned for score in scores if score.graded) + total_possible_graded = sum(score.possible for score in scores if score.graded) - total_correct_graded = sum((score.earned*1.0/score.possible)*score.weight for score in scores if score.graded) - total_possible_graded = sum(score.weight for score in scores if score.graded) - - total_correct = sum((score.earned*1.0/score.possible)*score.weight for score in scores) - total_possible = sum(score.weight for score in scores) + total_correct = sum(score.earned for score in scores) + total_possible = sum(score.possible for score in scores) #regardless of whether or not it is graded all_total = Score(total_correct, total_possible, - section_weight, False, section_name) #selecting only graded things graded_total = Score(total_correct_graded, total_possible_graded, - section_weight, True, section_name) diff --git a/djangoapps/courseware/tests.py b/djangoapps/courseware/tests.py index 1785d348d8..7d02b45264 100644 --- a/djangoapps/courseware/tests.py +++ b/djangoapps/courseware/tests.py @@ -61,38 +61,38 @@ class GradesheetTest(unittest.TestCase): 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, weight=1, graded=False, section="summary")) - self.assertEqual(graded, Score(earned=0, possible=0, weight=1, graded=True, section="summary")) + self.assertEqual(all, Score(earned=0, possible=0, graded=False, section="summary")) + self.assertEqual(graded, Score(earned=0, possible=0, graded=True, section="summary")) - scores.append(Score(earned=0, possible=5, weight=1, graded=False, 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=1, weight=1, graded=False, section="summary")) - self.assertEqual(graded, Score(earned=0, possible=0, weight=1, graded=True, section="summary")) + self.assertEqual(all, Score(earned=0, possible=1, graded=False, section="summary")) + self.assertEqual(graded, Score(earned=0, possible=0, graded=True, section="summary")) - scores.append(Score(earned=3, possible=5, weight=1, 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.0/5, possible=2, weight=1, graded=False, section="summary")) - self.assertAlmostEqual(graded, Score(earned=3.0/5, possible=1, weight=1, graded=True, section="summary")) + self.assertAlmostEqual(all, Score(earned=3.0/5, possible=2, graded=False, section="summary")) + self.assertAlmostEqual(graded, Score(earned=3.0/5, possible=1, graded=True, section="summary")) scores.append(Score(earned=2, possible=5, weight=2, graded=True, section="summary")) all, graded = aggregate_scores(scores) - self.assertAlmostEqual(all, Score(earned=7.0/5, possible=4, weight=1, graded=False, section="summary")) - self.assertAlmostEqual(graded, Score(earned=7.0/5, possible=3, weight=1, graded=True, section="summary")) + self.assertAlmostEqual(all, Score(earned=7.0/5, possible=4, graded=False, section="summary")) + self.assertAlmostEqual(graded, Score(earned=7.0/5, possible=3, graded=True, section="summary")) scores.append(Score(earned=2, possible=5, weight=0, graded=True, section="summary")) all, graded = aggregate_scores(scores) - self.assertAlmostEqual(all, Score(earned=7.0/5, possible=4, weight=1, graded=False, section="summary")) - self.assertAlmostEqual(graded, Score(earned=7.0/5, possible=3, weight=1, graded=True, section="summary")) + self.assertAlmostEqual(all, Score(earned=7.0/5, possible=4, graded=False, section="summary")) + self.assertAlmostEqual(graded, Score(earned=7.0/5, possible=3, graded=True, section="summary")) scores.append(Score(earned=2, possible=5, weight=3, graded=False, section="summary")) all, graded = aggregate_scores(scores) - self.assertAlmostEqual(all, Score(earned=13.0/5, possible=7, weight=1, graded=False, section="summary")) - self.assertAlmostEqual(graded, Score(earned=7.0/5, possible=3, weight=1, graded=True, section="summary")) + self.assertAlmostEqual(all, Score(earned=13.0/5, possible=7, graded=False, section="summary")) + self.assertAlmostEqual(graded, Score(earned=7.0/5, possible=3, graded=True, section="summary")) scores.append(Score(earned=2, possible=5, weight=.5, graded=True, section="summary")) all, graded = aggregate_scores(scores) - self.assertAlmostEqual(all, Score(earned=14.0/5, possible=7.5, weight=1, graded=False, section="summary")) - self.assertAlmostEqual(graded, Score(earned=8.0/5, possible=3.5, weight=1, graded=True, section="summary")) + self.assertAlmostEqual(all, Score(earned=14.0/5, possible=7.5, graded=False, section="summary")) + self.assertAlmostEqual(graded, Score(earned=8.0/5, possible=3.5, graded=True, section="summary")) class GraderTest(unittest.TestCase): @@ -106,19 +106,19 @@ class GraderTest(unittest.TestCase): } test_gradesheet = { - 'Homework': [Score(earned=2, possible=20.0, weight=1, graded=True, section='hw1'), - Score(earned=16, possible=16.0, weight=1, graded=True, section='hw2')], + '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 - 'Lab': [Score(earned=1, possible=2.0, weight=1, graded=True, section='lab1'), #Dropped - Score(earned=1, possible=1.0, weight=1, graded=True, section='lab2'), - Score(earned=1, possible=1.0, weight=1, graded=True, section='lab3'), - Score(earned=5, possible=25.0, weight=1, graded=True, section='lab4'), #Dropped - Score(earned=3, possible=4.0, weight=1, graded=True, section='lab5'), #Dropped - Score(earned=6, possible=7.0, weight=1, graded=True, section='lab6'), - Score(earned=5, possible=6.0, weight=1, graded=True, section='lab7')], + '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')], - 'Midterm' : [Score(earned=50.5, possible=100, weight=1, graded=True, section="Midterm Exam"),], + 'Midterm' : [Score(earned=50.5, possible=100, graded=True, section="Midterm Exam"),], } def test_SingleSectionGrader(self): diff --git a/templates/profile.html b/templates/profile.html index 9e2e880556..a43b4e04c8 100644 --- a/templates/profile.html +++ b/templates/profile.html @@ -154,7 +154,7 @@ $(function() { %>

- ${ section['section'] } ${"({0:g}/{1:g}) {2}".format( earned, total, percentageString )}

+ ${ section['section'] } ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )} ${section['subtitle']} %if 'due' in section and section['due']!="": due ${section['due']} @@ -164,7 +164,7 @@ $(function() {
    ${ "Problem Scores: " if section['graded'] else "Practice Scores: "} %for score in section['scores']: -
  1. ${"{0:g}/{1:g}".format(score.earned,score.possible)}
  2. +
  3. ${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}
  4. %endfor
%endif