I've been trying to figure this out my own, but I couldn't come up with solutions for this. I did come across to SpecialSym["$", "#", "#"] but I wasn't able to work that one into this code.
print("Password is incorrect, please try again...")
passW()
You can do this by adding the condition which would check whether any of the characters is in the list ["$", "#", "#"] or not.
The updated code would be:
import re #regular expression
print("Please enter a password to log in...")
def passW():
while True:
password=input("Enter a password:\n")
if password=="Y0urC0llege":
print("Logging in...")
print("Your login was successful.")
print("Welcome, Professor.")
break
elif len(password) < 10:
print("Please make sure your password is as least 10 characters long.")
elif re.search("[0-9]", password) is None:
print("Please contain as least 1 number in your password.")
elif re.search("[A-Z]", password) is None:
print("Please contain 1 capital letter in your password")
elif re.search("[$##]", password) is None:
print("Please contain as least 1 character symbol in your password.")
else:
print("Password is incorrect, please try again...")
passW()
Hope it helps.
You have to take special characters in a variable after that you can check the condition like below:
SpecialSym = ['!','#','#'] # You can add as many symbols you want.
elif not any(char in SpecialSym for char in password):
print("Please contain as least 1 character symbol in your password.")
Related
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
I'm trying to create this python program that will prompt the user to enter a password. However, the password has to be between 6 and 12 characters. Also it must have a "#" in it but not in the first character or last. This is what I have so far, I'm not sure what I'm doing wrong I just keep getting the "Not a valid password" response. Any help would be greatly appreciated. Thank You
# This program will determine whether a password meets all security requirements
import re
print ("Hello, please enter a password between 6 and 12 characters.")
print ("The password may consist of a combination of numbers and letters, but the one of characters (after the first and before the last) must be a # sign.")
password = input("Please enter your password: ")
x = True
while x:
if (len(password)<6 or len(password)>12):
break
elif not re.search("[a-z]", password):
break
elif not re.search("[0-9]", password):
break
elif not re.search("[A-Z]", password):
break
elif not re.search("[#]", password):
break
else:
print("Valid Password")
x = false
break
if x:
print("Not a valid password")
# This program will determine whether a password meets all security requirements
import re
print ("Hello, please enter a password between 6 and 12 characters.")
print ("The password may consist of a combination of numbers and letters, but the one of characters (after the first and before the last) must be a # sign.")
is_valid = False
while not is_valid:
password = input("Please enter your password: ")
if (len(password)<6 or len(password)>12):
print('Password is the wrong length')
continue
if not re.search("[a-z]", password):
print('Password missing lowercase letter.')
continue
if not re.search("[0-9]", password):
print('Password missing a number.')
continue
if not re.search("[A-Z]", password):
print('Password missing uppercase letter.')
continue
if re.search("^#", password) or re.search("#$", password):
print('Password cannot begin or end with #.')
continue
print("Valid Password")
is_valid = True
I think this is roughly what you're trying to do, you can improve it to fit your use case. The way you have your loop currently it will only ever run once, the break statement exits the loop if it hits one of your conditions. The while statement never gets a chance to check the x variable you set to false.
I modified the loop so it will repeatedly prompt until the password fits the format you specified. You could also add a prompt to quit or try another password for a better user experience. I modified your # check so the regex checks if it is either at the beginning or the end of the password.
Also I changed all your conditions to if statements. The order the conditions are checked is important, and could potentially hid a false condition. Like the classic FizzBuzz problem.
I'm checking my password for this criteria
be at least 10 characters long
contain at least 1 capital letter
contain at least 1 number
contain at least one of the characters $, #, %, &, or *
not contain any spaces
my code:
password = input("enter a password ")
def passwordIsOk (password):
symbols = "$#%&*"
if len (password) > 10:
if any(i.isupper() for i in password):
if any(i.isdigit() for i in password):
if " " not in password:
for i in range(0,5):
if symbols[i] in password:
passwordValid = True
if passwordValid == True:
print("ok buddy")
else:
print("Password must contain $#%&*")
else:
print("Password must not contain spaces")
else:
print("Password must have at least 1 number")
else:
print("Password must have at least 1 capital letter")
else:
print("Password must be greater than 10 characters")
passwordIsOk(password)
It works, but It just don't feel right :(
You can avoid this kind of nested if structure by inverting the conditions. This makes the code much more readable, and puts the error messages next to the conditions which check for those errors.
def passwordIsOk(password):
symbols = "$#%&*"
if len (password) <= 10:
print("Password must be greater than 10 characters")
elif not any(i.isupper() for i in password):
print("Password must have at least 1 capital letter")
elif not any(i.isdigit() for i in password):
print("Password must have at least 1 number")
elif " " in password:
print("Password must not contain spaces")
elif not any(s in password for s in symbols):
print("Password must contain at least one of " + symbols)
else:
print("ok buddy")
password = input("enter a password ")
passwordIsOk(password)
Putting aside the nested if structure, you could use any to check if it contains any special symbol:
password = input("enter a password ")
def passwordIsOk (password):
symbols = "$#%&*"
if len (password) > 10:
if any(i.isupper() for i in password):
if any(i.isdigit() for i in password):
if " " not in password:
if any(s in password for s in symbols):
passwordValid = True
print("ok buddy")
else:
print("Password must contain $#%&*")
else:
print("Password must not contain spaces")
else:
print("Password must have at least 1 number")
else:
print("Password must have at least 1 capital letter")
else:
print("Password must be greater than 10 characters")
passwordIsOk(password)
It is arguably easier to read and it will print all the problems with the password if you invert and flatten out the if statements using the passwordValid flag like so:
password = input("enter a password ")
def passwordIsOk (password):
passwordValid = True
symbols = "$#%&*"
if len (password) <= 10:
passwordValid = False
print("Password must be greater than 10 characters")
if not any(i.isupper() for i in password):
passwordValid = False
print("Password must have at least 1 capital letter")
if not any(i.isdigit() for i in password):
passwordValid = False
print("Password must have at least 1 number")
if " " in password:
passwordValid = False
print("Password must not contain spaces")
if not any(s in password for s in symbols):
passwordValid = False
print("Password must contain at least one of $#%&*")
if passwordValid:
print("ok buddy")
passwordIsOk(password)
A common method in password validation are regular expressions.
# coding: utf-8
import re
from getpass import getpass
def passwordIsOk(password):
if len(password) < 10:
print("Password must be greater than 10 characters")
elif not re.search('[A-Z]',password):
print("Password must have at least 1 capital letter")
elif not re.search('[0-9]',password):
print("Password must have at least 1 number")
elif not re.search('[$#%&*]',password ):
print("Password must contain at least one of $#%&*")
elif " " in password:
print("Password must not contain spaces")
else:
print("ok buddy")
pswd = getpass("Enter password: ")
passwordIsOk(pswd)
I am working on an assignment for password validation where the program keeps asking the user for a valid password until one is given. I am having trouble checking the input string for special characters. Currently the program accepts the password even if their is no special characters. Also I would like to implement a feature that terminates the loop after 3 unsuccessful attempts but am not sure which loop to implement the count in.
Here is my code:
import re
specialCharacters = ['$', '#', '#', '!', '*']
def passwordValidation():
while True:
password = input("Please enter a password: ")
if len(password) < 6:
print("Your password must be at least 6 characters.")
elif re.search('[0-9]',password) is None:
print("Your password must have at least 1 number")
elif re.search('[A-Z]',password) is None:
print("Your password must have at least 1 uppercase letter.")
elif re.search('specialCharacters',password) is None:
print("Your password must have at least 1 special character ($, #, #, !, *)")
else:
print("Congratulations! Your password is valid.")
break
passwordValidation()
There is no need to use regular expression for something so simple. How about:
elif not any(c in specialCharacters for c in password):
or
specialCharacters = set('$##!*')
...
elif not specialCharacters.intersection(password):
I have set up a program to change a "password". I have it checking to see if it is at least 8 characters, contains a capital letter and has a number, and if it does not meet this criteria, it asks for the password again. I have everything working except the checking for a number and I was wondering if someone could help.
npwv = 1
while npwv == 1:
npw = input("Please enter new password.")
npwc = input ("Please confirm new password")
if npwc == npw:
if npwc.isupper()== False:
if npwc.islower()== False:
if len(npwc) >= 8:
if str.isdigit(npwc) == True:
npw=npwc
print("Your password has been changed")
else:
print("Your password must contain a number")
npwv = 1
else:
print("Your password must contain at least 8 characters.")
npwv = 1
else:
print("Your password must contain at least 1 upper case character.")
npwv = 1
else:
print ("Passwords don't match")
npwv = 1
You are checking if the password itself is fully uppercase or composed of numbers. What you need to check if if the characters in the password match this criteria.
has_upper = any([c.isupper() for c in npwc])
has_digit = any([c.isdigit() for c in npwc])
You can also use regular expressions.
By the way, you should prefer getpass to get the password from the user.
Have you considered using .isalnum()?
>>> foo = "123asd"
>>> foo
'123asd'
>>> foo.isalnum()
True
>>>
Edit: Judging by the other answers, I am not sure what are you looking for, could explain it with examples?
I would suggest using sets, and the string package from stdlib for your list of acceptable characters.
I would also suggest refactoring a bit to remove a lot of the nesting with if / else branches.
import string
upper = set(list(string.uppercase))
lower = set(list(string.lowercase))
numbers = set(list(string.digits))
while True:
npw = input("Please enter new password: ")
npwc = input("Please confirm new password: ")
if npwc != npw:
print("Passwords don't match")
continue
if len(npcw) < 8:
print("Your password must contain at least 8 characters.")
continue
chars = set(list(npwc))
if not upper.intersection(chars):
print("Your password must contain at least 1 upper case character.")
continue
if not lower.intersection(chars):
print("Your password must contain at least 1 lower case character.")
continue
if not numbers.intersection(chars):
print("Your password must contain a number")
continue
npw = npwc
print("Your password has been changed")
break
This can be made more compact but yeah..
while True:
npw = input("Please enter new password.")
npwc = input ("Please confirm new password")
if npwc == npw:
if any(x.isupper() for x in npwc):
if any(x.islower() for x in npwc):
if len(npwc) >= 8:
if any (x.isdigit() for x in npwc):
npw=npwc
print("Your password has been changed")
#break # you probably want to exit the loop at this point
else:
print("Your password must contain a number")
else:
print("Your password must contain at least 8 characters.")
else:
print("Your password must contain at least 1 upper case character.")
else:
print("Your password must contain at least 1 lower case character.")
else:
print("Passwords don't match")
This looks like a job for regular expressions. Solution below:
import re
def password_validator(password):
if len(password) < 8:
return False, "Your password must contain at least 8 characters"
if not re.match('.*[0-9]', password):
return False, "Your password must contain a number"
if not re.match('.*[A-Z]', password):
return False, "Your password must contain at least 1 upper case character."
if not re.match('.*[a-z]', password):
return False, "Your password must contain at least 1 lower case character."
return True, "Your password has been changed"
while True:
npw = input("Please enter new password.")
npwc = input("Please confirm new password")
if npw != npwc:
print("Passwords don't match")
continue
is_valid, message = password_validator(npw)
print(message)
if is_valid:
break
You could also validate the whole thing in one go as:
pattern = """
(?=.*[a-z]) # use positive lookahead to see if at least one lower case letter exists
(?=.*[A-Z]) # use positive lookahead to see if at least one upper case letter exists
(?=.*\d) # use positive lookahead to see if at least one digit exists
[A-Za-z0-9##$%^&+=]{8,} # match any character in [] at least 8 times
"""
pwd_validator = re.compile(pattern, re.VERBOSE)
if pwd_validator.match(password):
# legit password
else:
# no match ask again
Hope this helps. The re.VERBOSE just makes this regular expression self-documenting so a lot easier to understand in future.