6 Week Sprint
In [1]:
Copied!
import datetime
import calendar
from collections import Counter
def get_major_month_abbr(week_dates):
"""Returns the abbreviation of the month with >= 3 workdays (Mon-Fri) in the week."""
workday_months = [d.month for d in week_dates[1:6]] # Mon to Fri
month_counts = Counter(workday_months)
# Find month with 3+ workdays, default to Wednesday's month if none exists
major_month_num = next((month for month, count in month_counts.items() if count >= 3), week_dates[3].month)
return calendar.month_abbr[major_month_num]
def generate_and_print_calendar(year):
"""Generates and prints a 52-week custom calendar (1+6+6 structure) for the year."""
jan_1 = datetime.date(year, 1, 1)
start_date = jan_1 - datetime.timedelta(days=(jan_1.weekday() + 1) % 7) # Sunday of Jan 1st's week
current_date = start_date
col_w = {"label": 12, "month": 5, "day": 4}
total_width = col_w["label"] + col_w["month"] + 7 * col_w["day"] + 8 # Account for spaces
# Print Header
header_parts = [
f"{'SPRINT':<{col_w['label']}}",
f"{'MONTH':<{col_w['month']}}",
] + [f"{day:<{col_w['day']}}" for day in ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]]
print(" ".join(header_parts))
print("-" * total_width)
for week_idx in range(52):
q_num = (week_idx // 13) + 1
w_in_q = week_idx % 13 # Week index within quarter (0-12)
# Determine week label components
if w_in_q == 0:
block_type, block_week_num_str = 'P', ''
week_label = f"Q{q_num} Planning"
else:
if 1 <= w_in_q <= 6:
block_type, block_week_num_str = 'a', str(w_in_q)
else: # 7 <= w_in_q <= 12
block_type, block_week_num_str = 'b', str(w_in_q - 6)
week_label = f"Q{q_num}{block_type} Week {block_week_num_str}"
week_dates = [current_date + datetime.timedelta(days=i) for i in range(7)]
major_month = get_major_month_abbr(week_dates)
day_strs = [calendar.month_abbr[d.month] if d.day == 1 else str(d.day) for d in week_dates]
# Print week row
row_parts = [
f"{week_label:<{col_w['label']}}",
f"{major_month:<{col_w['month']}}",
] + [f"{day:<{col_w['day']}}" for day in day_strs]
print(" ".join(row_parts))
# Print separator line after P, A6, B6 blocks
if w_in_q in [0, 6, 12] and week_idx < 51:
print("-" * total_width)
current_date += datetime.timedelta(weeks=1)
# --- Generate and Print the Calendar for 2025 ---
generate_and_print_calendar(2025)
import datetime
import calendar
from collections import Counter
def get_major_month_abbr(week_dates):
"""Returns the abbreviation of the month with >= 3 workdays (Mon-Fri) in the week."""
workday_months = [d.month for d in week_dates[1:6]] # Mon to Fri
month_counts = Counter(workday_months)
# Find month with 3+ workdays, default to Wednesday's month if none exists
major_month_num = next((month for month, count in month_counts.items() if count >= 3), week_dates[3].month)
return calendar.month_abbr[major_month_num]
def generate_and_print_calendar(year):
"""Generates and prints a 52-week custom calendar (1+6+6 structure) for the year."""
jan_1 = datetime.date(year, 1, 1)
start_date = jan_1 - datetime.timedelta(days=(jan_1.weekday() + 1) % 7) # Sunday of Jan 1st's week
current_date = start_date
col_w = {"label": 12, "month": 5, "day": 4}
total_width = col_w["label"] + col_w["month"] + 7 * col_w["day"] + 8 # Account for spaces
# Print Header
header_parts = [
f"{'SPRINT':<{col_w['label']}}",
f"{'MONTH':<{col_w['month']}}",
] + [f"{day:<{col_w['day']}}" for day in ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]]
print(" ".join(header_parts))
print("-" * total_width)
for week_idx in range(52):
q_num = (week_idx // 13) + 1
w_in_q = week_idx % 13 # Week index within quarter (0-12)
# Determine week label components
if w_in_q == 0:
block_type, block_week_num_str = 'P', ''
week_label = f"Q{q_num} Planning"
else:
if 1 <= w_in_q <= 6:
block_type, block_week_num_str = 'a', str(w_in_q)
else: # 7 <= w_in_q <= 12
block_type, block_week_num_str = 'b', str(w_in_q - 6)
week_label = f"Q{q_num}{block_type} Week {block_week_num_str}"
week_dates = [current_date + datetime.timedelta(days=i) for i in range(7)]
major_month = get_major_month_abbr(week_dates)
day_strs = [calendar.month_abbr[d.month] if d.day == 1 else str(d.day) for d in week_dates]
# Print week row
row_parts = [
f"{week_label:<{col_w['label']}}",
f"{major_month:<{col_w['month']}}",
] + [f"{day:<{col_w['day']}}" for day in day_strs]
print(" ".join(row_parts))
# Print separator line after P, A6, B6 blocks
if w_in_q in [0, 6, 12] and week_idx < 51:
print("-" * total_width)
current_date += datetime.timedelta(weeks=1)
# --- Generate and Print the Calendar for 2025 ---
generate_and_print_calendar(2025)
SPRINT MONTH Sun Mon Tue Wed Thu Fri Sat ----------------------------------------------------- Q1 Planning Jan 29 30 31 Jan 2 3 4 ----------------------------------------------------- Q1a Week 1 Jan 5 6 7 8 9 10 11 Q1a Week 2 Jan 12 13 14 15 16 17 18 Q1a Week 3 Jan 19 20 21 22 23 24 25 Q1a Week 4 Jan 26 27 28 29 30 31 Feb Q1a Week 5 Feb 2 3 4 5 6 7 8 Q1a Week 6 Feb 9 10 11 12 13 14 15 ----------------------------------------------------- Q1b Week 1 Feb 16 17 18 19 20 21 22 Q1b Week 2 Feb 23 24 25 26 27 28 Mar Q1b Week 3 Mar 2 3 4 5 6 7 8 Q1b Week 4 Mar 9 10 11 12 13 14 15 Q1b Week 5 Mar 16 17 18 19 20 21 22 Q1b Week 6 Mar 23 24 25 26 27 28 29 ----------------------------------------------------- Q2 Planning Apr 30 31 Apr 2 3 4 5 ----------------------------------------------------- Q2a Week 1 Apr 6 7 8 9 10 11 12 Q2a Week 2 Apr 13 14 15 16 17 18 19 Q2a Week 3 Apr 20 21 22 23 24 25 26 Q2a Week 4 Apr 27 28 29 30 May 2 3 Q2a Week 5 May 4 5 6 7 8 9 10 Q2a Week 6 May 11 12 13 14 15 16 17 ----------------------------------------------------- Q2b Week 1 May 18 19 20 21 22 23 24 Q2b Week 2 May 25 26 27 28 29 30 31 Q2b Week 3 Jun Jun 2 3 4 5 6 7 Q2b Week 4 Jun 8 9 10 11 12 13 14 Q2b Week 5 Jun 15 16 17 18 19 20 21 Q2b Week 6 Jun 22 23 24 25 26 27 28 ----------------------------------------------------- Q3 Planning Jul 29 30 Jul 2 3 4 5 ----------------------------------------------------- Q3a Week 1 Jul 6 7 8 9 10 11 12 Q3a Week 2 Jul 13 14 15 16 17 18 19 Q3a Week 3 Jul 20 21 22 23 24 25 26 Q3a Week 4 Jul 27 28 29 30 31 Aug 2 Q3a Week 5 Aug 3 4 5 6 7 8 9 Q3a Week 6 Aug 10 11 12 13 14 15 16 ----------------------------------------------------- Q3b Week 1 Aug 17 18 19 20 21 22 23 Q3b Week 2 Aug 24 25 26 27 28 29 30 Q3b Week 3 Sep 31 Sep 2 3 4 5 6 Q3b Week 4 Sep 7 8 9 10 11 12 13 Q3b Week 5 Sep 14 15 16 17 18 19 20 Q3b Week 6 Sep 21 22 23 24 25 26 27 ----------------------------------------------------- Q4 Planning Oct 28 29 30 Oct 2 3 4 ----------------------------------------------------- Q4a Week 1 Oct 5 6 7 8 9 10 11 Q4a Week 2 Oct 12 13 14 15 16 17 18 Q4a Week 3 Oct 19 20 21 22 23 24 25 Q4a Week 4 Oct 26 27 28 29 30 31 Nov Q4a Week 5 Nov 2 3 4 5 6 7 8 Q4a Week 6 Nov 9 10 11 12 13 14 15 ----------------------------------------------------- Q4b Week 1 Nov 16 17 18 19 20 21 22 Q4b Week 2 Nov 23 24 25 26 27 28 29 Q4b Week 3 Dec 30 Dec 2 3 4 5 6 Q4b Week 4 Dec 7 8 9 10 11 12 13 Q4b Week 5 Dec 14 15 16 17 18 19 20 Q4b Week 6 Dec 21 22 23 24 25 26 27
In [ ]:
Copied!