Numerical evaluation in exec?

21 views
Skip to first unread message

Boris Kheyfets

unread,
Sep 11, 2013, 9:51:38 AM9/11/13
to sy...@googlegroups.com

Why this

d2bdy2 = b_i.diff(y_i, 2)
exec("pprint({{'{0}': {0}}})".format("d2bdy2"))

is not equivalent to

def assign_and_pprint(Name, Expr):
    exec("{Name} = {Expr}".format(Name=Name, Expr=Expr))
    exec("pprint({{'{Name}': {Name}}})".format(Name=Name))

assign_and_pprint("d2bdy2", b_i.diff(y_i, 2))

Compelete example:

#!/usr/bin/python2.7

from sympy import *

def assign_and_pprint(Name, Expr):
    exec("{Name} = {Expr}".format(Name=Name, Expr=Expr))
    exec("pprint({{'{Name}': {Name}}})".format(Name=Name))


var("""
b_i y_i nu
""", positive=True)

b_i = 2**(S(2)/3) / (nu**(S(4)/3) * (y_i - 1)**(S(8)/3))

d2bdy2 = b_i.diff(y_i, 2)
exec("pprint({{'{0}': {0}}})".format("d2bdy2"))

assign_and_pprint("d2bdy2", b_i.diff(y_i, 2))

Which gives:

⎧                  2/3      ⎫
⎪              88⋅2         ⎪
⎨d2bdy2: ───────────────────⎬
⎪           4/3         14/3⎪
⎩        9⋅ν   ⋅(yᵢ - 1)    ⎭
⎧                          -1.33333333333333         -4.66666666666667⎫
⎨d2bdy2: 15.5212547303557⋅ν                 ⋅(yᵢ - 1)                 ⎬
⎩                                                                     ⎭

Aaron Meurer

unread,
Sep 11, 2013, 1:29:44 PM9/11/13
to sy...@googlegroups.com
It's because the string form of the expression contains division of
numeric literals, which exec evaluates to floats. If you want to avoid
this, you should use sympify(), or use the srepr() form of the
expression instead of the str() form.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> For more options, visit https://groups.google.com/groups/opt_out.

Boris Kheyfets

unread,
Sep 11, 2013, 4:17:27 PM9/11/13
to sy...@googlegroups.com
Thanks for a reply. I tried it, but:


exec("{Name} = sympify({Expr})".format(Name=Name, Expr=Expr))

gives the same, and


exec(sympify("{Name} = {Expr}".format(Name=Name, Expr=sympify(Expr))))

gives an error...



You received this message because you are subscribed to a topic in the Google Groups "sympy" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/sympy/D5O51p6OPXE/unsubscribe.
To unsubscribe from this group and all its topics, send an email to sympy+un...@googlegroups.com.

Aaron Meurer

unread,
Sep 12, 2013, 8:14:45 PM9/12/13
to sy...@googlegroups.com
The first one is still calling exec on the string form. The second
one doesn't work because sympify() can't handle statements like "x =
1".

I recommend avoiding magic to do assignment (and avoiding exec in
general), but if you must do it, you're better off injecting the name
into the namespace, like var() does. Look at its source to see how it
works (https://github.com/sympy/sympy/blob/master/sympy/core/symbol.py#L465).

Aaron Meurer
Reply all
Reply to author
Forward
0 new messages