Oh, thanks a lot. Now it's working fine.
Now the only problem is that the code is evaluated when calling
sympify, and not when calling evalf.
Could I ask you what is the way to keep the function lazy? I explain
myself better. Since the function SUM has to operate on a database if
I have something like that:
>>> SUM('field') + SUM('field') + SUM('field') #not lazy, computes immediately
>>> three queries
>>> 1234
I'm doing the same operation three times and this is not very good in
terms of performances, what I expected would have been:
>>> a = SUM('field') + SUM('field') + SUM('field') -> 3SUM('field') # one
>>> single query
>>> print a
>>> 3*SUM('field')
>>> print N(a)
>>> 1234
just like other functions work. e.g.
>>> log(10)+log(10)+log(10)
>>> 3*log(10)
On Jun 2, 9:38 am, Mateusz Paprocki <[email protected]> wrote:
> Hi,
>
> On 2 June 2011 09:07, luke <[email protected]> wrote:
>
>
>
>
>
>
>
>
>
> > Hi eveyone,
> > I'm developing an web application which has to interact with "user-
> > defined formulas" of some financial kpis.
> > I decided to use sympy to have a more solid math engine.
> > Basically the input I reiceve is very simple, it might be in the worst
> > case something like:
>
> > kpi -> "(log(sum('production'))*count('sales')/min('spread')" (this
> > formula is totally made-up)
>
> > I defined some functions to interact with the database according to
> > the official docs and they seem to be working:
>
> > For example defining
>
> > from sympy.core.function import Function
>
> > class SUM(Function):
> > nargs = 2
> > @classmethod
> > def eval(cls, arg):
> > map = Code("""function () {
> > emit("sum",{%(field)s:this.%(field)s});
> > }""" % {'field':arg})
> > reduce = Code("""
> > function(key, values) {
> > var sum = 0;
> > values.forEach(function(doc) {
> > if (doc.%(field)s != undefined){
> > sum += doc.%(field)s;
> > }
> > });
> > return {%(field)s:sum};
> > };""" % {'field':arg})
> > result = db.people.map_reduce(map, reduce, "myresults")
> > return result.find_one()['value'][unicode(arg)]
>
> > #EOF
>
> > Then from the command line I can type:
>
> > >>> print SUM("field")
> > >>> 1923
>
> Very interesting application. I'm not sure if you are familiar with this,
> but staying on the safe side note here that SUM("field") doesn't do exactly
> what you expect, but the outcome is fine. Usually, SymPy's functions don't
> accept raw string arguments, but sympify() them:
>
> In [1]: class fun(Function):
> ...: nargs = 1
> ...: @classmethod
> ...: def eval(cls, arg):
> ...: print type(arg)
> ...:
> ...:
>
> In [2]: fun('abc')
> <class 'sympy.core.symbol.Symbol'>
> Out[2]: fun(abc)
>
> So in eval() you got a symbol not string 'abc', but as str() of a Symbol is
> simply the name of the symbol, then this (and your code) works as expected:
>
> In [3]: print "---%s---" % Symbol('abc')
> ---abc---
>
>
>
> > But when I try to use sympify my function doesn't evaluate..
>
> > >>> print sympify("SUM('field')").evalf()
> > >>> SUM(field)
> > >>> N("SUM('field')")
> > >>> SUM(field)
>
> The problem here is that SymPy, precisely speaking sympify(), doesn't know
> what SUM() is, because SUM() resides in the global namespace of the
> interpreter, which is unknown to sympify(), e.g.:
>
> In [4]: sympify("whatever(10)")
> Out[4]: whatever(10)
>
> whatever() is unknown to sympify(), so a new Function object is constructed
> for it. The same for fun() which I defined above:
>
> In [6]: sympify("fun(10)")
> Out[6]: fun(10)
>
> To overcome this, pass globals() to sympify(), e.g.:
>
> In [7]: sympify("fun(10)", globals())
> <class 'sympy.core.numbers.Integer'>
> Out[7]: fun(10)
>
> (in your case this will be sympify("SUM('field')", globals())).
>
>
>
> > Am I doing anything wrong?
> > Thanks in advance!
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "sympy" group.
> > To post to this group, send email to [email protected].
> > To unsubscribe from this group, send email to
> > [email protected].
> > For more options, visit this group at
> >http://groups.google.com/group/sympy?hl=en.
>
> Mateusz
--
You received this message because you are subscribed to the Google Groups
"sympy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sympy?hl=en.