Skip to content

Commit d8323fe

Browse files
authored
refactor: remove CategoryProblem (#993)
1 parent 0460e47 commit d8323fe

24 files changed

+267
-245
lines changed

bullet/bullet_admin/forms/review.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,9 @@ def clean(self):
1717

1818

1919
def get_review_formset(team: Team):
20-
problems = team.venue.category.problems.count()
20+
problems = (
21+
team.venue.category.competition.problem_count
22+
- team.venue.category.first_problem
23+
+ 1
24+
)
2125
return formset_factory(ReviewForm, min_num=problems, max_num=problems)

bullet/bullet_admin/urls/__init__.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
archive,
77
auth,
88
category,
9-
categoryproblems,
109
competition,
1110
content,
1211
education,
@@ -277,11 +276,6 @@
277276
education.SchoolCreateView.as_view(),
278277
name="school_create",
279278
),
280-
path(
281-
"problems/generate/",
282-
categoryproblems.ProblemsGenerateView.as_view(),
283-
name="problems_generate",
284-
),
285279
path("gallery/albums/", albums.AlbumListView.as_view(), name="album_list"),
286280
path("gallery/albums/new/", albums.AlbumCreateView.as_view(), name="album_create"),
287281
path(

bullet/bullet_admin/views/categoryproblems.py

Lines changed: 0 additions & 45 deletions
This file was deleted.

bullet/bullet_admin/views/scanning.py

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
mark_problem_unsolved,
2424
)
2525
from problems.logic.scanner import ScannedBarcode, parse_barcode, save_scan
26-
from problems.models import CategoryProblem, Problem, ScannerLog, SolvedProblem
26+
from problems.models import Problem, ScannerLog, SolvedProblem
2727
from users.models import Team
2828

2929
from bullet_admin.forms.review import get_review_formset
@@ -161,11 +161,9 @@ def scan(self, request):
161161
if scanned_barcode.team.is_reviewed:
162162
raise ValueError("The team was already reviewed.")
163163

