import os
import json
import time
base_dir = os.path.dirname(os.path.dirname(file)) # dirname获取当前文件所在的目录路径,嵌套使用就是获取上一级的路径
db_dir = os.path.join(base_dir, 'db') # 项目根目录路径与'db'拼接
if not os.path.isdir(db_dir): # 判断db文件目录是否存在,就是判断db文件夹存不存在
os.mkdir(db_dir) # 不存在就创建一个
is_login = {'status': False,'real_name': ''}
装饰器
def outer(func):
def inner(args, **kwargs):
if is_login.get('status'):
start_time = time.time() # 获取时间戳
res = func(args, **kwargs)
end_time = time.time() # 再获取时间戳
use_time = end_time - start_time
print(f'程序执行时间为{use_time}') # 打印统计时间
return res
else:
print('您还没有登录,请先登录')
login()
return inner
def register(): # 先写注册功能
while True:
username = input('请输入用户名q>>:').strip()
if username == 'q':
break
user_file_path = os.path.join(db_dir, f'{username}.json') # 将db文件路径与用户名.json文件名拼接,形成字符串,后续打开不需要r''了
if os.path.isfile(user_file_path): # 判断拼接的路径是否已经存在
print('该用户名已经存在,请重新注册')
continue
password = input('请输入密码').strip() # 获取用户密码
age = input('请输入年龄').strip() # 获取用户年龄
user_dict = {
'real_name': username, # 构建用户字典
'real_pwd': password,
'real_age': age,
'real_account': 15000,
'shop_car': {}
}
with open(user_file_path, 'w', encoding='utf8')as f: # 用w模式打开该文件,如果这个文件不存在,就会自动创建该文件了
json.dump(user_dict, f) # 先将字典转为json格式,再写入文件
print('用户注册成功')
break
def login(): # 再写登录功能
while True:
username = input('请输入用户名q>>:').strip()
if username == 'q':
break
user_file_path = os.path.join(db_dir, f'{username}.json') # 还是先拼接出用户名文件路径
if not os.path.isfile(user_file_path): # 判断这个路径存不存在
print('该用户名不存在')
continue
password = input('请输入密码').strip()
with open(user_file_path, 'r', encoding='utf8')as f: # r模式打开用户文件
user_dict2 = json.load(f) # 先读出来,再反序列化将json格式数据转为正常格式数据
if user_dict2.get('real_pwd') == password: # 判断密码是否正确
print('登录成功')
is_login['status'] = True
is_login['real_name'] = username
print(is_login['real_name'])
break
else:
print('密码错误')
@outer
def check1(): # 再写查看功能
while True:
username = input('请输入用户名(q):').strip()
user_file_path = os.path.join(db_dir, f'{username}.json') # 还是先拼接出用户名文件路径
if username == 'q':
break
with open(user_file_path, 'r', encoding='utf8') as f: # 打开用户文件字典
user_dict = json.load(f) # 读出后反序列化转为正常字典,再取出字典里面值,格式化打印输出
print(f"""
------------user_info----------
姓名:{user_dict.get('real_name')}
年龄:{user_dict.get('real_age')}
账户余额:{user_dict.get('real_account')}
-------------------------------
""")
用户可以反复添加商品,在购物车中记录数量
{'极品木瓜':[个数,单价]}
@outer
def add_shop_car():
temp_shop_car888 = {} # 9.构建一个临时购物车可能刚刚用户运行过购物车功能了{木瓜:[数量,价格],飞饼:[数量,价格],}
while True:
good_list = [['挂壁面', 3], ['印度飞饼', 22], ['极品木瓜', 666],
['土耳其土豆', 999], ['伊拉克拌面', 1000],
['董卓戏张飞公仔', 2000], ['仿真玩偶', 10000]
] # 1.获取商品信息(目前是写死的 后期可以动态获取)
# print("""
# 0.挂壁面 单价:3元
# 1.印度飞饼 单价:22元
# 2.极品木瓜 单价:666元
# 3.土耳其土豆 单价:999元
# 4.伊拉克拌面 单价:1000元
# 5.董卓戏张飞公仔 单价:2000元
# 6.仿真玩偶 单价:10000元
# """) 这种手写的肯定不方便,肯定是要考虑如何实现自动化打印出所有的商品信息!!!
for i, j in enumerate(good_list): # 2.循环打印商品信息供用户选择
print(f"商品编号:{i} | 名称:{j[0]} | 单价:{j[1]}")
good_id = input('请输入需要的商品编号(q)>>:').strip() # 3.获取用户输入的商品编号
分隔一下 第三部分
if good_id == 'q': # 13.添加结束标志 用于保存购物车数据
user_file_path = os.path.join(db_dir, f'{is_login.get("real_name")}.json') # 14.获取当前登录用户的字典数据文件路径
with open(user_file_path, 'r', encoding='utf8') as f: # 15.打开用户文件
user_date_dict111 = json.load(f) # 16.读出来并反序列化为用户字典
old_shop_car222 = user_date_dict111.get('shop_car') # 17. 得到用户字典里面的原来的'shop_car'信息 {'印度飞饼':[10, 22]}
# 18.保存购物车数据
"""
user_dict['shop_car'] = temp_shop_car 不能直接替换 可能有原先的数据
比如(老字典)原来购物车user_dict['shop_car']里面的历史数据如下:
{"username": "jason", "password": "123", "balance": 15000, "shop_car": {'印度飞饼':[10, 22]}}
现在临时购物车temp_shop_car里面的信息如下
{'印度飞饼': [1888, 22], '极品木瓜': [10, 666]}
这个时候用上面代码又会直接把原来的{'印度飞饼':[10, 22]}数据直接覆盖掉了!!!!!!!!!
购物车就这个地方绕,其他的地方都简单!!!!!!!!!
"""
for i_name, j_list in temp_shop_car888.items(): # 19.每一次for循环拿到临时字典里面的一组键值对!!! for循环拿出刚刚用户选购生成的临时购物车里的数据
if i_name in old_shop_car222: # 20. 如果临时字典里面的for循环出的键也就是商品名在老字典里面,说原购物车里面已经添加过该商品的数量。
old_shop_car222[i_name][0] += temp_shop_car888[i_name][0] # 21. 将老字典里面的该商品数量,增加一个临时字典里面该商品的数量!!关键!!
else:
old_shop_car222[i_name] = j_list # 22. 如果临时字典里面的for循环出的键也就是商品名不在老字典里面,说明以前没添加过,直接按键添加就行了
# 如果for循环出的临时字典里面的商品名不在老购物车里面,没有就直接将临时字典for循环出的商品名与列表作为键值对添加到老字典里面去!!!
# for循环玩,把老字典里面的信息都更新一遍后,准备把老字典再写进用户文件里面去!!!
user_date_dict111['shop_car'] = old_shop_car222 # 23. 最后将用户字典里的shop_car再更新一下
with open(user_file_path, 'w', encoding='utf8') as f1: # 24. 再重新打开用户文键
json.dump(user_date_dict111, f1, ensure_ascii=False) # 25. w模式重新写入,覆盖掉原数据
print('添加商品成功 欢迎下次再来')
break # 26. 最后结束循环
分隔一下 第二部分
if not good_id.isdigit(): # 4.判断输入商品编号是否为纯数字
print('商品编号必须是纯数字')
continue
good_id = int(good_id) # 5.把字符串转为整型数字
if good_id not in range(len(good_list)): # 6.判断输入的商品编号在不在超出商品的列表范围
print('您选择的商品编号不在已存在的商品编号内 无法选择购买')
continue
good_list_temp = good_list[good_id] # 7.根据商品编号获取商品信息 大列表中对的小列表
good_name = good_list_temp[0] # 拿到小列表中的商品名
good_price = good_list_temp[1] # 拿到小列表里面的商品价格
good_num = input(f'请输入你要购买的{good_name}商品的数量>>:').strip() # 8.获取想要购买的商品个数
if not good_num.isdigit():
print('商品数量必须是纯数字')
continue
good_num = int(good_num) # 10.把字符串转为数字,下面就是购物车最关键的地方了!!!
if good_name in temp_shop_car888: # 11.如果选购的商品名已经再购物车了,说明以前已经选过了,现在又要增加数量!!
temp_shop_car888.get(good_name)[0] += good_num # 12.如果在里面,则要在原来该商品的数量上再加上本次输入的商品数量
else:
temp_shop_car888[good_name] = [good_num, good_price] # 如果不在里面,就直接往字典里面添加键值对
# 列表[0]可以就看成是一个变量名绑定了索引0对应的数据,现在将该变量名重新绑定给,原索引0对应的数据再加上本次用户输入的数量和了,比如
# l1=[11,22]
# l1[0]=l1[0]+3
# print(l1[0]) 结果就是14了
# 也就是说,判断键是否已存在, 如果存在, 则会去该列表,将原临时购物车中的商品的数量,自增用户输入的数量
"""
这个地方不能直接这么写!!!!!! 如果不判断直接添加键值对到临时字典里就会,直接把之前购物车里面的同样商品的价格数量的列表覆盖掉
temp_shop_car[good_name] = [goods_num,goods_price]
# old_temp_shop_car = {'印度飞饼':[10, 22]} 用户第一次选了10个飞饼
# new_temp_shop_car = {'印度飞饼':[10, 22] } 用户第二次右选了10个飞饼,按理说数量应该为20.但由于是直接往字典里加的,
# 字典的键存在会替换值,所以代码直接这样就有问题了!!!
"""
标签:shop,good,name,python,购物车,user,path,十九,字典
From: https://www.cnblogs.com/tengyifan888/p/16823525.html