-
-
Save sdcampbell/1d9febc4494610cfbaac50a42e5e13d8 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
''' | |
basictable | |
Copyright (c) 2017 Rich Kelley | |
Contact: | |
@RGKelley5 | |
RK5DEVMAIL[A T]gmail[D O T]com | |
www.bytesdarkly.com | |
License: MIT | |
This module contains a single function, print_table, that is used to format screen output for recordsets. | |
I often need to print table formated data, but don't want to require external libs. This function is compact enough | |
to be included in any script. | |
Data Format: | |
----------- | |
The recordset format is a list of dictionaries where the dictionary keys are the column headings. All the | |
records are required to have the same number of columns and same heading values (keys) | |
[ | |
{'Col1':data1, 'Col2': data2, 'Col3':data2, 'Col4':'data4'}, | |
{'Col1':data1, 'Col2': data2, 'Col3':data2, 'Col4':'data4'}, | |
{'Col1':data1, 'Col2': data2, 'Col3':data2, 'Col4':'data4'}, | |
{'Col1':data1, 'Col2': data2, 'Col3':data2, 'Col4':'data4'}, | |
] | |
Usage: | |
------ | |
>>> from basictable import print_table | |
>>> data = [] | |
>>> for i in range(20): | |
... data.append({'Col1':1, 'Col2': "test", 'Col3':'test test', 'Col4':'some longer string'}) | |
... | |
>>> print_table(data) | |
Col3 Col4 Col1 Col2 | |
--------- ------------------ ---- ---- | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
>>> print_table(data, border=True) | |
|------------------------------------------------------| | |
| Col3 | Col4 | Col1 | Col2 | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|-------------+----------------------+--------+--------| | |
| test test | some longer string | 1 | test | | |
|------------------------------------------------------| | |
>>> print_table(data, headings_justify='left') | |
Col3 Col4 Col1 Col2 | |
--------- ------------------ ---- ---- | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
test test some longer string 1 test | |
>>> print_table(data, headings_justify='left', order=('Col4','Col3','Col2','Col1')) | |
Col4 Col3 Col2 Col1 | |
------------------ --------- ---- ---- | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
some longer string test test test 1 | |
>>> print_table(data, data_justify='center', order=('Col1',)) | |
Col1 Col2 Col4 Col3 | |
---- ---- ------------------ --------- | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
1 test some longer string test test | |
>>> print_table(data, data_justify='center', order=('Col1','Col2','Col3')) | |
Col1 Col2 Col3 Col4 | |
---- ---- --------- ------------------ | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
1 test test test some longer string | |
>>> print_table(data, data_justify='center', border=True, order=('Col1','Col2','Col3')) | |
|------------------------------------------------------| | |
| Col1 | Col2 | Col3 | Col4 | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|--------+--------+-------------+----------------------| | |
| 1 | test | test test | some longer string | | |
|------------------------------------------------------| | |
>>> print_table(data, data_justify='center', border=True, order=('Col1','Col2','Col3'), padding=8) | |
|------------------------------------------------------------------------------------------------------| | |
| Col1 | Col2 | Col3 | Col4 | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|--------------------+--------------------+-------------------------+----------------------------------| | |
| 1 | test | test test | some longer string | | |
|------------------------------------------------------------------------------------------------------| | |
''' | |
def print_table(data, records_per_page=None, padding=2, headings_justify='center', data_justify='left', border=False, order=()): | |
''' Print data in table format ''' | |
if not data: | |
raise Exception("Empty data set!") | |
JUSTIFY = { | |
'center': '^', | |
'left': '<', | |
'right': '>', | |
} | |
headings_justify = headings_justify.lower() | |
data_justify = data_justify.lower() | |
if headings_justify not in JUSTIFY.keys(): | |
headings_justify = 'center' | |
if data_justify not in JUSTIFY.keys(): | |
data_justify = 'center' | |
if order: | |
fields = list(order) | |
fields += [i for i in data[0].keys() if i not in fields] | |
fields = tuple(fields) | |
else: | |
fields = tuple(data[0].keys()) | |
# Check if data is normal. All records need to have the same number of fields and same field names | |
for item in data: | |
if not all(i in fields for i in item.keys()) or len(item.keys()) != len(fields): | |
raise Exception("Fields not consistent") | |
# Clean the data. Items with None, bytearrays, or dates need to be converted to str types | |
rows = [] | |
for item in data: | |
sorted_data = [] | |
if order: | |
for i in order: | |
sorted_data.append(item[i]) | |
sorted_data += [v for k,v in item.items() if k not in order] | |
else: | |
sorted_data = list(item.values()) | |
cleaned_nones = ['' if v is None else v for v in sorted_data] | |
cleaned_bytes = [base64.b64encode(v).decode() if type(v) is bytearray else v for v in cleaned_nones] | |
cleaned_all = [str(v) for v in cleaned_bytes] | |
rows.append(cleaned_all) | |
# Get the lengths of each field | |
lengths = dict(zip(fields, tuple(len(_) for _ in fields))) | |
# Get the maximum needed length for each column in recordset. e.g the longest str | |
for row in data: | |
for item in row: | |
lengths[item] = max(len(str(row[item])), lengths[item]) | |
row_format = "" | |
line_format = "" | |
clean_row_format = "" | |
clean_line_format = "" | |
header_format = "" | |
clean_header_format = "" | |
for field in fields: | |
header_format += "{:" + JUSTIFY[headings_justify] + str(lengths[field]) + "}" + " "*padding + "|" + " "*padding | |
row_format += "{:" + JUSTIFY[data_justify] + str(lengths[field]) + "}" + " "*padding + "|" + " "*padding | |
line_format += "-"*padding + "{:^" + str(lengths[field]) + "}" + "-"*padding + "+" | |
clean_header_format += "{:" + JUSTIFY[headings_justify] + str(lengths[field]) + "}" + " "*padding + " " + " "*padding | |
clean_row_format += "{:" + JUSTIFY[data_justify] + str(lengths[field]) + "}" + " "*padding + " " + " "*padding | |
clean_line_format += " "*padding + "{:<" + str(lengths[field]) + "}" + " "*padding + " " | |
headers = header_format.format(*fields) | |
headers = "|" + " "*padding + headers | |
clean_headers = clean_header_format.format(*fields) | |
clean_headers = " "*padding + clean_headers | |
solid_line = "-"*(len(headers)-padding-2) | |
solid_line = "|" + solid_line + "|" | |
clean_solid_line = " "*(len(headers)-padding-2) | |
clean_solid_line = " " + clean_solid_line + " " | |
lines = ("-"*lengths[field] for field in fields) | |
spacer_line = line_format.format(*lines) | |
spacer_line = "|" + spacer_line[:len(spacer_line)-1] + "|" | |
lines = ("-"*lengths[field] for field in fields) | |
clean_spacer_line = clean_line_format.format(*lines) | |
clean_spacer_line = clean_spacer_line[:len(clean_spacer_line)] | |
if not border: | |
print() | |
print(clean_headers) # e.g. field1 | |
print(clean_spacer_line) # ------ | |
num_rows = len(rows) | |
current_row = 0 | |
for row in rows: | |
current_row += 1 | |
data_row = clean_row_format.format(*row) | |
print(" "*padding + data_row) | |
if records_per_page: | |
if current_row % records_per_page == 0: | |
r = input("") | |
print('\n') | |
else: | |
print(solid_line) # e.g. |--------| | |
print(headers) # e.g. | field1 | | |
print(spacer_line) # e.g. |--------| | |
num_rows = len(rows) | |
current_row = 0 | |
for row in rows: | |
current_row += 1 | |
data_row = row_format.format(*row) | |
print("|" + " "*padding + data_row) | |
if current_row == num_rows: | |
print(solid_line) | |
else: | |
print(spacer_line) | |
if records_per_page: | |
if current_row % records_per_page == 0: | |
r = input("") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment