阅读进度管理程序,设定目标自动计算每日页数,提醒打卡,提高读完率,不半途而废。
阅读进度管理程序一、实际应用场景描述在知识爆炸的时代很多人都有阅读计划比如今年读50本书、每月精读2本专业书。然而现实往往是买书如山倒读书如抽丝。读者常常因为工作忙碌、缺乏明确目标、没有及时反馈而半途而废。本系统针对这些痛点通过Python编程实现智能阅读进度管理根据书籍难度、个人阅读速度、剩余时间自动计算每日必读页数通过定时提醒和进度追踪帮助读者建立阅读习惯提高完读率。二、引入痛点1. 目标模糊只定读50本书的大目标没有分解到每日可执行任务2. 缺乏监督没有外部压力容易找借口拖延3. 进度不透明不知道自己落后多少缺乏紧迫感4. 动力不足看不到进步容易失去兴趣5. 时间管理差不会根据剩余时间调整阅读计划6. 中断后难续停读几天后就再也捡不起来三、核心逻辑讲解3.1 阅读管理系统架构┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐│ 书籍信息管理 │ → │ 目标设定与分解 │ → │ 阅读能力评估 ││(书名/总页数/难度)│ │(截止日期/优先级) │ │(历史速度分析) │└─────────────────┘ └──────────────────┘ └─────────────────┘↓┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐│ 智能计划生成 │ ← │ 进度监控与反馈 │ ← │ 每日任务计算 ││(动态页数分配) │ │(打卡/提醒/统计) │ │(含缓冲机制) │└─────────────────┘ └──────────────────┘ └─────────────────┘3.2 核心算法公式每日必读页数计算基础页数 剩余页数 ÷ 剩余天数难度系数 简单(0.8) | 中等(1.0) | 困难(1.2)时间系数 工作日(1.0) | 周末(0.7) | 节假日(0.5)调整后页数 基础页数 × 难度系数 × 时间系数 × 紧急度加成紧急度加成 1 (已延误天数 × 0.1)最大不超过1.5阅读速度评估平均速度 累计阅读页数 ÷ 累计阅读天数预估完成时间 剩余页数 ÷ 平均速度置信区间 平均速度 ± (标准差 × 1.96 ÷ √天数)打卡激励机制连续打卡天数奖励 floor(连续天数 ÷ 7) × 10%超额完成任务奖励 min(超额比例, 50%)综合积极性评分 基础分 × (1 打卡奖励 超额奖励)四、代码模块化实现4.1 项目结构reading_progress_manager/├── main.py # 程序入口├── config.py # 配置文件├── book_manager.py # 书籍管理模块├── goal_planner.py # 目标规划模块├── progress_tracker.py # 进度追踪模块├── reminder.py # 提醒服务模块├── scheduler.py # 定时调度模块├── analytics.py # 数据分析模块├── utils.py # 工具函数├── data/│ └── reading_data.json # 阅读数据├── logs/│ └── reading_log.txt # 阅读日志├── requirements.txt # 依赖包└── README.md # 项目说明4.2 核心代码实现config.py - 配置文件配置模块 - 存储系统全局配置参数核心知识点配置集中化管理、枚举定义、类型注解from dataclasses import dataclass, fieldfrom typing import Dict, List, Optionalfrom enum import Enumimport osclass BookDifficulty(Enum):书籍难度等级EASY easy # 轻松读物小说、散文MEDIUM medium # 中等难度科普、商业HARD hard # 困难内容学术、哲学class ReadingTimeType(Enum):阅读时段类型WEEKDAY weekday # 工作日WEEKEND weekend # 周末HOLIDAY holiday # 节假日dataclassclass SystemConfig:系统配置类# 提醒配置check_interval_minutes: int 60 # 检查间隔分钟reminder_enabled: bool True # 是否启用提醒quiet_hours_start: int 22 # 免打扰开始时间quiet_hours_end: int 8 # 免打扰结束时间# 计划配置default_daily_pages: int 20 # 默认每日页数min_daily_pages: int 5 # 最小每日页数max_daily_pages: int 100 # 最大每日页数buffer_days: int 2 # 缓冲天数# 激励配置streak_bonus_rate: float 0.1 # 连续打卡奖励率overtime_bonus_cap: float 0.5 # 超额奖励上限weekly_review_day: int 7 # 周回顾日周日dataclassclass DifficultyConfig:难度配置类difficulty: BookDifficultycoefficient: float # 难度系数description: strexamples: List[str]# 难度系数配置DIFFICULTY_SETTINGS: Dict[BookDifficulty, DifficultyConfig] {BookDifficulty.EASY: DifficultyConfig(difficultyBookDifficulty.EASY,coefficient0.8,description轻松读物可快速阅读,examples[小说, 散文, 杂志, 漫画]),BookDifficulty.MEDIUM: DifficultyConfig(difficultyBookDifficulty.MEDIUM,coefficient1.0,description中等难度需要专注理解,examples[商业管理, 科普读物, 传记, 历史]),BookDifficulty.HARD: DifficultyConfig(difficultyBookDifficulty.HARD,coefficient1.2,description高难度内容需深度思考,examples[学术论文, 哲学著作, 技术专著, 经典文学])}# 时间系数配置TIME_COEFFICIENTS: Dict[ReadingTimeType, float] {ReadingTimeType.WEEKDAY: 1.0, # 工作日正常ReadingTimeType.WEEKEND: 0.7, # 周末时间充裕系数降低ReadingTimeType.HOLIDAY: 0.5 # 节假日系数最低}# 系统默认配置DEFAULT_CONFIG SystemConfig()# 数据文件路径DATA_DIR dataLOG_DIR logsDATA_FILE os.path.join(DATA_DIR, reading_data.json)LOG_FILE os.path.join(LOG_DIR, reading_log.txt)book_manager.py - 书籍管理模块书籍管理模块 - 负责书籍的增删改查及状态管理核心知识点面向对象设计、数据验证、JSON序列化import jsonimport osfrom datetime import datetime, datefrom typing import Optional, Dict, List, Anyfrom dataclasses import dataclass, asdict, fieldfrom enum import Enumimport uuidimport logginglogging.basicConfig(levellogging.INFO)logger logging.getLogger(__name__)class BookStatus(Enum):书籍状态枚举NOT_STARTED not_started # 未开始IN_PROGRESS in_progress # 进行中COMPLETED completed # 已完成PAUSED paused # 已暂停ABANDONED abandoned # 已放弃dataclassclass ReadingSession:单次阅读记录session_id: strpages_read: int # 本次阅读页数start_time: str # 开始时间end_time: str # 结束时间duration_minutes: int # 持续分钟数notes: str # 阅读笔记mood: int 3 # 心情指数 1-5dataclassclass Book:书籍实体类book_id: str # 唯一标识title: str # 书名author: str # 作者total_pages: int # 总页数difficulty: str # 难度等级status: str # 书籍状态current_page: int 0 # 当前页码start_date: Optional[str] None # 开始阅读日期target_completion_date: Optional[str] None # 目标完成日期priority: int 3 # 优先级 1-5tags: List[str] field(default_factorylist) # 标签sessions: List[Dict] field(default_factorylist) # 阅读会话历史created_at: str field(default_factorylambda: datetime.now().isoformat())updated_at: str field(default_factorylambda: datetime.now().isoformat())def to_dict(self) - Dict:转换为字典格式return asdict(self)classmethoddef from_dict(cls, data: Dict) - Book:从字典创建书籍对象return cls(**data)propertydef progress_percentage(self) - float:计算阅读进度百分比if self.total_pages 0:return 0.0return round((self.current_page / self.total_pages) * 100, 1)propertydef remaining_pages(self) - int:计算剩余页数return max(0, self.total_pages - self.current_page)propertydef is_overdue(self) - bool:判断是否逾期if not self.target_completion_date or self.status BookStatus.COMPLETED.value:return Falsetarget_date datetime.fromisoformat(self.target_completion_date).date()return date.today() target_dateclass BookManager:书籍管理器 - 单例模式管理所有书籍核心功能书籍CRUD、状态管理、数据持久化_instance Nonedef __new__(cls, *args, **kwargs):单例模式确保全局只有一个管理器实例if cls._instance is None:cls._instance super().__new__(cls)return cls._instancedef __init__(self, data_file: str data/reading_data.json):self.data_file data_fileself.books: Dict[str, Book] {}self._load_data()def _load_data(self) - None:从JSON文件加载书籍数据try:if os.path.exists(self.data_file):with open(self.data_file, r, encodingutf-8) as f:data json.load(f)for book_data in data:book Book.from_dict(book_data)self.books[book.book_id] booklogger.info(f成功加载 {len(self.books)} 本书籍数据)except Exception as e:logger.error(f加载数据失败: {e})self.books {}def _save_data(self) - None:保存书籍数据到JSON文件try:os.makedirs(os.path.dirname(self.data_file), exist_okTrue)data [book.to_dict() for book in self.books.values()]with open(self.data_file, w, encodingutf-8) as f:json.dump(data, f, ensure_asciiFalse, indent2)logger.debug(书籍数据保存成功)except Exception as e:logger.error(f保存数据失败: {e})def add_book(self, title: str, author: str, total_pages: int,difficulty: str, target_date: str None,priority: int 3, tags: List[str] None) - Book:添加新书籍Args:title: 书名author: 作者total_pages: 总页数difficulty: 难度等级 (easy/medium/hard)target_date: 目标完成日期 (YYYY-MM-DD)priority: 优先级 1-5tags: 标签列表Returns:创建的书籍对象# 验证参数self._validate_book_params(title, total_pages, difficulty, priority)# 生成唯一IDbook_id str(uuid.uuid4())[:8]# 处理目标日期if target_date:# 验证日期格式datetime.strptime(target_date, %Y-%m-%d)else:# 默认30天后完成target_date (date.today() timedelta(days30)).isoformat()# 创建书籍对象book Book(book_idbook_id,titletitle,authorauthor,total_pagestotal_pages,difficultydifficulty,statusBookStatus.NOT_STARTED.value,target_completion_datetarget_date,prioritypriority,tagstags or [],start_dateNone)self.books[book_id] bookself._save_data()logger.info(f成功添加书籍: {title} by {author})return bookdef _validate_book_params(self, title: str, total_pages: int,difficulty: str, priority: int) - None:验证书籍参数if not title or len(title.strip()) 0:raise ValueError(书名不能为空)if total_pages 0:raise ValueError(总页数必须大于0)if difficulty not in [easy, medium, hard]:raise ValueError(难度必须是 easy/medium/hard)if not 1 priority 5:raise ValueError(优先级必须在1-5之间)def remove_book(self, book_id: str) - bool:删除书籍if book_id in self.books:book self.books.pop(book_id)self._save_data()logger.info(f已删除书籍: {book.title})return Truereturn Falsedef get_book(self, book_id: str) - Optional[Book]:获取单个书籍return self.books.get(book_id)def list_books(self, status: str None,sort_by: str priority) - List[Book]:列出书籍Args:status: 筛选状态None表示全部sort_by: 排序字段 (priority, progress, deadline)Returns:书籍列表books list(self.books.values())# 状态筛选if status:books [b for b in books if b.status status]# 排序if sort_by priority:books.sort(keylambda x: (-x.priority, x.progress_percentage))elif sort_by progress:books.sort(keylambda x: x.progress_percentage, reverseTrue)elif sort_by deadline:books.sort(keylambda x: (x.target_completion_date or 9999-12-31))return booksdef update_progress(self, book_id: str, pages_read: int,notes: str , mood: int 3) - bool:更新阅读进度Args:book_id: 书籍IDpages_read: 本次阅读页数notes: 阅读笔记mood: 心情指数 1-5Returns:更新是否成功book self.get_book(book_id)if not book:logger.warning(f书籍不存在: {book_id})return False# 验证页数有效性new_page book.current_page pages_readif new_page book.total_pages:logger.warning(f页数超出范围已调整为最大页数)pages_read book.total_pages - book.current_pagenew_page book.total_pagesif pages_read 0:logger.warning(阅读页数必须大于0)return False# 创建阅读会话记录session ReadingSession(session_idstr(uuid.uuid4())[:8],pages_readpages_read,start_timedatetime.now().isoformat(),end_timedatetime.now().isoformat(),duration_minutes30, # 默认30分钟可后续完善notesnotes,moodmood)# 更新书籍状态if book.status BookStatus.NOT_STARTED.value:book.status BookStatus.IN_PROGRESS.valuebook.start_date date.today().isoformat()book.current_page new_pagebook.sessions.append(session.to_dict())book.updated_at datetime.now().isoformat()# 检查是否完成if new_page book.total_pages:book.status BookStatus.COMPLETED.valuebook.current_page book.total_pageslogger.info(f 恭喜完成阅读: {book.title})self._save_data()logger.info(f更新{book.title}进度: {pages_read}页, 当前{new_page}/{book.total_pages}页)return Truedef pause_book(self, book_id: str) - bool:暂停阅读某本书book self.get_book(book_id)if book and book.status BookStatus.IN_PROGRESS.value:book.status BookStatus.PAUSED.valueself._save_data()logger.info(f已暂停书籍: {book.title})return Truereturn Falsedef resume_book(self, book_id: str) - bool:恢复阅读某本书book self.get_book(book_id)if book and book.status BookStatus.PAUSED.value:book.status BookStatus.IN_PROGRESS.valueself._save_data()logger.info(f已恢复书籍: {book.title})return Truereturn Falsedef abandon_book(self, book_id: str, reason: str ) - bool:放弃阅读某本书book self.get_book(book_id)if book:book.status BookStatus.ABANDONED.valuebook.updated_at datetime.now().isoformat()self._save_data()logger.info(f已放弃书籍: {book.title}, 原因: {reason})return Truereturn Falsedef get_statistics(self) - Dict[str, Any]:获取阅读统计信息books list(self.books.values())total_books len(books)completed len([b for b in books if b.status BookStatus.COMPLETED.value])in_progress len([b for b in books if b.status BookStatus.IN_PROGRESS.value])paused len([b for b in books if b.status BookStatus.PAUSED.value])abandoned len([b for b in books if b.status BookStatus.ABANDONED.value])# 计算总阅读页数total_pages_read sum(b.current_page for b in books)total_pages_all sum(b.total_pages for b in books)# 计算平均进度avg_progress 0if total_books 0:avg_progress round(sum(b.progress_percentage for b in books) / total_books, 1)return {total_books: total_books,completed: completed,in_progress: in_progress,paused: paused,abandoned: abandoned,completion_rate: round(completed / total_books * 100, 1) if total_books 0 else 0,total_pages_read: total_pages_read,total_pages_all: total_pages_all,average_progress: avg_progress}goal_planner.py - 目标规划模块目标规划模块 - 智能计算每日阅读任务核心知识点数学建模、时间管理、动态规划from dataclasses import dataclass, fieldfrom datetime import datetime, date, timedeltafrom typing import Dict, List, Optional, Tuplefrom enum import Enumimport mathimport logginglogging.basicConfig(levellogging.INFO)logger logging.getLogger(__name__)dataclassclass DailyPlan:每日阅读计划date: strbook_id: strbook_title: strtarget_pages: intactual_pages: int 0is_completed: bool Falseis_overtime: bool Falsebuffer_used: bool Falsedataclassclass PlanResult:计划计算结果daily_plans: List[DailyPlan]total_target_pages: intaverage_daily_pages: floatestimated_completion_date: strrisk_level: str # low/medium/highrecommendations: List[str]class GoalPlanner:目标规划器 - 根据书籍信息和时间约束计算最优阅读计划核心算法考虑难度、时间、缓冲区的动态规划def __init__(self, config: SystemConfig None):self.config config or DEFAULT_CONFIGself.difficulty_settings DIFFICULTY_SETTINGSself.time_coefficients TIME_COEFFICIENTSdef create_reading_plan(self, book: Book,start_date: str None,end_date: str None) - PlanResult:为单本书创建阅读计划Args:book: 书籍对象start_date: 开始日期默认今天end_date: 结束日期默认目标完成日期Returns:计划结果# 确定日期范围if not start_date:start_date date.today()else:start_date datetime.strptime(start_date, %Y-%m-%d).date()if not end_date:if book.target_completion_date:end_date datetime.strptime(book.target_completion_date, %Y-%m-%d).date()else:# 默认30天end_date start_date timedelta(days30)else:end_date datetime.strptime(end_date, %Y-%m-%d).date()# 计算基础参数remaining_days (end_date - start_date).days 1remaining_pages book.total_pages - book.current_pageif remaining_pages 0:return self._create_empty_plan(book)# 获取难度系数difficulty_config self.difficulty_settings[BookDifficulty(book.difficulty)]difficulty_coeff difficulty_config.coefficient# 计算每日基础页数base_daily_pages remaining_pages / remaining_days# 获取时间系数考虑工作日/周末分布time_distribution self._calculate_time_distribution(start_date, end_date)weighted_time_coeff self._calculate_weighted_time_coeff(time_distribution)# 计算调整后每日页数adjusted_pages base_daily_pages * difficulty_coeff * weighted_time_coeff# 应用缓冲区策略final_daily_pages, buffer_info self._apply_buffer_strategy(adjusted_pages, remaining_days)# 限制页数范围final_daily_pages self._clamp_pages(final_daily_pages)# 生成每日计划daily_plans self._generate_daily_plans(book, start_date, end_date, final_daily_pages,difficulty_coeff, buffer_info)# 风险评估risk_level self._assess_risk(daily_plans, book)# 生成建议recommendations self._generate_recommendations(book, daily_plans, risk_level)# 计算预计完成日期estimated_completion self._calculate_estimated_completion(daily_plans)total_target sum(p.target_pages for p in daily_plans)return PlanResult(daily_plansdaily_plans,total_target_pagesint(total_target),average_daily_pagesround(total_target / len(daily_plans), 1),estimated_completion_dateestimated_completion,risk_levelrisk_level,recommendationsrecommendations)def _calculate_time_distribution(self, start_date: date,end_date: date) - Dict[str, int]:计算时间段内的工作日/周末分布distribution {ReadingTimeType.利用AI解决实际问题如果你觉得这个工具好用欢迎关注长安牧笛
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2414021.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!