ATM + 购物车

需求分析

'''
- 额度 15000或自定义 - 实现购物商城,买东西加入 购物车,调用信用卡接口结账 - 可以提现,手续费5% - 支持多账户登录 - 支持账户间转账 - 记录每月日常消费流水 - 提供还款接口 - ATM记录操作日志 - 提供管理接口,包括添加账户、用户额度,冻结账户等... - 用户认证功能 '''

一个项目是如何从无到有的

# 1、需求分析:
'''
开发项目前,都必须找到相应的客户,让客户给企业提出项目的需求,以及需要实现的功能有哪些,拿到需求后再提取出一些列功能。
''' # 2、设计程序以及程序的架构
'''
在所有一线开发的企业里,在一个项目开发前,都应该设计程序,那样会让程序解开耦合,从而提高项目的管理以及开发的效率。
''' # 3、分任务开发
'''
在公司里面,开发项目需要这几种岗位人才:
UI设计: 软件的外观设计者,通过一些炫酷的设计,提高用户的对软件的体验感。
前端开发: UI设计仅仅只是把一些外观图设计出来,那前端开发需要把UI的设计图拿到之后,对软件界面的进行排版。
后端开发(python): 项目里业务以及功能的逻辑处理!
''' # 4、项目测试
'''
测试工程师: 对后端以及前端开发好的项目进行功能和性能测试,测试的过程中出现bug就会立即让开发人员去修整,待整个项目几乎没有bug,以及性能达到项目实际的预期,就会准备上线运行。 测试分为两种:
1.黑盒测试:
通过对软件界面的功能进行测试,测试一些能让用户看到的bug。(例如穿越火线的卡箱子等等...)
2.白盒测试:
对软件进行性能测试,例如每秒钟能承受多少用户量的访问等...
''' # 5、上线运行
'''
运维工程师(linux): 拿到前面整个项目编写完的代码,部署到服务器,上线运行!
'''

程序架构

程序目录设计

# 接下来我们写的功能都在按照这个文件目录来写,请认真阅读这个目录所对应的功能。

'''
- ATM
  - conf 配置文件文件夹
    - setting.py   - lib 公共方法文件夹
    - common.py  公共方法文件   - interface 接口层文件夹
    - user.py  用户接口文件
    - bank.py  银行接口文件   - core 用户功能文件夹
    - src.py  视图文件   - db 数据处理层文件夹
    - db_handler.py  数据处理功能文件   - start.py  程序的入口文件,启动文件   - readme  程序的说明文件 '''

程序模块

