我的“月账单系统”
前几天的一个想法,催生了我完成了“我的月账单系统”,这是我修习Python以来,做的第三个完整的东东。😁第二个是学生信息记录管理系统,第一个是名片管理系统。
名片管理系统是看到人家名片系统调用自定义的函数,还以为是python的“命令”,那时对函数概念模糊。🧐边做边学字典dict,最终还是鼓捣出来了。🤪
做学生信息记录管理系统时,我倒是对dict比较熟悉了。当时看到人家学校毕设题目有人说想做那个。本着学习dict的目的,我用dict字典存储数据,也想搞一个。😋为了直接写dict到磁盘文件,学习的通用数据传输格式json的简单用法。json序列化不了以元组为key的字典,又逼着我会了Python自己的二进制python数据序列化到磁盘文件pickle。🤗最终努力二十天左右,才得以完成。💪💪
本系统,只记录支出账目
前两个东东的链接:
目录文件
目录文件夹下就两个*.py文件,其他文件都是运行生成的。第一个文件夹下是python首次运行python代码的编译文件,如代码没有修改,就直接运行编译文件,加快速度。
cd 进入*.py文件所在文件夹,直接python mybill_main.py运行主程序代码文件,输入正确口令,就进入系统主菜单。
主程序代码
#/usr/bin/nve python #python目录声明,方便代码在Linux移植
# coding: utf-8 #编码声明
from mybill_tools import * #加载自定义的“我的月账单”功能函数模块
'''“我的月账单”主程序'''
ispasswords() #口令校验,校验成功进入系统。
blank = ' '*16 #空格长度设置
while True: #菜单循环
show_menu() #菜单显示。
while True: #菜单选择。
flag = input(f'\n{blank}菜单选择:').strip()
if flag not in '012345': #菜单选择范围。
input(f'\n{line}\n{blank}输入错误!\n{line}\n')
continue #选择错误,重新选择。
break #选择合规,退出菜单选择循环。
ismenu(flag) #菜单确认,据不同选择,执行相应模块。
添加新账
添加新账模块代码
(如果从语句注释不能清楚作用,请评论区留言指教和探讨。🤝)
def mybill_append(): #添加新账函数
'''添加新账'''
blank = ' '*10 #重置空格长度。
if mybill['02month'] is None:
month = input(f'\n\n{line}\n{blank}月账月份为空,请输入:').strip()
mybill['02month'] = month
mybill_save() #月账单写入磁盘。
input(f'\n{line}\n{blank:14}月份已保存。\n{line}')
if mybill['03mybill_end']=='1':
flag = input(f'\n\n{line}\n{blank}月账已完成记账。\n{line}\n\n{blank}开启新的月账?(Y) ').strip()
if flag in ('Y', 'y'): #清空已完成月账,并写入保留keys。
flag = input(f'\n\n{line}\n{blank}月账已完成记账。\n{line}\n\n{blank}再次确认开启新月账?(Y) ').strip()
if flag in ('Y', 'y'):
mybill.clear() #清空月账字典。
for i, j in zip(reserved_words, reserved_values):
mybill[i] = j #写入保留keys。
else:
input(f'\n\n{line}\n{blank}您已放弃开启新月账,程序将返回。\n{line}\n')
return #不再次确认“开启新月账”,返回主菜。
else:
input(f'\n\n{line}\n{blank}您已放弃开启新月账,程序将返回。\n{line}\n')
return #不再次确认“开启新月账”,返回主菜。
source = '(a:支付宝 w:微信 y:翼支付 x:现金)'
s = '账源(a, w, y)', '账名', '金额'
flag = False #设置实际记账标识。
while True: #循环记账
bill = []
blank = ' '*8
print(f'\n{line}\n {source}\n{blank:11}§输入全空结束新账添加§\n{line}')
for i in s:
bill.append(input(f'\n{blank}{i}:').strip())
if ''.join(bill)=='':
if flag is False:
return #没有实际记账,返回主菜单。
break #输入新账全空退出记账
t_s = f'{t[0]}-{t[1]}-{t[2]} {t[3]}:{t[4]} ' #记账日期贴入
bill_name = "".join((bill[0], t_s, bill[1]))
value = float(bill[2]) #int()不能转化浮点数,所以用浮点数转换函数
print(f'\n\n{line}\n待入新账>> {bill_name}:{float(value):.2f}')
isbill = input(f'\n{line}\n确认直接回车,任意键重新输入:')
if isbill=='': #确认过的记账存入月账字典
flag = True #记账标识
mybill[bill_name] = value
mybill_save() #月账单写入磁盘
blank = ' '*11 #重置空格长度。
input(f'\n{line}\n{blank}添加新账已存入月账单。\n{line}')
缩进太深,是少了一层 else: 始终不出我想要的。终归,被我找到。补上代码了。🤪🤪
添加新账单时检测到完账标识,提示清空月账单,开启新月账。新月账开启第一次记账会要求输入月份。下面截屏是代码运行效果。
效果
账单浏览
账单浏览模块代码
(如果从语句注释不能清楚作用,请评论区留言指教和探讨。🤝)
def browse_mybill(): #月账单浏览函数。
'''月账浏览'''
keys = list(mybill.keys()) #获取月账键。
keys.sort()
for i in reserved_words: #剔除口令、月份、完账状态键。列印不用显示。
keys.remove(i)
print(f'{new_line}{blank*2}月账列印\n{line}\n')
for i, j in enumerate(keys): #enmerate枚举列印月账单。
print(f'{" "*4}{i+1:3}. {j}:{mybill[j]:.2f}')
input(f'{" "*4}...............The.End...............\n\n{line}')
return keys #函数返回全部账单键列表。
月底扎账
月底扎账模块代码
(如果从语句注释不能清楚作用,请评论区留言指教和探讨。🤝)
def mybill_count(): #月底扎账函数。
'''月底扎账'''
if mybill['03mybill_end']=='0':
flag = input(f'\n\n{line}\n{blank}月记账完结标识为“0”。\n\n{blank}确认完成月记账输入“1”:').strip()
if flag=='1':
isflag = input(f'\n\n{line}\n{blank}确认记账完成?(Y) ').strip()
if isflag not in ('Y', 'y'):
return
mybill['03mybill_end'] = flag
mybill_save() #月账单写入磁盘。
input(f'\n\n{line}\n{blank}月账记账完成标识已保存。\n{line}\n')
elif mybill['03mybill_end']=='1':
mybill_temp = mybill.copy() #复制月账
for i in reserved_words: #剔除口令、月份、完账状态键。列印不用显示。
del mybill_temp[i]
mybill_sum = sum(mybill_temp.values())
input(f'\n\n{line}\n{blank}{mybill["02month"]}月共花费:{mybill_sum:.2f}\n{line}\n')
return mybill_sum #返回月账单金额汇总。
文本账单导出
导出的文本账单
文本账单导出模块代码
(如果从语句注释不能清楚作用,请评论区留言指教和探讨。🤝)
def mybilltotxt(): #月度扎账文本输出函数。
'''文本账单'''
month = mybill['02month']
bill_name = f'{month}月账单.txt'
with open(bill_name, 'w') as f:
f.write(f'{blank:15}{month}月份账单\n{line}\n')
for i, j in enumerate(browse_mybill()):
f.write(f'\n{i+1:3}. {j}:{mybill[j]}')
localtime_s = f'{t[0]}年{t[1]}月{t[2]}日'
f.write(f'\n\n{line}\n\n{blank}本月共花费:{mybill_count():.2f}\n\n{line}\n{blank:22}{localtime_s}\n')
os.system(f'ls -l {bill_name}') #
input(f'\n\n{line}\n{blank:11}文本账单成功导出。\n{line}\n\n{blank:22}{localtime_s}')
口令更改
口令更改模块代码
(如果从语句注释不能清楚作用,请评论区留言指教和探讨。🤝)
def change_passwords(): #口令更改函数。
'''口令更改'''
passwords = mybill['01passwords']
if passwords!='': #原口令不为'',校验口令成功继续,败返回。
input_s = input(f'\n\n{line}\n{blank:13}旧口令:')
input_s = passwords_encrypt(input_s)
if input_s!=passwords:
input(f'\n\n{line}\n{blank:15}旧口令错误!\n{line}')
return
new = input(f'\n\n{line}\n{blank:13}新口令:')
new2 = input(f'\n\n{line}\n{blank}再次输入新口令:')
if new!=new2:
input(f'\n\n{line}\n{blank}两次输入新口令不一致!\n{line}')
return
new = passwords_encrypt(new)
mybill['01passwords'] = new
mybill_save() #月账单写入磁盘。
input(f'\n\n{line}\n{blank:15}口令更改成功!\n{line}')
口令加密
这次的口令加密,不像学生信息记录管理系统,使用 ord(passwords[i])+number 固定数字,而是用 k = 1 … k += k ord(passwords[i])+k 动态数字加密,从而避免了口令字符连续而密文也连续的尴尬。😋
口令字符串与密文样例
口令加密模块代码
(如果从语句注释不能清楚作用,请评论区留言指教和探讨。🤝)
def passwords_encrypt(words): #口令加密函数。
'''口令加密'''
encrypt_words = [] #密文列表。
k = 1 #加密变量
for i in words: #循环逐位加密口令字符串。
encrypt_words.append(f'{ord(i)+k}')
k += k #计算加密value
return ''.join(encrypt_words) #拼接密文列表成字符串返回。
先前写的简单口令:
简单加密口令(chr()、ord())
退出系统
自定义功能模块
功能模块完整代码
#/usr/bin/nve python
# coding: utf-8
import os, time, pickle, glob
reserved_words = '01passwords', '02month', '03mybill_end'
reserved_values = '', None, '0'
if glob.glob('mybill.db')==[]: #磁盘没有月账数据,则创建月账字典mybill。
mybill = {i: j for i, j in zip(reserved_words, reserved_values)}
else: #磁盘有月账数据文件,则读取到字典mybill。
mybill = pickle.load(open('mybill.db', 'rb'))
t = time.localtime() #当前时间数组攻取。
k = 1 #模块打印序号变量
'''我的账单功能模块'''
new_line = '\n'*4 #大换行设置
blank = ' '*10 #空格长度
line = '﹊'*21 #信息显示分割线
if __name__=='__main__':
print(f'\n\n\n{blank:8}【我的账单系统】功能模块\n{line}\n')
def clear(): #清屏函数
'''Linux清屏'''
l = os.system('clear') #调用Linux清屏命令
if __name__=='__main__':
print(f'\n§{k:2d}. 清屏模块:clear()')
k += 1
def ispasswords(): #口令校验函数
'''口令校验'''
passwords = mybill['01passwords']
if passwords!='':
input_s = input(f'{new_line}$>> 口令? ')
input_s = passwords_encrypt(input_s) #调用口令加密模块加密输入口令。
if input_s!=passwords: #密文口令比对。
input(f'\n\n{line}\n{blank:15}口令错误!将退出系统。\n{line}')
exit() #退出系统,python启动时就已把exit()、quit()注入内存,可以直接调用。
if __name__=='__main__':
print(f'\n§{k:2d}. 口令校验模块:ispasswords()')
k += 1
def show_menu(): #菜单列印函数。
'''菜单显示'''
blank = ' '*10 #重置空格长度。
t = time.localtime() #菜单列印一次刷单一次当前时间数组
localtime_s = f'{line}\n{blank}{t[0]:4}年{t[1]:2}月{t[2]:2}日 {t[3]:2}:{t[4]:2}:{t[5]:2}\n{line}\n'
menu_s = '添加新账', '账本浏览', '月底扎账', '月账导出', '口令更换'
clear() #调用模块清屏
print(f'{new_line}{blank}【我的月账单系统菜单】\n\n{localtime_s}\n')
blank = ' '*15 #重置空格长度。
for k, i in enumerate(menu_s): #enmerate枚举列印菜单项。
print(f'{blank}{k+1}. {i}\n')
print(f'{blank}0. 退出系统\n\n\n{line}')
if __name__=='__main__':
print(f'\n§{k:2d}. 菜单显示模块:show_menu()')
k += 1
def ismenu(flag): #菜单转向函数
'''菜单确认'''
if flag=='1':
mybill_append() #新账添加
if flag=='2':
browse_mybill() #月账浏览
if flag=='3':
mybill_count() #月底扎账
if flag=='4':
mybilltotxt() #文本账单导出
if flag=='5':
change_passwords() #口令更改
if flag=='0':
clear()
print(f'{new_line}{line}\n{blank} 您已成功退出系统。\n\n{blank} 欢迎再次使用。\n{line}\n')
exit() #退出系统
if __name__=='__main__':
print(f'\n§{k:2d}. 菜单确认模块:ismenu(flag)')
k += 1
def mybill_save(): #月账单写入磁盘函数。
'''月账单写入磁盘'''
pickle.dump(mybill, open('mybill.db', 'wb')) #序列化月账字典到磁盘文件
os.system(r'ls -l mybill.db') #列印月账磁盘数据文件。
if __name__=='__main__':
print(f'{new_line}已写入磁盘月账单文件详情:')
print(f'\n§{k:2d}. 月账单写入磁盘模块:mybill_save()')
k += 1
def mybill_append(): #添加新账函数
'''添加新账'''
blank = ' '*10 #重置空格长度。
if mybill['02month'] is None:
month = input(f'\n\n{line}\n{blank}月账月份为空,请输入:').strip()
mybill['02month'] = month
mybill_save() #月账单写入磁盘。
input(f'\n{line}\n{blank:14}月份已保存。\n{line}')
if mybill['03mybill_end']=='1':
flag = input(f'\n\n{line}\n{blank}月账已完成记账。\n{line}\n\n{blank}开启新的月账?(Y) ').strip()
if flag in ('Y', 'y'): #清空已完成月账,并写入保留keys。
flag = input(f'\n\n{line}\n{blank}月账已完成记账。\n{line}\n\n{blank}再次确认开启新月账?(Y) ').strip()
if flag in ('Y', 'y'):
mybill.clear() #清空月账字典。
for i, j in zip(reserved_words, reserved_values):
mybill[i] = j #写入保留keys。
else:
input(f'\n\n{line}\n{blank}您已放弃开启新月账,程序将返回。\n{line}\n')
return #不再次确认“开启新月账”,返回主菜。
else:
input(f'\n\n{line}\n{blank}您已放弃开启新月账,程序将返回。\n{line}\n')
return #不再次确认“开启新月账”,返回主菜。
source = '(a:支付宝 w:微信 y:翼支付 x:现金)'
s = '账源(a, w, y)', '账名', '金额'
flag = False #设置实际记账标识。
while True: #循环记账
bill = []
blank = ' '*8
print(f'\n{line}\n {source}\n{blank:11}§输入全空结束新账添加§\n{line}')
for i in s:
bill.append(input(f'\n{blank}{i}:').strip())
if ''.join(bill)=='':
if flag is False:
return #没有实际记账,返回主菜单。
break #输入新账全空退出记账
t_s = f'{t[0]}-{t[1]}-{t[2]} {t[3]}:{t[4]} ' #记账日期贴入
bill_name = "".join((bill[0], t_s, bill[1]))
value = float(bill[2]) #int()不能转化浮点数,所以用浮点数转换函数
print(f'\n\n{line}\n待入新账>> {bill_name}:{float(value):.2f}')
isbill = input(f'\n{line}\n确认直接回车,任意键重新输入:')
if isbill=='': #确认过的记账存入月账字典
flag = True #记账标识
mybill[bill_name] = value
mybill_save() #月账单写入磁盘
blank = ' '*11 #重置空格长度。
input(f'\n{line}\n{blank}添加新账已存入月账单。\n{line}')
if __name__=='__main__':
print(f'\n§{k:2d}. 录入新账模块:mybill_append()')
k += 1
def browse_mybill(): #月账单浏览函数。
'''月账浏览'''
keys = list(mybill.keys()) #获取月账键。
keys.sort()
for i in reserved_words: #剔除口令、月份、完账状态键。列印不用显示。
keys.remove(i)
print(f'{new_line}{blank*2}月账列印\n{line}\n')
for i, j in enumerate(keys): #enmerate枚举列印月账单。
print(f'{" "*4}{i+1:3}. {j}:{mybill[j]:.2f}')
input(f'{" "*4}...............The.End...............\n\n{line}')
return keys #函数返回全部账单键列表。
if __name__=='__main__':
print(f'\n§{k:2d}. 月账浏览模块:browse_mybill()')
k += 1
def mybill_count(): #月底扎账函数。
'''月底扎账'''
if mybill['03mybill_end']=='0':
flag = input(f'\n\n{line}\n{blank}月记账完结标识为“0”。\n\n{blank}确认完成月记账输入“1”:').strip()
if flag=='1':
isflag = input(f'\n\n{line}\n{blank}确认记账完成?(Y) ').strip()
if isflag not in ('Y', 'y'):
return
mybill['03mybill_end'] = flag
mybill_save() #月账单写入磁盘。
input(f'\n\n{line}\n{blank}月账记账完成标识已保存。\n{line}\n')
elif mybill['03mybill_end']=='1':
mybill_temp = mybill.copy() #复制月账
for i in reserved_words: #剔除口令、月份、完账状态键。列印不用显示。
del mybill_temp[i]
mybill_sum = sum(mybill_temp.values())
input(f'\n\n{line}\n{blank}{mybill["02month"]}月共花费:{mybill_sum:.2f}\n{line}\n')
return mybill_sum #返回月账单金额汇总。
if __name__=='__main__':
print(f'\n§{k:2d}. 月底扎账模块:mybill_count()')
k += 1
def mybilltotxt(): #月度扎账文本输出函数。
'''文本账单'''
month = mybill['02month']
bill_name = f'{month}月账单.txt'
with open(bill_name, 'w') as f:
f.write(f'{blank:15}{month}月份账单\n{line}\n')
for i, j in enumerate(browse_mybill()):
f.write(f'\n{i+1:3}. {j}:{mybill[j]}')
localtime_s = f'{t[0]}年{t[1]}月{t[2]}日'
f.write(f'\n\n{line}\n\n{blank}本月共花费:{mybill_count():.2f}\n\n{line}\n{blank:22}{localtime_s}\n')
os.system(f'ls -l {bill_name}') #
input(f'\n\n{line}\n{blank:11}文本账单成功导出。\n{line}\n\n{blank:22}{localtime_s}')
if __name__=='__main__':
print(f'\n§{k:2d}. 账单文本导出模块:mybilltotxt()')
k += 1
def passwords_encrypt(words): #口令加密函数。
'''口令加密'''
encrypt_words = [] #密文列表。
k = 1 #加密变量
for i in words: #循环逐位加密口令字符串。
encrypt_words.append(f'{ord(i)+k}')
k += k #计算加密value
return ''.join(encrypt_words) #拼接密文列表返回。
if __name__=='__main__':
print(f'\n§{k:2d}. 口令加密模块:passwords_encrypt(words)')
k += 1
def change_passwords(): #口令更改函数。
'''口令更改'''
passwords = mybill['01passwords']
if passwords!='': #原口令不为'',校验口令成功继续,败返回。
input_s = input(f'\n\n{line}\n{blank:13}旧口令:')
input_s = passwords_encrypt(input_s)
if input_s!=passwords:
input(f'\n\n{line}\n{blank:15}旧口令错误!\n{line}')
return
new = input(f'\n\n{line}\n{blank:13}新口令:')
new2 = input(f'\n\n{line}\n{blank}再次输入新口令:')
if new!=new2:
input(f'\n\n{line}\n{blank}两次输入新口令不一致!\n{line}')
return
new = passwords_encrypt(new)
mybill['01passwords'] = new
mybill_save() #月账单写入磁盘。
input(f'\n\n{line}\n{blank:15}口令更改成功!\n{line}')
if __name__=='__main__':
print(f'\n§{k:2d}. 口令更改模块:change_passwords()')
k += 1
s = '………………………………The…Codes…End………………………………'
if __name__=='__main__':
print(f'\n\n{s}\n\n{line}\n')
#………………………………The…Codes…End………………………………
改进中的账单字符串
我的博文推荐:
- 尼姆游戏(聪明版/傻瓜式•人机对战)(当前阅读3220)(代码优化版)
- 练习:字符串统计(坑:f‘string‘报错)(当前阅读1324)
- 练习:求列表(整数列表)平衡点(当前阅读1689)
- 密码强度检测器(当前阅读1661)
- 电话拨号键盘的字母组合(当前阅读1201)
推荐条件 点阅破千
参考文章:
上一篇: Python中的*
下一篇: 调皮的空字符串 ‘‘
回首页
精品文章:
- 通过内置对象理解python'
- 正则表达式
- python中“*”的作用
- Python 完全自学手册
- 海象运算符
- Python中的 `!=`与`is not`不同
- 学习编程的正确方法
来源:老齐教室
CSDN实用技巧博文: