Introduction

NBA scouts do not just list stats. They turn numbers into a clear story about a player's role, strengths, and next steps.

In this project, you will build a Python program that turns basketball stats into a clean scouting report.

What we're building

By the end of this project, you will:

  • Format report text with strings and f-strings
  • Use functions to generate reusable scouting templates
  • Turn basketball stats into analysis language
  • Load player data from CSV and generate multiple reports

Why this matters

This is exactly how real analytics workflows scale: one code template plus many rows of data.

Part 1: Quick Start

Set up your project in Cursor

For this project, you will create your files from scratch (no starter pack download).

Before you start: quick vocabulary

  • A folder is a container that holds files.
  • A file is one item inside a folder.
  • A file extension is the ending in the file name:
    • .py means Python code.
    • .csv means table-style data.
  1. Pick an easy location for your project folder:
    • Mac: Desktop in Finder
    • Windows: Desktop in File Explorer
    • Chromebook: My files in the Files app
  2. Create a folder called basketball-scouting-report.
  3. In Cursor, go to File > Open Folder and open basketball-scouting-report.
  4. In Cursor's left file explorer:
    • click New Folder and create data
    • click New File and create scouting_report.py
    • open data, click New File, and create players.csv
  5. If you do not see file extensions on your computer, that is okay. Type the full names exactly, including .py and .csv.

Writing the code

Type this into scouting_report.py:

player_name = "Jalen Carter"
team_name = "Greenville Comets"
primary_stat_name = "Points per game"
primary_stat_value = 24.6

print(f"Scouting Report: {player_name} ({team_name})")
print(f"Top stat: {primary_stat_name} - {primary_stat_value}")

This is your first "quick win." You are combining text and numbers into a readable report line.

Running the code

Save the file (Cmd + S on Mac, Ctrl + S on Windows/Chromebook).

Run the file with Cursor's built-in Run Python File play button in the top-right.

If the play button is missing, install/enable the Python extension in Cursor and reopen scouting_report.py.

Expected output:

Scouting Report: Jalen Carter (Greenville Comets)
Top stat: Points per game - 24.6

If your output matches, your project setup is working.

Part 2: Project Milestones

Milestone 1: Build a reusable report function

A function is a reusable recipe. Instead of rewriting print lines for every player, we write the recipe once and call it many times.

Add this below your existing code:

def build_report(player_name, team_name, position, ppg, apg, rpg):
    report = (
        f"=== Scouting Report ===\n"
        f"Player: {player_name}\n"
        f"Team: {team_name}\n"
        f"Position: {position}\n"
        f"PPG: {ppg}\n"
        f"APG: {apg}\n"
        f"RPG: {rpg}\n"
    )
    return report

print(build_report("Jalen Carter", "Greenville Comets", "SG", 24.6, 6.2, 5.1))

Expected output:

=== Scouting Report ===
Player: Jalen Carter
Team: Greenville Comets
Position: SG
PPG: 24.6
APG: 6.2
RPG: 5.1

Milestone 2: Add strengths and growth areas

Now we add decision logic with if, elif, and else. This lets your program turn raw numbers into coaching language.

Add this below Milestone 1 code:

def scoring_label(ppg):
    if ppg >= 25:
        return "Strength: Elite scoring volume."
    if ppg >= 18:
        return "Strength: Reliable scoring pressure."
    return "Growth Area: Increase scoring consistency."

def playmaking_label(apg):
    if apg >= 7:
        return "Strength: High-level playmaker."
    if apg >= 4:
        return "Strength: Solid secondary creator."
    return "Growth Area: Improve passing reads."

print(scoring_label(24.6))
print(playmaking_label(6.2))

Expected output:

Strength: Reliable scoring pressure.
Strength: Solid secondary creator.

Try changing the numbers in print(scoring_label(...)) to see how labels change.

Milestone 3: Create a full scouting summary paragraph

Now build one polished paragraph that sounds like an analyst note.

Add this below your current code:

def build_summary(player_name, position, trend_note, strength_line, growth_line):
    return (
        f"{player_name} projects as a {position} who can impact both scoring and shot creation. "
        f"{strength_line} {growth_line} "
        f"Recent trend: {trend_note}."
    )

summary = build_summary(
    "Jalen Carter",
    "two-way guard",
    "scored 20+ in four of the last five games",
    "Creates rim pressure and draws help defenders.",
    "Can reduce live-ball turnovers against traps."
)

print(summary)

Expected output:

Jalen Carter projects as a two-way guard who can impact both scoring and shot creation. Creates rim pressure and draws help defenders. Can reduce live-ball turnovers against traps. Recent trend: scored 20+ in four of the last five games.

