10 lines of code to implement a duty alert application

In my work, I often encounter application scenarios where team members need to be on duty, schedule and remind. While there are some apps available, they can be cumbersome for programmers to use and may not be flexible.

So, how do we hand lift a simple duty scheduling and remind the application?

Consider a simple case where the constraint is assumed as follows:

  • The duty order is fixed and will not be modified once it is determined
  • Each person is assigned a fixed number of hours, eg: each person is assigned a week

The demand assumption is as follows:

  • Remind the watchman of the time when it is appropriate
  • Alert the watchman and warn the next watchman

Constraints and requirements are translated into code as follows:


on_duty_list = [Sun Wukong.'Sand Monk'.'Pig Eight Quit'.'White Horse'] List of people on duty
on_duty_period_in_days = 7 # Each person is worth one week
notify_days = [1.5] # Assume that the first day of duty is reminded, and the fifth day is reminded again
Start time of first person on duty
on_duty_first_person = Sun Wukong
on_duty_first_day = '2022-03-24 00:00:00'
Alert message template
notify_template = Template(R "" "" = = = = = = = = = = = the police on duty to remind the = = = = = = = = "${on_duty_person_this_week} this week the watch 】 【 】 【 on duty time ${on_duty_range} ${on_duty_person_next_week} """)
Copy the code

How to use the program to calculate which person should be on duty at the current time?

Simple math is used here: divisible, mod

The time difference between the current time and the start time of the first person on duty is divided by 7 days to get the number of weeks, and then the total number of people on duty is taken to get the number of people on duty.

def WhoIsOnDuty(timeTs = int(time.time())) :
    ref_timeTs = UnixTimeFromDate(on_duty_first_day)
    deltaTs = timeTs - ref_timeTs
    deltaDay = deltaTs / oneDayTs
    index = deltaDay / on_duty_period_in_days % len(on_duty_list)
    return on_duty_list[index]
Copy the code

How do you calculate the time range?

This involves simple date calculations, using the DateTime library

def WhoIsOnDuty(timeTs = int(time.time())) :
    ref_timeTs = UnixTimeFromDate(on_duty_first_day)
    deltaTs = timeTs - ref_timeTs
    deltaDay = deltaTs / oneDayTs
    index = deltaDay / on_duty_period_in_days % len(on_duty_list)
    day_index = deltaDay % on_duty_period_in_days
    ts = time.localtime(timeTs)
    start_day = str(datetime.date(ts.tm_year, ts.tm_mon, ts.tm_mday) + datetime.timedelta(days = -day_index))
    end_day = str(datetime.date(ts.tm_year, ts.tm_mon, ts.tm_mday) + datetime.timedelta(days = - day_index + on_duty_period_in_days - 1))
    return on_duty_list[index], day_index + 1, start_day, end_day, on_duty_list[(index+1) %len(on_duty_list)]
Copy the code

These 10 lines of code are the heart of the application.

The entire application code is as follows:

#! /usr/bin/env python
# coding: utf-8

import time
from string import Template
import datetime

on_duty_list = [Sun Wukong.'Sand Monk'.'Pig Eight Quit'.'White Horse']
on_duty_period_in_days = 7 # day
notify_days = [1.5]
on_duty_first_person = Sun Wukong
on_duty_first_day = 'the 2022-03-24 10:00:00'
oneDayTs = 24 * 60 * 60

notify_template = Template(R "" "" = = = = = = = = = = = the police on duty to remind the = = = = = = = = "${on_duty_person_this_week} this week the watch 】 【 】 【 on duty time ${on_duty_range} ${on_duty_person_next_week} """)

def SendMessage(message='test') :
    print message

def PairListToMessage(pair_list) :
    conent_arr = []
    for k, v in pair_list:
        conent_arr.append(' '.join(['【' + k + '】', v]))
    return '\n'.join(conent_arr)

def UnixTimeFromDate(time_str, format='%Y-%m-%d %H:%M:%S') :
    First convert to time array
    timeArray = time.strptime(time_str, "%Y-%m-%d %H:%M:%S")
    # convert to timestamp
    timeStamp = int(time.mktime(timeArray))
    return timeStamp

def DatetimeStr(timeTs, format='%Y-%m-%d %H:%M:%S') :
    return time.strftime(format, time.localtime(timeTs))

def WhoIsOnDuty(timeTs = int(time.time())) :
    ref_timeTs = UnixTimeFromDate(on_duty_first_day)
    deltaTs = timeTs - ref_timeTs
    deltaDay = deltaTs / oneDayTs
    index = deltaDay / on_duty_period_in_days % len(on_duty_list)
    day_index = deltaDay % on_duty_period_in_days
    ts = time.localtime(timeTs)
    start_day = str(datetime.date(ts.tm_year, ts.tm_mon, ts.tm_mday) + datetime.timedelta(days = -day_index))
    end_day = str(datetime.date(ts.tm_year, ts.tm_mon, ts.tm_mday) + datetime.timedelta(days = - day_index + on_duty_period_in_days - 1))
    return on_duty_list[index], day_index + 1, start_day, end_day, on_duty_list[(index+1) %len(on_duty_list)]


Remind the staff on duty this week and the staff on duty next week
notify_counter = 0
on_duty_person_this_week = ' '
While True:
    timeTs = int(time.time())
    timeStr = DatetimeStr(timeTs)
    on_duty_person, day, start_day, end_day, on_duty_person_next = WhoIsOnDuty(timeTs)
    ifon_duty_person ! = on_duty_person_this_week: on_duty_person_this_week = on_duty_person notify_counter =0
        SendMessage(notify_template.safe_substitute({
            'on_duty_person_this_week': on_duty_person,
            'on_duty_person_next_week': on_duty_person_next,
            'on_duty_range': '~'.join([start_day, end_day]),
        }))
        notify_counter += 1
    else:
        if notify_counter < 2 and day in notify_days:
            SendMessage(notify_template.safe_substitute({
                'on_duty_person_this_week': on_duty_person,
                'on_duty_person_next_week': on_duty_person_next,
                'on_duty_range': '~'.join([start_day, end_day]),
            }))
            notify_counter += 1
    time.sleep(1)
Copy the code

The effect is as follows:

Here leave a question to the reader, welcome to comment section exchange.

  • How to realize the function of temporary shift?
  • Call the third party API implementation such as public number remind, SMS remind, etc

If you find this article helpful, you can follow it on our wechat official account: Small but Beautiful Python for more fresh articles.