def __init__(self, players): """ Creates a new ``Squad`` from the given players and decorates it with cumulative delta mean data. Args: players (list): The players in the ``Squad``. """ self.delegate = Squad(players)
def test_single_player_squad(self): player = Player('Dwayne', 'Johnson', skating=10, shooting=20, checking=30) squad = Squad([player]) self.assertEqual(player.skating, squad.skating_average) self.assertEqual(player.shooting, squad.shooting_average) self.assertEqual(player.checking, squad.checking_average)
def make_squads_minimize_cumulative_delta_mean(num_squads, players): """ Makes closely matched squads from the given set of players. Algorithm steps: 1. Calculate S(i) - Mean(i) for each player, where S(i) is the player's rating for the i-th skill, and Mean(i) is the mean value of the i-th skill over all players. S(i) - Mean(i) = Delta(i) 2. Calculate the cumulative delta mean for each player. The cumulative delta mean is the sum of |Delta(i)| for each of the player's i skills. 3. Sort the players in order of descending cumulative delta mean. 4. If applicable, place the players with the largest cumulative delta mean on the waiting list. These are our biggest outliers. 5. If players were moved to the waiting list, repeat steps (1-3) on the reduced set of players. We want to recalculate Delta(i) and the cumulative delta mean for each player with the outliers removed. 6. Take the N players with the largest cumulative delta mean, and assign 1 to each of the N squads. 7. While there are players left, round robin through each of the N squads and pick the 'best fit' available player and add it to the squad. The best fit player is the player who results in the lowest cumulative delta mean for the squad. Args: num_squads (int): The number of squads to make. players (list): The available players. Returns: list(``Squad``), list(``Player``): A (squads, waiting_list) tuple. """ _validate_arguments(num_squads, players) waiting_list = [] if num_squads == players: # handle special case where each squad has a single player and the waiting list is empty return [Squad([p]) for p in players], waiting_list players = _decorate_players_with_delta_mean_data(players) players.sort(key=lambda p: p.cumulative_delta_mean, reverse=True) players_per_squad = get_players_per_squad(num_squads, players) players_on_wait_list = len(players) - players_per_squad*num_squads waiting_list = [players.pop(0) for _ in range(players_on_wait_list)] if len(waiting_list) > 0: # recalculate the means and re-decorate with delta mean data now that the outliers are removed players = _decorate_players_with_delta_mean_data(players) players.sort(key=lambda p: p.cumulative_delta_mean, reverse=True) # initialize the required number of squads, each with one of the outlier players squads = [DeltaMeanSquadDecorator([players.pop(0)]) for _ in range(num_squads)] while len(players) > 0: for squad in squads: _append_best_fit_for_squad(squad, players) return squads, waiting_list
def test_get_decorated_squad_attributes(self): player1 = Player('name1', 'lastName1', skating=34, shooting=89, checking=10) player2 = Player('name2', 'lastName2', skating=0, shooting=55, checking=98) (mean_skating, mean_shooting, mean_checking) = (60, 55, 40) squad = Squad([DeltaMeanPlayerDecorator(player1, mean_skating, mean_shooting, mean_checking), DeltaMeanPlayerDecorator(player2, mean_skating, mean_shooting, mean_checking)]) decorated_squad = DeltaMeanSquadDecorator(squad.players) # the attributes of the Squad should be accessible from the decorated object self.assertEqual(squad.players, decorated_squad.players) self.assertEqual(squad.skating_average, decorated_squad.skating_average) self.assertEqual(squad.shooting_average, decorated_squad.shooting_average) self.assertEqual(squad.checking_average, decorated_squad.checking_average) # test decorator methods self.assertEqual(148, decorated_squad.cumulative_delta_mean)
def test_modify_players(self): squad = Squad() self.assertIsNone(squad.skating_average) self.assertIsNone(squad.shooting_average) self.assertIsNone(squad.checking_average) new_player = Player('Brody', 'Harrison', skating=10, shooting=15, checking=22) squad.players.append(new_player) self.assertEqual(10, squad.skating_average) self.assertEqual(15, squad.shooting_average) self.assertEqual(22, squad.checking_average)
def test_multi_player_squad(self): player1 = Player('Richard', 'Wagner', skating=20, shooting=55, checking=25) player2 = Player('Fred', 'Couples', skating=10, shooting=5, checking=30) player3 = Player('Geena', 'Davis', skating=90, shooting=30, checking=5) squad = Squad([player1, player2, player3]) self.assertEqual(40, squad.skating_average) self.assertEqual(30, squad.shooting_average) self.assertEqual(20, squad.checking_average)
def make_random_squads(num_squads, players): """ Makes squads by choosing players at random, without regard for their individual skill ratings. This algorithm isn't intended to be used in production, but it will serve as a useful baseline for evaluating other potential algorithms. Args: num_squads (int): The number of squads to build. players list(``Player``): The list of players to choose from. Returns: list(``Squad``), list(``Player``): A (squads, waiting_list) tuple. """ _validate_arguments(num_squads, players) waiting_list = list(players) shuffle(waiting_list) squads = [] players_per_squad = get_players_per_squad(num_squads, players) for _ in range(num_squads): squad = Squad([waiting_list.pop(0) for _ in range(players_per_squad)]) squads.append(squad) return squads, waiting_list
def test_empty_squad(self): squad = Squad() self.assertIsNone(squad.skating_average) self.assertIsNone(squad.shooting_average) self.assertIsNone(squad.checking_average)