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 -~----------~----~----~----~------~----~------~--~---
