def get_unique_league(args: Namespace) -> str: if len(args.league) > 1: messages.error_message("This tool only supports a single league. " "You selected: '{}'".format(','.join(args.league))) else: (league_code,) = args.league return league_code
def get_unique_event(args: Namespace) -> str: if len(args.event) > 1: messages.error_message("This tool only supports a single event. " "You selected: '{}'".format(','.join(args.event))) else: (event,) = args.event return event
def name(cls, func: Callable or partial, negate: bool, short: bool = False) -> str: if type(func) is partial: try: if short: func_name = Event.short_table[func.func] else: func_name = Event.long_table[func.func] (op, arg) = func.args op_name = Event.op_table[(op, negate)] return '{} {} {}'.format(func_name, op_name, arg) except KeyError: messages.error_message( "Unable to construct name for '{}'".format( func.func.__name__, op.__name__)) else: if short: func_name = Event.short_table[func] else: func_name = Event.long_table[func] if negate: return 'No {}'.format(func_name) else: return func_name
def team_position(self, team: Team) -> int: for i, row in enumerate(self): if row.TEAM == team: return i error_message("Unable to find team '{}' in the table".format( team.name))
def add(cls, name: str): if name not in cls.inventory: stem, op, bound = Event.decode(name) if stem in cls.stems: cls.inventory[name] = partial(cls.stems[stem], getattr(operator, op), bound) else: messages.error_message("Event '{}' is not valid".format(name))
def get_unique_team(args: Namespace) -> str: team_names = get_multiple_teams(args) if len(team_names) > 1: messages.error_message("This tool only supports a single team. " "You selected: '{}'".format(','.join(team_names))) else: (team_name,) = team_names return team_name
def main(args: Namespace): load_teams(args.database) leagues = [] if args.country: for country in args.country: leagues.extend([ code for code, league in league_register.items() if league.country == country.capitalize() ]) if args.league: leagues.extend(list(args.league)) if not args.country and not args.league: leagues.extend(list(league_register.keys())) for league_code in leagues: league = league_register[league_code] load_league(args.database, league) seasons = Season.seasons(league) if not seasons: messages.warning_message("No season data found") else: if args.history: seasons = seasons[-args.history:] if seasons[-1].current: this_season = seasons.pop() if args.team: teams = [] for team_name in get_multiple_teams(args): (row, ) = extract_picked_team(args.database, team_name, league) team = Team.inventory[row[0]] teams.append(team) else: teams = this_season.teams() events = [Event.get(event) for event in args.event] historical_data = {} for event in events: historical_data[event] = DataUnit(Counter(), seasons) for season in seasons: for team in season.teams(): count_events(season, team, args.venue, args.half, event, args.negate, historical_data[event]) analyse_teams(args, league, seasons, this_season, teams, historical_data) else: messages.error_message( "The current season has not yet started")
def main(args: Namespace): load_teams(args.database) league = league_register[get_unique_league(args)] load_league(args.database, league) seasons = Season.seasons(league) if not seasons: messages.error_message("No season data found") if args.history: seasons = seasons[-args.history:] (row, ) = extract_picked_team(args.database, get_unique_team(args), league) selected_team = Team.inventory[row[0]] if args.averages: if seasons[-1].current: seasons.pop() if seasons: team_season_stats = [] collective_season_stats = [] for season in seasons: stats = compute_statistics(season, selected_team, args.venue, args.game_states) team_season_stats.append(stats) teams = season.teams() if selected_team in teams: this_season_stats = [] for team in teams: if team != selected_team: stats = compute_statistics(season, team, args.venue, args.game_states) this_season_stats.append(stats) collective_season_stats.append( reduce(this_season_stats, median)) team_stats = reduce(team_season_stats, median, len(collective_season_stats)) collective_stats = reduce(collective_season_stats, sum) display_averages(selected_team, args.venue, seasons, team_stats, collective_stats, args.block) else: messages.error_message('No historical data to analyse') else: team_season_stats = [] for season in seasons: stats = compute_statistics(season, selected_team, args.venue, args.game_states) team_season_stats.append(stats) team_stats = reduce(team_season_stats, sum) display_summations(selected_team, args.venue, seasons, team_stats, args.block)
def main(args: Namespace): load_teams(args.database) league = league_register[get_unique_league(args)] load_league(args.database, league) seasons = Season.seasons(league) if not seasons: messages.error_message("No season data found") for season in seasons: show_results(league, season, args.results)
def extract_picked_team(database_name: str, team_name: str, league: League = None, error: bool = True) -> List[str]: team_name = team_name.replace('*', '%') team_name = team_name.replace("'", "''") team_rows = [] constraints = [] team_constraint = "{} {} '{}' {} {}".format(ColumnNames.Name.name, Keywords.LIKE.name, team_name, Keywords.COLLATE.name, Keywords.NOCASE.name) constraints.append(team_constraint) with Database(database_name) as db: team_rows.extend(db.fetch_all_rows(Team.sql_table(), constraints)) if (not team_rows or len(team_rows) > 1) and league: team_rows = [] country_constaint = "{}='{}' {} {}".format(ColumnNames.Country.name, league.country, Keywords.COLLATE.name, Keywords.NOCASE.name) constraints.append(country_constaint) with Database(database_name) as db: team_rows.extend(db.fetch_all_rows(Team.sql_table(), constraints)) if not team_rows: if error: messages.error_message( "No team '{}' found in the database.".format(team_name)) else: all_rows = [] with Database(database_name) as db: all_rows.extend(db.fetch_all_rows(Team.sql_table(), [])) expr = compile(r'.*{}.*'.format(team_name.replace('%', '.*'))) return [row for row in all_rows if expr.match(row[1])] elif len(team_rows) > 1: if error: options = ', '.join(row[1] for row in team_rows) messages.error_message( "Too many teams match the name '{}' in the database: {}.". format(team_name, options)) else: return team_rows else: return team_rows
def main(args: Namespace): load_teams(args.database) league = league_register[get_unique_league(args)] load_league(args.database, league) seasons = Season.seasons(league) if not seasons: messages.error_message("No season data found") season_to_summary = OrderedDict() ylim = 0 for season in seasons: summary = compute_summary(season, args.half) if summary: season_to_summary[season] = summary ylim = max(ylim, season_to_summary[season].home_goals, season_to_summary[season].away_goals) ylim += 25 title = '{} {}'.format(league.country, league.name) if args.half != Half.both: title += ' ({} half)'.format(args.half.name) show(title, season_to_summary, ylim, args.block)
'USA1W': League('USA', 'NWSL Women'), 'UZB1': League('Uzbekistan', 'Super League'), 'VEN1': League('Venezuela', 'Primera Division'), 'VEN2': League('Venezuela', 'Segunda Division'), 'VIE1': League('Vietnam', 'V.League 1'), 'WAL1': League('Wales', 'Premier'), 'XXK1': League('Kosovo', 'Superliga'), 'ZAF1': League('South-Africa', 'Premier Soccer League'), 'ZAF2': League('South-Africa', '1st Division') }) for league in league_register.values(): if league.country not in country_register: messages.error_message("Unrecognised country '{}' for league".format( league.country)) def get_league_code(league: League) -> str: for key, candidate in league_register.items(): if candidate.name == league.name and candidate.country == league.country: return key
def from_string(string: str): try: return Analysis[string.upper()] except KeyError: error_message("Analysis '{}' is not valid".format(string))
def from_string(string: str): try: return Position[string.lower()] except KeyError: error_message("Position '{}' is not valid".format(string))
def check_database_exists(database_name: str): path = Path(database_name) if not path.exists(): messages.error_message( "Unable to find database '{}'".format(database_name))
def next(self) -> str: if self.index > len(self.choices) - 1: error_message('Out of options for next color') self.index += 1 return self.choices[self.index - 1]
def from_string(cls, string: str): try: return Half[string.lower()] except KeyError: messages.error_message("Half '{}' is not valid".format(string))
def from_string(string: str): try: return Venue[string.lower()] except KeyError: messages.error_message("Venue '{}' is not valid".format(string))
def main(args: Namespace): load_teams(args.database) league = league_register[get_unique_league(args)] load_league(args.database, league) seasons = Season.seasons(league) if not seasons: messages.error_message("No season data found") if args.history: seasons = seasons[-args.history:] if args.team: (row, ) = extract_picked_team(args.database, args.team, league) selected_team = Team.inventory[row[0]] else: selected_team = None func = Event.get(get_unique_event(args)) if args.chunks: data = compute_chunked_data(seasons, func, args.negate, args.venue, args.half, args.chunks) nrows = len(data) if selected_team is not None: ncols = 3 else: ncols = 1 fig, axes = plt.subplots(nrows=len(data), ncols=ncols, figsize=(20, 13), squeeze=False, constrained_layout=True) x_limit, _ = find_limits(data) for i, datum in enumerate(data): ax = axes[i, 0] plot(ax, datum, x_limit, args.lines) if selected_team is not None: golden_season = seasons[-1] golden_table = LeagueTable(golden_season, args.half) golden_map = golden_table.group(args.chunks) chunk_to_seasons = OrderedDict() for chunk_id in range(golden_map.number_of_chunks()): if chunk_id not in chunk_to_seasons: chunk_to_seasons[chunk_id] = [] for season in seasons: if season != golden_season: table = LeagueTable(season, args.half) table_map = table.group(args.chunks) if selected_team in season.teams(): position = table.team_position(selected_team) chunk_id = table_map.get_chunk(position) chunk_to_seasons[chunk_id].append(season) chunk_to_datum = OrderedDict() for chunk_id, chunk_seasons in chunk_to_seasons.items(): if chunk_seasons: datum = DataUnit(Counter(), chunk_seasons, team=selected_team, positions=golden_map.get_rows(chunk_id)) chunk_to_datum[chunk_id] = datum for season in seasons: if season == golden_season: position = golden_table.team_position(selected_team) datum = DataUnit(Counter(), [golden_season], team=selected_team, positions=[position], highlight=True) golden_datum = datum else: if selected_team in season.teams(): table = LeagueTable(season, args.half) table_map = table.group(args.chunks) position = table.team_position(selected_team) chunk_id = table_map.get_chunk(position) datum = chunk_to_datum[chunk_id] count_events(season, selected_team, args.venue, args.half, func, args.negate, datum) position = golden_table.team_position(selected_team) chunk_id = golden_map.get_chunk(position) ax = axes[chunk_id, 1] plot(ax, golden_datum, x_limit, args.lines) used = {(chunk_id, 1)} for chunk_id, datum in chunk_to_datum.items(): ax = axes[chunk_id, 2] plot(ax, datum, x_limit, args.lines) used.add((chunk_id, 2)) for i in range(0, nrows): for j in range(1, 3): if (i, j) not in used: fig.delaxes(axes[i, j]) else: data = compute_aggregated_data(seasons, selected_team, func, args.negate, args.venue, args.half) x_limit, _ = find_limits(data) display = DisplayGrid(len(data), 2) fig, axes = plt.subplots(nrows=display.nrows, ncols=display.ncols, figsize=(20, 10), squeeze=False) for i, datum in enumerate(data): cell_x, cell_y = display.index(i) ax = axes[cell_x, cell_y] plot(ax, datum, x_limit, args.lines) title = construct_title(league, func, args.negate, args.venue, args.half) fig.suptitle(title, fontweight='bold', fontsize=14) plt.show(block=args.block)
def group(self, chunk_size: int) -> TableMap: if chunk_size <= 0 or chunk_size > len(self): error_message('Chunk size {} is not for tables of size {}.'.format( chunk_size, len(self))) return TableMap(chunk_size, len(self))