----- Original Message -----
From: "Carl Banks" <[EMAIL PROTECTED]>
Newsgroups: comp.lang.python
To: <python-list@python.org>
Sent: Saturday, September 02, 2006 6:33 AM
Subject: Re: Using eval with substitutions


> [EMAIL PROTECTED] wrote:
> > >>> a,b=3,4
> > >>> x="a+b"
...
 > Careful.  Here be dragons.
...
> However, this is just a big potentially dangerous hack.  It's probably
...

> Carl Banks

-----------------------

Dragons indeed!
      To wit, I did get carried away a little with my suggestions and derived a 
class Formlua_Expander from SE. A few hours later it
worked just beautifully:

>>> FE = FORMEX.Formula_Expander ()
>>> FE.define ('l=102.8')
>>> FE.define ('d=8.5')
>>> FE.define ('pi=3.14159')
>>> FE.define ('r=d/2')
>>> FE.define ('section=r*r*pi')
>>> FE.define ('pipe_volume=l*section')
>>> FE ('pipe_volume')
5833.3828517499996
>>> FE.expand ('pipe_volume')
'((102.8)*(((8.5)/2)*((8.5)/2)*(3.14159)))'

The expansion cascade:

Data Chain
----------------------------------------------------------------------------------
  pipe_volume
0 
--------------------------------------------------------------------------------
  (l*section)
1 
--------------------------------------------------------------------------------
  (l*(r*r*pi))
2 
--------------------------------------------------------------------------------
  (l*((d/2)*(d/2)*pi))
3 
--------------------------------------------------------------------------------
  ((102.8)*(((8.5)/2)*((8.5)/2)*(3.14159)))
----------------------------------------------------------------------------------

Wonderful! Some more:

>>> FE.define ('m_per_foot=0.3048')
>>> FE.define ('pipe_volume_metric=pipe_volume*m_per_foot')
>>> FE ('pipe_volume_metric')

Traceback (most recent call last):
  File "<pyshell#199>", line 1, in -toplevel-
    FE ('pipe_volume_metric')
  File "c:\i\sony\fre\src\python\FORMEX.py", line 175, in __call__
    try: return eval (expression)
  File "<string>", line 1
    (((102.8)*(((8.5)/2)*((8.5)/2)*(3.14159)))*m_pe((8.5)/2)_foot(102.8)e)
                                                                ^
Oops!

>>> FE.show (1)
...
(1st pass) ...
    1: |pipe_volume_metric|->|(pipe_volume*m_per_foot)|
(2nd pass) ...
    1: |pipe_volume|->|(l*section)|
(3rd pass) ...
    1: |section|->|(r*r*pi)|
(4th pass) ...
    1: |r|->|(d/2)|
(5th pass) ...
    1: |d|->|(8.5)|
    2: |l|->|(102.8)|
    3: |m_per_foot|->|(0.3048)|
    4: |pi|->|(3.14159)|

Data Chain
----------------------------------------------------------------------------------
  pipe_volume_metric
0 
--------------------------------------------------------------------------------
  (pipe_volume*m_per_foot)
1 
--------------------------------------------------------------------------------
  ((l*section)*m_per_foot)
2 
--------------------------------------------------------------------------------
  ((l*(r*r*pi))*m_per_foot)
3 
--------------------------------------------------------------------------------
  ((l*((d/2)*(d/2)*pi))*m_pe(d/2)_foot)
4 
--------------------------------------------------------------------------------
  (((102.8)*(((8.5)/2)*((8.5)/2)*(3.14159)))*m_pe((8.5)/2)_foot(102.8)e)
----------------------------------------------------------------------------------

An unwanted substitution occurs in pass 4 when the 'r' in 'm_per_foot' is 
replaced
by the substitution meant for 'r' (radius).

Conclusion: Forget it! - Forget this approach anyway. There are probably 
formula parsers out there that are more intelligent than
this hack.

Frederic

(Learning by making mistakes is faster than by avoiding mistakes and if it's 
fun on top of it all the better.)


-- 
http://mail.python.org/mailman/listinfo/python-list

Reply via email to