on writing a while loop for rolling two dice

dn PythonList at DancesWithMice.info
Sat Sep 11 05:09:38 EDT 2021



On 11/09/2021 18.03, Chris Angelico wrote:
> On Sat, Sep 11, 2021 at 3:26 PM dn via Python-list
> <python-list at python.org> wrote:
>>
>> On 31/08/2021 01.50, Chris Angelico wrote:
>>> On Mon, Aug 30, 2021 at 11:13 PM David Raymond <David.Raymond at tomtom.com> wrote:
>>>>
>>>>> def how_many_times():
>>>>>   x, y = 0, 1
>>>>>   c = 0
>>>>>   while x != y:
>>>>>     c = c + 1
>>>>>     x, y = roll()
>>>>>   return c, (x, y)
>>>>
>>>> Since I haven't seen it used in answers yet, here's another option using our new walrus operator
>>>>
>>>> def how_many_times():
>>>>     roll_count = 1
>>>>     while (rolls := roll())[0] != rolls[1]:
>>>>         roll_count += 1
>>>>     return (roll_count, rolls)
>>>>
>>>
>>> Since we're creating solutions that use features in completely
>>> unnecessary ways, here's a version that uses collections.Counter:
>>>
>>> def how_many_times():
>>>     return next((count, rolls) for count, rolls in
>>> enumerate(iter(roll, None)) if len(Counter(rolls)) == 1)
>>>
>>> Do I get bonus points for it being a one-liner that doesn't fit in
>>> eighty characters?
>>
>>
>> Herewith my claim to one-liner fame (assuming such leads in any way to
>> virtue or fame)
>>
>> It retains @Peter's preference for a more re-usable roll_die() which
>> returns a single event, cf the OP's roll() which returns two results).
>>
>>
>> import itertools, random
>>
>> def roll_die():
>>     while True:
>>         yield random.randrange(1, 7)
>>
>> def how_many_times():
>>     return list( itertools.takewhile( lambda r:r[ 0 ] != r[ 1 ],
>>                                       zip( roll_die(), roll_die() )
>>                                       )
>>                )
>>
>> Also, a claim for 'bonus points' because the one-liner will fit within
>> 80-characters - if only I didn't have that pernicious and vile habit of
>> coding a more readable layout.
>>
>> It doesn't use a two-arg iter, but still rates because it does use a
>> relatively-obscure member of the itertools library...
>>
> 
> Nice, but that's only going to give you the ones that don't match. You
> can then count those, and that's a start, but how do you capture the
> matching rolls?
> 
> I smell another opportunity for gratuitous use of a language feature:
> nonlocal. In a lambda function. Which may require shenanigans of epic
> proportions.


The stated requirement is: "I'd like to get the number of times I
tried". Given such: why bother with returning any of the pairs of values?

Further, if you look at the OP's original solution, it only publishes
the last pair, ie the match, without mention of the list of non-matches.
Was it perhaps only a means of testing the solution?

Regret that I'll settle for (or continue to seek) 'fame'. I don't play
guitar, so have no use for epic.
-- 
Regards,
=dn


More information about the Python-list mailing list