小程序2:实现一个购物车
目录
10.如果用户买的商品总价格已经超过了充值金额,代表购物失败,需要从购物车中去删除商品
购物车需要实现的功能
1.正常结算的流程
2.如果余额不足,要删除商品之后再结算
3.如果半途不想买了,按q退出
商品列表要从json文件中取出
下面是json文件的数据内容(shopping.json)
购物车实现流程
1.读取json数据
def read_data(filename,lst=[]): """ 将json文件数据读出来,放到新列表中 :param filename: 要读的json数据文件 :param lst: 读出文件后放入的新列表 :return: """ with open(filename,mode='r+',encoding="utf-8") as fp: for i in fp: dic = json.loads(i) # 将取出的每个小字典i换一个家,放到dic中 print(dic,"dic***") lst.append(dic) # 将每个小字典都放到列表中 return lst goods_lst = read_data("shopping_data.json")
最后返回的lst,它是长这个样子的:
在最后一行,我们调用了刚刚定义的read_data方法,并用good_lst接收,所以现在good_lst就是上面那个样子咯 - -
2.动态进度条
def progress(percent): """ 实现一个进度条的效果 :param percent: 百分比 :return: """ # 如果百分比超过了1,说明数据已经接受完毕 if percent > 1: percent = 1 # 打印对应的#号效果 strvar = "#"*int(percent*50) # 每2%是一颗星,100%是50颗星 print("\r[%-50s] %d%%" % (strvar,int(percent*100)),end="") # 星星+百分比数字
def exe_process(): """ 执行进度条 :return: """ # 初始化接受的字节数 recv_size = 0 # 文件接受总大小 total_size = 102400 while recv_size < total_size: recv_size+=1024 # 模拟延迟3 time.sleep(0.01) # 计算百分比 percent = recv_size/total_size # 调用上面定义的进度条效果 progress(percent)
实现效果如下:
3.充值
现在,我们已经把json数据取出来放到了自己专属的列表里面,同时也做了一个动态的进度条,说明我们的准备工作已经完成了,接下来,就开启正式篇章!
首先,我们必须要先充值,只有你充值了你才能进去买商品~
def recharge(): """ 充值函数 :return: """ global money # money是我们定义的一个全局变量,用来存放用户充值了多少钱 while True: # 设置死循环,万一充值失败,还能重新充值呢 strvar = input("请输入您要充值的金额:") # 用户输入要充值的金额 if strvar.isdecimal(): # 充值成功 money = int(strvar) print("恭喜你,充值成功{}元人民币".format(money)) break else: # 充值失败,重新执行while循环 progress("充值失败,非数字")
实现效果如下:
4.加载中....
充值完,会有一个短暂的加载中的显示,这个很easy,不多赘述
def loading(): """ 加载中 :return: """ print("加载商品中 ... ") exe_process() print()
5.展现全部商品列表
充完钱,也加载完了,现在应该显示出商城里都有哪些商品
def show_goods(): strvar = "{}".format("商品名称").center(20) # 让商品名称居中,并左右都有空格,总共占20个字符 print("序号"+strvar+"价格") # 将序号 商品名称 价格拼接 ,实现 序号 商品名称 价格的效果 for k, v in enumerate(goods_lst,start=1): # print(k,"k***") # k就是编号, 1 2 3 4 5 # print(v,"v***") # v是good_lst字典 # 把序号加到字典v当中 v['num'] = k # 字典v多了一个新的成员num # print(v,"v***") # 现在的v是升级版的字典,里面多了个键:num # 打印出商品的内容 print("{dic[num]:<12}{dic[name]:<12} {dic[price]}".format(dic=v))
实现效果如下:
6.添加购物车
现在我们的商品列表展现出来了,等待我们的就是购买商品啦,在购买商品时,我们每买一个商品,都要显示买的是什么,买了几个,花了多少钱
所以根据这个需求,我们要单独创建一个函数,来做这件事情
def add_car(num): '''添加购物车的时候,我们需要新定义一个数据容器,也就是购物车,用来存放我们买的商品信息''' # 当前购买的商品不在购物车当中,那就添加购物车 if num not in car: car[num] = { "name":goods_lst[num-1]["name"], "price":goods_lst[num-1]["price"], "account":1 } # 如果当前购买的商品在购物车当中,只是在商品的数量上做累加 else: car[num]["account"] += 1 print(car) add_car(3)
在设计购物车时,我们重新定义了一个数据容器:购物车car
它是一个字典,并且在设计这个字典的内部结构时,使用了num单独做键,名字价格数量三者作为一个小字典作为大字典的值这种结构。
这种结构的设计,会让我们接下来取数据的工作变的更加容易
7.展现购物车
既然都添加购物车了,当然也要展现购物车啦
在我们每次买了一个商品之后,都应该显示您选择商品的具体信息
包括名称 单价 数量
所以这个函数,我们就展现一下购物车
def show_car(num): """ 展示购物车 :param num: 商品编号 :return: """ print("*"*50) print("您选择的商品具体信息:") print("*-商品名称:{}".format(car[num]["name"])) print("*-商品单价:{}".format(car[num]["price"])) print("*-商品数量:{}".format(car[num]["account"])) print("*" * 50) print("已成功添加到购物车~ 请继续shopping ~")
实现效果如下:
8.展现购物车中所有商品信息,并计算价格
这个时候,我们已经买了不少东西了,现在我们需要看一下我们都买了哪些东西,并计算一下商品的总价格是多少
def balance(): """ 展现购物车中所有商品详情信息,并计算商品总价格 :return: 商品总价格 """ total = 0 # 初始化一个total 用来存放商品总价格 print("[-------------------您购物车的具体商品如下:-------------------]") for k,v in car.items(): # k是商品编号,v是小字典 # 计算当前商品的总价格 cur_price = v["price"]*v["account"] # 计算购物车中所有商品的总价格 total += cur_price v['num'] = k # v字典添加了第四个成员:商品编号num v['cur_price'] = cur_price # v字典添加了第五个成员:当前商品总价格cur_price print( "序号{dic[num]}: 商品名称:{dic[name]} 商品单价:{dic[price]} 商品数量:{dic[account]} 此商品总价:{dic[cur_price]}".format(dic=v)) return total
实现效果如下:
9.如果用户买的商品总价格没有超过充值金额,代表购物成功
def success(total,money): """ 消费金额小于充值金额-->代表购物成功 :param total:消费总金额 :param money: 充值金额 :return: """ print("正在结算数据中") exe_process() progress("\n请稍后") time.sleep(0.2) print("一共:{}元".format(total)) print("[您已经成功购买以上所有商品 , 余额还剩{}元,感谢您下次光临~]".format(money - total))
实现效果如下:
10.如果用户买的商品总价格已经超过了充值金额,代表购物失败,需要从购物车中去删除商品
def del_goods(total,money): """ 消费金额大于充值金额,消费失败,需要从购物车删除上商品 :param total: 消费金额 :param money: 充值金额 :return: """ print("余额不足,还差{}元,请忍痛割爱,删除某些商品".format(total-money)) num = input("请输入要删除的商品序号:") # 判断当前num是纯数字字符串 if num.isdecimal(): num = int(num) # 判断该序号是否是购物车的数据 if num in car: car[num]["account"]-=1 # 如果数量已经减到0件,意味着从购物车清空该数据 if not car[num]["account"]: car.pop(num) else: print("输入序号不在范围内") else: print("输入序号非法")
实现效果如下:
11.用主函数去调用之前已经定义好的函数
主函数起到一个总调度的作用,整个购物车主要分为充值→展示→购买→结算这几个过程
在购买商品时,会遇到如下这几种情况:
1.你输入了一个购买商品序号,如果你输入的序号在购物车序号范围内,则添加购物车并且展示购物车
2.当你购买完毕时,你需要结算购物车,在输入序号时选择输入n,即可进行结算
在计算时,无非就两种情况:钱够和钱不够
如果钱够,即调用success函数,程序结束。
如果钱不够,就调用del_goods函数,删除商品后再进行结算。
3.在你购买的过程中,如果你突然不想买东西了,你可以输入q直接退出购物车程序。3
4.如果你输入的不是上述三种的任意一种,那么会直接报错。
def main(): """ 主函数,总调度 :return: """ # 1.充值 recharge() # 2.加载中 loading() # 3.展示商品 show_goods() # 4.购买商品 sign = True while sign: num = input("请输入您要购买的商品:") # 购买商品 if num.isdecimal(): num = int(num) if 0 < num <= len( goods_lst ): # 添加购物车 add_car(num) # 展现购物车 show_car(num) else: error() # 计算商品 elif num.upper() == "N": while True: total = balance() if total > money: # 删除购物车中的商品 del_goods(total,money) else: # 打印成功的消息 success(total,money) sign = False break # 按q退出 elif num.upper() == "Q": # 退出 myexit() sign = False # 都不满足,直接报错 else: error() main()
购物车程序所有代码
至此,我们实现了购物车的所有功能,下面是购物车的源码
# ### shopping 购物车 import time,json money = 0 car = {} """ car = { 1:{"name","price","account":2}, 2:{"name","price","account":2}, 3:{"name","price","account":2} } """ # 读取数据 def read_data(filename,lst = []): with open(filename,mode="r+",encoding="utf-8") as fp: for i in fp: dic = json.loads(i) lst.append(dic) return lst # 商品列表 goods_lst = read_data("shopping_data.json") # 进度条 def progress(percent,): # 如果百分比超过了1,说明数据已经接受完毕; if percent > 1: percent = 1 # 打印对应的#号效果 strvar = "#" * int(percent * 50) # %% => % print("\r[%-50s] %d%%" % (strvar,int(percent * 100)) , end="" ) # 执行进度条 def exe_process(): # 初始化接受的字节数 recv_size = 0 # 文件接受总大小 total_size = 102400 while recv_size < total_size: recv_size += 1024 # 模拟延迟 time.sleep(0.01) # 计算百分比 percent = recv_size/total_size #0.001 # 调用进度条 progress(percent) # 充值 def recharge(): global money while True: strvar = input("请充值吧,大哥~") if strvar.isdecimal(): money = int(strvar) print("恭喜你~ 充值成功{}元人民币".format(money)) break else: print("充值失败,非数字.") # 加载中 def loading(): """ 加载中 :return: """ print("加载商品中 ... ") exe_process() print() # 展现商品 def show_goods(): # 序号 商品名称 价格 strvar = "{}".format("商品名称").center(20) print("序号"+strvar+"价格") for k,v in enumerate(goods_lst,start=1): # 把序号加到字典v当中 v["num"] = k # 商品的内容 print("{v[num]:<12}{v[name]:<12} {v[price]}".format(v=v)) # 报错信息 def error(): print("*"*50) print("*{val:^44}*".format(val="这是错误的选项")) print("*"*50) time.sleep(0.5) # 添加购物车 def add_car(num): """ # 购物车: {序号 : 商品信息(名称,价格,数量) } car = { 1:{"name","price","account":2}, 2:{"name","price","account":2}, 3:{"name","price","account":2} } # 商品列表 [ {'name': '电脑', 'price': 1999, 'num': 1}, {'name': '鼠标', 'price': 10, 'num': 2}, {'name': '游艇', 'price': 20, 'num': 3}, {'name': '美女', 'price': 998, 'num': 4}, {'name': '风油精', 'price': 30, 'num': 5} ] """ print(goods_lst) # 当前购买的商品不再购物车当中,那就添加购物车 if num not in car: car[num] = { "name":goods_lst[num-1]["name"], "price":goods_lst[num-1]["price"], "account":1 } # 当前购买的商品再购物车当中,只是在商品的数量上做累加 else: car[num]["account"] += 1 print(car) # 展现购物车 def show_car(num): print("*"*50) print("您选择的商品具体信息:") print("*-商品名称:{}".format(car[num]["name"])) print("*-商品单价:{}".format(car[num]["price"])) print("*-商品数量:{}".format(car[num]["account"])) print("*"*50) print("已成功添加到购物车~ 请继续shopping ~") # 计算价格 def balance(): total = 0 print("[-------------------您购物车的具体商品如下:-------------------]") # 序号2: 商品名称:鼠标 商品单价:10 商品数量:1 此商品总价:10 # 序号3: 商品名称:游艇 商品单价:20 商品数量:1 此商品总价:20 for k,v in car.items(): # 计算当前商品的总价格 cur_price = v["price"] * v["account"] # 计算购物车中所有商品的总价格 total += cur_price v["num"] = k v["cur_price"] = cur_price print("序号{dic[num]}: 商品名称:{dic[name]} 商品单价:{dic[price]} 商品数量:{dic[account]} 此商品总价:{dic[cur_price]}".format(dic=v)) return total # 成功消息 def success(total,money): print("正在结算数据中 ... ") exe_process() print("\n请稍后...") time.sleep(0.1) print("[一共:{}元]".format(total)) # 剩余的金额 = 充值的金额 - 消费的金额 print("[您已经成功购买以上所有商品 , 余额还剩{}元,感谢您下次光临~]".format(money-total)) # 删除商品 def del_goods(total,money): print("余额不足,还差{}元,请忍痛割爱,删除某些商品".format(total-money)) num = input("[-------------------请输入要删除的商品序号:-------------------]") # 判断当前num是存数字字符串 if num.isdecimal(): num = int(num) # 判断该序号是否是购物车中的数据 if num in car: car[num]["account"] -= 1 # 如果数量已经减到0件,意味着从购物车中清空该数据. if not car[num]["account"]: car.pop(num) else: error() else: error() # 退出 def myexit(): print("[============== 欢迎下次光临: ==============]") time.sleep(0.5) def main(): """ 主函数,总调度 :return: """ # 1.充值 recharge() # 2.加载中 loading() # 3.展示商品 show_goods() # 4.购买商品 sign = True while sign: num = input("请输入您要购买的商品:") # 购买商品 if num.isdecimal(): num = int(num) if 0 < num <= len( goods_lst ): # 添加购物车 add_car(num) # 展现购物车 show_car(num) else: error() # 计算商品 elif num.upper() == "N": while True: total = balance() if total > money: # 删除购物车中的商品 del_goods(total,money) else: # 打印成功的消息 success(total,money) sign = False break # 按q退出 elif num.upper() == "Q": # 退出 myexit() sign = False # 都不满足,直接报错 else: error() main()
购物车的流程图