def get_starting_squad(fpl_team_id=None): """ use the transactions table in the db """ if not fpl_team_id: # use the most recent transaction in the table most_recent = (session.query(Transaction).order_by( Transaction.id.desc()).filter_by(free_hit=0).first()) fpl_team_id = most_recent.fpl_team_id print("Getting starting squad for {}".format(fpl_team_id)) s = Squad() # Don't include free hit transfers as they only apply for the week the # chip is activated transactions = (session.query(Transaction).order_by( Transaction.gameweek, Transaction.id).filter_by( fpl_team_id=fpl_team_id).filter_by(free_hit=0).all()) for trans in transactions: if trans.bought_or_sold == -1: s.remove_player(trans.player_id, price=trans.price) else: # within an individual transfer we can violate the budget and squad # constraints, as long as the final squad for that gameweek obeys them s.add_player( trans.player_id, price=trans.price, season=trans.season, gameweek=trans.gameweek, check_budget=False, check_team=False, ) return s
def get_starting_squad(fpl_team_id=None, use_api=False, apifetcher=None): """ use the transactions table in the db, or the API if requested """ if use_api: if not fpl_team_id: raise RuntimeError( "Please specify fpl_team_id to get current squad from API") players_prices = get_current_squad_from_api(fpl_team_id, apifetcher=apifetcher) s = Squad(season=CURRENT_SEASON) for pp in players_prices: s.add_player( pp[0], price=pp[1], gameweek=NEXT_GAMEWEEK - 1, check_budget=False, check_team=False, ) s.budget = get_bank(fpl_team_id, season=CURRENT_SEASON) return s # otherwise, we use the Transaction table in the DB if not fpl_team_id: # use the most recent transaction in the table most_recent = (session.query(Transaction).order_by( Transaction.id.desc()).filter_by(free_hit=0).first()) if most_recent is None: raise ValueError("No transactions in database.") fpl_team_id = most_recent.fpl_team_id print("Getting starting squad for {}".format(fpl_team_id)) # Don't include free hit transfers as they only apply for the week the # chip is activated transactions = (session.query(Transaction).order_by( Transaction.gameweek, Transaction.id).filter_by( fpl_team_id=fpl_team_id).filter_by(free_hit=0).all()) if len(transactions) == 0: raise ValueError( f"No transactions in database for team ID {fpl_team_id}") s = Squad(season=transactions[0].season) for trans in transactions: if trans.bought_or_sold == -1: s.remove_player(trans.player_id, price=trans.price) else: # within an individual transfer we can violate the budget and squad # constraints, as long as the final squad for that gameweek obeys them s.add_player( trans.player_id, price=trans.price, gameweek=trans.gameweek, check_budget=False, check_team=False, ) return s
def test_remove_player(fill_players): """ add a player then remove them. """ with test_session_scope() as ts: t = Squad() t.add_player(1, season=TEST_SEASON, dbsession=ts) assert len(t.players) == 1 assert t.num_position["GK"] == 1 t.remove_player(1, season=TEST_SEASON, use_api=False, dbsession=ts) assert len(t.players) == 0 assert t.num_position["GK"] == 0 assert t.budget == 1000
def get_starting_squad(): """ use the transactions table in the db """ s = Squad() # Don't include free hit transfers as they only apply for the week the chip is activated transactions = (session.query(Transaction).order_by( Transaction.id).filter_by(free_hit=0).all()) for trans in transactions: if trans.bought_or_sold == -1: s.remove_player(trans.player_id, price=trans.price) else: ## within an individual transfer we can violate the budget and team constraints, ## as long as the final team for that gameweek obeys them s.add_player( trans.player_id, price=trans.price, season=trans.season, gameweek=trans.gameweek, check_budget=False, check_team=False, ) return s
def make_new_squad_iter( gw_range, tag, budget=1000, season=CURRENT_SEASON, num_iterations=100, update_func_and_args=None, verbose=False, bench_boost_gw=None, triple_captain_gw=None, **kwargs, ): """ Make a squad from scratch, i.e. for gameweek 1, or for wildcard, or free hit, by selecting high scoring players and then iteratively replacing them with cheaper options until we have a valid squad. """ transfer_gw = min(gw_range) # the gw we're making the new squad best_score = 0.0 best_squad = None for iteration in range(num_iterations): if verbose: print("Choosing new squad: iteration {}".format(iteration)) if update_func_and_args: # call function to update progress bar. # this was passed as a tuple (func, increment, pid) update_func_and_args[0](update_func_and_args[1], update_func_and_args[2]) predicted_points = {} t = Squad(budget, season=season) # first iteration - fill up from the front for pos in positions: predicted_points[pos] = get_predicted_points(gameweek=gw_range, position=pos, tag=tag, season=season) for pp in predicted_points[pos]: t.add_player(pp[0], gameweek=transfer_gw) if t.num_position[pos] == TOTAL_PER_POSITION[pos]: break # presumably we didn't get a complete squad now excluded_player_ids = [] while not t.is_complete(): # randomly swap out a player and replace with a cheaper one in the # same position player_to_remove = t.players[random.randint(0, len(t.players) - 1)] remove_cost = player_to_remove.purchase_price t.remove_player(player_to_remove.player_id, gameweek=transfer_gw) excluded_player_ids.append(player_to_remove.player_id) for pp in predicted_points[player_to_remove.position]: if (pp[0] not in excluded_player_ids or random.random() < 0.3): # some chance to put player back cp = CandidatePlayer(pp[0], gameweek=transfer_gw, season=season) if cp.purchase_price >= remove_cost: continue else: t.add_player(pp[0], gameweek=transfer_gw) # now try again to fill up the rest of the squad for pos in positions: num_missing = TOTAL_PER_POSITION[pos] - t.num_position[pos] if num_missing == 0: continue for pp in predicted_points[pos]: if pp[0] in excluded_player_ids: continue t.add_player(pp[0], gameweek=transfer_gw) if t.num_position[pos] == TOTAL_PER_POSITION[pos]: break # we have a complete squad score = 0.0 for gw in gw_range: if gw == bench_boost_gw: score += t.get_expected_points( gw, tag, bench_boost=True) * get_discount_factor( gw_range[0], gw) elif gw == triple_captain_gw: score += t.get_expected_points( gw, tag, triple_captain=True) * get_discount_factor( gw_range[0], gw) else: score += t.get_expected_points(gw, tag) * get_discount_factor( gw_range[0], gw) if score > best_score: best_score = score best_squad = t if verbose: print("====================================\n") print(best_squad) print(best_score) return best_squad