Empty Pipes



VIM Python Snippets

  • 02 Oct 2014
  • |
  • linux
  • python
  • vim
  • |

There are many times when a task calls for a simple python script. It is usually something small that takes some input file as a parameter, does some processing, and then spits out some results. It might even take an options or two. It’s tempting to just throw some lines of code into a file and be done with it. This may work but often just makes things more difficult later.

Consider the following code (let’s creatively call it do_stuff.py) which simply converts the input to uppercase:

import sys

for line in sys.stdin:
    print line.upper()

What happens, however, when it grows a little bit and we add a function?

import random
import sys

def uppercase_and_scramble(line):
   ll = list(line)
   random.shuffle(ll)
   return "".join(ll)

for line in sys.stdin:
    print line.upper()

What happens if we want to include that function into another file? Then importing do_stuff.py will cause the for loop to run. A much better solution is to do all of the ‘scripty’ stuff in a main function that only gets called if the file is called as a script (as opposed to being imported as a library):

import random
import sys
from optparse import OptionParser

def uppercase_and_scramble(line):
    '''
    Make the line uppercase, scramble its contents and return the result.
    '''
    ll = list(line)
    random.shuffle(ll)
    return "".join(ll)

def main():
    usage = """
    python do_stuff.py

    Process lines from the input.
    """
    num_args= 0
    parser = OptionParser(usage=usage)

    #parser.add_option('-o', '--options', dest='some_option', default='yo', help="Place holder for a real option", type='str')
    #parser.add_option('-u', '--useless', dest='uselesss', default=False, action='store_true', help='Another useless option')

    (options, args) = parser.parse_args()

    if len(args) < num_args:
        parser.print_help()
        sys.exit(1)

    for line in sys.stdin:
        print uppercase_and_scramble(line)

if __name__ == '__main__':
    main()

That’s a lot of code for a simple task. Well it doesn’t necessarily require much typing to enter thanks to the SnipMate plugin for vim. By adding the following code in ~/.vim/snippets/python.snippets we can create almost all of the code by typing start and hitting tab right at the beginning of the script.

snippet start
    import sys
    from optparse import OptionParser

    def main():
        usage = """
        ${1:usage}
        """
        num_args= 0
        parser = OptionParser(usage=usage)

        #parser.add_option('-o', '--options', dest='some_option', default='yo', help="Place holder for a real option", type='str')
        #parser.add_option('-u', '--useless', dest='uselesss', default=False, action='store_true', help='Another useless option')

        (options, args) = parser.parse_args()

        if len(args) < num_args:
            parser.print_help()
            sys.exit(1)

    if __name__ == '__main__':
        main()

This will create the main function and position the cursor within the usage string thus making it a snap to write some quick documentation of what this script will do. The num_args variable is there to make sure the user enters the right number of arguments. Otherwise the script exits with an error. The rest of the processing code should go directly after the if statement. When scripts are written in this manner, they can be painlessly turned into libraries at a future point in time.