ATM + 购物车

需求分析

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

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

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

程序架构

程序目录设计

  1. # 接下来我们写的功能都在按照这个文件目录来写,请认真阅读这个目录所对应的功能。
  2. '''
  3. - ATM
  4.   - conf 配置文件文件夹
  5.     - setting.py
  6.   - lib 公共方法文件夹
  7.     - common.py  公共方法文件
  8.   - interface 接口层文件夹
  9.     - user.py  用户接口文件
  10.     - bank.py  银行接口文件
  11.   - core 用户功能文件夹
  12.     - src.py  视图文件
  13.   - db 数据处理层文件夹
  14.     - db_handler.py  数据处理功能文件
  15.   - start.py  程序的入口文件,启动文件
  16.   - readme  程序的说明文件
  17. '''

程序模块

  1. # confs
  2. ## settings.py(主要存一些常量,主要是功能界面,商品列表,日志路径,数据路径)
  3. import os
  4. import sys
  5. ########
  6. #功能展示#
  7. #########
  8. FUNC_MSG = {
  9. '0': "注销",
  10. '1': "登录",
  11. '2': "注册",
  12. '3': "查看余额",
  13. '4': "转账",
  14. '5': "还款",
  15. '6': "取现",
  16. '7': "查看流水",
  17. '8': "购物",
  18. '9': "购物车",
  19. }
  20. SHOP_DIST = [
  21. ['饼干', 10],
  22. ['薯片', 10],
  23. ['火腿肠', 20],
  24. ['雪糕', 10],
  25. ['别墅', 1000000]
  26. ]
  27. # LOG_PATH = os.path
  28. ATM_PATH = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
  29. DB_PATH = os.path.join(ATM_PATH, 'db')
  30. #core
  31. ## src.py(主界面,主要是和用户交互的界面)
  32. from libs import common
  33. from db import db_handler
  34. from interface import user
  35. from interface import bank
  36. from confs import settings
  37. #设置一个字典类型的全局变量,用于判断是否登录
  38. user_info = {
  39. 'user': None
  40. }
  41. # 注销功能
  42. def logout():
  43. user_info['user'] = None # 将values值设置为空
  44. print('注销成功')
  45. # 登录模块
  46. def login():
  47. count = 0 #计数,连续三次注册失败,退出功能
  48. print("欢迎来到登录功能")
  49. while True:
  50. username, pwd = common.input_username_pwd() # 调用输入接口,接收输入信息
  51. flag = common.check_user(username) # 调用核对用户接口,验证用户是否已经存在
  52. if not flag:
  53. print('未注册')
  54. break
  55. flag, msg = user.login_interface(username, pwd)
  56. if flag:
  57. user_info['user'] = username #登录成功,赋值
  58. print(user_info['user'])
  59. print(msg)
  60. break
  61. else:
  62. print(msg)
  63. count += 1
  64. if count == 3:
  65. break
  66. #注册模块
  67. def register():
  68. print("欢迎来到注册模块")
  69. username, pwd = common.input_username_pwd()
  70. flag = common.check_user(username) #先判断是否存在
  71. if flag:
  72. print("无需注册,用户已经存在")
  73. else:
  74. msg = user.register_interface(username, pwd) # 调用注册接口
  75. print(msg)
  76. @common.login_auth # 加语法糖,查看余额前先登录
  77. def check_extra():
  78. print("欢迎来到查看余额模块")
  79. msg = user.check_extra(user_info.get('user')) # 调用查看余额接口
  80. print(msg)
  81. # 转账,需要有发起人,接收人和钱
  82. @common.login_auth
  83. def transfer():
  84. print("欢迎来到转账模块")
  85. while True:
  86. from_username = user_info.get('user')
  87. to_username = input('请输入你要转账的用户名:')
  88. flag = common.check_user(to_username) #先判断用户是否存在
  89. if flag:
  90. money = input("请输入你要转账的金额").strip()
  91. if not money.isdigit():
  92. print("请输入数字")
  93. continue
  94. money = int(money)
  95. msg = bank.transfer_interface(from_username, to_username, money) #调用转账接口
  96. print(msg)
  97. break
  98. print("用户不存在")
  99. @common.login_auth
  100. #还款模块
  101. def repay():
  102. print("欢迎来到还款模块")
  103. msg = bank.repay_interface(user_info['user']) #调用还款接口
  104. print(msg)
  105. @common.login_auth
  106. #取现功能
  107. def withdraw():
  108. print("欢迎来到取现功能")
  109. while True:
  110. money = input("请输入取现金额:")
  111. if not money.isdigit():
  112. print("输入必须是数字")
  113. continue
  114. else:
  115. money = int(money)
  116. msg = bank.withdraw_interface(user_info['user'], money)#调用取现模块
  117. print(msg)
  118. break
  119. @common.login_auth
  120. #查看流水模块
  121. def history():
  122. print("欢迎来到查看流水模块")
  123. msg = bank.bank_flow_interface(user_info['user'])#调用查看流水模块
  124. print(msg)
  125. @common.login_auth
  126. #购物模块
  127. def shopping():
  128. print("欢迎来到购物模块")
  129. while True:
  130. for index, goods in enumerate(settings.SHOP_DIST): #用列表存储的商品输出,得到索引和有两个元素的商品小列表
  131. print(f'{index} {goods}')
  132. goods_n = input("请输入你要的商品编号,按q退出:")
  133. if goods_n == 'q':
  134. break
  135. if not goods_n.isdigit():
  136. print("输入有误")
  137. continue
  138. goods_n = int(goods_n)
  139. goods = settings.SHOP_DIST[goods_n] # 拿到的商品是一个有两个值(第一个是商品名,第二个是价格)的列表
  140. goods_name = goods[0] # 列表第一个元素是商品名
  141. user_dic = db_handler.read_json(user_info['user']) # 拿到当前用户的数据字典
  142. my_money = user_dic['extra'] # 把用户字典中的查看额度取出来
  143. if goods[-1] <= my_money: # 如果商品金额小于额度,可以买
  144. if goods_name in user_dic['shop_car']:
  145. user_dic['shop_car'][goods_name] += goods[-1] # 如果我的字典里面的购物车字典有该商品,把价格加上去
  146. else:
  147. user_dic['shop_car'][goods_name] = goods[-1] # 如果我的字典里面的购物车字典没有该商品,把商品名加上去,价格加上去
  148. db_handler.save_json(user_dic) # 做完修改要保存
  149. print(f'{goods_name}加入购物车成功')
  150. else:
  151. print("余额不足")
  152. break
  153. print(f"你的购物车是{user_dic['shop_car']}") # 买完之后要打印一下
  154. @common.login_auth
  155. # 购物车模块
  156. def shopping_car():
  157. print("欢迎来到购物车模块")
  158. while True:
  159. user_dic = db_handler.read_json(user_info['user']) #用户数据读取
  160. goods_dic = user_dic['shop_car'] # 拿到用户数据字典的购物车字典
  161. cost_choice = input(f"购物车是{goods_dic},是否选择购买y/n:") # 判断是否购买
  162. if cost_choice == 'n':
  163. break
  164. elif cost_choice == 'y':
  165. cost = sum(goods_dic.values()) # 把用户购物车字典中的值求和得到总价
  166. if cost > user_dic['extra']:
  167. print('余额不足,支付失败')
  168. break
  169. user_dic['extra'] -= cost # 支付就是把用户字典的额度减去总价
  170. db_handler.save_json(user_dic) # 操作完了保存
  171. print("支付成功")
  172. break
  173. def run():
  174. FUNC_DICT = {
  175. '0':logout,
  176. '1':login,
  177. '2':register,
  178. '3':check_extra,
  179. '4':transfer,
  180. '5':repay,
  181. '6':withdraw,
  182. '7':history,
  183. '8':shopping,
  184. '9':shopping_car,
  185. }
  186. from confs.settings import FUNC_MSG
  187. while True:
  188. for k, v in FUNC_MSG.items(): # 把功能列表打印出来展示给用户,包括序号和值
  189. print(f'{k}: {v}')
  190. func_choice = input("请输入你需要的功能,按q退出>>>>>").strip()
  191. if func_choice == 'q':
  192. break
  193. if not FUNC_DICT.get(func_choice):
  194. print('输入有误,请重新输入')
  195. continue
  196. func = FUNC_DICT.get(func_choice)
  197. func()
  198. if __name__ == '__main__':
  199. run()
  200. # db
  201. ## db_handler(数据处理模块,主要是用户存取数据,格式是json)
  202. import os
  203. import json
  204. from confs import settings
  205. import sys
  206. def save_json(user_dic): #存数据,记得存的是字典,所有拼接名字的时候要把字典里面的用户名取出来
  207. user_path = os.path.join(settings.DB_PATH,
  208. f'{user_dic.get("username")}.json') #拼接路径
  209. with open(user_path, 'w', encoding='utf8') as fw:
  210. json.dump(user_dic, fw) # 存进去,第一个参数是数据,第二个是文件,就是把第一个数据存到第二个文件中
  211. def read_json(username):# 读数据, 拼路径,读出来数据就可以了,记得返回
  212. user_path = os.path.join(settings.DB_PATH, f'{username}.json')
  213. if os.path.exists(user_path):
  214. with open(user_path, 'r', encoding='utf8') as fr:
  215. data = json.load(fr)
  216. return data
  217. #interface(主要就是银行和用户两个接口)
  218. ## bank.py
  219. from db import db_handler
  220. def transfer_interface(from_username, to_username, money):# 转账接口,
  221. from_user_dic = db_handler.read_json(from_username) # 读当前用户数据
  222. to_user_dict = db_handler.read_json(to_username) # 读要转账用户数据
  223. my_money = from_user_dic['extra'] # 把用户的钱单独拿出来
  224. if money > my_money:
  225. return '钱不够'
  226. else:
  227. from_user_dic['extra'] -= money # 我减钱
  228. to_user_dict['extra'] += money # 对方加钱
  229. msg_f = f'已向{to_username}转账{money}元' #记录我的信息
  230. msg_t = f'已收到{from_username}转账{money}元' #记录对方信息
  231. from_user_dic['bank_flow'].append(msg_f) #加我流水
  232. to_user_dict['bank_flow'].append(msg_t) #加对方流水
  233. db_handler.save_json(from_user_dic) #存数据
  234. db_handler.save_json(to_user_dict) #存数据
  235. return msg_f #返回操作信息
  236. def repay_interface(username): #还款接口
  237. while True:
  238. money = input("请输入你的还款金额:").strip()
  239. if not money.isdigit():
  240. print('请输入数字')
  241. else:
  242. money = int(money)
  243. user_dic = db_handler.read_json(username) #拿用户数据
  244. user_dic['extra'] += money # 字典里面加钱
  245. db_handler.save_json(user_dic) #保存数据
  246. return f'{username}已成功还款{money}' #返回信息
  247. def withdraw_interface(username, money):# 取现接口
  248. user_dic = db_handler.read_json(username) #拿用户信息
  249. if money*1.005 > user_dic['extra']:
  250. return "钱不够"
  251. else:
  252. user_dic['extra'] -= money*1.05 # 减钱
  253. db_handler.save_json(user_dic) # 存数据
  254. return f'{username}已成功取现{money}元'
  255. def bank_flow_interface(username): # 银行流水信息
  256. user_dic = db_handler.read_json(username) # 拿用户数据
  257. return user_dic['bank_flow'] #返回用户字典里的流水
  258. ## user.py(用户接口)
  259. from db import db_handler
  260. from confs import settings
  261. import os
  262. def register_interface(username, pwd): #注册接口
  263. #新生成的用户的信息字典
  264. user_dic = {
  265. 'username': username,
  266. 'pwd': pwd,
  267. 'extra': 1500000,
  268. 'bank_flow':[],
  269. 'shop_car':{}
  270. }
  271. db_handler.save_json(user_dic) #保存数据
  272. return f'{username}注册成功'
  273. def login_interface(username, pwd): #登录模块
  274. user_data = db_handler.read_json(username) # 拿数据
  275. if user_data['pwd'] == pwd:
  276. return True, '登录成功'
  277. else:
  278. return False, '密码输入错误'
  279. def check_extra(username):# 查看余额接口
  280. user_data = db_handler.read_json(username) # 拿数据
  281. extra = user_data['extra']
  282. return f'{username}查看了余额,余额为{extra}元'
  283. # libs
  284. ## common.py(通用模块)
  285. import logging
  286. import os
  287. from db import db_handler
  288. from confs import settings
  289. import logging.config
  290. def input_username_pwd():# 用户输入的模块
  291. username = input('请输入用户名>>>>').strip()
  292. pwd = input("请输入密码>>>>").strip()
  293. return username, pwd
  294. def check_user(username): # 检查用户是否存在模块
  295. user_path = os.path.join(settings.DB_PATH, f'{username}.json') #拼接用户路径,判断是否有该路径
  296. if os.path.exists(user_path):
  297. return True
  298. else:
  299. return False
  300. def login_auth(func): # 装饰函数,用于验证是否登录,套用装饰函数模板
  301. from core import src
  302. def inner(*args, **kwargs):
  303. if src.user_info.get('user'):
  304. res = func(*args, **kwargs)
  305. return res
  306. else:
  307. print('未登录,请去登录!')
  308. src.login()
  309. return inner
  310. #start.py (开始模块,项目的起始点)
  311. from core import src
  312. import os
  313. import sys
  314. sys.path.append(os.path.dirname(__file__)) #一定要把当前路径加入环境变量里
  315. if __name__ == '__main__':
  316. src.run()

