Python 从函数跳到主菜单的不可见跳转-有人能发现错误吗?
我有下面的代码,其中从quiz1()函数跳回到login函数的第48行,令人困惑。代码看起来很好,找不到错误的来源或原因,因为没有理由返回 可以在此处测试并找到文件的完整代码: 测试数据:Python 从函数跳到主菜单的不可见跳转-有人能发现错误吗?,python,function,Python,Function,我有下面的代码,其中从quiz1()函数跳回到login函数的第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
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()
评论
我假设错误在登录代码中的某个地方。要奖励答案我想:
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
,函数定义如下所示(简单得多):
此外,我想指出,将密码存储在文本文件中是一个坏主意,即使是出于学习目的。如果不想使用数据库,请使用二进制文件来存储用户名和密码。使用如下例行程序:
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)
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()
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
稍后,您可以按如下方式检索词典:
with open("userdata.pkl", "rb") as f:
userdata = pickle.load(f)
现在,
print(userdata)
会给出:{“user1”:“password1”,“user2”:“password2”}
我发现了我认为是错误的地方
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
用户登录后,关闭该文件。然后调用主菜单功能。从主菜单函数返回后,继续for循环到文件的下一行。。。但是你已经关闭了那个文件。。。因此是错误的
试试看它是否有效(不需要csv阅读器)
在循环中执行
main菜单
是您的错误。
尝试:
由于程序未完成,您需要退出
def quiz1():
print("===Quiz1===")
print("Question 1:")
exit()
我不知道你是否已经解决了这个问题,但最初的问题是list.index并不像你想象的那样-它不会给出当前项的索引,而是搜索匹配项并给出该索引。例如:
row = [1, 1, 1, 1, 1]
print(row[4], row.index(row[4]))
打印10
,而不是14
。您的userinfo文件包含两个包含“admin”的字段,因此您将获得两个与密码匹配的字段
获取当前字段索引的最佳方法是使用enumerate
for currentindex, field in enumerate(row):
重写login()函数使其更具可读性,我认为您打算执行以下操作:
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)
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()
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
从当前函数调用下一个函数的方式也有问题。e、 例如,如果反复输入错误的密码,则会得到以下函数调用链:
main -> welcomemenu -> login -> welcomemenu -> login -> welcomemenu ->
login -> welcomemenu -> login -> welcomemenu -> login -> welcomemenu ->
login -> welcomemenu -> login -> welcomemenu -> login -> welcomemenu etc
这种模式迟早会给你带来问题。相反,尝试安排对“扇出”的函数调用,如下所示:
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)
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()
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)等
我认为你应该使用数据库(如果这是一个轻型应用程序,可能是sqlite)来存储用户名和密码。我不想使用数据库。这是用于教学和学习的目的,需要解决,因为isIs现在已经修复了吗?这是一个有用的帖子,谢谢。如果你能分析代码中的奇怪错误,我可以接受你的答案。你也可以编辑你的答案,包括用户名和密码搜索。更新:这似乎可行…(在循环出现时),但如果组合错误,它仍然不会说“无效”:Sam Chats-谢谢,但与萨克森州的Rolf的答案类似,它似乎可行,但无法进一步测试。试试这个(它在登录功能中包含您的代码)…首先将用户名和密码弄错,然后继续将其弄错,并使用游戏和测验功能。您会注意到第二次它仍然错误地返回到登录函数!为什么?你还接到了whileloop中主菜单的呼叫,并清除了标志。我认为这并不理想?Saxony的repl.it/KdEI/4 Rolf解决方案似乎最接近,但当您第一次尝试时用户名和密码出错时,仍然不起作用。然后通过admin和admin123,您会注意到错误…它从quiz1函数返回,位于登录函数53中感谢您neh。如果您能够查看该链接,它将向您显示,即使删除f.close(),错误(跳回第48行)仍然存在。请参阅更新-从while循环中删除的主菜单调用,这会有所帮助。仍然需要修复。这是因为当你需要一个循环时,你有两个循环。。。不需要第二个循环。不必检查行(0到4)的每个字段,只需检查行[0]和行[1],我将添加更优雅的解决方案,看看是否有帮助。。。如果没有,请告诉我。谢谢neh-但我正在尝试修复现有的解决方案。这是Sam Chat的解决方案-请参阅上面的帖子以获取我的评论。它似乎可以工作,但如果你第一次把用户名和密码弄错了,它就不能工作。此外,他还接到了whileloop内主菜单的电话,并清除了旗帜。我不认为那是理想的。。。这是登录功能中与您的解决方案的链接。它似乎可以工作,但用以下方法测试它:首先将用户名和密码弄错,然后再次检查并转到测验函数=您将看到它再次返回到登录函数。。。!有什么想法吗?我明白你的意思,但问题仍然没有完全解决……exit()只是关闭整个程序并强制退出。我只想让它在命令提示下停止?您可以使用命令行上的-I
(减号眼)选项在交互模式下运行脚本,但我看不到结果。顺便说一句,取消已授予的声誉积分并对现有问题增加进一步要求是不可取的。你当然可以接受另一个答案,如果它更适合你的问题。如果是这样,我鼓励你这样做。