# Path: kardboard/util.py
# def make_start_date(year=None, month=None, day=None, date=None):
#     start_date = munge_date(year, month, day, date)
#     start_date = start_date.replace(hour=23, minute=59, second=59)
#     start_date = start_date.replace(hour=0, minute=0, second=0)
#     return start_date
# 
# def make_end_date(year=None, month=None, day=None, date=None):
#     end_date = munge_date(year, month, day, date)
#     end_date = end_date.replace(hour=23, minute=59, second=59)
#     return end_date
# 
# def average(values):
#     """Computes the arithmetic mean of a list of numbers.
# 
#     >>> print average([20, 30, 70])
#     40.0
#     """
#     try:
#         return stats.mean(values)
#     except ZeroDivisionError:
#         return None
# 
# def median(values):
#     try:
#         return stats.median(values)
#     except (ValueError, UnboundLocalError):
#         return None
# 
# Path: kardboard/models/statelog.py
# class StateLog(app.db.Document):
#     card = app.db.ReferenceField(
#         'Kard',
#         reverse_delete_rule=app.db.CASCADE,
#         required=True,
#         dbref=False,
#     )
#     # Card that this record is about
#     state = app.db.StringField(required=True)
#     # The state the card was in for this record
#     entered = app.db.DateTimeField(required=True)
#     # Datetime the card entered its state
#     exited = app.db.DateTimeField(required=False)
#     # Datetime the card exited this state
#     _duration = app.db.IntField(required=False)
#     # The duration the card was in this state
#     service_class = app.db.StringField(required=False)
#     # The service class the card was in while in this state
# 
#     created_at = app.db.DateTimeField(required=True)
#     updated_at = app.db.DateTimeField(required=True)
# 
#     meta = {
#         'cascade': False,
#         'ordering': ['-created_at'],
#         'indexes': ['card', 'state', ['card', 'created_at']]
#     }
# 
#     def save(self, *args, **kwargs):
#         if self.id is None:
#             self.created_at = now()
#         if self.entered and self.exited:
#             self._duration = self.duration
#         self.updated_at = now()
#         super(StateLog, self).save(*args, **kwargs)
# 
#     def __repr__(self):
#         return "<StateLog: %s, %s, %s -- %s, %s hours>" % (
#             self.card.key,
#             self.state,
#             self.entered,
#             self.exited,
#             self._duration
#         )
# 
#     @classmethod
#     def kard_pre_save(cls, sender, document, **kwargs):
#         observed_card = document
# 
#         if observed_card.state_changing is False:
#             # No need to worry about logging it, nothing's changing!
#             return None
# 
#         try:
#             observed_card.old_state
#         except AttributeError:
#             raise
# 
#         # If you're here it's because the observed_card's state is changing
#         if observed_card.old_state is not None:
#             try:
#                 slos = cls.objects.filter(
#                     card=observed_card,
#                     state=observed_card.old_state,
#                     service_class=observed_card.service_class.get('name'),
#                     exited__exists=False)
#                 for s in slos:
#                     s.exited = now()
#                     s.save()  # Close the old state log
#             except cls.DoesNotExist:
#                 #  For some reason we didn't record the old state, this should only happen when first rolled out
#                 pass
# 
#     @classmethod
#     def kard_post_save(cls, sender, document, **kwargs):
#         observed_card = document
# 
#         # Is there a currently open state log
#         logs = cls.objects.filter(
#             card=observed_card,
#             state=observed_card.state,
#             exited__exists=False,
#         ).order_by('-entered')
#         if len(logs) == 0:
#             sl = cls(
#                 card=observed_card,
#                 state=observed_card.state,
#                 entered=now()
#             )
#         else:
#             sl = logs[0]
# 
#         sl.service_class = observed_card.service_class.get('name')
#         sl.save()
# 
#     @property
#     def duration(self):
#         if self._duration is not None:
#             return self._duration
# 
#         if self.exited is not None:
#             exited = self.exited
#         else:
#             exited = now()
#         delta = exited - self.entered
#         return delta_in_hours(delta)


import datetime
    import sys
from collections import defaultdict
from dateutil.relativedelta import relativedelta
from kardboard.util import make_start_date, make_end_date, average, median
from kardboard.models.statelog import StateLog




def histogram(counts):
    d = defaultdict(int)
    for c in counts:
        d[c] += 1
    return dict(d)


def state_transition_counts(state, months, count_type="exit", raw=False):

# Path: kardboard/util.py
# def make_start_date(year=None, month=None, day=None, date=None):
#     start_date = munge_date(year, month, day, date)
#     start_date = start_date.replace(hour=23, minute=59, second=59)
#     start_date = start_date.replace(hour=0, minute=0, second=0)
#     return start_date
# 
# def make_end_date(year=None, month=None, day=None, date=None):
#     end_date = munge_date(year, month, day, date)
#     end_date = end_date.replace(hour=23, minute=59, second=59)
#     return end_date
# 
# def average(values):
#     """Computes the arithmetic mean of a list of numbers.
# 
#     >>> print average([20, 30, 70])
#     40.0
#     """
#     try:
#         return stats.mean(values)
#     except ZeroDivisionError:
#         return None
# 
# def median(values):
#     try:
#         return stats.median(values)
#     except (ValueError, UnboundLocalError):
#         return None
# 
# Path: kardboard/models/statelog.py
# class StateLog(app.db.Document):
#     card = app.db.ReferenceField(
#         'Kard',
#         reverse_delete_rule=app.db.CASCADE,
#         required=True,
#         dbref=False,
#     )
#     # Card that this record is about
#     state = app.db.StringField(required=True)
#     # The state the card was in for this record
#     entered = app.db.DateTimeField(required=True)
#     # Datetime the card entered its state
#     exited = app.db.DateTimeField(required=False)
#     # Datetime the card exited this state
#     _duration = app.db.IntField(required=False)
#     # The duration the card was in this state
#     service_class = app.db.StringField(required=False)
#     # The service class the card was in while in this state
# 
#     created_at = app.db.DateTimeField(required=True)
#     updated_at = app.db.DateTimeField(required=True)
# 
#     meta = {
#         'cascade': False,
#         'ordering': ['-created_at'],
#         'indexes': ['card', 'state', ['card', 'created_at']]
#     }
# 
#     def save(self, *args, **kwargs):
#         if self.id is None:
#             self.created_at = now()
#         if self.entered and self.exited:
#             self._duration = self.duration
#         self.updated_at = now()
#         super(StateLog, self).save(*args, **kwargs)
# 
#     def __repr__(self):
#         return "<StateLog: %s, %s, %s -- %s, %s hours>" % (
#             self.card.key,
#             self.state,
#             self.entered,
#             self.exited,
#             self._duration
#         )
# 
#     @classmethod
#     def kard_pre_save(cls, sender, document, **kwargs):
#         observed_card = document
# 
#         if observed_card.state_changing is False:
#             # No need to worry about logging it, nothing's changing!
#             return None
# 
#         try:
#             observed_card.old_state
#         except AttributeError:
#             raise
# 
#         # If you're here it's because the observed_card's state is changing
#         if observed_card.old_state is not None:
#             try:
#                 slos = cls.objects.filter(
#                     card=observed_card,
#                     state=observed_card.old_state,
#                     service_class=observed_card.service_class.get('name'),
#                     exited__exists=False)
#                 for s in slos:
#                     s.exited = now()
#                     s.save()  # Close the old state log
#             except cls.DoesNotExist:
#                 #  For some reason we didn't record the old state, this should only happen when first rolled out
#                 pass
# 
#     @classmethod
#     def kard_post_save(cls, sender, document, **kwargs):
#         observed_card = document
# 
#         # Is there a currently open state log
#         logs = cls.objects.filter(
#             card=observed_card,
#             state=observed_card.state,
#             exited__exists=False,
#         ).order_by('-entered')
#         if len(logs) == 0:
#             sl = cls(
#                 card=observed_card,
#                 state=observed_card.state,
#                 entered=now()
#             )
#         else:
#             sl = logs[0]
# 
#         sl.service_class = observed_card.service_class.get('name')
#         sl.save()
# 
#     @property
#     def duration(self):
#         if self._duration is not None:
#             return self._duration
# 
#         if self.exited is not None:
#             exited = self.exited
#         else:
#             exited = now()
#         delta = exited - self.entered
#         return delta_in_hours(delta)


# Path: bin/state-exit-count.py
import datetime
    import sys
from collections import defaultdict
from dateutil.relativedelta import relativedelta
from kardboard.util import make_start_date, make_end_date, average, median
from kardboard.models.statelog import StateLog





def histogram(counts):
    d = defaultdict(int)
    for c in counts:
        d[c] += 1
    return dict(d)


def state_transition_counts(state, months, count_type="exit", raw=False):

    end = make_end_date(date=datetime.datetime.now())