From 8ef912494915f5538fe80ea3dfab2358ef963787 Mon Sep 17 00:00:00 2001 From: AdityaKeshan Date: Thu, 6 Oct 2022 19:24:53 +0530 Subject: [PATCH 1/5] Added Sprint Races --- README.md | 1 + f1pystats/__init__.py | 3 +- f1pystats/f1pystats.py | 17 ++++ f1pystats/sprint_results.py | 20 ++++ tests/test_data/top_3_sprint_2022_11.json | 107 ++++++++++++++++++++++ tests/test_sprint_results.py | 49 ++++++++++ 6 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 f1pystats/sprint_results.py create mode 100644 tests/test_data/top_3_sprint_2022_11.json create mode 100644 tests/test_sprint_results.py diff --git a/README.md b/README.md index 6c5fbd0..10260a7 100644 --- a/README.md +++ b/README.md @@ -43,6 +43,7 @@ The package currently contains eight functions | fp.pit_stops(year, round, stop_number) | Returns the pit stop info for a specific race/pit stop | Pandas DataFrame | | fp.finishing_status(year,race_round) | Returns the finishing status of races in a year (or a particular race if specified) | Pandas DataFrame | |fp.get_drivers(year, race_round) | Returns information on drivers in a given year (or a particular race if specified) | Pandas DataFrame | +|fp.sprint_results(year,race_round) | Returns the sprint qualifying results for a specific year and round | Pandas DataFrame| # Contributions diff --git a/f1pystats/__init__.py b/f1pystats/__init__.py index 24ed5cf..c200aa1 100644 --- a/f1pystats/__init__.py +++ b/f1pystats/__init__.py @@ -10,4 +10,5 @@ lap_times, pit_stops, get_drivers, - finishing_status) + finishing_status, + sprint_results) diff --git a/f1pystats/f1pystats.py b/f1pystats/f1pystats.py index 8c3d63d..8987e26 100644 --- a/f1pystats/f1pystats.py +++ b/f1pystats/f1pystats.py @@ -3,6 +3,8 @@ import requests import pandas as pd +from .sprint_results import SprintResults + from .pit_stops import PitStops from .driver_results import DriverResults @@ -14,6 +16,7 @@ from .race_schedule import RaceSchedule from .lap_times import LapTimes + from .finishing_status import FinishingStatus from .driver_info import DriverInfo @@ -208,6 +211,20 @@ def finishing_status(year: int, race_round: int = 0): zip(status_id, status_info, status_count), columns=["StatusId", "Status", "Count"] ) +def sprint_results(year: int, race_round: int): + """Returns the sprint qualifying results for a year and round""" + json_data=_get_json_content_from_url(f"http://ergast.com/api/f1/{year}/{race_round}/sprint.json") + if len(json_data["MRData"]["RaceTable"]["Races"])==0 : + return "No Sprint Race found for this Grand Prix" + s_results=SprintResults(json_data["MRData"]["RaceTable"]["Races"][0]["SprintResults"]) + driver_pos=s_results.get_driver_pos() + driver_name=s_results.get_driver_name() + driver_team=s_results.get_driver_team() + driver_status=s_results.get_driver_status() + return pd.DataFrame( + zip(driver_pos,driver_name,driver_team,driver_status), + columns=["Position", "Name", "Constructor", "Status"] + ) def _get_json_content_from_url(url, *args, timeout: int = 15, **kwargs): """Returns JSON content from requestsm URL""" diff --git a/f1pystats/sprint_results.py b/f1pystats/sprint_results.py new file mode 100644 index 0000000..cdc34ac --- /dev/null +++ b/f1pystats/sprint_results.py @@ -0,0 +1,20 @@ +"""Contains all functions used by sprint_results()""" + + +class SprintResults(): + """Contains all the methods used to get sprint qualifying results""" + + def __init__(self, results): + self.results = results + def get_driver_pos(self): + """Returns driver position""" + return [i["position"] for i in self.results] + def get_driver_name(self): + """Returns driver name""" + return [i["Driver"]["givenName"]+" "+i["Driver"]["familyName"] for i in self.results] + def get_driver_team(self): + """Returns the driver team name""" + return [i["Constructor"]["name"] for i in self.results] + def get_driver_status(self): + """Returns the driver sprint status""" + return [i["status"] for i in self.results] diff --git a/tests/test_data/top_3_sprint_2022_11.json b/tests/test_data/top_3_sprint_2022_11.json new file mode 100644 index 0000000..a1c9f65 --- /dev/null +++ b/tests/test_data/top_3_sprint_2022_11.json @@ -0,0 +1,107 @@ +[ + { + "number": "1", + "position": "1", + "positionText": "1", + "points": "8", + "Driver": { + "driverId": "max_verstappen", + "permanentNumber": "33", + "code": "VER", + "url": "http://en.wikipedia.org/wiki/Max_Verstappen", + "givenName": "Max", + "familyName": "Verstappen", + "dateOfBirth": "1997-09-30", + "nationality": "Dutch" + }, + "Constructor": { + "constructorId": "red_bull", + "url": "http://en.wikipedia.org/wiki/Red_Bull_Racing", + "name": "Red Bull", + "nationality": "Austrian" + }, + "grid": "1", + "laps": "23", + "status": "Finished", + "Time": { + "millis": "1590059", + "time": "26:30.059" + }, + "FastestLap": { + "lap": "5", + "Time": { + "time": "1:08.455" + } + } + }, + { + "number": "16", + "position": "2", + "positionText": "2", + "points": "7", + "Driver": { + "driverId": "leclerc", + "permanentNumber": "16", + "code": "LEC", + "url": "http://en.wikipedia.org/wiki/Charles_Leclerc", + "givenName": "Charles", + "familyName": "Leclerc", + "dateOfBirth": "1997-10-16", + "nationality": "Monegasque" + }, + "Constructor": { + "constructorId": "ferrari", + "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari", + "name": "Ferrari", + "nationality": "Italian" + }, + "grid": "2", + "laps": "23", + "status": "Finished", + "Time": { + "millis": "1591734", + "time": "+1.675" + }, + "FastestLap": { + "lap": "4", + "Time": { + "time": "1:08.321" + } + } + }, + { + "number": "55", + "position": "3", + "positionText": "3", + "points": "6", + "Driver": { + "driverId": "sainz", + "permanentNumber": "55", + "code": "SAI", + "url": "http://en.wikipedia.org/wiki/Carlos_Sainz_Jr.", + "givenName": "Carlos", + "familyName": "Sainz", + "dateOfBirth": "1994-09-01", + "nationality": "Spanish" + }, + "Constructor": { + "constructorId": "ferrari", + "url": "http://en.wikipedia.org/wiki/Scuderia_Ferrari", + "name": "Ferrari", + "nationality": "Italian" + }, + "grid": "3", + "laps": "23", + "status": "Finished", + "Time": { + "millis": "1595703", + "time": "+5.644" + }, + "FastestLap": { + "lap": "4", + "Time": { + "time": "1:08.409" + } + } + } + ] \ No newline at end of file diff --git a/tests/test_sprint_results.py b/tests/test_sprint_results.py new file mode 100644 index 0000000..883f772 --- /dev/null +++ b/tests/test_sprint_results.py @@ -0,0 +1,49 @@ +"""This module is responsible for testing the methods in sprint_results.py""" + +import json +from f1pystats.sprint_results import SprintResults + + +class TestSprintResults: + """Contains functions for testing the methods in SprintResults""" + + data = "" + with open("tests/test_data/top_3_sprint_2022_11.json", encoding='utf-8') as f: + data = json.load(f) + f.close() + + s_result = SprintResults(data) + + def test_get_driver_pos(self): + """Test the driver position returned by get_driver_pos""" + driver_pos = self.s_result.get_driver_pos() + assert driver_pos == [ + "1", "2", "3" + ] + + def test_get_driver_name(self): + """Test the driver name returned by get_driver_name""" + name = self.s_result.get_driver_name() + assert name == [ + "Max Verstappen", + "Charles Leclerc", + "Carlos Sainz" + ] + + def test_get_driver_team(self): + """Test the driver team returned by get_driver_team""" + team = self.s_result.get_driver_team() + assert team == [ + "Red Bull", + "Ferrari", + "Ferrari" + ] + + def test_get_driver_status(self): + """Test the driver status returned by get_driver_status""" + status = self.s_result.get_driver_status() + assert status == [ + "Finished", + "Finished", + "Finished" + ] From 6ca708e48d1e9962c0faeee76ceea0f43cb41cd7 Mon Sep 17 00:00:00 2001 From: AdityaKeshan Date: Thu, 6 Oct 2022 19:31:34 +0530 Subject: [PATCH 2/5] Added Sprint Races --- f1pystats/__init__.py | 2 +- f1pystats/f1pystats.py | 4 +++- tests/test_sprint_results.py | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/f1pystats/__init__.py b/f1pystats/__init__.py index c200aa1..8631047 100644 --- a/f1pystats/__init__.py +++ b/f1pystats/__init__.py @@ -10,5 +10,5 @@ lap_times, pit_stops, get_drivers, - finishing_status, + finishing_status, sprint_results) diff --git a/f1pystats/f1pystats.py b/f1pystats/f1pystats.py index 8987e26..c0e5756 100644 --- a/f1pystats/f1pystats.py +++ b/f1pystats/f1pystats.py @@ -213,7 +213,9 @@ def finishing_status(year: int, race_round: int = 0): def sprint_results(year: int, race_round: int): """Returns the sprint qualifying results for a year and round""" - json_data=_get_json_content_from_url(f"http://ergast.com/api/f1/{year}/{race_round}/sprint.json") + json_data=_get_json_content_from_url( + f"http://ergast.com/api/f1/{year}/{race_round}/sprint.json" + ) if len(json_data["MRData"]["RaceTable"]["Races"])==0 : return "No Sprint Race found for this Grand Prix" s_results=SprintResults(json_data["MRData"]["RaceTable"]["Races"][0]["SprintResults"]) diff --git a/tests/test_sprint_results.py b/tests/test_sprint_results.py index 883f772..6fb976d 100644 --- a/tests/test_sprint_results.py +++ b/tests/test_sprint_results.py @@ -38,7 +38,7 @@ def test_get_driver_team(self): "Ferrari", "Ferrari" ] - + def test_get_driver_status(self): """Test the driver status returned by get_driver_status""" status = self.s_result.get_driver_status() From c7b9006f3a4acf8f10b0545365c2ed4f64c2e3bc Mon Sep 17 00:00:00 2001 From: AdityaKeshan Date: Thu, 6 Oct 2022 21:14:06 +0530 Subject: [PATCH 3/5] Added Sprint Races --- f1pystats/f1pystats.py | 17 +++++++++++--- f1pystats/sprint_results.py | 18 +++++++++++++++ tests/test_sprint_results.py | 45 ++++++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 3 deletions(-) diff --git a/f1pystats/f1pystats.py b/f1pystats/f1pystats.py index c0e5756..2323e7d 100644 --- a/f1pystats/f1pystats.py +++ b/f1pystats/f1pystats.py @@ -217,15 +217,26 @@ def sprint_results(year: int, race_round: int): f"http://ergast.com/api/f1/{year}/{race_round}/sprint.json" ) if len(json_data["MRData"]["RaceTable"]["Races"])==0 : - return "No Sprint Race found for this Grand Prix" + raise Exception("ERR: No Sprint Race found for this Grand Prix") s_results=SprintResults(json_data["MRData"]["RaceTable"]["Races"][0]["SprintResults"]) driver_pos=s_results.get_driver_pos() driver_name=s_results.get_driver_name() driver_team=s_results.get_driver_team() driver_status=s_results.get_driver_status() + driver_number=s_results.get_driver_number() + driver_laps=s_results.get_laps() + driver_grid=s_results.get_driver_grid() + driver_time=s_results.get_driver_time() + driver_points=s_results.get_driver_points() return pd.DataFrame( - zip(driver_pos,driver_name,driver_team,driver_status), - columns=["Position", "Name", "Constructor", "Status"] + zip( + driver_pos,driver_name, driver_number,driver_team, + driver_laps, driver_grid,driver_status, driver_time, driver_points + ), + columns=[ + "Position", "Name", "Driver Number", "Constructor", + "Laps", "Grid","Status", "Time", "Points" + ] ) def _get_json_content_from_url(url, *args, timeout: int = 15, **kwargs): diff --git a/f1pystats/sprint_results.py b/f1pystats/sprint_results.py index cdc34ac..e834e60 100644 --- a/f1pystats/sprint_results.py +++ b/f1pystats/sprint_results.py @@ -18,3 +18,21 @@ def get_driver_team(self): def get_driver_status(self): """Returns the driver sprint status""" return [i["status"] for i in self.results] + def get_driver_number(self): + """Returns the driver number""" + return [i["Driver"]["permanentNumber"] for i in self.results] + def get_laps(self): + """Returns the driver sprint laps""" + return [i["laps"] for i in self.results] + def get_driver_grid(self): + """Returns the driver sprint grid status""" + return [i["grid"] for i in self.results] + def get_driver_time(self): + """Returns the driver sprint time""" + time=[] + for i in self.results: + time.append(i.get("Time",{"time":"DNF"})['time']) + return time + def get_driver_points(self): + """Returns the driver sprint points""" + return [i["points"] for i in self.results] diff --git a/tests/test_sprint_results.py b/tests/test_sprint_results.py index 6fb976d..1807999 100644 --- a/tests/test_sprint_results.py +++ b/tests/test_sprint_results.py @@ -47,3 +47,48 @@ def test_get_driver_status(self): "Finished", "Finished" ] + + def test_get_driver_number(self): + """Test the driver number returned by get_driver_number""" + number = self.s_result.get_driver_number() + assert number == [ + "33", + "16", + "55" + ] + + def test_get_laps(self): + """Test the driver laps returned by get_laps""" + laps = self.s_result.get_laps() + assert laps == [ + "23", + "23", + "23" + ] + + def test_get_driver_grid(self): + """Test the driver grid position returned by get_driver_grid""" + grid = self.s_result.get_driver_grid() + assert grid == [ + "1", + "2", + "3" + ] + + def test_get_driver_time(self): + """Test the driver time returned by get_driver_time""" + driver_time = self.s_result.get_driver_time() + assert driver_time == [ + "26:30.059", + "+1.675", + "+5.644" + ] + + def test_get_driver_points(self): + """Test the driver points returned by get_driver_points""" + points = self.s_result.get_driver_points() + assert points == [ + "8", + "7", + "6" + ] From 77ac756040363d20fdcf73e63d368cdbc80e1117 Mon Sep 17 00:00:00 2001 From: alec-kr <52685467+alec-kr@users.noreply.github.com> Date: Thu, 6 Oct 2022 14:39:59 -0400 Subject: [PATCH 4/5] Update f1pystats.py --- f1pystats/f1pystats.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/f1pystats/f1pystats.py b/f1pystats/f1pystats.py index 2323e7d..899691f 100644 --- a/f1pystats/f1pystats.py +++ b/f1pystats/f1pystats.py @@ -217,7 +217,7 @@ def sprint_results(year: int, race_round: int): f"http://ergast.com/api/f1/{year}/{race_round}/sprint.json" ) if len(json_data["MRData"]["RaceTable"]["Races"])==0 : - raise Exception("ERR: No Sprint Race found for this Grand Prix") + raise ValueError("No Sprint Race found for this Grand Prix") s_results=SprintResults(json_data["MRData"]["RaceTable"]["Races"][0]["SprintResults"]) driver_pos=s_results.get_driver_pos() driver_name=s_results.get_driver_name() From fd0f4fd71f1541233cb63b60ac1c3f95e725cc85 Mon Sep 17 00:00:00 2001 From: alec-kr <52685467+alec-kr@users.noreply.github.com> Date: Thu, 6 Oct 2022 14:43:15 -0400 Subject: [PATCH 5/5] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 10260a7..0bf9502 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ poetry add ../F1Pystats/dist/f1pystats-0.1.0.whl import F1PyStats as fp ``` -The package currently contains eight functions +The package currently contains nine functions | Function | Description | Returned Datatype | |----------------------------- |--------------------------------------------------------------------- |------------------- | | fp.driver_standings(year) | Returns the driver standings for a particular year | Pandas DataFrame | @@ -43,7 +43,7 @@ The package currently contains eight functions | fp.pit_stops(year, round, stop_number) | Returns the pit stop info for a specific race/pit stop | Pandas DataFrame | | fp.finishing_status(year,race_round) | Returns the finishing status of races in a year (or a particular race if specified) | Pandas DataFrame | |fp.get_drivers(year, race_round) | Returns information on drivers in a given year (or a particular race if specified) | Pandas DataFrame | -|fp.sprint_results(year,race_round) | Returns the sprint qualifying results for a specific year and round | Pandas DataFrame| +|fp.sprint_results(year,race_round) | Returns the sprint qualifying results for a specific race | Pandas DataFrame| # Contributions