学习python之路--Day2:购物车程序

需求

用户登陆,第一次登陆,要求输入工资,商品信息从文件里读取,购买商品,扣除余额,退出之后,下一次登陆仍然记住余额;商家登陆,可以添加商品,修改商品价格。

思路

商品信息存放在文件里,程序启动时读取文件,将文件中的商品信息,组成列表。文件信息可以写成列表元组形式,也可以写成字符,再由程序拼接成列表元组,看实际操作怎么方便吧。
第一次登陆需要输入工资,之后就不需要,这个需要创建一个余额文件,启动程序读取文件,如果文件为空,则需要输入工资,如果不为空,读取余额文件,购买商品扣除余额之后修改余额文件。
添加商品,需要输入商品名,价格,创建一个列表,修改价格,用操作列表方式修改。

用户接口流程图

shopping.png

我们先做一个初步的程序,将列表直接写在脚本中,代码示例如下:

#-*- coding:utf-8 -*-
#owner:houyizhong

shoplist=[[1,"iphone",5800],[2,"ipad",3500],[3,"mac pro",12000],[4,"mac air",6800],[5,"apple watch",3000]]
my_shoplist=[]
salary=int(input("Enter your salary:"))

while True:
        print(shoplist)
        enter_choice=input("Enter your choice:")
        #print enter_choice
        #print type(enter_choice)
        if enter_choice == "q":
                print("your salary is {}".format(salary))
                print("your shoplist is {}".format(my_shoplist))
                break
        else:
                shop_choice=int(enter_choice)
                i=shop_choice-1
                shop_goods=shoplist[i][1]
                price=shoplist[i][2]
                if salary >= price:
                        print("you buy {}".format(shoplist[i]))
                        my_shoplist.append(shop_goods)
                        salary -= price
                else:
                        print("\nsorry your salary isn's enought\n")

上面中,我们将商品列表写为
shoplist=[[1,"iphone",5800],[2,"ipad",3500],[3,"mac pro",12000],[4,"mac air",6800],[5,"apple watch",3000]]

也是说,每个商品的序号是写死的,这样是因为还未掌握打印列表项目序号的方法,通过学习和上网查找,我们知道,enumerate(list)方法可以打印出列表各项object的在列表中的index位置,用法如下:

list=["a","b","c"]
for i in enumerate(list):
    print(i)

-----------------
(0, 'a')
(1, 'b')
(2, 'c')

另外,我们这个程序还有个bug就是,如果用户输入的"salary"和"enter_choice"既非数字也非退出键"q",那么程序会出现报错,所以,我们需要对用户输入的salary和enter_choice做一个判断,我们用arg.isdigit()方法来判断变量是否是数字类型,用法示例如下(需要注意的是,变量赋值得是字符str,数字int是不能用isdigit方法判断的):

salary=input()
if salary.isdigit():
    print True

除此之外,我们还要考虑到当商品编号超出可供选择的范围会报错,所以我们还需要对用户输入的choice做一个判断如果,选择在0到5之间就返回正确的值,不在这个返回就会返回商品不存在信息。

经过完善,我们的代码如下:

#-*- coding:utf-8 -*-
#owner:houyizhong

shoplist=[["iphone",5800],["ipad",3500],["mac pro",12000],["mac air",6800],["apple watch",3000]]
my_shoplist=[]
salary=input("Enter your salary:")

if salary.isdigit():
    salary=int(salary)
    while True:
        for index,item in enumerate(product_list):
            print(index+1,item)
        user_choice=input("Choice a product code:")
        if user_choice.isdigit():
            user_choice = int(user_choice)
            if  user_choice <= len(product_list) and user_choice > 0:
                user_choice -= 1
                if product_list[user_choice][1] <= salary:
                    shopping_list.append(product_list[user_choice][0])
                    salary -= product_list[user_choice][1]
                    print("Added {0} to your shopping_list!Your salary is {1}\n".format(product_list[user_choice][0],salary))
                else:
                    print("Sorry your salary is not enought!\n")
            else:
                print("Sorry,product code isn's exist!\n")
        elif user_choice == "q":
            exit("Your shopping list is {0},your salary is {1}.".format(shopping_list,salary))
        else:
            print("Your enter invalid!\n")
else:
    if salary == "q":
        exit("Your shopping list is {0},your salary is {1}.".format(shopping_list,salary))
    else:
        print("Sorry,your enter invalid!")

继续

目前,我们已经做出了一个demo版的购物车程序,接下来,我们要实现从文件中读取数据。

根据以往的经验,我决定把存放商品信息的文件,按如下格式写:

#cat product.txt
iphone:5800
mac pro:12000
bike:800
book:55
coffee:31

这样我将信息加入列表时,就只需要按照":"来分裂原本并在一起的数据,用split(":")方法即可形成一个单独的小列表。

product_list=[['iphone', 5800], ['mac pro', 12000], ['bike', 800], ['book', 55], ['coffee', 31]]

问题

在实现过程中,遇到了一个问题,就是我从balance.txt文件中读取数据,file.readlines()形成一个列表,如果文件为空,则,这个列表为空,那么怎么判断列表是否为空呢,通过上网查询,很快找到了答案:

有两种方法,一种是根据len(list)来判断,另外一种直接以list为判断条件,list为空直接返回False,示例如下

if len(mylist):
# Do something with my list
else:
# The list is empty
if mylist:
# Do something with my list
else:
# The list is empty

两种方法都可以用来判断列表是否有数据。

形成代码如下:

product_list=[]
shopping_list=[]

#read product file
product_file=open("product.txt","r")
pro_read=product_file.readlines()
product_file.close()

#read product and price
for i in pro_read:
        i=i.strip()
        pro_raw=i.split(":")
        price=int(pro_raw[1])
        pro_raw.insert(1,price)
        pro_raw.pop()
        product_list.append(pro_raw)


#read balance file
balance_file=open("balance.txt","r")
bal_read=balance_file.readlines()
balance_file.close()

#if balance exists
if bal_read:
        salary=int(bal_read)
else:
        salary=input("Enter your salary:")


if salary.isdigit():
    salary=int(salary)
    while True:
        for index,item in enumerate(product_list):
            print(index+1,item)
        user_choice=input("Choice a product code:")
        if user_choice.isdigit():
            user_choice = int(user_choice)
            if  user_choice <= len(product_list) and user_choice > 0:
                user_choice -= 1
                if product_list[user_choice][1] <= salary:
                    shopping_list.append(product_list[user_choice][0])
                    salary -= product_list[user_choice][1]
                    print("Added {0} to your shopping_list!Your salary is {1}\n".format(product_list[user_choice][0],salary))
                else:
                    print("Sorry your salary is not enought!\n")
            else:
                print("Sorry,product code isn's exist!\n")
        elif user_choice == "q":
            exit("Your shopping list is {0},your salary is {1}.".format(shopping_list,salary))
        else:
            print("Your enter invalid!\n")
else:
    if salary == "q":
        exit("Your shopping list is {0},your salary is {1}.".format(shopping_list,salary))
    else:
        print("Sorry,your enter invalid!")

写入balance.txt

接下来,我们需要把余额写入balance文件,根据流程图,写入动作是发生在退出程序时的,每一次退出都要有修改文件的动作。所以我们用def函数来做这个操作更好。

代码如下:

#-*-coding:utf-8 -*-
#owner:houyizhong
#version:2.0

product_list=[]
shopping_list=[]

#read product file
product_file=open("product.txt","r")
pro_read=product_file.readlines()
product_file.close()

#read product and price
for i in pro_read:
        i=i.strip()
        pro_raw=i.split(":")
        price=int(pro_raw[1])
        pro_raw.insert(1,price)
        pro_raw.pop()
        product_list.append(pro_raw)

#read balance file
balance_file=open("balance.txt","r")
bal_read=balance_file.readlines()
balance_file.close()

#write balance file
def write_balance (balance):
        balance_file=open("balance.txt","w")
        balance_file.write("{}".format(balance))
        balance_file.close()
        exit("Your shopping list is {0},your salary is {1}.".format(shopping_list,salary))

#if balance exists
if bal_read:
        salary=bal_read[0]
else:
        salary=input("Enter your salary:")

if salary.isdigit():
    salary=int(salary)
    while True:
        for index,item in enumerate(product_list):
            print(index+1,item)
        user_choice=input("Choice a product code:")
        if user_choice.isdigit():
            user_choice = int(user_choice)
            if  user_choice <= len(product_list) and user_choice > 0:
                user_choice -= 1
                if product_list[user_choice][1] <= salary:
                    shopping_list.append(product_list[user_choice][0])
                    salary -= product_list[user_choice][1]
                    print("Added {0} to your shopping_list!Your salary is {1}\n".format(product_list[user_choice][0],salary))
                else:
                    print("Sorry your salary is not enought!\n")
            else:
                print("Sorry,product code isn's exist!\n")
        elif user_choice == "q":
                write_balance(salary)
        else:
            print("Your enter invalid!\n")
else:
    if salary == "q":
        write_balance(salary)
    else:
        print("Sorry,your enter invalid!")

关于用户接口的部分到现在为止就算完成了,接下里是商家接口的。

商家接口

流程图示意

manage_product.png

流程确定好了以后,我们来想想怎么写文件比较好,之前我们的商品文件是用这种形式写的:

#cat product.txt
iphone:5800
mac pro:12000
bike:800
book:55
coffee:31

写入文件的话,需要写成

for i in list:
    f.write("{0}:{1}".format(i[0],i[1]))

先试一下。复制这段代码,实验成功之后,我们再来写其他的部分。

def函数

可以多用用def函数,因为看流程图有很多动作是可以复用的。

#-*- coding:utf-8 -*-
#owner:houyizhong
#version:1.0

product_list=[]

#read product file
product_file=open("product.txt","r")
pro_read=product_file.readlines()
product_file.close()

#read the product and price
for i in pro_read:
        i=i.strip()
        pro_raw=i.split(":")
        product_list.append(pro_raw)

def write_product ():
        f=open("product.txt","w")
        for i in product_list:
                f.write("{0}:{1}\n".format(i[0],i[1]))
        f.close()
        exit()

