• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
秋天的童话
梦想从此启航
博客园    首页    新随笔    联系   管理    订阅  订阅

优秀作业:登录锁定和三层菜单程序展示之二

     来自python12期的王同佩的优秀作业:

 

一、登录验证之readme说明:

整体思路:
1、外层定义一个while True死循环,用于用户输入用户名(用户名输入不对的话,会一直要求输入)

2、初始工作
1、定义2个空的列表,空列表1计划把文件中的2行字符串,分别作为列表存到这里列表变量中,
遍历这个列表后,用于通过索引号取出用户名和密码字段,用于和用户输入的用户名和密码对比进行判断

空列表2计划将修改登录次数后的2个字符串作为元素,写入到这个列表变量中,最终用于写到文件中
2、定义一个flag,当用户输入的用户名==列表中的索引号是0的用户名的时候,flag=1
那么flag =0就代表用户输入的用户名不存在
3、读写模式打开文件对象(先读后写)
1、读文件,遍历文件对象,将字符串strip去换行符后,用split拆分成列表;
2、将列表[-1]转换成int,便于登录次数计算
3、将把文件中的2行字符串,分别作为列表添加这里空列表1变量中
4、用户输入用户名raw-input
5、几个场景
# 1 用户名为空:len(用户名)==0
# 2 用户名不存在:flag =0
# 3 用户名存在: 用户输入的用户名==子列表[0]
# a 用户名和密码都正确 登录次数改为0 break退出当前循环 sys.exit()退出整个程序
# b 密码错误 登录次数+1(列表中) 将修改后的列表转换成字符串,写入到文件

3、遍历内部含有2个列表的列表

4、内层定义一个while True死循环,用于用户输入密码(密码输入不对的话,会一直要求输入,直到break跳出内循环)
1、密码输入raw_input(或者getpass-密码看不见)
2、密码判断(用户名正确的前提下)
1、分支1:密码正确且登录次数小于3,提示登录成功;
2、分支2:登录次数大于等于3,提示用户锁定;
3、分支3、密码错误(登录次数+1),提示还有几次登录机会;
3、将登录次数转换成str
4、将修改后的字符串添加到空列表2

5、判断用户不存在 if flag == 0 ,提示用户不存在,用户重新输入,回到外循环while

6、如果用户存在的话
1、光标seek(0)到文件最开始
2、将修改了登录次数的列表(空列表2中的数据) ,用换行符\n 连接join成一个多行字符串
3、write这个字符串到文件对象
4、关闭文件对象
5、break 跳出外循环


# 整体思路分支:
# 分支1:用户名为空
# 分支2:用户名不存在
# 分支3:用户名密码正确,登录成功,登录此次置为1
# 分支4:用户名正确,但是登录次数大于3,锁定
# 分支5:用户名正确,密码每错误一次,登录次数加1,登录次数为3的时候,锁定
# (这里每次密码错误,只会要求重新输入密码,不用再次输入用户名了)

# 登录接口涉及知识点:
# 1、字典和列表的取值方式:列表通过索引取出用户名、密码、错误登录次数;字典通过key取值
# 2、读写文件
# 1、读文件:1for遍历 2strip去换行 3split拆成列表 4错误登录次数转换成数字,便于计算 5将2个子列表append到空列表中
# 2、写文件:1列表最后一项错误登录次数转换成str 2将列表用;连接符join成字符串作为列表的元素,append到空列表2
# 3光标来到文件最开始seek(0) 4将空列表2的2个元素用连接符\n连接join成一个换行的2行字符串
# 5写入文件 6关闭文件
# 3、多次嵌套循环的跳出
# 4、异常处理:错误登录次数不少数字,锁定
# 5、用户是否存在的标识flag
# 6、颜色提示语
# 加颜色:成功绿色 失败红色
# '\033[32;1m登录成功,欢迎%s\033[0m' --绿色
# '\033[31;1m用户"%s"已锁定,请联系管理员\033[0m' --红色
# 7、getpass不明文显示密码

 

二、登录验证之流程图:

 

三、登录验证之用户信息userinfo.txt:


jack;123;0
tom;123;0


 

四、登录验证之代码:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

# import getpass
import sys

while True:#死循环,用于61行输入用户名(用户名输入不对的话,会一直要求输入)
    old_user_list = []  #计划把文件中的2行字符串,分别作为列表存到这里列表变量中
    new_user_list = []  #计划将修改登录次数后的2个字符串作为元素,写入到这个列表变量中
    # # 定义一个标识数,来判断用户是否存在
    flag = 0   #0的话代表用户名不存在  不是0代表用户名存在(首先用户存在的时候,就将flag置为1;
    # --用户输入的==子列表的第一个元素(文件中的用户名)
    # 那么flag==0的时候,就是用户不存咋)
    f = file('userinfo.txt', 'r+')  #读写模式打开文件(先将文件的字符串读入到内存,转换成列表后修改登录次数
    #然后将修改后的字符串seek(0)到文件开始,覆盖写入修改后的字符串到文件 )
    # 从文件中读取用户信息保存到用户列表内
    for line in f:   #遍历文件(读取文件字符串到内存 1拆成列表 2将登录次数转换成int,便于计算 3、将2个列表作为元素添加到空列表)
        # print line,  #"jack;123;3"
        tmp_line_list = line.strip().split(';')  #将字符串去掉换行符后,用";"作为分隔符,拆分成列表
        # 将用户登录错误次数转为int类型,如果转换失败,将用户锁定
        # print tmp_line_list  #['jack', '123', '0']  ['tom', '123', '0']
        try:
            tmp_line_list[-1] = int(tmp_line_list[-1])  #将列表的最后一项-登录次数转换成int,用于计算
        except ValueError, e:
            tmp_line_list[-1] = 3
        old_user_list.append(tmp_line_list)  #将2个列表作为元素添加到空白列表中
        # print old_user_list   #[['jack', '123', 0], ['tom', '123', 0]]
    username = raw_input('请输入用户名: ').strip()  #将输入的用户名去掉2边空格
    if len(username) == 0:  #判断输入的用户名是否为空
        print '\033[31;1m用户名不能为空!\033[0m'  #提示有颜色
        continue  #跳出当次迭代(当次循环),回到最外层的while死循环,重新输入用户名

    for user_line in old_user_list:  #遍历内部含有2个列表的列表,和while和for循环有点区别
        #print user_line  #['jack', '123', 0] ['tom', '123', 0]
        if username == user_line[0]:  #判断输入的用户名是否等于子列表的第一个元素(文件中的用户名)
            # # 用户存在标识数加1
            # print user_line[0]
            flag = 1
            while True:  #定义一个内部的while死循环,用于73行输入密码(密码输入不对,会一直要求输入,除非break)
                password = raw_input('请输入密码: ')  #输入密码
                if password == user_line[1] and user_line[-1] < 3: #判断输入的密码等于子列表的第2个元素(文件中的密码)且登录次数小于3
                    # 用户登录成功后将错误次数重置为0
                    # print user_line[1]
                    user_line[-1] = 0   #将登录次数置为0
                    print '\033[32;1m登录成功,欢迎%s!\033[0m' % username #提示成功,提示语有颜色,成功显示绿色(亮青色)
                    break  #跳出内部的while循环(不会再要求输入密码) 走到106行
                    # sys.exit()  #引发一个 SystemExit异常,若没有捕获这个异常,Python解释器会直接退出
                elif user_line[-1] >= 3:  #如果登录次数大于等于3
                    print '\033[31;1m用户"%s"已锁定,请联系管理员!\033[0m' % username  #提示语有颜色,失败显示红色
                    # time.sleep(3)
                    break
                    #sys.exit() #引发一个 SystemExit异常,若没有捕获这个异常,Python解释器会直接退出
                else:  # 用户名正确,密码错误
                    # 用户名正确,密码错误,错误次数加1
                    user_line[-1] += 1  #子列表的最后一项-登录次数加1
                    # 获取剩余尝试次数
                    rest_nums = 3 - user_line[-1]  #定义剩余的尝试次数
                    # 如果尝试次数为0,则不再允许尝试
                    if rest_nums == 0:  #如果剩余尝试次数是0
                        print '\033[31;1m用户"%s"已锁定,请联系管理员!\033[0m' % username  #失败显示红色
                        flag = 3
                        break#跳出内部的while循环(不会再要求输入密码) 走到106行
                    else:
                        print "\033[31;1m密码错误!您还可以尝试%d次,错误3次后用户将被锁定,登录成功后错误次数将重置!\033[0m" % rest_nums
                        #失败显示红色  这里没有break,会重复3次提示输入密码,直到锁定
                        # continue   这里可以注释continue,因为内循环中continue后没有代码,加和不加效果一样
        # 将用户错误次数转为str类型
        user_line[-1] = str(user_line[-1])  #前面56行转换成数字,为了计算,现在要存储到文件,应该转换成str类型
        # 将用户信息转为以“;”分割的字符串,添加到新的用户列表
        new_user_list.append(';'.join(user_line))  #将修改后的字符串添加到新的空白列表
        # print new_user_list  #['jack;123;0', 'tom;123;0']
    if flag == 0:  #flag=0 标识用户名不存在
        print '\033[31;1m用户名不存在,请重新输入!\033[0m'   #重新输入用户名,到了58行  失败显示红色
    else:   #表示用户名存在的所有情况,将修改完登录次数的列表转换成字符串写入到文件
        f.seek(0)   #回到文件最开始处,将内存中存储的字符串写入到文件对象,覆盖之前的文件内容
        # 将新的用户列表转为以“\n”为分割的字符串,写入到用户信息文件
        f.write('\n'.join(new_user_list))  #字符串在文件中是分行存储的,所以用\n换行
        # print '\n'.join(new_user_list)
        #jack;123;0\ntom;123;0
        f.flush()
        f.close()  #关闭文件对象
        break  #跳出外循环while
        #sys.exit() #引发一个 SystemExit异常,若没有捕获这个异常,Python解释器会直接退出
        #跳出外循环while
    # f.seek(0)    #用户名不存在的时候,执行下述代码,此处代码可以注释
    # # 将新的用户列表转为以“\n”为分割的字符串,写入到用户信息文件
    # f.write('\n'.join(new_user_list))
    # # print '\n'.join(new_user_list)
    # f.flush()
    # f.close()
