Indentation for code readability

Discussion in 'Python' started by DE, Mar 30, 2007.

  1. DE

    DE Guest

    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
     
    DE, Mar 30, 2007
    #1
    1. Advertising

  2. DE schrieb:
    > 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
     
    =?ISO-8859-1?Q?Thomas_Kr=FCger?=, Mar 30, 2007
    #2
    1. Advertising

  3. DE

    John Machin Guest

    On Mar 30, 7:04 pm, "DE" <> wrote:
    > 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
     
    John Machin, Mar 30, 2007
    #3
  4. DE

    Peter Otten Guest

    DE wrote:

    > 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
     
    Peter Otten, Mar 30, 2007
    #4
  5. DE wrote:

    > 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

    --
    BOFH excuse #175:

    OS swapped to disk
     
    Bjoern Schliessmann, Mar 30, 2007
    #5
  6. On Fri, 30 Mar 2007 02:04:45 -0700, DE wrote:

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


    --
    Steven.
     
    Steven D'Aprano, Mar 30, 2007
    #6
  7. DE

    Mark Jackson Guest

    "DE" <> writes:
    > 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.

    --
    Mark Jackson - http://www.alumni.caltech.edu/~mjackson
    Every 10 years we say to ourselves, "If only we had
    done the right thing 10 years ago."
    - Thomas Friedman
     
    Mark Jackson, Mar 30, 2007
    #7
  8. DE

    DE Guest

    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.
     
    DE, Mar 30, 2007
    #8
  9. DE

    Duncan Booth Guest

    "DE" <> wrote:

    > 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()
     
    Duncan Booth, Mar 30, 2007
    #9
  10. DE

    DE Guest

    >
    > 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..
     
    DE, Mar 30, 2007
    #10
  11. DE

    DE Guest

    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
     
    DE, Mar 30, 2007
    #11
  12. Thomas Krüger <> wrote:

    > 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
     
    Alex Martelli, Mar 30, 2007
    #12
  13. DE

    Paul McGuire Guest

    On Mar 30, 4:04 am, "DE" <> wrote:
    >
    > 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
     
    Paul McGuire, Mar 30, 2007
    #13
  14. DE

    DE Guest

    >
    > > 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 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 :)
     
    DE, Mar 30, 2007
    #14
  15. DE

    Robert Kern Guest

    Steven D'Aprano wrote:
    > On Fri, 30 Mar 2007 02:04:45 -0700, DE wrote:
    >
    >> 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?


    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
     
    Robert Kern, Mar 31, 2007
    #15
  16. On Fri, 30 Mar 2007 18:32:02 -0500, Robert Kern wrote:

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


    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.



    --
    Steven.
     
    Steven D'Aprano, Mar 31, 2007
    #16
  17. DE

    jkn Guest

    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
     
    jkn, Mar 31, 2007
    #17
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. David Stockwell
    Replies:
    3
    Views:
    331
    Peter Hansen
    Jun 2, 2004
  2. Replies:
    9
    Views:
    360
    Jerry Coffin
    Jul 28, 2006
  3. Licheng Fang

    Problem of Readability of Python

    Licheng Fang, Oct 7, 2007, in forum: Python
    Replies:
    35
    Views:
    1,095
    Marc 'BlackJack' Rintsch
    Oct 18, 2007
  4. Marco Bizzarri
    Replies:
    8
    Views:
    270
    Fredrik Lundh
    Sep 13, 2008
  5. Jesse B.
    Replies:
    2
    Views:
    224
    Josh Cheek
    Mar 27, 2010
Loading...

Share This Page