"from pylab import *" will no longer override min() and max()

Why not go one step higher and discuss the issue in

    > Numeric and numarray? It seems like a typical problem in
    > the python community that conflicts are not discussed and
    > decided centrally but instead everyone just does things
    > their way. The possibility to change and fix everything
    > by a wrapper module really causes a huge mess in the
    > various libraries...

I still believe that this is not a problem with Numeric or numarray
[1]. There is nothing to fix there in my opinion (Todd or Perry can
jump in here). Those modules provide min/max/etc in their respective
mlab modules, which do exactly what they advertise: they provide
matlab functionality and matlab provides min/max with a different
signature than python's. There is no problem as long as the user is
mindful of namespaces; there's a reason your mother always told you
never to do 'from somemodule import *'. I tend to heed that advice,
with the one exception being pylab, in which I try to provide a
matlab-like environment where the symbols are all provided in a single
namespace.

Note also that matplotlib's numerix module is more than a simple
numarray/Numeric switcher because it *combines* symbols from all of
their respective submodules. Eg from na_imports, which is where
matplotlib.numerix gets the numarray symbols from

    from numarray.linear_algebra.mlab import *
    from numarray import *
    import numarray.linear_algebra as LinearAlgebra
    import numarray.linear_algebra.mlab as MLab
    from numarray.linear_algebra import inverse, eigenvectors
    from numarray.convolve import convolve
    from numarray.fft import fft
    import numarray.random_array as RandomArray
    from numarray.numeric import nonzero

So we are taking names from a bunch of different namespaces and
pooling them in numerix, which is then pooled into pylab. This is a
good thing for users who want a matlab-like environment, and who want
to be able to switch between Numeric and numarray w/o having to write
a bunch of conditional code to handle the different directory layouts,
but as we've observed can bite you if you are unaware that pylab is
providing matlab names rather than python names in some cases.

Perhaps I'm wrong, but I suspect that 1) Numeric developers would be
very reluctant to change a name that has been in the code base for
god-knows-how-long and thus would break lots of code, and 2) the
functions in MLab actually do exactly what they are designed to do and
are well advertised as such. I for one would definitely be against a
change, because when I do MLab.min I want the matlab signature.

Basically the question is: when confronted with a name clash, should a
module prefer python over matlab. Numeric.MLab rightly (I think)
chose to go with matlab names, but some disagree with this decision
(yes, you Fernando). For pylab, which has its genesis in matlab
compatibility but serves a wider community that may not know or care
about matlab, it may be sensible to make a different choice. In
brief, I don't think it is terribly confusing for Numeric.MLab to have
one policy that when confronting a name clash they go with the matlab
name, and for matplotlib.numerix have a different policy and say we'll
go with the built-in and provide the amin, amax, etc symbols for the
MLab versions. Two different packages/modules can rightly have
different policies on how closely they want to abide by the matlab
names.

JDH

[1] http://sourceforge.net/mailarchive/message.php?msg_id=10514961

    > Why not go one step higher and discuss the issue in
    > Numeric and numarray? It seems like a typical problem in
    > the python community that conflicts are not discussed and
    > decided centrally but instead everyone just does things
    > their way. The possibility to change and fix everything
    > by a wrapper module really causes a huge mess in the
    > various libraries...

I still believe that this is not a problem with Numeric or numarray
[1]. There is nothing to fix there in my opinion (Todd or Perry can
jump in here). Those modules provide min/max/etc in their respective
mlab modules, which do exactly what they advertise: they provide
matlab functionality and matlab provides min/max with a different
signature than python's.

I agree with this; pylab has a very clear "right" to choose whatever
API semantics it wants. It occurs to me now that numerix probably needs
to evolve away from MLab back to pure Numeric, but that has nothing to
do with the pylab API which can remain as it is.

I agree that overriding builtins is a mistake, but I think we're in a
bind here.

[snip]

There is no problem as long as the user is
mindful of namespaces; there's a reason your mother always told you
never to do 'from somemodule import *'. I tend to heed that advice,

This is my position as well: Don't use from *. Using it opens you up
to new names appearing in your module namespace based on changes outside
the module; using it non-interactively is an engineering error.

[snip]

