Last active
October 1, 2020 01:07
-
-
Save Rich5/ac6a926fd80445f325dc07fc543b8143 to your computer and use it in GitHub Desktop.
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
''' | |
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 | | |
|------------------------------------------------------------------------------------------------------| | |
>>> print_table(data, border=True, records_per_page=3) | |
|------------------------------------------------------| | |
| Col1 | Col3 | Col2 | Col4 | | |
|--------+-------------+--------+----------------------| | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
[press any key] | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
[press any key] | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
| 1 | test test | test | some longer string | | |
|--------+-------------+--------+----------------------| | |
[press any key] | |
| 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 TYPES | |
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] | |
# requires, import base64 | |
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) | |
''' | |
CALCULATE THE MAX LENGTHS FOR EACH COLUMN | |
''' | |
# 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]) | |
''' | |
GENERATE ALL THE FORMAT STRINGS FOR PRINTING | |
''' | |
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 TABLE WITHOUT BORDERS | |
''' | |
print() | |
print(clean_headers) # e.g. field1 | |
print(clean_spacer_line) # ------ | |
for row_num, row in enumerate(rows): | |
data_row = clean_row_format.format(*row) | |
print(" "*padding + data_row) | |
if records_per_page: | |
if (row_num+1) % records_per_page == 0: | |
r = input("") | |
print('\n') | |
else: | |
''' | |
PRINT TABLE WITH BORDERS | |
''' | |
print(solid_line) # e.g. |--------| | |
print(headers) # e.g. | field1 | | |
print(spacer_line) # e.g. |---+----| | |
num_rows = len(rows) | |
for row_num, row in enumerate(rows): | |
data_row = row_format.format(*row) | |
print("|" + " "*padding + data_row) | |
if (row_num +1) == num_rows: | |
print(solid_line) | |
else: | |
print(spacer_line) | |
if records_per_page: | |
if (row_num+1) % records_per_page == 0: | |
r = input("") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment