@Phoenix's solution is good but not optimized for performance. I've taken their code and made some tweaks.
def check_password(password):
if len(password) > 8:
return False
has_uppercase = False
has_number = False
for c in password:
if not has_uppercase and c.isupper():
if has_number:
return True
has_uppercase = True
elif not has_number and c.isdigit():
if has_uppercase:
return True
has_number = True
return False
password = str(input("Please enter your password: "))
if check_password(password):
print("Successful password")
else:
print("Try again")
Benchmarks:
# check_password.py
import random
import string
def rand_password(max_length):
return "".join(
random.choices(
string.ascii_letters + string.digits, k=random.randint(1, max_length)
)
)
def check_password_1(password):
# Check if password has at least one uppercase letter
has_uppercase = any(c.isupper() for c in password)
# Check if password has at least one number
has_number = any(c.isdigit() for c in password)
# Check if password is no more than 8 characters long
is_short_enough = len(password) <= 8
# Return True if password meets all criteria, False otherwise
return has_uppercase and has_number and is_short_enough
def check_password_2(password):
if len(password) > 8:
return False
has_uppercase = False
has_number = False
for c in password:
if not has_uppercase and c.isupper():
if has_number:
return True
has_uppercase = True
elif not has_number and c.isdigit():
if has_uppercase:
return True
has_number = True
return False
In [1]: import random
...: from check_password import rand_password, check_password_1, check_password_2
In [2]: random.seed(1)
In [3]: %timeit check_password_1(rand_password(16))
5.38 µs ± 50.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
In [4]: random.seed(1)
In [5]: %timeit check_password_2(rand_password(16))
4.3 µs ± 62.2 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
1or2, why notTrueorFalse?