Python基础篇---hashilb加密模块和logging模块

本章内容

       • hashlib模块

       • logging模块

       • 作业

hashlib模块


hashlib模块是加密模块,加密就是将明文数据通过一些手段变成人看不懂的密文数据,密文数据的表现形式一般都是一串没有规则的字符串。

加密算法:将明文变成密文的内部规则。算法的难易程度可以根据产生密文的长短来判断,越长算法越复杂。

当我们涉及到隐私数据的时候,应该考虑使用加密,比较常见的就是对用户的密码进行加密,防止密码泄露。

import hashlib
# 指定算法
md5=hashlib.md5()
# 将明文数据传递给算法对象
md5.update(b'kuci519332')  # 只能接收bytes类型
"""如果字符串中是纯数字和英文 那么直接在前面加b转成bytes类型"""
# 获取加密之后的密文数据
res=md5.hexdigest()
print(res)  # 3cc8dabf3b68130cb9066da1023cfad5
# 在传入数据的时候 只要内容一致 那么算法的结果肯定一致
m=hashlib.md5()
m.update(b'hello')
m.update(b'world')
m.update(b'tom')
print(m.hexdigest())  # 98e5ef2eb2537644da0f786c8a102f63
m.update(b'helloworldtom')
print(m.hexdigest())  # 98e5ef2eb2537644da0f786c8a102f63

加密补充:加密之后的结果是无法直接反解密的,所谓的反解密其实是暴力破解,其实是反复的猜。

md5解密的内部本质:碰撞,即找到一个原文,算出来的MD5码和已知的MD5码一样,就对应上了。

解密的方法:

穷举法
    穷举法非常简单,就是不停地尝试各种字符的排列组合,看哪一个组合的MD5码能对上。可惜缺点是太耗费时间了。
字典法
    把计算结果以字典的形式存放起来,一个萝卜一个坑,一个原文对应着一个MD5码。将已知的MD5码查表,直接反查出原文,缺点是比较费空间。

加盐处理:增加破解的难度

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

动态加盐:干扰项动态变化

利用用户名的一部分,或者当前日期时间等动态的数据来当干扰项。

加密应用场景

密码加密如何比对
	用户输入的还是明文但是到了程序里面之后会采用相同的加密算法变成密文
        之后拿着密文与跟数据库里面的密文比对如果一致就是密码正确不一致就是错误
文件内容一致性校验
        作为软件的提供者 我们在提供安全软件的同时会对给该软件内容做加密处理得到一个该安全软件独有的密文
	用户在下载软件之后也会对内容做相同的加密之后比对两次密文是否一致
	如果是表示中途没有被修改 如果不是表示中途被修改过 可能存在病毒 

  

logging模块


 logging模块是日志模块,日志模块就是在程序的各个环境记录 便于后续的查看。

1.日志等级

日志按照重要程度分为五个级别:默认只有达到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('提示')

 

 作业


1.简单的密码加密存储操作

import json,hashlib
d = {'username': 'jason', 'pwd': '123'}
res = d.get('pwd')
rs=res.encode()
md5=hashlib.md5()
md5.update(rs)
res2=md5.hexdigest()
# 将上述字典写入文件
with open(r'a.txt','w',encoding='utf8') as f:
    json.dump(res2, f)  # 将加密的数据存到文件中
# 获取用户输入的密码
pwd_get=input('输入密码:').strip().encode()
m=hashlib.md5()
m.update(pwd_get)
pwd_md5=m.hexdigest()
# 将文件内容获取出来
with open(r'a.txt','r',encoding='utf8') as f:
    data = json.load(f)
if pwd_md5 == data :
    print('密码正确')
else:
    print('密码错误')
View Code

2.编程题

