> Source URL: /ai-and-sports/projects/5-personal-scouting-report-generator/personal-scouting-report-generator.baseball.project
---
title: Your Personal Scouting Report Generator (Baseball)
student_outcomes:
  - use strings and f-strings to format polished scouting writeups
  - build reusable functions that generate reports for different players
  - combine multiple stats into strengths, weaknesses, and summary language
  - load player data from a CSV file and generate reports automatically
---

# Project: Your Personal Scouting Report Generator (Baseball)

---

## Introduction

Baseball scouts do not just list batting lines. They turn numbers into a clear story about approach, consistency, and upside.

In this project, you will build a Python program that turns baseball 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 baseball stats into analysis language**
- **Load player data from CSV** and generate multiple reports

### Why this matters

This mirrors real front-office workflows: one reporting format that can be reused across many players.

---

## 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 `baseball-scouting-report`.
3. In Cursor, go to `File > Open Folder` and open `baseball-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`:

```python
player_name = "Diego Alvarez"
team_name = "Greenville Hawks"
primary_stat_name = "Batting average"
primary_stat_value = 0.311

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 already generating a readable baseball report line.

### Running the code

Save the file (<Kbd>Cmd + S</Kbd> on Mac, <Kbd>Ctrl + S</Kbd> 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: Diego Alvarez (Greenville Hawks)
Top stat: Batting average - 0.311
```

If your output matches, your setup is working.

---

## Part 2: Project Milestones

### Milestone 1: Build a reusable report function

A function is a reusable recipe. Write it once, then use it for every player.

Add this below your existing code:

```python
def build_report(player_name, team_name, position, batting_avg, obp, slg):
    report = (
        f"=== Scouting Report ===\n"
        f"Player: {player_name}\n"
        f"Team: {team_name}\n"
        f"Position: {position}\n"
        f"AVG: {batting_avg}\n"
        f"OBP: {obp}\n"
        f"SLG: {slg}\n"
    )
    return report

print(build_report("Diego Alvarez", "Greenville Hawks", "SS", 0.311, 0.382, 0.512))
```

Expected output:

```text
=== Scouting Report ===
Player: Diego Alvarez
Team: Greenville Hawks
Position: SS
AVG: 0.311
OBP: 0.382
SLG: 0.512
```

---

### Milestone 2: Add strengths and growth areas

Now add decision logic (`if/elif/else`) so your code can describe what the stats mean.

Add this below Milestone 1 code:

```python
def contact_label(batting_avg):
    if batting_avg >= 0.300:
        return "Strength: Excellent contact consistency."
    if batting_avg >= 0.260:
        return "Strength: Solid hit tool."
    return "Growth Area: Improve quality of contact."

def discipline_label(obp):
    if obp >= 0.370:
        return "Strength: Advanced plate discipline."
    if obp >= 0.330:
        return "Strength: Serviceable on-base profile."
    return "Growth Area: Improve swing decisions."

print(contact_label(0.311))
print(discipline_label(0.382))
```

Expected output:

```text
Strength: Excellent contact consistency.
Strength: Advanced plate discipline.
```

Try different values to see how labels update.

---

### Milestone 3: Create a full scouting summary paragraph

Now build one polished paragraph that sounds like a scouting note.

Add this below your current code:

```python
def build_summary(player_name, role, trend_note, strength_line, growth_line):
    return (
        f"{player_name} projects as a {role}. "
        f"{strength_line} {growth_line} "
        f"Recent trend: {trend_note}."
    )

summary = build_summary(
    "Diego Alvarez",
    "top-of-order contact bat with gap power",
    "multi-hit games in 5 of the last 8 contests",
    "Stays through the middle of the field with consistent timing.",
    "Can improve damage on inside fastballs."
)

print(summary)
```

Expected output:

```text
Diego Alvarez projects as a top-of-order contact bat with gap power. Stays through the middle of the field with consistent timing. Can improve damage on inside fastballs. Recent trend: multi-hit games in 5 of the last 8 contests.
```

---

### Milestone 4: Load player reports from CSV data

Now separate data from code with `data/players.csv`.
This is how you scale from one player to a full lineup.

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`:

```text
name,team,position,batting_avg,obp,slg,ops,trend_note
Diego Alvarez,Greenville Hawks,SS,0.311,0.382,0.512,0.894,multi-hit games in 5 of last 8 contests
Noah Bennett,Greenville Hawks,CF,0.287,0.356,0.471,0.827,extra-base hit in 4 of last 7 contests
Eli Ramos,Greenville Hawks,3B,0.263,0.338,0.446,0.784,walk rate improved over last 10 games
```

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

```python
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"],
            "batting_avg": float(row["batting_avg"]),
            "obp": float(row["obp"]),
            "slg": float(row["slg"]),
            "ops": float(row["ops"]),
            "trend_note": row["trend_note"]
        })

print(players)
```

Click **Run Python File** again.

Expected output (shortened example):

```text
[{'name': 'Diego Alvarez', 'team': 'Greenville Hawks', ...}, {'name': 'Noah Bennett', ...}, ...]
```

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

---

### Milestone 5: Print final scouting cards for each player

Now combine:

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

Add this below Milestone 4:

```python
def print_scouting_card(player):
    strength = contact_label(player["batting_avg"])
    growth = discipline_label(player["obp"])
    summary = build_summary(
        player["name"],
        "lineup bat who can control at-bats",
        player["trend_note"],
        strength,
        growth
    )

    print("=" * 48)
    print(f"SCOUTING CARD: {player['name']}")
    print("=" * 48)
    print(build_report(
        player["name"],
        player["team"],
        player["position"],
        player["batting_avg"],
        player["obp"],
        player["slg"]
    ))
    print(summary)
    print("=" * 48)

for player in players:
    print_scouting_card(player)
```

Expected result:

- You should see one scouting card per player.
- Each card should include report lines and a summary paragraph.

If you made it this far, you built a full baseball scouting report generator from scratch.

---

## Common Fixes

- `FileNotFoundError`: confirm the path is exactly `data/players.csv`.
- `ValueError`: check that `batting_avg`, `obp`, and `slg` are numeric in CSV.
- 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:

```text
You are my Python tutor and coding assistant.

Goal:
Add letter grades (A/B/C) for AVG, OBP, and SLG.

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 minimal code changes.
- Keep code beginner-friendly.

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

### Bonus 2: Add a Batted-Ball Profile Section

Try this prompt:

```text
You are my Python tutor and coding assistant.

Goal:
Add a "Batted-Ball Profile" section with line-drive and hard-hit notes.

Context:
I am using data/players.csv in scouting_report.py.
Include any CSV header updates.

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

Output format:
1) Updated CSV header + sample row
2) Code changes only
3) Where to paste changes
4) One test run to verify output
```

### Bonus 3: Export Reports to a File

Try this prompt:

```text
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 save to file.
- Use simple Python only.

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


---

## Backlinks

The following sources link to this document:

- [>button: ⚾ Baseball](/ai-and-sports/projects/5-personal-scouting-report-generator/personal-scouting-report-generator.project.llm.md)
