580 lines
19 KiB
Markdown
580 lines
19 KiB
Markdown
---
|
||
title: Decouvrir le langage
|
||
author: Steve Kossouho
|
||
---
|
||
|
||
# Bases du langage
|
||
|
||
----
|
||
|
||
## Le langage Python
|
||
|
||
Le langage Python peut être découpé en deux grands types d'instructions :
|
||
|
||
- Les déclarations
|
||
- Les expressions
|
||
|
||
Les déclarations sont en général des instructions pour créer des variables ou des structures de données.
|
||
|
||
Les expressions sont des instructions pour effectuer des calculs ou récupérer des données.
|
||
|
||
----
|
||
|
||
## Hello World
|
||
|
||
```python {.numberLines}
|
||
print("Hello world!")
|
||
```
|
||
|
||
----
|
||
|
||
## Commentaires
|
||
|
||
En Python, un commentaire est un élément textuel dans votre code qui sera ignoré à l'exécution.
|
||
Il ne pourra pas causer d'erreur de syntaxe, mais encore faut-il l'utiliser correctement :
|
||
|
||
```python {.numberLines}
|
||
# Commentaire sur sa propre ligne
|
||
print("Bonjour") # Commentaire à la fin d'une ligne de code
|
||
```
|
||
|
||
----
|
||
|
||
## Variables
|
||
|
||
Une variable est une boîte en mémoire à laquelle on donne un nom, et dans cette boîte, on place une valeur.
|
||
Cette valeur peut être un peu n'importe quoi en Python, mais notamment :
|
||
|
||
- Un nombre (entier ou flottant)
|
||
- Une chaîne de caractères (texte)
|
||
- D'autres types avancés (collection, date, heure, classes, etc.)
|
||
|
||
----
|
||
|
||
## Exemple d'assignation de variables
|
||
|
||
```python {.numberLines}
|
||
a = 15 # Python comprend qu'il s'agit d'un entier
|
||
c = 3.14159265358979323 # Python comprend qu'il s'agit d'un flottant
|
||
b = "Bonjour" # Python reconnaît du texte
|
||
d = input("Entrez du texte")
|
||
del c # Détruit la variable, qui devient invalide
|
||
```
|
||
|
||
**Note** : une chaîne de caractères peut aussi être marquée par le caractère `'` :
|
||
|
||
```python {.numberLines}
|
||
b = 'Bonjour' # Python reconnaît du texte
|
||
```
|
||
|
||
----
|
||
|
||
## Changer la valeur associée à une variable
|
||
|
||
Une variable a, comme son nom l'indique, la capacité de changer de valeur dans le temps.
|
||
|
||
En Python, on utilise exactement la même syntaxe pour déclarer une nouvelle variable ou encore
|
||
changer la valeur qui lui est associée :
|
||
|
||
```python {.numberLines}
|
||
a = 15
|
||
print(a) # Affiche 15
|
||
a = 99
|
||
print(a) # Affiche 99
|
||
a = a + 1 # ou a += 1
|
||
print(a) # Affiche 100
|
||
a = "Bonjour" # On associe une valeur d'un type différent
|
||
print(a) # Affiche le texte "Bonjour"
|
||
```
|
||
|
||
----
|
||
|
||
## Typographie des variables
|
||
|
||
Typographie conventionnelle des noms de variables :
|
||
|
||
- Tout en minuscules (ex. `texte`, `tour_eiffel`)
|
||
- Commence par une lettre (obligatoire, ex. `saisie`)
|
||
- Contient des underscores entre les mots (ex. `user_name`)
|
||
- Pas d'accent ni d'espace ni de tiret
|
||
- Peut contenir un chiffre, mais pas en premier caractère (ex. `mambo_number_5`)
|
||
|
||
----
|
||
|
||
## Expressions
|
||
|
||
Une expression correspond toujours à une valeur que l'on pourrait mettre dans une variable.
|
||
|
||
```python {.numberLines}
|
||
a = 15
|
||
chaine = "bonjour"
|
||
nombre = 15
|
||
print(a) # `a` existe et peut être utilisée comme expression
|
||
beau_temps = True # Valeur spécifique *vrai*
|
||
sale_temps = False # Valeur spécifique *faux*
|
||
non_defini = None # valeur spéciale considérée comme "pas de valeur".
|
||
```
|
||
|
||
----
|
||
|
||
## Types de données
|
||
|
||
En programmation, les types de données ont des noms, et en Python ce sont les suivants :
|
||
|
||
- `int`{.python} : (integer) nombres entiers
|
||
- `float`{.python} : (floating point numbers) nombres à virgule flottante
|
||
- `str`{.python} : (string) chaînes de caractères
|
||
- `bool`{.python} : (boolean) c'est vrai / c'est faux
|
||
|
||
```python {.numberLines}
|
||
print(type(15)) # Affiche <class int>
|
||
print(type(15.0)) # Affiche <class float>
|
||
print(type("Bonjour")) # Affiche <class str>
|
||
```
|
||
|
||
----
|
||
|
||
## Expressions et opérateurs
|
||
|
||
Il est pratique de pouvoir écrire des expressions simples, mais c'est mieux de pouvoir faire des
|
||
calculs avec. Il existe des opérateurs mathématiques, mais aussi de comparaison etc.
|
||
|
||
```python {.numberLines}
|
||
a = 15
|
||
chaine = "bonjour " + "les amis" # intuitif
|
||
produit = 15 * 60 # intuitif aussi
|
||
a_double = a * 2 # ça aussi
|
||
```
|
||
|
||
Exemples d'opérateurs : `+`{.python}, `>`{.python}, `**`{.python}, `%`{.python}, `and`{.python},
|
||
`&`{.python}, `|`{.python}, `^`{.python}, `is`{.python}, `in`{.python}...
|
||
|
||
----
|
||
|
||
### Opérateurs arithmétiques
|
||
|
||
- Arithmétiques : `+`{.python}, `-`{.python}, `*`{.python}, `/`{.python}
|
||
- Modulo : `%`{.python} (reste de la division entière)
|
||
- Division entière : `//`{.python}
|
||
- Exposant : `**`{.python} (ex. `2 ** 3 == 8`{.python})
|
||
|
||
----
|
||
|
||
### Opérateurs de comparaison
|
||
|
||
- `>`{.python}, `<`{.python}, `>=`{.python}, `<=`{.python}
|
||
- `==`{.python} (équivalent), `!=`{.python} (non équivalent)
|
||
|
||
----
|
||
|
||
### Opérateurs booléens en langage naturel
|
||
|
||
- `a and b`{.python} : Vaut `True`{.python} si `a` **et** `b` valent `True`{.python}, sinon `False`.
|
||
- `a or b`{.python} : Vaut `True`{.python} si `a` **ou** `b` vaut `True`{.python}, sinon `False`.
|
||
- `a in b`{.python} : `True`{.python} si `a` fait partie de la collection ou séquence `b`.
|
||
- `a not in b`{.python} : `True`{.python} si `a` ne fait pas partie de la collection ou séquence `b`
|
||
.
|
||
- `a is b`{.python} : `True`{.python} si `a` est la même référence que `b`. Utilisé avec les booléens
|
||
et `None`{.python} notamment.
|
||
- `a is not b`{.python} : `True`{.python} si `a` n'est pas la même référence que `b`.
|
||
- `not a`{.python} : Convertit `a` en booléen, et renvoie la valeur opposée.
|
||
|
||
----
|
||
|
||
#### Opérateurs booléens (avancé)
|
||
|
||
Si `a`{.python} et `b`{.python} ne sont pas des booléens, la règle plus générale pour l'évaluation
|
||
des expressions utilisant des opérateurs booléens est la suivante :
|
||
|
||
- `a and b`{.python} : Vaut `a` si `a` est équivalent à la valeur fausse, sinon vaut b.
|
||
- `a or b`{.python} : Vaut `a` si `a` est équivalent à la valeur vraie, sinon vaut `b`.
|
||
|
||
----
|
||
|
||
### Opérateurs booléens (avancé, exemples)
|
||
|
||
Toutes les instructions suivantes affichent `True`{.python} :
|
||
|
||
```python {.numberLines}
|
||
print(("hello" and 0) == 0)
|
||
print((0 and "hello") == 0)
|
||
print(("hello" and 2) == 2)
|
||
print(("hello" or False) == "hello")
|
||
print((False or "") == "")
|
||
print("hello" is not False)
|
||
```
|
||
|
||
Ici, on teste en premier que `"hello" and 0`{.python} vaut bien `0`{.python}, et ainsi de suite…
|
||
|
||
----
|
||
|
||
### Exemple avec quelques opérateurs
|
||
|
||
```python {.numberLines}
|
||
distance = 17543 # 17543 mètres
|
||
kilometers = distance // 1000 # division entière par lots de 1000 mètres
|
||
remaining_meters = distance % 1000 # reste après la division entière
|
||
print(kilometers, "kilomètres et", remaining_meters, "mètres")
|
||
|
||
print(2 ** 3) # affiche `8`
|
||
print(2 <= 3) # affiche `True`
|
||
```
|
||
|
||
Petit exemple de code avec conversion d'ordres de grandeur proportionnels (ex. mètres),
|
||
et usage d'autres opérateurs pour des opérations plus classiques.
|
||
|
||
----
|
||
|
||
`a += b`{.python} est équivalent à → `a = a + b`{.python}
|
||
|
||
Des opérateurs similaires sont disponibles pour les autres opérations arithmétiques :
|
||
|
||
`-=`{.python}, `*=`{.python}, `/=`{.python}, `**=`{.python}, `//=`{.python}
|
||
et `%=`{.python}
|
||
|
||
(_dans la pratique, on n'utilisera que très rarement autre chose que les opérations de base, mais le principe est là_)
|
||
|
||
----
|
||
|
||
### Priorité des opérateurs en Python
|
||
|
||
| Opérateurs | Signification |
|
||
|------------------------------------------------------------------|---------------------------------------------------|
|
||
| `()` | Parenthèses |
|
||
| `**` | Exposant |
|
||
| `+x`, `-x`, `~x` | Plus unaire, Moins unaire, NOT binaire |
|
||
| `*`, `/`, `//`, `%` | Multiplication, Division, Division entière, Modulo |
|
||
| `+`, `-` | Addition, Soustraction |
|
||
| `<<`, `>>` | Opérateurs de décalage binaire |
|
||
| `&` | AND binaire |
|
||
| `^` | XOR binaire |
|
||
| `\|` | OR binaire |
|
||
| `==`, `!=`, `>`, `>=`, `<`, `<=`, `is`, `is not`, `in`, `not in` | Comparaisons, Identité, Opérateurs d'appartenance |
|
||
| `not` | NOT logique |
|
||
| `and` | AND logique |
|
||
| `or` | OR logique |
|
||
| `:=` | Expression d'assignation |
|
||
|
||
----
|
||
|
||
# Structures de contrôle
|
||
|
||
----
|
||
|
||
## Conditions
|
||
|
||
Dans tous les langages impératifs, on peut choisir de n'exécuter un bout de code que lorsque
|
||
certaines conditions sont vérifiées. En Python comme ailleurs, on utilise le mot-clé `if`{.python}
|
||
pour faire ce choix.
|
||
|
||
Le mot-clé `if`{.python} est suivi d'une expression booléenne (`True`{.python} ou `False`{.python}
|
||
ou équivalent) qui permet de savoir si on exécute du code ou pas.
|
||
|
||
```python {.numberLines}
|
||
a = 15
|
||
if a > 10: # l'expression de comparaison renvoie un booléen True
|
||
print("A est bien supérieur à 10.")
|
||
print("Le bloc de la condition a bien été exécuté.")
|
||
print("Exécuté quoi qu'il arrive")
|
||
```
|
||
|
||
. . .
|
||
|
||
Ce qui est exécuté pour cette condition est indenté de 4 espaces (on parle de bloc). Grâce à
|
||
l'indentation, Python sait où le code en question commence et où il s'arrête.
|
||
|
||
----
|
||
|
||
## Syntaxe : blocs vides
|
||
|
||
En Python, un bloc ne peut pas être vide (erreur de syntaxe), même si vous ne souhaitez rien y faire.
|
||
Si vous souhaitez écrire un bloc syntax(ct)iquement valide sans rien y faire, Python propose un mot-clé
|
||
spécifique à cet effet : `pass`{.python}. (Un commentaire ne suffit pas à former un bloc
|
||
valide car il est ignoré dans la grammaire Python)
|
||
|
||
```python {.numberLines}
|
||
if True:
|
||
pass # utiliser une ellipse (...) fonctionne aussi mais peu utilisé
|
||
```
|
||
|
||
----
|
||
|
||
## Conditions : `if…else`
|
||
|
||
Variante `if`…`else` :
|
||
|
||
On peut exécuter du code si une condition est vraie, mais on peut aussi exécuter du code si cette
|
||
condition ne s'est pas produite ! Le mot-clé `else`{.python} est au même niveau d'indentation que
|
||
le `if`{.python}, et apparaît **une seule fois au maximum** pour le `if`{.python} auquel il est associé.
|
||
|
||
```python {.numberLines}
|
||
a = 50
|
||
if a > 75:
|
||
print("A est supérieur à 75")
|
||
else:
|
||
print("A est inférieur ou égal à 75")
|
||
```
|
||
|
||
----
|
||
|
||
## Conditions : `if…elif…else`
|
||
|
||
On peut exécuter du code si une condition est vraie (`if`). Si elle est fausse, on peut exécuter du
|
||
code si une autre condition est vraie (`elif`), et ainsi de suite. La première condition vraie voit son bloc
|
||
exécuté, et l'interpréteur quitte ensuite la structure `if`{.python}.
|
||
Si un bloc `else`{.python} existe, il est toujours en dernier, et sera exécuté si toutes les conditions
|
||
le précédant ont été fausses.
|
||
|
||
```python {.numberLines}
|
||
vote = 3 # Valeurs entre 1, 2 et 3
|
||
|
||
if vote == 1:
|
||
print("Vous avez voté pour Andre")
|
||
elif vote == 2: # Le vote n'est pas 1, mais 2
|
||
print("Vous avez voté pour Beverly")
|
||
elif vote == 3: # Le vote n'est ni 1 ni 2, mais 3
|
||
print("Vous avez voté pour Carlos")
|
||
else: # Aucun des cas de figure du dessus
|
||
print("Vote incorrect")
|
||
```
|
||
|
||
----
|
||
|
||
## Faire des boucles : `for … in liste`
|
||
|
||
En programmation, une boucle consiste à répéter un bloc de code. En Python, le bloc est répété à
|
||
chaque fois qu'on parcourt un élément dans une liste. Par exemple, si on veut afficher les 10
|
||
premiers nombres, de 0 à 9, on utilise le mot-clé `for`{.python} avec la fonction `range`{.python} :
|
||
|
||
```python {.numberLines}
|
||
nombres = range(10) # une liste de 10 entiers de 0 à 9 inclus
|
||
for i in nombres: # Le bloc sera exécuté 10 fois
|
||
# La variable nommée i que nous avons déclarée sera modifiée par Python à chaque itération
|
||
print(i) # `i` contient tour à tour les nombres de 0 à 9
|
||
```
|
||
|
||
**À noter** : la variable `i` reste disponible après l'exécution de la boucle et contient la dernière
|
||
valeur assignée lors de la boucle.
|
||
|
||
----
|
||
|
||
### La fonction `range()`{.python}
|
||
|
||
La fonction `range()`{.python} fournie par Python permet de générer des suites arithmétiques de nombres
|
||
entiers. Elle fonctionne avec un, deux ou trois arguments selon l'objectif.
|
||
|
||
```python {.numberLines}
|
||
zero_to_nine = range(10) # stop (non inclus)
|
||
one_to_eight = range(1, 9) # start, stop
|
||
every_other_one = range(0, 10, 2) # start, stop, step
|
||
no_number_generated = range(10, 0, 2) # start, stop, step
|
||
```
|
||
|
||
----
|
||
|
||
## Faire des boucles : `while condition`
|
||
|
||
Python propose un autre type de boucle `while`{.python} dont le bloc est exécuté tant qu'une
|
||
condition est vraie (une expression convertie en booléen). Dès qu'elle devient fausse au début d'une
|
||
itération, Python quitte la boucle et passe à la suite.
|
||
|
||
```python {.numberLines}
|
||
nombre = 12
|
||
while nombre > 10:
|
||
print(nombre)
|
||
nombre = nombre - 1
|
||
```
|
||
|
||
**Attention** : Une boucle peut ne jamais se lancer, ou tourner indéfiniment !
|
||
Dans un terminal normal, (au clavier) `⌨️ Ctrl + C` interrompt le script. Dans un lancement de script avec PyCharm,
|
||
seul le bouton `⏹ Stop` peut l'interrompre.
|
||
|
||
----
|
||
|
||
## Exemple d'algorithme : Suite de Fibonacci
|
||
|
||
**Suite de Fibonacci** : Une suite commençant par les nombres 0 et 1. On peut générer itérativement les
|
||
éléments successifs de la suite simplement; chaque nouveau nombre de la suite est la somme des deux qui le précèdent.
|
||
|
||
Cela donne dans l'ordre :
|
||
|
||
`0 1 1 2 3 5 8 13 21 34 55 89 144 …`
|
||
|
||
Pour le résoudre, au choix, on utilise :
|
||
|
||
- Deux variables (avec ou sans _unpacking_), ou trois avec une variable temporaire.
|
||
- Une boucle `while`{.python} (pour définir quand on s'arrête d'afficher un nouvel élément)
|
||
|
||
----
|
||
|
||
### Fibonacci : unpacking
|
||
|
||
En Python, le "dépaquetage" (**unpacking**) est une forme d'assignation de variables où, lorsque
|
||
l'expression à droite du signe `=` est une séquence à `n` éléments (avec `n > 1`),
|
||
vous pouvez assigner la séquence à `n` variables :
|
||
|
||
```python {.numberLines}
|
||
a, b, c = (1, 2, 3) # a = 1, b = 2 et c = 3
|
||
a, b = (1, 2, 3) # erreur, trop d'éléments à dépaqueter
|
||
a = (1, 2, 3) # aucun problème, a est une séquence de 3 éléments
|
||
```
|
||
|
||
. . .
|
||
|
||
**Rappel** : si vous assignez la séquence à `1` variable, ça fonctionnera à nouveau, et votre
|
||
variable sera une séquence de `n` éléments.
|
||
|
||
----
|
||
|
||
## Interrompre des boucles
|
||
|
||
On peut interrompre une boucle `for`{.python} ou `while`{.python} avec deux mots-clés :
|
||
|
||
- `break`{.python},
|
||
- `continue`{.python}.
|
||
|
||
----
|
||
|
||
### Interruption : `break`{.python}
|
||
|
||
Lorsque l'on se trouve dans le bloc d'une boucle (seule la boucle directement englobante est concernée),
|
||
l'exécution d'une instruction `break`{.python} interrompt immédiatement la boucle en cours, qu'il s'agisse
|
||
d'un `for`{.python} ou d'un `while`{.python}.
|
||
|
||
L'utilisation classique du mot-clé `break` s'applique aux traitements où vous exécutez une boucle (potentiellement
|
||
avec un nombre d'itérations que vous ne contrôlez pas) à la recherche d'une information. Dans ce cas précis, si
|
||
vous trouvez l'information qui vous intéresse avant la fin naturelle de la boucle, il n'est alors plus nécessaire
|
||
de la laisser se poursuivre; typiquement, si vous trouvez votre information à la ligne 10 d'un fichier de 900 000
|
||
lignes, _pourquoi parcourir les 899 990 lignes restantes_ ?
|
||
|
||
----
|
||
|
||
### `break`{.python} : Exemple
|
||
|
||
Que fait cet exemple-ci ?
|
||
|
||
```python {.numberLines}
|
||
for number in range(10 ** 9):
|
||
if number == 23:
|
||
print("Valeur trouvée")
|
||
break
|
||
else:
|
||
print("Itération...")
|
||
```
|
||
|
||
----
|
||
|
||
### Interruption : `continue`{.python}
|
||
|
||
Lorsque l'on se trouve dans le bloc d'une boucle, l'exécution d'une instruction `continue`{.python} revient
|
||
immédiatement à la première ligne de l'itération suivante, ou autrement dit, ignore le reste du code de l'itération en cours.
|
||
|
||
L'utilisation d'un mot-clé `continue`{.python} peut **toujours** être remplacée par un `if`{.python}, plus lisible.
|
||
Cependant, ce mot-clé peut servir à réduire le niveau d'indentation d'un bloc complexe :
|
||
|
||
----
|
||
|
||
#### `continue`{.python} : Exemple
|
||
|
||
```python {.numberLines}
|
||
for x, y in zip(a, b):
|
||
if x > y:
|
||
z = process_z(x, y)
|
||
if y - z < x:
|
||
y = min(y, z)
|
||
other_actions()
|
||
```
|
||
|
||
. . .
|
||
|
||
Deviendrait comme suit.
|
||
|
||
```python
|
||
for x, y in zip(a, b):
|
||
if x <= y:
|
||
continue
|
||
z = process_z(x, y)
|
||
if y - z >= x:
|
||
continue
|
||
y = min(y, z)
|
||
other_actions()
|
||
```
|
||
|
||
Très peu de développeurs s'en servent car le gain est minime à part pour ces raisons d'indentation.
|
||
Les cas d'indentation extrême doivent pouvoir être simplifiés d'une autre manière.
|
||
|
||
----
|
||
|
||
## Bonus : Opérateur morse (walrus)
|
||
|
||
Sans rentrer dans le détail, on peut, depuis Python 3.8 (fin 2019), simplifier des boucles `while`{.python} avec un opérateur `:=`{.python}.
|
||
C'est un opérateur qui permet d'assigner une valeur à une variable, mais contrairement au mot-clé `=`{.python}, l'opérateur
|
||
forme une expression dont la valeur est l'opérande de droite. On peut ainsi écrire :
|
||
|
||
```python {.numberLines}
|
||
while (saisie := input("Saisissez oui :")) != "oui":
|
||
print("Saisie incorrecte")
|
||
```
|
||
|
||
. . .
|
||
|
||
au lieu d'écrire :
|
||
|
||
```python {.numberLines}
|
||
saisie = input("Saisissez oui :") # afficher l'invite et récupérer la saisie
|
||
while saisie != "oui":
|
||
print("Saisie incorrecte !")
|
||
saisie = input("Saisissez oui :")
|
||
```
|
||
|
||
----
|
||
|
||
## Opérateur morse : considérations
|
||
|
||
Attention toutefois, l'opérateur possède la priorité la plus basse de tous les opérateurs Python, et dans
|
||
certains cas, l'expression l'utilisant **doit** employer des parenthèses pour ne pas provoquer d'erreur de
|
||
syntaxe. **Dans le doute, utilisez toujours des parenthèses.**
|
||
|
||
```python {.numberLines}
|
||
a := 1 # Erreur de syntaxe
|
||
```
|
||
|
||
. . .
|
||
|
||
```python {.numberLines}
|
||
(a := 1) # Ça fonctionne, mais ça n'a aucun intérêt
|
||
```
|
||
|
||
. . .
|
||
|
||
```python {.numberLines}
|
||
print(a := 1 < 9) # Affiche True, et a == True
|
||
```
|
||
. . .
|
||
|
||
```python {.numberLines}
|
||
print((a := 1) < 9) # Affiche True, et a == 1, ce qu'on voulait
|
||
```
|
||
|
||
----
|
||
|
||
### Petit plus : expression ternaire
|
||
|
||
En Python, il est possible de décrire une expression qui vaut une valeur `a` si une condition est
|
||
vraie, et `b` sinon. Sans cet opérateur, on écrit :
|
||
|
||
```python {.numberLines}
|
||
if condition:
|
||
variable = a
|
||
else:
|
||
variable = b
|
||
```
|
||
|
||
. . .
|
||
|
||
Avec cet opérateur, on écrira plutôt :
|
||
|
||
```python {.numberLines}
|
||
variable = a if condition else b
|
||
```
|