Update docs and type hints in interval_tree. Add it to the pydocs.
[pyutils.git] / src / pyutils / types / histogram.py
index d0a755b3b572d46f0dbf407b4d87673db6bbc466..55abd69588a66906091f452cb44b696b2698c85a 100644 (file)
@@ -8,30 +8,28 @@ This is a text-based histogram class.  It creates output like this:
 
 A Histogram helper class.  Creates outputs like this::
 
-      [4..5): ▏                                                     ( 0.16% n=1)
-      [5..6): ██▍                                                   ( 0.64% n=4)
-      [6..7): ██████▏                                               ( 1.60% n=10)
-      [7..8): ████████████▍                                         ( 3.20% n=20)
-      [8..9): █████████████████████▊                                ( 5.60% n=35)
-     [9..10): ████████████████████████████████▍                     ( 8.32% n=52)
-    [10..11): ██████████████████████████████████████████▍           (10.88% n=68)
-    [11..12): █████████████████████████████████████████████████▉    (12.80% n=80)
-    [12..13): ████████████████████████████████████████████████████▉ (13.60% n=85)
-    [13..14): █████████████████████████████████████████████████▉    (12.80% n=80)
-    [14..15): ██████████████████████████████████████████▍           (10.88% n=68)
-    [15..16): ████████████████████████████████▍                     ( 8.32% n=52)
-    [16..17): █████████████████████▊                                ( 5.60% n=35)
-    [17..18): ████████████▍                                         ( 3.20% n=20)
-    [18..19): ██████▏                                               ( 1.60% n=10)
-    [19..20): ██▍                                                   ( 0.64% n=4)
-    [20..21): ▏                                                     ( 0.16% n=1)
+      [5..6): ▏                                                     ( 0.10% n=1)
+      [6..7): █▋                                                    ( 0.49% n=5)
+      [7..8): █████▏                                                ( 1.46% n=15)
+      [8..9): ███████████▉                                          ( 3.42% n=35)
+     [9..10): ██████████████████████▏                               ( 6.35% n=65)
+    [10..11): ██████████████████████████████████▌                   ( 9.86% n=101)
+    [11..12): ██████████████████████████████████████████████▏       (13.18% n=135)
+    [12..13): ████████████████████████████████████████████████████▉ (15.14% n=155)
+    [13..14): ████████████████████████████████████████████████████▉ (15.14% n=155)
+    [14..15): ██████████████████████████████████████████████▏       (13.18% n=135)
+    [15..16): ██████████████████████████████████▌                   ( 9.86% n=101)
+    [16..17): ██████████████████████▏                               ( 6.35% n=65)
+    [17..18): ███████████▉                                          ( 3.42% n=35)
+    [18..19): █████▏                                                ( 1.46% n=15)
+    [19..20): █▋                                                    ( 0.49% n=5)
+    [20..21): ▏                                                     ( 0.10% n=1)
     --------------------------------------------------------------------------------
-     [4..21):                                                         pop(Σn)=625
-                                                                      mean(x̄)=12.000
+     [5..21):                                                         pop(Σn)=1024
+                                                                      mean(μ)=12.500
                                                                   median(p50)=12.000
                                                                      mode(Mo)=12.000
-                                                                     stdev(σ)=0.113
-
+                                                                     stdev(σ)=2.500
 """
 
 import math
@@ -183,7 +181,7 @@ class SimpleHistogram(Generic[T]):
                     details.lowest_start = start
                 if details.highest_end is None or end > details.highest_end:
                     details.highest_end = end
-                label = f'[{label_formatter}..{label_formatter}): ' % (start, end)
+                label = f"[{label_formatter}..{label_formatter}): " % (start, end)
                 label_width = len(label)
                 if (
                     details.max_label_width is None
@@ -192,7 +190,7 @@ class SimpleHistogram(Generic[T]):
                     details.max_label_width = label_width
         return details
 
-    def __repr__(self, *, width: int = 80, label_formatter: str = '%d') -> str:
+    def __repr__(self, *, width: int = 80, label_formatter: str = "%d") -> str:
         """Returns a pretty (text) representation of the histogram and
         some vital stats about the population in it (min, max, mean,
         median, mode, stdev, etc...)
@@ -207,7 +205,7 @@ class SimpleHistogram(Generic[T]):
         assert details.lowest_start is not None
         assert details.highest_end is not None
         assert details.max_population is not None
-        sigma_label = f'[{label_formatter}..{label_formatter}): ' % (
+        sigma_label = f"[{label_formatter}..{label_formatter}): " % (
             details.lowest_start,
             details.highest_end,
         )
@@ -218,7 +216,7 @@ class SimpleHistogram(Generic[T]):
         for (start, end), pop in sorted(self.buckets.items(), key=lambda x: x[0]):
             if start < details.lowest_start:
                 continue
-            label = f'[{label_formatter}..{label_formatter}): ' % (start, end)
+            label = f"[{label_formatter}..{label_formatter}): " % (start, end)
             bar = bar_graph_string(
                 pop,
                 details.max_population,
@@ -232,17 +230,17 @@ class SimpleHistogram(Generic[T]):
             txt += f"({pop/self.count*100.0:5.2f}% n={pop})\n"
             if start == details.last_bucket_start:
                 break
-        txt += '-' * width + '\n'
+        txt += "-" * width + "\n"
         txt += sigma_label.rjust(details.max_label_width)
-        txt += ' ' * (bar_width - 2)
-        txt += f'     pop(Σn)={self.count}\n'
-        txt += ' ' * (bar_width + details.max_label_width - 2)
-        txt += f'     mean(x̄)={self.stats.get_mean():.3f}\n'
-        txt += ' ' * (bar_width + details.max_label_width - 2)
-        txt += f' median(p50)={self.stats.get_median():.3f}\n'
-        txt += ' ' * (bar_width + details.max_label_width - 2)
-        txt += f'    mode(Mo)={self.stats.get_mode()[0]:.3f}\n'
-        txt += ' ' * (bar_width + details.max_label_width - 2)
-        txt += f'    stdev(σ)={self.stats.get_stdev():.3f}\n'
-        txt += '\n'
+        txt += " " * (bar_width - 2)
+        txt += f"     pop(Σn)={self.count}\n"
+        txt += " " * (bar_width + details.max_label_width - 2)
+        txt += f"     mean(μ)={self.stats.get_mean():.3f}\n"
+        txt += " " * (bar_width + details.max_label_width - 2)
+        txt += f" median(p50)={self.stats.get_median():.3f}\n"
+        txt += " " * (bar_width + details.max_label_width - 2)
+        txt += f"    mode(Mo)={self.stats.get_mode()[0]:.3f}\n"
+        txt += " " * (bar_width + details.max_label_width - 2)
+        txt += f"    stdev(σ)={self.stats.get_stdev():.3f}\n"
+        txt += "\n"
         return txt