常用内置模块(三)

内容概要

  • 简易版购物车
  • hashlib加密模块
  • loggin模块

简易版购物车

点击查看代码
    import os
    import json

    # 获取当前执行文件所在的路径
    user_path = os.path.dirname(__file__)
    # 拼接db文件夹的路径
    data_path = os.path.join(user_path, 'db')
    # 如果没有db文件夹则创建
    if not os.path.exists(data_path):
        os.mkdir(data_path)

    # 定义一个记录用户是否登录的全局变量
    '''不要直接记录整个用户字典 安全性较低 不符合编程原则!!!'''
    is_login = {
        'username': None  # 用户登录成功之后修改为当前用户名
    }
    # 登录验证装饰器 执行添加购物车和结算购物车前验证
    def login_auth(func_name):
        def inner(*args, **kwargs):
            if is_login.get('username'):
                res = func_name(*args, **kwargs)
                return res
            else:
                print('您还没有登录 请先登录')
                login()

        return inner

    def register():
        print('----------注册功能---------')
        # 1.获取用户名 密码和确认密码
        username = input('请输入用户名>>>:').strip()
        password = input('请输入你的密码>>>:').strip()
        con_password = input('请确认密码>>>:').strip()
        # 2.对比两次输入的密码是否一致
        if not password == con_password:
            print('密码不一致')
            return  # 结束函数运行
        # 3.拼接用户数据路径
        file_path = os.path.join(data_path,f'{username}.json')  # db文件夹下的文件
        # 4.校验用户名是否存在即校验文件路径是否存在
        if os.path.isfile(file_path):  # isfile判断文件路径是否存在
            print('用户名已存在 不能再注册')
            return  # 结束函数运行
        # 5.初始化用户数据
        user_info = {'username':username,'password':password,'balance':15000,'shop_car':{}}
        # 序列化到用户数据文件
        with open(file_path, 'w', encoding='utf8') as f:
            json.dump(user_info,f, ensure_ascii=False)
            print(f'{username}注册成功!')

    def login():
        print('---------登录功能---------')
        # 1.获取用户登录的信息
        username = input('请输入用户名>>>:').strip()
        password = input('请输入密码>>>:').strip()
        # 2.拼接用户路径
        file_path = os.path.join(data_path,f'{username}.json')
        # 3.判断用户路径是否存在
        if not os.path.isfile(file_path):
            print('用户不存在 请先注册!!')
            register()  # 用户不存在跳到注册界面提示用户注册
        # 4.如果用户存在 获取用户的详细数据
        with open(file_path, 'r',encoding='utf8') as f:
            user_info = json.load(f)
        # 5.判断密码是否正确
        if password == user_info.get('password'):
            print('登录成功!!!')
        # 6.修改全局字典
            is_login['username'] = username
        else:
            print('密码错误!!!')

    @login_auth
    def add_shop_car():
        """
        购物车数据格式    {'极品木瓜':[个数,单价]}
        """
        print('---------添加购物车-------')
        # 1.定义购物车数据
        good_list = [
            ['挂壁面', 3],
            ['印度飞饼', 22],
            ['极品木瓜', 666],
            ['土耳其土豆', 999],
            ['伊拉克拌面', 1000],
            ['董卓戏张飞公仔', 2000],
            ['仿真玩偶', 10000]
        ]
        # 11.创建一个临时存储商品数据的字典
        temp_car_dict = {}  # 格式为 {'极品木瓜':[11,22],'印度飞饼':[25,3]}
        # 2.商品可反复购买 加循环即可
        while True:
            # 3.反复打印可供购买的商品
            for i,j in enumerate(good_list):  # 用解压赋值和枚举 i=0 j=['挂壁面', 3]
                print(f"商品编号:{i}  |  商品名称:{j[0]}  |  商品单价:{j[1]}")
            # 4.获取用户想要购买的商品编号
            choice = input('请输入您想要购买的商品编号或者输入y退出添加>>>:').strip()
            # 12.如果用户输入y则修改用户购物车保存数据
            if choice == 'y':
                file_path = os.path.join(data_path, '%s.json' % is_login.get('username'))
                with open(file_path, 'r', encoding='utf8') as f:
                    user_info = json.load(f)
                # 修改用户购物车数据(不能直接替换 还要考虑购物车内是否已经存在数据)
                real_shop_car = user_info.get('shop_car')
                for good_name in temp_car_dict:
                    # 判断商品是否已在购物车 如果在则数量相加
                    if good_name in real_shop_car:
                        real_shop_car[good_name][0] += temp_car_dict[good_name][0]
                    else:
                        real_shop_car[good_name] = temp_car_dict[good_name]
                user_info['shop_car'] = real_shop_car
                # 重新写入文件
                with open(file_path,'w', encoding='utf8') as f:
                    json.dump(user_info, f, ensure_ascii=False)
                print('商品数据添加购物车成功')
                break

            # 5.校验用户输入商品编号是否是纯数字
            if not choice.isdigit():
                print('商品编号必须是纯数字')
                continue
            # 6.将用户输入的字符串转成整数 便于后边的索引取值
            choice = int(choice)
            # 7.校验数字是否在编号范围内 即索引范围内
            if not choice in range(len(good_list)):
                print('没有该商品')
                continue
            # 8.获取用户想要购买的商品的数据
            target_good_list = good_list[choice]
            target_good_name = target_good_list[0]
            target_good_price = target_good_list[1]
            # 9.获取用户想要购买的当前商品的数量
            target_good_num = input('输入你想要购买该商品的数量>>>:').strip()
            if target_good_num.isdigit():  # 再结算前 可以添加任意多个商品数量
                # 将输入的字符串型数字转为整型
                target_good_num = int(target_good_num)
                # 10.确认商品和数量 添加购物车 但是要考虑用户还可能购买其他商品
                """临时购物车字典里面可能已经存在一些商品 也可能是第一次购买"""
                if target_good_name not in temp_car_dict:
                    temp_car_dict[target_good_name] = [target_good_num,target_good_price]
                else:
                    temp_car_dict[target_good_name][0] += target_good_num
            else:
                print('商品个数为纯数字')

    @login_auth
    def pay_shop_car():
        print('---------结算购物车------')
        # 1.获取当前用户数据
        file_path = os.path.join(data_path, '%s.json' % is_login.get('username'))
        # 2.获取用户购物车数据
        with open(file_path, 'r', encoding='utf8') as f:
            user_info = json.load(f)
            shop_car = user_info.get('shop_car')
            # 定义总价
            total_money = 0
            # 3.计算商品总价 总价=数量*单价 (取出字典的value 用内置方法values())
            for good_num,good_price in shop_car.values():
                total_money += good_num * good_price
            # 4.判断用户的余额是否买得起商品
            balance = user_info.get('balance')
            if balance > total_money:
                rest_money = balance - total_money
                user_info['balance'] = rest_money
                # 5.支付成功 将购物车清空
                user_info['shop_car'] = {}
                # 6.保存数据
                with open(file_path, 'w', encoding='utf8') as f:
                    json.dump(user_info, f, ensure_ascii=False)
                    print(f'结算成功 今日消费{total_money},您的余额{rest_money} 欢迎下次光临!!!')
            else:
                print('余额不足! 请充值!!!')

    @login_auth
    def money():
        print('----------充值功能---------')
        # 1.获取用户数据
        file_path = os.path.join(data_path,'%s.json' % is_login.get('username'))
        with open(file_path, 'r', encoding='utf8') as f:
            user_info = json.load(f)
        balance = user_info.get('balance')
        # 获取要充值的数据
        add_money = input('请输入您的充值数额>>>:').strip()
        # 判断是否是数字
        if add_money.isdigit():
            new_balance = balance + add_money
            user_info['balance'] = new_balance
            # 保存数据
            with open(file_path, 'w', encoding='utf8') as f:
                json.dump(user_info,f, ensure_ascii=False)
            print(f'成功充值{add_money}!!!')
        else:
            print('请规范输入数额!!!')


    # 定义功能字典通过编号获取对应的功能
    func_dict = {'1':register,'2':login,'3':add_shop_car,'4':pay_shop_car,'5':money}
    while True:
        print("""
        -------------应用功能------------
            1.用户注册
            2.用户登录
            3.添加购物车
            4.结算购物车
            5.充值功能
        """)
        # 获取用户的功能编号
        choice = input('请输入您想要执行的功能编号>>>:').strip()
        if choice in func_dict:
            func_name = func_dict.get(choice)
            func_name()
        else:
            print('请输入正确的功能编号!!!')



hashlib加密模块

    """加密模块"""
    # 什么是加密
        将明文(人看得懂)数据通过一些手段变成密文数据(人看不懂)
        密文数据的表现形式一般都是一串没有规则的字符串

    # 加密算法
        加密算法有很多种>>>(将明文变密文的内部规则)
        算法的难易程度可以根据产生密文的长短来判断
            越长意味着算法越复杂

    # 什么时候使用加密
        涉及到隐私数据的时候 应该考虑使用加密
        最为常见的就是对用户的密码加密 防止密码泄露

    # 基本使用
        import hashlib
      # 1.指定算法>>>:md5算法(最为常见 一般的业务需求足够了)
      # md5 = hashlib.md5()
      # 2.将明文数据传递给算法对象
      # md5.update(b'hello')  # 只能接收bytes类型
      """如果字符串中是纯数字和英文 那么直接在前面加b转成bytes类型"""
      # 3.获取加密之后的密文数据
      # res = md5.hexdigest()
      # print(res)  # 5d41402abc4b2a76b9719d911017c592
      # 在传入数据的时候 只要内容一致 那么算法的结果肯定一致
      md5 = hashlib.md5()
      # md5.update(b'hello')
      # md5.update(b'world')
      # md5.update(b'jason')
      # print(md5.hexdigest())  # 8faebe82e744992e51c86845cac3e1b7
      md5.update(b'helloworldjason')
      print(md5.hexdigest())  # 8faebe82e744992e51c86845cac3e1b7

加密补充

    1.加密之后的结果是无法直接反解密的
        8faebe82e744992e51c86845cac3e1b7
      # 所谓的反解密其实是暴力破解>>>:反复的猜
      """
      md5解密内部本质
        提前想好很多可能是密码的组合
            123						自己加密
            321						自己加密
            222						自己加密
        {'密文1':123,'密文2':321}
      """

    2.加盐处理
        增加破解的难度
      import hashlib
      md5 = hashlib.md5()
      # 加盐处理(添加一些额外的干扰项)
      md5.update('你追我'.encode('utf8'))
      md5.update(b'123')
      print(md5.hexdigest())  # ce850e70febde5f3506fec0479dc0f96

    3.动态加盐
        干扰项动态变化
        可以是用户名的一部分 也可以当前时间...

    """
    加密应用场景
    1.密码加密如何比对
        用户输入的还是明文但是到了程序里面之后会采用相同的加密算法变成密文
        之后拿着密文与跟数据库里面的密文比对如果一致就是密码正确不一致就是错误

    2.文件内容一致性校验
        作为软件的提供者 我们在提供安全软件的同时会对给该软件内容做加密处理得到一个该安全软件独有的密文
        用户在下载软件之后也会对内容做相同的加密之后比对两次密文是否一致
        如果是表示中途没有被修改 如果不是表示中途被修改过 可能存在病毒 
    """
    针对大文件一致性校验的优化策略
        如果一个文件有10G 那么如果全部读取并加密速度太慢
      这个时候可以考虑对文件内容进行切片读取并加密的操作

logging模块

    '''日志模块就是在程序的各个环境记录 便于后续的查看'''
    # 针对日志模块 我们只需要听流程思路 最后CV即可 无需详细记忆

    # 1.日志等级
        import logging
      # 日志按照重要程度分为五个级别:默认只有达到warning警告级别及以上才会记录日志
      # logging.debug('debug message')  # 10
      # logging.info('info message')  # 20
      # logging.warning('warning message')  # 30
      # logging.error('error message')  # 40
      # logging.critical('critical message')  # 50

    # 2.基本使用
        import logging

      file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8', )
      # 所有的格式不需要记忆 后续几乎都是拷贝加修改
      logging.basicConfig(
          format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
          datefmt='%Y-%m-%d %H:%M:%S %p',
          handlers=[file_handler, ],
          level=logging.ERROR
      )

      logging.error('警告多看代码少睡觉!')

posted @ 2022-03-31 21:30  Mr_胡萝卜须  阅读(40)  评论(0)    收藏  举报