Introduction
Football scouts do not just read stat sheets. They turn numbers into clear stories about role, strengths, and what a player can improve next.
In this project, you will build a Python program that turns football 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 football stats into analysis language
- Load player data from CSV and generate multiple reports
Why this matters
This is how real analysis teams work: one report template, many players, consistent output.
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:
.pymeans Python code..csvmeans table-style data.
- Pick an easy location for your project folder:
- Mac:
Desktopin Finder - Windows:
Desktopin File Explorer - Chromebook:
My filesin the Files app
- Mac:
- Create a folder called
football-scouting-report. - In Cursor, go to
File > Open Folderand openfootball-scouting-report. - 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 createplayers.csv
- click New Folder and create
- If you do not see file extensions on your computer, that is okay. Type the full names exactly, including
.pyand.csv.
Writing the code
Type this into scouting_report.py:
player_name = "Aiden Brooks"
team_name = "Greenville Knights"
primary_stat_name = "Passing yards per game"
primary_stat_value = 278.4
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 football 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: Aiden Brooks (Greenville Knights)
Top stat: Passing yards per game - 278.4
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:
def build_report(player_name, team_name, position, pass_yds_pg, pass_td_pg, comp_pct):
report = (
f"=== Scouting Report ===\n"
f"Player: {player_name}\n"
f"Team: {team_name}\n"
f"Position: {position}\n"
f"Pass Yds/G: {pass_yds_pg}\n"
f"Pass TD/G: {pass_td_pg}\n"
f"Comp %: {comp_pct}\n"
)
return report
print(build_report("Aiden Brooks", "Greenville Knights", "QB", 278.4, 2.2, 67.8))
Expected output:
=== Scouting Report ===
Player: Aiden Brooks
Team: Greenville Knights
Position: QB
Pass Yds/G: 278.4
Pass TD/G: 2.2
Comp %: 67.8
Milestone 2: Add strengths and growth areas
Now add decision logic (if/elif/else) to convert numbers into coach-friendly language.
Add this below Milestone 1 code:
def passing_volume_label(pass_yds_pg):
if pass_yds_pg >= 280:
return "Strength: High passing volume."
if pass_yds_pg >= 220:
return "Strength: Reliable production through the air."
return "Growth Area: Increase consistent yardage output."
def accuracy_label(comp_pct):
if comp_pct >= 67:
return "Strength: Efficient ball placement."
if comp_pct >= 62:
return "Strength: Solid short-area accuracy."
return "Growth Area: Improve timing and accuracy under pressure."
print(passing_volume_label(278.4))
print(accuracy_label(67.8))
Expected output:
Strength: Reliable production through the air.
Strength: Efficient ball placement.
Try different numbers and watch the labels change.
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:
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(
"Aiden Brooks",
"rhythm passer with vertical upside",
"9 passing touchdowns across the last 4 games",
"Operates quickly and identifies leverage matchups.",
"Can reduce risky throws late across the middle."
)
print(summary)
Expected output:
Aiden Brooks projects as a rhythm passer with vertical upside. Operates quickly and identifies leverage matchups. Can reduce risky throws late across the middle. Recent trend: 9 passing touchdowns across the last 4 games.
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 position group.
- Open
data/players.csv. - Paste the data below.
- Save the file.
- Make sure the file name is exactly
players.csv(notplayers.csv.txt).
Paste this into data/players.csv:
name,team,position,pass_yds_pg,pass_td_pg,comp_pct,rush_yds_pg,trend_note
Aiden Brooks,Greenville Knights,QB,278.4,2.2,67.8,24.1,9 passing touchdowns across the last 4 games
Liam Carter,Greenville Knights,QB,241.7,1.8,64.9,31.6,completion rate above 65 percent in 5 straight games
Mason Reed,Greenville Knights,QB,215.3,1.5,61.8,42.2,rushing usage increased in red zone packages
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"],
"pass_yds_pg": float(row["pass_yds_pg"]),
"pass_td_pg": float(row["pass_td_pg"]),
"comp_pct": float(row["comp_pct"]),
"rush_yds_pg": float(row["rush_yds_pg"]),
"trend_note": row["trend_note"]
})
print(players)
Click Run Python File again.
Expected output (shortened example):
[{'name': 'Aiden Brooks', 'team': 'Greenville Knights', ...}, {'name': 'Liam Carter', ...}, ...]
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:
def print_scouting_card(player):
strength = passing_volume_label(player["pass_yds_pg"])
growth = accuracy_label(player["comp_pct"])
summary = build_summary(
player["name"],
"field general who can distribute across all levels",
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["pass_yds_pg"],
player["pass_td_pg"],
player["comp_pct"]
))
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 football scouting report generator from scratch.
Common Fixes
FileNotFoundError: confirm the path is exactlydata/players.csv.ValueError: check thatpass_yds_pg,pass_td_pg, andcomp_pctare 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:
- Goal: what you want to build
- Context: file name + what code already exists
- Constraints: keep beginner-friendly, minimal changes
- 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 passing yards, touchdown rate, and completion percentage.
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 Pocket Presence Section
Try this prompt:
You are my Python tutor and coding assistant.
Goal:
Add a "Pocket Presence" section with sack rate and pressure 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:
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