def _set_cumulative_points(self, point, previous): """ In place modification of point cumulative-to-present based on previous sorted points. """ mode = getattr(self, 'cumulative', '') if not mode: return # not cumulative, no more work to do opkey = getattr(self, 'cumulative_fn', 'SUM') cfn = AGGREGATE_FUNCTIONS.get(opkey) to_date = list(previous) + [point] _div = lambda a, b: float(a) / float(b) if b else NOVALUE divide = lambda a, b: NOVALUE if a is None or b is None else _div(a, b) if mode == 'numerator': key = 'raw_numerator' values = filter( lambda v: not math.isnan(v), [p.get(key) for p in to_date], ) cnum = point['cumulative_numerator'] = cfn(values) val = point['value'] = self._normalize( divide(cnum, point.get('raw_denominator'))) point['display_value'] = self.display_format(val) point['user_notes'] = '%s%s' % ( point.get('user_notes', '') or '', ' (cumulative numerator)', ) return # TODO: denominator, both, final modes
def _summarized_field_value(self, context, fieldpath, fn): """Return summarized value, for field, across all records in context""" fn = AGGREGATE_FUNCTIONS.get(fn) values = filter( lambda v: v is not None, [getattr(record, fieldpath, None) for record in context.values()]) return fn([float(v) for v in values])
def _set_cumulative_points(self, point, previous): """ In place modification of point cumulative-to-present based on previous sorted points. """ mode = getattr(self, 'cumulative', '') if not mode: return # not cumulative, no more work to do opkey = getattr(self, 'cumulative_fn', 'SUM') cfn = AGGREGATE_FUNCTIONS.get(opkey) to_date = list(previous) + [point] _div = lambda a, b: float(a) / float(b) if b else NOVALUE divide = lambda a, b: NOVALUE if a is None or b is None else _div(a, b) if mode == 'numerator': key = 'raw_numerator' values = filter( lambda v: not math.isnan(v), [p.get(key) for p in to_date], ) cnum = point['cumulative_numerator'] = cfn(values) val = point['value'] = self._normalize( divide(cnum, point.get('raw_denominator')) ) point['display_value'] = self.display_format(val) point['user_notes'] = '%s%s' % ( point.get('user_notes', '') or '', ' (cumulative numerator)', ) return # TODO: denominator, both, final modes
def _summarized_field_value(self, context, fieldpath, fn): """Return summarized value, for field, across all records in context""" fn = AGGREGATE_FUNCTIONS.get(fn) values = filter( lambda v: v is not None, [getattr(record, fieldpath, None) for record in context.values()] ) return fn([float(v) for v in values])
def _aggregate_dataset_points(self, aggregated, fn_name): """ given a list of other aggregated datasets, get data for each, and calculate aggregate values for points, given a value aggregation function (fn). """ consider = lambda o: o is not None fn = AGGREGATE_FUNCTIONS.get(fn_name) label = dict(AGGREGATE_LABELS).get(fn_name, '') result = [] raw = [] for ds in filter(consider, aggregated): points = self._dataset_points(ds) raw.append(points) all_points = list(chain(*raw)) _date = lambda info: info.get('start', None) dates = sorted(set(map(_date, all_points))) # de-duped ordered dates for d in dates: _hasvalue = lambda info: not math.isnan(info.get('value', NOVALUE)) _match = lambda info: info.get('start') == d and _hasvalue(info) matches = filter(_match, all_points) if not matches: continue # skip columns/dates for which no match found values = [info.get('value') for info in matches] calculated_value = fn(values) if math.isnan(calculated_value): continue includes = ', '.join([info.get('title') for info in matches]) result.append({ 'title': '%s: %s' % (label, d.isoformat()), 'url': self.absolute_url(), 'path': '--', 'start': d, 'value': calculated_value, 'user_notes': 'Aggregate value (%s) includes: %s' % ( label, includes, ), 'display_value': self.display_format(calculated_value), }) return result