def get_tables(self): if self.tournament.pref('teams_in_debate') != 'bp': logger.warning("Tried to access position balance report for a non-BP tournament") return [] if self.round.prev is None: logger.warning("Tried to access position balance report for first round") return [] if self.round.is_break_round: logger.warning("Tried to access position balance report for a break round") return [] draw = self.round.debate_set_with_prefetches(ordering=('room_rank',), institutions=True) teams = Team.objects.filter(debateteam__debate__round=self.round) side_histories_before = get_side_history(teams, self.tournament.sides, self.round.prev.seq) side_histories_now = get_side_history(teams, self.tournament.sides, self.round.seq) metrics = self.tournament.pref('team_standings_precedence') generator = TeamStandingsGenerator(metrics[0:1], ()) standings = generator.generate(teams, round=self.round.prev) summary_table = PositionBalanceReportSummaryTableBuilder(view=self, title=_("Teams with position imbalances"), empty_title=_("No teams with position imbalances! Hooray!") + " 😊") summary_table.build(draw, teams, side_histories_before, side_histories_now, standings) draw_table = PositionBalanceReportDrawTableBuilder(view=self, title=_("Annotated draw")) draw_table.build(draw, teams, side_histories_before, side_histories_now, standings) return [summary_table, draw_table]
def get_breaking_teams(category, prefetch=(), rankings=('rank', )): """Returns a list of StandingInfo objects, one for each team, with one additional attribute populated: for each StandingInfo `tsi`, `tsi.break_rank` is the rank of the team out of those that are in the break. `prefetch` is passed to `prefetch_related()` in the Team query. `rankings` is passed to `rankings` in the TeamStandingsGenerator. """ teams = category.breaking_teams.all().prefetch_related(*prefetch) metrics = category.tournament.pref('team_standings_precedence') generator = TeamStandingsGenerator(metrics, rankings) standings = generator.generate(teams) breakingteams_by_team_id = { bt.team_id: bt for bt in category.breakingteam_set.all() } for tsi in standings: bt = breakingteams_by_team_id[tsi.team.id] if bt.break_rank is None: if bt.remark: tsi.break_rank = "(" + bt.get_remark_display().lower() + ")" else: tsi.break_rank = "<no rank, no remark>" else: tsi.break_rank = bt.break_rank return standings
def retrieve_standings(self): """Retrieves standings and places them in `self.standings`.""" metrics = self.category.tournament.pref('team_standings_precedence') self.check_required_metrics(metrics) generator = TeamStandingsGenerator(metrics, self.rankings) generated = generator.generate(self.team_queryset) self.standings = list(generated)
def get_standard_table(self): r = self.round if r.is_break_round: sort_key = "room-rank" sort_order = 'asc' else: sort_key = "bracket" sort_order = 'desc' table = AdminDrawTableBuilder(view=self, sort_key=sort_key, sort_order=sort_order, empty_title=_("No debates in this round")) draw = self.get_draw() populate_history(draw) if r.is_break_round: table.add_room_rank_columns(draw) else: table.add_debate_bracket_columns(draw) table.add_debate_venue_columns(draw, for_admin=True) table.add_debate_team_columns(draw) # For draw details and draw draft pages if (r.draw_status == Round.STATUS_DRAFT or self.detailed) and r.prev: teams = Team.objects.filter(debateteam__debate__round=r) metrics = self.tournament.pref('team_standings_precedence') if self.tournament.pref('teams_in_debate') == 'two': pullup_metric = PowerPairedDrawGenerator.PULLUP_RESTRICTION_METRICS[self.tournament.pref('draw_pullup_restriction')] else: pullup_metric = None # subrank only makes sense if there's a second metric to rank on rankings = ('rank', 'subrank') if len(metrics) > 1 else ('rank',) generator = TeamStandingsGenerator(metrics, rankings, extra_metrics=(pullup_metric,) if pullup_metric and pullup_metric not in metrics else ()) standings = generator.generate(teams, round=r.prev) if not r.is_break_round: table.add_debate_ranking_columns(draw, standings) else: self._add_break_rank_columns(table, draw, r.break_category) table.add_debate_metric_columns(draw, standings) table.add_debate_side_history_columns(draw, r.prev) elif not (r.draw_status == Round.STATUS_DRAFT or self.detailed): table.add_debate_adjudicators_column(draw, show_splits=False, for_admin=True) table.add_draw_conflicts_columns(draw, self.venue_conflicts, self.adjudicator_conflicts) if not r.is_break_round: table.highlight_rows_by_column_value(column=0) # highlight first row of a new bracket return table
def get_bp_position_balance_table(self): draw = self.get_draw() teams = Team.objects.filter(debateteam__debate__round=self.round) side_histories_before = get_side_history(teams, self.tournament.sides, self.round.prev.seq) side_histories_now = get_side_history(teams, self.tournament.sides, self.round.seq) generator = TeamStandingsGenerator(('points',), ()) standings = generator.generate(teams, round=self.round.prev) draw_table = PositionBalanceReportDrawTableBuilder(view=self) draw_table.build(draw, teams, side_histories_before, side_histories_now, standings) self.highlighted_cells_exist = any(draw_table.get_imbalance_category(team) is not None for team in teams) return draw_table
def get_teams(self): metrics = self.round.tournament.pref('team_standings_precedence') generator = TeamStandingsGenerator(metrics, ('rank', 'subrank'), tiebreak="random") standings = generator.generate(super().get_teams(), round=self.round.prev) ranked = [] for standing in standings: team = standing.team team.points = next(standing.itermetrics()) ranked.append(team) return ranked
def get_standard_table(self): r = self.get_round() if r.is_break_round: sort_key = _("Room rank") sort_order = 'asc' else: sort_key = _("Bracket") sort_order = 'desc' table = AdminDrawTableBuilder( view=self, sort_key=sort_key, sort_order=sort_order, empty_title=_("No Debates for this Round")) draw = self.get_draw() populate_history(draw) if r.is_break_round: table.add_room_rank_columns(draw) else: table.add_debate_bracket_columns(draw) table.add_debate_venue_columns(draw, for_admin=True) table.add_debate_team_columns(draw) # For draw details and draw draft pages if (r.draw_status == Round.STATUS_DRAFT or self.detailed) and r.prev: teams = Team.objects.filter(debateteam__debate__round=r) metrics = self.get_tournament().pref('team_standings_precedence') generator = TeamStandingsGenerator(metrics, ('rank', 'subrank')) standings = generator.generate(teams, round=r.prev) if not r.is_break_round: table.add_debate_ranking_columns(draw, standings) else: self._add_break_rank_columns(table, draw, r.break_category) table.add_debate_metric_columns(draw, standings) table.add_debate_side_history_columns(draw, r.prev) elif not (r.draw_status == Round.STATUS_DRAFT or self.detailed): table.add_debate_adjudicators_column(draw, show_splits=False) table.add_draw_conflicts_columns(draw, self.venue_conflicts, self.adjudicator_conflicts) if not r.is_break_round: table.highlight_rows_by_column_value( column=0) # highlight first row of a new bracket return table
def get_table(self): r = self.get_round() tournament = self.get_tournament() table = TabbycatTableBuilder(view=self) if r.draw_status == r.STATUS_NONE: return table # Return Blank draw = r.debate_set_with_prefetches(ordering=('room_rank', ), institutions=True, venues=True) populate_history(draw) if r.is_break_round: table.add_room_rank_columns(draw) else: table.add_debate_bracket_columns(draw) table.add_debate_venue_columns(draw, for_admin=True) table.add_team_columns([d.aff_team for d in draw], key=aff_name(tournament).capitalize(), hide_institution=True) table.add_team_columns([d.neg_team for d in draw], key=neg_name(tournament).capitalize(), hide_institution=True) # For draw details and draw draft pages if (r.draw_status == r.STATUS_DRAFT or self.detailed) and r.prev: teams = Team.objects.filter(debateteam__debate__round=r) metrics = r.tournament.pref('team_standings_precedence') generator = TeamStandingsGenerator(metrics, ('rank', 'subrank')) standings = generator.generate(teams, round=r.prev) if not r.is_break_round: table.add_debate_ranking_columns(draw, standings) else: self._add_break_rank_columns(table, draw, r.break_category) table.add_debate_metric_columns(draw, standings) table.add_sides_count([d.aff_team for d in draw], r.prev, 'aff') table.add_sides_count([d.neg_team for d in draw], r.prev, 'neg') else: table.add_debate_adjudicators_column(draw, show_splits=False) table.add_draw_conflicts_columns(draw) if not r.is_break_round: table.highlight_rows_by_column_value( column=0) # highlight first row of a new bracket return table
def get_teams(self): """Get teams in ranked order.""" teams = super().get_teams() if self.round.tournament.pref( 'draw_pullup_restriction') == 'least_to_date': annotate_npullups(teams, self.round.prev) metrics = self.round.tournament.pref('team_standings_precedence') generator = TeamStandingsGenerator(metrics, ('rank', 'subrank'), tiebreak="random") standings = generator.generate(teams, round=self.round.prev) ranked = [] for standing in standings: team = standing.team team.points = next(standing.itermetrics()) ranked.append(team) return ranked
def get_teams(self): """Get teams in ranked order.""" teams = super().get_teams() metrics = self.round.tournament.pref('team_standings_precedence') pullup_metric = PowerPairedDrawGenerator.PULLUP_RESTRICTION_METRICS[self.round.tournament.pref('draw_pullup_restriction')] generator = TeamStandingsGenerator(metrics, ('rank', 'subrank'), tiebreak="random", extra_metrics=(pullup_metric,) if pullup_metric and pullup_metric not in metrics else ()) standings = generator.generate(teams, round=self.round.prev) ranked = [] for standing in standings: team = standing.team team.points = next(standing.itermetrics(), 0) or 0 if pullup_metric: setattr(team, pullup_metric, standing.metrics[pullup_metric]) ranked.append(team) return ranked