Skip to content

Commit

Permalink
A lot of refactoring and now headers accepting any data type (as rows…
Browse files Browse the repository at this point in the history
… accept)
  • Loading branch information
Álvaro Justen aka Turicas committed Nov 2, 2011
1 parent 3cc743a commit 7d050f9
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 32 deletions.
56 changes: 27 additions & 29 deletions outputty.py
Expand Up @@ -38,62 +38,60 @@ def __init__(self, headers=[], dash='-', pipe='|', plus='+',
self.output_encoding = output_encoding
self.rows = []
if from_csv:
self.import_from_csv(from_csv)
self._import_from_csv(from_csv)


def _convert_to_unicode(self, element):
if not isinstance(element, (str, unicode)):
return unicode(element)
else:
if isinstance(element, (str, unicode)):
return element.decode(self.input_encoding)
else:
return unicode(element)


def _organize_data(self):
result = []
result.append([x.decode(self.input_encoding) for x in self.headers])
result.append([self._convert_to_unicode(x) for x in self.headers])
for row in self.rows:
if isinstance(row, dict):
row_data = []
for header_name in self.headers:
if header_name in row:
data = self._convert_to_unicode(row[header_name])
else:
data = unicode()
row_data.append(data)
if header_name not in row:
row[header_name] = ''
row_data.append(self._convert_to_unicode(row[header_name]))
else:
row_data = [self._convert_to_unicode(info) for info in row]
result.append(row_data)
self.data = result


def _define_maximum_column_sizes(self):
self.max_sizes = {}
self.max_size = {}
for column in zip(*self.data):
self.max_sizes[column[0]] = max([len(x) for x in column])

self.max_size[column[0]] = max([len(x) for x in column])


def _make_line_from_row_data(self, row_data):
return '%s %s %s' % (self.pipe, (' %s ' % self.pipe).join(row_data),
self.pipe)


def __unicode__(self):
self._organize_data()
self._define_maximum_column_sizes()
unicode_headers, rows = self.data[0], self.data[1:]

unicode_headers = self.data[0]
dashes = [self.dash * (self.max_sizes[x] + 2) for x in unicode_headers]
dashes = [self.dash * (self.max_size[x] + 2) for x in unicode_headers]
centered_headers = [x.center(self.max_size[x]) for x in unicode_headers]
split_line = self.plus + self.plus.join(dashes) + self.plus
headers_centralized = [x.center(self.max_sizes[x]) \
for x in unicode_headers]
space_pipe_space = ' %s ' % self.pipe
header_line = self.pipe + ' ' + \
space_pipe_space.join(headers_centralized) + ' ' + \
self.pipe
header_line = self._make_line_from_row_data(centered_headers)

result = [split_line, header_line, split_line]
for row in self.data[1:]:
for row in rows:
row_data = []
for i, info in enumerate(row):
data = info.rjust(self.max_sizes[unicode_headers[i]])
data = info.rjust(self.max_size[unicode_headers[i]])
row_data.append(data)
result.append('%s %s %s' % (self.pipe,
space_pipe_space.join(row_data),
self.pipe))
result.append(self._make_line_from_row_data(row_data))
if self.rows:
result.append(split_line)
return '\n'.join(result)
Expand All @@ -103,13 +101,13 @@ def __str__(self):
return self.__unicode__().encode(self.output_encoding)


def import_from_csv(self, filename):
def _import_from_csv(self, filename):
self.csv_filename = filename
fp = open(filename, 'r')
reader = csv.reader(fp)
data = list(reader) #reader is an iterator
fp.close()
self.headers = data[0]
self.rows = data[1:]
self.headers, self.rows = data[0], data[1:]


def to_csv(self, filename):
Expand Down
17 changes: 14 additions & 3 deletions tests/test_Table.py
Expand Up @@ -114,22 +114,33 @@ def test_table_with_changed_separators(self):
===== ====== ====== ''')


def test_table_should_accept_rows_as_dict_or_list_or_tuple(self):
def test_table_should_accept_rows_as_dict_list_tuple_int_or_float(self):
my_table = Table(headers=['ham', 'spam', 'eggs'])
my_table.rows.append({'ham': 'eggs', 'spam': 'ham', 'eggs': 'spam'})
my_table.rows.append([1, 2, 3])
my_table.rows.append([1, 42, 3])
my_table.rows.append([3.14, 2.71, 0.0])
my_table.rows.append(('spam', 'eggs', 'ham'))
self.assertEqual(str(my_table), '''
+------+------+------+
| ham | spam | eggs |
+------+------+------+
| eggs | ham | spam |
| 1 | 2 | 3 |
| 1 | 42 | 3 |
| 3.14 | 2.71 | 0.0 |
| spam | eggs | ham |
+------+------+------+
'''.strip())


def test_table_should_accept_headers_as_dict_list_tuple_int_or_float(self):
my_table = Table(headers=[42, 3.14, (4, 2), [3, 14], {'answer': 42}])
self.assertEqual(str(my_table), '''
+----+------+--------+---------+----------------+
| 42 | 3.14 | (4, 2) | [3, 14] | {'answer': 42} |
+----+------+--------+---------+----------------+
'''.strip())


def test_table_with_many_headers_and_rows_right_aligned(self):
my_table = Table(headers=['ham', 'spam', 'eggs'])
my_table.rows.append({'ham': '', 'spam': '', 'eggs': ''})
Expand Down

0 comments on commit 7d050f9

Please sign in to comment.