mirror of
https://github.com/nprasad2077/nbaStats.git
synced 2026-11-05 17:45:48 +00:00
16 files changed
+488
-11
No files matched your search
@@ -0,0 +1,21 @@
|
||||
# Generated by Django 4.2 on 2023-05-08 23:59
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('nba_data', '0011_alter_playerplayoffadvanceddata_bpm_and_more'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PlayerSalaryData',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('player_name', models.CharField(max_length=255, null=True)),
|
||||
('salary', models.IntegerField(null=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
# Generated by Django 4.2 on 2023-05-09 00:16
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('nba_data', '0012_playersalarydata'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name='playersalarydata',
|
||||
name='season',
|
||||
field=models.IntegerField(null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='playersalarydata',
|
||||
name='team',
|
||||
field=models.CharField(default='', max_length=30),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,34 @@
|
||||
# Generated by Django 4.2 on 2023-05-10 02:06
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('nba_data', '0013_playersalarydata_season_playersalarydata_team'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='PlayerShotChartData',
|
||||
fields=[
|
||||
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('player_name', models.CharField(default='', max_length=255)),
|
||||
('top', models.IntegerField(null=True)),
|
||||
('left', models.IntegerField(null=True)),
|
||||
('date', models.CharField(default='', max_length=255)),
|
||||
('qtr', models.CharField(default='', max_length=6)),
|
||||
('time_remaining', models.IntegerField(null=True)),
|
||||
('result', models.BooleanField(null=True)),
|
||||
('shot_type', models.CharField(default='', max_length=6)),
|
||||
('distance_ft', models.IntegerField(null=True)),
|
||||
('lead', models.BooleanField(null=True)),
|
||||
('lebron_team_score', models.IntegerField(null=True)),
|
||||
('opponent_team_score', models.IntegerField(null=True)),
|
||||
('opponent', models.CharField(default='', max_length=30)),
|
||||
('team', models.CharField(default='', max_length=30)),
|
||||
('season', models.IntegerField(null=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2 on 2023-05-10 02:34
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('nba_data', '0014_playershotchartdata'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='playershotchartdata',
|
||||
name='time_remaining',
|
||||
field=models.CharField(default='', max_length=12),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2 on 2023-05-10 05:32
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('nba_data', '0015_alter_playershotchartdata_time_remaining'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='playershotchartdata',
|
||||
name='qtr',
|
||||
field=models.CharField(default='', max_length=255),
|
||||
),
|
||||
]
|
||||
@@ -0,0 +1,18 @@
|
||||
# Generated by Django 4.2 on 2023-05-10 05:33
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('nba_data', '0016_alter_playershotchartdata_qtr'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='playershotchartdata',
|
||||
name='result',
|
||||
field=models.BooleanField(default='', null=True),
|
||||
),
|
||||
]
|
||||
@@ -199,6 +199,40 @@ class PlayerPlayoffAdvancedData(models.Model):
|
||||
def __str__(self):
|
||||
return self.player_name
|
||||
|
||||
|
||||
class PlayerSalaryData(models.Model):
|
||||
player_name = models.CharField(max_length=255, null=True)
|
||||
salary = models.IntegerField(null=True)
|
||||
team = models.CharField(max_length=30, default='')
|
||||
season = models.IntegerField(null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.player_name
|
||||
|
||||
|
||||
class PlayerShotChartData(models.Model):
|
||||
player_name = models.CharField(max_length=255, default='')
|
||||
top = models.IntegerField(null=True)
|
||||
left = models.IntegerField(null=True)
|
||||
date = models.CharField(max_length=255, default='')
|
||||
qtr = models.CharField(max_length=255, default='')
|
||||
time_remaining = models.CharField(max_length=12, default='')
|
||||
result = models.BooleanField(null=True, default='')
|
||||
shot_type = models.CharField(max_length=6, default='')
|
||||
distance_ft = models.IntegerField(null=True)
|
||||
lead = models.BooleanField(null=True)
|
||||
lebron_team_score = models.IntegerField(null=True)
|
||||
opponent_team_score = models.IntegerField(null=True)
|
||||
opponent = models.CharField(max_length=30, default='')
|
||||
team = models.CharField(max_length=30, default='')
|
||||
season = models.IntegerField(null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.player_name
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -15,10 +15,19 @@ django.setup()
|
||||
|
||||
from nba_data.models import PlayerAdvancedData
|
||||
|
||||
# If season is 2014, then change CHO to CHA
|
||||
teams = ['HOU' ,'PHI', 'BOS', 'NYK', 'BRK', 'TOR', 'MEM', 'NOP', 'DAL', 'SAS', 'DEN', 'MIN', 'OKC', 'UTA', 'POR', 'MIL', 'CLE', 'CHI', 'IND', 'DET', 'SAC', 'PHO', 'GSW', 'LAC', 'LAL', 'MIA', 'ATL', 'WAS', 'ORL', 'CHO']
|
||||
team_abbreviations = ['ATL', 'BOS', 'BRK', 'CHI', 'CHO', 'CLE', 'DAL', 'DEN', 'DET', 'GSW', 'HOU', 'IND', 'LAC', 'LAL', 'MEM', 'MIA', 'MIL', 'MIN', 'NOP', 'NYK', 'OKC', 'ORL', 'PHI', 'PHO', 'POR', 'SAC', 'SAS', 'TOR', 'UTA', 'WAS']
|
||||
|
||||
# Change CHO to CHA 2014 and prior.
|
||||
# Change NOP to NOH for 2013 and prior.
|
||||
# Change BRK to NJN for 2012 and prior.
|
||||
# Change OKC to SEA for 2008 and prior.
|
||||
# Change NOH to NOK for 2007 and 2006
|
||||
# Change NOK to NOH for 2005 and prior.
|
||||
# Change NOH to CHH for 2002 and prior. NOLA did not have a team before 2003.
|
||||
# Change WAS to WSB for 1997 and prior.
|
||||
# Change MEM to VAN for 2001 and prior.
|
||||
# Change LAC to SDC for 1984 and prior.
|
||||
|
||||
teams = ['HOU' ,'PHI', 'BOS', 'NYK', 'NJN', 'TOR', 'MEM', 'NOH', 'DAL', 'SAS', 'DEN', 'MIN', 'OKC', 'UTA', 'POR', 'MIL', 'CLE', 'CHI', 'IND', 'DET', 'SAC', 'PHO', 'GSW', 'LAC', 'LAL', 'MIA', 'ATL', 'WAS', 'ORL', 'CHA']
|
||||
season = input('What season? ')
|
||||
|
||||
for team in teams:
|
||||
|
||||
@@ -29,6 +29,7 @@ from nba_data.models import PlayerPlayoffTotalsData
|
||||
|
||||
teams = ['HOU' ,'PHI', 'BOS', 'NYK', 'NJN', 'TOR', 'MEM', 'NOH', 'DAL', 'SAS', 'DEN', 'MIN', 'OKC', 'UTA', 'POR', 'MIL', 'CLE', 'CHI', 'IND', 'DET', 'SAC', 'PHO', 'GSW', 'LAC', 'LAL', 'MIA', 'ATL', 'WAS', 'ORL', 'CHA']
|
||||
|
||||
|
||||
team_abbreviations = ['ATL', 'BOS', 'BRK', 'CHI', 'CHO', 'CLE', 'DAL', 'DEN', 'DET', 'GSW', 'HOU', 'IND', 'LAC', 'LAL', 'MEM', 'MIA', 'MIL', 'MIN', 'NOP', 'NYK', 'OKC', 'ORL', 'PHI', 'PHO', 'POR', 'SAC', 'SAS', 'TOR', 'UTA', 'WAS']
|
||||
|
||||
season = input('What season? ')
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
import requests
|
||||
from bs4 import BeautifulSoup, Comment
|
||||
import csv
|
||||
import json
|
||||
import time
|
||||
import re
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
|
||||
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nba_stats.settings')
|
||||
django.setup()
|
||||
|
||||
from nba_data.models import PlayerSalaryData
|
||||
|
||||
# Change CHO to CHA 2014 and prior.
|
||||
# Change NOP to NOH for 2013 and prior.
|
||||
# Change OKC to SEA for 2008 and prior.
|
||||
# Change NOH to NOK for 2007 and 2006
|
||||
# Change NOK to NOH for 2005 and prior.
|
||||
# Change NOH to CHH for 2002 and prior. NOLA did not have a team before 2003.
|
||||
# Change WAS to WSB for 1997 and prior.
|
||||
# Change BRK to NJN for 2012 and prior.
|
||||
# Change MEM to VAN for 2001 and prior.
|
||||
# Change LAC to SDC for 1984 and prior.
|
||||
|
||||
|
||||
teams = ['HOU' ,'PHI', 'BOS', 'NYK', 'BRK', 'TOR', 'MEM', 'NOP', 'DAL', 'SAS', 'DEN', 'MIN', 'OKC', 'UTA', 'POR', 'MIL', 'CLE', 'CHI', 'IND', 'DET', 'SAC', 'PHO', 'GSW', 'LAC', 'LAL', 'MIA', 'ATL', 'WAS', 'ORL', 'CHO']
|
||||
teams_test = ['HOU', 'PHI', 'BOS']
|
||||
|
||||
season = input('What season? ')
|
||||
|
||||
for team in teams:
|
||||
url_make = 'https://www.basketball-reference.com/teams/' + team + '/' + season + '.html'
|
||||
response = requests.get(url_make)
|
||||
|
||||
soup = BeautifulSoup(response.text, "html.parser")
|
||||
|
||||
comment = soup.find(string=lambda text: isinstance(text, Comment) and "salaries2" in text)
|
||||
table_soup = BeautifulSoup(comment, "html.parser")
|
||||
table = table_soup.find("table", {'class': 'suppress_all stats_table', 'id': 'salaries2'})
|
||||
|
||||
if table is None:
|
||||
print(f"Table not found for team {team} and season {season}.")
|
||||
# sys.exit(1)
|
||||
continue
|
||||
|
||||
header_row = table.find("thead").find("tr")
|
||||
rows = table.find("tbody").find_all("tr")
|
||||
|
||||
|
||||
# Extract coloumn headers
|
||||
headers = ['player_name']
|
||||
headers.extend([col.text.strip() for col in header_row.find_all("th")][2:])
|
||||
headers.extend(['team', 'season']) # Add 'team' and 'season' fields to headers
|
||||
|
||||
# Extract rows as dictionaries
|
||||
data = []
|
||||
for row in rows:
|
||||
cols = row.find_all("td")
|
||||
cols = [col.text.strip() for col in cols]
|
||||
row_dict = {header: (None if col == "" else col) for header, col in zip(headers, cols)}
|
||||
row_dict['team'] = team
|
||||
row_dict['season'] = season
|
||||
data.append(row_dict)
|
||||
|
||||
|
||||
# locate current directory
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# save as CSV file
|
||||
csv_output_path = os.path.join(script_dir, '..', 'data', f'{team}_{season}_player_salary_output.csv')
|
||||
with open(csv_output_path, "w", newline="") as csvfile:
|
||||
writer = csv.DictWriter(csvfile, fieldnames=headers)
|
||||
writer.writeheader()
|
||||
for row in data:
|
||||
writer.writerow(row)
|
||||
|
||||
# Save as JSON
|
||||
json_output_path = os.path.join(script_dir, '..', 'data', f'{team}_{season}_player_salary_output.json')
|
||||
with open(json_output_path, 'w') as jsonfile:
|
||||
json.dump(data, jsonfile)
|
||||
|
||||
# save data to database
|
||||
|
||||
for row in data:
|
||||
|
||||
row['Salary'] = int(row['Salary'].replace(',', '').replace('$', '')) if row['Salary'] else None
|
||||
|
||||
player_data = PlayerSalaryData(
|
||||
player_name = row['player_name'],
|
||||
salary = row['Salary'],
|
||||
team = row['team'],
|
||||
season = row['season'],
|
||||
)
|
||||
player_data.save()
|
||||
|
||||
print('success')
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
import os
|
||||
import sys
|
||||
import django
|
||||
import requests
|
||||
from bs4 import BeautifulSoup, Comment
|
||||
import csv
|
||||
import re
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
||||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'nba_stats.settings')
|
||||
django.setup()
|
||||
|
||||
from nba_data.models import PlayerShotChartData
|
||||
|
||||
player_name = 'LeBron James'
|
||||
season = 2014
|
||||
# team = 'LAL' # You might want to find a way to get this from the webpage
|
||||
url = 'https://www.basketball-reference.com/players/j/jamesle01/shooting/' + \
|
||||
str(season)
|
||||
|
||||
response = requests.get(url)
|
||||
soup = BeautifulSoup(response.text, "html.parser")
|
||||
|
||||
# Find the comment containing the shot chart
|
||||
comment = soup.find(string=lambda text: isinstance(
|
||||
text, Comment) and "div_shot-chart" in text)
|
||||
shot_chart_soup = BeautifulSoup(comment, "html.parser")
|
||||
|
||||
# Now you can find the shot chart in the parsed comment
|
||||
shot_chart = shot_chart_soup.find("div", {"id": "shot-wrapper"})
|
||||
|
||||
shots = shot_chart.find_all("div", {"class": ["tooltip make", "tooltip miss"]})
|
||||
|
||||
# save data to database and CSV
|
||||
shot_chart_data = []
|
||||
|
||||
for shot_div in shots:
|
||||
try:
|
||||
# Parse shot data
|
||||
style_values = shot_div['style'].split(';')
|
||||
top_value = int(style_values[0].split(
|
||||
':')[1].replace('px', '').strip())
|
||||
left_value = int(style_values[1].split(
|
||||
':')[1].replace('px', '').strip())
|
||||
|
||||
# Parse tip attribute
|
||||
tip_parts = shot_div['tip'].split('<br>')
|
||||
|
||||
# Within your loop:
|
||||
date_and_opponent = re.split(' at | vs ', tip_parts[0])
|
||||
date = date_and_opponent[0].strip().split(
|
||||
',')[0] + ',' + date_and_opponent[0].strip().split(',')[1]
|
||||
team = date_and_opponent[0].strip().split(',')[2].strip()
|
||||
opponent = date_and_opponent[1].strip()
|
||||
|
||||
quarter_and_time = tip_parts[1].split(',')
|
||||
quarter = quarter_and_time[0].strip()
|
||||
time_remaining = quarter_and_time[1].strip().split(' ')[0]
|
||||
|
||||
result_and_type_and_distance = tip_parts[2].split(' ')
|
||||
result = result_and_type_and_distance[0].strip() == 'Made'
|
||||
shot_type = int(result_and_type_and_distance[1][0])
|
||||
distance_ft = int(result_and_type_and_distance[-2].strip())
|
||||
|
||||
team_score_and_opponent_score = tip_parts[3].split(' ')[-1].split('-')
|
||||
team_score = int(team_score_and_opponent_score[0].strip())
|
||||
opponent_score = int(team_score_and_opponent_score[1].strip())
|
||||
|
||||
lead = team_score > opponent_score
|
||||
|
||||
shot_chart_row = {
|
||||
'player_name': player_name,
|
||||
'top': top_value,
|
||||
'left': left_value,
|
||||
'date': date,
|
||||
'qtr': quarter,
|
||||
'time_remaining': time_remaining,
|
||||
'result': result,
|
||||
'shot_type': shot_type,
|
||||
'distance_ft': distance_ft,
|
||||
'lead': lead,
|
||||
'lebron_team_score': team_score,
|
||||
'opponent_team_score': opponent_score,
|
||||
'opponent': opponent,
|
||||
'team': team,
|
||||
'season': season
|
||||
}
|
||||
shot_chart_data.append(shot_chart_row)
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error processing shot_div: {shot_div}")
|
||||
print(f"Exception: {e}")
|
||||
|
||||
|
||||
# save as CSV file
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
csv_output_path = os.path.join(
|
||||
script_dir, '..', 'data', f'{player_name}_{season}_shot_chart_output.csv')
|
||||
with open(csv_output_path, "w", newline="") as csvfile:
|
||||
writer = csv.DictWriter(csvfile, fieldnames=shot_chart_data[0].keys())
|
||||
writer.writeheader()
|
||||
for row in shot_chart_data:
|
||||
writer.writerow(row)
|
||||
|
||||
# Save the records in the database
|
||||
try:
|
||||
PlayerShotChartData.objects.bulk_create(
|
||||
PlayerShotChartData(**row) for row in shot_chart_data
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error inserting data into database: {e}")
|
||||
|
||||
print('success')
|
||||
@@ -15,8 +15,19 @@ django.setup()
|
||||
|
||||
from nba_data.models import PlayerTotalsData
|
||||
|
||||
teams = ['HOU' ,'PHI', 'BOS', 'NYK', 'BRK', 'TOR', 'MEM', 'NOP', 'DAL', 'SAS', 'DEN', 'MIN', 'OKC', 'UTA', 'POR', 'MIL', 'CLE', 'CHI', 'IND', 'DET', 'SAC', 'PHO', 'GSW', 'LAC', 'LAL', 'MIA', 'ATL', 'WAS', 'ORL', 'CHO']
|
||||
team_abbreviations = ['ATL', 'BOS', 'BRK', 'CHI', 'CHO', 'CLE', 'DAL', 'DEN', 'DET', 'GSW', 'HOU', 'IND', 'LAC', 'LAL', 'MEM', 'MIA', 'MIL', 'MIN', 'NOP', 'NYK', 'OKC', 'ORL', 'PHI', 'PHO', 'POR', 'SAC', 'SAS', 'TOR', 'UTA', 'WAS']
|
||||
# Change CHO to CHA 2014 and prior.
|
||||
# Change NOP to NOH for 2013 and prior.
|
||||
# Change OKC to SEA for 2008 and prior.
|
||||
# Change NOH to NOK for 2007 and 2006
|
||||
# Change NOK to NOH for 2005 and prior.
|
||||
# Change NOH to CHH for 2002 and prior. NOLA did not have a team before 2003.
|
||||
# Change WAS to WSB for 1997 and prior.
|
||||
# Change BRK to NJN for 2012 and prior.
|
||||
# Change MEM to VAN for 2001 and prior.
|
||||
# Change LAC to SDC for 1984 and prior.
|
||||
|
||||
teams = ['HOU' ,'PHI', 'BOS', 'NYK', 'NJN', 'TOR', 'MEM', 'NOH', 'DAL', 'SAS', 'DEN', 'MIN', 'OKC', 'UTA', 'POR', 'MIL', 'CLE', 'CHI', 'IND', 'DET', 'SAC', 'PHO', 'GSW', 'LAC', 'LAL', 'MIA', 'ATL', 'WAS', 'ORL', 'CHA']
|
||||
|
||||
|
||||
# team = input('What team? ')
|
||||
# OMIT above. Will now only ask for season and iterate thru teams list.
|
||||
|
||||
+16
-1
@@ -1,6 +1,6 @@
|
||||
# Serializers are defined that will convert model instances to JSON
|
||||
from rest_framework import serializers
|
||||
from .models import PlayerData, PlayerTotalsData, PlayerAdvancedData, PlayerPlayoffTotalsData, PlayerPlayoffAdvancedData
|
||||
from .models import PlayerData, PlayerTotalsData, PlayerAdvancedData, PlayerPlayoffTotalsData, PlayerPlayoffAdvancedData, PlayerSalaryData, PlayerShotChartData
|
||||
|
||||
class PlayerDataSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
@@ -30,5 +30,20 @@ class PlayerPlayoffAdvancedDataSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PlayerPlayoffAdvancedData
|
||||
fields = '__all__'
|
||||
|
||||
class PlayerSalaryDataSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = PlayerSalaryData
|
||||
fields = '__all__'
|
||||
|
||||
class PlayerShotChartDataSerializer(serializers.ModelSerializer):
|
||||
color = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = PlayerShotChartData
|
||||
fields = ['top', 'left', 'date', 'qtr', 'time_remaining', 'result', 'shot_type', 'distance_ft', 'lead', 'lebron_team_score', 'opponent_team_score', 'opponent', 'team', 'season', 'color']
|
||||
|
||||
def get_color(self, obj):
|
||||
return 'green' if obj.result else 'red'
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>NBA Data API</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>Welcome to NBA Data API!</h1>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
+4
-1
@@ -1,7 +1,8 @@
|
||||
from django.urls import path
|
||||
from .views import PlayerDataList, PlayerDataByTeamList, PlayerDataBySeasonList, PlayerDataByNameList, TopScorersbySeasonList, TopScorersbySeasonListPlayoffs, ThreeTwoTopPointTrends, TopAssistsBySeasonList, TopReboundsBySeasonList, TopBlocksBySeasonList, TopStealsBySeasonList, TopOffensiveReboundsBySeasonList, TopDefensiveReboundsBySeasonList, PointsPerGameHistogramBySeasonList, TopPtsScatterPlotData, TopPtsScatterPlotDataFast, TopPtsScatterPlotDataFast2018, Top20ScorersPost2009WS, Top20ScorersPost2014WS, Top20ScorersPost2018WS, TopAssistsBySeasonListPlayoffs, Top25ScorersPostSeasonPlayoffs, TopPtsScatterPlotDataFastSelect, OverallDBStats, TopScorersbySeasonTotalsList, TopAssistsBySeasonTotalsList, TopReboundsbySeasonTotalsList, TopStealsbySeasonTotalsList, TopBlocksbySeasonTotalsList, TopDefensiveReboundsBySeasonTotalsList, TopOffensiveReboundsbySeasonTotalsList
|
||||
from .views import PlayerDataList, PlayerDataByTeamList, PlayerDataBySeasonList, PlayerDataByNameList, TopScorersbySeasonList, TopScorersbySeasonListPlayoffs, ThreeTwoTopPointTrends, TopAssistsBySeasonList, TopReboundsBySeasonList, TopBlocksBySeasonList, TopStealsBySeasonList, TopOffensiveReboundsBySeasonList, TopDefensiveReboundsBySeasonList, PointsPerGameHistogramBySeasonList, TopPtsScatterPlotData, TopPtsScatterPlotDataFast, TopPtsScatterPlotDataFast2018, Top20ScorersPost2009WS, Top20ScorersPost2014WS, Top20ScorersPost2018WS, TopAssistsBySeasonListPlayoffs, Top25ScorersPostSeasonPlayoffs, TopPtsScatterPlotDataFastSelect, OverallDBStats, TopScorersbySeasonTotalsList, TopAssistsBySeasonTotalsList, TopReboundsbySeasonTotalsList, TopStealsbySeasonTotalsList, TopBlocksbySeasonTotalsList, TopDefensiveReboundsBySeasonTotalsList, TopOffensiveReboundsbySeasonTotalsList, UsageRateHistogramView, PlayerShotChartDataList, landing_page
|
||||
|
||||
urlpatterns = [
|
||||
path('', landing_page, name='landing'),
|
||||
path('api/playerdata/', PlayerDataList.as_view(), name='playerdata_list'),
|
||||
path('api/playerdata/team/<str:team>/', PlayerDataByTeamList.as_view(), name='playerdata_by_team'),
|
||||
path('api/playerdata/season/<str:season>/', PlayerDataBySeasonList.as_view(), name='playerdata_by_season'),
|
||||
@@ -24,6 +25,7 @@ urlpatterns = [
|
||||
path('api/top_rebounds_defensive/<int:season>/', TopDefensiveReboundsBySeasonList.as_view(), name='top_rebounds_DRB'),
|
||||
path('api/top_rebounds_defensive/totals/<int:season>/', TopDefensiveReboundsBySeasonTotalsList.as_view(), name='top_rebounds_DRB_totals'),
|
||||
path('api/points_per_game_histogram/<int:season>/', PointsPerGameHistogramBySeasonList.as_view(), name='points_per_game_histogram'),
|
||||
path('api/usage_histogram/<int:season>/', UsageRateHistogramView.as_view(), name='usage_histogram'),
|
||||
path('api/top_pts_scatter_plot/', TopPtsScatterPlotData.as_view(), name='top_pts_scatter_plot'),
|
||||
path('api/top_pts_scatter_plot_fast/', TopPtsScatterPlotDataFast.as_view(), name='top_pts_scatter_plot_fast'),
|
||||
path('api/top_pts_scatter_plot_fast_2018/', TopPtsScatterPlotDataFast2018.as_view(), name='top_pts_scatter_plot_fast_2018'),
|
||||
@@ -33,4 +35,5 @@ urlpatterns = [
|
||||
path('api/top_25_PTS_ws/playoffs/<int:season>/', Top25ScorersPostSeasonPlayoffs.as_view(), name='top_25_PTS_ws_playoffs'),
|
||||
path('api/top_25_PTS_ws/season/<int:season>/', TopPtsScatterPlotDataFastSelect.as_view(), name='top_25_PTS_ws_season'),
|
||||
path('api/stats/', OverallDBStats.as_view(), name='overall_db_stats'),
|
||||
path('api/shot_chart_data/<str:player_name>/<str:season>/', PlayerShotChartDataList.as_view(), name='player_shot_chart'),
|
||||
]
|
||||
+45
-4
@@ -1,12 +1,12 @@
|
||||
from django.shortcuts import render
|
||||
from django.http import JsonResponse, Http404
|
||||
from django.core import serializers
|
||||
from .models import PlayerData, PlayerTotalsData, PlayerAdvancedData, PlayerPlayoffTotalsData, PlayerPlayoffAdvancedData
|
||||
from .models import PlayerData, PlayerTotalsData, PlayerAdvancedData, PlayerPlayoffTotalsData, PlayerPlayoffAdvancedData, PlayerShotChartData
|
||||
from rest_framework import generics
|
||||
from .serializers import PlayerDataSerializer, HistogramDataSerializer, PlayerPlayoffTotalsDataSerializer, PlayerTotalsDataSerializer
|
||||
from .serializers import PlayerDataSerializer, HistogramDataSerializer, PlayerPlayoffTotalsDataSerializer, PlayerTotalsDataSerializer, PlayerShotChartDataSerializer
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.response import Response
|
||||
from django.db.models import Avg, Sum, F, FloatField, Min, Max
|
||||
from django.db.models import Avg, Sum, F, Min, Max
|
||||
from collections import Counter
|
||||
import math
|
||||
from django.db import connection
|
||||
@@ -245,8 +245,40 @@ class PointsPerGameHistogramBySeasonList(generics.ListAPIView):
|
||||
|
||||
return histogram_list
|
||||
|
||||
# USG Percent Histogram
|
||||
|
||||
# Scatter Plot - Top 30 players by total PTS across all seasons in DB. Then map those 30 players on a scatter plot against total PTS/WS for each season.
|
||||
class UsageRateHistogramView(generics.ListAPIView):
|
||||
serializer_class = HistogramDataSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
season = self.kwargs['season']
|
||||
queryset = PlayerAdvancedData.objects.filter(season=season)
|
||||
|
||||
# Get the usage rates for each player, ignoring null values
|
||||
usage_rate_list = [player.usg_percent for player in queryset if player.usg_percent is not None]
|
||||
|
||||
# Define histogram bins for usage rate ranges
|
||||
bin_ranges = [i * 5 for i in range(21)] # 0, 5, 10, ..., 100
|
||||
histogram_data = Counter()
|
||||
|
||||
# Fill the histogram with data
|
||||
for usage_rate in usage_rate_list:
|
||||
bin_index = next(
|
||||
(i for i, r in enumerate(bin_ranges) if r >= usage_rate), -1)
|
||||
if bin_index >= 1:
|
||||
bin_label = f"{bin_ranges[bin_index - 1]}-{bin_ranges[bin_index]}"
|
||||
histogram_data[bin_label] += 1
|
||||
|
||||
# Convert histogram_data to list of dicts for serialization
|
||||
histogram_list = [{"range": k, "count": v}
|
||||
for k, v in histogram_data.items()]
|
||||
|
||||
return histogram_list
|
||||
|
||||
|
||||
|
||||
|
||||
# Scatter Plot - Top 25 players by total PTS across all seasons in DB. Then map those 25 players on a scatter plot against total PTS/WS for each season.
|
||||
|
||||
class TopPtsScatterPlotData(APIView):
|
||||
def get(self, request, *args, **kwargs):
|
||||
@@ -627,5 +659,14 @@ class OverallDBStats(APIView):
|
||||
return Response(response_data)
|
||||
|
||||
|
||||
class PlayerShotChartDataList(generics.ListAPIView):
|
||||
serializer_class = PlayerShotChartDataSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
player_name = self.kwargs['player_name']
|
||||
season = self.kwargs['season']
|
||||
return PlayerShotChartData.objects.filter(player_name__icontains=player_name, season=season).order_by('id')
|
||||
|
||||
|
||||
def landing_page(request):
|
||||
return render(request, 'landing.html')
|
||||
Reference in new issue
Block a user