# Path: user_metrics/etl/aggregator.py
# METRIC_AGG_METHOD_FLAG = 'metric_agg_flag'
# 
# METRIC_AGG_METHOD_NAME = 'metric_agg_name'
# 
# METRIC_AGG_METHOD_HEAD = 'metric_agg_head'
# 
# METRIC_AGG_METHOD_KWARGS = 'metric_agg_kwargs'
# 
# Path: user_metrics/metrics/user_metric.py
# def pre_metrics_init(init_f):
#     def wrapper(self, **kwargs):
# def log_pool_worker_start(metric_name, worker_name, data, args):
# def log_pool_worker_end(metric_name, worker_name, extra=''):
#     def __init__(self, message="Unable to process results using "
#                                "strategy."):
#     def append_params(self, class_ref):
#     def _pack_params(self):
#     def _unpack_params(args):
#     def assign_attributes(self, kwargs, arg_type):
#     def __init__(self, **kwargs):
#     def __str__(self):
#     def __iter__(self):
#     def _construct_data_point(cls):
#     def _format_namespace(cls, namespace):
#     def header():
#     def pre_process_metric_call(proc_func):
#         def wrapper(self, users, **kwargs):
#     def process(self, users, **kwargs):
# class UserMetricError(Exception):
# class UserMetric(object):
#     ALL_NAMESPACES = 'all'
#     DATETIME_STR_FORMAT = "%Y%m%d%H%M%S"
#     DEFAULT_DATE_START = '20100101000000'
#     DEFAULT_DATE_END = '20200101000000'
#     DEFAULT_DATA_RANGE = 14
# 
# Path: user_metrics/etl/aggregator.py
# def weighted_rate(iter, **kwargs):
#     """
#         Computes a weighted rate over the elements of the iterator.
#     """
# 
#     def weight_method_default(x):
#         return 1
# 
#     weight_idx = kwargs['weight_idx'] if 'weight_idx' in kwargs else 1
#     val_idx = kwargs['val_idx'] if 'val_idx' in kwargs else 1
#     weight_method = kwargs['weight_method'] if 'cmp_method' in kwargs else \
#         weight_method_default
# 
#     count = 0
#     total_weight = 0.0
#     weighted_sum = 0.0
#     for r in iter.__iter__():
#         try:
#             count += 1
#             weight = weight_method(r[weight_idx])
#             total_weight += r[weight_idx]
#             weighted_sum += weight * r[val_idx]
#         except IndexError:
#             continue
#         except TypeError:
#             continue
#     if count:
#         return [count, total_weight, weighted_sum / count]
#     else:
#         return [count, total_weight, 0.0]
# 
# def decorator_builder(header):
#     """
#         Decorator method to annotate aggregation methods to ensure the correct
#         data model is exposed by::
# 
#             metric_agg = decorator_builder(Metric.header())(metric_agg)
#     """
#     def eval_data_model(f):
#         def wrapper(metric, **kwargs):
#             if hasattr(metric, 'header'):
#                 header_arg = metric.header()
#                 if all(
#                         header_arg[i] == header[i]
#                         for i in range(len(header)-1)):
#                     return f(metric, **kwargs)
#             else:
#                 raise AggregatorError('This aggregator (%s) does not operate '
#                                       'on this data type.' % f.__name__)
#         return wrapper
#     return eval_data_model
# 
# def boolean_rate(iter, **kwargs):
#     """
#         Computes the fraction of rows meeting a comparison criteria defined
#         by `cmp_method`.  The index containing the value is passed as a kwarg
#         (`bool_idx`).
# 
#         Useful aggregator for boolean metrics: threshold, survival,
#                 live_accounts
#     """
# 
#     def cmp_method_default(x):
#         return x > 0
# 
#     val_idx = kwargs['val_idx'] if 'val_idx' in kwargs else 1
#     cmp_method = kwargs['cmp_method'] if 'cmp_method' in kwargs \
#         else cmp_method_default
# 
#     total = 0
#     pos = 0
#     for r in iter.__iter__():
#         try:
#             if cmp_method(r[val_idx]):
#                 pos += 1
#             total += 1
#         except IndexError:
#             continue
#         except TypeError:
#             continue
#     if total:
#         return [total, pos, float(pos) / total]
#     else:
#         return [total, pos, 0.0]


from collections import namedtuple
from user_metrics.etl.aggregator import METRIC_AGG_METHOD_FLAG, \
    METRIC_AGG_METHOD_NAME, METRIC_AGG_METHOD_HEAD, METRIC_AGG_METHOD_KWARGS
from user_metrics.metrics import user_metric as um
from user_metrics.metrics import query_mod
from user_metrics.etl.aggregator import weighted_rate, decorator_builder,\
    boolean_rate
                rowValues[userid][type] = first

        self._results = [[user,
                          rowValues.get(user)['is_blocked'],
                          rowValues.get(user)['block_count'],
                          rowValues.get(user)['block_first'],
                          rowValues.get(user)['block_last']]
                         for user in rowValues.keys()]
        return self


# ==========================
# DEFINE METRIC AGGREGATORS
# ==========================

# Build "rate" decorator
block_rate_agg = weighted_rate
block_rate_agg = decorator_builder(Blocks.header())(block_rate_agg)

setattr(block_rate_agg, METRIC_AGG_METHOD_FLAG, True)
setattr(block_rate_agg, METRIC_AGG_METHOD_NAME, 'b_rate_agg')
setattr(block_rate_agg, METRIC_AGG_METHOD_HEAD, ['total_users',
                                                    'total_weight',
                                                    'rate'])
setattr(block_rate_agg, METRIC_AGG_METHOD_KWARGS, {
    'val_idx': 2,
})

# Build "proportion" decorator
block_prop_agg = boolean_rate

# Path: user_metrics/etl/aggregator.py
# METRIC_AGG_METHOD_FLAG = 'metric_agg_flag'
# 
# METRIC_AGG_METHOD_NAME = 'metric_agg_name'
# 
# METRIC_AGG_METHOD_HEAD = 'metric_agg_head'
# 
# METRIC_AGG_METHOD_KWARGS = 'metric_agg_kwargs'
# 
# Path: user_metrics/metrics/user_metric.py
# def pre_metrics_init(init_f):
#     def wrapper(self, **kwargs):
# def log_pool_worker_start(metric_name, worker_name, data, args):
# def log_pool_worker_end(metric_name, worker_name, extra=''):
#     def __init__(self, message="Unable to process results using "
#                                "strategy."):
#     def append_params(self, class_ref):
#     def _pack_params(self):
#     def _unpack_params(args):
#     def assign_attributes(self, kwargs, arg_type):
#     def __init__(self, **kwargs):
#     def __str__(self):
#     def __iter__(self):
#     def _construct_data_point(cls):
#     def _format_namespace(cls, namespace):
#     def header():
#     def pre_process_metric_call(proc_func):
#         def wrapper(self, users, **kwargs):
#     def process(self, users, **kwargs):
# class UserMetricError(Exception):
# class UserMetric(object):
#     ALL_NAMESPACES = 'all'
#     DATETIME_STR_FORMAT = "%Y%m%d%H%M%S"
#     DEFAULT_DATE_START = '20100101000000'
#     DEFAULT_DATE_END = '20200101000000'
#     DEFAULT_DATA_RANGE = 14
# 
# Path: user_metrics/etl/aggregator.py
# def weighted_rate(iter, **kwargs):
#     """
#         Computes a weighted rate over the elements of the iterator.
#     """
# 
#     def weight_method_default(x):
#         return 1
# 
#     weight_idx = kwargs['weight_idx'] if 'weight_idx' in kwargs else 1
#     val_idx = kwargs['val_idx'] if 'val_idx' in kwargs else 1
#     weight_method = kwargs['weight_method'] if 'cmp_method' in kwargs else \
#         weight_method_default
# 
#     count = 0
#     total_weight = 0.0
#     weighted_sum = 0.0
#     for r in iter.__iter__():
#         try:
#             count += 1
#             weight = weight_method(r[weight_idx])
#             total_weight += r[weight_idx]
#             weighted_sum += weight * r[val_idx]
#         except IndexError:
#             continue
#         except TypeError:
#             continue
#     if count:
#         return [count, total_weight, weighted_sum / count]
#     else:
#         return [count, total_weight, 0.0]
# 
# def decorator_builder(header):
#     """
#         Decorator method to annotate aggregation methods to ensure the correct
#         data model is exposed by::
# 
#             metric_agg = decorator_builder(Metric.header())(metric_agg)
#     """
#     def eval_data_model(f):
#         def wrapper(metric, **kwargs):
#             if hasattr(metric, 'header'):
#                 header_arg = metric.header()
#                 if all(
#                         header_arg[i] == header[i]
#                         for i in range(len(header)-1)):
#                     return f(metric, **kwargs)
#             else:
#                 raise AggregatorError('This aggregator (%s) does not operate '
#                                       'on this data type.' % f.__name__)
#         return wrapper
#     return eval_data_model
# 
# def boolean_rate(iter, **kwargs):
#     """
#         Computes the fraction of rows meeting a comparison criteria defined
#         by `cmp_method`.  The index containing the value is passed as a kwarg
#         (`bool_idx`).
# 
#         Useful aggregator for boolean metrics: threshold, survival,
#                 live_accounts
#     """
# 
#     def cmp_method_default(x):
#         return x > 0
# 
#     val_idx = kwargs['val_idx'] if 'val_idx' in kwargs else 1
#     cmp_method = kwargs['cmp_method'] if 'cmp_method' in kwargs \
#         else cmp_method_default
# 
#     total = 0
#     pos = 0
#     for r in iter.__iter__():
#         try:
#             if cmp_method(r[val_idx]):
#                 pos += 1
#             total += 1
#         except IndexError:
#             continue
#         except TypeError:
#             continue
#     if total:
#         return [total, pos, float(pos) / total]
#     else:
#         return [total, pos, 0.0]


# Path: user_metrics/metrics/blocks.py
from collections import namedtuple
from user_metrics.etl.aggregator import METRIC_AGG_METHOD_FLAG, \
    METRIC_AGG_METHOD_NAME, METRIC_AGG_METHOD_HEAD, METRIC_AGG_METHOD_KWARGS
from user_metrics.metrics import user_metric as um
from user_metrics.metrics import query_mod
from user_metrics.etl.aggregator import weighted_rate, decorator_builder,\
    boolean_rate

                rowValues[userid][type] = first

        self._results = [[user,
                          rowValues.get(user)['is_blocked'],
                          rowValues.get(user)['block_count'],
                          rowValues.get(user)['block_first'],
                          rowValues.get(user)['block_last']]
                         for user in rowValues.keys()]
        return self


# ==========================
# DEFINE METRIC AGGREGATORS
# ==========================

# Build "rate" decorator
block_rate_agg = weighted_rate
block_rate_agg = decorator_builder(Blocks.header())(block_rate_agg)

setattr(block_rate_agg, METRIC_AGG_METHOD_FLAG, True)
setattr(block_rate_agg, METRIC_AGG_METHOD_NAME, 'b_rate_agg')
setattr(block_rate_agg, METRIC_AGG_METHOD_HEAD, ['total_users',
                                                    'total_weight',
                                                    'rate'])
setattr(block_rate_agg, METRIC_AGG_METHOD_KWARGS, {
    'val_idx': 2,
})

# Build "proportion" decorator
block_prop_agg = boolean_rate

block_prop_agg = decorator_builder(Blocks.header())(block_prop_agg)