Implicit Subs Syntax - f(x=1,y=2)

3 views
Skip to first unread message

Lance Larsen

unread,
Nov 18, 2008, 11:20:04 PM11/18/08
to sympy-patches
# HG changeset patch
# User "Lance Larsen <lance.c...@gmail.com>"
# Date 1226946818 25200
# Node ID 060b92b72467a29a2d098e7ce0ee96cbf4c2395b
# Parent d1019a5c66d12d524fe64359c1bd8054cab0cfa9
Substitution syntax extension - implements f.subs(x=1,y=2) and
shorthand syntax f(x=1,y=2).

diff -r d1019a5c66d1 -r 060b92b72467 sympy/core/basic.py
--- a/sympy/core/basic.py Tue Nov 18 17:36:24 2008 +0100
+++ b/sympy/core/basic.py Mon Nov 17 11:33:38 2008 -0700
@@ -896,26 +896,43 @@
"""
return self

- def subs(self, *args):
+ 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 +940,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 +1951,25 @@
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. All subs syntax is
supported
+ the two parameter syntax f(x,2) for f(x=2).
+
+ 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
+ """
+ if len(args) > 1:
+ raise Exception("Unsupported syntax. Pass a dictionary, a
list of substitution pairs, or name=value pairs.")
+ return self.subs(*args, **kwargs)

def __float__(self):
result = self.evalf()
diff -r d1019a5c66d1 -r 060b92b72467 sympy/core/tests/test_subs.py
--- a/sympy/core/tests/test_subs.py Tue Nov 18 17:36:24 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

Brian Granger

unread,
Nov 19, 2008, 12:42:30 AM11/19/08
to sympy-...@googlegroups.com
Lance,

Sorry if I am being a pain in the #%%, I just want to make sure that
we get the desig of this right as someone else said "you only get to
implement __call__ once". I do appreciate you willingness to do the
implementation of this and hear me out. A few things about this most
recent patch:

The patch allows __call__ to be used in the following ways:

+ >>> f = 1+x*y
+ >>> f(x=pi,y=2)
+ 1 + 2*pi

This is great and I think we all agree that this absolutely should be
supported. +1 on this.

+ >>> f({x:pi, y:2})
+ 1 + 2*pi

I am +0 on this. The main thing that I am guided by is that __call__
should be used to implement something that looks like a function call
(in the mathematical sense). The mathematician in me sees this and
asks, how do I can a function with a dictionary?

+ >>> f([(x,pi),(y,2)])
+ 1 + 2*pi

I am -1 on this. Try to forget about subs for a second. Most new
users will want to use a function call syntax before they do a subs (I
am thinking of my students in the physics department). This syntax is
_very_ confusing for someone expecting function calls to behave like
they do in math.

Also, it violates this (pun intended):

>>> import this
...
There should be one-- and preferably only one --obvious way to do it.
...

For function calling that involves key/value pairs f(x=1,y=3) already
works just fine. As an aside, this is also a complaint that I have
about subs - we have a single function that can be called in (it seems
10 different ways. It that really needed. Simplify, simplify,
sympify.

Other thoughts?

Brian

Lance Larsen

unread,
Nov 19, 2008, 9:01:37 AM11/19/08
to sympy-patches
Submission of patch with changes suggested by Brian in post.

# HG changeset patch
# User "Lance Larsen <lance.c...@gmail.com>"
# Date 1226946818 25200
# Node ID 5699c540c62b31ddf3c96e07fae6fe64cf10eb1e
# Parent d1019a5c66d12d524fe64359c1bd8054cab0cfa9
Substitution syntax extension - implements f.subs(x=1,y=2) and
shorthand syntax f(x=1,y=2).

diff -r d1019a5c66d1 -r 5699c540c62b sympy/core/basic.py
+ """Alias for calling the subs function. Substitution using
two parameters
+ (i.e. f(x,3)) and list of pairs (f([(x,3),(y,2)])) is not
supported
+ because the notation may be confusing to sympy users.
+
+ 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
+ """
+ if len(args) > 1 or (len(args) == 1 and isinstance(args
[0]),dict):
+ sequence = args[0]
+ raise Exception("Unsupported syntax. Pass a dictionary or
name=value pairs.")
+ return self.subs(*args, **kwargs)

def __float__(self):
result = self.evalf()
diff -r d1019a5c66d1 -r 5699c540c62b sympy/core/tests/test_subs.py
--- a/sympy/core/tests/test_subs.py Tue Nov 18 17:36:24 2008 +0100
+++ b/sympy/core/tests/test_subs.py Mon Nov 17 11:33:38 2008 -0700
@@ -169,3 +169,14 @@
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.subs(x=1, y=2) == 2*a + 6*b
+

Lance Larsen

unread,
Nov 19, 2008, 9:35:15 AM11/19/08
to sympy-patches
> Sorry if I am being a pain in the #%%, I just want to make sure that
> we get the desig of this right as someone else said "you only get to
> implement __call__ once".

No worries. I appreciate you clarifying your viewpoint. You may not
like what you get if you don't give your opinion.

> The patch allows __call__ to be used in the following ways:
>
> +        >>> f = 1+x*y
> +        >>> f(x=pi,y=2)
> +        1 + 2*pi
>
> This is great and I think we all agree that this absolutely should be
> supported.  +1 on this.
>
> +        >>> f({x:pi, y:2})
> +        1 + 2*pi
>
> I am +0 on this.  The main thing that I am guided by is that __call__
> should be used to implement something that looks like a function call
> (in the mathematical sense).  The mathematician in me sees this and
> asks, how do I can a function with a dictionary?

I am imcluding the f({x:pi,y:4}) syntax because Ondrej is right about
the limitations of the f(x=pi,y=4) syntax, and I think that this
method of substitution may prove to be a popular shorthand for subs.

> +        >>> f([(x,pi),(y,2)])
> +        1 + 2*pi
>
> I am -1 on this.  Try to forget about subs for a second.  Most new
> users will want to use a function call syntax before they do a subs (I
> am thinking of my students in the physics department).  This syntax is
> _very_ confusing for someone expecting function calls to behave like
> they do in math.

I don't have a strong opinion on this and I can see how this may lead
to confusion for someone who is a casual user of sympy, so I have
taken your suggestion and removed the dictionary of pairs option in
the new patch I submitted to the thread.

> Also, it violates this (pun intended):
>
> >>> import this
>
> ...
> There should be one-- and preferably only one --obvious way to do it.
> ...
>
> For function calling that involves key/value pairs f(x=1,y=3) already
> works just fine.  As an aside, this is also a complaint that I have
> about subs - we have a single function that can be called in (it seems
> 10 different ways.  It that really needed.  Simplify, simplify,
> sympify.

Sometimes it is nice to have multiple ways to do something. I was
recently looking at using sympy with Mako to embed calculations in a
LaTeX document. The Mako syntax is fairly lightweight and easy to
used. For example, if you have the sympy expression f=x+y you can used
$(latex(f)) to print out the latex version of 'x+y'. I wanted to
things like ${latex(f) + '=' + latex(f({x=1,y=2}))}, unfortunately
Mako does not support brackets {} inside a ${...} expression. It was
convenient that the dictionary approach was supported. I personally
don't mind have a few ways to do something as long as they are clean
(easy to use and make sense), reasonably documented, and prove
convenient under common use cases. Not sure if the dictionary of pairs
fits that category, but it did happen to help in the case of Mako.

-Lance

Lance Larsen

unread,
Nov 19, 2008, 9:41:52 AM11/19/08
to sympy-patches
Guess I should proof read my posts more carefully - lots of
grammatical mistakes :) oh well. Thanks for the input Brian.

-Lance

Lance Larsen

unread,
Nov 19, 2008, 10:17:21 AM11/19/08
to sympy-patches
I forgot to run the test cases against the second patch. It has
errors. Will correct an resubmit later today.

-Lance

Brian Granger

unread,
Nov 19, 2008, 2:29:22 PM11/19/08
to sympy-...@googlegroups.com
> No worries. I appreciate you clarifying your viewpoint. You may not
> like what you get if you don't give your opinion.

Thanks.

> I am imcluding the f({x:pi,y:4}) syntax because Ondrej is right about
> the limitations of the f(x=pi,y=4) syntax, and I think that this
> method of substitution may prove to be a popular shorthand for subs.

This is fine - I forgot that this case does solve the limitations of
the f(x=10,y=4) syntax.

>> + >>> f([(x,pi),(y,2)])
>> + 1 + 2*pi
>>
>> I am -1 on this. Try to forget about subs for a second. Most new
>> users will want to use a function call syntax before they do a subs (I
>> am thinking of my students in the physics department). This syntax is
>> _very_ confusing for someone expecting function calls to behave like
>> they do in math.
>
> I don't have a strong opinion on this and I can see how this may lead
> to confusion for someone who is a casual user of sympy, so I have
> taken your suggestion and removed the dictionary of pairs option in
> the new patch I submitted to the thread.

Thanks, I think this is an improvement.

> Sometimes it is nice to have multiple ways to do something. I was
> recently looking at using sympy with Mako to embed calculations in a
> LaTeX document. The Mako syntax is fairly lightweight and easy to
> used. For example, if you have the sympy expression f=x+y you can used
> $(latex(f)) to print out the latex version of 'x+y'. I wanted to
> things like ${latex(f) + '=' + latex(f({x=1,y=2}))}, unfortunately
> Mako does not support brackets {} inside a ${...} expression. It was
> convenient that the dictionary approach was supported. I personally
> don't mind have a few ways to do something as long as they are clean
> (easy to use and make sense), reasonably documented, and prove
> convenient under common use cases. Not sure if the dictionary of pairs
> fits that category, but it did happen to help in the case of Mako.

Very, very true and this is always a careful balancing act.
Especially because you can't always imagine the ways in which users
will want to use your code.

I guess only one other thing needs to be resolved: what do people
think about my .bindings proposal? Obviously *I* think it (I an open
to variants of it) is a good idea, but I really would like to hear
from others. Also, once Lance finishes this patch, I don't mind doing
the implementation of .bindings if there is support for it.

Cheers,

Brian

PS - I am _really_ looking forward to having these things in sympy!!!

> -Lance
> >
>

Andy Ray Terrel

unread,
Nov 19, 2008, 3:15:34 PM11/19/08
to sympy-...@googlegroups.com
Hello Lance,

I wasn't able to get this patch to apply, are you using:

[diff]
git = true
showfunc = 1

in your ~/.hgrc file.


Alternatively does someone know how to import hg diffs using git,
cause I'm not getting it right now.

-- Andy

Ondrej Certik

unread,
Nov 19, 2008, 3:36:38 PM11/19/08
to sympy-...@googlegroups.com

Lance Larsen

unread,
Nov 19, 2008, 4:42:04 PM11/19/08
to sympy-patches
For what it is worth, I fixed the errors in the last patch submitted.
Looks like a previous patch has already been applied in main
repository though. I used a different method to export this patch. I
used the command 'hg qdiff' to get the diff info and stole the patch
header from my previously submitted patch. Don't know if this causes
problems. 'hg email' was complaining about my parent repository setup
and I didn't have time to debug this so I tried a workaround.

-Lance

# HG changeset patch
# User "Lance Larsen <lance.c...@gmail.com>"
# Date 1226946818 25200
# Node ID 5699c540c62b31ddf3c96e07fae6fe64cf10eb1e
# Parent d1019a5c66d12d524fe64359c1bd8054cab0cfa9
Substitution syntax extension - implements f.subs(x=1,y=2) and
shorthand syntax f(x=1,y=2).

diff -r dab6435e04fd sympy/core/basic.py
--- a/sympy/core/basic.py Thu Nov 06 23:12:01 2008 +0100
+++ b/sympy/core/basic.py Wed Nov 19 14:33:25 2008 -0700
@@ -899,26 +899,43 @@
@@ -926,9 +943,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")

@@ -1935,9 +1954,25 @@
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. Substitution using
two parameters
+ (i.e. f(x,3)) and list of pairs (f([(x,3),(y,2)])) is not
supported
+ because the notation may be confusing to sympy users.
+
+ 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
+ """
+ if len(args) > 1 or (len(args) == 1 and isinstance(args[0],
(list, tuple))):
+ sequence = args[0]
+ raise Exception("Unsupported syntax. Pass a dictionary or
name=value pairs.")
+ return self.subs(*args, **kwargs)

def __float__(self):
result = self.evalf()
diff -r dab6435e04fd sympy/core/tests/test_subs.py
--- a/sympy/core/tests/test_subs.py Thu Nov 06 23:12:01 2008 +0100
+++ b/sympy/core/tests/test_subs.py Wed Nov 19 14:33:25 2008 -0700
@@ -169,3 +169,14 @@
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.subs(x=1, y=2) == 2*a + 6*b
+

Ondrej Certik

unread,
Nov 19, 2008, 8:18:29 PM11/19/08
to sympy-...@googlegroups.com
On Wed, Nov 19, 2008 at 10:42 PM, Lance Larsen <lance.c...@gmail.com> wrote:
>
> For what it is worth, I fixed the errors in the last patch submitted.
> Looks like a previous patch has already been applied in main
> repository though. I used a different method to export this patch. I

Which patch was applied in the main repo?

> used the command 'hg qdiff' to get the diff info and stole the patch
> header from my previously submitted patch. Don't know if this causes
> problems. 'hg email' was complaining about my parent repository setup
> and I didn't have time to debug this so I tried a workaround.

It should not cause problems. But you can easily export patches using
"hg export tip" or just passing some particular revision to it.

This patch looks good to me. Brian -- is it ok with you as well?

Ondrej

Ondrej Certik

unread,
Nov 19, 2008, 8:22:41 PM11/19/08
to sympy-...@googlegroups.com

Btw, as to the argument that by giving all **kw arguments to the user
--- why not to just use this:

In [3]: (x*y).subs(dict(x=5, y=3))
Out[3]: 15

which works right now with the current sympy?

Ondrej

Ondrej Certik

unread,
Nov 19, 2008, 8:25:22 PM11/19/08
to sympy-...@googlegroups.com

The advantage of using dict() is that it is Pythonic (imho) and it
could be used anywhere in sympy where a dictionary is used. That's
basically a question to Lance. Since Sage already supports the
subs(x=5, y=3) syntax, I don't mind applying the patch.

Ondrej

Lance Larsen

unread,
Nov 19, 2008, 9:54:10 PM11/19/08
to sympy-patches
> Which patch was applied in the main repo?

I did a pull from the main line and it looked like one of my original
patches was included in my repository. If this wasn't from the main
repo (and it sounds like it wasn't), I must have committed the hg
patch locally when I was experimenting with hg without knowing it.
Mercurial seems less intuitive to me than other source controls I have
used so far (I have used central repository source controls like svn,
cvs, and source safe). I do like the idea of the distributed
repository system and the patch queue though. Pretty cool.

> Btw, as to the argument that by giving all **kw arguments to the user
> --- why not to just use this:
> In [3]: (x*y).subs(dict(x=5, y=3))
> Out[3]: 15
> which works right now with the current sympy?

The reason for the f(x=1, y=2) syntax is convenience and readability.
It is a syntax I find fairly natural. I became interested in having
this notation in sympy when I started to consider sympy as a tool for
writing LaTeX papers and embedding calculations. Under this setting it
is nice to have calculations be compact and readable. This syntax
seemed like the best choice to me.

-Lance

Brian Granger

unread,
Nov 20, 2008, 1:10:53 AM11/20/08
to sympy-...@googlegroups.com
> This patch looks good to me. Brian -- is it ok with you as well?

As much as I can tell from looking at the diff, yes, it is OK. I say
go ahead, if we want to add the bindings thing later we can, but even
this is a nice improvement.

Brian

> Ondrej
>
> >
>

Ondrej Certik

unread,
Nov 20, 2008, 4:35:58 AM11/20/08
to sympy-...@googlegroups.com
On Thu, Nov 20, 2008 at 7:10 AM, Brian Granger <elliso...@gmail.com> wrote:
>
>> This patch looks good to me. Brian -- is it ok with you as well?
>
> As much as I can tell from looking at the diff, yes, it is OK. I say
> go ahead, if we want to add the bindings thing later we can, but even
> this is a nice improvement.

I tried to push the patch in, but I am having hard time applying it
--- Lance, could you please push your repository to
http://www.bitbucket.org/? So that I can just pull it. Because
currently I am having:

$ patch -p1 --dry-run -l < pa5
patching file sympy/core/basic.py
patch: **** malformed patch at line 61: return
self._subs_dict(sequence)


and I haven't figured out how to fix this, apart from applying all
changes by hand line by line.

Thanks,
Ondrej

Andy R. Terrel

unread,
Nov 20, 2008, 6:50:55 PM11/20/08
to sympy-patches
This patch doesn't treat dummies well, but I guess that can be fixed
later:

In [6]: a_d = Symbol('a',dummy=True)
In [7]: a = Symbol('alpha',dummy=True)
In [8]: f = 2*a*a_d*x
In [9]: f
Out[9]: 2*x*a*alpha
In [10]: f(a=2)
Out[10]: 2*x*a*alpha
In [11]: f(a_d=2)
Out[11]: 2*x*a*alpha
In [12]: f(alpha=2)
Out[12]: 2*x*a*alpha
In [13]: a = Symbol('alpha')
In [14]: f = 2*a*a_d*x
In [15]: f(alpha=2)
Out[15]: 4*x*a
In [16]: f(a=2)
Out[16]: 2*alpha*x*a


On Nov 19, 10:42 pm, Lance Larsen <lance.c.lar...@gmail.com> wrote:
> For what it is worth, I fixed the errors in the last patch submitted.
> Looks like a previous patch has already been applied in main
> repository though. I used a different method to export this patch. I
> used the command 'hg qdiff' to get the diff info and stole the patch
> header from my previously submitted patch. Don't know if this causes
> problems. 'hg email' was complaining about my parent repository setup
> and I didn't have time to debug this so I tried a workaround.
>
> -Lance
>
> # HG changeset patch
> # User "Lance Larsen <lance.c.lar...@gmail.com>"
Why do we use Exception instead of ValueError or TypeError?

Lance Larsen

unread,
Nov 21, 2008, 1:07:43 AM11/21/08
to sympy-patches
Here is a corrected implicit subs patch. Note that there is another
__call__ syntax proposal that is being discussed at present on the
thread:

http://groups.google.com/group/sympy-patches/browse_thread/thread/628ebc799ee57ec1

# HG changeset patch
# User "Lance Larsen <lance.c...@gmail.com>"
# Date 1226946818 25200
# Node ID 857ff7513ab41f5c8473a9e67be2c8ef51b9f366
# Parent d1019a5c66d12d524fe64359c1bd8054cab0cfa9
Substitution syntax extension - accepts f.subs(x=1,y=2) and shorthand
syntax f(x=1,y=2).

diff -r d1019a5c66d1 -r 857ff7513ab4 sympy/core/basic.py
--- a/sympy/core/basic.py Tue Nov 18 17:36:24 2008 +0100
+++ b/sympy/core/basic.py Mon Nov 17 11:33:38 2008 -0700
@@ -896,26 +896,43 @@
@@ -923,9 +940,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 +1951,25 @@
diff -r d1019a5c66d1 -r 857ff7513ab4 sympy/core/tests/test_subs.py
--- a/sympy/core/tests/test_subs.py Tue Nov 18 17:36:24 2008 +0100
+++ b/sympy/core/tests/test_subs.py Mon Nov 17 11:33:38 2008 -0700
Reply all
Reply to author
Forward
0 new messages