python实现购物车

个人正在学习python,在网上找了几道练习题,题目参考:流程图以及参考代码

作业要求:

1、启动程序后,可以选择注册、登录、退出

2、选择注册后可以输入用户名和密码进行注册

3、注册后会重新选择,然后登录进入,每次登录时会提示上一次登录时间

4、选择退出时会打印购物车的历史购物记录(购物时间、商品名称、商品数量)

5、登录失败三次时会被锁定

6、可以进行充值

7、选择商品种类三级进行选择需要购买的商品

8、每次操作之前都可以选择退出或者返回上一步

参考代码:

black_list.json

{
    "terry": null
}

database.json

{
    "lierl": {
        "balance": 1502.0,
        "last_login_time": "2018-04-01 09:34:01",
        "pwd": "ec34a5f24bbbe82ad0d89ac656674316",
        "register_time": "2018-04-01 08:36:07",
        "shopping_list": [
            {
                "buy_time": "2018-04-01 08:00:10",
                "goods_name": "森马",
                "goods_num": 3
            },
            {
                "buy_time": "2018-04-01 09:34:28",
                "goods_name": "乐视电视",
                "goods_num": 2
            }
        ]
    }
}

goods.json

{
  "家电类": {
    "电视": {
      "小米电视": 3999,
      "乐视电视": 4299
    },
    "空调": {
      "格力空调": 8999,
      "海尔空调": 6000
    },
    "冰箱": {
      "美的冰箱": 5099,
      "西门子冰箱": 4599
    }
  },
  "3C类": {
    "电脑": {
      "联想笔记本": 6888,
      "mac air": 8009
    },
    "手机": {
      "小米5": 1999,
      "iPhone6": 5299
    }
  },
  "生活类": {
    "鞋子": {
      "NIKE篮球鞋": 899,
      "安踏": 399
    },
    "T恤": {
      "森马": 89,
      "真维斯": 75,
      "优衣库": 97
    }
  }
}

代码参考:

#!/usr/bin/env python3
# encoding:utf-8
'''
@author: lierl
@file: do_shopping_cart.py
@time: 2018/3/31 11:44
'''
import datetime

__author__ = 'lierl'

'''
程序要求

1、启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表
2、允许用户根据商品编号购买商品
3、用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒
4、可随时退出,退出时,打印已购买商品和余额
5、在用户使用过程中, 关键输出,如余额,商品已加入购物车等消息,需高亮显示
6、用户下一次登录后,输入用户名密码,直接回到上次的状态,即上次消费的余额什么的还是那些,再次登录可继续购买
7、允许查询之前的消费记录

shopping过程中余额不足的话,无法在购物过程中直接充值,所以增加了判断,让用户在购物过程中可以选择充值、退出、返回

循环打印第一级的分类的时候,使用enumerate,可以输出下标,而脚本中没有使用下标进行判断,而是让用户直接输入分类名称,实际上这个地方使用enumerate更灵活,后面判断用户输入的时候,可以用下标判断或用分类判断
开始使用了os.system('clear'),但是发生乱码问题,应该是字符集的问题
'''
import json
import re
import hashlib
'''
编码:把一个Python对象编码转换成Json字符串   json.dumps()   返回str
解码:把Json格式字符串解码转换成Python对象   json.loads()   返回dict,也可转为相应的对象

问题:
为何不把加载database.json之后的数据声明成全局变量,因为个人可能多次购买,每购买一次会写入到database.json,如果生命全局变量,则加载新的数据,会导致问题
'''

welcome_info = '''
1. 按"A"注册
2. 按"B"登录
3. 按"Q"退出
'''

#加载json文件,默认加载database.json
def _load_database(filename = 'database.json'):
    with open(file=filename, mode='r', encoding='utf-8') as f:
        database = json.load(f)
    return database#dict字段

#用于将购物相关信息保存到JSON文件,比如购物时间,购物历史,购物列表,账户余额,创建的新用户和现有已存在用户信息
def _save_account(database, filename='database.json'):
    # 打开并可写文件,若文件已存在,则以前的内容将被清除
    with open(file=filename, mode='w', encoding="utf-8") as f:
        json.dump(database, f, indent=4, sort_keys=True, ensure_ascii=False)#把dict写入到文件中

#获取当前格式化后的时间
def _get_current_format_time():
    return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')#获取当前时间


#获取用户的购物日期
def _get_shopping_date(account):
    database = _load_database()
    return database[account]['shopping_time']

