# [Tutor] Use functions re avoid Re: Can the following algorithm be improved?

Nathan Pinno falcon3166 at hotmail.com
Tue Aug 9 21:32:18 CEST 2005

```Hey Brian and all,

Just coded in and tried your program Brian. Doesn't print a thing.

I thought the odds were more like 6/52! or 1/(1.3443029195*10^84).
---------------------------------------------------------------
Early to bed,
Early to rise,
Makes a man healthy, wealthy, and wise.
--Benjamin Franklin
-------------------------------------------------------------------
----- Original Message -----
From: "Brian van den Broek" <bvande at po-box.mcgill.ca>
To: "Nathan Pinno" <falcon3166 at hotmail.com>
Cc: "Tutor mailing list" <tutor at python.org>
Sent: Sunday, August 07, 2005 10:03 PM
Subject: Re: [Tutor] Use functions re avoid Re: Can the following algorithm
be improved?

> Nathan Pinno said unto the world upon 2005-08-07 22:10:
>> My message is in the attachment.
>
> Nathan,
>
> Just one fellow's voice, but I vote for "please don't do that" [the
>
>> Here is the improved algorithm:
>> import random    a = random.choice(range(52))
> <snip assignments b-t>
>> u = random.choice(range(52))
>> cards = ['Ace of Hearts','Two of Hearts',
>
> <snip definition of a full deck>
>
>>          'Jack of Clubs','Queen of Clubs','King of Clubs']
>> print "The Card Dealer"
>> print "By Nathan Pinno"
>> while 1:
>>     cd = int(raw_input("How many cards to deal (1-6) or 9 to exit:"))
>>     if cd == 1:
>>         print cards[a]
>>     elif cd == 2:
>>         print cards[b]
>>         print cards[c]
>>     elif cd == 3:
>>         print cards[d]
>>         print cards[e]
>>         print cards[f]
>>     elif cd == 4:
>>         print cards[g]
> <snip>
>>         print cards[j]
>>     elif cd == 5:
>>         print cards[k]
> <snip>
>>         print cards[o]
>>     elif cd == 6:
>>         print cards[p]
> <snip q-t>
>>         print cards[u]
>>     elif cd == 9:
>>         break
>> print "Goodbye."
>>
>> Can it be improved on anympre?
>
> <snip lots of good advice from Danny>
>
> Yep. You should follow Danny's suggestion and make a function which deals
> a single card. Then, your can call that function the requisite number of
> times.
>
> I'm not sure in the code here why you define a-u. Is there some reason you
> cannot have the two card case use a and b, the 3 case a, b, and c, etc.?
>
>> R. Alan Monroe suggested a different way. Instead of cards, you would
>> would
>> have cardrank and type. To get the cardrank and type you would do a % 4,
>> and for the type a % 13. It would work, only how would you keep two
> > identical cards from showing up?
>
> Good question. But notice that your code has the same problem. Nothing
> stops the (dramatically unlikely) even that a-u all get assigned the same
> card. Over 6 cards, it will certainly turn up that you have given the same
> card twice with this code, too. (The way I figure it:
>
> >>> ( (52**6) - (52*51*50*49*48*47.0) ) / (52**6)
> 0.25858966166881681
>
> 25% of the time.)
>
> Say you go with your method of defining a deck (cards above) and then
> making random choices from it. Try something like this (untested code):
>
> cards = ["Ace of ...",] # As above
> cards_dealt = []
> def get_card():
>     while True:
>         new_card = random.choice(cards)]
>         if new_card not in cards_dealt:
>             cards_dealt.append(new_card)
>             break
>     return new_card
>
> while True:
>     cd = #as before
>     if cd == 9:
>         break
>     elif cd in range(1, 7):
>         the_deal = []
>         for i in range(cd):
>             the_deal.append(get_card())
>     else:
>
>
> This could still be improved a lot (it was off the cuff). For instance,
> get_card might in theory take 1000's of attempts to get a 'fresh' card.
> There are much more efficient ways. But it might be a shorter step from
> the code you have. Small improvements are small, but they are also
> improvements.
>
> I really suggest you take make a closer examination of Danny's coin
> example.
>
> Best,
>
> Brian vdB
>
>
```