[Tutor] Use functions re avoid Re: Can the following algorithm be improved?
Brian van den Broek
bvande at po-box.mcgill.ca
Mon Aug 8 06:03:46 CEST 2005
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
attachment]. It makes it more work to read your message.
> 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:
print "Read the instructions, please."
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
More information about the Tutor
mailing list