|
|
|
|
|
|
| Author |
Message |
pavlovevidence@gmail.com *nix forums beginner
Joined: 17 Jul 2006
Posts: 17
|
Posted: Wed Jul 19, 2006 7:15 pm Post subject:
Re: Coding style
|
|
|
Patrick Maupin wrote:
| Quote: | The original post did not say "this function is iterating twice over
the same data." It only said that there might be a significant
computational cost on an empty iterator, and wished that the code would
somehow throw an exception to alert the programmer to this cost.
|
You're misrepresenting what I said. Cost was merely the
best-case-scenario. Bugs could arise if, say, the finalization
silently depends on non-empty iterable.
| Quote: | But this is still not a good reason why, in the general
case, "if len(lst)" should be preferred over "if lst".
|
Whatever. The OP asked for a reason one should be preferred over the
other; this was simply one reason to use "if len(lst)>0". Not good
enough for you? Fine, you still have all the reasons to continue to
use "if lst" (as opposed to just bashing "if len(lst)>0") that you and
others have shared with us in this thread.
(Wait a second....)
Carl Banks |
|
| Back to top |
|
 |
Donn Cave *nix forums Guru Wannabe
Joined: 20 Feb 2005
Posts: 172
|
Posted: Wed Jul 19, 2006 8:45 pm Post subject:
Re: Coding style
|
|
|
In article <e9ksvr$g8u$1@news.albasani.net>,
Georg Brandl <g.brandl-nospam@gmx.net> wrote:
| Quote: | Lawrence D'Oliveiro wrote:
One of my rules is, always program like the language actually has a Boolean
type, even if it doesn't. That means, never assume that arbitrary values
can be interpreted as true or false, always put in an explicit comparison
if necessary so it's obvious the expression is a Boolean.
You can do that, but it's not considered Pythonic. And it might be
ineffective.
Other than in PHP, Python has clear rules when an object of a builtin type
is considered false (i.e. when it's empty). So why not take advantage of
this?
|
I don't know whether she would welcome this or not, but here
I provide an archive link to a classic post by Laura Creighton
on this matter:
http://groups.google.com/group/comp.lang.python/msg/2de5e1c8384c0360
It's lengthy but very readable, and for me it has that quality of
exposition where you feel at first reading as though you had
already known all that -- even if you really hadn't.
But I don't know where she is today, or the Python she was
writing about.
Donn Cave, donn@u.washington.edu |
|
| Back to top |
|
 |
Patrick Maupin *nix forums beginner
Joined: 23 Jun 2005
Posts: 32
|
Posted: Thu Jul 20, 2006 4:25 am Post subject:
Re: Coding style
|
|
|
Terry Reedy wrote:
| Quote: |
Carl Banks wrote:
def process_values(lst):
if not lst:
return
do_expensive_initialization_step()
for item in lst:
do_something_with(item)
do_expensive_finalization_step()
Given that the input is going to be scanned by an iterator, it really makes
sense to me to accept an iterator as input. (Unless the function is for
special-case usage in a predefined, never to be expanded, set of
circumstances in which such generality is not needed. In such a case, if
lst: is no problem.) I think the following, untested rewrite suffices.
def process_values(lst):
it = iter(lst)
try:
item = it.next()
do_expensive_initialization_step()
do_something_with(item) # see note
for item in it:
do_something_with(item)
do_expensive_finalization_step()
except StopIteration:
pass # or any special empty input code
# note: if writing do_something_with(item) is bothersome,
# replace 3 lines with
while True:
do_something_with(item)
try:
item = it.next
except StopIteration:
break
In general, to work with iterators instead of containers, change
if container:
do_stuff()
else:
do_empty()
to
try:
item = it.next()
do_modified_stuff() # taking into account that have item already
except StopIteration:
do_empty()
|
Good example. But if you want, you can also do the same thing
without explicitly dealing with StopIteration exceptions, by (ab)using
the for statment to deal with the StopIteration exceptions implicitly
for you:
def process_values(lst):
it = iter(lst)
# This for statement executes 0 or 1 times
for item in it:
do_expensive_initialization_step()
do_something_with(item)
break
else:
# Empty list code, if needed, goes here...
return
# This for statement executes max(0, len(lst) - 1) times
for item in it:
do_something_with(item)
do_expensive_finalization_step()
And, of course, if you really want to defer optimizations, and you
expect the code to not be in a critical speed path and to not be passed
huge lists or iterators, you could take the original function and add:
lst = list(lst)
as the first line. Frankly, if I had a working function in a piece of
code, and then a failure because it was being called with a generator,
I would find this very tempting unless I strongly suspected it would
cause issues later.
Regards,
Pat |
|
| Back to top |
|
 |
Lawrence D'Oliveiro *nix forums Guru
Joined: 25 Mar 2005
Posts: 723
|
Posted: Thu Jul 20, 2006 5:47 am Post subject:
Re: Coding style
|
|
|
In message <e9ksvr$g8u$1@news.albasani.net>, Georg Brandl wrote:
| Quote: | Lawrence D'Oliveiro wrote:
In message <Q8OdnfqZn6udnSHZnZ2dnUVZ_vOdnZ2d@nmt.edu>, Bob Greschke
wrote:
I'd go even one step further. Turn it into English (or your favorite
non-computer language):
1. While list, pop.
2. While the length of the list is greater than 0, pop.
Which one makes more sense? Guess which one I like. CPU cycles be
damned.
:)
One of my rules is, always program like the language actually has a
Boolean type, even if it doesn't. That means, never assume that arbitrary
values can be interpreted as true or false, always put in an explicit
comparison if necessary so it's obvious the expression is a Boolean.
You can do that, but it's not considered Pythonic. And it might be
ineffective.
Other than in PHP, Python has clear rules when an object of a builtin type
is considered false (i.e. when it's empty). So why not take advantage of
this?
|
Because the clearest rule of all is that True is true, and False is false,
and that's all I want to have to remember. |
|
| Back to top |
|
 |
Antoon Pardon *nix forums Guru
Joined: 21 Feb 2005
Posts: 483
|
Posted: Thu Jul 20, 2006 7:32 am Post subject:
Re: Coding style
|
|
|
On 2006-07-19, Georg Brandl <g.brandl-nospam@gmx.net> wrote:
| Quote: | Antoon Pardon wrote:
Other than in PHP, Python has clear rules when an object of a builtin type
is considered false (i.e. when it's empty). So why not take advantage of
this?
Because it doesn't always do what I want.
I once had a producer consumer code. When the client asked whether new
items were available the function could return three different values
1) a list with items, to be consumed
2) an empty list (meaning there were no items available for the
moment but there could be in the future
3) None (meaning the producer was done)
Just testing for the truth value of the returned result in order
to see whether the client should continue or not would often
have made the client exit prematurely.
IME such cases where testing for the truth value of an object
don't give the expected result, happen often enough to make me
carefully think about what I want to test for and then explicitly
do so.
You're right, carefully thinking is always a good thing. Not using a
language feature just because it would fail in another case is not.
|
I would say the opposite is just as true. Using a language feature
just because it happens to give the right answer, is not a good thing.
You don't know how your code will evolve and my experience is that the
lesser you use this feature, the lesser the chance you will have
to track a nasty bug later.
--
Antoon Pardon |
|
| Back to top |
|
 |
Antoon Pardon *nix forums Guru
Joined: 21 Feb 2005
Posts: 483
|
Posted: Thu Jul 20, 2006 7:50 am Post subject:
Re: Coding style
|
|
|
On 2006-07-19, Donn Cave <donn@u.washington.edu> wrote:
| Quote: | In article <e9ksvr$g8u$1@news.albasani.net>,
Georg Brandl <g.brandl-nospam@gmx.net> wrote:
Lawrence D'Oliveiro wrote:
One of my rules is, always program like the language actually has a Boolean
type, even if it doesn't. That means, never assume that arbitrary values
can be interpreted as true or false, always put in an explicit comparison
if necessary so it's obvious the expression is a Boolean.
You can do that, but it's not considered Pythonic. And it might be
ineffective.
Other than in PHP, Python has clear rules when an object of a builtin type
is considered false (i.e. when it's empty). So why not take advantage of
this?
I don't know whether she would welcome this or not, but here
I provide an archive link to a classic post by Laura Creighton
on this matter:
http://groups.google.com/group/comp.lang.python/msg/2de5e1c8384c0360
It's lengthy but very readable, and for me it has that quality of
exposition where you feel at first reading as though you had
already known all that -- even if you really hadn't.
|
Well for me it wasn't, I don't agree with it at all.
IMO, whether something is to be considered "True" or "False"
is application dependent. There are cases where I would
consider an empty sequence as True, because a sequence in
itself would mean, continue and the members would be
the current available elements to be processed.
Nothing is IMO not specific enough and doesn't make
the disctinction between nothing (temporarily) now
and nothing more (for ever).
That is why I think the distinction between True and
False is more usefull than the distinction between
nothing and something.
--
Antoon Pardon |
|
| Back to top |
|
 |
Antoon Pardon *nix forums Guru
Joined: 21 Feb 2005
Posts: 483
|
Posted: Thu Jul 20, 2006 8:50 am Post subject:
Re: Coding style
|
|
|
On 2006-07-19, Dennis Lee Bieber <wlfraed@ix.netcom.com> wrote:
| Quote: | On 19 Jul 2006 12:27:39 GMT, Antoon Pardon <apardon@forel.vub.ac.be
declaimed the following in comp.lang.python:
I once had a producer consumer code. When the client asked whether new
items were available the function could return three different values
1) a list with items, to be consumed
2) an empty list (meaning there were no items available for the
moment but there could be in the future
3) None (meaning the producer was done)
You have a documented interface with a tri-state return... For this
situation, you would need the explicit test... I'd probably end up with
something like
while True:
retrn = function()
if retrn is None:
break
elif retrn:
consume
|
The problem is how people here react:
Suppose I have the following kind of code:
while True:
try:
if len(result) > 0:
foo()
else
bar()
except TypeError:
break
This code makes the distinction between the three possibilities,
whether it is a good way or not I won't discuss, this is just
meant as an illustration.
Now I have a problem with the code between the if and else, so
I come to the newsgroup and post something like:
I have a problem with the following kind of code, it seems
to do blob, but I would have expected blib.
if len(result) > 0:
foo()
else:
...
And before you know it someone will respond that I shouldn't
use
if len(result) > 0:
but should just use:
if result:
Which isn't at all helpfull with my original problem, but would
be wrong in the context where the code is actually used.
--
Antoon Pardon |
|
| Back to top |
|
 |
