aboutsummaryrefslogtreecommitdiff
path: root/deprecated/crb/table_formatter.py
diff options
context:
space:
mode:
Diffstat (limited to 'deprecated/crb/table_formatter.py')
-rw-r--r--deprecated/crb/table_formatter.py258
1 files changed, 258 insertions, 0 deletions
diff --git a/deprecated/crb/table_formatter.py b/deprecated/crb/table_formatter.py
new file mode 100644
index 00000000..b8e25d5f
--- /dev/null
+++ b/deprecated/crb/table_formatter.py
@@ -0,0 +1,258 @@
+import numpy
+import re
+
+
+def IsFloat(text):
+ if text is None:
+ return False
+ try:
+ float(text)
+ return True
+ except ValueError:
+ return False
+
+
+def RemoveTrailingZeros(x):
+ ret = x
+ ret = re.sub('\.0*$', '', ret)
+ ret = re.sub('(\.[1-9]*)0+$', '\\1', ret)
+ return ret
+
+
+def HumanizeFloat(x, n=2):
+ if not IsFloat(x):
+ return x
+ digits = re.findall('[0-9.]', str(x))
+ decimal_found = False
+ ret = ''
+ sig_figs = 0
+ for digit in digits:
+ if digit == '.':
+ decimal_found = True
+ elif sig_figs != 0 or digit != '0':
+ sig_figs += 1
+ if decimal_found and sig_figs >= n:
+ break
+ ret += digit
+ return ret
+
+
+def GetNSigFigs(x, n=2):
+ if not IsFloat(x):
+ return x
+ my_fmt = '%.' + str(n - 1) + 'e'
+ x_string = my_fmt % x
+ f = float(x_string)
+ return f
+
+
+def GetFormattedPercent(baseline, other, bad_result='--'):
+ result = '%8s' % GetPercent(baseline, other, bad_result)
+ return result
+
+
+def GetPercent(baseline, other, bad_result='--'):
+ result = bad_result
+ if IsFloat(baseline) and IsFloat(other):
+ try:
+ pct = (float(other) / float(baseline) - 1) * 100
+ result = '%+1.1f' % pct
+ except ZeroDivisionError:
+ pass
+ return result
+
+
+def FitString(text, length):
+ if len(text) == length:
+ return text
+ elif len(text) > length:
+ return text[-length:]
+ else:
+ fmt = '%%%ds' % length
+ return fmt % text
+
+
+class TableFormatter(object):
+
+ def __init__(self):
+ self.d = '\t'
+ self.bad_result = 'x'
+
+ def GetTablePercents(self, table):
+ # Assumes table is not transposed.
+ pct_table = []
+
+ pct_table.append(table[0])
+ for i in range(1, len(table)):
+ row = []
+ row.append(table[i][0])
+ for j in range(1, len(table[0])):
+ c = table[i][j]
+ b = table[i][1]
+ p = GetPercent(b, c, self.bad_result)
+ row.append(p)
+ pct_table.append(row)
+ return pct_table
+
+ def FormatFloat(self, c, max_length=8):
+ if not IsFloat(c):
+ return c
+ f = float(c)
+ ret = HumanizeFloat(f, 4)
+ ret = RemoveTrailingZeros(ret)
+ if len(ret) > max_length:
+ ret = '%1.1ef' % f
+ return ret
+
+ def TransposeTable(self, table):
+ transposed_table = []
+ for i in range(len(table[0])):
+ row = []
+ for j in range(len(table)):
+ row.append(table[j][i])
+ transposed_table.append(row)
+ return transposed_table
+
+ def GetTableLabels(self, table):
+ ret = ''
+ header = table[0]
+ for i in range(1, len(header)):
+ ret += '%d: %s\n' % (i, header[i])
+ return ret
+
+ def GetFormattedTable(self,
+ table,
+ transposed=False,
+ first_column_width=30,
+ column_width=14,
+ percents_only=True,
+ fit_string=True):
+ o = ''
+ pct_table = self.GetTablePercents(table)
+ if transposed == True:
+ table = self.TransposeTable(table)
+ pct_table = self.TransposeTable(table)
+
+ for i in range(0, len(table)):
+ for j in range(len(table[0])):
+ if j == 0:
+ width = first_column_width
+ else:
+ width = column_width
+
+ c = table[i][j]
+ p = pct_table[i][j]
+
+ # Replace labels with numbers: 0... n
+ if IsFloat(c):
+ c = self.FormatFloat(c)
+
+ if IsFloat(p) and not percents_only:
+ p = '%s%%' % p
+
+ # Print percent values side by side.
+ if j != 0:
+ if percents_only:
+ c = '%s' % p
+ else:
+ c = '%s (%s)' % (c, p)
+
+ if i == 0 and j != 0:
+ c = str(j)
+
+ if fit_string:
+ o += FitString(c, width) + self.d
+ else:
+ o += c + self.d
+ o += '\n'
+ return o
+
+ def GetGroups(self, table):
+ labels = table[0]
+ groups = []
+ group_dict = {}
+ for i in range(1, len(labels)):
+ label = labels[i]
+ stripped_label = self.GetStrippedLabel(label)
+ if stripped_label not in group_dict:
+ group_dict[stripped_label] = len(groups)
+ groups.append([])
+ groups[group_dict[stripped_label]].append(i)
+ return groups
+
+ def GetSummaryTableValues(self, table):
+ # First get the groups
+ groups = self.GetGroups(table)
+
+ summary_table = []
+
+ labels = table[0]
+
+ summary_labels = ['Summary Table']
+ for group in groups:
+ label = labels[group[0]]
+ stripped_label = self.GetStrippedLabel(label)
+ group_label = '%s (%d runs)' % (stripped_label, len(group))
+ summary_labels.append(group_label)
+ summary_table.append(summary_labels)
+
+ for i in range(1, len(table)):
+ row = table[i]
+ summary_row = [row[0]]
+ for group in groups:
+ group_runs = []
+ for index in group:
+ group_runs.append(row[index])
+ group_run = self.AggregateResults(group_runs)
+ summary_row.append(group_run)
+ summary_table.append(summary_row)
+
+ return summary_table
+
+ # Drop N% slowest and M% fastest numbers, and return arithmean of
+ # the remaining.
+ @staticmethod
+ def AverageWithDrops(numbers, slow_percent=20, fast_percent=20):
+ sorted_numbers = list(numbers)
+ sorted_numbers.sort()
+ num_slow = int(slow_percent / 100.0 * len(sorted_numbers))
+ num_fast = int(fast_percent / 100.0 * len(sorted_numbers))
+ sorted_numbers = sorted_numbers[num_slow:]
+ if num_fast:
+ sorted_numbers = sorted_numbers[:-num_fast]
+ return numpy.average(sorted_numbers)
+
+ @staticmethod
+ def AggregateResults(group_results):
+ ret = ''
+ if not group_results:
+ return ret
+ all_floats = True
+ all_passes = True
+ all_fails = True
+ for group_result in group_results:
+ if not IsFloat(group_result):
+ all_floats = False
+ if group_result != 'PASSED':
+ all_passes = False
+ if group_result != 'FAILED':
+ all_fails = False
+ if all_floats == True:
+ float_results = [float(v) for v in group_results]
+ ret = '%f' % TableFormatter.AverageWithDrops(float_results)
+ # Add this line for standard deviation.
+ ### ret += " %f" % numpy.std(float_results)
+ elif all_passes == True:
+ ret = 'ALL_PASS'
+ elif all_fails == True:
+ ret = 'ALL_FAILS'
+ return ret
+
+ @staticmethod
+ def GetStrippedLabel(label):
+ return re.sub('\s*\S+:\S+\s*', '', label)
+### return re.sub("\s*remote:\S*\s*i:\d+$", "", label)
+
+ @staticmethod
+ def GetLabelWithIteration(label, iteration):
+ return '%s i:%d' % (label, iteration)