3b1e1b9fe8d417a31118a272b5294ac3f783b162
[framework/uifw/expedite.git] / src / bin / expedite-cmp
1 #!/usr/bin/env python
2
3 import sys
4 import os
5 import os.path
6 import csv
7 from optparse import OptionParser
8
9 parser = OptionParser(usage="%prog [options] <reference> <file2> .. <fileN>",
10                       description="""\
11 Generate reports comparing two or more outputs of expedite.
12
13 Just run expedite and save output to a file and then feed them to this
14 program. The first file is used as base for comparison and other files
15 will print relative improvements.
16 """)
17 parser.add_option("-e", "--accepted-error",
18                   help=("maximum error to accept as percentage 0.0-1.0. "
19                         "[default=%default]"),
20                   action="store", type="float", default=0.05)
21 parser.add_option("-r", "--report",
22                   help=("kind of report to use. One of text or html. "
23                         "[default=%default]"),
24                   action="store", type="choice", default="text",
25                   choices=["text", "html"])
26 parser.add_option("-p", "--percentual",
27                   help=("show percentual instead of raw numbers for "
28                         "non-reference values."),
29                   action="store_true", default=False)
30 parser.add_option("-C", "--no-color", dest="color",
31                   help="do not use color in reports.",
32                   action="store_false", default=True)
33
34 options, files = parser.parse_args()
35 if len(files) < 2:
36     raise SystemExit("need at least 2 files to compare")
37
38
39 ref_f = files[0]
40 others_f = files[1:]
41
42 max_test_name = 0
43 data = {}
44 tests = []
45 for f in files:
46     d = data[f] = {}
47     for row in csv.reader(open(f)):
48         t = row[1].strip()
49         if f == ref_f:
50             tests.append(t)
51         d[t] = float(row[0])
52         max_test_name = max(len(t), max_test_name)
53
54 def report_text():
55     test_name_fmt = "%%%ds:" % max_test_name
56
57     print test_name_fmt % "\\",
58     for f in files:
59         n, e = os.path.splitext(f)
60         print "%7.7s" % n[-7:],
61     print
62
63     if options.color and os.environ.get("TERM", "") == "xterm":
64         color_good = "\033[1;32m"
65         color_bad = "\033[1;31m"
66         color_equal = "\033[1;30m"
67         color_reset = "\033[0m"
68     else:
69         color_good = ""
70         color_bad = ""
71         color_equal = ""
72         color_reset = ""
73
74
75     def print_row(test):
76         print test_name_fmt % test,
77         ref_val = data[ref_f][test]
78         print "%7.2f" % ref_val,
79         for f in others_f:
80             try:
81                 val = data[f][test]
82             except KeyError:
83                 print "-?????-",
84                 continue
85
86             percent = (val - ref_val) / ref_val
87             if percent < -options.accepted_error:
88                 c = color_bad
89             elif percent > options.accepted_error:
90                 c = color_good
91             else:
92                 c = color_equal
93
94             if options.percentual:
95                 print "%s%+6.1f%%%s" % (c, (percent * 100), color_reset),
96             else:
97                 print "%s%7.2f%s" % (c, val, color_reset),
98
99         print
100
101     for t in tests:
102         print_row(t)
103
104
105 def report_html():
106     import time
107
108     fnames = [os.path.basename(f) for f in files]
109     print """\
110 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
111   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
112
113 <html xmlns="http://www.w3.org/1999/xhtml">
114   <head>
115     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
116     <title>expedite comparison sheet: %(files)s</title>
117   </head>
118   <style type="text/css">
119     td.value, td.value-reference, td.value-missing, td.value-good, td.value-bad, td.value-equal
120     {
121        font-family: courier, monospaced;
122        font-size: 10pt;
123        text-align: right;
124     }
125     td.test-name, thead tr td { text-align: right; }\
126 """
127     if options.color:
128         print """\
129     td.value-good { background-color: #aaffaa; }
130     td.value-bad { background-color: #ffaaaa; }
131     td.value-missing { background-color: #ffffaa; }
132     td.test-name, thead tr td
133     {
134        font-weight: bold;
135        background-color: #d9d9d9;
136     }
137 """
138
139     print """
140   </style>
141   <body>
142      <p>Comparison sheet for %(files)s, created at %(date)s.</p>
143      <table>
144        <thead>
145          <tr>
146            <td>\\</td>\
147 """ % {"files": ", ".join(fnames),
148        "date": time.asctime(),
149        }
150
151     for f in fnames:
152         print """\
153            <td>%s</td>\
154 """ % f
155     print """\
156          </tr>
157        </thead>
158        <tbody>\
159 """
160
161     def print_row(test):
162         ref_val = data[ref_f][test]
163         print """\
164          <tr>
165            <td class="test-name">%s</td>
166            <td class="value-reference">%7.2f</td>\
167 """ % (test, ref_val)
168
169         for f in others_f:
170             try:
171                 val = data[f][test]
172             except KeyError:
173                 print """\
174            <td class="value-missing">-?????-</td>\
175 """
176                 continue
177
178             percent = (val - ref_val) / ref_val
179             if percent < -options.accepted_error:
180                 c = 'bad'
181             elif percent > options.accepted_error:
182                 c = 'good'
183             else:
184                 c = 'equal'
185
186             if options.percentual:
187                 v = "%+6.1f%%" % (percent * 100)
188             else:
189                 v = "%7.2f" % val
190
191             print """\
192            <td class="value-%s">%s</td>\
193 """ % (c, v)
194
195         print """\
196          </tr>\
197 """
198
199     for t in tests:
200         print_row(t)
201
202     print """\
203        </tbody>
204      </table>
205   </body>
206 </html>
207 """
208
209 if options.report == "text":
210     report_text()
211 elif options.report == "html":
212     report_html()