优秀作业:登录锁定和三层菜单程序展示之一
来自python12期的王松的优秀作业:
一、登录验证之readme说明:
提示:两个应用均基于python2.7写的,3.x版本会报错
blog: blog.csdn.net/songfreeman
本目录为第一天的作业,主要包括2个应用:
1: day1_2_loginauth.py
用户登陆验证程序:
主要功能:
1) 用户登陆
2) 登陆失败3次后锁定账户,并记录到文件
3) 登陆成功之后判断用户类型,根据用户类型显示不同菜单
4) 用户类型分为普通用户和管理员权限用户
普通用户权限功能:
a: 搜索用户
b: 修改密码
管理员用户权限功能:
a: 搜索用户
b: 添加用户
c: 删除用户
d: 解锁用户
设计思路:
将用户的个功能通过函数方式进行模块化,登陆后通过用户角色选择不同菜单,
所有数据保存到txt文本文件中,程序启动后将所有数据加载到内存中,每次做修改后重新写到txt文件中去
由于测试需要,增加和删除一些用户,为了免于每次都更改txt文件,就增加了删除、添加、解锁等模块
涉及到的主要知识点:
1、文件的读、写操作
2、全局变量的操作
3、if...else ; while 等表达式的使用
4、字典、列表的操作
二、登录验证之流程图:

