Algorithmique Programmation - Laurent POINTAL Département Mesures Physiques - Cours S'1 - limsi
←
→
Transcription du contenu de la page
Si votre navigateur ne rend pas la page correctement, lisez s'il vous plaît le contenu de la page ci-dessous
Algorithmique Programmation Département Mesures Physiques — Cours S'1 Laurent POINTAL CNRS/LIMSI laurent.pointal@limsi.fr laurent.pointal@u-psud.fr Version 1 — Janvier 2019 24/01/19 15:39
page 2/73 Algorithmique-Programmation Sommaire I -Introduction................................................................3 VI.1 -Vocabulaire....................................................37 I.1 -Styles utilisés......................................................4 VI.2 -Défnition.......................................................37 I.2 -Vocabulaire…......................................................4 VI.3 -Utilisation (appel).........................................39 I.3 -Ordinateur et exécution...................................5 VI.3.a -Arguments d’appel..............................................40 I.3.a -Représentation binaire............................................5 VI.3.b -Appels entre fonctions.......................................41 I.3.b -Exécution d’un programme....................................6 VI.4 -Variables, portée et durée de vie..............43 I.4 -Langage Python.................................................7 VI.5 -Valeurs de retour..........................................44 I.4.a -Mots clés du langage................................................7 VI.5.a -Valeurs multiples.................................................44 I.4.b -Structure d’un programme.....................................7 VI.5.b -Aucune valeur : Procédures..............................45 I.4.c -Installation de Python..............................................7 VI.6 -Efets de bord................................................45 I.4.d -Tester Python en mode interactif.........................8 VI.6.a -Fonctions pures....................................................45 I.4.e -Tester Python en ligne.............................................8 VII -Tableaux de données..........................................47 I.4.f -Exécuter des programmes Python.........................9 VII.1 -Déclaration de tableau..............................47 I.5 -Algorithmique....................................................9 I.5.a -Organigramme........................................................10 VII.2 -Opérations sur les tableaux.....................48 VII.2.a -Indexation............................................................48 I.6 -Tester un programme.....................................11 VII.2.b -Méthodes sur les tableaux................................48 I.6.a -Techniques de débogage.......................................11 VII.2.c -Duplication de tableau......................................49 I.6.b -Erreurs en Python..................................................11 VII.3 -Instruction de boucle sur tableau...........50 II -Types de base...........................................................13 VII.3.a -Boucle sur les valeurs........................................50 II.1 -Nombres...........................................................13 VII.3.b -Boucle sur les indices........................................52 II.1.a -Entiers......................................................................13 VII.4 -Fonctions et tableaux.................................53 II.1.b -Flotants (réels)......................................................13 VII.4.a -Efet de bord sur paramètre.............................54 II.1.c -Opérations sur les nombres................................14 VII.5 -Tableaux à 2 dimensions...........................55 II.2 -Valeurs logiques.............................................16 II.2.a -Opérations booléennes........................................16 VIII -Fichiers.................................................................57 II.3 -Textes................................................................17 VIII.1 -Ouverture/Fermeture...............................57 II.3.a -Opérations sur les chaînes..................................19 VIII.1.a -Ouverture...........................................................57 II.3.b -Indexation et sous-chaînes.................................20 VIII.1.b -Fermeture...........................................................58 II.3.c -Méthodes sur les chaînes.....................................20 VIII.2 -Lecture.........................................................58 II.3.d -Modifcation d’une chaîne..................................22 VIII.2.a -Lecture de nombres..........................................59 III -Variables et afectation........................................23 VIII.3 -Écriture........................................................60 III.1 -Instruction d’afectation.............................23 VIII.3.a -Écriture de nombres.........................................60 III.1.a -Utilisation des variables.....................................23 IX -Modules...................................................................62 III.1.b -Constantes.............................................................24 IX.1 -Import.............................................................62 III.1.c -Afectations multiples.........................................24 IX.1.a -Emplacement........................................................63 III.2 -Noms des identifcateurs............................24 IX.2 -Défnition.......................................................63 III.2.a -Règles générales...................................................24 IX.3 -Utilisation.......................................................64 III.2.b -Conventions pour l’apprentissage...................25 X -Programmation Objet...........................................66 IV -Afchage et saisie.................................................27 X.1 -Vocabulaire......................................................66 IV.1 -Fonction d’afchage.....................................27 X.2 -Exemple complet...........................................66 IV.1.a -Formatage des valeurs........................................27 X.2.a -Défnition de la classe..........................................66 IV.2 -Fonction de saisie.........................................28 X.2.b -Utilisation de la classe.........................................68 V -Structures de contrôle...........................................29 X.3 -Défnition de classe.......................................69 V.1 -Signalisation d’erreur....................................29 X.3.a -Défnition des atributs........................................69 V.2 -Bloc d’instructions.........................................29 X.3.b -Représentation pour l’afchage.........................69 V.3 -Instruction conditionnelle si.......................30 X.4 -Manipulation d’objets...................................69 V.3.a -Alternative sinon...................................................31 X.4.a -Création...................................................................69 V.3.b -Alternatives multiples..........................................32 X.4.b -Atributs..................................................................69 V.3.c -Imbrication de conditions....................................33 X.4.c -Méthodes.................................................................70 V.3.d -Choix multiple.......................................................33 X.5 -Sous-classes.....................................................70 V.4 -Instruction de répétition tant que.............33 X.5.a -Héritage...................................................................70 V.4.a -Raccourci de boucle : continuer.........................35 X.5.b -Redéfnition............................................................71 V.4.b -Rupture de boucle : stopper................................36 XI -Python pratique....................................................72 VI -Fonctions.................................................................37
I - Introduction page 3/73 Algorithmique-Programmation I - Introduction Le cours, le poly, les TDs et TPs du semestre S'1 ont été revus par rapport au semestre S1 afn de res- treindre certains aspects de programmation spécifques à Python — bien pratiques mais qui peuvent perturber la compréhension — pour pouvoir se concentrer sur les grands principes d’algorithmique et leur mise en œuvre simplement dans des programmes. Ces aspects ignorés sont listés dans le chapitre fnal « Python pratique ». Pour apprendre à programmer, rien ne remplace la pratique sur ordinateur, avec des problèmes simples au début puis de plus en plus élaborés. Essayez chez vous ou dans les salles informatique à l’IUT, posez des questions à vos enseignants cours/TD/TP. Pour commencer, un diagramme résumant les éléments abordés dans cete matière : On retrouve 4 éléments principaux dans ce graphique : 1. on va traiter des données, elles sont au centre de tout, 2. l’algorithmique va nous fournir des constructions pour exprimer la résolution du problème, 3. le programme doit permetre d’exprimer l’algorithme et de manipuler des données au cours de son exécution, 4. les instructions du programme s’exécutent en séquence, une par une, sur un ordinateur et manipulent les données en mémoire.
I - Introduction page 4/73 Algorithmique-Programmation I.1 - Styles utilisés Dans ce cours nous utilisons les styles de caractères suivants pour les éléments importants et les éléments très importants. Nous utiliserons les styles de paragraphes suivants pour le code : Algorithmique Programme script Python Exécution d'un script Python, les saisies de l'utilisateur sont indiquées en gras Session interactive shell Python, saisies utilisateur en gras Les exemples de programmes sont colorisés ainsi (commentaire, mot clé, identificateur, littéral) : # Un exemple import sys def affiche_args(lArgs): print("Arguments:") for sa in lArgs: print(sa) affiche_args(sys.argv) I.2 - Vocabulaire… Le terme français Informatique1 vient d’Information Automatique — c’est la science et la technologie du traitement automatique de l’information. Les anglophones utilisent le terme Computer Science (science des calculateurs). Le terme français Ordinateur2 a remplacé celui de calculateur, on y retrouve sémantiquement l’ordon- nancement des instructions et le fait de donner des ordres à la machine. Algorithme3 : Processus systématiques de résolution d’un problème permetant de décrire précisément des étapes pour le résoudre ; le problème consistant en des données en entrée devant aboutir à des données en sortie, la résolution devant être non ambiguë et se faire en un temps fni. • Systématique → on doit pouvoir l’appliquer à des jeux de données diférentes, • Précisément → on doit être précis, l’interprétation sémantique doit être claire, • Étapes → notion de temps, séquencement des opérations à réaliser l’une après l’autre. Et si on réféchit à la programmation de l’algorithme pour son exécution sur un ordinateur, on peut se poser plusieurs questions : • Processus → comment exprimer l’algorithme pour que l’humain puisse le rédiger et que l’ordi- nateur le comprenne pour l’exécuter ? • Systématique → comment être générique dans l’expression pour s’adapter aux jeux de don- nées ? • Étapes → comment indiquer l’ordre de séquencement ? • Données → comment les représenter dans le codage binaire de l’ordinateur ? 1 Inventé par Philippe Dreyfus en 1962. 2 Inventé par Jacques Perret en 1955, à partir de la description des machines vendues par IBM. 3 Algorithme vient du nom du mathématicien, géographe, astrologue et astronome perse Al-Khwârizmî (~780-~850)
I - Introduction page 5/73 Algorithmique-Programmation I.3 - Ordinateur et exécution On retrouve diférents composants électroniques dans l’ordinateur, que l’on peut schématiser par : L’ensemble est cadencé par une horloge et fonctionne avec des signaux électroniques sur deux états, représentant des informations numériques sous forme binaire. I.3.a - Représentation binaire Cete représentation utilise des unités d’information appelées « bit », éléments binaires pouvant prendre deux états logiques : 0/1, Faux/Vrai, absence de signal/présence de signal… Tout ce que mani- pule l’ordinateur, programmes et données, est représenté sous cete forme. Pour noter les valeurs on préfère généralement une notation hexadécimale (base 16) à la notation binaire bien trop longue. À chaque regroupement de 4 bits correspond un chifre hexadécimal : Binaire Hexa Décimal Binaire Hexa Décimal Binaire Hexa Décimal Binaire Hexa Décimal 0000 0 0 0100 4 4 1000 8 8 1100 C 12 0001 1 1 0101 5 5 1001 9 9 1101 D 13 0010 2 2 0110 6 6 1010 A 10 1110 E 14 0011 3 3 0111 7 7 1011 B 11 1111 F 15 Note : on trouve très souvent le préfxe 0x avant les nombres hexadécimaux (ex. 0x5F78E2). Pour coller à l’organisation des bits dans l’ordinateur, et pour des facilitées de lecture, on regroupe généralement les bits par paquets de 8 appelés octets (bytes). Chaque octet peut être noté à l’aide de deux chifres hexadécimaux : 01000010 01101111 01101110 01101010 1101111 01110101 1110010 0100001 42 6F 6E 6A 6F 75 72 21 Cet exemple de 8 octets correspond au codage du texte ASCII « Bonjour! ». Il correspond aussi au codage de deux nombres entiers 14022442842 et 11723572729. Il correspond aussi au codage d’un nombre réel 12079297126422283,56655. Il correspond aussi au codage de deux couleurs RGBA4 et . Il corres- pond aussi à une adresse en mémoire sur 64 bits. Ça pourrait aussi être une partie d’une image ou d’un son, ou encore d’un programme sur votre ordinateur. Suivant le type des données numériques binaires stockées, les octets peuvent représenter difé- rentes informations, on ne les interprétera pas de la même façon et on ne pourra pas faire les mêmes opérations. La défnition précise des types de données manipulées est un élément essentiel lors du passage de l’algorithme au programme, elle détermine les contraintes imposées par la machine et les opérations que l’on pourra efectuer sur les données. 4 RGBA pour Red Green Blue Alpha, valeurs de trois composantes de couleurs ainsi que la transparence, sur un octet chacun.
I - Introduction page 6/73 Algorithmique-Programmation Bases de numération Un rappel concernant les bases dans l’écriture de nombres entiers. Pour un nombre N β, exprimé dans la base β, à chaque chifre de N correspond un multiplicateur par une puissance de β utilisée, de gauche à droite en ordre décroissant jusqu’à β0. Exemples : 1782910 = 1×103 + 7×102 + 8×101 + 9×100 = 1×1000 + 7×100 + 8×10 + 9×1 112012 = 1×23 + 1×22 + 0×21 + 1×20 = 1×8 + 1×4 + 0×2 + 1×1 = 1310 225F16 = 2×163 + 2×162 + 5×161 + 15×160 = 2×4096 + 2×256 + 5×16 + 15×1 = 8799 I.3.b - Exécution d’un programme Seul langage que comprend le microprocesseur au cœur de l’ordinateur : son langage machine spéci- fque (aussi appelé code machine, code natif ou encore code binaire). C’est un codage purement numé- rique représentant des opérations très basiques et/ou des données. Il peut être exprimé dans un langage symbolique textuel d’un peu plus haut niveau, appelé langage d’assemblage, à partir duquel un programme assembleur permet d’interpréter les symboles pour générer le programme exécutable en code machine. Exemple5 de programme assembleur sous Windows (sans les commentaires) : ORG 100h MOV AH, 09h MOV DX, message INT 21h RET message db "Bonjour le monde !", '$' Pas très adapté à l’être humain, on a besoin de données de plus haut niveau, d’exprimer des concepts plus abstraits, de comprendre facilement un code écrit… de là sont nés de (très 6) nombreux langages de programmation (Lisp, Fortran, Cobol, Algol, APL, Basic, PL/1, Simula, C, Smaltalk, Prolog, Pascal, Forth, SQL, Ada, C++, Eifel, Perl, Haskell, Python, Ruby, Lua, Javascript, Java, PHP, C#, Rust, Go…). La plupart expriment les programmes avec du texte, mais on peut trouver certains langages graphiques (LabView, Pd, NodeBox…). Chaque langage a ses avantages et inconvénients, est plus ou moins adapté suivant le type de problème que l’on veut résoudre. Ils permetent d’exprimer les algorithmes en ofrant diférents paradigmes7 de programmation (logiques de fonctionnement) parmi lesquels on citera : • La programmation impérative, où l’exécution d’une séquence d’instructions va modifer l’état des données (la plupart des langages sont impératifs). • La programmation objet à base de classes, qui est une façon d’organiser et de regrouper les données et les traitements qui y sont liés. • La programmation fonctionnelle déclarative, qui se rapproche des théories mathématiques. On distingue historiquement deux modes d’exécution : « compilation » et « interprétation » : • La compilation : un programme intermédiaire, le compilateur, lit le texte du programme en lan- gage de haut niveau et le traduit en code machine directement exécutable par le processeur. Ensuite, le code machine est directement exécuté par le processeur dans le cadre d’un pro- cessus du système d’exploitation. • L’interprétation : un programme intermédiaire, l’interpréteur, lit le texte du programme de haut niveau et en assure lui-même l’interprétation ligne par ligne. 5 Source : https://fr.wikiversity.org/wiki/Assembleur/Le_langage_assembleur 6 Voir une historique sur https://www.levenez.com/lang/ 7 Voir https://fr.wikipedia.org/wiki/Paradigme_(programmation)
I - Introduction page 7/73 Algorithmique-Programmation Les techniques actuelles mixent allègrement ces deux modes d’exécution, utilisant parfois des représen- tations intermédiaires, appelées byte-code, ou générant directement le code machine par de la compi- lation à la volée juste avant de l’exécuter. I.4 - Langage Python Langage créé en 1991 aux Pays-Bas par Guido van Rossum, son utilisation s’est régulièrement étendue dans des domaines très variés ; il est maintenant un des premiers langages pour l’apprentissage de l’al- gorithmique et de la programmation. Il a été introduit dans le cadre de ce cours en 2006 par B. Cordeau. Il permet de metre en œuvre les trois paradigmes de programmation présentés. Python exécute ses programmes avec une compilation du texte « source » vers une représentation en byte-code intermédiaire, qui est ensuite interprété par un interpréteur « machine virtuelle ». Sa syntaxe très lisible lui permet de passer simplement de l’algorithme au programme et donc de pouvoir rapide- ment tester l’exécution du programme sur des jeux de données. I.4.a - Mots clés du langage Dans les programmes Python, ces mots clés (keywords) sont interprétés avec une signifcation particu- lière : and, as, assert, break, class, continue, def, del, elif, else, except, False, finally, for, from, global, if, import, in, is, lambda, None, nonlocal, not, or, pass, raise, return, True, try, while, with, yield. Dans ce cours nous n’aborderons pas tous les mots clés. I.4.b - Structure d’un programme Les programmes Python sont simplement des fchiers textes, appelés aussi fchiers scripts Python, avec une extension .py. Ils sont formés de lignes qui contiennent les instructions à exécuter, une par ligne 8. Le caractère # permet d’introduire des com- mentaires dans le code du programme (du # à la fn de la ligne). Si l’instruction sur une ligne contient une expression non terminée — un ( ou [ ou { non fermé — alors elle se continue sur les lignes suivantes tant que l’expression n’est pas terminée par le ) ou ] ou } fermant. Un caractère \ tout en fn de ligne permet aussi de poursuivre l’instruction commencée sur la ligne suivante. L’exécution est réalisée ligne par ligne en parcourant le programme de haut en bas, avec des ruptures et des reprises possibles grâce aux structures de contrôle (cf. p29) et aux fonctions (cf. p33). Il utilise l’indentation (décalage du texte) pour délimiter les blocs d’instructions9 liées à ces structures de contrôles et fonctions. La structure visuelle du programme est donc l’image de sa structure fonctionnelle. Atention : utiliser des espaces pour réaliser l’indentation, pas le caractère de tabulation (confgurez votre éditeur pour que touche tabulation génère ces espaces). Un fchier script Python constitue un module (cf. p62), que l’on peut importer pour le réutiliser dans un autre programme. I.4.c - Installation de Python Pour ne pas perdre inutilement de place dans ce document (nombreuses copies d’écran, cas particuliers suivant les machines, nécessité de mise à jour suivant les problèmes rencontrés…), l’installation de Python est décrite ici : https://perso.limsi.fr/pointal/python:installation: 8 La possibilité de placer plusieurs instructions sur la même ligne — séparées par des ; — est très peu utilisée et est déconseillée. 9 Pour délimiter les blocs d’instructions les autres langages utilisent généralement des symboles, comme {}, ou encore des mots clés comme begin et end.
I - Introduction page 8/73 Algorithmique-Programmation Si vous avez déjà un Python de version supérieure ou égale à Python 3.6 avec la librairie matplotlib installée, c’est bon. Sinon, il vous faut faire une réinstallation (ou une installation en plus — plusieurs versions de Python peuvent être installées en parallèle… il faut juste choisir la bonne lorsqu’on exécute un script), dans ce cas voir la documentation d’installation disponible en ligne. I.4.d - Tester Python en mode interactif Python ofre un mode « calculatrice », permetant de tester facilement de petites expressions (dès que le test devient conséquent il vaut mieux le placer dans un fchier script). Le plus simple est d’ouvrir l'IDE (Integrated Development Environment) que vous avez choisi et d’utiliser l’interpréteur Python démarre automatiquement dans cet environnement (souvent appelé « Shell Python »). Il afche une invite (ou prompt) sous la forme de >>>10, après laquelle vous pouvez directe- ment saisir des expressions de calcul ou des instructions qui sont exécutées dès que vous validez par la touche Entrée (il peut être nécessaire de la presser deux fois). En mode interactif la valeur résultant d’une expression de calcul est directement afchée. Qelques exemples : >>> 20 * 5.5 + 3 * 5 # expression de calcul sur des nombres 125.0 >>> sLang = "Python 3" # instruction d'affectation >>> (sLang + " ") * 5 # expression de calcul sur du texte 'Python 3 Python 3 Python 3 Python 3 Python 3 ' >>> for c in sLang: # instruction de boucle suivie d'un bloc d'instructions ... print(f"{c} {ord(c)}") ... print("---") ... P 80 --- y 121 --- t 116 --- h 104 --- o 111 --- n 110 --- 32 Édition dans Python Tutor --- 3 51 --- >>> ((12 + 8) * 4 + # expression de calcul sur des nombres, sur plusieurs lignes ... 10 * 2) 100 Notez que l’invite est changée en ... lorsque l’interpréteur est en atente de la suite de l’expression ou de l’instruction. I.4.e - Tester Python en ligne Le site web Python Tutor permet de saisir un programme puis de le tester en visualisant l’état des variables au fur et à mesure de l’exécution. Cela aide beaucoup à la compréhension des modifcations des variables en mémoire au fur et à mesure de l’avancement de l’exécution du programme et des appels de fonctions (sous-programmes). → http://www.pythontutor.com/ → http://www.pythontutor.com/visualize.html#mode=edit N’oubliez pas de sélectionner Python en version 3.6 ou plus récent. Lors de la visualisation de l’exécution il est possible avec le bouton Forward d’exécuter les lignes une à une et de suivre dans partie droite non seulement les afchages, mais aussi les variables et leurs valeurs 10 L’invite peut être In [1]: si iPython est installé — le fonctionnement reste similaire.
I - Introduction page 9/73 Algorithmique-Programmation courantes. Le bouton Back permet de revenir à la ligne précédemment exécutée en remetant les variables dans l’état où elles étaient (cet outil d’enseignement met en place toute une infrastructure pour cela, en exécution normale on ne peut pas revenir en arrière). Merci à Philip J. Guo pour cet excellent outil. I.4.f - Exécuter des programmes Python À partir de l’IDE que vous avez choisi, ouvrez le fchier script contenant le programme à exécuter et demandez son exécution directement via les commandes dans l’IDE : • Avec Pyzo, menu Exécuter → Démarrer le script (raccourci E), qui a l’avantage de redémarrer l’interpréteur Python donc de partir d’un environnement d’interprétation vierge. Attention car Pyzo supporte aussi le raccourci qui exécute le module dans l’interpréteur Python courant mais sans le redémarrer (toutes ce qui a été défni lors des tests précédents reste présent en mémoire). • Avec IDLE, menu Run → Run module (raccourci ). • Avec PyCharm, menu Run → Run (raccourci ). Sinon, en ligne de commande vous pouvez directement appeler le programme python (Python 3) en lui donnant comme argument le fchier script à exécuter (dans les exemples toto.py). Si le programme python que vous désirez utiliser est directement accessible (dans le PATH) : laurent@litchi:~$ python3 toto.py Si vous devez utiliser une installation spécifque de Python, il faut l’indiquer sur la ligne de commande : laurent@litchi:~$ ./apps/miniconda3/bin/python3 toto.py I.5 - Algorithmique Qand on fait le parallèle avec des recetes de cuisine, ou des notices de montage, dans les algorithmes il va nous falloir pouvoir : • Spécifer l’ordre dans lequel sont exécutées, une à une, les instructions. ➔ En fonctionnement normal, exécution dans l’ordre de lecture de haut en bas (ça sera pareil pour les programmes). • Ne réaliser certaines séquences d'ordres que dans des cas particuliers. ➔ Instruction d’exécution conditionnelle de bloc d’instructions suivant un test logique. • Répéter un certain nombre de fois certaines séquences d'ordres. ➔ Instructions de boucle sur un bloc d’instructions, soit tant qu’un test logique est vrai, soit lié à plusieurs données à traiter de façon similaire.
I - Introduction page 10/73 Algorithmique-Programmation • Identifer les données que l'on va manipuler (algorithme générique) et ce que l’on va en faire. ➔ Défnition de noms, les variables, qui identifent symboliquement les données, auxquelles elles ne seront associées que lors de l’exécution. ➔ Spécifcation des types des données manipulées pour savoir ce que l’on peut faire avec. ➔ Moyens de récupérer les données à traiter et de sauvegarder les résultats des traitements. • Défnir des parties d’algorithme que l’on pourra réutiliser à diférents endroits dans avoir à les re-détailler. ➔ Défnition de procédures et fonctions. Nous allons voir par la suite l’aspect algorithmique et l’aspect programmation sur ces diférents points. I.5.a - Organigramme Pour présenter certains éléments d’algorithmique, nous utilisons soit une représentation textuelle en français — assez proche des programmes Python, soit une représentation graphique sous la forme d’or- ganigrammes simplifés qui permetent d’identifer visuellement le déroulement de l’exécution avec des formes reliées par des fèches. Graphiques organigramme Exemple Note : La représentation en organigramme peut être très « parlante » et peut aider à comprendre la logique de fonctionnement d’un algorithme. Mais elle devient vite fouillis (« spagheti » avec des fèches dans tous les sens) et peu pratique lorsque l’algorithme prend de l’importance ou qu’on com- mence à défnir et utiliser des fonctions — on la réservera à la compréhension des grands principes et des algorithmes simples.
I - Introduction page 11/73 Algorithmique-Programmation I.6 - Tester un programme Tester un algorithme sur un ordinateur correspond à faire exécuter un programme qui réalise cet algo- rithme en lui fournissant des données de test et à vérifer que les résultats atendus correspondent bien aux données fournies. Pour cela on a généralement des données réduites correspondant à des cas connus ou bien qu’on sait calculer/vérifer à la main. On dispose en général de plusieurs jeux de tests, avec des données correspondant chacun aux difé- rents cas d’utilisation identifés, incluant les cas où le programme doit détecter des erreurs. Ceci doit permetre de vérifer l’ensemble des instructions du programme 11. I.6.a - Techniques de débogage Afichages au cours de l’exécution Technique simple consistant à ajouter des instructions d’afchage à certains endroits choisis dans le programme afn de vérifer que les données manipulées et les transformations efectuées sont bien celles atendues. Ces afchages devront être mis en commentaire ou bien supprimés une fois que le programme sera au point. Exécution pas à pas Les IDE fournissent généralement des possibilités d’exécuter les programmes ligne à ligne, avec une pause entre deux instructions pendant laquelle il est possible d’afcher les valeurs des diférentes variables. Ils permetent souvent de placer des points d’arrêts dans le programme, où l’exécution nor- male se met en pause et permet de passer en pas à pas, puis de repasser quand on le veut en exécution normale jusqu’au prochain point d’arrêt. Voir la documentation de l’IDE utilisé pour savoir comment activer et utiliser cete fonctionnalité. Tests et assertions Outre les vérifcations normales permetant de valider les données fournies (cas d’erreur atendus que l’on veut détecter), les langages permetent souvent d’insérer des contrôles de validité (de vérifcations d’assertions12) testant que les données sont bien atendues, respectent bien certaines règles — donc que les transformations efectuées par les instructions produisent bien ce à quoi le programmeur s’atend. En général ces contrôles peuvent être laissés dans le code du programme, ils sont activés en fonction- nement de débogage (debug) et peuvent être désactivés en fonctionnement optimal (release). Utilisation d’outils externes Enfn, certains outils externes permetent de travailler soit sur le code du programme pour efectuer des vérifcations statiques plus poussées sur celui-ci que ce que ne fait le compilateur, soit à l’exécution du programme pour tracer les chemins d’exécution et l’impact du programme sur son environnement (occupation mémoire, tests de couverture du code, analyse des performances). Traitement des erreurs Les mécanismes d’indication et de traitement des erreurs diférent suivant les langages de programma- tion. I.6.b - Erreurs en Python Lorsque Python détecte une erreur soit de syntaxe soit d’exécution, il le signale en procédant à une levée d’exception (ou déclenchement d'exception). Ceci provoque l’arrêt des instructions en cours et le 11 On parle de « tests de couverture », qui doivent permetre d’exécuter toutes les alternatives possibles du programme. 12 Le langage Python ofre une instruction assert condition. L’option -O de Python désactive les assertions.
I - Introduction page 12/73 Algorithmique-Programmation passage du programme dans des blocs d’instruction spécifques. Nous ne verrons en cours que la levée d’exception (cf. p29), pas leur traitement. Lecture du “Traceback” Si aucun code de traitement ne bloque une exception, celle-ci fnit par générer l’afchage d’un message d’erreur accompagné d’un retraçage (traceback) des instructions qui ont mené à l’erreur. Cet afchage commence par le mot Traceback sur la première ligne, suivi de couples de lignes décrivant l’origine des instructions ayant conduit à l’erreur (du plus ancien à celui qui a généré l’erreur), et en dernière ligne une indication de la classe de l’erreur accompagnée d’un message explicatif. Traceback (most recent call last): File "/.../principal.py", line 42, in print(validation.test(9, 1)) File "/.../validation.py", line 10, in test return 3 * calculs.preparation(x, y) File "/.../calculs.py", line 12, in preparation return 1 + simulrap(a, b-1) File "/.../calculs.py", line 25, in simulrap return abs(x) / (3 * y) ZeroDivisionError: division by zero Dans cet exemple nous avons eu une division par zéro, au niveau de l’instruction à la ligne 25 du fchier Python calculs.py dans la fonction simulrap (sur une instruction avec une division par 3×y ). Les argu- ments d’appel ont été fournis à cete fonction par la fonction preparation en ligne 12… etc. Il est nécessaire d’apprendre à lire et décoder ces retraçages afn de savoir déboguer et corriger les pro- grammes.
II - Types de base page 13/73 Algorithmique-Programmation II - Types de base Note : la représentation littérale des valeurs est la forme sous laquelle on les écrit dans les pro- grammes. II.1 - Nombres II.1.a - Entiers En algorithmique on les choisira par exemple pour du dénombrement, du comptage. En Python on utilise le type de données int. La représentation litérale utilise simplement des chifres en base 10 avec un signe optionnel : >>> 0 0 >>> type(0) >>> 1 1 >>> 144 144 >>> -321 -321 >>> +51 +51 La fonction standard int() permet dans un programme de convertir une représentation textuelle d’un nombre vers l’entier correspondant. Il est aussi possible avec int() de convertir n’importe quelle valeur compatible en une valeur entière. >>> int('0') 0 >>> int('-12') -12 >>> int('48') 48 >>> int(3.712) # Conversion d'un nombre réel en nombre entier 3 II.1.b - Flotants (réels) En algorithmique ils sont généralement choisis pour des mesures de grandeurs physiques, du calcul numérique. On utilise souvent le terme fottant (foat) pour « nombre décimal à virgule fotante ». En Python on utilise le type de données float. La représentation litérale combine un signe optionnel, les chifres qui forment le nombre, avec un point obligatoire (.) pour la virgule décimale, et éventuelle- ment un E ou un e suivi d’une puissance de 10. >>> 0.0 0.0 >>> type(0.0) >>> 12.765 12.765 >>> .32 0.32 >>> -45.84 -45.84
II - Types de base page 14/73 Algorithmique-Programmation >>> 1e6 1000000.0 >>> -3.14e2 -314.0 >>> 8.6592E-10 8.6592e-10 >>> 8.6592E-4 0.00086592 La fonction standard float() permet dans un programme de convertir une représentation textuelle d’un nombre vers le fotant correspondant. >>> float('0') 0.0 >>> float('0.425') 0.425 >>> float('-23E-10') -2.3e-09 Attention : La représentation en mémoire des fotants impose des limites13 et provoque des pertes de précision lors des calculs. Par exemple : >>> 1e20 + 1 - 1e20 # Notez la perte de 1 devant 1020 0.0 >>> 0.1 * 0.1 * 0.1 # Notez l'apparition du chiffre 2 en 19ème décimale 0.0010000000000000002 II.1.c - Opérations sur les nombres On utilise en algorithmique les opérations que l’on pratique couramment en mathématiques ou en phy- sique pour manipuler des valeurs numériques : addition, soustraction, multiplication, division, éléva- tion à une puissance, valeur absolue, division euclidienne (entière) et reste… On peut utiliser des paren- thèses pour regrouper des parties d’expression et modifer les priorités des opérateurs. En Python on dispose d’opérateurs (caractères ayant une signifcation particulière) et de fonctions dédiées, utilisables indiféremment avec les nombres entiers ou fotants qui peuvent être combinés dans les expressions de calcul14 : >>> 28 + 2 # Addition, opérateur + 30 >>> 28 + 2.0 # Résultat flottant dès qu'il y a un flottant dans l'opération! 30.0 >>> 18 - 9 # Soustraction, opérateur - 9 >>> 45 * 3 # Multiplication, opérateur * 135 >>> 20 / 3 # Division flottante (même avec des entiers!)15 6.666666666666667 # Division entière de l'exemple: 20 = 3 * 6 + 2 >>> 20 // 3 # Division entière (dite euclidienne), opérateur // 6 >>> 20 % 3 # Reste de la division entière, opérateur % 2 >>> 5 ** 3 # Élévation à la puissance, opérateur ** 125 >>> 2 ** 0.5 1.4142135623730951 >>> pow(0.5, 4) # Fonction élévation à la puissance 0.0625 >>> abs(-3.5) # Fonction valeur absolue 3.5 >>> round(34.6732, 1) # Fonction arrondi à n décimales 34.7 Priorité dans les expressions mathématiques (opérateurs associatifs de gauche à droite sauf si précisé) : 1. Expressions parenthésées (…) 2. Accès aux valeurs des variables (x, x.nom, x[index]…, fonction(x)) 13 Comptez ~15 chifres décimaux signifcatifs et des ordres de grandeur jusqu’à 10 ±308. 14 Il existe aussi des opérateurs, que nous ne détaillerons pas ici, travaillant directement au niveau des bits des entiers. 15 Atention, dans la plupart des langages une division d’entiers donne un résultat entier ⇒ 1/2→0
II - Types de base page 15/73 Algorithmique-Programmation 3. Opérateur élévation à une puissance ** (associatif de droite à gauche) 4. Opérateurs unaires positif/négatif + - 5. Opérateurs de multiplication/division * / // % 6. Opérateurs d’addition/soustraction + - Exemples de parenthésage d’expressions : >>> 4 + 3 * 5 ** 2 79 >>> (4 + 3) * 5 ** 2 175 >>> ((4 + 3) * 5) ** 2 1225 >>> 4 + (3 * 5) ** 2 229 Attention, en Python la notation de parenthèses contenant des virgules de séparation est la défnition d’un tuple (conteneur permetant de regrouper plusieurs valeurs). >>> (4 + 3, 5 ** 2) (7, 25) Si vous voyez apparaître des erreurs du genre TypeError metant en cause un 'tuple', vous avez peut- être une expression parenthésée contenant une virgule involontaire. Fonctions mathématiques Les fonctions mathématiques usuelles sont accessibles via une librairie particulière disponible en stan- dard, le module math. Il faut importer ce module (ou bien directement les fonction de ce module) pour pouvoir les utiliser. Ce module contient aussi la défnition des valeurs de pi et e. Les fonctions s’ap- pliquent à des valeurs numériques entières ou fotantes, les angles sont exprimés en radians. >>> from math import pi, e, sin, cos, tan, degrees, radians, log, log10, sqrt, acos, asin, atan, acos, asin, atan, atan2, floor, ceil, trunc, hypot >>> pi # Rapport du périmètre d'un cercle sur son diamètre 3.141592653589793 >>> e # Valeur de la base des logarithmes naturels (népériens) 2.718281828459045 >>> sin(pi/4) # Fonction sinus 0.7071067811865475 >>> cos(1) # Fonction cosinus 0.5403023058681398 >>> tan(pi/4) # Fonction tangente 0.9999999999999999 >>> degrees(2*pi) # Fonction conversion radians → degrés 360.0 >>> radians(90) # Fonction conversion degrés → radians 1.5707963267948966 >>> log(1) # Fonction logarithme naturel (népérien, base e) 0.0 >>> log(e) 1.0 >>> log(e ** 2) 2.0 >>> log10(1) # Fonction logarithme base 10 0.0 >>> log10(1000) 3.0 >>> sqrt(2) # Fonction racine carrée 1.4142135623730951 >>> sqrt(81) 9.0 >>> acos(0.5) # Fonction arc cosinus 1.0471975511965979 >>> asin(1) # Fonction arc sinus 1.5707963267948966 >>> atan(1) # Fonction arc tangente 0.7853981633974483
II - Types de base page 16/73 Algorithmique-Programmation >>> atan2(-3,-4) # Fonction arc tangente x/y (considère signes de x et de y) -2.498091544796509 >>> floor(23.78) # Fonction arrondi à l'entier immédiatement inférieur ou égal 23 >>> ceil(23.78) # Fonction arrondi à l'entier immédiatement supérieur ou égal 24 >>> trunc(23.67672) # Fonction troncature à la partie entière seulement 23 >>> hypot(4,3) # Fonction hypothénuse √(x²+y²) 5.0 Pour les tests d’égalités entre nombres fottants Python fournit une fonction isclose()16 : >>> from math import isclose >>> 0.1 * 0.1 * 0.1 == 0.001 False >>> isclose(0.1 * 0.1 * 0.1, 0.001) True II.2 - Valeurs logiques L’algèbre de Boole17 considère deux valeurs de vérité, vrai et faux. Elle est utilisée couramment, non seulement en mathématiques, mais aussi dans la vie de tous les jours. Elle se retrouve naturellement dans les algorithmes. En algorithmique on utilise simplement des valeurs Vrai et Faux. En Python on utilise le type de données bool dont il existe deux valeurs litérales : False et True. >>> True # Constante booléenne vrai True >>> False # Constante booléenne faux False >>> type(True) II.2.a - Opérations booléennes Comparaisons On obtient souvent des valeurs logiques simplement en comparant des valeurs d’autres types entre elles — il faut bien sûr que ces types soient comparables, que cela ait un sens. Tous ces opérateurs de comparaison et de relation d’ordre, fournissent un résultat booléen : >>> 34 == 2 * 17 # Opérateur test d'égalité == True >>> 27 != 3 * 9 # Opérateur test de différence != False >>> 56 < 12 # Opérateur test strictement inférieur < False >>> 56 > 45 > 4 * 5 # Opérateur test strictement supérieur > True >>> 23 >= 25 # Opérateur test supérieur ou égal >= False Notez le double == pour la comparaison testant l’égalité, et le != pour la comparaison testant la difé- rence. Ces opérateurs de comparaison sont moins prioritaires que les opérateurs mathématiques. Python peut réaliser la conversion directe implicite de nombreuses valeurs vers les booléens, ce qui peut causer certaines incompréhensions. Pour le cours nous passerons explicitement par des opéra- tions de comparaison pour obtenir des booléens. 16 Pour tester l’égalité de x avec 0, il faut tester l’égalité de x+1 avec 1. 17 Du logicien, mathématicien et philosophe Britannique George Boole (1815-1864).
II - Types de base page 17/73 Algorithmique-Programmation Algèbre de Boole Il existe trois opérateurs logiques fondamentaux, disponibles en Python : • Le NON, ou négation, inverse la valeur logique. En Python c’est l’opérateur not : x not x False True True False • Le ET, ou conjonction, fournit une valeur vraie lorsque tous ses opérandes sont vrais. En Python c’est l’opérateur and : x y x and y False False False False True False True False False True True True • Le OU, ou disjonction, fournit une valeur vraie lorsque au moins un de ses opérandes est vrai. En Python c’est l’opérateur or. x y x or y False False False False True True True False True True True True Priorité : ces 3 opérateurs booléens sont moins prioritaires que les opérateurs de comparaison et opéra- teurs mathématiques, et sont évalués dans l’ordre : 1) not, 2) and, 3) or. En cas de doute, n’hésitez pas à utiliser des parenthèses. À partir de ces trois relations logiques fondamentales l’algèbre de Boole défnit une série de relations composées que nous ne détaillerons pas ici. Les opérateurs de base possèdent plusieurs propriétés intéressantes pour transformer et/ou simplifer des expressions logiques, outre la commutativité, l’associativité, et la distributivité entre ET et OU, citons : Propriété ET OU Élément neutre True and x ⇔ x False or x ⇔ x Élément absorbant False and x ⇔ False True or x ⇔ True Simplifcation x and (not x or y) ⇔ x and y x or (not x and y) ⇔ x or y Complémentaire x and not x ⇔ False x or not x ⇔ True Les Lois de De Morgan ofrent un outil supplémentaire de transformation lorsqu’on a une négation de ET ou une négation de OU. not (x or y) ⇔ (not x) and (not y) not (x and y) ⇔ (not x) or (not y) II.3 - Textes Aussi appelés chaînes de caractères (raccourci en « chaîne ») ou encore séquences de caractères ; où chaque symbole du texte est représenté par un caractère : letres alphabétiques, chifres, marques syn- taxiques, espaces… En algorithmique on manipule du texte dès que l’on a des données liées à la langue, que ça soit un caractère, un nom, un mot, une phrase ou encore un texte complet. Dans la description d’un algorithme on note généralement les textes entre guillemets “…” (éventuellement des chevrons «… »).
II - Types de base page 18/73 Algorithmique-Programmation En Python on utilise le type de données str qui stocke les chaînes sous la forme de séquences de carac- tères (comme tout est numérique, sous la forme d’entiers correspondant à des codes de caractères). Les valeurs litérales sont écrites entre des couples de guillemets " ou bien des couples d’apostrophes ' (uti- liser l’un permet de metre l’autre dans le texte), sur la même ligne. Le caractère \, ou backslash, est appelé caractère d’échappement. Combiné à d’autres caractères, il per- met de spécifer des notations particulières dans une chaîne — voir tableau ci-après. Note : dans les exemples ci-après on passe par print() pour éviter que l’interpréteur Python n’afche la forme litérale de la chaîne. >>> print("") # Chaîne vide (contient 0 caractère) >>> print("A") # Chaîne d'un seul caractère18 A >>> print("Un texte simple") Un texte simple >>> print('Un autre') Un autre >>> print("Avec l'inclusion de \"guillemets\" et de \\ dans le texte") Avec l'inclusion de "guillemets" et de \ dans le texte >>> print("Sur\nplusieurs\nlignes") Sur plusieurs lignes >>> print("Du texte\n\tavec des tabulations\n\td'alignement") Du texte avec des tabulations d'alignement >>> print("Caractère OE liés par son code \u0152") Caractère OE liés par son code Œ >>> print("Caractère pi par son nom \N{GREEK SMALL LETTER PI}") Caractère pi par son nom π Il est aussi possible d’exprimer une chaîne en utilisant des paires de triples guillemets ou des paires de triples apostrophes. Cete syntaxe permet de placer, sans échappement, des retours à la ligne (ainsi que des " et ') dans la chaîne. >>> print("""Une chaine "texte" sur plusieurs lignes, - où tous les caractères - comptent jusqu'au triplet de fermeture""") Une chaine "texte" sur plusieurs lignes, - où tous les caractères - comptent jusqu'au triplet de fermeture La fonction str() permet de convertir la plupart des valeurs en leur représentation sous forme de texte : >>> str(184) # Conversion nombre entier en chaîne '184' >>> str(3.14) # Conversion nombre flottant en chaîne '3.14' >>> str(True) # Conversion booléen en chaîne 'True' Qelques séquences utiles avec le caractère d’échappement : Séquence Usage \\ Insère un simple \ \" Insère un " (utile dans une chaîne entre ") \' Insère un ' (utile dans une chaîne entre ') 18 Là où Python utilise une chaîne d’un caractère lorsqu’il n’y a qu’un caractère à traiter, la plupart des langages ont un type caractère spécifque.
II - Types de base page 19/73 Algorithmique-Programmation Séquence Usage \n Insère un retour à la ligne (line feed, code 10) \r Insère un retour chariot (carriage return, code 13) \t Insère une tabulation horizontale (code 9) \f Insère un saut de page (form feed, code 12) \xhh Où hh sont 2 chifres hexadécimaux, insère le caractère correspondant au code unicode sur 2 chifres \uhhhh Idem avec 4 chifres hexadécimaux \Uhhhhhhhh Idem avec 8 chifres hexadécimaux \N{nom} Insère le caractère correspondant au nom unicode II.3.a - Opérations sur les chaînes En algorithmique les opérations de base sur les chaînes doivent permetre au moins la concaténation (mise bout à bout), d’en connaître la longueur (nombre de caractères) et de pouvoir réaliser l’extrac- tion d’une partie de chaîne (sur une longueur à partir d’une position). On considère généralement qu’une série d’opérations de plus haut niveau sont également disponibles (recherche de sous-chaîne, conversion minuscule/majuscule, découpage sur un caractère séparateur…). En Python, une fois constituée en mémoire, une chaîne n’est plus modifable, il faut en construire une nouvelle qui inclue les modifcations voulues. On dit que les chaînes Python sont immuables19. Toutes les opérations de modifcation sur les chaînes produisent donc de nou- velles chaînes. L’opérateur + entre deux chaînes permet la concaténation de celles-ci. L’opérateur * entre une chaîne et un nombre entier permet la répétition de la chaîne. La fonction len() permet de connaître la longueur (nombre de caractères) d’une chaîne. >>> "Je programme" + " en Python" # Concaténation 'Je programme en Python' >>> "Répéter " * 6 # Répétition 'Répéter Répéter Répéter Répéter Répéter Répéter ' >>> len("Le langage Python") # Longueur 17 Les comparaisons entre chaînes sont réalisées simplement en comparant consécutivement les codes des caractères de même index dans les deux chaînes — de tous les caractères, espaces et symboles compris. La première diférence donne la relation d’ordre. Si une chaîne a été complètement parcourue et pas l’autre, alors l’autre est « plus grande ». >>> "Hello" == "Hello" True >>> "Hello" == " Hello " # Blancs significatifs pour la comparaison False >>> "Hello" > "Hella" # Caractère a final dans la seconde chaîne < caractère o True >>> "Hello" < "Hello you" # Seconde chaîne identique au début, mais plus longue True Deux fonctions, chr() et ord(), permetent de passer du code au caractère et vice-versa. >>> chr(937) # Code → caractère 'Ω' >>> ord('Ω') # Caractère → code 937 Un truc pratique : les codes de a à z sont consécutifs, les codes de A à Z sont consécutifs, et les codes de 0 à 9 sont consécutifs. >>> ord('a'), ord('b'), ord('c'), '…', ord('z') 19 Dans d’autres langages les chaînes créées peuvent être modifées, élément à prendre en compte lors de la programmation. On trouve aussi souvent l’anglicisme « immutable »
Vous pouvez aussi lire