大作業:小型購物車系統
阿新 • • 發佈:2018-12-11
中秋佳節,首先在這裡給各位看到文章的大佬說一聲:中秋快樂。中秋節還在CSDN的一定都是最刻苦的,我們都是有夢想的人,我們也一定能實現我們的夢想!!
程式碼多有漏洞,希望各位大佬幫忙指出,一定認真修改。
作業要求:
寫一個購物車系統,其中包括:1. 註冊;2. 登入;3. 購物;4. 支付;5.充值等功能。
# Coding: utf-8 # Author: Catalog Spri # date: 2018/9/22 # time: 下午2:09 import os, sys # 匯入os, sys庫,os庫用來操作檔案:刪除或重新命名;sys庫用來直接退出程式。 def register(): ''' 將註冊功能封裝,方便後面直接呼叫 :return: 返回值為True ''' spec_char = ['&', '*', '$', '@', '#', '%', '!', '(', ')'] # 定義特殊字元列表,方便密碼合法性監測 with open('account.txt', mode='a+', encoding='utf-8') as f_acc: f_acc.seek(0) # a+模式開啟,需要將檔案指標移至檔案頭 sgn_name = input('Username>>:').strip() for line in f_acc: # 迴圈輸出資料庫中的行 line = line.split('|') if sgn_name == line[0]: # 判斷使用者輸入使用者名稱和資料庫中使用者名稱是否重複。 print('Username already exists, please re-try.') break if sgn_name[0].isdigit() or len(sgn_name) < 6 or len(sgn_name) > 16: print('Incorrect input, please re-try.') # 判斷使用者名稱合法性 break else: # for迴圈正常結束,沒有被break打破,證明使用者名稱合法,執行else程式碼塊 sgn_pwd = input('Password>>:').strip() for char in spec_char: # 迴圈取出特殊字元列表中的字元 if len(sgn_pwd) < 6 or char in sgn_pwd: # 密碼合法性監測 print('Incorrect input, please re-try.') break else: # for迴圈正常結束,沒有被break打破,證明密碼合法,執行else程式碼塊 print('Registration success') info = ('%s|%s|100000\n' % (sgn_name, sgn_pwd)) # 將使用者名稱、密碼、初始金額組成一個字串 f_acc.write(info) # 寫入使用者資料庫中 f_acc.flush() return True # 能走到這一步說明使用者註冊成功。 def log_in(): ''' 將登入系統封裝,方便後面呼叫 函式遇到return會直接結束函式 :return: 返回值為布林值 ''' blacklist = {} # 臨時黑名單計次系統 while True: inp_name = input('Username>>:').strip() inp_pwd = input('Password>>:').strip() with open('blacklist.txt') as f_lock: # 開啟黑名單檔案,判斷使用者名稱是否在黑名單中 for line in f_lock: line = line.strip('\n') if inp_name == line: print('Account has been locked.') return False # 如果使用者名稱在黑名單中,則直接結束登入函式,不再向下執行程式碼 with open('account.txt') as f_msg: # 判斷使用者名稱密碼與資料庫中使用者名稱密碼是否一致 for line in f_msg: line = line.strip('\n').split('|') if inp_name == line[0] and inp_pwd == line[1]: print('Login successful.') return inp_name # 登入成功則結束函式,不再向下執行程式碼 if inp_name == line[0]: # 能執行到這裡則使用者名稱不正確或密碼不正確,判斷使用者名稱是否正確,使用者名稱正確,密碼不正確,則應該新增到臨時黑名單計次資料中 if inp_name in blacklist: # 使用者名稱已存在於臨時黑名單系統,則計次+1 blacklist[inp_name] += 1 else: # 使用者名稱不存在於臨時黑名單系統,則新增進臨時黑名單系統。 blacklist[inp_name] = 1 break with open('blacklist.txt', mode='a', encoding='utf-8') as f_lock: if blacklist.get(inp_name) == 3: # 如果臨時黑名單系統中的次數已經達到三次,則鎖定賬戶,將賬戶名新增到黑名單檔案中。 f_lock.write('%s\n' % inp_name) f_lock.flush() print('Username or password is incorrect, please re-try.\n') def buy(goods_list, shopping_car): ''' 將購物功能封裝 第一個引數為貨物清單,因為每次的貨品清單可能不同,所以不應該將貨物清單在函式中寫死, 可以在函式外寫好,然後以引數的形式傳入函式。 第二個引數為購物車,不應該在函式中將購物車直接定義為空,因為不知道使用者購物車以前是否為空。 :return:將購物車返回,方便後面充值時呼叫 ''' goods_dic = {} # 將商品與商品前的序號建立聯絡 count = 1 # 在商品前面加上序號 print(' Product list '.center(50, '-')) for msg in goods_list: print(count, msg.center(15, ' '), goods_list[msg]) goods_dic[str(count)] = msg count += 1 goods_choice = input('Please enter the name of products \ or the number of produces. >>:').strip() if goods_choice in goods_list or goods_choice in goods_dic: # 判斷使用者輸入是否正確 amount = input('How much do you want to buy? >>:') # 接收使用者購買數量 if amount.isdigit(): # 判斷使用者輸入是否為純數字 amount = int(amount) if goods_choice.isdigit(): # 判斷使用者輸入是否為純數字 goods_name = goods_dic[goods_choice] else: goods_name = goods_choice # 將使用者輸入與商品名稱建立聯絡 if goods_name in shopping_car: # 判斷商品是否已經在購物車中,已存在則數量相加 shopping_car[goods_name] += amount else: # 未存在則新增進購物車 shopping_car[goods_name] = amount return shopping_car # 將購物車作為返回值 print('Incorrect input, please re-try.') # 使用者輸入不正確則執行改行 def pay(shopping_car): # 以上面的購物車為引數傳入,實現支付功能 ''' 將支付功能封裝 :return: ''' total = 0 # 用來存放總金額 for item in shopping_car: # 迴圈取出購物車中的所有商品 single = goods[item] * shopping_car[item] # 計算一種商品的總金額 total += single # 計算全部商品總金額 with open('account.txt') as f1, open('Temporary Files', mode='w') as f2: # 修改使用者資料庫中的金額。前天講到,修改檔案的兩種方法。可以作為參考來理解 for line in f1: line = line.strip('\n').split('|') if inp_name == line[0]: # 判斷使用者名稱與資料庫中的使用者名稱是否一致 money = int(line[2]) # 使用者名稱一致才能修改其後面的金額 money -= total if money < 0: print('Insufficient balance') return False # 如果金額不足,則不能購買,結束函式 else: money = str(money) line = '|'.join(line).replace(line[2], money) f2.write('%s\n' % line) # 金額充足,扣款成功,寫入使用者資料庫 f2.flush() continue line = '|'.join(line) # 使用者名稱與資料庫中的使用者名稱不一致則直接寫入資料庫 f2.write('%s\n' % line) os.remove('account.txt') os.rename('Temporary Files', 'account.txt') print('Payment successful.') def charge(): ''' 充值功能封裝 :return: ''' while True: # 讓使用者輸入要充值的金額,若輸入錯誤則再次輸入 charges = input('Please enter the amount >>:') if charges.isdigit(): charges = int(charges) break else: print('Incorrect input.') with open('account.txt') as f1, open('Temporary Files', mode='w') as f2: for line in f1: # 使用者充值成功需要更改資料庫中資料 line = line.strip('\n').split('|') if inp_name == line[0]: # 判斷使用者名稱與資料庫中哪一行相同 money = int(line[2]) money += charges # 使用者名稱匹配成功則進行充值 money = str(money) print('Now your balance is %s.' % money) line = '|'.join(line).replace(line[2], money) f2.write('%s\n' % line) # 將充值後的資料寫入資料庫 f2.flush() continue # 跳過本次迴圈 line = '|'.join(line) f2.write('%s\n' % line) # 使用者名稱與資料庫中的匹配不成功則直接寫入資料部,不作修改 os.remove('account.txt') os.rename('Temporary Files', 'account.txt') print('Recharge successful.') ''' 定義商品清單 ''' goods = { 'iPhone XS Max': 9599, 'iPhone XS': 8699, 'iPad': 2565, 'AirPods': 1276, 'MacBook Air': 6928, 'MacBook Pro': 11786, } ''' 定義一個空字典,方便存放使用者要購買的商品,以商品和購買數量作為鍵值對 ''' shopping_car = {} while True: choice = input('Log in or register? >>:').strip().lower() # 使用者輸入登入或註冊 if choice == 'register': # 使用者輸入註冊則執行register函式 if register(): # 若註冊成功,register函式返回值為True,執行下面程式碼,執行不成功則返回外層迴圈。 reg_choice = input('Press any key to return to the upper layer. \ Press q to exit the program >>:').strip() if reg_choice == 'q': sys.exit() else: continue elif choice == 'log in': # 使用者輸入登入則執行log_in函式 inp_name = log_in() # log_in函式的返回值即為使用者名稱。需要將其賦予一個變數名方便呼叫 while tag: if inp_name: print(' 功能選擇 '.center(50, '-'), end='') fun_choice = input(''' 1. 購物 2. 支付 3. 充值 4. 退出 >>>:''') if fun_choice == '1' or fun_choice == '購物': buying = buy(goods, shopping_car) elif fun_choice == '2' or fun_choice == '支付': try: # 不購物直接支付會報錯,try語句可以使程式不報錯。 pay(buying) except: # 捕獲異常。 print('No items in the shopping cart.') elif fun_choice == '3' or fun_choice == '充值': charge() elif fun_choice == '4' or fun_choice == '退出': sys.exit() else: print('Incorrect input, please re-try.') else: sys.exit() else: print('Incorrect input, please re-try.') sys.exit()