python课程学习-模块1-作业-03购物车程序

1. 功能要求

基础要求

1、启动程序后,输入用户名密码后,让用户输入工资,然后打印商品列表
2、允许用户根据商品编号购买商品
3、用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒
4、可随时退出,退出时,打印已购买商品和余额
5、在用户使用过程中,
关键输出,如余额,商品已加入购物车等消息,需高亮显示

扩展需求

1、用户下一次登录后,输入用户名密码,直接回到上次的状态,即上次消费的余额什么的还是那些,再次登录可继续购买
2、允许查询之前的消费记录

2. 流程图

购物车

3. Readme

功能:简单的购物车程序
1. 实现老用户登录以及新用户注册
2. 登陆后可以根据订单号查询用户之前的购物信息
3. 购物中可以选择商品和购买数量
4. 购买完毕后,显示购物列表,订单号,并修改用户余额信息
5. 将用户认证,用户注册,打印商品信息等封装成模块

代码语言
python3.6

版本
version 0.0.1

4. 程序

import time

goods = [
    {"name": "电脑", "price": 2000},
    {"name": "鼠标", "price": 10},
    {"name": "游艇", "price": 20},
    {"name": "手机", "price": 998},
]


user_file = 'userfile'
# user_file格式如下
# 用户名1:密码
# 用户名2:密码

with open(user_file, 'r') as fr:
    user = fr.read().split('\n')[:-1]
    user_list = {}
    for record in user:
        name, password, balance = record.split(',')
        user_list[name] = {'password': str(password), 'balance': int(balance)}


# 打印商品列表
def print_goods(goods_info):
    print('下面是可选择的商品'.center(12, '-'))
    print('-商品名-商品价格-'.center(12, '-'))
    goods_list = []
    for serial in goods_info:
        print('  {0:<4} {1:<4}'.format(serial['name'], serial['price']))
        goods_list.append(serial['name'])
    return goods_list


# 老用户认证
def old_user_login(username, user_pass):
    if username in user_list:
        if user_pass == user_list[username]['password']:
            user_balance = user_list[username]['balance']
            return username, user_balance
        else:
            print("\033[1;31;m密码输入错误,请确认后重新输入!\033[0m")
            return 1
    else:
        print("\033[1;31;m没有此用户信息,请确认后重新输入!\033[0m")
        return 2


# 新用户注册
def newer_register():
    print("\033[1;31;m下面开始新用户注册流程:\033[0m")
    name_registry = input("名字 >>> ")
    password_registry = input("密码 >>> ")

    n = 0
    while n < 3:
        n += 1
        if name_registry in user_list:
            print('\033[1;31;m此用户已存在,请重新登录\033[0m')
            return 2
            break
        try:
            balance_registry = int(input("存入金额 >>> "))
            if balance_registry <= 0:
                print("\033[1;31;m金额输入错误,请重新输入\033[0m")
            with open(user_file, 'a+') as fa:
                fa.write(name_registry + ',' + password_registry + ',' + str(balance_registry) + '\n')
                user_list[name_registry] = {'password': password_registry, 'balance': str(balance_registry)}
                return name_registry, balance_registry
            break
        except ValueError:
            print("\033[1;31;m金额输入错误,请重新输入\033[0m")

        if n == 3:
            print("\033[1;31;m输入错误3次,注册失败,退出登录\033[0m")
            return 1


# 查询老用户订单
def _search_order(username):
    print("---用户订单查询---")

    n = 0
    while n < 3:
        ordernum = input("请输入订单号(q退出)")
        if ordernum == 'q':
            print("退出查询")
            break
            return 1
        orderfile = 'order.{}.{}.txt'.format(username, ordernum)
        try:
            with open(orderfile, 'r+') as f:
                print(f.read().encode('utf-8'))
                return 0
        except FileNotFoundError:
            print('当前用户下没有查找到此订单信息,请重新输入')
            n += 1
        if n == 3:
            print('订单信息输入错误3次,退出查询')
            return 3


# 开始用户登录程序
print("欢迎登陆欢乐超市购物系统\n"
      "1. 老用户登录\n"
      "2. 新用户注册\n")
user_choice = input(">>> ")

if user_choice == '1':
    n = 0
    while n < 3:
        username = input("请输入用户名(q退出):")
        password = input("请输入用户密码:")

        if username == 'q':
            print("\033[1;31;m退出登录\033[0m")
            exit(4)
        result = old_user_login(username, password)
        if result == 1 or result == 2:
            n += 1
            if n == 3:
                print("输入错误3次,退出登录!")
                exit(1)
            continue
        else:
            username, balance = result
            break

    # 查询之前的订单
    query_order = input('是否查询之前的用户订单(y or n)?')
    if query_order == 'y' or query_order == 'Y':
        _search_order(username)

elif user_choice == '2':
    result = newer_register()
    if result == 1 or result == 2:
        exit(1)
    else:
        username, balance = result
else:
    print("输入错误,退出登录")
    exit(2)

print("\033[1;32;m用户{0}登陆成功!您的当前余额为{1}\033[0m".format(username, balance))

start_shop = input("是否开始购买?(N直接退出)")

if start_shop == 'n' or start_shop == 'N':
    print("退出购买!!!")
    exit(3)

good_list = []
for i in goods:
    good_list.append(i['name'])

choices = []      # 购物列表
tmp_choices = []  # 临时购物列表
cost_sum = 0  # 花费
# choices = {'name':'apple','price':11899,'count':1}
# order = [{'order_num':1001011, 'username':'Lily', 'order_list': {choices}}]
# tmp_choices = [已购商品名]

while True:
    print_goods(goods)
    # 输入商品名开始购买
    while True:
        order = input('请输入商品名:')
        if order in good_list:
            order_index = good_list.index(order)
            break
        else:
            print("商品名输入错误,请重新输入")

    # 输入购买数量
    num = 0
    while True:
        num = input("请输入购买数量:")
        if num.isdigit():
            num = int(num)
            if num > 0 and (num % 1 == 0):
                break
        else:
            print("购买数量输入错误")

    # 计算购买花费
    order_price = goods[order_index]['price']
    cost_tmp = cost_sum + order_price * num

    if cost_tmp > balance:
        # 如果金额不足就退出重选
        print("\033[1;31;m余额不足,请重新选择商品\033[0m")
        continue
    else:
        cost_sum += order_price * num
        if order in tmp_choices:
            order_index = tmp_choices.index(order)
            choices[order_index]['count'] += num
        else:
            tmp_choices.append(order)
            choices.append({'name': order, 'price': order_price, 'count': num})
        print("商品\033[1;31;m{}\033[0m加入购物车成功".format(order))

        # 是否还要继续购买
        buy_or_not = input('是否继续购物?(y/n)')
        # 如果不购买就进行结算
        if buy_or_not == 'n' or buy_or_not == 'N':
            print('--------你购买的商品列表如下---------')
            print('--商品名称--商品单价--商品数量--')
            for goodname in choices:
                print('{0:<10} {1:<7} {2:<7}'.format(goodname['name'], goodname['price'], goodname['count']))

            # 写入订单信息
            now_time = str(int(time.time()))
            order_num = 'order.{}.{}.txt'.format(username, now_time)
            order_txt = {'cost': cost_sum, 'name': username, 'ordernum': now_time, 'order_list': choices}
            with open(order_num, 'w+') as fw:
                fw.write(str(order_txt))

            # 修改用户余额,写入新的用户文件
            user_list[username]['balance'] = balance - cost_sum
            with open('userfile', 'w', encoding="utf-8") as fw:
                for user_info in user_list.keys():
                    line = '{0},{1},{2}\n'.format(user_info, user_list[user_info]['password'],
                                                  user_list[user_info]['balance'])
                    fw.write(line)

            print('\033[1;32;m本次购物合计消费:{0}元,余额为{1}元,订单号为{2}\033[0m'.format(
                cost_sum, balance - cost_sum, now_time))
            break

5. 测试

1. 正常的流程
这里写图片描述
这里写图片描述
2. 新用户注册

用户已经存在

欢迎登陆欢乐超市购物系统
1. 老用户登录
2. 新用户注册

>>> 2
下面开始新用户注册流程:
名字 >>> haha
密码 >>> test
此用户已存在,请重新登录

用户不存在,新用户注册

这里写图片描述
这里写图片描述
新的用户文件如下:

test,test1234,4640
Lily,abc123,120010
zpf,111,111
alex,1234,1200487

订单信息如下:
文件名:order.alex.1522663214.txt

{'cost': 34080, 'name': 'alex', 'ordernum': '1522674679', 'order_list': [{'name': '电脑', 'price': 2000, 'count': 12}, {'name': '手机', 'price': 998, 'count': 10}, {'name': '鼠标', 'price': 10, 'count': 10}]}

上面的文件内容是文本的形式
正常输入高亮显示
这里写图片描述

6.思考

1. 数据结构的问题

题目中给定的数据结构如下:
goods = [
{“name”: “电脑”, “price”: 2000},
{“name”: “鼠标”, “price”: 10},
{“name”: “游艇”, “price”: 20},
{“name”: “手机”, “price”: 998},
]
感觉这种结构没有下面的好处理一些:
goods ={
10001: {“name”: “电脑”, “price”: 2000},
10002: {“name”: “鼠标”, “price”: 10},
10003: {“name”: “游艇”, “price”: 20},
10004: {“name”: “手机”, “price”: 998},
}
字典形式的结构,商品编号是keys,商品信息是values,这样的话更好处理。列表形式的还要先进行转换。

2. 函数化处理过程

刚开始的时候,想把登陆流程也封装成函数,但是有一个问题,用户名和用户余额在下面的购物流程中是需要用到的,而新用户登录与老用户登录的认证流程是不同的,最后的输出也不一样,而用户名和用户余额这两个变量就必须是全局变量,强行函数化所有的处理流程是没有必要的。

3. 程序判断的问题

上面的程序运行中需要对于用户的输入进行各种判断,刚开始感觉有些晕。

4. 数据存储的问题

可以看到,用户认证文件(包括用户名,密码,余额),用户订单信息都是用文本文件进行处理的,而文本文件每次读取和写入都要进行预处理,在真实的环境里面肯定是要用到mysql,redis这些数据库的,使用数据库更方便处理这些数据。

5. 可以升级的一些功能

  1. 可以让用户删除已购商品,比如减少数量,直接删除等
  2. 用户充值
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值