一.需求分析
ATM機要為用戶提供轉賬,提現,還款,付款,消費流水,操作記錄等操作接口
ATM機要為管理員提供創建用戶,凍結解凍,修改額度的功能
ATM機管理員認證使用裝飾器來實現
購物車要提供管理員和用戶兩個接口
用戶接口需要提供,查詢余額,充值,查詢用戶消費記錄,購物等操作接口
商戶接口需要提供,上架,下架,修改,查看上架貨品等操作接口
二.流程圖
三.代碼實現
工程的創建按照較為簡便的格式來描述,大致目錄結構如圖:
ATMandShopCar/ |-- bin/ | |-- |-- DataAccess
| |--ATM_UserCard.txt
| |--ATM_UserInfo.txt
| |--ATM_UserOpt.txt
| |--goods_info.txt
| |--users_info.txt
| |--users_value.txt
|
|-- ShopingCar/ | |-- tests/ | | |-- __init__.py | | |-- test_main.py | |--ATM.py
| |--DataAccess.py
| |--ShoopingCar.py
| |-- __init__.py | |-- main.py | |-- docs/ | |-- conf.py | |-- abc.rst | |-- setup.py |-- requirements.txt |-- README
上述目錄中最主要的部分是:DataAccess和ShopingCar兩個文件夾,DataAccess主要存放用戶操作數據,俗稱數據庫,本工程使用文本作為存儲數據的載體。ShopingCar為程序處理.py,DataAccess.py主要用於對數據庫的操作,ATM.py和ShoopingCar.py分別處理相應的atm機和購物車的邏輯。main.py為主函數,處理程序主邏輯。
DataAccess.py程序代碼如下:
import os import time BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+'/DataAccess/'#設置路徑 user_status = False # 用戶轉賬接口 def ATM_UserTranster(UserID): #用戶轉賬接口 #此程序接口不適用與管理數據量較大的數據,采用的是一次讀取文件所有數據操作方式 with open(BASE_DIR +'ATM_Useropt.txt', 'a')as f: info = UserID + ' ' + '轉賬' + ' ' + time.strftime('%Y-%m-%d-%X') + '\n' f.write(info) a = [] with open(BASE_DIR + 'ATM_UserCard.txt', 'r') as f: for line in f: a.append(line.strip().split(' ')) for i,index in enumerate(a): if index[0] == UserID: if index[4] == '0': print("當前賬戶被凍結,無法轉賬!") return Balance = int(index[5]) pos=i print("賬戶\033[32;1m%s\033[0m可供轉賬余額為 :%s" % (UserID, Balance)) break while True: UserCardID = input('請輸入待轉賬用戶卡號輸入q退出 :') if UserCardID.isdigit(): for index in a : if index[0] == UserCardID: Value = input("請輸入轉賬金額輸q退出:") if Value.isdigit(): Value = int(Value) if Value>Balance: print("操作失敗,余額不足!") else: index[5]=str(int(index[5])+Value) a[pos][5]=str(Balance-Value) with open(BASE_DIR + 'ATM_UserCard.txt', 'w') as f: for line in a: f.write(' '.join(line)+'\n') print("轉賬成功!當前賬戶余額為 :\033[32;1m%s\033[0m"%a[pos][5]) return elif 'q' == Value: break else: pass elif 'q' == UserCardID: break else: pass #提現接口 def ATM_UserWithdrawal(UserID): with open(BASE_DIR +'ATM_Useropt.txt', 'a')as f: info = UserID+ ' '+'提現' + ' ' + time.strftime('%Y-%m-%d-%X') + '\n' f.write(info) a = [] with open(BASE_DIR + 'ATM_UserCard.txt', 'r') as f: for line in f: a.append(line.strip().split(' ')) for i,index in enumerate(a): if index[0] == UserID: if index[4] == '0': print("當前賬戶被凍結,無法提現!") return Balance = int(index[5]) print("賬戶\033[32;1m%s\033[0m可供提現金額為 :%s" % (UserID, Balance)) break while True: Value=input("請輸入要提現的金額輸入q退出:") if Value.isdigit(): Value = int(Value) if Value>Balance: print("余額不足,提現失敗") else: Balance = Balance-Value print("提現成功,賬戶余額為 \033[32;1m%s\033[0m"%Balance) elif 'q'==Value: index[5] = str(Balance) with open(BASE_DIR + 'ATM_UserCard.txt', 'w') as f: for line in a: f.write(' '.join(line) + '\n') print("謝謝使用!") return break else: pass #流水 def ATM_UserWater(UserName,UserID): with open(BASE_DIR + 'ATM_Useropt.txt', 'a')as f: info = UserID + ' ' + '查流水' + ' ' + time.strftime('%Y-%m-%d-%X') + '\n' f.write(info) user_info = [] with open(BASE_DIR + 'ATM_UserInfo.txt', 'r')as f: for line in f: user_info.append(line.strip().split(' ')) T = False for line in user_info: if UserName == line[0]: T = True print('用戶 :\033[32;1m%s\033[0m 購物清單 :%s 消費 :%s 日期 :%s' % (line[0], line[1], line[2], line[3])) if T == False: print("用戶\033[32;1m%s\033[0m無消費記錄!" % UserName) #操作記錄 def ATM_UserOpt(UserID): with open(BASE_DIR + 'ATM_Useropt.txt', 'a')as f: info = UserID + ' ' + '查操作記錄' + ' ' + time.strftime('%Y-%m-%d-%X') + '\n' f.write(info) user_info = [] with open(BASE_DIR + 'ATM_Useropt.txt', 'r')as f: for line in f: user_info.append(line.strip().split(' ')) T = False for line in user_info: if UserID == line[0]: T = True print('用戶 :\033[32;1m%s\033[0m 操作內容 :%s 日期 :%s' % (line[0],line[1],line[2])) if T == False: print("用戶\033[32;1m%s\033[0m 無操作記錄!" % UserID) #還款接口 def ATM_UserReimbursement(UserID): with open(BASE_DIR + 'ATM_Useropt.txt', 'a')as f: info = UserID + ' ' + '還款' + ' ' + time.strftime('%Y-%m-%d-%X') + '\n' f.write(info) a = [] with open(BASE_DIR + 'ATM_UserCard.txt', 'r') as f: for line in f: a.append(line.strip().split(' ')) for i, index in enumerate(a): if index[0] == UserID: if index[4] == '0': print("當前賬戶被凍結,無法操作!") return Balance = 15000-int(index[5]) if Balance<0: print("賬戶\033[32;1m%s\033[0m無需還款!"%UserID) return print("賬戶\033[32;1m%s\033[0m需要還款金額為 :%s" % (UserID, Balance)) break while True: Value = input("請輸入還款金額輸入q退出 :") if Value.isdigit(): Value = int(Value) if(int(index[5])+Value)>int(index[3]): index[5] = str(int(index[5])+Value) print("還款成功,當前賬戶活期余額為 :%s,剩余可用信用額度為 :%s"%(int(index[5])-int(index[3]),index[3])) else: index[5] = str(int(index[5]) + Value) print("還需還款金額為 :%s,當前可用額度為 :%s" %(int(index[3])-int(index[5]),index[5])) elif Value=='q': with open(BASE_DIR + 'ATM_UserCard.txt', 'w') as f: for line in a: f.write(' '.join(line) + '\n') print("謝謝使用!") break else: pass # 用戶刷卡接口 # 參數:Count_Value消費金額 def ATM_ExpensePort(Count_Value): UserInfo = [] with open(BASE_DIR + 'ATM_UserCard.txt', 'r') as f: for line in f: UserInfo.append(line.strip().split(' ')) while True: UserID = input("請輸入賬戶名稱:") Password = input("請輸入密碼:") t = True for line in UserInfo: if line[0] == UserID and line[1] == Password: t = False if line[4] == '1': print("賬戶當前可用額度為:\033[32;1m%s\033[0m" % line[5]) if int(Count_Value) > int(line[5]): print("賬戶額度不足!") else: line[5] = str(int(line[5]) - int(Count_Value)) print("此次消費:\033[32;1m%s\033[0m,當前額度為:\033[32;1m%s\033[0m" % (Count_Value, line[5])) with open(BASE_DIR + 'ATM_UserCard.txt', 'w')as f: for line in UserInfo: f.write(' '.join(line) + '\n') return True else: print("帳號已被封鎖,請到櫃台處理!") return False if t == True: print("賬戶或密碼錯誤!") pass #認證裝飾器 def login(func): def inuc(*args, **kwargs): _username = "alex" # 假裝這是DB里存的用戶信息 _password = "123456" # 假裝這是DB里存的用戶信息 global user_status if user_status == False: username = input("username:") password = input("password:") if username == _username and password == _password: print("登入成功!") user_status = True if user_status == True: func(*args, **kwargs) return inuc #添加賬戶 @login def ATM_UserAdd(): a=[] with open(BASE_DIR + 'ATM_UserCard.txt', 'r') as f: for line in f: a.append(line.strip().split(' ')) while True: Value = input("請輸入要注冊的賬號,密碼,用戶名,以逗號隔開,輸入q退出 :") if Value =='q': break else: b=Value.split(',') f = True for line in a: if line[0]==b[0]: f = False break if f==False: print("賬戶已存在!") pass else: b.extend(['15000','1','15000',time.strftime( '%Y-%m-%d-%X')]) with open(BASE_DIR + 'ATM_UserCard.txt','a')as f: f.write(' '.join(b) + '\n') print("用戶注冊成功!") break #用戶額度管理 @login def Account_Manage(): a = [] with open(BASE_DIR + 'ATM_UserCard.txt', 'r') as f: for line in f: a.append(line.strip().split(' ')) Over_Flag = False while True: if Over_Flag == True: break UserId = input("請輸入用戶賬戶:") if UserId.isdigit(): F = False for line in a: if UserId == line[0]: F = True print("用戶當前額度為:\033[32;1m%s\033[0m"%line[3]) while True: Value = input("請輸入更新額度,輸入q退出:") if Value.isdigit(): line[3] = Value print("額度修改成功!") elif Value=='q': with open(BASE_DIR + 'ATM_UserCard.txt','w')as f: for lines in a: f.write(' '.join(lines)+'\n') Over_Flag = True break else: print("輸入有誤!") break if F == False: print("賬戶不存在!") elif UserId == 'q': break else: print("輸入有誤!") pass #賬戶凍結 @login def user_freeze(): a=[] with open(BASE_DIR + 'ATM_UserCard.txt', 'r') as f: for line in f: a.append(line.strip().split(' ')) while True: UserId = input("請輸入用戶賬戶:") if UserId.isdigit(): for line in a: if UserId == line[0]: if line[4]=='1': print("賬戶當前狀態為:\033[32;1m%s\033[0m" %('正常')) else: print("賬戶當前狀態為:\033[32;1m%s\033[0m" %('凍結')) while True: Flag = input("1.凍結,2.解凍,q.退出:") if Flag.isdigit(): if Flag =='1': line[4] = '0' print("該賬戶已凍結!") elif Flag =='2': line[4] = '1' print("該賬戶已解凍!") else: pass elif Flag == 'q': with open(BASE_DIR + 'ATM_UserCard.txt','w')as f: for lines in a: f.write(' '.join(lines)+'\n') break else: pass elif Flag == 'q': break else: pass #查詢數據庫中的數據 def search_data_access(): goods=[] with open(BASE_DIR+'goods_info.txt','r')as f: for line in f: goods.append(line.strip().split(' ')) for i in range(len(goods)): print('%s 價格 :%s 庫存 :%s'%(goods[i][0],goods[i][1],goods[i][2])) #添加商品操作 #參數說明:goodname 商品名 prace 價格 Num 庫存量 def add_goods_opt(GoodName,prace,Num): goods = [] with open(BASE_DIR+'goods_info.txt','r')as f: for line in f: goods.append(line.strip().split(' ')) T = False for line in goods: if line[0] == GoodName: T = True print("商品已存在,添加失敗!") return Info = GoodName+' '+str(prace)+' '+str(Num)+'\n' with open(BASE_DIR + 'goods_info.txt', 'a')as f: f.write(Info) print("添加商品%s成功!" %GoodName ) #刪除商品操作 def delet_goods_opt(GoodName): goods=[] with open(BASE_DIR+'goods_info.txt','r')as f: for line in f: goods.append(line.strip().split(' ')) for line in goods: if GoodName == line[0]: print("刪除商品%s成功!"%line[0]) goods.remove(line) with open(BASE_DIR + 'goods_info.txt', 'w')as f: for line in goods: f.write(' '.join(line) + '\n') return print("沒有此商品信息,刪除失敗!") #修改商品參數 #參數說明:goodname 商品名 prace 價格 Num 庫存量 def Change_goods_info(GoodName,prace,Num): goods = [] with open(BASE_DIR+'goods_info.txt','r')as f: for line in f: goods.append(line.strip().split(' ')) for line in goods: if line[0] == GoodName: line[1] = str(prace) line[2] = str(Num) with open(BASE_DIR+'goods_info.txt','w')as f: for lines in goods: f.write(' '.join(lines) + '\n') print("商品%s參數修改成功!"%(GoodName)) return print("數據庫中沒有此商品,修改失敗!") #查用戶余額 def user_printAccountBalance(UserName): user_info=[] with open(BASE_DIR + 'users_value.txt', 'r')as f: for line in f: user_info.append(line.strip().split(' ')) for line in user_info: if line[0] == UserName: print("\033[32;1m%s\033[0m的賬戶余額 :\033[32;1m%s\033[0m"%(UserName,line[1])) return #充值 # UserName :用戶名,充值金額 :新老用戶標識 新用戶為True老用戶為False def user_TopUp(UserName,Value): user_info = [] with open(BASE_DIR+'users_value.txt', 'r')as f: for line in f: user_info.append(line.strip().split(' ')) for line in user_info: if line[0] == UserName: line[1]=str(int(line[1])+Value) with open(BASE_DIR+'users_value.txt', 'w')as f: for lines in user_info: f.write(' '.join(line) + '\n') print("充值成功\033[32;1m%s\033[0m當前的賬戶余額 :\033[32;1m%s\033[0m" % (UserName, line[1])) return user_info = UserName + ' ' + str(Value) + '\n' with open(BASE_DIR + 'users_value.txt', 'a')as f: f.write(user_info) print("新用戶充值成功\033[32;1m%s\033[0m當前的賬戶余額 :\033[32;1m%s\033[0m" % (UserName, Value)) #查詢用戶消費記錄 def user_RecordsConsumption(UserName): user_info = [] with open(BASE_DIR+'users_info.txt', 'r')as f: for line in f: user_info.append(line.strip().split(' ')) T = False for line in user_info: if UserName == line[0]: T=True print('用戶 :\033[32;1m%s\033[0m 購物清單 :%s 消費 :%s 日期 :%s'%(line[0],line[1],line[2],line[3])) if T==False: print("用戶\033[32;1m%s\033[0m無消費記錄!"%UserName) #購物車 def user_ShoopCar(Username): goods_info = [] ShoopCar = [] # 創建購物車列表 expense = 0 Salary = 0 Count = 0 with open(BASE_DIR + 'goods_info.txt', 'r')as f: for line in f: goods_info.append(line.strip().split(' ')) with open(BASE_DIR + 'users_value.txt', 'r')as f: for line in f: if line.split(' ')[0] == Username: Salary = int(line.split(' ')[1]) while True: for i, index in enumerate(goods_info): print(i, index) getNum = input("請輸入要購買的商品編號,輸入c結算,輸入q退出:") if getNum.isdigit():# getNum=int(getNum) Count += int(goods_info[getNum][1]) ShoopCar.append(goods_info[getNum][0]) expense += int(goods_info[getNum][1])#消費入庫 if int(goods_info[getNum][2]) > 0: goods_info[getNum][2] = str(int(goods_info[getNum][2])-1) print("當前已消費 :\033[32;1m%s\033[0m"%Count) elif getNum=='c':#結算 while True: opt = input("結算方式:1.余額,2.刷卡,3.退出 :") if opt.isdigit(): if opt=='1': if Salary < Count: print("余額不足") pass else: print("付款成功,當前余額為:\033[32;1m%s\033[0m"%(Salary-Count)) with open(BASE_DIR + 'users_info.txt', 'a')as f: f.write(Username + ' ' + ','.join(ShoopCar) + ' ' + str(expense) + ' ' + time.strftime('%Y-%m-%d-%X') + '\n') with open(BASE_DIR+'goods_info.txt', 'w')as f: for line in goods_info: f.write(' '.join(line)+'\n') value_info = [] with open(BASE_DIR+'users_value.txt', 'r')as f: for line in f: value_info.append(line.strip().split(' ')) for line in value_info: if line[0] == Username: line[1] = str(Salary-Count) with open(BASE_DIR + 'users_value.txt', 'w')as f: for line in value_info: f.write(' '.join(line) + '\n') elif opt == '2':#刷卡 if ATM_ExpensePort(Count)==True:#刷卡接口 with open(BASE_DIR + 'ATM_UserInfo.txt', 'a')as f: f.write(Username + ' ' + ','.join(ShoopCar) + ' ' + str(expense) + ' ' + time.strftime('%Y-%m-%d-%X') + '\n') with open(BASE_DIR + 'users_info.txt', 'a')as f: f.write(Username + ' ' + ','.join(ShoopCar) + ' ' + str(expense) + ' ' + time.strftime('%Y-%m-%d-%X') + '\n') with open(BASE_DIR+'goods_info.txt', 'w')as f: for line in goods_info: f.write(' '.join(line)+'\n') elif opt == '3': return else: pass break elif getNum=='q':#退出 break else: pass
ATM.py程序代碼如下:
from ATMandShoopCar.ShoopingCar import DataAccess import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))+'/DataAccess/'#設置路徑 #ATM操作 def ATM_Opt(): a=[] with open(BASE_DIR+'ATM_UserCard.txt','r')as f: for line in f: a.append(line.strip().split(' ')) while True: opt = input("1.用戶選項,2.管理員選項,輸入q退出:") if opt.isdigit(): if opt =='1':#用戶選項 while True: username=input("請輸入用戶賬號,輸入q退出:") if username=='q':break password=input("請輸入密碼,輸入q退出:") if password=='q': break T = False for line in a: if line[0]==username and line[1]==password: T = True print("登入成功!!!") while True: Chose =input("1.轉賬,2.提現,3.消費流水,4.還款,5.用戶操作記錄,輸入q退出: ") if Chose.isdigit(): if Chose=='1': DataAccess.ATM_UserTranster(username)#轉賬 elif Chose=='2': DataAccess.ATM_UserWithdrawal(username)#提現 elif Chose=='3': Username=input("請輸入用戶名:") DataAccess.ATM_UserWater(Username,username)#消費流水 elif Chose=='4': DataAccess.ATM_UserReimbursement(username)#還款 elif Chose=='5': DataAccess.ATM_UserOpt(username)#用戶操作記錄 else: pass elif Chose=='q': break else: pass break if T ==False: print("賬號密碼錯誤!!") elif opt=='2':#管理員選項 while True: Chose = input("1.添加賬戶,2.用戶額度管理,3.賬戶凍結,輸入q退出: ") if Chose.isdigit(): if Chose == '1': DataAccess.ATM_UserAdd()#賬戶添加 elif Chose =='2': DataAccess.Account_Manage() elif Chose =='3': DataAccess.user_freeze() else: pass elif Chose =='q': global user_status user_status = False break else: pass else: pass elif opt=='q': break else: pass
ShoopingCar.py程序代碼如下:
from ATMandShoopCar.ShoopingCar import DataAccess def ShoopingCar_Opt(): while True: Num=input("1.用戶界面,2.商家界面,輸入q退出 :") if Num.isdigit(): Num = int(Num) if Num == 1: username = input("Please Input The Username :") DataAccess.user_printAccountBalance(username) while True: UserChoose = input("1.查詢購物記錄,2.購物,3.充值,輸入q返回上級目錄 :") if UserChoose.isdigit(): UserChoose = int(UserChoose) if UserChoose == 1: DataAccess.user_RecordsConsumption(username)#查詢購物記錄 break elif UserChoose == 2: DataAccess.user_ShoopCar(username)#購物車 break elif UserChoose == 3: value = int(input("請輸入充值金額 :")) DataAccess.user_TopUp(username, value)#充值 elif UserChoose=='q': break else: pass elif Num == 2:#商家界面 DataAccess.search_data_access()#打印商品信息和庫存 while True: UserChoose = input("1.添加商品,2.修改商品信息,3.刪除商品,輸入q返回上級目錄 :") if UserChoose.isdigit(): UserChoose = int(UserChoose) if UserChoose==1: goodsname=input("請輸入商品名 :") goodsvalue=int(input("請輸入商品價格 :")) goodnum = int(input("請輸入商品數量 :")) DataAccess.add_goods_opt(goodsname, goodsvalue, goodnum)#商品添加操作 elif UserChoose==2: goodsname = input("請輸入要修改的商品名 :") goodsvalue = int(input("請輸入商品價格 :")) goodnum = int(input("請輸入商品數量 :")) DataAccess.Change_goods_info(goodsname, goodsvalue, goodnum) elif UserChoose==3: goodsname = input("請輸入要刪除的商品名 :") DataAccess.delet_goods_opt(goodsname) elif UserChoose=='q': break else: pass else: pass elif Num == 'q': break else: pass
main.py程序代碼如下:
from ATMandShoopCar.ShoopingCar import ShoopingCar from ATMandShoopCar.ShoopingCar import ATM def main(): while True: opt=input("1.ATM,2.購物車,輸入q退出:") if opt.isdigit(): if opt =='1': ATM.ATM_Opt() elif opt=='2': ShoopingCar.ShoopingCar_Opt() else: pass elif opt=='q': break else: pass main()
數據庫ATM_Use'rCard.txt格式如圖:
數據庫ATM_Use'rInfo.txt格式如圖:
數據庫ATM_UserOpt.txt格式如圖:
數據庫goods_info.txt格式如圖:
數據庫users_info.txt格式如圖:
數據庫users_value.txt格式如圖: