In [1]:
from IPython.core.display import display, HTML
display(HTML("<style>.container { width:90% !important; }</style>"))
In [2]:
import sys #only needed to determine Python version number
import matplotlib #only needed to determine Matplotlib version number

print('Python version ' + sys.version)
print('Matplotlib version ' + matplotlib.__version__ )

%reset -f
Python version 3.6.2 |Anaconda custom (64-bit)| (default, Jul 20 2017, 13:51:32) 
[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]
Matplotlib version 2.1.0

M62_CM1 Introduction aux Notebooks IPython et rappels sur le langage Python.

Table of Contents

Notebook Jupyter


Jupyter est une application Web qui regroupe intimement deux fonctionnalités très différentes :

  • Un outil qui permet de créer des documents multimédia intégrant du texte, des formules mathématiques, des graphiques, des images, voire des animations et des vidéos.
  • Une interface qui permet d'exécuter du code informatique. Pour cela Jupyter s'appuie sur des programmes indépendants capablent d'interpréter le langage dans lequel est écrit ce code. Dans la terminologie de Jupyter ces interpréteurs sont appelés des noyaux (kernel en anglais). Nous utiliserons le noyau pour le langage Python 3.

Les documents Jupyter sont appelés des notebooks. Un fichier notebook est reconnaissable par son extension $\texttt{.ipynb}$. Le document que vous lisez actuellement est un notebook.

Pour commencer, dans un terminal, lancer la commande jupyter notebook & (ou anaconda-navigator &). Cela ouvrira automatiquement un navigateur dans lequel on peut alors commencer à travailler. L'onglet principal représente l’arborescence des fichiers.

Installation simple

La façon la plus simple d’installer Python et Jupyter est d’installer Anaconda. Les procédures d’installations détaillées selon chaque système d’exploitation sont décrites à l’adresse : https://docs.anaconda.com/anaconda/install/. Les procédures suivantes sont un résumé rapide de la procédure d’installation.

  • Installation sous Windows.
    1. Télécharger Anaconda 5.2 (ou plus récent) pour Python 3.6 (ou plus récent) à l’adresse : https://www.anaconda.com/download/#windows ;
    2. Double cliquer sur le fichier téléchargé pour lancer l’installation d’Anaconda, puis suivre la procédure d’installation (il n’est pas nécessaire d’installer VS Code).
    3. Une fois l’installation terminée, lancer Anaconda Navigator à partir du menu démarrer.
  • Installation sous macOS.
    1. Télécharger Anaconda 5.2 (ou plus récent) pour Python 3.6 (ou plus récent) à l’adresse : https://www.anaconda.com/download/#macos ;
    2. Double cliquer sur le fichier téléchargé pour lancer l’installation d’Anaconda, puis suivre la procédure d’installation (il n’est pas nécessaire d’installer VS Code).
    3. Une fois l’installation terminée, lancer Anaconda Navigator à partir de la liste des applications.
  • Installation sous Linux.
    1. Télécharger Anaconda 5.2 (ou plus récent) pour Python 3.6 (ou plus récent) à l’adresse : https://www.anaconda.com/download/#linux ;
    2. Exécuter le fichier téléchargé avec bash puis suivre la procédure d’installation (il n’est pas nécessaire d’installer VS Code).
    3. Une fois l’installation terminée, taper anaconda-navigator dans un nouveau terminal pour lancer Anaconda Navigator.

Références

Manipulation du notebook

Le notebook est constitué d'une succession de cellules comportant

  • soit du texte en Markdown comme ici,
  • soit du code comme dans la cellule suivante (Python pour nous):
In [3]:
x=range(3)

Un liseré repère la cellule actuellement selectionnée.
Les cellules peuvent être dans le mode commande ou le mode édition:

  • mode commande : permet de se déplacer d'une cellule à l'autre et d'exécuter les cellules
  • mode édition : permet de modifier le contenu d'une cellule.
  1. Mode commande
    Pour entrer dans le mode commande de la cellule sélectionnée, il suffit de presser la touche [Esc]. Quand vous êtes dans le mode commande, vous pouvez ajouter ou supprimer des cellules mais vous ne pouvez pas saisir de texte dans une cellule.
    Voici les raccourcis principaux disponibles en mode commande :

    • A et B : Insèrent une nouvelle cellule, respectivement au-dessus ou au-dessous de la cellule sélectionnée.
    • M : Transforme la cellule en une cellule de type Markdown.
    • Y : Transforme la cellule en une cellule de type Code.
    • C et V : Copie et colle des cellules.
    • DD : Supprime la cellule sélectionnée.
    • Z : Annule la dernière suppression de cellule.
    • II : Interrompt l'exécution du code.
    • 00 : Redémarre l'interpréteur. Il se retrouve alors dans son état initial.
    • H : Affiche la liste de tous les raccourcis clavier.
  2. Mode édition
    Pour entrer dans le mode édition de la cellule sélectionnée, il suffit de presser la touche [Enter] ou de double-cliquer à l'intérieur de la cellule. Quand une cellule est en édition vous pouvez saisir du texte comme dans un éditeur classique.
    Lorsque le curseur est en début de ligne ou lorsque vous avez sélectionné du texte, l'appui sur la touche [Tab] (respectivement [Shift-TAB]) indente (respectivement désindente) les lignes correspondantes.
    Voici d'autres raccourcis clavier :

    • [Ctrl-A] : Sélectionne tout le texte de la cellule.
    • [Ctrl-Z] : Annule les dernières saisies de texte.
    • [Ctrl-Enter] : Exécute la cellule.
    • [Shift-Enter] : Exécute la cellule et sélectionne la cellule suivante. L'appui répété de cette touche permet ainsi d'exécuter pas à pas toutes les cellules du notebook.
    • [Alt-Enter] : Exécute la cellule et insére une nouvelle cellule juste en dessous.
    • [ESC] : Passe dans le mode commande

Mode édition : les cellules Markdown et sa syntaxe

La touche M transforme la cellule sélectionnée en type Markdown. Vous pouvez alors rédiger du texte enrichi (titres, sous-titres, gras, italique, alinéas, tableaux, liens hypertexte, etc).
Le texte de la cellule doit être rédigé en langage Markdown qui est un langage de balisage léger. La syntaxe markdown est facile à apprendre (le plus simple est d'ailleurs de regarder des exemples de documents). Voici quelque liens :

Il est également possible d'insérer des morceaux de texte en langage $\LaTeX$ pour composer des expressions mathématiques.

La syntaxe

Markdown est un système d’édition et de formatage de texte. La philosophie du système veut que le texte écrit soit lisible sans interpréteur particulier en mode texte. Il est léger et épuré de l’essentiel de la verbosité d’un language balisé.
Les éléments de syntaxe sont des caractères de ponctuation qui font sens visuellement même non convertis. Une fois converti, le navigateur web (qui joue alors le rôle d’interpréteur) en rendra la lecture plus claire.

Vous pouvez tout à fait introduire directement des balises HTML dans votre texte. Attention, le formatage markdown ne sera pas appliqué à l’intérieur de ces balises.

Les titres

Il est possible de titrer en ajoutant des dièses (#) au début de la ligne. Il n’y a pas de limite au nombre de niveaux de titres qu’il est possible d’utiliser (mais n’allez pas au delà de 4).

# Title 1  
## Title 2  
### Title 3  
####  Title 4
#####  Title 5

Les paragraphes

Pour afficher un paragraphe, laisser une ligne vide.

Effectuer un saut de ligne simple dans votre texte markdown n’aura aucun effet. Sauf si vous terminez votre ligne par un double espace (ou plus que ça)...
comme ici.

L’emphase

Pour formater une partie de votre texte comme emphase, entourez le par des astérisques * ou des underscores _. Entourer par un signe unique passe en italique et par un double signe en gras. Il est possible de combiner les deux.
Un double tildes ~~ vous permettent de barrer le texte.

Les citations

Pour afficher un bloc de citation, commencez le paragraphe par un chevron fermant >. Si votre bloc contient plusieurs lignes, vous pouvez faire des sauts de lignes à la main et toutes les ouvrir par un chevron fermant, mais ce n’est pas nécessaire. Ces bloc peuvent contenir d’autres éléments markdown comme des titres ou des listes.

Les listes non ordonnée

Pour afficher une liste, commencez la ligne par une astérisque *, un moins - ou un plus +. Là encore, le choix n’a pas d’importance, mais il faut rester cohérent dans votre document.

+ item  
+ item  
+ item  

donne

  • item
  • item
  • item

Les listes ordonnées

Pour afficher une liste ordonnée, commencez la ligne par un nombre suivit d’un point.

1. item  
123. item  
17. item  

donne

  1. item
  2. item
  3. item

Le bloc de code

Pour afficher un bloc de code, sautez deux lignes comme pour un paragraphe, puis indentez avec 4 espaces ou une tabulation.
Pour afficher du code dans une ligne, il faut l’entourer par des guillemets simples (`).

Les filets ou barres de séparation

Pour afficher un filet de séparation, entrez dans votre texte au moins 3 astérisques * ou 3 moins - sur une ligne entourée de sauts de lignes. Il est possible de les séparer par des espaces.

Les liens

Il y a deux façons d’afficher un lien.

  1. De manière automatique en encadrant un lien par des chevrons, par exemple <http://www.google.com> donne http://www.google.com. Il est alors cliquable et affiche l’url indiquée entre chevrons.
  2. Ou en ajoutant des paramètres. Le texte à afficher est alors indiqué entre crochets suivit de l’adresse du lien entre parenthèses, par exemple [google](http://www.google.com "link to google") donne google. Dans les parenthèses, à la suite du lien, on peut indiquer un titre entre guillemets. Ce titre sera affiché lors du survol du lien dans le navigateur. Il sera également lu par les navigateurs textuels pour les déficients visuels.

Les images

Pour afficher une image, commencez par un point d’exclamation. Puis indiquez le texte alternatif entre crochets. Ce dernier sera affiché si l’image n’est pas chargé et lue par les moteurs de recherche. Terminez par l’URL de l’image entre parenthèses. Cette URL peut être un lien vers le web ou un chemin local de ce type : /dossier_images/nom_de_mon_image.jpg. Après le lien vers l’image, il est possible d’ajouter un titre lu par les navigateurs textuels et affiché au survol de l’image par les autres.
![Jupyter logo](https://upload.wikimedia.org/wikipedia/commons/3/38/Jupyter_logo.svg)
donne Jupyter logo

Si l'image doit être redimensionnée, utiliser directement du $\texttt{html}$:
![Google logo](https://www.google.fr/images/srpr/logo11w.png "google logo") donne
Google logo

<img src = "https://www.google.fr/images/srpr/logo11w.png" title = "google logo" alt = "Google logo" width="200"> donne
Google logo

Les tableaux

L’idée globale est de “dessiner” des colonnes en les entourant avec des pipes |. Le nombre de colonnes est défini dans la première ligne du tableau et vous devez pour chaque ligne avoir le même nombre de colonnes, même si certaines sont vides.
La première ligne sera votre en-tête. La seconde ligne sépare cet en-tête du corps du tableau, elle ne contient que des tiret - Il n'est plus possible de définir l'alignement des colonnes dans markdown.

| Header 1 | header 2 | header 3 |  
|----------|----------|----------|  
| 1 Online |   1      |    value |  
| Line 2   |   2      |    value |  
| 3 Online |   3      |    value |  
Header 1 header 2 header 3
1 Online 1 value
Line 2 2 value
3 Online 3 value

Assistant en ligne : Markdown Tables Generator

Échappement des caractères

Les caractères spéciaux ayant un sens en markdown doivent être échappés. Si vous souhaitez utiliser dans votre texte des astérisques, accolades, dièses... à une position indiquant à markdown que vous désirer un formatage particulier, vous devez les échapper en les faisant précéder d’un antislash \. Sinon markdown les masquera et appliquera le formatage correspondant. Les caractères suivants sont à échapper :

\ * ` - _ [] () {} # + . !  

Mode édition: les équations

Les équations peuvent être directement données au format $\LaTeX$, on peut donc par exemple écrire $x_i$ au milieu d’une ligne ou bien écrire des équations dans une nouvelle ligne et centrées:
$$\sum_{n=1}^{\infty}\frac{1}{n^2}=\frac{\pi^2}{6}. $$
Quelques commandes $\LaTeX$ de base sont expliquées sur cette page, et pour plus de détails, vous pourrez consulter mon polycopié d'Initiation à $\LaTeX2e$, disponible ici, en particulier le chapitre 3.

Les modes mathématiques

Pour taper des formules mathématiques avec $\LaTeX$ , il y a besoin d’entrer en mode mathématiques.
Il existe deux modes mathématiques : les formules dans le texte (appelée inline) et les formules en évidence (dites en displaystyle).

  • Pour mettre une formule dans le texte, comme $y=f(x)$, il suffit de mettre la formule entre deux dollars: $y=f(x)$.
    Remarquer la différence entre le mode texte et le mode mathématique : avec des dollars on a $y=f(x)$ tandis que sans dollars on a y=f(x)
  • Pour mettre une formule en évidence, comme $$y=f(x)$$ il faut mettre la formule entre deux doubles dollars $$y=f(x)$$

Indices et exposantes

Deux opérations fondamentales en mode mathématique sont la mise en exposant et la mise en indice.

  • Pour obtenir un indice, il faut utiliser la touche _ qui s’obtient avec la touche «8». Par exemple, taper $x_1$ donnera $x_1$. Attention, taper $x_12$ ne donne pas $x_{12}$ mais $x_12$: seul le premier caractère tapé après _ est mis en indice; pour obtenir $x_{12}$, il faut taper $x_{12}$.
  • Pour obtenir un exposant, il faut utiliser ^ (accent circonflexe qui s’obtient en tapant deux fois la touche «^»). Par exemple, $x^2$ donne $x^2$. De même que pour les indices, $x^23$ donne $x^23$ tandis que $x^{23}$ donne $x^{23}$.
  • On peut bien sûr combiner les deux, dans l’ordre que l’on veux : $x_1^2$ ou $x^2_1$ donnent $x^2_1$

Symboles d'usage courant

Résultat Commande Résultat Commande Résultat Commande
$\infty$ \infty $\le$ \le $\iff$ \iff
$\forall$ \forall $\leq$ \leq $\nearrow$ \nearrow
$\exists$ \exists $\ge$ \ge $\searrow$ \searrow
$\nexists$ \nexists $\geq$ \geq $\in$ \in
$\partial$ \partial $\approx$ \approx $\subset$ \subset
$\ell$ \ell $\simeq$ \simeq $\cup$ \cup
$\pm$ \pm $\equiv$ \equiv $\cap$ \cap
$\mp$ \mp $\to$ \to $\setminus$ \setminus
$\times$ \times $\mapsto$ \mapsto $\emptyset$ \emptyset
$\neq$ \neq $\implies$ \implies

Pour la négation d'un symbole, on peut utiliser \not. Par exemple, $F \not\subset E$ fournit $F \not\subset E$.

Racine carrée, racine n-ième

La racine carrée s'obtient par \sqrt{...} et la racine n-ième par \sqrt[n]{...}:

$$

\sqrt{1+x} + \sqrt[3]{1+x} $$

$$\sqrt{1+x} + \sqrt[3]{1+x}$$

Fractions et coefficients binomiaux

Pour les fractions, on utilise la commande \frac{}{} qui prend deux arguments, dans l'ordre le numérateur et le dénominateur.
Pour les coefficients binomiaux on utilise la commande \binom{}{}.
Le rendu change selon qu'il s'agit d'une formule inline ou d'une formule displaystyle:
$\frac{1}{2}+1$ donne $\frac{1}{2}+1$
$$\frac{1}{2}+1$$ donne $$\frac{1}{2}+1$$

Lettres grecques

Pour taper les lettres grecques, il suffit de précéder le nom de la lettre par un backslash; par exemple $\alpha$ donne $\alpha$. Voici une liste complète des lettres grecques disponibles sous $\LaTeX$:

Résultat Commande Résultat Commande Résultat Commande
$ \alpha$ \alph$ $ \nu$ \nu $ \Gamma$ \Gamma
$ \beta$ \beta $ \xi$ \xi $ \Delta$ \Delta
$ \gamma$ \gamma $ \pi$ \pi $ \Theta$ \Theta
$ \delta$ \delta $ \varpi$ \varpi $ \Lambda$ \Lambda
$ \epsilon$ \epsilon $ \rho$ \rho $ \Xi$ \Xi
$ \varepsilon$ \varepsilon $ \varrho$ \varrho $ \Pi$ \Pi
$ \zeta$ \zeta $ \sigma$ \sigma $ \Sigma$ \Sigma
$ \eta$ \eta $ \tau$ \tau $ \Upsilon$ \Upsilon
$ \theta$ \theta $ \upsilon$ \upsilon $ \Phi$ \Phi
$ \vartheta$ \vartheta $ \chi$ \chi $ \Psi$ \Psi
$ \iota$ \iota $ \phi$ \phi $ \Omega$ \Omega
$ \kappa$ \kappa $ \varphi$ \varphi
$ \lambda$ \lambda $ \psi$ \psi
$ \mu$ \mu $ \omega$ \omega

Texte dans une formule displaystyle

La commande \text{} permet d'insérer du texte dans une formule displaystyle (les commandes \quad et \qquad insèrent de l'espace autour du texte):

$$

y = x^2 \qquad \text{et donc} \quad x = \pm\sqrt{y} $$

donne $$y = x^2 \qquad \text{et donc} \quad x = \pm\sqrt{y} $$

Fonctions mathématiques

Résultat Commande Résultat Commande Résultat Commande Résultat Commande
$\exp$ \exp $\cos$ \cos $\cosh$ \cosh $\lim$ \lim
$\ln$ \ln $\sin$ \sin $\sinh$ \sinh $\limsup$ \limsup
$\lg$ \lg $\tan$ \tan $\tanh$ \tanh $\liminf$ \liminf
$\log$ \log $\cot$ \cot $\coth$ \coth $\max$ \max
$\inf$ \inf $\arccos$ \arccos $\gcd$ \gcd $\sup$ \sup
$\det$ \det $\arcsin$ \arcsin $\hom$ \hom $\min$ \min
$\deg$ \deg $\arctan$ \arctan $\ker$ \ker $\arg$ \arg
$\dim$ \dim

 Grands opérateurs: intégrales, sommes, produits, etc.

Le rendu des grands opérateurs change selon qu'il s'agit d'une formule inline ou d'une formule displaystyle. Certaines de ces commandes prennent, tout comme $\max$ ou $\lim$, des bornes. Le principe est le même, on utilise des indices ou des exposants pour les taper. Le placement des indices et exposants dépend à nouveau de si la formule est mise en évidence ou pas.
$\int_a^b f(x) dx$ et $\sum_{i=0}^n u_n$ donnent $\int_a^b f(x) dx$ et $\sum_{i=0}^n u_n$
$$\int_a^b f(x) dx$$ et $$\sum_{i=0}^n u_n$$ donnent $$\int_a^b f(x) dx$$ et $$\sum_{i=0}^n u_n$$

Ponctuellement et seulement si absolument nécessaire, dans une formule inline

  • on peut forcer le positionnement des indices avec \limits:
    $\int\limits_a^b f(x) dx$ et $\sum\limits_{i=0}^n u_n$ donnent $\int\limits_a^b f(x) dx$ et $\sum\limits_{i=0}^n u_n$
  • on peut forcer la dimension et le positionnement des indices avec \displaystyle
    $\displaystyle\int_a^b f(x) dx$ et $\displaystyle\sum_{i=0}^n u_n$ donnent $\displaystyle\int_a^b f(x) dx$ et $\displaystyle\sum_{i=0}^n u_n$
Résultat inline Commande Résultat displaystyle Commande
$\int$ $\int$ $\displaystyle\int$ $$\int$$
$\iint$ $\iint$ $\displaystyle\iint$ $$\iint$$
$\iiint$ $\iiint$ $\displaystyle\iiint$ $$\iiint$$
$\sum$ $\sum$ $\displaystyle\sum$ $$\sum$$
$\prod$ $\prod$ $\displaystyle\prod$ $$\prod$$
$\bigcup$ $\bigcup$ $\displaystyle\bigcup$ $$\bigcup$$
$\bigcap$ $\bigcap$ $\displaystyle\bigcap$ $$\bigcap$$
$\bigsqcup$ $\bigsqcup$ $\displaystyle\bigsqcup$ $$\bigsqcup$$
$\bigoplus$ $\bigoplus$ $\displaystyle\bigoplus$ $$\bigoplus$$
$\bigotimes$ $\bigotimes$ $\displaystyle\bigotimes$ $$\bigotimes$$
$\coprod$ $\coprod$ $\displaystyle\coprod$ $$\coprod$$

Pour mettre plusieurs lignes dans les indices, il faut utiliser \substack{}; à l'intérieur de l'argument de \substack, on passe à la ligne avec \\.

$$

Li(x)=\prod{\substack{j=0\j\neq i}}^n\frac{x-x_j}{x_i-x_j} $$

donne $$L_i(x)=\prod_{\substack{j=0\\j\neq i}}^n\frac{x-x_j}{x_i-x_j}$$

Accents mathématiques

Voici les accents pouvant se mettre sur une lettre seule:

Résultat Commande Résultat Commande Résultat Commande
$\tilde{a}$ \tilde{a} $\mathring{a}$ \mathring{a} $\dot{a}$ \dot{a}
$\vec{a}$ \vec{a} $\grave{a}$ \grave{a} $\ddot{a}$ \ddot{a}
$\hat{a}$ \hat{a} $\acute{a}$ \acute{a} $\dddot{a}$ \dddot{a}
$\bar{a}$ \bar{a} $\breve{a}$ \breve{a} $\ddddot{a}$ \ddddot{a}
$\check{a}$ \check{a}

Il existe aussi des accents extensibles:

Résultat Commande Résultat Commande Résultat Commande
$\widehat{abc}$ \widehat{abc} $\widetilde{abc}$ \widetilde{abc} $\overleftarrow{abc}$ \overleftarrow{abc}
$\overline{abc}$ \overline{abc} $\underbrace{abc}$ \underbrace{abc} $\underleftarrow{abc}$ \underleftarrow{abc}
$\underline{abc}$ \underline{abc} $\overrightarrow{abc}$ \overrightarrow{abc} $\overleftrightarrow{abc}$ \overleftrightarrow{abc}
$\overbrace{abc}$ \overbrace{abc} $\underrightarrow{abc}$ \underrightarrow{abc} $\underleftrightarrow{abc}$ \underleftrightarrow{abc}

Pour \underbrace il est possible de placer du matériel en-dessous en utilisant _ et pour \overbrace du matériel au-dessus en utilisant ^:

$$

\underbrace{x^3 + x^2 + x + 1}_{\to 0} \qquad \overbrace{x^3 + x^2 + x + 1}^{= 0} $$

donne $$\underbrace{x^3 + x^2 + x + 1}_{\to 0} \qquad \overbrace{x^3 + x^2 + x + 1}^{= 0}$$

Délimiteurs

Résultat Commande Résultat Commande Résultat Commande
$($ ( $/$ / $\lfloor$ \lfloor
$)$ ) $\backslash$ \backslash $\rfloor$ \rfloor
$[$ [ $\lvert$ \lvert $\lceil$ \lceil
$]$ ] $\rvert$ \rvert $\rceil$ \rceil
$\{$ \{ $\lVert$ \lVert $\langle$ \langle
$\}$ \} $\rVert$ \rVert $\rangle$ \rangle
rien .

Il est important de comprendre que, même si \lvert et \rvert se ressemblent, ils ne peuvent pas être interchangés: \lvert doit toujours être utilisé pour ouvrir et \rvert pour refermer. Par exemple, $\lvert x\rvert$ se tape $\lvert x \rvert$. Les seuls délimiteurs à n'être ni ouvrant ni fermant mais médian sont le slash /, l'anti-slash \ et le \middle.

Pour avoir des délimiteurs qui sont de la même taille que ce qu'ils entourent, il faut précéder le délimiteur ouvrant par \left et le délimiteur fermant par \right:

$$

(1+\frac{1}{n})^n $$ donne $$(1+\frac{1}{n})^n$$

$$

\left(1+\frac{1}{n}\right)^n $$ donne $$\left(1+\frac{1}{n}\right)^n$$

Voici un exemple d'utilisation d'un délimiteur vide:

$$

\left.\frac{\partial P}{\partial T}\right|{V}=\frac{nR}{V} $$ donne $$\left.\frac{\partial P}{\partial T}\right|{V}=\frac{nR}{V}$$

On peut aussi utiliser \middle pour mettre un délimiteur médian au milieu d'un couple \left et \right, comme dans la définition d'un ensemble:

$$

\left{ x \middle| x^2<\frac{1}{2} \right} $$

donne $$\left\{ x \middle| x^2<\frac{1}{2} \right\}$$ On note qu'ici la barre verticale est trop proche de ce qu'il y a autour d'elle et il faut rajouter à la main deux petits espaces avec la commande \,:

$$

\left{ x \, \middle| \, x^2<\frac{1}{2} \right} $$ donne $$\left{ x \, \middle| \, x^2<\frac{1}{2} \right}$$

Alphabets mathématiques

Voici un résumé des alphabets mathématiques disponibles:

Résultat Commande Résultat Commande
$C$ C $x$ x
$\mathbb{C}$ \mathbb{C} $\mathrm{x}$ \mathrm{x}
$\mathcal{C}$ \mathcal{C} $\mathbf{x}$ \mathbf{x}
$\mathscr{C}$ \mathscr{C} $\boldsymbol{\sigma}$ \boldsymbol{\sigma}
$\mathfrak{C}$ \mathfrak{C} $\mathit{PGL}$ \mathit{PGL}

Ne pas confondre \mathrm et \text: le premier est pour mettre des maths en romain tandis que le second est pour insérer du texte dans une formule.

Tableaux mathématiques

Pour composer des tableaux mathématiques on utilise l'environnement {array}.
Cet environnement prend un argument obligatoire qui est la spécification du type des colonnes.
Les types de colonnes de base sont c (centré), l (aligné à gauche) et r (aligné à droite).
Le texte des différentes colonnes est séparé par un & et on passe à la ligne suivante en utilisant \\.
Pour rajouter un trait vertical entre deux colonnes, il suffit de mettre un | (qu'on obtient avec la combinaison de touches "AltGr+6") dans la spécification des colonnes.
Pour tracer un trait horizontal, il y a la commande \hline. Cette commande doit être soit au tout début du tableau soit après un \\.

$$
\begin{array}{|c|c|} \hline f(x) & f'(x)\\ \hline x^n & nx^{n-1}\\ \ln(x) & \frac{1}{x}\\ \hline \end{array}$$ donne $$\begin{array}{|c|c|} \hline f(x) & f'(x)\\ \hline x^n & nx^{n-1}\\ \ln(x) & \frac{1}{x}\\ \hline \end{array}

$$

Distinction de cas

Pour définir une fonction par morceaux on peut utiliser l'environnement {cases}, qui s'utilise de la façon suivante:

$$

H(x) = \begin{cases} 0 & \text{si $x < 0$,} \\ 1 & \text{si $x \geq 0$.} \end{cases} $$

donne $$ H(x) = \begin{cases} 0 & \text{si $x < 0$,} \\ 1 & \text{si $x \geq 0$.} \end{cases} $$

Matrices

On tape les matrices comme des tableaux, sauf qu'on utilise les environnements {matrix}, {pmatrix}, {bmatrix}, {Bmatrix}, {vmatrix}, {Vmatrix} ou {smallmatrix}:

$$
\begin{matrix} a & b \\ c & d \end{matrix}


\quad \begin{pmatrix} a & b \\ c & d \end{pmatrix} \quad \begin{bmatrix} a & b \\ c & d \end{bmatrix} \quad \begin{Bmatrix} a & b \ c & d \end{Bmatrix} \quad \begin{vmatrix} a & b \\ c & d \end{vmatrix} \quad \begin{Vmatrix} a & b \ c & d \end{Vmatrix} \quad \begin{smallmatrix} a & b \\ c & d \end{smallmatrix} $$

donne$$ \begin{matrix} a & b \\ c & d \end{matrix} \quad \begin{pmatrix} a & b \\ c & d \end{pmatrix} \quad \begin{bmatrix} a & b \\ c & d \end{bmatrix} \quad \begin{Bmatrix} a & b \\ c & d \end{Bmatrix} \quad \begin{vmatrix} a & b \\ c & d \end{vmatrix} \quad \begin{Vmatrix} a & b \\ c & d \end{Vmatrix} \quad \begin{smallmatrix} a & b \\ c & d \end{smallmatrix} $$

Alignement de formules

Pour aligner plusieurs formules, on dispose des environnements {align} et {multline} (il n'est pas nécessaire d'utiliser les $$...$$). Ne jamais mettre de \\ sur la dernière ligne de ces environnements.

  • L'environnement {align} permet d'aligner plusieurs signes d'égalité à l'intérieur d'une même formule:
\begin{align}

A & = B \ & = C+D \ & = E \end{align}

donne \begin{align} A & = B \\ & = C+D \\ & = E \end{align} On peut au besoin mettre plusieurs équations en colonne:

\begin{align}

A & = B & E & = F & I & = J \ & = C+C & & = G & & = K \ & = D & & & & \end{align}

donne \begin{align} A & = B & E & = F & I & = J \\ & = C+C & & = G & & = K \\ & = D & & & & \end{align}

  • L'environnement {multline} permet de découper une formule trop grande en plusieurs morceaux sans contrôle précis de l'alignement:
\begin{multline}

A+B+C+D+E+F+G+H+I+J\ +A+B+C+D+E+F+G+H+I+J\ +A+B+C+D+E+F+G+H+I+J\ +A+B+C+D+E+F+G+H+I+J \end{multline}

donne \begin{multline} A+B+C+D+E+F+G+H+I+J\\ +A+B+C+D+E+F+G+H+I+J\\ +A+B+C+D+E+F+G+H+I+J\\ +A+B+C+D+E+F+G+H+I+J \end{multline}

Le package $\texttt{amsmath}$ de $\LaTeX$ défini d'autres environnements, vous pouvez les utiliser (après avoir lu la documentation du package et compris dans quels cas il faut utiliser un environnement plutôt qu'un autre). En revanche, l'utilisation de l'environnement {eqnarray} pour mettre en forme une formule sur plusieurs lignes, qu'on peut trouver dans certains vieux manuels, sera considéré comme une faute grave. Cet environnement a plusieurs défauts bien illustré dans ce document: Avoid eqnarray!

Flèches extensibles

On dispose de deux flèches extensibles, \xleftarrow[]{} et \xrightarrow[]{}. Pour mettre une formule dessus, on utilise l'argument obligatoire entre accolades tandis que pour mettre une formule dessous, on utilise l'argument optionnel entre crochets:

$$

f(x) \xrightarrow{\text{d'après }(H)} a \quad f(x) \xrightarrow[x\to0]{} a \quad f(x) \xrightarrow[x\to0]{\text{d'après }(H)} a $$

donne $$ f(x) \xrightarrow{\text{d'après }(H)} a \quad f(x) \xrightarrow[x\to0]{} a \quad f(x) \xrightarrow[x\to0]{\text{d'après }(H)} a $$

Modules de congruences

Selon l'apparence voulue, il y a trois façon d'écrire les modules de congruence:

$a \equiv b \mod m$
$a \equiv b \pmod m$
$a \equiv b \pod m$

donnent
$a \equiv b \mod m$
$a \equiv b \pmod m$
$a \equiv b \pod m$
Il y a aussi la commande \bmod qu'on peut utiliser dans le contexte suivant
$\gcd(n,m\bmod n)$ donne $\gcd(n,m\bmod n)$

Placer au-dessus ou en-dessous

Les commandes \underset{en-dessous}{symbole} et \overset{au-dessus}{symbole} permettent de placer du matériel arbitraire en-dessous ou au-dessus de n'importe quel symbole.

$$

A \overset{\text{déf}}{=} \frac{1}{n} \underset{n \to +\infty}{\in} o\left(\frac{1}{n^2}\right) $$

donne $$ A \overset{\text{déf}}{=} \frac{1}{n} \underset{n \to +\infty}{\in} o\left(\frac{1}{n^2}\right) $$

Mode édition : les celulles Code

Lorsqu'on ouvre un terminal, un programme interpréteur de commandes système est lancé et attend les commandes pour les exécuter. De la même façon, en arrière-plan d'un notebook, un interpréteur de code a été lancé et attend lui aussi qu'on lui donne du code. Dans le coin supérieur droit vous pouvez voir qu'il s'agit ici de l'interpréteur Python 3.

Un notebook est constitué de cellules successives. Les cellules pour écrire du code sont repérables par le prompt In[ ]. Essayons :

In [4]:
2 / 3
Out[4]:
0.6666666666666666

Le texte 2 / 3 a été transmis à l'interpréteur Python 3. Il s'agit d'une expression Python 3 valide. L'interpréteur a donc pu l'évaluer. La valeur de l'expression (dont le type est ici un nombre flottant) est alors récupérée et représentée sous la forme du texte affiché à droite du prompt de sortie

N'oubliez pas que vous êtes dans un notebook. Vous pouvez donc modifier l'expression ci-dessus et la ré-exécuter en appuyant sur [Shift-ENTER]. Le numéro entre crochet est un compteur. Il est incrémenté à chaque sollicitation de l'interpréteur.

In [5]:
h = 2+2

L'exécution de l'instruction ci-dessus n'a produit aucun résultat en sortie. Cette instruction a cependant eu un effet. Elle a modifié l'état de l'interpréteur. En interne, l'interpréteur a associé la valeur de l'expression 2+2 (c'est-à-dire le type entier 4) au nom hauteur.

On peut alors exécuter :

In [6]:
h=2*h
h
Out[6]:
8

Lorsque vous ouvrez un notebook vous le visualisez tel qu'il a été sauvegardé. Vous voyez en particulier les résultats des séquences de code qui ont été exécutées. Cependant, à l'ouverture du notebook, un nouvel interpréteur tout neuf est lancé. Vous devez donc exécuter à nouveau les cellules. Mais dans quel ordre? La réponse naturelle est "dans l'ordre où apparaissent les cellules"... mais cela suppose que la personne qui a réalisé le notebook a fait correctement les choses.

Pour commenter une ou plusieurs lignes, les selectionner et appuyer sur [Ctrl-/]:

Les exceptions

Dans certaines situations, l'interpréteur peut s'interrompre en levant une exception. Les exceptions n'ont rien d'exceptionnelles. On en rencontre souvent, en particulier lorsque l'on commet des erreurs de programmation.

In [7]:
T = [18, 5, 3]
# T[3] # Décommenter la ligne pour voir l'exception

Pour comprendre ce qui a produit l'exception il faut :

  • identifier le nom de l'exception, ici IndexError,
  • lire le message associé, ici 'list index of range',
  • identifier l'instruction qui l'a provoqué, ici l'évaluation de T[3] à la ligne 2.

Il se peut aussi que le code que l'on exécute ne se termine pas :

In [8]:
k = 1
# while k > 0:   # Décommenter pour voir l'exception
#     k = k + 1

Lorqu'une cellule de code s'exécute le prompt comporte une étoile In[ *]. Pour interrompre l'interpréteur, il suffit d'appuyer deux fois sur la touche I. Si cela s'avère nécessaire, il est également possible de redémarrer l'interpréteur. Pour cela il faut appuyer deux fois sur la touche 0. L'interpréteur se retrouve alors dans son état initial.

 Entrée et sortie standard

Les programmes, quels qu'ils soient, lisent des données en provenance de sources variées (fichiers, réseaux, ports usb, etc). Ils envoient eux-mêmes des données vers diverses destinations. Dans tous les cas, cela se traduit par la lecture ou l'écriture de flux d'octets.

Dans un programme Python la fonction print permet d'écrire sur la sortie standard.

In [9]:
print("Accueil s'écrit :")
for x in "accueil":
    print(x)
Accueil s'écrit :
a
c
c
u
e
i
l

Remarquez que l'exécution du code ci-dessus n'a retourné aucune valeur. Il n'y a pas de prompt Out[ ]. Remarquez aussi que chaque fonction print a également envoyé un caractère saut de ligne sur la sortie standard.

L'aide en ligne IPython

  • L'auto-complétion Lorsque vous commencez à saisir un nom connu de l'interpréteur, l'appui sur la touche [TAB] complète le nom automatiquement. Si plusieurs noms sont possibles un menu contextuel vous propose de choisir. Ceci économise de la frappe tout en évitant les erreurs d'orthographe dans les noms des variables.
  • Les infobulles Lorsque le curseur de saisie est sur un nom connu de l'interpréteur (ou immédiatement à droite), l'appui sur [Shift-TAB] affiche une infobulle qui donne un descriptif succinct de l'objet désigné par ce nom. C'est un moyen rapide de vérifier par exemple quels sont les arguments qui sont attendus par une fonction.
  • Documentation en ligne Pour lire la documentation en ligne concernant un objet python (module, fonction, classe, etc), il suffit d'ajouter un ? juste après le nom et d'appuyer sur la touche [Enter]. Un pager s'ouvre alors avec la dite documentation.
In [10]:
?abs

Les commandes systèmes

Lorsque le texte de la cellule débute par un ! alors IPython en déduit que le reste du texte n'est pas du code python mais une commande système qui doit être exécutée par le Shell. Autrement dit IPython peut se substituer au terminal.

In [11]:
# Liste le contenu du dossier courant
!ls -l
total 3604
-rw-rw-r-- 1 minnolina minnolina   36617 févr. 18 10:39 chevre1.png
-rw-rw-r-- 1 minnolina minnolina   29100 févr. 18 10:38 chevre2.png
-rw-rw-r-- 1 minnolina minnolina   32188 févr. 18 10:38 chevre3.png
-rw-rw-r-- 1 minnolina minnolina   32205 juil. 28  2015 erreurEuler.png
-rw-rw-r-- 1 minnolina minnolina   36739 févr. 18 11:14 fraise.png
-rw-rw-r-- 1 minnolina minnolina 1173088 mars   8 16:29 M62-CM1.ipynb
-rw-rw-r-- 1 minnolina minnolina  604731 mars   8 16:35 M62-CM2.ipynb
-rw-rw-r-- 1 minnolina minnolina  207432 mars   8 13:20 M62-CM3.ipynb
-rw-rw-r-- 1 minnolina minnolina  227565 mars   7 13:07 M62-TP1.ipynb
-rw-rw-r-- 1 minnolina minnolina   75804 mars   7 10:18 M62-TP2-NumVSFormel.ipynb
-rw-rw-r-- 1 minnolina minnolina  265506 mars   8 16:16 M62-TP3-Eulers.ipynb
-rw-rw-r-- 1 minnolina minnolina  394900 févr. 15 11:43 M62-TP4-schemas-1.ipynb
-rw-rw-r-- 1 minnolina minnolina  174883 févr. 19 21:57 M62-TP4-schemas-2.ipynb
-rw-rw-r-- 1 minnolina minnolina   39717 févr. 15 17:03 M62-TP5-PbLimites.ipynb
-rw-rw-r-- 1 minnolina minnolina    3719 févr. 18 10:24 M62-TP6-Examen.ipynb
drwxrwxr-x 2 minnolina minnolina    4096 févr. 18 14:49 __pycache__
-rw-rw-r-- 1 minnolina minnolina   31964 mars   8 12:11 R33-2017-DM2-exo2-Verhulst-1.png
-rw-rw-r-- 1 minnolina minnolina   12954 avril 23  2018 tikzmagic.py
-rw-rw-r-- 1 minnolina minnolina    1509 mars   4 13:31 Untitled1.ipynb
-rw-rw-r-- 1 minnolina minnolina   12332 mars   7 11:44 Untitled2.ipynb
-rw-rw-r-- 1 minnolina minnolina  192583 févr. 28 13:14 Untitled.ipynb

Les commandes magiques de IPython

%matplotlib inline & %matplotlib notebook

Si la commande magisue %matplotlib est appelée sans argument, la sortie d'une commande de traçage est affichée à l'aide du backend matplotlib par défaut dans une fenêtre séparée.

Alternativement, le backend peut être explicitement demandé en utilisant, par exemple:

  • %matplotlib inline : la sortie est affichée directement sous la cellule de code qui l’a produite,
  • %matplotlib notebook : la sortie est affichée directement sous la cellule de code qui l’a produite et, de plus, permet des figures interactives.
%pylab inline

Importe les modules numpy et matplotlib. L'option inline indique que les figures Matplotlib seront insérées dans le notebook lui-même plutôt que dans une fenêtre graphique à part.
L'instruction %pylab inline exécute en particulier les deux instructions
import numpy as np
import matplotlib.pyplot as plt

In [12]:
%pylab inline
Populating the interactive namespace from numpy and matplotlib
In [13]:
plot([1,2],[3,4]);
%autosave 300

Sauvegarde automatiquement le notebook tous les 300 secondes (=5 minues)

%who, %whos et %reset

%who, %whos affichent les objets qui sont actuellement définis dans l'interpréteur Python.
%reset efface les variables définie; %reset -f efface les variables définies sans demander confirmation.

In [14]:
%who
T	 h	 k	 x	 
In [15]:
%reset -f
In [16]:
%who
Interactive namespace is empty.

Exporter un notebook

Lorsque vous avez terminé la rédaction de votre document, vous pouvez le télécharger sur l'ordinateur local dans le format qui vous convient. Choisir pour cela File/Download as...

Pour mettre vos notebooks en ligne : nbviewer

Notions de base de Python


In [2]:
# Enable inline plotting
%matplotlib inline 
%autosave 300
Autosaving every 300 seconds

Indentation

Le corps d'un bloc de code (boucles, sous-routines, etc.) est défini par son indentation: l'indentation est une partie intégrante de la syntaxe de Python.

Commentaires

Le symbole dièse # indique le début d'un commentaire: tous les caractères entre # et la fin de la ligne sont ignorés par l'interpréteur.

Variables et affectation

Dans la plupart des langages informatiques, le nom d'une variable représente une valeur d'un type donné stockée dans un emplacement de mémoire fixe. La valeur peut être modifiée, mais pas le type. Ce n'est pas le cas en Python, où les variables sont typées dynamiquement.

In [18]:
b = 2 # b is an integer
print(b)
2
In [19]:
b = b*2.0 # b is a float
print(b)
4.0

L'affectation b = 2 crée une association entre le nom $b$ et le nombre entier $2$. La déclaration b*2.0 évalue l'expression et associe le résultat à $b$; l'association d'origine avec l'entier $2$ est détruite. Maintenant $b$ se réfère à la valeur en virgule flottante $4.0$. Il faut bien prendre garde au fait que l'instruction d'affectation (=) n'a pas la même signification que le symbole d'égalité ($=$) en mathématiques (ceci explique pourquoi l'affectation de $3$ à $x$, qu'en Python s'écrit x = 3, en algorithmique se note souvent $x\leftarrow 3$).

On peut aussi effectuer des affectations parallèles:

In [20]:
a, b = 128, 256
print(a)
print(b)

a,b = b,a
print(a)
print(b)
128
256
256
128

Attention: Python est sensible à la casse. Ainsi, les noms n et N représentent différents objets. Les noms de variables peuvent être non seulement des lettres, mais aussi des mots; ils peuvent contenir des chiffres (à condition toutefois de ne pas commencer par un chiffre), ainsi que certains caractères spéciaux comme le tiret bas _ (appelé underscore en anglais).

Chaîne de caractères (Strings)

Une chaîne de caractères est une séquence de caractères entre guillemets (simples ou doubles). Les chaînes de caractères sont concaténées avec l'opérateur plus +, tandis que l'opérateur : est utilisé pour extraire une portion de la chaîne. Voici un exemple:

In [21]:
string1 = 'Press return to exit'
string2 = 'the program'
print(string1 + ' ' + string2) # Concatenation
print(string1[0:12])# Slicing
Press return to exit the program
Press return

Une chaîne de caractères est un objet immuable, i.e. ses caractères ne peuvent pas être modifiés par une affectation, et sa longueur est fixe. Si on essaye de modifier un caractère d'une chaîne de caractères, Python renvoie une erreur comme dans l'exemple suivant:

In [22]:
s = 'Press return to exit'
#s[0] = 'p' # Décommenter pour voir l'exception

Listes

Une liste est une suite d'objets, rangés dans un certain ordre. Chaque objet est séparé par une virgule et la suite est encadrée par des crochets. Une liste n'est pas forcement homogène: elle peut contenir des objets de types différents les uns des autres. La première manipulation que l'on a besoin d'effectuer sur une liste, c'est d'en extraire et/ou modifier un élément: la syntaxe est ListName[index]. Voici un exemple:

In [23]:
fraise = [12, 10, 18, 7, 15, 3] # Create a list
print(fraise)
fraise[2]
fraise[1] = 11 
print(fraise)
[12, 10, 18, 7, 15, 3]
[12, 11, 18, 7, 15, 3]

En Python, les éléments d'une liste sont indexés à partir de $0$.

In [24]:
fraise[0], fraise[1], fraise[2], fraise[3], fraise[4], fraise[5]
Out[24]:
(12, 11, 18, 7, 15, 3)

Si on tente d'extraire un élément avec un index dépassant la taille de la liste, Python renvoi un message d'erreur:

In [25]:
#fraise[6] # Décommenter pour voir l'exception

On peut extraire une sous-liste en déclarant l'indice de début (inclus) et l'indice de fin (exclu), séparés par deux-points: ListName[i:j], ou encore une sous-liste en déclarant l'indice de début (inclus), l'indice de fin (exclu) et le pas, séparés par des deux-points: ListName[i:j:k].
Cette opération est connue sous le nom de slicing (en anglais).

Un dessin et quelques exemples permettrons de bien comprendre cette opération fort utile:

In [26]:
fraise[2:4]
Out[26]:
[18, 7]
In [27]:
fraise[2:]
Out[27]:
[18, 7, 15, 3]
In [28]:
fraise[:2]
Out[28]:
[12, 11]
In [29]:
fraise[:]
Out[29]:
[12, 11, 18, 7, 15, 3]
In [30]:
fraise[2:5]
Out[30]:
[18, 7, 15]
In [31]:
fraise[2:6]
Out[31]:
[18, 7, 15, 3]
In [32]:
fraise[2:7]
Out[32]:
[18, 7, 15, 3]
In [33]:
fraise[2:6:2]
Out[33]:
[18, 15]
In [34]:
fraise[-2:-4]
Out[34]:
[]
In [35]:
fraise[-4:-2]
Out[35]:
[18, 7]
In [36]:
fraise[-1]
Out[36]:
3

À noter que lorsqu'on utilise des tranches, les dépassements d'indices sont licites.

Voici quelques opérations et méthodes très courantes associées aux listes:

  • a.append(x) ajoute l'élément x en fin de la liste a
  • a.extend(L) ajoute les éléments de la liste L en fin de la liste a, équivaut à a+L
  • a.insert(i,x) ajoute l'élément x en position i de la liste a, équivaut à a[i:i]=x
  • a.remove(x) supprime la première occurrence de l'élément x dans la liste a
  • a.pop([i]) supprime l'élément d'indice i dans la liste a et le renvoi
  • a.index(x) renvoie l'indice de la première occurrence de l'élément x dans la liste a
  • a.count(x) renvoie le nombre d'occurrence de l'élément x dans la liste a
  • a.sort() modifie la liste a en la triant
  • a.reverse() modifie la liste a en inversant les éléments
  • len(a) renvoie le nombre d'éléments de la liste a
  • x in a renvoi True si la liste a contient l'élément x, False sinon
  • x not in a renvoi True si la liste a ne contient pas l'élément x, False sinon
  • max(a) renvoi le plus grand élément de la liste a
  • min(a) renvoi le plus petit élément de la liste a
In [37]:
a = [2, 37, 20, 83, -79, 21] # Create a list
print(a)
[2, 37, 20, 83, -79, 21]
In [38]:
a.append(100) # Append 100 to list
print(a)
[2, 37, 20, 83, -79, 21, 100]
In [39]:
L = [17, 34, 21]
a.extend(L)
print(a)
[2, 37, 20, 83, -79, 21, 100, 17, 34, 21]
In [40]:
a.count(21)
Out[40]:
2
In [41]:
a.remove(21)
In [42]:
print(a)
[2, 37, 20, 83, -79, 100, 17, 34, 21]
In [43]:
a.count(21)
Out[43]:
1
In [44]:
a.pop(4)
Out[44]:
-79
In [45]:
print(a)
[2, 37, 20, 83, 100, 17, 34, 21]
In [46]:
a.index(100)
Out[46]:
4
In [47]:
a.reverse()
In [48]:
print(a)
[21, 34, 17, 100, 83, 20, 37, 2]
In [49]:
a.sort()
In [50]:
print(a)
[2, 17, 20, 21, 34, 37, 83, 100]
In [51]:
len(a) # Determine length of list
Out[51]:
8
In [52]:
a.insert(2,7) # Insert 7 in position 2
In [53]:
print(a)
[2, 17, 7, 20, 21, 34, 37, 83, 100]
In [54]:
a[0] = 21 # Modify selected element
In [55]:
print(a)
[21, 17, 7, 20, 21, 34, 37, 83, 100]
In [56]:
a[2:4] = [-2,-5,-1978] # Modify selected elements
In [57]:
print(a)
[21, 17, -2, -5, -1978, 21, 34, 37, 83, 100]

ATTENTION: si a est une liste, la commande b=a ne crée pas un nouvel objet b mais simplement une référence (pointeur) vers a. Ainsi, tout changement effectué sur b sera répercuté sur a aussi! Pour créer une copie c de la liste a qui soit vraiment indépendante on utilisera la commande deepcopy du module copy comme dans les exemples suivants:

In [58]:
import copy
a = [1.0, 2.0, 3.0]
b = a # 'b' is an alias of 'a'
b[0] = 5.0 # Change 'b'
print(a) # The change is reflected in 'a'
print(b)
[5.0, 2.0, 3.0]
[5.0, 2.0, 3.0]
In [59]:
a = [1.0, 2.0, 3.0]
c = copy.deepcopy(a) # 'c' is an independent copy of 'a'
c[0] = 5.0 # Change 'c'
print(a) # 'a' is not affected by the change
print(c)
[1.0, 2.0, 3.0]
[5.0, 2.0, 3.0]

Qu'est-ce qui se passe lorsque on copie une liste a avec la commande b=a? En effet, une liste fonctionne comme un carnet d'adresses qui contient les emplacements en mémoire des différents éléments de la liste. Lorsque on écrit b=a on dit que b contient les mêmes adresses que a (on dit que les deux listes pointent vers le même objet). Ainsi, lorsqu'on modifie la valeur de l'objet, la modification sera visible depuis les deux alias.

Matrices (sans NumPy)

Les matrices peuvent être représentées comme des listes imbriquées: chaque ligne est un élément d'une liste. Par exemple, le code

In [60]:
a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

définit a comme la matrice $3\times3$ $$ \begin{pmatrix} 1&2&3\\ 4&5&6\\ 7&8&9 \end{pmatrix}. $$ La commande len (comme length) renvoie la longueur d'une liste. On obtient donc le nombre de ligne de la matrice avec len(a) et son nombre de colonnes avec len(a[0]):

In [61]:
print(a)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
In [62]:
print(a[1]) # Print second row (element 1)
[4, 5, 6]
In [63]:
print(a[1][2]) # Print third element of second row
6
In [64]:
print(len(a))
3
In [65]:
print(len(a[0]))
3

Dans Python les indices commences à zéro, ainsi a[0] indique la première ligne, a[1] la deuxième etc. $$ \mathbb{A}= \begin{pmatrix} a_{00} &a_{01}&a_{02}&\dots\\ a_{10} &a_{11}&a_{12}&\dots\\ \vdots &\vdots&\vdots&\vdots \end{pmatrix} $$

Dictionnaires

Un dictionnaire est une sorte de liste mais au lieu d'utiliser des index, on utilise des clés, c'est à dire des valeurs autres que numériques.

Pour initialiser un dictionnaire, on utile la syntaxe suivante:

In [160]:
a={}

Pour ajouter des valeurs à un dictionnaire il faut indiquer une clé ainsi qu'une valeur:

In [161]:
a["nom"] = "engel"
a["prenom"] = "olivier"
print(a)
{'nom': 'engel', 'prenom': 'olivier'}

La méthode get permet de récupérer une valeur dans un dictionnaire et, si la clé est introuvable, de donner une valeur à retourner par défaut:

In [162]:
data={}
data = {"name": "Olivier", "age": 30}
print(data.get("name"))
print(data.get("adresse", "Adresse inconnue"))
Olivier
Adresse inconnue

Pour vérifier la présence d'une clé on utilise in

In [163]:
"nom" in a
Out[163]:
True
In [164]:
"age" in a
Out[164]:
False

Il est possible de supprimer une entrée en indiquant sa clé, comme pour les listes:

In [165]:
del a["nom"]
print(a)
{'prenom': 'olivier'}
  • Pour récupérer les clés on utilise la méthode keys
  • Pour récupérer les valeurs on utilise la méthode values
  • Pour récupérer les clés et les valeurs en même temps, on utilise la méthode items qui retourne un tuple.
In [166]:
fiche = {"nom":"engel","prenom":"olivier"}

for cle in fiche.keys():
    print(cle)

for valeur in fiche.values():
    print(valeur)

for cle,valeur in fiche.items():
    print(cle, valeur)
nom
prenom
engel
olivier
nom engel
prenom olivier

On peut utiliser des tuples comme clé comme lors de l'utilisation de coordonnées:

In [167]:
b = {}
b[(3,2)]=12
b[(4,5)]=13
b
Out[167]:
{(3, 2): 12, (4, 5): 13}

Comme pour les listes, pour créer une copie indépendante utiliser la méthode copy:

In [168]:
d = {"k1":"olivier", "k2":"engel"}
e = d.copy()
print(d)
print(e)
d["k1"] = "XXX"
print(d)
print(e)
{'k1': 'olivier', 'k2': 'engel'}
{'k1': 'olivier', 'k2': 'engel'}
{'k1': 'XXX', 'k2': 'engel'}
{'k1': 'olivier', 'k2': 'engel'}

 Fonction range

La fonction range crée un itérateur. Au lieu de créer et garder en mémoire une liste d'entiers, cette fonction génère les entiers au fur et à mesure des besoins:

  • range(n) renvoi un itérateur parcourant $0,1,2,\dots,n-1$;
  • range(n,m) renvoi un itérateur parcourant $n,n+1,n+2,\dots,m-1$;
  • range(n,m,p) renvoi un itérateur parcourant $n,n+p,n+2p,\dots,m-1$.
In [169]:
A = range(0,10)
print(A)
range(0, 10)

Pour les afficher on crée une list:

In [170]:
A = list(A)
print(A)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [171]:
print(list(range(0)))
[]
In [172]:
print(list(range(1)))
[0]
In [173]:
print(list(range(3,7)))
[3, 4, 5, 6]
In [174]:
print(list(range(0,20,5)))
[0, 5, 10, 15]
In [175]:
print(list(range(0,20,-5)))
[]
In [176]:
print(list(range(0,-20,-5)))
[0, -5, -10, -15]
In [177]:
print(list(range(20,0,-5)))
[20, 15, 10, 5]

Fonction print

Pour afficher à l'écran des objets on utilise la fonction print(object1, object2, ...) qui convertis object1, object2 en chaînes de caractères et les affiche sur la même ligne séparés par des espace.

In [178]:
a = 12345,6789
b = [2, 4, 6, 8]
print(a,b)
(12345, 6789) [2, 4, 6, 8]

Le retour à la ligne peut être forcé par le caractère \n, la tabulation par le caractère \t.

In [179]:
print("a=", a, "\tb=", b)
print("a=", a, "\nb=", b)
a= (12345, 6789) 	b= [2, 4, 6, 8]
a= (12345, 6789) 
b= [2, 4, 6, 8]

Pour mettre en colonne des nombres on pourra utiliser l'opérateur %: la commande print('%format1, %format2,...' %(n1,n2,...) affiche les nombres n1,n2,... selon les règles %format1, %format2,.... Typiquement on utilise

  • wd pour un entier
  • w.df pour un nombre en notation floating point
  • w.de pour un nombre en notation scientifique

w est la largeur du champ total et d le nombre de chiffres après la virgule.

In [180]:
a = 1234.56789
n = 9876
print('%7.2f' %a)
1234.57
In [181]:
print('n = %6d' %n)
n =   9876
In [182]:
print('n = %06d' %n)
n = 009876
In [183]:
print('%12.3f %6d' %(a,n))
    1234.568   9876
In [184]:
print('%12.4e %6d' %(a,n))
  1.2346e+03   9876

Opérations arithmétiques

  • + Addition
  • - Soustraction
  • * Multiplication
  • / Division
  • ** Exponentiation
  • // Quotient de la division euclidienne
  • % Reste de la division euclidienne
In [185]:
a = 100
b = 17
c = a-b
a,b,c
Out[185]:
(100, 17, 83)
In [186]:
a = 2
c = b+a
a,b,c
Out[186]:
(2, 17, 19)
In [187]:
a = 3
b = 4
c = a
a = b
b = c
a, b, c 
Out[187]:
(4, 3, 3)

Certains de ces opérations sont aussi définies pour les chaînes de caractères et les listes comme dans l'exemple suivant:

In [188]:
s = 'Hello '
t = 'to you'
a = [1, 2, 3]
print(3*s) # Repetition
Hello Hello Hello 
In [189]:
print(3*a) # Repetition
[1, 2, 3, 1, 2, 3, 1, 2, 3]
In [190]:
print(a + [4, 5]) # Append elements
[1, 2, 3, 4, 5]
In [191]:
print(s + t) # Concatenation
Hello to you
In [192]:
#print(3 + s) # Décommenter pour voir l'exception

Il existe aussi les opérateurs augmentés:

On écrit Équivaut à
a += b a = a + b
a -= b a = a - b
a *= b a = a * b
a /= b a = a / b
a **= b a = a ** b
a %= b a = a % b

Opérateurs de comparaison et connecteurs logiques

Les opérateurs de comparaison renvoient True si la condition est vérifiée, False sinon. Ces opérateurs sont

On écrit Ça signifie
< $<$
> $>$
<= $\le$
>= $\ge$
== $=$
!= $\neq$
in $\in$

Attention: bien distinguer l'instruction d'affectation = du symbole de comparaison ==.

Pour combiner des conditions complexes (par exemple $x>-2$ et $x^2<5$), on peut combiner des variables booléennes en utilisant les connecteurs logiques:

On écrit Ça signifie
and et
or ou
not non

Deux nombres de type différents (entier, à virgule flottante, etc.) sont convertis en un type commun avant de faire la comparaison. Dans tous les autres cas, deux objets de type différents sont considérés non égaux.

In [193]:
a = 2 # Integer
b = 1.99 # Floating
c = '2' # String
print('a>b?',a>b)
print('a==c?',a==c)
print('(a>b) and (a==c)?',(a>b) and (a==c))
print('(a>b) or (a==c)?',(a>b) or (a==c))
a>b? True
a==c? False
(a>b) and (a==c)? False
(a>b) or (a==c)? True

Fonctions


Supposons de vouloir calculer les images de certains nombres par une fonction polynomiale donnée. Si la fonction en question est un peu longue à saisir, par exemple $f\colon x\mapsto 2x^7-x^6+5x^5-x^4+9x^3+7x^2+8x-1$, il est rapidement fastidieux de la saisir à chaque fois que l'on souhaite calculer l'image d'un nombre par cette fonction.

def

Il est tout à fait possible de définir une fonction (au sens du langage Python) qui ressemble à une fonction mathématique. La syntaxe est la suivante:

def FunctionName(parameters):
    statements
    return values


La déclaration d'une nouvelle fonction commence par le mot-clé def. Ensuite, toujours sur la même ligne, vient le nom de la fonction (ici FunctionName) suivi des paramètres formels de la fonction (ici parameters), placés entre parenthèses, le tout terminé par deux-points (on peut mettre autant de paramètres formels qu'on le souhaite et éventuellement aucun). Une fois la première ligne saisie, on appuie sur la touche Entrée: le curseur passe à la ligne suivante avec une indentation. Si l'instruction return est absente, la fonction renvoi l'objet None.

In [194]:
def f(x):
    return 2*x**7 - x**6 + 5*x**5 - x**4 + 9*x**3 + 7*x**2 + 8*x -1

f(2)
Out[194]:
451

Attention: dès que Python atteint l'instruction return something, il renvoi l'objet something et abandonne aussitôt après l'exécution de la fonction (on parle de code mort pour désigner les lignes qui suivent l'instruction return.

Voici un bêtisier pour mieux comprendre les règles:

  • dans ce premier cas il manque les deux-points en fin de ligne,
In [195]:
#def f(x) # Décommenter pour voir l'exception
  • dans ce deuxième il manque l'indentation,
In [196]:
# Décommenter pour voir l'exception
#def f(x):
#return 2*x**7-x**6+5*x**5-x**4+9*x**3+7*x**2+8*x-1 
  • dans ce troisième il manque le mot return et donc tout appel de la fonction aura comme réponse None,
In [197]:
# Décommenter pour voir l'exception
#def f(x):
#    2*x**7-x**6+5*x**5-x**4+9*x**3+7*x**2+8*x-1
#print(f(2))
  • dans ce quatrième l'instruction print 'Hello' n'est jamais lue par Python car elle apparait après l'instruction return.
In [198]:
def f(x):
	a = 2*x**7-x**6+5*x**5-x**4+9*x**3+7*x**2+8*x-1
	return a
	print('Hello')
    
print(f(2))
451

Attention: les variables définies à l'intérieur d'une fonction ne sont pas visibles depuis l'extérieur de la fonction. On exprime cela en disant qu'une telle variable est locale à la fonction. De plus, si une variable existe déjà avant l'exécution de la fonction, tout se passe comme si, durant l'exécution de la fonction, cette variable était masquée momentanément, puis restituée à la fin de l'exécution de la fonction.

Dans l'exemple suivant, la variable x est une variable locale à la fonction f: crée au cours de l'exécution de la fonction f, elle est supprimée une fois l'exécution terminée:

In [199]:
# Décommenter pour voir l'exception
def f(y):
    x = 2
    return 4.*y

print(f(5))
#print(x)
20.0

Dans l'exemple suivant, la variable x est une variable qui vaut $6$ à l'extérieur de la fonction et $7$ au cours de l'exécution de la fonction f:

In [200]:
x = 6.
def f(y):
    x = 7
    return x*y

print(x)
print(f(1.))
print(x)
6.0
7.0
6.0

Dans l'exemple suivant la fonction derivatives approche les dérivées première et seconde d'une fonction $f$ par les formules \begin{align*} f'(x)&\simeq\frac{f(x+h)-f(x-h)}{2h}, & f''(x)&\simeq\frac{f(x+h)-2f(x)+f(x-h)}{h^2} \end{align*}

In [201]:
import math
def derivatives(f,x,h):
    df  = (f(x+h)-f(x-h))/(2.*h)
    ddf = (f(x+h)-2.*f(x)+f(x-h))/h**2
    return df,ddf

Si on veut calculer la valeur des dérivées première et seconde de la fonction $x\mapsto\cos(x)$ en $x=\frac{\pi}{2}$ il suffit d'écrire

In [202]:
df, ddf = derivatives(math.cos,math.pi/2,1.0e-5)
print('First derivative =', df)
print('Second derivative =', ddf)
First derivative = -0.9999999999898845
Second derivative = 1.6940658945086004e-11

Attention: si une liste est passée comme paramètre d'une fonction et cette fonction la modifie, cette modification se répercute sur la liste initiale. Si ce n'est pas le résultat voulu, il faut travailler sur une copie de la liste.

In [203]:
def squares(a):
    for i in range(len(a)):
        a[i] = a[i]**2

a = [1,2,3,4]
print(a) 
squares(a)
print(a) 
[1, 2, 3, 4]
[1, 4, 9, 16]

Fonctions Lambda (fonctions anonimes)

Quand on définit la fonction $f\colon x\mapsto 2x$ avec

In [204]:
def f(x):
    return 2*x

on fait deux choses: on crée l'objet «fonction qui a $x$ associe $2x$» et on affecte cet objet à une variable (globale) $f$:

In [205]:
f(3)
Out[205]:
6

On peut aussi créer une fonction sans lui donner de nom, c'est une fonction lambda: la ligne

In [206]:
(lambda x: 2*x)(3)
Out[206]:
6

se lit «fonction qui a $x$ associe $2x$» (i.e. $x\mapsto 2x$) évaluée en $x=3$.

La ligne

In [207]:
g = lambda x: x*2
g(3)
Out[207]:
6

équivaut à

In [208]:
def g(x): 
    return x*2 

g(3)
Out[208]:
6

Les fonctions lambda sont surtout utiles pour passer une fonction en paramètre à une autre (par exemple, pour appliquer la fonction à tous les éléments d'une liste):

In [209]:
m = map(lambda x: x+1, [1, 3, 42])  
list(m)
Out[209]:
[2, 4, 43]

Une fonction lambda peut avoir plusieurs paramètres:

In [210]:
somme = lambda x,y : x + y
somme(10, 3)  
Out[210]:
13

Pour éviter la tentation de code illisible, Python limite les fonctions lambda: une seule ligne et return implicite. Si on veut écrire des choses plus compliquées, on utilise def (on peut toujours). Même avec ces limitations, on peut souvent s'en sortir. Par exemple

In [211]:
def abs_avec_def(x):
    if x >= 0:
        return x
    else:
        return -x
list(map(abs_avec_def, [-1, 0, 42]))  
Out[211]:
[1, 0, 42]

est équivalent à

In [212]:
list(map(lambda x: x if x >= 0 else -x, [-1, 0, 42]))  
Out[212]:
[1, 0, 42]

Cependant, dans des nombreuses situations il sera plus simple d'utiliser les list-comprehensions.

List-comprehensions

Les listes définies par compréhension permettent de générer des listes de manière très concise sans avoir à utiliser des boucles. La syntaxe pour définir une liste par compréhension est très proche de celle utilisée en mathématiques pour définir un ensemble:

  • en mathématiques: $\big\{\ f(x)\ \big|\ x\in E\ \big\}$
  • en python: [f(x) for x in E]
In [213]:
liste = [2, 4, 6, 8, 10]
In [214]:
[3*x for x in liste] 
Out[214]:
[6, 12, 18, 24, 30]
In [215]:
[[x,x**3] for x in liste] 
Out[215]:
[[2, 8], [4, 64], [6, 216], [8, 512], [10, 1000]]
In [216]:
[3*x for x in liste if x>5]
Out[216]:
[18, 24, 30]
In [217]:
[3*x for x in liste if x**2<50]
Out[217]:
[6, 12, 18]
In [218]:
liste2 = range(3)
[x*y for x in liste for y in liste2]
Out[218]:
[0, 2, 4, 0, 4, 8, 0, 6, 12, 0, 8, 16, 0, 10, 20]

Le code vu à propos des lambda functions

In [219]:
m = map(lambda x: x+1, [1, 3, 42])  
list(m)
Out[219]:
[2, 4, 43]

équivaut à

In [220]:
[x+1 for x in [1, 3, 42]]
Out[220]:
[2, 4, 43]

Pour un entier $n\in\mathbb{N}$ donné, on calcule la liste de ses diviseurs :

In [221]:
n = 100
[d for d in range(1,n+1) if (n%d==0)]
Out[221]:
[1, 2, 4, 5, 10, 20, 25, 50, 100]

Après avoir définie une liste, on affiche d'abord les carrés des éléments de la liste liste donnée, ensuite les nombres paires, enfin les carrés pairs:

In [222]:
liste = [1, 2, 3, 4, 5, 6, 7]
print([x**2 for x in liste])
print([x    for x in liste if x % 2 == 0])
print([x**2 for x in liste if x**2 % 2 == 0])
print([x    for x in [a** 2 for a in liste] if x % 2 == 0])
[1, 4, 9, 16, 25, 36, 49]
[2, 4, 6]
[4, 16, 36]
[4, 16, 36]

Structure conditionnelle


Supposons vouloir définir la fonction valeur absolue: $$ \lvert x\rvert =\begin{cases}x&\text{si }x\ge0,\\-x&\text{sinon.}\end{cases} $$ On a besoin d'une instruction qui opère une disjonction de cas. En Python il s'agit de l'instruction de choix introduite par le mot-clé if. La syntaxe est la suivante:

if condition_1: instruction_1.1 instruction_1.2 elif condition_2: instruction_2.1 instruction_2.2 ... else: instruction_n.1 instruction_n.2

condition_1, condition_2... représentent des ensembles d'instructions dont la valeur est True ou False (on les obtient en général en utilisant les opérateurs de comparaison). La première condition condition_i ayant la valeur True entraîne l'exécution des instructions instruction_i.1 et instruction_i.2. Si toutes les conditions sont fausses, les instructions instruction_n.1 et instruction_n.2 sont exécutées.

Bien noter le rôle essentiel de l'indentation qui permet de délimiter chaque bloc d'instructions et la présence des deux points après la condition du choix (mot clé if) et après le mot clé else.

Voici un exemple pour établir si un nombre est positif:

In [223]:
def sign_of(a):
    if a < 0.0:
        sign = 'negative'
    elif a > 0.0:
        sign = 'positive'
    else:
        sign = 'zero'
    return sign

a = 2.0
print ('a is ' + sign_of(a))  
a = -2.0
print ('a is ' + sign_of(a))  
a = 0.0
print ('a is ' + sign_of(a))  
a is positive
a is negative
a is zero

La fonction valeur absolue peut être définie comme suit:

In [224]:
def val_abs(x):
    if x>0:
        return x
    else:
        return -x

print(val_abs(5))
print(val_abs(-5))
5
5

Boucles


Les structure de répétition se classent en deux catégories: les répétitions conditionnelles pour lesquelles le bloc d'instructions est à répéter autant de fois qu'une condition est vérifiée, et les répétitions inconditionnelles pour lesquelles le bloc d'instructions est à répéter un nombre donné de fois.

Bouclewhile: répétition conditionnelle

Le constructeur while a la forme générale suivante (attention à l'indentation et aux deux points):

while condition: instruction_1 instruction_2

condition représente des ensembles d'instructions dont la valeur est True ou False. Tant que la condition condition a la valeur True, on exécute les instructions instruction_i.

Attention: si la condition ne devient jamais fausse, le bloc d'instructions est répété indéfiniment et le programme ne se termine pas.

Voici un exemple pour créer la liste $\left[1,\frac{1}{2},\frac{1}{3},\frac{1}{4}\right]$:

In [225]:
nMax = 5
n = 1
a = [] # Create empty list
while n<nMax:
    a.append(1.0/n) # Append element to list
    n += 1
print(a)
[1.0, 0.5, 0.3333333333333333, 0.25]

Dans l'exemple suivant on calcul la somme des $n$ premiers entiers:

In [226]:
def somme(n):
    s ,i = 0, 0
    while i<n:
        i += 1
        s += i
    return s
n=100
print(somme(n))
print('En effet n(n+1)/2=',n*(n+1)/2)
5050
En effet n(n+1)/2= 5050.0

 Répétition for

Lorsque l'on souhaite répéter un bloc d'instructions un nombre déterminé de fois, on peut utiliser un compteur actif, c'est-à-dire une variable qui compte le nombre de répétitions et conditionne la sortie de la boucle. C'est la structure introduite par le mot-clé for qui a la forme générale suivante (attention à l'indentation et aux deux points):

for target in sequence: instruction_1 instruction_2

target est le compteur actif et sequence est un itérateur (souvent généré par la fonction range ou une liste ou une chaîne de caractères). Tant que target appartient à sequence, on exécute les instructions instruction_i.

Voici un exemple pour créer la liste $\left[1,\frac{1}{2},\frac{1}{3},\frac{1}{4}\right]$ avec un itérateur généré par la fonction range:

In [227]:
nMax = 5
a = [] # Create empty list
for n in range(1,nMax):
    a.append(1/n) # Append element to list
print(a)
[1.0, 0.5, 0.3333333333333333, 0.25]

La même avec avec une list-comprhension:

In [228]:
a=[1/n for n in range(1,nMax)]
print(a)
[1.0, 0.5, 0.3333333333333333, 0.25]

Interrompre une boucle: break et continue

L'instruction break sort de la plus petite boucle for ou while englobante.

In [229]:
for i in [1,2,3,4,5]:
    if i==4:
        print("J'ai trouvé")
        break
    print(i)
1
2
3
J'ai trouvé
In [230]:
for lettre in 'Notebook IPython':
    if lettre=='P':
        break
    print(lettre)
N
o
t
e
b
o
o
k
 
I

L'instruction continue continue sur la prochaine itération de la boucle.

In [231]:
a=0
while a<=5:
    a+=1
    if a%2==0:
        continue
    print(a)
print("Boucle terminée")
1
3
5
Boucle terminée

Les instructions de boucle ont une clause else qui est exécutée lorsque la boucle se termine par épuisement de la liste (avec for) ou quand la condition devient fausse (avec while), mais pas quand la boucle est interrompue par une instruction break.

La boucle suivante recherche des nombres premiers:

In [232]:
for n in range(2,10):
    for x in range(2,n):
        if n%x==0:
            print(n, 'egale', x, '*', n/x)
            break # on sort de la boucle 'for' interne
    else:
        print(n, 'est un nombre premier')
2 est un nombre premier
3 est un nombre premier
4 egale 2 * 2.0
5 est un nombre premier
6 egale 2 * 3.0
7 est un nombre premier
8 egale 2 * 4.0
9 egale 3 * 3.0

Modules


Un module est une collection de fonctions. Il y a différents types de modules: ceux qui sont inclus dans la version de Python comme random ou math, ceux que l'on peut rajouter comme numpy ou matplotlib et ceux que l'on peut faire soi-même (il s'agit dans les cas simples d'un fichier Python contenant un ensemble de fonctions).

Pour importer un module, on peut utiliser la commande import ModuleName. Il est alors possible d'obtenir une aide sur le module avec la commande help(ModuleName). La liste des fonctions définies dans un module peut être affichée par la commande dir(ModuleName). Les fonctions s'utilisent sous la forme ModuleName.FunctionName(parameters).

Il est également possible d'importer le contenu du module sous la forme from ModuleName import * et alors les fonctions peuvent être utilisées directement par FunctionName(parameters).

Python offre par défaut une bibliothèque de plus de deux cents modules qui évite d'avoir à réinventer la roue dès que l'on souhaite écrire un programme. Ces modules couvrent des domaines très divers: mathématiques (fonctions mathématiques usuelles, calculs sur les réels, sur les complexes, combinatoire\dots), administration système, programmation réseau, manipulation de fichiers, etc. Ici on en présente seulement quelques-uns, à savoir ce dont on se servira dans les projets.

Le module math

Dans Python seulement quelque fonction mathématique est prédéfinie:

  • abs(a) Valeur absolue de $a$
  • max(suite) Plus grande valeur de la suite
  • min(suite) Plus petite valeur de la suite
  • round(a,n) Arrondi $a$ à $n$ décimales près
  • pow(a,n) Exponentiation, renvoi $a^n$
  • sum(L) Somme des éléments de la suite
  • divmod(a,b) Renvoie quotient et reste de la division de $a$ par $b$
  • cmp(a,b) Renvoie $\begin{cases}-1&\text{si }a<b,\\0&\text{si }a=b,\\1&\text{si }a>b.\end{cases}$
    Toutes les autres fonctions mathématiques sont définies dans le module math. Comme mentionné précédemment, on dispose de plusieurs syntaxes pour importer un module:
In [233]:
import math
print(math.pi)
print(math.sin(math.pi))
print(math.log(1.0))
3.141592653589793
1.2246467991473532e-16
0.0
In [234]:
from math import *
print(pi)
print(sin(pi))
print(log(1.0))
3.141592653589793
1.2246467991473532e-16
0.0

Voici la liste des fonctions définies dans le module math:

In [235]:
import math
dir(math)
Out[235]:
['__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__',
 'acos',
 'acosh',
 'asin',
 'asinh',
 'atan',
 'atan2',
 'atanh',
 'ceil',
 'copysign',
 'cos',
 'cosh',
 'degrees',
 'e',
 'erf',
 'erfc',
 'exp',
 'expm1',
 'fabs',
 'factorial',
 'floor',
 'fmod',
 'frexp',
 'fsum',
 'gamma',
 'gcd',
 'hypot',
 'inf',
 'isclose',
 'isfinite',
 'isinf',
 'isnan',
 'ldexp',
 'lgamma',
 'log',
 'log10',
 'log1p',
 'log2',
 'modf',
 'nan',
 'pi',
 'pow',
 'radians',
 'sin',
 'sinh',
 'sqrt',
 'tan',
 'tanh',
 'tau',
 'trunc']

Notons que le module définit les deux constantes $\pi$ (pi) et $e$ (e).

Le module random

Ce module propose diverses fonctions permettant de générer des nombres (pseudo-)aléatoires qui suivent différentes distributions mathématiques. Il apparait assez difficile d'écrire un algorithme qui soit réellement non-déterministe (c'est-à-dire qui produise un résultat totalement imprévisible). Il existe cependant des techniques mathématiques permettant de simuler plus ou moins bien l'effet du hasard. Voici quelques fonctions fournies par ce module:

  • random.range(p,n,h) choisit un éléments aléatoirement dans la liste range(p,n,h)
  • random.randint(a,b) choisit un entier aléatoirement dans l'intervalle $[a;b]$
  • random.choice(seq) choisit un éléments aléatoirement dans la liste seq
  • random.random() renvoie un décimal aléatoire dans $[0;1[$
  • random.uniform(a,b) choisit un décimal aléatoire dans $[a;b]$

Dessiner des courbes avec le module matplotlib


Le tracé de courbes scientifiques peut se faire à l'aide du module matplotlib.
Matplotlib est un package complet; pylab et pyplot sont des modules de matplotlib qui sont installés avec matplotlib.
Pylab associe les fonctions de pyplot (pour les tracés) avec les fonctionnalité du module numpy pour obtenir un environnement très proche de celui de MATLAB.

On peut écrire et exécuter des script Python (qui utilisent Matplotlib) en ligne à l'adresse https://trinket.io/python/a8645625fd
Pour l'utiliser, on peut importer le module pylab.

La référence complète de matplotlib est lisible à l'adresse: http://matplotlib.sourceforge.net/matplotlib.pylab.html Il est en particulier recommandé de regarder les screenshots (captures d'écrans), qui sont donnés avec le code utilisé pour les générer.

Vous pouvez consulter aussi

1D

Pour tracer le graphe d'une fonction $f\colon[a,b]\to\mathbb{R}$, Python a besoin d'une grille de points $x_i$ où évaluer la fonction, ensuite il relie entre eux les points $(x_i,f(x_i))$ par des segments. Plus les points sont nombreux, plus le graphe est proche du graphe de la fonction $f$. Pour générer les points $x_i$ on peut utiliser

  • l'instruction linspace(a,b,n+1) qui construit la liste de $n+1$ éléments $$ \left[a,a+h,a+2h,\dots,b=a+nh\right] \quad\text{avec } h=\frac{b-a}{n} $$
  • ou l'instruction arange(a,b,h) qui construit la liste de $n=E(\frac{b-a}{h})+1$ éléments $$ \left[a,a+h,a+2h,\dots,a+nh\right] $$ Voici un exemple avec une sinusoïde:
In [236]:
%matplotlib inline
from matplotlib.pylab import *
x = linspace(-5,5,101) # x = [-5,-4.9,-4.8,...,5] with 101 elements
y = sin(x) # operation is broadcasted to all elements of the array
plot(x,y);
#show()

ou encore

In [237]:
from matplotlib.pylab import *
x = arange(-5,5,0.1) # x = [-5,-4.9,-4.8,...,5] with 101 elements
y = sin(x) # operation is broadcasted to all elements of the array
plot(x,y);
# show()

On obtient une courbe sur laquelle on peut zoomer, modifier les marge et sauvegarder dans différents formats.

Plusieurs courbes sur le même repère

On peut même tracer plusieurs courbes sur la même figure. Par exemple, dans la figure suivante, on a tracé la même fonction: la courbe bleu correspond à la grille la plus grossière, la courbe rouge correspond à la grille la plus fine:

In [238]:
from matplotlib.pylab import *
a = linspace(-5,5,5) 
fa = sin(a) # matplotlib importe numpy qui redefinie les fonctions de base pour pouvoir les appliquer a un vecteur
plot(a,fa,'b-',label="$f(a)$");
b = linspace(-5,5,101) 
fb = sin(b) 
plot(b,fb,'r-.',label="$f(b)$" );
legend();

Pour tracer plusieurs courbes sur le même repère, on peut les mettre les unes à la suite des autres en spécifiant la couleur et le type de trait, changer les étiquettes des axes, donner un titre, ajouter une grille, une légende etc.

Par exemple, dans le code ci-dessous "r-" indique que la première courbe est à tracer en rouge (red) avec un trait continu, et "g." que la deuxième est à tracer en vert (green) avec des points.

In [239]:
from matplotlib.pylab import *
x = linspace(-5,5,101) 
y1 = sin(x)            
y2 = cos(x)
plot(x,y1,"r-",x,y2,"g.")
legend(['sinus','cosinus'])
xlabel('abscisses')
ylabel('ordonnees')
title('Comparaison de sin(x) et cos(x)')
grid(True)

Quelques options de pylab:

Line style Color Symbols
- solid line b blue v triangle down symbols
-- dashed line r red > triangle right symbols
: dotted line m magenta + plus symbols
-. dash-dot line k black D diamond symbols
. points g green , pixels
o filled circles c cyan < triangle left symbols
^ filled triangles up y yellow s square symbols
w white x cross symbols
* star symbols

On peut déplacer la légende en spécifiant l'une des valeurs suivantes:

best, upper right, upper left, lower right, lower left, center right, center left, lower center, upper center, center:

In [240]:
from matplotlib.pylab import *
x = arange(-pi,pi,0.05*pi)
plot(x,sin(x),'co',x,cos(x),'mD')
legend(['sinus','cosinus'],loc='upper left')
axis([-pi, pi, -1, 1]) # axis([xmin, xmax, ymin, ymax])
Out[240]:
[-3.141592653589793, 3.141592653589793, -1, 1]
In [4]:
from matplotlib.pylab import *

a = linspace(-5,5,5) 
fa = sin(a) 
plot(a,fa,ls='--', lw=3, color="blue", label=r"$f(a)$")
b = linspace(-5,5,10) 
fb = sin(b) 
plot(b,fb,ls='--', lw=2.0, color="orange", label=r"$f(b)$")
c = linspace(-5,5,101) 
fc = sin(c) 
plot(c,fc,ls='-.', lw=0.5, color="green", label=r"$f(c)$")

plot([0], [0.5], lw=0.5, marker='o', color="cyan")
text(0, 0.6,r"$\sigma_i$", horizontalalignment='center', fontsize=20)

xlim(-5, 5)
ylim(-1, 1)
yticks([-1, -0.5, 0, 1])
xticks([-4, -2, 0, 2])

xlabel("$x$", fontsize=18)
ylabel("$y$", fontsize=18)

legend(bbox_to_anchor=(1.04,1),loc='upper left', ncol=1, fontsize=14, frameon=False);

Plusieurs "fenêtres" graphiques

On génère deux fenêtres contenant chacune un graphe:

In [242]:
from matplotlib.pylab import *
x = arange(-pi,pi,0.05*pi)
figure(1)
plot(x, sin(x), 'r')
figure(2)
plot(x, cos(x), 'g')
Out[242]:
[<matplotlib.lines.Line2D at 0x7f4701e3aa20>]

Plusieurs repères dans la même fenêtre

La fonction subplot(x,y,z) subdivise la figure sous forme d'une matrice (x,y) et chaque case est numérotée, z étant le numéro de la case où afficher le graphe. La numérotation se fait de gauche à droite, puis de haut en bas, en commençant par $1$.

In [243]:
from matplotlib.pylab import *
x = arange(-pi,pi,0.05*pi)

figure(figsize=(10, 10), facecolor="#f1f1f1")
# axes coordinates as fractions of the canvas width and height
#left, bottom, width, height = 0.1, 0.1, 0.8, 0.8
#axes((left, bottom, width, height), facecolor="#e1e1e1")

subplot(4,3,1)
plot(x, sin(x), 'r')
subplot(4,3,5)
plot(x, cos(x), 'g')
subplot(4,3,9)
plot(x, x*x, 'b')
subplot(4,3,12)
plot(x, exp(-x*x), 'm')
Out[243]:
[<matplotlib.lines.Line2D at 0x7f4702bbdcc0>]

Animations

Pour afficher une animation on utilisera le module animation de matplotlib. Voici un exemple avec deux méthodes différentes : la première utilise la commande magique %matplotlib inline, la deuxième la commande magique %matplotlib notebook qui permet d'intéragir avec l'animation.

In [257]:
%reset -f
%matplotlib inline

from matplotlib.pylab import *
import matplotlib.animation as animation
from IPython.display import display, clear_output

fig = figure()
axis([0,3,-1,1])
line, = plot([],[],lw=2) 

x = linspace(0,3,100)
animate = lambda i: line.set_data(x, cos(2*pi*(x-0.01*i)))

# CI
plot(x,cos(2*pi*x))

# Marche en temps
for i in range(len(x)):
    animate(i)
    clear_output(wait=True)
    display(fig)
clear_output(wait=True)
In [258]:
%reset -f
%matplotlib notebook
%matplotlib notebook
from matplotlib.pylab import *
from matplotlib import animation

x = linspace(0,3,100)

# First set up the figure, the axis, and the plot element we want to animate
fig = figure() # initialise la figure
line, = plot([],[],lw=2) 
axis([0,3,-1,1])

# Define the initialization function, which plots the background of each frame:
# init = lambda : plot([],[]) 
init = lambda : plot(x,cos(2*pi*x))

# Define the animation function, which is called for each new frame:
animate = lambda i: line.set_data(x,cos(2*pi*(x-0.01*i)))

# call the animator. blit=True means only re-draw the parts that have changed. 
ani = animation.FuncAnimation(fig, animate, init_func=init, frames=100, blit=False, interval=20, repeat=False)

# Eventually
# from IPython.display import HTML, Image
# ani.save('animation.gif', writer='imagemagick', fps=60)
# Image(url='animation.gif')

2D

La représentation graphique de l’évolution d’une fonction $f$ de deux variables $x$ et $y$ n'est pas une tâche facile, surtout si le graphique en question est destiné à être imprimé. Dans ce type de cas, un graphe faisant apparaître les lignes de niveaux de la fonction en question peut être une solution intéressante et lisible. Commençons donc par considérer l'exemple simple d'une fonction de la forme: $$ f(x,y)= \frac{\sin(x^2+y^2)}{x^2+y^2} $$

Le tracé de cette fonction en courbes de niveaux va nécessiter la création d’un maillage bidimensionnel permettant de stocker l’intervalle de chacune des variables. La fonction destinée à cela s’appelle meshgrid (incluse dans le module NumPy). On construit donc le maillage en question sur le rectangle $[-5;5]\times[-5;5]$. La fonction meshgrid fait appel dans ce cas à deux fonctions linspace pour chacune des variables. z est ici un objet array qui contient les valeurs de la fonction $f$ sur chaque nœud du maillage.

In [246]:
%matplotlib inline
from matplotlib.pylab import *
x=linspace(-2*pi,2*pi,200)
y=linspace(-2*pi,2*pi,200)
xx,yy = meshgrid(x,y)
z = sin(xx**2 + yy**2) / (xx**2 + yy**2)
In [247]:
imshow(z);

Pour tracer l’évolution de $f$ en lignes de niveaux on utilisera les fonctionscontour et contourf avec comme arguments les variables x et y, les valeurs de z correspondantes (et eventuellement le nombre de lignes de niveaux choisit).

In [248]:
h = contour(x,y,z)
In [249]:
h = contour(x,y,z,20)