Git : un élément essentiel au quotidien

Git est un système de contrôle de version qui facilite la sauvegarde, la gestion des évolutions et le partage d’un projet informatique. Il s’agit d’un élément devenu indispensable dans le domaine de la data science. Ce chapitre présente quelques concepts qui seront mis en pratique dans le suivant.

Tutoriel
Git
Author

Lino Galiana

Published

2024-04-27

Cette page reprend des éléments présents dans un cours dédié fait avec Romain Avouac.

1 Pourquoi faire du Git ?

1.1 Les problèmes classiques

Dans un projet, il est commun de se demander (ou de demander à quelqu’un) :

  • quelle était la bonne version d’un programme ?
  • qui était l’auteur d’un bout de code en particulier ?
  • si un changement était important ou juste un essai ?
  • où retrouver des traces d’un vieil essai abandonné mais potentiellement finalement prometteur ?
  • comment fusionner des programmes écrits par plusieurs personnes ?
  • etc.

1.2 La solution: le contrôle de version

Il existe un outil informatique puissant qui répond à tous ces besoins : la gestion de version (version control system (VCS) en anglais). Ses avantages sont incontestables et permettent de facilement :

  • enregistrer l’historique des modifications d’un ensemble de fichiers ;
  • revenir à des versions précédentes d’un ou plusieurs fichiers ;
  • rechercher les modifications qui ont pu créer des erreurs ;
  • partager ses modifications et récupérer celles des autres ;
  • proposer des modifications, les discuter, sans pour autant modifier d’emblée la dernière version existante ;
  • identifier les auteurs et la date des modifications.

En outre, ces outils fonctionnent avec tous les langages informatiques (texte, R, Python, Markdown, LaTeX, Java, etc.) car reposent sur la comparaison des lignes et des caractères des programmes.

1.3 Avantages du contrôle de version

On peut ainsi résumer les principaux avantages du contrôle de version de la manière suivante :

  1. Conserver et archiver l’ensemble des versions d’un code ou d’une documentation
  2. Travailler efficacement en équipe
  3. Améliorer la qualité des codes
  4. Simplifier la communication autour d’un projet

1.3.1 Conserver et archiver du code

Une des principales fonctionnalités de la gestion de version est de conserver l’ensemble des fichiers de façon sécurisée et de proposer un archivage structuré des codes. Les fichiers sont stockés dans un dépôt, qui constitue le projet.

Tout repose dans la gestion et la présentation de l’historique des modifications. Chaque modification (ajout, suppression ou changement) sur un ou plusieurs fichiers est identifiée par son auteur, sa date et un bref descriptif1. Chaque changement est donc unique et aisément identifiable quand les modifications sont classées par ordre chronologique. Les groupes de modifications transmis au dépôt sont appelées commit.

Avec des outils graphiques, on peut vérifier l’ ensemble des évolutions d’un fichier (history), ou l’histoire d’un dépôt. On peut aussi se concentrer sur une modification particulière d’un fichier ou vérifier, pour un fichier, la modification qui a entraîné l’apparition de telle ou telle ligne (blame)

Sur son poste de travail, les dizaines (voire centaines) de programmes organisés à la main n’existent plus. Tout est regroupé dans un seul dossier, rassemblant les éléments du dépôt. Au sein du dépôt, tout l’historique est stocké et accessible rapidement. Si on souhaite travailler sur la dernière version des programmes (ou sur une ancienne version spécifique), il n’y a plus besoin de conserver les autres fichiers car ils sont dans l’historique du projet. Il est alors possible de choisir sur quelle version on veut travailler (la dernière commune à tout le monde, la sienne en train d’être développée, celle de l’année dernière, etc.).

1.3.2 Travailler efficacement en équipe

Le deuxième avantage de la gestion de version représente une amélioration notable du travail en équipe sur des codes en commun.

La gestion de version permet de collaborer simplement et avec méthode. De façon organisée, elle permet de :

  • travailler en parallèle et fusionner facilement du code
  • partager une documentation des programmes grâce :
    • aux commentaires des modifications
    • à la possibilité d’une documentation commune et collaborative
  • trouver rapidement des erreurs et en diffuser rapidement la correction

A ces avantages s’ajoutent les fonctionalités collaboratives des forges qui sont des plateformes où peuvent être stockés des dépôts. Néanmoins, ces forges proposent aujourd’hui beaucoup de fonctionalités qui vont au-delà de l’archivage de code : interagir via des issues, faire des suggestions de modifications, exécuter du code dans des environnements normalisés, etc. Il faut vraiment les voir comme des réseaux sociaux du code. Les principales plateformes dans ce domaine étant Github et Gitlab.

