-1

I know this question has been asked quite few times here. Went through dozen of answers, but non of them are working for me. I am trying to re-run the main() when user input is == "y". What my code does, when the input is "y", it asks the same question again "try_again". Other checks are working correctly.

Could it be that the issue is within my main()? My code is below:

import sys


def play_again():
    '''
    Placeholder
    '''
    while True:
        try_again = input('Would you like to play again? (Y/N)\n')
        again = try_again.lower()
        if again not in ('y', 'n'):
            print("Invalid input.")
            play_again()
        if again == 'y':
            main()
        else:
            print("Goodbye")
            sys.exit()


def main():
    # all the code from the script


main()
play_again()
  • 1
    Please make a [mre]. A function can't be empty, though I'm assuming you've left out the meat of your code for the sake of example. If I put some dummy code, like `print('main!')` in `def main`, I can't reproduce the issue; it works perfectly fine for me. That said, using recursion here is not great; for better approaches, check out [Asking the user for input until they give a valid response](/q/23294658/4518341). BTW, check out [How to ask a good question](/help/how-to-ask) if you want more tips, and take the [tour] if you haven't already – wjandrea Jan 15 '23 at 00:41
  • Don't use recursion for this. You need to use a `while True:` loop, and if the user wants to exit, then you `break` the loop. – Tim Roberts Jan 15 '23 at 00:41

1 Answers1

2

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()
Grismar
  • 27,561
  • 4
  • 31
  • 54