编程题
    # 项目功能
      1.用户注册
    2.用户登录
    3.添加购物车
    4.结算购物车
  # 项目说明
      用户数据采用json格式存储到文件目录db下 一个用户一个单独的文件
        数据格式 {"name":"jason","pwd":123} 
      # ps:文件名可以直接用用户名便于校验
    用户注册时给每个用户添加两个默认的键值对(账户余额 购物车)
        {"balance":15000,"shop_car":{}}
    添加购物车功能 商品列表可以自定义或者采用下列格式
        good_list = [
                ['挂壁面',3]
                ['印度飞饼', 22]
            ['极品木瓜', 666], 
            ['土耳其土豆', 999],  
            ['伊拉克拌面', 1000],  
            ['董卓戏张飞公仔', 2000],  
            ['仿真玩偶', 10000] 
        ]
      用户可以反复添加商品,在购物车中记录数量
              {'极品木瓜':[个数,单价]}
    结算购物车
        获取用户购物车中所有的商品计算总价并结算即可
  # 思考:针对添加购物车和结算只有登录的用户才可以执行如何实现
编程题目要求

题目初步分析

注册
     用户数据查用json格式存放,需要用到json的序列化和反序列化,
     一个用户一个文件,文件名用用户名便于校验,还要给用户添加两个默认的键值对,
     就直接把用户名,密码,余额和购物车用一个字典存放,利用序列化存放到文件,
     用户名和密码用变量名进行传值,余额和购物车默认参数。

登入
    登入需要从db文件里获取用户名和密码,用户名直接校验文件名是否存在,用反序列化获取文件内容,然后密码直接用键取值去比对。
    针对添加购物车和结算只有登录的用户,需要添加一个全局变量,给登入函数创建一个装饰器,实现校验登入功能。
    登入成功后全局变量修改。

购物车
    商品的存放信息方式是列表,商品可以利用枚举给商品添加索引序号,然后用户通过序号添加商品到购物车,
    用户可以反复添加商品,在购物车中记录数量用字典的方式记录,选择商品后可以添加一个购买的个数,
    添加一次后再添加,不能直接替换,还应该考虑购物车内是否已经存在数据,存在就累加,不存在就添加。

结算
    先获取购物车信息里的商品个数和单价,进行累积,
    判断余额和购物车的总价能否购买。  

分模块编写代码,4个主要功能加上用户功能选择,分为5个模块去编写。

选择功能的模块:

# 给其他4个功能保存到字典中,通过输入的编号选择执行的功能
func_dict = {'1': register, '2': login, '3': add_shop_car, '4': clear_shop_car}
while True:
    print("""
    1.用户注册
    2.用户登录
    3.添加购物车
    4.结算购物车
    """)
    choice = input('请输入您想要执行的功能编号>>>:').strip()
    # 用成员运算判断输入的序号是否存在在字典的键中,
    if choice in func_dict:
        # 存在的话,执行选择的功能
        func_name = func_dict.get(choice)
        func_name()
    else:
        print('功能编号不存在')
View Code

注册模块:

import os
import json

# 获取执行文件所在的路径
current_path = os.path.dirname(__file__)
# 拼接db文件夹的路径,把db文件添加到当前目录,然后将用户名存入db文件。
data_path = os.path.join(current_path, 'db')
if not os.path.exists(data_path):  # 如果文件夹路径不存在
    os.mkdir(data_path)  # 创建该文件夹

def register():
    # 1.利用input方法,获取用户名和密码、确认密码,strip方法去除首尾空格
    username = input('username>>>:').strip()
    password = input('password>>>:').strip()
    confirm_pwd = input('confirm_pwd>>>:').strip()
    # 2.先比对两次密码是否一致
    if not password == confirm_pwd:
        print('两次密码不一致')
        return  # 如果2次密码不一致,结束函数运行(这里也可以在外层弄个大循环)
    # 3.拼接用户数据文件路径,先通过os.path.dirname(__file__)获取当前执行文件的路径,
    file_path = os.path.join(data_path, f'{username}.json')  # ...db/tony.json
    # 4.校验用户名是否已存在>>>:因为文件名是用用户名的,校验文件路径是否存在就相当于校验用户是否存在
    if os.path.isfile(file_path):  # 用os模块里的 isfile 判断文件存在了 就是用户存在了
        print('用户名已存在')
        return  # 结束函数运行
    # 5.初始化用户数据,直接把用户名,密码,余额和购物车用一个字典存放,用户名和密码用变量名进行传值,余额和购物车默认参数。
    user_dict = {'username': username, 'password': password, 'balance': 15000, 'shop_car': {}}
    # 6.序列化到文件中,利用json模块的dump序列号用户数据存入文件,注册也完成了。
    with open(file_path, 'w', encoding='utf8') as f:
        json.dump(user_dict, f)
    print(f'{username}注册成功')
View Code

登入模块:

# 定义一个记录用户是否登录的全局变量,用字典记录用户的用户名,没有登入前为none,用户登录成功之后修改为当前用户名,
# 也方便后面获取当前用户的余额和购物车进行操作。
'''不要直接记录整个用户字典 安全性较低 不符合编程原则!!!'''
is_login = {
    'username': None  # 用户登录成功之后修改为当前用户名
}

# 登录认证装饰器
def login_auth(func_name):
    def inner(*args, **kwargs):
        if is_login.get('username'):  # 用于判断当前用户有没有登入,如果登入了全局变量里is_login的username的值为用户名,布尔值为True。
            res = func_name(*args, **kwargs)  # 执行被修饰的函数
            return res # 返回
        else:
            print('您还没有登录 请先登录')  # 没有登入,username值为none,布尔值为False,执行登入操作。
            login()

    return inner

def login():
    # 1.获取用户名和密码,也是通过input和strip获取
    username = input('username>>>:').strip()
    password = input('password>>>:').strip()
    # 2.拼接用户文件路径 data_path是db文件的路径,在后面添加输入的用户名,
    file_path = os.path.join(data_path, f'{username}.json')
    # 3.判断文件路径是否存在  如果存在表示有这个用户 不存在表示没有
    if not os.path.isfile(file_path):
        print('用户名不存在')
        return  # 用户名不存在利用return结束函数的运行
    # 4.用户名存在 通过json的反序列化获取用户的数据,进行比对
    with open(file_path, 'r', encoding='utf8') as f:
        user_dict = json.load(f)  # {'username':'jason','password':123}
    # 5.因为用户数据的密码是通过键值对的方式存储,可以直接通过键获取密码,判断密码是否正确
    if password == user_dict.get('password'):
        print('登录成功')
        # 6.修改全局字典
        is_login['username'] = username
    else:
        print('密码错误')
View Code

购物车模块:

@login_auth  # 用装饰器语法糖判断用户是否登入
def add_shop_car():
    """
    购物车数据格式    {'极品木瓜':[个数,单价]}
    """
    # 1.定义购物车数据(代码直接写死 也可以通过专门的商品文件便于后期维护更新)
    good_list = [
        ['挂壁面', 3],
        ['印度飞饼', 22],
        ['极品木瓜', 666],
        ['土耳其土豆', 999],
        ['伊拉克拌面', 1000],
        ['董卓戏张飞公仔', 2000],
        ['仿真玩偶', 10000]
    ]
    # 11.我们可以创建一个临时存储商品数据的字典
    temp_shop_car = {}  # {'极品木瓜':[10,22],'印度飞饼':[100,3]}
    # 2.打印商品信息供用户选择,商品可以反复购买,所以这里可以加循环,
    while True:
        # 3.循环打印商品信息供用户选择  最好给商品添加编号,所以可以利用enumerate枚举,
        # 因为枚举出来的数据是由索引个值组成的,所以可以用i表示商品的编号,用j表示商品的信息,方便后面信息的获取
        for i, j in enumerate(good_list):  # i=0 j=['挂壁面', 3]
            print("商品编号:%s  |  商品名称:%s  |   商品单价:%s" % (i, j[0], j[1]))
        # 4.用input strip获取用户想要购买的商品编号,
        choice = input('请输入您想要购买的商品编号或者输入y退出添加>>>:').strip()
        # 12.修改用户购物车数据保存,如果用户输入的是y,就执行退出购物车功能保持数据
        if choice == 'y':
            # 通过获取全局变量is——login里的用户名,我们就可以知道我们要保持数据到哪个用户的数据,也就是哪个文件路径里。
            file_path = os.path.join(data_path, '%s.json' % is_login.get('username'))
            with open(file_path, 'r', encoding='utf8') as f:
                user_dict = json.load(f)
            # 修改用户购物车数据(不能直接替换 还应该考虑购物车内是否已经存在数据)
            # 通过get键获取购物车内已存在的数据
            real_shop_car = user_dict.get('shop_car')  # {'极品木瓜':[1,22]}
            # 用遍历获取临时存储购物车字典里的商品
            for good_name in temp_shop_car:
                if good_name in real_shop_car: # 如果临时购物车里商品存在与真实购物车里,主要通过索引购物车信息里的数目进行累加
                    real_shop_car[good_name][0] += temp_shop_car[good_name][0]
                else:  # 如果临时购物车里商品不存在与真实购物车里,就直接通过添加临时购物车里的商品进真实购物车里
                    real_shop_car[good_name] = temp_shop_car[good_name]
            # 保存修改好的真实购物车数据
            user_dict['shop_car'] = real_shop_car
            # 利用序列号重修写入到用户的数据文件里,购物车修改添加成功
            with open(file_path, 'w', encoding='utf8') as f:
                json.dump(user_dict, f, ensure_ascii=False)
            print('商品数据添加购物车成功')
            break

        # 5.用isdigit校验输入的商品编号是否是纯数字
        if not choice.isdigit():
            print('商品编号必须是数字')
            continue
        # 6.将用户输入的字符串类型编号转成整数类型便于后续索引取值
        choice = int(choice)
        # 7.通过len获取列表里的商品个数,校验数字范围是否在商品列表的索引范围内
        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] # 索引1 获取商品单价,后面计算总价用
        # 9.获取用户想要购买的当前商品的数量
        target_num = input('请输入你想要购买的数量>>>:').strip()
        if target_num.isdigit():  # 判断输入的是否是纯数字,
            target_num = int(target_num)  # 将输入的纯数字转成整型
            # 10.确定了商量和数量 添加购物车 但是要考虑用户还可能购买其他商品
            """临时购物车字典里面可能已经存在一些商品 也可能是第一次购买"""

            if target_good_name not in temp_shop_car:  # {'极品木瓜':[1,666]} 利用成员运算,判断购物车里是否有当前需要被添加的商品
                # 没有的话,给购物车字典传由商品为键,商品数目和商品单价组成的列表为值
                temp_shop_car[target_good_name] = [target_num, target_good_price]
            else:
                # 由的话 通过索引获取当前商品已有的数目,然后加上需要添加的数目即可。
                temp_shop_car[target_good_name][0] += target_num  # {'极品木瓜':[1+9,666]}
                # 然后就考虑然后保持数据到用户信息里的购物车
        else:
            print('商品的个数必须是纯数字')
View Code

结算模块:

@login_auth  # 用装饰器语法糖判断一下用户是否登入
def clear_shop_car():
    # 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_dict = json.load(f)
    shop_car = user_dict.get('shop_car')  # {'商品名称':[个数,单价]}
    # 定义一个总价 
    total_money = 0
    # 3.因为商品单价个数目是一个列表还是一个字典的值,通过values获取信息列表,利用解压赋值和遍历获取所以商品信息里单价和数目,
    for good_num,good_price in shop_car.values():  # [个数,单价]
        total_money += good_num * good_price
    # 4.有了总价还需要判断用户能否买得起,用get方法获取用户数据里的余额
    balance = user_dict.get('balance')
    if balance > total_money:
        # 余额大于总价,余额减总价 等到一个新的余额
        rest_money = balance - total_money
        # 将新的余额传入用户数据
        user_dict['balance'] = rest_money
        # 5.扣钱完毕 清空购物车
        user_dict['shop_car'] = {}
        # 6.利用json的序列化将修改后的用户数据写入文件中进行保存,nsure_ascii=False可以将存入的数据中的中文保留。
        with open(file_path,'w',encoding='utf8') as f:
            json.dump(user_dict, f, ensure_ascii=False)
        print(f'结算成功 今日消费{total_money} 余额{rest_money} 欢迎下次光临!!!')
    else:
        print('钱不够 你个穷逼!!!')
View Code

总代码:

import os
import json

# 获取执行文件所在的路径
current_path = os.path.dirname(__file__)
# 拼接db文件夹的路径,把db文件添加到当前目录,然后将用户名存入db文件。
data_path = os.path.join(current_path, 'db')
if not os.path.exists(data_path):  # 如果文件夹路径不存在
    os.mkdir(data_path)  # 创建该文件夹

# 定义一个记录用户是否登录的全局变量,用字典记录用户的用户名,没有登入前为none,用户登录成功之后修改为当前用户名,
# 也方便后面获取当前用户的余额和购物车进行操作。
'''不要直接记录整个用户字典 安全性较低 不符合编程原则!!!'''
is_login = {
    'username': None  # 用户登录成功之后修改为当前用户名
}
def register():
    # 1.利用input方法,获取用户名和密码、确认密码,strip方法去除首尾空格
    username = input('username>>>:').strip()
    password = input('password>>>:').strip()
    confirm_pwd = input('confirm_pwd>>>:').strip()
    # 2.先比对两次密码是否一致
    if not password == confirm_pwd:
        print('两次密码不一致')
        return  # 如果2次密码不一致,结束函数运行(这里也可以在外层弄个大循环)
    # 3.拼接用户数据文件路径,先通过os.path.dirname(__file__)获取当前执行文件的路径,
    file_path = os.path.join(data_path, f'{username}.json')  # ...db/tony.json
    # 4.校验用户名是否已存在>>>:因为文件名是用用户名的,校验文件路径是否存在就相当于校验用户是否存在
    if os.path.isfile(file_path):  # 用os模块里的 isfile 判断文件存在了 就是用户存在了
        print('用户名已存在')
        return  # 结束函数运行
    # 5.初始化用户数据,直接把用户名,密码,余额和购物车用一个字典存放,用户名和密码用变量名进行传值,余额和购物车默认参数。
    user_dict = {'username': username, 'password': password, 'balance': 15000, 'shop_car': {}}
    # 6.序列化到文件中,利用json模块的dump序列号用户数据存入文件,注册也完成了。
    with open(file_path, 'w', encoding='utf8') as f:
        json.dump(user_dict, f)
    print(f'{username}注册成功')

# 登录认证装饰器
def login_auth(func_name):
    def inner(*args, **kwargs):
        if is_login.get('username'):  # 用于判断当前用户有没有登入,如果登入了全局变量里is_login的username的值为用户名,布尔值为True。
            res = func_name(*args, **kwargs)  # 执行被修饰的函数
            return res # 返回
        else:
            print('您还没有登录 请先登录')  # 没有登入,username值为none,布尔值为False,执行登入操作。
            login()

    return inner

def login():
    # 1.获取用户名和密码,也是通过input和strip获取
    username = input('username>>>:').strip()
    password = input('password>>>:').strip()
    # 2.拼接用户文件路径 data_path是db文件的路径,在后面添加输入的用户名,
    file_path = os.path.join(data_path, f'{username}.json')
    # 3.判断文件路径是否存在  如果存在表示有这个用户 不存在表示没有
    if not os.path.isfile(file_path):
        print('用户名不存在')
        return  # 用户名不存在利用return结束函数的运行
    # 4.用户名存在 通过json的反序列化获取用户的数据,进行比对
    with open(file_path, 'r', encoding='utf8') as f:
        user_dict = json.load(f)  # {'username':'jason','password':123}
    # 5.因为用户数据的密码是通过键值对的方式存储,可以直接通过键获取密码,判断密码是否正确
    if password == user_dict.get('password'):
        print('登录成功')
        # 6.修改全局字典
        is_login['username'] = username
    else:
        print('密码错误')

@login_auth  # 用装饰器语法糖判断用户是否登入
def add_shop_car():
    """
    购物车数据格式    {'极品木瓜':[个数,单价]}
    """
    # 1.定义购物车数据(代码直接写死 也可以通过专门的商品文件便于后期维护更新)
    good_list = [
        ['挂壁面', 3],
        ['印度飞饼', 22],
        ['极品木瓜', 666],
        ['土耳其土豆', 999],
        ['伊拉克拌面', 1000],
        ['董卓戏张飞公仔', 2000],
        ['仿真玩偶', 10000]
    ]
    # 11.我们可以创建一个临时存储商品数据的字典
    temp_shop_car = {}  # {'极品木瓜':[10,22],'印度飞饼':[100,3]}
    # 2.打印商品信息供用户选择,商品可以反复购买,所以这里可以加循环,
    while True:
        # 3.循环打印商品信息供用户选择  最好给商品添加编号,所以可以利用enumerate枚举,
        # 因为枚举出来的数据是由索引个值组成的,所以可以用i表示商品的编号,用j表示商品的信息,方便后面信息的获取
        for i, j in enumerate(good_list):  # i=0 j=['挂壁面', 3]
            print("商品编号:%s  |  商品名称:%s  |   商品单价:%s" % (i, j[0], j[1]))
        # 4.用input strip获取用户想要购买的商品编号,
        choice = input('请输入您想要购买的商品编号或者输入y退出添加>>>:').strip()
        # 12.修改用户购物车数据保存,如果用户输入的是y,就执行退出购物车功能保持数据
        if choice == 'y':
            # 通过获取全局变量is——login里的用户名,我们就可以知道我们要保持数据到哪个用户的数据,也就是哪个文件路径里。
            file_path = os.path.join(data_path, '%s.json' % is_login.get('username'))
            with open(file_path, 'r', encoding='utf8') as f:
                user_dict = json.load(f)
            # 修改用户购物车数据(不能直接替换 还应该考虑购物车内是否已经存在数据)
            # 通过get键获取购物车内已存在的数据
            real_shop_car = user_dict.get('shop_car')  # {'极品木瓜':[1,22]}
            # 用遍历获取临时存储购物车字典里的商品
            for good_name in temp_shop_car:
                if good_name in real_shop_car: # 如果临时购物车里商品存在与真实购物车里,主要通过索引购物车信息里的数目进行累加
                    real_shop_car[good_name][0] += temp_shop_car[good_name][0]
                else:  # 如果临时购物车里商品不存在与真实购物车里,就直接通过添加临时购物车里的商品进真实购物车里
                    real_shop_car[good_name] = temp_shop_car[good_name]
            # 保存修改好的真实购物车数据
            user_dict['shop_car'] = real_shop_car
            # 利用序列号重修写入到用户的数据文件里,购物车修改添加成功
            with open(file_path, 'w', encoding='utf8') as f:
                json.dump(user_dict, f, ensure_ascii=False)
            print('商品数据添加购物车成功')
            break

        # 5.用isdigit校验输入的商品编号是否是纯数字
        if not choice.isdigit():
            print('商品编号必须是数字')
            continue
        # 6.将用户输入的字符串类型编号转成整数类型便于后续索引取值
        choice = int(choice)
        # 7.通过len获取列表里的商品个数,校验数字范围是否在商品列表的索引范围内
        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] # 索引1 获取商品单价,后面计算总价用
        # 9.获取用户想要购买的当前商品的数量
        target_num = input('请输入你想要购买的数量>>>:').strip()
        if target_num.isdigit():  # 判断输入的是否是纯数字,
            target_num = int(target_num)  # 将输入的纯数字转成整型
            # 10.确定了商量和数量 添加购物车 但是要考虑用户还可能购买其他商品
            """临时购物车字典里面可能已经存在一些商品 也可能是第一次购买"""

            if target_good_name not in temp_shop_car:  # {'极品木瓜':[1,666]} 利用成员运算,判断购物车里是否有当前需要被添加的商品
                # 没有的话,给购物车字典传由商品为键,商品数目和商品单价组成的列表为值
                temp_shop_car[target_good_name] = [target_num, target_good_price]
            else:
                # 由的话 通过索引获取当前商品已有的数目,然后加上需要添加的数目即可。
                temp_shop_car[target_good_name][0] += target_num  # {'极品木瓜':[1+9,666]}
                # 然后就考虑然后保持数据到用户信息里的购物车
        else:
            print('商品的个数必须是纯数字')

@login_auth  # 用装饰器语法糖判断一下用户是否登入
def clear_shop_car():
    # 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_dict = json.load(f)
    shop_car = user_dict.get('shop_car')  # {'商品名称':[个数,单价]}
    # 定义一个总价
    total_money = 0
    # 3.因为商品单价个数目是一个列表还是一个字典的值,通过values获取信息列表,利用解压赋值和遍历获取所以商品信息里单价和数目,
    for good_num,good_price in shop_car.values():  # [个数,单价]
        total_money += good_num * good_price
    # 4.有了总价还需要判断用户能否买得起,用get方法获取用户数据里的余额
    balance = user_dict.get('balance')
    if balance > total_money:
        # 余额大于总价,余额减总价 等到一个新的余额
        rest_money = balance - total_money
        # 将新的余额传入用户数据
        user_dict['balance'] = rest_money
        # 5.扣钱完毕 清空购物车
        user_dict['shop_car'] = {}
        # 6.利用json的序列化将修改后的用户数据写入文件中进行保存,nsure_ascii=False可以将存入的数据中的中文保留。
        with open(file_path,'w',encoding='utf8') as f:
            json.dump(user_dict, f, ensure_ascii=False)
        print(f'结算成功 今日消费{total_money} 余额{rest_money} 欢迎下次光临!!!')
    else:
        print('钱不够 你个穷逼!!!')

# 给其他4个功能保存到字典中,通过输入的编号选择执行的功能
func_dict = {'1': register, '2': login, '3': add_shop_car, '4': clear_shop_car}
while True:
    print("""
    1.用户注册
    2.用户登录
    3.添加购物车
    4.结算购物车
    """)
    choice = input('请输入您想要执行的功能编号>>>:').strip()
    # 用成员运算判断输入的序号是否存在在字典的键中,
    if choice in func_dict:
        # 存在的话,执行选择的功能
        func_name = func_dict.get(choice)
        func_name()
    else:
        print('功能编号不存在')
View Code

 

心得体会:

         这个编程题用到了很多之前学习到的知识点,都是通过之前学的小知识点结合起来的,近期学的知识点还好,有的时候有很些知识点已经有些模糊了,就比如枚举,我印象里是有一个可以把索引和值结合起来输出的方法,就是想不到,还是通过翻自己写的博客去复习。还有就是编程逻辑和编程代码的实现不符合,能想到怎么实现这个功能的逻辑,但用代码写出来就有点困难了,还是知识点掌握的不够全,代码写的太少,还得练。

        编写一个程序代码的方法,可以先把功能模块的结构搭建起来,然后再去完善功能代码。对于比较复杂的业务逻辑,可以先写纯注释的思维逻辑,然后一步一步的编写成python代码。完成一个功能,先找到功能的主题部分,然后再去补充和完善代码。可以写一个功能运行一下检查逻辑很代码问题。

 

posted @ 2022-03-31 19:30  早安_1207  阅读(112)  评论(0)    收藏  举报
返回顶端