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"
|
data_dir = "data"
|
||||||
league_dir = "leagues"
|
league_dir = "leagues"
|
||||||
|
statements_file = os.path.join(data_dir, "sql_statements.xvi")
|
||||||
|
|
||||||
def create_connection(league_name):
|
def create_connection(league_name):
|
||||||
#create connection, create db if doesn't exist
|
#create connection, create db if doesn't exist
|
||||||
|
@ -21,6 +22,45 @@ def create_connection(league_name):
|
||||||
print("oops, db connection no work")
|
print("oops, db connection no work")
|
||||||
return conn
|
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):
|
def create_season_connection(league_name, season_num):
|
||||||
#create connection, create db if doesn't exist
|
#create connection, create db if doesn't exist
|
||||||
conn = None
|
conn = None
|
||||||
|
@ -129,6 +169,19 @@ def add_stats(league_name, player_game_stats_list):
|
||||||
conn.commit()
|
conn.commit()
|
||||||
conn.close()
|
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):
|
def update_standings(league_name, update_dic):
|
||||||
if league_exists(league_name):
|
if league_exists(league_name):
|
||||||
conn = create_connection(league_name)
|
conn = create_connection(league_name)
|
||||||
|
|
16
leagues.py
16
leagues.py
|
@ -415,6 +415,22 @@ class league_structure(object):
|
||||||
|
|
||||||
return tournaments
|
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):
|
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):
|
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:
|
else:
|
||||||
await msg.channel.send("Can't find that league, boss.")
|
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):
|
class LeagueDivisionDisplayCommand(Command):
|
||||||
name = "divisionstandings"
|
name = "divisionstandings"
|
||||||
template = "m;divisionstandings [league name]\n[team name]"
|
template = "m;divisionstandings [league name]\n[team name]"
|
||||||
|
@ -1118,6 +1140,7 @@ commands = [
|
||||||
StartLeagueCommand(),
|
StartLeagueCommand(),
|
||||||
LeaguePauseCommand(),
|
LeaguePauseCommand(),
|
||||||
LeagueDisplayCommand(),
|
LeagueDisplayCommand(),
|
||||||
|
LeagueLeadersCommand(),
|
||||||
LeagueDivisionDisplayCommand(),
|
LeagueDivisionDisplayCommand(),
|
||||||
LeagueWildcardCommand(),
|
LeagueWildcardCommand(),
|
||||||
LeagueScheduleCommand(),
|
LeagueScheduleCommand(),
|
||||||
|
|
Loading…
Reference in a new issue