----- 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