API¶
Arenas¶
Arena and corner loading routines.
- class sr.comp.arenas.Arena(name, display_name, colour)[source]¶
Bases:
NamedTuple
- colour: sr.comp.types.Colour¶
Alias for field number 2
- name: sr.comp.types.ArenaName¶
Alias for field number 0
- class sr.comp.arenas.Corner(number, colour)[source]¶
Bases:
NamedTuple
- colour: sr.comp.types.Colour¶
Alias for field number 1
- number: sr.comp.arenas.CornerNumber¶
Alias for field number 0
- sr.comp.arenas.load_arenas(filename: pathlib.Path) dict[sr.comp.types.ArenaName, sr.comp.arenas.Arena] [source]¶
Load arenas from a YAML file.
- sr.comp.arenas.load_corners(filename: pathlib.Path) dict[sr.comp.arenas.CornerNumber, sr.comp.arenas.Corner] [source]¶
Load corner colours from a YAML file.
Competition¶
Core competition functions.
- class sr.comp.comp.SRComp(root: str | pathlib.Path)[source]¶
Bases:
object
A class containing all the various parts of a competition.
- Parameters
root (Path) – The root path of the
compstate
repo.
- arenas¶
A
collections.OrderedDict
mapping arena names tosr.comp.arenas.Arena
objects.
- awards¶
A
dict
mappingsr.comp.winners.Award
objects to alist
of teams.
- corners¶
A
collections.OrderedDict
mapping corner numbers tosr.comp.arenas.Corner
objects.
- schedule¶
A
sr.comp.matches.MatchSchedule
instance.
- scores¶
A
sr.comp.scores.Scores
instance.
- state¶
The current commit of the Compstate repository.
- teams¶
A mapping of TLAs to
sr.comp.teams.Team
objects.
- timezone¶
The timezone of the competition.
- venue¶
A
sr.comp.venue.Venue
instance.
- sr.comp.comp.load_scorer(root: pathlib.Path) Type[Union[sr.comp.types.ValidatingScorer, sr.comp.types.SimpleScorer]] [source]¶
Load the scorer module from Compstate repo.
- Parameters
root (Path) – The path to the compstate repo.
Knockout Schedulers¶
Knockout schedule generation.
- class sr.comp.knockout_scheduler.base_scheduler.BaseKnockoutScheduler(schedule: MatchSchedule, scores: Scores, arenas: Iterable[ArenaName], num_teams_per_arena: int, teams: Mapping[TLA, Team], config: YAMLData)[source]¶
Bases:
object
Base class for knockout schedulers offering common functionality.
- Parameters
- add_knockouts() None [source]¶
Add the knockouts to the schedule.
Derived classes must override this method.
- static get_match_display_name(rounds_remaining: int, round_num: int, global_num: sr.comp.types.MatchNumber) str [source]¶
Get a human-readable match display name.
- Parameters
rounds_remaining – The number of knockout rounds remaining.
knockout_num – The match number within the knockout round.
global_num – The global match number.
- get_ranking(game: sr.comp.match_period.Match) list[sr.comp.types.TLA] [source]¶
Get a ranking of the given match’s teams.
- Parameters
game – A game.
- num_teams_per_arena¶
The number of spaces for teams in an arena.
This is used in building matches where we don’t yet know which teams will actually be playing, and for filling in when there aren’t enough teams to fill the arena.
- class sr.comp.knockout_scheduler.KnockoutScheduler(schedule: MatchSchedule, scores: Scores, arenas: Iterable[ArenaName], num_teams_per_arena: int, teams: Mapping[TLA, Team], config: YAMLData)[source]¶
Bases:
sr.comp.knockout_scheduler.base_scheduler.BaseKnockoutScheduler
A class that can be used to generate a knockout schedule based on seeding.
Due to the way the seeding logic works, this class is suitable only when games feature four slots for competitors, with the top two progressing to the next round.
- Parameters
- add_knockouts() None [source]¶
Add the knockouts to the schedule.
Derived classes must override this method.
- get_winners(game: sr.comp.match_period.Match) list[sr.comp.types.TLA] [source]¶
Find the parent match’s winners.
- Parameters
game – A game.
- num_teams_per_arena = 4¶
Constant value due to the way the automatic seeding works.
- class sr.comp.knockout_scheduler.StaticScheduler(*args: Any, **kwargs: Any)[source]¶
Bases:
sr.comp.knockout_scheduler.base_scheduler.BaseKnockoutScheduler
A knockout scheduler which loads almost fixed data from the config. Assumes only a single arena.
Due to the nature of its interaction with the seedings, this scheduler has a very limited handling of dropped-out teams: it only adjusts its scheduling for dropouts before the knockouts.
- The practical results of this dropout behaviour are:
the schedule is stable when teams drop out, as this either affects the entire knockout or none of it
dropping out a team such that there are no longer enough seeds requires manual changes to the schedule to remove the seeds which cannot be filled
Stable Random¶
A stable random number generator implementation.
- class sr.comp.knockout_scheduler.stable_random.Random[source]¶
Bases:
object
Our own random number generator that is guaranteed to be stable.
Python’s random number generator’s stability across Python versions is complicated. Different versions will produce different results. It’s easier right now to just have our own random number generator that’s not as good, but is definitely stable between machines.
Note
This class is deliberately not a sub-class of
random.Random
since any of the functionality provided by the class (i.e. not just the generation portion) could change between Python versions. Instead, any additionally required functionality should be added below as needed and _importantly_ tests for the functionality to ensure that the output is the same on all supported platforms.
Match Period¶
Classes that are useful for dealing with match periods.
- class sr.comp.match_period.Delay(delay, time)[source]¶
Bases:
NamedTuple
- delay: datetime.timedelta¶
Alias for field number 0
- time: datetime.datetime¶
Alias for field number 1
- class sr.comp.match_period.Match(num, display_name, arena, teams, start_time, end_time, type, use_resolved_ranking)[source]¶
Bases:
NamedTuple
- arena: sr.comp.types.ArenaName¶
Alias for field number 2
- end_time: datetime.datetime¶
Alias for field number 5
- num: sr.comp.types.MatchNumber¶
Alias for field number 0
- start_time: datetime.datetime¶
Alias for field number 4
- type: sr.comp.match_period.MatchType¶
Alias for field number 6
- class sr.comp.match_period.MatchPeriod(start_time, end_time, max_end_time, description, matches, type)[source]¶
Bases:
NamedTuple
- end_time: datetime.datetime¶
Alias for field number 1
- max_end_time: datetime.datetime¶
Alias for field number 2
- start_time: datetime.datetime¶
Alias for field number 0
- type: sr.comp.match_period.MatchType¶
Alias for field number 5
Match Period Clock¶
A clock to manage match periods.
- class sr.comp.match_period_clock.MatchPeriodClock(period: sr.comp.match_period.MatchPeriod, delays: Iterable[sr.comp.match_period.Delay])[source]¶
Bases:
object
A clock for use in scheduling matches within a
MatchPeriod
.It is generally expected that the time information here will be in the form of
datetime
andtimedelta
instances, though any data which can be compared and added appropriately should work.Delay rules:
Only delays which are scheduled after the start of the given period will be considered.
Delays are cumulative.
Delays take effect as soon as their
time
is reached.
- advance_time(duration: datetime.timedelta) None [source]¶
Make a given amount of time pass. This is expected to be called after scheduling some matches in order to move to the next timeslot.
Note
It is assumed that the duration value will always be ‘positive’, i.e. that time will not go backwards. The results of the duration value being ‘negative’ are undefined.
- property current_time: datetime.datetime¶
Get the apparent current time. This is a combination of the time which has passed (through calls to
advance_time
) and the delays which have occurred.Will raise an
OutOfTimeException
if either:the end of the period has been reached (i.e: the sum of durations passed to
advance_time
has exceeded the planned duration of the period), orthe maximum end of the period has been reached (i.e: the current time would be after the period’s
max_end_time
).
- static delays_for_period(period: sr.comp.match_period.MatchPeriod, delays: Iterable[sr.comp.match_period.Delay]) list[sr.comp.match_period.Delay] [source]¶
Filter and sort a list of all possible delays to include only those which occur after the start of the given period.
- Parameters
period (MatchPeriod) – The period to get the delays for.
- Returns
A sorted list of delays which occur after the start of the period.
- iterslots(slot_duration: datetime.timedelta) Iterator[datetime.datetime] [source]¶
Iterate through all the available timeslots of the given size within the
MatchPeriod
, taking into account delays.This is equivalent to checking the current_time and repeatedly calling
advance_time
with the given duration. As a result, it is safe to calladvance_time
between iterations if additional gaps between slots are needed.
Matches¶
Match schedule library.
- class sr.comp.matches.MatchSchedule(y: Any, league: sr.comp.types.LeagueMatches, teams: Mapping[sr.comp.types.TLA, sr.comp.teams.Team], num_teams_per_arena: int)[source]¶
Bases:
object
A match schedule.
- add_tiebreaker(scores: sr.comp.scores.Scores, time: datetime.datetime) None [source]¶
Add a tie breaker to the league if required. Also set a
tiebreaker
attribute if necessary.- Parameters
scores (Scores) – The scores for the competition.
time (datetime.datetime) – The time to have the tiebreaker match.
- classmethod create(config_fname: pathlib.Path, league_fname: pathlib.Path, scores: sr.comp.scores.Scores, arenas: Mapping[sr.comp.types.ArenaName, sr.comp.arenas.Arena], num_teams_per_arena: int, teams: Mapping[sr.comp.types.TLA, sr.comp.teams.Team]) sr.comp.matches.TSchedule [source]¶
Create a new match schedule around the given config data.
- property datetime_now: datetime.datetime¶
Get the current date and time, with the correct timezone.
- delay_at(date: datetime.datetime) datetime.timedelta [source]¶
Calculates the active delay at a given
date
. Intended for use only in exposing the current delay value – scheduling should be done using aMatchPeriodClock
instead.- Parameters
date (datetime) – The date to find the delay for.
- Returns
A
datetime.timedelta
specifying the active delay.
- property final_match: sr.comp.match_period.Match¶
Get the
Match
for the last match of the competition.This is the info for the ‘finals’ of the competition (i.e: the last of the knockout matches) unless there is a tiebreaker.
- get_staging_times(match: sr.comp.match_period.Match) sr.comp.matches.StagingTimes [source]¶
- knockout_rounds: list[list[sr.comp.match_period.Match]]¶
A list of the knockout matches by round. Each entry in the list represents a round of knockout matches, such that knockout_rounds[-1] contains a list with only one match – the final.
- match_periods: list[sr.comp.match_period.MatchPeriod]¶
A list of the
MatchPeriod
s which contain the matches for the competition.
- matches: list[sr.comp.match_period.MatchSlot]¶
A list of match slots in the schedule. Each match slot is a dict of arena to the
Match
occurring in that arena.
- matches_at(date: datetime.datetime) Iterator[sr.comp.match_period.Match] [source]¶
Get all the matches that occur around a specific
date
.- Parameters
date (datetime) – The date at which matches occur.
- Returns
An iterable list of matches.
- n_planned_league_matches¶
The number of planned league matches.
- period_at(date: datetime.datetime) sr.comp.match_period.MatchPeriod | None [source]¶
Get the match period that occur around a specific
date
.- Parameters
date (datetime) – The date at which period occurs.
- Returns
The period at that time or
None
.
- class sr.comp.matches.StagingOffsets[source]¶
Bases:
typing_extensions.TypedDict
- closes: datetime.timedelta¶
- duration: datetime.timedelta¶
- opens: datetime.timedelta¶
- signal_shepherds: Mapping[sr.comp.types.ShepherdName, datetime.timedelta]¶
- signal_teams: datetime.timedelta¶
- class sr.comp.matches.StagingTimes[source]¶
Bases:
typing_extensions.TypedDict
- closes: datetime.datetime¶
- duration: datetime.timedelta¶
- opens: datetime.datetime¶
- signal_shepherds: Mapping[sr.comp.types.ShepherdName, datetime.datetime]¶
- signal_teams: datetime.datetime¶
- exception sr.comp.matches.WrongNumberOfTeams(match_n: int, arena_name: str, teams: Sequence[Optional[sr.comp.types.TLA]], num_teams_per_arena: int)[source]¶
Bases:
Exception
- sr.comp.matches.get_timezone(name: str) datetime.tzinfo [source]¶
Raw Compstate¶
Utilities for working with raw Compstate repositories.
- class sr.comp.raw_compstate.RawCompstate(path: str | pathlib.Path, local_only: bool)[source]¶
Bases:
object
Helper class to interact with a Compstate as raw files in a Git repository on disk.
- Parameters
path (Path) – The path to the Compstate repository.
local_only (bool) – If true, this disabled the pulling, committing and pushing functionality.
- get_score_path(match: sr.comp.match_period.Match) str [source]¶
Get the path to the score file for the given match.
- git(command_pieces: Iterable[str], err_msg: str = '', *, return_output: Literal[True]) str [source]¶
- git(command_pieces: Iterable[str], err_msg: str = '', return_output: Literal[False] = False) int
- git(command_pieces: Iterable[str], err_msg: str = '', return_output: bool = False) str | int
- property has_changes: bool¶
Whether or not there are any changes to files in the state, including untracked files.
- property layout: sr.comp.types.LayoutData¶
- load() sr.comp.comp.SRComp [source]¶
Load the state as an
SRComp
instance.
- load_score(match: sr.comp.match_period.Match) sr.comp.types.ScoreData [source]¶
Load raw score data for the given match.
- load_shepherds() list[sr.comp.raw_compstate.ShepherdInfo] [source]¶
Load the shepherds’ state.
- save_score(match: sr.comp.match_period.Match, score: sr.comp.types.ScoreData) None [source]¶
Save raw score data for the given match.
- property shepherding: sr.comp.types.ShepherdingData¶
Provides access to the raw shepherding data. Most consumers actually want to use
load_shepherds
instead.
Scores¶
Utilities for working with scores.
- class sr.comp.scores.BaseScores(scores_data: Iterable[sr.comp.types.ScoreData], teams: Iterable[sr.comp.types.TLA], scorer: Type[Union[sr.comp.types.ValidatingScorer, sr.comp.types.SimpleScorer]], num_teams_per_arena: int)[source]¶
Bases:
object
A generic class that holds scores.
- Parameters
- game_points: dict[typing.Tuple[sr.comp.types.ArenaName, sr.comp.types.MatchNumber], typing.Mapping[sr.comp.types.TLA, sr.comp.types.GamePoints]]¶
Game points data for each match. Keys are tuples of the form
(arena_id, match_num)
, values aredict
s mapping TLAs to the number of game points they scored.
- game_positions: dict[typing.Tuple[sr.comp.types.ArenaName, sr.comp.types.MatchNumber], typing.Mapping[league_ranker.RankedPosition, set[sr.comp.types.TLA]]]¶
Game position data for each match. Keys are tuples of the form
(arena_id, match_num)
, values aredict
s mapping ranked positions (i.e: first is 1, etc.) to an iterable of TLAs which have that position. Based solely on teams’ game points.
- get_rankings(match: sr.comp.match_period.Match) Mapping[sr.comp.types.TLA, league_ranker.RankedPosition] [source]¶
Return a mapping of TLAs to ranked positions for the given match.
This is an internal API – most consumers should use
Scores.get_scores
instead.
- property last_scored_match: Optional[sr.comp.types.MatchNumber]¶
The most match with the highest id for which we have score data.
- ranked_points: dict[typing.Tuple[sr.comp.types.ArenaName, sr.comp.types.MatchNumber], dict[sr.comp.types.TLA, league_ranker.LeaguePoints]]¶
Normalised (aka ‘league’) points earned in each match. Keys are tuples of the form
(arena_id, match_num)
, values aredict
s mapping TLAs to the number of normalised points they would earn for that match.
- teams: Mapping[sr.comp.types.TLA, sr.comp.scores.TeamScore]¶
Points for each team earned during this portion of the competition. Maps TLAs to
TeamScore
instances.
- exception sr.comp.scores.DuplicateScoresheet(match_id: Tuple[sr.comp.types.ArenaName, sr.comp.types.MatchNumber])[source]¶
Bases:
Exception
An exception that occurs if two scoresheets for the same match have been entered.
- exception sr.comp.scores.InvalidTeam(tla: sr.comp.types.TLA, context: str)[source]¶
Bases:
Exception
An exception that occurs when a score contains an invalid team.
- class sr.comp.scores.KnockoutScores(scores_data: Iterable[sr.comp.types.ScoreData], teams: Iterable[sr.comp.types.TLA], scorer: Type[Union[sr.comp.types.ValidatingScorer, sr.comp.types.SimpleScorer]], num_teams_per_arena: int, league_positions: Mapping[sr.comp.types.TLA, sr.comp.scores.LeaguePosition])[source]¶
Bases:
sr.comp.scores.BaseScores
A class which holds knockout scores.
- static calculate_ranking(match_points: Mapping[sr.comp.types.TLA, league_ranker.LeaguePoints], league_positions: Mapping[sr.comp.types.TLA, sr.comp.scores.LeaguePosition]) dict[sr.comp.types.TLA, league_ranker.RankedPosition] [source]¶
Get a ranking of the given match’s teams.
- Parameters
match_points – A map of TLAs to (normalised) scores.
league_positions – A map of TLAs to league positions.
- get_rankings(match: sr.comp.match_period.Match) Mapping[sr.comp.types.TLA, league_ranker.RankedPosition] [source]¶
Return a mapping of TLAs to ranked positions for the given match.
This is an internal API – most consumers should use
Scores.get_scores
instead.
- resolved_positions¶
Position data for each match which includes adjustment for ties. Keys are tuples of the form
(arena_id, match_num)
, values areOrderedDict
s mapping TLAs to the ranked position (i.e: first is 1, etc.) of that team, with the winning team in the start of the list of keys. Tie resolution is done by league position.
- class sr.comp.scores.LeagueScores(scores_data: Iterable[sr.comp.types.ScoreData], teams: Iterable[sr.comp.types.TLA], scorer: Type[Union[sr.comp.types.ValidatingScorer, sr.comp.types.SimpleScorer]], num_teams_per_arena: int, extra: Optional[Mapping[sr.comp.types.TLA, sr.comp.scores.TeamScore]] = None)[source]¶
Bases:
sr.comp.scores.BaseScores
A class which holds league scores.
- positions¶
An
OrderedDict
of TLAs tosr.comp.scores.LeaguePosition
s.
- static rank_league(team_scores: Mapping[sr.comp.types.TLA, sr.comp.scores.TeamScore]) Mapping[sr.comp.types.TLA, sr.comp.scores.LeaguePosition] [source]¶
Given a mapping of TLA to TeamScore, returns a mapping of TLA to league position which both allows for ties and enables their resolution deterministically.
- class sr.comp.scores.MatchScore(match_id: 'MatchId', game: 'Mapping[TLA, GamePoints]', normalised: 'Mapping[TLA, LeaguePoints]', ranking: 'Mapping[TLA, RankedPosition]')[source]¶
Bases:
object
- game: Mapping[sr.comp.types.TLA, sr.comp.types.GamePoints]¶
- match_id: Tuple[sr.comp.types.ArenaName, sr.comp.types.MatchNumber]¶
- normalised: Mapping[sr.comp.types.TLA, league_ranker.LeaguePoints]¶
- ranking: Mapping[sr.comp.types.TLA, league_ranker.RankedPosition]¶
- class sr.comp.scores.Scores(league: sr.comp.scores.LeagueScores, knockout: sr.comp.scores.KnockoutScores, tiebreaker: sr.comp.scores.TiebreakerScores)[source]¶
Bases:
object
A simple class which stores references to the league and knockout scores.
- get_scores(match: sr.comp.match_period.Match) sr.comp.scores.MatchScore | None [source]¶
Get the scores for a given match.
- Parameters
match (sr.comp.match_period.Match) – A match.
- Returns
An object describing the scores for the match, if scores have been recorded yet. Otherwise None.
- Return type
- knockout¶
The
KnockoutScores
for the competition.
- last_scored_match¶
The match with the highest id for which we have score data.
- league¶
The
LeagueScores
for the competition.
- classmethod load(root: pathlib.Path, teams: Iterable[sr.comp.types.TLA], scorer: Type[Union[sr.comp.types.ValidatingScorer, sr.comp.types.SimpleScorer]], num_teams_per_arena: int) sr.comp.scores.Scores [source]¶
- tiebreaker¶
The
TiebreakerScores
for the competition.
- class sr.comp.scores.TeamScore(league: league_ranker.LeaguePoints = 0, game: sr.comp.types.GamePoints = 0)[source]¶
Bases:
object
A team score.
- class sr.comp.scores.TiebreakerScores(scores_data: Iterable[sr.comp.types.ScoreData], teams: Iterable[sr.comp.types.TLA], scorer: Type[Union[sr.comp.types.ValidatingScorer, sr.comp.types.SimpleScorer]], num_teams_per_arena: int, league_positions: Mapping[sr.comp.types.TLA, sr.comp.scores.LeaguePosition])[source]¶
- sr.comp.scores.degroup(grouped_positions: Mapping[sr.comp.scores.T, Iterable[sr.comp.types.TLA]]) collections.OrderedDict[sr.comp.types.TLA, sr.comp.scores.T] [source]¶
Given a mapping of positions to collections of teams at that position, returns an
OrderedDict
of teams to their positions.Where more than one team has a given position, they are sorted before being inserted.
- sr.comp.scores.get_validated_scores(scorer_cls: Type[Union[sr.comp.types.ValidatingScorer, sr.comp.types.SimpleScorer]], input_data: sr.comp.types.ScoreData) Mapping[sr.comp.types.TLA, sr.comp.types.GamePoints] [source]¶
Helper function which mimics the behaviour from libproton.
Given a libproton 3.0 (Proton 3.0.0-rc2) compatible class this will calculate the scores and validate the input.
- sr.comp.scores.load_external_scores(scores_data: Iterable[sr.comp.types.ExternalScoreData], teams: Iterable[sr.comp.types.TLA]) Mapping[sr.comp.types.TLA, sr.comp.scores.TeamScore] [source]¶
Mechanism to import additional scores from an external source.
This provides flexibility in the sources of score data.
- sr.comp.scores.load_external_scores_data(result_dir: pathlib.Path) Iterator[sr.comp.types.ExternalScoreData] [source]¶
- sr.comp.scores.load_scores_data(result_dir: pathlib.Path) Iterator[sr.comp.types.ScoreData] [source]¶
- sr.comp.scores.results_finder(root: pathlib.Path) Iterator[pathlib.Path] [source]¶
An iterator that finds score sheet files.
Teams¶
Team metadata library.
- class sr.comp.teams.Team(tla, name, rookie, dropped_out_after)[source]¶
Bases:
NamedTuple
- dropped_out_after: Optional[sr.comp.types.MatchNumber]¶
Alias for field number 3
- is_still_around(match_number: sr.comp.types.MatchNumber) bool [source]¶
Check if this team is still around at a certain match.
- Parameters
match_number (int) – The number of the match to check.
- Returns
True
if the team is still playing.
- tla: sr.comp.types.TLA¶
Alias for field number 0
- sr.comp.teams.load_teams(filename: pathlib.Path) dict[sr.comp.types.TLA, sr.comp.teams.Team] [source]¶
Load teams from a YAML file.
- Parameters
filename (Path) – The filename of the YAML file to load.
- Returns
A dictionary mapping TLAs to
Team
objects.
Validation¶
Compstate validation routines.
- class sr.comp.validation.NaiveValidationError(message: 'str', code: 'str', level: 'ErrorLevel' = 'error')[source]¶
Bases:
object
- level: Literal['error', 'warning', 'hint'] = 'error'¶
- with_source(error_type: sr.comp.validation.ErrorType, id_: object) sr.comp.validation.ValidationError [source]¶
- exception sr.comp.validation.ValidationError(message: 'str', code: 'str', source: 'tuple[ErrorType, object] | None', level: 'ErrorLevel' = 'error')[source]¶
Bases:
Exception
- level: Literal['error', 'warning', 'hint'] = 'error'¶
- sr.comp.validation.find_missing_scores(match_type: sr.comp.match_period.MatchType, match_ids: Iterable[Tuple[sr.comp.types.ArenaName, sr.comp.types.MatchNumber]], last_match: int | None, schedule: Iterable[sr.comp.match_period.MatchSlot]) Sequence[tuple[sr.comp.types.MatchNumber, set[sr.comp.types.ArenaName]]] [source]¶
Given a collection of
match_ids
for which we have scores, thematch_type
currently under consideration, the number of thelast_match
which was scored and the list of all known matches determine which scores should be present but aren’t.
- sr.comp.validation.find_teams_without_league_matches(matches: Iterable[sr.comp.match_period.MatchSlot], possible_teams: Iterable[sr.comp.types.TLA]) set[sr.comp.types.TLA] [source]¶
Find teams that don’t have league matches.
- sr.comp.validation.report_errors(error_type: sr.comp.validation.ErrorType, id_: object, errors: list[str]) None [source]¶
Print out errors nicely formatted.
- sr.comp.validation.report_validation_errors(errors: Sequence[sr.comp.validation.ValidationError]) None [source]¶
- sr.comp.validation.validate(comp: sr.comp.comp.SRComp) int [source]¶
Validate a Compstate repo.
- Parameters
comp (sr.comp.SRComp) – A competition instance.
- Returns
The number of errors that have occurred.
- sr.comp.validation.validate_match(match: sr.comp.match_period.MatchSlot, possible_teams: Iterable[sr.comp.types.TLA]) Iterator[sr.comp.validation.NaiveValidationError] [source]¶
Check that the teams featuring in a match exist and are only required in one arena at a time.
- sr.comp.validation.validate_match_score(match_type: sr.comp.match_period.MatchType, match_score: Mapping[sr.comp.types.TLA, object], scheduled_match: sr.comp.match_period.Match) Iterator[sr.comp.validation.NaiveValidationError] [source]¶
Check that the match awards points to the right teams, by checking that the teams with points were scheduled to appear in the match.
- sr.comp.validation.validate_schedule(schedule: sr.comp.matches.MatchSchedule, possible_teams: Iterable[sr.comp.types.TLA], possible_arenas: Container[sr.comp.types.ArenaName]) Iterator[sr.comp.validation.ValidationError] [source]¶
Check that the schedule contains enough time for all the matches, and that the matches themselves are valid.
- sr.comp.validation.validate_schedule_arenas(matches: Iterable[sr.comp.match_period.MatchSlot], possible_arenas: Container[sr.comp.types.ArenaName]) Iterator[sr.comp.validation.ValidationError] [source]¶
Check that any arena referenced by a match actually exists.
- sr.comp.validation.validate_schedule_count(schedule: sr.comp.matches.MatchSchedule) Iterator[sr.comp.validation.ValidationError] [source]¶
- sr.comp.validation.validate_schedule_timings(scheduled_matches: Iterable[sr.comp.match_period.MatchSlot], match_duration: datetime.timedelta) Iterator[sr.comp.validation.ValidationError] [source]¶
- sr.comp.validation.validate_scores(match_type: sr.comp.match_period.MatchType, scores: sr.comp.scores.BaseScores, schedule: Sequence[sr.comp.match_period.MatchSlot]) Iterator[sr.comp.validation.ValidationError] [source]¶
Validate that the scores are sane.
- sr.comp.validation.validate_scores_inner(match_type: sr.comp.match_period.MatchType, scores: sr.comp.scores.BaseScores, schedule: Sequence[sr.comp.match_period.MatchSlot]) Iterator[sr.comp.validation.ValidationError] [source]¶
Validate that scores are sane.
- sr.comp.validation.validate_team_matches(matches: Iterable[sr.comp.match_period.MatchSlot], possible_teams: Iterable[sr.comp.types.TLA]) Iterator[sr.comp.validation.ValidationError] [source]¶
Check that all teams have been assigned league matches. We don’t need (or want) to check the knockouts, since those are scheduled dynamically based on the list of teams.
- sr.comp.validation.warn_missing_scores(match_type: sr.comp.match_period.MatchType, scores: sr.comp.scores.BaseScores, schedule: Iterable[sr.comp.match_period.MatchSlot]) Iterator[sr.comp.validation.ValidationError] [source]¶
Check that the scores up to the most recent are all present.
- sr.comp.validation.with_source(naive_errors: Iterable[sr.comp.validation.NaiveValidationError], source: tuple[sr.comp.validation.ErrorType, object]) Iterator[sr.comp.validation.ValidationError] [source]¶
Venue¶
Venue layout metadata library.
- exception sr.comp.venue.InvalidRegionException(region: sr.comp.types.RegionName, area: str)[source]¶
Bases:
Exception
An exception that occurs when there are invalid regions mentioned in the shepherding data.
- exception sr.comp.venue.LayoutTeamsException(duplicate_teams: Iterable[sr.comp.types.TLA], extra_teams: Iterable[sr.comp.types.TLA], missing_teams: Iterable[sr.comp.types.TLA])[source]¶
Bases:
sr.comp.venue.MismatchException
[sr.comp.types.TLA
]An exception that occurs when there are duplicate, extra or missing teams in a layout.
- exception sr.comp.venue.MismatchException(tpl: str, duplicates: Iterable[sr.comp.venue.T_str], extras: Iterable[sr.comp.venue.T_str], missing: Iterable[sr.comp.venue.T_str])[source]¶
Bases:
Exception
,Generic
[sr.comp.venue.T_str
]An exception that occurs when there are duplicate, extra or missing items.
- exception sr.comp.venue.ShepherdingAreasException(where: str, duplicate: Iterable[str], extra: Iterable[str], missing: Iterable[str])[source]¶
Bases:
sr.comp.venue.MismatchException
[str
]An exception that occurs when there are duplicate, extra or missing shepherding areas in the staging times.
- class sr.comp.venue.Venue(teams: Iterable[sr.comp.types.TLA], layout_file: pathlib.Path, shepherding_file: pathlib.Path)[source]¶
Bases:
object
A class providing information about the layout within the venue.
- check_staging_times(staging_times: sr.comp.matches.StagingOffsets) None [source]¶
- classmethod check_teams(teams: Iterable[sr.comp.types.TLA], teams_layout: list[sr.comp.types.RegionData]) None [source]¶
Check that the given layout of teams contains the same set of teams as the reference.
Will throw a
LayoutTeamsException
if there are any missing, extra or duplicate teams found.
Winners¶
Calculation of winners of awards.
The awards calculated are:
1st place,
2nd place,
3rd place,
Rookie award (rookie team with highest league position).
- class sr.comp.winners.Award(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]¶
Bases:
enum.Enum
Award types.
These correspond with awards as specified in the rulebook.
- committee = 'committee'¶
- first = 'first'¶
- image = 'image'¶
- movement = 'movement'¶
- rookie = 'rookie'¶
- second = 'second'¶
- third = 'third'¶
- web = 'web'¶
- sr.comp.winners.compute_awards(scores: sr.comp.scores.Scores, final_match: sr.comp.match_period.Match, teams: Mapping[sr.comp.types.TLA, sr.comp.teams.Team], path: pathlib.Path | None = None) Mapping[sr.comp.winners.Award, List[sr.comp.types.TLA]] [source]¶
Compute the awards handed out from configuration.
- Parameters
scores (sr.comp.scores.Scores) – The scores.
final_match (Match) – The match to use as the final.
teams (dict) – A mapping from TLAs to
sr.comp.teams.Team
objects.
- Returns
A dictionary of
Award
types to TLAs is returned. This may not have a key for any award type that has not yet been determined.
YAML Loader¶
YAML loading routines.
This includes parsing of dates and times properly, and also ensures the C YAML loader is used which is necessary for optimum performance.
- sr.comp.yaml_loader.load(file_path: pathlib.Path) Any [source]¶
Load a YAML fie and return the results.
- Parameters
file_path (Path) – The path to the YAML file.
- Returns
The parsed contents.
- sr.comp.yaml_loader.time_constructor(_: Any, node: yaml.nodes.Node) datetime.datetime [source]¶