Last active
July 3, 2018 07:46
-
-
Save jerblack/4daade57690dadcb6b1c330fc00295e3 to your computer and use it in GitHub Desktop.
Python table printing function which will print a structured table with headers, defined column widths, automatic text wrapping in columns, and automatic table sizing to fit the table within the terminal width.
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
""" | |
print_table will print a structured table with headers, defined column widths, and automatic text wrapping in columns. | |
It will also determine the terminal width and reduce the column widths automatically so they all fit without wrapping outside of the table | |
print_table requires 3 parameters | |
headers: A list or tuple of headers (strings) | |
rows: A list of lists or tuples with table row information as strings | |
each entry in inner list maps to a column. | |
For a 3 column table, provide a list of lists or tuples with a length of 3 | |
sizes: A list or tuple of integers specifying maximum column width for each column. Must provide a value for each column. | |
columns will automatically be shrunk to fit the size of the widest data in the column if smaller than max width. | |
""" | |
import os | |
DEFAULT_WIDTH = 80 | |
def print_table(headers, rows, sizes): | |
def fit_to_term(): | |
# find terminal width, then reduce largest column size by 1 until everything fits | |
try: | |
x, _ = os.get_terminal_size() | |
except OSError: | |
x = DEFAULT_WIDTH | |
width = sum(short_sizes) + len(short_sizes) - 1 | |
sizes = [s for s in short_sizes] | |
while width > x: | |
widest = max(sizes) | |
for n, size in enumerate(sizes): | |
if size == widest: | |
sizes[n] -= 1 | |
width = sum(sizes) + len(sizes) - 1 | |
break | |
return sizes | |
output = [] | |
template = "" | |
if type(rows[0]) is str: | |
rows = [rows, ] | |
short_sizes = [] | |
# automatically shrink columns to the minimum required for the longest data if not longer than | |
# specified size | |
for n, s in enumerate(sizes): | |
max_size = s | |
h_len = len(headers[n]) | |
size = h_len if h_len < max_size else max_size | |
for r in rows: | |
s_len = len(r[n]) if len(r[n]) < max_size else max_size | |
size = s_len if s_len > size else size | |
short_sizes.append(size) | |
short_sizes = fit_to_term() | |
for size in short_sizes: | |
template += "{:<"+str(size)+"} " | |
def process_row(row): | |
while any(row): | |
line = [] | |
rest = [] | |
for n, s in enumerate(row): | |
line.append(s[:short_sizes[n]]) | |
rest.append(s[short_sizes[n]:]) | |
output.append(template.format(*line)) | |
row = rest | |
process_row(headers) | |
dashes = ['-'*s for s in short_sizes] | |
process_row(dashes) | |
for row in rows: | |
process_row(row) | |
for o in output: | |
print(o) | |
""" | |
# | |
# header = ['name','id','keywords'] | |
# rows = [['aabcdefghijklmnopqrstuvwxyz','babcdefghijklmnopqrstuvwxyz','cabcdefghijklmnopqrstuvwxyz'], | |
# ['dabcdefghijklmnopqrstuvwxyz', 'eabcdefghijklmnopqrstuvwxyz', 'fabcdefghijklmnopqrstuvwxyz'], | |
# ['aabcdefghijklmnopqrstuvwxyz','babcdefghijklmnopqrstuvwxyz','cabcdefghijklmnopqrstuvwxyz'], | |
# ['dabcdefghijklmnopqrstuvwxyz', 'eabcdefghijklmnopqrstuvwxyz', 'fabcdefghijklmnopqrstuvwxyz']] | |
# print_table(header, rows, (15, 10, 7)) | |
name id keyword | |
s | |
--------------- ---------- ------- | |
aabcdefghijklmn babcdefghi cabcdef | |
opqrstuvwxyz jklmnopqrs ghijklm | |
tuvwxyz nopqrst | |
uvwxyz | |
dabcdefghijklmn eabcdefghi fabcdef | |
opqrstuvwxyz jklmnopqrs ghijklm | |
tuvwxyz nopqrst | |
uvwxyz | |
aabcdefghijklmn babcdefghi cabcdef | |
opqrstuvwxyz jklmnopqrs ghijklm | |
tuvwxyz nopqrst | |
uvwxyz | |
dabcdefghijklmn eabcdefghi fabcdef | |
opqrstuvwxyz jklmnopqrs ghijklm | |
tuvwxyz nopqrst | |
uvwxyz | |
""" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment