0

I have the following code trying to solve the problem below:

Thrown n dice m times, calculate the probability of getting at least one 6.

I know that the exact probability of getting at least 1 six when throwing 2 dice is 11/36.

My program below seems to want the probability to be 0.333, which is close, but it should be 11/36 right?

Great if the suggestions can continue on the standard code I have made, but vectorized code is also appreciated.

import random
from sys import argv

m = int(argv[1]) # performing the experiment with m dice n times
n = int(argv[2]) # Throwing m dice n times
s = 0            # Counts the number of times m dies shows at least one 6

print '%.g dice are thrown %.g times' % (m, n)

for i in xrange(n):
    list = []    # used to clear the list for new die count
    for q in xrange(m):
        r = random.randint(1,6)#Picks a random integer on interval [1,6]
        list.append(r)         #appends integer value
        if len(list) == m:     #when list is full, that is when m dice has been thrown
            for i in xrange(len(list)):
                #print list
                if list[i] == 6: #if the list of elements has a six add to the counter
                    s += 1
                    pass #I want the loop to exit when it finds an element = 6

print 'Number of times one of the n dice show at least one 6: %.g' % s  
print 'Probability of at least 1 six from %.g dice is = %2.3f' % (m,s/float(n))

I will edit the code and questions if something is unclear.

Sample on output:

Terminal > python one6_ndice.py 2 1000000
2 dice are thrown 1e+06 times
Number of times one of the n dice show atleast one 6: 3e+05
Probability of atleast 1 six from 2 dice is = 0.333
Palaios
  • 57
  • 1
  • 8

2 Answers2

2

I think the problem is here:

 pass #I want the loop to exit when it finds an element = 6

pass won't exit the loop. pass is the no-operation command; it does nothing at all. You probably want break (which exits the loop).

BTW, don't call your lists list -- that clobbers the builtin list.

For a more compact expression, you might consider

sum(any(random.randint(1,6) == 6 for die in xrange(n)) for trial in xrange(m))

or

sum(6 in (random.randint(1,6) for die in range(n)) for trial in range(m))
DSM
  • 342,061
  • 65
  • 592
  • 494
  • Thank you for the suggestion and the pass/loop enlightenment. That seems to have fixed everything. BTW if I choose a best answer is it still possible to answer the question? – Palaios Nov 10 '12 at 15:11
  • 1
    @Palaios: yep, people can continue to answer. – DSM Nov 10 '12 at 15:14
1

You don't have to loop on the list neither to check its length. Just feed it and check if 6 is in it:

for i in xrange(n):
    list = []
    for q in xrange(m):
        r = random.randint(1, 6)
        list.append(r)
    if 6 in list:
        s += 1

If you want your program to be more compact and don't want to feed a list each time, you can stop the generation with break when you get a "6":

for i in xrange(n):
    for q in xrange(m):
        if random.randint(1, 6) == 6:
            s += 1
            break
Nicolas
  • 5,583
  • 1
  • 25
  • 37