From 9685825b2c2a05b006c6140cebee6d7ed770e2c4 Mon Sep 17 00:00:00 2001 From: Arielle Murad Date: Sun, 2 Apr 2023 16:54:26 -0700 Subject: [PATCH] [Feature] - Show game logs on player details page (#35) * style game logs for the player details view * show game log stats on player details page * add sticky table heading * update package version --- pyproject.toml | 2 +- rel_bball_analytics/games/styles.py | 38 +++++++++++++ rel_bball_analytics/games/utils.py | 27 ++++++++++ rel_bball_analytics/players/styles.py | 17 +----- rel_bball_analytics/players/utils.py | 17 ++++++ rel_bball_analytics/players/views.py | 3 +- rel_bball_analytics/static/py/games.py | 53 +++++++++++++++++++ rel_bball_analytics/templates/base.html | 2 +- rel_bball_analytics/templates/home.html | 2 + .../templates/players/details.html | 7 ++- .../templates/players/search.html | 42 ++++++++------- 11 files changed, 169 insertions(+), 41 deletions(-) create mode 100644 rel_bball_analytics/games/styles.py create mode 100644 rel_bball_analytics/static/py/games.py diff --git a/pyproject.toml b/pyproject.toml index 71dca76..a7bc951 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "rel-bball-analytics" -version = "1.2.2" +version = "1.3.0" description = "" authors = ["Arielle Murad "] readme = "README.md" diff --git a/rel_bball_analytics/games/styles.py b/rel_bball_analytics/games/styles.py new file mode 100644 index 0000000..87f3fd5 --- /dev/null +++ b/rel_bball_analytics/games/styles.py @@ -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"] diff --git a/rel_bball_analytics/games/utils.py b/rel_bball_analytics/games/utils.py index 9182e57..f2a9aa6 100644 --- a/rel_bball_analytics/games/utils.py +++ b/rel_bball_analytics/games/utils.py @@ -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"] diff --git a/rel_bball_analytics/players/styles.py b/rel_bball_analytics/players/styles.py index e6ac264..48924af 100644 --- a/rel_bball_analytics/players/styles.py +++ b/rel_bball_analytics/players/styles.py @@ -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): diff --git a/rel_bball_analytics/players/utils.py b/rel_bball_analytics/players/utils.py index 48848c1..ac01359 100644 --- a/rel_bball_analytics/players/utils.py +++ b/rel_bball_analytics/players/utils.py @@ -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""" diff --git a/rel_bball_analytics/players/views.py b/rel_bball_analytics/players/views.py index 1e31e46..a975707 100644 --- a/rel_bball_analytics/players/views.py +++ b/rel_bball_analytics/players/views.py @@ -34,6 +34,7 @@ def search(): @players_bp.route("/_", 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 @@ -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), ) diff --git a/rel_bball_analytics/static/py/games.py b/rel_bball_analytics/static/py/games.py new file mode 100644 index 0000000..7e28eff --- /dev/null +++ b/rel_bball_analytics/static/py/games.py @@ -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), + ], + }, + ] diff --git a/rel_bball_analytics/templates/base.html b/rel_bball_analytics/templates/base.html index c20a445..0eb6d74 100644 --- a/rel_bball_analytics/templates/base.html +++ b/rel_bball_analytics/templates/base.html @@ -17,7 +17,7 @@ Home Players -
+
{% block content %} {% endblock %}
diff --git a/rel_bball_analytics/templates/home.html b/rel_bball_analytics/templates/home.html index d3c3946..c731e54 100644 --- a/rel_bball_analytics/templates/home.html +++ b/rel_bball_analytics/templates/home.html @@ -1,5 +1,7 @@ {% extends 'base.html' %} {% block content %} +

Welcome to Basketball Analytics

+
{% endblock %} diff --git a/rel_bball_analytics/templates/players/details.html b/rel_bball_analytics/templates/players/details.html index a382dd9..d3d8b8f 100644 --- a/rel_bball_analytics/templates/players/details.html +++ b/rel_bball_analytics/templates/players/details.html @@ -6,7 +6,7 @@ {% block content %}

{{ player_data.firstname }} {{ player_data.lastname }}

-
+

Birthdate: {{ player_data.birth_date }}

Country: {{ player_data.country }}

@@ -30,7 +30,7 @@

{{ player_data.firstname }} {{ player_data.lastname }}

Per-Game Statistics ({{ player_data.season }})

-
+
@@ -78,4 +78,7 @@

Per-Game Statistics ({{ player_data.season }})

G
+ +

Game Log ({{ player_data.season }})

+{{ game_log|safe }} {% endblock %} diff --git a/rel_bball_analytics/templates/players/search.html b/rel_bball_analytics/templates/players/search.html index 90cd748..51d572e 100644 --- a/rel_bball_analytics/templates/players/search.html +++ b/rel_bball_analytics/templates/players/search.html @@ -1,27 +1,29 @@ {% extends 'base.html' %} {% block content %} -

NBA Player Search

+
+

NBA Player Search

-
-
- - - -
-
+
+
+ + + +
+
-
- {% block players %} {% endblock %} +
+ {% block players %} {% endblock %} +
{% endblock %}