''' 需求: # 编写小说阅读程序实现下属功能 # 一:程序运行开始时显示 # 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消费) 金额" # 附加: # 可以拓展作者模块,作者可以上传自己的作品 ''' ''' 项目目录 小说阅读程序 book_list 二狗的妻子与大草原的故事.txt 令人羞耻的爱.txt 倚天屠狗记.txt 沙雕英雄转.txt 高效养猪36技(01).txt 高效养猪36技(02).txt 高效养猪36技(03).txt 高效养猪36技(04).txt access.log auther.py db.txt story_class.txt 小说阅读程序.py '''
- auther.py (作者模块,可上传小说)
import os def upload(story_dic): src = input(r'上传的小说路径:').strip() price = input('小说价格(元):').strip() if not os.path.exists(src): return print('上传失败,小说路径错误') with open(r'story_class.txt.swap', 'wt', encoding='utf-8') as w: # print(story_dic) book_name = src.split('\\')[-1] new_book_list = [book_name, int(price)] k = len(story_dic['2']) story_dic['2'][str(k)] = new_book_list w.write(f'{story_dic}') print('上传成功') # upload()
- 小说阅读程序.py
import os import time import auther login_user = None class_dic = {} # 判断用户是否存在 def is_user(inp_user): if not os.path.exists(r'db.txt'): return False with open('db.txt','rt', encoding='utf-8') as f: for is_user in f: user, *_ = is_user.strip().split(':') if inp_user == user: return True else: return False # 登录认证的装饰器 def is_login(func): def wrapper(): global login_user if login_user: func() else: res = login() return func() if res else print('用户名不存在') return wrapper def login(): global login_user while True: inp_name = input('用户名:').strip() inp_pwd = input('密码:').strip() if not is_user(inp_name): return False with open(r'db.txt', 'rt', encoding='utf-8') as f: for line in f: user, pwd, *_ = line.strip().split(':') if inp_name == user and inp_pwd == pwd: login_user = inp_name print('欢迎,【%s】' % login_user) return True else: print('密码错误') def register(): while True: inp_user = input('请输入用户名:').strip() inp_pwd = input('请输入密码:').strip() inp_pwd2 = input('请确认密码:').strip() first_money = 0 if inp_pwd != inp_pwd2: print('两次密码不一致') continue if inp_user and inp_pwd and inp_pwd2: if is_user(inp_user): print("用户名已存在") continue else: with open(r'db.txt', 'at', encoding='utf-8') as f: f.write('{}:{}:{}\n'.format(inp_user, inp_pwd, first_money)) return print("注册成功") else: print("输入不能为空") # 记录消费充值日志的装饰器 def access_log(modle): def inner(func): def wrapper(*args, **kwargs): with open(r'access.log', 'at', encoding='utf-8') as log: global login_user if modle == 'recharge': start_time = time.strftime('%Y-%m-%d %X') money = func(*args, **kwargs) if money is not None: log.write(f'{start_time} {login_user} 充值 {money}元\n') elif modle == 'story': start_time = time.strftime('%Y-%m-%d %X') money = func(*args, **kwargs) if money == 302: # print('阅读失败,用户取消支付') return 302 elif money == 303: # print("阅读失败,余额不足") return 303 else: log.write(f'{start_time} {login_user} 消费 {money}元\n') return 200 return wrapper return inner @is_login @access_log(modle='recharge') def recharge(): inp_user = input("请输入用户名:").strip() inp_money = input("请输入充值金额:").strip() # 判断用户是否存在 if not is_user(inp_user): return print("用户名不存在") # 开始执行充值 with open(r'db.txt', 'rt', encoding='utf-8') as r,\ open(r'db.txt.swap', 'wt', encoding='utf-8') as w: for line in r: user, pwd, money = line.strip().split(':') if inp_user == user and pwd and money: new_money = int(money) + int(inp_money) w.write('{}:{}:{}\n'.format(inp_user, pwd, new_money)) else: w.write('{}:{}:{}\n'.format(user, pwd, money)) os.remove('db.txt') os.rename('db.txt.swap', 'db.txt') print('充值成功') return inp_money @is_login def read_story(): func_story = ''' 0 玄幻武侠 1 都市爱情 2 高效养猪36技 3 上传小说 ''' # 将图书信息字典设为全局并在局部调用全局 global class_dic if not os.path.exists('story_class.txt'): print("暂无小说") return 404 print(func_story) with open(r'story_class.txt', 'rt', encoding='utf-8') as f: # 将文件中字典格式的图书信息字符串转换成图书信息字典赋给全局的class_dic class_dic = eval(f.read()) inp_num = input('请输入小说类别编号:').strip() # 作者模块上传小说 if inp_num == '3': auther.upload(class_dic) elif inp_num in class_dic: print('编号 书名 价格'.center(6, ' ')) # 打印编号 书名 价格 for story_dic in class_dic[inp_num]: print(f'{story_dic} ' f'《{class_dic[inp_num][story_dic][0].replace(".txt", "")}》 ' f' {class_dic[inp_num][story_dic][1]}元'.center(8, ' ')) story_num = input("请输入小说编号:").strip() if story_num in class_dic[inp_num]: # 是否阅读 res = is_read(class_dic[inp_num][story_num]) if res == 200: # inp_num:小说类别编号 story_num:小说编号 open_story(class_dic[inp_num][story_num][0]) return 200 elif res == 303: print('阅读失败,余额不足') return 303 elif res == 302: print('阅读失败,用户取消支付') return 302 else: print('小说不存在') return 404 else: print('不存在的编号') return 404 if os.path.exists('story_class.txt.swap'): os.remove('story_class.txt') os.rename('story_class.txt.swap', 'story_class.txt') # 载入小说 def open_story(src): print("小说加载中。。。\n") time.sleep(1) with open(r'book_list\%s' % src, 'rt', encoding='utf-8') as book: story = book.read() print(story) time.sleep(4) print("小说加载完毕\n") time.sleep(5) # 付费阅读操作 @access_log(modle='story') def is_read(story_info): global login_user book_money = int(story_info[1]) inp = input('是否付费?(y/n):').strip() if inp in ['y', 'Y', 'n', 'N']: if inp.lower() == 'y': # 开始付费操作 with open(r'db.txt', 'rt', encoding='utf-8') as r, \ open(r'db.txt.swap', 'wt', encoding='utf-8') as w: for line in r: user, pwd, money = line.strip().split(':') if login_user == user and pwd and money: money = int(money) # 余额不足返回303状态码 if book_money > money: return 303 else: new_money = money - book_money w.write(f'{login_user}:{pwd}:{new_money}\n') else: w.write(f'{user}:{pwd}:{money}\n') os.remove('db.txt') os.rename('db.txt.swap', 'db.txt') # 返回图书价格 return book_money else: # 用户取消支付返回302状态码 return 302 else: is_read(story_info) def main(): func_dic = { '0': ('账号注册', register), '1': ('充值功能', recharge), '2': ('阅读小说', read_story) } while True: print('Umi小说阅读程序') for index in func_dic: print('{} {}'.format(index, func_dic[index][0]).center(9, ' ')) cmd = input("请输入功能编号:").strip() if cmd not in func_dic: print("必须输入指定功能编号.") else: func_dic[cmd][1]() if __name__ == '__main__': main()
来源:https://www.cnblogs.com/guanxiying/p/12584590.html