I) Variables, opérations arithmétiques et fonctions
1) Notion de variable
Définition du mot ordinateur d'après "Le Petit Larousse" :
"Ordinateur : Machine automatique de traitement de l'information, obéissant à des programmes formés par des suites d'opérations arithmétiques et logiques."
Qui dit "traitement de l'information", dit donc données à manipuler. Un programme "passe" donc son temps à traiter des données. Pour pouvoir traiter ces données, l'ordinateur doit les ranger dans sa mémoire (RAM - Random Access Memory). La RAM se compose de cases dans lesquelles nous allons ranger ces données (une donnée dans une case). Chaque case a une adresse (ce qui permet au processeur de savoir où sont rangées les données).
Alors, qu'est-ce qu'une variable ?
C'est une petite information (une donnée) temporaire que l'on stocke dans une case de la RAM. On dit qu'elle est "variable", car c'est une valeur qui peut changer pendant le déroulement du programme.
Une variable est constituée de 2 choses :
-
une valeur présente en mémoire (par exemple le nombre entier 12)
-
un nom (par exemple i)
On dira donc qu'une variable est l'association d'un nom et d'une valeur.
Il est aussi possible d'associer un nom à un nombre à virgule :
Un nom peut donc être associé à plusieurs types d'entités (pour l'instant nous n'en avons vu que deux, mais nous en verrons d'autres plus loin) : les nombres entiers ("integer" en anglais, abrégé en "int") et les nombres à virgule ("float" en anglais). Il est possible de connaître le type de l'entité à l'aide de l'instruction "type".
Si on écrittype(a) dans la console, cela donnera comme résultat int alors que type(b) donnera float
2) Opérations arithmétiques
Un ordinateur est bien évidemment capable d'effectuer des opérations mathématiques (arithmétiques).
| Opérations | Opérateur | Exemple | Résultat |
|---|---|---|---|
| Addition | + | 2 + 3 | 5 |
| Soustraction | - | 7 - 3 | 4 |
| Multiplication | * | 5 * 2 | 10 |
| Division | / | 7 / 2 | 3.5 |
| Division euclidienne | // | 7 // 2 | 3 |
| Reste | % | 7 % 2 | 1 |
| Puissance | ** | 2 ** 3 | 8 |
Il est tout à fait possible d'effectuer des opérations directement avec des nombres, mais il est aussi possible d'utiliser des variables.
Considérons maintenant le programme suivant :
D'après vous, quelle est la valeur de la variablea après l'exécution du programme ci-dessus ?
La réponse est 12.
Détaillons ce qui se passe dans ce programme :
Nous créons une variable : le nom a est associé à l'entier 11. La suite est un peu plus complexe, mais très importante à comprendre. Il va falloir lire la ligne a = a + 1 de droite à gauche, décortiquons cette ligne :
- a + 1 : nous prenons la valeur actuelle associée au nom a (c'est-à-dire 11) et nous ajoutons 1 à 11, à droite de l'égalité nous avons donc maintenant la valeur 12
- nous associons la valeur qui vient d'être calculée au nom a
Donc la valeur de a est bien 12
Ce raisonnement peut être généralisé pour éviter des erreurs parfois difficiles à corriger : dans une égalité, commencer toujours par évaluer l'expression se trouvant à droite du signe égal.
L'opération
3) Les fonctions
a) Notion de fonction
Les fonctions permettent de décomposer un programme complexe en une série de sous-programmes plus simples. De plus, les fonctions sont réutilisables : si nous disposons d'une fonction capable de calculer une racine carrée, par exemple, nous pouvons l'utiliser un peu partout dans notre programme sans avoir à la réécrire à chaque fois (on parle de factorisation du code)
La notion de fonction en informatique est comparable à la notion de fonction en mathématiques.

Si nous avons y = 3x+2, pour une valeur donnée de x, nous aurons une valeur de y.
Exemple : x=4 donc y= 14 (y = 3.4+2=14, attention ici le point correspond au signe "multiplié").
La fonction en informatique est basée sur la même idée :

Voici la syntaxe employée en Python pour définir une fonction :
La fonction renvoie la valeur associée à y.
ATTENTION : Notez bien la présence du décalage entre la première ligne et les lignes suivantes. Ce décalage est appelé indentation, l'indentation permet de définir un bloc de code. Dans l'exemple ci-dessus, l'indentation nous permet de savoir que instruction_1, instruction_2 et return y constituent un bloc de code, ce bloc correspond au contenu de la fonction. "suite programme" ne fait pas partie de la fonction, car il n'est pas indenté. Pour indenter du code, il y a 2 solutions : mettre 4 espaces ou utiliser une tabulation. En Python il est conseillé d'utiliser les 4 espaces, mais ce n'est pas une obligation. Une chose est sûre, une fois que vous avez choisi une méthode, n'en changé surtout pas au cours d'un même programme !
Codons notre exemple en créant une fonction ma_fonction :
Pour "utiliser" la fonction ma_fonction, il suffit d'écrire :ma_fonction(4) (dans ce cas précis, notre fonction renverra le nombre 14 : x sera égale à 4 dans la fonction on aura donc le calcul 3 . 4 + 2 = 12 + 2 = 14).
Si on considère cet exemple :
Après l'exécution de ce programme, la valeur de la variable solution sera 14. En effet, au moment de l'exécution de notre programme le code ma_fonction(4) sera systématiquement remplacé par la valeur renvoyée par la fonction. Dans notre exemple le ma_fonction(4) sera remplacé par le nombre 14, d'où la valeur 14 pour la variable solution.
Il est possible de passer plusieurs paramètres à une fonction :
Dans ce cas, dans la fonction, le paramètrex sera égal à 4 et le paramètre b à 3 (attention à l'ordre des paramètres). On a aura donc la variable solution qui aura pour valeur 11 (2.4 + 3 = 11) après l'exécution de ce programme.
Les paramètres peuvent être des chaînes de caractères (ainsi que la valeur retournée)
Attention : remarquez bien les guillemets autour du paramètre toto (c'est une chaîne de caractères)
b) Les fonctions natives de python
Python propose des fonction prêtes à être utilisées par le programmeur : les fonctions natives (built-in function en anglais). Nous avons déjà eu l'occasion d'en voir deux avec type (qui renvoie le type d'une variable) et str qui renvoie la chaîne de caractère obtenue à partir d'un nombre (str(4) renvoie le caractère 4). Il existe beaucoup d'autres fonctions natives Python (il en existe plus de 50). Dans l'immédiat, nous allons en étudier deux autres :
-
la fonction
lenprend en paramètre une chaîne de caractères et renvoie le nombre de caractères présents dans cette chaîne de caractères (par exemplelen("azerty")renvoie 6) ; -
la fonction
printpermet d'afficher à l'écran la valeur qui lui est passée en paramètre.
c) Les modules en Python
Il est possible d'utiliser d'autres fonctions "prêtes à l'emploi" en important des modules. Un module est un fichier contenant des fonctions qui pourront être utilisées dans d'autres programmes. Le module math est un module très important puisqu'il comporte toutes les fonctions mathématiques classiques : cosinus, sinus, exposant, racine carrée...
Pour utiliser les fonctions présentes dans un module, il est nécessaire d'importer le module dans notre programme. Par exemple, pour pouvoir utiliser les fonctions du module math il faudra écrire :
Pour utiliser une fonction d'un module importé, il faudra préciser le nom du module qui propose cette fonction. Par exemple, pour déterminer le sinus de 3.14, il faudra écrire :
- la variable
puisaura pour valeur ; - la variable
racineaura pour valeur 4 (racine carrée de 16) ; - la variable
saura pour valeur 0.05 (le sinus de 3.14 est 0.05).
Une autre façon consiste à importer une, plusieurs fonctions.
Reprenons le programme précédent pour importer toutes les fonctions du module math avec le symbole * :
- Dans ce cas, on perd l'information du module d'appartenance, ce qui peut parfois être embêtant.
- Si on peut l'éviter ou si on est certain qu'il n'y aura pas de confit entre plusieurs modules, on pourra s'en servir.
d) Les fonctions et le mot clé return
Il est possible d'écrire une fonction sans utiliser le mot clé return, cette pratique est souvent considérée comme une "mauvaise pratique", mais Python ne renverra pas d'erreur si vous le faites. Le code suivant est tout à fait correct :
Pour information, même en l'absence de return, une fonction Python renvoie quand même "quelque chose", puisqu'elle renvoie None qui veut dire rien...
Dans le cas ci-dessus nous aurons donc :

4) Variables locales et variables globales
a) Variables et fonctions
Considérons le programme suivant:
Nous commençons par définir une fonctionma_fonc qui ne prend aucun paramètre et qui ne renvoie aucune valeur (absence du mot clé return). Cette fonction attribue juste la valeur 5 a la variable ayant pour nom i.
A la 3e ligne du programme, nous exécutons la fonction ma_fonc.
Rappelons que la fonction print permet d'afficher à l'écran la valeur qui lui est passée en paramètre. La 4e ligne de ce programme permet donc d'afficher la valeur de la variable i à l'écran.
On pourrait penser que ce programme va donc afficher 5 ! Pas du tout, nous avons le droit à l'erreur suivante :
Le message d'erreur est suffisamment parlant, inutile de s'attarder dessus : la variable i n'est pas définie. A noter que cette erreur est déclenchée par la 4e ligne (le print).
Pourquoi cette erreur, la variable i est bien définie dans la fonction ma_fonc et la fonction ma_fonc est bien exécutée, où est donc le problème ?
En fait, la variable i est une variable dite locale : elle a été définie dans une fonction et elle "restera" dans cette fonction. Une fois que l'exécution de la fonction sera terminée, la variable i sera "détruite" (supprimée de la mémoire). Elle n'est donc pas accessible depuis "l'extérieur" de la fonction (ce qui explique le message d'erreur que nous obtenons, car le print est en dehors la fonction ma_fonc, la variable i n'est donc plus accessible).
Étudions maintenant un cas un peu plus complexe :
On pourrait s'attendre à voir s'afficher la valeur 5 à l'écran. Pas du tout, nous ne rencontrons pas d'erreur cette fois, mais c'est la valeur 3 qui s'affiche à l'écran.En fait dans cet exemple nous avons 2 variables i différentes : la variable i "globale" (celle qui a été définie en dehors de toute fonction) et la variable i "locale" (celle qui a été définie dans la fonction). Ces 2 variables portent le même nom, mais sont différentes (elles correspondent à des cases mémoire différentes). Au moment de l'exécution du print à la 5e ligne seule la variable globale existe encore (celle définie à la première ligne du programme), d'où l'affichage du 3.
Une variable globale peut être "utilisée" à l'intérieur d'une fonction :
Attention, leprint se situe dans la fonction (la ligne du print est bien indentée)
Ce programme permet d'afficher la valeur 3 à l'écran.
Quand on cherche à utiliser une variable dans une fonction, le système va d'abord chercher si cette variable se "trouve" dans l'espace local de la fonction, puis, s'il ne la trouve pas dans cet espace local, le système va aller rechercher la variable dans l'espace global. Pour le print(i) situé dans la fonction le système ne trouve pas de variable i dans l'espace local de la fonction ma_fonc, il passe donc à l'espace global et trouve la variable i (nous avons donc 3 qui s'affiche).
Il est important de bien comprendre que dans la programme ci-dessous le système trouve une variable i dans l'espace local de la fonction, la "recherche" de la variable i se serait arrêtée là :
et ce programme affiche la valeur 5 à l'écran. i a été trouvée dans l'espace local de la fonctionma_fonc, la recherche ne va donc pas plus loin (inutile de remonter jusqu'à l'espace global)
En revanche le programme ci-dessous génère une erreur : "UnboundLocalError: local variable 'i' referenced before assignment"
Il n'est à priori pas possible de modifier une variable globale (ici la variable i) dans une fonction.
Pour pouvoir modifier une variable globale dans une fonction, il faut utiliser le mot clé global :
Je ne vais pas m'étendre sur l'utilisation du mot clé global car comme nous allons le voir maintenant, c'est une (très) mauvaise pratique, car cette utilisation peut entraîner des "effets de bord".
b) Les effets de bord
On parle d'effet de bord quand une fonction modifie l'état d'une variable globale. Dans notre exemple ci-dessus, la fonction ma_fonc modifie bien la valeur de i : avant l'exécution de ma_fonc, i a la valeur 3, après l'exécution de la fonction ma_fonc, i est associé à la valeur 4. Nous avons donc bien un effet de bord.
Les effets de bord c'est "mal" ! Mais pourquoi est-ce "mal" ?
Les effets de bords provoquent parfois des comportements non désirés par le programmeur (évidemment dans des programmes très complexes, pas dans des cas simplistes comme celui que nous venons de voir). Ils rendent aussi parfois les programmes difficilement lisibles (difficilement compréhensibles). À cause des effets de bord, on risque de se retrouver avec des variables qui auront des valeurs qui n'étaient pas prévues par le programmeur. On dit aussi qu'à un instant donné, l'état futur des variables est difficilement prévisible à cause des effets de bord. En résumé, on évitera autant que possible l'utilisation du global.
Un paradigme de programmation se propose d'éviter au maximum les effets de bords : la programmation fonctionnelle. Nous étudierons ce paradigme de programmation en terminale.