Reputation: 145
I have a string str1 = " 2*PI"
where PI is a global string PI = "1*pi"
If I perform eval(str1)
it tries to evaluate 1.*pi1.*pi
. How do I get it evaluate it as 2*(1*pi)
i.e 2 pi?
Upvotes: 0
Views: 296
Reputation: 8987
eval(str1)
returns 1.*pi1.*pi
because eval(str1)
evaluates to 2*"1*pi"
and multiplication between a string and an integer results in a repetition of the string.
Format the string directly into str1
instead.
from math import pi
PI = "1*pi"
str1 = f"2*({PI})" # or for versions < Python-3.6: "2*({})".format(PI)
print(str1) # '2*(1*pi)'
print(eval(str1)) # 6.283185307179586
If you're not in control of PI
, you can evaluate PI
first, then format it into the expression.
eval(f"2*({eval(PI)})") # or equivalently eval("2*({})".format(eval(PI)))
If you're not in control of str1
either, you can replace all PI
tokens with its literal string value: 1*pi
.
eval(str1.replace('PI', PI))
But this doesn't handle edge cases such as 2*PIE
(if they ever appear). A more robust solution would be use a regex and surround PI
with \b
characters to match a full token.
import re
eval(re.sub(r'\bPI\b', PI, str1))
This appropriately excludes strings such as 2*PIZZA
or 2*API
.
Upvotes: 3
Reputation: 145
Thanks evaluating first seems to have solved the problem.
So I now have
from math import pi
PI = eval("1*pi")
str1 = "2*PI"
eval(str1)
Which avoided any need for a replace
Upvotes: 1
Reputation: 2234
what if you evaluated - eval() - the PI string first and the inserted the evaluated in to str1 as a str through the str() command and then evaluated str1
from math import *
PI = "1*pi"
str1 = "2*PI"
PI = str(eval(PI)) # Turns our PI string into a number
str1 = str1.replace("PI",PI) # Sets our PI number in
print(eval(str1)) # Calculates it one last time
OUTPUT
6.283185307179586
Upvotes: 2