From fce9941b0c761d237a5692daaef75f7d1aceace5 Mon Sep 17 00:00:00 2001 From: sqlcoder Date: Mon, 8 Jun 2009 00:17:48 +0100 Subject: [PATCH] add position capability to playerstats tab --- pyfpdb/Filters.py | 47 +++++++++++++++++++++- pyfpdb/FpdbSQLQueries.py | 18 +++++++-- pyfpdb/GuiPlayerStats.py | 86 +++++++++++++++++++++++++--------------- 3 files changed, 114 insertions(+), 37 deletions(-) diff --git a/pyfpdb/Filters.py b/pyfpdb/Filters.py index 3a5f0365..4846b998 100644 --- a/pyfpdb/Filters.py +++ b/pyfpdb/Filters.py @@ -44,6 +44,7 @@ class Filters(threading.Thread): self.games = {} self.limits = {} self.seats = {} + self.groups = {} self.siteid = {} self.heroes = {} self.boxes = {} @@ -52,6 +53,7 @@ class Filters(threading.Thread): self.filterText = {'limitsall':'All', 'limitsnone':'None', 'limitsshow':'Show _Limits' ,'seatsbetween':'Between:', 'seatsand':'And:', 'seatsshow':'Show Number of _Players' ,'limitstitle':'Limits:', 'seatstitle':'Number of Players:' + ,'groupstitle':'Grouping:', 'posnshow':'Show Position Stats:' } # For use in date ranges. @@ -109,6 +111,15 @@ class Filters(threading.Thread): self.fillSeatsFrame(vbox, self.display) seatsFrame.add(vbox) + # Groups + groupsFrame = gtk.Frame() + groupsFrame.show() + vbox = gtk.VBox(False, 0) + self.sbGroups = {} + + self.fillGroupsFrame(vbox, self.display) + groupsFrame.add(vbox) + # Date dateFrame = gtk.Frame("Date:") dateFrame.set_label_align(0.0, 0.0) @@ -131,6 +142,7 @@ class Filters(threading.Thread): self.mainVBox.add(gamesFrame) self.mainVBox.add(limitsFrame) self.mainVBox.add(seatsFrame) + self.mainVBox.add(groupsFrame) self.mainVBox.add(dateFrame) self.mainVBox.add(self.Button1) self.mainVBox.add(self.Button2) @@ -148,6 +160,8 @@ class Filters(threading.Thread): limitsFrame.hide() if "Seats" not in self.display or self.display["Seats"] == False: seatsFrame.hide() + if "Groups" not in self.display or self.display["Groups"] == False: + groupsFrame.hide() if "Dates" not in self.display or self.display["Dates"] == False: dateFrame.hide() if "Button1" not in self.display or self.display["Button1"] == False: @@ -183,6 +197,9 @@ class Filters(threading.Thread): self.seats['to'] = self.sbSeats['to'].get_value_as_int() return self.seats + def getGroups(self): + return self.groups + def getDates(self): return self.__get_dates() @@ -274,6 +291,11 @@ class Filters(threading.Thread): self.seats[seat] = w.get_active() print "self.seats[%s] set to %s" %(seat, self.seats[seat]) + def __set_group_select(self, w, group): + #print "__set_seat_select: seat =", seat, "active =", w.get_active() + self.groups[group] = w.get_active() + print "self.groups[%s] set to %s" %(group, self.groups[group]) + def fillPlayerFrame(self, vbox): for site in self.conf.get_supported_sites(): pathHBox = gtk.HBox(False, 0) @@ -389,10 +411,33 @@ class Filters(threading.Thread): self.sbSeats['show'] = cb self.seats['show'] = False - self.sbSeats['from'] = sb1 self.sbSeats['to'] = sb2 + def fillGroupsFrame(self, vbox, display): + hbox = gtk.HBox(False, 0) + vbox.pack_start(hbox, False, False, 0) + lbl_title = gtk.Label(self.filterText['groupstitle']) + lbl_title.set_alignment(xalign=0.0, yalign=0.5) + hbox.pack_start(lbl_title, expand=True, padding=3) + showb = gtk.Button(label="hide", stock=None, use_underline=True) + showb.set_alignment(xalign=1.0, yalign=0.5) + showb.connect('clicked', self.__toggle_box, 'groups') + hbox.pack_start(showb, expand=False, padding=1) + + vbox1 = gtk.VBox(False, 0) + vbox.pack_start(vbox1, False, False, 0) + self.boxes['groups'] = vbox1 + + 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 + def fillCardsFrame(self, vbox): hbox1 = gtk.HBox(True,0) hbox1.show() diff --git a/pyfpdb/FpdbSQLQueries.py b/pyfpdb/FpdbSQLQueries.py index 4445908e..598c0868 100644 --- a/pyfpdb/FpdbSQLQueries.py +++ b/pyfpdb/FpdbSQLQueries.py @@ -910,6 +910,7 @@ class FpdbSQLQueries: ,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 @@ -963,12 +964,17 @@ class FpdbSQLQueries: ,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' + else concat('Z', ) + end ,maxbigblind desc ,upper(gt.limitType) @@ -983,7 +989,8 @@ class FpdbSQLQueries: ,s.name ,min(gt.bigBlind) AS minbigblind ,max(gt.bigBlind) AS maxbigblind - /*, AS gtid*/ + /*, 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 @@ -993,8 +1000,8 @@ class FpdbSQLQueries: ,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 + ,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 @@ -1037,12 +1044,17 @@ class FpdbSQLQueries: ,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' + else 'Z'|| + end ,maxbigblind desc ,upper(gt.limitType) diff --git a/pyfpdb/GuiPlayerStats.py b/pyfpdb/GuiPlayerStats.py index 28990279..268aeab3 100644 --- a/pyfpdb/GuiPlayerStats.py +++ b/pyfpdb/GuiPlayerStats.py @@ -76,27 +76,28 @@ class GuiPlayerStats (threading.Thread): # ToDo: create popup to adjust column config # columns to display, keys match column name returned by sql, values in tuple are: # is column displayed, column heading, xalignment, formatting - self.columns = [ ("game", True, "Game", 0.0, "%s") - , ("hand", False, "Hand", 0.0, "%s") # true not allowed for this line - , ("n", True, "Hds", 1.0, "%d") - , ("avgseats", True, "Seats", 1.0, "%3.1f") - , ("vpip", True, "VPIP", 1.0, "%3.1f") - , ("pfr", True, "PFR", 1.0, "%3.1f") - , ("pf3", True, "PF3", 1.0, "%3.1f") - , ("steals", True, "Steals", 1.0, "%3.1f") - , ("saw_f", True, "Saw_F", 1.0, "%3.1f") - , ("sawsd", True, "SawSD", 1.0, "%3.1f") - , ("wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f") - , ("wmsd", True, "W$SD", 1.0, "%3.1f") - , ("flafq", True, "FlAFq", 1.0, "%3.1f") - , ("tuafq", True, "TuAFq", 1.0, "%3.1f") - , ("rvafq", True, "RvAFq", 1.0, "%3.1f") - , ("pofafq", False, "PoFAFq", 1.0, "%3.1f") - , ("net", True, "Net($)", 1.0, "%6.2f") - , ("bbper100", True, "bb/100", 1.0, "%4.2f") - , ("rake", True, "Rake($)", 1.0, "%6.2f") - , ("bb100xr", True, "bbxr/100", 1.0, "%4.2f") - , ("variance", True, "Variance", 1.0, "%5.2f") + self.columns = [ ["game", True, "Game", 0.0, "%s"] + , ["hand", False, "Hand", 0.0, "%s"] # true not allowed for this line + , ["plposition", False, "Posn", 1.0, "%s"] # true not allowed for this line (set in code) + , ["n", True, "Hds", 1.0, "%d"] + , ["avgseats", True, "Seats", 1.0, "%3.1f"] + , ["vpip", True, "VPIP", 1.0, "%3.1f"] + , ["pfr", True, "PFR", 1.0, "%3.1f"] + , ["pf3", True, "PF3", 1.0, "%3.1f"] + , ["steals", True, "Steals", 1.0, "%3.1f"] + , ["saw_f", True, "Saw_F", 1.0, "%3.1f"] + , ["sawsd", True, "SawSD", 1.0, "%3.1f"] + , ["wtsdwsf", True, "WtSDwsF", 1.0, "%3.1f"] + , ["wmsd", True, "W$SD", 1.0, "%3.1f"] + , ["flafq", True, "FlAFq", 1.0, "%3.1f"] + , ["tuafq", True, "TuAFq", 1.0, "%3.1f"] + , ["rvafq", True, "RvAFq", 1.0, "%3.1f"] + , ["pofafq", False, "PoFAFq", 1.0, "%3.1f"] + , ["net", True, "Net($)", 1.0, "%6.2f"] + , ["bbper100", True, "bb/100", 1.0, "%4.2f"] + , ["rake", True, "Rake($)", 1.0, "%6.2f"] + , ["bb100xr", True, "bbxr/100", 1.0, "%4.2f"] + , ["variance", True, "Variance", 1.0, "%5.2f"] ] # Detail filters: This holds the data used in the popup window, extra values are @@ -136,7 +137,7 @@ class GuiPlayerStats (threading.Thread): self.main_hbox.pack_start(self.stats_frame, expand=True, fill=True) # make sure Hand column is not displayed - [x for x in self.columns if x[0] == 'hand'][0][1] == False + [x for x in self.columns if x[0] == 'hand'][0][1] = False def get_vbox(self): """returns the vbox of this thread""" @@ -156,6 +157,7 @@ class GuiPlayerStats (threading.Thread): siteids = self.filters.getSiteIds() limits = self.filters.getLimits() seats = self.filters.getSeats() + groups = self.filters.getGroups() dates = self.filters.getDates() sitenos = [] playerids = [] @@ -180,16 +182,16 @@ class GuiPlayerStats (threading.Thread): print "No limits found" return - self.createStatsTable(vbox, playerids, sitenos, limits, seats, dates) + self.createStatsTable(vbox, playerids, sitenos, limits, seats, groups, dates) - def createStatsTable(self, vbox, playerids, sitenos, limits, seats, dates): + def createStatsTable(self, vbox, playerids, sitenos, limits, seats, groups, dates): starttime = time() # Display summary table at top of page # 3rd parameter passes extra flags, currently includes: # holecards - whether to display card breakdown (True/False) flags = [False] - self.addTable(vbox, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, dates) + self.addTable(vbox, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, groups, dates) # Separator sep = gtk.HSeparator() @@ -212,13 +214,13 @@ class GuiPlayerStats (threading.Thread): # Detailed table flags = [True] - self.addTable(vbox1, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, dates) + self.addTable(vbox1, 'playerDetailedStats', flags, playerids, sitenos, limits, seats, groups, dates) self.db.db.commit() print "Stats page displayed in %4.2f seconds" % (time() - starttime) #end def fillStatsFrame(self, vbox): - def addTable(self, vbox, query, flags, playerids, sitenos, limits, seats, dates): + def addTable(self, vbox, query, flags, playerids, sitenos, limits, seats, groups, dates): row = 0 sqlrow = 0 colalias,colshow,colheading,colxalign,colformat = 0,1,2,3,4 @@ -231,7 +233,7 @@ class GuiPlayerStats (threading.Thread): self.stats_table.show() tmp = self.sql.query[query] - tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, seats, dates) + tmp = self.refineQuery(tmp, flags, playerids, sitenos, limits, seats, groups, dates) self.cursor.execute(tmp) result = self.cursor.fetchall() colnames = [desc[0].lower() for desc in self.cursor.description] @@ -245,6 +247,8 @@ class GuiPlayerStats (threading.Thread): view.set_grid_lines(gtk.TREE_VIEW_GRID_LINES_BOTH) vbox.pack_start(view, expand=False, padding=3) textcell = gtk.CellRendererText() + textcell50 = gtk.CellRendererText() + textcell50.set_property('xalign', 0.5) numcell = gtk.CellRendererText() numcell.set_property('xalign', 1.0) listcols = [] @@ -258,17 +262,18 @@ class GuiPlayerStats (threading.Thread): listcols.append(gtk.TreeViewColumn(s)) view.append_column(listcols[col]) if column[colformat] == '%s': - if col == 1 and holecards: + if column[colxalign] == 0.0: listcols[col].pack_start(textcell, expand=True) + listcols[col].add_attribute(textcell, 'text', col) else: - listcols[col].pack_start(textcell, expand=True) - listcols[col].add_attribute(textcell, 'text', col) + listcols[col].pack_start(textcell50, expand=True) + listcols[col].add_attribute(textcell50, 'text', col) listcols[col].set_expand(True) else: listcols[col].pack_start(numcell, expand=True) listcols[col].add_attribute(numcell, 'text', col) - listcols[col].set_alignment(1.0) listcols[col].set_expand(True) + #listcols[col].set_alignment(column[colxalign]) # no effect? rows = len(result) # +1 for title row @@ -281,6 +286,11 @@ class GuiPlayerStats (threading.Thread): for col,column in enumerate(cols_to_show): if column[colalias] in colnames: value = result[sqlrow][colnames.index(column[colalias])] + if column[colalias] == 'plposition': + if value == 'B': + value = 'BB' + if value == 'S': + value = 'SB' else: if column[colalias] == 'game': if holecards: @@ -313,7 +323,7 @@ class GuiPlayerStats (threading.Thread): #end def addTable(self, query, vars, playerids, sitenos, limits, seats): - def refineQuery(self, query, flags, playerids, sitenos, limits, seats, dates): + def refineQuery(self, query, flags, playerids, sitenos, limits, seats, groups, dates): if not flags: holecards = False else: holecards = flags[0] @@ -376,6 +386,16 @@ class GuiPlayerStats (threading.Thread): # Filter on dates query = query.replace("", " between '" + dates[0] + "' and '" + dates[1] + "'") + # Group by position? + if groups['posn']: + query = query.replace("", 'hp.position') + # set flag in self.columns to show posn column + [x for x in self.columns if x[0] == 'plposition'][0][1] = True + else: + query = query.replace("", "'1'") + # unset flag in self.columns to hide posn column + [x for x in self.columns if x[0] == 'plposition'][0][1] = False + #print "query =\n", query return(query) #end def refineQuery(self, query, playerids, sitenos, limits):