Un cadavre exquis pour découvrir le travail collaboratif Git

Ce chapitre propose une mise en application de quelques principes centraux du langage Git vus précédemment.

Exercice
Git
Auteur·rice

Lino Galiana

Date de publication

2024-11-20

1 Un cadavre exquis pour découvrir le travail collaboratif

Jusqu’à présent, nous avons découvert les vertus de Git dans un projet individuel. Nous allons maintenant aller plus loin dans un projet collectif. Pour rappel, dans le chapitre précédent nous avons évoqué les concepts natifs de Git que sont dépôts local et distant (remote), l’opération de clone, staging area, commit, push, pull, les branches. Nous avons aussi évoqué certains concepts liés à la forge Github que sont l’authentification et les issues.

Maintenant, nous allons évoquer les enjeux liés au travail collaboratif, ce qui nous amènera, notamment, à évoquer les enjeux de la gestion de conflits.

2 Le workflow adopté

Nous allons adopter le mode de travail le plus simple, le Github flow. Nous l’avons déjà adopté lors du dernier exercice du chapitre précédent, consacré à l’utilisation des branches.

Le Github flow correspond à cette forme caractéristique d’arbre:

  1. La branche main constitue le tronc
  2. Les branches partent de main et divergent
  3. Lorsque les modifications aboutissent, elles sont intégrées à main ; la branche en question disparaît :

Des workflows plus complexes existent pour les projets de grande envergure.

Il existe des workflows plus complexes, notamment le Git Flow que j’utilise pour développer ce cours. Ce tutoriel, très bien fait, illustre avec un graphique la complexité accrue de ce flow :

Cette fois, une branche intermédiaire, par exemple une branche development, intègre des modifications à tester avant de les intégrer dans la version officielle (main).

Tip

Vous pourrez trouvez des dizaines d’articles et d’ouvrages sur ce sujet dont chacun prétend avoir trouvé la meilleure organisation du travail (Git flow, GitHub flow, GitLab flow…). Ne lisez pas trop ces livres et articles sinon vous serez perdus (un peu comme avec les magazines destinés aux jeunes parents…).

La méthode de travail la plus simple est le Github flow qu’on vous a proposé d’adopter. L’arborescence est reconnaissable : des branches divergent et reviennent systématiquement vers main.

Pour des projets plus complexes dans des équipes développant des applications, on pourra utiliser d’autres méthodes de travail, notamment le Git flow. Il n’existe pas de règles universelles pour déterminer la méthode de travail ; l’important c’est, avant tout, de se mettre d’accord sur des règles communes de travail avec votre équipe.

2.1 Les conflits

Au cours du dernier exercice du chapitre précédent, nous avons, sans vraiment l’expliquer, découvert le principe du merge (ou fusion, en Français). Les fusions de versions consistent à réconcilier deux versions d’un code. Cela peut se faire en privilégiant l’une sur l’autre ou bien en choisissant, dans les passages qui divergent, parfois l’une et parfois l’autre. On parle de conflits pour désigner une situation où un même fichier présente deux versions différentes qui doivent être réconciliées.

Git simplifie énormément la gestion de conflits, c’est l’une des raisons de son succès. Si vous avez déjà partagé du code par mail en équipe, vous devez savoir que réconcilier des versions est extrêmement fastidieux : il faut, plus ou moins ligne à ligne, vérifier que la version que vous avez reçu par mail ne diffère pas de la vôtre, que vous avez fait évoluer en parallèle. Grâce au suivi fin de l’évolution d’un fichier que permet Git, cette gestion de conflits sera facilitée. Il faudra tout de même privilégier une version sur l’autre mais cela sera plus rapide et plus fiable.

Si Git offre des fonctionnalités intéressantes, pour la gestion des conflits, ce n’est néanmoins pas une excuse pour être désorganisé. Comme nous allons le voir dans les prochains exercices, on a certes des chapitres

Méthode pour les merges

Lors du chapitre précédent, nous avons fait un merge de notre branche issue-1 vers main, notre branche principale. Nous sommes passés par l’interface de Github pour faire cela. Il s’agit de la méthode recommandée pour les merges vers main. Cela permet de garder une trace explicite de ceux-ci (par exemple ici), sans avoir à chercher dans l’arborescence, parfois complexe, d’un projet.

La bonne pratique veut qu’on fasse un squash commit pour éviter une inflation du nombre de commits dans main: les branches ont vocation à proposer une multitude de petits commits, les modifications dans main doivent être simples à tracer d’où le fait de modifier des petits bouts de code.

Comme on l’a fait dans un exercice précédent, il est très pratique d’ajouter dans le corps du message close #xxxx est le numéro d’une issue associée à la pull request. Lorsque la pull request sera fusionnée, l’issue sera automatiquement fermée et un lien sera créé entre l’issue et la pull request. Cela vous permettra de comprendre, plusieurs mois ou années plus tard comment et pourquoi telle ou telle fonctionnalité a été implémentée.

En revanche, l’intégration des dernières modifications de main vers une branche se fait en local. Si votre branche est en conflit, le conflit doit être résolu dans la branche et pas dans main. main doit toujours rester propre.

2.2 Divergence d’historique: les différentes situations

2.2.1 Cas simple

Imaginons deux personnes qui collaborent sur un projet, Alice et Bob. Bob a mis de côté le projet quelques jours. Il veut récupérer les avancées faites par Alice pendant cette période. Celle-ci a fait évoluer le projet, supposons avec un seul commit puisque cela ne change rien.

Figure 2.1: Historique de Bob en retard (cas simple)

L’historique de Bob est cohérent avec celui sur Github, il lui manque juste le dernier commit en bleu (Figure 2.1). Il suffit donc à Bob de récupérer ce commit en local avant de commencer à éditer ses fichiers.

Ce type de fusion est un fast-forward merge. Le commit distant est rajouté à l’historique local, sans difficulté. Le dépôt local est à nouveau à jour avec le dépôt distant.

Il s’agit du merge idéal car celui-ci peut être automatisé, il n’y a aucun risque d’écraser des modifications faites par Bob par celles d’Alice. Une organisation d’équipe adéquate permettra de s’assurer que la plupart des merges seront de ce type.

2.2.2 Cas plus compliqué

Maintenant, imaginons le cas plus compliqué où Bob avait fait évoluer son code en parallèle, sans récupérer les modifications d’Alice avant de revenir sur le projet.

Son historique local diverge donc de l’historique distant:

Figure 2.2: Historique de Bob en retard (cas plus compliqué)

Les derniers commits ne sont pas les mêmes. Git ne peut pas résoudre de lui-même la divergence. C’est à Bob de trancher sur la version qu’il préfère. Deux stratégies pour réconcilier les historiques sont accessibles:

  • Le merge ;
  • Le rebase.

La première méthode, la plus simple, est le merge.

Figure 2.3: Historique de Bob en retard: résolution par merge

Le rapatriement des modifications d’Alice dans l’historique de Bob crée un premier commit de merge. Les fichiers en question présenteront alors des balises permettant d’identifier la divergence de version et la source de celle-ci. Dans le fichier brut, cela donnera

import pandas as pd

<<<<<<< main
toto = pd.read_csv("source.csv")
=======
toto = pd.read_csv("source.csv", sep = ";")
>>>>>>> zyx911fhjehzafoldfkjknvjnvjnj;

toto.head(2)

VSCode, grâce à l’extension Git, propose une visualisation native de ce bout de code et propose, en clique-bouton, différentes manières de réconcilier les versions. Il est bien sûr toujours possible d’éditer ces fichiers : il suffit de supprimer les balises et modifier les lignes en question.

Figure 2.4: Les conflits dans VSCode

Une fois les versions réconciliées, il ne reste plus qu’à faire un nouveau commit. Cette histoire réconcilie les versions d’Alice et Bob. L’inconvénient est qu’elle rend l’historique non linéaire (voir la documentation d’Atlassian pour plus de détails) mais c’est Git qui a géré automatiquement ce sujet en créant une branche temporaire. Jusqu’à récemment, ceci était le comportement par défaut de Git.

Une autre approche est accessible, le rebase. In fine ceci va correspondre à cet historique, propre.

Figure 2.5

Néanmoins ceci implique des étapes intermédiaires qui consistent à réécrire l’historique, ce qui est déjà une opération avancée. En fait, Git effectue trois étapes:

  1. Supprime temporairement le commit local
  2. Réalise un fast forward merge maintenant que le commit local n’est plus là
  3. Rajoute le commit local au bout de l’historique
Figure 2.6

Le commit local a changé d’identité, ce qui explique son nouveau SHA. Cette approche présente l’avantage de garder un historique linéaire. Néanmoins, elle peut avoir des effects de bord et est donc à utiliser avec précaution (plus d’explications dans la documentation de Git). Quand on débute, et même après, il est recommandé de privilégier la méthode merge. Pour cela, en ligne de commande, il faut taper la commande

git config pull.rebase false

3 Mise en pratique

Exercice 1 : Interactions avec le dépôt distant

