This is the coding challenge for the Central Ohio Python Users Group for March 2016.
Building on last month's challenge, this month's challenge will involve figuring out dates.
This challenge has three parts. Each part builds on the previous part, and feel free to do all the parts or only some. This challenge is for you, so implement it any way you want. Find a new module, or way of implementing that scratches your itches.
Given a month (say February), return a list of dates in that month that the Central Ohio Python Users Group met (in the case of February, it would return 2/22/2010, 2/28/2011, 2/27/2012, 2/25/2013, 2/24/2014, and 2/29/2015.
You can figure out those dates by implementing the following rules:
The first COhPy meeting was September 28, 2009.
COhPy meets the last Monday of the month, with the following exceptions:
COhPy never meets in November.
COhPy meets the first Monday of the month in December EXCEPT when that Monday is the 1st or 2nd of December, when it meets on the SECOND Monday.
In May, to avoid Memorial Day, COhPy meets on the second-to-last Monday of the month.
Given a set of dates (particularly the dates returned in Part One), return the high temperature in Columbus, Ohio at the airport (weather station KCMH) for each of those dates.
Here are a couple of resources to get historical weather observations:
APIs:
CSV and other data:
Based on the data in Part Two (or whatever data you want) predict the high temperature for the next COhPy meetup. Your prediction algorithm will run on meetup day the month prior to the one you are predicting.
At the April 2016 meeting we will run your prediction algorithms, and at the May meetup, the algorithm that most closely predicted the high reported by weather station KCMH for the May meetup will receive a Python ball cap! In the event of a tie, the tied algorithms will face off to predict June (or we'll randomly decide :-)!
Given a month (say February), return a list of dates in that month that the Central Ohio Python Users Group met (in the case of February, it would return 2/22/2010, 2/28/2011, 2/27/2012, 2/25/2013, 2/24/2014, and 2/29/2015.
You can figure out those dates by implementing the following rules:
The first COhPy meeting was September 28, 2009.
COhPy meets the last Monday of the month, with the following exceptions:
COhPy never meets in November.
COhPy meets the first Monday of the month in December EXCEPT when that Monday is the 1st or 2nd of December, when it meets on the SECOND Monday.
In May, to avoid Memorial Day, COhPy meets on the second-to-last Monday of the month.
get_past_cohpy_meeting_dates_of_month() in the cells below is my solution for Part One. There is also some code to demonstrate it.
from __future__ import print_function
import datetime
import calendar
FIRST_MEETING = datetime.date(2009, 9, 28)
FIRST_MEETING
datetime.date(2009, 9, 28)
FIRST_MEETING.year
2009
MONTHS_PER_YEAR = 12
def get_dates_for_weekday(year, month, weekday):
'''Returns list of dates of specified month
that are on specified weekday.
Dates are in ascending order.
'''
c = calendar.Calendar()
return [
day_of_month
for day_of_month, day_of_week in c.itermonthdays2(year, month)
if day_of_month and day_of_week == weekday]
assert get_dates_for_weekday(2016, 4, calendar.MONDAY) == [4, 11, 18, 25]
get_dates_for_weekday(2016, 4, calendar.MONDAY)
[4, 11, 18, 25]
def get_cohpy_meeting_date(year, month):
'''Returns date of specified cohpy meeting as datetime.date object
or None if there is no COhPy meeting that month.'''
month_name = calendar.month_name[month]
if month_name == 'November':
return None # COhPy does not meet in November.
mondays = get_dates_for_weekday(year, month, calendar.MONDAY)
if month_name == 'December':
date = mondays[0]
if date <= 2:
date = mondays[1]
return date
elif month_name == 'May':
return mondays[-2]
else:
return mondays[-1]
def get_cohpy_meeting_dates_of_month(month, min_date, max_date):
'''Returns generator of datetime.date objects for
dates of COhPy meetings in specified month
between min_date and max_date inclusive.'''
for year in range(min_date.year, max_date.year + 1):
date_of_month = get_cohpy_meeting_date(year, month)
if not date_of_month:
continue
date = datetime.date(year, month, date_of_month)
if min_date <= date <= max_date:
yield date
today = datetime.date.today()
day_before_today = today - datetime.timedelta(days=1)
today, day_before_today
(datetime.date(2016, 4, 25), datetime.date(2016, 4, 24))
for d in get_cohpy_meeting_dates_of_month(2, FIRST_MEETING, day_before_today):
print(d)
2010-02-22 2011-02-28 2012-02-27 2013-02-25 2014-02-24 2015-02-23 2016-02-29
# Demonstrate that get_past_cohpy_meeting_dates_of_month() works.
for month in range(1, MONTHS_PER_YEAR + 1):
month_name = calendar.month_name[month]
dates = list(get_cohpy_meeting_dates_of_month(month, FIRST_MEETING, day_before_today))
if dates:
print('Meetings in %s before %s:' % (month_name, today))
for date in dates:
print(' %s' % date)
else:
print('No meetings in %s before %s.' % (month_name, today))
Meetings in January before 2016-04-25: 2010-01-25 2011-01-31 2012-01-30 2013-01-28 2014-01-27 2015-01-26 2016-01-25 Meetings in February before 2016-04-25: 2010-02-22 2011-02-28 2012-02-27 2013-02-25 2014-02-24 2015-02-23 2016-02-29 Meetings in March before 2016-04-25: 2010-03-29 2011-03-28 2012-03-26 2013-03-25 2014-03-31 2015-03-30 2016-03-28 Meetings in April before 2016-04-25: 2010-04-26 2011-04-25 2012-04-30 2013-04-29 2014-04-28 2015-04-27 Meetings in May before 2016-04-25: 2010-05-24 2011-05-23 2012-05-21 2013-05-20 2014-05-19 2015-05-18 Meetings in June before 2016-04-25: 2010-06-28 2011-06-27 2012-06-25 2013-06-24 2014-06-30 2015-06-29 Meetings in July before 2016-04-25: 2010-07-26 2011-07-25 2012-07-30 2013-07-29 2014-07-28 2015-07-27 Meetings in August before 2016-04-25: 2010-08-30 2011-08-29 2012-08-27 2013-08-26 2014-08-25 2015-08-31 Meetings in September before 2016-04-25: 2009-09-28 2010-09-27 2011-09-26 2012-09-24 2013-09-30 2014-09-29 2015-09-28 Meetings in October before 2016-04-25: 2009-10-26 2010-10-25 2011-10-31 2012-10-29 2013-10-28 2014-10-27 2015-10-26 No meetings in November before 2016-04-25. Meetings in December before 2016-04-25: 2009-12-07 2010-12-06 2011-12-05 2012-12-03 2013-12-09 2014-12-08 2015-12-07