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

  • 2019 年 10 月 7 日
  • 笔记

ATM+购物车

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

'''  项目的由来,几个阶段      0.采集项目需求      1.需求分析      2.程序的架构设计      3.分任务开发      4.测试      5.上线运行  '''

需求分析: # 对项目需求进行分析,并提取出相应的功能

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

程序架构设计

'''      用户功能层:          负责接收用户输入的内容,并返回结果给用户(还可以做一些小的判断)        接口层:          处理业务逻辑        数据处理层:          增、删、改、查         三层架构的好处:          代码结构清晰,一层是一层的          低耦合,可扩展性强              部分之间联系不是特别固定,好扩展                  比如用户层我不用cmd了,改用网页,改用APP,接口层级数据处理层不需要改动直接就可以用了          易维护、管理              出现bug比较好定位,要修改配置也比较方便,扩展功能也是,可以很快定位到目标代码,不用很长的代码翻来翻去  '''

分任务开发

'''      - CTO 首席技术官          - 技术总监              - 架构师                  - 项目经理                      - 普通开发                      UI:用户界面设计师                      前段:网页的开发                      后端:写业务逻辑、接口的                      测试:测试软件                      运维:项目部署上线  '''

测试

'''      - 手动测试          传统人工去手动测试      - 自动化测试          通过脚本模拟人的行为,自动化执行测试        - 黑盒测试:          对用户界面进行测试      - 白盒测试:          对软件的性能进行测试,例如每分钟能接收多少并发量  '''

上线运行: # 将项目交给运维人员上线

部分流程具体案例

功能需求

'''      - 额度15000  ---> 注册功能        - 可以提现,手续费5%  ---> 提现        - 支持账户间转账   ---> 转账        - 记录消费流水  ---> 记录流水        - 提供还款接口  ---> 还款        - 用户认证功能  ---> 登陆认证,使用装饰器  '''

本文程序功能

目录规范及三层架构

各文件代码