L’usage individuel, c’est-à-dire seul sur son projet, permet aussi de “travailler en équipe avec soi-même” car il permet de retrouver des mois plus tard le contenu et le contexte des modifications. Cela est notamment précieux lors des changements de poste ou des travaux réguliers mais espacés dans le temps (par exemple, un mois par an chaque année). Même lorsqu’on travaille tout seul, on collabore avec un moi futur qui peut ne plus se souvenir de la modification des fichiers.

1.3.3 Améliorer la qualité des codes

Le fonctionnement de la gestion de version, reposant sur l’archivage structuré des modifications et les commentaires les accompagnant, renforce la qualité des programmes informatiques. Ils sont plus documentés, plus riches et mieux structurés. C’est pour cette raison que le contrôle de version ne doit pas être considéré comme un outil réservé à des développeurs : toute personne travaillant sur des programmes informatiques gagne à utiliser du contrôle de version.

Les services d’intégration continue permettent de faire des tests automatiques de programmes informatiques, notamment de packages, qui renforcent la réplicabilité des programmes. Mettre en place des méthodes de travail fondées sur l’intégration continue rend les programmes plus robustes en forçant ceux-ci à tourner sur des machines autres que celles du développeur du code.

1.3.4 Simplifier la communication autour d’un projet

Les sites de dépôts Github et Gitlab permettent de faire beaucoup plus que seulement archiver des codes. Les fonctionalités de déploiement en continu permettent ainsi de :

  • créer des sites web pour valoriser des projets (par exemple les sites readthedocs en python)
  • déployer de la documentation en continu
  • rendre visible la qualité d’un projet avec des services de code coverage, de tests automatiques ou d’environnements intégrés de travail (binder, etc.) qu’on rend généralement visible au moyen de badges (exemple ici)

2 Comment faire du contrôle de version ?

Il existe plusieurs manières d’utiliser le contrôle de version :

Git a initialement été conçu pour la ligne de commande. Il existe néanmoins des interfaces graphiques performantes et pratiques, notamment lorsque l’on désire comparer deux versions d’un même fichier côte à côte. Ces interfaces graphiques couvrent la majorité des besoins quotidiens. Néanmoins, pour certaines tâches, il faut nécessairement passer par la ligne de commande.

En résumé,

Avant Gestion de version
Archivage à la main automatique
Envoi de modification mail, dossier partagé code partagé
Fusion de code copié-collé simple, sûr
Versions du modèle dossiers archivés historique riche
Gestion des erreurs à la main méthodique

3 Quelques bases sur Git

3.1 Copies de travail et dépôt collectif

Git est un système décentralisé et asynchrone de gestion de version. Cela signifie que:

  • Chaque membre d’un projet travaille sur une copie locale du dépôt (système decentralisé). Cette copie de travail s’appelle un clone. Cela signifie qu’on n’a pas une cohérence en continu de notre version de travail avec le dépôt ; on peut très bien ne jamais vouloir les mettre en cohérence (par exemple, si on teste une piste qui s’avère infructueuse) ;
  • C’est lorsqu’on propose la publication de modifications sur le dépôt collectif qu’on doit s’assurer de la cohérence avec la version disponible en ligne (système asynchrone).

Le dépôt distant est généralement stocké sur une forge logicielle (Github ou Gitlab) et sert à centraliser la version collective d’un projet. Les copies locales sont des copies de travail qu’on utilise pour faire évoluer un projet :

Il est tout à fait possible de faire du contrôle de version sans mettre en place de dépôt distant. Cependant,

  • c’est dangereux puisque le dépôt distant fait office de sauvegarde d’un projet. Sans dépôt distant, on peut tout perdre en cas de problème sur la copie locale de travail ;
  • c’est désirer être moins efficace car, comme nous allons le montrer, les fonctionalités des plateformes Github et Gitlab sont également très bénéfiques lorsqu’on travaille tout seul.

3.2 Principe

Les trois manipulations les plus courantes sont les suivantes et représentées sur le diagramme ci-après :

  • commit : je valide les modifications que j’ai faites en local avec un message qui les explique
  • pull : je récupère la dernière version des codes du dépôt distant
  • push : je transmets mes modifications validées au dépôt distant

