前言
本人初学python,知识有限,本篇仅供 自我记录用,同时也虚心向各位前辈们请教,欢迎大家提出建议。
之前写完程序后,过段时间总容易忘,因此觉得得写篇东西记录下来,当做日后参考使用。
有用java尝试写错词本,可是在实现部分功能如随机取单词的时候出现了些问题,后来转到python来写,通过random.sample方法解决了这个问题。
系统设计
功能点
主要是为了记录自己经常错的单词
- 输入1,进行背单词操作,提示用户输入背诵单词数目n,背诵n个单词,背诵错误的放入新字典,迭代再次背诵;
- 输入2,进行新增单词操作,提示用户输入英文单词和对应的中文意思(多个),并且自动监测英文单词是否存在于单词库中,输入0返回;
- 输入3,查看单词库,并且可以进行修改和删除单词;
- 输入4,break退出程序。
最后,通过pyinstaller -F将程序打包为exe可执行程序,供平常使用。
代码逻辑
主方法使用while True来进行循环,方便进行各项操作,新增单词中同理。
- (1)输入1,进行背单词操作,提示用户输入背诵单词数目n,然后从单词库(txt文件)用random.sample随机提取出n个单词(taken),通过split方法拆分,用for循环放入字典中;
(2)进入check单词核查方法,用户开始根据英文输入中文意思,从中文意思列表中循环匹配。若有正确的意思则显示“回答正确”;若没有则显示“回答错误”,并且将其放入一个新字典中,再次调用背单词方法check进行迭代,直到新字典为空。 - (1)输入2,进行新增单词操作,提示用户输入英文单词(输入0结束),而后调用addCheck方法检查单词库中是否有对应的单词,若有,则返回错误信息;
(2)提示用户输入中文意思,可以输入多个,输入0结束,将输入的中文意思保存为列表,使用**’,'join()**方法将中文意思列表转换为字符串;
(3)将单词和中文组合成:**word:mean1,mean2,……**的样式,存入单词库(txt文件)中。 - 输入3,将单词库文件中的单词取出成字符串打印出来,可以选择是否修改单词库,若输入0,进入modify函数修改单词库:
(1)将取出的字符串整理成字典,类似于taken;
(2)提示输入需要修改的单词,输入0结束,输入1进行删除单词操作;
(3)若删除单词,则提示用户输入需要删除的单词,直到输入0结束;
(4)通过for循环遍历字典的元素,找到匹配的则提示用户输入中文意思,存入列表,完成后修改该键(英文单词)对应的值为新的中文意思组,并显示修改该键成功;
(5)若未找到单词或没有进行修改,则显示“输入单词不在单词库中或修改失败!”;
(5)上述完成后,若用户有进行修改或删除单词的操作,则用wt格式打开文件,将新的字典用写入文件中成为新单词库覆盖原单词库,显示“修改单词库成功”,否则显示“未修改单词库!”。 - 输入4,用break退出主方法的while循环从而退出程序。
数据
worddb.txt:单词库
附上代码:
import os
import random
def taken(n):#从单词库中随机取出n个单词存入字典
try:
if os.path.exists("worddb.txt"):
with open("worddb.txt", "rt", encoding="utf-8") as fobj:
megs = fobj.read()
megs = megs.splitlines()
megs = random.sample(megs, int(n)) # 取出n个不重复的单词
# print(megs)#调试
megs = random.sample(megs, int(n)) # 取出n个不重复的单词
# print(megs)#调试
dic = {}
for meg in megs:
meg = meg.split(":")
word = meg[0]
megCn = meg[1].split(",") # 将中文意思分割开
dic2 = {word: megCn}
dic.update(dic2)
return dic # 将获取的单词字典返回
else:
return '文件不存在,请先录入单词!' # 若没有录入单词,发出错误警告
except Exception as e:
print(e)
def check(dic):#检查新增单词是否存在于单词库中
try:
dic3 = {} # 存储错误答案的键值对
for key, values in dic.items():
# print(key+":"+str(values))#调试
mean = input(key + ":")
right = False
for value in values:
if (mean == value):
print("回答正确!")
right = True
break
if (right == False):
print("回答错误!")
dic4 = {key: values}
dic3.update(dic4) # 若回答错误,再将这个键值对放入新字典
# print(dic3)#调试
print("正确答案是" + key + ":" + str(values))
# print(dic3)#调试
if (dic3): # 若有错误单词,即dic3不为空等价于True,进行迭代重复背诵
check(dic3)
except Exception as e:
print(e)
def recite(n):#背诵单词
try:
dic = taken(n) # 获取单词字典
if type(dic).__name__ == 'dict': # 判断返回值是否为字典类型
check(dic) # 进行背单词核查
print("测试完成!")
else:
print(dic) # 若不为字典类型则是taken中判断不存在文件,返回错误信息
except Exception as e:
print(e)
def add():#新增单词
try:
while True:
word = input("请输入英文单词(输入0结束):")
if word == '0': break # 输入结束
ifindb = addCheck(word) # 判断单词是否在单词库中
if ifindb == True:
print("该单词已存在,请重新输入!")
continue
means = [] # 一个英文单词多个中文意思
while True:
mean = input("请输入中文意思(输入0结束):")
if mean == '0': break
means.append(mean)
means = ','.join(means) # 将列表转换为字符串,用,分隔
with open("worddb.txt", "at", encoding="utf-8") as fobj:
fobj.write(word + ":" + means + "\n")
except Exception as e:
print(e)
def addCheck(word): # 新增单词时判断单词是否在单词库中
try:
if os.path.exists("worddb.txt"):
with open("worddb.txt", "rt", encoding="utf-8") as fobj:
megs = fobj.read()
megs = megs.splitlines()
for meg in megs:
meg = meg.split(":") # 将英文单词和中文意思分开
if meg[0] == word:
return True # 已存在单词,返回True
return False # 循环后没有找到同样的单词,返回False
else:
return True # 若还没有创建文件,返回False
except Exception as e:
print(e)
def show():#展示单词库
try:
if os.path.exists("worddb.txt"):
with open("worddb.txt", "rt", encoding="utf-8") as fobj:
megs = fobj.read()
print(megs)
m=input('是否要修改单词:0:是;其他任意输入:否')
if m=='0':modify(megs)
else:
print('文件不存在,请先录入单词!')
except Exception as e:
print(e)
def modify(megs):#修改单词库
try:
megs = megs.splitlines()
dic = {}#与taken方法中类似,提取单词库中内容到一个字典中
for meg in megs:
meg = meg.split(":")
word = meg[0]
megCn = meg[1].split(",") # 将中文意思分割开
dic2 = {word: megCn}
dic.update(dic2)
ifModify=False#用于检测数据是否有更改过,修改过一个单词,也算做数据有更改过
while True:#开始修改单词
newWord=input('请输入想要修改的单词(输入0结束,输入1进行删除单词操作):')
if newWord=='0':break#输入0结束
elif newWord=='1':
while True:#进行删除单词
delWord=input('请输入需要删除的单词(输入0结束):')
if delWord=='0':break
del dic[delWord]#删除指定键的单词
print('删除单词成功!')
ifModify=True
continue
ifUpdate =False;#用于检测字典是否进行修改,仅针对这个单词是否修改成功
for key, values in dic.items():#检测单词循环
if newWord==key:
newValues=[]#用于存放新的中文意思组
while True:
newValue=input('请输入新的中文意思(输入0结束):')
if newValue=='0':break#输入0结束
newValues.append(newValue)
dic[key]=newValues#将修改的中文意思组更新到字典中
print('修改'+key+'成功!')
ifUpdate=True
ifModify=True
break#找到对应英文单词并修改后退出遍历,进行下一个英文单词修改
if ifUpdate==False and ifModify==False:print('输入单词不在单词库中或修改失败!')#若输入其他或者未进行修改
if ifModify==True:
with open("worddb.txt", "wt", encoding="utf-8") as fobj:#需要放在for前面,要不每次都是新写一个文件
for key, values in dic.items():
values=','.join(values) # 将列表转换为字符串,用,分隔
fobj.write(key+':'+values+'\n')
print('修改单词库成功!')
else:print('未修改单词库!')
except Exception as e:
print(e)
# 主方法
while True:
do = input("请输入序号以进行你想要的操作:1、背单词;2、新增单词;3、查看单词库;4、退出程序")
if do == "1":
n = input("请输入背诵单词数目:")
recite(n)
elif do == "2":
add()
elif do == "3":
show()
elif do == "4":
break
else:
print("输入有误,请重新输入")
需要改进的地方
- 许多函数的代码比较类似,整体代码比较冗余,会反复读取文件,若记录单词多可能会读取比较慢。因此需要加强代码重用,组合各个功能中相同基础功能的代码为新函数,节省空间;
- 各变量命名不够严谨,需要加强规范命名;
- 考虑界面设计。
笔记
- 随机取出的数可以重复:need=[random.randint(0,100) for _ in range(要取出的数据条数)];
随机取出的数不可以重复:need = random.sample([要取数据的列表], 要取出的数据个数)。 - 在python中,{},[],(),等,即为空都等价于False!所以判断字典、列表等是否为空可以用if dic。
- 删除单词部分,若在for循环遍历字典内部查找单词进行删除,会改变字典大小使得for循环无法继续,因此在外部单独进行输入删除。
- 修改单词部分,155行,最后写入文件需要放在for前面,要不每个值都会新写一个文件覆盖掉。
- 打包文件常用方法:pyinstaller -F xxx.py 打包exe命令,但是会有黑窗口;pyinstaller -F -w xxx.py去除黑窗口