我有以下代码,其中一个令人困惑的跳转回到quiz1()函数的登录函数中的第48行。代码似乎很好,无法找到错误的来源或原因,因为它没有理由回去!
可以在此处测试并找到包含文件的完整代码:
测试数据:
username: admin
password: admin123
Press 1 to play
Press 1 to go to Quiz
>>ERROR (Jumps back to the main menu, and specifically to line 48 in the login function
注释
我假设错误位于登录代码中的某处。要给出答案,我想:
登录功能代码:
def login():
print("===Login===")
username=input("Enter username:")
password=input("Enter password:")
with open('userinfo.txt','r') as f:
reader=csv.reader(f)
username_correct=False
password_correct=False
while username_correct==False and password_correct==False:
for row in reader:
for field in row:
if field==username:
currentindex=row.index(field)
if row[currentindex+1]==password:
print("****You're in!*****")
username_correct=True
password_correct=True
print()
f.close()
mainmenu()
else:
break
print("Wrong username or password, sorry!")
welcomemenu()
更新
这似乎有效,通过从while循环中删除对主菜单的调用。但是,如果用户错误的话,代码需要重构优雅和输出“无效组合或用户详细信息”的最佳方式:
def login():
print("===Login===")
passwordC=False
usernameC=False
while passwordC==False and usernameC==False:
username=input("Enter username:")
password=input("Enter password:")
with open('userinfo.txt','r') as f:
reader=csv.reader(f)
for row in reader:
for field in row:
if field==username and row[1]==password:
passwordC=True
usernameC=True
if passwordC==True and usernameC==True:
print("**You're in**")
mainmenu()
else:
print("Try again - wrong username and password")
login()
答案 0 :(得分:1)
在循环中执行mainmenu
是您的错误。
尝试:
def login():
print("===Login===")
username=input("Enter username:")
password=input("Enter password:")
with open('userinfo.txt','r') as f:
reader=csv.reader(f)
username_correct=False
password_correct=False
for row in reader:
for field in row:
if field==username:
currentindex=row.index(field)
if row[currentindex+1]==password:
username_correct=True
password_correct=True
if password_correct == False or username_correct == False:
print("Wrong username or password, sorry!")
welcomemenu()
print("****You're in!*****")
mainmenu()
由于程序未完成,您需要退出
def quiz1():
print("===Quiz1===")
print("Question 1:")
exit()
答案 1 :(得分:0)
不需要usernameC
和passwordC
:
def login():
print("===Login===")
while True:
username=input("Enter username:")
password=input("Enter password:")
with open('userinfo.txt','r') as f:
reader=csv.reader(f)
for row in reader:
for field in row:
if field==username and row[1]==password:
mainmenu()
break
print("Try again - wrong username and password")
这应该解决问题。
如果你想使用我在下面描述的pickle
,函数定义将如下所示(更简单):
with open("userdata.pkl", "rb") as f:
userdata = pickle.load(f)
def login():
print("===Login===")
while True:
username=input("Enter username:")
password=input("Enter password:")
if username in userdata:
if userdata[username] == password: # Checks the password.
mainmenu()
break
print("Try again - wrong username and password")
此外,我想指出,即使出于学习目的,将密码存储在文本文件中也是一个坏主意。如果您不想使用数据库,请使用二进制文件来存储用户名和密码。使用如下例程:
import pickle
data = {"user1": "password1", "user2": "password2"} # dictionary would be the data structure of the choice for this case.
with open("userdata.pkl", "wb") as f:
pickle.dump(data, f)
稍后,您可以按如下方式检索字典:
with open("userdata.pkl", "rb") as f:
userdata = pickle.load(f)
现在,print(userdata)
会提供:{"user1": "password1", "user2": "password2"}
答案 2 :(得分:0)
我发现了我认为的错误。
for row in reader:
for field in row:
if field==username:
currentindex=row.index(field)
if row[currentindex+1]==password:
print("****You're in!*****")
username_correct=True
password_correct=True
print()
f.close()
mainmenu()
else:
break
用户登录后关闭文件。然后你调用mainmenu函数。从主菜单函数返回后,您继续循环到文件的下一行...但您已经关闭该文件...因此错误。
试试看看它是否有效(不需要csv阅读器)
def login():
print("===Login===")
username=input("Enter username:")
password=input("Enter password:")
with open('userinfo.txt','r') as f:
authenticated = False
line = f.readline().strip()
while authenticated ==False and line != "":
values = line.split(",")
if len(values) >= 2 and values[0] == username and values[1] == password:
authenticated=True
line = f.readline().strip()
if authenticated:
print("****You're in!*****")
mainmenu()
else:
print("Wrong username or password, sorry!")
welcomemenu()
答案 3 :(得分:0)
我不知道你是否已经解决了这个问题,但最初的问题是list.index没有按照你的想法做到 - 它没有给出当前项目的索引,而是搜索对于匹配的项目并给出该索引。所以,例如:
row = [1, 1, 1, 1, 1]
print(row[4], row.index(row[4]))
打印1 0
,而不是1 4
。您的userinfo文件包含两个包含“admin”的字段,因此您将获得两个与密码匹配的字段。
获取当前字段索引的最佳方法是使用enumerate
。
for currentindex, field in enumerate(row):
重写login()函数,使其更具可读性,我认为您打算执行以下操作:
def is_valid_user(username, password):
with open('userinfo.txt','r') as f:
for row in csv.reader(f):
if row[0] == username and row[1] == password:
return True
return False
def login():
print("===Login===")
username=input("Enter username:")
password=input("Enter password:")
if is_valid_user(username, password):
mainmenu()
else:
print("Wrong username or password, sorry!")
welcomemenu()
从当前函数调用下一个函数的方式也存在问题。 例如,如果您反复输入错误的密码,您将获得以下函数调用链:
main -> welcomemenu -> login -> welcomemenu -> login -> welcomemenu ->
login -> welcomemenu -> login -> welcomemenu -> login -> welcomemenu ->
login -> welcomemenu -> login -> welcomemenu -> login -> welcomemenu etc
迟早,这种模式会给你带来麻烦。相反,尝试将函数调用安排为“扇出”,如下所示:
def welcomemenu():
while True:
print("""
=========*WELCOME MENU*===========
1. Register
2. Login
3. Quit
*You need to register and login for access to the game menu
""")
userselection=int(input("Enter Selection"))
if userselection==1:
register()
elif userselection==2:
if login():
mainmenu()
break
elif userselection==3:
break
def is_valid_user(username, password):
with open('userinfo.txt','r') as f:
for row in csv.reader(f):
if row[0] == username and row[1] == password:
return True
return False
def login():
print("===Login===")
username=input("Enter username:")
password=input("Enter password:")
valid = is_valid_user(username, password)
if not valid:
print("Wrong username or password, sorry!")
return valid
所以'错误的密码'序列现在会出现:
main -> welcomemenu -> login (back) -> login (back) -> login (back) etc