|
5 | 5 | class CDPMetric(cdp.cdp_tool.CDPTool):
|
6 | 6 | __metaclass__ = abc.ABCMeta
|
7 | 7 |
|
8 |
| - def __init__(self, var, data1, data2): |
9 |
| - self.var = var |
10 |
| - self.data1 = data1 |
11 |
| - self.data2 = data2 |
| 8 | + def __init__(self, metric_path): |
| 9 | + # metric_path: printed when this metric is used. |
| 10 | + # Let's users know when a metric is called in the code. |
| 11 | + # _values: dictionary of the computed values. This allows for compound metrics. |
| 12 | + self._metric_path = metric_path |
| 13 | + # get the 'filename' from /path/to/filename.py |
| 14 | + name_with_py = self._metric_path.split('/')[-1] |
| 15 | + name = name_with_py.split('.')[0] |
| 16 | + self._values = {name: self} |
12 | 17 |
|
13 |
| - def __call__(self): |
14 |
| - self.compute() |
| 18 | + def __call__(self, *args, **kwargs): |
| 19 | + self._show_metric_information() |
| 20 | + if self._is_compound(): |
| 21 | + # Remove the 'CompoundMetric' key from the _values |
| 22 | + self._values.pop('CompoundMetric') |
| 23 | + # loop through and calculate all of the metrics |
| 24 | + for key, value in self._values.items(): |
| 25 | + # replaces the function with the actual value |
| 26 | + self._values[key] = value(*args, **kwargs) |
| 27 | + return self._values |
| 28 | + else: |
| 29 | + return self.compute(*args, **kwargs) |
| 30 | + |
| 31 | + def __add__(self, other): |
| 32 | + class CompoundMetric(CDPMetric): |
| 33 | + def compute(self): |
| 34 | + pass |
| 35 | + compound_metric = CompoundMetric('CompoundMetric') |
| 36 | + self._add_values_dict_into_first(compound_metric, self) |
| 37 | + self._add_values_dict_into_first(compound_metric, other) |
| 38 | + return compound_metric |
| 39 | + |
| 40 | + def __sub__(self, other): |
| 41 | + class CompoundMetric(CDPMetric): |
| 42 | + def compute(self): |
| 43 | + pass |
| 44 | + if not self._is_compound(): |
| 45 | + raise TypeError('First operand must be a CompoundMetric') |
| 46 | + compound_metric = CompoundMetric('CompoundMetric') |
| 47 | + self._add_values_dict_into_first(compound_metric, self) |
| 48 | + self._subtract_values_dict_into_first(compound_metric, other) |
| 49 | + return compound_metric |
| 50 | + |
| 51 | + def _is_compound(self): |
| 52 | + """ Determines if the current metric was a compound metric, one |
| 53 | + created with the + operator. """ |
| 54 | + return len(self._values) > 1 |
| 55 | + |
| 56 | + def _add_values_dict_into_first(self, compound_metric, other_metric): |
| 57 | + """ Merges the _values dict of two objects of type CDPMetric |
| 58 | + into the first. """ |
| 59 | + for key, value in other_metric._values.items(): |
| 60 | + compound_metric._values[key] = value |
| 61 | + |
| 62 | + def _subtract_values_dict_into_first(self, compound_metric, other_metric): |
| 63 | + """ Removes the elements of the _values dict of the second |
| 64 | + object from the first object's _values dict. """ |
| 65 | + for key in other_metric._values: |
| 66 | + if compound_metric._values.pop(key, None) is None: |
| 67 | + print "Could not subtract %s metric since it's not in the first operand." % key |
| 68 | + |
| 69 | + def _show_metric_information(self): |
| 70 | + """ Displays information about this metric so that a user |
| 71 | + can easily identify what metrics are being used. """ |
| 72 | + print 'Using metric: ' + self._metric_path |
15 | 73 |
|
16 | 74 | @abc.abstractmethod
|
17 | 75 | def compute(self):
|
|
0 commit comments