【python作业2回顾】——编写购物车程序、三级菜单程序

第一部分:课堂小练习的思考总结

一、购物车程序

课程中要求所用时间:30分钟
实际自己所用时间:3个小时
这个练习所用时间严重超标,1.5小时用来做基本需求,1.5小时用来做优化了。

需求描述:
1、启动程序后,让用户输入工资,然后打印商品列表
2、允许用户根据商品编号购买商品
3、用户选择商品后,检查余额是否够,够就直接退款,不够就提醒
4、可随时退出,退出时,打印已购买商品和余额

1.1 分析需求

(1)需要创建一个列表用来展示商品信息,再创建一个空列表用来显示已购买的商品信息
(2)用户选择商品后,根据索引的方式找对应商品价格,再根据账户余额进行数据对比
(3)如果成功就在账户余额中减去商品价格,并把此商品放到空列表中,否则,打印账户余额不足。

1.2 思考+第一次代码:

对购物车的随时退出刚开始不知道如何实现,想通过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.3 踩坑点

当时创建商品列表时,有的用双引号,有的用单引号,导致最后索引超出范围,一直没看出来,耽误好长时间,所以以后注意单引号和双引号。

错误示范:
踩坑点

1.4 待改进的方面

(1)问题:对数据边界做了检验并处理,但是对异常值未做检验,例如用户输入字符时,就没有进行处理,因为在选择用户序号时,默认强制字符串转int型了。

待解决方法:选择商品序号时,先不要强制转换字符类型,然后根据字符的范围进行判断,例如字符必须在1到5之间,如果超过范围,直接提醒用户重新操作,如果不超过然后再转换。

ps:如何判定字符在1到5之间?根据ascii码?还是直接字符校验,例如设置一个列表,
list=[‘1’,‘2’,‘3’,‘4’,‘5’],循环列表然后校验,但是好麻烦,还要经过循环,这个后面需要再考虑下。

解决办法:在网上查了一下,发现有个方法可以用,就是isdigit(),可以对用户输入的内容判断是否是数字(注意不是整型数字),然后再进行处理。

定义:
Python isdigit() 方法检测字符串是否只由数字组成。

语法:

str.isdigit()

返回值
如果字符串只包含数字则返回 True 否则返回 False。

(2)当时做列表扩展列表的时候,总是有问题,然后查了很多博客,说明列表还是掌握的不牢固,需要多加强。

(3)时间上所用太多,想的多,做的少(光想了,没有用代码去实现),这个需要去改进。

1.5 优化后的代码

(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.1 需求分析

这个需求一看都能明白,也不知道我哪根筋搭错了,理解偏了(明明作文都没跑题过)

脑袋有坑的理解:
(1)一下子打印出全部菜单,并且全部展示出来。
(2)输入1展示1级菜单,输入2展示2级菜单,输入3展示3级菜单(明明输入2之后还有不同选择)

真实需求:
先展示1级菜单,输入谁进入谁的二级菜单

1.2 第一次代码

基本不用看,太垃圾了,都没实现返回上一级菜单。

'''
要求:
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,但是不知道怎么用

1.3 优化的代码

在网上的讲解之后,自己回顾默写的,(中间又偷偷看了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.4 总结

(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)

奥利给,,加油,,我最棒

你可能感兴趣的:(python)