From ba21e38cdb3d504a69f6808913ea2a649ab4e916 Mon Sep 17 00:00:00 2001 From: Scott Gasch Date: Thu, 2 Jun 2022 21:43:08 -0700 Subject: [PATCH] Make the bar graph thing do fractions. --- histogram.py | 9 ++++--- ml/model_trainer.py | 4 +-- tests/run_tests.py | 18 +++++++------- text_utils.py | 59 +++++++++++++++++++++++++++++++++------------ 4 files changed, 60 insertions(+), 30 deletions(-) diff --git a/histogram.py b/histogram.py index 86d0493..ee1601a 100644 --- a/histogram.py +++ b/histogram.py @@ -165,7 +165,7 @@ class SimpleHistogram(Generic[T]): some vital stats about the population in it (min, max, mean, median, mode, stdev, etc...) """ - from text_utils import bar_graph + from text_utils import BarGraphText, bar_graph_string details = self._get_bucket_details(label_formatter) txt = "" @@ -187,9 +187,10 @@ class SimpleHistogram(Generic[T]): if start < details.lowest_start: continue label = f'[{label_formatter}..{label_formatter}): ' % (start, end) - bar = bar_graph( - (pop / details.max_population), - include_text=False, + bar = bar_graph_string( + pop, + details.max_population, + text=BarGraphText.NONE, width=bar_width, left_end="", right_end="", diff --git a/ml/model_trainer.py b/ml/model_trainer.py index 34ded74..07f7b99 100644 --- a/ml/model_trainer.py +++ b/ml/model_trainer.py @@ -278,9 +278,9 @@ class TrainingBlueprint(ABC): def make_progress_graph(self) -> None: if not self.spec.quiet: - from text_utils import progress_graph + from text_utils import bar_graph - progress_graph(self.file_done_count, self.total_file_count) + bar_graph(self.file_done_count, self.total_file_count) @timed def read_input_files(self): diff --git a/tests/run_tests.py b/tests/run_tests.py index 5162e23..6f4b399 100755 --- a/tests/run_tests.py +++ b/tests/run_tests.py @@ -372,6 +372,10 @@ def main() -> Optional[int]: failed = 0 for thread in threads: + (s, tr) = thread.get_status() + started += s + failed += len(tr.tests_failed) + len(tr.tests_timed_out) + done += failed + len(tr.tests_succeeded) if not thread.is_alive(): tid = thread.name if tid not in results: @@ -383,11 +387,6 @@ def main() -> Optional[int]: 'Thread %s returned abnormal results; killing the others.', tid ) halt_event.set() - else: - (s, tr) = thread.get_status() - started += s - failed += len(tr.tests_failed) + len(tr.tests_timed_out) - done += failed + len(tr.tests_succeeded) if started > 0: percent_done = done / started @@ -401,18 +400,19 @@ def main() -> Optional[int]: if percent_done < 100.0: print( - text_utils.bar_graph( - percent_done, + text_utils.bar_graph_string( + done, + started, + text=text_utils.BarGraphText.FRACTION, width=80, fgcolor=color, ), end='\r', flush=True, ) - else: - print("Finished.\n") time.sleep(0.5) + print('\rFinal Report:') if config.config['coverage']: code_coverage_report() total_problems = test_results_report(results) diff --git a/text_utils.py b/text_utils.py index 3b28968..6437e62 100644 --- a/text_utils.py +++ b/text_utils.py @@ -6,6 +6,7 @@ """Utilities for dealing with "text".""" import contextlib +import enum import logging import math import os @@ -75,11 +76,25 @@ def get_console_rows_columns() -> RowsColumns: return RowsColumns(int(rows), int(cols)) -def progress_graph( +class BarGraphText(enum.Enum): + """What kind of text to include at the end of the bar graph?""" + + NONE = (0,) + """None, leave it blank.""" + + PERCENTAGE = (1,) + """XX.X%""" + + FRACTION = (2,) + """N / K""" + + +def bar_graph( current: int, total: int, *, width=70, + text: BarGraphText = BarGraphText.PERCENTAGE, fgcolor=fg("school bus yellow"), left_end="[", right_end="]", @@ -90,6 +105,7 @@ def progress_graph( Args: current: how many have we done so far? total: how many are there to do total? + text: how should we render the text at the end? width: how many columns wide should be progress graph be? fgcolor: what color should "done" part of the graph be? left_end: the character at the left side of the graph @@ -98,11 +114,11 @@ def progress_graph( so that subsequent calls to this method redraw the graph iteratively. """ - percent = current / total ret = "\r" if redraw else "\n" - bar = bar_graph( - percent, - include_text=True, + bar = bar_graph_string( + current, + total, + text=text, width=width, fgcolor=fgcolor, left_end=left_end, @@ -111,10 +127,21 @@ def progress_graph( print(bar, end=ret, flush=True, file=sys.stderr) -def bar_graph( - percentage: float, +def _make_bar_graph_text(text: BarGraphText, current: int, total: int, percentage: float): + if text == BarGraphText.NONE: + return "" + elif text == BarGraphText.PERCENTAGE: + return f'{percentage:.1f}' + elif text == BarGraphText.FRACTION: + return f'{current} / {total}' + raise ValueError(text) + + +def bar_graph_string( + current: int, + total: int, *, - include_text=True, + text: BarGraphText = BarGraphText.PERCENTAGE, width=70, fgcolor=fg("school bus yellow"), reset_seq=reset(), @@ -124,25 +151,27 @@ def bar_graph( """Returns a string containing a bar graph. Args: - percentage: percentage complete (0..100) - include_text: should we include the percentage text at the end? + current: how many have we done so far? + total: how many are there to do total? + text: how should we render the text at the end? width: how many columns wide should be progress graph be? fgcolor: what color should "done" part of the graph be? reset_seq: sequence to use to turn off color left_end: the character at the left side of the graph right_end: the character at the right side of the graph - >>> bar_graph(0.5, fgcolor='', reset_seq='') + >>> bar_graph(5, 10, fgcolor='', reset_seq='') '[███████████████████████████████████ ] 50.0%' """ + if total != 0: + percentage = float(current) / float(total) + else: + percentage = 0.0 if percentage < 0.0 or percentage > 1.0: raise ValueError(percentage) - if include_text: - text = f"{percentage*100.0:2.1f}%" - else: - text = "" + text = _make_bar_graph_text(text, current, total, percentage) whole_width = math.floor(percentage * width) if whole_width == width: whole_width -= 1 -- 2.46.0