Re: [TSBOAPOOOWTDI]using names from modules

2017-11-05 Thread Paul Moore
On 5 November 2017 at 13:54, Stefan Ram  wrote:
> Paul Moore  writes:
>>But regardless, the Zen isn't intended to be taken quite as literally
>>as the OP was trying to do. It's a statement of principles, not a set
>>of rules.
>
>   What I am looking for is a default notation to use in my
>   beginner's tutorial and also to recommand for beginners.

Then "import math" at the top of the file, and refer to module
functions as "math.sin".

That's the normal approach you'd see in pretty much every Python
project on the web, so "follow normal practice" applies. By the time
your students know enough to ask if there's a way to avoid needing to
repeat "math" (and understand the answer) they are likely to be
experienced enough to judge which option is better in a given
situation.

Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [TSBOAPOOOWTDI]using names from modules

2017-11-05 Thread Steve D'Aprano
On Mon, 6 Nov 2017 12:54 am, Stefan Ram wrote:

> Paul Moore  writes:
>>But regardless, the Zen isn't intended to be taken quite as literally
>>as the OP was trying to do. It's a statement of principles, not a set
>>of rules.
> 
>   What I am looking for is a default notation to use in my
>   beginner's tutorial and also to recommand for beginners.

When I first started learning Python, I had a bit of difficulty with the two
import forms. For about an hour, until I experimented in the interactive
interpreter until I got it.

Part of the problem at the time was that I had no concept of "namespaces" or
modules.

If your students are experienced in other languages, don't treat them like
dummies. They'll probably understand about namespaces and variable scopes.
Teach them that math.cos is the syntax for accessing a name "cos" inside
the "math" namespace, and they'll get it. Teach them that the from...import
version brings the name into the current scope, and they'll get that too. You
might have to give them analogous examples from whatever languages they're
used to.

If your students are completely new to this, like I was, then it might help to
start them with just the "import math" form, and then later introduce 
"from...import" as syntactic sugar for:

import math
cos = math.cos
del math

Although I wouldn't literally teach `del` at this point, I'd just leave it out
and and "except that the name 'math' isn't actually made available".


>   Learners have a limited capacity for learning and storing
>   information.

People don't learn isolated facts too well. But they learn *models* which they
can then infer behaviour from VERY well. This is why the Principle of Least
Surprise is so important for usable interfaces and APIs.

If you try to teach things as isolated facts, students will struggle. But:

- teach import math first;

- then show how `from math import cos` is syntactic sugar for making a local
alias for math.cos;

- then you can show that there's no particular reason why the names have to be
the same:

from math import cos as mycos

is just sugar for

import math
mycos = math.cos


But don't teach them this:

> |from math import *

There's no reason for beginners to use wildcard imports until they've mastered
*not* using wildcard imports.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [TSBOAPOOOWTDI]using names from modules

2017-11-05 Thread Paul Moore
On 5 November 2017 at 01:19, Steve D'Aprano  wrote:
> On Sun, 5 Nov 2017 06:42 am, Stefan Ram wrote:
>
>> What is the one way to do it?
>
> There is no philosophy of "one way to do it" in Python, that is a
> misunderstanding (possibly deliberate...) spread about by Perl users, to
> contrast Python from Perl's "more than one way to do it".
>
> The Zen of Python says:
>
> There should be one-- and preferably only one --obvious way to do it.
>
>
> The emphasis is on "obvious", not "one". There should be *at least* one, but
> preferably only one, OBVIOUS way to solve any problem.
>
> As for the question of importing names, the obvious way is to use a regular
> import:
>
>
> import math
> y = math.cos(x)
>
>
> which has the advantage of making it obvious where the name comes from, but
> the disadvantage that it is more to type and involves an extra name lookup at
> runtime, which is not free.
>
> But:
>
> - when performance matters
>
> - or the name is very well known
>
> - or you're only using a single name from the module (or at most a few)
>
> - especially if it repeats the module name (e.g. fractions.Fraction)
>
> it is acceptable to use the "from module import name" version:
>
> from math import cos
> y = cos(x)
>
>
> Which you use depends on the situation and personal taste.

Also, if what you are trying to "do" is different (for example, you're
trying to write code that looks familiar to mathematicians) the
obvious way may be different too (so "from math import cos" may be the
obvious approach in that situation).

But regardless, the Zen isn't intended to be taken quite as literally
as the OP was trying to do. It's a statement of principles, not a set
of rules.
Paul
-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [TSBOAPOOOWTDI]using names from modules

2017-11-04 Thread Steve D'Aprano
On Sun, 5 Nov 2017 06:42 am, Stefan Ram wrote:

> What is the one way to do it?

There is no philosophy of "one way to do it" in Python, that is a
misunderstanding (possibly deliberate...) spread about by Perl users, to
contrast Python from Perl's "more than one way to do it".

The Zen of Python says:

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


The emphasis is on "obvious", not "one". There should be *at least* one, but
preferably only one, OBVIOUS way to solve any problem.

As for the question of importing names, the obvious way is to use a regular
import:


import math
y = math.cos(x)


which has the advantage of making it obvious where the name comes from, but
the disadvantage that it is more to type and involves an extra name lookup at
runtime, which is not free.

But:

- when performance matters

- or the name is very well known

- or you're only using a single name from the module (or at most a few)

- especially if it repeats the module name (e.g. fractions.Fraction)

it is acceptable to use the "from module import name" version:

from math import cos
y = cos(x)


Which you use depends on the situation and personal taste.



-- 
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.

-- 
https://mail.python.org/mailman/listinfo/python-list


Re: [TSBOAPOOOWTDI]using names from modules

2017-11-04 Thread Terry Reedy

On 11/4/2017 3:42 PM, Stefan Ram wrote:

   What is better:

...
import math
...
... math.cos ...
...

   or

...
from math import cos
...
... cos ...
...

   ?

   (To me, the first is more readable, because at the site
   where »math.cos« is used, it is made clear that »cos«
   comes from math. But I assume that the second might use
   one less name lookup and therefore is faster. What is the
   one way to do it?)


There is no 'one way', which is why there is more than one way.
The first lets the reader know the source at each use site.
The second lets the reader know what use is made of the source at the 
top.  The advantage depends on how familiar the *reader* is with the 
source module and the functions therein.


Is your question generic to any module and object,  or specific to the 
math module?  If generic, and mode is part of the package you are 
writing, then 'import mod' is less likely to create a circular import 
error.  On the other hand, 'from mod import obj' is better for testing 
because it lets one mock obj in the importing module without touching 
the imported module (where the original may be internally needed in the 
same test).  With idlelib, there are both circular import and testing 
issues.


If importing a module is expensive in some way, then knowing that B only 
needs one or two 'cheap' items from A is needed may suggest a workaround 
or refactoring.  For instance, move items from  A to B and reverse the 
import between them.


Replacing an existing 'from tkinter import *' with 'import tkinter' or 
'import tkinter as tk' requires prefixing every existing reference to a 
tkinter object.  Replacing the same with 'from tkinter import Tk, ...' 
requires list each object.  The latter localizes the patch.  Plus see 
the preceding paragraphs.  In either case, complete enough test coverage 
is needed to make the change.


I initially started with the 'as tk' replacement, but switched to the 
list version.  A tkinter-specific reason was planning to switch from tk 
to ttk versions of widgets.  Moving, for instance, 'Button' from the 
tkinter list to the tkinter.ttk list, instead of changing prefixes, 
would be both easy and make it obvious, at the top, that the change had 
been made, and for all Buttons.


--
Terry Jan Reedy


--
https://mail.python.org/mailman/listinfo/python-list


Re: [TSBOAPOOOWTDI]using names from modules

2017-11-04 Thread Cameron Simpson

On 04Nov2017 20:59, Peter J. Holzer  wrote:

On 2017-11-04 19:42, Stefan Ram  wrote:

  What is better:
...
import math
...
... math.cos ...

  or
...
from math import cos
...
... cos ...
  ?

  (To me, the first is more readable, because at the site
  where »math.cos« is used, it is made clear that »cos«
  comes from math.


If I'm doing trigonometric computations I think the *second* is *much*
more readable. I'm using the well-known cosine function - that this was
imported from the math module is pure noise.

For other functions this may be less clear. I tend to use the first
style more often, although that gets a bit verbose sometimes
(os.path.join(os.path.dirname(...), ...)), [...]


I think the same. If the function is well known and idstinctively named, just 
use the short form ("cos(value)").


I also use the first style, but not often.

Regarding the less clear function names, particularly things like 
"os.path.join", my os.path imports often look like this these days:


 from os.path import dirname, exists as pathexists, isdir as pathisdir, join as 
joinpath

This lets me use distinct but short names in the code. To take Peter's example:

 joinpath(dirname(...), ...)

You can see I've given a distinctive name to "join", which would otherwise be 
pretty vague.


Cheers,
Cameron Simpson  (formerly c...@zip.com.au)"
--
https://mail.python.org/mailman/listinfo/python-list


Re: [TSBOAPOOOWTDI]using names from modules

2017-11-04 Thread Peter J. Holzer
On 2017-11-04 19:42, Stefan Ram  wrote:
>   What is better:
>
> ...
> import math
> ...
> ... math.cos ...
> ...
>
>   or
>
> ...
> from math import cos
> ...
> ... cos ...
> ...
>
>   ?
>
>   (To me, the first is more readable, because at the site
>   where »math.cos« is used, it is made clear that »cos«
>   comes from math.

If I'm doing trigonometric computations I think the *second* is *much*
more readable. I'm using the well-known cosine function - that this was
imported from the math module is pure noise.

For other functions this may be less clear. I tend to use the first
style more often, although that gets a bit verbose sometimes
(os.path.join(os.path.dirname(...), ...)), And I do notice that the
second style seems to be preferred in Django.

>   But I assume that the second might use
>   one less name lookup and therefore is faster. What is the
>   one way to do it?)

I'm not worried about performance unless there is clear performance
advantage (for real programs, not benchmarks).

hp

-- 
   _  | Peter J. Holzer| Fluch der elektronischen Textverarbeitung:
|_|_) || Man feilt solange an seinen Text um, bis
| |   | h...@hjp.at | die Satzbestandteile des Satzes nicht mehr
__/   | http://www.hjp.at/ | zusammenpaßt. -- Ralph Babel
-- 
https://mail.python.org/mailman/listinfo/python-list