bruno modulix *nix forums Guru
Joined: 21 Feb 2005
Posts: 819
|
Posted: Thu Jul 20, 2006 9:34 am Post subject:
Re: Coding style
|
|
|
Lawrence D'Oliveiro wrote:
| Quote: | In message <44bcaa47$0$18293$636a55ce@news.free.fr>, Bruno Desthuilliers
wrote:
Lawrence D'Oliveiro wrote:
In message <Q8OdnfqZn6udnSHZnZ2dnUVZ_vOdnZ2d@nmt.edu>, Bob Greschke
wrote:
I'd go even one step further. Turn it into English (or your favorite
non-computer language):
1. While list, pop.
2. While the length of the list is greater than 0, pop.
Which one makes more sense? Guess which one I like. CPU cycles be
damned.
:)
One of my rules is, always program like the language actually has a
Boolean type, even if it doesn't.
Python has a boolean type.
A _proper_ boolean type would _have_ to be used in conditionals.
|
Try using something that cannot be fed to bool() into a conditional.
| Quote: |
That means, never assume that arbitrary values
can be interpreted as true or false,
There's nothing to assume, and nothing arbitrary in it.
It's all clearly
defined in whole letters in the language references.
Not simply enough.
|
Then it's a documentation problem.
| Quote: |
always put in an explicit comparison
if necessary so it's obvious the expression is a Boolean.
The fact that the expression is used in the context of a if statement is
clearly enough to denote a boolean expression.
Which is an inconsistent use of the term "boolean" compared to your
statement above that "Python has a boolean type", is it not?
|
No. It is not. A boolean expression is an expression you can pass to
bool().
| Quote: |
Explicitly testing against a boolean is uselessly redundant...
Not sure this has anything with what I was saying.
|
You said:
"""
| Quote: | always put in an explicit comparison
if necessary so it's obvious the expression is a Boolean.
""" |
Since the expression following an if will be handled as if passed to
bool() [1], adding a comparison to True will yield a strictly equivalent
result (True == True => True, False == True => False). From a boolean
logic POV, it's a no-op [2]. So it's useless and redundant.
[1] FWIW, it may be just how it works - I've not checked implementation.
Anyway you can easily verify by yourself that it works the same way.
[2] but it still requires extra work from the interpreter - without
changing anything to the result of the test.
FWIW, what would you rather use:
if <some_exp> == True:
return True
elif <some_exp> == False:
return False
else:
raise "???"
or:
return bool(<some_exp>)
--
bruno desthuilliers
python -c "print '@'.join(['.'.join([w[::-1] for w in p.split('.')]) for
p in 'onurb@xiludom.gro'.split('@')])" |
|
| Back to top |
|
 |
Donn Cave *nix forums Guru Wannabe
Joined: 20 Feb 2005
Posts: 172
|
Posted: Thu Jul 20, 2006 4:33 pm Post subject:
Re: Coding style
|
|
|
In article <slrnebuddu.6ig.apardon@rcpc42.vub.ac.be>,
Antoon Pardon <apardon@forel.vub.ac.be> wrote:
| Quote: | On 2006-07-19, Donn Cave <donn@u.washington.edu> wrote:
....
http://groups.google.com/group/comp.lang.python/msg/2de5e1c8384c0360
It's lengthy but very readable, and for me it has that quality of
exposition where you feel at first reading as though you had
already known all that -- even if you really hadn't.
Well for me it wasn't, I don't agree with it at all.
|
People sometimes ask, "what does `the exception that proves the rule'
mean?"
Donn Cave, donn@u.washington.edu |
|
| Back to top |
|
 |
Dennis Lee Bieber *nix forums Guru
Joined: 05 Mar 2005
Posts: 819
|
Posted: Thu Jul 20, 2006 5:20 pm Post subject:
Re: Coding style
|
|
|
On 20 Jul 2006 08:50:44 GMT, Antoon Pardon <apardon@forel.vub.ac.be>
declaimed the following in comp.lang.python:
| Quote: |
Suppose I have the following kind of code:
while True:
try:
if len(result) > 0:
foo()
else
bar()
except TypeError:
break
This code makes the distinction between the three possibilities,
whether it is a good way or not I won't discuss, this is just
meant as an illustration.
<shudder> I look at that and my first thought is: |
there is no way to tell if foo() or bar() raised TypeError.
In the absence of documentation about a tri-state "result" being
normal, my second thought IS that the len(result) > 0 is redundandant;
bar() should be responsible for properly handling the difference between
None and empty conditions.
A third thought -- foo() and bar() must be implementing hidden
side-effects since the only way out of the loop is by changing result,
and result is not an argument in or out of either foo or bar.
| Quote: | Which isn't at all helpfull with my original problem, but would
be wrong in the context where the code is actually used.
|
Well, in this case, you didn't supply the context (an expected
tri-state return, for example) so most of us would react as to a
two-state model: if result: process data; else: nothing to process
In your above example, I'd probably even skip the elif format
while True:
if result is None: break
if result:
foo()
else:
bar()
It explicitly shows that the value "None" is expected, and is the
signal for loop termination... and that there is different processing
for empty/0 results versus non-empty/non-0 results (and this scheme even
works with scalars, not just sequences)
--
Wulfraed Dennis Lee Bieber KD6MOG
wlfraed@ix.netcom.com wulfraed@bestiaria.com
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: web-asst@bestiaria.com)
HTTP://www.bestiaria.com/ |
|
| Back to top |
|
 |
Antoon Pardon *nix forums Guru
Joined: 21 Feb 2005
Posts: 483
|
Posted: Fri Jul 21, 2006 12:00 pm Post subject:
Re: Coding style
|
|
|
On 2006-07-20, Dennis Lee Bieber <wlfraed@ix.netcom.com> wrote:
| Quote: | On 20 Jul 2006 08:50:44 GMT, Antoon Pardon <apardon@forel.vub.ac.be
declaimed the following in comp.lang.python:
Suppose I have the following kind of code:
while True:
try:
if len(result) > 0:
foo()
else
bar()
except TypeError:
break
This code makes the distinction between the three possibilities,
whether it is a good way or not I won't discuss, this is just
meant as an illustration.
<shudder> I look at that and my first thought is:
there is no way to tell if foo() or bar() raised TypeError.
In the absence of documentation about a tri-state "result" being
normal, my second thought IS that the len(result) > 0 is redundandant;
bar() should be responsible for properly handling the difference between
None and empty conditions.
A third thought -- foo() and bar() must be implementing hidden
side-effects since the only way out of the loop is by changing result,
and result is not an argument in or out of either foo or bar.
Which isn't at all helpfull with my original problem, but would
be wrong in the context where the code is actually used.
Well, in this case, you didn't supply the context (an expected
tri-state return, for example) so most of us would react as to a
two-state model: if result: process data; else: nothing to process
In your above example, I'd probably even skip the elif format
while True:
if result is None: break
if result:
foo()
else:
bar()
It explicitly shows that the value "None" is expected, and is the
signal for loop termination... and that there is different processing
for empty/0 results versus non-empty/non-0 results (and this scheme even
works with scalars, not just sequences)
|
Thank you for illustrating my point so well. What happened here? You saw
some code who made you shudder, and you reacted in a way to get released
from that shudder. Whether that reaction would be helpfull or relevant
to the problem of the original person seems to be unimportant.
What happens a lot is that someone has trouble with some code, a bug
or lack of understanding. So he reduces his code to a sample he can
use as an illustration of the problem and will easily fit in a news
article. That there can be issues with this code is normal, but
fixing the code so that these issues go a way, will probably just
obscure the point that he is trying to make.
So we have code with certain shudder characteristics. And instead
of trying to help the OP with his problem, some people react
to the shudder and come with all sort of comments that might be
true if the code as shown was production code, but which totally
miss the point the code was illustrating and thus aren't much
helpfull.
--
Antoon Pardon |
|
| Back to top |
|
 |
Google
|
|
| Back to top |
|
 |
|
|
The time now is Sat Nov 22, 2008 8:54 pm | All times are GMT
|
|
Camilo jose cela | Loans | Xbox Mod Chip | Mortgage | Credit Card
|
|
Copyright © 2004-2005 DeniX Solutions SRL
|
|
|
|
Other DeniX Solutions sites:
Unix/Linux blog |
electronics forum |
medicine forum |
science forum |
|
|
Privacy Policy
|
Powered by phpBB © 2001, 2005 phpBB Group
|
|