day1作业:编写登录窗口一个文件实现
思路:
1、参考模型,这个作业我参考了linux的登录认证流程以及结合网上银行支付宝等锁定规则;
1)认证流程参考的是Linux的登录:当你输入完用户名密码后再验证用户名是否存在用户是否被锁定,然后在验证密码是否正确,如果验证不过去只会告诉你验证失败,而不告诉你到底是用户名错误还是密码错误,增加了暴力破解的难度;
2)关于输入错误次数的计数和锁定,我参考的是银行和支付宝的做法,也就是只关心你输错了多少次,不关心输对了多少次,也就是说输错了两次,第三次输对了,前面的计数不清零,也就是你今天输入了1000次输对了997次,只输错了3次,那对不起,依然要锁定。而且输入错误的3次不一定要连续。只要三次输入错误三次就锁定。
2、关于计数和状态的保存我考虑还是通过文件来持久化保存,每次输入错误次数的累加和锁定都保存到文件中,这样虽然增加了文件的操作,但是保证了程序的可靠性,这样程序退出,计数依然有效。文件类型如下:
alex sb lock 3
tom 666 unlock 0
geng 888 unlock 2
其中第一列是用户名,第二列是密码,第三列是用户状态(lock代表锁定,unlock代表没有锁定),第四列是登录次数(其实,登录次数只要错误的时候登录次数加一即可,没有错误的时候不用管它)。

代码如下:
def write_file(messages,filename):
"""向文件中添加信息,一行一行添加信息,打开文件使用'w'格式要注意"""
with open(filename,"w") as f:
for key,values in messages.items():
"""
lines = []
print(key,value)
lines.append(key)
lines.extend(value) #把一个列表的信息添加到另一个列表中
print("lines",lines)
f.write(" ".join(lines) + "\n")
"""
values.insert(,key) #由于字典的值是列表,可以直接向列表中插入元素
f.write(" ".join(values) + "\n") #字符串拼接,字符串与列表拼接 # messages = {"alex":["sb","lock",""],"tom":["","unlock",""],"geng":["","unlock",""]}
# write_file(messages,"account.db") if __name__ == "__main__":
active = True
#程序执行的标识符,可以通过标识符来执行程序
while active:
username = input("请输入你的用户名(输入quit退出):")
users_dict = {} #用户字典,用于存放用户的信息,键-用户名,值-列表对应的密码,状态,次数
with open("account.db","r") as obj_f: #打开文件,读取文件信息
lines = obj_f.readlines() #按行读取文件,读取到一个列表中
for line in lines:
user_list = line.strip().split()
users_dict[user_list[]] = user_list[:] #把用户信息存放在一个字典中,字典的值是一个列表 if username in users_dict.keys():
if users_dict[username][] == "lock":
print("您输入的用户名已经锁定,请联系管理员!")
exit()
else:
while int(users_dict[username][]) < :
user_pwd = input("请输入密码:")
if users_dict[username][] == user_pwd:
print("欢迎回来,祝你生活愉快,天天OOXX!")
else:
if int(users_dict[username][]) != :
print("还有%s次机会,用户将被锁定!" % ( - int(users_dict[username][])))
users_dict[username][] = int(users_dict[username][]) +
else:
#输入次数过多,要锁定用户
print("对不起,您输入的次数过多,你的用户名已经被锁定,请联系管理员!")
users_dict[username][] = "lock"
users_dict[username][] = ""
write_file(users_dict,"account.db")
elif username == "quit":
exit() else:
print("您输入的用户名不存在,请重新输入!")
运行结果如下:
请输入你的用户名(输入quit退出):tom
请输入密码:22
还有2次机会,用户将被锁定!
请输入密码:22
还有1次机会,用户将被锁定!
请输入密码:22
对不起,您输入的次数过多,你的用户名已经被锁定,请联系管理员!
请输入你的用户名(输入quit退出):alex
您输入的用户名已经锁定,请联系管理员!
其实对文件的操作,其本质上还是对字符串列表,字典的操作,文件的操作,读取文件的方法,readlines()按行读取存放到一个列表中,使用dict(字典)记录用户信息。字符串的拼接(join)方法,(" ".join(list)),字符串与列表进行拼接,形成一个新的字符串,其实字符串的本质上在python中存储的形式就是以列表的形式存储,列表之间的拼接,list.extend(list),列表之间的拼接。
代码说明:
1、这里用了两个今天课程没有讲的内容:字典和函数,将用户信息以字典的方式保存是出于判断用户名是否存在的考虑,读文件的时候直接将用户名作为字典的一个key,其他的信息作为字典的value与key一一对应,这样在判断用户名是否存在只需要通过in这个成员运算符进行判断就可以了;
2、代码的第61和62两行代码完成的就是将文件变成字典的过程。

