On Mon, Nov 17, 2008 at 8:04 PM, Lance Larsen <[EMAIL PROTECTED]> wrote:
>
> Here is the patch for the implicit subs call syntax (i.e. f(x=1, y=2)
> vs. f.subs({x:1,y:2}) ). I changed the behavior of the __call__ method
> in the Basic class, but this did not seem to affect any test cases. If
> this causes a problem, the __call__ can be modified to behave as
> before if a *arg value is passed in, but use subs if **kwargs are
> passed in. I think it is more straight forward to just make __call__
> an alias for subs so that is what I did. However, there may be use
> cases that require the old __call__ code that I am not aware of (there
> didn't appear to be in the test cases). I had trouble setting up the
> smtp server for patchbomb on my machine, so I am sending this manually
> via gmail using the patchbomb output. Hope it works. :)
>
> -Lance Larsen
>
>
> # HG changeset patch
> # User Lance Larsen
> # Date 1226946818 25200
> # Node ID 35c17486e4205095a59d2bb8cd421f48925472a5
> # Parent  e8ef8227fecd5271cf2680af328525f5510734b7
> [mq]: implicit_subs_call_syntax.patch
>
> diff -r e8ef8227fecd -r 35c17486e420 sympy/core/basic.py
> --- a/sympy/core/basic.py       Fri Nov 14 17:01:51 2008 +0100
> +++ b/sympy/core/basic.py       Mon Nov 17 11:33:38 2008 -0700
> @@ -87,10 +87,13 @@
>     classnamespace = {}
>     singleton = {}
>
> -    def __init__(cls, *args, **kws):
> +    def __init__(cls,*args,**kws):

^^ why are you deleting the whitespace? I suggest to leave it as it was.

>         n = cls.__name__
>         c = BasicMeta.classnamespace.get(n)
> -        BasicMeta.classnamespace[n] = cls
> +        if c is None:
> +            BasicMeta.classnamespace[n] = cls
> +        else:
> +            print 'Ignoring redefinition of %s: %s defined earlier than %s' 
> % (
> n, c, cls)
>         super(BasicMeta, cls).__init__(cls)

^^^ why are you introducing the "Ignoring redefinition..." thing? We
removed that recently -- maybe it is a leftover from a merge?

>
>         # --- assumptions ---
> @@ -896,26 +899,41 @@
>         """
>         return self
>
> -    def subs(self, *args):
> -        """
> -        Substitutes an expression.
> +    def subs(self, *args, **kwargs):
> +        """Substitutes an expression.
>
>         Calls either _subs_old_new, _subs_dict or _subs_list depending
> -        if you give it two arguments (old, new), a dictionary or a list.
> +        if you give it two arguments (old, new), a dictionary, a list or
> +        pass in named parameters. When named parameters are passed in,
> +        these are converted to a dictionary and _subs_dict is called.
>
>         Examples:
>
>         >>> from sympy import *
>         >>> x,y = symbols('xy')
> -        >>> (1+x*y).subs(x, pi)
> -        1 + pi*y
> +        >>> (1+x*y).subs(x=pi, y=2)
> +        1 + 2*pi
>         >>> (1+x*y).subs({x:pi, y:2})
>         1 + 2*pi
>         >>> (1+x*y).subs([(x,pi), (y,2)])
>         1 + 2*pi
> +        >>> (1+x*y).subs(x, pi)
> +        1 + pi*y
>
> +        Subs can be called implicitly as well as shown in the following
> +        examples:
> +
> +        >>> f = 1+x*y
> +        >>> f(x=pi, y=2)
> +        1 + 2*pi
> +        >>> f({x:pi, y:2})
> +        1 + 2*pi
> +        >>> f([(x,pi), (y,2)])
> +        1 + 2*pi
> +        >>> f(x, pi)
> +        1 + pi*y
>         """
> -        if len(args) == 1:
> +        if len(args) == 1 and len(kwargs) == 0:
>             sequence = args[0]
>             if isinstance(sequence, dict):
>                 return self._subs_dict(sequence)
> @@ -923,9 +941,11 @@
>                 return self._subs_list(sequence)
>             else:
>                 raise TypeError("Not an iterable container")
> -        elif len(args) == 2:
> +        elif len(args) == 2 and len(kwargs) == 0:
>             old, new = args
>             return self._subs_old_new(old, new)
> +        elif len(args) == 0 and len(kwargs) > 0:
> +            return self._subs_dict(kwargs)
>         else:
>             raise Exception("subs accept either 1 or 2 arguments")
>
> @@ -1932,9 +1952,24 @@
>         from sympy.integrals import integrate
>         return integrate(self, *args, **kwargs)
>
> -    #XXX fix the removeme
> -    def __call__(self, *args, **removeme):
> -        return Function(self[0])(*args)
> +    def __call__(self, *args, **kwargs):
> +        """Alias for calling the subs function.
> +
> +        Examples:
> +
> +        >>> from sympy import *
> +        >>> x,y = symbols('xy')
> +        >>> f = 1+x*y
> +        >>> f(x=pi,y=2)
> +        1 + 2*pi
> +        >>> f({x:pi, y:2})
> +        1 + 2*pi
> +        >>> f([(x,pi), (y,2)])
> +        1 + 2*pi
> +        >>> f(x, pi)
> +        1 + pi*y
> +        """
> +        return self.subs(*args, **kwargs)
>
>     def __float__(self):
>         result = self.evalf()
> diff -r e8ef8227fecd -r 35c17486e420 sympy/core/tests/test_subs.py
> --- a/sympy/core/tests/test_subs.py     Fri Nov 14 17:01:51 2008 +0100
> +++ b/sympy/core/tests/test_subs.py     Mon Nov 17 11:33:38 2008 -0700
> @@ -169,3 +169,16 @@
>     assert (f(x,y)).subs(f,sin) == f(x,y)
>     assert (sin(x)+atan2(x,y)).subs([[atan2,f],[sin,g]]) == f(x,y) + g(x)
>     assert (g(f(x+y, x))).subs([[f, l], [g, exp]]) == exp(x + sin(x + y))
> +
> +def test_subs_call_syntax():
> +    a, b, x, y, p, q = map(Symbol, "abxypq")
> +    f = 2*a*x+3*b*y
> +    assert f(x=1, y=2) == 2*a + 6*b
> +    assert f({a*x:p,b*y:q}) == 2*p + 3*q
> +def test_implicit_subs_call_syntax():
> +    a, b, x, y, p, q = map(Symbol, 'abxypq')
> +    f = 2*a*x + 3*b*y
> +    assert f(x=1, y=2) == 2*a + 6*b
> +    assert f({a*x:p,b*y:q}) == 2*p + 3*q
> +    assert f([(a*x,p),(b*y,q)]) == 2*p + 3*q
> +    assert f(a*x, p) == 2*p + 3*b*y
> \ No newline at end of file

Otherwise the patch looks good as it is to me.

However, there seem to be some confusion about what we agreed to
implement, so let's discuss it first, then apply this patch (with the
first 2 hunks removed, as I noted above --- if you agree of course).

Ondrej

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sympy-patches" group.
To post to this group, send email to sympy-patches@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sympy-patches?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to