Password Generator

Python Projects — Password Generator
Python Projects (Beginner)
Course 4 · Chapter 3 · Password Generator

🔐 Password Generator

A customizable password generator — but the real lesson in this chapter isn't string handling, it's a genuinely important distinction most beginners never hear explicitly: random and secrets look similar but are not interchangeable for anything security-related.

🎮 What We're Building

A tool that asks how long the password should be and which character types to include (lowercase, uppercase, digits, symbols), then generates a genuinely random password matching those choices.

Step 1: Character Pools with the string Module

import string print(string.ascii_lowercase) # abcdefghijklmnopqrstuvwxyz print(string.ascii_uppercase) # ABCDEFGHIJKLMNOPQRSTUVWXYZ print(string.digits) # 0123456789 print(string.punctuation) # !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~

The string module provides these character sets as ready-made constants — no need to type them out by hand. Combining the ones you want (with +, Course 1, Chapter 5's string concatenation) builds the pool a password's characters get picked from.

Step 2: random vs secrets — Choosing the Right Tool

import random import secrets random.choice("abc") # fine for games, simulations, non-security randomness secrets.choice("abc") # the correct choice for anything security-sensitive
⚠ random Is Not Cryptographically Secure

Course 1, Chapter 9 and the earlier projects in this course used random for a dice roll and a secret number — perfectly fine there, since nothing security-sensitive depended on it. random's numbers are generated by a pseudo-random algorithm that is predictable if an attacker can determine its internal state — completely unacceptable for passwords, tokens, or anything else where guessability matters. The secrets module exists specifically for this: it's built on a cryptographically secure random source, and secrets.choice() is the correct replacement for random.choice() anywhere security is actually at stake.

Step 3: Building the Password

pool = string.ascii_lowercase + string.ascii_uppercase + string.digits password = "".join(secrets.choice(pool) for _ in range(12)) print(password)

A generator expression (Course 2, Chapter 5) calls secrets.choice(pool) once per character, 12 times; "".join(...) (Course 1, Chapter 5) combines the individual characters into one final string. _ is a common convention for a loop variable whose actual value is never used — only the number of repetitions matters here.

Step 4: Letting the User Customize It

length = int(input("Password length: ")) use_upper = input("Include uppercase? (y/n): ").lower() == "y" use_digits = input("Include digits? (y/n): ").lower() == "y" use_symbols = input("Include symbols? (y/n): ").lower() == "y" pool = string.ascii_lowercase if use_upper: pool += string.ascii_uppercase if use_digits: pool += string.digits if use_symbols: pool += string.punctuation

Each if check (Course 1, Chapter 3) conditionally grows the character pool — pool += is the same string-concatenation-as-accumulation pattern from Course 1, Chapter 4's loop-accumulator idea, just applied once per option instead of once per loop iteration.

🏁 The Complete Password Generator

import string import secrets length = int(input("Password length: ")) use_upper = input("Include uppercase? (y/n): ").lower() == "y" use_digits = input("Include digits? (y/n): ").lower() == "y" use_symbols = input("Include symbols? (y/n): ").lower() == "y" pool = string.ascii_lowercase if use_upper: pool += string.ascii_uppercase if use_digits: pool += string.digits if use_symbols: pool += string.punctuation password = "".join(secrets.choice(pool) for _ in range(length)) print(f"Your password: {password}")

string module

ascii_lowercase, ascii_uppercase, digits, punctuation — ready-made character sets.

secrets, not random

Cryptographically secure — the correct choice for anything security-sensitive.

Conditional pool building

Each if optionally adds a character set based on user choice.

Generator expression + join

Builds the final password one character at a time, joined into a string.

🚀 Extend This Project

Try these on your own:

  • Guarantee at least one character from each selected type appears (right now, a short password could randomly end up all lowercase even with other options enabled) — build one guaranteed character per selected type first, then fill the rest randomly.
  • Add input validation with try/except (Course 2, Chapter 3) around the length input.
  • Generate several passwords at once and let the user pick their favorite from a numbered list.
  • Add a simple strength estimate — print "weak"/"medium"/"strong" based on length and how many character types were included.

🎯 What's Next

Next chapter: To-Do List CLI App — functions and basic persistence to a text/JSON file.