需求
模擬實現一個ATM + 購物商城程序
額度 15000或自定義
實現購物商城,買東西加入 購物車,調用信用卡接口結賬
支持多賬戶登錄
支持賬戶間轉賬
記錄每月日常消費流水
提供還款接口
ATM記錄操作日誌
提供管理接口,包括添加賬戶、用戶額度,凍結賬戶等。。。
用戶認證用裝飾器
測試信息
ATM.py 主腳本
以下文件需提前創建
db.txt 用戶名密碼認證文件
{'admin': '000','lyndon': '123', 'egon': '456', 'alex': '789'}
assest.txt 用戶資產信息 #用戶初始額度爲15000,admin管理員沒有資產記錄
{'lyndon': ['15000', '15000'], 'egon': ['15000', '15000'], 'alex': ['15000', '15000']}
frozen_user.txt 凍結賬戶文件
op.log admin操作記錄(添加用戶、凍結賬戶、調整額度)
flow.log 賬戶流水記錄(商城結算、信用卡還款、轉賬)
import os,time # 導入所使用的模塊
current_user={'user':None} # 全局字典控制二次認證免密碼登錄
def auth(func): # 認證函數
def wrapper(*args,**kwargs):
if current_user['user']: # 判斷是否已認證
return func(*args,**kwargs)
print('請輸入你要登錄的賬號')
name=input('input your name:').strip()
passwd=input('input your password:').strip()
with open('frozen_user.txt','r',encoding='utf-8') as f: # 判斷是否在凍結賬戶文件中
for i in f.readlines():
if name in i:
print('賬戶已凍結')
return op()
with open('db.txt','r',encoding='utf-8') as f_read: # 進行用戶名密碼認證
user_dic=eval(f_read.read())
if name == 'admin' and passwd == user_dic[name]: # 判斷是否爲admin用戶登錄
current_user['user'] = name
return admin()
if name in user_dic and passwd == user_dic[name]:
current_user['user'] = name
res=func(*args,**kwargs)
return res
else:
print('name or password error!')
exit()
return wrapper
@auth
def op(): #主菜單
print('''
【1】 購物商城
【2】 ATM管理
【3】 切換賬號
【4】 退出
''')
chooise=input('請輸入你的選擇:').strip()
if chooise == '1':
return shop()
elif chooise == '2':
return atm(current_user['user'])
elif chooise == '3':
current_user['user']=None # 選擇切換賬號時重置全局變量
return op()
elif chooise == '4':
exit()
else:
print('輸入錯誤,請重新輸入')
return op()
def atm(user): #ATM管理
if user == 'admin':
return admin()
else:
print('''
【1】 還款
【2】 轉賬
【3】 返回主菜單
''')
choice=input('請輸入你的選擇:').strip()
if choice == '1':
return repayment()
elif choice == '2':
return transfer()
elif choice == '3':
return op()
else:
print('輸入錯誤,重新輸入')
return atm(user)
def shop(): #購物商城
goods ={'電腦': 2000,'鼠標': 10,'遊艇': 20,'美女': 998}
goods_list =[]
moneys=0
tag=1
while tag == 1:
for key,value in goods.items():
print(key,value)
choice=input('請輸入要購買的商品名稱:').strip()
if choice not in goods:
print('商品不存在,請重新輸入')
continue
count = input('輸入購買數量: ').strip()
if count.isdigit():
goods_list.append((choice, goods[choice], int(count)))
money=int(goods[choice])*int(count)
moneys=moneys+money
print('當前購物車:%s' %goods_list)
while tag == 1:
choices=input('''
【1】 繼續購買
【2】 結算
【3】 退回主菜單
請選擇:''').strip()
if choices == '1':break
elif choices == '3':
op()
tag=0
elif choices == '2':
checkout(moneys,goods_list) #調用結算函數時傳入錢數和購物車商品
tag=0
else:
print('輸入錯誤')
continue
else:
print('輸入錯誤,請重新購買')
continue
def checkout(nums,goods): # 購物商城下結算
with open('assets.txt','r',encoding='utf-8') as f_read:
with open('assets.swap.txt','w+',encoding='utf-8') as f_write:
money_dic=eval(f_read.read())
money=money_dic[current_user['user']][0] # 判斷錢數與額度的大小,用戶資產使用字典嵌套
if int(nums) > int(money):
print('餘額不足,請重新購買')
goods=[]
shop()
money_dic[current_user['user']][0]=str(int(money) - int(nums))
s=str(money_dic)
f_write.writelines(s)
os.remove('assets.txt')
os.rename('assets.swap.txt', 'assets.txt')
print('購買成功,當前餘額爲:%s' %money_dic[current_user['user']][0])
start=time.strftime('%Y-%m-%d %H:%M:%S',time.localtime(time.time()))
with open('flow.log','a',encoding='utf-8') as f: # 寫入流水日誌
f.write('%s %s 購買物品 %s 支出%s,餘額%s\n' %(start,current_user['user'],goods,nums,money_dic[current_user['user']][0]))
return shop()
def repayment(): #信用卡管理下還款
with open ('assets.txt','r',encoding='utf-8') as f_read:
money_dic = eval(f_read.read())
money=money_dic[current_user['user']][0]
quot=money_dic[current_user['user']][1]
owe=(int(quot) - int(money))
if owe <= 0:
print('當前餘額爲 %s 不需要還款。' %money)
else:
print('當前賬單爲:%s' %owe)
re=input('輸入還款金額:').strip()
if re.isdigit() and len(money) != 0 :
with open('assets.swap.txt', 'w+', encoding='utf-8') as f_write:
money_dic[current_user['user']][0] = str(int(money) + int(re))
s = str(money_dic)
f_write.writelines(s)
print('還款成功,當前餘額爲:%s' %money_dic[current_user['user']][0])
start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
with open('flow.log', 'a', encoding='utf-8') as f:
f.write('%s %s 主動還款%s 餘額%s\n' % (start, current_user['user'], re, money_dic[current_user['user']][0]))
else:
print('輸入金額錯誤,請重新輸入')
repayment()
os.remove('assets.txt')
os.rename('assets.swap.txt', 'assets.txt')
def transfer(): #ATM管理下轉賬
with open ('assets.txt','r',encoding='utf-8') as f_read:
money_dic = eval(f_read.read())
money=money_dic[current_user['user']][0]
print('當前賬戶餘額爲:%s' %money)
other=input('轉入賬戶:').strip()
tran_money=input('轉入金額:').strip()
if other in money_dic and tran_money.isdigit() and len(tran_money) != 0:
with open('assets.swap.txt', 'w+', encoding='utf-8') as f_write:
money_dic[current_user['user']][0] = str(int(money) - int(tran_money))
other_money = money_dic[other][0]
money_dic[other][0] = str(int(other_money) + int(tran_money))
s = str(money_dic)
f_write.writelines(s)
os.remove('assets.txt')
os.rename('assets.swap.txt', 'assets.txt')
print('轉賬成功,當前餘額爲:%s' % money_dic[current_user['user']][0])
start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
with open('flow.log', 'a', encoding='utf-8') as f:
f.write('%s %s 向 %s 轉賬%s 餘額%s\n' % (start,current_user['user'],other,tran_money,money_dic[current_user['user']][0]))
else:
print('帳戶不存在、已凍結或輸入金額有誤')
transfer()
def admin(): #ATM管理下管理員操作
print('''
【1】 添加賬戶
【2】 調整額度
【3】 凍結賬戶
【4】 退出管理
''')
choice=input('請輸入你的選擇:').strip()
if choice == '1':
user_add()
elif choice == '2':
adjustment()
elif choice == '3':
frozen()
elif choice == '4':
current_user['user']=None
op()
else:
print('輸入錯誤,重新輸入:')
admin()
def user_add(): #admin管理接口下添加用戶
with open('db.txt', 'r', encoding='utf-8') as f_read:
user_dic = eval(f_read.read())
user_name=input('創建用戶名:').strip()
user_passwd=input('設置密碼:').strip()
passwd_ag=input('確認密碼:').strip()
if user_name not in user_dic and user_passwd == passwd_ag:
user_dic[user_name]=user_passwd
user_list=str(user_dic)
with open('db.txt','w',encoding='utf-8') as f:
f.write(user_list)
with open('assets.txt','r',encoding='utf-8') as f1:
with open('assets.swap.txt','w',encoding='utf-8') as f2:
money_dic = eval(f1.read())
money_dic[user_name]=['15000','15000'] #添加用戶時,設置初始額度爲15000
s=str(money_dic)
f2.write(s)
print('%s 用戶已添加' %user_name)
start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
with open('op.log', 'a', encoding='utf-8') as f3:
f3.write('%s %s 添加賬戶:%s 密碼:%s\n' % (start, current_user['user'], user_name,user_passwd))
else:
print('用戶名已存在或兩次輸入密碼不一致')
admin()
os.remove('assets.txt')
os.rename('assets.swap.txt', 'assets.txt')
admin()
def adjustment(): #admin管理接口下調整額度
with open ('assets.txt','r',encoding='utf-8') as f_read:
money_dic = eval(f_read.read())
adjust_user = input('請輸入需要調整的賬戶:').strip()
quot=money_dic[adjust_user][1]
if adjust_user not in money_dic:
print('用戶不存在')
return admin()
else:
print('%s 當前額度爲 %s' %(adjust_user,quot))
adjust_quot=input('調整爲:').strip()
if adjust_quot.isdigit() and len(adjust_user) != 0:
with open('assets.swap.txt', 'w+', encoding='utf-8') as f_write:
money_dic[adjust_user][0]=str(int(money_dic[adjust_user][0]) + int(adjust_quot) - int(quot))
money_dic[adjust_user][1] = adjust_quot
s=str(money_dic)
f_write.writelines(s)
print('%s 調整額度成功,當前額度爲:%s' %(adjust_user,money_dic[adjust_user][1]))
start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
with open('op.log', 'a', encoding='utf-8') as f:
f.write('%s %s 調整 %s 額度由%s ---> %s\n' % (start, current_user['user'], adjust_user,quot,money_dic[adjust_user][1]))
else:
print('輸入金額錯誤')
admin()
os.remove('assets.txt')
os.rename('assets.swap.txt', 'assets.txt')
admin()
def frozen(): # admin管理接口下凍結賬戶(已知bug爲如果輸入爲已凍結賬號會重新凍結)
frozen_name=input('請輸入你要凍結的賬戶名(admin無法凍結):').strip()
with open('db.txt','r',encoding='utf-8') as f_read:
user_dic = eval(f_read.read())
if frozen_name in user_dic and frozen_name != 'admin':
with open('frozen_user.txt','a',encoding='utf-8') as f_write:
print('%s 賬號已凍結' % frozen_name)
f_write.write('%s\n' % frozen_name)
start = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))
with open('op.log', 'a', encoding='utf-8') as f:
f.write('%s %s 凍結賬戶 %s\n' % (start,current_user['user'],frozen_name))
admin()
else:
print('賬戶不存在')
return frozen()
op()