poker icon indicating copy to clipboard operation
poker copied to clipboard

Pokerstars hand history parser does not work

Open yuma300 opened this issue 5 years ago • 8 comments

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

yuma300 avatar Sep 21 '19 05:09 yuma300

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'

Johnpc123 avatar Apr 13 '20 22:04 Johnpc123

Same for me, testing with No Limit Cash Game Hands. Can provide you some examples if needed.

chris060986 avatar Apr 24 '20 06:04 chris060986

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.

jfiedler5 avatar May 18 '20 16:05 jfiedler5

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.

chris060986 avatar May 18 '20 16:05 chris060986

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

jfiedler5 avatar May 18 '20 17:05 jfiedler5

As far as I can tell, there's still the same problem with regex Johnpc123 mentioned.

jfiedler5 avatar May 19 '20 20:05 jfiedler5

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.

chris060986 avatar May 20 '20 07:05 chris060986

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! :)

jfiedler5 avatar May 20 '20 15:05 jfiedler5