Python - rolling a dice fairly and counting how many 4's I get

5.2k views Asked by At

So I had to make code that roll a die fairly and counted how many 4's I got. With the help of you all on here I got it to work. Well now I have to created another die and roll them and then add they products together. This is the instructions I've been given.

"Then write another function that simulates rolling two fair dice. The easy way is to call the function you just wrote, twice, and add the numbers you get. This should return a number between 2 and 12. It should calculate BOTH numbers in ONE run – you are counting two distinct things."

And this is my code freshly fixed.

from random import randrange
def roll():
    rolled = randrange(1,7)
    if rolled == 1:
        return "1"
    if rolled == 2:
        return "2"
    if rolled == 3:
        return "3"
    if rolled == 4:
        return "4"
    if rolled == 5:
        return "5"
    if rolled == 6:
        return "6"


def rollManyCountTwo(n):
    twoCount = 0
    for i in range (n):
        if roll() == "2":
            twoCount += 1
    print ("In", n,"rolls of a pair of dice, there were",twoCount,"twos.")

rollManyCountTwo(6000)
3

There are 3 answers

4
Anand S Kumar On BEST ANSWER

You shouldn't be calling randrange() inside the roll() in every if condition, instead you should call it once and save it in a variable and check.

The code would look like -

from random import randrange
def roll():
    rolled = randrange(1,7)
    if rolled == 1:
        return "1"
    if rolled == 2:
        return "2"
    if rolled == 3:
        return "3"
    if rolled == 4:
        return "4"
    if rolled == 5:
        return "5"
    if rolled == 6:
        return "6"


def rollManyCountFour(n):
    fourCount = 0
    for i in range (n):
        if roll() == "6":
            fourCount += 1
    print ("In", n,"rolls of a due, there were",fourCount,"fours.")

rollManyCountFour(6000)
5
Marcus Müller On

Your code is bad, and hence, not as random as it should be.

randrange(low,up) includes both boundaries.

Look at what you do in the roll function:

you roll a dice. If it is 1, you return "1". If it is not 1, you roll the dice again! That's simply wrong, and in a game would be considered cheating.

Your roll function is absolutely unnecessary, and can be replaced by str(randrange(1,6)).

Also, why would you need the numbers as strings? You don't actually use these strings, so just stick with the result of randrange as it is -- a number.

EDIT:

You say

Yeah I'm assuming some of it is unnecessary but it's for a class and this is the way he wants it so I'm trying to keep it how he wants. I thought that's what I was doing but I could find a way around it!

All of it is unnecessary. There is a function that does what you want, so no need to encapsulate this in a class.

Well, you can just

class ash_class(object):
    def roll():
        return str(randrange(1,6))

For your counting problem: Python comes with all the tools.

counts = [0] * 6 # this is [0,0,0,0,0,0]
for i in range(n):
    counts[randrange(1,6)] += 1
print counts

As you notice, it's really handy if the randrange numbers are numbers and not strings, as you can then use them like numbers to index an array.

As a personal advice: There should always be the freedom to discuss bad design choice. One such bad design choice is forcing you to convert numbers to strings, when you clearly need to work with them as numbers.

0
Thomas.F On

I have used np.random.randint(1, 7, N), with N being the number of rolls and have used the following system to store it (if this helps):

R1s = 0
R2s = 0
R3s = 0
R4s = 0
R5s = 0
R6s = 0
for i in range(0, N):
    if x[i] == 1:
        R1s += 1
    elif x[i] == 2:
        R2s += 1
    elif x[i] == 3:
        R3s += 1
    elif x[i] == 4:
        R4s += 1
    elif x[i] == 5:
        R5s += 1
    else:
        R6s += 1

print(R1s)
# Ans ≈ N/6