# 代码实现: 购物车
# 功能要求: 1.用户输入总资产,例如:2000.
# 2.显示商品列表,让用户根据序号选择商品,加入购物车购买
# 3.如果商品总额大于总资产,提示账户余额不足,否则,购买成功
# 额外功能: 1.支持 一次购买多种商品多个数目
# 2.支持 多次购买
# 3.支持 在用户继续购买时显示商品库存
# 4.支持 在选择商品时输入任意字符,但必须是"商品编号:购买数量"的格式
# 5.支持 判断初始资产是否可以买到最低单价的商品,以及购买后钱包余额是否可以继续挑选商品,如不够则提示用户
# 6.支持 选择的商品数量超出库存时自动修改为最大库存量,并提示用户所选商品名和修改后的最大库存数目
# 7.支持 购买后显示用户买了哪些商品,单价多少,数量多少,单种商品花费多少,总花费及余额
# 8.支持 选择的商品总价大于资产数时,显示需补充的差价
# 9.支持 商品售空时再次显示时自动删除该商品(不显示该条目)
# 10.支持 判断连续购买的次数并在用户选择结束购买时显示"谢谢%d次惠顾
# 11.如需添加录入新商品的功能,可用以下代码实现:
# 12.还可添加一项: 将商品列表添加到本地json文件/服务器数据库等
1 def format_insert_words_and_add_good_info(insert_words, separator_symbol):
2 insert_words_formatted_list = insert_words.split(separator_symbol)
3 # 此处省略类似下面select_goods()函数里的格式化输入的步骤,自动删除所有不合法的输入
4 # 以下代码默认good_insert的内容为合法内容,且省略了商品名已存在时修改录入的商品名为'商品1'的步骤
5 good_temp_dic = {"name": insert_words_formatted_list[0], "price": int(insert_words_formatted_list[1]),
6 "allowance": int(insert_words_formatted_list[2])}
7 goods.append(good_temp_dic)
8 return goods
9
10
11 def show_insert():
12 try:
13 good_insert = input("请输入准备添加到货架的商品的'名字','单价','数量',用英文逗号/英文句号或空格隔开: ").strip()
14 if ',' in good_insert:
15 format_insert_words_and_add_good_info(good_insert, ',')
16 elif '.' in good_insert:
17 format_insert_words_and_add_good_info(good_insert, '.')
18 elif ' ' in good_insert:
19 format_insert_words_and_add_good_info(good_insert, ' ')
20 else:
21 print('分隔符输入不合法,未能录入数据')
22 show_insert()
23 except KeyboardInterrupt:
24 print('\n手动终止录入进程,再见...')
25
26 def write_goods_info():
27 show_insert()
28 with open('goods_info.json','w') as info_file:
29 # 这里如果用遍历goods的方法,只添加商品的字典,那么在上面'格式化插入的文字以及添加商品信息'方法里直接追加good_temp_dic
30 # with open('goods_info.json','a') as info_file:
31 info_file.write(goods)
32
录入新商品&插入数据库
额外功能实现代码如下
1 goods = [{"name": "电脑", "price": 1999, "allowance": 100},
2 {"name": "鼠标", "price": 10, "allowance": 100},
3 {"name": "游艇", "price": 20, "allowance": 100},
4 {"name": "美女", "price": 998, "allowance": 100},
5 {"name": "帅哥", "price": 98, "allowance": 100}, ]
6 price_list = [] # 方便后面比较钱包余额是否大于最小单价
7 for good_index_temp in range(0, len(goods)): price_list.append(goods[good_index_temp]['price'])
8
9
10 def show_goods():
11 print('**********商品列表**********')
12 print('编号\t\t商品\t\t价格\t\t库存')
13 for good_index in range(0, len(goods)):
14 good_index += 1
15 print('{0}\t\t{1}\t\t{2}\t\t{3}'.format(good_index, goods[good_index - 1]['name'],
16 goods[good_index - 1]['price'],
17 goods[good_index - 1]['allowance']))
18
19
20 def show_wallet():
21 wallet = input('偷偷show一下钱包金额:').strip()
22 if wallet.isdigit():
23 wallet = int(wallet)
24 if wallet < min(price_list):
25 print('穷逼滚,再给你一次机会')
26 show_wallet()
27 else:
28 print('总资产%d元,开始购物吧高富帅' % wallet)
29 return wallet
30 else:
31 print('糊弄谁呢?再给你一次机会')
32 show_wallet()
33
34
35 def select_goods(wallet, shopping_count=0): # return customer_choice_list, return selected_goods
36 customer_choice = input("请选择商品编号及数量(以':'区分),使用空格隔开: ")
37 # ' 4:3:4 3:2 5:1 a:1 %:# # @ 1:120 2:m ''
38 customer_choice_list = customer_choice.split(' ')
39 print(customer_choice_list)
40 temp_list = customer_choice_list.copy() # 浅拷贝,以便后面遍历时删除无效项或非法项
41 for element in temp_list:
42 if element == '' or element == ' ': # 去空(无效项)
43 # print('过多的空格已被自动删除')
44 customer_choice_list.remove(element)
45 elif ':' not in element: # 去掉无":"匹配的项(无效项)
46 # print('无效的匹配项已被自动删除')
47 customer_choice_list.remove(element)
48 elif len(element.split(':')) != 2: # 去掉":"匹配后长度不为2(不是正常匹配)的项目(非法项)
49 # print('非法项已被自动删除')
50 customer_choice_list.remove(element)
51 elif element.split(':')[0].isdigit() == 0 or element.split(':')[-1].isdigit() == 0: # 去掉首尾非数字的项(非法项)
52 # print('非商品编号或非正常商品数量,已自动删除')
53 customer_choice_list.remove(element)
54 elif int(element.split(':')[0]) not in range(1, len(goods) + 1): # print('选择的商品编号不存在,已自动删除.')
55 customer_choice_list.remove(element)
56 elif int(element.split(':')[-1]) > goods[int(element.split(':')[0]) - 1]['allowance']:
57 customer_choice_list.remove(element)
58 element = element.split(':')[0] + ':' + str(goods[int(element.split(':')[0]) - 1]['allowance'])
59 print(">>>%s<<<选择了过多的数量,已自动修改为最大库存量>>%d<<" % (
60 goods[int(element.split(':')[0]) - 1]['name'], goods[int(element.split(':')[0]) - 1]['allowance']))
61 customer_choice_list.append(element)
62 del temp_list # 释放临时列表内存
63 print('您选择了如下商品:⤵⤵⤵⤵') # 只是展示给用户知道他买了什么
64 selected_goods = [] # 只是展示给用户知道他买了什么
65 for selection in customer_choice_list:
66 shopping_cart = {'商品名': goods[int(selection.split(':')[0]) - 1]['name'],
67 '单价': goods[int(selection.split(':')[0]) - 1]['price'],
68 '购买数量': int(selection.split(':')[-1])}
69 shopping_cart['所需金额'] = shopping_cart['单价'] * shopping_cart['购买数量']
70 selected_goods.append(shopping_cart)
71 for selected_good in selected_goods:
72 print(selected_good) # 只是展示给用户,并没有他意
73 sum_price = 0
74 temp_list = goods.copy() # 浅拷贝商品列表,以便在删除某商品时仍可计算客户所花总价
75 for customer_choice_list_element in customer_choice_list:
76 goods[int(customer_choice_list_element.split(':')[0]) - 1]['allowance'] -= int(
77 customer_choice_list_element.split(':')[-1])
78 if goods[int(customer_choice_list_element.split(':')[0]) - 1]['allowance'] == 0:
79 goods.pop(int(customer_choice_list_element.split(':')[0]) - 1)
80 sum_price += temp_list[int(customer_choice_list_element.split(':')[0]) - 1]['price'] * int(
81 customer_choice_list_element.split(':')[-1])
82 wallet_allowance = wallet - sum_price
83 del temp_list # 释放临时内存
84 if wallet_allowance < 0:
85 print('余额不足,还需补充%d元.请下次多带点钱来,穷逼!' % abs(wallet_allowance))
86 elif wallet_allowance < min(price_list):
87 print('此次购物花费%d元,余额%d元' % (sum_price, wallet_allowance))
88 print('余额暂不够买任何商品了,下次请多带点钱来吧!')
89 else:
90 print('此次购物花费%d元,余额%d元' % (sum_price, wallet_allowance))
91 while 'Query_Go_On_Shopping?':
92 try:
93 customer_selection = input('是否需要继续购买?Y/N').strip().lower()
94 if customer_selection == 'n':
95 shopping_count += 1
96 print('谢谢%d次惠顾,欢迎下次光临...' % shopping_count)
97 break
98 elif customer_selection == 'y':
99 show_goods() # 展示商品余量
100 shopping_count += 1
101 select_goods(wallet_allowance, shopping_count)
102 break
103 else:
104 print('选择无效,请重新选择')
105 except KeyboardInterrupt:
106 print('手动打断购物进程,再见')
107
108
109 if __name__ == '__main__':
110 show_goods()
111 select_goods(show_wallet())
购物车模块代码
不会实现的功能是:用户在购买结束后不会询问用户是否继续购买(因代码里已实现多次购买功能)
代码里用到的方法:
1️⃣print()里的占位符,使用{0}{1}...方式占位
1 def show_goods():
2 print('**********商品列表**********')
3 print('编号\t\t商品\t\t价格\t\t库存')
4 for good_index in range(0, len(goods)):
5 good_index += 1
6 print('{0}\t\t{1}\t\t{2}\t\t{3}'.format(good_index, goods[good_index - 1]['name'],
7 goods[good_index - 1]['price'],
8 goods[good_index - 1]['allowance']))
2️⃣判断用户输入的内容的数据类型(是否为数字)
1 def show_wallet():
2 wallet = input('偷偷show一下钱包金额:').strip()
3 if wallet.isdigit():
4 wallet = int(wallet)
5 if wallet < min(price_list):
6 print('穷逼滚,再给你一次机会')
7 show_wallet()
8 else:
9 print('总资产%d元,开始购物吧高富帅' % wallet)
10 return wallet
11 else:
12 print('糊弄谁呢?再给你一次机会')
13 show_wallet()
3️⃣去除列表里的元素时: 单纯用while可能会删不干净
用for遍历则绝对会出错,因为在遍历列表(或字典)时不可修改其内容,不然其长度会改变,遍历一定是不成功的
可以试试浅拷贝一份列表,for遍历拷贝后的列表,在for循环里删除原列表中想要删除的元素,然后del浅拷贝的列表以释放内存
1 # 接上文
2 # 因if判断条件中变量命名写得有点长,所以没使用and连接,而是直接多个elif判断
3 customer_choice = input("请选择商品编号及数量(以':'区分),使用空格隔开: ")
4 # 如输入内容为:' 4:3:4 3:2 5:1 a:1 %:# # @ 1:120 2:m ''
5 customer_choice_list = customer_choice.split(' ')
6 print(customer_choice_list)
7 temp_list = customer_choice_list.copy() # 浅拷贝,以便后面遍历时删除无效项或非法项
8 for element in temp_list:
9 if element == '' or element == ' ': # 去空(无效项)
10 # print('过多的空格已被自动删除')
11 customer_choice_list.remove(element)
12 elif ':' not in element: # 去掉无":"匹配的项(无效项)
13 # print('无效的匹配项已被自动删除')
14 customer_choice_list.remove(element)
15 elif len(element.split(':')) != 2: # 去掉":"匹配后长度不为2(不是正常匹配)的项目(非法项)
16 # print('非法项已被自动删除')
17 customer_choice_list.remove(element)
18 elif element.split(':')[0].isdigit() == 0 or element.split(':')[-1].isdigit() == 0: # 去掉首尾非数字的项(非法项)
19 # print('非商品编号或非正常商品数量,已自动删除')
20 customer_choice_list.remove(element)
21 elif int(element.split(':')[0]) not in range(1, len(goods) + 1): # print('选择的商品编号不存在,已自动删除.')
22 customer_choice_list.remove(element)
23 elif int(element.split(':')[-1]) > goods[int(element.split(':')[0]) - 1]['allowance']:
24 customer_choice_list.remove(element)
25 element = element.split(':')[0] + ':' + str(goods[int(element.split(':')[0]) - 1]['allowance'])
26 print(">>>%s<<<选择了过多的数量,已自动修改为最大库存量>>%d<<" % (
27 goods[int(element.split(':')[0]) - 1]['name'], goods[int(element.split(':')[0]) - 1]['allowance']))
28 customer_choice_list.append(element)
29 del temp_list # 释放临时列表内存
然后就是for遍历上述代码返回的customer_choice_list,将与之对应的商品信息添加到购物列表里(这一步只是为了展示给用户知道他买了什么东西)
注意: 如果需要让用户可以多次购物,那么他的多次购物的代码一定要写在一个函数里
不然结算sum_price时就无法得到钱包余额,或需要重新调用结算函数,导致用户还需要重新走一次购买流程