Skip to content

Commit

Permalink
Merge pull request #66 from Esterni/xriga/update-chart-data-objects
Browse files Browse the repository at this point in the history
Update Chart Data Objects
  • Loading branch information
XanderRiga authored Aug 25, 2020
2 parents ab631ff + 1255965 commit 3cea16a
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 71 deletions.
6 changes: 3 additions & 3 deletions client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,14 @@ async def test_current_seasons(self):
async def test_irating(self):
response = await client.irating(499343, constants.Category.road.value)
self.assertIsInstance(response, chart_data.ChartData)
for irating in response.list:
for irating in response.content:
self.assertIsInstance(irating, chart_data.IRating)

@async_test
async def test_ttrating(self):
response = await client.ttrating(499343, constants.Category.road.value)
self.assertIsInstance(response, chart_data.ChartData)
for ttrating in response.list:
for ttrating in response.content:
self.assertIsInstance(ttrating, chart_data.TTRating)

@async_test
Expand All @@ -79,7 +79,7 @@ async def test_license_class(self):
constants.Category.road.value
)
self.assertIsInstance(response, chart_data.ChartData)
for license_class in response.list:
for license_class in response.content:
self.assertIsInstance(license_class, chart_data.LicenseClass)

@async_test
Expand Down
110 changes: 68 additions & 42 deletions pyracing/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -374,19 +374,80 @@ async def event_results(
return [historical_data.EventResults(x) for
x in response.json()["d"]["r"]]

async def irating(self, cust_id, category):
async def irating(self, cust_id, category) -> \
chart_data.ChartData[chart_data.IRating]:
""" Utilizes the stats_chart class to return a list of iRating values
that are used in the /CareerStats charts. Accessing
get_irating().current will give the most recent irating of a cust_id
get_irating().current() will give the most recent irating of a cust_id
"""
chart_type = ct.ChartType.irating.value
response = await self.stats_chart(cust_id, category, chart_type)
ir_list = [chart_data.IRating(x) for x in response.json()]
response = await self._stats_chart(cust_id, category, chart_type)
ir_list = []
for irating in response.json():
ir_list.append(
chart_data.IRating(timestamp=irating[0], value=irating[1])
)

return chart_data.ChartData(
category=category,
type=chart_type,
content=ir_list)

async def ttrating(self, cust_id, category) -> \
chart_data.ChartData[chart_data.TTRating]:
""" Utilizes the stats_chart class to return a list of ttrating values
that are used in the /CareerStats charts.
"""
chart_type = ct.ChartType.ttrating.value
response = await self._stats_chart(cust_id, category, chart_type)

ttrating_list = []
for ttrating in response.json():
ttrating_list.append(
chart_data.TTRating(timestamp=ttrating[0], value=ttrating[1])
)

return chart_data.ChartData(
category=category,
type=chart_type,
content=ttrating_list)

async def license_class(self, cust_id, category) -> \
chart_data.ChartData[chart_data.LicenseClass]:
""" Utilizes the stats_chart class to return a list of license values
that are used in the /CareerStats charts. See the LicenseClass class
for how to further use this data.
"""
chart_type = ct.ChartType.license_class.value
response = await self._stats_chart(cust_id, category, chart_type)

license_class_list = []
for license_class in response.json():
license_class_list.append(
chart_data.LicenseClass(
timestamp=license_class[0], license_number=license_class[1]
))

return chart_data.ChartData(
category,
ct.ChartType.irating.value,
ir_list)
category=category,
type=chart_type,
content=license_class_list)

async def _stats_chart(self, cust_id, category, chart_type):
""" Returns a list in the form of time:value for the race category
specified. chart_type changes values between iRating, ttRating, or
Safety Rating. Category chooses 1 of the 4 disciplines.
*NOTE* if you are using this, you should use `irating`, `ttrating`
or `license_class` instead. This is used by those methods for the
specific types of each of them.
"""
payload = {
'custId': cust_id,
'catId': category,
'chartType': chart_type
}
url = ct.URL_STATS_CHART
return await self._build_request(url, payload)

