Python dice rolling simulation - python

I'm having trouble with a code where I need to roll a six-sided die 1000 times and then return a list of how many times each number on the die was rolled.
The code runs just fine and I can get a list at the end, but my list keeps having 0 in place of four so it appears that my function is not keeping tabs on the number 4 being rolled or it's not being rolled at all.
I'm kind of stumped and I thought maybe someone here could help. Any and all help is appreciated.
Here's my code.
def rollDie(number):
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
for i in range(0, number):
roll=int(random.randint(1,6))
if roll == 1:
one = one+1
elif roll == 2:
two = two+1
elif roll == 3:
three = three+1
elif roll == 4:
four == four+1
elif roll == 5:
five = five+1
elif roll == 6:
six = six+1
return [one,two,three,four,five,six]

You have a small typo; you are testing for equality, not assigning:
four == four+1
should be:
four = four+1
However, you already have a number between 1 and 6, why not make that into an index into the results list? That way you don't have to use so many if statements. Keep your data out of your variable names:
def rollDie(number):
counts = [0] * 6
for i in range(number):
roll = random.randint(1,6)
counts[roll - 1] += 1
return counts

I can't improve on Martijn Pieters's answer. :-) But this problem can be more conveniently solved using a list.
import random
def rollDie(number):
# create a list with 7 values; we will only use the top six
rolls = [0, 0, 0, 0, 0, 0, 0]
for i in range(0, number):
roll=int(random.randint(1,6))
rolls[roll] += 1
return rolls
if __name__ == "__main__":
result = rollDie(1000)
print(result[1:]) # print only the indices from 1 to 6
And, this is a little bit tricky, but here is a better way to create a list of 7 entries all set to zero:
rolls = [0] * 7
Why count the zeros yourself? It's easier to just make Python do the work for you. :-)
EDIT: The list is length 7 because we want to use indices 1 through 6. There is also a position 0 in the list, but we don't use it.
Another way to do it is to map the dice rolls onto indices. It's a pretty simple mapping: just subtract 1. So, a die roll of 1 would go into index 0 of the list, a die roll of 2 would go into index 1, and so on. Now we will use every position in the list.
Here's that version:
import random
def rollDie(number):
rolls = [0] * 6
for i in range(0, number):
roll=int(random.randint(1,6))
rolls[roll - 1] += 1
return rolls
if __name__ == "__main__":
result = rollDie(1000)
print(result)

You should do random.randint(1, 7), otherwise you will never get a 6.
...
roll = random.randint(1, 7)

import random
def dice():
print random.randint(1,6)
dice()

Related

I am new, trying to roll 3d6, rerolling 1's, and put them into a list. I cant seem to get 3 "new" values in the list. The numbers just keep adding up

import random
my_stats = []
stat = 0
while len(my_stats) < 3:
for i in range(1,4): # generates a num (d6) but no 1's
number = (random.randint(1, 6))
while number == 1:
number = (random.randint(1, 6))
else:
stat += number # sums the 3 rolls into stat
my_stats.append(stat)
print(my_stats)
I am not sure how to get 3 distinct entries in my list, just keeps adding up.
Your code currently rolls a die 3 times, adding the results if the roll is not 1, otherwise rerolling the die pointlessly (as the value is never used). The summed value is then appended to a list and you repeat the process, but without resetting the sum to 0 first. So it contains at least 2 errors (as ignoring the 1 and not using the reroll doesn't appear to be what you want)
I think this is what you were after:
import random
my_stats = []
stat = 0
while len(my_stats) < 3:
# you'd want to restart the count every time
stat = 0
# you'll need to keep track of the number of good rolls, can roll any number of 1's
good_rolls = 0
while good_rolls < 3:
number = (random.randint(1, 6))
if number != 1:
stat += number # sums the 3 rolls into stat
good_rolls += 1
my_stats.append(stat)
print(my_stats)
You never reset stat.
Try moving its initialization into the loop, e.g.
while len(my_stats) < 3:
stat = 0
for i in range(1,4):
# ...

While loop doesn't work/loops forever | Beginner question [duplicate]

This question already has answers here:
How can I read inputs as numbers?
(10 answers)
Closed 1 year ago.
Below is my attempted solution to this problem: The top prize in a lottery is won by matching three numbers between 1 and 30 to three random numbers drawn in the same order. When a ball is drawn it is put back into the machine before another ball is drawn. There are always 30 balls in the machine before a ball is drawn and a player may choose the same ball more than once. A draw takes place once a week. Write a function that takes three numbers as parameters, draws three random numbers between 1 and 30 and returns the number of weeks it took to win the jackpot. (E.g. Numbers chosen: 17, 12, 25 must match: ball one is 17, ball two is 12, ball three is 25.)
My attempt:
import random
chosen = []
for i in range(0, 3, 1):
chosen.append(input("Please input your lucky number: "))
drawn_numbers = []
count = 0
week_count = 0
print("Your chosen numbers are: {}, {}, {}".format(chosen[0], chosen[1], chosen[2]))
while count != 3:
for i in range(0, 3, 1):
random_number = random.randint(1, 30)
drawn_numbers.append(random_number)
for i in range(0, 3, 1):
if drawn_numbers[i] in chosen:
count += 1
week_count += 1
drawn_numbers = []
print("It took you {} weeks to win.".format(week_count))
For some reason the while loop just ignores the count += 1 part and loops randomly generated drawn_numbers lists forever.
Obviously there is something wrong with my loop, but I can't see it D:
Some advice on how to make that loop work would be nice. Thanks.
First of all - welcome to the world of Python!
You have several mistakes:
The input function returns a string and not an int. Meaning, the comparison you try to do implicitly in if drawn_numbers[i] in chosen would never be true, thus count is always 0 and you got yourself an infinite loop.
Assuming that you've fixed the mistake above, you still have a chance of count never hitting 3 at the evaluation of the loop. Consider the following scenario:
A user enters the numbers [1, 2, 3]
The drawn_numbers are [1, 2, 4]
Thus, count will be now 2
The while condition is count != 3 is True and thus the loop continues.
The numbers are drawn again are [1, 2, 4]
The count will be now 4
From now on, count can only increase and will never be equal to 3!
Do you see where this is going? Try to reset the count at the start of loop (inside)!
a lottery is won by matching three numbers ... in the same order
But the comparison you've implemented only looks for existence in the list instead of comparing element by element.
So, a working (not written in the most Pythonic way) version will be:
import random
chosen = []
for i in range(0, 3, 1):
chosen.append(int(input("Please input your lucky number: "))) # notice the int cast
drawn_numbers = []
count = 0
week_count = 0
print("Your chosen numbers are: {}, {}, {}".format(chosen[0], chosen[1], chosen[2]))
while count != 3:
count = 0 # notice that count is reset here
for i in range(0, 3, 1):
random_number = random.randint(1, 30)
drawn_numbers.append(random_number)
for i in range(0, 3, 1):
if drawn_numbers[i] == chosen[i]: # notice that we compare the elements in the same location
count += 1
week_count += 1
drawn_numbers = []
print("It took you {} weeks to win.".format(week_count))
If you're interested, here is a more Pythonic way:
import random
chosen = [int(input("Please input your lucky number: ")) for _ in range(3)]
print(f'Your chosen numbers are: {chosen}')
matched = False
week_count = 0
while not matched:
drawn_numbers = [random.randint(1, 30) for _ in range(3)]
matched = drawn_numbers == chosen
week_count += 1
print(f"It took you {week_count} weeks to win.")
In which you might find several features that might be new to you but I strongly encourage you to master them:
List comprehension
range(3) is equivalent to range(0, 3, 1)
Formatting string literals
The == operator actually compares two lists element by element!
Funny side note: Running this code without the order restriction results in much less weeks to wait to win the lottery :)
Have you checked your if-statement ever becomes true?
One thought is, that chosen might includes string-values as numbers. Try running:
print(type(chosen[0]))
This should be a int. Fix it by:
chosen.append(int(input("Please input your lucky number: ")))

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

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)
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.
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)
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

