Coverage for bundesliga_tippspiel/db/user_generated/LeaderboardEntry.py: 54%
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
21from jerrycan.base import db
22from jerrycan.db.ModelMixin import ModelMixin
23from jerrycan.db.User import User
26class LeaderboardEntry(ModelMixin, db.Model):
27 """
28 Model that describes the 'leaderboard_entries' SQL table
29 """
31 def __init__(self, *args, **kwargs):
32 """
33 Initializes the Model
34 :param args: The constructor arguments
35 :param kwargs: The constructor keyword arguments
36 """
37 super().__init__(*args, **kwargs)
39 __tablename__ = "leaderboard_entries"
41 league: int = db.Column(db.String(255), primary_key=True)
42 season: int = db.Column(db.Integer, primary_key=True)
43 matchday: int = db.Column(db.Integer, primary_key=True)
44 user_id: int = db.Column(
45 db.Integer,
46 db.ForeignKey("users.id"),
47 primary_key=True
48 )
50 points: int = db.Column(db.Integer, nullable=False)
51 position: int = db.Column(db.Integer, nullable=False)
52 no_bot_position: int = db.Column(db.Integer, nullable=False)
53 previous_position: int = db.Column(db.Integer, nullable=False)
54 no_bot_previous_position: int = db.Column(db.Integer, nullable=False)
56 user: User = db.relationship(
57 "User",
58 backref=db.backref("leaderboard_entries", cascade="all, delete")
59 )
61 def get_position_info(self, include_bots: bool) -> Tuple[int, int]:
62 """
63 Retrieves position info
64 :param include_bots: Whether or not to include bots in the ranking
65 :return: Current Position, Previous Position
66 """
67 current = self.position if include_bots else self.no_bot_position
68 previous = self.previous_position \
69 if include_bots else self.no_bot_previous_position
70 return current, previous
72 def get_tendency(self, include_bots: bool) -> str:
73 """
74 Calculates the position tendency
75 :param include_bots: Whether or not to include bots
76 :return: The tendency as a string (example '+2')
77 """
78 current, previous = self.get_position_info(include_bots)
79 tendency = previous - current
80 if tendency < 0:
81 return str(tendency)
82 elif tendency > 0:
83 return f"+{tendency}"
84 else:
85 return "-"
87 def get_tendency_class(self, include_bots: bool) -> str:
88 """
89 Calculates the tendency and returns the corrsponding CSS class
90 :param include_bots: Whether or not to include bots
91 :return: The tendency CSS class name
92 """
93 current, previous = self.get_position_info(include_bots)
95 if current < previous:
96 return "chevron-circle-up"
97 elif current > previous:
98 return "chevron-circle-down"
99 else:
100 return "minus-circle"
102 @classmethod
103 def load_history(cls, league: str, season: int, matchday: int) -> \
104 List[Tuple[User, List["LeaderboardEntry"]]]:
105 """
106 Loads the history for the previous matches in a season for each user
107 :param league: The league for which to retrieve the history
108 :param season: The season for which to retrieve the history
109 :param matchday: The matchday for which to retrieve the history
110 :return: The history as a list of tuples of users and a list of
111 the corresponding LeaderboardEntry objects.
112 Sorted by current position
113 """
114 entries: List[LeaderboardEntry] = [
115 x for x in
116 LeaderboardEntry.query.filter_by(
117 league=league,
118 season=season
119 ).options(db.joinedload(LeaderboardEntry.user)).all()
120 if x.matchday <= matchday
121 ]
122 entries.sort(key=lambda x: x.matchday) 122 ↛ exitline 122 didn't run the lambda on line 122
124 history_dict: Dict[int, List[LeaderboardEntry]] = {}
125 for entry in entries: 125 ↛ 126line 125 didn't jump to line 126, because the loop on line 125 never started
126 if entry.user_id not in history_dict:
127 history_dict[entry.user_id] = []
128 history_dict[entry.user_id].append(entry)
130 history_list = [
131 (history[-1].user, history)
132 for _, history in history_dict.items()
133 ]
134 history_list.sort(key=lambda x: x[1][-1].position) 134 ↛ exitline 134 didn't run the lambda on line 134
135 return history_list