设计目录结构:分层结构,类似MVC 1.建立api文件夹 api:接口==》专门处理业务逻辑相关的 user_interface.py--> 用户的业务逻辑 bank_interface.py--> 银行的业务逻辑 2.建立config文件夹 ==》 配置信息 setting.py--> 用户数据保存的路径 3.建core文件夹 ==》 核心文件,放置代码的主要功能 src.py--> 功能文件 4.建立db文件夹 ==》 database(数据库)==》存放、操作数据 db_handle.py-->数据处理层,处理数据的增删改查 user_data--> 用户存放数据的文件夹 5.建立lib文件夹 ==》 自定义模块/功能模块 common.py--> 常用功能,比如装饰器 6.run.py--> 项目的运行文件
src中写入:
import sys
print('Welcome to the bank!')
def register():
'''注册模块'''
pass
def login():
'''登录模块'''
pass
def cheak_money():
'''查看余额模块'''
pass
def save_money():
'''存钱模块'''
pass
def get_money():
'''取钱模块'''
pass
def account():
'''查看账单'''
pass
fun_select = {
0:('退出', sys.exit),
1:('注册', register),
2:('登录', login),
3:('查看余额', cheak_money),
4:('存钱', save_money),
5:('取钱', get_money),
6:('查看账单', account)
}
def atm():
while 1:
print('欢迎来到XX银行')
for k in fun_select:
print(k, fun_select[k][0]) # fun_select[k]是键对应的值,加上[0]取到功能描述的信息
input()
run中写入:
from core import src
if __name__ == '__main__':
src.atm()
这样就有银行的功能描述了
运行结果:
Welcome to the bank!
欢迎来到XX银行
0 退出
1 注册
2 登录
3 查看余额
4 存钱
5 取钱
6 查看账单
src中:
from api import user_interface
def register():
'''
注册函数
1.让用户输入一次用户名,密码,确认密码
2.判断输入是否合法,不合法提示一场,合法进入下一步
3.把注册的用户数据保存写入到user_data里面
'''
while 1:
user_name = input('请输入你的用户名:')
password = input('请输入你的密码:')
re_password = input('请确认你的密码:')
if password == re_password:
# 1.flag为布尔值,判断成功与否 2.msg为flag的补充信息
flag,msg = user_interface.register_info(user_name,password) # 把user_interface里面的函数调用过来
if flag:
print(flag)
break
else:
print(msg)
break
else:
print('两次密码输入不一致,请重新输入')
user_interface中:
from db import db_handle
'''
处理用户注册
1.保存用户注册的信息
2.把得到的字典数据保存到本地
'''
def register_info(user_name,password):
user_info = {
'user_name':user_name,
'password':password,
'money':1000,
'account':[] # 设置空列表
}
# 先查用户的数据
user_data = db_handle.select_data(user_name)
if user_data:
return False,f'注册失败,该用户名已存在'
db_handle.save_data(user_info)
return True,f'{user_name}注册成功' # 响应
db_handle中:
import os
import json
from config.setting import user_data
'''
专门对数据进行保存、读取、修改的模块
'''
def save_data(user_info):
user_name = user_info['user_name']
# with open('aa.txt','w',encoding='utf-8') as f: # 用txt来保存由于是一个字符串,不好对数据进行提取,需要切片等操作。
# f.write(str(user_info)) # user_info是字典类型,write里面要写字符串类型的
with open(f'{user_data}/{user_name}.json', 'w', encoding='utf-8') as f: # user_data下的user_name里面的内容
# dumps()dump()都能将字符串转成json格式,后者可以跟文件关联起来
json.dump(user_info,f) # dump(转json存的数据,文件对象)
# 查找用户数据
def select_data(user_name):
user_path = f'{user_data}/{user_name}.json'
if os.path.exists(user_path):
with open(user_path,'r',encoding='utf-8')as f:
ud = json.load(f) # 读取json文件
return ud
setting中:
# 最终数据会保存到user_data里面
user_data= r'E:\pycharm\pythonProjectATM\db\user_data' # 用一个变量保存user_data这个路径
# 可以在user_data的python文件上按住Ctrl+Shift+C
src中加入:
login_user = None # 定义下login_user
def login():
'''
登录模块
1.写一个死循环,让程序可以重复进行
2.让用户输入用户名和密码
3.进行逻辑判断-->账号密码是否一致
'''
while 1:
user_name = input('请输入用户名:')
password = input('请输入密码:')
flag,msg = user_interface.login_info(user_name,password)
if flag:
print(msg)
global login_user # 设置登陆成功的标识
login_user = user_name
break
else:
print(msg)
break
user_interface中加入:
'''
处理用户登录的逻辑
1.先查看用户是否存在-->存在继续下一步,不存在显示错误
2.密码是否一致-->一致就登陆,不一致登陆失败
'''
def login_info(user_name,password):
# 1.查看用户是否存在
user_data = db_handle.select_data(user_name)
if user_data:
if password == user_data['password']: # 如果输入的密码和原存的密码一样
return True,f'{user_name}登陆成功'
else:
return False,f'密码错误,请重新输入'
else:
return False,'用户不存在,请登录'
在common模块中:
'''
常用的功能模块,自定义的功能模块
'''
# 写一个装饰器,来扩展函数功能
from core import src
def is_login(func):
def check(*args,**kwargs): # 让check函数可以接收任意的值
if src.login_user:
res = func(*args,**kwargs)
return res
else:
print('你还没有登录,请登录/注册')
src.login() # 跳转到登陆界面
return check
src中加入:
?如下,但是后面的功能也都要这样写,有点麻烦。所以舍去这个方式。
def check_money():
'''查看余额模块'''
if login_user:
money = user_interface.check_money_info(login_user)
print(f'用户{login_user},账户余额为{money}元')
else:
print('请登录')
login()
刚刚写的common里面的装饰器代码就可以用上了。不过记得先导包,再加语法糖,如下。
from lib import common
@common.is_login # check_money = is_login(check_money)
def check_money():
'''查看余额模块'''
money = user_interface.check_money_info(login_user)
print(f'用户{login_user},账户余额为{money}元')
user_interface中加入:
# 查看余额的功能实现
def check_money_info(user_name):
user_data = db_handle.select_data(user_name)
return user_data['money'] # 返回字典money键的值
bank_interface中:
import time
from db import db_handle
'''
取款信息
'''
def get_money_info(login_name,money):
'''
1.获取用户数据-->查看现有余额
2.判断账户里是否有足够的钱
3.修改余额/提示取款异常,添加流水账单
4.保存数据-->修改余额,添加流水账单
5.返回取款结果和取款明细说明
'''
# 1.通过用户名,获取用户信息
user_data = db_handle.select_data(login_name)
# 2.查看余额
user_money = int(user_data['money'])
money = int(money)
# 3.判断余额是否足够
if user_money >= money:
# 4.修改余额数据
user_money -= money
user_data['money'] = user_money
# 5.添加流水账单
now_time = time.strftime('%Y-%m-%d %H:%M:%S')
# 返回取款信息
acc_info = f'{now_time} 用户{login_name},取款{money}元成功'
user_data['account'].append(acc_info)
# 6.保存数据,重新更新了用户的数据
db_handle.save_data(user_data)
return True,acc_info
else:
return False,'您的账户余额不足,请重新输入'
src中加入:
from api import bank_interface
@common.is_login
def get_money():
'''
取钱模块
1.让用户输入要取款的金额
2.进行取款的逻辑处理
3.返回取款结果
'''
while 1:
money = input('请输入取款金额:')
if not money.isdigit():
print('输入错误,请输入正确的金额')
continue
else:
flag,msg = bank_interface.get_money_info(login_user,money)
if flag:
print(msg)
break
else:
print(msg)
break
显示结果:
Welcome to the bank!
欢迎来到XX银行
0 退出
1 注册
2 登录
3 查看余额
4 存钱
5 取钱
6 查看账单
请选择你要做的操作:2
请输入用户名:aa
请输入密码:11
aa登陆成功
欢迎来到XX银行
0 退出
1 注册
2 登录
3 查看余额
4 存钱
5 取钱
6 查看账单
请选择你要做的操作:5
请输入取款金额:5
2024-01-15 15:00:49 用户aa,取款5元成功
bank_interface中加入:
'''
存钱行动
'''
def save_money_info(login_user,money):
'''
1.获取用户数据-->查看现有余额
2.修改余额
3.保存数据-->修改数据,添加流水账单
4.返回存款结果和存款结果明细
'''
# 1.获取用户数据
user_data = db_handle.select_data(login_user)
# 2.修改余额
user_data['money'] += int(money)
# 3.添加流水账单
now_time = time.strftime('%Y-%m-%d %H:%M:%S')
acc_info = f'{now_time} 用户{login_user},存款{money}元成功'
user_data['account'].append(acc_info) # 将存款信息追加到列表流水账单中
# 4.保存数据
db_handle.save_data(user_data)
return True,acc_info
src中加入:
@common.is_login
def save_money():
'''存钱模块'''
while 1:
# 接收用户输入的存款金额
money = input('请输入要存款的金额')
if not money.isdigit():
print('输入错误,请重新输入正确金额')
continue
else:
flag,msg = bank_interface.save_money_info(login_user,money)
if flag:
print(msg)
break
else:
print(msg)
break
运行结果:
欢迎来到XX银行
0 退出
1 注册
2 登录
3 查看余额
4 存钱
5 取钱
6 查看账单
请选择你要做的操作:4
请输入要存款的金额100
2024-01-15 15:22:03 用户aa,存款100元成功
欢迎来到XX银行
0 退出
1 注册
2 登录
3 查看余额
4 存钱
5 取钱
6 查看账单
请选择你要做的操作:3
用户aa,账户余额为1100元
bank_interface中加入:
'''
查看账单
'''
def get_acc(login_user):
user_data = db_handle.select_data(login_user)
return user_data['account']
src中加入:
from pprint import pprint
@common.is_login
def account():
'''查看账单'''
acc_list = bank_interface.get_acc(login_user)
if acc_list:
pprint(acc_list) # 格式化流水账单(变得美观一些)
else:
print('该用户目前没有流水账单')
格式化后:
欢迎来到XX银行
0 退出
1 注册
2 登录
3 查看余额
4 存钱
5 取钱
6 查看账单
请选择你要做的操作:6
['2024-01-15 15:00:13 用户aa,取款5元成功',
'2024-01-15 15:00:49 用户aa,取款5元成功',
'2024-01-15 15:20:18 用户aa,存款10元成功',
'2024-01-15 15:22:03 用户aa,存款100元成功',
'2024-01-15 15:28:38 用户aa,存款500元成功',
'2024-01-15 15:28:47 用户aa,取款250元成功',
'2024-01-15 15:28:56 用户aa,存款600元成功']