openSUSE/trollolo

View on GitHub
scripts/burndowndata.py

Summary

Maintainability
F
5 days
Test Coverage
#!/usr/bin/env python
import yaml


class BurndownData:
  "Store burndown data parsed from YAML file"

  def __init__(self, args):
    self.args = args
    burndown = self.readYAML(self.args.sprint)
    self.getSprintData(burndown)
    self.setBonusTasksDayOne(burndown)
    self.setUnplannedTasksDayOne(burndown)
    self.setExtraDays()
    self.setUnplannedDays()
    self.calculateYRange(self.total_story_points[0], self.bonus_tasks_done, self.bonus_story_points_done, self.unplanned_tasks_done, self.unplanned_story_points_done)
    self.setScaleFactor(self.total_tasks[0], self.total_story_points[0])

  def readYAML(self, sprint_number):
    with open('burndown-data-' + sprint_number + '.yaml', 'r') as f:
      burndown = yaml.load(f)
    return burndown

  def getSprintData(self, burndown):
    self.sprint_number = burndown["meta"]["sprint"]
    self.weekend_lines = burndown["meta"]["weekend_lines"]
    self.total_days = burndown["meta"]["total_days"]
    self.extra_day = 0
    self.unplanned_day = 0
    self.current_day = 1
    self.days = []
    self.tasks_extra_days = []
    self.unplanned_tasks_days = []
    self.story_points_extra_days = []
    self.unplanned_story_points_days = []
    self.open_story_points = []
    self.total_story_points = []
    self.bonus_story_points_done = []
    self.total_unplanned_story_points = []
    self.unplanned_story_points_done = []
    self.open_tasks = []
    self.total_tasks = []
    self.bonus_tasks_done = []
    self.total_unplanned_tasks = []
    self.unplanned_tasks_done = []
    self.x_fast_lane = []
    self.y_fast_lane = []
    self.total_fast_lane = []
    self.total_unplanned_fast_lane = []

    for day in burndown["days"]:
      self.days.append(self.current_day)
      self.open_story_points.append(day["story_points"]["open"])
      self.total_story_points.append(day["story_points"]["total"])
      self.open_tasks.append(day["tasks"]["open"])
      self.total_tasks.append(day["tasks"]["total"])

      if "tasks_extra" in day:
        self.tasks_extra_days.append(self.current_day)
        tasks = -day["tasks_extra"]["done"]
        self.bonus_tasks_done.append(tasks)

      if "story_points_extra" in day:
        self.story_points_extra_days.append(self.current_day)
        points = -day["story_points_extra"]["done"]
        self.bonus_story_points_done.append(points)

      if "unplanned_tasks" in day:
        self.unplanned_tasks_days.append(self.current_day)
        tasks = day["unplanned_tasks"]["open"] - day["unplanned_tasks"]["total"]
        self.unplanned_tasks_done.append(tasks)
        self.total_unplanned_tasks.append(day["unplanned_tasks"]["total"])
      else:
        self.total_unplanned_tasks.append(0)

      if "unplanned_story_points" in day:
        self.unplanned_story_points_days.append(self.current_day)
        points = day["unplanned_story_points"]["open"] - day["unplanned_story_points"]["total"]
        self.unplanned_story_points_done.append(points)
        self.total_unplanned_story_points.append(day["unplanned_story_points"]["total"])
      else:
        self.total_unplanned_story_points.append(0)

      if day.has_key("fast_lane"):
        self.x_fast_lane.append(self.current_day)
        self.y_fast_lane.append(day["fast_lane"]["open"])
        self.total_fast_lane.append(day["fast_lane"]["total"])
        self.total_unplanned_fast_lane.append(0)

      self.current_day += 1
    return

  def setBonusTasksDayOne(self, burndown):
    if burndown["days"][0].has_key("tasks_extra"):
      self.bonus_tasks_day_one = burndown["days"][0]["tasks_extra"]["done"]
    else:
      self.bonus_tasks_day_one = 0
    return

  def setUnplannedTasksDayOne(self, burndown):
    if burndown["days"][0].has_key("unplanned_tasks"):
      self.unplanned_tasks_day_one = burndown["days"][0]["unplanned_tasks"]["total"] - burndown["days"][0]["unplanned_tasks"]["open"]
    else:
      self.unplanned_tasks_day_one = 0
    return

  def setExtraDays(self):
    if len(self.story_points_extra_days) > 0:
      self.story_points_extra_days = [self.story_points_extra_days[0] - 1] + self.story_points_extra_days
      self.bonus_story_points_done = [0] + self.bonus_story_points_done
    if len(self.tasks_extra_days) > 0:
      if not self.args.no_tasks and not self.bonus_tasks_day_one:
        self.tasks_extra_days = [self.tasks_extra_days[0] - 1] + self.tasks_extra_days
        self.bonus_tasks_done = [0] + self.bonus_tasks_done
      self.extra_day = 1
    return

  def setUnplannedDays(self):
    if len(self.unplanned_story_points_days) > 0:
      self.unplanned_story_points_days = [self.unplanned_story_points_days[0] - 1] + self.unplanned_story_points_days
      self.unplanned_story_points_done = [0] + self.unplanned_story_points_done
    if len(self.unplanned_tasks_days) > 0:
      if not self.args.no_tasks and not self.unplanned_tasks_day_one:
        self.unplanned_tasks_days = [self.unplanned_tasks_days[0] - 1] + self.unplanned_tasks_days
        self.unplanned_tasks_done = [0] + self.unplanned_tasks_done
      self.unplanned_day = 1
    return

  def calculateYRange(self, total_story_points, bonus_tasks_done, bonus_story_points_done, unplanned_tasks_done, unplanned_story_points_done):
    self.ymax = total_story_points + 3

    if len(bonus_tasks_done) > 0:
      ymin_bonus_tasks = min(bonus_tasks_done) -3
    else:
      ymin_bonus_tasks = 0

    if len(unplanned_tasks_done) > 0:
      ymin_unplanned_tasks = min(unplanned_tasks_done) -3
    else:
      ymin_unplanned_tasks = 0

    ymin_bonus_story_points = 0

    if len(bonus_story_points_done) > 0:
      ymin_bonus_story_points = min(bonus_story_points_done) -3

    ymin_unplanned_story_points = 0

    if len(unplanned_story_points_done) > 0:
      ymin_unplanned_story_points = min(unplanned_story_points_done) -3

    self.ymin = min(ymin_bonus_tasks, ymin_bonus_story_points, ymin_unplanned_tasks, ymin_unplanned_story_points)
    if self.ymin > -3:
      self.ymin = -3
    return

  def setScaleFactor(self, total_tasks, total_story_points):
    if total_story_points <= 0.001:
      self.scalefactor = 1
    else:
      self.scalefactor = float(total_tasks) / float(total_story_points)
    return