Password Strength Auditor
Build the password checker every signup form runs: length rules, character variety, a scoring engine, and a batch audit that flags weak passwords.
How it works in the real world
When a signup form says "password too weak", this is the code behind it:
- Rules — small boolean functions, one per rule (length, digits, case…).
- Scoring — combine rule results into a score, map score → rating.
- Batch audit — run the scorer over many passwords and report the weak ones, exactly what a security team does after a breach.
Small pure functions composed into a pipeline — this is professional code structure in miniature.
The length rule
Write is_long_enough(pw) returning True when the password has at least 10 characters. Print the result for "secret" and "correcthorse".
return len(pw) >= 10 — a comparison already IS a boolean; no if needed.
def is_long_enough(pw):
return len(pw) >= 10
print(is_long_enough("secret"))
print(is_long_enough("correcthorse"))
Run your code to check this step…
The variety rule
Write has_variety(pw): True only if the password contains at least one digit, one uppercase and one lowercase letter. Test on "password1" and "Password1".
any(ch.isdigit() for ch in pw) checks digits — combine three of these with and.
def has_variety(pw):
has_digit = any(ch.isdigit() for ch in pw)
has_upper = any(ch.isupper() for ch in pw)
has_lower = any(ch.islower() for ch in pw)
return has_digit and has_upper and has_lower
print(has_variety("password1"))
print(has_variety("Password1"))
Run your code to check this step…
The scoring engine
Write strength(pw): score +1 each for length ≥ 10, any digit, any uppercase, any symbol from !@#$%^&*. Return "weak" (0–1), "okay" (2–3) or "strong" (4). Test the three prints.
score += len(pw) >= 10 works — True counts as 1! Symbols: any(ch in "!@#$%^&*" for ch in pw).
def strength(pw):
score = 0
score += len(pw) >= 10
score += any(ch.isdigit() for ch in pw)
score += any(ch.isupper() for ch in pw)
score += any(ch in "!@#$%^&*" for ch in pw)
if score <= 1:
return "weak"
if score <= 3:
return "okay"
return "strong"
print(strength("cat"))
print(strength("Tr0ub4dor!"))
print(strength("password123"))
Run your code to check this step…
The batch audit
Run the auditor over the list: print each weak password as name: weak, then a summary 2 of 4 passwords need changing.
Count the weak ones while looping, print each as you find it, then the summary line.
def strength(pw):
score = 0
score += len(pw) >= 10
score += any(ch.isdigit() for ch in pw)
score += any(ch.isupper() for ch in pw)
score += any(ch in "!@#$%^&*" for ch in pw)
if score <= 1:
return "weak"
if score <= 3:
return "okay"
return "strong"
passwords = ["hunter2", "Sup3rSecret!", "letmein", "N1nja#Warrior"]
weak = 0
for pw in passwords:
if strength(pw) == "weak":
print(f"{pw}: weak")
weak += 1
print(f"{weak} of {len(passwords)} passwords need changing")
Run your code to check this step…
Project shipped!
You just built a complete, working password strength auditor — the same architecture running in production software. Pick your next build →