endplay
endplay copied to clipboard
Feature Request for generate_deals and calc_all_tables Pattern
I propose some features to make the following code pattern easier and more obvious.
- DealList.to_list() which returns a Python list of Deal. The issue is when I access
d
aftercalc_all_tables
, I get an address exception so the workaround is to create a Python list/tuple beforecalc_all_tables
, henced_t = tuples(d)
. - DDTableList.ResTable.to_list() which returns a Python list of lists (list of directions containing list of suits), ordered same as pprint()
tuple(tuple(sd[suit][direction] for suit in [3,2,1,0,4]) for direction in [0,2,3,1])
? - Question: Why is resTable.pprint() ordered as NSWE instead of NSEW or NESW?
d = generate_deals()
d_t = tuple(d) # create a tuple before Deal storage goes wonky
tables = calc_all_tables(d_t)
t_t = (tt._data.resTable for tt in tables)
for ii,(dd,sd,tt) in enumerate(zip(d_t,t_t,tables)):
print(f"Deal: {ii+1}")
dd.pprint()
print()
tt.pprint()
print(tuple(tuple(sd[suit][direction] for suit in [3,2,1,0,4]) for direction in [0,2,3,1]))
print()
generate_deals
is a generator, so in the same way you might write list(range(n))
or list(permutations(l))
to collect the deals into a list you should do d = list(generate_deals())
- there isn't a DealList
object as such. I think this idiom is common enough, and lazy evaluation has enough upsides, that it is ok as is but I am open to counter arguments.
Is there a particular reason you would like the DDTable as a 2D list? Seeing as it is trivial to add to_list
I have put it in though. The reason for classes such as DDTable
and DDTableList
is that they just wrap the underlying C structs, avoiding making copies of the underlying data each time the dds interface is called. In the case above, the code could be rewritten using the __getitem__
operator of DDTable
:
from endplay import *
deals = list(generate_deals())
tables = calc_all_tables(deals)
for ii, (dd, tt) in enumerate(zip(deals, tables)):
print(f"Deal: {ii+1}")
dd.pprint()
print()
tt.pprint()
print(tuple(tuple(tt[s, p] for s in Denom.bidorder()) for p in Player.iter_order("NSEW")))
print()
It might be worthwhile me making it easier to customize the order of iteration of the enumerations though.
As for why the pprint order is NSWE: I agree, NSEW is more logical. I have changed that to the default, but added players
and denoms
parameters which let you customize the table to display any subset.