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

2019-09-26 10:25:45 浏览数 (1)

ATM 购物车

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

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

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

代码语言:javascript复制
    '''
        - 额度 15000或自定义  --> 注册功能

        - 实现购物商城,买东西加入购物车,调用信用卡接口结账   --> 购物车,支付(结账)功能

        - 可以提现,手续费5%  --> 提现

        - 支持多账户登录  --> 登录

        - 支持账户间转账  --> 转账

        - 记录每月日常消费流水  --> 记录流水

        - 提供还款接口  --> 还款

        - ATM记录操作日志  --> 日志功能

        - 提供管理接口,包括添加账户、用户额度,冻结账户等...  --> 管理员功能

        - 用户认证功能  --> 登录认证(装饰器)
    '''

程序架构设计

代码语言:javascript复制
'''
    用户功能层:
        负责接收用户输入的内容,并返回结果给用户(还可以做一些小的判断)

    接口层:
        处理业务逻辑

    数据处理层:
        增、删、改、查

     三层架构的好处:
        代码结构清晰,一层是一层的
        低耦合,可扩展性强
            部分之间联系不是特别固定,好扩展
                比如用户层我不用cmd了,改用网页,改用APP,接口层级数据处理层不需要改动直接就可以用了
        易维护、管理
            出现bug比较好定位,要修改配置也比较方便,扩展功能也是,可以很快定位到目标代码,不用很长的代码翻来翻去
'''

分任务开发

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

测试

代码语言:javascript复制
'''
    - 手动测试
        传统人工去手动测试
    - 自动化测试
        通过脚本模拟人的行为,自动化执行测试

    - 黑盒测试:
        对用户界面进行测试
    - 白盒测试:
        对软件的性能进行测试,例如每分钟能接收多少并发量
'''

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

部分流程具体案例

功能需求

代码语言:javascript复制
'''
    - 额度15000  ---> 注册功能

    - 可以提现,手续费5%  ---> 提现

    - 支持账户间转账   ---> 转账

    - 记录消费流水  ---> 记录流水

    - 提供还款接口  ---> 还款

    - 用户认证功能  ---> 登陆认证,使用装饰器
'''

本文程序功能

目录规范及三层架构

各文件代码

代码语言:javascript复制
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()
代码语言:javascript复制
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("您的输入有误,请重新输入!")
代码语言:javascript复制
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
代码语言:javascript复制
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
代码语言:javascript复制
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
代码语言:javascript复制
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
代码语言:javascript复制
import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_DIR)

今日小错误

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

代码语言:javascript复制
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

0 人点赞