The context: I am using the function get_quantity_input()
to get user input and validate that it is an integer.
The problem: When I enter an invalid non-integer value (e.g. q) and subsequently enter a valid integer value (e.g. 2) the function returns the default value of -69. This is puzzling and only gets more puzzling when you inspect the output. I am sure there is something basic that I am misunderstanding. Any insights are greatly appreciated!
The functions:
def player_characters():
pc_list = ['Dennis Le Menace', 'Pierre', 'Ronan', 'Dame Romaine']
pcs = []
for pc in pc_list:
pc_init = get_quantity_input('{} initiative: '.format(pc))
print(pc, pc_init)
pc_dex_bonus = get_dex_bonus(pc)
pcs.append(Character(pc, pc_init, pc_dex_bonus))
return pcs
def get_quantity_input(something):
num_of_something = -69
try:
num_of_something = int(input(something))
print('inside try', num_of_something)
except ValueError:
print('Invalid input, please enter a number.')
get_quantity_input(something)
print('before return', num_of_something)
return num_of_something
The output:
Dennis Le Menace initiative: q
Invalid input, please enter a number.
Dennis Le Menace initiative: 3
inside try 3
before return 3 <-- why does this not get returned?!
before return -69
Dennis Le Menace -69
Pierre initiative: 12
inside try 12
before return 12
Pierre 12
CodePudding user response:
You need to return
the result of your recursive call rather than just "falling through":
def get_quantity_input(something):
num_of_something = -69
try:
num_of_something = int(input(something))
print('inside try', num_of_something)
except ValueError:
print('Invalid input, please enter a number.')
return get_quantity_input(something) # <-- here
print('before return', num_of_something)
return num_of_something
I'd recommend simplifying the function down a bit by not declaring a default value that you never want to actually return -- as you have observed, this makes it easier to have mysterious bugs. If you want to do it recursively (which is not actually recommended) it would be more simply written as:
def get_quantity_input(something):
try:
return int(input(something))
except ValueError:
print('Invalid input, please enter a number.')
return get_quantity_input(something)
If the try
block succeeds, the function is done and the value is returned; if not, we just try the same thing again.
Because Python doesn't optimize recursion the way many languages do, using recursion for a loop is not recommended. (Specifically: most languages can do "tail call optimization" to handle arbitrarily deep recursion, provided that the result of the recursive call is to be returned immediately, by popping the stack before actually making the next recursive call, whereas Python will continue growing the stack and eventually raise an exception once it gets too deep.) Instead use while
:
def get_quantity_input(something):
while True:
try:
return int(input(something))
except ValueError:
print('Invalid input, please enter a number.')