1 import os 2 import json 3 4 # 获取程序运行目录 5 old_path=os.path.dirname((__file__)) 6 # 拼接db文件夹的路径 7 new_path=os.path.join(old_path,'db') 8 #判断db文件是否存在,取反。如果不存在就创建一个db文件夹 9 if not os.path.exists(new_path): 10 os.makedirs(new_path) 11 12 islogin={'isname':None} #声明一个全局变量的状态,存储用户登录状态、登录成功后将V值改成用户名 13 def login_other(name): 14 ''' 15 校验用户是否登录的装饰器 16 :param name: 17 :return: 登录状态 18 ''' 19 def info(*args,**kwargs): 20 if islogin.get('isname'): 21 res=name(*args,**kwargs) 22 return res 23 else: 24 print('请先登录') 25 Login() 26 27 return info 28 29 def register(): 30 ''' 31 注册函数功能介绍: 32 将用户的注册信息在db文件夹下生成一个以注册账号为名字的json文件、除保存账号和密码以外、默认自定义一个 33 资金键值对和购物车键值对、一个注册信息、一个json文件、对注册信息进行校对、账号是否存在、密码两次校验 34 :return: 35 ''' 36 #1:接收注册信息 37 username=input('输入注册用户名').strip() 38 #2:拼接.json文件的路径(db路径+json文件名) 39 new2_path = os.path.join(new_path, f'{username}.json') 40 #3:检验用户名是否存在,就是检查username.json文件是否存在 41 if os.path.isfile(new2_path): 42 print('用户名已存在') 43 return #结束函数 44 userpwd=input('请输入注册密码').strip() 45 userpwd_two=input('请再出输入注册密码').strip() 46 #4:检验两次输入的密码是否一致,取反、如果两次密码不一样、直接返回retrun结束函数 47 if not userpwd==userpwd_two: 48 print('两次密码不一致') 49 return 50 #5:初始化注册信息,将用户名和密码存储到db_dict字典中、并默认写入余额和空购物车 51 db_dict={'name':username,'pwd':userpwd,'balance':15000,'shop_car':{}} 52 #6:新建一个以username命令的json文件 53 with open(new2_path,'w',encoding='utf8') as f: 54 #7:序列化将db_dict数据写入到json文件中 55 json.dump(db_dict,f) 56 print(f'{username}注册成功') 57 58 59 def Login(): 60 ''' 61 功能解释: 62 用户输入账号密码后、利用账号去找对应的json文件、并将json文件读取出来存到一个字典中、用键值对去比对密码是否正确 63 :return: 64 ''' 65 username=input('请输入登陆账号').strip() 66 #拼接路径 67 login_file=os.path.join(new_path,f'{username}.json') 68 #判断用户名是否存在,就是查询username.json文件是否存在 69 if not os.path.isfile(login_file): 70 print('用户名不存在') 71 return 72 userpwd=input('请输入登陆密码').strip() 73 #解析json文本 74 with open(login_file,'r',encoding='utf8') as f: 75 #将读出来的json数据存储到json_dict字典中 76 json_dict=json.load(f) 77 #单独判断密码就行,用户名前面已经判断过了 78 if userpwd==json_dict.get('pwd'): 79 print('登陆成功') 80 islogin['isname']=username 81 else: 82 print('密码错误') 83 return 84 85 @login_other 86 def add_shop_car(): 87 ''' 88 功能解析: 89 购物车内数据形式为:饼干:[数量,价格] 90 先定义一个商品列表、用for循环带上编号枚举列出后展示、用户输入相应的编号后、将列表中的名字和价格取出来、再让用户输出一个数量、先存放到一个临时字典中 91 用while循环、让用户可以反复添加商品到购物车、如果添加的商品一样、则修改临时列表中的数量、如果不一样、新增新的商品键值对、 92 最后统一添加到json文件中的shop_car里面、添加到json文件中的时候也要做校验、如果临时字典中的商品、在json文件中已经有了、那么就不能直接替换、需要将json 93 文件中的商品键值对取出来。加上临时字典中的商品数量、再次写入进去、否则会将原来json文件中的购物车数据替换掉 94 其他校验:输入的商品编号不能超出商品列表的长度、编号必须为数字、 95 :return: 96 ''' 97 #1:定义一个商品数据 98 food_list=[ 99 ['苹果',10], 100 ['西瓜',20], 101 ['芒果',50], 102 ['榴莲',90], 103 ] 104 #2:商品可以反复添加购买、所以在最外层加一个while循环 105 temp_dict={} 106 while True: 107 #3:将商品数据用枚举的形式打印展示出来 108 for i,j in enumerate(food_list): 109 #4:为了方便展示、将i和j美化后格式化输出 110 print(f'编号:{i} | 品名:{j[0]} | 价格:{j[1]}') 111 # break #为了不一直打印商品列表、这里break结束for循环 112 #5:让用户输入商品编号 113 food_id=input('请输入商品编号或者输入Y结束购物').strip() 114 if food_id=='y': 115 ''' 将数据写入到json文件中去、 116 1:这里需要让用户输入一个指令、程序获取到这个指令后、开始执行将数据写入json文件的操作,所以我们将把输入编号的指令改下 117 2:写入json文件的时候也要做校验、不能直接替换、因为json数据中可能也已经有购物车数据了、如果有相同的数据还是要跟临时数据一样,增加数量''' 118 # 12:将json文件中的数据读出来,赋值给user_date_dict 119 with open(temp_file, 'r', encoding='utf8') as f: 120 user_date_dict = json.load(f) 121 '''考虑到多次添加购物车、为了防止数据被替换、这里加判断''' 122 #将json文件中的购物车数据取出来赋值给real_user_date 123 real_user_date=user_date_dict.get('shop_car') 124 #for循环临时购物车字典、取出K值(商品名) 125 for good_name in temp_dict: 126 #用商品名到real_user_date去找、如果存在则修改数量 127 if good_name in real_user_date: 128 #将真实购物车与临时购物车中同名字商品的数量相加、并赋值到真实购物车里 129 real_user_date[good_name][0]+=temp_dict[good_name][0] 130 else: 131 #否则没有相同的就在把临时字典中的商品名、在真实购物车字典中新建一个键值对赋值过去 132 real_user_date[good_name]=temp_dict[good_name] 133 #将数据统一写入到json文件中 134 user_date_dict['shop_car'] = real_user_date 135 with open(temp_file, 'w', encoding='utf8') as f: 136 json.dump(user_date_dict, f, ensure_ascii=False) # ensure_ascii表示不用ascii码 137 return 138 139 140 141 142 #6:判断用户编号是否为数字、 143 if not food_id.isdigit(): #取反、如不是数字就提示非法、然后return结束 144 print('编号只能为纯数字') 145 return 146 #7:用户输入的编号默认为字符串、将他转换成int整型 147 food_id=int(food_id) 148 #8:判断用户编号是否在合法范围内.取反 149 if food_id not in range(len(food_list)): 150 print('商品编号不存在') 151 return 152 #9:让用户输入购买的数量 153 food_number=input('请输入购买数量').strip() 154 #判断用户输入的数量是否为数字 155 if not food_number.isdigit(): 156 print('数量必须为纯数字') 157 return 158 food_number=int(food_number) 159 #10:将用户输入的购物信息用字典的形式暂时存起来、在循环外先定义一个空字典 160 #11:将信息存入到空字典中,先将商品名字和价格取出来复制给一个变量 161 food_list_l=food_list[food_id] #先取出小字典 162 food_name=food_list_l[0] #用索引取出品名 163 food_price=food_list_l[1] #用索引取出价格 164 165 '''由于购物车商品可以重复添加、所以这里需要加一个校验、如果临时字典中已有同样的 166 商品、则不能替换掉临时字典里的数据、而是要在把此商品在临时列表中数量相加''' 167 # 如果临时字典中已存在、则取出临时字典中food_name对应列表中的数量+=用户输入的数量 168 if food_name in temp_dict: 169 temp_dict[food_name][0] += food_number 170 else: 171 temp_dict[food_name]=[food_number,food_price] 172 #11: 准备将临时字典的数据写入到json文件中、首先要拼接路径,购物车函数外加了校验登录的装饰器、所以这里可以获取到登录名 173 temp_file=os.path.join(new_path,f'%s.json'%islogin.get('isname')) 174 175 176 177 178 179 180 181 182 183 @login_other 184 def settlement(): 185 #拼接json文件路径 186 set_file=os.path.join(new_path,r'%s.json'%islogin['isname']) 187 #读取json文件中的数据 188 with open(set_file,'r',encoding='utf8') as f: 189 set_dict=json.load(f) 190 shop_car_dict=set_dict.get('shop_car') #{'苹果': [30, 10], '西瓜': [20, 20]} 191 #计算价格 192 #1:先定义一个总价的变量 193 Total_price=0 194 #2:获取总价 195 #由于数量和价格是一个列表、用for循环shop_car_dict的values可以得到数量和价格 196 for i,j in shop_car_dict.values(): 197 Total_price+=i*j #每次循环让数量*价格。再+=就可以得到总价 198 #2:获取余额 199 balance=set_dict['balance'] 200 #3:比较余额和总价 201 if Total_price<=balance: 202 real_balance=balance-Total_price 203 set_dict['balance']=real_balance 204 set_dict['shop_car']={} 205 with open(set_file,'w',encoding='utf8') as f: 206 json.dump(set_dict,f) 207 print(f'结算成功,您的余额为{real_balance}') 208 else: 209 print('余额不足') 210 211 212 213 214 215 216 217 218 ''' 219 功能解释: 220 1:将4个函数名、带上编号、存到一个字典中 221 2:让用户输入编号后、利用get取出字典中的V值加()直接调用函数 222 3:判断用户输入编号是否存在字典中、不存在则返回错误提示 223 ''' 224 #1:定义一个功能编号的字典、用序号做K值、用函数名作为V值 225 def_dict={'1':register,'2':Login,'3':add_shop_car,'4':settlement} 226 while True: 227 print(''' 228 1:用户注册 229 2:用户登陆 230 3:添加购物车 231 4:结算购物车 232 ''') 233 choice=input('请输入要执行的功能编号').strip() 234 #判断输入的编号是否在定义的字典中 235 if choice in def_dict: 236 #如果在、则用get方法取出V值直接调用函数 237 def_dict.get(choice)() 238 else: 239 print('功能编号不存在')