三、登录验证之用户信息userinfo.txt:
{"islocked": "0", "password": "123456", "userrole": "admin", "name": "wangsong", "createtime": "2015-12-19 22:30:47"}
{"islocked": "0", "password": "123123", "userrole": "user", "name": "peter", "createtime": "2015-12-19 22:31:30"}
{"islocked": "1", "password": "121212", "createtime": "2015-12-19 22:52:02", "name": "lisi", "userrole": "admin"}
{"createtime": "2015-12-21 10:04:50", "islocked": "0", "password": "sansan333", "userrole": "admin", "name": "zhangsansan"}
{"islocked": "0", "password": "212121", "userrole": "user", "name": "zhaoliu", "createtime": "2015-12-21 11:03:48"}
四、登录验证之代码:
# -*- coding:utf-8 -*- """ __author: super """ import os import json import getpass from datetime import datetime # 存放所有用户信息列表变量 USER_INFO = [] # 存放登陆成功的用户名 LOGIN_USER = "" # 存放登陆用户的权限,初始值为'admin' LOGIN_USER_ROLE = "admin" # 允许输入错误的最大次数 LOGIN_MAX_ERR_COUNT = 3 # 存放用户信息的文件 DB_TXT_FILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'userinfo.txt') # 初始化数据,将文件中的数据加载到全局变量中 def init_data(): with open(DB_TXT_FILE, 'r') as f: for record in f.readlines(): user_info = json.loads(record.strip()) USER_INFO.append(user_info) return USER_INFO # 管理员权限的显示菜单 def get_admin_menus(): menu_list = ( {'key': '1', 'menu': '[1] search users ', 'function': 'user_search'}, {'key': '2', 'menu': '[2] add new users ', 'function': 'user_add'}, {'key': '3', 'menu': '[3] delete users ', 'function': 'user_del'}, {'key': '4', 'menu': '[4] unlock users ', 'function': 'user_unlock'}, {'key': '5', 'menu': '[5] exit system ', 'function': 'exit_sys'}, ) return menu_list # 普通用户权限的显示菜单 def get_user_menus(): menu_list = ( {'key': '1', 'menu': '[1] search users ', 'function': 'user_search'}, {'key': '2', 'menu': '[2] modify password ', 'function': 'user_modify_passwd'}, {'key': '5', 'menu': '[5] exit system ', 'function': 'exit_sys'}, ) return menu_list # 根据输入的按键返回函数名称 ,如果选择按键不存在则返回False def return_function_by_menu(menu_list): print("========= Choose Menu ========== \n") for menu in menu_list: print(menu['menu']) choose = raw_input('choose what do yo want to do :') # 获取要执行的函数名称 for keys in menu_list: if keys['key'] == choose: return keys['function'] else: print('\n\033[1;31m Error choose\033[0m') return False # 查找用户模块, def user_search(): print("\n======== Search Users =============\n") name = raw_input("Input user name to search [\033[1;30mEnter\033[0m to show all] :").strip().lower() if len(name) > 0: print_search_user_info(name) else: print_all_user() return True # 打印所有用户信息 def print_all_user(): for user in USER_INFO: print('name: %-25s | user role:%-7s | create time: %s | lockstatus: %s \n' % ( user['name'], user['userrole'], user['createtime'], user['islocked'])).strip() return True # 打印查询到的用户数据,并高亮显示 def print_search_user_info(name): search_user = name i = 0 record_count = 0 # 开始在用户信息列表中循环查找 while i < len(USER_INFO): user = USER_INFO[i] # 如果记录的用户包含要查找的名字 if user['name'].count(search_user) > 0: name = user['name'].replace(search_user, '\033[1;31m' + search_user + '\033[0m') # 高亮显示 role = user['userrole'] cdate = user['createtime'] lockstat = user['islocked'] print('name: %-25s | user role:%-7s | create time: %s | lockstatus: %s \n' % ( name, role, cdate, lockstat)).strip() record_count += 1 # 找到记录数 i += 1 print('\n%s records found ' % str(record_count)) # 判断用户是否存在(True / False) def check_user_is_exists(user_name): i = 0 user_exists_status = False while i < len(USER_INFO): user = USER_INFO[i] if user['name'] == user_name: user_exists_status = True break else: i += 1 return user_exists_status # 添加用户模块 def user_add(): # 添加完1个用户后是否继续添加标志 add_more_flag = True print('====== Add New Users ===========') while add_more_flag: name = "" password = "" # 如果输入用户名为空则不停让输入,直到输入不为空 while len(name) == 0: name = raw_input("username: ").strip().lower() # 如果输入密码为空则继续输入 while len(password) == 0: password = raw_input("password: ").strip() # 选择用户角色 role = raw_input("user role number[1:admin / 2:user(default)]: ") if len(role) == 0 or role == "2": user_role = "user" if role == "1": user_role = "admin" # 组合数据为字典 user_info_dic = {"createtime": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), "password": password, "name": name, "userrole": user_role, "islocked": "0"} USER_INFO.append(user_info_dic) save_data() # 继续添加吗? continue_flag = raw_input('add user successfull, add more?(Y/N)').strip().lower() if continue_flag == 'n': add_more_flag = False # 删除用户模块 def user_del(): print("========== Delete Users ==========\n") name = "" while len(name) == 0: name = raw_input("input the user name you want to delete:").strip().lower() # 检查用户是否存在 is_exists = check_user_is_exists(name) if is_exists: i = 0 while i < len(USER_INFO): if USER_INFO[i]["name"] == name: USER_INFO.remove(USER_INFO[i]) save_data() print("\033[1;32m\nuser %s delete successfull !\033[0m" % name) break else: i += 1 else: print("\033[1;31m\nThe user %s does not exists!\033[0m" % name) # 修改用户密码模块 def user_modify_password(): print("========== Modify User's Password ==========\n") i = 0 flag = True while flag: new_password = getpass.getpass('input new password: ') confirm_passwod = getpass.getpass('input confirm password:').strip() # 如果两次密码一样的话 if new_password == confirm_passwod: while i < len(USER_INFO): if USER_INFO[i]['name'] == LOGIN_USER: USER_INFO[i]['password'] = new_password save_data() flag = False print(" password change success. \n") break i += 1 else: print('new password and confirm password does not match! try again\n') # 锁定账户模块 def user_lock(): i = 0 while i < len(USER_INFO): if USER_INFO[i]["name"] == LOGIN_USER: USER_INFO[i]['islocked'] = "1" save_data() break else: i += 1 # 解锁用户模块 def user_unlock(): print("======== Unlock Users ============\n") unlock_user = raw_input("input the user name to be unlock:").strip().lower() i = 0 while i < len(USER_INFO): if USER_INFO[i]["name"] == unlock_user: USER_INFO[i]['islocked'] = "0" save_data() print("unlock success ") break else: i += 1 else: print("no user called %s found!" % unlock_user) # 将内存的数据写入文件 def save_data(): i = 0 try: with open(DB_TXT_FILE, 'w+') as f: while i < len(USER_INFO): user = json.dumps(USER_INFO[i]) f.write(user + "\n") i += 1 except Exception as e: print(e.message) # 用户登录 def user_login(): try_failed_count = 0 # 重试失败次数 print("========= Login system ===========\n") while try_failed_count < LOGIN_MAX_ERR_COUNT: i = 0 uname = raw_input('user name:').strip().lower() upasswd = getpass.getpass('password: ').strip() while i < len(USER_INFO): # 如果找到搜索的用户 if USER_INFO[i]['name'] == uname: LOGIN_USER = uname # 如果正确,检查用户是否锁定,如果锁定 if USER_INFO[i]['islocked'] == "1": print("Sorry,your accout is locked,contact administrator to unlock") exit() else: # 用户存在,检查输入密码是否正确 if USER_INFO[i]['password'] == upasswd: LOGIN_USER_ROLE = USER_INFO[i]['userrole'] print("\033[1;32m\nwelcome %s!\033[0m" % uname) return True # 用户正确,密码验证失败 else: print("login failed,name and password is not avaible,try again!") try_failed_count += 1 break # 没找到? 下一条继续找... else: i += 1 # 搜索一圈都没有找到搜索的用户 else: print("user does not found! try again.") else: # 密码超过3次啦,账户要锁定了 user_lock() print('sorry , you try more then 3 times, i locked this account!') return False if __name__ == "__main__": init_data() if user_login(): # 根据用户角色加载菜单 if LOGIN_USER_ROLE == "admin": menu_list = get_admin_menus() if LOGIN_USER_ROLE == "user": menu_list = get_user_menus() # 根据菜单选择执行函数 while True: func = False while not func: func = return_function_by_menu(menu_list) if func == "user_search": user_search() elif func == "user_add": user_add() elif func == "user_del": user_del() elif func == "user_modify_passwd": user_modify_password() elif func == "user_unlock": user_unlock() elif func == "exit_sys": exit()
五、三层菜单之readme:
day1_3_mutilmenu.py
三级菜单展现程序:
功能如下:
1) 显示省列表
2) 根据选择的省,展开该省下面的市列表
3) 根据选择的市,展开市下面的县或街道列表
4) 返回上级
5)exit退出应用
设计思路:
将所有菜单保存到不同列表中,每个菜单都有一个按键key作为菜单选择序号
二级菜单或三级菜单的key通过split来分隔后,与选择的上级按键可以进行匹配,key格式为 key-key-key方式
涉及到主要知识点:
1、列表、字典的操作
2、if...else ; while 等表达式的使用
六、三层菜单之流程图:

