-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp_types.py
More file actions
120 lines (83 loc) · 3.29 KB
/
app_types.py
File metadata and controls
120 lines (83 loc) · 3.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# app_types.py
"""
Type aliases for the Badminton App.
This module defines type aliases to improve code readability and provide
semantic meaning to complex type hints.
"""
from dataclasses import dataclass, field
from typing import Any
from enum import Enum
# =============================================================================
# Basic Type Aliases
# =============================================================================
class Gender(str, Enum):
"""Player gender enumeration for strict type checking."""
MALE = "M"
FEMALE = "F"
# A player's name (unique identifier)
PlayerName = str
# A pair of player names (used for partners/opponents tracking)
PlayerPair = tuple[PlayerName, PlayerName]
# =============================================================================
# Optimizer Type Aliases
# =============================================================================
# Mapping of player names to their normalized ratings (0-5 scale)
PlayerRatings = dict[PlayerName, float]
# Mapping of player names to their tier ratings (Z-score normalized, 0-5 scale)
TierRatings = dict[PlayerName, float]
# Mapping of player names to their real skill (direct normalized, 0-5 scale)
RealSkills = dict[PlayerName, float]
# Mapping of player names to their gender ('M' or 'F')
PlayerGenders = dict[PlayerName, Gender]
# Gender statistics: maps Gender -> (mean_mu, std_mu, player_count)
GenderStats = dict[Gender, tuple[float, float, int]]
# History of how often player pairs have shared a court together
# Value is (partner_count, opponent_count) for debugging and weighted penalty calculation
CourtHistory = dict[PlayerPair, tuple[int, int]]
# Graph of required partner relationships (player -> set of players they must partner with)
RequiredPartners = dict[PlayerName, set[PlayerName]]
# =============================================================================
# Match Data Classes
# =============================================================================
@dataclass
class SinglesMatch:
"""A singles match assignment.
Attributes:
court: Court number (1-indexed)
player_1: First player's name
player_2: Second player's name
"""
court: int
player_1: PlayerName
player_2: PlayerName
@dataclass
class DoublesMatch:
"""A doubles match assignment.
Attributes:
court: Court number (1-indexed)
team_1: Tuple of player names for team 1
team_2: Tuple of player names for team 2
"""
court: int
team_1: PlayerPair
team_2: PlayerPair
# A single match assignment
Match = SinglesMatch | DoublesMatch
# List of match assignments for a round
MatchList = list[Match]
# =============================================================================
# Result Data Classes
# =============================================================================
@dataclass
class OptimizerResult:
"""Result from the match optimizer.
Attributes:
matches: List of match assignments, or None if optimization failed
court_history: Updated court history after this round
success: Whether the optimization succeeded
"""
matches: MatchList | None
court_history: CourtHistory
success: bool = field(init=False)
def __post_init__(self) -> None:
self.success = self.matches is not None