Checking variables with isupper, islower and isdigit [duplicate] - python

This question already has an answer here:
Variable checking, something not right
(1 answer)
Closed 6 years ago.
I have tried to make a 'password checker' program that checks if an entered variable contains specific characters. I will need it to check thee things: uppercase, lowercase and number.
There are 3 things that the program will hopefully output, and these are:
Weak, for passwords with only upper OR only lower OR only number
Medium, for passwords that have upper and lower, OR upper and number, OR lower and number
Strong, for passwords that contain upper, lower and number at the same time.
This is my code:
if EnteredPassword.isupper() or EnteredPassword.islower() or EnteredPassword.isdigit():
print ("Your password is weak")
elif EnteredPassword.isupper()and EnteredPassword.islower():
print ("Your password is medium")
elif EnteredPassword.isupper() and EnteredPassword.isdigit():
print ("Your password is medium")
elif EnteredPassword.islower() and EnteredPassword.isdigit():
print ("Your password is medium")
elif EnteredPassword.isupper() and EnteredPassword.islower() and EnteredPassword.isdigit():
print ("Your password is strong")
else:
print ("That password should not have been accepted")
quit()
However, when the program is run, and for example I have put in UPPERLOWER6 the program skips to the else statement. If I put something that just contains UPPER etc., that is the only one that works and comes up with your password is weak
If there is anything wrong with the code I cannot see, please point it out. I have been re-directed to other questions but they are too complicated for me and people would know I have copied is, which is not allowed.
Many thanks!

you should do something like this:
Password Tester in Python
the functions you are using test the whole string and to make what you want to do is not the right option.

Use regex. Its easier.
Your code isn't working the way you want it to because isupper, islower and isdigit all check all the values of the string you feed it. i.e. 'a'.islower() returns True, while 'aA'.is lower() returns False.
So,
if str.isupper() and str.islower():
#statement
is never executed because one of the conditions is always bound to be False.
Note: isupper and islower ignore any digits if any character is present in the string. i.e. 'a6'.islower() return True, while '6'.islower() and 'a6'.isdigit() return False.

isupper / islower is not working same as like isdigit.
upper and lower ignores any digits and whitespaces (eg "UPPER6 ".isupper() is True)
on the other way digit check if string contains only digits
Anyway 'UPPERLOWER6' matches first condition, so it shouldn't skip to else. You string probably contains something else.
You can still iterate over chars, eg:
flags = [False] * 3
for ch in EnteredPassword:
flags[0] = flags[0] or ch.islower()
flags[1] = flags[1] or ch.isupper()
flags[2] = flags[2] or ch.isdigit()
strength = sum(flags)
print("Your password is {}".format(
["not accepted", "weak", "medium", "strong"][strength])
)

You r doing it wrong way as you can use isupper or islower functions only on characters and not on whole string. I would do something like this:
def containsOnlyUpper(s):
for c in s:
if(not c.isupper()):
return False
return True
def containsOnlyLower(s):
for c in s:
if(not c.islower()):
return False
return True
def containsOnlyNumber(s):
for c in s:
if(not c.isdigit()):
return False
return True
def containsUpperAndLower(s):
hasUpper = False
hasLower = False
for c in s:
if (c.islower()):
hasLower = True
if (c.isupper()):
hasUpper = True
if(hasUpper and hasLower):
return True
else:
return False
def containsUpperAndNumber(s):
hasUpper = False
hasNumber = False
for c in s:
if (c.isupper()):
hasUpper = True
if (c.isdigit()):
hasNumber = True
if(hasUpper and hasNumber):
return True
else:
return False
def containsLowerAndNumber(s):
hasLower = False
hasNumber = False
for c in s:
if (c.islower()):
hasLower = True
if (c.isdigit()):
hasNumber = True
if(hasLower and hasNumber):
return True
else:
return False
def isWeakPassword(s):
if(containsOnlyUpper(s) or containsOnlyLower(s) or containsOnlyNumber(s)):
return True
return False
def isMediumPassword(s):
if(containsUpperAndLower(s) or containsUpperAndNumber(s) or containsLowerAndNumber(s)):
return True
return False
def isStrongPassword(s):
hasUpper = False
hasLower = False
hasNumber = False
for c in s:
if (c.isupper()):
hasUpper = True
if (c.islower()):
hasLower = True
if (c.isdigit()):
hasNumber = True
if (hasLower and hasUpper and hasNumber):
return True
else:
return False
password = "UPPERLOWER6"
if(isWeakPassword(password)):
print "weak"
elif(isMediumPassword(password)):
print "medium"
elif(isStrongPassword(password)):
print "strong"
else:
print "none"

