Python indentation deters newbies?

R

Roy Smith

Ok, here is something short but more realistic and IMO not "ugly".

You may want to exit a nested loop when testing if a condition involving
several variables is met, such as searching for a zero of a multivariate
function.

In Python you can print i,j,k and exit() when m == 0, but in a larger program
you may want more control.

program xnest_loop
! find a Pythagorean triple
n = 5
ido: do i=1,n
do j=1,n
ij = i**2 + j**2
do k=1,n
m = ij - k**2
if (m == 0) exit ido
end do
end do
end do ido
if (m == 0) then
print*,i,j,k
else
print*,"no triple"
end if
end program xnest_loop

That's easy (and relatively common). I'd factor out the loop you labled
"ido:" into a separate function, and have your "exit ido" become a
return statement. There's nothing Python-specific about that; I'd use
the same refactoring strategy in C, Fortran, etc. I'm a big fan of
small, easy to understand, functions.
 
J

Jeff Shannon

You may want to exit a nested loop when testing if a condition involving
several variables is met, such as searching for a zero of a multivariate
function.

In Python you can print i,j,k and exit() when m == 0, but in a larger program
you may want more control.

In this case, I can see several Pythonic ways of doing this.

One would be to use an exception. While exceptions are not considered
good control structures in other languages, they *are* considered
acceptable (and even desirable) in Python.

Another way would be to wrap the nested loops inside a function, and
simply return the appropriate triple from that function as soon as you
find it.

An improvement on that would be to replace your return statement with a
yield. Suddenly you've got a generator that'll find a whole series of
Pythagorean triples!

def pyth_triple(max):
max += 1 # to simplify range() calls later
for i in range(1,max):
for j in range(1,max):
ij = i**2 + j**2
for k in range(1,max):
m = ij - k**2
if m == 0:
yield (i, j, k)

for triple in pyth_triple(10):
print triple
(3, 4, 5)
(4, 3, 5)
(6, 8, 10)
(8, 6, 10)

For my money, that's cleaner/clearer than the Fortran version.

Jeff Shannon
Technician/Programmer
Credit International
 
D

Dennis Lee Bieber

Column 72 is the last one available for statment text,
according to this IBM 888157 card here.
Well, at least I didn't extend into the "sequence number"
field... It's been some 26 years since I last created a FORTRAN layout
drum card.

--
 
S

Sibylle Koczian

Porky said:
Not only it's *not a problem*. I've found it quite useful since it
forces you to keep the proper indentation.
I think indentation that's only there for human eyes, not for the
compiler, can be the reason why you overlook your bugs:

First version:

if (condition) then
statement-1;
statement-2;
....

Second version:

if (condition) then
statement-1;
statement-1a;
statement-2;
....

This isn't Python but Pascal, but you probably wanted the compiler to do
exactly what Python _will_ do: execute statement-1a if (and only if)
condition is true. I've done this time and again and each time wondered
about incorrect results.

Of course this won't happen if you have to use braces or begin - end
even for a single statement. But with Pascal or C/C++ that's not enforced.

And those staircases of

end
end
end

(quite a short example) aren't really beautiful, or are they?

Koczian
 
A

Antoon Pardon

Op 2004-08-16 said:
That's been exactly my situation as well, which leads me to
theorize that those who react most strongly against Python's
syntactically significant indentation are those who were the
least consistent or, uh, "anal" about making sure their code
conformed to conventions.

The corollary would be that those who already wrote code which
would have been accepted by a compiler which checked indentation,
are those who hardly blink when encountering Python,
other than to say "Of course!" as you did, and carry on writing
code just as they used to, with a mild feeling of dismay that
it never occurred to them before to question the supposed
value of braces or begin/end tags.

I think both have their value. I still prefer modula2 style.
No begin (*) tags as the block is automtically started by
any compound statement so you only needed an end tag. My
experience is that proper indentation end end tags makes
for the best readabilty, better than either of them on
their own. And mostly I add comments to the end tags
to better see what control structures they end.

(*) This is not strictly true, there is a begin tag
but that was only used to start the body of a
procedure or module, not for compound statements.
 
A

Antoon Pardon

Op 2004-08-16 said:
Hmm... not for me. The answer would be "because they
taste like dirt",