注意点


  1. 1. 首先要把项目单独打开,即作为根目录。
  2. 2. 记住写项目,尤其是需要导入模块时,一定要写开始的函数(start.py),可以避免出现循环导入问题,造成一些变量传入出错。
  3. 3. 有些时候Pycharm不能识别数据类型,就没有提示,但不代表是错的,只要可以运行就可以。
  4. 4. 保存的是字典,所以拼接路径时要注意名字,取字典里key = username对应的值作为名字
  5. 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. 解决IDEA卡顿的问题(Windows和Mac)

    IDEA卡顿 最近一段时间经常会在开发的时候感觉到 IDEA 很卡,在一个类里上下滚动或者切换类文件时都能够明显的感觉到,我以为是我项目打开的太多了,毕竟内存优化已经做过了,但是今天实在是被这玩意儿卡 ...

  2. PS:老权限登录Action 中 WebObjManager有问题,一直登录不起问题

    .ashx后面代码要多继承一个, IRequiresSessionState接口

  3. Qt Quick 事件处理之鼠标、键盘、定时

    一.鼠标事件 MouseArea 对象可以附加到一个 item 上供 item 处理鼠标事件,它本身是一个不可见的 item .在其内部,可以直接引用它所附着的对象的属性和方法.你可以将 MouseA ...

  4. HTML连载26-谷歌开发者工具其它作用&CSS继承性

    一.谷歌开发者工具其他特性(谷歌浏览器快捷键F12) (1)元素选择, 在里面我们可以看到某些行的具体代码 (2)查看源代码 (3)该元素的样式显示,我们可以看到我们选中的元素的具体样式属性,可以在里 ...

  5. JAVA PTA 7-1 作品评分 (10 分)

    全国中小学生Scratch作品大赛拉开了序幕.每个参赛选手可以通过网络直接上传作品.本次比赛人人可做评委.每个网络评委可以通过网络对每一件作品进行打分.评分系统也是请程序高手设计的,能自动去掉一个最高 ...

  6. 遇到 npm WARN npm npm does not support Node.js vx.x.x的解决办法

    遇到如下警告 PS C:\Users\Administrator> npm npm WARN npm npm does not support Node.js v9.11.2 npm WARN ...

  7. scala中nothing和null的区别

    1:nothing是所有类型的子类,他没有具体的实例对象,常见的应用:抛出异常.程序exit.无线循环等. 2:nothing是所有类型的子类,也是null的子类,nothing没有对象,但是可以用来 ...

  8. pod install速度慢,pod repo update 速度慢解决方法

    相信大家已经感受到pod install速度越来越慢了,网上提供了几种解决方案,但是都没有完全解决速度慢的问题. 使用国内镜像的Specs 在pod install时使用命令pod install - ...

  9. 后台数据转换成Excel,前台下载

    <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactI ...

  10. ASP.NET Core 3.0 WebApi 系列【2】.Net Core 3.0+ CodeFirst + MySql 实现数据的迁移

    写在前面 在前一小节中,我们创建了基于RESFULL风格的服务.这个小节,尝试使用CodeFirst+MySql 的方式实现数据迁移. 一.开发环境 [1]运行环境:win10 家庭版 [2]开发工具 ...