Skip to content

Commit 807ead7

Browse files
moving scores to pass to course, not project
1 parent 5584ad2 commit 807ead7

12 files changed

Lines changed: 83 additions & 27 deletions

File tree

.dockerignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,7 @@ terraform/
33
Dockerfile
44
Makefile
55
README.md
6-
.venv
6+
.venv
7+
.envrc
8+
.envrc_template
9+
.github

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ deploy_prod:
9393
bash deploy/deploy_prod.sh
9494

9595

96+
sync: ## Install dev dependencies
97+
sync:
98+
uv sync --dev
99+
96100

97101
help: ## Show this help.
98102
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'

courses/admin/course.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def duplicate_course(modeladmin, request, queryset):
7474
first_homework_scored=False,
7575
finished=False,
7676
faq_document_url=course.faq_document_url,
77+
project_passing_score=course.project_passing_score,
7778
)
7879

7980
# Copy review criteria with all fields
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Generated by Django 5.2.4 on 2025-07-17 10:35
2+
3+
from django.db import migrations, models
4+
5+
6+
class Migration(migrations.Migration):
7+
8+
dependencies = [
9+
('courses', '0019_remove_homework_problems_comments_field_and_more'),
10+
]
11+
12+
operations = [
13+
migrations.RemoveField(
14+
model_name='project',
15+
name='points_to_pass',
16+
),
17+
migrations.AddField(
18+
model_name='course',
19+
name='project_passing_score',
20+
field=models.IntegerField(default=0, help_text='Minimum score required to pass any project in this course'),
21+
),
22+
]

courses/models/course.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ class Course(models.Model):
4747
help_text="Include field for problems and comments in homework",
4848
)
4949

50+
project_passing_score = models.IntegerField(
51+
default=0,
52+
help_text="Minimum score required to pass any project in this course",
53+
)
54+
5055
def __str__(self):
5156
return self.title
5257

courses/models/project.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ class Project(models.Model):
4242
points_for_peer_review = models.IntegerField(default=3)
4343
time_spent_evaluation_field = models.BooleanField(default=True)
4444

