91 lines
3.1 KiB
Python
91 lines
3.1 KiB
Python
from abc import ABCMeta, abstractmethod, abstractproperty
|
|
|
|
from django.utils import six
|
|
|
|
|
|
class abstractclassmethod(classmethod):
|
|
__isabstractmethod__ = True
|
|
|
|
def __init__(self, callable):
|
|
callable.__isabstractmethod__ = True
|
|
super(abstractclassmethod, self).__init__(callable)
|
|
|
|
|
|
class BaseContestFormat(six.with_metaclass(ABCMeta)):
|
|
@abstractmethod
|
|
def __init__(self, contest, config):
|
|
self.config = config
|
|
self.contest = contest
|
|
|
|
@abstractproperty
|
|
def name(self):
|
|
"""
|
|
Name of this contest format. Should be invoked with gettext_lazy.
|
|
|
|
:return: str
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
@abstractclassmethod
|
|
def validate(cls, config):
|
|
"""
|
|
Validates the contest format configuration.
|
|
|
|
:param config: A dictionary containing the configuration for this contest format.
|
|
:return: None
|
|
:raises: ValidationError
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
@abstractmethod
|
|
def update_participation(self, participation):
|
|
"""
|
|
Updates a ContestParticipation object's score, cumtime, and format_data fields based on this contest format.
|
|
Implementations should call ContestParticipation.save().
|
|
|
|
:param participation: A ContestParticipation object.
|
|
:return: None
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
@abstractmethod
|
|
def display_user_problem(self, participation, contest_problem):
|
|
"""
|
|
Returns the HTML fragment to show a user's performance on an individual problem. This is expected to use
|
|
information from the format_data field instead of computing it from scratch.
|
|
|
|
:param participation: The ContestParticipation object linking the user to the contest.
|
|
:param contest_problem: The ContestProblem object representing the problem in question.
|
|
:return: An HTML fragment, marked as safe for Jinja2.
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
@abstractmethod
|
|
def display_participation_result(self, participation):
|
|
"""
|
|
Returns the HTML fragment to show a user's performance on the whole contest. This is expected to use
|
|
information from the format_data field instead of computing it from scratch.
|
|
|
|
:param participation: The ContestParticipation object.
|
|
:return: An HTML fragment, marked as safe for Jinja2.
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
@abstractmethod
|
|
def get_problem_breakdown(self, participation, contest_problems):
|
|
"""
|
|
Returns a machine-readable breakdown for the user's performance on every problem.
|
|
|
|
:param participation: The ContestParticipation object.
|
|
:param contest_problems: The list of ContestProblem objects to display performance for.
|
|
:return: A list of dictionaries, whose content is to be determined by the contest system.
|
|
"""
|
|
raise NotImplementedError()
|
|
|
|
@classmethod
|
|
def best_solution_state(cls, points, total):
|
|
if not points:
|
|
return 'failed-score'
|
|
if points == total:
|
|
return 'full-score'
|
|
return 'partial-score'
|