0

I have the following code :

def Menu():
    try : choice = int(input("Enter your choice : "))
    except : 
        print('Invalid choice .')
        Menu()

    if choice>=6 or choice <=0: 
        print('Invalid choice .')
        Menu()
    else:print('OK')

if __name__ == '__main__':
    Menu()

When I enter a number between 1-5 , it print Ok . If I enter anything else , it reports invalid choice. Perfect till now . But when I have entered incorrect choice in the first attempt and try to enter correct choice on second attempt , it gives me this stupid error.

UnboundLocalError: local variable 'choice' referenced before assignment

What's wrong ? What is happening ? How am I messing such a simple code?

  • 1
    If you hit the exception, you don't assign anything to `choice`. – tdelaney May 07 '20 at 17:02
  • @tdelaney But I am entering the input . Why is it not being assigned ? – The Demonix _ Hermit May 07 '20 at 17:03
  • It doesn't give me any error. I entered incorrect choice on first attempt(8), then I entered 2 on the second attempt. It works perfectly! – 10 Rep May 07 '20 at 17:04
  • It is assigned in the inner Menu call, not the outer one, there are different ones – azro May 07 '20 at 17:04
  • Does this answer your question? [unboundlocalerror-on-local-variable-when-reassigned-after-first-use](https://stackoverflow.com/questions/370357). `choice` is no defined if the `except` occurs. Add a `return` after `Menu()` – stovfl May 07 '20 at 17:05
  • 1
    On invalid choice, you call `Menu()` again but its "choice" is a local variable that is destroyed when the inner function returns. You would need to return the choice in the inner function and then assign it to `choice` in the outer function for this to work. – tdelaney May 07 '20 at 17:06

1 Answers1

2

The problem is

  1. in first Menu call : enter
  2. in first Menu call : input a non-digit => Exception, nothing is assigned to choice
  3. in first Menu call : execute second Menu call
  4. in first Menu call : in second Menu : give correct input (1-5) else executed, end of method
  5. in first Menu call : come back, move to if/else : choice is not defined in the Menu call

DO never re-call a method inside itselt just do reset/restart its purpose, the way is to use a while loop

def Menu():
    choice = ''
    while not choice.isdigit() or not (0<int(choice)<6):
        choice = input("Enter your choice : ")

    print("Choice is ok", choice)
azro
  • 53,056
  • 7
  • 34
  • 70