5 Python Projects
to Build Today

Stop watching, start building. Each project takes 1-3 hours, teaches real skills, and gives you something you can actually show off.

1-3 hours each
📊 Beginner friendly
🧠 Real skills, real output
1
Password Generator
Build a tool you'll actually use every week

Create a program that generates secure, random passwords. The user picks a length and which character types to include (letters, numbers, symbols) — then gets a strong password instantly. Simple to build, genuinely useful, and a great intro to working with randomness in Python.

random modulestring manipulationuser inputfunctions
import random
import string

def generate_password(length, use_symbols=True):
    characters = string.ascii_letters + string.digits
    if use_symbols:
        characters += string.punctuation

    password = ""
    for i in range(length):
        password += random.choice(characters)
    return password

# Ask the user
length = int(input("Password length: "))
symbols = input("Include symbols? (y/n): ")

result = generate_password(length, symbols == "y")
print(f"Your password: {result}")

Try using random.shuffle() on a list of characters to make the password even more random. You can also add a check that ensures at least one uppercase letter, one digit, and one symbol are always included.

Stretch challenge

Add a "password strength" checker that rates the generated password as Weak, Medium, or Strong based on its length and character variety. Then generate multiple passwords and let the user pick their favourite.

2
Quiz Game
Test your friends (or yourself) with a custom quiz

Build a multiple-choice quiz game that asks questions, tracks your score, and tells you how you did at the end. You'll store the questions as a list of dictionaries — one of the most common data structures you'll use in real Python work.

lists & dictionariesfor loopsif/else logicscore tracking
questions = [
    {
        "question": "What does HTML stand for?",
        "options": ["A) Hyper Text Markup Language",
                    "B) Hot Mail",
                    "C) How To Make Lasagna"],
        "answer": "A"
    },
    {
        "question": "Which planet is closest to the Sun?",
        "options": ["A) Earth", "B) Mercury", "C) Venus"],
        "answer": "B"
    }
]

score = 0

for q in questions:
    print(q["question"])
    for option in q["options"]:
        print(f"  {option}")
    user_answer = input("Your answer: ").upper()

    if user_answer == q["answer"]:
        print("Correct!\n")
        score += 1
    else:
        print(f"Wrong! The answer was {q['answer']}\n")

print(f"You scored {score}/{len(questions)}")

Add more questions to the list — the loop handles any number automatically. Try using random.shuffle(questions) at the start to randomise the order each time.

Stretch challenge

Add a timer using the time module to track how long the quiz takes. Show the final time alongside the score. Bonus: add difficulty levels that change how many options each question has.

3
Expense Tracker
Where does your money actually go?

Build a command-line app that logs expenses, categorises them, and shows you a summary. You'll save everything to a CSV file so nothing gets lost — and you'll learn how real applications store and retrieve data. This is the kind of project that makes a portfolio look serious.

file I/O (CSV)dictionariesdata analysiswhile loops
import csv
from datetime import datetime

def add_expense(expenses):
    amount = float(input("Amount: £"))
    category = input("Category (food/transport/other): ")
    note = input("Note: ")
    expenses.append({
        "date": datetime.now().strftime("%Y-%m-%d"),
        "amount": amount,
        "category": category,
        "note": note
    })
    print("Expense added!\n")

def show_summary(expenses):
    total = sum(e["amount"] for e in expenses)
    print(f"\nTotal spent: £{total:.2f}")
    categories = set(e["category"] for e in expenses)
    for cat in categories:
        cat_total = sum(e["amount"] for e in expenses
                       if e["category"] == cat)
        print(f"  {cat}: £{cat_total:.2f}")

expenses = []

while True:
    action = input("(a)dd / (s)ummary / (q)uit: ")
    if action == "a":
        add_expense(expenses)
    elif action == "s":
        show_summary(expenses)
    elif action == "q":
        break

To save expenses permanently, write them to a CSV file using csv.DictWriter. Load them back in when the program starts with csv.DictReader. This way your data survives between sessions.

Stretch challenge

Use pandas to read the CSV and create a monthly spending breakdown. Which category do you spend the most on? Can you spot any patterns?

4
Web Scraper
Pull real data from the internet automatically

Write a script that visits a website and extracts useful data automatically. You'll use the requests library to fetch pages and BeautifulSoup to parse the HTML. Then you'll scrape multiple pages, clean up the data, and save it all to a CSV file. This is one of the most in-demand Python skills — every data role mentions it.

requests libraryBeautifulSoupHTML parsingpaginationsaving to CSV
# First, install: pip install requests beautifulsoup4 pandas

import requests
from bs4 import BeautifulSoup
import pandas as pd

# Step 1: Scrape 5 pages of quotes
all_data = []

for page in range(1, 6):
    url = f"https://quotes.toscrape.com/page/{page}/"
    response = requests.get(url)
    soup = BeautifulSoup(response.text, "html.parser")

    for quote in soup.find_all("div", class_="quote"):
        text = quote.find("span", class_="text").text
        author = quote.find("small", class_="author").text
        all_data.append({"quote": text, "author": author})

    print(f"Page {page} done — {len(all_data)} quotes so far")

# Step 2: Save to CSV
df = pd.DataFrame(all_data)
df.to_csv("quotes.csv", index=False)
print(f"\nSaved {len(df)} quotes to quotes.csv")

# Step 3: Quick analysis
print(f"\nTop 5 most quoted authors:")
print(df["author"].value_counts().head(5))

Install the libraries first: pip install requests beautifulsoup4 pandas. The site used here is built specifically for scraping practice, so you won't get blocked. Use your browser's "Inspect Element" to understand the HTML structure before writing your selectors.

Stretch challenge

Find which tags appear most often across all quotes. Create a bar chart of the top 10 tags using matplotlib. Then try scraping a different website — like a news homepage or a product listing page.

5
Data Explorer
Analyse a real dataset and find the story in the numbers

Load a real CSV dataset with pandas, explore it, clean it up, and answer questions about it. You'll calculate averages, group data, find patterns, and create visualisations. This is what data scientists do every single day — and it's more satisfying than you'd think.

pandasdata cleaninggroupby & aggregationmatplotlib chartsreal-world analysis
# First, install: pip install pandas matplotlib

import pandas as pd
import matplotlib.pyplot as plt

# Step 1: Load a real dataset (restaurant tips)
url = ("https://raw.githubusercontent.com/mwaskom/"
       "seaborn-data/master/tips.csv")
df = pd.read_csv(url)

# Step 2: Explore the data
print("First 5 rows:")
print(df.head())
print(f"\nShape: {df.shape[0]} rows, {df.shape[1]} columns")
print(f"\nColumn names: {list(df.columns)}")

# Step 3: Basic statistics
print(f"\nAverage bill: ${df['total_bill'].mean():.2f}")
print(f"Average tip:  ${df['tip'].mean():.2f}")
print(f"Highest tip:  ${df['tip'].max():.2f}")

# Step 4: Create a new column — tip percentage
df["tip_pct"] = df["tip"] / df["total_bill"] * 100
print(f"\nAverage tip percentage: {df['tip_pct'].mean():.1f}%")

# Step 5: Group by day — which day gets the best tips?
by_day = df.groupby("day")["tip_pct"].mean().sort_values()
print(f"\nAverage tip % by day:")
print(by_day)

# Step 6: Do smokers tip differently?
by_smoker = df.groupby("smoker")["tip_pct"].mean()
print(f"\nAverage tip % by smoker status:")
print(by_smoker)

# Step 7: Visualise — bar chart of tips by day
fig, axes = plt.subplots(1, 2, figsize=(12, 5))

by_day.plot(kind="bar", color="#4CAF50", ax=axes[0])
axes[0].set_title("Average Tip % by Day")
axes[0].set_ylabel("Tip %")

# Scatter plot — bill vs tip
axes[1].scatter(df["total_bill"], df["tip"],
               alpha=0.6, color="#4CAF50")
axes[1].set_title("Bill Amount vs Tip")
axes[1].set_xlabel("Total Bill ($)")
axes[1].set_ylabel("Tip ($)")

plt.tight_layout()
plt.savefig("tips_analysis.png")
print("\nCharts saved as tips_analysis.png")

Install pandas and matplotlib first: pip install pandas matplotlib. The dataset loads directly from a URL — no file downloads needed. Use df.describe() to get a quick statistical overview of every numeric column. If you want to use your own data, just replace the URL with a path to your Excel or CSV file.

Stretch challenge

Does table size affect tip percentage? Group by size and find out. Then create a third chart — a histogram showing the distribution of tip percentages. What's the most common tip range?