---
jupytext:
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.16.0
kernelspec:
  name: python3
  display_name: Python 3
---

# Installation, environnements et outils

```{code-cell} python
:tags: [hide-input]

import matplotlib.pyplot as plt
import matplotlib.patches as patches
import numpy as np
import seaborn as sns

sns.set_theme(style="whitegrid", palette="muted", font_scale=1.1)
```

## Pourquoi Python ?

Python est aujourd'hui l'un des langages de programmation les plus utilisés au monde, et ce pour de bonnes raisons. Sa syntaxe claire, sa lisibilité remarquable et l'étendue de son écosystème en font un choix de prédilection aussi bien pour les débutants que pour les ingénieurs expérimentés.

L'histoire de Python commence en 1991, lorsque **Guido van Rossum**, alors chercheur au Centrum Wiskunde & Informatica (CWI) aux Pays-Bas, publie la version 0.9 de son nouveau langage. Guido travaillait auparavant sur ABC, un langage pédagogique conçu pour être facile à apprendre, mais frustré par ses limitations, il décide de créer quelque chose de nouveau. Il baptise son langage Python en hommage à la troupe comique britannique *Monty Python's Flying Circus*, dont il était admirateur — un choix qui donne d'emblée au projet une touche d'humour et de légèreté.

La philosophie de Python est résumée dans un document poétique connu sous le nom de **Zen de Python**, rédigé par Tim Peters. On peut l'afficher à tout moment depuis l'interpréteur Python :

```{code-cell} python
import this
```

Ces vingt aphorismes constituent une véritable charte de conception. Parmi les plus importants : *Beautiful is better than ugly* (le code doit être élégant), *Explicit is better than implicit* (la clarté prime sur la magie), *Simple is better than complex* (la simplicité est une vertu), et *There should be one obvious way to do it* (Python décourage la prolifération de styles différents pour accomplir la même chose). Cette philosophie se traduit concrètement dans la conception du langage : Python impose l'indentation comme structure syntaxique, favorise les noms explicites et rend le code lisible presque comme de la prose.

### Cas d'usage et domaines d'application

La polyvalence de Python est l'une de ses forces majeures. Il est utilisé dans des domaines extrêmement variés :

- **Scripts et automatisation** : Python remplace avantageusement les scripts shell pour automatiser des tâches répétitives — renommage de fichiers, traitement de données, envoi d'emails, interaction avec des API.
- **Développement web** : des frameworks comme **Django** et **FastAPI** permettent de construire des applications web robustes et performantes. Django suit le paradigme MVC et inclut un ORM puissant ; FastAPI est orienté vers les API asynchrones et tire parti des annotations de types.
- **Science des données et analyse** : l'écosystème **NumPy**, **Pandas**, **Matplotlib** et **Seaborn** a rendu Python incontournable pour l'analyse et la visualisation de données.
- **Intelligence artificielle et apprentissage automatique** : **TensorFlow**, **PyTorch**, **scikit-learn** et **Hugging Face Transformers** ont fait de Python la langue franche de l'IA. Pratiquement toutes les recherches en deep learning sont publiées avec du code Python.
- **Calcul scientifique** : **SciPy**, **SymPy**, **Astropy** et bien d'autres bibliothèques servent de fondation aux sciences physiques, biologiques et computationnelles.
- **Systèmes embarqués et IoT** : MicroPython et CircuitPython apportent Python sur les microcontrôleurs, ouvrant la voie à une programmation de bas niveau accessible.

Cette omniprésence s'explique aussi par la richesse de la **bibliothèque standard** (*standard library*), qui couvre nativement des besoins aussi divers que la manipulation de fichiers, la compression, les protocoles réseau, la cryptographie, la gestion des dates, le multithreading et bien plus encore.

## Installer Python

### Python 2 vs Python 3

Il est important de comprendre que Python 2 et Python 3 sont deux langages distincts et **incompatibles**. Python 2 a été officiellement abandonné le 1er janvier 2020 : il ne reçoit plus aucune mise à jour de sécurité. Toute nouvelle installation doit impérativement utiliser Python 3. Dans ce livre, nous utilisons exclusivement **Python 3** (version 3.10 ou supérieure).

