Python code seems to be ignoring ValueError - python

I want to handle possible ValueErrors resulting from invalid user input but I still get the red errors in the console instead of the program printing 'Invalid entry' as I intended. I'm not sure what's going wrong.
input_number = input("How many numbers would you like the program to calculate the average of?\n>> ")
try:
input_number = int(input_number)
except ValueError:
print("Invalid entry")
for i in range(input_number):
input("Please enter a whole number (%i/%i numbers entered):\n>> " % (i + 1, input_number))
It seems to ignore my try except statement as the error appears on the line of the for statement, saying "TypeError: 'str' object cannot be interpreted as an integer". It still doesn't work even if I amend the except to be "except ValueError or TypeError".

The problem is that when you catch the ValueError, you don't do anything to fix input_number (i.e. make it an int), so the program continues past your try statement and into your range() call, which proceeds to raise another exception because input_number isn't an int.
Simply catching an exception doesn't fix the error that caused it to be raised in the first place. If you catch an exception, you need to understand why it raised, and do something appropriate to correct the situation; blindly catching an exception will often just lead to another error later in your program, as it did here.
One way to correct this situation is to prompt the user again:
while True:
try:
input_number = int(input(
"How many numbers would you like the program to calculate the average of?\n>> "
))
break
except ValueError:
print("Invalid entry")
With the above code, the loop continues until input_number is an int.
Since it looks like you'll be wanting to do this again, I'd suggest putting it in a function:
def input_number(prompt: str) -> int:
"""Prompt for a number until a valid int can be returned."""
while True:
try:
return int(input(prompt))
except ValueError:
print("Invalid entry")
n = input_number(
"How many numbers would you like the program to calculate the average of?\n>> "
)
numbers = [
input_number(f"Please enter a whole number ({i}/{n} numbers entered):\n>>")
for i in range(1, n+1)
]
print(f"Average: {sum(numbers)/len(numbers)}")
How many numbers would you like the program to calculate the average of?
>> I don't know
Invalid entry
How many numbers would you like the program to calculate the average of?
>> 4
Please enter a whole number (1/4 numbers entered):
>>5
Please enter a whole number (2/4 numbers entered):
>>42
Please enter a whole number (3/4 numbers entered):
>>???
Invalid entry
Please enter a whole number (3/4 numbers entered):
>>543
Please enter a whole number (4/4 numbers entered):
>>0
Average: 147.5

The clause should be
except (ValueError, TypeError):
...

Related

Calculate Long String Of Input [duplicate]

I am just starting to learn Python and am trying to handle errors a user might input. All the program does is use the math module, asks the user for an integer and returns the factorial of the number.
I am trying to catch errors for negative numbers, floats and text.
If I enter an integer the code runs like it should.
When I enter a wrong value, like -9 or apple, the try/except seems to not catch the error and I get the traceback information. The user shouldn't see this.
Any suggestions or pointers?
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
# max value is 2147483647
#if __name__ == '__main__':
try:
num = input("Enter a number: ")
except OverflowError:
print("Input cannot exceed 2147483647")
except ValueError:
print("Please enter a non-negative whole number")
except NameError:
print("Must be an integer")
else:
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
I am using Python 3.10 on a Windows 10 Pro (64-bit) PC if that matters.
Norman
Your code is missing the operation which can cause the exception: in fact, input('...') returns a string representing whatever user inputs. This means that your num variable is a string (you can check by printing type(num).
You have to try to cast it into an integer:
try:
num = int(input('...'))
except ValueError:
print('invalid input')
Be carefull: if user input the value "-3", it will be accepted: the string will be cast into the integer -3 and this is correct.
If user inputs words like 'apple' or floats like 3.14, the exception raised is ValueError.
My suggest is to do something like this:
try:
num = int(input('...'))
if num >= 0:
# computing factorial
else:
print('error: only positive numbers will be accepted')
return
except ValueError:
print('invalid input')
That is because input() do not raise an error just because you want just a number. You have to check the type of input by yourself and then also raise an error by yourself.
e.g.
if not isinstance("string", int):
raise ValueError
edit: also have a look here for more information about input(): https://www.python-kurs.eu/python3_eingabe.php
It always returns a string, so you have to convert your input actively in the type you want and make your type check during/after the conversion
I took the path yondaime offered and got pretty close to what I wanted. The final result is below.
I thank all of you for your comments. The last time I did anything even slightly like programming was in Fortran on punch cards on an IBM 360.
I apologize for asking such basic questions but really am trying.
The code that works but really doesn't point out exactly which fault happened. I will try to figure out how to convert the string in the input statement to a float and see if there is a remainder (modulo maybe?) so the user gets a better hint what was wrong.
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
try:
num = int(input('Enter a positive whole number: '))
if (num >= 0 and num <= 2147483647):
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
else:
print('Number must be between 0 and 2147483647 are allowed.')
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
except ValueError:
print('Text or decimal numbers are not allowed. Please enter a whole number between 0 and 2147483647')
I have a lot time to learn because I'm bored in retirement ...
Norman

Python beginner help input error handling

I am just starting to learn Python and am trying to handle errors a user might input. All the program does is use the math module, asks the user for an integer and returns the factorial of the number.
I am trying to catch errors for negative numbers, floats and text.
If I enter an integer the code runs like it should.
When I enter a wrong value, like -9 or apple, the try/except seems to not catch the error and I get the traceback information. The user shouldn't see this.
Any suggestions or pointers?
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
# max value is 2147483647
#if __name__ == '__main__':
try:
num = input("Enter a number: ")
except OverflowError:
print("Input cannot exceed 2147483647")
except ValueError:
print("Please enter a non-negative whole number")
except NameError:
print("Must be an integer")
else:
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
I am using Python 3.10 on a Windows 10 Pro (64-bit) PC if that matters.
Norman
Your code is missing the operation which can cause the exception: in fact, input('...') returns a string representing whatever user inputs. This means that your num variable is a string (you can check by printing type(num).
You have to try to cast it into an integer:
try:
num = int(input('...'))
except ValueError:
print('invalid input')
Be carefull: if user input the value "-3", it will be accepted: the string will be cast into the integer -3 and this is correct.
If user inputs words like 'apple' or floats like 3.14, the exception raised is ValueError.
My suggest is to do something like this:
try:
num = int(input('...'))
if num >= 0:
# computing factorial
else:
print('error: only positive numbers will be accepted')
return
except ValueError:
print('invalid input')
That is because input() do not raise an error just because you want just a number. You have to check the type of input by yourself and then also raise an error by yourself.
e.g.
if not isinstance("string", int):
raise ValueError
edit: also have a look here for more information about input(): https://www.python-kurs.eu/python3_eingabe.php
It always returns a string, so you have to convert your input actively in the type you want and make your type check during/after the conversion
I took the path yondaime offered and got pretty close to what I wanted. The final result is below.
I thank all of you for your comments. The last time I did anything even slightly like programming was in Fortran on punch cards on an IBM 360.
I apologize for asking such basic questions but really am trying.
The code that works but really doesn't point out exactly which fault happened. I will try to figure out how to convert the string in the input statement to a float and see if there is a remainder (modulo maybe?) so the user gets a better hint what was wrong.
import math
from datetime import datetime
import time
num = 0
start = 0
end = 0
try:
num = int(input('Enter a positive whole number: '))
if (num >= 0 and num <= 2147483647):
start = datetime.now()
print("The factorial of ", num, " is : ")
print(math.factorial(int(num)))
end = datetime.now()
else:
print('Number must be between 0 and 2147483647 are allowed.')
print(f"Time taken in (hh:mm:ss.ms) is {end - start}")
except ValueError:
print('Text or decimal numbers are not allowed. Please enter a whole number between 0 and 2147483647')
I have a lot time to learn because I'm bored in retirement ...
Norman

Responding to errors in python

I am new to python and have faced this issue. What this program does is ask the user his or her age. The age has to be a number or else it will return a value error. I have used the try/except method to respond to the error, but i also want it so that the age the user enters is below a specific value(eg 200).
while True:
try:
age=int(input('Please enter your age in years'))
break
except ValueError:
print ('\n\n\n\nThat\'s not a valid Number.\nPlease try Again.\n\n\n\n')
except:
if age>=200:
print ('\n\n\n\nThat\'s not a valid Number.\nPlease try Again.\n\n\n\n')
print (f'Your age is {age}')
I tried this and a bunch of other stuff. Can anyone help?
You first need to check if value entered is an integer, do this in try clause.
You then need to check if the value is within the range, do this in the else clause which only gets executed if the try block is successful.
Break out if the value is within the range.
Below code shows this.
while True:
try:
age=int(input('Please enter your age in years'))
except ValueError:
print ('\n\n\n\nThat\'s not a valid Number.\nPlease try Again.\n\n\n\n')
else:
if age>=200:
print ('\n\n\n\nThat\'s not a valid Number.\nPlease try Again.\n\n\n\n')
else:
break
print (f'Your age is {age}')
A possible solution:
while True:
age_input = input("Please enter your age in years: ")
# Check both if the string is an integer, and if the age is below 200.
if age_input.isdigit() and int(age_input) < 200:
print("Your age is {}".format(age_input))
break
# If reach here, it means that the above if statement evaluated to False.
print ("That's not a valid Number.\nPlease try Again.")
You don't need to do exception handling in this case.
isdigit() is a method of a String object that tells you if the given String contains only digits.
You can do an if statement right after the input(), still keeping the except ValueError, example:
while True:
try:
age=int(input('Please enter your age in years'))
if age < 200:
# age is valid, so we can break the loop
break
else:
# age is not valid, print error, and continue the loop
print('\n\n\n\nThat\'s not a valid Number.\nPlease try Again.\n\n\n\n')
except ValueError:
print('\n\n\n\nThat\'s not a valid Number.\nPlease try Again.\n\n\n\n')

Python data type validation integer

Hello I am creating a registration program and need to ask the user to input their age . However I want to make sure its not a letter by just consisting of numbers. How do I limit the user to only getting a number and if they input other character a error message shows up
while True:
age = int(input("Age: "))
if not (age) != int:
print ("Not a valid age")
continue
else:
break
You can use try and except statements here.
try:
age=int(age) #Do not typecast the age variable before this line
except ValueError:
print("Enter number")
If you do not want the program to proceed until the user enters a number, you can use a flag variable and put the code block mentioned above in a while loop.

Python input string error (don't want to use raw_input) [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I have a menu that asks for the user to pick one of the options. Since this menu is from 1 to 10, I'm using input besides raw_input.
My code as an if statement that if the number the user inputs is from 1 to 10 it does the option. If the user inputs any number besides that ones, the else statement says to the user pick a number from 1 to 10.
The problem is if the user types an string, lets say for example qwert. It gives me an error because its an string. I understand why and I don want to use raw_input.
What can I do to wen the user types a string it goes to my else statement and print for example "Only numbers are valid. Pick a number from 1 to 10"
I don't want to use any advanced programing to do this
Regards,
Favolas
EDIT
Thanks for all your answers and sorry for the late response but I had some health problems.
I couldn't use try or except because my teacher didn't allow it.
In the end, I've used raw_input because it was the simplest alternative but was glad to see that are many ways to solve this problem.
Regards,
Favolas
You can throw an exception when you try to convert your string into a number.
Example:
try:
int(myres)
except:
print "Only numbers are valid"
You should use raw_input(), even if you don't want to :) This will always give you a string. You can then use code like
s = raw_input()
try:
choice = int(s)
except ValueError:
# choice is invalid...
to try to convert to an int.
Im not sure what you consider advanced - a simple way to do it would be with something like this.
def getUserInput():
while True:
a = raw_input("Enter a number between 1 and 10: ")
try:
number = int(a)
if (0 < number <= 10):
return number
else:
print "Between 1 and 10 please"
except:
print "Im sorry, please enter a number between 1 and 10"
Here, I have used try/except statements, to ensure that the entered string can be converted to an integer. And a loop (which will keep running) until the entered number is between 1 and 10 (0< number <=10)
What you really are after is how to figure out if something could pass as an integer. The following would do the job:
try:
i = int(string_from_input)
ecxept ValueError:
# actions in case the input is anything other than int, like continuing the loop
You clearly have something against exception handling. I don't understand why -- it's a fundamental part of (not just Python) programming and something you should be comfortable with. It's no more 'advanced' than handling error codes, just a different mentality.
Here are the docs. It's pretty simple:
It is possible to write programs that
handle selected exceptions. Look at
the following example, which asks the
user for input until a valid integer
has been entered, but allows the user
to interrupt the program (using
Control-C or whatever the operating
system supports); note that a
user-generated interruption is
signalled by raising the
KeyboardInterrupt exception.
>>> while True:
... try:
... x = int(raw_input("Please enter a number: "))
... break
... except ValueError:
... print "Oops! That was no valid number. Try again..."
...
The try statement works as follows.
First, the try clause (the
statement(s) between the try and
except keywords) is executed. If no
exception occurs, the except clause is
skipped and execution of the try
statement is finished. If an exception
occurs during execution of the try
clause, the rest of the clause is
skipped. Then if its type matches the
exception named after the except
keyword, the except clause is
executed, and then execution continues
after the try statement. If an
exception occurs which does not match
the exception named in the except
clause, it is passed on to outer try
statements; if no handler is found, it
is an unhandled exception and
execution stops with a message as
shown above. A try statement may have
more than one except clause, to
specify handlers for different
exceptions. At most one handler will
be executed. Handlers only handle
exceptions that occur in the
corresponding try clause, not in other
handlers of the same try statement. An
except clause may name multiple
exceptions as a parenthesized tuple,
for example:
... except (RuntimeError, TypeError, NameError):
... pass
The last except clause may omit the
exception name(s), to serve as a
wildcard. Use this with extreme
caution, since it is easy to mask a
real programming error in this way! It
can also be used to print an error
message and then re-raise the
exception (allowing a caller to handle
the exception as well):
Personally, I liked my first answer better. However, this one should fit your requirements with more code.
import sys
def get_number(a, z):
if a > z:
a, z = z, a
while True:
line = get_line('Please enter a number: ')
if line is None:
sys.exit()
if line:
number = str_to_int(line)
if number is None:
print('You must enter base 10 digits.')
elif a <= number <= z:
return number
else:
print('Your number must be in this range:', a, '-', z)
else:
print('You must enter a number.')
def get_line(prompt):
sys.stdout.write(prompt)
sys.stdout.flush()
line = sys.stdin.readline()
if line:
return line[:-1]
def str_to_int(string):
zero = ord('0')
integer = 0
for character in string:
if '0' <= character <= '9':
integer *= 10
integer += ord(character) - zero
else:
return
return integer
May I recommend using this function in Python 3.1? The two arguments are the expected number range.
def get_number(a, z):
if a > z:
a, z = z, a
while True:
try:
line = input('Please enter a number: ')
except EOFError:
raise SystemExit()
else:
if line:
try:
number = int(line)
assert a <= number <= z
except ValueError:
print('You must enter base 10 digits.')
except AssertionError:
print('Your number must be in this range:', a, '-', z)
else:
return number
else:
print('You must enter a number.')

Categories

Resources