import os
from datetime import datetime
def create_path(*args):
for path in args:
if not os.path.exists(path):
os.mkdir(path)
# 定义根路径
BASE_DIR = os.path.dirname(__file__)
# 声明数据库路径
DB_DIR = os.path.join(BASE_DIR, 'database')
# 声明用户名和密码路径
PWD_DIR = os.path.join(DB_DIR, 'Pwd')
BANK_DIR = os.path.join(DB_DIR, 'Bank')
LOG_DIR = os.path.join(DB_DIR, 'Log')
FLOW_DIR = os.path.join(DB_DIR, 'Flow')
# 构建 路径列表
path_list = [PWD_DIR, BANK_DIR, LOG_DIR, FLOW_DIR]
# 解包传值,逐个创建
create_path(*path_list)
# 定义全局用户信息字典
login_user_dict = {
'username': '',
'is_admin': False,
'bank_id': "",
'bank_pwd': "",
"bank_balance": 0
}
# 获取到指定文件所在的文件路径
def get_tag_path(path):
# 用户名和密码存储 : path='user_pwd.txt' ---> database/Pwd/user_pwd.txt
if 'pwd' in path:
path = os.path.join(PWD_DIR, path)
# 银行信息存储 : path='username_bank.txt' ---> database/Bank/username_bank.txt
elif 'bank' in path:
path = os.path.join(BANK_DIR, path)
# 日志信息存储 : path='username_log.txt' ---> database/Log/username_log.txt
elif 'log' in path:
path = os.path.join(LOG_DIR, path)
# 流水信息存储 : path='username_flow.txt' ---> database/Flow/username_flow.txt
elif 'flow' in path:
path = os.path.join(FLOW_DIR, path)
# 返回指定文件的新路径
return path
# 读取数据并做数据处理
def read_data(tag=None, path=None, mode='r', encoding='utf-8'):
'''
:param tag: 标志位 : register login log flow
:param path: 文件名
:param mode: 文件操作模式
:param encoding: 文件默认编码
:return:
'''
# 【1】构建想要的路径 'user_pwd.txt' ---> database/Pwd/user_pwd.txt
path = get_tag_path(path)
# 【2】构建基础信息存储字典或列表
# 【2.1】存储用户名和密码
user_pwd_dict = {}
# 【2.2】存储银行信息
bank_data_dict = {}
# 【2.3】存储日志/流水信息
log_flow_list = []
try:
# 【3】未注册过的用户,肯定是不存在路径的,所以返回空的信息
if tag == 'register' and not os.path.exists(path):
return True, user_pwd_dict
# 【4】读取数据
with open(file=path, mode=mode, encoding=encoding) as fp:
data = fp.read()
# 【5】对数据结尾进行切分,因为每一行数据都是按照 \n 切分的
data_list = data.split('\n')
# 【6】去除掉最后的 空字符串
data_list.pop()
# 【7】根据标志位构建对应的数据字典
# 【7.1】注册/登陆需要的数据
if tag == 'register' or tag == 'login':
# (1)遍历信息列表
for data in data_list:
# (2)对元素进行切割 username|password|role
username, password, role = data.split('|')
# (3)拼接数据字典 {'username':{'password':password,'role':role}}
user_pwd_dict[username] = {'password': password, 'role': role}
# (4)返回用户数据字典
return True, user_pwd_dict
# 【7.2】银行信息
elif tag == "bank":
# (1)遍历数据列表
for data in data_list:
# (2)对元素进行切割 username|bank_id|bank_pwd|bank_balance
username, bank_id, bank_pwd, bank_balance = data.split('|')
# (3)拼接数据字典 {'username':{'bank_id':bank_id,'bank_pwd':bank_pwd,'bank_balance':bank_balance}}
bank_data_dict[username] = {'bank_id': 0 if bank_id == 'None' else int(bank_id),
'bank_pwd': 0 if bank_pwd == 'None' else int(bank_pwd),
'bank_balance': 0 if bank_balance == 'None' else int(bank_balance)}
# (4)返回银行数据字典
return True, bank_data_dict
# 【7.3】日志/流水信息
elif tag == 'log' or tag == 'flow':
# (1)遍历数据列表
for data in data_list:
# (2)将每一条日志/流水添加到列表中即可
log_flow_list.append(data)
# (3)返回信息列表
return True, log_flow_list
except Exception as error:
return False, error
# 保存用户数据
def save_data(mode='a', data=None, encoding='utf-8', path=None):
'''
:param mode: 默认文件操作模式 a 追加
:param data: 需要存储的数据
:param encoding: 默认编码
:param path: 文件名
:return: bool,成功/失败
'''
try:
# 【1】获取文件详细路径
path = get_tag_path(path)
# 【2】打开文件。写入数据
with open(file=path, mode=mode, encoding=encoding) as fp:
# 【3】写入数据 + '\n' 每一行是一条数据
fp.write(data + '\n')
# 【4】反馈信息
return True, f'数据写入成功'
except Exception as error:
return False, error
# 获取用户名和密码的公共函数
def get_user_pwd():
username = input("请输入用户名 :>>>> ").strip()
password = input("请输入密码 :>>>> ").strip()
return username, password
# 创建指定数据格式
def create_data_format(tag=None, **kwargs):
# 【1】默认构建的参数格式为 | 作为拼接的字符串数据
# 原理:遍历当前关键字参数(字典)的所有值,进行 .join() 拼接
data = '|'.join(kwargs.values())
# 【2】标志位声明并做数据处理
# 【2.1】标志位为当前数据格式为日志/流水数据格式
# {'username':'username','msg':msg}
if tag == 'log' or tag == 'flow':
data = f'当前用户 {kwargs.get("username")} 于 {datetime.now().strftime("%Y年%m月%d日 %H时%M分%S秒")} :>>>> {kwargs.get("msg")} !'
# 【3】将构建好的数据信息返回
return data
# 注册函数
def register():
# 【1】获取用户名和密码
username, password = get_user_pwd()
if username == 'dream' and password == '521':
role = 'admin'
else:
role = 'normal'
# 【2】校验当前用户名是否注册过
flag, user_pwd_dict = read_data(tag='register', path='user_pwd.txt')
# 【3】校验当前文件如果存在,则进行用户名是否存在过的校验
if username in user_pwd_dict.keys():
return False, f'当前用户名 {username} 已经注册过了!'
# 【4】当前文件不存在或返回的是空字典
if flag or not user_pwd_dict:
# 【5】开始注册,构建数据格式
# 【5.1】构建用户名和密码数据 username|password|role
pwd_data = create_data_format(username=username, password=password, role=role)
# 保存数据 data=需要保存的数据, path=保存数据的路径
save_data(data=pwd_data, path='user_pwd.txt')
# 【5.2】构建银行初始化信息数据 bank_username|bank_id|bank_pwd|bank_balance
bank_data = create_data_format(bank_username=username, bank_id='None', bank_pwd='None', bank_balance='None')
# 保存数据 data=需要保存的数据, path=保存数据的路径
save_data(data=bank_data, path=f'{username}_bank.txt')
# 【5.3】构建日志信息
log_data = create_data_format(tag='log', username=username, msg='注册成功!')
# 保存数据 data=需要保存的数据, path=保存数据的路径
save_data(data=log_data, path=f'{username}_log.txt')
# 【6】反馈信息
return True, log_data
def check_init_bank(func):
def inner(*args, **kwargs):
if login_user_dict.get('bank_id') == 'None':
return False, f'{login_user_dict["username"]} 还没有激活银行卡!'
return func(*args, **kwargs)
return inner
# 初始化银行信息
def init_bank_data(username):
'''
:param username: 需要初始化的用户名
:return:
'''
# 【1】获取到当前登录用户的银行数据
# {'username':{'bank_id':'None', 'bank_pwd':'None', 'bank_balance':'None'}}
flag, bank_data_dict = read_data(tag='bank', path=f"{username}_bank.txt")
# 【2】出错判断
if not flag:
return flag, bank_data_dict
# 【3】从指定银行数据中切取出来当前用户的银行信息
# {'bank_id':'None', 'bank_pwd':'None', 'bank_balance':'None'}
bank_data = bank_data_dict.get(username)
login_user_dict['bank_id'] = bank_data.get('bank_id')
login_user_dict['bank_pwd'] = bank_data.get('bank_pwd')
login_user_dict['bank_balance'] = bank_data.get('bank_balance')
return True, bank_data_dict
def login():
# 【1】获取用户名和密码
username, password = get_user_pwd()
# 【2】获取历史用户注册信息
flag, user_pwd_dict = read_data(tag='login', path='user_pwd.txt')
# 【3】根据当前用户名从历史用户信息中将当前用户信息筛选出来
user_pwd_data = user_pwd_dict.get(username)
# 【4】判断当前用户信息是否存在(文件不存在或者是用户名不在历史用户信息中)
if not flag or not user_pwd_data:
return flag, '请先注册,谢谢!'
# 【5】校验密码,密码不正确
if password != user_pwd_data.get('password'):
log_data = create_data_format(tag='log', username=username, msg=f'用户名{username}登录失败,密码错误!')
return False, log_data
# 【6】更新当前用户登陆信息
login_user_dict['username'] = username
if user_pwd_data.get('role') == 'admin':
login_user_dict['is_admin'] = True
else:
login_user_dict['is_admin'] = False
# 【7】初识化银行信息
init_bank_data(username=username)
# 【8】记录日志
log_data = create_data_format(tag='log', username=username, msg=f'用户名{username}登录成功!')
save_data(data=log_data, path=f'{username}_log.txt')
# 【9】返回信息
return True, log_data
# 校验用户是否登录
def login_auth(func):
def inner(*args, **kwargs):
if not login_user_dict['username']:
return False, '未登录,请先登录!'
return func(*args, **kwargs)
return inner
@login_auth
@check_init_bank
def active_bank_card():
# 【0】从已经登录的信息中获取到登陆用户的用户名
username = login_user_dict['username']
# 激活银行卡
# 【1】获取银行卡号:必须是数字并且必须是六位
bank_id = input("请输入银行账号 :>>>> ").strip()
if not bank_id.isdigit() or len(bank_id) != 6:
return False, f'银行账号必须为数字,且必须为6位!'
# 【2】获取银行密码:必须是数字,并且必须是三位
bank_pwd = input("请输入银行密码 :>>>> ").strip()
if not bank_pwd.isdigit() or len(bank_pwd) != 3:
return False, f'银行密码必须为数字,且必须为3位!'
# 【3】默认余额为 1000 元
bank_balance = 1000
# 【4】构建银行信息 : username|bank_id|bank_pwd|bank_balance
bank_data = create_data_format(username=username, bank_id=bank_id, bank_pwd=bank_pwd, balance=str(bank_balance))
save_data(path=f'{username}_bank.txt', data=bank_data)
# 【5】构建日志信息
log_data = create_data_format(tag='log', username=username, msg=f'用户{username}激活银行卡成功!')
save_data(path=f'{username}_log.txt', data=log_data)
# 【6】构建流水信息
flow_data = create_data_format(tag='flow', username=username,
msg=f'用户{username}激活银行卡成功!余额为{bank_balance}')
save_data(path=f'{username}_flow.txt', data=flow_data)
init_bank_data(username)
return True, log_data
# 取款功能
@login_auth
@check_init_bank
def withdraw_money():
username = login_user_dict['username']
# 【1】获取银行卡号:必须是数字并且必须是六位
out_balance = input("请输入取款金额 :>>>> ").strip()
# 【2】判断当前的取款金额
# 【2.1】必须是数字
if not out_balance.isdigit():
return False, '非法的余额!'
# 【2.2】转为数字类型
out_balance = int(out_balance)
# 判断当前取款金额必须大于 0
if out_balance < 0:
return False, f'当前取款金额必须大于基础金额0!'
# 【2.3】判断当前取款金额必须小于当前余额
print(login_user_dict)
if out_balance > login_user_dict['bank_balance']:
return False, f'当前余额不足!'
# 【3】获取银行密码:必须是数字,并且必须是三位
bank_pwd = input("请输入银行密码 :>>>> ").strip()
if not bank_pwd.isdigit() or len(bank_pwd) != 3:
return False, f'银行密码必须为数字,且必须为3位!'
bank_pwd = int(bank_pwd)
# 【4】校验当前取款密码
if bank_pwd != login_user_dict['bank_pwd']:
return False, f'当前取款密码错误!'
# 【5】校验通过,开始取钱
login_user_dict['bank_balance'] -= out_balance
# 【6】构建数据格式,存储数据
# 【6.1】构建银行数据格式
bank_data = create_data_format(bank_username=username, bank_id=str(login_user_dict['bank_id']),
bank_pwd=str(bank_pwd), bank_balance=str(login_user_dict['bank_balance']))
save_data(path=f'{username}_bank.txt', data=bank_data)
# 【6.2】构建日志数据格式
log_data = create_data_format(tag='log', username=username,
msg=f'取款 {out_balance} , 当前余额为{login_user_dict["bank_balance"]}')
save_data(path=f'{username}_log.txt', data=log_data)
# 【6.3】构建流水数据格式
flow_data = create_data_format(tag='flow', username=username,
msg=f'取款金额为 {out_balance} , 余额为 {login_user_dict["bank_balance"]}')
save_data(path=f'{username}_flow.txt', data=flow_data)
return True, log_data
# 获取指定用户的银行信息
def get_bank_data(username):
flag, bank_data_dict = read_data(tag='bank', path=f"{username}_bank.txt")
if not flag:
return flag, bank_data_dict
bank_data = bank_data_dict.get(username)
return True, bank_data
# 转账功能
@login_auth
@check_init_bank
def transfer_money():
from_username = login_user_dict['username']
# 【1】获取当前需要转账的金额
out_balance = input("请输入转账金额 :>>>> ").strip()
# 【2】判断当前的取款金额
# 【2.1】必须是数字
if not out_balance.isdigit():
return False, '非法的余额!'
# 【2.2】转为数字类型
out_balance = int(out_balance)
# 判断当前取款金额必须大于 0
if out_balance < 0:
return False, f'当前取款金额必须大于基础金额0!'
# 【2.3】判断当前取款金额必须小于当前余额
# print(login_user_dict)
if out_balance > login_user_dict['bank_balance']:
return False, f'当前余额不足!'
# 【3】获取对方用户账户和银行卡号
to_username = input("请输入对方用户名 :>>>> ").strip()
# 判断对方用户是否存在
# 【4】获取对方银行账号
to_bank_id = input("请输入对方银行卡号 :>>>> ").strip()
if not to_bank_id.isdigit() or len(to_bank_id) != 6:
return False, f'银行账号必须为数字,且必须为6位!'
to_bank_id = int(to_bank_id)
# 【5】获取对方用户的银行信息
flag, to_bank_data = get_bank_data(username=to_username)
if not flag:
return flag, to_bank_data
# 【6】判断用户信息是否正确
if to_bank_id != to_bank_data['bank_id']:
return False, f'当前转账账号与目标账号不一致'
# 【7】获取银行密码:必须是数字,并且必须是三位
bank_pwd = input("请输入银行密码 :>>>> ").strip()
if not bank_pwd.isdigit() or len(bank_pwd) != 3:
return False, f'银行密码必须为数字,且必须为3位!'
bank_pwd = int(bank_pwd)
# 【8】校验当前取款密码
if bank_pwd != login_user_dict['bank_pwd']:
return False, f'当前取款密码错误!'
# 【9】转账开始
# 【9.1】自己的钱减少
login_user_dict['bank_balance'] -= out_balance
# 【9.2】对方的钱增加
to_bank_data['bank_balance'] += out_balance
# 【10】创建银行数据
# 【10.1】自己的银行数据
my_user_bank_data = create_data_format(tag='bank', username=from_username,
bank_id=str(login_user_dict['bank_id']),
bank_pwd=str(login_user_dict['bank_pwd']),
bank_balance=str(login_user_dict['bank_balance']))
save_data(path=f'{from_username}_bank.txt', data=my_user_bank_data)
# 【10.2】对方的银行数据
to_user_bank_data = create_data_format(tag='bank', username=to_username,
bank_id=str(to_bank_data['bank_id']),
bank_pwd=str(to_bank_data['bank_pwd']),
bank_balance=str(to_bank_data['bank_balance'])
)
save_data(path=f'{to_username}_bank.txt', data=to_user_bank_data)
# 【11】记录日志和流水
# 【11.1】自己的日志
from_user_log = create_data_format(tag='log', username=from_username,
msg=f'向 {to_username} 转账 {out_balance} 成功')
save_data(path=f'{from_username}_log.txt', data=from_user_log)
# 【11.2】对方的日志
to_user_log = create_data_format(tag='log', username=to_username,
msg=f'收到 {from_username} 转账 {out_balance} 成功')
save_data(path=f'{to_username}_log.txt', data=to_user_log)
# 【12.1】自己的流水
from_user_flow = create_data_format(tag='flow', username=from_username,
msg=f'向 {to_username} 转账 {out_balance} 成功 余额为 {login_user_dict["bank_balance"]}')
save_data(path=f'{from_username}_flow.txt', data=from_user_flow)
# 【12.2】对方的流水
to_user_flow = create_data_format(tag='flow', username=to_username,
msg=f'收到 {from_username} 转账 {out_balance}成功 余额为 {to_bank_data["bank_balance"]}')
save_data(path=f'{to_username}_flow.txt', data=to_user_flow)
return True, from_user_log
# 充值金额
@login_auth
@check_init_bank
def recharge_money():
username = login_user_dict['username']
# 【1】获取当前需要转账的金额
balance = input("请输入充值金额 :>>>> ").strip()
# 【2】判断当前的取款金额
# 【2.1】必须是数字
if not balance.isdigit():
return False, '非法的余额!'
# 【2.2】转为数字类型
balance = int(balance)
# 判断当前取款金额必须大于 0
if balance < 0:
return False, f'当前存款金额必须大于基础金额0!'
# 【3】获取当前银行密码
bank_pwd = input("请输入银行密码 :>>>> ").strip()
if not bank_pwd.isdigit() or len(bank_pwd) != 3:
return False, f'银行密码必须为数字,且必须为3位!'
bank_pwd = int(bank_pwd)
# 【4】校验当前存款密码
if bank_pwd != login_user_dict['bank_pwd']:
return False, f'当前银行密码错误!'
# 【5】校验通过,开始取钱
login_user_dict['bank_balance'] += balance
# 【6】构建银行信息
bank_data = create_data_format(tag='bank', username=username,
bank_id=str(login_user_dict['bank_id']),
bank_pwd=str(login_user_dict['bank_pwd']),
bank_balance=str(login_user_dict['bank_balance']))
save_data(path=f'{username}_bank.txt', data=bank_data)
# 【7】构建日志信息
user_log = create_data_format(tag='log', username=username,
msg=f'充值成功 当前余额 {login_user_dict["bank_balance"]}')
save_data(path=f'{username}_log.txt', data=user_log)
# 【8】构建流水信息
user_flow = create_data_format(tag='flow', username=username,
msg=f'充值成功 当前余额 {login_user_dict["bank_balance"]}')
save_data(path=f'{username}_flow.txt', data=user_flow)
return True, user_log
# 打印流水
@login_auth
@check_init_bank
def check_flow():
flag, data_list = read_data(tag='flow', path=f'{login_user_dict["username"]}_flow.txt')
if not flag:
return flag, data_list
print(f'''打印当前用户 {login_user_dict["username"]} 流水开始''')
for data in data_list:
print(data)
return True, f'''打印当前用户 {login_user_dict["username"]} 流水结束'''
# 打印银行信息
@login_auth
@check_init_bank
def check_bank_info():
# 【1】获取到当前登录用户
username = login_user_dict['username']
# 【2】获取历史用户注册信息
flag, user_bank_dict = read_data(tag='bank', path=f'{username}_bank.txt')
# 【3】根据当前用户名从历史用户信息中将当前用户信息筛选出来
user_bank_data = user_bank_dict.get(username)
# 打印银行信息如下
msg = f'''
当前用户 {username} 信息如下
用户 名 :>> {username}
银行账号 :>> {user_bank_data["bank_id"]}
银行余额 :>> {user_bank_data["bank_balance"]}
'''
return True, msg
# 打印日志
@login_auth
@check_init_bank
def check_log():
flag, data_list = read_data(tag='log', path=f'{login_user_dict["username"]}_log.txt')
if not flag:
return flag, data_list
print(f'''打印当前用户 {login_user_dict["username"]} 日志开始''')
for data in data_list:
print(data)
return True, f'''打印当前用户 {login_user_dict["username"]} 日志结束'''
func_menu = '''
===================用户功能菜单=====================
1.注册
2.登陆
3.激活银行卡
4.取款
5.转账
6.充值余额
7.查看流水
8.查看银行信息(查看自己的卡号、余额、流水等信息)
9.查看个人日志
======================欢迎使用=======================
'''
func_dict = {
1: register,
2: login,
3: active_bank_card,
4: withdraw_money,
5: transfer_money,
6: recharge_money,
7: check_flow,
8: check_bank_info,
9: check_log
}
def main():
while True:
print(func_menu)
func_id = input("请输入功能ID :>>>> ").strip()
if not func_id.isdigit():
print(f"请输入合法的功能ID :>>>> {func_id}")
continue
func_id = int(func_id)
if func_id not in func_dict:
print(f"未找到对应的功能ID :>>>> {func_id}")
continue
func = func_dict.get(func_id)
flag, msg = func()
if flag:
print(msg)
else:
print(msg)
continue
main()
标签:username,功能,ATM,pwd,user,path,2.0,data,bank
From: https://www.cnblogs.com/dream-ze/p/17937394