NDOJ/judge/contest_format/base.py
2022-10-31 20:43:06 -05:00

97 lines
3.3 KiB
Python

from abc import ABCMeta, abstractmethod, abstractproperty
class abstractclassmethod(classmethod):
__isabstractmethod__ = True
def __init__(self, callable):
callable.__isabstractmethod__ = True
super(abstractclassmethod, self).__init__(callable)
class BaseContestFormat(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()
@abstractmethod
def get_contest_problem_label_script(self):
"""
Returns the default Lua script to generate contest problem labels.
:return: A string, the Lua script.
"""
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"