Exercises: Traditional Football Statistics
Practice calculating, analyzing, and interpreting traditional football statistics.
Level 1: Foundation (Exercises 1.1-1.8)
Exercise 1.1: Basic Counting Statistics
Given the following game data for a running back, calculate the basic statistics:
rushing_plays = [4, 7, -2, 12, 3, 8, 1, 15, 5, 2, 6, -1, 9, 4, 3, 22, 5, 1, 8, 6]
Calculate: 1. Total rushing yards 2. Number of carries 3. Yards per carry 4. Longest run 5. Number of runs of 10+ yards
Exercise 1.2: Passing Statistics
A quarterback has the following game statistics: - Completions: 24 - Attempts: 38 - Passing yards: 312 - Touchdowns: 3 - Interceptions: 1
Calculate: 1. Completion percentage 2. Yards per attempt 3. Touchdown percentage 4. Interception percentage
Exercise 1.3: Team Totals
Calculate team offensive totals from these individual stats:
passing = {'yards': 285, 'tds': 2, 'attempts': 35}
rushing = {'yards': 156, 'tds': 1, 'attempts': 28}
Calculate: 1. Total offensive yards 2. Total offensive touchdowns 3. Total offensive plays 4. Yards per play
Exercise 1.4: First Down Calculation
Given play-by-play data, determine which plays resulted in first downs:
plays = [
{'down': 1, 'distance': 10, 'yards': 4},
{'down': 2, 'distance': 6, 'yards': 8}, # First down?
{'down': 1, 'distance': 10, 'yards': 12}, # First down?
{'down': 3, 'distance': 5, 'yards': 3},
{'down': 4, 'distance': 2, 'yards': 3}, # First down?
]
Tasks: 1. Identify which plays resulted in first downs 2. Calculate first down percentage
Exercise 1.5: Turnover Margin
Team A and Team B have the following turnover statistics:
| Team | Interceptions Thrown | Fumbles Lost | Interceptions Caught | Fumbles Recovered |
|---|---|---|---|---|
| A | 2 | 1 | 3 | 0 |
| B | 1 | 2 | 1 | 2 |
Calculate: 1. Turnovers committed by each team 2. Turnovers forced by each team 3. Turnover margin for each team 4. Which team had the advantage?
Exercise 1.6: Third Down Efficiency
A team faced the following third down situations:
third_downs = [
{'distance': 3, 'result': 'first_down'},
{'distance': 8, 'result': 'incomplete'},
{'distance': 1, 'result': 'first_down'},
{'distance': 12, 'result': 'sack'},
{'distance': 5, 'result': 'first_down'},
{'distance': 7, 'result': 'incomplete'},
{'distance': 2, 'result': 'first_down'},
{'distance': 15, 'result': 'first_down'},
]
Calculate: 1. Third down attempts 2. Third down conversions 3. Third down conversion percentage 4. Conversion rate for short (1-3), medium (4-7), and long (8+) distances
Exercise 1.7: Red Zone Statistics
A team had 5 red zone trips with these results: - Trip 1: Touchdown - Trip 2: Field Goal - Trip 3: Touchdown - Trip 4: Turnover (interception) - Trip 5: Field Goal
Calculate: 1. Red zone scoring percentage 2. Red zone touchdown percentage 3. Points scored in red zone 4. Points per red zone trip
Exercise 1.8: Per-Game Averages
Convert these season totals to per-game averages (13-game season):
season_stats = {
'passing_yards': 3456,
'rushing_yards': 2145,
'points_scored': 455,
'first_downs': 286,
'turnovers': 18
}
Level 2: Application (Exercises 2.1-2.6)
Exercise 2.1: Quarterback Comparison
Compare these two quarterbacks and determine which had the better season:
QB A: - 312 completions, 478 attempts, 3,845 yards, 32 TDs, 8 INTs
QB B: - 245 completions, 385 attempts, 3,212 yards, 28 TDs, 5 INTs
Tasks: 1. Calculate completion %, YPA, TD%, INT% for each 2. Calculate passer rating for each 3. Which QB was more efficient? Which had more production?
Exercise 2.2: Rushing Attack Analysis
Analyze this team's rushing performance by runner:
rushers = {
'RB1': {'carries': 185, 'yards': 892, 'tds': 8, 'long': 45},
'RB2': {'carries': 98, 'yards': 456, 'tds': 5, 'long': 32},
'QB': {'carries': 65, 'yards': 312, 'tds': 4, 'long': 28},
'WR1': {'carries': 12, 'yards': 78, 'tds': 1, 'long': 22}
}
Calculate for each rusher and team total: 1. Yards per carry 2. Percentage of team carries 3. Percentage of team rushing yards 4. Touchdowns per carry
Exercise 2.3: Receiving Corps Analysis
Analyze this team's receiving production:
receivers = {
'WR1': {'targets': 125, 'receptions': 82, 'yards': 1156, 'tds': 9},
'WR2': {'targets': 95, 'receptions': 58, 'yards': 756, 'tds': 5},
'TE': {'targets': 68, 'receptions': 52, 'yards': 548, 'tds': 4},
'RB1': {'targets': 45, 'receptions': 38, 'yards': 285, 'tds': 2},
'WR3': {'targets': 42, 'receptions': 25, 'yards': 312, 'tds': 3}
}
Calculate for each receiver: 1. Catch rate 2. Yards per reception 3. Yards per target 4. Target share percentage
Exercise 2.4: Defensive Statistics
Calculate team defensive statistics from opponent offensive data:
games_allowed = [
{'opp': 'Team A', 'points': 24, 'yards': 385, 'pass_yds': 245, 'rush_yds': 140},
{'opp': 'Team B', 'points': 17, 'yards': 298, 'pass_yds': 198, 'rush_yds': 100},
{'opp': 'Team C', 'points': 31, 'yards': 425, 'pass_yds': 312, 'rush_yds': 113},
{'opp': 'Team D', 'points': 14, 'yards': 256, 'pass_yds': 156, 'rush_yds': 100},
{'opp': 'Team E', 'points': 28, 'yards': 378, 'pass_yds': 228, 'rush_yds': 150}
]
Calculate: 1. Points allowed per game 2. Total yards allowed per game 3. Passing yards allowed per game 4. Rushing yards allowed per game
Exercise 2.5: Special Teams Evaluation
Evaluate this kicker's season:
field_goals = [
{'distance': 25, 'made': True},
{'distance': 42, 'made': True},
{'distance': 38, 'made': False},
{'distance': 33, 'made': True},
{'distance': 48, 'made': True},
{'distance': 51, 'made': False},
{'distance': 29, 'made': True},
{'distance': 44, 'made': True},
{'distance': 37, 'made': True},
{'distance': 52, 'made': False}
]
extra_points = {'attempts': 45, 'made': 44}
Calculate: 1. Overall field goal percentage 2. FG% by distance range (under 40, 40-49, 50+) 3. Extra point percentage 4. Total points from kicking
Exercise 2.6: Box Score Analysis
Given this box score data, determine the winner and key statistical advantages:
home_team = {
'score': 31,
'first_downs': 24,
'total_yards': 425,
'passing_yards': 285,
'rushing_yards': 140,
'turnovers': 2,
'time_of_possession': '32:15',
'third_down': '7/14',
'penalties': 8,
'penalty_yards': 65
}
away_team = {
'score': 28,
'first_downs': 21,
'total_yards': 398,
'passing_yards': 312,
'rushing_yards': 86,
'turnovers': 1,
'time_of_possession': '27:45',
'third_down': '5/12',
'penalties': 5,
'penalty_yards': 42
}
Analysis: 1. Which team won and by how much? 2. Calculate yards per play for each team 3. Which team was more efficient on third down? 4. Did the team with fewer turnovers win?
Level 3: Intermediate (Exercises 3.1-3.5)
Exercise 3.1: Passer Rating Calculator
Implement the NFL passer rating formula:
def calculate_passer_rating(completions: int, attempts: int,
yards: int, touchdowns: int,
interceptions: int) -> float:
"""
Calculate NFL passer rating.
Formula:
a = ((Comp/Att * 100) - 30) / 20
b = ((Yards/Att) - 3) / 4
c = (TD/Att) * 20
d = 2.375 - ((Int/Att) * 25)
Each component capped at 0 and 2.375
Rating = ((a + b + c + d) / 6) * 100
"""
pass # Implement this
Test with: - Perfect rating scenario: 10/10, 400 yards, 4 TDs, 0 INTs - Average QB: 22/35, 250 yards, 2 TDs, 1 INT - Poor performance: 15/32, 145 yards, 0 TDs, 3 INTs
Exercise 3.2: Season Statistics Aggregator
Build a function to aggregate game-by-game stats into season totals:
games = [
{'week': 1, 'yards': 285, 'tds': 2, 'attempts': 35, 'completions': 22},
{'week': 2, 'yards': 312, 'tds': 3, 'attempts': 42, 'completions': 28},
{'week': 3, 'yards': 198, 'tds': 1, 'attempts': 28, 'completions': 18},
# ... more games
]
def aggregate_season_stats(games: list) -> dict:
"""
Aggregate game stats into season totals and calculate rates.
Returns:
- Total yards, TDs, attempts, completions
- Season completion %, YPA
- Per-game averages
"""
pass # Implement this
Exercise 3.3: Opponent-Adjusted Statistics
Adjust a team's statistics based on opponent strength:
games = [
{'opponent': 'Team A', 'opp_def_rank': 5, 'yards_gained': 350},
{'opponent': 'Team B', 'opp_def_rank': 45, 'yards_gained': 425},
{'opponent': 'Team C', 'opp_def_rank': 120, 'yards_gained': 520},
{'opponent': 'Team D', 'opp_def_rank': 25, 'yards_gained': 380},
]
Tasks: 1. Calculate raw average yards 2. Create a simple adjustment based on opponent rank 3. Which games were most impressive relative to opponent?
Exercise 3.4: Statistical Leaderboard
Create a leaderboard function:
players = [
{'name': 'Player A', 'team': 'Alabama', 'rushing_yards': 1256, 'games': 13},
{'name': 'Player B', 'team': 'Georgia', 'rushing_yards': 1189, 'games': 14},
{'name': 'Player C', 'team': 'Michigan', 'rushing_yards': 1345, 'games': 15},
{'name': 'Player D', 'team': 'Texas', 'rushing_yards': 1123, 'games': 13},
{'name': 'Player E', 'team': 'Ohio State', 'rushing_yards': 1087, 'games': 12},
]
def create_leaderboard(players: list, stat: str,
per_game: bool = False,
top_n: int = 5) -> pd.DataFrame:
"""
Create a leaderboard for a given statistic.
Parameters:
- stat: Which statistic to rank by
- per_game: Whether to use per-game average
- top_n: Number of players to include
"""
pass # Implement this
Exercise 3.5: Complete Team Profile
Build a comprehensive team statistics profile:
def create_team_profile(plays: pd.DataFrame, team: str) -> dict:
"""
Generate complete team statistical profile.
Returns dictionary with:
- Offensive statistics (passing, rushing, total)
- Defensive statistics
- Special teams
- Situational stats (3rd down, red zone)
- Turnover margin
"""
pass # Implement this
Level 4: Advanced (Exercises 4.1-4.4)
Exercise 4.1: Historical Comparison Tool
Build a tool to compare players across eras:
class HistoricalComparison:
"""
Compare players across different eras using era-adjusted statistics.
"""
def __init__(self, league_averages: dict):
"""
league_averages: {year: {stat: average}}
"""
self.league_averages = league_averages
def era_adjust(self, value: float, stat: str, year: int) -> float:
"""Adjust a statistic relative to era average."""
pass
def compare_players(self, player1: dict, player2: dict) -> pd.DataFrame:
"""
Compare two players from potentially different eras.
player dict: {name, year, stats: {stat: value}}
"""
pass
Exercise 4.2: Play-by-Play Statistics Engine
Build a complete statistics engine from play-by-play data:
class PlayByPlayStats:
"""
Calculate all traditional statistics from play-by-play data.
"""
def __init__(self, plays: pd.DataFrame):
self.plays = plays
def passing_stats(self, team: str = None, player: str = None) -> pd.DataFrame:
pass
def rushing_stats(self, team: str = None, player: str = None) -> pd.DataFrame:
pass
def receiving_stats(self, team: str = None, player: str = None) -> pd.DataFrame:
pass
def team_summary(self, team: str) -> dict:
pass
def game_summary(self, game_id: int) -> dict:
pass
def season_leaders(self, stat: str, position: str = None) -> pd.DataFrame:
pass
Exercise 4.3: Box Score Generator
Create a function that generates a formatted box score from play-by-play data:
def generate_box_score(plays: pd.DataFrame, game_id: int) -> str:
"""
Generate a formatted box score string from play-by-play data.
Should include:
- Score by quarter
- Team statistics comparison
- Individual leaders (passing, rushing, receiving)
- Key plays summary
"""
pass # Implement this
Exercise 4.4: Statistical Report Generator
Create a complete statistical report for a team's season:
class SeasonReport:
"""
Generate comprehensive season statistical report.
"""
def __init__(self, team: str, season: int, plays: pd.DataFrame):
self.team = team
self.season = season
self.plays = plays
def offensive_summary(self) -> dict:
"""Season offensive statistics."""
pass
def defensive_summary(self) -> dict:
"""Season defensive statistics."""
pass
def game_by_game(self) -> pd.DataFrame:
"""Game-by-game breakdown."""
pass
def player_statistics(self) -> dict:
"""Individual player statistics."""
pass
def generate_report(self) -> str:
"""Generate formatted text report."""
pass
Level 5: Mastery (Exercises 5.1-5.2)
Exercise 5.1: Complete Statistics Package
Build a production-ready statistics package:
class FootballStatistics:
"""
Complete football statistics package.
Features:
- Calculate all traditional statistics
- Support team and player levels
- Game, season, and career aggregations
- Leaderboards and rankings
- Formatted output (box scores, reports)
- Data validation
"""
def __init__(self, data_source):
pass
# Implement all methods needed for a complete package
Exercise 5.2: Statistics API
Create a REST API-like interface for statistics:
class StatsAPI:
"""
API-like interface for accessing football statistics.
Endpoints:
- get_player_stats(player_id, season, stat_type)
- get_team_stats(team, season, stat_type)
- get_game_stats(game_id)
- get_leaderboard(stat, season, limit)
- compare_players(player_ids, stats)
- compare_teams(team_ids, stats)
"""
def __init__(self, database):
pass
# Implement endpoint methods
Submission Guidelines
For each exercise:
- Code: Well-documented, following PEP 8
- Output: Show results of running your code
- Interpretation: Explain what the statistics mean
- Validation: Verify calculations are correct
Example format:
# Exercise X.Y: Title
def my_solution(data):
"""Calculate the required statistics."""
# Implementation
pass
# Test
result = my_solution(test_data)
print(f"Result: {result}")
# Interpretation
# The completion percentage of 65.2% is above the FBS average of ~62%,
# indicating above-average accuracy for this quarterback.