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

Nathan Pinno falcon3166 at hotmail.com
Tue Aug 9 21:35:33 CEST 2005

``` Hey all,

I just fixed it so that it prints. The problem was that it returned the

Nathan
---------------------------------------------------------------
Early to bed,
Early to rise,
Makes a man healthy, wealthy, and wise.
--Benjamin Franklin
-------------------------------------------------------------------
----- Original Message -----
From: "Nathan Pinno" <falcon3166 at hotmail.com>
To: "Brian van den Broek" <bvande at po-box.mcgill.ca>
Cc: "Tutor mailing list" <tutor at python.org>
Sent: Tuesday, August 09, 2005 1:32 PM
Subject: Re: [Tutor] Use functions re avoid Re: Can the following
algorithmbe improved?

> 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
>>
>>
> _______________________________________________
> Tutor maillist  -  Tutor at python.org
> http://mail.python.org/mailman/listinfo/tutor
>
```