目錄
前言
1. 數據管理模塊
?2. 記憶算法實現
3. 持久化存儲
?4. 用戶界面實現
5.整合與測試
前言
????????此篇文章為“有趣的python程序”專欄的第一篇文章,本專欄致力于分享一些有趣的編程作品,如果能夠使您產生興趣,不妨來動手改編使之成為更好的工具吧!若是能夠幫助到您,在下不勝榮幸!
我們先來確定一下單詞記憶程序的功能框架,它需要具有以下功能:
- 基于記憶曲線(艾賓浩斯遺忘曲線)安排單詞復習
- 記錄用戶對單詞的掌握情況
- 提供學習和測試兩種模式
- 持久化保存學習數據
故此我們可以將程序分為幾個核心部分:
- **數據管理**:存儲單詞及其記憶狀態
- **記憶算法**:計算下次復習時間
- **用戶界面**:與用戶交互的界面
- **持久化存儲**:保存學習進度
## 第二階段:分模塊實現
1. 數據管理模塊
先來看以下代碼:
import datetime
from collections import defaultdictclass WordMemorySystem:def __init__(self):# 使用字典存儲所有單詞數據self.word_data = defaultdict(dict)# 記憶曲線間隔 (天)self.review_intervals = [1, 2, 4, 7, 15, 30, 60, 90]def add_word(self, word, meaning, example=""):"""添加新單詞"""today = datetime.date.today()if word not in self.word_data:self.word_data[word] = {'meaning': meaning,'example': example,'added_date': today,'last_reviewed': today,'next_review': today + datetime.timedelta(days=self.review_intervals[0]),'review_count': 0,'correct_count': 0,'incorrect_count': 0}
我們在這里使用列表來儲存記憶曲線的節點,這樣當我們核對各個單詞的背誦時間時就可以與列表里的時間相比對,我們來詳細分析這一句。
'next_review': today + datetime.timedelta(days=self.review_intervals[0])
它的意思是指當前日期加上預設的復習間隔天數。
today
代表當前日期,通常通過datetime.date.today()
獲取。需要確保代碼中已正確定義該變量。
datetime.timedelta
Python標準庫中用于表示時間間隔的類。days
參數指定需要增加的天數。
self.review_intervals[0]
從對象屬性中獲取的第一個復習間隔天數。review_intervals
應為預定義的列表或數組,存儲著不同階段的復習間隔
?2. 記憶算法實現
def review_word(self, word, is_correct):"""記錄單詞復習結果并安排下次復習時間"""if word in self.word_data:info = self.word_data[word]info['last_reviewed'] = datetime.date.today()# 更新正確/錯誤計數if is_correct:info['correct_count'] += 1else:info['incorrect_count'] += 1# 根據記憶曲線安排下次復習時間review_count = min(info['review_count'], len(self.review_intervals) - 1)interval = self.review_intervals[review_count]# 如果不正確,縮短復習間隔if not is_correct:interval = max(1, interval // 2)info['next_review'] = datetime.date.today() + datetime.timedelta(days=interval)info['review_count'] += 1
這里我們需要做防越界處理:通過min()
函數確保review_count
不超過列表的最大索引。
3. 持久化存儲
import json
import osdef load_data(self, data_file='word_memory_data.json'):"""加載已有的單詞數據"""self.data_file = data_fileif os.path.exists(data_file):with open(data_file, 'r', encoding='utf-8') as f:data = json.load(f)# 將字符串日期轉換為datetime.date對象for word, word_info in data.items():for key in ['added_date', 'last_reviewed', 'next_review']:if key in word_info and word_info[key]:word_info[key] = datetime.datetime.strptime(word_info[key], '%Y-%m-%d').date()self.word_data[word] = word_infodef save_data(self):"""保存單詞數據到文件"""# 將datetime.date對象轉換為字符串data_to_save = {}for word, word_info in self.word_data.items():word_info_copy = word_info.copy()for key in ['added_date', 'last_reviewed', 'next_review']:if key in word_info_copy and word_info_copy[key]:word_info_copy[key] = word_info_copy[key].strftime('%Y-%m-%d')data_to_save[word] = word_info_copywith open(self.data_file, 'w', encoding='utf-8') as f:json.dump(data_to_save, f, ensure_ascii=False, indent=2)
?4. 用戶界面實現
在這里,我們來編寫用戶在命令行里交互時所能看到的用戶界面:
def learn_mode(self):"""學習模式:逐個顯示需要復習的單詞"""words_to_review = self.get_words_to_review()if not words_to_review:print("恭喜!今天沒有需要復習的單詞。")returnprint(f"\n今天有 {len(words_to_review)} 個單詞需要復習:")for word, info in words_to_review:print("\n" + "="*50)print(f"單詞: {word}")input("按回車鍵查看意思...")print(f"意思: {info['meaning']}")if info['example']:print(f"例句: {info['example']}")while True:response = input("你記住了嗎?(y/n): ").lower()if response in ['y', 'n']:self.review_word(word, response == 'y')breakprint("請輸入 y 或 n")print("\n復習完成!")
5.整合與測試
接下來我們給程序添加main函數,就離大功告成不遠了!
def main():system = WordMemorySystem()system.load_data()while True:print("\n" + "="*50)print("單詞記憶系統")print("1. 添加新單詞")print("2. 學習模式")print("3. 默寫測試")print("4. 退出")choice = input("請選擇操作: ")if choice == '1':word = input("輸入單詞: ").strip()meaning = input("輸入意思: ").strip()example = input("輸入例句 (可選): ").strip()system.add_word(word, meaning, example)system.save_data()elif choice == '2':system.learn_mode()system.save_data()elif choice == '3':system.test_mode()system.save_data()elif choice == '4':print("退出系統。")breakelse:print("無效選擇,請重新輸入。")
最后,我們來看看完整的代碼:
import datetime
import json
import os
import random
from collections import defaultdictclass WordMemorySystem:def __init__(self, data_file='word_memory_data.json'):self.data_file = data_fileself.word_data = defaultdict(dict)self.load_data()# 記憶曲線間隔 (天)self.review_intervals = [1, 2, 4, 7, 15, 30, 60, 90]def load_data(self):"""加載已有的單詞數據"""if os.path.exists(self.data_file):with open(self.data_file, 'r', encoding='utf-8') as f:data = json.load(f)# 將字符串日期轉換為datetime.date對象for word, word_info in data.items():for key in ['added_date', 'last_reviewed', 'next_review']:if key in word_info and word_info[key]:word_info[key] = datetime.datetime.strptime(word_info[key], '%Y-%m-%d').date()self.word_data[word] = word_infodef save_data(self):"""保存單詞數據到文件"""# 將datetime.date對象轉換為字符串data_to_save = {}for word, word_info in self.word_data.items():word_info_copy = word_info.copy()for key in ['added_date', 'last_reviewed', 'next_review']:if key in word_info_copy and word_info_copy[key]:word_info_copy[key] = word_info_copy[key].strftime('%Y-%m-%d')data_to_save[word] = word_info_copywith open(self.data_file, 'w', encoding='utf-8') as f:json.dump(data_to_save, f, ensure_ascii=False, indent=2)def add_word(self, word, meaning, example=""):"""添加新單詞"""today = datetime.date.today()if word not in self.word_data:self.word_data[word] = {'meaning': meaning,'example': example,'added_date': today,'last_reviewed': today,'next_review': today + datetime.timedelta(days=self.review_intervals[0]),'review_count': 0,'correct_count': 0,'incorrect_count': 0}print(f"已添加單詞: {word} - {meaning}")else:print(f"單詞 '{word}' 已存在")self.save_data()def get_words_to_review(self):"""獲取今天需要復習的單詞"""today = datetime.date.today()words_to_review = []for word, info in self.word_data.items():if 'next_review' in info and info['next_review'] <= today:words_to_review.append((word, info))# 按復習優先級排序 (先復習不熟悉的單詞)words_to_review.sort(key=lambda x: (x[1]['incorrect_count'] / (x[1]['correct_count'] + x[1]['incorrect_count'] + 1),x[1]['next_review']), reverse=True)return words_to_reviewdef review_word(self, word, is_correct):"""記錄單詞復習結果并安排下次復習時間"""if word in self.word_data:info = self.word_data[word]info['last_reviewed'] = datetime.date.today()# 更新正確/錯誤計數if is_correct:info['correct_count'] += 1else:info['incorrect_count'] += 1# 根據記憶曲線安排下次復習時間review_count = min(info['review_count'], len(self.review_intervals) - 1)interval = self.review_intervals[review_count]# 如果不正確,縮短復習間隔if not is_correct:interval = max(1, interval // 2)info['next_review'] = datetime.date.today() + datetime.timedelta(days=interval)info['review_count'] += 1self.save_data()def learn_mode(self):"""學習模式:逐個顯示需要復習的單詞"""words_to_review = self.get_words_to_review()if not words_to_review:print("恭喜!今天沒有需要復習的單詞。")returnprint(f"\n今天有 {len(words_to_review)} 個單詞需要復習:")for word, info in words_to_review:print("\n" + "=" * 50)print(f"單詞: {word}")input("按回車鍵查看意思...")print(f"意思: {info['meaning']}")if info['example']:print(f"例句: {info['example']}")while True:response = input("你記住了嗎?(y/n): ").lower()if response in ['y', 'n']:self.review_word(word, response == 'y')breakprint("請輸入 y 或 n")print("\n復習完成!")def test_mode(self):"""測試模式:默寫測試"""words_to_review = self.get_words_to_review()if not words_to_review:print("今天沒有需要復習的單詞。")returnprint("\n默寫測試模式 (輸入 q 退出)")random.shuffle(words_to_review)for word, info in words_to_review:print("\n" + "=" * 50)print(f"意思: {info['meaning']}")if info['example']:print(f"例句: {info['example']}")user_input = input("請輸入對應的單詞: ").strip()if user_input.lower() == 'q':breakif user_input.lower() == word.lower():print("正確!")self.review_word(word, True)else:print(f"錯誤!正確答案是: {word}")self.review_word(word, False)print("\n測試結束!")def main():system = WordMemorySystem()while True:print("\n" + "=" * 50)print("單詞記憶系統")print("1. 添加新單詞")print("2. 學習模式")print("3. 默寫測試")print("4. 查看所有單詞")print("5. 查看今天需要復習的單詞")print("6. 退出")choice = input("請選擇操作: ")if choice == '1':word = input("輸入單詞: ").strip()meaning = input("輸入意思: ").strip()example = input("輸入例句 (可選): ").strip()system.add_word(word, meaning, example)elif choice == '2':system.learn_mode()elif choice == '3':system.test_mode()elif choice == '4':if not system.word_data:print("還沒有添加任何單詞。")else:print("\n所有單詞:")for i, (word, info) in enumerate(system.word_data.items(), 1):print(f"{i}. {word}: {info['meaning']}")if info['example']:print(f" 例句: {info['example']}")print(f" 添加日期: {info['added_date']}, 最后復習: {info['last_reviewed']}, 下次復習: {info['next_review']}")print(f" 正確: {info['correct_count']}, 錯誤: {info['incorrect_count']}")elif choice == '5':words_to_review = system.get_words_to_review()if not words_to_review:print("今天沒有需要復習的單詞。")else:print(f"\n今天需要復習 {len(words_to_review)} 個單詞:")for i, (word, info) in enumerate(words_to_review, 1):print(f"{i}. {word}: {info['meaning']}")elif choice == '6':print("退出系統。")breakelse:print("無效選擇,請重新輸入。")if __name__ == "__main__":main()
好的!那么今天的內容就到這里了,現在我們只能在命令行中操作它,之后也可以給它添加圖形化界面使它更加有趣。
?