I'm pretty new to Python, Lately I was working on user input validation with nested try/except. My code is as below:
def user_input():
try:
myinput = 0
myinput = float(input("Enter a numberic value:"))
if myinput > 10:
raise ValueError('Expect a number between 0 and 10')
#print(myinput)
return myinput
except:
print("something went wrong try again!")
user_input()
print(user_input())
Though it was almost working as expected, I noticed an issue. When I call this function and at the initial stage if I pass an acceptable input the function returns the correct numeric value.
But when I try to input a false value initially and subsequently passing the correct value, the function seems not returning the numeric value. I tried to print the return output inside the function, there I'm getting the expected value.
Thanks in Advance
Try return user_input() instead of user_input() in the except block.
Related
This question already has answers here:
Asking the user for input until they give a valid response
(22 answers)
Closed 2 years ago.
What is the best way of repeatedly asking for the user for correct input?
For example I'd like to continue checking if the a value is an int or not and when it is finally say ok you picked number.
I'm stuck here:
try:
a = int(input())
except:
print("incorrect pick a number and try again")
#Somewhere here
print("Ok thanks you finally picked a number")
The only exception you want to catch is the ValueError raised by int should it not be able to convert its argument to an integer. The try statement will be in a loop that you will explicitly break out of if you don't get an exception.
while True:
response = input()
try:
a = int(response)
except ValueError:
print("incorrect pick a number and try again")
else:
print("Ok thanks you finally picked a number")
break
if you want/must mantain this code, i think the unique way is using a loop.
while True:
try:
a = int(input('Insert a number:'))
print ('Your number is {}'.format(a))
break
except ValueError:
print("incorrect pick a number and try again")
So if the user inserts an integer, the code prints number and break the loop else repeats the request.
I hope it's useful for you!
You can do it like this:
a = None
while type(a) != int:
try:
a = int(input())
except:
print("incorrect pick a number and try again")
print("Ok thanks you finally picked a number")
Essentially:
Create a variable with NoneType so when you first run the program it can access the while loop because the conditions meats.
Loop until the type of that variable is not int.
Request the user input and try to cast as integer, if it fails print an error and try again.
When the input is of integer type it exit the loop and print the final message.
You can use type() or isinstance() to check, but as suggested by #chepner avoid the usage of type because it simply returns the type of an object whereas, isinstance() returns true if the object argument is an instance of the classinfo argument, or of a (direct, indirect or virtual) subclass thereof.
To help you understand:
class foo:
pass
class bar(foo):
pass
isinstance(foo(), foo) # returns True
type(foo()) == foo # returns True
isinstance(bar(), foo) # returns True
type(bar()) == foo # returns False,and this probably won't be what you want.
In the case you want to use isinstance() the code will result as:
a = None
while not isinstance(a, int):
try:
a = int(input())
except:
print("incorrect pick a number and try again")
print("Ok thanks you finally picked a number")
As pointed out by #L3viathan you can also do:
a = None
while a is None:
try:
a = int(input())
except:
print("incorrect pick a number and try again")
print("Ok thanks you finally picked a number")
In this case you loop until a get a value, that will be done only if the exception is not thrown.
while True:
try:
number=int(input("Enter a number: "))
except:
print("incorrect pick a number and try again")
else:
print("ok Thanks you finally picked a number ")
break
Write a program which gets an input from the user by asking 'Give me an input:',and passes this string to 'silly_function' if the function returns without an error.simply print whatever it returned. However: if the function produces a ValueError,the program should instead print'I cannot use this value'; if the function produces a TypeError,the program should instead print 'Invalid input'
def silly_function(a):
a = input('Give me an input')
try:
sily_function(a)
except ValueError:
print('I cannot see this value')[enter image description here][1]
Let's try this together.
Code Analysis
def silly_function(a):
a = input('Give me an input')
this is fine, it will prompt the user for an input**
try:
silly_function(a)
Why do you need to call silly_function again ? I don't think that was the intended behavior ?
Also silly_function doesn't do anything that will terminate the recursion or generate an error , so this is bound to break.
except ValueError:
print('I cannot see this value')[enter image description here][1]
Suppose this is a typo, but see != useand you are only handling one error and not the other one.
Suggestion
Let's right in pseudocode a bit of help
def error_handling_function(a):
a = input('Give me an input')
try:
silly_function(a)
except #input error here:
#handle error here
except #input error here:
#handle error here
def silly_function(a):
#write code that can break and generate the two error you are looking for
I'm having trouble with an IF statement resulting from when a button is clicked.
The code I have so far is below, basically what I need is once the button is pressed it asks the question 'Are you sure you want to update?' This works fine. The user then clicks yes or no. No closes the pop up box (working ok), if the user clicks yes then it checks to see if the entry is blank. If it is it keeps the original variable (working ok), it also checks to see if the entry is a float and if it isn't then return an error message, this brings back an error message even if it is a float, what I want it to do is if its a float then use the entered value which the else statement should do. but it keeps bringing back the messagebox error.
def updatetimings():
ask = messagebox.askquestion('Validation','Are you sure you want to update timings?')
if ask =='yes':
try:
a = newv5c.get()
if a == "":
e1 = v5c_timing
elif type(a) != float :
messagebox.showinfo('Error','Please enter decimal numbers only')
else:
e1 = a
except ValueError:
messagebox.showinfo('Error','Please enter decimal numbers only')
pass
Maybe Psuedocode may help:
BUTTON CLICKED:
QUESTION ASKED
NO CLOSES WINDOW
YES = IF ENTRY IS BLANK THEN USE OLD VARIABLE
OR ENTRY = FLOAT THEN USE NEW VARIABLE
IF ITS ANY OTHER TYPE THEN SHOW ERROR MESSAGEBOX ,'WRONG TYPE'
I've set the entry as a StringVar() if that is the problem.
Thanks
In their comment, hiro protagonist suggested that a might always be a str. I agree that this is probably the case (although I don't know for sure). This is one way to structure your code to use float() to parse a value out of a:
def updatetimings():
ask = messagebox.askquestion('Validation','Are you sure you want to update timings?')
if ask == 'yes':
a = newv5c.get()
if a == '':
e1 = v5c_timing
else:
try:
# Try parsing a as a float. If it works, store the result in e1.
e1 = float(a)
except ValueError:
# If we're not able to parse a as a float, then show an error message.
messagebox.showinfo('Error','Please enter decimal numbers only')
I hope this helps!
I am trying to test each input then return that the number is cleared then do the math. For Example is a user inputs N instead of a number I want it to output that its not a number whereas if the user inputs 1 then I want it to move to the next function asking for a power then do the same thing and if that passes then goes to the final section which output the answer to the problem.
The program passes both the errors for the non number areas yet when it get to very last function it is telling me base nor power are defined.
Code is written in some Python2 and some Python3. All works fine though. I use python3 mostly.
[Test Picture/Error Msg][1]
# Below we are creating the recursive statement to do the math for us. We are calling Base and Power
# from the main function where the user Inputs the numbers.
def pow(base, power):
if power == 0:
return 1
if power == 1:
return base
else :
return base * pow(base, power - 1)
def determineBase():
while True:
try:
base = int(input ('Please Enter A Base: '))
except ValueError:
print("Please use whole numbers only. Not text nor decimals.")
continue
else:
return base
def determinePower():
while True:
try:
power = int(input ('Please Enter A Power: '))
except ValueError:
print("Please use whole numbers only. Not text nor decimals.")
continue
else:
return power
def main():
determineBase()
determinePower()
pow(base,power)
print("The answer to",base,"to the power of", power,"is", pow(base,power),".")
main()
def main():
determineBase()
determinePower()
pow(base,power)
Here, neither base nor power are defined. What you meant instead was to store the result from those function calls and pass those then:
def main():
base = determineBase()
power = determinePower()
pow(base, power)
The issue isn't inside the recursive function, it's inside your main function.
The problem is arising due to the fact that you are passing base as an argument to the pow() function without defining the variable base first (the same would subsequently be true for power).
In other words you need something along the lines of:
def main():
base = determineBase()
power = determinePower()
pow(base,power) #this line could probably be removed
print("The answer to",base,"to the power of", power,"is", pow(base,power),".")
As currently, you're not storing the values of these two functions.
I am writing a code for the wind chill index for an assignment for college.
The prof wants us to prevent the code from crashing upon user input of blank or letters, without using Try/Except Blocks. (He refers to string methods only).
Instead of crashing it should out put an error message eg. ("invalid input, digits only")
I tried utilizing the string.isdigit and string.isnumeric, but it won't accept the negative degrees as integers.
Any suggestions? (code below)
Would another "if" statement work?
Replace the punctuation:
if temperature.replace('-','').replace('.','').isnumeric():
Use an infinite loop and check that everything seems right.
Whenever there's an error, use the continue statement. And when all checks and conversions are done, use the break statement.
import re
import sys
while True:
print("Temperature")
s = sys.stdin.readline().rstrip('\n')
if re.match("^-?[0-9]+(\\.[0-9]+)?$", s) is None:
print("Doesn't look like a number")
continue
if '.' in s:
print("Number will be truncated to integer.")
temp = int(float(s))
if not (-50 <= temp <= 5):
print("Out of range")
continue
break