from datetime import timedelta from django.core.exceptions import ValidationError from django.db.models import Max from django.template.defaultfilters import floatformat from django.urls import reverse from django.utils.html import format_html from django.utils.safestring import mark_safe from django.utils.translation import gettext_lazy from judge.contest_format.base import BaseContestFormat from judge.contest_format.registry import register_contest_format from judge.utils.timedelta import nice_repr @register_contest_format("default") class DefaultContestFormat(BaseContestFormat): name = gettext_lazy("Default") @classmethod def validate(cls, config): if config is not None and (not isinstance(config, dict) or config): raise ValidationError( "default contest expects no config or empty dict as config" ) def __init__(self, contest, config): super(DefaultContestFormat, self).__init__(contest, config) def update_participation(self, participation): cumtime = 0 points = 0 format_data = {} queryset = participation.submissions if self.contest.freeze_after: queryset = queryset.filter( submission__date__lt=participation.start + self.contest.freeze_after ) queryset = queryset.values("problem_id").annotate( time=Max("submission__date"), points=Max("points"), ) for result in queryset: dt = (result["time"] - participation.start).total_seconds() if result["points"]: cumtime += dt format_data[str(result["problem_id"])] = { "time": dt, "points": result["points"], } points += result["points"] self.handle_frozen_state(participation, format_data) participation.cumtime = max(cumtime, 0) participation.score = round(points, self.contest.points_precision) participation.tiebreaker = 0 participation.format_data = format_data participation.save() def display_user_problem(self, participation, contest_problem): format_data = (participation.format_data or {}).get(str(contest_problem.id)) if format_data: return format_html( '