Récupération et traitement des fichiers csv "évolution de la
vaccination"
Pour l'évolution de la vaccination, on fait appel à deux fichiers de
référence. Par rapport aux fichiers indiquant l'état de la vaccination
à ce jour, ils reprennent le même genre d'information (sauf la population
estimée), mais la fournissent pour tous les jours depuis le 27 décembre
2020, jusqu'à la veille ou le jeudi précédent.
Ça entraîne des fichiers de référence beaucoup plus gros, et qui
s'allongent un peu chaque jour. Par exemple, le fichier de référence
qui montre l'évolution de la vaccination par classe d'âge a le contenu
suivant :
Pour connaître la date de dernière mise à jour de ce fichier, il faut au
moins lire en entier la première classe d'âge. On peut aussi lire tout
le fichier et récupérer la date de la dernière ligne. Mais récupérer la
totalité d'un fichier de référence juste pour savoir s'il est utile de
faire une mise à jour du fichier local est stupide !
Donc, pour déterminer si un fichier local relatif à l'évolution de la
vaccination est à jour (ou à peu près), on utilisera la même méthode
que pour le fichier local
vacsi-totgen.csv
Les fonctions
testmaj_a_fra () et
testmaj_regdom ()
permettent de mettre à jours les fichiers csv locaux :
- vacsi-a-fra.csv pour la première,
- vacsi-reg.csv et vacsi-dom.csv pour la
suivante.
Ce fichiers locaux permettront de réaliser des graphiques d'évolution
pour les différentes classes d'âge, les différentes régions, et les
différents DOM.
Toutefois, il est également intéressant de voir cette évolution sous
la forme de tableaux. Mais dans ce cas, une ligne par jour donnerait
des tables inutilement longues et précises. On préfère dans ce cas se
limiter à l'affichage pour 3 jours de chaque mois.
Des fichiers se limitant aux jours sélectionnés sont aussi générés.
Le fichier vacsi-a-fra et les fichiers dérivés
Tout d'abord, on cherche à savoir s'il est utile de faire une mise à
jour du fichier local
vacsi-a-fra.csv (et des fichiers dérivés).
Pour cela, on regarde si le fichier local
vacsi-tot-a-fra.csv
est plus récent que
vacsi-a-fra.csv. On ne fera une mise à jour
que dans ce cas.
// fichier qui sert à déterminer si une mise à jour est utile
$refdate = DIR_CSV."/vacsi-tot-a-fra.csv";
// fichier à mettre éventuellement à jour
$chemcsv = DIR_CSV."/vacsi-a-fra.csv";
// si le fichier est à jour
if (filemtime ($refdate) <= filemtime ($chemcsv))
// on n'a rien à faire
return;
Remarque : Dans le pire des cas, depuis la dernière mise à jour
des données sur le site web de référence, ni l'utilisateur actuel, ni
un utilisateur antérieur aura consulté l'état de la vaccination à ce
jour avant de regarder l'évolution de la vaccination. Dans ce cas, le
fichier
vacsi-a-fra.csv et ses dérivés ne seront pas mis à jour
à tort.
Toutefois :
- c'est moins grave d'oublier les tous derniers jours que dans le
cas de l'état de la vaccination "à ce jour",
- si on accède à la partie vaccination de ce site par le lien
"Voir les statistiques de vaccination" de la page d'accueil,
on arrive sur le tableau de l'état général de la vaccination
à ce jour et le problème ne se pose pas.
Comme pour les fichiers de référence sur la vaccination à ce jour, les
classes d'âge sont presque dans l'ordre mais pas tout à fait. La classe
d'âge concernant le 5 à 9 ans est entre la classe d'âge des 40 à 49 ans
et celle des 40 à 49 ans.
Pour remettre ça dans l'ordre (même si ce n'est pas indispensable), on
va recopier les lignes issues du fichier de référence dans 2 fichiers
distincts, un pour les deux classes d'âge jusqu'à 9 ans, et l'autre pour
toutes les classes d'âge à partir de 10 ans. Pour cela, on teste le
premier chiffre de la classe d'âge.
// comme la classe d'âge 09 est mal placée on commence
// par créer 2 fichiers qu'on fusionnera juste après
$nouvcsv1 = DIR_CSV."/vacsi-a-fra.new1";
$nouvcsv2 = DIR_CSV."/vacsi-a-fra.new2";
// les ouvrir en écriture
$descscv1 = fopen ($nouvcsv1, "w");
$descscv2 = fopen ($nouvcsv2, "w");
// si les ouvertures se sont bien passées
if ($descscv1 && $descscv2)
{
// lire la première ligne de l'url en oubliant "FR;"
$ligne_url = substr (fgets ($descurl, LG_MAX_CSV), 3);
// séparer les différents champs de la ligne
// on prévoie que des champs supplémentaires pourront apparaitre
$args = explode (";", trim ($ligne_url), 20);
// trouver le nombre de doses mémorisées
$doses = (count ($args) - 2) / 3;
// tant que la dernière ligne lue fait référence à une classe d'âge
while ($ligne_url [2] == ";")
{
// réordonner le champ date et supprimer les champs inutiles
$ligne_url = selchamps_evol ($ligne_url, $doses);
// recopier la ligne dans le bon fichier
if ($ligne_url [0] == "0")
fputs ($descscv1, $ligne_url);
else
fputs ($descscv2, $ligne_url);
// lire la ligne suivante de l'url en oubliant "FR;"
$ligne_url = substr (fgets ($descurl, LG_MAX_CSV), 3);
}
Il faut à présent mettre le contenu du 2ème fichier dans le premier.
// remplissage du fichier 2 terminé
fclose ($descscv2);
// on va rajouter son contenu au fichier 1
$descscv2 = fopen ($nouvcsv2, "r");
// si l'ouverture s'est bien passée
if ($descscv2)
{
// lire la première ligne du fichier 2
$ligne = fgets ($descscv2, LG_MAX_CSV);
// tant que non fin du fichier 2
while ($ligne)
{
// recopier la ligne dans le fichier 1
fputs ($descscv1, $ligne);
// lire la ligne suivante du fichier 2
$ligne = fgets ($descscv2, LG_MAX_CSV);
}
// terminé avec le fichier 2
fclose ($descscv2);
}
else
$erreur = "Problème pour terminer le fichier ".basename ($chemcsv);
Il reste les données concernant la vaccination tous âges confondus qu'on
va rajouter à la fin du fichier en remplaçant la classe d'âge numérotée
0 par "ta".
// on rajoute les données corespondant à toutes les classes d'âge réunies
// tant que non fin de fichier csv
while ($ligne_url)
{
// réordonner le champ date, supprimer les champs inutiles
// et rebaptise la classe d'age générale
$ligne_url = "ta".substr (selchamps_evol ($ligne_url, $doses), 1);
// recopier la ligne dans le dernier fichier
fputs ($descscv1, $ligne_url);
// lire la ligne suivante de l'url en oubliant "FR;"
$ligne_url = substr (fgets ($descurl, LG_MAX_CSV), 3);
}
Le remplissage du fichier
vacsi-a-fra.csv est terminé.
À présent, à partir de ce fichier, on va créer un fichier par classe
d'âge et un fichier tous âges confondus représentant l'évolution de la
vaccination tous les 10 jours environ.
On choisira de mémoriser dans les nouveaux fichiers les données des
1
er, 11
ème et 21
ème jours ou, si l'une
d'elles venait à être absentes, celle du premier jour qui suit.
L'état de la vaccination pour le jour le plus récent disponible sera
aussi recopié dans le fichier s'il ne l'a pas déjà été en sélectionnant
un jour sur 10.
Pour ça, on lit ligne par ligne le fichier
vacsi-a-fra.csv que
l'on vient de créer. A chaque nouvelle ligne, on commence par tester la
classe d'âge. Si ce n'est pas la même que pour la ligne précédente, on
va créer un nouveau fichier.
// lire la classe d'âge
$cl_age = fgets ($descscv, 3);
// tant que non fin de fichier
while ($cl_age)
{
// si la classe d'âge a changé par rapport à la ligne précédente
if ($cl_age != $cl_prec)
{
// si on remplissait un fichier
if ($cl_prec)
{
(...)
// fermer le fichier qu'on vient de remplir
fclose ($descout);
}
// nouveau fichier à remplir
$ficout = DIR_CSV."/vacsi-age-".$cl_age.".csv";
$descout = fopen ($ficout, "w");
// si l'ouverture s'est mal passée
if (! $descout)
// il pourra y avoir plusieurs erreurs du même type
$erreur = $erreur."Problème créer le fichier ".basename ($ficout)."<br>\n";
// mémoriser la nouvelle classe d'âge
$cl_prec = $cl_age;
// on commencera à afficher les données début janvier 2020
$dizaine = 0;
}
Les fichiers créés ont comme nom
vacsi-age-??.csv avec la classe
d'âge à la place des
??? . Par exemple
vacsi-age-24.csv
pour la classe d'âge des 18 à 24 ans. Le fichiers de l'évolution tous
âges confondus s'appelle
vacsi-age-ta.csv
On va recopier certaines lignes du fichier
vacsi-a-fra.csv
dans le nouveau fichier. Pour qu'une ligne soit choisie, il faut que le
chiffre des dizaines du jour du mois ait changé par rapport à la dernière
ligne recopiée et que le chiffre des unités du jour du mois ne soit pas
0. On exclue aussi le 31
ème jour lorsqu'il existe.
Le passage d'une dizaine de jours à la suivante s'effectue simplement
grâce à une addition modulo 3.
// lire le reste de la ligne
$ligmemo = fgets ($descscv, LG_MAX_CSV);
// si on n'a encore rien enregistré pour cette dizaine de jours
if ($ligmemo [0] == $dizaine && $ligmemo [1])
{
// le faire
fputs ($descout, $ligmemo);
// cette ligne ne sera pas réutilisée
$ligmemo = "";
// passer à la dizaine de jours suivante
$dizaine = ($dizaine + 1) % 3;
}
// lire la classe d'âge de la ligne suivante
$cl_age = fgets ($descscv, 3);
Enfin, lorsque toutes les dates d'une classe d'âge ont été explorée,
on recopie les données concernant le jour le plus récent si elles ne
viennent pas de l'être.
// si la ligne du jour n'a pas été recopiée
if ($ligmemo)
// le faire
fputs ($descout, $ligmemo);
Cette dernière opération se fait :
- lorsqu'on a lu entièrement le fichier vacsi-a-fra.csv
après avoir traité la catégorie "tous âges confondus",
- à chaque changement de classe d'âge. Dans ce cas, ces deux
instruction sont mise à la place des (...) dans le
code un peu plus haut.
Les fichiers vacsi-reg , vacsi-dom et les fichiers dérivés
Ces fichiers sont réalisés à partir d'un fichier de référence qui a
la même structure que le fichier de référence d'évolution de la
vaccination pas classe d'âge.
En particulier l'indication du DOM ou de la région figure en début
de ligne sous la forme d'un code de 2 chiffres :
- les DOM qui sont numérotés de 01 à 08,
- les régions de métropole ont des numéros compris entre 11 et
94.
Dans les fichiers
vacsi-dom.csv et
vacsi-reg.csv on
va remplacer ces codes numériques par des codes de 3 lettres :
- les 3 première lettres du nom de la région ou du DOM dans la
plupart des cas,
- la lettre s suivi des 2 premières lettres du 2ème
mot si le nom du DOM commence par "Saint".
Pour transformer les codes numérique de DOM puis de région en un code de
3 lettres, on procède de manière similaire à ce qui a été fait pour les
fichiers
vacsi-tot-dom.csv et
vacsi-tot-reg.csv
Un tableau est utilisé pour les DOM :
// code des DOM dans l'ordre de leur numéro du fichier csv de référence
$liste_codedom = array ("", "gua", "mar", "guy", "reu", "smi", "may", "sba", "sma");
et une instruction
switch ... case pour les codes de région.
Une fois les fichiers
vacsi-dom.csv et
vacsi-reg.csv
réalisés, on va créer des fichiers de nom
vacsi-dom-???.csv
et
vacsi-reg-???.csv avec le code de région ou de DOM à la
place des
???
Pour cela, on va utiliser une fonction appelée 2 fois :
// 2ème partie : on crée un fichier par région et un fichier par DOM
// avec une information tous les 10 jours
synthese_regdom ($csvreg, "reg");
synthese_regdom ($csvdom, "dom");
Le fonctionnement de
synthese_regdom (...) est similaire au
traitement qui a été fait pour les classes d'âge. La seule différence
est qu'on utilise des codes de 3 caractères au lieu de 2