Wikilivres
frwikibooks
https://fr.wikibooks.org/wiki/Accueil
MediaWiki 1.47.0-wmf.9
first-letter
Média
Spécial
Discussion
Utilisateur
Discussion utilisateur
Wikilivres
Discussion Wikilivres
Fichier
Discussion fichier
MediaWiki
Discussion MediaWiki
Modèle
Discussion modèle
Aide
Discussion aide
Catégorie
Discussion catégorie
Transwiki
Discussion Transwiki
Wikijunior
Discussion Wikijunior
TimedText
TimedText talk
Module
Discussion module
Event
Event talk
Nietzsche : Introduction à sa philosophie
0
3831
769313
767472
2026-07-03T03:35:40Z
PandaMystique
119061
769313
wikitext
text/x-wiki
{{Page de garde|image=Nietzsche - Introduction à sa philosophie, Wikilivres, 2026 (2).png|imagedesc=|description=
Friedrich Nietzsche est un philosophe allemand qui compte parmi les penseurs les plus lus et les plus discutés de la modernité philosophique. Son œuvre interroge la morale, la culture, la vérité et la condition humaine, à travers des formes d’écriture qui s’écartent du traité classique : l’aphorisme, l’essai bref, la prose poétique.
|avancement=Ébauche
|cdu=
* {{CDU item|1/10}}
|versions=
{{Moteur}}
{{version imprimable}}
}}
== Table des matières ==
=== Réévaluation des valeurs ===
<small>''Critique de la morale et de la métaphysique héritées''</small>
* [[/La moralité des mœurs/|La moralité des mœurs]] {{4/4}}
* [[/La métaphysique/|La métaphysique]]
* [[/Critique du christianisme/|Critique du christianisme]]
=== Culture et histoire ===
<small>''Nietzsche philologue et critique de la civilisation''</small>
* [[/Le problème de Socrate/|Le problème de Socrate]]
* [[/La culture grecque/|La culture grecque]]
* [[/La culture moderne/|La culture moderne]]
* [[/Philosophie et culture/|Philosophie et culture]]
* [[/Une philosophie politique ?/|Une philosophie politique ?]]
=== Une philosophie de l'affirmation ===
<small>''Les grands concepts qui parcourent l’œuvre''</small>
* [[/L'Apollinien et le Dionysien/|L’Apollinien et le Dionysien]] {{4/4}}
* [[/Volonté de puissance/|Volonté de puissance]]
* [[/Éternel Retour/|Éternel Retour]]
* [[/Surhomme/|Surhomme]]
* ''Amor fati''
=== Commentaires de l’œuvre ===
<small>''Lectures suivies de quelques textes''</small>
* [[/Humain, trop humain/|''Humain, trop humain'']]
* [[/Crépuscule des idoles/|''Crépuscule des idoles'']]
* [[Nietzsche : Introduction à sa philosophie/Ecce Homo - Humain, trop humain et deux suites|''Ecce Homo'']]
== Bibliographie ==
Des ressources bibliographiques plus complètes sont données dans chaque article
* Bernd Magnus et Kathleen M. Higgins (dir.), ''The Cambridge Companion to Nietzsche'', Cambridge, Cambridge University Press, coll. « Cambridge Companions to Philosophy », 1996.
* Keith Ansell Pearson (dir.), ''A Companion to Nietzsche'', Oxford, Blackwell, coll. « Blackwell Companions to Philosophy », 2006.
* John Richardson et Brian Leiter (dir.), ''Nietzsche'', Oxford, Oxford University Press, coll. « Oxford Readings in Philosophy », 2001.
* Patrick Wotling, ''Nietzsche et le problème de la civilisation'', Paris, Presses universitaires de France, coll. « Quadrige », 2009 [1re éd. 1995].
[[Catégorie:Nietzsche : Introduction à sa philosophie (livre)|*]]
[[Catégorie:Histoire de la philosophie]]
[[Catégorie:Philosophe]][[Catégorie:Philosophie]]
[[Catégorie:Classe 1 - Philosophie et psychologie]]
{{AutoCat}}
__NOTOC__
ndre34zmzj0f5esrar932lwe5ftyjfm
Philosophie
0
5270
769316
768240
2026-07-03T05:06:13Z
PandaMystique
119061
769316
wikitext
text/x-wiki
<!-- ══════════════════════════════════════════════
EN-TÊTE
══════════════════════════════════════════════ -->
<div style="padding: 6px 0 18px; border-bottom: 2px solid #1a2230; margin-bottom: 22px;">
<div style="font-size: 1.6em; font-weight: bold; line-height: 1.2; margin-bottom: 4px;">Classification de la philosophie</div>
<div style="font-size: 0.9em; line-height: 1.5;">Portail raisonné des livres, manuels et dictionnaires de philosophie sur Wikilivres. Les entrées sont rangées en cinq grandes aires, subdivisées selon la taxonomie standard des champs philosophiques.</div>
</div>
{{PhiloRecherche}}
<!-- ══════════════════════════════════════════════
ŒUVRE À LA UNE
══════════════════════════════════════════════ -->
<div style=" border: 1px solid #c8b898; border-radius: 8px; padding: 20px 24px; margin: 22px 0 26px;">
<table style="width: 100%; border-collapse: collapse;">
{{#switch: {{#expr: {{#time:z}} mod 7 }}
| 1 = <tr>
<td style="width: 76px; vertical-align: top; padding-right: 20px;">
<div style="background: #9a7840; color: #f4ebe0; text-align: center; padding: 34px 4px; font-size: 13px; letter-spacing: 0.15em; font-weight: 500; border-radius: 2px;">1677</div>
</td>
<td style="vertical-align: top;">
<div style="font-size: 0.72em; letter-spacing: 0.25em; text-transform: uppercase; font-weight: bold; margin-bottom: 6px;">Œuvre à la une</div>
<div style="font-size: 1.3em; font-weight: bold; line-height: 1.2; margin-bottom: 3px;">''[[Commentaire de l'Éthique{{!}}Éthique]]''</div>
<div style="font-size: 0.92em; font-style: italic; margin-bottom: 10px;">Baruch Spinoza</div>
<div style="font-size: 0.9em; line-height: 1.65;">Un traité conduit à la manière des géomètres, des définitions de la substance et de Dieu jusqu'à la liberté du sage et la joie de comprendre.</div>
<div style="margin-top: 10px; font-size: 0.88em;">[[Commentaire de l'Éthique{{!}}Lire le commentaire →]]</div>
</td>
</tr>
| 2 = <tr>
<td style="width: 76px; vertical-align: top; padding-right: 20px;">
<div style="background: #9a7840; color: #f4ebe0; text-align: center; padding: 34px 4px; font-size: 13px; letter-spacing: 0.15em; font-weight: 500; border-radius: 2px;">1755</div>
</td>
<td style="vertical-align: top;">
<div style="font-size: 0.72em; letter-spacing: 0.25em; text-transform: uppercase; font-weight: bold; margin-bottom: 6px;">Œuvre à la une</div>
<div style="font-size: 1.3em; font-weight: bold; line-height: 1.2; margin-bottom: 3px;">''[[Commentaire philosophique/Discours sur l'origine et les fondements de l'inégalité parmi les hommes{{!}}Discours sur l'inégalité]]''</div>
<div style="font-size: 0.92em; font-style: italic; margin-bottom: 10px;">Jean-Jacques Rousseau</div>
<div style="font-size: 0.9em; line-height: 1.65;">Comment, de l'homme des bois aux sociétés policées, l'inégalité s'est peu à peu installée parmi les hommes : une enquête sur ce que la civilisation a fait de notre nature.</div>
<div style="margin-top: 10px; font-size: 0.88em;">[[Commentaire philosophique/Discours sur l'origine et les fondements de l'inégalité parmi les hommes{{!}}Lire le commentaire →]]</div>
</td>
</tr>
| 3 = <tr>
<td style="width: 76px; vertical-align: top; padding-right: 20px;">
<div style="background: #9a7840; color: #f4ebe0; text-align: center; padding: 34px 4px; font-size: 13px; letter-spacing: 0.15em; font-weight: 500; border-radius: 2px;">1670</div>
</td>
<td style="vertical-align: top;">
<div style="font-size: 0.72em; letter-spacing: 0.25em; text-transform: uppercase; font-weight: bold; margin-bottom: 6px;">Œuvre à la une</div>
<div style="font-size: 1.3em; font-weight: bold; line-height: 1.2; margin-bottom: 3px;">''[[Philosophie/Commentaire du passage à propos de l'Homme esclave du divertissement{{!}}Pensées]]''</div>
<div style="font-size: 0.92em; font-style: italic; margin-bottom: 10px;">Blaise Pascal</div>
<div style="font-size: 0.9em; line-height: 1.65;">Pourquoi nous fuyons le repos et la chambre où il faudrait savoir rester seul : l'analyse du divertissement comme art d'oublier notre condition.</div>
<div style="margin-top: 10px; font-size: 0.88em;">[[Philosophie/Commentaire du passage à propos de l'Homme esclave du divertissement{{!}}Lire le commentaire →]]</div>
</td>
</tr>
| 4 = <tr>
<td style="width: 76px; vertical-align: top; padding-right: 20px;">
<div style="background: #9a7840; color: #f4ebe0; text-align: center; padding: 34px 4px; font-size: 13px; letter-spacing: 0.15em; font-weight: 500; border-radius: 2px;">-300</div>
</td>
<td style="vertical-align: top;">
<div style="font-size: 0.72em; letter-spacing: 0.25em; text-transform: uppercase; font-weight: bold; margin-bottom: 6px;">Œuvre à la une</div>
<div style="font-size: 1.3em; font-weight: bold; line-height: 1.2; margin-bottom: 3px;">''[[Commentaire philosophique/Lettre à Ménécée{{!}}Lettre à Ménécée]]''</div>
<div style="font-size: 0.92em; font-style: italic; margin-bottom: 10px;">Épicure</div>
<div style="font-size: 0.9em; line-height: 1.65;">Une lettre brève qui tient toute une morale : n'avoir plus peur des dieux ni de la mort, et mesurer ses désirs pour gagner la tranquillité de l'âme.</div>
<div style="margin-top: 10px; font-size: 0.88em;">[[Commentaire philosophique/Lettre à Ménécée{{!}}Lire le commentaire →]]</div>
</td>
</tr>
| 5 = <tr>
<td style="width: 76px; vertical-align: top; padding-right: 20px;">
<div style="background: #9a7840; color: #f4ebe0; text-align: center; padding: 34px 4px; font-size: 13px; letter-spacing: 0.15em; font-weight: 500; border-radius: 2px;">1888</div>
</td>
<td style="vertical-align: top;">
<div style="font-size: 0.72em; letter-spacing: 0.25em; text-transform: uppercase; font-weight: bold; margin-bottom: 6px;">Œuvre à la une</div>
<div style="font-size: 1.3em; font-weight: bold; line-height: 1.2; margin-bottom: 3px;">''[[Nietzsche : Introduction à sa philosophie/Crépuscule des idoles{{!}}Crépuscule des idoles]]''</div>
<div style="font-size: 0.92em; font-style: italic; margin-bottom: 10px;">Friedrich Nietzsche</div>
<div style="font-size: 0.9em; line-height: 1.65;">Une traversée « à coups de marteau » des idoles de la morale et de la raison, écrite vite et drue, où Nietzsche ausculte les certitudes héritées.</div>
<div style="margin-top: 10px; font-size: 0.88em;">[[Nietzsche : Introduction à sa philosophie/Crépuscule des idoles{{!}}Lire le commentaire →]]</div>
</td>
</tr>
| 6 = <tr>
<td style="width: 76px; vertical-align: top; padding-right: 20px;">
<div style="background: #9a7840; color: #f4ebe0; text-align: center; padding: 34px 4px; font-size: 13px; letter-spacing: 0.15em; font-weight: 500; border-radius: 2px;">1785</div>
</td>
<td style="vertical-align: top;">
<div style="font-size: 0.72em; letter-spacing: 0.25em; text-transform: uppercase; font-weight: bold; margin-bottom: 6px;">Œuvre à la une</div>
<div style="font-size: 1.3em; font-weight: bold; line-height: 1.2; margin-bottom: 3px;">''[[Commentaire de la Fondation de la métaphysique des mœurs{{!}}Fondation de la métaphysique des mœurs]]''</div>
<div style="font-size: 0.92em; font-style: italic; margin-bottom: 10px;">Emmanuel Kant</div>
<div style="font-size: 0.9em; line-height: 1.65;">Que vaut une action morale ? Kant y cherche le principe d'une volonté bonne et dégage l'impératif catégorique : n'agir que selon une maxime dont on peut vouloir qu'elle devienne loi universelle.</div>
<div style="margin-top: 10px; font-size: 0.88em;">[[Commentaire de la Fondation de la métaphysique des mœurs{{!}}Lire le commentaire →]]</div>
</td>
</tr>
| 0
| #default = <tr>
<td style="width: 76px; vertical-align: top; padding-right: 20px;">
<div style="background: #9a7840; color: #f4ebe0; text-align: center; padding: 34px 4px; font-size: 13px; letter-spacing: 0.15em; font-weight: 500; border-radius: 2px;">1641</div>
</td>
<td style="vertical-align: top;">
<div style="font-size: 0.72em; letter-spacing: 0.25em; text-transform: uppercase; font-weight: bold; margin-bottom: 6px;">Œuvre à la une</div>
<div style="font-size: 1.3em; font-weight: bold; line-height: 1.2; margin-bottom: 3px;">''[[Méditations métaphysiques{{!}}Méditations métaphysiques]]''</div>
<div style="font-size: 0.92em; font-style: italic; margin-bottom: 10px;">René Descartes</div>
<div style="font-size: 0.9em; line-height: 1.65;">Six méditations qui refondent le savoir sur le doute le plus exigeant, jusqu'à la première certitude retrouvée : je pense, donc je suis.</div>
<div style="margin-top: 10px; font-size: 0.88em;">[[Méditations métaphysiques{{!}}Lire le commentaire →]]</div>
</td>
</tr>
}}
</table>
</div>
<!-- ══════════════════════════════════════════════
CLUSTER 1 — MÉTAPHYSIQUE ET ÉPISTÉMOLOGIE
══════════════════════════════════════════════ -->
<div style="margin: 26px 0 10px; padding: 6px 0 4px; border-bottom: 1px solid #1a2230;">
<div style="font-size: 1.15em; font-weight: bold; ">Métaphysique et épistémologie</div>
</div>
<table style="width: 100%; border-collapse: separate; border-spacing: 14px 14px;">
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">[[Philosophie/Théorie de la connaissance|Théorie de la connaissance]] <span style=" font-weight: bold;">(8)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Connaissance|Connaissance]]<br/>
<span style=" font-weight: bold;">[[Philosophie/Théorie de la connaissance/Une définition traditionnelle|Définition traditionnelle]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Théorie de la connaissance/Le Problème de Gettier|Problème de Gettier]]</span><br/>
[[Dictionnaire de philosophie/Croyance|Croyance]]<br/>
[[Dictionnaire de philosophie/Vérité|Vérité]] <span style=" font-weight: 300;">([[Manuel de terminale de philosophie/Vérité|<small>terminale</small>]])</span><br/>
[[Dictionnaire de philosophie/Certitude|Certitude]]<br/>
[[Dictionnaire de philosophie/Cogito|Cogito]]<br/>
<span style=" font-weight: bold;">[[Philosophie/Raison et réel|Raison et réel]]</span>
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Doute et scepticisme <span style=" font-weight: bold;">(6)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Scepticisme|Scepticisme]]<br/>
[[Dictionnaire de philosophie/Doute|Doute]]<br/>
[[Dictionnaire de philosophie/Acatalépsie|Acatalépsie]]<br/>
[[Dictionnaire de philosophie/Agnosticisme|Agnosticisme]]<br/>
[[Dictionnaire de philosophie/Apparence|Apparence]]<br/>
[[Dictionnaire de philosophie/Erreur|Erreur]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Sources et méthode <span style=" font-weight: bold;">(8)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Raison|Raison]]</span><br/>
[[Dictionnaire de philosophie/Empirisme|Empirisme]]<br/>
[[Dictionnaire de philosophie/A priori|A priori]]<br/>
[[Dictionnaire de philosophie/Criticisme|Criticisme]]<br/>
[[Dictionnaire de philosophie/Abduction|Abduction]]<br/>
[[Dictionnaire de philosophie/Découverte|Découverte]]<br/>
[[Dictionnaire de philosophie/Expérience de pensée|Expérience de pensée]]<br/>
[[Dictionnaire de philosophie/Épistémologie|Épistémologie]]
</div>
</td>
</tr>
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">[[Dictionnaire de philosophie/Métaphysique|Métaphysique]] <span style=" font-weight: bold;">(8)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Absolu|Absolu]]<br/>
[[Dictionnaire de philosophie/Existence|Existence]]<br/>
[[Dictionnaire de philosophie/Accident|Accident]]<br/>
[[Dictionnaire de philosophie/Attribut|Attribut]]<br/>
[[Dictionnaire de philosophie/Individu|Individu]]<br/>
[[Dictionnaire de philosophie/Âme|Âme]]<br/>
[[Dictionnaire de philosophie/Atomisme|Atomisme]]<br/>
[[Dictionnaire de philosophie/Willard Van Orman Quine/Barbe de Platon|Barbe de Platon]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Cause, devenir et destin <span style=" font-weight: bold;">(7)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Acte/Puissance|Acte et Puissance]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Temps|Temps]]</span><br/>
[[Dictionnaire de philosophie/Causalité|Causalité]]<br/>
[[Dictionnaire de philosophie/Contingence|Contingence]]<br/>
[[Dictionnaire de philosophie/Déterminisme|Déterminisme]]<br/>
[[Dictionnaire de philosophie/Finitude|Finitude]]<br/>
[[Dictionnaire de philosophie/Mort|Mort]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">[[Philosophie/Philosophie de l'esprit|Philosophie de l'esprit]] <span style=" font-weight: bold;">(11)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Philosophie/Philosophie de l'esprit/Introduction|Introduction]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Philosophie de l'esprit/Argument de la connaissance|Argument de la connaissance]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Philosophie de l'esprit/Ce que Marie ne savait pas|Ce que Marie ne savait pas]]</span><br/>
[[Dictionnaire de philosophie/Conscience|Conscience]] <span style=" font-weight: 300;">([[Manuel de terminale de philosophie/Conscience|<small>terminale</small>]])</span><br/>
[[Dictionnaire de philosophie/Dualisme|Dualisme]] <span style=" font-weight: 300;">([[Philosophie/Philosophie de l'esprit/Dualisme|<small>cours</small>]] · [[Manuel de terminale de philosophie/Dualisme|<small>terminale</small>]])</span><br/>
[[Dictionnaire de philosophie/Émergence|Émergence]]<br/>
[[Philosophie/Philosophie de l'esprit/Physicalisme|Physicalisme]]<br/>
<span style=" font-weight: bold;">[[Dictionnaire de philosophie/Sujet|Sujet]]</span><br/>
[[Dictionnaire de philosophie/Imagination|Imagination]]<br/>
<span style=" font-weight: bold;">[[Philosophie/Perception|Perception]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Inconscient|Inconscient]]</span>
</div>
</td>
</tr>
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie du langage <span style=" font-weight: bold;">(5)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Langage|Langage]]</span><br/>
[[Dictionnaire de philosophie/Argument|Argument]]<br/>
[[Dictionnaire de philosophie/Concept|Concept]]<br/>
[[Dictionnaire de philosophie/Définition|Définition]]<br/>
[[Dictionnaire de philosophie/Dialogue|Dialogue]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie de l'action <span style=" font-weight: bold;">(8)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Action|Action]]<br/>
[[Dictionnaire de philosophie/Aboulie|Aboulie]]<br/>
[[Dictionnaire de philosophie/Altruisme|Altruisme]]<br/>
[[Dictionnaire de philosophie/Authenticité|Authenticité]]<br/>
<span style=" font-weight: bold;">[[Philosophie/Désir|Désir]]</span><br/>
[[Dictionnaire de philosophie/Désir|Désir (dictionnaire)]]<br/>
<span style=" font-weight: bold;">[[Philosophie/Liberté|Liberté]]</span><br/>
[[Dictionnaire de philosophie/Besoin|Besoin]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #3a5a80; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie de la religion <span style=" font-weight: bold;">(7)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Religion|Religion]]</span><br/>
<span style=" font-weight: bold;">[[Dictionnaire de philosophie/Athéisme|Athéisme]]</span><br/>
[[Dictionnaire de philosophie/Déisme|Déisme]]<br/>
<span style=" font-weight: bold;">[[Dictionnaire de philosophie/Monothéisme|Monothéisme]]</span><br/>
[[Dictionnaire de philosophie/Panthéisme|Panthéisme]]<br/>
[[Dictionnaire de philosophie/Théisme|Théisme]]<br/>
[[Dictionnaire de philosophie/Polythéisme|Polythéisme]]
</div>
</td>
</tr>
</table>
<!-- ══════════════════════════════════════════════
CLUSTER 2 — THÉORIE DE LA VALEUR
══════════════════════════════════════════════ -->
<div style="margin: 22px 0 10px; padding: 6px 0 4px; border-bottom: 1px solid #1a2230;">
<div style="font-size: 1.15em; font-weight: bold; ">Théorie de la valeur</div>
</div>
<table style="width: 100%; border-collapse: separate; border-spacing: 14px 14px;">
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #a86b3d; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Éthique normative <span style=" font-weight: bold;">(9)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Dictionnaire de philosophie/Morale|Morale]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Devoir|Devoir]]</span><br/>
[[Dictionnaire de philosophie/Bonheur|Bonheur]] <span style=" font-weight: 300;">([[Manuel de terminale de philosophie/Bonheur|<small>terminale</small>]])</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Liberté|Liberté (terminale)]]</span><br/>
[[Dictionnaire de philosophie/Ataraxie|Ataraxie]]<br/>
[[Dictionnaire de philosophie/Amour|Amour]]<br/>
[[Dictionnaire de philosophie/Amitié|Amitié]]<br/>
[[Dictionnaire de philosophie/Bien|Bien]]<br/>
[[Dictionnaire de philosophie/Courage|Courage]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #a86b3d; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Justice et société <span style=" font-weight: bold;">(8)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/État|État]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Justice|Justice]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Travail|Travail]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Travail et technique|Travail et technique]]</span><br/>
[[Dictionnaire de philosophie/Droit|Droit]]<br/>
[[Dictionnaire de philosophie/Démocratie|Démocratie]]<br/>
[[Dictionnaire de philosophie/Égalité|Égalité]]<br/>
[[Dictionnaire de philosophie/État de nature|État de nature]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #a86b3d; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Autrui, autonomie et existence <span style=" font-weight: bold;">(9)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Philosophie/Autrui|Autrui]]</span><br/>
[[Dictionnaire de philosophie/Altérité|Altérité]]<br/>
[[Dictionnaire de philosophie/Autorité|Autorité]]<br/>
[[Dictionnaire de philosophie/Autonomie|Autonomie]]<br/>
[[Dictionnaire de philosophie/Absurde|Absurde]]<br/>
[[Dictionnaire de philosophie/Affection|Affection]]<br/>
[[Dictionnaire de philosophie/Angoisse|Angoisse]]<br/>
[[Dictionnaire de philosophie/Divertissement|Divertissement]]<br/>
[[Dictionnaire de philosophie/Facticité|Facticité]]
</div>
</td>
</tr>
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #a86b3d; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Éthique appliquée <span style=" font-weight: bold;">(5)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Avortement|Avortement (éthique)]]<br/>
[[Dictionnaire de philosophie/Animal|Animal (droits)]]<br/>
[[Dictionnaire de philosophie/Bioéthique|Bioéthique]]<br/>
[[Dictionnaire de philosophie/Euthanasie|Euthanasie]]<br/>
[[Dictionnaire de philosophie/Personne non-humaine|Personne non-humaine]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #a86b3d; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Pouvoir et critique sociale <span style=" font-weight: bold;">(6)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Absolutisme|Absolutisme]]<br/>
[[Dictionnaire de philosophie/Anarchisme|Anarchisme]]<br/>
[[Dictionnaire de philosophie/Aliénation|Aliénation]]<br/>
[[Dictionnaire de philosophie/Consensus|Consensus]]<br/>
[[Dictionnaire de philosophie/Décadence|Décadence]]<br/>
[[Dictionnaire de philosophie/Désobéissance|Désobéissance]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #a86b3d; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Esthétique et culture <span style=" font-weight: bold;">(8)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Art|Art]]</span><br/>
[[Dictionnaire de philosophie/Art|Art (dictionnaire)]]<br/>
[[Dictionnaire de philosophie/Art (introduction)|Art (introduction)]]<br/>
[[Dictionnaire de philosophie/Art et Vérité|Art et vérité]]<br/>
[[Dictionnaire de philosophie/Beau|Beau]]<br/>
<span style=" font-weight: bold;">[[Philosophie/Culture|Culture]]</span><br/>
[[Dictionnaire de philosophie/Culture|Culture (dictionnaire)]]<br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Histoire|Histoire]]</span>
</div>
</td>
</tr>
</table>
<!-- ══════════════════════════════════════════════
CLUSTER 3 — SCIENCE, LOGIQUE ET MATHÉMATIQUES
══════════════════════════════════════════════ -->
<div style="margin: 22px 0 10px; padding: 6px 0 4px; border-bottom: 1px solid #1a2230;">
<div style="font-size: 1.15em; font-weight: bold; ">Science, logique et mathématiques</div>
</div>
<table style="width: 100%; border-collapse: separate; border-spacing: 14px 14px;">
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #5a7a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Logique <span style=" font-weight: bold;">(9)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/A (logique)|A (logique)]]<br/>
[[Dictionnaire de philosophie/Abstraction|Abstraction]]<br/>
[[Dictionnaire de philosophie/Antinomie|Antinomie]]<br/>
[[Dictionnaire de philosophie/Aporie|Aporie]]<br/>
[[Dictionnaire de philosophie/Axiome|Axiome]]<br/>
[[Dictionnaire de philosophie/Dialectique|Dialectique]]<br/>
[[Dictionnaire de philosophie/Déduction|Déduction]]<br/>
[[Dictionnaire de philosophie/Démonstration|Démonstration]]<br/>
[[Dictionnaire de philosophie/Diallèle|Diallèle]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #5a7a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie des sciences <span style=" font-weight: bold;">(6)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Philosophie/Théorie et expérience|Théorie et expérience]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Science|Science]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Technique|Technique]]</span><br/>
[[Dictionnaire de philosophie/Épistémologie|Épistémologie]]<br/>
[[Dictionnaire de philosophie/Bateau de Neurath|Bateau de Neurath]]<br/>
[[Dictionnaire de philosophie/Convention|Convention]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #5a7a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Nature et vivant <span style=" font-weight: bold;">(4)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Nature|Nature]]</span><br/>
[[Dictionnaire de philosophie/Animal|Animal]]<br/>
[[Dictionnaire de philosophie/Anthropocentrisme|Anthropocentrisme]]<br/>
[[Dictionnaire de philosophie/Intelligence animale|Intelligence animale]]
</div>
</td>
</tr>
</table>
<!-- ══════════════════════════════════════════════
CLUSTER 4 — HISTOIRE DE LA PHILOSOPHIE
══════════════════════════════════════════════ -->
<div style="margin: 22px 0 10px; padding: 6px 0 4px; border-bottom: 1px solid #1a2230;">
<div style="font-size: 1.15em; font-weight: bold; ">[[Philosophie/Histoire de la philosophie|Histoire de la philosophie]] <span style=" font-weight: bold; font-size: 0.92em;">(48)</span></div>
</div>
<table style="width: 100%; border-collapse: separate; border-spacing: 14px 14px;">
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #9a7840; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Antiquité <span style=" font-weight: bold;">(14)</span></div>
<div style="font-size: 0.82em; margin-bottom: 6px;">VI<sup>e</sup> av. — V<sup>e</sup> siècle</div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style="font-weight: bold; ">[[Philosophie/Présocratiques|Présocratiques]]</span> <span style=" font-weight: 300;">([[Philosophie/Présocratiques/Liste des Présocratiques|<small>Liste complète</small>]])</span><br/>
[[Philosophie/Thalès de Milet|Thalès de Milet]] - <span style=" font-weight: bold;">[[Philosophie/Anaximandre de Milet|Anaximandre]]</span> - <span style=" font-weight: bold;">[[Philosophie/Pythagore|Pythagore]]</span> - <span style=" font-weight: bold;">[[Parménide|Parménide]]</span> - [[Dictionnaire de philosophie/Anaxagore|Anaxagore]] - [[Dictionnaire de philosophie/Empédocle|Empédocle]]<br>
<span style=" font-weight: bold;">[[Pour lire Platon|Platon]]</span> <span style=" font-weight: 300;">([[Pour lire Platon/Guide des dialogues|<small>Guide des dialogues</small>]])</span><br/>
[[Dictionnaire de philosophie/Aristote|Aristote]]<br/>
<span style="font-weight: bold; ">Philosophie hellénistique</span><br/>
<span style=" font-weight: bold;">[[Commentaire philosophique/Lettre à Ménécée|Épicure]]</span> - <span style=" font-weight: bold;">[[Dictionnaire de philosophie/Ataraxie|Stoïcisme]]</span><br/>
[[Dictionnaire de philosophie/Acatalépsie|Scepticisme, acatalépsie]]<br/>
[[Dictionnaire de philosophie/Carnéade|Carnéade]]<br/>
[[Dictionnaire de philosophie/Pyrrhon d'Élis|Pyrrhon d'Élis]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #9a7840; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie médiévale <span style=" font-weight: bold;">(0)</span></div>
<div style="font-size: 0.82em; margin-bottom: 6px;">V<sup>e</sup> — XV<sup>e</sup> siècle</div>
<div style="font-size: 0.88em; line-height: 1.85; font-style: italic;">
<span style=" font-style: normal;">○</span> Augustin<br/>
<span style=" font-style: normal;">○</span> Anselme<br/>
<span style=" font-style: normal;">○</span> Thomas d'Aquin<br/>
<span style=" font-style: normal;">○</span> Averroès<br/>
<span style="font-size: 0.85em; ">(pages à rédiger)</span>
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #9a7840; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie classique <span style=" font-weight: bold;">(10)</span></div>
<div style="font-size: 0.82em; margin-bottom: 6px;">XVI<sup>e</sup> — XVIII<sup>e</sup> siècle</div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Philosophie moderne|Panorama : la philosophie moderne]]<br/>
<span style=" font-weight: bold;">[[Méditations métaphysiques|Descartes, Méditations]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Commentaire du passage à propos de l'Homme esclave du divertissement|Pascal, Divertissement]]</span><br/>
<span style=" font-weight: bold;">[[Commentaire de l'Éthique|Spinoza, Éthique]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Vocabulaire/David Hume|Hume]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Vocabulaire/Kant|Kant]]</span><br/>
<span style=" font-weight: bold;">[[Commentaire philosophique/Discours sur l'origine et les fondements de l'inégalité parmi les hommes|Rousseau, Inégalité]]</span><br/>
[[Dictionnaire de philosophie/René Descartes|René Descartes]]<br/>
[[Dictionnaire de philosophie/Julien Offray de La Mettrie|La Mettrie]]<br/>
[[Dictionnaire de philosophie/Chamfort|Chamfort]]
</div>
</td>
</tr>
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #9a7840; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie du XIX<sup>e</sup> siècle <span style=" font-weight: bold;">(5)</span></div>
<div style="font-size: 0.82em; margin-bottom: 6px;">De l'idéalisme au soupçon</div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Karl Marx|Karl Marx]]<br/>
<span style=" font-weight: bold;">[[Nietzsche : Introduction à sa philosophie|Nietzsche, une introduction]]</span><br/>
[[Dictionnaire de philosophie/Friedrich Nietzsche|Friedrich Nietzsche]]<br/>
[[Dictionnaire de philosophie/Max Stirner|Max Stirner]]<br/>
[[Dictionnaire de philosophie/Pierre Kropotkine|Pierre Kropotkine]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #9a7840; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Philosophie des XX<sup>e</sup> et XXI<sup>e</sup> siècles <span style=" font-weight: bold;">(7)</span></div>
<div style="font-size: 0.82em; margin-bottom: 6px;">Figures et itinéraires</div>
<div style="font-size: 0.88em; line-height: 1.75;">
[[Dictionnaire de philosophie/Moritz Schlick|Moritz Schlick]]<br/>
[[Dictionnaire de philosophie/Maurice Merleau-Ponty|Maurice Merleau-Ponty]]<br/>
[[Dictionnaire de philosophie/Willard Van Orman Quine|Willard Van Orman Quine]]<br/>
[[Dictionnaire de philosophie/Thomas Nagel|Thomas Nagel]]<br/>
[[Dictionnaire de philosophie/David Chalmers|David Chalmers]]<br/>
[[Dictionnaire de philosophie/Timothy Williamson|Timothy Williamson]]<br/>
[[Dictionnaire de philosophie/Philosophie suédoise contemporaine|Philosophie suédoise]]
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #9a7840; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Courants du XX<sup>e</sup> siècle <span style=" font-weight: bold;">(6)</span></div>
<div style="font-size: 0.82em; margin-bottom: 6px;">Écoles et traditions</div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Philosophie/Philosophie analytique|Philosophie analytique]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Philosophie analytique/Gottlob Frege|Gottlob Frege]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Existence et temps|Existentialisme]]</span><br/>
<span style=" font-weight: bold;">[[Être et Temps|Être et Temps (Heidegger)]]</span><br/>
[[Dictionnaire de philosophie/Dasein|Phénoménologie / Dasein]]<br/>
[[Dictionnaire de philosophie/Différence ontologique|Différence ontologique]]
</div>
</td>
</tr>
</table>
<div style=" border: 1px solid #d4dae2; border-left: 4px solid #9a7840; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; margin: 0 0 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Traditions non occidentales <span style=" font-weight: bold;">(6)</span> <span style="font-weight: normal; font-size: 0.85em;">· Afrique, Amériques, Asie</span></div>
<div style="font-size: 0.88em; line-height: 1.9;">
[[Dictionnaire de philosophie/Philosophie africaine|Philosophie africaine]] · [[Dictionnaire de philosophie/Argentine (Philosophie)|Argentine (XX<sup>e</sup> siècle)]] · [[Dictionnaire de philosophie/Chine|Chine]] · [[Dictionnaire de philosophie/Ghana|Ghana]] · [[Dictionnaire de philosophie/Ubuntu|Ubuntu]] · [[Dictionnaire de philosophie/Esthétique dans la pensée chinoise|Esthétique dans la pensée chinoise]]
</div>
</div>
<!-- ══════════════════════════════════════════════
CLUSTER 5 — OUVRAGES DE RÉFÉRENCE
══════════════════════════════════════════════ -->
<div style="margin: 22px 0 10px; padding: 6px 0 4px; border-bottom: 1px solid #1a2230;">
<div style="font-size: 1.15em; font-weight: bold; ">Ouvrages de référence et pédagogiques</div>
</div>
<!-- Autres ouvrages -->
<table style="width: 100%; border-collapse: separate; border-spacing: 14px 14px;">
<tr>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #4a4a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">[[Manuel de terminale de philosophie|Manuel de terminale]] <span style=" font-weight: bold;">(26)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
Éthique & action <span style="">(4)</span><br/>
Esprit & conscience <span style="">(4)</span><br/>
Connaissance & vérité <span style="">(5)</span><br/>
Monde & société <span style="">(4)</span><br/>
Culture & sens <span style="">(6)</span><br/>
Méthode & ressources <span style="">(3)</span>
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #4a4a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">[[:Catégorie:Commentaire philosophique|Commentaires d'œuvres]] <span style=" font-weight: bold;">(22)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style="font-weight: bold;">[[Commentaire philosophique/Lettre à Ménécée|Lettre à Ménécée]]</span> <span style="">·</span> Épicure<br/>
<span style="font-weight: bold;">[[Méditations métaphysiques|Méditations]]</span> <span style="">·</span> Descartes<br/>
<span style="font-weight: bold;">[[Philosophie/Commentaire du passage à propos de l'Homme esclave du divertissement|Divertissement]]</span> <span style="">·</span> Pascal<br/>
<span style="font-weight: bold;">[[Philosophie/Commentaire du passage à propos des deux infinis|Les deux infinis]]</span> <span style="">·</span> Pascal<br/>
<span style="font-weight: bold;">[[Commentaire de l'Éthique|Éthique]]</span> <span style="">·</span> Spinoza<br/>
<span style="font-weight: bold;">[[Commentaire philosophique/L'état de nature selon Hobbes et Rousseau.|L'état de nature]]</span> <span style="">·</span> Hobbes et Rousseau<br/>
<span style="font-weight: bold;">[[Commentaire philosophique/Discours sur l'origine et les fondements de l'inégalité parmi les hommes|Inégalité]]</span> <span style="">·</span> Rousseau<br/>
<span style="font-weight: bold;">[[Commentaire philosophique/Étude de texte sur la différence entre l'homme et l'animal à l'état de nature|L'homme et l'animal]]</span> <span style="">·</span> étude de texte<br/>
<span style="font-weight: bold;">[[Commentaire de la Fondation de la métaphysique des mœurs|Fondation de la métaphysique des mœurs]]</span> <span style="">·</span> Kant<br/>
<span style="font-weight: bold;">[[Nietzsche : Introduction à sa philosophie/Humain, trop humain|Humain, trop humain]]</span> <span style="">·</span> Nietzsche<br/>
<span style="font-weight: bold;">[[Nietzsche : Introduction à sa philosophie/Crépuscule des idoles|Crépuscule des idoles]]</span> <span style="">·</span> Nietzsche<br/>
<span style="font-weight: bold;">[[Être et Temps|Être et Temps]]</span> <span style="">·</span> Heidegger<br/>
<span style="font-weight: bold;">[[Bonheur, morale, et philosophie épistolaire|Philosophie épistolaire]]</span> <span style="">·</span> dossier
</div>
</td>
<td style="width: 33.33%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #4a4a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; margin-bottom: 6px;">[[:Catégorie:Vocabulaire philosophique|Vocabulaires]] <span style=" font-weight: bold;">(4)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style="font-weight: bold;">[[Philosophie/Présocratiques/Vocabulaire|Présocratiques]]</span><br/>
<span style="font-weight: bold;">[[Pour lire Platon/Vocabulaire|Platon]]</span><br/>
<span style="font-weight: bold;">[[Philosophie/Vocabulaire/David Hume|David Hume]]</span><br/>
<span style="font-weight: bold;">[[Philosophie/Vocabulaire/Kant|Kant]]</span>
</div>
<div style="height: 1px; margin: 10px 0;"></div>
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; margin-bottom: 10px;">[[Philosophie/Une brève introduction|Une brève introduction]] </div>
</td>
</tr>
</table>
<table style="width: 100%; border-collapse: separate; border-spacing: 14px 14px;">
<tr>
<td style="width: 50%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #4a4a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">[[Philosophie/Repères|Repères conceptuels]] <span style=" font-weight: bold;">(6)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Philosophie/Repères|Vue d'ensemble des repères]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Absolu/relatif|Absolu / relatif]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Abstrait/concret|Abstrait / concret]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Contingent/nécessaire/possible|Contingent / nécessaire / possible]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Expliquer/comprendre|Expliquer / comprendre]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Objectif/subjectif|Objectif / subjectif]]</span>
</div>
</td>
<td style="width: 50%; vertical-align: top; border: 1px solid #d4dae2; border-left: 4px solid #4a4a4a; border-radius: 0 8px 8px 0; padding: 12px 16px 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">Méthode et entraînement <span style=" font-weight: bold;">(3)</span></div>
<div style="font-size: 0.88em; line-height: 1.75;">
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Dissertation|La dissertation de philosophie]]</span><br/>
<span style=" font-weight: bold;">[[Manuel de terminale de philosophie/Archives|Archives de sujets]]</span><br/>
<span style=" font-weight: bold;">[[Philosophie/Une brève introduction/Pour travailler|Pour travailler]]</span>
</div>
</td>
</tr>
</table>
<!-- Dictionnaire — pleine largeur -->
<div style=" border: 1px solid #d4dae2; border-left: 4px solid #4a4a4a; border-radius: 0 8px 8px 0; padding: 14px 16px 16px; margin-bottom: 14px; box-shadow: 0 1px 4px rgba(26,34,48,0.05);">
<div style="font-size: 0.96em; font-weight: bold; padding-bottom: 8px; border-bottom: 1px solid #dfe4eb; margin-bottom: 10px;">[[Dictionnaire de philosophie|Dictionnaire de philosophie]] <span style=" font-weight: bold;">(129)</span></div>
<!-- Sélection d'articles thématiques du Dictionnaire -->
<table style="width: 100%; border-collapse: separate; border-spacing: 5px 5px;">
<tr>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/A|A]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/B|B]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/C|C]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/D|D]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/E|E]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/F|F]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/G|G]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/H|H]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/I|I]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/J|J]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/K|K]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/L|L]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/M|M]]</td>
</tr>
<tr>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/N|N]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/O|O]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/P|P]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/Q|Q]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/R|R]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/S|S]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/T|T]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/U|U]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;">[[Dictionnaire de philosophie/V|V]]</td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;"><span style="color: #b9bfc7;" title="Aucune entrée pour le moment">W</span></td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;"><span style="color: #b9bfc7;" title="Aucune entrée pour le moment">X</span></td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;"><span style="color: #b9bfc7;" title="Aucune entrée pour le moment">Y</span></td>
<td style="width: 7.69%; text-align: center; border: 1px solid #dbe2eb; border-radius: 4px; padding: 9px 0; font-size: 1.08em; font-weight: bold;"><span style="color: #b9bfc7;" title="Aucune entrée pour le moment">Z</span></td>
</tr>
</table>
</div>
<br>
<!-- ══════════════════════════════════════════════
PIED DE PAGE
══════════════════════════════════════════════ -->
<div style="margin-top: 10px; padding: 14px 0 4px; border-top: 1px solid #d4dae2; font-size: 0.86em; ">
<div style="margin-bottom: 6px;"><span style="font-weight: bold; ">Consulter ailleurs</span> · [[w:Philosophie|Wikipédia]] · [[wikt:philosophie|Wiktionnaire]] · [[v:Philosophie|Wikiversité]] · [[s:Portail:Philosophie|Wikisource]]</div>
<div style="margin-bottom: 10px;"><span style="font-weight: bold; ">Catégories sources</span> · [[:Catégorie:Discipline philosophique|Disciplines]] · [[:Catégorie:Histoire de la philosophie|Histoire]] · [[:Catégorie:Philosophe|Philosophes]] · [[:Catégorie:Dictionnaire de philosophie (livre)|Dictionnaire]] · [[:Catégorie:Manuel de terminale de philosophie (livre)|Manuel]] · [[:Catégorie:Commentaire philosophique|Commentaires]]</div>
</div>
[[Catégorie:Philosophie|*]]
kehxsnwhhtestp5c1ejjb9x8u12y32w
Pour lire Platon
0
29731
769315
766872
2026-07-03T03:36:33Z
PandaMystique
119061
769315
wikitext
text/x-wiki
{{Page de garde|image=Pour lire Platon, Wikilivres, 2026.png|imagedesc=|description=
Platon est un philosophe grec qui a vécu aux Ve et IVe siècles av. J.-C., il y a environ vingt-quatre siècles. Il appartenait à une famille aristocratique d’Athènes, qui était alors l’une des plus puissantes cités et l’un des grands centres culturels de la Grèce antique.
Platon est l’un des tout premiers, et l’un des plus importants, philosophes de la tradition occidentale. Il a joué un rôle décisif dans la définition classique de ce que l’on appelle la philosophie.
|avancement=Bon début
|cdu=
* {{CDU item|1/10}}
|versions=
{{Moteur}}
{{version imprimable}}
}}
== Introduction ==
Ce livre propose de fournir au lecteur les connaissances nécessaires à la compréhension des œuvres de Platon. Il s'adresse aux débutants (par exemple, des élèves de terminale, mais également tous ceux qui souhaitent acquérir une culture générale ou découvrir ce philosophe sans avoir de culture philosophique particulière) et aux lecteurs intermédiaires ou avancés, c'est-à-dire à des lecteurs qui ont lu quelques dialogues parmi les moins difficiles et qui sont éventuellement familiers de quelques-unes des notions principales de Platon.
Après une partie introductive, qui s'efforce de donner quelques outils simples et abordables, le ''Guide des Dialogues'' se compose de commentaires plus substantiels, sans être trop techniques, dans le but de progresser dans la lecture.
Ce livre ne s'adresse pas aux spécialistes de Platon qui ne trouveront ici rien qu'ils ne connaissent déjà par la fréquentation assidue des dialogues et des commentateurs.
== Table des matières ==
=== '''[[/Premiers pas/]]''' ===
* [[Pour lire Platon/Premiers pas#Qui est Platon ?|1 Qui est Platon ?]]
* [[Pour lire Platon/Premiers pas#Pourquoi Platon a-t-il écrit ?|2 Pourquoi Platon a-t-il écrit ?]]
* [[Pour lire Platon/Premiers pas#Qu’a-t-il écrit ?|3 Qu’a-t-il écrit ?]]
* [[Pour lire Platon/Premiers pas#Dans quel ordre Platon a-t-il écrit ses dialogues ?|4 Dans quel ordre Platon a-t-il écrit ses dialogues ?]]
* [[Pour lire Platon/Premiers pas#Pourquoi Platon a-t-il écrit des dialogues et non des traités ?|5 Pourquoi Platon a-t-il écrit des dialogues et non des traités ?]]
* [[Pour lire Platon/Premiers pas#Qui sont les personnages des dialogues de Platon ?|6 Qui sont les personnages des dialogues de Platon ?]]
* [[Pour lire Platon/Premiers pas#Pourquoi Socrate est-il le personnage principal des dialogues de Platon ?|7 Pourquoi Socrate est-il le personnage principal des dialogues de Platon ?]]
* [[Pour lire Platon/Premiers pas#De quoi Platon parle-t-il dans ses dialogues ?|8 De quoi Platon parle-t-il dans ses dialogues ?]]
* [[Pour lire Platon/Premiers pas#Les dialogues de Platon forment-ils un système philosophique ?|9 Les dialogues de Platon forment-ils un système philosophique ?]]
* [[Pour lire Platon/Premiers pas#Pourquoi lire un auteur mort il y a vingt-quatre siècles ?|10 Pourquoi lire un auteur mort il y a vingt-quatre siècles ?]]
=== '''[[/Conseils pour la lecture|Conseils pour la lecture]]''' ===
<small>''Quelques conseils élémentaires avant de se lancer''</small>
* [[Pour lire Platon/Conseils pour la lecture#Quelles traductions choisir ?|1 Quelles traductions choisir ?]]
* [[Pour lire Platon/Conseils pour la lecture#Faut-il apprendre le grec pour bien comprendre Platon ?|2 Faut-il apprendre le grec pour bien comprendre Platon ?]]
* [[Pour lire Platon/Conseils pour la lecture#Par quels dialogues commencer ?|3 Par quels dialogues commencer ?]]
* [[Pour lire Platon/Conseils pour la lecture#Comment tirer profit de la lecture des dialogues ?|4 Comment tirer profit de la lecture des dialogues ?]]
* [[Pour lire Platon/Conseils pour la lecture#Quels outils utiliser au cours de la lecture ?|5 Quels outils utiliser au cours de la lecture ?]]
* [[Pour lire Platon/Conseils pour la lecture#Quels livres lire sur Platon ?|6 Quels livres lire sur Platon ?]]
=== [[Pour lire Platon/Introduction par les dialogues|Introduction par les dialogues]] ===
* Le philosophe
** Qu'est-ce que l'amour de la sagesse ?
** Qu'est-ce que savoir ?
** Quelle est la place du philosophe dans la cité
* La vie éthique
** Qu'est-ce que l'âme ?
** Qu'est-ce que se connaître soi-même ?
** Qu'est-ce que la vertu ?
** Quel est le bien suprême de la vie ?
** Doit-on craindre la mort ?
* La politique
** Qu'est-ce que la politique ?
** Qu'est-ce qu'une cité juste ?
** Pourquoi agir selon la justice, si l'on peut tirer profit de l'injustice ?
** Pourquoi obéir aux lois ?
* L'art
** Faut-il contrôler l'art ?
* Erreurs fréquentes
** Platon diviserait le monde en deux
** Platon aurait inventé l'amour platonique
** L'âme serait composée de parties
** Chaque groupe de la cité juste posséderait une vertu
** La voix intérieure de Socrate serait celle d'un démon
=== [[Pour lire Platon/Introduction par les mythes|Introduction par les mythes]] ===
=== [[Pour lire Platon/Vocabulaire|Vocabulaire]] ===
== Le Guide des Dialogues ==
* [[Pour lire Platon/Guide des dialogues/Introduction|Introduction]]
* [[Pour lire Platon/Guide des dialogues|Guide des dialogues]]
== Bibliographie ==
* [[Pour lire Platon/Bibliographie|Bibliographie commentée]]
[[Catégorie:Histoire de la philosophie]][[Catégorie:Philosophe]]
{{AutoCat}}
__NOTOC__
[[Catégorie:Classe 1 - Philosophie et psychologie]]
[[Catégorie:Philosophie]]
gpn440eooqe5123p1orycq0oolagu14
Grec ancien/Dieux
0
29805
769319
769271
2026-07-03T07:37:37Z
~2026-34862-02
124042
Rectification d'erreurs.
769319
wikitext
text/x-wiki
{{Grec ancien}}
Il existe un très grand nombre de dieux grecs. ([[w:Généalogie de la mythologie grecque|les listes]] en font état de plus de 200) Ceux-ci sont tous classés selon leur famille :
*Les Ancêtres (Chaos, Gaïa, Ouranos)
*Descendants d'Ouranos et de Gaïa (Aphrodite, Molios, Théomisès)
*Géants (Cerbère, Chimère, Sphinx, Orthos)
*Descendance des Titans et des Titanides (Thémis, Pirène, Batia)
*Descendants des monstres (Cyclope)
*Descendants de Pontos (Amphitrite, Achille, Néréïdes)
*Descendants d'Éros
*Descendants d'Erèbe
*Descendants de Nyx
*Descendants de Tartare
*Descendants de Python
*Descendants d'Amythaon
*Descendants d'Idmon
*Descendants de Strophios
*Descendants de Plégias
*Nymphes
''Il existe de nombreuses sous-familles. En raison de leur nombre, nous n'en ferons pas état ici.''
== Les divinités Olympiennes ==
[[Fichier:Mytikas summit PJS.jpg|left|thumb|Le mont Olympe.]]
[[Fichier:Sarcophagus Prometheus Louvre Ma339.jpg|thumb|center|370px|Le cortège des dieux de l'Olympe. Sarcophage romain, vers 240 ap. J.-C., Musée du Louvre, Paris, France.]]
Les divinités Olympiennes, au nombre de 12, sont les dieux grecs qui vivent sur le mont Olympe. Ce nombre varie selon les siècles ; on y retrouve toujours Zeus, Héra, Poséidon, Arès, Hermès, Héphaïstos, Athéna, Apollon et Artémis qui sont complétés par Hestia, Déméter, Aphrodite, Dionysos et Hadès en fonction des époques.
== Liste détaillée ==
** [[/Aidos/]]
** [[/Aléthée/|Althée]]
** [[/Ananké/]]
** [[/Antéros/]]
** [[/Apaté/]]
** [[/Apollon/]]
** [[/Aphrodite/]]
** [[/Arès/]]
** [[/Arété/]]
** [[/Artémis/]]
** [[/Asclépios/]]
** [[/Até/]]
** [[/Athéna/]]
** [[/Chronos/]]
** [[/Cronos/]]
** [[/Coros/]]
** [[/Cybèle/]]
** [[/Déimos/]]
** [[/Déméter/]]
** [[/Dicé/]]
** [[/Dionysos/]]
** [[/Dolos/]]
** [[/Dysnomie/]]
** [[/Dyssebeia/]]
** [[/Dyssébie/]]
** [[/Eiréné/]]
** [[/Elpis/]]
** [[/Eunomie/]]
** [[/Eusébie/]]
** [[/Éléos/]]
** [[/Éole/]]
** [[/Éosphoros/]]
** [[/Éos/]]
** [[/Érèbe/]]
** [[/Éris/]]
** [[/Éros/]]
** [[/Ésa/]]
** [[/Gaïa/]]
** [[/Géras/]]
** [[/Harmonie/]]
** [[/Hadès/]]
** [[/Hespéros/]]
** [[/Hébé/]]
** [[/Hédoné/]]
** [[/Hédylogos/]]
** [[/Héphaïstos/]]
** [[/Héra/]]
** [[/Hermès/]]
** [[/Hestia/]]
** [[/Himéros/]]
** [[/Horkos/]]
** [[/Hybris/]]
** [[/Hygie/]]
** [[/Hypnos/]]
** [[/Hébé/]]
** [[/Hécate/]]
** [[/Hélios/]]
** [[/Héméra/]]
** [[/Hypnos/]]
** [[/Ilithyie/]]
** [[/Limos/]]
** [[/Lyssa/]]
** [[/Mania/]]
** [[/Momos/]]
** [[/Moros/]]
** [[/Métis/]]
** [[/Némésis/]]
** [[/Niké/]]
** [[/Nyx/]]
** [[/Oizys/]]
** [[/Ouranos/]]
** [[/Panacée/]]
** [[/Pan/]]
** [[/Péitho/]]
** [[/Pénia/]]
** [[/Perséphone/]]
** [[/Philotès/]]
** [[/Phobos/]]
** [[/Pistis/]]
** [[/Poséidon/]]
** [[/Pothos/]]
** [[/Rhéa/]]
** [[/Séléné/]]
** [[/Sophrosyne/]]
** [[/Thanatos/]]
** [[/Thémis/]]
** [[/Tyché/]]
** [[/Zélos/]]
** [[/Zeus/]]
** [[/Épiphron/]]
* [[../Texte : Odyssée|Texte : L'Odyssée, Livre 7]]
* [[../Exercices chapitre 4|Exercices]]
== Généalogie ==
{{Grec ancien/Arbre généalogique dieux}}
== Questions ==
{{Avertissement exercice}}
#Quelles divinités pouvez-vous reconnaître sur la fresque représentant le cortège des Dieux (§ « ''Les divinités Olymipiennes'' ») ?
{{boîte déroulante|titre=afficher les réponses|contenu=
On peut voir sur cette fresque (de gauche à droite) :
*Athéna,
*Hermès et son pétase ailé,
*Poséidon,
*Artémis.
}}
18vu23ey33ywhz3pusvngsjumdshwxr
Catégorie:Pour lire Platon (livre)
14
30835
769314
769267
2026-07-03T03:36:16Z
PandaMystique
119061
769314
wikitext
text/x-wiki
[[Catégorie:Livres par titre]]
[[Catégorie:Histoire de la philosophie]]
[[Catégorie:Classe 1 - Philosophie et psychologie]]
[[Catégorie:Philosophe]]
3926ov86r8r7mxhvw9ojgkxgghiotz3
Photographie/Personnalités/K/Hans Krum
0
59843
769310
455184
2026-07-02T20:00:32Z
Incall
119797
([[c:GR|GR]]) [[c:COM:FR|File renamed]]: [[File:Trondheim ca. 1860 - no-nb digifoto 20140717 00022 bldsa fFA00310.jpg]] → [[File:Trondhjem ca. 1860 - no-nb digifoto 20140717 00022 bldsa fFA00310.jpg]] [[c:COM:FR#FR3|Criterion 3]] (obvious error) · The city was named "Trondhjem", before it changed its name to "Trondheim" in 1931. This photograph is dated circa 1860, so the correct name would be "Trondhjem".
769310
wikitext
text/x-wiki
{{Ph s Personnalités}}
'''Hans Krum''' était un photographe norvégien né le 15 février 1818 à Bergen et décédé le 3 octobre 1882 à Trondheim. Il à travaillé à partir de 1852 è Bergen et Trondheim.
== Galerie de photographies ==
<gallery widths="240px" heights="240px">
Christiansten - no-nb digifoto 20140717 00029 bldsa fFA00361.jpg
Dronningens Gade i Throndhjem - no-nb digifoto 20130315 00055 bldsa FA0982.jpg
Elgeseter bridge between 1864 and 1884.jpg
Hans Krum panoramabild.jpg
Jernbanebroen i Trondhjem - no-nb digifoto 20130315 00050 bldsa FA0977.jpg
JohnWold1795.jpg
Kongens Gade i Throndhjem, 1878 - no-nb digifoto 20130315 00056 bldsa FA0983.jpg
Landgangsbroen og Munkholmen - no-nb digifoto 20130315 00054 bldsa FA0981.jpg
Lundamoe - no-nb digifoto 20140717 00017 bldsa fFA00165.jpg
Munkegaden i Trondhjem - no-nb digifoto 20130315 00044 bldsa FA0971.jpg
Nedre Lerfoss, Trondheim, ca. 1860 - no-nb digifoto 20140717 00027 bldsa fFA00359.jpg
Parti af Christiansund - no-nb digifoto 20140717 00016 bldsa fFA00164.jpg
Parti af Christiansund - no-nb digifoto 20140717 00024 bldsa fFA00312.jpg
Parti af Lundamoe ved Throndhjem - no-nb digifoto 20140717 00023 bldsa fFA00311.jpg
Parti af Lundamoe ved Throndhjem - no-nb digifoto 20140717 00026 bldsa fFA00358.jpg
Parti af Romsdalen - no-nb digifoto 20140717 00019 bldsa fFA00167 (cropped).jpg
Parti af Romsdalen - no-nb digifoto 20140717 00019 bldsa fFA00167.jpg
Parti af Throndhjem - no-nb digifoto 20130315 00048 bldsa FA0975.jpg
Parti af Throndhjem fra Steenbjerget - no-nb digifoto 20140717 00028 bldsa fFA00360.jpg
Parti af Throndhjem ved Brattoren - no-nb digifoto 20130315 00051 bldsa FA0978.jpg
Parti af Tronhjems Domkirke - no-nb digifoto 20140717 00025 bldsa fFA00313.jpg
Parti af Øen ved Trondhjem - no-nb digifoto 20140717 00014 bldsa fFA00162.jpg
Portrett av Peter Christen Asbjørnsen (1812-1885).jpg
Portrett av uidentifisert kvinne - no-nb digifoto 20130315 00040 bldsa FA0967.jpg
Portrett av uidentifisert kvinne - no-nb digifoto 20130315 00041 bldsa FA0968.jpg
Portrett av uidentifisert kvinne - no-nb digifoto 20130315 00042 bldsa FA0969.jpg
Rotvold ved Throndhjem - no-nb digifoto 20140717 00015 bldsa fFA00163 (cropped).jpg
Rotvold ved Throndhjem - no-nb digifoto 20140717 00015 bldsa fFA00163.jpg
Søndre Gade - no-nb digifoto 20130315 00053 bldsa FA0980.jpg
Throndhjem - no-nb digifoto 20130315 00049 bldsa FA0976 (contrast).jpg
Throndhjem - no-nb digifoto 20130315 00049 bldsa FA0976.jpg
Trondheim - no-nb digifoto 20130315 00045 bldsa FA0972.jpg
Trondheim ca. 1860 - no-nb digifoto 20140717 00021 bldsa fFA00309.jpg
Trondhjem ca. 1860 - no-nb digifoto 20140717 00022 bldsa fFA00310.jpg
Trondheim ca. 1865 - no-nb digifoto 20140717 00018 bldsa fFA00166.jpg
Øvre Leirfoss, Trondheim - no-nb digifoto 20140717 00020 bldsa fFA00306.jpg
Øvre Lerfos - no-nb digifoto 20130315 00046 bldsa FA0973.jpg
</gallery>
{{T|[[commons:Photographs by Hans Krum|voir les photos de Hans Krum sur Wikimedia Commons]]}}
{{Ph Personnalités}}
au4qqzloue20he4yn1umad6y8ehrdeb
Python pour le calcul scientifique/Éléments de programmation
0
72883
769320
768733
2026-07-03T09:42:12Z
Cdang
1202
/* Importer le contenu d'un fichier */ np.genfromtxt()
769320
wikitext
text/x-wiki
Rappel : les programmes commencent par :
<syntaxhighlight lang="python">
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as plt
</syntaxhighlight>
== Entrées et sorties ==
Pour permettre à l'utilisateur ou à l'utilisatrice d'entrer une valeur, nous utilisons la fonction <code lang="python">input()</code> comme évoqué précédemment (chapitre ''[[../Premiers programmes|Premiers programmes]]''), avec la syntaxe <code lang="python">''variable'' = input(''texte'')</code>. Notez que la valeur renvoyée par <code lang="python">input()</code> est une chaîne de caractères. Si vous voulez autre chose, typiquement un nombre, il faut convertir cette chaîne.
Par exemple, nous demandons ici d'entrer une longueur sous la forme d'une valeur numérique :
<syntaxhighlight lang="python">
longueurDefaut = 10.0
texteDemandeLongueur = f"Veuillez entrer la longueur en millimètres (valeur par défaut {longueurDefaut} mm) : "
longueur = input(texteDemandeLongueur)
if longueur=="":
longueur=longueurDefaut
else:
longueur=float(longueur)
print(longueur)
</syntaxhighlight>
{{voir|https://docs.python.org/3/library/functions.html#input}}
Pour afficher un texte, on utilise la fonction <code lang="python">print()</code>, également présentée dans le chapitre ''[[../Premiers programmes|Premiers programmes]]'', avec la syntaxe <code lang="python">print(''texte'')</code>. Le texte à afficher peut être de n'importe quel type (entier, réel en virgule flottante, booléen, chaîne de caractères…). On peut « mélanger » les types en les séparant par des virgules, par exemple
<syntaxhighlight lang="python">
print("La longueur vaut : ", longueur, " mm.")
</syntaxhighlight>
ou bien
<syntaxhighlight lang="python">
print("Essai de mélange ", 1, True, 10.0, " insensé.")
</syntaxhighlight>
Mais si l'on veut faire ça de manière harmonieuse, on a intérêt à tout convertir en chaînes de caractères, avec la fonction <code lang="python">str()</code>, et concaténer les chaînes avec <code lang="python">+</code>.
Par exemple :
<syntaxhighlight lang="python">
print("La longueur vaut : "+str(longueur)+" mm.")
</syntaxhighlight>
Nous pouvons aussi utiliser une « chaîne “f” » ''({{lang|en|f-string}})'' : on met un le <code lang="python">f</code> devant le guillemet ouvrant et dans la chaîne, on met un champ sous la forme <code lang="python">{''nomDeVariable''}</code>. L'exemple ci-dessus devient alors :
<syntaxhighlight lang="python">
print(f"La longueur vaut : {longueur} mm.")
</syntaxhighlight>
Les chaînes « f » sont détaillées dans la section ''[[#Chaînes de caractères|Chaînes de caractères]]'' ci-dessous.
Si l'on veut introduire un retour à la ligne dans la chaîne, on utilise les caractères <code lang="python">\n</code> (contre-oblique suivie de la lettre N minuscule). Par exemple
<syntaxhighlight lang="python">
print("Ceci est un texte\navec un retour à la ligne.")
</syntaxhighlight>
La commande <code>print()</code> admet les paramètres suivants (nous indiquons la valeur par défaut= :
* <code>end = "\n"</code> : détermine la fin de ligne ; on peut mettre <code>end = ""</code> si l'on ne veut pas de retour de ligne, ou bien <code>end = "\r"</code> ''({{lang|en|return}})'' si l'on veut revenir au début de la ligne pou repasser par-dessus ;
* <code>sep = " "</code> : séparateur des différents objets.
{{voir|https://docs.python.org/3/library/functions.html#print}}
Si vous voulez passer un argument directement au script Python, vous pouvez utiliser le module <code>sys</code>. L'argument est alors contenu dans la variable <code>sys.argv[1]</code> ; la variable <code>sys.argv[0]</code> contient le nom du scirpt lui-même. Par exemple
<syntaxhighlight lang="python">
import sys
print("Script : ", sys.argv[0])
print("Entrée : ", sys.argv[1])
</syntaxhighlight>
Si vous exécutez le script depuis une console (fenêtre de commande), le nom du fichier de script étant <code>monscript.py</code> :
<syntaxhighlight lang="text">
$ python monscript.py blabla
Script : monscript.py
Entrée : blabla
$_
</syntaxhighlight>
== Types de variables ==
=== Généralités ===
Python définit « tout seul » le type de la variable : « <code>3</code> » sera un entier ''({{lang|en|integer}})'', « <code>3.0</code> » sera un réel à virgule flottante ''({{lang|en|float}})'', « <code>"3"</code> » sera une chaîne de caractères ''({{lang|en|string}})''.
On peut connaître le type d'une variable avec la fonction <code>type()</code>.
On peut tester certaines valeurs, avec le module <code>NumPy</code> :
* <code>np.isnan(x)</code> indique si les valeurs de ''x'' sont des NaN ''({{lang|en|not a number}})'' ; si ''x'' est une matrice, le résultat est une matrice de booléens, l'élément [''i'', ''j''] est <code>True</code> si <code>x[i, j]</code> est un NaN ;
* <code>np.isinf(x)</code> indique si les valeurs de ''x'' sont ±∞ ; si ''x'' est une matrice, le résultat est une matrice booléenne de même dimension.
On peut forcer un type :
* <code>int(x)</code> : transforme la valeur ''x'' en nombre entier ;
* <code>long(x)</code> : " en entier long (précision illimitée) ;
* <code>float(x)</code> : " en nombre réel à virgule flottante ;
* <code>str(x)</code> : " en chaîne de caractères ;
* <code>complex(Re, Im)</code> : crée le nombre complexe ''Re'' + ''Im''·j, j désignant la racine carrée de –1 ;
* <code>list()</code> : crée une liste ;
* <code>tuple()</code> : crée un n-uplet.
Par exemple
<syntaxhighlight lang="python">
type(3) # <class 'int'>
type(float(3)) # <class 'float'>
complex(1, 1) == 1 + 1j # True
list("blabla") # ['b', 'l', 'a', 'b', 'l', 'a']
</syntaxhighlight>
Python distingue plusieurs genres de types :
* Un itérable est un objet dont on peut extraire les éléments un par un ; ce sont les objets pour lesquels on peut écrire <code> for i in ''iterable'':</code>. Il s'agit essentiellement des listes, n-uplets, chaînes de caractères, ensembles, dictionnaires et fichiers.
* Un modifiable ''({{lang|en|mutable}})'' est un objet que l'on peut modifier ; par exemple une liste est modifiable — on peut changer la valeur d'un élément, en ajouter ou en enlever un — mais les n-uplets non, pas plus qu'une chaîne de caractères ou un nombre.
* Un identifiable (''{{lang|en|hashable}}'', le ''{{lang|en|hashage}}'' étant une signature caractéristique d'un objet) : objet possédant un identifiant unique. Un objet identifiable est toujours non-modifiable ''({{lang|en|unmutable}})''.
=== Types numériques ===
==== Entiers ====
Nous pouvons définir les entiers au format octal ou hexadécimal : il faut débuter le nombre par respectivement <code>0o</code> (le chiffre zéro et la lettre o) et <code>0x</code> (le chiffre zéro et la lettre x). À l'inverse, la fonction <code>hex()</code> renvoie une chaîne correspondant à l'écriture d'un entier au format hexadécimal, et <code>oct()</code> renvoie la chaîne correspondant à l'éciture en octal. Par exemple :
<syntaxhighlight lang="python">
print(0o10, ";", 0x10)
# 8 ; 16
print(hex(20))
# 0x14
</syntaxhighlight>
==== Réels ====
Les réels disposent de fonctions spécifiques appelées « méthodes ».
Une méthode est une fonction spécifique à un type d'objets. Étant conçue ''ad hoc'', elle est souvent plus économe en ressource et en temps qu'une fonction générique. Pour appliquer la méthode <code>meth()</code> à la variable <code>x</code>, on écrit : <code>x.meth()</code>.
Nous avons déjà présenté la méthode <code>''float''.as_integer_ratio()</code> qui donne la fraction réduite égale à la valeur du nombre. Les réels disposent de plusieurs autres méthodes :
* <code>''float''.is_integer()</code> : indique si le nombre est un entier (<code>true</code> dans ce cas-là, <code>False</code> sinon) ;
* <code>''float''.from_number(''x'')</code> : transforme le nombre ''x'' en un réel (permet de convertir un entier en réel) ;
* <code>''float''.hex()</code> : renvoie une chaîne de caractères correspondant à l'écriture du nombre en hexadécimal ;
* <code>''float''.fromhex(''c'')</code> : transforme une chaîne de caractères, correspondant à l'écriture d'un nombre en hexadécimal, en un nombre réel correspondant.
Par exemple :
<syntaxhighlight lang="python">
a = 20.
print(a.hex())
# 0x1.4000000000000p+4
print(10..hex())
# 0x1.4000000000000p+3
</syntaxhighlight>
Dans le deuxième exemple, nous appliquons la méthode <code>''float''.hex()</code> directement au nombre <code>10.</code> ; le point est obligatoire car sinon, c'est un entier, pour lequel la méthode n'est pas définie. On aurait pu aussi écrire <code>print(10.0.hex())</code>.
Notez que la ''méthode'' <code>''float''.hex()</code> est différentes de la ''fonction'' <code>hex()</code> : la première concerne les réels, la seconde les entiers.
==== Complexes ====
Nous avons déjà mentionné la méthode <code>''complex''.conjugate()</code> qui donne le conjugué du nombre.
Un nombre complexe dispose de deux attributs :
* <code>''complex''.real</code> : sa partie réelle ;
* <code> ''complex''.imag</code> : sa partie imaginaire.
Par exemple :
<syntaxhighlight lang = "python">
a = 5+2j
print(a.conjugate(), ";", a.real, ";", a.imag)
# (5-2j) ; 5.0 ; 2.0
</syntaxhighlight>
=== Chaînes de caractères ===
; Ressources
: {{lien web
| url = https://docs.python.org/3/tutorial/inputoutput.html
| titre = 7. Input and Output
| site = Python Documentation
| consulté le = 2019-04-06
}}
: {{lien web
| url = https://docs.python.org/3/library/string.html
| titre = <code>string</code> — Common string operations
| site = Python Documentation
| consulté le = 2026-06-05
}}
==== Généralités ====
Il existe en fait trois manières de définir une chaîne de caractères :
* avec des guillemets simples ou doubles comme vu précédemment : <code>"…"</code> ou bien <code>'…'</code> ;
* avec trois guillemets doubles : <code>"""…"""</code> : cela permet d'avoir une chaîne de caractères s'étendant sur plusieurs lignes, les retours de ligne étant pris en compte ; c'est utilisé en particulier pour la description des fonctions (''{{lang|en|docstrings}}'', voir ci-après) ;
* avec des guillemets précédés d'un « r », <code>r"…"</code> ou <code>r'…'</code> : cela permet d'interpréter les barres de fraction inverses « \ » comme un caractère « normal » et non comme un caractère d'échappement (voir ci-après) ; cela est utile lorsque l'on utilise les possibilités LaTeX dans le tracé de graphiques (voir plus loin) ;
* avec des guillemets précédés d'un « f », <code>f"…"</code> ou <code>f'…'</code> : cela permet d'utiliser des variables formatées (voir ci-après).
Une chaîne de caractères n'est pas modifiable. Si l'on veut remplacer un caractère, l'insérer ou le supprimer, il faut transformer la chaîne en liste, avec la commande <code>list()</code>, puis rassembler la liste en la joignant ''({{lang|en|join}})'' à une chaîne vide :
<syntaxhighlight lang="python">
chaine = "blabla"
chaineList = list(chaine)
chaineList[2] = "c"
chaine = "".join(chaineList)
print(chaine) # blcbla
</syntaxhighlight>
Dans une chaîne simple <code>"…"</code> ou <code>'…'</code>, on peut introduire un retour à la ligne avec <code>\n</code>.
Chaque caractère possède un code ''({{lang|en|code point}})'' définit par la norme Unicode ''({{lang|en|Unicode code point}})''. Pour afficher le caractère correspondant à un code, on utilise <code>chr()</code>. Pour afficher le code correspondant à un caractère, on utilise <code>ord()</code>
<syntaxhighlight lang="python">
print(ord("a")) # 97
print(hex(ord("a"))) # 0x61
print(chr(97)) # a
print(chr(0x61)) # a
</syntaxhighlight>
==== Substitution de variables ====
Lorsque l'on veut utiliser des variables, on fait précéder les guillemets d'un « f » et l'on écrit les noms de variables entre accolades ; on parle de « chaîne f » ''(f-string)''. Par exemple :
<syntaxhighlight lang="python">
monde = "world"
chaine = f"Hello {monde}!"
print(chaine) # Hello world!
</syntaxhighlight>
On peut indiquer la taille de la chaîne générée à partir de la variable sous la forme <code>{nomVariable:taille}</code>, la taille étant un entier. Par exemple :
<syntaxhighlight lang="python">
chiffre1 = 1
nom1 = "un"
chiffre2 = 2
nom2 = "deux"
chaine = f"{nom1:5} : {chiffre1:5d}\n{nom2:5} : {chiffre2:5d}"
print(chaine)
# un : 1
# deux : 2
</syntaxhighlight>
Vous remarquez que l'on ajoute un « d » pour les entiers décimaux, et que les nombres sont alignés à droite. Si le nombre est un nombre réel à virgule flottante ''({{lang|en|float}})'', on peut indiquer le nombre de décimales sous la forme <code>.''n''f</code> :
<syntaxhighlight lang="python">
chaine = f"{np.pi:.5f}"
print(chaine)
# 3.15169
</syntaxhighlight>
Avec la syntaxe <code>''m''.''n''f</code>, on indique également que la totalité du nombre doit occuper ''m'' caractères.
Pour un nombre en notation scientifique (exponentielle), on utilise <code>.''n''e</code>.
Pour convertir un nombre en caractère Unicode correspondant, on utilise la lettre c :
<syntaxhighlight lang="python">
nompi = 0x03c0 # Caractère Unicode π : U+03C0
chaine = f"{nompi:c} = {np.pi:.5f}"
print(chaine)
# π = 3.14159
</syntaxhighlight>
Notez que dans le cas de nombres, la mise en forme marche aussi si l'on écrit directement le nombre dans l'accolade (au lieu d'une variable).
Le tiret de soulignement « <code>_</code> » (''underscore'', tiret du 8) permet de séparer les chiffres avant le séparateur décimal par groupe de trois chiffres séparés du tiret ; la virgule « <code>,</code> » les sépare d'une virgule.
<syntaxhighlight lang="python">
print(f"{1e6:_}, {1e6:,}")
# 1_000_000.0, 1,000,000.0
</syntaxhighlight>
La classe ''str'' dispose également de la méthode <code>.format()</code>. On indique un n-uplet de chaînes (ou de nombres) à la méthode et l'on met des accolades dans la chaîne principale ; les accolades sont remplacées dans l'ordre des chaînes de la méthode. On peut changer l'ordre en indiquant quelle valeur utiliser dans quelle accolade. Par exemple :
<syntaxhighlight lang="python">
chaine1 = "On compte {} puis {}".format(1, 2)
chaine2 = "On compte {0} puis {1}. Mais à rebours, on compte {1} puis {0}.".format("un", "deux")
print(chaine1, "\n", chaine2)
# On compte 1 puis 2
# On compte un puis deux. Mais à rebours, on compte deux puis un.
</syntaxhighlight>
L'utilisation du caractère pourcent « % » permet d'utiliser la mise en forme <code>sprintf()</code> du langage C :
<syntaxhighlight lang="python">
chaine = "π = %.5f" % np.pi
print(chaine)
# π = 3.14159
</syntaxhighlight>
; Exemple <nowiki>:</nowikI> barre de progression
: Voici une fonction affichant une barre de progression, pour la ''i''-ème étape d'un processus ayant ''n'' étapes (pour la notion de fonction, voir la section ci-après ''[[#Fonction|Fonction]]'').
: NB : nous avons utilisé les codes Unicode pour l'exemple, mais on peut évidemment copier le caractère, par exemple depuis une table Unicode ou une page Web<ref>Pour le point médian : ''{{W|Table des caractères Unicode/U0080}}'' ou ''{{W|Point médian}}''. Pour le pavé : ''{{W|Table des caractères Unicode/U2580}}''.</ref>, et le coller dans le code, comme nous l'avons fait dans le commentaire.
<syntaxhighlight lang="Python">
def barre_progression(i, n, largeur=40):
""" Affiche une barre de progression
Entrées :
— i : étape en cours, entier ;
— n : nombre d'étapes à réaliser, entier ;
— largeur : nombre de caractères total de la barre, entier.
Sortie : affichage de la barre de progression.
"""
taux = i/n
fait = int(largeur * taux)
barre = f"{0x2588:c}" * fait + f"{0x00b7:c}" * (largeur - fait) # U+2588 : pavé "█" ; U+00B7 : point médian "·"
print(f"Progression | {barre} | {100*taux:3.1f} %", end="\r")
barre_progression(25, 100)
# Progression | ██████████······························ | 25.0 %
</syntaxhighlight>
==== Méthodes des chaînes ====
Le type ''str'' dispose d'un certain nombre de méthodes. Nous avons déjà vu les méthodes <code>''str''.join()</code> et <code>''str''.format()</code>, en voici quelques autres :
* <code>''str''.capitalize()</code> : met le premier caractère en capitale (majuscule) et les autres en minuscule ;
* <code>''str''.lower()</code> : met tout en minuscules ''({{lang|en|lowercase}})'' ;
* <code>''str''.upper()</code> : met tout en capitales ''({{lang|en|lowercase}})'' ;
* <code>''str''.center(''n'')</code> : met la chaîne au centre d'une chaîne de longueur ''n'', en complétant avec des espaces ; on peut compléter avec d'autres caractères avec <code>''str''.center(''n'', ''c'')</code>, par exemple <code>"a".center(7, ".")</code> donne <code>"....a...."</code> ;
* <code>''str''.ljust(''n'', ''c'')</code> et <code>''str''.rjust(''n'', ''c'')</code> : comme <code>.center()</code> mais la chaîne est respectivement alignée au fer à gauche ''({{lang|en|left}})'' et à droite ''({{lang|en|right}})'' ;
* <code>''str''.isdigit()</code> : booléen vrai si tous les caractères sont des nombres ;
* <code>''str''.find(''sous-chaine'')</code>, <code>''str''.rfind(''sous-chaine'')</code> : indique respectivement le premier emplacement et le dernier emplacement de la sous-chaîne dans la chaîne, ou bien <code>-1</code> si la sous-chaîne est absente ;
* <code>''str''.partition(''séparateur'')</code> : retourne un triplet avec la portion de chaîne avant le séparateur, le séparateur puis la portion de chaîne après le séparateur ;
* <code>''str''.replace(''ancien'', ''nouveau'')</code> : remplace la chaîne ''ancien'' par la chaîne ''nouveau'' dans la chaîne ;
* <code>''str''.split(''séparateur'')</code> : découpe la chaîne au niveau des séparateurs et renvoie une liste.
==== Autres fonctions ====
La fonction <code>chr()</code> transforme un code Unicode en caractère. Par exemple, <code>chr(97)</code> donne <code>"a"</code> et <code>chr(0x03c0)</code> donne <code>"π"</code>.
Si on veut créer une liste de caractères qui se suivent, on peut par exemple utiliser :
<syntaxhighlight lang="python">
[chr(x) for x in range(97, 102)]
# ['a', 'b', 'c', 'd', 'e']
</syntaxhighlight>
Si on veut créer une liste de nombres sous la forme de chaînes de caractères, on peut utiliser la commande <code>str()</code> vue ci-dessus. Par exemple :
<syntaxhighlight lang="python">
[str(x) for x in range(1, 6)]
# ['1', '2', '3', '4', '5']
</syntaxhighlight>
Pour la syntaxe, voir ci-dessous la section [[#Définition en compréhension|''Définition en compréhension'']].
Ainsi, dans l'exemple de la barre de progression ci-dessus, on peut utiliser la solution suivante pour constituer la barre :
<syntaxhighlight lang="python">
barre = chr(0x2588) * fait + chr(0x00b7) * (largeur - fait) # U+2588 : bloc ; U+00B7 : point médian
</syntaxhighlight>
Rappel : le module <code>html</code> permet d'utiliser les entités HTML :
<syntaxhighlight lang="python">
import html
…
print(html.entities.html5["alpha;"]+html.entities.html5["middot;"])
# α·
</syntaxhighlight>
L'entité HTML <code>&xxx;</code> s'obtient par <code>html.entities.html5["xxx;"]</code>, donc en enlevant la perluète ; mais cela ne fonctionne pas avec les codes Unicode. Pour cela, on peut utiliser la commande <code>html.unescape()</code>. Ainsi, dans l'exemple de la barre de progression ci-dessus, on peut utiliser la solution suivante pour constituer la barre :
<syntaxhighlight lang="python">
barre = html.unescape("█") * fait + html.entities.html5["middot;"] * (largeur - fait) # U+2588 : bloc ; middot : point médian
</syntaxhighlight>
ou bien
<syntaxhighlight lang="python">
barre = barre = html.unescape("█" * fait + "·" * (largeur - fait)) # U+2588 : bloc ; middot : point médian
</syntaxhighlight>
La commande <code>html.unescape()</code> interprète donc une chaîne complète, par exemple
<syntaxhighlight lang="python">
print(html.unescape("L'esperluette est le caractère « & »."))
# L'esperluette est le caractère « & ».
</syntaxhighlight>
== Manipulation de listes ==
Les listes sont une structure de données fondamentale en Python.
; Ressources
* {{lien web
| url = https://docs.python.org/3/tutorial/datastructures.html
| langue = en
| titre = 5. Data structures
| site = Python documentation
| consulté le = 2019-03-16
}}
=== Copie d'une liste ===
Contrairement à d'autres types, lorsque vos écrivez <code>b = a</code> avec des listes, vous ne créez pas une copie de la variable <code>a</code>, vous créez un ''alias'' : l'objet <code>b</code> est un autre nom de l'objet <code>a</code>. En particulier, si vous modifiez <code>b</code>, vous modifiez en fait <code>a</code>. Par exemple :
<syntaxhighlight lang="python">
a = [1, 2, 3, 4]
b = a
b[2] = 5
print(a, b) # [1, 2, 5, 4] [1, 2, 5, 4]
</syntaxhighlight>
Si l'on veut créer une copie de <code>a</code>, il faut utiliser <code>a[:]</code> ou bien <code>a.copy()</code> :
<syntaxhighlight lang="python">
a = [1, 2, 3, 4]
b = a[:]
c = a.copy()
b[2] = 5
c[2] = 6
print(a, b, c) # [1, 2, 3, 4] [1, 2, 5, 4] [1, 2, 6, 4]
</syntaxhighlight>
=== Méthodes de listes ===
Pour modifier une liste, vous disposez des méthodes suivantes :
* <code>a.append(x)</code> : ajoute l'élément <code>x</code> à la fin de la liste <code>a</code> ;
* <code>a.extend(x)</code> : ajoute la liste <code>x</code> à la fin de la liste <code>a</code> ;
* <code>a.append(i, x)</code> : aoute l'élément <code>x</code> ''avant'' l'interstice ''i'' de la liste <code>a</code> ;
* <code> x = a.pop(i)</code> : enlève l'élément ''i'' de la liste <code>a</code> et le met dans la variable <code>x</code> ; <code> x = a.pop()</code> enlève le dernier élément de la liste ;
* <code>a.clear()</code> : vide la liste <code>a</code> ;
* <code>a.sort()</code> : trie la liste par ordre croissant ;
* <code>a.sort(reverse = True)</code> : trie par ordre décroissant ;
* <code>a.reverse()</code> : inverse l'ordre de <code>a</code>.
Pour supprimer l'élément à l'indice ''i'', au lieu d'utiliser <code>a.pop(i)</code>, on peut aussi utiliser
<syntaxhighlight lang="python">
del(a[i])
</syntaxhighlight>
Pour trier une liste, on peut aussi utiliser la fonction <code>sorted()</code>, ce qui permet par exemple de conserver la liste originale, non triée : <code>b = sorted(a)</code>. La fonction <code>sorted()</code> fonctionne avec tous les objets « itérables » comme par exemple une chaîne de caractères :
<syntaxhighlight lang="python">
a = "ahjbfk"
print(sorted(a)) # ['a', 'b', 'f', 'h', 'j', 'k']
</syntaxhighlight>
Pour mettre en évidence la performance de la méthode <code>''list''.sort()</code> par rapport à la fonction générique <code>sorted()</code> :
<syntaxhighlight lang="python">
import numpy as np
import time
a = np.random.rand(int(1e7))
t1 = time.perf_counter()
b = sorted(a) # Fonction générique
t2 = time.perf_counter()
a.sort() # Méthode spécifique
t3 = time.perf_counter()
print("Sorted :", t2-t1, " s ; .sort :", t3-t2, "s ; rapport :", (t2-t1)/(t3-t2))
# Sorted : 14.2... s ; .sort : 1.1... s ; rapport : 12.6...
</syntaxhighlight>
Par rapport à une valeur donnée :
* <code>a.remove(x)</code> : retire la première occurrence de la valeur <code>x</code> de la liste <code>a</code> ;
* <code>a.index(x)</code> : indique l'indice où se trouve la première occurrence de la valeur <code>x</code> ;
* <code>a.count(x)</code> : indique le nombre de fois que l'on trouve la valeur <code>x</code> dans la liste <code>a</code>.
=== Définition en compréhension ===
La [[w:fr:Liste en compréhension|définition en compréhension]] ''({{lang|en|list comprehension}})'' est une méthode permettant de construire des listes en indiquant simplement des axiomes, des consignes de filtrage. Cette méthode est élégante car proche de la notation mathématique et compacte, mais c'est une méthode itérative donc lente par rapport à une méthode vectorisée fournie par le module NumPy.
Par exemple, pour créer la liste des carrés des nombres entiers entre 0 et 9, il suffit d'écrire
<syntaxhighlight lang="python">
carre = [x**2 for x in range(10)]
</syntaxhighlight>
ce qui se rapproche de la notation d'ensemble <math>\{x^2 | x \in [0 ; 9] \}</math>.
Si l'on veut la liste des nombres strictement inférieurs à 20 dont le carré est supérieur à 10, on peut écrire :
<syntaxhighlight lang="python">
X = [x for x in range(20) if x**2 > 10]
</syntaxhighlight>
ce qui se rapproche de la notation d'ensemble <math>\{x | x \in [0 ; 19], x^2 > 10 \}</math>.
Pour mettre en évidence la performance du calcul vectorisé par rapport à la méthode itérative :
<syntaxhighlight lang="python">
import time
import numpy as np
n = int(1e7) # taille de la liste
t1 = time.perf_counter()
carre = [x**2 for x in range(n)] # Définition en compréhension
t2 = time.perf_counter()
carre2 = np.arange(n)**2 # Calcul vectorisé
t3 = time.perf_counter()
print("En compréhension : ", t2-t1, "s ; vectorisé :", t3-t2, "s ; rapport :", (t2-t1)/(t3-t2))
# En compréhension : 4.515... s ; vectorisé : 0.156... s ; rapport : 28.982...
</syntaxhighlight>
== Structure d'un programme ==
Un programme est simplement une suite d'instructions.
Dans les environnements Unix BSD, un programme Python peut être considéré comme un script c'est-à-dire qu'il suffit de taper son nom dans l'invite de commande ''({{lang|en|shell}})'' sans avoir à invoquer <code>python</code>. Le programme doit alors commencer par un en-tête normalisé surnommé ''{{lang|en|[[wikt:shebang|shebang]]}}'' :
<syntaxhighlight lang="python">
#!/usr/bin/env python3
</syntaxhighlight>
Ce ''{{lang|en|shebang}}'' est inutile avec Jupyter.
L'en-tête peut également contenir la description de l'encodage du fichier texte, typiquement :
<syntaxhighlight lang="python">
# coding: utf-8
</syntaxhighlight>
Le codage UTF-8 est le codage par défaut pour Python 3, il est donc inutile de l'indiquer.
Les commentaires sont introduits par le croisillon <code>#</code>.
On peut grouper une suite d'instructions dans un bloc. Un bloc d'instructions commence par deux-points « <code>:</code> » et est identé, c'est-à-dire qu'il a une marge constituée de quatre espaces — on peut aussi utiliser une tabulation mais il ne faut pas mélanger les deux méthodes ; les tabulations sont déconseillées, il vaut mieux utiliser quatre espaces<ref>{{lien web
| url = https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces
| titre = Tabs or Spaces?
| site = Python documentation
| consulté le = 2019-03-14
}}</ref>. Pour terminer le bloc, il suffit simplement de revenir en début de ligne ; contrairement à d'autres langages, il n'y a pas de commende de fin ''({{lang|en|end}})'', c'est l'indentation qui définit le bloc.
: # début du bloc
''instruction 1''
''instruction 2''
…
''dernière instruction du bloc''
''instruction hors bloc''
Par exemple, une exécution conditionnelle <code>if</code> ou une boucle <code>for</code> exécute un bloc d'instruction. Si l'on a besoin d'un bloc d'instruction qui « ne fait rien », on utilise l'instruction <code>pass</code>.
== Structures de contrôle ==
'''Boucle itérative'''
La boucle itérative s'écrit :
<syntaxhighlight lang="python">
for <variable> in <itérable>:
<bloc d’instructions>
</syntaxhighlight>
Si l'on veut que la variable prenne ''n'' valeurs de 0 à ''n'' – 1, on utilise l'instruction <code>range()</code> :
<syntaxhighlight lang="python">
for i in range(5):
print(i)
print("Fin de la boucle")
</syntaxhighlight>
<code>[▶]</code>
0
1
2
3
4
Fin de la boucle
En fait, la commande <code>range()</code> extrait des valeurs de l'ensemble des nombres entiers ; on peut ainsi utiliser le découpage en tranches, par exemple <code>range(2, 5)</code>pour avoir la « liste » <code>[2, 3, 4]</code>. Notez que <code>range()</code> ne crée pas à proprement parler une liste, cela crée un objet de type ''« {{lang|en|range}} »'' (plage, intervalle) ; pour avoir une liste, il faut écrire <code>list(range(n))</code>.
Dans une boucle, la commande <code>continue()</code> saute la fin du bloc d'instruction et passe à la valeur suivante de la boucle. La commande <code>break()</code> interrompt la boucle et passe à la suite.
'''Exécution conditionnelle'''
L'exécution conditionnelle s'écrit :
<syntaxhighlight lang="python">
if <booléen>:
<bloc d’instructions>
</syntaxhighlight>
On peut utiliser les commandes <code>elif</code> ''(else if'') et <code>else</code> :
<syntaxhighlight lang="python">
if <booléen>:
<bloc d’instructions>
elif <booléen>:
<bloc d’instructions>
else:
<bloc d’instructions>
</syntaxhighlight>
Notez que le test d'une condition est gourmand en ressources. S'il s'agit de savoir si l'on effectue une opération mathématique simple ou pas, on peut remplacer le test par une multiplication par un booléen (<code>True</code> vaut 1, <code>False</code> vaut 0). Par exemple, plutôt que d'écrire
<syntaxhighlight lang="python">
if a > 0:
b = b - c
</syntaxhighlight>
mieux vaut écrire :
<syntaxhighlight lang="python">
b = b - (a > 0)*c
</syntaxhighlight>
'''Boucle antéconditionnée'''
La boucle antéconditionnée s'écrit :
<syntaxhighlight lang="python">
while <booléen>:
<bloc d’instructions>
</syntaxhighlight>
Cette boucle peut contenir des instructions <code>continue()</code> et <code>break()</code>.
== Fonction ==
La déclaration d'une fonction utilise la commande <code>def</code>. La fonction est un bloc d'instructions. Si elle doit renvoyer des valeurs, on utilise la commande <code>return</code>. Par exemple
<syntaxhighlight lang="python">
def nombres(n):
"""But : Entrer plusieurs nombres
Entrée : n, entier : quantité de nombre à saisir.
Sortie : foo : liste de n réels.
""" # description de la fonction
foo = [] # initialisation
for i in range(n):
foo = foo+[float(input("Entrez un nombre"))]
return foo
a = nombres(3)
print(a)
</syntaxhighlight>
La fonction commence par une chaîne de caractères qui la décrit. Cette chaîne peut être récupérée automatiquement par certains logiciels pour faire une documentation automatique. Si la description prend plusieurs lignes, elle commence et finit par trois double-guillemets <code>"""…"""</code> ; en fait, par convention, même si cela n'est pas obligatoire, les descriptions sont toutes encadrées de trois double-guillemets. Cette description est appelée ''{{lang|en|docstring (documentation string)}}''. Pour récupérer les ''{{lang|en|docstrings}}'' :
<syntaxhighlight lang="python">
def foo():
"""Cette fonction ne fait rien"""
pass
print(foo.__doc__)
# Cette fonction ne fait rien
</syntaxhighlight>
L'instruction <code>input()</code> permet à l'utilisateur de saisir une valeur. La valeur est retournée sous la forme d'une chaîne de caractères qui est ensuite convertie en nombre réel avec l'instruction <code>float()</code>.
On peut définir une valeur par défaut en l'indiquant dans l'en-tête de la définition de la fonction, de la manière suivante :
<syntaxhighlight lang="python">
def nombres(n=1): # valeur par défaut : 1
"""But : Entrer plusieurs nombres
Entrée : n, entier : quantité de nombre à saisir.
Sortie : foo : liste de n réels.
""" # description de la fonction
foo = [] # initialisation
for i in range(n):
foo = foo+[float(input("Entrez un nombre"))]
return foo
</syntaxhighlight>
Si le paramètre à initialiser est de type modifiable ''({{lang|en|mutable}})'', comme par exemple une liste, il faut procéder comme suit :
<syntaxhighlight lang="python">
def fooFonction(fooListe=None): # valeur par défaut : n'existe pas
"""Description"""
if fooListe = None:
fooListe = [] # initialisation
<suite des instructions>
</syntaxhighlight>
Par défaut, les variables sont locales. On peut rendre une variable globale avec l'instruction <code>global</code> ''à l'intérieur de la fonction'', avant l'utilisation de la variable. Par exemple :
<syntaxhighlight lang="python">
a = 1
b = 1
def toto():
"""Test de variable globale.
Entrée : aucune.
Sortie : aucune."""
global a
a = 2
b = 2
toto()
print("a =", a, "; b =", b) # a = 2 ; b = 1
</syntaxhighlight>
Pour être plus précis : si une variable n'est pas assignée dans une fonction, alors Python va chercher une variable du même nom à l'extérieur de la fonction. Mais à partir du moment où la variable est assignée dans la fonction, elle devient locale ''sauf'' si l'on a utilisé l'instruction <code>global</code>.
Si l'on s'attend à un nombre indéfini d'arguments, on utilise la notion d'empaquetage/dépaquetage ''({{lang|en|packing/unpacking}})''<ref>{{lien web
| url = https://deusyss.developpez.com/tutoriels/Python/args_kwargs/
| titre = Introduction à *args et **kwargs
| consulté le = 2019-03-09
| site = Developpez.com
}}.</ref>. L'empaquetage consiste à mettre les arguments dans un n-uplet, le dépaquetage consiste à développer un n-uplet en plusieurs variables. Cela se fait en mettant un astérisque ''({{lang|en|splat}})'' « <code>*</code> » devant le nom de la variable. Par convention, on utilise le nom de variable <code>*args</code> mais cela n'est pas obligatoire.
<syntaxhighlight lang="python">
def concatenation(*args):
"""Concatène des chaînes de caractères
Entrée : *args, n-uplet de chaînes de caractères.
Sortie : resultat, chaîne de caractères."""
resultat = ""
for i in args:
resultat = resultat + i
return resultat
concatenation("a", "foo", "toto") # 'afoototo'
</syntaxhighlight>
À l'inverse, si une fonction doit recevoir plusieurs paramètres, on peut à la place lui transmettre une liste à dépaqueter :
<syntaxhighlight lang="python">
def addition(a, b):
"""Ajoute deux nombres
Entrées :
— a : réel ;
— b : réel.
Sortie : a+b, réel"""
return a+b
arg = (1, 2)
addition(*arg) # 3
</syntaxhighlight>
On peut aussi empaqueter/dépaqueter un dictionnaire, on utilise pour cela deux astérisques « <code>**</code> ». Par convention, on utilise le nom <code>**kwargs</code> sans que cela soit obligatoire.
L'instruction <code>lambda</code> permet de créer de petites fonctions ne contenant pas de boucle ni de branchement conditionnel. Cependant, si la déclaration est courte et compacte, le code n'est pas toujours facilement lisible ; l'utilisation de cette instruction n'est pas recommandée.
Par exemple l'expression
<syntaxhighlight lang="python">
f = lambda x: 2*x
</syntaxhighlight>
est la même chose que
<syntaxhighlight lang="python">
def f(x):
"""Calcule le double.
Entrée : x, réel.
Sortie : 2*x, réel."""
return 2*x
</syntaxhighlight>
{{note|L'instruction <code>eval()</code> exécute une chaîne de caractères, c'est-à-dire traite une chaîne de caractères comme si c'étaient des instructions données à Python. Cette instruction est à éviter pour deux raisons :
# Un utilisateur malveillant pourrait entrer du code malveillant dans la chaîne de caractères.
# L'exécution est lente puisque Python doit compiler la chaîne à la volée.
Cette instruction peut en général être remplacée par une autre instruction.
}}
== Gestion des erreurs ==
Dans un bloc d'instructions, on peut utiliser la structure <code>try:… except:</code>. Le bloc après <code>try</code> est exécuté ; si une erreur se déclare dans ce bloc, alors le bloc <code>except</code> s'exécute. Par exemple
<syntaxhighlight lang="python">
try:
1/0 # Génère une erreur
except:
print("Division par zéro") # Cette instruction est donc exécutée
</syntaxhighlight>
On peut compléter avec <code>else:</code> et <code>finally:</code> :
<syntaxhighlight lang="python">
try:
<code à exécuter>
except:
<s’exécute en cas d’erreur>
else:
<s’exécute s’il n’y a pas d’erreur>
finally:
<s’exécute dans tous les cas>
</syntaxhighlight>
On peut séparer les différents types d'erreur :
<syntaxhighlight lang="python">
try:
<code à exécuter>
except ValueError:
print("Valeur erronée")
except TypeError:
print("Type erroné")
</syntaxhighlight>
Les types d'erreur les plus courants sont :
* <code>NameError</code> : le nom de variable n'existe pas ;
* <code>TypeError</code> : la valeur n'est pas du bon type ;
* <code>ValueError</code> : la valeur n'est pas compatible avec ce qui est attendu ;
* <code>RuntimeError</code> : type d'erreur général.
On peut aussi créer ses propres erreurs : si une situation erronée survient, on peut « lever » une exception avec <code>raise</code>. Par exemple
<syntaxhighlight lang="python">
if a < 0:
raise ValueError("La valeur doit être positive")
</syntaxhighlight>
; Ressources
* {{lien web
| url = https://docs.python.org/3/tutorial/errors.html
| titre = Errors and exceptions
| lang = en
| site = Python documentation
| consulté le = 2019-03-12
}}
* {{lien web
| url = https://docs.python.org/3/library/exceptions.html
| titre = Built-in Exceptions
| lang = en
| site = Python documentation
| consulté le = 2019-03-12
}}
== Exercices ==
=== Calcul du PGCD et du PPCM par l'algorithme d'Euclide ===
{{loupe|w:Algorithme d'Euclide}}
Écrire un programme Python qui demande deux nombres entiers et affiche leurs PGCD et PPCM. Le programme utilisera l'algorithme d'Euclide.
{{boîte déroulante début|solution}}
<syntaxhighlight lang="python">
"""Programme : euclide.py
Auteur : User:cdang
date : 2019-02-19
dates de modification :
----------------------------------------------------------------------------
version de Python : 3
module requis : aucun
----------------------------------------------------------------------------
Objectif : calcule le PGCD et le PPCM de deux nombres entiers.
Entrée
------
au clavier, saisie de deux nombres entiers.
Sorties
-------
à l'écran, affichage du PGCD et du PPCM.
"""
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def euclide():
"""Calcule le PGCD et le PPCM avec l'algorithme d'Elclide
Entrée
------
Aucune, la saisie des paramètres fait partie de la fonction
Sortie
------
affichage du PGCD et du PPCM
"""
print("***** Algorithme d'Euclide *****\n")
a0 = int(input("Premier nombre entier : a = "))
b0 = int(input("Second nombre entier : b = "))
a = a0
b = b0
r = a%b # initialisation
while (r != 0) : # algorithme d'Euclide
a = b
b = r
r = a%b
# affichage des résultats
print("PGCD(", a0, ", ", b0, ") = ", b)
print("PPCM(", a0, ", ", b0, ") = ", a0*b0//b)
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
euclide()
</syntaxhighlight>
On peut simplifier la boucle centrale :
<syntaxhighlight lang="python">
while b: # s'exécute tant que b n'est pas 0
a, b = b, a % b # affectation de liste à liste
return a
</syntaxhighlight>
{{boîte déroulante fin}}
Notez que le module NumPy propose l'instruction <code>gcd()</code> :
<syntaxhighlight lang="python">
import numpy
…
print(numpy.gcd(a, b))
</syntaxhighlight>
=== Tours de Hanoï ===
{{loupe|w:Tours de Hanoï}}
Écrire un programme Python qui demande le nombre ''n'' de plateaux et affiche les manipulations nécessaires pour déplacer la pile d'un emplacement à un autre. Le programme utilisera l'algorithme récursif.
{{boîte déroulante début|solution}}
<syntaxhighlight lang="python">
"""nom : hanoi.py
auteur : User:cdang
date de création : 2019-02-19
dates de modification :
----------------------------------------------------------------------------
version de Python : 3
module requis : aucun
----------------------------------------------------------------------------
Objectif : résout le problème des tours de Hanoï
Entrées
-------
trois chaînes de caractères (nom des piliers)
Sorties
-------
une chaîne de caractères (liste des opérations)
"""
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def hanoi(a, b, c, n):
"""Résout le problème des tours de Hanoï de manière récursive
But : déplace la pile de n disques du piler a au pilier b
Entrées
-------
a, b c : chaînes de 1 caractère, référence des emplacements ;
n : entier, nombre de disques sur l'emplacement a
Sorties
-------
operations : chaînes de caractères décrivant les opérations
""""
if n>1:
operations = hanoi(a, c, b, n-1)
operations = operations+a+"→"+b+" ; "
operations = operations+hanoi(c, b, a, n-1)
else:
operations = a+"→"+b+" ; "
return operations
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
resultat = hanoi("1", "2", "3", 3)
print(resultat)
</syntaxhighlight>
{{boîte déroulante fin}}
=== Lancer de rayons ===
[[Fichier:Lentille hemispherique perspective.svg|vignette|Lentille hémisphérique.]]
Considérons une lentille hémisphérique de rayon R faite d’un verre d’indice de réfraction ''n''. Nous plaçons une source ponctuelle à une distance ''d'' du dioptre plan, sur l’axe optique. Tracer des rayons partant de la source et traversant la lentille.
{{clear}}
{{Boîte déroulante/début |titre=Analyse d’optique géométrique}}
[[Fichier:Lentille hemispherique analyse geometrique.svg|vignette|Analyse géométrique du problème.]]
Il s’agit d’un problème ayant une symétrie de révolution par rapport à l’axe optique. Nous pouvons nous réduire à un problème plan en nous plaçant dans un plan contenant l’axe optique ; l’axe optique est encore un axe de symétrie orthogonale, nous pouvons donc nous contenter d'étudier un demi-plan.
Pour simplifier, nous plaçons le centre du dioptre sphérique à l’origine O du repère. L’axe optique est l’axe ''x'' et l'axe perpendiculaire, vertical sur la figure, c’est l’axe ''y''.
Les coordonnées de la source sont donc (-''d'' ; 0). Le rayon issu de la source et faisant un angle θ avec l’axe ''x'' frappe le dioptre plan à l’altitude ''h''. Nous avons :
: ''h'' = ''d'' ⋅ tan θ.
L’angle d’incidence vaut θ. D’après la loi de Snell-Descartes, l'angle de réfraction θ<sub>2</sub> vaut :
: θ<sub>2</sub> = arcsin((sin θ) / ''n'').
Le rayon réfracté passe par le points de coordonnées (0, ''h''). L’équation de la droite est donc :
: ''y'' = a ⋅ ''x'' + ''h''
avec
: ''a'' = tan θ<sub>2</sub>.
L’équation du cercle de centre O et de rayon R est :
: ''x''<sup>2</sup> + ''y''<sup>2</sup> = R<sup>2</sup>.
Les coordonnées (''x''<sub>M</sub>, ''y''<sub>M</sub>) de l’intersection M du rayon avec le dioptre sphérique vérifient les deux équations. Par substitution, nous obtenons une équation du second degré en ''x'' que nous savons résoudre :
: ''x''<sub>M</sub><sup>2</sup> + (''a'' ⋅ ''x''<sub>M</sub> + ''h'')<sup>2</sup> = R<sup>2</sup>
: ⇔ (1 + ''a''<sup>2</sup>) ⋅ ''x''<sub>M</sub><sup>2</sup> + 2 ⋅ ''a'' ⋅ ''h'' ⋅ ''x''<sub>M</sub> + ''h''<sup>2</sup> – R<sup>2</sup> = 0.
D’après les propriétés du cercle, le rayon est perpendiculaire à la tangente. Le rayon [OM] est donc normal au dioptre en M. Nous pouvons déterminer l’angle d’incidence θ<sub>i</sub> par le produit scalaire :
: <math>\begin{pmatrix} 1 \\ a \end{pmatrix} \cdot \begin{pmatrix} x_\mathrm{M} \\ y_\mathrm{M} \end{pmatrix} = \sqrt{1^2 + a^2} \cdot \mathrm{R} \cdot \cos(\theta_\mathrm{i})</math>
ce qui nous permet de calculer cet angle :
: <math>\theta_\mathrm{i} = \operatorname{arcos} \left ( \frac{x_\mathrm{M} + a \cdot y_\mathrm{M}}{\mathrm{R} \cdot \sqrt{1^2 + a^2} } \right )</math>
Comme nous passons vers un milieu d’indice plus faible, il y a un risque de réflexion totale. L’angle limite est :
: θ<sub>max</sub> = arcsin(1/''n'').
Si l’on a θ<sub>i</sub> > θ<sub>max</sub>, le rayon repart vers l’intérieur. Nous ne traçons pas le rayon car cela nous emmènerait trop loin dans l’analyse. En revanche, si θ<sub>i</sub> ≤ θ<sub>max</sub>, alors nous pouvons appliquer la loi de Snell-Descartes pour avoir l’angle de réfraction θ<sub>e</sub> :
: θ<sub>e</sub> = arcsin(''n'' ⋅ sin θ<sub>i</sub>).
Pour tracer le rayon sortant, il nous faut l’angle θ<sub>3</sub> par rapport à l’horizontale. L’angle du rayon [OM] par rapport à l’horizontal vaut arctan(''y''<sub>M</sub> / ''x''<sub>M</sub>), nous avons donc
: θ<sub>3</sub> = arctan(''y''<sub>M</sub> / ''x''<sub>M</sub>) + θ<sub>e</sub>.
{{Boîte déroulante/fin}}
{{Boîte déroulante/début |titre=Analyse algorithmique}}
'''Structure des données'''
Le problème est décrit par trois paramètres :
# Le rayon <code>R1</code> de la lentille, en milliètres (réel en virgule flottante).
# L’indice du verre, <code>n</code> sans dimension (réel en virgule flottante). L’indice de l’air vaut 1.
# La distance de la source au dioptre d’entrée plan, <code>d</code> en millimètres (réel en virgule flottante).
Un rayon est caractérisé par quatre paramètres :
# L’angle d’émission <code>theta1</code> en radians (réel en virgule flottante).
# L’angle de réfraction dans la lentille <code>theta2</code> en radians (réel en virgule flottante).
# Les cordonnées <code>M</code> en millimètre (vecteur de dimension 2 <code>([x, y])</code> de réels en virgule flottante) du point d’intersection du rayon avec le dioptre sphérique.
# L’angle de réfraction dans l’air après la lentille <code>theta3</code> en radians (réel en virgule flottante).
Pour le calcul et le tracé, nous avons besoin des paramètres intermédiaires suivants :
* l’altitude ''y'' = <code>h</code> en millimètres (réel en virgule flottante) à laquelle le rayon frappe le dioptre plan d’entrée ;
* l’angle d’incidence du rayon avec le dioptre sphérique <code>thetaint</code> en radians (réel en virgule flottante).
Les angles sont stockés en radians car c’est l’unité naturelle pour le calcul mais nous affichons les valeurs en degrés. Comme le calcul de conversion est récurrent, nous conservons les facteurs <code>degversrad</code> (conversion des degrés vers les radians, facteur valant π/180, réel en virgule flottante) et <code>radversdeg</code> (conversion des radians vers les degrés, facteur valant 180/π, réel en virgule flottante).
'''Fonctions'''
Nous avons besoin d’une fonction qui calcule les trois paramètres du rayon <code>(theta2, M, theta3)</code> à partir de l’angle d’émission <code>theta1</code>. Nous appelons cette fonction <code>lanceRayon()</code>. Cette fonction fait appelle à une fonction qui calcule l’angle du rayon réfracté à partir de l’angle du rayon incident <code>theta1</code>, les deux angles étant par rapport à la normale au dioptre au point considéré. Nous appelons cette fonction <code>refrac()</code>.
La recherche de l’intersection <code>M</code> du rayon avec le dioptre sphérique nécessite de résoudre une équation du second degré. Nous utilisons pour cela la recherche des racines du polynôme en <code>x</code> avec la fonction <code lang="python">numpy.polynomial.polynomial.polyroots()</code>. D’après la configuration du problème géométrique, si l’on s’assure que le rayon frappe bien la lentille (0 ≤ <code>h</code> ≤ <code>R1</code>) alors nous sommes sûrs que le problème a deux solutions réelles (une positive et une négative) ou, dans le cas dégénéré où <code>h == R1</code>, une valeur unique <code>x == 0</code>. Comme nous recherchons la valeur positive, nous sélectionons la plus grande des deux racines.
Pour la gestion de la réflexion interne : dans la fonction <code>refrac()</code>, nous vérifions les conditions de réflexion totale et si elles sont remplies, alors nous générons une erreur (commandes <code lang="python">try… except</code> et <code lang="python">raise ValueError</code>). Cette erreur est propagée à la fonction <code>lanceRayon()</code> : <code>lanceRayon()</code> appelle la fonction <code>refrac()</code> et si cette fonction renvoie une erreur, alors <code>lanceRayon()</code> renvoie également une erreur.
Pour trouver l’angle d’émission <code>thetaLimite</code> provoquant la réflexion totale (en radians, réel en virgule flottante), nous effectuons une recherche par dichotomie :
* nous partons de l’angle maximum possible, lorsque le rayon frappe le sommet de la lentille, et nous appelons la fonction <code>lanceRayon()</code> ; si cela ne génère pas d’erreur, alors nous pouvons aller jusqu’à cette valeur, la recherche est terminée ; si cela génère une erreur, alors nous divisons la valeur par deux ;
* à une étape de la recherche donnée, si <code>lanceRayon()</code> ne génère pas d’erreur avec l’angle testé, alors nous savons que l’angle limite est supérieur à cette valeur ; cette valeur minore donc la valeur recherchée ; si au contraire <code>lanceRayon()</code> génère une erreur, alors c’est que l’angle est trop important, cette valeur majore donc la valeur recherchée ; nous pouvons ainsi resserer l’intervalle de recherche ;
* nous nous arrêtons lorsque les valeurs haute et basse sont suffisamment proche.
Concrètement :
# Nous définissons une variable <code>angleHaut</code> angle en radians, réel en virgule flottante) qui est l’angle d’émission le plus bas connu provoquant la réflexion totale.
# Nous définissons une variable <code>angleBas</code> angle en radians, réel en virgule flottante) qui est l’angle d’émission le plus haut connu ne provoquant pas de réflexion totale. Sa valeur initiale est 0. L’angle limite recherché est donc entre <code>angleBas</code> et <code>angleHaut</code>.
# Nous définissons l’angle <code>angleTest</code> comme étant la moyenne entre <code>angleBas</code> et <code>angleHaut</code>. Si <code>lanceRayon(angleTest)</code> génère une erreur, alors <code>angleTest</code> est la nouvelle valeur d’<code>angleHaut</code> (puisque c’est une valeur provoquant la réflexion totale et qu’elle est plus basse que la valeur actuelle d’<code>angleHaut</code>). À l’inverse, si <code>lanceRayon(angleTest)</code> ne génère pas d’erreur, alors <code>angleTest</code> est la nouvelle valeur d’<code>angleBas</code> (puisque c’est une valeur ne provoquant pas la réflexion totale et qu’elle est plus haute que la valeur actuelle d’<code>angleBas</code>).
# Nous arrêtons la procédure lorsque l’écart entre <code>angleBas</code> et <code>angleHaut</code> est inférieur à {{unité|10|échelle=<sup>–3</sup>|rad}} (valeur arbitraire).
La valeur retenue est la valeur finale d’<code>angleBas</code> (puisque l’on veut être sûr qu’il n’y ait pas de réflexion totale). La valeur affichée est la valeur en degrés arrondie au dixième.
{{Boîte déroulante/fin}}
{{Boîte déroulante/début |titre=Solution}}
Nous demandons à l’utilisateur ou à l’utilisatrice les valeurs des paramètres du problème : rayon de la lentille, distance de la source, indice de réfraction du verre. Nous vérifions que les valeurs entrées sont bien des nombres ; si c’est une chaîne vide, alors nous utilisons une valeur par défaut.
Nous créons une fonction <code>refrac()</code> qui permet de calculer l’angle réfracté à partir de l’angle d’incidence et des indices de réfraction. S’il y a rélexion totale, alors nous générons une erreur.
La fonction <code>lanceRayon()</code> calcule les différents points de passage du rayon. Elle appelle pour cela la fonction <code>refrac()</code>. Si un appel de la commande <code>refrac()</code> génère une erreur, alors nous générons également une erreur.
Nous déterminons l’angle d’émision du rayon <code>thetaLimite</code> qui provoque une réflecxion totale. Pour cela, nous créons une fonction <code>rechercheLimite()</code> qui cherche par dichotomie.
Nous traçons un rayon tous les 5° jusqu’à la valeur limite.
<syntaxhighlight lang="python">
#!/usr/bin/env python3
# coding: utf-8
"""nom : lancerRayons.py
auteur : User:cdang
date de création : 2022-05-06
dates de modification :
----------------------------------------------------------------------------
version de Python : 3
module requis : NumPy, matplotlib
----------------------------------------------------------------------------
Objectif : trace des trajets optique avec une lentille hémisphérique
Entrées
-------
Le rayon de la lentille, la distance de la source, l’indice de réfraction du verre,
trois chaînes de caractères saisies par l’utilisateur·rice et qui sont converties en réels.
Sorties
-------
La valeur limite de l’angle (réel) et le tracé de plusieurs rayons.
"""
# ******************************************************
# ******************************************************
# ** Lancer de rayons pour une lentille hémisphérique **
# ******************************************************
# ******************************************************
import numpy as np
import matplotlib.pyplot as plt
import numpy.polynomial.polynomial as nppol
# **************
# * Constantes *
# **************
# Pour la conversion degrés ↔ radians
radversdeg = 180/np.pi
degversrad = 1/radversdeg
# *************
# * Fonctions *
# *************
def boucleEntreeNombre(messageSaisie, valeurDefaut):
"""Permet de s’assurer que l’utilisateur·rice a bien entré un nombre.
Entrée :
— message à afficher (chaîne de caractères) ;
— valeur par défaut (réel à virgule flottante).
Sortie : nombre (réel à virgule flottante)."""
messageErreur = "Veuillez entrer une valeur numérique (ou vide pour accepter la valeur par défaut).\n"
execute = True
while execute:
strNombre = input(messageSaisie+f" (valeur par défaut {valeurDefaut}) : ")
if strNombre == "":
nombre = valeurDefaut
execute = False
else:
try:
nombre = float(strNombre)
except:
print(messageErreur)
else:
execute = False
return nombre
def initialisation():
"""L’utilisateur·rice entre les variables du problème.
Entrées : aucune.
Sorties :
— R1 (mm) : rayon de la lentille ;
— d (mm) : distance de la source au dioptre plan ;
— n (sans dimension) : indice de réfraction du verre."""
R1 = boucleEntreeNombre("Rayon de la lentille en mm", 20.0)
d = boucleEntreeNombre("Distance de la source au dioptre plan en mm", 20.0)
n = boucleEntreeNombre("Indice de réfraction (sans dimension)", 1.5)
return (R1, d, n)
def refrac(n1, n2, theta1):
"""Calcule l’angle de réfraction theta2 (radians) en fonction
— de l’angle d’incidence theta1 (radians);
— de l’indice de réfraction n1 du premier milieu ;
— de l’indice de réfraction n2 du second milieu."""
reflexionTotale=False
rapport=n2/n1
rapportinv=np.reciprocal(rapport)
if n1 > n2:
thetal = np.arcsin(rapport) # angle limite pour la réflexion totale
if theta1 >= thetal:
reflexionTotale=True
if reflexionTotale:
print("Réflexion totale")
raise ValueError
else:
return np.arcsin(rapportinv*np.sin(theta1))
def lanceRayon(n1, n2, d, R, theta1):
"""Détermine le rayon issu de la source
située à une distance d (mm) du bareau
et avec une élévation de theta1 (radians),
en fonction des indices de réfraction n1 et n2.
Les éléments retournés sont :
— la hauteur h (mm) à laquelle le rayon frappe le barreau ;
— l’angle de réfraction theta2 (radians)) dans le barreau ;
— l’angle de réfraction theta3 (radians) à la sortie du barreau
— le point M(x, y) (mm) auquel le rayon sort du barreau."""
h = d*np.tan(theta1)
if h >= R:
print("Le rayon est au-dessus du barreau")
raise ValueError
else:
theta2 = refrac(n1, n2, theta1)
a = np.tan(theta2)
x = max(nppol.polyroots([h*h - R*R, 2*a*h, 1+a*a])) # recherche de l’intersection du rayon avec le cercle
y = a*x + h
M = np.array([x, y])
thetaint = np.arccos((x + a*y)/(R*np.sqrt(1 + a*a)))
theta3 = np.arctan(y/x) - refrac(n2, n1, thetaint)
return (h, theta2, theta3, M)
def rechercheLimite(n1, n2, d, R):
"""Recherche l’angle limite pour la réflexion totale.
Entrée :
— indice de réfraction des milieux 1 et 2, n1 et n2 ;
— distance au barreau, d(mm).
Sortie : angle limite theta (radians)"""
angleHaut = np.arctan(R/d)
angleBas = 0
angleTest = angleHaut
try:
lanceRayon(n1, n2, d, angleTest, R)
except:
condition = True # il y a réflexion total en haut de la lentille
else:
condition = False # il n’y a jamais réflexion totale dans la lentille
while condition: #dichotomie
angleTest = np.mean([angleHaut, angleBas]) # on ajuste la valeur de test
try:
lanceRayon(n1, n2, d, R, angleTest)
except:
angleHaut = angleTest # réflexion totale : on abaisse la valeur maximale
else:
angleBas = angleTest # pas de réflexion totale : on monte la valeur minimale
condition = ((angleHaut - angleBas) >= 0.001) # on a cerné la limite à 0,001 rad près
if not condition:
angleTest = angleBas
return angleTest
# ***********************
# * Programme principal *
# ***********************
(R1, d, n) = initialisation()
xmax = round(R1 + d)
thetaLimite = rechercheLimite(1, n, d, R1)
thetaLimiteDeg = thetaLimite*radversdeg
print(f"Angle limite pour la réflexion totale : {thetaLimiteDeg:.1f}°.\n")
anglesDeg = np.arange(0, thetaLimiteDeg, 5)[1:] # trace un rayon tous les 5°
anglesRad = anglesDeg*degversrad
nb = len(anglesDeg)
h = np.zeros(nb) # initialisation des vecteurs de valeurs
theta2 = np.zeros(nb)
theta3 = np.zeros(nb)
M = np.zeros((nb, 2))
for i in range(nb):
(h[i], theta2[i], theta3[i], M[i, :]) = lanceRayon(1, n, d, R1, anglesRad[i])
(h_lim, theta2_lim, theta3_lim, M_lim) = lanceRayon(1, n, d, R1, thetaLimite)
# tracé
anglesCercle = 0.5*np.pi*(np.linspace(1, 0, 20))
x_cercle = R1*np.cos(anglesCercle) # coordonnées des pints du cercle
y_cercle = R1*np.sin(anglesCercle)
fig = plt.plot([-d,xmax], [0, 0], "k-.", linewidth="0.5") # tracé de l’axe optique
for i in range(nb):
plt.plot([-d, 0, M[i, 0], xmax], [0, h[i], M[i, 1], M[i, 1] + (xmax - M[i, 0])*np.tan(theta3[i])],
label=f"{anglesDeg[i]:.0f}°")
plt.plot([-d, 0, M_lim[0], xmax], [0, h_lim, M_lim[1], M_lim[1] + (xmax - M_lim[0])*np.tan(theta3_lim)],
label=f"{0.1*int(np.trunc(10*thetaLimite*radversdeg)):.1f}°")
plt.plot(x_cercle, y_cercle, "k", linewidth="0.5") # tracé du cercle
plt.plot([0,0], [0, R1], "k", linewidth="0.5") # tracé du premier dioptre
#plt.axis("square")
plt.gca().set_aspect("equal", adjustable="box")
plt.xlabel("x (mm)")
plt.ylabel("y (mm)")
plt.title("Lentille hémisphérique, lancer de rayons")
plt.legend()
plt.savefig("lentille_hemispherique_lancer_rayon.svg", format="svg")
plt.show()
</syntaxhighlight>
{{Boîte déroulante/fin}}
== Mesurer le temps ==
Le module <code>time</code> fournit les fonctions suivantes :
* <code>time.gmtime()</code> : renvoie la date et l'heure du méridien de Greenwich (''{{lang|en|Greenwich mean time}}'', GMT), sous la forme d'un dictionnaire (année, mois, jour du mois, heure, minute, seconde, jour de la semaine, jour de l'année, heure d'été/hiver),
** jour de la semaine est un entier entre 0 (lundi) et 6 (dimanche),
** jour du mois est un entier entre 1 et 366 ;
* <code>time.localtime()</code> : comme le précédent, mais l'heure est l'heure locale ;
* <code>time.time()</code> : donne le nombre de seconde qui se sont écoulées depuis le 1er janvier 1970 ;
* <code>time.gmtime(n)</code> et <code>time.localtime(n)</code> transforment un nombre de secondes (écoulées depuis le 1er janvier 1970) en une date au format (année, mois, jour, etc.), n-uplet de neuf valeurs ; <code>time.mktime()</code> fait le contraire, il transforme un n-uplet de neuf valeurs (années, mois, jour, etc.) en un nombre de secondes (écoulées depuis le 1er janvier 1970) ;
* <code>time.sleep(n)</code> : provoque une pause dans le déroulement du programme de ''n'' secondes ;
* <code>time.perf_counter()</code> : indique une date en seconde ; s'utilise pour mesurer la durée d'exécution d'une partie du code, en faisant la différence entre deux relevés.
Concernant la date et l'heure sous la forme d'un n-uplet, on peut extraire l'heure de la manière suivante :
<syntaxhighlight lang="python">
import time
a = time.localtime()
print("Il est ", a[3], "h", a[4])
# ou bien
print("Il est ", a.tm_hour, "h", a.tm_min)
</syntaxhighlight>
Pour mesurer la performance d'une portion de code :
<syntaxhighlight lang="python">
import time
t1 = time.perf_counter()
<suite d’instructions>
t2 = time.perf_counter()
print("Durée d'exécution :", t2-t1
</syntaxhighlight>
== Programmation orientée objet ==
Nous n'allons pas ici faire un cours de programmation orientée objet (POO), nous allons aborder le sujet de manière pragmatique.
De manière schématique, un « objet » est une « super-variable ». Cette super-variable peut contenir plusieurs variables, appelées « attributs » ; elle contient en fait un dictionnaire (paires « nom d'attribut : valeur d'attribut »). Elle peut aussi contenir des fonctions spécifiques appelées « méthodes ». De même qu'une variable a un type, un objet fait partie d'une « classe ». La classe est le modèle de l'objet ; en franglais informatique, on dit que l'objet est une instance de la classe.
La POO est donc un formalisme : lorsque l'on définit des variables et des fonctions concernant un même type d'objet (au sens commun du terme), on les empaquette dans une classe. Il faut donc d'abord définir la classe, puis attribuer cette classe à un objet (« instancier » la classe).
Considérons par exemple que nous voulons travailler sur des [[w:Engrenage|engrenages]] ; pour simplifier, nous nous contentons d'engrenages à dentures droites. Une roue dentée, un pignon, est essentiellement définie par son nombre de dents Z et par son module ''m'' qui correspond à la largeur de dents<ref>ainsi que par son épaisseur ''e'' et le matériau dont elle est faite mais nous allons négliger ces paramètres pour la simplicité de l'étude.</ref>. Nous allons définir trois méthodes : la méthode <code>.diametrePrimitif()</code> qui calcule le diamètre primitif de la roue dentée, <code>.pas()</code> qui calcule la largeur des dents au niveau du cercle primitif et <code>.rapport()</code> qui calcule le rapport de transmission de deux roues engrenées Z<sub>1</sub>/Z<sub>2</sub>. La méthode <code>.rapport()</code> vérifie par ailleurs que les roues ont le même module, condition indispensable pour former un engrenage.
Nous définissons la classe ainsi :
<syntaxhighlight lang="python">
class pignon:
"""roue dentée""" # explication de la classe
pi = 3.141592653589793 # pour calculer le pas
def __init__(self, Z=13, m=0.06):
# instructions lancées lors de la déclaration
"""Valeurs des attributs"""
self.Z = Z # nombre de dents
self.m = m # module
def diametrePrimitif(self):
"""Calcule le diamètre primitif"""
return self.m*self.Z
def pas(self):
"""Calcule le pas"""
return self.pi*self.m
def rapport(roueDentee, self):
"""Calcule le rapport de transmission"""
if roueDentee.m != self.m: # gestion de l'erreur
raise ValueError("Les pignons doivent avoir le même module")
else:
return roueDentee.Z/self.Z
</syntaxhighlight>
Nous remarquons que lorsque nous déclarons les méthodes, le paramètre <code>self</code> correspond à l'objet lui-même. Ainsi, dans la méthode <code>.rapport()</code>, la variable <code>self.Z</code> est le nombre de dents de la roue elle-même et <code>roueDentee.Z</code> est le nombre de dents de la roue passée en paramètre.
Pour déclarer les roues, nous écrivons :
<syntaxhighlight lang="python">
roue1 = pignon() # attribution de la classe, « instanciation »
roue1.Z = 13 # définition des caractéristiques du pignon « roue1 »
roue1.m = 2
roue2 = pignon(16, 2) # manière alternative
</syntaxhighlight>
Nous pouvons alors utiliser les objets de la manière suivante :
<syntaxhighlight lang="python">
print(roue1.Z) # 13
print(roue1.diametrePrimitif()) # 26
R = roue1.rapport(roue2) # 0.8125
</syntaxhighlight>
La commande <code>dir(a)</code> affiche tous les attributs et méthodes de l'objet <code>a</code>.
; Ressources
: {{lien web
| url = https://docs.python.org/3/tutorial/classes.html
| titre = Classes
| site = Python documentation
| consulté le = 2019-03-08
}}
== Interface graphique avec Tk ==
=== Généralités ===
Une interface graphique utilisateur (GUI, ''{{lang|en|graphic user interface}}'') est un ensemble de boîtes permettant d'interagir avec l'utilisateur, c'est-à-dire qui permettent la saisie d'informations, l'exécution d'actions et l'affichage d'informations. L'interface se compose d'éléments appelés ''{{lang|en|widgets}}''.
Les éléments ''({{lang|en|widgets}})'' classiques sont :
* boîte de dialogue ''({{lang|en|dialog box}})'' : fenêtre contenant d'autres éléments ;
* étiquette ''({{lang|en|label}})'' : texte affiché ;
* liste déroulante ''({{lang|en|drop-down list}})'' : zone permettant le choix d'une option, la liste se déployant lorsque l'on clique sur la zone ;
* zone de texte, champ de saisie ''({{lang|en|text box}})'' : zone permettant de taper du texte ;
* boîte combinée ''({{lang|en|combo box}})'' : zone de saisie de texte contenant une liste déroulante qui permet de choisir des éléments prédéfinis ;
* bouton ''({{lang|en|button}})'' : objet effectuant une action lorsque l'on clique dessus ;
* case à cocher ''({{lang|en|checkbox, tickbox}})'' : objet permettant d'activer ou de désactiver une option lorsque l'on clique dessus ;
* bouton radio, case d'option ''({{lang|en|radio button}})'' : objet permettant d'activer une option en désactivant les autres options ; une seule option peut être activée à la fois.
=== Avec Tk ===
Plusieurs modules permettent de gérer les interfaces graphiques. Nous choisissons ici le module développé sur la bibliothèque Tk qui est une bibliothèque multiplateforme. Pour cela, nous importons le module <code>tkinter</code> ainsi que le module <code>ttk</code>, ce dernier proposant des options plus « modernes » :
<syntaxhighlight lang="python">
import tkinter as tk
from tkinter import ttk
</syntaxhighlight>
Voici un programme permettant comme précédemment de calculer le rapport de transmission d'un engrenage. Nous détaillons sa construction ci-après.
<syntaxhighlight lang="python">
# référence : https://tkdocs.com/tutorial/firstexample.html
import tkinter as tk
from tkinter import ttk
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def calcule(*args):
"""Calcule le rapport de transmission d'un engrenage"""
try:
valeurZ1 = float(IUz1.get())
valeurM1 = float(IUm1.get())
valeurZ2 = float(IUz2.get())
valeurM2 = float(IUm2.get())
if valeurM1 != valeurM2:
IUrapport.set("Erreur de module")
else:
IUrapport.set(valeurZ2/valeurZ1)
except:
IUrapport.set("erreur")
# *************************
# *************************
# ** Interface graphique **
# *************************
# *************************
# fenetre principale
fenetre = tk.Tk()
fenetre.title("Rapport de réduction")
# élément (widget) cadre contenant tout le reste
cadre = ttk.Frame(fenetre, padding="3 3 12 12")
cadre.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
# le cadre s'étire si l'on étire la fenêtre
fenetre.columnconfigure(0, weight=1)
fenetre.rowconfigure(0, weight=1)
# Paramètres du système (variables)
IUz1 = tk.StringVar()
IUm1 = tk.StringVar()
IUz2 = tk.StringVar()
IUm2 = tk.StringVar()
IUrapport = tk.StringVar()
# Création des zones de saisie
z1_entry = ttk.Entry(cadre, width=7, textvariable=IUz1)
m1_entry = ttk.Entry(cadre, width=7, textvariable=IUm1)
z2_entry = ttk.Entry(cadre, width=7, textvariable=IUz2)
m2_entry = ttk.Entry(cadre, width=7, textvariable=IUm2)
# Création des étiquettes statiques
z1_label = ttk.Label(cadre, text="z1")
m1_label = ttk.Label(cadre, text="m1")
z2_label = ttk.Label(cadre, text="z2")
m2_label = ttk.Label(cadre, text="m2")
rapport_statique = ttk.Label(cadre, text="Rapport de transmission : ")
# Création de l'étiquette dynamique
rapport_dynamique = ttk.Label(cadre, textvariable=IUrapport)
# Création du bouton
bouton = ttk.Button(cadre, text="Calcul", command=calcule)
# Placement des éléments (widgets)
z1_label.grid(column=1, row=1, sticky=tk.W)
z1_entry.grid(column=2, row=1, sticky=(tk.W, tk.E))
m1_label.grid(column=1, row=2, sticky=tk.W)
m1_entry.grid(column=2, row=2, sticky=(tk.W, tk.E))
z2_label.grid(column=1, row=3, sticky=tk.W)
z2_entry.grid(column=2, row=3, sticky=(tk.W, tk.E))
m2_label.grid(column=1, row=4, sticky=tk.W)
m2_entry.grid(column=2, row=4, sticky=(tk.W, tk.E))
rapport_statique.grid(column=1, row=5, sticky=tk.W)
rapport_dynamique.grid(column=2, row=5, sticky=(tk.W, tk.E))
bouton.grid(column=2, row=6, sticky=tk.W)
# ajoute une gouttière entre les éléments
for enfant in cadre.winfo_children():
enfant.grid_configure(padx=5, pady=5)
# Emplacement initial du curseur
z1_entry.focus()
# effet de la touche [entrée]
fenetre.bind("<Return>", calcule)
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
# Affichage et activation de la fenêtre
fenetre.mainloop()
</syntaxhighlight>
[[Fichier:Organisation interface Tk Python.svg|vignette|upright=2|Organisation des ''widgets''.]]
'''Explications'''
Nous commençons par définir la boîte de dialogue que nous appelons <code>fenetre</code> ; c'est un objet <code>Tk</code> et nous lui donnons un titre « » :
<syntaxhighlight lang="python">
fenetre = tk.Tk()
fenetre.title("Rapport de réduction")
</syntaxhighlight>
Puis, nous définissons un cadre attaché à cette fenêtre et qui va nous permettre « d'accrocher » les autres éléments, ce qui permet de garder une apparence satisfaisante lorsque l'on retaille la fenêtre :
<syntaxhighlight lang="python">
cadre = ttk.Frame(fenetre)
</syntaxhighlight>
Le cadre va comporter six lignes ''({{lang|en|row}})'' et deux colonnes ''({{lang|en|column}})''.
Nous allons placer une étiquette ''({{lang|en|label}})'' « z1 » : <code>text="z1"</code>. Cette étiquette se trouve dans une case du cadre, celle de la première colonne et la première ligne : <code>grid(column=1, row=1)</code>. Par rapport à cette case, elle est collée à « l'ouest » (W, ''{{lang|en|west}}'', gauche) de la case : <code>sticky=tk.W</code>.
<syntaxhighlight lang="python">
z1_label = ttk.Label(cadre, text="z1") # Création de l'étiquette
z1_label.grid(column=1, row=1, sticky=tk.W) # Placement de l'étiquette
</syntaxhighlight>
Notez que l'on aurait pu écrire directement :
<syntaxhighlight lang="python">
ttk.Label(cadre, text="z1").grid(column=1, row=1, sticky=tk.W)
</syntaxhighlight>
mais le fait de séparer la création de l'élément et son placement facilite la maintenance (recherche d'erreur, évolution du code).
Pour tout ce qui est dynamique, c'est-à-dire les zone de saisie des valeurs et l'affichage du résultat, il faut définir des « chaînes variables » ''({{lang|variable strings}})'' :
<syntaxhighlight lang="python">
IUz1 = tk.StringVar()
</syntaxhighlight>
Cette variable est une variable globale à la création. Nous pouvons alors placer la zone de saisie ''({{lang|en|entry}})'' à côté de l'étiquette lui correspondant. Nous nommons la zone de saisie <code>z1_entry</code> :
<syntaxhighlight lang="python">
z1_entry = ttk.Entry(cadre, width=7, textvariable=IUz1)
</syntaxhighlight>
Nous faisons de même pour les trois autres paramètres de l'engrenage, ''m''<sub>1</sub>, ''z''<sub>2</sub> et ''m''<sub>2</sub>. Le résultat est également une chaîne variable globale. Par rapport à notre mise en page, elle se situe dans la case colonne 2 ligne 5, centrée sur cette case (collé à l'est et à l'ouest) :
<syntaxhighlight lang="python">
rapport = tk.StringVar()
rapport_dynamique = ttk.Label(cadre, textvariable=rapport)
rapport_dynamique.grid(column=2, row=5, sticky=(tk.W, tk.E))
</syntaxhighlight>
Il nous faut encore définir une fonction de manière classique, nous l'appelons « calcule ». Les variables étant globales, on les utilise directement. On récupère les valeurs avec la méthode <code>get()</code> et nous modifions la valeur avec la méthode <code>set()</code> :
<syntaxhighlight lang="python">
def calcule():
valeurZ1 = float(IUz1.get())
valeurZ2 = float(IUz2.get())
IUrapport.set(valeurZ2/valeurZ1)
</syntaxhighlight>
Cette fonction est déclenchée lorsque l'on clique sur le bouton « Calcul » situé dans la case du cadre ligne 6 colonne 2 :
<syntaxhighlight lang="python">
bouton = ttk.Button(cadre, text="Calcul", command=calcule)
bouton.grid(column=2, row=6, sticky=tk.W)
</syntaxhighlight>
ou bien si l'on appuie sur la touche <code>[entrée]</code> du clavier :
<syntaxhighlight lang="python">
fenetre.bind("<Return>", calcule)
</syntaxhighlight>
À tout ceci, nous ajoutons des « gouttières » (marges, ''{{lang|en|paddings}}'') afin d'espacer les éléments.
Il faut ensuite « activer » la fenêtre pour qu'elle s'affiche. La méthode est <code>mainloop()</code> (boucle principale) : « boucle » (elle est active en permanence et attend des actions sur ses éléments),
<syntaxhighlight lang="python">
fenetre.mainloop()
</syntaxhighlight>
Nous avons ci-dessus mis la plupart du code en programme principal. Nous pouvons aussi programmer de manière fonctionnelle, en mettant la plupart du code dans des fonctions ; cependant, pour que la fenêtre et les variables dynamiques soient globales à tout le programme, elles doivent être déclarées dans le programme principal. Nous pouvons aussi mêler la programmation orientée objet.
{{boîte déroulante début|Calcul du rapport de transmission en programmation fonctionnelle et orientée objet}}
<syntaxhighlight lang="python">
# référence : https://tkdocs.com/tutorial/firstexample.html
import tkinter as tk
from tkinter import ttk
# *************
# *************
# ** Classes **
# *************
# *************
class pignon:
"""roue dentée""" # explication de la classe
pi = 3.141592653589793 # pour calculer le pas
def __init__(self, Z=13, m=0.06):
"""Valeurs des attributs"""
# instructions lancées lors de la déclaration
self.Z = Z # nombre de dents
self.m = m # module
def diametrePrimitif(self):
"""Calcule le diamètre primitif"""
return self.m*self.Z
def pas(self):
"""Calcule le pas"""
return self.pi*self.m
def rapport(roueDentee, self):
"""Calcule le rapport de transmission"""
if roueDentee.m != self.m: # gestion de l'erreur
raise ValueError("Les pignons doivent avoir le même module")
else:
return roueDentee.Z/self.Z
# ************************
# ************************
# ** Variables globales **
# ************************
# ************************
# fenetre principale
fenetre = tk.Tk()
# Paramètres du système (variables)
IUz1 = tk.StringVar()
IUm1 = tk.StringVar()
IUz2 = tk.StringVar()
IUm2 = tk.StringVar()
IUrapport = tk.StringVar()
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def calcule(*args):
"""Calcule le rapport de transmission d'un engrenage"""
try:
valeurZ1 = float(IUz1.get())
valeurM1 = float(IUm1.get())
valeurZ2 = float(IUz2.get())
valeurM2 = float(IUm2.get())
if valeurM1 != valeurM2:
IUrapport.set("Erreur de module")
else:
roue1 = pignon(valeurZ1, valeurM1)
roue2 = pignon(valeurZ2, valeurM2)
IUrapport.set(roue1.rapport(roue2))
except:
IUrapport.set("Erreur")
# ***********************
# * Interface graphique *
# ***********************
def configureFenetre():
"""Configuration de la fenêtre principale"""
fenetre.title("Rapport de réduction")
# élément (widget) cadre contenant tout le reste
cadre = ttk.Frame(fenetre, padding="3 3 12 12")
cadre.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
# le cadre s'étire si l'on étire la fenêtre
fenetre.columnconfigure(0, weight=1)
fenetre.rowconfigure(0, weight=1)
# Création des zones de saisie
z1_entry = ttk.Entry(cadre, width=7, textvariable=IUz1)
m1_entry = ttk.Entry(cadre, width=7, textvariable=IUm1)
z2_entry = ttk.Entry(cadre, width=7, textvariable=IUz2)
m2_entry = ttk.Entry(cadre, width=7, textvariable=IUm2)
# Création des étiquettes statiques
z1_label = ttk.Label(cadre, text="z1")
m1_label = ttk.Label(cadre, text="m1")
z2_label = ttk.Label(cadre, text="z2")
m2_label = ttk.Label(cadre, text="m2")
rapport_statique = ttk.Label(cadre, text="Rapport de transmission : ")
# Création de l'étiquette dynamique
rapport_dynamique = ttk.Label(cadre, textvariable=IUrapport)
# Création du bouton
bouton = ttk.Button(cadre, text="Calcul", command=calcule)
# Placement des éléments (widgets)
z1_label.grid(column=1, row=1, sticky=tk.W)
z1_entry.grid(column=2, row=1, sticky=(tk.W, tk.E))
m1_label.grid(column=1, row=2, sticky=tk.W)
m1_entry.grid(column=2, row=2, sticky=(tk.W, tk.E))
z2_label.grid(column=1, row=3, sticky=tk.W)
z2_entry.grid(column=2, row=3, sticky=(tk.W, tk.E))
m2_label.grid(column=1, row=4, sticky=tk.W)
m2_entry.grid(column=2, row=4, sticky=(tk.W, tk.E))
rapport_statique.grid(column=1, row=5, sticky=tk.W)
rapport_dynamique.grid(column=2, row=5, sticky=(tk.W, tk.E))
bouton.grid(column=2, row=6, sticky=tk.W)
# ajoute une gouttière entre les éléments
for enfant in cadre.winfo_children():
enfant.grid_configure(padx=5, pady=5)
# Emplacement initial du curseur
z1_entry.focus()
# effet de la touche [entrée]
fenetre.bind("<Return>", calcule)
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
configureFenetre()
# Affichage et activation de la fenêtre
fenetre.mainloop()
</syntaxhighlight>
{{boîte déroulante fin}}
{{voir
|{{lien web |url=https://docs.python.org/3/library/tkinter.ttk.html |titre=tkinter.ttk — Tk themed widgets |site=docs.python.org |consulté le=2026-06-11}}
}}
{{voir
|{{lien web |url=https://matplotlib.org/stable/gallery/user_interfaces/embedding_in_tk_sgskip.html |titre=How to embed Matplotlib charts in Tkinter GUI? |site=Matplotlib.org |date=2025-07-15 |consulté le=2026-06-11}}
}}
=== Avec PyQt ===
Le module PyQt (prononcer \ˈpaɪ.kjut\) permet d'utiliser la bibliothèque Qt dévelopée par Riverbank Computing. Il permet notamment de créer des interfaces graphiques.
La communication entre objets Qt se fait par une mécanismes de « signal/emplacement » ''({{lang|en|signal/slot}})''. Un emplacement ''({{lang|en|slot}})'' est une fonction ''({{lang|en|callable}})'' ; un signal est un attribut d'un objet. Si l'attribut signal est défini pour l'emplacement, alors on dit que l'emplacement est relié à un signal. Par exemple, un objet <code>QPushButton</code> dispose du signal <code>clicked</code> qui est émis lorsque l'on clique dessus ; on peut ainsi faire exécuter un emplacement (fonction appelable) <code>action()</code> lorsque l'on clique sur le bouton par le biais du signal <code>clicked</code> :
<syntaxhighlight lang="python">
from PyQt5.QtWidgets import QPushButton
bouton = QPushButton("Appuies-moi dessus")
button.clicked.connect(action())
</syntaxhighlight>
{{voir|{{lien web |url=https://www.riverbankcomputing.com/static/Docs/PyQt6/ |titre=Reference guide PyQt6 |site=Riverbank Computing|consulté le=2026-0604}} }}
{{...}}
== Annotations ==
Une annotation est un commentaire qui sert à expliciter un type de variable. La syntaxe est différente des commentaires « classiques » : cela permet d'avoir un affichage différent avec les éditeurs de texte ayant une coloration syntaxique, et ces informations peuvent être récupérées par des logiciels extérieurs pour effectuer une documentation automatique ou bien des vérifications de type. Cependant :
* comme les commentaires normaux, ils n'ont aucune influence lors de l'exécution du texte ; en particulier :
* rien n'oblige à annoter les variables ;
* il est possible d'avoir une variable ayant un type différent de son annotation ; le fait de pouvoir définir et changer le type de variable à la volée est une fonctionnalité fondamentale de Python.
La syntaxe pour une annotation est :
: nom_de_variable + deux-points + espace + type
par exemple :
<syntaxhighlight lang="python">
a: int
</syntaxhighlight>
Notez qu'ici, la variable n'est ''pas'' créée. Pour la créer, il faut lui affecter une valeur. Il est possible de l'affecter après ou bien sur la même ligne avec la syntaxe :
: nom_de_variable + deux-points + espace + type + espace + égal + espace + valeur
par exemple :
<syntaxhighlight lang="python">
a: int
a = 5
# est équivalent à
a: int = 5
</syntaxhighlight>
Même si l'annotation n'a pas d'impact sur l'exécution, le type doit être un type existant sinon cela génère une erreur de syntaxe. Les types classiques sont :
: <code>int</code> — <code>float</code> — <code>str</code> — <code>bool</code> — <code>list</code> — <code>tuple</code> — <code>dict</code>
Il est également possible de mettre une chaîne de caractères :
<syntaxhighlight lang="python">
a: "ce que je veux" = 3.1516
</syntaxhighlight>
On peut annoter une fonction. Il est possible d'annoter les variables déclarées au sein de la fonction, mais pas les variables globales (puisqu'elle ne sont pas définie au sein de la fonction). On peut aussi annoter :
* les variables passées en paramètre, avec la même syntaxe dans les parenthèses ;
* annoter le type de la variable de sortie (retournée) en la faisant précéder de <code>-></code> :
<syntaxhighlight lang="python">
def plusCinq(a: float = 0) -> float:
return a + 5
</syntaxhighlight>
; Ressources
* {{lien web
| url = https://www.python.org/dev/peps/pep-0526/
| titre = PEP 526 -- Syntax for Variable Annotations
| site = Python.org
| consulté le = 2019-04-05
| lang = en
}}
* {{lien web
| url = https://www.python.org/dev/peps/pep-3107/
| titre = PEP 3107 -- Function Annotations
| site = Python.org
| consulté le = 2019-04-05
| lang = en
}}
== Décorateur ==
Un décorateur est une fonction qui s'applique à une fonction, à la manière de la composition mathématique ''g'' ∘ ƒ = ''g''(ƒ). Mais cette composition affecte la fonction elle-même ; l'utilisateur appelle la fonction ƒ mais c'est la fonction ''g'' ∘ ƒ qui s'exécute. Cette fonction ''g'' est appelée le décorateur.
L'intérêt est de pouvoir modifier une fonction sans modifier le code de la fonction elle-même.
Pour appliquer une décoration, il faut :
# Déclarer le décorateur : une fonction qui s'applique à une autre fonction.
# Affecter le décorateur à la fonction visée : en mettant <code>@''décoration''</code> juste avant la définition de la fonction.
Par exemple :
<syntaxhighlight lang="python">
def decorateur(f):
print("Avant la fonction")
f()
print("après la fonction")
@decorateur
def afficheFoo():
print("Foo.")
afficheFoo
# Avant la fonction
# Foo.
# Après la fonction
</syntaxhighlight>
Lorsque l'on appelle <code>afficheFoo</code>, on appelle en fait <code>decorateur(afficheFoo)</code>.
Si la fonction à modifier admet des paramètres, il faut définir une fonction enveloppante dans le décorateur. Par exemple, nous définissons ci-dessous un décorateur <code>deuxFois()</code> qui fait s'exécuter deux fois de suite la fonction :
<syntaxhighlight lang="python">
def deuxFois(f):
def conteneurFonction(*args, **kwargs):
f(*args, **kwargs)
f(*args, **kwargs)
return conteneurFonction
@deuxFois
def plusCinq(a: int = 0):
print(a + 5)
plusCinq(2)
# 7
# 7
print(plusCinq.__name__)
# conteneurFonction
</syntaxhighlight>
Nous voyons que l'application du décorateur a modifié le nom de la fonction — pas le nom de la variable qui contient la fonction mais bien son nom « intime ». Pour éviter cela, on utilise la méthode <code>wraps()</code> du module <code>functools</code> :
<syntaxhighlight lang="python">
import functools
def deuxFois(f):
@functools.wraps(f)
def conteneurFonction(*args, **kwargs):
f(*args, **kwargs)
f(*args, **kwargs)
return conteneurFonction
@deuxFois
def plusCinq(a: int = 0):
print(a + 5)
plusCinq(2)
# 7
# 7
print(plusCinq.__name__)
# plusCinq
</syntaxhighlight>
On peut par exemple utiliser un décorateur pour la mémoïsation. La mémoïsation est une méthode consistant à mémoriser les valeurs d'une fonction au fur et à mesure de son utilisation ; ainsi, si l'on veut évaluer la fonction avec les mêmes entrées, on se contente d'aller chercher la valeur enregistrée ce qui est plus rapide. On sacrifie donc la place mémoire au profit de la rapidité. On peut trouver des décorateurs de mémoïsation aux adresses suivantes :
* https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
* https://gist.github.com/robcowie/1357800
; Ressources
: {{lien web
| url = https://www.python.org/dev/peps/pep-0318/
| titre = PEP 318 -- Decorators for Functions and Methods
| site = Python.org
| lang = en
| consulté le = 2019-04-05
}}
== Manipulation de fichiers ==
=== Importer le contenu d'un fichier ===
Python possède la fonction <code lang="python">open()</code> qui permet d'ouvrir un fichier. Ouvrir signifie qu'il crée un objet de type <code>file</code> qui possède notamment les méthodes <code lang="python">.read()</code> et <code lang="python">.write()</code>. Il peut s'agir d'un objet de type « fichier binaire » ''({{lang|en|binary file}})'' ou « fichier texte » ''({{lang|en|text file}})''.
Si par exemple on veut utiliser (et donc lire) le contenu du fichier texte <code>monfichier.txt</code>, on écrit :
<syntaxhighlight lang="python">
fichier = open("monfichier.txt", "rt")
…
fichier.close()
</syntaxhighlight>
Le paramètre <code>"rt"</code> signifie que nous ouvrons le fichier en lecture ''({{lang|en|read}})'' et qu'il s'agit d'un objet de type fichier texte.
Notons deux choses :
* en faisant cela, nous ne faisons qu'associer le fichier à un objet Python, nous n'avons pas encore importé les données ;
* si nous ouvrons le fichier, il faut le fermer par la suite ; c'est pourquoi nous utilisons la méthode <code lang="python">.close()</code>.
Pour éviter d'avoir à fermer le fichier, nous pouvons l'ouvrir au sein d'un contexte :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
…
</syntaxhighlight>
Notons aussi que la chaîne de caractères indiquant le nom du fichier peut contenir le chemin d'accès au répertoire (dossier), mais sous Microsoft Windows, il faut utiliser des barres de fractions <code>/</code> pour séparer les sous-répertoires au lieu de la barre inversée habituelle, par exemple :
<syntaxhighlight lang="python">
chemin = "C:/Temp/monfichier.txt"
with open(chemin, "rt") as fichier:
…
</syntaxhighlight>
Pour mettre les données du fichier dans la variable <code>contenu</code>, nous écrivons donc :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.read()
print(contenu)
</syntaxhighlight>
et si nous ne voulons lire que les <code>n</code> premiers caractères (<code>n</code> étant un entier), nous utilisons <code lang="python">contenu = fichier.read(n)</code>. Cette lecture est séquentielle, c'est-à-dire que si nous appliquons la méthode plusieurs fois, nous reprenons la lecture là où nous l'avons laissée.
Si nous voulons lire une ligne, nous utilisons la méthode <code lang="python">.readline()</code>. La lecture ligne par ligne est également séquentielle. Nous pouvons aussi créer une liste dont chaque élément est une ligne du fichier ; nous utilisons alors la méthode <code lang="python">.readlines()</code> (notez le pluriel).
Chaque élément de la liste se termine par le caractère de fin de ligne <code lang="python">\n</code>. Pour l'enlever, nous pouvons utiliser la méthode <code lang="python">.rstrip()</code> pour chaque élément de la liste, par exemple. L'exemple complet est alors :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.readlines()
contenu = [item.rstrip() for item in contenu]
print(contenu)
</syntaxhighlight>
=== Importation avec NumPy ===
Les commandes <code>open</code> et <code>.read()</code> sont générales à Python. NumPy propose une fonction, <code>np.genfromtxt()</code>, qui sert à transformer du un fichier texte en matrice <code>ndarray</code>. Typiquement, pour un fichier CSV, on écrit :
<syntaxhighlight lang="python">
matrice = np.genfromtxt(r"emplacement/fichier.csv", delimiter=",")
</syntaxhighlight>
Cette fonction dispose de plusieurs paramètres, dont :
* <code>comments</code> : caractère, ou chaîne de caractères, introduisant un commentaire (à e pas prendre en compte), typiquement <code>comments="%"</comments>, <code>comments="#"</comments>, <code>comments="\\"</comments>…
* <code>skip_header</code> : nombre de ligne à ne pas prendre en compte en début de fichier, typiquement celles qui contiennent l'en-tête ;
* <code>skip_footer</code> : nombre de ligne à ne pas prendre en compte en fin de fichier ;
* <code>usecols</code> : n-uplet des colonnes à lire, les autres étant à ignorer ;
* <code>names</code> ; si on met <code>names = True</code>, alors la première ligne lue (après les lignes sautées par <code>skip_header</code>) sert à créer les nom d'une matrice structurée ''({{lang|en|structures array}})''.
La fonction <code>np.loadtxt()</code> fait la même chose que <code>np.genfromtxt()</code> mais avec moins d eparamètres.
{{voir|https://numpy.org/doc/stable/user/basics.io.genfromtxt.html}}
=== Exporter du contenu vers un fichier ===
Si nous voulons créer un fichier texte <code>monfichier.txt</code> pour y mettre le contenu de la variable <code>texte</code>, alors nous utilisons :
<syntaxhighlight lang="python">
with open("monfichier.txt", "wt") as fichier:
fichier.write(texte)
</syntaxhighlight>
Le module principal important pour la manipulation de fichiers est est <code lang="python">os</code>.
=== Exploiter le contenu d'un fichier texte ===
Avec un fichier texte, la méthode <code lang="python">.read()</code> crée une variable de type texte. Nous pouvons séparer cette variable en différentes lignes avec la méthode <code lang="python">.splitlines()</code>. Cela crée une liste de chaînes de caractères, chaque chaîne étant une ligne.
Si maintenant une ligne contient plusieurs données séparées par un séparateur commun, par exemple un espace, nous pouvons séparer les données par la méthode <code lang="python">.split(''séparateur'')</code>. Cela crée une liste de chaînes de caractères, chaque chaîne étant une donnée.
Si par exemple le fichier est du type CSV ''({{lang|en|comma separated values}}'', valeurs séparées par une virgule), l'exploitation du fichier est :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.read()
contenu = contenu.splitlines()
contenu = [item.split(",") for item in contenu]
</syntaxhighlight>
La variable <code>contenu</code> est une liste de listes. Pour avoir la ''n''<sup>e</sup> valeurs de la ''m''<sup>e</sup> ligne, on utilise :
<syntaxhighlight lang="python">
contenu[m-1][n-1]
</syntaxhighlight>
Si l'on veut extraire la ligne ''m'' il suffit d'écrire :
<syntaxhighlight lang="python">
contenu[m-1]
</syntaxhighlight>
mais si l'on veut la colonne ''n'', le plus simple est d'utiliser une définition en compréhension :
<syntaxhighlight lang="python">
[ligne[n-1] for ligne in contenu]
</syntaxhighlight>
Dans certains fichiers CSV, les séparateurs de valeurs ne sont pas des virgules, on peut donc utiliser un autre caractère pour le séparateur. Concernant les séparateurs particuliers :
* si le séparateur est une tabulation, on utilise <code lang="python">\t</code> : <code lang="python">contenu = [item.split("\t") for item in contenu]</code> ;
* si le séparateur est un nombre arbitraire d'espaces et/ou de tabulation, on ne définit aucun séparateur : <code lang="python">contenu = [item.split() for item in contenu]</code>.
Si la première ligne contient les en-têtes des colonnes, on peut l'enlever avec la fonction <code lang="python">del()</code> :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.read()
contenu = contenu.splitlines()
del(contenu[0])
contenu = [item.split(",") for item in contenu]
</syntaxhighlight>
Certains logiciels créent des fichiers en utilisant le séparateur décimal régional, qui en France est la virgule. Pour remplacer les virgules par des points, on peut utiliser la méthode <code lang="python">.replace()</code>, de préférence ''avant'' de séparer les valeurs :
<syntaxhighlight lang="python">
contenu = contenu.splitlines()
contenu = [item.replace(",", ".") for item in contenu] # remplace les virgules par des points
contenu = [item.split(";") for item in contenu] # si le séparateur est un point-virgule
</syntaxhighlight>
en effet, lorsque l'on a séparé les valeurs, on a une liste de liste, il faut alors balayer les sous-listes ce qui prend plus de temps :
<syntaxhighlight lang="python">
contenu = contenu.splitlines()
contenu = [item.split(";") for item in contenu] # si le séparateur est un point-virgule
contenu = [[subitem.replace(",", ".") for subitem in item] for item in contenu] # remplace les virgules par des points
</syntaxhighlight>
'''Exemple complet'''
Supposons que l'on ait un fichier texte de la forme :
<syntaxhighlight lang="text">
x y z V
0.0 1.5 3.2 8.657
0.4 1.5 3.2 8.392
0.2 1.5 3.2 8.485
...
</syntaxhighlight>
C'est un fichier valeurs V associées à des points de coordonnées ''(x, y, z)'' (un champ V sur l'espace, donc). Nous remarquons que seule la coordonnée ''x'' change : les données concernent la droite (''y'' = 1,5 ; ''z'' = 3,2). Nous remarquons aussi que les valeurs de ''x'' ne sont pas classées par ordre croissant ni décroissant.
Nous voulons au final avoir une matrice [[''x''], [V]] triée par ''x'' croissant. Pour cela, nous pouvons faire :
<syntaxhighlight lang="python">
with open(nomdefichier, "rt") ad fichier:
contenu = fichier.read()
contenu = contenu.splitlines()
contenu = [item.split(" ") for item in contenu
contenu = contenu[1:] # élimine la première ligne
x = np.array([float(ligne[0]) for ligne in contenu])
V = np.array([float(ligne[3]) for ligne in contenu])
donnees = np.concatenate((x.reshape(-1, 1), V.reshape(-1, 1)), axis=1) # matrice [[x], [V]]
ind = np.argsort(donnees[:, 0])
donnees = donnees[ind, :] # matrice triée
plt.plot(donnees[:, 0], donnees[:, 1])
</syntaxhighlight>
{{note|Pour le tri, voir [[../Manipulation_de_matrices#Fonctions_et_méthodes_de_base|''Manipulation de matrices'' > ''Fonctions et méthodes de base'']].}}
=== Cas d'un fichier CSV ===
Si le fichier CSV ne contient que des valeurs numériques, on peut utiliser :
<syntaxhighlight lang="python">
valeurs = np.loadtxt(chemin+nomfic, delimiter=",") # si le séparateur est une virgule
</syntaxhighlight>
Il existe un module <code lang="python">csv</code> dédié aux fichiers CSV. La manipulation du fichier se fait comme suit :
<syntaxhighlight lang="python">
import csv
with open(chemin+nomfic, "rt") as fichier:
lecteur = csv.reader(fichier, delimiter=",")
contenu = [ligne for ligne in lecteur]
print(contenu)
</syntaxhighlight>
=== Utilisation de Pandas ===
Pandas<ref>https://pandas.pydata.org/</ref> est un module gérant les tableaux de données, appelés <em lang="en">data frames</em>. Voici quelques commandes utiles :
<syntaxhighlight lang="python">
import numpy as np
import pandas as pd
M = np.random.rand(10, 10) # crée une matrice NumPy aléatoire de dimension 10 × 10
tableau = pd.DataFrame(M) # transforme la matrice en tableau DataFrame
tableau.to_csv("tableau.csv") # enregistre le tableau dans un fichier CSV
donnees = pd.read_csv("tableau.csv").to_numpy() # lit le fichier et transforme le tableau DataFrame en matrice NumPy
</syntaxhighlight>
Si on ne veut pas d'entête lorsque l'on écrit le fichier CSV, on ajoute l'attribut <code>header = False</code> :
<syntaxhighlight lang="python">
tableau.to_csv("tableau.csv", header = False) # enregistre le tableau dans un fichier CSV sans entête
donnees = pd.read_csv("tableau.csv").to_numpy() # lit le fichier et transforme le tableau DataFrame en matrice NumPy
</syntaxhighlight>
Par défaut, la fonction <code>pd.read_csv()</code> considère que le séparateur est une virgule, et la commande <code>pd.read_table()</code> que c'est une tabulation. On peut définir le séparateur avec le paramètre <code>sep</code> :
<syntaxhighlight lang="python">
donnees = pd.read_csv("tableau.csv", sep=";")
</syntaxhighlight>
On peut utiliser les séparateurs spéciaux :
* <code>\t</code> : tabulation ;
* <code>\s+</code> : nombre arbitraire d'espaces.
On peut par ailleurs utiliser les paramètres suivants :
* <code>dialect</code> : syntaxe du fichier, par exemple <code>dialect = "excel"</code> ;
* <code>nrows</code> (entier) : nombre de lignes lues ;
* <code>skiprows</code> (entier) : nombre de lignes sautées (non lues) en début de fichier ;
* <code>header</code> (entier) : numéro de ligne utilisé pour l'en-tête, par exemple <code>header = 0</code> pour la première ligne ;
* <code>skip_blank_lines</code> (booléen) : si la valeur est vraie (<code>True</code>), ne lit pas les lignes vide ; sinon, met une valeur <code>nan</code>.
Par exemple :
<syntaxhighlight lang="python">
donnees1 = pd.read_csv("tableau.csv", nrows=1, sep="\s+").to_numpy()
donnees2 = pd.read_csv("tableau.csv", skiprows=3, sep="\s+").to_numpy()
</syntaxhighlight>
{{voir|{{lien web |url=https://pandas.pydata.org/docs/user_guide/io.html |titre=IO tools (text, CSV, HDF5, …) |site=Pandas |consulté le=2026-05-06}} }}
== Exporter un programme Python ==
Vous pouvez créer un fichier « Python pur » <code>.py</code>. Pour cela, dans le menu <code>fichier/file</code> de Jupyter, choisir <code>télécharger/download</code> au format <code>.py</code> ; le fichier se trouve alors dans le répertoire de téléchargement du navigateur.
== Recommandations ==
Les recommandations de programmation sont générales et ne sont en grande partie pas spécifiques à Python.
{{voir|[[Découvrir_Scilab/Programmation#Recommandations]]}}
== Ressources ==
* {{lien web
| url = https://www.python.org/dev/peps/pep-0008/
| titre = PEP 8 -- Style Guide for Python Code
| site = Python documentation
| consulté le = 2019-03-14
}}
== Notes et références ==
{{références}}
----
[[../Fonctions mathématiques générales|Fonctions mathématiques générales]] < [[../|↑]] > [[../Graphiques|Graphiques]]
{{DEFAULTSORT:Elements de programmation}}
[[Catégorie:Python pour le calcul scientifique (livre)]]
p1zpv70h3t80a898406qhckzautw3i4
769321
769320
2026-07-03T09:42:52Z
Cdang
1202
/* Importation avec NumPy */ typo
769321
wikitext
text/x-wiki
Rappel : les programmes commencent par :
<syntaxhighlight lang="python">
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as plt
</syntaxhighlight>
== Entrées et sorties ==
Pour permettre à l'utilisateur ou à l'utilisatrice d'entrer une valeur, nous utilisons la fonction <code lang="python">input()</code> comme évoqué précédemment (chapitre ''[[../Premiers programmes|Premiers programmes]]''), avec la syntaxe <code lang="python">''variable'' = input(''texte'')</code>. Notez que la valeur renvoyée par <code lang="python">input()</code> est une chaîne de caractères. Si vous voulez autre chose, typiquement un nombre, il faut convertir cette chaîne.
Par exemple, nous demandons ici d'entrer une longueur sous la forme d'une valeur numérique :
<syntaxhighlight lang="python">
longueurDefaut = 10.0
texteDemandeLongueur = f"Veuillez entrer la longueur en millimètres (valeur par défaut {longueurDefaut} mm) : "
longueur = input(texteDemandeLongueur)
if longueur=="":
longueur=longueurDefaut
else:
longueur=float(longueur)
print(longueur)
</syntaxhighlight>
{{voir|https://docs.python.org/3/library/functions.html#input}}
Pour afficher un texte, on utilise la fonction <code lang="python">print()</code>, également présentée dans le chapitre ''[[../Premiers programmes|Premiers programmes]]'', avec la syntaxe <code lang="python">print(''texte'')</code>. Le texte à afficher peut être de n'importe quel type (entier, réel en virgule flottante, booléen, chaîne de caractères…). On peut « mélanger » les types en les séparant par des virgules, par exemple
<syntaxhighlight lang="python">
print("La longueur vaut : ", longueur, " mm.")
</syntaxhighlight>
ou bien
<syntaxhighlight lang="python">
print("Essai de mélange ", 1, True, 10.0, " insensé.")
</syntaxhighlight>
Mais si l'on veut faire ça de manière harmonieuse, on a intérêt à tout convertir en chaînes de caractères, avec la fonction <code lang="python">str()</code>, et concaténer les chaînes avec <code lang="python">+</code>.
Par exemple :
<syntaxhighlight lang="python">
print("La longueur vaut : "+str(longueur)+" mm.")
</syntaxhighlight>
Nous pouvons aussi utiliser une « chaîne “f” » ''({{lang|en|f-string}})'' : on met un le <code lang="python">f</code> devant le guillemet ouvrant et dans la chaîne, on met un champ sous la forme <code lang="python">{''nomDeVariable''}</code>. L'exemple ci-dessus devient alors :
<syntaxhighlight lang="python">
print(f"La longueur vaut : {longueur} mm.")
</syntaxhighlight>
Les chaînes « f » sont détaillées dans la section ''[[#Chaînes de caractères|Chaînes de caractères]]'' ci-dessous.
Si l'on veut introduire un retour à la ligne dans la chaîne, on utilise les caractères <code lang="python">\n</code> (contre-oblique suivie de la lettre N minuscule). Par exemple
<syntaxhighlight lang="python">
print("Ceci est un texte\navec un retour à la ligne.")
</syntaxhighlight>
La commande <code>print()</code> admet les paramètres suivants (nous indiquons la valeur par défaut= :
* <code>end = "\n"</code> : détermine la fin de ligne ; on peut mettre <code>end = ""</code> si l'on ne veut pas de retour de ligne, ou bien <code>end = "\r"</code> ''({{lang|en|return}})'' si l'on veut revenir au début de la ligne pou repasser par-dessus ;
* <code>sep = " "</code> : séparateur des différents objets.
{{voir|https://docs.python.org/3/library/functions.html#print}}
Si vous voulez passer un argument directement au script Python, vous pouvez utiliser le module <code>sys</code>. L'argument est alors contenu dans la variable <code>sys.argv[1]</code> ; la variable <code>sys.argv[0]</code> contient le nom du scirpt lui-même. Par exemple
<syntaxhighlight lang="python">
import sys
print("Script : ", sys.argv[0])
print("Entrée : ", sys.argv[1])
</syntaxhighlight>
Si vous exécutez le script depuis une console (fenêtre de commande), le nom du fichier de script étant <code>monscript.py</code> :
<syntaxhighlight lang="text">
$ python monscript.py blabla
Script : monscript.py
Entrée : blabla
$_
</syntaxhighlight>
== Types de variables ==
=== Généralités ===
Python définit « tout seul » le type de la variable : « <code>3</code> » sera un entier ''({{lang|en|integer}})'', « <code>3.0</code> » sera un réel à virgule flottante ''({{lang|en|float}})'', « <code>"3"</code> » sera une chaîne de caractères ''({{lang|en|string}})''.
On peut connaître le type d'une variable avec la fonction <code>type()</code>.
On peut tester certaines valeurs, avec le module <code>NumPy</code> :
* <code>np.isnan(x)</code> indique si les valeurs de ''x'' sont des NaN ''({{lang|en|not a number}})'' ; si ''x'' est une matrice, le résultat est une matrice de booléens, l'élément [''i'', ''j''] est <code>True</code> si <code>x[i, j]</code> est un NaN ;
* <code>np.isinf(x)</code> indique si les valeurs de ''x'' sont ±∞ ; si ''x'' est une matrice, le résultat est une matrice booléenne de même dimension.
On peut forcer un type :
* <code>int(x)</code> : transforme la valeur ''x'' en nombre entier ;
* <code>long(x)</code> : " en entier long (précision illimitée) ;
* <code>float(x)</code> : " en nombre réel à virgule flottante ;
* <code>str(x)</code> : " en chaîne de caractères ;
* <code>complex(Re, Im)</code> : crée le nombre complexe ''Re'' + ''Im''·j, j désignant la racine carrée de –1 ;
* <code>list()</code> : crée une liste ;
* <code>tuple()</code> : crée un n-uplet.
Par exemple
<syntaxhighlight lang="python">
type(3) # <class 'int'>
type(float(3)) # <class 'float'>
complex(1, 1) == 1 + 1j # True
list("blabla") # ['b', 'l', 'a', 'b', 'l', 'a']
</syntaxhighlight>
Python distingue plusieurs genres de types :
* Un itérable est un objet dont on peut extraire les éléments un par un ; ce sont les objets pour lesquels on peut écrire <code> for i in ''iterable'':</code>. Il s'agit essentiellement des listes, n-uplets, chaînes de caractères, ensembles, dictionnaires et fichiers.
* Un modifiable ''({{lang|en|mutable}})'' est un objet que l'on peut modifier ; par exemple une liste est modifiable — on peut changer la valeur d'un élément, en ajouter ou en enlever un — mais les n-uplets non, pas plus qu'une chaîne de caractères ou un nombre.
* Un identifiable (''{{lang|en|hashable}}'', le ''{{lang|en|hashage}}'' étant une signature caractéristique d'un objet) : objet possédant un identifiant unique. Un objet identifiable est toujours non-modifiable ''({{lang|en|unmutable}})''.
=== Types numériques ===
==== Entiers ====
Nous pouvons définir les entiers au format octal ou hexadécimal : il faut débuter le nombre par respectivement <code>0o</code> (le chiffre zéro et la lettre o) et <code>0x</code> (le chiffre zéro et la lettre x). À l'inverse, la fonction <code>hex()</code> renvoie une chaîne correspondant à l'écriture d'un entier au format hexadécimal, et <code>oct()</code> renvoie la chaîne correspondant à l'éciture en octal. Par exemple :
<syntaxhighlight lang="python">
print(0o10, ";", 0x10)
# 8 ; 16
print(hex(20))
# 0x14
</syntaxhighlight>
==== Réels ====
Les réels disposent de fonctions spécifiques appelées « méthodes ».
Une méthode est une fonction spécifique à un type d'objets. Étant conçue ''ad hoc'', elle est souvent plus économe en ressource et en temps qu'une fonction générique. Pour appliquer la méthode <code>meth()</code> à la variable <code>x</code>, on écrit : <code>x.meth()</code>.
Nous avons déjà présenté la méthode <code>''float''.as_integer_ratio()</code> qui donne la fraction réduite égale à la valeur du nombre. Les réels disposent de plusieurs autres méthodes :
* <code>''float''.is_integer()</code> : indique si le nombre est un entier (<code>true</code> dans ce cas-là, <code>False</code> sinon) ;
* <code>''float''.from_number(''x'')</code> : transforme le nombre ''x'' en un réel (permet de convertir un entier en réel) ;
* <code>''float''.hex()</code> : renvoie une chaîne de caractères correspondant à l'écriture du nombre en hexadécimal ;
* <code>''float''.fromhex(''c'')</code> : transforme une chaîne de caractères, correspondant à l'écriture d'un nombre en hexadécimal, en un nombre réel correspondant.
Par exemple :
<syntaxhighlight lang="python">
a = 20.
print(a.hex())
# 0x1.4000000000000p+4
print(10..hex())
# 0x1.4000000000000p+3
</syntaxhighlight>
Dans le deuxième exemple, nous appliquons la méthode <code>''float''.hex()</code> directement au nombre <code>10.</code> ; le point est obligatoire car sinon, c'est un entier, pour lequel la méthode n'est pas définie. On aurait pu aussi écrire <code>print(10.0.hex())</code>.
Notez que la ''méthode'' <code>''float''.hex()</code> est différentes de la ''fonction'' <code>hex()</code> : la première concerne les réels, la seconde les entiers.
==== Complexes ====
Nous avons déjà mentionné la méthode <code>''complex''.conjugate()</code> qui donne le conjugué du nombre.
Un nombre complexe dispose de deux attributs :
* <code>''complex''.real</code> : sa partie réelle ;
* <code> ''complex''.imag</code> : sa partie imaginaire.
Par exemple :
<syntaxhighlight lang = "python">
a = 5+2j
print(a.conjugate(), ";", a.real, ";", a.imag)
# (5-2j) ; 5.0 ; 2.0
</syntaxhighlight>
=== Chaînes de caractères ===
; Ressources
: {{lien web
| url = https://docs.python.org/3/tutorial/inputoutput.html
| titre = 7. Input and Output
| site = Python Documentation
| consulté le = 2019-04-06
}}
: {{lien web
| url = https://docs.python.org/3/library/string.html
| titre = <code>string</code> — Common string operations
| site = Python Documentation
| consulté le = 2026-06-05
}}
==== Généralités ====
Il existe en fait trois manières de définir une chaîne de caractères :
* avec des guillemets simples ou doubles comme vu précédemment : <code>"…"</code> ou bien <code>'…'</code> ;
* avec trois guillemets doubles : <code>"""…"""</code> : cela permet d'avoir une chaîne de caractères s'étendant sur plusieurs lignes, les retours de ligne étant pris en compte ; c'est utilisé en particulier pour la description des fonctions (''{{lang|en|docstrings}}'', voir ci-après) ;
* avec des guillemets précédés d'un « r », <code>r"…"</code> ou <code>r'…'</code> : cela permet d'interpréter les barres de fraction inverses « \ » comme un caractère « normal » et non comme un caractère d'échappement (voir ci-après) ; cela est utile lorsque l'on utilise les possibilités LaTeX dans le tracé de graphiques (voir plus loin) ;
* avec des guillemets précédés d'un « f », <code>f"…"</code> ou <code>f'…'</code> : cela permet d'utiliser des variables formatées (voir ci-après).
Une chaîne de caractères n'est pas modifiable. Si l'on veut remplacer un caractère, l'insérer ou le supprimer, il faut transformer la chaîne en liste, avec la commande <code>list()</code>, puis rassembler la liste en la joignant ''({{lang|en|join}})'' à une chaîne vide :
<syntaxhighlight lang="python">
chaine = "blabla"
chaineList = list(chaine)
chaineList[2] = "c"
chaine = "".join(chaineList)
print(chaine) # blcbla
</syntaxhighlight>
Dans une chaîne simple <code>"…"</code> ou <code>'…'</code>, on peut introduire un retour à la ligne avec <code>\n</code>.
Chaque caractère possède un code ''({{lang|en|code point}})'' définit par la norme Unicode ''({{lang|en|Unicode code point}})''. Pour afficher le caractère correspondant à un code, on utilise <code>chr()</code>. Pour afficher le code correspondant à un caractère, on utilise <code>ord()</code>
<syntaxhighlight lang="python">
print(ord("a")) # 97
print(hex(ord("a"))) # 0x61
print(chr(97)) # a
print(chr(0x61)) # a
</syntaxhighlight>
==== Substitution de variables ====
Lorsque l'on veut utiliser des variables, on fait précéder les guillemets d'un « f » et l'on écrit les noms de variables entre accolades ; on parle de « chaîne f » ''(f-string)''. Par exemple :
<syntaxhighlight lang="python">
monde = "world"
chaine = f"Hello {monde}!"
print(chaine) # Hello world!
</syntaxhighlight>
On peut indiquer la taille de la chaîne générée à partir de la variable sous la forme <code>{nomVariable:taille}</code>, la taille étant un entier. Par exemple :
<syntaxhighlight lang="python">
chiffre1 = 1
nom1 = "un"
chiffre2 = 2
nom2 = "deux"
chaine = f"{nom1:5} : {chiffre1:5d}\n{nom2:5} : {chiffre2:5d}"
print(chaine)
# un : 1
# deux : 2
</syntaxhighlight>
Vous remarquez que l'on ajoute un « d » pour les entiers décimaux, et que les nombres sont alignés à droite. Si le nombre est un nombre réel à virgule flottante ''({{lang|en|float}})'', on peut indiquer le nombre de décimales sous la forme <code>.''n''f</code> :
<syntaxhighlight lang="python">
chaine = f"{np.pi:.5f}"
print(chaine)
# 3.15169
</syntaxhighlight>
Avec la syntaxe <code>''m''.''n''f</code>, on indique également que la totalité du nombre doit occuper ''m'' caractères.
Pour un nombre en notation scientifique (exponentielle), on utilise <code>.''n''e</code>.
Pour convertir un nombre en caractère Unicode correspondant, on utilise la lettre c :
<syntaxhighlight lang="python">
nompi = 0x03c0 # Caractère Unicode π : U+03C0
chaine = f"{nompi:c} = {np.pi:.5f}"
print(chaine)
# π = 3.14159
</syntaxhighlight>
Notez que dans le cas de nombres, la mise en forme marche aussi si l'on écrit directement le nombre dans l'accolade (au lieu d'une variable).
Le tiret de soulignement « <code>_</code> » (''underscore'', tiret du 8) permet de séparer les chiffres avant le séparateur décimal par groupe de trois chiffres séparés du tiret ; la virgule « <code>,</code> » les sépare d'une virgule.
<syntaxhighlight lang="python">
print(f"{1e6:_}, {1e6:,}")
# 1_000_000.0, 1,000,000.0
</syntaxhighlight>
La classe ''str'' dispose également de la méthode <code>.format()</code>. On indique un n-uplet de chaînes (ou de nombres) à la méthode et l'on met des accolades dans la chaîne principale ; les accolades sont remplacées dans l'ordre des chaînes de la méthode. On peut changer l'ordre en indiquant quelle valeur utiliser dans quelle accolade. Par exemple :
<syntaxhighlight lang="python">
chaine1 = "On compte {} puis {}".format(1, 2)
chaine2 = "On compte {0} puis {1}. Mais à rebours, on compte {1} puis {0}.".format("un", "deux")
print(chaine1, "\n", chaine2)
# On compte 1 puis 2
# On compte un puis deux. Mais à rebours, on compte deux puis un.
</syntaxhighlight>
L'utilisation du caractère pourcent « % » permet d'utiliser la mise en forme <code>sprintf()</code> du langage C :
<syntaxhighlight lang="python">
chaine = "π = %.5f" % np.pi
print(chaine)
# π = 3.14159
</syntaxhighlight>
; Exemple <nowiki>:</nowikI> barre de progression
: Voici une fonction affichant une barre de progression, pour la ''i''-ème étape d'un processus ayant ''n'' étapes (pour la notion de fonction, voir la section ci-après ''[[#Fonction|Fonction]]'').
: NB : nous avons utilisé les codes Unicode pour l'exemple, mais on peut évidemment copier le caractère, par exemple depuis une table Unicode ou une page Web<ref>Pour le point médian : ''{{W|Table des caractères Unicode/U0080}}'' ou ''{{W|Point médian}}''. Pour le pavé : ''{{W|Table des caractères Unicode/U2580}}''.</ref>, et le coller dans le code, comme nous l'avons fait dans le commentaire.
<syntaxhighlight lang="Python">
def barre_progression(i, n, largeur=40):
""" Affiche une barre de progression
Entrées :
— i : étape en cours, entier ;
— n : nombre d'étapes à réaliser, entier ;
— largeur : nombre de caractères total de la barre, entier.
Sortie : affichage de la barre de progression.
"""
taux = i/n
fait = int(largeur * taux)
barre = f"{0x2588:c}" * fait + f"{0x00b7:c}" * (largeur - fait) # U+2588 : pavé "█" ; U+00B7 : point médian "·"
print(f"Progression | {barre} | {100*taux:3.1f} %", end="\r")
barre_progression(25, 100)
# Progression | ██████████······························ | 25.0 %
</syntaxhighlight>
==== Méthodes des chaînes ====
Le type ''str'' dispose d'un certain nombre de méthodes. Nous avons déjà vu les méthodes <code>''str''.join()</code> et <code>''str''.format()</code>, en voici quelques autres :
* <code>''str''.capitalize()</code> : met le premier caractère en capitale (majuscule) et les autres en minuscule ;
* <code>''str''.lower()</code> : met tout en minuscules ''({{lang|en|lowercase}})'' ;
* <code>''str''.upper()</code> : met tout en capitales ''({{lang|en|lowercase}})'' ;
* <code>''str''.center(''n'')</code> : met la chaîne au centre d'une chaîne de longueur ''n'', en complétant avec des espaces ; on peut compléter avec d'autres caractères avec <code>''str''.center(''n'', ''c'')</code>, par exemple <code>"a".center(7, ".")</code> donne <code>"....a...."</code> ;
* <code>''str''.ljust(''n'', ''c'')</code> et <code>''str''.rjust(''n'', ''c'')</code> : comme <code>.center()</code> mais la chaîne est respectivement alignée au fer à gauche ''({{lang|en|left}})'' et à droite ''({{lang|en|right}})'' ;
* <code>''str''.isdigit()</code> : booléen vrai si tous les caractères sont des nombres ;
* <code>''str''.find(''sous-chaine'')</code>, <code>''str''.rfind(''sous-chaine'')</code> : indique respectivement le premier emplacement et le dernier emplacement de la sous-chaîne dans la chaîne, ou bien <code>-1</code> si la sous-chaîne est absente ;
* <code>''str''.partition(''séparateur'')</code> : retourne un triplet avec la portion de chaîne avant le séparateur, le séparateur puis la portion de chaîne après le séparateur ;
* <code>''str''.replace(''ancien'', ''nouveau'')</code> : remplace la chaîne ''ancien'' par la chaîne ''nouveau'' dans la chaîne ;
* <code>''str''.split(''séparateur'')</code> : découpe la chaîne au niveau des séparateurs et renvoie une liste.
==== Autres fonctions ====
La fonction <code>chr()</code> transforme un code Unicode en caractère. Par exemple, <code>chr(97)</code> donne <code>"a"</code> et <code>chr(0x03c0)</code> donne <code>"π"</code>.
Si on veut créer une liste de caractères qui se suivent, on peut par exemple utiliser :
<syntaxhighlight lang="python">
[chr(x) for x in range(97, 102)]
# ['a', 'b', 'c', 'd', 'e']
</syntaxhighlight>
Si on veut créer une liste de nombres sous la forme de chaînes de caractères, on peut utiliser la commande <code>str()</code> vue ci-dessus. Par exemple :
<syntaxhighlight lang="python">
[str(x) for x in range(1, 6)]
# ['1', '2', '3', '4', '5']
</syntaxhighlight>
Pour la syntaxe, voir ci-dessous la section [[#Définition en compréhension|''Définition en compréhension'']].
Ainsi, dans l'exemple de la barre de progression ci-dessus, on peut utiliser la solution suivante pour constituer la barre :
<syntaxhighlight lang="python">
barre = chr(0x2588) * fait + chr(0x00b7) * (largeur - fait) # U+2588 : bloc ; U+00B7 : point médian
</syntaxhighlight>
Rappel : le module <code>html</code> permet d'utiliser les entités HTML :
<syntaxhighlight lang="python">
import html
…
print(html.entities.html5["alpha;"]+html.entities.html5["middot;"])
# α·
</syntaxhighlight>
L'entité HTML <code>&xxx;</code> s'obtient par <code>html.entities.html5["xxx;"]</code>, donc en enlevant la perluète ; mais cela ne fonctionne pas avec les codes Unicode. Pour cela, on peut utiliser la commande <code>html.unescape()</code>. Ainsi, dans l'exemple de la barre de progression ci-dessus, on peut utiliser la solution suivante pour constituer la barre :
<syntaxhighlight lang="python">
barre = html.unescape("█") * fait + html.entities.html5["middot;"] * (largeur - fait) # U+2588 : bloc ; middot : point médian
</syntaxhighlight>
ou bien
<syntaxhighlight lang="python">
barre = barre = html.unescape("█" * fait + "·" * (largeur - fait)) # U+2588 : bloc ; middot : point médian
</syntaxhighlight>
La commande <code>html.unescape()</code> interprète donc une chaîne complète, par exemple
<syntaxhighlight lang="python">
print(html.unescape("L'esperluette est le caractère « & »."))
# L'esperluette est le caractère « & ».
</syntaxhighlight>
== Manipulation de listes ==
Les listes sont une structure de données fondamentale en Python.
; Ressources
* {{lien web
| url = https://docs.python.org/3/tutorial/datastructures.html
| langue = en
| titre = 5. Data structures
| site = Python documentation
| consulté le = 2019-03-16
}}
=== Copie d'une liste ===
Contrairement à d'autres types, lorsque vos écrivez <code>b = a</code> avec des listes, vous ne créez pas une copie de la variable <code>a</code>, vous créez un ''alias'' : l'objet <code>b</code> est un autre nom de l'objet <code>a</code>. En particulier, si vous modifiez <code>b</code>, vous modifiez en fait <code>a</code>. Par exemple :
<syntaxhighlight lang="python">
a = [1, 2, 3, 4]
b = a
b[2] = 5
print(a, b) # [1, 2, 5, 4] [1, 2, 5, 4]
</syntaxhighlight>
Si l'on veut créer une copie de <code>a</code>, il faut utiliser <code>a[:]</code> ou bien <code>a.copy()</code> :
<syntaxhighlight lang="python">
a = [1, 2, 3, 4]
b = a[:]
c = a.copy()
b[2] = 5
c[2] = 6
print(a, b, c) # [1, 2, 3, 4] [1, 2, 5, 4] [1, 2, 6, 4]
</syntaxhighlight>
=== Méthodes de listes ===
Pour modifier une liste, vous disposez des méthodes suivantes :
* <code>a.append(x)</code> : ajoute l'élément <code>x</code> à la fin de la liste <code>a</code> ;
* <code>a.extend(x)</code> : ajoute la liste <code>x</code> à la fin de la liste <code>a</code> ;
* <code>a.append(i, x)</code> : aoute l'élément <code>x</code> ''avant'' l'interstice ''i'' de la liste <code>a</code> ;
* <code> x = a.pop(i)</code> : enlève l'élément ''i'' de la liste <code>a</code> et le met dans la variable <code>x</code> ; <code> x = a.pop()</code> enlève le dernier élément de la liste ;
* <code>a.clear()</code> : vide la liste <code>a</code> ;
* <code>a.sort()</code> : trie la liste par ordre croissant ;
* <code>a.sort(reverse = True)</code> : trie par ordre décroissant ;
* <code>a.reverse()</code> : inverse l'ordre de <code>a</code>.
Pour supprimer l'élément à l'indice ''i'', au lieu d'utiliser <code>a.pop(i)</code>, on peut aussi utiliser
<syntaxhighlight lang="python">
del(a[i])
</syntaxhighlight>
Pour trier une liste, on peut aussi utiliser la fonction <code>sorted()</code>, ce qui permet par exemple de conserver la liste originale, non triée : <code>b = sorted(a)</code>. La fonction <code>sorted()</code> fonctionne avec tous les objets « itérables » comme par exemple une chaîne de caractères :
<syntaxhighlight lang="python">
a = "ahjbfk"
print(sorted(a)) # ['a', 'b', 'f', 'h', 'j', 'k']
</syntaxhighlight>
Pour mettre en évidence la performance de la méthode <code>''list''.sort()</code> par rapport à la fonction générique <code>sorted()</code> :
<syntaxhighlight lang="python">
import numpy as np
import time
a = np.random.rand(int(1e7))
t1 = time.perf_counter()
b = sorted(a) # Fonction générique
t2 = time.perf_counter()
a.sort() # Méthode spécifique
t3 = time.perf_counter()
print("Sorted :", t2-t1, " s ; .sort :", t3-t2, "s ; rapport :", (t2-t1)/(t3-t2))
# Sorted : 14.2... s ; .sort : 1.1... s ; rapport : 12.6...
</syntaxhighlight>
Par rapport à une valeur donnée :
* <code>a.remove(x)</code> : retire la première occurrence de la valeur <code>x</code> de la liste <code>a</code> ;
* <code>a.index(x)</code> : indique l'indice où se trouve la première occurrence de la valeur <code>x</code> ;
* <code>a.count(x)</code> : indique le nombre de fois que l'on trouve la valeur <code>x</code> dans la liste <code>a</code>.
=== Définition en compréhension ===
La [[w:fr:Liste en compréhension|définition en compréhension]] ''({{lang|en|list comprehension}})'' est une méthode permettant de construire des listes en indiquant simplement des axiomes, des consignes de filtrage. Cette méthode est élégante car proche de la notation mathématique et compacte, mais c'est une méthode itérative donc lente par rapport à une méthode vectorisée fournie par le module NumPy.
Par exemple, pour créer la liste des carrés des nombres entiers entre 0 et 9, il suffit d'écrire
<syntaxhighlight lang="python">
carre = [x**2 for x in range(10)]
</syntaxhighlight>
ce qui se rapproche de la notation d'ensemble <math>\{x^2 | x \in [0 ; 9] \}</math>.
Si l'on veut la liste des nombres strictement inférieurs à 20 dont le carré est supérieur à 10, on peut écrire :
<syntaxhighlight lang="python">
X = [x for x in range(20) if x**2 > 10]
</syntaxhighlight>
ce qui se rapproche de la notation d'ensemble <math>\{x | x \in [0 ; 19], x^2 > 10 \}</math>.
Pour mettre en évidence la performance du calcul vectorisé par rapport à la méthode itérative :
<syntaxhighlight lang="python">
import time
import numpy as np
n = int(1e7) # taille de la liste
t1 = time.perf_counter()
carre = [x**2 for x in range(n)] # Définition en compréhension
t2 = time.perf_counter()
carre2 = np.arange(n)**2 # Calcul vectorisé
t3 = time.perf_counter()
print("En compréhension : ", t2-t1, "s ; vectorisé :", t3-t2, "s ; rapport :", (t2-t1)/(t3-t2))
# En compréhension : 4.515... s ; vectorisé : 0.156... s ; rapport : 28.982...
</syntaxhighlight>
== Structure d'un programme ==
Un programme est simplement une suite d'instructions.
Dans les environnements Unix BSD, un programme Python peut être considéré comme un script c'est-à-dire qu'il suffit de taper son nom dans l'invite de commande ''({{lang|en|shell}})'' sans avoir à invoquer <code>python</code>. Le programme doit alors commencer par un en-tête normalisé surnommé ''{{lang|en|[[wikt:shebang|shebang]]}}'' :
<syntaxhighlight lang="python">
#!/usr/bin/env python3
</syntaxhighlight>
Ce ''{{lang|en|shebang}}'' est inutile avec Jupyter.
L'en-tête peut également contenir la description de l'encodage du fichier texte, typiquement :
<syntaxhighlight lang="python">
# coding: utf-8
</syntaxhighlight>
Le codage UTF-8 est le codage par défaut pour Python 3, il est donc inutile de l'indiquer.
Les commentaires sont introduits par le croisillon <code>#</code>.
On peut grouper une suite d'instructions dans un bloc. Un bloc d'instructions commence par deux-points « <code>:</code> » et est identé, c'est-à-dire qu'il a une marge constituée de quatre espaces — on peut aussi utiliser une tabulation mais il ne faut pas mélanger les deux méthodes ; les tabulations sont déconseillées, il vaut mieux utiliser quatre espaces<ref>{{lien web
| url = https://www.python.org/dev/peps/pep-0008/#tabs-or-spaces
| titre = Tabs or Spaces?
| site = Python documentation
| consulté le = 2019-03-14
}}</ref>. Pour terminer le bloc, il suffit simplement de revenir en début de ligne ; contrairement à d'autres langages, il n'y a pas de commende de fin ''({{lang|en|end}})'', c'est l'indentation qui définit le bloc.
: # début du bloc
''instruction 1''
''instruction 2''
…
''dernière instruction du bloc''
''instruction hors bloc''
Par exemple, une exécution conditionnelle <code>if</code> ou une boucle <code>for</code> exécute un bloc d'instruction. Si l'on a besoin d'un bloc d'instruction qui « ne fait rien », on utilise l'instruction <code>pass</code>.
== Structures de contrôle ==
'''Boucle itérative'''
La boucle itérative s'écrit :
<syntaxhighlight lang="python">
for <variable> in <itérable>:
<bloc d’instructions>
</syntaxhighlight>
Si l'on veut que la variable prenne ''n'' valeurs de 0 à ''n'' – 1, on utilise l'instruction <code>range()</code> :
<syntaxhighlight lang="python">
for i in range(5):
print(i)
print("Fin de la boucle")
</syntaxhighlight>
<code>[▶]</code>
0
1
2
3
4
Fin de la boucle
En fait, la commande <code>range()</code> extrait des valeurs de l'ensemble des nombres entiers ; on peut ainsi utiliser le découpage en tranches, par exemple <code>range(2, 5)</code>pour avoir la « liste » <code>[2, 3, 4]</code>. Notez que <code>range()</code> ne crée pas à proprement parler une liste, cela crée un objet de type ''« {{lang|en|range}} »'' (plage, intervalle) ; pour avoir une liste, il faut écrire <code>list(range(n))</code>.
Dans une boucle, la commande <code>continue()</code> saute la fin du bloc d'instruction et passe à la valeur suivante de la boucle. La commande <code>break()</code> interrompt la boucle et passe à la suite.
'''Exécution conditionnelle'''
L'exécution conditionnelle s'écrit :
<syntaxhighlight lang="python">
if <booléen>:
<bloc d’instructions>
</syntaxhighlight>
On peut utiliser les commandes <code>elif</code> ''(else if'') et <code>else</code> :
<syntaxhighlight lang="python">
if <booléen>:
<bloc d’instructions>
elif <booléen>:
<bloc d’instructions>
else:
<bloc d’instructions>
</syntaxhighlight>
Notez que le test d'une condition est gourmand en ressources. S'il s'agit de savoir si l'on effectue une opération mathématique simple ou pas, on peut remplacer le test par une multiplication par un booléen (<code>True</code> vaut 1, <code>False</code> vaut 0). Par exemple, plutôt que d'écrire
<syntaxhighlight lang="python">
if a > 0:
b = b - c
</syntaxhighlight>
mieux vaut écrire :
<syntaxhighlight lang="python">
b = b - (a > 0)*c
</syntaxhighlight>
'''Boucle antéconditionnée'''
La boucle antéconditionnée s'écrit :
<syntaxhighlight lang="python">
while <booléen>:
<bloc d’instructions>
</syntaxhighlight>
Cette boucle peut contenir des instructions <code>continue()</code> et <code>break()</code>.
== Fonction ==
La déclaration d'une fonction utilise la commande <code>def</code>. La fonction est un bloc d'instructions. Si elle doit renvoyer des valeurs, on utilise la commande <code>return</code>. Par exemple
<syntaxhighlight lang="python">
def nombres(n):
"""But : Entrer plusieurs nombres
Entrée : n, entier : quantité de nombre à saisir.
Sortie : foo : liste de n réels.
""" # description de la fonction
foo = [] # initialisation
for i in range(n):
foo = foo+[float(input("Entrez un nombre"))]
return foo
a = nombres(3)
print(a)
</syntaxhighlight>
La fonction commence par une chaîne de caractères qui la décrit. Cette chaîne peut être récupérée automatiquement par certains logiciels pour faire une documentation automatique. Si la description prend plusieurs lignes, elle commence et finit par trois double-guillemets <code>"""…"""</code> ; en fait, par convention, même si cela n'est pas obligatoire, les descriptions sont toutes encadrées de trois double-guillemets. Cette description est appelée ''{{lang|en|docstring (documentation string)}}''. Pour récupérer les ''{{lang|en|docstrings}}'' :
<syntaxhighlight lang="python">
def foo():
"""Cette fonction ne fait rien"""
pass
print(foo.__doc__)
# Cette fonction ne fait rien
</syntaxhighlight>
L'instruction <code>input()</code> permet à l'utilisateur de saisir une valeur. La valeur est retournée sous la forme d'une chaîne de caractères qui est ensuite convertie en nombre réel avec l'instruction <code>float()</code>.
On peut définir une valeur par défaut en l'indiquant dans l'en-tête de la définition de la fonction, de la manière suivante :
<syntaxhighlight lang="python">
def nombres(n=1): # valeur par défaut : 1
"""But : Entrer plusieurs nombres
Entrée : n, entier : quantité de nombre à saisir.
Sortie : foo : liste de n réels.
""" # description de la fonction
foo = [] # initialisation
for i in range(n):
foo = foo+[float(input("Entrez un nombre"))]
return foo
</syntaxhighlight>
Si le paramètre à initialiser est de type modifiable ''({{lang|en|mutable}})'', comme par exemple une liste, il faut procéder comme suit :
<syntaxhighlight lang="python">
def fooFonction(fooListe=None): # valeur par défaut : n'existe pas
"""Description"""
if fooListe = None:
fooListe = [] # initialisation
<suite des instructions>
</syntaxhighlight>
Par défaut, les variables sont locales. On peut rendre une variable globale avec l'instruction <code>global</code> ''à l'intérieur de la fonction'', avant l'utilisation de la variable. Par exemple :
<syntaxhighlight lang="python">
a = 1
b = 1
def toto():
"""Test de variable globale.
Entrée : aucune.
Sortie : aucune."""
global a
a = 2
b = 2
toto()
print("a =", a, "; b =", b) # a = 2 ; b = 1
</syntaxhighlight>
Pour être plus précis : si une variable n'est pas assignée dans une fonction, alors Python va chercher une variable du même nom à l'extérieur de la fonction. Mais à partir du moment où la variable est assignée dans la fonction, elle devient locale ''sauf'' si l'on a utilisé l'instruction <code>global</code>.
Si l'on s'attend à un nombre indéfini d'arguments, on utilise la notion d'empaquetage/dépaquetage ''({{lang|en|packing/unpacking}})''<ref>{{lien web
| url = https://deusyss.developpez.com/tutoriels/Python/args_kwargs/
| titre = Introduction à *args et **kwargs
| consulté le = 2019-03-09
| site = Developpez.com
}}.</ref>. L'empaquetage consiste à mettre les arguments dans un n-uplet, le dépaquetage consiste à développer un n-uplet en plusieurs variables. Cela se fait en mettant un astérisque ''({{lang|en|splat}})'' « <code>*</code> » devant le nom de la variable. Par convention, on utilise le nom de variable <code>*args</code> mais cela n'est pas obligatoire.
<syntaxhighlight lang="python">
def concatenation(*args):
"""Concatène des chaînes de caractères
Entrée : *args, n-uplet de chaînes de caractères.
Sortie : resultat, chaîne de caractères."""
resultat = ""
for i in args:
resultat = resultat + i
return resultat
concatenation("a", "foo", "toto") # 'afoototo'
</syntaxhighlight>
À l'inverse, si une fonction doit recevoir plusieurs paramètres, on peut à la place lui transmettre une liste à dépaqueter :
<syntaxhighlight lang="python">
def addition(a, b):
"""Ajoute deux nombres
Entrées :
— a : réel ;
— b : réel.
Sortie : a+b, réel"""
return a+b
arg = (1, 2)
addition(*arg) # 3
</syntaxhighlight>
On peut aussi empaqueter/dépaqueter un dictionnaire, on utilise pour cela deux astérisques « <code>**</code> ». Par convention, on utilise le nom <code>**kwargs</code> sans que cela soit obligatoire.
L'instruction <code>lambda</code> permet de créer de petites fonctions ne contenant pas de boucle ni de branchement conditionnel. Cependant, si la déclaration est courte et compacte, le code n'est pas toujours facilement lisible ; l'utilisation de cette instruction n'est pas recommandée.
Par exemple l'expression
<syntaxhighlight lang="python">
f = lambda x: 2*x
</syntaxhighlight>
est la même chose que
<syntaxhighlight lang="python">
def f(x):
"""Calcule le double.
Entrée : x, réel.
Sortie : 2*x, réel."""
return 2*x
</syntaxhighlight>
{{note|L'instruction <code>eval()</code> exécute une chaîne de caractères, c'est-à-dire traite une chaîne de caractères comme si c'étaient des instructions données à Python. Cette instruction est à éviter pour deux raisons :
# Un utilisateur malveillant pourrait entrer du code malveillant dans la chaîne de caractères.
# L'exécution est lente puisque Python doit compiler la chaîne à la volée.
Cette instruction peut en général être remplacée par une autre instruction.
}}
== Gestion des erreurs ==
Dans un bloc d'instructions, on peut utiliser la structure <code>try:… except:</code>. Le bloc après <code>try</code> est exécuté ; si une erreur se déclare dans ce bloc, alors le bloc <code>except</code> s'exécute. Par exemple
<syntaxhighlight lang="python">
try:
1/0 # Génère une erreur
except:
print("Division par zéro") # Cette instruction est donc exécutée
</syntaxhighlight>
On peut compléter avec <code>else:</code> et <code>finally:</code> :
<syntaxhighlight lang="python">
try:
<code à exécuter>
except:
<s’exécute en cas d’erreur>
else:
<s’exécute s’il n’y a pas d’erreur>
finally:
<s’exécute dans tous les cas>
</syntaxhighlight>
On peut séparer les différents types d'erreur :
<syntaxhighlight lang="python">
try:
<code à exécuter>
except ValueError:
print("Valeur erronée")
except TypeError:
print("Type erroné")
</syntaxhighlight>
Les types d'erreur les plus courants sont :
* <code>NameError</code> : le nom de variable n'existe pas ;
* <code>TypeError</code> : la valeur n'est pas du bon type ;
* <code>ValueError</code> : la valeur n'est pas compatible avec ce qui est attendu ;
* <code>RuntimeError</code> : type d'erreur général.
On peut aussi créer ses propres erreurs : si une situation erronée survient, on peut « lever » une exception avec <code>raise</code>. Par exemple
<syntaxhighlight lang="python">
if a < 0:
raise ValueError("La valeur doit être positive")
</syntaxhighlight>
; Ressources
* {{lien web
| url = https://docs.python.org/3/tutorial/errors.html
| titre = Errors and exceptions
| lang = en
| site = Python documentation
| consulté le = 2019-03-12
}}
* {{lien web
| url = https://docs.python.org/3/library/exceptions.html
| titre = Built-in Exceptions
| lang = en
| site = Python documentation
| consulté le = 2019-03-12
}}
== Exercices ==
=== Calcul du PGCD et du PPCM par l'algorithme d'Euclide ===
{{loupe|w:Algorithme d'Euclide}}
Écrire un programme Python qui demande deux nombres entiers et affiche leurs PGCD et PPCM. Le programme utilisera l'algorithme d'Euclide.
{{boîte déroulante début|solution}}
<syntaxhighlight lang="python">
"""Programme : euclide.py
Auteur : User:cdang
date : 2019-02-19
dates de modification :
----------------------------------------------------------------------------
version de Python : 3
module requis : aucun
----------------------------------------------------------------------------
Objectif : calcule le PGCD et le PPCM de deux nombres entiers.
Entrée
------
au clavier, saisie de deux nombres entiers.
Sorties
-------
à l'écran, affichage du PGCD et du PPCM.
"""
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def euclide():
"""Calcule le PGCD et le PPCM avec l'algorithme d'Elclide
Entrée
------
Aucune, la saisie des paramètres fait partie de la fonction
Sortie
------
affichage du PGCD et du PPCM
"""
print("***** Algorithme d'Euclide *****\n")
a0 = int(input("Premier nombre entier : a = "))
b0 = int(input("Second nombre entier : b = "))
a = a0
b = b0
r = a%b # initialisation
while (r != 0) : # algorithme d'Euclide
a = b
b = r
r = a%b
# affichage des résultats
print("PGCD(", a0, ", ", b0, ") = ", b)
print("PPCM(", a0, ", ", b0, ") = ", a0*b0//b)
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
euclide()
</syntaxhighlight>
On peut simplifier la boucle centrale :
<syntaxhighlight lang="python">
while b: # s'exécute tant que b n'est pas 0
a, b = b, a % b # affectation de liste à liste
return a
</syntaxhighlight>
{{boîte déroulante fin}}
Notez que le module NumPy propose l'instruction <code>gcd()</code> :
<syntaxhighlight lang="python">
import numpy
…
print(numpy.gcd(a, b))
</syntaxhighlight>
=== Tours de Hanoï ===
{{loupe|w:Tours de Hanoï}}
Écrire un programme Python qui demande le nombre ''n'' de plateaux et affiche les manipulations nécessaires pour déplacer la pile d'un emplacement à un autre. Le programme utilisera l'algorithme récursif.
{{boîte déroulante début|solution}}
<syntaxhighlight lang="python">
"""nom : hanoi.py
auteur : User:cdang
date de création : 2019-02-19
dates de modification :
----------------------------------------------------------------------------
version de Python : 3
module requis : aucun
----------------------------------------------------------------------------
Objectif : résout le problème des tours de Hanoï
Entrées
-------
trois chaînes de caractères (nom des piliers)
Sorties
-------
une chaîne de caractères (liste des opérations)
"""
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def hanoi(a, b, c, n):
"""Résout le problème des tours de Hanoï de manière récursive
But : déplace la pile de n disques du piler a au pilier b
Entrées
-------
a, b c : chaînes de 1 caractère, référence des emplacements ;
n : entier, nombre de disques sur l'emplacement a
Sorties
-------
operations : chaînes de caractères décrivant les opérations
""""
if n>1:
operations = hanoi(a, c, b, n-1)
operations = operations+a+"→"+b+" ; "
operations = operations+hanoi(c, b, a, n-1)
else:
operations = a+"→"+b+" ; "
return operations
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
resultat = hanoi("1", "2", "3", 3)
print(resultat)
</syntaxhighlight>
{{boîte déroulante fin}}
=== Lancer de rayons ===
[[Fichier:Lentille hemispherique perspective.svg|vignette|Lentille hémisphérique.]]
Considérons une lentille hémisphérique de rayon R faite d’un verre d’indice de réfraction ''n''. Nous plaçons une source ponctuelle à une distance ''d'' du dioptre plan, sur l’axe optique. Tracer des rayons partant de la source et traversant la lentille.
{{clear}}
{{Boîte déroulante/début |titre=Analyse d’optique géométrique}}
[[Fichier:Lentille hemispherique analyse geometrique.svg|vignette|Analyse géométrique du problème.]]
Il s’agit d’un problème ayant une symétrie de révolution par rapport à l’axe optique. Nous pouvons nous réduire à un problème plan en nous plaçant dans un plan contenant l’axe optique ; l’axe optique est encore un axe de symétrie orthogonale, nous pouvons donc nous contenter d'étudier un demi-plan.
Pour simplifier, nous plaçons le centre du dioptre sphérique à l’origine O du repère. L’axe optique est l’axe ''x'' et l'axe perpendiculaire, vertical sur la figure, c’est l’axe ''y''.
Les coordonnées de la source sont donc (-''d'' ; 0). Le rayon issu de la source et faisant un angle θ avec l’axe ''x'' frappe le dioptre plan à l’altitude ''h''. Nous avons :
: ''h'' = ''d'' ⋅ tan θ.
L’angle d’incidence vaut θ. D’après la loi de Snell-Descartes, l'angle de réfraction θ<sub>2</sub> vaut :
: θ<sub>2</sub> = arcsin((sin θ) / ''n'').
Le rayon réfracté passe par le points de coordonnées (0, ''h''). L’équation de la droite est donc :
: ''y'' = a ⋅ ''x'' + ''h''
avec
: ''a'' = tan θ<sub>2</sub>.
L’équation du cercle de centre O et de rayon R est :
: ''x''<sup>2</sup> + ''y''<sup>2</sup> = R<sup>2</sup>.
Les coordonnées (''x''<sub>M</sub>, ''y''<sub>M</sub>) de l’intersection M du rayon avec le dioptre sphérique vérifient les deux équations. Par substitution, nous obtenons une équation du second degré en ''x'' que nous savons résoudre :
: ''x''<sub>M</sub><sup>2</sup> + (''a'' ⋅ ''x''<sub>M</sub> + ''h'')<sup>2</sup> = R<sup>2</sup>
: ⇔ (1 + ''a''<sup>2</sup>) ⋅ ''x''<sub>M</sub><sup>2</sup> + 2 ⋅ ''a'' ⋅ ''h'' ⋅ ''x''<sub>M</sub> + ''h''<sup>2</sup> – R<sup>2</sup> = 0.
D’après les propriétés du cercle, le rayon est perpendiculaire à la tangente. Le rayon [OM] est donc normal au dioptre en M. Nous pouvons déterminer l’angle d’incidence θ<sub>i</sub> par le produit scalaire :
: <math>\begin{pmatrix} 1 \\ a \end{pmatrix} \cdot \begin{pmatrix} x_\mathrm{M} \\ y_\mathrm{M} \end{pmatrix} = \sqrt{1^2 + a^2} \cdot \mathrm{R} \cdot \cos(\theta_\mathrm{i})</math>
ce qui nous permet de calculer cet angle :
: <math>\theta_\mathrm{i} = \operatorname{arcos} \left ( \frac{x_\mathrm{M} + a \cdot y_\mathrm{M}}{\mathrm{R} \cdot \sqrt{1^2 + a^2} } \right )</math>
Comme nous passons vers un milieu d’indice plus faible, il y a un risque de réflexion totale. L’angle limite est :
: θ<sub>max</sub> = arcsin(1/''n'').
Si l’on a θ<sub>i</sub> > θ<sub>max</sub>, le rayon repart vers l’intérieur. Nous ne traçons pas le rayon car cela nous emmènerait trop loin dans l’analyse. En revanche, si θ<sub>i</sub> ≤ θ<sub>max</sub>, alors nous pouvons appliquer la loi de Snell-Descartes pour avoir l’angle de réfraction θ<sub>e</sub> :
: θ<sub>e</sub> = arcsin(''n'' ⋅ sin θ<sub>i</sub>).
Pour tracer le rayon sortant, il nous faut l’angle θ<sub>3</sub> par rapport à l’horizontale. L’angle du rayon [OM] par rapport à l’horizontal vaut arctan(''y''<sub>M</sub> / ''x''<sub>M</sub>), nous avons donc
: θ<sub>3</sub> = arctan(''y''<sub>M</sub> / ''x''<sub>M</sub>) + θ<sub>e</sub>.
{{Boîte déroulante/fin}}
{{Boîte déroulante/début |titre=Analyse algorithmique}}
'''Structure des données'''
Le problème est décrit par trois paramètres :
# Le rayon <code>R1</code> de la lentille, en milliètres (réel en virgule flottante).
# L’indice du verre, <code>n</code> sans dimension (réel en virgule flottante). L’indice de l’air vaut 1.
# La distance de la source au dioptre d’entrée plan, <code>d</code> en millimètres (réel en virgule flottante).
Un rayon est caractérisé par quatre paramètres :
# L’angle d’émission <code>theta1</code> en radians (réel en virgule flottante).
# L’angle de réfraction dans la lentille <code>theta2</code> en radians (réel en virgule flottante).
# Les cordonnées <code>M</code> en millimètre (vecteur de dimension 2 <code>([x, y])</code> de réels en virgule flottante) du point d’intersection du rayon avec le dioptre sphérique.
# L’angle de réfraction dans l’air après la lentille <code>theta3</code> en radians (réel en virgule flottante).
Pour le calcul et le tracé, nous avons besoin des paramètres intermédiaires suivants :
* l’altitude ''y'' = <code>h</code> en millimètres (réel en virgule flottante) à laquelle le rayon frappe le dioptre plan d’entrée ;
* l’angle d’incidence du rayon avec le dioptre sphérique <code>thetaint</code> en radians (réel en virgule flottante).
Les angles sont stockés en radians car c’est l’unité naturelle pour le calcul mais nous affichons les valeurs en degrés. Comme le calcul de conversion est récurrent, nous conservons les facteurs <code>degversrad</code> (conversion des degrés vers les radians, facteur valant π/180, réel en virgule flottante) et <code>radversdeg</code> (conversion des radians vers les degrés, facteur valant 180/π, réel en virgule flottante).
'''Fonctions'''
Nous avons besoin d’une fonction qui calcule les trois paramètres du rayon <code>(theta2, M, theta3)</code> à partir de l’angle d’émission <code>theta1</code>. Nous appelons cette fonction <code>lanceRayon()</code>. Cette fonction fait appelle à une fonction qui calcule l’angle du rayon réfracté à partir de l’angle du rayon incident <code>theta1</code>, les deux angles étant par rapport à la normale au dioptre au point considéré. Nous appelons cette fonction <code>refrac()</code>.
La recherche de l’intersection <code>M</code> du rayon avec le dioptre sphérique nécessite de résoudre une équation du second degré. Nous utilisons pour cela la recherche des racines du polynôme en <code>x</code> avec la fonction <code lang="python">numpy.polynomial.polynomial.polyroots()</code>. D’après la configuration du problème géométrique, si l’on s’assure que le rayon frappe bien la lentille (0 ≤ <code>h</code> ≤ <code>R1</code>) alors nous sommes sûrs que le problème a deux solutions réelles (une positive et une négative) ou, dans le cas dégénéré où <code>h == R1</code>, une valeur unique <code>x == 0</code>. Comme nous recherchons la valeur positive, nous sélectionons la plus grande des deux racines.
Pour la gestion de la réflexion interne : dans la fonction <code>refrac()</code>, nous vérifions les conditions de réflexion totale et si elles sont remplies, alors nous générons une erreur (commandes <code lang="python">try… except</code> et <code lang="python">raise ValueError</code>). Cette erreur est propagée à la fonction <code>lanceRayon()</code> : <code>lanceRayon()</code> appelle la fonction <code>refrac()</code> et si cette fonction renvoie une erreur, alors <code>lanceRayon()</code> renvoie également une erreur.
Pour trouver l’angle d’émission <code>thetaLimite</code> provoquant la réflexion totale (en radians, réel en virgule flottante), nous effectuons une recherche par dichotomie :
* nous partons de l’angle maximum possible, lorsque le rayon frappe le sommet de la lentille, et nous appelons la fonction <code>lanceRayon()</code> ; si cela ne génère pas d’erreur, alors nous pouvons aller jusqu’à cette valeur, la recherche est terminée ; si cela génère une erreur, alors nous divisons la valeur par deux ;
* à une étape de la recherche donnée, si <code>lanceRayon()</code> ne génère pas d’erreur avec l’angle testé, alors nous savons que l’angle limite est supérieur à cette valeur ; cette valeur minore donc la valeur recherchée ; si au contraire <code>lanceRayon()</code> génère une erreur, alors c’est que l’angle est trop important, cette valeur majore donc la valeur recherchée ; nous pouvons ainsi resserer l’intervalle de recherche ;
* nous nous arrêtons lorsque les valeurs haute et basse sont suffisamment proche.
Concrètement :
# Nous définissons une variable <code>angleHaut</code> angle en radians, réel en virgule flottante) qui est l’angle d’émission le plus bas connu provoquant la réflexion totale.
# Nous définissons une variable <code>angleBas</code> angle en radians, réel en virgule flottante) qui est l’angle d’émission le plus haut connu ne provoquant pas de réflexion totale. Sa valeur initiale est 0. L’angle limite recherché est donc entre <code>angleBas</code> et <code>angleHaut</code>.
# Nous définissons l’angle <code>angleTest</code> comme étant la moyenne entre <code>angleBas</code> et <code>angleHaut</code>. Si <code>lanceRayon(angleTest)</code> génère une erreur, alors <code>angleTest</code> est la nouvelle valeur d’<code>angleHaut</code> (puisque c’est une valeur provoquant la réflexion totale et qu’elle est plus basse que la valeur actuelle d’<code>angleHaut</code>). À l’inverse, si <code>lanceRayon(angleTest)</code> ne génère pas d’erreur, alors <code>angleTest</code> est la nouvelle valeur d’<code>angleBas</code> (puisque c’est une valeur ne provoquant pas la réflexion totale et qu’elle est plus haute que la valeur actuelle d’<code>angleBas</code>).
# Nous arrêtons la procédure lorsque l’écart entre <code>angleBas</code> et <code>angleHaut</code> est inférieur à {{unité|10|échelle=<sup>–3</sup>|rad}} (valeur arbitraire).
La valeur retenue est la valeur finale d’<code>angleBas</code> (puisque l’on veut être sûr qu’il n’y ait pas de réflexion totale). La valeur affichée est la valeur en degrés arrondie au dixième.
{{Boîte déroulante/fin}}
{{Boîte déroulante/début |titre=Solution}}
Nous demandons à l’utilisateur ou à l’utilisatrice les valeurs des paramètres du problème : rayon de la lentille, distance de la source, indice de réfraction du verre. Nous vérifions que les valeurs entrées sont bien des nombres ; si c’est une chaîne vide, alors nous utilisons une valeur par défaut.
Nous créons une fonction <code>refrac()</code> qui permet de calculer l’angle réfracté à partir de l’angle d’incidence et des indices de réfraction. S’il y a rélexion totale, alors nous générons une erreur.
La fonction <code>lanceRayon()</code> calcule les différents points de passage du rayon. Elle appelle pour cela la fonction <code>refrac()</code>. Si un appel de la commande <code>refrac()</code> génère une erreur, alors nous générons également une erreur.
Nous déterminons l’angle d’émision du rayon <code>thetaLimite</code> qui provoque une réflecxion totale. Pour cela, nous créons une fonction <code>rechercheLimite()</code> qui cherche par dichotomie.
Nous traçons un rayon tous les 5° jusqu’à la valeur limite.
<syntaxhighlight lang="python">
#!/usr/bin/env python3
# coding: utf-8
"""nom : lancerRayons.py
auteur : User:cdang
date de création : 2022-05-06
dates de modification :
----------------------------------------------------------------------------
version de Python : 3
module requis : NumPy, matplotlib
----------------------------------------------------------------------------
Objectif : trace des trajets optique avec une lentille hémisphérique
Entrées
-------
Le rayon de la lentille, la distance de la source, l’indice de réfraction du verre,
trois chaînes de caractères saisies par l’utilisateur·rice et qui sont converties en réels.
Sorties
-------
La valeur limite de l’angle (réel) et le tracé de plusieurs rayons.
"""
# ******************************************************
# ******************************************************
# ** Lancer de rayons pour une lentille hémisphérique **
# ******************************************************
# ******************************************************
import numpy as np
import matplotlib.pyplot as plt
import numpy.polynomial.polynomial as nppol
# **************
# * Constantes *
# **************
# Pour la conversion degrés ↔ radians
radversdeg = 180/np.pi
degversrad = 1/radversdeg
# *************
# * Fonctions *
# *************
def boucleEntreeNombre(messageSaisie, valeurDefaut):
"""Permet de s’assurer que l’utilisateur·rice a bien entré un nombre.
Entrée :
— message à afficher (chaîne de caractères) ;
— valeur par défaut (réel à virgule flottante).
Sortie : nombre (réel à virgule flottante)."""
messageErreur = "Veuillez entrer une valeur numérique (ou vide pour accepter la valeur par défaut).\n"
execute = True
while execute:
strNombre = input(messageSaisie+f" (valeur par défaut {valeurDefaut}) : ")
if strNombre == "":
nombre = valeurDefaut
execute = False
else:
try:
nombre = float(strNombre)
except:
print(messageErreur)
else:
execute = False
return nombre
def initialisation():
"""L’utilisateur·rice entre les variables du problème.
Entrées : aucune.
Sorties :
— R1 (mm) : rayon de la lentille ;
— d (mm) : distance de la source au dioptre plan ;
— n (sans dimension) : indice de réfraction du verre."""
R1 = boucleEntreeNombre("Rayon de la lentille en mm", 20.0)
d = boucleEntreeNombre("Distance de la source au dioptre plan en mm", 20.0)
n = boucleEntreeNombre("Indice de réfraction (sans dimension)", 1.5)
return (R1, d, n)
def refrac(n1, n2, theta1):
"""Calcule l’angle de réfraction theta2 (radians) en fonction
— de l’angle d’incidence theta1 (radians);
— de l’indice de réfraction n1 du premier milieu ;
— de l’indice de réfraction n2 du second milieu."""
reflexionTotale=False
rapport=n2/n1
rapportinv=np.reciprocal(rapport)
if n1 > n2:
thetal = np.arcsin(rapport) # angle limite pour la réflexion totale
if theta1 >= thetal:
reflexionTotale=True
if reflexionTotale:
print("Réflexion totale")
raise ValueError
else:
return np.arcsin(rapportinv*np.sin(theta1))
def lanceRayon(n1, n2, d, R, theta1):
"""Détermine le rayon issu de la source
située à une distance d (mm) du bareau
et avec une élévation de theta1 (radians),
en fonction des indices de réfraction n1 et n2.
Les éléments retournés sont :
— la hauteur h (mm) à laquelle le rayon frappe le barreau ;
— l’angle de réfraction theta2 (radians)) dans le barreau ;
— l’angle de réfraction theta3 (radians) à la sortie du barreau
— le point M(x, y) (mm) auquel le rayon sort du barreau."""
h = d*np.tan(theta1)
if h >= R:
print("Le rayon est au-dessus du barreau")
raise ValueError
else:
theta2 = refrac(n1, n2, theta1)
a = np.tan(theta2)
x = max(nppol.polyroots([h*h - R*R, 2*a*h, 1+a*a])) # recherche de l’intersection du rayon avec le cercle
y = a*x + h
M = np.array([x, y])
thetaint = np.arccos((x + a*y)/(R*np.sqrt(1 + a*a)))
theta3 = np.arctan(y/x) - refrac(n2, n1, thetaint)
return (h, theta2, theta3, M)
def rechercheLimite(n1, n2, d, R):
"""Recherche l’angle limite pour la réflexion totale.
Entrée :
— indice de réfraction des milieux 1 et 2, n1 et n2 ;
— distance au barreau, d(mm).
Sortie : angle limite theta (radians)"""
angleHaut = np.arctan(R/d)
angleBas = 0
angleTest = angleHaut
try:
lanceRayon(n1, n2, d, angleTest, R)
except:
condition = True # il y a réflexion total en haut de la lentille
else:
condition = False # il n’y a jamais réflexion totale dans la lentille
while condition: #dichotomie
angleTest = np.mean([angleHaut, angleBas]) # on ajuste la valeur de test
try:
lanceRayon(n1, n2, d, R, angleTest)
except:
angleHaut = angleTest # réflexion totale : on abaisse la valeur maximale
else:
angleBas = angleTest # pas de réflexion totale : on monte la valeur minimale
condition = ((angleHaut - angleBas) >= 0.001) # on a cerné la limite à 0,001 rad près
if not condition:
angleTest = angleBas
return angleTest
# ***********************
# * Programme principal *
# ***********************
(R1, d, n) = initialisation()
xmax = round(R1 + d)
thetaLimite = rechercheLimite(1, n, d, R1)
thetaLimiteDeg = thetaLimite*radversdeg
print(f"Angle limite pour la réflexion totale : {thetaLimiteDeg:.1f}°.\n")
anglesDeg = np.arange(0, thetaLimiteDeg, 5)[1:] # trace un rayon tous les 5°
anglesRad = anglesDeg*degversrad
nb = len(anglesDeg)
h = np.zeros(nb) # initialisation des vecteurs de valeurs
theta2 = np.zeros(nb)
theta3 = np.zeros(nb)
M = np.zeros((nb, 2))
for i in range(nb):
(h[i], theta2[i], theta3[i], M[i, :]) = lanceRayon(1, n, d, R1, anglesRad[i])
(h_lim, theta2_lim, theta3_lim, M_lim) = lanceRayon(1, n, d, R1, thetaLimite)
# tracé
anglesCercle = 0.5*np.pi*(np.linspace(1, 0, 20))
x_cercle = R1*np.cos(anglesCercle) # coordonnées des pints du cercle
y_cercle = R1*np.sin(anglesCercle)
fig = plt.plot([-d,xmax], [0, 0], "k-.", linewidth="0.5") # tracé de l’axe optique
for i in range(nb):
plt.plot([-d, 0, M[i, 0], xmax], [0, h[i], M[i, 1], M[i, 1] + (xmax - M[i, 0])*np.tan(theta3[i])],
label=f"{anglesDeg[i]:.0f}°")
plt.plot([-d, 0, M_lim[0], xmax], [0, h_lim, M_lim[1], M_lim[1] + (xmax - M_lim[0])*np.tan(theta3_lim)],
label=f"{0.1*int(np.trunc(10*thetaLimite*radversdeg)):.1f}°")
plt.plot(x_cercle, y_cercle, "k", linewidth="0.5") # tracé du cercle
plt.plot([0,0], [0, R1], "k", linewidth="0.5") # tracé du premier dioptre
#plt.axis("square")
plt.gca().set_aspect("equal", adjustable="box")
plt.xlabel("x (mm)")
plt.ylabel("y (mm)")
plt.title("Lentille hémisphérique, lancer de rayons")
plt.legend()
plt.savefig("lentille_hemispherique_lancer_rayon.svg", format="svg")
plt.show()
</syntaxhighlight>
{{Boîte déroulante/fin}}
== Mesurer le temps ==
Le module <code>time</code> fournit les fonctions suivantes :
* <code>time.gmtime()</code> : renvoie la date et l'heure du méridien de Greenwich (''{{lang|en|Greenwich mean time}}'', GMT), sous la forme d'un dictionnaire (année, mois, jour du mois, heure, minute, seconde, jour de la semaine, jour de l'année, heure d'été/hiver),
** jour de la semaine est un entier entre 0 (lundi) et 6 (dimanche),
** jour du mois est un entier entre 1 et 366 ;
* <code>time.localtime()</code> : comme le précédent, mais l'heure est l'heure locale ;
* <code>time.time()</code> : donne le nombre de seconde qui se sont écoulées depuis le 1er janvier 1970 ;
* <code>time.gmtime(n)</code> et <code>time.localtime(n)</code> transforment un nombre de secondes (écoulées depuis le 1er janvier 1970) en une date au format (année, mois, jour, etc.), n-uplet de neuf valeurs ; <code>time.mktime()</code> fait le contraire, il transforme un n-uplet de neuf valeurs (années, mois, jour, etc.) en un nombre de secondes (écoulées depuis le 1er janvier 1970) ;
* <code>time.sleep(n)</code> : provoque une pause dans le déroulement du programme de ''n'' secondes ;
* <code>time.perf_counter()</code> : indique une date en seconde ; s'utilise pour mesurer la durée d'exécution d'une partie du code, en faisant la différence entre deux relevés.
Concernant la date et l'heure sous la forme d'un n-uplet, on peut extraire l'heure de la manière suivante :
<syntaxhighlight lang="python">
import time
a = time.localtime()
print("Il est ", a[3], "h", a[4])
# ou bien
print("Il est ", a.tm_hour, "h", a.tm_min)
</syntaxhighlight>
Pour mesurer la performance d'une portion de code :
<syntaxhighlight lang="python">
import time
t1 = time.perf_counter()
<suite d’instructions>
t2 = time.perf_counter()
print("Durée d'exécution :", t2-t1
</syntaxhighlight>
== Programmation orientée objet ==
Nous n'allons pas ici faire un cours de programmation orientée objet (POO), nous allons aborder le sujet de manière pragmatique.
De manière schématique, un « objet » est une « super-variable ». Cette super-variable peut contenir plusieurs variables, appelées « attributs » ; elle contient en fait un dictionnaire (paires « nom d'attribut : valeur d'attribut »). Elle peut aussi contenir des fonctions spécifiques appelées « méthodes ». De même qu'une variable a un type, un objet fait partie d'une « classe ». La classe est le modèle de l'objet ; en franglais informatique, on dit que l'objet est une instance de la classe.
La POO est donc un formalisme : lorsque l'on définit des variables et des fonctions concernant un même type d'objet (au sens commun du terme), on les empaquette dans une classe. Il faut donc d'abord définir la classe, puis attribuer cette classe à un objet (« instancier » la classe).
Considérons par exemple que nous voulons travailler sur des [[w:Engrenage|engrenages]] ; pour simplifier, nous nous contentons d'engrenages à dentures droites. Une roue dentée, un pignon, est essentiellement définie par son nombre de dents Z et par son module ''m'' qui correspond à la largeur de dents<ref>ainsi que par son épaisseur ''e'' et le matériau dont elle est faite mais nous allons négliger ces paramètres pour la simplicité de l'étude.</ref>. Nous allons définir trois méthodes : la méthode <code>.diametrePrimitif()</code> qui calcule le diamètre primitif de la roue dentée, <code>.pas()</code> qui calcule la largeur des dents au niveau du cercle primitif et <code>.rapport()</code> qui calcule le rapport de transmission de deux roues engrenées Z<sub>1</sub>/Z<sub>2</sub>. La méthode <code>.rapport()</code> vérifie par ailleurs que les roues ont le même module, condition indispensable pour former un engrenage.
Nous définissons la classe ainsi :
<syntaxhighlight lang="python">
class pignon:
"""roue dentée""" # explication de la classe
pi = 3.141592653589793 # pour calculer le pas
def __init__(self, Z=13, m=0.06):
# instructions lancées lors de la déclaration
"""Valeurs des attributs"""
self.Z = Z # nombre de dents
self.m = m # module
def diametrePrimitif(self):
"""Calcule le diamètre primitif"""
return self.m*self.Z
def pas(self):
"""Calcule le pas"""
return self.pi*self.m
def rapport(roueDentee, self):
"""Calcule le rapport de transmission"""
if roueDentee.m != self.m: # gestion de l'erreur
raise ValueError("Les pignons doivent avoir le même module")
else:
return roueDentee.Z/self.Z
</syntaxhighlight>
Nous remarquons que lorsque nous déclarons les méthodes, le paramètre <code>self</code> correspond à l'objet lui-même. Ainsi, dans la méthode <code>.rapport()</code>, la variable <code>self.Z</code> est le nombre de dents de la roue elle-même et <code>roueDentee.Z</code> est le nombre de dents de la roue passée en paramètre.
Pour déclarer les roues, nous écrivons :
<syntaxhighlight lang="python">
roue1 = pignon() # attribution de la classe, « instanciation »
roue1.Z = 13 # définition des caractéristiques du pignon « roue1 »
roue1.m = 2
roue2 = pignon(16, 2) # manière alternative
</syntaxhighlight>
Nous pouvons alors utiliser les objets de la manière suivante :
<syntaxhighlight lang="python">
print(roue1.Z) # 13
print(roue1.diametrePrimitif()) # 26
R = roue1.rapport(roue2) # 0.8125
</syntaxhighlight>
La commande <code>dir(a)</code> affiche tous les attributs et méthodes de l'objet <code>a</code>.
; Ressources
: {{lien web
| url = https://docs.python.org/3/tutorial/classes.html
| titre = Classes
| site = Python documentation
| consulté le = 2019-03-08
}}
== Interface graphique avec Tk ==
=== Généralités ===
Une interface graphique utilisateur (GUI, ''{{lang|en|graphic user interface}}'') est un ensemble de boîtes permettant d'interagir avec l'utilisateur, c'est-à-dire qui permettent la saisie d'informations, l'exécution d'actions et l'affichage d'informations. L'interface se compose d'éléments appelés ''{{lang|en|widgets}}''.
Les éléments ''({{lang|en|widgets}})'' classiques sont :
* boîte de dialogue ''({{lang|en|dialog box}})'' : fenêtre contenant d'autres éléments ;
* étiquette ''({{lang|en|label}})'' : texte affiché ;
* liste déroulante ''({{lang|en|drop-down list}})'' : zone permettant le choix d'une option, la liste se déployant lorsque l'on clique sur la zone ;
* zone de texte, champ de saisie ''({{lang|en|text box}})'' : zone permettant de taper du texte ;
* boîte combinée ''({{lang|en|combo box}})'' : zone de saisie de texte contenant une liste déroulante qui permet de choisir des éléments prédéfinis ;
* bouton ''({{lang|en|button}})'' : objet effectuant une action lorsque l'on clique dessus ;
* case à cocher ''({{lang|en|checkbox, tickbox}})'' : objet permettant d'activer ou de désactiver une option lorsque l'on clique dessus ;
* bouton radio, case d'option ''({{lang|en|radio button}})'' : objet permettant d'activer une option en désactivant les autres options ; une seule option peut être activée à la fois.
=== Avec Tk ===
Plusieurs modules permettent de gérer les interfaces graphiques. Nous choisissons ici le module développé sur la bibliothèque Tk qui est une bibliothèque multiplateforme. Pour cela, nous importons le module <code>tkinter</code> ainsi que le module <code>ttk</code>, ce dernier proposant des options plus « modernes » :
<syntaxhighlight lang="python">
import tkinter as tk
from tkinter import ttk
</syntaxhighlight>
Voici un programme permettant comme précédemment de calculer le rapport de transmission d'un engrenage. Nous détaillons sa construction ci-après.
<syntaxhighlight lang="python">
# référence : https://tkdocs.com/tutorial/firstexample.html
import tkinter as tk
from tkinter import ttk
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def calcule(*args):
"""Calcule le rapport de transmission d'un engrenage"""
try:
valeurZ1 = float(IUz1.get())
valeurM1 = float(IUm1.get())
valeurZ2 = float(IUz2.get())
valeurM2 = float(IUm2.get())
if valeurM1 != valeurM2:
IUrapport.set("Erreur de module")
else:
IUrapport.set(valeurZ2/valeurZ1)
except:
IUrapport.set("erreur")
# *************************
# *************************
# ** Interface graphique **
# *************************
# *************************
# fenetre principale
fenetre = tk.Tk()
fenetre.title("Rapport de réduction")
# élément (widget) cadre contenant tout le reste
cadre = ttk.Frame(fenetre, padding="3 3 12 12")
cadre.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
# le cadre s'étire si l'on étire la fenêtre
fenetre.columnconfigure(0, weight=1)
fenetre.rowconfigure(0, weight=1)
# Paramètres du système (variables)
IUz1 = tk.StringVar()
IUm1 = tk.StringVar()
IUz2 = tk.StringVar()
IUm2 = tk.StringVar()
IUrapport = tk.StringVar()
# Création des zones de saisie
z1_entry = ttk.Entry(cadre, width=7, textvariable=IUz1)
m1_entry = ttk.Entry(cadre, width=7, textvariable=IUm1)
z2_entry = ttk.Entry(cadre, width=7, textvariable=IUz2)
m2_entry = ttk.Entry(cadre, width=7, textvariable=IUm2)
# Création des étiquettes statiques
z1_label = ttk.Label(cadre, text="z1")
m1_label = ttk.Label(cadre, text="m1")
z2_label = ttk.Label(cadre, text="z2")
m2_label = ttk.Label(cadre, text="m2")
rapport_statique = ttk.Label(cadre, text="Rapport de transmission : ")
# Création de l'étiquette dynamique
rapport_dynamique = ttk.Label(cadre, textvariable=IUrapport)
# Création du bouton
bouton = ttk.Button(cadre, text="Calcul", command=calcule)
# Placement des éléments (widgets)
z1_label.grid(column=1, row=1, sticky=tk.W)
z1_entry.grid(column=2, row=1, sticky=(tk.W, tk.E))
m1_label.grid(column=1, row=2, sticky=tk.W)
m1_entry.grid(column=2, row=2, sticky=(tk.W, tk.E))
z2_label.grid(column=1, row=3, sticky=tk.W)
z2_entry.grid(column=2, row=3, sticky=(tk.W, tk.E))
m2_label.grid(column=1, row=4, sticky=tk.W)
m2_entry.grid(column=2, row=4, sticky=(tk.W, tk.E))
rapport_statique.grid(column=1, row=5, sticky=tk.W)
rapport_dynamique.grid(column=2, row=5, sticky=(tk.W, tk.E))
bouton.grid(column=2, row=6, sticky=tk.W)
# ajoute une gouttière entre les éléments
for enfant in cadre.winfo_children():
enfant.grid_configure(padx=5, pady=5)
# Emplacement initial du curseur
z1_entry.focus()
# effet de la touche [entrée]
fenetre.bind("<Return>", calcule)
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
# Affichage et activation de la fenêtre
fenetre.mainloop()
</syntaxhighlight>
[[Fichier:Organisation interface Tk Python.svg|vignette|upright=2|Organisation des ''widgets''.]]
'''Explications'''
Nous commençons par définir la boîte de dialogue que nous appelons <code>fenetre</code> ; c'est un objet <code>Tk</code> et nous lui donnons un titre « » :
<syntaxhighlight lang="python">
fenetre = tk.Tk()
fenetre.title("Rapport de réduction")
</syntaxhighlight>
Puis, nous définissons un cadre attaché à cette fenêtre et qui va nous permettre « d'accrocher » les autres éléments, ce qui permet de garder une apparence satisfaisante lorsque l'on retaille la fenêtre :
<syntaxhighlight lang="python">
cadre = ttk.Frame(fenetre)
</syntaxhighlight>
Le cadre va comporter six lignes ''({{lang|en|row}})'' et deux colonnes ''({{lang|en|column}})''.
Nous allons placer une étiquette ''({{lang|en|label}})'' « z1 » : <code>text="z1"</code>. Cette étiquette se trouve dans une case du cadre, celle de la première colonne et la première ligne : <code>grid(column=1, row=1)</code>. Par rapport à cette case, elle est collée à « l'ouest » (W, ''{{lang|en|west}}'', gauche) de la case : <code>sticky=tk.W</code>.
<syntaxhighlight lang="python">
z1_label = ttk.Label(cadre, text="z1") # Création de l'étiquette
z1_label.grid(column=1, row=1, sticky=tk.W) # Placement de l'étiquette
</syntaxhighlight>
Notez que l'on aurait pu écrire directement :
<syntaxhighlight lang="python">
ttk.Label(cadre, text="z1").grid(column=1, row=1, sticky=tk.W)
</syntaxhighlight>
mais le fait de séparer la création de l'élément et son placement facilite la maintenance (recherche d'erreur, évolution du code).
Pour tout ce qui est dynamique, c'est-à-dire les zone de saisie des valeurs et l'affichage du résultat, il faut définir des « chaînes variables » ''({{lang|variable strings}})'' :
<syntaxhighlight lang="python">
IUz1 = tk.StringVar()
</syntaxhighlight>
Cette variable est une variable globale à la création. Nous pouvons alors placer la zone de saisie ''({{lang|en|entry}})'' à côté de l'étiquette lui correspondant. Nous nommons la zone de saisie <code>z1_entry</code> :
<syntaxhighlight lang="python">
z1_entry = ttk.Entry(cadre, width=7, textvariable=IUz1)
</syntaxhighlight>
Nous faisons de même pour les trois autres paramètres de l'engrenage, ''m''<sub>1</sub>, ''z''<sub>2</sub> et ''m''<sub>2</sub>. Le résultat est également une chaîne variable globale. Par rapport à notre mise en page, elle se situe dans la case colonne 2 ligne 5, centrée sur cette case (collé à l'est et à l'ouest) :
<syntaxhighlight lang="python">
rapport = tk.StringVar()
rapport_dynamique = ttk.Label(cadre, textvariable=rapport)
rapport_dynamique.grid(column=2, row=5, sticky=(tk.W, tk.E))
</syntaxhighlight>
Il nous faut encore définir une fonction de manière classique, nous l'appelons « calcule ». Les variables étant globales, on les utilise directement. On récupère les valeurs avec la méthode <code>get()</code> et nous modifions la valeur avec la méthode <code>set()</code> :
<syntaxhighlight lang="python">
def calcule():
valeurZ1 = float(IUz1.get())
valeurZ2 = float(IUz2.get())
IUrapport.set(valeurZ2/valeurZ1)
</syntaxhighlight>
Cette fonction est déclenchée lorsque l'on clique sur le bouton « Calcul » situé dans la case du cadre ligne 6 colonne 2 :
<syntaxhighlight lang="python">
bouton = ttk.Button(cadre, text="Calcul", command=calcule)
bouton.grid(column=2, row=6, sticky=tk.W)
</syntaxhighlight>
ou bien si l'on appuie sur la touche <code>[entrée]</code> du clavier :
<syntaxhighlight lang="python">
fenetre.bind("<Return>", calcule)
</syntaxhighlight>
À tout ceci, nous ajoutons des « gouttières » (marges, ''{{lang|en|paddings}}'') afin d'espacer les éléments.
Il faut ensuite « activer » la fenêtre pour qu'elle s'affiche. La méthode est <code>mainloop()</code> (boucle principale) : « boucle » (elle est active en permanence et attend des actions sur ses éléments),
<syntaxhighlight lang="python">
fenetre.mainloop()
</syntaxhighlight>
Nous avons ci-dessus mis la plupart du code en programme principal. Nous pouvons aussi programmer de manière fonctionnelle, en mettant la plupart du code dans des fonctions ; cependant, pour que la fenêtre et les variables dynamiques soient globales à tout le programme, elles doivent être déclarées dans le programme principal. Nous pouvons aussi mêler la programmation orientée objet.
{{boîte déroulante début|Calcul du rapport de transmission en programmation fonctionnelle et orientée objet}}
<syntaxhighlight lang="python">
# référence : https://tkdocs.com/tutorial/firstexample.html
import tkinter as tk
from tkinter import ttk
# *************
# *************
# ** Classes **
# *************
# *************
class pignon:
"""roue dentée""" # explication de la classe
pi = 3.141592653589793 # pour calculer le pas
def __init__(self, Z=13, m=0.06):
"""Valeurs des attributs"""
# instructions lancées lors de la déclaration
self.Z = Z # nombre de dents
self.m = m # module
def diametrePrimitif(self):
"""Calcule le diamètre primitif"""
return self.m*self.Z
def pas(self):
"""Calcule le pas"""
return self.pi*self.m
def rapport(roueDentee, self):
"""Calcule le rapport de transmission"""
if roueDentee.m != self.m: # gestion de l'erreur
raise ValueError("Les pignons doivent avoir le même module")
else:
return roueDentee.Z/self.Z
# ************************
# ************************
# ** Variables globales **
# ************************
# ************************
# fenetre principale
fenetre = tk.Tk()
# Paramètres du système (variables)
IUz1 = tk.StringVar()
IUm1 = tk.StringVar()
IUz2 = tk.StringVar()
IUm2 = tk.StringVar()
IUrapport = tk.StringVar()
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def calcule(*args):
"""Calcule le rapport de transmission d'un engrenage"""
try:
valeurZ1 = float(IUz1.get())
valeurM1 = float(IUm1.get())
valeurZ2 = float(IUz2.get())
valeurM2 = float(IUm2.get())
if valeurM1 != valeurM2:
IUrapport.set("Erreur de module")
else:
roue1 = pignon(valeurZ1, valeurM1)
roue2 = pignon(valeurZ2, valeurM2)
IUrapport.set(roue1.rapport(roue2))
except:
IUrapport.set("Erreur")
# ***********************
# * Interface graphique *
# ***********************
def configureFenetre():
"""Configuration de la fenêtre principale"""
fenetre.title("Rapport de réduction")
# élément (widget) cadre contenant tout le reste
cadre = ttk.Frame(fenetre, padding="3 3 12 12")
cadre.grid(column=0, row=0, sticky=(tk.N, tk.W, tk.E, tk.S))
# le cadre s'étire si l'on étire la fenêtre
fenetre.columnconfigure(0, weight=1)
fenetre.rowconfigure(0, weight=1)
# Création des zones de saisie
z1_entry = ttk.Entry(cadre, width=7, textvariable=IUz1)
m1_entry = ttk.Entry(cadre, width=7, textvariable=IUm1)
z2_entry = ttk.Entry(cadre, width=7, textvariable=IUz2)
m2_entry = ttk.Entry(cadre, width=7, textvariable=IUm2)
# Création des étiquettes statiques
z1_label = ttk.Label(cadre, text="z1")
m1_label = ttk.Label(cadre, text="m1")
z2_label = ttk.Label(cadre, text="z2")
m2_label = ttk.Label(cadre, text="m2")
rapport_statique = ttk.Label(cadre, text="Rapport de transmission : ")
# Création de l'étiquette dynamique
rapport_dynamique = ttk.Label(cadre, textvariable=IUrapport)
# Création du bouton
bouton = ttk.Button(cadre, text="Calcul", command=calcule)
# Placement des éléments (widgets)
z1_label.grid(column=1, row=1, sticky=tk.W)
z1_entry.grid(column=2, row=1, sticky=(tk.W, tk.E))
m1_label.grid(column=1, row=2, sticky=tk.W)
m1_entry.grid(column=2, row=2, sticky=(tk.W, tk.E))
z2_label.grid(column=1, row=3, sticky=tk.W)
z2_entry.grid(column=2, row=3, sticky=(tk.W, tk.E))
m2_label.grid(column=1, row=4, sticky=tk.W)
m2_entry.grid(column=2, row=4, sticky=(tk.W, tk.E))
rapport_statique.grid(column=1, row=5, sticky=tk.W)
rapport_dynamique.grid(column=2, row=5, sticky=(tk.W, tk.E))
bouton.grid(column=2, row=6, sticky=tk.W)
# ajoute une gouttière entre les éléments
for enfant in cadre.winfo_children():
enfant.grid_configure(padx=5, pady=5)
# Emplacement initial du curseur
z1_entry.focus()
# effet de la touche [entrée]
fenetre.bind("<Return>", calcule)
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
configureFenetre()
# Affichage et activation de la fenêtre
fenetre.mainloop()
</syntaxhighlight>
{{boîte déroulante fin}}
{{voir
|{{lien web |url=https://docs.python.org/3/library/tkinter.ttk.html |titre=tkinter.ttk — Tk themed widgets |site=docs.python.org |consulté le=2026-06-11}}
}}
{{voir
|{{lien web |url=https://matplotlib.org/stable/gallery/user_interfaces/embedding_in_tk_sgskip.html |titre=How to embed Matplotlib charts in Tkinter GUI? |site=Matplotlib.org |date=2025-07-15 |consulté le=2026-06-11}}
}}
=== Avec PyQt ===
Le module PyQt (prononcer \ˈpaɪ.kjut\) permet d'utiliser la bibliothèque Qt dévelopée par Riverbank Computing. Il permet notamment de créer des interfaces graphiques.
La communication entre objets Qt se fait par une mécanismes de « signal/emplacement » ''({{lang|en|signal/slot}})''. Un emplacement ''({{lang|en|slot}})'' est une fonction ''({{lang|en|callable}})'' ; un signal est un attribut d'un objet. Si l'attribut signal est défini pour l'emplacement, alors on dit que l'emplacement est relié à un signal. Par exemple, un objet <code>QPushButton</code> dispose du signal <code>clicked</code> qui est émis lorsque l'on clique dessus ; on peut ainsi faire exécuter un emplacement (fonction appelable) <code>action()</code> lorsque l'on clique sur le bouton par le biais du signal <code>clicked</code> :
<syntaxhighlight lang="python">
from PyQt5.QtWidgets import QPushButton
bouton = QPushButton("Appuies-moi dessus")
button.clicked.connect(action())
</syntaxhighlight>
{{voir|{{lien web |url=https://www.riverbankcomputing.com/static/Docs/PyQt6/ |titre=Reference guide PyQt6 |site=Riverbank Computing|consulté le=2026-0604}} }}
{{...}}
== Annotations ==
Une annotation est un commentaire qui sert à expliciter un type de variable. La syntaxe est différente des commentaires « classiques » : cela permet d'avoir un affichage différent avec les éditeurs de texte ayant une coloration syntaxique, et ces informations peuvent être récupérées par des logiciels extérieurs pour effectuer une documentation automatique ou bien des vérifications de type. Cependant :
* comme les commentaires normaux, ils n'ont aucune influence lors de l'exécution du texte ; en particulier :
* rien n'oblige à annoter les variables ;
* il est possible d'avoir une variable ayant un type différent de son annotation ; le fait de pouvoir définir et changer le type de variable à la volée est une fonctionnalité fondamentale de Python.
La syntaxe pour une annotation est :
: nom_de_variable + deux-points + espace + type
par exemple :
<syntaxhighlight lang="python">
a: int
</syntaxhighlight>
Notez qu'ici, la variable n'est ''pas'' créée. Pour la créer, il faut lui affecter une valeur. Il est possible de l'affecter après ou bien sur la même ligne avec la syntaxe :
: nom_de_variable + deux-points + espace + type + espace + égal + espace + valeur
par exemple :
<syntaxhighlight lang="python">
a: int
a = 5
# est équivalent à
a: int = 5
</syntaxhighlight>
Même si l'annotation n'a pas d'impact sur l'exécution, le type doit être un type existant sinon cela génère une erreur de syntaxe. Les types classiques sont :
: <code>int</code> — <code>float</code> — <code>str</code> — <code>bool</code> — <code>list</code> — <code>tuple</code> — <code>dict</code>
Il est également possible de mettre une chaîne de caractères :
<syntaxhighlight lang="python">
a: "ce que je veux" = 3.1516
</syntaxhighlight>
On peut annoter une fonction. Il est possible d'annoter les variables déclarées au sein de la fonction, mais pas les variables globales (puisqu'elle ne sont pas définie au sein de la fonction). On peut aussi annoter :
* les variables passées en paramètre, avec la même syntaxe dans les parenthèses ;
* annoter le type de la variable de sortie (retournée) en la faisant précéder de <code>-></code> :
<syntaxhighlight lang="python">
def plusCinq(a: float = 0) -> float:
return a + 5
</syntaxhighlight>
; Ressources
* {{lien web
| url = https://www.python.org/dev/peps/pep-0526/
| titre = PEP 526 -- Syntax for Variable Annotations
| site = Python.org
| consulté le = 2019-04-05
| lang = en
}}
* {{lien web
| url = https://www.python.org/dev/peps/pep-3107/
| titre = PEP 3107 -- Function Annotations
| site = Python.org
| consulté le = 2019-04-05
| lang = en
}}
== Décorateur ==
Un décorateur est une fonction qui s'applique à une fonction, à la manière de la composition mathématique ''g'' ∘ ƒ = ''g''(ƒ). Mais cette composition affecte la fonction elle-même ; l'utilisateur appelle la fonction ƒ mais c'est la fonction ''g'' ∘ ƒ qui s'exécute. Cette fonction ''g'' est appelée le décorateur.
L'intérêt est de pouvoir modifier une fonction sans modifier le code de la fonction elle-même.
Pour appliquer une décoration, il faut :
# Déclarer le décorateur : une fonction qui s'applique à une autre fonction.
# Affecter le décorateur à la fonction visée : en mettant <code>@''décoration''</code> juste avant la définition de la fonction.
Par exemple :
<syntaxhighlight lang="python">
def decorateur(f):
print("Avant la fonction")
f()
print("après la fonction")
@decorateur
def afficheFoo():
print("Foo.")
afficheFoo
# Avant la fonction
# Foo.
# Après la fonction
</syntaxhighlight>
Lorsque l'on appelle <code>afficheFoo</code>, on appelle en fait <code>decorateur(afficheFoo)</code>.
Si la fonction à modifier admet des paramètres, il faut définir une fonction enveloppante dans le décorateur. Par exemple, nous définissons ci-dessous un décorateur <code>deuxFois()</code> qui fait s'exécuter deux fois de suite la fonction :
<syntaxhighlight lang="python">
def deuxFois(f):
def conteneurFonction(*args, **kwargs):
f(*args, **kwargs)
f(*args, **kwargs)
return conteneurFonction
@deuxFois
def plusCinq(a: int = 0):
print(a + 5)
plusCinq(2)
# 7
# 7
print(plusCinq.__name__)
# conteneurFonction
</syntaxhighlight>
Nous voyons que l'application du décorateur a modifié le nom de la fonction — pas le nom de la variable qui contient la fonction mais bien son nom « intime ». Pour éviter cela, on utilise la méthode <code>wraps()</code> du module <code>functools</code> :
<syntaxhighlight lang="python">
import functools
def deuxFois(f):
@functools.wraps(f)
def conteneurFonction(*args, **kwargs):
f(*args, **kwargs)
f(*args, **kwargs)
return conteneurFonction
@deuxFois
def plusCinq(a: int = 0):
print(a + 5)
plusCinq(2)
# 7
# 7
print(plusCinq.__name__)
# plusCinq
</syntaxhighlight>
On peut par exemple utiliser un décorateur pour la mémoïsation. La mémoïsation est une méthode consistant à mémoriser les valeurs d'une fonction au fur et à mesure de son utilisation ; ainsi, si l'on veut évaluer la fonction avec les mêmes entrées, on se contente d'aller chercher la valeur enregistrée ce qui est plus rapide. On sacrifie donc la place mémoire au profit de la rapidité. On peut trouver des décorateurs de mémoïsation aux adresses suivantes :
* https://wiki.python.org/moin/PythonDecoratorLibrary#Memoize
* https://gist.github.com/robcowie/1357800
; Ressources
: {{lien web
| url = https://www.python.org/dev/peps/pep-0318/
| titre = PEP 318 -- Decorators for Functions and Methods
| site = Python.org
| lang = en
| consulté le = 2019-04-05
}}
== Manipulation de fichiers ==
=== Importer le contenu d'un fichier ===
Python possède la fonction <code lang="python">open()</code> qui permet d'ouvrir un fichier. Ouvrir signifie qu'il crée un objet de type <code>file</code> qui possède notamment les méthodes <code lang="python">.read()</code> et <code lang="python">.write()</code>. Il peut s'agir d'un objet de type « fichier binaire » ''({{lang|en|binary file}})'' ou « fichier texte » ''({{lang|en|text file}})''.
Si par exemple on veut utiliser (et donc lire) le contenu du fichier texte <code>monfichier.txt</code>, on écrit :
<syntaxhighlight lang="python">
fichier = open("monfichier.txt", "rt")
…
fichier.close()
</syntaxhighlight>
Le paramètre <code>"rt"</code> signifie que nous ouvrons le fichier en lecture ''({{lang|en|read}})'' et qu'il s'agit d'un objet de type fichier texte.
Notons deux choses :
* en faisant cela, nous ne faisons qu'associer le fichier à un objet Python, nous n'avons pas encore importé les données ;
* si nous ouvrons le fichier, il faut le fermer par la suite ; c'est pourquoi nous utilisons la méthode <code lang="python">.close()</code>.
Pour éviter d'avoir à fermer le fichier, nous pouvons l'ouvrir au sein d'un contexte :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
…
</syntaxhighlight>
Notons aussi que la chaîne de caractères indiquant le nom du fichier peut contenir le chemin d'accès au répertoire (dossier), mais sous Microsoft Windows, il faut utiliser des barres de fractions <code>/</code> pour séparer les sous-répertoires au lieu de la barre inversée habituelle, par exemple :
<syntaxhighlight lang="python">
chemin = "C:/Temp/monfichier.txt"
with open(chemin, "rt") as fichier:
…
</syntaxhighlight>
Pour mettre les données du fichier dans la variable <code>contenu</code>, nous écrivons donc :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.read()
print(contenu)
</syntaxhighlight>
et si nous ne voulons lire que les <code>n</code> premiers caractères (<code>n</code> étant un entier), nous utilisons <code lang="python">contenu = fichier.read(n)</code>. Cette lecture est séquentielle, c'est-à-dire que si nous appliquons la méthode plusieurs fois, nous reprenons la lecture là où nous l'avons laissée.
Si nous voulons lire une ligne, nous utilisons la méthode <code lang="python">.readline()</code>. La lecture ligne par ligne est également séquentielle. Nous pouvons aussi créer une liste dont chaque élément est une ligne du fichier ; nous utilisons alors la méthode <code lang="python">.readlines()</code> (notez le pluriel).
Chaque élément de la liste se termine par le caractère de fin de ligne <code lang="python">\n</code>. Pour l'enlever, nous pouvons utiliser la méthode <code lang="python">.rstrip()</code> pour chaque élément de la liste, par exemple. L'exemple complet est alors :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.readlines()
contenu = [item.rstrip() for item in contenu]
print(contenu)
</syntaxhighlight>
=== Importation avec NumPy ===
Les commandes <code>open</code> et <code>.read()</code> sont générales à Python. NumPy propose une fonction, <code>np.genfromtxt()</code>, qui sert à transformer du un fichier texte en matrice <code>ndarray</code>. Typiquement, pour un fichier CSV, on écrit :
<syntaxhighlight lang="python">
matrice = np.genfromtxt(r"emplacement/fichier.csv", delimiter=",")
</syntaxhighlight>
Cette fonction dispose de plusieurs paramètres, dont :
* <code>comments</code> : caractère, ou chaîne de caractères, introduisant un commentaire (à e pas prendre en compte), typiquement <code>comments="%"</code>, <code>comments="#"</code>, <code>comments="\\"</code>…
* <code>skip_header</code> : nombre de ligne à ne pas prendre en compte en début de fichier, typiquement celles qui contiennent l'en-tête ;
* <code>skip_footer</code> : nombre de ligne à ne pas prendre en compte en fin de fichier ;
* <code>usecols</code> : n-uplet des colonnes à lire, les autres étant à ignorer ;
* <code>names</code> ; si on met <code>names = True</code>, alors la première ligne lue (après les lignes sautées par <code>skip_header</code>) sert à créer les nom d'une matrice structurée ''({{lang|en|structures array}})''.
La fonction <code>np.loadtxt()</code> fait la même chose que <code>np.genfromtxt()</code> mais avec moins d eparamètres.
{{voir|https://numpy.org/doc/stable/user/basics.io.genfromtxt.html}}
=== Exporter du contenu vers un fichier ===
Si nous voulons créer un fichier texte <code>monfichier.txt</code> pour y mettre le contenu de la variable <code>texte</code>, alors nous utilisons :
<syntaxhighlight lang="python">
with open("monfichier.txt", "wt") as fichier:
fichier.write(texte)
</syntaxhighlight>
Le module principal important pour la manipulation de fichiers est est <code lang="python">os</code>.
=== Exploiter le contenu d'un fichier texte ===
Avec un fichier texte, la méthode <code lang="python">.read()</code> crée une variable de type texte. Nous pouvons séparer cette variable en différentes lignes avec la méthode <code lang="python">.splitlines()</code>. Cela crée une liste de chaînes de caractères, chaque chaîne étant une ligne.
Si maintenant une ligne contient plusieurs données séparées par un séparateur commun, par exemple un espace, nous pouvons séparer les données par la méthode <code lang="python">.split(''séparateur'')</code>. Cela crée une liste de chaînes de caractères, chaque chaîne étant une donnée.
Si par exemple le fichier est du type CSV ''({{lang|en|comma separated values}}'', valeurs séparées par une virgule), l'exploitation du fichier est :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.read()
contenu = contenu.splitlines()
contenu = [item.split(",") for item in contenu]
</syntaxhighlight>
La variable <code>contenu</code> est une liste de listes. Pour avoir la ''n''<sup>e</sup> valeurs de la ''m''<sup>e</sup> ligne, on utilise :
<syntaxhighlight lang="python">
contenu[m-1][n-1]
</syntaxhighlight>
Si l'on veut extraire la ligne ''m'' il suffit d'écrire :
<syntaxhighlight lang="python">
contenu[m-1]
</syntaxhighlight>
mais si l'on veut la colonne ''n'', le plus simple est d'utiliser une définition en compréhension :
<syntaxhighlight lang="python">
[ligne[n-1] for ligne in contenu]
</syntaxhighlight>
Dans certains fichiers CSV, les séparateurs de valeurs ne sont pas des virgules, on peut donc utiliser un autre caractère pour le séparateur. Concernant les séparateurs particuliers :
* si le séparateur est une tabulation, on utilise <code lang="python">\t</code> : <code lang="python">contenu = [item.split("\t") for item in contenu]</code> ;
* si le séparateur est un nombre arbitraire d'espaces et/ou de tabulation, on ne définit aucun séparateur : <code lang="python">contenu = [item.split() for item in contenu]</code>.
Si la première ligne contient les en-têtes des colonnes, on peut l'enlever avec la fonction <code lang="python">del()</code> :
<syntaxhighlight lang="python">
with open("monfichier.txt", "rt") as fichier:
contenu = fichier.read()
contenu = contenu.splitlines()
del(contenu[0])
contenu = [item.split(",") for item in contenu]
</syntaxhighlight>
Certains logiciels créent des fichiers en utilisant le séparateur décimal régional, qui en France est la virgule. Pour remplacer les virgules par des points, on peut utiliser la méthode <code lang="python">.replace()</code>, de préférence ''avant'' de séparer les valeurs :
<syntaxhighlight lang="python">
contenu = contenu.splitlines()
contenu = [item.replace(",", ".") for item in contenu] # remplace les virgules par des points
contenu = [item.split(";") for item in contenu] # si le séparateur est un point-virgule
</syntaxhighlight>
en effet, lorsque l'on a séparé les valeurs, on a une liste de liste, il faut alors balayer les sous-listes ce qui prend plus de temps :
<syntaxhighlight lang="python">
contenu = contenu.splitlines()
contenu = [item.split(";") for item in contenu] # si le séparateur est un point-virgule
contenu = [[subitem.replace(",", ".") for subitem in item] for item in contenu] # remplace les virgules par des points
</syntaxhighlight>
'''Exemple complet'''
Supposons que l'on ait un fichier texte de la forme :
<syntaxhighlight lang="text">
x y z V
0.0 1.5 3.2 8.657
0.4 1.5 3.2 8.392
0.2 1.5 3.2 8.485
...
</syntaxhighlight>
C'est un fichier valeurs V associées à des points de coordonnées ''(x, y, z)'' (un champ V sur l'espace, donc). Nous remarquons que seule la coordonnée ''x'' change : les données concernent la droite (''y'' = 1,5 ; ''z'' = 3,2). Nous remarquons aussi que les valeurs de ''x'' ne sont pas classées par ordre croissant ni décroissant.
Nous voulons au final avoir une matrice [[''x''], [V]] triée par ''x'' croissant. Pour cela, nous pouvons faire :
<syntaxhighlight lang="python">
with open(nomdefichier, "rt") ad fichier:
contenu = fichier.read()
contenu = contenu.splitlines()
contenu = [item.split(" ") for item in contenu
contenu = contenu[1:] # élimine la première ligne
x = np.array([float(ligne[0]) for ligne in contenu])
V = np.array([float(ligne[3]) for ligne in contenu])
donnees = np.concatenate((x.reshape(-1, 1), V.reshape(-1, 1)), axis=1) # matrice [[x], [V]]
ind = np.argsort(donnees[:, 0])
donnees = donnees[ind, :] # matrice triée
plt.plot(donnees[:, 0], donnees[:, 1])
</syntaxhighlight>
{{note|Pour le tri, voir [[../Manipulation_de_matrices#Fonctions_et_méthodes_de_base|''Manipulation de matrices'' > ''Fonctions et méthodes de base'']].}}
=== Cas d'un fichier CSV ===
Si le fichier CSV ne contient que des valeurs numériques, on peut utiliser :
<syntaxhighlight lang="python">
valeurs = np.loadtxt(chemin+nomfic, delimiter=",") # si le séparateur est une virgule
</syntaxhighlight>
Il existe un module <code lang="python">csv</code> dédié aux fichiers CSV. La manipulation du fichier se fait comme suit :
<syntaxhighlight lang="python">
import csv
with open(chemin+nomfic, "rt") as fichier:
lecteur = csv.reader(fichier, delimiter=",")
contenu = [ligne for ligne in lecteur]
print(contenu)
</syntaxhighlight>
=== Utilisation de Pandas ===
Pandas<ref>https://pandas.pydata.org/</ref> est un module gérant les tableaux de données, appelés <em lang="en">data frames</em>. Voici quelques commandes utiles :
<syntaxhighlight lang="python">
import numpy as np
import pandas as pd
M = np.random.rand(10, 10) # crée une matrice NumPy aléatoire de dimension 10 × 10
tableau = pd.DataFrame(M) # transforme la matrice en tableau DataFrame
tableau.to_csv("tableau.csv") # enregistre le tableau dans un fichier CSV
donnees = pd.read_csv("tableau.csv").to_numpy() # lit le fichier et transforme le tableau DataFrame en matrice NumPy
</syntaxhighlight>
Si on ne veut pas d'entête lorsque l'on écrit le fichier CSV, on ajoute l'attribut <code>header = False</code> :
<syntaxhighlight lang="python">
tableau.to_csv("tableau.csv", header = False) # enregistre le tableau dans un fichier CSV sans entête
donnees = pd.read_csv("tableau.csv").to_numpy() # lit le fichier et transforme le tableau DataFrame en matrice NumPy
</syntaxhighlight>
Par défaut, la fonction <code>pd.read_csv()</code> considère que le séparateur est une virgule, et la commande <code>pd.read_table()</code> que c'est une tabulation. On peut définir le séparateur avec le paramètre <code>sep</code> :
<syntaxhighlight lang="python">
donnees = pd.read_csv("tableau.csv", sep=";")
</syntaxhighlight>
On peut utiliser les séparateurs spéciaux :
* <code>\t</code> : tabulation ;
* <code>\s+</code> : nombre arbitraire d'espaces.
On peut par ailleurs utiliser les paramètres suivants :
* <code>dialect</code> : syntaxe du fichier, par exemple <code>dialect = "excel"</code> ;
* <code>nrows</code> (entier) : nombre de lignes lues ;
* <code>skiprows</code> (entier) : nombre de lignes sautées (non lues) en début de fichier ;
* <code>header</code> (entier) : numéro de ligne utilisé pour l'en-tête, par exemple <code>header = 0</code> pour la première ligne ;
* <code>skip_blank_lines</code> (booléen) : si la valeur est vraie (<code>True</code>), ne lit pas les lignes vide ; sinon, met une valeur <code>nan</code>.
Par exemple :
<syntaxhighlight lang="python">
donnees1 = pd.read_csv("tableau.csv", nrows=1, sep="\s+").to_numpy()
donnees2 = pd.read_csv("tableau.csv", skiprows=3, sep="\s+").to_numpy()
</syntaxhighlight>
{{voir|{{lien web |url=https://pandas.pydata.org/docs/user_guide/io.html |titre=IO tools (text, CSV, HDF5, …) |site=Pandas |consulté le=2026-05-06}} }}
== Exporter un programme Python ==
Vous pouvez créer un fichier « Python pur » <code>.py</code>. Pour cela, dans le menu <code>fichier/file</code> de Jupyter, choisir <code>télécharger/download</code> au format <code>.py</code> ; le fichier se trouve alors dans le répertoire de téléchargement du navigateur.
== Recommandations ==
Les recommandations de programmation sont générales et ne sont en grande partie pas spécifiques à Python.
{{voir|[[Découvrir_Scilab/Programmation#Recommandations]]}}
== Ressources ==
* {{lien web
| url = https://www.python.org/dev/peps/pep-0008/
| titre = PEP 8 -- Style Guide for Python Code
| site = Python documentation
| consulté le = 2019-03-14
}}
== Notes et références ==
{{références}}
----
[[../Fonctions mathématiques générales|Fonctions mathématiques générales]] < [[../|↑]] > [[../Graphiques|Graphiques]]
{{DEFAULTSORT:Elements de programmation}}
[[Catégorie:Python pour le calcul scientifique (livre)]]
418nowqlnzcsbg8550uu98e55jt3d7w
Python pour le calcul scientifique/Manipulation de matrices
0
72889
769323
769250
2026-07-03T10:47:10Z
Cdang
1202
/* Trouver une valeur */ intersect1d
769323
wikitext
text/x-wiki
Les matrices sont un élément primordial du calcul scientifique sur ordinateur pour deux raisons :
# L'algèbre linéaire est au cœur de nombreux calculs.
# Les matrices sont l'élément de base du calcul vectorisé qui permet un gain de temps appréciable.
Pour pouvoir expliter les matrices, il faut charger le module NumPy ; nous utilisons également Matplotlib pour les graphiques. Ainsi, les programmes contiennent tous au début :
<syntaxhighlight lang="python">
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as plt
</syntaxhighlight>
== Rappels et complément sur le tranchage ==
Soit une liste L composée de ''n'' éléments.
* Les éléments sont numérotés de 0 à ''n'' – 1.
* Le premier élément s'obtient par <code lang="python">L[0]</code>.
* Le i-ème élément s'obtient par <code lang="python">L[''i'' - 1]</code>.
* L'avant-dernier élément s'obtient par <code lang="python">L[-2]</code>.
* Le dernier élément s'obtient par <code lang="python">L[-1]</code>.
* La sous-liste composée des éléments contigus ''i'' à ''j'' s'obtient par <code lang="python">L[''i'' - 1:j]</code>.
Ainsi, <code lang="python">L[0:1]</code> va extraire le premier élément, <code lang="python">L[1:-1]</code> va extraire tous les éléments sauf le premier et le dernier.
{{voir|[[Python_pour_le_calcul_scientifique/Découverte_de_Python_et_de_Jupyter#Itérable|Découverte_de_Python_et_de_Jupyter > Itérable]]}}
NumPy fournit des fonctions permettant de manipuler les matrices :
* <code lang="python">np.append(A, B)</code> : fusionne les vecteurs A et B ;<br /> s'il s'agit de matrices ou de tenseurs, la fonction les « aplatit », les transforme en vecteur ;<br />si l'on veut intégrer B dans A, on utilise <code lang="python">A = np.append(A, B)</code> ;
* <code lang="python">np.append(A, B, axis = ''i'')</code> : fusionne les tenseurs selon l'indice ''i'' (<code>0</code> pour le premier indice, <code>1</code> pour le deuxième…) ;
* <code lang="python">np.insert(A, i, m)</code> : insère le vecteur ''m'' dans le vecteur A (ou la matrice A aplatie) à l'emplacement ''i'' ;
* <code lang="python">np.insert(A, i, M, axis = ''j'')</code> : insère le tenseur M dans le tenseur A à l'emplacement ''i'' de l'indice ''j'' ;
* <code lang="python">np.delete(A, I)</code> : efface les éléments définis par le tranchage I du vecteur A (ou de la matrice A aplatie) ;
* <code lang="python">np.delete(A, I, axis = ''j'')</code> : efface les éléments définis par le tranchage I selon l'indice ''j'' du tenseur A.
<syntaxhighlight lang="Python">
A = np.array([[1]])
B = np.array([[2, 3, 4]])
C = np.append(A, B, axis=1)
print(A, B, C, sep="\n")
# [[1]]
# [[2 3 4]]
# [[1 2 3 4]]
D = np.array([[10, 20, 30, 40]])
E = np.append(C, D, axis=0)
print(E)
# [[ 1 2 3 4]
# [10 20 30 40]]
</syntaxhighlight>
On peut utiliser <code>np.r_[A, B]</code> pour concaténer A et B en ligne ''(row), et <code>np.c_[A, B]</code> pour les concaténer en colonne.
On peut extraire une sous-matrice à partir d'une matrice de booléens :
<syntaxhighlight lang="Python">
A = np.array([[1, 2], [3, 4], [5, 6]])
booleen = np.logical_or(A==1, A==3)
print(booleen)
# [[ True False]
# [ True False]
# [ False False]]
print(A[booleen])
# [1 3]
booleen = np.logical_or(A[:, 0]==1, A[:, 0]==3)
print(booleen)
# [ True True False]
print(A[booleen])
# [[1 2]
# [3 4]]
print(A[booleen][:, 1])
# [2 4]
</syntaxhighlight>
== Différence entre ''array'' et ''matrix'' ==
Il existe deux types d'objet NumPy pour décrire les matrices : les objets ''array'' (tableau, classe <code>ndarray</code>) et les objets ''matrix'' (matrice, classe <code>matrix</code>).
<syntaxhighlight lang="Python">
A = np.array([[1, 2], [3, 4], [5, 6]])
B = np.matrix([[1, 2], [3, 4], [5, 6]])
</syntaxhighlight>
Il y a trois différences :
* les objets ''array'' peuvent être de n'importe quelle dimension : 0 (scalaire), 1 (vecteur), 2 (matrice), 3 (tenseur d'ordre 3)… alors qu'un objet ''matrix'' est nécessairement de dimension 2 ;
* les opération sur les objets ''matrix'' sont par défaut des opérations matricielles ; ainsi, la multiplication <code>A * B</code> va être une multiplication terme à terme si A et B sont des ''array'', et une multiplication matricielle si A et B sont des ''matrix'' ; pour avoir la multiplication matricielle entre ''array'', il faut utiliser <code>a@b</code> ou <code>np.dot(a,b)</code> ;
* si une matrice A est inversible, alors avec un objet ''matrix'', on peut utiliser la méthode <code>A.I</code> ; si A est un objet ''array'', il faut utiliser <code>np.linalg.inv(A)</code>.
La classe <code>matrix</code> a été dépréciée, il est recommandé de n'utiliser que la classe <code>ndarray</code>. Nous n'utiliserons donc pas la classe <code>matrix</code>.
== Définir un tenseur ==
Un tenseur est similaire à une liste mais il est défini par la fonction <code>np.array()</code>. La définition et l'extraction de composante utilise la méthode du découpage en tranches ''({{lang|en|slicing}})''.
'''Exemples'''
<syntaxhighlight lang="python">
a = np.array([1, 3, 5, 7]) # vecteur
bc = np.array([[1], [2], [3], [4]]) # matrice 4 × 1 (matrice colonne)
bl = np.array([[1, 2, 3, 4]]) # matrice 1 × 4 (matrice ligne)
c = np.array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5]]) # matrice 3 × 3
d = np.array([[[1, 2, 3],
[2, 3, 4]],
[[10, 9, 8],
[ 7, 6, 5]]]) # tenseur d'ordre 3, de dimension 3 × 2 × 2
</syntaxhighlight>
Notez que dans NumPy, un vecteur n'est pas la même chose qu'une matrice ligne ou colonne. Un vecteur de dimension ''n'' est un tenseur d'ordre 1 et de dimension ''n'' ; une matrice ligne ou colonne est un tenseur d'ordre 2 et de dimension 1 × ''n'' ou ''n'' × 1.
<syntaxhighlight lang="python">
a = np.array([1, 2, 3])
b = np.array([[1, 2, 3]])
c = np.array([[1], [2], [3]])
print(a.size, b.size, c.size) # 3 3 3
print(a.ndim, b.ndim, c.ndim) # 1 2 2
print(a.shape, b.shape, c.shape) # (3,) (1, 3) (3, 1)
</syntaxhighlight>
La fonction <code>np.arange()</code> est similaire à la fonction <code>range()</code> pour les liste ; elle génère un vecteur de réels. La fonction <code>np.linspace()</code> permet également de créer un vecteur de même type, mais on indique le dernier nombre alors que la règle du découpage en tranches fait que le nombre maximal indiqué à <code>np.arange()</code> est le premier nombre qui ne ''figure pas'' dans le vecteur.). La fonction <code>np.zeros()</code> génère une matrice nulle, <code>np.zeros_like()</code> une matrice nulle ayant les dimensions d'une matrice fournie comme modèle. De même, <code>np.ones()</code> et <code>np.ones_like()</code> crée des matrices, dont toutes les composantes sont à 1. La fonction <code>np.eye()</code> crée une matrice unité.
'''Exemples'''
<syntaxhighlight lang="python">
e = np.arange(0, 2, 0.1) # vecteur [0, 0.1, 0.2…, 1.8, 1.9]
f = np.linspace(0, 2, 5) # 5 nombres entre 0 et 2 soit le vecteur [0, 0.5, 1, 1.5, 2]
g = np.zeros(3) # vecteur nul de dimension 3
h = np.zeros((3, 3)) # matrice nulle 3 × 3
k = np.ones_like(a) # matrice de 1 de même dimension que a
u = np.eye(3) # matrice unité 3 × 3
</syntaxhighlight>
Le paramètre <code>dtype</code> permet de forcer le type. Par exemple
<syntaxhighlight lang="python">
a = np.array([1, 2, 3], dtype="complex")
k = np.ones_like(a, dtype="int")
</syntaxhighlight>
La commande <code>np.linspace()</code> peut créer des matrices colonne : on donne la première et la dernière ligne ; par exemple : :
<syntaxhighlight lang="python">
np.linspace([1, -1], [10, -10], 4)
# [[ 1. -1.]
# [ 4. -4.]
# [ 7. -7.]
# [ 10. -10.]]
</syntaxhighlight>
Les commandes <code>np.geomspace()</code> et <code>np.geomspace()</code> fonctionnent comme <code>np.linspace()</code>, mais avec une progression logarithmique. La commande <code>np.geomspace(a, b, n)</code> crée un vecteur (ou une matrice colonne) allant de ''a'' à ''b'' alors que <code>np.logspace(a, b, n)</code> crée un vecteur (ou une matrice colonne) allant de 10<sup>''a''</sup> à 10<sup>''b''</sup>.
La méthode <code>.reshape()</code> remet en forme une matrice. Par exemple, pour transformer un vecteur de dimension 9 en une matrice 3 × 3 :
<syntaxhighlight lang="python">
a = np.arange(1, 10)
b = a.reshape(3, 3)
# ou bien directement
c = np.arange(1, 10).reshape(3, 3)
</syntaxhighlight>
Avec la méthode <code>.reshape()</code>, on peut utiliser la valeur –1 pour une des dimensions ; sa valeur est alors automatiquement calculée en fonction du nombre d'éléments et de l'autre dimension. On peut aussi utiliser une dimension vide ; cela crée alors un vecteur. Par exemple, pour une matrice M quelconque :
<syntaxhighlight lang="python">
M.reshape(-1, 1) # crée une matrice colonne
M.reshape(1, -1) # crée une matrice ligne
M.reshape(-1,) # crée un vecteur
</syntaxhighlight>
La méthode <code>.fill()</code> remplit la matrice avec un scalaire :
<syntaxhighlight lang="python">
b.fill(5) # remplace les valeurs de b par la valeur 5
</syntaxhighlight>
== Extraction matricielle ==
Si l'on veut extraire les colonnes 1 et 3 pour toutes les lignes d'une matrice M, on utilise :
<syntaxhighlight lang="python">
M[:, [0, 2]]
</syntaxhighlight>
== Trouver une valeur ==
Pour trouver une valeur, on utilise la fonction <code>where()</code> :
<syntaxhighlight lang="python">
A = np.array([[1, 2], [3, 4]])
print(A)
# [[1 2]
# [3 4]]
B = np.where(A == 3)
print(B)
# (array([1]), array([0])
print(B[0][0], B[1][0])
# 1 0
C = np.where(A == 5)
print(C)
# (array([], dtype=int64), array([], dtype=int64))
# C est un n-uplet (tuple) contenant deux vecteurs d'entiers vides.
print(len(C[0])) # taille du premier vecteur du n-uplet C
# 0
</syntaxhighlight>
Notez que <code>where()</code> peut servir à construire une matrice à partir de deux autres matrices selon une condition. Par exemple, pour comparer les éléments deux à deux et sélectionner le plus grand :
<syntaxhighlight lang="python">
A = np.array([[1, 2], [3, 4]])
B = np.array([[0, 1], [4, 5]])
C = np.where(A > B, A, B)
print(C)
# [[1 2]
# [4 5]
</syntaxhighlight>
La syntaxe générale est <code>C = np.where(condition, A, B)</code> où <code>condition</code> est une matrice de booléens ; pour un indice (''i'', ''j''), si <code>condition[i, j]</code> est vrai, alors <code>C[i, j]</code> vaut <code>A[i, j]</code>, sinon elle vaut <code>B[i, j]</code>.
La fonction <code>np.intersect1d()</code> permet de comparer deux vecteurs — s'il s'agit de matrices, elles sont aplaties — matrices et de chercher les éléments qui sont communs aux deux : <code>np.intersect1d(A, B)</code> donne un vecteur contenant les valeurs communes. Si l'on veut les indices des premières occurrences, on ajoute le paramètre <code>return_indices = True</code> :
<syntaxhighlight lang="python">
(valeurs, indices1, indices2) = np.intersect1d(A, B, return_indices = True)
print(all(A[indices1] == B[indices2]))
# True
</syntaxhighlight>
== Assemblage de matrices ==
Si l'on veut regrouper deux matrices, on utilise la commande <code>np.concatenate()</code>. On utilise le paramètre ''axis'' pour indiquer si l'on empile les matrices l'une au-dessus de l'autre (<code>axis=0</code>) ou bien l'une derrière l'autre (<code>axis=1</code>). Par exemple :
<syntaxhighlight lang="python">
A = np.array([[1 ,2], [3, 4]])
B = np.array([[5 ,6], [7, 8]])
C = np.concatenate((A, B), axis = 0)
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
D = np.concatenate((A, B), axis = 1)
# [[1 2 5 6]
# [3 4 7 8]]
</syntaxhighlight>
Si l'on veut transformer deux vecteurs en une matrice de deux colonnes, chaque vecteur occupant une colonne :
<syntaxhighlight lang="python">
A = np.array([1 ,2])
B = np.array([3 ,4])
C = np.concatenate((A.reshape(-1, 1), B.reshape(-1, 1)), axis = 1)
# [[1 3]
# [2 4]]
</syntaxhighlight>
== Opérations matricielles ==
Les quatre opérations classiques <code lang="python>+</code>, <code lang="python>-</code> et <code lang="python>/</code> ne fonctionnent qu'entre tenseurs de mêmes dimensions et sont des opérations élément par élément ''({{lang|en|elementwise operations}})'' :
* <code lang="python">(A + B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] + B[i, j, k]</code> ;
* <code lang="python">(A - B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] - B[i, j, k]</code> ;
* <code lang="python">(A / B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] / B[i, j, k]</code>.
La multiplication élément par élément se fait avec
: <code lang="python">np.multiply(A, B)</code> qui vaut <code lang="python">A[i, j, k] * B[i, j, k]</code>.
De même, les fonctions <code lang="python>np.add()</code>, <code lang="python>np.subtract()</code>, <code lang="python>np.multiply()</code> et <code lang="python>np.divide()</code> effectuent des opérations élément par élément sur des tenseurs de mêmes dimensions :
* <code lang="python">np.add(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] + B[i, j, k]</code> ;
* <code lang="python">np.subtract(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] - B[i, j, k]</code> ;
* <code lang="python">np.multiply(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] * B[i, j, k]</code> ;
* <code lang="python">np.divide(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] / B[i, j, k]</code>.
La multiplication matricielle, au sens de l'algèbre linéaire, se fait avec les fonctions <code lang="python">np.dot()</code> ou <code lang="python">np.matmul()</code>, ou bien avec l'opérateur <code>@</code>.
<syntaxhighlight lang="python">
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(a @ b) # np.matmul(a, b)
# [[19 22]
# [43 50]]
</syntaxhighlight>
Pour un poduit scalaire :
<syntaxhighlight lang="python">
A = np.array([1, 2, 3])
B = np.array([4, 5, 6])
# 32
</syntaxhighlight>
Notez que :
* pour le produit par un scalaire, les fonctions <code lang="python">np.multiply()</code> et l'opérateur <code lang="python">*</code> sont plus performants ;
* la fonction <code lang="python">np.dot()</code> est plus performante pour le produit scalaire de deux vecteurs réels ;
* lorsque l'on a des vecteurs complexes, la fonction <code lang="python">np.vdot()</code> fait le produit par le conjugué du premier membre (<code lang="python">np.vdot(a, b) == np.dot(a.conj(), b)</code>) ;
* la fonction <code lang="python">np.matmul()</code> et l'opérateur <code lang="python">@</code> (<code lang="python">A @ B</code>) sont plus performants pour un produit matriciel.
L'opérateur <code>@=</code> fait un produit matriciel en modifiant la variable elle-même (à l'image de <code>*=</code> pour les nombres).
== Calcul vectorisé ==
Les fonctions de NumPy traitent en général les matrices en entier. Ainsi, il n'est pas nécessaire de créer une boucle pour faire défiler les indices un par un. Il en résulte un code clair et compact et surtout un plus grande rapidité d'exécution. Par exemple :
<syntaxhighlight lang="python">
x = np.linspace(0, 2*np.pi, 50) # 50 points entre 0 et 2π
y = np.sin(x)
plt.plot(x, y)
</syntaxhighlight>
La variable <code>x</code> est un vecteur de 50 valeurs et il est traité en une seule passe par la fonction sinus <code>np.sin()</code>.
Outre le tranchage ''({{lang|en|slicing}})'', on peut utiliser deux autres méthodes pour extraire certaines valeurs d'une matrice :
* utiliser un vecteur ou une matrice d'indices, Python extrait alors les valeurs correspondant aux indices ;
* utiliser un vecteur ou une matrice de booléens de même dimension que a matrice ; Python extrait alors les valeurs correspondant aux <code>True</code>, la matrice booléenne est un « masque » pour la matrice d'origine. Par exemple :
<syntaxhighlight lang="python">
a = np.arange(0, 10)
b = np.array([1, 3, 5, 7, 9])
c = np.array([True, True, False, False, True, False, True, False, False, True])
print(a[b], "\n", a[c])
</syntaxhighlight>
Si l'on veut inverser tous les éléments d'une matrice de bolléens, il faut utiliser la fonction <code>np.logical_not()</code>
'''Exercice'''
Écrire un programme Python mettant en œuvre le [[w:crible d'Érathostène|crible d'Érathostène]] pour trouver les nombres premiers inférieurs à une valeur donnée.
{{boîte déroulante début|Solution}}
<syntaxhighlight lang="python">
#!/usr/bin/env python
# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def eratosthene(limite):
# Détermine la liste des nombres premiers entre 1 et N
# par le crible d'Ératosthène
# Entrées : limite : nombre entier, N
# Sorties : liste : vecteur d'entiers,liste des nombres premiers
indices = (np.ones(limite) == 1) # vecteur de booléens tous à True
# à la fin, indice(i-1) est True si i est premier, False sinon
indices[0]=False # 1 n'est pas premier
imax = int(limite)
i = 2 # initialisation
repete = (i <= imax)
while repete:
if indices[i-1]:
jmax = int(limite/i)
j = np.arange(1, jmax)+1
indices[i*j-1]=False # élimination des multiples de i
test = (i*jmax == imax)
i = i + 1
repete = i*i < limite # condition d'arrêt
liste0 = np.arange(limite)
liste = liste0[indices]+1
return liste
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
print("***** Recherche de nombres premiers par le crible d'Ératosthène *****\n")
nmax = eval(input("Entrez la valeur maximale : "))
resultat = eratosthene(nmax)
print("\n", resultat.shape[0], "nombres premiers entre 1 et", nmax, ":\n")
print(resultat)
plt.plot(resultat, np.zeros_like(resultat), "|")
</syntaxhighlight>
L'extraction par un vecteur d'indice intervient dans l'instruction :
<syntaxhighlight lang="python">
indices[i*j-1]=False
</syntaxhighlight>
qui élimine en une seule passe tous les multiples de ''i''. L'extraction par un vecteur booléen intervient dans l'instruction :
<syntaxhighlight lang="python">
liste = liste0[indices]+1
</syntaxhighlight>
qui permet d'extraire toutes la valeurs conservées en une seule passe.
{{boîte déroulante fin}}
== Attributs ==
La classe <code>ndarray</code>, qui définit les matrices, possède un certain nombre d'attributs :
* <code>.shape</code> : dimensions de la matrice ;
* <code>.ndim</code> : ordre du tenseur ;
* <code>.size</code> : nombre d'éléments ;
* <code>.dtype</code> : type des éléments.
<syntaxhighlight lang="python">
a = np.linspace(1, 9, 9)
print("a", a, "\n",
" ; shape :", a.shape,
" ; dim : ", a.ndim,
" ; size : ", a.size,
" ; dtype : ", a.dtype, "\n")
</syntaxhighlight>
* <code>.real</code>, <code>.imag</code> : parties réelle et imaginaire de la matrice ;
* <code>.flat</code> : liste des éléments de la matrice ; les éléments sont réorganisés en une liste ;
* <code>.T</code> : transposée.
<syntaxhighlight lang="python">a = np.arange(0, 9).reshape(3, 3)
print(a)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
print(a.T)
# [[0 3 6]
# [1 4 7]
# [2 5 8]]
print(a.flat[:])
# array([0, 1, 2, 3, 4, 5, 6, 7, 8])
</syntaxhighlight>
; Ressources
: Section « Attribute », {{lien web
| url = https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html
| titre = numpy.ndarray
| site = Numpy and Scipy Documentation
| consulté le = 2019-03-16
}}
== Fonctions et méthodes de base ==
La classe <code>ndarray</code> possède un certain nombre de méthodes :
* <code>.min()</code> et <code>.max()</code> : valeurs respectivement minimale et maximale ;
* <code>.ptp()</code> : amplitude « max – min » ''({{lang|en|peak to peak}})'' ;
* <code>.argmin()</code> et <code>argmax()</code> : indice où se trouvent les valeurs respectivement minimale et maximale ;
* <code>.sum()</code>, <code>prod()</code> : somme et produit de tous les éléments de la matrice ;
* <code>.cumsum()</code>, <code>cumprod()</code> : somme et produit cumulés.
<syntaxhighlight lang="python">
a = np.linspace(1, 9, 9)
print("min : ", a.min(),
"; max : ", a.max(), "\n",
"sum : ", a.sum(),
"; cumsum : ", a.cumsum(), "\n",
"prod : ", a.prod(),
"; cumprod : ", a.cumprod(), "\n")
</syntaxhighlight>
Méthodes statistiques :
* <code>.mean()</code> : moyenne ;
* <code>.std()</code> : écart type ''({{lang|en|standard deviation}})''.
{{loupe|../Statistiques}}
Extraction de données :
* <code>.diagonal()</code> : vecteur contenant les éléments de la diagonale ;
* <code>.flatten()</code> : matrice « aplatie », c'est-à-dire vecteur contenant les éléments réorganisés en liste ; par rapport à l'attribut <code>.flat</code>, on peut choisir le sens de linéarisation (par lignes, <code>.flatten(C)</code>, ou par colonnes, <code>.flatten(F)</code>) mais cela crée une copie, on ne peut pas par exemple s'en servir pour modifier la matrice ;
* <code>.tofile()</code> : crée un fichier texte contenant les valeurs de la matrice ; par exemple, pour une matrice <code>a</code> et pour séparer les valeurs par un point-virgule :
<syntaxhighlight lang="python">
a.tofile("matriceA.txt", sep=" ; ")
</syntaxhighlight>
* <code>.astype(''type'')</code> : copie la matrice en convertissant le type de données :
<syntaxhighlight lang="python">
a = a.astype(float) # pour avoir une matrice de réels en virgule flottante
a = a.astype(str) # pour avoir une matrice de chaînes de caractères
</syntaxhighlight>
Tri :
* <code>np.sort(M, i)</code> : crée une copie et trie la matrice selon l'axe ''i'' (0 pour le premier indice, 1 pour le deuxième… la valeur par défaut est –1 pour le dernier indice, la valeur ''none'' aplatit la matrice) ; <code>np.sort(M, 0)</code> trie chaque colonne indépendamment par ordre croissant, <code>np.sort(M, 1)</code> trie chaque ligne indépendamment par ordre croissant ;
* <code>M.sort(i)</code> : cette méthode trie la matrice en elle-même ;
* <code>np.argsort(M, i)</code> : crée une matrice contenant le nouvel indice, selon l'axe ''i'', de chaque élément.
<syntaxhighlight lang="python">
M = np.array([[1, 5, 7, 5], [2, 9, 4, 3], [9, 1, 7, 5]])
M.sort(1) # tri des lignes indépendamment -> [[1, 5, 5, 7], [2, 3, 4, 9], [1, 5, 7, 9]]
</syntaxhighlight>
Pour trier les lignes selon la deuxième colonne d'une matrice, tout en conservant les lignes intactes, on peut faire comme suit :
<syntaxhighlight lang="python">
M = np.array([[1, 5, 7, 5], [2, 9, 4, 3], [9, 1, 7, 5]])
ind = np.argsort(M[:, 1]) # indices de tri selon la 2e colonne
N = M[ind, :] # réarrangement des lignes -> [[9, *1*, 7, 5], [1, *5*, 7, 5], [2, *9*, 4, 3]]
</syntaxhighlight>
Pour faire un tri lexicographique, on utilise la fonction <code>np.lexsort()</code> en indiquant les différentes colonnes :
<syntaxhighlight lang="python">
M = np.array([[1, 5, 7, 5], [2, 9, 4, 3], [9, 1, 7, 5], [2, 9, 8, 5]])
ind = np.lexsort((M[:, 3], M[:, 2], M[:, 1], M[:, 0])) # indices de tri selon la 1re, puis la 2e, puis la 3e, puis la 4e colonne
N = M[ind, :] # réarrangement des lignes -> [[1, 5, 7, 5], [2, 9, 4, 3], [2, 9, 8, 5], [9, 1, 7, 5]]
</syntaxhighlight>
Le tri se fait par ordre croissant. Pour trier par ordre décroissant, on inverse l'ordre de la matrice en faisant une extraction avec un pas de moins un, par exemple pour inverser les lignes :
<syntaxhighlight lang="python">
M = M[:, ::-1]
</syntaxhighlight>
Algèbre linéaire :
* <code>a.dot(b)</code> : produit matriciel ''a''⋅''b'' ; on peut aussi écrire <code>a@b</code> ;
* <code>.trace()</code> : trace de la matrice (somme des éléments diagonaux) ;
* <code>.transpose()</code> : transpose la matrice, résultat similaire à l'attribut <code>.T</code> ;
* <code>np.cross()</code> : produit vectoriel dans ℝ³.
{{loupe|../Algèbre linéaire}}
Matrices de booléens :
* <code>.all()</code> : applique un « et » logique à toutes les valeurs de la matrice ;
* <code>.any()</code> : applique un « ou » logique à toutes les valeurs de la matrice.
{{loupe|../Fonctions mathématiques générales#Fonctions booléennes}}
Autre méthodes :
* <code>.conj()</code> : conjugué des valeurs complexes ;
* <code>.nonzero()</code> : n-uplet contenant les indices des valeurs non-nulles ;
* <code>.round(n)</code> : arrondit les valeurs à la ''n''-ième décimale.
; Ressources
: Section « Method », {{lien web
| url = https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html
| titre = numpy.ndarray
| site = Numpy and Scipy Documentation
| consulté le = 2019-03-16
}}
== Propagation ==
Le terme « propagation » ''({{lang|en|broadcasting}})'' désigne la manière dont Python complète les matrice lorsque des dimensions manquent.
Supposons que l'on veuille additionner deux matrices M<sub>1</sub> et M<sub>2</sub> de dimensions ''m''<sub>1</sub> × ''n''<sub>1</sub> et ''m''<sub>2</sub> × ''n''<sub>2</sub> différentes. Alors :
* le résultat a pour dimension max(''m''<sub>1</sub>, ''m''<sub>2</sub>) × max(''n''<sub>1</sub>, ''n''<sub>2</sub>) ;
* si une des dimensions vaut 1, alors les valeurs de l'autre dimension sont dupliquées ;
* sinon, les dimensions manquantes pour chaque matrice sont complétées par des 1.
Par exemple :
: <math>\mathrm{A} = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
: <math>5 + \mathrm{A} = \begin{pmatrix} 5 & 5 \\ 5 & 5 \end{pmatrix} + \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
:: La matrice (5) est de dimension 1 × 1, la valeur « 5 » est donc répétée dans les deux dimensions
<syntaxhighlight lang="python">
A = np.array([[1, 2], [3, 4]])
print(5 + A)
# [[6 7]
# [7 8]]
</syntaxhighlight>
: <math>(5, 4) + \mathrm{A} = \begin{pmatrix} 5 & 4 \\ 5 & 4 \end{pmatrix} + \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
<syntaxhighlight lang="python">
print(np.array([[5, 4]]) + A)
# [[6 6]
# [6 8]]
</syntaxhighlight>
: <math>\begin{pmatrix} 5 \\ 4 \end{pmatrix} + \mathrm{A} = \begin{pmatrix} 5 & 5 \\ 4 & 4 \end{pmatrix} + \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
<syntaxhighlight lang="python">
print(np.array([[5], [4]]) + A)
# [[6 7]
# [7 8]]
</syntaxhighlight>
== Fonctions « universelles » ==
Les fonctions universelles ''({{lang|en|ufunc}})'' sont les fonctions s'appliquant aux matrices, des fonctions vectorisées.
; Ressource
: {{lien web
| url = https://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs
| titre = Available ufuncs
| site = SciPy documentation
| consulté le = 2019-03-21
}}
== Algèbre linéaire ==
{{loupe|../Algèbre linéaire}}
== Notes et références ==
{{références}}
----
[[../Graphiques|Graphiques]] < [[../|↑]] > [[../Polynômes|Polynômes]]
[[Catégorie:Python pour le calcul scientifique (livre)]]
ofqpl6vukzq9usplarw3gmhlsb6b41z
769324
769323
2026-07-03T10:52:17Z
Cdang
1202
/* Définir un tenseur */ np.empty
769324
wikitext
text/x-wiki
Les matrices sont un élément primordial du calcul scientifique sur ordinateur pour deux raisons :
# L'algèbre linéaire est au cœur de nombreux calculs.
# Les matrices sont l'élément de base du calcul vectorisé qui permet un gain de temps appréciable.
Pour pouvoir expliter les matrices, il faut charger le module NumPy ; nous utilisons également Matplotlib pour les graphiques. Ainsi, les programmes contiennent tous au début :
<syntaxhighlight lang="python">
#!/usr/bin/python3
import numpy as np
import matplotlib.pyplot as plt
</syntaxhighlight>
== Rappels et complément sur le tranchage ==
Soit une liste L composée de ''n'' éléments.
* Les éléments sont numérotés de 0 à ''n'' – 1.
* Le premier élément s'obtient par <code lang="python">L[0]</code>.
* Le i-ème élément s'obtient par <code lang="python">L[''i'' - 1]</code>.
* L'avant-dernier élément s'obtient par <code lang="python">L[-2]</code>.
* Le dernier élément s'obtient par <code lang="python">L[-1]</code>.
* La sous-liste composée des éléments contigus ''i'' à ''j'' s'obtient par <code lang="python">L[''i'' - 1:j]</code>.
Ainsi, <code lang="python">L[0:1]</code> va extraire le premier élément, <code lang="python">L[1:-1]</code> va extraire tous les éléments sauf le premier et le dernier.
{{voir|[[Python_pour_le_calcul_scientifique/Découverte_de_Python_et_de_Jupyter#Itérable|Découverte_de_Python_et_de_Jupyter > Itérable]]}}
NumPy fournit des fonctions permettant de manipuler les matrices :
* <code lang="python">np.append(A, B)</code> : fusionne les vecteurs A et B ;<br /> s'il s'agit de matrices ou de tenseurs, la fonction les « aplatit », les transforme en vecteur ;<br />si l'on veut intégrer B dans A, on utilise <code lang="python">A = np.append(A, B)</code> ;
* <code lang="python">np.append(A, B, axis = ''i'')</code> : fusionne les tenseurs selon l'indice ''i'' (<code>0</code> pour le premier indice, <code>1</code> pour le deuxième…) ;
* <code lang="python">np.insert(A, i, m)</code> : insère le vecteur ''m'' dans le vecteur A (ou la matrice A aplatie) à l'emplacement ''i'' ;
* <code lang="python">np.insert(A, i, M, axis = ''j'')</code> : insère le tenseur M dans le tenseur A à l'emplacement ''i'' de l'indice ''j'' ;
* <code lang="python">np.delete(A, I)</code> : efface les éléments définis par le tranchage I du vecteur A (ou de la matrice A aplatie) ;
* <code lang="python">np.delete(A, I, axis = ''j'')</code> : efface les éléments définis par le tranchage I selon l'indice ''j'' du tenseur A.
<syntaxhighlight lang="Python">
A = np.array([[1]])
B = np.array([[2, 3, 4]])
C = np.append(A, B, axis=1)
print(A, B, C, sep="\n")
# [[1]]
# [[2 3 4]]
# [[1 2 3 4]]
D = np.array([[10, 20, 30, 40]])
E = np.append(C, D, axis=0)
print(E)
# [[ 1 2 3 4]
# [10 20 30 40]]
</syntaxhighlight>
On peut utiliser <code>np.r_[A, B]</code> pour concaténer A et B en ligne ''(row), et <code>np.c_[A, B]</code> pour les concaténer en colonne.
On peut extraire une sous-matrice à partir d'une matrice de booléens :
<syntaxhighlight lang="Python">
A = np.array([[1, 2], [3, 4], [5, 6]])
booleen = np.logical_or(A==1, A==3)
print(booleen)
# [[ True False]
# [ True False]
# [ False False]]
print(A[booleen])
# [1 3]
booleen = np.logical_or(A[:, 0]==1, A[:, 0]==3)
print(booleen)
# [ True True False]
print(A[booleen])
# [[1 2]
# [3 4]]
print(A[booleen][:, 1])
# [2 4]
</syntaxhighlight>
== Différence entre ''array'' et ''matrix'' ==
Il existe deux types d'objet NumPy pour décrire les matrices : les objets ''array'' (tableau, classe <code>ndarray</code>) et les objets ''matrix'' (matrice, classe <code>matrix</code>).
<syntaxhighlight lang="Python">
A = np.array([[1, 2], [3, 4], [5, 6]])
B = np.matrix([[1, 2], [3, 4], [5, 6]])
</syntaxhighlight>
Il y a trois différences :
* les objets ''array'' peuvent être de n'importe quelle dimension : 0 (scalaire), 1 (vecteur), 2 (matrice), 3 (tenseur d'ordre 3)… alors qu'un objet ''matrix'' est nécessairement de dimension 2 ;
* les opération sur les objets ''matrix'' sont par défaut des opérations matricielles ; ainsi, la multiplication <code>A * B</code> va être une multiplication terme à terme si A et B sont des ''array'', et une multiplication matricielle si A et B sont des ''matrix'' ; pour avoir la multiplication matricielle entre ''array'', il faut utiliser <code>a@b</code> ou <code>np.dot(a,b)</code> ;
* si une matrice A est inversible, alors avec un objet ''matrix'', on peut utiliser la méthode <code>A.I</code> ; si A est un objet ''array'', il faut utiliser <code>np.linalg.inv(A)</code>.
La classe <code>matrix</code> a été dépréciée, il est recommandé de n'utiliser que la classe <code>ndarray</code>. Nous n'utiliserons donc pas la classe <code>matrix</code>.
== Définir un tenseur ==
Un tenseur est similaire à une liste mais il est défini par la fonction <code>np.array()</code>. La définition et l'extraction de composante utilise la méthode du découpage en tranches ''({{lang|en|slicing}})''.
'''Exemples'''
<syntaxhighlight lang="python">
a = np.array([1, 3, 5, 7]) # vecteur
bc = np.array([[1], [2], [3], [4]]) # matrice 4 × 1 (matrice colonne)
bl = np.array([[1, 2, 3, 4]]) # matrice 1 × 4 (matrice ligne)
c = np.array([[1, 2, 3],
[2, 3, 4],
[3, 4, 5]]) # matrice 3 × 3
d = np.array([[[1, 2, 3],
[2, 3, 4]],
[[10, 9, 8],
[ 7, 6, 5]]]) # tenseur d'ordre 3, de dimension 3 × 2 × 2
</syntaxhighlight>
Notez que dans NumPy, un vecteur n'est pas la même chose qu'une matrice ligne ou colonne. Un vecteur de dimension ''n'' est un tenseur d'ordre 1 et de dimension ''n'' ; une matrice ligne ou colonne est un tenseur d'ordre 2 et de dimension 1 × ''n'' ou ''n'' × 1.
<syntaxhighlight lang="python">
a = np.array([1, 2, 3])
b = np.array([[1, 2, 3]])
c = np.array([[1], [2], [3]])
print(a.size, b.size, c.size) # 3 3 3
print(a.ndim, b.ndim, c.ndim) # 1 2 2
print(a.shape, b.shape, c.shape) # (3,) (1, 3) (3, 1)
</syntaxhighlight>
La fonction <code>np.arange()</code> est similaire à la fonction <code>range()</code> pour les liste ; elle génère un vecteur de réels. La fonction <code>np.linspace()</code> permet également de créer un vecteur de même type, mais on indique le dernier nombre alors que la règle du découpage en tranches fait que le nombre maximal indiqué à <code>np.arange()</code> est le premier nombre qui ne ''figure pas'' dans le vecteur.). La fonction <code>np.zeros()</code> génère une matrice nulle, <code>np.zeros_like()</code> une matrice nulle ayant les dimensions d'une matrice fournie comme modèle. De même, <code>np.ones()</code> et <code>np.ones_like()</code> crée des matrices, dont toutes les composantes sont à 1. La fonction <code>np.eye()</code> crée une matrice unité.
La fonction <code>np.empty()</code> crée une matrice dont les valeurs ne sont pas initialisées.
'''Exemples'''
<syntaxhighlight lang="python">
e = np.arange(0, 2, 0.1) # vecteur [0, 0.1, 0.2…, 1.8, 1.9]
f = np.linspace(0, 2, 5) # 5 nombres entre 0 et 2 soit le vecteur [0, 0.5, 1, 1.5, 2]
g = np.zeros(3) # vecteur nul de dimension 3
h = np.zeros((3, 3)) # matrice nulle 3 × 3
k = np.ones_like(a) # matrice de 1 de même dimension que a
u = np.eye(3) # matrice unité 3 × 3
</syntaxhighlight>
Le paramètre <code>dtype</code> permet de forcer le type. Par exemple
<syntaxhighlight lang="python">
a = np.array([1, 2, 3], dtype="complex")
k = np.ones_like(a, dtype="int")
</syntaxhighlight>
La commande <code>np.linspace()</code> peut créer des matrices colonne : on donne la première et la dernière ligne ; par exemple : :
<syntaxhighlight lang="python">
np.linspace([1, -1], [10, -10], 4)
# [[ 1. -1.]
# [ 4. -4.]
# [ 7. -7.]
# [ 10. -10.]]
</syntaxhighlight>
Les commandes <code>np.geomspace()</code> et <code>np.geomspace()</code> fonctionnent comme <code>np.linspace()</code>, mais avec une progression logarithmique. La commande <code>np.geomspace(a, b, n)</code> crée un vecteur (ou une matrice colonne) allant de ''a'' à ''b'' alors que <code>np.logspace(a, b, n)</code> crée un vecteur (ou une matrice colonne) allant de 10<sup>''a''</sup> à 10<sup>''b''</sup>.
La méthode <code>.reshape()</code> remet en forme une matrice. Par exemple, pour transformer un vecteur de dimension 9 en une matrice 3 × 3 :
<syntaxhighlight lang="python">
a = np.arange(1, 10)
b = a.reshape(3, 3)
# ou bien directement
c = np.arange(1, 10).reshape(3, 3)
</syntaxhighlight>
Avec la méthode <code>.reshape()</code>, on peut utiliser la valeur –1 pour une des dimensions ; sa valeur est alors automatiquement calculée en fonction du nombre d'éléments et de l'autre dimension. On peut aussi utiliser une dimension vide ; cela crée alors un vecteur. Par exemple, pour une matrice M quelconque :
<syntaxhighlight lang="python">
M.reshape(-1, 1) # crée une matrice colonne
M.reshape(1, -1) # crée une matrice ligne
M.reshape(-1,) # crée un vecteur
</syntaxhighlight>
La méthode <code>.fill()</code> remplit la matrice avec un scalaire :
<syntaxhighlight lang="python">
b.fill(5) # remplace les valeurs de b par la valeur 5
</syntaxhighlight>
== Extraction matricielle ==
Si l'on veut extraire les colonnes 1 et 3 pour toutes les lignes d'une matrice M, on utilise :
<syntaxhighlight lang="python">
M[:, [0, 2]]
</syntaxhighlight>
== Trouver une valeur ==
Pour trouver une valeur, on utilise la fonction <code>where()</code> :
<syntaxhighlight lang="python">
A = np.array([[1, 2], [3, 4]])
print(A)
# [[1 2]
# [3 4]]
B = np.where(A == 3)
print(B)
# (array([1]), array([0])
print(B[0][0], B[1][0])
# 1 0
C = np.where(A == 5)
print(C)
# (array([], dtype=int64), array([], dtype=int64))
# C est un n-uplet (tuple) contenant deux vecteurs d'entiers vides.
print(len(C[0])) # taille du premier vecteur du n-uplet C
# 0
</syntaxhighlight>
Notez que <code>where()</code> peut servir à construire une matrice à partir de deux autres matrices selon une condition. Par exemple, pour comparer les éléments deux à deux et sélectionner le plus grand :
<syntaxhighlight lang="python">
A = np.array([[1, 2], [3, 4]])
B = np.array([[0, 1], [4, 5]])
C = np.where(A > B, A, B)
print(C)
# [[1 2]
# [4 5]
</syntaxhighlight>
La syntaxe générale est <code>C = np.where(condition, A, B)</code> où <code>condition</code> est une matrice de booléens ; pour un indice (''i'', ''j''), si <code>condition[i, j]</code> est vrai, alors <code>C[i, j]</code> vaut <code>A[i, j]</code>, sinon elle vaut <code>B[i, j]</code>.
La fonction <code>np.intersect1d()</code> permet de comparer deux vecteurs — s'il s'agit de matrices, elles sont aplaties — matrices et de chercher les éléments qui sont communs aux deux : <code>np.intersect1d(A, B)</code> donne un vecteur contenant les valeurs communes. Si l'on veut les indices des premières occurrences, on ajoute le paramètre <code>return_indices = True</code> :
<syntaxhighlight lang="python">
(valeurs, indices1, indices2) = np.intersect1d(A, B, return_indices = True)
print(all(A[indices1] == B[indices2]))
# True
</syntaxhighlight>
== Assemblage de matrices ==
Si l'on veut regrouper deux matrices, on utilise la commande <code>np.concatenate()</code>. On utilise le paramètre ''axis'' pour indiquer si l'on empile les matrices l'une au-dessus de l'autre (<code>axis=0</code>) ou bien l'une derrière l'autre (<code>axis=1</code>). Par exemple :
<syntaxhighlight lang="python">
A = np.array([[1 ,2], [3, 4]])
B = np.array([[5 ,6], [7, 8]])
C = np.concatenate((A, B), axis = 0)
# [[1 2]
# [3 4]
# [5 6]
# [7 8]]
D = np.concatenate((A, B), axis = 1)
# [[1 2 5 6]
# [3 4 7 8]]
</syntaxhighlight>
Si l'on veut transformer deux vecteurs en une matrice de deux colonnes, chaque vecteur occupant une colonne :
<syntaxhighlight lang="python">
A = np.array([1 ,2])
B = np.array([3 ,4])
C = np.concatenate((A.reshape(-1, 1), B.reshape(-1, 1)), axis = 1)
# [[1 3]
# [2 4]]
</syntaxhighlight>
== Opérations matricielles ==
Les quatre opérations classiques <code lang="python>+</code>, <code lang="python>-</code> et <code lang="python>/</code> ne fonctionnent qu'entre tenseurs de mêmes dimensions et sont des opérations élément par élément ''({{lang|en|elementwise operations}})'' :
* <code lang="python">(A + B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] + B[i, j, k]</code> ;
* <code lang="python">(A - B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] - B[i, j, k]</code> ;
* <code lang="python">(A / B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] / B[i, j, k]</code>.
La multiplication élément par élément se fait avec
: <code lang="python">np.multiply(A, B)</code> qui vaut <code lang="python">A[i, j, k] * B[i, j, k]</code>.
De même, les fonctions <code lang="python>np.add()</code>, <code lang="python>np.subtract()</code>, <code lang="python>np.multiply()</code> et <code lang="python>np.divide()</code> effectuent des opérations élément par élément sur des tenseurs de mêmes dimensions :
* <code lang="python">np.add(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] + B[i, j, k]</code> ;
* <code lang="python">np.subtract(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] - B[i, j, k]</code> ;
* <code lang="python">np.multiply(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] * B[i, j, k]</code> ;
* <code lang="python">np.divide(A, B)[i, j, k]</code> vaut <code lang="python">A[i, j, k] / B[i, j, k]</code>.
La multiplication matricielle, au sens de l'algèbre linéaire, se fait avec les fonctions <code lang="python">np.dot()</code> ou <code lang="python">np.matmul()</code>, ou bien avec l'opérateur <code>@</code>.
<syntaxhighlight lang="python">
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print(a @ b) # np.matmul(a, b)
# [[19 22]
# [43 50]]
</syntaxhighlight>
Pour un poduit scalaire :
<syntaxhighlight lang="python">
A = np.array([1, 2, 3])
B = np.array([4, 5, 6])
# 32
</syntaxhighlight>
Notez que :
* pour le produit par un scalaire, les fonctions <code lang="python">np.multiply()</code> et l'opérateur <code lang="python">*</code> sont plus performants ;
* la fonction <code lang="python">np.dot()</code> est plus performante pour le produit scalaire de deux vecteurs réels ;
* lorsque l'on a des vecteurs complexes, la fonction <code lang="python">np.vdot()</code> fait le produit par le conjugué du premier membre (<code lang="python">np.vdot(a, b) == np.dot(a.conj(), b)</code>) ;
* la fonction <code lang="python">np.matmul()</code> et l'opérateur <code lang="python">@</code> (<code lang="python">A @ B</code>) sont plus performants pour un produit matriciel.
L'opérateur <code>@=</code> fait un produit matriciel en modifiant la variable elle-même (à l'image de <code>*=</code> pour les nombres).
== Calcul vectorisé ==
Les fonctions de NumPy traitent en général les matrices en entier. Ainsi, il n'est pas nécessaire de créer une boucle pour faire défiler les indices un par un. Il en résulte un code clair et compact et surtout un plus grande rapidité d'exécution. Par exemple :
<syntaxhighlight lang="python">
x = np.linspace(0, 2*np.pi, 50) # 50 points entre 0 et 2π
y = np.sin(x)
plt.plot(x, y)
</syntaxhighlight>
La variable <code>x</code> est un vecteur de 50 valeurs et il est traité en une seule passe par la fonction sinus <code>np.sin()</code>.
Outre le tranchage ''({{lang|en|slicing}})'', on peut utiliser deux autres méthodes pour extraire certaines valeurs d'une matrice :
* utiliser un vecteur ou une matrice d'indices, Python extrait alors les valeurs correspondant aux indices ;
* utiliser un vecteur ou une matrice de booléens de même dimension que a matrice ; Python extrait alors les valeurs correspondant aux <code>True</code>, la matrice booléenne est un « masque » pour la matrice d'origine. Par exemple :
<syntaxhighlight lang="python">
a = np.arange(0, 10)
b = np.array([1, 3, 5, 7, 9])
c = np.array([True, True, False, False, True, False, True, False, False, True])
print(a[b], "\n", a[c])
</syntaxhighlight>
Si l'on veut inverser tous les éléments d'une matrice de bolléens, il faut utiliser la fonction <code>np.logical_not()</code>
'''Exercice'''
Écrire un programme Python mettant en œuvre le [[w:crible d'Érathostène|crible d'Érathostène]] pour trouver les nombres premiers inférieurs à une valeur donnée.
{{boîte déroulante début|Solution}}
<syntaxhighlight lang="python">
#!/usr/bin/env python
# coding: utf-8
import numpy as np
import matplotlib.pyplot as plt
# ***************
# ***************
# ** Fonctions **
# ***************
# ***************
def eratosthene(limite):
# Détermine la liste des nombres premiers entre 1 et N
# par le crible d'Ératosthène
# Entrées : limite : nombre entier, N
# Sorties : liste : vecteur d'entiers,liste des nombres premiers
indices = (np.ones(limite) == 1) # vecteur de booléens tous à True
# à la fin, indice(i-1) est True si i est premier, False sinon
indices[0]=False # 1 n'est pas premier
imax = int(limite)
i = 2 # initialisation
repete = (i <= imax)
while repete:
if indices[i-1]:
jmax = int(limite/i)
j = np.arange(1, jmax)+1
indices[i*j-1]=False # élimination des multiples de i
test = (i*jmax == imax)
i = i + 1
repete = i*i < limite # condition d'arrêt
liste0 = np.arange(limite)
liste = liste0[indices]+1
return liste
# *************************
# *************************
# ** Programme principal **
# *************************
# *************************
print("***** Recherche de nombres premiers par le crible d'Ératosthène *****\n")
nmax = eval(input("Entrez la valeur maximale : "))
resultat = eratosthene(nmax)
print("\n", resultat.shape[0], "nombres premiers entre 1 et", nmax, ":\n")
print(resultat)
plt.plot(resultat, np.zeros_like(resultat), "|")
</syntaxhighlight>
L'extraction par un vecteur d'indice intervient dans l'instruction :
<syntaxhighlight lang="python">
indices[i*j-1]=False
</syntaxhighlight>
qui élimine en une seule passe tous les multiples de ''i''. L'extraction par un vecteur booléen intervient dans l'instruction :
<syntaxhighlight lang="python">
liste = liste0[indices]+1
</syntaxhighlight>
qui permet d'extraire toutes la valeurs conservées en une seule passe.
{{boîte déroulante fin}}
== Attributs ==
La classe <code>ndarray</code>, qui définit les matrices, possède un certain nombre d'attributs :
* <code>.shape</code> : dimensions de la matrice ;
* <code>.ndim</code> : ordre du tenseur ;
* <code>.size</code> : nombre d'éléments ;
* <code>.dtype</code> : type des éléments.
<syntaxhighlight lang="python">
a = np.linspace(1, 9, 9)
print("a", a, "\n",
" ; shape :", a.shape,
" ; dim : ", a.ndim,
" ; size : ", a.size,
" ; dtype : ", a.dtype, "\n")
</syntaxhighlight>
* <code>.real</code>, <code>.imag</code> : parties réelle et imaginaire de la matrice ;
* <code>.flat</code> : liste des éléments de la matrice ; les éléments sont réorganisés en une liste ;
* <code>.T</code> : transposée.
<syntaxhighlight lang="python">a = np.arange(0, 9).reshape(3, 3)
print(a)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
print(a.T)
# [[0 3 6]
# [1 4 7]
# [2 5 8]]
print(a.flat[:])
# array([0, 1, 2, 3, 4, 5, 6, 7, 8])
</syntaxhighlight>
; Ressources
: Section « Attribute », {{lien web
| url = https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html
| titre = numpy.ndarray
| site = Numpy and Scipy Documentation
| consulté le = 2019-03-16
}}
== Fonctions et méthodes de base ==
La classe <code>ndarray</code> possède un certain nombre de méthodes :
* <code>.min()</code> et <code>.max()</code> : valeurs respectivement minimale et maximale ;
* <code>.ptp()</code> : amplitude « max – min » ''({{lang|en|peak to peak}})'' ;
* <code>.argmin()</code> et <code>argmax()</code> : indice où se trouvent les valeurs respectivement minimale et maximale ;
* <code>.sum()</code>, <code>prod()</code> : somme et produit de tous les éléments de la matrice ;
* <code>.cumsum()</code>, <code>cumprod()</code> : somme et produit cumulés.
<syntaxhighlight lang="python">
a = np.linspace(1, 9, 9)
print("min : ", a.min(),
"; max : ", a.max(), "\n",
"sum : ", a.sum(),
"; cumsum : ", a.cumsum(), "\n",
"prod : ", a.prod(),
"; cumprod : ", a.cumprod(), "\n")
</syntaxhighlight>
Méthodes statistiques :
* <code>.mean()</code> : moyenne ;
* <code>.std()</code> : écart type ''({{lang|en|standard deviation}})''.
{{loupe|../Statistiques}}
Extraction de données :
* <code>.diagonal()</code> : vecteur contenant les éléments de la diagonale ;
* <code>.flatten()</code> : matrice « aplatie », c'est-à-dire vecteur contenant les éléments réorganisés en liste ; par rapport à l'attribut <code>.flat</code>, on peut choisir le sens de linéarisation (par lignes, <code>.flatten(C)</code>, ou par colonnes, <code>.flatten(F)</code>) mais cela crée une copie, on ne peut pas par exemple s'en servir pour modifier la matrice ;
* <code>.tofile()</code> : crée un fichier texte contenant les valeurs de la matrice ; par exemple, pour une matrice <code>a</code> et pour séparer les valeurs par un point-virgule :
<syntaxhighlight lang="python">
a.tofile("matriceA.txt", sep=" ; ")
</syntaxhighlight>
* <code>.astype(''type'')</code> : copie la matrice en convertissant le type de données :
<syntaxhighlight lang="python">
a = a.astype(float) # pour avoir une matrice de réels en virgule flottante
a = a.astype(str) # pour avoir une matrice de chaînes de caractères
</syntaxhighlight>
Tri :
* <code>np.sort(M, i)</code> : crée une copie et trie la matrice selon l'axe ''i'' (0 pour le premier indice, 1 pour le deuxième… la valeur par défaut est –1 pour le dernier indice, la valeur ''none'' aplatit la matrice) ; <code>np.sort(M, 0)</code> trie chaque colonne indépendamment par ordre croissant, <code>np.sort(M, 1)</code> trie chaque ligne indépendamment par ordre croissant ;
* <code>M.sort(i)</code> : cette méthode trie la matrice en elle-même ;
* <code>np.argsort(M, i)</code> : crée une matrice contenant le nouvel indice, selon l'axe ''i'', de chaque élément.
<syntaxhighlight lang="python">
M = np.array([[1, 5, 7, 5], [2, 9, 4, 3], [9, 1, 7, 5]])
M.sort(1) # tri des lignes indépendamment -> [[1, 5, 5, 7], [2, 3, 4, 9], [1, 5, 7, 9]]
</syntaxhighlight>
Pour trier les lignes selon la deuxième colonne d'une matrice, tout en conservant les lignes intactes, on peut faire comme suit :
<syntaxhighlight lang="python">
M = np.array([[1, 5, 7, 5], [2, 9, 4, 3], [9, 1, 7, 5]])
ind = np.argsort(M[:, 1]) # indices de tri selon la 2e colonne
N = M[ind, :] # réarrangement des lignes -> [[9, *1*, 7, 5], [1, *5*, 7, 5], [2, *9*, 4, 3]]
</syntaxhighlight>
Pour faire un tri lexicographique, on utilise la fonction <code>np.lexsort()</code> en indiquant les différentes colonnes :
<syntaxhighlight lang="python">
M = np.array([[1, 5, 7, 5], [2, 9, 4, 3], [9, 1, 7, 5], [2, 9, 8, 5]])
ind = np.lexsort((M[:, 3], M[:, 2], M[:, 1], M[:, 0])) # indices de tri selon la 1re, puis la 2e, puis la 3e, puis la 4e colonne
N = M[ind, :] # réarrangement des lignes -> [[1, 5, 7, 5], [2, 9, 4, 3], [2, 9, 8, 5], [9, 1, 7, 5]]
</syntaxhighlight>
Le tri se fait par ordre croissant. Pour trier par ordre décroissant, on inverse l'ordre de la matrice en faisant une extraction avec un pas de moins un, par exemple pour inverser les lignes :
<syntaxhighlight lang="python">
M = M[:, ::-1]
</syntaxhighlight>
Algèbre linéaire :
* <code>a.dot(b)</code> : produit matriciel ''a''⋅''b'' ; on peut aussi écrire <code>a@b</code> ;
* <code>.trace()</code> : trace de la matrice (somme des éléments diagonaux) ;
* <code>.transpose()</code> : transpose la matrice, résultat similaire à l'attribut <code>.T</code> ;
* <code>np.cross()</code> : produit vectoriel dans ℝ³.
{{loupe|../Algèbre linéaire}}
Matrices de booléens :
* <code>.all()</code> : applique un « et » logique à toutes les valeurs de la matrice ;
* <code>.any()</code> : applique un « ou » logique à toutes les valeurs de la matrice.
{{loupe|../Fonctions mathématiques générales#Fonctions booléennes}}
Autre méthodes :
* <code>.conj()</code> : conjugué des valeurs complexes ;
* <code>.nonzero()</code> : n-uplet contenant les indices des valeurs non-nulles ;
* <code>.round(n)</code> : arrondit les valeurs à la ''n''-ième décimale.
; Ressources
: Section « Method », {{lien web
| url = https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html
| titre = numpy.ndarray
| site = Numpy and Scipy Documentation
| consulté le = 2019-03-16
}}
== Propagation ==
Le terme « propagation » ''({{lang|en|broadcasting}})'' désigne la manière dont Python complète les matrice lorsque des dimensions manquent.
Supposons que l'on veuille additionner deux matrices M<sub>1</sub> et M<sub>2</sub> de dimensions ''m''<sub>1</sub> × ''n''<sub>1</sub> et ''m''<sub>2</sub> × ''n''<sub>2</sub> différentes. Alors :
* le résultat a pour dimension max(''m''<sub>1</sub>, ''m''<sub>2</sub>) × max(''n''<sub>1</sub>, ''n''<sub>2</sub>) ;
* si une des dimensions vaut 1, alors les valeurs de l'autre dimension sont dupliquées ;
* sinon, les dimensions manquantes pour chaque matrice sont complétées par des 1.
Par exemple :
: <math>\mathrm{A} = \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
: <math>5 + \mathrm{A} = \begin{pmatrix} 5 & 5 \\ 5 & 5 \end{pmatrix} + \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
:: La matrice (5) est de dimension 1 × 1, la valeur « 5 » est donc répétée dans les deux dimensions
<syntaxhighlight lang="python">
A = np.array([[1, 2], [3, 4]])
print(5 + A)
# [[6 7]
# [7 8]]
</syntaxhighlight>
: <math>(5, 4) + \mathrm{A} = \begin{pmatrix} 5 & 4 \\ 5 & 4 \end{pmatrix} + \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
<syntaxhighlight lang="python">
print(np.array([[5, 4]]) + A)
# [[6 6]
# [6 8]]
</syntaxhighlight>
: <math>\begin{pmatrix} 5 \\ 4 \end{pmatrix} + \mathrm{A} = \begin{pmatrix} 5 & 5 \\ 4 & 4 \end{pmatrix} + \begin{pmatrix} 1 & 2 \\ 3 & 4 \end{pmatrix} </math>
<syntaxhighlight lang="python">
print(np.array([[5], [4]]) + A)
# [[6 7]
# [7 8]]
</syntaxhighlight>
== Fonctions « universelles » ==
Les fonctions universelles ''({{lang|en|ufunc}})'' sont les fonctions s'appliquant aux matrices, des fonctions vectorisées.
; Ressource
: {{lien web
| url = https://docs.scipy.org/doc/numpy/reference/ufuncs.html#available-ufuncs
| titre = Available ufuncs
| site = SciPy documentation
| consulté le = 2019-03-21
}}
== Algèbre linéaire ==
{{loupe|../Algèbre linéaire}}
== Notes et références ==
{{références}}
----
[[../Graphiques|Graphiques]] < [[../|↑]] > [[../Polynômes|Polynômes]]
[[Catégorie:Python pour le calcul scientifique (livre)]]
nptxxn2q3zux0j38jptbiqla8unlpia
Python pour le calcul scientifique/Annexe/Index
0
83349
769322
769298
2026-07-03T10:38:18Z
Cdang
1202
np.genfromtxt(), np.loadtxt()
769322
wikitext
text/x-wiki
{{SommaireCompact}}
== * ==
* <code>+</code> (plus) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>+=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>-</code> (moins) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|3]]
* <code>-=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>*</code> (astérisque) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>**</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>/</code> (barre de fraction) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>//</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>^</code> (circonflexe) : [[../../Découverte_de_Python_et_de_Jupyter#cite_note-2|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&</code> (esperluette) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>|</code> (tube) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>|=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>_</code> (tiret de soulignement, ''{{lang|en|underscore}}'') : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]], [[../../Éléments_de_programmation#Substitution_de_variables|2]]
* <code>callable.__call__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Appelable|1]]
* <code>iterator.__next__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== A ==
* <code>plt.add_subplot()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axis.add_patch()</code> : [[../../Graphiques#Dessins|1]]
* aléatoire (générateur de nombres pseudo-~) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Graphiques|2]], [[../../Polynômes#Régression polynomiale|3]], [[../../Statistiques#Fréquence, histogramme|'''4''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]], [[../../Régression et optimisation#Régression linéaire|6]]
* <code>and</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]], [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|2]] <br />voir [[#*|&]], [[#L|np.logical_all()]]
* <code>all</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]
* <code>list.append()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>axes.annotate()</code> : [[../../Graphiques#Annotations|1]]
* <code>np.arange()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Premier_tracé_graphique|1]], [[../../Éléments_de_programmation#Définition_en_compréhension|2]], [[../../Graphiques|3]], [[../../Manipulation_de_matrices#Définir_un_tenseur|'''3''']]<br /> → [[#R|<code>range()</code>]]
* <code>np.array()</code> (classe <code>ndarray</code>) : [[../../Fonctions_mathématiques_générales#Vecteurs_et_matrices|1]], [[../../Éléments_de_programmation#Exploiter_le_contenu_d'un_fichier_texte|2]], [[../../Graphiques#Transformation_des_objets_graphiques|3]], [[../../Manipulation_de_matrices|'''4''']], [[../../Statistiques#Méthodes_de_matrices|5]], [[../../Algèbre_linéaire#Opérations_vectorielles|6]]
* <code>float.as_integer_ratio()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]], [[../../Éléments_de_programmation#Réels|2]]
* <code>fig.axes</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
== B ==
* <code>plt.bar()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* booléens : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Fonctions mathématiques générales#Fonctions booléennes|2]]
* <code>break()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== C ==
* ''{{lang|en|callable}}'' (« appelable ») : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]]
* <code>str.capitalize()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.center()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>chr()</code> : [[../../Éléments_de_programmation#Autres_fonctions|1]]
* classe (d'un langage orienté objet) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* <code>color</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>fig.colorbar()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* complexe (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* compréhension (définition en) : [[../../Éléments_de_programmation#Définition_en_compréhension|1]]
* <code>itertools.compress()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>plt.contour()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>plt.contourf()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>continue()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== D ==
* <code>def</code> : [[../../Éléments_de_programmation#Fonction|1]]
* <code>del()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* division euclidienne : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>divmode()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>dpi</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
== E ==
* <code>edgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>elif</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>else</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>enumerate()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* espace de nom (<code>np.</code>, <code>plt.</code>, <code>scipy.</code>…) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]], [[../../Découverte_de_Python_et_de_Jupyter#Les_espaces_de_noms|2]]
== F ==
* <code>facecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>figsize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>fillstyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>str.find()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* fonction (définir une ~) : [[../../Éléments_de_programmation#Fonction|1]]
* <code>for</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== G ==
* <code>plt.gca()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>plt.gcf()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>np.genfromtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* GIF animé : [[../../Graphiques#Créer_un_GIF_animé|1]]
== H ==
* <code>plt.hist()</code> : [[../../Graphiques|1]]
* <code>html</code> (module) : [[../../Découverte_de_Python_et_de_Jupyter#Les_chaînes_de_caractères|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]]
== I ==
* <code>if</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* imaginaire (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>in</code> : [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|1]], [[../../Éléments de programmation#Définition en compréhension|2]]
* infini +∞, <code>float("inf")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* instance (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* installation d'un module : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* <code>is</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]]
* <code>str.isdigit()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>float.is_integer()</code> : [[../../Éléments_de_programmation#Réels|1]]
* <code>iter()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* itérable : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== J ==
* <code>j</code> (imaginaire) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
== L ==
* LaTeX : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* <code>layout</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>plt.legend()</code> : [[../../Graphiques|1]], [[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|2]]
* <code>linear</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>linestyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>linewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>list()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.ljust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>np.loadtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* <code>log</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>np.logical_and()</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]<br /> voir [[#A|and]]
* <code>logit</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>str.lower()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>ls</code> (paramètre) : voir ''linestyle''
* <code>lw</code> (paramètre) : voir ''linewidth''
== M ==
* <code>marker</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markerfacecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markersize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* Matplotlib (module, <code>np</code>) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]<br />→ [[#P|Pyplot]]
* <code>np.matrix()</code> (déprécié) : [[../../Manipulation_de_matrices#Différence_entre_array_et_matrix|1]], [[../../Algèbre_linéaire#Opérations_vectorielles|2]]<br />→ [[#A|<code>np.array()</code>]]
* <code>np.meshgrid()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* méthode (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* module : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
== N ==
* NaN ''(not a number)'', <code>float("nan")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>nextafter()</code> : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]]
* <code>normal()</code> [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]]
* <code>np.</code> : espace de nom, abréviation de <code>numpy.</code><br />→ Numpy
* Numpy (module) : [[../../Découverte de Python et de Jupyter|1]]
== P ==
* <code>str.partition()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* ''patch'' (pièce, dessin) : [[../../Graphiques#Dessins|1]]
* <code>plt.pcolormesh()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>pip install</code> : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* PIL (module ''Python imaging library'') : [[../../Graphiques#Créer_un_GIF_animé|1]]
* <code>plt.plot()</code> : [[../../Graphiques|1]]
* <code>plt.plot_surface()</code> : [[../../Graphiques#Surfaces_3D|1]]
* <code>plt</code> : espace de nom, abréviation de <code>pyplot.</code><br />→ <code>plt</code>
* <code>plt.polar()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>list.pop()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>pow()</code> : [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|1]]
* puissance (élévation à la) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>pyplot</code> (<code>plt</code>, option de Matplotlib) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]
* PyQt (module) : [[../../Éléments_de_programmation#Avec_PyQt|1]]
== Q ==
* <code>plt.quiver()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
== R ==
* <code>rand()</code> : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']]
* <code>randn()</code> : [[../../Graphiques|1]], [[../../Polynômes#Régression polynomiale|2]], [[../../Statistiques#Fréquence, histogramme|'''3''']], [[../../Régression et optimisation#Régression linéaire|4]]
* <code>random</code> (module NumPy) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|3]]
* <code>range()</code> : [[../../Premiers programmes#Deuxième_programme|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]], [[../../Éléments_de_programmation#Définition_en_compréhension|3]], [[../../Éléments_de_programmation#Structures_de_contrôle|4]]<br /> → [[#A|<code>np.arange()</code>]]
* <code>plt.rcParams()</code> : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* réel à virgule flottante (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>list.remove()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.replace()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>reversed()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.rfind()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.rjust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== S ==
* <code>plt.savefig()</code> : [[../../Graphiques#Exemple|1]]
* <code>line2D.set()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>axis.set_aspect()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>line2D.set_label()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>line2D.set_linestyle()</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>axes.set_rticks()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_thetagrids()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_title()</code> : [[../../Graphiques#Exemple|1]]
* <code>axes.set_xlabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_xlim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_xsticks()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axes.set_ylabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_ylim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_minor_formatter()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* ''shebang'' : [[../../Découverte de Python et de Jupyter|1]]
* <code>plt.show()</code> : [[../../Graphiques|1]]
* <code>list.sort()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>sorted()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.split()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>plt.step()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* <code>plt.subplots()</code> : [[../../Graphiques#Exemple|1]]
* <code>fig.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>plt.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>symlog</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
== T ==
* <code>plt.text()</code> : [[../../Graphiques#Annotations|1]]
* <code>plt.title()</code> : [[../../Graphiques|1]]
* <code>aix.transData()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>transform</code> (paramètre) : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>matplotlib.transforms()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* Tk (module) : [[../../Éléments_de_programmation#Avec_Tk|1]]
== U ==
* <code>str.upper()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== W ==
* <code>where()</code> : [[../../Manipulation_de_matrices#Trouver_une_valeur|1]]
* <code>while</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== X ==
* <code>plt.xlabel()</code> : [[../../Graphiques|1]]
== Y ==
* <code>plt.ylabel()</code> : [[../../Graphiques|1]]
== Z ==
* <code>zip()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
----
[[../../Traitement d'images|Traitement d'images]] < [[../../|↑]] >
[[Catégorie:Python pour le calcul scientifique (livre)]]
ptr48w27td27olba4z28187dbct6p56
769325
769322
2026-07-03T10:54:08Z
Cdang
1202
/* E */ np.empty()
769325
wikitext
text/x-wiki
{{SommaireCompact}}
== * ==
* <code>+</code> (plus) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>+=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>-</code> (moins) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|3]]
* <code>-=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>*</code> (astérisque) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>**</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>/</code> (barre de fraction) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>//</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>^</code> (circonflexe) : [[../../Découverte_de_Python_et_de_Jupyter#cite_note-2|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&</code> (esperluette) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>|</code> (tube) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>|=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>_</code> (tiret de soulignement, ''{{lang|en|underscore}}'') : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]], [[../../Éléments_de_programmation#Substitution_de_variables|2]]
* <code>callable.__call__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Appelable|1]]
* <code>iterator.__next__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== A ==
* <code>plt.add_subplot()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axis.add_patch()</code> : [[../../Graphiques#Dessins|1]]
* aléatoire (générateur de nombres pseudo-~) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Graphiques|2]], [[../../Polynômes#Régression polynomiale|3]], [[../../Statistiques#Fréquence, histogramme|'''4''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]], [[../../Régression et optimisation#Régression linéaire|6]]
* <code>and</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]], [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|2]] <br />voir [[#*|&]], [[#L|np.logical_all()]]
* <code>all</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]
* <code>list.append()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>axes.annotate()</code> : [[../../Graphiques#Annotations|1]]
* <code>np.arange()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Premier_tracé_graphique|1]], [[../../Éléments_de_programmation#Définition_en_compréhension|2]], [[../../Graphiques|3]], [[../../Manipulation_de_matrices#Définir_un_tenseur|'''3''']]<br /> → [[#R|<code>range()</code>]]
* <code>np.array()</code> (classe <code>ndarray</code>) : [[../../Fonctions_mathématiques_générales#Vecteurs_et_matrices|1]], [[../../Éléments_de_programmation#Exploiter_le_contenu_d'un_fichier_texte|2]], [[../../Graphiques#Transformation_des_objets_graphiques|3]], [[../../Manipulation_de_matrices|'''4''']], [[../../Statistiques#Méthodes_de_matrices|5]], [[../../Algèbre_linéaire#Opérations_vectorielles|6]]
* <code>float.as_integer_ratio()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]], [[../../Éléments_de_programmation#Réels|2]]
* <code>fig.axes</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
== B ==
* <code>plt.bar()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* booléens : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Fonctions mathématiques générales#Fonctions booléennes|2]]
* <code>break()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== C ==
* ''{{lang|en|callable}}'' (« appelable ») : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]]
* <code>str.capitalize()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.center()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>chr()</code> : [[../../Éléments_de_programmation#Autres_fonctions|1]]
* classe (d'un langage orienté objet) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* <code>color</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>fig.colorbar()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* complexe (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* compréhension (définition en) : [[../../Éléments_de_programmation#Définition_en_compréhension|1]]
* <code>itertools.compress()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>plt.contour()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>plt.contourf()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>continue()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== D ==
* <code>def</code> : [[../../Éléments_de_programmation#Fonction|1]]
* <code>del()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* division euclidienne : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>divmode()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>dpi</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
== E ==
* <code>edgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>elif</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>else</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>np.empty()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>enumerate()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* espace de nom (<code>np.</code>, <code>plt.</code>, <code>scipy.</code>…) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]], [[../../Découverte_de_Python_et_de_Jupyter#Les_espaces_de_noms|2]]
== F ==
* <code>facecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>figsize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>fillstyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>str.find()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* fonction (définir une ~) : [[../../Éléments_de_programmation#Fonction|1]]
* <code>for</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== G ==
* <code>plt.gca()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>plt.gcf()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>np.genfromtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* GIF animé : [[../../Graphiques#Créer_un_GIF_animé|1]]
== H ==
* <code>plt.hist()</code> : [[../../Graphiques|1]]
* <code>html</code> (module) : [[../../Découverte_de_Python_et_de_Jupyter#Les_chaînes_de_caractères|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]]
== I ==
* <code>if</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* imaginaire (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>in</code> : [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|1]], [[../../Éléments de programmation#Définition en compréhension|2]]
* infini +∞, <code>float("inf")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* instance (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* installation d'un module : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* <code>is</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]]
* <code>str.isdigit()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>float.is_integer()</code> : [[../../Éléments_de_programmation#Réels|1]]
* <code>iter()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* itérable : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== J ==
* <code>j</code> (imaginaire) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
== L ==
* LaTeX : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* <code>layout</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>plt.legend()</code> : [[../../Graphiques|1]], [[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|2]]
* <code>linear</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>linestyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>linewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>list()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.ljust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>np.loadtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* <code>log</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>np.logical_and()</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]<br /> voir [[#A|and]]
* <code>logit</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>str.lower()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>ls</code> (paramètre) : voir ''linestyle''
* <code>lw</code> (paramètre) : voir ''linewidth''
== M ==
* <code>marker</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markerfacecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markersize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* Matplotlib (module, <code>np</code>) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]<br />→ [[#P|Pyplot]]
* <code>np.matrix()</code> (déprécié) : [[../../Manipulation_de_matrices#Différence_entre_array_et_matrix|1]], [[../../Algèbre_linéaire#Opérations_vectorielles|2]]<br />→ [[#A|<code>np.array()</code>]]
* <code>np.meshgrid()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* méthode (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* module : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
== N ==
* NaN ''(not a number)'', <code>float("nan")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>nextafter()</code> : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]]
* <code>normal()</code> [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]]
* <code>np.</code> : espace de nom, abréviation de <code>numpy.</code><br />→ Numpy
* Numpy (module) : [[../../Découverte de Python et de Jupyter|1]]
== P ==
* <code>str.partition()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* ''patch'' (pièce, dessin) : [[../../Graphiques#Dessins|1]]
* <code>plt.pcolormesh()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>pip install</code> : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* PIL (module ''Python imaging library'') : [[../../Graphiques#Créer_un_GIF_animé|1]]
* <code>plt.plot()</code> : [[../../Graphiques|1]]
* <code>plt.plot_surface()</code> : [[../../Graphiques#Surfaces_3D|1]]
* <code>plt</code> : espace de nom, abréviation de <code>pyplot.</code><br />→ <code>plt</code>
* <code>plt.polar()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>list.pop()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>pow()</code> : [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|1]]
* puissance (élévation à la) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>pyplot</code> (<code>plt</code>, option de Matplotlib) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]
* PyQt (module) : [[../../Éléments_de_programmation#Avec_PyQt|1]]
== Q ==
* <code>plt.quiver()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
== R ==
* <code>rand()</code> : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']]
* <code>randn()</code> : [[../../Graphiques|1]], [[../../Polynômes#Régression polynomiale|2]], [[../../Statistiques#Fréquence, histogramme|'''3''']], [[../../Régression et optimisation#Régression linéaire|4]]
* <code>random</code> (module NumPy) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|3]]
* <code>range()</code> : [[../../Premiers programmes#Deuxième_programme|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]], [[../../Éléments_de_programmation#Définition_en_compréhension|3]], [[../../Éléments_de_programmation#Structures_de_contrôle|4]]<br /> → [[#A|<code>np.arange()</code>]]
* <code>plt.rcParams()</code> : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* réel à virgule flottante (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>list.remove()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.replace()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>reversed()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.rfind()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.rjust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== S ==
* <code>plt.savefig()</code> : [[../../Graphiques#Exemple|1]]
* <code>line2D.set()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>axis.set_aspect()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>line2D.set_label()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>line2D.set_linestyle()</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>axes.set_rticks()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_thetagrids()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_title()</code> : [[../../Graphiques#Exemple|1]]
* <code>axes.set_xlabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_xlim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_xsticks()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axes.set_ylabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_ylim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_minor_formatter()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* ''shebang'' : [[../../Découverte de Python et de Jupyter|1]]
* <code>plt.show()</code> : [[../../Graphiques|1]]
* <code>list.sort()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>sorted()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.split()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>plt.step()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* <code>plt.subplots()</code> : [[../../Graphiques#Exemple|1]]
* <code>fig.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>plt.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>symlog</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
== T ==
* <code>plt.text()</code> : [[../../Graphiques#Annotations|1]]
* <code>plt.title()</code> : [[../../Graphiques|1]]
* <code>aix.transData()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>transform</code> (paramètre) : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>matplotlib.transforms()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* Tk (module) : [[../../Éléments_de_programmation#Avec_Tk|1]]
== U ==
* <code>str.upper()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== W ==
* <code>where()</code> : [[../../Manipulation_de_matrices#Trouver_une_valeur|1]]
* <code>while</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== X ==
* <code>plt.xlabel()</code> : [[../../Graphiques|1]]
== Y ==
* <code>plt.ylabel()</code> : [[../../Graphiques|1]]
== Z ==
* <code>zip()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
----
[[../../Traitement d'images|Traitement d'images]] < [[../../|↑]] >
[[Catégorie:Python pour le calcul scientifique (livre)]]
j5vhify5xwjzuoych6uwgkoifsb7ful
769326
769325
2026-07-03T10:55:37Z
Cdang
1202
/* Z */ np.zeros
769326
wikitext
text/x-wiki
{{SommaireCompact}}
== * ==
* <code>+</code> (plus) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>+=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>-</code> (moins) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|3]]
* <code>-=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>*</code> (astérisque) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>**</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>/</code> (barre de fraction) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>//</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>^</code> (circonflexe) : [[../../Découverte_de_Python_et_de_Jupyter#cite_note-2|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&</code> (esperluette) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>|</code> (tube) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>|=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>_</code> (tiret de soulignement, ''{{lang|en|underscore}}'') : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]], [[../../Éléments_de_programmation#Substitution_de_variables|2]]
* <code>callable.__call__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Appelable|1]]
* <code>iterator.__next__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== A ==
* <code>plt.add_subplot()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axis.add_patch()</code> : [[../../Graphiques#Dessins|1]]
* aléatoire (générateur de nombres pseudo-~) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Graphiques|2]], [[../../Polynômes#Régression polynomiale|3]], [[../../Statistiques#Fréquence, histogramme|'''4''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]], [[../../Régression et optimisation#Régression linéaire|6]]
* <code>and</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]], [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|2]] <br />voir [[#*|&]], [[#L|np.logical_all()]]
* <code>all</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]
* <code>list.append()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>axes.annotate()</code> : [[../../Graphiques#Annotations|1]]
* <code>np.arange()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Premier_tracé_graphique|1]], [[../../Éléments_de_programmation#Définition_en_compréhension|2]], [[../../Graphiques|3]], [[../../Manipulation_de_matrices#Définir_un_tenseur|'''3''']]<br /> → [[#R|<code>range()</code>]]
* <code>np.array()</code> (classe <code>ndarray</code>) : [[../../Fonctions_mathématiques_générales#Vecteurs_et_matrices|1]], [[../../Éléments_de_programmation#Exploiter_le_contenu_d'un_fichier_texte|2]], [[../../Graphiques#Transformation_des_objets_graphiques|3]], [[../../Manipulation_de_matrices|'''4''']], [[../../Statistiques#Méthodes_de_matrices|5]], [[../../Algèbre_linéaire#Opérations_vectorielles|6]]
* <code>float.as_integer_ratio()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]], [[../../Éléments_de_programmation#Réels|2]]
* <code>fig.axes</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
== B ==
* <code>plt.bar()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* booléens : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Fonctions mathématiques générales#Fonctions booléennes|2]]
* <code>break()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== C ==
* ''{{lang|en|callable}}'' (« appelable ») : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]]
* <code>str.capitalize()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.center()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>chr()</code> : [[../../Éléments_de_programmation#Autres_fonctions|1]]
* classe (d'un langage orienté objet) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* <code>color</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>fig.colorbar()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* complexe (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* compréhension (définition en) : [[../../Éléments_de_programmation#Définition_en_compréhension|1]]
* <code>itertools.compress()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>plt.contour()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>plt.contourf()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>continue()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== D ==
* <code>def</code> : [[../../Éléments_de_programmation#Fonction|1]]
* <code>del()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* division euclidienne : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>divmode()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>dpi</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
== E ==
* <code>edgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>elif</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>else</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>np.empty()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>enumerate()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* espace de nom (<code>np.</code>, <code>plt.</code>, <code>scipy.</code>…) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]], [[../../Découverte_de_Python_et_de_Jupyter#Les_espaces_de_noms|2]]
== F ==
* <code>facecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>figsize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>fillstyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>str.find()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* fonction (définir une ~) : [[../../Éléments_de_programmation#Fonction|1]]
* <code>for</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== G ==
* <code>plt.gca()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>plt.gcf()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>np.genfromtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* GIF animé : [[../../Graphiques#Créer_un_GIF_animé|1]]
== H ==
* <code>plt.hist()</code> : [[../../Graphiques|1]]
* <code>html</code> (module) : [[../../Découverte_de_Python_et_de_Jupyter#Les_chaînes_de_caractères|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]]
== I ==
* <code>if</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* imaginaire (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>in</code> : [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|1]], [[../../Éléments de programmation#Définition en compréhension|2]]
* infini +∞, <code>float("inf")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* instance (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* installation d'un module : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* <code>is</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]]
* <code>str.isdigit()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>float.is_integer()</code> : [[../../Éléments_de_programmation#Réels|1]]
* <code>iter()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* itérable : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== J ==
* <code>j</code> (imaginaire) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
== L ==
* LaTeX : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* <code>layout</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>plt.legend()</code> : [[../../Graphiques|1]], [[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|2]]
* <code>linear</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>linestyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>linewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>list()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.ljust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>np.loadtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* <code>log</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>np.logical_and()</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]<br /> voir [[#A|and]]
* <code>logit</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>str.lower()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>ls</code> (paramètre) : voir ''linestyle''
* <code>lw</code> (paramètre) : voir ''linewidth''
== M ==
* <code>marker</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markerfacecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markersize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* Matplotlib (module, <code>np</code>) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]<br />→ [[#P|Pyplot]]
* <code>np.matrix()</code> (déprécié) : [[../../Manipulation_de_matrices#Différence_entre_array_et_matrix|1]], [[../../Algèbre_linéaire#Opérations_vectorielles|2]]<br />→ [[#A|<code>np.array()</code>]]
* <code>np.meshgrid()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* méthode (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* module : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
== N ==
* NaN ''(not a number)'', <code>float("nan")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>nextafter()</code> : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]]
* <code>normal()</code> [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]]
* <code>np.</code> : espace de nom, abréviation de <code>numpy.</code><br />→ Numpy
* Numpy (module) : [[../../Découverte de Python et de Jupyter|1]]
== P ==
* <code>str.partition()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* ''patch'' (pièce, dessin) : [[../../Graphiques#Dessins|1]]
* <code>plt.pcolormesh()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>pip install</code> : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* PIL (module ''Python imaging library'') : [[../../Graphiques#Créer_un_GIF_animé|1]]
* <code>plt.plot()</code> : [[../../Graphiques|1]]
* <code>plt.plot_surface()</code> : [[../../Graphiques#Surfaces_3D|1]]
* <code>plt</code> : espace de nom, abréviation de <code>pyplot.</code><br />→ <code>plt</code>
* <code>plt.polar()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>list.pop()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>pow()</code> : [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|1]]
* puissance (élévation à la) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>pyplot</code> (<code>plt</code>, option de Matplotlib) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]
* PyQt (module) : [[../../Éléments_de_programmation#Avec_PyQt|1]]
== Q ==
* <code>plt.quiver()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
== R ==
* <code>rand()</code> : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']]
* <code>randn()</code> : [[../../Graphiques|1]], [[../../Polynômes#Régression polynomiale|2]], [[../../Statistiques#Fréquence, histogramme|'''3''']], [[../../Régression et optimisation#Régression linéaire|4]]
* <code>random</code> (module NumPy) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|3]]
* <code>range()</code> : [[../../Premiers programmes#Deuxième_programme|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]], [[../../Éléments_de_programmation#Définition_en_compréhension|3]], [[../../Éléments_de_programmation#Structures_de_contrôle|4]]<br /> → [[#A|<code>np.arange()</code>]]
* <code>plt.rcParams()</code> : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* réel à virgule flottante (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>list.remove()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.replace()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>reversed()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.rfind()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.rjust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== S ==
* <code>plt.savefig()</code> : [[../../Graphiques#Exemple|1]]
* <code>line2D.set()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>axis.set_aspect()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>line2D.set_label()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>line2D.set_linestyle()</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>axes.set_rticks()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_thetagrids()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_title()</code> : [[../../Graphiques#Exemple|1]]
* <code>axes.set_xlabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_xlim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_xsticks()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axes.set_ylabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_ylim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_minor_formatter()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* ''shebang'' : [[../../Découverte de Python et de Jupyter|1]]
* <code>plt.show()</code> : [[../../Graphiques|1]]
* <code>list.sort()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>sorted()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.split()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>plt.step()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* <code>plt.subplots()</code> : [[../../Graphiques#Exemple|1]]
* <code>fig.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>plt.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>symlog</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
== T ==
* <code>plt.text()</code> : [[../../Graphiques#Annotations|1]]
* <code>plt.title()</code> : [[../../Graphiques|1]]
* <code>aix.transData()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>transform</code> (paramètre) : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>matplotlib.transforms()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* Tk (module) : [[../../Éléments_de_programmation#Avec_Tk|1]]
== U ==
* <code>str.upper()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== W ==
* <code>where()</code> : [[../../Manipulation_de_matrices#Trouver_une_valeur|1]]
* <code>while</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== X ==
* <code>plt.xlabel()</code> : [[../../Graphiques|1]]
== Y ==
* <code>plt.ylabel()</code> : [[../../Graphiques|1]]
== Z ==
* <code>np.zeros()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>np.zeros_like()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>zip()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
----
[[../../Traitement d'images|Traitement d'images]] < [[../../|↑]] >
[[Catégorie:Python pour le calcul scientifique (livre)]]
fl26j4quddx03wy8q56vyfae3m9kyy4
769327
769326
2026-07-03T10:57:21Z
Cdang
1202
/* N */ np.ones
769327
wikitext
text/x-wiki
{{SommaireCompact}}
== * ==
* <code>+</code> (plus) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>+=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>-</code> (moins) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|3]]
* <code>-=</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>*</code> (astérisque) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>**</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>/</code> (barre de fraction) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>//</code> : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>^</code> (circonflexe) : [[../../Découverte_de_Python_et_de_Jupyter#cite_note-2|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&</code> (esperluette) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>&=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>|</code> (tube) : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|2]]
* <code>|=</code> : [[../../Découverte de Python et de Jupyter#Les booléens|1]]
* <code>_</code> (tiret de soulignement, ''{{lang|en|underscore}}'') : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]], [[../../Éléments_de_programmation#Substitution_de_variables|2]]
* <code>callable.__call__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Appelable|1]]
* <code>iterator.__next__()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== A ==
* <code>plt.add_subplot()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axis.add_patch()</code> : [[../../Graphiques#Dessins|1]]
* aléatoire (générateur de nombres pseudo-~) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Graphiques|2]], [[../../Polynômes#Régression polynomiale|3]], [[../../Statistiques#Fréquence, histogramme|'''4''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]], [[../../Régression et optimisation#Régression linéaire|6]]
* <code>and</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]], [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|2]] <br />voir [[#*|&]], [[#L|np.logical_all()]]
* <code>all</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]
* <code>list.append()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>axes.annotate()</code> : [[../../Graphiques#Annotations|1]]
* <code>np.arange()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Premier_tracé_graphique|1]], [[../../Éléments_de_programmation#Définition_en_compréhension|2]], [[../../Graphiques|3]], [[../../Manipulation_de_matrices#Définir_un_tenseur|'''3''']]<br /> → [[#R|<code>range()</code>]]
* <code>np.array()</code> (classe <code>ndarray</code>) : [[../../Fonctions_mathématiques_générales#Vecteurs_et_matrices|1]], [[../../Éléments_de_programmation#Exploiter_le_contenu_d'un_fichier_texte|2]], [[../../Graphiques#Transformation_des_objets_graphiques|3]], [[../../Manipulation_de_matrices|'''4''']], [[../../Statistiques#Méthodes_de_matrices|5]], [[../../Algèbre_linéaire#Opérations_vectorielles|6]]
* <code>float.as_integer_ratio()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]], [[../../Éléments_de_programmation#Réels|2]]
* <code>fig.axes</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
== B ==
* <code>plt.bar()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* booléens : [[../../Découverte de Python et de Jupyter#Les booléens|1]], [[../../Fonctions mathématiques générales#Fonctions booléennes|2]]
* <code>break()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== C ==
* ''{{lang|en|callable}}'' (« appelable ») : [[../../Découverte_de_Python_et_de_Jupyter#Appelable_(callable)|1]]
* <code>str.capitalize()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.center()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>chr()</code> : [[../../Éléments_de_programmation#Autres_fonctions|1]]
* classe (d'un langage orienté objet) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* <code>color</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>fig.colorbar()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* complexe (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* compréhension (définition en) : [[../../Éléments_de_programmation#Définition_en_compréhension|1]]
* <code>itertools.compress()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>plt.contour()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>plt.contourf()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>continue()</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== D ==
* <code>def</code> : [[../../Éléments_de_programmation#Fonction|1]]
* <code>del()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* division euclidienne : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>divmode()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>dpi</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
== E ==
* <code>edgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>elif</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>else</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* <code>np.empty()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>enumerate()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* espace de nom (<code>np.</code>, <code>plt.</code>, <code>scipy.</code>…) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]], [[../../Découverte_de_Python_et_de_Jupyter#Les_espaces_de_noms|2]]
== F ==
* <code>facecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>figsize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>fillstyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>str.find()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* fonction (définir une ~) : [[../../Éléments_de_programmation#Fonction|1]]
* <code>for</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== G ==
* <code>plt.gca()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>plt.gcf()</code> : [[../../Graphiques#Styles_de_codage_«_pyplot_»_et_«_OO_»|1]]
* <code>np.genfromtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* GIF animé : [[../../Graphiques#Créer_un_GIF_animé|1]]
== H ==
* <code>plt.hist()</code> : [[../../Graphiques|1]]
* <code>html</code> (module) : [[../../Découverte_de_Python_et_de_Jupyter#Les_chaînes_de_caractères|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]]
== I ==
* <code>if</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
* imaginaire (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>in</code> : [[../../Découverte de Python et de Jupyter#Les ensembles et les dictionnaires|1]], [[../../Éléments de programmation#Définition en compréhension|2]]
* infini +∞, <code>float("inf")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* instance (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* installation d'un module : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* <code>is</code> : [[../../Découverte_de_Python_et_de_Jupyter#Les_booléens|1]]
* <code>str.isdigit()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>float.is_integer()</code> : [[../../Éléments_de_programmation#Réels|1]]
* <code>iter()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* itérable : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
== J ==
* <code>j</code> (imaginaire) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
== L ==
* LaTeX : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* <code>layout</code> (paramètre) : [[../../Graphiques#Mise_en_forme_de_la_figure|1]]
* <code>plt.legend()</code> : [[../../Graphiques|1]], [[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|2]]
* <code>linear</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>linestyle</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>linewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>list()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.ljust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>np.loadtxt()</code> : [[../../Éléments_de_programmation#Importation_avec_NumPy|1]]
* <code>log</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>np.logical_and()</code> : [[../../Fonctions_mathématiques_générales#Fonctions_booléennes|1]]<br /> voir [[#A|and]]
* <code>logit</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>str.lower()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>ls</code> (paramètre) : voir ''linestyle''
* <code>lw</code> (paramètre) : voir ''linewidth''
== M ==
* <code>marker</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markeredgewidth</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markerfacecolor</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>markersize</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* Matplotlib (module, <code>np</code>) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]<br />→ [[#P|Pyplot]]
* <code>np.matrix()</code> (déprécié) : [[../../Manipulation_de_matrices#Différence_entre_array_et_matrix|1]], [[../../Algèbre_linéaire#Opérations_vectorielles|2]]<br />→ [[#A|<code>np.array()</code>]]
* <code>np.meshgrid()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* méthode (d'une classe) : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
* module : [[../../Découverte_de_Python_et_de_Jupyter#Vocabulaire|1]]
== N ==
* NaN ''(not a number)'', <code>float("nan")</code> : [[../../Découverte_de_Python_et_de_Jupyter#Commandes_élémentaires|1]]
* <code>nextafter()</code> : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]]
* <code>normal()</code> [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|5]]
* <code>np.</code> : espace de nom, abréviation de <code>numpy.</code><br />→ Numpy
* Numpy (module) : [[../../Découverte de Python et de Jupyter|1]]
== O ==
* <code>np.ones()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>np.ones_like()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
== P ==
* <code>str.partition()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* ''patch'' (pièce, dessin) : [[../../Graphiques#Dessins|1]]
* <code>plt.pcolormesh()</code> : [[../../Graphiques#Cartes_de_valeurs_et_de_vecteurs|1]]
* <code>pip install</code> : [[../../Découverte de Python et de Jupyter#Installation et mise à jour de modules|1]]
* PIL (module ''Python imaging library'') : [[../../Graphiques#Créer_un_GIF_animé|1]]
* <code>plt.plot()</code> : [[../../Graphiques|1]]
* <code>plt.plot_surface()</code> : [[../../Graphiques#Surfaces_3D|1]]
* <code>plt</code> : espace de nom, abréviation de <code>pyplot.</code><br />→ <code>plt</code>
* <code>plt.polar()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>list.pop()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>pow()</code> : [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|1]]
* puissance (élévation à la) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]], [[../../Fonctions mathématiques générales#Rappel sur les opérations de base|2]]
* <code>pyplot</code> (<code>plt</code>, option de Matplotlib) : [[../../Découverte de Python et de Jupyter#Premier tracé graphique|1]], [[../../Graphiques|2]]
* PyQt (module) : [[../../Éléments_de_programmation#Avec_PyQt|1]]
== Q ==
* <code>plt.quiver()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
== R ==
* <code>rand()</code> : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']]
* <code>randn()</code> : [[../../Graphiques|1]], [[../../Polynômes#Régression polynomiale|2]], [[../../Statistiques#Fréquence, histogramme|'''3''']], [[../../Régression et optimisation#Régression linéaire|4]]
* <code>random</code> (module NumPy) : [[../../Éléments de programmation#Utilisation de Pandas|1]], [[../../Statistiques#Fréquence, histogramme|'''2''']], [[../../Interpolation, extrapolation et lissage#Avec le module scipy.signal|3]]
* <code>range()</code> : [[../../Premiers programmes#Deuxième_programme|1]], [[../../Éléments_de_programmation#Autres_fonctions|2]], [[../../Éléments_de_programmation#Définition_en_compréhension|3]], [[../../Éléments_de_programmation#Structures_de_contrôle|4]]<br /> → [[#A|<code>np.arange()</code>]]
* <code>plt.rcParams()</code> : [[../../Graphiques#Mise_en_forme_du_texte|1]]
* réel à virgule flottante (nombre) : [[../../Découverte de Python et de Jupyter#Commandes élémentaires|1]]
* <code>list.remove()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>str.replace()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>reversed()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.rfind()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>str.rjust()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== S ==
* <code>plt.savefig()</code> : [[../../Graphiques#Exemple|1]]
* <code>line2D.set()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>axis.set_aspect()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>line2D.set_label()</code>[[../../Graphiques#Plusieurs_courbes_sur_un_même_système_d'axes|1]]
* <code>line2D.set_linestyle()</code> (paramètre) : [[../../Graphiques#Mise_en_forme_d'une_courbe|1]]
* <code>axes.set_rticks()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_thetagrids()</code> : [[../../Graphiques#Tracé_polaire|1]]
* <code>axes.set_title()</code> : [[../../Graphiques#Exemple|1]]
* <code>axes.set_xlabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_xlim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_xsticks()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* <code>axes.set_ylabel()</code> : [[../../Graphiques#Exemple|1]]
* <code>axis.set_ylim()</code> : [[../../Graphiques#Dessins|1]]
* <code>axis.set_minor_formatter()</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
* ''shebang'' : [[../../Découverte de Python et de Jupyter|1]]
* <code>plt.show()</code> : [[../../Graphiques|1]]
* <code>list.sort()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Listes|1]]
* <code>sorted()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
* <code>str.split()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
* <code>plt.step()</code> : [[../../Graphiques#Autres_exemples_de_tracés_2D|1]]
* <code>plt.subplots()</code> : [[../../Graphiques#Exemple|1]]
* <code>fig.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>plt.suptitle()</code> : [[../../Graphiques#Exemple|1]]
* <code>symlog</code> (paramètre) : [[../../Graphiques#Gestion_des_échelles|1]]
== T ==
* <code>plt.text()</code> : [[../../Graphiques#Annotations|1]]
* <code>plt.title()</code> : [[../../Graphiques|1]]
* <code>aix.transData()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>transform</code> (paramètre) : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* <code>matplotlib.transforms()</code> : [[../../Graphiques#Transformation_des_objets_graphiques|1]]
* Tk (module) : [[../../Éléments_de_programmation#Avec_Tk|1]]
== U ==
* <code>str.upper()</code> : [[../../Éléments_de_programmation#Méthodes_des_chaînes|1]]
== W ==
* <code>where()</code> : [[../../Manipulation_de_matrices#Trouver_une_valeur|1]]
* <code>while</code> : [[../../Éléments_de_programmation#Structures_de_contrôle|1]]
== X ==
* <code>plt.xlabel()</code> : [[../../Graphiques|1]]
== Y ==
* <code>plt.ylabel()</code> : [[../../Graphiques|1]]
== Z ==
* <code>np.zeros()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>np.zeros_like()</code> : [[../../Manipulation_de_matrices#Définir_un_tenseur|1]]
* <code>zip()</code> : [[../../Découverte_de_Python_et_de_Jupyter#Itérable|1]]
----
[[../../Traitement d'images|Traitement d'images]] < [[../../|↑]] >
[[Catégorie:Python pour le calcul scientifique (livre)]]
5u80pv64b22d53a80izrz5555h26uh8
Catégorie:Nietzsche : Introduction à sa philosophie (livre)
14
83862
769312
766871
2026-07-03T03:34:37Z
PandaMystique
119061
769312
wikitext
text/x-wiki
[[Catégorie:Classe 1 - Philosophie et psychologie]]
[[Catégorie:Philosophe]]
hr371r0d0t6xsrg082hlnrrwnxcr2i6
Dictionnaire de philosophie/Dialogue
0
84033
769311
2026-07-03T03:24:57Z
PandaMystique
119061
Page créée avec « {{DicoPhilo|Dialogue|lecture=oui}} [[Fichier:Sanzio 01.jpg|vignette|Raphaël, ''L'École d'Athènes'' (1509-1511), fresque du Vatican. Au centre, Platon et Aristote avancent en conversant : la peinture donne à la philosophie entière la figure d'un entretien qui ne s'interrompt pas.]] Le dialogue occupe dans la philosophie une position singulière, que peu d'autres genres (le traité, la méditation, l'aphorisme, la lettre) peuvent lui disputer : il n'est pas se... »
769311
wikitext
text/x-wiki
{{DicoPhilo|Dialogue|lecture=oui}}
[[Fichier:Sanzio 01.jpg|vignette|Raphaël, ''L'École d'Athènes'' (1509-1511), fresque du Vatican. Au centre, Platon et Aristote avancent en conversant : la peinture donne à la philosophie entière la figure d'un entretien qui ne s'interrompt pas.]]
Le dialogue occupe dans la philosophie une position singulière, que peu d'autres genres (le traité, la méditation, l'aphorisme, la lettre) peuvent lui disputer : il n'est pas seulement une manière d'exposer la pensée, il passe, depuis Socrate, pour la manière dont la pensée se fait. Le mot vient du grec ''dialogos'' (διάλογος), formé sur le verbe ''legein'' (λέγειν), parler, et sur le préverbe ''dia'' (διά), qui signifie « à travers ». Contrairement à une étymologie répandue, ''dia'' ne veut pas dire « deux » : un dialogue peut réunir trois, cinq ou dix interlocuteurs. Ce qui le définit n'est pas le nombre des voix, mais le trajet que le sens accomplit entre elles : le dialogue est ce qui advient à travers la parole échangée, ce ''logos'' qui circule, se heurte, se corrige et, parfois, s'éclaire.
L'histoire de la notion présente un paradoxe. La philosophie s'écrit le plus souvent en traités, en méditations, en articles ; elle est pourtant, telle que Platon en a fixé l'image pour la postérité, née en dialogues, ceux que Socrate menait sur l'agora et que son élève a transformés en œuvres, et elle n'a cessé d'y revenir. La précision s'impose : avant Socrate, la pensée grecque s'énonçait déjà en poèmes, en sentences, en traités, d'Anaximandre à Parménide et à Héraclite ; ce qui naît avec le dialogue n'est donc pas la philosophie elle-même, mais l'image durable de ce qu'elle fait quand elle se cherche. Trois grands moments scandent cette histoire. Le premier est l'invention socratique : l'examen en commun, la réfutation, la mise au monde des idées par la question. Le deuxième est l'histoire du dialogue comme genre littéraire, de Cicéron à Hume et à Diderot, où la fiction d'une conversation sert tour à tour la pédagogie, la prudence face à la censure et la mise en scène de l'indécidable. Le troisième est propre au XX{{e}} siècle : le dialogue cesse alors d'être une forme pour devenir un concept central, chez Martin Buber qui en fait la structure de l'existence, chez Hans-Georg Gadamer qui en fait le modèle de toute compréhension, chez Jürgen Habermas qui en fait la source des normes morales et politiques, chez Emmanuel Levinas qui y lit la naissance même de l'éthique.
L'article suit ces trois moments, puis se retourne sur eux : que faut-il pour qu'un échange de paroles mérite le nom de dialogue ? Et que faire lorsque le dialogue échoue, lorsqu'il exclut, lorsqu'il sert de masque à la force ? La question n'a rien de spéculatif : elle engage la classe, le tribunal, l'hôpital, l'assemblée politique, et jusqu'aux machines qui, désormais, nous répondent.
== Ce que dialoguer veut dire ==
Chacun a fait l'expérience de deux régimes de la parole. Dans le premier, les participants attendent leur tour pour placer ce qu'ils avaient préparé ; les répliques se succèdent sans se toucher ; on sort de l'échange tel qu'on y est entré, conforté et un peu las. Dans le second, une objection nous arrête, une question nous oblige à préciser ce que nous croyions clair, et nous découvrons en parlant une idée que nous n'avions pas en commençant. Le premier régime juxtapose des monologues. Le second seul mérite le nom de dialogue.
Cette expérience commune permet de tracer quelques distinctions. La conversation vise le plaisir de l'échange et la convivialité : elle peut sauter d'un sujet à l'autre, elle n'a pas d'objet obligé et ne doit rien conclure. Le débat oppose des positions arrêtées d'avance devant un tiers, auditoire ou jury, qu'il s'agit de gagner : on peut remporter un débat sans avoir rien appris. La négociation ajuste des intérêts par concessions réciproques : chacun cède un peu pour obtenir beaucoup, et nul n'est tenu de croire ce qu'il concède. Le dialogue, lui, se reconnaît à ceci que les interlocuteurs se soumettent ensemble à un tiers qui n'est ni l'un ni l'autre : la question examinée, ce que Gadamer appellera la chose même (''die Sache selbst''). On n'y cherche pas à vaincre l'autre, mais à trouver avec lui ; et l'on y accepte un risque que le débatteur refuse par principe : celui d'être déplacé, corrigé, changé par ce qui sera dit.
Trois conditions se laissent ainsi dégager. La réciprocité, d'abord : les rôles de questionneur et de répondant doivent pouvoir s'échanger, faute de quoi l'entretien devient interrogatoire ou leçon. La communauté de l'objet, ensuite : il faut que les interlocuteurs parlent de la même chose et se sachent tenus par elle ; deux monologues alternés portent sur deux objets qui se ressemblent. Le risque assumé, enfin : entrer en dialogue, c'est admettre par avance que l'on pourrait en sortir autre, sans quoi l'on n'écoute que pour préparer sa réplique. Ces conditions sont exigeantes ; c'est pourquoi le dialogue est rare, et pourquoi tant d'échanges qui en portent le nom n'en ont que l'apparence.
Une dernière remarque élargit la notion au-delà de la rencontre entre personnes. Platon définit la pensée elle-même comme un dialogue : penser, écrit-il, c'est le discours que l'âme se tient silencieusement à elle-même, s'interrogeant et se répondant, affirmant et niant tour à tour<ref>Platon, ''Théétète'', 189e-190a ; ''Sophiste'', 263e-264a.</ref>. La [[Dictionnaire de philosophie/Conscience|conscience]] qui délibère est déjà une assemblée. Cette définition renverse l'ordre que nous croyons naturel : nous pensons que le dialogue extériorise une pensée d'abord solitaire ; Platon suggère que la pensée solitaire intériorise un dialogue d'abord vécu. La psychologie du développement retrouvera cette intuition : chez Lev Vygotski, le langage intérieur de l'enfant naît de l'intériorisation progressive des échanges avec autrui<ref>Lev Vygotski, ''Pensée et langage'' (1934), trad. Françoise Sève, Paris, La Dispute, 1997, chap. 7.</ref>. Nous ne dialoguons pas parce que nous pensons ; nous pensons parce que nous avons dialogué.
Le mot couvre donc quatre registres que l'article distingue et relie : une pratique (l'examen socratique), un genre d'écriture (de Platon à Diderot), une dimension de l'existence (les philosophies de la relation au XX{{e}} siècle) et une norme (l'éthique de la discussion). Leur unité tient dans l'idée que la [[Dictionnaire de philosophie/Vérité|vérité]] n'est pas un bien que l'on possède et que l'on transmet, mais quelque chose qui se cherche, et qui se cherche mieux à plusieurs.
== Socrate : l'examen en commun ==
[[Fichier:David - The Death of Socrates.jpg|vignette|Jacques-Louis David, ''La Mort de Socrate'' (1787). Jusque dans sa prison, entouré de ses amis, Socrate meurt comme il a vécu : en discutant.]]
=== La réfutation et l'aporie ===
Socrate n'a rien écrit. Ce que nous savons de sa pratique, nous le tenons surtout de [[s:Auteur:Platon|Platon]], et cette pratique tient en une scène mille fois rejouée. Sur l'agora ou dans un gymnase, Socrate aborde un homme réputé compétent : un général à qui il demande ce qu'est le courage, un devin à qui il demande ce qu'est la piété, un rhéteur à qui il demande ce qu'est son art. La question a une forme précise, « qu'est-ce que ? » (''ti esti''), et elle ne demande pas des exemples mais une définition : non pas des actes courageux, mais ce qui fait de tous ces actes des actes courageux. L'interlocuteur répond avec assurance. Socrate le prend au mot, tire les conséquences, les confronte à d'autres convictions du même interlocuteur, et fait apparaître que celui-ci soutient sans le savoir des thèses incompatibles. C'est la réfutation, l{{'}}''elenchos'' (ἔλεγχος) : non pas l'art de contredire, mais l'art de montrer à quelqu'un que son propre discours se contredit.
Le résultat ordinaire de l'examen est l'embarras, ce que les Grecs nomment [[Dictionnaire de philosophie/Aporie|aporie]] (ἀπορία), littéralement l'absence de passage. Ménon, qui discourait sans peine sur la vertu, compare Socrate à ce poisson marin, la torpille, qui engourdit quiconque la touche : le voilà incapable de dire ce qu'il croyait savoir<ref>Platon, ''[[s:Ménon (trad. Cousin)|Ménon]]'', 80a-b.</ref>. L'image dit le malaise, mais Socrate la retourne : la torpille, répond-il en substance, est engourdie elle-même, et l'engourdissement partagé est le commencement de la recherche. La suite du ''Ménon'' le montre en acte. Interrogeant un jeune esclave sur un problème de géométrie, la duplication du carré, Socrate le laisse d'abord répondre de travers avec aplomb, puis l'amène, questions après questions, à reconnaître son erreur, enfin à trouver la solution en examinant des figures tracées sur le sable<ref>Platon, ''Ménon'', 82b-85c.</ref>. Le moment central n'est pas la solution : c'est l'instant où l'esclave, réfuté, passe de la fausse assurance au désir de savoir. Avant, note Socrate, il aurait péroré ; maintenant qu'il éprouve son ignorance, il cherchera volontiers<ref>Platon, ''Ménon'', 84a-c.</ref>. L'aporie n'est pas une panne du dialogue : elle en est le premier fruit.
C'est pourquoi la réfutation, loin d'humilier, purifie. Un passage du ''Sophiste'' décrit l{{'}}''elenchos'' comme la plus grande des purifications : celui qui se croit savant est comme un malade qui refuse le remède ; il faut d'abord le délivrer des opinions qui obstruent son âme, comme le médecin purge le corps avant de le nourrir<ref>Platon, ''Sophiste'', 230b-e.</ref>. Socrate se dit d'ailleurs le premier bénéficiaire de l'épreuve. Au rhéteur Gorgias, il déclare être de ces hommes qui ont plaisir à être réfutés quand ils se trompent, autant qu'à réfuter autrui, car c'est un plus grand bien d'être délivré du plus grand mal, l'opinion fausse, que d'en délivrer un autre<ref>Platon, ''[[s:Gorgias (trad. Cousin)|Gorgias]]'', 458a.</ref>. Et lorsque Polos, plus tard dans le même entretien, croit l'écraser en invoquant l'opinion de tous, Socrate répond que les témoins ne comptent pas en philosophie : un seul témoignage l'intéresse, celui de son interlocuteur, et la vérité ne s'établit pas à la majorité des voix<ref>Platon, ''Gorgias'', 471e-472c.</ref>. Le dialogue socratique est ce tribunal étrange où chacun n'a jamais qu'un juge, celui qui lui fait face, et où perdre son procès est la meilleure des issues.
Cette pratique engage une conception de l'existence. Au tribunal qui va le condamner, Socrate déclare qu'une vie sans examen ne vaut pas d'être vécue par un homme<ref>Platon, ''[[s:Apologie de Socrate (trad. Cousin)|Apologie de Socrate]]'', 38a.</ref>. La formule est célèbre ; on oublie parfois que l'examen dont il parle n'est pas une introspection solitaire, mais l'épreuve quotidienne de la discussion, s'examiner soi-même et les autres. La philosophie, sous la figure que Socrate lui imprime et que l'Occident retiendra, naît comme une activité à deux voix.
=== La maïeutique : accoucher les esprits ===
Le ''Théétète'' donne à cette activité son image la plus durable. Socrate y confie exercer le métier de sa mère, la sage-femme Phénarète, à cette différence près qu'il accouche les hommes et non les femmes, les âmes et non les corps<ref>Platon, ''[[s:Théétète (trad. Cousin)|Théétète]]'', 148e-151d.</ref>. C'est la maïeutique (μαιευτική), l'art de l'accouchement. Comme les sages-femmes, dit-il, il est lui-même stérile : le dieu le contraint d'aider les autres à enfanter sans rien enfanter lui-même<ref>Platon, ''Théétète'', 150c-d.</ref>. Sa fonction est double : provoquer le travail par ses questions, puis éprouver le nouveau-né, distinguer l'idée viable du simple vent. Beaucoup des pensées qu'il aide à naître ne survivent pas à l'examen ; l'essentiel est que celui qui les portait le découvre lui-même.
L'image maïeutique s'oppose terme à terme à une autre représentation du savoir, que Platon récuse ailleurs par une comparaison restée fameuse : au début du ''Banquet'', Socrate raille l'espoir d'Agathon de voir la sagesse couler du plus plein vers le plus vide par simple contact, comme l'eau passe d'une coupe à l'autre le long d'un brin de laine<ref>Platon, ''[[s:Le Banquet (trad. Cousin)|Banquet]]'', 175d-e.</ref>. Le savoir ne se verse pas. Il ne se transmet pas comme un contenu que le maître posséderait et que l'élève recevrait ; il se forme dans celui qui cherche, et la parole d'autrui n'y sert ni de récipient ni de tuyau, mais d'instrument obstétrical. Toute pédagogie du dialogue, jusqu'aux pratiques contemporaines de la discussion à visée philosophique, vit de cette intuition : on n'apprend à penser qu'en pensant, et l'on ne pense d'abord qu'interrogé.
La maïeutique a pourtant ses ombres, que les lecteurs de Platon n'ont pas manqué de relever. Celui qui conduit l'accouchement choisit les questions, et qui choisit les questions oriente les réponses : l'esclave du ''Ménon'' trouve, mais il trouve ce que Socrate lui fait trouver. L'égalité des interlocuteurs, que le dialogue semble promettre, coexiste avec une asymétrie des rôles que Socrate ne dissimule d'ailleurs pas. Le dialogue socratique n'est pas une conversation entre égaux : c'est une relation orientée, où l'un sait au moins questionner. Cette tension entre réciprocité proclamée et direction effective accompagnera toute l'histoire de la notion.
=== Dialogue, éristique, rhétorique ===
Pour comprendre ce que Socrate invente, il faut voir contre quoi il l'invente. Athènes est pleine de paroles : celle des assemblées, celle des tribunaux, celle des maîtres qui enseignent à bien parler. Le dialogue socratique se définit contre deux contrefaçons qui lui ressemblent comme des sœurs.
La première est l'éristique (du grec ''eris'', la querelle) : l'art de vaincre dans la discussion, quel que soit le vrai. L{{'}}''Euthydème'' met en scène deux frères sophistes qui réfutent n'importe quelle thèse et son contraire, par jeu et pour la gloire ; les coups portent, l'auditoire rit, personne n'apprend rien. La différence avec l{{'}}''elenchos'' ne tient pas à la technique, souvent identique, mais à la visée : l'éristique vise l'adversaire, le dialogue vise la chose. L'un veut avoir raison, l'autre veut que raison soit rendue, à qui que ce soit.
La seconde contrefaçon est la rhétorique, l'art des longs discours qui persuadent une foule. Dès l'ouverture du ''Gorgias'', Socrate demande à son hôte de renoncer aux tirades et de bien vouloir répondre brièvement, question après question : il oppose le ''dialegesthai'', l'entretien serré, à la ''makrologia'', le discours-fleuve qui subjugue sans instruire<ref>Platon, ''Gorgias'', 448d-449c.</ref>. L'enjeu n'est pas une affaire de format. Une foule ne peut ni interrompre, ni demander une précision, ni objecter : elle subit le discours. Un interlocuteur peut tout cela : il le contrôle. Le passage du grand discours au dialogue est le passage d'une parole qui s'impose à une parole qui s'expose.
Le ''Protagoras'' montre ce que coûte cette exigence. Au milieu de l'entretien, Protagoras, pressé par les questions, se réfugie dans un long développement ; Socrate, qui se dit incapable de suivre les discours étendus, menace de s'en aller ; l'assistance s'interpose, on négocie, et l'on convient de règles : questions brèves, réponses brèves, rôles échangeables<ref>Platon, ''[[s:Protagoras (trad. Cousin)|Protagoras]]'', 334c-338e.</ref>. La scène, presque comique, enseigne quelque chose d'essentiel : le dialogue ne va pas de soi, il repose sur un accord préalable quant à ses propres règles, accord toujours révocable et parfois arraché. D'autres scènes rappellent sa fragilité : au premier livre de la ''République'', Thrasymaque, excédé d'écouter, bondit sur les interlocuteurs « comme une bête fauve », et il faut l'apprivoiser avant de pouvoir discuter<ref>Platon, ''[[s:La République (trad. Cousin)|République]]'', I, 336b.</ref>. Le dialogue est une paix armée conclue au bord de l'affrontement, et qui peut à tout instant y retomber.
Aristote résumera d'un trait la position singulière de Socrate dans ce paysage : il interrogeait mais ne répondait pas, car il reconnaissait ne pas savoir<ref>Aristote, ''Réfutations sophistiques'', 34, 183b.</ref>. L'aveu d'ignorance n'est pas une coquetterie : il est la condition qui empêche l'entretien de se refermer en leçon. Celui qui sait n'a plus besoin de personne ; celui qui sait qu'il ne sait pas a besoin de tous.
== Platon : pourquoi écrire des dialogues ? ==
=== Une forme qui pense ===
Le plus étrange n'est pas que Socrate ait dialogué : c'est que Platon, si l'on met à part les Lettres transmises sous son nom, dont l'authenticité est discutée, ait écrit des dialogues, et presque rien que des dialogues. L'un des plus grands écrivains de la philosophie ne s'exprime jamais en son nom. Il ne figure que deux fois dans son œuvre, et comme en creux : présent parmi d'autres au procès de Socrate, absent, « malade », le jour de sa mort<ref>Platon, ''Apologie de Socrate'', 34a et 38b ; ''Phédon'', 59b.</ref>. Aucun traité, aucune préface, aucun « je pense que ». Le lecteur cherche la doctrine de Platon comme on cherche l'auteur dans une pièce de théâtre : elle est partout et nulle part, distribuée entre des voix dont aucune ne porte officiellement la sienne.
Cet anonymat n'est pas une coquetterie littéraire, c'est un dispositif. Puisque personne ne parle au nom de l'auteur, le lecteur ne peut pas recevoir : il doit juger. Qui a raison, de Socrate ou de Calliclès ? Le texte ne le dit pas à sa place ; il donne à chacun ses meilleures armes et laisse le procès ouvert. Les personnages ne sont pas des porte-voix mais des positions incarnées : Calliclès n'est pas un argument sur la loi du plus fort, c'est une manière de vivre qui argumente ; le réfuter suppose de comprendre ce qui, dans une vie, le rend désirable. La forme dialoguée permet ainsi ce qu'aucun traité ne permet : montrer les idées aux prises avec les caractères, les résistances, la mauvaise foi, la séduction, la colère, bref avec tout ce qui fait qu'un raisonnement, dans la vie, ne suffit presque jamais.
Elle permet même de montrer l'échec. Vers la fin du ''Gorgias'', Calliclès, lassé d'être réfuté, refuse de continuer à répondre ; et Socrate, pour achever l'examen, en est réduit à poursuivre seul, se posant les questions et y répondant tour à tour<ref>Platon, ''Gorgias'', 505e-506c.</ref>. La scène est d'une ironie amère : le champion du dialogue finit en monologue, faute de partenaire. Platon ne cache pas cette limite, il la met en scène : on ne dialogue pas avec qui refuse de jouer, et la parole la plus droite ne peut rien contre un silence décidé. Les dialogues dits aporétiques, qui s'achèvent sans réponse, relèvent du même courage formel : plutôt qu'un savoir de façade, l'aveu écrit d'une recherche inachevée.
La forme varie d'ailleurs avec l'âge de l'œuvre. Aux entretiens vifs et sans conclusion des premiers dialogues succèdent des œuvres où Socrate expose longuement, à peine relancé par des répondants dociles, comme dans la ''République'' ; les dialogues tardifs se font plus techniques, et les ''Lois'', ultime ouvrage, n'ont même plus Socrate. La critique y a souvent lu un déclin du dialogue vers le traité déguisé. C'est possible ; c'est aussi le signe que Platon a exploré toutes les puissances du genre, du drame aporétique à l'exposé conduit, y compris ses formes emboîtées : le ''Banquet'' nous parvient comme le récit d'un récit, Apollodore rapportant ce qu'Aristodème lui a raconté d'un banquet ancien, où Socrate lui-même rapporte l'enseignement d'une femme, Diotime<ref>Platon, ''Banquet'', 172a-174a et 201d.</ref>. La vérité y passe de bouche en bouche, toujours reçue, jamais possédée : la structure narrative dit déjà la thèse.
=== La critique de l'écriture ===
Il y a plus déconcertant encore : Platon, écrivain, a écrit contre l'écriture. À la fin du ''[[s:Phèdre (Platon, trad. Cousin)|Phèdre]]'', Socrate rapporte un mythe égyptien : le dieu Theuth, inventeur des lettres, les présente au roi Thamous comme un remède (''pharmakon'') pour la mémoire et la sagesse ; le roi répond que ce prétendu remède sera un poison, car le même mot grec dit les deux : les hommes, se fiant aux signes écrits, cesseront d'exercer leur mémoire, et prendront l'apparence du savoir pour le savoir<ref>Platon, ''Phèdre'', 274e-275b.</ref>. Suit le réquisitoire. L'écrit ressemble à la peinture : ses créatures se tiennent devant nous comme des vivants, mais si on les interroge, elles gardent un silence plein de majesté. Interrogez un livre : il répète indéfiniment la même chose. Il roule de tous côtés, entre les mains de ceux qui le comprennent et de ceux qu'il n'aurait jamais dû toucher, sans savoir à qui il doit parler et à qui se taire ; et quand on le maltraite, il ne peut se défendre seul, il a toujours besoin du secours de son père<ref>Platon, ''Phèdre'', 275d-e.</ref>. À ce discours orphelin, Socrate oppose le discours vivant et animé, celui qui s'écrit avec la science dans l'âme de celui qui apprend, qui sait devant qui parler et devant qui se taire, et qui peut se porter secours à lui-même<ref>Platon, ''Phèdre'', 276a-277a.</ref>. Autrement dit : le dialogue.
La ''Lettre VII'', si elle est authentique, prolonge le propos : sur ce qui lui tient le plus à cœur, écrit son auteur, il n'existe et n'existera jamais d'ouvrage de Platon, car cela ne se laisse pas dire comme les autres savoirs ; c'est d'un long commerce avec la chose même et de la vie partagée que la lumière jaillit soudain dans l'âme, comme la flamme naît d'une étincelle<ref>Platon, ''Lettre VII'', 341c-d. L'authenticité de la lettre est discutée depuis l'Antiquité ; la critique récente reste partagée.</ref>. Qu'on prête ou non ces lignes à Platon, elles disent avec force ce que le ''Phèdre'' suggère : le savoir qui compte n'est pas un contenu transportable, mais l'effet d'une fréquentation, et la fréquentation demande la présence.
Reste le paradoxe, que Platon ne pouvait ignorer : cette critique de l'écrit, nous la lisons dans un livre. La réponse la plus convaincante tient à la forme même de l'œuvre. Si l'on doit écrire, il faut écrire ce qui ressemble le moins à un livre et le plus à une parole vivante : non des thèses, mais des conversations, avec leurs questions, leurs objections, leurs détours, leurs silences et leurs échecs. Le dialogue écrit est un texte qui met en scène sa propre discussion, qui inscrit l'objection dans sa structure et qui, ne donnant jamais le dernier mot à l'auteur, contraint le lecteur à le chercher. Il ne supprime pas les défauts de l'écrit ; il les combat de l'intérieur, en faisant du lecteur ce que le livre ordinaire ne peut pas avoir : un interlocuteur.
=== Le dialogue de l'âme avec elle-même ===
On a rencontré plus haut la définition du ''Théétète'' et du ''Sophiste'' : penser, c'est dialoguer silencieusement avec soi-même<ref>Platon, ''Théétète'', 189e-190a ; ''Sophiste'', 263e-264a.</ref>. Il faut en mesurer la portée. Si la pensée est un dialogue intérieur, alors le dialogue n'est pas un habillage social que la pensée revêtirait pour sortir : il est sa forme native, et la méditation solitaire elle-même reste une scène à plusieurs voix, où je me questionne, me réponds, m'objecte. L'opinion (''doxa'') est définie dans le même passage comme l'arrêt de ce dialogue : le moment où l'âme, cessant de balancer, affirme d'une seule voix. Penser, c'est tenir l'assemblée ouverte ; opiner, c'est la clore. On comprend mieux, dès lors, pourquoi la fausse assurance est l'ennemie première de Socrate : elle n'est pas une erreur parmi d'autres, elle est la fin prématurée du dialogue intérieur, que la réfutation vient rouvrir du dehors.
== La dialectique réglée : d'Aristote à la disputatio ==
=== Aristote : l'entretien comme exercice ===
[[Dictionnaire de philosophie/Aristote|Aristote]] hérite du dialogue socratique et lui fait subir un traitement qui lui ressemble : il le codifie. Ses propres dialogues, qui firent l'admiration de l'Antiquité, ce « fleuve d'or » dont parlait Cicéron, sont perdus<ref>Cicéron, ''Secondes Académiques'', II, 38, 119.</ref> ; ce qui nous reste, dans les ''Topiques'', est autre chose : le manuel d'un art réglé de la discussion. Deux rôles y sont distribués, un questionneur et un répondant ; une thèse est posée ; le questionneur doit conduire le répondant à la contradiction, le répondant défendre sa position sans incohérence. Le raisonnement dialectique se définit par ses prémisses : il ne part pas, comme la démonstration scientifique, de propositions vraies et premières, mais des ''endoxa'' (ἔνδοξα), les opinions autorisées, celles qu'admettent tous les hommes, ou la plupart, ou les plus sages<ref>Aristote, ''Topiques'', I, 1, 100a25-100b23.</ref>. La [[Dictionnaire de philosophie/Dialectique|dialectique]] est ainsi l'art de raisonner correctement en terrain partagé, distincte à la fois de la science, qui prouve, et de l'éristique, qui triche en partant d'opinions qui semblent admises sans l'être. Le mot change ici discrètement de portée : ce que la dialectique règle n'est plus la rencontre singulière de deux esprits, c'est une procédure d'examen des thèses, que n'importe quel couple d'interlocuteurs exercés peut faire fonctionner.
À quoi bon cet art ? Aristote répond avec précision : il sert à l'exercice de l'esprit, comme une gymnastique ; il sert dans les rencontres, pour discuter avec le grand nombre à partir de ses propres convictions plutôt que d'un savoir qu'il n'a pas ; il sert enfin aux sciences philosophiques elles-mêmes, car développer les difficultés dans les deux sens rend plus apte à discerner le vrai du faux, et parce que les principes premiers de chaque science, indémontrables par elle, ne peuvent être abordés que par l'examen des opinions reçues<ref>Aristote, ''Topiques'', I, 2, 101a25-101b4.</ref>. Le dernier point est le plus fort : au sommet du savoir, là où la démonstration ne peut plus rien puisqu'il s'agit de ses propres points de départ, on retrouve la discussion. La méthode d'Aristote en porte partout la marque : ses traités s'ouvrent presque toujours par la revue des opinions antérieures et le développement méthodique des difficultés (''diaporêsai''), dialogue avec les absents qui tient lieu d'entretien.
Avec Aristote, le dialogue change ainsi de statut : de rencontre de rue, il devient institution scolaire, joute réglée dont l'Académie puis le Lycée font un instrument de formation. Il y perd en imprévu ce qu'il gagne en rigueur ; il y gagne surtout une postérité.
=== La disputatio médiévale ===
Cette postérité a un nom : la ''disputatio'', cœur battant de l'université médiévale. L'enseignement y repose sur deux exercices, la ''lectio'', lecture commentée des textes, et la ''disputatio'', discussion publique d'une question. La procédure est strictement dialogique : une question est posée (''quaestio'') ; des arguments sont d'abord donnés contre la position que le maître soutiendra (''videtur quod non'') ; une autorité contraire est citée (''sed contra'') ; le maître expose alors sa solution (''respondeo'') ; enfin, chaque objection initiale reçoit une réponse motivée. Les grandes sommes scolastiques conservent cette structure comme un fossile vivant : chaque article de la ''Somme de théologie'' de Thomas d'Aquin est un micro-dialogue cristallisé, qui commence par donner la parole à l'adversaire<ref>La structure est constante dans toute la ''Somme de théologie'' ; voir par exemple Thomas d'Aquin, ''Somme de théologie'', I, question 2, article 3, où les objections contre l'existence de Dieu ouvrent l'article.</ref>. Détail qui n'en est pas un : l'objection vient toujours en premier, et la règle du jeu exige de lui donner sa force la plus grande. La scolastique a fait de la charité interprétative une obligation de méthode bien avant que la philosophie contemporaine ne lui donne ce nom.
L'esprit de l'exercice s'exprime dans une œuvre qui le précède et l'annonce : le ''Sic et non'' de Pierre Abélard, recueil de cent cinquante-huit questions sur lesquelles sont rassemblées, sans solution, des autorités qui affirment et des autorités qui nient. Le prologue en donne la raison : c'est en doutant que nous venons à l'enquête, et c'est en enquêtant que nous atteignons la vérité (« Dubitando quippe ad inquisitionem venimus ; inquirendo veritatem percipimus »)<ref>Pierre Abélard, ''Sic et non'', prologue.</ref>. Le désaccord des autorités n'est pas un scandale à cacher : c'est le moteur de la recherche, et l'exposer en deux colonnes, c'est déjà instituer un dialogue entre les textes.
L'institution eut ses grandeurs et ses ridicules. Grandeur des ''disputationes de quolibet'', séances où le maître répondait à n'importe quelle question posée par n'importe qui, épreuve publique sans filet ; ridicule, à la longue, d'un formalisme où la subtilité tourne à vide, que les humanistes de la Renaissance ne se lasseront pas de moquer. Mais la structure a survécu à ses excès : la soutenance de thèse, la controverse académique, l'évaluation par les pairs, jusqu'à la section « objections et réponses » de nos articles, descendent en droite ligne de la ''disputatio''. L'université moderne discute encore, pour une part, dans des formes héritées du XIII{{e}} siècle, en croyant souvent les avoir inventées ; l'imprimé, la revue savante, la spécialisation des disciplines et l'anonymat de l'expertise ont transformé l'exercice, mais son squelette, soumettre toute thèse à l'objection avant de la recevoir, reste celui de l'école médiévale.
=== Dialoguer entre les religions ===
Le Moyen Âge a aussi tenté le dialogue le plus difficile, celui des religions. Abélard, encore lui, compose un ''Dialogue entre un philosophe, un juif et un chrétien'' où les trois protagonistes prennent la raison pour arbitre de leur différend<ref>Pierre Abélard, ''Conférences'' (''Collationes''), trad. Maurice de Gandillac, Paris, Éditions du Cerf, 1993.</ref>. Près d'un siècle et demi plus tard, le Majorquin Raymond Lulle écrit le ''Livre du gentil et des trois sages'' : un païen en quête de vérité écoute un juif, un chrétien et un musulman exposer tour à tour leur foi, sans s'interrompre ni s'injurier ; et quand, au terme du parcours, le gentil s'apprête à révéler laquelle l'a convaincu, les trois sages refusent de l'entendre, afin de pouvoir continuer à chercher ensemble<ref>Raymond Lulle, ''Le Livre du gentil et des trois sages'' (v. 1274-1276), épilogue.</ref>. Cette fin suspendue est peut-être la plus belle définition médiévale du dialogue : la recherche commune y vaut mieux que la victoire, et connaître le vainqueur tuerait la recherche. L'année même de la chute de Constantinople paraît enfin le ''De pace fidei'' de Nicolas de Cues (1453) : bouleversé par la nouvelle, l'auteur imagine un concile céleste où les sages de toutes les nations découvrent, sous la diversité des cultes, une seule religion dans la variété des rites (« una religio in rituum varietate »)<ref>Nicolas de Cues, ''De pace fidei'' (1453), chap. I.</ref>.
Il ne faut pas embellir : ces dialogues restent écrits d'une seule main, dans un cadre chrétien, et leur issue est rarement aussi ouverte que chez Lulle. Mais l'idée qui s'y forme traversera les siècles : là où la guerre tranche les différends par la force, le dialogue les confie à la parole, et ce transfert, même imparfait, même inégal, change la nature du conflit. On la retrouvera, formulée dans d'autres termes, au cœur des éthiques de la discussion contemporaines.
== L'âge classique : un genre pour penser librement ==
=== Montaigne : l'art de conférer ===
La Renaissance redécouvre les dialogues antiques et en fait un genre à la mode, d'Érasme, dont les ''Colloques'' apprennent le latin et la vie aux écoliers de toute l'Europe, aux dialogues italiens de cour. Mais c'est [[s:Auteur:Michel de Montaigne|Montaigne]] qui donne à la conversation sa philosophie. L'essai ''De l'art de conférer'' s'ouvre sur une déclaration sans détour : le plus fructueux et naturel exercice de notre esprit, c'est à son gré la conférence, c'est-à-dire, dans la langue du temps, la conversation, l'échange<ref>Michel de Montaigne, ''[[s:Essais/Livre III/Chapitre 8|Essais]]'', III, 8, « De l'art de conférer ».</ref>. Il en fait un exercice au sens plein, comparable à ceux du corps : l'étude des livres est un mouvement languissant ; la conférence apprend et exerce en même temps, car elle nous met aux prises avec des esprits qui répliquent.
Encore faut-il de la « forte partie » : Montaigne veut des contradicteurs vigoureux et redoute les approbations molles, qui n'apprennent rien. Il fait profession d'accueillir la correction d'où qu'elle vienne : « je festoie et caresse la vérité en quelque main que je la trouve, et m'y rends allègrement », écrit-il, tendant les armes à qui le reprend<ref>Montaigne, ''Essais'', III, 8.</ref>. La règle d'or de l'art de conférer est de dissocier la cause et la personne : c'est la thèse qu'on attaque, non l'homme, et c'est par la force des raisons qu'on se laisse vaincre, non par l'autorité ni par le nombre. Montaigne avoue la difficulté, décrit avec humour l'aigreur des disputes réelles, les querelles de mots, la vanité blessée ; son essai vaut précisément parce qu'il ne décrit pas un idéal, mais une pratique avec ses ratés. Trois siècles avant les éthiques de la discussion, tout y est déjà : la contradiction comme service rendu, l'égalité des raisons contre l'inégalité des rangs, et le plaisir, ce mot qui revient sans cesse, car pour Montaigne la conférence est d'abord une joie.
=== Le dialogue des systèmes : Galilée, Berkeley, Hume ===
L'âge classique fait du dialogue un genre à tout faire, et d'abord un abri. En 1632, Galilée publie son ''Dialogue sur les deux grands systèmes du monde'' : quatre journées de conversation dans un palais vénitien entre Salviati, qui défend Copernic, Simplicio, qui défend Aristote et Ptolémée, et Sagredo, honnête homme curieux qui écoute, questionne et penche peu à peu<ref>Galilée, ''Dialogue sur les deux grands systèmes du monde'' (1632), trad. René Fréreux avec le concours de François de Gandt, Paris, Éditions du Seuil, 1992.</ref>. La forme dialoguée devait protéger l'auteur : on n'affirme pas, on fait discuter des personnages, et l'ouvrage s'achève prudemment sans verdict. Elle précipita sa perte : le pape Urbain VIII reconnut l'un de ses arguments favoris placé dans la bouche de Simplicio, dont le nom sonnait comme « simplet », et le procès de 1633 suivit. L'épisode dit les deux faces du genre : écran commode pour avancer masqué, il est aussi une arme, car distribuer les rôles, c'est déjà juger. Quant à Sagredo, le tiers sans doctrine, il est la vraie invention du livre : ni savant ni docteur, il est la figure du lecteur dans le texte, celui dont l'assentiment se gagne, et par qui la science se fait publique. Fontenelle s'en souviendra dans ses ''[[s:Entretiens sur la pluralité des mondes|Entretiens sur la pluralité des mondes]]'' (1686), où l'astronomie nouvelle s'expose au fil de promenades nocturnes avec une marquise : la vulgarisation scientifique naît en forme de dialogue, et ce n'est pas un hasard, car expliquer, c'est répondre à des questions, et il faut bien quelqu'un pour les poser.
Le genre sert aussi la métaphysique. Malebranche donne avec les ''Entretiens sur la métaphysique et sur la religion'' (1688) un dialogue d'école, où Théodore conduit fermement le docile Ariste ; Berkeley, avec les ''Trois dialogues entre Hylas et Philonous'' (1713), quelque chose de plus vif : Hylas, dont le nom grec dit la matière, y défend le sens commun contre Philonous, l'ami de l'esprit, qui le mène pas à pas à l'immatérialisme. La doctrine la plus déroutante du siècle, il n'y a pas de matière, s'y présente comme le résultat d'une conversation où le lecteur voit chaque concession arrachée, et peut, à chaque pas, mesurer s'il l'aurait accordée.
C'est [[s:Auteur:David Hume|Hume]] qui donne au genre l'un de ses accomplissements philosophiques les plus subtils. Ses ''[[s:Dialogues sur la religion naturelle|Dialogues sur la religion naturelle]]'', publiés après sa mort en 1779, font discuter trois personnages : Cléanthe, qui prouve Dieu par l'ordre du monde comme on prouve un horloger par la montre, Déméa, qui juge cette théologie expérimentale indigne et s'en remet à l'a priori et à la foi, et Philon, sceptique, qui presse les deux autres de questions<ref>David Hume, ''Dialogues sur la religion naturelle'' (1779), trad. Michel Malherbe, Paris, Vrin, 1987.</ref>. L'équilibre des voix est si soigneusement tenu que les interprètes discutent encore : le jeune Pamphile, narrateur, conclut que les principes de Cléanthe approchent le plus de la vérité, mais les arguments les plus forts semblent revenir à Philon, et Hume laisse le lecteur arbitrer<ref>Hume, ''Dialogues sur la religion naturelle'', XII{{e}} partie et conclusion de Pamphile.</ref>. Ici, la forme dialoguée n'est plus un abri ni un ornement : elle est l'exacte expression épistémologique du sujet traité. Sur une question où, selon Hume, l'évidence ne permet pas de conclure, le traité mentirait par sa forme même ; seul le dialogue, qui distribue les raisons sans les totaliser, épouse l'état réel de la question. Le genre trouve là l'une de ses justifications les plus fortes : il est la forme littéraire de l'indécidable.
La philosophie moderne semble pourtant, dans le même temps, tourner le dos au dialogue : [[Dictionnaire de philosophie/René Descartes|Descartes]] pense seul, au coin de son poêle, et la méditation remplace l'entretien. Le contraste mérite d'être nuancé. Descartes a laissé un dialogue inachevé, ''La Recherche de la vérité par la lumière naturelle'' ; surtout, il a fait précéder la publication des ''Méditations métaphysiques'' d'un geste qui institutionnalise la discussion : il fit circuler le manuscrit, recueillit six séries d'objections, de Hobbes, de Gassendi, d'Arnauld et d'autres, y répondit point par point, et publia le tout ensemble, objections et réponses comprises<ref>René Descartes, ''Méditations métaphysiques'' (1641), publiées avec les ''Objections et Réponses''.</ref>. Le livre le plus solitaire du siècle paraît ainsi flanqué de son propre procès. Le dialogue ne disparaît pas de la philosophie moderne : il émigre de la fiction vers la controverse réelle, correspondances, journaux savants, académies, cette conversation écrite à l'échelle de l'Europe que le siècle nommera la République des Lettres.
=== Diderot : la pensée en mouvement ===
Chez [[s:Auteur:Denis Diderot|Diderot]], le dialogue cesse d'être un véhicule pour devenir un laboratoire. Presque toute son œuvre philosophique parle à deux voix : l{{'}}''[[s:Entretien entre d’Alembert et Diderot|Entretien entre d'Alembert et Diderot]]'', où le matérialisme s'invente en conversation ; ''Le Rêve de d'Alembert'', où la pensée se poursuit jusque dans le sommeil du géomètre, commentée à son chevet ; le ''Supplément au voyage de Bougainville'', où deux interlocuteurs anonymes font dialoguer l'Europe avec Tahiti ; ''Jacques le fataliste'', qui va jusqu'à prendre le lecteur à partie et à discuter avec lui la suite du récit. Le chef-d'œuvre du genre est ''[[s:Le Neveu de Rameau|Le Neveu de Rameau]]'' : Moi, philosophe posé, y rencontre Lui, bohème génial et cynique, parasite lucide qui dit tout haut ce que la société fait tout bas. Lui énonce des vérités que Moi ne peut ni admettre ni réfuter ; aucun des deux ne l'emporte, et le texte s'achève sur un « rira bien qui rira le dernier » qui ne tranche rien. Hegel, qui traduisit des passages du ''Neveu'' et le cita dans la ''Phénoménologie de l'esprit'', y reconnut la conscience déchirée de la culture moderne, dont le langage brillant et disloqué dit la vérité mieux que le discours honnête et posé<ref>G. W. F. Hegel, ''Phénoménologie de l'esprit'' (1807), chapitre VI, section « L'esprit devenu étranger à lui-même ; la culture », où ''Le Neveu de Rameau'' est cité.</ref>. Diderot montre ce que le dialogue permet et que rien d'autre ne permet : penser contre soi sans se renier, donner voix à ce qui, en nous, objecte.
Après les Lumières, le genre décline. Le traité systématique, la leçon universitaire, puis l'article de revue s'imposent comme les formes sérieuses du philosopher ; le dialogue paraît littéraire, donc suspect. Il survit en marge, chez Leopardi dont les ''Petites œuvres morales'' font converser la Nature et un Islandais, chez Valéry qui ressuscite Socrate aux Enfers dans ''Eupalinos'', et il faudra attendre le XX{{e}} siècle pour que le dialogue revienne au centre, non plus comme genre, mais comme concept.
== Le XX{{e}} siècle : les philosophies du dialogue ==
Au sortir de la Première Guerre mondiale, dans l'espace de langue allemande, une constellation de penseurs, souvent issus de la tradition juive (Buber, Rosenzweig, plus tard Levinas, qui écrira en français), mais non exclusivement (Jaspers suit un chemin voisin), opère ce qu'on a appelé le tournant dialogique. Leur point de départ commun est un refus : celui de la philosophie du sujet solitaire, ce moi souverain qui, de Descartes à l'idéalisme, constitue le monde depuis sa conscience et rencontre autrui en dernier, comme un problème. Contre elle, ils soutiennent que la relation précède les termes qu'elle relie : je ne suis pas d'abord un moi qui, ensuite, rencontrerait un toi ; c'est dans la rencontre que le moi advient. Le dialogue cesse ici d'être une méthode ou un genre : il devient la structure même de l'existence humaine.
=== Buber : Je et Tu ===
Le livre-manifeste de ce courant est ''Ich und Du'' de Martin Buber (1923), traduit en français sous le titre ''Je et Tu''. Sa thèse tient en une distinction : l'homme ne dit pas des mots isolés, il dit des mots fondateurs qui sont des couples, et il n'y en a que deux, Je-Tu et Je-Cela<ref>Martin Buber, ''Je et Tu'' (''Ich und Du'', 1923), trad. Geneviève Bianquis, Paris, Aubier, 1969, première partie.</ref>. Dire Je-Cela, c'est se rapporter au monde comme à un ensemble d'objets que l'on perçoit, utilise, classe et connaît : régime nécessaire, celui de l'expérience et de la technique, mais où l'autre n'est jamais qu'une chose parmi les choses, fût-elle une personne dont j'observe les qualités. Dire Je-Tu, c'est tout autre chose : se tenir en présence de quelqu'un, de tout son être, dans une réciprocité qui n'est pas un savoir. Le Tu n'est pas un objet mieux traité : il n'est pas un objet du tout. Et le Je lui-même n'est pas le même dans les deux couples : le Je du Je-Cela possède et mesure ; le Je du Je-Tu se tient en relation. D'où les formules les plus citées du livre : au commencement est la relation (« Im Anfang ist die Beziehung »), et je deviens Je au contact du Tu (« Ich werde am Du »)<ref>Buber, ''Je et Tu'', première partie.</ref>. La relation n'est pas quelque chose qui arrive à des individus déjà constitués ; c'est en elle que l'individu se constitue.
Buber donne un lieu à cette relation : l'entre-deux (''das Zwischen''), sphère propre du dialogue, qui n'est ni en moi ni en toi, mais entre nous, et qui n'existe que le temps de la rencontre. Car telle est la mélancolie du livre : la relation ne dure pas. Tout Tu, écrit Buber, est condamné à redevenir un Cela ; la présence retombe en expérience, la rencontre en souvenir, l'être aimé en personne dont on connaît les habitudes. Le dialogue n'est pas un état que l'on possède, c'est un événement qui advient, et notre monde moderne, monde du Cela hypertrophié, de l'organisation et de l'usage, lui laisse de moins en moins de place. Dans un essai ultérieur, ''Dialogue'' (''Zwiesprache'', 1932), Buber affine le diagnostic en distinguant trois figures : le dialogue accompli, où chacun se tourne réellement vers l'autre ; le dialogue technique, simple échange d'informations qu'exige la marche des affaires ; et le monologue déguisé en dialogue, où deux hommes qui se parlent ne s'adressent en réalité qu'à eux-mêmes<ref>Martin Buber, ''Dialogue'' (''Zwiesprache'', 1932), dans ''La Vie en dialogue'', Paris, Aubier, 1959.</ref>. Chacun reconnaîtra la troisième figure : c'est la réunion où l'on n'écoute l'autre que pour guetter le moment de reprendre la parole. Buber ne condamne pas les deux premières ; il demande seulement qu'on ne prenne pas l'échange utile, ni la juxtaposition sonore des monologues, pour la rencontre.
=== Rosenzweig et Jaspers : le temps de la parole ===
Franz Rosenzweig, ami de Buber avec qui il traduira la Bible en allemand, donne au courant sa version la plus spéculative dans ''L'Étoile de la rédemption'' (1921), puis sa formulation la plus nette dans un essai de 1925, « La pensée nouvelle ». La pensée ancienne, y explique-t-il, pense pour personne et hors du temps : le penseur solitaire sait d'avance où son raisonnement le mène, et rien de ce qui arrive ne peut l'en détourner. La pensée nouvelle est une pensée parlante (''Sprachdenken'') : elle a besoin d'autrui et elle prend le temps au sérieux, car parler, c'est ne pas savoir d'avance ce que l'autre va dire, c'est attendre sa réplique, c'est recevoir de lui ses propres mots transformés<ref>Franz Rosenzweig, « La pensée nouvelle » (''Das neue Denken'', 1925) ; voir ''L'Étoile de la rédemption'' (1921), trad. Alexandre Derczanski et Jean-Louis Schlegel, Paris, Éditions du Seuil, 1982.</ref>. Le penseur peut être pauvre en monde : le parleur, jamais, car il vit de la présence d'un autre. Chez Karl Jaspers enfin, la communication devient le critère même de l'existence authentique : la vérité qui compte ne se possède pas seul, elle se cherche dans ce qu'il nomme un combat amoureux (''liebender Kampf''), lutte sans volonté de puissance où chacun met tout en question, soi compris, et arme l'autre au lieu de le désarmer<ref>Karl Jaspers, ''Philosophie'' (1932), t. II, chapitre sur la communication ; trad. Jeanne Hersch, ''Philosophie. Orientation dans le monde. Éclairement de l'existence. Métaphysique'', Berlin, Springer, 1986.</ref>. La formule dit bien la double face du dialogue existentiel : combat, car la complaisance y est une trahison ; amoureux, car la victoire n'y est rien si l'autre est perdu.
=== Levinas : le visage qui parle ===
Emmanuel Levinas porte le tournant dialogique à son point extrême en le déplaçant sur le terrain de l'éthique. Son grand livre, ''Totalité et infini'' (1961), s'ouvre sur un soupçon : la philosophie occidentale a presque toujours été une pensée de la totalité, qui ramène l'autre au même, l'étranger au connu, autrui à un cas de mes catégories ; et cette réduction théorique n'est pas innocente, la guerre en est la vérité pratique<ref>Emmanuel Levinas, ''Totalité et infini. Essai sur l'extériorité'' (1961), La Haye, Martinus Nijhoff ; rééd. Paris, Le Livre de Poche, 1990, préface.</ref>. Ce qui résiste à la totalité, c'est le visage d'autrui. Le visage, chez Levinas, n'est pas un ensemble de traits que je pourrais décrire, portrait ou signalement : il est ce qui, en l'autre, déborde toute image que je m'en fais, ce qui me regarde et me parle avant que je l'aie classé. « Le visage parle », dira-t-il : sa manifestation est déjà discours, premier mot avant tout mot<ref>Emmanuel Levinas, ''Éthique et infini. Dialogues avec Philippe Nemo'', Paris, Fayard, 1982, chap. « Le visage ».</ref>. Et ce que dit ce premier mot est un commandement : tu ne tueras point. L'éthique ne vient pas après la rencontre, comme une règle qu'on lui appliquerait ; elle est la rencontre même, en tant que le visage m'interdit et m'oblige.
Le langage prend alors un sens nouveau. Avant d'être transmission d'informations, parler est un événement social premier : c'est aborder autrui, répondre de soi devant lui, se tenir en sa présence sans pouvoir s'y dérober. Levinas distinguera plus tard le dit, le contenu énoncé, du dire, l'acte même de s'adresser, exposition à l'autre qui précède et excède tout contenu. Sur un point, il se sépare de Buber, qu'il a lu de près et discuté : la relation Je-Tu lui paraît trop symétrique, trop semblable à une amitié entre égaux qui se choisissent<ref>Emmanuel Levinas, « Martin Buber et la théorie de la connaissance », dans ''Noms propres'', Montpellier, Fata Morgana, 1976.</ref>. Pour Levinas, la relation à autrui est courbe et non droite : l'autre me vient de plus haut, sa demande m'oblige avant toute réciprocité, et je suis responsable de lui sans pouvoir exiger la pareille. Le dialogue, en son fond, n'est pas un contrat entre partenaires égaux : c'est une réponse à un appel qui m'a déjà atteint. On mesure la distance parcourue depuis Socrate : le dialogue n'est plus d'abord le chemin de la vérité, il est le lieu natal de la responsabilité.
=== Bakhtine : le dialogisme ===
Au même moment, en Union soviétique, Mikhaïl Bakhtine élabore de son côté une pensée du dialogue partie non de la métaphysique mais du roman. Le mot y reçoit un sens nouveau : le dialogisme n'est ni la rencontre éthique de Buber ni l'entretien socratique, mais une propriété du langage lui-même, la présence de plusieurs voix dans toute parole. Son livre sur Dostoïevski soutient que cet écrivain a inventé une forme neuve, le roman polyphonique : ses personnages ne sont pas des objets que l'auteur décrit et juge du dehors, mais des voix à part entière, des consciences qui répliquent, résistent au narrateur et gardent le dernier mot sur elles-mêmes<ref>Mikhaïl Bakhtine, ''La Poétique de Dostoïevski'' (1929, remanié en 1963), trad. Isabelle Kolitcheff, présentation de Julia Kristeva, Paris, Éditions du Seuil, 1970.</ref>. De cette poétique, Bakhtine tire une anthropologie : la conscience n'existe jamais au singulier ; être, pour l'homme, c'est communiquer dialogiquement, et le dialogue n'a pas de fin, deux voix étant le minimum de la vie<ref>Bakhtine, ''La Poétique de Dostoïevski'', chap. « Le dialogue chez Dostoïevski ».</ref>. Il tire aussi une théorie du langage : tout mot que nous prononçons est habité par les usages qui l'ont précédé et tendu vers la réponse qu'il anticipe ; même le monologue le plus fermé est saturé de répliques. Ce dialogisme généralisé, qui fait de chaque énoncé un maillon dans une chaîne de paroles, a essaimé bien au-delà de la critique littéraire, dans les sciences du langage et l'éthique de la lecture : comprendre un texte, c'est déjà lui répondre, et l'auteur écrit toujours en attente d'un répondant. On rejoint, par le roman, ce que l'herméneutique établit au même siècle par un autre chemin.
== L'herméneutique : comprendre, c'est dialoguer ==
Que faisons-nous quand nous comprenons un texte, une œuvre, une parole venue d'ailleurs ou d'autrefois ? La réponse de Hans-Georg Gadamer, dans ''Vérité et méthode'' (1960), tient en une thèse : comprendre a la structure d'un dialogue, et le dialogue platonicien en reste le modèle<ref>Hans-Georg Gadamer, ''Vérité et méthode. Les grandes lignes d'une herméneutique philosophique'' (1960), éd. intégrale, trad. Pierre Fruchon, Jean Grondin et Gilbert Merlio, Paris, Éditions du Seuil, 1996, deuxième partie.</ref>. L'herméneutique, née comme art d'interpréter les textes difficiles, devient chez lui une philosophie : une description de ce qui arrive chaque fois que du sens nous parvient.
Le cœur du dispositif est ce que Gadamer nomme, après l'historien et philosophe R. G. Collingwood, la logique de question et réponse<ref>R. G. Collingwood, ''An Autobiography'', Oxford, Oxford University Press, 1939, chap. V ; Gadamer, ''Vérité et méthode'', deuxième partie.</ref>. Un énoncé n'a de sens que comme réponse : comprendre une phrase, un livre, une œuvre, c'est retrouver la question à laquelle ils répondent, question qui n'est presque jamais formulée dans le texte et qu'il faut reconstruire. Comprendre la ''Critique de la raison pure'', ce n'est pas enregistrer ses thèses : c'est retrouver la difficulté qui la rend nécessaire, au point de pouvoir se la poser soi-même. D'où le primat herméneutique de la question : interpréter, c'est interroger, et se laisser interroger, car le texte, à son tour, met en question ce que je croyais savoir. Gadamer réhabilite au passage un mot honni : le préjugé. Nous n'abordons jamais rien l'esprit vide ; nos pré-jugements, hérités de notre langue et de notre histoire, sont la condition de toute compréhension, comme les attentes du lecteur sont la condition de la lecture. L'important n'est pas de s'en défaire, ce qui est impossible, mais de les mettre en jeu : le dialogue avec le texte est précisément l'épreuve où mes anticipations se corrigent à ce qu'il dit.
De là l'image la plus connue du livre : la fusion des horizons (''Horizontverschmelzung''). Mon horizon est tout ce que je peux voir depuis le point où je me tiens ; le texte ancien a le sien. Comprendre n'est ni annexer son horizon au mien, en le réduisant à ce que j'attends, ni abandonner le mien pour me transporter, illusoirement, dans le sien : c'est l'élargissement où les deux entrent en contact et se transforment, comme dans une conversation réussie chacun sort déplacé sans avoir été absorbé<ref>Gadamer, ''Vérité et méthode'', deuxième partie.</ref>. La compréhension n'est pas une opération qu'un sujet effectue sur un objet : c'est un événement qui advient entre deux, et dont la langue est l'élément. Gadamer peut alors risquer sa formule la plus commentée : l'être qui peut être compris est langage (« Sein, das verstanden werden kann, ist Sprache »)<ref>Gadamer, ''Vérité et méthode'', troisième partie (''Gesammelte Werke'', t. 1, Tübingen, Mohr Siebeck, p. 478).</ref>. Tout ce qui se comprend se comprend comme on comprend une parole : en lui répondant. La tradition entière change alors de visage : elle n'est plus un dépôt mort que la science examine, mais un partenaire qui nous parle et à qui nous ne cessons de répondre, même quand nous la contestons.
Paul Ricœur a prolongé et corrigé ce modèle sur un point qui importe à notre sujet. Un texte n'est pas un interlocuteur comme un autre : l'écriture l'a détaché de son auteur, de sa situation, de son premier public, et cette distance n'est pas un accident regrettable mais une chance, car c'est elle qui ouvre le texte à des lectures que l'auteur n'a pas prévues<ref>Paul Ricœur, ''Du texte à l'action. Essais d'herméneutique II'', Paris, Éditions du Seuil, 1986, notamment « La fonction herméneutique de la distanciation ».</ref>. Le dialogue avec un livre est donc un dialogue étrange, où l'un des partenaires ne peut plus préciser sa pensée, et où l'autre doit répondre pour deux : la lecture achève le discours que l'écriture avait suspendu. Ricœur a aussi servi de médiateur dans le débat qui opposa Gadamer à Habermas : à l'herméneutique qui écoute la tradition, Habermas objectait qu'une tradition peut être systématiquement faussée par la domination, et qu'il faut alors la critiquer plutôt que la comprendre ; Ricœur montra que la critique elle-même parle depuis une tradition, celle de l'émancipation, et que comprendre et critiquer sont deux moments d'un même dialogue avec le passé plutôt que deux camps<ref>Paul Ricœur, « Herméneutique et critique des idéologies » (1973), repris dans ''Du texte à l'action'', Paris, Éditions du Seuil, 1986.</ref>. La querelle, exemplaire, portait au fond sur ceci : le dialogue doit-il d'abord faire confiance à ce qui lui vient, ou d'abord s'en méfier ? La section suivante donne la parole au second parti.
== L'éthique de la discussion ==
L'idée que la discussion n'est pas seulement un moyen de connaître mais la source des normes a des ancêtres. Kant, déjà, faisait de la communication une condition de la pensée : penserions-nous beaucoup, et penserions-nous bien, demandait-il, si nous ne pensions pas pour ainsi dire en communauté avec d'autres, auxquels nous communiquons nos pensées et qui nous communiquent les leurs ? La puissance qui prive les hommes de la liberté de communiquer leur ôte du même coup la liberté de penser<ref>Emmanuel Kant, ''Qu'est-ce que s'orienter dans la pensée ?'' (1786), Ak VIII, 144, note.</ref>. Et parmi les maximes du sens commun, il plaçait la pensée élargie : penser en se mettant à la place de tout autre<ref>Emmanuel Kant, ''Critique de la faculté de juger'' (1790), § 40.</ref>. John Stuart Mill en tira au XIX{{e}} siècle la défense classique de la libre discussion : qui ne connaît que son propre côté d'une question la connaît à peine, et même une opinion vraie, soustraite à la contradiction, dégénère en dogme mort, formule répétée dont on a perdu les raisons<ref>John Stuart Mill, ''[[s:De la liberté|De la liberté]]'' (1859), chap. II.</ref>. La vérité elle-même, pour rester vivante, a besoin d'adversaires.
C'est toutefois dans la seconde moitié du XX{{e}} siècle, chez Karl-Otto Apel et Jürgen Habermas, que cette intuition devient un programme : l'éthique de la discussion (''Diskursethik''). Encore un déplacement du mot : il ne s'agit plus ici du dialogue vécu, celui de Buber ou de Levinas, ni de l'entretien herméneutique, mais des conditions normatives de l'argumentation publique, de ce que doit être une discussion pour que ses résultats obligent. La délibération, au sens de la philosophie politique, est ce type de discussion rapporté à une décision collective à prendre. Son point de départ est un déplacement du concept de raison. La raison n'est pas une faculté logée dans la tête d'un sujet solitaire : elle réside dans les pratiques d'entente entre sujets, dans ce que Habermas appelle l'agir communicationnel, par différence avec l'agir stratégique<ref>Jürgen Habermas, ''Théorie de l'agir communicationnel'' (1981), trad. Jean-Marc Ferry et Jean-Louis Schlegel, Paris, Fayard, 1987, t. I.</ref>. Dans l'agir stratégique, je traite autrui comme un élément de la situation, à influencer par la carotte, le bâton ou la ruse ; dans l'agir communicationnel, je cherche son assentiment par des raisons qu'il peut examiner. Or quiconque parle sérieusement élève, qu'il le veuille ou non, des prétentions à la validité : il prétend que ce qu'il dit est compréhensible, vrai, normativement juste et sincère, et il s'engage, si on le lui demande, à en répondre par des arguments. La parole la plus ordinaire contient ainsi la promesse d'une discussion possible ; l'argumentation n'est pas un ornement de la vie sociale, elle en est la police d'assurance.
De cette analyse, l'éthique de la discussion tire sa norme. Dans une discussion digne de ce nom, aucune force ne doit l'emporter que la force sans contrainte du meilleur argument (« der zwanglose Zwang des besseren Arguments »)<ref>Habermas, ''Théorie de l'agir communicationnel'', t. I, chap. I.</ref> : ni le rang, ni le nombre, ni la menace, ni la séduction. Habermas a d'abord décrit cette exigence comme une situation idéale de parole, où chacun aurait des chances égales de parler, de questionner et de contester, sans contrainte externe ni interne ; il a précisé ensuite qu'il s'agit non d'un état à réaliser mais d'une présupposition inévitable : quiconque argumente fait comme si ces conditions étaient remplies, et c'est ce « comme si », opérant dans chaque discussion réelle, qui permet de la critiquer. Le principe moral prend alors une forme dialogique : seules peuvent prétendre à la validité les normes qui pourraient recueillir l'assentiment de tous les concernés en tant que participants à une discussion pratique<ref>Jürgen Habermas, ''Morale et communication'' (1983), trad. Christian Bouchindhomme, Paris, Éditions du Cerf, 1986, chap. « Notes programmatiques pour fonder en raison une éthique de la discussion ».</ref>. La différence avec Kant est exactement là : le test kantien de l'universalisation, chacun peut le faire seul, dans le silence de sa conscience ; le test habermassien exige la discussion réelle, car nul ne peut anticiper seul ce que les autres, de leur point de vue, pourraient accepter. Le monologue moral, si bien intentionné soit-il, usurpe la place des intéressés.
Apel donne à l'édifice son verrou logique : la contradiction performative. Le sceptique qui entreprend de démontrer par arguments que l'argumentation ne vaut rien se réfute en acte, car son geste présuppose ce que sa thèse nie ; quiconque argumente a toujours déjà reconnu une communauté de communication et ses règles, dont on ne peut sortir qu'en se taisant<ref>Karl-Otto Apel, ''Éthique de la discussion'', trad. Mark Hunyadi, Paris, Éditions du Cerf, 1994.</ref>. On peut refuser de discuter ; on ne peut pas discuter contre la discussion. Les retombées pratiques de ce programme sont partout visibles : la théorie de la [[Dictionnaire de philosophie/Démocratie|démocratie]] délibérative, qui fait dépendre la légitimité des lois de la qualité de la délibération publique qui les précède ; les comités d'éthique et les conférences de citoyens, qui institutionnalisent la discussion sur les questions que nul expert ne peut trancher seul, de la [[Dictionnaire de philosophie/Bioéthique|bioéthique]] au climat. Que ces institutions restent en deçà de leur idée, leurs promoteurs le savent ; l'idée sert justement à mesurer l'écart.
== Les limites du dialogue ==
L'éloge du dialogue a ses contrepoisons, et il serait contraire à son esprit de ne pas les entendre. Le plus ancien est l'ironie des moralistes : Schopenhauer, dans un opuscule posthume que la tradition intitule ''L'Art d'avoir toujours raison'', recense trente-huit stratagèmes pour l'emporter dans la dispute, de la généralisation abusive à l'attaque personnelle en passant par la diversion et l'appel à l'auditoire<ref>Arthur Schopenhauer, ''La Dialectique éristique'' (''Eristische Dialektik'', écrit vers 1830, publié après sa mort), connu en français sous le titre ''L'Art d'avoir toujours raison''.</ref>. Le propos est à double fond : sous la satire, un constat désabusé, la discussion réelle est un combat de vanités où la vérité pèse peu, et un remède, car nommer les stratagèmes, c'est apprendre à les reconnaître, chez l'autre et chez soi. Le petit livre de Schopenhauer inocule ainsi au lecteur, à dose maîtrisée, le mal dont il traite : qui a étudié les stratagèmes se laisse moins prendre, et se surprend moins souvent à en user.
Les critiques du XX{{e}} siècle vont plus loin : elles ne visent pas les tricheurs, mais le jeu. Jean-François Lyotard, dans ''Le Différend'' (1983), conteste l'idée qu'un langage commun soit toujours disponible pour régler les conflits. Il distingue le litige, différend réglable parce que les deux parties partagent un idiome et un tribunal, du différend au sens strict : le cas où le tort subi par l'une des parties ne peut pas se formuler dans la langue où l'on juge, de sorte que le plaignant, sommé de prouver dans un idiome qui l'exclut, est victime une seconde fois<ref>Jean-François Lyotard, ''Le Différend'', Paris, Éditions de Minuit, 1983.</ref>. L'exigence de consensus, si elle presse de conclure, peut alors faire violence : elle demande à l'inaudible de se taire faute de s'être fait entendre. Jacques Rancière déplace le soupçon vers la politique : le désaccord qui compte, la mésentente, ne porte pas sur les arguments échangés mais sur la scène de l'échange elle-même, sur qui est compté comme interlocuteur et sur ce que parler veut dire ; la politique commence quand ceux dont la voix n'était perçue que comme du bruit se font reconnaître comme des êtres parlants<ref>Jacques Rancière, ''La Mésentente. Politique et philosophie'', Paris, Galilée, 1995.</ref>. Avant de discuter, il faut être admis à la table, et l'admission ne se discute pas à la table : elle se conquiert.
La philosophie contemporaine a donné un nom aux inégalités qui faussent l'échange : l'injustice épistémique. Miranda Fricker en distingue deux formes. L'injustice testimoniale ampute la crédibilité d'un locuteur en raison d'un préjugé sur son identité : la même phrase, dans la même réunion, pèse moins dans une bouche que dans une autre. L'injustice herméneutique, plus insidieuse, prive un groupe des concepts nécessaires pour formuler son expérience : avant que l'expression « harcèlement sexuel » n'existe, ce que subissaient les femmes concernées restait, pour la discussion publique, littéralement indicible<ref>Miranda Fricker, ''Epistemic Injustice. Power and the Ethics of Knowing'', Oxford, Oxford University Press, 2007, chap. 1 et 7.</ref>. Trois critiques se dessinent ainsi, qui ne visent pas le même point. Lyotard vise la langue : il n'existe pas toujours d'idiome commun où le tort puisse se dire. Rancière vise la scène : avant tout échange, il a fallu décider qui compte comme interlocuteur, et cette décision-là n'a pas été discutée. Fricker vise les partenaires : ils n'entrent pas dans l'échange avec la même crédibilité ni les mêmes ressources pour interpréter ce qu'ils vivent. Aucune des trois ne réfute l'éthique de la discussion : toutes en durcissent les conditions. Si les chances de parole et de crédibilité sont inégalement distribuées, l'appel au dialogue peut servir de masque : « discutons » est parfois le dernier mot de la force, celui qui somme le faible de jouer à un jeu dont les règles le condamnent. Michel Foucault, dans ses derniers cours, a opposé à l'image irénique de l'échange une autre figure grecque, la ''parrhêsia'' (παρρησία), le dire-vrai courageux : parler franchement à plus puissant que soi, en risquant la relation et parfois la vie<ref>Michel Foucault, ''Le Gouvernement de soi et des autres. Cours au Collège de France, 1982-1983'', Paris, Gallimard-Seuil, 2008 ; ''Le Courage de la vérité. Cours au Collège de France, 1984'', Paris, Gallimard-Seuil, 2009.</ref>. Le rappel est salutaire : un dialogue où nul ne risque rien, où la franchise ne coûte rien à personne, a toutes chances de n'être qu'une cérémonie.
Une dernière limite est plus discrète : le malentendu. Deux interlocuteurs peuvent croire parler de la même chose et poursuivre deux objets différents ; le dialogue de sourds n'est pas toujours bruyant, il est parfois courtois et long. La philosophie du langage a pourtant montré que le malentendu même a des bornes : pour comprendre quelqu'un, fût-ce de travers, je dois déjà lui prêter une large rationalité et beaucoup de croyances vraies, faute de quoi ses paroles ne seraient pas même interprétables ; c'est le principe de charité, au sens que Donald Davidson a donné à l'expression<ref>Donald Davidson, ''Enquêtes sur la vérité et l'interprétation'' (1984), trad. Pascal Engel, Nîmes, Éditions Jacqueline Chambon, 1993.</ref>. Le désaccord le plus vif suppose un immense accord de fond, ne serait-ce que sur le sens des mots avec lesquels on se dispute. C'est une consolation logique : si nous pouvons nous quereller, c'est que nous nous comprenons déjà beaucoup.
== Le dialogue à l'épreuve du présent ==
Trois chantiers contemporains mettent la notion au travail. Le premier est le dialogue entre les cultures. La mondialisation l'a rendu inévitable ; elle n'a pas dit comment le mener. Deux facilités se présentent, que François Jullien invite à refuser ensemble : l'universalisme de surplomb, qui croit disposer d'avance de la langue commune où toutes les cultures viendraient se dire, et le relativisme des identités, qui enferme chacune dans sa différence et rend l'échange sans objet. Jullien propose de penser par écarts plutôt que par différences : l'écart n'assigne pas d'identités, il ouvre un entre-deux où chaque pensée, dévisagée par l'autre, découvre ses propres partis pris impensés ; les cultures n'y sont pas des essences à comparer mais des ressources à exploiter en commun<ref>François Jullien, ''L'Écart et l'entre. Leçon inaugurale de la Chaire sur l'altérité'', Paris, Galilée, 2012 ; ''Il n'y a pas d'identité culturelle'', Paris, L'Herne, 2016.</ref>. Le dialogue interculturel réussi ne produit pas un consensus tiède : il rend chacun étranger à ses propres évidences, et c'est son gain.
Le deuxième chantier est pédagogique et civique. La philosophie pour enfants, initiée par Matthew Lipman, transforme la classe en communauté de recherche : une question née d'un récit, des règles explicites d'écoute et de reprise, un maître qui anime sans conclure ; l'hypothèse est socratique, on apprend à penser en pensant ensemble, et l'expérience montre que l'exigence n'a pas d'âge<ref>Matthew Lipman, ''À l'école de la pensée'' (''Thinking in Education'', 1991), trad. Nicole Decostre, Bruxelles, De Boeck, 1995.</ref>. Les cafés philosophiques, les débats à visée philosophique, les conventions citoyennes tirées au sort sur le climat ou la fin de vie relèvent de la même conviction : la délibération est une compétence qui s'exerce, et une société qui ne la pratique plus la perd. L'éthique clinique en offre l'exemple le plus grave : au chevet des malades, quand les principes se contredisent et que la décision n'attend pas, les équipes recourent à la délibération collégiale, non parce qu'elle garantit la bonne réponse, mais parce qu'elle est la moins mauvaise procédure que nous connaissions pour décider dans l'incertain sans confisquer la décision.
Le troisième chantier était impensable il y a un siècle : nous parlons désormais avec des machines. Alan Turing, en 1950, proposait déjà de remplacer la question « les machines peuvent-elles penser ? » par un test de conversation : si, dialoguant à l'aveugle, un juge ne distingue pas la machine de l'homme, sur quoi fonder le refus de lui attribuer l'intelligence<ref>Alan Turing, « Computing Machinery and Intelligence », ''Mind'', vol. 59, n° 236, 1950, p. 433-460.</ref> ? Seize ans plus tard, le programme ELIZA de Joseph Weizenbaum, simple jeu de reformulations imitant un psychothérapeute, vit des usagers avertis se confier à lui comme à une personne, au point d'inquiéter son créateur, qui consacra un livre à mettre en garde contre cette pente<ref>Joseph Weizenbaum, « ELIZA », ''Communications of the ACM'', vol. 9, n° 1, 1966, p. 36-45 ; ''Computer Power and Human Reason'', San Francisco, W. H. Freeman, 1976.</ref>. L'épisode, démultiplié aujourd'hui par les agents conversationnels, pose à la notion une question de fond que cet article donne les moyens d'instruire. Une machine qui répond satisfait-elle aux conditions dégagées plus haut ? Elle soutient l'échange réglé, et souvent mieux que nous ; mais le risque d'être changé, la responsabilité de ce qui est dit, le visage au sens de Levinas, l'entre-deux au sens de Buber font question. Décider si ces conditions sont remplies, imitables ou hors d'atteinte, c'est décider ce que nous mettons dans le mot dialogue ; et il n'est pas indifférent que cette décision, comme toutes celles qui comptent, ne puisse se prendre qu'en discutant.
Au terme du parcours, la leçon socratique reste entière. Le dialogue n'est pas la politesse de la pensée, un supplément d'âme qu'on ajouterait au savoir : il en est le régime natif, celui où les raisons s'éprouvent, où l'ignorance s'avoue, où l'autre compte. Il a ses conditions, exigeantes, ses contrefaçons, nombreuses, et ses limites, réelles ; les connaître fait partie de l'art. Le contraire du dialogue n'est pas le silence, qui en est parfois un moment : c'est le discours qui n'attend plus de réponse.
== Notes et références ==
{{références|colonnes=2}}
== Bibliographie ==
=== Textes classiques ===
* Platon, ''Œuvres complètes'', sous la direction de Luc Brisson, Paris, Flammarion, 2008.
* Aristote, ''Topiques'', texte établi et traduit par Jacques Brunschwig, Paris, Les Belles Lettres, t. I, 1967 ; t. II, 2007.
* Pierre Abélard, ''Conférences. Dialogue d'un philosophe avec un juif et un chrétien'', traduction de Maurice de Gandillac, Paris, Éditions du Cerf, 1993.
* Michel de Montaigne, « De l'art de conférer », ''Essais'', III, 8, édition de Pierre Villey, Paris, Presses Universitaires de France, coll. « Quadrige », 2004.
* Galilée, ''Dialogue sur les deux grands systèmes du monde'', traduction de René Fréreux avec le concours de François de Gandt, Paris, Éditions du Seuil, 1992.
* David Hume, ''Dialogues sur la religion naturelle'', traduction de Michel Malherbe, Paris, Vrin, 1987.
* Denis Diderot, ''Le Neveu de Rameau'', édition de Michel Delon, Paris, Gallimard, coll. « Folio classique », 2006.
* Emmanuel Kant, ''Qu'est-ce que s'orienter dans la pensée ?'' (1786), traduction et introduction d'Alexis Philonenko, Paris, Vrin, 1959.
* John Stuart Mill, ''De la liberté'' (1859), traduction de Laurence Lenglet à partir de la traduction de Dupond-White, Paris, Gallimard, coll. « Folio essais », 1990.
=== Philosophies du dialogue, herméneutique, éthique de la discussion ===
* Karl-Otto Apel, ''Éthique de la discussion'', traduction de Mark Hunyadi, Paris, Éditions du Cerf, 1994.
* Mikhaïl Bakhtine, ''La Poétique de Dostoïevski'', traduction d'Isabelle Kolitcheff, présentation de Julia Kristeva, Paris, Éditions du Seuil, 1970.
* Martin Buber, ''Je et Tu'', traduction de Geneviève Bianquis, Paris, Aubier, 1969.
* Martin Buber, ''La Vie en dialogue'', Paris, Aubier, 1959.
* Michel Foucault, ''Le Courage de la vérité. Cours au Collège de France, 1984'', édition de Frédéric Gros, Paris, Gallimard-Seuil, 2009.
* Hans-Georg Gadamer, ''Vérité et méthode. Les grandes lignes d'une herméneutique philosophique'', édition intégrale, traduction de Pierre Fruchon, Jean Grondin et Gilbert Merlio, Paris, Éditions du Seuil, 1996.
* Jürgen Habermas, ''Théorie de l'agir communicationnel'', traduction de Jean-Marc Ferry et Jean-Louis Schlegel, Paris, Fayard, 1987, 2 vol.
* Jürgen Habermas, ''Morale et communication'', traduction de Christian Bouchindhomme, Paris, Éditions du Cerf, 1986.
* François Jullien, ''L'Écart et l'entre. Leçon inaugurale de la Chaire sur l'altérité'', Paris, Galilée, 2012.
* Emmanuel Levinas, ''Totalité et infini. Essai sur l'extériorité'' (1961), La Haye, Martinus Nijhoff ; rééd. Paris, Le Livre de Poche, 1990.
* Emmanuel Levinas, ''Éthique et infini. Dialogues avec Philippe Nemo'', Paris, Fayard, 1982.
* Emmanuel Levinas, ''Noms propres'', Montpellier, Fata Morgana, 1976.
* Jean-François Lyotard, ''Le Différend'', Paris, Éditions de Minuit, 1983.
* Jacques Rancière, ''La Mésentente. Politique et philosophie'', Paris, Galilée, 1995.
* Paul Ricœur, ''Du texte à l'action. Essais d'herméneutique II'', Paris, Éditions du Seuil, 1986.
* Franz Rosenzweig, ''L'Étoile de la rédemption'', traduction d'Alexandre Derczanski et Jean-Louis Schlegel, Paris, Éditions du Seuil, 1982.
=== Études ===
* Barbara Cassin (dir.), ''Vocabulaire européen des philosophies. Dictionnaire des intraduisibles'', Paris, Éditions du Seuil / Le Robert, 2004.
* Monique Dixsaut, ''Le Naturel philosophe. Essai sur les dialogues de Platon'', Paris, Vrin, 1985.
* Michael Frede, « Plato's Arguments and the Dialogue Form », dans James C. Klagge et Nicholas D. Smith (dir.), ''Methods of Interpreting Plato and His Dialogues'', ''Oxford Studies in Ancient Philosophy'', volume supplémentaire, Oxford, Clarendon Press, 1992, p. 201-219.
* Miranda Fricker, ''Epistemic Injustice. Power and the Ethics of Knowing'', Oxford, Oxford University Press, 2007.
* Hans-Georg Gadamer, ''Dialogue and Dialectic. Eight Hermeneutical Studies on Plato'', traduction de P. Christopher Smith, New Haven, Yale University Press, 1980.
* Vittorio Hösle, ''The Philosophical Dialogue. A Poetics and a Hermeneutics'', Notre Dame, University of Notre Dame Press, 2012.
* Francis Jacques, ''Dialogiques. Recherches logiques sur le dialogue'', Paris, Presses Universitaires de France, 1979.
* Charles H. Kahn, ''Plato and the Socratic Dialogue. The Philosophical Use of a Literary Form'', Cambridge, Cambridge University Press, 1996.
* Matthew Lipman, ''À l'école de la pensée'', traduction de Nicole Decostre, Bruxelles, De Boeck, 1995.
* Dmitri Nikulin, ''Dialectic and Dialogue'', Stanford, Stanford University Press, 2010.
{{AutoCat}}
dt66q3mpmdm193ibd0ztkgqava55ff9
Grec ancien/Dieux/Éosphoros
0
84034
769317
2026-07-03T07:29:12Z
~2026-34862-02
124042
Page créée avec « {{Grec ancien}} {{Dieu grec |nom=Éosphoros |img=Evelyn de Morgan - Phosphorus and Hesperus, (1881).jpg |comim=Éosphoros (torche levée) et Hespéros (torche baissée) par Evelyn De Morgan. |ngr=Ἑωσφόρος |par=Céphale et Éos |ddd=Dieu de |dd=l'aurore |rom=Lucifer |fs=Hespéros |enf=Céyx, Leuconoé, Dédalion, Aradia }} '''Éosphoros''' représente la planète Vénus lors de son lever. == Mythe == »
769317
wikitext
text/x-wiki
{{Grec ancien}}
{{Dieu grec
|nom=Éosphoros
|img=Evelyn de Morgan - Phosphorus and Hesperus, (1881).jpg
|comim=Éosphoros (torche levée) et Hespéros (torche baissée) par Evelyn De Morgan.
|ngr=Ἑωσφόρος
|par=Céphale et Éos
|ddd=Dieu de
|dd=l'aurore
|rom=Lucifer
|fs=Hespéros
|enf=Céyx, Leuconoé, Dédalion, Aradia
}}
'''Éosphoros''' représente la planète Vénus lors de son lever.
== Mythe ==
nyt75o9089t0jmz25sustt3pkfhurn1
Grec ancien/Dieux/Hespéros
0
84035
769318
2026-07-03T07:36:09Z
~2026-34862-02
124042
Page créée avec « {{Grec ancien}} {{Dieu grec |nom=Hespéros |img=Evelyn de Morgan - Phosphorus and Hesperus, (1881).jpg |comim=Éosphoros (torche levée) et Hespéros (torche baissée) par Evelyn De Morgan. |ngr=Ἕσπερος |par=Céphale et Éos |ddd=Dieu du |dd=crépuscule |rom=Vesper |fs=Éosphoros |enf=Céyx, Leuconoé, Dédalion, Aradia }} '''Hespéros''' représente la planète Vénus lors de son coucher. == Mythe == »
769318
wikitext
text/x-wiki
{{Grec ancien}}
{{Dieu grec
|nom=Hespéros
|img=Evelyn de Morgan - Phosphorus and Hesperus, (1881).jpg
|comim=Éosphoros (torche levée) et Hespéros (torche baissée) par Evelyn De Morgan.
|ngr=Ἕσπερος
|par=Céphale et Éos
|ddd=Dieu du
|dd=crépuscule
|rom=Vesper
|fs=Éosphoros
|enf=Céyx, Leuconoé, Dédalion, Aradia
}}
'''Hespéros''' représente la planète Vénus lors de son coucher.
== Mythe ==
nf45l66ub4266jve8g9hx83fjh90vpx