# confs
## settings.py(主要存一些常量,主要是功能界面,商品列表,日志路径,数据路径) import os
import sys ########
#功能展示#
#########
FUNC_MSG = {
'0': "注销",
'1': "登录",
'2': "注册",
'3': "查看余额",
'4': "转账",
'5': "还款",
'6': "取现",
'7': "查看流水",
'8': "购物",
'9': "购物车",
} SHOP_DIST = [
['饼干', 10],
['薯片', 10],
['火腿肠', 20],
['雪糕', 10],
['别墅', 1000000]
]
# LOG_PATH = os.path
ATM_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
DB_PATH = os.path.join(ATM_PATH, 'db') #core
## src.py(主界面,主要是和用户交互的界面)
from libs import common
from db import db_handler
from interface import user
from interface import bank
from confs import settings #设置一个字典类型的全局变量,用于判断是否登录
user_info = {
'user': None
} # 注销功能
def logout():
user_info['user'] = None # 将values值设置为空
print('注销成功') # 登录模块
def login():
count = 0 #计数,连续三次注册失败,退出功能
print("欢迎来到登录功能")
while True:
username, pwd = common.input_username_pwd() # 调用输入接口,接收输入信息
flag = common.check_user(username) # 调用核对用户接口,验证用户是否已经存在
if not flag:
print('未注册')
break
flag, msg = user.login_interface(username, pwd)
if flag:
user_info['user'] = username #登录成功,赋值
print(user_info['user'])
print(msg)
break
else:
print(msg)
count += 1
if count == 3:
break #注册模块
def register():
print("欢迎来到注册模块") username, pwd = common.input_username_pwd()
flag = common.check_user(username) #先判断是否存在
if flag:
print("无需注册,用户已经存在")
else:
msg = user.register_interface(username, pwd) # 调用注册接口
print(msg) @common.login_auth # 加语法糖,查看余额前先登录
def check_extra():
print("欢迎来到查看余额模块")
msg = user.check_extra(user_info.get('user')) # 调用查看余额接口
print(msg) # 转账,需要有发起人,接收人和钱
@common.login_auth
def transfer():
print("欢迎来到转账模块") while True:
from_username = user_info.get('user')
to_username = input('请输入你要转账的用户名:')
flag = common.check_user(to_username) #先判断用户是否存在
if flag:
money = input("请输入你要转账的金额").strip()
if not money.isdigit():
print("请输入数字")
continue
money = int(money)
msg = bank.transfer_interface(from_username, to_username, money) #调用转账接口
print(msg)
break
print("用户不存在") @common.login_auth
#还款模块
def repay():
print("欢迎来到还款模块") msg = bank.repay_interface(user_info['user']) #调用还款接口
print(msg) @common.login_auth
#取现功能
def withdraw():
print("欢迎来到取现功能")
while True:
money = input("请输入取现金额:")
if not money.isdigit():
print("输入必须是数字")
continue
else:
money = int(money)
msg = bank.withdraw_interface(user_info['user'], money)#调用取现模块
print(msg)
break
@common.login_auth
#查看流水模块
def history():
print("欢迎来到查看流水模块") msg = bank.bank_flow_interface(user_info['user'])#调用查看流水模块
print(msg) @common.login_auth
#购物模块
def shopping():
print("欢迎来到购物模块")
while True:
for index, goods in enumerate(settings.SHOP_DIST): #用列表存储的商品输出,得到索引和有两个元素的商品小列表
print(f'{index} {goods}')
goods_n = input("请输入你要的商品编号,按q退出:")
if goods_n == 'q':
break
if not goods_n.isdigit():
print("输入有误")
continue
goods_n = int(goods_n)
goods = settings.SHOP_DIST[goods_n] # 拿到的商品是一个有两个值(第一个是商品名,第二个是价格)的列表
goods_name = goods[0] # 列表第一个元素是商品名
user_dic = db_handler.read_json(user_info['user']) # 拿到当前用户的数据字典
my_money = user_dic['extra'] # 把用户字典中的查看额度取出来
if goods[-1] <= my_money: # 如果商品金额小于额度,可以买
if goods_name in user_dic['shop_car']:
user_dic['shop_car'][goods_name] += goods[-1] # 如果我的字典里面的购物车字典有该商品,把价格加上去
else:
user_dic['shop_car'][goods_name] = goods[-1] # 如果我的字典里面的购物车字典没有该商品,把商品名加上去,价格加上去
db_handler.save_json(user_dic) # 做完修改要保存
print(f'{goods_name}加入购物车成功')
else:
print("余额不足")
break
print(f"你的购物车是{user_dic['shop_car']}") # 买完之后要打印一下 @common.login_auth
# 购物车模块
def shopping_car():
print("欢迎来到购物车模块") while True:
user_dic = db_handler.read_json(user_info['user']) #用户数据读取
goods_dic = user_dic['shop_car'] # 拿到用户数据字典的购物车字典
cost_choice = input(f"购物车是{goods_dic},是否选择购买y/n:") # 判断是否购买
if cost_choice == 'n':
break
elif cost_choice == 'y':
cost = sum(goods_dic.values()) # 把用户购物车字典中的值求和得到总价
if cost > user_dic['extra']:
print('余额不足,支付失败')
break
user_dic['extra'] -= cost # 支付就是把用户字典的额度减去总价
db_handler.save_json(user_dic) # 操作完了保存
print("支付成功")
break def run(): FUNC_DICT = {
'0':logout,
'1':login,
'2':register,
'3':check_extra,
'4':transfer,
'5':repay,
'6':withdraw,
'7':history,
'8':shopping,
'9':shopping_car,
}
from confs.settings import FUNC_MSG
while True:
for k, v in FUNC_MSG.items(): # 把功能列表打印出来展示给用户,包括序号和值
print(f'{k}: {v}') func_choice = input("请输入你需要的功能,按q退出>>>>>").strip()
if func_choice == 'q':
break if not FUNC_DICT.get(func_choice):
print('输入有误,请重新输入')
continue func = FUNC_DICT.get(func_choice)
func() if __name__ == '__main__':
run() # db
## db_handler(数据处理模块,主要是用户存取数据,格式是json) import os
import json
from confs import settings
import sys def save_json(user_dic): #存数据,记得存的是字典,所有拼接名字的时候要把字典里面的用户名取出来
user_path = os.path.join(settings.DB_PATH,
f'{user_dic.get("username")}.json') #拼接路径
with open(user_path, 'w', encoding='utf8') as fw:
json.dump(user_dic, fw) # 存进去,第一个参数是数据,第二个是文件,就是把第一个数据存到第二个文件中 def read_json(username):# 读数据, 拼路径,读出来数据就可以了,记得返回
user_path = os.path.join(settings.DB_PATH, f'{username}.json')
if os.path.exists(user_path):
with open(user_path, 'r', encoding='utf8') as fr:
data = json.load(fr)
return data #interface(主要就是银行和用户两个接口)
## bank.py
from db import db_handler def transfer_interface(from_username, to_username, money):# 转账接口,
from_user_dic = db_handler.read_json(from_username) # 读当前用户数据
to_user_dict = db_handler.read_json(to_username) # 读要转账用户数据
my_money = from_user_dic['extra'] # 把用户的钱单独拿出来 if money > my_money:
return '钱不够' else:
from_user_dic['extra'] -= money # 我减钱
to_user_dict['extra'] += money # 对方加钱
msg_f = f'已向{to_username}转账{money}元' #记录我的信息
msg_t = f'已收到{from_username}转账{money}元' #记录对方信息 from_user_dic['bank_flow'].append(msg_f) #加我流水
to_user_dict['bank_flow'].append(msg_t) #加对方流水 db_handler.save_json(from_user_dic) #存数据
db_handler.save_json(to_user_dict) #存数据
return msg_f #返回操作信息 def repay_interface(username): #还款接口
while True:
money = input("请输入你的还款金额:").strip()
if not money.isdigit():
print('请输入数字')
else:
money = int(money)
user_dic = db_handler.read_json(username) #拿用户数据
user_dic['extra'] += money # 字典里面加钱
db_handler.save_json(user_dic) #保存数据
return f'{username}已成功还款{money}' #返回信息 def withdraw_interface(username, money):# 取现接口
user_dic = db_handler.read_json(username) #拿用户信息 if money*1.005 > user_dic['extra']:
return "钱不够"
else:
user_dic['extra'] -= money*1.05 # 减钱
db_handler.save_json(user_dic) # 存数据
return f'{username}已成功取现{money}元' def bank_flow_interface(username): # 银行流水信息
user_dic = db_handler.read_json(username) # 拿用户数据
return user_dic['bank_flow'] #返回用户字典里的流水 ## user.py(用户接口)
from db import db_handler
from confs import settings
import os def register_interface(username, pwd): #注册接口
#新生成的用户的信息字典
user_dic = {
'username': username,
'pwd': pwd,
'extra': 1500000,
'bank_flow':[],
'shop_car':{}
}
db_handler.save_json(user_dic) #保存数据
return f'{username}注册成功' def login_interface(username, pwd): #登录模块
user_data = db_handler.read_json(username) # 拿数据 if user_data['pwd'] == pwd:
return True, '登录成功'
else:
return False, '密码输入错误' def check_extra(username):# 查看余额接口
user_data = db_handler.read_json(username) # 拿数据
extra = user_data['extra']
return f'{username}查看了余额,余额为{extra}元' # libs
## common.py(通用模块)
import logging
import os
from db import db_handler
from confs import settings
import logging.config def input_username_pwd():# 用户输入的模块
username = input('请输入用户名>>>>').strip()
pwd = input("请输入密码>>>>").strip() return username, pwd def check_user(username): # 检查用户是否存在模块
user_path = os.path.join(settings.DB_PATH, f'{username}.json') #拼接用户路径,判断是否有该路径
if os.path.exists(user_path):
return True
else:
return False def login_auth(func): # 装饰函数,用于验证是否登录,套用装饰函数模板
from core import src
def inner(*args, **kwargs):
if src.user_info.get('user'):
res = func(*args, **kwargs)
return res
else:
print('未登录,请去登录!')
src.login() return inner #start.py (开始模块,项目的起始点) from core import src
import os
import sys sys.path.append(os.path.dirname(__file__)) #一定要把当前路径加入环境变量里
if __name__ == '__main__':
src.run()

