10行代码实现一个值班提醒应用(代码片段)

简信君 简信君     2022-10-21     567

关键词:

10行代码实现一个值班提醒应用

工作当中,经常遇到团队成员需要值班排班及提醒的应用场景。虽然,有一些现成的APP可以用,但是对程序员来讲使用起来不免有些繁琐,而且可能不太灵活。

那么,我们如何手撸一个简单值班排班及提醒的应用呢?

考虑一种简单的情况,对约束做如下假设:

  • 值班顺序固定,一旦确定下来不再修改
  • 每人值固定时间的班,比如:每人值一周

对需求假设如下:

  • 在合适的时间,提醒值班人值班时间
  • 提醒值班人的同时预告下一个值班人

约束和需求转化为代码如下:


on_duty_list = [\'孙悟空\', \'沙和尚\', \'猪八戒\', \'白龙马\'] # 值班人列表
on_duty_period_in_days = 7 # 每人值一周
notify_days = [1, 5] # 假设值班第一天提醒一次,第5天再提醒一次
# 第一个值班人值班开始时间
on_duty_first_person = \'孙悟空\'
on_duty_first_day = \'2022-03-24 00:00:00\'
# 提醒消息模板
notify_template = Template(r"""
【===========报警值班提醒========】
【本周值班人】$on_duty_person_this_week
【值班时间】 $on_duty_range
【下周值班人】$on_duty_person_next_week
""")

如何用程序来计算当前时间应该是哪个人值班呢?

这里用到简单数学计算:整除、取余运算

当前时间与首个值班人值班开始时间的时间差整除7天得到过了多少周,然后再对总值班人数取余,得到当前应该是第几个值班人值班。

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]

如何计算值班时间范围呢?

这里涉及到简单的日期计算,使用了datetime库

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)]

这10行代码,是整个应用的核心。

整个应用代码如下:

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

import time
from string import Template
import datetime

