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漏写)
  • 相关阅读:
    2. Add Two Numbers
    1. Two Sum
    22. Generate Parentheses (backTracking)
    21. Merge Two Sorted Lists
    20. Valid Parentheses (Stack)
    19. Remove Nth Node From End of List
    18. 4Sum (通用算法 nSum)
    17. Letter Combinations of a Phone Number (backtracking)
    LeetCode SQL: Combine Two Tables
    LeetCode SQL:Employees Earning More Than Their Managers
  • 原文地址:https://www.cnblogs.com/suwanbin/p/11228714.html
Copyright © 2011-2022 走看看