async def last_races_stats(self, cust_id):
""" Returns stat summary for the driver's last 10 races as seen
Expand Down Expand Up @@ -671,41 +732,6 @@ async def series_race_results(self, season_id, race_week=1):
return [historical_data.SeriesRaceResults(x) for
x in response.json()['d']]

async def ttrating(self, cust_id, category):
""" Utilizes the stats_chart class to return a list of ttrating values
that are used in the /CareerStats charts.
"""
chart_type = ct.ChartType.ttrating.value
response = await self.stats_chart(cust_id, category, chart_type)
ttrating_list = [chart_data.TTRating(x) for x in response.json()]

return chart_data.ChartData(category, chart_type, ttrating_list)

async def license_class(self, cust_id, category):
""" Utilizes the stats_chart class to return a list of license values
that are used in the /CareerStats charts. See the LicenseClass class
for how to further use this data.
"""
chart_type = ct.ChartType.license_class.value
response = await self.stats_chart(cust_id, category, chart_type)
license_class_list = [chart_data.LicenseClass(x) for
x in response.json()]

return chart_data.ChartData(category, chart_type, license_class_list)

async def stats_chart(self, cust_id, category, chart_type):
""" Returns a list in the form of time:value for the race category
specified. chart_type changes values between iRating, ttRating, or
Safety Rating. Category chooses 1 of the 4 disciplines.
"""
payload = {
'custId': cust_id,
'catId': category,
'chartType': chart_type
}
url = ct.URL_STATS_CHART
return await self._build_request(url, payload)

async def subsession_data(self, subsession_id, cust_id=None):
""" Returns extensive data about a session. This endpoint contains
data points about a session that are unavailable anywhere else.
Expand Down
71 changes: 45 additions & 26 deletions pyracing/response_objects/chart_data.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
from pyracing.constants import ChartType, Category, License
from pyracing.helpers import datetime_from_iracing_timestamp
from dataclasses import dataclass
from datetime import datetime
from typing import List, TypeVar, Generic

T = TypeVar("T")

class ChartData:
def __init__(self, category, type, list):
self.category = category # oval, road, dirt_road, dirt_oval
self.list = list # A list of Iratings, TTRatings, or LicenseClasses
self.type = type # irating, ttrating, or license_class

@dataclass(frozen=True)
class ChartData(Generic[T]):
category: str # oval, road, dirt_road, dirt_oval
type: str # irating, ttrating, license_class
content: List[T]

# The last thing in the list, which is chronologically, the most recent
def current(self):
return self.list[-1]
return self.content[-1]

def type_string(self):
return ChartType(self.type).name
Expand All @@ -18,32 +24,45 @@ def category_string(self):
return Category(self.category).name


class IRating:
def __init__(self, tuple):
self.datetime = datetime_from_iracing_timestamp(tuple[0])
self.value = tuple[1]
@dataclass(frozen=True)
class IRating():
value: int
timestamp: int

def datetime(self) -> datetime:
return datetime_from_iracing_timestamp(self.timestamp)


class TTRating:
def __init__(self, tuple):
self.datetime = datetime_from_iracing_timestamp(tuple[0])
self.value = tuple[1]
@dataclass(frozen=True)
class TTRating():
value: int
timestamp: int

def datetime(self) -> datetime:
return datetime_from_iracing_timestamp(self.timestamp)


# LicenseClass is in the format `4368` where the first digit represents the
# license class A through Rookie which can be seen in Constants.
# License and the next 3 digits are the actual rating, so the example '4368'
# would be B class with a 3.68 rating
class LicenseClass:
def __init__(self, tuple):
self.class_number = int(str(tuple[1])[0])
self.datetime = datetime_from_iracing_timestamp(tuple[0])
self.license_level = self.get_safety_rating(str(tuple[1]))

def class_letter(self):
return License(self.class_number).name

@staticmethod
def get_safety_rating(string):
relevant_chars = string[1:]
@dataclass(frozen=True)
class LicenseClass():
license_number: int
timestamp: int

def datetime(self) -> datetime:
return datetime_from_iracing_timestamp(self.timestamp)

# 1, 2, 3, 4, 5
def class_number(self) -> int:
return int(str(self.license_number)[0])

# A, B, C, D, R
def class_letter(self) -> str:
return License(self.class_number()).name

# example: 3.15
def safety_rating(self) -> str:
relevant_chars = str(self.license_number)[1:]
return relevant_chars[0] + '.' + relevant_chars[1:]

0 comments on commit 3cea16a

Please sign in to comment.