Skip to content

Commit

Permalink
[Feature] - Show game logs on player details page (#35)
Browse files Browse the repository at this point in the history
* style game logs for the player details view

* show game log stats on player details page

* add sticky table heading

* update package version
  • Loading branch information
ArielleMurad authored Apr 2, 2023
1 parent 089f87c commit 9685825
Show file tree
Hide file tree
Showing 11 changed files with 169 additions and 41 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "rel-bball-analytics"
version = "1.2.2"
version = "1.3.0"
description = ""
authors = ["Arielle Murad <[email protected]>"]
readme = "README.md"
Expand Down
38 changes: 38 additions & 0 deletions rel_bball_analytics/games/styles.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import pandas as pd

import rel_bball_analytics.static.py.games as styles

from .utils import GAME_LOG_COLUMNS


def format_game_log(game_log: pd.DataFrame):
"""Returns HTML with formatted game log table to be displayed on details page"""
game_log = game_log.sort_values(by=["date"])

game_log["date"] = game_log["date"].apply(format_date)
game_log["result"] = game_log.apply(format_result, axis=1)
game_log["opponent"] = game_log.apply(get_opponent, axis=1)

game_log = game_log[GAME_LOG_COLUMNS.keys()].rename(columns=GAME_LOG_COLUMNS)

return (
game_log.style.format(precision=1, na_rep="")
.set_table_styles(styles.game_log_table())
.hide(axis=0)
.to_html()
)


def format_date(date):
return date.date().strftime("%Y-%m-%d")


def format_result(row):
result = "W" if row["team"] == row["winner"] else "L"
sign = "+" if row["team"] == row["winner"] else "-"

return f"{result} ({sign}{row['difference']})"


def get_opponent(row):
return row["home"] if row["team"] == row["away"] else row["away"]
27 changes: 27 additions & 0 deletions rel_bball_analytics/games/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,33 @@
"difference",
]

GAME_LOG_COLUMNS = {
"date": "Date",
"team": "Team",
"opponent": "Opp",
"result": "Score",
"position": "Pos",
"minutes_played": "MP",
"field_goals_made": "FG",
"field_goal_attempts": "FGA",
"field_goal_percentage": "FG%",
"three_points_made": "3P",
"three_point_attempts": "3PA",
"three_point_percentage": "3P%",
"free_throws_made": "FT",
"free_throw_attempts": "FTA",
"free_throw_percentage": "FT%",
"offensive_rebounds": "ORB",
"defensive_rebounds": "DRB",
"total_rebounds": "TRB",
"assists": "AST",
"steals": "STL",
"blocks": "BLK",
"turnovers": "TOV",
"personal_fouls": "PF",
"points": "PTS",
}


def get_winner(row):
return row["home"] if row["home_score"] > row["away_score"] else row["away"]
Expand Down
17 changes: 1 addition & 16 deletions rel_bball_analytics/players/styles.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,7 @@

import rel_bball_analytics.static.py.players as styles

TABLE_COLUMNS = {
"firstname": "First Name",
"lastname": "Last Name",
"age": "Age",
"team": "Team",
"position": "Position",
"games_played": "GP",
"points": "PPG",
"field_goal_percentage": "FG%",
"three_point_percentage": "FG3%",
"free_throw_percentage": "FT%",
"total_rebounds": "TRB",
"assists": "AST",
"is_active": "Is Active?",
"link": "",
}
from .utils import TABLE_COLUMNS


def format_search_result(search_result: pd.DataFrame):
Expand Down
17 changes: 17 additions & 0 deletions rel_bball_analytics/players/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,23 @@
"college",
]

TABLE_COLUMNS = {
"firstname": "First Name",
"lastname": "Last Name",
"age": "Age",
"team": "Team",
"position": "Position",
"games_played": "GP",
"points": "PPG",
"field_goal_percentage": "FG%",
"three_point_percentage": "3P%",
"free_throw_percentage": "FT%",
"total_rebounds": "TRB",
"assists": "AST",
"is_active": "Is Active?",
"link": "",
}


def calculate_age(birth_date: str):
"""Calculate age from birth date string given in the api response"""
Expand Down
3 changes: 2 additions & 1 deletion rel_bball_analytics/players/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def search():
@players_bp.route("/<id>_<season>", methods=["GET"])
def details(id, season):
from rel_bball_analytics.games.game_log import get_game_log
from rel_bball_analytics.games.styles import format_game_log

from .search import get_player_details
from .styles import format_player_details
Expand All @@ -49,5 +50,5 @@ def details(id, season):
return render_template(
"players/details.html",
player_data=format_player_details(player_data=player_data),
game_log=game_log,
game_log=format_game_log(game_log=game_log),
)
53 changes: 53 additions & 0 deletions rel_bball_analytics/static/py/games.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
TEXT_PRIMARY = "black"

BG_LIGHT = "#D3D3D3"

BORDER_PRIMARY = "2px solid black"

PADDING = "12px"

FONT_FAMILY = "Helvetica, sans-serif"
FONT_SIZE = "14px"


def game_log_table():
return [
{
"selector": "",
"props": [
("border-collapse", "collapse"),
("font-family", FONT_FAMILY),
("font-size", FONT_SIZE),
],
},
{
"selector": "td",
"props": [
("padding", PADDING),
("text-align", "center"),
("border-top", BORDER_PRIMARY),
],
},
{
"selector": "th",
"props": [
("position", "sticky"),
("top", "56px"),
("background-color", "white"),
],
},
{
"selector": "thead th",
"props": [
("font-weight", "bold"),
("padding", PADDING),
("text-align", "center"),
],
},
{
"selector": "tbody tr:hover",
"props": [
("background-color", BG_LIGHT),
],
},
]
2 changes: 1 addition & 1 deletion rel_bball_analytics/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<a class="navbar-brand ml-2 mr-4" href="{{ url_for('home')}}">Home</a>
<a class="navbar-brand ml-2 mr-4" href="{{ url_for('players.search')}}">Players</a>
</nav>
<div class="container">
<div style="padding-left: 4rem;">
{% block content %} {% endblock %}
</div>
</body>
Expand Down
2 changes: 2 additions & 0 deletions rel_bball_analytics/templates/home.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{% extends 'base.html' %}

{% block content %}
<div class="container">
<h1 class="title mt-4">Welcome to Basketball Analytics</h1>
</div>
{% endblock %}
7 changes: 5 additions & 2 deletions rel_bball_analytics/templates/players/details.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

{% block content %}
<h1 class="mt-4">{{ player_data.firstname }} {{ player_data.lastname }}</h1>
<div class="container mt-2">
<div class="mt-2">
<div class="column-30 mb-4">
<p class="mb-2"><b>Birthdate: </b>{{ player_data.birth_date }}</p>
<p class="mb-2"><b>Country: </b>{{ player_data.country }}</p>
Expand All @@ -30,7 +30,7 @@ <h1 class="mt-4">{{ player_data.firstname }} {{ player_data.lastname }}</h1>
</div>

<h2 class="mt-4">Per-Game Statistics ({{ player_data.season }}) </h2>
<div class="container mt-2">
<div class="mt-2">
<table class="season-stats">
<tr>
<th>G</th>
Expand Down Expand Up @@ -78,4 +78,7 @@ <h2 class="mt-4">Per-Game Statistics ({{ player_data.season }}) </h2>
</tr>
</table>
</div>

<h2 class="mt-4">Game Log ({{ player_data.season }}) </h2>
{{ game_log|safe }}
{% endblock %}
42 changes: 22 additions & 20 deletions rel_bball_analytics/templates/players/search.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,29 @@
{% extends 'base.html' %}

{% block content %}
<h1 class="mt-4 mb-2">NBA Player Search</h1>
<div class="container">
<h1 class="mt-4 mb-2">NBA Player Search</h1>

<form class="form-inline" method="post">
<div class="form-group">
<input type="text" name="name" placeholder="Last Name" class="form-control mr-4" required></input>
<select name="season" id="season" class="form-control mr-4" required>
<option value="" selected disabled>Season</option>
<option value="2022">2022-23</option>
<option value="2021">2021-22</option>
<option value="2020">2020-21</option>
<option value="2019">2019-20</option>
<option value="2018">2018-19</option>
<option value="2017">2017-18</option>
<option value="2016">2016-17</option>
<option value="2015">2015-16</option>
</select>
<button type="submit" class="btn btn-primary">Search</button>
</div>
</form>
<form class="form-inline" method="post">
<div class="form-group">
<input type="text" name="name" placeholder="Last Name" class="form-control mr-4" required></input>
<select name="season" id="season" class="form-control mr-4" required>
<option value="" selected disabled>Season</option>
<option value="2022">2022-23</option>
<option value="2021">2021-22</option>
<option value="2020">2020-21</option>
<option value="2019">2019-20</option>
<option value="2018">2018-19</option>
<option value="2017">2017-18</option>
<option value="2016">2016-17</option>
<option value="2015">2015-16</option>
</select>
<button type="submit" class="btn btn-primary">Search</button>
</div>
</form>

<div class="container mt-4">
{% block players %} {% endblock %}
<div class="mt-4">
{% block players %} {% endblock %}
</div>
</div>
{% endblock %}

0 comments on commit 9685825

Please sign in to comment.