Open Side Menu Go to the Top
Register
Will Tipton Video Pack 2 - Solving Poker Will Tipton Video Pack 2 - Solving Poker

07-22-2014 , 09:43 AM
Got it!
When I first installed Anaconda, I was debating whether to put it on the HD or SSD. So had some path problems with an obsolete install folder.

Back to the videos. =)
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 09:44 AM
Quote:
Originally Posted by Sevendeuceo
ZhengHe,

Your Anaconda command window states that "pydot" was installed. That should be pydot2.

Might have you mistakenly typed "pip install pydot" instead of
"pip install pydot2" ?
I kept trying both.
To be clear, when I start following along with the video, I should still import "pydot", and not "pydot2".
Is that right?
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 09:49 AM
Quote:
Originally Posted by ZhengHe
I kept trying both.
To be clear, when I start following along with the video, I should still import "pydot", and not "pydot2".
Is that right?
Yes, that's right. "import pydot"

Glad your problem is solved.
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 10:09 AM
A question, is following logic correct?

flops
We can have 52*51*50/6=22100 different flops.
And such (if we would adapt EQarray code a bit) we would require 22100 stored EQArray ('x','y','z','__','__') of 56Mb =113Gb instead of 52^3=140 608 / or 7690Gb.

EQ, all-in at flop
And such, if we set up a tree where a random flop is dealt; the code would each time have to consult one of the 22100 stored EQArray stored at HD.
At first sight, we could say that we are required to generate all these 22100 EQArrays if we get a hand at flop that goes all-in at flop.

However, if we eventually went through all possible flops for each [i,j][a,b] aka went through all the possible EQArrays (that do not conflict); we can conclude that the resulting equity of [i,j][a,b]=sum(1/22100 * EQ('x','y','z','__','__'))
Now, if our code is written correctly, we do not sum 22100 EQ's, we actually sum less as some boards are impossible to be dealt.

And such, instead of having to adapt code; generate and store 22100 EQArray stored at HD; generate each flop; combine the equities; we can actually just use EQArray('__','__','__','__','__') for each hand we get all-in at flop.

Now, EV, all-in at flop
Let's assume that the EV is of algebraic form [a + b EQ('x','y','z','__','__')]
and such
EVflop = sum(1/22100 * [a + b EQ('x','y','z','__','__')])
once again, if our code is written correctly, we do not sum 22100 EV's, we actually sum less as some boards are impossible to be dealt.
= a+b[sum(1/22100 * EQ('x','y','z','__','__'))]
OR = a + b EQ('__','__','__','__','__')

Once again we can just use EQArray('__','__','__','__','__') for each hand we get all-in at flop.

turns
after 4 cards; there are 22100 * 49 = 1 082 900 boards possible.
However, we can once again adapt EQArray code, simply because in the above line each board of 4 cards is present 4 times.
To rephrase it : 52*51*50*49/24 = 270 725
And such we require the software to generate 270 725 EQ('x','y','z','a','__')
or 14.46Tb of information.

EQ turns after flop call
If we move to the turn; there are theoretically 49 EQ('x','y','z','a','__') over which we sum the EQ's. However each time 4 EQArrays will not be counted as they conflict with cards present in the starting hands.
However, we once again arrived into:
EQ(turn) = sum(1/49*EQ('x','y','z','a','__'))
which is equal to EQ('x','y','z','__','__') for the specific flop dealt.

And such instead of having to adapt code for turns; generate and store 270 725 EQ('x','y','z','a','__') stored at HD; generate each turn; combine the equities; we can actually just use EQ('x','y','z','__','__') for the specific flop dealt whenever a hand goes all-in at turn after a flop call.

Once again, at this time we can think that we require EQ('x','y','z','__','__') when we go to turn after flop call; however because we will iterate all flops, and after a flop is generated, we will iterate over all turns, we can just use once again EQArray('__','__','__','__','__') whenever a hand goes all-in at turn after a flop call.

EV turn after flop call
EQ river after flop+turn call
EV river after flop+turn call
idem dito

And such we can just use EQArray('__','__','__','__','__') whenever we get a hand all-in; simply because our software will iterate over all possible flops, all possible turns, all possible rivers and combine the results. And instead of letting our software iterate over all these things correctly and combine correctly; this iteration and combination is already done and present into EQArray('__','__','__','__','__')
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 11:32 AM
Quote:
Originally Posted by stevepa
same problem from my question minotaurs, though interestingly your numbers are different than both mine and the video's...I've forwarded my stuff to Will so he can try to figure out what's going on.
Quote:
Originally Posted by minotaurs
Yea interesting. Sevendeuceo has the same problem as well. Maybe you can let us know as well when Will tells you whats going on there?
quick update on this -- I don't see any salient difference between our code . I'll look at it more tonight.
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 01:40 PM
Quote:
ZeroDivisionError Traceback (most recent call last)
<ipython-input-145-ec23ba4cad64> in <module>()
1 bob = Range()
----> 2 bob._repr_svg_()

<ipython-input-144-22468b7f3c1b> in _repr_svg_(self)
135 for i in range (numRanks):
136 for j in range(numRanks):
--> 137 frac = self.getAmbigFrac(ranks[1], ranks[j], i > j)
138 hexcolor = '#%02x%02x%02x' % (255*(1-frac), 255, 255*(1-frac))
139 result += '<rect x="' + str(i*20) + '"y="' + str(j*20) + '" width="20" height="20" fill="' + hexcolor+'"></rect>'

<ipython-input-144-22468b7f3c1b> in getAmbigFrac(self, rank1, rank2, suited)
129 nHand += 1 #short for nHand = nHand+1
130 nFrac += self.getFrac(pe.string2card([card1,card2]))
--> 131 return (nFrac/nHand)
132
133 def _repr_svg_(self):

ZeroDivisionError: float division by zero
Not sure if its entirely cool to copy/paste this cause it does include a minor part of the code from the video, but I have trouble debugging near the end of the range video. Anyway if you can see a solution based on just this error that would be extremely helpfull, if not can anyone with knowledge pm me and/or post here so I can pm him and we can maybe agree to take a closer look.
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 02:23 PM
Quote:
Originally Posted by oxiej
Not sure if its entirely cool to copy/paste this cause it does include a minor part of the code from the video, but I have trouble debugging near the end of the range video. Anyway if you can see a solution based on just this error that would be extremely helpfull, if not can anyone with knowledge pm me and/or post here so I can pm him and we can maybe agree to take a closer look.
The post is fine, but thanks for thinking of it.

Looks like the nHand variable is 0 when it tries to do the division. Could you try the procedure in post #16?
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 03:15 PM
Quote:
Originally Posted by yaqh
The post is fine, but thanks for thinking of it.

Looks like the nHand variable is 0 when it tries to do the division. Could you try the procedure in post #16?
Hey, sorry i missed post 16, will be more diligent next time with my debugging problems!

In either case the issue is solved but i'm not 100% sure why. I altered the inputs for nhand and nfrac to be >0 manually and that solved the problem. Then I turned them back to 0 and it somehow just kept working.
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 03:25 PM
I'm on video 7.

I've defined the _repr_svg_(self): function, yet when I run

bob = Range()
display(bob)

Im still getting this
<__main__.Range instance at 0x05D2D7B0>

My Range Class doesnt give any problems when I run that cell.

Any help would be greatly appreciated, thanks!
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 03:39 PM
Quote:
Originally Posted by oxiej
Hey, sorry i missed post 16, will be more diligent next time with my debugging problems!

In either case the issue is solved but i'm not 100% sure why. I altered the inputs for nhand and nfrac to be >0 manually and that solved the problem. Then I turned them back to 0 and it somehow just kept working.
Quote:
137 frac = self.getAmbigFrac(ranks[1], ranks[j], i > j)
Does it not have to be ranks[i] instead of ranks[1] ?
Meaning, did you not typed from time to time a 1 instead of an i ?
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 03:47 PM
Quote:
Originally Posted by Emus
Does it not have to be ranks[i] instead of ranks[1] ?
Meaning, did you not typed from time to time a 1 instead of an i ?
Yes this was part of the problem, fortunatly i only made the mistake once
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 03:58 PM
Quote:
Originally Posted by MrPete
I'm on video 7.

I've defined the _repr_svg_(self): function, yet when I run

bob = Range()
display(bob)

Im still getting this
<__main__.Range instance at 0x05D2D7B0>

My Range Class doesnt give any problems when I run that cell.

Any help would be greatly appreciated, thanks!
Hey, check out the Technical FAQ section on the vidpack's page (link in op).
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 05:15 PM
Quote:
Originally Posted by yaqh
Hey, check out the Technical FAQ section on the vidpack's page (link in op).
Thanks! Here is error. I've stared at the code in the video for a long while, and I cant see what I've missed.



Code:
TypeError                                 Traceback (most recent call last)
<ipython-input-141-ec23ba4cad64> in <module>()
      1 bob = Range()
----> 2 bob._repr_svg_()

<ipython-input-140-06646e53c88d> in _repr_svg_(self)
    126         for i in range(numRanks):
    127             for j in range(numRanks):
--> 128                 frac = self.getAmbigFrac(ranks[i], ranks[j], i > j)
    129                 hexcolor = '#%02x%02x%02x' % (255*(1-frac), 255*(1-(0.5*frac)), 255*(1-frac))
    130                 result += '<rect x="' + str(i*20) + '" y ="' + str(j*20) + '" width="20" height="20" fill="'                + hexcolour+'"></rect>'

<ipython-input-140-06646e53c88d> in getAmbigFrac(self, rank1, rank2, suited)
    119                     continue
    120                 nHand += 1 # short for nHand = nHand + 1
--> 121                 nFrac += self.getFrac(pe.string2card([card1,card2]))
    122         return nFrac / nHand
    123 

TypeError: unsupported operand type(s) for +=: 'float' and 'NoneType'
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 07:04 PM
Hmm maybe someone can help.

In video 5 towards the end i keep getting this error.

Code:
AttributeError                            Traceback (most recent call last)
<ipython-input-130-72e875fb97fa> in <module>()
----> 1 myEArray = EquityArray(board)

<ipython-input-125-78ec8f472ae2> in __init__(self, b)
      9         self.eArray = numpy.zeros((numCards, numCards, numCards, numCards))
     10         if os.path.isfile(self.getFilename()):
---> 11             self.eArray = numpy.load(self.Filename)
     12         else:
     13             self.makeArray()

AttributeError: EquityArray instance has no attribute 'Filename'
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 07:20 PM
Quote:
Originally Posted by MrPete
Thanks! Here is error. I've stared at the code in the video for a long while, and I cant see what I've missed.



Code:
TypeError                                 Traceback (most recent call last)
<ipython-input-141-ec23ba4cad64> in <module>()
      1 bob = Range()
----> 2 bob._repr_svg_()

<ipython-input-140-06646e53c88d> in _repr_svg_(self)
    126         for i in range(numRanks):
    127             for j in range(numRanks):
--> 128                 frac = self.getAmbigFrac(ranks[i], ranks[j], i > j)
    129                 hexcolor = '#%02x%02x%02x' % (255*(1-frac), 255*(1-(0.5*frac)), 255*(1-frac))
    130                 result += '<rect x="' + str(i*20) + '" y ="' + str(j*20) + '" width="20" height="20" fill="'                + hexcolour+'"></rect>'

<ipython-input-140-06646e53c88d> in getAmbigFrac(self, rank1, rank2, suited)
    119                     continue
    120                 nHand += 1 # short for nHand = nHand + 1
--> 121                 nFrac += self.getFrac(pe.string2card([card1,card2]))
    122         return nFrac / nHand
    123 

TypeError: unsupported operand type(s) for +=: 'float' and 'NoneType'
The error message there says that you're trying to add a number (a float) to a NoneType which is essentially a special error-indicating thing. And it says the error is coming from a line where you're adding nfrac to the result of the getFrac function. Presumably you expect to be adding two numbers together. Please figure out which of the summands is incorrect, and then investigate why. See post #16 for more ideas about tracking down issues and providing useful debugging info.
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 07:21 PM
Quote:
Originally Posted by klondi
Hmm maybe someone can help.

In video 5 towards the end i keep getting this error.

Code:
AttributeError                            Traceback (most recent call last)
 in ()
----> 1 myEArray = EquityArray(board)

 in __init__(self, b)
      9         self.eArray = numpy.zeros((numCards, numCards, numCards, numCards))
     10         if os.path.isfile(self.getFilename()):
---> 11             self.eArray = numpy.load(self.Filename)
     12         else:
     13             self.makeArray()

AttributeError: EquityArray instance has no attribute 'Filename'
This is a known issue that will be added to the errata, but I imagine it's something you are able to figure out.

Does your equityarray instance have a Filename attribute? Should it? What is that code trying to do, and how can it do that?

Last edited by yaqh; 07-22-2014 at 07:33 PM.
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 08:02 PM
Quote:
Originally Posted by yaqh
quick update on this -- I don't see any salient difference between our code . I'll look at it more tonight.
While your were going through the debugging process, in the video, you also made some last minute changes in the code. It occurred to me that, maybe, in some procedure, you corrected the error-generating bug and updated the cell, but after that you changed some code and didn't updated the cell again before running doFP(). If that's the case, of course, you won't be able to reproduce your earlier results without changing the code back.

I'll watch again this part of the video to see if that might be the case.
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 10:11 PM
Quote:
Originally Posted by Sevendeuceo
While your were going through the debugging process, in the video, you also made some last minute changes in the code. It occurred to me that, maybe, in some procedure, you corrected the error-generating bug and updated the cell, but after that you changed some code and didn't updated the cell again before running doFP(). If that's the case, of course, you won't be able to reproduce your earlier results without changing the code back.

I'll watch again this part of the video to see if that might be the case.
Yea, actually all the errata and bugs in the videos so far were introduced by last minute "improvements" or transcription errors that I made while recording. It's hard to think and be on video at the same time .

Anyhow, I found the issue here.. I changed the name of one of the arguments to the getEquityVsHand function from "board" to "b", but forgot to make the change everywhere else in the function body. I forget exactly when I made the change... maybe it wasn't on video.

Spoiler:

NOTE: This code has a bug
Code:
# We want to compute an equity using pe.poker_eval and make a function to take care of the details.
# Inputs:
#   hand and villainHand - lists of cards in numerical format describing two hands
#   board - list of cards describing the board
# Output: all-in equity of hand vs villainHand on board
#         unless any of hand, villainHand, and board conflict
#         in which case we return -1
def getEquityVsHand(hand, villainHand, b):
    if conflicts(hand,villainHand) or conflicts(hand,board) or conflicts(board,villainHand):
        return -1
    peresult = pe.poker_eval(game='holdem', pockets=[hand,villainHand], board = b)
    numWins = peresult['eval'][0]['winhi']
    numTies = peresult['eval'][0]['tiehi']
    numRunouts = peresult['info'][0]
    return (numWins + numTies/2.0) / numRunouts


So, having fixed the equity calcs, my results agree with stevepa's and sevendeuceo's... guess you have more work to do minotaurs
Will Tipton Video Pack 2 - Solving Poker Quote
07-22-2014 , 10:37 PM
Quote:
Originally Posted by yaqh
So, having fixed the equity calcs, my results agree with stevepa's and sevendeuceo's... guess you have more work to do minotaurs
Thanks for hunting that down! I was able to reproduce the results from your video, now, through reintroducing that bug and, of course, temporarily renaming the three relevant equity arrays on the disk so as to force the re-calculation of them. It's nice that this is now sorted out.
Will Tipton Video Pack 2 - Solving Poker Quote
07-23-2014 , 03:42 AM
Quote:
Originally Posted by yaqh
This is a known issue that will be added to the errata, but I imagine it's something you are able to figure out.

Does your equityarray instance have a Filename attribute? Should it? What is that code trying to do, and how can it do that?
Hmm I am stuck here.

I dont think it has the Filename attribute, but I am confused about it. Not exactly sure where to put in the attribute. I tryed various things wich dident seem to solve the problem.

Tryed something like this wich dident help ?
Code:
def __init__(self, b, Filename):
I think it is trying to look for a file but it dont know where to find it ?

Also one other thing.

In my Ipython notebook it looks like it is stored on a localhost:8888. There was also another project in my folder from someone named kevin whom I dont know who is ??

In your video there was another path shown when you moved the preflop.ea.npy file to the documents /iPython Notebooks folder. I moved mine to the similar folder on my system so not sure if this has anything to do with the problem. Just odd ?
Will Tipton Video Pack 2 - Solving Poker Quote
07-23-2014 , 04:09 AM
Well i think i finally figured it out with the getFilename attribute.

I think i had already tryed this solution yesterday but it produced abother error. so i abonded it.

Code:
AttributeError                            Traceback (most recent call last)
<ipython-input-108-72e875fb97fa> in <module>()
----> 1 myEArray = EquityArray(board)

<ipython-input-106-d36e1d4e9bb6> in __init__(self, b)
      9         self.eArray = numpy.zeros((numCards, numCards, numCards, numCards))
     10         if os.path.isfile(self.getFilename()):
---> 11             self.eArray = numpy.load(self.getFilename) # changed self.Filename to .getFilename
     12         else:
     13             self.makeArray()

