When the except block handles an exception, the factorial
function does not explicitly return a value, so the function returns None
. Then, the None
is passed to the print function. It is as though the code is written like this:
result = factorial("xyz") # result is None
print(result) # this is where "None" is printed
I think the best way to solve this is to separate parsing the number from the factorial function:
def factorial(number):
""" This function will calculate the factorial (N!) of a number """
output = "null"
if number > 0:
return number * factorial(number - 1)
elif number == 0:
return 1
else:
return output
try:
# first, parse the input
number = int("xyz")
# Now that `number` is guaranteed to be an integer, pass it
# to the factorial function.
print(factorial(number))
except:
# If the input was not an integer, this is where the
# exception is handled. The print function was not called
# in the try block, so there is no extra "None" in the output
print("Error, please ensure you are inputting a integer.")
This works, but the factorial
function now sometimes returns a number and sometimes returns the string "null". It would be better if it either returned a number, or it threw an exception. We can raise a ValueError if the user provides a negative number:
def factorial(number):
""" This function will calculate the factorial (N!) of a number """
if number > 0:
return number * factorial(number - 1)
elif number == 0:
return 1
else:
raise ValueError("Number must not be negative")
def parse_and_compute_factorial(input):
try:
# first, parse the input
number = int(input)
except ValueError:
print("Error, please ensure you are inputting a integer.")
return
try:
print(factorial(number))
except ValueError as err:
print(err)
parse_and_compute_factorial("xyz") # prints "Error, please ensure you are inputting a integer"
parse_and_compute_factorial("-5") # prints "Number must not be negative"
parse_and_compute_factorial("5") # prints "120"