9
9
10
10
class RacingStats :
11
11
def __init__ (self , using = "default" ):
12
+ """Initialize RacingStats with database connection.
13
+
14
+ Args:
15
+ using (str, optional): Database connection to use. Defaults to "default".
16
+ """
12
17
self .using = using
13
18
pass
14
19
15
20
def combos (self , type = "" , ** kwargs ):
21
+ """Convenience method that calls driver_combos().
22
+
23
+ Args:
24
+ type (str, optional): Type of racing to filter for ("circuit" or "rally"). Defaults to "".
25
+ **kwargs: Additional arguments passed to driver_combos().
26
+
27
+ Returns:
28
+ QuerySet: Results from driver_combos().
29
+ """
16
30
return self .driver_combos (type = type , ** kwargs )
17
31
18
32
def driver_combos (self , driver = None , range = 30 , type = "circuit" , ** kwargs ):
33
+ """Get combinations of game/track/car with statistics.
34
+
35
+ Args:
36
+ driver (str, optional): Filter by driver name. Defaults to None.
37
+ range (int, optional): Number of days to look back. Defaults to 30.
38
+ type (str, optional): Type of racing to filter for:
39
+ - "circuit": Only circuit racing games
40
+ - "rally": Only rally games
41
+ - "": All games
42
+ **kwargs: Additional filter arguments
43
+
44
+ Returns:
45
+ QuerySet: Contains for each combo:
46
+ - session__game__name: Game name
47
+ - track__name: Track name ("Multiple" for rally)
48
+ - car__name: Car name
49
+ - lap_count: Total number of laps
50
+ - valid_lap_count: Number of valid laps
51
+ - latest_lap_end: Most recent lap end time
52
+
53
+ Example:
54
+ >>> stats = RacingStats()
55
+ >>> # Get circuit combos for last 7 days
56
+ >>> circuit_combos = stats.driver_combos(range=7, type="circuit")
57
+ >>> # Get rally combos for specific driver
58
+ >>> rally_combos = stats.driver_combos(driver="John", type="rally")
59
+ """
19
60
filter = {}
20
61
if driver is not None :
21
62
filter ["session__driver__name" ] = driver
@@ -55,11 +96,48 @@ def driver_combos(self, driver=None, range=30, type="circuit", **kwargs):
55
96
return laps
56
97
57
98
def known_combos_list (self , game = None , track = None , car = None , ** kwargs ):
99
+ """Generator yielding tuples of known game/car/track combinations.
100
+
101
+ Args:
102
+ game (str, optional): Filter by game name. Defaults to None.
103
+ track (str, optional): Filter by track name. Defaults to None.
104
+ car (str, optional): Filter by car name. Defaults to None.
105
+ **kwargs: Additional filter arguments
106
+
107
+ Yields:
108
+ tuple: (game_name, car_name, track_name, lap_count)
109
+
110
+ Example:
111
+ >>> stats = RacingStats()
112
+ >>> # List all AC combos
113
+ >>> for game, car, track, count in stats.known_combos_list(game="Assetto Corsa"):
114
+ ... print(f"{car} on {track}: {count} laps")
115
+ """
58
116
laps = self .known_combos (game , track , car , ** kwargs )
59
117
for row in laps :
60
118
yield row ["track__game__name" ], row ["car__name" ], row ["track__name" ], row ["count" ]
61
119
62
120
def known_combos (self , game = None , track = None , car = None , ** kwargs ):
121
+ """Get known combinations of game/car/track with valid lap counts.
122
+
123
+ Args:
124
+ game (str, optional): Filter by game name. Defaults to None.
125
+ track (str, optional): Filter by track name. Defaults to None.
126
+ car (str, optional): Filter by car name. Defaults to None.
127
+ **kwargs: Additional filter arguments
128
+
129
+ Returns:
130
+ QuerySet: Contains for each combo:
131
+ - track__name: Track name
132
+ - car__name: Car name
133
+ - track__game__name: Game name
134
+ - count: Number of valid laps
135
+
136
+ Example:
137
+ >>> stats = RacingStats()
138
+ >>> # Get all GT3 car combos
139
+ >>> gt3_combos = stats.known_combos(car="GT3")
140
+ """
63
141
filter = {}
64
142
if game :
65
143
filter ["track__game__name" ] = game
@@ -77,6 +155,25 @@ def known_combos(self, game=None, track=None, car=None, **kwargs):
77
155
return laps
78
156
79
157
def fast_lap_values (self , game = None , track = None , car = None , ** kwargs ):
158
+ """Get combinations that have fast lap records.
159
+
160
+ Args:
161
+ game (str, optional): Filter by game name. Defaults to None.
162
+ track (str, optional): Filter by track name. Defaults to None.
163
+ car (str, optional): Filter by car name. Defaults to None.
164
+ **kwargs: Additional filter arguments
165
+
166
+ Returns:
167
+ QuerySet: Contains for each combo:
168
+ - track__name: Track name
169
+ - car__name: Car name
170
+ - game__name: Game name
171
+
172
+ Example:
173
+ >>> stats = RacingStats()
174
+ >>> # Get all fast lap combos for Spa
175
+ >>> spa_records = stats.fast_lap_values(track="Spa")
176
+ """
80
177
filter = {}
81
178
if game :
82
179
filter ["game__name" ] = game
@@ -97,6 +194,24 @@ def fast_lap_values(self, game=None, track=None, car=None, **kwargs):
97
194
# yield row["track__game__name"], row["car__name"], row["track__name"], row["count"]
98
195
99
196
def fast_laps (self , game = None , track = None , car = None , ** kwargs ):
197
+ """Get FastLap records for a specific game/track/car combination.
198
+
199
+ Args:
200
+ game (str): Game name to filter by
201
+ track (str): Track name to filter by
202
+ car (str): Car name to filter by
203
+ **kwargs: Additional filter arguments
204
+
205
+ Returns:
206
+ QuerySet[FastLap]: Matching FastLap records
207
+
208
+ Example:
209
+ >>> stats = RacingStats()
210
+ >>> # Get fastest laps for GT3 cars at Spa in AC
211
+ >>> records = stats.fast_laps(game="Assetto Corsa",
212
+ ... track="Spa",
213
+ ... car="GT3")
214
+ """
100
215
filter = {}
101
216
filter ["game__name" ] = game
102
217
filter ["track__name" ] = track
@@ -106,6 +221,24 @@ def fast_laps(self, game=None, track=None, car=None, **kwargs):
106
221
return laps
107
222
108
223
def laps (self , game = None , track = None , car = None , driver = None , valid = None , ** kwargs ):
224
+ """Get lap records filtered by various criteria.
225
+
226
+ Args:
227
+ game (str, optional): Filter by game name. Defaults to None.
228
+ track (str, optional): Filter by track name. Defaults to None.
229
+ car (str, optional): Filter by car name. Defaults to None.
230
+ driver (str, optional): Filter by driver name. Defaults to None.
231
+ valid (bool, optional): Filter by lap validity. Defaults to None.
232
+ **kwargs: Additional filter arguments
233
+
234
+ Returns:
235
+ QuerySet[Lap]: Matching Lap records, ordered by time
236
+
237
+ Example:
238
+ >>> stats = RacingStats()
239
+ >>> # Get all valid laps by a driver
240
+ >>> driver_laps = stats.laps(driver="John", valid=True)
241
+ """
109
242
filter = {}
110
243
if game :
111
244
filter ["track__game__name" ] = game
@@ -130,6 +263,26 @@ def laps(self, game=None, track=None, car=None, driver=None, valid=None, **kwarg
130
263
# yield lap
131
264
132
265
def sessions (self , game = None , track = None , car = None , driver = None , session_ids = None , ** kwargs ):
266
+ """Get racing sessions filtered by various criteria.
267
+
268
+ Args:
269
+ game (str, optional): Filter by game name. Defaults to None.
270
+ track (str, optional): Filter by track name. Defaults to None.
271
+ car (str, optional): Filter by car name. Defaults to None.
272
+ driver (str, optional): Filter by driver name. Defaults to None.
273
+ session_ids (list, optional): Filter by specific session IDs. Defaults to None.
274
+ **kwargs: Additional filter arguments
275
+
276
+ Returns:
277
+ QuerySet[Session]: Matching Session records, ordered by start time
278
+
279
+ Example:
280
+ >>> stats = RacingStats()
281
+ >>> # Get all sessions for a specific driver
282
+ >>> driver_sessions = stats.sessions(driver="John")
283
+ >>> # Get specific sessions by ID
284
+ >>> specific_sessions = stats.sessions(session_ids=[1,2,3])
285
+ """
133
286
filter = {}
134
287
if game :
135
288
filter ["game__name" ] = game
@@ -148,6 +301,24 @@ def sessions(self, game=None, track=None, car=None, driver=None, session_ids=Non
148
301
return sessions
149
302
150
303
def fast_laps_cursor (self , game = None , track = None , car = None , ** kwargs ):
304
+ """Get lap counts by track and car using direct database cursor.
305
+
306
+ Uses raw SQL for potentially better performance when getting aggregate counts.
307
+
308
+ Args:
309
+ game (str, optional): Filter by game name. Defaults to None.
310
+ track (str, optional): Filter by track name. Defaults to None.
311
+ car (str, optional): Filter by car name. Defaults to None.
312
+ **kwargs: Additional filter arguments
313
+
314
+ Returns:
315
+ list[tuple]: Each tuple contains (count, track_id, car_id)
316
+
317
+ Example:
318
+ >>> stats = RacingStats()
319
+ >>> # Get lap counts for all track/car combos in AC
320
+ >>> counts = stats.fast_laps_cursor(game="Assetto Corsa")
321
+ """
151
322
where = []
152
323
filter_game = None
153
324
if game :
0 commit comments