Langages et programmation
Introduction
Qu'est-ce qu'un programme ?
Un programme informatique est un ensemble d'opĂ©rations destinĂ©es Ă ĂȘtre exĂ©cutĂ©es par un ordinateur. Ă la diffĂ©rence d'un algorithme, il est en gĂ©nĂ©ral Ă©crit dans un langage de programmation.
Qu'est-ce qu'un langage de programmation ?
C'est un langage "facilement" comprĂ©hensible par un ĂȘtre humain et qui peut ĂȘtre "traduit" dans le langage machine qui est difficilement manipulable par un humain. Comme n'importe quel langage, un langage de programmation possĂšde des symboles, une grammaire, une orthographe, on parle de syntaxe.
Il existe des centaines de langage de programmation : par exemple Javascript, les langages C et C++, Java, Lisp, OCaml, PHP, Smalltalk, Ruby, etc.
Les langages peuvent sembler trÚs différents mais ils partagent tous des structures communes. Le langage que nous utiliserons principalement dans ce cours sera Python, cependant l'objectif de ce cours n'est pas d'apprendre le langage Python en particulier, mais d'insister sur les bases qu'ils partagent avec les autres langages.
On n'apprend pas "un langage de programmation", on apprend Ă programmer.
Remarque
Dans la suite du cours, nous utiliserons
systÚmatiquement >>> pour représenter une console interprétant Python, le résultat étant affiché à la ligne en dessous, comme dans l'exemple ci-contre:
>>> 3 + 7
10
ĂlĂ©ments de base d'un programme
Notion d'expression
Une expression est un texte qui peut ĂȘtre Ă©valuĂ© par l'interprĂ©teur Python, câest Ă dire que que chaque expression possĂšde une valeur que lâon peut obtenir par un calcul.
-
7est une expression simple, le rĂ©sultat de son Ă©valuation est7âïž RĂ©sultat>>> 7 7 -
3 + 4est une expression composĂ©e, le rĂ©sultat de son Ă©valuation est7.âïž RĂ©sultat>>> 3 + 4 7 -
on appelle la fonction
maxavec les arguments3et4âïž RĂ©sultat>>> max(3, 4) 4 -
on peut créer des expressions arbitrairement complexes
âïž RĂ©sultat>>> 2 + max(3 + 4, 4) 9
Commentaire
Les commentaires sont des portions du code source ignorĂ©es par la machine car destinĂ©es en gĂ©nĂ©ral Ă un lecteur humain pour permettre dâexpliquer le code. En Python, le reste dâune ligne suivant un # est un commentaire.
>>> # Cette expression ne fait strictement rien
Notion de type
Un aspect essentiel des langages de programmation est la notion de type. Tout objet manipulĂ© par Python en possĂšde un, qui caractĂ©rise la maniĂšre dont il est reprĂ©sentĂ© dans la mĂ©moire de lâordinateur, et dont vont dĂ©pendre les opĂ©rations et fonctions quâon peut lui appliquer.
La fonction type permet de connaĂźtre le type dâun objet. Par exemple, le type int est utilisĂ© pour reprĂ©senter les nombres entiers (nĂ©gatifs et positifs), le type str pour les chaĂźnes de caractĂšres :
>>> type (2)
<class âint â>
>>> type(" Bonjour ")
<class âstr â>
Les types sont importants pour dĂ©finir les opĂ©rations que lâon peut appliquer aux objets, par exemple :
>>> 7 + " Bonjour "
Traceback (most recent call last):
File "<stdin >", line 1, in <module >
TypeError : unsupported operand type(s) for +: âint â and âstr â
LâinterprĂ©teur nous signale quâil nâest pas possible dâadditionner un objet de type int et une chaĂźne de caractĂšre de type str.
Python possÚde également un type float, pour les nombres décimaux. Le nom float vient de la dénomination nombre à virgule flottante sur laquelle nous reviendront plus tard.
On remarque que la « virgule » se note avec un point (comme sur la calculatrice) et quâil est possible dâadditonner un Ă©lĂ©ment de type int avec un type float.
>>> type (4.25)
<class âfloat â>
>>> type (2.0)
<class âfloat â>
>>> 4.5 + 3
7.5
Attention, une fois entre guillemet un nombre nâest plus du type int ou float mais devient une chaĂźne de caractĂšre.
>>> type("42")
<class âstr â>
On peut parfois convertir un type en un autre, par exemple :
>>> type(int("42")) # La fonction int permet d'effectuer la conversion
<class âint â>
Opérateurs arithmétiques
Le langage Python fournit les opérateurs mathématiques classiques
-
Addition, soustraction
âïž RĂ©sultat>>> 2 + 3 5 >>> 2 - 3 -1 -
Multiplication, division
âïž RĂ©sultat>>> 3 * 5 15 >>> 15 / 2 7.5 -
Mise Ă la puissance
âïž RĂ©sultat>>> 2 ** 5 # 2 puissance 5 32 -
Quotient dans la division euclidienne
âïž RĂ©sultat>>> 15 // 2 # 15 divisĂ© par 2 donne 7 reste 1 7 -
Reste dans la division euclidienne
âïž RĂ©sultat>>> 15 % 2 # 15 divisĂ© par 2 donne 7 reste 1 1
Fonctions
Définir une fonction
Considérons le problÚme suivant :
« Calculer le pĂ©rimĂštre dâun rectangle dĂ©fini par sa largeur et sa longueur. »
La solution mathĂ©matique est dâappliquer dans chacun des cas la formule $2 \times (\text{longueur } + \text{ largeur})$, en fonction des dimensions du rectangle. Par exemple en Python :
>>> 2 * (4 + 3) # rectangle de longueur 4 et de largeur 3
14
>>> 2 * (7 + 5) # rectangle de longueur 7 et de largeur 5
24
On peut définir une fonction perimetre qui prend en argument deux nombres longueur et largeur et qui renvoie le périmÚtre d'un rectangle ayant pour dimensions longueur $\times$ largeur.
| đ Code Python | |
|---|---|
1 2 3 4 5 6 | |
On peut à présent appeler la fonction perimetre :
>>> perimetre(4, 3)
14
>>> perimetre(7, 5)
24
Spécification
Lâobjectif de la spĂ©cification dâune fonction est de permettre de dĂ©finir explicitement son comportement, de comprendre ce quâelle fait et quelles sont ses restrictions.
La fonction Python help permet dâobtenir la spĂ©cification dâune fonction :
>>> help(perimetre)
perimetre(longueur, largeur)
int, int -> int
precondition : (longueur > 0) et (largeur > 0)
Renvoie le périmÚtre d'un rectangle de dimensions longueur à largeur
La spĂ©cification dâune fonction peut se dĂ©composer en quatre parties :
- lâen-tĂȘte qui prĂ©cise le nom de la fonction et de ses paramĂštres (on dit aussi de ses arguments) ;
- la signature qui précise le type de ses paramÚtres et de sa valeur de retour ;
- dâĂ©ventuelles prĂ©conditions qui fixent les restrictions sur les paramĂštres ;
- la description du rĂŽle de la fonction.
Tests
Pour dĂ©tecter dâĂ©ventuelles erreurs, les fonctions sont accompagnĂ©es dâun jeu de tests. On utilise pour cela lâinstruction assert.
assert perimetre(4, 3) == 14
assert perimetre(7, 5) == 24
assert perimetre(2, 2) == 8
Si perimetre(4, 3) ne renvoie pas la valeur attendue 14, un message dâerreur apparaitra. Par exemple
>>> assert perimetre(4, 3) == 42 # la valeur de test est incorrecte
Traceback (most recent call last):
File "<stdin>", line 1, in <module >
AssertionError
Création d'une fonction
L'utilisation de fonctions est fondamentale en informatique. Cela permet notamment de réutiliser des portions de codes utiles. Pour cela on ajoute un niveau d'intation au code en question, et on ajoute la spécification de la fonction. Par exemple :
| đ Code Python | |
|---|---|
1 2 3 4 5 6 | |
| đ Code Python | |
|---|---|
1 2 3 4 5 6 7 8 9 10 | |
BibliothĂšques de fonctiosn
Les fonctions les plus utiles sont souvent déjà écrites en Python. Nous pouvons en utiliser certaines directement,
comme : max, help, type ou print.
Dâautres sont aussi disponibles dans des bibliothĂšques de fonctions (en anglais librairies ou module). Par exemple :
math(qui contient toutes les fonctions mathématiques courantes) ;random(qui contient des fonctions qui renvoient des nombres pseudo-aléatoires).
Pour pouvoir utiliser les fonctions présents dans ces bibliothÚques, on doit importer la bibliothÚque. Par exemple, pour obtenir un nombre au hasard entre 0 et 10 (inclus).
>>> import random # import de la bibliothĂšque
>>> random.randint(0, 10) # appel de la fonction randint du module random
7
On peut également importer une fonction d'une bibliothÚque spécifique. Par exemple, la fonction sqrt du module math calcule la racine carrée d'un nombre flottant.
>>> from math import sqrt
>>> sqrt(2)
1.4142135623730951
Remarque. L'instruction from turtle import * importe toutes les fonctions du module turtle. C'est une mauvaise pratique dans le cas général.
Variables et affectation
Quand on exécute un programme, la machine nous attribue une plage de mémoire dans laquelle nous pouvons stocker des données. Cette mémoire est constituée de "cases", toutes identifiées par une adresse.
Une variable peut ĂȘtre vue comme un nom que l'on donne Ă une valeur stockĂ©e en mĂ©moire. On peut utiliser les variables pour stocker ou modifier une information en mĂ©moire.
Lorsque l'on donne une valeur $v$ à une variable ma_variable, on écrit en pseudo-code $\texttt{ma_variable} \leftarrow v$. L'instruction Python correspondante est ma_variable = v.
On dit que l'on affecte Ă ma_variable la valeur $v$.
Si ma_variable possÚde déjà une valeur, la nouvelle valeur écrase la précédente.
Remarque. En Python, le nom dâune variable ou dâune fonction est une suite de lettres (minuscules ou majuscules) et de chiffres, qui doit toujours commencer par une lettre, et qui ne contient pas de caractĂšres spĂ©ciaux sauf lâunderscore : _. Il nâest pas possible dâutiliser des mots clefs du langage, tel que def ou for.
Il est dâusage de choisir des termes explicites pour faciliter la lecture du code. Nous Ă©viterons les majuscules et les accents pour les noms de variables ou de fonction, nous utiliserons _ pour sĂ©parer les mots.
Noms de variable
Barrer avec une croix les noms de variables qui sont invalides. Rayer d'un trait les noms de variable qui sont mals choisis.
hello |
"world" |
for |
enâtete |
état |
6_nbre |
|---|---|---|---|---|---|
six nbr |
nbr |
Dromadaire |
monChameau |
mon_python |
attention! |
def |
_largeur_ |
42 |
Affectation de $1$ Ă la variable a
>>> a = 1
>>> a
1
On peut modifier le contenu d'une variable Ă l'aide de plusieurs affectations.
>>> a = 1
>>> a = 2
>>> a
2
On peut copier le contenu d'une variable dans une autre.
>>> a = 1
>>> b = a
>>> b
1
Les variables peuvent ĂȘtre utilisĂ©es dans des expressions.
>>> l = 4
>>> L = 3
>>> p = 2*(l + L)
>>> p
14
Il est possible de réaliser des affectations multiples.
>>> a, b, c = 1, 2, "NSI"
>>> b
2
La fonction id renvoie un nombre entier qui reprĂ©sente la case mĂ©moire oĂč est stockĂ©e l'information relative Ă la variable.
>>> a = 1
>>> id(a)
140344818602800
Important. L'affectation copie la valeur de l'expression Ă droite du signe = dans la case mĂ©moire identifiĂ©e par le nom Ă gauche du signe =. La valeur de la variable peut-ĂȘtre modifiĂ©e Ă un autre endroit du programme.
>>> a = 1
>>> c = a + 1
>>> a = 42
>>> c
2
Ainsi, le signe = en Python ne traduit pas une égalité mathématique entre objets.
Conditions et instructions conditionnelle
Une condition est une expression qui s'évalue à True (la condition est vraie) ou False (la condition est fausse). On dit que les conditions sont de type booléen.
Les conditions portent sur les variables en mémoire. En pseudo code on utilise les symboles mathématiques. En Python on utilise les symboles suivants :
\renewcommand{\arraystretch}{1.5}
| Tester si | Code python |
|---|---|
x est égal à y |
|
x est différent de y |
|
x est inférieur à y |
|
x est supérieur ou égal à y |
|
x \(\in\) \([\texttt{a}, \texttt{b}]\) |
On peut combiner des conditions entre elles à l'aide des opérateurs and, or et not.
On peut comparer des nombres entre eux :
>>> 3 + 7 < 5
False
On peut affecter le résultat d'une expression à une variable
>>> condition = 3 + 7 < 5
>>> condition
False
On peut exprimer des conditions complexes :
x < 0 or x > 100 # False si x appartient Ă [0 ; 100]
0 <= y and y <= 100 # True si y appartient Ă [0 ; 100]
0 <= z <= 100 # True si z appartient Ă [0 ; 100]
not (x < 0) # False si x < 0
Il est souvent nécessaire de n'exécuter des instructions que dans certains cas. Dans ce cas on utilise une structure conditionnelle.
Par exemple, on dispose des instructions instruction1, instruction2, instruction3, instruction4, et instruction5 et de conditions condition1, condition2 et condition3.
| đ Code Python | |
|---|---|
1 2 3 4 5 | |
| đ Code Python | |
|---|---|
1 2 3 4 5 6 7 | |
| đ Code Python | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
On remarque un décalage vers la droite à l'écriture des instructions. C'est ce que l'on appelle l'indentation. Il sert à structurer le code. L'annulation de l'indentation marque la sortie de la structure conditionnelle.
| đ Code Python | |
|---|---|
1 2 3 4 | |
fin
| đ Code Python | |
|---|---|
1 2 3 4 5 6 | |
négatif
fin
| đ Code Python | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
bon
Boucles
Boucles bornées
Lorsque l'on souhaite répéter un bloc d'instruction un nombre de fois connu à l'avance, on utilise une boucle bornée, aussi appelée boucle for ("pour").
| đ Code Python | |
|---|---|
1 2 | |
Par exemple :
| đ Code Python | |
|---|---|
1 2 3 4 | |
| đ Code Python | |
|---|---|
1 2 3 | |
| đ Code Python | |
|---|---|
1 2 3 | |
| đ Code Python | |
|---|---|
1 2 3 4 | |
| đ Code Python | |
|---|---|
1 2 3 4 5 6 7 8 9 | |
Remarque. On peut utiliser différentes syntaxes pour la boucle for :
for i in range(n): |
i prend successivement pour valeurs 0, 1, \ldots, n - 1 |
|---|---|
for i in range(n, m): |
i prend successivement pour valeurs n, n + 1, \ldots, m - 1 |
for i in range(n, m, p): |
i prend successivement pour valeurs n, n + p, n + 2p, \ldots |
for i in a, b, c, d: |
i prend successivement pour valeurs a, b, c, puis d |
| đ Code Python | |
|---|---|
1 2 | |
0 1 2
| đ Code Python | |
|---|---|
1 2 | |
2 3 4
| đ Code Python | |
|---|---|
1 2 | |
2 6 10 14
| đ Code Python | |
|---|---|
1 2 | |
5 4 3 2 1 0
Boucles non bornées
Il arrive parfois que l'on souhaite répéter un bloc d'instruction un nombre de fois qui n'est pas connu à l'avance. Pour cela, on utilise une boucle non bornée, aussi appelée boucle while ("tant que").
| đ Code Python | |
|---|---|
1 2 | |
On souhaite déterminer le plus petit nombre entier $n$ tel que $2^n$ soit plus grand qu'un certain nombre flottant nbr fixé à l'avance. On calcule les différentes puissances de $2$ : $2^0$, $2^1$, $2^2$, $2^3$, \ldots tant que celles-ci sont plus petites que nbr.
| đ Code Python | |
|---|---|
1 2 3 4 5 6 7 8 | |
On dresse la trace d'exécution de plus_petit_entier(10) :
| Ligne exécutée | l3. |
||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
nbr |
|||||||||||||
exposant |
|||||||||||||
2**exposant < nbr |
Attention. Si la condition de la boucle est toujours vraie, alors les instructions sont rĂ©pĂ©tĂ©es sans jamais s'arrĂȘter. On parle de "boucle infinie".
| đ Code Python | |
|---|---|
1 2 3 | |
Il est toujours possible de transformer une boucle for en une boucle while. Cependant, le contraire n'est pas toujours vrai.
Par exemple, les deux programmes ci-dessous produisent le mĂȘme affichage.
| đ Code Python | |
|---|---|
1 2 | |
| đ Code Python | |
|---|---|
1 2 3 4 | |
Il n'est par contre pas possible de transformer la boucle while de la fonction plus_petit_entier en boucle for.
Lorsque l'on peut se passer d'une boucle while, on préfÚre toujours écrire un programme à l'aide d'une boucle for.