Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # =============================================================================
- # >> IMPORTS
- # =============================================================================
- # Python
- import itertools
- import sys
- # =============================================================================
- # >> BACKWARDS COMPATIBILITY
- # =============================================================================
- # In Python 3 izip_longest has been renamed to zip_longest.
- if sys.version_info >= (3,):
- zip_longest = itertools.zip_longest
- else:
- zip_longest = itertools.izip_longest
- # =============================================================================
- # >> CONSTANTS
- # =============================================================================
- DEFAULT_ENCODING = 'utf-8'
- # =============================================================================
- # >> CLASSES
- # =============================================================================
- class Alignment(object):
- '''
- Contains constants to specify the aligment of table items.
- '''
- LEFT = unicode.ljust
- RIGHT = unicode.rjust
- CENTER = unicode.center
- class Column(list):
- '''
- Represents a column of a table.
- '''
- def __init__(self, name, alignment=Alignment.CENTER, left_padding=2,
- right_padding=2):
- '''
- Intializes the column.
- @param <name>:
- Name of the column.
- @param <alignment>:
- The alignment of the column name.
- @param <left_padding>:
- Number of spaces for left padding.
- @param <right_padding>:
- Number of spaces for right padding.
- '''
- self.name = Item(name, alignment)
- self.left_padding = left_padding
- self.right_padding = right_padding
- def _get_max_padding(self):
- '''
- Returns the length of the longest item in the column (including the
- name of the column).
- '''
- length = len(self.name)
- if not self:
- return length
- return max(len(max(self, key=len)), length)
- def _format(self, encoding=DEFAULT_ENCODING):
- '''
- Returns a two-tuple containing the formated name of the column and a
- tuple containing all formatted items of this row.
- '''
- padding = self._get_max_padding()
- return (
- self.name._format(
- padding, self.left_padding, self.right_padding, encoding),
- tuple(item._format(padding, self.left_padding,
- self.right_padding, encoding) for item in self)
- )
- class Item(object):
- '''
- Represents a value/item of a column.
- '''
- def __init__(self, value, alignment=Alignment.LEFT):
- '''
- Initializes the item.
- @param <value>:
- The value this item should have.
- @param <aligment>:
- The aligment of the item in the table.
- '''
- self.value = str(value)
- self.alignment = alignment
- def __len__(self):
- '''
- Returns the length of the value.
- '''
- return len(self.value)
- def _format(self, padding, left_padding, right_padding,
- encoding=DEFAULT_ENCODING):
- '''
- Formats the item.
- @param <padding>:
- The length of the longest item in the column.
- @param <left_padding>:
- A number that defines how many spaces should be added to the left of
- the item.
- @param <right_padding>:
- A number that defines how many spaces should be added to the right of
- the item.
- @param <encoding>:
- Specifies the encoding.
- '''
- return unicode(' ', encoding)*left_padding \
- + self.alignment(self.value.decode(encoding), padding) \
- + unicode(' ', encoding)*right_padding
- class HorizontalSeparator(Item):
- '''
- Represents a horizontal separator.
- '''
- def __init__(self, separator=unicode('-', DEFAULT_ENCODING)):
- '''
- Initializes the separator.
- @param <separator>:
- The character that should be used to separate.
- '''
- if not isinstance(separator, unicode) \
- or len(separator) != 1:
- raise ValueError('Separator must be a single character and a unicode object.')
- self.separator = separator
- def __len__(self):
- '''
- Returns 0.
- '''
- return 0
- def _format(self, padding, left_padding, right_padding,
- encoding=DEFAULT_ENCODING):
- '''
- Formats the item.
- @param <padding>:
- The length of the longest item in the column.
- @param <left_padding>:
- A number that defines how many spaces should be added to the left of
- the item.
- @param <right_padding>:
- A number that defines how many spaces should be added to the right of
- the item.
- @param <encoding>:
- Specifies the encoding.
- '''
- return self.separator.decode(encoding) \
- * (left_padding + padding + right_padding)
- class AsciiTable(object):
- '''
- Represents a table.
- '''
- def __init__(self, *columns):
- '''
- Adds the given objects as columns to the table. If a given column is
- not a Column object, it will be created.
- '''
- if len(columns) == 0:
- raise ValueError('Table must have at least one column.')
- self._columns = []
- for column in columns:
- if not isinstance(column, Column):
- column = Column(column)
- self._columns.append(column)
- def __len__(self):
- '''
- Returns the number of columns.
- '''
- return len(self._columns)
- def __iter__(self):
- '''
- Returns an iterator for all columns.
- '''
- return iter(self._columns)
- def __getitem__(self, index):
- '''
- Returns the column at the given index.
- '''
- return self._columns[index]
- def add_row(self, *items):
- '''
- Appends the given items to the table's columns.
- '''
- if len(items) != len(self):
- raise ValueError('You must add exactly the same number of items' \
- ' like the number of columns.')
- for index, item in enumerate(items):
- if not isinstance(item, Item):
- item = Item(item)
- self[index].append(item)
- def format(self, header_separator=unicode('=', DEFAULT_ENCODING),
- column_separator=unicode('|', DEFAULT_ENCODING),
- encoding=DEFAULT_ENCODING):
- '''
- Formats the table and returns an ASCII table string.
- @param <header_separator>:
- A single character that defines the character that should be used to
- create the horizontal separator.
- @param <column_separator>:
- A single character that defines the character that should be used to
- create the vertical separators.
- @param <encoding>:
- Specifies the encoding.
- '''
- if not isinstance(header_separator, unicode) \
- or len(header_separator) != 1:
- raise ValueError('Header separator must be a single character a' \
- 'nd a unicode object.')
- columns = []
- rows = []
- for column in self:
- column, row = column._format(encoding)
- columns.append(column)
- rows.append(row)
- header = column_separator.join(columns)
- return unicode('{0}\n{1}\n{2}', encoding).format(
- header,
- header_separator*len(header),
- unicode('\n', encoding).join(column_separator.join(row) \
- for row in zip_longest(*rows, fillvalue=''))
- )
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement