9–12. 用户名和密码.
回顾练习 7-5 , 修改代码使之可以支持"上次登录时间". 请参阅 time 模块中的文档了解如
何记录用户上次登录的时间. 另外提供一个"系统管理员", 它可以导出所有用户的用户名, 密码
(如果想要的话,你可以把密码加密), 以及"上次登录时间".
a) 数据应该保存在磁盘中, 使用冒号( : ) 分割, 一次写入一行, 例如
"joe:boohoo:953176591.145", 文件中数据的行数应该等于你系统上的用户数.
b) 进一步改进你的程序, 不再一次写入一行, 而使用 pickle 模块保存整个数据对象. 请参
阅 pickle 模块的文档了解如何序列化/扁平化对象, 以及如何读写保存的对象. 一般来说, 这个
解决方案的代码行数要比 a) 的少.
c) 使用 shelve 模块替换 pickle 模块, 由于可以省去一些维护代码,这个解决方案的代码比
b) 的更少.
__author__ = 'nhchen'
import time,string,os,shelve
dbfile=shelve.open('db.sheve')
#dbfile['superadmin']={'name':'suppername','pwd':323859219,'lasttime':0}
dbfile.close()
nowtime=time.time() # get time vlaue
def gettime(nowtime):
#change time 'example 1357635049.372' to be '%Y/%m/%d %H:%M:%S'
return time.strftime('%Y/%m/%d %H:%M:%S',time.localtime(nowtime))
#db = {'superadmin':[323859219,0]} ##{name:[pwd,time]} superadmin:861116
def newuser():
#create user
dbfile=shelve.open('db.sheve')
keys=[key for key in dbfile]
dbfile.close()
prompt = 'login desired: '
while True:
name1 = raw_input(prompt)
name=name1.lower() ##set lower
if name in keys:
prompt = 'name taken, try another: '
continue
elif len(set(name) - set(string.letters+string.digits))>0:
prompt = 'has wrong letter: '
continue
else:
break
pwd = raw_input('passwd: ')
dbfile=shelve.open('db.sheve')
dbfile[name] = {'name':name,'pwd':abs(hash(pwd)),'lasttime':0}
dbfile.close()
def olduser():
#user login
dbfile=shelve.open('db.sheve')
keys=[key for key in dbfile]
dbfile.close()
nowtime=time.time()
name1 = raw_input('login: ')
name=name1.lower()
if name not in keys: #when name not in db
choose=raw_input("will you create a new user(Y/N):")
if choose.lower()=='y': # create new user
if len(set(name) - set(string.letters+string.digits))>0:
print 'has wrong letter,goto create to newuser'
newuser()
pwd = raw_input('passwd: ')
dbfile=shelve.open('db.sheve')
dbfile[name] = {'name':name,'pwd':abs(hash(pwd)),'lasttime':0}
dbfile.close()
else:
pass
showmenu()
else:
pass
dbfile=shelve.open('db.sheve')
pwd = raw_input('passwd: ')
name2=dbfile[name]
passwd = name2['pwd']
if passwd == abs(hash(pwd)):
if name2['lasttime']==0:
print 'welcome back', name,'your first time loggin'
else:
print 'welcome back', name
if nowtime-name2['pwd']<=14400: ##14400s=4hours,the time from lastlogin to now
print 'you already logged at time',gettime(name2['lasttime'])
name2['lasttime']=nowtime # set the time of this login
dbfile[name]=name2
dbfile.close()
if name=='superadmin':
choose=raw_input('you can output the name:')
if choose.strip()[0].lower()=='y':
file=open('name_information.txt','w')
for i in keys():
file.write('%s\t%i\t%f\n'%(i,dbfile[i]['pwd'],dbfile[i]['lasttime']))
file.close()
else:
print 'login incorrect'
def showuser():
#show all users
dbfile=shelve.open('db.sheve')
for key in dbfile:
print key,dbfile[key]
dbfile.close()
def deluser():
# delete a user
dbfile=shelve.open('db.sheve')
name1=raw_input('delete user:')
name=name1.lower()
del dbfile[name]
dbfile.close()
def showmenu():
prompt = """
(N)ew User Login
(E)xisting User Login
(Q)uit
(S)how all users
(D)elete user
Enter choice: """
done = 0
while not done:
chosen = 0
while not chosen:
try:
choice = raw_input(prompt)[0]
except (EOFError, KeyboardInterrupt):
choice = 'q'
print '\nYou picked: [%s]' % choice
if choice not in 'neqsd':
print 'invalid menu option, try again'
else:
chosen = 1
if choice == 'q': done = 1
if choice == 'n': newuser()
if choice == 'e': olduser()
if choice == 's': showuser()
if choice == 'd': deluser()
if __name__ == '__main__':
showmenu()