'Why do I get different results if I run this code inside main() versus without main()?

I have the following piece of code. If I just execute it (using IDLE Shell) without enclosing in main() I get different results then if I enclose it in main().

Example, if I run without main() and reply "a" to the first prompt and "b" to the second prompt, after the exec() instruction, name prints out changed from "a" to "b". But if I place the code in def main() the exec() instruction doesn't change name to "b", it remains as "a".

Here is the code:

def main():
    name = input("Enter variable name:")
    action = input ('enter action  ')
    print("printing name  ",name)
    print("printing action  ",action)
    print("Now using exec")
    exec("name=action")
    print("printing name  ",name)
    print("printing action", action)
     
main()

I want the user to enter the name of a variable in my program and then specify a new value for that variable.

I have tried key/value pair, but might have not done it correctly. I have tried locals()[name] = action.

I believe I have tried all the "dynamically set local variable" threads on this site and others. I must be missing something in those steps. What posted above is the closest I could get.



Solution 1:[1]

Well I believe I found a solution but it is pretty messy. I found "itemgetter" which will retrieve the value for a given key. I think that avoids the risk associated with exec() or other methods. But it requires me to type in all my names twice.

To expand my situation. I have, for example N+1 variables called names and N+1 values for the variables. In my present case, N is 12 but increasing as I add more items.

I create the dictionary:

vars={'name0': value0, name1:value1,......nameN:valueN}

Then, the user enters name and value (note in my first post I used action but using the term value aids understanding) and then:

vars[name]=value.

Then I move all the values into my variables:

name0=itemgetter('name0')(vars)
name1=itemgetter('name1')(vars)
.
.
.
nameN=itemgetter('nameN')(vars)

Thus I guess it works but it is messy to type the names once for the dictionary and again for setting the values to the names. Of course when I add a new name I have to remember add it in two places.

Any ideas for improvement?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 PeteC