def get_course_mau_history_metrics(site, course_id, date_for, months_back): """Quick copy/modification of 'get_monthly_history_metric' for Course MAU """ date_for = as_date(date_for) history = [] for year, month, _ in previous_months_iterator( month_for=date_for, months_back=months_back, ): period = '{year}/{month}'.format(year=year, month=str(month).zfill(2)) active_users = get_mau_from_site_course(site=site, course_id=course_id, year=year, month=month) history.append(dict( period=period, value=active_users.count(), )) if history: # use the last entry current_month = history[-1]['value'] else: # This should work for float too since '0 == 0.0' resolves to True current_month = 0 return dict(current_month=current_month, history=history)
def get_monthly_history_metric(func, site, date_for, months_back, include_current_in_history=True): # pylint: disable=unused-argument """Convenience method to retrieve current and historic data Convenience function to populate monthly metrics data with history. Purpose is to provide a time series list of values for a particular metrics going back N months :param func: the function we call for each time point :param date_for: The most recent date for which we generate data. This is the "current month" :param months_back: How many months back to retrieve data :param include_current_in_history: flag to include the current month as well as previous months :type func: Python function :type date_for: datetime.datetime, datetime.date, or date as a string :type months_back: integer :type include_current_in_history: boolean :return: a dict with two keys. ``current_month`` contains the monthly metrics for the month in ``date_for``. ``history`` contains a list of metrics for the current period and perids going back ``months_back`` :rtype: dict Each list item contains two keys, ``period``, containing the year and month for the data and ``value`` containing the numeric value of the data """ date_for = as_date(date_for) history = [] for month in previous_months_iterator( month_for=date_for, months_back=months_back, ): period = period_str(month) value = func( site=site, start_date=datetime.date(month[0], month[1], 1), end_date=datetime.date(month[0], month[1], month[2]), ) history.append(dict( period=period, value=value, )) if history: # use the last entry current_month = history[-1]['value'] else: # This should work for float too since '0 == 0.0' resolves to True current_month = 0 return dict( current_month=current_month, history=history, )
def test_previous_months_iterator(self, month_for, months_back): expected_vals = [] month_for = datetime.date(year=month_for[0], month=month_for[1], day=month_for[2]) for i in range(max(1, months_back), 0, -1): # e.g., 6, 5, 4, 3, 2, 1 a_month = month_for - relativedelta(months=i - 1) last_day_in_month = calendar.monthrange(a_month.year, a_month.month)[1] expected_vals.append( (a_month.year, a_month.month, last_day_in_month)) vals = list(previous_months_iterator(month_for, months_back)) assert vals == expected_vals
def test_previous_months_iterator(self, month_for, months_back, first_month): def as_month_tuple(month): return (month.year, month.month) expected_vals = [] for i in range(months_back): a_month = first_month+relativedelta(months=i) last_day_in_month = calendar.monthrange(a_month.year, a_month.month)[1] expected_vals.append( (a_month.year, a_month.month, last_day_in_month) ) expected_vals.append(month_for) vals = list(previous_months_iterator(month_for, months_back)) assert vals == expected_vals