123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- '''Tool for a script to keep track changes performed on a large number
- of objects.
- StatsCount - when you are counting incidences of a small set of outcomes
- StatsList - when you also want to remember an ID associated with each incidence
- Examples:
- from running_stats import StatsCount
- package_stats = StatsCount()
- for package in packages:
- if package.enabled:
- package.delete()
- package_stats.increment('deleted')
- else:
- package_stats.increment('not deleted')
- print package_stats.report()
- > deleted: 30
- > not deleted: 70
- from running_stats import StatsList
- package_stats = StatsList()
- for package in packages:
- if package.enabled:
- package.delete()
- package_stats.add('deleted', package.name)
- else:
- package_stats.add('not deleted' package.name)
- print package_stats.report()
- > deleted: 30 pollution-uk, flood-regions, river-quality, ...
- > not deleted: 70 spending-bristol, ...
- '''
- from __future__ import print_function
- import copy
- import datetime
- class StatsCount(dict):
- # {category:count}
- _init_value = 0
- report_value_limit = 150
- def __init__(self, *args, **kwargs):
- self._start_time = datetime.datetime.now()
- super(StatsCount, self).__init__(*args, **kwargs)
- def _init_category(self, category):
- if category not in self:
- self[category] = copy.deepcopy(self._init_value)
- def increment(self, category):
- self._init_category(category)
- self[category] += 1
- def report_value(self, category):
- '''Returns the value for a category and value to sort categories by.'''
- value = repr(self[category])
- if len(value) > self.report_value_limit:
- value = value[:self.report_value_limit] + '...'
- return (value, self[category])
- def report(self, indent=1, order_by_title=False, show_time_taken=True):
- lines = []
- indent_str = '\t' * indent
- report_dict = dict()
- for category in list(self.keys()):
- report_dict[category] = self.report_value(category)
- if order_by_title:
- items = sorted(report_dict.items())
- else:
- items = sorted(iter(report_dict.items()),
- key=lambda x: -x[1][1])
- for category, value_tuple in items:
- value = value_tuple[0]
- lines.append(indent_str + '%s: %s' % (category, value))
- if not self:
- lines = [indent_str + 'None']
- if show_time_taken:
- time_taken = datetime.datetime.now() - self._start_time
- lines.append(indent_str + 'Time taken (h:m:s): %s' % time_taken)
- return '\n'.join(lines)
- class StatsList(StatsCount):
- # {category:[values]}
- _init_value = []
- def add(self, category, value):
- self._init_category(category)
- self[category].append(value)
- return '%s: %s' % (category, value) # so you can log it too
- def report_value(self, category):
- value = self[category]
- number_of_values = len(value)
- value_str = '%i %r' % (number_of_values, value)
- if len(value_str) > self.report_value_limit:
- value_str = value_str[:self.report_value_limit] + '...'
- return (value_str, number_of_values)
- if __name__ == '__main__':
- package_stats = StatsList()
- package_stats.add('Success', 'good1')
- package_stats.add('Success', 'good2')
- package_stats.add('Success', 'good3')
- package_stats.add('Success', 'good4')
- package_stats.add('Failure', 'bad1')
- print(package_stats.report())
- print(StatsList().report())
|