Vous êtes sur la page 1sur 41

Cours d'algorithmique

(et notions de Python 3)


BTS SIO 1  U22

Alain Satabin

Lycée Monge
Charleville-Mézières

juin 2012 (version 1.0)


octobre 2012 (version 1.1)
novembre 2013 (version 1.2)
Table des matières

1 Préliminaires indispensables 4
1.1 De quoi est-il question ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.1.1 Dénition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.1.2 Commentaires excessivement importants . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.1.3 Quelques exemples de la vie courante . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.1.4 Tout petit déjà . . . ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

1.1.5 Quelques règles méthodologiques dont on ne dérogera point ! . . . . . . . . . . . . . . . 4

1.2 Et l'informatique dans tout ça ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.2.1 Petit point d'histoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

1.2.2 Machine et algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Variables et opérateurs 6
2.1 Utilisation des variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.1.1 Les conventions d'écriture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.1.2 Aectation d'une variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.1.3 Évaluation à la main . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

2.1.4 Typage et transtypage de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.1.5 Lecture / Écriture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

2.1.6 Schéma d'écriture d'un algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2 Opérateurs de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2.1 Sur les variables réelles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2.2 Sur les variables entières . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2.3 Sur les chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.2.4 Sur les booléens . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2.3 Quelques fonctions utiles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3.1 Sur les nombres . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3.2 Sur les chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.3.3 Transtypage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

3 Structures de contrôle 10
3.1 Traitement conditionnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.1.1 Traitement simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.1.2 Traitement étendu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10

3.1.3 Imbrication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

3.2 Les boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.2.1 La boucle "Tant Que" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12

3.2.2 La boucle "Pour" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

3.2.3 Imbrication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

4 Les tableaux 15
4.1 Deux exemples pour se faire une idée . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.1.1 Un exemple à une dimension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

U22 - Algorithmique - Chapitre n°0 Page 1/40


4.1.2 Un exemple à deux dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.2 La théorie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.2.1 Des variables à tiroirs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

4.2.2 Taille d'un tableau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.2.3 Aectation directe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.2.4 Extension d'un tableau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

4.3 Exemples rédigés . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

4.3.1 Test de lancer de dés : un tableau de taille xée . . . . . . . . . . . . . . . . . . . . . . 17

4.3.2 Analyse d'une série de notes : un tableau à taille variable . . . . . . . . . . . . . . . . 18

4.3.3 Le triangle de Pascal : un tableau à deux dimensions . . . . . . . . . . . . . . . . . . . 19

5 Procédures et Fonctions 20
5.1 La sous-traitance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

5.1.1 Pourquoi ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

5.1.2 La division des tâches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

5.1.3 Éviter la répétition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5.1.4 Fonctionnement général . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21

5.1.5 Syntaxe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.2 Deux espèces de sous-algorithme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.2.1 La procédure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.2.2 La fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

5.2.3 Des sous-algorithmes adaptables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

5.2.4 Conventions d'écriture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.3 Fonctions et procédures avec arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.3.1 Le passage d'arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24

5.3.2 Un exemple de procédure avec deux arguments . . . . . . . . . . . . . . . . . . . . . . 25

5.3.3 Un classique : la fonction factorielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

5.4 La portée des variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

5.4.1 Quel est le problème ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

5.4.2 Variables globales et locales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

5.4.3 Visibilité des variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5.4.4 Le comportement des homonymies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

6 La récursivité 30
6.1 La magie de l'auto-référence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6.1.1 Un petit exemple ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6.1.2 Une fonction auto-référentielle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6.1.3 Comment ça marche ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30

6.2 La solution est en vous . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6.2.1 Dénition de la récursivité . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6.2.2 Je vous demande de vous arrêter ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31

6.2.3 Fonctionne avec pile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

6.2.4 La fonction factorielle, le retour ! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

6.3 Réexions sur le procédé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

6.3.1 Le piège classique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

U22 - Algorithmique - Chapitre n°0 Page 2/40


6.3.2 À utiliser avec modération . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

6.3.3 En bouquet nal : les tours de Hanoï . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33

A Les bases du Python 3 35


A.1 Interface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.2 Commentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.3 Structure générale . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.4 Aectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.5 Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.6 Saisie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

A.7 Achage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35

B Opérations et fonctions élémentaires en Python 3 36


B.1 Opérations et opérateurs de base . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

B.2 Fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36

C Structures de contrôle élémentaires en Python 3 37


C.1 Traitement conditionnel simple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

C.2 Traitement conditionnel étendu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

C.3 Boucle Tant que . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

C.4 Boucle Pour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

D Les tableaux en Python 3 38


D.1 Tableau à une dimension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

D.1.1 Déclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

D.1.2 Accès aux données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

D.1.3 Aectation dynamique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

D.2 Tableau à deux dimensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

D.2.1 Déclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

D.2.2 Accès aux données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

D.2.3 Aectation dynamique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

E Dénition de procédure et fonction en Python 3 39


E.1 Procédure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

E.2 Fonction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

F Codes Ascii de 32 à 127 40

U22 - Algorithmique - Chapitre n°0 Page 3/40


U22 - Chapitre n° 1
Préliminaires indispensables

1.1 De quoi est-il question ?


1.1.1 Définition
Un algorithme est une séquence ordonnée d'instructions exécutées de façon logique, mais non intelligente.

1.1.2 Commentaires excessivement importants

Un algorithme possède un début et une n et doit se terminer en un temps ni.

Les instructions composant un algorithme sont susamment simples pour être compréhensibles par l'exécu-
tant (homme ou machine). On les appelle alors des instructions élémentaires.
 Logique et non intelligente  signie que l'exécutant (homme ou machine) doit appliquer strictement les
instructions les unes après les autres, sans se poser la question de la justesse du résultat, ni de la façon dont
il est obtenu. Si l'algorithme est bien fait, le résultat est correct dans tous les cas de gure !

Le concepteur d'un algorithme (donc vous !) doit dominer l'action globale à réaliser et doit en même temps
être capable de la décomposer en une suite d'actes élémentaires compréhensibles par l'exécutant qui, lui, est
un profane dans le domaine. Cela n'est pas toujours une opération aisée !

1.1.3 Quelques exemples de la vie courante

Exemple 1 : Une recette de cuisine.

Exemple 2 : Une notice de montage.

Exemple 3 : Un guide de réparation.

Exemple 4 : Un itinéraire.

1.1.4 Tout petit déjà . . . !

Dès l'école primaire vous avez fréquemment manipulé la notion d'algorithme. Lorsque, par exemple, à partir
des tables d'addition des nombres à 1 chire vous avez appris à additionner deux nombres quelconques . . .
et ensuite en apprenant à faire des multiplications.

En géométrie vous avez également rencontré bon nombre d'algorithmes : par exemple en apprenant le pro-
tocole de construction d'une médiatrice d'un segment avec une règle et un compas.

1.1.5 Quelques règles méthodologiques dont on ne dérogera point !


Article 1 : Vériez sur des cas simples que vous avez compris le problème à résoudre et que vous savez le
faire  à la main 

Article 2 : Décomposez votre résolution du problème en actions de plus en plus simples . . . jusqu'à atteindre
un niveau élémentaire que l'exécutant comprendra

Article 3 : Choisissez intelligemment les noms de variable


1
que vous serez amenés à dénir

Article 4 : Ne supposez jamais que l'exécutant va supposer quelque chose


2

Article 5 : Mettez des titres et des commentaires


3

Article 6 : Testez votre algorithme  à la main  sur des cas particuliers simples
4

Article 7 : N'hésitez jamais à tout reprendre à zéro !


5

1. les variables sont à un algorithme ce que les personnages sont à un roman ou un lm
2. l'exécutant possède un vocabulaire limité et est obéissant, mais bête !
3. cela n'a aucune utilité pour le bon fonctionnement de l'algorithme, mais le rend plus lisible et plus compréhensible
4. le concepteur doit être capable de simuler le comportement d'un exécutant bête et discipliné !
5. rien de plus horrible et incertain qu'un algorithme  bidouillé  et rustiné de toutes parts !

U22 - Algorithmique - Chapitre n°1 Page 4/40


1.2 Et l'informatique dans tout ça ?
1.2.1 Petit point d'histoire
Étymologiquement, le mot  algorithme  prend ses racines dans le nom du mathématicien arabe du moyen
6 7
âge : Al-Kawarizmi. Le mot fut inventé par Ada Lovelace , assistante de Charles Babbage.

En 1936, le mathématicien anglais Alan Turing publie un document sur la résolution des problèmes
calculables par une machine virtuelle simple : la machine de Turing. Considérée comme le premier ordinateur
conceptualisé, sa machine est universelle et peut résoudre tout problème se traduisant en algorithme à partir
d'un nombre très réduit d'instructions élémentaires.

C'est avec le mathématicien américano-hongrois John von Neumann qu'il réalisera et fera fonctionner le
21 juin 1948 le premier ordinateur : le Manchester Mark I. Pour la circonstance il crée le premier langage
informatique, le short code, doté d'une cinquantaine d'instructions.

1.2.2 Machine et algorithme

Une machine en général et un ordinateur en particulier sont des objets idiots qui se contentent de faire à la
lettre ce que vous lui dictez de faire. Les mythes d'ordinateurs intelligents (Matrix, 2001 Odyssée de l'espace,
R2D2, etc.) restent pour l'instant du domaine de la science-ction !

8 9
Un ordinateur n'est qu'un ensemble de circuits logiques traitant des informations binaires . Une façon
de s'adresser à lui pour lui faire remplir une tâche est de lui parler dans son langage primaire : le langage
machine 10
.

C'est long et fastidieux !

C'est pour cette raison que se sont développés des logiciels appelés langages de programmation 11 qui sont en
quelque sorte des interprètes traduisant des instructions claires en langage machine.

Lorsqu'il est traduit dans un langage de programmation, l'algorithme s'appelle un programme et son concep-
teur le programmeur ou développeur s'il s'agit de projets plus sophistiqués.

Le but de ce cours est d'apprendre à écrire des algorithmes, c'est à dire à décomposer une action compliquée
en instructions simples. Cet exercice est a priori totalement indépendant d'un langage de programmation et
reste un travail  de papier . Nous écrirons nos algorithmes dans un pseudo-langage et, pour les tester sur
une machine, nous les traduirons dans un langage de programmation.

Cette mise en ÷uvre d'un algorithme sur une machine s'appelle l' implémentation.
12
Nous choisirons le Python 3 . La syntaxe liée à ce langage gure en annexe de ce document et sera vue
au fur et à mesure du déroulement du cours d'algorithmique.

6. Fille de l'écrivain britannique Lord Byron (1788-1824)


7. Mathématicien inventeur britannique (1791-1871) qui fut l'un des précurseurs de l'informatique en concevant sur le papier
une machine analytique mécanique, programmable, à mémoires et dotée d'organes d'entrées-sortie. La technique des tailles de
pignon d'engrenage et autres petites pièces mécaniques n'était pas susamment maitrisée à l'époque et il ne verra jamais sa
machine fonctionner ! A la n du XXe siècle, des chercheurs britanniques réalisèrent la machine selon les plans de l'inventeur et
nous savons aujourd'hui qu'elle fonctionne.
8. portes OU, ET, NON, NONET, NONOU, etc.
9. présence ou absence de courant sur une patte d'entrée d'un composant électronique
10. succession de 1 et 0 traduisant des instructions et données, avec un nombre restreint d'instructions
11. ADA, FORTRAN, BASIC, COBOL, PASCAL, C, JAVA, etc.
12. Ce choix est arbitraire et l'algorithme écrit est universel . . . vous pouvez le traduire dans tout autre langage
U22 - Algorithmique - Chapitre n°1 Page 5/40
U22 - Chapitre n° 2
Variables et opérateurs

2.1 Utilisation des variables


2.1.1 Les conventions d'écriture
Pour fonctionner, un algorithme a besoin de mémoriser des valeurs (données fournies par l'utilisateur, résul-
tats à acher, quantités intermédiaires pour un traitement . . .) an de pouvoir les réutiliser ensuite.

