Skip to content

Commit ced78a6

Browse files
Exclude unscored homeworks from dashboard difficulty stats
The Question difficulty and Assignment difficulty sections on the course dashboard were computing stats from Answer.is_correct and Submission.questions_score for all homeworks, including unscored ones. Unscored homeworks have is_correct=False and questions_score=0 by default, so they showed 0 correct answers and 0% scores — misleading data that looked like real difficulty metrics. Now both sections filter to only include homeworks in the SCORED state.
1 parent b86827b commit ced78a6

4 files changed

Lines changed: 79 additions & 3 deletions

File tree

courses/tests/test_dashboard_homework_difficulty.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from django.urls import reverse
22

3+
from courses.models import HomeworkState
34
from courses.tests.dashboard_homework_base import (
45
DashboardHomeworkStatsTestBase,
56
)
@@ -8,11 +9,15 @@
89
class DashboardHomeworkDifficultyTestCase(DashboardHomeworkStatsTestBase):
910
def test_homework_difficulty_ranking(self):
1011
self.add_questions(self.homework, 3)
12+
self.homework.state = HomeworkState.SCORED.value
13+
self.homework.save()
1114
harder_homework = self.create_homework_for_difficulty(
1215
"hw2",
1316
"Homework 2",
1417
14,
1518
)
19+
harder_homework.state = HomeworkState.SCORED.value
20+
harder_homework.save()
1621
self.add_questions(harder_homework, 10)
1722
self.create_difficulty_submissions(harder_homework)
1823

@@ -22,3 +27,25 @@ def test_homework_difficulty_ranking(self):
2227
self.assert_difficulty_ranking(response, harder_homework)
2328
self.assertContains(response, "Assignment difficulty")
2429
self.assertContains(response, "Completion")
30+
31+
def test_difficulty_excludes_unscored_homework(self):
32+
self.add_questions(self.homework, 3)
33+
self.homework.state = HomeworkState.SCORED.value
34+
self.homework.save()
35+
unscored = self.create_homework_for_difficulty(
36+
"hw2",
37+
"Homework 2",
38+
14,
39+
)
40+
self.add_questions(unscored, 3)
41+
self.create_difficulty_submissions(unscored)
42+
43+
url = reverse("dashboard", args=[self.course.slug])
44+
response = self.client.get(url)
45+
46+
difficulty_stats = response.context["homework_difficulty_stats"]
47+
homework_titles = [
48+
hw_stat["homework"].title for hw_stat in difficulty_stats
49+
]
50+
self.assertIn("Homework 1", homework_titles)
51+
self.assertNotIn("Homework 2", homework_titles)

courses/tests/test_dashboard_question_difficulty.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,47 @@ def test_question_difficulty_empty_without_answers(self):
113113

114114
self.assertEqual(response.context["question_difficulty"], [])
115115
self.assertNotContains(response, "Question difficulty")
116+
117+
def test_question_difficulty_excludes_unscored_homework(self):
118+
self.create_answers([True, False])
119+
120+
unscored = Homework.objects.create(
121+
course=self.course,
122+
slug="hw2",
123+
title="Homework 2",
124+
due_date=timezone.now() + timedelta(days=14),
125+
state=HomeworkState.OPEN.value,
126+
)
127+
unscored_question = Question.objects.create(
128+
homework=unscored,
129+
text="Unscored question?",
130+
question_type=QuestionTypes.MULTIPLE_CHOICE.value,
131+
answer_type=AnswerTypes.INTEGER.value,
132+
scores_for_correct_answer=1,
133+
)
134+
user = User.objects.create_user(
135+
username="unscored_student@test.com",
136+
email="unscored_student@test.com",
137+
password="12345",
138+
)
139+
enrollment = Enrollment.objects.create(
140+
student=user, course=self.course
141+
)
142+
submission = Submission.objects.create(
143+
homework=unscored,
144+
student=user,
145+
enrollment=enrollment,
146+
)
147+
Answer.objects.create(
148+
submission=submission,
149+
question=unscored_question,
150+
answer_text="1",
151+
is_correct=False,
152+
)
153+
154+
response = self.client.get(self.dashboard_url())
155+
156+
groups = response.context["question_difficulty"]
157+
homework_titles = [g["homework_title"] for g in groups]
158+
self.assertIn("Homework 1", homework_titles)
159+
self.assertNotIn("Homework 2", homework_titles)

courses/views/dashboard_homeworks.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from django.db.models import Sum
55

6-
from courses.models.homework import Homework, Submission
6+
from courses.models.homework import Homework, HomeworkState, Submission
77
from courses.views.dashboard_metrics import (
88
quartile_fields,
99
safe_quartiles,
@@ -188,7 +188,11 @@ def _homework_difficulty_sort_key(hw_stat):
188188
def dashboard_homework_difficulty_stats(homework_stats):
189189
difficulty_stats = []
190190
for hw_stat in homework_stats:
191-
if hw_stat["score_ratio"] is not None:
191+
homework = hw_stat["homework"]
192+
if (
193+
hw_stat["score_ratio"] is not None
194+
and homework.state == HomeworkState.SCORED.value
195+
):
192196
difficulty_stats.append(hw_stat)
193197
difficulty_stats.sort(key=_homework_difficulty_sort_key)
194198
for rank, hw_stat in enumerate(difficulty_stats, start=1):

courses/views/dashboard_questions.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from django.db.models import Count, Q
22

3-
from courses.models.homework import Answer, AnswerTypes
3+
from courses.models.homework import Answer, AnswerTypes, HomeworkState
44

55

66
def dashboard_question_difficulty(course):
@@ -13,6 +13,7 @@ def dashboard_question_difficulty(course):
1313
rows = (
1414
Answer.objects
1515
.filter(question__homework__course=course)
16+
.filter(question__homework__state=HomeworkState.SCORED.value)
1617
.exclude(question__answer_type=AnswerTypes.ANY.value)
1718
.values(
1819
"question_id",

0 commit comments

Comments
 (0)