python以ATM+购物车剖析一个项目的由来及流程
ATM+购物车
一个项目是如何从无到有的
'''
项目的由来,几个阶段
0.采集项目需求
1.需求分析
2.程序的架构设计
3.分任务开发
4.测试
5.上线运行
'''
需求分析: # 对项目需求进行分析,并提取出相应的功能
'''
- 额度 15000或自定义 --> 注册功能 - 实现购物商城,买东西加入购物车,调用信用卡接口结账 --> 购物车,支付(结账)功能 - 可以提现,手续费5% --> 提现 - 支持多账户登录 --> 登录 - 支持账户间转账 --> 转账 - 记录每月日常消费流水 --> 记录流水 - 提供还款接口 --> 还款 - ATM记录操作日志 --> 日志功能 - 提供管理接口,包括添加账户、用户额度,冻结账户等... --> 管理员功能 - 用户认证功能 --> 登录认证(装饰器)
'''
需求分析
程序架构设计
'''
用户功能层:
负责接收用户输入的内容,并返回结果给用户(还可以做一些小的判断) 接口层:
处理业务逻辑 数据处理层:
增、删、改、查 三层架构的好处:
代码结构清晰,一层是一层的
低耦合,可扩展性强
部分之间联系不是特别固定,好扩展
比如用户层我不用cmd了,改用网页,改用APP,接口层级数据处理层不需要改动直接就可以用了
易维护、管理
出现bug比较好定位,要修改配置也比较方便,扩展功能也是,可以很快定位到目标代码,不用很长的代码翻来翻去
'''
程序架构设计
分任务开发
'''
- CTO 首席技术官
- 技术总监
- 架构师
- 项目经理
- 普通开发
UI:用户界面设计师
前段:网页的开发
后端:写业务逻辑、接口的
测试:测试软件
运维:项目部署上线
'''
分任务开发
测试
'''
- 手动测试
传统人工去手动测试
- 自动化测试
通过脚本模拟人的行为,自动化执行测试 - 黑盒测试:
对用户界面进行测试
- 白盒测试:
对软件的性能进行测试,例如每分钟能接收多少并发量
'''
测试
上线运行: # 将项目交给运维人员上线
部分流程具体案例
功能需求
'''
- 额度15000 ---> 注册功能 - 可以提现,手续费5% ---> 提现 - 支持账户间转账 ---> 转账 - 记录消费流水 ---> 记录流水 - 提供还款接口 ---> 还款 - 用户认证功能 ---> 登陆认证,使用装饰器
'''
本文程序功能

目录规范及三层架构