import os  import sys    BASE_DIR = os.path.dirname(os.path.dirname(__file__))  sys.path.append(BASE_DIR)    from core import src  if __name__ == '__main__':      src.run()
from interface import user_interface  from lib import common  from interface import bank_interface      def register():      while True:          username = input("请输入用户名>>>:").strip()          if username == 'q':              break          if user_interface.check_user_exits(username):              print("用户名已存在,请重新输入")              continue          pwd = input("请输入密码>>>:").strip()          repwd = input("请再次输入密码>>>:").strip()          if pwd != repwd:              print("两次密码不一致,请重新输入")              continue            if user_interface.register(username, pwd):              print(f"{username}用户注册成功")              break      def login():      while True:          username = input("请输入用户名>>>:").strip()          if username == 'q':              return False          flag = user_interface.check_user_exits(username)          if not flag:              print(f"用户{username}不存在,请重试")              continue          pwd = input("请输入密码>>>:").strip()          flag = user_interface.login(username, pwd)          if not flag:              print("密码不正确,请重试")              continue          print(f"{username}您好,欢迎登录!")          break      @common.login_auth  def check_balance():      username = current_user_dict.get('username')      balance = user_interface.get_balance(username)      print(f"{username}您好,您的账户余额为{balance}元")      @common.login_auth  def repay():      while True:          username = current_user_dict.get('username')          money = input("请输入还款金额>>>:").strip()          if not money.isdigit():              print("请正确输入金额!")              continue          money = int(money)          flag = bank_interface.repay(username, money)          if flag:              print(f"{username}您好,您已成功还款{money}元")              break          else:              print("还款失败,请您重试")      @common.login_auth  def withdraw():      while True:          username = current_user_dict.get('username')          money = input("请输入提现金额>>>:").strip()          if not money.isdigit():              print("请正确输入金额!")              continue          money = int(money)          flag = bank_interface.withdraw(username, money)          if flag:              print(f"{username}您好,您已成功提现{money}元,手续费{money*0.05}元,现余额为{current_user_dict['balance']}元")              break          else:              print("还款失败,请您重试")        pass      @common.login_auth  def transfer():      while True:          username = current_user_dict.get('username')          target_user = input("请输入转账收款人>>>:").strip()          if target_user == 'q':              break          if target_user == username:              continue          flag = user_interface.check_user_exits(target_user)          if not flag:              print(f"{target_user}用户不存在,请重试")              continue          money = input("请输入转账金额>>>:").strip()          if not money.isdigit():              print("请正确输入金额!")              continue          money = int(money)          if money <= current_user_dict['balance']:              flag = bank_interface.transfer(username, target_user, money)              if flag:                  print(f"您已成功向{target_user}转账{money}元,现余额为{current_user_dict['balance']}元")                  break              print("转账失败,请重试")          else:              print("转账失败,转账金额大于您的余额")      @common.login_auth  def check_flow():      username = current_user_dict.get('username')      flow = user_interface.check_flow(username)      print(f"{username}您好,您的个人流水如下:")      for i in flow:          print(i)      @common.login_auth  def logout():      flag = user_interface.logout()      if flag:          print(f"用户注销登录成功,欢迎下次光临")      func_list = {      "1": register,      "2": login,      "3": check_balance,      "4": repay,      "5": withdraw,      "6": transfer,      "7": logout,      "8": check_flow  }    current_user_dict = {      "username": None,      "pwd": None,      'balance': None,      'flow': [],      'shop_cart': {},      'lock': None,  }      def run():      while True:          print("""          1.注册            2.登录            3.查看余额          4.还款            5.提现            6.转账          7.注销登录         8.检查流水          """)            choice = input("请输入功能编号(Q退出)>>>:").strip()          if choice == 'q':              print("感谢您的使用,祝您生活越快~")              break          elif choice in func_list:              func_list[choice]()          else:              print("您的输入有误,请重新输入!")
from db import db_handler  from lib import common  from core import src      def check_user_exits(username):      user_dict = db_handler.select(username)      if not user_dict:          return False      return True      def register(username, pwd, balance=15000):      pwd = common.get_md5(pwd)      user_dict = {          "username": username,          "pwd": pwd,          'balance': balance,          'flow': [],          'shop_cart': {},          'lock': False,      }      return db_handler.save(user_dict)      def login(username: str, pwd: str):      user_dict = db_handler.select(username)      pwd = common.get_md5(pwd)      if not user_dict:          return False      if user_dict['pwd'] != pwd:          return False      src.current_user_dict = user_dict      return True      def get_balance(username: str) -> float:      user_dict = db_handler.select(username)      src.current_user_dict['balance'] = user_dict['balance']      return user_dict.get('balance')      def check_flow(username):      user_dict = db_handler.select(username)      return user_dict['flow']      def logout():      src.current_user_dict = {          "username": None,          "pwd": None,          'balance': None,          'flow': [],          'shop_cart': {},          'lock': None,      }      return True
from db import db_handler  from core import src      def repay(username, money) -> bool:      user_dict = db_handler.select(username)      user_dict['balance'] += money      user_dict['flow'].append(f"{username}成功还款{money}元,现余额为{user_dict.get('balance')}")      src.current_user_dict = user_dict      return db_handler.save(user_dict)      def withdraw(username, money):      user_dict = db_handler.select(username)      if user_dict['balance'] >= money*1.05:          user_dict['balance'] -= money*1.05          user_dict['flow'].append(f"{username}提现{money}元,手续费{money*0.05}元,现余额为{user_dict['balance']}元")          src.current_user_dict = user_dict          return db_handler.save(user_dict)      else:          return False      def transfer(username, targer_user, money):      user_dict = db_handler.select(username)      user_dict['balance'] -= money      user_dict['flow'].append(f"{username}向{targer_user}转账{money}元,现余额为{user_dict['balance']}元")      src.current_user_dict = user_dict      if not db_handler.save(user_dict):          return False        targer_user_dict = db_handler.select(targer_user)      targer_user_dict['balance'] += money      targer_user_dict['flow'].append(f"{targer_user}接收到{username}转账{money}元,现余额为{targer_user_dict['balance']}元")      if not db_handler.save(targer_user_dict):          # 这里存储失败了,那么转账人(username)的扣款操作应该要退回          return False        return True
import os  from conf import settings  import json  DB_DIR = os.path.join(settings.BASE_DIR, "db")      def select(username: str):      user_file_path = os.path.join(DB_DIR, f"{username}.json")      if not os.path.exists(user_file_path):          return False      with open(user_file_path, 'r', encoding='utf-8') as f:          user_dict = json.load(f)      return user_dict      def save(user_dict: dict) -> bool:      user_file_path = os.path.join(DB_DIR, f"{user_dict['username']}.json")      with open(user_file_path, 'w', encoding='utf-8') as f:          json.dump(user_dict, f)      return True
import hashlib  from core import src      def get_md5(string: str) -> str:      md = hashlib.md5()      md.update('md5_salt'.encode('utf-8'))      md.update(string.encode('utf-8'))      return md.hexdigest()      def login_auth(func):      def inner(*args, **kwargs):          if not src.current_user_dict.get('username'):              print("请先登录后再操作!")          else:              res = func(*args, **kwargs)              return res      return inner
import os  import sys  BASE_DIR = os.path.dirname(os.path.dirname(__file__))  sys.path.append(BASE_DIR)

今日小错误

找了半天才发现问题,记住报错,下次看到类似报错就可以立马发现问题了

file_path = r'E:PyCharm 2019.1.3ATM+SHOP2libcommon.py'  # with open(file_path, 'r', 'utf-8') as f:  # 报错(不要忘了写 encoding!)  #     print('hello')  # Traceback (most recent call last):  #   File "E:/PyCharm 2019.1.3/ATM+SHOP2/test.py", line 2, in <module>  #     with open(file_path, 'r', 'utf-8') as f:  # TypeError: an integer is required (got type str)    with open(file_path, 'r', encoding='utf-8') as f:      print('hello')  # hello