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. 可以升级的一些功能
- 可以让用户删除已购商品,比如减少数量,直接删除等
- 用户充值