注意点


1. 首先要把项目单独打开,即作为根目录。
2. 记住写项目,尤其是需要导入模块时,一定要写开始的函数(start.py),可以避免出现循环导入问题,造成一些变量传入出错。
3. 有些时候Pycharm不能识别数据类型,就没有提示,但不代表是错的,只要可以运行就可以。
4. 保存的是字典,所以拼接路径时要注意名字,取字典里key = username对应的值作为名字
5. 登录成功后把user_info['user']赋值为输入的用户名

Python实战之ATM+购物车的更多相关文章

  1. Python入门之ATM+购物车代码版思维导图

    该项目结合了ATM模版和购物车需求,整个思维导图用Python代码实现,使用思维导图可以清晰明了的看清整个框架: 过程中,用到了Python的知识有Python常用模块,Python常用内置包,log ...

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

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

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

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

  4. [py]python之信用卡ATM

    python之信用卡ATM 参考: http://www.cnblogs.com/wushank/p/5248916.html 他的博客写的很ok 需求介绍 模拟实现一个ATM + 购物商城程序 额度 ...

  5. 项目: ATM+购物车

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

  6. zeromq 学习和python实战

    参考文档: 官网 http://zeromq.org/ http://www.cnblogs.com/rainbowzc/p/3357594.html   原理解读 zeromq只是一层针对socke ...

  7. Python实战:美女图片下载器,海量图片任你下载

    Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...

  8. Python实战:Python爬虫学习教程,获取电影排行榜

    Python应用现在如火如荼,应用范围很广.因其效率高开发迅速的优势,快速进入编程语言排行榜前几名.本系列文章致力于可以全面系统的介绍Python语言开发知识和相关知识总结.希望大家能够快速入门并学习 ...

  9. python实战--数据结构二叉树

    此文将讲述如何用python实战解决二叉树实验 前面已经讲述了python语言的基本用法,现在让我们实战一下具体明确python的用法 点击我进入python速成笔记 先看一下最终效果图: 首先我们要 ...

