-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: TTTK-55 statistics.py added: provides different getters and add…
…/update-methods. Also can count emojis and saves them into db.
- Loading branch information
1 parent
e6fefd3
commit a5f34da
Showing
1 changed file
with
393 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,394 @@ | ||
import emoji | ||
import sqlite3 | ||
|
||
|
||
class Statistics: | ||
def __init__(self) -> None: | ||
pass | ||
def __init__(self, path: str = './Data/statistics.db') -> None: | ||
""" | ||
Initializes the statistics object by creating a connection to the database | ||
and creating the table if it doesn't exist | ||
:param path: path to db file, default is './Data/statistics.db' | ||
""" | ||
self.path = path | ||
self.conn = sqlite3.connect(self.path) | ||
self.cursor = self.conn.cursor() | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
CREATE TABLE IF NOT EXISTS statistics( | ||
uuid TEXT, | ||
wins_first INT, | ||
wins_second INT, | ||
loses_first INT, | ||
loses_second INT, | ||
draws_first INT, | ||
draws_second INT, | ||
moves INT, | ||
emojis INT | ||
) | ||
""") | ||
|
||
""" | ||
________Public Methods_________ | ||
________Main Methods___________ | ||
""" | ||
|
||
def get_statistics(self, uuid: str) -> tuple: | ||
""" | ||
Returns the statistics of a profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:return: tuple containing: | ||
(uuid : str, wins_first : int, wins_second : int, loses_first : int, | ||
loses_second : int, draws : int, moves : int, emojis : int) | ||
""" | ||
return self._get_profile(uuid) | ||
|
||
def get_all_statistics(self) -> list: | ||
""" | ||
Returns all statistics from the database | ||
:return: an array of tuples containing: | ||
(uuid : str, wins_first : int, wins_second : int, loses_first : int, | ||
loses_second : int, draws : int, moves : int, emojis : int) | ||
""" | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
SELECT * FROM statistics | ||
""") | ||
return self.cursor.fetchall() | ||
|
||
def add_profile(self, uuid: str, wins_first: int = 0, wins_second: int = 0, loses_first: int = 0, | ||
loses_second: int = 0, draws_first: int = 0, draws_second = 0, moves: int = 0, emojis: int = 0 | ||
) -> None: | ||
""" | ||
Adds a new profile to the database | ||
:param uuid: uuid of the profile that is added | ||
:param wins_first: wins if player started the round | ||
:param wins_second: wins if other player started the round | ||
:param loses_first: loses if player started the round | ||
:param loses_second: loses if other player started the round | ||
:param draws_first: draws if player started the round | ||
:param draws_second: draws if other player started the round | ||
:param moves: moves made by the profile | ||
:param emojis: emojis used by the profile | ||
:return: | ||
""" | ||
self._add_profile(uuid, wins_first = wins_first, wins_second = wins_second, | ||
loses_first = loses_first, loses_second = loses_second, | ||
draws_first = draws_first, draws_second = draws_second, | ||
moves = moves, emojis = emojis) | ||
|
||
def update_statistics(self, uuid: str, type: str, moves: int) -> None: | ||
""" | ||
Updates the statistics of a profile by its uuid | ||
:param uuid: uuid of the profile that is updated | ||
:param type: type of the update, can be: | ||
'wins_first' (if player started the round), 'wins_second' (if other player started the round), | ||
'draws_first', 'draws_second', 'loses_first', 'loses_second' | ||
:param moves: number of moves that were made in the game | ||
""" | ||
if type not in ['wins_first', 'wins_second', 'draws_first', 'draws_second', 'loses_first', 'loses_second']: | ||
raise ValueError('Invalid type') | ||
self._update_wins(uuid, type) | ||
self._update_moves(uuid, moves) | ||
|
||
def count_emojis(self, uuid: str, message: str) -> None: | ||
""" | ||
Counts the emojis in the given message and updates the emoji | ||
statistics of a profile by its uuid | ||
:param uuid: uuid of the profile that is updated | ||
:param message: message that is checked for emojis | ||
""" | ||
self._update_emojis(uuid, emoji.emoji_count(message)) | ||
|
||
""" | ||
________Delete Methods_________ | ||
""" | ||
def delete_statistics(self, uuid: str) -> None: | ||
""" | ||
Deletes statistics of a profile by its uuid | ||
:param uuid: uuid of the profile that is deleted | ||
""" | ||
if self._check_profile(uuid): | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
DELETE FROM statistics | ||
WHERE uuid = '{uuid}' | ||
""") | ||
""" | ||
________Reset Methods_________ | ||
""" | ||
def reset_statistics(self, uuid: str, arg: str): | ||
""" | ||
Resets the statistics of a profile by its uuid | ||
:param uuid: uuid of the profile that is reset | ||
:param arg: statistics that is get reseted, hast to be one of those: | ||
'wins_first', 'wins_second', 'loses_first', 'loses_second', 'draws_first', 'draws_second', 'emojis', 'moves' | ||
:return: | ||
""" | ||
if arg not in ['wins_first', 'wins_second' 'loses_first', 'loses_second', | ||
'draws_first', 'draws_secons', 'emojis', 'moves']: | ||
raise ValueError('Invalid type') | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
UPDATE statistics | ||
SET {arg} = 0 | ||
WHERE uuid = '{uuid}' | ||
""") | ||
|
||
""" | ||
________Get Methods___________ | ||
""" | ||
|
||
# TODO : how does draws influence wr? | ||
# TODO : for all getters: if profile with given uuid doesn't exist: return None or raise error? | ||
def get_winrates(self, uuid: str, type: str = "all") -> float: | ||
""" | ||
Returns the winrate of a profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:param type: type of the winrate, can be: | ||
'first' (if player started the round), 'second' (if other player started the round), 'all' (overall) | ||
standard is 'all' | ||
:return: winrate as a float | ||
""" | ||
if type not in ['first', 'second', 'all']: | ||
raise ValueError('Invalid type') | ||
if self._check_profile(uuid): | ||
profile = self._get_profile(uuid) | ||
if type == 'all': | ||
return (profile[1] + profile[2]) / (profile[1] + profile[2] + profile[3] + profile[4]) | ||
elif type == 'first': | ||
return profile[1] / (profile[1] + profile[3]) | ||
elif type == 'second': | ||
return profile[2] / (profile[2] + profile[4]) | ||
else: | ||
return None | ||
|
||
def get_emojis(self, uuid: str) -> int: | ||
""" | ||
Returns the number of emojis used by a profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:return: number of emojis as an int | ||
""" | ||
if self._check_profile(uuid): | ||
profile = self._get_profile(uuid) | ||
return profile[8] | ||
else: | ||
return None | ||
|
||
def get_moves(self, uuid: str) -> int: | ||
""" | ||
Returns the number of moves made by a profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:return: number of moves as an int | ||
""" | ||
if self._check_profile(uuid): | ||
profile = self._get_profile(uuid) | ||
return profile[7] | ||
else: | ||
return None | ||
|
||
def get_wins(self, uuid: str, type='all') -> int: | ||
""" | ||
Returns the number of wins of a profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:param type: type of wins, can be: | ||
'first' (if player started the round), 'second' (if other player started the round), 'all' (overall) | ||
standard is 'all' | ||
:return: number of wins as an int | ||
""" | ||
if type not in ['first', 'second', 'all']: | ||
raise ValueError('Invalid type') | ||
if self._check_profile(uuid): | ||
profile = self._get_profile(uuid) | ||
if type == 'all': | ||
return profile[1] + profile[2] | ||
elif type == 'first': | ||
return profile[1] | ||
elif type == 'second': | ||
return profile[2] | ||
else: | ||
return None | ||
|
||
def get_loses(self, uuid: str, type='all') -> int: | ||
""" | ||
Returns the number of loses of a profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:param type: type of loses, can be: | ||
'first' (if player started the round), 'second' (if other player started the round), 'all' (overall) | ||
standard is 'all' | ||
:return: number of loses as an int | ||
""" | ||
if type not in ['first', 'second', 'all']: | ||
raise ValueError('Invalid type') | ||
if self._check_profile(uuid): | ||
profile = self._get_profile(uuid) | ||
if type == 'all': | ||
return profile[3] + profile[4] | ||
elif type == 'first': | ||
return profile[3] | ||
elif type == 'second': | ||
return profile[4] | ||
else: | ||
return None | ||
|
||
def get_draws(self, uuid: str, type: str = 'all') -> int: | ||
""" | ||
Returns the number of draws of a profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:param type: type of draws, can be: | ||
'first' (if player started the round), 'second' (if other player started the round), 'all' (overall) | ||
standard is 'all' | ||
:return: number of draws as an int | ||
""" | ||
if type not in ['first', 'second', 'all']: | ||
raise ValueError('Invalid type') | ||
if self._check_profile(uuid): | ||
profile = self._get_profile(uuid) | ||
if type == 'all': | ||
return profile[5] + profile[6] | ||
elif type == 'first': | ||
return profile[5] | ||
elif type == 'second': | ||
return profile[6] | ||
else: | ||
return None | ||
|
||
""" | ||
________Private Methods_________ | ||
________Update Methods__________ | ||
All update functions add new profiles if they don't exist | ||
""" | ||
|
||
def _update_wins(self, uuid: str, type: str) -> None: | ||
""" | ||
Updates the wins of a profile by its uuid | ||
:param uuid: uuid of the profile that is updated | ||
:param type: type of the win, can be: | ||
'wins_first' (if player started the round), 'wins_second' (if other player started the round), | ||
'draws_first', 'draws_second', 'loses_first', 'loses_second' | ||
""" | ||
if type not in ['wins_first', 'wins_second', 'draws_first', 'draws_second', 'loses_first', 'loses_second']: | ||
raise ValueError('Invalid type') | ||
if self._check_profile(uuid): | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
UPDATE statistics | ||
SET {type} = {type} + 1 | ||
WHERE uuid = '{uuid}' | ||
""") | ||
else: | ||
self._add_profile(uuid, wins_first=1 if type == 'wins_first' else 0, | ||
wins_second=1 if type == 'wins_second' else 0, | ||
draws_first=1 if type == 'draws_first' else 0, | ||
draws_second= 1 if type == 'draws_second' else 0, | ||
loses_first=1 if type == 'loses_first' else 0, | ||
loses_second=1 if type == 'loses_second' else 0) | ||
|
||
def _update_moves(self, uuid: str, moves: int) -> None: | ||
""" | ||
Updates the moves of a profile by its uuid | ||
:param uuid: uuid of the profile that is updated | ||
:param moves: moves that are added to the statistics | ||
""" | ||
if self._check_profile(uuid): | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
UPDATE statistics | ||
SET moves = moves + {moves} | ||
WHERE uuid = '{uuid}' | ||
""") | ||
else: | ||
self._add_profile(uuid, moves=moves) | ||
|
||
def _update_emojis(self, uuid: str, count: int) -> None: | ||
""" | ||
Updates the emojis of a profile by its uuid | ||
:param uuid: uuid of the profile that is updated | ||
:param count: count of emojis that are added to the statistics | ||
""" | ||
if self._check_profile(uuid): | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
UPDATE statistics | ||
SET emojis = emojis + :emoji | ||
WHERE uuid = '{uuid}' | ||
""", {'emoji': count}) | ||
else: | ||
self._add_profile(uuid, emojis=count) | ||
|
||
""" | ||
_________Check Methods_________ | ||
""" | ||
|
||
def _check_profile(self, uuid: str) -> bool: | ||
""" | ||
Checks if a profile with the given uuid exists | ||
:param uuid: uuid of the profile that is checked | ||
:return: True if the profile exists, False if it doesn't | ||
""" | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
SELECT * FROM statistics | ||
WHERE uuid = '{uuid}' | ||
""") | ||
return True if self.cursor.fetchone() is not None else False | ||
|
||
""" | ||
_________Get Methods_________ | ||
""" | ||
|
||
def _get_profile(self, uuid: str) -> tuple: | ||
""" | ||
Returns the profile by its uuid | ||
:param uuid: uuid of the profile that is searched | ||
:return: profile statistics as a tuple | ||
""" | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
SELECT * FROM statistics | ||
WHERE uuid = '{uuid}' | ||
""") | ||
return self.cursor.fetchone() | ||
|
||
""" | ||
_________Add Methods_________ | ||
""" | ||
|
||
def _add_profile(self, uuid: str, wins_first: int = 0, wins_second: int = 0, | ||
draws_first: int = 0, draws_second = 0, loses_first: int = 0, | ||
loses_second: int = 0, moves: int = 0, | ||
emojis: int = 0) -> None: | ||
""" | ||
Adds a new profile to the database | ||
:param uuid: uuid of the profile that is added | ||
:param wins_first: wins if player started the round | ||
:param wins_second: wins if other player started the round | ||
:param draws_first: draws if player started the round | ||
:param draws_second: draws if other player started the round | ||
:param loses_first: loses if player started the round | ||
:param loses_second: loses if other player started the round | ||
:param moves: moves made by the profile | ||
:param emojis: emojis used by the profile | ||
""" | ||
with self.conn: | ||
self.cursor.execute(f""" | ||
INSERT INTO statistics | ||
VALUES ( | ||
:uuid, | ||
:wins_first, | ||
:wins_second, | ||
:loses_first, | ||
:loses_second, | ||
:draws_first, | ||
:draws_second, | ||
:moves, | ||
:emojis | ||
) | ||
""", {'uuid': uuid, 'wins_first': wins_first, 'wins_second': wins_second, | ||
'loses_first': loses_first, 'loses_second': loses_second, 'draws_first': draws_first, 'draws_second': draws_second, 'moves': moves, 'emojis': emojis}) | ||
|
||
statistics = Statistics() | ||
statistics.update_statistics("test", "draws_first", 5) | ||
statistics.count_emojis("test", "🤔 🙈 me así, se 😌 ds 💕👭👙 hello 👩🏾🎓 emoji hello 👨👩👦👦 how are 😊 you today🙅🏽🙅🏽") | ||
print(statistics.get_statistics("test")) |