arre99 commited on
Commit
44e58a6
·
1 Parent(s): b139634

added constructors standings and tidied up the UI for driver standings

Browse files
Files changed (4) hide show
  1. api_playground.ipynb +201 -0
  2. app.py +18 -19
  3. tools.py +22 -1
  4. utils/constants.py +14 -1
api_playground.ipynb CHANGED
@@ -385,6 +385,207 @@
385
  "driver_standings.head(2)"
386
  ]
387
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  {
389
  "cell_type": "code",
390
  "execution_count": 2,
 
385
  "driver_standings.head(2)"
386
  ]
387
  },
388
+ {
389
+ "cell_type": "code",
390
+ "execution_count": 33,
391
+ "id": "feeb4592",
392
+ "metadata": {},
393
+ "outputs": [
394
+ {
395
+ "data": {
396
+ "text/html": [
397
+ "<div>\n",
398
+ "<style scoped>\n",
399
+ " .dataframe tbody tr th:only-of-type {\n",
400
+ " vertical-align: middle;\n",
401
+ " }\n",
402
+ "\n",
403
+ " .dataframe tbody tr th {\n",
404
+ " vertical-align: top;\n",
405
+ " }\n",
406
+ "\n",
407
+ " .dataframe thead th {\n",
408
+ " text-align: right;\n",
409
+ " }\n",
410
+ "</style>\n",
411
+ "<table border=\"1\" class=\"dataframe\">\n",
412
+ " <thead>\n",
413
+ " <tr style=\"text-align: right;\">\n",
414
+ " <th></th>\n",
415
+ " <th>position</th>\n",
416
+ " <th>positionText</th>\n",
417
+ " <th>points</th>\n",
418
+ " <th>wins</th>\n",
419
+ " <th>constructorId</th>\n",
420
+ " <th>constructorUrl</th>\n",
421
+ " <th>constructorName</th>\n",
422
+ " <th>constructorNationality</th>\n",
423
+ " </tr>\n",
424
+ " </thead>\n",
425
+ " <tbody>\n",
426
+ " <tr>\n",
427
+ " <th>0</th>\n",
428
+ " <td>1</td>\n",
429
+ " <td>1</td>\n",
430
+ " <td>362.0</td>\n",
431
+ " <td>7</td>\n",
432
+ " <td>mclaren</td>\n",
433
+ " <td>http://en.wikipedia.org/wiki/McLaren</td>\n",
434
+ " <td>McLaren</td>\n",
435
+ " <td>British</td>\n",
436
+ " </tr>\n",
437
+ " <tr>\n",
438
+ " <th>1</th>\n",
439
+ " <td>2</td>\n",
440
+ " <td>2</td>\n",
441
+ " <td>165.0</td>\n",
442
+ " <td>0</td>\n",
443
+ " <td>ferrari</td>\n",
444
+ " <td>http://en.wikipedia.org/wiki/Scuderia_Ferrari</td>\n",
445
+ " <td>Ferrari</td>\n",
446
+ " <td>Italian</td>\n",
447
+ " </tr>\n",
448
+ " <tr>\n",
449
+ " <th>2</th>\n",
450
+ " <td>3</td>\n",
451
+ " <td>3</td>\n",
452
+ " <td>159.0</td>\n",
453
+ " <td>0</td>\n",
454
+ " <td>mercedes</td>\n",
455
+ " <td>http://en.wikipedia.org/wiki/Mercedes-Benz_in_...</td>\n",
456
+ " <td>Mercedes</td>\n",
457
+ " <td>German</td>\n",
458
+ " </tr>\n",
459
+ " <tr>\n",
460
+ " <th>3</th>\n",
461
+ " <td>4</td>\n",
462
+ " <td>4</td>\n",
463
+ " <td>144.0</td>\n",
464
+ " <td>2</td>\n",
465
+ " <td>red_bull</td>\n",
466
+ " <td>http://en.wikipedia.org/wiki/Red_Bull_Racing</td>\n",
467
+ " <td>Red Bull</td>\n",
468
+ " <td>Austrian</td>\n",
469
+ " </tr>\n",
470
+ " <tr>\n",
471
+ " <th>4</th>\n",
472
+ " <td>5</td>\n",
473
+ " <td>5</td>\n",
474
+ " <td>54.0</td>\n",
475
+ " <td>0</td>\n",
476
+ " <td>williams</td>\n",
477
+ " <td>http://en.wikipedia.org/wiki/Williams_Grand_Pr...</td>\n",
478
+ " <td>Williams</td>\n",
479
+ " <td>British</td>\n",
480
+ " </tr>\n",
481
+ " <tr>\n",
482
+ " <th>5</th>\n",
483
+ " <td>6</td>\n",
484
+ " <td>6</td>\n",
485
+ " <td>28.0</td>\n",
486
+ " <td>0</td>\n",
487
+ " <td>rb</td>\n",
488
+ " <td>http://en.wikipedia.org/wiki/RB_Formula_One_Team</td>\n",
489
+ " <td>RB F1 Team</td>\n",
490
+ " <td>Italian</td>\n",
491
+ " </tr>\n",
492
+ " <tr>\n",
493
+ " <th>6</th>\n",
494
+ " <td>7</td>\n",
495
+ " <td>7</td>\n",
496
+ " <td>26.0</td>\n",
497
+ " <td>0</td>\n",
498
+ " <td>haas</td>\n",
499
+ " <td>http://en.wikipedia.org/wiki/Haas_F1_Team</td>\n",
500
+ " <td>Haas F1 Team</td>\n",
501
+ " <td>American</td>\n",
502
+ " </tr>\n",
503
+ " <tr>\n",
504
+ " <th>7</th>\n",
505
+ " <td>8</td>\n",
506
+ " <td>8</td>\n",
507
+ " <td>16.0</td>\n",
508
+ " <td>0</td>\n",
509
+ " <td>sauber</td>\n",
510
+ " <td>http://en.wikipedia.org/wiki/Sauber_Motorsport</td>\n",
511
+ " <td>Sauber</td>\n",
512
+ " <td>Swiss</td>\n",
513
+ " </tr>\n",
514
+ " <tr>\n",
515
+ " <th>8</th>\n",
516
+ " <td>9</td>\n",
517
+ " <td>9</td>\n",
518
+ " <td>16.0</td>\n",
519
+ " <td>0</td>\n",
520
+ " <td>aston_martin</td>\n",
521
+ " <td>http://en.wikipedia.org/wiki/Aston_Martin_in_F...</td>\n",
522
+ " <td>Aston Martin</td>\n",
523
+ " <td>British</td>\n",
524
+ " </tr>\n",
525
+ " <tr>\n",
526
+ " <th>9</th>\n",
527
+ " <td>10</td>\n",
528
+ " <td>10</td>\n",
529
+ " <td>11.0</td>\n",
530
+ " <td>0</td>\n",
531
+ " <td>alpine</td>\n",
532
+ " <td>http://en.wikipedia.org/wiki/Alpine_F1_Team</td>\n",
533
+ " <td>Alpine F1 Team</td>\n",
534
+ " <td>French</td>\n",
535
+ " </tr>\n",
536
+ " </tbody>\n",
537
+ "</table>\n",
538
+ "</div>"
539
+ ],
540
+ "text/plain": [
541
+ " position positionText points wins constructorId \\\n",
542
+ "0 1 1 362.0 7 mclaren \n",
543
+ "1 2 2 165.0 0 ferrari \n",
544
+ "2 3 3 159.0 0 mercedes \n",
545
+ "3 4 4 144.0 2 red_bull \n",
546
+ "4 5 5 54.0 0 williams \n",
547
+ "5 6 6 28.0 0 rb \n",
548
+ "6 7 7 26.0 0 haas \n",
549
+ "7 8 8 16.0 0 sauber \n",
550
+ "8 9 9 16.0 0 aston_martin \n",
551
+ "9 10 10 11.0 0 alpine \n",
552
+ "\n",
553
+ " constructorUrl constructorName \\\n",
554
+ "0 http://en.wikipedia.org/wiki/McLaren McLaren \n",
555
+ "1 http://en.wikipedia.org/wiki/Scuderia_Ferrari Ferrari \n",
556
+ "2 http://en.wikipedia.org/wiki/Mercedes-Benz_in_... Mercedes \n",
557
+ "3 http://en.wikipedia.org/wiki/Red_Bull_Racing Red Bull \n",
558
+ "4 http://en.wikipedia.org/wiki/Williams_Grand_Pr... Williams \n",
559
+ "5 http://en.wikipedia.org/wiki/RB_Formula_One_Team RB F1 Team \n",
560
+ "6 http://en.wikipedia.org/wiki/Haas_F1_Team Haas F1 Team \n",
561
+ "7 http://en.wikipedia.org/wiki/Sauber_Motorsport Sauber \n",
562
+ "8 http://en.wikipedia.org/wiki/Aston_Martin_in_F... Aston Martin \n",
563
+ "9 http://en.wikipedia.org/wiki/Alpine_F1_Team Alpine F1 Team \n",
564
+ "\n",
565
+ " constructorNationality \n",
566
+ "0 British \n",
567
+ "1 Italian \n",
568
+ "2 German \n",
569
+ "3 Austrian \n",
570
+ "4 British \n",
571
+ "5 Italian \n",
572
+ "6 American \n",
573
+ "7 Swiss \n",
574
+ "8 British \n",
575
+ "9 French "
576
+ ]
577
+ },
578
+ "execution_count": 33,
579
+ "metadata": {},
580
+ "output_type": "execute_result"
581
+ }
582
+ ],
583
+ "source": [
584
+ "ergastandings = fastf1.ergast.Ergast()\n",
585
+ "constructor_standings = ergastandings.get_constructor_standings(2025).content[0]\n",
586
+ "constructor_standings.head(10)"
587
+ ]
588
+ },
589
  {
590
  "cell_type": "code",
591
  "execution_count": 2,
app.py CHANGED
@@ -1,35 +1,33 @@
1
- import json
2
- import random
3
- import datetime
4
  import gradio as gr
5
 
6
  # Local modules
7
  import tools
8
  from utils.constants import (
9
- AVAILABLE_SESSION_TYPES,
10
- DROPDOWN_SESSION_TYPES
 
11
  )
12
 
13
- # Variables
14
- CURRENT_YEAR = datetime.datetime.now().year
15
-
16
-
17
- # Load in driver names
18
- with open("assets/driver_names.json") as f:
19
- driver_names = json.load(f)["drivers"]
20
- with open("assets/constructor_details.json") as f:
21
- constructor_names = [constructor["constructor"] for constructor in json.load(f)["constructors"]]
22
-
23
-
24
  iface_driver_championship_standings = gr.Interface(
25
  fn=tools.driver_championship_standings,
26
  inputs=[
27
  gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
28
- gr.Dropdown(driver_names)
29
  ],
30
  outputs="text",
31
  title="Driver Championship Standings",
32
- description="Get the championship standings for the given driver"
 
 
 
 
 
 
 
 
 
 
 
33
  )
34
 
35
  iface_event_info = gr.Interface(
@@ -60,7 +58,7 @@ iface_track_visualization = gr.Interface(
60
  gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
61
  gr.Textbox(label="Grand Prix", placeholder="Ex: Monaco", info="The name of the GP/country/location (Fuzzy matching supported)"),
62
  gr.Radio(["speed", "corners", "gear"], label="Visualization type", value="speed"),
63
- gr.Dropdown(driver_names)
64
  ],
65
  outputs="image",
66
  title="Track Visualizations",
@@ -70,6 +68,7 @@ iface_track_visualization = gr.Interface(
70
 
71
  named_interfaces = {
72
  "Driver Championship Standings": iface_driver_championship_standings,
 
73
  "Event Info": iface_event_info,
74
  "Season Calendar": iface_season_calendar,
75
  "Track Visualizations": iface_track_visualization
 
 
 
 
1
  import gradio as gr
2
 
3
  # Local modules
4
  import tools
5
  from utils.constants import (
6
+ DRIVER_NAMES,
7
+ CONSTRUCTOR_NAMES,
8
+ CURRENT_YEAR
9
  )
10
 
 
 
 
 
 
 
 
 
 
 
 
11
  iface_driver_championship_standings = gr.Interface(
12
  fn=tools.driver_championship_standings,
13
  inputs=[
14
  gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
15
+ gr.Dropdown(label="Driver", choices=DRIVER_NAMES)
16
  ],
17
  outputs="text",
18
  title="Driver Championship Standings",
19
+ description="Get the driver championship standings"
20
+ )
21
+
22
+ iface_constructor_championship_standings = gr.Interface(
23
+ fn=tools.constructor_championship_standings,
24
+ inputs=[
25
+ gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
26
+ gr.Dropdown(label="Constructor", choices=CONSTRUCTOR_NAMES)
27
+ ],
28
+ outputs="text",
29
+ title="Constructor Championship Standings",
30
+ description="Get the constructor championship standings"
31
  )
32
 
33
  iface_event_info = gr.Interface(
 
58
  gr.Number(label="Calendar year", value=CURRENT_YEAR, minimum=1950, maximum=CURRENT_YEAR),
59
  gr.Textbox(label="Grand Prix", placeholder="Ex: Monaco", info="The name of the GP/country/location (Fuzzy matching supported)"),
60
  gr.Radio(["speed", "corners", "gear"], label="Visualization type", value="speed"),
61
+ gr.Dropdown(DRIVER_NAMES)
62
  ],
63
  outputs="image",
64
  title="Track Visualizations",
 
68
 
69
  named_interfaces = {
70
  "Driver Championship Standings": iface_driver_championship_standings,
71
+ "Constructor Championship Standings": iface_constructor_championship_standings,
72
  "Event Info": iface_event_info,
73
  "Season Calendar": iface_season_calendar,
74
  "Track Visualizations": iface_track_visualization
tools.py CHANGED
@@ -73,7 +73,28 @@ def driver_championship_standings(year: int, driver_name: str) -> str:
73
 
74
 
75
  def constructor_championship_standings(year: int, constructor_name: str) -> str:
76
- pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
 
78
 
79
 
 
73
 
74
 
75
  def constructor_championship_standings(year: int, constructor_name: str) -> str:
76
+
77
+ team_mapping = {
78
+ "McLaren": "McLaren",
79
+ "Ferrari": "Ferrari",
80
+ "Red Bull Racing": "Red Bull",
81
+ "Mercedes": "Mercedes",
82
+ "Aston Martin": "Aston Martin",
83
+ "Alpine": "Alpine F1 Team",
84
+ "Haas": "Haas F1 Team",
85
+ "Racing Bulls": "RB F1 Team",
86
+ "Williams": "Williams",
87
+ "Kick Sauber": "Sauber"
88
+ }
89
+
90
+ ergast = fastf1.ergast.Ergast()
91
+ constructor_standings = ergast.get_constructor_standings(year).content[0]
92
+ constructor_standing = constructor_standings[["position", "points", "wins", "constructorName"]].reset_index(drop=True)
93
+ mapped_name = team_mapping[constructor_name]
94
+ constructor_standing = constructor_standing[constructor_standing["constructorName"] == mapped_name]
95
+ suffix = "st" if constructor_standing['position'].iloc[0] == 1 else "nd" if constructor_standing['position'].iloc[0] == 2 else "rd" if constructor_standing['position'].iloc[0] == 3 else "th"
96
+ standings_string = f"{constructor_name} are {constructor_standing['position'].iloc[0]}{suffix} with {constructor_standing['points'].iloc[0]} points and {constructor_standing['wins'].iloc[0]} wins"
97
+ return standings_string
98
 
99
 
100
 
utils/constants.py CHANGED
@@ -1,3 +1,5 @@
 
 
1
 
2
  AVAILABLE_SESSION_TYPES = [
3
  "fp1", "fp2", "fp3", "q", "s", "ss", "sq", "r",
@@ -8,4 +10,15 @@ AVAILABLE_SESSION_TYPES = [
8
  DROPDOWN_SESSION_TYPES = [
9
  "practice 1", "practice 2", "practice 3", "sprint",
10
  "sprint shootout", "sprint qualifying", "qualifying", "race"
11
- ]
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ import datetime
3
 
4
  AVAILABLE_SESSION_TYPES = [
5
  "fp1", "fp2", "fp3", "q", "s", "ss", "sq", "r",
 
10
  DROPDOWN_SESSION_TYPES = [
11
  "practice 1", "practice 2", "practice 3", "sprint",
12
  "sprint shootout", "sprint qualifying", "qualifying", "race"
13
+ ]
14
+
15
+ # Load in driver names
16
+ with open("assets/driver_names.json") as f:
17
+ DRIVER_NAMES: list[str] = json.load(f)["drivers"]
18
+
19
+ # Load in constructor names
20
+ with open("assets/constructors.json") as f:
21
+ CONSTRUCTOR_NAMES: list[str] = json.load(f)["constructors"]
22
+
23
+ # Variables
24
+ CURRENT_YEAR = datetime.datetime.now().year