周末作业——小说阅读程序

倖福魔咒の 提交于 2020-03-27 23:38:54
'''
需求:
# 编写小说阅读程序实现下属功能
# 一:程序运行开始时显示
#    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()
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!