需求
模拟实现一个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()