#获取历史购物信息
def _get_shopping_history(account):
    database = _load_database()
    account_data = database[account]#dict
    history_shopping_list = account_data['shopping_list']#list
    if len(history_shopping_list) > 0:#如果购物列表中有数据
        for history_shopping_data in history_shopping_list:
            buy_time = history_shopping_data['buy_time']#购买时间
            goods_name = history_shopping_data['goods_name']#商品名称
            goods_num = history_shopping_data['goods_num']#购买数量
            print("您于%s购买了%s件%s" % (buy_time, goods_num, goods_name))
    else:
        print("您的购物车是空的。。。")

#默认设置变量account=None来判断账号是否已经登录,如果没有登录就退出,则不打印购物信息
#如果已经登录过,则打印购物历史信息
def _logout(account_name = None):
    if account_name is not None:
        _get_shopping_history(account_name)
    print('感谢您的光临,欢迎下次光临')
    exit()

#获取账户余额
def _get_balance(account_name):
    database = _load_database()
    return database[account_name]['balance']

#购物
def _shopping(account_name):
    goods = _load_database(filename='goods.json')#从文件中获取所有的商品

    while True:
        goods_first = {}
        goods_first_index = []
        for index, good in enumerate(goods, start=1):
            goods_first[index] = good
            goods_first_index.append(index)
            print('商品编号:%s          商品类型:%s' % (index, good))
        shopping_first_no = input("请输入商品类型编号(按b返回上一页,按q退出):").strip()
        if shopping_first_no.isdigit():
            shopping_first_no = int(shopping_first_no)
            if shopping_first_no in goods_first_index:
                while True:
                    goods_name = goods_first[shopping_first_no]
                    print("%s下有以下商品:" % goods_name)
                    goods_seconds = {}
                    goods_seconds_index = []
                    for index,good in enumerate(goods[goods_name].keys(), start=1):
                        print('商品编号:%s          商品名称:%s' % (index, good))
                        goods_seconds_index.append(index)
                        goods_seconds[index] = good

                    shopping_second_no = input("请输入商品名称编号(按b返回上一页,按q退出):").strip()

                    if shopping_second_no.isdigit():
                        shopping_second_no = int(shopping_second_no)
                        if shopping_second_no in goods_seconds_index:
                            while True:
                                goods_third_name = goods_seconds[shopping_second_no]
                                print("有以下几种%s" % goods_third_name)
                                final_goods_name = goods[goods_name][goods_third_name]
                                goods_final = {}
                                goods_final_index=[]

                                for index, good in enumerate(final_goods_name.keys(), start=1):
                                    print('%s编号:%s          %s名称:%s          价格为:%s' % (goods_third_name, index, goods_third_name, good,final_goods_name[good]))
                                    goods_final[index] = good
                                    goods_final_index.append(index)
                                goods_final_no = input("请输入购买%s的编号(按b返回上一页,按q退出):" % goods_third_name).strip()
                                if goods_final_no.isdigit():
                                    goods_final_no = int(goods_final_no)
                                    if goods_final_no in goods_final_index:
                                        final_name = goods_final[goods_final_no]
                                        buy_num = input("请输入购买%s数量:" % final_name).strip()
                                        if buy_num.isdigit():
                                            buy_num = int(buy_num)
                                            database = _load_database()
                                            account_balance = database[account_name]['balance']
                                            goods_price = final_goods_name[final_name]
                                            sum_amount = buy_num * goods_price
                                            if account_balance >= sum_amount:
                                                database[account_name]['balance'] = account_balance - sum_amount
                                                shopping_list_data = {}
                                                shopping_list_data['buy_time'] = _get_current_format_time()
                                                shopping_list_data['goods_name'] = final_name
                                                shopping_list_data['goods_num'] = buy_num
                                                database[account_name]['shopping_list'].append(shopping_list_data)
                                                d1 = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')  # 获取当前时间
                                                _save_account(database)#保存购物时间到数据库中,即:database.json
                                                #提示用户买了什么东西
                                                print("您于%s购买了%s件%s" % (d1, buy_num, final_name))
                                            else:
                                                print('您的账户余额不足,请您及时充值!')
                                            return None
                                        else:
                                            print("您输入有误,请重新输入")
                                    else:
                                        print("您输入有误,请重新输入")
                                elif goods_final_no == 'q':
                                    _logout(account_name)
                                elif goods_final_no == 'b':
                                    break
                                else:
                                    print("您输入有误,请重新输入")
                        else:
                            print("您输入有误,请重新输入")
                    elif shopping_second_no == 'q':
                        _logout(account_name)
                    elif shopping_second_no == 'b':
                        print("进入这里没有?")
                        break
                    else:
                        print("您输入有误,请重新输入")
            else:
                print("您输入有误,请重新输入")
        elif shopping_first_no == 'q':
            _logout(account_name)
        elif shopping_first_no == 'b':
            return
        else:
            print("您输入有误,请重新输入")

#充值操作
def _recharge(account_name):
    database = _load_database()
    print("您的账户当前余额为:%.2f " % _get_balance(account_name))
    while True:
        input_data = input("您正在进行充值...请输入充值金额(按b返回上一页,按q退出):").strip()
        if re.match(pattern=r'^\d+.\d{1,2}$', string=input_data):
            #输入的金额必须为数字,充值完毕写入库中,退出当前循环
            if input_data.isdigit():#整数数字
                amount = int(input_data)
            else:#小数
                amount = float(input_data)
            database[account_name]['balance'] += amount
            _save_account(database)
            #获取到当前用户余额
            curr_balance = _get_balance(account_name)
            print('您已成功充值,您的余额为\033[32m%.2f\033[0m元' % curr_balance)
            break
        elif input_data == 'b':
            break
        elif input_data == 'q':
            _logout(account_name)
        else:
            print("您输入的有误,请重新输入金额")

#登录
def _login():
    account_name = input("请输入账号(按q退出系统):").strip()
    if account_name == 'q':
        _logout()
    else:
        #加载黑名单
        black_data_list = _load_database('black_list.json')
        black_user_list = []#用来存放所有的黑名单用户名
        for black_user in black_data_list.keys():
            black_user_list.append(black_user)

        #如果用户不在黑名单中
        if account_name not in black_user_list:
            #不在黑名单,则去判断是否在已有账户列表中
            current_data_list = _load_database()
            current_user_list = []
            for current_user in current_data_list.keys():
                current_user_list.append(current_user)

            if account_name in current_user_list:
                loginTimes = 1#登录次数
                # 输入用户在数据库中
                current_user_passwd = current_data_list[account_name]['pwd']#获取当前用户的密码
                while loginTimes <= 3:
                    input_passwd = input("请输入密码:").strip()
                    if _get_md5(input_passwd) == current_user_passwd:
                        #登录成功,修改最新登录时间
                        last_login_time = current_data_list[account_name]['last_login_time']
                        if last_login_time is not None:
                            print("登录成功,上一次登录时间:%s" % last_login_time)
                        else:
                            print("登录成功,您可以购物啦")
                        current_data_list[account_name]['last_login_time'] = _get_current_format_time()
                        _save_account(current_data_list)
                        #密码正确
                        account_balance = current_data_list[account_name]['balance']#根据账户获取账户余额
                        #高亮 打印账户余额
                        print('您的账户余额是\033[32m%.2f\033[0m' % account_balance)
                        while True:
                            #让用户输入特定字母进入特定的菜单
                            print("*"*60)
                            print("您可以进行以下操作:")
                            print("h: 查询购物历史")
                            print("s: 开始购物")
                            print("t: 充值")
                            print("q: 退出")
                            print("*" * 20)
                            command = input("请输入操作指令:").strip()
                            if command == 'h':#查询历史购物
                                _get_shopping_history(account_name)
                            elif command == 't':#充值操作
                                _recharge(account_name)
                            elif command == 's':#清空购物车,把shopping_list和shopping_time清空
                                # _clear_shopping_cart(account_name)
                                _shopping(account_name)  # 开始购物
                            elif command == 'q':
                                _logout(account_name)
                            else:
                                # 如果用户的操作不符合上面所有的情况,则输出错误信息
                                print('输入有误,请检查后重新输入!')
                    else:
                        # 不成功提示用户有三次机会,如果三次都不成功,将锁定用户名
                        if loginTimes == 3:  # 三次不成功
                            print("对不起,你输入的次数过多,你的用户名已经被锁定,请联系管理员")
                            #保存用户到black_list.json中
                            black_data_list[account_name] = None
                            # black_data_list.setdefault(account_name)
                            #添加到黑名单列表
                            _save_account(database=black_data_list, filename='black_list.json')
                            _logout()#退出登录
                        else:
                            print("对不起,你输入的密码不对,你还有%s次机会" % (3 - loginTimes))
                            loginTimes += 1
            else:
                #输入用户不在数据库中
                print('账号不存在,请重试!或输入b返回上一层,输入q,退出购物程序!')
                print('-----------------------------------------------------')
        else:#该账户在黑名单中,则打印信息并退出
            print("您的账号已经被锁定,请联系管理员处理")
            _logout()#退出

def _get_md5(str):
    h1 = hashlib.md5()
    h1.update(str.encode('utf-8'))
    return h1.hexdigest()

