-
Notifications
You must be signed in to change notification settings - Fork 3
/
FormatTable.py
executable file
·159 lines (145 loc) · 4.93 KB
/
FormatTable.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#!/usr/bin/env python
__author__ = "Scott Hendrickson"
__version__ = "1.0.1"
__email__ = "[email protected]"
from FNumber import FNumber
from copy import copy
LATEX_HDR = """
%%%% Table generated by formatTable utility %%%%
%%%% add \usepackage[group-separator={,}]{siunitx}
%%%%
\\begin{table}
\\begin{tabular}{%s}
\\hline
"""
LATEX_HROW = """\\hline
"""
LATEX_FTR = """\\hline
\\end{tabular}
\\end{table}
%% Table generated by formatTable utility %%
"""
TABLE_ROWS = 44
class Offsets(object):
""" Simple container for column alignement offset information. "test" each
number in the column and this object will return the column width and
decimal offset required to accomodate all the numbers. """
def __init__(self):
self.right = []
self.left = []
def test(self, column, left, right):
if column > len(self.left) - 1:
self.left.append(0)
self.right.append(0)
if self.left[column] < left:
self.left[column] = left
if self.right[column] < right:
self.right[column] = right
def getRight(self, c):
return self.right[c]
def getLeft(self, c):
return self.left[c]
def size(self, c):
return self.right[c] + self.left[c]
class FormatTable(object):
""" Create a text table of decimal aligned numbers formated with FNumber. """
def __init__(self, table, sf=None, latex=False, sflist=None, maxColWidth=None):
self.offsets = Offsets()
self.cnums = []
exec("sfl=%s"%sflist)
for row in table:
if sf is None:
if sflist is None:
# if sf=None, then each number is a tuple with the second element
# containing the sf to use for that number
tmp = [FNumber(x, int(s), latex, maxColWidth) for (x,s) in row]
else:
tmp = [FNumber(x, int(s), latex, maxColWidth) for (x,s) in zip(row,sfl)]
else:
# All numbers in the table use the same sf
tmp = [FNumber(x, int(sf), latex, maxColWidth) for x in row]
self.cnums.append(tmp)
for i in range(0,len(tmp)):
self.offsets.test(i, tmp[i].getOffset(), tmp[i].getRightOffset())
if latex:
self.header = LATEX_HDR%("|" + "S|"*len(self.cnums[0]))
self.tableSeparator = " & "
self.header_row = LATEX_HROW
self.endline = " \\\\\n"
self.footer = LATEX_FTR
else:
self.header = ""
self.tableSeparator = " | "
# get full table width
width = len(self.tableSeparator.join(
[self.cnums[0][i].getPadded(self.offsets.size(i), self.offsets.getLeft(i)) for i in range(len(self.cnums[0]))]))
self.endline = " \n"
self.header_row = '-'*width + self.endline
self.footer = "\n\n"
def __repr__(self):
res = self.header
count = 0
tmp_headers = None
for row in self.cnums:
count += 1
tmp = []
for i in range(len(row)):
tmp.append(row[i].getPadded(self.offsets.size(i), self.offsets.getLeft(i)))
line = self.tableSeparator.join(tmp) + self.endline
res += line
if count == 1:
tmp_headers = copy(line)
res += self.header_row
if count%TABLE_ROWS == 0:
res += self.footer + self.header + tmp_headers + self.header_row
res += self.footer
return res
if __name__ == '__main__':
""" Simple example of multi-column table with varying sf specified for each number. """
values = [ [
("column 1", 0),
("column 2", 0),
("column C", 0),
("another column", 0)],[
(1234.234, 1),
(1234.234, 2),
(1234.234, 3),
(123.234, 3)],[
(123.234, 4),
(1234.234, 1),
(123.234, 4),
(1234.234, 4)],[
(1234.234, 5),
(-1234.234, 5),
(1234.234, 6),
(1234.234, 7)],[
(1234.234, 9),
(.23456789, 1),
(.23456789, 2),
(-.23456789, 2)],[
(.23456789, 3),
(.23456789, 4),
(.23456789, 5),
(.0023456789, 3)],[
(.00023456789, 4),
(.000023456789, 5),
(23456789, 2),
(23456789, 4)],[
(23456789, 6),
(-23456789, 6),
(23456789.123345, 8),
(23456789.123345, 15)
] ]
ft = FormatTable(values)
print ft
print "*****\n"
# ...and same numbers with constant sf for the whole table
arry = []
for v in values:
tmp = [x[0] for x in v]
arry.append(tmp)
f1 = FormatTable (arry, 3)
print f1
print "*****\n"
f2 = FormatTable (arry, 3, latex=True)
print f2