3

I've looked at the other post similar to my question, Password check- Python 3, except my question involves checking if the password contains both uppercase and lower case questions. My code is the following, but when executed it fails to recognize that both lower and upper case letters are in the password, it only recognizes one type. How would I get it to recognize both types? Also is there an easier way to have the code check if all of those values occur without having to make functions for each individual step?

def Get_Password():
    return input("Enter your desired password: ")

def Count_Digits(password):
    return sum(character.isdigit() for character in password)

def Valid_password_length(password):
    if len(password) >= 10:
        return ('step1' == True)
    else:
        return ('step1' == False, print("Invalid password: too short"))

def Valid_password_characters(password):
    if password.isalnum():
        return ('step2' == True)
    else:
        return ('step2' == False, print("Invalid password: illegal character detected"))

def Valid_password_numdigit(password):
    if Count_Digits(password) >= 2:
        return ('step3' == True)
    else:
        return ('step3' == False, print("Invalid password: Must have at least 2 digits"))

def Valid_password_lowercase(password):
    for i in (password):
        if i.islower() == True:
            return ('step4' == True)
        else:
            return ('step4' == False, print("Invalid password: No lowercase characters detected"))

def Valid_password_uppercase(password):
    for i in (password):
        if i.isupper() == True:
            return ('step5' == True)
        else:
            return ('step5' == False, print("Invalid password: No uppercase characters detected"))

def password_checker():
    password = Get_Password()
    Valid_password_length(password)
    Valid_password_characters(password)
    Valid_password_numdigit(password)
    Valid_password_lowercase(password)
    Valid_password_uppercase(password)

    if 'step1' and 'step2' and 'step3' and 'step4' and 'step5' == True:
        print("Congratulations! This password is valid")

password_checker()
Community
  • 1
  • 1
Ashton
  • 33
  • 1
  • 1
  • 3
  • 7
    Why do you have `return ('stepX' == True)`? That's the same thing as `return False` since a string is not equal to any boolean. – mgilson Oct 12 '16 at 05:28
  • Also you are returning tuples in the False cases. To add to that you dont even inspect the return values of the functions. – Paul Rooney Oct 12 '16 at 06:01

4 Answers4

5
import sys

def Valid_password_mixed_case(password):
    letters = set(password)
    mixed = any(letter.islower() for letter in letters) and any(letter.isupper() for letter in letters)
    if not mixed:
        print("Invalid password: Mixed case characters not detected", file=sys.stderr)
    return mixed

A complete solution:

import sys

def Get_Password():
    return input("Enter your desired password: ")

def Count_Digits(password):
    return sum(1 for character in password if character.isdigit())

def Valid_password_length(password):
    correct_length = len(password) >= 10

    if not correct_length:
        print("Invalid password: too short", file=sys.stderr)

    return correct_length

def Valid_password_characters(password):
    correct_characters = password.isalnum()

    if not correct_characters:
        print("Invalid password: illegal character detected", file=sys.stderr)

    return correct_characters

def Valid_password_numdigit(password):
    sufficient_digits = Count_Digits(password) >= 2

    if not sufficient_digits:
        print("Invalid password: Must have at least 2 digits", file=sys.stderr)

    return sufficient_digits

def Valid_password_mixed_case(password):
    letters = set(password)

    lower = any(letter.islower() for letter in letters)
    upper = any(letter.isupper() for letter in letters)

    if not upper:
        print("Invalid password: No uppercase characters detected", file=sys.stderr)

    if not lower:
        print("Invalid password: No lowercase characters detected", file=sys.stderr)

    return lower and upper

def password_checker():
    password = Get_Password()
    if Valid_password_length(password) and \
        Valid_password_characters(password) and \
        Valid_password_numdigit(password) and \
        Valid_password_mixed_case(password):

        print("Congratulations! This password is valid")

password_checker()
cdlane
  • 33,404
  • 4
  • 23
  • 63
0

Your question is simple to answer. You are returning things of the form return('steps' == True) which is always going to return false. So just replace those with return True or return False.

Assuming you fix the above, your looping is also buggy. You only want to return false after you have looped through the entire string. Consider the password: ABCd. This contains a lowercase character but your check lowercase method would return false because the first letter is uppercase. You want to look through every character in password and if none of those are lowercase, then return false.

If you want a neater way to do it, cdlane's answer is a nice pythonic way.

Community
  • 1
  • 1
gowrath
  • 2,676
  • 2
  • 14
  • 29
0

Answer to question Break line not executing marked as duplicated:

password = input('Enter your password')
password_letters = list(password)
upper = False
lower = False
name = 'Papa'
surname = 'Johns'

for letter in password_letters:
    if letter.isupper():
        upper = True
    elif letter.islower():
        lower = True

    if upper and lower:
        break

if len(password) <= 5:
    print('password is to short')
elif name.lower() in password.lower() or surname.lower() in password.lower():
    print('You cannot have first or last name in password')
elif not (upper and lower):
    print('You must have both upper and lower case in password')
else:
    print('Password is valid')
epinal
  • 1,063
  • 10
  • 24
-1

You could use regular expression :

i.e. :

def Valid_mixed_password(password):
    lower = re.compile(r'.*[a-z]+') # Compile to match lowercase
    upper = re.compile(r'.*[A-Z]+') # Compile to match uppercase
    if lower.match(password) and upper.match(password): # if the password contains both (lowercase and uppercase letters) then return True
        return True
    else: # Else, the password does not contains uppercase and lowercase letters then return False
        return False

>>> print Valid_mixed_password("hello")
False
>>> print Valid_mixed_password("HELLO")
False
>>> print Valid_mixed_password("HellO")
True
>>> print Valid_mixed_password("heLLo")
True

Hope it helps.

JazZ
  • 4,062
  • 2
  • 15
  • 36