Les deux dernières manipulations correspondent aux interactions (notamment la mise en cohérence) avec le dépôt commun alors que la première manipulation commit correspond à la modification des fichiers faite pour faire évoluer un projet.

De manière plus précise, il y a trois étapes avant d’envoyer les modifications validées (commit) au dépôt. Elles se définissent en fonction des commandes qui permettent de les appliquer quand Git est utilisé en lignes de commandes :

  • diff : inspection des modifications. Cela permet de comparer les fichiers modifiés et de distinguer les fichiers ajoutés ou supprimés.
  • staging area : sélection des modifications.
  • commit : validation des modifications sélectionnées (avec commentaire).

Lors des étapes de push et pull, des conflits peuvent apparaître, par exemple lorsque deux personnes ont modifié le même programme simultanément. Le terme conflit peut faire peur mais en fait c’est l’un des apports principaux de Git que de faciliter énormément la gestion de versions différentes. Les exercices du chapitre suivant l’illustreront.

3.3 Les branches

C’est une des fonctionnalités les plus pratiques de la gestion de version. La création de branches dans un projet (qui devient ainsi un arbre) permet de développer en parallèle des correctifs ou une nouvelle fonctionnalité sans modifier le dépôt commun.

Cela permet de séparer le nouveau développement et de faire cohabiter plusieurs versions, pouvant évoluer séparément ou pouvant être facilement rassemblées. Git est optimisé pour le travail sur les branches.

Dans un projet collaboratif, une branche dite master joue le rôle du tronc. C’est autour d’elle que vont pousser ou se greffer les branches. L’un des avantages de Git est qu’on peut toujours revenir en arrière. Ce filet de sécurité permet d’oser des expérimentations, y compris au sein d’une branche. Il faut être prêt à aller dans la ligne de commande pour cela mais c’est extrêmement confortable.

4 Conseil de praticien : ne pas négliger le .gitignore

Un fichier à ne pas négliger est le .gitignore. Il s’agit d’un garde-fou car tous les fichiers (notamment des données, potentiellement volumineuses ou confidentielles) n’ont pas vocation à être partagés.

Le site gitignore.io est très pratique. Le fichier suivant est par exemple proposé pour les utilisateurs de Python, auquel on peut ajouter quelques lignes adaptées aux utilisateurs de données :

Exemple de .gitignore pour les utilisateurs de données

"""
~~~raw
*.html
*.pdf
*.csv
*.tsv
*.json
*.xml
*.shp
*.xls
*.xlsx

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
pip-wheel-metadata/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST

# PyInstaller
#  Usually these files are written by a Python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal

# Flask stuff:
instance/
.webassets-cache

# Scrapy stuff:
.scrapy

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# Jupyter Notebook
.ipynb_checkpoints

# IPython
profile_default/
ipython_config.py

# pyenv
.python-version

# pipenv
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
#   install all needed dependencies.
#Pipfile.lock

# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/

# Celery stuff
celerybeat-schedule
celerybeat.pid

# SageMath parsed files
*.sage.py

# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# Spyder project settings
.spyderproject
.spyproject

# Rope project settings
.ropeproject

# mkdocs documentation
/site

# mypy
.mypy_cache/
.dmypy.json
dmypy.json

# Pyre type checker
.pyre/

# pytype static type analyzer
.pytype/
~~~
"""
)

Informations additionnelles

environment files have been tested on.

Latest built version: 2024-04-27

Python version used:

'3.11.6 | packaged by conda-forge | (main, Oct  3 2023, 10:40:35) [GCC 12.3.0]'
Package Version
affine 2.4.0
aiobotocore 2.12.2
aiohttp 3.9.3
aioitertools 0.11.0
aiosignal 1.3.1
alembic 1.13.1
aniso8601 9.0.1
annotated-types 0.6.0
appdirs 1.4.4
archspec 0.2.3
astroid 3.1.0
asttokens 2.4.1
attrs 23.2.0
Babel 2.14.0
bcrypt 4.1.2
beautifulsoup4 4.12.3
black 24.4.2
blinker 1.7.0
blis 0.7.11
bokeh 3.4.0
boltons 23.1.1
boto3 1.34.51
botocore 1.34.51
branca 0.7.1
Brotli 1.1.0
cachetools 5.3.3
cartiflette 0.0.2
Cartopy 0.23.0
catalogue 2.0.10
cattrs 23.2.3
certifi 2024.2.2
cffi 1.16.0
charset-normalizer 3.3.2
chromedriver-autoinstaller 0.6.4
click 8.1.7
click-plugins 1.1.1
cligj 0.7.2
cloudpathlib 0.16.0
cloudpickle 3.0.0
colorama 0.4.6
comm 0.2.2
commonmark 0.9.1
conda 24.3.0
conda-libmamba-solver 24.1.0
conda-package-handling 2.2.0
conda_package_streaming 0.9.0
confection 0.1.4
contextily 1.6.0
contourpy 1.2.1
cryptography 42.0.5
cycler 0.12.1
cymem 2.0.8
cytoolz 0.12.3
dask 2024.4.1
dask-expr 1.0.10
debugpy 1.8.1
decorator 5.1.1
dill 0.3.8
distributed 2024.4.1
distro 1.9.0
docker 7.0.0
duckdb 0.10.1
en-core-web-sm 3.7.1
entrypoints 0.4
et-xmlfile 1.1.0
exceptiongroup 1.2.0
executing 2.0.1
fastjsonschema 2.19.1
fiona 1.9.6
flake8 7.0.0
Flask 3.0.2
folium 0.16.0
fontawesomefree 6.5.1
fonttools 4.51.0
fr-core-news-sm 3.7.0
frozenlist 1.4.1
fsspec 2023.12.2
GDAL 3.8.4
gensim 4.3.2
geographiclib 2.0
geopandas 0.12.2
geoplot 0.5.1
geopy 2.4.1
gitdb 4.0.11
GitPython 3.1.43
google-auth 2.29.0
graphene 3.3
graphql-core 3.2.3
graphql-relay 3.2.0
graphviz 0.20.3
great-tables 0.5.0
greenlet 3.0.3
gunicorn 21.2.0
h11 0.14.0
htmltools 0.5.1
hvac 2.1.0
idna 3.6
imageio 2.34.1
importlib_metadata 7.1.0
importlib_resources 6.4.0
inflate64 1.0.0
ipykernel 6.29.3
ipython 8.22.2
ipywidgets 8.1.2
isort 5.13.2
itsdangerous 2.1.2
jedi 0.19.1
Jinja2 3.1.3
jmespath 1.0.1
joblib 1.3.2
jsonpatch 1.33
jsonpointer 2.4
jsonschema 4.21.1
jsonschema-specifications 2023.12.1
jupyter-cache 1.0.0
jupyter_client 8.6.1
jupyter_core 5.7.2
jupyterlab_widgets 3.0.10
kaleido 0.2.1
kiwisolver 1.4.5
kubernetes 29.0.0
langcodes 3.4.0
language_data 1.2.0
lazy_loader 0.4
libmambapy 1.5.7
llvmlite 0.42.0
locket 1.0.0
lxml 5.2.1
lz4 4.3.3
Mako 1.3.2
mamba 1.5.7
mapclassify 2.6.1
marisa-trie 1.1.0
Markdown 3.6
MarkupSafe 2.1.5
matplotlib 3.8.3
matplotlib-inline 0.1.6
mccabe 0.7.0
menuinst 2.0.2
mercantile 1.2.1
mizani 0.11.2
mlflow 2.11.3
mlflow-skinny 2.11.3
msgpack 1.0.7
multidict 6.0.5
multivolumefile 0.2.3
munkres 1.1.4
murmurhash 1.0.10
mypy 1.9.0
mypy-extensions 1.0.0
nbclient 0.10.0
nbformat 5.10.4
nest_asyncio 1.6.0
networkx 3.3
nltk 3.8.1
numba 0.59.1
numpy 1.26.4
oauthlib 3.2.2
opencv-python-headless 4.9.0.80
openpyxl 3.1.2
outcome 1.3.0.post0
OWSLib 0.28.1
packaging 23.2
pandas 2.2.1
paramiko 3.4.0
parso 0.8.4
partd 1.4.1
pathspec 0.12.1
patsy 0.5.6
Pebble 5.0.7
pexpect 4.9.0
pickleshare 0.7.5
pillow 10.3.0
pip 24.0
pkgutil_resolve_name 1.3.10
platformdirs 4.2.0
plotly 5.19.0
plotnine 0.13.5
pluggy 1.4.0
polars 0.20.18
preshed 3.0.9
prometheus_client 0.20.0
prometheus-flask-exporter 0.23.0
prompt-toolkit 3.0.42
protobuf 4.25.3
psutil 5.9.8
ptyprocess 0.7.0
pure-eval 0.2.2
py7zr 0.20.8
pyarrow 15.0.0
pyarrow-hotfix 0.6
pyasn1 0.5.1
pyasn1-modules 0.3.0
pybcj 1.0.2
pycodestyle 2.11.1
pycosat 0.6.6
pycparser 2.21
pycryptodomex 3.20.0
pydantic 2.7.1
pydantic_core 2.18.2
pyflakes 3.2.0
Pygments 2.17.2
PyJWT 2.8.0
pylint 3.1.0
PyNaCl 1.5.0
pynsee 0.1.7
pyOpenSSL 24.0.0
pyparsing 3.1.2
pyppmd 1.1.0
pyproj 3.6.1
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.0
PyYAML 6.0.1
pyzmq 25.1.2
pyzstd 0.15.10
QtPy 2.4.1
querystring-parser 1.2.4
rasterio 1.3.10
referencing 0.34.0
regex 2023.12.25
requests 2.31.0
requests-cache 1.2.0
requests-oauthlib 2.0.0
rpds-py 0.18.0
rsa 4.9
Rtree 1.2.0
ruamel.yaml 0.18.6
ruamel.yaml.clib 0.2.8
s3fs 2023.12.2
s3transfer 0.10.1
scikit-image 0.23.2
scikit-learn 1.4.1.post1
scipy 1.13.0
seaborn 0.13.2
selenium 4.20.0
setuptools 69.2.0
shapely 2.0.3
six 1.16.0
smart-open 6.4.0
smmap 5.0.0
sniffio 1.3.1
snuggs 1.4.7
sortedcontainers 2.4.0
soupsieve 2.5
spacy 3.7.4
spacy-legacy 3.0.12
spacy-loggers 1.0.5
SQLAlchemy 2.0.29
sqlparse 0.4.4
srsly 2.4.8
stack-data 0.6.2
statsmodels 0.14.1
tabulate 0.9.0
tblib 3.0.0
tenacity 8.2.3
texttable 1.7.0
thinc 8.2.3
threadpoolctl 3.4.0
tifffile 2024.4.24
tomli 2.0.1
tomlkit 0.12.4
toolz 0.12.1
topojson 1.8
tornado 6.4
tqdm 4.66.2
traitlets 5.14.2
trio 0.25.0
trio-websocket 0.11.1
truststore 0.8.0
typer 0.9.4
typing_extensions 4.11.0
tzdata 2024.1
Unidecode 1.3.8
url-normalize 1.4.3
urllib3 1.26.18
wasabi 1.1.2
wcwidth 0.2.13
weasel 0.3.4
webcolors 1.13
webdriver-manager 4.0.1
websocket-client 1.7.0
Werkzeug 3.0.2
wheel 0.43.0
widgetsnbextension 4.0.10
wordcloud 1.9.3
wrapt 1.16.0
wsproto 1.2.0
xgboost 2.0.3
xlrd 2.0.1
xyzservices 2024.4.0
yarl 1.9.4
yellowbrick 1.5
zict 3.0.0
zipp 3.17.0
zstandard 0.22.0

View file history

SHA Date Author Description
c9f9f8a 2024-04-24 15:09:35 Lino Galiana Dark mode and CSS improvements (#494)
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)
09654c7 2023-11-14 15:16:44 Antoine Palazzolo Suggestions Git & Visualisation (#449)
e3f1ef1 2023-11-13 11:53:50 Thomas Faria Relecture git (#448)
1229936 2023-11-10 11:02:28 linogaliana gitignore
57f108f 2023-11-10 10:59:36 linogaliana Intro git
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)
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)
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)
f394b23 2022-10-13 14:32:05 Lino Galiana Dernieres modifs geopandas (#298)
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)
f95b174 2021-11-03 12:08:34 Lino Galiana Enrichi la section sur la gestion des dépendances (#175)
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)
283e8e9 2020-10-02 18:54:30 Lino Galiana Première partie des exos git (#61)
Back to top

Footnotes

  1. Plus précisément, chaque modification est identifiée de manière unique par un code SHA auquel est associé l’auteur, l’horodatage et des métadonnées (par exemple le message descriptif associé).↩︎

Citation

BibTeX citation:
@book{galiana2023,
  author = {Galiana, Lino},
  title = {Python Pour La Data Science},
  date = {2023},
  url = {https://pythonds.linogaliana.fr/},
  doi = {10.5281/zenodo.8229676},
  langid = {en}
}
For attribution, please cite this work as:
Galiana, Lino. 2023. Python Pour La Data Science. https://doi.org/10.5281/zenodo.8229676.