Here are my notes:
1st ___day
1-7
1 day before: 28-6 (1-6, 28-31)
2 days before: 27-5 (1-5, 27-31)
3 days before: 26-4 (1-4, 26-31)
etc
2nd ___day
8-14
1 day before: 7-13
2 days before: 6-12
3 days before: 5-11
3rd ___day
15-21
1 day before: 14-20
2 days before: 13-19
3 days before: 12-18
4th ___day
22-28
1 day before: 21-27
2 days before: 20-26
3 days before: 19-25
5th ___day
29-31
1 day before: 28-30
2 days before: 27-29
3 days before: 26-28
# INPUT
# day: which day of the week car must be moved (0 - 6 = Mon - Sun)
# n: which ___day car must be moved (1 - 5 = 1st, 2nd, 3rd, 4th, 5th)
# days_before: how many days before to notify
#
# OUTPUT
# notice_day: which day of the week to notify
# start_date: start of range of possible dates (inclusive)
# end_date: end of range possible dates (inclusive)
def get_date_range(n, day, days_before):
start_date = ((n - 1) * 7) + 1 # Start date for range for nth ___day
start_date = start_date - days_before
if start_date < 0:
start_date = (start_date % 28) + 1 # % 28 to account for all months including shortest
end_date = n * 7 # End date for range for nth ___day
end_date = end_date - days_before
if end_date < 0:
end_date = (end_date % 28) + 1
notice_day = (day - days_before) % 7
return (notice_day, start_date, end_date)
# Notify on day of the week notice_day between dates start_date and end_date
# note that if start_date > end_date, we must use two ranges: end_date-31 and 1-start_date
i'm going to add your recent python logic to these notes as more to
reference:
#!/usr/bin/env python3
from sys import argv
# USAGE
# dates.py week day days_before
if len(argv) != 4 or \
int(argv[1]) < 1 or int(argv[1]) > 5 or \
int(argv[2]) < 0 or int(argv[2]) > 6 or \
int(argv[3]) < 0:
print('USAGE: days.py week day days_before')
print(' week: number of the week car must be moved; must be 1-5')
print(' day: number of the day car must be moved; 0-6 = Mon-Sun')
print(' days_before: how many days before car must be moved to send notification; must be > 0')
print('EXAMPLE - to notify 3 days before the 2nd Tuesday: days.py 2 1 3')
exit()
# INPUT
# day: which day of the week car must be moved (0 - 6 = Mon - Sun)
# week: which week car must be moved (1 - 5 = 1st, 2nd, 3rd, 4th, 5th)
# days_before: how many days before to notify
#
# OUTPUT
# notice_day: which day of the week to notify
# start_date: start of range of possible dates (inclusive)
# end_date: end of range possible dates (inclusive)
def get_date_range(week, day, days_before):
start_date = ((week - 1) * 7) + 1 # Start date for range for nth ___day
start_date = start_date - days_before
if start_date <= 0:
start_date = ((start_date - 1) % 28) + 1 # % 28 to account for all months including shortest
end_date = week * 7 # End date for range for nth ___day
end_date = end_date - days_before
if end_date <= 0:
end_date = ((end_date - 1) % 28) + 1
notice_day = (day - days_before) % 7
return (notice_day, start_date, end_date)
# Notify on day of the week notice_day between dates start_date and end_date
# note that if start_date > end_date, we must use two ranges: end_date-31 and 1-start_date
def number_suffix(n):
if n % 100 in [11, 12, 13]:
return 'th'
elif n % 10 in [1, 2, 3]:
return ['st', 'nd', 'rd'][(n % 10) - 1]
else:
return 'th'
week = int(argv[1])
day = int(argv[2])
days_before = int(argv[3])
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
print('Street cleaning is on the', str(week) + number_suffix(week), days[day],
'of the month.')
start = ((week - 1) * 7) + 1
end = week * 7
print('This will fall between the', str(start) + number_suffix(start), 'and',
str(end) + number_suffix(end), 'of the month.')
date_range = get_date_range(week, day, days_before)
print('In order to notify', days_before, ('day' if days_before == 1 else 'days'),
'in advance, you will need to send an email on a', days[date_range[0]],
'between the', str(date_range[1]) + number_suffix(date_range[1]), 'and',
str(date_range[2]) + number_suffix(date_range[2]), 'of the month.')
i think it will be worth considering how much we want to stick to
writing precise cronjobs that will run the script only when necessary,
vs a cronjob that runs as frequently as reasonably possible.
i recall from another brainstorming session of ours that you suggested
having a configuration based approach.
i like that idea.
if we opt for sending notifications whenever a user likes, (email for
starters, push notifications can be implemented later), how do you think
we should format that configuration file?
i was thinking if the user specific config file states when they want to
receive notifications however fancily we implement it (e.g. the thursday
before the second tuesday of the month), along with their preferred
message content and subject, priority (e.g. urgent), we can have a
cronjob that runs and checks each user's config file and sends out
notifications based off of that.
what says you?