各文件代码
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()
bin/starts.py
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 = {
"": register,
"": login,
"": check_balance,
"": repay,
"": withdraw,
"": transfer,
"": logout,
"": 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("您的输入有误,请重新输入!")
core/src.py
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
interface/user_interface.py
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
interface/bank_interface.py
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
db/db_handler.py
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
lib/common.py
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)
conf/settings.py
今日小错误
找了半天才发现问题,记住报错,下次看到类似报错就可以立马发现问题了
file_path = r'E:\PyCharm 2019.1.3\ATM+SHOP2\lib\common.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
今日小错误(encoding漏写)
python以ATM+购物车剖析一个项目的由来及流程的更多相关文章
- Python学习--------------Atm+购物车系统
一.程序需求 模拟实现一个ATM + 购物商城程序: 1.额度 15000或自定义 2.实现购物商城,买东西加入 购物车,调用信用卡接口结账 3.可以提现,手续费5% 4.每月22号出账单,每月10号 ...
- Python实战之ATM+购物车
ATM + 购物车 需求分析 ''' - 额度 15000或自定义 - 实现购物商城,买东西加入 购物车,调用信用卡接口结账 - 可以提现,手续费5% - 支持多账户登录 - 支持账户间转账 - 记录 ...
- 项目: ATM+购物车
ATM+购物车 项目文件: 介绍 以下为文件夹层次和内容: readme.md 1. 需求 模拟银行取款 + 购物全过程 1.注册 2.登录 3.提现 4.还款 5.转账 6.查看余额 7.查看购物车 ...
- 阶段性项目 ATM+购物车项目
ATM + 购物车https://www.cnblogs.com/kermitjam/articles/10687180.html readme 内容前戏: 一个项目是如何从无到有的. 一 需求分析 ...
- ATM + 购物车项目
''' 存放配置文件 ''' import os #获取项目根目录 BASE_PATH=os.path.dirname(os.path.dirname(__file__)) #获取用户目录 USER_ ...
- Python计算一个项目中含有的代码行数
最近想要知道以前做过的project有多少行代码,因为文件太多,直接手工数效率太低,于是编写一个python程序用来计算一个project有多少代码行. 首先,在一个项目中,有很多子文件夹,子文件夹中 ...
- Python 入门基础16 -- ATM + 购物车
ATM + 购物车 1.需求分析 2.设计程序以及程序的架构 设计程序的好处: - 扩展性强 - 逻辑清晰 3.分任务开发 4.测试 黑盒: 白盒: 对程序性能的测试 5.上线运行 # Tank -- ...
- 推荐:一个适合于Python新手的入门练手项目
随着人工智能的兴起,国内掀起了一股Python学习热潮,入门级编程语言,大多选择Python,有经验的程序员,也开始学习Python,正所谓是人生苦短,我用Python 有个Python入门练手项目, ...
- ATM购物车程序项目规范(更新到高级版)
ATM购物车程序(高级版) 之前的低级版本已经删除,现在的内容太多,没时间把内容上传,有时间我会把项目源码奉上! 我已经把整个项目源码传到群文件里了,需要的可以加主页qq群号.同时群内也有免费的学习资 ...
随机推荐
- WebAPI服务端内嵌在CS程序里面
有时候我们不需要将WebAPI发布到iis上运行,需要将webapi内嵌到cs程序内部,随程序一起启动,其实比较简单,需要一个类,如下 public class Startup { public st ...
- OpenSSL包括了8个功能
什么是OpenSSL 众多的密码算法.公钥基础设施标准以及SSL协议,或许这些有趣的功能会让你产生实现所有这些 算法和标准的想法.果真如此,在对你表示敬佩的同时,还是忍不住提醒你:这是一个令人望而生畏 ...
- .NET错误:未找到类型或命名空间名称
现象:编译项目时提示未找到类型或命名空间名称"... " 解决方法:如果是未找到类型,检查是否引用了类型所在的命名空间,使用using指令:如果是未找到命名空间,那么检查是否引用了 ...
- Python自学day-2
一.模块 模块分两种:标准库和第三方库,标准库是不需要安装就可以使用的库. import [模块名]:导入一个库,优先是在项目路径中寻找.自定义模块名不要和标准库模块名相同. sy ...
- JS中 【“逻辑运算”,“面试题:作用域问题”,“dom对象”】这些问题的意见见解
1.逻辑运算 || && ! ||:遇到第一个为true的值就中止并返回 &&:遇到第一个为false的值就中止并返回,如果没有false值,就返回最后一个不是fa ...
- C++ 洛谷 P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 题解
P2921 [USACO08DEC]在农场万圣节Trick or Treat on the Farm 分析: 这棵树上有且仅有一个环 两种情况: 1.讨论一个点在环上,如果在则答案与它指向点相同, 2 ...
- 微信小程序在ios下Echarts图表不能滑动的解决方案
问题现象 这个问题的现象说起来很简单. 小程序页面中有一篇很长的文章,内部有一个Echarts图表,手指上下滑动观看内容. 但是手指滑动区域在Echarts图表上时,页面却不能滑动了. 如下图: 追踪 ...
- archery 平台升级部署实践
v1.3.8 → v1.5.0 1.安装.升级python3 venv 环境 1.1.安装 python36 全新安装需要执行,升级安装可忽略 https://www.cnblogs.com/Davi ...
- CodeForces 696A:Lorenzo Von Matterhorn(map的用法)
http://codeforces.com/contest/697/problem/C C. Lorenzo Von Matterhorn time limit per test 1 second m ...
- Docker环境下的前后端分离项目部署与运维(十二)使用Portainer管理Docker
安装 docker hub地址:https://hub.docker.com/r/portainer/portainer/ # 每台服务器都要安装 docker pull portainer/port ...