2017-07-27 46 views
2

我制作了一个程序,用于存储您输入的登录详细信息,并允许您将其登录到菜单的主要部分。例如,当所有数据类型都是字符串时,一切正常; modea = input("Etc")允许用户通过输入对应于该选项的数字输入来选择选项,例如“2”,则它应当在满足if modea == 2语句时调用其分配的功能,但是如果我尝试将字符串更改为整数数据类型,例如modea = int(input("Etc")),即使我要输入预期的输入,循环也不会停止并继续运行,就像我没有输入任何内容一样,与仅使用modea = input("etc")的地方相反,它将所有内容视为字符串,它仍然接受数字输入并执行其输入分配的动作,但不是如果数据类型是一个整数?Python:无法使用不同类型的变量终止循环

我在这里添加了完整的代码,使它更有意义,大多数可以忽略,因为它按预期运行,但我似乎无法弄清楚代码的logged()函数部分发生了什么我试图通过在if语句被满足时终止其循环来获得modea = int(input("etc"))的工作,但它只是继续循环,就好像一切都是空的。帮助将不胜感激。

#import modules 
import time 
import sys 
import re 

#Initialise variables that could help with error handling 
name = "" 
mode = "" 
username = "" 
password = "" 
addusername = "" 
addpassword = "" 
exit = "" 
modea = "" 
new_app = "" 
new_pass = "" 
quit = "" 

#Dictionary to store more than one set of login details 
vault = {} 

#Lists to store website names and passwords 
appvault = [] 
passvault = [] 


#FIRST MENU AND REGISTERING LOGIN DETAILS ----------------------------------------------------------------------------------------------------------------------------------------- 

def menu(): #The menu function is the 1st menu that asks the user to either register their login details or to login with existing login details saved into the vault dictionary 
    print("--------------------------*ENTERING THE MAIN MENU*-----------------------------------\n") #triple """ used to effectively format the menu 
    mode = input(str("""Hello {}, below are the modes that you can choose from:\n 
    ########################################################################## 
    a) Login with username and password 
    b) Register as a new user 
    To select a mode, enter the corresponding letter of the mode below 
    ##########################################################################\n 
    > """.format(name))).strip() #greets user and removes any white space 
    return mode #returns the input 

def login(username, password): #The login function is where the user logins in with existing registered details in the vault dictionary 
    if len(vault) > 0 : #user has to append usernames and passwords before it asks for login details 
     print("Welcome {} to the login console".format(name)) 
     noloop = True #Starts a loop if True will begin looping 
     while noloop: 
      addusername = input("Please enter username: ") 
      if addusername == "": 
       print("Username not entered, try again!") 
       continue #returns to the beginning of the while loop if null 
      addpassword = input("Please enter password: ") 
      if addpassword == "": 
       print("Password not entered, try again!") 
       continue #returns to the beginning of the while loop if null 
      try: 
       if vault[addusername] == addpassword: #If the username and password match with the login details appended into the dictionary, it will count as matching details. 
        print("Username matches!") 
        print("Password matches!") 
        print("Logging into password vault...\n") 
        noloop = logged() #jumps to logged function and tells the user they are logged on 
        return noloop #to return the noloop depending on users option (True or False) 
      except KeyError: #the except keyerror recognises the existence of the username and password in the list 
       print("The entered username or password is not found!") 

    else: 
     print("You have no usernames and passwords stored!") #When the user selects option A before adding any login details to the dictionary 
     return True #returning to the start of the loop when the else statement is printed 

def register(): #example where the username is appended. Same applies for the password 
    global username #initialises global variables 
    global password 
    print("Please create a username and password into the password vault.\n") 

    while True: 
     validname = True #whileloop will loop the username variable and while True it runs the loop 
     while validname: 
      username = input("Please enter a username you would like to add to the password vault. NOTE: Your username must be at least 3 characters long: ").strip().lower() 
      if not username.isalnum(): #handles usernames with no input, contain spaces between them or have symbols in them. 
       print("Your username cannot be null, contain spaces or contain symbols \n") 
      elif len(username) < 3: #any username with less than 3 characters is rejected and looped back 
       print("Your username must be at least 3 characters long \n") 
      elif len(username) > 30: #any username with more than 30 characters is rejected and looped back 
       print("Your username cannot be over 30 characters long \n") 
      else: 
       validname = False #whileloop is False will mean the loop will break and proceed onto asking password 
     validpass = True #whileloop will loop the password variable and while True it runs the loop 

     while validpass: 
      password = input("Please enter a password you would like to add to the password vault. NOTE: Your password must be at least 8 characters long: ").strip().lower() 
      if not password.isalnum(): #handles null input passwords, passwords that contain spaces or symbols 
       print("Your password cannot be null, contain spaces or contain symbols \n") 
      elif len(password) < 8: #passwords that are less than 8 characters long are rejected and loops back 
       print("Your password must be at least 8 characters long \n") 
      elif len(password) > 20: #passwords that are more than 20 characters long are rejected and loops back 
       print("Your password cannot be over 20 characters long \n") 
      else: 
       validpass = False #The validpass has to be True to stay in the function, otherwise if it is false, it will execute another action, in this case the password is appended. 
     vault[username] = password #the appending process of username and passwords to the dictionary 
     validinput = True #whileloop asking for the user if they want to quit or add more login details 
     while validinput: 
      exit = input("\nDo you want to register more usernames and passwords? Enter 'end' to exit or any key to continue to add more username and passwords:\n> ") 
      if exit in ["end", "End", "END"]: #if input matches these conditions, the loop will then break and thus jump back to the main menu 
       return #returns outputs to the called function 
      else: 
       validinput = False #if user decides not to quit and to add more login details, then register is called and the process of asking for login input repeats 
       register() 
     return register #returns login details to the function 


#LOGGED ONTO THE PASSWORD AND WEBSITE APP ADDING CONSOLE------------------------------------------------------------------------------------------------------------------------ 

def logged(): #The logged function is the 2nd menu where the user is able to access after logging in with their registered login details 
    print("-----------------------------*ENTERING THE PASSWORD VAULT MENU*-----------------------------------\n") 
    print("You are logged in, welcome to the password vault console.") 
    keeplooping = True #whileloop that is True will keep the menu in a loop 
    while keeplooping:  
     try: 
      modea = int(input("""Below are the options you can choose from in the password vault console: 
      ##########################################################################\n 
      1) Find the password for an existing website/app 
      2) Add a new website/app and a new password for it 
      3) Summary of the password vault 
      4) Exit 
      ##########################################################################\n 
      > """)) 
     except ValueError: 
      print("Please enter a valid option!") 

    if modea == 1: #if the user enters 1 as instructed, then they have decided to choose to find existing apps and passwords 
     viewapp() #viewapp function is called 

    elif modea == 2: #if user enters 2 as instructed, then they have decided to add new app/websites and the passwords for it 
     addapp() #addapp function is called 

    elif modea == 3: #if the user enters 3 as instructed, then they have decided to look at the summary of passwords entered so far 
     summary() #summary function is called 

    elif modea == 4: #if the user enters 4 as instructed, then they have deicided to quit the entire program. All loops stop and program ends with print statement saying "Goodbye" 
     keeplooping = False 
     print("*Exiting program*\n") 
     time.sleep(2) 
     print("############################################################") 
     print("Goodbye user and thanks for using the password vault program") 
     print("############################################################") 
     return keeplooping 
    else: 
     print("That was not a valid option, please try again: ") 
     validintro = False 