原创张晓宇代码实例:
#!/usr/bin/env python3
# coding:utf-
'''
Created on: 2015年12月29日 @author: 张晓宇 Email: @qq.com Version: 1.0 Description: 输入用户名密码,认证成功显示欢迎信息,认证失败,输错三次后锁定 Help:
'''
import os
# 定义用户信息写入函数,用于把用户信息写回文件
def write_to_account_file(accounts,account_file_path):
"""accounts是一个用户信息字典,目的是把变更过的信息写入文件中"""
account_file = open(account_file_path,"w")
for key,val in accounts.items():
line = []
line.append(key)
line.extend(val)
print(" ".join(line)) #字符串与列表拼接,目的是实现列表中每个元素加空格生成一个字符串如a b c d格式
account_file.write(" ".join(line) + "\n") #往文件中添加信息
account_file.close() #直接打开文件的时候一定要记得关闭文件,以免文件休息丢失 if __name__ == '__main__': '''
@parameters:
account_file_path:账户文件
password_col_num:账户文件中密码所在的列(从0开始)
status_col_num:账户文件中账户状态所在的列(从0开始)
error_count_num:账户文件中输入错误次数所在的列(从0开始)
app_info:系统信息,用户启动应用后的输出
welcome_msg:用户成功登录后的信息
'''
account_file_path = 'account.db'
password_col_num =
status_col_num =
error_count_num =
app_info = '''
+---------------------------------+
| Welcome to gcx system |
| Version:2.0 |
| Author:zhuzhu |
+---------------------------------+
'''
welcome_msg = "Welcome %s,authentication is successful!"
if os.path.exists(account_file_path): #os.path.exists()判断文件是否存在,返回布尔值
# 判断账户文件是否存在
account_file = open(account_file_path,"r")
else:
#文件不存在,看系统是否有误
print("Error:Account file 'account.db' is not exit,please check!")
exit() #读账户文件
accounts = {}
for line in account_file.readlines(): #按行读取文件
account = line.strip().split() #清楚空格后进行分列,生成一个列表
accounts[account[]] = account[:]
"""把列表中的第一个元素(用户名)当做键,用户的其他信息当做值,组成键值对存放在字典中"""
"""account[0]键,account[1:]是值"""
account_file.close() #关闭文件
flag = True
while flag:
print(app_info)
#输入用户名
username = input("Username(Enter quit to exit): ").strip()
#判断用户是否输入的为quit
if username == "quit":
#是则退出循环,程序结束
break
password = input("Password: ").strip()
#判断用户名是否存在
if username not in accounts.keys():
#不存在提示错误信息并退出当前循环让用户重新输入
print("Error:Username or Password it is error!")
continue #结束本次循环,让用户再次输入用户名和密码,继续执行下一次循环
if accounts[username][status_col_num - ] == "lock":
#如果被锁定退出当前循环让用户重新输入
print("Error:Account is locked.Please contact the administrator!")
continue #跳过本次循环,让用户重新输入进行验证,这个可以避免很多缩进,能够继续执行下一次
#判断用户密码是否正确
if password == accounts[username][password_col_num - ]:
#正确显示欢迎信息
print(welcome_msg %username)
break
else:
#用户密码不正确的情况
#提示用户名或密码错误
print("Error:Username or Password it is error!")
#输入错误次数加1
accounts[username][error_count_num - ] = str(int(accounts[username][error_count_num - ]) + )
#判断是否已经达3次
if int(accounts[username][error_count_num - ]) == :
#如果输入错误达到3次
#提示账户将被锁定
print("Error: This account will be locked,Please contact the administrator!System will be exit!")
#将用户状态改为lock并写入文件
accounts[username][status_col_num - ] == "lock"
write_to_account_file(accounts,account_file_path)
break
write_to_account_file(accounts,account_file_path)
上面代码中亮点:
(1)continue:结束本次循环,continue后面的代码都不执行,达到重新让用户输入的目的,很多网页都是让用户一直输入,知道用户要么选择注册,要么关掉网页;
(2)文档的规范性比较好,有解释;
(3)文件就是一行一行读,然后一行一行写入文件,修改的过程中要用到列表和字典的知识;
(4)" ".join(list)字符串与列表的拼接,生成新的字符串;
(5)split()字符串的分割;extend()列表之间的拼接。
day1作业:编写登录窗口一个文件实现的更多相关文章
- day1 作业编写登录窗口
作业一:编写登录接口 (1)输入用户名和密码: (2)认证成功后显示欢迎信息: (3)输错三次后锁定. 思路:我们知道,要想让程序记住之前输入多少次,锁定用户,那么可以使用数据库来保存用户的状态,然而 ...
- day1作业:登录接口
作业一:编写登陆接口 1.输入用户名和密码 2.认证成功后显示欢迎信息 3.输错三次后锁定 思路: (1)用户输入用户名: (2)去锁定文件中验证用户名是否锁定: (3)去当前用户验证用户是否存在: ...
- Day1作业-模拟登录
# /usr/bin/env python# -*- coding: utf-8 -*-# Author:jenvid.yangimport getpassimport shutiluserspwd ...
- WPF MVVM从入门到精通2:实现一个登录窗口
原文:WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通1:MVVM模式简介 WPF MVVM从入门到精通2:实现一个登录窗口 WPF MVVM从入门到精通3:数据绑定 ...
- python基础一之课后作业:编写登录接口
1 # Author : Mamba 2 3 #python基础一之课后作业:编写登录接口 4 5 # 输入用户名密码 6 # 认证成功后显示欢迎信息 7 # 用户名3次输入错误后,退出程序 8 # ...
- Day1作业---登录接口及多级菜单
#!/usr/bin/env python # -*- coding:utf-8 -*- # Author:Ma Qing data = { "山东" :{ "济南&qu ...
- 【2017-04-24】winform基础、登录窗口、窗口属性
一.winform基础 客户端应用程序:C/S 客户端应用程序可以操作用户电脑中的文件,代码要在用户电脑上执行,吃用户电脑配置. 窗体是由控件和属性做出来的 控件:窗体里所放的东西."视图 ...
- 关于python怎样编写登录接口
把今天的成果展示下,关于怎么用python编写登录接口, 要求是 1.输入用户名和密码 2.输错三次密码就锁定用户 3.认证成功后输出欢迎信息 账号文件内容如下: sanjiang sanjian ...
- delphi 基础之三 编写和调用dll文件
delphi 编写和调用dll文件 Windows 的执行文件可以划分为两种形式程序和动态连接库 (DLLs).一般程序运行是用.EXE文件,但应用程序有时也可以调用存储在DLL的函数. 在如下几 ...
随机推荐
- 2017 清北济南考前刷题Day 7 morning
期望得分:100+50+20=170 实际得分:10+50+20=80 1. 纸牌 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真眼可以看到所有牌朝上的一面和朝下的 ...
- SXOI2018 游记
noilinux@Capella:~$ cd /Memories/ noilinux@Capella:/Memories$ rm *SXOI* rm:是否删除有写保护的普通文件 "SXOI2 ...
- 关于mysql 5.7版本“报[Err] 1093 - You can't specify target table 'XXX' for update in FROM clause”错误的bug
不同于oracle和sqlserver,mysql并不支持在更新某个表的数据时又查询了它,而查询的数据又做了更新的条件,因此我们需要使用如下的语句绕过: , notice_code ) a) ; 本地 ...
- 有用的Javascript,长期更新...
1,点击目标区域以外隐藏,运用场景:点击遮罩层,弹层关闭. // 点击目标区域以外隐藏 $(document).on("click", function (event) { var ...
- 动态引用外部的Javascript脚本文件[转]
你可以参考下面方法,进行动态为网页引用外部的Javascript脚本文件.代码写在Page_Init方法内. VB.NET: 下图是运行时,查看HTML的源代码: C#:
- ASP.NET中常用输出JS脚本的类(来自于周公博客)
using System; using System.Collections.Generic; using System.Text; using System.Web; using System.We ...
- CF 1008C Reorder the Array
You are given an array of integers. Vasya can permute (change order) its integers. He wants to do it ...
- Dream------scala--函数定义、流程控制、异常处理
Dream------scala--函数定义.流程控制.异常处理 一.函数的定义 1.新建工程
- Spring4笔记5--基于注解的DI(依赖注入)
基于注解的DI(依赖注入): 对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 Bean 实例.只需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解. < ...
- weblogica domain目录 环境变量 如何启动weblogic server
手工启动weblogic server