2017-06-23 316 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循環中處理。