While loop to maximise password attempts - Python 3 - python

I'm practising my coding - pretty new to this - and i'm trying to create a login system, all is working well so far but i'm trying to use a while loop to maximise the number of user attempts at inputting the correct password. Even if the user inputs the correct password, the loop will carry on until the loop is completed and will continue to say carry on.
login = {
"alex": "dog123"
}
passkey = login.values()
correct_user = True
while correct_user:
user = input("Please input your username ")
if user in login:
print(f'Hello {user}, please input your password.')
correct_user = False
else:
print("Invalid user")
attempt = 0
max_attempts = 3
correct_password = True
while correct_password:
password = input(">")
if password in passkey:
print(f"""Welcome back {user}!
How can i help you today?""")
correct_password = False
else:
while attempt < max_attempts:
print("try again")
attempt += 1
password = input(">")
if password in passkey:
correct_password = False
else:
print("too many guesses!")
break

Try this.
login = {
"alex": "dog123"
}
passkey = login.values()
correct_user = True
while correct_user:
user = input("Please input your username ")
if user in login:
print(f'Hello {user}, please input your password.')
correct_user = False
else:
print("Invalid user")
attempt = 0
max_attempts = 3
correct_password = True
while correct_password:
if attempt < max_attempts: # checks if an attempt is left.
password = input(">")
if password == login[user]: # Check password equal current userpassword.
print(f"""Welcome back {user}!
How can I help you today?""")
correct_password = False
else:
print("Invalid password")
attempt += 1
else: # print too many attempts
print("Too many attempts")
correct_password = False
Don't use password in passkey to check that if password is correct or not. Why?
Explanation
Let say you have more than one users
login = {
"alex": "dog123",
"alice": "cat123"
}
If you use in and check that if password is in passwords list then you face a bug
When
Example
If user is equal alex and password is cat123 then you code don't print that password is incorrect.
So use == and check if password == login[user] here user and password are the one that user enters.
"#alex comments. what does the '[user]' aspect mean?".
#alex if you want all values from the dictionary then you use dict.values(), But if you want a specific key's value then you use dict['Key'] or dict.get('Key'). Let's say user='alex' then login[user] gives the value of the user from the login dict which is 'dog123'. Note if the user is not in the dict then it will give you a KeyError. But if you use dict.get(user) it will return the value of user or None if user is not in dict

Your error comes from breaking out of the inner while loop but still having the outer one running; it's better to use only one loop (and you don't need the 'correct_password' flag any more):
attempt = 0
max_attempts = 3
passkey = ['sesame']
while attempt < max_attempts:
password = input(">")
if password in passkey:
print(f"""Welcome back {user}! How can i help you today?""")
break
else:
attempt += 1
if attempt < max_attempts:
print("try again")
else:
print("too many guesses!")
As a side note, codester_09 is right about the way you check the password, so implement their modification too.

Related

How to write a script that only allows a limited number of attempts to input something correctly?

What should I be using when I want the following program to, after 2 wrong attempts and one (last) correct attempt, not to lock the account?
I am using the following code for a program that asks the user for a password, if the password is correct it accepts the password, if not says "try again" and if there are 3 attempts it says account is locked, but my problem is that even if there are two wrong attempts and one correct attempt, it'll still say "account is locked". What should I be doing differently?
count = 0
while True:
password = input("Password: ")
count += 1
if count == 3:
print("account locked")
break
else:
if password == 'blue':
print("password accepted")
break
else:
print("wrong password, try again")
As the comment states, you should only be incrementing if the password is incorrect.
I do think, however, it's also worth pointing out that the use of while True + break can make your code harder to read, and is usually worth avoiding if you have some explicit condition you want to break on. That makes it easier for you and others to debug your code.
In this case, you only want to prompt for the password while the correct password hasn't been entered and three attempts haven't been used. So, you can make that condition explicit, like so:
count = 0
correct_password_entered = False
while not correct_password_entered and count < 3:
password = input("Password: ")
if password == 'blue':
print("password accepted")
correct_password_entered = True
else:
print("wrong password, try again")
count += 1
if count == 3:
print('account locked')
Had a different approach to your problem. I also added a message saying how many more attempts are left before the account locks.
count = 3
pwd = 'blue'
while count > 0:
count -= 1
password = input("Password: ")
if password == pwd:
print("password accepted")
break
else:
print("wrong password, try again")
print(f"You have {count} attempts left.")
if count == 0:
print("You have been locked out.")
The other answers are correct and I'm not adding a "better" solution, just a different one, so if you accept an answer I think it should be one of them.
I'd just like to take this opportunity to show a different approach using the lesser known for-else construct, as I think this would be a perfect fit here and may be a bit more pythonic.
for i in range(3):
password = input("Password: ")
if password == "blue":
print("password accepted")
break
else:
print("wrong password, try again")
else:
print("account locked")
The else part of a for loop will execute if the loop ran through without breaking.
I also changed some parts in my 1st code, I think it should be alright now.
count = 1
while True:
password = input("Password: ")
if password == '456':
print('password accepted')
break
else:
if count == 3:
print('access locked')
break
else:
print('wrong-try again')
count += 1

Python, Username and Password with 3 attempts

I have started learning python about 2 weeks ago and am trying to create a password system that can store multiple usernames and passwords. I am trying to add a bit of code where it makes you wait a minute if you input a wrong password 3 times.
I keep on getting an error where if you get the password wrong 3 times and wait the 60 seconds, even if you do input the right password and username it prints "Your password is wrong. You have only 3 attempts left."
Can somebody help and point out flaws that I have in the code?
import time
username = ["Test","Test2"]
password = ["1Ac!","2Bd!"]
success = 0
Tries = 0
Valid = False
Pass = ""
def login():
global success
global Pass
global Tries
inuser = input(str("Enter your username: \n"))
inpass = input(str("Enter your password: \n"))
if inuser not in username:
print("username not found in directory")
login()
else:
posUser = username.index(inuser)
Pass = password[posUser]
while success != 1:
if Tries == 3:
print("You have had too many attempts. Wait 60 seconds before trying again")
for i in range(60, 0, -1):
time.sleep(1)
print(i)
if Tries == 3:
Tries = 0
inuser=str("0")
inuser=str("0")
login()
else:
break
if Pass == inpass:
success=1
else:
Tries += 1
AttemptsLeft = (3 - Tries)+ 1
print("Your password is wrong. You have only {} attempts left.".format(AttemptsLeft))
login()
login()
if success==1:
print("Welcome to ------")
If you get rid of the recursion, everything will get simpler.
import time
username = ["Test","Test2"]
password = ["1Ac!","2Bd!"]
success = 0
Tries = 0
Valid = False
Pass = ""
def login():
global success
global Pass
global Tries
while success != 1:
inuser = input(str("Enter your username: \n"))
inpass = input(str("Enter your password: \n"))
if inuser not in username:
print("username not found in directory")
else:
posUser = username.index(inuser)
Pass = password[posUser]
if Tries == 3:
print("You have had too many attempts. Wait 60 seconds before trying again")
for i in range(60, 0, -1):
time.sleep(1)
print(i)
Tries = 0
inuser=str("0")
inuser=str("0")
if Pass == inpass:
success=1
elif Pass != "":
Tries += 1
AttemptsLeft = (3 - Tries)+ 1
print("Your password is wrong. You have only {} attempts left.".format(AttemptsLeft))
login()
if success==1:
print("Welcome to ------")
You should also consider getting rid of the global variables. Instead, return values using return.
import time
username = ["Test","Test2"]
password = ["1Ac!","2Bd!"]
success = 0
Tries = 0
Valid = False
Pass = ""
def login():
success = 0
Pass = ""
Tries = 0
while success != 1:
inuser = input(str("Enter your username: \n"))
inpass = input(str("Enter your password: \n"))
if inuser not in username:
print("username not found in directory")
else:
posUser = username.index(inuser)
Pass = password[posUser]
if Tries == 3:
print("You have had too many attempts. Wait 60 seconds before trying again")
for i in range(10, 0, -1):
time.sleep(1)
print(i)
Tries = 0
inuser=str("0")
inuser=str("0")
if Pass == inpass:
return True
elif Pass != "":
Tries += 1
AttemptsLeft = (3 - Tries)+ 1
print("Your password is wrong. You have only {} attempts left.".format(AttemptsLeft))
if login():
print("Welcome to ------")
Your code needed some refining. I also made a timer for stopping. Also, you should use getpass library to not show the password.
import time
import getpass
username = ["Test","Test2"]
password = ["1Ac!","2Bd!"]
Tries = 1
def login():
global Tries
print("\n----------------- Login -----------------------\n")
inuser = input("Enter your username: ")
inpass = getpass.getpass("Enter your password: ")
if inuser not in username:
print(f"User {inuser} was not found.")
login()
else:
xindex=username.index(inuser)
passw=password[xindex]
if inpass==passw:
return True
else:
if Tries==3:
print("\nToo many attempts. Please wait for 60 seconds.")
for k in range(x,0,-1):
b=f"Time left: {k} Seconds"
print(b,end="\r")
time.sleep(1)
Tries=0
login()
else:
Tries+=1
print("\nWrong Password or Username.")
login()
x=login()
if x:
print("Welcome to ---------")
Others have provided the solution, I will try to provide the reasoning:
This is because of the recursion in line number 38 where you're calling the login function after setting Tries=0.
When the recursive call is made, the compiler puts the rest of the statements below it on hold (you can imagine all the below statements pushed to a stack to be executed later). The program counter now goes to the start of the function: Where you'll enter the right username and password, therefore it sets the success variable to 1. Now that your function has completed, the compiler had a set of pending statements before remember?
It goes and executes them. But in there, the value of the variable inpass is still the old, incorrect one and that is why it prints out Wrong password. You can understand this by printing out inpass just before the line
if Pass == inpass:
TlDr; Get rid of the recursion

Need help defining a list without changing the value it already has

Ok, I'm pretty new to python and I was trying to see if I could make a simple login/register system that just uses usernames and passwords. I added this at the start of the code so I didn't have to manually restart it every time I want to test something:
loop = True
while loop == True:
then, I made two lists called 'accountUsernames' and 'accountPasswords' with just a couple of random usernames and passwords. The idea was that every account would have its password and username index be the same, and the code would check if the username and password the user entered while logging in had the same index. When I started writing the code of the register system, I realized I was kind of stuck. I was using the append feature to add the username and password the user had entered into the previously mentioned lists, but when it did so, the code would loop back to the start because it was over, meaning the lists would also be changed to their previous state. I was wondering if there was a way I could define those lists at the start without giving them any values, or changing the values it already has from the previous loop. Here's the full code:
loop = True
while loop == True:
accountUsernames = ['a', '1']
accountPasswords = ['b', '2']
lr = input('Would you like to login or register?\n')
if lr.lower() == 'login':
loginUsername = input('Please enter your username.\n')
loginPassword = input('Please enter your password.\n')
if loginUsername in accountUsernames:
loginIndex = accountUsernames.index(loginUsername)
if accountPasswords[loginIndex] == loginPassword:
print('You have successfully logged in!')
else:
print('Invalid username or password. Please try again.')
else:
print('Invalid username or password. Please try again.')
elif lr.lower() == 'register':
registerUsername = str(input('Please enter a username.\n'))
registerPassword = str(input('Please enter a password.\n'))
registerPasswordConfirmation = str(input('Please confirm your password.\n'))
if registerUsername in accountUsernames:
print('That username is already taken. Please try again.')
elif registerPassword != registerPasswordConfirmation:
print('These passwords do not match. Please try again.')
else:
accountUsernames.append(registerUsername)
accountPasswords.append(registerPassword)
print('You have successfully registered! You can now log in.')
I know it probably has a lot of glaring issues but as I said, I'm pretty new to python. Also, sorry if I over/under-explained the issue. I would really appreciate your help.
I don't really understand the question, but why don't you define the accountUsernames and accountPasswords before the loop starts, like this:
accountUsernames=[]
accountPasswords=[]
while loop:
#insert loop code here
Another suggestion that you should implement is instead of having two lists, to have a dictionary.
userData={}
def addUser(username, password):
global userData
userData[username]=password
def checkUser(username,password):
global userData
if username in userData:
if password==userData[username]:
return True
return False
loop=True
while loop:
#insert code
Just place the accountUsernames and accountPasswords lists outside the loop like this:
accountUsernames = ['a', '1']
accountPasswords = ['b', '2']
loop = True
while loop == True:
lr = input('Would you like to login or register?\n')
if lr.lower() == 'login':
loginUsername = input('Please enter your username.\n')
loginPassword = input('Please enter your password.\n')
if loginUsername in accountUsernames:
loginIndex = accountUsernames.index(loginUsername)
if accountPasswords[loginIndex] == loginPassword:
print('You have successfully logged in!')
else:
print('Invalid username or password. Please try again.')
else:
print('Invalid username or password. Please try again.')
elif lr.lower() == 'register':
registerUsername = str(input('Please enter a username.\n'))
registerPassword = str(input('Please enter a password.\n'))
registerPasswordConfirmation = str(input('Please confirm your password.\n'))
if registerUsername in accountUsernames:
print('That username is already taken. Please try again.')
elif registerPassword != registerPasswordConfirmation:
print('These passwords do not match. Please try again.')
else:
accountUsernames.append(registerUsername)
accountPasswords.append(registerPassword)
print('You have successfully registered! You can now log in.')

Login using two Dictionary

def login():
while True:
username = input("Please enter your username or x to quit: ")
if username.casefold() == "x":
break
else:
password = input("\nPlease enter your password: ")
if username =="" or password =="":
print("You cannot leave this blank,Please try again.")
else:
if len(username)>0 and len(password)>0:
for i in memberDict:
if username == i and password == memberDict[i]:
print(f"Login successful, Welcome Member, {memberDict[i]}")
statuslist.append(0)
break
else:
for i in adminDict:
if username == i and password == adminDict[i]:
print(f"Login successful, Welcome Admin, {adminDict[i]}")
statuslist.append(1)
break
else:
print("Login failed, There is no registered customers. Please try again.")
I am trying to login via 2 different dictionaries. Dictionary works fine, just having issues having to read both of them and separate them as admin users or members
im trying to append 0 as member, 1 as admin.
if content of memberDict and adminDict do not duplicate, then you do need to go through all users in both dict to check if user exist, just use a found variable so it reduce time complexity from O(member) * O(admin) to O(member) + O(admin)
def login():
while True:
username = input("Please enter your username or x to quit: ")
if username.casefold() == "x":
break
else:
password = input("\nPlease enter your password: ")
if username =="" or password =="":
print("You cannot leave this blank,Please try again.")
else:
if len(username)>0 and len(password)>0:
found = False
for i in memberDict:
if username == i and password == memberDict[i]:
print(f"Login successful, Welcome Member, {memberDict[i]}")
statuslist.append(0)
found = True
break
for i in adminDict:
if username == i and password == adminDict[i]:
print(f"Login successful, Welcome Admin, {adminDict[i]}")
statuslist.append(1)
found = True
break
if not found:
print("Login failed, There is no registered customers. Please try again.")
The second "admin" loop appears within the member dict loop.
that is you should:
for i in memberDict:
if username == i and password == memberDict[i]:
print(f"Login successful, Welcome Member, {memberDict[i]}")
statuslist.append(0)
login=True
for i in adminDict:
if username == i and password == adminDict[i]:
print(f"Login successful, Welcome Admin, {adminDict[i]}")
statuslist.append(1)
login=True
if not login:
print("Login failed, There is no registered customers. Please try again.")
But in fact, you should probably not iterate over the dicts. you can tell if the key i is in dict memberDict or adminDict by
if i in memberDict:
if memberDict[i] == password:
# Display login message
and likewise for adminDict
edit for clarity:
What I meant to say is that you're trying to locate a key and value pair if it exists in your dicts. you do not need to iterate over the dicts (that is, use a for loop). You can find out if a key is in a dict (in your case, a username in a MemberDict by using if i in memberDict -> returns True if the key i is in the dict, false otherwise.

How to make my code break out of loop and actually detect a certain input

