summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app.py32
-rw-r--r--model.py96
-rw-r--r--templates/court.j22
-rw-r--r--templates/courts.j24
4 files changed, 62 insertions, 72 deletions
diff --git a/app.py b/app.py
index 6c1609a..5c39c0d 100644
--- a/app.py
+++ b/app.py
@@ -6,10 +6,10 @@ from model import CourtList, PlayerList, GameList
load_dotenv()
-PLAYER_LIST = PlayerList(location="test_data_large.csv")
-COURT_LIST = CourtList(12)
+PLAYERS = PlayerList(location="test_data_large.csv")
+COURTS = CourtList(12)
GAME_GENERATOR = GameList()
-GAME_GENERATOR.clear(COURT_LIST)
+GAME_GENERATOR.clear(COURTS)
app = Flask("Match Up! Backend")
@@ -25,21 +25,21 @@ def home():
@app.route("/random-games", methods=["POST"])
def get_random_games():
print("Creating new games...")
- GAME_GENERATOR.create_random_games(COURT_LIST, PLAYER_LIST)
+ GAME_GENERATOR.create_random_games(COURTS, PLAYERS)
return render_template("games.j2", games=GAME_GENERATOR.games)
@app.route("/skilled-games", methods=["POST"])
def get_skilled_games():
print("Creating new games...")
- GAME_GENERATOR.create_skilled_games(COURT_LIST, PLAYER_LIST)
+ GAME_GENERATOR.create_skilled_games(COURTS, PLAYERS)
return render_template("games.j2", games=GAME_GENERATOR.games)
@app.route("/clear-games", methods=["POST"])
def clear_games():
print("Clearing games...")
- GAME_GENERATOR.clear(COURT_LIST)
+ GAME_GENERATOR.clear(COURTS)
return render_template("games.j2", games=GAME_GENERATOR.games)
@@ -50,30 +50,26 @@ def get_list_of_games():
@app.route("/player-toggle/<player_request>", methods=["POST"])
def toggle_player(player_request):
- selection = PLAYER_LIST.get_player(player_request)
+ selection = PLAYERS.get_player(player_request)
if len(selection) != 1:
abort(404)
- PLAYER_LIST.toggle_player(player_request)
- selection = PLAYER_LIST.get_player(player_request)
+ PLAYERS.toggle_player(player_request)
+ selection = PLAYERS.get_player(player_request)
return render_template("player.j2", player=selection[0])
@app.route("/player-list", methods=["GET"])
def get_list_of_players():
- return render_template("players.j2", players=PLAYER_LIST.players)
+ return render_template("players.j2", players=PLAYERS.players)
@app.route("/court-toggle/<court_number>", methods=["POST"])
def toggle_court(court_number):
- court_number = int(court_number)
- selection = COURT_LIST.get_court(court_number)
- if len(selection) != 1:
- abort(404, f"Multiple courts requested: {len(selection)}")
- COURT_LIST.toggle_court(court_number)
- selection = COURT_LIST.get_court(court_number)
- return render_template("court.j2", court=selection[0])
+ id = int(court_number)
+ status = COURTS.toggle_court_status(id)
+ return render_template("court.j2", id=id, status=status)
@app.route("/court-list", methods=["GET"])
def get_list_of_courts():
- return render_template("courts.j2", courts=COURT_LIST.courts)
+ return render_template("courts.j2", courts=COURTS.courts)
diff --git a/model.py b/model.py
index c83bcfd..bfaa9d5 100644
--- a/model.py
+++ b/model.py
@@ -4,36 +4,28 @@ from pathlib import Path
from random import sample
from operator import attrgetter
from dataclasses import dataclass
-
-
-@dataclass
-class Court:
- number: int
- status: bool
+from typing import Tuple
@dataclass
class CourtList:
total: int
- def __post_init__(self):
- self.courts = [Court(i + 1, True) for i in range(self.total)]
+ def __post_init__(self) -> None:
+ self.courts = {i + 1: True for i in range(self.total)}
- def get_court(self, court_number: int):
- return [court for court in self.courts if court.number == court_number]
+ def get_court_status(self, court_number: int) -> bool:
+ return self.courts[court_number]
- def toggle_court(self, court_number: int):
- self.courts = [
- (
- Court(
- number=court_number,
- status=not court.status,
- )
- if court_number == court.number
- else court
- )
- for court in self.courts
- ]
+ def toggle_court_status(self, court_number: int) -> None:
+ current_status = self.courts[court_number]
+ self.courts[court_number] = not current_status
+ return not current_status
+
+ def separate_courts(self) -> Tuple[dict, dict]:
+ active_courts = {k: v for k, v in self.courts.items() if v}
+ inactive_courts = {k: v for k, v in self.courts.items() if not v}
+ return active_courts, inactive_courts
@dataclass
@@ -96,7 +88,7 @@ class Team:
@dataclass
class Game:
- court: Court
+ court: int
team1: Team
team2: Team
@@ -105,36 +97,33 @@ DUMMY_PLAYER = Player(name="-")
DUMMY_TEAM = Team(player1=DUMMY_PLAYER, player2=DUMMY_PLAYER)
-def create_dummy_games(courts: list[Court]):
- return [Game(court, DUMMY_TEAM, DUMMY_TEAM) for court in courts]
+def create_dummy_games(courts: dict):
+ return [Game(court, DUMMY_TEAM, DUMMY_TEAM) for court, _ in courts.items()]
RESERVED_PLAYER = Player(name="Reserved")
RESERVED_TEAM = Team(player1=RESERVED_PLAYER, player2=RESERVED_PLAYER)
-def create_reserved_games(courts: list[Court]):
- return [Game(court, RESERVED_TEAM, RESERVED_TEAM) for court in courts]
+def create_reserved_games(courts: dict):
+ return [Game(court, RESERVED_TEAM, RESERVED_TEAM) for court, _ in courts.items()]
PLAYER_PER_COURT = 4
-def create_single_game(court: Court, players: list[Player]):
+def create_game(court: int, players: list[Player]):
team1 = Team(player1=players[0], player2=players[3])
team2 = Team(player1=players[1], player2=players[2])
return Game(court, team1, team2)
-def create_possible_games(court_list: list[Court], players: list[Player]):
+def create_possible_games(courts: dict, players: list[Player]):
+ count = len(players)
clumped_players = [
- players[i : i + PLAYER_PER_COURT]
- for i in range(0, len(players), PLAYER_PER_COURT)
- ]
- games = [
- create_single_game(court, clump)
- for court, clump in zip(court_list, clumped_players)
+ players[i : i + PLAYER_PER_COURT] for i in range(0, count, PLAYER_PER_COURT)
]
+ games = [create_game(court, clump) for court, clump in zip(courts, clumped_players)]
return games
@@ -142,42 +131,47 @@ def create_possible_games(court_list: list[Court], players: list[Player]):
class GameList:
def clear(self, court_list: CourtList):
- courts = court_list.courts
- active_courts = [court for court in courts if court.status]
- inactive_courts = [court for court in courts if not court.status]
+ active_courts, inactive_courts = court_list.separate_courts()
dummy_games = create_dummy_games(active_courts)
reserved_games = create_reserved_games(inactive_courts)
games = dummy_games + reserved_games
- games.sort(key=attrgetter("court.number"))
+ games.sort(key=attrgetter("court"))
self.games = games
- def create_random_games(self, court_list: CourtList, player_list: PlayerList):
+ def create_random_games(self, courts: CourtList, player_list: PlayerList):
active_players = player_list.get_active_players()
- active_courts = [court for court in court_list.courts if court.status]
- inactive_courts = [court for court in court_list.courts if not court.status]
+ active_courts, inactive_courts = courts.separate_courts()
possible_games = floor(len(active_players) / PLAYER_PER_COURT)
+ if possible_games > len(active_courts):
+ possible_games = len(active_courts)
current_players = sample(active_players, possible_games * PLAYER_PER_COURT)
active_games = create_possible_games(
- active_courts[:possible_games], current_players
+ dict(list(active_courts.items())[:possible_games]), current_players
+ )
+ dummy_games = create_dummy_games(
+ dict(list(active_courts.items())[possible_games:])
)
- dummy_games = create_dummy_games(active_courts[possible_games:])
reserved_games = create_reserved_games(inactive_courts)
games = active_games + dummy_games + reserved_games
- games.sort(key=attrgetter("court.number"))
+ games.sort(key=attrgetter("court"))
self.games = games
- def create_skilled_games(self, court_list: CourtList, player_list: PlayerList):
+ def create_skilled_games(self, courts: CourtList, player_list: PlayerList):
active_players = player_list.get_active_players()
- active_courts = [court for court in court_list.courts if court.status]
- inactive_courts = [court for court in court_list.courts if not court.status]
+ active_courts, inactive_courts = courts.separate_courts()
possible_games = floor(len(active_players) / PLAYER_PER_COURT)
+ if possible_games > len(active_courts):
+ possible_games = len(active_courts)
current_players = sample(active_players, possible_games * PLAYER_PER_COURT)
current_players.sort(key=attrgetter("skill"))
+
active_games = create_possible_games(
- active_courts[:possible_games], current_players
+ dict(list(active_courts.items())[:possible_games]), current_players
+ )
+ dummy_games = create_dummy_games(
+ dict(list(active_courts.items())[possible_games:])
)
- dummy_games = create_dummy_games(active_courts[possible_games:])
reserved_games = create_reserved_games(inactive_courts)
games = active_games + dummy_games + reserved_games
- games.sort(key=attrgetter("court.number"))
+ games.sort(key=attrgetter("court"))
self.games = games
diff --git a/templates/court.j2 b/templates/court.j2
index 425e7d5..5eeb65a 100644
--- a/templates/court.j2
+++ b/templates/court.j2
@@ -1 +1 @@
-<button class={% if court.status %} "button is-success" {% else %} "button is-danger" {% endif %} hx-post="{{ "/court-toggle/" ~ court.number}}" hx-trigger="click" hx-swap="outerHTML">{{ court.number }}</button> \ No newline at end of file
+<button class={% if status %} "button is-success" {% else %} "button is-danger" {% endif %} hx-post="{{ "/court-toggle/" ~ id}}" hx-trigger="click" hx-swap="outerHTML">{{ id }}</button> \ No newline at end of file
diff --git a/templates/courts.j2 b/templates/courts.j2
index 64fd44a..4e3cb3a 100644
--- a/templates/courts.j2
+++ b/templates/courts.j2
@@ -1,8 +1,8 @@
<div class="fixed-grid has-12-cols">
<div class="grid">
-{% for court in courts %}
+{% for key, value in courts.items() %}
<div class="cell">
- <button class={% if court.status %} "button is-success" {% else %} "button is-danger" {% endif %} hx-post="{{ "/court-toggle/" ~ court.number}}" hx-trigger="click" hx-swap="outerHTML">{{ court.number }}</button>
+ <button class={% if value %} "button is-success" {% else %} "button is-danger" {% endif %} hx-post="{{ "/court-toggle/" ~ key}}" hx-trigger="click" hx-swap="outerHTML">{{ key }}</button>
</div>
{% endfor %}
</div>