diff --git a/league_storage.py b/league_storage.py index a6a5a37..2b36a6f 100644 --- a/league_storage.py +++ b/league_storage.py @@ -3,6 +3,7 @@ import sqlite3 as sql data_dir = "data" league_dir = "leagues" +statements_file = os.path.join(data_dir, "sql_statements.xvi") def create_connection(league_name): #create connection, create db if doesn't exist @@ -21,6 +22,45 @@ def create_connection(league_name): print("oops, db connection no work") return conn +def statements(): + if not os.path.exists(os.path.dirname(statements_file)): + os.makedirs(os.path.dirname(statements_file)) + if not os.path.exists(statements_file): + #generate default statements: bat_base and pitch_base to be appended with a relevant ORDER BY statement + config_dic = { + "bat_base" : """SELECT name, team_name, + plate_appearances - (walks_taken + sacrifices) as ABs, + ROUND(hits*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as BA, + ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as SLG, + ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) as OBP, + ROUND((walks_taken + hits)*1.0/plate_appearances*1.0,3) + ROUND(total_bases*1.0 / (plate_appearances - (walks_taken + sacrifices)*1.0),3) as OPS +FROM stats WHERE plate_appearances > 8""", + "avg" : ["ORDER BY BA DESC;", "bat_base"], + "slg" : ["ORDER BY SLG DESC;", "bat_base"], + "obp" : ["ORDER BY OBP DESC;", "bat_base"], + "ops" : ["ORDER BY OPS DESC;", "bat_base"], + "pitch_base" : """SELECT name, team_name, + ROUND(((outs_pitched*1.0)/3.0),1) as IP, + ROUND(runs_allowed*27.0/(outs_pitched*1.0),3) as ERA, + ROUND((walks_allowed+hits_allowed)*3.0/(outs_pitched*1.0),3) as WHIP, + ROUND(walks_allowed*27.0/(outs_pitched*1.0),3) as BBper9, + ROUND(strikeouts_given*27.0/(outs_pitched*1.0),3) as Kper9, + ROUND(strikeouts_given*1.0/walks_allowed*1.0,3) as KperBB +FROM stats WHERE outs_pitched > 20 +""", + "era" : ["ORDER BY ERA ASC;", "pitch_base"], + "whip" : ["ORDER BY WHIP ASC;", "pitch_base"], + "kper9" : ["ORDER BY Kper9 DESC;", "pitch_base"], + "bbper9" : ["ORDER BY BBper9 ASC;", "pitch_base"], + "kperbb" : ["ORDER BY KperBB DESC;", "pitch_base"] + } + with open(statements_file, "w") as config_file: + json.dump(config_dic, config_file, indent=4) + return config_dic + else: + with open(statements_file) as config_file: + return json.load(config_file) + def create_season_connection(league_name, season_num): #create connection, create db if doesn't exist conn = None @@ -129,6 +169,19 @@ def add_stats(league_name, player_game_stats_list): conn.commit() conn.close() +def get_stats(league_name, stat, is_batter=True): + conn = create_connection(league_name) + stats = None + if conn is not None: + conn.row_factory = sql.Row + c=conn.cursor() + + if stat in statements().keys(): + c.execute(statements()[statements()[stat][1]]+"\n"+statements()[stat][0]) + stats = c.fetchall() + conn.close() + return stats + def update_standings(league_name, update_dic): if league_exists(league_name): conn = create_connection(league_name) diff --git a/leagues.py b/leagues.py index cfa41c3..7970c0d 100644 --- a/leagues.py +++ b/leagues.py @@ -415,6 +415,22 @@ class league_structure(object): return tournaments + def stat_embed(self, stat_name): + this_embed = Embed(color=Color.purple(), title=f"{self.name} Season {self.season} {stat_name} Leaders") + stats = league_db.get_stats(self.name, stat_name.lower()) + if stats is None: + return None + else: + stat_names = list(stats[0].keys())[2:] + for index in range(0, min(10,len(stats))): + this_row = list(stats[index]) + player_name = this_row.pop(0) + content_string = f"**{this_row.pop(0)}**\n" + for stat_index in range(0, len(this_row)): + content_string += f"**{stat_names[stat_index]}**: {str(this_row[stat_index])}; " + this_embed.add_field(name=player_name, value=content_string, inline=False) + return this_embed + class tournament(object): def __init__(self, name, team_dic, series_length = 5, finals_series_length = 7, max_innings = 9, id = None, secs_between_games = 300, secs_between_rounds = 600): diff --git a/the_prestige.py b/the_prestige.py index 400d06e..0241f9d 100644 --- a/the_prestige.py +++ b/the_prestige.py @@ -880,6 +880,28 @@ class LeagueDisplayCommand(Command): else: await msg.channel.send("Can't find that league, boss.") +class LeagueLeadersCommand(Command): + name = "leagueleaders" + template = "m;leagueleaders [league name]\n[stat name/abbreviation]" + description = "Displays a league's leaders in the given stats. A list of the allowed stats can be found on the github readme." + + async def execute(self, msg, command): + if league_exists(command.split("\n")[0].strip()): + league = leagues.load_league_file(command.split("\n")[0].strip()) + stat_name = command.split("\n")[1].strip() + stat_embed = league.stat_embed(stat_name) + if stat_embed is None: + await msg.channel.send("We don't know what that stat is, chief.") + return + try: + await msg.channel.send(embed=stat_embed) + return + except: + await msg.channel.send("Nobody's played enough games to get meaningful stats in that category yet, chief. Try again after the next game or two.") + return + + await msg.channel.send("Can't find that league, boss.") + class LeagueDivisionDisplayCommand(Command): name = "divisionstandings" template = "m;divisionstandings [league name]\n[team name]" @@ -1118,6 +1140,7 @@ commands = [ StartLeagueCommand(), LeaguePauseCommand(), LeagueDisplayCommand(), + LeagueLeadersCommand(), LeagueDivisionDisplayCommand(), LeagueWildcardCommand(), LeagueScheduleCommand(),