Moved the weighting of problems to when problem scores are retrieved.
This commit is contained in:
@@ -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)
|
||||
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -154,7 +154,7 @@ $(function() {
|
||||
%>
|
||||
|
||||
<h3><a href="${reverse('courseware_section', args=format_url_params([chapter['course'], chapter['chapter'], section['section']])) }">
|
||||
${ section['section'] }</a> ${"({0:g}/{1:g}) {2}".format( earned, total, percentageString )}</h3>
|
||||
${ section['section'] }</a> ${"({0:.3n}/{1:.3n}) {2}".format( float(earned), float(total), percentageString )}</h3>
|
||||
${section['subtitle']}
|
||||
%if 'due' in section and section['due']!="":
|
||||
due ${section['due']}
|
||||
@@ -164,7 +164,7 @@ $(function() {
|
||||
<ol class="scores">
|
||||
${ "Problem Scores: " if section['graded'] else "Practice Scores: "}
|
||||
%for score in section['scores']:
|
||||
<li class="score">${"{0:g}/{1:g}".format(score.earned,score.possible)}</li>
|
||||
<li class="score">${"{0:.3n}/{1:.3n}".format(float(score.earned),float(score.possible))}</li>
|
||||
%endfor
|
||||
</ol>
|
||||
%endif
|
||||
|
||||
Reference in New Issue
Block a user