aboutsummaryrefslogtreecommitdiff
path: root/src/match_up/model.py
diff options
context:
space:
mode:
authorKaran Jayachandra <mail@karanjayachandra.com>2024-11-12 18:15:29 +0100
committerKaran Jayachandra <mail@karanjayachandra.com>2024-11-12 18:15:29 +0100
commit7c0820d3d19927e695faa18cb3f5494ee39e0c77 (patch)
tree16f0c045a928a390558e81610ab8ca68e32249d8 /src/match_up/model.py
parent7feeb30875c19a9f305e02f802e3634469349655 (diff)
Database handling added
Diffstat (limited to 'src/match_up/model.py')
-rw-r--r--src/match_up/model.py224
1 files changed, 162 insertions, 62 deletions
diff --git a/src/match_up/model.py b/src/match_up/model.py
index 5d6c0f5..4f8ec8c 100644
--- a/src/match_up/model.py
+++ b/src/match_up/model.py
@@ -1,9 +1,15 @@
from math import floor
-from csv import reader
from typing import Tuple
-from names import get_full_name
+from os.path import join, isfile
from dataclasses import dataclass
+from importlib.resources import path
+from pandas import read_csv, DataFrame
+from sqlalchemy.orm import sessionmaker
from random import randint, getrandbits
+from names import get_first_name, get_last_name
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy import create_engine, Column, String, Integer, not_
+
MIN_LEVEL = 1
MAX_LEVEL = 10
@@ -11,17 +17,60 @@ DEFAULT_COURTS = 12
PLAYER_PER_COURT = 4
-@dataclass
-class Player:
- name: str
- skill: int = 1
- status: bool = False
+Base = declarative_base()
+
+
+class Player(Base):
+ __tablename__ = "players"
+ id = Column("id", Integer, primary_key=True)
+ first = Column("first", String)
+ last = Column("last", String)
+ level = Column("level", Integer)
+ status = Column("status", Integer)
+ count = Column("count", Integer)
+
+ def __init__(
+ self,
+ id: int = None,
+ first: str = "",
+ last: str = "",
+ level: int = None,
+ status: bool = None,
+ count: int = None,
+ ):
+ self.id = id
+ self.first = first
+ self.last = last
+ self.status = status
+ self.level = level
+ self.count = count
+
+ def __repr__(self):
+ status = "active" if self.status else "inactive"
+ return f"{self.first} {self.last} (Level {self.level}) is {status} and has played {self.count} games"
+
+
+class DisplayPlayer:
+ id: int
+ first: str
+ last: str
+ status: bool
+
+ def __init__(self, player: Player):
+ self.id = player.id
+ self.first = player.first
+ self.last = player.last
+ self.status = player.status
+
+ def __repr__(self):
+ status = "active" if self.status else "inactive"
+ return f"{self.first} {self.last} is {status}"
@dataclass
class Team:
- player1: str
- player2: str
+ player1: DisplayPlayer
+ player2: DisplayPlayer
@dataclass
@@ -55,69 +104,120 @@ class CourtList:
return active_courts, inactive_courts
-def _load_csv_players(file_name: str) -> dict:
- with open(file_name, newline="") as file:
- pointer = reader(file)
- next(pointer, None)
- players = {id: Player(row[0], int(row[1])) for id, row in enumerate(pointer)}
- return players
-
-
-def _generate_random_players(player_count: int = 80) -> list[Player]:
- players = {
- i: Player(
- name=get_full_name(),
- skill=randint(MIN_LEVEL, MAX_LEVEL),
- status=bool(getrandbits(1)),
- )
- for i in range(player_count)
- }
- return players
-
-
-@dataclass
class PlayerList:
- location: str = None
- guests: int = 0
+ guests: dict = {"low": 0, "mid": 0, "high": 0}
- def __post_init__(self) -> None:
- if self.location is not None:
- self.players = _load_csv_players(self.location)
- else:
- self.players = _generate_random_players()
- self.guest_id_start = len(self.players) + 1
+ def __init__(self, csv_location: str = None) -> None:
+ with path("match_up") as p:
+ self.db_location = join(p, "players.db")
+ generate_random_players = False
+ if not isfile(self.db_location):
+ print(f"No database file found")
+ if csv_location is None:
+ generate_random_players = True
+ engine = create_engine("sqlite:///" + self.db_location, echo=True)
+ Base.metadata.create_all(bind=engine)
+ self.session = sessionmaker(bind=engine)()
+ if csv_location is not None:
+ print(f"CSV file provided, updating the database")
+ self.session.query(Player).delete()
+ self._init_database_from_csv(read_csv(self.csv_location))
+ elif generate_random_players:
+ print(f"Generating random players for testing")
+ self._init_random_database()
- def increment_guests(self):
- self.guests = self.guests + 1
- return self.guests
+ def increment_guests(self, level: str):
+ self.guests[level] = self.guests[level] + 1
+ return self.guests[level]
- def decrement_guests(self):
- if self.guests == 0:
+ def decrement_guests(self, level: str):
+ if self.guests[level] == 0:
return 0
- self.guests = self.guests - 1
- return self.guests
+ self.guests[level] = self.guests[level] - 1
+ return self.guests[level]
- def get_player_status(self, player_number: int) -> bool:
- return self.players[player_number].status
+ def get_player_status(self, id: int) -> bool:
+ return self.session.query(Player).filter(Player.id == id).first().status
- def toggle_player_status(self, player_number: int) -> Tuple[bool, str]:
- new_status = not self.players[player_number].status
- self.players[player_number].status = new_status
- return new_status, self.players[player_number].name
+ def toggle_player_status(self, id: int) -> DisplayPlayer:
+ player = self.session.query(Player).filter(Player.id == id).first()
+ player.status = not player.status
+ self.session.commit()
+ return DisplayPlayer(player)
- def get_players(self) -> dict:
- return self.players
+ def get_all_players(self) -> list[Player]:
+ all_players = [DisplayPlayer(p) for p in self.session.query(Player).all()]
+ return all_players
def get_possible_game_count(self) -> int:
- total_players = len(self.get_potential_players())
+ total_players = len(self.get_players())
possible_games = floor(total_players / PLAYER_PER_COURT)
return possible_games
- def get_potential_players(self) -> dict:
- players = {k: v for k, v in self.players.items() if v.status}
- guests = {
- self.guest_id_start + k: Player(name=f"Guest {k}")
- for k in range(1, self.guests + 1)
- }
- players.update(guests)
- return players
+ def get_players(self, rounds: int = 0) -> list[Player]:
+ active_players = (
+ self.session.query(Player).filter(not_(Player.status == 0)).all()
+ )
+ low_guests = [
+ Player(
+ id=1000 + i,
+ first=f"Beginner",
+ last=f"{i}",
+ level=1,
+ status=True,
+ count=rounds,
+ )
+ for i in range(1, self.guests["low"] + 1)
+ ]
+ mid_guests = [
+ Player(
+ id=2000 + i,
+ first=f"Novice",
+ last=f"{i}",
+ level=4,
+ status=True,
+ count=rounds,
+ )
+ for i in range(1, self.guests["mid"] + 1)
+ ]
+ high_guests = [
+ Player(
+ id=3000 + i,
+ first=f"Intermediate",
+ last=f"{i}",
+ level=7,
+ status=True,
+ count=rounds,
+ )
+ for i in range(1, self.guests["high"] + 1)
+ ]
+ return active_players + low_guests + mid_guests + high_guests
+
+ def increment_game_count(self, player_ids: list[int]):
+ return 0
+
+ def _init_database_from_csv(self, data: DataFrame) -> None:
+ for _, entry in data.iterrows():
+ player = Player(
+ id=entry["id"],
+ first=entry["first"],
+ last=entry["last"],
+ level=entry["skill"],
+ status=False,
+ count=0,
+ )
+ self.session.add(player)
+ self.session.commit()
+
+ def _init_random_database(self, player_count: int = 80) -> None:
+ for i in range(player_count):
+ player = Player(
+ id=i,
+ first=get_first_name(),
+ last=get_last_name(),
+ level=randint(MIN_LEVEL, MAX_LEVEL),
+ status=getrandbits(1),
+ count=0,
+ )
+ self.session.add(player)
+ self.session.commit()