ascii tables
John Hunter
jdhunter at ace.bsd.uchicago.edu
Thu May 29 15:01:47 EDT 2003
>>>>> "Peter" == Peter Hansen <peter at engcorp.com> writes:
Peter> John Hunter wrote:
>> I often need to print several equal length, homogeneous lists
>> (some lists are strings, some ints, some floats), and I would
>> like to make a nice ascii table for display, with configurable
>> format strings for each column, row and column separators
>> etc.... Anyone know of some code that does this?
Peter> Not existing code, but it doesn't sound too hard.
Peter> Here are some ideas (untested):
Peter> [ 'test', 55.6, 'a longer string' ]
The problem is that the lists are homogeneous, ie, all elements of the
same type. This arises a lot in my data analyses, where I may have an
array of heights, and array of weights, and array of names, etc, all
of the same length, and I want to pretty print them. Sorry I wasn't
clearer in my original post.
Here is my first pass at a solution, which prints
Name | Age | Sex | Weight | Height
------------------------------------
John | 35 | M | 170.0 | 60.1
------------------------------------
Miriam | 31 | F | 135.0 | 58.2
------------------------------------
Rahel | 5 | F | 40.0 | 48.2
------------------------------------
Ava | 2 | F | 25.0 | 30.0
def ascii_table(headers, cols, fmts, alignments=None,
rowSep='-', colSep='|', pad=1):
"""
Pretty print the homogenous lists in cols.
headers is a len(columns) tuple of header strings.
cols is a len(columns) tuple of homogeneous lists.
fmts is a len(columns) tuple of format strings.
alignments, if not None, is a a len(columns) tuple of horiz
alignment strings: 'l' or 'r' or 'c'. Default 'l'
"""
if alignments is None:
alignments = ['l']*len(cols)
def pad_entry(entry, align, width):
numSpaces = width-len(entry)-1 + pad
if align=='l': return entry + ' '*numSpaces
elif align=='r': return ' '*numSpaces + entry
else: # align center
s = ' '*(numSpaces/2) + entry + ' '*(numSpaces/2)
if numSpaces % 2 == 1: s += ' '
return s
colStrs = []
for col,fmt,header,align in zip(cols, fmts, headers, alignments):
entries = [header]
entries.extend([fmt % val for val in col])
width = max(map(len, entries))
colStrs.append([pad_entry(entry, align, width) for entry in entries])
colSep = ' '*pad + colSep + ' '*pad
lines = [colSep.join(tup) for tup in zip(*colStrs)]
maxLen = max(map(len, lines))
rowSep = '\n' + rowSep*maxLen + '\n'
return rowSep.join(lines)
if __name__=='__main__':
headers = 'Name', 'Age', 'Sex', 'Weight', 'Height'
names = 'John', 'Miriam', 'Rahel', 'Ava'
ages = 35, 31, 5, 2
sexes = 'M', 'F', 'F', 'F'
weights = 170, 135, 40, 25
heights = 60.1, 58.2, 48.2, 30
print ascii_table(headers,
cols = (names, ages, sexes, weights, heights),
fmts = ('%s', '%d', '%s', '%1.1f', '%1.1f'),
alignments = ('l', 'r', 'c', 'r', 'r'),
)
More information about the Python-list
mailing list