diff options
Diffstat (limited to 'src/match_up')
| -rw-r--r-- | src/match_up/controller.py | 54 | ||||
| -rw-r--r-- | src/match_up/data.py | 1 | ||||
| -rw-r--r-- | src/match_up/model.py | 71 | ||||
| -rw-r--r-- | src/match_up/routes.py | 4 | ||||
| -rw-r--r-- | src/match_up/utilities.py | 100 |
5 files changed, 130 insertions, 100 deletions
diff --git a/src/match_up/controller.py b/src/match_up/controller.py index 4c7119f..b00bf6b 100644 --- a/src/match_up/controller.py +++ b/src/match_up/controller.py @@ -2,7 +2,14 @@ from typing import Tuple from operator import attrgetter from match_up.data import Game, PLAYER_PER_COURT from match_up.model import Player, PlayerList, CourtList -from match_up.utilities import _create_placeholders, _select_players, _create_shuffle_games, _create_team_games +from match_up.utilities import ( + _create_placeholders, + _select_players, + _create_shuffle_games, + _create_team_games, + separate_teams_and_players, + split_courts, +) class RoundGenerator: @@ -37,33 +44,20 @@ class RoundGenerator: required_player_count = len(used_courts) * PLAYER_PER_COURT active_players = self.players.get_players() if group_by_team: - unique_team_id = {player.team for player in active_players} - grouped_players_by_team = {team_id: [] for team_id in unique_team_id} - for player in active_players: - team = player.team - grouped_players_by_team[team].append(player) - active_teams = {} - players_without_team = [] - for team_id in grouped_players_by_team: - if team_id == 0: - players_without_team += [player for player in grouped_players_by_team[team_id]] - else: - if len(grouped_players_by_team[team_id]) >= 4: - active_teams[team_id] = grouped_players_by_team[team_id] - else: - players_without_team += [player for player in grouped_players_by_team[team_id]] - - regular_courts = len(used_courts) - len(active_teams) - reg_courts = {A:N for (A,N) in [x for x in used_courts.items()][:regular_courts]} - team_courts = {A:N for (A,N) in [x for x in used_courts.items()][regular_courts:]} - - required_player_count = required_player_count - (PLAYER_PER_COURT * len(active_teams)) - selected_players_without_team = _select_players(players_without_team, required_player_count) - regular_games = _create_shuffle_games(reg_courts, selected_players_without_team, total_levels) - - team_games, selected_players_with_team = _create_team_games(team_courts, active_teams) - - selected_players = selected_players_without_team + selected_players_with_team + active_teams, team_less_players = separate_teams_and_players(active_players) + regular_court_count = len(used_courts) - len(active_teams) + regular_courts, team_courts = split_courts(used_courts, regular_court_count) + new_player_count = required_player_count - ( + PLAYER_PER_COURT * len(active_teams) + ) + regular_players = _select_players(team_less_players, new_player_count) + regular_games = _create_shuffle_games( + regular_courts, regular_players, total_levels + ) + team_games, selected_team_players = _create_team_games( + team_courts, active_teams + ) + selected_players = regular_players + selected_team_players games = regular_games + team_games else: selected_players = _select_players(active_players, required_player_count) @@ -80,7 +74,9 @@ class RoundGenerator: def propose(self, levels: int, group_by_team: bool) -> list[Game]: inactive_games = self._create_inactive_games() - active_games, selected_players = self._create_active_games(levels, group_by_team) + active_games, selected_players = self._create_active_games( + levels, group_by_team + ) games = active_games + inactive_games games.sort(key=attrgetter("court")) self.proposed_games = games diff --git a/src/match_up/data.py b/src/match_up/data.py index d8996fe..c00dde2 100644 --- a/src/match_up/data.py +++ b/src/match_up/data.py @@ -22,7 +22,6 @@ class Player(BASE): status = Column("status", Integer) count = Column("count", Integer) - def __init__( self, id: int, diff --git a/src/match_up/model.py b/src/match_up/model.py index 52d72b2..467310b 100644 --- a/src/match_up/model.py +++ b/src/match_up/model.py @@ -1,12 +1,23 @@ from math import floor from typing import Tuple from os.path import isfile +from pandas import read_csv from dataclasses import dataclass from importlib.resources import path +from random import getrandbits, randint from sqlalchemy.orm import sessionmaker from sqlalchemy import create_engine, not_ -from match_up.data import PLAYER_PER_COURT, BASE, Player, DisplayPlayer -from match_up.utilities import _init_database_from_csv, _init_random_database +from names import get_first_name, get_last_name +from match_up.data import ( + MIN_LEVEL, + MAX_LEVEL, + PLAYER_PER_COURT, + BASE, + GUEST_LEVELS, + GUESTS_PER_LEVEL, + Player, + DisplayPlayer, +) @dataclass @@ -33,6 +44,62 @@ class CourtList: return active_courts, inactive_courts +def _init_guests(session) -> None: + for level_id, level in enumerate(GUEST_LEVELS): + for player_id in range(GUESTS_PER_LEVEL): + unique_id = (level_id * GUESTS_PER_LEVEL) + player_id + 1 + player = Player( + id=-unique_id, + first="Guest", + last=str(unique_id), + level=level, + status=False, + count=0, + ) + session.add(player) + session.commit() + + +def _init_database_from_csv(session, csv_location: str) -> None: + data = read_csv(csv_location) + session.query(Player).delete() + for _, entry in data.iterrows(): + player = Player( + id=entry["id"], + first=entry["first"], + last=entry["last"], + level=entry["skill"], + team=entry["team"], + status=False, + count=0, + ) + session.add(player) + session.commit() + _init_guests(session) + + +def _init_random_database(session, player_count: int = 80) -> None: + total_teams = 5 + players_per_team = 5 + for i in range(player_count): + if i < total_teams * players_per_team: + team = floor(i / players_per_team) + 1 + else: + team = 0 + player = Player( + id=i, + first=get_first_name(), + last=get_last_name(), + level=randint(MIN_LEVEL, MAX_LEVEL), + team=team, + status=bool(getrandbits(1)), + count=0, + ) + session.add(player) + session.commit() + _init_guests(session) + + class PlayerList: def __init__(self, csv_location=None) -> None: diff --git a/src/match_up/routes.py b/src/match_up/routes.py index f9cd2fa..e5a3b99 100644 --- a/src/match_up/routes.py +++ b/src/match_up/routes.py @@ -19,7 +19,9 @@ def get_controls(): def get_random_games(): levels = int(request.form["levels"].split()[0]) team_practice = request.form["team"] == "Teams" - return render_template("games.j2", games=_rg.propose(levels, team_practice), title="Proposal") + return render_template( + "games.j2", games=_rg.propose(levels, team_practice), title="Proposal" + ) @_app.route("/confirm", methods=["POST"]) diff --git a/src/match_up/utilities.py b/src/match_up/utilities.py index fa82b58..7140a5f 100644 --- a/src/match_up/utilities.py +++ b/src/match_up/utilities.py @@ -1,17 +1,7 @@ -from math import floor from typing import Tuple -from random import shuffle -from pandas import read_csv -from random import randint, getrandbits, sample -from names import get_first_name, get_last_name +from random import shuffle, sample from match_up.data import Player, DisplayPlayer, Team, Game -from match_up.data import ( - MIN_LEVEL, - MAX_LEVEL, - PLAYER_PER_COURT, - GUESTS_PER_LEVEL, - GUEST_LEVELS, -) +from match_up.data import MAX_LEVEL, PLAYER_PER_COURT def _shuffle_two_lists(a: list, b: list) -> Tuple[list, list]: @@ -71,7 +61,9 @@ def _create_groups_of_four_players( return court_players -def _create_shuffle_games(courts: dict, players: list[Player], levels: int) -> list[Game]: +def _create_shuffle_games( + courts: dict, players: list[Player], levels: int +) -> list[Game]: court_players = _create_groups_of_four_players(players, levels) games = [] for court, players in zip(courts, court_players): @@ -84,13 +76,14 @@ def _create_shuffle_games(courts: dict, players: list[Player], levels: int) -> l games.append(Game(court, team1, team2)) return games + def _create_team_games(courts: dict, teams: dict) -> tuple[list[Game], list[Player]]: games = [] selected_players = [] for court, (_, players) in zip(courts, teams.items()): players = sample(players, PLAYER_PER_COURT) - selected_players.append(players) - players.sort(key=lambda x : x.level, reverse=True) + selected_players += players + players.sort(key=lambda x: x.level, reverse=True) team1 = Team( player1=DisplayPlayer(players[0]), player2=DisplayPlayer(players[3]) ) @@ -101,57 +94,30 @@ def _create_team_games(courts: dict, teams: dict) -> tuple[list[Game], list[Play return games, selected_players -def _init_guests(session) -> None: - for level_id, level in enumerate(GUEST_LEVELS): - for player_id in range(GUESTS_PER_LEVEL): - unique_id = (level_id * GUESTS_PER_LEVEL) + player_id + 1 - player = Player( - id=-unique_id, - first="Guest", - last=str(unique_id), - level=level, - status=False, - count=0, - ) - session.add(player) - session.commit() - - -def _init_database_from_csv(session, csv_location: str) -> None: - data = read_csv(csv_location) - session.query(Player).delete() - for _, entry in data.iterrows(): - player = Player( - id=entry["id"], - first=entry["first"], - last=entry["last"], - level=entry["skill"], - team=entry["team"], - status=False, - count=0, - ) - session.add(player) - session.commit() - _init_guests(session) +def separate_teams_and_players(players: list[Player]) -> Tuple[dict, list[Player]]: + unique_team_id = {player.team for player in players} + grouped_players_by_team = {team_id: [] for team_id in unique_team_id} + for player in players: + team = player.team + grouped_players_by_team[team].append(player) + active_teams = {} + players_without_team = [] + for team_id in grouped_players_by_team: + if team_id == 0: + players_without_team += [ + player for player in grouped_players_by_team[team_id] + ] + else: + if len(grouped_players_by_team[team_id]) >= 4: + active_teams[team_id] = grouped_players_by_team[team_id] + else: + players_without_team += [ + player for player in grouped_players_by_team[team_id] + ] + return active_teams, players_without_team -def _init_random_database(session, player_count: int = 80) -> None: - total_teams = 5 - players_per_team = 5 - for i in range(player_count): - if i < total_teams * players_per_team: - team = floor(i / players_per_team) + 1 - else: - team = 0 - player = Player( - id=i, - first=get_first_name(), - last=get_last_name(), - level=randint(MIN_LEVEL, MAX_LEVEL), - team=team, - status=bool(getrandbits(1)), - count=0, - ) - session.add(player) - session.commit() - _init_guests(session) +def split_courts(courts: dict, n) -> Tuple[dict, dict]: + first_half = {k: v for (k, v) in [x for x in courts.items()][:n]} + second_half = {k: v for (k, v) in [x for x in courts.items()][n:]} + return first_half, second_half |