七、三层菜单之代码:
# -*- coding:utf-8 -*- """ __author: super """ # 一级菜单: 省 def show_province(): province_list = ( {'pid': '1', 'pname': '北京'}, {'pid': '2', 'pname': '河北'}, {'pid': '3', 'pname': '河南'}, {'pid': '4', 'pname': '湖北'}, {'pid': '5', 'pname': '江苏'}, ) return province_list # 二级菜单: 市 def show_city(): city_list = ( ({'cid': '1-1', 'cname': '西城区'}, {'cid': '1-2', 'cname': '东城区'}, {'cid': '1-3', 'cname': '海淀区'},), ({'cid': '2-1', 'cname': '石家庄'}, {'cid': '2-2', 'cname': '保定市'}, {'cid': '2-3', 'cname': '邢台市'},), ({'cid': '3-1', 'cname': '郑州市'}, {'cid': '3-2', 'cname': '开封市'}, {'cid': '3-3', 'cname': '洛阳市'},), ({'cid': '4-1', 'cname': '武汉市'}, {'cid': '4-2', 'cname': '宜昌市'}, {'cid': '4-3', 'cname': '荆门市'},), ) return city_list # 三级菜单: 区县 def show_area(): area_list = ( ({'aid': '1-1-1', 'aname': '阜成门'},{'aid': '1-1-2', 'aname': '长椿街'},{'aid': '1-1-31', 'aname': '宣武门'},), ({'aid': '1-2-1', 'aname': '金宝街'},{'aid': '1-2-2', 'aname': '珠市口'},{'aid': '1-2-3', 'aname': '东直门'},), ({'aid': '1-3-1', 'aname': '中关村'},{'aid': '1-3-2', 'aname': '西二旗'},{'aid': '1-3-3', 'aname': '肖家河'},), ({'aid': '2-1-1', 'aname': '长安区'}, {'aid': '2-1-2', 'aname': '桥东区'}, {'aid': '2-1-3', 'aname': '桥西区'},), ({'aid': '2-2-1', 'aname': '新市区'}, {'aid': '2-2-2', 'aname': '北市区'}, {'aid': '2-2-3', 'aname': '南市区'},), ({'aid': '2-3-1', 'aname': '邢台县'}, {'aid': '2-3-2', 'aname': '内丘县'}, {'aid': '2-3-3', 'aname': '柏乡县'},), ({'aid': '3-1-1', 'aname': '金水区'}, {'aid': '3-1-2', 'aname': '二七区'}, {'aid': '3-1-3', 'aname': '上街区'},), ({'aid': '3-2-1', 'aname': '龙亭区'}, {'aid': '3-2-2', 'aname': '南关区'}, {'aid': '3-2-3', 'aname': '开封县'},), ({'aid': '3-3-1', 'aname': '老城区'}, {'aid': '3-3-2', 'aname': '西工区'}, {'aid': '3-3-3', 'aname': '新安县'},), ({'aid': '4-1-1', 'aname': '江岸区'}, {'aid': '4-1-2', 'aname': '江汉区'}, {'aid': '4-1-3', 'aname': '武昌区'},), ({'aid': '4-2-1', 'aname': '宜昌县'}, {'aid': '4-2-2', 'aname': '远安县'}, {'aid': '4-2-3', 'aname': '新山县'},), ({'aid': '4-3-1', 'aname': '东宝区'}, {'aid': '4-3-2', 'aname': '京山县'}, {'aid': '4-3-3', 'aname': '沙洋县'},), ) return area_list # 显示全部的省级菜单 def print_province_menu_all(): menu_list = show_province() for menu in menu_list: symbols = "|" + "-" * 2 print(symbols + "[" + menu['pid'] + "] " + menu['pname']) # 根据选择的省级菜单编号,显示指定的某个省 def print_province_menu_by_pid(pid): menu_list = show_province() for menu in menu_list: symbols = "|" + "-" * 2 if menu['pid'] == pid: print(symbols + "[" + menu['pid'] + "] " + menu['pname']) break # 打印指定的省编号ID下的所有市名称 def print_city_menu_all(pid_choosed): # 显示指定的省 print_province_menu_by_pid(pid_choosed) symbols = "|" + "-" * 4 for city_list in show_city(): for city in city_list: pid, cid = city['cid'].split('-') if pid == pid_choosed: print(symbols + '[' + cid + '] ' + city['cname']) return True # 根据用户的选择市ID号显示指定的市 def print_city_menu_by_cid(ppid, ccid): print_province_menu_by_pid(ppid) symbols = "|" + "-" * 4 for city_list in show_city(): for city in city_list: pid, cid = city['cid'].split('-') if pid ==ppid and cid == ccid: print(symbols + '[' + cid + '] ' + city['cname']) return True # 显示指定的省-市下的所有区县 def print_area_all(pid, cid): # 显示选中的市 print_city_menu_by_cid(pid,cid) symbols = "|" + "-" * 6 for area_list in show_area(): for area in area_list: ppid, ccid, aid = area['aid'].split('-') if ppid == pid and ccid == cid: print(symbols + '[' + aid + '] ' + area['aname']) return True # 判断输入的省编号是否存在(True / False ) def check_pid_is_exists(pid): is_exists_flag = False for menu in show_province(): if menu['pid'] == pid: is_exists_flag = True break return is_exists_flag # 判断选择市是否存在 def check_cid_is_exists(pid,key): is_exists_flag = False for city_list in show_city(): for city in city_list: if city['cid'] == pid + "-" + key: is_exists_flag = True return is_exists_flag # if __name__ == "__main__": pid_choosed = "" # 选中的省编号 cid_choosed = "" # 选中的市编号 finish_flag = True # 外层循环标识 # 外层循环,当二级菜单返回上一级是返回到此 while finish_flag: # 显示1级菜单 print_province_menu_all() # 选择省菜单的编号 pid = "" # 你没有选择编号或者编号不存在? 继续输入吧老兄 while len(pid) == 0 or not check_pid_is_exists(pid): pid = raw_input("选择省编号[exit 退出系统] : ") # 你要退出? if pid == "exit": exit() else: pid_choosed = pid # 内层循环,当三级菜单返回时上一级是返回到此 city_flag = True # 内层循环标识 while city_flag: # 打印选定省下的所有2级菜单 print_city_menu_all(pid_choosed) # 选择市级菜单编号 cid = "" while len(cid) == 0: cid = raw_input("请选择市编号[quit 返回上级菜单] : ").strip().lower() else: # 返回上一级菜单,跳出内层循环到外层 if cid == 'quit': city_flag = False continue else: cid_choosed = cid if check_cid_is_exists(pid_choosed,cid_choosed): # 显示三级菜单 print_area_all(pid_choosed, cid_choosed) next_choose = raw_input("quit 返回上一级菜单: ") # 返回二级菜单,继续内层循环 while next_choose != "quit": next_choose = raw_input("quit 返回上一级菜单: ") else: continue else: print('\n输入错误,不存在对应的市! ')
浙公网安备 33010602011771号