Ejemplo n.º 1
0
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
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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))
Ejemplo n.º 5
0
 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))
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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")
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
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)
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
    '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
Ejemplo n.º 13
0
 def from_string(string: str):
     try:
         return Analysis[string.upper()]
     except KeyError:
         error_message("Analysis '{}' is not valid".format(string))
Ejemplo n.º 14
0
 def from_string(string: str):
     try:
         return Position[string.lower()]
     except KeyError:
         error_message("Position '{}' is not valid".format(string))
Ejemplo n.º 15
0
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))
Ejemplo n.º 16
0
 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]
Ejemplo n.º 17
0
 def from_string(cls, string: str):
     try:
         return Half[string.lower()]
     except KeyError:
         messages.error_message("Half '{}' is not valid".format(string))
Ejemplo n.º 18
0
 def from_string(string: str):
     try:
         return Venue[string.lower()]
     except KeyError:
         messages.error_message("Venue '{}' is not valid".format(string))
Ejemplo n.º 19
0
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)
Ejemplo n.º 20
0
 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))