zoukankan      html  css  js  c++  java
  • python以ATM+购物车剖析一个项目的由来及流程

    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()
    bin/starts.py
    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("您的输入有误,请重新输入!")
    core/src.py
    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
    interface/user_interface.py
    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
    interface/bank_interface.py
    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
    db/db_handler.py
    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
    lib/common.py
    import os
    import sys
    BASE_DIR = os.path.dirname(os.path.dirname(__file__))
    sys.path.append(BASE_DIR)
    conf/settings.py

    今日小错误

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

    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
    今日小错误(encoding漏写)
  • 相关阅读:
    maven总结二: 常用标签及属性
    maven总结一: 常用命令
    SpringCloud集成Seata并使用Nacos做注册中心与配置中心
    Seata 分布式事务解决方案及特点
    mui 文件附件下载
    Mock学习记录
    postman 测试elasticsearch 导出json
    elasticsearch 整合spring cloud Alibaba nacos 配置文件
    Elasticsearch 多字段高亮分页查询 返回泛型List集合
    Elasticsearch 多字段高亮字段返回json
  • 原文地址:https://www.cnblogs.com/suwanbin/p/11228714.html
Copyright © 2011-2022 走看看