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. 常用shell脚本

    [脚本1]打印形状打印等腰三角形.直角三角形.倒直角三角形.菱形 #!/bin/bash # 等腰三角形 read -p "Please input the length: " n ...

  2. MySQL中的相关表操作

    简单表操作 1.表操作之修改表 .修改表名 alter table 表名 rename 新表名 .增加字段 alter table 表名 add 新字段名 数据类型[相关约束性条件...], add ...

  3. innodb部分内部操作

    tab_node_t* tab_create_graph_create( /*====================*/ dict_table_t* table, /*!< in: table ...

  4. Docker笔记:常用服务安装——Nginx、MySql、Redis(转载)

    转载地址:https://www.cnblogs.com/spec-dog/p/11320513.html 开发中经常需要安装一些常用的服务软件,如Nginx.MySql.Redis等,如果按照普通的 ...

  5. ant-design-pro引用css

    ant-design-pro中默认只能引用less文件,引用了css文件也是无效的.所以需要在配置文件config.js中找到  cssLoaderOptions,在 getLocalIdent中加入 ...

  6. API管理之YApi实现前后端高度分离

    全手打原创,转载请标明出处:https://www.cnblogs.com/dreamsqin/p/11972789.html,多谢,=.=~ 背景描述   前后端分离已成为互联网项目开发的业界标准使 ...

  7. typora安装自定义主题小计

    我写MarkDown一直使用VSCode,后来因为有导出PDF的需求,就用了typora(含书签) PS:VSCode的导出PDF虽然也可以,但不含书签 typora的默认主题是github,虽然还可 ...

  8. 关于PHP Fatal error: Invalid handle returned

    我在使用thinkphp5使用pdo的方式连接sqlserver的时候出现如此错误 尝试了网上的多种方法 PHP Fatal error: Invalid handle returned 端口写在了 ...

  9. java 获取真实ip地址

    /** * 获取真实ip地址 * @param request * @return */ public static String getIpAddress(HttpServletRequest re ...

  10. python 练习题:小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点

    # -*- coding: utf-8 -*- # 小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点,并用字符串格式化显示出'xx.x%',只保留小数点后1位. s1 = 72 ...