Password Generator
BasicCreate strong, random passwords with Python
1) Project Overview
You will build a small program that creates a strong, random password for the user. The user chooses:
- How long the password should be
- Whether to include lowercase letters, uppercase letters, numbers, and symbols
The program then mixes characters randomly and prints a password that is hard to guess.
2) Learning Objectives
By the end of this project, students will:
- Use variables, strings, and lists
- Get input from the user and validate it
- Use decision-making with if/else
- Use loops (while and for)
- Use the random module to pick random characters
- Combine small steps to solve a real problem
3) Step-by-Step Explanation
- Plan the character groups:
- Lowercase letters: abcdefghijklmnopqrstuvwxyz
- Uppercase letters: ABCDEFGHIJKLMNOPQRSTUVWXYZ
- Digits: 0123456789
- Symbols: !@#$%^&*()-_=+[]{};:,.?/
- Import the random module to pick random characters and shuffle them.
- Ask the user for a password length (for example, 4 to 64).
- Ask the user yes/no questions to include lowercase, uppercase, digits, and symbols.
- Check that the user picked at least one type. If not, ask again.
- Make sure the chosen length is big enough to include at least one character from each picked type. If not, ask again.
- Build the password:
- First, guarantee at least one character from each selected group.
- Then, fill the rest with random characters from all the chosen groups.
- Shuffle the characters so the guaranteed ones are not always at the front.
- Join the characters together and print the final password.
4) Complete and well-commented Python code
Note: This uses only the built-in random module.
import random
# Character groups to choose from
LOWERCASE = "abcdefghijklmnopqrstuvwxyz"
UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
DIGITS = "0123456789"
SYMBOLS = "!@#$%^&*()-_=+[]{};:,.?/"
def get_yes_no(prompt):
"""
Ask a yes/no question until the user answers clearly.
Returns True for yes, False for no.
"""
while True:
answer = input(prompt + " (y/n): ").strip().lower()
if answer in ("y", "yes"):
return True
if answer in ("n", "no"):
return False
print("Please type 'y' for yes or 'n' for no.")
def get_int_in_range(prompt, min_value, max_value):
"""
Ask for a whole number within [min_value, max_value].
Re-asks if the input is not valid.
"""
while True:
text = input(f"{prompt} ({min_value}-{max_value}): ").strip()
try:
value = int(text)
if min_value <= value <= max_value:
return value
else:
print(f"Please enter a number between {min_value} and {max_value}.")
except ValueError:
print("That doesn't look like a whole number. Try again.")
def generate_password(length, use_lower, use_upper, use_digits, use_symbols):
"""
Generate a password of 'length' using the selected character groups.
Ensures at least one character from each selected group.
"""
# Collect all allowed characters in one string
allowed = ""
if use_lower:
allowed += LOWERCASE
if use_upper:
allowed += UPPERCASE
if use_digits:
allowed += DIGITS
if use_symbols:
allowed += SYMBOLS
# Safety check: if nothing is selected, return empty string
if not allowed:
return ""
password_chars = []
# Guarantee at least one from each selected group
if use_lower:
password_chars.append(random.choice(LOWERCASE))
if use_upper:
password_chars.append(random.choice(UPPERCASE))
if use_digits:
password_chars.append(random.choice(DIGITS))
if use_symbols:
password_chars.append(random.choice(SYMBOLS))
# Fill the remaining characters randomly from all allowed
remaining = length - len(password_chars)
for _ in range(remaining):
password_chars.append(random.choice(allowed))
# Shuffle so the guaranteed characters aren't always at the start
random.shuffle(password_chars)
# Join the list into a single string
return "".join(password_chars)
def main():
print("Welcome to the Simple Password Generator!")
print("Answer a few questions, and I'll make a secure password for you.\n")
# Keep asking until we have valid choices and length
while True:
# 1) Ask for desired length
length = get_int_in_range("Choose password length", 4, 64)
# 2) Ask which groups to include
use_lower = get_yes_no("Include lowercase letters (a-z)?")
use_upper = get_yes_no("Include uppercase letters (A-Z)?")
use_digits = get_yes_no("Include digits (0-9)?")
use_symbols = get_yes_no("Include symbols (!@#$...)?")
# 3) Make sure at least one group is chosen
selected_count = sum([use_lower, use_upper, use_digits, use_symbols])
if selected_count == 0:
print("\nYou must pick at least one type of character. Let's try again.\n")
continue
# 4) Make sure length can fit at least one from each selected group
if length < selected_count:
print(f"\nLength is too small for your choices.")
print(f"You selected {selected_count} character types, so length must be at least {selected_count}.")
print("Let's try again.\n")
continue
# If everything is valid, break out of the loop
break
# Generate and show the password
password = generate_password(length, use_lower, use_upper, use_digits, use_symbols)
print("\nYour new password is:")
print(password)
print("\nKeep it somewhere safe!")
if __name__ == "__main__":
main()
5) Output examples
Example 1: Typical run
Answer a few questions, and I'll make a secure password for you.
Choose password length (4-64): 12
Include lowercase letters (a-z)? (y/n): y
Include uppercase letters (A-Z)? (y/n): y
Include digits (0-9)? (y/n): y
Include symbols (!@#$...)? (y/n): n
Your new password is:
fG6aQwD1uzpB
Keep it somewhere safe!
Example 2: Not enough length for chosen types
Include lowercase letters (a-z)? (y/n): y
Include uppercase letters (A-Z)? (y/n): y
Include digits (0-9)? (y/n): y
Include symbols (!@#$...)? (y/n): n
Length is too small for your choices.
You selected 3 character types, so length must be at least 3.
Let's try again.
Choose password length (4-64): 8
Include lowercase letters (a-z)? (y/n): y
Include uppercase letters (A-Z)? (y/n): n
Include digits (0-9)? (y/n): y
Include symbols (!@#$...)? (y/n): n
Your new password is:
m7k3w20b
Keep it somewhere safe!
Example 3: User forgets to pick any type
Include lowercase letters (a-z)? (y/n): n
Include uppercase letters (A-Z)? (y/n): n
Include digits (0-9)? (y/n): n
Include symbols (!@#$...)? (y/n): n
You must pick at least one type of character. Let's try again.
6) Small Exercise
Challenge: Let the user generate several passwords at once
- Ask: "How many passwords do you want?" (for example, 1–10)
- Use a loop to call
generate_passwordthat many times. - Print each password on a new line with a number (like #1, #2, #3).
Bonus idea: Add an option to avoid similar-looking characters such as 0 and O, or 1 and l.
7) Summary
Great job! You learned how to take user input, make smart checks, and use randomness to build strong passwords. These are the same building blocks used in many real programs. Keep experimenting, try the small exercise, and have fun turning your ideas into code!