Cet exercice se fait par groupe de trois ou quatre. Il y aura deux rôles dans ce scénario :

  • Une personne aura la responsabilité d’être mainteneur
  • Deux à trois personnes seront développeurs.

1️⃣ Le.la mainteneur.e crée un dépôt sur Github sans cliquer sur l’option Add a README. Créer un .gitignore selon le modèle Python. Il/Elle donne des droits au(x) développeur.euse(s) du projet (Settings > Manage Access > Invite a collaborator).

2️⃣ Chaque membre du projet, crée une copie locale du projet (un clone). Si vous avez un trou de mémoire, vous pouvez retourner au chapitre précédent pour vérifier la démarche.

3️⃣ Chaque membre du projet crée un fichier avec son nom et son prénom, selon cette structure nom-prenom.md en évitant les caractères spéciaux. Il écrit dedans trois phrases de son choix sans ponctuation ni majuscules (pour pouvoir effectuer une correction ultérieurement). Enfin, il commit sur le projet par le biais de l’extension visuelle.

En ligne de commande cela donnerait les commandes équivalentes

git add nom-prenom.md
git commit -m "C'est l'histoire de XXXXX"

4️⃣ Chacun essaie d’envoyer (push) ses modifications locales sur le dépôt en passant par les boutons adéquats de l’extension visuelle.

En ligne de commande cela donnerait la commande équivalente

git push origin main

5️⃣ A ce stade, une seule personne (la plus rapide) devrait ne pas avoir rencontré de rejet du push. C’est normal, avant d’accepter une modification Git vérifie en premier lieu la cohérence de la branche avec le dépôt distant. Le premier ayant fait un push a modifié le dépôt commun ; les autres doivent intégrer ces modifications dans leur version locale (pull) avant d’avoir le droit de proposer un changement.

Pour celui/celle/ceux dont le push a été refusé, il faudra faire un pull. Faire celui-ci en utilisant l’extension graphique de VSCode.

En ligne de commande cela donnerait la commande équivalente

git pull origin main

pour essayer de ramener les modifications distantes en local. Celui-ci devrait échouer et les options affichées par VSCode ne devraient pas vous permettre de résoudre le problème, seulement de le comprendre. En cliquant sur Show command output, vous devriez voir s’afficher le message suivant:

hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

Dans un terminal ((☰ > Terminal > New Terminal), copier la règle git config pull.rebase false qui est recommandée lorsqu’on débute dans Git (et même quand on est plus à l’aise).

6️⃣ Regarder l’arbre obtenu dans l’interface pour comprendre comment a été intégrée la modification de votre camarade ayant pu faire son push avant.

Vous remarquerez que les commits de vos camarades sont intégrés tels quels à l’histoire du dépôt.

7️⃣ Faire à nouveau un push. C’est fini pour la 2e personne. La dernière personne doit refaire, à nouveau, les étapes 5 à 7 (dans une équipe de quatre il faudra encore le refaire une fois).

❓ Question : que se serait-il passé si les différents membres du groupe avaient effectué leurs modifications sur un seul et même fichier ?

Le prochain exercice offre une réponse à cette question.

Exercice 2 : Gérer les conflits quand on travaille sur le même fichier

Dans la continuité de l’exercice précédent, chaque personne va travailler sur les fichiers des autres membres de l’équipe.

1️⃣ Les deux ou trois développeurs ajoutent la ponctuation et les majuscules du fichier du premier développeur.

2️⃣ Ils sautent une ligne et ajoutent une phrase (pas tous la même).

3️⃣ Valider les résultats avec un commit et faire un push.

4️⃣ La personne la plus rapide n’a, normalement, rencontré aucune difficulté (elle peut s’arrêter temporairement pour regarder ce qui va se passer chez les voisins). Les autres voient leur push refusé et doivent faire un pull.

💥 Il y a conflit, ce qui doit être signalé par un message du type :

Auto-merging XXXXXX
CONFLICT (content): Merge conflict in XXXXXX.md
Automatic merge failed; fix conflicts and then commit the result.

5️⃣ Etudier le résultat de git status

6️⃣ Si vous ouvrez les fichiers incriminés, vous devriez voir des balises du type

<<<<<<< HEAD
this is some content to mess with
content to append
=======
totally different content to merge later
>>>>>>> new_branch_to_merge_later

qui sont mises en forme par VSCode comme dans la Figure 2.4.

7️⃣ Corriger les fichiers en choisissant, pour chaque bloc, la version qui vous convient grâce aux actions permises par Git (Accept Current Change…)

Faire un commit avec le titre “Résolution du conflit par XXXX” où XXXX est votre nom.

8️⃣ Faire un push. Pour la dernière personne, refaire les opérations 4 à 8

Git permet donc de travailler, en même temps, sur le même fichier et de limiter le nombre de gestes manuels nécessaires pour faire la fusion. Lorsqu’on travaille sur des bouts différents du même fichier, on n’a même pas besoin de faire de modification manuelle, la fusion peut être automatique.

Git est un outil très puissant. Mais, il ne remplace pas une bonne organisation du travail. Vous l’avez vu, ce mode de travail uniquement sur main peut être pénible. Les branches prennent tout leur sens dans ce cas.

Exercice 3 : Gestion des branches
1️⃣ Le.la mainteneur.euse va contribuer directement dans main et ne crée pas de branche. Chaque développeur crée une branche, en local nommée contrib-XXXXXXXXXX est le prénom. Pour cela, dans l’interface de VSCode, cliquer sur ... > Branch > Create branch et mettre le nom de la branche dans le menu adéquat

En ligne de commande cela donnerait la commande équivalente

git checkout -b contrib-XXXXX

2️⃣ Chaque membre du groupe crée un fichier README.md où il écrit une phrase sujet-verbe-complément. Le mainteneur est le seul à ajouter un titre dans le README (qu’il commit dans main).

3️⃣ Chacun push le produit de son subconscient sur le dépôt.

4️⃣ Les développeurs.euses ouvrent, chacun, une pull request sur Github. Le sens à choisir est branche -> main. Les développeurs.euses donnent un titre explicite à cette pull request.

Le/la mainteneur.euse choisit une des pull request et la valide avec l’option squash commits. Vérifier sur la page d’accueil le résultat.

5️⃣ Chaque développeur revient sur main en cliquant sur ... > Checkout to et en choisissant main. Faire un pull.

6️⃣ Revenir sur votre branche et faire ... > Branch > Merge et choisir main. Regarder l’arbre obtenu.

7️⃣ L’auteur (si 2 développeurs) ou les deux auteurs (si 3 développeurs) de la pull request non validée doivent à nouveau répéter les opérations 5 et 6.

8️⃣ Une fois le conflit de version réglé et poussé, le mainteneur valide la pull request selon la même procédure que précédemment.

9️⃣ Vérifier l’arborescence du dépôt dans Insights > Network. Votre arbre doit avoir une forme caractéristique de ce qu’on appelle le Github flow:

Il n’est absolument pas obligatoire que chaque projet collaboratif choisisse ce mode de collaboration. Pour de nombreux projets, où on édite pas le même bout de fichier en même temps, passer directement par main est suffisant. Le mode ci-dessus est important pour des projets conséquents, où la branche main se doit d’être irréprochable parce que, par exemple, elle entraîne une série de tests automatisés et le déploiement automatisé d’un livrable. Mais pour des projets plus modestes, il n’est pas indispensable d’aller dans un formalisme extrême. Le bon usage de Git est un usage pragmatique où celui-ci est utilisé pour ses avantages et où l’organisation du travail s’adapte à ceux-ci.

4 Les enjeux spécifiques liés à l’interaction difficile entre Git et les notebooks

Le format notebook est très intéressant pour l’expérimentation et la diffusion finale de résultats. Néanmoins, la structure complexe d’un notebook rend compliquée le contrôle de version. En effet, l’ouverture dans un éditeur adapté (Jupyter ou VSCode) offre une mise en forme qui ne correspond pas à la structure brute du fichier, tel qu’il est stocké sur le disque. En arrière plan, les notebooks sont des JSON qui embarquent de nombreux éléments: code, résultats d’exécution, métadonnées annexes… Le suivi fin des modifications du fichier permis par Git est compliqué sur un fichier ayant une telle structure. L’objectif de cet exercice est d’illustrer ces enjeux et évoque quelques solutions possibles.

Exercice 4 : Contrôle de version et notebooks, un ménage difficile

Cet exercice se fait toujours en équipe. Lorsqu’il est demandé de faire un commit, lui donner un nom signifiant pour s’y retrouver facilement quand il est demandé de regarder l’historique. Ne pas faire de push ou pull avant d’en arriver à la partie où cela est demandé.

  1. Tous les membres de l’équipe reviennent à leur branche main sur leur copie de travail

Chaque membre de l’équipe fait les questions suivantes.

  1. Mesurer le poids de l’ensemble de l’historique en ligne de commande avec la commande
du -sh .git
  1. Télécharger le notebook servant à cet exercice avant la commande suivante, en ligne de commande:
curl "https://minio.lab.sspcloud.fr/lgaliana/python-ENSAE/inputs/git/exemple.ipynb" -o "notebook.ipynb"
  • Ne pas ouvrir ce fichier (objet de la prochaine question).

  • Faire un commit de ce notebook puis refaire

du -sh .git
  • Observez le premier changement de poids de notre historique
  1. Ouvrir le notebook, exécuter ses cellules en les réordonnant si nécessaire pour débugger le fichier.
  • Faire un commit de ce notebook quand il fonctionne puis refaire
du -sh .git
  1. Maintenant, faire les modifications suivantes du fichier:
    • Modifier la cellule df.head(3) en df.head(20)
    • Créer une nouvelle cellule avec le code df["TYPEQU"].value_counts().plot(kind = "bar")
    • Modifier la variable zoom_start dans la cellule produisant la carte interactive. Fixer sa valeur à 13 plutôt que 15.
  • Faire un commit de ce notebook quand il fonctionne puis refaire
du -sh .git
  1. Changer la couleur du barplot avec l’argument color. Sauvegarder, committer puis refaire
du -sh .git
  1. Regarder l’historique depuis l’extension VSCode. Observer la manière dont évolue votre fichier à chaque commit.

Maintenant, nous pouvons passer à l’étape collaborative.

  1. Chaque membre de l’équipe push:
  • Si le push fonctionne (personne la plus rapide), modifier à nouveau à nouveau la couleur du barplot. Committer mais ne pas pusher (attendre que les autres membres du groupe l’ait fait puis passer à la question 9)
  • Si le push ne fonctionne pas (personnes moins rapides), passer à la question 9.
  1. Dans l’extension VSCode, afficher l’arbre en cliquant sur le bouton View Git Graph.
  • En haut de celui-ci, cliquer sur Uncommitted changes. Cela affiche les modifications qui ne sont pas encore acceptées.
  • Cliquer sur notebook.ipynb pour voir le diff entre votre version et celle de votre camarade. Comprenez-vous le problème ?
  • Accepter à la main chaque différence serait trop coûteux. Accepter la version de votre camarade (Accept incoming). Committer et observer le diff. Pusher.

Pour la dernière personne du groupe n’ayant pas pu pusher, refaire la question 9. Après avoir pushé, la personne ayant été la plus rapide à la question 8 peut faire la question 9 en récupérant les derniers commits.

Cet exercice permet d’illustrer trois points de difficultés avec les notebooks:

  • La taille des fichiers ipynb devient vite importante car les outputs sont insérés dedans, de manière brute.
  • Il devient vite difficile de suivre les changements du code car celui-ci est noyé au milieu d’autres modifications (notamment celles des outputs).
  • La résolution de conflits est compliquée car il faut garder la structure JSON. Il est d’ailleurs fréquent qu’un merge casse cette structure et rende le notebook illisible.

Pour régler ces problèmes, il existe plusieurs méthodes:

  • Si on désire rester sur le notebook comme endroit où est stocké le code, il faut cliquer sur le bouton Clear all outputs avant de faire une étape git add. Le package nbstripout peut être une solution intéressante pour ne pas avoir à le faire manuellement à chaque fois car on prend le risque d’oublier et donc de faire quand même grossir la taille du dépôt. Néanmoins, cette approche ne règle qu’une partie des problèmes puisqu’elle ne fait qu’alléger le JSON versionné, elle rend moins probable mais ne rend pas impossible le risque de casser le notebook lors d’une résolution de conflit.
  • Travailler en équipe sur des notebooks différents comme ceci était conseillé pour les fichiers texte. Cela permet de ne plus avoir de conflit. Cependant, cela risque d’induire des redondances de code et donc des problèmes ultérieurement si on désire synthétiser les différents travaux.
  • Adopter une structure plus modulaire en déportant le maximum de code dans des fichiers .py et en important les éléments adéquats dans les notebooks. Ceci permet de tirer avantage de Git, qui suit très bien les fichiers .py, tout en offrant des bénéfices sur la qualité des notebooks. En étant moins monolithiques, ils seront probablement de meilleure qualité.

Cette dernière approche est une manière de s’ouvrir aux bonnes pratiques qui sont évoquées dans le cours de 3e année de “Mise en production”.

5 Conclusion

Ces chapitres consacrés à Git ont permis de démystifier ce logiciel en illustrant, par la pratique, les principaux concepts et la gymnastique quotidienne. Ils visent à faire économiser de précieuses heures car l’apprentissage de Git en autodidacte est souvent frustrant et incomplet. Il est indispensable de garder cette habitude de faire du Git sur ses projets. Ces derniers seront de meilleure qualité.

Nous n’avons vu que les fonctionnalités basiques de Git et de Github. L’objet du cours de 3e année de l’ENSAE de “Mise en production de projets data science est de faire découvrir d’autres fonctionnalités de Git et Github qui permettent de produire des projets plus ambitieux, plus fiables et plus évolutifs.

Informations additionnelles

environment files have been tested on.

Latest built version: 2024-11-20

Python version used:

'3.12.6 | packaged by conda-forge | (main, Sep 30 2024, 18:08:52) [GCC 13.3.0]'
Package Version
affine 2.4.0
aiobotocore 2.15.1
aiohappyeyeballs 2.4.3
aiohttp 3.10.8
aioitertools 0.12.0
aiosignal 1.3.1
alembic 1.13.3
altair 5.4.1
aniso8601 9.0.1
annotated-types 0.7.0
appdirs 1.4.4
archspec 0.2.3
asttokens 2.4.1
attrs 24.2.0
babel 2.16.0
bcrypt 4.2.0
beautifulsoup4 4.12.3
black 24.8.0
blinker 1.8.2
blis 0.7.11
bokeh 3.5.2
boltons 24.0.0
boto3 1.35.23
botocore 1.35.23
branca 0.7.2
Brotli 1.1.0
cachetools 5.5.0
cartiflette 0.0.2
Cartopy 0.24.1
catalogue 2.0.10
cattrs 24.1.2
certifi 2024.8.30
cffi 1.17.1
charset-normalizer 3.3.2
click 8.1.7
click-plugins 1.1.1
cligj 0.7.2
cloudpathlib 0.20.0
cloudpickle 3.0.0
colorama 0.4.6
comm 0.2.2
commonmark 0.9.1
conda 24.9.1
conda-libmamba-solver 24.7.0
conda-package-handling 2.3.0
conda_package_streaming 0.10.0
confection 0.1.5
contextily 1.6.2
contourpy 1.3.0
cryptography 43.0.1
cycler 0.12.1
cymem 2.0.8
cytoolz 1.0.0
dask 2024.9.1
dask-expr 1.1.15
databricks-sdk 0.33.0
debugpy 1.8.6
decorator 5.1.1
Deprecated 1.2.14
diskcache 5.6.3
distributed 2024.9.1
distro 1.9.0
docker 7.1.0
duckdb 0.10.1
en-core-web-sm 3.7.1
entrypoints 0.4
et_xmlfile 2.0.0
exceptiongroup 1.2.2
executing 2.1.0
fastexcel 0.11.6
fastjsonschema 2.20.0
fiona 1.10.1
Flask 3.0.3
folium 0.17.0
fontawesomefree 6.6.0
fonttools 4.54.1
frozendict 2.4.4
frozenlist 1.4.1
fsspec 2023.12.2
gensim 4.3.2
geographiclib 2.0
geopandas 1.0.1
geoplot 0.5.1
geopy 2.4.1
gitdb 4.0.11
GitPython 3.1.43
google-auth 2.35.0
graphene 3.3
graphql-core 3.2.4
graphql-relay 3.2.0
graphviz 0.20.3
great-tables 0.12.0
greenlet 3.1.1
gunicorn 22.0.0
h2 4.1.0
hpack 4.0.0
htmltools 0.6.0
hyperframe 6.0.1
idna 3.10
imageio 2.36.0
importlib_metadata 8.5.0
importlib_resources 6.4.5
inflate64 1.0.0
ipykernel 6.29.5
ipython 8.28.0
itsdangerous 2.2.0
jedi 0.19.1
Jinja2 3.1.4
jmespath 1.0.1
joblib 1.4.2
jsonpatch 1.33
jsonpointer 3.0.0
jsonschema 4.23.0
jsonschema-specifications 2024.10.1
jupyter-cache 1.0.0
jupyter_client 8.6.3
jupyter_core 5.7.2
kaleido 0.2.1
kiwisolver 1.4.7
langcodes 3.5.0
language_data 1.3.0
lazy_loader 0.4
libmambapy 1.5.9
locket 1.0.0
lxml 5.3.0
lz4 4.3.3
Mako 1.3.5
mamba 1.5.9
mapclassify 2.8.1
marisa-trie 1.2.1
Markdown 3.6
markdown-it-py 3.0.0
MarkupSafe 2.1.5
matplotlib 3.9.2
matplotlib-inline 0.1.7
mdurl 0.1.2
menuinst 2.1.2
mercantile 1.2.1
mizani 0.11.4
mlflow 2.16.2
mlflow-skinny 2.16.2
msgpack 1.1.0
multidict 6.1.0
multivolumefile 0.2.3
munkres 1.1.4
murmurhash 1.0.10
mypy-extensions 1.0.0
narwhals 1.14.1
nbclient 0.10.0
nbformat 5.10.4
nest_asyncio 1.6.0
networkx 3.3
nltk 3.9.1
numpy 1.26.4
opencv-python-headless 4.10.0.84
openpyxl 3.1.5
opentelemetry-api 1.16.0
opentelemetry-sdk 1.16.0
opentelemetry-semantic-conventions 0.37b0
OWSLib 0.28.1
packaging 24.1
pandas 2.2.3
paramiko 3.5.0
parso 0.8.4
partd 1.4.2
pathspec 0.12.1
patsy 0.5.6
Pebble 5.0.7
pexpect 4.9.0
pickleshare 0.7.5
pillow 10.4.0
pip 24.2
platformdirs 4.3.6
plotly 5.24.1
plotnine 0.13.6
pluggy 1.5.0
polars 1.8.2
preshed 3.0.9
prometheus_client 0.21.0
prometheus_flask_exporter 0.23.1
prompt_toolkit 3.0.48
protobuf 4.25.3
psutil 6.0.0
ptyprocess 0.7.0
pure_eval 0.2.3
py7zr 0.20.8
pyarrow 17.0.0
pyarrow-hotfix 0.6
pyasn1 0.6.1
pyasn1_modules 0.4.1
pybcj 1.0.2
pycosat 0.6.6
pycparser 2.22
pycryptodomex 3.21.0
pydantic 2.9.2
pydantic_core 2.23.4
Pygments 2.18.0
PyNaCl 1.5.0
pynsee 0.1.8
pyogrio 0.10.0
pyOpenSSL 24.2.1
pyparsing 3.1.4
pyppmd 1.1.0
pyproj 3.7.0
pyshp 2.3.1
PySocks 1.7.1
python-dateutil 2.9.0
python-dotenv 1.0.1
python-magic 0.4.27
pytz 2024.1
pyu2f 0.1.5
pywaffle 1.1.1
PyYAML 6.0.2
pyzmq 26.2.0
pyzstd 0.16.2
querystring_parser 1.2.4
rasterio 1.4.2
referencing 0.35.1
regex 2024.9.11
requests 2.32.3
requests-cache 1.2.1
retrying 1.3.4
rich 13.9.4
rpds-py 0.21.0
rsa 4.9
ruamel.yaml 0.18.6
ruamel.yaml.clib 0.2.8
s3fs 2023.12.2
s3transfer 0.10.2
scikit-image 0.24.0
scikit-learn 1.5.2
scipy 1.13.0
seaborn 0.13.2
setuptools 74.1.2
shapely 2.0.6
shellingham 1.5.4
six 1.16.0
smart-open 7.0.5
smmap 5.0.0
sortedcontainers 2.4.0
soupsieve 2.5
spacy 3.7.5
spacy-legacy 3.0.12
spacy-loggers 1.0.5
SQLAlchemy 2.0.35
sqlparse 0.5.1
srsly 2.4.8
stack-data 0.6.2
statsmodels 0.14.4
tabulate 0.9.0
tblib 3.0.0
tenacity 9.0.0
texttable 1.7.0
thinc 8.2.5
threadpoolctl 3.5.0
tifffile 2024.9.20
toolz 1.0.0
topojson 1.9
tornado 6.4.1
tqdm 4.66.5
traitlets 5.14.3
truststore 0.9.2
typer 0.13.1
typing_extensions 4.12.2
tzdata 2024.2
Unidecode 1.3.8
url-normalize 1.4.3
urllib3 1.26.20
wasabi 1.1.3
wcwidth 0.2.13
weasel 0.4.1
webdriver-manager 4.0.2
websocket-client 1.8.0
Werkzeug 3.0.4
wheel 0.44.0
wordcloud 1.9.3
wrapt 1.16.0
xgboost 2.1.1
xlrd 2.0.1
xyzservices 2024.9.0
yarl 1.13.1
yellowbrick 1.5
zict 3.0.0
zipp 3.20.2
zstandard 0.23.0

View file history

SHA Date Author Description
1202a02 2024-10-22 11:25:10 Lino Galiana Git, modifs suite au cours de 2024 (#568)
00f28a3 2024-10-15 13:41:20 lgaliana Ajoute questions collaboratifs Git
e0fa908 2024-10-12 13:50:16 lgaliana Mise en forme exogit
adc4657 2024-10-11 17:17:25 lgaliana color
288bd4a 2024-10-11 17:16:19 lgaliana Interface graphique pour l’exo 3 également
25ca332 2024-10-11 16:38:02 lgaliana Retirer ligne de commande
20672a4 2024-10-11 13:11:20 Lino Galiana Quelques correctifs supplémentaires sur Git et mercator (#566)
3e04253 2024-09-30 10:11:32 Lino Galiana Grosse mise à jour de la partie Git (#557)
580cba7 2024-08-07 18:59:35 Lino Galiana Multilingual version as quarto profile (#533)
005d89b 2023-12-20 17:23:04 Lino Galiana Finalise l’affichage des statistiques Git (#478)
4c1c22d 2023-12-10 11:50:56 Lino Galiana Badge en javascript plutôt (#469)
1f23de2 2023-12-01 17:25:36 Lino Galiana Stockage des images sur S3 (#466)
a06a268 2023-11-23 18:23:28 Antoine Palazzolo 2ème relectures chapitres ML (#457)
56d092b 2023-11-14 15:43:00 Antoine Palazzolo update readme (#451)
09654c7 2023-11-14 15:16:44 Antoine Palazzolo Suggestions Git & Visualisation (#449)
b6ae3e3 2023-11-14 05:49:42 linogaliana Corrige balise md
ae5205f 2023-11-13 20:35:43 linogaliana précision
428d669 2023-11-13 20:31:11 linogaliana Exo gitignore
66c6a29 2023-11-13 19:53:49 linogaliana jupyter sspcloud credential helper
69d5bc7 2023-11-13 19:44:01 linogaliana mise à jour de quelques consignes
e3f1ef1 2023-11-13 11:53:50 Thomas Faria Relecture git (#448)
ea9400a 2023-11-05 10:54:04 tomseimandi Include VSCode instructions in exogit (#447)
9366e8d 2023-10-09 12:06:23 Lino Galiana Retrait des box hugo sur l’exo git (#428)
a771183 2023-10-09 11:27:45 Antoine Palazzolo Relecture TD2 par Antoine (#418)
f8831e7 2023-10-09 10:53:34 Lino Galiana Relecture antuki geopandas (#429)
5ab34aa 2023-10-04 14:54:20 Kim A Relecture Kim pandas & git (#416)
154f09e 2023-09-26 14:59:11 Antoine Palazzolo Des typos corrigées par Antoine (#411)
b649205 2023-08-28 15:47:09 linogaliana Nice image
9a4e226 2023-08-28 17:11:52 Lino Galiana Action to check URL still exist (#399)
3bdf3b0 2023-08-25 11:23:02 Lino Galiana Simplification de la structure 🤓 (#393)
30823c4 2023-08-24 14:30:55 Lino Galiana Liens morts navbar (#392)
2dbf853 2023-07-05 11:21:40 Lino Galiana Add nice featured images (#368)
34cc32c 2022-10-14 22:05:47 Lino Galiana Relecture Git (#300)
fd439f0 2022-09-19 09:37:50 avouacr fix ssp cloud links
3056d41 2022-09-02 12:19:55 avouacr fix all SSP Cloud launcher links
f10815b 2022-08-25 16:00:03 Lino Galiana Notebooks should now look more beautiful (#260)
12965ba 2022-05-25 15:53:27 Lino Galiana :launch: Bascule vers quarto (#226)
9c71d6e 2022-03-08 10:34:26 Lino Galiana Plus d’éléments sur S3 (#218)
0e01c33 2021-11-10 12:09:22 Lino Galiana Relecture @antuki API+Webscraping + Git (#178)
9a3f7ad 2021-10-31 18:36:25 Lino Galiana Nettoyage partie API + Git (#170)
2f4d390 2021-09-02 15:12:29 Lino Galiana Utilise un shortcode github (#131)
4cdb759 2021-05-12 10:37:23 Lino Galiana :sparkles: :star2: Nouveau thème hugo :snake: :fire: (#105)
7f9f97b 2021-04-30 21:44:04 Lino Galiana 🐳 + 🐍 New workflow (docker 🐳) and new dataset for modelization (2020 🇺🇸 elections) (#99)
36ed7b1 2020-10-07 12:36:03 Lino Galiana Cadavre exquis (#66)
d1ad64c 2020-10-04 14:43:55 Lino Galiana Finalisation de la première partie de l’exo git (#62)
283e8e9 2020-10-02 18:54:30 Lino Galiana Première partie des exos git (#61)
Retour au sommet

Citation

BibTeX
@book{galiana2023,
  author = {Galiana, Lino},
  title = {Python pour la data science},
  date = {2023},
  url = {https://pythonds.linogaliana.fr/},
  doi = {10.5281/zenodo.8229676},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
Galiana, Lino. 2023. Python pour la data science. https://doi.org/10.5281/zenodo.8229676.