April 12th, 2005, 09:49 AM
how can I get a string evaluated as I expected?
I get a line from a file like this:
cgbo = 1.0e-9
I want to know whether cgbo is equal to 0, so I do:
cgbo = re.sub(r'^.*=', '',line)
# do something here ...
But sometimes, the line looks like this:
cgbo = 1.0e-9*(160/(300+500))
eval(cgbo) will give 0 because (160/500) is 0 in python. But
I expect it is done in float and give me back 2.0e-10
How can I achieve this?
Thanks a lot for your ideas.
April 13th, 2005, 01:40 AM
It appends ".0" to all integers following an opening parenthesis of an expression, so everything within the parenthesis evaluates to float.
cgbo = re.sub("(?<=[(])(?P<int>\d+)(?=[)+*/-])", "\g<int>.0",
It requires that the expression does not contain whitespace. It's not fully tested, but it works for the example you provided.
Be careful with using the eval function. There are several threads in this forum dealing with this topic (search this forum for "eval(").
April 13th, 2005, 03:03 AM
Originally Posted by xbguan
If you need to use division, you should always use from __future__ import division as it forces "/" to return a float if necessary ("//" does integer division)
from __future__ import division
line = "cgbo = 1.0e-9*(160/(300+500))"
varnam, expression = line.split("=")
BTW, in Python, if you're using a regex and your expression to match is simple then there's probably a Pythonic non-regex way to do it...
April 13th, 2005, 03:13 AM
True. If the values were only numbers, he should just be using float(). The problem is that they can be full expressions. Really, he'd need to implement (or find and download) a parser for mathematical expressions to be safe...
Originally Posted by sbkwi
or (dare I say it) use a regex to verify...
he could probably just use the following though:
I don't _think_ that's exploitable (since the only letter it allows is "e") ...
for char in expression:
if char not in ("0123456789()/*+-.e"):
April 13th, 2005, 04:47 AM
Thank you hydroxide and sbkwi for your ideas.
I came up with an idea later yesterday which is very close to sbkwi's. I
didn't replace the integers with its float version. I replaced '/' with '*1.0/'.
But I likes 'from __future__ import division' better. I will go with it if I learned it earlier.