Added a lot to the doc and I need to sleep
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 21 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 7.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
+152
-1
@@ -1782,7 +1782,158 @@ Ce soucis mets en lumière un principe assez important de l'informatique "Ggarba
|
||||
|
||||
### Affichage des données
|
||||
|
||||
### Prédictions
|
||||
Maintenant que l'on a stocké toutes ces données, il faut en faire quelque chose sinon ca ne sert a rien.
|
||||
|
||||
Afficher les données est techniquement la partie la plus simple du projet. Il faut prendre les données qui nous intéressent de la base de données et des résultats de l'OCR et les afficher sur des composants Windows Forms.
|
||||
|
||||
Il y a deux types d'affichages actuellements mis en place dans le projet sur les trois prévus initialement :
|
||||
|
||||
#### Affichage direct
|
||||
|
||||
L'affichage direct est simplement l'affichage du résultat de l'OCR.
|
||||
|
||||
Par exemple le classement live ainsi que les écarts entre les pilotes sont affichés directement depuis les résultats de l'OCR. Ce ne sont pas forcément des données prises dans la base de donnée.
|
||||
|
||||
Voici un exemple :
|
||||
|
||||
```Csharp
|
||||
for (int driverCount = 0; driverCount < liveData.Count; driverCount++)
|
||||
{
|
||||
DriverData driver = liveData[driverCount];
|
||||
lblDriverName.Text = driver.Name;
|
||||
lblDriverPosition.Text = driver.Position;
|
||||
lblDriverLapTime.Text = Reader.ConvertMsToTime(driver.LapTime);
|
||||
}
|
||||
```
|
||||
|
||||
C'est l'affichage le plus simple et celui qui est le plus soumis à des erreurs. En effet, si un pilote est mal detecté on le verra directement mal s'afficher dans la Form principale.
|
||||
|
||||
C'est également l'affichage le moins intéressant car il ne crée aucune information, il ne fait que remontrer les infos que l'on peut déja voir dans la F1TV
|
||||
|
||||

|
||||
|
||||
#### Affichage calculé
|
||||
|
||||
La encore il y a plusieurs types d'affichages :
|
||||
|
||||
##### Affichage Hybride
|
||||
|
||||
Pour ce qui est des affichages hybrides ce sont des affichages qui vont chercher des informations lives et des informations dans la base de donnée. Ils ne font pas de calculs à proprement parler mais ils affichent plus d'informations que ce que montre la F1TV. Cela veut dire qu'ils représentent un début de plusvalue par rapport à l'alternative qu'est la page DATA de la F1TV.
|
||||
|
||||
Ils ne sont pas beaucoup plus durs à implémenter mais demandent de faire des requêtes à la base de donnée.
|
||||
|
||||
Comme exemple d'affichage hybride on a l'affichage des cinq derniers tours d'un pilote. C'est un affichage qui ne demande aucun calcul mais qui permet deja de se rendre compte de si le pilote est enn train de perdre ou gagner du temps ou si il est constant, ce qui n'est pas possible actuellement avec la F1TV à moins d'avoir une excellente mémoire.
|
||||
|
||||

