diff --git a/scripts/code.py b/scripts/code.py index 13ef0cc4..bd49c5ea 100755 --- a/scripts/code.py +++ b/scripts/code.py @@ -399,14 +399,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -420,22 +420,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -446,30 +453,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -496,21 +490,28 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # print our table for line in lines: - print('%-*s %s%s' % ( - widths[0], line[0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1])) + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def main(obj_paths, *, diff --git a/scripts/cov.py b/scripts/cov.py index 0b44e2a2..232e2d40 100755 --- a/scripts/cov.py +++ b/scripts/cov.py @@ -387,14 +387,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -408,22 +408,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -434,30 +441,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -484,21 +478,28 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # print our table for line in lines: - print('%-*s %s%s' % ( - widths[0], line[0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1])) + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def annotate(Result, results, *, diff --git a/scripts/data.py b/scripts/data.py index 7e4edaee..245cb88c 100755 --- a/scripts/data.py +++ b/scripts/data.py @@ -399,14 +399,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -420,22 +420,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -446,30 +453,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -496,21 +490,28 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # print our table for line in lines: - print('%-*s %s%s' % ( - widths[0], line[0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1])) + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def main(obj_paths, *, diff --git a/scripts/perf.py b/scripts/perf.py index a6161a9b..a33d76c1 100755 --- a/scripts/perf.py +++ b/scripts/perf.py @@ -723,14 +723,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -744,22 +744,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -770,30 +777,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -820,13 +814,19 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # adjust the name width based on the call depth if not summary: @@ -855,11 +855,12 @@ def table(Result, results, diff_results=None, *, widths[0] += 4*max(depth_-1, 0) # print the tree recursively - print('%-*s %s%s' % ( - widths[0], lines[0][0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], lines[0][1:-1])), - lines[0][-1])) + print('%-*s %s' % ( + widths[0], lines[0][0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(lines[0][1:], 1)))) if not summary: def recurse(results_, depth_, prefixes=('', '', '', '')): @@ -887,14 +888,15 @@ def table(Result, results, diff_results=None, *, r = table_[name] is_last = (i == len(names_)-1) + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] print('%s%-*s %s' % ( prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), - name, - ' '.join('%*s' % (w, x) - for w, x in zip( - widths[1:], - table_entry(name, r)[1:])))) + widths[0] - len(prefixes[0+is_last]), line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) # recurse? if depth_ > 1: @@ -909,11 +911,12 @@ def table(Result, results, diff_results=None, *, # we have enough going on with diffing to make the top layer # a special case for name, line in zip(names, lines[1:-1]): - print('%-*s %s%s' % ( - widths[0], line[0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1])) + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) if name in table and depth > 1: recurse( @@ -924,11 +927,12 @@ def table(Result, results, diff_results=None, *, "| ", " ")) - print('%-*s %s%s' % ( - widths[0], lines[-1][0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], lines[-1][1:-1])), - lines[-1][-1])) + print('%-*s %s' % ( + widths[0], lines[-1][0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(lines[-1][1:], 1)))) def annotate(Result, results, *, diff --git a/scripts/perfbd.py b/scripts/perfbd.py index 290bbd46..1fc167fd 100755 --- a/scripts/perfbd.py +++ b/scripts/perfbd.py @@ -687,14 +687,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -708,22 +708,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -734,30 +741,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -784,13 +778,19 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # adjust the name width based on the call depth if not summary: @@ -819,11 +819,12 @@ def table(Result, results, diff_results=None, *, widths[0] += 4*max(depth_-1, 0) # print the tree recursively - print('%-*s %s%s' % ( - widths[0], lines[0][0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], lines[0][1:-1])), - lines[0][-1])) + print('%-*s %s' % ( + widths[0], lines[0][0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(lines[0][1:], 1)))) if not summary: def recurse(results_, depth_, prefixes=('', '', '', '')): @@ -851,14 +852,15 @@ def table(Result, results, diff_results=None, *, r = table_[name] is_last = (i == len(names_)-1) + line = table_entry(name, r) + line = [x if isinstance(x, tuple) else (x, []) for x in line] print('%s%-*s %s' % ( prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), - name, - ' '.join('%*s' % (w, x) - for w, x in zip( - widths[1:], - table_entry(name, r)[1:])))) + widths[0] - len(prefixes[0+is_last]), line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) # recurse? if depth_ > 1: @@ -873,11 +875,12 @@ def table(Result, results, diff_results=None, *, # we have enough going on with diffing to make the top layer # a special case for name, line in zip(names, lines[1:-1]): - print('%-*s %s%s' % ( - widths[0], line[0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1])) + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) if name in table and depth > 1: recurse( @@ -888,11 +891,12 @@ def table(Result, results, diff_results=None, *, "| ", " ")) - print('%-*s %s%s' % ( - widths[0], lines[-1][0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], lines[-1][1:-1])), - lines[-1][-1])) + print('%-*s %s' % ( + widths[0], lines[-1][0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(lines[-1][1:], 1)))) def annotate(Result, results, *, diff --git a/scripts/stack.py b/scripts/stack.py index 058a65c0..b4089847 100755 --- a/scripts/stack.py +++ b/scripts/stack.py @@ -358,14 +358,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -379,22 +379,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -405,30 +412,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -455,13 +449,19 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # adjust the name width based on the call depth if not summary: @@ -486,11 +486,12 @@ def table(Result, results, diff_results=None, *, widths[0] += 4*max(depth_-1, 0) # print the tree recursively - print('%-*s %s%s' % ( - widths[0], lines[0][0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], lines[0][1:-1])), - lines[0][-1])) + print('%-*s %s' % ( + widths[0], lines[0][0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(lines[0][1:], 1)))) if not summary: line_table = {n: l for n, l in zip(names, lines[1:-1])} @@ -502,17 +503,13 @@ def table(Result, results, diff_results=None, *, line = line_table[name] is_last = (i == len(names_)-1) - print('%s%-*s ' % ( + print('%s%-*s %s' % ( prefixes[0+is_last], - widths[0] - len(prefixes[0+is_last]), - line[0]), - end='') - print(' %s%s' % ( - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1]), - end='') - print() + widths[0] - len(prefixes[0+is_last]), line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) # recurse? if name in table and depth_ > 1: @@ -530,11 +527,12 @@ def table(Result, results, diff_results=None, *, recurse(names, depth) - print('%-*s %s%s' % ( - widths[0], lines[-1][0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], lines[-1][1:-1])), - lines[-1][-1])) + print('%-*s %s' % ( + widths[0], lines[-1][0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(lines[-1][1:], 1)))) def main(ci_paths, diff --git a/scripts/structs.py b/scripts/structs.py index c1a51ac6..3d1a2129 100755 --- a/scripts/structs.py +++ b/scripts/structs.py @@ -348,14 +348,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -369,22 +369,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -395,30 +402,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -445,21 +439,28 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # print our table for line in lines: - print('%-*s %s%s' % ( - widths[0], line[0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1])) + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def main(obj_paths, *, diff --git a/scripts/summary.py b/scripts/summary.py index 997d9d0d..2b1a0c8a 100755 --- a/scripts/summary.py +++ b/scripts/summary.py @@ -479,14 +479,14 @@ def table(Result, results, diff_results=None, *, lines = [] # header - header = [] - header.append('%s%s' % ( - ','.join(by), - ' (%d added, %d removed)' % ( - sum(1 for n in table if n not in diff_table), - sum(1 for n in diff_table if n not in table)) - if diff_results is not None and not percent else '') - if not summary else '') + header = [ + '%s%s' % ( + ','.join(by), + ' (%d added, %d removed)' % ( + sum(1 for n in table if n not in diff_table), + sum(1 for n in diff_table if n not in table)) + if diff_results is not None and not percent else '') + if not summary else ''] if diff_results is None: for k in fields: header.append(k) @@ -500,22 +500,29 @@ def table(Result, results, diff_results=None, *, header.append('n'+k) for k in fields: header.append('d'+k) - header.append('') lines.append(header) def table_entry(name, r, diff_r=None): - entry = [] - entry.append(name) + entry = [name] if diff_results is None: for k in fields: - entry.append(getattr(r, k).table() + entry.append( + (getattr(r, k).table(), + getattr(getattr(r, k), 'notes', lambda: [])()) if getattr(r, k, None) is not None else types[k].none) elif percent: for k in fields: - entry.append(getattr(r, k).table() - if getattr(r, k, None) is not None - else types[k].none) + entry.append( + (getattr(r, k).table() + if getattr(r, k, None) is not None + else types[k].none, + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) else: for k in fields: entry.append(getattr(diff_r, k).table() @@ -526,30 +533,17 @@ def table(Result, results, diff_results=None, *, if getattr(r, k, None) is not None else types[k].none) for k in fields: - entry.append(types[k].diff( - getattr(r, k, None), - getattr(diff_r, k, None))) - if diff_results is None: - notes = [] - for k in fields: - try: - notes.extend(getattr(r, k).notes()) - except AttributeError: - pass - entry.append(' (%s)' % ', '.join(notes) - if notes else '') - else: - ratios = [ - types[k].ratio( - getattr(r, k, None), - getattr(diff_r, k, None)) - for k in fields] - entry.append(' (%s)' % ', '.join( - '+∞%' if t == +m.inf - else '-∞%' if t == -m.inf - else '%+.1f%%' % (100*t) - for t in ratios) - if percent or any(ratios) else '') + entry.append( + (types[k].diff( + getattr(r, k, None), + getattr(diff_r, k, None)), + (lambda t: ['+∞%'] if t == +m.inf + else ['-∞%'] if t == -m.inf + else ['%+.1f%%' % (100*t)] if t + else [])( + types[k].ratio( + getattr(r, k, None), + getattr(diff_r, k, None))))) return entry # entries @@ -576,21 +570,28 @@ def table(Result, results, diff_results=None, *, diff_r = next(iter(fold(Result, diff_results, by=[])), None) lines.append(table_entry('TOTAL', r, diff_r)) - # find the best widths, note that column 0 contains the names and - # column -1 the ratios/notes, so those are handled a bit differently - widths = [ - ((max(it.chain([w], (len(l[i]) for l in lines)))+1+4-1)//4)*4-1 - for w, i in zip( - it.chain([23], it.repeat(7)), - range(len(lines[0])-1))] + # homogenize + lines = [ + [x if isinstance(x, tuple) else (x, []) for x in line] + for line in lines] + + # find the best widths, note that column 0 contains the names and is + # handled a bit differently + widths = co.defaultdict(lambda: 7, {0: 23}) + notes = co.defaultdict(lambda: 0) + for line in lines: + for i, x in enumerate(line): + widths[i] = max(widths[i], ((len(x[0])+1+4-1)//4)*4-1) + notes[i] = max(notes[i], 1+2*len(x[1])+sum(len(n) for n in x[1])) # print our table for line in lines: - print('%-*s %s%s' % ( - widths[0], line[0], - ' '.join('%*s' % (w, x) - for w, x in zip(widths[1:], line[1:-1])), - line[-1])) + print('%-*s %s' % ( + widths[0], line[0][0], + ' '.join('%*s%-*s' % ( + widths[i], x[0], + notes[i], ' (%s)' % ', '.join(x[1]) if x[1] else '') + for i, x in enumerate(line[1:], 1)))) def main(csv_paths, *,