Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Python (http://www.velocityreviews.com/forums/f43-python.html)
-   -   Good code patterns in Python (http://www.velocityreviews.com/forums/t319053-good-code-patterns-in-python.html)

Will Stuyvesant 07-01-2003 09:49 AM

Good code patterns in Python
 
If you know that your source code is going to be used
later by others, then I feel that code with the pattern:

if some_condition:
some_name = some_value
else:
some_name = other_value

is often a mistake. Much better, safer, would be:

some_name = some_value
if not some_condition:
some_name = other_value

Why?

Because those people reusing your code might decide to
change or adapt the "if" part of the first example. Or
the "else" part for that matter. And then they could end
up with "some_name" being undefined, crashing other code
maybe 1000's of lines away. This could happen for example
because they use exceptions in the "if" part that jump out
of it, etc.

There is the small overhead of assigning something twice
to some_name in the safer example, so if performance is
*that* important then the first example is better, but I
feel there should be comments with warnings around it:
**CREATING A NEW OBJECT REFERENCE HERE!** Hmm, now that
makes code ugly :-)

What are your thoughts about this? I am interested in
current large scale software development practice, and
guidelines that are used there, especially for dynamically
typed languages like Python.

There must be a lot of advisable code design patterns (I
can't find a good name in English) like this for use in
software development with many programmers. Perhaps a
collection with good documentation would be interesting?
Or a tool like pychecker that flags "bad" patterns?


--
People who miss goto now use exceptions

Terry Reedy 07-01-2003 04:31 PM

Re: Good code patterns in Python
 

"Will Stuyvesant" <hwlgw@hotmail.com> wrote in message
news:cb035744.0307010149.399df2eb@posting.google.c om...
> If you know that your source code is going to be used
> later by others, then I feel that code with the pattern:
>
> if some_condition:
> some_name = some_value
> else:
> some_name = other_value
>
> is often a mistake. Much better, safer, would be:
>
> some_name = some_value
> if not some_condition:
> some_name = other_value


If, bool(some_value) == True, I personally would use the near-ternary
idiom

some_name = some_condition and some_value or other_value

(or equivalent form for bool(other_value)== True or either == False).

This is both safe and efficient, avoiding both

> Because those people reusing your code might decide to
> change or adapt the "if" part of the first example. Or
> the "else" part for that matter. And then they could end
> up with "some_name" being undefined, crashing other code
> maybe 1000's of lines away.


and

> There is the small overhead of assigning something twice


(I acknowledge that some think this ugly and worse and would not be
caught dead writing such an 'abomination', so flame repetition is not
necessary ;-)

Terry J. Reedy



Jiri Barton 07-01-2003 04:38 PM

Re: Good code patterns in Python
 
One, there has been a proposal for a ternary operator on python.org. You
know that kind of (cond) ? (eval1) : (eval2) stuff.

Two, no need to guard that code. Passing and assigning a paramater should
always make you THINK about what's happening.

Three, how about
a = 1
b = 0
......
if b == 0:
a = 0
else:
a = a/b
? You cannot replace it with your pattern. Sure enough, there are far more
examples of this -- when you cannot evaluate the first expression.

Jiri Barton





Steven Taschuk 07-01-2003 06:26 PM

Re: Good code patterns in Python
 
Quoth Will Stuyvesant:
> If you know that your source code is going to be used
> later by others, then I feel that code with the pattern:
>
> if some_condition:
> some_name = some_value
> else:
> some_name = other_value
>
> is often a mistake. Much better, safer, would be:
>
> some_name = some_value
> if not some_condition:
> some_name = other_value


I join the Ms in disagreeing strongly. The visual parallelism of
the first reflects the conceptual parallelism of the two cases,
while the second obscures it.

> Because those people reusing your code might decide to
> change or adapt the "if" part of the first example. Or
> the "else" part for that matter. And then they could end
> up with "some_name" being undefined, crashing other code
> maybe 1000's of lines away. This could happen for example
> because they use exceptions in the "if" part that jump out
> of it, etc.


I assume you're not speaking of local variables here -- a function
thousands of lines long would be unconscionable.

Presumably you're speaking of attributes, and the danger is that
an exception in one branch would cause the object's invariants be
broken. But I don't see how this would happen in practice, in a
way which would (a) leave the attribute undefined and (b) imply to
the caller that everything was fine. Do you have an example?

(Much more serious and more common is the danger that after an
exception is raised, the function has done half its work and left
the object in a broken state. But this has nothing to do with
what you're talking about.)

> There is the small overhead of assigning something twice


Too minor to worry about:

$ timeit -s'def foo(): global a; a = 1' 'foo()'
100000 loops, best of 3: 5.51 usec per loop
$ timeit -s'def foo(): global a; a = 1; a = 1' 'foo()'
100000 loops, best of 3: 6.1 usec per loop

If I'm running the code a million times, and everything else in
the loop takes less than a microsecond, this might be worth
thinking about.

--
Steven Taschuk w_w
staschuk@telusplanet.net ,-= U
1 1


Lulu of the Lotus-Eaters 07-01-2003 06:26 PM

Re: Good code patterns in Python
 
|hwlgw@hotmail.com (Will Stuyvesant) wrote:
|> if some_condition:
|> some_name = some_value
|> else:
|> some_name = other_value
|> is often a mistake. Much better, safer, would be:
|> some_name = some_value
|> if not some_condition:
|> some_name = other_value

mis6@pitt.edu (Michele Simionato) wrote previously:
|I am sorry, but I feel that the first form is MUCH more readable than the
|second one; the first form is crystal clear to me, whereas I must read
|the second form two or three times to understand what it is going on.

Moreover, actual code often assigns from computations, not simply one
name to another. The harder-to-read form risks bad side effects (or
simply a performance hit):

some_name = some_computation()
if not some_condition:
some_name = other_computation()

The straightforward if/else form avoids superfluous computations.

Yours, Lulu...

--
mertz@ _/_/_/_/_/_/_/ THIS MESSAGE WAS BROUGHT TO YOU BY:_/_/_/_/ v i
gnosis _/_/ Postmodern Enterprises _/_/ s r
..cx _/_/ MAKERS OF CHAOS.... _/_/ i u
_/_/_/_/_/ LOOK FOR IT IN A NEIGHBORHOOD NEAR YOU_/_/_/_/_/ g s



Dennis Lee Bieber 07-02-2003 04:58 AM

Re: Good code patterns in Python
 
Will Stuyvesant fed this fish to the penguins on Tuesday 01 July 2003
02:49 am:

>
> some_name = some_value
> if not some_condition:
> some_name = other_value
>

Ugh... Shades of old BASIC...

10 sn = sv
20 if sc then 40
30 sn = ov
40 ...

--
> ================================================== ============ <
> wlfraed@ix.netcom.com | Wulfraed Dennis Lee Bieber KD6MOG <
> wulfraed@dm.net | Bestiaria Support Staff <
> ================================================== ============ <
> Bestiaria Home Page: http://www.beastie.dm.net/ <
> Home Page: http://www.dm.net/~wulfraed/ <



Kirk Job-Sluder 07-02-2003 06:48 AM

Re: Good code patterns in Python
 
Will Stuyvesant <hwlgw@hotmail.com> wrote:
> If you know that your source code is going to be used
> later by others, then I feel that code with the pattern:
>
> if some_condition:
> some_name = some_value
> else:
> some_name = other_value
>
> is often a mistake. Much better, safer, would be:
>
> some_name = some_value
> if not some_condition:
> some_name = other_value
>
> Why?


My personal opinion is that it depends on context. The first idiom
is more clear when you are dealing with some kind of a switch. The
second idiom works better if you have a default value that needs to be
overridden in some cases.

> Because those people reusing your code might decide to
> change or adapt the "if" part of the first example. Or
> the "else" part for that matter. And then they could end
> up with "some_name" being undefined, crashing other code
> maybe 1000's of lines away. This could happen for example
> because they use exceptions in the "if" part that jump out
> of it, etc.


Of course, another alternative is to combine both approaches by setting
a default value:

#set default for some_value
some_value = []
if condition1:
some_value = function1()
else:
some_value = function2()

And then if you really want to be safe the functions using
some_value should do reality checks as well.
def function3(some_value=[]):
if len(some_value):
do something
else:
do something else.

I think that an argument for the readability of if-else is that because
the logic is made more clear, it can be more effectively replaced.


> There is the small overhead of assigning something twice
> to some_name in the safer example, so if performance is
> *that* important then the first example is better, but I
> feel there should be comments with warnings around it:
> **CREATING A NEW OBJECT REFERENCE HERE!** Hmm, now that
> makes code ugly :-)


The problem here is that ***creating a new object reference*** is not
only ugly, but its ambiguous as well. (What kind of object, what is it
used for?) If indeed some_name is an important variable in your program,
then provide a full description.

#some_value (string) is used to hold the widgit that will
#be passed to a wadget and eventually passed
#to standard output.

--
Kirk Job-Sluder
http://www.jobsluder.net/~kirk/


Erik Max Francis 07-02-2003 07:12 AM

Re: Good code patterns in Python
 
Kirk Job-Sluder wrote:

> Will Stuyvesant <hwlgw@hotmail.com> wrote:
>
> > If you know that your source code is going to be used
> > later by others, then I feel that code with the pattern:
> >
> > if some_condition:
> > some_name = some_value
> > else:
> > some_name = other_value
> >
> > is often a mistake. Much better, safer, would be:
> >
> > some_name = some_value
> > if not some_condition:
> > some_name = other_value
> >
> > Why?

>
> My personal opinion is that it depends on context. The first idiom
> is more clear when you are dealing with some kind of a switch. The
> second idiom works better if you have a default value that needs to be
> overridden in some cases.


I presume the "mistake" he's referring to with the first snippet is the
potential problem that could happen if the variable is named
incorrectly:

if condition:
variable = someValue
else:
varaible = otherValue # [sic] note the typo!

When you really want an atomic assignment of one singular variable. The
complete solution to this would probably be a conditional expression,
e.g.:

variable = (if condition: someValue else: otherValue)

eliminating the duplication which can lead to errors. (Python, of
course, doesn't have such a construct, and the silence after the
conditional expression PEP vote and the long silence thereafter suggests
that it never will.)

I still don't think this significant of a risk to warrant widespread
conversion of statements to the form Will suggests, especially when you
have things like PyChecker that can check for (probable) typos. It's a
slightly unfortunate wart in dynamic languages without conditional
operators, but I don't think it rises to the level of something that
should be corrected via such (what seems to me) a heavy-handed style.

--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ When the solution is simple, God is answering.
\__/ Albert Einstein

Bernhard Herzog 07-02-2003 11:06 AM

Re: Good code patterns in Python
 
Erik Max Francis <max@alcyone.com> writes:

> The
> complete solution to this would probably be a conditional expression,
> e.g.:
>
> variable = (if condition: someValue else: otherValue)
>
> eliminating the duplication which can lead to errors. (Python, of
> course, doesn't have such a construct, and the silence after the
> conditional expression PEP vote and the long silence thereafter suggests
> that it never will.)


Guido broke his silence at EuroPython: The ternary operator will not be
added to Python.

Bernhard

--
Intevation GmbH http://intevation.de/
Sketch http://sketch.sourceforge.net/
MapIt! http://www.mapit.de/

Erik Max Francis 07-02-2003 10:16 PM

Re: Good code patterns in Python
 
Bernhard Herzog wrote:

> Guido broke his silence at EuroPython: The ternary operator will not
> be
> added to Python.


As I said, it's hardly a big surprise.

--
Erik Max Francis && max@alcyone.com && http://www.alcyone.com/max/
__ San Jose, CA, USA && 37 20 N 121 53 W && &tSftDotIotE
/ \ Divorces are made in Heaven.
\__/ Oscar Wilde


All times are GMT. The time now is 04:52 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.