|
||||
|
||||
Voici un exemmple du type de code necessaire pour afficher ce genre de données:
|
||||
|
||||
```Csharp
|
||||
public List<(int LapTime, int Lap)> GetDriverLaptimes(string driverName,int numberOfLaptimes)
|
||||
{
|
||||
int driverId = GetDriverID(driverName);
|
||||
List<(int LapTime, int Lap)> lapData = new List<(int LapTime, int Lap)>();
|
||||
string selectQuery = "Select LapTime,Lap from Stats WHERE DriverID = @driverID ORDER BY Lap DESC LIMIT @limit";
|
||||
using (var command = new SQLiteCommand(selectQuery, Connection))
|
||||
{
|
||||
command.Parameters.AddWithValue("@driverID", driverId);
|
||||
command.Parameters.AddWithValue("@limit", numberOfLaptimes);
|
||||
|
||||
SQLiteDataReader reader = command.ExecuteReader();
|
||||
while (reader.Read())
|
||||
{
|
||||
int lapTime = reader.GetInt32(0);
|
||||
int lap = reader.GetInt32(1);
|
||||
lapData.Add((lapTime, lap));
|
||||
}
|
||||
}
|
||||
return lapData;
|
||||
}
|
||||
|
||||
public void Display(){
|
||||
List<(int LapTime, int Lap)> lapsInfos = Storage.GetDriverLaptimes(driverName, 5);
|
||||
int id = 0;
|
||||
foreach ((int LapTime, int Lap) lapData in lapsInfos){
|
||||
Labels[id].Text = LapTime;
|
||||
id++;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Note: Le code montré ici n'est pas forcément le code utilisé dans le projet.
|
||||
|
||||
D'une certaine facon les fenêtres de bataille et de dépassements sont aussi des hybrides.
|
||||
|
||||

|
||||
|
||||
Ici ce sont les batailles qui sont représentées. Aucune donnée n'est calculée, c'est litterallement directement les données de la F1TV, mais la nuance est qu'on ne montre que les pilotes qui sont en train de se battre et que on leur assigne une couleur selon à quel point ils sont proches. On a une plus-value sur la F1TV sans pour autant faire de monstres calculs.
|
||||
|
||||
Pour info, les pilotes considèrés comme êtant en train de se battre sont les pilotes à moins de trois secondes les uns des autres et les couleurs sont suivantes :
|
||||
|
||||
- Vert : Dans la zone de DRS (Moins d'une seconde)
|
||||
- Jaune : Plus d'une seconde
|
||||
- Noir : Plus de deux secondes
|
||||
|
||||

|
||||
|
||||
La c'est l'historique des dépassements qui est affiché. On pourrait presque dire que c'est un affichage complêtement calculé car ce ne sont pas des informations disponibles directement sur la F1TV cependant je dirais que cela reste un hybride car il n'y a aucuns calculs. On regarde juste les différences entre l'ancienne position d'un pilote et la nouvelle et on affiche les changements.
|
||||
|
||||
##### Affichage totalement calculé
|
||||
|
||||
L'affichage complêtement calculé est un type d'affichage qui ne montre aucune information trouvée sur la page de la F1TV. C'est le premier affichage à traiter l'information qu'il trouve et il retourne des informations nouvelles. La nuance avec les affichages prédictif est qu'il ne crée pas réellement de l'information, il la déduit.
|
||||
|
||||
Le but est de prendre un certain nombre d'informations trouvées sur la page de la F1TV et de calculer des choses pour faire ressortir des tendances à l'utilisateur. Cependant on reste sur des informations factuelles. Ce sont des infos déduites que techniquement unn humain avec une bonne mémoire et fort en calcul mental pourrait faire. Mais la c'est fait automatiquement pour tous les pilotes et c'est affiché de sorte à faire ressortir les valeurs spéciales.
|
||||
|
||||
Comme c'est un peu plus abstrait, je pense qu'un exemple vaut mieux que 1000 mots.
|
||||
|
||||

|
||||
|
||||
Ci dessus on peut voir un bon exemple. C'est une fenêtre qui montre qui sont les pilotes les plus rapides et les moins rapides et qui montre la différence de temps au tour.
|
||||
|
||||
Cette information est totalement déduite et n'est en aucun cas trouvable sur la F1TV mais elle n'est pas inventée. Elle est simplement calculée.
|
||||
|
||||
La formule est assez simple, je prend les cinq derniers temps au tour de tous les pilotes. Je fais une moyenne qui donne un temps. Et ensuite je trie les pilotes en fonction de ce temps et je n'affiche que les cinq plus rapide et les cinq plus lents. Ensuite il suffit de prendre le temps le plus rapide et faire une petite soustraction pour avoir l'écart.
|
||||
|
||||
C'est une stat assez intéressante car elle lisse les différences d'un tour à l'autre et fait ressortir une tendance. On peut voir pour le grand prix de monaco 2023 par exemple, le moment ou les pneus pluie deviennent plus intéressants que les pneus secs car on voit que les pilotes les plus rapides sont les pilotes de fond de grille qui ont chaussé les pneus pluie en premier tandis que les plus lents sont les pilotes sur pneus secs vieux.
|
||||
|
||||
Voici un bout de code qui s'occupe de faire les calculs :
|
||||
|
||||
```Csharp
|
||||
List<(int avg, string driverName)> averages = new List<(int avg, string driverName)>();
|
||||
foreach (DriverData driver in LiveDriverDataLogs[LiveDriverDataLogs.Count - 1])
|
||||
{
|
||||
//We want to recover the last 5 lap times
|
||||
List<(int lapTime,int lap)> laps = Storage.GetDriverLaptimes(driver.Name,5);
|
||||
if(laps.Count > 0)
|
||||
{
|
||||
int avg = 0;
|
||||
foreach ((int lapTime, int lap) lap in laps)
|
||||
{
|
||||
avg += lap.lapTime;
|
||||
}
|
||||
avg = avg / laps.Count;
|
||||
averages.Add((avg, driver.Name));
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Affichage prédictif
|
||||
|
||||
C'est ici que ca devient vraiment dommage, le projet a mannqué de temps pour implémenter des affichages prédictifs mais le potentiel est la !
|
||||
|
||||
Un affichage prédictif est un affichage qui crée des informations à partir des infos qu'il a mais qui fait plus qu'un calcul. Le but est de tenter de deviner quelque chose.
|
||||
|
||||
Voici des exemples d'affichages prédictifs qui pourraient être mis en place averc l'architecture actuelle du projet :
|
||||
|
||||
- Si un pilote a des pneus depuis plus de 20 tours et que son temps au tour est en chute libre depuis cinq tours. Alors ce pilote va peut-être devoir s'arrêter.
|
||||
- Si un pilote tourne une seconde au tour plus vite que le pilote devant lui et que ce pilote est à 10 secondes devant, alors il devrait pouvoir le rattraper d'ici dix tours.
|
||||
- Si un arrêt au stand est en moyenne de 23 secondes, alors un pilote 3ème ressortirais potentiellement 7ème si il s'arrête maintenant.
|
||||
|
||||
Tous ces exemples sont des mini algorythmes prédictifs qui pourraient être implémentés assez facilement dans l'architecture actuelle du projet et pourraient apporter une immense plus-value si ils sont bien paramêtrés.
|
||||
|
||||
On peut même imaginer que l'algorythme se corrige tout seul si il voit qu'il a eu tort pour que les course suivante il puisse mieux s'en sortir.
|
||||
|
||||
Les possibilitées sont infinies !
|
||||
|
||||
## Tests
|
||||
|
||||
|
||||
Reference in New Issue
Block a user