Indentation for code readability

D

DE

Hello,

Here is what I do in C++ and can not right now in python :

pushMatrix()
{
drawStuff();

pushMatrix();
{
drawSomeOtherStuff()
}
popMatrix();
}
popMatrix();

The curly brackets have no functional meaning but increase the
readability significantly. I want to be able to do the same thing in
python. Since curly brackets are not available and indenting without
an if or while conditional doesn't work, I have started to question if
this is possible in python at all.

Any ideas ?

MDE
 
?

=?ISO-8859-1?Q?Thomas_Kr=FCger?=

DE said:
Hello,

Here is what I do in C++ and can not right now in python :

pushMatrix()
{
drawStuff();

pushMatrix();
{
drawSomeOtherStuff()
}
popMatrix();
}
popMatrix();

The curly brackets have no functional meaning but increase the
readability significantly. I want to be able to do the same thing in
python. Since curly brackets are not available and indenting without
an if or while conditional doesn't work, I have started to question if
this is possible in python at all.

Any ideas ?

I've been thinking about that for some minutes now and I have doubts
that it will increase the readability. Maybe for you as you invented
that style but not for others.
There are a few standards for formatting C code and even this few have
cause many discussions between developers.
Python has one convention (defined in PEP 8) and the deeper you dive
into the language the more you will like it.
BTW: having one way to do it is one of the main ideas of Python's
philosophy.

Thomas
 
J

John Machin

Hello,

Here is what I do in C++ and can not right now in python :

pushMatrix()
{
drawStuff();

pushMatrix();
{
drawSomeOtherStuff()
}
popMatrix();}

popMatrix();

The curly brackets have no functional meaning but increase the
readability significantly. I want to be able to do the same thing in
python. Since curly brackets are not available and indenting without
an if or while conditional doesn't work, I have started to question if
this is possible in python at all.

Any ideas ?

You *can* use round brackets and/or square brackets. E.g.

def pushMatrix():
drawStuff()
pushMatrix()
(
drawSomeOtherStuff()
)
[
drawEvenMoreStuff()
]
popMatrix()

Whether you *should* do that is a different question ... It's a bit
like an English definition of a Scottish gentleman: one who can play
the bagpipes, but doesn't :)

HTH,
John
 
P

Peter Otten

DE said:
Hello,

Here is what I do in C++ and can not right now in python :

pushMatrix()
{
drawStuff();

pushMatrix();
{
drawSomeOtherStuff()
}
popMatrix();
}
popMatrix();

The curly brackets have no functional meaning but increase the
readability significantly. I want to be able to do the same thing in
python. Since curly brackets are not available and indenting without
an if or while conditional doesn't work, I have started to question if
this is possible in python at all.

Any ideas ?

You could use

if True:
# do stuff

but I have no sympathy for such self-inflicted noise.

With Python 2.5 you can do even better -- you can emulate what should have
been RAII in your C++ example in the first place:

from __future__ import with_statement

from contextlib import contextmanager

def push_matrix():
print "push"

def pop_matrix():
print "pop"

@contextmanager
def matrix():
m = push_matrix()
try:
yield m
finally:
pop_matrix()

with matrix():
print "do stuff"
with matrix():
print "do more stuff"

Peter
 
B

Bjoern Schliessmann

DE said:
The curly brackets have no functional meaning but increase the
readability significantly.

Personally, I don't think so. It quite explodes the code.

Yes, I also indent "BSD style" in my C++ programs.

Regards,


Björn
 
S

Steven D'Aprano

Hello,

Here is what I do in C++ and can not right now in python :

pushMatrix()
{
drawStuff();

pushMatrix();
{
drawSomeOtherStuff()
}
popMatrix();
}
popMatrix();

The curly brackets have no functional meaning
but increase the readability significantly.

I don't understand why you are indenting
the function calls. What does the
indentation and spacing signify?

Or, to put it another way:


I don't understand why you
{
are indenting
{
the function calls.
}
What does the
}
indentation signify?


I want to be able to do the same thing in
python. Since curly brackets are not available and indenting without
an if or while conditional doesn't work, I have started to question if
this is possible in python at all.

Thank goodness it isn't, in general.

But if you want people to point at you and laugh in the street, you can do
this:

pushMatrix()
if True:
drawStuff();

pushMatrix();
if True:
drawSomeOtherStuff()

popMatrix();

popMatrix();


Any ideas ?

Some people
have a strange
idea of
"increase
readability".
 
M

Mark Jackson

DE said:
Hello,

Here is what I do in C++ and can not right now in python :

pushMatrix()
{
drawStuff();

pushMatrix();
{
drawSomeOtherStuff()
}
popMatrix();
}
popMatrix();

The curly brackets have no functional meaning but increase the
readability significantly.

You are e. e. cummings, and I claim my £5.
 
D

DE

Thanks Peter. This sounds like to right solution for my case, because
in addition to indentation, I can automate push and pop. I'll
investigate this further. I appreciate.
 
D

Duncan Booth

DE said:
Here is what I do in C++ and can not right now in python :

pushMatrix()
{
drawStuff();

pushMatrix();
{
drawSomeOtherStuff()
}
popMatrix();
}
popMatrix();

If I understand this contortion is because you have some sort of stack
and you want the code to follow the depth as you push and pop things
from the stack.

If you write this in Python then when drawSomeOtherStuff() throws an
exception your 'stack' will get messed up, so you'll need to add some
more code to handle this. Using Python 2.5 this is the sort of thing you
should end up with (and you'll notice that your indentation appears
naturally when you do this):


from __future__ import with_statement
from contextlib import contextmanager

# Dummy functions so this executes
def pushMatrix(arg): print "pushMatrix", arg
def popMatrix(arg): print "popMatrix", arg
def drawStuff(): print "drawStuff"
def drawSomeOtherStuff(): print "drawSomeOtherStuff"

# The matrix stack implemented as a context handler.
@contextmanager
def NewMatrixContext(arg):
pushMatrix(arg)
try:
yield
finally:
popMatrix(arg)

# and finally the function to actually draw stuff in appropriate
# contexts.
def fn():
with NewMatrixContext(1):
drawStuff()
with NewMatrixContext(2):
drawSomeOtherStuff()

fn()
 
D

DE

I don't understand why you are indenting
the function calls. What does the
indentation and spacing signify?

The indentation of function calls increases readability not in the
sense that it is easier to decrypt the code, but rather it is
analogous to the coordinate system transformations these matrix push
and pop calls perform..
 
D

DE

Thanks Duncan. I guess you and Peter have been typing in the same
minute :) It really looks like a good solution, I wasn't aware this
with statement in Python. I can imagine the context handler coming
handy in other cases too.

Devrim
 
A

Alex Martelli

Thomas Krüger said:
BTW: having one way to do it is one of the main ideas of Python's
philosophy.

Yes, just like C's -- see point 4 in the "Spirit of C" summary taken
from the ISO Standard for C and quoted e.g. at
<http://www.artima.com/cppsource/spiritofc.html> . Of course, it's an
ideal, a design principle, not an actual description of how things turn
out (in either language).


Alex
 
P

Paul McGuire

The curly brackets have no functional meaning...

"Curly brackets have no functional meaning"? Surely you must be
thinking of C, but not C++. Some of the most powerful idioms (idia?)
of C++ make use of functionality that runs when a closing bracket
causes local variables to fall out of scope. In fact, this technique
is crucial to writing exception-safe code.

The most obvious has to do with memory allocation/deallocation, and
the STL template <auto_ptr>. <auto_ptr> was invented to prevent this
problem:

{
// create a pointer - let's pretend I need a pointer
// and can't just allocate blah as a local SomeObject
SomeObject* blah = new SomeObject();

// do something with blah
blah->doSomething();

// do something else - OOPS! exception happened
blah->doSomethingBad();

delete blah; // never got here - memory leaked
}

Instead, define blah using <auto_ptr>:

{
// create a pointer - let's pretend I need a pointer
// and can't just allocate blah as a local SomeObject
auto_ptr<SomeObject> blah ( new SomeObject() );

// do something with blah
blah->doSomething();

// do something else - OOPS! exception happened
blah->doSomethingBad();

// but we don't care because when auto_ptr goes out
// of scope, it deletes its pointers allocated
// memory
}

I was on one C++ project in which our coding guidelines said something
to the effect of "no delete statements except in cleanup templates,"
meaning that all allocated variables had to be wrapped in some form of
auto_ptr template to ensure resource release on delete, even in the
face of exceptions.

So that closing '}' actually DOES do something functional, in running
the destructors of all locally declared variables.