I think you could set variables as flags, then check the letter and recording the number of occurrences in input one by one.

Related

How can check number in string?

I want to know that 'password' is containd number using 'string.digits'
import string
def validate_password(password):
is_long = len(password)
if is_long < 8:
return False
includes_digit = password
for digit in string.digits:
if digit in includes_digit:
break
return False
for u in string.ascii_uppercase:
if u in includes_digit:
break
return False
for char in string.ascii_lowercase:
if char in password:
break
return False
return True
is_password_valid = validate_password("12345678ff")
print(is_password_valid)
I guess that is ok but didn't work
help me plz
In all of your validators, you don't return False because that return statement is underneath the if statement. You always break before reaching the return.
Put an else under your for loops like this. This part executes if the for loop finishes without encountering a break.
includes_digit = password
for digit in string.digits:
if digit in includes_digit:
break
else:
return False
You should use regex in this case.
import re
password = 'Azerty123'
contains_digit = bool(re.search('\d', password))
print(contains_digit) # True

Python boolean check in other functions

this is my code for a password and I actually have 4 conditions. Then, I am cheking at the end with def final_password that if all of the 4 previous fuctions are TRUE then the password in TRUE otherwise it's FALSE. However, the last one did not work, during my testing it was always FALSE even when the 4 conditions where TRUE. Thank you!
NON_ALPHABETIC_CARACTERS = ("!", "?", "ยง")
def password_len (password) :
lenght_caracters_check = False
for i in password :
if len(password) > 4 and len(password) < 10 :
lenght_caracters_check = True
break
else :
return lenght_caracters_check
def password_numeric_caracters (password) :
numeric_caracters_check = False
for i in password :
if i.isnumeric () :
numeric_caracters_check = True
break
else :
return numeric_caracters_check
def password_alphabetic_caracters (password) :
alphabetic_caracters_check = False
for i in password :
if i.isalpha () :
alphabetic_caracters_check = True
break
else :
return alphabetic_caracters_check
def special_caracters (password) :
special_caracters_check = False
for i in password :
if i in NON_ALPHABETIC_CARACTERS :
special_caracters_check = True
break
else :
return special_caracters_check
def final_password (password) :
final_password_check = False
if password_len(password) and password_numeric_caracters(password) and password_alphabetic_caracters(password) and password_special_caracters(password) :
final_password_check = True
return final_password_check
You need to add "return" to all functions for True cases.
For True cases you are just setting a variable true. However you are not returning it.
In addition there is no overall check for all characters since you are breaking the loop for the first success case. You need to modify break with continue:
for i in password :
if i.isalpha () :
continue
else :
return False
return True
There are some other issues with your code, but answering your question, your function special_caracters(password) does not return any value when the condition is True. Try refactoring it a bit:
def special_caracters (password):
for i in password:
if i in NON_ALPHABETIC_CARACTERS:
return True
return False

Validating the contents of a user entered string in Python?

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.

Python Password Checker

