I think e.subs(dict(x=1, y=2)) or e.subs({x:1, y:2}) is much better
than e.subs(x=1, y=2), because it's more explicit, pythonic and less
magic.

Vinzent

On Nov 28, 3:06 pm, "Ondrej Certik" <[EMAIL PROTECTED]> wrote:
> Hi,
>
> there is a long discussion in the following two threads:
>
> http://groups.google.com/group/sympy-patches/browse_thread/thread/83c...http://groups.google.com/group/sympy-patches/browse_thread/thread/628...
>
> (don't forget to click next at the bottom of the page to get to the next 
> pages).
>
> First note, that our current .subs() is verstile enough to support
> almost all kinds of syntax. For example:
>
> In [1]: e = x**y+3*x+sin(y)
>
> In [2]: e
> Out[2]:
>                 y
> 3⋅x + sin(y) + x
>
> In [3]: e.subs(x, z)
> Out[3]:
>                 y
> 3⋅z + sin(y) + z
>
> In [4]: e.subs({x: z})
> Out[4]:
>                 y
> 3⋅z + sin(y) + z
>
> In [5]: e.subs(dict(x=z))
> Out[5]:
>                 y
> 3⋅z + sin(y) + z
>
> In [6]: e.subs({x: 1, y: 2})
> Out[6]: 4 + sin(2)
>
> In [7]: e.subs(dict(x=1, y=2))
> Out[7]: 4 + sin(2)
>
> However, it may be useful to allow f(x=1, y=2) directly instead of the
> equivalent e.subs(dict(x=1, y=2)).
> There are pros and cons of each approach, so let me summarize it:
>
> 1) do not allow the e(x=1) syntax, i.e. raise an exception in e.__call__
>
> this doesn't cause any problems
>
> 2) implement e.__call__ along these lines:
>
> def __call__(self, *args, **kwargs):
>     return self.subs(kwargs)
>
> so now e(x=1, y=2) will be possible. A huge disadvantage is that the
> following code will fail:
>
> x = Symbol("a")
> f = x*y
>
> f(x=3)
>
> This is because .subs() will try to substitute for Symbol("x"), but
> there is no Symbol("x") in the expression, only Symbol("a").
>
> Another problem is that what if your Symbol contains characters that
> cannot be in a Python variable, like "\", "-", ..., then it will not
> work.
>
> 3) implement e.__call__ along these lines (nice trick by Riccardo):
>
>     def __call__(self, *args, **kwargs):
>         import inspect
>         frame = inspect.currentframe().f_back.f_globals
>         nkwargs = {}
>         try:
>             for k, v in kwargs.iteritems():
>                 nkwargs[eval(k, frame)] = v
>         finally:
>             del frame
>         return self._subs_dict(nkwargs)
>
> In [1]: t = Symbol("theta")
>
> In [2]: f = x+t**2
>
> In [3]: f(x=10,t=3)
> Out[3]: 19
>
> Now it correctly finds the right variable to substitute for. However,
> I and Brian don't like this, because playing with frames is a messy
> stuff.
>
> Read also the threads for more opinions. For comparison, here is what Sage 
> does:
>
> sage: t = var("theta")
> sage: t
> theta
> sage: f = x+t**2
> sage: f(x=10,t=3)
> theta^2 + 10
>
> So Sage chose the option 2).
>
> So which option should we choose?
>
> Ondrej
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to