On Sun, 5 Sep 2010 08:39:07 am lists wrote:

> while tossNo <= 99:
>     coinToss = random.randint

Move that out of the loop. There's no need to make the assignment 100 
times.

>     tossNo += 1
>     if coinToss(1,2) == 1:
>         heads += 1
>     else:
>         tails += 1


Rather than count the number of loops yourself, let Python do the 
counting:

import random
coinToss = random.randint
heads = tails = 0
for tossNo in range(100):
    if coinToss(1, 2) == 1:
        heads += 1
    else: 
        tails += 1



Can we do better? Absolutely! Since we know that there are exactly 100 
coin tosses, and the number of heads plus the number of tails makes 
100, why are we counting them both?


import random
coinToss = random.randint
heads = 0
for tossNo in range(100):
    if coinToss(1, 2) == 1:
        heads += 1

print "The coin landed on tails " + str(100-heads) + " times."
print "The coin landed on heads " + str(heads) + " times."

One small weakness -- if we ever decide to change the number of coin 
tosses from 100 to some other number, we have to remember to change 100 
in two places. We can fix that by defining a named constant. Python 
doesn't actually have constants, so we use the naming convention "all 
uppercase means this is a constant, please don't modify it":


import random
coinToss = random.randint
heads = 0
COUNT = 100
for tossNo in range(COUNT):
    if coinToss(1, 2) == 1:
        heads += 1

print "The coin landed on tails " + str(COUNT-heads) + " times."
print "The coin landed on heads " + str(heads) + " times."


Can we do better? Absolutely -- nothing says that heads must be 1 and 
tails 2. If we make heads 1 and tails 0, we get a neat optimization:

import random
coinToss = random.randint
heads = 0
COUNT = 100
for tossNo in range(COUNT):
    heads += coinToss(0, 1)



Can we do better? Yes. The function "coinToss" is misleading. It doesn't 
toss a coin, not even figuratively speaking -- it takes two arguments, 
and returns an integer between those two limits. How is that related to 
tossing a coin? What are you going to do, this?

coinToss(1, 7)  # toss a seven-sided coin

No, that's ridiculous, and so the name is misleading. What your function 
does is return a random integer. That's no surprise, because it's just 
random.randint renamed. So let's fix that by making a proper coinToss 
function:

import random
def coinToss():
    return random.randint(0, 1)

heads = 0
COUNT = 100
for tossNo in range(COUNT):
    heads += coinToss()


Can we do better? Yes, for some definition of "better":

import random
import functools
coinToss = functools.partial(random.randint, 0, 1)
COUNT = 100
heads = sum(coinToss() for tossNo in range(COUNT))
print "The coin landed on tails %d times." % (COUNT-heads)
print "The coin landed on heads %d times." % heads


It's certainly short and concise. You should be able to guess what sum 
does, and if you can guess what functools.partial does you're doing 
well :)



-- 
Steven D'Aprano
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor

Reply via email to