45-
points_to_pass = models.IntegerField(default=0)
46-
4745
state = models.CharField(
4846
max_length=2,
4947
choices=[(state.value, state.name) for state in ProjectState],
@@ -53,6 +51,11 @@ class Project(models.Model):
5351
def __str__(self):
5452
return self.title
5553

54+
@property
55+
def points_to_pass(self):
56+
"""Get the passing score from the course"""
57+
return self.course.project_passing_score
58+
5659
class Meta:
5760
unique_together = ("course", "slug")
5861

courses/projects.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ def select_random_assignment(
5555

5656
if n <= num_projects_to_review:
5757
raise ValueError(
58-
"The number of projects to review should be greater than the number of submissions. " +
59-
f"Number of projects to review: {num_projects_to_review}, Number of submissions: {n}"
58+
"The number of projects to review should be greater than the number of submissions. "
59+
+ f"Number of projects to review: {num_projects_to_review}, Number of submissions: {n}"
6060
)
6161

62-
random.seed(seed)
62+
random.seed(seed)
6363

6464
submissions_list = list(submissions)
6565

@@ -217,7 +217,7 @@ def score_project(project: Project) -> tuple[ProjectActionStatus, str]:
217217
if project.points_to_pass == 0:
218218
return (
219219
ProjectActionStatus.FAIL,
220-
"Project has no points to pass. Update the `point_to_pass` field to greater than zero value",
220+
"Project has no points to pass. Update the course's `project_passing_score` field to greater than zero value",
221221
)
222222

223223
if project.state != ProjectState.PEER_REVIEWING.value:
@@ -302,7 +302,8 @@ def score_project(project: Project) -> tuple[ProjectActionStatus, str]:
302302
num_mandatory_projects_reviewed += 1
303303

304304
submission.peer_review_score = (
305-
num_mandatory_projects_reviewed * project.points_for_peer_review
305+
num_mandatory_projects_reviewed
306+
* project.points_for_peer_review
306307
)
307308

308309
learning_in_public_cap_project = (
@@ -369,7 +370,7 @@ def score_project(project: Project) -> tuple[ProjectActionStatus, str]:
369370
) and submission.reviewed_enough_peers
370371

371372
submissions_to_update.append(submission)
372-
373+
373374
if submission.passed:
374375
passed += 1
375376

courses/tests/test_course.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,7 @@ def test_duplicate_course(self):
447447
self.course.slug = f"test-course-{current_year - 1}"
448448
self.course.social_media_hashtag = "#testcourse2023"
449449
self.course.faq_document_url = "https://example.com/faq"
450+
self.course.project_passing_score = 75
450451
self.course.save()
451452

452453
# Execute the duplicate action
@@ -479,6 +480,9 @@ def test_duplicate_course(self):
479480
self.assertEqual(
480481
new_course.faq_document_url, self.course.faq_document_url
481482
)
483+
self.assertEqual(
484+
new_course.project_passing_score, self.course.project_passing_score
485+
)
482486
self.assertFalse(new_course.first_homework_scored)
483487
self.assertFalse(new_course.finished)
484488

courses/tests/test_project_score.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ def setUp(self):
5656
course=self.course,
5757
)
5858

59+
# Set the course's project passing score
60+
self.course.project_passing_score = 70
61+
self.course.save()
62+
5963
self.project = Project.objects.create(
6064
course=self.course,
6165
slug="test-project",
@@ -67,7 +71,6 @@ def setUp(self):
6771
learning_in_public_cap_project=5,
6872
learning_in_public_cap_review=3,
6973
number_of_peers_to_evaluate=3,
70-
points_to_pass=70,
7174
)
7275

7376
self.submission = ProjectSubmission.objects.create(
@@ -386,8 +389,8 @@ def test_project_passed(self):
386389
scores = [3, 3, 0]
387390
expected_project_score = 3
388391

389-
self.project.points_to_pass = 3
390-
self.project.save()
392+
self.course.project_passing_score = 3
393+
self.course.save()
391394

392395
answers_and_scores = list(zip(answers, scores))
393396

@@ -425,8 +428,8 @@ def test_project_not_passed(self):
425428
scores = [3, 0, 0]
426429
expected_project_score = 0
427430

428-
self.project.points_to_pass = 3
429-
self.project.save()
431+
self.course.project_passing_score = 3
432+
self.course.save()
430433

431434
answers_and_scores = list(zip(answers, scores))
432435

@@ -452,8 +455,8 @@ def test_project_not_passed(self):
452455
)
453456

454457
def test_not_scoring_when_passing_score_is_0(self):
455-
self.project.points_to_pass = 0
456-
self.project.save()
458+
self.course.project_passing_score = 0
459+
self.course.save()
457460

458461
status, _ = score_project(self.project)
459462
self.assertEqual(status, ProjectActionStatus.FAIL)
@@ -478,8 +481,8 @@ def test_project_passed_with_optional(self):
478481
scores = [3, 3, 0]
479482
expected_project_score = 3
480483

481-
self.project.points_to_pass = 3
482-
self.project.save()
484+
self.course.project_passing_score = 3
485+
self.course.save()
483486

484487
answers_and_scores = list(zip(answers, scores))
485488

courses/views/data.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,10 +103,14 @@ def project_data_view(request, course_slug: str, project_slug: str):
103103
}
104104
submission_data.append(submission_dict)
105105

106+
# Get project data and add the points_to_pass property
107+
project_data = model_to_dict(project)
108+
project_data['points_to_pass'] = project.points_to_pass
109+
106110
# Compile the result
107111
result = {
108112
"course": course_data,
109-
"project": model_to_dict(project),
113+
"project": project_data,
110114
"submissions": submission_data,
111115
}
112116

0 commit comments

Comments
 (0)