7.22 今日作业:
1、 编写日志装饰器,实现功能如:一旦函数f1执行,则将消息2017-07-21 11:12:11 f1 run写入到日志文件中,日志文件路径可以指定
import time
from functools import wraps
def log(file_path):
def outer(func):
@wraps(func)
def wrapper(*args, **kwargs):
with open(f"{file_path}", mode='a', encoding='utf-8') as f:
f.write(f"{time.strftime('%Y-%m-%d %X')} {func.__name__} run\n")
res = func(*args, **kwargs)
return res
return wrapper
return outer
2、基于迭代器的方式,用while循环迭代取值字符串、列表、元组、字典、集合、文件对象
字符串:
msg = 'hello world'
res = msg.__iter__()
while True:
try:
print(next(res))
except StopIteration:
break
列表:
l1 = [1, 2, 3, 4, 5, 6]
res1 = l1.__iter__()
while True:
try:
print(next(res1))
except StopIteration:
break
元组:
t = (111, 222, 333)
res2 = t.__iter__()
while True:
try:
print(next(res2))
except StopIteration:
break
字典:
dic = {'k1': 111, 'k2': 222, 'k3': 333}
res3 = dic.__iter__()
while True:
try:
print(next(res3))
except StopIteration:
break
集合:
ss = {111, 222, 333}
res4 = ss.__iter__()
while True:
try:
print(next(res4))
except StopIteration:
break
文件对象:
with open('a.txt', mode='r', encoding='utf-8') as f:
while True:
try:
print(next(f))
except StopIteration:
break
3、自定义迭代器实现range功能
def diy_range(start_num, end_num, step=1):
while start_num < end_num:
yield start_num
start_num += step
==================== 本周选做作业如下 ====================
编写小说阅读程序实现下属功能
一:程序运行开始时显示
0 账号注册
1 登录功能
2 充值功能
3 阅读小说
二:完成下述功能
2.1、账号注册
- 针对文件db.txt,内容格式为:“用户名:密码:金额” 完成注册功能
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 os
import time
change_money = 0
db_dic = {}
login_user = None
symbol = [] # 特殊字符列表
for num in range(32, 48):
symbol.append(chr(num))
for num in range(58, 65):
symbol.append(chr(num))
for num in range(91, 97):
symbol.append(chr(num))
for num in range(123, 127):
symbol.append(chr(num))
def deco1(func1): # 登录装饰器
def wrapper1(*args, **kwargs):
global login_user
with open('db.txt', mode='r', encoding='utf-8') as f: # 用户资料写进字典
for line in f:
name, pwd, money = line.strip('\n').split(':')
db_dic[name] = [pwd, int(money)]
flag = False
if login_user is None:
print('请先登录')
i = 0
while i < 3:
inp_name = input('请输入您的用户名:').strip()
if inp_name in db_dic:
inp_pwd = input('请输入您的密码:').strip()
if inp_pwd == db_dic[inp_name][0]:
print('登录成功!')
login_user = inp_name
flag = True
break
else:
print('登录失败!')
i += 1
else:
print('用户名不存在')
if flag or login_user:
res1 = func1(*args, **kwargs)
return res1
return wrapper1
def log(func2): # 日志装饰器
def wrapper2(*args, **kwargs):
res2 = func2(*args, **kwargs)
with open('access.log', mode='a', encoding='utf-8') as log_f:
# "时间 用户名 操作(充值or消费) 金额"
operation = ('充值了' if func2.__name__ == 'recharge' else '消费了')
log_f.write(f'{time.strftime("%Y-%m-%d %X")} {login_user} {operation} {change_money}元\n')
return res2
return wrapper2
def register(): # 注册功能
with open('db.txt', mode='r', encoding='utf-8') as f1:
for line in f1:
name, pwd, money = line.strip('\n').split(':')
db_dic[name] = [pwd, money]
while True:
inp_name = input("请注册您的用户名:").strip()
if inp_name in db_dic:
print('用户名已存在,请重新注册')
continue
else:
while True:
flag = False
inp_pwd = input('请注册您的密码').strip()
for item in inp_pwd:
if item in symbol:
print('密码不能含有特殊字符,请重新输入')
flag = True
break
else:
if len(inp_pwd) < 6:
flag = True
if flag:
continue
else:
re_pwd = input('请确认您的密码').strip()
if re_pwd != inp_pwd:
print('两次密码不一致,请重新输入')
continue
else:
print('注册成功!')
with open('db.txt', 'a', encoding='utf-8') as f2:
f2.write(f'{inp_name}:{inp_pwd}:{0}\n')
return
def login():
global login_user
with open('db.txt', mode='r', encoding='utf-8') as f: # 用户资料写进字典
for line in f:
name, pwd, money = line.strip('\n').split(':')
db_dic[name] = [pwd, int(money)]
i = 0
while i < 3:
inp_name = input('请输入您的用户名:').strip()
if inp_name in db_dic:
inp_pwd = input('请输入您的密码:').strip()
if inp_pwd == db_dic[inp_name][0]:
print('登录成功!')
login_user = inp_name
break
else:
print('登录失败!')
i += 1
else:
print('用户名不存在')
# 2.2、充值功能
@deco1
@log
def recharge():
while True:
recharge_flag = False
add_money = input('请充值:').strip()
if add_money.isdigit():
add_money = int(add_money)
if add_money > 0:
global change_money
change_money = add_money
db_dic[login_user][1] += add_money
recharge_flag = True
print(f"充值成功!账户余额为{db_dic[login_user][1]}元")
with open('.db.txt', 'w', encoding='utf-8') as w_f:
for k, v in db_dic.items():
v[1] = str(v[1])
w_f.write(f'{k}:{v[0]}:{v[1]}\n')
else:
print('你拿我开心呢?!!金额必须大于零,大于零,大于零!!!')
else:
print('输入的充值金额不能识别,请重新输入')
if recharge_flag:
os.remove('db.txt')
os.renames('.db.txt', 'db.txt')
return
@deco1
@log
def reading():
with open('story_class.txt', mode='r', encoding='utf-8') as f1:
dic = eval(f1.read())
print('''
0 玄幻武侠
1 都市爱情
2 高校养猪36技
''')
tag = False
cmd1 = input('请输入你喜欢的类型:').strip()
while True:
if cmd1 in ['0', '1', '2']:
dic1 = dic.get(cmd1)
for k, v in dic1.items():
print(f'编号:{k} 小说:{v[0]} 价格:{v[1]}元')
choice = input('请输入需要购买的小说编号:').strip()
while True:
if choice in dic1:
cmd2 = input('请确认是否购买(购买输y或者Y,不买输入n或者N,输入0退出):').strip()
if cmd2 == 'y' or cmd2 == 'Y':
price = int(dic1[choice][1])
if db_dic[login_user][1] >= price:
db_dic[login_user][1] -= price
tag = True
global change_money
change_money = price
with open('.db.txt', 'w', encoding='utf-8') as w_f:
for k, v in db_dic.items():
v[1] = str(v[1])
w_f.write(f'{k}:{v[0]}:{v[1]}\n')
os.remove('db.txt')
os.renames('.db.txt', 'db.txt')
break
elif cmd2 == 'n' or cmd2 == 'N':
continue
elif cmd2 == '0':
return
else:
print('请输入正确的指令')
else:
print('不能识别的指令')
else:
print('输入的编号不存在,请重新输入!')
continue
if tag:
with open(f'{dic[cmd1][choice][0]}', mode='r', encoding='utf-8') as f2:
res = f2.read()
print(res)
return
def shuqi():
while True:
print('''
0 账号注册
1 登录功能
2 充值功能
3 阅读小说
''')
b_cmd = input('请输入您的指令(输入q退出):').strip()
if b_cmd == 'q':
break
elif b_cmd == '0':
register()
elif b_cmd == '1':
login()
elif b_cmd == '2':
recharge()
elif b_cmd == '3':
reading()
shuqi()
**附加:
可以拓展作者模块,作者可以上传自己的作品