How do I check if the user has entered a number? - python

I making a quiz program using Python 3. I'm trying to implement checks so that if the user enters a string, the console won't spit out errors. The code I've put in doesn't work, and I'm not sure how to go about fixing it.
import random
import operator
operation=[
(operator.add, "+"),
(operator.mul, "*"),
(operator.sub, "-")
]
num_of_q=10
score=0
name=input("What is your name? ")
class_num =input("Which class are you in? ")
print(name,", welcome to this maths test!")
for _ in range(num_of_q):
num1=random.randint(0,10)
num2=random.randint(1,10)
op,symbol=random.choice(operation)
print("What is",num1,symbol,num2,"?")
if int(input()) == op(num1, num2):
print("Correct")
score += 1
try:
val = int(input())
except ValueError:
print("That's not a number!")
else:
print("Incorrect")
if num_of_q==10:
print(name,"you got",score,"/",num_of_q)

You need to catch the exception already in the first if clause. For example:
for _ in range(num_of_q):
num1=random.randint(0,10)
num2=random.randint(1,10)
op,symbol=random.choice(operation)
print("What is",num1,symbol,num2,"?")
try:
outcome = int(input())
except ValueError:
print("That's not a number!")
else:
if outcome == op(num1, num2):
print("Correct")
score += 1
else:
print("Incorrect")
I've also removed the val = int(input()) clause - it seems to serve no purpose.
EDIT
If you want to give the user more than one chance to answer the question, you can embed the entire thing in a while loop:
for _ in range(num_of_q):
num1=random.randint(0,10)
num2=random.randint(1,10)
op,symbol=random.choice(operation)
while True:
print("What is",num1,symbol,num2,"?")
try:
outcome = int(input())
except ValueError:
print("That's not a number!")
else:
if outcome == op(num1, num2):
print("Correct")
score += 1
break
else:
print("Incorrect, please try again")
This will loop eternally until the right answer is given, but you could easily adapt this to keep a count as well to give the user a fixed number of trials.

Change
print("What is",num1,symbol,num2,"?")
if int(input()) == op(num1, num2):
to
print("What is",num1,symbol,num2,"?")
user_input = input()
if not user_input.isdigit():
print("Please input a number")
# Loop till you have correct input type
else:
# Carry on
The .isdigit() method for strings will check if the input is an integer.
This, however, will not work if the input is a float. For that the easiest test would be to attempt to convert it in a try/except block, ie.
user_input = input()
try:
user_input = float(user_input)
except ValueError:
print("Please input a number.")

Related

How do I correctly use isinstance() in my random number guessing game or is another function needed?

I want this number guessing game to be able to catch every possible exception or error the user enters. I've successfully prevented the use of strings when guessing the number, but I want the console to display a custom message when a float is entered saying something along the lines of "Only whole numbers between 1-20 are allowed". I realize my exception would work to catch this kind of error, but for learning purposes, I want to specifically handle if the user enters a float instead of an int. From what I could find online the isinstance() function seemed to be exactly what I was looking for. I tried applying it in a way that seemed logical, but when I try to run the code and enter a float when guessing the random number it just reverts to my generalized exception. I'm new to Python so if anyone is nice enough to assist I would also appreciate any criticism of my code. I tried making this without much help from the internet. Although it works for the most part I can't get over the feeling I'm being inefficient. I'm self-taught if that helps my case lol. Here's my source code, thanks:
import random
import sys
def getRandNum():
num = random.randint(1,20)
return num
def getGuess(stored_num, name, gameOn = True):
while True:
try:
user_answer = int(input("Hello " + name + " I'm thinking of a number between 1-20. Can you guess what number I'm thinking of"))
while gameOn:
if user_answer >= 21 or user_answer <=0:
print("That is not a number between 1-20. Try again.")
user_answer = int(input())
elif isinstance(user_answer, int) != True:
print("Only enter whole numbers. No decimals u cheater!")
user_answer = int(input())
elif user_answer > stored_num:
print("That guess is too high. Try again " + name + " !")
user_answer = int(input())
elif user_answer < stored_num:
print("That guess is too low. Try again " + name + " !")
user_answer = int(input())
elif user_answer == stored_num:
print("You are correct! You win " + name + " !")
break
except ValueError:
print("That was not a number, try again")
def startGame():
print("Whats Your name partner?")
name = input()
stored_num = getRandNum()
getGuess(stored_num, name)
def startProgram():
startGame()
startProgram()
while True:
answer = input("Would you like to play again? Type Y to continue.")
if answer.lower() == "y":
startProgram()
else:
break
quit()
The only thing that needs be in the try statement is the code that checks if the input can be converted to an int. You can start with a function whose only job is to prompt the user for a number until int(response) does, indeed, succeed without an exception.
def get_guess():
while True:
response = input("> ")
try:
return int(response)
except ValueError:
print("That was not a number, try again")
Once you have a valid int, then you can perform the range check to see if it is out of bounds, too low, too high, or equal.
# The former getGuess
def play_game(stored_num, name):
print(f"Hello {name}, I'm thinking of a number between 1-20.")
print("Can you guess what number I'm thinking of?")
while True:
user_answer = get_guess()
if user_answer >= 21 or user_answer <=0:
print("That is not a number between 1-20. Try again.")
elif user_answer > stored_num:
print(f"That guess is too high. Try again {name}!")
elif user_answer < stored_num:
print(f"That guess is too low. Try again {name}!")
else: # Equality is the only possibility left
print("You are correct! You win {name}!")
break

My python code does not run a print statement at the end of a loop

I have this problem when i run the program it all goes good an all, but when a user gets the right answer, the code does not print neither print("Good Job!") or print("Correct"). what is wrong with the code ?
import random
firstNumber = random.randint(1, 50)
secondNumber = random.randint(1, 50)
result = firstNumber + secondNumber
result = int(result)
print("Hello ! What\'s your name ? ")
name = input()
print("Hello !"+" "+ name)
print("Ok !"+" "+ name +" "+ "let\'s start !")
print("What is"+ " " + str(firstNumber) +"+"+ str(secondNumber))
userAnswer = int(input("Your answer : "))
while (userAnswer != result) :
if (userAnswer > result) :
print("Wrong")
else:
print("Wrong")
userAnswer = int(input("Your answer : "))
if (userAnswer == result):
print("Correct")
print("Good Job!")
break
input("\n\n Press to exit")
The problem is that your while-loop will only run as long as the first answer is wrong. Everything that is indented after while (userAnswer != result) will be ignored by Python if the first answer is right. So logically a first correct answer can never reach print("Correct"), since that would require the answer to be both wrong (to start the while loop) and right (to get to "Correct").
One option is to get rid of the while-loop, and just use if's. You get two chances this way, then you lose.
if (userAnswer == result):
print("Well done!")
else:
print("Wrong")
userAnswer = int(input("Your answer : "))
if (userAnswer == result):
print("Correct")
print("Good Job!")
else:
print("Nope all wrong you lose")
Another option is to make an infinite loop using While. (like #csharpcoder said)
while (True) :
userAnswer = int(input("Your answer : "))
if (userAnswer == result):
print("Correct")
print("Good Job!")
break
else:
print ("Wrong answer")
In the last option a wrong answer gets "Wrong answer" and the while-loop starts again, since True is of course still True. So you try again, until you get the right answer, which will bring you to "correct, good job" and then break (which stops the loop).
I struggled with while-loops and kind of getting it in my head that indentation means Python will treat it as 'one thing' and skip it all if I start it with something that's False.
If the answer is correct, then
while (userAnswer != result) :
will cause the loop contents to be skipped.
First of all, you get input outside of your loop and then don't do anything with it. If your answer is correct on the first try, you will get no output because userAnswer != result will be False immediately and your while loop won't run.
Some other points:
if (userAnswer > result) :
print("Wrong")
else:
print("Wrong")
is redundant because you are guaranteed to fall into one of these, as you will only get here if the answer is wrong (and therefore > or < result). Just print "Wrong" without a condition, as the only reason this would run is if the answer was wrong.
print("Correct")
print("Good Job!")
You can use \n to print on a new line instead of having multiple print statements together. Usually you only use multiple prints together for readability, but print("Correct\nGood job!") isn't that much less readable.
if (userAnswer == result):
#...
break
You don't need break here because the answer is already correct and the loop won't repeat anyway.
print("Hello !"+" "+ name)
print("Ok !"+" "+ name +" "+ "let\'s start !")
print("What is"+ " " + str(firstNumber) +"+"+ str(secondNumber))
Here, you append string literals to string literals ("Hello!" + " "). You don't need to do that as you can just write "Hello! ".
result = firstNumber + secondNumber
result = int(result)
The result (pun not intended) is already an integer, so you don't need to convert it.
How about using a infinite while loop something like this :
while (True) :
userAnswer = int(input("Your answer : "))
if (userAnswer == result):
print("Correct")
print("Good Job!")
break
else:
print ("Wrong answer")
In your logic if you enter the wrong answer first time and correct answer afterwards , then it will work as per your requirement , but if you enter the correct answer first time it will simple skip the while loop .
I played around a bit to refactor, in an attempt to make it more clear:
import random
name = input("Hello ! What's your name? ")
print("Hello, {name}!".format(name=name))
print("Ok, {name}, let's start!".format(name=name))
first_number = random.randint(1, 50)
second_number = random.randint(1, 50)
correct_answer = first_number + second_number
print("What is, '{first} + {second}'?".format(first=first_number,
second=second_number))
user_answer = None
while user_answer != correct_answer:
try:
user_answer = int(input("Your answer : ")) # ValueError will be raised if non integer value given
except ValueError:
print("Invalid Input!")
user_answer = None
if user_answer:
if user_answer == correct_answer:
print("Correct")
print("Good Job!")
else:
print('--> Wrong, try again!')
input("\n<< Press any key to exit >>")

Would like to know how to add some code to make my program be able to deal with letters being inputted

My program is a simple arithmetic quiz however i want to know how to make it so that it doesn't just stop when i don't enter in an integer.
questionNo=0
score=0
name=input("What is your name?")
print("Welcome ",name," to your arithmetic quiz!")
time.sleep(1)
while questionNo<10:
function=random.randint(1,3)
if function==1:
rNumber1=random.randint(1,100)
rNumber2=random.randint(1,100)
print("Question is : ", rNumber1," + ",rNumber2)
guess=int(input("What is the answer?"))
ans=rNumber1+rNumber2
if ans==guess:
print("Correct!")
score+=1
time.sleep(1)
else:
print("Wrong")
time.sleep(1)
elif function==2:
rNumber1=random.randint(1,10)
rNumber2=random.randint(1,10)
print("Question is : ", rNumber1," X ",rNumber2)
guess=int(input("What is the answer?"))
ans=rNumber1*rNumber2
if ans==guess:
print("Correct!")
score+=1
time.sleep(1)
else:
print("Wrong")
time.sleep(1)
else:
rNumber1=random.randint(1,100)
rNumber2=random.randint(1,100)
print("Question is : ", rNumber1," - ",rNumber2)
guess=int(input("What is the answer?"))
ans=rNumber1-rNumber2
if ans==guess:
print("Correct!")
score+=1
time.sleep(1)
else:
print("Wrong")
time.sleep(1)
questionNo+=1
print("Well done ",name,"! You got ",score,"/10")
Wrap your call to int(input()) in a try-except clause.
Trying to convert a value of type str to int will always raise a ValueError exception.
So, wherever you want to catch this illegal conversion, meaning, whenever int(input()) is called, wrap it in the try-except in order to handle it:
try:
guess = int(input("What is the answer?"))
except ValueError:
print("You must enter a number as the answer!")
continue
And don't increment the questionNo counter in the except clause in order to keep the same number of questions in total.

Python - Checking for an empty input + script troubles

I am very knew to Python, so as expected, I'm encountering problems often when scripting and am usually not sure how to fix them.
I'm making a small game where you try and guess a number which the program has randomly chosen. I've gotten pretty far, but I noticed the program simply displayed an error message when I input nothing. I would like the program to display the text "Enter a number." in this situation, and then prompt the "Your guess: " input again, but after a lot of research, I'm really not sure how to successfully implement that feature into my code. My issue, specifically, is the "try and except" section - I don't really know how to write them properly, but I saw another post on here suggesting to use them.
import random
def question():
print("Guess a number between 1 and 100.")
randomNumber = random.randint(1, 100)
found = False
while not found:
myNumber = int(input("Your guess: "), 10)
try:
myNumber = int(input("Your guess: "), 10)
except ValueError:
print("Enter a number.")
if myNumber == randomNumber:
print("Correct!")
found = True
elif myNumber > randomNumber:
print("Wrong, guess lower!")
else:
print("Wrong, guess higher!")
question()
You should be able to see my intentions in the code I've written, thanks.
You're almost right. Just continue to the next iteration after handling exception.
import random
def question():
print("Guess a number between 1 and 100.")
randomNumber = random.randint(1, 100)
found = False
while not found:
try:
myNumber = int(input("Your guess: "), 10)
except Exception:
print('Enter a number.')
continue
if myNumber == randomNumber:
print("Correct!")
found = True
elif myNumber > randomNumber:
print("Wrong, guess lower!")
else:
print("Wrong, guess higher!")
question()
You can write a function like this:
def input_num(input_string):
""" This function collects user input
Args:
input_string: message for user
Return:
user_input: returns user_input if it is a digit
"""
user_input = raw_input("{}: ".format(input_string))
if not user_input.isdigit():
input_num(input_string)
return int(user_input)
then call this function
user_num = input_num("Enter a number")
It will keep asking a user to provide a valid input until user puts one
I'm confused why you ask for the input twice. You only need to ask them for input once. After that, you need to add a continue to your except statement. Otherwise, it will not repeat and just end the program. This is what your modified while loop should look like.
while not found:
try:
myNumber = int(input("Your guess: "), 10)
except ValueError:
print("Enter a number.")
continue
if myNumber == randomNumber:
print("Correct!")
found = True
elif myNumber > randomNumber:
print("Wrong, guess lower!")
else:
print("Wrong, guess higher!")
Just use the continue keyword in your except to continue the loop.
except ValueError:
print('Enter a number')
continue

Could not convert string to float in input

#My code should take a random between 1 and 100 and let you guess it.
#This part works, but I want to add the posibility to reveal the number and then is when I get the error "could not convert string to float"
def reveal(guess):
return secret_number
import random
secret_number = random.random()*100
guess = float(input("Take a guess: ")) #This is the input
while secret_number != guess :
if guess < secret_number:
print("Higher...")
elif guess > secret_number:
print("Lower...")
guess = float(input("Take a guess: ")) #This input is here in order for the program not to print Higher or Lower without ever stopping
else:
print("\nYou guessed it! The number was " ,secret_number)
if guess == "reveal": #This is where I "tried" to make the reveal thingy.
print ("Number was", secret_number)
input("\n\n Press the enter key to exit")
Any help would be a great service. Also I am only programming for just a few weeks so sorry if my code looks wrong.
If you want to use float number to compare, the game may be endless because a float number has many fractional digits. Use int number.
#!/usr/bin/env python3.3
# coding: utf-8
import random
def guess_number():
try:
guess = int(input("Take a guess:"))
except ValueError:
print("Sorry, you should input a number")
guess = -1
return guess
if __name__ == '__main__':
secret_number = int(random.random() * 100)
while True:
guess = guess_number()
if guess == -1:
continue
elif guess < secret_number:
print("Lower...")
elif guess > secret_number:
print("Higher...")
else:
print("\nYou got it! The number was ", secret_number)
input("\n\nPress any key to exit.")
break # or 'import sys; sys.exit(0)'
import random
LOWEST = 1
HIGHEST = 100
def main():
print('Guess the secret number between {} and {}!'.format(LOWEST, HIGHEST))
secret = random.randint(LOWEST, HIGHEST)
tries = 0
while True:
guess = raw_input('Your guess: ').strip().lower()
if guess.isdigit():
tries += 1
guess = int(guess)
if guess < secret:
print('Higher!')
elif guess > secret:
print('Lower!')
else:
print('You got it in {} tries!'.format(tries))
break
elif guess == "reveal":
print('The secret number was {}'.format(secret))
break
else:
print('Please enter a number between {} and {}'.format(LOWEST, HIGHEST))
if __name__=="__main__":
main()
Use random.range instead of random.random.
secret_number = random.range(1,100,1)
And ...,str(secret_number)
...
else:
print("\nYou guessed it! The number was " ,str(secret_number))
if guess == "reveal": #This is where I "tried" to make the reveal thingy.
print ("Number was", str(secret_number))
...
That way you will be concatenating a string with a string. Also, you can keep random.random and only make the second change.
EDIT:
Another thing to do is to use raw_input instead of input. Then use try.
guess = raw_input("Take a guess: ")
try:
guess = float(guess)
except:
pass
This will try to convert guess into a float, and it that fails, then it will remain a string. That should solve your problem.
You could isolate concerns by defining a function that asks user for input until a float is provided:
def input_float(prompt):
while True:
try:
return float(input(prompt))
except ValueError:
print("You should input a float number. Try again.")
Then you could use it in your script:
guess = input_float("Take a guess: ")
If you want to accept 'reveal' as an input in addition to a float number:
def input_float_or_command(prompt, command='reveal'):
while True:
s = input(prompt)
if s == command:
return s
try:
return float(s)
except ValueError:
print("You should input a float number or %r. Try again." % command)

Categories