- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtexttable.py
More file actions
Latest commit
119 lines (98 loc) · 3.67 KB
/
Copy pathtexttable.py
File metadata and controls
119 lines (98 loc) · 3.67 KB
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
fromcollectionsimportOrderedDict
classttrow(OrderedDict):
pass
#
# A class to print text in formatted tables.
#
classtexttable:
# Formats a fixed-width text table, with borders.
#
# param rows array of rows. each row contains array or ttrow (key/val)
# param headertype keys | firstrow | none/None
# param footertype keys | lastrow | none/None
# param empty_row_string String to use when there is no data, or None.
@classmethod
deftable( cls, rows, headertype='keys', footertype='none', empty_row_string='No Data' ):
ifnotlen( rows ):
if( empty_row_string!=None ):
rows= [ [ empty_row_string ] ]
else:
return''
header=footer=None
if( headertype=='keys'andisinstance(rows[0], dict)):
header=cls.obj_arr( rows[0] ).keys()
elif( headertype=='firstrow' ):
header=cls.obj_arr( rows[0] )
rows=rows[1:]
if( footertype=='keys'andlen( rows ) andisinstance(rows[len(rows)-1],dict) ):
footer=cls.obj_arr( rows[len(rows) -1] ).keys()
elif( footertype=='lastrow'andlen( rows ) ):
footer=cls.obj_arr( rows[len(rows)-1] )
rows=rows[:-1]
col_widths= {}
if( header ):
cls.calc_row_col_widths( col_widths, header )
if( footer ):
cls.calc_row_col_widths( col_widths, footer )
forrowinrows:
row=cls.obj_arr( row )
cls.calc_row_col_widths( col_widths, row )
buf=''
if( header ):
buf+=cls.print_divider_row( col_widths )
buf+=cls.print_row( col_widths, header )
buf+=cls.print_divider_row( col_widths )
forrowinrows:
row=cls.obj_arr( row )
buf+=cls.print_row( col_widths, row )
buf+=cls.print_divider_row( col_widths )
if( footer ):
buf+=cls.print_row( col_widths, footer )
buf+=cls.print_divider_row( col_widths )
returnbuf
@classmethod
defprint_divider_row( cls, col_widths ):
buf='+'
foriinrange(0, len(col_widths)):
width=col_widths[i]
buf+='-'+'-'.ljust( width, '-' ) +"-+"
buf+="\n"
returnbuf
@classmethod
defprint_row( cls, col_widths, row ):
buf='|'
idx=0
forvalinrow:
ifisinstance(row, dict):
val=row[val]
val=str(val)
pad_type='left'ifcls.is_numeric( val ) else'right'
ifpad_type=='left':
buf+=' '+val.rjust( col_widths[idx], ' ' ) +" |"
else:
buf+=' '+val.ljust( col_widths[idx], ' ' ) +" |"
idx=idx+1
returnbuf+"\n"
@classmethod
defcalc_row_col_widths( cls, col_widths, row ):
idx=0
forvalinrow:
ifisinstance(row, dict):
val=row[val]
val=str(val)
ifidxnotincol_widths:
col_widths[idx] =0
if( len(val) >col_widths[idx] ):
col_widths[idx] =len(val)
idx=idx+1
@classmethod
defobj_arr( cls, t ):
returnt
returndir( t ) ifisinstance( t, object ) elset
@classmethod
defis_numeric(cls, var):
try:
float(var)
returnTrue
exceptValueError:
returnFalse