# 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 build_numpy_op_agg(agg_meta_list, metric_header, method_handle):
#     """
#         Builder method for ``numpy_op`` aggregator.
#     """
#     agg_method = numpy_op
#     agg_method = decorator_builder(metric_header)(agg_method)
#     agg_meta_header = [o.field_name for o in agg_meta_list]
# 
#     setattr(agg_method, METRIC_AGG_METHOD_FLAG, True)
#     setattr(agg_method, METRIC_AGG_METHOD_NAME, method_handle)
#     setattr(agg_method, METRIC_AGG_METHOD_HEAD, agg_meta_header)
#     setattr(agg_method, METRIC_AGG_METHOD_KWARGS,
#             {
#                 'agg_meta': agg_meta_list
#             }
#             )
#     return agg_method
# 
# def build_agg_meta(op_list, field_prefix_names):
#     """
#         Builder helper method for building module aggregators via
#         ``build_numpy_op_agg``.
#     """
#     return [AggregatorMeta(name + op.__name__, index, op)
#             for name, index in field_prefix_names.iteritems()
#             for op in op_list]
# 
# Path: user_metrics/metrics/users.py
# USER_METRIC_PERIOD_TYPE = enum(REGISTRATION='REGISTRATION', INPUT='INPUT')
# 
# Path: user_metrics/metrics/user_metric.py
# METRIC_AGG_METHOD_KWARGS = 'metric_agg_kwargs'


from copy import deepcopy
from dateutil.parser import parse as date_parse
from user_metrics.etl.aggregator import weighted_rate, decorator_builder, \
    build_numpy_op_agg, build_agg_meta
from numpy import median, min, max, mean, std
from user_metrics.metrics.users import USER_METRIC_PERIOD_TYPE as umpt
from user_metrics.utils import enum, format_mediawiki_timestamp
from user_metrics.metrics.user_metric import METRIC_AGG_METHOD_KWARGS
import user_metric as um
import edit_count as ec

    @um.UserMetric.pre_process_metric_call
    def process(self, user_handle, **kwargs):
        """
            Determine the edit rate of user(s).  The parameter *user_handle*
            can be either a string or an integer or a list of these types.
            When the *user_handle* type is integer it is interpreted as a user
            id, and as a user_name for string input.  If a list of users is
            passed to the *process* method then a dict object with edit rates
            keyed by user handles is returned.

            - Parameters:
                - **user_handle** - String or Integer (optionally lists).
                    Value or list of values representing user handle(s).

            - Return:
                - Dictionary. key(string): user handle, value(Float):
                edit counts
        """

        # Extract edit count for given parameters
        edit_rate = list()
        ec_kwargs = deepcopy(self.__dict__)
        e = ec.EditCount(**ec_kwargs).process(user_handle, **kwargs)

        # Compute time difference between datetime objects and get the
        # integer number of seconds

        if self.group == umpt.REGISTRATION:
            time_diff_sec = self.t * 3600.0

# 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 build_numpy_op_agg(agg_meta_list, metric_header, method_handle):
#     """
#         Builder method for ``numpy_op`` aggregator.
#     """
#     agg_method = numpy_op
#     agg_method = decorator_builder(metric_header)(agg_method)
#     agg_meta_header = [o.field_name for o in agg_meta_list]
# 
#     setattr(agg_method, METRIC_AGG_METHOD_FLAG, True)
#     setattr(agg_method, METRIC_AGG_METHOD_NAME, method_handle)
#     setattr(agg_method, METRIC_AGG_METHOD_HEAD, agg_meta_header)
#     setattr(agg_method, METRIC_AGG_METHOD_KWARGS,
#             {
#                 'agg_meta': agg_meta_list
#             }
#             )
#     return agg_method
# 
# def build_agg_meta(op_list, field_prefix_names):
#     """
#         Builder helper method for building module aggregators via
#         ``build_numpy_op_agg``.
#     """
#     return [AggregatorMeta(name + op.__name__, index, op)
#             for name, index in field_prefix_names.iteritems()
#             for op in op_list]
# 
# Path: user_metrics/metrics/users.py
# USER_METRIC_PERIOD_TYPE = enum(REGISTRATION='REGISTRATION', INPUT='INPUT')
# 
# Path: user_metrics/metrics/user_metric.py
# METRIC_AGG_METHOD_KWARGS = 'metric_agg_kwargs'


# Path: user_metrics/metrics/edit_rate.py
from copy import deepcopy
from dateutil.parser import parse as date_parse
from user_metrics.etl.aggregator import weighted_rate, decorator_builder, \
    build_numpy_op_agg, build_agg_meta
from numpy import median, min, max, mean, std
from user_metrics.metrics.users import USER_METRIC_PERIOD_TYPE as umpt
from user_metrics.utils import enum, format_mediawiki_timestamp
from user_metrics.metrics.user_metric import METRIC_AGG_METHOD_KWARGS
import user_metric as um
import edit_count as ec


    @um.UserMetric.pre_process_metric_call
    def process(self, user_handle, **kwargs):
        """
            Determine the edit rate of user(s).  The parameter *user_handle*
            can be either a string or an integer or a list of these types.
            When the *user_handle* type is integer it is interpreted as a user
            id, and as a user_name for string input.  If a list of users is
            passed to the *process* method then a dict object with edit rates
            keyed by user handles is returned.

            - Parameters:
                - **user_handle** - String or Integer (optionally lists).
                    Value or list of values representing user handle(s).

            - Return:
                - Dictionary. key(string): user handle, value(Float):
                edit counts
        """

        # Extract edit count for given parameters
        edit_rate = list()
        ec_kwargs = deepcopy(self.__dict__)
        e = ec.EditCount(**ec_kwargs).process(user_handle, **kwargs)

        # Compute time difference between datetime objects and get the
        # integer number of seconds

        if self.group == umpt.REGISTRATION:
            time_diff_sec = self.t * 3600.0

        elif self.group == umpt.INPUT: