Skip to content

Commit 2b2c9d8

Browse files
authored
Merge pull request #21 from python-tableformatter/README_TODOs
Completed basic documentation in README.md
2 parents 9a1dd65 + ac887c5 commit 2b2c9d8

File tree

3 files changed

+148
-42
lines changed

3 files changed

+148
-42
lines changed

README.md

Lines changed: 131 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
tableformatter: tabular data formatter
2-
======================================
1+
# tableformatter: tabular data formatter
32
[![Latest Version](https://img.shields.io/pypi/v/tableformatter.svg?style=flat-square&label=latest%20stable%20version)](https://pypi.org/project/tableformatter/)
43
[![Build status](https://api.travis-ci.com/python-tableformatter/tableformatter.svg?branch=master)](https://travis-ci.com/python-tableformatter/tableformatter)
54
[![Appveyor build status](https://img.shields.io/appveyor/ci/anselor/tableformatter.svg?style=flat-square&label=windows%20build)](https://ci.appveyor.com/project/anselor/tableformatter)
@@ -16,8 +15,8 @@ receive arbitrary Python objects.
1615

1716
[![Screenshot](tf.png)](https://github.com/python-tableformatter/tableformatter/blob/master/tf.png)
1817

19-
Main Features
20-
-------------
18+
19+
## Main Features
2120
- Easy to display simple tables with just one function call when you don't need the fine-grained control
2221
- Fine-grained control of almost every aspect of how data is formatted when you want it
2322
- Tables with column headers
@@ -28,14 +27,13 @@ Main Features
2827
- Support for Python 3.4+ on Windows, macOS, and Linux
2928

3029

31-
Installation
32-
============
30+
## Installation
3331
```Bash
3432
pip install tableformatter
3533
```
3634

37-
Dependencies
38-
------------
35+
36+
## Dependencies
3937
``tableformatter`` depends on the [wcwidth](https://github.com/jquast/wcwidth) module for measuring the width of
4038
unicode strings rendered to a terminal.
4139

@@ -46,20 +44,19 @@ If you wish to use the optional support for color, then at least one of the foll
4644
If both ``colorama`` and ``colored`` are installed, then ``colored`` will take precedence.
4745

4846

49-
Usage
50-
=====
47+
## Usage
5148
For simple cases, you only need to use a single function from this module: ``generate_table``. The only required argument
5249
to this function is ``rows`` which is an Iterable of Iterables such as a list of lists or another tabular data type like
5350
a 2D [numpy](http://www.numpy.org) array. ``generate_table`` outputs a nicely formatted table:
5451

5552
```Python
56-
from tableformatter import generate_table
53+
import tableformatter as tf
5754

5855
rows = [('A1', 'A2', 'A3', 'A4'),
5956
('B1', 'B2\nB2\nB2', 'B3', 'B4'),
6057
('C1', 'C2', 'C3', 'C4'),
6158
('D1', 'D2', 'D3', 'D4')]
62-
print(generate_table(rows))
59+
print(tf.generate_table(rows))
6360
╔════╤════╤════╤════╗
6461
║ A1 │ A2 │ A3 │ A4 ║
6562
║ B1 │ B2 │ B3 │ B4 ║
@@ -72,13 +69,13 @@ print(generate_table(rows))
7269

7370
*NOTE: Rendering of tables looks much better in Python than it appears in this Markdown file.*
7471

75-
Column Headers
76-
--------------
72+
73+
## Column Headers
7774
The second argument to ``generate_table`` named ``columns`` is optional and defines a list of column headers to be used.
7875

7976
```Python
8077
cols = ['Col1', 'Col2', 'Col3', 'Col4']
81-
print(generate_table(rows, cols))
78+
print(tf.generate_table(rows, cols))
8279
╔══════╤══════╤══════╤══════╗
8380
║ Col1 │ Col2 │ Col3 │ Col4 ║
8481
╠══════╪══════╪══════╪══════╣
@@ -91,8 +88,8 @@ print(generate_table(rows, cols))
9188
╚══════╧══════╧══════╧══════╝
9289
```
9390

94-
Grid Style
95-
----------
91+
92+
## Grid Style
9693
The third argument to ``generated`` table named ``grid_style`` is optional and specifies how the table lines are drawn.
9794

9895
Supported grid sytles are:
@@ -102,9 +99,7 @@ Supported grid sytles are:
10299
* **SparseGrid** - sparse grid with no lines at all to conserve both vertical and horizontal space
103100

104101
```Python
105-
from tableformatter import FancyGrid
106-
107-
print(generate_table(rows, grid_style=FancyGrid()))
102+
print(tf.generate_table(rows, grid_style=tf.FancyGrid()))
108103
╔════╤════╤════╤════╗
109104
║ A1 │ A2 │ A3 │ A4 ║
110105
╟────┼────┼────┼────╢
@@ -118,14 +113,14 @@ print(generate_table(rows, grid_style=FancyGrid()))
118113
╚════╧════╧════╧════╝
119114
```
120115

121-
Transposed Tables
122-
-----------------
116+
117+
## Transposed Tables
123118
Normally the "rows" are displayed left-to-right and "columns" are displayed up-to-down. However, if you want to transpose
124119
this and print "rows" up-to-down and "columns" left-to-right then that is easily done using the fourth (optional) argument
125120
to ``generate_table``:
126121

127122
```Python
128-
print(generate_table(rows, cols, transpose=True))
123+
print(tf.generate_table(rows, cols, transpose=True))
129124
╔══════╦════╤════╤════╤════╗
130125
║ Col1 ║ A1 │ B1 │ C1 │ D1 ║
131126
║ Col2 ║ A2 │ B2 │ C2 │ D2 ║
@@ -136,14 +131,118 @@ print(generate_table(rows, cols, transpose=True))
136131
╚══════╩════╧════╧════╧════╝
137132
```
138133

139-
Column Alignment
140-
----------------
141-
TODO
142134

143-
Number Formatting
144-
-----------------
145-
TODO
135+
## Column Formatting
136+
For rich column formatting, instead of passing a simple iterable to the 2nd argument of ``generate_table``, an iterable
137+
of ``tableformatter.Column`` objects can be passed. The ``Column`` class has the following attributes, all of which are
138+
optional other than the first:
139+
140+
| Attribute name | Description |
141+
| -------------- | ----------- |
142+
| col_name | Column name to display
143+
| width | Number of displayed terminal characters. Unicode wide characters count as 2 displayed characters.
144+
| attrib | The name of the object attribute to look up for cell contents on this column
145+
| wrap_mode | Defines how to handle long cells that must be wrapped or truncated
146+
| wrap_prefix | String to display at the beginning of each wrapped line in a cell
147+
| cell_padding | Number of padding spaces to the left and right of each cell
148+
| header_halign | Horizontal alignment of the column header
149+
| header_valign | Vertical alignment of the column header
150+
| cell_halign | Horizontal alignment of the cells in this column
151+
| cell_valign | Vertical alignment of the cells in this column
152+
| formatter | Callable that can process the value in this column for display
153+
| obj_formatter | Callable that processes the row object to generate content for this column
154+
155+
See the [columns.py](https://github.com/python-tableformatter/tableformatter/blob/master/examples/columns.py) example
156+
for a demonstration for how all of these options can be used.
157+
158+
### Column Alignment
159+
You can override both the horizontal and vertical alignment. This can be done separately for the column header versus
160+
the cell contents.
161+
162+
Possible alignments are all elements within the ``ColumnAlignment`` enum class:
163+
* Horizontal alignments:
164+
* AlignLeft (*default*)
165+
* AlignCenter
166+
* AlignRight
167+
* Vertical alignments:
168+
* AlignTop (*default*)
169+
* AlignBottom
170+
171+
```Python
172+
columns = (tf.Column('Col1', cell_halign=tf.ColumnAlignment.AlignLeft),
173+
tf.Column('Col2', cell_halign=tf.ColumnAlignment.AlignRight),
174+
tf.Column('Col3', cell_halign=tf.ColumnAlignment.AlignCenter),
175+
tf.Column('Col4', cell_valign=tf.ColumnAlignment.AlignBottom))
176+
print(tf.generate_table(rows, columns))
177+
╔══════╤══════╤══════╤══════╗
178+
║ Col1 │ Col2 │ Col3 │ col4 ║
179+
╠══════╪══════╪══════╪══════╣
180+
║ A1 │ A2 │ A3 │ A4 ║
181+
║ B1 │ B2 │ B3 │ ║
182+
║ │ B2 │ │ ║
183+
║ │ B2 │ │ B4 ║
184+
║ C1 │ C2 │ C3 │ C4 ║
185+
║ D1 │ D2 │ D3 │ D4 ║
186+
╚══════╧══════╧══════╧══════╝
187+
```
188+
189+
### Number Formatting
190+
The ``formatter`` attribute of the ``Column`` class accepts an arbitrary callable which accepts a single argument containing
191+
the cell contents for that column and returns a string with the contents formatted in the
192+
desired format. There are a couple callable classes built into ``tableformatter`` to help
193+
formatting numbers:
194+
* FormatBytes - formats a value in bytes into a human readable string
195+
* FormatCommas - Formats a number with comma separators
196+
197+
```Python
198+
rows = [(None, None),
199+
('123', '123'),
200+
(123, 123),
201+
(12345, 12345),
202+
(12345678, 12345678),
203+
(1234567890, 1234567890),
204+
(1234567890123, 1234567890123)]
205+
cols = (tf.Column('First', width=20, formatter=tf.FormatBytes(), cell_halign=tf.ColumnAlignment.AlignRight),
206+
tf.Column('Second', formatter=tf.FormatCommas(), cell_halign=tf.ColumnAlignment.AlignRight))
207+
print(tf.generate_table(rows, cols))
208+
╔═══════════╤═══════════════════╗
209+
║ First │ Second ║
210+
╠═══════════╪═══════════════════╣
211+
║ │ ║
212+
123.00 B │ 123
213+
123.00 B │ 123
214+
12.06 KB12,345
215+
11.77 MB12,345,678
216+
1.15 GB1,234,567,890
217+
1.12 TB1,234,567,890,123
218+
╚═══════════╧═══════════════════╝
219+
```
220+
221+
See the [cmd2_tables.py](https://github.com/python-tableformatter/tableformatter/blob/master/examples/formatters.py) example
222+
for examples of how custom formatter functions can be used.
223+
224+
225+
## Color
226+
If either ``colorama`` or ``colored`` is installed, then ``tableformatter`` has support for altering both the foreground
227+
and background color of cell contents.
228+
229+
### Alternating background row color
230+
It is trivial to alternate the background color of each row as follows:
231+
```Python
232+
from colorama import Back
233+
print(generate_table(rows, cols, grid_style=tf.AlternatingRowGrid(Back.GREEN, Back.BLUE)))
234+
```
235+
See the [cmd2_tables.py](https://github.com/python-tableformatter/tableformatter/blob/master/examples/cmd2_tables.py) or
236+
[color.py](https://github.com/python-tableformatter/tableformatter/blob/master/examples/color.py) examples for more
237+
complete examples.
238+
239+
### Dynamically setting cell color based on cell contents
240+
The 5th argument to ``generate_table`` is **row_tagger** and it expects a callable which accepts a single argument for
241+
the row contents and returns a dictionary of row options for that row which can
242+
be used to set the foreground and/or background color of all cells in that row.
243+
244+
See the ``high_density_tuples`` function in the [cmd2_tables.py](https://github.com/python-tableformatter/tableformatter/blob/master/examples/cmd2_tables.py)
245+
example for a demonstration of how to use this feature.
246+
247+
146248

147-
Color
148-
-----
149-
TODO

examples/cmd2_tables.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22
# coding=utf-8
33
"""A simple example demonstrating the following:
44
1) How to integrate tableformatter into an interactive command-line application using the cmd2 module
@@ -31,11 +31,13 @@
3131
# Configure colors for when users chooses the "-c" flag to enable color in the table output
3232
try:
3333
from colored import bg
34+
3435
BACK_PRI = bg(4)
3536
BACK_ALT = bg(22)
3637
except ImportError:
3738
try:
3839
from colorama import Back
40+
3941
BACK_PRI = Back.LIGHTBLUE_EX
4042
BACK_ALT = Back.LIGHTYELLOW_EX
4143
except ImportError:
@@ -64,12 +66,11 @@ def two_dec(num: float) -> str:
6466
['Guangzho (广州市)', 'Guangdong', 'China', 'Asia', 13081000, 1347.81],
6567
['Mumbai (मुंबई)', 'Maharashtra', 'India', 'Asia', 12442373, 465.78],
6668
['Istanbul (İstanbuld)', 'Istanbul', 'Turkey', 'Eurasia', 12661000, 620.29],
67-
]
69+
]
6870

6971
# Calculate population density
7072
for row in EXAMPLE_ITERABLE_DATA:
71-
row.append(row[-2]/row[-1])
72-
73+
row.append(row[-2] / row[-1])
7374

7475
# Column headers plus optional formatting info for each column
7576
COLUMNS = [tf.Column('City', width=11, header_halign=tf.ColumnAlignment.AlignCenter),
@@ -81,13 +82,14 @@ def two_dec(num: float) -> str:
8182
cell_halign=tf.ColumnAlignment.AlignRight, formatter=two_dec),
8283
tf.Column('Pop. Density (/km²)', width=12, header_halign=tf.ColumnAlignment.AlignCenter,
8384
cell_halign=tf.ColumnAlignment.AlignRight, formatter=no_dec),
84-
]
85+
]
8586

8687

8788
# ######## Table data formatted as an iterable of python objects #########
8889

8990
class CityInfo(object):
9091
"""City information container"""
92+
9193
def __init__(self, city: str, province: str, country: str, continent: str, population: int, area: float):
9294
self.city = city
9395
self.province = province
@@ -131,8 +133,7 @@ def pop_density(data: CityInfo) -> str:
131133
cell_halign=tf.ColumnAlignment.AlignRight, formatter=two_dec),
132134
tf.Column('Pop. Density (/km²)', width=12, header_halign=tf.ColumnAlignment.AlignCenter,
133135
cell_halign=tf.ColumnAlignment.AlignRight, obj_formatter=pop_density),
134-
]
135-
136+
]
136137

137138
EXTREMELY_HIGH_POULATION_DENSITY = 25000
138139

@@ -177,14 +178,20 @@ def ptable(self, rows, columns, grid_args, row_stylist):
177178
else:
178179
grid = None
179180

180-
formatted_table = tf.generate_table(rows=rows, columns=columns, grid_style=grid, row_tagger=row_stylist)
181+
transpose = False
182+
if grid_args.transpose:
183+
transpose = True
184+
185+
formatted_table = tf.generate_table(rows=rows, columns=columns, grid_style=grid, row_tagger=row_stylist,
186+
transpose=transpose)
181187
self.ppaged(formatted_table, chop=True)
182188

183189
table_parser = argparse.ArgumentParser()
184190
table_item_group = table_parser.add_mutually_exclusive_group()
185191
table_item_group.add_argument('-c', '--color', action='store_true', help='Enable color')
186192
table_item_group.add_argument('-f', '--fancy', action='store_true', help='Fancy Grid')
187193
table_item_group.add_argument('-s', '--sparse', action='store_true', help='Sparse Grid')
194+
table_parser.add_argument('-t', '--transpose', action='store_true', help='Transpose rows and columns')
188195

189196
@cmd2.with_argparser(table_parser)
190197
def do_table(self, args):

tableformatter.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -668,14 +668,14 @@ def Column(col_name: str,
668668
:param col_name: Column name to display
669669
:param width: Number of displayed terminal characters. Unicode wide characters count as 2 displayed characters.
670670
:param attrib: The name of the object attribute to look up for cell contents on this column
671-
:param wrap_mode: Defines how to handle long cells that must be wropped or truncated
671+
:param wrap_mode: Defines how to handle long cells that must be wrapped or truncated
672672
:param wrap_prefix: String to display at the beginning of each wrapped line in a cell
673673
:param cell_padding: Number of padding spaces to the left and right of each cell
674674
:param header_halign: Horizontal alignment of the column header
675675
:param header_valign: Vertical alignment of the column header
676676
:param cell_halign: Horizontal alignment of the cells in this column
677677
:param cell_valign: Vertical alignment of the cells in this column
678-
:param formatter: Callable that can process the value in this column for display.
678+
:param formatter: Callable that can process the value in this column for display
679679
:param obj_formatter: Callable that processes the row object to generate content for this column
680680
:return: A column tuple the TableFormatter expects
681681
"""

0 commit comments

Comments
 (0)