diff --git a/pyfpdb/Database.py b/pyfpdb/Database.py index 38c475d9..e05a38b8 100755 --- a/pyfpdb/Database.py +++ b/pyfpdb/Database.py @@ -431,6 +431,11 @@ class Database: if hud_style == 'S' or h_hud_style == 'S': self.get_stats_from_hand_session(hand, stat_dict, hero_id, hud_style, h_hud_style) + try: + print "Session: hero_id =", hero_id, "hds =", stat_dict[hero_id]['n'] + except: + pass + if hud_style == 'S' and h_hud_style == 'S': return stat_dict @@ -452,7 +457,7 @@ class Database: #elif h_hud_style == 'H': # h_stylekey = date_nhands_ago needs array by player here ... - #if aggregate: always use aggreagte query now: use agg_bb_mult of 1 for no aggregation: + #if aggregate: always use aggregate query now: use agg_bb_mult of 1 for no aggregation: query = 'get_stats_from_hand_aggregated' subs = (hand, hero_id, stylekey, agg_bb_mult, agg_bb_mult, hero_id, h_stylekey, h_agg_bb_mult, h_agg_bb_mult) print "agg query subs:", subs @@ -474,6 +479,10 @@ class Database: t_dict[name.lower()] = val # print t_dict stat_dict[t_dict['player_id']] = t_dict + try: + print "get_stats end: hero_id =", hero_id, "hds =", stat_dict[hero_id]['n'] + except: + pass return stat_dict diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py index d4563059..2a02aedf 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -54,6 +54,7 @@ class Filters(threading.Thread): ,'seatsbetween':'Between:', 'seatsand':'And:', 'seatsshow':'Show Number of _Players' ,'limitstitle':'Limits:', 'seatstitle':'Number of Players:' ,'groupstitle':'Grouping:', 'posnshow':'Show Position Stats:' + ,'limitsFL':'FL', 'limitsNL':'NL' } # For use in date ranges. @@ -98,6 +99,8 @@ class Filters(threading.Thread): self.cbLimits = {} self.cbNoLimits = None self.cbAllLimits = None + self.cbFL = None + self.cbNL = None self.fillLimitsFrame(vbox, self.display) limitsFrame.add(vbox) @@ -288,12 +291,29 @@ class Filters(threading.Thread): self.cbAllLimits.set_active(False) elif limit == "all": if self.limits[limit]: - for cb in self.cbLimits.values(): - cb.set_active(True) + #for cb in self.cbLimits.values(): + # cb.set_active(True) + if self.cbFL != None: + self.cbFL.set_active(True) + if self.cbNL != None: + self.cbNL.set_active(True) elif limit == "none": if self.limits[limit]: for cb in self.cbLimits.values(): cb.set_active(False) + self.cbNL.set_active(False) + self.cbFL.set_active(False) + elif limit == "fl": + for cb in self.cbLimits.values(): + #print "cb label: ", cb.children()[0].get_text() + if cb.get_children()[0].get_text().isdigit(): + cb.set_active(self.limits[limit]) + + elif limit == "nl": + for cb in self.cbLimits.values(): + t = cb.get_children()[0].get_text() + if "nl" in t and len(t) > 2: + cb.set_active(self.limits[limit]) def __set_seat_select(self, w, seat): #print "__set_seat_select: seat =", seat, "active =", w.get_active() @@ -352,8 +372,10 @@ class Filters(threading.Thread): vbox.pack_start(vbox1, False, False, 0) self.boxes['limits'] = vbox1 - self.cursor.execute(self.sql.query['getLimits']) + self.cursor.execute(self.sql.query['getLimits2']) + # selects limitType, bigBlind result = self.db.cursor.fetchall() + fl, nl = False, False if len(result) >= 1: hbox = gtk.HBox(True, 0) vbox1.pack_start(hbox, False, False, 0) @@ -367,17 +389,37 @@ class Filters(threading.Thread): vbox2.pack_start(hbox, False, False, 0) else: vbox3.pack_start(hbox, False, False, 0) - self.cbLimits[line[0]] = self.createLimitLine(hbox, line[0], line[0]) + if line[0] == 'fl': + self.cbLimits[line[1]] = self.createLimitLine(hbox, str(line[1]), str(line[1])) + fl = True + else: + self.cbLimits[str(line[1])+line[0]] = self.createLimitLine(hbox, str(line[1])+line[0], str(line[1])+line[0]) + nl = True if "LimitSep" in display and display["LimitSep"] == True and len(result) >= 2: + hbox = gtk.HBox(True, 0) + vbox1.pack_start(hbox, False, False, 0) + vbox2 = gtk.VBox(False, 0) + hbox.pack_start(vbox2, False, False, 0) + vbox3 = gtk.VBox(False, 0) + hbox.pack_start(vbox3, False, False, 0) + hbox = gtk.HBox(False, 0) - vbox1.pack_start(hbox, False, True, 0) + vbox2.pack_start(hbox, False, False, 0) self.cbAllLimits = self.createLimitLine(hbox, 'all', self.filterText['limitsall']) hbox = gtk.HBox(False, 0) - vbox1.pack_start(hbox, False, True, 0) + vbox2.pack_start(hbox, False, False, 0) self.cbNoLimits = self.createLimitLine(hbox, 'none', self.filterText['limitsnone']) - hbox = gtk.HBox(False, 0) - vbox1.pack_start(hbox, False, True, 0) - cb = self.createLimitLine(hbox, 'show', self.filterText['limitsshow']) + + if "LimitType" in display and display["LimitType"] == True and len(result) >= 2: + if fl: + hbox = gtk.HBox(False, 0) + vbox3.pack_start(hbox, False, False, 0) + self.cbFL = self.createLimitLine(hbox, 'fl', self.filterText['limitsFL']) + if nl: + hbox = gtk.HBox(False, 0) + vbox3.pack_start(hbox, False, False, 0) + self.cbNL = self.createLimitLine(hbox, 'nl', self.filterText['limitsNL']) + else: print "INFO: No games returned from database" @@ -411,15 +453,6 @@ class Filters(threading.Thread): hbox.pack_start(lbl_to, expand=False, padding=3) hbox.pack_start(sb2, False, False, 0) - if "SeatSep" in display and display["SeatSep"] == True: - hbox = gtk.HBox(False, 0) - vbox1.pack_start(hbox, False, True, 0) - cb = gtk.CheckButton(self.filterText['seatsshow']) - cb.connect('clicked', self.__set_seat_select, 'show') - hbox.pack_start(cb, False, False, 0) - self.sbSeats['show'] = cb - self.seats['show'] = False - self.sbSeats['from'] = sb1 self.sbSeats['to'] = sb2 @@ -439,14 +472,26 @@ class Filters(threading.Thread): self.boxes['groups'] = vbox1 hbox = gtk.HBox(False, 0) - vbox1.pack_start(hbox, False, True, 0) + vbox1.pack_start(hbox, False, False, 0) + cb = self.createLimitLine(hbox, 'show', self.filterText['limitsshow']) + hbox = gtk.HBox(False, 0) + vbox1.pack_start(hbox, False, True, 0) cb = gtk.CheckButton(self.filterText['posnshow']) cb.connect('clicked', self.__set_group_select, 'posn') hbox.pack_start(cb, False, False, 0) self.sbGroups['posn'] = cb self.groups['posn'] = False + if "SeatSep" in display and display["SeatSep"] == True: + hbox = gtk.HBox(False, 0) + vbox1.pack_start(hbox, False, True, 0) + cb = gtk.CheckButton(self.filterText['seatsshow']) + cb.connect('clicked', self.__set_seat_select, 'show') + hbox.pack_start(cb, False, False, 0) + self.sbSeats['show'] = cb + self.seats['show'] = False + def fillCardsFrame(self, vbox): hbox1 = gtk.HBox(True,0) hbox1.show() diff --git a/pyfpdb/GuiPlayerStats.py b/pyfpdb/GuiPlayerStats.py index add46bef..007ab4dd 100644 --- a/pyfpdb/GuiPlayerStats.py +++ b/pyfpdb/GuiPlayerStats.py @@ -54,17 +54,18 @@ class GuiPlayerStats (threading.Thread): self.filterText = {'handhead':'Hand Breakdown for all levels listed above' } - filters_display = { "Heroes" : True, - "Sites" : True, - "Games" : False, - "Limits" : True, - "LimitSep" : True, - "Seats" : True, - "SeatSep" : True, - "Dates" : True, - "Groups" : True, - "Button1" : True, - "Button2" : True + filters_display = { "Heroes" : True, + "Sites" : True, + "Games" : False, + "Limits" : True, + "LimitSep" : True, + "LimitType" : True, + "Seats" : True, + "SeatSep" : True, + "Dates" : True, + "Groups" : True, + "Button1" : True, + "Button2" : True } self.filters = Filters.Filters(self.db, self.conf, self.sql, display = filters_display) @@ -344,13 +345,26 @@ class GuiPlayerStats (threading.Thread): query = query.replace('', '') query = query.replace('', '') - if [x for x in limits if str(x).isdigit()]: - blindtest = str(tuple([x for x in limits if str(x).isdigit()])) + lims = [int(x) for x in limits if x.isdigit()] + nolims = [int(x[0:-2]) for x in limits if len(x) > 2 and x[-2:] == 'nl'] + bbtest = "and ( (gt.limitType = 'fl' and gt.bigBlind in " + # and ( (limit and bb in()) or (nolimit and bb in ()) ) + if lims: + blindtest = str(tuple(lims)) blindtest = blindtest.replace("L", "") blindtest = blindtest.replace(",)",")") - query = query.replace("", " and gt.bigBlind in " + blindtest + " ") + bbtest = bbtest + blindtest + ' ) ' else: - query = query.replace("", "") + bbtest = bbtest + '(-1) ) ' + bbtest = bbtest + " or (gt.limitType = 'nl' and gt.bigBlind in " + if nolims: + blindtest = str(tuple(nolims)) + blindtest = blindtest.replace("L", "") + blindtest = blindtest.replace(",)",")") + bbtest = bbtest + blindtest + ' ) )' + else: + bbtest = bbtest + '(-1) ) )' + query = query.replace("", bbtest) if holecards: # pinch level variables for hole card query query = query.replace("", "hp.startcards") diff --git a/pyfpdb/SQL.py b/pyfpdb/SQL.py index 1145afec..9279126e 100644 --- a/pyfpdb/SQL.py +++ b/pyfpdb/SQL.py @@ -1720,6 +1720,9 @@ class Sql: self.query['getSiteId'] = """SELECT id from Sites where name = %s""" self.query['getGames'] = """SELECT DISTINCT category from Gametypes""" self.query['getLimits'] = """SELECT DISTINCT bigBlind from Gametypes ORDER by bigBlind DESC""" + self.query['getLimits2'] = """SELECT DISTINCT limitType, bigBlind + from Gametypes + ORDER by limitType DESC, bigBlind DESC""" if db_server == 'mysql': self.query['playerDetailedStats'] = """ @@ -1775,7 +1778,7 @@ class Sql: inner join Gametypes gt on (gt.Id = h.gameTypeId) inner join Sites s on (s.Id = gt.siteId) where hp.playerId in - and hp.tourneysPlayersId IS NULL + /*and hp.tourneysPlayersId IS NULL*/ and h.seats @@ -1797,11 +1800,11 @@ class Sql: else concat('Z', ) end + ,upper(gt.limitType) desc ,maxbigblind desc - ,upper(gt.limitType) ,s.name """ - else: # assume postgresql + elif db_server == 'postgresql': self.query['playerDetailedStats'] = """ select AS hgametypeid ,gt.base @@ -1855,7 +1858,7 @@ class Sql: inner join Gametypes gt on (gt.Id = h.gameTypeId) inner join Sites s on (s.Id = gt.siteId) where hp.playerId in - and hp.tourneysPlayersId IS NULL + /*and hp.tourneysPlayersId IS NULL*/ and h.seats @@ -1878,12 +1881,91 @@ class Sql: else 'Z'|| end + ,upper(gt.limitType) desc + ,maxbigblind desc + ,s.name + """ + elif db_server == 'sqlite': + self.query['playerDetailedStats'] = """ + select AS hgametypeid + ,gt.base + ,gt.category + ,upper(gt.limitType) AS limittype + ,s.name + ,min(gt.bigBlind) AS minbigblind + ,max(gt.bigBlind) AS maxbigblind + /*, AS gtid*/ + , AS plposition + ,count(1) AS n + ,100.0*sum(cast(hp.street0VPI as integer))/count(1) AS vpip + ,100.0*sum(cast(hp.street0Aggr as integer))/count(1) AS pfr + ,case when sum(cast(hp.street0_3Bchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street0_3Bdone as integer))/sum(cast(hp.street0_3Bchance as integer)) + end AS pf3 + ,case when sum(cast(hp.stealattemptchance as integer)) = 0 then -999 + else 100.0*sum(cast(hp.stealattempted as integer))/sum(cast(hp.stealattemptchance as integer)) + end AS steals + ,100.0*sum(cast(hp.street1Seen as integer))/count(1) AS saw_f + ,100.0*sum(cast(hp.sawShowdown as integer))/count(1) AS sawsd + ,case when sum(cast(hp.street1Seen as integer)) = 0 then -999 + else 100.0*sum(cast(hp.sawShowdown as integer))/sum(cast(hp.street1Seen as integer)) + end AS wtsdwsf + ,case when sum(cast(hp.sawShowdown as integer)) = 0 then -999 + else 100.0*sum(cast(hp.wonAtSD as integer))/sum(cast(hp.sawShowdown as integer)) + end AS wmsd + ,case when sum(cast(hp.street1Seen as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street1Aggr as integer))/sum(cast(hp.street1Seen as integer)) + end AS flafq + ,case when sum(cast(hp.street2Seen as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street2Aggr as integer))/sum(cast(hp.street2Seen as integer)) + end AS tuafq + ,case when sum(cast(hp.street3Seen as integer)) = 0 then -999 + else 100.0*sum(cast(hp.street3Aggr as integer))/sum(cast(hp.street3Seen as integer)) + end AS rvafq + ,case when sum(cast(hp.street1Seen as integer))+sum(cast(hp.street2Seen as integer))+sum(cast(hp.street3Seen as integer)) = 0 then -999 + else 100.0*(sum(cast(hp.street1Aggr as integer))+sum(cast(hp.street2Aggr as integer))+sum(cast(hp.street3Aggr as integer))) + /(sum(cast(hp.street1Seen as integer))+sum(cast(hp.street2Seen as integer))+sum(cast(hp.street3Seen as integer))) + end AS pofafq + ,sum(hp.totalProfit)/100.0 AS net + ,sum(hp.rake)/100.0 AS rake + ,100.0*avg(hp.totalProfit/(gt.bigBlind+0.0)) AS bbper100 + ,avg(hp.totalProfit)/100.0 AS profitperhand + ,100.0*avg((hp.totalProfit+hp.rake)/(gt.bigBlind+0.0)) AS bb100xr + ,avg((hp.totalProfit+hp.rake)/100.0) AS profhndxr + ,avg(h.seats+0.0) AS avgseats + ,variance(hp.totalProfit/100.0) AS variance + from HandsPlayers hp + inner join Hands h on (h.id = hp.handId) + inner join Gametypes gt on (gt.Id = h.gameTypeId) + inner join Sites s on (s.Id = gt.siteId) + where hp.playerId in + /*and hp.tourneysPlayersId IS NULL*/ + and h.seats + + + and to_char(h.handStart, 'YYYY-MM-DD') + group by hgameTypeId + ,hp.playerId + ,gt.base + ,gt.category + + ,plposition + ,upper(gt.limitType) + ,s.name + order by hp.playerId + ,gt.base + ,gt.category + + ,case when 'B' then 'B' + when 'S' then 'S' + when '0' then 'Y' + else 'Z'|| + end + + ,upper(gt.limitType) desc ,maxbigblind desc - ,upper(gt.limitType) ,s.name """ - #elif db_server == 'sqlite': - # self.query['playerDetailedStats'] = """ """ if db_server == 'mysql': self.query['playerStats'] = """