From f9a769ebd36d4909fcc97deddf93d202283fc13c Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Mon, 4 May 2009 20:12:41 +0100 Subject: [PATCH] add summaries to position stats and allow choice of levels --- pyfpdb/Filters.py | 9 ++- pyfpdb/FpdbSQLQueries.py | 128 +++++++++++++++-------------------- pyfpdb/GuiPlayerStats.py | 1 + pyfpdb/GuiPositionalStats.py | 115 ++++++++++++++++++++++--------- 4 files changed, 146 insertions(+), 107 deletions(-) diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py index df6262a3..e319c5fd 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -83,7 +83,7 @@ class Filters(threading.Thread): limitsFrame.show() vbox = gtk.VBox(False, 0) - self.fillLimitsFrame(vbox) + self.fillLimitsFrame(vbox, display) limitsFrame.add(vbox) dateFrame = gtk.Frame("Date:") @@ -197,6 +197,7 @@ class Filters(threading.Thread): cb = gtk.CheckButton(str(limit)) cb.connect('clicked', self.__set_limit_select, limit) hbox.pack_start(cb, False, False, 0) + cb.set_active(True) def __set_site_select(self, w, site): print w.get_active() @@ -245,7 +246,7 @@ class Filters(threading.Thread): else: print "INFO: No games returned from database" - def fillLimitsFrame(self, vbox): + def fillLimitsFrame(self, vbox, display): self.cursor.execute(self.sql.query['getLimits']) result = self.db.cursor.fetchall() if len(result) >= 1: @@ -253,6 +254,10 @@ class Filters(threading.Thread): hbox = gtk.HBox(False, 0) vbox.pack_start(hbox, False, True, 0) self.createLimitLine(hbox, line[0]) + if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2: + hbox = gtk.HBox(False, 0) + vbox.pack_start(hbox, False, True, 0) + self.createLimitLine(hbox, "Separate levels") else: print "INFO: No games returned from database" diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py index d5dc7412..1525b7e4 100644 --- a/pyfpdb/FpdbSQLQueries.py +++ b/pyfpdb/FpdbSQLQueries.py @@ -677,7 +677,6 @@ class FpdbSQLQueries: else format(100.0*sum(street0_3b4bdone)/sum(street0_3b4bchance),1) end AS pf3 ,case when sum(stealattemptchance) = 0 then '-' - else format(100.0*sum(stealattempted)/sum(stealattemptchance),1) end AS steals ,format(100.0*sum(street1Seen)/sum(HDs),1) AS saw_f @@ -709,7 +708,7 @@ class FpdbSQLQueries: inner join Sites s on s.Id = gt.siteId inner join HudCache hc on hc.gameTypeId = gt.Id where hc.playerId in - # use here ? + and group by gt.base ,gt.category ,upper(gt.limitType) @@ -729,7 +728,6 @@ class FpdbSQLQueries: inner join Hands h ON h.id = hp.handId left join HandsActions ha ON ha.handPlayerId = hp.id where hp.playerId in - # use here ? and hp.tourneysPlayersId IS NULL group by hp.handId, h.gameTypeId, hp.position, hp.winnings ) hprof @@ -815,6 +813,7 @@ class FpdbSQLQueries: inner join Sites s on s.Id = gt.siteId inner join HudCache hc on hc.gameTypeId = gt.Id where hc.playerId in + and group by gt.base ,gt.category ,upper(gt.limitType) @@ -853,10 +852,7 @@ class FpdbSQLQueries: concat(upper(stats.limitType), ' ' ,concat(upper(substring(stats.category,1,1)),substring(stats.category,2) ), ' ' ,stats.name, ' $' - ,cast(trim(leading ' ' from - case when stats.bigBlind < 100 then format(stats.bigBlind/100.0,2) - else format(stats.bigBlind/100.0,0) - end ) as char) + ,cast(stats.bigBlindDesc as char) ) AS Game ,case when stats.PlPosition = -2 then 'BB' when stats.PlPosition = -1 then 'SB' @@ -879,25 +875,20 @@ class FpdbSQLQueries: ,stats.TuAFq ,stats.RvAFq ,stats.PoFAFq - /* if you have handsactions data the next 3 fields should give same answer as - following 3 commented out fields */ ,stats.Net ,stats.BBper100 ,stats.Profitperhand - /*,format(hprof2.sum_profit/100.0,2) AS Net - ,format((hprof2.sum_profit/(stats.bigBlind+0.0)) / (stats.n/100.0),2) - AS BBlPer100 - ,hprof2.profitperhand AS Profitperhand - */ - ,format(hprof2.variance,2) AS Variance + ,case when hprof2.variance = -999 then 'NA' + else format(hprof2.variance, 2) + end AS Variance FROM (select /* stats from hudcache */ gt.base ,gt.category - ,upper(gt.limitType) as limitType + ,upper(gt.limitType) AS limitType ,s.name - ,gt.bigBlind - ,hc.gametypeId + , AS bigBlindDesc + , AS gtId ,case when hc.position = 'B' then -2 when hc.position = 'S' then -1 when hc.position = 'D' then 0 @@ -944,18 +935,18 @@ class FpdbSQLQueries: inner join Sites s on s.Id = gt.siteId inner join HudCache hc on hc.gameTypeId = gt.Id where hc.playerId in - # use here ? + and group by gt.base ,gt.category ,upper(gt.limitType) ,s.name - ,gt.bigBlind - ,hc.gametypeId + + ,gtId ,PlPosition ) stats inner join ( select # profit from handsplayers/handsactions - hprof.gameTypeId, + hprof.gtId, case when hprof.position = 'B' then -2 when hprof.position = 'S' then -1 when hprof.position in ('3','4') then 2 @@ -964,23 +955,24 @@ class FpdbSQLQueries: end as PlPosition, sum(hprof.profit) as sum_profit, avg(hprof.profit/100.0) as profitperhand, - variance(hprof.profit/100.0) as variance + case when hprof.gtId = 1 then -999 + else variance(hprof.profit/100.0) + end as variance from - (select hp.handId, h.gameTypeId, hp.position, hp.winnings, SUM(ha.amount) as costs - , hp.winnings - SUM(ha.amount) as profit - from HandsPlayers hp - inner join Hands h ON h.id = hp.handId - left join HandsActions ha ON ha.handPlayerId = hp.id - where hp.playerId in - # use here ? - and hp.tourneysPlayersId IS NULL - group by hp.handId, h.gameTypeId, hp.position, hp.winnings - ) hprof - group by hprof.gameTypeId, PlPosition + (select hp.handId, as gtId, hp.position, hp.winnings + , SUM(ha.amount) as costs, hp.winnings - SUM(ha.amount) as profit + from HandsPlayers hp + inner join Hands h ON h.id = hp.handId + left join HandsActions ha ON ha.handPlayerId = hp.id + where hp.playerId in + and hp.tourneysPlayersId IS NULL + group by hp.handId, gtId, hp.position, hp.winnings + ) hprof + group by hprof.gtId, PlPosition ) hprof2 - on ( hprof2.gameTypeId = stats.gameTypeId + on ( hprof2.gtId = stats.gtId and hprof2.PlPosition = stats.PlPosition) - order by stats.category, stats.limittype, stats.bigBlind, cast(stats.PlPosition as signed) + order by stats.category, stats.limitType, stats.bigBlindDesc, cast(stats.PlPosition as signed) """ elif(self.dbname == 'PostgreSQL'): self.query['playerStatsByPosition'] = """ @@ -988,11 +980,7 @@ class FpdbSQLQueries: upper(stats.limitType) || ' ' || upper(substr(stats.category,1,1)) || substr(stats.category,2) || ' ' || stats.name || ' $' - || trim(leading ' ' from - case when stats.bigBlind < 100 - then to_char(stats.bigBlind/100.0,'90D00') - else to_char(stats.bigBlind/100.0,'999990') - end ) AS Game + || stats.bigBlindDesc AS Game ,case when stats.PlPosition = -2 then 'BB' when stats.PlPosition = -1 then 'SB' when stats.PlPosition = 0 then 'Btn' @@ -1014,25 +1002,20 @@ class FpdbSQLQueries: ,stats.TuAFq ,stats.RvAFq ,stats.PoFAFq - /* if you have handsactions data the next 3 fields should give same answer as - following 3 commented out fields */ ,stats.Net ,stats.BBper100 ,stats.Profitperhand - /*,format(hprof2.sum_profit/100.0,2) AS Net - ,format((hprof2.sum_profit/(stats.bigBlind+0.0)) / (stats.n/100.0),2) - AS BBlPer100 - ,hprof2.profitperhand AS Profitperhand - */ - ,to_char(hprof2.variance, '0D00') AS Variance + ,case when hprof2.variance = -999 then 'NA' + else to_char(hprof2.variance, '0D00') + end AS Variance FROM (select /* stats from hudcache */ gt.base ,gt.category - ,upper(gt.limitType) as limitType + ,upper(gt.limitType) AS limitType ,s.name - ,gt.bigBlind - ,hc.gametypeId + , AS bigBlindDesc + , AS gtId ,case when hc.position = 'B' then -2 when hc.position = 'S' then -1 when hc.position = 'D' then 0 @@ -1040,9 +1023,8 @@ class FpdbSQLQueries: when hc.position = 'M' then 2 when hc.position = 'E' then 5 else 9 - end as PlPosition + end AS PlPosition ,sum(HDs) AS n - ,to_char(round(100.0*sum(street0VPI)/sum(HDs)),'90D0') AS vpip ,to_char(round(100.0*sum(street0Aggr)/sum(HDs)),'90D0') AS pfr ,case when sum(street0_3b4bchance) = 0 then '0' @@ -1074,23 +1056,22 @@ class FpdbSQLQueries: end AS PoFAFq ,to_char(sum(totalProfit)/100.0,'9G999G990D00') AS Net ,case when sum(HDs) = 0 then '0' - else to_char((sum(totalProfit)/(gt.bigBlind+0.0)) / (sum(HDs)/100.0), '990D00') + else to_char(sum(totalProfit/(gt.bigBlind+0.0)) / (sum(HDs)/100.0), '990D00') end AS BBper100 ,case when sum(HDs) = 0 then '0' else to_char( (sum(totalProfit)/100.0) / sum(HDs), '90D0000') end AS Profitperhand - from Gametypes gt inner join Sites s on (s.Id = gt.siteId) inner join HudCache hc on (hc.gameTypeId = gt.Id) where hc.playerId in - /* use here ? */ + and group by gt.base ,gt.category ,upper(gt.limitType) ,s.name - ,gt.bigBlind - ,hc.gametypeId + + ,gtId ,PlPosition ) stats inner join @@ -1104,23 +1085,24 @@ class FpdbSQLQueries: end as PlPosition, sum(hprof.profit) as sum_profit, avg(hprof.profit/100.0) as profitperhand, - variance(hprof.profit/100.0) as variance + case when hprof.gameTypeId = 1 then -999 + else variance(hprof.profit/100.0) + end as variance from - (select hp.handId, h.gameTypeId, hp.position, hp.winnings, SUM(ha.amount) as costs - , hp.winnings - SUM(ha.amount) as profit - from HandsPlayers hp - inner join Hands h ON h.id = hp.handId - left join HandsActions ha ON ha.handPlayerId = hp.id - where hp.playerId in - /* use here ? */ - and hp.tourneysPlayersId IS NULL - group by hp.handId, h.gameTypeId, hp.position, hp.winnings - ) hprof + (select hp.handId, as gameTypeId, hp.position, hp.winnings + , SUM(ha.amount) as costs, hp.winnings - SUM(ha.amount) as profit + from HandsPlayers hp + inner join Hands h ON h.id = hp.handId + left join HandsActions ha ON ha.handPlayerId = hp.id + where hp.playerId in + and hp.tourneysPlayersId IS NULL + group by hp.handId, gameTypeId, hp.position, hp.winnings + ) hprof group by hprof.gameTypeId, PlPosition - ) hprof2 - on ( hprof2.gameTypeId = stats.gameTypeId + ) hprof2 + on ( hprof2.gameTypeId = stats.gtId and hprof2.PlPosition = stats.PlPosition) - order by stats.category, stats.limittype, stats.bigBlind, cast(stats.PlPosition as smallint) + order by stats.category, stats.limitType, stats.bigBlindDesc, cast(stats.PlPosition as smallint) """ elif(self.dbname == 'SQLite'): self.query['playerStatsByPosition'] = """ """ diff --git a/pyfpdb/GuiPlayerStats.py b/pyfpdb/GuiPlayerStats.py index e3ab446c..aef2ba38 100644 --- a/pyfpdb/GuiPlayerStats.py +++ b/pyfpdb/GuiPlayerStats.py @@ -115,6 +115,7 @@ class GuiPlayerStats (threading.Thread): nametest = nametest.replace(",)",")") tmp = tmp.replace("", nametest) + tmp = tmp.replace("", "1 = 1") self.cursor.execute(tmp) result = self.cursor.fetchall() diff --git a/pyfpdb/GuiPositionalStats.py b/pyfpdb/GuiPositionalStats.py index 70a877f0..9346bff2 100644 --- a/pyfpdb/GuiPositionalStats.py +++ b/pyfpdb/GuiPositionalStats.py @@ -36,6 +36,9 @@ class GuiPositionalStats (threading.Thread): self.db.do_connect(self.conf) self.cursor=self.db.cursor self.sql = querylist + self.MYSQL_INNODB = 2 + self.PGSQL = 3 + self.SQLITE = 4 settings = {} settings.update(config.get_db_parameters()) @@ -43,13 +46,14 @@ class GuiPositionalStats (threading.Thread): settings.update(config.get_import_parameters()) settings.update(config.get_default_paths()) - filters_display = { "Heroes" : True, - "Sites" : True, - "Games" : False, - "Limits" : False, - "Dates" : False, - "Button1" : True, - "Button2" : False + filters_display = { "Heroes" : True, + "Sites" : True, + "Games" : False, + "Limits" : True, + "LimitSep" : True, + "Dates" : False, + "Button1" : True, + "Button2" : False } self.filters = Filters.Filters(db, settings, config, querylist, display = filters_display) @@ -107,6 +111,7 @@ class GuiPositionalStats (threading.Thread): sites = self.filters.getSites() heroes = self.filters.getHeroes() siteids = self.filters.getSiteIds() + limits = self.filters.getLimits() sitenos = [] playerids = [] @@ -126,19 +131,15 @@ class GuiPositionalStats (threading.Thread): if not playerids: print "No player ids found" return + if not limits: + print "No limits found" + return - self.createStatsTable(vbox, playerids, sitenos) + self.createStatsTable(vbox, playerids, sitenos, limits) - def createStatsTable(self, vbox, playerids, sitenos): + def createStatsTable(self, vbox, playerids, sitenos, limits): tmp = self.sql.query['playerStatsByPosition'] - - nametest = str(tuple(playerids)) - nametest = nametest.replace("L", "") - nametest = nametest.replace(",)",")") - - tmp = tmp.replace("", nametest) - #tmp = tmp.replace("", "gt.id") - + tmp = self.refineQuery(tmp, playerids, sitenos, limits) self.cursor.execute(tmp) result = self.cursor.fetchall() self.stats_table = gtk.Table(1, 1, False) # gtk table expands as required @@ -195,13 +196,14 @@ class GuiPositionalStats (threading.Thread): # show totals at bottom tmp = self.sql.query['playerStats'] - tmp = tmp.replace("", nametest) + tmp = self.refineQuery(tmp, playerids, sitenos, limits) + self.cursor.execute(tmp) result = self.cursor.fetchall() rows = len(result) colnames = [desc[0].lower() for desc in self.cursor.description] - # blank row + # blank row between main stats and totals: col = 0 if(row%2 == 0): bgcolor = "white" @@ -249,18 +251,67 @@ class GuiPositionalStats (threading.Thread): self.db.db.rollback() #end def fillStatsFrame(self, vbox): + def refineQuery(self, query, playerids, sitenos, limits): + nametest = str(tuple(playerids)) + nametest = nametest.replace("L", "") + nametest = nametest.replace(",)",")") + query = query.replace("", nametest) + blindtest = str(tuple([x for x in limits if str(x).isdigit()])) + blindtest = blindtest.replace("L", "") + blindtest = blindtest.replace(",)",")") + query = query.replace("", "gt.bigBlind in " + blindtest) - - - - - - - - - - - - - + groupLevels = "Separate" not in str(limits) + if groupLevels: + if self.db.backend == self.MYSQL_INNODB: + bigblindselect = """concat(trim(leading ' ' from + case when min(gt.bigBlind) < 100 + then format(min(gt.bigBlind)/100.0, 2) + else format(min(gt.bigBlind)/100.0, 0) + end) + ,' - ' + trim(leading ' ' from + case when max(gt.bigBlind) < 100 + then format(max(gt.bigBlind)/100.0, 2) + else format(max(gt.bigBlind)/100.0, 0) + end) + ) """ + else: + bigblindselect = """trim(leading ' ' from + case when min(gt.bigBlind) < 100 + then to_char(min(gt.bigBlind)/100.0,'90D00') + else to_char(min(gt.bigBlind)/100.0,'999990') + end) + || ' - ' || + trim(leading ' ' from + case when max(gt.bigBlind) < 100 + then to_char(max(gt.bigBlind)/100.0,'90D00') + else to_char(max(gt.bigBlind)/100.0,'999990') + end) """ + query = query.replace("", bigblindselect) + query = query.replace("", "") + query = query.replace("", "-1") + query = query.replace("", "-1") + else: + if self.db.backend == self.MYSQL_INNODB: + bigblindselect = """trim(leading ' ' from + case when gt.bigBlind < 100 + then format(gt.bigBlind/100.0, 2) + else format(gt.bigBlind/100.0, 0) + end + ) """ + else: + bigblindselect = """trim(leading ' ' from + case when gt.bigBlind < 100 + then to_char(gt.bigBlind/100.0,'90D00') + else to_char(gt.bigBlind/100.0,'999990') + end + ) """ + query = query.replace("", bigblindselect) + query = query.replace("", ",gt.bigBlind") + query = query.replace("", "hc.gametypeId") + query = query.replace("", "h.gameTypeId") + #print "query =\n", query + return(query) + #end def refineQuery(self, query, playerids, sitenos, limits):