课程中要求所用时间:30分钟
实际自己所用时间:3个小时
这个练习所用时间严重超标,1.5小时用来做基本需求,1.5小时用来做优化了。
需求描述:
1、启动程序后,让用户输入工资,然后打印商品列表
2、允许用户根据商品编号购买商品
3、用户选择商品后,检查余额是否够,够就直接退款,不够就提醒
4、可随时退出,退出时,打印已购买商品和余额
(1)需要创建一个列表用来展示商品信息,再创建一个空列表用来显示已购买的商品信息
(2)用户选择商品后,根据索引的方式找对应商品价格,再根据账户余额进行数据对比
(3)如果成功就在账户余额中减去商品价格,并把此商品放到空列表中,否则,打印账户余额不足。
对购物车的随时退出刚开始不知道如何实现,想通过while的判断条件去实现,当用户想退出时,就把flag=1,但是后来发现实现失败,因为一开始flag赋值就是0了,所以根本不会满足循环条件,所以这个不能使用,但是如何实现随时退出呢?
所以在我的代码中就把退出做成一个选项,如果选择此选项,就是想要退出,具体情况看代码。
flag = 0
while flag = 1:
for i in goods_show:
print(i)
'''
购物车程序:
需求:
1、启动程序后,让用户输入工资,然后打印商品列表
2、允许用户根据商品编号购买商品
3、用户选择商品后,检查余额是否够,够就直接退款,不够就提醒
4、可随时退出,退出时,打印已购买商品和余额
'''
import itertools
salary = int(input("您好,请输入你的账户余额(工资): "))
#商品列表
goods_show = [["1:"," apple",50],["2:"," orange",30],["3:"," water",10],["4:"," banana",101],["5: 退出"]]
user_buy = []
#通过while循环控制一直可以选择购买商品
while True:
for i in goods_show:
print(i)
buy = [] #注意这个位置,只有每次把buy清空,才不会有多余的数据插入到user_buy中,踩坑点
user_choose = int(input("请选择您想购买的商品序号: "))
goods_index = user_choose - 1 #索引是从0开始,所以需要减去1
#对比商品价格和余额的大小,是否具有购买能力
if goods_index > 4 or goods_index < 0: #对异常输入数据做处理
print("error! 请重新输入正确的商品序号~~")
continue
elif goods_index == 4:
yes_no = input("您是否要退出程序?请确认(q:退出 其他:不退出)")
if yes_no == "q":
break
else:
continue #如果不想退出就直接结束本次循环,继续下次结束
else:
if salary >= goods_show[goods_index][2]:
salary = salary - goods_show[goods_index][2]
buy.insert(-1,goods_show[goods_index][2])
buy.insert(-1,goods_show[goods_index][1])
user_buy.insert(-1,buy)
print("当前购买的商品名称是{name},价格是{money2}".format(name=buy[0],money2=buy[1]))
continue
else:
print("您的余额还有{money},无法购买此商品!".format(money=salary))
print("你的账户余额(工资)还剩余:{money2}".format(money2=salary))
print("您本次所购买的商品信息如下所示:"+'\n',user_buy)
当时创建商品列表时,有的用双引号,有的用单引号,导致最后索引超出范围,一直没看出来,耽误好长时间,所以以后注意单引号和双引号。
(1)问题:对数据边界做了检验并处理,但是对异常值未做检验,例如用户输入字符时,就没有进行处理,因为在选择用户序号时,默认强制字符串转int型了。
待解决方法:选择商品序号时,先不要强制转换字符类型,然后根据字符的范围进行判断,例如字符必须在1到5之间,如果超过范围,直接提醒用户重新操作,如果不超过然后再转换。
ps:如何判定字符在1到5之间?根据ascii码?还是直接字符校验,例如设置一个列表,
list=[‘1’,‘2’,‘3’,‘4’,‘5’],循环列表然后校验,但是好麻烦,还要经过循环,这个后面需要再考虑下。
解决办法:在网上查了一下,发现有个方法可以用,就是isdigit(),可以对用户输入的内容判断是否是数字(注意不是整型数字),然后再进行处理。
定义:
Python isdigit() 方法检测字符串是否只由数字组成。
语法:
str.isdigit()
返回值
如果字符串只包含数字则返回 True 否则返回 False。
(2)当时做列表扩展列表的时候,总是有问题,然后查了很多博客,说明列表还是掌握的不牢固,需要多加强。
(3)时间上所用太多,想的多,做的少(光想了,没有用代码去实现),这个需要去改进。
(1)对数据边界做了检验并处理,例如输入的数据超过了列表的索引,或者负数的存在,将会提示用户输入的不正确,并重新输入。
(2)退出登录时,给用户一个确认操作,如果要求是字符q才能退出,那么其他就是不退出。在代码中给出了检验,如果输入内容不等于字符q,那么就会结束当前循环,并继续下次循环,重新开始选商品。
(3)对列表的序号进行优化,之前是把序号放在了列表中,现在是进行改进,不在列表中添加序号了,直接使用enumerate打印索引。
(4)列表长度不能直接用数字代表,例如5,而是用len(list)
(5)while True中可以用exit()方法进行退出
但是注意:
exit()的退出是退出了程序,再也不运行任何代码了,包括循环外的代码。
而break是退出本次循环,还会继续运行循环外的代码,注意二者的区别使用。
'''
购物车程序:
需求:
1、启动程序后,让用户输入工资,然后打印商品列表
2、允许用户根据商品编号购买商品
3、用户选择商品后,检查余额是否够,够就直接退款,不够就提醒
4、可随时退出,退出时,打印已购买商品和余额
'''
while True:
salary = input("您好,请输入你的账户余额(工资): ")
if salary.isdigit():
salary = int(salary)
break
else:
print("\033[31;1m您输入的余额不正确!请重新输入\033[0m。")
continue
#商品列表
goods_show = [["apple",50],["orange",30],["water",10],["banana",101],["退出"]]
user_buy = []
#通过while循环控制一直可以选择购买商品
while True:
for index,item in enumerate(goods_show): #进行改进,不在列表中添加序号了,直接使用enumerate打印索引
print(index+1,item)
buy = [] #注意这个位置,只有每次把buy清空,才不会有多余的数据插入到user_buy中,踩坑点
user_choose = input("请选择您想购买的商品序号: ")
if user_choose.isdigit(): #通过isdigit()实现了用户非法输入的问题
user_choose = int(user_choose)
goods_index = user_choose - 1 # 索引是从0开始,所以需要减去1
# 对比商品价格和余额的大小,是否具有购买能力
if goods_index > len(goods_show) - 1 or goods_index < 0: # 对异常输入数据做处理
print("\033[31;1merror! 请重新输入正确的商品序号~~\033[0m")
continue
elif goods_index == len(goods_show) - 1:
yes_no = input("您是否要退出程序?请确认(q:退出 其他:不退出)")
if yes_no == "q":
break
else:
continue # 如果不想退出就直接结束本次循环,继续下次结束
else:
if salary >= goods_show[goods_index][1]:
salary = salary - goods_show[goods_index][1]
buy.insert(-1, goods_show[goods_index][1])
buy.insert(-1, goods_show[goods_index][0])
user_buy.insert(-1, buy)
# 颜色加高亮,固定格式,死记硬背 \033[31;1m需高亮部分\033[0m 31荧光色,32红色 30白色 42背景是红底,这是3和4的区别。。。
print(
"当前购买的商品名称是\033[32;1m{name}\033[0m,价格是\033[31;1m{money2}\033[0m".format(name=buy[0], money2=buy[1]))
continue
else:
print("您的余额还有{money},无法购买此商品!".format(money=salary))
else:
print("\033[31;1m您输入的序号不存在,请重新再试!!!\033[0m")
continue
print("你的账户余额(工资)还剩余:\033[32;1m{money2}\033[0m".format(money2=salary))
print("您本次所购买的商品信息如下所示:"+'\n',user_buy)
要求:
1.打印市、区、街道三级菜单
2.按b可随时返回上一级
3.按q可随时退出程序
这个需求一看都能明白,也不知道我哪根筋搭错了,理解偏了(明明作文都没跑题过)
脑袋有坑的理解:
(1)一下子打印出全部菜单,并且全部展示出来。
(2)输入1展示1级菜单,输入2展示2级菜单,输入3展示3级菜单(明明输入2之后还有不同选择)
真实需求:
先展示1级菜单,输入谁进入谁的二级菜单
基本不用看,太垃圾了,都没实现返回上一级菜单。
'''
要求:
1.打印市、区、街道三级菜单
2.按b可随时返回上一级(未实现)
3.按q可随时退出程序
'''
dict={
'北京':{'海淀区':['中关村','北太平庄','西三旗'], '昌平区':['回龙观','霍营','沙河'],'朝阳区':['酒仙桥','望京','将台']},
'上海':{'浦东新区':['陆家嘴','周家渡','塘桥'],'宝山区':['罗店镇','大场镇','杨行镇'],'虹口区':['广中路','曲阳路','欧阳路']},
'广州':{'白云区':['曲沃','侯马','临汾'],'天河区':['运城','新绛','闻喜'],'南沙区':['太原','小店','杏花岭']}
}
for i in dict:
print(i, ':')
for j in dict[i]:
print(j.rjust(8,' '), ':')
for k in dict[i][j]:
print(k.rjust(16,' '))
while True:
operate_choose = input("please input you want to go menu: ")
if operate_choose.isdigit():
operate_choose = int(operate_choose)
if operate_choose == 3:
for i in dict:
print(i, ':')
for j in dict[i]:
print(j.rjust(8, ' '), ':')
for k in dict[i][j]:
print(k.rjust(16, ' '))
# while True:
# operate_choose1 = input("接下来的操作:")
# if operate_choose1 == 'b':
elif operate_choose == 2:
for i in dict:
print(i, ':')
for j in dict[i]:
print(j.rjust(8, ' '), ':')
elif operate_choose == 1:
for i in dict:
print(i, ':')
else:
print("请输入正确的数字(1 2 3)")
continue
elif operate_choose == 'b':
print("待补充~~")
elif operate_choose == 'q':
exit()
else:
print("input content is error!")
print("请重新输入")
continue
也想到了while中嵌套while,但是不知道怎么用
在网上的讲解之后,自己回顾默写的,(中间又偷偷看了2眼),然后写的。
'''
要求:
1.打印市、区、街道三级菜单
2.按b可随时返回上一级
3.按q可随时退出程序
'''
dict = {
'北京': {'海淀区': ['中关村', '北太平庄', '西三旗'], '昌平区': ['回龙观', '霍营', '沙河'], '朝阳区': ['酒仙桥', '望京', '将台']},
'上海': {'浦东新区': ['陆家嘴', '周家渡', '塘桥'], '宝山区': ['罗店镇', '大场镇', '杨行镇'], '虹口区': ['广中路', '曲阳路', '欧阳路']},
'广州': {'白云区': ['曲沃', '侯马', '临汾'], '天河区': ['运城', '新绛', '闻喜'], '南沙区': ['太原', '小店', '杏花岭']}
}
choose_flag = False
while not choose_flag:
for i1 in dict:
print(i1)
choose1 = input(">>>请选择要进入的二级菜单是:")
if choose1 in dict:
while not choose_flag:
for i2 in dict[choose1]:
print('\t',i2)
choose2 = input(">>>请选择要进入的三级菜单是:")
if choose2 in dict[choose1]:
while not choose_flag:
for i3 in dict[choose1][choose2]:
print('\t\t',i3)
choose3 = input(">>>请选择接下来的操作(q:退出 b:返回上一级):")
if choose3 == 'b':
break
elif choose3 == 'q':
choose_flag = True
else:
print("您输入的有误,请重新输入")
continue
elif choose2 == 'b':
break
elif choose2 == 'q':
choose_flag = True
else:
print("您输入的有误,请重新输入")
continue
elif choose1 == 'q':
choose_flag = True
else:
print("您输入的有误,请重新输入")
continue
(1)在实现:按b可随时返回上一级时,可通过修改判断条件来实现。新掌握了一种方法,这个方法可以以后用。
flag = False
while not flag:
if a1 == 'str'
print(a1)
else:
flag = True
#通过设置flag为真,那么循环条件就为假,此时结束循环,特别适用在循环套循环中。
(2)字典的打印和操作一定要掌握好。
(3)注意需要嵌套while的地方,这个很重要,为甚在这个地方嵌套?是因为返回上一级了,就要展示上一级的菜单,所以不能在input前面嵌套,这也是写的时候踩的坑(为了这个坑,就去瞅别人的代码了)
(4)在打印字典的菜单时,为了区分一级二级三积极菜单,就想用空格填充
#刚开始的写法:
print(' ',i)
#自己查询后的写法:
print(i.rjust(15,' '))
#别人代码的写法
print('\t\t\t',i)
奥利给,,加油,,我最棒