Align columns

From Rosetta Code
Revision as of 05:27, 16 November 2008 by rosettacode>Paddy3118 (Align columns of text)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Task
Align columns
You are encouraged to solve this task according to the task description, using any language you may know.

Given a text file of many lines, where fields within a line are delineated by a single 'dollar' character, write a program that aligns each column of fields by ensuring that words in each column are separated by at least one space. Further, allow for each word in a column to be either left justified, right justified, or center justified within its column.

Use the following text to test your programs:

Given$a$text$file$of$many$lines,$where$fields$within$a$line$
are$delineated$by$a$single$'dollar'$character,$write$a$program
that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$
column$are$separated$by$at$least$one$space.
Further,$allow$for$each$word$in$a$column$to$be$either$left$
justified,$right$justified,$or$center$justified$within$its$column.

Python

<python>from StringIO import StringIO

textinfile = Given$a$text$file$of$many$lines,$where$fields$within$a$line$ are$delineated$by$a$single$'dollar'$character,$write$a$program that$aligns$each$column$of$fields$by$ensuring$that$words$in$each$ column$are$separated$by$at$least$one$space. Further,$allow$for$each$word$in$a$column$to$be$either$left$ justified,$right$justified,$or$center$justified$within$its$column.

j2justifier = dict(L=str.ljust, R=str.rjust, C=str.center)

def aligner(infile, justification = 'L'):

  \
 Justify columns of textual tabular input where the record separator is the newline
 and the field separator is a 'dollar' character.
 justification can be L, R, or C; (Left, Right, or Centered).
 
 Return the justified output as a string
 
 assert justification in 'LRC', "justification can be L, R, or C; (Left, Right, or Centered)."
 justifier = j2justifier[justification]
 
 fieldsbyrecord= [line.strip().split('$') for line in infile]
 # 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]
 # rotate
 fieldsbycolumn = zip(*fieldsbyrecord)
 # calculate max fieldwidth per column
 colwidths = [max(len(field) for field in column)
              for column in fieldsbycolumn]
 # pad fields in columns to colwidth with spaces
 fieldsbycolumn = [ [justifier(field, width) for field in column]
                    for width, column in zip(colwidths, fieldsbycolumn) ]
 # rotate again
 fieldsbyrecord = zip(*fieldsbycolumn)
 return "\n".join( " ".join(record) for record in fieldsbyrecord)


for align in 'Left Right Center'.split():

 infile = StringIO(textinfile)
 print "\n# %s Column-aligned output:" % align
 print aligner(infile, align[0])</python>

Example output:

# Left Column-aligned output:
Given      a          text       file   of     many      lines,     where    fields  within  a      line 
are        delineated by         a      single 'dollar'  character, write    a       program             
that       aligns     each       column of     fields    by         ensuring that    words   in     each 
column     are        separated  by     at     least     one        space.                               
Further,   allow      for        each   word   in        a          column   to      be      either left 
justified, right      justified, or     center justified within     its      column.                     

# Right Column-aligned output:
     Given          a       text   file     of      many     lines,    where  fields  within      a line 
       are delineated         by      a single  'dollar' character,    write       a program             
      that     aligns       each column     of    fields         by ensuring    that   words     in each 
    column        are  separated     by     at     least        one   space.                             
  Further,      allow        for   each   word        in          a   column      to      be either left 
justified,      right justified,     or center justified     within      its column.                     

# Center Column-aligned output:
  Given        a         text     file    of      many     lines,    where    fields  within   a    line 
   are     delineated     by       a    single  'dollar' character,  write      a    program             
   that      aligns      each    column   of     fields      by     ensuring   that   words    in   each 
  column      are     separated    by     at     least      one      space.                              
 Further,    allow       for      each   word      in        a       column     to      be   either left 
justified,   right    justified,   or   center justified   within     its    column.