端午节大礼包(投票系统)

# ! /usr/bin/env python3.6
# -*- coding: utf-8 -*-
# 2018/6/15 18:28


'''
明星投票系统的相关功能.
功能需求:
    1,用户注册,将用户名和密码保存在文件中
    2,登陆功能.不需要三次登陆,正常反复死循环登陆,直到登陆成功为止
    3,用户登陆后可以查看所有明星信息,明星信息保存在明星文件中.
        例如:
            1 林俊杰 1
            2 周杰伦 0
            3 麻花疼 0
        第一位是序号,第二位是名字,第三位是票数
    4,给明星进行投票
    5,每个人每24小时只能投一次票(扩展功能,装饰器)
    思路:每次用户投票之后,都从文件中查询一下用户上一次的投票时间,让用户上一次投票时间和当前系统时间做差
    .如果大于24小时.则可以进行投票.,如果小于24小时则提示用户不能进行投票
'''
import time, os


lst = ['注册', '登陆', '查看明星', '明星投票', '退出系统']
dic = {'name': None}


def start_menu():
    '''明星菜单,显示明星姓名,序号,票数'''
    if not dic['name']:
        print('请先登录')
        return
    print(">>>>>以下是明星信息>>>>>")
    with open('start_info', 'r', encoding='utf-8') as f:
        for item in f:
            print(eval(item)['id'], eval(item)['name'])
    print(">>>>>>>>>>>>>>>>>>>>>>>>")


def menu():
    '''系统首页菜单'''
    print("欢迎进入明星投票系统:")
    for num, item in enumerate(lst):
        print(num + 1, item)


def re_wrapper(func):
    def inner(*args, **kwargs):
        '''注册函数的装饰器,每个用户注册成功之后会在user_vote_info中记录下初始状态,名字,state,time(时间戳)'''
        dic = {}
        dic1 = {}
        print("*"*5+"请注册你的账户"+"*"*5)
        while 1:
            user_naem = input('请输入您的用户名:')
            passwd = input("请输入密码:")
            passwd1 = input("请再次输入您的密码:")
            if passwd == passwd1:
                with open("user_info", 'a', encoding='utf-8') as f:
                    dic['name'] = user_naem
                    dic['passwd'] = passwd
                    f.write(str(dic)+'
')
                    ret = func()
                with open("user_vote_info", 'a', encoding='utf-8') as w:
                    dic1['name'] = user_naem
                    dic1['state'] = 0
                    dic1['time'] = None
                    w.write(str(dic1) + '
')
                    return ret
            else:
                print("密码不一致,请重新输入用户名密码")
    return inner


def lg_wrapper(func):
    def inner(*args, **kwargs):
        '''登陆装饰器,循环登陆知道登陆成功,改进:循环文件查看是否用户名已经被注册'''
        print("*"*5+"欢迎登陆投票系统"+"*"*5)
        while 1:
            user_name = input('请输入用户名:').strip()
            passwd = input("请输入密码:").strip()
            with open("user_info", 'r', encoding='utf-8') as f:
                for line in f:
                    if eval(line.strip())['name'] == user_name and eval(line.strip())['passwd'] == passwd:
                        ret = func(*args, **kwargs)
                        dic['name'] = user_name
                        return ret
                else:
                    print('登陆失败')

    return inner


def vote_wrapper(func):
    def inner(*args, **kwargs):
        '''投票装饰器,判断是否经过了24小时,只有经过了24小时才能投票,利用user_vote_info文件中的time(时间戳)进行计算'''
        if not dic['name']:
            return
        current = time.time()
        f = open("user_vote_info", 'r', encoding='utf-8')
        for item in f:
            dic5 = eval(item)
            if dic5['name'] == dic['name']:
                '''判断状态'''
                if dic5['state'] == 0:
                    f.close()
                    ret = func(*args, **kwargs)
                    print("*"*5+"恭喜您投票成功"+"*"*5)
                    return ret
                else:
                    if current - dic5['time'] >= 86400:
                        f.close()
                        ret = func(*args, **kwargs)
                        print("*" * 5 + "恭喜您投票成功" + "*" * 5)
                        return ret
                    else:
                        print("不符合投票条件,请耐心等待")
            else:
                pass
    return inner


@re_wrapper
def register():
    print("*"*5+"恭喜您注册成功!!!"+"*"*5)


@lg_wrapper
def login():
    print("*"*5+'恭喜您登陆成功!!!'+"*"*5)


def look_start():
    '''展示投票的具体信息'''
    if not dic['name']:
        print('请先登录')
        return
    print(">>>>>一下是实时得票情况>>>>>")
    with open('start_info', 'r', encoding='utf-8') as f:
        for item in f:
            print(eval(item)['id'], eval(item)["name"], eval(item)['content'])
    print(">>>>>>>>>>>>>>>>>>>>>>>>>>>>")


@vote_wrapper
def vote():
    '''实现投票计数功能'''
    if not dic['name']:
        return
    global vote_start
    user_section = input("请选择您选择投票明星的序号:")
    with open('start_info', 'r', encoding='utf-8') as f,
            open("start_info_1", 'w', encoding='utf-8') as w:
        for item in f:
            dic1 = eval(item.strip())
            if user_section == str(dic1['id']):
                dic1['content'] = dic1['content'] + 1
                # print(dic)
                w.write(str(dic1)+"
")
                with open('user_vote_info', 'r', encoding='utf-8') as we,
                    open('user_vote_info_1', 'w', encoding='utf-8') as w1:
                    for el in we:
                        dic2 = eval(el)
                        if dic2['name'] == dic['name']:
                            start = time.time()
                            dic2['time'] = start
                            dic2['state'] = 1
                            w1.write(str(dic2) + '
')
                        else:
                            w1.write(el)
                os.remove('user_vote_info')
                os.rename("user_vote_info_1", "user_vote_info")
            else:
                w.write(item)
    os.remove("start_info")
    os.rename("start_info_1", "start_info")
    # print('这里是投票功能')


if __name__ == '__main__':
    menu()
    while 1:
        user_input = input("请输入您的选择:")
        if user_input.isdigit() and int(user_input) >= 1 and int(user_input) <= 5:
            if user_input.strip() == '1':
                register()
            elif user_input.strip() == '2':
                login()
            elif user_input.strip() == '3':
                look_start()
            elif user_input.strip() == '4':
                start_menu()
                vote()
            else:
                break
        else:
            print("请输入正确的序号")
View Code

使用到的文件有(start_info),(user_vote_info),(user_info)

以下修改上述代码的一些细节问题:

主要修改内容为:投票的函数的装饰器.将被装饰的目标函数与装饰器的逻辑区分开,不要将目标函数写到装饰器的逻辑之外!!!

def vote_wrapper(func):
    def inner(*args, **kwargs):
        '''投票装饰器,判断是否经过了24小时,只有经过了24小时才能投票,利用user_vote_info文件中的time(时间戳)进行计算'''
        if not dic['name']:
            return
        current = time.time()
        f = open("user_vote_info", 'r', encoding='utf-8')
        for item in f:
            dic5 = eval(item)
            if dic5['name'] == dic['name']:
                if dic5['state'] != 0 and current - dic5['time'] < 86400: # 不执行投票的结果有1,state=1(!=0)并且时间小于24小时.
                    print('24小时之内不能重复投票')
                    return
                else:
                    break
        f.close()
        ret = func(*args, **kwargs)  # 执行投票的结果有1,state=0,2,state=1,时间大于86400
        return ret
    return inne

 ***修改之后的代码***

原文地址:https://www.cnblogs.com/chenrun/p/9190990.html