You're treating a function call like a 'go to' statement, but that's not how it works.
When you call a function in Python, the program remembers where the execution was at when the function was called, and then it jumps to the start of the function (creating a local scope for the function, which has the parameters you passed to it in it already, just like regular variables).
The function runs and when it terminates, or executes a return
statement, it goes back to where the function was called, and continues execution from there. If a return value was provided, you can capture that by assigning it to a variable, like x = f()
.
A function terminates without return
when it reaches the end of the function's main body, but that's effectively the same as putting a return None
at the end.
In your code, you call main()
when you want to get back to the main
function, but you probably want return
instead. You call play_again()
again to restart the function, but that's not needed because you're already inside a while True
loop, which you can exit with a break
. And calling it again, will just cause the code to return to where you called it again later - which is not what you want.
So, your code should be something like:
def play_again():
while True:
try_again = input('Would you like to play again? (Y/N)\n')
# no need to introduce more variables, could even do this in one line
try_again = try_again.lower()
if try_again not in ('y', 'n'):
print("Invalid input.")
elif again == 'y':
continue # not needed, but causes the loop start again immediately
else:
print("Goodbye")
break
# no exit required, that quits the entire script, not the function
def main():
# all the code from the script
play_again()