More Examples¶
Join tables together side by side¶
The function monotable.join_strings() lays out multi-line strings side by side. In this example table1, table2, and table3 are multi-line strings representing rendered ASCII tables. Note how the vertical alignment within each table is maintained in the result.
from monotable import join_strings
table1 = '\n'.join([
"',' and '%' formats.",
"--------------------",
" comma percent",
"--------------------",
"123,456,789 33.0%",
" 2,345,678 99.5%",
"--------------------"
])
table2 = '\n'.join([
" Formatting directives.",
"--------------------------------",
" 24 hour",
" temp wind precip.",
"hour change speed (inches)",
"--------------------------------",
"07 -2 11 3.40",
"08 same calm",
"09 +5 offline 0.67",
"--------------------------------"
])
table3 = '\n'.join([
" parentheses directive.",
"-------------------------",
"Description Amount",
"-------------------------",
"receivables 51",
"other assets 9,050",
"gifts n/a",
"pending payments (75)",
"other liabilities (623)",
"-------------------------",
])
tables = [table1, table2, table3]
print(join_strings(
tables,
rsep=' ')) # 3 spaces between each table
',' and '%' formats. Formatting directives. parentheses directive.
-------------------- -------------------------------- -------------------------
comma percent 24 hour Description Amount
-------------------- temp wind precip. -------------------------
123,456,789 33.0% hour change speed (inches) receivables 51
2,345,678 99.5% -------------------------------- other assets 9,050
-------------------- 07 -2 11 3.40 gifts n/a
08 same calm pending payments (75)
09 +5 offline 0.67 other liabilities (623)
-------------------------------- -------------------------
User defined format function¶
Set a user defined format function for the 3rd column.
The user defined format function directive is plugged in to the table by passing a mapping to mono() or monocol() as keyword only argument format_func_map. The mapping contains the name of the format function as the key and function object as the value.
The keys in the mapping become format directive function names.
from monotable import mono
# User defined format function.
def fulfill_menu_request(value, spec):
_, _ = value, spec # avoid unused variable nag
return 'Spam!' # ignore both args
my_functions = {'fulfill_menu_request': fulfill_menu_request}
headings = ['Id Number', 'Duties', 'Meal\nPreference']
formats = ['', '', '(fulfill_menu_request)']
cells = [[1, 'President and CEO', 'steak'],
[2, 'Raise capital', 'eggs'],
[3, 'Oversee day to day operations', 'toast']]
print(mono(
headings, formats, cells,
title='>User defined format function.',
format_func_map=my_functions))
User defined format function.
----------------------------------------------------
Meal
Id Number Duties Preference
----------------------------------------------------
1 President and CEO Spam!
2 Raise capital Spam!
3 Oversee day to day operations Spam!
----------------------------------------------------
- The user defined format function fulfill_menu_request() ignores the arguments and returns the string ‘Spam!’.
- Keys in the dictionary my_functions become directive names,
- The Duties column auto-aligns to the left since the cells are strings.
- The headings auto-align to the alignment of the cell in the first row.
- The title starts with an
'>'
align_spec_char which right aligns the title over the table.
Change or omit the guidelines¶
from monotable import mono
headings = ['purchased\nparrot\nheart rate', 'life\nstate']
# > is needed to right align None cell since it auto-aligns to left.
# monotable uses empty string to format the second column.
formats = ['>(none=rest).0f']
cells = [[0, 'demised'],
[0.0, 'passed on'],
[None, 'is no more'],
[-1],
[0, 'ceased to be']]
print(mono(
headings, formats, cells,
title='Complaint\n(registered)',
# top guideline is equals, heading is period, bottom is omitted.
guideline_chars='=. '))
Complaint
(registered)
========================
purchased
parrot life
heart rate state
........................
0 demised
0 passed on
rest is no more
-1
0 ceased to be
Limit column width¶
Here we employ the format directive (width=15) to limit the width of the second column to 15 characters or less. The more_marker ‘…’ shows where text was omitted.
The width=N format directive applies only to the cells, not the heading.
from monotable import mono
headings = ['Id Number', 'Duties', 'Start Date']
formats = ['', '(width=15)']
cells = [[1, 'President and CEO', '06/02/2016'],
[2, 'Raise capital', '06/10/2016'],
[3, 'Oversee day to day operations', '06/21/2016']]
print(mono(headings, formats, cells,
title='Limit center column to 15 characters.'))
Limit center column to 15 characters.
--------------------------------------
Id Number Duties Start Date
--------------------------------------
1 President an... 06/02/2016
2 Raise capital 06/10/2016
3 Oversee day ... 06/21/2016
--------------------------------------
Wrap a column and limit cell height¶
The second column is wrapped to a maximum width of 12 characters.
Here we customize an instance of class MonoTable in order to change the class variable max_cell_height. We call MonoTable’s table() method.
from monotable import MonoTable
headings = ['Id Number', 'Duties', 'Start Date']
formats = ['', '(width=12;wrap)']
t3 = MonoTable()
t3.max_cell_height = 2 # override class var
cells = [[1, 'President and CEO', '06/02/2016'],
[2, 'Raise capital', '06/10/2016'],
[3, 'Oversee day to day operations', '06/21/2016']]
title = ('Wrap center column to a maximum of 12 characters.\n'
'Limit cell height to 2 lines')
print(t3.table(headings, formats, cells, title=title))
Wrap center column to a maximum of 12 characters.
Limit cell height to 2 lines
----------------------------------
Id Number Duties Start Date
----------------------------------
1 President 06/02/2016
and CEO
2 Raise 06/10/2016
capital
3 Oversee day 06/21/2016
to day ...
----------------------------------
- Limiting the maximum cell height to 2 lines affects the Duties cell in the bottom row. The more_marker ‘…’ is placed at the end of the cell to indicate text was omitted.
- The default max_cell_height is None which means unlimited.
- max_cell_height is applied to every cell in the table.
- Changing max_cell_height to 1 assures there will be no multi-line cells in the table.
- The second column ended up wrapping to 11 characters wide, one character less than the format directive (width=12;wrap) specified. This behaviour is a side affect of using Python textwrap to implement the format directive.
Fix column width¶
Add ;fixed after (width=11) to fix the column width. The formatted text will be padded or truncated to the exact width.
fixed can also be used with wrap like this: (width=N;fixed;wrap).
from monotable import mono
headings = ['left\ncol', 'mid\ncol', 'right\ncol']
formats = ['', '^(width=11;fixed)']
cells = [['A', 1, 'x'],
['B', 222, 'y'],
['C', 3, 'z']]
title = 'Middle column is fixed width.'
print(mono(headings, formats, cells, title=title))
Middle column is fixed width.
------------------------
left mid right
col col col
------------------------
A 1 x
B 222 y
C 3 z
------------------------
- The align_spec_prefix ‘^’ of the formats[1] center justifies the column.
Selecting keys from a dictionary and table borders¶
This example sets the format function of the second column. A format string has the form:
[align_spec][directives][format_spec]
align_spec is one of the characters ‘<’, ‘^’, ‘>’ to override auto-alignment. align_spec is not used in this example.
directives is one or more format directives enclosed by '('
and ')'
separated by ';'
. In the second column the directive
is (mformat)
.
mformat selects the function monotable.plugin.mformat()
as the format function.
This example also shows formatted cells with newlines.
from monotable import mono
headings = ['int', 'Formatted by mformat()']
formats = ['',
'(mformat)name= {name}\nage= {age:.1f}\ncolor= {favorite_color}']
cells = [[2345, dict(name='Row Zero',
age=888.000,
favorite_color='blue')],
[6789, dict(name='Row One',
age=999.111,
favorite_color='No! Red!')]]
print(mono(headings, formats, cells,
title='mformat() Formatting.',
bordered=True))
mformat() Formatting.
+------+------------------------+
| int | Formatted by mformat() |
+======+========================+
| 2345 | name= Row Zero |
| | age= 888.0 |
| | color= blue |
+------+------------------------+
| 6789 | name= Row One |
| | age= 999.1 |
| | color= No! Red! |
+------+------------------------+
Selecting attributes or elements¶
Here one attribute of a cell object is selected for formatting in the first column. The second column selects the element indexed by [1] from a sequence.
from monotable import mono
headings = ['x\nattrib.', '[1]\nindex']
formats = ['(sformat){.x}', '(sformat){[1]}']
class MyCell:
def __init__(self, x, y):
self.x = x
self.y = y
cells = [[MyCell(1, 91), ['a', 'bb']],
[MyCell(2, 92), ['c', 'dd']]]
print(mono(headings, formats, cells,
title='<Select attribute/index.'))
Select attribute/index.
--------------
x [1]
attrib. index
--------------
1 bb
2 dd
--------------
- Set the format directive to ‘(sformat)’ to select monotable.plugin.sformat() as the format function. It is an adapter to string.format().
- The format_spec
'{.x}'
selects the attribute named ‘x’ of the cell. - The format_spec
'{[1]}'
selects the element at index 1 of the cell. - Note that a cell passed to str.format() satisfies only the first replacement field of the Python Format String Syntax. You can only use one replacement field with the sformat format directive.
- Note that the first column auto-aligns to the left. This is because auto-align senses the cell type which is class MyCell. Only cells that inherit from numbers.Number are auto-aligned to the right. MyCell does not inherit from numbers.Number.
- You can override auto-alignment on the first
column by adding the align_spec
'>'
at the start of the format string. - Since the heading auto-aligns to the alignment of the cell in the first row, you can also override auto-alignment on the first heading to keep it left aligned.
# Continues previous example.
headings = ['<x\nattrib.', '[1]\nindex']
formats = ['>(sformat){.x}', '(sformat){[1]}']
print(mono(headings, formats, cells,
title='<Select attribute/index.'))
Select attribute/index.
--------------
x [1]
attrib. index
--------------
1 bb
2 dd
--------------
Make a reStructuredText Simple Table¶
The separated_guidelines and guideline_chars class variables can be overridden to produce reStructuredText Simple Table markup.
from monotable import MonoTable
class SeparatedMonoTable(MonoTable):
separated_guidelines = True
guideline_chars = '==='
headings = ['directive name', 'format function', 'description']
t4 = SeparatedMonoTable()
cells = [['mformat', 'monotable.plugin.mformat', 'mapping with str.format()'],
['pformat', 'monotable.plugin.pformat', 'printf style'],
['sformat', 'monotable.plugin.sformat', 'str.format()'],
['tformat', 'monotable.plugin.tformat', 'string.Template()'],
['function-name', '--', 'user defined function']]
print(t4.table(headings, [], cells))
============== ======================== =========================
directive name format function description
============== ======================== =========================
mformat monotable.plugin.mformat mapping with str.format()
pformat monotable.plugin.pformat printf style
sformat monotable.plugin.sformat str.format()
tformat monotable.plugin.tformat string.Template()
function-name -- user defined function
============== ======================== =========================
Which looks like this when rendered.
directive name | format function | description |
---|---|---|
mformat | monotable.plugin.mformat | mapping with str.format() |
pformat | monotable.plugin.pformat | printf style |
sformat | monotable.plugin.sformat | str.format() |
tformat | monotable.plugin.tformat | string.Template() |
function-name | – | user defined function |
String template substitution¶
The format directive tformat is used to select keys from a dictionary. It is implemented by an adapter to Python standard library string.Template.substitute().
from monotable import MonoTable
headings = ['an\nint', 'Formatted by\nstr.Template()']
formats = ['', '(tformat)name= $name\nage= $age\ncolor= $favorite_color']
cells = [[2345,
dict(name='Row Zero', age=888, favorite_color='blue')],
[6789,
dict(name='Row One', age=999, favorite_color='No......')]]
print(mono(headings, formats, cells,
title='A multi-line\nTitle.', bordered=True))
A multi-line
Title.
+------+-----------------+
| an | Formatted by |
| int | str.Template() |
+======+=================+
| 2345 | name= Row Zero |
| | age= 888 |
| | color= blue |
+------+-----------------+
| 6789 | name= Row One |
| | age= 999 |
| | color= No...... |
+------+-----------------+
- The title auto-aligns to center justification.
- Title auto-alignment is overridden by placing an align_spec char at the beginning of the title string.
Tiled table of four tables¶
See test_tile_four_tables_together() near the bottom of pytest cases of examples.