docs: def punchcard(self, branch='master', limit=None, days=None, by=None, normalize=None, ignore_globs=None,
                    include_globs=None):
          """
          Returns a pandas DataFrame containing all of the data for a punchcard.
  
           * day_of_week
           * hour_of_day
           * author / committer
           * lines
           * insertions
           * deletions
           * net
  
          :param branch: the branch to return commits for
          :param limit: (optional, default=None) a maximum number of commits to return, None for no limit
          :param days: (optional, default=None) number of days to return, if limit is None
          :param by: (optional, default=None) agg by options, None for no aggregation (just a high level punchcard), or 'committer', 'author'
          :param normalize: (optional, default=None) if an integer, returns the data normalized to max value of that (for plotting)
          :param ignore_globs: (optional, default=None) a list of globs to ignore, default none excludes nothing
          :param include_globs: (optinal, default=None) a list of globs to include, default of None includes everything.
          :return: DataFrame
          """
  
          ch = self.commit_history(
              branch=branch,
              limit=limit,
              days=days,
              ignore_globs=ignore_globs,
              include_globs=include_globs
          )
  
          # add in the date fields
          ch['day_of_week'] = ch.index.map(lambda x: x.weekday())
          ch['hour_of_day'] = ch.index.map(lambda x: x.hour)
  
          aggs = ['hour_of_day', 'day_of_week']
          if by is not None:
              aggs.append(by)
  
          punch_card = ch.groupby(aggs).agg({
              'lines': np.sum,
              'insertions': np.sum,
              'deletions': np.sum,
              'net': np.sum
          })
          punch_card.reset_index(inplace=True)
  
          # normalize all cols
          if normalize is not None:
              for col in ['lines', 'insertions', 'deletions', 'net']:
                  punch_card[col] = (punch_card[col] / punch_card[col].sum()) * normalize
  
          return punch_card