#添加账户
def _add_user():
    while True:
        account_name = input("请输入账户:").strip()
        if account_name is not '':
            while True:
                account_pwd = input("请输入密码:").strip()
                if account_pwd is not '':
                    #初始化数据
                    database = _load_database()
                    account_data_dict = {}
                    account_data_dict['shopping_list'] = []
                    account_data_dict['pwd'] = _get_md5(account_pwd)
                    account_data_dict['balance'] = 0.0
                    account_data_dict['last_login_time'] = None
                    account_data_dict['register_time'] = _get_current_format_time()
                    database[account_name] =  account_data_dict
                    _save_account(database)
                    print("注册成功,请重新登录进行购物")
                    break
                else:
                    print("账户密码不能为空,请重新输入")
            break
        else:
            print("账户号不能为空,请重新输入")

def main():
    while True:
        #打印登录提示信息
        '''
        1. 按"A"注册
        2. 按"B"登录
        3. 按"Q"退出
        '''
        print("*"*60)
        print("欢迎光临购物系统".rjust(10, ' '))
        print("您可以进行如下操作:".rjust(12, ' '))
        print("A:注册".rjust(6,' '))
        print("B:登录".rjust(6,' '))
        print("Q:退出".rjust(6,' '))
        print("*"*60)
        command = input("  请输入选项:").strip()#用户输入指令
        command = command.upper()
        if command == 'A':#创建用户
            _add_user()
        elif command == 'B':#登录
            _login()
        elif command == 'Q':#退出登录
            _logout()
        else:#如果用户输入选项不存在则需要重新输入
            print("输入信息有误,请重新输入")


if __name__ == '__main__':
    main()
运行
************************************************************
  欢迎光临购物系统
  您可以进行如下操作:
  A:注册
  B:登录
  Q:退出
************************************************************
  请输入选项:a
请输入账户:test
请输入密码:test
注册成功,请重新登录进行购物
************************************************************
  欢迎光临购物系统
  您可以进行如下操作:
  A:注册
  B:登录
  Q:退出
************************************************************
  请输入选项:b
请输入账号(按q退出系统):test
请输入密码:test
登录成功,您可以购物啦
您的账户余额是0.00
************************************************************
您可以进行以下操作:
h: 查询购物历史
s: 开始购物
t: 充值
q: 退出
********************
请输入操作指令:t
您的账户当前余额为:0.00 
您正在进行充值...请输入充值金额(按b返回上一页,按q退出):10000
您已成功充值,您的余额为10000.00元
************************************************************
您可以进行以下操作:
h: 查询购物历史
s: 开始购物
t: 充值
q: 退出
********************
请输入操作指令:s
商品编号:1          商品类型:3C类
商品编号:2          商品类型:家电类
商品编号:3          商品类型:生活类
请输入商品类型编号(按b返回上一页,按q退出):1
3C类下有以下商品:
商品编号:1          商品名称:手机
商品编号:2          商品名称:电脑
请输入商品名称编号(按b返回上一页,按q退出):2
有以下几种电脑
电脑编号:1          电脑名称:mac air          价格为:8009
电脑编号:2          电脑名称:联想笔记本          价格为:6888
请输入购买电脑的编号(按b返回上一页,按q退出):b
3C类下有以下商品:
商品编号:1          商品名称:手机
商品编号:2          商品名称:电脑
请输入商品名称编号(按b返回上一页,按q退出):1
有以下几种手机
手机编号:1          手机名称:iPhone6          价格为:5299
手机编号:2          手机名称:小米5          价格为:1999
请输入购买手机的编号(按b返回上一页,按q退出):1
请输入购买iPhone6数量:1
您于2018-04-01 09:50:35购买了1件iPhone6
************************************************************
您可以进行以下操作:
h: 查询购物历史
s: 开始购物
t: 充值
q: 退出
********************
请输入操作指令:s
商品编号:1          商品类型:3C类
商品编号:2          商品类型:家电类
商品编号:3          商品类型:生活类
请输入商品类型编号(按b返回上一页,按q退出):3
生活类下有以下商品:
商品编号:1          商品名称:T恤
商品编号:2          商品名称:鞋子
请输入商品名称编号(按b返回上一页,按q退出):1
有以下几种T恤
T恤编号:1          T恤名称:真维斯          价格为:75
T恤编号:2          T恤名称:优衣库          价格为:97
T恤编号:3          T恤名称:森马          价格为:89
请输入购买T恤的编号(按b返回上一页,按q退出):1
请输入购买真维斯数量:10
您于2018-04-01 09:50:56购买了10件真维斯
************************************************************
您可以进行以下操作:
h: 查询购物历史
s: 开始购物
t: 充值
q: 退出
********************
请输入操作指令:q
您于2018-04-01 09:50:35购买了1件iPhone6
您于2018-04-01 09:50:56购买了10件真维斯
感谢您的光临,欢迎下次光临

个人 觉得购物方法_shopping()中的代码过多,可以把每一级的代码给抽取出来,仅供大家参考,转载请注明出处


  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值