登录验证

 

五、三层菜单之readme:

# 整体思路:
# 1 将省市区行政区划用字典列表来构造,用key取省或者地市列表,用for遍历显示字典或者列表的元素
# 2 根据整个字典的key,得到省列表,遍历打印省的名字列表
# 3 设置用于跳出外循环的flag(跳出嵌套循环)
# 4 两层嵌套循环,外循环for指定3次固定循环,3次输入省名字错误,程序退出(在外循环for后,通过else来实现)
# 内循环while True是死循环,不指定次数(地市名字输入错误后,会一直要求输入,直到输入正确为止),
# 通过break退出内循环
# 5 通过整个字典的key得到省列表,通过省字典的key得到地市列表,遍历打印地市的名字列表
# 6 判断输入的地市是否在省字典中,在的话,通过省字典的key,for遍历打印区县的名字列表
# 不在的话,提示"输入的地市名字不对,请重新输入",continue跳出当次迭代(循环),继续输入地市名字
# 还在内循环while中
# 7 打印区县列表后,2个选择,1是退出整个程序(2个嵌套循环都退出),2是回到上一级别菜单(只需要退出内循环的当前迭代)
# 8 回到上一级别菜单(只退出内循环while) 判断用户输入的是否是"b",是的话,continnue 退出内循环的当前迭代,开始内循环下次迭代
# 9 退出整个程序(2个嵌套循环都退出) 判断用户输入的是否是"q",是的话,先将flag变成True,然后break退出while内循环
# 再做一个判断,判断flag是否是True,如果是的话,break退出for外循环,至此,退出整个程序(2个嵌套循环都退出)

 

六、三层菜单之流程图:

 

七、三层菜单之代码:

__author__ = 'Administrator'
# -*- coding:utf-8 -*-

# 三级菜单--嵌套循环
#  可依次选择进入各子菜单
#  所需新知识点:列表、字典
# 1北京
#   1、海淀
#     2、朝阳
#     3、昌平
#        1、沙河
#        2、天通苑
#        3、回龙观
#        b是返回上一级菜单--continue(跳出内循环的当次迭代)
#        q是退出整个循环--break(退出多层嵌套)
# 2,上海
# 3、hk

