← All projects

P—05 · Case study

Fencing results reader

For the French Fencing Federation, a web tool that reads a competition’s raw export and turns it into pools, bouts, rankings and stats, ready to share with coaches.

RoleWeb developer (internship)
ClientFrench Fencing Federation (FFE)
TimelineJun – Jul 2024 · Paris
StackPHP · SimpleXML · HTML/CSS
Code on GitHub ↗ Requirements spec (French, PDF) ↗
01 — Context

After every competition: Excel.

At the end of a competition, the refereeing software produces an XML file with everything in it: pools, every bout, the direct-elimination brackets, the final ranking, the referees.

The catch is that nobody reads XML. Staff opened the file by hand to work out who beat whom, copied the scores into Excel and rebuilt the rankings before sending them to coaches. Every competition meant starting from scratch, and it depended on whoever happened to be free that weekend.

02 — The ask

Fast, reliable, usable by non-developers.

Before writing any code, I wrote a requirements spec describing every page, the data it shows and how navigation works. In practice, I was the product manager before I was the developer.

PageContent
index.phpCompetition name, venue, date, format (pools → direct elimination).
inscrits.phpRegistered fencers: name, club, category, weapon, with search.
arbitre.phpReferees assigned to the event, with club and level.
poules.phpEvery pool and every bout: touches scored and received, wins, referee.
classement_f.phpFinal ranking, medals, and the round each fencer reached.
match.phpDetailed view of a single bout for review with the coach.
03 — Architecture

One file in, pages out.

The key decision: no database. Everything is computed in memory from the XML on each load. For a new competition, you swap the file and the site is up to date, with nothing to reprogram or migrate.

InputXML export

Refereeing software (e.g. lille.xml)

ProcessingPHP + SimpleXML

Extraction, stats computation

OutputHTML pages

One URL per view, easy to share

04 — The code

Reading a pool.

A simplified excerpt from poules.php: load the export, loop over each pool, then over each bout and its score. The same pattern drives the rankings, referees and registrations pages.

poules.phpPHP
// Load the competition data
$xml = simplexml_load_file("lille.xml");
$pools = [];

foreach ($xml->Poule as $poule) {
    $num = (string) $poule['Num'];
    $pools[$num] = ["referee" => (string) $poule['Arbitre'], "matches" => []];

    foreach ($poule->Match as $m) {
        $pools[$num]["matches"][] = [
            "a"  => (string) $m->TireurA['Nom'],
            "b"  => (string) $m->TireurB['Nom'],
            "sa" => (int) $m['ScoreA'],
            "sb" => (int) $m['ScoreB'],
        ];
    }
}
// … then render each pool as an HTML table
05 — Iteration

Demo, feedback, version two.

I demoed the tool live to the federation lead. Most of the feedback was about which metrics actually matter to a coach, so I reworked the stats and the layout accordingly.

The spec also laid out future work: tracking cards per fencer, referee stats, and flagging upsets (a low seed beating a favorite).

06 — Outcome

Minutes instead of hours.

Minutesto produce a recap, instead of rebuilding it by hand
1 versionof the results, the same for every coach
0 database: dropping in the XML is enough

Above all, I learned to turn “we want stats” into metrics you can actually compute, and to present information the way people need it in the field.