Python while loop restarting code from the beginning - python

Need help adding a while loop to my code to start it from the beginning again after the user agrees to it. Every time I add it at the end of the code it skips it when I run it and I'm not sure how to do it at all. Any help is welcomed. Thank you!
print('Welcome to the Dice Game')
print(" ")
print('This program will simulate rolling a dice and will track the frequency each value is rolled.')
print(" ")
print('After rolling the dice, the program will output a summary table for the session.')
print(" ")
raw_input("Press Enter to continue...")
# function to roll the dice and get a value
def roll_dice():
r=random.randint(1,6)
return r
#to track the number of times rolled the dice
rolled=0
# to track the number of remaining turns
remaining=10000
# list to store the results
result=[]
# to track the number of sessions
sessions=0
while True:
#incrementing the session variable
sessions+=1
#getting the number of turns from the user
n=int(input("How many times would you like to roll the dice? "))
#checking the number of turns greater than remaining turns or not
if n > remaining:
print('You have only remaining',remaining)
continue
#rolling the dice according to the value of n
if rolled <= 10000 and n <= remaining :
for i in range(n):
result.append(roll_dice())
#updating the remaining turns and rolled variables
remaining=remaining-n
rolled=rolled+n
#printing the results and session variable
if rolled==10000:
print('---------------')
for i in range(len(result)):
print('|{:7d} | {:d} |'.format( i+1,result[i]))
print('---------------')
print('Rolled 10000 times in %d sessions' % sessions)
sys.exit(0)

Your rolled, remaining, result and sessions variables persist on the next iteration of the while loop. You need to redefine the variables on each iteration of the loop, because you're checking against the remaining variable to check if the user's turn is over. So instead of:
def roll_dice():
# ...
rolled = 0
remaining = 10000
result = []
sessions = 0
while True:
# ...
you need:
def roll_dice():
# ...
while True:
rolled = 0
remaining = 10000
result = []
sessions = 0
# ...

I see many unnecessary variables and comparisons in your code, a cleaner code usually results less bugs and better readability.
I suggest something like this:
def do_dice_game(rounds=1000):
sessions = 0
rolls = []
while rounds > 0:
sessions += 1
user_input = rounds + 1
while user_input > rounds:
user_input = int(raw_input("..."))
rolls += [random.randint(1, 6) for i in range(user_input)]
rounds -= user_input
# print something
def do_games():
to_continue = True
while to_continue:
do_dice_game()
to_continue = raw_input("...") == "continue"
Also, according to your code, numbers of each session has no effect on the final "rolled" result. You can always just record the number of sessions and then roll 1000 random numbers at the end.

Related

Yahtzee dice roll loop

I need help condensing my Yahtzee code. I'm familiar with loops, but I can't seem to figure out how to do it without wiping my roll each turn. It's set up to roll 5 random dice and then you choose which you want to keep. It will then roll what's left for three total rolls. I thought of making a placeholder list, but I can't make it work that way either.
Dice = [‘⚀ ’,‘⚁ ‘,’ ⚂ ‘,’ ⚃ ‘,’ ⚄ ‘,’ ⚅ ‘]
turns = 3
#first roll
first_roll = []
for _ in range(5):
roll = random.choice(dice)
first_roll.append(roll)
print(first_roll)
turns -= 1
print(f'You have {turns} turns left.')
keep = input("Which dice would you like to keep? 1 - 5: ").split()
clear()
#second roll
second_roll = []
for i in keep:
x = int(i)
j = first_roll[x-1]
second_roll.append(j)
remainder = 5 - len(second_roll)
for _ in range(remainder):
roll = random.choice(dice)
second_roll.append(roll)
print(second_roll)
turns -= 1
print(f'This is your last turn.')
keep = input("Which dice would you like to keep? 1 - 5: ").split()
clear()
#third roll
third_roll = []
for i in keep:
x = int(i)
j = second_roll[x-1]
third_roll.append(j)
remainder = 5 - len(third_roll)
for _ in range(remainder):
roll = random.choice(dice)
third_roll.append(roll)
print(third_roll)
So I'm not sure if this is exactly what you're looking for, but I created a function that lets you continuously roll for X turns and the dice pool gets progressively smaller like your code shows. I thoroughly commented the code to hopefully give you a good explanation to what I'm doing.
import random
#Dice characters
dice = ['1','2','3','4','5','6']
#Number of turns player has
turns = 3
#This is the group of dice kept by the player
kept_dice = []
def roll():
#This is the group of dice randomly chosen
rolled_dice = []
#Generate up to 5 random dice based on how many have been kept so far
for _ in range(5 - len(kept_dice)):
#Append random dice value to rolled_dice array
rolled_dice.append(random.choice(dice))
#Print roll group
print(rolled_dice)
dice_to_keep = int(input("Which dice would you like to keep? 1 - 5: "))
kept_dice.append(rolled_dice[dice_to_keep-1])
while turns != 0:
#Let the user know how many turns they have left
print(f'You have {turns} turns left.')
#Roll dice
roll()
#Subtract 1 turn
turns -= 1
#After all turns, show the kept dice:
print("Kept dice:")
print(kept_dice)

Im a little stuck in a dice rolling program in python, am very new to python and very confused

This is what the instructions are telling me to do...
main – This function is the main routine. It should do the following:
Ask the user how many dice they want to roll. If the user enters a number less than 1 or greater than 10, the program should continue to ask the user for a valid number between 1 and 10. Remember you can use a while loop to do input validation.
Once the program has a valid number from the user, it should use that number as an argument when calling the roll_dice function.
roll_dice – This function has one parameter, num_dice, which is the number of dice to roll.
Since the program will be displaying the total of the dice, start by initializing a variable to 0 which will keep a running total.
Use a for loop to roll each die the number of times specified.
Use the randint function from the random module to get a random digit between 1 and 6 inclusive.
Print the number of the loop iteration and the die value as indicated in the Sample Output.
Make sure to update the running total INSIDE the for loop.
After the for loop is complete, print the total value of all the dice that were rolled.
And this is the code I have so far:
import random
def main():
num_dice = int(input('How many dice do you want to roll?'))
while num_dice < 1 or num_dice > 10:
print('Enter a number between 1 and 10.')
num_dice = (input('How many dice do you want to roll?'))
roll_dice(num_dice)
def roll_dice(num_dice):
rolls = 0
for i in range(num_dice):
print(f'Roll #', rolls, random.randint(1, 6))
rolls+=1
main()
There's a few improvements:
you typically don't want to repeat code, so it would be better to only have the input statement in there once (that would have also avoided the mistake you made on the second one);
you are asked to return a sum total of rolls, but also to print each roll; you can either compute it before printing, or print the assigned value directly (with a walrus operator :=)
once you have the total, you'll need to do something with it, like print it.
Something like:
import random
def main():
# you can loop 'forever' and then break out under the right condition
while True:
# you'd forgotten one of the int()
num_dice = int(input('How many dice do you want to roll?'))
if num_dice < 1 or num_dice > 10:
print('Enter a number between 1 and 10.')
else:
break
result = roll_dice(num_dice)
print(f'The total for {num_dice} rolls was {result}.')
def roll_dice(num_dice):
rolls = 0
for i in range(1, num_dice + 1):
# you printed rolls, but you want i, starting at 1
# roll := something, causes roll to be assigned, but also returns the value
print(f'Roll #{i} = {(roll := random.randint(1, 6))}')
rolls += roll
return rolls
main()
(Edit: I noticed that you were already using an f-string in roll_dice, so you may as well make actual use of it)
I like #Blckknght's suggestion for another nice use of the walrus operator in a shorter version of main():
def main():
# you can loop 'forever' and then break out under the right condition
while (n := int(input('How many dice do you want to roll?'))) < 1 or n > 10:
print('Enter a number between 1 and 10.')
result = roll_dice(n)
print(f'The total for {n} rolls was {result}.')
Beware though: if someone asks you to explain your code, you better know what's going on here:
due to short-circuit evaluation, the first part of the or in the while is executed first, and the second part is only executed if the first part is False; that's why you can use the := in the first part and know that num_dice will have been updated for the second part;
the walrus operator assigns the righthand value, but also returns it, so it can be compared to 1
def main():
num_dice = int(input('How many dice do you want to roll?'))
while num_dice < 1 or num_dice > 10:
print('Enter a number between 1 and 10.')
num_dice = (input('How many dice do you want to roll?'))
roll_dice(num_dice)
def roll_dice(num_dice):
rolls = 0
for i in range(num_dice):
print(f'Roll #', rolls, random.randint(1, 6))
out_ran_num = random.randint(1, 6)
rolls+=out_ran_num
return rolls
main()
Please check indentation
First, we want to keep asking the user how many dice they want to roll until they give a valid input, we can do that with a while loop like so:
valid_integer = False
# While the user hasn't given a valid integer
while valid_integer == False:
# Note: this will crash if the user does not input a number
num_dice = int(input('How many dice do you want to roll?'))
# Checking if the input is valid
if num_dice < 1 or num_dice > 10:
print("Please enter a number between 1 and 10")
# Because we did not change the variable valid_integer, it will loop again
else:
valid_integer = True
print(roll_dice(num_dice))
Now we need to create the roll_dice function, it needs to take one parameter (the number of dice to roll) and return a integer (the total of the dice rolls)
import random
# num_dice: int is known as type hinting, it is used to indicate the type of a value
def roll_dice(num_dice: int):
total = 0
for i in range(num_dice):
roll = random.randint(1, 6)
total += roll
return total
Now we can put the code together! We need to put the loop in a function main() and call it. Don't forget your imports!
import random
def main():
valid_integer = False
# While the user hasn't given a valid integer
while valid_integer == False:
# Note: this will crash if the user does not input a number
num_dice = int(input('How many dice do you want to roll?'))
# Checking if the input is valid
if num_dice < 1 or num_dice > 10:
print("Please enter a number between 1 and 10")
# Because we did not change the variable valid_integer, it will loop again
else:
valid_integer = True
print(roll_dice(num_dice))
# num_dice: int is known as type hinting, it is used to indicate the type of a value
def roll_dice(num_dice: int):
total = 0
for i in range(num_dice):
roll = random.randint(1, 6)
total += roll
return total
if __name__ == "__main__":
main()
more info on if __name__ == "__main__" What does if __name__ == "__main__": do?
In main function in while loop there should int for taking input and should use roll_dice function outside while loop. there should be return word to get total as shown in figure
In roll_dies function there should should be rolls+=random.randint(1,6) and also
return rolls outside for loop

Calculating an average in "Rock, Paper, Scissors"

Last night I was thinking to my self about the probability of getting the same outcome in "Rock, Paper, Scissors" 10 times in a row. I worked out how to do that and completed that task but then I wanted to challenge myself a bit, so I wanted to adapt the program so it ran the initial program a number of times (10,000) and then outputted the average result, which I hoped would be close to the probability of getting the same 10 times in a row. Please note that I am not taking into account tactics, just that both players randomly pick either r, p, or s.
def rps():
num=0 # num is the number of times i want the programme to run while roll<10:
total=0 # this should be close to 3^10 * 10000, its the result of all the tries added together
while num <10001:
tries=0 # this is how many times the programme has tried to get p1=p2
roll=0 # this is the amount of times it has counted p1=p2 (it gets re-set everytime it reaches 10)
import random
while roll <10:
p1=random.randint(1,3)
p2=random.randint(1,3)
if p1==p2:
roll=roll+1
else:
tries=tries + 1
roll=0
num=num+1
if roll==10:
total=total+roll
roll=0
if num==10000:
print (num)
print (total/num)
rps()
There are quite a few problems with the program, for once, there isn't any use for the second for loop, I get that you are using the second for loop to reset the counter if the number of consecutive rolls reaches 10, but you are already doing that here
if roll==10:
total=total+roll
roll=0
by setting roll=0, you are resetting it.
also, the last if condition adds to the complexity,
if num==10000:
print (num)
print (total/num)
instead of this, you can just print the average outside the loop like this
if roll==10:
total=total+roll
roll=0
print (total/10000) #this being outside the while loop
one more thing, you are incrementing num only when roll1 != roll2, this adds to the number of times the loop has to run
This is how the program came out after the changes
import random
def rps():
num=0 #num is the number of times i want the programme to run while roll<10:
total=0 #this should be close to 3^10 * 10000, its the result of all the tries added together
roll = 0
while num <10001:
tries=0 #this is how many times the programme has tried to get p1=p2
p1=random.randint(1,3)
p2=random.randint(1,3)
if p1==p2:
roll = roll+1
else:
tries = tries + 1
roll = 0
if roll==10:
print(roll)
total += roll
roll=0
num = num + 1
print (total/10000)
print(tries)
rps()
The answer coming out was 0,I guess it was highly unlikely that you get 10 in a row.
Some self-explanatory code (so you can also learn to write clean code):
import random
def get_10_outcomes():
return [
(random.randint(1, 3), random.randint(1, 3))
]
def have_we_got_10_in_a_row():
return (
len(set(get_10_outcomes()))
== 1
)
def how_many_10_in_a_row_in_10000():
return len(list(filter(
None,
[have_we_got_10_in_a_row() for _ in range(10000)]
)))
def get_chance_of_10_in_a_row():
return how_many_10_in_a_row_in_10000() / 10000
chance = get_chance_of_10_in_a_row()
print('{:.3%}'.format(chance))

Python: iterate over true and false variables in a list, with different outcomes

I'm programming a yahtzee like game where a player rolls 5 dice and gets to pick which dice to re-roll.
I can't get my function to properly iterate over the user input verify that they are valid.
Here's some code:
def diceroll():
raw_input("Press enter to roll dice: ")
a = random.randint(1, 6)
b = random.randint(1, 6)
c = random.randint(1, 6)
d = random.randint(1, 6)
e = random.randint(1, 6)
myroll.append(a)
myroll.append(b)
myroll.append(c)
myroll.append(d)
myroll.append(e)
print "Your roll:"
print myroll
diceSelect()
def diceSelect():
s = raw_input("Enter the numbers of the dice you'd like to roll again, separated by spaces, then press ENTER: ")
rollAgain = map(int, s.split())
updateMyRoll(rollAgain)
def updateMyRoll(a):
reroll = []
for n in a:
if n in myroll:
reroll.append(n)
removeCommonElements(myroll, a)
print "deleting elements..."
elif n not in myroll:
print "I don't think you rolled", n, "."
diceSelect()
else:
print "I don't understand..."
diceSelect()
print "Your remaining dice: ", myroll
def removeCommonElements(a,b,):
for e in a[:]:
if e in b:
a.remove(e)
b.remove(e)
The problem is likely in the diceSelect function, such that I can enter only true values and it works fine, I can enter only false values and get the desired effect for ONLY the first false value (which I understand based on the code... but would like to change), or I can enter true AND false values but it ONLY acts on the true values but ignores the false values.
How can I iterate over these values and re-prompt the user to enter all true values?
You've got a couple of problems here in your code. I've re-written your code a bit:
def diceroll(dice_count=6):
raw_input("Press enter to roll dice: ")
# No need to create a variable for each roll.
# Also modifying global variables is a bad idea
rolls = []
for _ in range(dice_count-1):
rolls.append(random.randint(1,6))
# or **instead** of the above three lines, a list
# comprehension
rolls = [random.randint(1,6) for _ in range(dice_count-1)]
return rolls
def roll_select():
# one letter variable names are hard to follow
choices = raw_input("Enter the numbers of the dice you'd like to roll again, separated by spaces, then press ENTER: ")
# again, modifying global variables is a bad idea
# so return the selection
return map(int, choices.split())
def roll_new_dice(myroll):
# no need to create a new list, we have everything
# we need right here
for val in roll_select():
try:
print('deleting {}'.format(val))
# we can just remove the values directly. We'll get
# an exception if they're not in the list.
myroll.remove(val)
except ValueError:
print("That wasn't one of your rolls")
# Then we can re-use our function - this time
# extending our list.
myroll.extend(diceroll(6-len(myroll)))
rolls = diceroll()
print('You rolled {}'.format(rolls))
changes = roll_select()
if changes:
roll_new_dice(rolls)
print('Your new rolls: {}'.format(rolls))
Hopefully this should be a bit clearer than what you had before.

