What is wrong with this Python code? Refuses input - python

Every time I enter 4, 6 or 12 it doesn't accept it. Why? The code looks fine to me. Please tell me how to correct or what to change.
import random
def roll_the_dice():
print("Roll The Dice")
print()
repeat = True
while repeat:
number_of_sides = input("Please select a dice with 4, 6 or 12 sides: ")
if (number_of_sides in [4,6,12] and len(number_of_sides) == 0 and
number_of_sides == int):
user_score = random.randint(1,number_of_sides)
print("{0} sided dice thrown, score {1}".format(
number_of_sides,user_score))
roll_again = input("Do you want to roll the dice again? ")
roll_again.lower()
if roll_again == "no":
print("Have a nice day")
repeat = False
elif len(roll_again) == 0:
print("Error please type 'yes' or 'no'")
roll_again = input("Do you want to roll the dice again? ")
else:
print("You have entered an incorrect value, please try again")
number_of_sides = input("Please select a dice with 4, 6 or 12 sides: ")

In Python 3, when using input(), it returns a string. Thus, you would have something like "4". And "4" is not 4.
So in your script, specifically at the if number_of_sides in [4,6,12], it will always be False, because you are really saying if "4" in [4,6,12] (I'm just doing 4 as an example).
Convert the string to an integer:
>>> int("4")
4
It also looks like you are trying to determine if an input was given. len(...) == 0 is not needed. You can just say if number_of_sides. Because an empty string is False, and if one was entered, then the if-statement will not execute.
Also, number_of_sides == int is not the way to check if an object is an integer. Use isinstance():
>>> isinstance("4", int)
False
>>> isinstance(4, int)
True
Some other tiny things:
.lower() does not sort the string in place, as strings are immutable in python. You might just want to attach .lower() onto the end of the input().
You might also want to use a while loop for your second input. Observe:
roll_again = ''
while True:
roll_again = input('Do you want to roll the dice again? ')
if roll_again in ('yes', 'no'):
break
print("You have entered an incorrect value, please try again")
if roll_again == "no":
print("Have a nice day")
repeat = False
else:
print("Let's go again!")

Haidro gave you the reason, but here is a different way to approach your problem:
def get_dice_size():
dice_size = input('Enter the number of sides on the dice: ')
while dice_size not in ['4','6','12']:
print 'Sorry, please enter one of 4, 6 or 12:'
dice_size = input('Enter the number of sides on the dice: ')
return int(dice_size)
def main():
dice_size = get_dice_size()
repeat = True
while repeat:
print('Rolling the dice...')
user_score = random.randint(1,dice_size)
print("{0} sided dice thrown, score {1}".format(dice_size,user_score))
roll_again = input("Do you want to roll the dice again? ")
if roll_again.lower() == 'yes':
dice_size = get_dice_size()
else:
repeat = False
print('Thank you for playing!')

You should change your script like shown below.
This is the important part:
try:
number_of_sides = int(input("Please select a dice with 4, 6 or 12 sides: "))
except ValueError:
wrong = True
Convert to int right at input time with int(input("…. If the user enters anything that cannot be converted into an integer Python will raise a ValueError. You can catch this, show a message and go to the start of the loop with continue.
import random
def roll_the_dice():
print("Roll The Dice")
print()
repeat = True
while repeat:
wrong = False
try:
number_of_sides = int(input("Please select a dice with 4, 6 or 12 sides: "))
except ValueError:
wrong = True
if wrong or number_of_sides not in [4,6,12]:
print("You have entered an incorrect value, please try again")
continue
else:
user_score = random.randint(1,number_of_sides)
print("{0} sided dice thrown, score {1}".format(
number_of_sides,user_score))
roll_again = input("Do you want to roll the dice again? ")
if roll_again in ('y', 'Y', 'yes', 'Yes'):
continue
else:
print("Have a nice day")
repeat = False
roll_the_dice()

Related

How to loop a simple game to continue until user stops it not using a break?

def set_number():
import random
return random.randint(1,500)
#This function plays the game
def number_guessing_game(number):
guess_counter = 0
guess = int(input("Enter a number between 1 and 500."))
while guess != number:
guess_counter += 1
if guess > number:
print(f"You guessed too high. Try Again!")
guess = int(input("Enter a number between 1 and 500."))
elif guess < number:
print(f"You guessed too low. Try Again!")
guess = int(input("Enter a number between 1 and 500."))
if guess == number:
print(f"You guessed the number! Good Job.!")
again = str(input("would you like to play again? Enter 'y' for yes or 'n' to close the game."))
def main():
print(f"Welcome to the Number Guessing Game!\n" +
f"You will have unlimited guesses. The number is between 1 and 500.\n" +
f"Good Luck!")
number = set_number()
guess_count = number_guessing_game(number)
main()
I am working on a simple game project for my coding class. I am not good at coding at all. I came up with this part of the program, I just cannot figure out how to loop the entire number_guessing_game function until the user enters 'n' to stop it, I can't use a break because we did not learn it in the class and I will receive a 0 if I use a break.
I tried nesting a while loop inside of the function but I know I did it wrong.
Instead of using break use return.
def main():
print(f"Welcome to the Number Guessing Game!\n" +
f"You will have unlimited guesses. The number is between 1 and 500.\n" +
f"Good Luck!")
while True:
number = set_number()
number_guessing_game(number)
again = input("would you like to play again? Enter 'y' for yes or 'n' to close the game.")
if again == 'n':
return
main()
You will probably want to remove the last line of the number_guessing_game function if you use this approach
First, your code is assuming the return of input is an integer that can be converted with int(). If you were to give it 'n' your program will crash.
Instead you could use the string class method isdigit() to see if the input was an integer value and then make a logical decision about it. Also note you do not need to convert the return from input to a str() as it is already a str type. You can confirm this with a print(type(input("give me something")))
guess = input("Enter a number between 1 and 500. 'n' to quit"))
if guess.isdigit():
[your code to check the value]
elif ('n' == guess):
return
else:
print(f"You entered an invalid entry: {guess}. Please re-enter a valid value")
If you dont like the idea of using 'return' you could change your while loop to look something like:
while(('n' != guess) or (guess != number)):
If you want the function body looping continuously you could have some code like:
def number_guessing_game(number):
exit_game = False
guess_counter = 0
while(exit_game != True):
guess = input("Enter a number between 1 and 500.))
guess_counter += 1
if guess.isdigit():
if int(guess) > number:
print("You guessed too high. Try Again!")
elif int(guess) < number:
print("You guessed too low. Try Again!")
elif int(guess) == number:
print("You guessed the number! Good Job.!")
again = input("would you like to play again? Enter 'y' for yes or 'n' to close)
if ('n' == again):
exit_game = True
else:
print("Error, please enter a valid value")

What's the reason why second parameter of a function is always being treated as 1?

My goal is to create a dice roller which lets the user choose both the number of dice and number of sides.
The problem started when I made it possible for the user to go through the process again (select number of dice and of sides). Now it doesn't display the result of anything besides the first die and, when the user types "n" and function breaks, sometimes it does, and sometimes it keeps going. This last part makes sense because the function "start" comes next. I haven't figured a way to truly finish running the script.
from random import randint
def dice(n_sides, n_dice):
rolls = []
for i in range(n_dice):
# variable "roll" generates random number between 1 and user input
roll = randint(1, n_sides)
# variable "roll" is appended to the previously created empty list "rolls"
rolls.append(roll)
# enumerates however many results there was
i += 1
# prints the end result to the user
print("Result", i, ":", roll)
choice = input("Do you want to roll the dice again? (y/n)")
# if user input is "y", start over by running function "start"
if choice.lower() == 'y':
start()
# uses lower() so that lower case is allowed
elif choice.lower() == 'n':
# break terminates function
break
def start():
print()
try:
print("How many sides your dice has?")
n_sides = int(input().lower())
# if something other than integers are typed by user
except ValueError:
print("This is not a whole number.")
try:
print("How many dice do you want to use?")
n_dice = int(input().lower())
# if something other than integers are typed by user
except ValueError:
print("This is not a whole number.")
dice(n_sides, n_dice)
start()
Here's a better way to organize this. Have each function do one thing. When it has done its one thing, let someone else make the decisions.
Also, it's pointless to call lower() when all you want is integers.
from random import randint
def dice(n_sides, n_dice):
rolls = []
for i in range(n_dice):
# variable "roll" generates random number between 1 and user input
roll = randint(1, n_sides)
# variable "roll" is appended to the previously created empty list "rolls"
rolls.append(roll)
# prints the end result to the user
print("Result", i+1, ":", roll)
return rolls
def round():
print()
try:
n_sides = int(input("How many sides your dice has?"))
# if something other than integers are typed by user
except ValueError:
print("This is not a whole number.")
continue
try:
n_dice = int(input("How many dice do you want to use?"))
# if something other than integers are typed by user
except ValueError:
print("This is not a whole number.")
continue
print(dice(n_sides, n_dice))
while True:
round()
choice = input("Do you want to roll the dice again? (y/n)")
if choice.lower() == 'n':
break
What I understood is, you have n dices each having m sides and the user will roll all the dices per input.
Your code has the bug inside dice(n_sides, n_dice): function as you are executing all the statements in the for loop which is running same times the number of dices. Remember, indentation is important in python
Also, while you're taking input, you can use a while loop to force the user to input a valid number like this:
isNumeric = False
while(isNumeric == False):
try:
print("How many sides your dice has?")
n_sides = int(input().lower())
isNumeric = True
# if something other than integers are typed by user
except ValueError:
print("This is not a whole number.")
isNumeric = False
while(isNumeric == False):
try:
print("How many dice do you want to use?")
n_dice = int(input().lower())
isNumeric = True
# if something other than integers are typed by user
except ValueError:
print("This is not a whole number.")
To remove the bug in your dice function, you can do as follows:
def dice(n_sides, n_dice):
rolls = []
for i in range(n_dice):
# variable "roll" generates random number between 1 and user input
roll = randint(1, n_sides)
# variable "roll" is appended to the previously created empty list "rolls"
rolls.append(roll)
# prints the end result to the user
print("Result of Dice Number", i+1, ":", roll)
choice = input("Do you want to roll the dice again? (y/n)")
# if user input is "y", start over by running function "start"
if choice.lower() == 'y':
start()
# uses lower() so that lower case is allowed
This will smoothly solve all of your problems!
First of all, I would use exit() instead of break. Break can be used in loops (see here: https://www.programiz.com/python-programming/break-continue)
Secondly, use a while loop for the yes or no question, like:
while True:
a = input("Do you want to roll the dice again? (y/n)")
if a == "y":
start()
continue
elif a == "n":
exit()
else:
print("Enter either y/n")
So if you don't want to change the logic of the code:
from random import randint
def dice(n_sides, n_dice):
rolls = []
for i in range(n_dice):
roll = randint(1, n_sides)
rolls.append(roll)
i += 1
print("Result", i, ":", roll)
while True:
a = input("Do you want to roll the dice again? (y/n)")
if a == "y":
start()
continue
elif a == "n":
exit()
else:
print("Enter either y/n")
def start():
while True:
try:
print("How many sides your dice has?")
n_sides = int(input())
break
except ValueError:
print("This is not a whole number.")
while True:
try:
print("How many dice do you want to use?")
n_dice = int(input())
break
except ValueError:
print("This is not a whole number.")
dice(n_sides, n_dice)
if __name__ == '__main__':
start()
Edit:
you need to import exit to do this: from sys import exit

Computer Generates a Number, User Guesses Number, No Matter What it is Always Incorrect

I made a simple program where a user guesses a randomly generated computer number. To test if the program is working, I changed the generated computer value to 5. However, when I "guess" 5, I am somehow still incorrect.
Can someone please tell me what is wrong with this code?
I tried messing about with returning variables but I don't understand how the return command works so I was not successful.
def computer_roll():
global comproll
comproll = random.randint(1,3)
# comproll = 5
user_guess()
def user_guess():
global user
user = input("Input a number: ")
guess_evaluation()
def guess_evaluation():
if user != comproll:
print("You are incorrect.")
again = input("Would you like to try again? ")
if again in("y"):
user_guess()
elif again in ("n"):
print("Thanks for playing.")
elif user == comproll:
print("You are correct.")
again = input("Would you like to play again? ")
if again in("y"):
user_guess()
elif again in ("n"):
print("Thanks for playing.")
computer_roll() # Start```
# Expected Results:
# When I enter 5 it should say "You are correct." and then "Would you like to play again?"
# Actual Results:
# When I enter 5 it says "You are incorrect" and then "Would you like to play again?"
You are comparing integer with string which is why it will never be correct.
Try, user = int(input("Input a number: "))
On a sidenote, you really shouldn't be using global variables. Learn to use returns especially since you are using functions, otherwise there is no point using functions at all.
Below is a sample code:
import numpy as np
import random
def computer_roll():
return random.randint(4,6)
def user_guess():
return int(input("Input a number: "))
def guess_evaluation():
if user_guess() != computer_roll():
print("You are incorrect.")
else:
print("You are correct.")
again = input("Would you like to play again? ")
if again in ("n"):
print("Thanks for playing.")
else:
guess_evaluation()
guess_evaluation()
For me it works, except for the syntax error at the input field:
def guess_evaluation():
if user != comproll:
print("You are incorrect.")
again = input("Would you like to try again? ")
if again in("y"): # syntax error here, enter space between "in" and "('y')".
user_guess()
elif again in ("n"):
print("Thanks for playing.")
user input curently a string when comproll is a int. You can change this with:
user = int(input("Input a number: "))

Ask for correct input untill it is given in python [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 4 years ago.
I have a code that is asking a user if they wanna play a game they either press Y or N. If they press Y it asks them to choose a number between 1 and 10 if they press N it says oh okay.
But I want it to ask again if the user input is not y or n. and if they dont press y or n it will ask again and again and again untill they press y or n.
#!/usr/bin/env python3
import random
number = random.randint(1, 10)
tries = 0
win = False # setting a win flag to false
name = input("Hello, What is your username?")
print("Hello" + name + "." )
question = input("Would you like to play a game? [Y/N] ")
if question.lower() == "n": #in case of capital letters is entered
print("oh..okay")
exit()
if question.lower() == "y":
print("I'm thinking of a number between 1 & 10")
while not win: # while the win is not true, run the while loop. We set win to false at the start therefore this will always run
guess = int(input("Have a guess: "))
tries = tries + 1
if guess == number:
win = True # set win to true when the user guesses correctly.
elif guess < number:
print("Guess Higher")
elif guess > number:
print("Guess Lower")
# if win is true then output message
print("Congrats, you guessed correctly. The number was indeed {}".format(number))
print("it had taken you {} tries".format(tries))
Add a while loop to make sure they choose one of them:
[..]
question = ''
while question.lower() not in ['n', 'y']:
question = input("Would you like to play a game? [Y/N] ")
if question.lower() == "n": #in case of capital letters is entered
print("oh..okay")
exit()
# No need of else or elif here because 'n' answers will exit code.
print("I'm thinking of a number between 1 & 10")
[..]
Try putting your question code in a function. Like this:
def ask():
question = input("Would you like to play a game? [Y/N] ")
if question.lower() == "n": #in case of capital letters is entered
print("oh..okay")
exit()
elif question.lower() == "y":
print("I'm thinking of a number between 1 & 10")
else:
ask()

PYTHON: Unable to loop properly

EDIT: Thank you, the question has been answered!
The program works properly, asides from the fact that it does not loop to allow the user to play a new game. ie, after entering too many, too few, or the perfect amount of change, the program asks "Try again (y/n)?: " as it should. But I can't find out why it doesn't loop... And when it loops, it doesn't need to include the large paragraph about explaining the game. Just the line about "Enter coins that add up to "+str(number)+" cents, one per line." Any tips?
#Setup
import random
playagain = "y"
#Main Loop
if (playagain == "y"):
number = random.randint(1,99) #Generation of how many cents
total = 0 #Running sum of guessed coins.
print("The purpose of this exercise is to enter a number of coin values")
print("that add up to a displayed target value. \n")
print("Enter coins values as 1-penny, 5-nickel, 10-dime,and 25-quarter.")
print("Hit return after the last entered coin value.\n")
print("Enter coins that add up to "+str(number)+" cents, one per line.\n")
while (True):
if (total == 0):
word = "first"
else:
word = "next"
guess = str(input("Enter "+str(word)+" number: ")) #Records coin value
#Entry Validation
if (guess == ""): #When user is done guessing.
if (total < number):
print("Sorry - you only entered "+str(total)+" cents.\n")
break
elif (total > number):
print("Sorry - total amount exceeds "+str(number)+" cents.\n")
break
else:
print("Correct!")
break
elif (int(guess) == 1) or (int(guess) == 5) or (int(guess) == 10) or (int(guess) == 25):
total = total + int(guess)
else:
print("Invalid entry")
playagain = str(input("Try again (y/n)?: ")) #BRETT: I can't seem to get this to loop properly.
By using break, you're completely leaving the while loop and never checking the playagain condition. If you want to see if the user wants to play again put the 'playagain' check in another while loop.
#Setup
import random
playagain = "y"
#Main Loop
while (playagain == "y"):
number = random.randint(1,99) #Generation of how many cents
total = 0 #Running sum of guessed coins.
print("The purpose of this exercise is to enter a number of coin values")
print("that add up to a displayed target value. \n")
print("Enter coins values as 1-penny, 5-nickel, 10-dime,and 25-quarter.")
print("Hit return after the last entered coin value.\n")
print("Enter coins that add up to "+str(number)+" cents, one per line.\n")
while (True):
if (total == 0):
word = "first"
else:
word = "next"
guess = str(input("Enter "+str(word)+" number: ")) #Records coin value
#Entry Validation
if (guess == ""): #When user is done guessing.
if (total < number):
print("Sorry - you only entered "+str(total)+" cents.\n")
break
elif (total > number):
print("Sorry - total amount exceeds "+str(number)+" cents.\n")
break
else:
print("Correct!")
break
elif (int(guess) == 1) or (int(guess) == 5) or (int(guess) == 10) or (int(guess) == 25):
total = total + int(guess)
else:
print("Invalid entry")
playagain = str(input("Try again (y/n)?: ")) #BRETT: I can't seem to get this to loop properly.
You set playagain to y/n, but the code doesn't go back around to the beginning if playagain is equal to 'y'. Try making if playagain == "y" into while playagain == "y". That way, it goes through the first time and keeps going back to the beginning if playagain is still set to "y".
Also, indent your last line (playagain = str(....)) so it's part of the while playagain == "y" loop. If it's not, then the code will be stuck in an infinite loop because playagain isn't being changed inside the while loop.
Indent the last line as far as the while True line. And change the if (playagain == "y"): to a
while (playagain == "y"):
Your "Main loop" is not a loop, it is just an if statement. Also it is better to use raw_input because input will eval your input. Try something along the lines of this:
playagain = 'y'
#Main loop
while playagain == 'y':
print "do gamelogic here..."
playagain = raw_input("Try again (y/n)?: ")
Inside your gamelogic, you could use a boolean to check wether you need to print the game explanation:
show_explanation = True
while playagain == 'y':
if show_explanation:
print "how to play is only shown once..."
show_explanation = False
print "Always do this part of the code"
...
playagain = raw_input("Try again (y/n)?: ")

Categories

Resources