ATM 最初版

# 二 一个项目开发前,有一份开发文档
#
#     项目: 编写小说阅读程序实现下属功能
#
#         # 一:程序运行开始时显示
#             0 账号注册
#             1 账号登录
#             2 充值功能
#             3 阅读小说
import os,sys

ATM_PATH = os.path.dirname(__file__)
DB_PATH = os.path.join(ATM_PATH,'db.txt')
LOG_PATH = os.path.join(ATM_PATH,'log.txt')
DIR_PATH = os.path.join(ATM_PATH,'story_class.txt')


def check(user):
    with open(DB_PATH,'r',encoding='utf-8') as f:
        for line in f:
            users = line.strip().split(':')
            if user == users[0]:
                return True
        else:
            return False


def log_in():
    global user_in
    global login
    while True:
        user = input('请输入账号:').strip()
        with open(DB_PATH,'r',encoding='utf-8') as f:
            pwd = input('请输入密码:').strip()
            for line in f:
                users = line.strip().split(':')
                if user == users[0] and pwd == users[1]:
                    print('登录成功')
                    user_in = user
                    login = True
                    return True
            else:
                print('登录失败,请重新登录')


def register():
    while True:
        user = input('请输入账号:').strip()
        if user:
            if not check(user):
                pwd = input('请输入密码:').strip()
                if pwd:
                    pwd2 = input('请确认密码:').strip()
                    if pwd == pwd2:
                        with open(DB_PATH,'a',encoding='utf-8') as f:
                            f.write('{}:{}:{}
'.format(user,pwd,0))
                            print('注册成功')
                    else:
                        print('密码不一致')
                else:
                    print('密码不能为空哦')
            else:
                print('账号已存在')
        else:
            print('账号不能为空哦')


def log_money(func):
    def wrapper(*args,**kwargs):
        func(*args,**kwargs)
        with open(LOG_PATH,'a',encoding='utf-8') as f:
            import time
            time1 = time.strftime('%Y-%m-%d %X')
            if func.__name__ == 'money_in':
                f.write('{} {} 充值 {}元
'.format(time1,user_in,money))
            if func.__name__ == 'money_out':
                f.write('{} {} 消费 {}元
'.format(time1,user_in,money))
    return wrapper


def log_in_check(func):
    def wrapper(*args,**kwargs):
        if login:
            func(*args,**kwargs)
            return True
        else:
            print('请登录后再操作')
            return False
    return wrapper


@log_money
@log_in_check
def money_in():
    while True:
        money = input('充值多少:').strip()
        if money.isdigit():
            money = int(money)
            NEW_PATH = os.path.join(ATM_PATH,'.db.txt.swap')
            with open(DB_PATH,'r',encoding='utf-8') as f,
                open(NEW_PATH,'w',encoding='utf-8') as f1:
                for line in f:
                    users = line.strip().split(':')
                    if user_in == users[0]:
                        users[2] = int(users[2]) + money
                    f1.write('{}:{}:{}
'.format(users[0],users[1],users[2]))
                print('充值成功,金额为:{}'.format(money))
            os.remove(DB_PATH)
            os.rename(NEW_PATH,DB_PATH)
            break
        else:
            print('请输入整数数字')


@log_money
def money_out(money):
    while True:
        money = int(money)
        NEW_PATH = os.path.join(ATM_PATH, '.db.txt.swap')
        with open(DB_PATH, 'r', encoding='utf-8') as f, 
                open(NEW_PATH, 'w', encoding='utf-8') as f1:
            for line in f:
                users = line.strip().split(':')
                if user_in == users[0]:
                    users[2] = int(users[2]) - money
                f1.write('{}:{}:{}
'.format(users[0], users[1], users[2]))
            print('购买成功,金额为:{}'.format(money))
        os.remove(DB_PATH)
        os.rename(NEW_PATH, DB_PATH)
        break

@log_in_check
def read_book():
    with open(DIR_PATH,'r',encoding='utf-8') as f1:
        dir = eval(f1.read())
    while True:
        print("""==========================
        0  玄幻武侠
        1  都市爱情
        2  高效养猪36技
        10 上传的小说
==========================""")
        choice = input('请输入编号:').strip()
        if choice.isdigit():
            if choice in dir:
                dir1 =dir[choice]
                for i in dir1:
                    print('{} {} 价格:{}'.format(i,dir1[i][0],dir1[i][1]))
                choice2 = input('请输入编号:').strip()
                if choice2.isdigit():
                    if choice2 in dir[choice]:
                        dir2 = dir1[choice2]
                        shop = input('是否购买 {} ,价格: {},y确认:'.format(dir2[0],dir2[1]))
                        if shop.lower() == 'y':
                            global money
                            money = dir2[1]
                            money_out(money)
                            book = dir2[0]
                            RD_PATH = os.path.join(ATM_PATH, 'fictions', book)
                            with open(RD_PATH,'r',encoding='utf-8') as f:
                                book_data = f.read()
                                print('''* * * * * * * * * * * * * * * * * * *
{0}
* * * * * * * * * * * * * * * * * * *'''.format(book_data))
                            input()
                            break
                        else:
                            break
                    else:
                        print('没有这个书哦')
                else:
                    print('请输入整数数字')
            else:
                print('还没有这个书哦')
        else:
            print('请输入整数数字')


@log_in_check
def book_up():
    while True:
        path_book = input('请输入所要上传的书籍路径:').strip()
        if os.path.exists(path_book):
            name = os.path.basename(r'{}'.format(path_book))
            print(name)
            UP_PATH = os.path.join(ATM_PATH, 'fictions', name)
            print(UP_PATH)
            if os.path.exists(UP_PATH):
                up_choice = input('文件已存在,是否覆盖:y/n:::').strip()
                if up_choice.lower() != 'y':
                    continue
            with open(path_book,'rb') as f,
                    open(r'{}'.format(UP_PATH),'wb') as f1:
                print('正在上传 ...')
                f1.write(f.read())
                print('上传完成')
            with open(DIR_PATH,'r',encoding='utf-8') as f,
                    open('book_up.txt','w',encoding='utf-8') as f1:
                d = eval(f.read().strip())
                d['10'][str(len(d['10']))] = [name,0]
                print(d['10'])
                f1.write(str(d))
            os.remove(DIR_PATH)
            os.rename('book_up.txt',DIR_PATH)
            break
        else:
            print('路径不存在,请重新输入')


if __name__ == '__main__':
    func_dic = {'0':['账号注册',register],
                '1':['账号登录',log_in],
                '2':['充值功能',money_in],
                '3':['阅读小说',read_book],
                '4':['上传小说',book_up],
                '5':['退出',exit],
                }

    user_in = None
    login =False
    while True:
        print('===========================')
        for i in range(len(func_dic)):
            print('{} {}'.format(i,func_dic[str(i)][0]))
        print('---------------------------')
        choice = input('请输入命令编号:').strip()
        if choice == 'q':
            break
        if choice in func_dic:
            func_dic[choice][1]()
        else:
            print('没有这个编号')
            continue


#         # 三:文件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消费) 金额"
#
#
#         # 附加:
#         # 可以拓展作者模块,作者可以上传自己的作品

原文地址:https://www.cnblogs.com/pythonwl/p/12589133.html