-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprint_table.py
122 lines (99 loc) · 3.72 KB
/
print_table.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import sys
write = sys.stdout.write
def print_table(data, schema, titles = None):
'''Prints a list of dictionaries as a table
params: data: The list / tuple of dictionaries / lists / tuples (of dictionaries / lists / tuples ...)
schema: A list or a set that describes how to iterate in d
titles: Column titles to use instead of the keys
Schema format:
[key1, key2, [key3, key3-1], [key3, key3-2], [key3, key3-3, key3-3-1]]
This prints (here d is the short for data):
|-------------|--------------|----------------------|----------------------|--------------------------------|
| key1 | key2 | key3-1 | key3-2 | key3-3-1 |
|-------------|--------------|----------------------|----------------------|--------------------------------|
| d[0][key1] | d[0][key2] | d[0][key3][key3-1] | d[0][key3][key3-2] | d[0][key3][key3-3][key3-3-1] |
| d[1][key1] | d[1][key2] | d[1][key3][key3-1] | d[1][key3][key3-2] | d[1][key3][key3-3][key3-3-1] |
| d[2][key1] | d[2][key2] | d[2][key3][key3-1] | d[2][key3][key3-2] | d[2][key3][key3-3][key3-3-1] |
| .... |
|-------------|--------------|----------------------|----------------------|--------------------------------|
if titles list / tuple is provided, it's values will be used as column titles instead of the keys.
'''
# Verify param types
if type(data) not in (list, tuple):
raise TypeError("data must be a list or a tuple")
if type(schema) not in (list, tuple):
raise TypeError("schema must be a list or a tuple")
if type(titles) not in (list, tuple, None):
raise TypeError("titles must be a list or a tuple or None")
# Use keys as titles if needed
if titles == None:
titles = _create_titles(schema)
lens = _find_lengths(data, schema, titles)
# Print top border
for l in lens:
write(('|{:-<%d}' % (l+4)).format(""))
write("|\n")
# Print column names
for c in range(len(lens)):
write(('| {:<%d} ' % lens[c]).format(titles[c]))
write("|\n")
# Print middle border
for l in lens:
write(('|{:-<%d}' % (l+4)).format(""))
write("|\n")
# Print data
for line in data:
for c in range(len(lens)):
write(('| {:<%d} ' % lens[c]).format(_col_value(line, schema, c)))
write("|\n")
# Print lower border
for l in lens:
write(('|{:-<%d}' % (l+4)).format(""))
write("|\n")
def _create_titles(schema):
'''Returns a list of column names filled with the keys from schema'''
ret = []
for k in schema:
if type(k) == str:
ret.append(k)
else:
if type(k) in (list, tuple):
ret.append(k[-1])
else:
raise TypeError("Invalid type in schema: Expected list or tuple, got %s." % str(type(k)))
return ret
def _find_lengths(data, schema, titles):
'''Returns a list of the lengths of the longest string in each column (including the title)'''
ret = []
for k in titles:
ret.append(len(k))
for line in data:
for col in range(len(schema)):
l = len(_col_value(line, schema, col))
if l > ret[col]:
ret[col] = l
return ret
def _col_value(line, schema, col):
'''Returns the value of col-th column of line according to the schema'''
if type(schema[col]) in (str, int, bool, tuple, float):
return str(line[schema[col]])
else:
val = line
for k in schema[col]:
val = val[k]
return str(val)
return ""
# test code:
#a = [[1,2,3], [4,5,6], [7,8,9]]
#s = [0,1,2]
#t = ["a", "b", "c"]
#
#print_table(a,s,t)
#
#print("")
#
#a = [["teste 1", ["sub 1-1", "sub 1-2"], "aaaa", {"asd":321, "bbb":"bla bla", "c":[1,2,3]}]]
#s = [0, [1,0], [1,1], 2, [3, "asd"], [3,"bbb"], [3,"c",1]]
#t = ["A", "Very long title :)", "3", "TTTT", "5555", "6666", "7777"]
#
#print_table(a,s,t)