E:\Programmer\Ipython\lib\site-packages\numpy\lib\npyio.pyc in load(file, mmap_mode)
    379         _ZIP_PREFIX = asbytes('PK\x03\x04')
    380         N = len(format.MAGIC_PREFIX)
--> 381         magic = fid.read(N)
    382         fid.seek(-N, 1) # back-up
    383         if magic.startswith(_ZIP_PREFIX):

AttributeError: 'function' object has no attribute 'read'
Anyway now went through it again and put in the () after getFilename and all seems ok now :-)
Will Tipton Video Pack 2 - Solving Poker Quote
07-23-2014 , 04:19 AM
Hi,

Regarding the second example.
Bet and check for 7h7s are ~20.9.
My code outputs the same results as stevepa and sevendeuceo, and 19.7 for this example. That should be right, given the soln will sue the getequityvshand somewhere, and board changes will have non-negligible effects. What do you guys think?
Will Tipton Video Pack 2 - Solving Poker Quote
07-23-2014 , 12:20 PM
Quote:
Originally Posted by yaqh
Yea, actually all the errata and bugs in the videos so far were introduced by last minute "improvements" or transcription errors that I made while recording. It's hard to think and be on video at the same time .

Anyhow, I found the issue here.. I changed the name of one of the arguments to the getEquityVsHand function from "board" to "b", but forgot to make the change everywhere else in the function body. I forget exactly when I made the change... maybe it wasn't on video.

Spoiler:

NOTE: This code has a bug
Code:
# We want to compute an equity using pe.poker_eval and make a function to take care of the details.
# Inputs:
#   hand and villainHand - lists of cards in numerical format describing two hands
#   board - list of cards describing the board
# Output: all-in equity of hand vs villainHand on board
#         unless any of hand, villainHand, and board conflict
#         in which case we return -1
def getEquityVsHand(hand, villainHand, b):
    if conflicts(hand,villainHand) or conflicts(hand,board) or conflicts(board,villainHand):
        return -1
    peresult = pe.poker_eval(game='holdem', pockets=[hand,villainHand], board = b)
    numWins = peresult['eval'][0]['winhi']
    numTies = peresult['eval'][0]['tiehi']
    numRunouts = peresult['info'][0]
    return (numWins + numTies/2.0) / numRunouts


So, having fixed the equity calcs, my results agree with stevepa's and sevendeuceo's... guess you have more work to do minotaurs
But i already have b instead of board in that function and i got exactly the same results with doFP() when you were doing calculations to minraise shove game. Not for a digit different. But im getting different numbers when we are doing that big tree (T) For 1st tree all the functions must have worked the same way as yours but than from nowhere im getting different results in 2nd tree (also for tree T i was looking over the code like 3 times and picture as well and they were the same)
Will Tipton Video Pack 2 - Solving Poker Quote
07-23-2014 , 01:44 PM
Quote:
Originally Posted by minotaurs
But i already have b instead of board in that function and i got exactly the same results with doFP() when you were doing calculations to minraise shove game. Not for a digit different. But im getting different numbers when we are doing that big tree (T) For 1st tree all the functions must have worked the same way as yours but than from nowhere im getting different results in 2nd tree (also for tree T i was looking over the code like 3 times and picture as well and they were the same)
The bug only affected EquityArray generation, and the preflop equity array was generated and distributed separately, so there should never have been any issues with the preflop only games.

If your preflop games work but the postflop ones don't, one place to check/focus on would be the getMaxEVsAtNewCardsDP (or so) function.

PS I know I've missed a few questions ITT, and I'll get back to them.
Will Tipton Video Pack 2 - Solving Poker Quote
07-23-2014 , 02:22 PM
Quote:
Originally Posted by yaqh
The bug only affected EquityArray generation, and the preflop equity array was generated and distributed separately, so there should never have been any issues with the preflop only games.

If your preflop games work but the postflop ones don't, one place to check/focus on would be the getMaxEVsAtNewCardsDP (or so) function.

PS I know I've missed a few questions ITT, and I'll get back to them.
Well i did check setMaxExplEVsAtNatureDP and i changed numCards to numHands like in the video. Everything else was like identical (i changed that numHands to numCards previosuly just because i though that maybe u misstyped that but anyways it didnt change any EV's even for 0.0000001)

Code:
for i in range(0, numHands):
        for j in range(i+1, numCards):
            if conflicts([i,j], tree.decPts[iDecPt].eArray.board):
Will Tipton Video Pack 2 - Solving Poker Quote

      
m