How to terminate this loop in python? - python

import random
def validate_user_input(input):
try:
val = int(input)
except ValueError:
print("Please enter a valid input.")
return True
hidden_number = random.randint(1, 10)
user_input = ""
while user_input != hidden_number:
user_input = input("Guess the number from (1 to 1000).")
if validate_user_input(user_input) is True:
continue
else:
if int(user_input) == hidden_number:
print("You have guessed the correct number.", hidden_number)
elif int(user_input) > hidden_number:
print("You have guessed a number higher than the correct number.")
elif int(user_input) < hidden_number:
print("You have guessed a number lower than the correct number.")
else:
print("You have guessed the correct number.")
When the user has inputted the correct number I want the while function to terminate but it instead continues to loop. I tried setting a variable as true in the else function instead but that doesn't work either.
Python 3.5+

The problem is that the input function returns a string, and not an integer. The right way to make your code work without changing it would be to declare user_input as an integer somewhere in the loop. One way to do it to keep the validate_user_input function active and useful would be to put the int() directly in the while declaration, just like this:
import random
def validate_user_input(input):
try:
val = int(input)
except ValueError:
print("Please enter a valid input.")
return True
hidden_number = random.randint(1, 10)
user_input = 0
while int(user_input) != hidden_number:
user_input = input("Guess the number from (1 to 1000)."))
if validate_user_input(user_input) is True:
continue
else:
if int(user_input) == hidden_number:
print("You have guessed the correct number.", hidden_number)
elif int(user_input) > hidden_number:
print("You have guessed a number higher than the correct number.")
elif int(user_input) < hidden_number:
print("You have guessed a number lower than the correct number.")
else:
print("You have guessed the correct number.")

Related

Is there a way to make an integer input output a certain thing when a sting or float is inputted? [duplicate]

This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed last year.
Here is my code:
x = 1
while x == 1:
fav_number = int(input("Guess my favorite number: "))
print()
if fav_number == 8:
print("Gongrats, you guessed it!")
x = 2
else:
print("Nope, try again!")
print()
In this example, I want it to also say "Nope, try again!" when the user inputs in a float or a string without crashing the program.
while True:
try: #Use the try/except block to raise exception if value is not integer
fav_number = int(input("Guess my favorite number: "))
print()
except ValueError: # if value is anything but integer, exception is raised
print("Invalid entry. Try again.")
else:
if fav_number == 8:
print("Gongrats, you guessed it!")
break #code ends when number is guessed
else:
print("Nope, try again!")
To make it more interesting, you can add a predefined number of attempts. If attempts are exhausted, code stops:
attempts = 5
while attempts > 0:
attempts -= 1
try: #Use the try/except block to raise exception if value is not integer
fav_number = int(input("Guess my favorite number: "))
print()
except ValueError: # if value is anything but integer, exception is raised
print("Invalid entry. Try again.")
else:
if attempts > 0:
if fav_number == 8:
print("Gongrats, you guessed it!")
break #code ends when number is guessed
else:
print("Nope, try again!")
print(f"You have {attempts} left")
else:
print("You have exhausted your attempts.")
You can, use eval in python for the string would convert int to int and float to float without exception. Check the documentation here: https://docs.python.org/3/library/functions.html#eval
So basically you can change the int to eval:
x = 1
while x == 1:
fav_number = eval(input("Guess my favorite number: "))
print()
if fav_number == 8:
print("Gongrats, you guessed it!")
x = 2
else:
print("Nope, try again!")
print()

Getting error from implementing Try/Except

I am trying to add a try/except to my guessing game for non numerical entries from the user. Im not really sure how to implement it with my code but I did try but got an error saying:
ValueError: invalid literal for int() with base 10: 'v'
I am not sure how to rearrange my code to get it to work with the try/except.
def guessing_game(secret_number: int, user_guess: int):
num_tries: int = 0
user_name: str = input("Please enter your name: ")
print(f"Hello {user_name}, i am thinking of a number between 1 and 20")
secret_number: int = randint(1, 19)
user_guess: int = int(input("Guess what it is: "))
try:
while num_tries != 5:
if user_guess > secret_number:
user_guess = int(input("Your guess is too high. Try again: "))
elif user_guess < secret_number:
user_guess = int(input("Your guess is too low. Try again: "))
else:
print(f"Congrats {user_name}, {secret_number} was the number i was thinking of")
break
num_tries += 1
if user_guess != secret_number and num_tries == 5:
print(f"Sorry.The number I was thinking of was {secret_number}")
except ValueError:
print("Error, value must be numerical")
guessing_game(2, 8)
You're probably looking for something like this. No need to wrap everything in a function here (you weren't using the two arguments you passed in anyway).
The outer for loop handles stopping the game once all attempts are exhausted; Python's (quite unique) for/else structure handles losing the game.
The inner while loop loops for as long as the user is giving invalid input; you could add if not (1 <= user_guess <= 19): raise ValueError() in there to also have validation for whether the user is being silly and entering e.g. -1 or 69.
To simplify things, there's only one input() any more, and the game loop modifies the prompt for it.
from random import randint
user_name: str = input("Please enter your name: ")
print(f"Hello {user_name}, i am thinking of a number between 1 and 20")
secret_number: int = randint(1, 19)
prompt = "Guess what it is: "
for num_tries in range(5):
while True:
try:
user_guess: int = int(input(prompt))
break # out of the while
except ValueError:
print("Error, value must be numerical")
if user_guess > secret_number:
prompt = "Your guess is too high. Try again: "
elif user_guess < secret_number:
prompt = "Your guess is too low. Try again: "
else:
print(f"Congrats {user_name}, {secret_number} was the number i was thinking of")
break
else: # for loop was not `break`ed out of
print(f"Sorry. The number I was thinking of was {secret_number}")
Error explanation:
You are not correctly catching the exception because the input casting is outside the try block.
When user tries to enter a literal string, the line:
user_guess: int = int(input("Guess what it is: "))
raises ValueError because that string is not int-castable and the instruction is not inside the try, meaning that the default traceback handles the exception.
Just move that line inside the try block
try:
user_guess: int = int(input("Guess what it is: "))
Code improvement:
That been said, you need to organize your code better. First off your function should just do the matching between user input and secret number. Then you would create the loop and call that function for each user input:
def guessing_game(secret_number: int, user_guess: int):
if user_guess > secret_number:
print("Your guess is too high.")
elif user_guess < secret_number:
user_guess = print("Your guess is too low.")
else:
print(f"Congrats {user_name}, {secret_number} was the number i was thinking of")
return True
user_name = input("Please enter your name: ") # String casting is redundant here.
print(f"Hello {user_name}, i am thinking of a number between 1 and 20")
secret_number = randint(1, 19) # Why not (1,20) though?
# Here is the loop. It keeps prompting the user to enter a number and if the
# input represents a valid integer the function is called to compair them.
num_tries = 0
while True:
if num_tries == 5:
print(f"Sorry.The number I was thinking of was {secret_number}")
break
try:
user_guess = int(input("Guess what it is: "))
if guessing_game(secret_number, user_guess) == True:
break
except ValueError:
print("Error, value must be numerical")
num_tries += 1

Crashing when improper input given more than once

I'm trying to make a simple number guesser program, it works pretty well however if I enter 'a' twice instead of a valid int it crashes out. Can someone explain what I'm doing wrong here.
import random
def input_sanitiser():
guess = input("Please enter a number between 1 and 10: ")
while True:
if type(guess) != int:
guess = int(input("That isn't a number, try again: "))
elif guess not in range (1,11):
guess = int(input("This is not a valid number, try again: "))
else:
break
def main():
number = random.randrange(1,10)
guess = 0
input_sanitiser()
while guess != number:
if guess < number:
print("This number is too low!")
input_sanitiser()
if guess > number:
print("This number is too high!")
input_sanitiser()
else:
break
print ("Congratulations, you've guessed correctly")
if __name__ == "__main__":
main()
You want to check the input before trying to convert it to int:
int(input("This is not a valid number, try again: "))
I would write:
while True:
try:
guess = int(input("This is not a valid number, try again: "))
except ValueError:
pass
else:
break
Side note: the code isn't working as expected:
def main():
number = random.randrange(1,10)
guess = 0
input_sanitiser() # <<<<<<<<<<
while guess != number:
Note that input_sanitiser does not modify the variable guess in main, you need some other way round, like processing the input then returning the result from input_sanitiser, like this:
def input_sanitiser():
guess = input("Please enter a number between 1 and 10: ")
while True:
try:
guess = int(input("This is not a valid number, try again: "))
except ValueError:
continue # keep asking for a valid number
if guess not in range(1, 11):
print("number out of range")
continue
break
return guess
def main():
number = random.randrange(1,10)
guess = input_sanitiser()
while guess != number:
if guess < number:
print("This number is too low!")
guess = input_sanitiser()
if guess > number:
print("This number is too high!")
guess = input_sanitiser()
else:
break
print ("Congratulations, you've guessed correctly")

Cleanup this program

I finally got it working! But for some reason the program prints out the previous error statement (too high or too low or please enter values between...), along with the value error message if the user enters in something that the try catches. Could anyone explain why? Any shortening/cleanup is also welcome. Sorry for any errors. Thanks!
'''
This is a guessing game that finds a random number, and then
Tells the user if their guess is too low or too high. It will also give
Error messages for any numbers outside of the accepted range, and will also
Give errors for anything not an integer.
At the end (if the user guesses correctly) it will ask if the
User would like to play again or quit.
'''
import random
def start_here():
print("Welcome to the guessing game!")
play_game()
def play_game():
random_number = random.randrange(1, 100)
correct = False
user_guess = True
while not correct:
try:
user_guess = int(input("Enter your guess: "))
except ValueError:
print("Please only use integers")
if user_guess > 100 or user_guess < 1:
print("Please only enter numbers between 1 and 100!")
elif user_guess > random_number:
print("Too high, try again. ")
elif user_guess < random_number:
print("Too low, try again! ")
elif user_guess == random_number:
break
if user_guess == random_number:
replay = (input("Great! You guessed it! would you like to play again? y or n"))
if replay == "y":
start_here()
else:
print("See ya later!")
start_here()
Keep in mind that the code after the try-except block gets executed irrespective of whether an exception was thrown or not. If the except block gets invoked you want your code to skip through the rest of the statements in the while loop and continue at the next iteration of the loop, where the user is prompted for input again. This can be achieved by using the continue keyword in the except block like so:
try:
user_guess = int(input("Enter your guess: "))
except ValueError:
print("Please only use integers")
continue
The continue statement directs the interpreter to skip the remaining statements in the current iteration of the loop. The flow of control can then re-enter the loop or exit, depending on the loop condition.
Now that your code runs the way it is intended to, here is how you can make it more concise:
Firstly, there is a neat feature in Python which allows you to write conditions like not 1 <= user_guess <= 100. These conditions are much quicker to read, and you can replace this in your code.
Secondly, the start_here() function is redundant. You can easily replace play_game() in its place with a few modifications like so:
import random
def play_game():
print("Welcome to the guessing game!") #Modification here
random_number = random.randrange(1, 100)
correct = False
user_guess = True
while not correct:
try:
user_guess = int(input("Enter your guess: "))
except ValueError:
print("Please only use integers")
continue #Modification here
if not 1<=user_guess<=100: #Modification here
print("Please only enter numbers between 1 and 100!")
elif user_guess > random_number:
print("Too high, try again. ")
elif user_guess < random_number:
print("Too low, try again! ")
elif user_guess == random_number:
break
if user_guess == random_number:
replay = (input("Great! You guessed it! would you like to play again? y or n"))
if replay == "y":
play_game() #Modification here
else:
print("See ya later!")
play_game() #Modification here
or you could entirely replace the play_game() function with a while loop like so:
import random
replay = 'y' #Modification here
while replay == 'y': #Modification here
print("Welcome to the guessing game!")
random_number = random.randrange(1, 100)
correct = False
user_guess = True
while not correct:
try:
user_guess = int(input("Enter your guess: "))
except ValueError:
print("Please only use integers")
continue
if not 1<=user_guess<=100 :
print("Please only enter numbers between 1 and 100!")
elif user_guess > random_number:
print("Too high, try again. ")
elif user_guess < random_number:
print("Too low, try again! ")
elif user_guess == random_number:
break
if user_guess == random_number: #Modification here
replay = input("Great! You guessed it! would you like to play again? y or n")
print("See ya later!") #Modification here
Here:
while not correct:
try:
user_guess = int(input("Enter your guess: "))
except ValueError:
print("Please only use integers")
if user_guess > 100 or user_guess < 1:
# etc
If the user input is not a valid int, you display an error message but still proceed with testing the value against the random number. You should instead skip the rest of the loop, or extract the part getting the user input into it's own loop. As a general rule, one function should do only one thing, then you use another function to control the whole program's flow:
def get_num():
while True:
try:
user_guess = int(input("Enter your guess: ").strip())
except ValueError:
print("Please only use integers")
continue
if user_guess > 100 or user_guess < 1:
print("Please only enter numbers between 1 and 100!")
continue
return user_guess
def again():
replay = input("would you like to play again? y or n"))
return replay.strip().lower() == "y"
def play_game():
random_number = random.randrange(1, 100)
while True:
user_guess = get_num()
if user_guess > random_number:
print("Too high, try again. ")
elif user_guess < random_number:
print("Too low, try again! ")
else:
# if it's neither too high nor too low then it's equal...
break
# no need to test again, we can only get here when the user
# found the number
print("Great! You guessed it!")
def main():
print("Welcome to the guessing game!")
while True:
play_game()
if not again():
break
if __name__ == "__main__":
main()

Guessing game: matching user input with randomly generated number

def var (guess):
return guess
guess = int(input("Guess a number 1 through 10: "))
import random
num = (random.randint(1,10))
while True:
try:
guess = num
print("you guessed the right number!")
break
except:
print("try again")
break
So for this program I am trying to figure out how to have the user input a number and to guess what number (1 through 10) the program generated. It seems that every time I input a value it always gives me the "you guess the right number!" string even if I input a value higher than 10.
EDIT: Why would someone downvote my question o_o
You need to get user's input inside while loop so that user's input got updated with each iteration.
import random
num = (random.randint(1,10))
while True:
try:
guess = int(input("Guess a number 1 through 10: "))
if guess == num:
print("you guessed the right number!")
break
else:
print("try again")
except:
print('Invalid Input')
try/except is for exception handling, Not matching values. What you are looking for is if statments, For example:
guess = int(input("Guess a number 1 through 10: "))
import random
num = (random.randint(1,10))
if guess == num:
print("You guessed the right number!")
else:
print("Try again")
I think you may have intended to continue looping until the right number is guessed, In which case, This will work:
import random
num = (random.randint(1,10))
while True:
guess = int(input("Guess a number 1 through 10: "))
if guess == num:
print("You guessed the right number!")
break
else:
print("Try again")

Categories

Resources