def add_speaker_scores_column(self, teamscores): data = [{ 'text': ", ".join([metricformat(ss.score) for ss in ts.debate_team.speaker_scores]) or "—", 'tooltip': "<br>".join(["%s for %s" % (metricformat(ss.score), ss.speaker) for ss in ts.debate_team.speaker_scores]), } for ts in teamscores] header = {'key': 'speaks', 'tooltip': _("Speaker scores<br>(in speaking order)"), 'text': _("Speaks")} self.add_column(header, data)
def _show_score(self, ts, cell): score = ts.score if self.tournament.integer_scores(ts.debate_team.debate.round.stage) and score.is_integer(): score = int(ts.score) cell['subtext'] = metricformat(score) cell['popover']['content'].append( {'text': _("Total speaker score: <strong>%s</strong>") % metricformat(score)})
def add_speaker_scores_column(self, teamscores): data = [{ 'text': ", ".join([metricformat(ss.score) for ss in ts.debate_team.speaker_scores]) or "—", 'tooltip': "<br>".join(["%s for %s" % (metricformat(ss.score), ss.speaker) for ss in ts.debate_team.speaker_scores]), } for ts in teamscores] header = {'key': 'speaks', 'tooltip': _("Speaker scores<br>(in speaking order)"), 'text': _("Speaks")} self.add_column(header, data)
def _result_cell_bp(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team'): return {'text': self.BLANK_TEXT} other_teams = {dt.side: dt.team.short_name for dt in ts.debate_team.debate.debateteam_set.all()} other_team_strs = [_("Teams in debate:")] for side in self.tournament.sides: if ts.debate_team.debate.sides_confirmed: line = _("%(team)s (%(side)s)") % { 'team': other_teams.get(side, "??"), 'side': get_side_name(self.tournament, side, 'abbr') } else: line = other_teams.get(side, "??") if side == ts.debate_team.side: line = "<strong>" + line + "</strong>" other_team_strs.append(line) cell = {'popover': { 'content': [{'text': "<br />".join(other_team_strs)}], 'title': "" }} if ts.debate_team.debate.round.is_break_round: cell = self._result_cell_class_four_elim(ts.win, cell) if ts.win is True: cell['text'] = _("advancing") cell['popover']['title'] = _("Advancing") elif ts.win is False: cell['text'] = _("eliminated") cell['popover']['title'] = _("Eliminated") else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") else: cell = self._result_cell_class_four(ts.points, cell) places = {0: _("4th"), 1: _("3rd"), 2: _("2nd"), 3: _("1st")} if ts.points is not None: place = places.get(ts.points, "??") cell['text'] = place cell['popover']['title'] = _("Took %(place)s") % {'place': place} else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") if show_score and ts.score is not None: cell['subtext'] = metricformat(ts.score) cell['popover']['content'].append( {'text': _("Received <strong>%s</strong> team points") % metricformat(ts.score)}) if show_ballots: cell['popover']['content'].append( {'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate.id})}) return cell
def _result_cell_two(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team') or not hasattr(ts.debate_team.opponent, 'team'): return {'text': self.BLANK_TEXT} opp = ts.debate_team.opponent.team opp_vshort = '<i class="emoji">' + opp.emoji + '</i>' if opp.emoji else "…" cell = { 'text': _(" vs %(opposition)s") % {'opposition': opp_vshort if compress else self._team_short_name(opp)}, 'popover': {'content': [], 'title': ''}, 'class': "no-wrap", } cell = self._result_cell_class_two(ts.win, cell) if ts.win is True: cell['popover']['title'] = _("Won against %(team)s") % {'team': self._team_long_name(opp)} elif ts.win is False: cell['popover']['title'] = _("Lost to %(team)s") % {'team': self._team_long_name(opp)} else: # None cell['popover']['title'] = _("No result for debate against %(team)s") % {'team': self._team_long_name(opp)} if show_score and ts.score is not None: score = ts.score if self.tournament.integer_scores(ts.debate_team.debate.round.stage) and score.is_integer(): score = int(ts.score) cell['subtext'] = metricformat(score) cell['popover']['content'].append( {'text': _("Total speaker score: <strong>%s</strong>") % metricformat(score)}) if show_ballots: if self.admin: cell['popover']['content'].append({ 'text': _("View/edit debate ballot"), 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': ts.ballot_submission_id}) }) elif self.tournament.pref('ballots_released'): cell['popover']['content'].append({ 'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate_id}) }) if self._show_speakers_in_draw: cell['popover']['content'].append({ 'text': ", ".join([s.name for s in opp.speakers]) }) if self._show_record_links: cell['popover']['content'].append( self._team_record_link(opp)) return cell
def add_all_columns_for_team(self, side): teams = [debate.get_team(side) for debate in self.debates] side_abbr = get_side_name(self.tournament, side, 'abbr') self.add_team_columns(teams, key=side_abbr, show_emoji=False) # Highlight the team column for row in self.data: row[-1]['class'] = 'highlight-col' # Points of team metric_info = next(self.standings.metrics_info()) header = { 'key': "pts" + side_abbr, # always use 'pts' to make it more predictable 'tooltip': _("%(team)s: %(metric)s") % { 'team': side_abbr, 'metric': metric_info['name'] }, 'icon': 'star' } infos = self.standings.get_standings(teams) self.add_column( header, [metricformat(info.metrics[metric_info['key']]) for info in infos]) # Side history after last round header = self._prepend_side_header(side, _("side history before this round"), _("Sides"), text_only=True) cells = self._side_history_by_team(self.side_histories_before, teams) self.add_column(header, cells) # Position cost incurred, post-weighting header = self._prepend_side_header(side, _("position cost"), _("Cost"), text_only=True) pos = self.tournament.sides.index(side) cells = [ metricformat(self.get_position_cost(pos, team)) for team in teams ] self.add_column(header, cells) # Highlight according to category for row, team in zip(self.data, teams): category = self.get_imbalance_category(team) if category is None: continue for cell in row[-4:]: cell['class'] = cell.get('class', '') + ' table-' + category[0]
def add_metric_columns(self, standings, integer_score_columns=[]): """`integer_score_columns`, if given, indicates which metrics to cast to an int if the metric's value is an integer. For example, if the tournament preferences are such that the total speaker score should always be an integer, a list containing the string 'total' or 'speaks_sum' should be passed in via this argument.""" headers = self._standings_headers(standings.metrics_info()) data = [] for standing in standings: row = [] for key, metric in zip(standings.metric_keys, standing.itermetrics()): if metric is None: row.append({'text': '—', 'sort': 0}) continue if key in integer_score_columns and hasattr(metric, 'is_integer') and metric.is_integer(): metric = int(metric) try: sort = float(metric) except (TypeError, ValueError): sort = 99999 row.append({'text': metricformat(metric), 'sort': sort}) data.append(row) self.add_columns(headers, data)
def add_permitted_points_column(self): first_metric = self.standings.metric_keys[0] points = [info.metrics[first_metric] for info in self.standings] points.sort(reverse=True) pref = self.tournament.pref('bp_pullup_distribution') define_rooms_func = getattr( BPHungarianDrawGenerator, BPHungarianDrawGenerator.DEFINE_ROOM_FUNCTIONS[pref]) rooms = define_rooms_func(points) data = [sorted(allowed, reverse=True) for level, allowed in rooms] cells = [] for datum in data: strs = [metricformat(x) for x in datum] strs[0] = "<strong>%s</strong>" % strs[0] cells.append(", ".join(strs)) header = { 'key': "room", 'icon': "bar-chart", 'tooltip': _("Teams with this many points are permitted in this debate<br>\n(bracket in bold)" ), } self.add_column(header, cells)
def _result_cell(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team') or not hasattr(ts.debate_team.opponent, 'team'): return {'text': '-'} opp = ts.debate_team.opponent.team opp_vshort = '<i class="emoji">' + opp.emoji + '</i>' if opp.emoji else "…" cell = { 'text': " vs " + (opp_vshort if compress else opp.short_name), 'popover': {'content': [{'text': ''}], 'title': ''} } if ts.win is True: cell['icon'] = "glyphicon-arrow-up text-success" cell['sort'] = 1 cell['popover']['title'] = "Won against " + opp.long_name elif ts.win is False: cell['icon'] = "glyphicon-arrow-down text-danger" cell['sort'] = 2 cell['popover']['title'] = "Lost to " + opp.long_name else: # None cell['icon'] = "" cell['sort'] = 3 cell['popover']['title'] = "No result for debate against " + opp.long_name if show_score: cell['subtext'] = metricformat(ts.score) cell['popover']['content'].append( {'text': 'Received <strong>%s</strong> team points' % metricformat(ts.score)}) if show_ballots: cell['popover']['content'].append( {'text': 'View Debate Ballot', 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate.id})}) if self._show_speakers_in_draw: cell['popover']['content'].append({'text': "Speakers in <strong>" + opp.short_name + "</strong>: " + ", ".join([s.name for s in opp.speakers])}) if self._show_record_links: cell['popover']['content'].append( self._team_record_link(opp)) return cell
def add_metric_columns(self, standings): headers = self._standings_headers(standings.metrics_info()) data = [] for standing in standings: row = [] for metric in standing.itermetrics(): try: sort = float(metric) except (TypeError, ValueError): sort = 99999 row.append({'text': metricformat(metric), 'sort': sort}) data.append(row) self.add_columns(headers, data)
def _result_cell_two(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team') or not hasattr(ts.debate_team.opponent, 'team'): return {'text': self.BLANK_TEXT} opp = ts.debate_team.opponent.team opp_vshort = '<i class="emoji">' + opp.emoji + '</i>' if opp.emoji else "…" cell = { 'text': _(" vs %(opposition)s") % {'opposition': opp_vshort if compress else opp.short_name}, 'popover': {'content': [], 'title': ''} } cell = self._result_cell_class_two(ts.win, cell) if ts.win is True: cell['popover']['title'] = _("Won against %(team)s") % {'team': opp.long_name} elif ts.win is False: cell['popover']['title'] = _("Lost to %(team)s") % {'team': opp.long_name} else: # None cell['popover']['title'] = _("No result for debate against %(team)s") % {'team': opp.long_name} if show_score: cell['subtext'] = metricformat(ts.score) cell['popover']['content'].append( {'text': _("Received <strong>%s</strong> team points") % metricformat(ts.score)}) if show_ballots: cell['popover']['content'].append( {'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate.id})}) if self._show_speakers_in_draw: cell['popover']['content'].append({'text': _("Speakers in <strong>%(opp)s</strong>: %(speakers)s") % { 'opp': opp.short_name, 'speakers': ", ".join([s.name for s in opp.speakers])}}) if self._show_record_links: cell['popover']['content'].append( self._team_record_link(opp)) return cell
def add_all_columns_for_team(self, side): teams = [debate.get_team(side) for debate in self.debates] side_abbr = get_side_name(self.tournament, side, 'abbr') self.add_team_columns(teams, key=side_abbr, show_emoji=False) # Highlight the team column for row in self.data: row[-1]['class'] = 'highlight-col' # Points of team metric_info = next(self.standings.metrics_info()) header = { 'key': "pts", # always use 'pts' to make it more predictable 'tooltip': _("%(team)s: %(metric)s") % {'team': side_abbr, 'metric': metric_info['name']}, 'icon': 'star' } infos = self.standings.get_standings(teams) self.add_column(header, [metricformat(info.metrics[metric_info['key']]) for info in infos]) # Side history after last round header = self._prepend_side_header(side, _("side history before this round"), _("Sides"), text_only=True) cells = self._side_history_by_team(self.side_histories_before, teams) self.add_column(header, cells) # Position cost incurred, post-weighting header = self._prepend_side_header(side, _("position cost"), _("Cost"), text_only=True) pos = self.tournament.sides.index(side) cells = [metricformat(self.get_position_cost(pos, team)) for team in teams] self.add_column(header, cells) # Highlight according to category for row, team in zip(self.data, teams): category = self.get_imbalance_category(team) if category is None: continue for cell in row[-4:]: cell['class'] = cell.get('class', '') + ' table-' + category[0]
def add_all_columns_for_team(self, side): teams = [debate.get_team(side) for debate in self.debates] side_abbr = get_side_name(self.tournament, side, 'abbr') self.add_team_columns(teams, key=side_abbr, hide_emoji=True) # Highlight the team column for row in self.data: row[-1]['class'] = 'highlight-col' # Points of team infos = self.standings.get_standings(teams) header = { 'key': _("Pts"), 'tooltip': side_abbr + " " + _("Points"), 'icon': 'star' } self.add_column(header, [info.metrics['points'] for info in infos]) # Side history after last round header = self._prepend_side_header(side, _("side history before this round"), _("Sides"), text_only=True) cells = self._side_history_by_team(self.side_histories_before, teams) self.add_column(header, cells) # Position cost incurred, post-weighting header = self._prepend_side_header(side, _("position cost"), _("Cost"), text_only=True) pos = self.tournament.sides.index(side) cells = [ metricformat(self.get_position_cost(pos, team)) for team in teams ] self.add_column(header, cells) # Highlight according to category for row, team in zip(self.data, teams): category = self.get_imbalance_category(team) if category is None: continue for cell in row[-4:]: cell['class'] = cell.get('class', '') + ' table-' + category[0]
def add_permitted_points_column(self): first_metric = self.standings.metric_keys[0] points = [info.metrics[first_metric] for info in self.standings] points.sort(reverse=True) pref = self.tournament.pref('bp_pullup_distribution') define_rooms_func = getattr(BPHungarianDrawGenerator, BPHungarianDrawGenerator.DEFINE_ROOM_FUNCTIONS[pref]) rooms = define_rooms_func(points) data = [sorted(allowed, reverse=True) for level, allowed in rooms] cells = [] for datum in data: strs = [metricformat(x) for x in datum] strs[0] = "<strong>%s</strong>" % strs[0] cells.append(", ".join(strs)) header = { 'key': "room", 'icon': "bar-chart", 'tooltip': _("Teams with this many points are permitted in this debate<br>\n(bracket in bold)"), } self.add_column(header, cells)
def add_metric_columns(self, standings, integer_score_columns=[]): """`integer_score_columns`, if given, indicates which metrics to cast to an int if the metric's value is an integer. For example, if the tournament preferences are such that the total speaker score should always be an integer, a list containing the string 'total' or 'speaks_sum' should be passed in via this argument.""" headers = self._standings_headers(standings.metrics_info()) data = [] for standing in standings: row = [] for key, metric in zip(standings.metric_keys, standing.itermetrics()): if key in integer_score_columns and hasattr(metric, 'is_integer') and metric.is_integer(): metric = int(metric) try: sort = float(metric) except (TypeError, ValueError): sort = 99999 row.append({'text': metricformat(metric), 'sort': sort}) data.append(row) self.add_columns(headers, data)
def build(self, draw, teams, side_histories_before, side_histories_now, standings): self.side_histories_before = side_histories_before self.side_histories_now = side_histories_now self.standings = standings # Filter for just those teams that are "noteworthy" teams = [team for team in teams if self.get_imbalance_category(team) is not None] self.add_team_columns(teams) # First metric metric_info = next(self.standings.metrics_info()) header = { 'key': "pts", # always use 'pts' to make it more predictable 'title': force_text(metric_info['abbr']), 'tooltip': force_text(metric_info['name']), } infos = self.standings.get_standings(teams) cells = [] for info in infos: points = info.metrics[metric_info['key']] cells.append({ 'text': metricformat(points), 'sort': points, }) self.add_column(header, cells) # Sides sides_lookup = {dt.team_id: dt.side for debate in draw for dt in debate.debateteam_set.all()} sides = [sides_lookup[team.id] for team in teams] poses = [self.tournament.sides.index(side) for side in sides] # used later names = {side: get_side_name(self.tournament, side, 'abbr') for side in self.tournament.sides} header = {'key': "side", 'title': _("Side"), 'tooltip': _("Position this round")} self.add_column(header, [names[side] for side in sides]) # Side counts before and now header = {'key': "before", 'title': _("Before"), 'tooltip': _("Side history before this round")} cells = self._side_history_by_team(self.side_histories_before, teams) self.add_column(header, cells) header = {'key': "after", 'title': _("After"), 'tooltip': _("Side history after this round")} side_histories_now_highlighted = [] for team, pos in zip(teams, poses): history = [str(x) for x in self.side_histories_now[team.id]] history[pos] = "<strong>" + history[pos] + "</strong>" history_str = self.side_history_separator.join(history) side_histories_now_highlighted.append(history_str) self.add_column(header, side_histories_now_highlighted) # Position cost header = {'key': "cost", 'title': _("Cost"), 'tooltip': _("Position cost")} cells = [metricformat(self.get_position_cost(pos, team)) for pos, team in zip(poses, teams)] self.add_column(header, cells) # Status cells = [] for team in teams: style, category, sort = self.get_imbalance_category(team) cells.append({ 'text': self.STATUSES[category], 'sort': sort, 'class': 'text-' + style }) self.add_column({'key': 'status', 'title': _("Status")}, cells) # Sort by points as secondary sort (will be sorted by cost in Vue) self.data.sort(key=lambda x: x[1].get('sort', 0), reverse=True)
def _result_cell_bp(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team'): return {'text': self.BLANK_TEXT} other_teams = { dt.side: self._team_short_name(dt.team) for dt in ts.debate_team.debate.debateteam_set.all() } other_team_strs = [_("Teams in debate:")] for side in self.tournament.sides: if ts.debate_team.debate.sides_confirmed: line = _("%(team)s (%(side)s)") % { 'team': other_teams.get(side, _("??")), 'side': get_side_name(self.tournament, side, 'abbr'), } else: line = other_teams.get(side, _("??")) if side == ts.debate_team.side: line = "<strong>" + line + "</strong>" other_team_strs.append(line) cell = { 'popover': { 'content': [{ 'text': "<br />".join(other_team_strs) }], 'title': "", 'class': "no-wrap", } } if ts.debate_team.debate.round.is_break_round: cell = self._result_cell_class_four_elim(ts.win, cell) if ts.win is True: cell['text'] = _("advancing") cell['popover']['title'] = _("Advancing") elif ts.win is False: cell['text'] = _("eliminated") cell['popover']['title'] = _("Eliminated") else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") else: cell = self._result_cell_class_four(ts.points, cell) places = [ordinal(n) for n in reversed(range(1, 5))] if ts.points is not None: place = places[ts.points] if ts.points < 4 else _("??") cell['text'] = place cell['popover']['title'] = _("Placed %(place)s") % { 'place': place } else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") if show_score and ts.score is not None: score = ts.score if self.tournament.integer_scores( ts.debate_team.debate.round.stage) and score.is_integer(): score = int(ts.score) cell['subtext'] = metricformat(score) cell['popover']['content'].append({ 'text': _("Total speaker score: <strong>%s</strong>") % metricformat(score) }) if show_ballots: if self.admin: cell['popover']['content'].append({ 'text': _("View/edit debate ballot"), 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': ts.ballot_submission_id}), }) elif self.tournament.pref('ballots_released'): cell['popover']['content'].append({ 'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate_id}), }) return cell
def _result_cell_bp(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team'): return {'text': self.BLANK_TEXT} other_teams = {dt.side: self._team_short_name(dt.team) for dt in ts.debate_team.debate.debateteam_set.all()} other_team_strs = [_("Teams in debate:")] for side in self.tournament.sides: if ts.debate_team.debate.sides_confirmed: line = _("%(team)s (%(side)s)") % { 'team': other_teams.get(side, "??"), 'side': get_side_name(self.tournament, side, 'abbr') } else: line = other_teams.get(side, "??") if side == ts.debate_team.side: line = "<strong>" + line + "</strong>" other_team_strs.append(line) cell = {'popover': { 'content': [{'text': "<br />".join(other_team_strs)}], 'title': "", 'class': "no-wrap", }} if ts.debate_team.debate.round.is_break_round: cell = self._result_cell_class_four_elim(ts.win, cell) if ts.win is True: cell['text'] = _("advancing") cell['popover']['title'] = _("Advancing") elif ts.win is False: cell['text'] = _("eliminated") cell['popover']['title'] = _("Eliminated") else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") else: cell = self._result_cell_class_four(ts.points, cell) places = {0: _("4th"), 1: _("3rd"), 2: _("2nd"), 3: _("1st")} if ts.points is not None: place = places.get(ts.points, "??") cell['text'] = place cell['popover']['title'] = _("Placed %(place)s") % {'place': place} else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") if show_score and ts.score is not None: score = ts.score if self.tournament.integer_scores(ts.debate_team.debate.round.stage) and score.is_integer(): score = int(ts.score) cell['subtext'] = metricformat(score) cell['popover']['content'].append( {'text': _("Total speaker score: <strong>%s</strong>") % metricformat(score)}) if show_ballots: if self.admin: cell['popover']['content'].append({ 'text': _("View/edit debate ballot"), 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': ts.ballot_submission_id}) }) elif self.tournament.pref('ballots_released'): cell['popover']['content'].append({ 'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate_id}) }) return cell
def build(self, draw, teams, side_histories_before, side_histories_now, standings): self.side_histories_before = side_histories_before self.side_histories_now = side_histories_now self.standings = standings # Filter for just those teams that are "noteworthy" teams = [ team for team in teams if self.get_imbalance_category(team) is not None ] self.add_team_columns(teams) # Points infos = self.standings.get_standings(teams) header = {'key': _("Pts"), 'tooltip': _("Points")} self.add_column(header, [info.metrics['points'] for info in infos]) # Sides sides_lookup = { dt.team_id: dt.side for debate in draw for dt in debate.debateteam_set.all() } sides = [sides_lookup[team.id] for team in teams] poses = [self.tournament.sides.index(side) for side in sides] # used later names = { side: get_side_name(self.tournament, side, 'abbr') for side in self.tournament.sides } header = {'key': _("Side"), 'tooltip': _("Position this round")} self.add_column(header, [names[side] for side in sides]) # Side counts before and now header = { 'key': _("Before"), 'tooltip': _("Side history before this round") } cells = self._side_history_by_team(self.side_histories_before, teams) self.add_column(header, cells) header = { 'key': _("After"), 'tooltip': _("Side history after this round") } side_histories_now_highlighted = [] for team, pos in zip(teams, poses): history = [str(x) for x in self.side_histories_now[team.id]] history[pos] = "<strong>" + history[pos] + "</strong>" history_str = self.side_history_separator.join(history) side_histories_now_highlighted.append(history_str) self.add_column(header, side_histories_now_highlighted) # Position cost header = {'key': _("Cost"), 'tooltip': _("Position cost")} cells = [ metricformat(self.get_position_cost(pos, team)) for pos, team in zip(poses, teams) ] self.add_column(header, cells) # Status cells = [] for team in teams: style, category, sort = self.get_imbalance_category(team) cells.append({ 'text': self.STATUSES[category], 'sort': sort, 'class': 'text-' + style }) self.add_column(_("Status"), cells) # Sort by points as secondary sort (will be sorted by cost in Vue) self.data.sort(key=lambda x: x[1]['sort'], reverse=True)
def _result_cell(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team') or not hasattr( ts.debate_team.opponent, 'team'): return {'text': self.BLANK_TEXT} opp = ts.debate_team.opponent.team opp_vshort = '<i class="emoji">' + opp.emoji + '</i>' if opp.emoji else "…" cell = { 'text': " vs " + (opp_vshort if compress else opp.short_name), 'popover': { 'content': [{ 'text': '' }], 'title': '' } } if ts.win is True: cell['icon'] = "glyphicon-arrow-up text-success" cell['sort'] = 1 cell['popover']['title'] = "Won against " + opp.long_name elif ts.win is False: cell['icon'] = "glyphicon-arrow-down text-danger" cell['sort'] = 2 cell['popover']['title'] = "Lost to " + opp.long_name else: # None cell['icon'] = "" cell['sort'] = 3 cell['popover'][ 'title'] = "No result for debate against " + opp.long_name if show_score: cell['subtext'] = metricformat(ts.score) cell['popover']['content'].append({ 'text': 'Received <strong>%s</strong> team points' % metricformat(ts.score) }) if show_ballots: cell['popover']['content'].append({ 'text': 'View Debate Ballot', 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate.id}) }) if self._show_speakers_in_draw: cell['popover']['content'].append({ 'text': "Speakers in <strong>" + opp.short_name + "</strong>: " + ", ".join([s.name for s in opp.speakers]) }) if self._show_record_links: cell['popover']['content'].append(self._team_record_link(opp)) return cell
def build(self, draw, teams, side_histories_before, side_histories_now, standings): self.side_histories_before = side_histories_before self.side_histories_now = side_histories_now self.standings = standings # Filter for just those teams that are "noteworthy" teams = [ team for team in teams if self.get_imbalance_category(team) is not None ] self.add_team_columns(teams) # First metric if len(self.standings.metric_keys ) == 0: # special case: no metrics used header = { 'key': "pts", 'title': "?", 'tooltip': _("No metrics in the team standings precedence"), } self.add_column(header, [0] * len(teams)) else: metric_info = next(self.standings.metrics_info()) header = { 'key': "pts", # always use 'pts' to make it more predictable 'title': force_text(metric_info['abbr']), 'tooltip': force_text(metric_info['name']), } cells = [] infos = self.standings.get_standings(teams) for info in infos: points = info.metrics[metric_info['key']] cells.append({ 'text': metricformat(points), 'sort': points, }) self.add_column(header, cells) # Sides sides_lookup = { dt.team_id: dt.side for debate in draw for dt in debate.debateteam_set.all() } sides = [sides_lookup[team.id] for team in teams] poses = [self.tournament.sides.index(side) for side in sides] # used later names = { side: get_side_name(self.tournament, side, 'abbr') for side in self.tournament.sides } header = { 'key': "side", 'title': _("Side"), 'tooltip': _("Position this round") } self.add_column(header, [names[side] for side in sides]) # Side counts before and now header = { 'key': "before", 'title': _("Before"), 'tooltip': _("Side history before this round") } cells = self._side_history_by_team(self.side_histories_before, teams) self.add_column(header, cells) header = { 'key': "after", 'title': _("After"), 'tooltip': _("Side history after this round") } side_histories_now_highlighted = [] for team, pos in zip(teams, poses): history = [str(x) for x in self.side_histories_now[team.id]] history[pos] = "<strong>" + history[pos] + "</strong>" history_str = self.side_history_separator.join(history) side_histories_now_highlighted.append(history_str) self.add_column(header, side_histories_now_highlighted) # Position cost header = { 'key': "cost", 'title': _("Cost"), 'tooltip': _("Position cost") } cells = [ metricformat(self.get_position_cost(pos, team)) for pos, team in zip(poses, teams) ] self.add_column(header, cells) # Status cells = [] for team in teams: style, category, sort = self.get_imbalance_category(team) cells.append({ 'text': self.STATUSES[category], 'sort': sort, 'class': 'text-' + style, }) self.add_column({'key': 'status', 'title': _("Status")}, cells) # Sort by points as secondary sort (will be sorted by cost in Vue) self.data.sort(key=lambda x: x[1].get('sort', 0), reverse=True)