Coverage for bundesliga_tippspiel/utils/collections/UserStatsGenerator.py: 86%

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

74 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""" 

19 

20from typing import Tuple, List, Dict, Union, Any 

21from jerrycan.db.User import User 

22from bundesliga_tippspiel.db import Team, LeaderboardEntry 

23from bundesliga_tippspiel.utils.collections.StatsGenerator import \ 

24 StatsGenerator 

25 

26 

27class UserStatsGenerator(StatsGenerator): 

28 """ 

29 Class that generates statistics for a single user 

30 """ 

31 

32 def __init__( 

33 self, 

34 league: str, 

35 season: int, 

36 matchday: int, 

37 user: User, 

38 include_bots: bool 

39 ): 

40 """ 

41 Initializes the UserStatsGenerator object 

42 :param league: The league for which to generate statistics 

43 :param season: The season for which to generate statistics 

44 :param matchday: The matchday for which to generate statistics 

45 :param user: The user for which to generate statistics 

46 :param include_bots: Whether or not to include bots 

47 """ 

48 super().__init__(league, season, matchday, include_bots) 

49 self.user = user 

50 histories = [ 

51 history for history_user, history in self.history 

52 if history_user.id == self.user.id 

53 ] 

54 self.user_history = [] if len(histories) == 0 else histories[0] 

55 self.per_day_user_history: Dict[int, LeaderboardEntry] = { 

56 x.matchday: x for x in self.user_history 

57 } 

58 self.user_bets = [x for x in self.bets if x.user_id == self.user.id] 

59 

60 def get_user_position(self) -> int: 

61 """ 

62 :return: The current position of the user 

63 """ 

64 history = self.per_day_user_history.get(self.selected_matchday) 

65 if history is None: 65 ↛ 68line 65 didn't jump to line 68, because the condition on line 65 was never false

66 return 0 

67 else: 

68 return history.get_position_info(self.include_bots)[0] 

69 

70 def get_user_first_half_position(self) -> int: 

71 """ 

72 :return: The user's position in the first half of the season 

73 """ 

74 return self.extract_user_position(self.get_first_half_ranking()) 

75 

76 def get_user_second_half_position(self) -> int: 

77 """ 

78 :return: The user's position in the second half of the season 

79 """ 

80 return self.extract_user_position(self.get_second_half_ranking()) 

81 

82 def get_user_best_position(self) -> int: 

83 """ 

84 :return: The user's best position during the season 

85 """ 

86 best = len(self.users) 

87 for history_item in self.user_history: 87 ↛ 88line 87 didn't jump to line 88, because the loop on line 87 never started

88 position = history_item.get_position_info(self.include_bots)[0] 

89 best = min(position, best) 

90 return best 

91 

92 def get_user_worst_position(self) -> int: 

93 """ 

94 :return: The user's worst position during the season 

95 """ 

96 worst = 1 

97 for history_item in self.user_history: 97 ↛ 98line 97 didn't jump to line 98, because the loop on line 97 never started

98 position = history_item.get_position_info(self.include_bots)[0] 

99 worst = max(position, worst) 

100 return worst 

101 

102 def get_user_points(self) -> int: 

103 """ 

104 :return: The user's current point total 

105 """ 

106 history = self.per_day_user_history.get(self.selected_matchday) 

107 return 0 if history is None else history.points 

108 

109 def get_user_bet_count(self) -> int: 

110 """ 

111 :return: The amount of bets the user has placed 

112 """ 

113 return len(self.user_bets) 

114 

115 def get_user_betting_average(self) -> float: 

116 """ 

117 :return: The average points per bet of the user 

118 """ 

119 points = [bet.points for bet in self.user_bets] 

120 total = len(points) 

121 return 0.0 if total == 0 else sum(points) / total 

122 

123 def get_user_participation(self) -> int: 

124 """ 

125 :return: The user's participation up to this point 

126 """ 

127 ranking = self.get_participation_ranking() 

128 try: 

129 return [x for x in ranking if x[0].id == self.user.id][0][1] 

130 except IndexError: 

131 return 0 

132 

133 def get_user_correct_bets(self) -> int: 

134 """ 

135 :return: The amount of correct bets for this user 

136 """ 

137 ranking = self.get_correct_bets_ranking() 

138 try: 

139 return [x for x in ranking if x[0].id == self.user.id][0][1] 

140 except IndexError: 

141 return 0 

142 

143 def get_user_wrong_bets(self) -> int: 

144 """ 

145 :return: The amount of wrong bets for this user 

146 """ 

147 ranking = self.get_wrong_bets_ranking() 

148 try: 

149 return [x for x in ranking if x[0].id == self.user.id][0][1] 

150 except IndexError: 

151 return 0 

152 

153 def get_user_best_team(self) -> Tuple[Team, float]: 

154 """ 

155 :return: The team this user has achieved the most points for so far 

156 """ 

157 return self.get_user_average_points_per_team()[0] 

158 

159 def get_user_worst_team(self) -> Tuple[Team, float]: 

160 """ 

161 :return: The team this user has achieved the least points for so far 

162 """ 

163 return self.get_user_average_points_per_team()[-1] 

164 

165 def get_user_average_points_per_team(self) -> List[Tuple[Team, float]]: 

166 """ 

167 :return: The average points per team for this user 

168 """ 

169 return self.calculate_average_points_per_team(self.user_bets) 

170 

171 def extract_user_position(self, ranking: List[Tuple[User, Any]]) -> int: 

172 """ 

173 Extracts the user's position from a ranking 

174 :return: The position in the ranking 

175 """ 

176 try: 

177 order = [x[0].id for x in ranking] 

178 return order.index(self.user.id) + 1 

179 except ValueError: 

180 return 0 

181 

182 def get_user_points_distribution(self) -> Dict[int, int]: 

183 """ 

184 :return: A distribution of points for all possible point results 

185 """ 

186 return self.calculate_point_distribution_per_user()[self.user]