zoukankan      html  css  js  c++  java
  • 购物商城

      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()
  • 相关阅读:
    Linux系统排查1——内存篇
    (原创)Python字符串系列(1)——str对象
    (原创)Python文件与文件系统系列(2)——os模块对文件、文件系统操作的支持
    (原创)Python文件与文件系统系列(5)——stat模块
    (原创)Python文件与文件系统系列(4)——文件描述字操作
    CenterOS7——使用yum命令报错Could not retrieve mirrorlist
    awk 查询某一列大于1900的值
    /bin/bash^M: bad interpreter: No such file or directory
    linux 设置时间同步
    CentOS7 服务器分析挖矿病毒,清理挖矿病毒 tor2web
  • 原文地址:https://www.cnblogs.com/alibner/p/6848563.html
Copyright © 2011-2022 走看看