Last active
September 30, 2015 09:56
-
-
Save jepio/bc2e011fe6ccca60e7a3 to your computer and use it in GitHub Desktop.
Print a calendar!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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