Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
F1 Overtake Analyser
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Lennard Geese
F1 Overtake Analyser
Commits
8f7de52f
Commit
8f7de52f
authored
1 week ago
by
Lennard Geese
Browse files
Options
Downloads
Patches
Plain Diff
Reorganize code
parent
3bfe983b
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
DataAnalyser.py
+15
-15
15 additions, 15 deletions
DataAnalyser.py
DataImporter.py
+80
-66
80 additions, 66 deletions
DataImporter.py
with
95 additions
and
81 deletions
DataAnalyser.py
+
15
−
15
View file @
8f7de52f
...
@@ -201,6 +201,7 @@ class DataAnalyser(DataHandler):
...
@@ -201,6 +201,7 @@ class DataAnalyser(DataHandler):
return
False
return
False
# ===== Tire Changes =====
# ===== Tire Changes =====
def
getFirstTireChanges
(
self
,
races
:
list
[
Session
]):
def
getFirstTireChanges
(
self
,
races
:
list
[
Session
]):
...
@@ -245,19 +246,6 @@ class DataAnalyser(DataHandler):
...
@@ -245,19 +246,6 @@ class DataAnalyser(DataHandler):
return
latestTireChangeLap
return
latestTireChangeLap
def
__getFirstLapWithoutCompound
(
self
,
compoundsPerLap
:
list
[
list
[
str
]],
startingCompound
:
str
):
currentLap
=
0
compoundFilter
=
self
.
__generateFilter
(
startingCompound
)
for
compoundsThisLap
in
compoundsPerLap
:
noStartingCompoundsLeft
=
True
for
compound
in
compoundsThisLap
:
if
compound
in
compoundFilter
:
noStartingCompoundsLeft
=
False
if
noStartingCompoundsLeft
:
return
currentLap
currentLap
+=
1
return
-
1
# no lap without compound found; all laps use same compound type
def
getCompoundsForRace
(
self
,
race
:
Session
):
def
getCompoundsForRace
(
self
,
race
:
Session
):
compoundsPerLap
:
list
[
list
[
str
]]
=
[[]]
compoundsPerLap
:
list
[
list
[
str
]]
=
[[]]
allRaceLaps
=
race
.
laps
allRaceLaps
=
race
.
laps
...
@@ -276,6 +264,19 @@ class DataAnalyser(DataHandler):
...
@@ -276,6 +264,19 @@ class DataAnalyser(DataHandler):
return
compoundsPerLap
return
compoundsPerLap
def
__getFirstLapWithoutCompound
(
self
,
compoundsPerLap
:
list
[
list
[
str
]],
startingCompound
:
str
):
currentLap
=
0
compoundFilter
=
self
.
__generateFilter
(
startingCompound
)
for
compoundsThisLap
in
compoundsPerLap
:
noStartingCompoundsLeft
=
True
for
compound
in
compoundsThisLap
:
if
compound
in
compoundFilter
:
noStartingCompoundsLeft
=
False
if
noStartingCompoundsLeft
:
return
currentLap
currentLap
+=
1
return
-
1
# no lap without compound found; all laps use same compound type
def
__getPredominantCompound
(
self
,
compoundsThisLap
:
list
[
str
]):
def
__getPredominantCompound
(
self
,
compoundsThisLap
:
list
[
str
]):
slickCounter
=
0
slickCounter
=
0
interCounter
=
0
interCounter
=
0
...
@@ -314,11 +315,10 @@ class DataAnalyser(DataHandler):
...
@@ -314,11 +315,10 @@ class DataAnalyser(DataHandler):
# ===== Events =====
# ===== Events =====
# def analyseRacesForSafetyCars(self, races):
# ===== Other
# ===== Other
=====
def
__enforceSessionType
(
self
,
session
:
Session
,
sessionType
:
str
):
def
__enforceSessionType
(
self
,
session
:
Session
,
sessionType
:
str
):
if
sessionType
not
in
self
.
validSessionTypes
:
if
sessionType
not
in
self
.
validSessionTypes
:
...
...
This diff is collapsed.
Click to expand it.
DataImporter.py
+
80
−
66
View file @
8f7de52f
...
@@ -22,68 +22,7 @@ class DataImporter(DataHandler, ABC):
...
@@ -22,68 +22,7 @@ class DataImporter(DataHandler, ABC):
sessions. If the method does not require one of these, it should not be part of this class.
sessions. If the method does not require one of these, it should not be part of this class.
"""
"""
def
fetchWeather
(
self
,
event
:
Event
|
SessionIdentifier
|
list
[
Event
]
|
list
[
SessionIdentifier
]):
# ===== Sessions =====
"""
Fetch session weather from the wikipedia entry for the specified event(s).
:param event: The event or identifier for any session of the event to fetch weather for. Alternatively a list of
these.
:return: Weather conditions as string, or a list of such strings if a list is provided.
"""
# Recursive call if list provided
if
isinstance
(
event
,
list
):
weatherEntries
:
list
[
string
]
=
[]
for
e
in
event
:
weatherEntries
.
append
(
self
.
fetchWeather
(
e
))
return
weatherEntries
# Convert from SessionIdentifier to Event if needed
if
isinstance
(
event
,
SessionIdentifier
):
event
=
self
.
importEvent
(
event
.
year
,
event
.
event
)
# Fetch weather
wikiHtml
=
self
.
__importWikiHtml
(
event
)
analyser
=
DataAnalyser
()
weather
=
analyser
.
extractWeatherFromHtml
(
wikiHtml
)
return
weather
def
__importWikiHtml
(
self
,
event
:
Event
):
"""
Fetch the HTML contents of the wikipedia page for the event given.
:param event: Event whose wikipedia page to fetch.
:return: HTML content of the wikipedia page as a string.
"""
apiRootUrl
:
string
=
"
https://en.wikipedia.org/wiki/
"
grandPrixName
:
string
=
f
"
{
event
.
year
}
{
event
[
"
EventName
"
]
}
"
uri
:
string
=
re
.
sub
(
"
"
,
"
_
"
,
grandPrixName
)
url
:
string
=
f
"
{
apiRootUrl
}{
uri
}
"
response
=
requests
.
get
(
url
)
if
not
response
.
ok
:
raise
ConnectionError
(
f
"
Could not fetch wikipedia article with URL
{
url
}
"
)
return
response
.
text
# URL example: https://en.wikipedia.org/w/api.php?action=query&titles=2024_S%C3%A3o_Paulo_Grand_Prix&prop=extracts&format=json&exintro=1
def
importEvent
(
self
,
year
:
int
,
event
:
int
|
str
):
return
fastf1
.
get_event
(
year
,
event
)
def
importAllEventsFromYear
(
self
,
year
:
int
):
"""
Get all event objects from given year.
:param year: Year from which to retrieve event objects.
:return: List of all event objects from the given year. Returns None if
"""
if
self
.
__isInFuture
(
year
):
raise
ValueError
(
"
Cannot get event data from the future :)
"
)
events
:
list
[
Event
]
=
[]
schedule
:
EventSchedule
=
fastf1
.
get_event_schedule
(
year
,
include_testing
=
False
)
if
schedule
.
empty
:
print
(
f
"
INFO: No races have run in
{
year
}
yet. You will receive a None object
"
)
return
None
for
raceIndex
in
schedule
[
'
RoundNumber
'
]:
events
.
append
(
schedule
.
get_event_by_round
(
raceIndex
))
return
events
def
importSessionWeather
(
self
,
sessionIdentifier
:
SessionIdentifier
):
def
importSessionWeather
(
self
,
sessionIdentifier
:
SessionIdentifier
):
"""
"""
...
@@ -111,6 +50,10 @@ class DataImporter(DataHandler, ABC):
...
@@ -111,6 +50,10 @@ class DataImporter(DataHandler, ABC):
session
.
load
(
laps
=
laps
,
telemetry
=
telemetry
,
weather
=
weather
,
messages
=
messages
)
session
.
load
(
laps
=
laps
,
telemetry
=
telemetry
,
weather
=
weather
,
messages
=
messages
)
return
session
return
session
# ===== Events =====
def
getWetEventsSince
(
self
,
firstYear
:
int
):
def
getWetEventsSince
(
self
,
firstYear
:
int
):
if
self
.
__isInFuture
(
firstYear
):
raise
ValueError
(
"
Cannot get race data from the future :)
"
)
if
self
.
__isInFuture
(
firstYear
):
raise
ValueError
(
"
Cannot get race data from the future :)
"
)
...
@@ -131,10 +74,6 @@ class DataImporter(DataHandler, ABC):
...
@@ -131,10 +74,6 @@ class DataImporter(DataHandler, ABC):
return
rainRaces
return
rainRaces
def
__isInFuture
(
self
,
year
:
int
):
currentYear
=
datetime
.
now
().
year
return
year
>
currentYear
def
getRainRacesSince
(
self
,
firstYear
:
int
):
def
getRainRacesSince
(
self
,
firstYear
:
int
):
"""
"""
Retrieve all race sessions since and including given year that had at least one minute of rainfall during the race session.
Retrieve all race sessions since and including given year that had at least one minute of rainfall during the race session.
...
@@ -174,3 +113,78 @@ class DataImporter(DataHandler, ABC):
...
@@ -174,3 +113,78 @@ class DataImporter(DataHandler, ABC):
return
rainRaces
return
rainRaces
def
importEvent
(
self
,
year
:
int
,
event
:
int
|
str
):
return
fastf1
.
get_event
(
year
,
event
)
def
importAllEventsFromYear
(
self
,
year
:
int
):
"""
Get all event objects from given year.
:param year: Year from which to retrieve event objects.
:return: List of all event objects from the given year. Returns None if
"""
if
self
.
__isInFuture
(
year
):
raise
ValueError
(
"
Cannot get event data from the future :)
"
)
events
:
list
[
Event
]
=
[]
schedule
:
EventSchedule
=
fastf1
.
get_event_schedule
(
year
,
include_testing
=
False
)
if
schedule
.
empty
:
print
(
f
"
INFO: No races have run in
{
year
}
yet. You will receive a None object
"
)
return
None
for
raceIndex
in
schedule
[
'
RoundNumber
'
]:
events
.
append
(
schedule
.
get_event_by_round
(
raceIndex
))
return
events
# ===== Weather =====
def
fetchWeather
(
self
,
event
:
Event
|
SessionIdentifier
|
list
[
Event
]
|
list
[
SessionIdentifier
]):
"""
Fetch session weather from the wikipedia entry for the specified event(s).
:param event: The event or identifier for any session of the event to fetch weather for. Alternatively a list of
these.
:return: Weather conditions as string, or a list of such strings if a list is provided.
"""
# Recursive call if list provided
if
isinstance
(
event
,
list
):
weatherEntries
:
list
[
string
]
=
[]
for
e
in
event
:
weatherEntries
.
append
(
self
.
fetchWeather
(
e
))
return
weatherEntries
# Convert from SessionIdentifier to Event if needed
if
isinstance
(
event
,
SessionIdentifier
):
event
=
self
.
importEvent
(
event
.
year
,
event
.
event
)
# Fetch weather
wikiHtml
=
self
.
__importWikiHtml
(
event
)
analyser
=
DataAnalyser
()
weather
=
analyser
.
extractWeatherFromHtml
(
wikiHtml
)
return
weather
def
__importWikiHtml
(
self
,
event
:
Event
):
"""
Fetch the HTML contents of the wikipedia page for the event given.
:param event: Event whose wikipedia page to fetch.
:return: HTML content of the wikipedia page as a string.
"""
apiRootUrl
:
string
=
"
https://en.wikipedia.org/wiki/
"
grandPrixName
:
string
=
f
"
{
event
.
year
}
{
event
[
"
EventName
"
]
}
"
uri
:
string
=
re
.
sub
(
"
"
,
"
_
"
,
grandPrixName
)
url
:
string
=
f
"
{
apiRootUrl
}{
uri
}
"
response
=
requests
.
get
(
url
)
if
not
response
.
ok
:
raise
ConnectionError
(
f
"
Could not fetch wikipedia article with URL
{
url
}
"
)
return
response
.
text
# URL example: https://en.wikipedia.org/w/api.php?action=query&titles=2024_S%C3%A3o_Paulo_Grand_Prix&prop=extracts&format=json&exintro=1
# ===== Other =====
def
__isInFuture
(
self
,
year
:
int
):
currentYear
=
datetime
.
now
().
year
return
year
>
currentYear
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment