def _check_if_final_blocked(self):
     # Get ranking of previous round
     prev_round = SchenkelRound.objects.get_prev(self.round)
     prev_ranking = prev_round.get_ranking()
     # Filter teams in group
     teams_list = self.teams_list
     prev_ranking = [rank for rank in prev_ranking if rank.team in teams_list]
     # Compute the potential new ranking
     # (worst result for team #1, team #2 and best for team #3)
     new_results = [TeamResult(team=prev_ranking[0].team, points=1),
                    TeamResult(team=prev_ranking[1].team, points=1),
                    TeamResult(team=prev_ranking[2].team, points=2, ends=8, stones=64)]
     new_ranking = compute_ranking(add_results_to_ranking(prev_ranking[:3], new_results))
     # If team #3 win, final can't be blocked
     self.final_blocked = not new_ranking[0].team == prev_ranking[2].team
     self.save()
     return self.final_blocked
 def _check_if_final_blocked(self):
     # Get ranking of previous round
     prev_round = SchenkelRound.objects.get_prev(self.round)
     prev_ranking = prev_round.get_ranking()
     # Filter teams in group
     teams_list = self.teams_list
     prev_ranking = [
         rank for rank in prev_ranking if rank.team in teams_list
     ]
     # Compute the potential new ranking
     # (worst result for team #1, team #2 and best for team #3)
     new_results = [
         TeamResult(team=prev_ranking[0].team, points=1),
         TeamResult(team=prev_ranking[1].team, points=1),
         TeamResult(team=prev_ranking[2].team, points=2, ends=8, stones=64)
     ]
     new_ranking = compute_ranking(
         add_results_to_ranking(prev_ranking[:3], new_results))
     # If team #3 win, final can't be blocked
     self.final_blocked = not new_ranking[0].team == prev_ranking[2].team
     self.save()
     return self.final_blocked
 def compute_ranking_for_group(self, group):
     if not group.finished:
         return []
     # --
     # Round type : Group or Ranking (or Final with final not blocked)
     # --
     if self.type == 'G' or self.type == 'R' or not self.final_is_blocked:
         # Get results for the group
         results = group.get_results()
         # Get old ranking if exists
         # and compute new global results
         if self.order > 1:
             # Type 'Group'
             if self.type == 'G':
                 # Get only results of the group for previous round
                 prev_group = SchenkelGroup.objects.get_prev_round(group)
                 prev_ranking_db = prev_group.get_ranking()
             # Type 'Ranking'
             else:
                 # Get all results of all groups for the previous round
                 prev_round = SchenkelRound.objects.get_prev(self)
                 prev_ranking_db = prev_round.get_ranking()
             # Compute new results
             new_results = add_results_to_ranking(
                 convert_ranking_db_to_team_results(prev_ranking_db),
                 results)
         else:
             new_results = results
         # Compute new ranking
         new_ranking = compute_ranking(new_results)
         # Create GoupRanking objects
         new_ranking_objs = []
         for rank in new_ranking:
             obj = SchenkelGroupRanking.objects.create(
                 group=group,
                 team=rank.team,
                 rank=rank.rank,
                 ex_aequo=rank.ex_aequo,
                 points=rank.points,
                 ends=rank.ends,
                 stones=rank.stones,
                 ends_received=rank.ends_received,
                 stones_received=rank.stones_received)
             new_ranking_objs.append(obj)
         # Try to prepare matches of next round
         if self.type != 'F':
             next_round_group = SchenkelGroup.objects.get_next_round(group)
             if next_round_group:
                 next_round_group.populate_matches()
         return new_ranking_objs
     # --
     # Round type : Final (with fianl blocked)
     # --
     elif self.type == 'F':
         # --
         # Only 2 first teams can win the tournament:
         # --
         # Get all results of all groups for the previous round
         prev_round = SchenkelRound.objects.get_prev(self)
         prev_ranking = convert_ranking_db_to_team_results(
             prev_round.get_ranking())
         # Get 2 first teams before compute new ranking
         finalists_prev_ranking = [prev_ranking[0], prev_ranking[1]]
         prev_ranking.remove(finalists_prev_ranking[0])
         prev_ranking.remove(finalists_prev_ranking[1])
         finalists_teams = [
             finalist.team for finalist in finalists_prev_ranking
         ]
         finalists_results = []
         # Get results of group
         results = group.get_results()
         # Get results of 2 first teams
         for result in results:
             if result.team in finalists_teams:
                 finalists_results.append(result)
         # Remove those results of the global list
         for result in finalists_results:
             results.remove(result)
         # Get winner and looser fo final match
         if finalists_results[0].points > finalists_results[1].points:
             winner = finalists_results[0].team
         elif finalists_results[0].points < finalists_results[1].points:
             winner = finalists_results[1].team
         else:
             winner = None
             raise NotImplementedError
         # Compute "normal" ranking for other team
         new_results = add_results_to_ranking(prev_ranking, results)
         new_tmp_ranking = compute_ranking(new_results, first_rank=3)
         # Compute new results for finalists
         finalists_new_results = add_results_to_ranking(
             finalists_prev_ranking, finalists_results)
         # Add the 2 finalist at the begining of the ranking (winner in 1st, looser in 2nd)
         finalists_results[0].ex_aequo = finalists_results[
             1].ex_aequo = False
         if finalists_results[0].team == winner:
             finalists_new_results[1].rank = 2
             new_tmp_ranking.insert(0, finalists_new_results[1])
             finalists_new_results[0].rank = 1
             new_tmp_ranking.insert(0, finalists_new_results[0])
         else:
             finalists_results[0].rank = 2
             new_tmp_ranking.insert(0, finalists_new_results[0])
             finalists_results[1].rank = 1
             new_tmp_ranking.insert(0, finalists_new_results[1])
         # Create Ranking in db
         new_ranking_objs = []
         for rank in new_tmp_ranking:
             obj = SchenkelGroupRanking.objects.create(
                 group=group,
                 team=rank.team,
                 rank=rank.rank,
                 ex_aequo=rank.ex_aequo,
                 points=rank.points,
                 ends=rank.ends,
                 stones=rank.stones,
                 ends_received=rank.ends_received,
                 stones_received=rank.stones_received)
             new_ranking_objs.append(obj)
         return new_ranking_objs
     else:
         raise ValueError()
 def compute_ranking_for_group(self, group):
     if not group.finished:
         return []
     # --
     # Round type : Group or Ranking (or Final with final not blocked)
     # --
     if self.type == 'G' or self.type == 'R' or not self.final_is_blocked:
         # Get results for the group
         results = group.get_results()
         # Get old ranking if exists
         # and compute new global results
         if self.order > 1:
             # Type 'Group'
             if self.type == 'G':
                 # Get only results of the group for previous round
                 prev_group = SchenkelGroup.objects.get_prev_round(group)
                 prev_ranking_db = prev_group.get_ranking()
             # Type 'Ranking'
             else:
                 # Get all results of all groups for the previous round
                 prev_round = SchenkelRound.objects.get_prev(self)
                 prev_ranking_db = prev_round.get_ranking()
             # Compute new results
             new_results = add_results_to_ranking(convert_ranking_db_to_team_results(prev_ranking_db), results)
         else:
             new_results = results
         # Compute new ranking
         new_ranking = compute_ranking(new_results)
         # Create GoupRanking objects
         new_ranking_objs = []
         for rank in new_ranking:
             obj = SchenkelGroupRanking.objects.create(group=group, team=rank.team,
                                                       rank=rank.rank, ex_aequo=rank.ex_aequo,
                                                       points=rank.points, ends=rank.ends, stones=rank.stones,
                                                       ends_received=rank.ends_received, stones_received=rank.stones_received)
             new_ranking_objs.append(obj)
         # Try to prepare matches of next round
         if self.type != 'F':
             next_round_group = SchenkelGroup.objects.get_next_round(group)
             if next_round_group:
                 next_round_group.populate_matches()
         return new_ranking_objs
     # --
     # Round type : Final (with fianl blocked)
     # --
     elif self.type == 'F':
         # --
         # Only 2 first teams can win the tournament:
         # --
         # Get all results of all groups for the previous round
         prev_round = SchenkelRound.objects.get_prev(self)
         prev_ranking = convert_ranking_db_to_team_results(prev_round.get_ranking())
         # Get 2 first teams before compute new ranking
         finalists_prev_ranking = [prev_ranking[0], prev_ranking[1]]
         prev_ranking.remove(finalists_prev_ranking[0])
         prev_ranking.remove(finalists_prev_ranking[1])
         finalists_teams = [finalist.team for finalist in finalists_prev_ranking]
         finalists_results = []
         # Get results of group
         results = group.get_results()
         # Get results of 2 first teams
         for result in results:
             if result.team in finalists_teams:
                 finalists_results.append(result)
         # Remove those results of the global list
         for result in finalists_results:
             results.remove(result)
         # Get winner and looser fo final match
         if finalists_results[0].points > finalists_results[1].points:
             winner = finalists_results[0].team
         elif finalists_results[0].points < finalists_results[1].points:
             winner = finalists_results[1].team
         else:
             winner = None
             raise NotImplementedError
         # Compute "normal" ranking for other team
         new_results = add_results_to_ranking(prev_ranking, results)
         new_tmp_ranking = compute_ranking(new_results, first_rank=3)
         # Compute new results for finalists
         finalists_new_results = add_results_to_ranking(finalists_prev_ranking, finalists_results)
         # Add the 2 finalist at the begining of the ranking (winner in 1st, looser in 2nd)
         finalists_results[0].ex_aequo = finalists_results[1].ex_aequo = False
         if finalists_results[0].team == winner:
             finalists_new_results[1].rank = 2
             new_tmp_ranking.insert(0, finalists_new_results[1])
             finalists_new_results[0].rank = 1
             new_tmp_ranking.insert(0, finalists_new_results[0])
         else:
             finalists_results[0].rank = 2
             new_tmp_ranking.insert(0, finalists_new_results[0])
             finalists_results[1].rank = 1
             new_tmp_ranking.insert(0, finalists_new_results[1])
         # Create Ranking in db
         new_ranking_objs = []
         for rank in new_tmp_ranking:
             obj = SchenkelGroupRanking.objects.create(group=group, team=rank.team,
                                                       rank=rank.rank, ex_aequo=rank.ex_aequo,
                                                       points=rank.points, ends=rank.ends, stones=rank.stones,
                                                       ends_received=rank.ends_received, stones_received=rank.stones_received)
             new_ranking_objs.append(obj)
         return new_ranking_objs
     else:
         raise ValueError()