I'm trying to write a Python program that prompts the user for a password. It must meet the following requirements:
no less than 6 characters in length
no more than 12 characters in length
at least 1 numerical digit
at least 1 alphabetical character
no spaces
I can get through requirements 1-3, but as soon as I put in requirement 4, it stops working. I haven't even gotten to requirement 5 because I'm currently stuck. Any help is greatly appreciated! TIA!
Here is my code:
# --- Main ----------
def main():
#display student info
studentInfo()
#display welcome message
welcomeMsg()
#prompt user for a password
passWord = input("\nPlease create a password:\n")
#call function for password length validation
passWord = correctPW(passWord)
# --- Functions ----------
#student info
def studentInfo():
print("\nName:\tNAME")
print("Class:\tCMIS102")
print("Date:\t26 July 2022")
#welcome message
def welcomeMsg():
print("\nThis program will prompt the user to enter a password with the following requirements:")
print("\t- No less than 6 characters in length")
print("\t- No more than 12 characters in length")
print("\t- No spaces")
print("\t- At least one numerical digit")
print("\t- At least one alphabetical character")
#validate password requirements
def correctPW(passWord):
#check for minimum character requirement
while (len(passWord) < 6) or (len(passWord) > 12):
print("\nSorry! Your password is invalid.")
print("It must be no less than 6 characters and no more than 12 characters in length.")
passWord = input("\nPlease create a password:\n")
#check for one numerical digit and alphabetical character requirement
while (passWord.isdigit() < 1):
print("\nSorry! Your password is invalid.")
print("It must contain at least one numerical digit.")
passWord = input("\nPlease create a password:\n")
while (passWord.isalpha() < 1):
print("\nSorry! Your password is invalid.")
print("It must contain at least one alphabetical character.")
passWord = input("\nPlease create a password:\n")
#display if all password requirements are met
if (len(passWord) >= 6) and (len(passWord) <= 12) and (passWord.isdigit() >= 1) and (passWord.isalpha() >= 1):
print("\nCongratulations! Your password is valid!")
# --- Execute ----------
main()
The isdigit function will return True if all of the char in the password be numbers, like '65' or '1235' but if in the password, the user has any char near the numbers, like 'asdf3567' or '1a2b3c4d' or etc, it will return False, so this condition password.isdigit() < 1 is not a good condition
The isalpha function will return True if all of the char in the password be alphabets, like 'abc' or 'simplepassword' but if in the password, user has any char near the alphabets, like 'asdf3567' or '1a2/$b3c4d' or etc, it will return False, so this condition password.isalpha() < 1 is not a good condition
str.isdigit(): Return True if all characters in the string are digits and there is at least one character, False otherwise.
—https://docs.python.org/3/library/stdtypes.html#str.isdigit
Therefore, if passWord is (for example) "a1", then passWord.isdigit() will return False. You can, however, use it for each characters in the string, by using list (or generator) comprehension.
def check(password):
if not (6 <= len(password) <= 12):
print("Length must be between 6 and 12 (inclusive).")
return False
if any(char.isdigit() for char in password):
print("Must have a digit.")
return False
if any(char.isalpha() for char in password):
print("Must have an alphabet.")
return False
if any(char.isspace() for char in password):
print("Must not have a space.")
return False
return True
while True:
password = input("Enter a password: ")
if check(password):
break
print(f"Your password is: {password}... Oops, I said it out loud!")
If you want the actual number of digits in the password, you can use sum instead of any:
if sum(char.isdigit() for char in password) < 1:
Based on help(str) in python shell:
isdigit(self, /)
Return True if the string is a digit string, False otherwise.
A string is a digit string if all characters in the string are digits and there
is at least one character in the string.
isalpha(self, /)
Return True if the string is an alphabetic string, False otherwise.
A string is alphabetic if all characters in the string are alphabetic and there
is at least one character in the string.
So in lines:
while (passWord.isdigit() < 1): ...
while (passWord.isalpha() < 1): ...
passWord.isdigit() and passWord/.isalpha() even for your valid inputs are always False and for both of them < 1 will be True
and this will cause an infinite loop in your program.
I applied two new functions to your code to check if user inputs a valid pass you expected or not.
# --- Main ----------
def main():
#display student info
studentInfo()
#display welcome message
welcomeMsg()
#prompt user for a password
passWord = input("\nPlease create a password:\n")
#call function for password length validation
passWord = correctPW(passWord)
# --- Functions ----------
#student info
def studentInfo():
print("\nName:\tJessica Graeber")
print("Class:\tCMIS102")
print("Date:\t26 July 2022")
#welcome message
def welcomeMsg():
print("\nThis program will prompt the user to enter a password with the following requirements:")
print("\t- No less than 6 characters in length")
print("\t- No more than 12 characters in length")
print("\t- No spaces")
print("\t- At least one numerical digit")
print("\t- At least one alphabetical character")
def containsLetterAndNumber(input_password):
return input_password.isalnum() and not input_password.isalpha() and not input_password.isdigit()
def containsBlankSpace(input_password):
return (' ' in input_password)
#validate password requirements
def correctPW(passWord):
#check for minimum character requirement
while (len(passWord) < 6) or (len(passWord) > 12):
print("\nSorry! Your password is invalid.")
print("It must be no less than 6 characters and no more than 12 characters in length.")
passWord = input("\nPlease create a password:\n")
#check for one numerical digit and alphabetical character requirement
while not containsLetterAndNumber(passWord):
print("\nSorry! Your password is invalid.")
print("It must contain at least one alphabetical character and one numerical digit.")
passWord = input("\nPlease create a password:\n")
while containsBlankSpace(passWord):
print("\nSorry! Your password is invalid.")
print("It shouldn't have any blank space in it.")
passWord = input("\nPlease create a password:\n")
# display if all password requirements are met
if (len(passWord) >= 6) and (len(passWord) <= 12) and containsLetterAndNumber(passWord) and (not containsBlankSpace(passWord)):
print("\nCongratulations! Your password is valid!")
# --- Execute ----------
main()
Related
I make password genrator using python then the teacher told to create a code that make the user choose what he want in the password
the password contains
1- lower case characters
2- upper case characters
3- numbers
4- punticuation marks
the teacher want me to make the user choose if he want punticution or not
if he dont want it have to be deleted from the password
i tried so hard but i got stuck
from msilib import change_sequence
import string
import random # I import this line to make the password unorgnaized
# this code below is all the characters we need for the password
s1 = list(string.ascii_lowercase)
s2 = list(string.ascii_uppercase)
s3 = list(string.digits)
s4 = list(string.punctuation)
# this code is for the user to put how much characters he need
characters_number = input("how many characters for the password?:")
# this while loop code is to make the user choose only 6 characters and up
while True:
try:
characters_number = int(characters_number)
if characters_number < 6 :
print("you need at least 6 characters") # if the user choose an letter or digits it will not allow him
characters_number = input("please enter the number again:")
else:
break # I break the loop here if the user write the correct data
except: #this code here if the user enter anything except numbers
print("please enter numbers only")
characters_number = input("how many characters for the password?:")
# the random and shuffle is to make the password unorgnized
random.shuffle(s1)
random.shuffle(s2)
random.shuffle(s3)
random.shuffle(s4)
# the password that will appear to the user it contains upper and lower letters, numbers and digit
# part1 here is for the letters I allocated 30% of the password for letters
# part2 here is for the digits and numbers I allocated 20% of the password for letters
part1 = round(characters_number * (30/100))
part2 = round(characters_number * (20/100))
password = []
for x in range(part1):
password.append(s1[x])
password.append(s2[x])
#the for loops here here is to create the password
for x in range(part2):
password.append(s3[x])
password.append(s4[x])
#this code here is to transform the password for list method to a string
password = "".join(password[0:])
print(password)
You can write a function like this:
def isUserNeedPunctuationMarks():
result = None
while True:
inp = input("Do you need punctuation marks in your password? (y/n)")
inp = inp.lower()
if inp == "y":
result = True
break
elif inp == "n":
result == False
break
else:
print("You must enter y or n")
return result
The above function will return True if the user needs punctuation marks, and False otherwise. User has to type y (for yes) or n(for no).
You can call isUserNeedPunctuationMarks() in the right place in your code. For example, removing punctuation marks from password string, you have to write a condition like this:
import re
if not isUserNeedPunctuationMarks():
password = re.sub(r'[^\w\s]', '', password) # This removes punctuation marks from a string using regex
Hope this helps :)
Write a program that asks the user to enter a password (with the prompt "Password:"). It should then reward the user with "Congratulations, you're in!" if the password is between 8 and 20 characters long (inclusive), ends with a digit, and contains a period or comma. Otherwise, it should say "Wrong! This incident will be reported!"
I need to be able to have a number at the end and contain either a period or a comma. I am not sure on how to isolate these two parts of the password. What do I do to have the user asked to enter a password?
user_pass = str(input())
if (len(user_pass <= 8) and (len(user_pass >= 20)) and
print ("Congratulations, you're in!")
else:
print ('Wrong! This incident will be reported!')
Just add more conditions using and.
Python 3:
password = input("Password: ")
if (8 <= len(password) <= 20) and password[-1].isdecimal() and any(x in password for x in {'.', ','}):
print("Congratulations, you're in!")
else:
print("Wrong! This incident will be reported!")
Python 2:
password = raw_input("Password: ")
if (8 <= len(password) <= 20) and unicode(password[-1]).isdecimal() and any(x in password for x in {'.', ','}):
print("Congratulations, you're in!")
else:
print("Wrong! This incident will be reported!")
A hint:
def password_is_good(password):
return (
password_length_is_correct(password) and
password_ends_with_digit(password) and
password_contains_punctuation(password)
)
def password_length_is_correct(password):
# implement this, and the rest.
password = str(input())
if password_is_good(password):
# do something.
else:
# do something else.
You can access string elements by index, with negative indexes counting from the end; e.g. password[-1] would access the last character.
You can use the in operator to check for a character to be present in a string, like if 'c' in 'abcdef'.
Task: Password validator
a. The length of the password needs to be from 8 to 30 characters.
b. The password needs to contain at least 2 uppercase characters.
c. The password needs to contain at least 2 lowercase characters.
d. The password needs to contain at least 1 digit.
e. The password needs to contain exactly 1, but not more of the following special characters:
#/%&*_-
This is my code:
special_character_set = "#/%&*_-"
is_valid = False
import re
while True:
password = input("please enter a password: ")
if len(password) > 30 or len(password)< 8:
print("The length of the password needs to be from 8 to 30 characters!")
continue
elif re.search('[0-9]', password) is None:
print("The password needs to contain at least 1 digit!")
continue
elif re.search ('[A-Z][A-Z]', password) is None:
print("The password needs to contain at least 2 uppercase characters!")
continue
elif re.search('[a-z][a-z]', password) is None:
print("The password needs to contain at least 2 lowercase characters!")
continue
elif re.search('[#/%&*_-]', password) is None:
print("The password needs to contain one of the following special characters: #/%&*_-!")
continue
else:
is_valid = True
if is_valid:
print("valid password")
break
It works. However, the condition e) has not been completely fulfilled. How can I make the password contain ONLY ONE of the special characters?
What about len + re.findall():
...
elif len(re.findall('[#/%&*_-]', password)) != 1:
# Some number of special characters other than 1 was found
...
or
...
elif len(re.findall('[#/%&*_-]', password)) == 0:
# No special characters were found
...
elif len(re.findall('[#/%&*_-]', password)) > 1:
# Too many special characters were found
(and if you do the latter, try not to run the regex twice)
Don't use regex for this; add up the counts of special characters in the proposed password:
>>> passwd = "My_Pass#"
>>> special = '[#/%&*_-]'
>>> special_count = sum(passwd.count(c) for c in special)
>>> special_count
2
You can now use special_count as desired.
I'm working on a password checker that checks if the string is a valid password. I have to check if there is at least eight characters, must consist of only letters and digits and the last two characters must be digits.
It all seems to work so far other than the password.isdigit(). sometimes the password comes out valid and sometimes it doesn't. Any suggestions?
# Gets the users password
password = input('Enter a string for password: ')
# Splices the last two characters of the password
lastTwo = password[-2:]
# Checks the password if it is less than 8 characters
while len(password) < 8:
print('The password you entered is too short.')
print()
password = input('Enter a string for password: ')
# Checks the password if it is composed of letters and numbers
while password.isalnum() == False:
print('Your password has special characters not allowed.')
print()
password = input('Enter a string for password: ')
# Checks the spice to verify they are digits
while lastTwo.isdigit() == False:
print('Your last two characters of your password must be digits.')
print()
password = input('Enter a string for password: ')
print('Your password is valid.')
There are a handful of issues with your provided code. Particularly, you only check the subsequent rules while len(password) < 8. If you give it a password of length 10, the rules are never checked. Additionally, you don't update the lastTwo with each new password attempted
One way to fix this would be to replace your several while statements with if...elif..elif...else... wrapped in an overall while statement, as follows:
# Gets the users password
password = input('Enter a string for password: ')
while True:
# Checks the password if it is less than 8 characters
if len(password) < 8:
print('The password you entered is too short.')
# Checks the password if it is composed of letters and numbers
elif not password.isalnum():
print('Your password has special characters not allowed.')
# Checks the spice to verify they are digits
elif not password[:-2].isdigit():
print('Your last two characters of your password must be digits.')
else:
# we only get here when all rules are True
break
print()
password = input('Enter a string for password: ')
print('Your password is valid.')
This should work as you intended it. But while we're at it, why not tell the user every rule their password has broken? From a UI point of view, it helps to keep the user informed.
If we store an information message alongside whether the relevant rule has been met, we can quickly work out all of the rules that have been broken, like so:
valid_password = False
while not valid_password:
# Get a password
password = input('\nEnter a string for password: ')
# applies all checks
checks = {
'- end in two digits': password[-2].isdigit(),
'- not contain any special characters': password.isalnum(),
'- be over 8 characters long': len(password) > 8
}
# if all values in the dictionary are true, the password is valid.
if all(checks.values()):
valid_password = True
# otherwise, return the rules violated
else:
print('This password is not valid. Passwords must:\n{}'.format(
'\n'.join([k for k, v in checks.items() if not v])))
print('Your password is valid.')
You never update your value of lastTwo inside your while loop. Thus imagine if a user first entered a password abc123. Then lastTwo would be calculated as 23.
Now your code would find that the password is too short and prompt the user for a new password. Suppose he enters abcdefgh. This now passes your first and second checks. Notice however that lastTwo is still 23, and thus your third check will incorrectly pass.
You should thus recalculate the value of lastTwo whenever you accept a new password or directly check like this:
while (password[-2:]).isdigit() == False:
As part of an assignment, I'm creating a program to ask a user to input a username and password.
I've completed the username part (easy), but in the assignment instructions, the password must:
contain an uppercase character
contain a lowercase character
be longer than 6 characters
contain a number
have no white space
There are 5 specific error messages that need to display if any of these conditions are not true.
What I've got currently has some weird behavior, the errors only show up in a specific order (for example, password "f" will have the error "must have an uppercase character" instead of "must be longer than 6 characters"). I know this is because of the nesting order of the if statements, but if there's a better way... It also for some reason doesn't catch white space in the password. I know it probably isn't the most efficient way but here's what I've got so far:
def validatePassword():
accept = "n"
while accept == "n":
password = input("Please enter a valid password: ")
upper = "n"
lower = "n"
digit = "n"
length = "n"
white = "n"
if len(password) >= 6:
length = "y"
for char in password:
if char in string.ascii_uppercase:
upper = "y"
if char in string.ascii_lowercase:
lower = "y"
if char in string.digits:
digit = "y"
if char not in string.whitespace:
white = "y"
if upper == "y":
if lower == "y":
if digit == "y":
if length == "y":
if white == "y":
accept = "y"
else:
print("::: ERROR :::",password,"must not have any white space character.")
else:
print("::: ERROR :::",password,"must be longer than 6 characters.")
else:
print("::: ERROR :::",password,"must contain a number.")
else:
print("::: ERROR :::",password,"must contain a lowercase character.")
else:
print("::: ERROR :::",password,"must contain an uppercase character.")
return password
You could try something like this:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def validatePassword(password):
if not any(x.isupper() for x in password):
return False, "No upper case character"
if not any(x.islower() for x in password):
return False, "No lower case character"
if len(password) < 6:
return False, "Not longer than 6 characters"
if not any(x.isdigit() for x in password):
return False, "No number"
if any(x.isspace() for x in password):
return False, "Contains hitespace"
return True, ""
def test():
# test some passwords
test_passwords = ["lkjasdf", "KAJSDF", "lfSF", "asdfADSF", "asdf ADSF 123", "asdfADSF123"]
for p in test_passwords:
print validatePassword(p)
# "real" usage
while True:
password = input("Please enter a valid password: ")
result, message = validatePassword(password)
if result is True:
break
else:
print(message)
if __name__ == '__main__':
test()
Obviously the correct way to do this is with any() and a generator expression, but seeing as how you said I'm like 8 weeks into a 10 week introductory course those probably don't help you.
Here's how you can do it without using any() by just looping through the characters checking for the presence of certain types of characters.
def validate_password(password):
hasUpper = hasLower = hasNumber = hasWhiteSpace = False
for char in passwordStr:
if char.isupper():
hasUpper = True
if char.islower():
hasLower = True
if char.isdigit():
hasNumber = True
if char.isspace():
hasWhiteSpace = True
if len(password) <= 6:
return False, "Password must be longer than 6 characters"
if not hasUpper:
return False, "Password must contain atleast one uppercase character"
if not hasLower:
return False, "Password must contain atleast one lowercase letter"
if not hasNumber:
return False, "Password must contain alteast one number"
if hasWhiteSpace:
return False, "Password cannot contain any white space"
return True
First, there's the data type bool which can represent the values True and False. You should use them to represent simple true/false states instead of assigning the strings "y" and "n".
Second, checking every character separately and storing whether the different conditions are met at least once is a possible way. However, Python has powerful string examination methods that can make your life much easier. Let me demonstrate them by writing a short function which takes aa password as argument and simply returns True or False depending on whether the passwords meets your restrictions:
def is_password_valid(password):
# check password length:
if len(password) < 6:
print("Your password is too short, at least 6 characters are required!")
return False
# check if password contains any non-alphanumeric letters (including whitespace):
# (isalnum() only returns true if the string only contains letters and digits, nothing else)
if not password.isalnum():
print("Your password may only contain letters and digits!")
return False
# check if password contains letters:
# (isdigit() only returns true if all of the characters are numbers)
if password.isdigit():
print("Your password does not contain any letters!")
return False
# check if password contains uppercase letters:
# (islower() only returns true if all of the letters are lowercase, non-letters are ignored)
if password.islower():
print("Your password does not contain any uppercase letters!")
return False
# check if password contains lowercase letters:
# (isupper() only returns true if all of the letters are uppercase, non-letters are ignored)
if password.isupper():
print("Your password does not contain any lowercase letters!")
return False
# check if password contains lowercase numbers:
# (isalpha() only returns true if all of the characters are letters)
if password.isalpha():
print("Your password does not contain any numbers!")
# if all conditions above are okay, the password is valid:
print("The password is okay.")
return True
You may of course reorder the blocks in my code above as you wish.
You can then simply use this helper function inside your loop which looks a lot simpler and cleaner now:
def validate_password():
accept = False
while not accept:
password = input("Please enter a valid password: ")
accept = is_password_valid(password)
You can try Regular Expressions. If you don't know about regex, as you've mentioned in your comment, this is a great website.
For validation, check if the password matches with any of the rules which will render it invalid and if not, it is a valid password.
import re
def validate(passwd):
pattern = r'^(.{0,5}|[^0-9]*|[^A-Z]*|[^a-z]*|.*\s+.*)$'
result = re.search(pattern, passwd)
if result:
print 'Invalid Password'
else:
print 'Valid Password'
What this does is check if, passwd is less than 6 chars OR contains no numbers OR contains no uppercase chars OR contains no lowercase chars OR contains spaces. If none of the criteria matches, the password is valid.