gotner
gotner

Reputation: 87

Python nested loops issues

I am trying to learn Python and I am writing a few scripts for fun to get used to the language.

I am trying to create a script that will roll 3 'dice' and if all 3 return 6, it will write it to a list, otherwise roll again and update the counter.

All this is supposed to happen a large amount of times, so that I can get a large list and then calculate the average amount of rolls needed to get triple 6.

After many iterations this is my code right now (probably sub-optimal since I edited it a lot to try and find a way for it to work)

    #!/usr/bin/python

from random import randint

first = randint(0,5)
second = randint(0,5)
third = randint(0,5)
count = 1
list = []

for_list =  range(10000)

for item in for_list:
        while first != 5 or second != 5 or third != 5:
                count+=1
                first = randint(0,5)
                second = randint(0,5)
                third = randint(0,5)
                if first == 5 and second == 5 and third == 5:
                        list.append(count)
                        count = 1
print sum(list) / float(len(list))

print list

Right now it seems like the while loop works, but I cant figure out how to get it to actually run many times (the for loop, in this example 10,000 times).

This is my output (prints "average" and the list, containing the count variable:

218.0
[218]

So in this run it took 218 rolls. After that the script ends. Can anyone help me understand why the script isn't running the for loop?

Thanks!

Upvotes: 1

Views: 668

Answers (2)

x otikoruk x
x otikoruk x

Reputation: 422

After a few modifications, I believe this may be what you want:

from random import randint

first = randint(0,5)
second = randint(0,5)
third = randint(0,5)
count = 1
list = []

for_list = 10001
completed = 0

while completed < for_list:
    completed = completed+1
    count=count+1
    first = randint(0,5)
    second = randint(0,5)
    third = randint(0,5)
    if first == 5 and second == 5 and third == 5:
        list.append(count)
        count = 1

print sum(list) / float(len(list))

print list

Which returned;

172.071428571 [214, 196, 44, 14, 43, 31, 427, 179, 427, 48, 134, 78, 261, 256, 36, 242, 244, 40, 189, 53, 140, 690, 26, 802, 39, 45, 2, 93, 30, 26, 351, 117, 455, 24, 190, 359, 83, 23, 60, 81, 38, 3, 173, 205, 175, 689, 233, 59, 26, 122, 263, 415, 211, 38, 94, 100]

EDIT: As Martijn Pieters (below) has said, you could remove the

first = randint(0,5)
second = randint(0,5)
third = randint(0,5)

from the outside of the loop.

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1121884

Your boolean condition is at fault here:

first != 5 or second != 5 or third != 5

This is only ever False if all three values are set to 5. The moment you find a triple-5 set, your while loop is always going to be False.

So after finding your first match, from there on out your first, second and third variables are set to 5, and the while loop is never entered the other 9999 times your for loop iterates.

Rather than use a while loop here, just use a large number of iterations and roll the dice each iteration, then use a simple if to add it to the list:

results = []
counter = 0

for iteration in xrange(10 ** 6):  # 1 million times
    counter += 1
    roll = random.randint(1, 6), random.randint(1, 6), random.randint(1, 6)
    if roll == (6, 6, 6):
        results.append(counter)
        counter = 0

I used a better name for the results list; you want to avoid using the same name as a built-in type for your variables. Since you are using Python 2, I also switched to using xrange(); no point in building a whole list of integers just to control how many times your loop should repeat.

I used a tuple to store the three dice rolls, and picked numbers from 1 to 6 to match the conventional dice numbers. You can then test if a match is found by comparing against another tuple of 3 numbers.

Demo:

>>> results = []
>>> counter = 0
>>> for iteration in xrange(10 ** 6):  # 1 million times
...     counter += 1
...     roll = random.randint(1, 6), random.randint(1, 6), random.randint(1, 6)
...     if roll == (6, 6, 6):
...         results.append(counter)
...         counter = 0
... 
>>> sum(results, 0.0) / len(results)
217.40704500978472
>>> len(results)
4599

Upvotes: 4

Related Questions