# 整体思路:
# 1 将省市区行政区划用字典列表来构造,用key取省或者地市列表,用for遍历显示字典或者列表的元素
# 2 根据整个字典的key,得到省列表,遍历打印省的名字列表
# 3 设置用于跳出外循环的flag(跳出嵌套循环)
# 4 两层嵌套循环,外循环for指定3次固定循环,3次输入省名字错误,程序退出(在外循环for后,通过else来实现)
#     内循环while True是死循环,不指定次数(地市名字输入错误后,会一直要求输入,直到输入正确为止),
#     通过break退出内循环
# 5 通过整个字典的key得到省列表,通过省字典的key得到地市列表,遍历打印地市的名字列表
# 6 判断输入的地市是否在省字典中,在的话,通过省字典的key,for遍历打印区县的名字列表
#    不在的话,提示"输入的地市名字不对,请重新输入",continue跳出当次迭代(循环),继续输入地市名字
#    还在内循环while中
# 7 打印区县列表后,2个选择,1是退出整个程序(2个嵌套循环都退出),2是回到上一级别菜单(只需要退出内循环的当前迭代)
# 8 回到上一级别菜单(只退出内循环while) 判断用户输入的是否是"b",是的话,continnue 退出内循环的当前迭代,开始内循环下次迭代
# 9 退出整个程序(2个嵌套循环都退出) 判断用户输入的是否是"q",是的话,先将flag变成True,然后break退出while内循环
#   再做一个判断,判断flag是否是True,如果是的话,break退出for外循环,至此,退出整个程序(2个嵌套循环都退出)


#将省市区行政区划用字典列表来构造,用key取省或者地市列表,用for遍历显示字典或者列表的元素
city_map = {
    "湖北":{"武汉":["武昌","汉阳","汉口"],
            "黄冈":["黄州","红安","麻城"]},
    "吉林":{"长春":["高新区","南关区"],
            "四平":["东区","西区"]},
}  #定义一个字典
print "--------地图------"
for i in city_map:    #遍历字典的key,列出省市的名字
    print i
print "------------------"
jump_flag = False   #用于跳出外循环
for i in range(3):  #外循环,指定循环3次,3次外循环完了,就退出程序
    city_name = raw_input("请输入你要查看的省市名字:")
    if city_name in city_map:  #检查输入的省是否在地图中,如果省名字3次输入错误,走到60行,程序退出
        sheng_name = city_map[city_name]  #使用输入的信息作为key,取出省信息,存在字典中
        shi_name =sheng_name.keys()  #取出省中有哪些地市,存在列表中
        while True:  #内循环,死循环,不指定循环次数,通过break或者flag跳出
            print "----包含的市是----"    #友好的提示,分隔线
            for i in shi_name:  #遍历列表,取出地市名字,打印出来
                print i
            print "------------------"    #友好的提示,分隔线
            shi_name_input = raw_input("请输入你要查看的地市名字:")
            if shi_name_input in shi_name: #判断输入的地市名字是否在地市列表中
                quxian_name = city_map[city_name][shi_name_input]  #取出地市中有哪些区县,存在列表中
                print "----包含的区县是----"  #友好的提示,分隔线
                for i in quxian_name: #遍历列表,取出区县名字,打印出来
                    print i
                print "-------------------"  #友好的提示,分隔线
            if shi_name_input not in shi_name: #如果输入的地市名字不在在地市列表中
                print "输入的地市名字不对,请重新输入"
                continue  #跳出当次迭代,开始下一次迭代循环,直到地市名字输入正确为止
            jump_shi = raw_input("请问是否退出?按b是返回上一级菜单;按q是退出整个程序")
            #显示完区县后,就要退出程序了,一个是全部退出,一个是返回上一级菜单
            if jump_shi == "q":
                jump_flag = True  #用于跳出外循环
                break  #跳出while内循环
            if jump_shi == "b":
                continue  # 跳出当次迭代,开始下一次迭代循环,来到41行,重新输入地市处,返回上一步
            print "你输入的信息有误,请重新输入"
        if jump_flag:   #跳出外循环的条件满足
            break  #跳出外循环
else:#上面的3次for循环正常执行完毕,else才会执行,如果是不正常退出(break),else不会执行
    print "3次输入错误,程序退出"
三层菜单

 

做人一定要靠自己
posted @ 2016-01-10 21:56  凯-子  阅读(303)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3