I need some help figuring out how to make a function that checks a string for a bunch of conditions.
Passwords must be at least 5 characters long
Passwords must contain at least one upper case letter
Passwords must contain at least two numbers
Passwords may not contain the characters "E" or "e"
Passwords must include at least one special symbol: !, #, #, $, %, ^, &
right now this is all that I have
def passwordChecker(password):
'''
'''
caps = sum(1 for c in password if c.isupper())
nums = sum(1 for c in password if c.isdigit())
symb = any(c in password for c in '!##$%^&')
note = any(c in password for c in 'Ee')
if len(password) <5:
return False
elif caps < 1:
return False
elif nums < 1:
return False
elif symb == False:
return False
else:
return True
Edit**
Just realized that I have to check also if there are commonly used passwords like 'password' or '111111' and I dont really know about how I would approach this.
Just an alternative using regular expressions:
import re
def passwordChecker(password):
return all(re.search(pattern, password) for pattern in
('.{5}', '[A-Z]', '\d.*\d', '^[^Ee]*$', '[!##$%^&]'))
Demo using five barely invalid and five barely valid tests (one invalid and one valid for each of the five rules):
for password in ('1A!', '12!34', 'A1bc!', 'A12E!', 'A12bc',
'1A!2.', 'A2!34', 'A12c!', 'A12b!', 'A12b#'):
print(passwordChecker(password))
Prints False for the first five and True for the last five.
you are just missing a branch
elif note:
return False
before the else:
This is a good time to talk about decorators! I love using decorators to validate data, probably too much. You could make validators for all that, and wrap it around your get_password method.
def v_length(password):
return len(password) >= 5
def v_upper(password):
return password.lower() != password
def v_2_nums(password):
return sum(c.isdigit() for c in password) >= 2
def v_no_e(password):
return "e" not in password.lower()
def v_specialchar(password):
any(s in password for s in "!##$%^&")
def validator(*tests):
def wrap(func):
def wrapped(*args, **kwargs):
result = func(*args, **kwargs)
if not all(test(result) for test in tests):
# fail the input somehow -- how??
return result
return wrapped
return wrap
#validator(v_length, v_upper, v_2_nums, v_no_e, v_specialchar)
def get_password():
pwd = input("Enter your password: ")
I like to wrap my validators in their own factories when I do this in real code, so that it's easier to change per application
def v_length(min_length):
def wrapped(password):
return len(password) >= min_length
return wrapped
#validator(v_length(8))
def get_weak_password():
input("Enter your wussy password: ")
#validator(v_length(64))
def get_strong_password():
input("Enter your Herculean password: ")
This second approach works well for checking for common passwords.
def v_common(common_pwd_set):
def wrapped(password):
return password not in common_pwd_set
return wrapped
COMMON_PASSWORDS = {"hunter2", "111111", "password"}
#validator(v_common(COMMON_PASSWORDS))
def get_password():
pwd = input("Use a tricksy one! ")
The following checks for each failure condition, with short-circuiting (it'll stop checking once it finds something). The "common" passwords aren't really common, but I wanted values that would pass the rest of the checks.
def passwordChecker(password):
'''
A password checker. Returns True if the password is acceptable; False otherwise.
'''
if (len(password) < 5 or
not any(c.isupper() for c in password) or
sum(c.isdigit() for c in password) < 2 or
'e' in password.lower() or
not (set(password) & set('!##$%^&')) or
password in {'Password12!', 'Passwd12!'}):
return False
return True
>>> passwordChecker('Password12!')
False
>>> passwordChecker('hi')
False
>>> passwordChecker('H12!')
False
>>> passwordChecker('Hi12!')
True
Yet another way to do this...
def passwordChecker(password):
return (len(password) > 4 and
len(filter(str.isupper, password)) > 0 and
len(filter(str.isdigit, password)) > 1 and
'e' not in password.lower() and
any(special in password for special in '!##$%^&') and
password not in ('password', '111111'))
I think the most interesting part of my solution is the use of filter; some people like it, others hate it. Anyway, all of the other solutions work just as well. Just thought I'd throw this one into the mix for completeness.

Python: How to display errors in "Making a Valid Password" and indicate if first character is a letter?

I'm trying to make a password with typical requirements like it has at least 1 uppercase/lowercase, etc. If the password is not valid according to the requirements, we have to display the errors in order for the user to try to get it correct again.
I started out with a while loop so that in the end the user will have an option to continue with another test or not. These are general steps I did.
At the end, if the user's text input is determined to not be valid, I have to display what his/her errors were. That's my main problem now. The code is better after a suggestion. Now I just have to display the errors somehow.
Here's how my code went
while True:
pw = input('Enter password to be tested if valid or not: ')
correct_length = False
uc_letter = False
lc_letter = False
digit = False
no_blanks = True
first_letter = False
if len(pw) >= 8:
correct_length = True
for ch in pw:
if ch.isupper():
uc_letter = True
if ch.islower():
lc_letter = True
if pw.isalnum():
digit = True
if pw[:1].isalpha():
first_letter = True
if not pw.find(' '):
no_blanks = True
if correct_length and uc_letter and lc_letter and digit and first_letter and no_blanks:
valid_pw = True
else:
valid_pw = False
#This is the part where I'm suppose to display the errors if the user gets it wrong.
#Initially, in the test for ch. above, I put in an else: with a print statement but because of the for- statement, it prints it out for every single character.
answer = input('Try another password input? y/n ')
if answer == 'y'
answer = True
else:
break
isdigit only returns True or False.
if ch.isdigit():
If you want to check if the first two characters are digits, do it outside the loop:
if pw[:2].isdigit():
digit = True
for ch in pw:
...
And to check if there are spaces in the string:
if not pw.find(' '):
no_blanks = True
Or if you want to escape all kinds of white spaces and blanks, including newline characters:
import string
...
if not any(c in string.whitespace for c in pw):
no_blanks = True
for ch in pw:
...
For the white space I would use (don't forget to import string):
import string
for ws in string.whitespace:
if ws in pw:
no_blanks = False
break
This checks for all kinds of white space, including for example Space and Tab
For the digits I would define dig_count = 0 before your for-loop.
Inside the for-loop:
if ch.isdigit():
dig_count += 1
After the for-loop:
if dig_count >= 2:
digit = True

Categories

Resources