Motiver vos méninges, faites des concours

En tant que développeur, il est rare que nos algorithmes soient vraiment révolutionnaires. Souvent nos travaux sont tout autre. Nous devons assembler, comprendre le métier, proposer des solutions innovantes .. mais pas faire des algorithmes réellement complexes. La difficulté est réelle .. mais il ne s’agit pas d’algorithme à proprement dit.

Les challenges de programmation sont une occasion unique de faire travailler nos méninges, bien fatigué par des années de temps perdu à comprendre pourquoi « le ca marche sur mon PC » ne s’applique plus en production.

Les challenges peuvent être plus ou moins long et plus ou moins sponsorisés. Votre objectifs sera soit de vous faire remarquer par un recruteur … soit simplement prendre du plaisir.

Durant les fêtes qui s’approche, le site Coding Game propose un concours particulier par sa longueur. Vous aurez 3 semaines pour réfléchir, aucune excuse pour ne pas s’y frotter.

Le concours débute le 12.12.2022 à 16H00.

C’est par ici que cela se passe : https://www.codingame.com/contests/fall-challenge-2022

Bon jeu et bonne prise de tête.

C’est cela qu’on aime ^^.

#codinggame #bot #IA

L’objectif de cet article est d’étudier une étude de cas pratique : mettre en place un nœud IPFS sous une distribution Linux basé sur debian.

Installation du serveur IPFS

sudo apt install golang -y
wget https://dist.ipfs.io/go-ipfs/v0.14.0/go-ipfs_v0.14.0_linux-amd64.tar.gz$
tar xvfz go-ipfs_v0.14.0_linux-amd64.tar.gz

La configuration d’un nœud local se fait simplement en suivant les instructions données par l’exe.

./ipfs init
./ipfs cat /ipfs/XxXX/readme
./ipfs daemon

Le nœud est ensuite opérationnel et consultable sur l’url local suivante :



L’ajout d’un fichier à l’aide de la ligne de commande se fait via : ./ipfs add ../merle.jpg

Cette commande vous affichera le hash correspondant à votre fichier :


Cette valeur ( QmXrMP1aHHQHpuGoGioDbdKcnGtij6yx418Xb9wwoGwgue ) correspond à l’identifiant unique de votre fichier. Il peut ensuite être utilisé pour localiser ou faire des actions dessus.

Depuis l’interface Web, il est possible de vérifier l’enregistrement de votre fichier :

Toutes les actions faisables en ligne sont réalisables depuis la console.
La suppression via rm, l’étiquetage, via pin add pour l’étiquetage de fichier.

La mise en place de ce type de service est ultra-basique. Il est recommandé d’utiliser un service d’étiquetage centralisé pour faciliter la diffusion de ses fichiers. Une fois ceci fait, on peut se lancer dans d’autres expériences : la publication d’un site web statique directement en IPFS, l’hébergement d’une collection de NTF.

L’objectif est de pouvoir proposer de manière simple ces fichiers au plus grand nombre sans risque de défaillance d’un serveur centralisé.

Nota : cet article est assez court mais a pour objectif d’être le premier dans ma découverte du web3. A suivre donc ^^

Référence :

Abyss-project blog

Base transparence – échec lors de la montée en charge

Dans l’article précédent, nous étions partis sur une extraction des données.
En effet, notre objectif était d’avoir une résultat rapide afin d’avoir des données affichages.  Nous sommes donc sur un cas d’école entre le cas utilisé par un développeur qui travail sur une extraction afin de valider ses travaux … qui échoue une fois les données de production utilisées.

En regardant le volume des données, rien de plus normal. Nous utilisons comme base de travail 3 fichiers de plusieurs gigas que nous combinons entre eux avant de faire les opérations. Autant dire que cela explose très rapidement.

En ré-ordonnant les opérations, et filtrant les données, tout rentre dans l’ordre.

Le code est le suivant :

 

self.loader.load_avantages(light)
data_avantages = self.loader.avantages[[‘entreprise_identifiant’, ‘avant_montant_ttc’]]

#calcul de la rémunération (avantage)
data = data_avantages.groupby([« entreprise_identifiant »])[« avant_montant_ttc »].sum().sort_values(ascending=False).head(nb_entreprise)

### jointure entreprise et avantage
self.loader.load_entreprises()
data_merge = merge(data, self.loader.entreprises, how= »left », left_on=[« entreprise_identifiant »], right_on= »identifiant »)
data_merge.to_excel(writer, sheet_name= »Avantage »)