def viewapp(): #The viewapp function is the 1st option of the password and vault menu that allows the user to view the app/websites and passwords stored so far 
    if len(appvault) > 0: #The website/apps and passwords are only shown once the user has entered a set of the info, otherwise no info will be shown 
     print("""Below are the details of the website/apps and passwords stored so far: 
(NOTE: Websites/apps and passwords are shown in order of being appended; 1st password is for 1st website, etc...\n""") 
     for app in appvault: 
      print("Here are the website/app you have stored:") 
      print("- {}\n".format(app)) #Website/app is printed out here 
    if len(passvault) > 0 : #The website/apps and passwords are only shown once the user has entered a set of the info, otherwise no info will be shown 
     for code in passvault: 
      print("Here are the password you have stored for the websites/apps: ") 
      print("- {}\n".format(code)) #The passwords are printed out here 

    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: #if the user enters a website with more than 20 characters, it is rejected and loops back and asks for input again 
       print("Please enter a new website/app name with no more than 20 characters: ") 
      elif len(new_app) < 1: #if the user enters nothing, program loops back and asks for input again 
       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: ").strip() 
      if not new_pass.isalnum(): #checks if the entered username has spaces, or symbols or is a null input, which would be rejected and the program will loop back 
       print("Your password for the website/app cannot be null, contain spaces or contain symbols \n")    
      elif len(new_pass) < 8: #the password must be at least 8 characters long to be accepted as valid 
       print("Your new password must be at least 8 characters long: ") 
      elif len(new_pass) > 20: #the password must not exceed 20 characters, otherwise it would be rejected and will loop back 
       print("Your new password cannot be over 20 characters long: ") 
      else: 
       validnewpass = False 
       passvault.append(new_pass) 

     validquit = True 
     while validquit: 
      quit = input("\nDo you want to enter more websites/apps and passwords? Enter '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"]: 
       return 
      else: 
       validquit = False 
       addapp() 
      return addapp   

def summary(): #The summary function is a print statement of how many password have been stored, the passwords with the longest or shortest characters are also displayed 
    if len(passvault) > 0: #The user must have entered at least 1 password before the summary option can be viewed 
      print("----------------------------------------------------------------------") 
      print("Here is a summary of the passwords stored in the password vault:\n") 
      print("The number of passwords stored so far:", len(passvault)) #len counts the amount of passwords stored in the passvault list 
      print("Passwords with the longest characters: ", max(new_pass for (new_pass) in passvault)) #max finds the passwords appended in the passvault list with the longest password 
      print("Passwords with the shortest charactrs: ", min(new_pass for (new_pass) in passvault)) #min finds the passwords appended in the passvault list with the shortet password 
      print("----------------------------------------------------------------------") 
    else: 
     print("You have no passwords entered yet!")  

#Main routine 
print("Welcome user to the password vault program") 
print("In this program you will be able to store your usernames and passwords in password vaults and view them later on.\n") 
validintro = False 
while not validintro: 
    name = input(str("Greetings user, what is your name?: ")).lower().strip() 
    if not re.match("^[a-z]*$", name): 
     print("Your name must only contain letters from a-z: ") 
    elif len(name) < 1: 
     print("Please enter a name that is valid: ") 
    elif len(name) > 30: 
     print("Please enter a name with no more than 30 characters long: ") 
    else: 
     validintro = True 
     print("Welcome to the password vault program {}.\n".format(name)) 

#The main program to run in a while loop for the program to keep on going back to the menu part of the program for more input till the user wants the program to stop 
validintro = False 
while not validintro: 
     chosen_option = menu() 
     validintro = False 

     if chosen_option in ["a", "A"]: 
      validintro = not login(username, password) 

     elif chosen_option in ["b", "B"]: 
      register() 

     else: 
      print("""That was not a valid option, please try again:\n """) 
      validintro = False 

回答

2

您有一个缩进错误。

您的while keeplooping:循环logged()只包含try/except块,因此它一直保持循环。我想你想缩进它下面的if声明。

编辑基于评论:

当你try/except达到except它打印语句,然后不断去。您没有在except语句中包含任何内容来告诉while循环重新开始。由于modea的分配失败,因此未尝试引用该分配并导致错误。如果您想尝试另一种输入时,用户将在一个糟糕的值,你可以使用continue

except ValueError: 
     print("Please enter a valid option!") 
     continue 

这将导致整个指令串再次打印 - 有可能是一个更好的逻辑,但至少这会防止错误。

+0

糟糕对不起,我认为缩进错误来自以前的register()函数,因为我可能粘贴它不正确,但至于缩进if语句,它提出了错误消息“UnboundLocalError:本地变量”modea'之前引用分配”。 – Shad342

+0

@ Shad342啊是的,看到更新。 –