學習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引用進來,這樣方便查閱。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,447評論 25 708
  • 需求 額度 15000或自定義 實現購物商城,買東西加入 購物車,調用信用卡接口結賬 可以提現,手續費5% 支持多...
    houyizhong閱讀 2,067評論 3 2
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,973評論 19 139
  • 若論此事。佛未出世。祖未西來。照天照地。無欠無餘。即黃面老子出世。胡亂四十九年。終日搖唇鼓舌。亦未道著一字。及末後...
    幽和閱讀 501評論 0 0
  • 作者:奔騰 說好了,從這個假期開始,要好好學習,天天向上,從新做人的。 可是,這個假期,感覺每天都在荒廢中渡過。那...
    生活的ATM閱讀 741評論 7 4