A noter :

data = data_avantages.groupby([« entreprise_identifiant »])[« avant_montant_ttc »].sum().sort_values(ascending=False).head(nb_entreprise)

4 opérations dans cette ligne.

  • Le groupby permet de regrouper l’ensemble des avantages  par entreprise.
  • Le sum : permet de les cumuler
  • Le sort_values : permet de les trier dans l’ordre croissant
  • Le head permet de ne récupérer que les nb_entreprises les plus important.

Le github du projet a été mis à jour : https://github.com/SaugetMarc/transparence

 

 

 

 

 

 

Python Pandas Excel : un premier formatage

L’objectif de cet article est donc de montrer une chaîne complète de traitement de l’information, permettant à partir d’un ensemble de fichier résultat de type CSV, d’aller à un tableau formaté, pouvant être directement diffusé.

Le choix des données initiales

Pour avoir une base de travail, le plus simple est de partir sur des données issues de l’Open Data. Ces données sont facilement accessibles, fournies dans un résultat exploitable .. et sont souvent des mines d’information.

Mon choix c’est fait sur la base de données Transparence. Ces données sont directement accessible sur le portail suivant : transparence-santé.

La modélisation des données est la suivante :

    • Un fichier pour la description des entreprises
    • Un fichier pour la description des avantages
    • Un fichier pour la description des conventions.

La manipulation des données en Python

Nous allons faire simple, car dans ce cas précis, l’objectif est de voir comment charger les données, renseigner les jointures entre elles et produire quelques résultats.

Les données sont actuellement centrées sur l’entreprise. Notre  exemple sera de construire un graphique  contenant  les 50 entreprises les plus dépensières (convention + avantage).

Chargement et jointure des fichiers

Pour le chargement des fichiers, le plus simple est d’utiliser les méthodes mises à disposition par le frameworks Panda.  Mais avant tout chose, il est nécessaire de se faire un jeu de données possédant une taille utilisable pour les tests.

Le plus simple est de prendre une sous-sélection des fichiers de bases. Avec un environnement bash, la commande head permet de faire cela très rapidement.

head -n 50 avantage.csv > avantage_light.csv 

Une bonne habitude est d’utiliser dès que possible un fichier de configuration pour votre projet.  Les chaînes magiques ont malheureusement tendance à rester beaucoup trop longtemps dans les projets

DATA = {

'avantage' : 'data/avantage_light.csv',
'convention': 'data/convention_light.csv',
'entreprise': 'data/entreprise.csv',
'remuneration':'data/remuneration_light.csv'

}

Le chargement des fichiers se fait avec la commande suivante :

defloadcsv(self):
self.entreprises = read_csv(settings.DATA['entreprise'], header=0, delimiter=',', error_bad_lines=False)
self.avantages = read_csv(settings.DATA['avantage'], header=0, delimiter=';', error_bad_lines=False)
self.conventions = read_csv(settings.DATA['convention'], header=0, delimiter=';', error_bad_lines=False)
self.remunerations = read_csv(settings.DATA['remuneration'], header=0, delimiter=';', error_bad_lines=False)

Les travaux préparatoires sont maintenant terminés

Après une rapide analyse des fichiers, tous utilisent l’identifiant de l’entreprise comme données de jointure. Le seul point à prendre en compte porte sur le fait que suivant le fichier, l’identifiant n’a pas le même nom.  Il faut donc préciser le nom de la colonne pour pouvoir faire un rapprochement.

La jointure se fait donc à l’aide de la commande suivante :

data_merge = merge(self.loader.avantages, self.loader.entreprises, how="left", left_on=["entreprise_identifiant"], right_on="identifiant")
 
Puis, afin de regrouper les données par secteurs, il faut faire une opération de regroupement sur deux informations : le secteur et le nom de l’entreprise :
(La commande finale  head(50) permet de limiter l’extraction au 50 premières lignes, utile en cas de test)
 
data = data_merge.groupby(["secteur","entreprise_identifiant"])["avant_montant_ttc"].sum().head(50)
L’enregistrement basic dans un fichier excel se fait avec la commande suivante :
data.to_excel(writer, sheet_name="Avantage")
Simple, mais peu exploitable en production. En effet, le résultat obtenu n’est pas des plus présentable.
 

Construction du fichier excel formaté.

