diff --git a/saucebrush/stats.py b/saucebrush/stats.py index cc5ba83..796d3fe 100644 --- a/saucebrush/stats.py +++ b/saucebrush/stats.py @@ -7,7 +7,9 @@ def _average(values): :param values: an iterable of ints or floats to average """ - return sum(values) / float(len(values)) + value_count = len(values) + if len(values) > 0: + return sum(values) / float(value_count) def _median(values): """ Calculate the median of a list of values. @@ -174,4 +176,28 @@ class StandardDeviation(StatsFilter): :param population: True if values represents entire population, False if values is a sample. Default: False """ - return _stddev(self._values, population) \ No newline at end of file + return _stddev(self._values, population) + +class Histogram(StatsFilter): + + label_length = 6 + + def __init__(self, field, **kwargs): + super(Histogram, self).__init__(field, **kwargs) + self._data = {} + + def process_field(self, item): + if item not in self._data: + self._data[item] = 0 + self._data[item] += 1 + + def value(self): + return self._data.copy() + + def __str__(self): + output = "" + for key in sorted(self._data.keys()): + key_str = str(key).ljust(self.label_length)[:self.label_length] + output += "%s %s\n" % (key_str, "*" * self._data[key]) + return output + \ No newline at end of file diff --git a/saucebrush/tests/stats.py b/saucebrush/tests/stats.py index cd797a1..5040ddf 100644 --- a/saucebrush/tests/stats.py +++ b/saucebrush/tests/stats.py @@ -1,5 +1,5 @@ import unittest -from saucebrush.stats import Sum, Average, Median, MinMax, StandardDeviation +from saucebrush.stats import Sum, Average, Median, MinMax, StandardDeviation, Histogram class StatsTestCase(unittest.TestCase): @@ -41,6 +41,12 @@ class StatsTestCase(unittest.TestCase): self.assertEqual(fltr.median(), 5) self.assertEqual(fltr.value(), (55.4346462061408, 3073.0)) self.assertEqual(fltr.value(True), (45.2621990922521, 2048.6666666666665)) + + def test_histogram(self): + fltr = Histogram('a') + fltr.label_length = 1 + list(fltr.attach(self._simple_data())) + self.assertEqual(str(fltr), "1 **\n5 *\n") if __name__ == '__main__': unittest.main()