In any significant codebase star-import is a bad idea. It makes it hard to trace the origin of an imported name when looking at the code. If I'm looking at the code and I see sp.cos then I expect that sp will be defined or imported somewhere at the top of the file and I can just go to the first occurrence of it in the file to see where it comes from. Likewise if you use "from sympy import cos" and I see cos(2) I expect that cos will be imported at the top and I can search for that.
I feel there are some good reasons to star import SymPy (which is why this subject keeps coming up) these reasons tend to get downplayed. One is the obvious fact that complicated algebraic equations just don't look nice with sp. prefixing functions like cos(). Another is the fact that I would guess many users only intend to use SymPy even though their code is complicated - not really throw away one-off code. Such users are, in effect, using Sympy as an algebra processing system, and are not interested in Python, though they might want to import their own modules that also star imported SymPy.
SymPy's 750000 lines of code is obviously an extreme case.
There also seems to be a certain inconsistency associated with importing SymPy symbols selectively (tested using 1.6):
import sympy
from sympy import integrate
from sympy import sin
x=sympy.symbols('x')
integrate(sin(x),x)
Returns
-cos(x)
I would have expected -sympy.cos(x), and indeed if you
subsequently enter cos(x), you get a name error because cos is not
defined!
For these reasons, I think it might be worth devising a set of rules that can be followed so as to import SymPy safely as widely as possible. How about:
1) Only import SymPy using * Thus numpy (say) would have to be imported as
import numpy as np and incur the clumsier syntax of np.cos(...)
This is nearly inevitable because you can't end up with two things called cos.
2) If you are importing other modules that you have written, use exactly the same import commands in all of them.
Struggling as a newcomer with SymPy without importing everything
including sympy.abc (and maybe without knowing the Python
language) can be extremely frustrating .
David
On 29/06/2020 17:16, Oscar Benjamin wrote:
In any significant codebase star-import is a bad idea. It makes it hard to trace the origin of an imported name when looking at the code. If I'm looking at the code and I see sp.cos then I expect that sp will be defined or imported somewhere at the top of the file and I can just go to the first occurrence of it in the file to see where it comes from. Likewise if you use "from sympy import cos" and I see cos(2) I expect that cos will be imported at the top and I can search for that.I feel there are some good reasons to star import SymPy (which is why this subject keeps coming up) these reasons tend to get downplayed. One is the obvious fact that complicated algebraic equations just don't look nice with sp. prefixing functions like cos(). Another is the fact that I would guess many users only intend to use SymPy even though their code is complicated - not really throw away one-off code. Such users are, in effect, using Sympy as an algebra processing system, and are not interested in Python, though they might want to import their own modules that also star imported SymPy.
SymPy's 750000 lines of code is obviously an extreme case.
There also seems to be a certain inconsistency associated with importing SymPy symbols selectively (tested using 1.6):
import sympy
from sympy import integrate
from sympy import sin
x=sympy.symbols('x')integrate(sin(x),x)
Returns
-cos(x)
I would have expected -sympy.cos(x), and indeed if you subsequently enter cos(x), you get a name error because cos is not defined!
The printer doesn't take into account your namespace. It is copy-pastable from the point of view of having all the SymPy names imported. We could add a string printer mode that prefixes all SymPy names.
Thanks, I wasn't aware that print() works that way.
The problem seems to remain that if you integrate sin(x) you get cos(x), yo get a symbol cos that you didn't anticipate. Maybe integrating sin(x**3) would be a better example, where hypergeometrics and gamma functions suddenly appear in the answer - I mean these will appear without regard to the selective importing of SymPy. Thus if you copy/paste these into an input, these will generate an undefined name error because they are not prefixed.If you don't like using sym.cos and so on everywhere, you can just import things directly, like from sympy import cos
Precisely - as explained above.
I mean, is copy/paste an unusual thing to use - I would have thought it was completely normal.
I don't know Python anywhere near well enough to figure out if it
is possible for print() or something else, like fullprint() to add
appropriate prefixes (like sp.) to things (not just every possible
prefix) as it outputs them - can it extract enough information to
actually do this?
My suggestion to use "from sympy import *" within modules was meant to apply in a situation where you used a collection of modules for various purposes which all imported just SymPy. I can't quite see what the problem is in that case, unless you use Python tools.
Even without using *, it is still possible to accidentally import something from more than one module:
from sympy import sin
from numpy import sin
Indeed if you are going to use numpy in conjunction with sympy, this sort of clash seems quite inevitable unless you make all the numpy symbols work using the np. prefix.
BTW, I really do not wish to be a nuisance, because I do realise
what a magnificent facility SymPy represents, and the work that
must have gone into it.
David