您现在的位置是:网站首页> 编程资料编程资料

Python实战之ATM取款机的实现_python_

2023-05-25 403人已围观

简介 Python实战之ATM取款机的实现_python_

一、项目视图分析

通过上图,我们可以看到,一个完整的项目,基本包括三个部分:用户视图层、接口层、数据处理层,其中,用户视图层是用来接收用户的数据输入的,比如:有户名,密码;接口层是要接收用户视图层传来的数据,然后做判断:名字是否存在、密码是否正确,这就要求接口层调用数据处理层的方法;数据处理层就需要接收接口层的参数,把接口层需要的增、删、改、查的数据结果返回给接口层,接口层再把判断的结果返回给用户层。

二、文件结构分析

文件主要有以下几个部分:conf(setting.py-参数配置,比如:日志文件的配置、路径等)、core(src.py\admin.py-用户视图层,分为图通用户和管理员)、interface(接口层,里面有很多接口:用户接口,购物接口,银行接口,管理员接口,分这么细是为了“解耦合”)、db(用户数据存放;数据处理层:主要负责数据的增、删、改、查)、lib(公共方法:比如登录功能的装饰器)、log(日志文件)、readme(文档说明)、strat启动

三、完整代码

1.start.py

# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:59 @Author : Rice @CSDN : C_小米同学 @FileName: start.py ''' ''' 程序的入口 ''' import sys import os #添加解释器的环境变量 sys.path.append( os.path.dirname(__file__) ) #导入用户视图层 from core import src # 开始执行项目函数 if __name__ == '__main__': # 1.先执行用户视图层 src.run()

2.conf

-settings.py

# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:49 @Author : Rice @CSDN : C_小米同学 @FileName: settings.py ''' ''' 存放配置信息 ''' import os #获取项目根目录路劲 BASE_PATH = os.path.dirname( os.path.dirname(__file__) ) # 获取user_data文件夹目录路径 USER_DATA_PATH = os.path.abspath(os.path.join(BASE_PATH, 'db','user_data')) #USER_DATA_PATH2 = os.path.join(BASE_PATH, 'db','user_data').replace('\\','/') username = 'rice' user_path = os.path.abspath(os.path.join(USER_DATA_PATH, f'{username}.json')).replace('\\','/') """ logging配置 """ BASE_PATH2 = os.path.dirname(os.path.dirname(__file__)) logfile_dir = os.path.abspath(os.path.join(BASE_PATH2,'log')).replace('\\','/') logfile_name = 'atm.log' #如果不存在定义的日志目录就创建一个 if not os.path.isdir(logfile_dir): os.mkdir(logfile_dir) #log文件的全路径 logfile_path = os.path.join(logfile_dir, logfile_name).replace('\\','/') standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' test_format = '%(asctime)s] %(message)s' # 3、日志配置字典 LOGGING_DIC = { 'version': 1, 'disable_existing_loggers': False, 'formatters': { 'standard': { 'format': standard_format }, 'simple': { 'format': simple_format }, }, 'filters': {}, 'handlers': { # 打印到终端的日志 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', # 打印到屏幕 'formatter': 'simple' }, # 打印到文件的日志,收集info及以上的日志 'default': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件,日志轮转 'formatter': 'simple', # 可以定制日志文件路径 # BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # log文件的目录 # LOG_PATH = os.path.join(BASE_DIR,'a1.log') 'filename': logfile_path, # 日志文件 'maxBytes': 1024 * 1024 * 5, # 日志大小 5M 'backupCount': 5, 'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了 }, }, 'loggers': { # logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 这里把上面定义的两个handler都加上,即log数据既写入文件又打印到屏幕 'level': 'DEBUG', # loggers(第一层日志级别关限制)--->handlers(第二层日志级别关卡限制) 'propagate': True, # 默认为True,向上(更高level的logger)传递,通常设置为False即可,否则会一份日志向上层层传递 }, }, } if __name__ == '__main__': print(user_path)

3.core

-src.py

# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:51 @Author : Rice @CSDN : C_小米同学 @FileName: src.py ''' ''' 用户视图层 ''' from interface import user_interface from lib import common from interface import bank_interface from interface import shop_interface #全局变量,记录用户是否已登录 login_user = None # 1.注册功能 def register(): while True: # 1)让用户输入用户名和密码校验 username = input('请输入用户名:').strip() password = input('请输入密码:').strip() re_password = input('请确认密码:').strip() #可以输入自定义的金额 # 小的逻辑错误:比如两次密码是否一致 if password == re_password: #2)调用接口层的注册接口,将用户名与密码交给接口层来进行处理 #一个元祖 flag, msg = user_interface.register_interface(username, password) # 3)根据flag判断用户注册是否成功,用于控制break if flag: print(msg) break else: print(msg) # 2.登录功能 #成功登录了之后,一定会修改全局变量:login_user def login(): #登录视图 while True: #1)让用户输入用户名和密码 username = input('请输入用户名:').strip() password = input('请输入密码:').strip() #2)调用接口层,将数据传给登录接口 flag, msg = user_interface.login_interface(username, password) if flag: print(msg) global login_user login_user = username break else: print(msg) #有一个小bug,输入错误后,我想返回主页 #d #成功登录了# # 3.查看余额 @common.login_auth def check_balance(): #1.直接调用查看余额接口,获取用户余额 #装饰器本身是有login_user balance = user_interface.check_bal_interface(login_user) print(f'用户{login_user} 账户余额为:{balance}') # 4.提现功能 @common.login_auth def withdraw(): while True: #1)让用户输入提现金额 input_money = input('请输入提现金额:').strip() #2)判断用户输入的金额是否是数字 if not input_money.isdigit(): #isdigit()-可以判断字符串 print('请输入') continue #3)用户提现金额,将数据提现的金额交给接口层处理 flag, msg = bank_interface.withdraw_interface(login_user, input_money) if flag: print(msg) break # 5.还款功能 @common.login_auth def repay(): ''' 银行卡还款,无论是信用卡或储蓄卡,是否能任意大小的金额 :return: ''' while True: #1) 让用户输入还款金额 input_money = input('请输入需要还款的金额:').strip() #2)判断用户输入的是否是数字 if not input_money.isdigit(): print('请输入正确的金额') continue input_money = int(input_money) #3)判断用户输入的金额大于0 if input_money > 0: #4)调用还款接口 flag, msg = bank_interface.repay_interface(login_user, input_money) if flag: print(msg) break else: print('输入的金额不能小于0') # 6.转账功能 @common.login_auth def transfer(): ''' 1.接收 用户输入的 转账金额 2.接收用户输入的 转账目标用户 :return: ''' while True: #1) 让用户输入转账用户与金额 to_user = input('请输入转账目标用户').strip() money = input('请输入转账金额').strip() #2)数据判断 if not money.isdigit(): print('请输入数字') continue money = int(money) if money > 0: #调用转账接口 flag, msg = bank_interface.transfer_interface( login_user,to_user,money ) if flag: print(msg) break else: print(msg) else: print('请输入正确的金额') # 7.查看流水 @common.login_auth def check_flow(): #直接调用查看流水接口 flow_list = bank_interface.check_flow_interface(login_user) if flow_list: for flow in flow_list: print(flow) else: print('当前用户没有流水!') # 8.购物功能 @common.login_auth def shop(): #不从文件中读取商品数据,直接写 #创建商品列表 # shop_list = { # '0': {'name': '包子', 'price': 30} # } shop_list = [ ['包子', 3], #0 ['可乐', 5], #1 ['book', 200], ['pc', 9999], ] #初始化当前购物车 shopping_car = {} #{'商品名称':['单价','数量']]} while True: #枚举:enumerate(可迭代对象)--->元祖(可迭代对象的索引,索引对应的值) for index, shop in enumerate(shop_list): shop_name, shop_price = shop print(f'商品编号为{index}, 商品名称{shop_name}, 商品单价:{shop_price}') print(shop) choice = input('请输入商品编号:(是否结账输入y or n)').strip() #让用户根据商品编号进行选择 #输入的是y进行支付结算功能 if choice == 'y': if not shopping_car: print('购物车是空的,不能支付,请重新输入') continue #调用支付接口进行支付 flag, msg = shop_interface.shopping_interface(login_user,shopping_car) if flag: print(msg) break else: print(msg) #输入的是n添加购物车(把shopping_car添加到json中) elif choice == 'n': #调用添加购物车接口 if not shopping_car: print('购物车是空的,不能添加,请重新输入') continue flag, msg = shop_interface.add_shop_car_interface(login_user, shopping_car) if flag: print(msg) break else: print(msg) if not choice.isdigit(): print('请输入正确的编号!') continue if not choice.isdigit(): print('请输入正确的编号!') continue choice = int(choice) if choice not in range(len(shop_list)): print('请输入正确的编号!') continue shop_name, shop_price = shop_list[choice] #加入购物车 #判断用户选择的商品是否重复,重复加1 if shop_name in shopping_car: #添加商品数量 shopping_car[shop_name][1] += 1 else: #否则数量默认为1 shopping_car[shop_name] = [shop_price, 1] # 9.查看购物车 @common.login_auth def check_shop_car(): shop_car = shop_interface.check_shop_car_interface(login_user) print(shop_car) # 10.管理员功能 @common.login_auth def admin(): ''' 管理员功能:课后作业 :return: ''' from core import admin admin.admin_run() # 创建函数功能字典 func_dic = { '1': register, '2': login, '3': check_balance, '4': withdraw, '5': repay, '6': transfer, '7': check_flow, '8': shop, '9': check_shop_car, '10': admin } # 视图层主程序 def run(): while True: print(''' ======= ATM + 购物车 ======= 1.注册功能 2.登录功能 3.查看余额 4.提现功能 5.还款功能 6.转账功能 7.查看流水 8.购物功能 9.查看购物车 10.管理员功能 ========== end ============ ''') choice = input('请输入功能编号:').strip() if choice not in func_dic: print('请输入正确的功能编号!') continue func_dic.get(choice)()

-admin.py

# -*- coding: utf-8 -*- ''' @Time : 2022/09/04 11:50 @Author : Rice @CSDN : C_小米同学 @FileName: admin.py ''' from core import src from interface import admin_interface # 添加用户 def add_user(): src.register() # 修改用户额度 def change_balance(): while True: change_user = input('请输入需要修改额度的用户').strip() money = input('请输入需要修改的用户额度:').strip() if not money.isdigit(): print('请输入数字') continue flag, msg = admin_interface.change_balance_interface(change_user, money) if flag: print(msg) break else: print(msg) break # 输入修改额度 # 输入修改用户 # 调用修改额度接口 # 冻结账户 def lock_user(): while True: change_user = input('请输入需要修改额度的用户:').strip() flag, msg = admin_interface.lock_user_interface(change_user) if flag: print(msg) break else: print(msg) break # 管理员功能字典 admin_dic = { '1': add_user, '2': change_balance, '3': lock_user } def admin_run(): while True: print(''' 1、添加用户 2、修改额度 3、冻结账户 ''') choice = input('请输入管理员功能编号:').strip() # 判断功能编号是否存在 if choice not in admin_dic: print('请输入正确的功能编号!') continue # 调用用于选择的功能函数 admin_dic.get(c
                
                

-六神源码网