Les différences majeures entre Python 2 et Python 3 incluent : la division entière (`3/2` vaut `1.5` en Python 3 mais `1` en Python 2), les chaînes Unicode par défaut en Python 3, la syntaxe de `print` (fonction en Python 3, instruction en Python 2) et de nombreuses améliorations de la bibliothèque standard.

### Gérer les versions avec `pyenv`

La gestion de plusieurs versions de Python sur un même système peut vite devenir complexe. L'outil **`pyenv`** résout élégamment ce problème en permettant d'installer et de basculer entre différentes versions de Python sans toucher au Python système.

Installation de `pyenv` sur Linux/macOS :

```bash
curl https://pyenv.run | bash
```

Après l'installation, on ajoute les lignes suivantes à `~/.bashrc` ou `~/.zshrc` :

```bash
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"
eval "$(pyenv init -)"
```

Les commandes essentielles de `pyenv` :

```bash
# Lister les versions disponibles
pyenv install --list

# Installer une version spécifique
pyenv install 3.12.3

# Définir la version globale
pyenv global 3.12.3

# Définir une version locale (dans le dossier courant)
pyenv local 3.11.8

# Vérifier la version active
python --version
```

La commande `pyenv local` crée un fichier `.python-version` dans le répertoire courant, ce qui garantit que tous les collaborateurs d'un projet utilisent exactement la même version de Python.

## `uv` — le gestionnaire moderne

### Présentation

**`uv`** est un outil de gestion de paquets et d'environnements Python écrit en **Rust**, développé par la société Astral (à l'origine de `ruff`, le linter ultra-rapide). Il a été conçu pour remplacer `pip`, `pip-tools`, `virtualenv`, `venv` et même une partie des fonctionnalités de `poetry`, en offrant une interface unifiée et des performances bien supérieures. Sur des projets comportant des centaines de dépendances, `uv` peut être dix à cent fois plus rapide que `pip`.

Installation de `uv` :

```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

### Créer un projet et un environnement virtuel

Un **environnement virtuel** est un dossier isolé contenant une installation Python et ses paquets, indépendante du reste du système. Cela permet d'avoir des dépendances différentes par projet sans conflits.

```bash
# Créer un nouveau projet (génère pyproject.toml + .venv)
uv init mon_projet
cd mon_projet

# Ou créer simplement un environnement virtuel dans le dossier courant
uv venv

# Activer l'environnement (Linux/macOS)
source .venv/bin/activate

# Activer l'environnement (Windows)
.venv\Scripts\activate
```

### Installer des paquets

```bash
# Ajouter une dépendance au projet (màj pyproject.toml + uv.lock)
uv add numpy pandas matplotlib

# Installer un paquet sans l'ajouter aux dépendances du projet
uv pip install requests

# Installer les dépendances listées dans pyproject.toml
uv sync

# Afficher les paquets installés
uv pip list
```

### Exécuter du code avec `uv run`

La commande `uv run` exécute un script dans l'environnement du projet, sans avoir besoin d'activer manuellement l'environnement virtuel :

```bash
# Exécuter un script Python
uv run hello.py

# Exécuter une commande dans l'environnement
uv run python -c "import numpy; print(numpy.__version__)"

# Lancer Jupyter
uv run jupyter lab
```

### Avantages sur `pip` et `venv`

Par rapport à la combinaison traditionnelle `pip` + `venv`, `uv` offre plusieurs avantages décisifs :

- **Vitesse** : la résolution des dépendances et leur téléchargement sont nettement plus rapides.
- **Reproductibilité** : le fichier `uv.lock` fixe exactement les versions de toutes les dépendances, directes et transitives.
- **Interface unifiée** : une seule commande gère la création d'environnements, l'installation de paquets et l'exécution de scripts.
- **Compatibilité** : `uv` est compatible avec `pyproject.toml` et les standards modernes de l'écosystème Python.

## Le REPL Python

Le **REPL** (*Read-Eval-Print Loop*) est l'interpréteur interactif de Python. On le lance simplement en tapant `python` (ou `python3`) dans un terminal. Il lit chaque expression saisie, l'évalue et en affiche le résultat immédiatement — un outil précieux pour explorer le langage et tester des idées rapidement.

```{code-cell} python
# Calcul immédiat
2 ** 10
```

```{code-cell} python
# La variable _ contient le dernier résultat calculé
_ * 2
```

### Fonctions d'introspection

Le REPL fournit plusieurs outils d'exploration particulièrement utiles :

```{code-cell} python
# help() affiche la documentation d'un objet
help(len)
```

```{code-cell} python
# dir() liste les attributs et méthodes d'un objet
print(dir([]))
```

```{code-cell} python
# type() retourne le type d'un objet
print(type(42))
print(type(3.14))
print(type("bonjour"))
print(type([1, 2, 3]))
```

```{prf:remark}
:label: remark-01-01
La variable spéciale `_` dans le REPL contient toujours le résultat de la dernière expression évaluée. C'est une commodité pratique pour enchaîner des calculs sans avoir à stocker les résultats intermédiaires dans des variables. Cette convention ne fonctionne que dans le REPL interactif, pas dans un script ordinaire.
```

Pour une expérience interactive plus riche, on peut installer **IPython** (`uv add ipython`), qui offre la coloration syntaxique, la complétion avancée, la magie (`%timeit`, `%matplotlib`), et une gestion bien meilleure de l'historique.

## Éditeurs et IDE

Le choix de l'éditeur est une question de préférence personnelle, mais certains outils sont particulièrement bien adaptés à Python.

### Visual Studio Code

**VS Code** est un éditeur polyvalent, léger et extensible, qui est devenu l'un des environnements de développement Python les plus populaires. Pour configurer VS Code pour Python :

1. Installer VS Code depuis [code.visualstudio.com](https://code.visualstudio.com).
2. Installer l'extension **Python** (publiée par Microsoft) depuis le marché d'extensions.
3. Installer l'extension **Pylance** pour bénéficier d'une analyse statique avancée, de la complétion intelligente basée sur les annotations de types, et de l'inférence de types.

La configuration recommandée dans `.vscode/settings.json` :

```json
{
  "python.defaultInterpreterPath": ".venv/bin/python",
  "editor.formatOnSave": true,
  "[python]": {
    "editor.defaultFormatter": "charliermarsh.ruff"
  },
  "python.analysis.typeCheckingMode": "basic"
}
```

### PyCharm

**PyCharm** (de JetBrains) est un IDE dédié à Python, plus lourd que VS Code mais offrant une intégration très poussée : débogueur visuel, profiler intégré, support natif des frameworks web, gestion des environnements virtuels et des bases de données. La version Community est gratuite et couvre l'essentiel.

### Jupyter Lab

**Jupyter Lab** est l'environnement de prédilection pour l'exploration de données et le calcul scientifique. Il combine du code exécutable, du texte au format Markdown, des équations LaTeX et des visualisations dans des notebooks interactifs. C'est le format utilisé dans ce livre.

## Premier script Python

Créons notre premier fichier Python. Par convention, les fichiers Python ont l'extension `.py`.

```{code-cell} python
# Contenu du fichier hello.py
print("Bonjour, monde !")
print("Python version :", __import__('sys').version)
```

Dans un terminal, ce script s'exécute de deux façons :

```bash
# Méthode classique
python hello.py

# Avec uv (sans activer l'environnement)
uv run hello.py
```

```{prf:example} Structure d'un script Python typique
:label: example-01-01
Un script Python bien structuré respecte quelques conventions :

```python
#!/usr/bin/env python3
"""
Module de démonstration.

Ce module illustre la structure standard d'un script Python.
"""

# Imports de la bibliothèque standard d'abord
import sys
import os

# Puis imports tiers
import numpy as np

# Puis imports locaux
# from mon_module import ma_fonction


def main() -> None:
    """Point d'entrée principal du script."""
    print("Bonjour depuis main() !")
    print(f"Version Python : {sys.version}")


if __name__ == "__main__":
    main()
```

Le bloc `if __name__ == "__main__":` est fondamental : il garantit que `main()` n'est appelée que lorsque le fichier est exécuté directement, et non lorsqu'il est importé comme module par un autre fichier.
```

```{prf:definition} Module et script
:label: definition-01-01
En Python, tout fichier `.py` est à la fois un **script** (exécutable directement) et un **module** (importable par d'autres fichiers). La variable `__name__` vaut `"__main__"` quand le fichier est exécuté directement, et le nom du fichier (sans l'extension) quand il est importé. Cette dualité est au cœur du système de modules Python.
```

## Visualisation de l'écosystème Python

```{code-cell} python
:tags: [hide-input]

fig, ax = plt.subplots(figsize=(12, 8))
ax.set_xlim(0, 10)
ax.set_ylim(0, 10)
ax.axis('off')
ax.set_title("L'écosystème Python : des couches successives", fontsize=15,
             fontweight='bold', pad=20)

palette = sns.color_palette("muted", 4)

couches = [
    (0.3, 0.3, 9.4, 1.8, palette[0], "Langage Python",
     "Syntaxe, types, structures de contrôle, fonctions, classes…"),
    (0.7, 2.4, 8.6, 1.8, palette[1], "Bibliothèque standard (stdlib)",
     "os, sys, math, json, csv, re, datetime, pathlib, collections…"),
    (1.1, 4.5, 7.8, 1.8, palette[2], "Paquets tiers",
     "NumPy, Pandas, Matplotlib, Django, FastAPI, scikit-learn, PyTorch…"),
    (1.5, 6.6, 7.0, 1.8, palette[3], "Applications",
     "Scripts, API web, notebooks, modèles ML, outils CLI…"),
]

for (x, y, w, h, color, titre, sous_titre) in couches:
    box = patches.FancyBboxPatch(
        (x, y), w, h,
        boxstyle="round,pad=0.2",
        linewidth=2,
        edgecolor=color,
        facecolor=color,
        alpha=0.25
    )
    ax.add_patch(box)
    border = patches.FancyBboxPatch(
        (x, y), w, h,
        boxstyle="round,pad=0.2",
        linewidth=2,
        edgecolor=color,
        facecolor='none'
    )
    ax.add_patch(border)
    ax.text(x + w / 2, y + h - 0.45, titre,
            ha='center', va='center',
            fontsize=12, fontweight='bold', color=color)
    ax.text(x + w / 2, y + 0.6, sous_titre,
            ha='center', va='center',
            fontsize=8.5, color='#444444', style='italic')

# Flèche indiquant la direction de construction
for y_arrow in [2.15, 4.35, 6.45]:
    ax.annotate('', xy=(5.0, y_arrow + 0.05), xytext=(5.0, y_arrow - 0.05),
                arrowprops=dict(arrowstyle='->', color='#888888', lw=2))

ax.text(9.7, 5.5, 'Abstraction\ncroissante', ha='center', va='center',
        fontsize=9, color='#888888', style='italic',
        rotation=90)
ax.annotate('', xy=(9.5, 8.1), xytext=(9.5, 0.4),
            arrowprops=dict(arrowstyle='->', color='#aaaaaa', lw=1.5))

plt.tight_layout()
plt.show()
```

## Résumé

Dans ce premier chapitre, nous avons posé les fondations nécessaires pour travailler avec Python :

- Python est un langage créé en **1991 par Guido van Rossum**, dont la philosophie est résumée dans le **Zen de Python** : clarté, simplicité, et une façon évidente de faire les choses. Il s'applique à une vaste gamme de domaines : scripts, web, data science, IA, sciences.
- Il est impératif d'utiliser **Python 3** (Python 2 est abandonné depuis 2020). L'outil **`pyenv`** permet de gérer facilement plusieurs versions sur un même système.
- **`uv`** est le gestionnaire moderne de référence : il remplace `pip` + `venv` en offrant vitesse, reproductibilité (via `uv.lock`) et une interface unifiée pour créer des environnements, installer des paquets et exécuter des scripts.
- Le **REPL** Python est un outil interactif indispensable pour explorer le langage. Les fonctions `help()`, `dir()` et `type()` permettent d'inspecter n'importe quel objet.
- **VS Code** avec les extensions Python et Pylance constitue un environnement de développement confortable et puissant pour les projets Python.
- Tout fichier `.py` est à la fois un script et un module ; le bloc `if __name__ == "__main__":` est la convention pour définir le point d'entrée d'un script.

Dans le chapitre suivant, nous plongerons dans les **types de base** de Python : entiers, flottants, booléens, chaînes de caractères et `None`, en explorant leurs propriétés et leurs opérations fondamentales.
