Front end

User Interface
Lab 5 - Transforming raw data into actionable player insights
Author

Ludovic Deneuville

Before you start

This tutorial combines explanations and code phases. The explanations should not take precedence over those of your teacher.

NoteConcepts covered
  • Front-end development
  • Navigation between pages
  • Connection to the Back End
  • Vibe coding

Create your branch

For each practical session, the teacher provides a starting branch: tp<N>-start.

You will have to create a personal branch: <username>-tp<N> (e.g. camille-tp2) and work on your own branch.

To start with a clean and up-to-date codebase:

Then use the standard Git cycle: add, commit, push after each part.

1 The goal

From the beginning, we’ve focused solely on back-end development. Today, we’re going to focus on front-end development.

The aim isn’t to turn you into Streamlit experts, but to use fairly simple features to create a user-friendly interface.

Last time, we created an endpoint to retrieve a player’s games.

Let’s use it to create a new page that displays some stats for each player.

Important

Feel free to:

  • use streamlit documentation
  • see existing pages in the project

You can use LLMs (Codestral, etc.) to assist your development. However, do not simply copy-paste. Your role is to act as an architect: define the requirements, guide the AI through the implementation, and rigorously verify the logic.

2 Play Dice

Let’s start with something easy : a page for playing dice

Before, we only had one type of game, but that’s no longer the case.

    • Also amend the link to this page

The page for playing dice will look very similar.

    • update game_mode, do you still need a choice parameter?

3 Player’s page

Currently, your application displays a list of players, but there is no way to “drill down” into a specific player’s profile. We need to implement Contextual Navigation.

We will create a new page Player stats displaying for a specific player, informations and game history.

3.1 Player’s information

Let’s start by retrieving and then displaying the player’s details.

The page url will be something like http://<my-frontend-url>/player_stats?id_player=4.

    • Check the response
    • username in a st.subheader element
    • use st.columns to create 2 columns
    • col1: elo in a st.metric
    • col2: use st.write to display its email, and st.checkbox if he is a Pokemon’s fan

3.2 Match History Retrieval

Below you will add a table containing the Game history.

    • Check the response
    • if no game has been played, display it

The next step is to display a table using the JSON data sent by the API.

Mode Opponent Result
dice maurice (1000) Loss
dice maurice (1000) Draw
dice maurice (1000) Win
coinflip maurice (1000) Win

3.3 Contextual Navigation

You could navigate to the previous page using its URL, but it would be better to have a button that takes you there directly.

We will add one to the players’ list.

In file src/pages/list_players.py you have a dataframe:

    • for example: /player_stats?id_player=4

Now let’s use config st.column_config.LinkColumn to generate a link:

    • For your first attempt, use LinkColumn without any argument
    • st.column_config.LinkColumn()

You can check this by clicking on the link to see if it takes you to the correct page.

    • label="Stats", display_text="📊"

4 To go further

Bonus

4.1 Win/Loss Aggregation

Displaying a list of games is helpful, but a professional dashboard provides high-level KPIs (Key Performance Indicators). We need to calculate the player’s win/loss record.

The Problem: The client (Frontend) should not perform mathematical calculations on a list of games. Doing so increases bandwidth usage and violates the principle of Separation of Concerns.

The Solution: The Service must perform the aggregation and return a simplified summary.

    • It must return a dictionary containing the count of wins, losses, and draws

End of the Lab

Important

When you have finished coding, don’t forget to:

    • If your service is terminated, all unpushed code is lost…
    • to free up reserved resources