Perhaps I'm wrong, but I suspect that 1) Numeric developers would be
very reluctant to change a name that has been in the code base for
god-knows-how-long and thus would break lots of code, and 2) the
functions in MLab actually do exactly what they are designed to do and
are well advertised as such. I for one would definitely be against a
change, because when I do MLab.min I want the matlab signature.

I have a strong aversion to breaking Numeric compatibility, so I need
to reverse my earlier "unleash Andrew" comment and we should keep
numerix compatible with Numeric.

[snip]

MLab versions. Two different packages/modules can rightly have
different policies on how closely they want to abide by the matlab
names.

I agree. That's why Python has namespaces.

IMHO, this boils down to choosing the lesser of two evils, so if we're
talking about breaking APIs in the name of purity or remaining
compatible with Numeric but a little impure, I'd prefer compatible. My
$.02

Cheers,
Todd

···

On Thu, 2005-01-20 at 09:28, John Hunter wrote:

As long as this is being discussed, I'll put in my $0.2

I think encouraging "import *" Is a BAD IDEA. Even for interactive use.

Since I've used Python, the only time I've used import * is for Numeric, and now I've started using import Numeric as N.

Namespaces are one honking great idea -- let's do more of those!

That's why I'm resistant to using import *

Anyway, I'm very happy about matplotlib because it does most of what I need, does it well, works with wx and AGG, and is constantly being improved.

However, even though I'm an old matlab fanatic, I'm not thrilled with the efforts to make matplotlib matlab-like. I have various reasons for using Python rather than matlab, but one of the primary ones is that I like the language better, and I like OO. Hence, I'd much rather have a platting package be pythonic than matlab-like. Name spaces and OO are a big part of this.

Name spaces and an OO interface are very linked, by the way. The reason NumPy is commonly used with the import * approach is that there are a LOT of functions exposed, and we all get tired of typing Numeric. (or even N.). However, many of those functions should really be methods. I've always been confused by the Numeric docs, which suggest that the function interface is necessary so that you can do, for instance:

B = Numeric.transpose(A)

and A doesn't have to be a Numeric Array. This would be very cool if transpose (and many other ufuncs) returned the type that was input, but it doesn't, it returns an array, so it's really the equivalent of:

B = array(A)
B.transpose(B)

if transpose were an array method. Is it really so onerous to type that extra line? I like the extra line, because it makes things clear to me what's going on.

anyway, to cut my rant short, here is my vote for matplotlib development (not that I get a vote, but hopefully I'll have time to help out someday)

1) Deprecate "from pylab import *"
2) Improve the OO interface to make it just as easy to use.

Even with improvements, I understand that it will be a little bit more awkward to use in interactive mode, but how much does anyone really do interactively anyway? Even with Matlab, I soon learned that if I'm typing more that 3 lines, I should put it in a script.

I know we can do (2) without doing (1), but if (1) is what's in all the examples, it's going to get used.

OK, enough of my rant.

-Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                         
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@...259...

OK, let's get this straight. The situation as it stands:

Currently in CVS is an implementation such that "from pylab import *" does not override builtins. I think we all agree that this is the right behavior. The question is now the implementation. (The code I checked in simply restores of pylab's names to the builtins. e.g. in the pylab.py: "min = __builtin__.min")

John suggests moving my "solution" (I prefer to think of it as a band-aid, curing the symptom, but not the cause) up the chain to numerix, such that numerix.min = __builtin__.min (same for max, etc). Additionally, he suggests bringing a few more names into existence such that numerix.nxmin = mlab.min (same again for max, etc). I have no problem with this, but Todd "we should keep numerix compatible with Numeric" Miller does, and I can see he has a valid point. Thus, I see no easy resolution which is of little consequence to those of us who do not use numerix in our code.

Since I am personally quite busy with other stuff, and I don't see a clear consensus of this numerix issue, which is secondary to my initial gripe regarding pylab. I am disinclined to do anything more at this point. I will hereby let someone who cares more than I do about numerix take it from here.

For the record, I agree with everyone that "from blah import *" is a bad idea. However, pylab is special and thus deserves special attention. Partly this is because John, Fernando, and others have spent many hours making sure it plays well in IPython, resulting in IPython's pylab mode being the best Python interactive scientific plotting solution. Personally, I agree with Fernando's decision to do a "from pylab import *" in ipython -pylab because it enables rapid, interactive data exploration. (Besides which, it freakin' rocks!! :slight_smile:

Given ipython -pylab is my most frequently used interactive Python, I want min/max/etc to be the builtin functions (especially since I tend to do "run -i blah.py" from IPython a lot, which thus inherit names, including min and max, from ipython's interactive namespace).
Also, I am still intrigued by Norbert's suggestion to change Python itself to eliminate this mess, but I don't have the time to deal with it. Furthermore, even if someone did step up to the plate, this is a longer term solution, and we'd still need a "band-aid" for the immediate term.

Getting back to my day job now,
Andrew

Sorry Andrew. I wasn't paying careful enough attention to what John was
saying and have a different idea of what numerix should evolve into: a
simple numarray/Numeric switcher which provides "normalized" access to
the standard packages. If multiple namespaces are combined, that's OK
as long as we don't inject new behavior which defeats numerix's role as
a Numeric replacement. In the general sense, the purpose of numerix is
to make Numeric software available for numarray users. Fairly soon I
think we're going to want to factor it out of matplotlib and use it in
other places.

I agree with John that numerix is not completely a simple switcher now,
but I think that's where it needs to head. Whatever short term solution
is chosen for min,max,etc... isn't that big a deal.

Regards,
Todd

···

On Thu, 2005-01-20 at 15:41, Andrew Straw wrote:

OK, let's get this straight. The situation as it stands:

Currently in CVS is an implementation such that "from pylab import *"
does not override builtins. I think we all agree that this is the right
behavior. The question is now the implementation. (The code I checked
in simply restores of pylab's names to the builtins. e.g. in the
pylab.py: "min = __builtin__.min")

John suggests moving my "solution" (I prefer to think of it as a
band-aid, curing the symptom, but not the cause) up the chain to
numerix, such that numerix.min = __builtin__.min (same for max, etc).
Additionally, he suggests bringing a few more names into existence such
that numerix.nxmin = mlab.min (same again for max, etc). I have no
problem with this, but Todd "we should keep numerix compatible with
Numeric" Miller does, and I can see he has a valid point. Thus, I see
no easy resolution which is of little consequence to those of us who do
not use numerix in our code.

Since I am personally quite busy with other stuff, and I don't see a
clear consensus of this numerix issue, which is secondary to my initial
gripe regarding pylab. I am disinclined to do anything more at this
point. I will hereby let someone who cares more than I do about numerix
take it from here.

For the record, I agree with everyone that "from blah import *" is a bad
idea. However, pylab is special and thus deserves special attention.
Partly this is because John, Fernando, and others have spent many hours
making sure it plays well in IPython, resulting in IPython's pylab mode
being the best Python interactive scientific plotting solution.
Personally, I agree with Fernando's decision to do a "from pylab import
*" in ipython -pylab because it enables rapid, interactive data
exploration. (Besides which, it freakin' rocks!! :slight_smile:

Given ipython -pylab is my most frequently used interactive Python, I
want min/max/etc to be the builtin functions (especially since I tend to
do "run -i blah.py" from IPython a lot, which thus inherit names,
including min and max, from ipython's interactive namespace).

Also, I am still intrigued by Norbert's suggestion to change Python
itself to eliminate this mess, but I don't have the time to deal with
it. Furthermore, even if someone did step up to the plate, this is a
longer term solution, and we'd still need a "band-aid" for the immediate
term.

Getting back to my day job now,
Andrew

Maybe, the situation could be somewhat relaxed by uncluttering pylab:

Currently, pylab.py does two things:

* give a stateful matlab like interface to the object-oriented matplotlib
plotting library

* pull together all kinds of namespaces.

What about pulling all the plotting routines into a separate file that can be
included by anyone who just wants the comfortable plotting commands without
all the other namespace cluttering. pylab itself would then only contain lots
of imports and all the namespace mangling.

For me personally, this would be the solution. I use matplotlib for plotting
only and for my purpose , simple plotting interface from pylab is much nicer
than the full object oriented interface.

For numerics, however, I would prefer to go as pythonic as possible without
any compromises for matlab similarity.

Cleanly dividing the two purposes of matplotlib (nice plotting and matlab
similarity) would certainly help matters.

···

--
_________________________________________Norbert Nemec
         Bernhardstr. 2 ... D-93053 Regensburg
     Tel: 0941 - 2009638 ... Mobil: 0179 - 7475199
           eMail: <Norbert@...399...>