---
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]{.naming}
- Les [expressions]{.naming}

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 complètement 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 référence à une donnée à laquelle on donne un nom. Une variable est toujours associée à 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")  # Une fonction retourne une valeur
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 ceux de base 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`{.python}.
- `a or b`{.python} : Vaut `True`{.python} si `a` **ou** `b` vaut `True`{.python}, sinon `False`{.python}.
- `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`

# Pour les pros de l'algèbre binaire
print(0b1010 & 0b0011)  # affiche 2 (0b0010)
print(0b1010 | 0b0011)  # affiche 11 (0b1011)
```

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.

----

### Opérateurs d'assignation supplémentaires

`a += b`{.python} est équivalent à → `a = a + b`{.python}

Des opérateurs similaires sont disponibles pour les autres opérations arithmétiques :

| Opérateur | Description                             | Exemple          | Équivalent à          |
|-----------|-----------------------------------------|------------------|------------------------|
| `=`       | Assignation simple                      | `x = 5`          | -                      |
| `+=`      | Addition puis assignation               | `x += 3`         | `x = x + 3`            |
| `-=`      | Soustraction puis assignation           | `x -= 2`         | `x = x - 2`            |
| `*=`      | Multiplication puis assignation         | `x *= 4`         | `x = x * 4`            |
| `/=`      | Division puis assignation               | `x /= 2`         | `x = x / 2`            |
| `//=`     | Division entière puis assignation       | `x //= 2`        | `x = x // 2`           |
| `%=`      | Modulo puis assignation                 | `x %= 3`         | `x = x % 3`            |
| `**=`     | Exponentiation puis assignation         | `x **= 2`        | `x = x ** 2`           |
1 sur 2

----

| Opérateur | Description                             | Exemple          | Équivalent à          |
|-----------|-----------------------------------------|------------------|------------------------|
| `&=`      | ET binaire puis assignation             | `x &= 1`         | `x = x & 1`            |
| `|=`      | OU binaire puis assignation             | `x |= 2`         | `x = x | 2`            |
| `^=`      | OU exclusif (XOR) binaire puis assignation | `x ^= 3`       | `x = x ^ 3`            |
| `<<=`     | Décalage binaire à gauche puis assignation | `x <<= 1`     | `x = x << 1`           |
| `>>=`     | Décalage binaire à droite puis assignation | `x >>= 1`     | `x = x >> 1`           |
2 sur 2

(_dans la pratique, on n'utilisera que très rarement autre chose que les opérations de base)

----

### Priorité des opérateurs en Python

| Opérateurs                                                       | Signification                          |
|------------------------------------------------------------------|----------------------------------------|
| `()`                                                             | Parenthèses                            |
| `**`                                                             | Exposant                               |
| `+x`, `-x`, `~x`                                                 | Plus unaire, Moins unaire, NOT binaire |
| `*`, `/`, `//`, `%`                                              | Multiplication, Divisions, Modulo      |
| `+`, `-`                                                         | Addition, Soustraction                 |
| `<<`, `>>`                                                       | Opérateurs de décalage binaire         |
| `&`                                                              | AND binaire                            |
| `^`                                                              | XOR binaire                            |
| <code>&#124;</code>                                              | OR binaire                             |
1 sur 2

----

| Opérateurs                                                       | Signification                          |
|------------------------------------------------------------------|----------------------------------------|
| `==`, `!=`, `>`, `>=`, `<`, `<=`, `is`, `is not`, `in`, `not in` | Comparaisons, appartenance             |
| `not`                                                            | NOT logique                            |
| `and`                                                            | AND logique                            |
| `or`                                                             | OR logique                             |
| `:=`                                                             | Expression d'assignation               |
2 sur 2

----

# Structures de contrôle

Les structures de contrôle permettent de contrôler l'exécution du code, pour en augmenter l'interactivité.
Nous parlerons dans cette partie de plusieurs sujets :

- Conditions
- Boucles : `for`
- Boucles : `while`
- Interrompre des boucles

----

## 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 déterminer si l'on va exécuter 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]{.naming}). Grâce à
l'indentation, Python sait où le code concerné 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 récupère une valeur 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},
qui elle, génère des suites arithmétiques d'entiers :

```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]{.naming} de nombres
entiers. Une suite arithmétique possède une valeur de [départ]{.naming}, de [fin]{.naming}, et un [pas]{.naming} à ajouter à chaque étape.

La fonction range fonctionne avec un, deux, ou trois arguments. La valeur de fin n'est **jamais** générée :

```python {.numberLines}
# Un argument : fin. départ = 0, pas = 1
zero_to_nine = range(10)  # 0, 1, 2, ..., 8, 9
# Deux arguments : début, fin. pas = 1
one_to_eight = range(1, 9)  # 1, 2, ..., 7, 8
impossible_1 = range(9, 1)  # ∅ ensemble vide
# Trois arguments : début, fin, pas.
every_other_one = range(0, 10, 2)  # 0, 2, 4, 6, 8
impossible_2 = range(10, 0, 2)  # ∅ ensemble vide
every_other_reverse = range(10, 0, -2)  # 10, 8, 6, 4, 2
```

----

## 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 évaluée comme 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 :

| n      | 0  | 1  | 2  | 3  | 4  | 5  | 6  | 7   | 8   | 9   | 10  | 11  | 12   |
|--------|----|----|----|----|----|----|----|-----|-----|-----|-----|-----|------|
| F(n)   | 0  | 1  | 1  | 2  | 3  | 5  | 8  | 13  | 21  | 34  | 55  | 89  | 144  |


Pour le faire, 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]{.naming}) est une forme d'assignation de variables où, lorsque
l'expression à droite du signe `=` est un objet de type séquence à `n` éléments (avec `n > 1`), 
vous pouvez assigner la séquence à exactement `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 un objet de type 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.

----

## Extra : Opérateur morse (walrus)

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
```

----

### Extra : 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 ce type d'expression, on écrit :

```python {.numberLines}
if condition:
    variable = a
else:
    variable = b    
```

. . .

Avec ce type d'expression, on pourra plutôt écrire :

```python {.numberLines}
variable = a if condition else b
```

----

### Extra : Convertir des données d'un type à un autre

Nous avons vu, ici et là, quelques fonctions pour déclarer des valeurs de base, ou convertir des
valeurs. En voici une liste plus complète :

- `bool(val)`{.python}
- `int(val)`{.python}, `float(val)`{.python}
- `str(val)`{.python}
- `list(val)`{.python}, `tuple(val)`{.python}
- `set(val)`{.python}, `dict(val)`{.python}

Toutes ces fonctions renvoient un nouveau booléen, entier, flottant etc. correspondant à une
conversion de l'expression passée en argument. Cela fonctionne uniquement lorsque la conversion a du sens.

----

Appelées sans argument, ces fonctions vous renvoient `False`{.python}, `0`{.python}, une chaîne ou une
collection vide (des valeurs considérées neutres, qui renvoient toujours `False`{.python} lorsqu'on les convertit en booléen). 

Lorsque vous passez un argument à ces fonctions, elles vous renvoient une nouvelle valeur, 
qui est une conversion de l'argument passé vers le type
représenté par la fonction. Ce n'est pas toujours possible d'effectuer une conversion; par exemple, il est impossible de
convertir une liste vers un nombre flottant, ou encore de convertir la chaîne `"bonjour"`{.python} vers un nombre entier.

```python {.numberLines}
converted1 = int(3.14159)  # tronque le flottant / retire la partie décimale
converted3 = float("3.14159")  # comprend le texte et génère un flottant
converted2 = list(1)  # erreur
converted4 = float("salut")  # aucun caractère valide pour représenter un nombre, échoue
```
