def demand(self, from_date, to_date, types=None): """ Return the number of issues created each week - i.e. the demand on the system """ if self.work_items is None: self.work_items = self.source.work_items() details = [] for work_item in self.work_items: detail = work_item.detail() detail['count'] = 1 # Need to figure out where to put this # resolution_date_str = f.resolutiondate # if resolution_date_str is not None: # resolution_date = datetime.strptime(resolution_date_str[:10], # '%Y-%m-%d') # week = week_start_date(resolution_date.isocalendar()[0], # resolution_date.isocalendar()[1]).strftime('%Y-%m-%d') # else: # week = None detail['week_created'] = week_start_date( detail['date_created'].isocalendar()[0], detail['date_created'].isocalendar()[1]).strftime('%Y-%m-%d') include = True swimlane = work_item.category if types is not None and self.types is not None: include = False for type_grouping in types: if work_item.type in self.types[type_grouping]: swimlane = swimlane + '-' + type_grouping include = True detail['swimlane'] = swimlane if include: details.append(detail) df = pd.DataFrame(details) table = pd.tools.pivot.pivot_table(df, rows=['week_created'], cols=['swimlane'], values='count', aggfunc=np.count_nonzero) reindexed = table.reindex(index=fill_date_index_blanks(table.index), fill_value=np.int64(0)) reindexed.index.name = "week" return reindexed
def demand(self, from_date, to_date, types=None): """ Return the number of issues created each week - i.e. the demand on the system """ if self.work_items is None: self.work_items = self.source.work_items() details = [] for work_item in self.work_items: detail = work_item.detail() detail['count'] = 1 # Need to figure out where to put this # resolution_date_str = f.resolutiondate # if resolution_date_str is not None: # resolution_date = datetime.strptime(resolution_date_str[:10], # '%Y-%m-%d') # week = week_start_date(resolution_date.isocalendar()[0], # resolution_date.isocalendar()[1]).strftime('%Y-%m-%d') # else: # week = None detail['week_created'] = week_start_date(detail['date_created'].isocalendar()[0], detail['date_created'].isocalendar()[1]).strftime('%Y-%m-%d') include = True swimlane = work_item.category if types is not None and self.types is not None: include = False for type_grouping in types: if work_item.type in self.types[type_grouping]: swimlane = swimlane + '-' + type_grouping include = True detail['swimlane'] = swimlane if include: details.append(detail) df = pd.DataFrame(details) table = pd.tools.pivot.pivot_table(df, rows=['week_created'], cols=['swimlane'], values='count', aggfunc=np.count_nonzero) reindexed = table.reindex(index=fill_date_index_blanks(table.index), fill_value=np.int64(0)) reindexed.index.name = "week" return reindexed
def _issues_as_rows(self, issues, types=None): """ Get issues into a state where we can stick them into a Pandas dataframe """ # TODO: Decide if this should be a class / helper method? # TODO: See if has any overlap with throughput function issue_rows = [] for issue in issues: f = issue.fields resolution_date_str = f.resolutiondate if resolution_date_str is not None: resolution_date = datetime.strptime(resolution_date_str[:10], '%Y-%m-%d') week = week_start_date(resolution_date.isocalendar()[0], resolution_date.isocalendar()[1]).strftime('%Y-%m-%d') else: week = None date_created = datetime.strptime(f.created[:10], '%Y-%m-%d') week_created = week_start_date(date_created.isocalendar()[0], date_created.isocalendar()[1]).strftime('%Y-%m-%d') if issue.changelog is not None: tis = time_in_states(issue.changelog.histories, datetime.strptime(f.created[:10], '%Y-%m-%d'), date.today()) since = tis[-1]['days'] else: since = None include = True # TODO: This looks like a bit of a hack. # Can we do without iterating over loop, seeing as we # only ever want one swimlane/category combination? swimlane = issue.category if types is not None and self.types is not None: include = False for type_grouping in types: if f.issuetype.name in self.types[type_grouping]: swimlane = swimlane + '-' + type_grouping include = True if include: try: story_points = f.customfield_10002 except AttributeError: story_points = None try: epic_link = f.customfield_10200 except AttributeError: epic_link = None # TODO: Fields need to come out of config too. issue_row = {'swimlane': swimlane, 'type': f.issuetype.name, 'id': issue.key, 'name': f.summary, 'status': f.status.name, 'project': f.project.name, 'components': None, 'week': week, 'since': since, 'created': f.created, 'week_created': week_created, 'story_points': story_points, 'epic_link': epic_link, 'count': 1} for cycle in self.cycles: try: issue_row[cycle] = getattr(issue, cycle) except AttributeError: pass components = [] for component in f.components: components.append(component.name) issue_row['components'] = ",".join(components) issue_rows.append(issue_row) return issue_rows
def _issues_as_rows(self, issues, types=None): """ Get issues into a state where we can stick them into a Pandas dataframe """ # TODO: Decide if this should be a class / helper method? # TODO: See if has any overlap with throughput function issue_rows = [] for issue in issues: f = issue.fields resolution_date_str = f.resolutiondate if resolution_date_str is not None: resolution_date = datetime.strptime(resolution_date_str[:10], '%Y-%m-%d') week = week_start_date( resolution_date.isocalendar()[0], resolution_date.isocalendar()[1]).strftime('%Y-%m-%d') else: week = None date_created = datetime.strptime(f.created[:10], '%Y-%m-%d') week_created = week_start_date( date_created.isocalendar()[0], date_created.isocalendar()[1]).strftime('%Y-%m-%d') if issue.changelog is not None: tis = time_in_states( issue.changelog.histories, datetime.strptime(f.created[:10], '%Y-%m-%d'), date.today()) since = tis[-1]['days'] else: since = None include = True # TODO: This looks like a bit of a hack. # Can we do without iterating over loop, seeing as we # only ever want one swimlane/category combination? swimlane = issue.category if types is not None and self.types is not None: include = False for type_grouping in types: if f.issuetype.name in self.types[type_grouping]: swimlane = swimlane + '-' + type_grouping include = True if include: try: story_points = f.customfield_10002 except AttributeError: story_points = None try: epic_link = f.customfield_10200 except AttributeError: epic_link = None # TODO: Fields need to come out of config too. issue_row = { 'swimlane': swimlane, 'type': f.issuetype.name, 'id': issue.key, 'name': f.summary, 'status': f.status.name, 'project': f.project.name, 'components': None, 'week': week, 'since': since, 'created': f.created, 'week_created': week_created, 'story_points': story_points, 'epic_link': epic_link, 'count': 1 } for cycle in self.cycles: try: issue_row[cycle] = getattr(issue, cycle) except AttributeError: pass components = [] for component in f.components: components.append(component.name) issue_row['components'] = ",".join(components) issue_rows.append(issue_row) return issue_rows