'python calculating parsed logical expression (without eval)
I'm looking for the best way of calculating a string expression that holds a logical expression like: x and not y or (z or w) or a json logic like: {"and": {"x": "true", "y": "false"}, "or": {"or": {"z": "true", "w": "True"}}}
I decide how to config file should look like so the format could be changed, it's just an example.
I saw a way to parse the first string using pyparse to something like: ['x', 'AND', 'y', 'OR', ['z', 'OR', 'W']] but I don't know how to get the value of the expression after I parsed it.
About the json logic format I saw the package json-logic tried it but it seems like the code is broken since I can't run any of their examples so if there is something else I think that would be great.
x = True
y = False
z = False
w = False
calc_string_as_bool('x and not y or (z or w)') -> True
Thanks for the help.
Solution 1:[1]
It sounds to me like what you're after is eval, even though you say without eval.
In [1]: True and True
Out[1]: True
In [2]: e = "True and True"
In [3]: eval(e)
Out[3]: True
In [4]: el = ["True", "and", "True"]
In [5]: eval(" ".join(el))
Out[5]: True
Maybe you can clarify why using eval to do what eval does isn't an option.
Adding example, based on sample in question:
def eval_recurse(ops, replacements):
evaluated = []
for op in ops:
if type(op) is list:
evaluated.append(str(eval_recurse(op, replacements)))
continue
if str(op).lower() in ["and", "not", "or"]:
op = op.lower()
if op in replacements:
op = str(replacements[op])
evaluated.append(op)
return eval(" ".join(evaluated))
if __name__ == "__main__":
replacements = {"x": True, "y": False, "z": False, "w": False}
print(eval_recurse(["x", "AND", "NOT", "y", "OR", ["z", "OR", "w"]], replacements))
This yields True. This may not be helpful since you don't want to use eval, but I figured I'd provide it in case.
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 |
