Python實(shí)戰(zhàn)之ATM取款機(jī)的實(shí)現(xiàn)
一、項(xiàng)目視圖分析

通過(guò)上圖,我們可以看到,一個(gè)完整的項(xiàng)目,基本包括三個(gè)部分:用戶視圖層、接口層、數(shù)據(jù)處理層,其中,用戶視圖層是用來(lái)接收用戶的數(shù)據(jù)輸入的,比如:有戶名,密碼;接口層是要接收用戶視圖層傳來(lái)的數(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(接口層,里面有很多接口:用戶接口,購(gòu)物接口,銀行接口,管理員接口,分這么細(xì)是為了“解耦合”)、db(用戶數(shù)據(jù)存放;數(shù)據(jù)處理層:主要負(fù)責(zé)數(shù)據(jù)的增、刪、改、查)、lib(公共方法:比如登錄功能的裝飾器)、log(日志文件)、readme(文檔說(shuō)明)、strat啟動(dòng)
三、完整代碼
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
# 開(kāi)始執(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ù)既寫(xiě)入文件又打印到屏幕
'level': 'DEBUG', # loggers(第一層日志級(jí)別關(guān)限制)--->handlers(第二層日志級(jí)別關(guān)卡限制)
'propagate': True, # 默認(rèn)為T(mén)rue,向上(更高level的logger)傳遞,通常設(shè)置為False即可,否則會(huì)一份日志向上層層傳遞
},
},
}
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.注冊(cè)功能
def register():
while True:
# 1)讓用戶輸入用戶名和密碼校驗(yàn)
username = input('請(qǐng)輸入用戶名:').strip()
password = input('請(qǐng)輸入密碼:').strip()
re_password = input('請(qǐng)確認(rèn)密碼:').strip()
#可以輸入自定義的金額
# 小的邏輯錯(cuò)誤:比如兩次密碼是否一致
if password == re_password:
#2)調(diào)用接口層的注冊(cè)接口,將用戶名與密碼交給接口層來(lái)進(jìn)行處理
#一個(gè)元祖
flag, msg = user_interface.register_interface(username, password)
# 3)根據(jù)flag判斷用戶注冊(cè)是否成功,用于控制break
if flag:
print(msg)
break
else:
print(msg)
# 2.登錄功能
#成功登錄了之后,一定會(huì)修改全局變量:login_user
def login():
#登錄視圖
while True:
#1)讓用戶輸入用戶名和密碼
username = input('請(qǐng)輸入用戶名:').strip()
password = input('請(qǐng)輸入密碼:').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ò)誤后,我想返回主頁(yè) #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('請(qǐng)輸入提現(xiàn)金額:').strip()
#2)判斷用戶輸入的金額是否是數(shù)字
if not input_money.isdigit(): #isdigit()-可以判斷字符串
print('請(qǐng)輸入')
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():
'''
銀行卡還款,無(wú)論是信用卡或儲(chǔ)蓄卡,是否能任意大小的金額
:return:
'''
while True:
#1) 讓用戶輸入還款金額
input_money = input('請(qǐng)輸入需要還款的金額:').strip()
#2)判斷用戶輸入的是否是數(shù)字
if not input_money.isdigit():
print('請(qǐng)輸入正確的金額')
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('請(qǐng)輸入轉(zhuǎn)賬目標(biāo)用戶').strip()
money = input('請(qǐng)輸入轉(zhuǎn)賬金額').strip()
#2)數(shù)據(jù)判斷
if not money.isdigit():
print('請(qǐng)輸入數(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('請(qǐng)輸入正確的金額')
# 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)前用戶沒(méi)有流水!')
# 8.購(gòu)物功能
@common.login_auth
def shop():
#不從文件中讀取商品數(shù)據(jù),直接寫(xiě)
#創(chuàng)建商品列表
# shop_list = {
# '0': {'name': '包子', 'price': 30}
# }
shop_list = [
['包子', 3], #0
['可樂(lè)', 5], #1
['book', 200],
['pc', 9999],
]
#初始化當(dāng)前購(gòu)物車
shopping_car = {} #{'商品名稱':['單價(jià)','數(shù)量']]}
while True:
#枚舉:enumerate(可迭代對(duì)象)--->元祖(可迭代對(duì)象的索引,索引對(duì)應(yīng)的值)
for index, shop in enumerate(shop_list):
shop_name, shop_price = shop
print(f'商品編號(hào)為{index}, 商品名稱{shop_name}, 商品單價(jià):{shop_price}')
print(shop)
choice = input('請(qǐng)輸入商品編號(hào):(是否結(jié)賬輸入y or n)').strip()
#讓用戶根據(jù)商品編號(hào)進(jìn)行選擇
#輸入的是y進(jìn)行支付結(jié)算功能
if choice == 'y':
if not shopping_car:
print('購(gòu)物車是空的,不能支付,請(qǐng)重新輸入')
continue
#調(diào)用支付接口進(jìn)行支付
flag, msg = shop_interface.shopping_interface(login_user,shopping_car)
if flag:
print(msg)
break
else:
print(msg)
#輸入的是n添加購(gòu)物車(把shopping_car添加到j(luò)son中)
elif choice == 'n':
#調(diào)用添加購(gòu)物車接口
if not shopping_car:
print('購(gòu)物車是空的,不能添加,請(qǐng)重新輸入')
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('請(qǐng)輸入正確的編號(hào)!')
continue
if not choice.isdigit():
print('請(qǐng)輸入正確的編號(hào)!')
continue
choice = int(choice)
if choice not in range(len(shop_list)):
print('請(qǐng)輸入正確的編號(hào)!')
continue
shop_name, shop_price = shop_list[choice]
#加入購(gòu)物車
#判斷用戶選擇的商品是否重復(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.查看購(gòu)物車
@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 + 購(gòu)物車 =======
1.注冊(cè)功能
2.登錄功能
3.查看余額
4.提現(xiàn)功能
5.還款功能
6.轉(zhuǎn)賬功能
7.查看流水
8.購(gòu)物功能
9.查看購(gòu)物車
10.管理員功能
========== end ============
''')
choice = input('請(qǐng)輸入功能編號(hào):').strip()
if choice not in func_dic:
print('請(qǐng)輸入正確的功能編號(hào)!')
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('請(qǐng)輸入需要修改額度的用戶').strip()
money = input('請(qǐng)輸入需要修改的用戶額度:').strip()
if not money.isdigit():
print('請(qǐng)輸入數(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('請(qǐng)輸入需要修改額度的用戶:').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('請(qǐng)輸入管理員功能編號(hào):').strip()
# 判斷功能編號(hào)是否存在
if choice not in admin_dic:
print('請(qǐng)輸入正確的功能編號(hào)!')
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)
#注冊(cè)接口
def register_interface(username, password, balance=5000):
# 2)查看用戶是否存在
#2.1)調(diào)用 數(shù)據(jù)處理層中的select函數(shù),會(huì)返回用戶字典或None
user_dic = db_handler.select(username)
#若用戶存在,則return,告訴用戶重新輸入(是通過(guò)用戶名來(lái)判斷是否存在的,跟密碼沒(méi)關(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': [],
# 用于記錄用戶購(gòu)物車
'shop_car': {},
# locked: 用于記錄用戶是否被凍結(jié)
# False:未凍結(jié) True:已凍結(jié)
'locked': False
}
#3.2)保存數(shù)據(jù)
db_handler.save(user_dic)
msg = f'{username} 用戶注冊(cè)成功'
#記錄日志
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
'''
'''
商城購(gòu)物接口層
'''
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, '支付失敗,金額不足'
#購(gòu)物車添加接口
def add_shop_car_interface(login_user, shopping_car):
#獲取當(dāng)前用戶的購(gòu)物車
user_dic = db_handler.select(login_user)
shop_car = user_dic.get('shop_car')
#添加購(gòu)物車
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, '添加購(gòu)物車成功'
#查看購(gòu)物車接口
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)用戶的錢(qiá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.給用戶加錢(qián)操作
:param username:
:param money:
:return:
'''
#1.獲取用戶字典
user_dic = db_handler.select(username)
#2.直接做加錢(qián)的操作
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ù)處理層
-專門(mén)用戶處理數(shù)據(jù)
'''
import json
import os
from conf import settings
#查看數(shù)據(jù)
def select(username):
#1)接收接口層傳過(guò)來(lái)的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)打開(kāi)數(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('使用功能前,請(qǐng)先登錄')
src.login()
return inner
#添加日子功能:(日志功能在接口層使用)
#獲取日志功能
#獲取日志對(duì)象
def get_logger(log_type):
'''
:param log_type: 比如是user日子,bank日子,購(gòu)物商城日志
:return:
'''
#1、加載日志配置信息
logging.config.dictConfig(settings.LOGGING_DIC)
#2、獲取日志對(duì)象
logger = logging.getLogger(log_type)
return logger7.readme
# 項(xiàng)目說(shuō)明書(shū)
## 項(xiàng)目:ATM + 購(gòu)物車
# 項(xiàng)目需求
模擬實(shí)現(xiàn)一個(gè)ATM + 購(gòu)物商城程序
1.額度 15000或自定義 ->注冊(cè)功能
2.實(shí)現(xiàn)購(gòu)物商城,買東西加入 購(gòu)物車,調(diào)用信用卡接口結(jié)賬-》購(gòu)物、支付
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.注冊(cè)功能
2.登錄功能
3.查看余額
4.提現(xiàn)功能
5.還款功能
6.轉(zhuǎn)賬功能
7.查看流水
8.購(gòu)物功能
9.查看購(gòu)物車
10.管理員功能
# 一個(gè)項(xiàng)目如何從無(wú)到有
## 一 需求分析
1.拿到項(xiàng)目,想在客戶那里討論需求
商量項(xiàng)目的功能能否實(shí)現(xiàn),周期,價(jià)格,得到需求文檔
2.最后在公司內(nèi)部需要開(kāi)一次會(huì)議,得到最終的開(kāi)發(fā)文檔,
交給不同的崗位的程序員進(jìn)行開(kāi)發(fā)
-Python:后端,爬蟲(chóng)
-不同的崗位:
-UI界面設(shè)計(jì):
-設(shè)計(jì)軟件的布局,會(huì)根據(jù)軟件的外觀切成一張張圖片
-前端:
-拿到UI交給他的圖片,去搭建網(wǎng)頁(yè)頁(yè)面
-設(shè)計(jì)一些頁(yè)面中,哪些位置需要接收數(shù)據(jù),需要進(jìn)行數(shù)據(jù)交互
-后端:
-直接核心的業(yè)務(wù)邏輯,調(diào)度數(shù)據(jù)庫(kù)進(jìn)行數(shù)據(jù)的增刪
-測(cè)試:
-會(huì)給代碼進(jìn)行全面測(cè)試,比如壓力測(cè)試,界面測(cè)試
-運(yùn)維
-部署項(xiàng)目
## 二 程序的架構(gòu)設(shè)計(jì)
### 1、程序設(shè)計(jì)的好處
1)思路不清晰
2)不會(huì)出現(xiàn)寫(xiě)一半推翻重寫(xiě)
3)方便自己或以后的同時(shí)更好維護(hù)
### 2、 三層架構(gòu)設(shè)計(jì)的好處
1)每個(gè)功能都分成三部分
2)如果用戶更換不同的用戶界面或不同的數(shù)據(jù)儲(chǔ)存機(jī)制,這樣
都不會(huì)影響接口層的核心邏輯代碼。拓展性強(qiáng)
3)可以在接口層,準(zhǔn)確的記錄接口和流水
### 3、三層架構(gòu)
#### 一 用戶視圖層
用于與用戶交互的,可以接受用戶輸入,打印接口返回的數(shù)據(jù)
#### 二 邏輯接口層
接受 用戶視圖層 傳遞過(guò)來(lái)的參數(shù),根據(jù)邏輯判斷調(diào)用數(shù)據(jù)層加以處理,
并返回一個(gè)結(jié)果給用戶視圖層
#### 三 數(shù)據(jù)處理層
接受接口層傳遞過(guò)來(lái)的參數(shù),做數(shù)據(jù)的
- 保存 save()
- 查看數(shù)據(jù) select()
- 更新數(shù)據(jù)
- 刪除數(shù)據(jù)
## 三 分任務(wù)開(kāi)發(fā)
## 四 測(cè)試
## 五 上線
# 統(tǒng)計(jì)代碼以上就是Python實(shí)戰(zhàn)之ATM取款機(jī)的實(shí)現(xiàn)的詳細(xì)內(nèi)容,更多關(guān)于Python ATM取款機(jī)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Caffe均值文件mean.binaryproto轉(zhuǎn)mean.npy的方法
今天小編就為大家分享一篇Caffe均值文件mean.binaryproto轉(zhuǎn)mean.npy的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
python數(shù)據(jù)結(jié)構(gòu)的排序算法
下面是是對(duì)python數(shù)據(jù)結(jié)構(gòu)的排序算法的一些講解及示意圖,感興趣的小伙伴一起來(lái)學(xué)習(xí)吧2021-08-08
實(shí)例講解python中的序列化知識(shí)點(diǎn)
本篇文章通過(guò)代碼實(shí)例給大家詳細(xì)分享了關(guān)于python中的序列化知識(shí)點(diǎn)內(nèi)容,有興趣的朋友們可以學(xué)習(xí)下。2018-10-10
python實(shí)例小練習(xí)之Turtle繪制南方的雪花
Turtle庫(kù)是Python語(yǔ)言中一個(gè)很流行的繪制圖像的函數(shù)庫(kù),想象一個(gè)小烏龜,在一個(gè)橫軸為x、縱軸為y的坐標(biāo)系原點(diǎn),(0,0)位置開(kāi)始,它根據(jù)一組函數(shù)指令的控制,在這個(gè)平面坐標(biāo)系中移動(dòng),從而在它爬行的路徑上繪制了圖形2021-09-09
Python構(gòu)建一個(gè)文檔掃描器的實(shí)現(xiàn)
本文主要介紹了Python構(gòu)建一個(gè)文檔掃描器的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03
Python使用Joblib模塊實(shí)現(xiàn)加快任務(wù)處理速度
在Python編程中,處理大規(guī)模數(shù)據(jù)或者進(jìn)行復(fù)雜的計(jì)算任務(wù)時(shí),通常需要考慮如何提高程序的運(yùn)行效率,本文主要介紹了如何使用Joblib模塊來(lái)加快任務(wù)處理速度,需要的可以參考下2024-03-03
解決Jupyter無(wú)法導(dǎo)入已安裝的 module問(wèn)題
這篇文章主要介紹了解決Jupyter無(wú)法導(dǎo)入已安裝的 module問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-04-04

