views:

138

answers:

5

In Python, what do you do when you write 100 lines of code and forget to add a bunch of loop statements somewhere?

I mean, if you add a while statement somewhere, you've to now indent all the lines below it. It's not like you can just put braces and be done with it. Go to every single line and add tabs/spaces. What if you were adding nested loops/if/then statements to existing code?

Am I missing some shortcut?

+9  A: 

I think every serious editor or IDE supports the option to select multiple lines and press tab to indent or Shift-Tab to unindent all that lines.

Peter Smit
True. You can't use plain old notepad, I guess.
AspiringGuru
Absolutely. No one should code without it! +1
JoshD
A: 

You have to use an editor command to re-indent.

Keep in mind: Beautiful is better than ugly.

... and the rest of "The Zen of Python, by Tim Peters"

# python -c "import this"
Michalis Giannakidis
`Flat is better than nested` comes to mind.
intuited
*Although that way may not be obvious at first unless you're Dutch.* ... wait, what are we playing again?
detly
+2  A: 

in IDLE, the standard python IDE, select the code, go on 'format' and you can chooose indent region, dedent region and so on

Ant
Or just press TAB (or Ctrl-]) to indent selection.
atzz
of course ;) (just chars for the limit)
Ant
A: 
  • textmate (and maybe e?): select then apple-]
  • bbedit: also select then apple-]
  • emacs: select then M-x 'indent-region'
  • bpython: don't know, autoindenting is so easy in bpython, you'd have to work to break it
  • xcode: don't do python in xcode

that's generally all I need to know. also yeah it's easy to slap a brace above or below a poorly indented block, but you know it's just going to confuse the shit out of you a week later when you haven't been staring at it for like a day. srsly u guys.

fish2000
+1  A: 

edit: rewrote to accomodate fileinput's "eccentricities"*

def indent_code(filename, startline, endline):
    from fileinput import input
    from itertools import izip, count

    all_remaining = count()
    def print_lines(lines, prefix='', range=all_remaining):
        for _, line in izip(range, lines):
            print prefix + line,

    lines = input(filename, inplace=1)
    print_lines(lines, range=xrange(1, startline))  # 1-based line numbers
    print_lines(lines, '    ', xrange(startline, endline + 1)) # inclusive
    print_lines(lines)

def main():
    import argparse
    parser = argparse.ArgumentParser()
    parser.add_argument('filename')
    parser.add_argument('startline', type=int)
    parser.add_argument('endline', type=int)
    ns = parser.parse_args()
    indent_code(ns.filename, ns.startline, ns.endline)

if __name__ == '__main__':
    main()

Well, either that or >}.

*: I originally wrote this using a nice, concise combination of stdout.writelines and some generator expressions. Unfortunately, that code didn't work. The iterator returned by fileinput.input() doesn't actually open a file until you call its next method. It works its sketchy output-redirection magic on sys.stdout at the same time. This means that if you call sys.stdout.writelines and pass it the fileinput.input iterator, your call, and the output, goes to the original standard out rather than the one remapped by fileinput to the file "currently" being processed. So you end up with the lines that are supposed to replace the contents of the file being instead just printed to the terminal.

It's possible to work around this issue by calling next on the fileinput iterator before calling stdout.writelines, but this causes other problems: reaching the end of the input file causes its handle to be closed from the iterator's next method when called within file.writelines. Under Python 2.6, this segfaults because there's no check made (in the C code which implements writelines) to see if the file is still open, and the file handle non-zero, after getting the next value from the iterator. I think under 2.7 it just throws an exception, so this strategy might work there.

The above code actually does test correctly.

intuited
**note:** The above code doesn't actually work. `inplace` processing using `fileinput` does not adhere to the principle of least surprise.
intuited
**now with functionality!**
intuited