But why should Python folks care, since garbage collection takes care
of our basic memory needs without all this auto_ptr<Stuff> stuff?
Well memory allocation is only one of these symmetric function cases.
Garbage collection doesn't do anything for us in:
- database transaction commit/rollback
- mutex lock/unlock
- web client session close/release
- release of any other kind of allocatable resource

AND, it does this deterministically, not "at some possible time in the
future" like GC.
(Yes, I know that CPython's ref counting scheme *does* release memory
immediately, but this is an implementation-specific behavior.)

Prior to Python 2.5's "with" construct, the closest Pythoners could
get was to use try/catch/finally, and put the resource release code
into the finally block. There are also some decorators on the Python
wiki that encapsulate this "be sure to close the door" logic into some
friendlier syntax (even if it does use that ugly '@').

-- Paul
 
D

DE

"Curly brackets have no functional meaning"? Surely you must be
thinking of C, but not C++. Some of the most powerful idioms (idia?)
of C++ make use of functionality that runs when a closing bracket
causes local variables to fall out of scope. In fact, this technique
is crucial to writing exception-safe code.

The curly brackets have no functional meaning in the scope of the
example I have written in my original mail. I usually ask C++ memory
management issues in in the relevant newsgroup :)
 
R

Robert Kern

Steven said:
I don't understand why you are indenting
the function calls. What does the
indentation and spacing signify?

pushMatrix() pushes a transformation matrix onto the stack of transformation
matrices. The drawing functions draw inside this context of transformations.
popMatrix() pops the last transformation matrix. For example, one could push a
rotation matrix that rotates the coordinate system 90 degrees from horizontal.
drawStuff() might draw some text; usually this would be horizontal, but in the
context of the transformation, it will ultimately be drawn vertically.

As others have mentioned, this is a perfectly good application of Python 2.5's
"with" statement and its context managers. The indentation is meaningful and useful.
Some people
have a strange
idea of
"increase
readability".

Please contain the snark. You didn't understand why someone might want this, and
that's fine. But please wait until you get a response before assuming that there
could be no good reason for wanting this.

--
Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
that is made terrible by our own mad attempt to interpret it as though it had
an underlying truth."
-- Umberto Eco
 
S

Steven D'Aprano

Please contain the snark. You didn't understand why someone might want this, and
that's fine. But please wait until you get a response before assuming that there
could be no good reason for wanting this.

No, I think the snark was justified. Even the Original Poster admitted in
his reply that when he said "increases readability", he didn't so much
mean making the code easier to read (or as he put it, "decrypt the code")
as mirror the stack depth.

The indentation might even be meaningful, but it hardly increases
readability, and I object strongly (hence the snark) to people labeling
any code convention that carries information or is useful *in any way* as
"increasing readability".

As a general technique, trying to mirror the stack depth with indentation
is doomed to failure for anything but the most trivial code. Try following
that tactic with code that pushes and pops a variable number of items onto
the stack, or mix it with other indented blocks (for, if, etc.).

In my opinion, the O.P. has got the wrong tactic -- one which doesn't
scale, doesn't cope with Python blocks, decreases readability, and is
incompatible with code pretty-printers. He has to manually keep the
indentation adjusted with the stack depth, and if he gets it wrong (which
he will for complex code) the compiler won't tell him.

That's not to say it isn't useful, if his code is small enough. But the
right tactic is, as many people have pointed out, to use context managers
to *ensure* the stack is popped the right number of times, instead of
using indentation as a proxy for stack depth.

There very well might not be a right solution in other languages, I don't
know. For short pieces of code, indents may be no worse than manually
appending the stack depth to each line as a comment, and it might even be
better. But it no more increases readability than it decreases memory
usage or makes the code run faster.
 
J

jkn

If I wanted to mark out stack depth stuff like this in python, I'd do
it
with some form of stylised comment, like this:

# LEVEL 0

pushMatrix():
# ....LEVEL 1

drawstuff()
pushMatrix()
# ........LEVEL 2

drawSomeOtherStuff()
popMatrix()
# ....LEVEL 1

popMatrix()
# LEVEL 0

(there's probably a better comment form for your specific
requirement).

Any decent modern editor should be capable of being set up to
highlight such lines in a colour/style of your choice, and you then
set your eyeball filter to look for those lines when you want to be
sure of where you are.

jon N
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top