Last active
February 18, 2023 02:25
-
-
Save bpeterso2000/976777a4a4a1d09af32d6b80910da59d to your computer and use it in GitHub Desktop.
Display a list of lists as a simple text table with rows, columns and an optional header.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from math import log10 | |
from typing import Sequence | |
def print_table(rows: Sequence[Sequence], hdr=True, rownums=True) -> None: | |
"""Display as a simple text table; rows, columns & optional header. | |
rows: | |
Rows & columns where each cell object is a string or can be | |
converted into a string. | |
hdr: | |
Indicates that the first row contains header labels | |
rownums: | |
Adda a new column at the beginning of the table containing | |
row numbers. | |
raises: | |
TypeError if a cell can't be coverted to a string. | |
tailored for low-complexity: | |
* If rows differ in numbers of columns then blank cells will | |
be padded to ensure every row has the same number of columns. | |
* The text in the cells will be always be left aligned; | |
doesn't support other alignments. | |
* The borders are always drawn with pluses (+) and dashes (-); | |
doesn't support border customization | |
* Doesn't support word wrapping in cells. | |
* Doesn't check and limit column sizes to fit terminal width. | |
* Doesn't support column or row spanning. | |
>>> table = [ | |
... ['Element', 'Symbol', 'Upper Crustal Abundance (ppm)'], | |
... ['Cerium', 'Ce', 64], | |
... ['Lanthanum', 'La', 30] | |
... ] | |
>>> print_table(table) | |
+---+-----------+--------+-------------------------------+ | |
| | Element | Symbol | Upper Crustal Abundance (ppm) | | |
+---+-----------+--------+-------------------------------+ | |
| 1 | Cerium | Ce | 64 | | |
| 2 | Lanthanum | La | 30 | | |
+---+-----------+--------+-------------------------------+ | |
>>> print_table(table, rownums=False) | |
+-----------+--------+-------------------------------+ | |
| Element | Symbol | Upper Crustal Abundance (ppm) | | |
+-----------+--------+-------------------------------+ | |
| Cerium | Ce | 64 | | |
| Lanthanum | La | 30 | | |
+-----------+--------+-------------------------------+ | |
>>> table = table[1:] | |
>>> print_table(table, hdr=False) | |
+---+-----------+----+----+ | |
| 1 | Cerium | Ce | 64 | | |
| 2 | Lanthanum | La | 30 | | |
+---+-----------+----+----+ | |
>>> print_table(table, hdr=False, rownums=False) | |
+-----------+----+----+ | |
| Cerium | Ce | 64 | | |
| Lanthanum | La | 30 | | |
+-----------+----+----+ | |
>>> table = [['Element', 'Symbol', 'No Data'], ['Cerium', 'Ce']] | |
>>> print_table(table) | |
+---+---------+--------+---------+ | |
| | Element | Symbol | No Data | | |
+---+---------+--------+---------+ | |
| 1 | Cerium | Ce | | | |
+---+---------+--------+---------+ | |
""" | |
# ensure each row has the same number of columns | |
uniq_num_cols = {len(i) for i in rows} | |
if len(uniq_num_cols) > 1: | |
num_cols = max(uniq_num_cols) | |
rows = [i + [''] * (num_cols - len(i)) for i in rows] | |
# add a column containing the row numbers | |
if rownums: | |
rows = rows[:] | |
if hdr: | |
rows[0] = [''] + rows[0] | |
for num in range(hdr, len(rows)): | |
rows[num] = [num + (not hdr)] + rows[num] | |
try: | |
widths = [max(len(str(j)) for j in i) for i in zip(*rows)] | |
except TypeError: | |
raise | |
# draw table | |
res = [] | |
for row in rows: | |
cols = ' | '.join(str(j).ljust(k) for j, k in zip(row, widths)) | |
res.append(f'| {cols} |') | |
hsep = ['+%s+' % '+'.join('-' * (i + 2) for i in widths)] | |
if hdr: | |
res = res[:1] + hsep + res[1:] | |
print('\n'.join(hsep + res + hsep)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment