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+购物车剖析一个项目的由来及流程的更多相关文章

  1. Python学习--------------Atm+购物车系统

    一.程序需求 模拟实现一个ATM + 购物商城程序: 1.额度 15000或自定义 2.实现购物商城,买东西加入 购物车,调用信用卡接口结账 3.可以提现,手续费5% 4.每月22号出账单,每月10号 ...

  2. Python实战之ATM+购物车

    ATM + 购物车 需求分析 ''' - 额度 15000或自定义 - 实现购物商城,买东西加入 购物车,调用信用卡接口结账 - 可以提现,手续费5% - 支持多账户登录 - 支持账户间转账 - 记录 ...

  3. 项目: ATM+购物车

    ATM+购物车 项目文件: 介绍 以下为文件夹层次和内容: readme.md 1. 需求 模拟银行取款 + 购物全过程 1.注册 2.登录 3.提现 4.还款 5.转账 6.查看余额 7.查看购物车 ...

  4. 阶段性项目 ATM+购物车项目

    ATM + 购物车https://www.cnblogs.com/kermitjam/articles/10687180.html readme 内容前戏: 一个项目是如何从无到有的. 一 需求分析 ...

  5. ATM + 购物车项目

    ''' 存放配置文件 ''' import os #获取项目根目录 BASE_PATH=os.path.dirname(os.path.dirname(__file__)) #获取用户目录 USER_ ...

  6. Python计算一个项目中含有的代码行数

    最近想要知道以前做过的project有多少行代码,因为文件太多,直接手工数效率太低,于是编写一个python程序用来计算一个project有多少代码行. 首先,在一个项目中,有很多子文件夹,子文件夹中 ...

  7. Python 入门基础16 -- ATM + 购物车

    ATM + 购物车 1.需求分析 2.设计程序以及程序的架构 设计程序的好处: - 扩展性强 - 逻辑清晰 3.分任务开发 4.测试 黑盒: 白盒: 对程序性能的测试 5.上线运行 # Tank -- ...

  8. 推荐:一个适合于Python新手的入门练手项目

    随着人工智能的兴起,国内掀起了一股Python学习热潮,入门级编程语言,大多选择Python,有经验的程序员,也开始学习Python,正所谓是人生苦短,我用Python 有个Python入门练手项目, ...

  9. ATM购物车程序项目规范(更新到高级版)

    ATM购物车程序(高级版) 之前的低级版本已经删除,现在的内容太多,没时间把内容上传,有时间我会把项目源码奉上! 我已经把整个项目源码传到群文件里了,需要的可以加主页qq群号.同时群内也有免费的学习资 ...

随机推荐

  1. Java实现Qt的SIGNAL-SLOT机制(保存到Map中,从而将它们关联起来,收到信号进行解析,最后反射调用)

    SIGNAL-SLOT是Qt的一大特色,使用起来十分方便.在传统的AWT和Swing编程中,我们都是为要在 监听的对象上添加Listener监听器.被监听对象中保存有Listener的列表,当相关事件 ...

  2. 使用C#的HttpWebRequest模拟登陆访问人人网

    使用任何语言做模拟登陆或者抓取访问页面,无外乎以下思路: 第一 启用一个web访问会话方法或者实例化一个web访问类,如.net中的HttpWebRequest:第二 模拟POST或者GET方式提交的 ...

  3. 线性表List

    数组array是基本的数据结构,但它的功能有限,线性表list可以认为是扩展了功能的数组.可以自动调整大小.添加和删除元素不需要其他元素移位. 根据指针数量和指向的不同,线性表分为单向链表.双向链表和 ...

  4. ABP开发框架前后端开发系列---(10)Web API调用类的简化处理

    在较早期的随笔<ABP开发框架前后端开发系列---(5)Web API调用类在Winform项目中的使用>已经介绍了Web API调用类的封装处理,虽然这些调用类我们可以使用代码生成工具快 ...

  5. RocketMQ(6)---发送普通消息(三种方式)

    发送普通消息(三种方式) RocketMQ 发送普通消息有三种实现方式:可靠同步发送.可靠异步发送.单向(Oneway)发送. 注意 :顺序消息只支持可靠同步发送. GitHub地址: https:/ ...

  6. Java类库的源码

    Java类库中的类,包括System.String.Scanner.Math.Random等:这些类也是用Java编写的. Java类库中包含数千个文件,其中的很多文件都包含数千行代码:因为Java类 ...

  7. Python将pyc转为py

    安装pip install uncompyle2, 使用uncompyle2 xxx.pyc > xxx.py

  8. java 中的一些运算符问题

    逻辑运算符 && 与 &: 在这二个与运算符中,一般用于if的判断中,A&&B,假设A的条件不满足时 则不会去判断后面的B, 如果A满足条件时就会接下来去做B条 ...

  9. idea 提示:ERROR util.Shell: Failed to locate the winutils binary in the hadoop binary path java.io.IOException解决方法

    Windows系统中的IDEA链接Linux里面的Hadoop的api时出现的问题 提示:ERROR util.Shell: Failed to locate the winutils binary ...

  10. 嵊州D3T1 山魔 烙饼问题

    嵊州D3T1 山魔 有n 座山,每座山有南北两面. 每一天,一些山的某一面(不一定相同) 会受到山魔的袭击. 但是山魔一天最多只会袭击k座山. 当每座山的每一面都被袭击过后,山魔就会离开. 那么至少要 ...