Merge branch 'master' of git://git.assembla.com/fpdboz.git
This commit is contained in:
commit
75026dbd30
|
@ -1,3 +1,9 @@
|
|||
free-poker-tools (0.21~rc1) unstable; urgency=low
|
||||
|
||||
* First 0.21 release candidate
|
||||
|
||||
-- Mika Bostrom <bostik@iki.fi> Mon, 06 Dec 2010 17:30:54 +0200
|
||||
|
||||
free-poker-tools (0.20.906-1) unstable; urgency=low
|
||||
|
||||
* New snapshot
|
||||
|
|
|
@ -11,9 +11,8 @@ Section: games
|
|||
Priority: extra
|
||||
Depends: ${python:Depends}, python-gtk2, python-matplotlib,
|
||||
python-support, python-xlib,
|
||||
mysql-server | postgresql | python-pysqlite2,
|
||||
python-psycopg2 | python-mysqldb
|
||||
Suggests: wine
|
||||
python-pysqlite2
|
||||
Suggests: wine, postgresql | mysql-server, python-psycopg2 | python-mysqldb
|
||||
Description: free poker database with HUD
|
||||
FPDB is a statistics tool for online poker. It supports most sites
|
||||
and several games. Most prominent feature is its heads-up display
|
||||
|
|
|
@ -60,11 +60,14 @@ import Configuration
|
|||
# Other library modules
|
||||
try:
|
||||
import sqlalchemy.pool as pool
|
||||
use_pool = True
|
||||
#use_pool = True
|
||||
# Forcing to False so we can use connection.row_factory
|
||||
use_pool = False
|
||||
except ImportError:
|
||||
log.info(_("Not using sqlalchemy connection pool."))
|
||||
use_pool = False
|
||||
|
||||
|
||||
try:
|
||||
from numpy import var
|
||||
use_numpy = True
|
||||
|
@ -447,6 +450,7 @@ class Database:
|
|||
log.info(_("Connecting to SQLite: %(database)s") % {'database':self.db_path})
|
||||
if os.path.exists(database) or create:
|
||||
self.connection = sqlite3.connect(self.db_path, detect_types=sqlite3.PARSE_DECLTYPES)
|
||||
self.connection.row_factory = sqlite3.Row
|
||||
self.__connected = True
|
||||
sqlite3.register_converter("bool", lambda x: bool(int(x)))
|
||||
sqlite3.register_adapter(bool, lambda x: "1" if x else "0")
|
||||
|
@ -2094,7 +2098,7 @@ class Database:
|
|||
if (game['type']=='ring'): line[0] = 1 # count ring hands
|
||||
if (game['type']=='tour'): line[1] = 1 # count tour hands
|
||||
if (game['type']=='ring'): line[2] = pdata[p]['totalProfit'] #sum of profit
|
||||
if (game['type']=='ring'): line[3] = float(Decimal(pdata[p]['totalProfit'])/Decimal(bigBet)) #sum of big bets won
|
||||
if (game['type']=='ring'): line[3] = 0 #float(Decimal(pdata[p]['totalProfit'])/Decimal(bigBet)) #sum of big bets won
|
||||
line[4] = startTime
|
||||
inserts.append(line)
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@ import gtk
|
|||
import math
|
||||
import gobject
|
||||
|
||||
import pprint
|
||||
pp = pprint.PrettyPrinter(indent=4)
|
||||
|
||||
|
||||
class GuiReplayer:
|
||||
def __init__(self, config, querylist, mainwin, options = None, debug=True):
|
||||
|
@ -100,30 +103,16 @@ class GuiReplayer:
|
|||
|
||||
self.replayBox.pack_start(self.area)
|
||||
|
||||
self.MyHand = self.importhand()
|
||||
gobject.timeout_add(1000,self.draw_action)
|
||||
|
||||
self.maxseats=self.MyHand.maxseats
|
||||
self.MyHand = self.importhand()
|
||||
self.table = Table(self.area, self.MyHand).table
|
||||
|
||||
if self.MyHand.gametype['currency']=="USD": #TODO: check if there are others ..
|
||||
self.currency="$"
|
||||
elif self.MyHand.gametype['currency']=="EUR":
|
||||
self.currency="€"
|
||||
|
||||
|
||||
self.table={} #create table with positions, player names, status (live/folded), stacks and chips on table
|
||||
for i in range(0,self.maxseats): # radius: 200, center: 250,250
|
||||
x= int (round(250+200*math.cos(2*i*math.pi/self.maxseats)))
|
||||
y= int (round(250+200*math.sin(2*i*math.pi/self.maxseats)))
|
||||
try:
|
||||
self.table[i]={"name":self.MyHand.players[i][1],"stack":Decimal(self.MyHand.players[i][2]),"x":x,"y":y,"chips":0,"status":"live"} #save coordinates of each player
|
||||
try:
|
||||
self.table[i]['holecards']=self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][1]+' '+self.MyHand.holecards["PREFLOP"][self.MyHand.players[i][1]][2]
|
||||
print "holecards: ",self.table[i]['holecards']
|
||||
except:
|
||||
self.table[i]['holecards']=''
|
||||
except IndexError: #if seat is empty
|
||||
print "seat ",i+1," out of ",self.maxseats," empty"
|
||||
|
||||
self.actions=[] #create list with all actions
|
||||
|
||||
if isinstance(self.MyHand, HoldemOmahaHand):
|
||||
|
@ -133,7 +122,6 @@ class GuiReplayer:
|
|||
self.action_number=0
|
||||
self.action_level=0
|
||||
self.pot=0
|
||||
gobject.timeout_add(1000,self.draw_action)
|
||||
|
||||
|
||||
def area_expose(self, area, event):
|
||||
|
@ -249,7 +237,7 @@ class GuiReplayer:
|
|||
be replaced by a function to select a hand from the db in the not so distant future.
|
||||
This code has been shamelessly stolen from Carl
|
||||
"""
|
||||
if True:
|
||||
if False:
|
||||
settings = {}
|
||||
settings.update(self.conf.get_db_parameters())
|
||||
settings.update(self.conf.get_import_parameters())
|
||||
|
@ -276,7 +264,7 @@ class GuiReplayer:
|
|||
# for the Hand.__init__
|
||||
|
||||
####### Shift this section in Database.py for all to use ######
|
||||
handid = 40
|
||||
handid = 1
|
||||
q = self.sql.query['get_gameinfo_from_hid']
|
||||
q = q.replace('%s', self.sql.query['placeholder'])
|
||||
|
||||
|
@ -295,10 +283,74 @@ class GuiReplayer:
|
|||
print "DEBUG: Create stud hand here"
|
||||
elif gametype['base'] == 'draw':
|
||||
print "DEBUG: Create draw hand here"
|
||||
return h
|
||||
|
||||
def temp(self):
|
||||
pass
|
||||
|
||||
class Table:
|
||||
def __init__(self, darea, hand):
|
||||
self.darea = darea
|
||||
self.hand = hand
|
||||
self.players = []
|
||||
#self.pixmap = gtk.gdk.Pixmap(darea, width, height, depth=-1)
|
||||
|
||||
# tmp var while refactoring
|
||||
self.table = {}
|
||||
i = 0
|
||||
for seat, name, chips in hand.players:
|
||||
self.players.append(Player(hand, name, chips, seat))
|
||||
self.table[i] = self.players[i].get_hash()
|
||||
i += 1
|
||||
|
||||
pp.pprint(self.table)
|
||||
|
||||
def draw(self):
|
||||
draw_players()
|
||||
draw_pot()
|
||||
draw_community_cards()
|
||||
|
||||
class Player:
|
||||
def __init__(self, hand, name, stack, seat):
|
||||
self.status = 'live'
|
||||
self.stack = Decimal(stack)
|
||||
self.chips = 0
|
||||
self.seat = seat
|
||||
self.name = name
|
||||
self.holecards = hand.join_holecards(name)
|
||||
self.x = int (round(250+200*math.cos(2*self.seat*math.pi/hand.maxseats)))
|
||||
self.y = int (round(250+200*math.sin(2*self.seat*math.pi/hand.maxseats)))
|
||||
|
||||
def get_hash(self):
|
||||
return { 'chips': 0,
|
||||
'holecards': self.holecards,
|
||||
'name': self.name,
|
||||
'stack': self.stack,
|
||||
'status': self.status,
|
||||
'x': self.x,
|
||||
'y': self.y,
|
||||
}
|
||||
|
||||
def draw(self):
|
||||
draw_name()
|
||||
draw_stack()
|
||||
draw_cards()
|
||||
|
||||
class Pot:
|
||||
def __init__(self, hand):
|
||||
self.total = 0.0
|
||||
|
||||
def draw(self):
|
||||
pass
|
||||
|
||||
class CommunityCards:
|
||||
def __init__(self, hand):
|
||||
self.pixbuf = self.gen_pixbuf_from_file(PATH_TO_THE_FILE)
|
||||
|
||||
def draw(self):
|
||||
pass
|
||||
|
||||
|
||||
def main(argv=None):
|
||||
"""main can also be called in the python interpreter, by supplying the command line as the argument."""
|
||||
if argv is None:
|
||||
|
|
|
@ -52,7 +52,7 @@ onlinehelp = {'Game':_('Type of Game'),
|
|||
'PF3':_('% Pre Flop Re-Raise / 3Bet'),
|
||||
'AggFac':_('Aggression Factor\n'),
|
||||
'AggFreq':_('Aggression Frequency\nBet or Raise vs Fold'),
|
||||
'ContBet':_('Continuation Bet on the flop'),
|
||||
'ContBet':_('Continuation Bet post-flop'),
|
||||
'RFI':_('% Raise First In\% Raise when first to bet'),
|
||||
'Steals':_('% First to raise pre-flop\nand steal blinds'),
|
||||
'Saw_F':_('% Saw Flop vs hands dealt'),
|
||||
|
|
185
pyfpdb/Hand.py
185
pyfpdb/Hand.py
|
@ -289,104 +289,131 @@ db: a connected Database object"""
|
|||
hp.seatno,
|
||||
round(hp.winnings / 100.0,2) as winnings,
|
||||
p.name,
|
||||
round(hp.startcash / 100.0,2) as chips,
|
||||
hp.card1,hp.card2,
|
||||
round(hp.startCash / 100.0,2) as chips,
|
||||
hp.card1,hp.card2,hp.card3,hp.card4,
|
||||
hp.position
|
||||
FROM
|
||||
HandsPlayers as hp,
|
||||
Players as p
|
||||
WHERE
|
||||
hp.handId = %s
|
||||
and p.id = hp.playerid
|
||||
and p.id = hp.playerId
|
||||
ORDER BY
|
||||
hp.seatno
|
||||
"""
|
||||
q = q.replace('%s', db.sql.query['placeholder'])
|
||||
|
||||
# PlayerStacks
|
||||
c.execute(q, (handId,))
|
||||
for (seat, winnings, name, chips, card1,card2, position) in c.fetchall():
|
||||
print "DEBUG: seat: '%s'\tname: '%s'\tchips: '%s'" % (seat, name, chips)
|
||||
for (seat, winnings, name, chips, card1, card2, card3, card4, position) in c.fetchall():
|
||||
#print "DEBUG: addPlayer(%s, %s, %s)" %(seat,name,str(chips))
|
||||
self.addPlayer(seat,name,str(chips))
|
||||
#if card1 and card2:
|
||||
# self.addHoleCards(map(Card.valueSuitFromCard, (card1,card2)), name, dealt=True)
|
||||
#if winnings > 0:
|
||||
# self.addCollectPot(name, winnings)
|
||||
#if position == 'B':
|
||||
# self.buttonpos = seat
|
||||
#print "DEBUG: card1: %s" % card1
|
||||
# map() should work, but is returning integers... FIXME later
|
||||
#cardlist = map(Card.valueSuitFromCard, [card1, card2, card3, card4])
|
||||
cardlist = [Card.valueSuitFromCard(card1), Card.valueSuitFromCard(card2), Card.valueSuitFromCard(card3), Card.valueSuitFromCard(card4)]
|
||||
#print "DEUBG: cardlist: '%s'" % cardlist
|
||||
if cardlist[0] == '':
|
||||
pass
|
||||
elif self.gametype['category'] == 'holdem':
|
||||
self.addHoleCards('PREFLOP', name, closed=cardlist[0:2], shown=False, mucked=False, dealt=True)
|
||||
elif self.gametype['category'] == 'omaha':
|
||||
self.addHoleCards('PREFLOP', name, closed=cardlist, shown=False, mucked=False, dealt=True)
|
||||
if winnings > 0:
|
||||
self.addCollectPot(name, str(winnings))
|
||||
if position == 'B':
|
||||
self.buttonpos = seat
|
||||
|
||||
|
||||
# HandInfo : HID, TABLE
|
||||
# BUTTON - why is this treated specially in Hand?
|
||||
# answer: it is written out in hand histories
|
||||
# still, I think we should record all the active seat positions in a seat_order array
|
||||
#c.execute("""SELECT
|
||||
# h.sitehandno as hid,
|
||||
# h.tablename as table,
|
||||
# h.startTime as startTime
|
||||
# FROM
|
||||
# Hands as h
|
||||
# WHERE h.id = %(handid)s
|
||||
# """, {'handid':handid})
|
||||
#res = c.fetchone()
|
||||
#h.handid = res[0]
|
||||
#h.tablename = res[1]
|
||||
#h.startTime = res[2] # automatically a datetime
|
||||
# HandInfo
|
||||
q = """SELECT *
|
||||
FROM Hands
|
||||
WHERE id = %s
|
||||
"""
|
||||
q = q.replace('%s', db.sql.query['placeholder'])
|
||||
c.execute(q, (handId,))
|
||||
|
||||
# NOTE: This relies on row_factory = sqlite3.Row (set in connect() params)
|
||||
# Need to find MySQL and Postgres equivalents
|
||||
# MySQL maybe: cursorclass=MySQLdb.cursors.DictCursor
|
||||
res = c.fetchone()
|
||||
self.tablename = res['tableName']
|
||||
self.handid = res['siteHandNo']
|
||||
self.startTime = datetime.datetime.strptime(res['startTime'], "%Y-%m-%d %H:%M:%S+00:00")
|
||||
#res['tourneyId']
|
||||
#gametypeId
|
||||
#res['importTime'] # Don't really care about this
|
||||
#res['seats']
|
||||
self.maxseats = res['maxSeats']
|
||||
#res['rush']
|
||||
cards = map(Card.valueSuitFromCard, [res['boardcard1'], res['boardcard2'], res['boardcard3'], res['boardcard4'], res['boardcard5']])
|
||||
#print "DEBUG: res['boardcard1']: %s" % res['boardcard1']
|
||||
#print "DEBUG: cards: %s" % cards
|
||||
if cards[0]:
|
||||
self.setCommunityCards('FLOP', cards[0:3])
|
||||
if cards[3]:
|
||||
self.setCommunityCards('TURN', [cards[3]])
|
||||
if cards[4]:
|
||||
self.setCommunityCards('RIVER', [cards[4]])
|
||||
# playersVpi | playersAtStreet1 | playersAtStreet2 | playersAtStreet3 |
|
||||
# playersAtStreet4 | playersAtShowdown | street0Raises | street1Raises |
|
||||
# street2Raises | street3Raises | street4Raises | street1Pot | street2Pot |
|
||||
# street3Pot | street4Pot | showdownPot | comment | commentTs | texture
|
||||
|
||||
|
||||
#cards = map(Card.valueSuitFromCard, res[11:16] )
|
||||
#if cards[0]:
|
||||
# h.setCommunityCards('FLOP', cards[0:3])
|
||||
#if cards[3]:
|
||||
# h.setCommunityCards('TURN', [cards[3]])
|
||||
#if cards[4]:
|
||||
# h.setCommunityCards('RIVER', [cards[4]])
|
||||
#[Card.valueSuitFromCard(x) for x in cards]
|
||||
# Actions
|
||||
q = """SELECT
|
||||
ha.actionNo,
|
||||
p.name,
|
||||
ha.street,
|
||||
ha.actionId,
|
||||
ha.allIn,
|
||||
round(ha.amount / 100.0,2) as bet
|
||||
FROM
|
||||
HandsActions as ha,
|
||||
HandsPlayers as hp,
|
||||
Players as p,
|
||||
Hands as h
|
||||
WHERE
|
||||
h.id = %s
|
||||
and ha.handsPlayerId = hp.id
|
||||
and hp.playerId = p.id
|
||||
AND h.id = hp.handId
|
||||
ORDER BY
|
||||
ha.id ASC
|
||||
; """
|
||||
q = q.replace('%s', db.sql.query['placeholder'])
|
||||
c.execute(q, (handId,))
|
||||
for row in c.fetchall():
|
||||
name = row['name']
|
||||
street = row['street']
|
||||
act = row['actionId']
|
||||
# allin True/False if row['allIn'] == 0
|
||||
bet = row['bet']
|
||||
street = self.allStreets[int(street)+1]
|
||||
#print "DEBUG: name: '%s' street: '%s' act: '%s' bet: '%s'" %(name, street, act, bet)
|
||||
if act == 2: # Small Blind
|
||||
print "DEBUG: addBlind(%s, 'small blind', %s" %(name, str(bet))
|
||||
self.addBlind(name, 'small blind', str(bet))
|
||||
elif act == 4: # Big Blind
|
||||
self.addBlind(name, 'big blind', str(bet))
|
||||
elif act == 6: # Call
|
||||
self.addCall(street, name, str(bet))
|
||||
elif act == 8: # Bet
|
||||
self.addBet(street, name, str(bet))
|
||||
elif act == 10: # Fold
|
||||
self.addFold(street, name)
|
||||
elif act == 11: # Check
|
||||
self.addCheck(street, name)
|
||||
else:
|
||||
print "DEBUG: unknown action: '%s'" % act
|
||||
|
||||
|
||||
# actions
|
||||
#c.execute("""SELECT
|
||||
# (ha.street,ha.actionno) as actnum,
|
||||
# p.name,
|
||||
# ha.street,
|
||||
# ha.action,
|
||||
# ha.allin,
|
||||
# round(ha.amount / 100.0,2)
|
||||
# FROM
|
||||
# handsplayers as hp,
|
||||
# handsactions as ha,
|
||||
# players as p
|
||||
# WHERE
|
||||
# hp.handid = %(handid)s
|
||||
# and ha.handsplayerid = hp.id
|
||||
# and p.id = hp.playerid
|
||||
# ORDER BY
|
||||
# ha.street,ha.actionno
|
||||
# """, {'handid':handid})
|
||||
#res = c.fetchall()
|
||||
#for (actnum,player, streetnum, act, allin, amount) in res:
|
||||
# act=act.strip()
|
||||
# street = h.allStreets[streetnum+1]
|
||||
# if act==u'blind':
|
||||
# h.addBlind(player, 'big blind', amount)
|
||||
# # TODO: The type of blind is not recorded in the DB.
|
||||
# # TODO: preflop street name anomalies in Hand
|
||||
# elif act==u'fold':
|
||||
# h.addFold(street,player)
|
||||
# elif act==u'call':
|
||||
# h.addCall(street,player,amount)
|
||||
# elif act==u'bet':
|
||||
# h.addBet(street,player,amount)
|
||||
# elif act==u'check':
|
||||
# h.addCheck(street,player)
|
||||
# elif act==u'unbet':
|
||||
# pass
|
||||
# else:
|
||||
# print act, player, streetnum, allin, amount
|
||||
# # TODO : other actions
|
||||
self.totalPot()
|
||||
self.rake = self.totalpot - self.totalcollected
|
||||
self.writeHand()
|
||||
|
||||
#hhc.readShowdownActions(self)
|
||||
#hc.readShownCards(self)
|
||||
#h.totalPot()
|
||||
#h.rake = h.totalpot - h.totalcollected
|
||||
|
||||
|
||||
def addPlayer(self, seat, name, chips):
|
||||
|
@ -980,7 +1007,7 @@ class HoldemOmahaHand(Hand):
|
|||
log.debug(self.actions['PREFLOP'])
|
||||
for player in [x for x in self.players if x[1] in players_who_act_preflop]:
|
||||
#Only print stacks of players who do something preflop
|
||||
print >>fh, ("Seat %s: %s ($%s in chips) " %(player[0], player[1], player[2]))
|
||||
print >>fh, ("Seat %s: %s ($%.2f in chips) " %(player[0], player[1], float(player[2])))
|
||||
|
||||
if self.actions['BLINDSANTES']:
|
||||
for act in self.actions['BLINDSANTES']:
|
||||
|
|
|
@ -2246,7 +2246,7 @@ class Sql:
|
|||
(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer))) +
|
||||
(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer))) )
|
||||
AS aggfrq
|
||||
,100.0*(sum(cast(hp.street1CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street4CBDone as <signed>integer)))
|
||||
,100.0*(sum(cast(hp.street1CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street3CBDone as <signed>integer)) + sum(cast(hp.street4CBDone as <signed>integer)))
|
||||
/ (sum(cast(hp.street1CBChance as <signed>integer))+ sum(cast(hp.street2CBChance as <signed>integer))+ sum(cast(hp.street3CBChance as <signed>integer))+ sum(cast(hp.street4CBChance as <signed>integer)))
|
||||
AS conbet
|
||||
,sum(hp.totalProfit)/100.0 AS net
|
||||
|
@ -2367,7 +2367,7 @@ class Sql:
|
|||
(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer))) +
|
||||
(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer))) )
|
||||
AS aggfrq
|
||||
,100.0*(sum(cast(hp.street1CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street4CBDone as <signed>integer)))
|
||||
,100.0*(sum(cast(hp.street1CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street3CBDone as <signed>integer)) + sum(cast(hp.street4CBDone as <signed>integer)))
|
||||
/ (sum(cast(hp.street1CBChance as <signed>integer))+ sum(cast(hp.street2CBChance as <signed>integer))+ sum(cast(hp.street3CBChance as <signed>integer))+ sum(cast(hp.street4CBChance as <signed>integer)))
|
||||
AS conbet
|
||||
,sum(hp.totalProfit)/100.0 AS net
|
||||
|
@ -2489,7 +2489,7 @@ class Sql:
|
|||
(sum(cast(hp.street1Calls as <signed>integer))+ sum(cast(hp.street2Calls as <signed>integer))+ sum(cast(hp.street3Calls as <signed>integer))+ sum(cast(hp.street4Calls as <signed>integer))) +
|
||||
(sum(cast(hp.street1Aggr as <signed>integer)) + sum(cast(hp.street2Aggr as <signed>integer)) + sum(cast(hp.street3Aggr as <signed>integer)) + sum(cast(hp.street4Aggr as <signed>integer))) )
|
||||
AS aggfrq
|
||||
,100.0*(sum(cast(hp.street1CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street4CBDone as <signed>integer)))
|
||||
,100.0*(sum(cast(hp.street1CBDone as <signed>integer)) + sum(cast(hp.street2CBDone as <signed>integer)) + sum(cast(hp.street3CBDone as <signed>integer)) + sum(cast(hp.street4CBDone as <signed>integer)))
|
||||
/ (sum(cast(hp.street1CBChance as <signed>integer))+ sum(cast(hp.street2CBChance as <signed>integer))+ sum(cast(hp.street3CBChance as <signed>integer))+ sum(cast(hp.street4CBChance as <signed>integer)))
|
||||
AS conbet
|
||||
,sum(hp.totalProfit)/100.0 AS net
|
||||
|
|
|
@ -624,4 +624,4 @@ class ProgressBar:
|
|||
|
||||
|
||||
if __name__ == "__main__":
|
||||
print _("CLI for fpdb_import is now available as CliFpdb.py")
|
||||
print _("CLI for importing hands is GuiBulkImport.py")
|
||||
|
|
Loading…
Reference in New Issue
Block a user