How to use the random.choice function with a large amount of numbers [duplicate]

This question already has answers here:
Python dice rolling simulation
(4 answers)
Closed 9 years ago.
I have a homework problem that states use the random.choice function to simulate the
roll of the die. . It will still simulate rolling a six-sided die 1000 times. Do i have to type out the list like 0, 1000? Or is there an easier way of doing it.
import random
def rolldie3():
#6 variables set to 0 as the counter
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
#use for loop for 1000 times to run
for i in range(1000):
scores = range(0,1000)
#get a random number out of the list
roll = random.choice(scores)
if roll == 1:
one = one + 1
elif roll == 2:
two = two + 1
elif roll == 3:
three = three + 1
elif roll == 4:
four = four + 1
elif roll == 5:
five = five + 1
elif roll == 6:
six = six + 1
#return the variables as a list
return [one,two,three,four,five,six]
I think you want something like this:
roll = random.choice([1,2,3,4,5,6])
As is, you're choosing a random dice roll, but only doing anything if it's 1 through 6.
Check out the random.choice description: http://docs.python.org/2/library/random.html#random.choice
random.choice(seq)
Return a random element from the non-empty sequence seq. If seq is empty, raises IndexError.
So you need to call this function by passing it a sequence to pick from, which you're trying to do with your scores variable. But that goes from 0 to 999, when you want it to go from 1 to 6. So define your range better:
scores = range(1,7)
for i in range(1000):
#get a random number out of the list
roll = random.choice(scores)
...
range(x,y) counts from x (inclusive) to y (exclusive), which is why 7 gives what you want.

While loop while rolling dice

I am trying to use a while loop instead of a for loop while rolling dice. I do not think elif is right, but I cannot figure out how to use the while loop within this. This is what I have so far:
import random
def rolldiewhileloop():
number = 10
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
while number > 0:
flip = int(random.random() * 6)
if(flip == 1):
one = one + 1
elif flip == 2:
two = two + 1
elif flip == 3:
three = three + 1
elif flip == 4:
four = four + 1
elif flip == 5:
five = five + 1
elif flip == 6:
six = six + 1
return [one, two, three, four, five, six]
In your current while loop you aren't changing the value of number, so this will be an infinite loop. Since you are starting at 10 and looping until number is less than or equal to zero, you should probably be decrementing by one on each iteration:
number = 10
while number > 0:
number -= 1
# the rest of the loop
Note that number -= 1 is equivalent to number = number - 1.
As a side note, instead of multiplying the result of random.random() it would be better to use random.randint(1, 6). Also, since you are returning an array already it would be more Pythonic to create a list of the results and modify that, rather than creating a separate variable for each possibility. For example:
def rolldiewhileloop():
results = [0] * 6
number = 10
while number > 0:
number -= 1
flip = random.randint(1, 6)
results[flip-1] += 1
return results
You need to decrement number on each pass of the while loop. Put number -= 1 as the last line in the while loop.

Categories