ATM+购物车

项目文件:

介绍

以下为文件夹层次和内容:


readme.md

1. 需求

模拟银行取款 + 购物全过程

1.注册

2.登录

3.提现

4.还款

5.转账

6.查看余额

7.查看购物车

8.查看消费流水

9.添加购物车

10.记录日志

11.用装饰器判断用户状态

2. 编程思想

分层架构

  • 用户层: 实现用户交互. 接收用户想完成的操作
  • 接口层: 将用户操作封装成方法. 调用数据库并对数据库进行修改. 记录用户行为
  • 数据库层: 通过接口层的调用将用户数据返回给前两层进行操作. 将用户数据保存
  • 日志: 将get_logger封装成方法放置在接口层. 记录用户每一次的操作

3.总结

  1. 编程的思想值得学习. 一个项目第一步主要就是确定架构. 然后向各个模块内填写代码
  2. 各个模块之间相互调用一定要逻辑清晰. 否则容易出现bug
  3. 该项目为面向过程编程. 在打下python基础的同时为面向对象编程做基础

bin

start.py

import os
import sys path = os.path.dirname(os.path.dirname(__file__)) # 取根目录
sys.path.append(path) # 添加根目录
from core.user_command import run # 导包 if __name__ == '__main__':
# 程序入口
run()

conf

setting.py

import os

base_path = os.path.dirname(os.path.dirname(__file__))
db_path = os.path.join(base_path, "db")
log_path = os.path.join(base_path, "log")
user_dic = {"name": None} # 加上用户登录状态 # -*- encoding:utf-8 -*-
# @time: 2022/6/1 22:57
# @author: Maxs_hu """
logging配置
""" # 定义三种日志输出格式 开始
# standard_format = '%(asctime)s - %(filename)s:%(lineno)d - %(levelname)s - %(message)s'
standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \
'[%(levelname)s][%(message)s]' simple_format = '%(asctime)s - %(levelname)s - %(message)s' id_simple_format = '[%(asctime)s] %(message)s' # log文件的全路径
logfile1_path = os.path.join(log_path, "log.log")
logfile2_path = os.path.join(log_path, "another.log") # log配置字典
LOGGING_DIC = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'formatter1': {
'format': standard_format
},
'formatter2': {
'format': simple_format
},
},
'filters': {},
'handlers': {
# 打印到终端的日志
'sm': {
'level': 'DEBUG',
'class': 'logging.StreamHandler', # 打印到屏幕
'formatter': 'formatter1'
},
# 打印到文件的日志,收集info及以上的日志
'h1': {
'level': 'DEBUG',
'class': 'logging.FileHandler', # 保存到文件
'formatter': 'formatter1',
'filename': logfile1_path, # 日志文件
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
},
'h2': {
'level': 'DEBUG',
'class': 'logging.FileHandler', # 保存到文件
'formatter': 'formatter2',
'filename': logfile2_path, # 日志文件
'encoding': 'utf-8', # 日志文件的编码,再也不用担心中文log乱码了
}, },
'loggers': {
# logging.getLogger(__name__)拿到的logger配置
'logger1': {
'handlers': ['h1', 'h2', 'sm'],
'level': 'DEBUG',
'propagate': False, # 向上(更高level的logger)传递
},
},
}

core

user_command.py

from interface import user, bank, shop
from conf.setting import user_dic # 用户登录状态
from lib.common import login_auth def register():
while True:
print("***注册***")
username = input("请输入用户名:").strip()
password = input("请输入密码:").strip()
# 调用接口
state, msg = user.register_interface(username, password)
if state:
print(msg)
user_dic['name'] = username
break
else:
print(msg) def login():
while True:
print("***登录***")
username = input("请输入用户名:").strip()
password = input("请输入密码:").strip()
state, msg = user.login_interface(username, password)
if state:
user_dic["name"] = username
print(msg)
break
else:
print(msg) @login_auth # check_balance = login_auth(check_balance)
def check_balance():
print("***查看余额***")
balance = bank.balance_interface(user_dic['name'])
print(balance) @login_auth
def transfer():
while True:
print("***转账***")
username = user_dic['name']
to_username = input("请输入转账对象用户名:").strip()
amount = int(input("请输入转账金额:").strip())
state, msg = user.transfer_interface(username, to_username, amount)
if state:
print(msg)
break
else:
print(msg) @login_auth
def repay():
while True:
print("***还款***")
username = user_dic['name']
amount = int(input("请输入还款金额:").strip())
state, msg = user.repay_interface(username, amount)
if state:
print(msg)
break
else:
print(msg) @login_auth
def withdraw():
while True:
print("***取款***")
username = user_dic['name']
amount = int(input("请输入取款金额:").strip())
state, msg = bank.withdraw_interface(username, amount)
if state:
print(msg)
break
else:
print(msg) @login_auth
def check_records():
while True:
print("***查看流水***")
username = user_dic['name']
msg = user.check_interface(username)
if msg:
print(msg)
break
else:
print("暂无流水")
break @login_auth
def shopping():
print("***购物***")
username = user_dic['name']
goods_list = [
["coffee", 20],
["car", 100000],
["pen", 5],
["ice_cream", 25],
["mac_pro", 1000]
]
shopping_cart = {} # {"name": {"price": price, "count": count}, ......}
cost = 0
count = 0
# 查看账户
balance = bank.balance_interface(user_dic['name'])
# 开始购物
while True:
for i, goods in enumerate(goods_list):
print(i + 1, goods)
choice = input("请输入你要购买的商品编号(buy退出并购买, q只退出不购买):").strip()
if choice.isdigit():
choice = int(choice)
if 0 < choice <= len(goods_list) + 1:
goods_price = goods_list[choice - 1][1]
goods_name = goods_list[choice - 1][0]
if goods_price <= balance:
count += 1 # 商品数量
balance -= goods_price
cost += goods_price
shopping_cart[goods_name] = {"price": goods_price, "count": count}
print("添加购物车成功")
else:
print("余额不足")
else:
print("商品不存在")
elif choice == "q":
state, msg = shop.save_shopping(username, shopping_cart)
if state:
print(msg)
break
else:
print(msg)
break
elif choice == 'buy':
# 调用银行接口
state, msg = shop.shopping_interface(username, cost, shopping_cart)
if state:
print(msg)
break
else:
print(msg)
break
else:
print("请输入数字") @login_auth
def check_shopping_cards():
while True:
print("***查看购物车***")
username = user_dic['name']
res = shop.check_shopping_interface(username)
if res:
print(res)
break
else:
print("购物车为空")
break func_dic = {
"1": register,
"2": login,
"3": check_balance,
"4": transfer,
"5": repay,
"6": withdraw,
"7": check_records,
"8": shopping,
"9": check_shopping_cards
} def run():
while True:
print("""请选择需要办理的业务:
1.注册
2.登录
3.查看余额
4.转账
5.还款
6.取款
7.查看消费流水
8.购物
9.查看购物车
""") choice = input("请输入数字实现功能(q退出):").strip()
if choice == 'q':
print("欢迎下次光临")
break
if choice not in func_dic:
continue
func_dic[choice]() # 加上括号直接调用

db

db_handle.py

import os
from conf import setting
import json # 查数据
def select(username):
db_path = setting.db_path
user_info_path = os.path.join(db_path, "%s.json" % username) # 创建json地址
# 判断是否存在该用户
if os.path.exists(user_info_path):
with open(user_info_path, 'r', encoding='utf-8') as f:
return True, json.load(f)
else:
return False, "该用户不存在" # 存数据
def save(user_dic):
db_path = setting.db_path
user_path = os.path.join(db_path, "%s.json" % user_dic["username"])
# 将用户信息存到用户地址里面
with open(user_path, "w", encoding='utf-8') as f:
json.dump(user_dic, f) # 将字典转化成json格式
f.flush() # 将数据强行刷入硬盘

interface

bank.py

from db.db_handle import select
from db.db_handle import save
from lib import common bank_logger = common.get_logger("bank") def balance_interface(username):
state, msg = select(username)
if state:
bank_logger.info("查看余额")
return msg["balance"]
else:
return "出现未知错误" def withdraw_interface(username, amount):
state, msg = select(username)
amount = amount * 1.08 # 加上手续费
if state:
if msg['balance'] > amount:
msg['balance'] -= amount
msg['bank_flow'].append("取款%s" % amount)
save(msg)
bank_logger.info("取款")
return True, "取款成功"
else:
return False, "余额不足"
else:
return False, msg def consume_interface(username, cost):
state, msg = select(username)
if state:
msg['balance'] -= cost
msg['bank_flow'].append("消费%s" % cost)
save(msg)
bank_logger.info("消费")
return True, "消费成功"
else:
return False, msg

shop.py

from db import db_handle
from interface import bank
from lib import common shop_logger = common.get_logger("shop") def check_shopping_interface(username):
state, msg = db_handle.select(username)
shop_logger.info("查看购物车")
return msg["shopping_cart"] def shopping_interface(username, cost, shopping_cart):
state, msg = bank.consume_interface(username, cost)
if state:
state, msg = db_handle.select(username)
msg["shopping_cart"] = shopping_cart
db_handle.save(msg)
shop_logger.info("购物")
return True, "购物成功"
else:
return False, msg def save_shopping(name, shopping_cart):
state, msg = db_handle.select(name)
if state:
msg["shopping_cart"] = shopping_cart
db_handle.save(msg)
shop_logger.info("存入购物车")
return True, "存入购物车成功"
else:
return False, "存入购物车失败"

user.py

# -*- encoding:utf-8 -*-
# @time: 2022/5/29 23:00
# @author: Maxs_hu
from db import db_handle
from lib import common user_logger = common.get_logger("user") def register_interface(username, password, balance=1500):
# 调用数据库
state, msg = db_handle.select(username)
if not state:
user_account = {
"username": username,
"password": password,
"balance": balance,
"credit": balance,
"locked": False,
"bank_flow": [],
"shopping_cart": {}
}
db_handle.save(user_account)
user_logger.info("注册")
return True, "注册完成"
else:
return False, "用户已存在" def login_interface(name, password):
state, msg = db_handle.select(name)
if state:
if msg["password"] == password:
user_logger.info("登录成功")
return True, "登录"
else:
return False, "密码错误"
else:
return False, msg def transfer_interface(username, to_username, amount):
state, msg = db_handle.select(username)
# 账户扣款
if state:
if int(msg['balance']) > amount:
msg['balance'] -= amount
msg['bank_flow'].append("转账给%s%s" % (to_username, amount))
# 将修改的数据保存下来
db_handle.save(msg)
else:
return False, "余额不足"
else:
return False, msg
# 转账
flag, info = db_handle.select(to_username)
if flag:
info['balance'] += amount
info['bank_flow'].append("收到%s转账%s" % (username, amount))
# 将修改的数据保存下来
db_handle.save(info)
user_logger.info("转账")
return True, "转账成功"
else:
return False, info def repay_interface(username, amount):
state, msg = db_handle.select(username)
if state:
msg['credit'] += amount
msg['bank_flow'].append("还款%s" % amount)
db_handle.save(msg)
user_logger.info("还款")
return True, "还款成功"
else:
return False, msg def check_interface(username):
state, msg = db_handle.select(username)
user_logger.info("查看流水")
return msg['bank_flow']

lib

common.py

# -*- encoding:utf-8 -*-
# @time: 2022/5/29 22:59
# @author: Maxs_hu
from conf.setting import user_dic, LOGGING_DIC
from core import user_command
import logging.config # 用户登录状态装饰器
def login_auth(func):
def inner(*args, **kwargs):
if user_dic['name']:
res = func(*args, **kwargs)
return res
else:
user_command.login() # 调用login方法去登录
return inner # 日志
def get_logger(name):
logging.config.dictConfig(LOGGING_DIC)
my_logger = logging.getLogger('logger1')
return my_logger

log

another.log

log.log

项目: ATM+购物车的更多相关文章

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

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

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

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

  3. python以ATM+购物车剖析一个项目的由来及流程

    ATM+购物车 一个项目是如何从无到有的 ''' 项目的由来,几个阶段 0.采集项目需求 1.需求分析 2.程序的架构设计 3.分任务开发 4.测试 5.上线运行 ''' 需求分析: # 对项目需求进 ...

  4. ATM + 购物车项目

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

  5. day19 十九、ATM+购物车

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

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

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

  7. Python实战之ATM+购物车

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

  8. ATM购物车+三层结构项目设计

    ATM购物车项目 模拟实现一个ATM + 购物商城程序. 该程序实现普通用户的登录注册.提现充值还款等功能,并且支持到网上商城购物的功能. 账户余额足够支付商品价格时,扣款支付:余额不足时,无法支付, ...

  9. ATM+购物车结构

    ATM+购物车 1.需求分析 2.程序设计及目录设计 3.编写程序 4.调试程序

随机推荐

  1. 数据结构 - AVL 树

    简介 基本概念 AVL 树是最早被发明的自平衡的二叉查找树,在 AVL 树中,任意结点的两个子树的高度最大差别为 1,所以它也被称为高度平衡树,其本质仍然是一颗二叉查找树. 结合二叉查找树,AVL 树 ...

  2. Effective HPA:预测未来的弹性伸缩产品

    作者 胡启明,腾讯云专家工程师,专注 Kubernetes.降本增效等云原生领域,Crane 核心开发工程师,现负责成本优化开源项目 Crane 开源治理和弹性能力落地工作. 余宇飞,腾讯云专家工程师 ...

  3. vscode golang 不能自动补全问题

    问题描述: 使用vscode编辑go语言时,有时候会莫名其妙的代码不能自动补全,struct的属性值不能自动提示,这时候如果重新启动vscode也没有效果,就可能是gocode插件出了问题或者有了更新 ...

  4. python学习-Day17

    目录 今日内容详细 生成器对象(自定义迭代器) 小总结 自定义range方法 通过生成器模拟range方法 先以两个参数的range方法为例 针对一个参数情况 针对三个参数情况 自定义的range方法 ...

  5. python学习-Day8

    目录 作业讲解 数据类型内置方法3 字典 ( dict ,可变类型) 类型转换 -- dict() 需要掌握的方法 按key取值(可存可取) 统计字典中键值对的个数(len) 成员运算 删除键值对 获 ...

  6. 交换机做节点的vlan划分

    基础准备 准备一台个人pc,两台物理服务器和一台三层交换机,以及网线若干. ip地址规划如下: 主机名 IP 控制节点 192.168.100.0 计算节点 192.168.200.0 个人pc 19 ...

  7. 【CSAPP】Shell Lab 实验笔记

    shlab这节是要求写个支持任务(job)功能的简易shell,主要考察了linux信号机制的相关内容.难度上如果熟读了<CSAPP>的"异常控制流"一章,应该是可以不 ...

  8. 文件共享总结下篇-NFS学习笔记

    一.NFS原理 ## 本次实验以CentOS7.7为例 [root@qll251 ~]# cat /etc/redhat-release CentOS Linux release 7.7.1908 ( ...

  9. 基于Docker&Kubernetes构建PaaS平台基础知识梳理

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 基于Docker&Kubernetes构建Paa ...

  10. 网络排查工具MTR介绍

    开源Linux 回复"读书",挑选书籍资料~ 常用的 ping,tracert,nslookup 一般用来判断主机的网络连通性,其实 Linux 下有一个更好用的网络连通性判断工具 ...