ascii tables
John Hunter
jdhunter at ace.bsd.uchicago.edu
Mon Jun 2 12:28:57 EDT 2003
>>>>> "Carel" == Carel Fellinger <carel.fellinger at chello.nl> writes:
Carel> it's old printer wisdom that one should be very reluctant
Carel> to use lines in tables, and indeed I find the following
Carel> much easier on the eyes:
I agree, I modified ascii_table to take a '' argument for rowSep,
which prints the table as you suggested, and added a repeatHeader
entry to allow you to repeat the header every so many lines for long
tables. I also added headerColSep and headerRowSep variables so that
the separator for headers and regular rows can be different, with
default values making them the same.
Carel> you could also use str's center, ljust and rjust methods.
Another good suggestion, implemented below.
The code below, with suitable args, now 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
Thanks,
John Hunter
def ascii_table(headers, cols, fmts, alignments=None,
rowSep='-', colSep='|', pad=1,
headerRowSep=None,
headerColSep=None,
repeatHeader=0):
"""
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 (len num rows)
fmts is a len(columns) tuple of format strings.
alignments, if not None, is a list of horiz alignment strings:
'l' or 'r' or 'c'. Default is 'l'
repeatHeader, if not 0, will repeat the header every repeatHeader
rows
rowSep is used to join the rows; ifis '', rows will be joined with a newline alone
colSep is used to join the columns
headerRowSep is used to separate the headers from the other rows.
If None, just use rowSep
headerColSep is used to separate the header columns. If None,
just use colSep
Example usage:
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'),
)
"""
if alignments is None:
alignments = ['l']*len(cols)
if headerColSep is None: headerColSep = colSep
colSepWid = max(len(colSep), len(headerColSep))
colSep = ' '*pad + colSep + ' '*pad
headerColSep = ' '*pad + headerColSep + ' '*pad
def pad_entry(entry, align, width):
if align=='l': return entry.ljust(width)
elif align=='r': return entry.rjust(width)
else: return entry.center(width)
colStrs = []
headerStrs = []
widths = []
for col,fmt,header,align in zip(cols, fmts, headers, alignments):
entries = [fmt % val for val in col]
width = max(len(header), max(map(len, entries))) + colSepWid
colStrs.append([pad_entry(entry, align, width)
for entry in entries])
headerStrs.append( pad_entry(header, align, width) )
lines = [colSep.join(tup) for tup in zip(*colStrs)]
header = headerColSep.join(headerStrs)
maxLen = max(len(header), max(map(len, lines)))
if rowSep is '': rowSep = '\n'
else: rowSep = '\n' + rowSep*maxLen + '\n'
if headerRowSep is None: headerRowSep = rowSep
else: headerRowSep = '\n' + headerRowSep*maxLen + '\n'
s = header + headerRowSep
for i,line in enumerate(lines):
if repeatHeader and i>0 and i%repeatHeader==0:
s += '\n' + header + headerRowSep
s += line + rowSep
return s
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'),
repeatHeader=0,
rowSep='',
colSep=' ',
headerRowSep = '*',
headerColSep = ':',
pad=1,
)
More information about the Python-list
mailing list