Password can only contain number letters and underscores - python

The assignment is:
Write a Python program which prompts the user to create a user account and checks whether the provided user name and password are legal.
Note: A password should start with a letter and only consists of letters, numbers and the underscore symbol "_". The length should be between 8 to 16.
I'm having trouble with the "a password should start with a letter and only consists of letters, numbers and the underscore symbol "_". " part. (I know it's not the most elegant code)
username=input("Please enter a username:")
usepass=input("Please enter a password:")
#username
if len(username)<6 or len(username)>12:
print("Username is incorrect length. Your username must be between 6 and 12 characters.")
if username.isalnum() == False:
print("Username must only contain letters and numbers.")
username1=username[0]
if username1.isnumeric()== True :
print ("Your username must start with a letter")
#password
if len(usepass)<8 or len(usepass)>16:
print("Password is incorrect length. Your password must be between 8 and 16 characters.")
usepass1=usepass[0]
if usepass1.isalpha()==False:
print("Your password must start with a letter")
if usepass.isalnum()==False:
print("Your password must only contain numbers, letters and underscores.")

Rather than use the isalnum method, lets try to solve this on your own. The main thing you're lacking here is a loop. For example, if I want to test every letter, I can loop over the letters, and use the ord method to verify that every letter is in the right range.
You should structure your methods to test each of the unique conditions as stated in the question. If it passes all the conditions you can return true at the end.
def is_valid_user(username):
# a user name should start with a letter
is_first_lower = ord('a') <= ord(username[0]) <= ord('z')
is_first_upper = ord('A') <= ord(username[0]) <= ord('Z')
if not (is_first_lower or is_first_upper):
return False
# only consists of letters and numbers
for character in username:
is_lower = ord('a') <= ord(character) <= ord('z')
is_upper = ord('A') <= ord(character) <= ord('Z')
is_number = ord('0') <= ord(character) <= ord('9')
if not (is_lower or is_upper or is_number):
return False
# check the other cases like "The length should be between 6 and 12"
...
# All the tests passed so return true
return True
Now you can think about how you can make an is_valid_password method. This method should be similar, but have a few different conditions. Bonus: Think about how you can make other methods to share checks between the is_valid_user and is_valid_password methods.

i solved it by creating a new variable that removes an underscore and uses .isalnum to compare that variable
rmveudrsre = usepass.replace("_", "")
if rmveudrsre.isalnum()==False:
print("Your password must only contain numbers, letters and underscores.")

Related

Python - Password Validation program

I am trying to make a program that carries out password validation when a user is making an account for this first time and has to enter a new password.
The password has to be more than 8 letters, contain an upper case letter, a lower case letter and a number.
I've done the following code, and it doesn't work at the moment. I think it's because islower() only works if all characters in the string are lower, same with isupper but for uppercase letters. How can I solve this issue, to get a nice clean solution for the requirements? Thanks
while loop:
pass1 = input('type a password: ')
if len(pass1) > 8 and pass1.islower() and pass1.isupper() and pass1.isdigit():
print('password successful')
break
else:
print('Password not valid, please retry')
Create another if else statement where you check islower method return true or false or set it equal to another boolean value then use that value in the second(which is your main if statement) statement then run it.
The condition that you are looking for is as follows: the password must be alphanumeric, but it must not consist of all lower-case letters, it must not consist of all upper-case letters, it must not consist of all letters, and it must not consist of all digits:
pass1.isalnum() and not pass1.isupper()\
and not pass1.islower()\
and not pass1.isalpha()\
and not pass1.isdigit()
This should work.
def anyLower(s):
return s.upper() != s
def anyUpper(s):
return s.lower() != s
def anyDigit(s):
return any(char.isdigit() for char in s)
while True:
userInput = input("Type a password: ")
if len(userInput) > 8 and anyLower(userInput) and anyUpper(userInput) and anyDigit(userInput):
print("Password successful")
break
else:
print("Password not valid, please retry")
anyLower() function converts the string to uppercase and checks if it changes, if it has changed, then the string must contain at least one lowercase character. anyUpper() works in a similar way.
anyDigit() iterates through all of the characters in the string and returns true if any of the characters are digits using the any() function.
You can try utilizing the built-in any() method along with the built-in map() method to check if any of the characters in the string, mapped with your choice of str method, returns True:
conditions = str.islower, str.isupper, str.isdigit
while True:
pass1 = input('type a password: ')
if len(pass1) > 8 and all(any(map(c, pass1)) for c in conditions):
print('password successful')
break
else:
print('Password not valid, please retry')
The password has to be more than 8 letters, contain an upper case letter, a lower case letter and a number.
It's good programming practice to code to functional requirements so it would be useful to have a specific function such as is_password_valid().
And, since the intent is to check if all the conditions are met, you can exit early before needing to check all the characters (possibly many times) as some of the other answers here do. In other words, something like (with a test harness):
import sys
def is_password_valid(password):
if len(password) <= 8:
return False
has_upper, has_lower, has_digit = False, False, False
for character in password:
if character.islower(): has_lower = True
elif character.isupper(): has_upper = True
elif character.isdigit(): has_digit = True
if has_lower and has_upper and has_digit:
return True
return False
chs = ['1', 'a', 'B', '_']
for ch1 in chs:
for ch2 in chs:
for ch3 in chs:
for ch4 in chs:
str1 = ch1 + ch2 + ch3 + ch4 + "....."
print(f"{str1} : {is_password_valid(str1)}")

Making a valid password checker. Can not get my program to get through the if conditions to print a valid password

I have been assigned the following exercise as homework:
Some Web sites impose certain rules for passwords. Write a function that checks whether a string is a valid password. Suppose the password rules are as follows:
A password must have at least eight characters.
A password must consist of only letters and digits.
A password must contain at least two digits.
Write a program that prompts the user to enter a password and displays valid password if the rules are followed or invalid password otherwise.
I know there's a more efficient and proper way of doing this but i'm just starting out so I don't necessarily need to be those right now. Just want to finish this question.
The counter/ accumulator works and I don't get any errors but I can not fulfill the if condition correctly so that this program prints "valid password"
password = str(input("Enter in a password to be checked: "))
def valid_password_checker(password):
from string import ascii_lowercase as alphabet
digits = '0123456789' # creates a string of digits
digit = 0 # acc for digits
length = 0 # acc for length
for char in password: # calls on each character in string
if char in alphabet:
length += 1
if char in digits:
digit += 1
if digit >= 2:
flag = True
if length >= 8 and digit is True:
print("valid password")
else:
print("Password does not contain enough characters or digits.")
else:
print("Password does not contain enough digits.")
valid_password_checker(password)
The problem with your existing code is that the variable digit is a number, and therefore doing digit is True as you have done in your if statement, always return False. If you remove digit is True, then your existing solution will work. Take a look however at my version:
def valid(password):
digits = 0
characters = 0
for char in password:
if char.isalpha():
characters += 1
elif char.isdigit():
digits += 1
characters += 1
if characters >= 8:
if digits >= 2:
print("Password is valid")
else:
print("Password doesn't contain enough digits")
else:
print("Password doesn't contain enough characters")
I have made the following modifications from your original:
Used the built-in function str.isdigit() for checking if a character is a digit.
Used the built-in function str.isalpha() for checking if a character is a letter of the alphabet
Moved everything but the counting operations outside of the for loop, so that the function doesn't print multiple things
If you want, you can undo the first two changes, if you're worried about your teacher knowing you asked for help. However, I wouldn't turn in the solution that prints "Password doesn't contain enough digits" as many times as there are characters in the inputted password.
you can write something like this:
password = str(input("What is the password that you want to validate: "))
def get_digits(password):
return [i for i in password if i.isdigit()]
numbers = ''.join(get_digits(password))
if (len(password) < 8) or (len(numbers) < 2):
print(password, "is an invalid password")
else:
print(password, "is a valid password")
nice and simple.

How to check if a string contains at least 2 digits and no spaces?

I have to build a program where you enter a password. The password must contain at least 8 characters, start with a letter, have both upper and lower case letters, have no spaces and at least 2 digits.
I have everything else down except for the last 2.
I tried using a for loop to see if there are spaces or digits, but it will only work if the whole password consists of spaces or digits. If there is a number or a space, if prints off the error message for as many characters there are in the password, not just for how many digits or spaces there are. I know this is happening because of the for loop, but I'm stuck on how to fix it.
Here is what I have so far:
again = 'y'
while again == 'y':
minimum_characters = 8
error = 0
print('Password must contain 8 characters, start with a letter,')
print(' have no blanks, at least one uppercase and lowercase letter,')
print(' and must contain at least 2 digits.')
password = input('Enter a password: ')
passlength = len(password)
#validity checks for errors
if passlength < minimum_characters:
error += 1
print (error, '- Not a valid password. Must contain AT LEAST 8 characters. PW entered has', passlength, '.')
if not password[0].isalpha():
error += 1
print(error, '- The password must begin with a letter.')
if password.isalpha():
error += 1
print(error, '- The password must contain at least 2 digits.')
if password.isupper():
error += 1
print(error, '- You need at least one lower case letter.')
if password.islower():
error += 1
print(error,'- You need at least one upper case letter.')
again = input('Test another password? (Y or N): ')
again = again.lower()
if " " in password:
error += 1
print(error, '- Not a valid password. It contains spaces.')
if len([x for x in pwd if x.isdigit()]) < 2:
error += 1
print(error, '- The password must contain at least 2 digits.')
User regular expression
import re
sequence = "1Sentence1e"
if re.match("(?:\d.*?){2,}", sequence):
print("Match!")
else:
print("Not match!")
Fiddle: http://tpcg.io/73SyIc
Regular expression match javascript syntax
"(...) have no spaces and at least 2 digits."
A few options that will work for counting the number of occurrences of any character/digit. Simply replace with what you need (digits and spaces in the examples):
if any([x for x in password if x == " "]):
# 1 or more spaces in password
if password.count(" ") > 0:
# 1 or more spaces in password
if len([x for x in password if x.isdigit()]) < 2:
# less than 2 digits
To report an error when the string contains less than 2 digits you can use:
if sum(map(str.isdigit, password)) < 2:
Also, your checks for uppercase and lowercase letters are incorrect:
if password.isupper():
checks if all characters are uppercase. To check if any character is uppercase you can use:
any(map(str.isupper, password))

Checking password input for integers, capitals and lowercase?

I am doing some work for my computing class at school and we need to ask for input of a password. The input needs to be between 6 and 12 characters, and contain uppercase, lowercase and numbers in it. I have this so far :
import sys
import os
def checkPass():
passLoop = True
while passLoop:
print("Welcome user!")
x = len(input("Please enter your password, between 6 and 12 characters. "))
if x < 6:
print("Your password is too short")
r = input("Please press any key to restart the program")
elif x > 12:
print("Your password is too long")
r = input("Please press any key to restart the program")
else:
print("Thank you for entering your password.")
print("Your password is strong. Thank you for entering!")
passLoop = False
checkPass()
I need your help checking for uppercase, lowercase and integers. I'm only young so please don't be too harsh!
^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?\d).{6,12}$
You can try this.This employs re.
You can use it like
import re
if re.match(r"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?\d).{6,12}$",pass,re.M):
print "valid"
else:
print "invalid"
See demo.
http://regex101.com/r/dZ1vT6/28
let's assume you have the password stored in a variable named passwd.
Then we can take your literal requirements and write checks for them:
The input needs to be between 6 and 12 characters,
if not 6 <= len(passwd) <= 12: ...
and contain uppercase,
if not any(c.isupper() for c in passwd): ...
lowercase
if not any(c.islower() for c in passwd): ...
and numbers in it.
if not any(c.isdigit() for c in passwd): ...
On a side note: you really should not limit the length of passwords.
the any function in combination with a map can be helpful. The map function iterates over all characters of the given string and test via the given lambda function if the character is an uppercase. The is consumed by the any function which returns true on the first true from the map function
>>> any(map(lambda a:a.isupper(),"aba"))
False
>>> any(map(lambda a:a.isupper(),"aBa"))
True
you can wrap that into a separate function like
>>> def test(passwd,func):
return any(map(func,passwd))
>>> test("aBa",str.isupper)
True
>>> test("ab0",str.isdigit)
True
>>> test("aBa",str.islower)
True

Having trouble learning how to look at individual characters in a string checking for case or digit

I am trying to write a simple password checker for homework assignment, looking for at least one capital, one lower case, one digit, and it needs to be 6 or more chars.
I have searched and searched on here and elsewhere, but either what I read doesn't match our instruction, or the replies are more advanced than myself. Any help I get will be cited as a comment in my assignment.
This is just the part of my code which checks for caps, it only looks at the whole string, not the individual characters and I can't seem to find the solution.
passwd = input('enter password: ') ## we are actually using (sys.agrv)
## but I am using this for testing
character = passwd[0:]
lcase_bad = False
for character in passwd:
if not character.islower() > 1:
lcase_bad = True
if lcase_bad:
print('Password must include lowercase letters ')
else:
print('password accepted')
for character in passwd:
Here you're iterating through each letter of the input.
When you do if not character.islower() > 1:, it will always be True. .islower() returns either True or False, depending on if the string is a capital letter or not. not False == 1, because boolean is a subclass of int. not True == 0. Both are not greater than one.
You can just do something like:
capital = False
lowercase = False
number = False
if len(passwd) < 6:
print 'That was not more than 6 characters'
else:
for character in passwd:
if character.islower():
lowercase = True
elif character.isupper():
capital = True
elif character.isdigit():
number = True
if capital and lowercase and number:
break
else:
print 'That did not have a capital letter, lowercase letter, and a digit'
Of course this is useful if you want to tell the person what the password didn't have. However, you can also just do one test instead.
Just check for all those conditions one after another:
mystring = input("enter password: ")
if any(c.isupper() for c in mystring) \ # There is an uppercase letter
and any(c.islower() for c in mystring) \ # There is a lowercase letter
and any(c.isdigit() for c in mystring) \ # There is a number
and len(mystring) > 5: # The length is 6 or greater
# string passed all tests
else:
# One or more tests failed--input is bad.
You've almost got it! If you remove the > 1 from your code (which won't really do anything useful), you get this:
lcase_bad = False
for character in passwd:
if not character.islower():
lcase_bad = True
It just happens that this will test to see if the entire string is made of lowercase letters. If it is, lcase_bad will remain False; otherwise, it will become True. It should not be an extreme leap of faith to see that if you flip the False and True around and call it lcase_good, you can see whether at least one character is lowercase.
As iCodez notes, you can also rewrite it using any with a generator comprehension. It reads fairly easily:
if any(character.islower() for character in passwd):
However, you probably haven't gotten to generator comprehensions, so it might be best to stay with a for loop for clarity's sake.

Categories