164-
problem_count = CategoryProblem.objects.filter(
165-
category=scanned_barcode.team.venue.category
166-
).count()
164+
max_problem_number = self.venue.category.competition.problem_count
167165
last = get_last_problem_for_team(scanned_barcode.team)
168-
if last < problem_count:
166+
if last < max_problem_number:
169167
if scanned_barcode.problem_number != last + 1:
170168
raise ValueError(
171169
f"Expected problem number {last + 1}, got "
@@ -291,22 +289,22 @@ def get_form_class(self):
291289
return get_review_formset(self.team)
292290

293291
def get_initial(self):
294-
category_problems = {
295-
cp.number: cp.problem_id
296-
for cp in CategoryProblem.objects.filter(
297-
category=self.team.venue.category
298-
).order_by("number")
299-
}
292+
competition = get_active_competition(self.request)
293+
problems = Problem.objects.filter(competition=competition)
294+
300295
solved_timestamps = {
301296
sp.problem_id: sp.competition_time for sp in self.team.solved_problems.all()
302297
}
303298
initial = []
304299

305-
for num, id in category_problems.items():
306-
row = {"number": num}
307-
if id in solved_timestamps:
300+
for problem in problems:
301+
if problem.number < self.team.venue.category.first_problem:
302+
continue
303+
304+
row = {"number": problem.number}
305+
if problem.id in solved_timestamps:
308306
row["is_solved"] = True
309-
row["competition_time"] = solved_timestamps[id]
307+
row["competition_time"] = solved_timestamps[problem.id]
310308

311309
initial.append(row)
312310

@@ -318,11 +316,9 @@ def get_context_data(self, **kwargs):
318316
return ctx
319317

320318
def form_valid(self, form):
321-
category_problems: dict[int, Problem] = {
322-
cp.number: cp.problem
323-
for cp in CategoryProblem.objects.filter(category=self.team.venue.category)
324-
.order_by("number")
325-
.select_related("problem")
319+
competition = get_active_competition(self.request)
320+
problems: dict[int, Problem] = {
321+
p.number: p for p in Problem.objects.filter(competition=competition)
326322
}
327323
solved: dict[int, SolvedProblem] = {
328324
sp.problem_id: sp for sp in self.team.solved_problems.all()
@@ -331,9 +327,10 @@ def form_valid(self, form):
331327
changed = False
332328
for row in form:
333329
num = row.cleaned_data.get("number")
334-
if num not in category_problems:
330+
if num not in problems or num < self.team.venue.category.first_problem:
335331
continue
336-
problem: Problem = category_problems[num]
332+
333+
problem: Problem = problems[num]
337334
is_solved: bool = row.cleaned_data.get("is_solved")
338335
competition_time: timedelta = row.cleaned_data.get("competition_time")
339336

@@ -383,8 +380,7 @@ def post(self, request, *args, **kwargs):
383380
continue
384381
problem = Problem.objects.filter(
385382
competition=team.venue.category.competition,
386-
category_problems__category=team.venue.category,
387-
category_problems__number=solve["problem"],
383+
number=solve["problem"],
388384
).first()
389385
if not problem:
390386
continue

bullet/bullet_admin/views/venues.py

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from documents.generators.tearoff import TearoffGenerator, TearoffRequirementMissing
2121
from documents.models import TexJob
2222
from problems.logic.results import save_country_ranks, save_venue_ranks
23-
from problems.models import CategoryProblem, Problem
23+
from problems.models import Problem
2424
from users.logic import get_venue_waiting_list, move_eligible_teams
2525
from users.models import Team
2626

@@ -226,14 +226,10 @@ def get_form_kwargs(self):
226226
kw = super().get_form_kwargs()
227227
competition = get_active_competition(self.request)
228228
problem_count = Problem.objects.filter(competition=competition).count()
229-
first_problem = (
230-
CategoryProblem.objects.filter(category=self.venue.category)
231-
.order_by("number")
232-
.first()
233-
)
229+
234230
kw["problems"] = problem_count
235231
kw["venue"] = self.venue
236-
kw["first_problem"] = first_problem.number if first_problem else 1
232+
kw["first_problem"] = self.venue.category.first_problem
237233
return kw
238234

239235
def form_valid(self, form):

bullet/competitions/models/venues.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from datetime import datetime
12
from typing import TYPE_CHECKING
23

34
from bullet_admin.utils import get_active_competition
@@ -136,7 +137,7 @@ def contact_email(self):
136137
return self.email
137138

138139
@property
139-
def start_time(self):
140+
def start_time(self) -> datetime:
140141
if self.local_start:
141142
return self.local_start
142143
return self.category.competition.competition_start

bullet/problems/admin.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@
33
from problems import models
44

55

6-
class CategoryProblemAdminInline(admin.TabularInline):
7-
model = models.CategoryProblem
6+
class ProblemStatementInline(admin.StackedInline):
7+
model = models.ProblemStatement
88

99

1010
@admin.register(models.Problem)
1111
class ProblemAdmin(admin.ModelAdmin):
1212
list_filter = ("competition", "competition__branch")
13-
list_display = ("name", "competition")
14-
inlines = (CategoryProblemAdminInline,)
13+
list_display = ("number", "competition")
14+
inlines = (ProblemStatementInline,)
1515

1616

1717
@admin.register(models.ProblemStatement)
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
from competitions.models import Competition
22

3-
from problems.factories.problems import CategoryProblemFactory, ProblemFactory
3+
from problems.factories.problems import ProblemFactory
44
from problems.models import Problem
55

66

77
def create_problems(competition: Competition) -> list[Problem]:
88
problems = ProblemFactory.create_batch(42, competition=competition)
9-
CategoryProblemFactory.create_batch(42)
109
return problems
Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,13 @@
11
import factory
2-
from competitions.models import Category, Competition
2+
from competitions.models import Competition
33
from factory.django import DjangoModelFactory
44

5-
from problems.models import CategoryProblem, Problem
5+
from problems.models import Problem
66

77

88
class ProblemFactory(DjangoModelFactory):
99
class Meta:
1010
model = Problem
1111

12-
name = factory.Faker("sentence")
13-
competition = factory.Faker("random_element", elements=Competition.objects.all())
14-
15-
16-
class CategoryProblemFactory(DjangoModelFactory):
17-
class Meta:
18-
model = CategoryProblem
19-
django_get_or_create = ("problem", "category", "number")
20-
21-
problem = factory.Faker("random_element", elements=Problem.objects.all())
22-
category = factory.Faker("random_element", elements=Category.objects.all())
2312
number = factory.Faker("random_int")
13+
competition = factory.Faker("random_element", elements=Competition.objects.all())

bullet/problems/logic/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99

1010
def get_last_problem_for_team(team: Team):
11+
"""
12+
Return the number of the highest problem the team should have on their table.
13+
"""
1114
return (
1215
SolvedProblem.objects.filter(team=team).count()
1316
+ team.venue.category.problems_per_team

0 commit comments

Comments
 (0)