一.需求分析
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') + ' ' 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("账户 33[32;1m%s 33[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)+' ') print("转账成功!当前账户余额为 : 33[32;1m%s 33[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') + ' ' 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("账户 33[32;1m%s 33[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("提现成功,账户余额为 33[32;1m%s 33[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) + ' ') 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') + ' ' 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('用户 : 33[32;1m%s 33[0m 购物清单 :%s 消费 :%s 日期 :%s' % (line[0], line[1], line[2], line[3])) if T == False: print("用户 33[32;1m%s 33[0m无消费记录!" % UserName) #操作记录 def ATM_UserOpt(UserID): with open(BASE_DIR + 'ATM_Useropt.txt', 'a')as f: info = UserID + ' ' + '查操作记录' + ' ' + time.strftime('%Y-%m-%d-%X') + ' ' 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('用户 : 33[32;1m%s 33[0m 操作内容 :%s 日期 :%s' % (line[0],line[1],line[2])) if T == False: print("用户 33[32;1m%s 33[0m 无操作记录!" % UserID) #还款接口 def ATM_UserReimbursement(UserID): with open(BASE_DIR + 'ATM_Useropt.txt', 'a')as f: info = UserID + ' ' + '还款' + ' ' + time.strftime('%Y-%m-%d-%X') + ' ' 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("账户 33[32;1m%s 33[0m无需还款!"%UserID) return print("账户 33[32;1m%s 33[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) + ' ') 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("账户当前可用额度为: 33[32;1m%s 33[0m" % line[5]) if int(Count_Value) > int(line[5]): print("账户额度不足!") else: line[5] = str(int(line[5]) - int(Count_Value)) print("此次消费: 33[32;1m%s 33[0m,当前额度为: 33[32;1m%s 33[0m" % (Count_Value, line[5])) with open(BASE_DIR + 'ATM_UserCard.txt', 'w')as f: for line in UserInfo: f.write(' '.join(line) + ' ') 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) + ' ') 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("用户当前额度为: 33[32;1m%s 33[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)+' ') 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("账户当前状态为: 33[32;1m%s 33[0m" %('正常')) else: print("账户当前状态为: 33[32;1m%s 33[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)+' ') 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)+' ' 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) + ' ') 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) + ' ') 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("