ATM 购物车
一个项目是如何从无到有的
代码语言:javascript复制'''
项目的由来,几个阶段
0.采集项目需求
1.需求分析
2.程序的架构设计
3.分任务开发
4.测试
5.上线运行
'''
需求分析: # 对项目需求进行分析,并提取出相应的功能
代码语言:javascript复制 '''
- 额度 15000或自定义 --> 注册功能
- 实现购物商城,买东西加入购物车,调用信用卡接口结账 --> 购物车,支付(结账)功能
- 可以提现,手续费5% --> 提现
- 支持多账户登录 --> 登录
- 支持账户间转账 --> 转账
- 记录每月日常消费流水 --> 记录流水
- 提供还款接口 --> 还款
- ATM记录操作日志 --> 日志功能
- 提供管理接口,包括添加账户、用户额度,冻结账户等... --> 管理员功能
- 用户认证功能 --> 登录认证(装饰器)
'''
程序架构设计
代码语言:javascript复制'''
用户功能层:
负责接收用户输入的内容,并返回结果给用户(还可以做一些小的判断)
接口层:
处理业务逻辑
数据处理层:
增、删、改、查
三层架构的好处:
代码结构清晰,一层是一层的
低耦合,可扩展性强
部分之间联系不是特别固定,好扩展
比如用户层我不用cmd了,改用网页,改用APP,接口层级数据处理层不需要改动直接就可以用了
易维护、管理
出现bug比较好定位,要修改配置也比较方便,扩展功能也是,可以很快定位到目标代码,不用很长的代码翻来翻去
'''
分任务开发
代码语言:javascript复制'''
- CTO 首席技术官
- 技术总监
- 架构师
- 项目经理
- 普通开发
UI:用户界面设计师
前段:网页的开发
后端:写业务逻辑、接口的
测试:测试软件
运维:项目部署上线
'''
测试
代码语言:javascript复制'''
- 手动测试
传统人工去手动测试
- 自动化测试
通过脚本模拟人的行为,自动化执行测试
- 黑盒测试:
对用户界面进行测试
- 白盒测试:
对软件的性能进行测试,例如每分钟能接收多少并发量
'''
上线运行: # 将项目交给运维人员上线
部分流程具体案例
功能需求
代码语言:javascript复制'''
- 额度15000 ---> 注册功能
- 可以提现,手续费5% ---> 提现
- 支持账户间转账 ---> 转账
- 记录消费流水 ---> 记录流水
- 提供还款接口 ---> 还款
- 用户认证功能 ---> 登陆认证,使用装饰器
'''
本文程序功能
目录规范及三层架构
各文件代码
代码语言:javascript复制import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
from core import src
if __name__ == '__main__':
src.run()
代码语言:javascript复制from interface import user_interface
from lib import common
from interface import bank_interface
def register():
while True:
username = input("请输入用户名>>>:").strip()
if username == 'q':
break
if user_interface.check_user_exits(username):
print("用户名已存在,请重新输入")
continue
pwd = input("请输入密码>>>:").strip()
repwd = input("请再次输入密码>>>:").strip()
if pwd != repwd:
print("两次密码不一致,请重新输入")
continue
if user_interface.register(username, pwd):
print(f"{username}用户注册成功")
break
def login():
while True:
username = input("请输入用户名>>>:").strip()
if username == 'q':
return False
flag = user_interface.check_user_exits(username)
if not flag:
print(f"用户{username}不存在,请重试")
continue
pwd = input("请输入密码>>>:").strip()
flag = user_interface.login(username, pwd)
if not flag:
print("密码不正确,请重试")
continue
print(f"{username}您好,欢迎登录!")
break
@common.login_auth
def check_balance():
username = current_user_dict.get('username')
balance = user_interface.get_balance(username)
print(f"{username}您好,您的账户余额为{balance}元")
@common.login_auth
def repay():
while True:
username = current_user_dict.get('username')
money = input("请输入还款金额>>>:").strip()
if not money.isdigit():
print("请正确输入金额!")
continue
money = int(money)
flag = bank_interface.repay(username, money)
if flag:
print(f"{username}您好,您已成功还款{money}元")
break
else:
print("还款失败,请您重试")
@common.login_auth
def withdraw():
while True:
username = current_user_dict.get('username')
money = input("请输入提现金额>>>:").strip()
if not money.isdigit():
print("请正确输入金额!")
continue
money = int(money)
flag = bank_interface.withdraw(username, money)
if flag:
print(f"{username}您好,您已成功提现{money}元,手续费{money*0.05}元,现余额为{current_user_dict['balance']}元")
break
else:
print("还款失败,请您重试")
pass
@common.login_auth
def transfer():
while True:
username = current_user_dict.get('username')
target_user = input("请输入转账收款人>>>:").strip()
if target_user == 'q':
break
if target_user == username:
continue
flag = user_interface.check_user_exits(target_user)
if not flag:
print(f"{target_user}用户不存在,请重试")
continue
money = input("请输入转账金额>>>:").strip()
if not money.isdigit():
print("请正确输入金额!")
continue
money = int(money)
if money <= current_user_dict['balance']:
flag = bank_interface.transfer(username, target_user, money)
if flag:
print(f"您已成功向{target_user}转账{money}元,现余额为{current_user_dict['balance']}元")
break
print("转账失败,请重试")
else:
print("转账失败,转账金额大于您的余额")
@common.login_auth
def check_flow():
username = current_user_dict.get('username')
flow = user_interface.check_flow(username)
print(f"{username}您好,您的个人流水如下:")
for i in flow:
print(i)
@common.login_auth
def logout():
flag = user_interface.logout()
if flag:
print(f"用户注销登录成功,欢迎下次光临")
func_list = {
"1": register,
"2": login,
"3": check_balance,
"4": repay,
"5": withdraw,
"6": transfer,
"7": logout,
"8": check_flow
}
current_user_dict = {
"username": None,
"pwd": None,
'balance': None,
'flow': [],
'shop_cart': {},
'lock': None,
}
def run():
while True:
print("""
1.注册 2.登录 3.查看余额
4.还款 5.提现 6.转账
7.注销登录 8.检查流水
""")
choice = input("请输入功能编号(Q退出)>>>:").strip()
if choice == 'q':
print("感谢您的使用,祝您生活越快~")
break
elif choice in func_list:
func_list[choice]()
else:
print("您的输入有误,请重新输入!")
代码语言:javascript复制from db import db_handler
from lib import common
from core import src
def check_user_exits(username):
user_dict = db_handler.select(username)
if not user_dict:
return False
return True
def register(username, pwd, balance=15000):
pwd = common.get_md5(pwd)
user_dict = {
"username": username,
"pwd": pwd,
'balance': balance,
'flow': [],
'shop_cart': {},
'lock': False,
}
return db_handler.save(user_dict)
def login(username: str, pwd: str):
user_dict = db_handler.select(username)
pwd = common.get_md5(pwd)
if not user_dict:
return False
if user_dict['pwd'] != pwd:
return False
src.current_user_dict = user_dict
return True
def get_balance(username: str) -> float:
user_dict = db_handler.select(username)
src.current_user_dict['balance'] = user_dict['balance']
return user_dict.get('balance')
def check_flow(username):
user_dict = db_handler.select(username)
return user_dict['flow']
def logout():
src.current_user_dict = {
"username": None,
"pwd": None,
'balance': None,
'flow': [],
'shop_cart': {},
'lock': None,
}
return True
代码语言:javascript复制from db import db_handler
from core import src
def repay(username, money) -> bool:
user_dict = db_handler.select(username)
user_dict['balance'] = money
user_dict['flow'].append(f"{username}成功还款{money}元,现余额为{user_dict.get('balance')}")
src.current_user_dict = user_dict
return db_handler.save(user_dict)
def withdraw(username, money):
user_dict = db_handler.select(username)
if user_dict['balance'] >= money*1.05:
user_dict['balance'] -= money*1.05
user_dict['flow'].append(f"{username}提现{money}元,手续费{money*0.05}元,现余额为{user_dict['balance']}元")
src.current_user_dict = user_dict
return db_handler.save(user_dict)
else:
return False
def transfer(username, targer_user, money):
user_dict = db_handler.select(username)
user_dict['balance'] -= money
user_dict['flow'].append(f"{username}向{targer_user}转账{money}元,现余额为{user_dict['balance']}元")
src.current_user_dict = user_dict
if not db_handler.save(user_dict):
return False
targer_user_dict = db_handler.select(targer_user)
targer_user_dict['balance'] = money
targer_user_dict['flow'].append(f"{targer_user}接收到{username}转账{money}元,现余额为{targer_user_dict['balance']}元")
if not db_handler.save(targer_user_dict):
# 这里存储失败了,那么转账人(username)的扣款操作应该要退回
return False
return True
代码语言:javascript复制import os
from conf import settings
import json
DB_DIR = os.path.join(settings.BASE_DIR, "db")
def select(username: str):
user_file_path = os.path.join(DB_DIR, f"{username}.json")
if not os.path.exists(user_file_path):
return False
with open(user_file_path, 'r', encoding='utf-8') as f:
user_dict = json.load(f)
return user_dict
def save(user_dict: dict) -> bool:
user_file_path = os.path.join(DB_DIR, f"{user_dict['username']}.json")
with open(user_file_path, 'w', encoding='utf-8') as f:
json.dump(user_dict, f)
return True
代码语言:javascript复制import hashlib
from core import src
def get_md5(string: str) -> str:
md = hashlib.md5()
md.update('md5_salt'.encode('utf-8'))
md.update(string.encode('utf-8'))
return md.hexdigest()
def login_auth(func):
def inner(*args, **kwargs):
if not src.current_user_dict.get('username'):
print("请先登录后再操作!")
else:
res = func(*args, **kwargs)
return res
return inner
代码语言:javascript复制import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
今日小错误
找了半天才发现问题,记住报错,下次看到类似报错就可以立马发现问题了
代码语言:javascript复制file_path = r'E:PyCharm 2019.1.3ATM SHOP2libcommon.py'
# with open(file_path, 'r', 'utf-8') as f: # 报错(不要忘了写 encoding!)
# print('hello')
# Traceback (most recent call last):
# File "E:/PyCharm 2019.1.3/ATM SHOP2/test.py", line 2, in <module>
# with open(file_path, 'r', 'utf-8') as f:
# TypeError: an integer is required (got type str)
with open(file_path, 'r', encoding='utf-8') as f:
print('hello')
# hello