随机推荐

  1. kinaba 安装踩坑: FATAL Error: [elasticsearch.url]: definition for this key is missing

    操作系统:Linux kibana 版本: 7.4.0 1. 在/etc/yum.repos.d/ 下新建 kibana.repo  配置 yum 源地址 内容如下: [root@localhost ...

  2. Java 并发系列之八:java 并发工具(4个)

    1. CountDownLatch 2. CyclicBarrier 3. Semaphore 4. Exchanger 5. txt java 并发工具 通俗理解 CountDownLatch 等A ...

  3. JVM系列之四:运行时数据区

    1. JVM架构图 Java虚拟机主要分为五大模块:类装载器子系统.运行时数据区.执行引擎.本地方法接口和垃圾收集模块. 2. JDK1.7内存模型-运行时数据区域 根据<Java 虚拟机规范( ...

  4. PyQt5笔记之菜单栏

    目录 菜单栏 创建单层菜单 创建多层菜单 右键打开菜单 官方菜单实例 菜单常用方法 菜单栏 创建单层菜单 import sys from PyQt5.QtWidgets import QApplica ...

  5. AngularJS简介与四大特征

    1.1 AngularJS简介 AngularJS  诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.A ...

  6. 使用docker安装gitlab,两台电脑gitlab库相互迁移

    原文来自合伙呀 https://hehuoya.com/2019/09/30/gitlab-docker/ Docker  for gitlab brew cask install docker do ...

  7. ReentrantLock的实现原理及AQS和CAS

    AQS,即AbstractQueuedSynchronizer, 队列同步器,它是多线程访问共享资源的同步器框架,Java中的ReentrantLock/Semaphore/CountDownLatc ...

  8. git add无效,git status(modified content, untracked content)

    问题一:git status 时文件目录后提示(modified content, untracked content) git add后也添加不上,文件不能提交上去   例如下图:   原因: 该文 ...

  9. JavaScaript学习笔记第(一)

    js由三部分组成,分别是ECMAScript.DOM.BOM 其中ECMAScript规定了js的语法 js是一门解释型语言.脚本语言.动态类型语言.基于对象语言 书写js代码和CSS一样,有三个书写 ...

  10. 小白开学Asp.Net Core 《八》

    小白开学Asp.Net Core <八> — — .Net Core 数据保护组件 1.背景 我在搞(https://github.com/AjuPrince/Aju.Carefree)这 ...