class ColumnWriter(object):
def __init__(self, columns):
columns = (-1, ) + tuple(columns)
widths = (c2 - c1 for c1, c2 in zip(columns, columns[1:]))
format_codes = ("{" + str(i) + ":>" + str(width) +"}"
for i, width in enumerate(widths))
self.format_string = ''.join(format_codes)
def get_row(self, values):
return self.format_string.format(*values)
cw = ColumnWriter((1, 20, 21))
print cw.get_row((1, 2, 3))
print cw.get_row((1, 'a', 'a'))
if you need the columns to vary from row to row, then you can do one liners.
import itertools
for columns in itertools.combinations(range(10), 3):
print ColumnWriter(columns).get_row(('.','.','.'))
It slacks on the error checking. It needs to check that columns
is sorted and that len(values) == len(columns)
.
It has problems with the value being longer than the area being allocated to hold it but I'm not sure what to do about this. Currently if that occurs, it overwrites the previous column. example:
print ColumnWriter((1, 2, 3)).get_row((1, 1, 'aa'))
If you had an iterable of rows that you wanted to write to a file, you could do something like this
rows = [(1, 3, 4), ('a', 'b', 4), ['foo', 'ten', 'mongoose']]
format = ColumnWriter((20, 30, 50)).get_row
with open(filename, 'w') as fout:
fout.write("\n".join(format(row) for row in rows))