def setUp(self): self.ml_model = factories.MLModelFactory(name="test_estimator", is_principal=True, used_in_competitions=True) candy = CandyStore(seasons=TIP_SEASON_RANGE) fixtures = data_factories.fake_fixture_data(fixtures=candy.fixtures( to_dict=None)) predictions = data_factories.fake_prediction_data( match_data=candy.fixtures(to_dict=None)) match_results = data_factories.fake_match_results_data( match_results=candy.match_results(to_dict=None)) self.fixture_data = [ fixtures.query("year == @season") for season in range(*TIP_SEASON_RANGE) ] self.prediction_data = [ predictions.query("year == @season") for season in range(*TIP_SEASON_RANGE) ] self.match_results_data = [ match_results.query("year == @season") for season in range(*TIP_SEASON_RANGE) ] self.api = api
def test_seasons_out_of_range(): current_year = date.today().year # When more than two seasons are given, it raises an exception seasons = (FIRST_AFL_SEASON, current_year + 1) with pytest.raises(AssertionError, match=r"seasons must be in the range"): CandyStore(seasons=(seasons[0] - 1, seasons[1])) with pytest.raises(AssertionError, match=r"seasons must be in the range"): CandyStore(seasons=(seasons[0], seasons[1] + 1))
def fake_fixture_data( fixtures: Optional[pd.DataFrame] = None, seasons: Union[Tuple[int, int], int] = 1, ) -> pd.DataFrame: """ Return minimally-valid data for fixture data. These matches are usually unplayed, future matches, but it is also possible to get data for past fixtures. """ fixtures = ( CandyStore(seasons=seasons).fixtures(to_dict=None) if fixtures is None else fixtures ) return ( fixtures.rename(columns={"season": "year", "round": "round_number"}).drop( "season_game", axis=1, errors="ignore" ) # Recreates data cleaning performed in data_import .assign( date=lambda df: pd.to_datetime(df["date"], utc=True), # Team name translations happen in augury's data pipeline home_team=_translate_team_names("home"), away_team=_translate_team_names("away"), ) )
def fake_match_data( match_results: Optional[pd.DataFrame] = None, seasons: Union[Tuple[int, int], int] = 1, ) -> pd.DataFrame: """Return minimally-valid dummy match results data.""" match_results = ( CandyStore(seasons=seasons).match_results(to_dict=None) if match_results is None else match_results ) return ( match_results.rename( columns={ "season": "year", "home_points": "home_score", "away_points": "away_score", } ) # Recreates data cleaning performed in data_import .assign( date=lambda df: pd.to_datetime(df["date"], utc=True), # Team name translations happen in augury's data pipeline home_team=_translate_team_names("home"), away_team=_translate_team_names("away"), ) )
def test_tuple_season_count(tuple_seasons): data = CandyStore(seasons=tuple_seasons).fixtures() data_frame = pd.DataFrame(data) first_season, last_season = tuple_seasons # It generates seasons across the given season range assert len(data_frame["season"].drop_duplicates()) == last_season - first_season
def test_too_long_tuple_seasons(tuple_seasons): current_year = date.today().year # When more than two seasons are given, it raises an exception seasons = tuple( sorted(tuple_seasons + (np.random.randint(FIRST_AFL_SEASON, current_year + 1),)) ) with pytest.raises(AssertionError, match=r"provide two seasons"): CandyStore(seasons=seasons)
def setUp(self): candy = CandyStore(seasons=MATCH_SEASON_RANGE) fixtures = data_factories.fake_fixture_data( fixtures=candy.fixtures(to_dict=None) ) predictions = data_factories.fake_prediction_data( fixtures=candy.fixtures(to_dict=None) ) self.fixture_return_values = [ fixtures.query("year == @season") for season in MOCK_IMPORT_SEASONS ] self.prediction_return_values = [ predictions.query("year == @season") for season in MOCK_IMPORT_SEASONS ] self.mock_submitter = FootyTipsSubmitter() self.mock_submitter.submit_tips = MagicMock() self.api = api
def fake_match_results_data( match_results: Optional[pd.DataFrame] = None, seasons: Union[Tuple[int, int], int] = 1, ) -> pd.DataFrame: """Return minimally-valid dummy match results data.""" match_results = (CandyStore(seasons=seasons).match_results( to_dict=None) if match_results is None else match_results) return match_results.assign(date=lambda df: pd.to_datetime(df["date"]).map( timezone.make_aware)).rename( columns={ "home_points": "home_score", "away_points": "away_score", "season": "year", })
def fake_fixture_data( fixtures: Optional[pd.DataFrame] = None, seasons: Union[Tuple[int, int], int] = 1) -> pd.DataFrame: """ Return minimally-valid data for fixture data. These matches are usually unplayed, future matches, but it is also possible to get data for past fixtures. """ fixtures = (CandyStore(seasons=seasons).fixtures( to_dict=None) if fixtures is None else fixtures) return (fixtures.rename(columns={ "season": "year", "round": "round_number" }).drop("season_game", axis=1, errors="ignore") # Recreates data cleaning performed in views.fixtures .assign(date=lambda df: pd.to_datetime(df["date"], utc=True)))
replace(".", "_").lower()) with localconverter(ro.default_converter + pandas2ri.converter): fitzroy = packages.importr("fitzRoy") fixtures = clean_column_names(fitzroy.get_fixture()) match_results = clean_column_names(fitzroy.get_match_results()) players = clean_column_names( fitzroy.get_afltables_stats(start_date="2019-01-01", end_date="2019-12-31")) betting_odds = clean_column_names( fitzroy.get_footywire_betting_odds(start_season="2019", end_season="2019")) data_factory = CandyStore(seasons=np.random.randint(1, 10)) @pytest.mark.parametrize( ["data_type", "fitzroy_data"], [ ("fixtures", fixtures), ("betting_odds", betting_odds), ("match_results", match_results), ("players", players), ], ) def test_matching_column_names(data_type, fitzroy_data): data = getattr(data_factory, data_type)(to_dict=None) data_columns = set(data.columns)
def test_int_season_count(int_seasons): data = CandyStore(seasons=int_seasons).fixtures() data_frame = pd.DataFrame(data) # It generates one season per requested season count assert len(data_frame["season"].drop_duplicates()) == int_seasons
def test_unknown_seasons_format(tuple_seasons): seasons = list(tuple_seasons) with pytest.raises(TypeError, match=r"seasons argument must be"): CandyStore(seasons=seasons)
def test_seasons_out_of_order(tuple_seasons): seasons = tuple(reversed(tuple_seasons)) with pytest.raises(AssertionError, match=r"First season must be less"): CandyStore(seasons=seasons)
def test_non_postive_seasons(): # When seasons is <= 0, it raises an exception seasons = np.random.randint(-10, 1) with pytest.raises(AssertionError, match=r"at least one season"): CandyStore(seasons=seasons)
def data_factory(): seasons = np.random.randint(1, 10) return CandyStore(seasons=seasons)