"""
====================本周选做作业如下====================
编写小说阅读程序实现下属功能
# 一:程序运行开始时显示
0 账号注册
1 充值功能
2 阅读小说
# 二: 针对文件db.txt,内容格式为:"用户名:密码:金额",完成下述功能
2.1、账号注册
2.2、充值功能
# 三:文件story_class.txt存放类别与小说文件路径,如下,读出来后可用eval反解出字典
{"0":{"0":["倚天屠狗记.txt",3],"1":["沙雕英雄转.txt",10]},"1":{"0":["令人羞耻的爱.txt",6],"1":["二狗的妻子与大草原的故事.txt",5]},}
3.1、用户登录成功后显示如下内容,根据用户选择,显示对应品类的小说编号、小说名字、以及小说的价格
0 玄幻武侠
1 都市爱情
2 高效养猪36技
3.2、用户输入具体的小说编号,提示是否付费,用户输入y确定后,扣费并显示小说内容,如果余额不足则提示余额不足
# 四:为功能2.2、3.1、3.2编写认证功能装饰器,要求必须登录后才能执行操作
# 五:为功能2.2、3.2编写记录日志的装饰器,日志格式为:"时间 用户名 操作(充值or消费) 金额"
# 附加:
# 可以拓展作者模块,作者可以上传自己的作品
"""
import time,os
username=None
online_time = 0
log_money=None
def log(func):
import time
def wrapper(*args,**kwargs):
with open('log.txt','a',encoding='utf-8') as w:
res=func(*args,**kwargs)
print(func.__name__)
print(log_money)
w.write('{} {} {} 操作(充值or消费) {}\n'.format(time.strftime('%Y-%m-%d %X'),username,func.__name__,log_money))
return res
return wrapper
"""
#如果now_time -online_time 时间大于180s或者username为假 该条件都为假,执行该函数时第一次调用会有now_time 和 online_time ,
第二次调用时只要条件为假那不会重新online_time,但是now_time会重新执行,username时不变的,
然后在执行res=func(*args,**kwargs),所以执行func函数时无需在重新登录
但是每次调用装饰器装饰的函数时都会重新定义now_time()的时间,所以当 now_time - online_time >= 180 时,就会要求重新登录
"""
def sign(func):
"""登录装饰器"""
def wrapper(*args,**kwargs):
global username
global online_time
now_time = time.time()
if not (username and now_time - online_time <= 180):
with open('db.txt', 'r', encoding='utf-8') as r:
input_account = input('请输入账号:').strip()
input_password = input('请输入密码:').strip()
for i in r:
account,password = i.split(':')[0],i.split(':')[1]
if input_account == account and input_password == password:
username=input_account
# signin.append(input_account)
print('登录成功')
online_time=time.time()
break
else:
print('登录失败')
return
res=func(*args,**kwargs)
return res
return wrapper
def register():
"""注册功能"""
with open('db.txt','a+',encoding='utf-8') as f:
while True:
input_account=input('请输入账号:').strip()
input_password=input('请输入密码:').strip()
f.seek(0,0)
for i in f:
if input_account in i.split(':')[0]:
print('账号已存')
break
else:
f.write('%s:%s:0\n'%(input_account,input_password))
print('账号注册成功')
break
@log
@sign
def recharge():
"""充值功能"""
global log_money
import os
input_money = input('请输入充值金额:').strip()
with open('db.txt','r',encoding='utf-8') as f , open('.db.txt.swap','a',encoding='utf-8') as w:
# input_money=input('请输入充值金额:').strip()
for a in f:
account,money = a.split(':')[0],a.split(':')[2]
if account == username:
new_money = int(money) + int(input_money)
i=a.replace(a.split(':')[2],str(new_money))
w.write('%s\n'%i)
print('充值成功')
# global log_money
log_money=input_money
else:
w.write('%s'%a)
os.remove('db.txt')
os.rename('.db.txt.swap','db.txt')
# recharge()
@log
def paycharge(x):
"""扣款功能"""
global log_money
with open('db.txt', 'r', encoding='utf-8') as f, open('.db.txt.swap', 'a', encoding='utf-8') as w:
# input_money=input('请输入充值金额:').strip()
for a in f:
account, money = a.split(':')[0], a.split(':')[2]
if account == username and int(money) >= int(x):
new_money = int(money) - int(x)
i = a.replace(a.split(':')[2], str(new_money))
w.write('%s\n' % i)
print('扣款成功')
log_money=x
else:
w.write('%s' % a)
if account == username and int(money) < int(x):
print('余额不足')
os.remove('db.txt')
os.rename('.db.txt.swap', 'db.txt')
def story_class(x):
"""书名清单"""
with open('story_class.txt','r',encoding='utf-8') as r:
while True:
try:
for i in r:
i=eval(i)
print('编号', '书名', '价格')
for nu in i[x]:
# print('编号','书名','价格')
print(nu,i[x][nu][0],i[x][nu][1])
choice=input('请输入编号:')
yes_no=input('该书价格为{},请确认是狗购买,Y/N:'.format(i[x][choice][1])).strip()
if yes_no == 'Y':
paycharge(i[x][choice][1])
else:
break
except KeyError:
print('该类别暂无书籍')
break
@sign
def read():
"""阅读功能"""
print("""
0 玄幻武侠
1 都市爱情
2 高效养猪36技
""")
choice=input('请输入编号:').strip()
res=story_class(choice)
return res
menu={
'0':['退出',None],
'1':['充值功能',recharge],
'2':['阅读小说',read],
'3':['账号注册',register]
}
def novel():
"""主程序"""
while True:
for i in menu:
print(i,menu[i][0])
# print(type(username))
choice=input('请输入选项:').strip()
if not choice.isdigit():
print('请输入数字')
if choice == '0':
break
if choice in menu:
menu[choice][1]()
else:
print('请输入正确序号')
novel()