Search code examples
pythonfunctionif-statementreturn

Unable to get return values when in if-elif-else python


I'm trying this on a larger piece of code, however to cut it short and simple, this is what I'm trying to do:

  1. To make a TUI based Menu (Like Switch case)
  2. Access functions from it, which return value
  3. Those values being passed into another options of menu

Code:

def menu():  
    ch = int(input('Choice:'))  
    a, b = 1, 1
    # li = ['', '']

    if ch is 1:
        a = 11
        # li[0] = a
        menu()
    elif ch is 2:
        b = 22
        print(a+b)
        # print(li[0]+b)
        menu()
    else:
        print('End')

menu()

When executed:

Choice:1
Choice:2
23
Choice:3
End

Expectation:

Choice:1   # Expecting a = 11
Choice:2   # Expecting 11 + 22
33         # Result to be 33
Choice:3
End

Now, I do understand that is just modifying the local copy of variable. In what way can I get the value to carry forward?

I'm assuming the 11 is value in return from some function written and the second condition is taking the value as parameter for further computation.

I tried this code with a List, however not successful with that. You can check the comments in code.

Not, just with if - else, I went after exec() function to execute, but that just was a bizarre idea.

Any other way is also appreciable.


Solution

  • Each call to menu() produces a new, separate local scope, with the variables in that scope independent from other calls to menu(). Changes in one call do not affect the local values in other calls, even recursive ones. So when you call menu(), the new function call starts at the top, and the line a, b = 1, 1 is executed and new, local variables a and b are created, both set to 1.

    Don't use recursion. Use a while loop, and break or return to exit the loop when you are done:

    def menu():  
        # set the initial values for a and b before starting the loop
        a, b = 1, 1
        while True:
            ch = int(input('Choice:'))  
    
            if ch == 1:
                a = 11
    
            elif ch == 2:
                b = 22
                print(a+b)
    
            else:
                print('End')
                # exit the function, and thus also exit the loop
                return
    

    Demo:

    >>> menu()
    Choice:1
    Choice:2
    33
    Choice:2
    33
    Choice:4
    End
    

    Recursion is never a good idea for menus anyway; function calls cause the current function state to be pushed on top of a stack, to be retrieved later when the function call returns. That stack has a limited amount of space; too many in-progress function calls and you'll get a runtime error. And you'd be surprised how often users will push a computer menu to those limits.

    You could of course pass along the current values of a and b to another function by passing them along as function parameters, and you could return new state back to the caller with return. But it's so much easier to use an endless loop, and that way you don't have to think about having to pass along your program state each time you want to ask the user for the next input.

    Note: Do not use is to test for value equality, use ==. is tests for identity, if both expressions reference the same object, not just if two objects have the same value. ch is 1 and ch is 2 only happens to work in CPython because you hit upon an implementation detail of the interpreter.