diff --git a/draftfast/constants/positions.py b/draftfast/constants/positions.py index fb83377..31d182a 100644 --- a/draftfast/constants/positions.py +++ b/draftfast/constants/positions.py @@ -3,7 +3,13 @@ POSITIONS_BY_SITE_BY_LEAGUE = { "DRAFT_KINGS": { - "NBA": [["PG", 1, 3], ["SG", 1, 3], ["SF", 1, 3], ["PF", 1, 3], ["C", 1, 2]], + "NBA": [ + ["PG", 1, 3], + ["SG", 1, 3], + ["SF", 1, 3], + ["PF", 1, 3], + ["C", 1, 2], + ], "NBA_SHOWDOWN": [ ["CPT", 1, 1], ["FLEX", 5, 5], diff --git a/draftfast/csv_parse/salary_download.py b/draftfast/csv_parse/salary_download.py index f8da5b5..38989dc 100644 --- a/draftfast/csv_parse/salary_download.py +++ b/draftfast/csv_parse/salary_download.py @@ -54,7 +54,9 @@ def generate_players_from_csvs( errors, ) - with open(salary_file_location, "r", encoding=encoding, errors=errors) as csv_file: + with open( + salary_file_location, "r", encoding=encoding, errors=errors + ) as csv_file: csv_data = csv.DictReader(csv_file) pos_key = "Position" is_nhl = ruleset and ruleset.league == "NHL" @@ -200,7 +202,9 @@ def _parse_fd_mvp_nfl_row(pos: str, row: dict) -> List[ShowdownPlayer]: ] -def _parse_mvp_mlb_row(pos: str, row: dict, ruleset: RuleSet) -> List[ShowdownPlayer]: +def _parse_mvp_mlb_row( + pos: str, row: dict, ruleset: RuleSet +) -> List[ShowdownPlayer]: """ FanDuel CSVs give all players without breaking out an MVP / STAR position. Unlike DK, salary does not change here. diff --git a/draftfast/csv_parse/uploaders.py b/draftfast/csv_parse/uploaders.py index da4c6ad..e3262a0 100644 --- a/draftfast/csv_parse/uploaders.py +++ b/draftfast/csv_parse/uploaders.py @@ -47,7 +47,9 @@ def map_pids(pid_file, encoding, errors, game=DRAFT_KINGS): ) f.close() - f = islice(open(pid_file, "r", encoding=encoding, errors=errors), n, None) + f = islice( + open(pid_file, "r", encoding=encoding, errors=errors), n, None + ) reader = csv.DictReader(f, fieldnames=fields) for line in reader: # DraftKings adds spaces to DST for NFL @@ -62,7 +64,11 @@ def map_pids(pid_file, encoding, errors, game=DRAFT_KINGS): class CSVUploader(object): def __init__( - self, pid_file, upload_file="./upload.csv", encoding="utf-8", errors="replace" + self, + pid_file, + upload_file="./upload.csv", + encoding="utf-8", + errors="replace", ): self.upload_file = upload_file self.encoding = encoding @@ -222,5 +228,8 @@ def write_rosters(self, rosters): writer.writerow(self.HEADERS) for roster in rosters: writer.writerow( - [p.get_player_id(self.pid_map) for p in roster.sorted_players()] + [ + p.get_player_id(self.pid_map) + for p in roster.sorted_players() + ] ) diff --git a/draftfast/exposure.py b/draftfast/exposure.py index da1e147..7b9dd9b 100644 --- a/draftfast/exposure.py +++ b/draftfast/exposure.py @@ -47,9 +47,13 @@ def get_exposure_args( exposures[p.name] = exposures.get(p.name, 0) + 1 if use_random: - return get_exposure_args_random(exposures, exposure_bounds, n, random_seed) + return get_exposure_args_random( + exposures, exposure_bounds, n, random_seed + ) - return get_exposure_args_deterministic(exposures, existing_rosters, exposure_bounds) + return get_exposure_args_deterministic( + exposures, existing_rosters, exposure_bounds + ) def get_exposure_args_deterministic( @@ -78,7 +82,9 @@ def get_exposure_args_deterministic( } -def get_exposure_args_random(exposures, exposure_bounds, n, random_seed) -> dict: +def get_exposure_args_random( + exposures, exposure_bounds, n, random_seed +) -> dict: locked = [] for bound in exposure_bounds: @@ -129,7 +135,9 @@ def get_exposure_table(rosters, bounds): exposures[p.name] = exposures.get(p.name, 0) + 1 players[p.name] = p - exposures = OrderedDict(sorted(exposures.items(), key=lambda t: t[1], reverse=True)) + exposures = OrderedDict( + sorted(exposures.items(), key=lambda t: t[1], reverse=True) + ) table_data = [] headers = [ @@ -162,7 +170,9 @@ def get_exposure_table(rosters, bounds): continue - table_data.append(players[name].to_exposure_table_row(num, s_min, s_max)) + table_data.append( + players[name].to_exposure_table_row(num, s_min, s_max) + ) table = AsciiTable(table_data) table.justify_columns[4] = "right" diff --git a/draftfast/lineup_constraints.py b/draftfast/lineup_constraints.py index b484897..5703ced 100644 --- a/draftfast/lineup_constraints.py +++ b/draftfast/lineup_constraints.py @@ -311,7 +311,9 @@ def _bounds_str(self): def _exact_bounds_sanity_check(self): if self.exact <= 0: - raise ConstraintException("Exact bound may not less than or equal to zero") + raise ConstraintException( + "Exact bound may not less than or equal to zero" + ) if self.exact >= len(self.players): raise ConstraintException( "Exact bound may not be greater than or equal to number " @@ -329,7 +331,9 @@ def _ub_lb_bounds_sanity_check(self): ) if self.ub < self.lb: raise ConstraintException( - "Upper bound for {!r} cannot be less than lower bound.".format(self) + "Upper bound for {!r} cannot be less than lower bound.".format( + self + ) ) if self.ub > len(self.players) or self.lb > len(self.players): raise ConstraintException( diff --git a/draftfast/optimize.py b/draftfast/optimize.py index 2b8f33a..40b52dc 100644 --- a/draftfast/optimize.py +++ b/draftfast/optimize.py @@ -88,7 +88,10 @@ def run( PLAYER COUNT: {} """.format( - optimizer_settings, constraints, player_settings, len(players or []) + optimizer_settings, + constraints, + player_settings, + len(players or []), ) ) return None diff --git a/draftfast/optimizer.py b/draftfast/optimizer.py index 13ce404..b143ab2 100644 --- a/draftfast/optimizer.py +++ b/draftfast/optimizer.py @@ -1,7 +1,10 @@ from typing import List from ortools.linear_solver import pywraplp from draftfast.settings import OptimizerSettings -from draftfast.dke_exceptions import InvalidBoundsException, PlayerBanAndLockException +from draftfast.dke_exceptions import ( + InvalidBoundsException, + PlayerBanAndLockException, +) from draftfast.orm import Player from draftfast.rules import RuleSet from draftfast.lineup_constraints import LineupConstraints @@ -131,7 +134,9 @@ def _set_player_constraints(self): ub = 0 if (p.ban or p.position_ban) else 1 if lb > ub: - raise InvalidBoundsException("Invalid bounds for {}".format(p.name)) + raise InvalidBoundsException( + "Invalid bounds for {}".format(p.name) + ) if (p.multi_position or self.showdown) and not ( p.position_lock or p.position_ban @@ -208,7 +213,10 @@ def _set_stack(self): stack_cap.SetCoefficient(self.variables[i], 1) self._set_stacking_type( - stack_lock_pos, stack_lock_eligible_pos, stack_team, stack.count + stack_lock_pos, + stack_lock_eligible_pos, + stack_team, + stack.count, ) def _set_stacking_type( @@ -236,7 +244,9 @@ def _set_stacking_type( self.solver.Sum(skillplayers_on_team) >= self.solver.Sum(locked_on_team) ) - self.solver.Add((self.solver.Sum(skillplayers_on_team)) >= count - 1) + self.solver.Add( + (self.solver.Sum(skillplayers_on_team)) >= count - 1 + ) def _set_combo(self): if self.settings: @@ -277,7 +287,8 @@ def _set_no_opp_defense(self): offensive_against = [ self.variables[i] for i, p in enumerated_players - if p.pos in offensive_pos and p.is_opposing_team_in_match_up(team) + if p.pos in offensive_pos + and p.is_opposing_team_in_match_up(team) ] # TODO this is gross for showdown @@ -323,7 +334,9 @@ def _set_custom_rules(self): for i, p in self.enumerated_players if rule.group_b(p) ] - self.solver.Add(rule.comparison(self.solver.Sum, group_a, group_b)) + self.solver.Add( + rule.comparison(self.solver.Sum, group_a, group_b) + ) def _set_positions(self): for position, min_limit, max_limit in self.position_limits: @@ -334,7 +347,11 @@ def _set_positions(self): position_cap.SetCoefficient(self.variables[i], 1) def _set_general_positions(self): - for general_position, min_limit, max_limit in self.general_position_limits: + for ( + general_position, + min_limit, + max_limit, + ) in self.general_position_limits: position_cap = self.solver.Constraint(min_limit, max_limit) for i, player in self.enumerated_players: @@ -368,9 +385,12 @@ def _set_min_teams(self): for i, p in self.enumerated_players if p.team == team ] - self.solver.Add(team_var <= self.solver.Sum(players_on_team)) self.solver.Add( - self.max_players_per_team >= self.solver.Sum(players_on_team) + team_var <= self.solver.Sum(players_on_team) + ) + self.solver.Add( + self.max_players_per_team + >= self.solver.Sum(players_on_team) ) if len(teams) > 0: diff --git a/draftfast/orm.py b/draftfast/orm.py index 3b6e7b5..b6ce88e 100644 --- a/draftfast/orm.py +++ b/draftfast/orm.py @@ -232,7 +232,9 @@ def __repr__(self): def identifier(self): if self.cached_id: return self.cached_id - self.cached_id = " ".join(sorted([x.roster_id for x in self.sorted_players()])) + self.cached_id = " ".join( + sorted([x.roster_id for x in self.sorted_players()]) + ) return self.cached_id @@ -370,7 +372,9 @@ def identifier(self): """ if self.cached_id: return self.cached_id - self.cached_id = " ".join(sorted([x.solver_id for x in self.sorted_players()])) + self.cached_id = " ".join( + sorted([x.solver_id for x in self.sorted_players()]) + ) return self.cached_id diff --git a/draftfast/pickem/pickem_optimize.py b/draftfast/pickem/pickem_optimize.py index 81e1acd..c8feadb 100644 --- a/draftfast/pickem/pickem_optimize.py +++ b/draftfast/pickem/pickem_optimize.py @@ -11,7 +11,9 @@ def optimize( constraints: LineupConstraints = LineupConstraints(), ): lineup_players = [] - all_players = list(filter(add_pickem_contraints(player_settings), all_players)) + all_players = list( + filter(add_pickem_contraints(player_settings), all_players) + ) if constraints.has_group_constraints(): raise NotImplementedError("Groups are not supported for pickem") diff --git a/draftfast/pickem/pickem_orm.py b/draftfast/pickem/pickem_orm.py index 07ed76a..a45537a 100644 --- a/draftfast/pickem/pickem_orm.py +++ b/draftfast/pickem/pickem_orm.py @@ -51,7 +51,11 @@ def __repr__(self): ] for p in self.players: table_data.append(p.to_table_row()) - return AsciiTable(table_data).table + "\n" + "Total: {}".format(self.total) + return ( + AsciiTable(table_data).table + + "\n" + + "Total: {}".format(self.total) + ) @property def players(self): diff --git a/draftfast/player_pool.py b/draftfast/player_pool.py index 8a3c916..0e8da44 100644 --- a/draftfast/player_pool.py +++ b/draftfast/player_pool.py @@ -4,10 +4,14 @@ from draftfast.settings import PlayerPoolSettings -def filter_pool(pool: list, player_settings: PlayerPoolSettings) -> List[Player]: +def filter_pool( + pool: list, player_settings: PlayerPoolSettings +) -> List[Player]: if player_settings.randomize: for player in pool: - factor = 1 + runiform(-player_settings.randomize, player_settings.randomize) + factor = 1 + runiform( + -player_settings.randomize, player_settings.randomize + ) player.proj = player.proj * factor return list( diff --git a/draftfast/settings.py b/draftfast/settings.py index 3396fbc..bb51588 100644 --- a/draftfast/settings.py +++ b/draftfast/settings.py @@ -130,12 +130,16 @@ def __repr__(self): def __str__(self): lines = [] if self.stacks and len(self.stacks): - lines.append("Stacks: {}".format([(x.team, x.count) for x in self.stacks])) + lines.append( + "Stacks: {}".format([(x.team, x.count) for x in self.stacks]) + ) if self.min_teams: lines.append("Min teams: {}".format(self.min_teams)) if self.no_offense_against_defense: lines.append( - "No offense against D: {}".format(self.no_offense_against_defense) + "No offense against D: {}".format( + self.no_offense_against_defense + ) ) if self.custom_rules: lines.append("Custom rules: {}".format(self.custom_rules)) @@ -156,7 +160,11 @@ def __init__(self, pid_file, upload_file, rule_set, rosters): class Stack(object): def __init__( - self, team: str, count: int, stack_lock_pos=None, stack_eligible_pos=None + self, + team: str, + count: int, + stack_lock_pos=None, + stack_eligible_pos=None, ): self.team = team self.count = count diff --git a/draftfast/test/test_csgo_showdown.py b/draftfast/test/test_csgo_showdown.py index 0dced7e..40861a6 100644 --- a/draftfast/test/test_csgo_showdown.py +++ b/draftfast/test/test_csgo_showdown.py @@ -10,19 +10,39 @@ def _build_mock_player_pool(): player_pool = [ - Player(name="A1", cost=5500, proj=100, pos="QB", team="X", matchup="X@Y"), - Player(name="A2", cost=5500, proj=41, pos="QB", team="X", matchup="X@Y"), - Player(name="A11", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y"), - Player(name="A3", cost=5500, proj=42, pos="WR", team="X", matchup="X@Y"), - Player(name="A4", cost=5500, proj=43, pos="WR", team="X", matchup="X@Y"), - Player(name="A5", cost=5500, proj=44, pos="WR", team="X", matchup="X@Y"), - Player(name="A6", cost=5500, proj=45, pos="RB", team="X", matchup="X@Y"), + Player( + name="A1", cost=5500, proj=100, pos="QB", team="X", matchup="X@Y" + ), + Player( + name="A2", cost=5500, proj=41, pos="QB", team="X", matchup="X@Y" + ), + Player( + name="A11", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A3", cost=5500, proj=42, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A4", cost=5500, proj=43, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A5", cost=5500, proj=44, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A6", cost=5500, proj=45, pos="RB", team="X", matchup="X@Y" + ), # Test that max players per team works. Everyone # on Y is projected for 1 point, under normal # opto should never be picked. - Player(name="A7", cost=5500, proj=1, pos="RB", team="Y", matchup="X@Y"), - Player(name="A8", cost=5500, proj=1, pos="RB", team="Y", matchup="X@Y"), - Player(name="A9", cost=5500, proj=1, pos="TE", team="Y", matchup="X@Y"), + Player( + name="A7", cost=5500, proj=1, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A8", cost=5500, proj=1, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A9", cost=5500, proj=1, pos="TE", team="Y", matchup="X@Y" + ), ] def capt_boost(p): diff --git a/draftfast/test/test_csv_upload.py b/draftfast/test/test_csv_upload.py index aa6310e..2f5ae74 100644 --- a/draftfast/test/test_csv_upload.py +++ b/draftfast/test/test_csv_upload.py @@ -44,7 +44,9 @@ def test_dk_nba_upload(): def test_dk_nfl_upload(): row = _get_first_written_row( game=rules.DRAFT_KINGS, - salary_file_location="{}/data/dk-nfl-upload-salaries.csv".format(CURRENT_DIR), + salary_file_location="{}/data/dk-nfl-upload-salaries.csv".format( + CURRENT_DIR + ), rule_set=rules.DK_NFL_RULE_SET, pid_file="{}/data/dk-nfl-upload.csv".format(CURRENT_DIR), Uploader=uploaders.DraftKingsNFLUploader, @@ -68,7 +70,9 @@ def test_dk_nfl_upload(): def test_dk_el_upload(): row = _get_first_written_row( game=rules.DRAFT_KINGS, - salary_file_location="{}/data/dk-euro-league-salaries.csv".format(CURRENT_DIR), + salary_file_location="{}/data/dk-euro-league-salaries.csv".format( + CURRENT_DIR + ), rule_set=rules.DK_EURO_LEAGUE_RULE_SET, pid_file="{}/data/dk-euro-league-pids.csv".format(CURRENT_DIR), Uploader=uploaders.DraftKingsELUploader, @@ -89,7 +93,9 @@ def test_dk_el_upload(): def test_dk_soccer_upload(): row = _get_first_written_row( game=rules.DRAFT_KINGS, - salary_file_location="{}/data/dk-soccer-salaries.csv".format(CURRENT_DIR), + salary_file_location="{}/data/dk-soccer-salaries.csv".format( + CURRENT_DIR + ), rule_set=rules.DK_SOCCER_RULE_SET, pid_file="{}/data/dk-soccer-pids.csv".format(CURRENT_DIR), Uploader=uploaders.DraftKingsSoccerUploader, @@ -160,7 +166,9 @@ def test_dk_nhl_uploader(): def test_pickem_nba_upload(): - salary_file_location = "{}/data/dk-nba-pickem-salaries.csv".format(CURRENT_DIR) + salary_file_location = "{}/data/dk-nba-pickem-salaries.csv".format( + CURRENT_DIR + ) players = salary_download.generate_players_from_csvs( game=rules.DRAFT_KINGS, salary_file_location=salary_file_location, diff --git a/draftfast/test/test_custom_rules.py b/draftfast/test/test_custom_rules.py index f0586e7..6b18a93 100644 --- a/draftfast/test/test_custom_rules.py +++ b/draftfast/test/test_custom_rules.py @@ -123,7 +123,9 @@ def test_if_one_then_two(): # Without this rule, A4 and A9 would never appear in the optimized # lineup. Both have a 0 point projection. - assertions.assertEqual(True, "A1" in names and "A9" in names and "A4" in names) + assertions.assertEqual( + True, "A1" in names and "A9" in names and "A4" in names + ) def test_never_two(): @@ -181,4 +183,6 @@ def test_team_rules(): optimizer_settings=settings, ) names = {p.name for p in roster.players} - assertions.assertEqual(True, "A100" in names and "A101" in names and "A10" in names) + assertions.assertEqual( + True, "A100" in names and "A101" in names and "A10" in names + ) diff --git a/draftfast/test/test_lineup_constraints.py b/draftfast/test/test_lineup_constraints.py index 62a0754..f98e47a 100644 --- a/draftfast/test/test_lineup_constraints.py +++ b/draftfast/test/test_lineup_constraints.py @@ -31,13 +31,17 @@ def test_constraint_set_eq(): lcs1 = LineupConstraints() lcs1.add_group_constraint(["Spencer Ware", "Amari Cooper"], 1) lcs1.ban(["Packers"]) - lcs1.add_group_constraint(["Eli Manning", "Russell Wilson", "Doug Martin"], (1, 3)) + lcs1.add_group_constraint( + ["Eli Manning", "Russell Wilson", "Doug Martin"], (1, 3) + ) lcs1.lock(["Will Fuller"]) lcs2 = LineupConstraints() lcs2.add_group_constraint(["Spencer Ware", "Amari Cooper"], 1) lcs2.ban(["Packers"]) - lcs2.add_group_constraint(["Eli Manning", "Russell Wilson", "Doug Martin"], (1, 3)) + lcs2.add_group_constraint( + ["Eli Manning", "Russell Wilson", "Doug Martin"], (1, 3) + ) lcs2.lock(["Will Fuller"]) assertions.assertEqual(lcs1, lcs2) @@ -47,7 +51,9 @@ def test_build_constraint_set(): lcs = LineupConstraints() lcs.add_group_constraint(["Spencer Ware", "Amari Cooper"], 1) lcs.ban(["Packers"]) - lcs.add_group_constraint(["Eli Manning", "Russell Wilson", "Doug Martin"], (1, 3)) + lcs.add_group_constraint( + ["Eli Manning", "Russell Wilson", "Doug Martin"], (1, 3) + ) lcs.lock(["Will Fuller"]) assertions.assertEqual(len(lcs), 4) diff --git a/draftfast/test/test_mlb.py b/draftfast/test/test_mlb.py index 9a85403..a880da8 100644 --- a/draftfast/test/test_mlb.py +++ b/draftfast/test/test_mlb.py @@ -84,7 +84,8 @@ def comp(sum, a, b): # Given 1B in optimized lineup group_a=lambda p: p.pos == "1B" and p.team == "ATL", # Ensure the stack is four players - group_b=lambda p: "1B" not in p.pos and p.team == "ATL", # batters only + group_b=lambda p: "1B" not in p.pos + and p.team == "ATL", # batters only comparison=comp, ) ) @@ -93,7 +94,8 @@ def comp(sum, a, b): # Given 1B in optimized lineup group_a=lambda p: p.pos == "1B" and p.team == "BOS", # Ensure the stack is four players - group_b=lambda p: "1B" not in p.pos and p.team == "BOS", # batters only + group_b=lambda p: "1B" not in p.pos + and p.team == "BOS", # batters only comparison=comp, ) ) @@ -108,6 +110,10 @@ def comp(sum, a, b): ) team_for_first = [p for p in roster.players if p.pos == "1B"][0].team total = len( - [p for p in roster.players if p.team == team_for_first and "P" not in p.pos] + [ + p + for p in roster.players + if p.team == team_for_first and "P" not in p.pos + ] ) assert total > 3, f"{total} below 4" diff --git a/draftfast/test/test_nba_general.py b/draftfast/test/test_nba_general.py index 13707ab..11ca926 100644 --- a/draftfast/test/test_nba_general.py +++ b/draftfast/test/test_nba_general.py @@ -29,7 +29,9 @@ def test_general_center(): def test_optimize_with_general(): def get_player_count_at_pos(roster, pos): - return len([p for p in roster.players if p.nba_general_position == pos]) + return len( + [p for p in roster.players if p.nba_general_position == pos] + ) current_dir = os.path.dirname(os.path.abspath(__file__)) players = sd.generate_players_from_csvs( @@ -62,6 +64,12 @@ def get_player_count_at_pos(roster, pos): assertions.assertEqual(rosters[i], rosters[0]) assertions.assertEqual(rosters[i].projected(), 279.53) - assertions.assertTrue(get_player_count_at_pos(rosters[i], "G") in [3, 4]) - assertions.assertTrue(get_player_count_at_pos(rosters[i], "F") in [3, 4]) - assertions.assertTrue(get_player_count_at_pos(rosters[i], "C") in [1, 2]) + assertions.assertTrue( + get_player_count_at_pos(rosters[i], "G") in [3, 4] + ) + assertions.assertTrue( + get_player_count_at_pos(rosters[i], "F") in [3, 4] + ) + assertions.assertTrue( + get_player_count_at_pos(rosters[i], "C") in [1, 2] + ) diff --git a/draftfast/test/test_nfl_showdown.py b/draftfast/test/test_nfl_showdown.py index ebc31d1..7337494 100644 --- a/draftfast/test/test_nfl_showdown.py +++ b/draftfast/test/test_nfl_showdown.py @@ -12,30 +12,78 @@ def _build_mock_player_pool(): player_pool = [ - Player(name="A1", cost=5500, proj=100, pos="QB", team="X", matchup="X@Y"), - Player(name="A2", cost=5500, proj=41, pos="QB", team="X", matchup="X@Y"), - Player(name="A11", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y"), - Player(name="A3", cost=5500, proj=42, pos="WR", team="X", matchup="X@Y"), - Player(name="A4", cost=5500, proj=43, pos="WR", team="X", matchup="X@Y"), - Player(name="A5", cost=5500, proj=44, pos="WR", team="X", matchup="X@Y"), - Player(name="A6", cost=5500, proj=45, pos="RB", team="X", matchup="X@Y"), - Player(name="A7", cost=5500, proj=46, pos="RB", team="X", matchup="X@Y"), - Player(name="A8", cost=5500, proj=47, pos="RB", team="X", matchup="X@Y"), - Player(name="A9", cost=5500, proj=48, pos="TE", team="X", matchup="X@Y"), - Player(name="A10", cost=5500, proj=49, pos="TE", team="X", matchup="X@Y"), - Player(name="A12", cost=5500, proj=51, pos="DST", team="X", matchup="X@Y"), - Player(name="A14", cost=5500, proj=40, pos="QB", team="Y", matchup="X@Y"), - Player(name="A21", cost=5500, proj=41, pos="QB", team="Y", matchup="X@Y"), - Player(name="A11", cost=5500, proj=50, pos="WR", team="Y", matchup="X@Y"), - Player(name="A31", cost=5500, proj=42, pos="WR", team="Y", matchup="X@Y"), - Player(name="A41", cost=5500, proj=43, pos="WR", team="Y", matchup="X@Y"), - Player(name="A51", cost=5500, proj=54, pos="WR", team="Y", matchup="X@Y"), - Player(name="A61", cost=5500, proj=45, pos="RB", team="Y", matchup="X@Y"), - Player(name="A71", cost=5500, proj=56, pos="RB", team="Y", matchup="X@Y"), - Player(name="A81", cost=5500, proj=47, pos="RB", team="Y", matchup="X@Y"), - Player(name="A91", cost=5500, proj=48, pos="TE", team="Y", matchup="X@Y"), - Player(name="A110", cost=5500, proj=49, pos="TE", team="Y", matchup="X@Y"), - Player(name="A112", cost=5500, proj=60, pos="DST", team="Y", matchup="X@Y"), + Player( + name="A1", cost=5500, proj=100, pos="QB", team="X", matchup="X@Y" + ), + Player( + name="A2", cost=5500, proj=41, pos="QB", team="X", matchup="X@Y" + ), + Player( + name="A11", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A3", cost=5500, proj=42, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A4", cost=5500, proj=43, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A5", cost=5500, proj=44, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A6", cost=5500, proj=45, pos="RB", team="X", matchup="X@Y" + ), + Player( + name="A7", cost=5500, proj=46, pos="RB", team="X", matchup="X@Y" + ), + Player( + name="A8", cost=5500, proj=47, pos="RB", team="X", matchup="X@Y" + ), + Player( + name="A9", cost=5500, proj=48, pos="TE", team="X", matchup="X@Y" + ), + Player( + name="A10", cost=5500, proj=49, pos="TE", team="X", matchup="X@Y" + ), + Player( + name="A12", cost=5500, proj=51, pos="DST", team="X", matchup="X@Y" + ), + Player( + name="A14", cost=5500, proj=40, pos="QB", team="Y", matchup="X@Y" + ), + Player( + name="A21", cost=5500, proj=41, pos="QB", team="Y", matchup="X@Y" + ), + Player( + name="A11", cost=5500, proj=50, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A31", cost=5500, proj=42, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A41", cost=5500, proj=43, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A51", cost=5500, proj=54, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A61", cost=5500, proj=45, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A71", cost=5500, proj=56, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A81", cost=5500, proj=47, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A91", cost=5500, proj=48, pos="TE", team="Y", matchup="X@Y" + ), + Player( + name="A110", cost=5500, proj=49, pos="TE", team="Y", matchup="X@Y" + ), + Player( + name="A112", cost=5500, proj=60, pos="DST", team="Y", matchup="X@Y" + ), ] def capt_boost(p): diff --git a/draftfast/test/test_optimize.py b/draftfast/test/test_optimize.py index c380771..4a3551d 100644 --- a/draftfast/test/test_optimize.py +++ b/draftfast/test/test_optimize.py @@ -89,7 +89,9 @@ def test_nfl_dk(): projection_file_location=projection_file, game=rules.DRAFT_KINGS, ) - roster = run(rule_set=rules.DK_NFL_RULE_SET, player_pool=players, verbose=True) + roster = run( + rule_set=rules.DK_NFL_RULE_SET, player_pool=players, verbose=True + ) assertions.assertNotEqual(roster, None) assertions.assertEqual(roster.projected(), 124.30) @@ -100,7 +102,9 @@ def test_nfl_fd(): salary_file_location=fd_nfl_salary_file, game=rules.FAN_DUEL, ) - roster = run(rule_set=rules.FD_NFL_RULE_SET, player_pool=players, verbose=True) + roster = run( + rule_set=rules.FD_NFL_RULE_SET, player_pool=players, verbose=True + ) assertions.assertNotEqual(roster, None) assertions.assertAlmostEqual(roster.projected(), 155.0172712846236) @@ -132,7 +136,9 @@ def test_multi_roster_nfl(): projection_file_location=projection_file, game=rules.DRAFT_KINGS, ) - roster = run(rule_set=rules.DK_NFL_RULE_SET, player_pool=players, verbose=True) + roster = run( + rule_set=rules.DK_NFL_RULE_SET, player_pool=players, verbose=True + ) second_roster = run( rule_set=rules.DK_NFL_RULE_SET, player_pool=players, @@ -191,8 +197,12 @@ def test_uniques_nba(): third_players = third_roster.sorted_players() crossover_a = list(set(players).intersection(second_players)) crossover_b = list(set(players).intersection(third_players)) - assertions.assertEqual(len(crossover_a), rules.DK_NBA_RULE_SET.roster_size - 1) - assertions.assertEqual(len(crossover_b), rules.DK_NBA_RULE_SET.roster_size - 2) + assertions.assertEqual( + len(crossover_a), rules.DK_NBA_RULE_SET.roster_size - 1 + ) + assertions.assertEqual( + len(crossover_b), rules.DK_NBA_RULE_SET.roster_size - 2 + ) def test_respect_lock(): @@ -252,7 +262,9 @@ def test_respect_group1(): ), ) - group_count = len([x for x in roster.sorted_players() if x.name in grouped_players]) + group_count = len( + [x for x in roster.sorted_players() if x.name in grouped_players] + ) assertions.assertEqual(group_count, 2) @@ -280,7 +292,9 @@ def test_respect_group2(): ), ) - group_count = len([x for x in roster.sorted_players() if x.name in grouped_players]) + group_count = len( + [x for x in roster.sorted_players() if x.name in grouped_players] + ) assertions.assertTrue(group_count >= 2 and group_count <= 3) @@ -308,7 +322,9 @@ def test_respect_group3(): ), ) - group_count = len([x for x in roster.sorted_players() if x.name in grouped_players]) + group_count = len( + [x for x in roster.sorted_players() if x.name in grouped_players] + ) assertions.assertTrue(group_count == 1) @@ -321,13 +337,21 @@ def test_stack(): roster = run( rule_set=rules.DK_NFL_RULE_SET, player_pool=players, - optimizer_settings=OptimizerSettings(stacks=[Stack(team="NE", count=5)]), + optimizer_settings=OptimizerSettings( + stacks=[Stack(team="NE", count=5)] + ), verbose=True, ) - ne_players_count = len([p for p in roster.sorted_players() if p.team == "NE"]) + ne_players_count = len( + [p for p in roster.sorted_players() if p.team == "NE"] + ) assertions.assertEqual(5, ne_players_count) ne_def = len( - [p for p in roster.sorted_players() if p.team == "NE" and p.pos == "DST"] + [ + p + for p in roster.sorted_players() + if p.team == "NE" and p.pos == "DST" + ] ) assertions.assertEqual(ne_def, 1) @@ -353,14 +377,24 @@ def test_custom_stack(): ), verbose=True, ) - ne_players_count = len([p for p in roster.sorted_players() if p.team == "NE"]) + ne_players_count = len( + [p for p in roster.sorted_players() if p.team == "NE"] + ) assertions.assertEqual(5, ne_players_count) ne_def = len( - [p for p in roster.sorted_players() if p.team == "NE" and p.pos == "DST"] + [ + p + for p in roster.sorted_players() + if p.team == "NE" and p.pos == "DST" + ] ) assertions.assertEqual(ne_def, 0) wides = len( - [p for p in roster.sorted_players() if p.team == "NE" and p.pos == "WR"] + [ + p + for p in roster.sorted_players() + if p.team == "NE" and p.pos == "WR" + ] ) assertions.assertEqual(wides, 4) @@ -375,7 +409,9 @@ def test_force_combo(): roster = run( rule_set=rules.DK_NFL_RULE_SET, player_pool=players, - optimizer_settings=OptimizerSettings(stacks=[Stack(team="NE", count=5)]), + optimizer_settings=OptimizerSettings( + stacks=[Stack(team="NE", count=5)] + ), constraints=LineupConstraints( locked=["Sam Bradford"], ), @@ -403,12 +439,20 @@ def test_force_combo(): assertions.assertEqual(qb.pos, "QB") wr_team_count = len( - [x for x in roster.sorted_players() if x.team == qb.team and x.pos == "WR"] + [ + x + for x in roster.sorted_players() + if x.team == qb.team and x.pos == "WR" + ] ) assertions.assertEqual(wr_team_count, 1) te_team_count = len( - [x for x in roster.sorted_players() if x.team == qb.team and x.pos == "TE"] + [ + x + for x in roster.sorted_players() + if x.team == qb.team and x.pos == "TE" + ] ) assertions.assertEqual(te_team_count, 0) @@ -436,7 +480,11 @@ def test_te_combo(): qb = roster.sorted_players()[0] assertions.assertEqual(qb.pos, "QB") team_count = len( - [x for x in roster.sorted_players() if x.team == qb.team and x.pos == "TE"] + [ + x + for x in roster.sorted_players() + if x.team == qb.team and x.pos == "TE" + ] ) assertions.assertEqual(team_count, 1) @@ -461,7 +509,11 @@ def test_te_combo(): qb = roster.sorted_players()[0] assertions.assertEqual(qb.pos, "QB") team_count = len( - [x for x in roster.sorted_players() if x.team == qb.team and x.pos == "WR"] + [ + x + for x in roster.sorted_players() + if x.team == qb.team and x.pos == "WR" + ] ) assertions.assertEqual(team_count, 1) @@ -476,7 +528,8 @@ def test_impossible_constraints(): rule_set=rules.DK_NFL_RULE_SET, player_pool=players, optimizer_settings=OptimizerSettings( - stacks=[Stack(team="NE", count=100)], no_offense_against_defense=True + stacks=[Stack(team="NE", count=100)], + no_offense_against_defense=True, ), constraints=LineupConstraints( banned=["Sammy Watkins", "Kellen Davis"], @@ -567,7 +620,9 @@ def test_multi_position_group_constraint(): verbose=True, ) - group_count = len([x for x in roster.sorted_players() if x.name in grouped_players]) + group_count = len( + [x for x in roster.sorted_players() if x.name in grouped_players] + ) assertions.assertEqual(group_count, 2) assertions.assertEqual(roster.projected(), 1304) @@ -592,37 +647,81 @@ def test_multi_position_group_constraint2(): verbose=True, ) - group_count = len([x for x in roster.sorted_players() if x.name in grouped_players]) + group_count = len( + [x for x in roster.sorted_players() if x.name in grouped_players] + ) assertions.assertEqual(group_count, 2) assertions.assertAlmostEqual(roster.projected(), 120.89999999999999) def test_no_opposing_def_dk_nfl_mock(): mock_pool = [ - Player(name="A1", cost=5500, proj=40, pos="QB", team="X", matchup="X@Y"), - Player(name="A2", cost=5500, proj=41, pos="QB", team="Y", matchup="X@Y"), - Player(name="A11", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y"), - Player(name="A3", cost=5500, proj=42, pos="WR", team="Y", matchup="X@Y"), - Player(name="A4", cost=5500, proj=43, pos="WR", team="X", matchup="X@Y"), - Player(name="A5", cost=5500, proj=44, pos="WR", team="Y", matchup="X@Y"), - Player(name="A111", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y"), - Player(name="A31", cost=5500, proj=42, pos="WR", team="Y", matchup="X@Y"), - Player(name="A41", cost=5500, proj=62, pos="WR", team="X", matchup="X@Y"), - Player(name="A51", cost=5500, proj=63, pos="WR", team="Y", matchup="X@Y"), - Player(name="A6", cost=5500, proj=45, pos="RB", team="X", matchup="X@Y"), - Player(name="A7", cost=5500, proj=46, pos="RB", team="Y", matchup="X@Y"), - Player(name="A8", cost=5500, proj=47, pos="RB", team="X", matchup="X@Y"), - Player(name="A71", cost=5500, proj=46, pos="RB", team="Y", matchup="X@Y"), - Player(name="A81", cost=5500, proj=47, pos="RB", team="X", matchup="X@Y"), - Player(name="A711", cost=5500, proj=46, pos="RB", team="Y", matchup="X@Y"), - Player(name="A9", cost=5500, proj=48, pos="TE", team="X", matchup="X@Y"), - Player(name="A10", cost=5500, proj=49, pos="TE", team="Y", matchup="X@Y"), - Player(name="A12", cost=5500, proj=51, pos="DST", team="X", matchup="X@Y"), - Player(name="A13", cost=5500, proj=500, pos="DST", team="Y", matchup="X@Y"), + Player( + name="A1", cost=5500, proj=40, pos="QB", team="X", matchup="X@Y" + ), + Player( + name="A2", cost=5500, proj=41, pos="QB", team="Y", matchup="X@Y" + ), + Player( + name="A11", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A3", cost=5500, proj=42, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A4", cost=5500, proj=43, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A5", cost=5500, proj=44, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A111", cost=5500, proj=50, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A31", cost=5500, proj=42, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A41", cost=5500, proj=62, pos="WR", team="X", matchup="X@Y" + ), + Player( + name="A51", cost=5500, proj=63, pos="WR", team="Y", matchup="X@Y" + ), + Player( + name="A6", cost=5500, proj=45, pos="RB", team="X", matchup="X@Y" + ), + Player( + name="A7", cost=5500, proj=46, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A8", cost=5500, proj=47, pos="RB", team="X", matchup="X@Y" + ), + Player( + name="A71", cost=5500, proj=46, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A81", cost=5500, proj=47, pos="RB", team="X", matchup="X@Y" + ), + Player( + name="A711", cost=5500, proj=46, pos="RB", team="Y", matchup="X@Y" + ), + Player( + name="A9", cost=5500, proj=48, pos="TE", team="X", matchup="X@Y" + ), + Player( + name="A10", cost=5500, proj=49, pos="TE", team="Y", matchup="X@Y" + ), + Player( + name="A12", cost=5500, proj=51, pos="DST", team="X", matchup="X@Y" + ), + Player( + name="A13", cost=5500, proj=500, pos="DST", team="Y", matchup="X@Y" + ), ] # mock pool is constructed such that optimal lineup has qb opposing dst - roster = run(rule_set=rules.DK_NFL_RULE_SET, player_pool=mock_pool, verbose=True) + roster = run( + rule_set=rules.DK_NFL_RULE_SET, player_pool=mock_pool, verbose=True + ) assertions.assertEqual(roster.projected(), 909) qb_team = roster.sorted_players()[0].team @@ -655,7 +754,9 @@ def test_no_opposing_def_dk_nfl_mock(): # add a player from a third team, min 2 teams mock_pool.append( - Player(name="B2", cost=5500, proj=70, pos="QB", team="Q", matchup="Q@Z") + Player( + name="B2", cost=5500, proj=70, pos="QB", team="Q", matchup="Q@Z" + ) ) roster = run( rule_set=rules.DK_NFL_RULE_SET, @@ -724,7 +825,9 @@ def test_no_opposing_def_fd_nfl(): rule_set=rules.FD_NFL_RULE_SET, player_pool=players, optimizer_settings=OptimizerSettings(no_offense_against_defense=True), - constraints=LineupConstraints(locked=["Eric Ebron", "Jacksonville Jaguars"]), + constraints=LineupConstraints( + locked=["Eric Ebron", "Jacksonville Jaguars"] + ), verbose=True, ) diff --git a/draftfast/test/test_pickem.py b/draftfast/test/test_pickem.py index 3973165..bd3f1d9 100644 --- a/draftfast/test/test_pickem.py +++ b/draftfast/test/test_pickem.py @@ -61,7 +61,9 @@ def test_banned_players(): def test_locked_players(): players = _generate_test_player_data() - optimized = optimize(players, constraints=LineupConstraints(locked=["B", "D"])) + optimized = optimize( + players, constraints=LineupConstraints(locked=["B", "D"]) + ) assertions.assertEqual(optimized.total, 49 + 47 + 46 + 44 + 42 + 40) diff --git a/draftfast/test/test_roster.py b/draftfast/test/test_roster.py index 0f7431e..96d2423 100644 --- a/draftfast/test/test_roster.py +++ b/draftfast/test/test_roster.py @@ -1,4 +1,10 @@ -from draftfast.orm import NFLRoster, Player, ShowdownRoster, RosterGroup, MVPRoster +from draftfast.orm import ( + NFLRoster, + Player, + ShowdownRoster, + RosterGroup, + MVPRoster, +) import unittest assertions = unittest.TestCase("__init__") @@ -138,7 +144,9 @@ def test_roster_group(): rg = RosterGroup(rosters=[roster_a, roster_b]) assertions.assertEqual(rg.get_similarity_score(), 1) assertions.assertEqual(rg.get_salary_frequency(), [(2, 2)]) - assertions.assertEqual(rg.get_player_frequency(), [(player_a, 2), (player_b, 2)]) + assertions.assertEqual( + rg.get_player_frequency(), [(player_a, 2), (player_b, 2)] + ) rg_2 = RosterGroup(rosters=[roster_a, roster_c]) assertions.assertEqual(rg_2.get_similarity_score(), 0.5)