Python for Analytics — Practice Exercises¶
Consolidation exercises covering all Python basics topics: variables, control flow, functions, lists, dicts, file I/O, and data pipelines. These mirror the kinds of tasks you'd do as an analyst on the first day of a new job.
Setup¶
# Sample dataset — paste this at the top of your notebook
orders = [
{"order_id": "O001", "customer_id": "C001", "product": "Headphones",
"category": "Electronics", "quantity": 2, "unit_price": 149.00,
"status": "completed", "month": "2024-01"},
{"order_id": "O002", "customer_id": "C003", "product": "Standing Desk",
"category": "Furniture", "quantity": 1, "unit_price": 389.00,
"status": "completed", "month": "2024-01"},
{"order_id": "O003", "customer_id": "C002", "product": "Analytics Book",
"category": "Books", "quantity": 3, "unit_price": 49.99,
"status": "pending", "month": "2024-01"},
{"order_id": "O004", "customer_id": "C001", "product": "Yoga Mat",
"category": "Sports", "quantity": 1, "unit_price": 35.99,
"status": "completed", "month": "2024-02"},
{"order_id": "O005", "customer_id": "C004", "product": "Headphones",
"category": "Electronics", "quantity": 1, "unit_price": 149.00,
"status": "cancelled", "month": "2024-02"},
{"order_id": "O006", "customer_id": "C003", "product": "Analytics Book",
"category": "Books", "quantity": 5, "unit_price": 49.99,
"status": "completed", "month": "2024-02"},
{"order_id": "O007", "customer_id": "C005", "product": "Coffee Maker",
"category": "Kitchen", "quantity": 2, "unit_price": 89.99,
"status": "completed", "month": "2024-02"},
{"order_id": "O008", "customer_id": "C002", "product": "Standing Desk",
"category": "Furniture", "quantity": 1, "unit_price": 389.00,
"status": "pending", "month": "2024-03"},
]
# Add calculated total to each order
for o in orders:
o["total"] = o["quantity"] * o["unit_price"]
Level 1 — Basics¶
Exercise 1.1 — Count and filter
Count how many orders are 'completed', 'pending', and 'cancelled' respectively. Use a Counter.
Exercise 1.2 — Totals Calculate the total revenue from completed orders only.
Exercise 1.3 — List comprehension
Create a list of all order_id values for completed orders. Use a list comprehension.
Exercise 1.4 — F-string formatting Print a summary line for each order:
(Use the customer_id as the name — we don't have names in this dataset yet.)Show answers
from collections import Counter
# 1.1
status_counts = Counter(o["status"] for o in orders)
print(status_counts)
# 1.2
completed_revenue = sum(o["total"] for o in orders if o["status"] == "completed")
print(f"Completed revenue: £{completed_revenue:,.2f}")
# 1.3
completed_ids = [o["order_id"] for o in orders if o["status"] == "completed"]
print(completed_ids)
# 1.4
for o in orders:
flag = "✓" if o["status"] == "completed" else "✗"
print(f"{o['order_id']} | {o['customer_id']:<8} | {o['product']:<18} | £{o['total']:>7.2f} | {flag}")
Level 2 — Functions and Grouping¶
Exercise 2.1 — Write a function
Write a function order_summary(orders) that takes the orders list and returns a dict with:
- total_orders: total count
- completed_orders: count of completed
- total_revenue: sum of totals for completed orders
- avg_order_value: mean total for completed orders
- completion_rate: completed / total as a float (e.g., 0.625)
Exercise 2.2 — Group by
Group orders by category. For each category, print: category name, number of completed orders, and total revenue.
Exercise 2.3 — Monthly trend Calculate revenue per month (completed orders only). Print the months in order with their revenue and month-over-month change.
Show answers
import statistics
from collections import defaultdict
# 2.1
def order_summary(orders):
completed = [o for o in orders if o["status"] == "completed"]
totals = [o["total"] for o in completed]
return {
"total_orders": len(orders),
"completed_orders": len(completed),
"total_revenue": sum(totals),
"avg_order_value": statistics.mean(totals) if totals else 0,
"completion_rate": len(completed) / len(orders) if orders else 0,
}
summary = order_summary(orders)
for k, v in summary.items():
if isinstance(v, float):
print(f"{k}: {v:.2f}")
else:
print(f"{k}: {v}")
# 2.2
by_category = defaultdict(lambda: {"orders": 0, "revenue": 0.0})
for o in orders:
if o["status"] == "completed":
by_category[o["category"]]["orders"] += 1
by_category[o["category"]]["revenue"] += o["total"]
for cat, data in sorted(by_category.items(), key=lambda x: -x[1]["revenue"]):
print(f"{cat:20} | {data['orders']} orders | £{data['revenue']:,.2f}")
# 2.3
by_month = defaultdict(float)
for o in orders:
if o["status"] == "completed":
by_month[o["month"]] += o["total"]
months = sorted(by_month.keys())
prev = None
for month in months:
rev = by_month[month]
if prev is not None:
change = (rev - prev) / prev * 100
print(f"{month}: £{rev:,.2f} ({change:+.1f}%)")
else:
print(f"{month}: £{rev:,.2f}")
prev = rev
Level 3 — Stretch¶
Exercise 3.1 — Top customers
Write a function top_customers(orders, n=3) that returns a list of the top N customers by total spend (completed orders only), as a list of dicts sorted by spend descending.
Expected output shape:
[
{"customer_id": "C003", "orders": 2, "total_spend": 638.95},
{"customer_id": "C001", "orders": 2, "total_spend": 333.99},
...
]
Exercise 3.2 — Outlier detection
Write a function flag_outliers(orders) that flags orders where the total is more than 2 standard deviations above the mean of completed orders. Return a list of outlier order_id values.
Exercise 3.3 — Export pipeline
Write a complete pipeline that:
1. Loads orders from a CSV file (orders.csv)
2. Adds the calculated total column
3. Filters to completed orders
4. Groups by category
5. Exports the category summary to category_summary.csv
Show answers
from collections import defaultdict
import statistics, csv
# 3.1
def top_customers(orders, n=3):
by_customer = defaultdict(lambda: {"orders": 0, "total_spend": 0.0})
for o in orders:
if o["status"] == "completed":
cid = o["customer_id"]
by_customer[cid]["orders"] += 1
by_customer[cid]["total_spend"] += o["total"]
result = [
{"customer_id": cid, **data}
for cid, data in by_customer.items()
]
return sorted(result, key=lambda x: -x["total_spend"])[:n]
for c in top_customers(orders):
print(f"{c['customer_id']}: {c['orders']} orders, £{c['total_spend']:,.2f}")
# 3.2
def flag_outliers(orders):
completed_totals = [o["total"] for o in orders if o["status"] == "completed"]
mean = statistics.mean(completed_totals)
std = statistics.stdev(completed_totals)
threshold = mean + 2 * std
return [o["order_id"] for o in orders if o["total"] > threshold]
print("Outlier orders:", flag_outliers(orders))
# 3.3
def run_pipeline(input_path, output_path):
# Load
with open(input_path, "r", newline="", encoding="utf-8") as f:
raw = list(csv.DictReader(f))
# Transform
orders = [
{**o, "total": float(o["quantity"]) * float(o["unit_price"])}
for o in raw
]
# Filter and group
by_category = defaultdict(lambda: {"orders": 0, "revenue": 0.0})
for o in orders:
if o["status"] == "completed":
by_category[o["category"]]["orders"] += 1
by_category[o["category"]]["revenue"] += o["total"]
# Export
rows = [
{"category": cat, **data}
for cat, data in sorted(by_category.items(), key=lambda x: -x[1]["revenue"])
]
with open(output_path, "w", newline="", encoding="utf-8") as f:
writer = csv.DictWriter(f, fieldnames=["category", "orders", "revenue"])
writer.writeheader()
writer.writerows(rows)
print(f"Exported {len(rows)} categories to {output_path}")