0

I want to use "exec" to compress many lines of code. But since the project I am working on is somewhat complex, I will simplify my code.

Let's suppose I want to make a function that will add me 3 numbers, one could easily write:

def sum3(a,b,c):
    return a+b+c

But since the project I'm working on involves many more variables and more dynamic code, let's say we want that function to use "exec". My attempt to use it was as follows:

def suma_eval(a,b,c):
    suma=0
        for item in ("a","b","c"):
        exec(f'''suma+={item}''')
        print(f"""suma+={item}""")
    return suma

Screenshot #1

It doesn't work. What did I do wrong?

UPDATE #1:

I already put it in a line as you indicated, the error stopped, but the result is a 0, when it should be 73. That is, the function is not working as expected.

Screenshot #2

UPDATE #2:

My problema has been solved, thank you so much, this is the answer:

def suma_eval(a,b,c):
    suma=0
    ldict={}
    for item in ("a","b","c"):
        exec(f'''suma+={item}''',locals(),ldict)
        suma=ldict["suma"]
    return suma
FARS
  • 1
  • 2
  • In the screenshot, you have `suma+={item}` in a separate line. When using triple quotes, whitespace is kept as-is in the string, so there are spaces before the line, that cause the error – Pietro Mar 18 '21 at 00:23
  • I already put it in a line as you indicated, the error stopped, but the result is a zero, when it should be 73. That is, the function is not working as expected. – FARS Mar 18 '21 at 00:37
  • You *cannot dynamically modify local namespaces in python*. Have you read the documentation for `exec`? Why are you even using `exec` here to begin with? – juanpa.arrivillaga Mar 18 '21 at 01:41

2 Answers2

0

Because your code after this line: for item in ("a","b","c"): doesn't have an indent.

Tkinter Lover
  • 835
  • 3
  • 19
-1

As pointed out in the comments,if you only need to sum the elements you can use sum:

values = [1, 2, 3, 4, 5]
sum(values)

If you need more complex behaviours, you can look into map, reduce and filter. Reduce allows you to apply any function cumulatively to all the items in an iterable, and generate a single final value.

import functools

def customfunc(a, b):
    partial_result = a ** 2 - b
    print(f"{a} {b} -> {partial_result}")
    return partial_result

functools.reduce(customfunc, values)

# prints:
# 1 2 -> -1
# -1 3 -> -2
# -2 4 -> 0
# 0 5 -> -5
Pietro
  • 1,090
  • 2
  • 9
  • 15
  • I know those tools, but I strictly want to use "exec" (or some other similar function like "compile") to execute lines of code dynamically. It would be enough for me if the stated problem is solved for me to implement it in my project. – FARS Mar 18 '21 at 00:35
  • Why on earth would you use `reduce` instead of `sum` – juanpa.arrivillaga Mar 18 '21 at 01:43
  • @juanpa.arrivillaga If sum is the operation you want, that would be the optimal solution, I agree. Reduce allows you to apply any custom function cumulatively to all the items in an iterable, and generate a single final value. I have updated the answer to highlight this. – Pietro Mar 18 '21 at 10:21