I am doing a basic Python assessment on a password vault but am getting errors that I can't seem to solve myself. and btw guys I didn't come here for a grammar and punctuation lesson, so if you are just here to edit my question and not offer any assistance please dont bother.
For example, in this part of the code I want the user to input 1 or 2, and if he selects 1 it asks him to log in, while if he selects 2 it asks him to register. But at the moment it is completely ignoring the parameters and accepting anything.
Another problem is that when the user enters the valid password, instead of just stopping at password correct, it for some reason re-asks "what is your username."
while True:
login_orsignup1 = input('''Press
1) to Log in
2) to register a new account
''')
if login_orsignup1 != 1:
while True:
username = input('''What is your,
Username: ''')
if input_username == username:
l_p = input('''What is your password ''')
while True:
if l_p == input_lockerpassword:
print("Password Correct")
break
login_originup1()
----------------------------------------------------------#Full code begins now
l_p = ""
print("------------------------------------------------------------------------")
print('''Welcome to password Locker, a place where you can
store all your passwords to easily enter your precious accounts without
hassle.''')
print("------------------------------------------------------------------------")
print('''First lets make an account,''')
while True:
first_name = input('''What is your first name?
''')
if first_name.isdigit(): #isdigit, detects if there
print("Please enter a valid answer, No nubers shoud be present")
elif first_name == "":
print("Please enter an answer")
#the continue code skips the boundries within the loop and carries on with the connected program until it is succesfully met
else:
break #the break loop exits the current loop and continues with the next programes following it
while True:
sur_name = input('''What is your surname?
''')
if sur_name.isdigit(): #isdigit detects if the
print("No numbers")
elif sur_name == "":
print("Please enter an answer")
#the continue code skips the boundries within the loop and carries on with the connected program until it is succesfully met
else:
break
print('''------------------------------------------------------------------------''')
print('''Welcome, {} {}
what would you like your username to be, it should be something
memorable and no longer than fifteen characters long, '''.format(first_name, sur_name))
while True:
input_username = input("")
if 0 < len(input_username) < 16:
print('''Nice, username''')
break
elif input_username == "":
print("Please enter an answer")
else:
print('''Your username should be a maximum of 15 charecters, ''')
print('''-------------------------------------------------------------------------''')
while True:
input_lockerpassword = input('''Now it's time to setup a password for your locker, It should be between 4
and 10 charecters long,
''')
if len(input_lockerpassword) > 4 and len(input_lockerpassword) < 11:
print('''{}, is locked in thanks for joining Password Locker'''.format(input_lockerpassword))
break
else:
print("It should be between 4 and 10 charecters long!")
print('''
-------------------------------------------------------------------------------------------''')
def login_originup1():
print(''' Welcome to password vault, You can either login or create a New account''')
while True:
login_orsignup1 = input('''Press
1) to Log in
2) to register a new account
''')
if login_orsignup1 != 1:
while True:
username = input('''What is your,
Username: ''')
if input_username == username:
l_p = input('''What is your password ''')
while True:
if l_p == input_lockerpassword:
print("Password Correct")
break
login_originup1()```
Ok, first of all, you should know that the input() function returns a string and, as such, your first condition : if login_orsignup1 != 1 will always be true, because the string object '1' isn't equal to the int object 1. As for why you get asked again for the user after having a good password, that is because the break statement only breaks from the current loop. So you only break of this loop to get back at the start of your username verification loop. I would suggest a cleaner implementation like so :
# login or sign-up loop
while True:
login_orsignup1 = input(" Press \n1) to Log in \n2) to register a new account")
# you can have the input result in a variable like so, if you want to use it later on
if login_orsignup1 == "1": # you said '1' was for login, right?
# or you can test this directly in your if statement
# if it is only needed for this condition
while input("What is your username: ") != username:
print("Incorrect username")
# same thing for password, but could be implemented another way if you
# don't want to loop until the user gets the correct password
while input("What is your password: ") != input_lockerpassword:
print("Incorrect password for this username")
# your code gets here only if the user entered the right credentials
# so you can now break of the login or sign-up loop
break
elif login_orsignup1 == "2":
# code for registration here
This could be good enough for a simple thing. I would recommend designing this console program by following concepts of a state-machine and adding more code at each step to handle cases like going back one step or back at the start.
Hope this helps
the problem is in your login_originup1 function you are making three While loops that the program can't escape from in your function you are asking if login_orsignup1 != 1
without an else statement so if the user wanted to login he would press input in "1" then the program will say that
"1" =! 1 is false
it will look for an else statement But not find one so it will go back to the start of the loop and ask the user to input again. this is it for the First Loop.
Now if the user Inputs in "2" (which means that the user wants to register) it will make him log-in because:
"2" =! 1is true
and will continue to the next while loop in here you will be asking for the username and the user will give the username. Now this is it for the Second Loop
we now go to the last loop where you ask for the Password and the User Will give the Password. The program Will either 1. say that it was false and ask for the password again or 2. it will accept the password and Break the While loop. Now this is it for the Third Loop
so why is it asking me for the Username Because the break statement breaks only the while loop it is in so that break statement broke only the third while loop and was back to the Second Loop which the Second Loop will bring us back into the Third Loop again
so how to fix this?
simple like this:
def login_originup1():
print('Welcome to password vault, You can either login or create a New account')
while True:
login_orsignu = input('Press\n1) to Log in\n2) to register a new account\n')
loopBreaker = 0
if loopBreaker:
break
if int(login_orsignu) != 1:
while True:
if loopBreaker:
break
username = input('What is your,\nUsername:')
if input_username == username:
l_p = input('What is your password ')
while True:
if loopBreaker:
break
if l_p == input_lockerpassword:
print("Password Correct")
loopBreaker = 1
break

Categories