formations/python-initiation/initiation.md
2023-05-27 09:28:28 +02:00

1670 lines
23 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Python
notes:
Juste pour le doctest :
```python
import random
random.seed(42)
ingredients = ["sel", "farine", "sucre", "levure", "beurre", "œuf"]
def randint(a, b):
return 4 # https://xkcd.com/221/
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},
]
```
## Python
par
Julien Palard <julien@palard.fr>
https://mdk.fr
notes:
Introduce yourself!
Ça couvre les types de bases survol quelques strucutres de contrôle,
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)
::: notes
https://insights.stackoverflow.com/trends
## Installation
https://python.org
 ou 
![](static/Anaconda_Logo.png)
::: notes
- 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
```
::: notes
- 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
>>>
```
notes:
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
```pycon
>>> 10
10
```
notes:
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
```pycon
>>> 60 * 60 * 4
14400
```
## Les exceptions
```pycon
>>> 5 / 0
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ZeroDivisionError: division by zero
```
notes:
Lisez *TOUJOURS* la dernière ligne en premier !
# Types natifs
## Booléens
```pycon
>>> True
True
>>> False
False
```
## Nombres
```pycon
>>> 42
42
```
## Nombres
```pycon
>>> 18446744073709551616
18446744073709551616
```
## Nombres
```pycon
>>> 3.1415
3.1415
```
## Chaînes de caractères
```pycon
>>> "Beurre ou huile d'olive ?"
"Beurre ou huile d'olive ?"
```
notes:
Expliquer ce qu'est une chaîne, sans parler de pointeurs, on est pas
dans un cours de C89.
## Chaînes de caractères
```pycon
>>> 'Cuisson "au beurre" !!'
'Cuisson "au beurre" !!'
```
notes:
Les triples quotes apparaissent jour 2.
## Listes
```pycon
>>> ["1 kg de farine", "12 œufs", "130 g de beurre"]
['1 kg de farine', '12 œufs', '130 g de beurre']
```
notes:
La représentation est souvent du Python valide.
## Listes
```pycon
>>> ["farine", 1000]
['farine', 1000]
```
notes:
Attention à ne pas abuser du mélange autorisé des types.
## *n*-uplets, *tuple*
```pycon
>>> ("œufs", 12)
('œufs', 12)
>>> ("sucre", 130)
('sucre', 130)
```
notes:
C'est la virgule qui fait le n-uplet, pas les parenthèses.
Pensez au *n*-uplet comme une structure C, *a record*, pas comme une
liste, par exemple des coordonnées : (x, y).
## Listes et tuples
```pycon
>>> [("farine", 1000), ("œufs", 12), ("sucre", 130)]
[('farine', 1000), ('œufs', 12), ('sucre', 130)]
```
notes:
Une liste c'est de la donnée, ce qu'elle contint c'est de la donnée.
## Ensembles
```python
{"farine", "sucre", "œuf", "levure", "sel", "beurre"}
```
notes:
Un ensemble n'est pas ordonné.
## Dictionnaires
```python
{
"un verre": "25 cl",
"un petit verre": "12 cl",
"qs": "quantité suffisante"
}
```
notes:
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
## Les opérateurs mathématiques
```pycon
>>> 10 + 10
20
>>> 10.5 + 2
12.5
```
## Les opérateurs mathématiques
```pycon
>>> (4 * 10**1) + (2 * 10**0)
42
```
## Les opérateurs mathématiques
```pycon
>>> 10 / 2
5.0
```
## Les opérateurs
```pycon
>>> "Bri" + "oche"
'Brioche'
```
notes:
It's called concatenation of strings.
## Les opérateurs
```pycon
>>> "mur" * 2
'murmur'
```
notes:
Tant qu'il n'y a pas d'ambiguité, c'est implémenté.
## Les opérateurs
```pycon
>>> ["farine", "œufs"] + ["sucre", "sel"]
['farine', 'œufs', 'sucre', 'sel']
```
## Les Comparisons
```pycon
>>> 10 < 1
False
>>> 10 == 10
True
>>> 10 >= 20
False
```
notes:
Déconseiller l'utilisation de `is`, de toute facons PyLint leur dira
quand l'utiliser.
## Logique
```pycon
>>> True or False
True
>>> True and False
False
>>> not True
False
```
notes:
On utilisera ça plus tard, avec les structures de contrôle.
## Test d'appartenance
```pycon
>>> "chocolat" in "pain au chocolat"
True
```
## Test d'appartenance
```pycon
>>> "sel" in {"farine", "œuf", "sucre", "sel", "levure"}
True
```
## Travailler avec les ensembles
```pycon
>>> {"farine", "sel"} | {"œuf", "sel"} == {"sel", "farine", "œuf"}
True
```
notes:
C'est une union.
## Travailler avec les ensembles
```pycon
>>> {"farine", "levure", "sel"} & {"œuf", "sel", "sucre"}
{'sel'}
```
notes:
Une intersection.
## Mais en cas d'ambiguité…
```pycon
>>> "farine" * "sucre"
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é…
```pycon
>>> {"farine", "levure"} + {"sel", "œuf"}
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'set' and 'set'
```
# Les variables
## Affectation
```pycon
>>> preparation = 20
>>> cuisson = 30
>>> preparation + cuisson
50
```
notes:
JAMAIS dire : On met 20 dans « preparation ».
## Affectation multiple
```pycon
>>> preparation, cuisson = 20, 30
>>> preparation
20
>>> cuisson
30
```
## Accès par indice
```pycon
>>> etapes = ["preparation", "cuisson", "dégustation"]
>>> etapes[0]
'preparation'
>>> etapes[1]
'cuisson'
>>> etapes[2]
'dégustation'
```
notes:
On réutilise le nom pour accéder au contenu.
Bien prendre le temps d'expliquer la syntaxe ici.
## Accès par clé
```pycon
>>> definitions = {
... "un verre": "25 cl",
... "un petit verre": "12 cl",
... "qs": "quantité suffisante"
... }
...
>>> definitions["un petit verre"]
'12 cl'
```
# Les fonctions
## print
```pycon
>>> print("Brioche")
Brioche
```
notes:
C'est leur première fonction, s'attarder sur la syntaxe !
## print
```pycon
>>> print("La moitié de 130 g :", 130 // 2, "g")
La moitié de 130 g : 65 g
```
notes:
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.
Exercices:
- Print 42
- Number of seconds in a year
- Using operators
## str, list, int, ...
```pycon
>>> str(130)
'130'
```
## str, list, int, ...
```pycon
>>> int("130")
130
```
## len
```pycon
>>> len(["farine", "œufs", "sucre"])
3
>>> len("farine")
6
```
notes:
Exercise: Character counting
## range
```pycon
>>> 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)`
- ...
notes:
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.
## sorted
```pycon
>>> sorted({"sel", "farine", "sucre"})
['farine', 'sel', 'sucre']
```
## Les importer des modules
```pycon
>>> from random import choice
>>> print(choice(["Pain au chocolat", "Chocolatine"]))
Pain au chocolat
```
notes:
Exercice : Import.
# Les instructions
## if
```pycon
>>> if "sucre" in ingredients and "œuf" in ingredients:
... print("Commencer par blanchir les œufs.")
Commencer par blanchir les œufs.
```
notes:
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 ».
## Le `else`
Après un bloc `if`, on peut ajouter un bloc `else` :
```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.
```
## Le `elif`
Après un `if`, on peut ajouter un ou des bloc `elif` :
```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.
```
notes:
Parler de `pass` et de `...`.
## for
```pycon
>>> for ingredient in ingredients:
... print(ingredient)
...
sel
farine
sucre
levure
beurre
œuf
```
```pycon
>>> ingredient = ingredients[0]
>>> print(ingredient)
sel
>>> ingredient = ingredients[1]
>>> print(ingredient)
farine
>>> ingredient = ingredients[2]
>>> print(ingredient)
sucre
```
## for
```pycon
>>> for lettre in "Œuf":
... print(lettre)
...
Œ
u
f
>>>
```
## for
```pycon
>>> for i in range(5):
... print(i)
0
1
2
3
4
```
notes:
Exercice : Square numbers, powers of two, comparisons.
## 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`
```pycon
>>> while il_reste_de_la_pâte:
... faire_une_crêpe()
...
```
# Les méthodes
## Sur les chaînes
```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
```pycon
>>> s = "Durée : {} minutes."
>>> s.format(3600 // 60)
'Durée : 60 minutes.'
```
## Sur les listes
```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
```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')])
```
# Les variables (suite)
## Le type des variables
En Python, les variables ne sont que des noms.
Des « étiquettes » qu'on colle aux objets.
> Comme sur les pots de confiture.
## 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.
Sans. Exceptions.
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:
On dit qu'elles sont immuables (*immutable* en anglais).
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.
- ...
notes:
- Listes
- Dictionnaires
- Ensembles
- ...
## Les types immuables
- On ne peut pas dire que maintenant 10 vaut 12.
- Ni que faux devient vrai.
- Ni qu'une paire contient maintenant trois éléments.
- ...
notes:
- Les chaînes
- Les *n*-uplets
- Les entiers
- Les booléens
- ...
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é
En Python, ce qui est vide est faux, `0` est faux, `None` est faux,
`False` est faux. Le reste est vrai :
```pycon
>>> bool("Non vide")
True
>>> bool([]) # Une liste vide
False
>>> bool(0.0)
False
```
notes:
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`.
# Les fonctions
## Syntaxe
```python
def ma_fonction(ses_paramètres):
... # Le code de la fonction
```
notes:
Passer du temps sur la syntaxe et le vocabulaire
- fonction
- paramètre, argument
- `return`
## Exemple
```pycon
>>> def temps_total(temps_de_preparation, temps_de_cuisson):
... return temps_de_preparation + temps_de_cuisson
...
>>> temps_total(30, 20)
50
```
## Paramètres
Une fonction prend des paramètres et renvoie une valeur.
```python
def fahrenheit_to_celsius(fahrenheit):
return (fahrenheit - 32) * 5/9
```
## Arguments
On peut donc lui donner des arguments :
```pycon
>>> fahrenheit_to_celsius(320)
160.0
>>> fahrenheit_to_celsius(390)
198.88888888888889
>>> fahrenheit_to_celsius(450)
232.22222222222223
```
notes:
Exercices: First function, Print even numbers, ...
# Les chaînes
```pycon
>>> """Elle préfère "l'huile d'olive"."""
'Elle préfère "l\'huile d\'olive".'
```
notes:
~ 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
```pycon
>>> 0.1 + 0.1
0.2
```
## Les opérateurs mathématiques
```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`
```pycon
>>> while True:
... if not il_reste_de_la_pâte:
... break
... faire_une_crêpe()
...
```
## `continue`
```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`
```pycon
>>> try:
... int("2 kg")
... except ValueError:
... print("Raté")
Raté
```
# La notation en compréhension
C'est transformer ça :
```pycon
>>> durées = []
>>> for recette in recettes:
... durées.append(recette["durée"])
>>> durées
[35, 20, 13]
```
## La notation en compréhension
en :
```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
notes:
On pourrait traduire par « tranches » et filer la métaphore culinaire…
['incontestable', 'contestable', 'testable', 'stable']
```python
seq = 'incontestable'
```
## Les *slices*
```pycon
>>> seq = 'incontestable'
>>> seq[0]
'i'
```
## Les *slices*
```text
11
0123456789 |
incontestable—12
|
10
```
```pycon
>>> seq[5:9]
'test'
>>> seq[5:13]
'testable'
>>> seq[7:13]
'stable'
```
## Les *slices*
```pycon
>>> seq[:2]
'in'
>>> seq[2:]
'contestable'
```
## Les *slices*
```pycon
>>> seq[-1]
'e'
```
## Les *slices*
```pycon
>>> seq[-6:]
'stable'
```
## Les *slices*
```pycon
>>> "perso"[::2]
'pro'
```
notes:
```python
dict = ['ados', 'assit', 'engager', 'éroder', 'épater', 'ivres', 'soda', 'tissa', 'regagne', 'erodé', 'retapé', 'servi']
```
## Les *slices*
```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
```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.
BiaisedDice(Dice) est un bon exemple d'héritage.
## Utilisation
```pycon
>>> dice = Dice()
>>> dice.throw()
>>> dice.value
4
```
## Utilisation
```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.
~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.
# `*`, `**`
## `*`
Signifie « plusieurs », comme dans une liste ou un *n*-uplet.
```pycon
>>> 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:]
## `*`
```pycon
>>> def sum(*args):
... print(args)
...
>>> sum(1, 2, 3, 4, 5)
(1, 2, 3, 4, 5)
```
## `*`
```pycon
>>> [0, 0, 0, *range(3)]
[0, 0, 0, 0, 1, 2]
```
## `*`
```pycon
>>> print(*range(5))
0 1 2 3 4
```
## `**`
Signifie « plusieurs, nommés », comme dans un dictionnaire.
```pycon
>>> def p(**kwargs):
... for key, value in kwargs.items():
... print(key, "→", value)
...
>>> p(x=10, y=12)
x → 10
y → 12
```
## `**`
```pycon
>>> defaults = {"path": "./",
... "pattern": "*.txt"}
>>> {**defaults, "pattern": "*.md"}
{'path': './', 'pattern': '*.md'}
```
## `**`
```pycon
>>> 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 :
```pycon
>>> "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 ...
```pycon
>>> 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 !