If you work in managing software development, you may have wanted a to automatically generate a calendar for your sprints. I needed to do this at work recently, and think you may find this useful.
Sprints are typically in units of weeks (in other words constant units of duration) instead of months whose durations vary. This makes the starting and ending dates sometimes a bit difficult to deal with because they are not aligned to to the expected days in the month.
Figuring out these dates isn’t very hard using the datetime module. Below is the Python code that finds the dates for 12 sprints each lasting 28 days (4 weeks), starting with January 2, 2012 as the seventh sprint.
---
import datetime
first_sprint_starts_on = datetime.date(2012,1,2)
num_sprints = 12
start_sprint_number = 7
days_in_sprint = 28
for i in xrange(num_sprints) :
sprintnumber = i+start_sprint_number
sprintname = "Sprint %s" % ( sprintnumber )
begin_date = first_sprint_starts_on + datetime.timedelta( i*days_in_sprint )
end_date = begin_date + datetime.timedelta( days = (days_in_sprint-1) )
print sprintname, begin_date, end_date
---
Running this script yields …
---
Sprint 7 2012-01-02 2012-01-29 Sprint 8 2012-01-30 2012-02-26 Sprint 9 2012-02-27 2012-03-25 Sprint 10 2012-03-26 2012-04-22 Sprint 11 2012-04-23 2012-05-20 Sprint 12 2012-05-21 2012-06-17 Sprint 13 2012-06-18 2012-07-15 Sprint 14 2012-07-16 2012-08-12 Sprint 15 2012-08-13 2012-09-09 Sprint 16 2012-09-10 2012-10-07 Sprint 17 2012-10-08 2012-11-04 Sprint 18 2012-11-05 2012-12-02
---
Drawing the Calendar in Visio
Our next task is to draw it in Visio.
---
import clr
import System
import datetime
clr.AddReference("Microsoft.Office.Interop.Visio")
import Microsoft.Office.Interop.Visio
# sprint options
first_sprint_starts_on = datetime.date(2012,1,2)
num_sprints = 12
start_sprint_number = 7
days_in_sprint = 28
# rendering options
sprint_height = 1.0
sprint_width = 2.0
margin = 0.5
draw_vertical = True
# render based on options
IVisio = Microsoft.Office.Interop.Visio
visapp = IVisio.ApplicationClass()
doc = visapp.Documents.Add("")
page = visapp.ActivePage
if (draw_vertical) :
page_width = margin*2 + sprint_width
page_height = margin*2 + (num_sprints *sprint_height)
else :
page_width = margin*2 + (num_sprints *sprint_width)
page_height = margin*2 + sprint_height
page.PageSheet.CellsU["PageWidth"].FormulaU = page_width
page.PageSheet.CellsU["PageHeight"].FormulaU = page_height
for i in xrange(num_sprints) :
sprintnumber = i+start_sprint_number
sprintname = "Sprint %s" % ( sprintnumber )
begin_date = first_sprint_starts_on + datetime.timedelta( i*days_in_sprint )
end_date = begin_date + datetime.timedelta( days = (days_in_sprint-1) )
print sprintname, begin_date, end_date
if (draw_vertical) :
x0 = margin
x1 = margin + sprint_width
y1 = (page_height - margin) - (i*sprint_height)
y0 = y1 - sprint_height
else :
y0 = margin
y1 = margin + sprint_height
x1 = margin + (i*sprint_width)
x0 = x1 + sprint_width
shape = page.DrawRectangle(x0, y0, x1, y1)
sprintlabel = sprintname + "\n" + begin_date.strftime("%m/%d") + " - " + end_date.strftime("%m/%d")
shape.Text = sprintlabel
---
Notice that the rendering options control how the calendar appears. For example, you can control where the calendar draws vertically or horizontally.
The result looks like this for vertical rendering.
And like this for horizontal rendering: