【2.0】ATM功能实现
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()
__EOF__

本文作者:Chimengmeng
本文链接:https://www.cnblogs.com/dream-ze/p/17937394.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文链接:https://www.cnblogs.com/dream-ze/p/17937394.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
本文来自博客园,作者:Chimengmeng,转载请注明原文链接:https://www.cnblogs.com/dream-ze/p/17937394
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了