7-4. 建立字典。
给定两个长度相同的列表,比如说,列表[1, 2, 3,...]和['abc', 'def','ghi',...],用这两个列表里的所有数据组成一个字典,像这样:{1:'abc', 2: 'def', 3: 'ghi',...}
1 listdict = dict(zip([1,2,3], ['abc','def','ghi'])) 2 print(listdict)
7–5. userpw2.py.
下面的问题和例题7.1 中管理名字-密码的键值对数据的程序有关。
(a)修改那个脚本,使它能记录用户上次的登录日期和时间(用time 模块),并与用户密码一起保存起来。程序的界面有要求用户输入用户名和密码的提示。无论户名是否成功登录,都应有提示,在户名成功登录后,应更新相应用户的上次登录时间戳。如果本次登录与上次登录在时间上相差不超过4 个小时,则通知该用户: “You already logged in at: <last_ login_timestamp>.”
(b) 添加一个“管理”菜单,其中有以下两项:(1)删除一个用户 (2)显示系统中所有用户的名字和他们的密码的清单。
(c) 口令目前没有加密。请添加一段对口令加密的代码(请参考crypt, rotor, 或其它加密模块)
(d) 为程序添加图形界面,例如,用Tkinter 写。
(e) 要求用户名不区分大小写。
(f) 加强对用户名的限制,不允许符号和空白符。
(g)合并“新用户”和“老用户”两个选项。如果一个新用户试图用一个不存在的用户名登录,
询问该用户是否是新用户,如果回答是肯定的,就创建该帐户。否则,按照老用户的方式登录。
1 import time 2 import hashlib 3 from datetime import datetime 4 5 db = {} 6 7 def newuser(): 8 """注册""" 9 value = [] 10 prompt = 'login desired: ' 11 while True: 12 name = input(prompt).lower() 13 if not name.isalnum() and '' in name: 14 print('name format error') 15 continue 16 else: 17 if name in db: 18 prompt = 'name taken, try another: ' 19 continue 20 else: 21 break 22 pwd = input('login password desired:') 23 m = hashlib.md5() 24 m.update(pwd.encode(encoding='utf-8')) 25 value.append(m.hexdigest()) 26 value.append(datetime.now()) 27 value.append(time.time()) 28 db[name] = value 29 print('new user is %s, register time is %s' % (name, db[name][1])) 30 31 def olduser(): 32 """登录""" 33 name = input('Username:').lower() 34 pwd = input('Password:') 35 m = hashlib.md5() 36 m.update(pwd.encode(encoding='utf-8')) 37 passwd = db.get(name) 38 if passwd[0] == m.hexdigest(): 39 newtimestamp = time.time() 40 newtime = datetime.now() 41 if newtimestamp - db[name][2] < 14400: 42 print('You already logged in at %s:' % db[name][1]) 43 else: 44 passwd[1] = newtime 45 print('Welcome back %s, login time is %s' % (name, passwd[1])) 46 else: 47 print('Login incorrect') 48 49 50 def deluser(): 51 """删除""" 52 print(db) 53 name = input('Input a user name to remove:').lower() 54 if name in db: 55 db.pop(name) 56 print("Done") 57 else: 58 print('Input error') 59 60 def getuserpwd(): 61 """查询""" 62 while True: 63 name = input('login name desired:').lower() 64 if not name.isalnum() and '' in name: 65 print('name format error') 66 continue 67 else: 68 if name not in db: 69 print('User name is not in db') 70 answer = input('register a new user? y/n').lower() 71 if 'y' == answer: 72 newuser() 73 break 74 elif 'n' == answer: 75 break 76 else: 77 print('user name is already in db') 78 olduser() 79 break 80 81 def removeuser(): 82 """删除""" 83 print(db) 84 name = input('Input a user name to remove:').lower() 85 if name in db: 86 db.pop(name) 87 else: 88 print('Input error') 89 90 def getuser(): 91 """查询""" 92 while True: 93 name = input('login name desired:').lower() 94 if not name.isalnum() and '' in name: 95 print('name format error') 96 continue 97 else: 98 if name not in db: 99 print('User name is not in db') 100 answer = input('register a new user? y/n').lower() 101 if 'y' == answer: 102 newuser() 103 break 104 elif 'n' == answer: 105 break 106 else: 107 print('user name is already in db') 108 olduser() 109 break 110 111 def showmenu(): 112 """总菜单""" 113 prompt = """ 114 (N)ew User Login 115 (E)xisting User Login 116 (G)et user 117 (R)emove a existing user 118 (Q)uit 119 120 Enter choice: """ 121 122 done = False 123 while not done: 124 125 chosen = False 126 while not chosen: 127 try: 128 choice = input(prompt).strip()[0].lower() 129 except (EOFError, KeyboardInterrupt): 130 choice = 'q' 131 print('\nYou picked: [%s]' % choice) 132 if choice not in 'negrq': 133 print('invalid option, try again') 134 135 else: 136 chosen = True 137 138 if choice == 'q': done = True 139 if choice == 'n': newuser() 140 if choice == 'e': olduser() 141 if choice == 'g': getuser() 142 if choice == 'r': removeuser() 143 144 145 if __name__ == '__main__': 146 showmenu()
7-7. 颠倒字典中的键和值。用一个字典做输入,输出另一个字典,用前者的键做值,前者的值做键。
1 dict_sort = {1: 'a', 2: 'b'} 2 dictreverse = {} 3 for key, value in dict_sort.items(): 4 dictreverse[value] = key 5 print(dictreverse)
7-8. 人力资源。
创建一个简单的雇员姓名和编号的程序。让用户输入一组雇员姓名和编号。你的程序可以提供按照姓名排序输出的功能,雇员姓名显示在前面,后面是对应的雇员编号。附加题:添加一项功能,按照雇员编号的顺序输出数据。
1 name_number = {} 2 while True: 3 name = input("输入姓名:") 4 number = input("输入编号:") 5 6 name_number[name] = number 7 for name, number in name_number.items(): 8 print(name, ':', number) 9 print(number, ':', name)
7–13. 随机数。
修改练习5-17 的代码:使用random 模块中的randint()或randrange()方法生成一个随机数集合:从0 到9(包括9)中随机选择,生成1 到10 个随机数。这些数字组成集合A(A 可以是可变集合,也可以不是)。同理,按此方法生成集合B。每次新生成集合A 和B 后,显示结果 A | B 和 A & B
7-14. 用户验证。修改前面的练习,要求用户输入A|B和A&B的结果,并告诉用户的答案是否正确,而不是将A|B和A&B的结果直接显示出来。如果用户回答错误,允许他修改解决方案,然后重新验证用户输入的答案。如果用户三次提交的答案均不正确,程序将显示正确结果。附加题:运用你关于集合的知识,创建某个集合的潜在子集,并询问用户此潜在子集是否真是该集合的子集,要求和主程序一样有显示更正和答案的功能。
1 import random 2 A = [] 3 B = [] 4 for i in range(random.randint(1,11)): 5 A.append(random.randint(0, 9)) 6 B.append(random.randint(0, 9)) 7 print('A:', set(A)) 8 print('B:', set(B)) 9 C = set(A) | set(B) 10 D = set(A) & set(B) 11 12 i = 0 13 while i <= 3: 14 15 union = set(input('Union: ')) 16 intersection = set(input('Intersection: ')) 17 if union == C: 18 print('回答正确') 19 if intersection == D: 20 print('回答正确') 21 else: 22 print('回答错误') 23 i += 1