patternpythonMinor
Finding the date from "2nd Friday of X month"-style input
Viewed 0 times
thedateinputfridaystylemonthfindingfrom2nd
Problem
I've been working through some puzzles from exercism.io. Current puzzle asks me to return a
I'm still fairly new to Python, and
Quick note: The "teenth" thing:
Note that "Monteenth", "Tuesteenth", etc are all made up words. There
was a meetup whose members realised that there are exactly 7 days that
end in '-teenth'. Therefore, one is guaranteed that each day of the
week (Monday, Tuesday, ...) will have exactly one date that is named
with '-teenth' in every month.
date() from input that essentially says "The 3rd Friday of December" or "The 1st Monday of October". I'd love to hear some feedback on how to clean this code up:def meetup_day(year, month, weekday, spec_weekday):
import calendar
from datetime import date
last_day = calendar.monthrange(year, month)[1]
wkday = {'Monday': 0, 'Tuesday': 1, 'Wednesday': 2, 'Thursday': 3, 'Friday': 4, 'Saturday': 5, 'Sunday': 6}
schedule_day = wkday[weekday]
if spec_weekday == "teenth":
check_range = range(13, 20)
elif spec_weekday == "last":
check_range = range(last_day - 6, last_day + 1)
else:
spec_weekday = int(spec_weekday[0:1])
check_range = range(7 * spec_weekday - 6, 7 * spec_weekday + 1)
for index in check_range:
if index > last_day:
break
if schedule_day == calendar.weekday(year, month, index):
schedule_day = index
return date(year, month, schedule_day)
meetup_day(2014, 3, "Friday", "2nd")
meetup_day(2013, 6, "Wednesday", "4th")
meetup_day(2013, 12, "Monday", "1st")
meetup_day(2015, 5, "Tuesday", "teenth")
meetup_day(2015, 4, "Thursday", "last")I'm still fairly new to Python, and
datetime stuff throws me through a loop. I chose to use calendar as well as date because I thought the syntax was easier to understand. However, I'm definitely open to ideas on more efficient ways to do this.Quick note: The "teenth" thing:
Note that "Monteenth", "Tuesteenth", etc are all made up words. There
was a meetup whose members realised that there are exactly 7 days that
end in '-teenth'. Therefore, one is guaranteed that each day of the
week (Monday, Tuesday, ...) will have exactly one date that is named
with '-teenth' in every month.
Solution
Your code is pretty clear but can be improved using builtin capabilities of
Python related remarks:
calendar: the monthcalendar method return a list of list representing each week of the selected month (zeroes are days that are not in the month). By filtering these weeks using the index of the day you are looking for, you get all the possible day of the month that are the requested day. You can then just pick the right one into this list.Python related remarks:
- Put your import at the beginning of the file, not into functions. It will slow you down if you are heavily calling functions that contain import statements;
wkdayis a constant and must be declared as such: outside of the function and with proper case;
- there is no really need to make
wkdaya dictionary given that you can get the same information it holds using.indexon a list;
- [optional] depending on your needs, you may want to perform proper input validations.
import calendar
from datetime import date
DAY_NAMES = [day for day in calendar.day_name]
def meetup_day(year, month, weekday, spec_weekday):
day_index = DAY_NAMES.index(weekday)
possible_dates = [
week[day_index]
for week in calendar.monthcalendar(year, month)
if week[day_index]] # remove zeroes
if spec_weekday == 'teenth':
for day_num in possible_dates:
if 13 <= day_num <= 19:
return date(year, month, day_num)
elif spec_weekday == 'last':
day_index = -1
elif spec_weekday == 'first':
day_index = 0
else:
day_index = int(spec_weekday[0]) - 1
return date(year, month, possible_dates[day_index])
meetup_day(2014, 3, "Friday", "2nd")
meetup_day(2013, 6, "Wednesday", "4th")
meetup_day(2013, 12, "Monday", "1st")
meetup_day(2015, 5, "Tuesday", "teenth")
meetup_day(2015, 4, "Thursday", "last")Code Snippets
import calendar
from datetime import date
DAY_NAMES = [day for day in calendar.day_name]
def meetup_day(year, month, weekday, spec_weekday):
day_index = DAY_NAMES.index(weekday)
possible_dates = [
week[day_index]
for week in calendar.monthcalendar(year, month)
if week[day_index]] # remove zeroes
if spec_weekday == 'teenth':
for day_num in possible_dates:
if 13 <= day_num <= 19:
return date(year, month, day_num)
elif spec_weekday == 'last':
day_index = -1
elif spec_weekday == 'first':
day_index = 0
else:
day_index = int(spec_weekday[0]) - 1
return date(year, month, possible_dates[day_index])
meetup_day(2014, 3, "Friday", "2nd")
meetup_day(2013, 6, "Wednesday", "4th")
meetup_day(2013, 12, "Monday", "1st")
meetup_day(2015, 5, "Tuesday", "teenth")
meetup_day(2015, 4, "Thursday", "last")Context
StackExchange Code Review Q#108543, answer score: 2
Revisions (0)
No revisions yet.