Pour cela il utilise ce qu'on appelle une variable, comparable à une boîte dans laquelle on peut déposer ou y
lire une valeur. An de s'y retrouver, cette  boîte  est étiquetée par un nom de variable.
Les noms de variables ne doivent pas comporter d'espace et ne peuvent pas commencer par
un chire. D'une façon générale, on se limitera aux caractères alphanumériques non accentués et au tiret
de soulignement.

La bonne lisibilité d'un algorithme étant fondamentale, il est important de choisir des noms de variable
reétant le rôle joué par la variable en question.

Par exemple voici quelques noms de variable valides : N ; Date ; Resultat_01 ; NbreValeurs ; Nom_Famille ...

2.1.2 Affectation d'une variable

Le fait d'attribuer un contenu à une variable s'appelle l' aectation. Dans l'écriture d'un algorithme, elle est
symbolisée par ← selon la syntaxe :
N omV ariable ← V aleur
signiant que la quantité située à droite de la èche est évaluée, puis stockée dans la variable nommée
NomVariable, remplaçant ainsi son ancien contenu.

Voici quelques exemples d'aectation :

N←7 Met la valeur 7 dans la variable N


Mess ← "Bonjour" Met dans la variable Mess Bonjour
la chaîne de caractères
Date ← "7" Met la chaîne de caractère 7 Date
dans la variable
A←B Met dans la variable A le contenu de la variable B
Res ← Nb1+Nb2 Additionne les contenus des variables Nb1 et Nb2 et met le résultat dans Res
P ← P+2 Ajoute 2 au contenu de P et met le résultat dans P

2.1.3 Évaluation à la main

Lors de la mise au point d'un algorithme ou de la recherche d'erreurs, il est extrêmement important de savoir
le tester  à la main . Cela consiste à simuler la machine en suivant l'algorithme pas à pas et en tenant à
jour un tableau de contenu des variables. On parle alors du tracé pas à pas de l'algorithme.

Voici dans le tableau de droite un exemple de tracé de la suite d'instructions écrite à gauche :

instructions A B C D
Début début n.a. n.a. n.a. n.a.
A←2
←2
A 2 n.a. n.a. n.a.
B←5
←5
B 2 5 n.a. n.a.
C ← 12
C ← 12 2 5 12 n.a.
D←A+B
D ← A + B 2 5 12 7
C←A+C
C ← A + C 2 5 14 7
B←B+C
B ← B + C 2 19 14 7
A←CA
A ← C  A 12 19 14 7
D←B×DC
Fin D ← B × D  C 12 19 14 119
n 12 19 14 119

U22 - Algorithmique - Chapitre n°2 Page 6/40


2.1.4 Typage et transtypage de variables

On distingue pour pour commencer 4 types de variables : entier ; réel ; chaîne de caractères ; booléen.
Les deux premiers types servent à manipuler les nombres entiers ou "à virgule" (Z ou R)
Les chaînes de caractères sont conventionnellement écrites entre guillemets dans un algorithme.

Une variable de type booléen ne peut accueillir que l'une des deux valeurs Vrai ou Faux. Par exemple, si dans
un algorithme la variable Test est déclarée booléenne, on pourra trouver des instructions du genre Test ← Vrai
ou encore Test ← (Annee > 1582) 1 .
Les aectations opérées par l'algorithme doivent évidemment être cohérentes avec les types déclarés ! Par
exemple, si les variables A et B sont déclarées entières, les instructions A ← 3.7 ou A ← B/2 sont des erreurs.
De même, si A une variable de type entière et B de type réelle, l'aectation A ← B engendre une erreur, alors
que B←A est une instruction correcte.

Il convient de faire la diérence entre "3.14" (chaîne de caractères) et 3.14 (nombre réel) ou entre 3.0 (nombre
réel) et 3 (nombre entier)

Certaines fonctions, comme la partie entière ou l'arrondi à 0 décimale, ont la faculté de transformer un
nombre réel en nombre entier et pourront s'avérer fort utiles.

D'autres opérations de transtypage permettent de transformer une chaîne de caractères en nombre et ré-
ciproquement. Lors du transtypage d'une chaine en nombre, il est nécessaire que le contenu de la chaine
soit cohérent avec ce qu'on veut en faire ! Par exemple le transtypage de la chaine "3.14" en nombre entier
engendre une erreur.

Avant leur utilisation, les variables doivent toujours être initialisées, soit par une saisie (voir plus
loin), soit par l'aection d'une valeur xée.

2.1.5 Lecture / Écriture

Un algorithme doit évidemment pouvoir communiquer avec son utilisateur !

La lecture d'une donnée saisie au clavier par l'utilisateur et son stockage dans une variable s'écrit :

NomVariable ← saisir()
En arrivant sur cette instruction, le programme se met en attente d'une entrée. L'utilisateur tape quelque
chose au clavier et le valide, provoquant le stockage de la valeur tapée dans la variable NomVariable et la
reprise de l'algorithme à l'instruction suivante.

L'écriture d'un résultat ou d'un message se fait grâce à l'instruction acher(. . .)


Attention de ne pas confondre les instructions acher("Bonjour") et acher(Bonjour) : la première écrira la
chaîne de caractères Bonjour à l'écran alors que la seconde écrira le contenu de la variable Bonjour.
On peut acher plusieurs informations à la suite en les séparant par des virgules à l'intérieur de l'instruction
acher.
Par exemple la séquence d'instructions suivante :

...
A←2
B←5
Acher("A vaut ",A," , B vaut ",B," et leur somme vaut ",A+B)
...
provoquera la sortie à l'écran de : A vaut 2 , B vaut 5 et leur somme vaut 7
On peut provoquer une saisie avec l'achage d'un message grâce à l'instruction :

NomVariable ← saisir("message à acher ")


1. Annee étant ici une variable entière ; la variable Test sera aectée par Vrai ou Faux suivant que le contenu de Annee est
strictement supérieur à 1582 ou non
U22 - Algorithmique - Chapitre n°2 Page 7/40
Par exemple l'algorithme suivant ache le double de la valeur saisie :

Algorithme : Ache_Double
Rôle : calculer le double d'un entier donné
Entrées : Un nombre entier A
Sortie : achage de 2×A
Variables : entier : A
Début
A ← saisir("Donnez-moi un nombre entier : ")
Acher("le double de votre nombre vaut ",2×A)
Fin

2.1.6 Schéma d'écriture d'un algorithme

L'écriture d'un algorithme obéit à des règles précises et doit comporter :


ˆ un nom (répondant aux mêmes contraintes que les noms de variables)
ˆ son rôle (un commentaire décrivant ce que fait l'algorithme et éventuellement sa façon de procéder)

ˆ ses entrées / sorties (voir ci-dessous)

ˆ la déclaration des variables utilisées (noms et types)

ˆ un début et une n encadrant la suite d'instructions constituant l'algorithme

ˆ des commentaires an d'être facilement lisible et compréhensible. On signalera un commentaire par le
symbole #. Tout ce qui suit ce symbole sur la même ligne est ignoré par la machine.

2.2 Opérateurs de base


2.2.1 Sur les variables réelles
Les opérations classiques : + ; − ; × ; ÷ ; ax avec les priorités usuelles : l'élévation en puissance est évaluée
avant les multiplications (et divisions) qui sont elles-même évaluées avant les additions (et soustraction).
Vous avez bien sûr le droit (parfois même le devoir !) d'utiliser des parenthèses.

2.2.2 Sur les variables entières

L'addition, la soustraction et la multiplication restent valides. L'élévation en puissance n'est cohérente que si
la puissance est entière et positive (sinon le résultat n'est plus nécessairement entier). Quant à la division, elle
doit s'adapter au cas entier et nous disposons de deux opérateurs : div et mod qui donnent respectivement
le quotient et le reste de la division euclidienne.

Par exemple : (17 div 3) renvoie 5 et (17 mod 3) fournit 2.

2.2.3 Sur les chaînes de caractères

Une seule opération est possible sur les chaînes : la concaténation, qui consiste à les mettre bout à bout et
que nous symboliserons par +.
Par exemple après la séquence d'instructions (A et B étant des variables de type chaîne) :

...
A ← "Salut"
B ← A+"Tu vas bien ?"
...
la variable B contiendra : "SalutTu vas bien ?".

2.2.4 Sur les booléens

Nous retrouvons ici les opérateurs classiques (qui vont être) vus en logique : ET, OU et NON.

U22 - Algorithmique - Chapitre n°2 Page 8/40


2.3 Quelques fonctions utiles
2.3.1 Sur les nombres
En respectant bien les ensembles de dénition, on peut évidemment utiliser les fonctions mathématiques
usuelles (logarithme, exponentielle, racine carrée, partie entière, valeur absolue...).

Il sera aussi pratique d'utiliser les deux fonctions suivantes :

aléa() qui renvoie un nombre réel aléatoire de l'intervalle [0 ; 1[

arrondi(x,n) qui arrondit un réel x à un certain nombre n de décimales.

2.3.2 Sur les chaînes de caractères

Notons que le premier caractère d'une chaîne a pour rang 0.

Nous nous limiterons à quelques manipulations correspondant à des fonctions existant dans pratiquement
tous les langages de programmation :

long(ch) nombre de caractères de la chaine ch


long("et toi ?") vaut 8
majus(ch) , minus(ch) mise en majuscule ou minuscule de ch
majus("AsDePique") renvoie "ASDEPIQUE"
minus("AsDePique") renvoie "asdepique"
position(ch1 ,ch2 ,n) renvoie la position de la chaînech1 dans la chaîne ch2 à partir de la position n
renvoie −1 si la chaîne ch1 n'est pas trouvée
position("nj","Bonjour",0) renvoie 2
position("o","Bonjour",2) renvoie 4
extrait(ch,n,p) renvoie la sous-chaine de p caractères extraite de ch à partir du caractère de rang n
extrait("Bonjour",2,4) renvoie la chaîne "njou".
carASCII(n) renvoie le caractère dont le code ASCII est n
carASCII(97) renvoie "a"
codeASCII(caract) renvoie le code ASCII du caractère caract
codeASCII("a") renvoie 97.

2.3.3 Transtypage

L'instruction 123 + 456 renvoie 579 alors que "123"+"456" renvoie la chaîne "123456".
Il nous sera souvent utile de pouvoir convertir une chaîne en un nombre, ou réciproquement :

entier(ch) convertit la chaine ch en un nombre entier


entier("123") renvoie le nombre entier 123
entier("-12") renvoie le nombre entier -12
entier("12.3") renvoie une erreur
entier("25 km") renvoie une erreur
réel(ch) convertit la chaine ch en un nombre réel
réel("123") renvoie le nombre réel 123.0
réel("-12.3") renvoie le nombre réel -12.3
réel("salut") renvoie une erreur
réel("25,8") renvoie une erreur
chaine(x) convertit le nombre x (entier ou réel) en chaine
chaine(123) renvoie la chaine "123"
chaine(-12.3) renvoie la chaine "-12.3"

U22 - Algorithmique - Chapitre n°2 Page 9/40


U22 - Chapitre n° 3
Structures de contrôle

3.1 Traitement conditionnel


3.1.1 Traitement simple
Le traitement simple consiste à tester une condition et à réaliser une action (suite d'instructions) lorsque elle
est vraie. Sa structure est la suivante :

Si (condition) Alors
action si condition vraie . . .
Fin Si

La condition est une phrase logique ou une variable booléenne. Dans le cas où la condition n'est pas réalisée,
l'action est ignorée et on passe directement à l'instruction suivant le Fin Si.
Par exemple, la séquence suivante ache le plus grand nombre pair inférieur ou égal au nombre entier saisi :

...
A ← saisir("Tapez un entier positif : ")
B←A
Si ((A mod 2) = 1) Alors
acher("votre nombre est impair")
B←A1
Fin Si
acher("Le plus grand entier pair inférieur ou égal à votre nombre est : " , B)
...
Et, pour information, son implémentation en Python 3 est :

syntaxe python 3

...
A = int(input( "Tapez un entier positif : "))
B = A
if ((A % 2) == 1) :
print("votre nombre est impair")
B = A  1
# fin Si
print("Le plus grand entier pair inférieur ou égal à votre nombre est : " , B)
...

3.1.2 Traitement étendu

Le principe reste identique au traitement simple, mais on est dirigé vers une autre suite d'instructions lorsque
la condition n'est pas réalisée. La structure est la suivante :

Si (condition) Alors
action si condition vraie . . .
Sinon
action si condition fausse . . .
Fin Si

Notons que cette fois une des deux actions, et une seule, sera exécutée.

U22 - Algorithmique - Chapitre n°3 Page 10/40


Par exemple, voici une séquence comparant deux nombres saisis :

...
acher("Donnez-moi deux nombres réels : ")
A ← saisir("A = ")
B ← saisir("B = ")
Si (A=B) Alors
acher("Les deux nombres saisis sont égaux")
Sinon
acher("Les deux nombres saisis sont diérents")
Fin Si
...
Et son implémentation en Python 3 :

syntaxe python 3

...
print("Donnez-moi deux nombres réels : ")
A = float(input("A = "))
B = float(input("B = "))
if (A == B) :
print("Les deux nombres saisis sont égaux")
else :
print("Les deux nombres saisis sont différents")
# Fin Si
...

3.1.3 Imbrication

Les structures peuvent évidemment être imbriquées les unes dans les autres an de créer des sous-cas. Par
exemple la séquence suivante saisit l'âge de l'utilisateur (variable entière positive Age ) et suivant les cas
détermine s'il est en âge de voter ou de conduire (variables Voter booléenne et Conduire de type chaîne).
...
Age ← saisir("Quel est votre âge ? ")
Si (Age > 18) Alors
# il peut voter et conduire seul s'il a le permis
Voter ← Vrai
Conduire ← "possible seul"
Sinon
# il est mineur donc ne peut pas voter
Voter ← Faux
Si (Age > 16) Alors
# peut éventuellement être en conduite accompagnée
Conduire ← "possible accompagné"
Sinon
# moins de 16 ans, il ne peut pas conduire
Conduire ← "impossible"
Fin Si
Fin Si
...
On notera que l'indentation est fondamentale à la compréhension des imbrications !

U22 - Algorithmique - Chapitre n°3 Page 11/40


3.2 Les boucles
3.2.1 La boucle "Tant Que"

La structure est la suivante :

Tant que (condition)


action . . .
Fin Tant que

Lorsque l'instruction "Tant Que" est rencontrée, la condition est évaluée. Si elle est réalisée, on exécute
l'action spéciée et lorsque le "Fin Tant Que" est rencontré on revient au "Tant Que" et on recommence. Si
elle n'est pas réalisée, on ignore l'action et on passe directement à l'instruction suivant le "Fin Tant Que"
(sortie de boucle).

Voici par exemple une séquence qui ache l'alphabet en majuscule :

...
n ← 65
Tant que (n 6 90)
acher(carASCII(n))
n ← n+1
Fin Tant Que
...
et l'implémentation correspondante en Python 3 :

syntaxe python 3

...
n = 65
while (n <= 90) :
print(chr(n))
n = n+1
# Fin Tant Que
...

On notera l'importance de l'initialisation des variables utilisées dans la condition : si n était initialisé par 95,
les instructions situées dans la boucle ne seraient jamais exécutées. Par ailleurs, les variables utilisées dans
la condition doivent évoluer dans le contenu de la boucle . . . faute de quoi on ne pourrait plus en sortir une
fois rentré ! (enlevez le n←n+1 dans l'exemple précédent et vous verrez).

Et une mauvaise aectation peut avoir le même eet. Le seul moyen de ne pas tomber dans le piège des
boucles innies (ou jamais parcourues !) est de tester son algorithme à la main sur des cas simples . . . et là
les failles apparaissent. Essayez sur le morceau d'algorithme suivant :

...
n←5
Tant que n 6= 10
acher(n)
n ← n+2
Fin Tant Que
...
Vous remarquerez dans ce cas que le problème peut disparaitre de diérentes façons :
ˆ par exemple en remplaçant n ← n + 2 par n ← n + 1
ˆ ou bien en remplaçant n ← 5 par n ← 4
ˆ ou encore en remplaçant la condition n 6= 10 par n < 10

U22 - Algorithmique - Chapitre n°3 Page 12/40


3.2.2 La boucle "Pour"

Il s'agit d'une boucle "comptée" dans laquelle le programme s'occupe de tout : initialisation de la variable
de comptage, son évolution et la condition d'arrêt. Sa structure est la suivante :

Pour VariableComptage allant de ValeurDébut à ValeurFin


action . . .
VariableComptage suivant
instruction suivante

Lorsque l'instruction "Pour" est rencontrée la première fois, le protocole suivant s'enclenche :

1. aecter VariableComptage par ValeurDebut


2. tester la condition (VariableComptage 6 ValeurFin ) :
Si elle est vraie aller au point 3
Si elle est fausse aller au point 6

3. exécuter la séquence d'instructions de l'action

4. une fois en "V ariableComptage suivant", incrémenter V ariableComptage (augmenter de 1)


5. aller au point 2

6. continuer l'algorithme à l'instruction " instruction suivante "


On remarquera que cette boucle est équivalente à la structure "Tant Que" suivante :

VariableComptage ← ValeurDebut
Tant que (VariableComptage 6 ValeurFin)
action . . .
VariableComptage ← VariableComptage + 1
Fin Tant que
instruction suivante
Quatre points extrêmement importants sont à noter :

1. l'action n'est jamais jamais réalisée si V aleurDebut > V aleurF in


2. si V aleurDebut 6 V aleurF in,
l'action sera exécutée exactement (V aleurF in − V aleurDebut + 1) fois

3. dans l'action, le contenu de V ariableComptage ne doit en aucun cas être modié

4. à la sortie de la boucle "pour", V ariableComptage contient la valeur (V aleurF in + 1)


L'exemple du paragraphe précédent aurait pu aussi s'écrire comme ceci :

...
Pour n allant de 65 à 90
acher(carASCII(n))
n suivant
...
ce qui donnerait une fois implémenté :

syntaxe Python 3

...
for n in range(65,91) :
print(ch(n))
# n suivant
...

U22 - Algorithmique - Chapitre n°3 Page 13/40


3.2.3 Imbrication

Là encore, les structures peuvent être imbriquées les unes dans les autres. Par exemple, la séquence suivante
ache les tables de multiplications de 2 à 9 :

...
Pour i allant de 2 à 9
acher("Table des ",i," :")
Pour j allant de 1 à 10
acher(i , " fois " , j , ' = ' , i×j)
j suivant
i suivant
...
ce qui, une fois implémenté, donnera :

syntaxe python 3

...
for i in range(2,10) :
print("Table des ",i," : ")
for j in range(1,11) :
print(i , " fois " , j , ' = ' , i*j)
# j suivant
# i suivant
...

U22 - Algorithmique - Chapitre n°3 Page 14/40


U22 - Chapitre n° 4
Les tableaux

4.1 Deux exemples pour se faire une idée


4.1.1 Un exemple à une dimension
Variables :
i : entier
Nom_Jour : tableau de chaînes à 1 dimension [0 . . . 6]
Début
...
Nom_Jour[0] ← "lundi"
Nom_Jour[1] ← "mardi"
...
Nom_Jour[6] ← "dimanche"
...
i ← résultat d'un calcul ou d'une saisie
acher("ce jour là était un " , Nom_Jour[i])
...
Fin

4.1.2 Un exemple à deux dimensions

Un relevé de notes de 5 devoirs réalisés dans une classe de 31 étudiants est un tableau à deux dimensions :

ˆ l'indice de ligne correspondant à l'étudiant concerné


ˆ l'indice de colonne correspondant au devoir réalisé

La déclaration de ce tableau est : Notes : tableau d'entiers à deux dimensions [0 . . . 30][0 . . . 4]


Par exemple la note du 6e étudiant (par ordre alphabétique) au 3e devoir est stockée dans Notes[5][2].

4.2 La théorie
4.2.1 Des variables à tiroirs . . .

Un tableau est comparable à un ensemble de boîtes dans lesquelles on va stocker des informations.

Il est repéré par un nom qui obéit aux même règles que les noms de variable ( Nom_Jour dans l'exemple 1
et Notes dans l'exemple 2).

Il possède aussi un type qui dénit le type des données qui y vont être stockées (chaine de caractères dans
l'exemple 1 et entier dans l'exemple 2).

Un tableau est aussi caractérisé par une dimension :

ˆ Un tableau à une dimension est comparable à une suite de cases, chacune repérée par un indice
(voir exemple 1)
ˆ Un tableau à deux dimensions est comparable à un meuble à tiroirs, chacun repéré par un
indice de rangée (ou ligne) et un indice de colonne (voir exemple 2).

Chaque "case" ou "tiroir" s'appelle une cellule et les indices commencent à 0. Pour repérer une cellule précise
dans un tableau, on place son indice entre crochets derrière le nom du tableau.

Un tableau à 2 dimensions est en fait un tableau à 1 dimension (les lignes) dont les cellules sont des tableaux
à 1 dimension (les colonnes).

Dans l'exemple 2, on peut considérer le relevé de notes comme un tableau à 1 dimension et 31 cellules (les
étudiants), chaque cellule étant un tableau à 1 dimension et 5 cellules (les notes). Notes est un tableau à
deux dimensions et N otes[3] est un tableau à 1 dimension et 5 cellules : les notes du quatrième étudiant.

U22 - Algorithmique - Chapitre n°4 Page 15/40


4.2.2 Taille d'un tableau

La taille d'un tableau est son nombre de cellules quand il s'agit d'un tableau à 1 dimension, et son nombre
de lignes et de colonnes pour un tableau à 2 dimensions.

Lors de la déclaration du tableau, la taille sera précisée si elle est prévisible et gée.

La fonction long() qui a été dénie sur les chaines de caractères sera aussi utilisable pour les tableaux :

ˆ pour un tableau à 1 dimension, cette fonction renvoie le nombre de cellules


ˆ pour un tableau à 2 dimensions, cette fonction renvoie le nombre de lignes.

En reprenant les notations les exemples :

ˆ long(Nom_Jour) renvoie 7
ˆ long(Notes) renvoie 31
ˆ long(Notes[3]) renvoie 5

4.2.3 Affectation directe

Un tableau peut être initialisé par aectation directe et globale.

Dans l'exemple 1, les 7 lignes d'initialisation pouvaient être remplacées par une seule :

Nom_Jour ← ["lundi","mardi","mercredi","jeudi","vendredi","samedi","dimanche"]
De même pour un tableau à 2 dimensions. Si vous voulez par exemple que le tableau matrice contienne :

3 1 6 0
5 2 4 2

vous pouvez l'aecter de la façon suivante :

matrice ← [[3,1,6,0],[5,2,4,2]]
4.2.4 Extension d'un tableau

La taille d'un tableau n'est pas toujours prévisible dès le début d'un algorithme. On peut dans ce cas déclarer
un tableau qui sera initialisé vide . . . c'est à dire avec 0 cellule, et au gré des besoins on ajoute une nouvelle
cellule au tableau en y stockant une valeur. La taille du tableau évolue en conséquence.

On conviendra que la procédure étendre(N omT ableau,V aleur) ajoute une cellule au tableau N omT ableau
avec valeur comme contenu.

Par exemple, si le tableau d'entiers machin est aecté par [2,5,4], l'instruction ci-dessous augmentera sa taille
de 1 et il contiendra ensuite [2,5,4,8].
...
étendre(machin,8)
...
ce que je vous engage à tester en Python 3 avec les instructions suivantes :

éditeur python 3

>>> machin=[2,5,4]
>>> len(machin)
3
>>> machin.append(8)
>>> len(machin)
4
>>> machin
[2,5,4,8]

U22 - Algorithmique - Chapitre n°4 Page 16/40


4.3 Exemples rédigés
4.3.1 Test de lancer de dés : un tableau de taille fixée

L'algorithme qui suit a pour but de tester le générateur aléatoire. Il simule 600 lancers de dé et ache, pour
chaque face, le nombre de fois où elle a été obtenue en agrémentant cela d'un diagramme bâton horizontal.

ALGORITHME : Lancers de dé
ROLE : Simuler 600 lancers de dés et acher sous forme d'histogramme les résultats pour chaque face
ENTREES : 
SORTIE : L'eectif d'obtention de chaque face et une présentation en diagramme bâton horizontal
VARIABLES i , j , lancer : entiers
eectif [0 .. 5] : tableau d'entiers
DEBUT
eectif ← [0,0,0,0,0,0] # initialisation du tableau d'eectifs à 0
# ===== simulation des lancers
pour i allant de 0 à 599 # 600 lancers : boucle comptée de 600 tours
lancer ← PartieEntiere(6*alea()) # nombre entier aléatoire de 0 à 5
eectif[lancer] ← eectif[lancer]+1 # comptabiliser le résultat du lancer
i suivant
# ===== achage des résultats
acher("Face <tab> Eectif <tab> Diagramme") # titres
pour i allant de 0 à 5 # i varie de 0 à 5 ; face n(i+1)
acher(i+1,<tab>,eectif[i],<tab>,<rester sur la ligne>) # numéro de face et son eectif
pour j allant de 0 à eectif[i]  1 # acher autant . . .
acher("=",<rester sur la ligne>) # . . . de signes "=" que . . .
j suivant # . . . l'eectif de la face
acher() # va à la ligne
i suivant
FIN

ce que vous pouvez implémenter et sauvegarder sous le nom indiqué :

nom fichier : Cours_4_3_1.py

# ALGORITHME : Lancers de dé
# ROLE : Simuler 600 lancers de dés et
afficher sous forme d'histogramme les résultats pour chaque face
# ENTREES : -
# SORTIE : L'effectif d'obtention de chaque face et une présentation en diagramme bâton horizontal
# VARIABLES i , j , lancer : entiers
# effectif [0 .. 5] : tableau d'entiers
# importation des modules utiles
from math import *
from random import *
# DEBUT
effectif = [0,0,0,0,0,0] # initialisation du tableau d'effectifs à 0
# ===== simulation des lancers
for i in range(0,600) : # 600 lancers : boucle comptée de 600 tours
lancer = floor(6*random()) # nombre entier aléatoire de 0 à 5
effectif[lancer] = effectif[lancer]+1 # comptabiliser le résultat du lancer
# i suivant
# ===== affichage des résultats
print("Face","Effectif","Diagramme",sep="\t") # titres
for i in range(0,6) :
# i varie de 0 à 5; face n(i+1)
print(i+1,effectif[i],"",sep="\t",end="") # numéro de face et son effectif
for j in range(0,effectif[i]) : # afficher autant ...
print("=",end="") # ... de signes "=" que ...
# j suivant # ... l'effectif de la face
print() # va à la ligne
# i suivant
# FIN

U22 - Algorithmique - Chapitre n°4 Page 17/40


4.3.2 Analyse d'une série de notes : un tableau à taille variable

L'algorithme qui suit saisit un certain nombre de notes et les stocke dans un tableau. La n de la saisie est
détectée par l'entrée d'une valeur supérieure strictement à 20 ou strictement négative.

Une fois la série terminée, l'algorithme détermine (et ache) le nombre de notes, les notes extrêmes et la
moyenne arrondie à 1 décimale.

Je vous laisse le soin d'analyser le contenu de cet algorithme et de l'implémenter en Python 3 en le sauve-
gardant sous le nom Cours_4_3_2.py.

ALGORITHME : Série de notes


ROLE : Analyser une série de notes en calculant certaines caractéristiques
ENTREES : Une série de notes de 0 à 20
SORTIES : Le nombre de notes, la série de notes, les valeurs extrêmes et la moyenne (à 1 décimale)
VARIABLES :
i , nombre : entiers
note , maxi , mini , som : réels
notes[ ] : tableau de réels
ni : booléen
DEBUT
notes ← [ ] # initialisation du tableau de notes (vide)
# ===== saisie des notes
ni ← Faux # initialisation du détecteur de n de saisie
acher("l'entrée d'une valeur négative ou supérieure à 20 arrête la saisie")
tant que (non ni)
note ← saisie("valeur suivante : ") # saisie sous forme de nombre réel
ni ← ((note < 0) ou (note > 20)) # Vrai si note non valide
si (non ni) alors # note valide donc à prendre en compte
étendre(notes,note) # ajouter une cellule au tableau avec cette valeur
n si
n tant que
# ===== analyse de la série
nombre ← long(notes) # nombre de notes saisies
si (nombre > 0) alors # l'analyse n'est faite que si il y a des notes !
som ← notes[0] # initialisation somme
maxi ← notes[0] # initialisation valeur maximale
mini ← notes[0] # initialisation valeur minimale
pour i allant de 1 à (nombre  1) # parcours du reste du tableau
som ← som + notes[i] # calcul de la somme
si (notes[i] > maxi) alors
maxi ← notes[i] # nouveau maximum
sinon
si (notes[i] < mini) alors
mini ← notes[i] # nouveau minimum
n si
n si
i suivant
n si
# ===== achage des résultats
acher("nombre de notes : ",nombre)
si (nombre > 0) alors # l'achage n'a de sens que si il y a des notes !
acher("notes : ",notes)
acher("moyenne : ",arrondi(som/nombre,1))
acher("note maximale : ",maxi)
acher("note minimale : ",mini)
sinon
acher("il faudrait saisir au moins une note !")
n si
FIN

U22 - Algorithmique - Chapitre n°4 Page 18/40


4.3.3 Le triangle de Pascal : un tableau à deux dimensions

Le triangle de Pascal est un tableau de nombres permettant d'écrire le développement de (a + b)n . Il sera
approfondi en cours de dénombrement et seule sa construction nous intéresse ici.

En voici les premières lignes (complétées par des 0 pour en faire un tableau rectangulaire) :

1 0 0 0 0 0 0
1 1 0 0 0 0 0
1 2 1 0 0 0 0
1 3 3 1 0 0 0
1 4 6 4 1 0 0
1 5 10 10 5 1 0
1 6 15 20 15 6 1

On remarquera plusieurs choses :

ˆ si on veut écrire les n premières lignes du triangle, il faudra n colonnes


ˆ la première colonne ne contient que des "1"
ˆ seul le triangle inférieur gauche est non nul (d'où le nom de la chose)
ˆ chaque ligne s'obtient à partir de la précédente en additionnant deux cellules voisines et en
plaçant le résultat sous celle de droite.

L'algorithme suivant saisit le nombre de lignes désiré et les achent. Faites-en un tracé pas à pas pour la
valeur n = 4 an de bien comprendre son fonctionnement. Il est également conseillé de l'implémenter en
Python 3 et de le sauvegarder sous le nom Cours_4_3_3.py.

ALGORITHME : triangle de Pascal


ROLE : calculer et acher un certain nombre de lignes du triangle de Pascal
ENTREES : le nombre de lignes désiré
SORTIES : acher les lignes demandées
VARIABLES :
i,j,n : entiers
pascal[ ][ ] : tableau d'entiers
DEBUT
# ===== initialisations
n ← saisie("Nombre de lignes à acher : ") # combien de lignes à calculer ?
pascal ← tableau n lignes , n colonnes de 0 # initialisation du tableau avec des 0 (voir note a )
pour i allant de 0 à (n  1) # mettre la première colonne à 1
pascal[i][0] ← 1
i suivant
# ===== calcul des coecients
pour i allant de 1 à (n  1) # on va calculer la ligne i
pour j allant de 1 à i # seulement les cellules à gauche de la diagonale
# somme des deux cellules de la ligne précédente (même colonne et colonne précédente)
pascal[i][j] ← pascal[i  1][j] + pascal[i  1][j  1]
j suivant
i suivant
# ===== achage des résultats
pour i allant de 0 à (n  1) # on va acher la ligne i
pour j allant de 0 à i # seulement les cellules à gauche de la diagonale
acher(pascal[i][j],<rester sur la ligne>)
j suivant
acher() # aller à la ligne
i suivant
FIN
a. en python, cette ligne se code : pascal=[[0 for j in range(0,n)] for i in range(0,n)]

U22 - Algorithmique - Chapitre n°4 Page 19/40


U22 - Chapitre n° 5
Procédures et Fonctions

5.1 La sous-traitance
5.1.1 Pourquoi ?
Le concept de langage procédural, consistant à dénir des sous-algorithmes qui peuvent être appelés de façon
indépendante, présente trois avantages non négligeables :

ˆ décomposer une tâche complexe en tâches plus simples traitées indépendamment


ˆ éviter la répétition d'une portion d'algorithme qui doit être exécutée plusieurs fois
ˆ permet la réutilisation d'une tâche routinière dans d'autres algorithmes (copier/coller d'un sous-algorithme)

5.1.2 La division des tâches

Le premier point est la clé de l'analyse dite descendante d'un problème. La tâche globale est subdivisée
en sous-problèmes conés à des équipes diérentes qui peuvent à leur tour, si elles en éprouvent le besoin,
les subdiviser à nouveau. Cette structure emboîtée en  poupées russes  doit évidemment s'assurer que
l'assemblage nal des  briques  conçues par les diérentes équipes et sous-équipes conduit de façon cohé-
rente au résultat attendu. Chaque sous-algorithme doit donc obéir à un cahier des charges précis édicté par
l'algorithme qui fait appel à lui.

sous probleme 1-a


%
sous probleme 1
% &
problème général sous problème 1-b
&
sous problème 2

Cette structure se concrétisera en algorithme de la façon suivante :

sous-algorithme sous_probleme_1_a()
( . . .)
n sous-algorithme
sous-algorithme sous_probleme_1_b()
( . . .)
n sous-algorithme
sous-algorithme sous_probleme_1()
appeler sous_probleme_1_a()
appeler sous_probleme_1_b()
n sous-algorithme
sous-algorithme sous_probleme_2()
( . . .)
n sous-algorithme
algorithme probleme_general
( . . .)
DEBUT
( . . .)
appeler sous_probleme_1()
appeler sous_probleme_2()
( . . .)
FIN
U22 - Algorithmique - Chapitre n°5 Page 20/40
5.1.3 Éviter la répétition

Le deuxième point est dicté par un souci d'optimisation et permet d'éviter la répétition de séquences d'ins-
tructions identiques ou similaires. Il n'est pas rare, dans la résolution d'un problème, d'avoir à faire appel
plusieurs fois à une même tâche. Dans ce cas, un sous-algorithme exécutant cette tâche sera déni et appelé
plusieurs fois. D'un point de vue structure algorithmique, cela ressemble à cela :

sous-algorithme tache_a_repeter()
( . . .)
n sous-algorithme
algorithme probleme_general
( . . .)
DEBUT
( . . .)
appeler tache_a_repeter()
( . . .)
appeler tache_a_repeter()
( . . .)
appeler tache_a_repeter()
( . . .)
FIN

5.1.4 Fonctionnement général

Il est clair que les sous-algorithmes doivent être dénis avant qu'un appel ne leur soit destiné. Par exemple
dans le premier encadré, déclarer sous_probleme_1 avant de déclarer sous_probleme_1_a engendrerait une
erreur. Comme dans un roman, il faut que les personnages soient présentés avant de les faire intervenir.

Par ailleurs, lors de l'appel d'un sous-algorithme, tout se passe comme si les instructions du sous-algorithme
étaient insérées à l'endroit de l'appel. Il est clair qu'au retour de l'appel, la machine reprend son histoire à
l'instruction qui suit l'appel.

Par exemple, dans la structure suivante :

1 sous-algorithme truc()
( . . .)
n sous-algorithme 2
3 sous-algorithme machin()
( . . .)
n sous-algorithme 4
5 algorithme probleme_general
( . . .)
DEBUT
( . . .)
appeler machin() 6 7
( . . .)
appeler truc() 8 9
( . . .)
appeler machin() 10 11
( . . .)
FIN 12

le cheminement suivi est : 5 → 6 → 3 → 4 → 7 → 8 → 1 → 2 → 9 → 10 → 3 → 4 → 11 → 12

U22 - Algorithmique - Chapitre n°5 Page 21/40


5.1.5 Syntaxe

Les noms donnés aux sous-algorithmes répondent aux mêmes exigences que les noms de variables : caractères
alphanumériques non accentués et trait de soulignement, le premier caractère étant obligatoirement une lettre.

Le nom doit se terminer par un couple de parenthèses (éventuellement vide) dont nous verrons l'utilité plus
loin.

5.2 Deux espèces de sous-algorithme


5.2.1 La procédure
La procédure est un sous-algorithme qui réalise une action. On l'appelle en écrivant tout simplement son
nom.

Voici un exemple de procédure qui envoie à l'écran un message d'erreur séparé par des lignes vides lorsqu'elle
est invoquée :

PROCÉDURE erreur()
passer une ligne
acher("Erreur fatale rencontrée")
passer une ligne
FIN PROCÉDURE
ALGORITHME principal
( . . .)
DEBUT
( . . .)
Si (condition_1) Alors
erreur()
Sinon
Si (condition_2) Alors
(. . .traitement du problème . . .)
Sinon
erreur()
Fin Si
Fin si
(. . .)
FIN

Cet algorithme appellera la procédure et achera le message d'erreur lorsque condition_1 sera remplie et,
quand elle ne l'est pas, si condition_2 ne l'est pas non plus.

5.2.2 La fonction

La fonction est un sous-algorithme qui renvoie une valeur. La dernière instruction d'une fonction sera le
renvoi de la valeur en question.

Contrairement à la procédure, elle n'est pas en elle-même une instruction mais doit intervenir, comme une
variable, dans une instruction de l'algorithme qui l'invoque.

Prenons par exemple un algorithme qui a régulièrement besoin d'une valeur de π à 5 décimales. Plutôt que
de taper à chaque fois cette valeur, on peut créer une fonction dont le nom est plus court à écrire :

U22 - Algorithmique - Chapitre n°5 Page 22/40


FONCTION pi_()
renvoyer 3,14159
FIN FONCTION
ALGORITHME principal
( . . .)
DEBUT
acher("une valeur arrondie de PI est : " , pi_())
R←5
acher("le périmètre du cercle de rayon " , R , " vaut " , 2×pi_()×R)
acher("et son aire vaut " , pi_()×R2 )
FIN

Un autre intérêt dans cette façon de procéder est que si par la suite on a besoin de résultats plus précis, il
sut d'augmenter le nombre de décimales à un seul endroit : dans le corps de la fonction.

5.2.3 Des sous-algorithmes adaptables

Il est clair que les deux exemples donnés ci-dessus sont quelque peu gés et il serait bon de leur donner un
peu de souplesse.

Prenons l'exemple de la procédure achant un message d'erreur. Elle pourrait être modiée de la façon
suivante :

PROCÉDURE erreur(message)
ARGUMENT message : chaîne de caractères
RÔLE acher un message d'erreur
passer une ligne
acher("Erreur fatale rencontrée : " , message)
passer une ligne
FIN PROCÉDURE
ALGORITHME principal
( . . .)
DEBUT
( . . .)
Si (condition_1) Alors
erreur("division par zéro")
Sinon
Si (condition_2) Alors
(. . .traitement du problème . . .)
Sinon
erreur("racine d'un nombre négatif")
Fin Si
Fin si
(. . .)
FIN

Au moment de l'appel, la valeur mise entre parenthèses est transférée dans la variable message servant
d'argument à la procédure.

Lorsque la condition_1 est remplie, on va voir s'acher Erreur fatale rencontrée : division par zéro,
et lorsque aucune condition n'est remplie, on verra Erreur fatale rencontrée : racine d'un nombre négatif.
De même, l'exemple de fonction donné précédemment serait également plus souple si le nombre de décimales
de l'arrondi n'était pas prédéterminé :

U22 - Algorithmique - Chapitre n°5 Page 23/40


FONCTION pi_(n)
ARGUMENT n : entier
TYPE RETOURNE réel
RÔLE : retourner une valeur de π arrondie à n décimales (n 6 11)
VARIABLE LOCALE pi_11 : réel
pi_11 ← 3,14159265359
renvoyer arrondi(pi_11 à n décimales)
FIN FONCTION
ALGORITHME principal
DEBUT
acher("une valeur arrondie de PI à 5 décimales est : " , pi_(5))
R←5
acher("le périmètre du cercle de rayon " , R , " vaut " , 2×pi_(3)×R)
acher("et son aire vaut " , pi_(6)×R2 )
FIN
Dans ce cas, le calcul de périmètre se fera avec une précision de 3 décimales et celui de l'aire avec 6 décimales.

5.2.4 Conventions d'écriture

Un sous-algorithme étant en lui même un algorithme, sa rédaction répond aux même règles et doit comporter
les commentaires et déclarations usuels (rôle, variables locales, . . .). Il faut y ajouter les types des arguments
passés et, dans le cas d'une fonction, le type de la valeur retournée (qui peut aussi être un tableau).

5.3 Fonctions et procédures avec arguments


5.3.1 Le passage d'arguments
Nous avons vu dans les deux derniers exemples l'intérêt d'avoir une procédure ou une fonction pouvant
s'adapter à un contexte particulier. Cela se fait en transmettant des paramètres dont le sous-algorithme va
pouvoir se servir pour opérer son traitement.

Les arguments passés gurent entre parenthèses dans la déclaration du sous-algorithme. Ils peuvent être
de types diérents et sont représentés par des noms de variable qui seront utilisé dans le corps du sous-
algorithme. Dans le cas de plusieurs arguments, les variables sont séparées par des virgules et l'ordre dans
lequel ils sont déclarés est extrêmement important.

Prenons par exemple la déclaration commençant de la façon suivante :

PROCEDURE bidule(n , p , test , message)


ARGUMENTS n , p : entiers
test : booléen
message : chaîne de caractères
Les appels de cette procédure ne seront valables que si 4 valeurs sont transmises : deux entiers, un booléen
et une chaîne de caractères, dans cet ordre. Avant de commencer à travailler, la procédure va aecter les
variables n, p, test et message par les 4 valeurs respectives transmises.

Par exemple l'appel bidule(3,5,Vrai,"bonjour") est correct, de même que bidule(5,3,Vrai,"bonjour") . . . qui
donnera probablement un résultat diérent du précédent (dans le premier cas n ← 3 et p ← 5 alors que dans
le second cas n←5 et p ← 3).
Par contre les appels bidule(3.2,5,Vrai,"bonjour") , bidule(3,5,"Vrai","bonjour") , bidule("3",5,Vrai,"bonjour")
ou bidule(3,5,Vrai,7) ne sont pas cohérents et engendrent une erreur.

On peut également transmettre une valeur à un sous-algorithme grâce à une variable dont le type est cohérent
avec l'argument correspondant.

Par exemple dans la procédure précédente, l'appel bidule(Nombre_Cas,5,Fini,"salutation") est correct si


Nombre_Cas est une variable entière et Fini une variable de type booléen. Dans ce cas, la procédure va
commencer par transférer les contenus des variables Nombre_Cas et Fini dans les variables n et test.
U22 - Algorithmique - Chapitre n°5 Page 24/40
5.3.2 Un exemple de procédure avec deux arguments

Je vous laisse analyser et vérier les achages de la procédure et du programme principal suivant :

PROCEDURE repetition(n , texte)


ARGUMENTS n : entier
texte : chaîne de caractères
ROLE ache n fois la chaîne texte en séparant par un espace
VARIABLE i : entier
Pour i allant de 1 à n
acher(texte," ") en restant sur la même ligne
i suivant
aller à la ligne
FIN PROCEDURE

ALGORITHME principal
ROLE tester la procédure repetition
ENTREES aucune
SORTIES achage de diérents appels par la procédure
VARIABLES Nbre : entier
Interjection : chaine de caractères
DEBUT
repetition(4,"Ha") # ache à l'écran : Ha Ha Ha Ha
Nbre ← 3
repetition(Nbre,"Oui") # ache à l'écran : Oui Oui Oui
Interjection ← "Ho"
repetition(Nbre+2, Interjection) # ache à l'écran : Ho Ho Ho Ho Ho
repetition(Nbre-2, "Interjection") # ache à l'écran : Interjection
FIN
puis l'implémenter en Python 3 :

nom de fichier : Cours_5_3_2.py

def repetition(n , texte):


# TYPE procédure
# ARGUMENTS n : entier
# texte : chaîne de caractères
# ROLE affiche n fois la chaîne texte en séparant par un espace
# VARIABLE i : entier
for i in range(n):
print(texte,end=" ")
# i suivant
print()
# FIN PROCEDURE

# ALGORITHME principal
# ROLE tester la procédure repetition
# ENTREES aucune
# SORTIES affichage de différents appels par la procédure
# VARIABLES Nbre : entier
# Interjection : chaine de caractères
# DEBUT
repetition(4,"Ha") # affiche à l'écran : Ha Ha Ha Ha
Nbre = 3
repetition(Nbre,"Oui") # affiche à l'écran : Oui Oui Oui
Interjection = "Ho"
repetition(Nbre+2, Interjection) # affiche à l'écran : Ho Ho Ho Ho Ho
repetition(Nbre-2, "Interjection") # affiche à l'écran : Interjection
# FIN

U22 - Algorithmique - Chapitre n°5 Page 25/40


5.3.3 Un classique : la fonction factorielle

Le factoriel d'un entier n, noté n!, est le produit de tous les entiers de 1 à n. Par exemple 3! = 1 × 2 × 3 = 6
et 6! = 720. Voici un exemple d'écriture de cette fonction :

FONCTION factoriel(n)
ARGUMENT n : entier
TYPE RENVOYE entier
ROLE renvoie le produit de tous les entiers de 1 à n
VARIABLES i , resultat : entiers
resultat ← 1
Pour i allant de 1 à n
resultat ← resultat × i
i suivant
renvoyer resultat
FIN FONCTION
Notons que ce n'est pas la variable resultat qui est retournée, mais son contenu (une valeur numérique). Je
vous laisse le soin de vérier les achages de ce programme test utilisant la fonction factoriel :

ALGORITHME principal
ROLE tester la fonction factoriel
ENTREES aucune
SORTIES achage de diérents retours de la fonction
VARIABLES Nbre1 , Nbre2 : entiers
DEBUT
acher(factoriel(4)) # ache à l'écran : 24
Nbre1 ← 5
Nbre2 ← 2× factoriel(Nbre1  2)  1 # Nbre2 est aecté par la valeur 11
acher(factoriel(Nbre1)) # ache à l'écran : 120
acher(factoriel((3 × Nbre2) mod Nbre1)) # ache à l'écran : 6
acher(factoriel(Nbre2) div factoriel(Nbre1)) # ache à l'écran : 332640
FIN
puis de tester le tout en Python 3 :

nom de fichier : Cours_5_3_3.py

def factoriel(n):
# TYPE fonction
# ARGUMENTS n : entier
# TYPE RENVOYE entier
# ROLE renvoie le produit de tous les entiers de 1 à n
# VARIABLES i , resultat : entiers
resultat = 1
for i in range(1,n+1):
resultat = resultat * i
# i suivant
return resultat
# FIN FONCTION

# ALGORITHME principal
# ROLE tester la fonction factoriel
# ENTREES aucune
# SORTIES affichage de différents retours de la fonction
# VARIABLES Nbre1 , Nbre2 : entiers
# DEBUT
print(factoriel(4)) # affiche à l'écran : 24
Nbre1 = 5
Nbre2 = 2*factoriel(Nbre1  2)  1 # Nbre2 est affecté par la valeur 11
print(factoriel(Nbre1)) # affiche à l'écran : 120
print(factoriel((3*Nbre2) % Nbre1)) # affiche à l'écran : 6
print(factoriel(Nbre2) // factoriel(Nbre1)) # affiche à l'écran : 332640
# FIN

U22 - Algorithmique - Chapitre n°5 Page 26/40


5.4 La portée des variables
5.4.1 Quel est le problème ?
Le concept de sous-algorithme est induit par la notion de travail en équipe. Un gros projet est géré par un
chef d'équipe qui va le décomposer en sous-projets, chacun avec un cahier des charges précis, et le coner
à des groupes distincts. Le chef de projet réalise l'algorithme principal qui fera appel aux sous-algorithmes
fournis par les diérents groupes. Chaque chef de groupe peut réitérer ce processus de division du travail
à l'intérieur de son groupe s'il en éprouve le besoin. Chaque groupe ou sous-groupe va ensuite travailler de
façon indépendante et, une fois les diérents modules réalisés, ils seront insérés dans le projet nal comme
des briques de construction . . . et cela doit fonctionner !

Comme elles ne communiquent pas ensemble durant la mise au point des sous-projets, il est tout à fait
possible que plusieurs équipes diérentes utilisent au sein de leur sous-algorithme des variables portant le
même nom (par exemple un compteur i). Il est clair que ces variables homonymes ne doivent pas interférer
une fois les sous-algorithmes aboutés dans le projet nal.

De même, il est tout à fait possible que le chef de projet manipule dans son algorithme principal des variables
contenant des données générales importantes pour le bon fonctionnement de l'ensemble. Il serait mal venu
que les sous-algorithmes modient les contenus de ces variables . . . même si, par le plus grand des hasards,
ils manipulent des variables de même nom.

Ce qui suit n'est pas simple, c'est même assez subtil . . . mais cela joue un rôle fondamental en programmation
et demande à être bien compris !

5.4.2 Variables globales et locales

Prenons déjà le cas simple d'un algorithme principal appelant un sous-algorithme :

Les variables déclarées et aectées dans l'algorithme principal sont des variables globales.
Les variables déclarées et aectées dans le sous-algorithme sont des variables locales à ce sous-algorithme.

Les arguments passés au sous-algorithme sont des variables locales et leur aectation se fait automatiquement
lors de l'appel du sous-algorithme.

Par exemple dans la structure suivante :

PROCEDURE alphonse(n , texte)


ARGUMENTS n : entier
texte : chaîne de caractères
ROLE ...
VARIABLE i : entier
(. . .)
i←7
(. . .)
FIN PROCEDURE

ALGORITHME principal
ROLE ...
VARIABLES Nb : entier
message : chaine de caractères
DEBUT
Nb ← 3
message ← "truc"
alphonse(Nb,message)
FIN

les variables Nb et message sont des variables globales et les variables n , texte et i sont des variables locales.
A l'appel de la procédure, n et texte sont initialisées par aectation des valeurs respectives 3 et "truc" et i
est ensuite initialisé par la valeur 7.

U22 - Algorithmique - Chapitre n°5 Page 27/40


Dans le cas d'un appel en cascade, le schéma se répercute à chaque niveau : si l'algorithme Albert appelle
le sous-algorithme Bernard qui, lui-même, appelle le sous-algorithme Chloé, il faut avoir conscience que les
variables propres à Bernard sont locales pour Albert, mais globales pour Chloé. Par contre les variables de
Albert sont globales pour les deux sous-algorithmes.

5.4.3 Visibilité des variables

A chaque étape du déroulement d'un algorithme, les variables globales sont  visibles  et leurs contenus
peuvent être utilisés par les sous-algorithmes appelés alors que les variables locales ne sont  visibles  que
dans le sous-algorithme où elles sont dénies. Mais bien qu'il puisse  voir  une variable qui lui est globale,
un sous-algorithme ne peut pas en modier la valeur.

Des exemples s'imposent !

Vériez attentivement le bien-fondé des commentaires . . . et l'achage obtenu dans l'exemple suivant :

PROCEDURE Esclave(n)
ARGUMENTS n : entier # n est une variable locale aectée lors de l'appel
VARIABLE i : entier # i est une variable locale qui doit être aectée dans la procédure
i←7 # aectation de la variable locale i
acher("i=",i ," n=",n) # ache des contenus locaux
n←i+n # aectation d'une variable locale par des valeurs locales
i ← Nb + n # aectation d'une variable locale en utilisant la variable globale Nb
acher("i=",i ," n=",n) # ache des contenus locaux
acher("Nb=",Nb) # ache un contenu global
FIN PROCEDURE # n d'existence des variables i et n
ALGORITHME Maitre
VARIABLES Nb : entier
DEBUT
Nb ← 3 # la variable globale Nb contient 3
Esclave(Nb) # appel de la procédure avec transfert du contenu de Nb dans n
acher("Nb=",Nb) # la variable Nb n'a pas été aectée par la procédure
Nb ← Nb + 5 # la variable globale Nb vaut maintenant 8
Esclave(Nb+4) # appel de procédure avec transfert de 12 dans l'argument n
acher("Nb=",Nb) # la variable Nb n'a pas été aectée par la procédure
FIN

Achage obtenu : i=7 n=3 / i=13 n=10 / Nb=3 / Nb=3 / i=7 n=12 / i=27 n=19 / Nb=8 / Nb=8

Mais attention ! L'encadré suivant comporte moult erreurs à bien comprendre :

PROCEDURE Esclave(n)
ARGUMENTS n : entier # n est une variable locale aectée lors de l'appel
VARIABLE i : entier # i est une variable locale qui doit être aectée dans la procédure
i ← n + Nb # pas de problème : on peut aecter une locale en utilisant une globale
Nb ← n + i # ERREUR : la procédure n'est pas autorisée à modier une variable globale
FIN PROCEDURE # les variables i et n n'existent plus à partir de là
ALGORITHME Maitre
VARIABLES Nb : entier
DEBUT
Nb ← 3 # la variable globale Nb contient 3
Esclave(Nb) # appel de la procédure avec transfert du contenu de Nb dans n
Nb ← 3 × n # ERREUR : variable locale n invisible d'ici
ache(i) # ERREUR : variable locale i invisible d'ici
FIN
Cela étant vu, que se passe-t-il lorsque des variables globales et locales portent le même nom ?

U22 - Algorithmique - Chapitre n°5 Page 28/40


5.4.4 Le comportement des homonymies

Lorsqu'un sous-algorithme rencontre une variable locale portant le même nom qu'une variable globale, il met
le contenu de la variable globale de côté an de pouvoir le restituer en sortant.

L'exemple suivant illustre la chose :

PROCEDURE Esclave(x)
ARGUMENTS x : entier # x est une variable locale aectée lors de l'appel
VARIABLE y : entier # y est une variable locale qui doit être aectée dans la procédure
y←2 # aectation de la variable locale y
x ← x+10 # modication de la variable locale x
acher("dans la procédure : x=",x ," y=",y)
FIN PROCEDURE # restitue les valeurs initiales des variables globales x et y
ALGORITHME Maitre
VARIABLES x , y : entiers # ces variables sont globales
DEBUT
x←3 # la variable globale x contient 3
y←5 # la variable globale y contient 5
acher("dans l'algorithme principal avant l'appel de procédure : x=",x," y=",y)
Esclave(x) # appel de la procédure avec transfert du contenu de x(global) dans x(local)
acher("en premier retour de procédure : x=",x," y=",y)
x ← x+y # ce sont ici les variables globales qui sont en jeu
Esclave(x+1) # appel de procédure avec transfert de 9 dans l'argument x(local)
ache ("en second retour de procédure : x=",x," y=",y)
FIN
et va provoquer l'achage suivant (à vérier) :

dans l'algorithme principal avant l'appel de procédure : x=3 y=5


dans la procédure : x=13 y=2
en premier retour de procédure : x=3 y=5
dans la procédure : x=19 y=2
en second retour de procédure : x=8 y=5

Pour le  fun  je vous laisse le soin de vérier que l'appel en cascade suivant :

FONCTION Esclave()
VARIABLE x : entier # x est une variable locale qui doit être aectée dans la procédure
x←2 # aectation de la variable locale x
renvoyer x # retourne le contenu de la variable locale x
FIN FONCTION # restitue la valeur de x initiale à celui qui a appelé
PROCEDURE Disciple()
VARIABLE x : entier # x est une variable locale qui doit être aectée dans la procédure
x←3 # aectation de la variable locale x
acher(x) # acher le contenu de la variable locale x (globale pour Esclave)
acher(Esclave()) # ache ce que renvoie la fonction Esclave
acher(x) # acher le contenu de la variable locale x
FIN PROCEDURE # restitue la valeur de x initiale à celui qui a appelé
ALGORITHME Maitre
VARIABLES x : entiers # cette variable est globale
DEBUT
x←1 # aectation de la variable globale x
acher(x) # acher le contenu de la variable globale x
acher(Esclave()) # ache ce que renvoie la fonction Esclave
acher(x) # acher le contenu de la variable globale x
Disciple # appelle la procédure disciple
acher(x) # ache le contenu de la variable globale x
FIN
ache (sur plusieurs lignes) : 1 / 2 / 1 / 3 / 2 / 3 / 1

U22 - Algorithmique - Chapitre n°5 Page 29/40


U22 - Chapitre n° 6
La récursivité

6.1 La magie de l'auto-référence


6.1.1 Un petit exemple ?
Plaçons-nous dans le cadre de l'organigramme hiérarchique d'une entreprise et considérons la dénition
suivante de "supérieur" d'un individu :

supérieur : chef du service ou supérieur du chef de service

Au premier abord, cette dénition semble totalement stupide puisque le mot à dénir est utilisé dans sa
propre dénition. Cela nous procure le sentiment de vouloir soulever la chaise sur laquelle nous sommes
assis !

Procédons à une analyse plus approfondie de la chose . . .

6.1.2 Une fonction auto-référentielle

Le but est de dénir, au regard de l'organigramme, si dans l'entreprise une personne A est un supérieur d'un
individu B. La dénition donnée ci-dessus correspond à la fonction booléenne suivante :

FONCTION supérieur(A,B)
VARIABLE LOCALE test : booléen
si B est au sommet de l'organigramme alors
test ← faux # point 1
sinon
si A est le chef de service de B alors
test ← vrai # point 2
sinon
test ← supérieur(A,chef de service de B) # point 3
n si
n si
retourner test # point 4
FIN FONCTION

6.1.3 Comment ça marche ?

Prenons comme base l'organigramme hiérarchique suivant :

Astride

Boris Chakira

David Erwan Farid Grichka Honoré

Igor Julieta Kasumi Liliane Manuelo

Traçons deux appels de la fonction superieur en repérant les individus par leur initiale.

U22 - Algorithmique - Chapitre n°6 Page 30/40


1er cas : Si on appelle la fonction superieur(A, K) (appel 0)
ˆ création d'une première variable locale test du niveau 0
ˆ comme K possède un chef de service et que ce n'est pasA, on va au point 3
ˆ pour aecter test superieur(A, G) (appel 1)
on appelle la fonction
ˆ création d'une deuxième variable locale test au niveau 1
ˆ comme G possède un chef de service et que ce n'est pas A, on va au point 3
ˆ pour aecter test on appelle la fonction superieur(A, C) (appel 2)
ˆ création d'une troisième variable locale test au niveau 2
ˆ comme C possède un chef de service et que c'est A, on va au point 2
ˆ test est donc aecter par Vrai et on va au point 4
ˆ l'appel 2 de la fonction retourne donc la valeur Vrai à l'appel 1
ˆ l'appel 1 aecte test du niveau 1 par Vrai en son point 3 et va au point 4
ˆ l'appel 1 de la fonction retourne donc la valeur Vrai à l'appel 0
ˆ l'appel 0 aecte test de niveau 0 par Vrai en son point 3 et va au point 4
ˆ l'appel de la fonction superieur(A, K) nous renvoie la valeur Vrai

2e cas : Si on appelle la fonction superieur(G, J) (appel 0)


ˆ création d'une première variable locale test du niveau 0
ˆ comme J possède un chef de service et que ce n'est pas G, on va au point 3
ˆ pour aecter test on appelle la fonction superieur(G, D) (appel 1)
ˆ création d'une deuxième variable locale test au niveau 1
ˆ comme D possède un chef de service et que ce n'est pas G, on va au point 3
ˆ pour aecter test on appelle la fonction superieur(G, B) (appel 2)
ˆ création d'une troisième variable locale test au niveau 2
ˆ comme B possède un chef de service et que ce n'est pas G, on va au point 3
ˆ pour aecter test on appelle la fonction superieur(G, A) (appel 3)
ˆ création d'une quatrième variable locale test au niveau 3
ˆ comme A ne possède pas de chef de service on va au point 1
ˆ test est donc aectée par Faux et on va au point 4
ˆ l'appel 3 de la fonction retourne donc la valeur Faux à l'appel 2
ˆ l'appel 2 aecte test de niveau 2 par Faux et on va au point 4
ˆ l'appel 2 de la fonction retourne donc la valeur Faux à l'appel 1
ˆ l'appel 1 aecte test du niveau 1 par Faux en son point 3 et va au point 4
ˆ l'appel 1 de la fonction retourne donc la valeur Faux à l'appel 0
ˆ l'appel 0 aecte test de niveau 0 par Faux en son point 3 et va au point 4
ˆ l'appel de la fonction superieur(A, K) nous renvoie la valeur Faux

Au travers de cette exemple, on comprend la philosophie de la chose : la fonction s'appelle elle-même avec
des paramètres à chaque fois diérents, jusqu'à ce qu'une condition d'arrêt permette de calculer un vrai
résultat et stoppe cette mise en abîme.

6.2 La solution est en vous . . .


6.2.1 Définition de la récursivité
Une fonction ou procédure est dite récursive lorsqu'elle possède, dans le corps de sa dénition, au moins un
appel à elle-même.

6.2.2 Je vous demande de vous arrêter !

Il est évident que si vous expliquez à quelqu'un que pour additionner 7 et 5, il sut d'additionner 7 et 5 . . .
vous n'apportez aucun élément pour aboutir au résultat ! L'appel récursif tourne ici en boucle innie.

Pour qu'une dénition récursive se termine en un temps ni, il faut que chaque nouvel appel se fasse en
transmettant des paramètres diérents, diminuant la diculté du problème, pour cheminer vers un cas où le
résultat sera calculé sans avoir recours à un nouvel appel.

U22 - Algorithmique - Chapitre n°6 Page 31/40


6.2.3 Fonctionne avec pile

Nous avons vu dans le premier exemple qu'un même nom de variable va être utilisé moult fois. Il est donc
nécessaire, lors d'un nouvel appel, de laisser au vestiaire les contenus des variables juste avant l'appel an
de les récupérer lors du retour de l'appel. Ce problème a déjà été évoqué et détaillé à la n du chapitre
précédent.

Pour réaliser ce prodige sans s'emmêler les pinceaux, on utilise une zone mémoire de stockage, appelé pile
LIFO (Last In First Out), qui fonctionne comme un empilement d'assiettes : la dernière posée sur la pile
sera la première à resservir quand on dépilera.

Le fonctionnement de cette pile est détaillé dans l'exemple qui suit (la dernière valeur entrée est à gauche).

6.2.4 La fonction factorielle, le retour !

Dans le chapitre précédent, nous avons déjà déni cette fonction. Nous allons le refaire, cette fois de façon
récursive :

FONCTION Factoriel(n)
Argument n : entier
Type retourné : entier
Rôle : calculer le produit des entiers de 1 à n
si (n=1) alors
retourner 1
sinon
retourner Factoriel(n1) × n
n si
FIN FONCTION

Étonnant de simplicité, n'est-il pas ? Traçons précisément l'appel F actoriel(4) (qui renvoie 24) :

ˆ met 4 sans n
ˆ va dans le "sinon" du 1er appel et doit appeler F actoriel(3)
ˆ met sur la pile l'ancienne valeur de n (la pile contient [4]) et met 3 dans n
ˆ va dans le "sinon" du 2e appel et doit appeler F actoriel(2)
ˆ met sur la pile l'ancienne valeur de n (la pile contient [3 ; 4]) et met 2 dans n
ˆ va dans le "sinon" du 3e appel et doit appeler F actoriel(1)
ˆ met sur la pile l'ancienne valeur de n (la pile contient [2 ; 3 ; 4]) et met 1 dans n
ˆ la condition est remplie au 4e appel : renvoie la valeur 1
ˆ quitte le 4e appel et dépile la valeur de n : n vaut 2 (la pile contient [3 ; 4])
ˆ revient dans le calcul du "sinon" du 3e appel et renvoie la valeur 1 × 2, c'est à dire 2
ˆ quitte le 3e appel et dépile la valeur de n : n vaut 3 (la pile contient [4])
ˆ revient dans le calcul du "sinon" du 2e appel et renvoie la valeur 2 × 3, c'est à dire 6
ˆ quitte le 2e appel et dépile la valeur de n : n vaut 4 (la pile est vide)
ˆ revient dans le calcul du "sinon" du 1er appel et renvoie la valeur 6 × 4, c'est à dire 24

6.3 Réflexions sur le procédé


6.3.1 Le piège classique
Dans l'utilisation de la récursivité, le plus délicat est de vérier que les appels en cascade vont s'arrêter.
Dans le cas contraire, l'algorithme va s'enfoncer en profondeur à l'inni dans les appels récursifs. Dans la
pratique, la machine ayant une mémoire limitée, le programme va "planter" lorsque la pile sera saturée.

Il est donc indispensable de tracer l'algorithme précisément "à la main" pour des valeurs raisonnables des
paramètres an de s'assurer que le processus se termine et "remonte" après un nombre ni d'opérations.

6.3.2 À utiliser avec modération

L'utilisation de la récursivité n'est pas toujours judicieuse !

U22 - Algorithmique - Chapitre n°6 Page 32/40


Reprenons l'exemple du triangle de Pascal vu à la n du chapitre sur les tableaux et créons de façon récursive
la fonction P ascal(n, p) dont le but est de renvoyer le coecient de la ligne n et colonne p du tableau (n et
p sont des entiers positifs ou nuls) :

FONCTION Pascal(n , p)
Arguments n , p : entiers
Type retourné entier
si ((p=0) OU (n=p)) alors # on est en première colonne ou sur la diagonale
retourner 1
sinon # se calcule avec la ligne précédente
retourner Pascal(n-1 , p) + Pascal(n-1 , p-1)
n si
Fin FONCTION

Une première remarque est de constater que chaque appel invoque deux fois la fonction. Analysons sous
forme arborescente l'appel P ascal(4, 2) (qui doit retourner 6) :

Pascal(4,2)

Pascal(3,2) Pascal(3,1)

Pascal(2,2) Pascal(2,1) Pascal(2,1) Pascal(2,0)

1 Pascal(1,1) Pascal(1,0) Pascal(1,1) Pascal(1,0) 1

1 1 1 1

Cet arbre permet de constater que les appels récursifs se terminent bien, que le résultat nal vaut bien 6,
mais aussi que la fonction P ascal(2, 1) a été calculée plusieurs fois.

Cela représente donc une redondance et une perte de temps qui devient importante lorsque nous transmettons
des valeurs plus élevées. Ici, l'utilisation de la récursivité ne s'avère pas très judicieuse !

6.3.3 En bouquet final : les tours de Hanoï

L'histoire de ce divertissement se perd dans la nuit des temps et il est répertorié sous diérentes appellations :
1 2
tours de Hanoï, de Brahma ou de Lucas .

Un plateau de jeu comporte 3 tiges verticales et sur l'une d'entre elles sont empilés des disques de tailles
décroissantes, les deux autres étant vides (tapez "tour de Hanoï" dans un moteur de recherche d'images). Le
but est de transférer la pile de disque sur un autre pic en respectant les deux règles suivantes : on ne bouge
qu'un disque à la fois et on ne peut pas poser un disque sur un autre plus petit que lui.

Par exemple, pour transférer une pile de 3 disques du pic no 1 sur le pic no 2, on procède de la façon suivante :

ˆ passer le disque 1 (le plus petit) du pic 1 au pic 2


ˆ passer le disque 2 (le moyen) du pic 1 au pic 3
ˆ passer le disque 1 du pic 2 au pic 3 (en le posant sur le 2)
ˆ passer le disque 3 (le grand) du pic 1 au pic 2 (maintenant libre)
ˆ passer le disque 1 du pic 3 au pic 1 (qui est vide)
ˆ passer le disque 2 du pic 3 au pic 2 (en le posant sur le 3)
ˆ passer le disque 1 du pic 1 au pic 2 (en le posant sur le 2. . . TERMINE)

Cela nous a demandé 7 manipulations. On démontre que pour transférer une pile de n disques, le nombre
minimal de manipulations est 2n − 1. Pour la petite histoire, l'anecdote rapporte que des moines d'un temple
1. Dieu créateur dans la religion Hindouiste
2. du nom du mathématicien Édouard LUCAS du XIXe siècle

U22 - Algorithmique - Chapitre n°6 Page 33/40


Bouddhiste devaient transférer 64 disques d'or et que l'aboutissement du transfert déclencherait la n du
monde. Une estimation optimiste consistant à considérer que les moines transfèrent 1 disque par seconde sans
jamais se tromper . . . nous conduit à une durée d'environ 580 milliards d'années pour réaliser l'opération !
Dormez tranquilles, braves gens !

L'algorithme de transport des disques se règle aisément de façon récursive. Prenons l'exemple du transfert
de 7 disques du pic 1 au pic 2. Le disque 7 étant le plus grand, n'importe quel autre peut être posé dessus. Il
sut donc de transporter les 6 autres disques du pic 1 au pic 3 en ignorant le disque 7, puis le disque 7 du
pic 1 au pic 2, puis ramener les 6 autres disques du pic 3 au pic 2 où la pile va se reconstituer sur le disque
7. Ainsi, nous voyons que si nous sommes capable de transférer une pile de 6 disques, alors nous savons le
faire pour 7. C'est le principe même de la récursivité.

Une dernière remarque avant de passer à l'algorithme : les pics étant numérotés de 1 à 3, leur somme vaut
6. Cela implique que si je veux transférer du pic a vers le pic b, le pic intermédiaire (le troisième) a pour
numéro (6 − a − b).

PROCEDURE Hanoi(n,a,b)
Arguments n , a , b : entiers
Rôle transférer n disques du pic a vers le pic b
Sortie acher la manipulation à opérer
Variable locale inter : entier
si (n=1) alors # bouger 1 disque (celui du dessus)
acher("porter un disque du pic ",a," au pic ",b)
sinon # bouger une pile de n disques
inter ← 6  a  b # numéro du troisième pic
Hanoi(n  1,a,inter) # envoyer n − 1 disques vers le pic intermédiaire
Hanoi(1,a,b) # bouger le plus grand disque
Hanoi(n  1,inter,b) # ramener n − 1 disques du pic intermédiaire
n si
Fin PROCEDURE

On constate que la procédure s'appelle trois fois, mais en transmettant un nombre de disques plus petit, et
qu'elle se résout lorsque ce nombre de disque vaut 1.

La traduction en python, que je vous engage à implémenter est la suivante :

nom de fichier: Cours_6_3_3.py

def Hanoi(n,a,b):
# Type: procédure
# Arguments: n , a , b : entiers
# Rôle: transférer n disques du pic a vers le pic b
# Sortie: afficher la manipulation à opérer
# Variable locale: inter : entier
if (n==1) : # bouger 1 disque (celui du dessus)
print("porter un disque du pic ",a," au pic ",b)
else : # bouger une pile de n disques
inter = 6  a  b # numéro du troisième pic
Hanoi(n  1,a,inter) # envoyer n − 1 disques vers le pic intermédiaire
Hanoi(1,a,b) # bouger le plus grand disque
Hanoi(n  1,inter,b) # ramener n − 1 disques du pic intermédiaire
fin si
# Fin PROCEDURE

Testez-là avec un appel à partir du programme principal . . . mais attention : pour transférer 10 disques, il y
a 1023 manipulations !

U22 - Algorithmique - Chapitre n°6 Page 34/40


Python 3  Annexe A
Les bases du Python 3

A.1 Interface
En lançant l'application IDLE (Python GUI) une fenêtre d'exécution Python Shell s'ouvre. Vous pouvez y
tester des lignes de commande et c'est là que les résultats de vos programmes s'acheront.

En chargeant un programme (menu Fichier) ou en créant un nouveau document, une fenêtre d'édition appa-
Ces derniers doivent être sauvegardés
raît. C'est dans celle-ci que vous pourrez taper vos programmes.
avec l'extension ".py" pour être reconnus par l'éditeur et proter de la coloration syntaxique.
A.2 Commentaires
Les commentaires doivent être précédés du symbole #. La n de ligne à partir de ce symbole est alors ignorée.
A.3 Structure générale
La structure d'un programme écrit en Python doit ressembler à ceci :

structure type en Python 3

# ALGORITHME ...
# ROLE ...
# ENTREES ...
# SORTIES ...
# VARIABLES noms
: types
# DEBUT
...
instructions # commentaire
# ===== titre
instructions # commentaire
...
# FIN

A.4 Affectation
L'aectation de NomVariable se fait grâce au symbole = suivant le schéma : NomVariable = Valeur
A.5 Chaînes de caractères
Doit être placée entre ' (et si une apostrophe gure dans la chaîne on la notera \') ou encore entre ". Un
retour à la ligne peut être provoqué en insérant \n dans la chaîne.

A.6 Saisie
input(message ) ache le contenu de message, attend une saisie au clavier validée par entrée et renvoie la
saisie sous forme d'une chaîne de caractères.

Par exemple : Nom = input('Quel est votre nom ? ')


Si la valeur de la saisie doit être stockée dans une variable entière (respectivement réelle) on lui appliquera
la fonction int (respectivement oat).
Par exemple : Age = int(input('Quel est votre âge ? '))
A.7 Affichage
print(Arg1 , Arg2 , . . .) ache les valeurs des arguments (contenus de variables, chaînes ou nombres) en les
séparant par un espace. En ajoutant en dernier argument sep=chaîne , c'est la chaîne spéciée qui séparera
l'achage des arguments.

Par exemple sep='*' les séparera par une étoile , sep= (chaîne vide) les accolera, sep='\t' insèrera une
tabulation entre chaque et sep='\n' les écrira en passant à la ligne à chaque fois.

De la même façon, en ajoutant en dernier argument end=chaîne vous pouvez décider comment l'achage
doit se comporter à la n de l'instruction print et, par exemple, l'empêcher d'aller à la ligne pour exécuter
l'achage suivant (en mettant la chaîne vide ou d'un espace).

U22 - Algorithmique - Annexe A Page 35/40


Python 3  Annexe B
Opérations et fonctions élémentaires en Python 3

B.1 Opérations et opérateurs de base


Symbole Signication Exemple Valeur renvoyée
+ addition 3+2 5
− soustraction 3−2 1
∗ multiplication 3∗2 6
/ division 3/2 1.5
∗∗ exponentiation 3 ∗ ∗2 9
// quotient entier (div) 17//3 5
% reste entier (mod) 17%3 2
== égalité (7 == 2) False
!= non égalité (7 != 2) True
<; > comparaison stricte (5 < 4) False
>= ; <= comparaison large (2+2 <= 4) True
+ concaténation 'abc' + 'def ' 'abcdef '
and ET logique (3 > 0) and (1 < 0) False
or OU logique (3 > 0) or (1 < 0) True
not NON logique not(3>0) False

B.2 Fonctions
Dans les exemples, la variable X est de type chaîne et est aectée par 'BonjouR'. Les fonctions annotées de
1 2
(*) ou de (**) nécessite le chargement d'un module spécial en début de programme.

Fonction Signication Type Exemple Renvoie


réel , entier )
round( arrondi réel round(3.2572 , 2) 3.26
abs(réel ) valeur absolue réel abs(-3.25) 3.25
random() nombre aléatoire dans [0; 1[ (**) réel
réel )
oor( partie entière (*) entier oor(−2.3) −3
réel )
exp( exponentielle (*) réel exp(−1.2) 0.301. . .
log(réel positif ) logarithme népérien (*) réel log(0.9) −0.105. . .
sqrt(réel positif ou nul ) racine carrée (*) réel sqrt(3.7) 1.923. . .
int(chaîne ) conversion en nombre entier entier int('235') 235
oat(chaîne ) conversion en nombre réel réel oat('23.5') 23.5
str(nombre ) conversion en chaîne chaîne str(3/2) '1.5'
chr(code ASCII ) code ASCII → caractère chaîne chr(97) 'a'
ord(caractère ) caractère → code ASCII entier ord('a') 97
len(chaîne ) nombre de caractères entier len(X) 7
chaîne.upper() mise en majuscule chaîne X.upper() 'BONJOUR'
chaîne.lower() mise en minuscule chaîne X.lower() 'bonjour'
chaîne [n] caractère de rang n chaîne X[2] 'n'
chaîne [n : p] extrait du rang n au rangp−1 chaîne X[1 : 5] 'onjo'
chaîne [n :] extrait à partir du rang n chaîne X[4 :] 'ouR'
chaîne [: p] les p premiers caractères chaîne X[: 3] 'Bon'
chaîne [−n :] les n derniers caractères chaîne X[−2 :] 'uR'
chaîne.nd(ch ) position d'apparition de ch entier X.nd('o') 1
X.nd('ur')  1
chaîne.nd(ch,n) cherche à partir du rang n entier X.nd('o',2) 4
chaîne.nd(ch,n,p) cherche du rang n au rang p−1 entier X.nd('o',2,4)  1

1. mettre en début de programme l'instruction : from math import *


2. mettre en début de programme l'instruction : from random import *
U22 - Algorithmique - Annexe B Page 36/40
Python 3  Annexe C
Structures de contrôle élémentaires en Python 3

C.1 Traitement conditionnel simple


...
if ( condition ) :
...
instructions à réaliser si la condition est remplie
...
# end if
...

C.2 Traitement conditionnel étendu


...
if ( condition ) :
...
instructions à réaliser si la condition est remplie
...
else :
...
instructions à réaliser si la condition n'est pas remplie
...
# end if
...

C.3 Boucle Tant que


...
while (condition ) :
...
instructions à réaliser dans la boucle
...
# end while
...

C.4 Boucle Pour


...
for variable de comptage in range(valeur départ,valeur d'arrivée + 1 ):
...
instructions à faire pour chaque valeur
...
# end for variable de comptage
...

Attention :

Si vous voulez que votre variable i de comptage aille de 5 à 10, il faudra mettre : for i in range(5,11).

U22 - Algorithmique - Annexe C Page 37/40


Python 3  Annexe D
Les tableaux en Python 3

D.1 Tableau à une dimension


D.1.1 Déclaration
Un tableau à une dimension peut être initialisé de diérentes façons :

L'instruction T = [] crée une variable tableau T à 1 dimension de taille 0.

L'instruction T = [2, 7, 0] crée un tableau T à 1 dimension de taille 3 donc les contenus des cellules
sont initialisés respectivement à 2, 7 et 0.

Pour créer un tableau T à 1 dimension de taille n dont tous les contenus sont initialisés à x, les instructions
suivantes sont équivalentes :

T = [x, x, · · · , x] T = [x] ∗ n T = [x for i in range(0, n)]

D.1.2 Accès aux données


La fonction len(T ) renvoie la taille du tableau T (nombre de cellules)

Pour 0 6 i 6 len(T ) − 1 , l'accès au contenu de la cellule de rang i du tableau T se fait en utilisant la


variable T [i] (que ce soit pour utiliser ou changer son contenu).

D.1.3 Affectation dynamique


L'instruction T.append(x) ajoute une cellule au tableau T en y mettant la valeur x. La taille du tableau
est donc augmentée de 1.

D.2 Tableau à deux dimensions


D.2.1 Déclaration
Un tableau T à deux dimensions de taille n × p (n lignes et p colonnes) se déclare comme un tableau à une
dimension de taille n dont les composantes sont des tableaux à une dimension de taille p.
Un tableau à deux dimensions peut être initialisé en y aectant directement le contenu de ses cellules :

Par exemple l'instruction T = [[2, 3], [5, 6], [8, 9]] crée le tableau T à deux dimensions, 3 lignes et 2
colonnes, possédant donc 6 cellules. Le contenu de la cellule qui se trouve à la ligne d'indice 2 et à la colonne
d'indice 0 valant 8.

Pour initialiser un tableau T de n lignes et p colonnes en mettant la valeur x dans toutes ses cellules, on
écrira l'instruction suivante : T = [[x for j in range(0, p)] for i in range(0, n)]

D.2.2 Accès aux données


Pour un tableau T à 2 dimensions, l'expression len(T ) renvoie le nombre de lignes du tableau T .
T [i] représente la ligne d'indice i. C'est un tableau à 1 dimension dont la taille est le nombre de colonnes de
T . L'expression len(T [0]) renvoie donc le nombre de colonnes du tableau T.
La variable T [i][j] représente la cellule de la ligne d'indice i et de la colonne d'indice j.

D.2.3 Affectation dynamique


L'aectation dynamique (un "append") sur un tableau à 2 dimensions est risquée !

En eet, si vous voulez lui ajouter une ligne, il faudra que l'ajout transmette un tableau à 1 dimension dont
la taille correspond au nombre de colonnes du tableau. Par exemple si le tableau T comporte p colonnes et
qu'on veut lui ajouter une ligne de "x", on écrira :

T.append([x] ∗ p)

Et si vous voulez lui ajouter une colonne, il faut cette fois ajouter une cellule par ligne et il faudra utiliser
une boucle. Par exemple si T contient n lignes et qu'on veut lui ajouter une colonne de "x", on écrira :

for i in range(0, n) : T [i].append(x)

U22 - Algorithmique - Annexe D Page 38/40


Python 3  Annexe E
Définition de procédure et fonction en Python 3

E.1 Procédure
def NomProcédure (liste d'arguments éventuels séparés par des virgules ) :
# type : procédure
# arguments : noms et types
# rôle : (. . .)
# variables : noms et types
suite d'instructions
# Fin de procédure
E.2 Fonction
def NomFonction (liste d'arguments éventuels séparés par des virgules ) :
# type : fonction
# arguments : noms et types
# rôle : (. . .)
# valeur renvoyée : type
# variables : noms et types
suite d'instructions
return NomDeVariable ou ValeurCalculée
# Fin de fonction

U22 - Algorithmique - Annexe E Page 39/40


Python 3  Annexe F
Codes Ascii de 32 à 127

Décimal Hexadécimal Binaire Caractère Décimal Hexadécimal Binaire Caractère


32 20 00100000 espace 80 50 01010000 P
33 21 00100001 ! 81 51 01010001 Q
34 22 00100010 " 82 52 01010010 R
35 23 00100011 # 83 53 01010011 S
36 24 00100100 $ 84 54 01010100 T
37 25 00100101 % 85 55 01010101 U
38 26 00100110 & 86 56 01010110 V
39 27 00100111 ' 87 57 01010111 W
40 28 00101000 ( 88 58 01011000 X
41 29 00101001 ) 89 59 01011001 Y
42 2A 00101010 * 90 5A 01011010 Z
43 2B 00101011 + 91 5B 01011011 [
44 2C 00101100 , 92 5C 01011100
45 2D 00101101 - 93 5D 01011101 ]
46 2E 00101110 . 94 5E 01011110 ∧
47 2F 00101111 / 95 5F 01011111 _
48 30 00110000 0 96 60 01100000 `
49 31 00110001 1 97 61 01100001 a
50 32 00110010 2 98 62 01100010 b
51 33 00110011 3 99 63 01100011 c
52 34 00110100 4 100 64 01100100 d
53 35 00110101 5 101 65 01100101 e
54 36 00110110 6 102 66 01100110 f
55 37 00110111 7 103 67 01100111 g
56 38 00111000 8 104 68 01101000 h
57 39 00111001 9 105 69 01101001 i
58 3A 00111010 : 106 6A 01101010 j
59 3B 00111011 ; 107 6B 01101011 k
60 3C 00111100 < 108 6C 01101100 l
61 3D 00111101 = 109 6D 01101101 m
62 3E 00111110 > 110 6E 01101110 n
63 3F 00111111 ? 111 6F 01101111 o
64 40 01000000 @ 112 70 01110000 p
65 41 01000001 A 113 71 01110001 q
66 42 01000010 B 114 72 01110010 r
67 43 01000011 C 115 73 01110011 s
68 44 01000100 D 116 74 01110100 t
69 45 01000101 E 117 75 01110101 u
70 46 01000110 F 118 76 01110110 v
71 47 01000111 G 119 77 01110111 w
72 48 01001000 H 120 78 01111000 x
73 49 01001001 I 121 79 01111001 y
74 4A 01001010 J 122 7A 01111010 z
75 4B 01001011 K 123 7B 01111011 {
76 4C 01001100 L 124 7C 01111100 |
77 4D 01001101 M 125 7D 01111101 }
78 4E 01001110 N 126 7E 01111110 ∼
79 4F 01001111 O 127 7F 01111111 delete

U22 - Algorithmique - Annexe F Page 40/40

Vous aimerez peut-être aussi