From 1c0754dc0c2108cd7f3ff308764e418935205e7d Mon Sep 17 00:00:00 2001 From: Svea Date: Thu, 18 Jan 2024 16:27:45 +0100 Subject: [PATCH 1/8] added basic user database and tests --- .../server/user_database.py | 65 +++++++++++++++++++ tests/user_database_test.py | 36 ++++++++++ 2 files changed, 101 insertions(+) create mode 100644 teamprojekt_competition_server/server/user_database.py create mode 100644 tests/user_database_test.py diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py new file mode 100644 index 00000000..cf82d770 --- /dev/null +++ b/teamprojekt_competition_server/server/user_database.py @@ -0,0 +1,65 @@ +"""User-Database-Module""" + +import sqlite3 + +USER_DB_NAME = "user" + + +# Connect to the database: +connection = sqlite3.connect('teamprojekt_competition_server/server/COMP_database.db') +cursor = connection.cursor() +cursor.execute(f""" + CREATE TABLE IF NOT EXISTS {USER_DB_NAME} ( + user_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + name TEXT NOT NULL, + token INTEGER NOT NULL, + TS_mu FLOAT NOT NULL, + TS_sigma FLOAT NOT NULL + )""") + +def _is_token_taken(new_token: int) -> bool: + cursor.execute(f""" + SELECT COUNT(*) FROM {USER_DB_NAME} WHERE token=? + """, (new_token,)) + count = cursor.fetchone()[0] + return count > 0 + + +def add_user( + user_name: str, user_token: int, mu=25.000, sigma = 8.333 +) -> int | None: + assert not _is_token_taken(user_token) + cursor.execute(f""" + INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", (user_name, user_token, mu, sigma)) + connection.commit() + return cursor.lastrowid + + + +def get_user(id: int) -> tuple: + cursor.execute(f""" + SELECT * FROM {USER_DB_NAME} WHERE user_id = ? + """, (id,)) + user = cursor.fetchone() + return user + + +def get_all_users() -> list[tuple]: + cursor.execute(f""" + SELECT * FROM {USER_DB_NAME} + """) + users = cursor.fetchall() + return users + + +def update_user_TS(id: int, new_mu:float, new_sigma:float): + cursor.execute(f""" + UPDATE {USER_DB_NAME} SET TS_mu=?, TS_sigma=? WHERE user_id=? + """, (new_mu, new_sigma, id)) + connection.commit() + + +def delete_user(id: int) -> None: + cursor.execute(f""" DELETE FROM {USER_DB_NAME} WHERE user_id = ? """, (id,)) + connection.commit() + diff --git a/tests/user_database_test.py b/tests/user_database_test.py new file mode 100644 index 00000000..41a20833 --- /dev/null +++ b/tests/user_database_test.py @@ -0,0 +1,36 @@ +import teamprojekt_competition_server.server.user_database as user_db +import logging + +# run with python -m tests.user_database_test + +logging.basicConfig(level=logging.DEBUG) + + +def user_database_tests(): + userID1 = user_db.add_user(user_name = "player_1", user_token= 123) + userID2 = user_db.add_user(user_name = "player_2", user_token= 456) + userID3 = user_db.add_user(user_name = "player_3", user_token= 789) + userID4 = user_db.add_user(user_name = "player_4", user_token= 444) + print(userID1, userID2, userID3, userID4) + + assert userID1 % 3 == 1 and userID2 % 3 == 2 and userID3 % 3 == 0 and userID4 % 3 == 1 + all_users = user_db.get_all_users() + print(all_users) + assert len(all_users) == 4 + + user = user_db.get_user(id = userID1) + print(f"User ID: {user[0]}, Name: {user[1]}, Token: {user[2]}, Mu: {user[3]}, Sigma: {user[4]}") + + user_db.update_user_TS(id=userID3, new_mu= 24.000, new_sigma=9.333) + user = user_db.get_user(id = userID3) + assert user[3] == 24.000 and user[4] == 9.333 + + user_db.delete_user(userID4) + all_users = user_db.get_all_users() + assert len(all_users) == 3 + + + +if __name__ == "__main__": + # user_database_tests() # only enable for manual testing + pass \ No newline at end of file From db8f60b30383242b581f3ef2398ae8d378b91ff1 Mon Sep 17 00:00:00 2001 From: Svea Date: Fri, 19 Jan 2024 13:59:34 +0100 Subject: [PATCH 2/8] added docstrings --- .../server/user_database.py | 97 +++++++++++++++---- 1 file changed, 78 insertions(+), 19 deletions(-) diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py index cf82d770..e5b3a774 100644 --- a/teamprojekt_competition_server/server/user_database.py +++ b/teamprojekt_competition_server/server/user_database.py @@ -6,60 +6,119 @@ # Connect to the database: -connection = sqlite3.connect('teamprojekt_competition_server/server/COMP_database.db') +connection = sqlite3.connect("teamprojekt_competition_server/server/COMP_database.db") cursor = connection.cursor() -cursor.execute(f""" +cursor.execute( + f""" CREATE TABLE IF NOT EXISTS {USER_DB_NAME} ( user_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, token INTEGER NOT NULL, TS_mu FLOAT NOT NULL, TS_sigma FLOAT NOT NULL - )""") + )""" +) + def _is_token_taken(new_token: int) -> bool: - cursor.execute(f""" + """tests whether a token has already been assigned to another user + + Args: + new_token (int): the token that should be tested + + Returns: + bool: + returns true if token has already been assigned to another user + returns false if the token does not yet exist + """ + cursor.execute( + f""" SELECT COUNT(*) FROM {USER_DB_NAME} WHERE token=? - """, (new_token,)) + """, + (new_token,), + ) count = cursor.fetchone()[0] return count > 0 -def add_user( - user_name: str, user_token: int, mu=25.000, sigma = 8.333 -) -> int | None: +def add_user(user_name: str, user_token: int, mu=25.000, sigma=8.333) -> int | None: + """adds a new user to the database + + Args: + user_name (str): name of the user + user_token (int): token for the user (must be unique for every user) + mu (float, optional): needed for TrueSkill. Defaults to 25.000. + sigma (float, optional): needed for TrueSkill. Defaults to 8.333. + + Returns: + int | None: returns the user_id + """ assert not _is_token_taken(user_token) - cursor.execute(f""" - INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", (user_name, user_token, mu, sigma)) + cursor.execute( + f""" + INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", + (user_name, user_token, mu, sigma), + ) connection.commit() return cursor.lastrowid - def get_user(id: int) -> tuple: - cursor.execute(f""" + """returns the database entry for the user with this id + + Args: + id (int): the id of the user + + Returns: + tuple: the database entry + """ + cursor.execute( + f""" SELECT * FROM {USER_DB_NAME} WHERE user_id = ? - """, (id,)) + """, + (id,), + ) user = cursor.fetchone() return user def get_all_users() -> list[tuple]: - cursor.execute(f""" + """returns the database entries for all users + + Returns: + list[tuple]: database entries of all users + """ + cursor.execute( + f""" SELECT * FROM {USER_DB_NAME} - """) + """ + ) users = cursor.fetchall() return users -def update_user_TS(id: int, new_mu:float, new_sigma:float): - cursor.execute(f""" +def update_user_TS(id: int, new_mu: float, new_sigma: float): + """updates the mu and sigma entries required for TrueSkill for one user + + Args: + id (int): user id + new_mu (float): new mu value + new_sigma (float): new sigma value + """ + cursor.execute( + f""" UPDATE {USER_DB_NAME} SET TS_mu=?, TS_sigma=? WHERE user_id=? - """, (new_mu, new_sigma, id)) + """, + (new_mu, new_sigma, id), + ) connection.commit() def delete_user(id: int) -> None: + """deletes a user from the database + + Args: + id (int): user id + """ cursor.execute(f""" DELETE FROM {USER_DB_NAME} WHERE user_id = ? """, (id,)) connection.commit() - From d47da7a183ce609b5e63eaaa21089b91c9efe5fc Mon Sep 17 00:00:00 2001 From: Svea Date: Fri, 19 Jan 2024 14:27:50 +0100 Subject: [PATCH 3/8] changed formatting --- .../server/user_database.py | 3 +- tests/user_database_test.py | 28 +++++++++++-------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py index e5b3a774..2b9cadbc 100644 --- a/teamprojekt_competition_server/server/user_database.py +++ b/teamprojekt_competition_server/server/user_database.py @@ -55,8 +55,7 @@ def add_user(user_name: str, user_token: int, mu=25.000, sigma=8.333) -> int | N """ assert not _is_token_taken(user_token) cursor.execute( - f""" - INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", + f"""INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", (user_name, user_token, mu, sigma), ) connection.commit() diff --git a/tests/user_database_test.py b/tests/user_database_test.py index 41a20833..9f7b2689 100644 --- a/tests/user_database_test.py +++ b/tests/user_database_test.py @@ -7,22 +7,27 @@ def user_database_tests(): - userID1 = user_db.add_user(user_name = "player_1", user_token= 123) - userID2 = user_db.add_user(user_name = "player_2", user_token= 456) - userID3 = user_db.add_user(user_name = "player_3", user_token= 789) - userID4 = user_db.add_user(user_name = "player_4", user_token= 444) + userID1 = user_db.add_user(user_name="player_1", user_token=123) + userID2 = user_db.add_user(user_name="player_2", user_token=456) + userID3 = user_db.add_user(user_name="player_3", user_token=789) + userID4 = user_db.add_user(user_name="player_4", user_token=444) print(userID1, userID2, userID3, userID4) - - assert userID1 % 3 == 1 and userID2 % 3 == 2 and userID3 % 3 == 0 and userID4 % 3 == 1 + + assert ( + userID1 % 3 == 1 and userID2 % 3 == 2 and userID3 % 3 == 0 and userID4 % 3 == 1 + ) all_users = user_db.get_all_users() print(all_users) assert len(all_users) == 4 - user = user_db.get_user(id = userID1) - print(f"User ID: {user[0]}, Name: {user[1]}, Token: {user[2]}, Mu: {user[3]}, Sigma: {user[4]}") + user = user_db.get_user(id=userID1) + print( + f"User ID: {user[0]}, Name: {user[1]}, \ + Token: {user[2]}, Mu: {user[3]}, Sigma: {user[4]}" + ) - user_db.update_user_TS(id=userID3, new_mu= 24.000, new_sigma=9.333) - user = user_db.get_user(id = userID3) + user_db.update_user_TS(id=userID3, new_mu=24.000, new_sigma=9.333) + user = user_db.get_user(id=userID3) assert user[3] == 24.000 and user[4] == 9.333 user_db.delete_user(userID4) @@ -30,7 +35,6 @@ def user_database_tests(): assert len(all_users) == 3 - if __name__ == "__main__": # user_database_tests() # only enable for manual testing - pass \ No newline at end of file + pass From 835883bff5aeee067715723695be68313619cac7 Mon Sep 17 00:00:00 2001 From: Svea Date: Fri, 19 Jan 2024 14:30:03 +0100 Subject: [PATCH 4/8] shorten a line --- teamprojekt_competition_server/server/user_database.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py index 2b9cadbc..7f797fc9 100644 --- a/teamprojekt_competition_server/server/user_database.py +++ b/teamprojekt_competition_server/server/user_database.py @@ -55,7 +55,8 @@ def add_user(user_name: str, user_token: int, mu=25.000, sigma=8.333) -> int | N """ assert not _is_token_taken(user_token) cursor.execute( - f"""INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", + f""" + INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", (user_name, user_token, mu, sigma), ) connection.commit() From 3a1e4fe17522d0fe92150435196f421dd838825e Mon Sep 17 00:00:00 2001 From: Svea Date: Mon, 22 Jan 2024 12:57:29 +0100 Subject: [PATCH 5/8] added verify_user() --- .../server/user_database.py | 19 +++++++++++++++++++ tests/user_database_test.py | 1 + 2 files changed, 20 insertions(+) diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py index 7f797fc9..f734a2ad 100644 --- a/teamprojekt_competition_server/server/user_database.py +++ b/teamprojekt_competition_server/server/user_database.py @@ -82,6 +82,25 @@ def get_user(id: int) -> tuple: return user +def verify_user(user_token: int) -> int: + """returns the corresponding user_id for a token + + Args: + user_token (int): token for which the user should be found + + Returns: + int: user_id + """ + res = cursor.execute( + f""" + SELECT user_id FROM {USER_DB_NAME} WHERE token = ? + """, + (user_token,), + ) + (id,) = res.fetchone() + return id + + def get_all_users() -> list[tuple]: """returns the database entries for all users diff --git a/tests/user_database_test.py b/tests/user_database_test.py index 9f7b2689..ebf67747 100644 --- a/tests/user_database_test.py +++ b/tests/user_database_test.py @@ -19,6 +19,7 @@ def user_database_tests(): all_users = user_db.get_all_users() print(all_users) assert len(all_users) == 4 + assert user_db.verify_user(123) == userID1 user = user_db.get_user(id=userID1) print( From 96c26bfdce6d68c5dcd119ba319ef6a0d7d83fa4 Mon Sep 17 00:00:00 2001 From: Svea Date: Mon, 22 Jan 2024 16:39:24 +0100 Subject: [PATCH 6/8] added get_matchmaking_parameters --- .../server/user_database.py | 48 ++++++++++++++----- tests/user_database_test.py | 6 +-- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py index f734a2ad..a472c251 100644 --- a/teamprojekt_competition_server/server/user_database.py +++ b/teamprojekt_competition_server/server/user_database.py @@ -1,6 +1,7 @@ """User-Database-Module""" import sqlite3 +import logging as log USER_DB_NAME = "user" @@ -14,8 +15,8 @@ user_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, token INTEGER NOT NULL, - TS_mu FLOAT NOT NULL, - TS_sigma FLOAT NOT NULL + mu FLOAT NOT NULL, + sigma FLOAT NOT NULL )""" ) @@ -41,14 +42,16 @@ def _is_token_taken(new_token: int) -> bool: return count > 0 -def add_user(user_name: str, user_token: int, mu=25.000, sigma=8.333) -> int | None: +def add_user( + user_name: str, user_token: int, user_mu=25.000, user_sigma=8.333 +) -> int | None: """adds a new user to the database Args: user_name (str): name of the user user_token (int): token for the user (must be unique for every user) - mu (float, optional): needed for TrueSkill. Defaults to 25.000. - sigma (float, optional): needed for TrueSkill. Defaults to 8.333. + user_mu (float, optional): needed for Matchmaking. Defaults to 25.000. + user_sigma (float, optional): needed for Matchmaking. Defaults to 8.333. Returns: int | None: returns the user_id @@ -56,11 +59,19 @@ def add_user(user_name: str, user_token: int, mu=25.000, sigma=8.333) -> int | N assert not _is_token_taken(user_token) cursor.execute( f""" - INSERT INTO {USER_DB_NAME}(name, token, TS_mu, TS_sigma) VALUES (?,?,?,?)""", - (user_name, user_token, mu, sigma), + INSERT INTO {USER_DB_NAME}(name, token, mu, sigma) VALUES (?,?,?,?)""", + (user_name, user_token, user_mu, user_sigma), ) connection.commit() - return cursor.lastrowid + id = cursor.lastrowid + log.debug( + ( + "inserted user(" + f"user_id={id}, name={user_name}, token={user_token}, " + f"mu={user_mu}, sigma={user_sigma})" + ) + ) + return id def get_user(id: int) -> tuple: @@ -70,7 +81,7 @@ def get_user(id: int) -> tuple: id (int): the id of the user Returns: - tuple: the database entry + tuple(int, string, int, float, float): the database entry (user_id, name, token, mu, sigma) """ cursor.execute( f""" @@ -105,7 +116,7 @@ def get_all_users() -> list[tuple]: """returns the database entries for all users Returns: - list[tuple]: database entries of all users + list[tuple(int, string, int, float, float)]: database entries of all users list[(user_id, name, token, mu, sigma)] """ cursor.execute( f""" @@ -116,8 +127,8 @@ def get_all_users() -> list[tuple]: return users -def update_user_TS(id: int, new_mu: float, new_sigma: float): - """updates the mu and sigma entries required for TrueSkill for one user +def update_matchmaking_parameters(id: int, new_mu: float, new_sigma: float): + """updates the mu and sigma entries required for Matchmaking for one user Args: id (int): user id @@ -126,13 +137,24 @@ def update_user_TS(id: int, new_mu: float, new_sigma: float): """ cursor.execute( f""" - UPDATE {USER_DB_NAME} SET TS_mu=?, TS_sigma=? WHERE user_id=? + UPDATE {USER_DB_NAME} SET mu=?, sigma=? WHERE user_id=? """, (new_mu, new_sigma, id), ) connection.commit() +def get_matchmaking_parameters(id: int) -> (float, float): + res = cursor.execute( + f""" + SELECT mu, sigma FROM {USER_DB_NAME} WHERE user_id = ? + """, + (id,), + ) + parameters = res.fetchone() + return parameters + + def delete_user(id: int) -> None: """deletes a user from the database diff --git a/tests/user_database_test.py b/tests/user_database_test.py index ebf67747..b52a27d0 100644 --- a/tests/user_database_test.py +++ b/tests/user_database_test.py @@ -27,9 +27,9 @@ def user_database_tests(): Token: {user[2]}, Mu: {user[3]}, Sigma: {user[4]}" ) - user_db.update_user_TS(id=userID3, new_mu=24.000, new_sigma=9.333) - user = user_db.get_user(id=userID3) - assert user[3] == 24.000 and user[4] == 9.333 + user_db.update_matchmaking_parameters(id=userID3, new_mu=24.000, new_sigma=9.333) + (mu, sigma) = user_db.get_matchmaking_parameters(id=userID3) + assert mu == 24.000 and sigma == 9.333 user_db.delete_user(userID4) all_users = user_db.get_all_users() From 3dd712540ee7923fac1524e2e0b0351af293eced Mon Sep 17 00:00:00 2001 From: Svea Date: Mon, 22 Jan 2024 16:44:42 +0100 Subject: [PATCH 7/8] added docstring --- teamprojekt_competition_server/server/user_database.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py index a472c251..af6633b6 100644 --- a/teamprojekt_competition_server/server/user_database.py +++ b/teamprojekt_competition_server/server/user_database.py @@ -145,6 +145,14 @@ def update_matchmaking_parameters(id: int, new_mu: float, new_sigma: float): def get_matchmaking_parameters(id: int) -> (float, float): + """gets the mu and sigma entries required for Matchmaking of the user + + Args: + id (int): user_id + + Returns: + (float, float): (mu, sigma) + """ res = cursor.execute( f""" SELECT mu, sigma FROM {USER_DB_NAME} WHERE user_id = ? From d71f5f36cafd5d133733cdc0d4d78f9767598cf5 Mon Sep 17 00:00:00 2001 From: Svea Date: Mon, 22 Jan 2024 16:49:09 +0100 Subject: [PATCH 8/8] formatting --- teamprojekt_competition_server/server/user_database.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/teamprojekt_competition_server/server/user_database.py b/teamprojekt_competition_server/server/user_database.py index af6633b6..fd37120f 100644 --- a/teamprojekt_competition_server/server/user_database.py +++ b/teamprojekt_competition_server/server/user_database.py @@ -81,7 +81,8 @@ def get_user(id: int) -> tuple: id (int): the id of the user Returns: - tuple(int, string, int, float, float): the database entry (user_id, name, token, mu, sigma) + tuple(int, string, int, float, float): database entry + (user_id, name, token, mu, sigma) """ cursor.execute( f""" @@ -116,7 +117,8 @@ def get_all_users() -> list[tuple]: """returns the database entries for all users Returns: - list[tuple(int, string, int, float, float)]: database entries of all users list[(user_id, name, token, mu, sigma)] + list[tuple(int, string, int, float, float)]: database entries of all users + list[(user_id, name, token, mu, sigma)] """ cursor.execute( f""" @@ -144,7 +146,7 @@ def update_matchmaking_parameters(id: int, new_mu: float, new_sigma: float): connection.commit() -def get_matchmaking_parameters(id: int) -> (float, float): +def get_matchmaking_parameters(id: int) -> tuple[float, float]: """gets the mu and sigma entries required for Matchmaking of the user Args: