# Tai Sakuma <tai.sakuma@gmail.com>
import copy
import logging
##__________________________________________________________________||
N_KEYS = 3
IDX_DEPTH = 0
IDX_PASS = 3
IDX_TOTAL = 4
##__________________________________________________________________||
[docs]class Count:
[docs] def __init__(self, selections=None):
if selections is None:
selections = [ ]
self._results = [ ]
for sel in selections:
self.add(sel)
def __repr__(self):
return '{}({!r})'.format(self.__class__.__name__, self._results)
def copy(self):
return copy.deepcopy(self)
def add(self, selection):
init_result = self._init_result_for_selection(selection)
self._results.append(init_result)
def _init_result_for_selection(self, selection):
#
class_name = selection.__class__.__name__
#
if hasattr(selection, 'name') and selection.name is not None:
selection_name = selection.name
else:
selection_name = ''
#
depth = 1
pass_ = 0
total = 0
#
return [depth, class_name, selection_name, pass_, total]
def count(self, pass_):
for r, p in zip(self._results, pass_):
r[IDX_TOTAL] += 1 # total
if p: r[IDX_PASS] += 1 # pass
def increment_depth(self, by = 1):
for r in self._results:
r[IDX_DEPTH] += by
def insert(self, i, other):
self._results[(i + 1):(i + 1)] = other._results
def results(self):
return self._results
def __add__(self, other):
ret = self.copy()
if other == 0: # other is 0 when e.g. sum([obj1, obj2])
return ret
self._add_results_inplace(ret._results, other._results)
return ret
def __iadd__(self, other):
self._add_results_inplace(self._results, other._results)
return self
def __radd__(self, other):
return self.__add__(other)
def _add_results_inplace(self, res1, res2):
if not len(res1) == len(res2):
logger = logging.getLogger(__name__)
logger.warning('cannot add because res1 and res2 don\'t have the same length: res1 = {}, res2 = {}'.format(res1, res2))
return
if not all([(r1[:N_KEYS] == r2[:N_KEYS]) for r1, r2 in zip(res1, res2)]):
logger = logging.getLogger(__name__)
logger.warning('cannot add because res1 and res2 don\'t have the same key columns: res1 = {}, res2 = {}'.format(res1, res2))
return
for r1, r2 in zip(res1, res2):
r1[IDX_PASS] += r2[IDX_PASS]
r1[IDX_TOTAL] += r2[IDX_TOTAL]
def to_tuple_list(self):
return [tuple(e) for e in self._results]
##__________________________________________________________________||