Delphi et KyliX des descendants de Pascal


Télécharger Delphi et KyliX des descendants de Pascal

★★★★★★★★★★3.5 étoiles sur 5 basé sur 1 votes.
Votez ce document:

Télécharger aussi :


Version Septembre 2017

Informatique Classe IIB

Programmation en

Python

par :

MM. Ben KREMER, David MANCINI,

Nino SILVERIO, Pascal ZEIHEN, François ZUIDBERG


 


Classe de IIB – Programmation en Python

 

Table des matières

1  Introduction – Premiers pas 1

1.1  Teaser .1

1.2  Informatique 2

1.3  Contenu du cours ..4

1.3.1  Langages de programmation ..4

1.3.2  Langages compilés et langages interprétés .5

1.4  Python 6

1.4.1  Origines de Python ..6

1.4.2  À quoi peut servir Python ? ..6

1.5  L’environnement de programmation Python ..7

1.5.1  IDLE 7

1.5.2  Thonny .8

1.5.3  PyCharm Edu ..9

1.5.4  Les deux modes d’utilisation de Python 9

1.5.5  L’interpréteur (Interpreter Mode) ..9

1.5.6  L’éditeur (script mode) 10

1.6  Debugging .10

1.6.1  Syntax Error .10

1.6.2  Runtime Error .11

1.6.3  Semantic Error 11

1.7  Exercices .11

2  Variables 13

2.1  Définition et dénomination .13

2.2  Valeurs et types 13

2.3  Attribuer une valeur ..14

2.4  Expressions et Opérateurs ..15

2.4.1  Définitions 15

2.4.2  Opérateurs mathématiques ..16

2.4.3  Opérateurs d'affectation = 16

2.4.4  Opérateurs sur les chaînes de caractères ..16

2.5  Entrée / Sortie ..17

2.5.1  Entrée .17

2.5.2  Sortie ..18

2.6  Commentaires ..19

2.7  Modules ..20

2.7.1  Le module math .20

2.8  Exercices .21

2.9  Styleguide ..24

2.9.1  Noms des variables ..24

2.9.2  Opérateurs 25 3 Structure alternative 27

3.1  Problème introductif : achat de photos ..27

3.2  Analyse du problème .27

3.3  Représentation schématique ..27

3.4  Solution ..27

3.5  Syntaxe 28

3.5.1  Syntaxe simplifiée .28

3.5.2  Syntaxe complète ..28

3.5.3  Syntaxe avancée .28

3.6 Les conditions (expressions logiques) 29

3.6.1  Les opérateurs relationnels ..29

3.6.2  Les opérateurs logiques and, or, not 29

3.6.3  Règles de priorité des opérateurs ..29

3.7 Exercices .30

 

Classe de IIB – Programmation en Python

 

4  Structure répétitive .32

4.1    Introduction ..32

4.2    Boucles For 32

4.2.1  Problème introductif : décollage d'une fusée 32

4.2.2  Représentation schématique 32

4.2.3  Solution .33

4.2.4  Syntaxe ..33

4.3    Boucles While 34

4.3.1  Problème introductif 34

4.3.2  Représentation schématique 35

4.3.3  Solution .35

4.3.4  Syntaxe ..35

4.4    Terminaison d'une boucle 35

4.5    Exercices .36

5  Les listes 40

5.1    Problème introductif ..40

5.2    Solution ..40

5.3    Syntaxe 40

5.4    Exercices .42

6  Indices et sous-intervalles (slices) .44

6.1    Notation ..44

6.2    Modification de (sous-)listes 46

6.3    Création automatisée de listes ..47

6.4    Exercices .48

7  Les tuplets (tuples) ..49

7.1    Notation ..49

7.2    Opération sur les tuplets .50

7.3    Application : vecteurs et matrices 51

7.4    Exercices .52

8  Les dictionnaires ..55

8.1    Problème introductif ..55

8.2    Création de dictionnaires .56

8.3    Opérations sur les dictionnaires 57

8.4    Exercices .59

9  Les chaînes de caractères (strings) ..61

9.1    Rappels 61

9.2    Compléments : méthodes utiles 62

10  Les fonctions 63

10.1 Introduction 63

10.2 Définition .64

10.3 Exercices ..65

10.4 Paramètres optionnels 66

10.5 Nombre indéterminé de paramètres .67

10.6 Variables locales et globales 68

10.7 Exercices ..70

11  Les fichiers 73

11.1 Introduction 73

11.2 Les entrées/sorties en mode console ..74

11.2.1  Les noms d'unités ..74

11.2.2  Redirection des entrées/sorties « console » ..75

11.2.3  Redirection des sorties « stdout » et « stderr » .75

11.2.4  Redirection de l'entrée standard « stdin » ..76

11.2.5  Tubes et filtres .76

11.2.6  Réalisation de filtres en Python 77

 

2

Classe de IIB – Programmation en Python

 

11.3 Les fonction de manipulation de fichiers 80

11.4 Exercices résolus ..83

11.5 Exercices à faire 84

11.6 Solutions proposées 86

 


1   Introduction – Premiers pas

1.1   Teaser

 

L’aguichage, ou teasing, est une technique courante au cinéma pour la promotion des superproductions. Il s'agit généralement de bandes-annonces particulièrement courtes. Les producteurs de cinéma font diffuser, longtemps avant la sortie d'un film, une ou plusieurs aguiches (appelées teasers en anglais), c'est-à-dire des séquences courtes et énigmatiques, au message minimaliste et percutant qui ne dévoile presque rien de la production. Ici, le teaser, est un très petit programme qui sert à résoudre une équation du second degré et qui montre de façon concise la beauté, la clarté et la puissance de Python.

Le code source du programme comprend trois parties :

1)    Demander à l’utilisateur d’entrer les trois coefficients du polynôme (lignes 6 à 8);

2)    calculer le delta et puis les deux racines sol1 et sol2 (ligne 11 et lignes 14 à 15); 3) afficher le résultat (ligne 17).

Ce programme est alors démarré et l’utilisateur peut entrer un polynôme, dans ce cas 1x2+4 x+5=0 et les solutions (complexes) sont : x1=?2?1 j et x2=?2+1 j .

Cet exemple illustre quelques atouts du langage Python.

Il est

•   simple

•   clair

•   modulaire

•   extensible

1.2   Informatique

Le terme informatique est un néologisme proposé en 1962 par Philippe Dreyfus pour caractériser le traitement automatique de l’information : il est construit sur la contraction de l’expression « information automatique ». Ce terme a été accepté par l’Académie française en avril 1966, et l’informatique devint alors officiellement la science du traitement automatique de l’information, où l’information est considérée comme le support des connaissances humaines et des communications dans les domaines techniques, économiques et sociaux.

Le mot informatique n’a pas vraiment d’équivalent aux Etats-Unis où l’on parle de Computing Science (science du calcul) alors que Informatics est admis par les Britanniques.

Définition 1 : informatique

L’informatique est la science du traitement automatique de l’information. L’informatique traite de deux aspects complémentaires : les programmes immatériels (logiciel, programme, application, software) qui décrivent un traitement à réaliser et les machines (matériel, hardware) qui exécutent ce traitement. Le matériel est donc l’ensemble des éléments physiques (microprocesseur, mémoire, écran, clavier, disques durs ) utilisés pour traiter les données. Dans ce contexte, l’ordinateur est un terme générique qui désigne un équipement informatique permettant de traiter des informations selon des séquences d’instructions (les programmes) qui constituent le logiciel. Le terme ordinateur a été proposé par le philologue Jacques Perret en avril 1955 en réponse à une demande d’IBM France qui estimait le mot « calculateur » (computer) bien trop restrictif en regard des possibilités de ces machines

Définition 2 : logiciel

Le logiciel (programme, application) est un ensemble structuré d’instructions décrivant un traitement d’informations à faire réaliser par un matériel informatique. Un ordinateur n’est rien d’autre qu’une machine effectuant des opérations simples sur des séquences de signaux électriques, lesquels sont conditionnés de manière à ne pouvoir prendre que deux états seulement.

Ces séquences de signaux obéissent à une logique binaire du type «tout ou rien» et peuvent donc être considérés conventionnellement comme des suites de nombres ne prenant jamais que les deux valeurs 0 et 1 : un ordinateur est donc incapable de traiter autre chose que des nombres binaires. Toute information d’un autre type doit être convertie, ou codée, en format binaire. C’est vrai non seulement pour les données que l’on souhaite traiter (les nombres, les textes, les images, les sons, les vidéos, etc.), mais aussi pour les programmes, c’est-àdire les séquences d’instructions que l’on va fournir à la machine pour lui dire ce qu’elle doit faire avec ces données.

Définition 3 : matériel

Le matériel informatique est un ensemble de dispositifs physiques utilisés pour traiter automatiquement des informations.

L’architecture matérielle d’un ordinateur repose sur le modèle de Von Neumann qui distingue classiquement 4 parties :

 

1.    L’unité arithmétique et logique, ou unité de traitement, effectue les opérations de base.

2.    L’unité de contrôle séquence les opérations.

3.    La mémoire contient à la fois les données et le programme qui dira à l’unité de contrôle quels calculs faire sur ces données. La mémoire se divise entre mémoire vive volatile (programmes et données en cours de fonctionnement) et mémoire de masse permanente (programmes et données de base de la machine).

4.    Les entrées-sorties sont des dispositifs permettant de communiquer avec le monde extérieur (écran, clavier, souris ). Les 2 premières parties sont souvent rassemblées au sein d’une même structure : le microprocesseur (la « puce »), unité centrale de l’ordinateur.

1.3 Contenu du cours

Dans ce cours, nous nous intéresserons aux aspects logiciels de l’informatique à l’aide du langage de programmation Python.

Nous allons écrire des logiciels (nommés programmes par la suite) qui sont des suites de commandes pour résoudre un problème, par exemple des calculs mathématiques comme la résolution d’un système d’équations ou la recherche des racines d’un polynôme. Un programme peut aussi être un calcul symbolique comme la recherche d’un mot dans un texte, le remplacement d’une partie d’un texte par une autre, l’enlèvement des yeux rouges sur une photo, etc.

1.3.1 Langages de programmation

Comme les «langages naturels» (le français, l'anglais…), les langages de programmation sont des systèmes d'expression et de communication. Mais les «phrases» utilisées par ces langages, appelées programmes, forment des textes destinés à être compris par des ordinateurs.

Cependant, les langages utilisés pour communiquer avec les ordinateurs ne sont pas tous considérés comme des langages de programmation. Il s'agit seulement des langages qui, théoriquement, sont suffisamment universels pour exprimer tous les traitements possibles (algorithmes) qu'un ordinateur peut effectuer.

Ne sont pas considérés comme des langages de programmation, les langages d'interrogation de bases de données, et plus généralement les langages dits «de quatrième génération» (L4G en abrégé) et langages SQL (Structured Query Language) qui permettent de réaliser de façon conviviale des applications particulières.

On peut considérer qu'un programme est un texte dépourvu de toute ambiguïté et qui doit être écrit en respectant scrupuleusement les «règles de grammaire» du langage.

Chaque langage de programmation offre les concepts suivants :

•   entrée de données par clavier, fichier et autre

•   sortie de données sur l’écran (affichage) ou dans un fichier

•   expressions et calculs mathématiques

•   structure alternative (if – then – else)

•   structures répétitives (for, while)

1.3.2 Langages compilés et langages interprétés

Compilation

La compilation consiste à traduire la totalité du code source en une fois. Le compilateur lit toutes les lignes du programme source et produit une nouvelle suite de codes appelé programme objet (ou code objet). Celui-ci peut désormais être exécuté indépendamment du compilateur et être conservé tel quel dans un fichier (« fichier exécutable »). Ce fichier peut être exécuté par le système d’exploitation pour lequel il a été compilé, par exemple pour Windows ou pour macOS. Les langages Ada, C, C++ et Fortran sont des exemples de langages compilés. Comme le programme est directement exécuté sur l'ordinateur, il sera en général plus rapide que le même programme dans un langage interprété.

Interprétation

L’interprétation consiste à traduire chaque ligne du programme source en quelques instructions du langage machine, qui sont ensuite directement exécutées au fur et à mesure (« au fil de l’eau »). Aucun programme objet n’est généré. L’interpréteur doit être utilisé chaque fois que l’on veut faire fonctionner le programme. Les langages Lisp et Prolog sont des exemples de langages interprétés.

Semi-compilation

Certains langages tentent de combiner les deux techniques afin d'en tirer le meilleur de chacune. C’est le cas des langages Python et Java par exemple. De tels langages commencent par compiler le code source pour produire un code intermédiaire, similaire à un langage machine (mais pour une machine virtuelle), que l’on appelle bytecode, lequel sera ensuite transmis à un interpréteur pour l’exécution finale. Du point de vue de l’ordinateur, le bytecode est très facile à interpréter en langage machine. Cette interprétation sera donc beaucoup plus rapide que celle d’un code source. Le fait de disposer en permanence d’un interpréteur permet de tester immédiatement n’importe quel petit morceau de programme. On pourra donc vérifier le bon fonctionnement de chaque composant d’une application au fur et à mesure de sa construction. L’interprétation du bytecode compilé n’est pas aussi rapide que celle d’un véritable code machine, mais elle est satisfaisante pour de très nombreux programmes.

1.4 Python

1.4.1 Origines de Python

Python est un langage de programmation objet semi-compilé. Son origine est le langage de script du système d’exploitation Amoeba (1990). Il a été développé par Guido Von Rossum au CWI, à l’Université d’Amsterdam et nommé par rapport au Monthy Python’s Flying Circus.

Depuis, Python est devenu un langage de programmation généraliste qui offre un environnement complet de développement comprenant un interpréteur performant et de nombreux modules. Un atout indéniable est sa disponibilité sur la grande majorité des plates-formes courantes (Windows, macOS, GNU/Linux).

Python est un langage open source supporté, développé et utilisé par une large communauté : 300 000 utilisateurs et plus de 500 000 téléchargements par an.

1.4.2 À quoi peut servir Python ?

Python est un langage puissant, à la fois facile à apprendre et riche en possibilités. Dès l’installation, on dispose de nombreuses fonctionnalités intégrées au langage.

Il est, en outre, très facile d'étendre les fonctionnalités existantes. Ainsi, il existe ce qu'on appelle des bibliothèques qui aident le développeur à travailler sur des projets particuliers. Plusieurs bibliothèques peuvent ainsi être installées pour, par exemple, développer des interfaces graphiques en Python, faire des calculs mathématiques avancés, etc.

Avec Python on peut réaliser:

•   de petits programmes très simples, appelés scripts, chargés d'une mission très précise sur l’ordinateur ;

•   des programmes complets, comme des jeux, des suites bureautiques, des logiciels multimédias, des clients de messagerie…

•   des projets très complexes, comme des progiciels (ensemble de plusieurs logiciels pouvant fonctionner ensemble, principalement utilisés dans le monde professionnel).

Voici quelques-unes des fonctionnalités offertes par Python et ses bibliothèques :

•   créer des interfaces graphiques ;

•   faire circuler des informations au travers d'un réseau ;

•   dialoguer d'une façon avancée avec votre système d'exploitation

1.5 L’environnement de programmation Python

Afin de pouvoir travailler avec Python, il faut créer/installer un environnement de travail/programmation. Cet environnement de travail comprend quatre éléments principaux, qui sont

•   l’interpréteur Python, la base du langage,

•   un débogueur, un outil permettant de traquer/chasser des erreurs

•   des librairies, offrant des fonctionnalités avancées non comprises dans le langage de base, et

•   un éditeur confortable, qui nous met tous ces éléments à disposition dans un environnement convivial.

1.5.1  IDLE

Initialement Python est équipé de l’environnement IDLE, qui est suffisant mais peu confortable.

 

1.5.2  Thonny

Un autre éditeur portable et facile à utiliser est Thonny, un projet open-source disponible pour tous les systèmes d’exploitation majeurs et qui est même l’éditeur principal du Raspberry Pi.

Il peut être téléchargé depuis le site :

 

1.5.3  PyCharm Edu

La société tchèque JetBrains commercialise des environnements professionnels et propose aussi PyCharm Edu, gratuit pour les utilisations non commerciales et qui sera la référence pour le présent cours.

Il peut être téléchargé depuis leur site :

Pour la procédure d’installation de ce produit, veuillez vous référer à :

 

1.5.4  Les deux modes d’utilisation de Python

1.5.5  L’interpréteur (Interpreter Mode)

L’interpréteur se présente par le triple chevron >>> qui est l’invite de Python (prompt en anglais) et qui signifie que Python attend une commande. L’esprit d’utilisation de l’interpréteur est un peu le même que celui d’une calculatrice.

 >>> 2 + 3 * 5

17

>>> a = 6

>>> b = 7 

 >>> a * b

42

L’interpréteur permet

•   de tester du code au fur et à mesure qu'on l'écrit.

•   d'effectuer des calculs.

1.5.6 L’éditeur (script mode)

L’éditeur est un utilitaire permettant d’écrire des programmes. On peut y écrire des scripts, c’est-à-dire des programmes petits ou grands.

= 6

= 7

= a*bprint(c)

42

Remarque

Un nombre décimal s'écrit avec un point et non une virgule.

Les calculs impliquant des nombres décimaux donnent parfois des résultats approximatifs, c'est pourquoi on préférera, dans la mesure du possible, travailler avec des nombres entiers.

1.6 Debugging

Il est très difficile d’écrire des programmes ne comportant pas d’erreurs. C’est pourquoi les environnements de programmation sont pourvus d’outils pour les traquer. La phase consistant à localiser des erreurs est appelée dans le jargon informatique le déboguage (debugging).

1.6.1  Syntax Error

Python ne peut exécuter un programme que si la syntaxe est correcte, sinon l’interpréteur affiche un message d’erreur. Ce type d’erreur est généralement très facile à corriger.

1.6.2  Runtime Error

Un programme syntaxiquement correct peut toujours contenir des erreurs qui n’apparaissent que lors de son exécution. Ce type d’erreur est appelé « runtime error » ou erreur à l’exécution. Ce type d’erreur est déjà plus difficile à traquer car il n’apparaît pas nécessairement lors de chaque exécution et dépend des valeurs des données (exemple : division par 0).

1.6.3  Semantic Error

Un programme qui contient une erreur sémantique peut être exécuté, mais il ne fait pas ce que le programmeur souhaite. Par exemple on veut calculer la somme de deux nombres mais au lieu du symbole + on a utilisé malencontreusement le symbole *. Le programme fait alors exactement ce qu’on a programmé, mais on n’a pas programmé ce qu’on voulait en fait avoir.

Les erreurs sémantiques sont de loin les plus difficiles à traquer. C’est pourquoi les environnements professionnels contiennent des outils pour les traquer (débogueur, etc.)

1.7 Exercices

Exercice 1-1

1.    Lancer l’interpréteur (Python Console)

2.    Calculer

                ?       la somme de 27 et de 15

                ?       la différence de 26 et de 18

                ?       le produit de 6 par 7

                ?       le quotient de 1024 par 512

                ?       247 modulo 60

                ?       247 divisé par 60 (=quotient de la division euclidienne)


 2   Variables

2   Variables

2.1   Définition et dénomination

Une variable est un objet informatique qui associe un nom à une valeur qui peut éventuellement varier au cours du temps.

Les noms de variables sont des identificateurs arbitraires, de préférence assez courts mais aussi explicites que possible, de manière à exprimer clairement ce que la variable est censée référencer.

2.2   Valeurs et types

 

2.3   Attribuer une valeur

Une fois nommée, il est souvent nécessaire de modifier la valeur de la donnée référencée par une variable. C’est le rôle de l’instruction d’affectation. L’affectation est l’opération qui consiste à attribuer une valeur à une variable.

L’instruction d’affectation est notée « = » en Python : variable = expression

Le nom de la variable à modifier est utilisé dans le membre de gauche du signe « = » et la valeur qu’on veut lui attribuer dans le membre de droite.

Le membre de droite de l’affectation est d’abord évalué sans être modifié, puis la valeur obtenue est affectée à la variable dont le nom est donné dans le membre de gauche. Cette opération ne modifie que le membre de gauche de l’affectation. Le membre de droite peut être une constante ou une expression évaluable.

entier = 42 somme = entier + 5

a = 10.57 b = 7.24 quotient = a / b

chaine1 = "Monty" chaine2 = chaine1 + "Python"

L’affectation a ainsi pour effet de réaliser plusieurs opérations dans la mémoire de l’ordinateur :

•   créer et mémoriser un nom de variable,

•   lui attribuer un type bien déterminé,

•   créer et mémoriser une valeur particulière,

•   établir un lien (par un système interne de pointeurs) entre le nom de la variable et l’emplacement mémoire de la valeur correspondante.

2.4 Expressions et Opérateurs

2.4.1 Définitions

Un opérateur est un symbole utilisé pour effectuer un calcul entre des opérandes.

Un opérande est une variable ou un littéral ou bien une expression.

Une expression est une suite valide d'opérateurs et d'opérandes.

Par exemple, dans l'expression suivante il y a deux opérateurs (= et +) et trois opérandes (x, y et 2).

 x = y + 2

Il existe différents types d'opérateurs :

•   les opérateurs mathématiques

•   les opérateurs d'affectation

•   les opérateurs sur les chaînes de caractères

•   les opérateurs logiques

•   les opérateurs de comparaisons

•   les opérateurs sur les séquences

Les opérateurs peuvent avoir des sens différents en fonction des types d'opérandes sur lesquels ils agissent.

2.4.2  Opérateurs mathématiques

 

2.4.3  Opérateurs d'affectation =

•   Affectation simple      x = 2

•   Affectation multiple     x = y = z = 3

•   Affectation parallèle    x, y = 1 , 0,5

2.4.4 Opérateurs sur les chaînes de caractères

Les chaînes de caractères sont de type str. Comme délimiteurs de chaînes constantes, on peut soit écrire des apostrophes soit des guillemets, mais pour une même chaîne les deux délimiteurs doivent être identiques :

'une chaîne'

"une autre chaîne"

'Il dit : "Bonjour !"'

"Il dit : \"Bonjour !\""

"l'un et l'autre"

'l\'un et l\'autre'

Les quatre derniers exemples illustrent que si l'on désire inclure dans la chaîne le symbole du délimiteur choisi, on doit le faire précéder d'un backslash « \ » .

Les deux opérateurs simples applicables aux chaînes de caractères sont la concaténation et la multiplication :

 print("Monty" + 'Python')

MontyPython

À ne pas confondre avec :  print("Monty", 'Python')

Monty Python

Si plusieurs arguments se succèdent pour print, une espace est automatiquement insérée entre les différents arguments.

 print(3 * "Monty")

MontyMontyMonty  print('Python' * 5)

PythonPythonPythonPythonPython

2.5 Entrée / Sortie

2.5.1 Entrée

Dans un programme, il est très pratique de pouvoir demander à l’utilisateur de saisir une chaîne de caractères.

Pour cela, Python dispose d’une instruction input(). Cette instruction renvoie une chaîne de caractères.

Ainsi, si l’utilisateur tape le mot Luxembourg, le résultat stocké est 'Luxembourg'.

>>> mot1 = input()

Luxembourg                  # ceci est tapé par l’utilisateur

>>> print(mot1)  Luxembourg

Pour faciliter l’usage d’un tel programme, on peut passer un texte à afficher comme argument à l’instruction input() :

>>> mot2 = input("Entrez un pays : ")

Entrez un pays : Belgique

>>> print(mot2)  Belgique

Pour utiliser des nombres entrés par un utilisateur, on doit convertir la chaîne de caractères en un type numérique. Pour la conversion de la chaîne de caractères en un nombre entier, on utilise la fonction int() :

>>> nombre1 = int(input("Entrez un nombre : "))

Entrez un nombre : 12

>>> nombre1 + 13

 25

2.5.2 Sortie

Les affichages sont en Python réalisés à l'aide de l'instruction print(text, end="final"): elle affiche le texte et termine cet affichage avec final. Si la partie end="final" n'est pas précisée Python utilise end="\n", ce qui signifie que l'on passe à la ligne après l'affichage de texte.

Voici quelques exemples qui illustrent différentes utilisations possibles de print().

 print("Bonjour !")  # affiche et passe à la ligne

 print("toto","titi")  # titi suit toto, passage à la ligne

print("toto",end="+") # termine par +, pas de passage à la ligne print("titi")         # titi s'ajoute à toto et passage à la ligne a = 42

                    print(a)              # a est converti en chaîne de caractères

 print() # simple passage à la ligne

2.6 Commentaires

On peut écrire à l'intérieur du code-source des commentaires, c'est-à-dire des explications (p.ex. en français) ou tout autre texte que le programmeur juge utile et que l'interpréteur n'est pas supposé de lire. Le symbole # signale que tout le texte qui le suit jusqu'à la fin de cette ligne est un commentaire.

 # un commentaire

Pour des commentaires s'étendant sur plusieurs lignes entières, on n'a pas besoin de commencer chaque ligne avec le symbole #, mais on peut écrire tout le commentaire entre les délimiteurs

''' commentaire suite du commentaire suite du commentaire ''' ou

""" commentaire suite du commentaire suite du commentaire """

Ce sont les mêmes délimiteurs que ceux utilisés pour les chaînes de caractères (qui eux ne sont pas des commentaires !), mais triplés.

Quelques recommandations :

•   Écrire un commentaire au début de chaque fichier-source, pour expliquer en quelques mots ce que le programme est censé faire.

•   Écrire un commentaire, au début ou à la fin de chaque fichiersource, pour donner les références lorsqu'on utilise des parties de code ou des algorithmes sous copyright ou copiés-collés du Web.

•   Écrire un commentaire par bloc de code non définitif, pour préciser quel type de maintenance est requis: faut-il corriger ou compléter le code, faut-il distinguer encore des cas particuliers? Cela est notamment utile lors des devoirs en classe et les examens : guider le correcteur dans sa tâche rapporte généralement plus de points que toute tentative de bluff ou de code-bidon.

•   Écrire un commentaire pour chaque déclaration d'une nouvelle classe, pour expliquer brièvement à quoi elle sert.

•   Écrire un commentaire pour chaque fonction, pour en préciser le fonctionnement ou les algorithmes utilisés. Exception : si le code de la fonction est assez trivial et son nom est bien choisi, le commentaire peut être omis.

•   Écrire un commentaire pour chaque variable rendue globale dans une fonction afin d'expliquer pourquoi on a besoin de la variable extérieure et quel est l'effet éventuel subi par elle.

•   Écrire un commentaire pour chaque bloc de code que l'on juge particulièrement difficile/astucieux/incompréhensible.

•   Écrire un commentaire pour chaque bloc de code dont l'exécution dépend de la sous-version de Python utilisée (p.ex. un code qui fonctionne bien sous Python 3.6, mais qui cause des problèmes sous Python 3.5).

•   Et surtout: ne pas écrire d'autres commentaires, qui risquent de détourner l'attention du lecteur.

2.7 Modules

Il s’agit d’une sorte de bibliothèque (un regroupement de fonctions prédéfinies) qui, une fois importée, permet d’accéder à de nouvelles fonctions.

2.7.1 Le module math

C’est un module qui permet d’avoir accès aux fonctions mathématiques comme le cosinus (cos), le sinus (sin), la racine carrée (sqrt), le nombre pi et bien d’autres

>>>from math import *     # importation du module

>>>cos(pi)       # cosinus d'un angle en radian -1.0

>>>sqrt(25)     # racine carrée

5.0

Pour une liste complète des possibilités offertes par ce module, veuillez vous référencer à ? Python module index ou aux liens sur le site du cours.

2.8 Exercices

Exercice 2-1 (Faire les premiers pas avec les chaînes de caractères)

Que va afficher la portion de code suivante ? Introduisez le programme dans Python et vérifiez votre résultat !

print ('hello world') print('hello world', 6 * 7) print('I like to add ', 4, ' to ', 20, ' and I get ', 20 + 4) print('hello' * 2)

Exercice 2-2 (Faire les premiers pas avec des variables)

Que va afficher la portion de code suivante ? Introduisez le programme dans Python et vérifiez votre résultat !

a = 2 b = 9

print(a + b) c = a * b print(c) d = a – (b + c) ** 2 print(d)

Exercice 2-3

Écrivez une instruction qui calcule et affiche le résultat de chacune des expressions suivantes.

a)  15+7?4+2÷3

b)  17?[14?3?(7?2?8)]?2

        c)        

        d)        

e)       

f)  

Exercice 2-4

Effectuez (sans l’aide de l’ordinateur) les expressions suivantes :

a)    86 // 15

b)    86 % 15

c)    (5-(3-7*2)*2)*2

d)    sqrt(9**2+19)

e)    145-(145//13)*13

f)  288 % 18

g)    288 / 18

Exercice 2-5 : Swap

a)    Écrivez un programme qui lit 2 nombres entiers du clavier et les affecte respectivement aux variables nombre1 et nombre2.

b)    Écrivez ensuite des instructions qui permettent d’échanger (swap) les valeurs des variables nombre1 et nombre2.

Exercice 2-6 : Moyenne arithmétique

Écrivez un programme qui lit 2 nombres réels du clavier, calcule leur moyenne (arithmétique) et l’affiche.

Exercice 2-7 : Moyenne harmonique

Écrivez un programme qui lit 2 nombres réels strictement positifs du clavier, calcule leur moyenne harmonique et l’affiche.

Rappelons que la moyenne harmonique de 2 nombres strictement positifs est donnée par la formule:

                                                                               1    1

+

                                                                     1      a    b

=

                                                                    mh               2

Il est recommandé de transformer la formule avant de l’utiliser dans le programme!

Exercice 2-8 : TVA

Écrivez un programme qui lit un nombre réel strictement positif qui représente le prix d’un article quelconque (TVA de 17% comprise). Le programme calculera le prix hors TVA de l’article et l’affichera.

Exercice 2-9 : Loi des résistances

Écrivez un programme qui lit du clavier 4 nombres réels, strictement positifs, représentant 4 résistances d’un circuit en parallèle. Le programme calculera ensuite la résistance résultante par la loi d’Ohm et l’affichera.

1

Rtotale=

                                                                                         R1         R2                    Rn

Exercice 2-10 : Aire d’un triangle par la formule d’Héron

Écrivez un programme qui lit 3 nombres réels, représentant les mesures des 3 côtés d’un triangle. (Ces nombres doivent donc vérifier l’inégalité triangulaire).

Le programme devra ensuite calculer, à l’aide de la formule d’Héron, l’aire du triangle correspondant à ces mesures et l’afficher.

Exercice 2-11 : Division euclidienne

Écrivez un programme qui lit le dividende et le diviseur non nul d’une division  et qui affiche la division euclidienne résultante.

Exemple : Si le dividende est 34 et le diviseur 8, le programme devra afficher 34=8*4+2.

Exercice 2-12 : Suite arithmétique

Écrivez un programme qui lit le premier terme et la raison d’une suite arithmétique. Le programme lira ensuite un nombre naturel n, calculera le ne terme ainsi que la somme des n premiers termes de la suite et les affichera.

2.9 Styleguide

2.9.1 Noms des variables

•   Un nom de variable est une séquence de lettres (a z , A Z) et de chiffres (0 9), qui doit toujours commencer par une lettre.

•   La « casse » est significative : les caractères majuscules et minuscules sont distingués. Ainsi, python, Python, PYTHON sont des variables différentes.

•   Le langage lui-même peut se réserver quelques noms comme c’est le cas pour Python. Ces mots réservés ne peuvent donc pas être utilisés comme noms de variable. Exemples : and, del, for, is, return, try, not, if, class, import, in, print, break, while, …

•   Lettres seules, en minuscule : pour les boucles et les indices.

for x in range(10):     print(x)

i = get_index() + 12 print(ma_liste[i])

•   Lettres minuscules avec blanc souligné : pour les modules, variables, fonctions et méthodes. une_variable = 10

def une_fonction():

    return locals() or {}

class UneClasse:     def une_methode_comme_une_autre(self):         return globals()

•   Lettres majuscules et blanc souligné : pour les (pseudo) constantes.

 MAX_SIZE = 100000  # à mettre après les imports

•   Camel case : nom de classe.

class CeciEstUneClasse:     def methodiquement(self):         pass

•   Si le nom contient un acronyme, on fait une entorse à la règle :

class HTMLParserCQFDDDTCCMB:     def methodiquement(self):         pass

2.9.2 Opérateurs

Les opérateurs doivent être entourés d’espaces :

variable = 'valeur' 1 + 2 À éviter :

variable='valeur'

1+2 Exception :

Lorsqu'on groupe les opérateurs mathématiques ayant la priorité la plus haute pour distinguer les groupes :

a = x*2 - 1 b = x*x + y*y c = (a+b) * (a-b)


 3   Structure alternative

3   Structure alternative

3.1   Problème introductif : achat de photos

Un magasin de photos propose le développement au tarif de 0,16 € l’unité.

Le tarif devient 0,12 € l’unité pour une commande d’au moins 75 photos.

On veut élaborer un algorithme donnant le montant dépensé pour un nombre n de photos à développer.

3.2   Analyse du problème

Comme le calcul se fait de manière différente selon le nombre de photos, on a besoin d’une nouvelle structure qui permet d’utiliser une instruction conditionnelle (ou test) dans l’algorithme :

•   Si le nombre de photos n est strictement inférieur à 75, alors le montant est n × 0,16.

•   Si le nombre de photos n est supérieur ou égal à 75, alors le montant est n × 0,12.

3.3   Représentation schématique

 

ordinogramme (flowchart)

3.4   Solution

n = int(input("Combien de photos voulez-vous faire développer? "))

if n >= 75:

    montant = n * 0.16 else :

    montant = n *  0.12 print ("Monant à payer :" + montant)

3.5 Syntaxe

3.5.1 Syntaxe simplifiée

if <condition>:     <instruction(s)>

3.5.2 Syntaxe complète

if <condition>:     <instruction(s)> else :     <instruction(s)>

3.5.3 Syntaxe avancée

if <condition>:     <instruction(s)> elif <condition2>:     <instruction(s)> elif <condition3>:     <instruction(s)> else :     <instruction(s)>

L’instruction elif permet de vérifier de multiples expressions et d'exécuter un bloc d'instructions dès qu'une des conditions est vérifiée.

Les instructions else et elif sont optionnelles. Contrairement à l'instruction else, on peut mettre autant d'instructions elif que l'on veut.

3.6 Les conditions (expressions logiques)

3.6.1 Les opérateurs relationnels

 

Deux opérandes de type string (chaîne de caractères) peuvent être comparées à l'aide des opérateurs relationnels.

"ALBERTA" > "ALBERT" et "BERNARD" > "ALBERTA"

L’ordre de classement des chaînes est l'ordre lexicographique (celui appliqué dans les lexiques). Les majuscules précèdent les minuscules.

Bien entendu, les opérateurs relationnels doivent respecter les règles stylistiques expliquées au point 2.9.

3.6.2 Les opérateurs logiques and, or, not

Les opérateurs logiques (not, and, or en français respectivement non, et, ou) permettent de combiner plusieurs conditions, par exemple :

•   (A>3) et (B<2) n'est vrai que si les deux conditions sont vérifiées à la fois ;

•   (A>3) ou (B<0) est vrai si au moins une des conditions est vraie.

Valeur de X Valeur de Y X and Y           X or Y             Valeur de X         not X

True True True True True False True False False True False True

False True False True False False False False

3.6.3 Règles de priorité des opérateurs

1.    ** (exponentiation)

2.    -, + (signe)

3.    *, /, //, %

4.    +, -

5.    ==, <=, >=, <, >,!=

6.    not

7.    and

8.    or

 

3.7 Exercices

Exercice 3-1

Quel est le résultat des opérations suivantes ?

•   6 <= 10

•   3 == 3

•   not False

•   (3 <= 1) and (2 > 0)

•   (3 > 1) and (2 > 0)

•   5 > 4

•   not (3 < 2)

•   (3 > 1) or (2 > 0)

•   3 != 3

•   not True

•   (3 <= 1) or (2 > 0)

Exercice 3-2

Écrivez un programme qui affiche le quotient de deux nombres lus au clavier. Respectez le cas où le diviseur est égal à 0.

Exercice 3-3

Écrivez un programme qui calcule la valeur absolue d'un nombre (positif ou négatif) sans utiliser la fonction .

Exercice 3-4

Écrivez un programme qui vérifie si un nombre lu au clavier est divisible par 2.

Exercice 3-5

Écrivez un programme qui affiche le plus grand de 2 nombres sans utiliser la fonction max.

Exercice 3-6

Écrivez un programme qui affiche le plus grand de 3 nombres sans utiliser la fonction max.



Exercice 3-7

Modifiez les valeurs de trois variables A, B, C entrées au clavier de manière à avoir A ? B ? C.

Exercice 3-8

Afficher la moyenne de 3 nombres lus au clavier. La moyenne est arrondie vers le haut. Le programme affiche un message « moyenne insuffisante », si elle est inférieure à 30, sinon il affiche « moyenne suffisante ».

Exercice 3-9

Imprimez le signe du produit de deux nombres sans faire de multiplication.

Exercice 3-10

Imprimez le signe de la somme de deux nombres sans faire d'addition.

Exercice 3-11

Soit une équation de la forme ax2+bx+c=0.

a)    Résolvez cette équation en supposant que a ? 0.

b)    Écrivez un nouveau programme qui tient compte du fait que les paramètres a, b, c peuvent être nuls.

Exercice 3-12

Les trois premiers chiffres d'un code EAN (code-barres) à 11 chiffres indiquent dans quel pays l'entreprise est membre du système EAN.

Déterminez si un code-barres donné correspond à un produit fabriqué par une entreprise située en Belgique ou au Luxembourg, sachant que le nombre formé par ces trois premiers chiffres doit se situer entre 540 et 549.

Par exemple, le produit avec le code-barres 5 450515 007806 est produit par une société ayant son siège social en Belgique ou au Luxembourg.

4   Structure répétitive

4.1   Introduction

Les programmes rencontrés jusqu’à présent sont d’une utilité très limitée. En effet le gain de temps réalisé à l’aide de l’ordinateur est quasi nul (par rapport à une calculatrice par exemple). L’unique avantage provient du fait qu’un même programme peut être réutilisé pour différentes valeurs des données. Cette situation va changer radicalement dans ce chapitre. Le mécanisme de structure répétitive permet d’exécuter plusieurs fois une certaine partie d’un programme !

4.2   Boucles For

4.2.1  Problème introductif : décollage d'une fusée

On veut élaborer un algorithme qui affiche successivement en passant à la ligne (après chaque nombre) 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, décollage. On pourrait bien sûr écrire

print(10) print(9)

print(1) print("décollage")

Mais si on replace 10 par 100, vous ne serez plus d’accord. On va donc demander à l’ordinateur de répéter des instructions plusieurs fois.

4.2.2  Représentation schématique

 

ordinogramme (flowchart)

4.2.3  Solution

for i in range(10,0,-1) :

    print(i) print("Décollage !")

4.2.4  Syntaxe

for <itérateur> in <liste de valeurs>:     <instruction(s)>

Avec Python, on dispose de plusieurs moyens de créer une liste de valeurs. Les listes seront traitées dans le prochain chapitre. Les exemples ci-dessous permettent de débuter.

•   On fournit tous les éléments à considérer

MesNombres=[4,5,7]

Pays=["Argentine","Bolivie","Chili","Danemark","Estonie","France"]

•   On utilise la fonction range(start,stop[,step]) range permet de créer rapidement une liste d’entiers, sans devoir les écrire. Attention, la valeur stop n’est pas comprise dans la liste ! range(11) équivaut à [0,1,2,3,4,5,6,7,8,9,10]. range(3,7) équivaut à [3,4,5,6].

range(6,1,-1) équivaut à [6,5,4,3,2].

•   On utilise une chaîne de caractères

Les chaînes de caractères ont un comportement de listes. Elles sont donc utilisables dans une boucle for.

for lettre in "coucou" :    print(lettre)

4.3   Boucles While

4.3.1  Problème introductif

Un algorithme célèbre circule depuis de nombreuses années dans les milieux mathématiques. Il est à l'origine de la conjecture de Collatz, du nom du mathématicien allemand Lothar Collatz (1910 – 1990), encore appelée problème (ou conjecture) de Syracuse, du nom d'une université américaine qui a contribué à le faire connaître, problème 3x+1, ou conjecture d'Ulam, du nom de Stanislas Ulam (1909 – 1984), qui l'a longtemps étudiée.

•   On prend un nombre entier naturel (non nul). S'il est pair, on le divise par 2, s'il est impair, on le multiplie par 3 et on ajoute 1.

•   On recommence avec le nombre obtenu

Si on répète ce procédé, on peut observer qu'on tombe toujours dans le cycle 4 ® 2 ® 1, qui se répète indéfiniment.

Exemple : 18 ® 9 ® 28 ® 14 ® 7 ® 22 ® 11 ® 34 ® 17 ® 52 ® 26 ® 13 ® 40 ® 20 ® 10 ® 5 ® 16 ® 8 ® 4 ® 2 ® 1

À l'aide de puissants ordinateurs, tous les entiers jusqu'à 5  10· 18 ont été testés. Tous vérifient cette propriété. De nombreuses variantes de l'algorithme ont été étudiées, parfois avec succès (remplacer 3 par un autre nombre premier, ajouter ou soustraire un autre nombre que 1, …) mais personne n'a jamais pu démontrer que, en partant d'un entier quelconque dans le problème de Syracuse, on tombe dans le cycle 4 ® 2 ® 1.

Le but du problème est d'afficher, pour un nombre donné, la suite des nombres produits en appliquant les règles décrites plus haut, jusqu'au premier 1 rencontré.

Pour résoudre le problème, on ne peut pas utiliser une boucle for puisqu'on ne connaît pas à l'avance le nombre d'itérations qu'il nous faut.

4.3.2 Représentation schématique

 

ordinogramme (flowchart)

4.3.3 Solution

x = int(input("Entrez la valeur de x :")) while x > 1:     print(x)     if (x % 2 == 0) : x = x / 2     else : x = 3 * x + 1 print(1)

4.3.4 Syntaxe

while <condition>:     <instruction(s)>

4.4 Terminaison d'une boucle

Lors de la conception d’une boucle, il est essentiel de veiller à ce que la boucle se termine, c’est-à-dire qu’après un nombre fini de passages la condition de boucle va finir par ne plus être vérifiée.

i = 1 while i <= 5:     puiss = puiss * 2

Cette boucle est mal conçue, car la seule variable i de la condition n’est pas modifiée dans le corps de boucle. À chaque passage l’évaluation de la condition donne le même résultat et le programme ne va plus sortir de la boucle.

4.5 Exercices

Exercice 4-1

On donne la partie de programme (toutes les variables sont de type int) :

result = 0 term = 7 for i in range(6): result = result + term     print(result)

Simulez l’exécution de ce programme en représentant dans un tableau les valeurs successives des variables. Que va afficher le programme ?

Introduisez le programme dans Python et vérifiez votre résultat !

Exercice 4-2

On donne la partie de programme (toutes les variables sont de type int) :

result = 1 factor = 5 while factor > 1:

    result = result * factor factor = factor - 1 print(result)

Simulez l’exécution de ce programme en représentant dans un tableau les valeurs successives des variables. Que va afficher le programme ?

Introduisez le programme dans Python et vérifiez votre résultat !

Exercice 4-3

Réécrivez le programme de l'exercice 4-1 à l’aide d’une boucle while.

Exercice 4-4 Somme de n nombres lus du clavier

Écrivez un programme qui lit d’abord le nombre naturel n, représentant le nombre de termes à ajouter. Ensuite le programme va lire n nombres réels du clavier, calculer leur somme et l’afficher.

Allez-vous utiliser une boucle for ou une boucle while ? Expliquez votre choix !

Exercice 4-5 Somme de nombres lus du clavier

Écrivez un programme qui calcule et affiche la somme de nombres réels lus successivement au clavier.

Le programme continue jusqu’à ce que l’utilisateur entre le nombre 0. S’il entre 0 comme premier nombre, le programme affichera 0.

Allez-vous utiliser une boucle for ou une boucle while ? Expliquez votre choix !

Exercice 4-6

Écrivez un programme qui lit le premier terme et la raison d’une suite arithmétique. Ensuite le programme lira un nombre naturel n et il calculera par sommation et affichera le ne terme et la somme des n premiers termes de la suite.

Dans cet exercice, on n’utilisera pas les formules des suites arithmétiques mais seulement la définition par récurrence.

Exercice 4-7

Même question pour une suite géométrique.

Exercice 4-8

La factorielle d’un nombre naturel n, notée n! est définie par :

?0!?1

???n?1? !? n!??n?1?

Ainsi si n n’est pas nul on a:

n!=n (n-1)(n-2) 32 1 ·         ·           ·           · · ·

et en particulier 1!=1, 2!=2 1=2, 3!=3 2 1=6, 4!=4 32 1=24 etc.·       · ·          · · ·

a)    Écrivez un programme qui lit un nombre naturel n et qui calculera et affichera ensuite n! par une boucle for.

b)    Même question mais avec une boucle while.

Exercice 4-9 (*) PGCD par l’algorithme d’Euclide (par division)

Les formules d’Euclide pour trouver le pgcd de 2 nombres naturels non nuls par division sont :

?pgcd(a,0) ? a

??pgcd(a,b) ? pgcd?b,a?

??pgcd(a,b) ? pgcd(amodb,b) si a ? b ? 0

Écrivez un programme qui lit les 2 nombres naturels a et b et qui calcule et affiche leur pgcd en utilisant ces formules.

Exercice 4-10 (*) PGCD par l’algorithme d’Euclide (par soustraction)

Les formules d’Euclide pour trouver le pgcd de 2 nombres naturels non nuls par soustraction sont :

?pgcd(a,a) ? a

??pgcd(a,b) ? pgcd(b,a)

??pgcd(a,b) ? pgcd(a ?b,b) si a ? b

Écrivez un programme qui lit les 2 nombres naturels a et b et qui calcule et affiche leur pgcd en utilisant ces formules.

Exercice 4-11 (*) Test de primalité

Écrivez un programme qui lit un nombre naturel non nul n et qui vérifie ensuite si n est premier. Vous pourrez améliorer le programme en n’essayant que les diviseurs potentiels inférieurs ou égaux à  .

Exercice 4-12 (*) Puissance rapide

Écrivez un programme qui calcule la puissance de deux nombres de manière « rapide » . La puissance rapide est définie à l'aide des propriétés suivantes :

?a0 ?1 ???a2n ? ?a2?n

??a2n?1 ? a2n ?a

?

Le programme n’est pas très différent de la puissance simple.

À l’intérieur de la boucle, l’exécution diffère selon la valeur de l'exposant.

Si l'exposant est pair, on peut appliquer la formule a2n ??a2?n . Cela consiste à remplacer la base par son carré et à réduire l’exposant de moitié.

Si l'exposant n’est pas pair, le programme applique le même algorithme que la puissance par produits successifs.

Remarquons que dans ce cas, l’exposant est diminué de 1 et qu’il va donc devenir pair pour le prochain passage dans la boucle ! Donc l’exposant est réduit de moitié après au plus deux passages dans la boucle. Ainsi pour n’importe quel exposant inférieur à 1024 le nombre de produits à calculer ne va pas dépasser 20 (210 = 1024), alors que 21000 nécessite exactement 1000 produits avec l’algorithme simple !

Exercice 4-13 (*) Table de multiplication

Écrivez un programme qui calcule et affiche une table de multiplication (« Einmaleins ») de 00 jusqu’à 10 10. L’affichage doit se faire sous forme de tableau «· · bien formaté ».

Exercice 4-14 (**) Factorisation première

En vous basant sur l’exercice 4-11, écrivez un programme qui lit un nombre naturel non nul n et qui calcule et affiche ensuite la décomposition en facteurs premiers de ce nombre :

Exemple : Pour 360, le programme affichera : 360=2 22 3 35· · · · ·

Exercice 4-15 (***) Factorisation première (produit de puissances)

Même question qu’à l’exercice précédent, mais on demande d’afficher le résultat comme produit de puissances.

Exemple : Pour 360, le programme affichera : 360=2^3 3^25¹·        ·

Exercice 4-16 (**) Conversion décimale ? binaire

Écrivez un programme qui lit un nombre naturel (en notation décimale) non nul

n. Le programme transformera et affichera ensuite ce nombre en notation binaire.

Exemple :     Pour 43, on affichera : 101011 car

                               43 = 1  · 25 + 0  2· 4 + 1  2· 3 + 0  2· 2 + 1  2· 1 + 1  2· 0

Exercice 4-17 (**) Conversion binaire ? décimale

Écrivez un programme qui lit un nombre naturel (en notation binaire) non nul n. Le programme transformera et affichera ensuite ce nombre en notation décimale.

Exemple : Pour 101011, on affichera : 43.

Le programme n’a pas besoin de vérifier si le nombre donné est effectivement en écriture binaire (seulement chiffres 0 et 1).

5   Les listes

5.1   Problème introductif

On veut écrire un programme qui permet d'effectuer certaines opérations (somme, différence, produit, évaluation en un point x, ) sur des polynômes.

Les types de variables utilisés jusqu'à maintenant ne sont pas suffisants pour pouvoir stocker les coefficients d'un polynôme, d'autant plus que le nombre de valeurs à retenir dépend du degré du polynôme.

Nous allons donc utiliser une liste pour stocker les différents coefficients. Les coefficients seront stockés de telle manière à ce que l'indice du coefficient dans la liste correspond à sa puissance de x dans le polynôme. Dans un premier temps, nous allons nous contenter d'écrire un programme qui demande à l'utilisateur d'entrer le degré d'un polynôme et ensuite les différents coefficients.

5.2   Solution

d = int(input("Entrez le degré du polynôme ")) poly = [] for i in range(d+1) : poly.append(float(input("Entrez le coefficient de puissance " + i)))

5.3 Syntaxe

•   Créer une liste

Pour créer une liste, rien de plus simple :  liste = []

•   Ajouter un élément à une liste

Vous pouvez ajouter les éléments que vous voulez lors de la création de la liste.

 liste = [1, 2, 3]

On peut également ajouter des éléments après la création de la liste avec la méthode append.  liste.append(1)

•   Afficher le contenu d'une liste  print(liste)

On peut également afficher un élément d'une liste grâce à son indice :  liste[2]

affiche le 3ème élément de la liste (pour rappel, on commence à compter à partir de 0).

•   Modifier un élément d'une liste

liste = ["a","d","m"] liste[2] = "z" print(liste)

["a", "d", "z"]

•   Supprimer un élément d'une liste

On peut supprimer un élément avec la fonction del grâce à son indice :

liste = ["a", "b", "c"] del liste[1] print(liste)

["a", "c"]

Il est également possible de supprimer une entrée d'une liste avec sa valeur avec la méthode remove.

liste = ["a", "b", "c"] liste.remove("a") print(liste)

["b", "c"]

•   Inverser les valeurs d'une liste

Vous pouvez inverser les items d'une liste avec la méthode reverse.

liste = ["a", "b", "c"] liste.reverse() print(liste)

["c", "b", "a"]

•   Compter le nombre d'items d'une liste

Il est possible de compter le nombre d'items d'une liste avec la fonction len.

liste = [1,2,3,5,10] len(liste)

5

•   Compter le nombre d’occurrences d'une valeur

Pour connaître le nombre d’occurrences d'une valeur dans une liste, vous pouvez utiliser la méthode count.

liste = ["a","a","a","b","c","c"] liste.count("a")

3  liste.count("c")

2

•   Trouver l'indice d'un élément donné

La méthode index vous permet de connaître la plus petite position de l'item cherché.

liste = ["a","a","a","b","c","c"] liste.index("b")

3

•   Trouver un item dans une liste

Pour savoir si un élément est dans une liste, vous pouvez utiliser le mot clé in.

liste = [1,2,3,5,10] 3 in liste True

 11 in liste False

5.4 Exercices

Exercice 5-1

Écrivez un programme qui demande à l’utilisateur 5 réels, les stocke dans une liste et affiche à la fin le contenu de la liste.

Exercice 5-2

Remplissez une liste avec 20 entiers aléatoires compris entre 1 et 100. Affichezla puis calculez le minimum, le maximum, la somme, la moyenne et l’écart type des valeurs de la liste et affichez-les.

Exercice 5-3

Remplissez une liste avec 30 entiers aléatoires compris entre 10 et 25. Comptez le nombre d’occurrences (fréquence) d’un entier entré par l’utilisateur. Inversez ensuite l’ordre des nombres dans la liste et affichez ensuite la liste réarrangée.

Exercice 5-4

On vous donne le numéro d’un jour d’une année. Déterminez le jour et le mois en question.

Exercice 5-5 Affichage d'un polynôme

Adaptez le programme introductif afin qu'il affiche le polynôme sous forme de texte.

Exemple :

La liste poly[1, 2, 3] sera affichée en tant que polynôme comme 3x^2 + 2x + 1.

Exercice 5-6 Évaluation d'un polynôme

Demandez à l’utilisateur une valeur réelle pour évaluer le polynôme en utilisant le schéma de Horner.

Exercice 5-7 Dérivée d'un polynôme

Calculez la dérivée d'un polynôme et affichez le polynôme résultant.

Exercice 5-8 (***) Simulation d’un tirage Lotto

Un joueur peut choisir 6 nombres entiers entre 1 et 49. Faites la saisie des nombres proposés par le joueur et mémorisez-les à l’aide d’une liste. Veillez à ce les 6 nombres soient distincts deux à deux.

Effectuez ensuite le tirage. Utilisez à nouveau une liste pour mémoriser le tirage. Veillez à ce qu’il y ait exactement 6 nombres différents.

Déterminez ensuite combien de nombres le joueur a deviné correctement et affichez le tirage ainsi que les nombres correctement devinés.

6   Indices et sous-intervalles (slices)

6.1 Notation

Nous avons vu dans les sections précédentes comment accéder aux éléments d’une chaîne (string) ou d’une liste. Un indice n ? 0 accède à l’élément numéro n + 1 :

s = "Albert Einstein" s[7]

'E' liste = [2, 3, 5, 7, 11, 13] liste[4]

11

Des indices strictement négatifs accèdent aux éléments à partir de la fin ; -1 renvoie au dernier élément, -2 à l'avant-dernier, etc. :

 s[-1]

'n'  liste[-3]

7

Il est également possible d’extraire des sous-chaînes ou sous-listes. On utilise comme indice un intervalle semi-ouvert (qu'on noterait en mathématiques

[a,b[ ) :

 s[2:6]

'bert'

La sous-chaîne précédente contient les éléments d’indice 2 à 5, c'est-à-dire les 3e, 4e, 5e et 6e caractères.  liste[2:-1]

[5, 7, 11]

La sous-liste précédente contient tous les éléments à partir du 3e (indice 2) jusqu’à l’avant-dernier (le dernier, d’indice -1, étant exclu).

On peut omettre l’indice de départ ou l’indice d’arrivée, si l’on veut construire des sous-intervalles à partir du début ou jusqu’à la fin de la chaîne/liste :

 liste[:4]

[2, 3, 5, 7]  s[7:]

'Einstein'

Exemple : On extrait aisément le nom de famille de la chaîne s en remarquant qu’il est précédé d’une espace :

 s[s.index(" ")+1:]

'Einstein'

On récupère une liste entière en omettant les deux extrémités de l’intervalle d’indices :

 liste[:]

[2, 3, 5, 7, 11, 13]

Cette notation paraît triviale ou même superflue à première vue, mais elle est essentielle si l’on veut copier des listes. En effet, en écrivant

liste = [2, 3, 5, 7, 11, 13] copie = liste

la copie renvoie à la même liste que la variable de départ ! Ainsi, en écrivant  copie[0] = 1

on a également modifié la liste de départ :

 

 liste

[1, 3, 5, 7, 11, 13]

La variable « copie » n’est qu’un alias de la variable « liste », ou autrement dit, les deux variables « liste » et « copie » pointent vers le même objet dans la mémoire. Un compteur interne comptabilise combien de fois un tel objet de la mémoire est référencé. Ainsi, lorsqu’on détruit une variable pointant vers un objet, ce dernier n’est pas effacé de la mémoire aussi longtemps que d’autres variables y pointent encore. Après l’instruction

 del copie

la variable liste (et surtout son contenu) existe encore :

 liste

[1, 3, 5, 7, 11, 13]

Par contre, lorsqu’on veut vraiment copier une liste, et créer ainsi une nouvelle variable indépendante de la première, il faut écrire :

liste = [2, 3, 5, 7, 11, 13] copie = liste[:]

Maintenant on peut modifier la copie sans toucher à l’original :

copie[0] = 1 liste

[2, 3, 5, 7, 11, 13]

6.2 Modification de (sous-)listes

Rappelons que les chaînes de caractères sont des structures non-modifiables, c’est-à-dire on ne peut pas simplement remplacer un caractère par un autre dans une chaîne :

s = "Hallo!" s[1] = "e"

ne produit pas la chaîne "Hello!", mais une erreur du type

'str' object does not support item assignment

Par contre, les éléments d’une liste sont modifiables, l’accès se faisant par l’indice, comme déjà montré dans la section précédente :

liste = [1, 3, 5, 7, 9] liste[2] = 11 liste

[1, 3, 11, 7, 9]

On peut aussi remplacer une sous-liste par un contenu nouveau :

liste = [1, 3, 5, 7, 9] liste[2:4] = [11, 12, 13] liste

[1, 3, 11, 12, 13, 9]

On vient de remplacer la sous-liste [5,7] par [11,12,13]. La taille d’une liste peut donc changer lors d’une telle affectation.

Attention ! Lorsqu’on veut remplacer un seul élément par plusieurs éléments dans une liste, il faut bien distinguer les deux cas suivants :

liste = [1, 3, 5, 7, 9] liste[2] = [11, 12, 13] liste

[1, 3, [11, 12, 13], 7, 9]

On vient de remplacer l’élément 5 par [11,12,13] et on a ainsi créé, peut-être sans le vouloir, une liste imbriquée dans la liste de départ, qui, elle, contient encore 5 éléments, la liste imbriquée comptant comme un seul élément de la liste enveloppante. D’autre part,

liste = [1, 3, 5, 7, 9] liste[2:2] = [11, 12, 13] liste

[1, 3, 11, 12, 13, 7, 9] donne une liste où l’élément 5 a été remplacé par plusieurs éléments nouveaux, ce qui augmente la taille de la liste initiale.

6.3 Création automatisée de listes

Rappelons la fonction range() vue plus haut lors de la définition des compteurs de boucles. L’objet renvoyé par range() n’est pas identique à une liste, mais il peut être transformé trivialement en une liste en le passant comme argument au constructeur de listes, noté list() :  list(range(10))

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

La fonction range() génère par défaut une séquence de nombres entiers de valeurs croissantes, et différant d’une unité. Lorsqu’on appelle range() avec un seul argument, la liste contiendra un nombre de valeurs égal à l'argument fourni, mais en commençant à partir de zéro (c'est-à-dire que range(n) génère les nombres de 0 à n-1). L’argument fourni ne figurera pas dans la liste générée !

On peut aussi utiliser range() avec deux ou même trois arguments séparés par des virgules, afin de générer des séquences de nombres plus spécifiques :

 list(range(5,14))

[5, 6, 7, 8, 9, 10, 11, 12, 13]  list(range(3, 17, 4))

[3, 7, 11, 15]

Les arguments peuvent être des nombres négatifs :

 list(range(10, -11, -3))

[10, 7, 4, 1, -2, -5, -8]

On remarque que la valeur du 2e argument ne figure plus dans la liste (principe d’intervalle semi-ouvert, noté [a,b[ en mathématiques).

6.4 Exercices

Exercice 6-1

Écrire un programme qui lit deux nombres naturels non nuls a et n et qui génère la liste des n premiers nombres premiers ? a.

Exercice 6-2

Écrire un programme qui lit un entier n ? 2 et ensuite lit (ou génère de manière automatisée à l'aide de valeurs aléatoires) une liste à n nombres réels strictement positifs. Le programme calculera et affichera alors les moyennes suivantes de ces nombres : la moyenne arithmétique, la moyenne géométrique, la moyenne harmonique et la moyenne quadratique.

Rappel :

Exercice 6-3

Écrire un programme qui lit un entier n ? 2 et ensuite lit (ou génère de manière automatisée à l'aide de valeurs aléatoires) une liste à n nombres réels. Le programme calculera et affichera alors la médiane, le premier quartile et le troisième quartile de cette liste de nombres.


 7   Les tuplets (tuples)

7   Les tuplets (tuples)

7.1   Notation

Nous avons rencontré dans les sections précédentes deux types de données composés : les chaînes de caractères (string, noté « str »en Python), qui sont composées de caractères, et les listes (list), qui sont composées d'éléments de n'importe quel type. Alors qu’il n'est pas possible de changer les caractères à l’intérieur d’une chaîne existante, on peut modifier directement les éléments à l’intérieur d’une liste. En d’autres termes, les listes sont des séquences modifiables, alors que les chaînes de caractères sont des séquences non-modifiables.

Python propose un type de données appelé tuplet, qui est semblable à une liste mais qui, comme les chaînes, n'est pas modifiable.

Syntaxiquement, un tuplet est une collection d'éléments séparés par des virgules :

t = (10, 20, 30) t

(10, 20, 30)

Le plus souvent, lorsque aucune ambiguïté n’est possible, on peut laisser de côté les parenthèses lors des affectations :

t = 11, 21, 31 t

(11, 21, 31)

L’interpréteur a correctement compris que les trois nombres séparés par des virgules forment implicitement un tuplet. Mais même si les parenthèses sont souvent facultatives, il est recommandé de les écrire lorsqu’elles aident à augmenter la lisibilité du code-source.

L'extraction des éléments d’un tuplet se fait aussi facilement :

 (x, y, z) = t ou même  x, y, z = t

Maintenant x vaut 11, y vaut 21 et z vaut 31.

7.2   Opération sur les tuplets

Les opérations que l’on peut effectuer sur des tuplets sont syntaxiquement similaires à celles que l’on effectue sur les listes, si ce n’est que les tuplets ne sont pas modifiables. Mais lorsqu’un tuplet contient comme élément une séquence modifiable (p.ex. une liste), celle-ci reste modifiable.

a = [1, 2, 3] b = (a, 4) b

([1, 2, 3], 4)

Le résultat est un tuplet à deux éléments, c’est-à-dire un couple, dont le premier élément est une liste à trois éléments. On ne peut pas modifier le premier élément de b :

 b[0] = 6

provoque une erreur. Par contre, on peut modifier un élément de la liste formant le premier élément de b :

b[0][1] = 6

([1, 6, 3], 4)

En même temps, on a bien sûr modifié le contenu de a, car a et b[0] pointent vers le même objet en mémoire.

 a

[1, 6, 3]

 

Classe de IIB – Programmation en Python

7.3 Application : vecteurs et matrices

Les vecteurs vus en mathématiques peuvent très bien être représentés par des tuplets ou par des listes de nombres. Si u et v sont deux variables de ce type, représentant des vecteurs de dimension 2, leur produit scalaire dans une base orthonormée est obtenu par  u[0]*v[0] + u[1]*v[1]

et le déterminant en dimension 2 se calcule comme suit :

 u[0]*v[1] - u[1]*v[0]

Par analogie, on obtient en dimension 3 pour le produit scalaire :

 u[0]*v[0] + u[1]*v[1] + u[2]*v[2]

et pour le produit vectoriel le vecteur écrit ici comme tuplet (triplet) :

 (u[1]*v[2]-u[2]*v[1], u[2]*v[0]-u[0]*v[2], u[0]*v[1]-u[1]*v[0]) Pour les matrices, on construit des tuplets de tuplets, ou des listes de listes :

a = [[1,2,3], [2,3,4], [3,4,5]] b = [[1,3,5], [2,4,6], [3,5,7]]

Pour effectuer par exemple le produit matriciel a.b, il faut d’abord disposer d’une matrice (c’est-à-dire d’une liste de listes) de bonnes dimensions (3x3), dont tous les éléments valent 0 :

 p = [[0,0,0],[0,0,0],[0,0,0]]

On pourrait également écrire, de façon moins répétitive, mais plus compliquée :

 p = [x[:] for x in [[0]*3]*3]

Cela peut paraître bizarre, mais il faut se rendre compte que la méthode plus simple  p = [[0]*3]*3

ne fonctionne tout simplement pas : le vecteur-ligne [0]*3 est créé, puis triplé, ce qui veut dire que la « matrice » p pointe trois fois vers le même vecteur-ligne. Lorsqu’on modifie un constituant de ce vecteur, la nouvelle valeur apparaît trois fois dans la colonne respective de la matrice.

Pour résoudre ce problème, on a donc construit d’abord trois vecteurs composés chacun de trois composants nuls ; le résultat, noté x, est copié dans p, pour que les trois vecteurs-lignes obtenus deviennent indépendants et ne représentent plus un seul objet dans la mémoire.

Ensuite on réalise le calcul pij = ?k aik bkj :

for i in range(3):     for j in range(3):         for k in range(3):

            p[i][j] += a[i][k] * b[k][j] p

[[14, 26, 38], [20, 38, 56], [26, 50, 74]]

7.4 Exercices

Exercice 7-1

Écrire un programme qui lit un entier n ? 2 et ensuite lit (ou génère de manière automatisée à l'aide de valeurs aléatoires) une matrice carrée d'ordre n. Le programme calculera et affichera alors le déterminant de cette matrice.

Exercice 7-2

Écrire un programme qui lit un entier n ? 2 et ensuite génère la matrice de Hilbert B d'ordre n :

 

Ainsi, pour n = 5 on a :

 

Le programme calculera et affichera le déterminant de la matrice (cf. Exercice 71). Pour différentes valeurs de n, comparer les valeurs avec celles obtenues par les collègues en classe et avec les valeurs exactes (utiliser p.ex. WolframAlpha pour cette vérification).

Classe de IIB – Programmation en Python

Exercice 7-3

Écrire un programme qui lit un entier n ? 2 et ensuite lit (ou génère de manière automatisée à l'aide de valeurs aléatoires) une matrice carrée d'ordre n. Le programme calculera et affichera l'inverse de la matrice de départ. Puis le programme calculera et affichera encore l'inverse de la matrice inverse précédente. Vérifier si le dernier résultat ne diffère pas (trop) de la matrice de départ et comparer les imprécisions éventuelles avec celles obtenues par les collègues en classe.

Indication, pour tester sérieusement le programme : les matrices de Hilbert sont des matrices particulièrement « méchantes » à inverser…


 8   Les dictionnaires

8   Les dictionnaires

8.1 Problème introductif

Réaliser un annuaire téléphonique qui permet notamment de retrouver rapidement le numéro de téléphone à partir du nom de l'abonné.

On pourrait réaliser deux listes en parallèle :

subscribers = ["LAML", "LCD", "AL"] numbers = ["26043211", "268071", "440249-6100"]

Ainsi l’abonné subscribers[i] possède le numéro numbers[i]. Cette méthode présente plusieurs inconvénients :

•   il faut veiller à la synchronisation permanente des deux listes lors de modifications ;

•   lorsqu’on veut trier la liste des abonnés, il ne faut pas oublier d’opérer les mêmes changements d’ordre dans la liste des numéros ;

•   l’accès à un numéro à partir du nom de l’abonné peut se faire comme suit :

 numbers[subscribers.index["LCD"]]

'268071' mais la notation est lourde et l'exécution est assez lente, parce que la liste des abonnés devra être lue en moyenne à moitié jusqu’à ce que l’indice correct soit trouvé.

Une variable de type dictionnaire (en Python : type dict) résout ce problème de façon élégante :

phonebook = {"LAML":"26043211", "LCD":"268071", "AL":"440249-6100"} phonebook["AL"]

'440249-6100'

On peut rajouter des données par affectation :

 phonebook["LCE"] = "7287151"

La liste des abonnés est obtenue par la méthode  list(())

['LCD', 'LCE', 'AL', 'LAML']

On remarque que l’ordre des éléments de cette liste n’est ni l’ordre lexicographique, ni l’ordre d’entrée des données ! Cela est dû à l’encodage efficace des données en mémoire qui ne respecte ni l’un ni l’autre de ces deux ordres.

L’ordre lexicographique est obtenu par  sorted(())

['AL', 'LAML', 'LCD', 'LCE']

8.2 Création de dictionnaires

Les dictionnaires ressemblent aux listes (ils sont modifiables comme elles), mais ce ne sont pas des séquences. Les éléments enregistrés dans un dictionnaire ne seront pas disposés dans un ordre immuable dans la mémoire. En revanche, on pourra accéder à n'importe lequel d'entre eux à l'aide d’un indice spécifique appelé clé (key), qui pourra être alphabétique, numérique, ou même d’un type composé (par exemple un tuplet de nombres représentant des coordonnées).

Comme dans une liste, les éléments stockés dans un dictionnaire peuvent être de n’importe quel type, par exemple des valeurs numériques, des chaînes, des listes, des tuplets, des dictionnaires.

Puisque le type dict est un type modifiable, on peut créer un dictionnaire vide, puis le remplir petit à petit. Les délimiteurs de dictionnaires sont des accolades {

}. Un dictionnaire vide est donc obtenu par  birth_year = { }

Pour rajouter des données, il n'est pas nécessaire d’utiliser la méthode append(), qui d’ailleurs n’existe pas pour les dictionnaires, mais on écrit simplement des affectations :

birth_year["Mozart"] = 1756 birth_year["Beethoven"] = 1770 print(birth_year["Mozart"]) print(birth_year)

1756

{'Beethoven': 1770, 'Mozart': 1756}

Classe de IIB – Programmation en Python

8.3 Opérations sur les dictionnaires

Il n’existe pas d’opération spécifique pour rajouter des éléments à un dictionnaire, mais l’affectation standard fonctionne, comme on vient de le voir.

 birth_year["Schubert"] = 1797

Pour effacer des données, on utilise l’instruction del :

del birth_year["Mozart"] birth_year

{'Beethoven': 1770, 'Schubert': 1797}

Le nombre d’éléments contenus dans un dictionnaire est fourni par len :

 len(birth_year)

2

Pour tester si un dictionnaire contient une certaine clé, on utilise in :

if "Dylan" in birth_year:

    print(birth_year["Dylan"]) else:     print("Compositeur inconnu")

Compositeur inconnu

Il ne faut pas accéder à une valeur dont la clé n’existe pas dans le dictionnaire :

 birth_year("Dylan")

provoque une erreur de type KeyError. Par contre, on peut utiliser la méthode get() pour combiner le test d’existence d’une clé et l’accès à sa valeur associée :

print(("Beethoven", "Compositeur inconnu")) print(("Dylan", "Compositeur inconnu"))

1770

Compositeur inconnu

On peut extraire des parties de données contenues dans un dictionnaire par les méthodes suivantes :

 ()

dict_keys(['Beethoven', 'Schubert'])

Ce résultat est utilisable dans la définition de boucles :

for c in ():

    print(c, "est né en", birth_year[c])

Beethoven est né en 1770

Schubert est né en 1797

Par abus de notation, le même résultat est obtenu en écrivant simplement :

for c in birth_year:

    print(c, "est né en", birth_year[c])

Beethoven est né en 1770

Schubert est né en 1797

Si l’on préfère extraire les clés sous forme de liste ou de tuplet, on pourra écrire :

 list(())

['Beethoven', 'Schubert']  tuple(())

('Beethoven', 'Schubert')

De manière analogue, on extrait les valeurs associées aux clés :

 birth_year.values() dict_values([1770, 1797])

 list(birth_year.values())

[1770, 1797]

La méthode items() renvoie tout le contenu du dictionnaire sous forme d’une séquence de couples :

 birth_year.items()

dict_items([('Beethoven', 1770), ('Schubert', 1797)])

Ceci nous donne encore une autre manière de parcourir un dictionnaire dans une boucle :

for c, y in birth_year.items():

    print(c, "est né en", y)

Beethoven est né en 1770

Schubert est né en 1797

Il faut toujours se rappeler que l’ordre dans lequel les éléments sont extraits du dictionnaire est imprévisible, car un dictionnaire n’est pas une séquence. Pour la même raison, on ne peut pas extraire un « sous-dictionnaire » d’un dictionnaire avec la méthode des sous-intervalles (slicing) vue pour les chaînes de caractères ou les listes.

Classe de IIB – Programmation en Python

Tout comme les listes, les dictionnaires ne sont pas copiés, lorsqu’on affecte une variable de dictionnaire à une autre variable (notation x = y), mais un alias est créé qui pointe vers le même objet en mémoire que le dictionnaire de départ. Nous avions résolu le problème de la copie véritable de listes en écrivant x = y[:], mais cette notation (slicing) n’existe pas pour les dictionnaires. Pour réaliser une copie d’un dictionnaire, qui sera dans la suite indépendante de l’original, il faut utiliser la méthode copy() : x = y.copy()

8.4 Exercices

Exercice 8-1

Soit le dictionnaire  roman = {"M":1000, "D":500, "C":100, "L":50}

Compléter ce dictionnaire avec des entrées similaires pour les lettres X (10), V (5) et I (1). Utiliser le dictionnaire pour transformer un nombre écrit en chiffres romains en notation décimale habituelle. Par exemple, le programme devra pouvoir transformer "MMXIX" en 2019 et "DCCCXLIV" en 844. On pourra se limiter aux nombres inférieurs à 5000.

Exercice 8-2

Soit le dictionnaire  school_notes = {}

Utiliser ce dictionnaire pour insérer les notes des devoirs en classe d’un trimestre donné. Si dans une branche il y a plusieurs devoirs en classe, on insère les notes correspondantes sous forme de liste. Par exemple, lorsqu’il y a un seul devoir en informatique, mais plusieurs devoirs en français dont la 1re note vaut 36 :

school_notes["Informatique"] = 60 school_notes["Français"] = [36]

Si la note du 2e devoir en français est égale à 44 :

 school_notes["Français"].append(44)

Écrire un programme qui permet l’entrée des branches et des notes, l’affichage du dictionnaire sous forme de tableau raisonnablement formaté et le calcul des moyennes trimestrielles pour les branches avec plusieurs notes.

Exercice 8-3 - Jeu de bataille navale

 

Utiliser un dictionnaire pour représenter les bateaux placés. On pourra par exemple numéroter les bateaux :

sea = { } sea["A1"] = 1 sea["B1"] = 1 sea["A3"] = 2  # etc.

Alternativement, on pourrait représenter les coordonnées par des couples de nombres naturels. Au lieu de numéroter les bateaux, on pourrait leur attribuer des noms (torpilleur, croiseur…). Par exemple :

sea = { } sea[1,1] = "torpilleur" sea[2,1] = "torpilleur" sea[1,3] = "croiseur"  # etc.

Les clés sont bien des couples : sea[1,1] signifie la même chose que sea[(1,1)]

Écrire un programme qui permet de placer un nombre fixe de bateaux. L’utilisateur pourra ensuite entrer des coordonnées pour essayer de faire couler les bateaux. Le programme utilisera l’opérateur in ou la méthode get() pour tester si un bateau a été touché et l’instruction del pour le faire couler.

Compléter ensuite le programme pour permettre un véritable jeu de bataille navale, avec deux joueurs (c’est-à-dire deux dictionnaires représentant les aires de jeu respectives).

 9   Les chaînes de caractères (strings)

9   Les chaînes de caractères (strings)

9.1 Rappels

Les chaînes de caractères, de type str en Python, ont comme délimiteurs des apostrophes '…' ou des guillemets "…". Lorsque le caractère choisi comme délimiteur apparaît lui-même dans la chaîne, il faut le faire précéder d'un backslash \

:

 s = 'aujourd\'hui'

Le caractère spécial \n représente le passage à la ligne suivante.

Une chaîne peut s'étendre sur plusieurs lignes, même dans le code-source, sans que l'on doive forcément recourir à \n. Cette chaîne est alors délimitée par des apostrophes ou des guillemets triples :

s = """Première ligne de texte.

Deuxième ligne de texte.

Troisième ligne de texte."""

On peut concaténer (joindre) des chaînes avec l'opérateur d'addition + et répéter des extraits plusieurs fois avec l'opérateur de multiplication * :

 print(2 * "ha" + 5 * "!")

haha!!!!!

Des chaînes de caractères littérales écrites qui se suivent directement sont concaténées implicitement :

 s = "aujourd'hui" " et demain"

est équivalent à  s = "aujourd'hui" + " et demain"

et donne la chaîne "aujourd'hui et demain".

L'usage des indices et des sous-intervalles pour extraire des caractères ou parties d'une chaîne a été introduit aux sections 6.1 et 6.2. Il faut remarquer que Python ne connaît pas de type "caractère", mais un caractère isolé est assimilé à une chaîne de longueur 1. Ainsi, le caractère s[0] et l'extrait s[0:1] de la chaîne non vide s représentent exactement la même chose, à savoir un str à 1 caractère.

9.2 Compléments : méthodes utiles

Voici quelques méthodes qui permettent de manipuler des chaînes de caractères (strings) :

s.capitalize() : renvoie une copie de s dont le premier caractère est transformé en majuscule et toutes les autres lettres de s en minuscules.

s.lower() : renvoie une copie de s dont toutes les lettres sont transformées en lettres minuscules.

s.upper() : renvoie une copie de s dont toutes les lettres sont transformées en lettres majuscules.

s.strip() : renvoie une copie de s, où les caractères invisibles (whitespaces, p.ex. les espaces) sont enlevés au début et à la fin.

s.strip(t) : renvoie une copie de s, où les caractères énumérés dans la chaîne t sont enlevés au début et à la fin (de la chaîne s).

s.split(t) : renvoie une liste de sous-chaînes obtenue à partir de s ; la chaîne est découpée aux endroits où la sous-chaîne t apparaît ; si t apparaît plusieurs fois consécutivement, des sous-chaînes vides sont générées à l'emplacement correspondant dans la liste renvoyée.

s.split() : renvoie une liste de mots obtenue à partir de s, c'est-à-dire s est découpé aux endroits contenant des caractères invisibles (whitespaces) ; contrairement à ce qui se passe pour s.split(t), des caractères invisibles juxtaposés ne génèrent pas de mots vides dans la liste.

s.find(t) : renvoie l'indice de la première occurrence de la chaîne t dans la chaîne

s. Si t n'est pas trouvé dans s, la valeur -1 est renvoyée. Pour tester simplement si t est contenu dans s, sans vouloir connaître la position précise, on préférera la notation compacte  t in s

qui renvoie directement True resp. False, plutôt que d'écrire

 s.find(t) >= 0

s.find(t, a, b) : limite la recherche de t à la sous-chaîne s[a:b].

s.replace(old, new) : renvoie une copie de s où toutes les occurrences de la souschaîne old sont remplacées par la sous-chaîne new.


s.replace(old, new, n) : renvoie une copie de s où les n premières occurrences de la sous-chaîne old sont remplacées par la sous-chaîne new.

s.isalpha() : renvoie True si s contient au moins un caractère et que tous ses caractères sont des lettres alphabétiques ; la méthode renvoie False sinon.

s.isdigit() : renvoie True si s contient au moins un caractère et que tous ses caractères sont des chiffres ; la méthode renvoie False sinon.

s.isalnum() : renvoie True si s contient au moins un caractère et que tous ses caractères sont des lettres alphabétiques ou des chiffres ; la méthode renvoie False sinon.



s.islower() : renvoie True si s contient au moins une lettre et que toutes ses lettres sont des lettres minuscules ; la méthode renvoie False sinon.

s.isupper() : renvoie True si s contient au moins une lettre et que toutes ses lettres sont des lettres majuscules ; la méthode renvoie False sinon.

s.isspace() : renvoie True si s contient au moins un caractère et que tous ses caractères sont invisibles (whitespaces) ; la méthode renvoie False sinon.

10   Les fonctions

10.1 Introduction

Écrivons un programme qui calcule le nombre de combinaisons de p objets parmi n (avec 0 ? p ? n).

Rappelons que ce nombre se détermine par la formule :

 

Nous constatons que pour chaque calcul d'un nombre de combinaisons nous devons effectuer trois fois le calcul d'une factorielle et ainsi répéter trois fois le même code.

Les fonctions servent à éviter ces redondances dans les programmes. Grâce à elles il suffit de noter une seule fois le code de calcul de la factorielle et de l'utiliser à chaque besoin.

Établissons d'abord le calcul de la factorielle n! sous forme de fonction.

def fact(n):

x = 1 for i in range(2, n+1):

x *= i

return x

L'identificateur n est un paramètre dont la valeur est fixée lors de chaque appel de la fonction. La fonction fact retourne une valeur qui sera transmise au programme appelant.

Une fonction, une fois définie comme telle, peut être utilisée comme suit :

def comb(n, p):

if 0 <= p <= n:

return fact(n)//(fact(p)*fact(n-p))

else:

return "mauvais arguments"

Ainsi, par exemple le nombre de tirages possibles du Samstagslotto est égal à  print(comb(49, 6))

13983816

Lorsque les arguments sont mal choisis, un message est renvoyé :

 print(comb(4, 5))

mauvais arguments

10.2 Définition

Une fonction est une partie de code d'un programme que nous pouvons utiliser (appeler) plusieurs fois. Chaque fois que nous l'utilisons, nous pouvons lui transmettre d'autres valeurs comme arguments qu'elle utilisera pendant son exécution. Le code de la fonction est placé plus haut dans le code-source que l'appel effectif de la fonction (c'est-à-dire au moment de l'appel de la fonction par l'interpréteur du programme sa définition doit déjà avoir été lue).

Syntaxe de la définition d'une fonction :

def <nom_de_fonction>(paramètre_1, …, paramètre_n):

instructions

Normalement, une ou plusieurs instructions sont du type

                       return <réponse>

Lorsqu'une fonction ne contient aucune instruction return, la valeur implicite None est renvoyée.

Une fonction peut renvoyer plusieurs réponses, regroupées sous forme de tuplet ou de liste par exemple.

Une fonction qui ne reçoit aucun argument garde néanmoins ses parenthèses, qui indiquent qu'il s'agit bien d'une fonction :

def <nom_de_fonction>():

instructions Syntaxe de l'appel d'une fonction :

par exemple

<nom_de_variable> = <nom_de_fonction>(arg_1, …, arg_n)

Les arguments sont affectés aux paramètres formels dans le même ordre qu'ils interviennent dans la déclaration de la fonction. Dans le corps de la fonction les paramètres se comportent comme des variables et peuvent être utilisés (notamment réaffectés) comme telles.

Une fonction peut appeler elle-même une ou plusieurs fonctions.

10.3 Exercices

Exercice 10-1

Écrire une fonction qui retourne la chaîne de caractères la plus longue de trois chaînes fournies.

Exercice 10-2

Écrire une fonction qui détecte si une chaîne de caractères ne contient aucune voyelle (lettres a, e, i, o, u).

Exercice 10-3

Écrire une fonction qui compte le nombre de chiffres (caractères 0, 1, …, 9) dans une chaîne de caractères.

Écrire deux variantes de cette fonction : La première compte simplement le total de chiffres trouvés dans la chaîne. La deuxième fonction renvoie une liste de 10 valeurs indiquant le nombre de chiffres 0 trouvés, le nombre de chiffres 1 trouvés, etc.

Exercice 10-4

Écrire un programme qui lit le numérateur et le dénominateur d'une fraction et à l'aide d'une fonction simp fournit la fraction simplifiée. Utiliser des tuplets pour représenter les fractions.

Exercice 10-5

Écrire une fonction moyenne qui calcule la moyenne des notes de devoirs en classe. La fonction accepte comme seul argument une liste de nombres (on suppose que tous les nombres sont des entiers entre 1 et 60) et elle renvoie un entier, à savoir la moyenne arrondie (vers le haut) des notes fournies.

Exercice 10-6 Opérations sur des polynômes

Demandez à l’utilisateur d’entrer deux polynômes (voir Chapitre 5).

Calculez la somme, la différence et le produit de ces deux polynômes et affichez le polynôme résultant de chaque opération.

10.4 Paramètres optionnels

Rappelons que certaines expressions acceptent un nombre variable d'arguments. Ainsi on peut écrire aussi bien range(2, 9, 1) que range(2, 9) pour décrire l'intervalle des nombres entiers de 2 à 8. Dans l'expression range(2, 9), le troisième argument n'est pas fourni et on peut supposer qu'il vaut 1 par défaut.

Les fonctions que nous définissons nous-mêmes peuvent également accepter les arguments par défaut. La fonction suivante calcule la longueur d'une diagonale d'un rectangle (en deux dimensions) ou d'un parallélépipède rectangulaire (en trois dimensions) en appliquant la formule de Pythagore :

def pyth(a, b, c=0):

return (a**2 + b**2 + c**2) ** (1/2)

Remarque : au lieu d'élever à la puissance 1/2 pour calculer la racine carrée, on aurait également pu importer la méthode sqrt de la bibliothèque math :

frommathimportsqrt def pyth(a, b, c=0):

return sqrt(a**2 + b**2 + c**2)

Lors de l'appel de la fonction pyth, on peut fournir soit deux, soit trois arguments. Lorsqu'on ne donne que deux arguments, la valeur par défaut (qui vaut 0 d'après la définition de la fonction) est utilisée pour le paramètre c.

 print(pyth(5, 12))

13.0  print(pyth(4, 7, 4))

9.0

10.5 Nombre indéterminé de paramètres

Rappelons que certaines expressions acceptent un nombre variable d'arguments. Ainsi on peut appeler print(…) avec un nombre quelconque d'arguments qui seront tous affichés, l'un après l'autre et séparés entre eux par une espace.

Les fonctions que nous définissons nous-mêmes peuvent également accepter un nombre quelconque d'arguments. La fonction suivante accepte comme premier argument une base b?2 et comme arguments supplémentaires des chiffres représentant un nombre entier positif en base b. Chaque chiffre doit être un entier compris entre 0 et b-1. La fonction détermine le nombre ainsi représenté et le renvoie, de sorte qu'il puisse être affiché en notation décimale.

def nombre_base(b, *c):

x = 0 for i in c:

if 0 <= i < b:

x = x*b + i

else: return "mauvais arguments"

return x

Ainsi, nombre_base(10, 3, 4, 5, 6) renvoie le nombre 3456, et nombre_base(7, 1, 2, 3) renvoie 66, car 1*72 + 2*7 + 3 = 66.

L'astérisque devant le paramètre c indique qu'il représente des arguments en nombre quelconque. On accède au contenu du paramètre c en parcourant son contenu dans une boucle (comme dans l'exemple précédent) ou avec la notation d'indice : p.ex. c[1] représente le deuxième argument fourni pour c, c'est-à-dire le troisième argument de la fonction, compte tenu de b.

10.6 Variables locales et globales

Une fonction reçoit le plus souvent des arguments qui sont affectés aux paramètres qui jouent le rôle de variables à l'intérieur de la fonction. Le passage argument => paramètre est toujours réalisé comme une affectation de variables et suit les mêmes règles. Les arguments simples (nombres, chaînes de caractères, tuplets) sont copiés lors de ce passage, mais les arguments plus complexes, notamment les listes et les dictionnaires, sont passés par référence, c'est-à-dire la fonction travaille avec les contenus originaux de ces variables, même si les noms des paramètres diffèrent de ceux des arguments !

Lorsque les paramètres ou des variables définies par la fonction portent le même nom que les arguments ou d'autres variables extérieures à la fonction, ils cachent leurs homonymes extérieurs et sont ainsi appelés « variables locales ».

Quelques exemples pour illustrer ce concept extrêmement important :

def f(x): x *= 2 y = 20 return x

x = 1 y = 10 print(f(x)) print(x, y)

2

1 10

En effet, le paramètre x de la fonction f est local à f et ne modifie pas le contenu de la variable x à l'extérieur de la fonction. De même, la variable y définie par la fonction est locale à f et n'a rien à faire avec la variable extérieure y, dont le contenu n'est pas accessible à f et ne peut donc pas être modifié par mégarde.

def f(x): global y x *= 2 y = 20

return x

x = 1 y = 10 print(f(x)) print(x, y)

2

1 20

Maintenant, y est déclaré comme variable globale, c'est-à-dire la même variable y est utilisée à l'intérieur comme à l'extérieur de la fonction f. Le contenu de y est ainsi modifié par f.

Cette technique ne s'applique pas aux paramètres : on ne peut pas accéder à l'original (la variable extérieure x) via le paramètre x en écrivant global x !

Pour les listes (ou les dictionnaires), les choses se compliquent un peu :

def f(li): li += [0] li[0] = 7 return len(li)

liste = [1, 2, 3, 4] print(f(liste))

(liste)

5

[7, 2, 3, 4, 0]

Le paramètre li contient seulement une référence vers la variable liste, donc la liste originale est modifiée par la fonction f. L'opérateur += est équivalent à la méthode append() : à la deuxième ligne du code, on aurait pu écrire tout aussi bien li.append(0), avec les mêmes effets sur liste.

def f(li): li = li + [0] li[0] = 7 return len(li)

liste = [1, 2, 3, 4] print(f(liste)) print(liste)

5

[1, 2, 3, 4]

À la deuxième ligne du code, une nouvelle liste est générée par li + [0], et cette nouvelle liste est stockée dans la variable locale équivalant au paramètre li. Comme il s'agit d'une nouvelle liste et que la variable li à laquelle elle est affectée est locale par définition, li est maintenant détachée de la variable extérieure liste vers laquelle li référençait jusqu'à présent. Les instructions suivantes ne modifient donc plus la variable liste.

10.7 Exercices

Exercice 10-7 (générique)

Revoir tous les exercices des chapitres précédents pour décider si l'introduction de fonctions ne permettrait pas de simplifier leur code respectif.

Exercice 10-8 - Le jeu de Mastermind.

Lire les règles du jeu sur

(Spiel)

Implémenter la table du jeu sous forme de liste contenant soit des listes à 4 éléments soit des quadruplets représentant les codes de couleurs. Une même couleur peut apparaître plusieurs fois dans le code ; en tout il y a 6 couleurs dispo-

nibles.

Après le démarrage du programme l'ordinateur déterminera un code de couleurs aléatoire qu'il n'affichera pas. L'utilisateur essaiera de deviner ce code secret et le programme donnera chaque fois les indications (pions noirs et pions blancs) sur l'(in)exactitude du code.

Exercice 10-9 - Le jeu de Mastermind, version plus difficile.

C'est maintenant le tour de l'ordinateur de deviner le code choisi par l'utilisateur. L'algorithme du programme doit être suffisamment raffiné pour pouvoir déterminer n'importe quel code secret (4 pions, 6 couleurs) en moins de 10 essais.

Exercice 10-10 - Le jeu de Mastermind, profiling session.

Reconsidérer le programme de l'exercice précédent. Tester l'efficacité de l'algorithme programmé en l'appliquant successivement (de façon automatisée bien sûr) aux 64 = 1296 codes secrets possibles et comptabiliser combien d'essais ont été nécessaires chaque fois pour déterminer le code secret. Afficher finalement la moyenne des nombres d'essais et aussi le nombre d'essais le plus élevé. Comparer ces valeurs avec celles obtenues par vos collègues en classe.

Exercice 10-11 - Le jeu d'échecs, représentation de l'échiquier.

Voir

(ceux qui ne connaissent pas le jeu devraient lire au moins les deux premiers chapitres « Règles du jeu » et « Notation des parties »).

Concevoir une manière intelligente de représenter un échiquier (c'est-à-dire une position de jeu) par une seule variable. Écrire une fonction qui affiche le contenu d'une telle variable de façon compréhensible à l'écran, par exemple en utilisant les abréviations internationales (anglaises). Pour la position initiale du jeu :

r n b q k b n r p p p p p p p p . # . # . # . # # . # . # . # .

. # . # . # . # # . # . # . # .

P P P P P P P P

R N B Q K B N R

Exercice 10-12 - Le jeu d'échecs, saisie d'une position de jeu.

Écrire une fonction qui accepte une chaîne de caractères du type FEN, voir , renvoie la position du jeu dans une variable du type de l'exercice précédent et l'affiche à l'écran. Les deux nombres à la fin de la chaîne FEN (relatifs au comptage des coups) peuvent être ignorés.

Exercice 10-13 - Le jeu d'échecs, générateur de coups.

Après avoir saisi une position du jeu (exercice précédent), le programme déterminera la liste de tous les coups que le joueur actuel pourra jouer. Pour garder un code-source lisible, il est recommandé d'écrire une fonction séparée pour chaque type de pièce (pion, cavalier, fou, tour, dame, roi) et pour les coups spéciaux éventuels. Veiller à la légalité des coups ! Vérifier notamment qu'après un coup joué le roi du joueur ne se retrouve pas en échec, ce qui peut être testé assez facilement en générant les coups de l'adversaire à partir de la nouvelle position du jeu et en regardant si l'un des coups consiste à capturer le roi du premier joueur.


 11   Les fichiers

11   Les fichiers

11.1   Introduction

Un fichier informatique est au sens commun, une collection de données numériques réunies sous un même nom, enregistrées sur un support de stockage permanent, appelé mémoire de masse, tel qu'un disque dur, un CD-ROM, une mémoire flash, et manipulées comme une unité. Un fichier porte un nom de fichier qui sert à désigner le contenu et y accéder. Ce nom comporte souvent, notamment dans l'environnement Windows, un suffixe : léxtension, qui renseigne sur la nature des informations contenues dans le fichier et donc des logiciels utilisables pour le manipuler. Chaque fichier comporte un certain nombre de métadonnées, informations concernant les informations, telles que suivant le système de fichier, la longueur du fichier, son auteur, les personnes autorisées à le manipuler, ou la date de la dernière modification. Le contenu est l'essence du fichier. Il existe des centaines, voire des milliers de types de fichiers, qui se différencient par la nature du contenu, le format, le logiciel utilisé pour manipuler le contenu, et l'usage qu'en fait l'ordinateur. La nature du contenu peut être des textes, des images, de l'audio ou de la vidéo.

Le format de fichier est la convention selon laquelle les informations sont numérisées et organisées dans le fichier et sert d'emballage dans lequel sera mis le contenu ainsi que les métadonnées. L'extension lorsqu'elle est présente, suffixe un nom du fichier, afin de renseigner sur le format du fichier et donc sur les logiciels pouvant être utilisés pour le manipuler. Chaque fichier peut être enregistré n'importe où dans le système de fichiers, et le logiciel qui le manipule propose un emplacement conventionnel de stockage. Certains formats sont dits propriétaires, c'est-à-dire que le format n'est connu que de son auteur et n'a jamais fait l'objet de publications.

Dans le traitement informatique des fichiers, on distingue deux grandes catégories:

•   les fichiers texte dont le contenu est lisible lorsqu'on l'affiche dans un éditeur de texte ou dans un navigateur internet et

•   les fichiers binaires. Dans ces derniers, les informations y sont stockées de manière particulière et il faut utiliser un programme spécial pour accéder à leur contenu (image JPG, document Word, etc.)

Nom

Nature du contenu

exécutables

fichiers qui peuvent être exécutés par l'ordinateur - autrement dit des programmes.

compressés

fichiers codés selon un procédé qui les rend plus petits que les fichiers originaux non codés. Un programme décompresseur est nécessaire pour effectuer le codage inverse et retrouver ainsi le fichier original.

images

des fichiers qui contiennent des images et du son sous une forme exploitable par l'ordinateur. De tels fichiers peuvent contenir des photos, des pictogrammes, des graphiques, des chansons, de la musique, des émissions radio ou des films.

audio

vidéo

documents

documents écrits, destinés à être imprimés et lus. Le fichier contient le texte ainsi que les informations de typographie (polices de caractères, couleurs).

texte

les fichiers texte brut contiennent des textes écrits, sans indications de typographie. Il peut s'agir de textes destinés aux utilisateurs, tels que des modes d'emploi ou des brouillons ; ou alors de textes destinés à l'ordinateur tels que du code source ou bien des données pour un programme.

Dans ce qui suit, nous ne considérons que les fichiers texte.

11.2   Les entrées/sorties en mode console

11.2.1 Les noms d'unités

Les périphériques en mode console sont traités comme s'il s'agissait de fichiers.

CON : est le nom d'unité de la console. En lecture, il se rapporte au clavier, en écriture, il fait référence à l'écran.

Pour s'en convaincre vous pouvez essayer d'afficher le contenu d'un fichier texte par la commande

COPY con:

Cette commande aura le même effet que la commande TYPE .

De même

COPY con:

va enregistrer dans le fichier "" tous les caractères que vous taperez ensuite au clavier. Il faudra terminer par le caractère [Ctrl+Z] pour mettre fin à cette saisie.

NUL est le nom d'un fichier fictif pouvant servir de destination pour des messages que l'on veut annuler.

11.2.2 Redirection des entrées/sorties « console »

Un programme peut être vu comme un système dans lequel entrent des données, elles y sont traitées et il en sort des résultats et/ou éventuellement des signaux d'erreurs.

Les programmes lancés en mode « invite de commande » :

•   reçoivent des données de l'entrée standard STDIN (généralement le clavier)

•   affichent les résultats sur la sortie standard STDOUT (généralement l'écran)

•   et envoient les messages d'erreur sur une sortie standard pour les erreurs STDERR (généralement l'écran aussi)

En général donc, les entrées/sorties des programmes en mode « invite de commande » concernent la console, c'est à dire le clavier et l'écran.

11.2.3 Redirection des sorties « stdout » et « stderr »

Pour rediriger la sortie standard vers un fichier, il suffit de faire suivre la commande par le signe '>' suivi du nom du fichier de destination. Le symbole '>' doit vous faire penser à une flèche qui indique la sortie choisie.

Exemple : enregistrer le contenu d'un répertoire dans un fichier.

 C:\>DIR >

Cela a pour effet de créer un fichier "" qui recevra le code sorti par la commande DIR. Ce fichier pourra ensuite être manipulé comme n'importe quel fichier texte : édition, recherche, impression, etc.

Si le fichier " " existait déjà, il serait écrasé et remplacé par un nouveau contenu.

Si vous désirez accumuler des données dans un fichier destination sans effacer ce qui y a été enregistré précédemment il suffit d'utiliser deux signes '>' consécutifs

Exemple dans lequel la date du jour est ajoutée à la fin du fichier « » :

 C:>Date /t >>

La sortie vers STDOUT peut être annulée en redirigeant ce qui lui est destiné vers la sortie "NUL"

Exemple : copier un fichier sans voir apparaître le message "1 fichier(s) copié(s)"

 COPY > NUL

11.2.4 Redirection de l'entrée standard « stdin »

Il est tout aussi facile de prendre un fichier comme origine des codes à fournir à un programme.

Exemple de programme qui trie le contenu du fichier d’entrée standard en ordre alphabétique croissant (SORT est une commande prédéfinie dans l’environnement « invite de commandes ») :  sort <

11.2.5 Tubes et filtres

Nous avons vu que les caractères '>' et '<' nous servent pour rediriger des entrées/sorties depuis ou vers des fichiers.

On pourrait imager un programme P1 dont le résultat sera envoyé dans un fichier TEMP qui doive servir comme entrée à un programme P2. Les commandes successives seraient :

P1 > temp

P2 < temp

Les données sorties par le programme P1 servent d'entrée au programme P2.

Il existe un moyen plus simple pour faire passer les données d'un programme à l'autre, c'est le « tube » (« pipe » en anglais) : P1 | P2 Exemple :

C:>DIR | MORE

Ou encore

C:>TYPE | SORT | MORE

Les programmes qui traitent les données qui leur parviennent en entrée pour les ressortir après les avoir traitées sont appelés des filtres.

Parmi eux, les plus célèbres en utilisant « l’invite de commande » sont SORT qui fait des tris, MORE qui affiche page par page et FIND pour rechercher une chaîne de caractères dans un fichier texte.

11.2.6 Réalisation de filtres en Python

Python permet de créer des programme console traitant les fichiers texte à la manière de filtres.

Exemple1.py

import sys line  = sys.stdin.readline() while line!='':

    print(line,end='')     line= sys.stdin.readline()

On peut accéder aux objets représentant les flux standard grâce au module « sys » qui propose plusieurs fonctions et variables permettant d'interagir avec le système, notamment stdin, stdout et stderr.

Ce programme lit chaque ligne du fichier fourni comme fichier d’entrée standard et l’écrit dans le fichier de sortie standard. La méthode readline() lit une ligne entière du fichier d’entrée standard en copiant aussi le caractère fin de ligne. S’il n’y a plus de ligne, c’est-à-dire dans le cas où la fin de fichier est atteinte, la méthode renvoie la chaîne vide « ‘’ ». Par défaut l’instruction print() ajoute un fin de ligne ce qui fait double emploi dans ce cas-ci puisque line contient déjà un caractère fin de ligne. L’option  « end='' » sert à empêcher d’écrire le caractère fin de ligne propre à l’instruction print().

Voici un exemple d’exécution de dans « l’invite de commande » :

j'aime Python j'aime Python

et l'informatique  en général!!! et l'informatique en général!!!

On constate que chaque ligne entrée au clavier (qui est par défaut le fichier d’entrée standard) est recopiée à l’écran (qui est par défaut le fichier de sortie standard).

Si on exécute ce programme dans une « invite de commande » on obtient par exemple :

D:\>python <

import sys

line  = sys.stdin.readline() while line!='':

    print(line,end='')     line= sys.stdin.readline()

Dans ce cas, le fichier standard d’entrée n’est plus le clavier, mais le fichier « » qui est donc affiché à l’écran. On pourrait maintenant effectuer une copie du fichier d’entrée en redirigeant le fichier de sortie standard comme par exemple ici :

D:\Python exemples>python < >

D:\>type import sys

line  = sys.stdin.readline() while line!='':

    print(line,end='')     line= sys.stdin.readline()

Voici un autre exemple de filtre qui a pour effet de numéroter les lignes du fichier d’entrée standard. import fileinput

num=1 for line in fileinput.input():     print(num,' ',line, end='')     num+=1

En exécutant ce programme dans une « invite de commande » on peut le combiner par exemple avec la commande TYPE pour obtenir un listing numéroté :

D:\>type | python

1      import sys

2      line = sys.stdin.readline()

3      while line!='':

4      print(line,end='')

5      line= sys.stdin.readline()

Le résultat de la commande TYPE de « l’invite de commande » est envoyé comme donnée d’entrée à travers un pipe à notre programme Python et produit ainsi un affichage numéroté du fichier . Nous pouvons évidemment rediriger cet affichage dans un fichier sur disque comme ici par exemple :

D:\>type | python >

Le programme suivant calcule et affiche la somme de tous les entiers composant le fichier d’entrée standard. import sys

sum=0 line = sys.stdin.readline() while line!='':         for i in line.split(): sum+= int(i)         line= sys.stdin.readline() print(sum)

Le fichier standard d’entrée est lu ligne par ligne. Chaque ligne est décomposée à l’aide de la méthode split() en ses différentes chaînes de caractères qui sont placées dans une liste. Nous savons que ces chaînes sont des entiers. La boucle for accède à chaque élément de la liste, le convertit en entier et l’additionne à sum.

Ce même programme peut être écrit de manière plus concise encore : import sys

sum=0 for line in sys.stdin: for i in line.split(): sum+= int(i) print(sum)

11.3 Les fonction de manipulation de fichiers

En Python, il est évidemment possible de travailler avec des fichiers texte sans utiliser la redirection des entrées/sorties et sans devoir travailler en mode console.

Pour travailler sur un fichier texte, il faut définir une variable associée à ce fichier en utilisant la méthode open(nom_de_fichier,mode). « nom_de_fichier » désigne une chaîne de caractères contenant le nom du fichier tel qu’il est connu par le système d’exploitation. Le paramètre « mode » indique la façon dont nous voulons travailler avec ce fichier. Voici quelques valeurs possibles pour le mode et les significations respectives..

Mode

Signification

"r"

Ouvre le fichier en mode lecture. C’est le mode par défaut.

"w"

Ouvre le fichier en mode écriture. Si le fichier existe déjà, il est vidé. Dans le cas contraire, il est créé.

"a"

Ouvre le fichier en mode écriture/ajout. Les données seront ajoutées à la fin du fichier. SI le fichier n’existe pas encore, il est créé.

Il existe plusieurs méthodes pour lire et écrire dans un fichier. Dans ce cours, nous ne considérons que deux primitives : readline() et write() appliqué à une variable de type fichier.

La méthode readline() renvoie une chaîne de caractères contenant l’entièreté de la ligne lue, le caractère fin de ligne compris. Lorsque la fin du fichier est atteinte, cette méthode retourne la chaîne de caractères vide « ‘’ ».

La méthode write() écrit dans le fichier l’argument du type chaîne de caractères fourni.

Lorsque le traitement du fichier est terminé, il faut fermer le fichier à l’aide de la méthode close().

#création du fichier fichier=open("","w") nom=input("Entrez le nom : ") while (nom!=''):

        age=input("Entrez l'âge : ")         fichier.write(nom+' '+age+'\n')         nom=input("Entrez le nom : ")

fichier.close() #lecture du fichier fichier=open("","r") line=fichier.readline() while line!='':

        print(line,end='')         line=fichier.readline() fichier.close() #ajout de données à la fin du fichier fichier=open("","a") nom=input("Entrez le nom : ") while (nom!=''):

        age=input("Entrez l'âge : ")         fichier.write(nom+' '+age+'\n')         nom=input("Entrez le nom : ")

fichier.close() #lecture du fichier fichier=open("","r") line=fichier.readline() while line!='':

        print(line,end='')         line=fichier.readline() fichier.close()

Voici un exemple d’une trace d’exécution de ce programme :

Entrez le nom : Tintin

Entrez l'âge : 77

Entrez le nom : Astérix Entrez l'âge : 30

Entrez le nom :

Tintin 77

Astérix 30

Entrez le nom : Obélix

Entrez l'âge : 40

Entrez le nom :

Tintin 77

Astérix 30 Obélix 40

11.4 Exercices résolus

1)      Écrire un programme qui détermine le nombre de lignes et de mots (séparéspar au moins une espace) dans un fichier texte dont le nom est entré sur le fichier d’entrée standard.

nomf=input("Entrez le nom du fichier à analyser : ") fichier=open(nomf,"r") nbLines=0 nbWords=0 line=fichier.readline() while line!='':

        nbLines += 1         nbWords += len(line.split())         line=fichier.readline() print(nomf+" contient "+str(nbLines)+" lignes et ",str(nbWords)+" mots") fichier.close()

2)      Un commissaire de gouvernement en charge d’un examen officiel dispose dufichier de toutes les notes des élèves dans une matière donnée. La correction de l’examen est toujours effectuée par exactement deux correcteurs dont les notes sont reprises en désordre dans le fichier « ». Pour garantir l’impartialité des corrections, les correcteurs ne connaissent pas les noms des élèves, mais uniquement un numéro qui leur a été attribué. Voici un exemple de fichier « » :

2 40

4 35

2 38

 

1 28

6 58

4 38

Le but du programme est d’afficher la moyenne des élèves en ordre croissant dans cette matière. Pour le fichier de données ci-dessus, le résultat à produire aura l’aspect suivant :

Numéro élève Moyenne

1      26.5

2      39.0

3      47.5

4      36.5

6 51.5

import sys

notes={} line=sys.stdin.readline() while line!='':

        detailLigne=line.split()         if detailLigne[0] in notes:

                notes[detailLigne[0]]=str(int(notes[detailLigne[0]])+ int(detailLigne[1]))         else : notes[detailLigne[0]]=detailLigne[1]         line=sys.stdin.readline() print("Numéro élève Moyenne") for i in sorted(notes):         print(i,"{0:16.6}".format(int(notes[i])/2))

11.5 Exercices à faire

Exercice 11-1

Soit un fichier d'entiers représentant les cours en bourse d’un titre sur une période. Écrire un programme console qui affiche le nombre de fois que le titre a effectué une hausse de cours d’un jour à l’autre. Pour simplifier, nous supposons que les cours de bourse sont représentés par des entiers. Les valeurs dans le fichier peuvent être réparties sur plusieurs lignes.

Exemple (se limitant à 7 jours consécutifs) :

45      47      51      38      45

57      57

Le programme affiche : 4

Le titre a en effet subi 4 hausses d’un jour à l’autre (45-47, 47-51, 38-45, 45-57).

Exercice 11-2

Écrivez un programme qui produit une liste de commandes avec leurs détails à partir du fichier de données « ». Cette liste est triée par ordre croissant des numéros de commande, le détail de chaque commande est présenté dans un ordre quelconque.

Chaque ligne du fichier à traiter « » a la structure suivante :

Numéro de l’article, numéro de commande, quantité, prix de l’article.

Voici un exemple de fichier « » :

A5 C1 4 20

A3 C7 2 12

A7 C1 1 10

A3 C2 2 15

A8 C3 1 100

A5 C2 2 20

Le programme à écrire produira les résultats suivants (exemple d’exécution basé sur le fichier « » ci-dessus) :

Liste des commandes

Commande : C1

Article    Prix  Qté  Total

A5          20€   4     80€

A7          10€   1     10€

Commande : C2

Article    Prix  Qté  Total

A3          15€   2     30€

A5          20€   2     40€

Commande : C3

Article    Prix  Qté  Total

A8         100€   1    100€

Commande : C7

Article    Prix  Qté  Total

A3          12€   2     24€

L’ordre dans lequel apparaissent les différents articles est quelconque !

Exercice 11-3

Vous êtes chargé d’écrire un programme permettant de fournir les résultats d’une élection. Lors de cette élection, au maximum 10 listes et 100 candidats se présentent devant les électeurs.

Vous disposez d’un fichier « » contenant toutes les données de cette élection. Il est structuré de la manière suivante :

Le premier entier représente le nombre de listes.

Il est suivi d’une série d’entiers qui fournit le nombre de candidats. Le n-ième entier de cette liste représente le numéro de la liste sur laquelle ce n-ième candidat se présente.

Cette liste de candidats est suivie de tous les bulletins de vote, c’est-à-dire des entiers représentant les numéros des candidats ayant reçu une voix.

Écrire un programme qui affiche une statistique sur le nombre et le pourcentage de voix obtenus par chacune des listes en présence.

Voici un exemple de fichier « » :

3

1 2 2 3 3 3 2

1 1 2 2 2 5 5 1 6 1

4 1 2 3 3 3 1

Dans cet exemple, il y a 7 candidats (1 à 7) avec pour chacun le numéro de la liste sur laquelle il est inscrit. Ici, le candidat 1 sur la liste 1, le candidat 2 sur la liste 2, le candidat 3 sur la liste 2, le candidat 4 sur la liste 3, etc.

Les deux dernières lignes représentent les bulletins de vote. Leur nombre est inconnu à l’avance et ils sont répartis sur une ou plusieurs lignes.

Le programme à écrire produira les résultats suivants (exemple d’exécution basé sur le fichier « » ci-dessus) :

Candidat Liste

1    1

2    2

3    2

4    3

5    3

6    3

7    2

Liste:     1      2      3

Voix:      6      7      4

Liste    1 :      35.29%

Liste    2 :      41.18%

Liste    3 :      23.53%

11.6 Solutions proposées

Exercice 1 import sys

nbHausses=0 cours_precedent = sys.maxsize line=sys.stdin.readline() while line!='':         for cours in line.split():

              if int(cours) > cours_precedent: nbHausses+=1               cours_precedent = int(cours)         line=sys.stdin.readline() print(nbHausses) Exercice 2 import sys

line=sys.stdin.readline() liste=[] while line!='':

        details = line.split()         i=0         found=False         while i<len(liste) and not found:

                if details[1] < liste[i][0]  : found=True                 else : i+=1         if found :

          liste.insert(i,(details[1], details[0], details[2], details[3]))         else :

liste.append((details[1], details[0], details[2], details[3]))         print(liste)         line=sys.stdin.readline()         print("Liste des commandes") commandeEnCours = liste[0][0] print("\nCommande:",commandeEnCours,end='') print("\nArticle Prix Qte Total") for i in range(len(liste)):         if commandeEnCours != liste[i][0] :                 print("\nCommande:",liste[i][0],end='')                 commandeEnCours = liste[i][0]                 print("\nArticle Prix Qte Total")         print(liste[i][1],end='')         print("{0:>10}".format(liste[i][3]+'€'),end='')         print("{0:>3}".format(liste[i][2]),end='')         print("{0:>7}".format(str(int(liste[i][3])*                                   int(liste[i][2]))+'€')) Exercice 3 import sys

nbreListes = int(sys.stdin.readline()) listeCandidats=sys.stdin.readline().split() print("Candidat Liste") for i in range(len(listeCandidats)):

        print("{0:>5}".format(i+1), "{0:>6}".format(listeCandidats[i])) voixListe=[] for i in range(nbreListes): voixListe.append(0) line = sys.stdin.readline() nbreVoix=0 while line!='':         for v in line.split():                 voixListe[int(listeCandidats[int(v)-1])-1]+=1                 nbreVoix += 1         line=sys.stdin.readline() print("Liste: 1      2      3") print("Voix:",end='') for i in range(nbreListes):

        print("{0:>7}".format(voixListe[i]),end='') print("") for i in range(nbreListes):

        print("Liste","{0:>4}".format(i+1),

              ":   ","{0:7.4}".format(int(voixListe[i])/nbreVoix*100)+'%')



D’après Jacques Tisseau, Ecole Nationale d’Ingénieurs de Brest

Monty Python est le nom d'une troupe d'humoristes britanniques rendue célèbre initialement grâce à sa première création, la série télévisée Monty Python's Flying Circus dont la diffusion débuta à la BBC le 5 octobre 1969 et qui se poursuivit durant 45 épisodes jusqu'au 5 décembre 1974.

En typographie et en informatique, le mot espace est généralement féminin pour désigner le blanc obtenu entre les mots imprimés sur le papier.

Recherchez à cet effet le fonctionnement de la méthode format



137