Count throws for sixes in rolling dice python
Question: For an introductionary course in Python I got an assignment to make a
simulation for eolling dice

You want all of your dices (5 in total) to get the value six, and count how
many throws in total it takes for a person to get all sixes. I need a loop
that simulates this problem 100.000 times and then need to divide the total
amount of counts by 100.000 to get the outcome. I know that the final outcome
should be something around 13, but I am not getting that and I am not sure
why.

I know something is wrong in my approach to this problem , but what?

    
    
    import random
    
    count1=0
    count2=0
    count3=0
    count4=0
    count5=0
    loopcounter = 0
    
    for loopcouter in range (1,100000):
        dice1=int( random.random()*6)+1
        if dice1 != 6:
            #reroll
            while dice1 != 6:
                dice1=int( random.random()*6)+1
                #set counter1
                count1 = count1+1
            else:
                count1 = 1
    
            dice2=int( random.random()*6)+1
            if dice2 != 6:
                #reroll while not six
                while dice2 != 6:
                    dice2=int( random.random()*6)+1
                    #set counter2
                    count2 = count2+1
            else:
                count2 = 1
    
            dice3=int( random.random()*6)+1
            if dice3 != 6:
                #reroll while not six
                while dice3 != 6:
                    dice3=int( random.random()*6)+1
                    #set counter3
                    count3 = count3+1
            else:
                count3 = 1
            dice4=int( random.random()*6)+1
            if dice4 != 6:
                #reroll while not six
                while dice4 != 6:
                    dice4=int( random.random()*6)+1
                    #set counter4
                    count4 = count4+1
            else:
                count4 = 1
    
            dice5=int( random.random()*6)+1
            if dice5 != 6:
                #reroll while not six
                while dice5 != 6:
                    dice5=int( random.random()*6)+1
                    #set counter5
                    count5 = count5+1
            else:
                count5 = 1
    
    
        #print (dice1)
        print (count1)
    
    #print (dice2)
    print (count2)
    #print (dice3)
    print (count3)
    #print (dice4)
    print (count4)
    #print (dice5)
    print (count5)
    
    allcount = count1+count2+count3+count4+count5
    averagecount = int(allcount / 100000)
    
    print ("the total number of throws is",allcount)
    print ("the average number of throws is",averagecount)
    

So, if anyone could tell me what I am doing wrong, that would be perfect!


Answer: According to the instructions you need the maximum of count for each round as
this will tell you how many rolls you needed to get all 6s. This is a re-write
of your code using a loop for each dice:

    
    
    import random
    
    allcount = 0
    for loopcouter in range(100000):   # 1,100000 would only loop 99999 times
        count = [0]*5
        for i in range(5):             # 5 dice
            while True:
                dice = random.randint(1,6)  # Use randint
                count[i] += 1
                if dice == 6:
                    break
        allcount += max(count)         # The number of rolls needed to get all 6s
    
    averagecount = allcount // 100000
    
    print("the total number of throws is", allcount)
    print("the average number of throws is", averagecount)
    

And this seems to average in 12/13 range.

There are many ways to solve this for example you can use `iter` and an
anonymous function `lambda` to replace the inner while loop. These start to
use more advanced features of python (iterators and generators):

    
    
    from random import randint
    
    allcount = 0
    for _ in range(100000):
        counts = [1]*5
        for i in range(5):
            dice = list(iter(lambda: randint(1,6), 6))
            counts[i] += len(dice)
        allcount += max(counts)
    averagecount = allcount // 100000
    

In fact you can completely collapse this into one line of code but it gets
increasingly harder to read and breaks all sorts of manner of style:

    
    
    allcount = sum(max((1 + sum(1 for _ in iter(lambda: randint(1, 6), 6)))
                       for _ in range(5)) for _ in range(100000))
    averagecount = allcount // 100000
    

