# ! /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("请输入正确的序号")
使用到的文件有(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
***修改之后的代码***