Coding style

A

Antoon Pardon

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.
 
A

Antoon Pardon

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.
 
B

Bruno Desthuilliers

Lawrence said:
In message <[email protected]>, Bruno Desthuilliers
wrote:




A _proper_ boolean type would _have_ to be used in conditionals.

Try using something that cannot be fed to bool() into a conditional.
Not simply enough.

Then it's a documentation problem.
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().
Not sure this has anything with what I was saying.

You said:
""""""

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>)
 
D

Donn Cave

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, (e-mail address removed)
 
D

Dennis Lee Bieber

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)


--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
A

Antoon Pardon

<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.



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.
 
G

Gerhard Fiedler

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.

In general, I'd say that in this case the example was not well-chosen.
After such a "shudder removal", a poster should IMO review what caused the
shudder, and rephrase the original problem without the shudder. That might
take a few iterations, but in general, either one or more of the "shudder
removals" actually address the OP's issue, maybe without any individual
helper understanding all of the problem (due to incomplete example code),
or the iterations lead to a code that's "shudder free" and still shows the
original problem -- now usually in a clearer form, because free of other
issues that are not relevant to the OP's point.

E.g. if someone makes a suggestion that is valid with the example code I
posted but not with the real code I have, I need to post an updated example
code that introduces a restriction similar to the one I actually have,
which then correctly invalidates the formerly valid suggestion -- and helps
getting more helpful responses. This is a process that in the past has
taught me a lot (not Python, but that's just because I'm too new here :).
Once you get good at this process, it often helps you find the problem even
before posting, because boiling code down to what the /real/ problem is can
show you a lot you otherwise miss.

(In case that sounds too general -- it is <g>. But it answers a general
point...)

Gerhard
 
D

Dennis Lee Bieber

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.

You miss one factor -- the specification of what the code sample is
supposed to handle. Showing a sample of code which may reproduce an
apparent problem, without stating /all/ the requirements of the
data/process, leaves the reviewer in the state of assuming all the
conditions are explicit in the code. And in the case of your sample --
that just isn't true. The try/except block is too general, and seems to
imply that the exception might be raised in either (or both) foo() or
bar() -- it is not clear that the try/except is being used to detect an
unstated exit condition requirement.

Formal (or even informal but written) requirements would have
revealed the needs to anyone:

1 <such and such> shall invoke foo() when the input data consists of a
non-empty list

2 <such and such> shall invoke bar() when the input data consists of
an empty data list

3a <such and such> shall loop until the specified exit condition occurs

3b <such and such> shall exit the loop when the input data consists of
a None object
--
Wulfraed Dennis Lee Bieber KD6MOG
(e-mail address removed) (e-mail address removed)
HTTP://wlfraed.home.netcom.com/
(Bestiaria Support Staff: (e-mail address removed))
HTTP://www.bestiaria.com/
 
B

Bruno Desthuilliers

Lawrence D'Oliveiro a écrit :
(snip)


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.

I somewhat agree with Laura Craighton (cf Donn's post above in this
thread). Things were clearer when there was no boolean type in Python,
and we just had the difference between 'nothing' (empty sequence, zero
numeric, None) and 'something' (almost anything else).
 
A

Antoon Pardon

You miss one factor -- the specification of what the code sample is
supposed to handle. Showing a sample of code which may reproduce an
apparent problem, without stating /all/ the requirements of the
data/process, leaves the reviewer in the state of assuming all the
conditions are explicit in the code.

No that leaves the reviewer in the state of assuming all *relevant*
conditions are explicit in the code.
And in the case of your sample --
that just isn't true. The try/except block is too general, and seems to
imply that the exception might be raised in either (or both) foo() or
bar()

Which in this case is totally irrelevant. The try/except block
was not part of the code that would have been posetd to the
newsgroup.
-- it is not clear that the try/except is being used to detect an
unstated exit condition requirement.

Again irrelevant. This was an example where someone had trouble
with his code (the try/except statement) which he would then
reduce to a minimal piece of code that would still show the
trouble some behaviour (Just the then part of an if statement)
which he would then post to the list.

All trouble with the so called original code is totally irrelevant
to the point I was trying to make and the more you try to critisize
it the more you are an illustration of the point I am trying to make.

This remark was just under that example code in my originle
article:

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.

What didn't you understand about the code just meant to be an
illustration.
 
A

Antoon Pardon

In general, I'd say that in this case the example was not well-chosen.
After such a "shudder removal", a poster should IMO review what caused the
shudder, and rephrase the original problem without the shudder.

The shudder is not with the poster. The poster can't predict how
the readers will react.
That might
take a few iterations, but in general, either one or more of the "shudder
removals" actually address the OP's issue, maybe without any individual
helper understanding all of the problem (due to incomplete example code),
or the iterations lead to a code that's "shudder free" and still shows the
original problem -- now usually in a clearer form, because free of other
issues that are not relevant to the OP's point.

I doubt that. My experience is that you have more chance of being helped
by people who try to understand where the OP is trying to go form than
from those who react to style issues. I have never seem a bug go away
because someone suggested to write "if Number:" instead of "if Number != 0:"
E.g. if someone makes a suggestion that is valid with the example code I
posted but not with the real code I have, I need to post an updated example
code that introduces a restriction similar to the one I actually have,
which then correctly invalidates the formerly valid suggestion -- and helps
getting more helpful responses.

Not necessarily. A valid suggestion doesn't imply a relevant suggestion.

If someone come with code like:

if Number != 0:

And someone suggests that the python idiom is

if Number:

Then that suggestion is valid, but it also is irrelevant. A bug doesn't
disappear because the latter is the python idiom for the former.
This is a process that in the past has
taught me a lot (not Python, but that's just because I'm too new here :).
Once you get good at this process, it often helps you find the problem even
before posting, because boiling code down to what the /real/ problem is can
show you a lot you otherwise miss.

Sure, but if you do that, you sometimes have code that deviates from
the python idiom because there was originnaly a good reason for, but
that isn't obvious any more because you are temporarily working with
a boiled down piece of code. People making suggestions on how to
make that boiled down code look more pythonic by using the python
idiom are IMO not very helpfull because essentially those are just
aesthetic.
 
G

Gerhard Fiedler

The shudder is not with the poster. The poster can't predict how the
readers will react.

Correct. But if someone with the potential to help shudders, I might just
rephrase my "question" (the code) to suit that person's preferences. Why
not?
I doubt that.

I'm not sure, but I've seen in the short time I've been here that a few of
the regulars both have their specific "shudder" issues, and post helpful
alternative solutions and corrections. So I think it definitely can help to
address their "shudder" issues and get this out of the way.
My experience is that you have more chance of being helped by people who
try to understand where the OP is trying to go form than from those who
react to style issues.

No contest to that. But why not talk to the others, who in a way insist on
their idiom but otherwise contribute to helpful solutions, in their idiom?
I have never seem a bug go away because someone suggested to write "if
Number:" instead of "if Number != 0:"

Of course. I didn't mean to imply this. But if the only thing that's
required from me is to rephrase my code idiom and replace the "number != 0"
comparisons with "number", that's a small price to pay.

You are right, IMO, that this stuff comes over as petty sometimes. And that
it often is far away from the original question. But just as often
corrections that at first seem petty lead to different ideas about
implementation that the OP didn't consider.

My view is: I ask for help on a public forum. I get what I get... and if I
consider that someone who responded with something that's not immediately
helpful has a potential to help me better, I try to get in a dialog and
address what has been suggested, carving out my real problem in the idiom
of that person. This is my responsibility -- after all, I'm the one who
wants to learn how that person would solve my problem. Later then I can try
to separate what I want to use from that solution from what I consider
personal preference of the helping person.

Not necessarily. A valid suggestion doesn't imply a relevant suggestion.

If someone come with code like:

if Number != 0:

And someone suggests that the python idiom is