on_duty_list = [\'孙悟空\', \'沙和尚\', \'猪八戒\', \'白龙马\']
on_duty_period_in_days = 7 # day
notify_days = [1, 5]
on_duty_first_person = \'孙悟空\'
on_duty_first_day = \'2022-03-24 10:00:00\'
oneDayTs = 24 * 60 * 60

notify_template = Template(r"""
【===========报警值班提醒========】
【本周值班人】$on_duty_person_this_week
【值班时间】 $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\'):
    # 先转换为时间数组
    timeArray = time.strptime(time_str, "%Y-%m-%d %H:%M:%S")
    # 转换为时间戳
    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)]


# 周四、每周一提醒本周值班人员,下周值班人员
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)
    if on_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)

效果如下:

这里留个思考题给读者,欢迎评论区交流。

  • 如何实现临时调班的功能?
  • 调用第三方API实现如公众号提醒、短信提醒等

如果觉得文章对你有些帮助,可以在微信公众号关注:小而美实用Python,获取更多新鲜文章。

dotnetcore优雅的命令行实现(代码片段)

介绍一个命令行的实现库,可以优雅而简单的实现命令行应用。 前言控制台应用Console,在我们开发中用处很多。小到一个简单的功能测试,或一组不需要复杂UI的工具类应用,大到后端的服务,都会用到Conso... 查看详情

python两行代码实现一个计算器(代码片段)

eval()函数的妙用官方文档中的解释是,将字符串str当成有效的表达式来求值并返回计算结果。globals和locals参数是可选的,如果提供了globals参数,那么它必须是dictionary类型;如果提供了locals参数,那么它可以是任意的map对象#通... 查看详情

物联网服务nodejs-5天学习第三天实战篇①——10行代码给她造个熬夜提醒睡觉机器人(代码片段)

...2.2.1access_token接口凭证2.2.2构造消息体2.2.3发送消息2.3NodeJS代码实现2.3.1对接微信模块2.3.2定时任务模块2.3.3编写10行代码3.总结面向读者群体❤️电子物联网专业同学,想针对硬件功能构造简单的服务器,不需要学习专业的... 查看详情

ios本地通知的实现(代码片段)

iOS本地通知所有的逻辑都在AppDelegate中,一个程序更新后用户长时间没有使用的提醒由本地应用触发的,它是基于时间行为的一种通知形式,例如闹钟,提醒事项,过了一段时间后台程序提醒用户使用该应用iOS通知机制又叫做消息机制,... 查看详情

国民应用qq如何实现高可用的订阅推送系统(代码片段)

导语|腾讯工程师许扬从QQ提醒实际业务场景出发,阐述一个订阅推送系统的技术要点和实现思路。如何通过推拉结合、异构存储、多重触发、可控调度、打散执行、可靠推送等技术,实现推送可靠性、推送可控性和... 查看详情

使用dotnetty实现redis的一个控制台应用程序(代码片段)

零:Demo跑出来的结果如图上图说明图中左边蓝色的命令行界面,是用windowspowershell命令行链接的。  1.打开powershell命令行界面,输入命令【telnet  127.0.0.1  6379】。   如果没有powershell,使用cmd命令行界面也是... 查看详情

cssgit命令行参考-有关设置和命令的注释和提醒(代码片段)

查看详情

第7章数组实验(代码片段)

C程序设计实验报告实验项目:7.3.1一维数组的应用写一个函数,对用随机函数产生的10个整数按从小到大的顺序排序(升序,用冒泡排序实现)写一个函数,对随机产生的10个整数按从小到大的顺序排序(升序,用选择排序实现... 查看详情

springboot中10行代码构建restful风格应用(代码片段)

RESTful,到现在相信已经没人不知道这个东西了吧!关于RESTful的概念,我这里就不做过多介绍了,传统的Struts对RESTful支持不够友好,但是SpringMVC对于RESTful提供了很好的支持,常见的相关注解有:@RestController@GetMapping@PutMapping@PostMa... 查看详情

cssgit命令行参考-关于git设置和命令的注释和提醒(代码片段)

查看详情

cssgit命令行参考-关于git设置和命令的注释和提醒(代码片段)

查看详情

cssgit命令行参考-关于git设置和命令的注释和提醒(代码片段)

查看详情

android向系统日历添加日程提醒事件(代码片段)

在项目开发过程中,有时会有预约提醒、定时提醒等需求,这时我们可以使用系统日历来辅助提醒。通过向系统日历中写入事件、设置提醒方式(闹钟),实现到达某个特定的时间自动提醒的功能。这样做的... 查看详情

python200行代码实现一个翻译软件(代码片段)

python200行代码实现一个翻译软件心血来潮写一个命令行的翻译软件方便使用(基于百度翻译api),话不多说上代码-_-支持从文件输入输出支持从剪切板输入输出#!/home/fyang/.virtualenvs/base/bin/pythonimportrequestsimportrandomimporthashlibimportjsonimpor... 查看详情

swift跑马灯(50行代码完美实现,超简单)(代码片段)

1、(10行)创建一个跑马灯背景letBG=UIView()BG.layer.cornerRadius=6BG.backgroundColor=.black.withAlphaComponent(0.4)self.view.addSubview(BG)BG.snp.makeConstraintsmakeinmake.left.equalTo(20)make.width.eq 查看详情

不背锅运维:go实现aes加密,并带你手撸一个命令行应用程序(代码片段)

...需求过于简单,那么本篇就用标准库中os即可。实战加密代码package mainimport ( "bytes" "crypto/aes" "crypto/cipher" "encoding/base64" "fmt")var EncKey = []byte("QAZWSXEDCRFVTGBY") // 16位密码串func pkcs7Paddin... 查看详情

linux一键部署alertmanager(代码片段)

 前言Alertmanager处理客户端应用程序(例如Prometheus服务器)发送的警报。它负责删除重复数据、分组并将它们路由到正确的接收器集成,例如电子邮件、PagerDuty或OpsGenie。它还负责警报的静音和抑制。创建一键安装aler... 查看详情

python一个简单的命令行笔记应用(代码片段)

查看详情