2

I want to use eval to do operations to see if a and b equals c with some operator.

My code:

def Expression(a, b, c):
 operators = ["+", "-", "*", "/"]
 return len([i for i in operators if eval("a () b".replace("()", i)) == c]) >= 1
Expression(1, 2, 3)

For some reason, this results in a NameError. Error log:

return len([i for i in operators if eval("a () b".replace("()", i)) == c]) >= 1
 File "<string>", line 1, in <module>
NameError: name 'a' is not defined

Since the function has a as a parameter I don't believe a should be undefined. What is the problem here?

Mehrdad Pedramfar
11.1k4 gold badges43 silver badges61 bronze badges
asked Feb 13, 2019 at 12:31
1
  • Hi, welcome to Stack Overflow. eval is usually associated with risky operations, what you are missing though is likely using string interpolation you want the value of a not just a variable. Try '{} () {}'.format(a, b).replace....` Commented Feb 13, 2019 at 12:53

1 Answer 1

8

The problem is in that case eval try to find a and b in global scope, not function scop(it means that a and b is just valid in the function block). so you can pass the function current scope using locals() to eval like this:

def Expression(a, b, c):
 operators = ["+", "-", "*", "/"]
 scope = locals()
 return len([i for i in operators if eval("a () b".replace("()", i), scope) == c]) >= 1

Then your code will work.

for better understanding try to define a and b in the global scope, then you can see it works, like this:

a=1
b=2
def Expression(c):
 operators = ["+", "-", "*", "/"]
 return len([i for i in operators if eval("a () b".replace("()", i)) == c]) >= 1
Expression(3)

Also, you can pass a custom scope to eval by creating a dictionary and pass it to eval:

scope = {'a':a, 'b':b}

So, it was your code problem. but for the better attitude you can use what @Rakesh said before, Using formatted strings, it gets the current a and b and pass it to eval as what they have inside, like this:

eval(f"{a}{i}{b}") # <Python3.6 
eval("{}{}{}".format(a,i,b)) 

Also you can use any() instead of len() >= 1

answered Feb 13, 2019 at 12:54
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.