Keith Sloan
Keith Sloan

Reputation: 145

Evaluation of strings

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

Answers (3)

TrebledJ
TrebledJ

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

Keith Sloan
Keith Sloan

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

Jonas Wolff
Jonas Wolff

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

Related Questions