if Number:

Then that suggestion is valid, but it also is irrelevant.

Correct. But if it helps the person who suggested it to see the original
problem, now not hidden (for that person) under offending idiom, then the
change was relevant -- not for the problem, but for the communication about
it.

It's like if you want good stock advice from your uncle, who's experienced
in the matter but very formal, ask him without using the f*** word. You can
use it when asking your other uncle, who's also experienced but doesn't
really care about formalities. Tune in if you want a good channel...

Sure, but if you do that, you sometimes have code that deviates from the
python idiom because there was originnaly a good reason for, but that
isn't obvious any more because you are temporarily working with a boiled
down piece of code. People making suggestions on how to make that boiled
down code look more pythonic by using the python idiom are IMO not very
helpfull because essentially those are just aesthetic.

I agree that mere aesthetic changes usually don't address the problem in
itself. But it's just like posting here in a distant Chinese dialect won't
do you any good (and neither in a distant, say, Scottish dialect :). If you
want to get up a helpful communication, you need to use the right language.
Here it is English and Python :) and if making my example code more
pythonic (and my textual part more English) helps me creating a better
communication about the issue I'm interested in, that's what I do (and what
I'd recommend everybody else to do).

If there is a valid reason for a part of the code being different
("non-pythonic"), and that difference may be relevant, then there's a way
to show that reason in the example code. It may be that exactly this
process of boiling the code down to the relevant pieces shows you the
answer. That happens more often than most people realize, and is a process
that's quite valuable.

To apply that to your example... If there's no particular reason to write
"number != 0", then just repost the problem code with "number" instead and
you're done. But if there's a reason, try to set up your example code so it
shows that reason. This both helps people understand your problem better,
and may just show the reason for the problem -- after all, you most often
than not don't know where exactly your problem is, so you're not in a good
position to judge what you can leave out of the code without taking out the
problematic part. So: boil down your code to what shows the problem, and
nothing more, as much as possible, and present it in an idiom that helps
the others to help you.

Gerhard
 
A

Antoon Pardon

Correct. But if someone with the potential to help shudders, I might just
rephrase my "question" (the code) to suit that person's preferences. Why
not?

The point is that the shudder makes people react in an unhelpfull way.
If you think they still can be helpfull and you want to respond in
such a way that makes it more likely they will respond in a helpfull
way, sure go ahead.
I'm not sure, but I've seen in the short time I've been here that a few of
the regulars both have their specific "shudder" issues, and post helpful
alternative solutions and corrections. So I think it definitely can help to
address their "shudder" issues and get this out of the way.

Sure, but it takes time. Not everyone thinks it is worth that time.
No contest to that. But why not talk to the others, who in a way insist on
their idiom but otherwise contribute to helpful solutions, in their idiom?

That is what each person has to decide for by himself. My personal
experience is others usually have come with equally usefull
contributions without losing time harping on Python idiom.
Your milage may vary.
My view is: I ask for help on a public forum. I get what I get... and if I
consider that someone who responded with something that's not immediately
helpful has a potential to help me better, I try to get in a dialog and
address what has been suggested, carving out my real problem in the idiom
of that person. This is my responsibility -- after all, I'm the one who
wants to learn how that person would solve my problem. Later then I can try
to separate what I want to use from that solution from what I consider
personal preference of the helping person.

It all depends. If that person is one of many that responded, I may
think it is not worth my time to find out how this particular person
would solve my problem. If he seems to be the only one who has a clue
I may be more inclined to get that dialog started.
Correct. But if it helps the person who suggested it to see the original
problem, now not hidden (for that person) under offending idiom, then the
change was relevant -- not for the problem, but for the communication about
it.

It's like if you want good stock advice from your uncle, who's experienced
in the matter but very formal, ask him without using the f*** word. You can
use it when asking your other uncle, who's also experienced but doesn't
really care about formalities. Tune in if you want a good channel...

That is one side of the coin. The other side is that if the formal
uncle is heard a lot without someone contradicting him from time
to time, then all the newbies will think that formal is the
way to go, creating a lot more people who are somewhat uptight.
causing a lot of time to go into getting things formal instead
of solving the problem.
I agree that mere aesthetic changes usually don't address the problem in
itself. But it's just like posting here in a distant Chinese dialect won't
do you any good (and neither in a distant, say, Scottish dialect :). If you
want to get up a helpful communication, you need to use the right language.
Here it is English and Python :) and if making my example code more
pythonic (and my textual part more English) helps me creating a better
communication about the issue I'm interested in, that's what I do (and what
I'd recommend everybody else to do).

If there is a valid reason for a part of the code being different
("non-pythonic"), and that difference may be relevant, then there's a way
to show that reason in the example code. It may be that exactly this
process of boiling the code down to the relevant pieces shows you the
answer. That happens more often than most people realize, and is a process
that's quite valuable.

To apply that to your example... If there's no particular reason to write
"number != 0", then just repost the problem code with "number" instead and
you're done. But if there's a reason, try to set up your example code so it
shows that reason.

This goes against the advise that is given here and in other language and
programming groups: If you have a problem with particular behaviour (a
bug) reduce your program to the minimal that still produces the trouble
some behaviour.
This both helps people understand your problem better,

Sure, but it seems there are people who can tangle the problem without
knowing whether or not there is a reason. They just look at the code
and figure out what it does, whithout bothering about how it should
look like and in the end that is the most helpfull attitude.
and may just show the reason for the problem -- after all, you most often
than not don't know where exactly your problem is, so you're not in a good
position to judge what you can leave out of the code without taking out the
problematic part. So: boil down your code to what shows the problem, and
nothing more, as much as possible, and present it in an idiom that helps
the others to help you.

I don't know. It seems a waste of time a lot of the times. If I'm
talking with someone in real life about a problem and I get the
feeling that person is more interested in me wording the problem
in the proper formal way instead of caring about the problem itself,
I probably consider not longer bothering this person with my problems
unless there seems to be no alternative.

I think the same applies to newsgroups.
 
G

Gerhard Fiedler

It all depends. If that person is one of many that responded, I may
think it is not worth my time to find out how this particular person
would solve my problem. If he seems to be the only one who has a clue I
may be more inclined to get that dialog started.

Exactly. If there are people more tuned into your channel, that's where
you're more inclined to go. If not, you tune into some other's channel.

That is one side of the coin. The other side is that if the formal uncle
is heard a lot without someone contradicting him from time to time, then
all the newbies will think that formal is the way to go, creating a lot
more people who are somewhat uptight. causing a lot of time to go into
getting things formal instead of solving the problem.

"So what?", I'm inclined to ask <g> If someone does something without
knowing why, I'm not really bursting of sympathy. In real life, I've found
that there isn't that much I have to invest to get the channel clean, so to
speak. And where I think it's too much, I don't do it. I don't see much of
a difference here.

You definitely have a point in that some of that is not necessary. But
then... there's so much in a typical communication situation that is not
(objectively) necessary :)

This goes against the advise that is given here and in other language and
programming groups: If you have a problem with particular behaviour (a
bug) reduce your program to the minimal that still produces the trouble
some behaviour.

Right... why against that? The minimal and communicable piece of code that
shows the problem. That's what I'm saying. To apply that to the example: if
the difference between the two styles is not relevant and "number" alone is
enough to reproduce the problem, post the code using "number". If "number
!= 0" is necessary to reproduce the problem, add some code that shows /why/
you have to use "number != 0" and can't use the simple "number". It may be
part of the problem.

Sure, but it seems there are people who can tangle the problem without
knowing whether or not there is a reason. They just look at the code
and figure out what it does, whithout bothering about how it should
look like and in the end that is the most helpfull attitude.

Sometimes. Sometimes digging deeper may be helpful, too. But nobody's
perfect anyway, so just pick up what suits you :)

Gerhard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,165
Latest member
JavierBrak
Top