Make the bar graph thing do fractions.
authorScott Gasch <[email protected]>
Fri, 3 Jun 2022 04:43:08 +0000 (21:43 -0700)
committerScott Gasch <[email protected]>
Fri, 3 Jun 2022 04:43:08 +0000 (21:43 -0700)
histogram.py
ml/model_trainer.py
tests/run_tests.py
text_utils.py

index 86d0493dc57e32056c4eb04ec4499992d365e542..ee1601a9c627fa430139772eeef84401ba4406f6 100644 (file)
@@ -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="",
index 34ded741a21131b8f7638ebf475374038c3e6101..07f7b99292c9c9a3c3ac3a685c40ca59ee1b9582 100644 (file)
@@ -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):
index 5162e238f1d37181b5dc9ea3988e1a443b3231c4..6f4b399e0e65286e9860fe92376746575dfc297a 100755 (executable)
@@ -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('\e[2K\rFinal Report:')
     if config.config['coverage']:
         code_coverage_report()
     total_problems = test_results_report(results)
index 3b289686d5b4554f1aa1dc40eb639c4b72586702..6437e62930d754bc7303e0550f262eee0b6746f1 100644 (file)
@@ -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