Build a Sales Performance Dashboard with KPI Analysis
Every business runs on sales data. Managers want to know which products are selling, which regions are performing, and whether things are getting better or worse. In this project, you'll build a complete sales analysis pipeline that answers these questions.
You'll start with raw transaction data and build up to a formatted report with KPIs, breakdowns, and growth metrics. This is the kind of work a data analyst does every week.
Step 1: Create the Sales Dataset
Our dataset represents three months of sales transactions for a small electronics company. Each row is a single sale with the date, product, salesperson, region, quantity, and unit price.
Notice that we immediately calculate a revenue column by multiplying quantity by unit price. This is a derived column that we'll use throughout the analysis.
Create a sales DataFrame from the provided data dictionary. Then:
1. Convert the date column to datetime using pd.to_datetime()
2. Add a revenue column (quantity * unit_price)
3. Add a month column that extracts the month name from the date (use .dt.strftime('%B') to get full month names like "January")
4. Print the total number of transactions and the columns list.
import pandas as pd
sales_data = {
'date': ['2024-01-05', '2024-01-15', '2024-02-03', '2024-02-18', '2024-03-01', '2024-03-15'],
'product': ['Laptop', 'Phone', 'Tablet', 'Laptop', 'Phone', 'Tablet'],
'quantity': [2, 5, 3, 1, 4, 2],
'unit_price': [999.99, 699.99, 449.99, 999.99, 699.99, 449.99]
}
# Create DataFrame and add columns
Step 2: Calculate Key Performance Indicators (KPIs)
KPIs are the numbers that tell you how the business is doing at a glance. For a sales team, the most important ones are total revenue, number of transactions, average order value, and total units sold. Let's calculate them all.
Write a function calculate_kpis(df) that takes a sales DataFrame (with a revenue and quantity column) and returns a dictionary with these keys:
total_revenue: sum of all revenuetransaction_count: number of rowsavg_order_value: mean revenue per transactiontotal_units: sum of all quantitiesavg_unit_price: total revenue divided by total unitsPrint each KPI formatted with 2 decimal places.
import pandas as pd
def calculate_kpis(df):
# Your code here
pass
data = {
'product': ['Laptop', 'Phone', 'Tablet', 'Laptop', 'Phone'],
'quantity': [2, 5, 3, 1, 4],
'unit_price': [999.99, 699.99, 449.99, 999.99, 699.99],
}
df = pd.DataFrame(data)
df['revenue'] = df['quantity'] * df['unit_price']
kpis = calculate_kpis(df)
for key, value in kpis.items():
print(f'{key}: {value:.2f}')Step 3: Break Down Performance by Product and Region
Overall numbers are useful, but managers always want to drill down. Which product brings in the most revenue? Which region is underperforming? The groupby() method is how you answer these questions.
Write a function breakdown_by(df, column) that:
1. Groups the DataFrame by the given column
2. Calculates total revenue, total units sold, and transaction count per group
3. Sorts by total revenue descending
4. Returns the result DataFrame
The returned DataFrame should have columns: total_revenue, total_units, transactions.
Call it for both 'product' and 'region' and print the results.
import pandas as pd
def breakdown_by(df, column):
# Your code here
pass
data = {
'product': ['Laptop', 'Phone', 'Tablet', 'Laptop', 'Phone', 'Tablet'],
'region': ['North', 'South', 'North', 'East', 'South', 'East'],
'quantity': [2, 5, 3, 1, 4, 2],
'unit_price': [999.99, 699.99, 449.99, 999.99, 699.99, 449.99]
}
df = pd.DataFrame(data)
df['revenue'] = df['quantity'] * df['unit_price']
print('=== By Product ===')
print(breakdown_by(df, 'product'))
print('\n=== By Region ===')
print(breakdown_by(df, 'region'))Step 4: Find Top Performers
Sales managers love rankings. Who's the top salesperson? What's the single biggest sale? Let's write code that answers both.
Write a function find_top_performers(df) that prints:
1. The top salesperson by total revenue (print: Top salesperson: NAME ($REVENUE))
2. The top product by total units sold (print: Top product: NAME (UNITS units))
3. The largest single sale by revenue (print: Largest sale: $REVENUE by NAME)
Format all dollar amounts with 2 decimal places.
import pandas as pd
def find_top_performers(df):
# Your code here
pass
data = {
'salesperson': ['Alice', 'Bob', 'Alice', 'Charlie', 'Bob'],
'product': ['Laptop', 'Phone', 'Phone', 'Laptop', 'Tablet'],
'quantity': [2, 5, 3, 1, 4],
'unit_price': [999.99, 699.99, 699.99, 999.99, 449.99]
}
df = pd.DataFrame(data)
df['revenue'] = df['quantity'] * df['unit_price']
find_top_performers(df)Step 5: Calculate Month-over-Month Growth
Trends matter more than snapshots. A $50,000 month sounds great, but if last month was $80,000, there's a problem. Month-over-month growth shows whether the business is improving or declining.
Write a function monthly_growth(df) that:
1. Groups the DataFrame by the month column
2. Calculates total revenue per month
3. Calculates the percentage change from one month to the next
4. Prints each month's revenue and growth rate
Format: MONTH: $REVENUE (GROWTH%) where growth shows +/- sign.
For the first month (no previous month), print: MONTH: $REVENUE
The months should appear in order: January, February, March.
import pandas as pd
def monthly_growth(df):
# Your code here
pass
data = {
'date': ['2024-01-05', '2024-01-20', '2024-02-10', '2024-02-25',
'2024-03-05', '2024-03-15', '2024-03-25'],
'product': ['A', 'B', 'A', 'B', 'A', 'B', 'A'],
'quantity': [2, 3, 4, 2, 5, 3, 2],
'unit_price': [100, 200, 100, 200, 100, 200, 100]
}
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'])
df['revenue'] = df['quantity'] * df['unit_price']
df['month'] = df['date'].dt.strftime('%B')
monthly_growth(df)Step 6: Create a Summary Report Function
Time to combine everything into a single report function. A good report function runs all the analysis and returns organized results. This makes it easy to generate reports for different time periods or datasets.
Write a function create_report(df) that returns a dictionary with:
kpis: dict with total_revenue, transaction_count, avg_order_valuetop_product: name of the product with highest total revenuetop_salesperson: name of the salesperson with highest total revenuebest_region: name of the region with highest total revenueThen print the report in a readable format.
import pandas as pd
def create_report(df):
# Your code here
pass
data = {
'product': ['Laptop', 'Phone', 'Laptop', 'Tablet', 'Phone'],
'salesperson': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob'],
'region': ['North', 'South', 'East', 'North', 'South'],
'quantity': [2, 5, 1, 3, 4],
'unit_price': [999.99, 699.99, 999.99, 449.99, 699.99]
}
df = pd.DataFrame(data)
df['revenue'] = df['quantity'] * df['unit_price']
report = create_report(df)
print(f'Total Revenue: ${report["kpis"]["total_revenue"]:.2f}')
print(f'Transactions: {report["kpis"]["transaction_count"]}')
print(f'Avg Order: ${report["kpis"]["avg_order_value"]:.2f}')
print(f'Top Product: {report["top_product"]}')
print(f'Top Salesperson: {report["top_salesperson"]}')
print(f'Best Region: {report["best_region"]}')Step 7: Generate a Formatted Report
Data analysis is only useful if people can read it. The final step is turning raw numbers into a nicely formatted text report. Good formatting uses alignment, separators, and clear labels to make the data scannable.
Write a function format_report(df) that prints a complete formatted sales report. The report should include:
1. A header with the title "SALES PERFORMANCE REPORT"
2. KPI section showing total revenue, transaction count, and average order value
3. Top performers section showing the top product and top salesperson
4. Use = and - characters as separators
Match this exact format:
================================
SALES PERFORMANCE REPORT
================================
Total Revenue: $8849.86
Transactions: 5
Avg Order Value: $1769.97
--------------------------------
Top Product: Phone
Top Salesperson: Bob
================================import pandas as pd
def format_report(df):
# Your code here
pass
data = {
'product': ['Laptop', 'Phone', 'Laptop', 'Tablet', 'Phone'],
'salesperson': ['Alice', 'Bob', 'Charlie', 'Alice', 'Bob'],
'quantity': [2, 5, 1, 3, 4],
'unit_price': [999.99, 699.99, 999.99, 449.99, 699.99]
}
df = pd.DataFrame(data)
df['revenue'] = df['quantity'] * df['unit_price']
format_report(df)What You Built
| You built a complete sales analysis pipeline that transforms raw transaction data into actionable insights: | ||
|---|---|---|
| --- | --- | --- |
| Data prep | Convert types, add derived columns | pd.to_datetime(), arithmetic |
| KPIs | Calculate summary metrics | .sum(), .mean(), len() |
| Breakdowns | Group by category | .groupby().agg() |
| Rankings | Find top performers | .idxmax() |
| Growth | Track trends over time | .pct_change() |
| Reporting | Present results clearly | f-string formatting |
This is the exact workflow data analysts follow in real companies. The dataset gets bigger and the analysis gets more sophisticated, but the pattern stays the same: load, prepare, analyze, report.