1 #!/usr/bin/env python 2 """ 3 购物系统 4 5 aim : 6 1. 登录-三次失败锁定; 账户锁定可通过验证码解锁重新设置密码 7 2. 展示商品-分页,当前页焦点 8 3. 购物记录-文件,用户退出会生成一个已购物日志文件. 9 4. 余额浮点数 10 5. 查看购物车支持模糊查询,不区分大小写 11 6. 区分游客和正式用户;游客可直接浏览商品,可直接加入购物车;但购买需登录 12 7. 游客浏览只有登录和购物车两个选项 13 8. 登录后,取消登录选项,增加结账,充值和退出三个选项 14 9. 游客状态的购物车,在登录后仍然保留;可直接进行结账操作. 15 16 need : 17 1. 用户输入 18 2. 商品信息文件 19 3. 用户信息文件 20 21 待完善: 22 1. 终端输出有待优化 23 { 24 1. 格式化字符串 25 2. 提示语 26 } 27 2. 目前购物车都是保存在内存, 程序一旦退出, 会被清空. 28 { 29 可保存在文件, 那么用户登录则可以写入文件;不管什么时候登录, 购物车有上次未购买的东西. 30 } 31 3. 购物车未实现增/删/修功能 32 { 33 1. 查看购物车应有此功能 34 2. 结账时提示也应有此功能 35 } 36 4. None 37 """ 38 39 40 # vars and funcs 41 42 # 格式化打印清单; 返回消费总金额 43 def show_card(dic): 44 sum_money = 0 45 top_str = ">>您选购的商品列表<<" 46 print(‘\n‘ + top_str.center(100, ‘ ‘)) 47 print("-" * 100) 48 print("{}\t\t{}\t\t{}\t\t{}".format("小计", "数量", "单价", "商品").expandtabs(10)) 49 print("-" * 100) 50 for ITEM in dic: 51 sum_money += float(get_price(ITEM)) * dic[ITEM] 52 print(‘%.2f\t\t%d\t\t%.2f\t\t%s‘.expandtabs(10) % ( 53 float(get_price(ITEM)) * dic[ITEM], dic[ITEM], 54 float(get_price(ITEM)), ITEM)) 55 print("-" * 100) 56 return sum_money 57 58 59 # 判断是否是浮点数 60 def is_floated(para): 61 try: 62 float(para) 63 return True 64 except: 65 return False 66 67 68 # 生成随机验证码 69 def get_random_code(): 70 import random 71 random_code = ‘‘ 72 for i in range(4): 73 cur = random.randrange(0, 4) 74 if cur != i: 75 temp = chr(random.randint(65, 90)) 76 else: 77 temp = random.randint(0, 9) 78 random_code += str(temp) 79 return random_code 80 81 82 # 解锁账户 83 def unlock_account(username): 84 print(‘\n解锁账户须进行以下验证‘) 85 while True: 86 code_random = get_random_code() 87 print(‘验证码: ‘, code_random) 88 user_code = input(‘请输入上述的验证码: ‘) 89 if str(user_code).strip() == code_random: 90 print(‘验证通过,请重新设置密码.‘) 91 new_pass = input(‘请输入新密码: ‘) 92 confirm_pass = input(‘请再输一遍密码: ‘) 93 if new_pass == confirm_pass: 94 for user_item in user_detail_list: 95 if user_item[‘name‘] == username: 96 user_item[‘pwd‘] = confirm_pass 97 user_item[‘times‘] = 0 98 return True 99 else: 100 print(‘输入错误,请重新设置.‘) 101 else: 102 print(‘验证码输入错误,请重新输入.‘) 103 104 105 # 判断是否有登录在线用户, 返回用户的姓名,登录状态,总金额,用户列表在总用户列表里面的下标 106 def user_is_auth(): 107 rt_list = [] 108 for user_dic in user_detail_list: 109 if user_dic[‘status‘] == 1: 110 rt_list.append(user_dic[‘name‘]) 111 rt_list.append(user_dic[‘status‘]) 112 rt_list.append(user_dic[‘money‘]) 113 rt_list.append(user_detail_list.index(user_dic)) 114 return rt_list 115 116 117 # 返回10条记录, 可根据page_numb来展示 118 def get_ten_record(pas_list, page_numb=1): 119 return_list = [] 120 start_num = (int(page_numb) - 1) * 10 121 end_num = int(page_numb) * 10 122 for ITEM in range(start_num, end_num): 123 return_list.append(pas_list[ITEM]) 124 return return_list 125 126 127 # 获取商品价格 128 def get_price(goods_name): 129 with open(‘goods.info‘, ‘r‘, encoding=‘utf-8‘) as file_goods: 130 for goods in file_goods.readlines(): 131 goods = goods.strip().split(‘---‘) 132 if goods_name in goods: 133 return goods[-1] 134 135 136 # 打印10条记录 137 def show_ten_record(return_list, num): 138 print(‘\n%s\t\t%s\t\t%s‘.expandtabs(10) % (‘商品ID‘, ‘商品价格‘, ‘商品名称‘)) 139 print(‘-‘ * 80) 140 for K, ITEM in enumerate(return_list, 1000 + 10 * (num - 1) + 1): 141 print(‘%d\t\t%.2f¥\t\t%s‘.expandtabs(10) % (K, float(ITEM[1]), ITEM[0])) 142 id_list.append(K) 143 print() 144 print_str = ‘‘ 145 for i in range(1, len(book_all_list) // 10 + 1): 146 if i != len(book_all_list) // 10: 147 print_str = print_str + ‘ ‘ + str(i) + ‘ | ‘ 148 else: 149 print_str = print_str + ‘ ‘ + str(i) + ‘ ‘ 150 print(print_str.replace(‘ ‘ + str(num) + ‘ ‘, ‘ < ‘ + str(num) + ‘ > ‘) + ‘\n‘) 151 152 153 # ########################## 用户信息文件处理 start ########################## 154 # 存放用户信息 155 # user_detail_list = [ 156 # { 157 # ‘name‘: ‘alex‘, 158 # ‘pwd‘: 12121212, 159 # ‘times‘: 2, 160 # ‘money‘: 120000.00, 161 # ‘status‘: 0 162 # } 163 # ... 164 # ] 165 user_detail_list = [] 166 167 with open(‘db‘, ‘r‘) as f_user: 168 for user_info in f_user.readlines(): 169 user_detail = user_info.split(‘|‘) 170 user_detail_list.append({ 171 ‘name‘: user_detail[0].strip(), 172 ‘pwd‘: user_detail[1].strip(), 173 ‘times‘: user_detail[2].strip(), 174 ‘money‘: user_detail[3].strip(), 175 ‘status‘: 0 # 登录状态,未登录0,登录1 176 }) 177 178 # 用户消费记录列表 179 record_user_crash = [] 180 # ########################## 用户信息文件处理 end ########################## 181 # ########################## 商品信息文件处理 start ########################## 182 # 将商品信息从文件里面取出来,每行一个列表,存在列表里面 183 book_all_list = [] 184 with open(‘goods.info‘, ‘r‘, encoding=‘utf-8‘) as f_goods: 185 for line in f_goods.readlines(): 186 book_list = line.strip().split(‘---‘) 187 book_all_list.append(book_list) 188 189 # 定义空列表,用来存放展示的商品ID,由于可变;因此选择list 190 id_list = [] 191 # 定义页码元组 192 pn_list = tuple(range(1, len(book_all_list) // 10 + 1)) 193 # 定义用户操作行为元组 194 uc_tuple = (‘登录‘, ‘购物车‘) 195 uc_login_tup = (‘充值‘, ‘结账‘, ‘购物车‘, ‘退出‘) 196 197 # 定义缺省购物车 198 # 购物车设计 199 # default_goods_dic = { 200 # ‘老男孩Mysql私房菜‘: 3 201 # } 202 default_goods_dic = {} 203 # ########################## 商品信息文件处理 end ########################## 204 # main start 205 print(‘‘‘\n 206 欢迎来到老男孩购物商城 207 提示: 208 a. 您可以直接输入商品ID将商品加入购物车 209 b. 您也可以直接登录、查看购物车 210 c. 您也可以输入页码进行翻页 211 ‘‘‘) 212 print(‘商品首页‘) 213 214 page_num = 1 215 while True: 216 # 默认显示首页 217 show_ten_record(get_ten_record(book_all_list, page_num), page_num) 218 219 # 获取登录状态 220 res_auth = user_is_auth() 221 222 # 登录判断 223 if res_auth: 224 # 用户文件名 - 字符串 225 user_record_file = user_is_auth()[0] + ‘.info‘ 226 227 # 一次性操作,登录后去掉登录显示 228 uc_temp = uc_login_tup 229 # 打印功能列表 230 for k, v in enumerate(uc_temp, 101): 231 print(‘{0}. {1}‘.format(k, v)) 232 233 user_choice_num = input(‘\n欢迎你, ‘ + res_auth[0] + ‘ 请开始你的表演: ‘) 234 else: 235 # 未登录时,显示登录 236 uc_temp = uc_tuple 237 # 打印功能列表 238 for k, v in enumerate(uc_temp, 101): 239 print(‘{0}. {1}‘.format(k, v)) 240 241 user_choice_num = input(‘\n游客,您好; 请开始你的表演: ‘) 242 243 if user_choice_num.isdigit(): 244 user_num = int(user_choice_num) 245 if user_num in pn_list: 246 page_num = user_num 247 print(‘\n当前您正在浏览第 {} 页‘.format(page_num)) 248 elif 100 < user_num < 105: 249 # 登录 默认显示 250 if uc_temp[user_num - 100 - 1] == ‘登录‘: 251 print(‘login‘) 252 flag = True 253 # 退出次数 254 exit_flag = 3 255 # main process 256 while flag: 257 user_name = input("用户名: ") 258 # 遍历用户信息列表 259 for item in user_detail_list: 260 # 判断用户名是否存在 261 if user_name == item[‘name‘]: 262 # 用户存在判断是否锁定 263 if int(item[‘times‘]) < exit_flag: 264 user_pwd = input("密码: ") 265 # 校验密码 266 if user_pwd == item[‘pwd‘]: 267 print(‘登录成功\n\n‘) 268 # 更新字典 269 item[‘times‘] = 0 270 # 写入登录状态 271 item[‘status‘] = 1 272 # 更新while循环标志位 273 flag = False 274 # 退出for循环 275 break 276 else: 277 print(‘密码错误‘) 278 # 更新字典 279 item[‘times‘] = int(item[‘times‘]) + 1 280 # 退出for循环,继续输入用户名 281 break 282 else: 283 print("用户已经锁定") 284 while True: 285 lock_choice = input(‘1. 更换账户\t2. 找回密码\n >> ‘) 286 if lock_choice.isdigit(): 287 if int(lock_choice) == 1: 288 break 289 elif int(lock_choice) == 2: 290 if unlock_account(user_name): 291 print(‘重置密码成功,请重新登录‘) 292 break 293 break 294 else: 295 print(‘用户名不存在‘) 296 297 # 充值 登录后显示 298 if uc_temp[user_num - 101] == ‘充值‘: 299 charge_money = input(‘请输入要充值的金额: ‘) 300 if is_floated(charge_money): 301 charge_money = float(charge_money) 302 item_money = float(res_auth[2]) 303 item_money += charge_money 304 user_detail_list[res_auth[-1]][‘money‘] = item_money 305 print(‘您已成功充值%.2f元, 账户余额%.2f‘ % (charge_money, item_money)) 306 else: 307 print(‘输入无效‘) 308 309 # 结账 登录后显示 310 if uc_temp[user_num - 101] == ‘结账‘: 311 import time 312 313 crash_money = 0 314 if default_goods_dic: 315 crash_money = show_card(default_goods_dic) 316 if float(crash_money) > float(res_auth[2]): 317 print(‘您本次消费总共:%.2f ;余额不足,您至少需要充值 %.2f 人民币!‘ % (crash_money, crash_money - float(res_auth[2]))) 318 else: 319 user_detail_list[res_auth[-1]][‘money‘] = float(res_auth[2]) - crash_money 320 print(‘您本次消费总共:%.2f ;\n\t\t账户余额: %.2f !‘ % (crash_money, float(res_auth[2]) - crash_money)) 321 # 将购物记录记录到文件 322 for item in default_goods_dic: 323 each_str = u‘{}在{}购买了{}本单价为{}人民币的{}\n‘.format( 324 user_is_auth()[0], time.strftime(‘%Y-%m-%d %H:%M:%S‘, time.localtime(time.time())), 325 default_goods_dic[item], get_price(item), item) 326 record_user_crash.append(each_str) 327 # 结账完毕,清空购物车 328 default_goods_dic.clear() 329 else: 330 print(‘购物车为空‘) 331 332 # 查看购物车 默认显示 333 if uc_temp[user_num - 101] == ‘购物车‘: 334 crash_money = 0 335 if default_goods_dic: 336 show_card(default_goods_dic) 337 crash_choice = input(‘结账请先登录, 查询请输入S/s, 继续请回车‘) 338 if crash_choice.lower() == ‘s‘: 339 while True: 340 sc_name = input(‘请输入要查询的商品名[支持模糊查询,退出请按Q/q]: ‘) 341 if sc_name.lower() != ‘q‘: 342 for item in default_goods_dic.keys(): 343 if sc_name.lower() in item.lower(): 344 print(‘%.2f\t\t%d\t\t%.2f\t\t%s‘.expandtabs(20) % ( 345 float(get_price(item)) * default_goods_dic[item], default_goods_dic[item], 346 float(get_price(item)), item)) 347 else: 348 break 349 else: 350 print(‘购物车为空‘) 351 352 # logout 353 if uc_temp[user_num - 101] == ‘退出‘: 354 print(‘欢迎下次光临‘) 355 break 356 357 elif user_num in id_list: 358 # # 添加商品到购物车,若未登录则添加到默认购物车dict,登录成功则创建用户自己的购物车dict 359 # 获取页码数 360 page_num = int(str(user_num)[-2]) + 1 361 # 获取商品列表下标 362 goods_index = int(str(user_num)[-1]) - 1 363 # 得到当前页当前id的商品信息 list 364 goods_info = get_ten_record(book_all_list, page_num)[goods_index] 365 # print(good_info) 366 # 往用户购物车添加记录,若无登录则使用default 367 if goods_info[0] not in default_goods_dic: 368 default_goods_dic[goods_info[0]] = 1 369 else: 370 default_goods_dic[goods_info[0]] += 1 371 print(‘\n提示: 您已成功将一本 {} 添加到购物车, 目前数量 {} 本‘.format(goods_info[0], default_goods_dic[goods_info[0]])) 372 else: 373 print(‘表演不满意,请重新开始你的表演\n‘) 374 375 # 最后,将用户信息写入文件 376 # 写入文件 377 with open(‘db‘, ‘w‘) as f_user: 378 for item in user_detail_list: 379 f_user.truncate() 380 item_str = ‘{name}|{pwd}|{times}|{money}|{status}\n‘.format_map(item) 381 # print(item_str) 382 f_user.writelines(item_str) 383 384 with open(user_record_file, ‘a‘) as uw_file: 385 uw_file.writelines(record_user_crash) 386 387 record_user_crash.clear()
时间: 2024-10-13 01:05:04