day09 Python写一个简单的购物车
一、简单购物车
基础要求: 1、启动程序后,输入用户名密码后,让用户输入工资,然后打印商品列表 2、允许用户根据商品编号购买商品 3、用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 4、可随时退出,退出时,打印已购买商品和余额 5、在用户使用过程中, 关键输出,如余额,商品已加入购物车等消息,需高亮显示 扩展需求: 1、用户下一次登录后,输入用户名密码,直接回到上次的状态,即上次消费的余额什么的还是那些,再次登录可继续购买 2、允许查询之前的消费记录
二、实例
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Author: fhb
# @Date : 2018/10/27
# @Desc :
from random import randint
import datetime, pickle, os
goods = [
{"name": "电脑", "price": 1999},
{"name": "鼠标", "price": 10},
{"name": "游艇", "price": 20},
{"name": "美女", "price": 998}
]
user_database = [
{"username": "fhb", "password": "123"},
{"username": "test", "password": "123"}
]
# 登陆次数限制
retry = 3
# 记录当前登陆成功的用户名
userinfo = ""
# 存放用户输入工资的状态,判断用户是否输入成功
salay_info = False
# 购物车
shop_list = []
# 存放用户余额、购买的商品、购买商品历史记录等信息
shop_list_record = {}
''' 用户购买记录信息要求如此方式存放 --> 数据结构
shop_list_record = {
"username":{
"balance":"0"
"shop_record":[
"2018-10-27 10:00 购买了:电脑,消费:10000",
"2018-10-27 10:05 购买了:电脑,消费:10000",
"2018-10-27 10:10 购买了:电脑,消费:10000",
],
},
"username2":{
"balance":"1000"
"shop_record":[
"2018-10-27 11:00 购买了:电脑,消费:10000",
"2018-10-27 11:05 购买了:电脑,消费:10000",
"2018-10-27 11:10 购买了:电脑,消费:10000",
],
}
}
'''
# 初始化账户余额为 0
balance = 0
# 初始化购买商品历史记录为空
history_info = []
# 验证用户名和密码
user_auth_status = False
while not user_auth_status:
username = input("请输入用户名: ").strip()
password = input("请输入密码: ").strip()
# 优先处理验证码
verify_check_status = False
while not verify_check_status:
num = 0
verify_code = ""
while num < 4:
verify_code += chr(randint(65, 90))
num += 1
verify_code_check = input("您的验证码是\033[1;31;40m{verify_code}\033[0m请输入验证码: ".format(verify_code=verify_code))
if verify_code_check.upper() == verify_code:
verify_check_status = True
else:
print("\033[1;31;40m验证码错误,请重新输入!\033[0m")
# 验证码通过认证之后,验证用户名和密码,三次登陆失败之后,登陆受限!
for user in user_database:
username_check = user.get("username")
# 此处先判断数据库中是否存在用户输入的用户和密码
if username_check and username_check == username and user["password"] == password:
user_auth_status = True
userinfo = username
print("登陆成功! 欢迎\033[1;31;40m{name}\033[0m".format(name=userinfo))
break
else:
retry -= 1
print("用户名和密码错误,请重新输入!,你还有 \033[1;31;40m{retry}\033[0m次登陆机会!".format(retry=retry))
# 判断登陆次数,剩余次数为 retry
if retry <= 0:
print("\033[1;31;40m登陆受限,退出!\033[0m")
break
# 用户登陆成功之后,才能查看商品列表以及后续操作
while user_auth_status:
# 存放商品列表
shop_list_dict = {} # 要求存放这种形式的数据 {'1': {'name': '电脑', 'price': 1999}, '2': {'name': '鼠标', 'price': 10}...
print("\n可选的商品列表:")
for good in range(len(goods)):
# 打印商品列表,并将编号和商品数据存放到一个新的字典shop_list_dict中,方便后面检索判断用户输入的内容是是否在商品列表中
print("编号:%s, 名称:%s, 价格:¥%s" % (good + 1, goods[good]["name"],goods[good]["price"]))
shop_list_dict.setdefault(str(good + 1), goods[good])
# 读取历史记录
if os.path.exists("shop_database.txt"):
with open("shop_database.txt", 'rb') as f:
history_record = pickle.load(f)
shop_list_record = history_record
record = history_record.get(userinfo)
if record:
result = record.get("balance")
history_data = record.get("shop_record")
if result:
balance = result
if history_data:
history_info = history_data
if balance <= 100:
ack_status = False
while not ack_status:
chiose = input("当前可以消费的账户余额为:%s ,是否继续充值[y/n]: " % balance).strip()
if chiose.lower() == "y":
# 此处判断用户输入的工资是否是数字组成,如果不是强制重新输入
while not salay_info:
salay_new = input("请输入工资: ").strip()
if salay_new.isdigit():
balance += int(salay_new)
salay_info = True
shop_list_record.setdefault(userinfo, {})["balance"] = balance
print("您当前的余额为: \033[1;31;40m{balance}\033[0m".format(balance=balance))
ack_status = True
else:
print("\033[1;31;40m工资输入有误,请重新输入!\033[0m")
elif chiose.lower() == "n":
ack_status = True
continue
else:
print("\033[1;31;40m输入有误,请重新输入!\033[0m")
# 等待用户选择商品
shop_num = input("请输入商品编号,选择购买商品[q for quit, h for history]: ").strip()
result = shop_list_dict.get(shop_num)
# 打印历史记录
if shop_num.upper() == "H":
if history_info:
n = 1
for h in history_info:
print("编号", n, h)
n += 1
else:
print("历史记录为空!")
continue
# 退出的时候,打印购买的商品列表,如果没有购买任何商品,打印没有购买商品。
elif shop_num.upper() == "Q":
print("你购买的商品列表: ")
if shop_list:
sum = 1
for l in shop_list:
print("编号:%s, 名称:%s, 价格:%s" % (sum, l["name"], l["price"]))
sum += 1
else:
print("你本次没有购买任何商品。")
# 退出的时候也要更新数据中的余额和商品记录信息
print("\033[1;31;40m当前账户余额: %s\033[0m" % balance)
shop_list_record.setdefault(userinfo, {})["balance"] = balance
with open("shop_database.txt", "wb") as f1:
pickle.dump(shop_list_record, f1)
exit(0)
elif result:
if result["price"] <= balance:
balance -= result["price"]
print("你选择的商品是: \033[1;31;40m%s\033[0m,当前余额: \033[1;31;40m%s\033[0m" % (result["name"], balance))
shop_list.append(result)
# 记录本次购买记录,方便用户后续查看
time_stamp = datetime.datetime.now()
shop_record = "时间:%s ,购买了:%s ,消费:%s;" % (time_stamp.strftime('%Y.%m.%d %H:%M:%S'), result["name"], result["price"])
shop_list_record.setdefault(userinfo, {}).setdefault("shop_record", []).append(shop_record)
else:
print("余额不足,请重新充值!\033[1;36;40m%s\033[0m" % balance)
else:
print("\033[1;31;40m商品编号错误,请重新输入!\033[0m")
# 每次消费,更新数据库中的余额 balance 中
shop_list_record.setdefault(userinfo, {})["balance"] = balance
# 将用户信息保存到文件中
with open("shop_database.txt", "wb") as f:
pickle.dump(shop_list_record, f)