a=[ lambda t: t**n for n in range(4) ]

Bengt Richter bokr at oz.net
Sat Apr 23 12:26:08 EDT 2005


On 22 Apr 2005 20:45:55 -0700, "El Pitonero" <pitonero at gmail.com> wrote:

>Bengt Richter wrote:
>> I still don't know what you are asking for, but here is a toy,
>> ...
>> But why not spend some time with the tutorials, so have a few more
>cards in your deck
>> before you try to play for real? ;-)
>
>Communication problem.
Indeed.

>
>All he wanted is automatic evaluation a la spreadsheet application.
>Just like in Microsoft Excel. That's all.
>
>There are many ways for implementing the requested feature. Here are
>two:
>
>(1) Push model: use event listeners. Register dependent quantities as
>event listeners of independent quantities. When an independent quantity
>is modified, fire off the event and update the dependent quantities.
>Excel uses the push model.
This is essentially what I was demonstrating with the namespace of FunArray,
showing object attribute namespace access as perhaps _the_ 'listening" hook
of Python -- which properties and overriding base class methods with
subclass methods etc. etc. all depend on.

FunArray 'listens' for named "spreadsheet cell" assignments to its namespace,
and it "listens" for a repr access to the "spreadsheet" as a whole, presenting
its status in terms of cell names and the formula value of the last cell entered.

Not conventional, but I wanted to stay as close to the OP's proposed
example interactive log (if that was what it was, which apparently it wasn't ;-)

This does also demonstrate that if you want to "listen" for apparent
assignments to bare names, AFAIK there is no way without byte code hackery
or using a trace hook, or just doing your own eval-print loop,
which is why I suggested the cmd module as a start.

of course, you could mess with displayhook to get what the OP originally
appeared to be asking for. E.g., this toy produces an interactive log
much like the OP specified:

 >>> class DH(object):
 ...     def __init__(self):
 ...         import math
 ...         self.env = vars(math)
 ...         self.env.update(vars(__builtins__))
 ...     def evalstrex(self, s):
 ...         for name in compile(s,'','eval').co_names:
 ...             if type(self.env[name]) == str:
 ...                 self.env[name] = self.evalstrex(self.env[name])
 ...         return eval(s, self.env)
 ...     def __call__(self, o):
 ...         if type(o)==str:
 ...             self.env.update(globals())
 ...             o = self.evalstrex(o)
 ...         sys.__displayhook__(o)
 ...
 >>> import sys
 >>> sys.displayhook = DH()

Other than the quotes around the formula,

 >>> a = '[sin(x), cos(x)]'
 >>> x=0.0
 >>> a
 [0.0, 1.0]
 >>> x=1.0
 >>> a
 [0.8414709848078965, 0.54030230586813977]

looks a lot like

 """
 I'm looking for array of functions.
 Something like a=[ sin(x) , cos(x) ]

 >>> x=0.0
 >>> a
 [0, 1]
 >>> x=1.0
 >>> a
 ...

 of course it can be made by
 >>> def cratearray(x):
 ...           ~~~~
 ...           return a
 a=createarray(1.0)

 but this isn't what i am asking for. something automized.
"""

Of course, this is not what the OP _really_ wanted ;-)

But it's kind of fun. Anything you type in quotes is evaluated
using available global bindings plus the ones in the math module
and __builtins__, and it's recursive, so if a name in the quoted
formula refers to another string (which must be a valid expression),
that is evaluated, and so on. This is "pull" based on interactive
display trigger ;-)

 >>> x='pi/6'
 >>> a
 [0.49999999999999994, 0.86602540378443871]

 >>> x='pi/6'
 >>> a
 [0.49999999999999994, 0.86602540378443871]
 >>> x = 'pi/y'
 >>> y=6
 >>> a
 [0.49999999999999994, 0.86602540378443871]
 >>> y=3
 >>> a
 [0.8660254037844386, 0.50000000000000011]

The display hook passes through non-strings, so you can box a string formula to see it:

 >>> [a]
 ['[sin(x), cos(x)]']
 >>> [x]
 ['pi/y']
 >>> [y]
 [3]


You could specify your spread sheet:

 >>> a1,a2,a3=100,200,'sum([a1,a2])'
 >>> a1,a2,a3
 (100, 200, 'sum([a1,a2])')
 >>> a1
 100
 >>> a2
 200
 >>> a3
 300

;-)

>
>(2) Pull model: lazy evaluation. Have some flag on whether an
>independent quantity has been changed. When evaluating a dependent
>quantity, survey its independent quantities recursively, and update the
>cached copies whereever necessary.
>
>Of course, combination of the two approaches is possible.
>
>For Python, metaclasses and/or decorators and/or properties may help.
>
>But functional languages are a more natural territory.
>

Regards,
Bengt Richter



More information about the Python-list mailing list