Python - Dice Simulator

This is my homework question:
Write a program that simulates rolling a set of six-sided dice multiple times. The program should use a dictionary to record the results and then display the results.
Input: The program should prompt for the number of dice to roll and the number of times to roll the dice.
Output:
The program is to display how many times each possible value was rolled. The format of the output must be as shown below:
The first column is the number shown on the dice when they are rolled. The brackets are only as wide as needed and the number inside the brackets is right justified. Note the minimum and maximum values in the sample runs below.
The second column is the number of times that value was rolled. This column is right justified.
The last column is the percent of times that the number was rolled. The percentages are displayed with an accuracy of one decimal place.
This is the code I have so far:
import random
from math import floor, ceil
one = 0
two = 0
three = 0
four = 0
five = 0
six = 0
rand = float(0)
rolltotal = int(input("How many times do you want to roll? "))
q = 0
while q < rolltotal:
q = q + 1
rand = ceil(6*(random.random()))
if rand == 1:
one = one + 1
elif rand == 2:
two = two + 1
elif rand == 3:
three = three + 1
elif rand == 4:
four = four + 1
elif rand == 5:
five = five + 1
else:
six = six + 1
total = one + two + three + four + five + six
print("[1]", one, " ",round(100*one/total, 1),"%")
print("[2]", two, " ",round(100*two/total, 1),"%")
print("[3]", three, " ",round(100*three/total, 1),"%")
print("[4]", four, " ",round(100*four/total, 1),"%")
print("[5]", five, " ",round(100*five/total, 1),"%")
print("[6]", six, " ",round(100*six/total, 1),"%")
My question is: I just know how to roll one dice. how can i get more than one .
from collections import defaultdict
import random
dice = int(input("How many dice do you want to roll? "))
rolls = int(input("How many times do you want to roll them? "))
irange = xrange
sides = [1,2,3,4,5,6]
d = defaultdict(int)
for r in irange(rolls):
d[sum( random.choice(sides) for d in irange(dice) )] += 1
total = float(rolls)
for k in sorted(d.keys()):
print "[%d] %d %.1f%%" % (k, d[k], 100.0*d[k]/total)
You would rather do the following:-
loop=True
import random #This allows python to import built in "random" function.
while loop is True:
dice=input("Which sided dice would you like to roll? (You can only choose 4,6 or 12) \n") # "\n" allows python to add a new line.
if dice=="4":
print("You have chosen to roll dice 4\nYour score is... \n", random.randint(1,4)) #This allows python to generate a random number from 1 to 4.
elif dice=="6":
print("You have chosen to roll dice 6\nYour score is...\n", random.randint(1,6)) #This allows python to generate a random number from 1 to 6.
elif dice=="12":
print("You have chosen to roll dice 12\nYour score is...\n", random.randint(1,12)) #This allows python to generate a random number from 1 to 12.
else: print("Invalid option! Please try again!")
loop2=input("Do you want to roll again? (Yes or No) \n")
if loop2=="yes" or loop2=="Yes": # "or" funtion allows python to accept any of the two answers input by the user.
loop=True
else: break # This function allows program to close.

Categories

Resources