dominicprice / endplay

A suite of tools for generation and analysis of bridge deals. Read the documentation at https://endplay.readthedocs.io
MIT License
21 stars 5 forks source link

Error importing LIN file: AttributeError: 'NoneType' object has no attribute 'suit' #55

Open LGTrader opened 1 week ago

LGTrader commented 1 week ago

I'm starting to work with LIN files downloaded from my games at BBO and ran into a hand that the lin.load() function is having trouble with. I don't see anything wrong in the LIN file myself but I could easily miss it. Original named Hand_08.lin I renamed it to 28 to make it last to load.

If it matters I'm on Kubuntu 24.04 in a virtual environment running Python 3.12

Very simple code to load a directory of LIN files to check them:

import glob
import os
import endplay.parsers.lin as lin

# Set the directory path where the .pbn files are located
path = '/home/mark/WinShare/Jack 6/BBO/2024_06_13/Lin Files/'  

# Create a list of all .lin files in the directory
lin_files = sorted(glob.glob(os.path.join(path, '*.lin')))

for file_name in lin_files:
    with open(file_name) as f:
        print()
        print(file_name)
        boards = lin.load(f)`

Lin Files.zip

LGTrader commented 1 week ago

Possibly I should have included a little more info showing the failure I see:

/home/mark/WinShare/Jack 6/BBO/2024_06_13/Lin Files/Hand_17.lin

/home/mark/WinShare/Jack 6/BBO/2024_06_13/Lin Files/Hand_18.lin

/home/mark/WinShare/Jack 6/BBO/2024_06_13/Lin Files/Hand_28.lin Traceback (most recent call last): File "/home/mark/CODE/python/Simple Bridge Program/LIN_File_Checker.py", line 15, in boards = lin.load(f) ^^^^^^^^^^^ File "/home/mark/Python_3.12_CUDA_venv/lib/python3.12/site-packages/endplay/parsers/lin.py", line 185, in load return parser.parse_file(fp) ^^^^^^^^^^^^^^^^^^^^^ File "/home/mark/Python_3.12_CUDA_venv/lib/python3.12/site-packages/endplay/parsers/lin.py", line 122, in parse_file boards.append(self.parse_line(line)) ^^^^^^^^^^^^^^^^^^^^^ File "/home/mark/Python_3.12_CUDA_venv/lib/python3.12/site-packages/endplay/parsers/lin.py", line 92, in parse_line tricks = total_tricks(play, contract.denom) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/mark/Python_3.12_CUDA_venv/lib/python3.12/site-packages/endplay/utils/play.py", line 42, in total_tricks winner = trick_winner(trick, first, trump) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/home/mark/Python_3.12_CUDA_venv/lib/python3.12/site-packages/endplay/utils/play.py", line 26, in trick_winner if trick[i].suit == topcard.suit: ^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'suit'

LGTrader commented 1 week ago

OK, I now know what happened, at least with this file. In the case of this hand we either ran out of time or possibly someone lost Internet connectivity so the LIN file was terminated prematurely also the game was awarded. The original LIN data looks like this:

pn|drpaul2,butteminer,jathomas3,lgtrader|st||md|2STKH28D68JQC35TJK,S249H467TJQD239C2,S567H5KAD457C689Q,|rh||ah|Board 8|sv|o|mb|p|mb|p|mb|1S|mb|2C|mb|p|mb|p|mb|d|mb|p|mb|2H|mb|3C|mb|p|mb|p|mb|3S|mb|p|mb|p|mb|p|pg||pc|DQ|pc|D2|pc|D4|pc|DK|pg||pc|CA|pc|C3|pc|C2|pc|C6|pg||pc|C4|pc|C5|pc|S2|pc|C8|pg||pc|D3|pc|D5|pc|DA|pc|D6|pg||pc|C7|pc|CT|pc|S9|pc|C9|pg||pc|S4|pc|S5|pc|SJ|pc|SK|pg||pc|CK|pc|D9|pc|CQ|pc|S3|pg||pc|H9|pc|H2|pc|H4|pc|HA|pg||pc|D7|pc|DT|pc|DJ|pc|H6|pg||pc|CJ|pc|H7|pc|H5|pc|S8|pg||pc|H3|pc|H8|pc|HQ|pc|HK|pg||pc|S6|

Looking at the last few tricks the game went like this:

|pc|CJ|pc|H7|pc|H5|pc|S8|pg| |pc|H3|pc|H8|pc|HQ|pc|HK|pg| |pc|S6|

North played the spade 6. I was sitting east with the spade A & Q. Not sure if we ran out of time or what happened but the last two tricks were awarded to me. To account for this I modified the original LIN file to show what would of happened. In the case of this hand there was no ambiguity as to what cards would have been played:

|pc|CJ|pc|H7|pc|H5|pc|S8|pg| |pc|H3|pc|H8|pc|HQ|pc|HK|pg| |pc|S6|pc|SA|pc|ST|pc|HT|pg| |pc|SQ|pc|D8|pc|HJ|pc|S7|pg||

With those modifications the file now loads and runs correctly.

In the short term I will just move the offending files to a unused location. I've found a few but not verified this is the issue in all of them.

I think this could be fixed by using double dummy to fill in the cards missing at the end which, if nothing else, might save someone some time in the future.

Hope this helps