Hi, On 2 June 2011 09:07, luke <luca.giaco...@gmail.com> 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 sympy@googlegroups.com. > To unsubscribe from this group, send email to > sympy+unsubscr...@googlegroups.com. > 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 sympy@googlegroups.com. To unsubscribe from this group, send email to sympy+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/sympy?hl=en.