Scaffolding the Olympic Head-to-Head Simulator

For the upcoming Olympic Games in Rio we decided to use the Triathlon API to build an application so users could quickly compare the performances of any two athletes in the start lists.

In this article we will introduce the application that was developed (in under a day) in order to demonstrate the various capabilities of the API and to provide an example of the API calls that it uses.

1061

Olympic Head-to-Head Matchup Simulator

Extracting Start Lists

To begin we need to know the start lists of the different programs in order to populate the corresponding dropdowns so users may choose which athletes to compare.

To get to the program information we first need to extract the event_id of the Rio Olympic Games. The simplest method is to use the Search API and we can use the query of Rio 2016 which returns the 2016 Rio de Janerio Olympic Games as the first result with the event_id of 100636.

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/search/events?query=2016%20rio"

We now use the event_id to find a listing of the programs at the Rio Games.

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/events/100636/programs"

This yields the following result:

{
    "code": 200,
    "status": "success",
    "data": [
        {
            "prog_id": 305290,
            "event_id": 100636,
            "prog_name": "Elite Men",
            "prog_date": "2016-08-18",
            "prog_time": "11:00:00",
            "prog_notes": null,
            "results": false,
            "team": false
        },
        {
            "prog_id": 305291,
            "event_id": 100636,
            "prog_name": "Elite Women",
            "prog_date": "2016-08-20",
            "prog_time": "11:00:00",
            "prog_notes": null,
            "results": false,
            "team": false
        }
    ]
}

So our application will use the start lists from the prog_id of 305290 for the Elite Men and 305291 for the Elite Women. To extract the start list we simply substitute the prog_id into the Program Entries API call:

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/events/100636/programs/305290/entries"

The result of this will yield an array of athlete objects which contains the necessary information required to populate our dropdowns to choose the athletes competing in the race. Note that we only need to execute this once so any results from this response may be cached and only needs to be rerun in the case that the start list is changed prior to the event.

Extracting Profile Data

In extracting the start lists we have the athlete_id for all athletes in the corresponding program which is the unique value we will use to obtain all the remaining info included in the simulator.

The Retrieve Athlete Information method contains the full profile of the athlete that we will use to extract the primary profile information such as the profile image, representing country, ranking information and summary fields. Using athlete Helen Jenkins (5573) as an example the following query is made to extract her profile:

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/athletes/5573"

As well as the basic profile information the result also contains a stats object that details the information required for the 'Career Stats' section of the simulator.

"stats": {
      "race_starts": 69,
      "race_finishes": 66,
      "finish_percentage": 96,
      "race_wins": 8,
      "race_podiums": 29,
      "race_podium_percentage": 42
}

Olympic Head-to-Head Stats

The above stats block includes all ITU races that Helen Jenkins has competed in and so to retrieve the specific Olympic stats we use the Athlete Statistics method using the event_id parameter to limit only to Olympic Games. As there are only 4 prior Games we simply use the Search API to extract the event_id of each and pass this pipe delimited list of event_ids to the athlete statistics method

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/athletes/5573/stats?event_id=4740|4529|4998|60952"

This will return a similar stats data object which contains only those starts, finishes, wins and podiums related to the prior Olympic Games.

To obtain all the Olympic results for an athlete we will use the Athlete Results method again limiting the event_ids to only Olympic Games results which will return an array of result objects.

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/athletes/5573/results?event_id=4740|4529|4998|60952"

WTS Head-to-Head Stats

🚧

Make use of a cache to improve the performance of your application

Most of the API calls made can benefit from caching as the information changes infrequently. In particular the matchups endpoint is resource intensive (and correspondingly slow) and will benefit the most from caching any requests to it.

To extract the WTS head-to-head matchups we turn to the dedicated Matchups Endpoint of the Statistics API passing in the relevant athlete_ids (in the following example Helen Jenkins and Gwen Jorgenson). The result of this API call will return the number of times the athletes have met in WTS races, basic WTS race stats for both athletes and a list of all times the athletes have competed together (and corresponding results), from which we may derive the latest head-to_head result.

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/statistics/matchups?athletes=athlete.id,in,40887,5573"

The only missing pieces of information are the WTS best finish and the WTS best 10km run time which are not currently included in the matchup response. To obtain both we use the Results method of the Statistics API. For the best finish we simply find the minimum position for an athlete from all WTS results:

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/statistics/results?analysis=minimum&target_property=position&filters=athlete.id,eq,5573"

Finally, to extract the best 10km run time we find the minimum of the splits.run property specifying filters for a Standard distance format and apply a sanity check that the run time must be greater than 1600 seconds (or about 26 minutes). This check removes events such as 2013 Kitzbuehel which used a different format despite being classified as a Standard distance.

curl --header "apikey: YOUR_APP_KEY" "https://api.triathlon.org/v1/statistics/results?collection=results&analysis=minimum&target_property=splits.run&filters=athlete.id,eq,5573|format,eq,Standard|splits.run,gt,1600"

This will yield the following result for Helen Jenkins with the result being returned in seconds. This may be easily converted to a time such as in PHP using a simple function such as gmdate("i:s", $run_time)

{
   "code":200,
   "status":"success",
   "data":{
      "result":1981
   }
}

Whilst there are many approaches to extracting the information on the Head-to-Head simulator this post details the methodology we used to develop the dynamic tool. To test any of the queries or to build your own application simply sign up for a free API key to access the entrire Triathlon API.