That is not an rational explanation. You have just stated
that the taste is similar to an other taste you don't
like. Now give an explanation why you don't like the
taste of dirt.
or "I hate purple", or "anything pickled
sucks".

Hating purple and stating that anything pickled sucks
don't strike me a rational explanations.
"I just don't" looks a lot like a cop-out.

How about: that is how my tongue and brain are wired.
 
A

Antoon Pardon

Op 2004-08-17 said:
I think indentation that's only there for human eyes, not for the
compiler, can be the reason why you overlook your bugs:

First version:

if (condition) then
statement-1;
statement-2;
...

Second version:

if (condition) then
statement-1;
statement-1a;
statement-2;
...

This isn't Python but Pascal, but you probably wanted the compiler to do
exactly what Python _will_ do: execute statement-1a if (and only if)
condition is true. I've done this time and again and each time wondered
about incorrect results.

Of course this won't happen if you have to use braces or begin - end
even for a single statement. But with Pascal or C/C++ that's not enforced.

That is why I prefer modula2 style.
And those staircases of

end
end
end

(quite a short example) aren't really beautiful, or are they?


Maybe not, but they do help readability in a whole lot of
cases.
 
P

Peter Hansen

Antoon said:
How about: that is how my tongue and brain are wired.

Sorry, such "explanations" are nothing more than
restatements of the original claim in different words.
They don't actually clarify the issue at all. That's
why I called "I just don't" a cop-out.

Anyway, this is far removed from the (to me) interesting
question of why people apparently have negative reactions
to Python's use of indentation. Some people have, in spite
of your claims that it's not possible, managed to produce
useful and interesting answers, and for that I thank them.
Please carry on about how it's not possible to provide
reasons for emotional reactions. The rest of the world
will continue to flow on past.

We now return to the regularly scheduled flame war...

-Peter
 
A

Antoon Pardon

Op 2004-08-17 said:
Sorry, such "explanations" are nothing more than
restatements of the original claim in different words.
They don't actually clarify the issue at all. That's
why I called "I just don't" a cop-out.

Anyway, this is far removed from the (to me) interesting
question of why people apparently have negative reactions
to Python's use of indentation. Some people have, in spite
of your claims that it's not possible, managed to produce
useful and interesting answers, and for that I thank them.

I would be most surprised if I made such a claim.

Please provide me with a reference so that I can apologize
if I actually did this.
 
P

Peter Hansen

Antoon said:
I would be most surprised if I made such a claim.

Please provide me with a reference so that I can apologize
if I actually did this.

No, the apology is mine. You picked up on the argument
Grant and Paramjit were making, but I wasn't paying
attention to the ever-changing debater in this discussion
and misremembered all the posts as being yours.

-Peter
 
R

Roy Smith

Dennis Lee Bieber said:
Well, at least I didn't extend into the "sequence number"
field... It's been some 26 years since I last created a FORTRAN layout
drum card.

I remember when I first found out about drum cards. That was cool. And
people thing language-sensitive editors are something new, huh?
 
T

Tim Hochberg

Jeff said:
In this case, I can see several Pythonic ways of doing this.

One would be to use an exception. While exceptions are not considered
good control structures in other languages, they *are* considered
acceptable (and even desirable) in Python.

Another way would be to wrap the nested loops inside a function, and
simply return the appropriate triple from that function as soon as you
find it.

An improvement on that would be to replace your return statement with a
yield. Suddenly you've got a generator that'll find a whole series of
Pythagorean triples!
[SNIP perfectly good Pythag. triple generator]

Just for fun, here's one that will spit out as many reduced pythagorean
triples as you care to look at.

-tim


def gcd(a, b):
# Euclidean alg.
assert (b > 0) and (b > 0)
if a < b:
a, b = b, a
while b:
a, b = b, a % b
return a

def rptriples():
"generate reduced pythagorean triples"
# Based on formulae from Mathworld, corrected by one from
# planetMath.
v = 1
while True:
u = 1 + (v%2) # u must be opposite parity from v
while u < v:
if gcd(u,v) == 1:
u2, v2 = u*u, v*v
a, b, c = v2-u2, 2*u*v, u2+v2
if a > b:
a, b = b, a
yield a, b, c
u += 2
v += 1
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,667
Latest member
DaniloB294

Latest Threads

Top