armi.utils.tabulate module
Pretty-print tabular data.
This file started out as the MIT-licensed “tabulate”. Though we have made, and will continue to make, many arbitrary changes as we need. Thanks to the tabulate team.
https://github.com/astanin/python-tabulate
Usage
The module provides just one function, tabulate, which takes a list of lists or other tabular data type as the first argument, and outputs anicely-formatted plain-text table:
>>> from armi.utils.tabulate import tabulate
>>> table = [["Sun",696000,1989100000],["Earth",6371,5973.6],
... ["Moon",1737,73.5],["Mars",3390,641.85]]
>>> print(tabulate(table))
----- ------ -------------
Sun 696000 1.9891e+09
Earth 6371 5973.6
Moon 1737 73.5
Mars 3390 641.85
----- ------ -------------
The following tabular data types are supported:
list of lists or another iterable of iterables
list or another iterable of dicts (keys as columns)
dict of iterables (keys as columns)
list of dataclasses (field names as columns)
two-dimensional NumPy array
NumPy record arrays (names as columns)
Table headers
To print nice column headers, supply the second argument (headers):
headers can be an explicit list of column headers
if headers=”firstrow”, then the first row of data is used
if headers=”keys”, then dictionary keys or column indices are used
Otherwise a headerless table is produced.
If the number of headers is less than the number of columns, they are supposed to be names of the last columns. This is consistent with the plain-text format of R:
>>> print(tabulate([["sex","age"],["Alice","F",24],["Bob","M",19]],
... headers="firstrow"))
sex age
----- ----- -----
Alice F 24
Bob M 19
Column and Headers alignment
tabulate tries to detect column types automatically, and aligns the values properly. By default it aligns decimal points of the numbers (or flushes integer numbers to the right), and flushes everything else to the left. Possible column alignments (numAlign, strAlign) are: “right”, “center”, “left”, “decimal” (only for numAlign), and None (to disable alignment).
- colGlobalAlign allows for global alignment of columns, before any specific override from
colAlign. Possible values are: None (defaults according to coltype), “right”, “center”, “decimal”, “left”.
- colAlign allows for column-wise override starting from left-most column. Possible values are:
“global” (no override), “right”, “center”, “decimal”, “left”.
- headersGlobalAlign allows for global headers alignment, before any specific override from
headersAlign. Possible values are: None (follow columns alignment), “right”, “center”, “left”.
- headersAlign allows for header-wise override starting from left-most given header. Possible
values are: “global” (no override), “same” (follow column alignment), “right”, “center”, “left”.
Note on intended behaviour: If there is no data, any column alignment argument is ignored. Hence, in this case, header alignment cannot be inferred from column alignment.
Table formats
intFmt is a format specification used for columns which contain numeric data without a decimal point. This can also be a list or tuple of format strings, one per column.
floatFmt is a format specification used for columns which contain numeric data with a decimal point. This can also be a list or tuple of format strings, one per column.
None values are replaced with a missingVal string (like floatFmt, this can also be a list of values for different columns):
>>> print(tabulate([["spam", 1, None],
... ["eggs", 42, 3.14],
... ["other", None, 2.7]], missingVal="?"))
----- -- ----
spam 1 ?
eggs 42 3.14
other ? 2.7
----- -- ----
Various plain-text table formats (tableFmt) are supported: ‘plain’, ‘simple’, ‘grid’, ‘rst’, and tsv. Variable tabulateFormats contains the list of currently supported formats.
“plain” format doesn’t use any pseudographics to draw tables, it separates columns with a double space:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
... ["strings", "numbers"], "plain"))
strings numbers
spam 41.9999
eggs 451
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tableFmt="plain"))
spam 41.9999
eggs 451
“simple” format is like Pandoc simple_tables:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
... ["strings", "numbers"], "simple"))
strings numbers
--------- ---------
spam 41.9999
eggs 451
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tableFmt="simple"))
---- --------
spam 41.9999
eggs 451
---- --------
“grid” is similar to tables produced by Emacs table.el package or Pandoc grid_tables:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
... ["strings", "numbers"], "grid"))
+-----------+-----------+
| strings | numbers |
+===========+===========+
| spam | 41.9999 |
+-----------+-----------+
| eggs | 451 |
+-----------+-----------+
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tableFmt="grid"))
+------+----------+
| spam | 41.9999 |
+------+----------+
| eggs | 451 |
+------+----------+
“rst” is like a simple table format from reStructuredText; please note that reStructuredText accepts also “grid” tables:
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]],
... ["strings", "numbers"], "rst"))
========= =========
strings numbers
========= =========
spam 41.9999
eggs 451
========= =========
>>> print(tabulate([["spam", 41.9999], ["eggs", "451.0"]], tableFmt="rst"))
==== ========
spam 41.9999
eggs 451
==== ========
Number parsing
By default, anything which can be parsed as a number is a number. This ensures numbers represented as strings are aligned properly. This can lead to weird results for particular strings such as specific git SHAs e.g. “42992e1” will be parsed into the number 429920 and aligned as such.
To completely disable number parsing (and alignment), use disableNumParse=True. For more fine grained control, a list column indices is used to disable number parsing only on those columns e.g. disableNumParse=[0, 2] would disable number parsing only on the first and third columns.
Column Widths and Auto Line Wrapping
Tabulate will, by default, set the width of each column to the length of the longest element in that column. However, in situations where fields are expected to reasonably be too long to look good as a single line, tabulate can help automate word wrapping long fields for you. Use the parameter maxcolwidth to provide a list of maximal column widths:
>>> print(tabulate( \
[('1', 'John Smith', \
'This is a rather long description that might look better if it is wrapped a bit')], \
headers=("Issue Id", "Author", "Description"), \
maxColWidths=[None, None, 30], \
tableFmt="grid" \
))
+------------+------------+-------------------------------+
| Issue Id | Author | Description |
+============+============+===============================+
| 1 | John Smith | This is a rather long |
| | | description that might look |
| | | better if it is wrapped a bit |
+------------+------------+-------------------------------+
Header column width can be specified in a similar way using maxheadercolwidth.
- class armi.utils.tabulate.Line(begin, hline, sep, end)
Bases:
tuple
Create new instance of Line(begin, hline, sep, end)
- begin
Alias for field number 0
- end
Alias for field number 3
- hline
Alias for field number 1
- sep
Alias for field number 2
- class armi.utils.tabulate.DataRow(begin, sep, end)
Bases:
tuple
Create new instance of DataRow(begin, sep, end)
- begin
Alias for field number 0
- end
Alias for field number 2
- sep
Alias for field number 1
- class armi.utils.tabulate.TableFormat(lineabove, linebelowheader, linebetweenrows, linebelow, headerrow, datarow, padding, withHeaderHide)
Bases:
tuple
Create new instance of TableFormat(lineabove, linebelowheader, linebetweenrows, linebelow, headerrow, datarow, padding, withHeaderHide)
- datarow
Alias for field number 5
- headerrow
Alias for field number 4
- lineabove
Alias for field number 0
- linebelow
Alias for field number 3
- linebelowheader
Alias for field number 1
- linebetweenrows
Alias for field number 2
- padding
Alias for field number 6
- withHeaderHide
Alias for field number 7
- armi.utils.tabulate.tabulate(data, headers=(), tableFmt='simple', floatFmt='g', intFmt='', numAlign='default', strAlign='default', missingVal='', showIndex='default', disableNumParse=False, colGlobalAlign=None, colAlign=None, maxColWidths=None, headersGlobalAlign=None, headersAlign=None, rowAlign=None, maxHeaderColWidths=None)[source]
Format a fixed width table for pretty printing.
- Parameters:
data (object) – The tabular data you want to print. This can be a list-of-lists/iterables, dict-of-lists/ iterables, 2D numpy arrays, or list of dataclasses.
headers=() – Nice column names. If this is “firstrow”, the first row of the data will be used. If it is “keys”m, then dictionary keys or column indices are used.
optional – Nice column names. If this is “firstrow”, the first row of the data will be used. If it is “keys”m, then dictionary keys or column indices are used.
tableFmt (str, optional) – There are custom table formats defined in this file, and you can choose between them with this string: “armi”, “simple”, “plain”, “grid”, “github”, “pretty”, “psql”, “rst”, “tsv”.
floatFmt (str, optional) – A format specification used for columns which contain numeric data with a decimal point. This can also be a list or tuple of format strings, one per column.
intFmt (str, optional) – A format specification used for columns which contain numeric data without a decimal point. This can also be a list or tuple of format strings, one per column.
numAlign (str, optional) – Specially align numbers, options: “right”, “center”, “left”, “decimal”.
strAlign (str, optional) – Specially align strings, options: “right”, “center”, “left”.
missingVal (str, optional) – None values are replaced with a missingVal string.
showIndex (str, optional) – Show these rows of data. If “always”, show row indices for all types of data. If “never”, don’t show row indices for all types of data. If showIndex is an iterable, show its values..
disableNumParse (bool, optional) – To disable number parsing (and alignment), use disableNumParse=True. For more fine grained control, [0, 2] would disable number parsing on the first and third columns.
colGlobalAlign (str, optional) – Allows for global alignment of columns, before any specific override from colAlign. Possible values are: None, “right”, “center”, “decimal”, “left”.
colAlign (str, optional) – Allows for column-wise override starting from left-most column. Possible values are: “global” (no override), “right”, “center”, “decimal”, “left”.
maxColWidths (list, optional) – A list of the maximum column widths.
headersGlobalAlign (str, optional) – Allows for global headers alignment, before any specific override from headersAlign. Possible values are: None (follow columns alignment), “right”, “center”, “left”.
headersAlign (str, optional) – Allows for header-wise override starting from left-most given header. Possible values are: “global” (no override), “same” (follow column alignment), “right”, “center”, “left”.
rowAlign (str, optional) – How do you want to align rows: “right”, “center”, “decimal”, “left”.
maxHeaderColWidths (list, optional) – List of column widths for the header.
- Returns:
A text representation of the tabular data.
- Return type: