implemented #184: leagueleaders, with various stats, reading sql commands from external hotloading file in /data
This commit is contained in:
parent
9f5e2bb19a
commit
468a1e67e7
|
@ -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)
|
||||
|
|
16
leagues.py
16
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):
|
||||
|
|
|
@ -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(),
|
||||
|
|
Loading…
Reference in a new issue