Skip to content

Instantly share code, notes, and snippets.

@jepio
Last active September 30, 2015 09:56
Show Gist options
  • Save jepio/bc2e011fe6ccca60e7a3 to your computer and use it in GitHub Desktop.
Save jepio/bc2e011fe6ccca60e7a3 to your computer and use it in GitHub Desktop.
Print a calendar!
#!/usr/bin/env python3
import itertools as it
import operator as op
from datetime import date, timedelta
import calendar as cal
def dates_in_year(year):
day = timedelta(days=1)
curr = date(year, 1, 1)
last = date(year + 1, 1, 1)
while curr != last:
yield curr
curr = curr + day
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
args = [iter(iterable)] * n
return it.zip_longest(*args, fillvalue=fillvalue)
def peek_first(iterable):
first = next(iterable)
return first, it.chain([first], iterable)
def year_to_months(year):
grouped_months = it.groupby(year, op.attrgetter('month'))
return (month for num_, month in grouped_months)
def month_to_weeks(month):
grouped_weeks = it.groupby(month, lambda d: d.isocalendar()[1])
return (week for _, week in grouped_weeks)
def format_week(week):
first, week = peek_first(week)
day = first.isoweekday()
left_padded = ' ' * 3 * day + ''.join('%3d' % n.day for n in week)
both_padded = left_padded.ljust(24)
return both_padded
def center(width, word):
return word.center(width - 3).rjust(width)
def layout_month(month):
first_day, month = peek_first(month)
month_name = cal.month_name[first_day.month]
centered = center(24, month_name)
weeks = [format_week(week) for week in month_to_weeks(month)]
yield centered
yield from weeks
yield from it.repeat(' ' * 24, 6 - len(weeks))
def layout_months(months):
return (layout_month(m) for m in months)
class Pipe:
def __init__(self, obj):
self.obj = obj
def __or__(self, fun):
self.obj = fun(self.obj)
return self
def __iter__(self):
return self.obj
if __name__ == '__main__':
nice_months = Pipe(2016) | dates_in_year | year_to_months | layout_months
# the usual problem with groups and sharing storage
# probably should move the list somewhere up the chain
for quarter in grouper(map(list, nice_months), 3):
lines = (''.join(x) for x in zip(*quarter))
print('\n'.join(lines))
# vim: set et ts=4 sw=4:
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment