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. MySql免安装版 Error 2003 Can connect to MySQL server on ...

    现象描述:mysql只能本地登录,无法远程登录 解决方案: 1. 查看mysql端口(默认端口3306,命令端口根据需要修改),发现只有本地连接端口开放. netstat -an|findstr 33 ...

  2. 3.5 常用Linux命令

    1.touch命令 touch命令用于创建空白文件或设置文件的时间,语法格式为"touch [参数] 文件名称". 2.mkdir命令 mkdir命令用于创建空白的目录,英文全称为 ...

  3. python学习-Day22

    目录 今日内容详细 hashlib加密模块 什么是加密 加密算法 加密的使用 基本使用 指定算法(md5) 将明文数据传递给算法对象 获取加密之后的密文数据 加密补充 加盐处理 动态加盐 加密应用场景 ...

  4. Django/SQL server 配置实现(附下载安装)

    连接方案1: conn = pymssql.connect(host='127.0.0.1', port=1433, user='sa', password='password', database= ...

  5. VSCODE调试时在cygwin.S中发生段错误

    起因: C++实现矩阵类和向量类 当看了我实现的矩阵类后,一个同学问我: 然后我就试了试1000维,结果运行时在cygwin.S里引发了奇奇怪怪的Segmentation fault,而且这个文件还是 ...

  6. MySQL 高频面试题,都在这了

    点击上方"开源Linux",选择"设为星标"回复"学习"获取独家整理的学习资料! 前言 本文主要受众为开发人员,所以不涉及到MySQL的服务 ...

  7. 【必看】局域网IP地址冲突罪魁祸首是谁?

    开源Linux 长按二维码加关注~ 上一篇:一文详解FTP.FTPS与SFTP的原理 现如今,人们的生活处处离不开网络.企业办公信息化对网络的依赖则更大.为了提升安全管理和信息化水平,很多企业不仅建设 ...

  8. 107_Power Pivot员工效率监控

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 1.背景 在劳动密集型行业中,员工效率是一个永恒的话题. 今天把零时用工的效率提升展示及效率监控建一个PP模型并输出. 达 ...

  9. goose消元

    ps.改了标题 魔板 思路:按序消除变量,用当前行(i)[行i消\(x_i\)元素],消后面的每一行的i元素 最后按逆序回代值 注意若有i~n行i元素系数都为0说明没有唯一解(其余x的解跟i元素有关) ...

  10. 白嫖Azure与体验GoLand远程开发

    前言 近期因为有本地开发远程使用Linux编译部署的需求,而虚拟机的性能实在是不敢恭维,WSL的坑之前也踩过(没有systemd等),故考虑使用SSH连接云服务器开发. 目前VSCode提出了Remo ...