Coverage for bundesliga_tippspiel/utils/collections/LeagueTable.py: 10%

Shortcuts on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

56 statements  

1"""LICENSE 

2Copyright 2017 Hermann Krumrey <hermann@krumreyh.com> 

3 

4This file is part of bundesliga-tippspiel. 

5 

6bundesliga-tippspiel is free software: you can redistribute it and/or modify 

7it under the terms of the GNU General Public License as published by 

8the Free Software Foundation, either version 3 of the License, or 

9(at your option) any later version. 

10 

11bundesliga-tippspiel is distributed in the hope that it will be useful, 

12but WITHOUT ANY WARRANTY; without even the implied warranty of 

13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

14GNU General Public License for more details. 

15 

16You should have received a copy of the GNU General Public License 

17along with bundesliga-tippspiel. If not, see <http://www.gnu.org/licenses/>. 

18LICENSE""" 

19from typing import Optional, List, Tuple, Dict, Union 

20 

21from jerrycan.base import db 

22from jerrycan.db.User import User 

23 

24from bundesliga_tippspiel.db import Match, Bet, Team 

25 

26 

27class LeagueTable: 

28 """ 

29 Class that create a league table 

30 """ 

31 

32 def __init__( 

33 self, 

34 league: str, 

35 season: int, 

36 matchday: int, 

37 user: Optional[User] 

38 ): 

39 """ 

40 Initializes the lague table object 

41 :param league: The league 

42 :param season: The season 

43 :param matchday: The matchday 

44 :param user: Optionally, a user. This will replace the real 

45 results with the bets of the player 

46 """ 

47 self.league = league 

48 self.season = season 

49 self.matchday = matchday 

50 self.user = user 

51 

52 self.teams = Team.get_teams_for_season(league, season) 

53 self.matches = Match.query.filter_by( 

54 league=league, season=season 

55 ).filter(Match.matchday <= matchday).options( 

56 db.joinedload(Match.home_team), 

57 db.joinedload(Match.away_team) 

58 ).all() 

59 self.bets = [] 

60 if self.user is not None: 

61 self.bets = [ 

62 x for x in Bet.query.filter_by( 

63 user_id=self.user.id, 

64 league=league, 

65 season=season 

66 ).options(db.joinedload(Bet.match)).all() 

67 if x.match.matchday <= matchday 

68 ] 

69 

70 def calculate_table(self) -> List[Tuple[ 

71 int, Team, int, int, int, int, int, int, int, int 

72 ]]: 

73 """ 

74 Calculates the table 

75 :return: A list of tuples with the following items: 

76 - position 

77 - team 

78 - matches 

79 - wins 

80 - draws 

81 - losses 

82 - goals for 

83 - goals against 

84 - goal difference 

85 - points 

86 """ 

87 teams = {team.abbreviation: team for team in self.teams} 

88 team_data = { 

89 team.abbreviation: { 

90 "matches": 0, 

91 "wins": 0, 

92 "draws": 0, 

93 "losses": 0, 

94 "goals_for": 0, 

95 "goals_against": 0, 

96 "points": 0 

97 } 

98 for team in self.teams 

99 } 

100 handled = [] 

101 match_infos = [] 

102 for bet in self.bets: 

103 match = bet.match 

104 home = match.home_team_abbreviation 

105 away = match.away_team_abbreviation 

106 identifier = home + away + str(match.matchday) 

107 handled.append(identifier) 

108 

109 if match.finished: 

110 match_infos.append( 

111 (home, away, bet.home_score, bet.away_score) 

112 ) 

113 

114 for match in self.matches: 

115 home = match.home_team_abbreviation 

116 away = match.away_team_abbreviation 

117 identifier = home + away + str(match.matchday) 

118 if identifier in handled: 

119 continue 

120 

121 if match.finished: 

122 match_infos.append( 

123 (home, away, match.home_ft_score, match.away_ft_score) 

124 ) 

125 

126 for home, away, home_score, away_score in match_infos: 

127 for team, team_score, opponent_score in [ 

128 (home, home_score, away_score), 

129 (away, away_score, home_score) 

130 ]: 

131 team_data[team]["matches"] += 1 

132 team_data[team]["goals_for"] += team_score 

133 team_data[team]["goals_against"] += opponent_score 

134 if team_score < opponent_score: 

135 team_data[team]["losses"] += 1 

136 elif team_score > opponent_score: 

137 team_data[team]["wins"] += 1 

138 team_data[team]["points"] += 3 

139 else: 

140 team_data[team]["draws"] += 1 

141 team_data[team]["points"] += 1 

142 team_values = list(team_data.items()) 

143 team_values.sort(key=lambda x: x[1]["goals_for"], reverse=True) 

144 team_values.sort( 

145 key=lambda x: x[1]["goals_for"] - x[1]["goals_against"], 

146 reverse=True 

147 ) 

148 team_values.sort(key=lambda x: x[1]["points"], reverse=True) 

149 data_tuples = [] 

150 for i, (team_abbreviation, data) in enumerate(team_values): 

151 data_tuples.append(( 

152 i + 1, 

153 teams[team_abbreviation], 

154 data["matches"], 

155 data["wins"], 

156 data["draws"], 

157 data["losses"], 

158 data["goals_for"], 

159 data["goals_against"], 

160 data["goals_for"] - data["goals_against"], 

161 data["points"] 

162 )) 

163 return data_tuples