poker
poker copied to clipboard
Pokerstars hand history parser does not work
When pokerstars hand history satisfy one of bellow cases, parser does not work.
-
player's stack is not integer but float
-
each hand metadata does not contain
[YYYY/MM/DD hh:mm:ss ET]
for instance, OK: PokerStars Hand #204460218022: Tournament #2698110868, $1.0+$1.8 USD Hold'em No Limit - Level I (10/20) - 2019/09/20 23:53:29 ET [2013/10/04 13:53:27 ET] NG: PokerStars Hand #204460218022: Tournament #2698110868, $1.0+$1.8 USD Hold'em No Limit - Level I (10/20) - 2019/09/20 23:53:29 ET
I'm also having trouble parsing Pokerstars hand history.
I used the setup from https://poker.readthedocs.io/en/latest/handhistory.html
Raw data is loaded, but the error below is thrown by match.group("ident")
in pokerstars.py. ..and there is this comment there...
self.ident = match.group("ident")
# We cannot use the knowledege of the game type to pick between the blind
# and cash blind captures because a cash game play money blind looks exactly
# like a tournament blind
/home/johnpc/card-parser/py/bin/python3 /home/johnpc/card-parser/py/parse.py
Traceback (most recent call last):
File "/home/johnpc/card-parser/py/parse.py", line 3, in <module>
hh.parse()
File "/home/johnpc/card-parser/py/lib/python3.6/site-packages/poker/room/pokerstars.py", line 174, in parse
self.parse_header()
File "/home/johnpc/card-parser/py/lib/python3.6/site-packages/poker/room/pokerstars.py", line 129, in parse_header
self.ident = match.group("ident")
AttributeError: 'NoneType' object has no attribute 'group'
Same for me, testing with No Limit Cash Game Hands. Can provide you some examples if needed.
Same here: self._header_re returns unexpectably: re.compile('\n ^PokerStars\\s+ # Poker Room\n Hand\\s+\\#(?P<ident>\\d+):\\s+ # Hand history id\n , re.VERBOSE)
and list self._splitted returns only 1 value, the name of .txt file.
I tried to fixed that and will open a pull request soon. But I am not totally done with testing. Maybe someone can support in that case.
Sounds great! I will be happy to give a feedback once working with the new version. Unfortunately, I'm not able to help much more. I attach a Pokerstars Cash game HH sample. Sample.txt
As far as I can tell, there's still the same problem with regex Johnpc123 mentioned.
Seems I didn't understand the problem you have. I created a short test in test suite with the first hand from your file and it seems to me the header will be parsed without errors on the bugfix/pokerstars branch.
class TestGithubSampleHand:
hand_text = """
PokerStars Hand #213919888265: Hold'em No Limit ($0.05/$0.10 USD) - 2020/05/15 15:17:05 ET
Table 'Telesto II' 6-max Seat #3 is the button
Seat 1: Kriszti1111 ($9.35 in chips)
Seat 2: VictorKaminskiy ($10 in chips)
Seat 3: svarojih ($18.17 in chips)
Seat 4: smac2016 ($10.31 in chips)
Seat 5: Joker7771777 ($6.95 in chips)
Seat 6: berezkas ($10 in chips)
smac2016: posts small blind $0.05
Joker7771777: posts big blind $0.10
*** HOLE CARDS ***
berezkas: folds
Kriszti1111: folds
VictorKaminskiy: folds
svarojih: folds
smac2016: folds
Uncalled bet ($0.05) returned to Joker7771777
Joker7771777 collected $0.10 from pot
*** SUMMARY ***
Total pot $0.10 | Rake $0
Seat 1: Kriszti1111 folded before Flop (didn't bet)
Seat 2: VictorKaminskiy folded before Flop (didn't bet)
Seat 3: svarojih (button) folded before Flop (didn't bet)
Seat 4: smac2016 (small blind) folded before Flop
Seat 5: Joker7771777 (big blind) collected ($0.10)
Seat 6: berezkas folded before Flop (didn't bet)
"""
@pytest.mark.parametrize(
("attribute", "expected_value"),
[
("ident", "213919888265"),
("game_type", GameType.CASH),
("currency", Currency("USD")),
("game", Game.HOLDEM),
("limit", Limit.NL),
("sb", Decimal('0.05')),
("bb", Decimal('0.10')),
("date", ET.localize(datetime(2020, 5, 15, 15, 17, 5))),
("extra", {"money_type": MoneyType.REAL}),
],
)
def test_values_after_header_parsed(self, hand_header, attribute, expected_value):
assert getattr(hand_header, attribute) == expected_value
May you can post a code snippet how you use the library, or how you test it.
Okay, there was a mistake on my side - header parsing and most of the others work!
I've made an adjustment on line 261 of pokerstars.py - changed type from int to Decimal, seems to have helped.
self.total_pot = Decimal(match.group(1))
Also, when there are more hands in hh file than 1, calling _parse_flop() method throws this InvalidOperation error. Is there a better approach for getting multiple hh parsed then going one-by-one? Can the variable keep data from more hh hands at the same time?
C:\ProgramData\Anaconda3\lib\site-packages\poker\room\pokerstars.py in _parse_flop(self)
237 stop = self._splitted.index("", start)
238 floplines = self._splitted[start:stop]
--> 239 self.flop = _Street(floplines)
240
241 def _parse_street(self, street):
C:\ProgramData\Anaconda3\lib\site-packages\poker\handhistory.py in __init__(self, flop)
97 self.cards = None
98 self._parse_cards(flop[0])
---> 99 self._parse_actions(flop[1:])
100 self._all_combinations = itertools.combinations(self.cards, 2)
101
C:\ProgramData\Anaconda3\lib\site-packages\poker\room\pokerstars.py in _parse_actions(self, actionlines)
25 for line in actionlines:
26 if line.startswith("Uncalled bet"):
---> 27 action = self._parse_uncalled(line)
28 elif "collected" in line:
29 action = self._parse_collected(line)
C:\ProgramData\Anaconda3\lib\site-packages\poker\room\pokerstars.py in _parse_uncalled(self, line)
46 name_start_index = line.find("to ") + 3
47 name = line[name_start_index:]
---> 48 return name, Action.RETURN, Decimal(amount)
49
50 def _parse_collected(self, line):
InvalidOperation: [<class 'decimal.ConversionSyntax'>]
As I'll work more with the parser, I'll give you more feedback, great job! :)