worksheet = writer.sheets["Avantage"]
format_size = 'C2:C'+str(data.shape[0]+1)
worksheet.conditional_format(format_size, {'type': '3_color_scale'})
worksheet.set_column('A:C', 20)

Avec ces 4 petites lignes, on a :

    • Déterminer la taille de la table
    • Changer le format de la dernière colonne (en gradiant)
    • Redimensionner la taille des 3 colonnes de notre table.

 

Pour aller plus loin, allez faire tour sur  Xlswriter.   L’ensemble des sources de ce petit projet sont ici

 

 

 

 

Un site statique en Jekyll

L’objectif est simple : proposer un site Internet flexible, évolutif et présentant le minimum de risque de sécurité.

Les bases sont posés et chacun des points peut être détaillé de la manière suivante :
Flexible : l’idée est de pas se contraindre dans un cadran trop fixe et de pouvoir présenter le contenu dans le format qui nous intéresse.

Evolutif : Le contenu est un élément dur à produire, il faut permettre une structure qui va pouvoir s’actualiser, se compléter facilement. Il faut aussi pouvoir présenter des actualité. Le besoin n’est pas d’une mise à jour à la journée, mais plutôt sur un rythme mensuel.

Sécurisé : rien de pire qu’un site qui se fait hacker et que diffuse de l’information non souhaité. Dans notre contexte, la surveillance du site sera moindre que sur un site d’entreprise. Les moyens sont limités, il faut donc limiter au maximum les sources d’incident.


Voici les trois éléments qui m’ont amené à proposer un site statique pour la commune de Couthenans (70400).

Choix du moteur :

En fait, le choix est relativement restreint. Et assez rapidement, j’ai du choisir entre Jekyll (ruby) et Pelican (Python). Sachant que je pratique plus le python que le ruby, je me suis tourné vers Pelican dans un premier temps.
Rapidement, j’ai buté sur des problèmes de présentation ou de mise en place de pluggin. Je ne pense que Pelican ait un potentiel plus faible, simplement que sa documentation et les templates associés sont moins riches. Mon choix est donc de partir sur Jekyll pour sa simplicité de mise en place.


Pour la mise en place d’un exemple de site, c’est tout simple, il suffit de suivre les tutoriaux, et quand vous arrivez au bout, vous avez un site fonctionnel. Pour la mise en forme, j’ai triché et j’ai utilisé un template existant (pourquoi ré-inventer la roue).  Je me suis donc basé sur les travaux de phlow (https://phlow.github.io/).

D’un point de vue technique, il faut lire la documentation du thème que l’on exploite et regarder comment les pages sont construites. Après quelques tests, le récupération d’un peu de contenu. On arrive rapidement à produire un site diffusable en production. La maquette du site peut être visible ici : http://couthenans.sauget.fr/

Mes seules notes sur ce projet concerne :
– la commande de compilation pour le développement :

bundle exec jekyll serve --config _config.yml, _config_dev.yml --livereload --incremental 

– la commande pour la production :

bundle exec jekyll build

Couthenans.fr
Que dire d’autres, pour vos sites à faible modification, essayer les sites statiques, cela fait gagner énormément de temps à vous et à l’utilisateur.

Prochaine étape : le passage de ce blog en statique, à raison d’un billet par an …
il est forcément un bon candidat ^^



Manipulation de fichier Excel : utilisez Python

Le besoin était simple, à partir d’un fichier de vente global à une société, il fallait proposer un fichier spécifique par commercial pour qu’il puisse saisir son prévisionnel propre à chacun de ses clients … puis proposer un outil permettant de réaliser la synthèse de ses documents particuliers.

La manipulation de fichier Excel via openpyxl

Les fonctions de base :

L’ouverture d’un fichier excel avec cette libraire se fait comme dans la vraie vie. Il faut ouvrir le fichier : load_workbook puis sélectionner l’onglet dans lequel on souhaite travailler . Les onglets sont stockés sous forme de dictionnaire, il suffit de donc le charger en utilisant comme clé le nom de l’onglet workbook[‘nomOnglet’].

Lire une valeur : Il suffit de repartir de l’objet utilisé pour récupérer l’onglet. Les cellules sont atteignables via le couple Ligne/colonne. Par exemple, pour récupérer la valeur en F13, il suffit de faire : val = onglet[‘F13’].value

def getValueNumerique(ong, key):    
   valT = 0    
   val  = ong[key].value    
   if (isinstance(val, Number)):
      valT =  val   
return valT

Enregistrer une valeur peut être réaliser en faisant une simple affectation : onglet[‘F13’] = val

Ajouter/dupliquer un onglet :         wb.copy_worksheet(wb[‘CC’])

Enregistrer le fichier final : wb.save(« nouveauNom »)

De un vers plusieurs : Python via Panda pour un éclatement rapide

La difficulté la plus grande est de trouver l’élément sur lequel vos filtres vont pouvoir s’appuyer. Dans mon contexte, chaque vente était relié à son représentant. La sélection des données fut donc de :

  • Filtrer sur la période de temps souhaité :         listeCommade38_2018 =   df_filtre_soc[( (df_filtre_soc[« MOIS_FACT »] >= 201800.) & (df_filtre_soc[« MOIS_FACT »] <= 201900.)  )]
  • Puis, après construit la liste des représentants, boucler dessus afin de ne traiter que les ventes du représentant en cours de traitement :     df_filtre = df[(df[« CODE_REPRESENTANT »] == representant_ref)]
  • Dans certain cas, nous n’avons pas besoin que d’une valeur, mais d’une combinaison de valeur. Dans ce cas, la fonction query facilite les regroupements d’information :   m2019 =   (liste_2019_cc_filtre.query(‘@pp.liste_ref in CODE_ART’))[« QTE_EXPE »]
  • On peut ensuite appliquer des fonctions sur le résultat obtenu : nbProd_2019 = m2019.sum()

De plusieurs vers un : une simple routine en Python

Tout aussi simple. Pour identifier l’ensemble des fichiers résultats, la commande glob.glob(path) permet de retrouver un ensemble de fichier correspondant à un dossier et possédant un pattern exploitable.

Ensuite, il suffit d’ouvrir chacun des fichiers, de retrouver l’onglet de synthèse, puis de lire les données calculée via macro. Attention, afin d’avoir la valeur et non la méthode de la macro, il faut passer des arguments à la fonction d’ouverture de document excel :     wb = load_workbook(fich, read_only=False, keep_vba=True,  data_only=True).

Dans mon cas, les données étant réparties en fonction d’un template fixe, j’ai préféré passer par un dictionnaire pour faciliter l’identification des données à consulter :

totaux ={
    'F7' : 0,
    'F8' : 0,
    'F9' : 0,
    'F13' : 0,
    'F14' : 0,
    'F15' : 0,
    'F16' : 0
}

Il suffit ensuite de boucler sur le dictionnaire, pour réaliser, en une boucle, la lecture de l’ensemble des données :

def rechercheOngletSynthese(wb, sommeTige):
    synth =  wb['Synthese']

    for key in totaux:
        val  = synth[key].value  

Une fois les valeurs obtenues, il n’y a plus qu’à construire le fichier résultat (basé une fois de plus sur un template excel.

wb = load_workbook(fichR, read_only=False, keep_vba=True,  data_only=True)

# On va dans l'onglet synthèse
synth =  wb['Synthese']
for key in totaux:
    synth[key] = totaux[key]

sauvegarde_finale('resultat2019.xls' , wb)

Au final, avec deux scripts, nous pouvons automatiser la génération des fichiers à faire remplir, puis la construction de la synthèse. Le temps de développement est relativement cours (le plus long fut la prise du résultat à produire). De plus, le résultat pouvant être produit à la demande, il est très simple de fournir des résultats intermédiaire … le temps que l’ensemble des fichiers reviennent après leur saisie.

Liste des imports utiles :

import csv
import pandas as pd
import produit 
import  re as Regex

#Pour le traitement des fichiers excels
from openpyxl import Workbook
from openpyxl import load_workbook
#Pour la vérification des nombres
from numbers import Number

# Pour les fichiers
import os.path
import glob
from pathlib import Path

import unicodedata

Url :

https://pypi.org/project/openpyxl/

https://pandas.pydata.org/

Un modèle de formulaire dynamique en Python / Django

Le concept : Un n-ième outil de création de formulaire

Le sujet n’est pas réellement innovant : il doit exister autant de site de formulaire dynamique que de développeur  … Pourtant, à chaque nouveau développement, il est rare de trouver l’outil, le module, qui va permettre de ne pas développer son modèle de formulaire. Il manque souvent, la fonctionnalité, ou le paramétrage qui va permettre d’avoir le paramétrage ou la personnalisation nécessaire.  Le principe de ce développement ne sera donc pas de faire le module de formulaire le plus complet possible … mais au contraire, de proposer un outil simple, robuste qui pourra être utilisé tel quel … ou étendu pour des besoins spécifiques.

L’innovation : Penser directement pour l’exploitation des résultats

En effet, un formulaire, quel qu’il soit n’est utile que si l’exploitation des résultats est possible.  L’objectif de ce développement sera donc de fournir l’ensemble des outils permettant la conception et l’utilisation d’un formulaire mais également, ceux qui permettent une exploitation ou un export des résultats.

Le mode de distribution

Sur ce point,  je vais essayer d’être le plus complet possible afin que tous puisse y trouver leur compte.  L’objectif sera donc de proposer :

  • Un service en ligne complet et autonome.
  • Une Api, permettant à des solutions de personnaliser complètement une partie de l’interface tout profitant d’un backend et de solution d’export existante.
  • Sous forme de brique logicielle autonome pouvant être déployant directement au sein d’une infrastructure
  • et pour ceux qui veulent aller plus loin dans la personnalisation, directement les sources de la solution (open ou closed source) en fonction de la cible du logiciel.

la stack technique

Pour le moment, rien n’est définitif … Mais le premier jet sera basé sur Python Django + un serveur MariaDB.  L’objectif de cette stack est de permettre d’obtenir un premier résultat rapide. De plus, ce choix permet de jolies évolutions. 

La cerise sur le gâteau est que Python est Le langage a suivre pour le moment. Ce choix est donc à la fois pour l’évolution du produit .. que pour mon évolution. 

Qu’est-ce que la dette technique ?

La dette technique est une métaphore du développement logiciel inventée par Ward Cunningham. … Cette définition reste vague mais pose le principe d’un coût représenté par un logiciel ou un SI relativement à sa qualité, sa maintenance ou son cycle de vie.

Un métaphore souvent utilisée pour illustrer ce phénomène est celle de la grenouille plongée dans l’eau bouillante : si l’augmentation de la température est lente, les grenouilles resteront tranquillement à leur place jusqu’à se trouver complètement cuites lorsque l’eau sera bouillante. En revanche, si vous jetez une grenouille directement dans l’eau bouillante, celle-ci trouvera immédiatement la force de s’extraire de ce milieu hostile.

Quand produit-on de la dette ?

Les causes de production de la dette technique sont multiples. Mais le critère le plus important est sur le type de production. Cette production est-elle prise en connaissance de cause (suite à des contraintes temporelles ou techniques), ou est-elle produite de manière passive (quand le choix est basée sur des bases non maîtrisées ou suite à des évolutions techniques non suivie).

Dans tous les cas, et surtout dans le second, il faut prendre le temps de faire l’audit des solutions mises en œuvre pour identifier toutes les sources de production de cette dette. Cette dette, tel un produit financier, à un coût. Ne pas le gérer,risque, à très court terme de rendre la solution beaucoup moins rentable qu’escomptée.

Conséquence de la dette technique

Contrairement à une croyance, même avec des équipes au top, il n’est pas possible d’avoir un projet rapide, pas cher et de qualité.

Les conséquences sur les projets

  • L’explosion du coût de la maintenance :
    Ajouter de la dette sans la prendre en compte risque de souvent complexifier le code de votre solution (duplication de code, de schéma, suppression de test (ou non écriture).
  • La non évolutivité du produit :
    L’ajout de la petite modification penser comme un simple héritage d’un mode de fonctionnement proche revient à modifier plusieurs fonctions utilisées jusqu’à lors telle des boites noires … Attention danger
  • La notion de risque à chaque déploiement :
    Les tests sont souvent les premiers à sauter … et dans ce cas, c’est uniquement lors de la mise en production que l’on risque de s’apercevoir que la boite noire est utilisée dans un autre module … sans aucun rapport fonctionnel …

null

Les conséquences sur les développeurs

  • Le découragement, la démotivation :
    C’est un élément rarement pris en compte mais travailler sur un logiciel instable est vite usant. Perdre beaucoup de son temps car le développement n’est pas ce qu’il aurait du être … ou que la modification simple doit juste être refaite à 10 endroits suite à des duplications de code … supprime vite toute envie de travailler sur un logiciel.
  • La perte de créativité :
    A perdre son temps dans la maintenance, le développeur va limiter l’impact de son travail au strict minimum, c »est à dire la correction de bogue sans avoir l’envie de prendre du recul sur son travail …
  • l’érosion des compétences :
    le pire qu’il peut arriver, à partir d’un certain temps, le développeur risque de se faire une raison … et de perpétuer les mauvaises pratiques qui sont en place dans la solution qu’il est entrain de maintenir.

Comment s’en prémunir?

L’importance de la conception initiale : Laisser le KISS (Keep It Simple and Stupid) pour le poc

L’entretien du code

  • La mise en place d’un PAQL, le plan d’assurance qualité est le document qui va permettre à un développeur de travailler dans un univers cohérent. Il ne s’agit pas de brider la créativité des développeurs, mais simplement de poser un ensemble de règle qui vont permettre à un nouveau développeur de savoir comment s’intégrer dans la structure.
  • Et de son application : c’est le pendant de toute documentation,, après sa rédaction, il faut se donner les capacités de s’assurer de son application … sinon, rapidement, le respect du PAQL ne sera qu’un lointain souvenir.
  • La mise en place d’une revue de code : l’objectif est de discuter du code produit et en aucune façon de le critiquer. Cette revue peut être le moment de mettre à jour le PAQL et de voir comment les stratégies de développement peuvent évoluer.

L’importance de l’automatisation

  • Pour toutes les tâches répétitives : export, admin, …
  • Pour les tests : unitaire ou fonctionnel
  • Pour la qualité du code

Et surtout : L’intégration de la dette dans le backlog des projets … car toute dette se rembourse … sinon d’elle même, elle causera la ruine du projet.

Quelques références

Livre :
– The Pragmatic Programmer,
– Code Legacy

Blog

Power Bi, Open Data et listing des pharmacies

Voici un petit article présentant comment il est possible d’obtenir un listing dans Power BI présentant une grande majorité des pharmacies.

La première étape est de récupérer un fichier contenant l’ensemble des établissements de santé.
Le choix se fait sur le fichier Fichier Finess:

Le choix est déterminé par la certification du fichier et sa fréquence de sa mise à jour.

Ce dossier du site Open Data contient en fait plusieurs documents distincts dont le détail est visible dans l’aperçu précédent.

Pour ce premier article, nous n’aurons besoin que du fichier contenant les extractions Finess des établissements ainsi que la géolocalisation de ces établissements. En supplément, il est possible de consulter le 1er fichier permettant d’obtenir un descriptif des différentes informations contenus dans le dossier.

Le traitement dans Power Bi sera minimaliste. La première étape consiste à importer les différents fichiers CSV. Après import des fichiers, il faut faire attention au typage automatique des colonnes. En effet, pour se faire, Power BI fait un échantillonnage sur les premières colonnes du fichier. Dans le cas des départements, cela pose problème car le type numérique du début de fichier n’est pas conservé sur son intégralité (2A / 2B pour la corse par exemple). Il est donc recommandé de conserver le type alphanumérique pour toutes valeurs qui n’est pas un nombre exploitable. Ceci se fait très facilement en appliquant changeant le type.

Pour le fichier structure, les étapes sont les suivantes :

  1. Source : import initial
  2. Promoted Headers : permet de sélectionner la première ligne comme entête de la table
  3. Changed Type : permet de passer du type numérique à alphanumérique
  4. Merged Queries : permet de faire une jointure entre le référentiel des types de voie et la table structure.

Un autre point à mentionner est que, dans le fichier fournit, le type de voie est donné sous la forme d’un référentiel qui n’est pas fourni. Pour le construire relativement rapidement, il suffit d’utiliser un tableur et de sélectionner l’ensemble des valeurs distincte de la colonne typvoie. Une fois la sélection obtenue, il est possible de créer son propre référentiel après avoir complété l’ensemble des libellés associés.

 

Nous obtenons donc 3 fichiers qu’il est possible le lier par la suite dans l’écran de modélisation.

Un dernier point de détail concerne le widget utilisé pour la localisation des établissements. Celui fonctionne à l’aide des adresses postales. L’inconvénient est quand le fichier fourni, l’adresse est éclaté dans plusieurs champs. Un moyen simple pour contourner ce problème est d’ajouter une colonne calculée à notre table, regroupant l’ensemble des champs devant être joint. On peut voir dans cette formule l’utilisation du référentiel sur le type de voie et l’ajout, en dur, du pays. Le fichier étant localisé par nature, il ne contient pas la notion de pays.

En conclusion, nous obtenons l’ensemble des établissements de santé, géolocalisées, dans des listes filtrables.