Original computing articles by a systems administrator

Getting Command Line Columns to Line up with Python

I created a solution for a program I am writing that makes columns line up when outputted to the command line. I am new to Python, and am hoping I might get some input on this topic.

In the text file that the program reads, the fields (columns) are delimited by ‘$’ and the records (lines) are delimited by newlines ‘\n’. So one line looks like: 1$foo$bar

I broke this task into two separate functions. The first function, opt_output, finds the max length of each column and returns a list such as [1, 23, 14] where 1 is the max width of the first column, 23 is the max length of the second column etc. This function takes a list object as an argument; that list is the file described above with one record as an object in the list. It then iterates over the list, splitting each record into a list on its delimiter. Then the function iterates over an individual record, saving the length of each item if the length is larger then the the length of the equivalent column in previous record. This is of course clearer in the code itself:

The Second function, print_line, takes one record as a list object (already split into items) and the value returned from the previous function. It then uses the values returned from opt_output and pads each item in the list with spaces. The number of spaces to pad it with is figured out by subtracting the length of the item from the max length of the column that was found by the previous function. Finally, it rejoins the list with the delimiter ‘$’ and then splits the list again using the padded spaces as the delimiter for each column:

When calling these functions I record the value of the first function in a variable so it does not have to iterate over the list over and over again. The print line function is called for each line in the file when outputting file to the screen. As long as there is a fixed width font everything lines up nicely in the terminal.

One Response to Getting Command Line Columns to Line up with Python

  1. Paddy3118 says:

    Hi,
    Nice problem.
    I have this solution in Python:

    from StringIO import StringIO
    from pprint import pprint as pp
    left_justified = False
    debug = False

    textinfile = ”’I$created$a$solution$for$a$program$I$am$writing$that
    makes$columns$line$up$when$outputted$to$the$command
    line.$I$am$new$to$Python,$and$am$hoping$I$might$get
    some$input$on$this$topic.$In$the$text$file$that$the
    program$reads,$the$fields$(columns)$are$delimited$by
    ‘dollar’$and$the$records$(lines)$are$delimited$by
    newlines$’\\n’.$So$one$line$looks$like:$”’

    “”"

    Solution to problem posed at:
      http://www.kbrandt.com/2008/06/getting-command-line-output-columns-to.html

    Output is the following if left-justified:

    # Column-aligned output:
    I created a solution for a program I am writing that
    makes columns line up when outputted to the command
    line. I am new to Python, and am hoping I might get
    some input on this topic. In the text file that the
    program reads, the fields (columns) are delimited by
    ‘dollar’ and the records (lines) are delimited by
    newlines ‘\n’. So one line looks like:

    And like this if not left-justified:

    # Column-aligned output:
           I created a solution for a program I am writing that
       makes columns line up when outputted to the command
       line. I am new to Python, and am hoping I might get
        some input on this topic. In the text file that the
     program reads, the fields (columns) are delimited by
    ‘dollar’ and the records (lines) are delimited by
    newlines ‘\n’. So one line looks like:

    “”"

    infile = StringIO(textinfile)

    fieldsbyrecord= [line.strip().split('$') for line in infile]
    if debug: print “fieldsbyrecord:”; print (fieldsbyrecord)
    # pad to same number of fields per record
    maxfields = max(len(record) for record in fieldsbyrecord)
    fieldsbyrecord = [fields + ['']*(maxfields – len(fields))
                      for fields in fieldsbyrecord]
    if debug: print “padded fieldsbyrecord:”; print (fieldsbyrecord)
    # rotate
    fieldsbycolumn = zip(*fieldsbyrecord)
    if debug: print “fieldsbycolumn:”; print (fieldsbycolumn)
    # calculate max fieldwidth per column
    colwidths = [max(len(field) for field in column)
                 for column in fieldsbycolumn]
    if debug: print “colwidths:”; print (colwidths)
    # pad fields in columns to colwidth with spaces
    # (Use -width for left justification,)
    fieldsbycolumn = [ ["%*s" % (-width if left_justified else width, field) for field in column]
                       for width, column in zip(colwidths, fieldsbycolumn) ]
    if debug: print “padded fieldsbycolumn:”; print (fieldsbycolumn)
    # rotate again
    fieldsbyrecord = zip(*fieldsbycolumn)
    if debug: print “padded rows and fields, fieldsbyrecord:”; print (fieldsbyrecord)
    # printit
    print “\n# Column-aligned output:”
    for record in fieldsbyrecord:
      print ” “.join(record)

    - Paddy.

Leave a Reply

*