定时提醒并记录饮水的脚本

wen 实用脚本 2

本文目录导读:

定时提醒并记录饮水的脚本

  1. 饮水提醒与记录脚本
  2. 使用方法

我来帮您创建一个定时提醒并记录饮水的Python脚本,这个脚本会每隔一段时间提醒您喝水,并记录您的饮水情况。

饮水提醒与记录脚本

安装依赖

安装必要的库:

pip install plyer schedule pandas

完整脚本

import time
import pandas as pd
from datetime import datetime, timedelta
from plyer import notification
import schedule
import sqlite3
import os
import json
from pathlib import Path
class WaterReminder:
    def __init__(self):
        # 配置文件路径
        self.config_file = Path.home() / '.water_reminder_config.json'
        self.db_file = Path.home() / '.water_reminder.db'
        # 默认设置
        self.default_config = {
            'interval_minutes': 30,  # 提醒间隔(分钟)
            'reminder_message': '💧 该喝水了!保持水分很重要哦!',
            'daily_goal': 2000,  # 每日目标饮水量(ml)
            'cup_size': 250,  # 每次饮水量(ml)
            'start_time': '08:00',  # 开始提醒时间
            'end_time': '22:00',  # 结束提醒时间
            'sound_enabled': False,
            'notification_title': '💧 饮水提醒'
        }
        # 加载或创建配置
        self.config = self.load_config()
        # 初始化数据库
        self.init_database()
        # 当前会话的饮水记录
        self.current_session = []
    def load_config(self):
        """加载配置"""
        if self.config_file.exists():
            with open(self.config_file, 'r', encoding='utf-8') as f:
                config = json.load(f)
                # 合并默认配置和新配置
                merged_config = self.default_config.copy()
                merged_config.update(config)
                return merged_config
        else:
            # 保存默认配置
            self.save_config(self.default_config)
            return self.default_config
    def save_config(self, config=None):
        """保存配置"""
        if config is None:
            config = self.config
        with open(self.config_file, 'w', encoding='utf-8') as f:
            json.dump(config, f, ensure_ascii=False, indent=2)
    def init_database(self):
        """初始化数据库"""
        conn = sqlite3.connect(str(self.db_file))
        cursor = conn.cursor()
        # 创建饮水记录表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS water_records (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                timestamp TEXT NOT NULL,
                amount INTEGER NOT NULL,
                date TEXT NOT NULL,
                note TEXT
            )
        ''')
        # 创建每日统计表
        cursor.execute('''
            CREATE TABLE IF NOT EXISTS daily_stats (
                id INTEGER PRIMARY KEY AUTOINCREMENT,
                date TEXT UNIQUE NOT NULL,
                total_amount INTEGER NOT NULL DEFAULT 0,
                cup_count INTEGER NOT NULL DEFAULT 0,
                goal_achieved INTEGER DEFAULT 0
            )
        ''')
        conn.commit()
        conn.close()
    def send_notification(self):
        """发送系统通知"""
        try:
            notification.notify(
                title=self.config['notification_title'],
                message=self.config['reminder_message'],
                timeout=10,
                app_name="Water Reminder",
                app_icon=None
            )
            print(f"[{datetime.now().strftime('%H:%M:%S')}] ⏰ 提醒:该喝水了!")
        except:
            print(f"[{datetime.now().strftime('%H:%M:%S')}] ⏰ 提醒:该喝水了!(通知失败,请检查系统通知设置)")
        # 记录提醒
        current_time = datetime.now()
        if self.is_within_working_hours(current_time):
            self.current_session.append({
                'timestamp': current_time.isoformat(),
                'type': 'reminder',
                'amount': 0
            })
    def is_within_working_hours(self, current_time):
        """检查是否在提醒时间范围内"""
        start = datetime.strptime(self.config['start_time'], '%H:%M').time()
        end = datetime.strptime(self.config['end_time'], '%H:%M').time()
        current = current_time.time()
        if start <= end:
            return start <= current <= end
        else:  # 跨天情况
            return current >= start or current <= end
    def log_water(self, amount=None, note=""):
        """记录饮水"""
        if amount is None:
            amount = self.config['cup_size']
        current_time = datetime.now()
        date_str = current_time.strftime('%Y-%m-%d')
        # 插入记录
        conn = sqlite3.connect(str(self.db_file))
        cursor = conn.cursor()
        cursor.execute('''
            INSERT INTO water_records (timestamp, amount, date, note)
            VALUES (?, ?, ?, ?)
        ''', (current_time.isoformat(), amount, date_str, note))
        # 更新每日统计
        cursor.execute('''
            INSERT INTO daily_stats (date, total_amount, cup_count, goal_achieved)
            VALUES (?, ?, 1, 0)
            ON CONFLICT(date) DO UPDATE SET
                total_amount = total_amount + ?,
                cup_count = cup_count + 1
        ''', (date_str, amount, amount))
        conn.commit()
        # 检查是否达到目标
        cursor.execute('''
            SELECT total_amount FROM daily_stats WHERE date = ?
        ''', (date_str,))
        result = cursor.fetchone()
        total_today = result[0] if result else 0
        conn.close()
        # 记录到当前会话
        record = {
            'timestamp': current_time.isoformat(),
            'type': 'drink',
            'amount': amount,
            'note': note
        }
        self.current_session.append(record)
        # 如果达到目标,更新状态
        if total_today >= self.config['daily_goal']:
            conn = sqlite3.connect(str(self.db_file))
            cursor = conn.cursor()
            cursor.execute('''
                UPDATE daily_stats SET goal_achieved = 1 WHERE date = ?
            ''', (date_str,))
            conn.commit()
            conn.close()
            print(f"🎉 恭喜!你已经达到了今日饮水目标 {self.config['daily_goal']}ml!")
        # 输出进度
        progress = min(total_today / self.config['daily_goal'] * 100, 100)
        print(f"✅ 已记录 {amount}ml 饮水,今日共 {total_today}ml,完成 {progress:.1f}%")
        return True
    def get_today_stats(self):
        """获取今日统计"""
        today = datetime.now().strftime('%Y-%m-%d')
        conn = sqlite3.connect(str(self.db_file))
        cursor = conn.cursor()
        cursor.execute('''
            SELECT total_amount, cup_count, goal_achieved
            FROM daily_stats WHERE date = ?
        ''', (today,))
        result = cursor.fetchone()
        conn.close()
        if result:
            return {
                'date': today,
                'total_amount': result[0],
                'cup_count': result[1],
                'goal_achieved': bool(result[2])
            }
        else:
            return {
                'date': today,
                'total_amount': 0,
                'cup_count': 0,
                'goal_achieved': False
            }
    def get_weekly_stats(self):
        """获取本周统计"""
        today = datetime.now()
        start_of_week = today - timedelta(days=today.weekday())
        conn = sqlite3.connect(str(self.db_file))
        cursor = conn.cursor()
        cursor.execute('''
            SELECT date, total_amount, cup_count, goal_achieved
            FROM daily_stats
            WHERE date >= ? AND date <= ?
            ORDER BY date
        ''', (start_of_week.strftime('%Y-%m-%d'), today.strftime('%Y-%m-%d')))
        results = cursor.fetchall()
        conn.close()
        stats = []
        for row in results:
            stats.append({
                'date': row[0],
                'total_amount': row[1],
                'cup_count': row[2],
                'goal_achieved': bool(row[3])
            })
        return stats
    def view_today(self):
        """查看今日饮水记录"""
        stats = self.get_today_stats()
        print(f"\n📊 今日饮水统计 ({stats['date']})")
        print(f"  总饮水量: {stats['total_amount']}ml")
        print(f"  饮水次数: {stats['cup_count']}次")
        print(f"  目标完成: {'✅' if stats['goal_achieved'] else '❌'}")
        if stats['total_amount'] < self.config['daily_goal']:
            remaining = self.config['daily_goal'] - stats['total_amount']
            print(f"  还需饮水: {remaining}ml")
    def view_week(self):
        """查看本周饮水记录"""
        stats = self.get_weekly_stats()
        if not stats:
            print("📊 本周暂无饮水记录")
            return
        print(f"\n📊 本周饮水统计")
        print(f"{'日期':<15} {'饮水量':<10} {'次数':<8} {'目标达成':<8}")
        print("-" * 41)
        total_week = 0
        for day in stats:
            goal_status = '✅' if day['goal_achieved'] else '❌'
            print(f"{day['date']:<15} {day['total_amount']:<10} {day['cup_count']:<8} {goal_status:<8}")
            total_week += day['total_amount']
        print("-" * 41)
        print(f"本周总饮水量: {total_week}ml")
        print(f"日均饮水量: {total_week // max(len(stats), 1)}ml")
    def update_config(self, key, value):
        """更新配置"""
        if key in self.config:
            self.config[key] = value
            self.save_config()
            print(f"✅ 配置已更新: {key} = {value}")
        else:
            print(f"❌ 配置键 '{key}' 不存在")
    def show_config(self):
        """显示当前配置"""
        print("\n⚙️ 当前配置:")
        for key, value in self.config.items():
            print(f"  {key}: {value}")
    def show_menu(self):
        """显示主菜单"""
        print("\n" + "="*40)
        print("       💧 智能饮水助手")
        print("="*40)
        print("1. 📝 记录饮水(默认杯量)")
        print("2. 📝 记录自定义饮水量")
        print("3. 📊 查看今日统计")
        print("4. 📊 查看本周统计")
        print("5. ⚙️ 设置")
        print("6. 🚀 启动自动提醒")
        print("7. 🚫 停止自动提醒")
        print("8. ❌ 退出")
        print("="*40)
    def settings_menu(self):
        """设置菜单"""
        while True:
            print("\n⚙️ 设置菜单:")
            print("1. 设置提醒间隔(分钟)")
            print("2. 设置每日目标(ml)")
            print("3. 设置杯量大小(ml)")
            print("4. 设置提醒开始时间")
            print("5. 设置提醒结束时间")
            print("6. 设置提醒标题")
            print("7. 设置提醒消息")
            print("8. 查看当前配置")
            print("9. 返回主菜单")
            choice = input("\n请选择操作: ").strip()
            if choice == '1':
                try:
                    value = int(input("输入提醒间隔(分钟): "))
                    self.update_config('interval_minutes', value)
                    self.restart_scheduler()
                except ValueError:
                    print("❌ 请输入有效的数字")
            elif choice == '2':
                try:
                    value = int(input("输入每日目标(ml): "))
                    self.update_config('daily_goal', value)
                except ValueError:
                    print("❌ 请输入有效的数字")
            elif choice == '3':
                try:
                    value = int(input("输入杯量大小(ml): "))
                    self.update_config('cup_size', value)
                except ValueError:
                    print("❌ 请输入有效的数字")
            elif choice == '4':
                value = input("输入开始时间(HH:MM格式,如08:00): ")
                try:
                    datetime.strptime(value, '%H:%M')
                    self.update_config('start_time', value)
                except ValueError:
                    print("❌ 时间格式错误,请使用HH:MM格式")
            elif choice == '5':
                value = input("输入结束时间(HH:MM格式,如22:00): ")
                try:
                    datetime.strptime(value, '%H:%M')
                    self.update_config('end_time', value)
                except ValueError:
                    print("❌ 时间格式错误,请使用HH:MM格式")
            elif choice == '6':
                value = input("输入提醒标题: ")
                self.update_config('notification_title', value)
            elif choice == '7':
                value = input("输入提醒消息: ")
                self.update_config('reminder_message', value)
            elif choice == '8':
                self.show_config()
            elif choice == '9':
                break
            else:
                print("❌ 无效选择,请重试")
    def restart_scheduler(self):
        """重新启动调度器"""
        schedule.clear()
        self.schedule_reminders()
    def schedule_reminders(self):
        """设置定时提醒"""
        interval = self.config['interval_minutes']
        if interval > 0:
            schedule.every(interval).minutes.do(self.send_notification)
            print(f"✅ 已设置每 {interval} 分钟提醒一次")
    def start_auto_reminder(self):
        """启动自动提醒"""
        # 清除已有的定时任务
        schedule.clear()
        # 设置新任务
        interval = self.config['interval_minutes']
        schedule.every(interval).minutes.do(self.send_notification)
        print(f"🚀 自动提醒已启动(每 {interval} 分钟)")
        print(f"⏰ 工作时间: {self.config['start_time']} - {self.config['end_time']}")
        # 立即发送一次提醒
        self.send_notification()
        # 运行调度器
        while True:
            schedule.run_pending()
            time.sleep(1)
    def stop_auto_reminder(self):
        """停止自动提醒"""
        schedule.clear()
        print("🛑 自动提醒已停止")
    def run(self):
        """运行主程序"""
        print("💧 欢迎使用智能饮水助手!")
        print("提示:输入 'help' 查看帮助,'exit' 退出程序")
        # 启动自动提醒(后台运行)
        self.schedule_reminders()
        while True:
            self.show_menu()
            choice = input("\n请选择操作: ").strip()
            if choice == '1':
                # 记录默认杯量
                self.log_water()
            elif choice == '2':
                # 记录自定义饮水量
                try:
                    amount = int(input("输入饮水量(ml): "))
                    note = input("输入备注(可选): ")
                    self.log_water(amount, note)
                except ValueError:
                    print("❌ 请输入有效的数字")
            elif choice == '3':
                self.view_today()
            elif choice == '4':
                self.view_week()
            elif choice == '5':
                self.settings_menu()
            elif choice == '6':
                self.start_auto_reminder()
            elif choice == '7':
                self.stop_auto_reminder()
            elif choice == '8' or choice.lower() == 'exit':
                print("👋 再见!保持饮水健康!")
                break
            elif choice.lower() == 'help':
                print("\n📖 帮助信息:")
                print("  - 脚本会自动在后台运行提醒")
                print("  - 每次提醒后请记录饮水")
                print("  - 默认杯量为 250ml")
                print("  - 每日目标为 2000ml")
                print("  - 你可以随时调整设置")
            else:
                print("❌ 无效选择,请重试")
# 运行程序
if __name__ == "__main__":
    reminder = WaterReminder()
    try:
        reminder.run()
    except KeyboardInterrupt:
        print("\n\n👋 程序已终止")

使用方法

  1. 运行脚本

    python water_reminder.py
  2. 主菜单功能

    • 记录饮水(默认杯量或自定义)
    • 查看今日/本周统计
    • 设置提醒参数
    • 启动/停止自动提醒
  3. 设置提醒参数

    • 提醒间隔(默认30分钟)
    • 每日目标饮水量(默认2000ml)
    • 杯量大小(默认250ml)
    • 工作时间范围
  4. 数据存储

    • 所有记录保存在SQLite数据库中
    • 配置文件为JSON格式
    • 数据持久化,不会丢失

这个脚本会:

  • 定时提醒您喝水
  • 记录每次饮水情况
  • 统计每日/每周饮水量
  • 提供配置选项
  • 数据持久化存储

您可以根据需要调整提醒间隔、目标饮水量等参数,祝您保持健康的饮水习惯!

抱歉,评论功能暂时关闭!