2017-06-23 313 views
1

我想完成我的程序我添加一个菜单,允许用户选择几个选项,允许用户在列表中存储网站名称和密码。但是,当我将一些网站名称和密码附加到它们各自的保管库时,出现了一个问题,当我尝试在追加网站名称和密码后选择一个选项时,例如“1”是预期的输入以调用viewapp( )功能来查看迄今存储的网站和密码。事情是调用viewapp()函数需要两次以上的时间,它会拒绝第一个期望的输入,但会奇怪地接受第二个输入。同样,当我选择第三个选项来调用summary()时,整个打印的摘要将打印两次,这与菜单中仅接受第二个预期输入的模式类似。该程序正在做我想做的事情,除了这个恼人的bug之外,在选择这四个选项时,它会在第二次请求输入时立即跳转到该函数。帮助将不胜感激。Python:被要求输入两次并输出重复的打印语句

appvault = [] 
passvault = [] 

def logged(): 
    print("----------------------------------------------------------------------\n") 
    print("Hello, welcome to the password vault console. ") 
    modea = input("""Below are the options you can choose from in the password vault console: 
    ##########################################################################\n 
    1) Find the password for an existing webiste/app 
    2) Add a new website/app and a new password for it 
    3) Summary of the password vault 
    4) Exit 
    ##########################################################################\n 
    > """).strip() 
    return modea 

def viewapp(): 
    if len(appvault) > 0: 
     for app in appvault: 
      print("Here is the website/app you have stored:") 
      print("- {}\n".format(app)) 
    if len(passvault) > 0 : 
     for code in passvault: 
      print("Here is the password you have stored for the website/app: ") 
      print("- {}\n".format(code)) 

    else: 
     print("You have no apps or passwords entered yet!") 

def addapp(): 
    while True: 
     validapp = True 
     while validapp: 
      new_app = input("Enter the new website/app name: ").strip().lower() 
      if len(new_app) > 20: 
       print("Please enter a new website/app name no more than 20 characters: ") 
      elif len(new_app) < 1: 
       print("Please enter a valid new website/app name: ") 
      else: 
       validapp = False 
       appvault.append(new_app) 

     validnewpass = True 
     while validnewpass: 
      new_pass = input("Enter a new password to be stored in the passsword vault: ") 
      if not new_pass.isalnum(): 
       print("Your password for the website/app cannot be null, contain spaces or contain symbols \n")    
      elif len(new_pass) < 8: 
       print("Your new password must be at least 8 characters long: ") 
      elif len(new_pass) > 20: 
       print("Your new password cannot be over 20 characters long: ") 
      else: 
       validnewpass = False 
       passvault.append(new_pass) 

     validquit = True 
     while validquit: 
      quit = input("\nEnter 'end' to exit or any key to continue to add more website/app names and passwords for them: \n> ") 
      if quit in ["end", "End", "END"]: 
       logged() 
      else: 
       validquit = False 
       addapp() 
      return addapp   

def summary(): 
    if len(passvault) > 0: 
     for passw in passvault: 
      print("----------------------------------------------------------------------") 
      print("Here is a summary of the passwords stored in the password vault:\n") 
      print("The number of passwords stored:", len(passvault)) 
      print("Passwords with the longest characters: ", max(new_pass for (new_pass) in passvault)) 
      print("Passwords with the shortest charactrs: ", min(new_pass for (new_pass) in passvault)) 
      print("----------------------------------------------------------------------") 
    else: 
     print("You have no passwords entered yet!") 

while True:   
    chosen_option = logged() 
    print(chosen_option) 
    if chosen_option == "1": 
     viewapp() 

    elif chosen_option == "2": 
     addapp() 

    elif chosen_option == "3": 
     summary() 

    elif chosen_option == "4": 
     break 
    else: 
     print("That was not a valid option, please try again: ") 

print("Goodbye") 

回答

2

这是因为你叫logged()退出addapp()时:

if quit in ["end", "End", "END"]: 
    logged() 

然后,进入选择由logged()返回,并扔掉,因为它没有分配到任何东西。

你现在回到前面的块的addapp()结束,下一个指令是return addapp,将带你回到你的主循环,在那里你会被chosen_option = logged()

再次发送到 logged()

请注意,在return addapp中,您返回addapp函数本身,这当然不是您想要执行的操作。因此,因为addapp()不需要返回值,只需使用return,或者根本不使用,Python将在函数结束时自动返回。

所以,解决你的问题:直接return,当你完成输入网站:

if quit in ["end", "End", "END"]: 
    return 

还请注意,您递归调用与自身addapp()当你添加更多的网站。
除非你真的想使用递归算法,而应该像在主循环中那样使用循环,否则你应该避免这种情况。默认情况下,巨蟒限制你到1000级递归的水平 - 这样,你甚至可以通过连续输入超过1000个站点崩溃的应用程序;)

摘要问题是由不必要for回路summary()

不仅造成
1

你快到了。问题是在addapp()函数在63行:

if quit not in ["end", "End", "END"]: 
    logged() 

如果更换

logged() 

pass 

那么一切都将工作正常。 无论如何,您并没有处理记录函数的结果。 您也不需要在这里处理记录的功能。 addapp将退出并且记录的函数将被调用,并在调用addapp函数的while循环中处理。