Python實(shí)戰(zhàn)之ATM取款機(jī)的實(shí)現(xiàn)
一、項(xiàng)目視圖分析
通過上圖,我們可以看到,一個(gè)完整的項(xiàng)目,基本包括三個(gè)部分:用戶視圖層、接口層、數(shù)據(jù)處理層,其中,用戶視圖層是用來接收用戶的數(shù)據(jù)輸入的,比如:有戶名,密碼;接口層是要接收用戶視圖層傳來的數(shù)據(jù),然后做判斷:名字是否存在、密碼是否正確,這就要求接口層調(diào)用數(shù)據(jù)處理層的方法;數(shù)據(jù)處理層就需要接收接口層的參數(shù),把接口層需要的增、刪、改、查的數(shù)據(jù)結(jié)果返回給接口層,接口層再把判斷的結(jié)果返回給用戶層。
二、文件結(jié)構(gòu)分析
文件主要有以下幾個(gè)部分:conf(setting.py-參數(shù)配置,比如:日志文件的配置、路徑等)、core(src.py\admin.py-用戶視圖層,分為圖通用戶和管理員)、interface(接口層,里面有很多接口:用戶接口,購物接口,銀行接口,管理員接口,分這么細(xì)是為了“解耦合”)、db(用戶數(shù)據(jù)存放;數(shù)據(jù)處理層:主要負(fù)責(zé)數(shù)據(jù)的增、刪、改、查)、lib(公共方法:比如登錄功能的裝飾器)、log(日志文件)、readme(文檔說明)、strat啟動
三、完整代碼
1.start.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:59 @Author : Rice @CSDN : C_小米同學(xué) @FileName: start.py ''' ''' 程序的入口 ''' import sys import os #添加解釋器的環(huán)境變量 sys.path.append( os.path.dirname(__file__) ) #導(dǎo)入用戶視圖層 from core import src # 開始執(zhí)行項(xiàng)目函數(shù) if __name__ == '__main__': # 1.先執(zhí)行用戶視圖層 src.run()
2.conf
-settings.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:49 @Author : Rice @CSDN : C_小米同學(xué) @FileName: settings.py ''' ''' 存放配置信息 ''' import os #獲取項(xiàng)目根目錄路勁 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' #如果不存在定義的日志目錄就創(chuàng)建一個(gè) 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', # 保存到文件,日志輪轉(zhuǎn) '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', # 日志文件的編碼,再也不用擔(dān)心中文log亂碼了 }, }, 'loggers': { # logging.getLogger(__name__)拿到的logger配置 '': { 'handlers': ['default', 'console'], # 這里把上面定義的兩個(gè)handler都加上,即log數(shù)據(jù)既寫入文件又打印到屏幕 'level': 'DEBUG', # loggers(第一層日志級別關(guān)限制)--->handlers(第二層日志級別關(guān)卡限制) 'propagate': True, # 默認(rèn)為True,向上(更高level的logger)傳遞,通常設(shè)置為False即可,否則會一份日志向上層層傳遞 }, }, } if __name__ == '__main__': print(user_path)
3.core
-src.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:51 @Author : Rice @CSDN : C_小米同學(xué) @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)讓用戶輸入用戶名和密碼校驗(yàn) username = input('請輸入用戶名:').strip() password = input('請輸入密碼:').strip() re_password = input('請確認(rèn)密碼:').strip() #可以輸入自定義的金額 # 小的邏輯錯(cuò)誤:比如兩次密碼是否一致 if password == re_password: #2)調(diào)用接口層的注冊接口,將用戶名與密碼交給接口層來進(jìn)行處理 #一個(gè)元祖 flag, msg = user_interface.register_interface(username, password) # 3)根據(jù)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)調(diào)用接口層,將數(shù)據(jù)傳給登錄接口 flag, msg = user_interface.login_interface(username, password) if flag: print(msg) global login_user login_user = username break else: print(msg) #有一個(gè)小bug,輸入錯(cuò)誤后,我想返回主頁 #d #成功登錄了# # 3.查看余額 @common.login_auth def check_balance(): #1.直接調(diào)用查看余額接口,獲取用戶余額 #裝飾器本身是有l(wèi)ogin_user balance = user_interface.check_bal_interface(login_user) print(f'用戶{login_user} 賬戶余額為:{balance}') # 4.提現(xiàn)功能 @common.login_auth def withdraw(): while True: #1)讓用戶輸入提現(xiàn)金額 input_money = input('請輸入提現(xiàn)金額:').strip() #2)判斷用戶輸入的金額是否是數(shù)字 if not input_money.isdigit(): #isdigit()-可以判斷字符串 print('請輸入') continue #3)用戶提現(xiàn)金額,將數(shù)據(jù)提現(xiàn)的金額交給接口層處理 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)判斷用戶輸入的是否是數(shù)字 if not input_money.isdigit(): print('請輸入正確的金額') continue input_money = int(input_money) #3)判斷用戶輸入的金額大于0 if input_money > 0: #4)調(diào)用還款接口 flag, msg = bank_interface.repay_interface(login_user, input_money) if flag: print(msg) break else: print('輸入的金額不能小于0') # 6.轉(zhuǎn)賬功能 @common.login_auth def transfer(): ''' 1.接收 用戶輸入的 轉(zhuǎn)賬金額 2.接收用戶輸入的 轉(zhuǎn)賬目標(biāo)用戶 :return: ''' while True: #1) 讓用戶輸入轉(zhuǎn)賬用戶與金額 to_user = input('請輸入轉(zhuǎn)賬目標(biāo)用戶').strip() money = input('請輸入轉(zhuǎn)賬金額').strip() #2)數(shù)據(jù)判斷 if not money.isdigit(): print('請輸入數(shù)字') continue money = int(money) if money > 0: #調(diào)用轉(zhuǎn)賬接口 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(): #直接調(diào)用查看流水接口 flow_list = bank_interface.check_flow_interface(login_user) if flow_list: for flow in flow_list: print(flow) else: print('當(dāng)前用戶沒有流水!') # 8.購物功能 @common.login_auth def shop(): #不從文件中讀取商品數(shù)據(jù),直接寫 #創(chuàng)建商品列表 # shop_list = { # '0': {'name': '包子', 'price': 30} # } shop_list = [ ['包子', 3], #0 ['可樂', 5], #1 ['book', 200], ['pc', 9999], ] #初始化當(dāng)前購物車 shopping_car = {} #{'商品名稱':['單價(jià)','數(shù)量']]} while True: #枚舉:enumerate(可迭代對象)--->元祖(可迭代對象的索引,索引對應(yīng)的值) for index, shop in enumerate(shop_list): shop_name, shop_price = shop print(f'商品編號為{index}, 商品名稱{shop_name}, 商品單價(jià):{shop_price}') print(shop) choice = input('請輸入商品編號:(是否結(jié)賬輸入y or n)').strip() #讓用戶根據(jù)商品編號進(jìn)行選擇 #輸入的是y進(jìn)行支付結(jié)算功能 if choice == 'y': if not shopping_car: print('購物車是空的,不能支付,請重新輸入') continue #調(diào)用支付接口進(jìn)行支付 flag, msg = shop_interface.shopping_interface(login_user,shopping_car) if flag: print(msg) break else: print(msg) #輸入的是n添加購物車(把shopping_car添加到j(luò)son中) elif choice == 'n': #調(diào)用添加購物車接口 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] #加入購物車 #判斷用戶選擇的商品是否重復(fù),重復(fù)加1 if shop_name in shopping_car: #添加商品數(shù)量 shopping_car[shop_name][1] += 1 else: #否則數(shù)量默認(rèn)為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(): ''' 管理員功能:課后作業(yè) :return: ''' from core import admin admin.admin_run() # 創(chuàng)建函數(shù)功能字典 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.提現(xiàn)功能 5.還款功能 6.轉(zhuǎn)賬功能 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_小米同學(xué) @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('請輸入數(shù)字') continue flag, msg = admin_interface.change_balance_interface(change_user, money) if flag: print(msg) break else: print(msg) break # 輸入修改額度 # 輸入修改用戶 # 調(diào)用修改額度接口 # 凍結(jié)賬戶 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、凍結(jié)賬戶 ''') choice = input('請輸入管理員功能編號:').strip() # 判斷功能編號是否存在 if choice not in admin_dic: print('請輸入正確的功能編號!') continue # 調(diào)用用于選擇的功能函數(shù) admin_dic.get(choice)()
4.interface
-user_interface.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:52 @Author : Rice @CSDN : C_小米同學(xué) @FileName: user_interface.py ''' ''' 邏輯接口層 用戶接口 ''' import json import os from conf import settings from db import db_handler from lib import common user_logger = common.get_logger('user') #user_logger.setLevel(10) #注冊接口 def register_interface(username, password, balance=5000): # 2)查看用戶是否存在 #2.1)調(diào)用 數(shù)據(jù)處理層中的select函數(shù),會返回用戶字典或None user_dic = db_handler.select(username) #若用戶存在,則return,告訴用戶重新輸入(是通過用戶名來判斷是否存在的,跟密碼沒關(guān)系) if user_dic: return False, '用戶名已存在!' #3)用戶不存在,則保存用戶數(shù)據(jù) #做密碼加密 password = common.get_pwd_md5(password) user_dic = { 'username': username, 'password': password, 'balance': balance, # 用于記錄用戶流水的列表 'flow': [], # 用于記錄用戶購物車 'shop_car': {}, # locked: 用于記錄用戶是否被凍結(jié) # False:未凍結(jié) True:已凍結(jié) 'locked': False } #3.2)保存數(shù)據(jù) db_handler.save(user_dic) msg = f'{username} 用戶注冊成功' #記錄日志 user_logger.info(msg) return True, msg #登錄接口 def login_interface(username, password): #1)先查看當(dāng)前用戶數(shù)據(jù)是否存在 user_dic = db_handler.select(username) #2)判斷用戶是否存在 #若有凍結(jié)用戶,則需要判斷是否被鎖定 if user_dic: if user_dic.get('locked'): return False, '當(dāng)前用戶已被鎖定' #給用戶輸入的密碼做一次加密 password = common.get_pwd_md5(password) #3)校驗(yàn)密碼是否一致 if password == user_dic.get('password'): msg = f'用戶{username}登錄成功!' user_logger.info(msg) return True, msg else: msg = f'用戶{username}密碼錯(cuò)誤!' user_logger.warn(msg) return False, msg msg = f'用戶{username}不存在!' user_logger.warn(msg) return False, msg #查看余額接口 def check_bal_interface(username): user_dic = db_handler.select(username) return user_dic['balance']
-shop_interface.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:53 @Author : Rice @CSDN : C_小米同學(xué) @FileName: shop_interface.py ''' ''' 商城購物接口層 ''' from db import db_handler #商品準(zhǔn)備結(jié)算接口 def shopping_interface(login_user, shopping_car): #計(jì)算消費(fèi)金額 cost = 0 for price_number in shopping_car.values(): price, number = price_number cost += (price*number) #導(dǎo)入銀行接口 from interface import bank_interface #邏輯校驗(yàn)成功后,在調(diào)用銀行支付接口 flag = bank_interface.pay_interface(login_user,cost) if flag: return True, '支付成功,準(zhǔn)備發(fā)貨' return False, '支付失敗,金額不足' #購物車添加接口 def add_shop_car_interface(login_user, shopping_car): #獲取當(dāng)前用戶的購物車 user_dic = db_handler.select(login_user) shop_car = user_dic.get('shop_car') #添加購物車 for shop_name, price_number in shopping_car.items(): #每個(gè)商品的數(shù)量 number = price_number[1] if shop_name in shop_car: user_dic['shop_car'][shop_name] += number db_handler.save(user_dic) print('添加到j(luò)son成功') else: user_dic['shop_car'].update({shop_name: price_number}) db_handler.save(user_dic) print('添加到j(luò)son成功') return True, '添加購物車成功' #查看購物車接口 def check_shop_car_interface(username): user_dic = db_handler.select(username) return user_dic.get('shop_car')
-bank_interface.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:53 @Author : Rice @CSDN : C_小米同學(xué) @FileName: bank_interface.py ''' ''' 銀行先關(guān)業(yè)務(wù)的接口 ''' from db import db_handler #提現(xiàn)接口(手續(xù)費(fèi)5%) def withdraw_interface(username, money): #1)先獲取用戶字典 user_dic = db_handler.select(username) #校驗(yàn)用戶的錢是否足夠 balance = int(user_dic.get('balance')) #本金+手續(xù)費(fèi) momey2 = int(money) * 1.05 #money是str,用int類型轉(zhuǎn)換 #判斷用戶金額是否足夠 if balance >= momey2: #2)修改用戶字典中的金額 balance -= momey2 user_dic['balance'] = balance #記錄流水 flow = f'用戶{username} 提現(xiàn)金額{money}成功,手續(xù)費(fèi)是:{momey2 - float(money)}$ 剩余{balance}' user_dic['flow'].append(flow) #3)再保存數(shù)據(jù),或更新數(shù)據(jù) db_handler.save(user_dic) # money是str,用int類型轉(zhuǎn)換 return True, flow def repay_interface(username, money): ''' 1.獲取用戶的金額 2.給用戶加錢操作 :param username: :param money: :return: ''' #1.獲取用戶字典 user_dic = db_handler.select(username) #2.直接做加錢的操作 user_dic['balance'] += money #記錄流水 flow = f'用戶{username} 還款{money}成功! 當(dāng)前額度為{user_dic["balance"]}' user_dic['flow'].append(flow) #3.調(diào)用數(shù)據(jù)處理層,將修改后的數(shù)據(jù)進(jìn)行更新 db_handler.save(user_dic) return True, flow def transfer_interface(login_user, to_user, money): ''' 1.獲取'當(dāng)前用戶' 數(shù)據(jù) 2.獲取'目標(biāo)用戶' 數(shù)據(jù) 3.獲取轉(zhuǎn)賬金額 :return: ''' login_user_dic = db_handler.select(login_user) to_user_dic = db_handler.select(to_user) if not to_user_dic: return False, '目標(biāo)用戶不存在' #4)若用戶存在,則判斷'當(dāng)前用戶的轉(zhuǎn)賬金額' 是足夠的 if login_user_dic['balance'] >= money: login_user_dic['balance'] -= money to_user_dic['balance'] += money #當(dāng)前用戶流水 login_user_flow = f'用戶{login_user} 給用戶 {to_user} 轉(zhuǎn)賬 {money}$ 成功' login_user_dic['balance'].append(login_user_flow) #目標(biāo)用戶流水 to_user_flow = f'用戶{to_user} 給用戶 {login_user} 轉(zhuǎn)賬 {money}$ 成功' to_user_dic['flow'].append(to_user_flow) #調(diào)用數(shù)據(jù)處理層,保存數(shù)據(jù) db_handler.save(login_user_dic) db_handler.save(to_user_dic) return True, login_user_flow return False, '當(dāng)前用戶轉(zhuǎn)賬金額不足' def check_flow_interface(login_user): user_dic = db_handler.select(login_user) return user_dic.get('flow') #支付接口 def pay_interface(login_user, cost): user_dic = db_handler.select(login_user) #判斷用戶金額 if user_dic.get('balance') >= cost: user_dic['balance'] -= cost flow = f'用戶消費(fèi)金額:{cost}$' user_dic['flow'].append(flow) #保存數(shù)據(jù) db_handler.save(user_dic) return True return False
-admin_interface.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/04 12:39 @Author : Rice @CSDN : C_小米同學(xué) @FileName: admin_interface.py ''' from db import db_handler from lib import common admin_logger = common.get_logger('admin') #修改額度接口 def change_balance_interface(username, money): user_dic = db_handler.select(username) if user_dic: #修改額度 user_dic['balance'] = int(money) db_handler.save(user_dic) msg = f'管理員修改用戶:{username}額度修改成功' admin_logger.info(msg) return True, '額度修改成功!' return False, '修改額度用戶不存在' #凍結(jié)賬戶接口 def lock_user_interface(username): user_dic = db_handler.select(username) if user_dic: user_dic['locked'] = True db_handler.save(user_dic) return True, f'用戶{username}凍結(jié)成功' return False, '凍結(jié)用戶不存在'
5.db
-db_handler.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:57 @Author : Rice @CSDN : C_小米同學(xué) @FileName: db_handler.py ''' ''' 數(shù)據(jù)處理層 -專門用戶處理數(shù)據(jù) ''' import json import os from conf import settings #查看數(shù)據(jù) def select(username): #1)接收接口層傳過來的username用戶名,拼接用戶json文件路勁 user_path = os.path.abspath(os.path.join(settings.USER_DATA_PATH, f'{username}.json')).replace('\\', '/') #2)校驗(yàn)用戶json文件是否存在 if os.path.exists(user_path): #3)打開數(shù)據(jù),并返回給接口層 with open(user_path, 'r', encoding='utf-8') as f: user_dic = json.load(f) # 導(dǎo)出數(shù)據(jù) return user_dic #3)不return,默認(rèn)返回return None #保存數(shù)據(jù) def save(user_dic): #1)拼接用戶的數(shù)據(jù)字典 username = user_dic.get('username') user_path = os.path.abspath(os.path.join(settings.USER_DATA_PATH, f'{username}.json')).replace('\\', '/') #2)保存用戶數(shù)據(jù) with open(user_path, 'w', encoding='utf-8') as f: # 導(dǎo)入數(shù)據(jù)(ensure_ascii=False,讓文件中的中文數(shù)據(jù)顯示更美觀) json.dump(user_dic, f, ensure_ascii=False)
6.lib
-common.py
# -*- coding: utf-8 -*- ''' @Time : 2022/09/02 14:50 @Author : Rice @CSDN : C_小米同學(xué) @FileName: common.py ''' ''' 存放公共方法 ''' import hashlib import logging.config from conf import settings def get_pwd_md5(password): md5_obj = hashlib.md5() md5_obj.update(password.encode('utf-8')) #傳入的數(shù)據(jù)需要時(shí)"字節(jié)串" salt = 'rice這是一個(gè)ATM' md5_obj.update(salt.encode('utf-8')) return md5_obj.hexdigest() #登錄認(rèn)證裝飾器 def login_auth(func): from core import src def inner(*args, **kwargs): if src.login_user: res = func(* args, ** kwargs) return res else: print('使用功能前,請先登錄') src.login() return inner #添加日子功能:(日志功能在接口層使用) #獲取日志功能 #獲取日志對象 def get_logger(log_type): ''' :param log_type: 比如是user日子,bank日子,購物商城日志 :return: ''' #1、加載日志配置信息 logging.config.dictConfig(settings.LOGGING_DIC) #2、獲取日志對象 logger = logging.getLogger(log_type) return logger
7.readme
# 項(xiàng)目說明書 ## 項(xiàng)目:ATM + 購物車 # 項(xiàng)目需求 模擬實(shí)現(xiàn)一個(gè)ATM + 購物商城程序 1.額度 15000或自定義 ->注冊功能 2.實(shí)現(xiàn)購物商城,買東西加入 購物車,調(diào)用信用卡接口結(jié)賬-》購物、支付 3.可以提現(xiàn),手續(xù)費(fèi)5%-》提現(xiàn)功能 4.支持多賬戶登錄-》登錄功能 5.支持賬戶間轉(zhuǎn)賬 -》轉(zhuǎn)賬功能 6.記錄日常消費(fèi)流水-》記錄流水功能 7.提供還款接口 -》還款功能 8.ATM記錄操作日志 —》記錄日志功能 9.提供管理接口,包括添加賬戶、用戶額度,凍結(jié)賬戶等。。。-》管理員功能 10.用戶認(rèn)證用裝飾器-》登錄認(rèn)證裝飾器 ## "用戶視圖層"展示給用戶選擇的功能 1.注冊功能 2.登錄功能 3.查看余額 4.提現(xiàn)功能 5.還款功能 6.轉(zhuǎn)賬功能 7.查看流水 8.購物功能 9.查看購物車 10.管理員功能 # 一個(gè)項(xiàng)目如何從無到有 ## 一 需求分析 1.拿到項(xiàng)目,想在客戶那里討論需求 商量項(xiàng)目的功能能否實(shí)現(xiàn),周期,價(jià)格,得到需求文檔 2.最后在公司內(nèi)部需要開一次會議,得到最終的開發(fā)文檔, 交給不同的崗位的程序員進(jìn)行開發(fā) -Python:后端,爬蟲 -不同的崗位: -UI界面設(shè)計(jì): -設(shè)計(jì)軟件的布局,會根據(jù)軟件的外觀切成一張張圖片 -前端: -拿到UI交給他的圖片,去搭建網(wǎng)頁頁面 -設(shè)計(jì)一些頁面中,哪些位置需要接收數(shù)據(jù),需要進(jìn)行數(shù)據(jù)交互 -后端: -直接核心的業(yè)務(wù)邏輯,調(diào)度數(shù)據(jù)庫進(jìn)行數(shù)據(jù)的增刪 -測試: -會給代碼進(jìn)行全面測試,比如壓力測試,界面測試 -運(yùn)維 -部署項(xiàng)目 ## 二 程序的架構(gòu)設(shè)計(jì) ### 1、程序設(shè)計(jì)的好處 1)思路不清晰 2)不會出現(xiàn)寫一半推翻重寫 3)方便自己或以后的同時(shí)更好維護(hù) ### 2、 三層架構(gòu)設(shè)計(jì)的好處 1)每個(gè)功能都分成三部分 2)如果用戶更換不同的用戶界面或不同的數(shù)據(jù)儲存機(jī)制,這樣 都不會影響接口層的核心邏輯代碼。拓展性強(qiáng) 3)可以在接口層,準(zhǔn)確的記錄接口和流水 ### 3、三層架構(gòu) #### 一 用戶視圖層 用于與用戶交互的,可以接受用戶輸入,打印接口返回的數(shù)據(jù) #### 二 邏輯接口層 接受 用戶視圖層 傳遞過來的參數(shù),根據(jù)邏輯判斷調(diào)用數(shù)據(jù)層加以處理, 并返回一個(gè)結(jié)果給用戶視圖層 #### 三 數(shù)據(jù)處理層 接受接口層傳遞過來的參數(shù),做數(shù)據(jù)的 - 保存 save() - 查看數(shù)據(jù) select() - 更新數(shù)據(jù) - 刪除數(shù)據(jù) ## 三 分任務(wù)開發(fā) ## 四 測試 ## 五 上線 # 統(tǒng)計(jì)代碼
以上就是Python實(shí)戰(zhàn)之ATM取款機(jī)的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Python ATM取款機(jī)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實(shí)現(xiàn)websocket的客戶端壓力測試
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)websocket的客戶端壓力測試,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06樹莓派與PC端在局域網(wǎng)內(nèi)運(yùn)用python實(shí)現(xiàn)即時(shí)通訊
這篇文章主要為大家詳細(xì)介紹了樹莓派與PC端在局域網(wǎng)內(nèi)運(yùn)用python實(shí)現(xiàn)即時(shí)通訊,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-06-06不歸路系列:Python入門之旅-一定要注意縮進(jìn)?。。。ㄍ扑])
這篇文章主要介紹了Python入門一定要注意縮進(jìn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Python時(shí)區(qū)設(shè)置方法與pytz查詢時(shí)區(qū)教程
這篇文章主要介紹了Python時(shí)區(qū)設(shè)置的方法和pytz查詢時(shí)區(qū)的方法,大家參考使用吧2013-11-11Python基于SMTP協(xié)議實(shí)現(xiàn)發(fā)送郵件功能詳解
這篇文章主要介紹了Python基于SMTP協(xié)議實(shí)現(xiàn)發(fā)送郵件功能,結(jié)合實(shí)例形式分析了Python使用SMTP協(xié)議實(shí)現(xiàn)郵件發(fā)送的相關(guān)操作技巧,并總結(jié)分析了Python發(fā)送純文本郵件、郵件附件、圖片郵件等相關(guān)操作技巧,需要的朋友可以參考下2018-08-08