def get_breaking_teams(category, include_all=False, include_categories=False): """Returns a list of Teams, with additional attributes. For each Team t in the returned list: t.rank is the rank of the team, including ineligible teams. t.break_rank is the rank of the team out of those that are in the break. 'category' must be a BreakCategory instance. If 'include_all' is True: - Teams that would break but for the institution cap are included in the returned list, with t.break_rank set to the string "(capped)". - If category.is_general is True, then teams that would break but for being ineligible for this category are included in the returned list, but with t.break_rank set to the string "(ineligible)". Note that in no circumstances are teams that broke in a higher priority category included in the list of returned teams. If 'include_all' is False, the capped and ineligible teams are excluded, but t.rank is still the rank including those teams. If 'include_categories' is True, t.categories_for_display will be a comma- delimited list of category names that are not this category, and lower or equal priority to this category. """ teams = category.breaking_teams.all() if not include_all: teams = teams.filter(break_rank__isnull=False) teams = annotate_team_standings(teams, tournament=category.tournament) for team in teams: bt = team.breakingteam_set.get(break_category=category) team.rank = bt.rank if bt.break_rank is None: if bt.remark: team.break_rank = "(" + bt.get_remark_display().lower() + ")" else: team.break_rank = "<error>" else: team.break_rank = bt.break_rank if include_categories: categories = team.break_categories_nongeneral.exclude( id=category.id).exclude(priority__lt=category.priority) team.categories_for_display = "(" + ", ".join( c.name for c in categories) + ")" if categories else "" else: team.categories_for_display = "" return teams
def get_breaking_teams(category, include_all=False, include_categories=False): """Returns a list of Teams, with additional attributes. For each Team t in the returned list: t.rank is the rank of the team, including ineligible teams. t.break_rank is the rank of the team out of those that are in the break. 'category' must be a BreakCategory instance. If 'include_all' is True: - Teams that would break but for the institution cap are included in the returned list, with t.break_rank set to the string "(capped)". - If category.is_general is True, then teams that would break but for being ineligible for this category are included in the returned list, but with t.break_rank set to the string "(ineligible)". Note that in no circumstances are teams that broke in a higher priority category included in the list of returned teams. If 'include_all' is False, the capped and ineligible teams are excluded, but t.rank is still the rank including those teams. If 'include_categories' is True, t.categories_for_display will be a comma- delimited list of category names that are not this category, and lower or equal priority to this category. """ teams = category.breaking_teams.all() if not include_all: teams = teams.filter(break_rank__isnull=False) teams = annotate_team_standings(teams, tournament=category.tournament) for team in teams: bt = team.breakingteam_set.get(break_category=category) team.rank = bt.rank if bt.break_rank is None: if bt.remark: team.break_rank = "(" + bt.get_remark_display().lower() + ")" else: team.break_rank = "<error>" else: team.break_rank = bt.break_rank if include_categories: categories = team.break_categories_nongeneral.exclude(id=category.id).exclude(priority__lt=category.priority) team.categories_for_display = "(" + ", ".join(c.name for c in categories) + ")" if categories else "" else: team.categories_for_display = "" return teams
def _generate_breaking_teams(category, eligible_teams, teams_broken_higher_priority=set()): """Generates a list of breaking teams for the given category and returns a list of teams in the (actual) break, i.e. excluding teams that are ineligible, capped, broke in a different break, and so on.""" eligible_teams = annotate_team_standings(eligible_teams, tournament=category.tournament) break_size = category.break_size institution_cap = category.institution_cap prev_rank_value = (None, None) # (points, speaks) prev_break_rank_value = (None, None) cur_rank = 0 breaking_teams = list() breaking_teams_to_create = list() # Variables for institutional caps and non-breaking teams cur_break_rank = 0 # actual break rank cur_break_seq = 0 # sequential count of breaking teams teams_from_institution = Counter() for i, team in enumerate(eligible_teams, start=1): try: bt = BreakingTeam.objects.get(break_category=category, team=team) existing = True except BreakingTeam.DoesNotExist: bt = BreakingTeam(break_category=category, team=team) existing = False # Compute overall rank rank_value = (team.points, team.speaker_score) if rank_value != prev_rank_value: # if we have enough teams, we're done if len(breaking_teams) >= break_size: break cur_rank = i prev_rank_value = rank_value bt.rank = cur_rank # If there is an existing remark, scrub the break rank and skip if existing and bt.remark: bt.break_rank = None # Check if ineligible elif not team.break_categories.filter(pk=category.pk).exists(): bt.remark = bt.REMARK_INELIGIBLE # Check if capped out by institution cap elif institution_cap > 0 and teams_from_institution[team.institution] >= institution_cap: bt.remark = bt.REMARK_CAPPED # Check if already broken to a higher category elif team in teams_broken_higher_priority: bt.remark = bt.REMARK_DIFFERENT_BREAK # If neither, this team is in the break else: # Compute break rank cur_break_seq += 1 if rank_value != prev_break_rank_value: cur_break_rank = cur_break_seq prev_break_rank_value = rank_value bt.break_rank = cur_break_rank breaking_teams.append(team) bt.full_clean() if existing: bt.save() else: breaking_teams_to_create.append(bt) # Take note of the institution teams_from_institution[team.institution] += 1 BreakingTeam.objects.bulk_create(breaking_teams_to_create) BreakingTeam.objects.filter(break_category=category, break_rank__isnull=False).exclude( team_id__in=[t.id for t in breaking_teams]).delete() return breaking_teams
def _generate_breaking_teams(category, eligible_teams, teams_broken_higher_priority=set()): """Generates a list of breaking teams for the given category and returns a list of teams in the (actual) break, i.e. excluding teams that are ineligible, capped, broke in a different break, and so on.""" eligible_teams = annotate_team_standings(eligible_teams, tournament=category.tournament) break_size = category.break_size institution_cap = category.institution_cap prev_rank_value = (None, None) # (points, speaks) prev_break_rank_value = (None, None) cur_rank = 0 breaking_teams = list() breaking_teams_to_create = list() # Variables for institutional caps and non-breaking teams cur_break_rank = 0 # actual break rank cur_break_seq = 0 # sequential count of breaking teams teams_from_institution = Counter() for i, team in enumerate(eligible_teams, start=1): try: bt = BreakingTeam.objects.get(break_category=category, team=team) existing = True except BreakingTeam.DoesNotExist: bt = BreakingTeam(break_category=category, team=team) existing = False # Compute overall rank rank_value = (team.points, team.speaker_score) if rank_value != prev_rank_value: # if we have enough teams, we're done if len(breaking_teams) >= break_size: break cur_rank = i prev_rank_value = rank_value bt.rank = cur_rank # If there is an existing remark, scrub the break rank and skip if existing and bt.remark: bt.break_rank = None # Check if ineligible elif not team.break_categories.filter(pk=category.pk).exists(): bt.remark = bt.REMARK_INELIGIBLE # Check if capped out by institution cap elif institution_cap > 0 and teams_from_institution[ team.institution] >= institution_cap: bt.remark = bt.REMARK_CAPPED # Check if already broken to a higher category elif team in teams_broken_higher_priority: bt.remark = bt.REMARK_DIFFERENT_BREAK # If neither, this team is in the break else: # Compute break rank cur_break_seq += 1 if rank_value != prev_break_rank_value: cur_break_rank = cur_break_seq prev_break_rank_value = rank_value bt.break_rank = cur_break_rank breaking_teams.append(team) bt.full_clean() if existing: bt.save() else: breaking_teams_to_create.append(bt) # Take note of the institution teams_from_institution[team.institution] += 1 BreakingTeam.objects.bulk_create(breaking_teams_to_create) BreakingTeam.objects.filter( break_category=category, break_rank__isnull=False).exclude( team_id__in=[t.id for t in breaking_teams]).delete() return breaking_teams