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
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
1"""LICENSE
2Copyright 2017 Hermann Krumrey <hermann@krumreyh.com>
4This file is part of bundesliga-tippspiel.
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.
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.
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"""
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
27class UserStatsGenerator(StatsGenerator):
28 """
29 Class that generates statistics for a single user
30 """
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]
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]
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())
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())
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
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
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
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)
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
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
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
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
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]
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]
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)
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
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]