Indents a table by column. - rows: A sequence of sequences of items, one sequence per row. - hasHeader: True if the first row consists of the columns' names. - headerChar: Character to be used for the row separator line (if hasHeader==True or separateRows==True).
(rows, hasHeader=False, headerChar='-', delim=' | ', justify='left',
separateRows=False, prefix='', postfix='', wrapfunc=lambda x:x)
| 1 | import cStringIO,operator |
| 2 | |
| 3 | def indent(rows, hasHeader=False, headerChar='-', delim=' | ', justify='left', |
| 4 | separateRows=False, prefix='', postfix='', wrapfunc=lambda x:x): |
| 5 | """Indents a table by column. |
| 6 | - rows: A sequence of sequences of items, one sequence per row. |
| 7 | - hasHeader: True if the first row consists of the columns' names. |
| 8 | - headerChar: Character to be used for the row separator line |
| 9 | (if hasHeader==True or separateRows==True). |
| 10 | - delim: The column delimiter. |
| 11 | - justify: Determines how are data justified in their column. |
| 12 | Valid values are 'left','right' and 'center'. |
| 13 | - separateRows: True if rows are to be separated by a line |
| 14 | of 'headerChar's. |
| 15 | - prefix: A string prepended to each printed row. |
| 16 | - postfix: A string appended to each printed row. |
| 17 | - wrapfunc: A function f(text) for wrapping text; each element in |
| 18 | the table is first wrapped by this function.""" |
| 19 | # closure for breaking logical rows to physical, using wrapfunc |
| 20 | def rowWrapper(row): |
| 21 | newRows = [wrapfunc(item).split('\n') for item in row] |
| 22 | return [[substr or '' for substr in item] for item in map(None,*newRows)] |
| 23 | # break each logical row into one or more physical ones |
| 24 | logicalRows = [rowWrapper(row) for row in rows] |
| 25 | # columns of physical rows |
| 26 | columns = map(None,*reduce(operator.add,logicalRows)) |
| 27 | # get the maximum of each column by the string length of its items |
| 28 | maxWidths = [max([len(str(item)) for item in column]) for column in columns] |
| 29 | rowSeparator = headerChar * (len(prefix) + len(postfix) + sum(maxWidths) + \ |
| 30 | len(delim)*(len(maxWidths)-1)) |
| 31 | # select the appropriate justify method |
| 32 | justify = {'center':str.center, 'right':str.rjust, 'left':str.ljust}[justify.lower()] |
| 33 | output=cStringIO.StringIO() |
| 34 | if separateRows: print >> output, rowSeparator |
| 35 | for physicalRows in logicalRows: |
| 36 | for row in physicalRows: |
| 37 | print >> output, \ |
| 38 | prefix \ |
| 39 | + delim.join([justify(str(item),width) for (item,width) in zip(row,maxWidths)]) \ |
| 40 | + postfix |
| 41 | if separateRows or hasHeader: print >> output, rowSeparator; hasHeader=False |
| 42 | return output.getvalue() |
| 43 | |
| 44 | # written by Mike Brown |
| 45 | # http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/148061 |
no test coverage detected