zoukankan      html  css  js  c++  java
  • ATM+购物车

    start.py

    from core import  src
    import  sys,os
    if __name__ == '__main__':
        src.run()

    bin 目录下存放文件  

    admin_info.py  、bank_info.py 、shopping.py、user_info.py

    admin_info.py

    from db import  db_hander
    #修改额度接口
    def change_balance_info(username,money):
        user_dic = db_hander.select(username)
        if user_dic:
            #修改额度
            user_dic['balance'] = int(money)
    
            # 保存修改后保存
            db_hander.save(user_dic)
            return  True,"额度修改成功"
        return False ,"修改用户不存在"
    # 冻结账号接口
    def lock_user_info(username):
        user_dic= db_hander.select(username)
        if user_dic:
            user_dic['lock'] = True
            db_hander.save(username)
            return  True ,f'已经将用户{username} 冻结'
        return False ,"没有这个用户冻结失败"

    bank_info.py

    """
    银行卡接口业务
    """
    from db import db_hander
    #提现接口
    def withdraw_info(username,menoy):
        #获取用户字典
        user_dic = db_hander.select(username)
        #查看用户的余额是否足够
        balance = int(user_dic.get('balance'))
        menoy_fee = int(menoy) * 1.05 # 提现需要增加百分之五的手续费,此时它已经变成了浮点型(float)
        #判断用户余额是否足够
        if balance >= menoy_fee:
            #修改用户字典中的金额
            balance -= menoy_fee
            user_dic['balance'] = balance
            flow= f'用户{username} 提现{menoy},手续费{menoy_fee-float(menoy)}'  # 因为在上面menoy_fee 在上面变成了浮点型,所以在这里 menoy 也要转换一下
            #保存金额
            db_hander.save(user_dic)
            return True,  flow
        return False,"你的穷屌丝,没钱还来提现"
    #还款接口
    def repay_info(username,money):
        #获取用户信息
        user_dic= db_hander.select(username)
        #充值操作
        user_dic['balance']+=money
        flow= f'用户{username},还款{money}成功 当前余额为{user_dic["balance"]}'
        user_dic['flow'].append(flow)
        #保存数据
        db_hander.save(user_dic)
        return  True, flow
    #转账接口
    def tranfer_hub(login_user,to_user,money):
        #获取当前用户信息
        login_user_dic=db_hander.select(login_user)
        #获取目标用户信息
        to_user_dic= db_hander.select(to_user)
        #检查目标账号是否存在
        if not to_user_dic:
            return  False ,"目标用户不存在"
        #判断当前用户的钱够不够
        if login_user_dic['balance'] >= money:  #如果足够那么进行转账
           #给当前用户做减钱操作
            login_user_dic['balance'] -= money
           #给目标用户做加钱操作
            to_user_dic['balance'] += money
           #记录当前用户流水
            login_user_flow = f'用户{login_user} 给 {to_user} 转了{money}'
            login_user_dic['flow'].append(login_user_flow)
           #保存当前数据
            db_hander.save(login_user_dic)
           #保存目标用户流水
            to_user_flow = f'用户{to_user} 收到 {login_user} 转了{money}'
            to_user_dic['flow'].append(to_user_flow)
           #保存目标用户数据
            db_hander.save(to_user_dic)
            return  True, login_user_flow
        return False ,'当前用户金额不足'
    
    
    #记录流水接口
    def check_flow(login_user):
        user_dic=db_hander.select(login_user)
        return user_dic.get('flow')
    
    
    #支付接口
    def pay_info(login_user,cost):
        user_dic= db_hander.select(login_user)
        if user_dic.get('balance') >= cost:
            user_dic['balance'] -= cost
            #记录流水
            flow = f'用户消费金额:{cost}元'
            user_dic['flow'].append(flow)
            #保存数据
            db_hander.save(user_dic)
            # 这里返回的True 或者false  是给用户接口层
            return True
        return False

    shopping.py

    """
    存放购物车信息
    """
    from bin import bank_info
    from db import db_hander
    #商品准备结算接口
    def shopping_info(login_user,shopping_car):
        cost = 0  # 定义初始金额
        for money_number in shopping_car.values():
            money ,number = money_number
            cost +=(money *number )
    
        flag  = bank_info.pay_info(login_user,cost)
        if flag:
            return  True,"支付成功"
        return  False ,"支付失败"
    #购物车添加接口
    def add_shop_car_info(login_user,shopping_car):
        #获取当前用户的购物车
        user_dic = db_hander.select(login_user)
    
        #获取用户文件中的商品数据
        shop_car = user_dic.get('shop_car')
        #检查当前用户选择的商品是否已经存在
        for shop_name ,money_number in shopping_car.items():
            number =money_number[1] #商品的数量
            if shop_name in shop_car:
                user_dic['shop_car'][shop_name][1] += number  #如果商品重复,要累加商品数量
            else:
                user_dic['shop_car'].upate(
                    {shop_name:money_number}  #如果不重复的,就更新奥字典中
                )
        db_hander.save(user_dic)
        return  True ,"添加购物车成功"
    
    
    #查看购物车接口
    def check_shop_car_info(login_user):
        user_dic = db_hander.select(login_user)
        return user_dic.get('shop_car')

    user_info.py

    """
    用户接口
    """
    import os
    import json
    from lib import common
    from db import db_hander
    user_log=common.get_logger('user')
    
    from config import setting  # 导入获取存放用户信息路径的自定义的模块
    #注册接口
    def redistered_info(username,password,balance=15000):
        #判断用户是否存在
        user_dic = db_hander.select(username)
        if user_dic:
            return False, "您注册的用户已经存在" #相当于返回的一个元组(False ,‘您注册的用户已经存在’)
        #密码加密
        password=common.get_pwd_md5(password)
    
        # 组织用户数据的字典信息
        user_dic = {
            'username': username,
            'password': password,
            'balance': balance,
            'flow': [],  # 定义列表记录ATM流水
            'lock': False,  # 定义用户状态如果为True
            'shop_car': {}
        }
    
        #保存数据
        db_hander.save(user_dic)
        msg = f'{username} 注册成功'
        user_log.info(msg)
        return True, msg
    
    #登录接口
    def login_info(username,password):
        #先查看当前用户是否存在
        user_dic=db_hander.select(username)
        if user_dic.get('lock'):
            return False ,"此账号已经被锁定"
        #判断用户是否存在
        if user_dic:  #后面没有条件对比,意为真就执行下面代码否则不执行
            #给用户输入进来的密码也做加密
            password = common.get_pwd_md5(password)
            if password == user_dic.get('password'):
                msg = f'用户{username} 登录成功'
                user_log.info(msg)
                return  True,msg
            else:
                msg = f'用户{username} 密码错误'
                user_log.error(msg)
                return False, msg
        msg = f'用户{username} 用户不存在'
        user_log.info(msg)
        return  False ,msg
    
    #查询余额
    def check_balance(username):
        user_dic = db_hander.select(username)
        return user_dic['balance']   # 只返回余额这个,如果返回user_dic 就是整个用户信息了

    config  目录下setting.py

    """
    配置信息
    """
    import  os
    # 获取db下存放用户信息的user_data 目录的路径
    BASE_PATCH=os.path.dirname(os.path.dirname(__file__)) #先获取到顶级目录
    USER_DATA=os.path.join(BASE_PATCH,'db','user_data') # 拼接路径获取到存放用户信息的user_data目录
    
    
    standard_format = '%(asctime)s - %(threadName)s:%(thread)d - %(name)s - %(filename)s:%(lineno)d - %(levelname)s - %(message)s'
    
    simple_format = '%(levelname)s -  %(asctime)s - %(filename)s:%(lineno)d - %(message)s'
    
    test_format = '%(asctime)s - %(message)s'
    
    # 3、日志配置字典
    LOGGING_DIC = {
        'version': 1,
        'disable_existing_loggers': False,
        'formatters': {
            'standard': {
                'format': standard_format
            },
            'simple': {
                'format': simple_format
            },
            'test': {
                'format': test_format
            },
        },
        'filters': {},
        'handlers': {
            #打印到终端的日志
            'tty': {
                'level': 'DEBUG',
                'class': 'logging.StreamHandler',  # 打印到屏幕
                'formatter': 'simple'
            },
            #打印到文件的日志,收集info及以上的日志
            # 'fh1': {
            #     'level': 'DEBUG',
            #     'class': 'logging.handlers.RotatingFileHandler',  # 保存到文件,日志轮转
            #     'formatter': 'standard',
            #     # 可以定制日志文件路径
            #     # BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # log文件的目录
            #     # LOG_PATH = os.path.join(BASE_DIR,'a1.log')
            #     'filename': 'a1.log',  # 日志文件
            #     'maxBytes': 1024*1024*5,  # 日志大小 5M
            #     'backupCount': 5,
            #     'encoding': 'utf-8',  # 日志文件的编码,再也不用担心中文log乱码了
            # },
            'fh2': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',  # 保存到文件
                'formatter': 'test',
                'filename': 'a2.log',
                'encoding': 'utf-8',
            },
            'fh1': {
                'level': 'DEBUG',
                'class': 'logging.FileHandler',  # 保存到文件
                'formatter': 'standard',
                'filename': 'a1.log',
                'encoding': 'utf-8',
            },
        },
        'loggers': {
            #logging.getLogger(__name__)拿到的logger配置
    
            '': {
                'handlers': ['fh1', 'fh2'],
                'level': 'DEBUG',
                'propagate': False,
            },
    
        },
    }

    core 目录下文件 src.py admin.py

    src.py

    """
    存放用户视图层
    """
    import json
    import os
    from core import  admin
    #记录已经登录的用户
    login_user=None
    # 1、注册功能
    from bin import user_info
    from bin import  bank_info
    from lib import  common
    from bin import shopping
    def redistered():
        while True:
            #1)用户用输入用户名和密码 进行校验
            username = input("请输入您的用户名").strip() # 去空格
            password = input("请输入您的密码").strip()
            re_password = input("请确认您的密码").strip()
            #判断两次密码是否一致
            if password == re_password:
                #调用接口层的注册接口,将用户名与密码交给接口层来处理
                #res ---> (FALSE,‘您注册的用户名已经存在’)
                #赋值解压,flag,msg ----> (false,'您注册的用户已经存在')
                flag,msg= user_info.redistered_info(
                    username,password
                )
                #根据flag判断是否注册成功
                if flag:  #if 后面不跟条件意为如果为True(真)
                    print(msg)
                    break
                else:
                    print(msg)
    # 2、登录功能
    def login():
        while True:
            username=input("请输入您的用户名:").strip()
            password=input("请输入您的密码:").strip()
            flag,msg=user_info.login_info(username,password)
            if flag:  #后面不跟条件意为如果为真(True)怎执行
                print(msg)
                global login_user   #把这获取到的用户名global 成为全局变量
                login_user=username
                break
            else:
                print(msg)
    # 3、查看余额功能
    @common.login_auth
    def check_balance():
        banlce = user_info.check_balance(login_user)
        print(f'用户{login_user} 您的余额为{banlce}')
    # 4、提现功能
    @common.login_auth
    def withdraw():
        while True:
            input_money= input("请输入要提取的金额").strip() #代表去空格
            #检查用户输入的是否是纯数字
            if not input_money.isdigit():
                print("请重新输入")
                continue
            #调用接口层来实现 用户提取金额
            flag,msg = bank_info.withdraw_info(
                login_user,input_money
            )
            if flag:    #后面不跟条件判断,意为如果结果为真(True) 就执行
                print(msg)
                break
            else:
                print(msg)
    # 5、还款功能
    @common.login_auth
    def repayment():
        while True:
            #让用户输入还款金额
            input_money= input('请输入还款金额').strip()
            #检查用户输入的是否数字
            if not input_money.isdigit():
                print("请输入正确的金额")
                continue
            input_money = int(input_money)
            # 检查用户输入的金额是否为正数
            if input_money >0:
                #调用还款接口
                flag,msg = bank_info.repay_info(
                    login_user,input_money
                )
                if flag: #意为真则执行
                    print(msg)
                    break
            else:
                print("您的还款金额必须大于0")
    # 6、转账功能
    @common.login_auth
    def tranfer():
        """转账的三个条件,当前用户,目标用户,转账金额"""
        while True:
            to_user= input("请输入目标账号").strip()
            money= int(input("请输入转账的金额").strip())
            if money >0:
                flag,msg = bank_info.tranfer_hub(
                    login_user,to_user,money
                )
                if flag: # 后面不跟判断意为如果为真(True)
                    print(msg)
                    break
                else:
                    print(msg)
            else:
                print("请输入正确的金额")
    # 7、查看流水
    @common.login_auth
    def check_water():
        flow_list=bank_info.check_flow(
            login_user
        )
        if flow_list:
            for flow in flow_list:
                print(flow)
        else:
            print("暂时没有流水记录")
    # 8、购物功能
    @common.login_auth
    def shopping():
        product_list = [['Iphone7', 5800],
                        ['Coffee', 30],
                        ['疙瘩汤', 10],
                        ['Python Book', 99],
                        ['Bike', 199],
                        ['ViVo X9', 2499],
    
                        ]
        shopping_car={} #创建一个空字典用于存放添加的商品
        while True:
            #使用枚举的方式来打印商品信息
            for index,shop in enumerate(product_list):   #枚举参数是可迭代对象变为元祖形式---------可迭代对象所以,索引对应的值
                shop_name,shop_money = shop              # 解压赋值
                print(f'商品编号为:{index},商品名称为{shop_name},商品单价为{shop_money}')
            choice=input("请输入商品编号,(是否结账输入 y 或 n)").strip()
            #输入y 代表进入结算功能
            if choice == 'y':
                if not shopping_car:
                    print("购物车是空的,不能结算请重新输入")
                    continue
                #调用支付接口
                flag,msg = shopping.shopping_info(login_user,shopping_car)
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
            elif choice == 'n':
                if not shopping_car:
                    print("购物车是空的,不能结算请重新输入")
                    continue
                flag,msg = shopping.add_shop_car_info(
                    login_user,shopping_car
                )
                if flag:
                    print(msg)
                    break
                else:
                    print(msg)
            if not choice.isdigit():
                print("请输入正确编号")
            choice=int(choice)
    
            if choice not in range(len(product_list)):
                print("请输入正确编号")
                continue
    
    
            shop_name,shop_money = product_list[choice] #获取到商品名称和单价
            #检查用户是否选择了多份同样的商品 默认为1
            if shop_money in shopping_car:
                shopping_car[shop_name][1]+=1              #记录商品被选择的次数
            else:
                shopping_car[shop_name] = [shop_money,1]   #z这里以字典套列表的形式{'商品名称':['钱','数量']}
            print("当前购物车有",shopping_car)
    # 9、查看购物车
    @common.login_auth
    def check_shop_car():
        shop_car=shopping.check_shop_car_info(login_user)
        print(shop_car)
    # 10、管理员功能
    def admin():
        admin.admin_run()
    
    
    
    
    #定义一个功能字典
    func_dic={
        '1':redistered,
        '2':login,
        '3':check_balance,
        '4':withdraw,
        '5':repayment,
        '6':tranfer,
        '7':check_water,
        '8':shopping,
        '9':check_shop_car,
        '10':admin,
    }
    
    
    
    
    def run():
        while True:
            print("""
            1、注册功能
            2、登录功能
            3、查看余额功能
            4、提现功能
            5、还款功能
            6、转账功能
            7、查看流水
            8、购物功能
            9、查看购物车
            10、管理员功能
            11、退出
            """)
            choice = input("请选择您的操作").strip()
            if choice  in func_dic:
                # print("请输入正确的选择")
                # continue
                func_dic.get(choice)() #获取用户输入的功能编号然后调用对应功能函数
            elif choice == '11':
                break
            else:
                print("请输入正确的选择")

    admin.py

    from core import  src
    from bin import  admin_info
    #添加管理员用户
    def add_user():
        src.redistered()
    #修改用户额度
    def change_balace():
        while True:
            change_user = input("请输入您要修改的用户").strip()
            money = input("请输入要修改的额度")
            if not money.isdigit():
                continue
            #调用修改额度的接口
            flag ,msg =admin_info.change_balance_info(
                change_user , money
            )
            if flag:
                print(msg)
                break
            else:
                print(msg)
    #冻结账号
    def lock_user():
        while True:
            #输入需要冻结的账号
            change_lock_user= input("请输入需要冻结的账号").strip()
            flag,msg = admin_info.lock_user_info(
                change_lock_user
    
            )
            if flag:
                print(msg)
                break
            else:
                print(msg)
    
    
    #admin功能字典
    
    admin_func={
        '1': add_user,
        '2': change_balace,
        '3':lock_user,
    }
    def admin_run():
        while True:
            print("""
            '1': 添加管理员账号,
            '2': 修改额度,
            '3':冻结账号,
            """)
            choice = input("请输入管理员功能编号:")
            if choice not in admin_func:
                print("请输入正确的功能编号")
                continue
            admin_func.get(choice)()

    db_hanlder.py

    """
    专门处理用户数据
    """
    import os
    import  json
    from config import setting
    #保存数据
    def select(username):
        #接收传过来的用户名
        user_path = os.path.join(
            setting.USER_DATA,f'{username}.json'
        )
        if os.path.exists(user_path):  # 判断是否有用户名的文件
            with open(user_path, 'r', encoding='utf-8') as f:
                user_dic=json.load(f)
                return user_dic #返回用户数据
    
    
    
    #保存数据
    def save(user_dic): # 接收用户接口文件传过来的用户字典信息
        username = user_dic.get('username') #获取到注册的用户名
        user_path = os.path.join(
            #为了方便取数一个用户一个json 文件以用户名命名的
            setting.USER_DATA,f'{username}.json'
        )
        #保存用户数据,
        with open(user_path,'w',encoding='utf-8') as f:
            json.dump(user_dic,f,ensure_ascii=False) # ensure_ascii =False 可以显示中文

    commony.py

    """
    存放公共方法
    """
    import logging.config
    from config import setting
    #密码加密
    import hashlib
    from core import src
    # 使用md5 加密
    def get_pwd_md5(password):
        md5_obj =hashlib.md5()
        md5_obj.update(password.encode('utf-8'))
        slat = '哈哈哈'  #加盐
        md5_obj.update(slat.encode('utf-8'))
        return  md5_obj.hexdigest()
    
    #登录认证装饰器
    def login_auth(func):
        def wrapper(*args,**kwargs):
            if src.login_user:  #后面没有条件判断意为如果为真(True)
                res= func(*args,**kwargs)
                return res
            else:
                print("请先登录账号")
                src.login()
        return wrapper
    
    #记录日志功能
    def get_logger(log_type):
        #加载日志配置信息
        logging.config.dictConfig(
            setting.LOGGING_DIC
        )
        #获取日志对象
        logger = logging.getLogger(log_type)
        return  logger

    导图思维,readme  文件查看

  • 相关阅读:
    JS 操作属性
    JS 操作对象 事件 样式
    JS 一个页面关闭多个页面
    JS DOM
    JS 语言基础
    JS 基础知识
    CSS样式表
    HTML 常用标记
    HTML iframe框架
    28-2 logging 日志模块
  • 原文地址:https://www.cnblogs.com/yjc53/p/13548965.html
Copyright © 2011-2022 走看看