我正在编写一个程序来模拟银行业务情景。它允许用户(一旦他们登录)显示他们的余额,提取和存款,并最终包含一个转移子程序。
我的问题是登录子程序。我无法让我的代码循环遍历保存它们的元组中的两个帐户。我可以登录到第一个帐户并使用该帐户执行所有代码的功能但是当我尝试访问第二个帐户时,我收到错误消息,告诉我该帐户未找到。我非常肯定这与我编写循环的方式有关,但我无法弄清楚如何修复它。
如果有人可以提供我可以用来修复此错误的解决方案,那么我将非常感激。如果有可能,解决方案是否也能坚持我的代码的一般格式,而不是我必须创建新函数并更改LogOn函数的整个主体?
以下是代码:
accounts=[
["Luke",'00001','1234',1337],
["Louis",'00002','4321',420],
]
name = ""
x = []
def LogOn():
global name
global x
print ("Welcome to the Bank of Bailey")
accnum = raw_input("-please enter your account number-")
if len(accnum) != 5:
print("That number is not valid, please enter a valid number")
LogOn()
else:
for x in range(0,len(accounts)):
if accnum in accounts[x][1]:
name = accounts[x][0]
print ("Account found")
pin = raw_input("-please enter your pin-")
if pin in accounts[x]:
print ("Pin found")
MainMenu()
else:
print("Pin not found")
print("Please try again")
LogOn()
break
else:
print("Account not found")
print("Please try again")
LogOn()
答案 0 :(得分:2)
问题是:
if accnum in accounts[x][1]:
do something
else:
print("Account not found")
print("Please try again")
LogOn()
在第一次迭代中已经调用了else分支(x = 0)! 如果找到了帐户,您应该在while循环后检查,否则会打印出错误消息。
您可以更好地使用调用LogOn()
的外部(无限)while循环,而不是递归到LogOn()
。在LogOn中,只需在错误情况下执行return
。
答案 1 :(得分:1)
一些观察结果:
希望有所帮助!
accounts=[
["Luke",'00001','1234',1337],
["Louis",'00002','4321',420],
]
name = ""
x = []
def LogOn():
global name
global x
print ("Welcome to the Bank of Bailey")
accnum = raw_input("-please enter your account number-")
if len(accnum) != 5:
print("That number is not valid, please enter a valid number")
LogOn()
else:
found = False
for account in accounts:
if accnum == account[1]:
found = True
name = account[0]
print ("Account found")
pin = raw_input("-please enter your pin-")
if pin in account[2]:
print ("Pin found")
MainMenu()
else:
print("Pin not found")
print("Please try again")
LogOn()
break
if not found:
print("Account not found")
print("Please try again")
LogOn()
答案 2 :(得分:1)
我喜欢@TimSC的答案,但我会再添加一些观察结果:
LogOn
不是一个好的功能名称;应该log_on
匹配PEP8 naming conventions(LogOn
表明它是一个类而不是一个函数。)
您将name
和x
声明为全局变量,然后永远不会使用它们。全局几乎总是一个坏主意,未使用的声明只会使你的代码混乱。
正如@CTX指出的那样,你正在使用递归(LogOn
调用LogOn
调用MainMenu
调用LogOn
等等,其中迭代会更有意义 - 你应该退出错误,不要再打电话给更深层次了。
混合输入/输出代码和动作代码通常是一个错误的决定;它使您的代码不那么灵活和可重用,并且通常也更难调试。您应该使用输入/输出函数来调用具有所需值的动作函数。
针对不良帐号给出单独的错误消息,坏针号是一个安全漏洞;它使潜在的攻击者更容易找到有效的帐号进行攻击。
在列表中查找相对较慢(O(n)
,即时间与列表中的项目数成比例)。改为使用dict(O(1)
即恒定时间 - 快速哈希计算会将您带到您正在寻找的项目。
这是一个幻想的版本;它可以给你一些思考的东西:
import sys
# version compatibility shim
if sys.hexversion < 0x3000000:
inp = raw_input # Python 2.x
else:
inp = input # Python 3.x
class Account:
index = {}
__slots__ = ("accnum", "pin", "name", "balance")
@classmethod
def log_in(cls, accnum, pin):
key = (accnum, pin)
acc = Account.index.get(key, None)
if acc is None:
raise ValueError("No such login (bad account# or PIN)")
else:
return acc
def __init__(self, accnum, pin, name, balance):
# save values
self.accnum = accnum
self.pin = pin
self.name = name
self.balance = balance
# add self to account index
key = (accnum, pin)
Account.index[key] = self
# create accounts
Account('00001', '1234', "Luke", 1337)
Account('00002', '4321', "Louis", 420)
def main():
while True:
print("\nWelcome to the Bank of Bailey")
accnum = inp("Please enter your account number: ").strip()
pin = inp("Please enter your PIN: ").strip()
try:
acc = Account.log_in(accnum, pin)
print("\nYour account has a current balance of ${:0.2f}".format(acc.balance))
print("Thank you for banking with us!")
except ValueError as ve:
print(ve)
if __name__ == "__main__":
main()