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群号.同时群内也有免费的学习资 ...
随机推荐
- Delphi中 TStringList 的详细用法 good
TStringList 类是在Delphi使用最厂的一个对像,我们这里一起来看看 TStringList 的详细用法. 先把要讨论的几个属性列出来:1.CommaText2.Delimiter &am ...
- javaweb各种框架组合案例(三):maven+spring+springMVC+hibernate
1.hibernate译为"越冬",指的是给java程序员带来春天,因为java程序员无需再关心各种sql了: 2.hibernate通过java类生成数据库表,通过操作对象来映射 ...
- Linux实战型企业运维工程师试题
1.如何通过Linux配置一个局域网或者IDC机房上网网关,请给出步骤及命令?答:上网网关配置(1)开启内核转发:sed -i 's#net.ipv4.ip_forward = 0#net.ipv4. ...
- apache虚拟主机防止php网页木马vhost.conf文件配置
<VirtualHost *> DocumentRoot "/www/www.abc.com" ServerName www.abc.com ServerAlias a ...
- spring 5.x 系列第14篇 —— 整合RabbitMQ (代码配置方式)
源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 本用例关于rabbitmq的整合提供简单消 ...
- Akka-CQRS(14)- Http标准安全解决方案:OAuth2-资源使用授权
上一篇讨论了SSL/TLS安全连接,主要是一套在通信层面的数据加密解决方案.但我们更需要一套方案来验证客户端.要把不能通过验证的网络请求过滤掉. OAuth2是一套行业标准的网络资源使用授权协议,也就 ...
- Linux下,非Docker启动Elasticsearch 6.3.0,安装ik分词器插件,以及使用Kibana测试Elasticsearch,
Linux下,非Docker启动Elasticsearch 6.3.0 查看java版本,需要1.8版本 java -version yum -y install java 创建用户,因为elasti ...
- 利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法
1.利用切片操作,实现一个trim()函数,去除字符串首尾的空格,注意不要调用str的strip()方法 首先判断字符串的长度是否为0,如果是,直接返回字符串 第二,循环判断字符串的首部是否有空格,如 ...
- 从无到有构建vue实战项目(三)
四.响应式布局的实现 elemnt-ui参考bootatrap提供了响应式布局,附上地址:https://element.eleme.cn/#/zh-CN/component/layout 以下是我的 ...
- 十年后,我又开始研究SEO了
2009年的时候,我就小打小闹式地要创业了,其实就是和同学在北京阜成门开了一家特产店.但我们的想法不止在这个店,有更大的目标,目前也不便在这里展开了.反正当时我就注意到了SEO,即搜索引擎优化.通俗地 ...