[Tutor] I flip a coin 1 million times what is the consecutive times it will come up head and come up tails

Alan Gauld alan.gauld at yahoo.co.uk
Tue Feb 26 18:31:39 EST 2019


On 26/02/2019 20:34, shaeffer at q.com wrote:
> I am learning python. 

I assume you are coming from some other language?
If not you have managed to come up with the most
convoluted and un-pythonic way imaginable to do
a fairly simple task!

>  I wanted to test my ability by making a program to
> keep track of the flip of a coin to find how many consecutive times it came
> up heads and tails.
> 
> import random
> 
> Hn = {}
> Tn = {}
> 
> for i in range (0,31):
>     vars()["Hn"+str(i)] = 0

This is insane!
Just use a list which is indexed by number.
No need for string conversions and no need for
the cumbersome access to vars

Hn = [0 for i in range(31)]

You can then access each cell using

Hn[num]

Instead of having to compute the name every time
and then access a dictionary.

> for i in range (0,31):
>     vars()["Tn"+str(i)] = 0    

Same here.

> total_Heads = 0
> total_tails= 0 
> tails_number = 0
> Heads_number = 0

> tries = 0
> while tries < 10000:
>     tries += 1
This is essentially a for loop:

for tries in range(10000):

>     coin = random.randint(1, 2)   #  Flip coin
>     if coin == 1:
>         Heads_number += 1         #  Incroment Heads count
>         total_Heads += 1
>         if tails_number > 0 :
>             vars()["Tn"+ str(tails_number)] += 1   #  Incroment tails
> consecutive count

This becomes

Tn[tails_number] += 1

But why are you incrementing the head counts above but the tails_number
value here? That doesn't make sense. I assume you are trying to
terminate the count of consecutive values?

>             tails_number = 0

>     if coin == 2:
>         tails_number += 1       #  Incroment Talies count
>         total_tails += 1
>         if Heads_number > 0:
>             vars()["Hn"+ str(Heads_number)] += 1  #  Incroment Heads
> consecutive count

Hn[heads_number] += 1

>             Heads_number = 0

> print (tries)
> print (total_tails, total_Heads)
> for i in range (30):
>     print ('%-15s %-15s' %(("Tn"+str(i)+"

      print('Tn[%d] %d   \tHn[%d] %d' % (i,Tn[i],i, Hn[i])

I think. Your code is so complex that I may have misread it.

> "+str(eval("Tn"+str(i)))),
> ("Hn"+str(i)+" "+str(eval("Hn"+str(i))))))

Using eval() should hardly ever (never?) be necessary
in normal coding and poses a significant security risk.
Any time you think you need to use it ask for help
because you are probably wrong and there will be a
better option.


> print out
> 100000000
> 
> 50000259 49999741
> 
> Tn0 0           Hn0 0          
> 
> Tn1 12497339    Hn1 12500186   
> 
> Tn2 6257043     Hn2 6251565    
> 
> Tn3 3120686     Hn3 3127257    

Given you only looped to 10,000 these results seem
rather suspect.

Even if your algorithm is correct, which I suspect
it may not be, the code is way too complex.

If all you want is the max count of consecutive head
and tails you only need to keep one counter for each
and update it each time a new max is reached. Keep
track of the last face. If the new toss is the same
increment the appropriate count. If its not then check
if the current count is greater than the previous max
for that face and if necessary update it. Then reset
the current count and face.

-- 
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos




More information about the Tutor mailing list