ATM + 購物車
需求分析
'''
- 額度 15000或自定義
- 實現購物商城,買東西加入 購物車,調用信用卡接口結賬
- 可以提現,手續費5%
- 支持多賬戶登錄
- 支持賬戶間轉賬
- 記錄每月日常消費流水
- 提供還款接口
- ATM記錄操作日志
- 提供管理接口,包括添加賬戶、用戶額度,凍結賬戶等...
- 用戶認證功能
'''
一個項目是如何從無到有的
# 1、需求分析:
'''
開發項目前,都必須找到相應的客戶,讓客戶給企業提出項目的需求,以及需要實現的功能有哪些,拿到需求后再提取出一些列功能。
'''
# 2、設計程序以及程序的架構
'''
在所有一線開發的企業里,在一個項目開發前,都應該設計程序,那樣會讓程序解開耦合,從而提高項目的管理以及開發的效率。
'''
# 3、分任務開發
'''
在公司里面,開發項目需要這幾種崗位人才:
UI設計: 軟件的外觀設計者,通過一些炫酷的設計,提高用戶的對軟件的體驗感。
前端開發: UI設計僅僅只是把一些外觀圖設計出來,那前端開發需要把UI的設計圖拿到之后,對軟件界面的進行排版。
后端開發(python): 項目里業務以及功能的邏輯處理!
'''
# 4、項目測試
'''
測試工程師: 對后端以及前端開發好的項目進行功能和性能測試,測試的過程中出現bug就會立即讓開發人員去修整,待整個項目幾乎沒有bug,以及性能達到項目實際的預期,就會準備上線運行。
測試分為兩種:
1.黑盒測試:
通過對軟件界面的功能進行測試,測試一些能讓用戶看到的bug。(例如穿越火線的卡箱子等等...)
2.白盒測試:
對軟件進行性能測試,例如每秒鐘能承受多少用戶量的訪問等...
'''
# 5、上線運行
'''
運維工程師(linux): 拿到前面整個項目編寫完的代碼,部署到服務器,上線運行!
'''
程序架構
程序目錄設計
# 接下來我們寫的功能都在按照這個文件目錄來寫,請認真閱讀這個目錄所對應的功能。
'''
- ATM
- conf 配置文件文件夾
- setting.py
- lib 公共方法文件夾
- common.py 公共方法文件
- interface 接口層文件夾
- user.py 用戶接口文件
- bank.py 銀行接口文件
- core 用戶功能文件夾
- src.py 視圖文件
- db 數據處理層文件夾
- db_handler.py 數據處理功能文件
- start.py 程序的入口文件,啟動文件
- readme 程序的說明文件
'''
程序模塊
# confs
## settings.py(主要存一些常量,主要是功能界面,商品列表,日志路徑,數據路徑)
import os
import sys
########
#功能展示#
#########
FUNC_MSG = {
'0': "注銷",
'1': "登錄",
'2': "注冊",
'3': "查看余額",
'4': "轉賬",
'5': "還款",
'6': "取現",
'7': "查看流水",
'8': "購物",
'9': "購物車",
}
SHOP_DIST = [
['餅干', 10],
['薯片', 10],
['火腿腸', 20],
['雪糕', 10],
['別墅', 1000000]
]
# LOG_PATH = os.path
ATM_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DB_PATH = os.path.join(ATM_PATH, 'db')
#core
## src.py(主界面,主要是和用戶交互的界面)
from libs import common
from db import db_handler
from interface import user
from interface import bank
from confs import settings
#設置一個字典類型的全局變量,用于判斷是否登錄
user_info = {
'user': None
}
# 注銷功能
def logout():
user_info['user'] = None # 將values值設置為空
print('注銷成功')
# 登錄模塊
def login():
count = 0 #計數,連續三次注冊失敗,退出功能
print("歡迎來到登錄功能")
while True:
username, pwd = common.input_username_pwd() # 調用輸入接口,接收輸入信息
flag = common.check_user(username) # 調用核對用戶接口,驗證用戶是否已經存在
if not flag:
print('未注冊')
break
flag, msg = user.login_interface(username, pwd)
if flag:
user_info['user'] = username #登錄成功,賦值
print(user_info['user'])
print(msg)
break
else:
print(msg)
count += 1
if count == 3:
break
#注冊模塊
def register():
print("歡迎來到注冊模塊")
username, pwd = common.input_username_pwd()
flag = common.check_user(username) #先判斷是否存在
if flag:
print("無需注冊,用戶已經存在")
else:
msg = user.register_interface(username, pwd) # 調用注冊接口
print(msg)
@common.login_auth # 加語法糖,查看余額前先登錄
def check_extra():
print("歡迎來到查看余額模塊")
msg = user.check_extra(user_info.get('user')) # 調用查看余額接口
print(msg)
# 轉賬,需要有發起人,接收人和錢
@common.login_auth
def transfer():
print("歡迎來到轉賬模塊")
while True:
from_username = user_info.get('user')
to_username = input('請輸入你要轉賬的用戶名:')
flag = common.check_user(to_username) #先判斷用戶是否存在
if flag:
money = input("請輸入你要轉賬的金額").strip()
if not money.isdigit():
print("請輸入數字")
continue
money = int(money)
msg = bank.transfer_interface(from_username, to_username, money) #調用轉賬接口
print(msg)
break
print("用戶不存在")
@common.login_auth
#還款模塊
def repay():
print("歡迎來到還款模塊")
msg = bank.repay_interface(user_info['user']) #調用還款接口
print(msg)
@common.login_auth
#取現功能
def withdraw():
print("歡迎來到取現功能")
while True:
money = input("請輸入取現金額:")
if not money.isdigit():
print("輸入必須是數字")
continue
else:
money = int(money)
msg = bank.withdraw_interface(user_info['user'], money)#調用取現模塊
print(msg)
break
@common.login_auth
#查看流水模塊
def history():
print("歡迎來到查看流水模塊")
msg = bank.bank_flow_interface(user_info['user'])#調用查看流水模塊
print(msg)
@common.login_auth
#購物模塊
def shopping():
print("歡迎來到購物模塊")
while True:
for index, goods in enumerate(settings.SHOP_DIST): #用列表存儲的商品輸出,得到索引和有兩個元素的商品小列表
print(f'{index} {goods}')
goods_n = input("請輸入你要的商品編號,按q退出:")
if goods_n == 'q':
break
if not goods_n.isdigit():
print("輸入有誤")
continue
goods_n = int(goods_n)
goods = settings.SHOP_DIST[goods_n] # 拿到的商品是一個有兩個值(第一個是商品名,第二個是價格)的列表
goods_name = goods[0] # 列表第一個元素是商品名
user_dic = db_handler.read_json(user_info['user']) # 拿到當前用戶的數據字典
my_money = user_dic['extra'] # 把用戶字典中的查看額度取出來
if goods[-1] <= my_money: # 如果商品金額小于額度,可以買
if goods_name in user_dic['shop_car']:
user_dic['shop_car'][goods_name] += goods[-1] # 如果我的字典里面的購物車字典有該商品,把價格加上去
else:
user_dic['shop_car'][goods_name] = goods[-1] # 如果我的字典里面的購物車字典沒有該商品,把商品名加上去,價格加上去
db_handler.save_json(user_dic) # 做完修改要保存
print(f'{goods_name}加入購物車成功')
else:
print("余額不足")
break
print(f"你的購物車是{user_dic['shop_car']}") # 買完之后要打印一下
@common.login_auth
# 購物車模塊
def shopping_car():
print("歡迎來到購物車模塊")
while True:
user_dic = db_handler.read_json(user_info['user']) #用戶數據讀取
goods_dic = user_dic['shop_car'] # 拿到用戶數據字典的購物車字典
cost_choice = input(f"購物車是{goods_dic},是否選擇購買y/n:") # 判斷是否購買
if cost_choice == 'n':
break
elif cost_choice == 'y':
cost = sum(goods_dic.values()) # 把用戶購物車字典中的值求和得到總價
if cost > user_dic['extra']:
print('余額不足,支付失敗')
break
user_dic['extra'] -= cost # 支付就是把用戶字典的額度減去總價
db_handler.save_json(user_dic) # 操作完了保存
print("支付成功")
break
def run():
FUNC_DICT = {
'0':logout,
'1':login,
'2':register,
'3':check_extra,
'4':transfer,
'5':repay,
'6':withdraw,
'7':history,
'8':shopping,
'9':shopping_car,
}
from confs.settings import FUNC_MSG
while True:
for k, v in FUNC_MSG.items(): # 把功能列表打印出來展示給用戶,包括序號和值
print(f'{k}: {v}')
func_choice = input("請輸入你需要的功能,按q退出>>>>>").strip()
if func_choice == 'q':
break
if not FUNC_DICT.get(func_choice):
print('輸入有誤,請重新輸入')
continue
func = FUNC_DICT.get(func_choice)
func()
if __name__ == '__main__':
run()
# db
## db_handler(數據處理模塊,主要是用戶存取數據,格式是json)
import os
import json
from confs import settings
import sys
def save_json(user_dic): #存數據,記得存的是字典,所有拼接名字的時候要把字典里面的用戶名取出來
user_path = os.path.join(settings.DB_PATH,
f'{user_dic.get("username")}.json') #拼接路徑
with open(user_path, 'w', encoding='utf8') as fw:
json.dump(user_dic, fw) # 存進去,第一個參數是數據,第二個是文件,就是把第一個數據存到第二個文件中
def read_json(username):# 讀數據, 拼路徑,讀出來數據就可以了,記得返回
user_path = os.path.join(settings.DB_PATH, f'{username}.json')
if os.path.exists(user_path):
with open(user_path, 'r', encoding='utf8') as fr:
data = json.load(fr)
return data
#interface(主要就是銀行和用戶兩個接口)
## bank.py
from db import db_handler
def transfer_interface(from_username, to_username, money):# 轉賬接口,
from_user_dic = db_handler.read_json(from_username) # 讀當前用戶數據
to_user_dict = db_handler.read_json(to_username) # 讀要轉賬用戶數據
my_money = from_user_dic['extra'] # 把用戶的錢單獨拿出來
if money > my_money:
return '錢不夠'
else:
from_user_dic['extra'] -= money # 我減錢
to_user_dict['extra'] += money # 對方加錢
msg_f = f'已向{to_username}轉賬{money}元' #記錄我的信息
msg_t = f'已收到{from_username}轉賬{money}元' #記錄對方信息
from_user_dic['bank_flow'].append(msg_f) #加我流水
to_user_dict['bank_flow'].append(msg_t) #加對方流水
db_handler.save_json(from_user_dic) #存數據
db_handler.save_json(to_user_dict) #存數據
return msg_f #返回操作信息
def repay_interface(username): #還款接口
while True:
money = input("請輸入你的還款金額:").strip()
if not money.isdigit():
print('請輸入數字')
else:
money = int(money)
user_dic = db_handler.read_json(username) #拿用戶數據
user_dic['extra'] += money # 字典里面加錢
db_handler.save_json(user_dic) #保存數據
return f'{username}已成功還款{money}' #返回信息
def withdraw_interface(username, money):# 取現接口
user_dic = db_handler.read_json(username) #拿用戶信息
if money*1.005 > user_dic['extra']:
return "錢不夠"
else:
user_dic['extra'] -= money*1.05 # 減錢
db_handler.save_json(user_dic) # 存數據
return f'{username}已成功取現{money}元'
def bank_flow_interface(username): # 銀行流水信息
user_dic = db_handler.read_json(username) # 拿用戶數據
return user_dic['bank_flow'] #返回用戶字典里的流水
## user.py(用戶接口)
from db import db_handler
from confs import settings
import os
def register_interface(username, pwd): #注冊接口
#新生成的用戶的信息字典
user_dic = {
'username': username,
'pwd': pwd,
'extra': 1500000,
'bank_flow':[],
'shop_car':{}
}
db_handler.save_json(user_dic) #保存數據
return f'{username}注冊成功'
def login_interface(username, pwd): #登錄模塊
user_data = db_handler.read_json(username) # 拿數據
if user_data['pwd'] == pwd:
return True, '登錄成功'
else:
return False, '密碼輸入錯誤'
def check_extra(username):# 查看余額接口
user_data = db_handler.read_json(username) # 拿數據
extra = user_data['extra']
return f'{username}查看了余額,余額為{extra}元'
# libs
## common.py(通用模塊)
import logging
import os
from db import db_handler
from confs import settings
import logging.config
def input_username_pwd():# 用戶輸入的模塊
username = input('請輸入用戶名>>>>').strip()
pwd = input("請輸入密碼>>>>").strip()
return username, pwd
def check_user(username): # 檢查用戶是否存在模塊
user_path = os.path.join(settings.DB_PATH, f'{username}.json') #拼接用戶路徑,判斷是否有該路徑
if os.path.exists(user_path):
return True
else:
return False
def login_auth(func): # 裝飾函數,用于驗證是否登錄,套用裝飾函數模板
from core import src
def inner(*args, **kwargs):
if src.user_info.get('user'):
res = func(*args, **kwargs)
return res
else:
print('未登錄,請去登錄!')
src.login()
return inner
#start.py (開始模塊,項目的起始點)
from core import src
import os
import sys
sys.path.append(os.path.dirname(__file__)) #一定要把當前路徑加入環境變量里
if __name__ == '__main__':
src.run()
注意點
1. 首先要把項目單獨打開,即作為根目錄。
2. 記住寫項目,尤其是需要導入模塊時,一定要寫開始的函數(start.py),可以避免出現循環導入問題,造成一些變量傳入出錯。
3. 有些時候Pycharm不能識別數據類型,就沒有提示,但不代表是錯的,只要可以運行就可以。
4. 保存的是字典,所以拼接路徑時要注意名字,取字典里key = username對應的值作為名字
5. 登錄成功后把user_info['user']賦值為輸入的用戶名
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
