X-Git-Url: https://wannabe.guru.org/gitweb/?a=blobdiff_plain;f=histogram.py;h=52a0d1fad558a493c6e303abdd07a6933053a045;hb=532df2c5b57c7517dfb3dddd8c1358fbadf8baf3;hp=9c07df9b588aef626ecf8217a70ac4fd9676eb9d;hpb=a4b50bb62e2653d3d084c6c7e0574abb9277b8d7;p=python_utils.git diff --git a/histogram.py b/histogram.py index 9c07df9..52a0d1f 100644 --- a/histogram.py +++ b/histogram.py @@ -1,6 +1,8 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- +# © Copyright 2021-2022, Scott Gasch + """A text-based simple histogram helper class.""" import math @@ -32,7 +34,7 @@ class SimpleHistogram(Generic[T]): NEGATIVE_INFINITY = -math.inf def __init__(self, buckets: List[Tuple[Bound, Bound]]): - from math_utils import RunningMedian + from math_utils import NumericPopulation self.buckets: Dict[Tuple[Bound, Bound], Count] = {} for start_end in buckets: @@ -40,7 +42,7 @@ class SimpleHistogram(Generic[T]): raise Exception("Buckets overlap?!") self.buckets[start_end] = 0 self.sigma: float = 0.0 - self.stats: RunningMedian = RunningMedian() + self.stats: NumericPopulation = NumericPopulation() self.maximum: Optional[T] = None self.minimum: Optional[T] = None self.count: Count = 0 @@ -122,9 +124,11 @@ class SimpleHistogram(Generic[T]): ) if len(sigma_label) > details.max_label_width: details.max_label_width = len(sigma_label) - bar_width = width - (details.max_label_width + 16) + bar_width = width - (details.max_label_width + 17) 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) bar = bar_graph( (pop / details.max_population), @@ -141,12 +145,14 @@ class SimpleHistogram(Generic[T]): txt += '-' * width + '\n' txt += sigma_label.rjust(details.max_label_width) txt += ' ' * (bar_width - 2) - txt += f'Σ=(100.00% n={self.count})\n' + 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'mean(μ)={self.stats.get_mean():.3f}\n' + txt += f' median(p50)={self.stats.get_median():.3f}\n' txt += ' ' * (bar_width + details.max_label_width - 2) - txt += f'p50(η)={self.stats.get_median():.3f}\n' + 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 += f' stdev(σ)={self.stats.get_stdev():.3f}\n' txt += '\n' return txt