def test_is_injured_or_suspended(): """ Check Player.is_injured_or_suspended() returns appropriate value both if details are available in attributes table for requested gameweek, and if they're not available. """ player_id = 1 season = "1920" price = 50 position = "MID" team = "ABC" # gw: (chance_of_playing_next_round, return_gameweek) team_dict = { 2: (100, None), 3: (75, None), 4: (50, 5), 5: (0, None), } player = Player() player.player_id = player_id player.name = "Test Player" player.attributes = [] for gw, attr in team_dict.items(): pa = PlayerAttributes() pa.season = season pa.team = team pa.gameweek = gw pa.price = price pa.position = position pa.player_id = player_id pa.chance_of_playing_next_round = attr[0] pa.return_gameweek = attr[1] player.attributes.append(pa) # gameweek available in attributes table # not injured, 100% available assert player.is_injured_or_suspended(season, 2, 2) is False assert player.is_injured_or_suspended(season, 2, 4) is False # not injured, 75% available assert player.is_injured_or_suspended(season, 3, 3) is False assert player.is_injured_or_suspended(season, 3, 5) is False # 50% available, expected back gw 5 assert player.is_injured_or_suspended(season, 4, 4) is True assert player.is_injured_or_suspended(season, 4, 5) is False # 100% unavailable, mo return gameweek assert player.is_injured_or_suspended(season, 5, 6) is True assert player.is_injured_or_suspended(season, 5, 7) is True # gameweek before earliest available: return status as of first available assert player.is_injured_or_suspended(season, 1, 1) is False # gameweek after last available: return status as of last available assert player.is_injured_or_suspended(season, 6, 1) is True
def test_get_position(): """ Check Player.position() returns appropriate value both if details are available in attributes table for requested gameweek, and if they're not available. """ player_id = 1 gameweek = 1 price = 50 pos_dict = {"1819": "MID", "1920": "FWD"} # season: position team = "TST" player = Player() player.player_id = player_id player.name = "Test Player" player.attributes = [] for season, position in pos_dict.items(): pa = PlayerAttributes() pa.season = season pa.team = team pa.gameweek = gameweek pa.price = price pa.position = position pa.player_id = player_id player.attributes.append(pa) # season available in attributes table assert player.position("1819") == pos_dict["1819"] assert player.position("1920") == pos_dict["1920"] # season not available assert player.position("1011") is None
def fill_players(): """ fill a bunch of dummy players """ team_list = list(alternative_team_names.keys()) season = CURRENT_SEASON gameweek = 1 with test_session_scope() as ts: if len(ts.query(Player).all()) > 0: return for i, n in enumerate(dummy_players): p = Player() p.player_id = i p.fpl_api_id = i p.name = n print("Filling {} {}".format(i, n)) try: ts.add(p) except Exception: print("Error adding {} {}".format(i, n)) # now fill player_attributes if i % 15 < 2: pos = "GK" elif i % 15 < 7: pos = "DEF" elif i % 15 < 12: pos = "MID" else: pos = "FWD" team = team_list[i % 20] # make the first 15 players affordable, # the next 15 almost affordable, # the next 15 mostly unaffordable, # and rest very expensive price = value_generator(i // 15, pos) pa = PlayerAttributes() pa.season = season pa.team = team pa.gameweek = gameweek pa.price = price pa.position = pos player = ts.query(Player).filter_by(player_id=i).first() pa.player = player ts.add(pa) ts.commit()
def test_get_team(): """ Check Player.team() returns appropriate value both if details are available in attributes table for requested gameweek, and if they're not available. """ player_id = 1 season = "1920" price = 50 position = "MID" team_dict = {2: "ABC", 5: "XYZ"} # gw: team player = Player() player.player_id = player_id player.name = "Test Player" player.attributes = [] for gw, team in team_dict.items(): pa = PlayerAttributes() pa.season = season pa.team = team pa.gameweek = gw pa.price = price pa.position = position pa.player_id = player_id player.attributes.append(pa) # gameweek available in attributes table assert player.team(season, 2) == team_dict[2] # gameweek before earliest available: return first available assert player.team(season, 1) == team_dict[2] # gameweek after last available: return last available assert player.team(season, 6) == team_dict[5] # gameweek between two available values: return nearest assert player.team(season, 3) == team_dict[2] assert player.team(season, 4) == team_dict[5] # no gameweek available for seaaon: return None assert player.team("1011", 1) is None
def test_get_price(): """ Check Player.price() returns appropriate value both if details are available in attributes table for requested gameweek, and if they're not available. """ player_id = 1 season = "1920" team = "TST" position = "MID" price_dict = {2: 50, 4: 150} # gw: price player = Player() player.player_id = player_id player.name = "Test Player" player.attributes = [] for gw, price in price_dict.items(): pa = PlayerAttributes() pa.season = season pa.team = team pa.gameweek = gw pa.price = price pa.position = position pa.player_id = player_id player.attributes.append(pa) # gameweek available in attributes table assert player.price(season, 2) == price_dict[2] # gameweek before earliest available: return first available assert player.price(season, 1) == price_dict[2] # gameweek after last available: return last available assert player.price(season, 5) == price_dict[4] # gameweek between two available values: interpolate assert player.price(season, 3) == (price_dict[2] + price_dict[4]) / 2 # no gameweek available for seaaon: return None assert player.price("1011", 1) is None
def fill_attributes_table_from_api(season, gw_start=1, dbsession=session): """ use the FPL API to get player attributes info for the current season """ fetcher = FPLDataFetcher() next_gw = get_next_gameweek(season=season, dbsession=dbsession) # needed for selected by calculation from percentage below n_players = fetcher.get_current_summary_data()["total_players"] input_data = fetcher.get_player_summary_data() for player_api_id in input_data.keys(): # find the player in the player table player = get_player_from_api_id(player_api_id, dbsession=dbsession) if not player: print("ATTRIBUTES {} No player found with id {}".format( season, player_api_id)) continue print("ATTRIBUTES {} {}".format(season, player.name)) # First update the current gameweek using the summary data p_summary = input_data[player_api_id] position = positions[p_summary["element_type"]] pa = get_player_attributes(player.player_id, season=season, gameweek=next_gw, dbsession=dbsession) if pa: # found pre-existing attributes for this gameweek update = True else: # no attributes for this gameweek for this player yet pa = PlayerAttributes() update = False pa.player = player pa.player_id = player.player_id pa.season = season pa.gameweek = next_gw pa.price = int(p_summary["now_cost"]) pa.team = get_team_name(p_summary["team"], season=season, dbsession=dbsession) pa.position = positions[p_summary["element_type"]] pa.selected = int( float(p_summary["selected_by_percent"]) * n_players / 100) pa.transfers_in = int(p_summary["transfers_in_event"]) pa.transfers_out = int(p_summary["transfers_out_event"]) pa.transfers_balance = pa.transfers_in - pa.transfers_out pa.chance_of_playing_next_round = p_summary[ "chance_of_playing_next_round"] pa.news = p_summary["news"] if (pa.chance_of_playing_next_round is not None and pa.chance_of_playing_next_round <= 50): pa.return_gameweek = get_return_gameweek_from_news( p_summary["news"], season=season, dbsession=dbsession, ) if not update: # only need to add to the dbsession for new entries, if we're doing # an update the final dbsession.commit() is enough dbsession.add(pa) # now get data for previous gameweeks if next_gw > 1: player_data = fetcher.get_gameweek_data_for_player(player_api_id) if not player_data: print("Failed to get data for", player.name) continue for gameweek, data in player_data.items(): if gameweek < gw_start: continue for result in data: # check whether there are pre-existing attributes to update pa = get_player_attributes( player.player_id, season=season, gameweek=gameweek, dbsession=dbsession, ) if pa: update = True else: pa = PlayerAttributes() update = False # determine the team the player played for in this fixture opponent_id = result["opponent_team"] was_home = result["was_home"] kickoff_time = result["kickoff_time"] team = get_player_team_from_fixture( gameweek, opponent_id, was_home, kickoff_time, season=season, dbsession=dbsession, ) pa.player = player pa.player_id = player.player_id pa.season = season pa.gameweek = gameweek pa.price = int(result["value"]) pa.team = team pa.position = position # does not change during season pa.transfers_balance = int(result["transfers_balance"]) pa.selected = int(result["selected"]) pa.transfers_in = int(result["transfers_in"]) pa.transfers_out = int(result["transfers_out"]) if not update: # don't need to add to dbsession if updating pre-existing row dbsession.add(pa) break # done this gameweek now
def fill_attributes_table_from_file(detail_data, season, dbsession=session): """Fill player attributes table for previous season using data from player detail JSON files. """ for player_name in detail_data.keys(): # find the player id in the player table. If they're not # there, then we don't care (probably not a current player). player = get_player(player_name, dbsession=dbsession) if not player: print("Couldn't find player {}".format(player_name)) continue print("ATTRIBUTES {} {}".format(season, player)) # now loop through all the fixtures that player played in # Only one attributes row per gameweek - create list of gameweeks # encountered so can ignore duplicates (e.g. from double gameweeks). previous_gameweeks = [] for fixture_data in detail_data[player_name]: gameweek = int(fixture_data["gameweek"]) if gameweek in previous_gameweeks: # already done this gameweek continue previous_gameweeks.append(gameweek) pa = PlayerAttributes() pa.player = player pa.player_id = player.player_id pa.season = season pa.gameweek = gameweek pa.price = int(fixture_data["value"]) pa.team = fixture_data["played_for"] pa.position = fixture_data["position"] pa.transfers_balance = int(fixture_data["transfers_balance"]) pa.selected = int(fixture_data["selected"]) pa.transfers_in = int(fixture_data["transfers_in"]) pa.transfers_out = int(fixture_data["transfers_out"]) dbsession.add(pa)