Milestone 4: Load player reports from CSV data

Now you will separate data from code by using data/players.csv. This is how analysts scale from one player to many players.

  1. Open data/players.csv.
  2. Paste the data below.
  3. Save the file.
  4. Make sure the file name is exactly players.csv (not players.csv.txt).

Paste this into data/players.csv:

name,team,position,ppg,apg,rpg,three_pt_pct,trend_note
Jalen Carter,Greenville Comets,SG,24.6,6.2,5.1,38.5,20+ points in 4 of last 5 games
Maya Brooks,Greenville Comets,PF,18.4,3.1,10.8,33.2,3 straight double-doubles
Noah Ellis,Greenville Comets,PG,15.9,8.4,4.3,36.1,assist rate up in last 6 games

Now load that file in Python. Add this below your existing code:

import csv

players = []

with open("data/players.csv", "r") as file:
    reader = csv.DictReader(file)
    for row in reader:
        players.append({
            "name": row["name"],
            "team": row["team"],
            "position": row["position"],
            "ppg": float(row["ppg"]),
            "apg": float(row["apg"]),
            "rpg": float(row["rpg"]),
            "three_pt_pct": float(row["three_pt_pct"]),
            "trend_note": row["trend_note"]
        })

print(players)

Click Run Python File again.

Expected output (shortened example):

[{'name': 'Jalen Carter', 'team': 'Greenville Comets', ...}, {'name': 'Maya Brooks', ...}, ...]

If you see a list of dictionaries, your CSV load worked.

Milestone 5: Print final scouting cards for each player

Now connect everything:

  • your report template
  • your label rules
  • your summary paragraph
  • your CSV player list

Add this below Milestone 4:

def print_scouting_card(player):
    strength = scoring_label(player["ppg"])
    growth = playmaking_label(player["apg"])
    summary = build_summary(
        player["name"],
        player["position"],
        player["trend_note"],
        strength,
        growth
    )

    print("=" * 46)
    print(f"SCOUTING CARD: {player['name']}")
    print("=" * 46)
    print(build_report(
        player["name"],
        player["team"],
        player["position"],
        player["ppg"],
        player["apg"],
        player["rpg"]
    ))
    print(summary)
    print("=" * 46)

for player in players:
    print_scouting_card(player)

Expected result:

  • You should see a scouting card for each player in your CSV.
  • Each card should include profile lines plus a summary paragraph.

If you made it this far, you built an automated basketball scouting report generator from scratch.

Common Fixes

  • FileNotFoundError: confirm the path is exactly data/players.csv.
  • ValueError: check the CSV has only numbers in ppg, apg, and rpg.
  • No play button: install/enable Python extension in Cursor and reopen scouting_report.py.

Bonus Exercises: Push It Further with Your Agent

Use this short prompt structure for better AI help:

  1. Goal: what you want to build
  2. Context: file name + what code already exists
  3. Constraints: keep beginner-friendly, minimal changes
  4. Output format: ask for exact code + where to paste + expected output

Bonus 1: Add Letter Grades

Try this prompt:

You are my Python tutor and coding assistant.

Goal:
Add letter grades (A/B/C) for PPG, APG, and RPG in my scouting cards.

Context:
I am editing scouting_report.py.
I already have build_report(...), build_summary(...), and print_scouting_card(...).

Constraints:
- Keep my existing output working.
- Make the smallest set of changes.
- Keep the code beginner-friendly.

Output format:
1) Short plan (3 bullets)
2) Exact code blocks to add/change
3) Exactly where to paste each block
4) Expected output example for one player

Bonus 2: Add a Shot Profile Section

Try this prompt:

You are my Python tutor and coding assistant.

Goal:
Add a "Shot Profile" section with 3PT% and FT% notes to each scouting card.

Context:
I am using data/players.csv in scouting_report.py.
Please include any CSV header changes I need.

Constraints:
- Keep the same project structure.
- Do not rewrite my whole file.
- Explain changes in simple language.

Output format:
1) Updated CSV header + sample rows
2) Code changes only
3) Where to paste changes
4) One quick test run to verify it works

Bonus 3: Export Reports to a File

Try this prompt:

You are my Python tutor and coding assistant.

Goal:
Write all scouting cards to scouting_reports.txt.

Context:
I already loop through players and print each card in scouting_report.py.

Constraints:
- Keep terminal output AND also save to file.
- Use simple Python only.
- Keep code readable for beginners.

Output format:
1) Minimal code changes
2) Where each change goes
3) Expected contents of scouting_reports.txt (first 10 lines)
4) One troubleshooting tip if file is empty