购物商城

  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         10. 用户登录后,选购商品,不结账,购物车保存. 退出下次登录购物车仍然有上次的记录,结账后清空.
 16         11. 购物车实现删除功能.
 17 
 18     need :
 19         1. 用户输入
 20         2. 商品信息文件
 21         3. 用户信息文件
 22 
 23     待完善:
 24         1. 终端输出有待优化
 25             {
 26                 1. 格式化字符串
 27                 2. 提示语
 28             }
 29         4. None
 30 """
 31 
 32 
 33 # vars and funcs
 34 
 35 # 格式化打印清单; 返回消费总金额
 36 def show_card(dic):
 37     sum_money = 0
 38     top_str = ">>您选购的商品列表<<"
 39     print('
' + top_str.center(100, ' '))
 40     print("-" * 100)
 41     print("{}		{}		{}		{}".format("小计", "数量", "单价", "商品").expandtabs(10))
 42     print("-" * 100)
 43     for ITEM in dic:
 44         sum_money += float(get_price(ITEM)) * int(dic[ITEM])
 45         print('%.2f		%d		%.2f		%s'.expandtabs(10) % (
 46             float(get_price(ITEM)) * int(dic[ITEM]), int(dic[ITEM]),
 47             float(get_price(ITEM)), ITEM))
 48     print("-" * 100)
 49     return sum_money
 50 
 51 
 52 # 判断是否是浮点数
 53 def is_floated(para):
 54     try:
 55         float(para)
 56         return True
 57     except:
 58         return False
 59 
 60 
 61 # 生成随机验证码
 62 def get_random_code():
 63     import random
 64     random_code = ''
 65     for i in range(4):
 66         cur = random.randrange(0, 4)
 67         if cur != i:
 68             temp = chr(random.randint(65, 90))
 69         else:
 70             temp = random.randint(0, 9)
 71         random_code += str(temp)
 72     return random_code
 73 
 74 
 75 # 解锁账户
 76 def unlock_account(username):
 77     print('
解锁账户须进行以下验证')
 78     while True:
 79         code_random = get_random_code()
 80         print('验证码: ', code_random)
 81         user_code = input('请输入上述的验证码: ')
 82         if str(user_code).strip() == code_random:
 83             print('验证通过,请重新设置密码.')
 84             new_pass = input('请输入新密码: ')
 85             confirm_pass = input('请再输一遍密码: ')
 86             if new_pass == confirm_pass:
 87                 for user_item in user_detail_list:
 88                     if user_item['name'] == username:
 89                         user_item['pwd'] = confirm_pass
 90                         user_item['times'] = 0
 91                         return True
 92             else:
 93                 print('输入错误,请重新设置.')
 94         else:
 95             print('验证码输入错误,请重新输入.')
 96 
 97 
 98 # 判断是否有登录在线用户, 返回用户的姓名,登录状态,总金额,用户列表在总用户列表里面的下标
 99 def user_is_auth():
100     rt_list = []
101     for user_dic in user_detail_list:
102         if user_dic['status'] == 1:
103             rt_list.append(user_dic['name'])
104             rt_list.append(user_dic['status'])
105             rt_list.append(user_dic['money'])
106             rt_list.append(user_detail_list.index(user_dic))
107     return rt_list
108 
109 
110 # 返回10条记录, 可根据page_numb来展示
111 def get_ten_record(pas_list, page_numb=1):
112     return_list = []
113     start_num = (int(page_numb) - 1) * 10
114     end_num = int(page_numb) * 10
115     for ITEM in range(start_num, end_num):
116         if ITEM < len(pas_list):
117             return_list.append(pas_list[ITEM])
118     return return_list
119 
120 
121 # 获取商品价格
122 def get_price(goods_name):
123     with open('goods.info', 'r', encoding='utf-8') as file_goods:
124         for goods in file_goods.readlines():
125             goods = goods.strip().split('---')
126             if goods_name in goods:
127                 return goods[-1]
128 
129 
130 # 打印10条记录
131 def show_ten_record(return_list, num):
132     print('
%s		%s		%s'.expandtabs(10) % ('商品ID', '商品价格', '商品名称'))
133     print('-' * 80)
134     for K, ITEM in enumerate(return_list, 1000 + 10 * (num - 1) + 1):
135         print('%d		%.2f¥		%s'.expandtabs(10) % (K, float(ITEM[1]), ITEM[0]))
136         id_list.append(K)
137     print()
138     print_str = ''
139     for i in range(1, end_with):
140         if i != end_with - 1:
141             print_str = print_str + ' ' + str(i) + ' | '
142         else:
143             print_str = print_str + ' ' + str(i) + ' '
144     print(print_str.replace(' ' + str(num) + ' ', ' < ' + str(num) + ' > ') + '
')
145 
146 
147 # ########################## 用户信息文件处理 start ##########################
148 # 存放用户信息
149 # user_detail_list = [
150 #     {
151 #         'name': 'alex',
152 #         'pwd': 12121212,
153 #         'times': 2,
154 #         'money': 120000.00,
155 #         'status': 0
156 #     }
157 #     ...
158 # ]
159 user_detail_list = []
160 
161 with open('db', 'r') as f_user:
162     for user_info in f_user.readlines():
163         user_detail = user_info.split('|')
164         user_detail_list.append({
165             'name': user_detail[0].strip(),
166             'pwd': user_detail[1].strip(),
167             'times': user_detail[2].strip(),
168             'money': user_detail[3].strip(),
169             'status': 0  # 登录状态,未登录0,登录1
170         })
171 
172 # 用户消费记录列表
173 record_user_crash = []
174 # ########################## 用户信息文件处理 end ##########################
175 # ########################## 商品信息文件处理 start ##########################
176 # 将商品信息从文件里面取出来,每行一个列表,存在列表里面
177 book_all_list = []
178 with open('goods.info', 'r', encoding='utf-8') as f_goods:
179     for line in f_goods.readlines():
180         book_list = line.strip().split('---')
181         book_all_list.append(book_list)
182 
183 # 定义空列表,用来存放展示的商品ID,由于可变;因此选择list
184 id_list = []
185 # 定义页码元组
186 lens = len(book_all_list)
187 if lens % 10:
188     end_with = lens // 10 + 2
189 else:
190     end_with = lens // 10 + 1
191 pn_list = tuple(range(1, lens))
192 # 定义用户操作行为元组
193 uc_tuple = ('登录', '购物车')
194 uc_login_tup = ('充值', '结账', '购物车', '退出')
195 
196 # 定义缺省购物车
197 # 购物车设计
198 # default_goods_dic = {
199 #         '老男孩Mysql私房菜': 3
200 #     }
201 default_goods_dic = {}
202 # ########################## 商品信息文件处理 end ##########################
203 # main start
204 print('''

205 欢迎来到老男孩购物商城
206 提示:
207     a. 您可以直接输入商品ID将商品加入购物车
208     b. 您也可以直接登录、查看购物车
209     c. 您也可以输入页码进行翻页
210 ''')
211 print('商品首页')
212 
213 page_num = 1
214 while True:
215     # 默认显示首页
216     show_ten_record(get_ten_record(book_all_list, page_num), page_num)
217 
218     # 获取登录状态
219     res_auth = user_is_auth()
220 
221     # 登录判断
222     if res_auth:
223         # 用户文件名 - 字符串
224         user_record_file = user_is_auth()[0] + '.info'
225 
226         # 用户登录,生成用户所属购物车文件
227         user_choice_file = user_is_auth()[0] + '.car'
228         import os
229 
230         if os.path.exists(user_choice_file):
231             if os.path.getsize(user_choice_file):
232                 with open(user_choice_file, 'r') as fw_shop:
233                     for line in fw_shop.readlines():
234                         shop_record = line.strip().split('---')
235                         default_goods_dic[shop_record[0]] = shop_record[-1]
236             os.remove(user_choice_file)
237         # print(default_goods_dic)
238         # 一次性操作,登录后去掉登录显示
239         uc_temp = uc_login_tup
240         # 打印功能列表
241         for k, v in enumerate(uc_temp, 101):
242             print('{0}. {1}'.format(k, v))
243 
244         user_choice_num = input('
欢迎你, ' + res_auth[0] + ' 请开始你的表演: ')
245     else:
246         # 未登录时,显示登录
247         uc_temp = uc_tuple
248         # 打印功能列表
249         for k, v in enumerate(uc_temp, 101):
250             print('{0}. {1}'.format(k, v))
251 
252         user_choice_num = input('
游客,您好; 请开始你的表演: ')
253 
254     if user_choice_num.isdigit():
255         user_num = int(user_choice_num)
256         if user_num in pn_list:
257             page_num = user_num
258             print('
当前您正在浏览第 {} 页'.format(page_num))
259         elif 100 < user_num < 105:
260             # 登录 默认显示
261             if uc_temp[user_num - 100 - 1] == '登录':
262                 print('login')
263                 flag = True
264                 # 退出次数
265                 exit_flag = 3
266                 # main process
267                 while flag:
268                     user_name = input("用户名: ")
269                     # 遍历用户信息列表
270                     for item in user_detail_list:
271                         # 判断用户名是否存在
272                         if user_name == item['name']:
273                             # 用户存在判断是否锁定
274                             if int(item['times']) < exit_flag:
275                                 user_pwd = input("密码: ")
276                                 # 校验密码
277                                 if user_pwd == item['pwd']:
278                                     print('登录成功

')
279                                     # 更新字典
280                                     item['times'] = 0
281                                     # 写入登录状态
282                                     item['status'] = 1
283                                     # 更新while循环标志位
284                                     flag = False
285                                     # 退出for循环
286                                     break
287                                 else:
288                                     print('密码错误')
289                                     # 更新字典
290                                     item['times'] = int(item['times']) + 1
291                                     # 退出for循环,继续输入用户名
292                                     break
293                             else:
294                                 print("用户已经锁定")
295                                 while True:
296                                     lock_choice = input('1. 更换账户	2. 找回密码
 >> ')
297                                     if lock_choice.isdigit():
298                                         if int(lock_choice) == 1:
299                                             break
300                                         elif int(lock_choice) == 2:
301                                             if unlock_account(user_name):
302                                                 print('重置密码成功,请重新登录')
303                                                 break
304                                 break
305                     else:
306                         print('用户名不存在')
307 
308             # 充值 登录后显示
309             if uc_temp[user_num - 101] == '充值':
310                 charge_money = input('请输入要充值的金额: ')
311                 if is_floated(charge_money):
312                     charge_money = float(charge_money)
313                     item_money = float(res_auth[2])
314                     item_money += charge_money
315                     user_detail_list[res_auth[-1]]['money'] = item_money
316                     print('您已成功充值%.2f元, 账户余额%.2f' % (charge_money, item_money))
317                 else:
318                     print('输入无效')
319 
320             # 结账 登录后显示
321             if uc_temp[user_num - 101] == '结账':
322                 import time
323 
324                 crash_money = 0
325                 if default_goods_dic:
326                     crash_money = show_card(default_goods_dic)
327                     if float(crash_money) > float(res_auth[2]):
328                         print('您本次消费总共:%.2f ;余额不足,您至少需要充值 %.2f 人民币!' % (crash_money, crash_money - float(res_auth[2])))
329                     else:
330                         user_detail_list[res_auth[-1]]['money'] = float(res_auth[2]) - crash_money
331                         print('您本次消费总共:%.2f ;
		账户余额: %.2f !' % (crash_money, float(res_auth[2]) - crash_money))
332                         # 将购物记录记录到文件
333                         for item in default_goods_dic:
334                             each_str = u'{}在{}购买了{}本单价为{}人民币的{}
'.format(
335                                 user_is_auth()[0], time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())),
336                                 default_goods_dic[item], get_price(item), item)
337                             record_user_crash.append(each_str)
338                         # 结账完毕,清空购物车
339                         default_goods_dic.clear()
340                 else:
341                     print('购物车为空')
342 
343             # 查看购物车 默认显示 支持删除
344             if uc_temp[user_num - 101] == '购物车':
345                 crash_money = 0
346                 if default_goods_dic:
347                     while True:
348                         show_card(default_goods_dic)
349                         crash_choice = input('结账请先登录, 查询请输入S/s, 删除请输入D/d, 返回请按Q/q')
350                         if crash_choice.strip().lower() == 's':
351                             while True:
352                                 sc_name = input('请输入要查询的商品名[支持模糊查询,退出请按Q/q]: ')
353                                 if sc_name.strip().lower() != 'q':
354                                     for item in default_goods_dic.keys():
355                                         if sc_name.lower() in item.lower() and sc_name.strip() != '':
356                                             print('%.2f		%d		%.2f		%s'.expandtabs(20) % (
357                                                 float(get_price(item)) * default_goods_dic[item],
358                                                 default_goods_dic[item],
359                                                 float(get_price(item)), item))
360                                 else:
361                                     break
362                         elif crash_choice.strip().lower() == 'd':
363                             while True:
364                                 if default_goods_dic:
365                                     del_name = input('请输入要删除的商品名称, 退出请按Q/q: ')
366                                     if del_name.strip().lower() != 'q':
367                                         try:
368                                             v = default_goods_dic.pop(del_name)
369                                             print('您已经从购物车移除{}本{}'.format(v, del_name))
370                                         except KeyError:
371                                             print('移除失败')
372                                     else:
373                                         break
374                                 else:
375                                     print('购物车已被清空')
376                         elif crash_choice.strip().lower() == 'q':
377                             break
378                 else:
379                     print('购物车为空')
380 
381             # logout
382             if uc_temp[user_num - 101] == '退出':
383                 print('欢迎下次光临')
384                 # 更新用户status
385                 user_detail_list[user_is_auth()[-1]]['status'] = 0
386                 if default_goods_dic:
387                     with open(user_choice_file, 'w') as fw_record:
388                         for item in default_goods_dic.items():
389                             fw_record.writelines(item[0] + '---' + str(item[1]) + '
')
390 
391                 break
392 
393         elif user_num in id_list:
394             # # 添加商品到购物车,若未登录则添加到默认购物车dict,登录成功则创建用户自己的购物车dict
395             # 获取页码数
396             # page_num = int(str(user_num)[-2]) + 1
397             page_num = int(str(user_num - 1)[-2]) + 1
398             # 获取商品列表下标
399             goods_index = int(str(user_num)[-1]) - 1
400             # 得到当前页当前id的商品信息 list
401             goods_info = get_ten_record(book_all_list, page_num)[goods_index]
402             # print(good_info)
403             # 往用户购物车添加记录,若无登录则使用default
404             if goods_info[0] not in default_goods_dic:
405                 default_goods_dic[goods_info[0]] = 1
406             else:
407                 default_goods_dic[goods_info[0]] += 1
408             print('
提示: 您已成功将一本 {} 添加到购物车, 目前数量 {} 本'.format(goods_info[0], default_goods_dic[goods_info[0]]))
409         else:
410             print('表演不满意,请重新开始你的表演
')
411 
412 # 最后,将用户信息写入文件
413 # 写入文件
414 with open('db', 'w') as f_user:
415     for item in user_detail_list:
416         f_user.truncate()
417         item_str = '{name}|{pwd}|{times}|{money}|{status}
'.format_map(item)
418         # print(item_str)
419         f_user.writelines(item_str)
420 
421 # 写入用户的购物记录
422 with open(user_record_file, 'a') as uw_file:
423     uw_file.writelines(record_user_crash)
424 record_user_crash.clear()
原文地址:https://www.cnblogs.com/alibner/p/6848563.html