formations/python-initiation/initiation.md

1670 lines
23 KiB
Markdown
Raw Normal View History

# Python
2020-02-21 00:16:24 +00:00
notes:
Juste pour le doctest :
2021-02-01 07:51:10 +00:00
```python
import random
random.seed(42)
ingredients = ["sel", "farine", "sucre", "levure", "beurre", "œuf"]
def randint(a, b):
return 4 # https://xkcd.com/221/
2021-02-01 07:51:10 +00:00
il_reste_de_la_pâte = 0
recettes = [
{'titre': 'Broyés du Poitou', 'ingredients': "farine", "durée": 35},
{'titre': 'Œufs mimosa', 'ingredients': "", "durée": 20},
{'titre': 'Houmous', 'ingredients': "", "durée": 13},
]
```
2021-02-01 07:51:10 +00:00
## Python
2020-01-11 22:14:57 +00:00
par
Julien Palard <julien@palard.fr>
2021-02-01 07:51:10 +00:00
https://mdk.fr
notes:
2020-02-21 00:16:24 +00:00
Introduce yourself!
2020-01-11 22:14:57 +00:00
Ça couvre les types de bases survol quelques strucutres de contrôle,
2020-01-11 22:14:57 +00:00
et quelques fonctions natives.
## Python : Introduction
Python est un langage de programmation permettant de s'exprimer de
manière **concise** et **lisible**.
## Qui utilise Python ?
YouTube, Dropbox, Reddit, Instagram, Spotify, NASA…
![](static/Black-hole-M87.jpg)
## Combien utilisent Python ?
![](static/Evolution_of_Python.png)
2021-03-28 08:09:33 +00:00
::: notes
https://insights.stackoverflow.com/trends
2020-01-11 22:14:57 +00:00
## Installation
https://python.org
 ou 
![](static/Anaconda_Logo.png)
2020-02-21 00:16:24 +00:00
::: notes
2020-01-11 22:14:57 +00:00
- On windows use the WSL, or gitforwindows.org if you can't
- https://docs.python.org/3/using/windows.html
- https://docs.python.org/3/using/mac.html
- On windows, don't install from the Microsoft Store.
## Démarrer un interpréteur
Sur Windows :
```text
py
```
Sur tous les autres OS :
```text
python3
```
2020-02-21 00:16:24 +00:00
::: notes
2020-01-11 22:14:57 +00:00
- Définir « Interpréteur »
- `py` sur Windows trouve l'interpréteur le plus récent.
## L'interpréteur
Parfois appelé le *REPL* ou *la console interactive*.
```bash
$ python3
>>> 5 + 2
7
2020-01-11 22:14:57 +00:00
>>>
```
notes:
2020-01-11 22:14:57 +00:00
Permet d'essayer un peu de Python sans pour autant ouvrir un fichier.
Et oui, même après 10 ans de Python, on l'utilise encore.
Expliquer les parties "R", "E", "P", "L".
## L'interpréteur
Il en existe plusieurs : Celui natif à Python, IDLE, IPython, …
Il ressemble généralement soit à ça :
```bash
>>>
```
soit à ça :
```bash
In [1]:
```
## Testons l'interpréteur
2023-05-27 07:28:28 +00:00
```pycon
2020-01-11 22:14:57 +00:00
>>> 10
10
```
2020-02-21 00:16:24 +00:00
notes:
2020-01-11 22:14:57 +00:00
L'interpréteur à lu les caractères `1` `0`, a compris que c'était un
nombre entier, l'a stocké dans sa représentation interne, un objet,
puis nous l'a représenté à son tour avec deux caractères `1` et `0`
pour qu'on puisse le lire.
## C'est votre nouvelle calculatrice
2023-05-27 07:28:28 +00:00
```pycon
2020-01-11 22:14:57 +00:00
>>> 60 * 60 * 4
14400
```
## Les exceptions
2023-05-27 07:28:28 +00:00
```pycon
2020-01-11 22:14:57 +00:00
>>> 5 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
```
notes:
2020-02-21 00:16:24 +00:00
2020-01-11 22:14:57 +00:00
Lisez *TOUJOURS* la dernière ligne en premier !
2020-01-13 17:25:06 +00:00
# Types natifs
## Booléens
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> True
True
>>> False
False
```
2020-02-28 08:33:11 +00:00
## Nombres
2020-01-13 17:25:06 +00:00
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> 42
42
```
2020-02-28 08:33:11 +00:00
## Nombres
2020-01-13 17:25:06 +00:00
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> 18446744073709551616
18446744073709551616
```
2020-02-28 08:33:11 +00:00
## Nombres
2020-01-13 17:25:06 +00:00
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> 3.1415
3.1415
```
## Chaînes de caractères
2023-05-27 07:28:28 +00:00
```pycon
>>> "Beurre ou huile d'olive ?"
"Beurre ou huile d'olive ?"
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-01-13 17:25:06 +00:00
Expliquer ce qu'est une chaîne, sans parler de pointeurs, on est pas
dans un cours de C89.
## Chaînes de caractères
2023-05-27 07:28:28 +00:00
```pycon
>>> 'Cuisson "au beurre" !!'
'Cuisson "au beurre" !!'
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2021-02-01 07:51:10 +00:00
Les triples quotes apparaissent jour 2.
2020-01-13 17:25:06 +00:00
## Listes
2023-05-27 07:28:28 +00:00
```pycon
>>> ["1 kg de farine", "12 œufs", "130 g de beurre"]
['1 kg de farine', '12 œufs', '130 g de beurre']
2020-01-13 17:25:06 +00:00
```
notes:
2020-01-13 17:25:06 +00:00
La représentation est souvent du Python valide.
## Listes
2023-05-27 07:28:28 +00:00
```pycon
>>> ["farine", 1000]
['farine', 1000]
2020-01-13 17:25:06 +00:00
```
notes:
2020-01-13 17:25:06 +00:00
Attention à ne pas abuser du mélange autorisé des types.
## *n*-uplets, *tuple*
2020-01-13 17:25:06 +00:00
2023-05-27 07:28:28 +00:00
```pycon
>>> ("œufs", 12)
('œufs', 12)
>>> ("sucre", 130)
('sucre', 130)
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-02-21 00:16:24 +00:00
C'est la virgule qui fait le n-uplet, pas les parenthèses.
2020-01-13 17:25:06 +00:00
Pensez au *n*-uplet comme une structure C, *a record*, pas comme une
liste, par exemple des coordonnées : (x, y).
2020-01-13 17:25:06 +00:00
## Listes et tuples
2023-05-27 07:28:28 +00:00
```pycon
>>> [("farine", 1000), ("œufs", 12), ("sucre", 130)]
[('farine', 1000), ('œufs', 12), ('sucre', 130)]
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-01-13 17:25:06 +00:00
Une liste c'est de la donnée, ce qu'elle contint c'est de la donnée.
2020-01-13 17:25:06 +00:00
## Ensembles
2020-02-21 00:16:24 +00:00
2020-01-13 17:25:06 +00:00
```python
{"farine", "sucre", "œuf", "levure", "sel", "beurre"}
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-02-21 00:16:24 +00:00
2020-01-13 17:25:06 +00:00
Un ensemble n'est pas ordonné.
## Dictionnaires
```python
{
"un verre": "25 cl",
"un petit verre": "12 cl",
"qs": "quantité suffisante"
}
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-01-13 17:25:06 +00:00
On associe une valeur à une clé. Utile *seulement* si on ne connaît
pas les clefs à l'avance, sinon c'est une classe.
# Les opérateurs
2020-01-13 21:25:16 +00:00
## Les opérateurs mathématiques
2020-01-13 17:25:06 +00:00
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> 10 + 10
20
>>> 10.5 + 2
12.5
```
2020-01-13 21:25:16 +00:00
## Les opérateurs mathématiques
2020-01-13 17:25:06 +00:00
2023-05-27 07:28:28 +00:00
```pycon
2022-03-09 07:41:02 +00:00
>>> (4 * 10**1) + (2 * 10**0)
2020-01-13 17:25:06 +00:00
42
```
2020-01-13 21:25:16 +00:00
## Les opérateurs mathématiques
2020-01-13 17:25:06 +00:00
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> 10 / 2
5.0
```
## Les opérateurs
2023-05-27 07:28:28 +00:00
```pycon
>>> "Bri" + "oche"
'Brioche'
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-02-21 00:16:24 +00:00
2020-01-13 17:25:06 +00:00
It's called concatenation of strings.
## Les opérateurs
2023-05-27 07:28:28 +00:00
```pycon
>>> "mur" * 2
'murmur'
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-02-21 00:16:24 +00:00
2020-01-13 17:25:06 +00:00
Tant qu'il n'y a pas d'ambiguité, c'est implémenté.
## Les opérateurs
2023-05-27 07:28:28 +00:00
```pycon
>>> ["farine", "œufs"] + ["sucre", "sel"]
['farine', 'œufs', 'sucre', 'sel']
2020-01-13 17:25:06 +00:00
```
## Les Comparisons
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> 10 < 1
False
>>> 10 == 10
True
>>> 10 >= 20
False
```
notes:
2020-01-13 17:25:06 +00:00
Déconseiller l'utilisation de `is`, de toute facons PyLint leur dira
quand l'utiliser.
## Logique
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:06 +00:00
>>> True or False
True
>>> True and False
False
>>> not True
False
```
notes:
On utilisera ça plus tard, avec les structures de contrôle.
2020-01-13 17:25:06 +00:00
## Test d'appartenance
2023-05-27 07:28:28 +00:00
```pycon
>>> "chocolat" in "pain au chocolat"
2020-01-13 17:25:06 +00:00
True
```
## Test d'appartenance
2023-05-27 07:28:28 +00:00
```pycon
>>> "sel" in {"farine", "œuf", "sucre", "sel", "levure"}
2020-01-13 17:25:06 +00:00
True
```
## Travailler avec les ensembles
2023-05-27 07:28:28 +00:00
```pycon
>>> {"farine", "sel"} | {"œuf", "sel"} == {"sel", "farine", "œuf"}
2020-01-13 17:25:06 +00:00
True
```
notes:
2020-02-21 00:16:24 +00:00
2020-01-13 17:25:06 +00:00
C'est une union.
## Travailler avec les ensembles
2023-05-27 07:28:28 +00:00
```pycon
>>> {"farine", "levure", "sel"} & {"œuf", "sel", "sucre"}
{'sel'}
2020-01-13 17:25:06 +00:00
```
notes:
2020-02-21 00:16:24 +00:00
2020-01-13 17:25:06 +00:00
Une intersection.
## Mais en cas d'ambiguité…
2023-05-27 07:28:28 +00:00
```pycon
>>> "farine" * "sucre"
2020-01-13 17:25:06 +00:00
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't multiply sequence by non-int of type 'str'
```
## Mais en cas d'ambiguité…
2023-05-27 07:28:28 +00:00
```pycon
>>> {"farine", "levure"} + {"sel", "œuf"}
2020-01-13 17:25:06 +00:00
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'set' and 'set'
```
2020-01-13 21:25:16 +00:00
# Les variables
2020-01-13 17:25:06 +00:00
## Affectation
2023-05-27 07:28:28 +00:00
```pycon
>>> preparation = 20
>>> cuisson = 30
>>> preparation + cuisson
50
2020-01-13 17:25:06 +00:00
```
notes:
2020-01-13 17:25:06 +00:00
JAMAIS dire : On met 20 dans « preparation ».
2020-01-13 17:25:06 +00:00
## Affectation multiple
2023-05-27 07:28:28 +00:00
```pycon
>>> preparation, cuisson = 20, 30
>>> preparation
20
>>> cuisson
30
2020-01-13 17:25:06 +00:00
```
## Accès par indice
2023-05-27 07:28:28 +00:00
```pycon
>>> etapes = ["preparation", "cuisson", "dégustation"]
>>> etapes[0]
'preparation'
>>> etapes[1]
'cuisson'
>>> etapes[2]
'dégustation'
2020-01-13 17:25:06 +00:00
```
2020-02-21 00:16:24 +00:00
notes:
2020-02-21 00:16:24 +00:00
2020-01-13 17:25:06 +00:00
On réutilise le nom pour accéder au contenu.
Bien prendre le temps d'expliquer la syntaxe ici.
## Accès par clé
2023-05-27 07:28:28 +00:00
```pycon
>>> definitions = {
... "un verre": "25 cl",
... "un petit verre": "12 cl",
... "qs": "quantité suffisante"
... }
...
>>> definitions["un petit verre"]
'12 cl'
2020-01-13 17:25:06 +00:00
```
2022-05-16 06:53:07 +00:00
# Les fonctions
2020-01-13 17:25:54 +00:00
## print
2023-05-27 07:28:28 +00:00
```pycon
>>> print("Brioche")
Brioche
2020-01-13 17:25:54 +00:00
```
notes:
2020-01-13 17:25:54 +00:00
C'est leur première fonction, s'attarder sur la syntaxe !
## print
2023-05-27 07:28:28 +00:00
```pycon
>>> print("La moitié de 130 g :", 130 // 2, "g")
La moitié de 130 g : 65 g
2020-01-13 17:25:54 +00:00
```
notes:
2020-01-13 17:25:54 +00:00
En effet, le P de REPL étant `print`, le print est implicite dans un REPL.
Mais le REPL sert a tester : on peut bien tester print dans le REPL.
2021-10-24 20:01:58 +00:00
Exercices:
- Print 42
- Number of seconds in a year
- Using operators
2022-05-16 06:53:07 +00:00
2021-02-01 07:51:10 +00:00
## str, list, int, ...
2023-05-27 07:28:28 +00:00
```pycon
>>> str(130)
'130'
2021-02-01 07:51:10 +00:00
```
## str, list, int, ...
2023-05-27 07:28:28 +00:00
```pycon
>>> int("130")
130
2021-02-01 07:51:10 +00:00
```
2020-01-13 17:25:54 +00:00
## len
2023-05-27 07:28:28 +00:00
```pycon
>>> len(["farine", "œufs", "sucre"])
2020-01-13 17:25:54 +00:00
3
>>> len("farine")
6
2020-01-13 17:25:54 +00:00
```
notes:
2021-10-24 20:01:58 +00:00
Exercise: Character counting
2020-01-13 17:25:54 +00:00
2022-05-16 06:53:07 +00:00
2020-01-13 17:25:54 +00:00
## range
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:25:54 +00:00
>>> list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(range(5, 10))
[5, 6, 7, 8, 9]
```
## help
Affiche la documentation de n'importe quoi, essayez :
- `help(str)`
- `help(list)`
- ...
2020-01-13 17:25:54 +00:00
notes:
2020-01-13 17:25:54 +00:00
Accepte aussi une valeur (et donc une variable) mais attention : si la
variable est une chaîne, `help` n'affichera pas la documentation des
chaînes.
2020-01-13 17:25:54 +00:00
## sorted
2023-05-27 07:28:28 +00:00
```pycon
>>> sorted({"sel", "farine", "sucre"})
['farine', 'sel', 'sucre']
2020-01-13 17:25:54 +00:00
```
2022-05-16 06:53:07 +00:00
## Les importer des modules
2023-05-27 07:28:28 +00:00
```pycon
>>> from random import choice
>>> print(choice(["Pain au chocolat", "Chocolatine"]))
Pain au chocolat
2022-05-16 06:53:07 +00:00
```
notes:
2022-05-16 06:53:07 +00:00
Exercice : Import.
2020-01-13 17:25:54 +00:00
2020-01-13 17:27:55 +00:00
# Les instructions
## if
2023-05-27 07:28:28 +00:00
```pycon
>>> if "sucre" in ingredients and "œuf" in ingredients:
... print("Commencer par blanchir les œufs.")
Commencer par blanchir les œufs.
2020-01-13 17:27:55 +00:00
```
notes:
2020-01-13 17:27:55 +00:00
Parler de l'indentation !
Notez le `...`, on a du appyer un coup en « entrée » pour fermer ce bloc.
1 était premier, avant, mais ça casse le théorème « Every possible
whole number can be written as a _unique_ product of primes ».
2021-02-01 07:51:10 +00:00
## Le `else`
Après un bloc `if`, on peut ajouter un bloc `else` :
2023-05-27 07:28:28 +00:00
```pycon
>>> if "sucre" in ingredients and "œuf" in ingredients:
... print("Commencer par blanchir les œufs.")
... else:
... print("Commencer comme vous voulez.")
Commencer par blanchir les œufs.
2021-02-01 07:51:10 +00:00
```
## Le `elif`
Après un `if`, on peut ajouter un ou des bloc `elif` :
2023-05-27 07:28:28 +00:00
```pycon
>>> grams = 1250
>>> if grams == 0:
... print("Ne pas en mettre")
... elif grams < 1000:
... print("En mettre", grams, "grammes.")
... else:
... kg, g = divmod(grams, 1000)
... print("En mettre", kg, "kg", "et", g, "g.")
...
En mettre 1 kg et 250 g.
2021-02-01 07:51:10 +00:00
```
notes:
2021-02-01 07:51:10 +00:00
Parler de `pass` et de `...`.
2020-01-13 17:27:55 +00:00
## for
2023-05-27 07:28:28 +00:00
```pycon
>>> for ingredient in ingredients:
... print(ingredient)
2020-01-13 17:27:55 +00:00
...
sel
farine
sucre
levure
beurre
œuf
2022-03-09 07:41:02 +00:00
```
2023-05-27 07:28:28 +00:00
```pycon
>>> ingredient = ingredients[0]
>>> print(ingredient)
sel
>>> ingredient = ingredients[1]
>>> print(ingredient)
farine
>>> ingredient = ingredients[2]
>>> print(ingredient)
sucre
2020-01-13 17:27:55 +00:00
```
## for
2023-05-27 07:28:28 +00:00
```pycon
>>> for lettre in "Œuf":
... print(lettre)
2020-01-13 17:27:55 +00:00
...
Œ
u
f
2020-01-13 17:27:55 +00:00
>>>
```
## for
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:27:55 +00:00
>>> for i in range(5):
... print(i)
0
1
2
3
4
```
notes:
Exercice : Square numbers, powers of two, comparisons.
2020-01-13 17:27:55 +00:00
2020-01-13 17:27:55 +00:00
## L'instruction `while`
Très rarement utilisée car le `for` est bien plus pratique, sert
cependant dans quelques cas:
- `while True:`
- `while il_reste_du_travail_à_faire:`
## L'instruction `while`
2023-05-27 07:28:28 +00:00
```pycon
>>> while il_reste_de_la_pâte:
... faire_une_crêpe()
...
2020-01-13 17:27:55 +00:00
```
# Les méthodes
## Sur les chaînes
2023-05-27 07:28:28 +00:00
```pycon
>>> s = "Pâte à crêpe"
>>> s.count("e")
2
>>> s.startswith("Pâte")
True
>>> s.split()
['Pâte', 'à', 'crêpe']
```
notes:
Exercise : Counting Words.
## Sur les chaînes
2023-05-27 07:28:28 +00:00
```pycon
>>> s = "Durée : {} minutes."
>>> s.format(3600 // 60)
'Durée : 60 minutes.'
```
## Sur les listes
2023-05-27 07:28:28 +00:00
```pycon
>>> ingredients = ["1 kg de farine", "12 œufs"]
>>> ingredients.append("130 g de beurre")
>>> ingredients
['1 kg de farine', '12 œufs', '130 g de beurre']
```
## Sur les dictionnaires
2023-05-27 07:28:28 +00:00
```pycon
>>> definitions = {
... "un verre": "25 cl",
... "un petit verre": "12 cl",
... "qs": "quantité suffisante"
... }
>>> definitions.items()
dict_items([('un verre', '25 cl'), ('un petit verre', '12 cl'), ('qs', 'quantité suffisante')])
```
2020-01-13 17:27:55 +00:00
# Les variables (suite)
## Le type des variables
En Python, les variables ne sont que des noms.
Des « étiquettes » qu'on colle aux objets.
2020-01-13 17:27:55 +00:00
> Comme sur les pots de confiture.
2020-01-13 17:27:55 +00:00
## Le type des variables
Seules les valeurs sont typées.
> L'étiquette n'a pas de goût, c'est la confiture qui a du goût.
notes:
Toutes les valeurs sont des objets.
2020-02-21 00:16:24 +00:00
Sans. Exceptions.
2020-01-13 17:27:55 +00:00
On peut « coller » plusieurs étiquettes à une même valeur.
C'est pour ça que pour `n = 10` on dit "n est assigné à 10", et non "10 est mis dans n".
## Immuables vs modifiables
Certains types sont modifiables, d'autres, non.
notes:
2020-02-21 00:16:24 +00:00
On dit qu'elles sont immuables (*immutable* en anglais).
2020-01-13 17:27:55 +00:00
Attention, les variables sont toujours ... variables, nous n'avons pas
de constantes.
## Les types modifiables
- On peut ajouter à une liste.
- On peut vider un ensemble.
- On peut supprimer une clef d'un dictionnaire.
- ...
2020-01-13 17:27:55 +00:00
notes:
2020-01-13 17:27:55 +00:00
- Listes
- Dictionnaires
- Ensembles
- ...
2020-01-13 17:27:55 +00:00
2021-10-24 21:12:03 +00:00
## Les types immuables
2020-01-13 17:27:55 +00:00
- On ne peut pas dire que maintenant 10 vaut 12.
- Ni que faux devient vrai.
- Ni qu'une paire contient maintenant trois éléments.
- ...
2020-01-13 17:27:55 +00:00
notes:
2020-01-13 17:27:55 +00:00
- Les chaînes
- Les *n*-uplets
- Les entiers
- Les booléens
- ...
2020-01-13 17:27:55 +00:00
Pour les chaînes c'est discutable, mais avoir des chaînes immuables
est confortable (clef de dictionnaires par exemple, ou la garantie
qu'un appel à une fonction avec une chaîne en paramètre ne va pas la
modifier).
## La vérité
2021-10-24 21:12:03 +00:00
En Python, ce qui est vide est faux, `0` est faux, `None` est faux,
`False` est faux. Le reste est vrai :
2020-01-13 17:27:55 +00:00
2023-05-27 07:28:28 +00:00
```pycon
2020-01-13 17:27:55 +00:00
>>> bool("Non vide")
True
>>> bool([]) # Une liste vide
False
>>> bool(0.0)
False
```
notes:
2020-02-21 00:16:24 +00:00
2020-01-13 17:27:55 +00:00
Attention à la sémantique : `if foo` est différent de `if foo is True`.
Leur rappeler que c'est pylint qui leur dira quand utiliser `is`, leur
dire quand même : pour `True`, `False`, et `None`.
2020-01-13 17:30:35 +00:00
2021-02-01 07:51:10 +00:00
# Les fonctions
2020-01-13 17:30:35 +00:00
## Syntaxe
```python
2021-02-01 07:51:10 +00:00
def ma_fonction(ses_paramètres):
... # Le code de la fonction
2020-01-13 17:30:35 +00:00
```
notes:
2020-01-13 17:30:35 +00:00
Passer du temps sur la syntaxe et le vocabulaire
- fonction
- paramètre, argument
- `return`
2021-03-28 08:09:33 +00:00
## Exemple
2023-05-27 07:28:28 +00:00
```pycon
>>> def temps_total(temps_de_preparation, temps_de_cuisson):
... return temps_de_preparation + temps_de_cuisson
...
>>> temps_total(30, 20)
50
2021-03-28 08:09:33 +00:00
```
2020-01-13 17:30:35 +00:00
## Paramètres
Une fonction prend des paramètres et renvoie une valeur.
```python
def fahrenheit_to_celsius(fahrenheit):
return (fahrenheit - 32) * 5/9
2020-01-13 17:30:35 +00:00
```
## Arguments
On peut donc lui donner des arguments :
2023-05-27 07:28:28 +00:00
```pycon
>>> fahrenheit_to_celsius(320)
160.0
>>> fahrenheit_to_celsius(390)
198.88888888888889
>>> fahrenheit_to_celsius(450)
232.22222222222223
2020-01-13 17:30:35 +00:00
```
2021-03-28 08:09:33 +00:00
notes:
Exercices: First function, Print even numbers, ...
# Les chaînes
2023-05-27 07:28:28 +00:00
```pycon
>>> """Elle préfère "l'huile d'olive"."""
'Elle préfère "l\'huile d\'olive".'
```
notes:
2022-03-10 09:44:38 +00:00
~ fin de jour 1 début de jour 2
## Les docstrings
```python
def une_fonction():
"""Une courte description."""
...
return ...
```
# Les nombres
## Les opérateurs mathématiques
2023-05-27 07:28:28 +00:00
```pycon
>>> 0.1 + 0.1
0.2
```
## Les opérateurs mathématiques
2023-05-27 07:28:28 +00:00
```pycon
>>> 0.1 + 0.2
0.30000000000000004
```
notes:
https://0.30000000000000004.com
# `for` et `while`
## `break` et `continue`
`break` sert à interrompre une boucle, `continue` sert à passer à
l'élément suivant. Qu'on soit dans un `for` ou dans un `while`.
## `break`
2023-05-27 07:28:28 +00:00
```pycon
>>> while True:
... if not il_reste_de_la_pâte:
... break
... faire_une_crêpe()
...
```
## `continue`
2023-05-27 07:28:28 +00:00
```pycon-repl
>>> for recette in recettes:
... if "sésame" in recette["ingredients"]:
... continue
... if "noix de Pécan" in recette["ingredients"]:
... continue
... print(recette["titre"])
Broyés du Poitou
Œufs mimosa
Houmous
```
## Les exceptions : `try`
2023-05-27 07:28:28 +00:00
```pycon
>>> try:
... int("2 kg")
... except ValueError:
... print("Raté")
Raté
```
# La notation en compréhension
C'est transformer ça :
2023-05-27 07:28:28 +00:00
```pycon
>>> durées = []
>>> for recette in recettes:
... durées.append(recette["durée"])
>>> durées
[35, 20, 13]
```
## La notation en compréhension
en :
2023-05-27 07:28:28 +00:00
```pycon
>>> [recette["durée"] for recette in recettes]
[35, 20, 13]
```
## La notation en compréhension
Ou :
```python
def compte_recettes(recettes, ingrédient):
trouvées = []
for recette in recettes:
if ingrédient in recette["ingredients"]:
trouvées.append(recette)
return len(trouvées)
```
## La notation en compréhension
en :
```python
def compte_recettes(recettes, ingrédient):
return len(
[
recette
for recette in recettes
if ingrédient in recette["ingredients"]
]
)
```
notes:
Elle devrait s'écrire sur une seule ligne, mais, vidéoprojecteur...
# Les *slices*
*slices* en anglais
2023-05-27 07:28:28 +00:00
notes:
On pourrait traduire par « tranches » et filer la métaphore culinaire…
2023-05-27 07:28:28 +00:00
['incontestable', 'contestable', 'testable', 'stable']
```python
seq = 'incontestable'
```
## Les *slices*
2023-05-27 07:28:28 +00:00
```pycon
>>> seq = 'incontestable'
>>> seq[0]
'i'
```
## Les *slices*
2023-05-27 07:28:28 +00:00
```text
11
0123456789 |
incontestable—12
|
10
```
```pycon
>>> seq[5:9]
'test'
>>> seq[5:13]
'testable'
2023-05-27 07:28:28 +00:00
>>> seq[7:13]
'stable'
```
## Les *slices*
2023-05-27 07:28:28 +00:00
```pycon
>>> seq[:2]
'in'
>>> seq[2:]
'contestable'
```
## Les *slices*
2023-05-27 07:28:28 +00:00
```pycon
>>> seq[-1]
'e'
```
## Les *slices*
2023-05-27 07:28:28 +00:00
```pycon
>>> seq[-6:]
'stable'
```
## Les *slices*
2023-05-27 07:28:28 +00:00
```pycon
>>> "perso"[::2]
'pro'
```
2023-05-27 07:28:28 +00:00
notes:
```python
2023-05-27 07:28:28 +00:00
dict = ['ados', 'assit', 'engager', 'éroder', 'épater', 'ivres', 'soda', 'tissa', 'regagne', 'erodé', 'retapé', 'servi']
```
## Les *slices*
2023-05-27 07:28:28 +00:00
```pycon
>>> for word in dict:
... if word[::-1] in dict:
... print(word, word[::-1])
ados soda
assit tissa
engager regagne
épater retapé
ivres servi
soda ados
tissa assit
regagne engager
retapé épater
servi ivres
```
## Les *slices*
`seq[<start>:<stop>:<step>]`
# Les classes
## La syntaxe
```python
class LeNomDeLaClasse:
"""Sa docstring, comme pour une
fonction.
"""
# Le corps de la classe.
```
Notes:
Dédiaboliser l'héritage, l'héritage multiple, les interfaces,
les classes abstraites, les méthodes virtuelles, ...
## À retenir
On pourrait trier les données en deux types :
- celles dont on connaît les attributs → classes
- celles dont on ne connaît pas les attributs → dictionnaires
Notes:
Le contexte, le métier, les bibliothèques utilisées peuvent générer
des cas particuliers, cette règle n'est pas absolue.
préciser peut être : "dont on connaît à toutes les étapes du programme".
## Exemple
```python
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
```
Notes: On connaît les attributs.
## Exemple
2023-05-27 07:28:28 +00:00
```pycon
>>> ISIN = {
... "GLE": "FR0000130809",
... "PARRO": "FR0004038263",
... "AM": "FR0000121725",
... }
```
Notes: On ne les connaît pas.
## Syntaxe → les méthodes
```python
class Dice:
def throw(self):
self.value = randint(1, 6)
```
Notes: Une classe *ne sert pas* à stocker des fonctions, mais des
données. Pensez aux structs C.
La données d'abord, l'algorithme après.
## Syntaxe → le constructeur
```python
class DiceCup:
def __init__(self, dices):
self.dices = dices
def shake(self):
...
```
Notes: Leur faire faire implémenter le __repr__, min, max, et mean.
Leur faire faire 1000 tirages dans un Counter, avec des valeurs ENTIẼRES.
2022-03-27 22:00:46 +00:00
BiaisedDice(Dice) est un bon exemple d'héritage.
## Utilisation
2023-05-27 07:28:28 +00:00
```pycon
>>> dice = Dice()
>>> dice.throw()
>>> dice.value
4
```
## Utilisation
2023-05-27 07:28:28 +00:00
```pycon
>>> cup = DiceCup(
... [Dice() for _ in range(10)]
... )
>>> cup.shake()
```
Notes:
Faire quelques exemples d'héritage simples avant de passer a la suite.
super() considered super() !
# pip, venvs, conda
## pip
C'est l'outil standard pour installer un paquet.
```bash
$ python3 -m pip install <package-name>
```
Mais, ça installe où ?
## venv
C'est l'outil standard pour indiquer où installer les paquets.
*On peut ainsi avoir plusieurs environnements, un par projet par exemple*.
Notes:
Pratique pour avoir des versions différentes.
## venv
```bash
$ python3 -m venv --prompt test .venv/
$ source .venv/bin/activate
(test) $ python3 -m pip install pytest
```
Notes: Dépendant du shell, les envoyer sur library/venv.html.
Insister sur le côté "trashable du venv" :
- Ne rien mettre dans .venv
- rm -fr .venv # au moindre souci
## conda
```bash
$ conda create --name test
$ conda activate test
(test) $ conda install numpy
```
# Tester
## pytest
```bash
(test) $ mkdir tests/
(test) $ pip install pytest
(test) $ editor tests/test_dice.py
```
Notes: C'est l'occasion de parler de assert.
## hypothesis
```python
from hypothesis import given
from hypothesis.strategies import integers
@given(integers(min_value=2,
max_value=1000))
def test_fib(i):
assert fib(i) == fib(i-1) + fib(i-2)
```
# Les bonnes pratiques
Notes: Prérequis: pip et venv.
2022-03-10 09:44:38 +00:00
~fin jour 2 / début jour 3.
## Bonnes habitudes
> There are 2 hard problems in computer science: cache invalidation,
> naming things, and off-by-1 errors.
## Bonnes habitudes
Pas plus de 7.
## Garder son code lisible
Attention au code vieillissant, au « je ne rajoute qu'une ligne ou
deux à cette fonction et c'est réglé ».
Notes: Deux ans après la fonction fait 800 lignes, et personne ne l'a
vu venir. flake8 peut aider.
## Les « linters »
Il existe plusieurs outils pour « relire » votre code :
- flake8,
- pylint,
- mypy,
- black,
- bandit,
- isort.
Et un pour les unifier tous : `tox`.
Notes: Leur faire implémenter un `is_prime(x)` pour jouer avec.
La règle des 7.
## flake8
Dans un venv :
```bash
(test) $ pip install flake8
(test) $ pip install flake8-bugbear
(test) $ flake8 --max-complexity 9 *.py
```
Notes:
Flake8 est rapide, n'effectuant pas les `imports` il ne peut repérer
qu'une catégorie de problèmes.
9 est trop bas, 15 est probablement un bon choix.
## pylint
```bash
(test) $ pip install pylint
(test) $ pylint is_prime.py
```
## mypy
`mypy` fonctionne avec des annotations de types.
```bash
(test) $ pip install mypy
(test) $ mypy is_prime.py
```
Notes: --ignore-missing-imports
## bandit
Bandit cherche les failles de sécurité...
```bash
(test) $ pip install bandit
(test) $ bandit is_prime.py
```
## tox
Permet de lancer les tests:
- sur plusieurs interpréteurs (s'ils sont installés),
- de plusieurs outils,
- en parallèle.
Notes: c.f. gh/JulienPalard/oeis.
## pdb
```
breakpoint()
```
## PYTHONDEVMODE=y
Et `./configure --with-pydebug`.
Notes: Voir mon bashrc :] Surtout "viable" depuis la 3.8.
2021-10-24 19:56:33 +00:00
# `*`, `**`
## `*`
Signifie « plusieurs », comme dans une liste ou un *n*-uplet.
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> begin, *rest = range(5)
>>> begin
0
>>> rest
[1, 2, 3, 4]
```
Notes:
Attention, initiation : Le but est de savoir que ça existe, savoire le
lire.
Équivaut à:
begin, rest = seq[0], seq[1:]
## `*`
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> def sum(*args):
... print(args)
...
>>> sum(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
```
## `*`
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> [0, 0, 0, *range(3)]
[0, 0, 0, 0, 1, 2]
```
## `*`
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> print(*range(5))
0 1 2 3 4
```
## `**`
Signifie « plusieurs, nommés », comme dans un dictionnaire.
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> def p(**kwargs):
... for key, value in kwargs.items():
... print(key, "→", value)
2021-10-24 19:56:33 +00:00
...
>>> p(x=10, y=12)
x → 10
y → 12
```
## `**`
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> defaults = {"path": "./",
... "pattern": "*.txt"}
>>> {**defaults, "pattern": "*.md"}
{'path': './', 'pattern': '*.md'}
```
## `**`
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> def p(x, y):
... print(f"x → {x}")
... print(f"y → {y}")
...
>>> point = {"x": 10, "y": 12}
>>> p(**point)
x → 10
y → 12
```
# L'encodage
## encoder
C'est transformer une chaîne en octets, pour son transport ou stockage :
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> "L'été".encode()
b"L'\xc3\xa9t\xc3\xa9"
>>> list("L'été".encode())
[76, 39, 195, 169, 116, 195, 169]
```
## décoder
C'est le contraire ...
2023-05-27 07:28:28 +00:00
```pycon
2021-10-24 19:56:33 +00:00
>>> bytes([76, 39, 195, 169, 116, 195, 169]).decode()
"L'été"
```
Notes:
Parler d'unicode, d'UTF-8, de latin-1. Ne pas oubilier de mentionner
que latin-1 et companie sont à taille fixe, et qu'UTF-8 est à taille
variable.
# Les modules utiles
- argparse
- re
- csv (quand on a pas Pandas)
- subprocess
# La communauté
> Come for the language, stay for the community
— Brett Cannon
## Les PyCons
La PyConFr (tous les ans, sauf cette année) ! Les meetups locaux hors période de pandémie !