def add_pro():
        addproduct=input("Enter add product:")
        addprice=input("Enter product price:")
        add_list=[addproduct,addprice]
        product_list.append(add_list)
        print ("Your list is {}\n".format(product_list))

def w_pro():
        changepro=input("Choice a product code:")
        changepro = int(changepro) -1
        changeprice=input("Enter product price:")
        product_list[changepro][1]=changeprice
        print ("Your list is {}\n".format(product_list))

def loop(enter_choice):
        while True:
                if enter_choice == "q":
                        exit()
                elif enter_choice == "add":
                        add_pro()
                        pass
                elif enter_choice == "w":
                        w_pro()
                        pass
                elif enter_choice == "wq":
                        write_product()
                else:
                        print("Sorry,your enter is invalid!\n")
                for index,item in enumerate(product_list):
                        print (index+1,item)
                print("\nEnter 'add':Added product\nEnter 'w':Change the product price\nEnter 'q':Out\nEnter 'wq':Save and exit\n")
                enter_choice=input("Enter your choice:")

while True:
        for index,item in enumerate(product_list):
                print (index+1,item)
        print("\nEnter 'add':Added product\nEnter 'w':Change the product price\nEnter 'q':Out\n")
        action=input("Enter your choice:")
        if action == "q":
                exit()
        elif action == "add":
                loop(action)
                pass
        elif action == "w":
                loop(action)
                pass
        else:
                print("Sorry,your enter is invalid!\n")

接下来跟之前一样,需要对用户输入的choice判断边界,以及是不是数据类型,最好我们给添加一个后退选项,对用户友好些。

完成后的代码如下:

#-*- coding:utf-8 -*-
#owner:houyizhong
#version:2.0

product_list=[]

#read product file
product_file=open("product.txt","r")
pro_read=product_file.readlines()
product_file.close()

#read the product and price
for i in pro_read:
        i=i.strip()
        pro_raw=i.split(":")
        product_list.append(pro_raw)

def write_product ():
        f=open("product.txt","w")
        for i in product_list:
                f.write("{0}:{1}\n".format(i[0],i[1]))
        f.close()
        exit()

def add_pro():
        addproduct=raw_input("Enter add product('b' is back):")
        if addproduct == "b":
                pass
        else:
                addprice=raw_input("Enter product price('b' is back):")
                if addprice == "b":
                        pass
                else:
                        add_list=[addproduct,addprice]
                        product_list.append(add_list)
                        print ("Your list is {}\n".format(product_list))

def w_pro():
        while True:
                changepro=raw_input("Choice a product code('b' is back):")
                if changepro.isdigit():
                        changepro = int(changepro) -1
                        if not 0 <= changepro < len(product_list):
                                print("Sorry,your enter is not exist!\n")
                        else:
                                changeprice=raw_input("Enter product price('b' is back):")
                                if changeprice == "b":
                                        pass
                                else:
                                        product_list[changepro][1]=changeprice
                                        print ("Your list is {}\n".format(product_list))
                                        break
                elif changepro == "b":
                        break
                else:
                        print("Please enter a digit!\n")

def loop(enter_choice):
        while True:
                if enter_choice == "q":
                        exit()
                elif enter_choice == "add":
                        add_pro()
                        pass
                elif enter_choice == "w":
                        w_pro()
                        pass
                elif enter_choice == "wq":
                        write_product()
                else:
                        print("Sorry,your enter is invalid!\n")

                for index,item in enumerate(product_list):
                        print (index+1,item)
                print("\nEnter 'add':Added product\nEnter 'w':Change the product price\nEnter 'q':Out\nEnter 'wq':Save and exit\n")
                enter_choice=raw_input("Enter your choice:")

while True:
        for index,item in enumerate(product_list):
                print (index+1,item)
        print("\nEnter 'add':Added product\nEnter 'w':Change the product price\nEnter 'q':Out\n")
        action=raw_input("Enter your choice:")
        if action == "q":
                exit()
        elif action == "add":
                loop(action)
                pass
        elif action == "w":
                loop(action)
                pass
        else:
                print("Sorry,your enter is invalid!\n")

到目前为止,我们已经完成了用户接口和商家接口的操作。

后续改进的意见

后续改进意见:
文件中的几个def函数 可以拿出来单独放在文件中,用import引用进来,这样方便查阅。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,658评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,482评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,213评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,395评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,487评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,523评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,525评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,300评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,753评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,048评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,223评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,905评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,541评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,168评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,417评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,094评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,088评论 2 352

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,979评论 25 707
  • 需求 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 支持多...
    houyizhong阅读 2,031评论 3 2
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,646评论 18 139
  • 若論此事。佛未出世。祖未西來。照天照地。無欠無餘。即黃面老子出世。胡亂四十九年。終日搖唇鼓舌。亦未道著一字。及末後...
    幽和阅读 436评论 0 0
  • 作者:奔腾 说好了,从这个假期开始,要好好学习,天天向上,从新做人的。 可是,这个假期,感觉每天都在荒废中渡过。那...
    生活的ATM阅读 705评论 7 4