Wikilivres
frwikibooks
https://fr.wikibooks.org/wiki/Accueil
MediaWiki 1.47.0-wmf.6
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
Modèle:Bienvenue nouveau
10
28360
767813
767720
2026-06-16T08:29:28Z
Fourmidable
92370
767813
wikitext
text/x-wiki
<div class="plainlinks" style="float: right; padding:0em; margin:0 0 1em 1em;background-color:#FFF;">
<p class="bloc" style="background-color:#438EDF;">Trouver un guide ou un manuel</p>
<inputbox>
type=search
width=30
namespaces=Principal
searchbuttonlabel=Chercher
break=no
</inputbox>
<p class="bloc" style=" margin-top: 1.2em; background-color:#E47B10;">Trouver de l'aide pour contribuer</p>
* [[Wikilivres:Bienvenue|Qu'est-ce que Wikilivres ?]]
* [[Wikilivres|Que faire sur Wikilivres ?]]
* [[Wikilivres:Présentation|Ce que Wikilivres n'est pas]]
* [[Aide:Accueil|Accueil de l'aide]]
* [[Aide:Comment modifier une page|Comment modifier une page]]
* [[Aide:Jargon|Le jargon des wikis]]
<p class="bloc" style=" margin-top: 1.2em; background-color:#4DB93A;">Discuter entre contributeurs</p>
* [[Aide:Poser une question|Poser une question]]
* [[Wikilivres:Le Bistro/{{CURRENTYEAR}}|Lancer une discussion]]
</div>
<h2>Bienvenue sur Wikilivres, {{BASEPAGENAME}} !</h2>
Bonjour, {{#if:{{{1|}}}|je suis [[Utilisateur:{{{1|}}}{{!}}{{{1|}}}]], et|}} je vous accueille en tant que wikilibraire bénévole.
Wikilivres repose sur des principes fondateurs respectés par tous :
# '''guides, manuels et tutoriels''' uniquement ([[v:|Wikiversité]] accueille tous types de ressources pédagogiques interactives avec des exercices et des quiz interactifs intégrés, et [[voy:|Wikivoyage]] les guides touristiques et les fiches de vocabulaire pour le tourisme) ;
# '''licence libre''', respect du droit d'auteur ;
# '''utilisation raisonnée et contrôlée de l'IA''' ;
# '''savoir-vivre''' dans les échanges (politesse et recherche de consensus).
Vous pouvez découvrir tout cela plus en détail en consultant les liens ci-contre →
{{clr|left}}
Je vous souhaite de prendre plaisir à contribuer sur Wikilivres.
À bientôt !
{{{sign|}}}
{{Grossir|P.S. : Vos nouveaux messages normalement signés par leurs expéditeurs seront affichés en bas de cette page. Pour répondre, vous pouvez soit le faire directement sur votre propre page de discussion en cliquant sur le mot bleu « Répondre » affiché à la suite du message, soit le faire sur la page de discussion de votre interlocuteur, qui est accessible via un hyperlien présent dans sa signature.|0.85}}
{{clr}}
<noinclude>
[[Catégorie:Modèles pour l'espace "Discussion"|{{PAGENAME}}]]
</noinclude>
c7te8e18a5oj14z8z6lkqpbhx1b7i44
767814
767813
2026-06-16T08:31:01Z
Fourmidable
92370
767814
wikitext
text/x-wiki
<div class="plainlinks" style="float: right; padding:0em; margin:0 0 1em 1em;background-color:#FFF;">
<p class="bloc" style="background-color:#438EDF;">Trouver un guide ou un manuel</p>
<inputbox>
type=search
width=30
namespaces=Principal
searchbuttonlabel=Chercher
break=no
</inputbox>
<p class="bloc" style=" margin-top: 1.2em; background-color:#E47B10;">Trouver de l'aide pour contribuer</p>
* [[Wikilivres:Bienvenue|Qu'est-ce que Wikilivres ?]]
* [[Wikilivres|Que faire sur Wikilivres ?]]
* [[Wikilivres:Présentation|Ce que Wikilivres n'est pas]]
* [[Aide:Accueil|Accueil de l'aide]]
* [[Aide:Comment modifier une page|Comment modifier une page]]
* [[Aide:Jargon|Le jargon des wikis]]
<p class="bloc" style=" margin-top: 1.2em; background-color:#4DB93A;">Discuter entre contributeurs</p>
* [[Aide:Poser une question|Poser une question]]
* [[Wikilivres:Le Bistro/{{CURRENTYEAR}}|Lancer une discussion]]
</div>
<h2>Bienvenue sur Wikilivres, {{BASEPAGENAME}} !</h2>
Bonjour, {{#if:{{{1|}}}|je suis [[Utilisateur:{{{1|}}}{{!}}{{{1|}}}]], et|}} je vous accueille en tant que wikilibraire bénévole.
Wikilivres repose sur des principes fondateurs respectés par tous :
# '''guides, manuels et tutoriels''' uniquement<ref group="note">[[v:|Wikiversité]] accueille tous types de ressources pédagogiques interactives avec des exercices et des quiz interactifs intégrés, ainsi que des travaux de recherche scientifique, et [[voy:|Wikivoyage]] les guides touristiques et les fiches de vocabulaire pour le tourisme</ref> ;
# '''licence libre''', respect du droit d'auteur ;
# '''utilisation raisonnée et contrôlée de l'IA''' ;
# '''savoir-vivre''' dans les échanges (politesse et recherche de consensus).
Vous pouvez découvrir tout cela plus en détail en consultant les liens ci-contre →
{{clr|left}}
Je vous souhaite de prendre plaisir à contribuer sur Wikilivres.
À bientôt !
{{{sign|}}}
{{Grossir|P.S. : Vos nouveaux messages normalement signés par leurs expéditeurs seront affichés en bas de cette page. Pour répondre, vous pouvez soit le faire directement sur votre propre page de discussion en cliquant sur le mot bleu « Répondre » affiché à la suite du message, soit le faire sur la page de discussion de votre interlocuteur, qui est accessible via un hyperlien présent dans sa signature.|0.85}}
{{clr}}
<references group="note"/>
<noinclude>
[[Catégorie:Modèles pour l'espace "Discussion"|{{PAGENAME}}]]
</noinclude>
tqhvjjp7aqesau1x4917uxoiek6712q
767815
767814
2026-06-16T08:31:45Z
Fourmidable
92370
767815
wikitext
text/x-wiki
<div class="plainlinks" style="float: right; padding:0em; margin:0 0 1em 1em;background-color:#FFF;">
<p class="bloc" style="background-color:#438EDF;">Trouver un guide ou un manuel</p>
<inputbox>
type=search
width=30
namespaces=Principal
searchbuttonlabel=Chercher
break=no
</inputbox>
<p class="bloc" style=" margin-top: 1.2em; background-color:#E47B10;">Trouver de l'aide pour contribuer</p>
* [[Wikilivres:Bienvenue|Qu'est-ce que Wikilivres ?]]
* [[Wikilivres|Que faire sur Wikilivres ?]]
* [[Wikilivres:Présentation|Ce que Wikilivres n'est pas]]
* [[Aide:Accueil|Accueil de l'aide]]
* [[Aide:Comment modifier une page|Comment modifier une page]]
* [[Aide:Jargon|Le jargon des wikis]]
<p class="bloc" style=" margin-top: 1.2em; background-color:#4DB93A;">Discuter entre contributeurs</p>
* [[Aide:Poser une question|Poser une question]]
* [[Wikilivres:Le Bistro/{{CURRENTYEAR}}|Lancer une discussion]]
</div>
<h2>Bienvenue sur Wikilivres, {{BASEPAGENAME}} !</h2>
Bonjour, {{#if:{{{1|}}}|je suis [[Utilisateur:{{{1|}}}{{!}}{{{1|}}}]], et|}} je vous accueille en tant que wikilibraire bénévole.
Wikilivres repose sur des principes fondateurs respectés par tous :
# '''guides, manuels et tutoriels''' uniquement<ref group="note">[[v:|Wikiversité]] accueille tous types de ressources pédagogiques interactives avec des exercices et des quiz intégrés, ainsi que des travaux de recherche scientifique, et [[voy:|Wikivoyage]] les guides touristiques et les fiches de vocabulaire pour le tourisme</ref> ;
# '''licence libre''', respect du droit d'auteur ;
# '''utilisation raisonnée et contrôlée de l'IA''' ;
# '''savoir-vivre''' dans les échanges (politesse et recherche de consensus).
Vous pouvez découvrir tout cela plus en détail en consultant les liens ci-contre →
{{clr|left}}
Je vous souhaite de prendre plaisir à contribuer sur Wikilivres.
À bientôt !
{{{sign|}}}
{{Grossir|P.S. : Vos nouveaux messages normalement signés par leurs expéditeurs seront affichés en bas de cette page. Pour répondre, vous pouvez soit le faire directement sur votre propre page de discussion en cliquant sur le mot bleu « Répondre » affiché à la suite du message, soit le faire sur la page de discussion de votre interlocuteur, qui est accessible via un hyperlien présent dans sa signature.|0.85}}
{{clr}}
<references group="note"/>
<noinclude>
[[Catégorie:Modèles pour l'espace "Discussion"|{{PAGENAME}}]]
</noinclude>
f5cqstag9rn4hk8xhupurobpo189ox2
Dictionnaire de philosophie/A
0
30496
767805
767701
2026-06-16T04:11:54Z
PandaMystique
119061
767805
wikitext
text/x-wiki
{{DicoPhilo |A}}
<!-- Grille de contenu -->
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2em; width: 100%; margin-bottom: 2em;">
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
:[[Dictionnaire de philosophie/A (logique)|A]]
:[[Dictionnaire de philosophie/Abduction|Abduction]] ᕻ
:[[Dictionnaire de philosophie/Aboulie|Aboulie]]
:[[Dictionnaire de philosophie/Absolu|Absolu]]
:[[Dictionnaire de philosophie/Absolutisme|Absolutisme]] ᕻ
:[[Dictionnaire de philosophie/Abstraction|Abstraction]] ᕻ
:[[Dictionnaire de philosophie/Absurde|Absurde]] ᕻ
:Académie
:[[Dictionnaire de philosophie/Acatalépsie|Acatalépsie]] ᕻ
:[[Dictionnaire de philosophie/Accident|Accident]]
:[[Manuel de terminale de philosophie/Acte/Puissance|Acte et Puissance]] <small>(M)</small>
:[[Dictionnaire de philosophie/Action|Action]]
:[[Dictionnaire de philosophie/Affection|Affection]]
:''Afrique''
::[[Dictionnaire de philosophie/Philosophie africaine|Philosophie africaine]]
:[[Dictionnaire de philosophie/Agnosticisme|Agnosticisme]]
:{{Page|Aliénation}}
:[[Dictionnaire de philosophie/Altérité|Altérité]]
:[[Dictionnaire de philosophie/Altruisme|Altruisme]]
:[[Dictionnaire de philosophie/Âme|Âme]]
:[[Dictionnaire de philosophie/Amitié|Amitié]]
</div>
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
:[[Dictionnaire de philosophie/Amour|Amour]]
:Analogie
:Analyse
:Analytique
:[[Dictionnaire de philosophie/Anarchisme|Anarchisme]]
:{{Page|Anaxagore}}
:[[Dictionnaire de philosophie/Angoisse|Angoisse]] ᕻ
:[[Dictionnaire de philosophie/Animal|Animal]]
::Communication animale
::Droits
::[[Dictionnaire de philosophie/Intelligence animale|Intelligence animale]] ᕻ
:[[Dictionnaire de philosophie/Anthropocentrisme|Anthropocentrisme]]
:[[Dictionnaire de philosophie/Antinomie|Antinomie]]
:[[Dictionnaire de philosophie/Aporie|Aporie]]
:[[Dictionnaire de philosophie/Apparence|Apparence]]
:[[Dictionnaire de philosophie/A priori|A priori]]
:[[Dictionnaire de philosophie/Argument|Argument]]
::[[Philosophie de l'esprit/Argument de la connaissance|— de la connaissance]]
:[[Dictionnaire de philosophie/Argentine (Philosophie)|Argentine]] (philosophie au XX{{e}} siècle)
</div>
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
:[[Dictionnaire de philosophie/Aristote|Aristote]]
::Aristotélisme
:[[Dictionnaire de philosophie/Art (introduction)|Art]] (introduction)
::[[Dictionnaire de philosophie/Art|Art]] (contemporain)
::[[Dictionnaire de philosophie/Art et Vérité|Art et Vérité]]
:[[Dictionnaire de philosophie/Ataraxie|Ataraxie]]
:[[Dictionnaire de philosophie/Athéisme|Athéisme]]
:Atome
::[[Dictionnaire de philosophie/Atomisme|Atomisme]]
:{{Page|Attribut}}
:[[Dictionnaire de philosophie/Authenticité|Authenticité]]
:[[Dictionnaire de philosophie/Autonomie|Autonomie]]
:[[Dictionnaire de philosophie/Autorité|Autorité]]
:[[Philosophie/Autrui|Autrui]] <small>(M)</small>
:[[Dictionnaire de philosophie/Avortement|Avortement]] (éthique) ᕻ
:[[Dictionnaire de philosophie/Axiome|Axiome]]
</div>
</div>
{{PhiloRecherche}}
{{Autocat}}
o0e2vdp2drbn8am0ljxbvxrwyv8pd0e
767810
767805
2026-06-16T04:40:20Z
PandaMystique
119061
767810
wikitext
text/x-wiki
{{DicoPhilo |A}}
<!-- Grille de contenu -->
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 2em; width: 100%; margin-bottom: 2em;">
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
:[[Dictionnaire de philosophie/A (logique)|A]]
:[[Dictionnaire de philosophie/Abduction|Abduction]] ᕻ
:[[Dictionnaire de philosophie/Aboulie|Aboulie]]
:[[Dictionnaire de philosophie/Absolu|Absolu]]
:[[Dictionnaire de philosophie/Absolutisme|Absolutisme]] ᕻ
:[[Dictionnaire de philosophie/Abstraction|Abstraction]] ᕻ
:[[Dictionnaire de philosophie/Absurde|Absurde]] ᕻ
:Académie
:[[Dictionnaire de philosophie/Acatalépsie|Acatalépsie]] ᕻ
:[[Dictionnaire de philosophie/Accident|Accident]]
:[[Manuel de terminale de philosophie/Acte/Puissance|Acte et Puissance]] <small>(M)</small>
:[[Dictionnaire de philosophie/Action|Action]]
:[[Dictionnaire de philosophie/Affection|Affection]]
:''Afrique''
::[[Dictionnaire de philosophie/Philosophie africaine|Philosophie africaine]]
:[[Dictionnaire de philosophie/Agnosticisme|Agnosticisme]]
:{{Page|Aliénation}}
:[[Dictionnaire de philosophie/Altérité|Altérité]]
:[[Dictionnaire de philosophie/Altruisme|Altruisme]]
:[[Dictionnaire de philosophie/Âme|Âme]]
:[[Dictionnaire de philosophie/Amitié|Amitié]]
</div>
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
:[[Dictionnaire de philosophie/Amour|Amour]]
:Analogie
:Analyse
:Analytique
:[[Dictionnaire de philosophie/Anarchisme|Anarchisme]] ᕻ
:{{Page|Anaxagore}}
:[[Dictionnaire de philosophie/Angoisse|Angoisse]] ᕻ
:[[Dictionnaire de philosophie/Animal|Animal]]
::Communication animale
::Droits
::[[Dictionnaire de philosophie/Intelligence animale|Intelligence animale]] ᕻ
:[[Dictionnaire de philosophie/Anthropocentrisme|Anthropocentrisme]]
:[[Dictionnaire de philosophie/Antinomie|Antinomie]]
:[[Dictionnaire de philosophie/Aporie|Aporie]]
:[[Dictionnaire de philosophie/Apparence|Apparence]]
:[[Dictionnaire de philosophie/A priori|A priori]]
:[[Dictionnaire de philosophie/Argument|Argument]]
::[[Philosophie de l'esprit/Argument de la connaissance|— de la connaissance]]
:[[Dictionnaire de philosophie/Argentine (Philosophie)|Argentine]] (philosophie au XX{{e}} siècle)
</div>
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
:[[Dictionnaire de philosophie/Aristote|Aristote]]
::Aristotélisme
:[[Dictionnaire de philosophie/Art (introduction)|Art]] (introduction)
::[[Dictionnaire de philosophie/Art|Art]] (contemporain)
::[[Dictionnaire de philosophie/Art et Vérité|Art et Vérité]]
:[[Dictionnaire de philosophie/Ataraxie|Ataraxie]]
:[[Dictionnaire de philosophie/Athéisme|Athéisme]]
:Atome
::[[Dictionnaire de philosophie/Atomisme|Atomisme]]
:{{Page|Attribut}}
:[[Dictionnaire de philosophie/Authenticité|Authenticité]]
:[[Dictionnaire de philosophie/Autonomie|Autonomie]]
:[[Dictionnaire de philosophie/Autorité|Autorité]]
:[[Philosophie/Autrui|Autrui]] <small>(M)</small>
:[[Dictionnaire de philosophie/Avortement|Avortement]] (éthique) ᕻ
:[[Dictionnaire de philosophie/Axiome|Axiome]]
</div>
</div>
{{PhiloRecherche}}
{{Autocat}}
ml180x5es2o21o3f9cksbo4n1nqnluj
Python pour le calcul scientifique/Éléments de programmation
0
72883
767812
767635
2026-06-16T08:11:34Z
Cdang
1202
/* Généralités */ chr, ord
767812
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>
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>
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 vrariables entre accolades. 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éal à 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 notaiton 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>
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} %")
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>
=== Exporter du contenu vers un fichier ===
Si nous voulons créer un fichier texte pour y mettre le contenu de la variable <code>texte</code>, alors nous utilisons :
<syntaxhighlight lang="python">
with open("monfichier.txt", "wt") as fichier:
contenu = 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>
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)]]
orpvkdd64e81q1n5snebn3zcgryq968
767816
767812
2026-06-16T08:39:51Z
Cdang
1202
/* Importer le contenu d'un fichier */ typo
767816
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>
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>
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 vrariables entre accolades. 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éal à 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 notaiton 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>
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} %")
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>
=== Exporter du contenu vers un fichier ===
Si nous voulons créer un fichier texte pour y mettre le contenu de la variable <code>texte</code>, alors nous utilisons :
<syntaxhighlight lang="python">
with open("monfichier.txt", "wt") as fichier:
contenu = 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>
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)]]
f8uqiuhj0ry7o7qula6t9xxa5i6kb3j
767817
767816
2026-06-16T08:41:01Z
Cdang
1202
/* Exporter du contenu vers un fichier */ corr.
767817
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>
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>
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 vrariables entre accolades. 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éal à 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 notaiton 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>
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} %")
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>
=== 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>
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)]]
84utvayho6fiy13bx5mkmoalgjvlx0m
767818
767817
2026-06-16T08:41:26Z
Cdang
1202
/* Exporter du contenu vers un fichier */ typo
767818
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>
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>
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 vrariables entre accolades. 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éal à 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 notaiton 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>
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} %")
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>
=== 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>
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)]]
lzuyy28odc23dc8vt7mivgvidkle25q
Programmation PHP avec Symfony/Composant
0
73411
767811
767495
2026-06-16T07:50:25Z
JackPotte
5426
/* messenger */
767811
wikitext
text/x-wiki
<noinclude>{{Symfony}}</noinclude>
== Description ==
Le framework Symfony permet nativement les fonctionnalités minimum dans un souci de performances, à l'instar d'un micro-framework.
Par exemple son compilateur permet d'utiliser plusieurs patrons de conception (design patterns) via des mots réservés dans services.yaml :
* arguments : [[Patrons de conception/Injection de dépendance|Injection de dépendance]]
* decorator : [[Patrons de conception/Décorateur|Décorateur]].
* shared : [[Patrons de conception/Singleton|Singleton]].
* factory : [[Patrons de conception/Fabrique|Fabrique]]<ref>https://symfony.com/doc/current/service_container/factories.html</ref>.
Toutefois, on peut lui ajouter des composants<ref>https://symfony.com/components</ref>, dont il convient de connaitre les fonctionnalités pour ne pas réinventer la roue. Pour les installer :
<pre>
composer require symfony/nom_du_composant
</pre>
Les quatre premiers ci-dessous sont inclus par défaut dans le microframework <code>symfony/skeleton</code>.
== framework-bundle ==
Structure la configuration principale du framework sans laquelle aucun composant n'est installable<ref>https://symfony.com/doc/current/reference/configuration/framework.html</ref>.
== console ==
[[Patrons de conception/Commande|Patrons de conception "Commande"]].
Fournit la possibilité d'exécuter le framework avec des commandes shell<ref>https://symfony.com/doc/current/components/console.html</ref>. Par exemple pour obtenir la liste de toutes les commandes disponibles dans un projet :
<pre>
php bin/console help list
</pre>
== dotenv ==
Gère les variables d'environnement non versionnées, contenues dans un fichier .env<ref>https://symfony.com/doc/current/components/dotenv.html</ref>. Elles peuvent aussi bénéficier de {{wt|type checking}} en préfixant les types avec ":". Ex de .env :
<pre>
IS_DEV_SERVER=1
</pre>
Le ''services.yaml, parameters:'' récupère ensuite cette valeur et vérifie qu'il s'agit d'un booléen (via le processeur de variable d'environnement "bool") :
<pre>
is_dev_server: '%env(bool:IS_DEV_SERVER)%'
</pre>
Il existe plusieurs processeurs de variable d'environnement (en plus de "bool" et des autres types)<ref>https://symfony.com/doc/current/configuration/env_var_processors.html</ref> :
* <code>base64:</code> encode en base64.
* <code>default:</code> remplace le deuxième paramètre par le premier si absent. Ex :
** <code>$addTestValues: '%env(bool:default::ADD_TEST_VALUES)%'</code> injecte "null" si ADD_TEST_VALUES n'est pas défini.
** <code>$addTestValues: '%env(bool:default:ADD_TEST_VALUES2:ADD_TEST_VALUES1)%'</code> injecte le contenu de ADD_TEST_VALUES2 si ADD_TEST_VALUES1 n'est pas défini.
* <code>file:</code> remplace le chemin d'un fichier par son contenu.
* <code>not:</code> renvoie l'inverse.
* <code>require:</code> fait un require() PHP.
* <code>resolve:</code> remplace le nom d'une variable par sa valeur.
* <code>trim:</code> fait un trim() PHP.
Pour définir une valeur par défaut en cas de variable d'environnement manquante (sans utiliser <code>default:</code>), dans ''services.yaml, parameters:'' :
<pre>
env(MY_MISSING_CONSTANT): '0'
</pre>
== yaml ==
Ajoute la conversion de fichier {{w|YAML}} en tableau PHP<ref>https://symfony.com/doc/current/components/yaml.html</ref>. Ce format de données constitue une alternative plus lisible au XML pour renseigner la configuration des services. Par défaut le framework se configure avec config.yaml.
== routing ==
[[Patrons de conception/Façade|patron de conception "Façade"]].
Installe les annotations permettant de router des URLs vers les classes des contrôleurs MVC.
{{article détaillé|Programmation PHP avec Symfony/Contrôleur#Routing}}
== serializer ==
Permet de convertir des objets en tableaux ou dans les principaux formats de notation : JSON, XML, YAML et CSV<ref>https://symfony.com/doc/current/components/serializer.html</ref>.
<pre>
composer require symfony/serializer
</pre>
Ce composant est notamment utilisé pour créer des APIs.
== form ==
Construit des formulaires HTML.
{{article détaillé|Programmation PHP avec Symfony/Formulaire}}
== validator ==
Fournit des règles de validation pour les données telles que les adresses emails ou les codes postaux. Utile à coupler avec les formulaires pour contrôler les saisies.
Ces règles peuvent porter sur les propriétés ou les getters.
Il permet aussi de créer des groupes de validateurs, et de les ordonner par séquences. Par défaut chaque classe a automatiquement deux groupes de validateurs : "default" et celui de son nom. Si une séquence est définie, le groupe "default" n'est plus égal au groupe de la classe (celui par défaut) mais à la séquence par défaut<ref>https://symfony.com/doc/current/validation/sequence_provider.html</ref>.
=== Exemples ===
* Dans une entité :
<pre>
use Symfony\Component\Validator\Constraints as Assert;
...
#[Assert\Email]
private ?string $email = null;
</pre>
* Dans un formulaire (inutile à faire si c'est déjà dans l'entité) :
<pre>
use Symfony\Component\Validator\Constraints\Email;
...
$builder->add('email', EmailType::class, [
'required' => false,
'constraints' => [new Email()],
])
</pre>
== translation ==
Les traductions sont stockées dans un fichier différent par domaine et par langue (code {{w|ISO 639}}). Les formats acceptés sont YAML, XML, PHP<ref>https://symfony.com/doc/current/translation.html</ref>.
On peut ensuite récupérer ces dictionnaires en Twig (via le filtre "trans"), ou en PHP (via le service "translator").
Par exemple, le domaine par défaut étant "messages", le français se trouve donc dans <code>translations/messages.fr.yml</code> ou <code>translations/messages.fr-FR.yml</code>.
=== Installation ===
<pre>
composer require symfony/translation
</pre>
Pour avoir les traductions inutilisées en anglais :
<pre>
bin/console debug:translation en --only-unused
</pre>
Pour les traductions manquantes en anglais :
<pre>
bin/console debug:translation en --only-missing
</pre>
On peut restreindre à un seul domaine avec une option : <code>--domain=mon_domaine</code>
=== Traduction en PHP ===
Le domaine et la langue sont facultatifs (car ils ont des valeurs par défaut) :
<pre>
$translator->trans('Hello World', domain: 'login', locale: 'fr_FR');
</pre>
{{remarque|le composant Symfony Form appelle automatiquement Translations pour ses "labels".}}
=== Traduction en Twig ===
Les traductions en Twig sont appelées par le [[Programmation PHP avec Symfony/Twig#Filtre_trans|filtre "trans"]] :
<pre>
{% trans_default_domain 'login' %}
{{ 'Hello World' |trans }}
</pre>
Ou :
<pre>
{{ 'Hello World' |trans({}, 'login', 'fr-FR') }}
</pre>
=== Variables ===
* YAML : la variable est entre accolades (selon la norme de l'{{w|International Components for Unicode|ICU}}<ref>https://symfony.com/doc/current/reference/formats/message_format.html</ref>)
<pre>
Hello World: 'Hello World name!'
</pre>
* Twig :
<pre>
{{ Hello World |trans({"name": userName}) }}
</pre>
* PHP
<pre>
$translator->trans('Hello World', ['name' => $userName]);
</pre>
Dans un formulaire Symfony :
<pre>
$builder
->add('hello', TextType::class,([
'label' => 'Hello World',
'label_translation_parameters' => [
'name' => $userName,
]
]))
;
</pre>
Par défaut le domaine de traduction est "message" mais on peut désactiver ces dernières avec : <code>choice_translation_domain => false</code>.
== event-dispatcher ==
[[Patrons de conception/Observateur|Patrons de conception "Observateur"]]<ref>http://www.jpsymfony.com/design_patterns/le-design-pattern-observer-avec-symfony2</ref> et [[Patrons de conception/Médiateur|"Médiateur"]]<ref>https://github.com/certificationy/symfony-pack/blob/babd3fee68a7e793767f67c6df140630f52e7f8d/data/architecture.yml#L13</ref>.
Assure la possibilité d'écouter des évènements pour qu'ils déclenchent des actions.
{{article détaillé|Programmation PHP avec Symfony/Évènement}}
== process ==
Permet de lancer des sous-processus en parallèle<ref>https://symfony.com/doc/current/components/process.html</ref>. Exemple qui lance une commande shell :
<pre>
$process = new Process(['ls']);
$process->run();
</pre>
{{attention|En l'absence de <code>$process->stop()</code> ou de timeout, le sous-processus peut être stoppé en redémarrant le serveur PHP.|clear=left}}
Exemple de requête SQL asynchrone<ref>https://gist.github.com/appaydin/42eaf953172fc7ea6a8b193694645324</ref> :
<pre>
$sql = 'SELECT * FROM ma_table LIMIT 1';
$process = Process::fromShellCommandline(sprintf('../bin/console doctrine:query:sql "%s"', $sql));
$process->setTimeout(3600);
$process->start();
</pre>
== cache ==
Gère les connexions, lectures et écritures vers des serveurs de mémoire caches tels que {{w|Redis}} ou {{w|Memcached}}.
Il fournit une classe ''cacheItem'' conforme à la PSR, instanciable par plusieurs adaptateurs.
Le cache ne sert qu'à accélérer l'application donc une panne sur celui-ci ne doit pas la bloquer. C'est pourquoi il vaut mieux avoir un ou plusieurs caches de secours, même moins rapides, pour prendre le relais dans une chaine de caches.
Pour mettre cela en place sur Symfony, définir le chaine et ses composants dans cache.yaml.
{{article détaillé|Programmation PHP/Redis#Dans Symfony}}
== asset ==
Ajoute la fonction Twig <code>asset()</code> pour accéder aux fichiers CSS, JS ou images selon leurs versions<ref>https://symfony.com/doc/current/components/asset.html</ref>.
== webpack-encore ==
Intégration de {{w|Webpack|lang=en}} pour gérer la partie {{wt|front end}} (ex : minifications des CSS et JS).
=== Installation<ref>https://symfonycasts.com/screencast/stimulus/encore</ref> ===
<pre>
composer require symfony/webpack-encore-bundle
yarn install
yarn build
</pre>
NB : si {{w|Yarn}} n'est pas installé, le faire avec {{w|npm}} : <code>apt install nodejs npm; npm install --global yarn</code>.
Cela crée les fichiers package.json et yarn.lock contenant les dépendances JavaScript, le dossier assets/ contenant les JS et CSS versionnés, et le fichier webpack.config.js dans lequel ils sont appelés.
De plus, des fonctions Twig permettent d'y accéder depuis les templates : <code>encore_entry_link_tags()</code> et <code>encore_entry_script_tags()</code>.
Par ailleurs, cela installe le framework JS Stimulus, et interprète les {{wt|attributs de données}} pour appeler ses contrôleurs ou méthodes.
=== Rebuild ===
Pour que le code se build en cours de frappe, deux solutions<ref>https://symfony.com/doc/current/frontend/encore/simple-example.html</ref> :
* Avec Yarn :
** yarn watch
** yarn dev-server
* Avec npm :
** npm watch
** npm run dev-server
La différence entre les deux est que le dev-server peut mettre à jour la page sans même la rafraichir.
== messenger ==
[[Patrons de conception/Chaîne de responsabilité|Patrons de conception "Chaîne de responsabilité"]].
Messenger permet d'utiliser des queues au protocole {{w|AMQP}}. En résumé, il gère l'envoi de messages dans des bus, ces messages transitent par d'éventuels ''middlewares'' puis arrivent à destination dans des ''handlers''<ref>https://vria.eu/delve_into_the_heart_of_the_symfony_messenger/</ref>. On peut aussi persister ces messages en les envoyant dans des ''transports'' via un {{wt|DSN}}, par exemple dans RabbitMQ, Redis ou Doctrine (donc une table des SGBD les plus populaires).
<pre>
php bin/console debug:messenger
</pre>
Chaque middleware doit passer le relais au suivant ainsi :
<pre>
return $stack->next()->handle($envelope, $stack);
</pre>
Pour stopper le message dans un middleware sans qu'il arrive aux handlers :
<pre>
return $envelope;
</pre>
Chaque message peut être défini comme à traiter en synchrone ou asynchrone.
=== En asynchrone ===
Une même commande peur traiter les plusieurs groupes de messages asynchrones, par exemple ceux qui doivent se relancer en cas d'erreur et ceux à ne surtout pas relancer car ils pourraient générer des doublons. Ex :
<pre>
bin/console messenger:consume async async_no_retry
</pre>
{{attention|Pour le faire tourner en dev avec les mêmes données dans le webprofiler que les autres commandes Symfony (requêtes Doctrine et HTTP Client), il faut ajouter l'option "no-reset" après "profile" :
<pre>
bin/console messenger:consume async async_no_retry --profile --no-reset -vvv
</pre>
}}
{{attention|Pour le faire tourner en prod sans qu'il n'interrompe ses traitements en cours à chaque MEP, il existe plusieurs solutions :
* Processus Linux ''supervisord'' : ne convient pas aux conteneurs car ils interrompent leurs traitements à chaque relance.
* Sidecar container [[Docker/Kubernetes|Kubernetes]] : idem.
* Conteneur dédié qui se redéploie gracieusement après chaque MEP. Par exemple dans Kubernetes, l'option <code>ttlSecondsAfterFinished: 3600</code> garantit que le conteneur attend la fin du traitement en cours jusqu'à 1h maximum avant de se redéployer.
}}
== workflow ==
[[Patrons de conception/Commande|Patrons de conception "État"]].
Ce composant nécessite de créer (en YAML, XML ou PHP) la configuration d'un {{w|automate fini}}<ref>https://symfony.com/doc/current/workflow.html</ref>, c'est-à-dire la liste de ses transitions et états (appelés "places").
Ces graphes sont ensuite visualisables en image ainsi :
<pre>
use Symfony\Component\Workflow\Definition;
use Symfony\Component\Workflow\Dumper\StateMachineGraphvizDumper;
class WorkflowDisplayer
...
$definition = new Definition($places, $transitions);
echo (new StateMachineGraphvizDumper())->dump($definition);
</pre>
<pre>
sudo apt install graphviz
php WorkflowDisplayer.php | dot -Tpng -o workflow.png
</pre>
== browser-kit ==
Simule un navigateur pour les tests d'intégration.
== config ==
Permet de manipuler des fichiers de configurations.
== contracts ==
Pour la {{w|programmation par contrat}}.
== css-selector ==
Pour utiliser {{w|XPath}}.
== debug ==
Fournit des méthodes statiques pour déboguer le PHP.
== dependency-injection ==
Normalise l'utilisation du ''container'' de services.
Permet aussi d'exécuter du code pendant la compilation via un ''compiler pass'', en implémentant l'interface ''CompilerPassInterface'' avec sa méthode ''process''<ref>https://symfony.com/doc/current/components/dependency_injection/compilation.html</ref>.
== dom-crawler ==
Fournit des méthodes pour parcourir le {{w|DOM}}.
== expression-language ==
[[Patrons de conception/Interpréteur|Patrons de conception "Interpréteur"]].
''Expression language ''sert à évaluer des expressions, ce qui peut permettre de définir des règles métier<ref>https://symfony.com/doc/current/components/expression_language.html</ref>.
Installation :
composer require symfony/expression-language
Exemple :
<pre>
$el = new ExpressionLanguage();
$operation = '1 + 2';
echo(
sprintf(
"L'opération %s vaut %s",
$el->compile($operation));
$el->evaluate($operation));
)
);
// Affiche : L'opération 1 + 2 vaut 3
</pre>
== filesystem ==
Méthodes de lecture et écriture dans les dossiers et fichiers.
== finder ==
Recherche dans les dossiers et fichiers.
== security ==
Ensemble de sous-composants assurant la sécurité d'un site. Ex : authentification, anti-{{w|CSRF}} ou droit des utilisateurs d'accéder à une page.
=== Installation ===
<pre>
composer require symfony/security-bundle
</pre>
=== Utilisation ===
Dans security.yaml, on peut par exemple définir les classes qui vont assurer l'authentification (''guard''), ou celle ''User'' qui sera instanciée après.
Pour obtenir l'utilisateur ou son token, on peut injecter :
<pre>
TokenStorageInterface $tokenStorage
</pre>
pour avoir l'utilisateur courant avec <code>$this->tokenStorage->getToken()?->getUser()</code>.
== guard ==
Extension de sécurité pour des authentifications complexes.
== http-client ==
Pour lancer des requêtes HTTP depuis l'application.
{{article détaillé|Programmation PHP avec Symfony/HttpClient}}
== http-foundation ==
Fournit des classes pour manipuler les requêtes HTTP, comme ''Request'' et ''Response'' que l'on retrouve dans les contrôleurs.
Par exemple :
<pre>
use Symfony\Component\HttpFoundation\Response;
//...
echo Response::HTTP_OK; // 200
echo Response::HTTP_NOT_FOUND; // 404
</pre>
== http-kernel ==
Permet d'utiliser des évènements lors des transformations des requêtes HTTP en réponses.
== inflector ==
Deprecated depuis Symfony 5.
Accorde les mots anglais au pluriel à partir de leurs singuliers.
== intl ==
Internationalisation, comme par exemple la classe "Locale" pour gérer une langue.
== ldap ==
Connexion aux serveur {{w|LDAP}}.
== lock ==
Pour verrouiller les accès aux ressources<ref>https://symfony.com/doc/current/components/lock.html</ref>.
Par exemple, pour ne pas qu'une commande soit lancée deux fois simultanément, bien que le composant console aie aussi cette fonctionnalité :
<pre>
use Symfony\Component\Console\Command\LockableTrait;
...
protected function execute(InputInterface $input, OutputInterface $output): int
{
if ($this->lock() === false) {
return Command::SUCCESS;
}
...
$this->release();
return Command::SUCCESS;
}
</pre>
== Maker bundle ==
Pour créer ou recréer des classes à partir de déductions<ref>https://symfony.com/bundles/SymfonyMakerBundle/current/index.html</ref>.
<pre>
composer require --dev symfony/maker-bundle
</pre>
NB : ce composant ne permet pas de générer des entités à partir d'une base de données.
== mailer ==
Pour envoyer des emails.
== mime ==
Manipulation des messages {{w|MIME}}.
== notifier ==
Pour envoyer des notifications telles que des emails, des SMS, des messages instantanés, etc.
== options-resolver ==
Gère les remplacements de propriétés par d'autres, avec certaines par défaut.
== phpunit-bridge ==
[[Patrons de conception/Pont|Patron de conception "Pont"]] qui apporte plusieurs fonctionnalités liées aux tests unitaires, telles que la liste des tests désuets ou des mocks de fonctions PHP natif.
== property-access ==
Pour lire les attributs de classe à partir de leurs getters, ou des tableaux.
== property-info ==
Pour lire les métadonnées des attributs de classe.
== stopwatch ==
Chronomètre pour mesurer des temps d'exécution.
== string ==
API convertissant certains objets en chaine de caractères. Ex :
<pre>
use Symfony\Component\String\Slugger\AsciiSlugger;
$slugger = new AsciiSlugger();
echo $slugger->slug('caractères spéciaux € $');
</pre>
Résultat :
caracteres-speciaux-EUR
== templating ==
Extension de construction de templates.
{{article détaillé|Programmation PHP avec Symfony/Templating}}
== var-dumper ==
Ajoute une fonction globale <code>dump()</code> pour déboguer des objets en les affichant avec une coloration syntaxique et des menus déroulant.
Ajoute aussi <code>dd()</code> pour ''dump() and die()''.
== var-exporter ==
Permet d'instancier une classe sans utiliser son constructeur.
== polyfill* ==
On trouve aussi une vingtaine de composants {{wt|polyfill}}, fournissant des fonctions PHP retirées dans les versions les plus récentes.
== Composants désuets ==
=== locale (<= v2.3) ===
Arrêté en 2011, car remplacé par le composant ''intl''<ref>https://symfony.com/components/Locale</ref>.
=== icu (<= v2.6) ===
Arrêté en 2014, car remplacé par le composant ''intl''<ref>https://symfony.com/components/Icu</ref>.
=== class-loader (<= v3.3) ===
Arrêté en 2011, car remplacé par composer.json<ref>https://symfony.com/components/ClassLoader</ref>.
== Ajoutés en 2020 ==
=== Uid ''(sic)'' (>= v5.1) ===
Pour générer des {{w|UUID}}<ref>https://symfony.com/doc/current/components/uid.html</ref>.
=== RateLimiter (>= v5.2) ===
[[Patrons de conception/Proxy|Patron de conception "Proxy"]], qui permet de limiter la consommation de ressources du serveur par les clients<ref>https://symfony.com/doc/current/rate_limiter.html</ref>
Installation :
<pre>
composer require symfony/rate-limiter
</pre>
Pour l'activer, ajouter la ligne suivante dans les pare-feux de security.yaml concernés :
<pre>
login_throttling: true
</pre>
=== Semaphore (>= v5.2) ===
Pour donner l'exclusivité d'accès à une ressource<ref>https://symfony.com/doc/current/components/semaphore.html</ref>.
== Ajoutés en 2021 ==
=== PasswordHasher (>= v5.3) ===
Pour gérer les chiffrements<ref>https://symfony.com/blog/new-in-symfony-5-3-passwordhasher-component</ref>.
=== Runtime (>= v5.3) ===
Pour le démarrage (bootstrap) : permettre de découpler l'application de son code de retour.
<ref>https://symfony.com/blog/new-in-symfony-5-3-runtime-component</ref>.
== Ajoutés en 2022 ==
=== HtmlSanitizer (>= v6.1) ===
=== Clock (>= v6.2) ===
=== Symfony UX (>= v5.4) ===
==== ux-autocomplete ====
==== ux-chartjs ====
Utilise Chart.js via Stimulus pour afficher des graphiques, via la fonction Twig <code>render_chart()</code><ref>https://symfony.com/bundles/ux-chartjs/current/index.html</ref>.
==== ux-react ====
Ajoute le framework {{w|React.js}}.
{{article détaillé|Programmation PHP avec Symfony/Stimulus}}
==== ux-vue ====
Ajoute le framework {{w|Vue.js}}.
== Ajoutés en 2023 ==
=== Webhook et RemoteEvent (>= v6.3) ===
<ref>https://symfony.com/blog/new-in-symfony-6-3-webhook-and-remoteevent-components</ref>
=== AssetMapper (>= v6.3) ===
<ref>https://symfony.com/blog/new-in-symfony-6-3-assetmapper-component</ref>
=== Scheduler (>= v6.3) ===
<ref>https://symfony.com/blog/new-in-symfony-6-3-scheduler-component</ref>
== Composants non listés comme tels ==
=== apache-pack ===
Pour faire tourner le site sans passer par le serveur <code>symfony server:start</code>.
== Références ==
{{Références}}
af6gswfqxydupomzu9db20pr7f2ob0x
Programmation PHP avec Symfony/Contrôleur
0
79901
767819
749407
2026-06-16T09:55:01Z
JackPotte
5426
/* Accès aux paramètres et services */
767819
wikitext
text/x-wiki
<noinclude>{{Symfony}}</noinclude>
== Principe ==
Les contrôleurs Symfony sont les classes qui définissent les opérations à réaliser quand on visite les pages du sites<ref>https://symfony.com/doc/current/controller.html</ref> : elles transforment une requête HTTP en réponse (JSON, XML (dont HTML), etc.).
Par convention, leurs noms se terminent par ''Controller'', les noms de leurs méthodes se terminent par "Action", et les URL qui provoquent leurs exécutions sont définies dans leurs annotations. L'exemple suivant affiche un texte quand on visite l'adresse "/" ou "/helloWorld" :
<pre>
class HelloWorldController extends AbstractController
{
#[Route(path: '/', name: 'helloWorld')]
#[Route(path: '/helloWorld', name: 'helloWorld')]
public function indexAction(Request $request): Response
{
return new Response('Hello World!');
}
}
</pre>
NB : en PHP < 8, remplacer l'attribut par une annotation :
<pre>
/**
* @Route("/", name="helloWorld")
* @Route("/helloWorld")
*/
</pre>
== Retours ==
Ces méthodes peuvent déboucher sur plusieurs actions :
* <code>Response()</code> : affiche un texte, et facultativement un {{w|Liste des codes HTTP|code HTTP}} en deuxième paramètre (ex : erreur 404).
** <code>JsonResponse()</code> ou <code>$this->json()</code> : affiche du JSON.
** <code>RedirectResponse()</code> : renvoie vers une autre adresse. Si elle se trouve dans la même application, on peut aussi utiliser le <code>$this->forward()</code> hérité du contrôleur abstrait.
** <code>BinaryFileResponse()</code> : renvoie un fichier à télécharger (à partir de son chemin).
* <code>$this->redirect('mon_url')</code> : redirige à une autre adresse.
* <code>$this->redirectToRoute('nom_de_la_route');</code> : redirige vers une route du site par son nom.
* <code>$this->generateUrl('app_mon_chemin', []);</code> : redirige vers une URL relative (ajouter <code>UrlGeneratorInterface::ABSOLUTE_URL</code> en paramètre 3 pour l'absolue, car il est à <code>UrlGeneratorInterface::ABSOLUTE_PATH</code> par défaut dans SF3).
* <code> $this->container->get('router')->generate('app_mon_chemin', ['paramètre' => 'mon_paramètre']);</code>.
* <code>$this->render()</code> : affiche une page à partir d'un template, par exemple HTML ou Twig.
{{remarque|On peut changer les options d'encodage en JSON ainsi :
<pre>
$response = new JsonResponse();
$response->setEncodingOptions(JSON_UNESCAPED_UNICODE);
$response->setData($data);
return $response;
</pre>
}}
== Requêtes ==
L'objet Request est à préférer à la variable superglobale $_REQUEST, car il fournit une sécurité et des méthodes de manipulation. Ex :
* $request->getMethod() : la méthode HTTP utilisée.
* $request->query : les arguments $_GET (query param).
* $request->request : les arguments $_POST (lui préférer $request->getContent()).
* $request->files : les fichiers $_FILES (dans un itérable FileBag).
== ParamConverter ==
On peut injecter un ID dans l'URL ou la requête pour le CRUD d'une [[Programmation PHP avec Symfony/Doctrine|entité]], mais grâce au paramConverter on peut aussi injecter directement l'entité. Ex :
<pre>
#[Route('/my_entity/{id}', methods: ['GET'])]
public function getProduct(MyEntity $myEntity): JsonResponse
{
return new JsonResponse($myEntity);
}
</pre>
{{attention|Avant Symfony 6.2 cela fonctionne avec un <code>composer require sensio/framework-extra-bundle</code>.}}
== Flashbag ==
On peut aussi ajouter un bandeau de message temporaire en en-tête via :
$this->addflash('success', 'mon_message');
Le Twig peut les récupérer ensuite avec<ref>https://stackoverflow.com/questions/14449967/symfony-setting-flash-and-checking-in-twig</ref> :
<pre>
{% for flashMessage in app.session.flashbag.get('success') %}
{{ flashMessage }}
{% endfor %}
</pre>
En effet, ils sont stockés dans un Flashbag : un objet de session.
De plus, il en existe plusieurs types (chacun avec une couleur) : ''success'', ''notice'', ''info'', ''warning'', ''error''.
{{attention|Le fait de lire les flash (au moins depuis les Twig avec app.flashes) vide leur tableau.}}
== Accès aux paramètres et services ==
Les contrôleurs étendent la {{w|classe abstraite}} <code>Symfony\Bundle\FrameworkBundle\Controller\AbstractController</code>. Cela leur permettait entre autres dans Symfony 2, de récupérer les services et paramètres ainsi :
<syntaxhighlight lang=php>
dump($this->get('session'));
dump($this->getParameter('kernel.project_dir'));
</syntaxhighlight>
Depuis Symfony 4, il faut injecter le service ''service_container'' pour accéder à la liste des services publics (<code>public: true</code> en YAML), mais la bonne pratique est d'injecter uniquement les services nécessaires dans le constructeur<ref>https://symfony.com/doc/current/best_practices.html#use-dependency-injection-to-get-services</ref><ref>https://symfony.com/doc/4.0/best_practices/controllers.html#fetching-services</ref>.
Les paramètres sont ceux des fichiers .yml du dossier "config", mais plusieurs autres paramètres sont fournis par Symfony :
bin/console debug:container --parameters
* kernel.debug : renvoie vrai si le site est en préprod et faux en prod.
* kernel.project_dir : dossier racine (qui contient bin/, config/, src/, var/, vendor/).
* kernel.build_dir.
* kernel.cache_dir.
* kernel.logs_dir.
* kernel.root_dir : ''deprecated'' en SF5.3. Chemin du site dans le système de fichier.
* kernel.bundles : liste JSON des bundles chargés.
Par ailleurs, une autre bonne pratique des constructeurs consiste à ne jamais exécuter de méthode dedans, pour plusieurs raisons :
# Leur initialisation car le travail de la méthode est alors fait à la construction du service, pas quand c'est réellement nécessaire, même si le service n'est jamais utilisé dans la requête.
# La difficulté à tester car pour instancier la classe, il faut que les données manipulées par la méthode soient valides ; et là on ne peut pas injecter un mock sans qu'elle soit appelée immédiatement.
# Les exceptions silencieuses car si la méthode lève une exception dans un constructeur, elle remonte comme une erreur de container, difficile à déboguer.
# le couplage temporel car le constructeur ne devrait servir qu'à stocker les dépendances, pas à exécuter de la logique.
== Routing ==
Par exemple pour créer une nouvelle page sur l'URL :
<pre>
http://localhost:8000/test
</pre>
Installer le routage :
<pre>
composer require sensio/framework-extra-bundle
composer require symfony/routing
</pre>
Par défaut, la page renvoie l'exception ''No route found for "GET /test"''. Pour la créer, il faut d'abord générer un fichier contrôleur (rôle {{w|Modèle-vue-contrôleur|MVC}}), qui fera le lien entre les URL, les données (modèle) et les pages (vue).
Les URL définies dans l'attribut (ou l'annotation) "route" d'une méthode exécuteront cette dernière :
<pre>
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class TestController extends AbstractController
{
#[route('/test/{numero}', name: 'test', requirements: ['id' => '\d*'], methods: ['GET', 'POST'], priority: -1)]
public function HelloWorldAction(int $numero = 0)
{
return new Response('Hello World! '.$numero);
}
}
</pre>
NB : en PHP < 8, remplacer l'attribut par une annotation :
<pre>
/**
* @Route("/test/{numero}", name="test", requirements={"id"="\d*"}, methods={"GET|POST"}, priority=-1)
*/
</pre>
Autres exemples de prérequis :
* <code>requirements={"id"="fr|en"}</code>
* <code>requirements={"id"="MaClasse::MA_CONSTANTE1|MaClasse::MA_CONSTANTE2"}</code>
* <code>requirements={"id"="(?!api/doc|_profiler).*"}</code>
{{remarque|1=On peut placer plusieurs attributs ou annotations "route" sur une même méthode. Il est alors possible de changer son comportement selon la route avec <code>if ($request->get('_route') === 'test')</code>.}}
=== Alias ===
Pour créer des alias, c'est-à-dire plusieurs autres URL pointant vers la page ci-dessus, on peut l'ajouter dans les annotations des contrôleurs, ou bien dans <u>config/routes.yaml</u> (anciennement <u>app\config\routing.yml</u> sur Symfony < 4) :
<pre>
test:
path: /test/{numero}
defaults: { _controller: AppBundle:Test:HelloWorld }
</pre>
À présent http://localhost:8000/test/1 ou http://localhost:8000/test/2 affichent "Hello World!".
{{attention|
* Une fois le YAML sauvegardé, l'URL fournie en annotation (/test) ne fonctionne plus.
* S'il y a des annotations précédant @Route dans le même bloc, cela peut inhiber son fonctionnement.
}}
=== Redirection vers la dernière page visitée ===
Une astuce pour rediriger l'utilisateur vers la dernière page qu'il avait visité :
<pre>
$router = $this->get('router');
$lastPage = $request->getSession()->get('last_view_page');
$parameterLastPage = $router->match($lastPage);
$routeLastPage = $parameterLastPage['_route'];
unset($parameterLastPage['_route']); // Pour ne pas la voir dans l'URL finale
return $this->redirect(
$this->generateUrl($routeLastPage, $parameterLastPage)
);
</pre>
=== Annotations.yaml ===
Ce fichier permet de définir des groupes de contrôleurs, dont les routes sont préfixées. Ex :
<pre>
back_controllers:
resource: ../../src/Controller/BackOffice
type: annotation
prefix: admin
front_controllers:
resource: ../../src/Controller/FrontOffice
type: annotation
prefix: api
</pre>
{{attention|1=Dans le cas où les contrôleurs ont des contrôles d'accès différents dans security.yaml, il est impératif de les préfixer ainsi pour éviter toute collision des gardiens.}}
{{remarque|security.yaml utilise les voteurs : des classes qui écoutent des évènements pour vérifier les permissions de l'utilisateur logué<ref>https://symfony.com/doc/current/security/voters.html</ref>.}}
=== Paramètres spéciaux ===
Il existe quatre paramètres spéciaux que l'on peut placer dans routes.yaml ou en argument des méthodes des contrôleurs<ref>https://symfony.com/doc/current/routing.html#special-routing-parameters</ref> :
* _controller : contrôleur appelé par le chemin.
* _ format : format de requête (ex : html, xml).
* _fragment : partie de l'URL après "#".
* _locale : langue de la requête (code ISO, ex : fr, en).
Exemple :
<pre>
#[Route('/controller_route', requirements: ['_locale' => 'en|fr'])]
class MyController extends AbstractController
</pre>
== Vue ==
Pour commencer à créer des pages plus complexes, il suffit de remplacer :
<pre>
return new Response('Hello World!');
</pre>
par une vue issue d'un {{w|Catégorie:Moteur de template|moteur de template}}. Celui de Symfony est [[Programmation PHP avec Symfony/Twig|Twig]] :
<pre>
return $this->render('helloWorld.html.twig');
</pre>
Pour installer les bibliothèques JavaScript qui agiront sur ces pages, se positionner dans <u>/public</u>. Exemple :
<pre>
cd public/
sudo apt-get install npm
npm install --save jquery
npm install --save bootstrap
</pre>
Ensuite il suffit de les appeler dans <u>/templates/helloWorld.html.twig</u> pour pouvoir les utiliser :
<pre>
<link rel="stylesheet" href="{{ asset('node_modules/bootstrap/dist/css/bootstrap.min.css') }}">
<script type="text/javascript" src="{{ asset('node_modules/jquery/dist/jquery.min.js') }}"></script>
<script type="text/javascript" src="{{ asset('node_modules/bootstrap/dist/js/bootstrap.min.js') }}"></script>
</pre>
== Modèle ==
Pour gérer le modèle du MVC, c'est-à-dire la structure des données stockées, l'{{w|Mapping objet-relationnel|ORM}} officiel de Symfony se nomme [[Programmation PHP avec Symfony/Doctrine|Doctrine]].
Par défaut, ses classes sont :
* src/Entity : les entités, reflets des tables.
* src/Repository : les requêtes SELECT SQL (ou find MongoDB).
== Tester un contrôleur ==
{{article détaillé|Programmation PHP avec Symfony/HttpClient#Tests}}
== Références ==
{{Références}}
ktxb0gbbi7326093ulq3gon57tb4byf
Dictionnaire de philosophie/Anarchisme
0
83018
767809
767685
2026-06-16T04:39:49Z
PandaMystique
119061
767809
wikitext
text/x-wiki
{{DicoPhilo|Anarchisme}}
[[Fichier:Anarchy-symbol.svg|vignette|redresse=0.6|Le « A cerclé », signe de ralliement du mouvement anarchiste, diffusé à partir des années 1960.]]
L'anarchisme compte parmi les théories politiques et sociales les plus décriées et les plus mal comprises de la tradition intellectuelle occidentale. On le réduit souvent à une apologie du désordre ou à un individualisme égocentré, alors qu'il repose sur une critique argumentée des structures de domination et sur un projet d'organisation sociale. Son objet n'est pas l'autorité en tout sens, encore moins la compétence, mais l'autorité non consentie et dominatrice, ainsi que la hiérarchie qui l'accompagne<ref>Pelletier, Philippe, ''L'Anarchisme'', Paris, Le Cavalier Bleu, coll. « Idées reçues », 2010, chapitre « L'anarchie, c'est le chaos ».</ref>. À cette critique s'ajoute l'esquisse d'une société organisée sur des bases non hiérarchiques, sans État contraignant, fondée sur l'autonomie individuelle et collective, la coopération volontaire et la solidarité mutuelle.
== Genèse historique et formulation théorique ==
[[Fichier:William Godwin cropped.jpg|vignette|gauche|redresse|William Godwin (1756-1836), dont l'{{'}}''Enquête sur la justice politique'' (1793) propose la première défense systématique des thèses anarchistes, avant même que le mot soit forgé.]]
On a parfois cherché des préfigurations de l'anarchisme dans des traditions anciennes, du taoïsme attribué à Lao-tseu au VIe siècle avant notre ère à certaines communautés religieuses égalitaires comme les Esséniens ou des courants anabaptistes. Guérin met en garde contre cette quête de précurseurs, qui s'attache selon lui à des « ressemblances superficielles »<ref>Guérin, ''L'anarchisme'', avant-propos.</ref>. Pelletier déplace la question du terrain doctrinal vers celui de l'anthropologie : à la suite de Pierre Clastres, Harold Barclay et David Graeber, il décrit des sociétés sans pouvoir politique coercitif, qu'il qualifie d'« anarchisantes » tout en les disant « très imparfaites », la guerre et certaines croyances mystiques y introduisant des formes d'autorité et d'aliénation<ref>Pelletier, ''L'Anarchisme'', « Un anarchisme "primitif" ? ».</ref>. En tant que philosophie articulée, l'anarchisme se forme dans le contexte de la modernité européenne, sur le terrain de la désintégration de l'ordre médiéval, de la phase la plus contestataire de la Réformation et des premières formes d'organisation politique et économique moderne<ref>Fiala, Andrew, "Anarchism", in ''The Stanford Encyclopedia of Philosophy'', Edward N. Zalta (éd.), Stanford University, 2017.</ref><ref>Woodcock, George, ''Anarchism: A History of Libertarian Ideas and Movements'', Peterborough, Broadview Press, 2004 (édition originale 1962), p. 28-35.</ref>.
Le premier auteur chez qui George Woodcock reconnaît les éléments d'une doctrine anarcho-communiste est Gerrard Winstanley, un négociant en tissus qui dirigea le petit mouvement des Diggers durant le Commonwealth anglais<ref>Woodcock, ''Anarchism'', 2004, p. 39-42.</ref>. Dans ses pamphlets de 1649 et 1650, notamment ''The New Law of Righteousnes'' (1649), Winstanley articulait une vision égalitaire fondée sur un christianisme rationnel : il identifiait le Christ à la liberté universelle et affirmait le caractère universellement corrupteur de l'autorité<ref>Winstanley, Gerrard, ''The New Law of Righteousnes'' [orthographe de l'édition originale de 1649], Londres, 1649, reproduit dans ''The Works of Gerrard Winstanley'', George H. Sabine (éd.), Ithaca, Cornell University Press, 1941, p. 149-200.</ref>. Il percevait un lien intime entre l'institution de la propriété et l'absence de liberté, et proposait une société où le travail serait effectué en commun et les produits partagés par un système d'entrepôts ouverts, sans commerce. Woodcock note toutefois que le dernier écrit de Winstanley, ''The Law of Freedom'' (1652) adressé à Cromwell, comporte des éléments autoritaires, dont le travail obligatoire et la peine de mort pour certains délits contre la collectivité, ce qui interdit d'en faire sans réserve un système anarchiste achevé<ref>Woodcock, ''L'Anarchisme. Une histoire des idées et mouvements libertaires'', Montréal, Lux, 2019, chapitre « L'arbre généalogique ».</ref>.
C'est William Godwin qui, avec son ''Enquête sur la justice politique et son influence sur la vertu générale et le bonheur'' (''An Enquiry Concerning Political Justice, and its Influence on General Virtue and Happiness'') publié en 1793, fournit la première défense systématique de l'anarchisme, même si le terme lui-même n'était pas encore employé<ref>Godwin, William, ''An Enquiry Concerning Political Justice, and its Influence on General Virtue and Happiness'', Londres, G.G.J. et J. Robinson, 1793, 2 volumes.</ref><ref>Philp, Mark, ''Godwin's Political Justice'', Londres, Duckworth, 1986, p. 1-25.</ref>. Godwin, influencé par la dissidence protestante anglaise et la philosophie française des Lumières, développa les critiques anarchistes de l'État, de la propriété accumulée et de la délégation d'autorité à travers les procédures démocratiques. Il croyait en une moralité fixe, se manifestant par la bienveillance universelle, et soutenait que les individus devaient agir selon leur propre raison plutôt qu'en obéissance à l'autorité d'institutions positives, lesquelles constituent toujours des obstacles au progrès éclairé<ref>Godwin, ''Political Justice'', vol. 1, livre II, chapitre 6, p. 234-248.</ref>.
C'est avec Pierre-Joseph Proudhon qu'apparaît le terme d'anarchisme comme désignation positive d'une philosophie<ref>Proudhon, Pierre-Joseph, ''Qu'est-ce que la propriété ? ou Recherche sur le principe du Droit et du Gouvernement'', Paris, J.-F. Brocard, 1840, p. 286.</ref>. En 1840, dans ''Qu'est-ce que la propriété ?'', Proudhon se décrivit lui-même comme anarchiste, considérant que l'organisation politique fondée sur l'autorité devait être remplacée par une organisation sociale et économique fondée sur l'accord contractuel volontaire. Avec cette formulation, un mot jusque-là péjoratif, synonyme de désordre, devient l'étiquette revendiquée d'une tradition cohérente. Pelletier rappelle que Proudhon emploie le mot ''anarchie'' dans un sens constructif dès les années 1840, et qu'il sera repris par dérision, à la manière des Gueux, par les socialistes « anti-autoritaires » des années 1880 que leurs adversaires marxistes et républicains désignaient ainsi<ref>Pelletier, ''L'Anarchisme'', « L'anarchie, c'est le chaos ».</ref>.
== Diversité des courants anarchistes ==
L'anarchisme ne constitue pas un corpus doctrinal unifié, mais une constellation de positions partageant certaines ressemblances de famille<ref>Jun, Nathan J., ''Anarchism and Political Modernity'', New York, Continuum, 2012, p. 15-40.</ref>. Ses variantes s'étendent de l'individualisme de Max Stirner à l'anarcho-communisme de Pierre Kropotkine, en passant par le mutuellisme de Proudhon, le collectivisme de Michel Bakounine et l'anarcho-syndicalisme. Guérin souligne cependant que cette diversité recouvre un ensemble de conceptions relativement homogènes : la formule de Bakounine définissant l'anarchisme comme « le proudhonisme largement développé et poussé jusqu'à ses extrêmes conséquences » vaut, à ses yeux, pour l'essentiel du courant social<ref>Guérin, ''L'anarchisme'', avant-propos.</ref>.
=== L'anarchisme individualiste ===
[[Fichier:Max Stirner-k.jpg|vignette|Max Stirner (1806-1856), tel que l'a croqué de mémoire Friedrich Engels. Son livre ''L'Unique et sa propriété'' (1844) passe pour l'acte de naissance de l'anarchisme individualiste.]]
Max Stirner, de son vrai nom Johann Kaspar Schmidt (1806-1856), représente la tendance la plus individualiste de la pensée anarchiste<ref>Stirner, Max, ''Der Einzige und sein Eigentum'', Leipzig, Otto Wigand, 1844 ; traduction française ''L'Unique et sa propriété'', Paris, Stock, 1900.</ref>. Son ouvrage ''L'Unique et sa propriété'' (''Der Einzige und sein Eigentum'', 1844), tenu pour un texte fondateur de l'anarchisme individualiste, défend une position où la liberté de l'individu est souveraine et où toute entrave à cette liberté est injustifiable. Stirner attaque non seulement l'État, le gouvernement, le droit et la propriété privée, mais aussi la religion, la famille, l'éthique et l'amour, toutes institutions qui imposent des limites à l'action individuelle<ref>Paterson, Ronald William Keith, ''The Nihilistic Egoist: Max Stirner'', Oxford, Oxford University Press, 1971, p. 97-135.</ref>. Pour lui, l'État, la propriété comme droit, les droits naturels et l'idée même de société sont des illusions, des « fantômes » (''Spuke'') dans l'esprit<ref>Stirner, ''L'Unique et sa propriété'', p. 43-67.</ref>. La propriété, écrit-il, résulte de la force : « Je ne recule pas timidement devant ta propriété, mais je la considère toujours comme ma propriété »<ref>Stirner, ''Der Einzige und sein Eigentum'', p. 251.</ref>.
Cette philosophie, parfois qualifiée d'égoïsme, soutient que l'individu n'a pas à se dévouer à « une grande idée, une bonne cause, une doctrine, un système, une vocation élevée », mais qu'il « vit sa propre vie » sans égard à « comment l'humanité peut s'en tirer »<ref>Stirner, ''L'Unique et sa propriété'', p. 5-12.</ref>. Stirner préconisait l'auto-affirmation et envisageait l'Union des égoïstes (''Verein von Egoisten''), association non systématique destinée à remplacer l'État, comprise comme une relation continuellement renouvelée par le soutien volontaire de toutes les parties<ref>Clark, John P., ''Max Stirner's Egoism'', Londres, Freedom Press, 1976, p. 71-89.</ref>. Guérin relativise l'opposition entre cet individualisme et l'anarchisme social, observant que « l'anarchiste individualiste pourrait bien être un sociétaire qui n'ose pas dire son nom »<ref>Guérin, ''L'anarchisme'', avant-propos.</ref>.
=== Le mutuellisme proudhonien ===
[[Fichier:Portrait Pierre-Joseph Proudhon by Nadar – BNF(cropped).jpg|vignette|gauche|redresse|Pierre-Joseph Proudhon (1809-1865), photographié par Nadar. En 1840, il revendique le premier le mot « anarchie » dans un sens positif.]]
Le mutuellisme, développé par Pierre-Joseph Proudhon (1809-1865), se distingue de l'anarchisme individualiste par son insistance sur la dimension sociale du comportement humain<ref>Vincent, K. Steven, ''Pierre-Joseph Proudhon and the Rise of French Republican Socialism'', Oxford, Oxford University Press, 1984, p. 145-178.</ref>. Proudhon rejetait l'action politique et la violence révolutionnaire, certains de ses disciples s'opposant même aux grèves comme forme de coercition, en faveur d'une réforme de la société par la propagation pacifique d'associations ouvrières consacrées notamment au crédit mutuel entre producteurs<ref>Proudhon, Pierre-Joseph, ''De la capacité politique des classes ouvrières'', Paris, E. Dentu, 1865, p. 89-124.</ref>. Un projet mutuelliste récurrent, jamais réalisé, était celui d'une banque populaire organisant l'échange de marchandises sur la base de bons de travail.
Proudhon établit une distinction entre la possession et la propriété : la possession a une valeur d'usage directe pour celui qui en dispose, tandis que la propriété est entendue comme propriété productive<ref>Proudhon, ''Qu'est-ce que la propriété ?'', p. 1-45.</ref>. Contrairement aux défenseurs de la propriété capitaliste, il insistait sur l'égalité et soutenait que tous les travailleurs devraient posséder une part de la propriété et accéder au capital, écrivant que « chaque travailleur employé dans l'association doit avoir une part indivise de la propriété de la compagnie »<ref>Proudhon, Pierre-Joseph, ''Théorie de la propriété'', Paris, Lacroix et Verboeckhoven, 1866, p. 137.</ref>. Il considérait que « la propriété privée de privilège a appelé et commandé l'État », et qu'elle n'était maintenue que par ses lois, sa police et son armée.
Les mutuellistes mettaient l'accent sur l'organisation fédéraliste, de la commune locale vers les échelons supérieurs, comme substitut à l'État national<ref>Proudhon, Pierre-Joseph, ''Du Principe fédératif et de la nécessité de reconstituer le parti de la révolution'', Paris, E. Dentu, 1863, p. 55-91.</ref>. Il convient toutefois de ne pas réduire le projet proudhonien au maintien de la petite propriété artisanale et paysanne. Guérin montre que la pensée économique de Proudhon est ambivalente : pour la grande industrie, il était délibérément collectiviste, écrivant que « la grande industrie et la grande culture, il faut à l'avenir les faire naître de l'association », et s'indignant qu'on le tînt pour un adversaire du progrès technique<ref>Guérin, ''L'anarchisme'', chapitre « L'autogestion ».</ref>. Guérin rappelle aussi que la « coterie soi-disant proudhonienne » formée autour du Proudhon des dernières années, qui tenta dans la Première Internationale d'opposer la propriété privée des moyens de production au collectivisme, était « mort-née », la plupart de ses membres se ralliant aux arguments de Bakounine<ref>Guérin, ''L'anarchisme'', chapitre « L'autogestion ».</ref>.
=== Le collectivisme bakouninien ===
[[Fichier:Mikhail Bakunin 1862 - Nadar (cropped).jpg|vignette|redresse|Michel Bakounine (1814-1876), photographié par Nadar en 1862. Théoricien du collectivisme, il anime l'opposition libertaire au marxisme au sein de la Première Internationale.]]
Le collectivisme est la forme d'anarchisme associée à Michel Bakounine (1814-1876)<ref>Bakunin, Michel, ''Œuvres complètes'', édition établie par Arthur Lehning, 8 volumes, Paris, Champ libre, 1973-1982.</ref>. Cette philosophie fut développée par Bakounine à partir de 1864, lorsqu'il forma ses premières organisations internationales, la Fraternité internationale puis l'Alliance internationale de la démocratie socialiste (1868). C'est l'anarchisme collectiviste qui forma la principale opposition au marxisme dans l'Association internationale des travailleurs, ouvrant la rivalité historique entre les conceptions libertaires et autoritaires du socialisme<ref>Carr, E. H., ''Michael Bakunin'', Londres, Macmillan, 1937, p. 345-412.</ref>.
Bakounine et les collectivistes s'accordaient avec les mutuellistes sur le rejet de l'État et des méthodes politiques, sur le fédéralisme et sur la rétribution du travailleur selon son travail. Ils en différaient en insistant sur la nécessité de moyens révolutionnaires pour abattre l'État, et surtout en préconisant la propriété publique de la terre et des moyens de production, gérés par des associations ouvrières. Alors que dans le mutuellisme l'unité de base était le travailleur individuel, dans le collectivisme c'était le groupe de travailleurs<ref>Bakunin, Michel, ''Étatisme et anarchie'', édition française établie par Renée Lamberet, Paris, Champ libre, 1976, p. 289-345.</ref>. Bakounine rejeta l'individualisme et soutint que l'anarchisme était une doctrine sociale, fondée sur l'acceptation de responsabilités collectives.
Ses écrits expriment une hostilité envers l'État et envers « l'organisation politique elle-même en tant que source d'oppression et d'exploitation »<ref>Bakunin, Michel, ''Dieu et l'État'', Genève, 1882 ; réédition Paris, Maspero, 1976, p. 29-67.</ref>. Ses solutions révolutionnaires visent le démantèlement de l'État et des institutions hiérarchiques, à remplacer par un système de communes librement fédérées, organisées du bas vers le haut, avec des associations volontaires de producteurs s'étendant du local à l'international. Sa pensée politique concerne des communautés émancipatrices où les membres développent leurs capacités sans se dominer les uns les autres<ref>Saltman, Richard B., ''The Social and Political Thought of Michael Bakunin'', Westport, Greenwood Press, 1983, p. 102-134.</ref>. Pour lui, la liberté exigeait la communauté, de sorte que nul n'est libre si tous ne le sont, ainsi que l'égalité, y compris dans les droits et les fonctions sociales pour les femmes.
=== L'anarcho-communisme kropotkinien ===
[[Fichier:Peter Kropotkin circa 1900(cropped).png|vignette|gauche|redresse|Pierre Kropotkine (1842-1921), géographe et théoricien de l'anarcho-communisme. Dans ''L'Entraide'' (1902), il fait de la coopération un facteur de l'évolution.]]
Ailleurs remplacé durant les années 1870 par l'anarcho-communisme, associé surtout à Pierre Kropotkine (1842-1921)<ref>Kropotkin, Pierre, ''La Conquête du pain'', Paris, Tresse et Stock, 1892 ; réédition Paris, Éditions du Sextant, 2006.</ref>, le collectivisme conserva en Espagne une influence plus durable qu'ailleurs, avant d'y être recouvert dans les années 1930 par l'anarcho-syndicalisme de la CNT et par le communisme libertaire<ref>Woodcock, ''L'Anarchisme'' (Lux, 2019), chapitre « L'anarchisme en Espagne ».</ref>. Kropotkine fut sans doute l'exposant le plus articulé d'une tendance issue des discussions entre intellectuels anarchistes à Genève après la Commune de Paris de 1871. Dans ''La Conquête du pain'' (1892) et ''Champs, usines et ateliers'' (''Fields, Factories and Workshops'', 1899), il élabora le schéma d'une société décentralisée fondée sur l'intégration de l'agriculture et de l'industrie, de la vie urbaine et de la vie rurale, de l'éducation et de l'apprentissage<ref>Kropotkin, Pierre, ''Fields, Factories and Workshops'', Londres, Thomas Nelson and Sons, 1899 ; traduction française ''Champs, usines et ateliers'', Paris, Stock, 1910.</ref>.
Kropotkine lia ses théories aux thèses évolutionnistes : l'anarchisme, suggérait-il dans ''L'Entraide'' (''Mutual Aid: A Factor of Evolution'', 1902), était le stade final du développement de la coopération comme facteur d'évolution<ref>Kropotkin, Pierre, ''Mutual Aid: A Factor of Evolution'', Londres, William Heinemann, 1902 ; traduction française ''L'Entraide, un facteur de l'évolution'', Paris, Hachette, 1906.</ref>. L'anarcho-communisme différait du collectivisme sur un point : le partage du produit du travail. À l'idée d'une rémunération selon les heures travaillées, les anarcho-communistes opposaient le mot d'ordre « De chacun selon ses moyens, à chacun selon ses besoins » et envisageaient des entrepôts ouverts où chacun prendrait ce dont il a besoin. Ils raisonnaient que le travail était un besoin naturel et que, sans restriction sur les biens disponibles, nul ne serait tenté de prendre plus qu'il ne peut utiliser<ref>Kropotkin, ''La Conquête du pain'', chapitre 5, p. 71-89.</ref>.
Kropotkine insistait sur les aspects mutualistes et coopératifs des communautés animales et humaines, soutenant que l'entraide, et non la seule compétition, est un facteur du changement évolutif, point ultérieurement repris par de nombreux biologistes<ref>Todes, Daniel P., ''Darwin without Malthus: The Struggle for Existence in Russian Evolutionary Thought'', Oxford, Oxford University Press, 1989, p. 123-145.</ref>. Il chercha à fonder l'éthique sur l'observation de la nature<ref>Kropotkin, Pierre, ''L'Éthique'', ouvrage posthume publié en 1922 ; traduction française Paris, Stock, 1979, p. 34-78.</ref>. En critiquant le capitalisme et l'État, en proposant la commune médiévale comme exemple et en mobilisant la biologie et l'éthologie pour l'analyse sociale, il unit des orientations évolutionnistes et révolutionnaires dans une vision du monde où la dimension écologique occupe une place centrale.
=== L'anarcho-syndicalisme ===
[[Fichier:Fernand Pelloutier-portrait.jpg|vignette|redresse|Fernand Pelloutier (1867-1901), animateur des Bourses du travail et l'une des figures de l'anarcho-syndicalisme français à ses débuts.]]
L'anarcho-syndicalisme se développa à la fin des années 1880, lorsque de nombreux anarchistes entrèrent dans les syndicats français qui réémergeaient après la suppression consécutive à la Commune de Paris<ref>Julliard, Jacques, ''Fernand Pelloutier et les origines du syndicalisme d'action directe'', Paris, Éditions du Seuil, 1971, p. 87-134.</ref>. Des militants anarchistes occupèrent ensuite des postes clés dans la Confédération générale du travail, fondée en 1895, et déplacèrent la base de l'anarchisme vers les syndicats, vus comme des organisations unissant les producteurs dans une lutte commune et dans un travail commun. Cette lutte devait prendre la forme de l'action directe, principalement dans l'industrie ; sa forme la plus élevée, la grève générale, pourrait paralyser le capitalisme et l'État<ref>Pouget, Émile, ''Le Sabotage'', Paris, Marcel Rivière, 1910, p. 17-45.</ref>. Les syndicats, organes de révolte, deviendraient alors les unités de base de la société libre : les travailleurs prendraient le contrôle des usines et se fédéreraient par industries.
L'anarcho-syndicalisme place ainsi les syndicats au centre du conflit de classe<ref>van der Linden, Marcel et Wayne Thorpe (éds.), ''Revolutionary Syndicalism: An International Perspective'', Aldershot, Scolar Press, 1990, p. 1-24.</ref>. Il les conçoit comme un moyen d'obtenir des améliorations immédiates et de préparer une révolution sociale prenant la forme d'une grève générale, dans le but d'abolir l'État et le capitalisme. Idéologie anti-parlementaire, il rejette les partis politiques et pratique l'action directe sous forme de grèves, de boycotts et de sabotage. Les organisations fédérales sont construites du bas vers le haut, sur une base à la fois territoriale et industrielle : les syndicats locaux se combinent en cartels, lesquels se regroupent à l'échelle régionale puis nationale, chaque syndicat étant aussi lié aux syndicats des métiers connexes au sein d'unions industrielles<ref>Rocker, Rudolf, ''Anarcho-Syndicalism: Theory and Practice'', Oakland, AK Press, 2004 (édition originale 1938), p. 54-82.</ref>.
En France, en Italie et en Espagne, ce fut la variante syndicaliste qui donna à l'anarchisme son seul soutien de masse. Ses principaux artisans furent des militants tels que Fernand Pelloutier, Georges Yvetot et Émile Pouget. Des intellectuels extérieurs au mouvement en tirèrent des conclusions théoriques, tel Georges Sorel, dont les ''Réflexions sur la violence'' (1908) voient dans la grève générale un mythe social. Sa trajectoire ultérieure, hétérodoxe, et le fait que Russell le présente d'abord comme un critique de Marx invitent à ne pas en faire la figure centrale du courant<ref>Russell, Bertrand, ''Le monde qui pourrait être. Socialisme, anarchisme et anarcho-syndicalisme'', Montréal, Lux, 2025, première partie, « La révolte anarcho-syndicaliste ».</ref>.
=== Une typologie wébérienne ===
La classification en trois courants, individualisme, communisme libertaire et anarcho-syndicalisme, demeure commode pour l'exposé historique, mais l'historien Gaetano Manfredonia la juge insuffisante. Reprenant la méthode des types idéaux de Max Weber, qui accentue certains traits pour construire des catégories absentes comme telles de la réalité empirique, il distingue trois types : l'insurrectionnalisme, le syndicalisme et l'éducationnisme-réalisateur. Chez un même individu, un groupe ou une organisation, ces orientations se confondent ou se succèdent<ref>Pelletier, ''L'Anarchisme'', « Une nouvelle typologie de l'anarchisme ».</ref>. Cette lecture présente l'avantage de saisir des dynamiques que la classification doctrinale fige en écoles séparées.
== Fondements philosophiques et critique de l'autorité ==
La critique anarchiste ne porte pas sur l'autorité en tout sens. Dans sa polémique avec les individualistes, Malatesta écrit qu'il accepte volontiers « l'autorité du conducteur de train » lorsqu'il voyage, et l'anarchisme reconnaît les compétences sans leur conférer de valeur hiérarchique : un hôpital a besoin de chirurgiens comme d'agents d'entretien<ref>Pelletier, ''L'Anarchisme'', « L'anarchie, c'est le chaos ».</ref>. En matière d'éducation, Bakounine formule le principe d'un mouvement allant « du maximum d'autorité au maximum de liberté », l'autorité s'imposant à qui n'a pas encore les moyens du discernement, puis cédant la place à la liberté<ref>Bakounine, ''Dieu et l'État'' ; cité par Pelletier, ''L'Anarchisme'', « L'anarchie, c'est le chaos ».</ref>. Ce que l'anarchisme combat est l'autorité non consentie et dominatrice, et la hiérarchie qui en découle.
Malgré leurs différences, toutes ces formes d'anarchisme se rejoignent dans le rejet de l'État, de la politique partisane et de la propriété accumulée, mais aussi dans des attitudes plus diffuses<ref>Marshall, Peter, ''Demanding the Impossible: A History of Anarchism'', Londres, Fontana Press, 1993, p. 3-19.</ref>. En évitant l'organisation partisane, l'anarchisme conserva un élément moral plus marqué que d'autres mouvements de protestation. Cet aspect se manifeste dans le goût de ses tenants pour la simplification de la vie, comprise non seulement comme suppression des complications de l'autorité, mais aussi comme refus des périls de la richesse et établissement d'une suffisance frugale.
Le rapport de l'anarchisme au progrès donne lieu à des lectures divergentes qu'il convient de signaler. Woodcock observe que l'accroissement continu des biens matériels n'a jamais séduit les anarchistes et qu'ils rejettent le présent au nom d'un futur de liberté sobre, ressuscitant les vertus d'un passé plus proche de la nature, une société qui, écrit-il, « rejette l'utopie » et ne connaît ni absolus ni perfections. Guérin nuance cette image : selon lui, l'anarchisme se veut constructif, refuse l'accusation d'utopie et recourt à la méthode historique pour montrer que la société future est le produit d'un travail souterrain du passé, et non une invention de doctrinaire<ref>Guérin, ''L'anarchisme'', chapitre « L'anarchisme n'est pas utopique ».</ref>.
La principale différence entre les anarchistes et les socialistes, marxistes compris, tient à ce que, pour ces derniers, l'État doit être pris en main comme première étape vers sa dissolution, alors que les anarchistes soutiennent que, le pouvoir corrompant, toute prise de la structure d'autorité existante ne peut que la perpétuer<ref>Guérin, Daniel, ''Anarchism: From Theory to Practice'', New York, Monthly Review Press, 1970, p. 13-43.</ref>. Les anarcho-syndicalistes considèrent toutefois leurs syndicats comme l'ossature d'une société nouvelle croissant au sein de l'ancienne.
Les anarchistes ont produit des arguments niant toute obligation générale d'obéir à l'État et soulignant les effets du pouvoir étatique<ref>Wolff, Robert Paul, ''In Defense of Anarchism'', New York, Harper & Row, 1970, p. 3-27.</ref>. Plus discutées sont leurs thèses selon lesquelles l'État devrait être aboli, l'ordre social possible sans lui et une transition vers l'anarchie réaliste<ref>McLaughlin, Paul, ''Anarchism and Authority: A Philosophical Introduction to Classical Anarchism'', Aldershot, Ashgate, 2007, p. 45-78.</ref>. Selon eux, la charge de la preuve incombe à qui prétend gouverner et contrôler autrui : l'autorité doit démontrer qu'elle agit dans l'intérêt de ceux qu'elle gouverne, faute de quoi son exercice est illégitime.
== L'organisation sans l'État : autogestion et fédéralisme ==
Les théoriciens du courant social distinguent l'anarchie du désordre. Proudhon soutient que l'anarchie n'est pas le désordre, mais l'ordre naturel par opposition à l'ordre artificiel imposé d'en haut, la « société organisée, vivante »<ref>Guérin, ''L'anarchisme'', chapitre « Nécessité de l'organisation ».</ref>. Voline précise qu'il ne s'agit pas d'« organisation » ou de « non-organisation », mais de deux principes d'organisation distincts, l'un partant de la base et se nouant en centres de coordination, l'autre calqué sur la vieille société d'oppression. Malatesta rappelle à l'ordre les anarchistes hostiles à toute organisation, observant que renoncer à s'organiser pour ne pas accepter la moindre autorité reviendrait à préférer une désorganisation qui rend la vie impossible<ref>Guérin, ''L'anarchisme'', chapitre « Nécessité de l'organisation ».</ref>.
L'autogestion constitue, selon Guérin, la création la plus originale de l'anarchisme<ref>Guérin, ''L'anarchisme'', avant-propos et chapitre « L'autogestion ».</ref>. Alors que le ''Manifeste communiste'' n'entrevoyait, pour une longue période, que la centralisation des instruments de production entre les mains de l'État, Proudhon proposa une conception antiétatique de la gestion économique. Devant la floraison spontanée d'associations ouvrières de production lors de la révolution de février 1848, il vit dans cette autogestion naissante, plus que dans la révolution politique, le fait révolutionnaire, et pressa les travailleurs de s'organiser pour devenir maîtres de la production. Les instruments de production et d'échange ne devraient être gérés ni par des compagnies capitalistes ni par l'État, mais par des associations ouvrières, seule manière, selon Proudhon, de mettre fin à l'aliénation des forces collectives<ref>Guérin, ''L'anarchisme'', chapitre « L'autogestion ».</ref>.
La démocratie directe du projet anarchiste repose sur le fédéralisme libertaire. Pelletier note que les anarchistes lui préfèrent parfois le terme de « gestion directe », pour se distinguer de l'expérience yougoslave conduite dans un cadre étatique et sans libertés publiques : chaque unité économique, chaque service public, chaque association se gère elle-même, l'égoïsme possible des unités étant contrebalancé par leur intégration horizontale dans la commune et la région<ref>Pelletier, ''L'Anarchisme'', « L'anarchisme est contre la démocratie ».</ref>. Le fédéralisme procède ainsi de la logique proudhonienne du contrat libre, synallagmatique et commutatif, et l'anarchisme se conçoit, selon Pelletier, comme un mode de gestion des antagonismes fondé sur l'équilibre des forces<ref>Pelletier, ''L'Anarchisme'', « L'anarchie, c'est le chaos » ; Proudhon, ''Du Principe fédératif''.</ref>.
[[Fichier:Barcelone 19 juillet 1936.jpg|vignette|gauche|Barcelone, juillet 1936. L'échec du soulèvement militaire en Catalogne ouvre une période de collectivisations, dont celles, fédérées par cantons, des collectivités agraires d'Aragon.]]
La révolution espagnole offrit à cette conception une mise à l'épreuve. En Aragon, après l'échec du putsch franquiste en Catalogne en juillet 1936, des collectivités agricoles se constituèrent et se fédérèrent par cantons puis dans un comité régional gérant un fonds d'échanges. Selon les sources libertaires et certains historiens, la production y fut maintenue ou accrue et la liberté laissée aux paysans qui ne souhaitaient pas s'y joindre, mais l'expérience reste débattue, inégale selon les lieux et traversée par des contraintes locales et par le contexte militaire<ref>Pelletier, ''L'Anarchisme'', « Gestion directe et collectivisation en Espagne » ; Préposiet, Jean, ''Histoire de l'anarchisme'', Paris, Tallandier, 2002, « L'Espagne et le collectivisme libertaire » ; sur les collectivités, Peirats, José, ''La CNT dans la Révolution espagnole'', Paris, Spartacus, 1975.</ref>. Ces collectivités furent en partie détruites en août 1937 par une colonne envoyée par les communistes espagnols, puis disparurent avec la victoire franquiste de 1939.
== Anarchisme écologique et dimensions contemporaines ==
L'anarchisme a joué un rôle dans la formation de la pensée environnementale moderne<ref>Jourdain, Edouard, ''Géopolitique de l'anarchisme. Vers un nouveau moment libertaire'', Paris, Le Cavalier Bleu, 2023, « Lutter contre le capitalisme pour préserver le monde : anarchisme et écologie » ; Purchase, Graham, ''Anarchism and Environmental Survival'', Tucson, See Sharp Press, 1994.</ref>. L'anarchisme écologique établit un lien entre la domination exercée sur le monde naturel et la domination sociale des humains les uns par les autres ; il conteste les formes institutionnelles et réformistes de l'environnementalisme, jugées trop étroitement centrées sur l'humain, et envisage une relation harmonieuse entre les humains et la nature, favorisée par des techniques non polluantes et des pratiques à échelle humaine.
=== Une généalogie libertaire de l'écologie ===
[[Fichier:Élisée Reclus, by Nadar.jpg|vignette|redresse|Élisée Reclus (1830-1905), géographe libertaire. Sa « mésologie », étude des milieux, en fait un précurseur d'une écologie d'inspiration anarchiste.]]
À côté de Thoreau et avant Bookchin, la tradition anarchiste possède aussi une généalogie écologique propre, notamment francophone. Élisée Reclus, géographe libertaire, développa la notion de « mésologie » comme étude des milieux où interagissent une multitude de sujets, dont la société<ref>Sur Reclus, voir Ferretti, Federico, ''Élisée Reclus, pour une géographie nouvelle'', Paris, Éditions du CTHS, 2014 ; Vincent, Jean-Didier, ''Élisée Reclus. Géographe, anarchiste, écologiste'', Paris, Robert Laffont, 2010.</ref>. Il tenait l'homme pour un élément d'un tout équilibré, écrivant que « l'homme est la nature prenant conscience d'elle-même »<ref>Reclus, Élisée, ''L'Homme et la Terre'', Paris, Librairie universelle, 1905.</ref>, et il déduisait de l'observation de cet équilibre que le capitalisme et le productivisme sont dommageables à la fois à la nature et à l'homme. Kropotkine, scientifique de formation, voyait pour sa part dans la nature un exemple pour la morale humaine : contre les darwinistes sociaux, il soutenait que c'est par la coopération que l'adaptation aux milieux est rendue possible<ref>Kropotkin, ''Mutual Aid''.</ref>. Ces analyses inspirèrent les urbanistes Ebenezer Howard et Patrick Geddes, dont les cités-jardins, intégrant le meilleur de la ville et de la campagne, devaient s'associer en confédérations<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Lutter contre le capitalisme pour préserver le monde ».</ref>.
Cette sensibilité s'incarna aussi dans des pratiques : le courant naturien, apparu à Paris en 1894, et des colonies rurales comme le milieu libre de Vaux (1902-1905) tentèrent une vie « dans la nature » que Serge Latouche rapproche du mouvement pour la décroissance<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Lutter contre le capitalisme pour préserver le monde ».</ref>.
=== Écologie sociale et primitivisme ===
[[Fichier:Benjamin D. Maxham - Henry David Thoreau - Restored.jpg|vignette|gauche|redresse|Henry David Thoreau (1817-1862) en 1856. Sa vie « dans les bois » à Walden et son éloge de la désobéissance civile nourrissent la sensibilité libertaire et écologique.]]
Henry David Thoreau (1817-1862), écrivain, naturaliste et transcendantaliste américain, exerça une influence durable sur la pensée environnementale<ref>Thoreau, Henry David, "La Désobéissance civile" (1849), in ''Désobéir'', Paris, Mille et Une Nuits, 1994, p. 7-35.</ref>. Sceptique à l'égard du gouvernement, surtout dans la mesure où celui-ci imposait l'esclavage et menait la guerre, il écrivait : « J'accepte de tout cœur la devise : "Ce gouvernement est le meilleur qui gouverne le moins" », ajoutant qu'il croyait aussi que « ce gouvernement est le meilleur qui ne gouverne pas du tout »<ref>Thoreau, Henry David, "Resistance to Civil Government", in ''Aesthetic Papers'', Boston, 1849, p. 189.</ref>. À Walden Pond, il trouva dans le monde naturel l'inspiration d'une éthique faite de compassion pour les animaux, de respect du sauvage, d'attachement au lieu et de vie simple et autosuffisante<ref>Thoreau, Henry David, ''Walden; or, Life in the Woods'', Boston, Ticknor and Fields, 1854, p. 1-23.</ref>. Plutôt qu'un anarchiste au sens strict, il représente une racine américaine de la pensée libertaire et écologique.
[[Fichier:Murray Bookchin (cropped).jpg|vignette|redresse|Murray Bookchin (1921-2006), théoricien de l'écologie sociale, pour qui les désordres écologiques s'enracinent dans les hiérarchies sociales.]]
Murray Bookchin (1921-2006), influencé par Kropotkine, maria la philosophie anarchiste aux préoccupations environnementales en développant l'écologie sociale<ref>Bookchin, Murray, ''The Ecology of Freedom: The Emergence and Dissolution of Hierarchy'', Palo Alto, Cheshire Books, 1982, p. 1-43.</ref>. Il soutenait que les problèmes écologiques prennent leur origine dans la sphère sociale, et en particulier dans les systèmes politiques hiérarchiques<ref>Bookchin, Murray, "Ecology and Revolutionary Thought" (1965), in ''Post-Scarcity Anarchism'', Berkeley, Ramparts Press, 1971, p. 57-82.</ref>. Le problème, selon lui, n'est pas la ville en elle-même, mais l'urbanisation capitaliste, qui entraîne une surexploitation conjointe de la nature et de l'homme ; à la domination, y compris sur la nature, il opposait une coopération de communautés organisées par le municipalisme libertaire<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Lutter contre le capitalisme pour préserver le monde ».</ref>. Vers la fin de sa vie, Bookchin se montra critique de l'anarchisme et se décrivit comme communaliste<ref>Bookchin, Murray, ''Social Anarchism or Lifestyle Anarchism: An Unbridgeable Chasm'', Oakland, AK Press, 1995, p. 1-35.</ref>. D'autres auteurs américains s'inscrivent dans cette tradition, dont l'historien Lewis Mumford, le poète Gary Snyder, le théoricien John Clark, qui insiste sur un imaginaire de la région, l'écrivain Edward Abbey et le critique de la technique David Watson<ref>Clark, John P., ''The Anarchist Moment: Reflections on Culture, Nature and Power'', Montréal, Black Rose Books, 1984, p. 123-156.</ref>.
L'anarcho-primitivisme constitue une variante plus contestée. Il oppose une critique écologique et politique aux origines mêmes de la civilisation, dont il dénonce les effets supposés : technologie, agriculture, domestication, croissance démographique, division du travail<ref>Zerzan, John, ''Elements of Refusal'', Seattle, Left Bank Books, 1988, p. 67-94.</ref>. John Zerzan fait remonter cette rupture à l'avènement du langage symbolique, des nombres et de l'agriculture, et soutient que l'on ne peut échapper à l'aliénation que par la multiplication de petits groupes affinitaires<ref>Zerzan, John, "Language: Origin and Meaning", in ''Future Primitive and Other Essays'', Brooklyn, Autonomedia, 1994, p. 23-51.</ref>. Jourdain observe que ce courant, oscillant entre le mythe du bon sauvage et des thèmes apocalyptiques, est loin de faire l'unanimité dans le mouvement<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Lutter contre le capitalisme pour préserver le monde ».</ref>. Une question voisine traverse la collapsologie, courant des années 2010 dont l'un des promoteurs, Pablo Servigne, est proche du mouvement anarchiste, et qui postule l'effondrement prochain de la civilisation industrielle<ref>Servigne, Pablo et Raphaël Stevens, ''Comment tout peut s'effondrer. Petit manuel de collapsologie à l'usage des générations présentes'', Paris, Seuil, 2015.</ref>. Cette perspective est critiquée, dans le mouvement anarchiste comme à l'extérieur, pour sa dépolitisation et son déterminisme<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Lutter contre le capitalisme pour préserver le monde » ; Charbonnier, Pierre, « Splendeurs et misères de la collapsologie. Les impensés du survivalisme de gauche », ''Revue du Crieur'', n° 13, 2019, p. 88-95.</ref>.
=== Communs et biorégionalisme ===
La réflexion contemporaine sur les communs prolonge cette tradition. Les communs désignent des ressources gérées par une communauté qui se donne des règles pour les préserver, hors de l'État comme du marché ; la clôture des communaux médiévaux par les propriétaires et l'État accompagne, selon cette lecture, la naissance du capitalisme<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Lutter contre le capitalisme pour préserver le monde ».</ref>. Le fonctionnement de ces communs a été documenté par l'économiste Elinor Ostrom<ref>Ostrom, Elinor, ''Governing the Commons: The Evolution of Institutions for Collective Action'', Cambridge, Cambridge University Press, 1990.</ref>, et l'on en trouve des exemples dans les ''acequias'', systèmes de cours d'eau gérés collectivement au Nouveau-Mexique depuis le XVIIe siècle, ou dans le « Parc de la pomme de terre » au Pérou, où des communautés indigènes préservent collectivement des centaines de variétés. Le biorégionalisme, forgé par Peter Berg et développé par Kirkpatrick Sale autour de la notion d'échelle humaine, conçoit la biorégion comme un espace où une population vit en symbiose avec son milieu<ref>Sale, Kirkpatrick, ''Dwellers in the Land: The Bioregional Vision'', San Francisco, Sierra Club Books, 1985.</ref> ; il valorise à ce titre les savoirs des populations autochtones, comme le font les travaux des anthropologues James Scott et David Graeber<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Lutter contre le capitalisme pour préserver le monde ».</ref>.
Les critiques de l'anarchisme écologique relèvent son penchant pour des visions idéalisées de la nature et de la nature humaine, son opposition à toute forme d'État centralisé, que certains jugent nécessaire pour traiter les problèmes écologiques à grande échelle, et son recours à des formes d'organisation décentralisées, jugées peu efficaces par ses adversaires. Les éco-anarchistes répondent que l'urgence des crises écologiques appelle des transformations éthiques et sociales de fond, et que la gestion par les communs se révèle souvent plus respectueuse de l'environnement que celle de l'État ou du marché.
== Héritages et pertinence contemporaine ==
L'anarchisme a exercé une influence précoce sur le mouvement environnemental. Par l'ampleur de ses analyses, il met en cause toute sous-estimation de la gravité de la crise environnementale et de l'étendue des mesures qu'elle appelle.
Au-delà de ce domaine, l'anarchisme demeure une critique des structures de pouvoir et de domination. Ses thèmes, opposition à l'autoritarisme, autonomie individuelle et collective, coopération volontaire et entraide, continuent d'inspirer des mouvements sociaux. Des Indignés espagnols au mouvement Occupy Wall Street, des protestations étudiantes québécoises de 2012 aux soulèvements ouverts par le Printemps arabe à la fin de 2010, on observe une résurgence de principes anarchistes : auto-organisation, association volontaire, démocratie directe, action collective non hiérarchique<ref>Graeber, David, ''The Democracy Project: A History, a Crisis, a Movement'', New York, Spiegel & Grau, 2013, p. 67-102.</ref>. Jourdain ajoute à ce panorama des expériences territoriales plus durables, des municipalités zapatistes du Chiapas à l'administration autonome du Rojava, où des principes confédéraux et autogestionnaires sont mis en œuvre<ref>Jourdain, ''Géopolitique de l'anarchisme'', « Au cœur des conflits » et conclusion.</ref>.
Comme l'observent David Graeber et Andrej Grubačić, le mouvement révolutionnaire mondial au XXIe siècle s'apparente davantage à la tradition de l'anarchisme qu'à celle du marxisme, avec une génération « beaucoup plus intéressée à développer de nouvelles formes de pratique qu'à débattre des points les plus fins de l'idéologie »<ref>Graeber, David et Andrej Grubačić, "Anarchism, or the Revolutionary Movement of the Twenty-first Century", ''ZNet'', 2004.</ref>. L'anarchisme contemporain se caractérise par son rejet du sectarisme et de l'avant-gardisme, par son internationalisme, sa décentralisation et sa démocratie directe. Il met l'accent sur la politique préfigurative, l'idée que les moyens doivent correspondre aux fins et que les formes d'organisation du présent doivent incarner les valeurs de la société visée<ref>Franks, Benjamin, "Prefiguration", in ''The Palgrave Handbook of Anarchism'', Carl Levy et Matthew S. Adams (éds.), Cham, Palgrave Macmillan, 2019, p. 1-17.</ref>. Sa critique de l'autorité politique a en outre nourri des débats sur la légitimité de l'État qui occupent les philosophes politiques contemporains : l'anarchisme philosophique, distinct de l'anarchisme politique, soutient qu'il n'existe pas d'autorité politique légitime, sans pour autant préconiser l'abolition immédiate de l'État<ref>Simmons, A. John, ''Moral Principles and Political Obligations'', Princeton, Princeton University Press, 1979, p. 192-216.</ref>.
== Débats et objections ==
[[Fichier:Russell in 1916.jpg|vignette|gauche|redresse|Bertrand Russell (1872-1970) en 1916. Favorable à l'anarchisme intégral comme but, il le tient pour inapplicable dans l'immédiat et propose le ''guild socialism'' comme compromis.]]
Les objections adressées à l'anarchisme ne relèvent pas toutes du rejet caricatural ; certaines, formulées par des auteurs attentifs, appellent des réponses précises.
La première porte sur la faisabilité. Bertrand Russell, qui tient l'anarchisme intégral pour l'objectif final souhaitable, le juge néanmoins « pour le moment irréalisable » et estime qu'il « ne survivrait pas au-delà d'un an ou deux à sa mise en application »<ref>Russell, ''Le monde qui pourrait être'', introduction.</ref>. Il craint qu'un anarcho-syndicalisme privé d'État ne doive réédifier une autorité centrale pour arbitrer les rivalités entre groupes de producteurs, et propose comme compromis le ''guild socialism'', qui associe la défiance libertaire envers l'État et l'exigence de coordination par un fédéralisme entre professions<ref>Russell, ''Le monde qui pourrait être'', introduction et deuxième partie.</ref>. Les anarchistes répondent généralement que l'anarchisme n'est pas une utopie sans assise : Guérin écrit qu'il rejette l'accusation d'utopie et se veut constructif, et les collectivisations agraires d'Aragon en 1936-1937 en offrent une réalisation concrète, quoique brève et débattue<ref>Guérin, ''L'anarchisme'', chapitre « L'anarchisme n'est pas utopique » ; Pelletier, ''L'Anarchisme'', « Gestion directe et collectivisation en Espagne ».</ref>.
La deuxième objection concerne la nature humaine. Russell observe que le respect de la liberté d'autrui n'est pas un instinct naturel et qu'en l'absence de tout frein le fort opprimerait le faible, la majorité la minorité, ou les partisans de la violence les plus pacifiques<ref>Russell, ''Le monde qui pourrait être'', chapitre « Gouvernement et lois ».</ref>. Il en conclut qu'une forme limitée de gouvernement et de législation demeure nécessaire, tout en restant un mal que l'on doit réduire autant que possible. La romancière Ursula Le Guin met en scène une difficulté voisine dans ''Les Dépossédés'' (1974) : sur une planète anarchiste, l'absence de lois se paie d'une conformité sociale qui érode la sphère privée. Jourdain en tire que la plupart des anarchistes admettent le caractère inévitable des règles et des pouvoirs, l'enjeu étant d'établir des rapports de force équilibrés, contrôlables et révocables, et de préserver l'autonomie individuelle en équilibre avec le collectif<ref>Jourdain, ''Géopolitique de l'anarchisme'', conclusion.</ref>.
La troisième objection, formulée par Robert Michels dans ''Les Partis politiques'' (1911), tient à la loi d'airain de l'oligarchie : toute organisation, parti ou syndicat, tend à se diviser en minorité dirigeante et majorité dirigée, les représentants finissant par s'affranchir du contrôle de la base. Préposiet observe que Michels, sans être anarchiste, rejoint ainsi la critique libertaire de la représentation, qu'il appuie sur une citation de Proudhon, mais que la portée de cette loi vaut aussi comme question adressée à l'anarchisme : les fédérations libertaires échappent-elles à la cristallisation d'une couche dirigeante<ref>Préposiet, ''Histoire de l'anarchisme'', « Un écueil. La loi d'airain de l'oligarchie ».</ref> ? Les anarchistes y répondent par le mandat impératif, limité et révocable, et par la décision prise collectivement plutôt que déléguée<ref>Pelletier, ''L'Anarchisme'', « L'anarchisme est contre la démocratie ».</ref>.
La quatrième touche au pluralisme des valeurs et au recours à l'opinion publique. Godwin et Kropotkine comptaient sur l'opinion pour dissuader les abus en l'absence de coercition. George Orwell objecte que cette dépendance pourrait conduire à une tyrannie morale qui, faute de limites codifiées, se révélerait plus oppressive que tout système de lois<ref>Orwell, George, "Réflexions sur Gandhi", in ''Essais, articles, lettres'', tome IV, Paris, Ivrea-Encyclopédie des Nuisances, 1995, p. 539-548.</ref>.
Reste la question de la défense collective : une société sans commandement centralisé peut peiner à résister à une agression organisée, comme le suggère l'écrasement militaire des expériences libertaires.
Ces objections n'épuisent pas le débat, mais elles indiquent les difficultés auxquelles le projet anarchiste doit répondre. L'anarchisme contemporain les aborde par l'expérimentation pratique, la réflexion critique et le dialogue avec d'autres traditions, plutôt que par la proclamation d'une cité idéale. Par sa critique de l'autorité, son insistance sur l'autonomie et la coopération volontaire et sa conception d'une organisation sans domination, il demeure une référence dans les débats sur le pouvoir, la liberté et la justice sociale.
== Notes et références ==
{{references|colonnes=2}}
== Bibliographie ==
=== Sources primaires ===
* Bakunin, Michel, ''Dieu et l'État'', Genève, 1882 ; réédition Paris, Maspero, 1976
* Bakunin, Michel, ''Étatisme et anarchie'', édition française établie par Renée Lamberet, Paris, Champ libre, 1976
* Bakunin, Michel, ''Œuvres complètes'', édition établie par Arthur Lehning, 8 volumes, Paris, Champ libre, 1973-1982
* Bookchin, Murray, ''Post-Scarcity Anarchism'', Berkeley, Ramparts Press, 1971
* Bookchin, Murray, ''The Ecology of Freedom: The Emergence and Dissolution of Hierarchy'', Palo Alto, Cheshire Books, 1982
* Bookchin, Murray, ''Social Anarchism or Lifestyle Anarchism: An Unbridgeable Chasm'', Oakland, AK Press, 1995
* Godwin, William, ''An Enquiry Concerning Political Justice, and its Influence on General Virtue and Happiness'', Londres, G.G.J. et J. Robinson, 1793, 2 volumes
* Kropotkin, Pierre, ''La Conquête du pain'', Paris, Tresse et Stock, 1892
* Kropotkin, Pierre, ''Mutual Aid: A Factor of Evolution'', Londres, William Heinemann, 1902
* Kropotkin, Pierre, ''L'Éthique'', ouvrage posthume, 1922 ; traduction française Paris, Stock, 1979
* Kropotkin, Pierre, ''Fields, Factories and Workshops'', Londres, Thomas Nelson and Sons, 1899
* Pouget, Émile, ''Le Sabotage'', Paris, Marcel Rivière, 1910
* Proudhon, Pierre-Joseph, ''Qu'est-ce que la propriété ? ou Recherche sur le principe du Droit et du Gouvernement'', Paris, J.-F. Brocard, 1840
* Proudhon, Pierre-Joseph, ''Du Principe fédératif et de la nécessité de reconstituer le parti de la révolution'', Paris, E. Dentu, 1863
* Proudhon, Pierre-Joseph, ''De la capacité politique des classes ouvrières'', Paris, E. Dentu, 1865
* Proudhon, Pierre-Joseph, ''Théorie de la propriété'', Paris, Lacroix et Verboeckhoven, 1866
* Reclus, Élisée, ''L'Homme et la Terre'', Paris, Librairie universelle, 1905, 6 volumes
* Rocker, Rudolf, ''Anarcho-Syndicalism: Theory and Practice'', Oakland, AK Press, 2004 (édition originale 1938)
* Russell, Bertrand, ''Le monde qui pourrait être. Socialisme, anarchisme et anarcho-syndicalisme'', Montréal, Lux, 2014 (rééd. 2025) ; édition originale ''Proposed Roads to Freedom'', 1918
* Sale, Kirkpatrick, ''Dwellers in the Land: The Bioregional Vision'', San Francisco, Sierra Club Books, 1985
* Servigne, Pablo et Raphaël Stevens, ''Comment tout peut s'effondrer. Petit manuel de collapsologie à l'usage des générations présentes'', Paris, Seuil, 2015
* Sorel, Georges, ''Réflexions sur la violence'', Paris, Marcel Rivière, 1908
* Stirner, Max, ''Der Einzige und sein Eigentum'', Leipzig, Otto Wigand, 1844
* Thoreau, Henry David, "Resistance to Civil Government", in ''Aesthetic Papers'', Boston, 1849
* Thoreau, Henry David, ''Walden; or, Life in the Woods'', Boston, Ticknor and Fields, 1854
* Voline, ''La Révolution inconnue'', Paris, 1947
* Zerzan, John, ''Elements of Refusal'', Seattle, Left Bank Books, 1988
* Zerzan, John, ''Future Primitive and Other Essays'', Brooklyn, Autonomedia, 1994
=== Études critiques et historiques ===
* Carr, E. H., ''Michael Bakunin'', Londres, Macmillan, 1937
* Charbonnier, Pierre, « Splendeurs et misères de la collapsologie. Les impensés du survivalisme de gauche », ''Revue du Crieur'', n° 13, La Découverte, 2019, p. 88-95
* Clark, John P., ''Max Stirner's Egoism'', Londres, Freedom Press, 1976
* Clark, John P., ''The Anarchist Moment: Reflections on Culture, Nature and Power'', Montréal, Black Rose Books, 1984
* Ferretti, Federico, ''Élisée Reclus, pour une géographie nouvelle'', Paris, Éditions du CTHS, 2014
* Fiala, Andrew, "Anarchism", in ''The Stanford Encyclopedia of Philosophy'', Edward N. Zalta (éd.), Stanford University, 2017
* Franks, Benjamin, "Prefiguration", in ''The Palgrave Handbook of Anarchism'', Carl Levy et Matthew S. Adams (éds.), Cham, Palgrave Macmillan, 2019
* Graeber, David, ''The Democracy Project: A History, a Crisis, a Movement'', New York, Spiegel & Grau, 2013
* Graeber, David et Andrej Grubačić, "Anarchism, or the Revolutionary Movement of the Twenty-first Century", ''ZNet'', 2004
* Guérin, Daniel, ''L'anarchisme. De la doctrine à la pratique'', suivi de ''Anarchisme et marxisme'', Paris, Gallimard, 1981 (première édition 1965)
* Guérin, Daniel, ''Ni Dieu ni Maître. Anthologie de l'anarchisme'', Paris, Maspero, 1970
* Guérin, Daniel, ''Anarchism: From Theory to Practice'', New York, Monthly Review Press, 1970
* Jourdain, Edouard, ''Géopolitique de l'anarchisme. Vers un nouveau moment libertaire'', Paris, Le Cavalier Bleu, 2023
* Julliard, Jacques, ''Fernand Pelloutier et les origines du syndicalisme d'action directe'', Paris, Éditions du Seuil, 1971
* Jun, Nathan J., ''Anarchism and Political Modernity'', New York, Continuum, 2012
* Marshall, Peter, ''Demanding the Impossible: A History of Anarchism'', Londres, Fontana Press, 1993
* McLaughlin, Paul, ''Anarchism and Authority: A Philosophical Introduction to Classical Anarchism'', Aldershot, Ashgate, 2007
* Orwell, George, "Réflexions sur Gandhi", in ''Essais, articles, lettres'', tome IV, Paris, Ivrea-Encyclopédie des Nuisances, 1995
* Ostrom, Elinor, ''Governing the Commons: The Evolution of Institutions for Collective Action'', Cambridge, Cambridge University Press, 1990
* Paterson, Ronald William Keith, ''The Nihilistic Egoist: Max Stirner'', Oxford, Oxford University Press, 1971
* Peirats, José, ''La CNT dans la Révolution espagnole'', Paris, Spartacus, 1975
* Pelletier, Philippe, ''L'Anarchisme'', Paris, Le Cavalier Bleu, coll. « Idées reçues », 2010
* Philp, Mark, ''Godwin's Political Justice'', Londres, Duckworth, 1986
* Préposiet, Jean, ''Histoire de l'anarchisme'', Paris, Tallandier, 2002
* Purchase, Graham, ''Anarchism and Environmental Survival'', Tucson, See Sharp Press, 1994
* Saltman, Richard B., ''The Social and Political Thought of Michael Bakunin'', Westport, Greenwood Press, 1983
* Simmons, A. John, ''Moral Principles and Political Obligations'', Princeton, Princeton University Press, 1979
* Todes, Daniel P., ''Darwin without Malthus: The Struggle for Existence in Russian Evolutionary Thought'', Oxford, Oxford University Press, 1989
* van der Linden, Marcel et Wayne Thorpe (éds.), ''Revolutionary Syndicalism: An International Perspective'', Aldershot, Scolar Press, 1990
* Vincent, Jean-Didier, ''Élisée Reclus. Géographe, anarchiste, écologiste'', Paris, Robert Laffont, 2010 (Prix Femina essai 2010)
* Vincent, K. Steven, ''Pierre-Joseph Proudhon and the Rise of French Republican Socialism'', Oxford, Oxford University Press, 1984
* Wolff, Robert Paul, ''In Defense of Anarchism'', New York, Harper & Row, 1970
* Woodcock, George, ''L'Anarchisme. Une histoire des idées et mouvements libertaires'', Montréal, Lux, 2019 (édition originale ''Anarchism: A History of Libertarian Ideas and Movements'', 1962)
== Liens externes ==
* [https://plato.stanford.edu/entries/anarchism/ Anarchism - Stanford Encyclopedia of Philosophy]
* [https://www.marxists.org/subject/anarchism/ Anarchism Archive]
[[Catégorie:Philosophie politique]]
{{Autocat}}
16wwwjrlw34zd8br03y7cny87wisymm
Discussion Wikilivres:Le Bistro/2026
5
83406
767795
767586
2026-06-15T16:48:35Z
MediaWiki message delivery
36013
/* Actualités techniques n° 2026-25 */ nouvelle section
767795
wikitext
text/x-wiki
== Actualités techniques n° 2026-03 ==
<section begin="technews-2026-W03"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/03|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* La Fondation Wikimedia a publié des questions directrices pour son plan annuel de juillet 2026 à juin 2027 sur les plateformes [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2026-2027/Product & Technology OKRs|Meta]] et ''[[diffblog:2025/12/10/shaping-wikimedia-foundations-2026-2027-annual-goals-key-questions-for-the-wikimedia-movement/|Diff]]''. Celles-ci portent sur les tendances mondiales, une expérimentation plus rapide et plus constructive, un meilleur accompagnement des nouveaux contributeurs, le renforcement du rôle des éditeurs et des utilisateurs avancés, l'amélioration de la collaboration entre les projets, ainsi que le développement et la fidélisation du lectorat. Des commentaires et suggestions sont les bienvenus sur la [[m:Talk:Wikimedia Foundation Annual Plan/2026-2027|page de discussion]].
'''Actualités pour la contribution'''
* Dans le cadre des travaux en cours de l'équipe technique communautaire sur le projet [[m:Special:MyLanguage/Community Wishlist/W372|Listes de surveillance multiples]], l'affichage de [[Special:EditWatchlist|Modifier la liste de surveillance]] sera mis à jour entant que qu'une première étape vers la prise en charge de plusieurs listes de surveillance. De plus, la pagination de [[Special:Search|Recherche]] sera également mise à jour, dans le cadre du travail sur le souhait [[m:Special:MyLanguage/Community Wishlist/W186|Refonte de la pagination / navigation des pages]]. [https://phabricator.wikimedia.org/T411596]
* [[m:Special:GlobalWatchlist|La Liste de Surveillance Globale]] est une [[mw:Special:MyLanguage/Extension:GlobalWatchlist|extension]] de MediaWiki qui vous permet de voir vos listes de surveillance provenant de différents wikis sur la même page. Il a récemment été mis à jour pour ressembler davantage à la [[Special:Watchlist|Liste de surveillance]] régulière, par exemple en le préparant pour les comptes temporaires dans le masquage IP (y compris le réacheminement des liens des utilisateurs vers les pages de contributions), en mettant les titres de page en gras et en ouvrant les liens dans les résumés d'édition et les balises dans de nouveaux onglets du navigateur. [https://phabricator.wikimedia.org/T398361][https://phabricator.wikimedia.org/T298919][https://phabricator.wikimedia.org/T273526][https://phabricator.wikimedia.org/T286309]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:28|la tâche soumise|les {{formatnum:28}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:28||s}} la semaine dernière]]. Par exemple, le problème selon lequel les blocs globaux ne disposaient pas de l'option permettant de désactiver l'envoi d'e-mails a maintenant été résolu et sera disponible à l'utilisation à partir de la semaine du 13 janvier. [https://phabricator.wikimedia.org/T401293]
'''Actualités pour la contribution technique'''
* L'[[mw:Special:MyLanguage/VisualEditor/Citation tool|outil de citation VisualEditor]] et les [[mw:Special:MyLanguage/Help:Reference Previews|Aperçus de référence]] prennent désormais en charge "carte" comme type de référence. [https://phabricator.wikimedia.org/T411083]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.10|MediaWiki]]/[[mw:MediaWiki 1.46/wmf.11|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/03|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W03"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 12 janvier 2026 à 20:33 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=29907192 -->
== Thank You for Last Year – Join Wiki Loves Ramadan 2026 ==
Dear Wikimedia communities,
We hope you are doing well, and we wish you a happy New Year.
''Last year, we captured light. This year, we’ll capture legacy.''
In 2025, communities around the world shared the glow of Ramadan nights and the warmth of collective iftars. In 2026, ''Wiki Loves Ramadan'' is expanding, bringing more stories, more cultures, and deeper global connections across Wikimedia projects.
We invite you to explore the ''Wiki Loves Ramadan 2026'' [[m:Special:MyLanguage/Wiki Loves Ramadan 2026|Meta page]] to learn how you can participate and [[m:Special:MyLanguage/Wiki Loves Ramadan 2026/Participating communities|sign up]] your community.
📷 ''Photo campaign on '' [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan 2026|Wikimedia Commons]]
If you have questions about the project, please refer to the FAQs:
* [[m:Special:MyLanguage/Wiki Loves Ramadan/FAQ/|Meta-Wiki]]
* [[c:Special:MyLanguage/Commons:Wiki Loves Ramadan/FAQ|Wikimedia Commons]]
''Early registration for updates is now open via the '''[[m:Special:RegisterForEvent/2710|Event page]]'''''
''Stay connected and receive updates:''
* [https://t.me/WikiLovesRamadan Telegram channel]
* [https://lists.wikimedia.org/postorius/lists/wikilovesramadan.lists.wikimedia.org/ Mailing list]
We look forward to collaborating with you and your community.
'''The Wiki Loves Ramadan 2026 Organizing Team''' 16 janvier 2026 à 20:44 (CET)
<!-- Message envoyé par User:ZI Jony@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29879549 -->
== <span lang="en" dir="ltr">Tech News: 2026-04</span> ==
<div lang="en" dir="ltr">
<section begin="technews-2026-W04"/><div class="plainlinks">
Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/04|Translations]] are available.
'''Updates for editors'''
* The tray shown on [[Special:Diff|Special:Diff]] in mobile view has been redesigned. It is now collapsed by default, and incorporates a link to undo the edit being viewed, making it easier for mobile editors and reviewers to take action while keeping the interface uncluttered. [https://phabricator.wikimedia.org/T402297]
* [[m:Special:GlobalWatchlist|The Global Watchlist]] lets you view your watchlists from multiple wikis on one page. The [[mw:Special:MyLanguage/Extension:GlobalWatchlist|extension]] continues to improve — it now automatically determines the text direction (ensuring correct display of sites with unusual domain names) and shows detailed descriptions for log actions. Later this week, a new permanent link for page creations and CSS classes for each entry element will be added. [https://phabricator.wikimedia.org/T412505][https://phabricator.wikimedia.org/T287929][https://phabricator.wikimedia.org/T262768][https://phabricator.wikimedia.org/T414135]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:32}} community-submitted {{PLURAL:32|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the previously observed issue in Vector 2022, where anchor link targets were obscured by the sticky header, has now been addressed. [https://phabricator.wikimedia.org/T406114]
'''Updates for technical contributors'''
* As mentioned in the [[m:Special:MyLanguage/Tech/News/2025/44|October 2025 deprecation announcement]], MediaWiki Interfaces team will begin sunsetting all transform endpoints containing a trailing slash from the MediaWiki REST API the week of January 26. Changes are expected to roll out to all wikis on or before January 30th. All API users currently calling them are encouraged to transition to the non-trailing slash versions. Both endpoint variations can be found, compared, and tested using the [https://test.wikipedia.org/wiki/Special:RestSandbox REST Sandbox]. If you have questions or encounter any problems, please file a ticket in Phabricator to the [https://phabricator.wikimedia.org/project/view/6931/ #MW-Interfaces-Team board].
* Interactive reference documentation for the [[mw:Special:MyLanguage/Wikimedia REST API|Wikimedia REST API]] has moved. Requests to API docs previously hosted through [[mw:Special:MyLanguage/RESTBase|RESTBase]] (e.g.: <code dir=ltr>https://en.wikipedia.org/api/rest_v1/</code>) are now redirected to the [[w:en:Special:RestSandbox|REST Sandbox]].
* The [[mw:Special:MyLanguage/Wikidata Platform|WMF Wikidata Platform team]] (WDP) has published its [[d:Special:MyLanguage/Wikidata:Wikidata Platform team/Newsletter|January 2026 newsletter]]. It includes updates on the legacy full-graph endpoint decommissioning, the User-Agent policy change, the monthly Blazegraph migration office hours, and efforts to reduce regressions caused by the legacy endpoint shutdown. As a reminder, you can [[m:Special:MyLanguage/Global message delivery/Targets/WDP team updates|subscribe to the WDP newsletter]]!
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.12|MediaWiki]]
'''Meetings and events'''
* The [[mw:Wikimedia Hackathon Northwestern Europe 2026|Wikimedia Hackathon Northwestern Europe 2026]] will take place on 13-14 March 2026 in Arnhem, the Netherlands. Applications opened mid-December and will close soon or when capacity is reached. It's a two-day, technically oriented hackathon bringing together Wikimedians from the region. Hope to see you there!
'''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]] • [[m:Special:MyLanguage/Tech/News#contribute|Contribute]] • [[m:Special:MyLanguage/Tech/News/2026/04|Translate]] • [[m:Tech|Get help]] • [[m:Talk:Tech/News|Give feedback]] • [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].''
</div><section end="technews-2026-W04"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 19 janvier 2026 à 21:29 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=29943403 -->
== Révision annuelle du code universel de conduite et des lignes directrices de l'application ==
<section begin="announcement-content" />
Nous vous informons que la période de relecture annuelle du Code de conduite universel et des règles d'applications est actuellement ouverte. Vous pouvez faire vos commentaires sur les modifications que vous souhaitez apporter jusqu'au 9 février 2026. C'est la première d'une série d'étapes nécessaires pour la révision annuelle. Vous trouverez [[m:Special:MyLanguage/Universal Code of Conduct/Annual review/2026|d'autres informations et les discussions auxquelles participer sur la page UCoC de Meta]].
Le [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee|Comité de coordination du code universel de conduite]] (U4C — Universal Code of Conduct Coordinating Committee) est un groupe global dont le rôle est de fournir une implémentation équitable et cohérente de l'UCoC. Cette relecture annuelle a été envisagée et mise en place par l'U4C. Pour plus d'informations et les responsabilités de l'U4C, veuillez lire la [[m:Special:MyLanguage/Universal Code of Conduct/Coordinating Committee/Charter|Charte de l'U4C]].
Veuillez partager ces informations avec les autres membres concernés de votre communauté.
-- En coopération avec l'U4C, [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|discussion]])<section end="announcement-content" />
19 janvier 2026 à 22:01 (CET)
<!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=29905753 -->
== Actualités techniques n° 2026-05 ==
<section begin="technews-2026-W05"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/05|D’autres traductions]] sont disponibles.
'''Actualités pour la contribution'''
* La Fondation Wikimedia invite à donner des commentaires sur [[m:Special:MyLanguage/Product and Technology Advisory Council/Year1 Reflections and Proposed Way Forward 2026 Update|l’avenir proposé]] du [[:m:Special:MyLanguage/Product and Technology Advisory Council|Conseil consultatif des produits et technologies]] jusqu’au 28 février.
* Tous les utilisateurs disposant d'un compte enregistré peuvent désormais utiliser des clés d'accès pour la [[m:Special:MyLanguage/Help:Two-factor authentication|double authentification]] (2FA). Les clés d'accès sont un moyen simple de se connecter sans utiliser un second appareil. Elles vérifient l'identité de l'utilisateur à l'aide d'une empreinte digitale, d'une reconnaissance faciale ou d'un code PIN. Pour configurer une clé d'accès, configurez d'abord une méthode 2FA classique. Actuellement, pour se connecter avec une clé d'accès, les utilisateurs doivent également utiliser un mot de passe. Plus tard ce trimestre, la connexion sans mot de passe permettra aux utilisateurs de se connecter d'un simple clic avec une clé d'accès. Les utilisateurs disposant de droits avancés devront également avoir la 2FA activée. Cela fait partie du projet [[mw:Special:MyLanguage/Product Safety and Integrity/Account Security|Sécurité du compte]].
* Les contributeurs non enregistrés sur des IP bloquées ou des plages d'IP bloquées peuvent désormais interagir sur le wiki pour faire appel d'un blocage en créant un compte temporaire afin de contester un blocage sur la page de discussion de l'utilisateur, sauf si l'option « empêcher cet utilisateur de modifier sa propre page de discussion » est activée. Cela résout le problème des utilisateurs déconnectés incapables d'utiliser le processus de déblocage par défaut via la page de discussion de l'utilisateur. [https://phabricator.wikimedia.org/T398673]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:20|la tâche soumise|les {{formatnum:20}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:20||s}} la semaine dernière]]. Par exemple, la description des méthodes d'authentification à deux facteurs (2FA) sur la page de gestion a été mise à jour. Il est désormais plus clair et plus facile pour les utilisateurs à comprendre et à utiliser. [https://phabricator.wikimedia.org/T332385]
'''Actualités pour la contribution technique'''
* Une nouvelle variable AbuseFilter, <code>account_type</code>, a été ajoutée pour fournir un moyen fiable de déterminer le type de compte créé dans les actions <code>createaccount</code> et <code>autocreateaccount</code>. Dans le cadre de ce changement, la variable <code>accountname</code> a été renommée en <code>account_name</code>, et <code>accountname</code> est désormais obsolète. Les gestionnaires de filtres doivent mettre à jour tous les filtres qui utilisent des vérifications de type de compte codées en dur ou la variable obsolète. [https://phabricator.wikimedia.org/T414049]
* Les vignettes d'images demandées dans des tailles non standard, et en utilisant des méthodes non standard telles que les requêtes directes à <code dir=ltr><nowiki>upload.wikimedia.org/…</nowiki></code>, cesseront de fonctionner dans un proche avenir. Ce changement vise à prévenir les abus externes continus par des robots et des aspirateurs web. Certains utilisateurs ayant des CSS/JS personnalisés, les administrateurs d'interface qui peuvent corriger les gadgets et les thèmes locaux, ainsi que les auteurs d'outils, devront mettre à jour leur code pour utiliser des tailles de vignettes standard. [[phab:T414805|Des détails, des liens de recherche et des exemples de correction sont disponibles dans la tâche]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.13|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/05|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W05"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 26 janvier 2026 à 22:17 (CET)
<!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=29969530 -->
== <span lang="en" dir="ltr">Tech News: 2026-06</span> ==
<div lang="en" dir="ltr">
<section begin="technews-2026-W06"/><div class="plainlinks">
Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/06|Translations]] are available.
'''Updates for editors'''
* The "{{int:pageinfo-toolboxlink}}" feature, which gives validating information about a page ([{{fullurl:{{FULLPAGENAME}}|action=info}} example]), now automatically includes a table of contents. If there is a local [[{{ns:8}}:Pageinfo-header]] page created by individual users, it can now be removed. [https://phabricator.wikimedia.org/T363726]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:21}} community-submitted {{PLURAL:21|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, VisualEditor previously added bold or italic formatting inside link descriptions, making the wikicode complex. This has now been fixed. [https://phabricator.wikimedia.org/T409669]
'''Updates for technical contributors'''
* There was no XML dump on 20 January. Additionally, from now on, dumps will be generated once per month only. [https://phabricator.wikimedia.org/T414389]
* The MediaWiki Interfaces team removed support for all transform endpoints containing a trailing slash from the [https://www.mediawiki.org/wiki/Special:MyLanguage/API:REST%20API MediaWiki REST API]. All API users currently calling those endpoints are encouraged to transition to the non-trailing slash versions. If you have questions or encounter any problems, please file a ticket in phabricator to the [https://phabricator.wikimedia.org/project/view/6931/ #MW-Interfaces-Team board].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.14|MediaWiki]]
'''Weekly highlight'''
* Users are reminded that the Wikimedia Foundation has shared some guiding questions for the July 2026–June 2027 Annual Plan on [[m:Special:MyLanguage/Wikimedia Foundation Annual Plan/2026-2027/Product & Technology OKRs|Meta]] and ''[[diffblog:2025/12/10/shaping-wikimedia-foundations-2026-2027-annual-goals-key-questions-for-the-wikimedia-movement/|Diff]]''. These focus on global trends, faster and healthier experimentation, better support for newcomers, strengthening editors and advanced users, improving collaboration across projects, and growing and retaining readership. Feedback and ideas are welcome on the [[m:Talk:Wikimedia Foundation Annual Plan/2026-2027|talk page]].
'''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]] • [[m:Special:MyLanguage/Tech/News#contribute|Contribute]] • [[m:Special:MyLanguage/Tech/News/2026/06|Translate]] • [[m:Tech|Get help]] • [[m:Talk:Tech/News|Give feedback]] • [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].''
</div><section end="technews-2026-W06"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 2 février 2026 à 18:43 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30000986 -->
== Actualités techniques n° 2026-07 ==
<section begin="technews-2026-W07"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/07|D’autres traductions]] sont disponibles.
'''Actualités pour la contribution'''
* [[File:Maki-gift-15.svg|12px|link=|class=skin-invert|Concerne un souhait]] Les contributeurs connectés qui gèrent de grandes ou complexes listes de suivi peuvent désormais organiser et filtrer les pages surveillées de manière à améliorer leurs flux de travail grâce à la nouvelle fonctionnalité [[mw:Special:MyLanguage/Help:Watchlist labels|Étiquettes de liste de suivi]]. En ajoutant des étiquettes personnalisées (par exemple : pages que vous avez créées, pages surveillées pour vandalisme, ou pages de discussion), les utilisateurs peuvent identifier plus rapidement ce qui nécessite une attention, réduire la charge cognitive et répondre plus efficacement. Cela améliore l'utilisabilité de la liste de suivi, en particulier pour les éditeurs très actifs.
* Une nouvelle fonctionnalité disponible sur [[Special:Contributions|Special:Contributions]] montre [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts|des comptes temporaires]] qui sont probablement utilisés par la même personne, et rend ainsi le patrouillage moins chronophage. En vérifiant les contributions d'un compte temporaire, les utilisateurs ayant accès aux adresses IP des comptes temporaires peuvent désormais avoir une vue des contributions des comptes temporaires associés. La fonctionnalité recherche toutes les adresses IP associées à un compte temporaire donné pendant la période de conservation des données et affiche toutes les contributions de tous les comptes temporaires ayant utilisé ces adresses IP. [[mw:Special:MyLanguage/Trust and Safety Product/Temporary Accounts#February 2026: Improvements to the patroller tooling|Plus...]] [https://phabricator.wikimedia.org/T415674]
* Lorsque les éditeurs prévisualisent une modification de wikitexte, la boîte de rappel indiquant qu'ils ne voient qu'une prévisualisation (qui est affichée en haut) a désormais un fond gris/neutre au lieu d'un fond jaune/d'avertissement. Cela facilite la distinction entre les notes de prévisualisation et les avertissements réels (par exemple, les conflits de modification ou les cibles de redirection problématiques), qui seront désormais affichés dans des boîtes d'avertissement ou d'erreur séparées. [https://phabricator.wikimedia.org/T414742]
* La [[m:Special:GlobalWatchlist|Liste de suivi globale]] vous permet de consulter vos listes de suivi provenant de plusieurs wikis sur une seule page. L' [[mw:Special:MyLanguage/Extension:GlobalWatchlist|extension]] continue de s'améliorer — elle prend désormais en charge correctement plus d'un site Wikibase, par exemple à la fois [[d:|Wikidata]] et [[testwikidata:|testwikidata]]. De plus, des problèmes concernant la direction du texte ont été résolus pour les utilisateurs qui préfèrent Wikidata ou d'autres sites Wikibase dans des langues de droite à gauche (RTL). [https://phabricator.wikimedia.org/T415440][https://phabricator.wikimedia.org/T415458]
* <span lang="en" dir="ltr" class="mw-content-ltr">The automatic "magic links" for ISBN, RFC, and PMID numbers have been [[mw:Special:MyLanguage/Help:Magic links|deprecated in wikitext since 2021]] due to inflexibility and difficulties with localization. Several wikis have successfully replaced RFC and PMID magic links with equivalent external links, but a template was often required to replace the functionality of the ISBN magic link. There is now a new [[mw:Special:MyLanguage/Help:Magic words#isbn|built-in parser function]] <code dir=ltr><nowiki>{{#isbn}}</nowiki></code> available to replace the basic functionality of the ISBN magic link. This makes it easier for wikis who wish to migrate off of the deprecated magic link functionality to do so.</span> [https://phabricator.wikimedia.org/T145604]
* Deux nouveaux wikis ont été créés :
** un {{int:project-localized-name-group-wikipedia}} dans [[d:Q35401|Jju]] ([[w:kaj:|<code>w:kaj:</code>]]) [https://phabricator.wikimedia.org/T413283]
** un {{int:project-localized-name-group-wikipedia}} dans [[d:Q1186896|Nawat]] ([[w:ppl:|<code>w:ppl:</code>]]) [https://phabricator.wikimedia.org/T413273]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:23|la tâche soumise|les {{formatnum:23}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:23||s}} la semaine dernière]].
'''Actualités pour la contribution technique'''
* Un nouveau groupe d'utilisateurs global a été créé : [[{{int:grouppage-local-bot}}|{{int:group-local-bot}}]]. Il sera utilisé en interne par le logiciel pour permettre aux robots communautaires de contourner les limites de débit appliquées aux [[w:en:Web_scraping|web scrapers]] abusifs. Les comptes approuvés en tant que robots sur au moins un wiki Wikimedia seront automatiquement ajoutés à ce groupe. Cela ne changera pas les autorisations dont dispose le robot. [https://phabricator.wikimedia.org/T415588]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.15|MediaWiki]]
'''Rencontres et évènements'''
* La [[mw:Special:MyLanguage/MediaWiki Users and Developers Conference Spring 2026|Conférence des utilisateurs et des développeurs de MediaWiki, Printemps 2026]] se tiendra du 25 au 27 mars à Salt Lake City, États-Unis. Cet événement est organisé par et pour la communauté MediaWiki de tiers. Vous pouvez proposer des sessions et vous inscrire pour y assister. [https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists.wikimedia.org/thread/AZBWVI46SDEB65PGR5J6E4TYOQQEZXM7/]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/07|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W07"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 10 février 2026 à 00:30 (CET)
<!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30026671 -->
== Actualités techniques n° 2026-08 ==
<section begin="technews-2026-W08"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/08|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* <span class="mw-translate-fuzzy">L'[[mw:Special:MyLanguage/Wikimedia Site Reliability Engineering|équipe SRE]] va procéder au nettoyage d'[[m:Special:MyLanguage/Etherpad|Etherpad]], l'éditeur web open source de documents collaboratifs en temps réel. Tous les blocs-notes seront définitivement supprimés après le 30 avril 2026 – si des projets de migration sont encore en cours à cette date, l'équipe pourra réexaminer la date au cas par cas. Veuillez effectuer des sauvegardes locales de tout contenu que vous souhaitez conserver, car les données supprimées ne pourront pas être récupérées. Ce nettoyage permet de réduire la taille de la base de données et l'empreinte de l'infrastructure. Etherpad continuera de prendre en charge la collaboration en temps réel, mais le stockage à long terme n'est plus assuré. D'autres nettoyages pourront avoir lieu ultérieurement sans préavis.</span> [https://phabricator.wikimedia.org/T415237]
'''Actualités pour la contribution'''
* L'équipe de Recherche d'Informations lancera une [[mw:Special:MyLanguage/Readers/Information Retrieval/Phase 1|expérimentation sur l'application mobile Android]], afin de tester des fonctionnalités de recherche hybrides capables de gérer à la fois les requêtes sémantiques et par mots-clés. L'amélioration de la recherche sur la plateforme permettra aux lecteurs de trouver plus facilement ce qu'ils cherchent, directement sur Wikipédia. L'expérimentation sera d'abord lancée sur Wikipédia en grec fin février, puis sur les versions anglaise, française et portugaise en mars. [https://diff.wikimedia.org/2026/01/08/semantic-search-making-it-easier-to-find-the-information-readers-want/ En savoir plus] sur le blog ''Diff''. [https://www.mediawiki.org/wiki/Readers/Information_Retrieval]
* L'équipe « Croissance des lecteurs » mènera [[mw:Special:MyLanguage/Readers/Reader Growth/WE3.10.2 Mobile Table of Contents|une expérience]] auprès des utilisateurs de la version mobile du site web qui ajoute une table des matières et développe automatiquement toutes les sections des articles, afin de mieux comprendre les problèmes de navigation qu'ils rencontrent. Le test sera disponible sur les versions arabe, chinoise, anglaise, française, indonésienne et vietnamienne de Wikipedia.
* Auparavant, les notifications ([[{{ns:8}}:Sitenotice]] et [[{{ns:8}}:Anonnotice]]) du site ne s'affichaient que sur la version ordinateur. Maintenant, elles s'afficheront désormais sur toutes les plateformes. Les utilisateurs mobiles verront ces notifications. Les administrateurs du site doivent être prêts à tester et à corriger les notifications sur les appareils mobiles afin d'éviter toute interférence avec les articles. Pour désactiver ces notifications, les administrateurs d'interface peuvent ajouter <code dir="ltr">#siteNotice { display: none; }</code> à [[{{ns:8}}:Minerva.css]]. [https://phabricator.wikimedia.org/T138572][https://phabricator.wikimedia.org/T416644]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:19|la tâche soumise|les {{formatnum:19}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:19||s}} la semaine dernière]]. Par exemple, un problème concernant la section ''[[Special:RecentChanges|Spécial:Modifications récentes]]'' a été résolu. Auparavant, cliquer sur « Masquer » dans les filtres actifs entraînait la disparition du bouton « Afficher les nouvelles modifications depuis… », alors qu'il aurait dû rester visible. Ce bouton fonctionne désormais correctement. [https://phabricator.wikimedia.org/T406339]
'''Actualités pour la contribution technique'''
* Une nouvelle documentation est désormais disponible pour aider les rédacteurs à déboguer les fonctionnalités de recherche interne. Elle facilite le dépannage lorsque des pages n'apparaissent pas dans les résultats, lorsque le classement semble inattendu et lorsqu'il est nécessaire d'inspecter le contenu indexé, ce qui permet de mieux comprendre et d'analyser le comportement de la recherche. [[mw:Help:CirrusSearch/Debug|En savoir plus]]. [https://phabricator.wikimedia.org/T411169]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.16|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/08|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W08"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 16 février 2026 à 20:17 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30086330 -->
== <span lang="en" dir="ltr">Tech News: 2026-09</span> ==
<div lang="en" dir="ltr">
<section begin="technews-2026-W09"/><div class="plainlinks">
Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/09|Translations]] are available.
'''Weekly highlight'''
* [[mw:Special:MyLanguage/Edit check/Reference Check|Reference Check]] has been deployed to English Wikipedia, completing its rollout across all Wikipedias. The feature prompts newcomers to add a citation before publishing new content, helping reduce common citation-related reverts and improve verifiability. In A/B testing, the impact was substantial: newcomers shown Reference Check were approximately 2.2 times more likely to include a reference on desktop and about 17.5 times more likely on mobile web. [https://analytics.wikimedia.org/published/reports/editing/reference_check_ab_test_report_final_2025.html]
'''Updates for editors'''
* The [[mw:Special:MyLanguage/Extension:InterwikiSorting|InterwikiSorting extension]], which allowed for the [[m:Special:MyLanguage/Interwiki sorting order|sorting of interwiki links]], has been undeployed from Wikipedia. As a result, editors who had enabled interwiki link sorting in non-compact mode (full list format) will now see links reordered. The links moving forward will be listed in the alphabetical order of language code. [https://phabricator.wikimedia.org/T253764]
* Later this week, people who are editing a page-section using the mobile visual editor, will notice a new "Edit full page" button. When tapped, you will be able to edit the entire article. This helps when the change you want to make is outside the section you initially opened. [https://phabricator.wikimedia.org/T387175][https://phabricator.wikimedia.org/T409112]
* [[mw:Special:MyLanguage/Readers/Reader Experience|The Reader Experience team]] is inviting editors to assess whether dark mode should still be considered "beta" on their wiki, based on their experience of how well it functions on desktop and mobile. If the feature is deemed mature, editors can update the interface messages in <code dir=ltr>MediaWiki:skin-theme-description</code> and <code dir=ltr>MediaWiki:Vector-night-mode-beta-tag</code> to indicate that dark mode is ready and no longer considered beta.
* The improved [[mw:Wikimedia_Apps/Team/iOS/Activity_Tab|Activity tab]] which displays user-insights is now available to all users of the Wikipedia iOS app (version 7.9.0 and later). Following earlier A/B testing that showed higher account creation among users with access to the feature, it has been rolled out to 100% of users along with some updates. The Activity tab now shows your edited articles in the timeline, offers editing impact insights like contribution counts and article view trends, and customization options to improve in-app experience for users.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:21}} community-submitted {{PLURAL:21|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, a bug that prevented [[mw:Special:MyLanguage/Extension:DiscussionTools|DiscussionTools]] from working on mobile has now been fixed, restoring full functionality. [https://phabricator.wikimedia.org/T415303]
'''Updates for technical contributors'''
* The [[m:Special:GlobalWatchlist|Global Watchlist]] lets you view your watchlists from multiple wikis on one page. The [[mw:Special:MyLanguage/Extension:GlobalWatchlist|extension]] that makes this possible continues to improve. The latest upgrade is the inclusion of a [[mw:Extension:GlobalWatchlist#hook|new hook]], <code dir=ltr>ext.globalwatchlist.rebuild</code>, which fires after each watchlist rebuild. This allows you to run gadgets and user scripts for the Special page. [https://phabricator.wikimedia.org/T275159]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.17|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]] • [[m:Special:MyLanguage/Tech/News#contribute|Contribute]] • [[m:Special:MyLanguage/Tech/News/2026/09|Translate]] • [[m:Tech|Get help]] • [[m:Talk:Tech/News|Give feedback]] • [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].''
</div><section end="technews-2026-W09"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 23 février 2026 à 20:03 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30119102 -->
== Actualités techniques n° 2026-10 ==
<section begin="technews-2026-W10"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/10|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* Le [[m:Special:MyLanguage/Wikipedia 25/Easter egg experiments|mode Anniversaire]] Wikipedia 25 est maintenant disponible sur Wikipédia en français, anglais, betawi, breton, chinois, espagnol, gorontalo, indonésien, italien, luxembourgeois, madurais, néerlandais, sicilien, tchèque, thaï et vietnamien ! Cette campagne à temps limitée célèbre 25 ans de Wikipédia avec une mascotte : « Baby Globe », disponible sous la forme d'un réglage. Lorsque ce réglage est activé, Baby Globe est montrée sur [[m:Special:MyLanguage/Wikipedia 25/Easter egg experiments/article configuration|environ 2 500 articles]], attendant d'être découverte par des lecteurs. Chaque communauté peut choisir d'activer le mode Anniversaire par consensus et en demandant à un administrateur de le rendre disponible et de le personaliser via une [[m:Special:MyLanguage/Wikipedia 25/Easter egg experiments#Community Configuration Demo|configuration]] sur le wiki local.
'''Actualités pour la contribution'''
* Le [[:m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|sous-référencement]], une nouvelle fonctionalité pour réutiliser des références avec des détails différents est maintenant disponible sur Wikipédia en suédois, polonais et [[:phab:T418209|quelques autres]]. Vous pouvez [[:m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing#test|essayer la fonctionalité]] sur ces projets ou sur testwiki et [https://en.wikipedia.beta.wmcloud.org/wiki/Sub-referencing betawiki]. Les retours des premiers essais sur Wikipédia en allemand ont été [[:m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing/Learnings|publiés dans un rapport]]. Contactez l'équipe de Wikimédia Allemagne si vous êtes [[:m:Talk:WMDE Technical Wishes/Sub-referencing#Pilot wikis|intéressés pour devenir un wiki pilote]].
* La [[mw:Special:MyLanguage/Help:Edit check#Paste check|vérification du collage clavier]] sera disponible sur tous les Wikipédias cette semaine. Cette fonctionalité avertit les nouveaux contributeurs qui collent du texte qu'ils n'ont probablement pas écrit de vérifier si laisser celui-ci risque de causer une violation du droit d'auteur. La vérification du collage clavier [[mw:Special:MyLanguage/Edit check/Tags|marque]] toutes les modifications où l'avertissement a été montré pour permettre leur vérification. Les administrateurs locaux peuvent configurer les différents aspects de cette fonctionalité à travers [[{{#special:EditChecks}}]]. Des [[mw:Special:MyLanguage/Edit check/Paste Check#A/B Experiment|études]] sur 22 wikis ont montré que cette vérification permet une réduction de 18% des annulations comparé au groupe de contrôle. Les traducteurs peuvent [https://translatewiki.net/w/i.php?title=Special%3ATranslate&group=ext-visualeditor-ve-mw-editcheck&filter=&optional=1&action=translate aider à traduire] cette fonctionalité.
* <span lang="en" dir="ltr" class="mw-content-ltr">The [[mw:Special:MyLanguage/Readers/Reader Experience|Reader Experience team]] will be standardizing the user menu in the top right for all mobile users so that it is closer to the desktop experience. Currently this user menu is only visible to users with Advanced Mobile Controls (AMC) turned on. The only change is that a couple buttons previously in the left-side menu will move to the top right for users who do not have AMC turned on. This change is expected to go out March 9 and seeks to improve the user interface.</span> [https://phabricator.wikimedia.org/T413912]
* À partir de la semaine du 2 mars, les emails envoyés lorsqu'une adresse email a été ajoutée, supprimée ou changée pour un compte changera pour adopter un formattage HTML beaucoup plus agréable et plus clair que le texte brut précédent. [https://phabricator.wikimedia.org/T410807]
* Les notifications sont actuellement limitées à 2 000 entrées historiques par utilisateur et remontent à 2013 lorsque la fonctionnalité a été publiée. Le système va être modifié pour ne stocker que les notifications des 5 dernières années, mais jusqu'à 10 000 d'entre elles. Cela contribuera à la santé à long terme des infrastructures et à empêcher que les notifications plus récentes disparaissent trop tôt. [https://phabricator.wikimedia.org/T383948]
* <span lang="en" dir="ltr" class="mw-content-ltr">The [[m:Special:GlobalWatchlist|Global Watchlist]] which lets you view your watchlists from multiple wikis on a single page continues to see improvements. The latest update improves label usage experience. The [[mw:Special:MyLanguage/Extension:GlobalWatchlist|extension]] now allows activating the [[mw:Special:MyLanguage/Manual:Language#Fallback languages|language fallback system]] for Wikidata items without labels in the viewed language, and showing those labels in the user’s preferred Wikidata language if no <code dir=ltr>uselang=</code> URL parameter is provided.</span> [https://phabricator.wikimedia.org/T373686][https://phabricator.wikimedia.org/T416111]
* L'équipe Wikipédia Android a commencé un test beta de la [[mw:Special:MyLanguage/Readers/Information Retrieval/Phase 1|recherche hybride]] sur Wikipédia en grec. Cette recherche hybride supporte les requêtes sémantique et par mot clés, permettant aux utilisateurs de trouver ce qu'ils cherchent plus facilement.
* Pour des raisons de sécurité, les membres de certains groupes sont [[m:Special:MyLanguage/Mandatory two-factor authentication for users with some extended rights|forcés d'avoir la double authentification]] (A2F) d'activée. Actuellement, l'A2F n'est nécessaire que pour utiliser les droits du groupe, et non pour en faire partie. Vu que ce système admet certaines failles, il sera [[phab:T418580|changé graduellement en mars]]. Les membres de ces groupes ne pourront plus désactiver la dernière méthose d'A2F sur leur compte, et il sera impossible d'ajouter des utilisateurs sans A2F à ces groupes. Il sera toujours possible de rajouter d'autres méthodes d'authentification et d'en enlever, tant qu'une est toujours activée. Dans la seconde moitié de mars, les utilisateurs sans A2F seront retirés de ces groupes. Cela s'applique aux administrateurs CentralNotice, aux vérificateurs d'utilisateurs, aux administrateurs d'interface, aux masqueurs, aux staff de Wikidata et Wikifonctions ainsi qu'aux bureaux IT et Confiance et sécurité de la WMF. Rien ne changera pour les autres utilisateurs. Voir la tâche liée pour le calendrier de déploiement. [https://phabricator.wikimedia.org/T418580]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:27|la tâche soumise|les {{formatnum:27}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:27||s}} la semaine dernière]]. Par exemple, le problème empêchant les utilisateurs de créer une instance dans [https://www.wikibase.cloud/ Wikibase.cloud] a maintenant été résolu. [https://phabricator.wikimedia.org/T416807]
'''Actualités pour la contribution technique'''
* <span lang="en" dir="ltr" class="mw-content-ltr">To help ensure [[mw:Special:MyLanguage/MediaWiki Product Insights/Responsible Reuse|fair use of infrastructure]], over the next month the Wikimedia Foundation will implement global API rate limits across our APIs. In early March, stricter limits will be applied to unidentified requests from outside Toolforge/WMCS and API requests that are made from web browsers. In April, higher limits will be applied to identified traffic. These limits are intentionally set as high as possible to minimise impact on the community. Bots running in Toolforge/WMCS or with the bot user right on any wiki should not be affected for now. However, all developers are advised to follow updated best practices. For more information, see [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|Wikimedia APIs/Rate limits]].</span>
* <span lang="en" dir="ltr" class="mw-content-ltr">The Wikidata Query Service Linked Data Fragment (LDF) endpoint will be decommissioned in February. This endpoint served limited traffic, which was successfully migrated to other data access methods that were better suited to support existing use cases. The hardware used to support the LDF endpoint will be reallocated to support the ongoing backend migration efforts.</span> [https://phabricator.wikimedia.org/T415696]
* Le nouvel analyseur syntaxique Parsoid [[mw:Special:MyLanguage/Parsoid/Parser Unification/Updates|continue d'être déployés sur plus de wikis]], améliorant la pérennité de la platforme et rendant plus facile l'ajout de nouvelles fonctionalités de lecture et de modification. Parsoid est maintenant l'analyseur par défaut sur 488 wikis de la WMF (268 Wikipédias), couvrant plus de 10% de toutes les lectures de pages Wikipédia.
* Le processus et les critères pour [[Special:MyLanguage/Wikimedia Enterprise#Access|demander un accès exceptionnel]] au flux à fort volume de l'API ''Wikimédia Entreprise'' (sans coût pour des utilisations en rapport à notre mission) [[m:Talk:Wikimedia Enterprise#Exceptional access criteria|ont maintenant été publiés]]. Notre but est de donner une documentation plus claire et plus complète aux utilisateurs.
* [https://techblog.wikimedia.org/ Le blog Tech], dédié à la communité technique de Wikimédia [https://techblog.wikimedia.org/2026/02/24/a-tech-blog-diff/ va migrer] vers [[diffblog:|Diff]], le blog pour les nouvelles et événements de la communauté. La migration devrait être terminée en Avril 2026, après quoi les nouveaux posts seront acceptés pour être publiés. Les lecteurs pourront lire les posts - anciens ou nouveaux - sur https://diff.wikimedia.org/.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.18|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/10|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W10"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 2 mars 2026 à 18:51 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30137798 -->
== <span lang="en" dir="ltr">Tech News: 2026-11</span> ==
<div lang="en" dir="ltr">
<section begin="technews-2026-W11"/><div class="plainlinks">
Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/11|Translations]] are available.
'''Weekly highlight'''
* [[m:Special:MyLanguage/Tech/Server switch|All wikis will be read-only]] for a few minutes on Wednesday, 25 March 2026 at [https://zonestamp.toolforge.org/1774450800 15:00 UTC]. This is for the datacenter server switchover backup tests, [[wikitech:Deployments/Yearly calendar|which happen twice a year]]. During the switchover, all Wikimedia website traffic is shifted from one primary data center to the backup data center to test availability and prevent service disruption even in emergencies.
* Last week, all wikis had 2 hours of read-only time, and extended unavailability for user-scripts and gadgets. This was due to a security incident which has since been resolved. Work is ongoing to prevent re-occurrences. For current information please see the [[m:Steward's noticeboard#Statement on Meta about today's user script security incident|post on the Stewards' noticeboard]] ([[m:Special:MyLanguage/Wikimedia Foundation/Product and Technology/Product Safety and Integrity/March 2026 User Script Incident|translations]]).
'''Updates for editors'''
* Users facing multiple blocks on mobile will now see the reasons for each block separately, instead of a generic message. This helps them understand why they are blocked and what steps they can take to resolve the issue. For example, users affected for using common VPNs (such as [[Special:MyLanguage/Apple iCloud Private Relay|iCloud Private Relay]]) will receive clearer guidance on what they need to do to start editing again. [https://phabricator.wikimedia.org/T357118]
* Later this week, [[mw:Special:MyLanguage/VisualEditor/Suggestion Mode|Suggestion Mode]] will become available as a beta feature within the visual editor at all Wikipedias. This feature proactively suggests various types of actions that people can consider taking to improve Wikipedia articles, and learn about related guidelines. The feature is locally configurable, and can also be locally expanded with custom Suggestions. Current settings can be seen at [[Special:EditChecks]] and there are [[mw:Special:MyLanguage/Help:Suggestion mode#For administrators %E2%80%93 local customization|instructions for how administrators can customize]] the links to point to local guidelines. The feature is connected to [[mw:Special:MyLanguage/Help:Edit check|Edit check]] which suggests improvements while someone is writing new content. In the future, the Editing team plans to evaluate the feature's impact with newcomers through a controlled experiment. [https://phabricator.wikimedia.org/T404600]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:23}} community-submitted {{PLURAL:23|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the issue where the cursor became misaligned during the use of CodeMirror’s syntax highlighting, which makes wikitext and code easier to read, has now been fixed. This problem specifically affected users who defined a font rule in a custom stylesheet while creating a new topic with DiscussionTools. [https://phabricator.wikimedia.org/T418793]
'''Updates for technical contributors'''
* API rate limiting update: To help ensure [[mw:Special:MyLanguage/MediaWiki Product Insights/Responsible Reuse|fair use of infrastructure]], global API rate limits will be applied this week to requests without a compliant User-Agent that originate from outside Toolforge/WMCS and to unauthenticated requests made from web browsers. Higher limits will be applied to identified traffic in April. Bots running in Toolforge/WMCS or with the bot user right on any wiki should not be affected for now. However, all developers are advised to follow updated best practices. For more information, see [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|Wikimedia APIs/Rate limits]].
* The new GraphQL API has been released. The API was developed as a flexible alternative to select features of the Wikidata Query Service (WDQS), to improve developer experience and foster adaptability, and efficient data access. Try it out and [[d:Wikidata:Wikibase GraphQL#Feedback and development|give feedback]]. You can also [https://greatquestion.co/wikimediadeutschland/GraphQLAPI/apply sign up for usability tests].
* The [[m:Special:MyLanguage/Product and Technology Advisory Council/Unsupported Tools Working Group|PTAC Unsupported Tools Working Group]] continued improvements to [[commons:Special:MyLanguage/Commons:Video2commons#|Video2Commons]] in February, with fixes addressing authentication errors, large-file handling, task queue visibility, and clearer upload behavior. Work is still ongoing in some areas, including changes related to deprecated server-side uploads. Read [[m:Special:MyLanguage/Product and Technology Advisory Council/Unsupported Tools Working Group#February 2026|this update]] to learn more.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.19|MediaWiki]]
'''In depth'''
* The Article Guidance team invites experienced Wikipedia editors from selected [[mw:Special:MyLanguage/Article guidance/Pilot wikis and collaborators#Collaborators|pilot wikis]] and interested contributors from other Wikipedias to fill out this questionnaire which is available in [https://docs.google.com/forms/d/e/1FAIpQLSfmLeVWnxmsCbPoI_UF2jyRcn73WRGWCVPHzerXb4Cz97X_Ag/viewform English], [https://docs.google.com/forms/d/e/1FAIpQLSd6rzr4XXQw8r4024fE3geTPFe13M_6w7Mitj-YJi0sOlWTAw/viewform?usp=header Arabic], [https://docs.google.com/forms/d/e/1FAIpQLSdok3-RfB18lcugYTUMGkpwmqG_8p760Wv4dCXitOXOszjUDw/viewform?usp=header Bengali], [https://docs.google.com/forms/d/e/1FAIpQLSfjTfYp4jEo0akA4B1e-Nfg3QZPCudUjhJzHzzDi6AHyAaMGA/viewform?usp=header Japanese], [https://docs.google.com/forms/d/e/1FAIpQLScteVoI29Aue4xc72dekk-6RYtvmMgQxzMI900UOawrFrSTWg/viewform?usp=header Portuguese], [https://docs.google.com/forms/d/e/1FAIpQLSetdxnYwL3ub2vqA7awCg5hJZPMIYcDPaiTe12rY9h0GYnVlw/viewform?usp=header Persian], and [https://docs.google.com/forms/d/e/1FAIpQLScNvfJF-Ot-4pzA4qAN771_0QDJ4Li19YcUsaTgSKW8Nc7U_Q/viewform?usp=header Turkish]. Your answers will help the team customize guidance for less experienced editors and help them learn community policies and practices while creating an article. Learn more [[mw:Special:MyLanguage/Article guidance|on the project page]].
'''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]] • [[m:Special:MyLanguage/Tech/News#contribute|Contribute]] • [[m:Special:MyLanguage/Tech/News/2026/11|Translate]] • [[m:Tech|Get help]] • [[m:Talk:Tech/News|Give feedback]] • [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].''
</div><section end="technews-2026-W11"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 9 mars 2026 à 19:52 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30213008 -->
== <span lang="en" dir="ltr">Tech News: 2026-12</span> ==
<div lang="en" dir="ltr">
<section begin="technews-2026-W12"/><div class="plainlinks">
Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/12|Translations]] are available.
'''Updates for editors'''
* The [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]] beta feature, also known as [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror 6]], has been used for wikitext syntax highlighting since November 2024. It will be promoted out of beta by May 2026 in order to bring improvements and new [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Features|features]] to all editors who use the standard syntax highlighter. If you have any questions or concerns about promoting the feature out of beta, [[mw:Special:MyLanguage/Help talk:Extension:CodeMirror|please share]]. [https://phabricator.wikimedia.org/T259059]
* Some changes to local user groups are performed by stewards on Meta-Wiki and logged there only. Now, interwiki rights changes will be logged both on Meta-Wiki and the wiki of the target user to make it easier to access a full record of user's rights changes on a local wiki. Past log entries for such changes will be backfilled in the coming weeks. [https://phabricator.wikimedia.org/T6055]
* On wikis using [[m:Special:MyLanguage/Flagged Revisions|Flagged Revisions]], the number of pending changes shown on [[{{#Special:PendingChanges}}]] previously counted pages which were no longer pending review, because they have been removed from the system without being reviewed, e.g. due to being deleted, moved to a different namespace, or due to wiki configuration changes. The count will be correct now. On some wikis the number shown will be much smaller than before. There should be no change to the list of pages itself. [https://phabricator.wikimedia.org/T413016]
* Wikifunctions composition language has been rewritten, resulting in a new version of the language. This change aims to increase service stability by reducing the orchestrator's memory consumption. This rewrite also enables substantial latency reduction, code simplification, and better abstractions, which will open the door to later feature additions. Read more about [[f:Special:MyLanguage/Wikifunctions:Status updates/2026-03-11|the changes]].
* Users can now sort search results alphabetically by page title. The update gives an additional option to finding pages more easily and quickly. Previously, results could be sorted by Edit date, Creation date, or Relevance. To use the new option, open 'Advanced Search' on the search results page and select 'Alphabetically' under 'Sorting Order'. [https://phabricator.wikimedia.org/T403775]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:28}} community-submitted {{PLURAL:28|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the bug that prevented UploadWizard on Wikimedia Commons from importing files from Flickr has now been fixed. [https://phabricator.wikimedia.org/T419263]
'''Updates for technical contributors'''
* A new special page, [[{{#special:LintTemplateErrors}}]], has been created to list transcluded pages that are flagged as containing lint errors to help users discover them easily. The list is sorted by the number of transclusions with errors. For example: [[{{#special:LintTemplateErrors}}/night-mode-unaware-background-color]]. [https://phabricator.wikimedia.org/T170874]
* Users of the [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]] beta feature have been using [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] instead of [[mw:Special:MyLanguage/Extension:CodeEditor|CodeEditor]] for syntax highlighting when editing JavaScript, CSS, JSON, Vue and Lua content pages, for some time now. Along with promoting CodeMirror 6 out of beta, the plan is to replace CodeEditor as the standard editor for these content models by May 2026. [[mw:Special:MyLanguage/Help talk:Extension:CodeMirror|Feedback or concerns are welcome]]. [https://phabricator.wikimedia.org/T419332]
* The [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] JavaScript modules will soon be upgraded to CodeMirror 6. Leading up to the upgrade, loading the <code dir=ltr>ext.CodeMirror</code> or <code dir=ltr>ext.CodeMirror.lib</code> modules from gadgets and user scripts was deprecated in July 2025. The use of the <code dir=ltr>ext.CodeMirror.switch</code> hook was also deprecated in March 2025. Contributors can now make their scripts or gadgets compatible with CodeMirror 6. See the [[mw:Special:MyLanguage/Extension:CodeMirror#Gadgets and user scripts|migration guide]] for more information. [https://phabricator.wikimedia.org/T373720]
* The MediaWiki Interfaces team is expanding coverage of REST API module definitions to include [[mw:Special:MyLanguage/API:REST API/Extensions|extension APIs]]. REST API modules are groups of related endpoints that can be independently managed and versioned. Modules now exist for [https://phabricator.wikimedia.org/T414470 GrowthExperiments] and [https://phabricator.wikimedia.org/T419053 Wikifunctions] APIs. As we migrate extension APIs to this structure, documentation will move out of the main MediaWiki OpenAPI spec and REST Sandbox view, and will instead be accessible via module-specific options in the dropdown on the [https://test.wikipedia.org/wiki/Special:RestSandbox REST Sandbox] (i.e., [[{{#Special:RestSandbox}}]], available on all wiki projects).
* The [[mw:Special:MyLanguage/Extension:Scribunto|Scribunto]] extension provides different pieces of information about the wiki where the module is being used via the [[mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual|mw.site]] library. Starting last week, the library also provides a [[mw:Special:MyLanguage/Extension:Scribunto/Lua reference manual#mw.site.wikiId|way]] of accessing the [[mw:Special:MyLanguage/Manual:Wiki ID|wiki ID]] that can be used to facilitate cross-wiki module maintenance. [https://phabricator.wikimedia.org/T146616]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.20|MediaWiki]]
'''In depth'''
* The [[m:Special:MyLanguage/Coolest Tool Award|2026 Coolest Tool Award]] celebrating outstanding community tools, is now open for nominations! Nominate your favorite tool using the [https://wikimediafoundation.limesurvey.net/435684?lang=en nomination survey] form by 23 March 2026. For more information on privacy and data handling, please see the [[foundation:Special:MyLanguage/Legal:Coolest_Tool_Award_2026_Survey_Privacy_Statement|survey privacy statement]].
'''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]] • [[m:Special:MyLanguage/Tech/News#contribute|Contribute]] • [[m:Special:MyLanguage/Tech/News/2026/12|Translate]] • [[m:Tech|Get help]] • [[m:Talk:Tech/News|Give feedback]] • [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].''
</div><section end="technews-2026-W12"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 16 mars 2026 à 20:35 (CET)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30260505 -->
== <span lang="en" dir="ltr">Upcoming deployment of CampaignEvents extension to Wikibooks</span> ==
<div lang="en" dir="ltr">
<section begin="message"/>
Hello everyone,
We are writing to inform you that the [[mw:Help:Extension:CampaignEvents|CampaignEvents extension]] will be deployed to all Wikibooks projects during the week of '''23 March 2026'''.
This follows last year’s broader rollout across Wikimedia projects. We realized that Wikibooks was not included at the time, and we’re now addressing that to ensure consistency across all communities.
The CampaignEvents extension provides tools to support event and campaign organization on-wiki, including features like on-wiki event registration and collaboration lists(global event list).
We welcome any questions, feedback, or concerns you may have. We are also happy to support anyone interested in trying out the tools.
''Apologies if this message is not in your preferred language. If you’re able to help translate it for your community, please feel free to do so.''
<section end="message"/>
</div>
<bdi lang="en" dir="ltr">[[User:Udehb-WMF|Udehb-WMF]] ([[User talk:Udehb-WMF|discussion]]) 19 mars 2026 à 19:22 (CET)</bdi>
<!-- Message envoyé par User:Udehb-WMF@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=User:Udehb-WMF/sandbox/MM_target&oldid=30284073 -->
== <span lang="en" dir="ltr">Tech News: 2026-13</span> ==
<div lang="en" dir="ltr">
<section begin="technews-2026-W13"/><div class="plainlinks">
Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/13|Translations]] are available.
'''Weekly highlight'''
* Wikimedia site users can now log in without a password using passkeys. This is a secure method supported by fingerprint, facial recognition, or PIN. With this change, all users who opt for passwordless login will find it easier, faster, and more secure to log in to their accounts using any device. The new passkey login option currently appears as an autofill suggestion in the username field. An additional [[phab:T417120|"Log in with passkey" button]] will soon be available for users who have already registered a passkey. This update will improve security and user experience. The [[c:File:Passwordless_login_screencast.webm|screen recording]] demonstrates the passwordless login process step by step.
* [[m:Special:MyLanguage/Tech/Server switch|All wikis will be read-only]] for a few minutes on Wednesday, 25 March 2026 at [https://zonestamp.toolforge.org/1774450800 15:00 UTC]. This is for the datacenter server switchover backup tests, [[wikitech:Deployments/Yearly calendar|which happen twice a year]]. During the switchover, all Wikimedia website traffic is shifted from one primary data center to the backup data center to test availability and prevent service disruption even in emergencies.
'''Updates for editors'''
* Wikimedia site users can now export their notifications older than 5 years using a [[toolforge:echo-chamber|new Toolforge tool]]. This will ensure that users retain their important notifications and avoid them being lost based on the planned change to delete notifications older than 5 years, as previously announced. [https://phabricator.wikimedia.org/T383948]
* Wikipedia editors in Indonesian, Thai, Turkish, and Simple English now have access to Special:PersonalDashboard. This is an [[mw:Special:MyLanguage/Moderator Tools/Dashboard|early version of an experience]] that introduces newer editors to patrolling workflows, making it easier for them to move from making edits to participating in more advanced moderation work on their project. [https://phabricator.wikimedia.org/T402647]
* The [[Special:Block]] now has two minor interface changes. Administrators can now easily perform indefinite blocks through a dedicated radio button in the expiry section. Also, choosing an indefinite expiry provides a different set of common reasons to select from, which can be changed at: [[MediaWiki:Ipbreason-indef-dropdown]]. [https://phabricator.wikimedia.org/T401823]
* Mobile editors [[mw:Special:MyLanguage/Contributors/Account Creation Experiments#Logged-out|at several wikis]] can now see an improved logged-out edit warning, thanks to the recent updates from the Growth team. These changes released last week are part of ongoing efforts and tests to enhance [[mw:Special:MyLanguage/Contributors/Account Creation Experiments|account creation experience on mobile]] and then increase participation. [https://phabricator.wikimedia.org/T408484]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:36}} community-submitted {{PLURAL:36|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, the bug that prevented mobile web users from seeing the block information when affected by multiple blocks has been fixed. They can now see messages of all the blocks currently affecting them when they access Wikipedia.
'''Updates for technical contributors'''
* Images built using Toolforge will soon get the upgraded buildpacks version, bringing support for newer language versions and other upstream improvements and fixes. If you use Toolforge Build Service, review the recent [https://lists.wikimedia.org/hyperkitty/list/cloud-announce@lists.wikimedia.org/thread/EMYTA32EV2V5SQ2JIEOD2CL66YFIZEKV/ cloud-announce email] and update your build configuration as necessary to ensure your tools are compatible. [https://wikitech.wikimedia.org/w/index.php?title=Help:Toolforge/Building_container_images&oldid=2392097#Buildpack_environment_upgrade_process][https://phabricator.wikimedia.org/T380127]
* The [https://api.wikimedia.org/wiki/Main_Page API Portal] documentation wiki will shut down in June 2026. API keys created on the API Portal will continue to work normally. api.wikimedia.org endpoints will be deprecated gradually starting in July 2026. Documentation on the API Portal is moving to [[mw:Wikimedia APIs|mediawiki.org]]. Learn more on the [[wikitech:API Portal/Deprecation|project page]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.21|MediaWiki]]
'''In depth'''
* [[m:Special:MyLanguage/WMDE Technical Wishes|WMDE Technical Wishes]] is considering improvements to [[m:WMDE Technical Wishes/References/VisualEditor automatic reference names|automatically generated reference names in VisualEditor]]. Please check out the [[m:WMDE Technical Wishes/References/VisualEditor automatic reference names#Proposed solutions|proposed solutions]] and participate in the [[m:Talk:WMDE Technical Wishes/References/VisualEditor automatic reference names#Request for comment|request for comment]].
'''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]] • [[m:Special:MyLanguage/Tech/News#contribute|Contribute]] • [[m:Special:MyLanguage/Tech/News/2026/13|Translate]] • [[m:Tech|Get help]] • [[m:Talk:Tech/News|Give feedback]] • [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].''
</div><section end="technews-2026-W13"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 23 mars 2026 à 17:51 (CET)
<!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30268305 -->
== Actualités techniques n° 2026-14 ==
<section begin="technews-2026-W14"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/14|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* Le version Beta de [[abstract:|Abstract Wikipedia]], un nouveau projet Wikimédia indépendant du langage, a été lancée la semaine dernière. Ce projet permet aux communautés de construire des articles Wikipédia dans leur langue natale, qui peuvent directement être lus par les autres utilisateurs et utilisatrices dans leur propre langage. Le wiki fonctionne grâce à des instructions de Wikifunctions et au contenu structuré issu de Wikidata. [[:f:Special:MyLanguage/Wikifunctions:Status updates/2026-03-26|En savoir plus]].
'''Actualités pour la contribution'''
* L'équipe Croissance mène un test A/B afin d'évaluer l'effet d'un message plus clair et plus convivial encourageant à la création de comptes sur les wikis. Actuellement, lorsqu'un utilisateur mobile non connecté lance la modification, un message d'avertissement s'affiche, pouvant paraître abrupt et décourageant. Il présente également la modification par compte temporaire comme option par défaut, au lieu d'inciter à la création d'un compte. Le test est mené sur dix Wikipédia, dont les versions en arabe, français, espagnol et allemand. [[mw:Special:MyLanguage/Contributors/Account Creation Experiments#2. Improve logged-out warning message (T415160)|En savoir plus]].
* L'équipe des applications Wikimédia sollicite vos commentaires sur [[mw:Special:MyLanguage/Wikimedia Apps/Team/Future of Editing on the Mobile Apps|comment devrait fonctionner l'édition dans les applications mobiles Wikipédia]]. La discussion porte sur l'amélioration de l'accès aux outils d'édition lorsque les utilisateurs appuient sur « Modifier ». Cette initiative s'inscrit dans un effort plus large visant à offrir aux lecteurs intéressés par la contribution une expérience utilisateur plus intuitive.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:45|la tâche soumise|les {{formatnum:45}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:45||s}} la semaine dernière]]. Par exemple, un problème avec la récupération de citations à partir du site d'archive de journaux [https://www.newspapers.com Newspapers.com], qui ne fonctionnait plus en raison d'un blocage des requêtes [[mw:Special:MyLanguage/Citoid|Citoid]], a maintenant été résolu. [https://phabricator.wikimedia.org/T419903]
'''Actualités pour la contribution technique'''
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.22|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/14|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W14"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 30 mars 2026 à 21:25 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30329462 -->
== Action Required: Update templates/modules for electoral maps (Migrating from P1846 to P14226) ==
Hello everyone,
This is a notice regarding an ongoing data migration on Wikidata that may affect your election-related templates and Lua modules (such as <code>Module:Itemgroup/list</code>).
'''The Change:'''<br />
Currently, many templates pull electoral maps from Wikidata using the property [[:d:Property:P1846|P1846]], combined with the qualifier [[:d:Property:P180|P180]]: [[:d:Q19571328|Q19571328]].
We are migrating this data (across roughly 4,000 items) to a newly created, dedicated property: '''[[:d:Property:P14226|P14226]]'''.
'''What You Need To Do:'''<br />
To ensure your templates and infoboxes do not break or lose their maps, please update your local code to fetch data from [[:d:Property:P14226|P14226]] instead of the old [[:d:Property:P1846|P1846]] + [[:d:Property:P180|P180]] structure. A [[m:Wikidata/Property Migration: P1846 to P14226/List|list of pages]] was generated using Wikimedia Global Search.
'''Deadline:'''<br />
We are temporarily retaining the old data on [[:d:Property:P1846|P1846]] to allow for a smooth transition. However, to complete the data cleanup on Wikidata, the old [[:d:Property:P1846|P1846]] statements will be removed after '''May 1, 2026'''. Please update your modules and templates before this date to prevent any disruption to your wiki's election articles.
Let us know if you have any questions or need assistance with the query logic. Thank you for your help! [[User:ZI Jony|ZI Jony]] using [[Utilisateur:MediaWiki message delivery|MediaWiki message delivery]] ([[Discussion utilisateur:MediaWiki message delivery|discussion]]) 3 avril 2026 à 19:11 (CEST)
<!-- Message envoyé par User:ZI Jony@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Non-Technical_Village_Pumps_distribution_list&oldid=29941252 -->
== Actualités techniques n° 2026-15 ==
<section begin="technews-2026-W15"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/15|D’autres traductions]] sont disponibles.
'''Actualités pour la contribution'''
* L’[[mw:Special:MyLanguage/Help:Extension:CampaignEvents|extension CampaignEvents]] comprend désormais une nouvelle fonctionnalité de définition d’objectifs de groupe, permettant aux organisateurs de définir et de suivre les objectifs de l’événement, tels que le nombre d’articles créés et de contributeurs participants en temps réel. De même, les participants peuvent travailler vers des cibles communes et voir leur impact collectif au fur et à mesure que l’événement se déroule. Cette fonctionnalité est désormais disponible sur tous les wikis Wikimedia. Pour en savoir plus, consultez [[mw:Special:MyLanguage/Help:Extension:CampaignEvents/Registration/Collaborative contributions#Goal setting|la documentation]].
* [[File:Maki-gift-15.svg|12px|link=|class=skin-invert|Concerne un souhait]] La nouvelle fonctionnalité d'[[mw:Special:MyLanguage/Help:Watchlist labels|étiquettes de liste de suivi]] (annoncée dans les [[m:Special:MyLanguage/Tech/News/2026/07|Actualités techniques 2026-07 ]]) est désormais disponible via l'ÉditeurVisuel, l'éditeur de code et l'«étoile de suivi»(ou le lien de suivi, pour les habillages qui n'ont pas d'icône d'étoile). Auparavant, il n'était possible d'attribuer des étiquettes que via [[Special:EditWatchlist|Modifier la liste de suivi]]. Dans ces trois emplacements, il s'agit d'un nouveau champ situé après le champ d'expiration.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:23|la tâche soumise|les {{formatnum:23}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:23||s}} la semaine dernière]]. Par exemple, le problème où les pages de discussion sur mobile avec Parsoid sont inutilisables après les en-têtes de section vides, a maintenant été résolu. [https://phabricator.wikimedia.org/T419171]
'''Actualités pour la contribution technique'''
* La [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|fonctionnalité de sous-référencement]], qui permet aux contributeurs d'ajouter des détails à une référence existante sans la dupliquer, sera progressivement déployée sur [[phab:T414094|davantage de wikis]] plus tard cette année. Les wikis utilisant le gadget [[mw:Special:MyLanguage/Reference Tooltips|Reference Tooltips]] sont encouragés à mettre à jour leur version (généralement sur [[m:MediaWiki:Gadget-ReferenceTooltips.js|MediaWiki:Gadget-ReferenceTooltips.js]] comme indiqué [https://en.wikipedia.org/w/index.php?diff=1344408362 ici]) pour assurer la compatibilité. D'autres gadgets liés aux références pourraient également être affectés. [https://phabricator.wikimedia.org/T416304]
* Toutes les éditions de Wikinews seront fermées et passeront en mode lecture seule le 4 mai 2026. Le contenu restera accessible, mais aucune nouvelle modification ni aucun nouvel article ne pourra être ajouté. Cette fermeture a été approuvée par le Conseil d'administration de la Fondation Wikimedia à la suite de discussions prolongées. [[m:Wikimedia Foundation Board noticeboard#Board of Trustees Approves Closure of Wikinews|En savoir plus]].
* L'[[:mw:Special:MyLanguage/API:Action API|API d'action]] a proposé plusieurs formats pour les résultats demandés. L'un d'entre eux, <bdi lang="zxx" dir="ltr"><code><nowiki>format=php</nowiki></code></bdi>, sera bientôt supprimé. Veuillez vous assurer que vos scripts ou robots utilisent le [[mw:Special:MyLanguage/API:Data formats#Output|format JSON]]. Cette suppression devrait affecter très peu de scripts et de robots. [https://phabricator.wikimedia.org/T118538]
* La page [[Special:NamespaceInfo|Special:NamespaceInfo]] inclut désormais les alias d'espace de noms. Par exemple «WP» pour l'espace de noms ''Projet'' (''Wikipédia'') sur la Wikipédia en allemand. [https://phabricator.wikimedia.org/T381455]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.23|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/15|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W15"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 6 avril 2026 à 18:19 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30362761 -->
== <span lang="en" dir="ltr">Tech News: 2026-16</span> ==
<div lang="en" dir="ltr">
<section begin="technews-2026-W16"/><div class="plainlinks">
Latest '''[[m:Special:MyLanguage/Tech/News|tech news]]''' from the Wikimedia technical community. Please tell other users about these changes. Not all changes will affect you. [[m:Special:MyLanguage/Tech/News/2026/16|Translations]] are available.
'''Weekly highlight'''
* Experienced editors are invited to [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Main_Page test] the [[mw:Special:MyLanguage/Article guidance|Article guidance]] feature, designed to help less-experienced editors create well-structured, policy-compliant Wikipedia articles. Testing instructions are [[mw:Special:MyLanguage/Article guidance/Test feature guide|available]]. Also, after reviewing [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Category:Pages_using_article_guidance the outlines], please provide feedback on the [[mw:Talk:Article guidance|project talk page]]. Based on your input, the feature will be refined and transferred to the pilot Wikipedias to translate and adapt. Check out [[c:File:Article Guidance workflow demo - April 2026.webm|the video]] explaining the feature.
'''Updates for editors'''
* On most wikis, all autoconfirmed users can now use [[Special:ChangeContentModel|Special:ChangeContentModel]] page to [[mw:Special:MyLanguage/Help:ChangeContentModel|create new pages with custom content models]], such as mass message lists, making custom page formats more accessible. Check [[Special:ListGroupRights|Special:ListGroupRights]] for the status of your wiki. [https://phabricator.wikimedia.org/T248294]
* The Growth team has launched an [[mw:Special:MyLanguage/Contributors/Account_Creation_Experiments|account creation experiment]] to evaluate whether adding an account creation button to the mobile web header increases new account registrations and encourages more mobile users to contribute to the wikis. The experiment is currently live on Hindi, Indonesian, Bengali, Thai, and Hebrew Wikipedia, and targets 10% of logged-out mobile web users.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] View all {{formatnum:30}} community-submitted {{PLURAL:30|task|tasks}} that were [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|resolved last week]]. For example, an issue where VisualEditor could get stuck loading on Windows devices with animations turned off, has now been fixed. [https://phabricator.wikimedia.org/T382856]
'''Updates for technical contributors'''
* Starting later this week, {{int:group-abusefilter}} who have the [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]] beta feature enabled will have [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] instead of [[mw:Special:MyLanguage/Extension:CodeEditor|CodeEditor]] as the editor at [[Special:AbuseFilter|Special:AbuseFilter]]. This is part of the broader effort to make the user experience more consistent across all editors. [https://phabricator.wikimedia.org/T399673][https://phabricator.wikimedia.org/T419332]
* Tools and bots that access the [[mw:Special:MyLanguage/Notifications/API|Notifications API]] (<bdi lang="zxx" dir="ltr"><code><nowiki>action=query&meta=notifications</nowiki></code></bdi>) will need to update their OAuth or BotPassword grants to also include access to private notifications. [https://phabricator.wikimedia.org/T421991]
* Due to a library upgrade, listings on category pages may be displayed out of order starting on Monday, 20th April. A migration script will be run to correct this, and will take hours to days depending on the size of the wiki (up to a week for English Wikipedia). [https://phabricator.wikimedia.org/T422544]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Recurrent item]] Detailed code updates later this week: [[mw:MediaWiki 1.46/wmf.24|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Tech news]]''' prepared by [[m:Special:MyLanguage/Tech/News/Writers|Tech News writers]] and posted by [[m:Special:MyLanguage/User:MediaWiki message delivery|bot]] • [[m:Special:MyLanguage/Tech/News#contribute|Contribute]] • [[m:Special:MyLanguage/Tech/News/2026/16|Translate]] • [[m:Tech|Get help]] • [[m:Talk:Tech/News|Give feedback]] • [[m:Global message delivery/Targets/Tech ambassadors|Subscribe or unsubscribe]].''
</div><section end="technews-2026-W16"/>
</div>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 13 avril 2026 à 17:19 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30380527 -->
== Actualités techniques n° 2026-17 ==
<section begin="technews-2026-W17"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/17|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* Après deux ans de développement, la version [[mw:Special:MyLanguage/Help:Extension:CodeMirror|{{int:codemirror-beta-feature-title}}]], également connue sous le nom de [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror 6]], sortira de sa phase bêta le mardi 21 avril. Elle offrira une meilleure lisibilité du code et du wikitext, une réduction des fautes de frappe et d'autres [[mw:Special:MyLanguage/Help:Extension:CodeMirror|avantages]] à tous les utilisateurs du surligneur de syntaxe standard. Un grand merci au bénévole [https://phabricator.wikimedia.org/p/Bhsd/ Bhsd] qui a développé de nombreuses nouvelles fonctionnalités, notamment [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Code folding|le repliement de code]], [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Autocompletion|la saisie semi-automatique]] et [[mw:Special:MyLanguage/Help:Extension:CodeMirror#Linting|l'analyse statique du code]]. [https://phabricator.wikimedia.org/T259059]
* Une mise à jour majeure de l'application Wikipédia pour iOS est en cours de déploiement, en restructurant l'interface pour s'harmoniser avec le tout nouveau design visuel "Liquid Glass" d'Apple. [https://apps.apple.com/us/app/wikipedia/id324715238 Télécharger la dernière version] et découvrez les nouveautés.
'''Actualités pour la contribution'''
* [[mw:Special:MyLanguage/Readers/Reader Experience/WE3.3.4 Reading lists|Les listes de lecture]] est une fonctionnalité qui permet aux lecteurs d'enregistrer des articles dans une liste pour les lire ultérieurement. Cette fonctionnalité est actuellement en version bêta sur les Wikipédias en arabe, français, indonésien, vietnamien et chinois, et activée par défaut pour tous les nouveaux comptes sur toutes les Wikipédias.
* Une expérimentation visant à étendre [[mw:Special:MyLanguage/Readers/Reader Growth/Mobile page previews|les aperçus de page au web mobile]] sera lancée la semaine du 20 avril sur les versions arabe, anglaise, française, italienne, polonaise et vietnamienne de Wikipédia. Les aperçus de page sont des fenêtres contextuelles affichant une miniature, un premier paragraphe et un lien bleu permettant d'ouvrir l'article complet, facilitant ainsi la découverte de contenu. Cette fonctionnalité est déjà disponible sur ordinateur et dans les applications. [[m:Special:MyLanguage/List of experiments in Product and Technology#Template|En savoir plus sur cette expérimentation et d'autres]].
* Sur plusieurs wikis, les contributeurs connectés qui n'ont pas [[mw:Special:MyLanguage/Help:Email confirmation|confirmé leur adresse électronique]] peuvent désormais voir une bannière les invitant à le faire. La confirmation de l'adresse électronique permet à un utilisateur de récupérer l'accès à son compte en cas de perte. [[mw:Special:MyLanguage/Product Safety and Integrity/Account Security#Encouraging users to confirm their email addresses|En savoir plus]]. [https://phabricator.wikimedia.org/T421366]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:15|la tâche soumise|les {{formatnum:15}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:15||s}} la semaine dernière]]. Par exemple, un problème qui entraînait des ralentissements lors de la modification de très grandes pages wiki dans l'éditeur wikitext de 2017, des problèmes de chargement, de prévisualisation et de défilement, ainsi que des problèmes de performance lors de la sélection, de la découpe ou du collage de contenu, a maintenant été résolu. [https://phabricator.wikimedia.org/T184857]
'''Actualités pour la contribution technique'''
* Dans le cadre de la promotion de [[mw:Special:MyLanguage/Help:Extension:CodeMirror|CodeMirror]] à partir d'une fonctionnalité bêta, tous les utilisateurs se serviront de [[mw:Special:MyLanguage/Extension:CodeMirror|CodeMirror]] au lieu de [[mw:Special:MyLanguage/Extension:CodeEditor|CodeEditor]] pour la coloration syntaxique lors de l'édition de pages de contenu JavaScript, CSS, JSON, Vue et Lua. [https://phabricator.wikimedia.org/T419332]
* <span class="mw-translate-fuzzy">Le service <code>mirrors.wikimedia.org</code> pour les utilisateurs de Debian et Ubuntu sera définitivement arrêté le 15 mai. Le matériel du serveur sera remplacé par des solutions plus performantes. Certains utilisateurs devront peut-être migrer vers un autre serveur qui ne devra prendre qu'une minute. [https://lists.wikimedia.org/hyperkitty/list/wikitech-l@lists.wikimedia.org/thread/LJYRIS4WB66HIRCAO4GIDTXCMDVZRBMA/ Vous pouvez en savoir plus].</span> [https://phabricator.wikimedia.org/T416707]
* Les tables <bdi lang="zxx" dir="ltr"><code><nowiki>image</nowiki></code></bdi> et <bdi lang="zxx" dir="ltr"><code><nowiki>oldimage</nowiki></code></bdi> seront supprimées de [[wikitech:Help:Wiki Replicas|wikireplicas]]. Si vos outils ou requêtes accèdent directement à <bdi lang="zxx" dir="ltr"><code><nowiki>image</nowiki></code></bdi> ou <bdi lang="zxx" dir="ltr"><code><nowiki>oldimage</nowiki></code></bdi>, veuillez les mettre à jour pour utiliser les tables <bdi lang="zxx" dir="ltr"><code><nowiki>file</nowiki></code></bdi> et <bdi lang="zxx" dir="ltr"><code><nowiki>filerevision</nowiki></code></bdi> avant le 28 mai. [https://phabricator.wikimedia.org/T28741]
* Suite à la récente mise en place de limites de débit globales pour les API non identifiées, la Fondation Wikimedia poursuit ses efforts pour garantir [[mw:Special:MyLanguage/MediaWiki Product Insights/Responsible Reuse|une utilisation équitable de l'infrastructure]] en appliquant des limites globales au trafic des API identifiées à partir de la dernière semaine d'avril. Ces limites sont volontairement fixées au niveau le plus élevé possible afin de minimiser l'impact sur la communauté. Les bots exécutés dans Toolforge/WMCS ou disposant des droits d'utilisateur de bot sur un wiki ne devraient pas être affectés pour le moment. Toutefois, il est conseillé à tous les développeurs de suivre les bonnes pratiques mises à jour. Pour plus d'informations, consultez la page [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|API Wikimedia/Limites de débit]] et la [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits/FAQ|Foire aux questions]].
* L'[[mw:Special:MyLanguage/Attribution API|API d'attribution]] est désormais disponible en [[mw:Special:MyLanguage/Wikimedia APIs/Stability policy|version bêta]]. Elle récupère les informations nécessaires pour créditer les articles et les fichiers multimédias de Wikimedia, quel que soit leur lieu d'utilisation. La documentation de référence est disponible sur la page dédiée au Sandbox REST, accessible sur tous les wikis Wikimedia (comme [https://en.wikipedia.org/w/index.php?api=attribution.v0-beta&title=Special%3ARestSandbox le sandbox REST de Wikipédia en anglais]). N'hésitez pas à partager vos commentaires sur la [[mw:Talk:Attribution API|page de discussion du projet]].
* Il n'y aura pas de nouvelle version de MediaWiki cette semaine.
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/17|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W17"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 20 avril 2026 à 17:00 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30432763 -->
== Request for comment (global AI policy) ==
<bdi lang="en" dir="ltr" class="mw-content-ltr">
Apologies for writing in English. {{int:Please-translate}}
A [[:m:Requests for comment/Artificial intelligence policy|request for comment]] is currently being held to decide on a global AI policy. {{int:Feedback-thanks-title}}
[[Utilisateur:MediaWiki message delivery|MediaWiki message delivery]] ([[Discussion utilisateur:MediaWiki message delivery|discussion]]) 26 avril 2026 à 02:57 (CEST)
</bdi>
<!-- Message envoyé par User:Codename Noreste@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30424282 -->
== Actualités techniques n° 2026-18 ==
<section begin="technews-2026-W18"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/18|D’autres traductions]] sont disponibles.
'''Actualités pour la contribution'''
* Un changement dans la manière dont les utilisateurs et utilisatrices sont automatiquement confirmés est en cours pour améliorer la protection contre le vandalisme. Actuellement, il suffit d’avoir un compte depuis quelques jours avec quelques contributions pour être ajouté au groupe [[{{int:grouppage-autoconfirmed/{{CONTENTLANGUAGE}}}}|{{int:group-autoconfirmed}}]]. Cette configuration tend à être exploitée par certains vandales qui créent des comptes et commencent à les utiliser après un certain temps. Pour réduire ce problème, la configuration va changer la semaine prochaine afin que l’âge du compte minimum pour être confirmé automatiquement ne soit calculé qu’à partir de la première modification, au lieu de la date d’inscription. L’âge minimum du compte restera le même, c’est seulement le point de départ pour calculer cet âge qui change. Ce changement ne sera déployé que sur les wikis qui nécessitent au moins une contribution pour satisfaire les conditions de confirmation automatique. [https://phabricator.wikimedia.org/T418484]
* Tous les utilisateurs et utilisatrices de Wikipédia avec un nouveau compte et ceux qui ont activé l’option « activer automatiquement la plupart des fonctionnalités bêta » peuvent désormais utiliser la fonctionnalité bêta de [[mw:Special:MyLanguage/Readers/Reader Experience/WE3.3.4 Reading lists|listes de lecture]] pour enregistrer des articles à lire plus tard. Cela permet d’organiser les lectures qui nous intéressent à un endroit unique pour y accéder facilement.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:30|la tâche soumise|les {{formatnum:30}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:30||s}} la semaine dernière]]. Par exemple, le problème avec les images d’infoboite qui avaient une marge intérieure immense dans Firefox a été corrigé. [https://phabricator.wikimedia.org/T423676]
'''Actualités pour la contribution technique'''
* Pour rappel, la limite globale d’accès à l’API sera appliquée cette semaine pour identifier le trafic de l’API. Le but est d’aider à garantir un [[mw:MediaWiki Product Insights/Responsible Reuse|accès équitable à l’infrastructure]]. Les robots qui s’exécutent dans Toolforge ou WMCS, ou avec le droit utilisateur ''robot'' sur les wikis, ne devraient pas être affectés pour le moment. Cependant, il est conseillé à tous les développeurs et développeuses de se conformer aux nouvelles bonnes pratiques à suivre. Pour plus d’informations, notamment la limite globale d’accès effective, consultez [[mw:Wikimedia APIs/Rate limits|la page sur la limite d’accès des API de Wikimedia]] et les [[mw:Wikimedia APIs/Rate limits/FAQ|questions-réponses]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.26|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/18|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W18"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 27 avril 2026 à 20:06 (CEST)
<!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30458046 -->
== Actualités techniques n° 2026-19 ==
<section begin="technews-2026-W19"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/19|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* L’équipe chargée des fonctionnalités de [[mw:Special:MyLanguage/Article guidance|Guidage des articles]] invite les contributeurs et contributrices expérimentés des [[mw:Special:MyLanguage/Article guidance/Pilot wikis and collaborators|Wikipédia pilotes]] (arabe, bangla, japonais, portugais, persan, turc, anglais simplifié, espagnol et français) à contribuer à la traduction et à l’adaptation des [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Category:Pages_using_article_guidance exemples de trames d’articles]. Ces trames guideront les contributeurs dans la création d’articles clairs, bien structurés et conformes aux règles lors de l’utilisation de [https://b24e11a4f1.catalyst.wmcloud.org/wiki/Special:NewArticle la fonctionnalité] dès son lancement en mai 2026. Des [[mw:Special:MyLanguage/Article guidance#Adapting a sample outline in a Wikipedia|instructions simples]] expliquant comment traduire et adapter ces trames sont disponibles.
'''Actualités pour la contribution'''
* Le [[:m:Special:MyLanguage/Product and Technology Advisory Council|Conseil consultatif sur les produits et les technologies]] a publié [[:m:Special:MyLanguage/Product and Technology Advisory Council/May 2026 draft PTAC recommendation for feedback|une proposition de recommandation]] d’une procédure type que les organisations affiliées à Wikimedia pourraient suivre pour contribuer au domaine technique. Les membres de la communauté sont invités à donner leur avis sur cette recommandation avant le 8 mai [[:m:Talk:Product and Technology Advisory Council/May 2026 draft PTAC recommendation for feedback|sur la page de discussion]].
* Le nombre de préférences de taille de la miniature disponibles dans MediaWiki va être réduit à trois options standardisées : ''petite'' (180 px), ''moyenne'' (250 px) et ''large'' (400 px), dans le cadre du travail en cours pour améliorer les performances et réduire la pression sur les services de miniatures. Par conséquent, les préférences existantes seront automatiquement adaptées à la nouvelle taille la plus proche (par exemple, les petites tailles comme 120 px ou 150 px s’afficheront à 180 px, tandis que les grandes tailles comme 300 px ou 360 px s’afficheront à 400 px). L’interface des préférences sera bientôt mise à jour pour refléter ces changements, et les utilisateurs qui souhaitent s’y opposer ou donner leur avis peuvent le faire. [https://phabricator.wikimedia.org/T424909]
* Dorénavant, même lorsqu’une permission expire automatiquement, les utilisateurs recevront une notification Echo similaire à la notification normale pour les changements de permissions. Quant au [[m:Special:MyLanguage/Global reminder bot|robot global de rappel]], il continue de prévenir les utilisateurs une semaine ''avant'' que leurs droits ne soient sur le point d’expirer, afin qu’ils puissent les faire renouveler.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:32|la tâche soumise|les {{formatnum:32}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:32||s}} la semaine dernière]]. Par exemple, le problème du sélecteur de langue ULS dans [[m:Special:Translate|Special:Translate]] qui faisait défiler verticalement alors qu’il ne devait pas, a été résolu. Auparavant, lorsque les utilisateurs ouvraient le menu déroulant « Traduire en français » et commençaient à saisir le nom d’une langue, la boîte de dialogue défilait verticalement de quelques pixels même lorsqu'il y avait suffisamment d’espace pour afficher tous les résultats. Le menu déroulant ne se déplace plus inutilement lors du filtrage des langues. [https://phabricator.wikimedia.org/T358864]
* La [[m:Special:GlobalWatchlist|liste de suivi globale]], qui vous permet de consulter vos listes de suivi provenant de plusieurs wikis sur une seule page, continue de s’améliorer. Par exemple, les listes de suivi pour les sites avec Wikibase tels que [[:d:|Wikidata]] prennent désormais en charge les éléments [[mw:Special:MyLanguage/Extension:EntitySchema|EntitySchema]] pour un meilleur suivi. Le mode Mises à jour en direct actualise désormais la page spéciale toutes les 60 secondes afin de se conformer aux [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|nouvelles limites globales d’accès à l’API]] pour une meilleure réactivité en temps réel. Par ailleurs, un bug de directionnalité du texte qui affichait les liens comme « changements 3 » au lieu de « 3 changements » dans les listes à directions mixtes a été corrigé. [https://phabricator.wikimedia.org/T415450][https://phabricator.wikimedia.org/T424422][https://phabricator.wikimedia.org/T418091]
'''Actualités pour la contribution technique'''
* La deuxième phase de [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits|limitations globales d’accès à l’API]] a été déployée pour réduire l’[[diffblog:2026/03/26/quo-vadis-crawlers-progress-and-whats-next-on-safeguarding-our-infrastructure/|impact des robots IA]] et assurer un accès équitable et durable aux ressources de Wikimedia, en donnant la priorité au trafic humain et conforme à notre mission. Les [[mw:Special:MyLanguage/Wikimedia APIs/Rate limits#Limits|limites]] ne s’appliquent plus par heure mais par minute, produisant une meilleure répartition dans les structures de trafic ainsi qu’une meilleure prévisibilité de la charge de l’API. Les utilisateurs de la communauté ne devraient pas être affectés, et aucune action n’est requise. Les premières indications montrent que certains requérants basés sur l'agent utilisateur ajustent leur comportement, et environ 64 % du trafic API automatisé a été identifié. La surveillance continue, et Wikimedia Enterprise reste disponible pour l’assistance commerciale.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.46/wmf.27|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/19|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W19"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 4 mai 2026 à 22:43 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30498077 -->
== Actualités techniques n° 2026-20 ==
<section begin="technews-2026-W20"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/20|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* La Communauté Technique a publié [[m:Special:MyLanguage/Community Wishlist/How to write a good wish|de nouvelles directives]] expliquant comment les souhaits sur la Liste de souhaits de la communauté sont triés et priorisés. La documentation vise à aider les contributeurs à rédiger des propositions plus solides en clarifiant les facteurs qui influencent les décisions de priorisation. Au-delà du nombre de votes, les directives mettent en avant des considérations telles que l'impact potentiel sur la communauté pour déterminer quels souhaits avanceront.
'''Actualités pour la contribution'''
* L'équipe de croissance des lecteurs lance une expérience pour tester une nouvelle [[mw:Special:MyLanguage/Readers/Reader_Growth/Share_Card|fonctionnalité de Partage de Carte]] qui permet aux lecteurs de créer des cartes visuellement attrayantes à partir d'articles Wikipédia ou de sections d'articles sélectionnées et de les partager en ligne, chaque carte renvoyant à l'article original afin d'aider à augmenter le lectorat et la découverte des articles. Le test A/B réservé aux mobiles ne sera disponible qu'à une partie des lecteurs sur les Wikipédia en arabe, chinois, français, vietnamien et anglais afin de mieux comprendre les habitudes de lecture et de partage, et est prévu pour commencer la semaine du 18 mai pour une durée de quatre semaines.
* Les applications Wikipedia pour Android et iOS ont récemment publié en version bêta le [[mw:Special:MyLanguage/Wikimedia_Apps/Team/25th_Birthday_Reading_Challenge|défi de lecture de 25 jours]], dans le cadre des efforts visant à stimuler l'engagement des lecteurs en encourageant les utilisateurs à atteindre des objectifs de lecture. Pour suivre leur série de lectures pendant le défi, les utilisateurs de l'application peuvent ajouter un widget avec Baby Globe à leur écran d'accueil. Le défi commence officiellement le 11 mai.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:17|la tâche soumise|les {{formatnum:17}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:17||s}} la semaine dernière]]. Par exemple, un problème où la préférence globale pour activer la coloration syntaxique dans le wikitexte pouvait s'éteindre de manière inattendue après avoir été activée a maintenant été corrigé. [https://phabricator.wikimedia.org/T425286]
'''Actualités pour la contribution technique'''
* [[File:Octicons-tools.svg|12px|link=|alt=|Sujet technique]] Le module ResourceLoader <bdi lang="zxx" dir="ltr"><code><nowiki>mediawiki.ui.input</nowiki></code></bdi>, obsolète depuis [[m:Special:MyLanguage/Tech/News/2023/39|septembre 2023]], sera supprimé cette semaine. Il existe un [[mw:Special:MyLanguage/Codex/Migrating_from_MediaWiki_UI|guide pour migrer de l’interface MediaWiki UI vers Codex]] pour tous les outils qui l’utilisent. [https://phabricator.wikimedia.org/T420125]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.47/wmf.2|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/20|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W20"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 11 mai 2026 à 21:20 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30524429 -->
== Actualités techniques n° 2026-21 ==
<section begin="technews-2026-W21"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/21|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* L'équipe de Wikipédia abstraite a identifié cinq wikis pilotes potentiels pour évaluer leur intérêt à adopter des articles abstraits sur leurs wikis. Les pilotes sont Wikipédia en Malayalam, en Bengali, en Dagbani, en Arabe et en Indonésien. La période de retour d'information sera ouverte jusqu'au 22 mai. Si votre communauté est intéressée à devenir un pilote, [[m:Talk:Abstract Wikipedia|faites-nous savoir sur Meta]].
'''Actualités pour la contribution'''
* Une expérience visant à afficher [[mw:Special:MyLanguage/Readers/Reader Experience/Reading lists|les listes de lecture]] aux lecteurs non connectés sur le web mobile sera lancée le 18 mai sur les Wikipédias Allemande, Espagnole, Italienne, Portugaise, Polonaise, Néerlandaise, Turque et Ourdou, et durera un mois. Cet effort soutient des objectifs plus larges consistant à aider les lecteurs à enregistrer et organiser des articles pour une lecture ultérieure, tout en encourageant des habitudes qui pourraient mener à de futures contributions sur Wikipédia.
* Pour prendre en charge un bouton de marquage dans la fonctionnalité bêta Liste de lecture, le menu "Outils > Action" a été mis à jour pour afficher des icônes, y compris l'indicateur en forme d'étoile de suivi qui aide les éditeurs à identifier les articles suivis temporairement. Les icônes correspondent désormais également à celles utilisées sur mobile, améliorant la cohérence entre les plateformes. Le changement est actuellement limité au menu des actions et concerne principalement les éditeurs ayant des droits d'utilisateur privilégié. [https://phabricator.wikimedia.org/T426008]
* [[mw:Special:MyLanguage/VisualEditor/Suggestion Mode|Mode de Suggestion]] a été publié en tant qu'[[w:en:A/B test|test A/B]] pour les nouveaux éditeurs sur le site mobile à [[phab:T421189|~15 Wikipédias]]. L'expérience mesurera l'impact que le Mode de Suggestion a sur la proportion de sessions d'édition sur le web mobile par des nouveaux éditeurs qui aboutissent à des modifications constructives (non annulées) des articles. L'expérience évaluera également l'impact de la fonctionnalité sur la rétention des éditeurs et surveillera les changements dans les taux d'annulation et de blocage.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:27|la tâche soumise|les {{formatnum:27}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:27||s}} la semaine dernière]]. Par exemple, un problème dans l'application Android de Wikipédia où les images pourraient parfois ne pas se charger après avoir ouvert une notification de liste de lecture recommandée, a maintenant été corrigé. [https://phabricator.wikimedia.org/T418231]
'''Actualités pour la contribution technique'''
* L'[[mw:Special:MyLanguage/Wikidata Platform|équipe de la Plateforme Wikidata]] a publié sa [[d:Special:MyLanguage/Wikidata:SPARQL query service/WDQS backend update/Backend Replacement|recommandation de remplacement du backend]] et l'[[wikitech:Wikidata Query Service/WDQS Architecture re-design|architecture technique]] qui l'accompagne pour la migration du Wikidata Query Service (WDQS) hors de Blazegraph grap. Les retours sont attendus jusqu'au 25 mai 2026, en particulier sur les éventuelles lacunes et impacts sur les cas d'utilisation avancés. Les membres de la communauté Wikidata et les utilisateurs de WDQS sont également encouragés à aider à identifier les outils et flux de travail à fort impact qui pourraient nécessiter une attention sur [[d:Wikidata:SPARQL query service/WDQS backend update/High-Impact Use Cases|cette page]]. Les retours peuvent être partagés sur la [[d:Wikidata talk:SPARQL query service/WDQS backend update|page de discussion de la migration]] ou lors de la [[d:Special:MyLanguage/Wikidata:Blazegraph Migration Office Hours|prochaine heure de bureau]]. Voir le [[d:Special:MyLanguage/Wikidata:Wikidata Platform team/Newsletter|bulletin de l'équipe WDP]] pour plus de détails.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.47/wmf.3|MediaWiki]]
'''En détails'''
* Sur les Wikipédia en anglais, en français, en japonais et quelques autres, il y a eu un [[diffblog:2025/09/02/better-detecting-bots-and-replacing-our-captcha/|essai de hCaptcha]], un service tiers de détection de robots. L'essai a montré que hCaptcha détecte et dissuade efficacement certaines activités automatisées de mauvaise foi, à la fois par lui-même et en donnant des signaux aux [[w:en:Wikipedia:Village pump (technical)/Archive 225#Introducing SuggestedInvestigations|checkusers et stewards]] pour qu'ils enquêtent. Comme les résultats étaient positifs, hCaptcha sera déployé sur toutes les wikis au cours des prochaines semaines. [[mw:Special:MyLanguage/Product Safety and Integrity/Anti-abuse signals/hCaptcha|Voir la page du projet hCaptcha]] pour des informations techniques sur la mise en œuvre et les protections de la vie privée. [[diffblog:2026/05/04/better-detecting-bots-and-replacing-our-captcha-part-2/|En savoir plus]].
* La dernière mise à jour de la Technologie communautaire est désormais disponible, avec des progrès dans plusieurs initiatives de la Liste de souhaits communautaire, y compris l'extension des listes de lecture de l'application mobile au site web, la prise en charge de nouvelles langues pour "Who Wrote That" et le Tableau de bord personnel, des améliorations du rendu 3D et des graphiques, ainsi que des travaux à venir sur le tri des pages de discussion, la lecture audio et les flux de travail d'édition. La mise à jour partage également les priorités actuelles, les tendances de l'état de la Liste de souhaits et les opportunités de retour d'information de la communauté sur les domaines de concentration futurs et le Plan annuel 2026–2027 de la Wikimedia Foundation. [[m:Special:MyLanguage/Community Wishlist/Updates#May 13, 2026: Latest updates from the Community Tech team|Lisez le bulletin d'information complet pour plus de détails]].
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/21|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W21"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 18 mai 2026 à 22:21 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30539262 -->
== Actualités techniques n° 2026-22 ==
<section begin="technews-2026-W22"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/22|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* Faisant suite à une [[mw:Special:MyLanguage/Contributors/Account Creation Experiments#LOWM|expérience fructueuse sur la création de comptes]], un message d'avertissement pour les personnes déconnectées sera déployé sur les wikis Wikimédia durant la première semaine de juin. Ce changement n'affectera que les personnes déconnectées sur l'interface web mobile qui commencent à modifier. Cette nouvelle expérience est faite pour encourager la création de comptes, tout en autorisant aux utilisateurs de modifier à l'aide de comptes temporaires. Les résultats de l'expérience ont montré une augmentation de la création de compte d'environ 27 % pour ceux ayant vu le nouveau message. Comme prévu, puisque plus de personnes créent un compte, la création de comptes temporaires a diminué de 16 %. L'expérience n'a pas montré d'autres changements sur la qualité des modifications ou sur les autres indicateurs surveillés. [https://phabricator.wikimedia.org/T424595]
'''Actualités pour la contribution'''
* Pour des raisons de sécurité, les membres de certains groupes d’utilisateurs sont [[m:Special:MyLanguage/Mandatory two-factor authentication for users with some extended rights|forcés d'avoir l'authentification à 2 facteurs]] (A2F) d'activée. Les membres de ces groupes seront dans l'impossibilité de désactiver la dernière méthode d'A2F sur leur compte, et il sera impossible d'ajouter des utilisateurs sans A2F à ces groupes. Ces utilisateurs auront toujours la possibilité d'ajouter ou d'enlever des nouvelles méthodes d'authentification, tant qu'une de ces méthodes est toujours activée. Dans les prochaines semaines, les utilisateurs sans A2F seront retirés de ces groupes. Cela s'applique entre autres aux bureaucrates. Veuillez lire les tâches liées pour les dates de déploiement. [https://phabricator.wikimedia.org/T423119][https://phabricator.wikimedia.org/T423120]
* L'[[m:Special:MyLanguage/WMDE Technical Wishes|équipe des souhaits techniques de Wikimédia Allemagne (WMDE)]] va lancer un [[w:fr:Test A/B|test A/B]] sur [[:phab:T415904|10 wikis]], pour essayer des [[m:WMDE Technical Wishes/References/Reference Previews|améliorations potentielles pour les aperçus de références]]. Cette expérience durera environ 2 semaines à la fin mai ou début juin et affectera 10 % du lectorat sur ordinateur sur les wikis participants.
* Après deux expériences fructueuses, l'équipe Croissance du lectorat déploiera une fonctionnalité de [[mw:Special:MyLanguage/Readers/Reader Growth/Image Browsing|visionnage d'images]] en bêta pour toutes les Wikipédia sur mobile le 25 mai. Cela veut dire que toutes les personnes ayant les fonctionnalités bêtas activées verront cette fonctionnalité. Les autres pourront l’activer dans leurs préférences. Cette fonctionnalité inclura un carrousel de toutes les images d'un article en haut de celui-ci, avec la possibilité pour les contributeurs d’[[mw:Readers/Reader_Growth/Image_Browsing#Phase_2.1_beta_feature|exclure des images du carrousel d'un article ou d'enlever la fonctionnalité pour l'entièreté de l'article]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:30|la tâche soumise|les {{formatnum:30}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:30||s}} la semaine dernière]]. Par exemple, les fichiers STL tridimensionnels étaient affichés incorrectement par l'extension 3D du lecteur multimédia, ce qui est maintenant corrigé. [https://phabricator.wikimedia.org/T416723]
'''Actualités pour la contribution technique'''
* Les classes CSS dépréciées <bdi lang="zxx" dir="ltr"><code><nowiki>tleft</nowiki></code></bdi> et <bdi lang="zxx" dir="ltr"><code><nowiki>tright</nowiki></code></bdi> ont été remplacées par <bdi lang="zxx" dir="ltr"><code><nowiki>floatleft</nowiki></code></bdi> et <bdi lang="zxx" dir="ltr"><code><nowiki>floatright</nowiki></code></bdi> car les premières ne fonctionnent pas correctement sur toutes les plateformes, dont l'interface web mobile et l'application mobile. Les projets se servant de ces classes sont encouragés à vérifier leur usage et à planifier leur migration. Sachez que <bdi lang="zxx" dir="ltr"><code><nowiki>floatleft</nowiki></code></bdi> et <bdi lang="zxx" dir="ltr"><code><nowiki>floatright</nowiki></code></bdi> pourraient aussi être dépréciées dans le futur, même s’il n'y a pas de calendrier défini. [[phab:T426452|En savoir plus]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.47/wmf.4|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/22|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W22"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 25 mai 2026 à 23:52 (CEST)
<!-- Message envoyé par User:Quiddity (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30584502 -->
== Votez maintenant aux élections 2026 de l'U4C ==
<section begin="announcement-content" />
Les votants éligibles sont invités à participer à l'élection 2026 du [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee|Comité de coordination du Code de conduite universel]]. De plus amples informations – notamment sur la vérification de l'éligibilité, le processus de vote, les candidats et un lien vers le scrutin – sont disponibles sur Meta à la [[m:Special:MyLanguage/Universal_Code_of_Conduct/Coordinating_Committee/Election/2026|page d'informations sur les élections de 2026]]. Le scrutin se termine le 2 juin 2026 à [https://zonestamp.toolforge.org/1780358400 00 h 00 UTC].
Veuillez voter si votre compte est éligble. Les résultats seront disponibles avant le 14 juin 2026. -- en coopération avec l'U4C.<section end="announcement-content" />
[[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) 27 mai 2026 à 19:14 (CEST)
<!-- Message envoyé par User:Keegan (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Distribution_list/Global_message_delivery&oldid=30513860 -->
== Actualités techniques n° 2026-23 ==
<section begin="technews-2026-W23"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/23|D’autres traductions]] sont disponibles.
'''Actualités pour la contribution'''
* L'équipe [[mw:Special:MyLanguage/Readers/Reader Experience|Reader Experience]] mène une expérience pour montrer la fonctionnalité [[mw:Special:MyLanguage/Readers/Reader Experience/Reading lists|listes de lecture]], qui est encore en développement, aux lecteurs non connectés sur mobile afin de tester si elle encourage la création de compte à un rythme plus élevé que le bouton watchstar. L'[[mw:Special:MyLanguage/Readers/Reader Experience/Reading lists#Experiment timeline|expérience]] a été lancée le 18 mai sur les wikis en allemand, espagnol, italien, portugais, polonais, néerlandais, turc et ourdou, et elle durera un mois.
* L'équipe Wikimedia Apps a publié la [[mw:Special:MyLanguage/Wikimedia Apps/Team/Explore Feed Refresh/Phase 1|Phase 1]] du flux d'accueil repensé pour l'application Android Beta. Le nouveau flux d'accueil comprend un onglet « Communauté » actualisé et un onglet « Pour vous » personnalisé contenant des recommandations de lecture mises à jour quotidiennement. La refonte fait partie d'un effort plus large visant à améliorer la découverte de contenu et à créer des expériences d'apprentissage plus engageantes dans les applications Wikipédia.
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:18|la tâche soumise|les {{formatnum:18}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:18||s}} la semaine dernière]]. Par exemple, un problème où les images pouvaient ne pas se charger pour certaines modifications suggérées sur [[w:Special:Homepage|Special:Homepage]], laissant la vignette bloquée dans un état de chargement, a maintenant été corrigé. [https://phabricator.wikimedia.org/T424048]
'''Actualités pour la contribution technique'''
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.47/wmf.5|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/23|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W23"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 1 juin 2026 à 23:08 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30613639 -->
== Actualités techniques n° 2026-24 ==
<section begin="technews-2026-W24"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/24|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* Wikimedia Entreprise a relevé les limites d’utilisation gratuite de ses API. La limite mensuelle de requêtes pour l’API « à la demande » (<i lang="en">On-demand</i>) est passée de {{formatnum:5000}} à {{formatnum:50000}} requêtes, tandis que celle de l’API des instantanés (<i lang="en">Snapshot</i>) est passée de 15 à 30 requêtes par mois. De plus, les instantanés de contenus structurés sont désormais accessibles aux comptes gratuits. Ces changements élargissent l’accès aux données de Wikimedia Entreprise pour les développeurs et développeuses, les chercheurs et chercheuses et les organisations qui utilisent les contenus Wikimédia. [https://enterprise.wikimedia.com/blog/enhanced-free-api]
'''Actualités pour la contribution'''
* La [[mw:Special:MyLanguage/Wikimedia_Apps/Team/Explore Feed Refresh/Phase 1|nouvelle version du Fil d’exploration]], désormais appelé « Fil d’accueil », est en cours de déploiement auprès de 50 % des utilisateurs de l’application Wikipédia pour Android. Le fil d’accueil aide le lectorat à découvrir du contenu pertinent grâce à deux nouveaux onglets : « Communauté » et « Pour vous ». L’onglet « Communauté » propose un flux défilant de contenus sélectionnés et d’actualités provenant de l’ensemble de la communauté et du mouvement Wikimédia, tandis que l’onglet « Pour vous » offre une expérience en plein écran et par glissement qui présente des contenus adaptés aux centres d’intérêt de l’utilisateur ou utilisatrice. Cette refonte s’inscrit dans le cadre d’un travail en cours visant à améliorer la découverte et à enrichir l’expérience d’apprentissage au sein de l’application Wikipédia.
* Le jeu-questionnaire quotidien [[mw:Special:MyLanguage/Wikimedia Apps/Team/iOS/"Which came first?" Game|Qu’est-ce qui est arrivé en premier ?]] est désormais disponible dans la version bêta de l’application Wikipédia pour iOS en anglais, allemand, français, portugais, russe, espagnol, arabe, chinois et turc. Le jeu s’appuie sur des événements historiques tirés de la rubrique « Éphéméride » de Wikipédia et met les lecteurs au défi de deviner lequel des deux événements s’est produit en premier. Le jeu avait déjà été lancé sur Android. Les communautés souhaitant rendre le jeu disponible dans leur langue peuvent [[mw:Special:MyLanguage/Wikimedia_Apps/Team/Games#Game availability by language|consulter les instructions et les conditions requises]].
* [[m:Special:MyLanguage/WMDE Technical Wishes/Sub-referencing|Les sous-références]], une nouvelle fonctionnalité de MediaWiki permettant aux contributeurs de réutiliser des références avec des détails différents, va commencer à être déployée sur les wikis Wikimédia après une phase pilote réussie. Le déploiement débutera le 8 juin pour la plupart des [[wikitech:Deployments/Train#Wednesday|wikis du groupe 1]] et Wikipédia en français, puis d'autres éditions linguistiques de Wikipédia bénéficieront de cette fonctionnalité au cours des prochains mois. Les communautés sont invitées à se préparer en vérifiant s’il existe des [https://translatewiki.net/w/i.php?title=Special%3ATranslate&group=ext-cite&language=en&action_source=search&filter=%21translated&optional=1&action=translate messages non traduits de l’extension Cite] dans leur langue et en passant en revue toute utilisation de l’outil [[mw:Special:MyLanguage/Reference Tooltips|Infobulles des références]], qui pourraient nécessiter des [[:phab:T416304#11668731|mises à jour]] pour prendre en charge la nouvelle fonctionnalité. Les wikis utilisant les [[mw:Special:MyLanguage/Help:Reference Previews|aperçus de référence]] n’ont aucune action à entreprendre. Les communautés peuvent également créer la [[Special:TrackingCategories|catégorie de suivi]] ''cite-tracking-category-ref-details'' en tant que catégorie cachée à l’aide de <code><nowiki>__HIDDENCAT__</nowiki></code> (ou d’un modèle dédié), et la relier à l’élément Wikidata correspondant [[d:Q129764848]]. [https://phabricator.wikimedia.org/T425662]
* L'[[mw:Special:MyLanguage/Readers/Reader Growth/Mobile page previews#Experimentation|expérience d'Aperçus de page]] sur le Web mobile a pris fin. L'équipe a décidé de ne pas déployer cette fonctionnalité après que les résultats ont montré qu'elle n'avait pas d'impact statistiquement significatif sur la fidélisation des lecteurs, l'amélioration de la fidélisation étant le principal indicateur de réussite. Les « Aperçus de page », déjà disponibles sur ordinateur et dans les applications, affichent une vignette, le premier paragraphe et un lien vers l'article complet lorsque les lecteurs cliquent sur un lien bleu. L'expérience a testé cette fonctionnalité sur le Web mobile sur six versions de Wikipédia.
* La [[mw:Special:MyLanguage/Codex/Design/Icons|bibliothèque d'icônes de l'interface utilisateur]] sera [[phab:T399175|mise à jour dans le courant de cette semaine ou la semaine prochaine]]. La plupart des quelque 300 icônes ont été légèrement peaufinées et une trentaine de nouvelles icônes ont été ajoutées. Ces modifications améliorent les icônes afin de les rendre plus cohérentes et plus compréhensibles, et d'offrir un meilleur équilibre visuel lorsqu'elles sont utilisées en groupe.
* L'interface [[mw:Special:MyLanguage/Universal Language Selector|Sélecteur universel de langue]] (ULS) de MediaWiki, qui aide les utilisateurs à sélectionner du contenu dans d'autres langues, a été mise à jour. La nouvelle version améliore la rapidité et l'accessibilité, et les utilisateurs des projets Wikimédia peuvent désormais épingler des langues pour changer de langue plus rapidement. Le déploiement sur les sites Wikimédia se fera progressivement au cours des prochaines semaines. Vous pouvez la tester dès maintenant en tant que fonctionnalité bêta en sélectionnant [[Special:Preferences#mw-prefsection-betafeatures|les fonctionnalités bêta]] dans les préférences de votre profil et partager vos commentaires sur [[mw:Special:MyLanguage/Universal Language Selector/New ULS|la page du projet]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:21|la tâche soumise|les {{formatnum:21}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:21||s}} la semaine dernière]]. Par exemple, un problème du le tableau de bord d'analyse des pages vues sur pageviews.wmcloud.org qui a arrêté de mettre à jour les données graphiques en mai 2026, affectant tous les utilisateurs, a été résolu. [https://phabricator.wikimedia.org/T427171]
'''Actualités pour la contribution technique'''
* La signature de la fonction <bdi lang="zxx" dir="ltr"><code><nowiki>mw.util.addPortletLink()</nowiki></code></bdi> a été simplifiée. Les développeurs peuvent désormais passer un objet de configuration à la place d'une liste de paramètres positionnels lors de la création de liens vers des portlets. L'ancienne signature de la fonction reste prise en charge à des fins de compatibilité ascendante. Par exemple, au lieu de : <bdi lang="zxx" dir="ltr"><code><nowiki>mw.util.addPortletLink('p-cactions', '#', 'Stub', 'ca-stubtag', 'Add a stub tag to this page');</nowiki></code></bdi>, utilisez <bdi lang="zxx" dir="ltr"><code><nowiki>mw.util.addPortletLink('p-cactions', { href: '#', text: 'Stub', id: 'ca-stubtag', tooltip: 'Add a stub tag to this page' });</nowiki></code></bdi>. Les responsables de la maintenance des scripts sont invités à passer en revue les utilisations existantes de <bdi lang="zxx" dir="ltr"><code><nowiki>addPortletLink()</nowiki></code></bdi> et à les mettre à jour si nécessaire. Cette modification sera disponible sur tous les wikis à partir du 11 juin. Merci à Gerges, bénévole de la communauté, d'avoir apporté cette amélioration. [https://phabricator.wikimedia.org/T427945]
* '''Discussion sur la liste de souhaits de la communauté''': les [[m:Special:MyLanguage/Community Wishlist/Updates#May 20, 2026: Community Tech becomes a program|changements introduits]] par les équipes Produit et Technologie visent à augmenter le nombre et la complexité des souhaits exaucés, notamment par la dissolution de l'équipe Community Tech. Ils [[m:Special:MyLanguage/Community Wishlist/Updates|mènent actuellement des discussions]] sur une [[m:Talk:Community Wishlist#Proposed direction for Wishlist|orientation proposée pour la liste de souhaits]] émanant des membres de la communauté. Cela inclut des moyens de structurer le vote annuel, un meilleur suivi des souhaits, la suppression de certains domaines prioritaires et des [[m:Special:MyLanguage/Community Wishlist/Updates|mises à jour concernant le personnel]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.47/wmf.6|MediaWiki]]
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/24|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W24"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 8 juin 2026 à 23:29 (CEST)
<!-- Message envoyé par User:STei (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30650573 -->
== Actualités techniques n° 2026-25 ==
<section begin="technews-2026-W25"/><div class="plainlinks">
Dernières '''[[m:Special:MyLanguage/Tech/News|actualités techniques]]''' de la communauté technique de Wikimedia. N’hésitez pas à informer les autres utilisateurs de ces changements. Certains changements ne vous concernent pas. [[m:Special:MyLanguage/Tech/News/2026/25|D’autres traductions]] sont disponibles.
'''En lumière cette semaine'''
* L'[[mw:Special:MyLanguage/Readers/Reader Growth|équipe chargée de la croissance du lectorat]] a lancé une fonctionnalité bêta d'[[mw:Special:MyLanguage/Readers/Reader Growth/Image Browsing|exploration des images]] sur la version mobile de toutes les Wikipédias. Cette fonctionnalité affiche un carrousel d'images en haut des articles contenant au moins trois images. Les contributeurs peuvent configurer cette fonctionnalité à l'aide des commandes suivantes : pour masquer une image spécifique sur une page, utilisez soit <code>class=notpageimage</code> pour l'exclure des aperçus miniatures, soit <code>class=noviewer</code> pour l'exclure de MediaViewer. Le carrousel peut également être désactivé complètement sur une page à l'aide du mot magique <code><nowiki>__NOMEDIAVIEWERCAROUSEL__</nowiki></code>. Pour faire des retours ou signaler des bugs, rendez-vous sur la [[mw:Talk:Readers/Reader Growth/Image Browsing|page de discussion du projet]].
* Les [[mw:Special:MyLanguage/Help:Tables#class="wikitable"|Wikitables]] peuvent désormais être [[mw:Special:MyLanguage/Help:Sortable tables#Forcing the initial sort direction|triées par ordre décroissant]] dès le premier clic en ajoutant <code dir=ltr>data-sort-order="desc"</code> à la cellule d'en-tête. Auparavant, par défaut, cliquer une première fois sur l'en-tête d'une colonne entraînait un tri par ordre croissant. Cette nouveauté offre davantage de contrôle et de flexibilité pour les Wikitables, tandis que le comportement par défaut pour les clics suivants reste inchangé. [https://phabricator.wikimedia.org/T398416]
'''Actualités pour la contribution'''
* La fonctionnalité d'[[mw:Special:MyLanguage/Article guidance|Aide à la rédaction d'articles]] est actuellement en phase de test auprès de certains contributeurs qui créent de nouveaux articles sur les Wikipédias en anglais simplifié, en français et en turc. L'expérience débutera bientôt sur les Wikipédias en arabe et en bengali également. [[w:simple:Special:NewArticle|Cette fonctionnalité]] fournit aux contributeurs des conseils élaborés par la communauté afin de les aider à créer des articles conformes aux normes communautaires. Les contributeurs expérimentés peuvent continuer à créer ou à adapter des modèles pour des types d'articles spécifiques qui sont couramment créés par des contributeurs moins expérimentés. Ces modèles guident les contributeurs moins expérimentés dans la création d'articles de haute qualité. Un guide rapide des balises utilisées dans les modèles est disponible sur [[mw:Special:MyLanguage/Article guidance/Test feature guide#Markups in outlines|cette page]]. [[w:fr:Projet:Aide à la rédaction d'articles#Liste de plans d'aide à la rédaction|Des exemples de modèles]] pouvant être adaptés, ainsi que des instructions sur la manière de les adapter, se trouvent dans [[mw:Special:MyLanguage/Article guidance#Adapting a sample outline in a Wikipedia|cette section]] de la page du projet.
* Les wikis qui souhaitent remplacer le bouton « indéfiniment » dans la page Special:Block pour les comptes temporaires (par exemple, les wikis qui bloquent les utilisateurs temporaires uniquement jusqu'à l'expiration de leur compte) pourront le faire en créant [[MediaWiki:ipb-indefinite-expiry-temporary-account]] avec la durée de blocage souhaitée. [https://phabricator.wikimedia.org/T427125]
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Voir {{PLURAL:41|la tâche soumise|les {{formatnum:41}} tâches soumises}} par la communauté [[m:Special:MyLanguage/Tech/News/Recently resolved community tasks|résolue{{PLURAL:41||s}} la semaine dernière]].
'''Actualités pour la contribution technique'''
* D'ici la fin du mois de juin, une chaîne « user-agent » valide sera requise pour les téléchargements automatisés de sauvegardes depuis le site dumps.wikimedia.org. Les requêtes automatisées fournissant une chaîne « user-agent » générique ou vide seront bloquées. Cette mesure [[phab:T400119|renforce l'application]] de la [[foundation:Special:MyLanguage/Policy:Wikimedia Foundation User-Agent Policy|politique relative à l'agent utilisateur]] en vigueur depuis longtemps. L'accès aux sauvegardes via Wikimedia Cloud Services restera inchangé.
* La mise en place des [[mw:Wikimedia APIs/Rate limits|limites de débit des API]] à l'échelle mondiale est désormais achevée ; ces limites s'appliquent à toutes les API et sont fixées aux niveaux indiqués dans la documentation pour tous les groupes. Les bots fonctionnant sur Toolforge/WMCS ou disposant du droit d'utilisateur « bot » sur n'importe quel wiki restent exemptés. Tous les bots doivent continuer à respecter les bonnes pratiques décrites dans la documentation afin d'éviter d'être soumis à des limites de débit.
* Le [https://api.wikimedia.org/wiki/Main_Page wiki du portail API] sera en lecture seule à partir de cette semaine (du 15 au 18 juin). La semaine suivante (du 22 au 25 juin), toutes les URL du wiki du portail API redirigeront vers [[mw:Wikimedia APIs|les API Wikimedia sur mediawiki.org]]. Pour en savoir plus, consultez la [[wikitech:API Portal/Deprecation|page du projet]].
* [[File:Reload icon with two arrows.svg|12px|link=|class=skin-invert|Sujet récurrent]] Détail des mises-à-jour à venir cette semaine : [[mw:MediaWiki 1.47/wmf.7|MediaWiki]]
'''Rencontres et évènements'''
* Le 17 juin à 18 h (UTC), la WMF organisera une réunion sur Discord consacrée à la revue de code. L'[[mw:Special:MyLanguage/Developer Satisfaction Survey/2026|enquête sur la satisfaction des développeurs]] nous a permis de constater que les bénévoles rencontrent des difficultés avec la revue de code, et nous souhaitons discuter de ces expériences afin de trouver des solutions concrètes. Vous pouvez rejoindre la réunion [https://discord.gg/wikipedia?event=1514727511102062664 via le serveur Discord de la communauté Wikimedia].
* La [[m:Special:MyLanguage/Conferencia Wikimedia de América Latina 2026|Conférence Wikimedia d'Amérique latine]] organisera un hackathon régional qui réunira la communauté technique du mouvement Wikimedia, notamment des développeurs, des administrateurs système, des data scientists et des utilisateurs disposant de droits étendus. Les contributeurs techniques intéressés peuvent [https://docs.google.com/forms/d/e/1FAIpQLSf4osJzTHBJjQbYJk7TMVEJjTEQv7IgtsUDfP-o-qTgeRQQxw/viewform postuler à une bourse] pour y participer jusqu'au 21 juin à minuit (heure de la Bolivie, UTC-4).
* Inscrivez-vous aux Wikimania Team Challenges pour participer à cet événement exceptionnel. Les défis par équipe se dérouleront en ligne et en présentiel les 21 et 22 juillet, avant la conférence Wikimania. Tout le monde est le bienvenu, quelles que soient ses compétences ou son inscription à Wikimania. Les équipes travailleront sur 10 défis importants visant à soutenir la communauté Wikimedia. Pour plus de détails, rendez-vous sur [[wmania:Special:MyLanguage/2026:Team challenges|la page des défis par équipe]] et [https://wikimedia.eventyay.com/wm/teamchallenges/ inscrivez-vous ici]. Les inscriptions se terminent le 20 juin à 23 h UTC.
'''''[[m:Special:MyLanguage/Tech/News|Actualités techniques]]''' préparées par les [[m:Special:MyLanguage/Tech/News/Writers|rédacteurs des actualités techniques]] et postées par [[m:Special:MyLanguage/User:MediaWiki message delivery|robot]]. [[m:Special:MyLanguage/Tech/News#contribute|Contribuer]] • [[m:Special:MyLanguage/Tech/News/2026/25|Traduire]] • [[m:Tech|Obtenir de l’aide]] • [[m:Talk:Tech/News|Donner son avis]] • [[m:Global message delivery/Targets/Tech ambassadors|S’abonner ou se désabonner]].''
</div><section end="technews-2026-W25"/>
<bdi lang="en" dir="ltr">[[User:MediaWiki message delivery|MediaWiki message delivery]]</bdi> 15 juin 2026 à 18:48 (CEST)
<!-- Message envoyé par User:UOzurumba (WMF)@metawiki en utilisant la liste sur https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Tech_ambassadors&oldid=30689604 -->
s998xecs0fxvdfbf9txbwkh7e84rq80
Wikilivres:Requêtes aux administrateurs/2026
4
83442
767797
767729
2026-06-15T20:05:23Z
JackPotte
5426
767797
wikitext
text/x-wiki
{{Wikilivres:Groupes}}
{{Wikilivres:Requêtes aux administrateurs/En-tête}}
== Demandes en souffrance ==
* '''Auteur :''' [[Utilisateur:Eihel|Eihel]] ([[Discussion utilisateur:Eihel|discussion]])
* '''Date :''' 14 juin 2026 à 16:43 (CEST)
* '''Livre / chapitre / utilisateur / message système concerné :''' [[Wikilivres:Demandes de suppression]]
* '''Requête :'''
Bonjour, Pouvez-vous répondre aux requêtes de cette page qui attendent depuis plus de onze semaines, s'il vous plaît ? —[[Utilisateur:Eihel|Eihel]] ([[Discussion utilisateur:Eihel|discussion]]) 14 juin 2026 à 16:43 (CEST)
{{État de la requête|état=traitée}}
'''Discussions :'''
Traité par VIGNERON... [[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 15 juin 2026 à 22:05 (CEST)
374a198ir4fuekn86vjwwccasf1o1w6
Latin/Vocabulaire/Verba Latina frequentissima/001-025
0
83936
767800
767783
2026-06-16T04:04:47Z
PandaMystique
119061
767800
wikitext
text/x-wiki
{{Sous-pages|[[Latin/Vocabulaire/Verba Latina frequentissima]]}}
<div style="text-align: center; font-size: 90%;">
[[#et|et]] · [[#sum|sum]] · [[#qui|qui]] · [[#in|in]] · [[#is|is]] · [[#non|non]] · [[#hic|hic]] · [[#ut|ut]] · [[#cum|cum]] · [[#si|si]] · [[#ad|ad]] · [[#quis|quis]] · [[#ille|ille]] · [[#dico|dico]] · [[#a, ab|a, ab]] · [[#sed|sed]] · [[#e, ex|e, ex]] · [[#suus|suus]] · [[#ego|ego]] · [[#tu|tu]] · [[#omnis|omnis]] · [[#ipse|ipse]] · [[#res|res]] · [[#aut|aut]] · [[#facio|facio]]
</div>
== et ==
(coni.) : et, aussi
''Exempla gradatim digesta''
# ''Puer et puella ludunt.'' (Le garçon et la fille jouent.)
# ''Senatus et populus de pace consultaverunt.'' (Le sénat et le peuple délibérèrent sur la paix.)
# ''Et legere et scribere didicit, quod paucis tum contigit.'' (Il apprit à la fois à lire et à écrire, ce qui échut alors à peu de gens.) Nota : ''et... et'' = « à la fois... et », « aussi bien... que ».
''Exempla elocutionis''
* ''Et pater et mater et filii et servi fugerunt.'' (Le père, et la mère, et les fils, et les esclaves s’enfuirent.)
*: ''Commentaire :'' la polysyndète, c’est-à-dire la répétition de ''et'' devant chaque membre, ralentit l’énoncé et fait peser chaque terme ; l’accumulation peut ainsi prendre une valeur pathétique.
* ''Veni et vidi et vici.'' (Je vins, et je vis, et je vainquis.) (d’après César)
*: ''Commentaire :'' ici ''et'' relie trois propositions, là où César écrivit sans liaison : ''veni, vidi, vici''. La coordination répétée étire le temps et donne du poids à chaque étape, au rebours de l’asyndète qui précipite. À comparer avec ''atque'', qui peut marquer une liaison plus appuyée, et avec l’enclitique ''-que'', qui unit étroitement deux termes solidaires, comme dans ''senatus populusque''. Choisir entre ''et'', ''atque'', ''-que'' et l’absence de liaison est déjà un fait de style.
== sum ==
''sum, esse, fui'' (v.) : être
''Exempla gradatim digesta''
# ''Roma magna urbs est.'' (Rome est une grande ville.)
# ''Heri domi non fui.'' (Hier, je n’étais pas chez moi.)
# ''Est sapientis nihil temere affirmare.'' (Il appartient au sage de ne rien affirmer à la légère.) Nota : ''est'' + génitif = « c’est le propre de ».
''Exempla elocutionis''
* ''Est in Sicilia fons aquae dulcis.'' (Il y a en Sicile une source d’eau douce.)
*: ''Commentaire :'' ''est'' en tête de phrase n’est pas ici une simple copule, mais un verbe d’existence, avec le sens de « il y a ». C’est une ouverture fréquente dans la description, en prose comme en poésie.
* ''Omnia praeclara rara.'' (Tout ce qui est remarquable est rare.) (Cicéron)
*: ''Commentaire :'' l’ellipse de la copule donne le ton de la maxime ; trois mots pleins, aucun mot de liaison, et l’écho sonore ''praeclara / rara'' scelle la formule.
== qui ==
''qui, quae, quod'' (pron. rel.) : qui, que
''Exempla gradatim digesta''
# ''Video puerum qui currit.'' (Je vois l’enfant qui court.)
# ''Quae dixisti, vera sunt.'' (Ce que tu as dit est vrai.)
# ''Misit legatos qui pacem peterent.'' (Il envoya des ambassadeurs pour demander la paix.) Nota : relative finale au subjonctif.
''Exempla elocutionis''
* ''Quae cum ita sint, perge quo coepisti.'' (Puisqu’il en est ainsi, poursuis dans la voie où tu t’es engagé.) (d’après Cicéron)
*: ''Commentaire :'' le relatif de liaison en tête de phrase est une articulation typique de la prose oratoire ; il rattache la phrase à ce qui précède sans employer une conjonction autonome.
* ''Urbem quam statuo vestra est.'' (La ville que je fonde est à vous.) (Virgile)
*: ''Commentaire :'' l’antécédent est attiré dans la relative : ''urbem'', attendu comme sujet de ''est'', prend le cas de ''quam''. Le tour est poétique et solennel, bien accordé à la parole d’une reine.
== in ==
(praep. + abl. / acc.) : dans, en ; vers
''Exempla gradatim digesta''
# ''In horto sumus.'' (Nous sommes dans le jardin.)
# ''In Italiam profectus est.'' (Il partit pour l’Italie.)
# ''In eo erat ut urbs caperetur.'' (On en était au point que la ville allait être prise.) Nota : ''in eo esse ut'' + subjonctif = « en être au point de », « être près de ».
''Exempla elocutionis''
* ''In foro, in curia, in templis timor erat.'' (Au forum, à la curie, dans les temples régnait la peur.)
*: ''Commentaire :'' l’anaphore de la préposition scande l’espace et suggère que la peur a gagné tous les lieux publics ; le procédé convient à l’amplification oratoire.
* ''In nova fert animus mutatas dicere formas corpora.'' (Mon esprit me porte à dire les formes changées en corps nouveaux.) (Ovide)
*: ''Commentaire :'' ''nova'' est séparé de ''corpora'' par presque tout le vers ; cette disjonction poétique fait attendre le nom et met en relief le programme même des ''Métamorphoses''.
== is ==
''is, ea, id'' (pron.) : ce, celui-ci ; lui, elle
''Exempla gradatim digesta''
# ''Puer venit; is meus amicus est.'' (Un garçon est venu ; celui-ci est mon ami.)
# ''Eius verba memoria teneo.'' (Je garde ses paroles en mémoire.)
# ''Ea est hominum natura ut libertatem cupiant.'' (Telle est la nature des hommes qu’ils désirent la liberté.) Nota : ''is... ut'' peut introduire une consécutive.
''Exempla elocutionis''
* ''Misit nuntium; is celeriter rediit.'' (Il envoya un messager ; celui-ci revint rapidement.)
*: ''Commentaire :'' ''is'' sert ici de reprise anaphorique neutre : il renvoie simplement au nom précédent, sans l’insistance de ''hic'' ni l’éloignement de ''ille''.
* ''Sibi imperare didicit, id quod difficillimum est.'' (Il apprit à se commander à lui-même, ce qui est très difficile.)
*: ''Commentaire :'' ''id quod'' reprend et évalue l’idée qui précède ; le tour convient bien à la prose morale et philosophique, lorsqu’il s’agit de souligner un paradoxe.
== non ==
(adv.) : ne... pas
''Exempla gradatim digesta''
# ''Non timeo.'' (Je n’ai pas peur.)
# ''Non omnes eadem amant.'' (Tous n’aiment pas les mêmes choses.)
# ''Non is sum qui mortis periculo terrear.'' (Je ne suis pas homme à être effrayé par le danger de mort.) Nota : ''non is qui'' + subjonctif.
''Exempla elocutionis''
* ''Non ignoro quid dicas.'' (Je n’ignore pas ce que tu veux dire.)
*: ''Commentaire :'' litote : la négation du contraire affirme plus fortement que l’affirmation directe. La formule peut être polie, ironique ou simplement prudente selon le contexte.
* ''Non vi sed consilio res gesta est.'' (C’est par la réflexion, non par la force, que l’affaire fut menée.)
*: ''Commentaire :'' ''non'' porte sur le seul mot ''vi'' et prépare l’antithèse ; la négation partielle met en relief le terme corrigé, ici ''consilio''.
== hic ==
''hic, haec, hoc'' (pron.) : ce, celui-ci
''Exempla gradatim digesta''
# ''Hic puer meus filius est.'' (Ce garçon est mon fils.)
# ''Hae litterae mihi gratissimae fuerunt.'' (Cette lettre m’a été très agréable.)
# ''Hoc unum scio: me nihil scire.'' (Je ne sais qu’une chose : que je ne sais rien.) Nota : proposition infinitive en apposition.
''Exempla elocutionis''
* ''Hic, hic est quem quaeritis.'' (Le voici, le voici, celui que vous cherchez.)
*: ''Commentaire :'' la gémination du démonstratif donne à l’énoncé une valeur fortement déictique ; l’écrit conserve comme la trace d’un geste.
* ''Hic ratione, ille cupiditate regitur.'' (Celui-ci est gouverné par la raison, celui-là par la passion.)
*: ''Commentaire :'' le couple ''hic... ille'' oppose deux figures : l’une proche du regard ou du raisonnement, l’autre tenue à distance. Il forme une armature commode pour la comparaison morale.
== ut ==
(coni. et adv.) : pour que ; comme ; de sorte que ; comment
''Exempla gradatim digesta''
# ''Ut vales?'' (Comment vas-tu ?)
# ''Edimus ut vivamus, non vivimus ut edamus.'' (Nous mangeons pour vivre, nous ne vivons pas pour manger.)
# ''Tanta tempestas fuit ut naves portum petere cogerentur.'' (La tempête fut si forte que les navires furent contraints de gagner le port.) Nota : consécutive.
''Exempla elocutionis''
* ''Ut sementem feceris, ita metes.'' (Tu récolteras selon ce que tu auras semé.) (proverbe cité par Cicéron)
*: ''Commentaire :'' le parallélisme ''ut... ita'' donne à la maxime sa netteté proverbiale ; l’image agricole rend la leçon morale immédiatement sensible.
* ''Ut saepe fortuna hominibus illudit!'' (Comme la fortune se joue souvent des hommes !)
*: ''Commentaire :'' ''ut'' exclamatif ouvre une réflexion pathétique sur le sort ; le tour convient à la plainte, à la consolation ou à la méditation morale.
== cum ==
(praep. + abl. ; coni.) : avec ; quand, puisque
''Exempla gradatim digesta''
# ''Cum patre ambulo.'' (Je me promène avec mon père.)
# ''Cum taces, consentire videris.'' (Quand tu te tais, tu sembles consentir.)
# ''Cum Romam venissem, ad te statim scripsi.'' (Comme j’étais arrivé à Rome, je t’ai aussitôt écrit.) Nota : ''cum'' historique + subjonctif plus-que-parfait.
''Exempla elocutionis''
* ''Iam nox erat, cum subito clamor oritur.'' (La nuit était déjà tombée, quand soudain un cri s’élève.)
*: ''Commentaire :'' c’est le ''cum'' dit inversum : la subordonnée porte le fait principal. Avec le présent historique, le procédé donne au récit la vivacité de la surprise.
* ''Cum tacent, clamant.'' (Leur silence est un cri.) (Cicéron)
*: ''Commentaire :'' paradoxe condensé en deux verbes antithétiques ; la brièveté fait la force de la formule.
== si ==
(coni.) : si
''Exempla gradatim digesta''
# ''Si pluit, domi maneo.'' (S’il pleut, je reste à la maison.)
# ''Si hoc feceris, te laudabo.'' (Si tu le fais, je te louerai.) Nota : futur antérieur dans la condition.
# ''Si scirem, dicerem.'' (Si je le savais, je le dirais.) Nota : irréel du présent, au subjonctif imparfait.
''Exempla elocutionis''
* ''Si dives es, time; si pauper, spera.'' (Si tu es riche, crains ; si tu es pauvre, espère.)
*: ''Commentaire :'' parallélisme antithétique avec ellipse de ''es'' dans le second membre ; la structure binaire convient au style sentencieux.
* ''O si illos dies revocare possem!'' (Ah ! si je pouvais rappeler ces jours-là !)
*: ''Commentaire :'' ''o si'' + subjonctif exprime le regret irréalisable ; le tour est lyrique et élégiaque, entre le souhait et la plainte.
== ad ==
(praep. + acc.) : vers, à, auprès de
''Exempla gradatim digesta''
# ''Ad scholam eo.'' (Je vais à l’école.)
# ''Legati ad Caesarem venerunt.'' (Des ambassadeurs vinrent auprès de César.)
# ''Nulla aetas ad discendum sera est.'' (Aucun âge n’est trop tardif pour apprendre.) Nota : ''ad'' + gérondif.
''Exempla elocutionis''
* ''Ad pacem petendam legati missi sunt.'' (Des ambassadeurs furent envoyés pour demander la paix.)
*: ''Commentaire :'' ''ad'' + adjectif verbal exprime régulièrement le but ; le tour convient particulièrement à une prose officielle, administrative ou militaire.
* ''Ad unum omnes perierunt.'' (Tous périrent jusqu’au dernier.)
*: ''Commentaire :'' ''ad unum'' est une formule expressive de totalité ; le décompte aboutit à l’unité, ce qui rend la destruction plus concrète.
== quis ==
''quis, quid'' (pron. interr. et indéf.) : qui ? quoi ? quelqu’un, quelque chose
''Exempla gradatim digesta''
# ''Quis es?'' (Qui es-tu ?)
# ''Quid de hac re sentis?'' (Que penses-tu de cette affaire ?)
# ''Nescio quis venerit.'' (Je ne sais pas qui est venu.) Nota : interrogation indirecte au subjonctif.
''Exempla elocutionis''
* ''Quis hoc credat? quis ferat? quis non doleat?'' (Qui le croirait ? qui le supporterait ? qui n’en souffrirait pas ?)
*: ''Commentaire :'' triple interrogation rhétorique en anaphore ; l’orateur ne cherche pas une réponse, il transforme la question en accusation.
* ''Si quis hoc neget, erret.'' (Si quelqu’un le niait, il se tromperait.)
*: ''Commentaire :'' après ''si'', ''quis'' vaut souvent ''aliquis'' ; c’est un tour fréquent dans la prose logique et philosophique, qui envisage une objection pour l’écarter.
== ille ==
''ille, illa, illud'' (pron.) : ce, celui-là
''Exempla gradatim digesta''
# ''Ille senex sapiens est.'' (Ce vieillard est sage.)
# ''Illo tempore Roma parva erat.'' (En ce temps-là, Rome était petite.)
# ''Ille ipse Cicero, quo nemo eloquentior fuit, errare potuit.'' (Cicéron lui-même, le plus éloquent de tous, a pu se tromper.) Nota : ablatif de comparaison.
''Exempla elocutionis''
* ''Alexander ille Magnus.'' (Le fameux Alexandre le Grand.)
*: ''Commentaire :'' ''ille'' postposé au nom propre peut signifier « le célèbre » ; le démonstratif de l’éloignement devient alors démonstratif de la gloire.
* ''At ille, nihil respondens, abiit.'' (Mais lui, sans rien répondre, s’en alla.)
*: ''Commentaire :'' ''at ille'' relance le récit en changeant de personnage ; c’est une cheville narrative utile dans le dialogue rapporté.
== dico ==
''dico, dicere, dixi, dictum'' (v.) : dire
''Exempla gradatim digesta''
# ''Quid dicis?'' (Que dis-tu ?)
# ''Pauca de pace dixit.'' (Il dit quelques mots sur la paix.)
# ''Dicitur Homerus caecus fuisse.'' (On dit qu’Homère était aveugle.) Nota : construction personnelle du passif + infinitif.
''Exempla elocutionis''
* ''Est haec, ut ita dicam, servitus voluntaria.'' (C’est là, pour ainsi dire, une servitude volontaire.)
*: ''Commentaire :'' ''ut ita dicam'' sert à excuser une expression nouvelle, hardie ou approximative ; c’est une précaution fréquente dans la prose argumentative.
* ''Dictum factum.'' (Aussitôt dit, aussitôt fait.)
*: ''Commentaire :'' la juxtaposition asyndétique de deux participes mime la rapidité qu’elle énonce. Le tour relève du style proverbial et familier.
== a, ab ==
(praep. + abl.) : de, depuis ; par
''Exempla gradatim digesta''
# ''A patre laudor.'' (Je suis loué par mon père.)
# ''Ab urbe condita annos numerabant Romani.'' (Les Romains comptaient les années depuis la fondation de la ville.)
# ''Non ab re erit haec commemorare.'' (Il ne sera pas hors de propos de rappeler cela.) Nota : locution ''ab re'' = « hors de propos ».
''Exempla elocutionis''
* ''Ab amicis, non ab hostibus, deceptus est.'' (C’est par ses amis, non par ses ennemis, qu’il fut trompé.)
*: ''Commentaire :'' l’antithèse des agents, soulignée par la reprise de ''ab'', fait porter tout le poids sur ''amicis'', placé en tête ; le scandale est dans l’ordre des mots.
* ''Ab ovo usque ad mala.'' (De l’œuf jusqu’aux fruits.) (Horace)
*: ''Commentaire :'' métonymie du banquet romain, depuis l’entrée jusqu’au dessert, pour dire « du début à la fin » ; l’expression concrète et familière est mise au service de la critique littéraire.
== sed ==
(coni.) : mais
''Exempla gradatim digesta''
# ''Non hodie sed cras veniam.'' (Je viendrai non aujourd’hui, mais demain.)
# ''Pauper erat, sed honeste vivebat.'' (Il était pauvre, mais il vivait honnêtement.)
# ''Non solum fortis sed etiam prudens fuit.'' (Il fut non seulement courageux, mais encore avisé.) Nota : ''non solum... sed etiam''.
''Exempla elocutionis''
* ''Difficile est; sed temptandum.'' (C’est difficile ; mais il faut essayer.)
*: ''Commentaire :'' après la concession, ''sed'' introduit la résolution ; l’ellipse de ''est'' rend la formule plus abrupte.
* ''Non scholae sed vitae discimus.'' (Nous apprenons non pour l’école, mais pour la vie.)
*: ''Commentaire :'' formule moderne qui inverse le mot de Sénèque, ''non vitae sed scholae discimus''. L’exemple montre que le déplacement des deux datifs suffit à changer entièrement la portée de la maxime.
== e, ex ==
(praep. + abl.) : hors de, de
''Exempla gradatim digesta''
# ''Ex schola venio.'' (Je viens de l’école.)
# ''Unus ex amicis meis aegrotat.'' (Un de mes amis est malade.)
# ''Ex eo intellegi potest quanta sit vis consuetudinis.'' (On peut comprendre par là combien est grande la force de l’habitude.) Nota : interrogative indirecte.
''Exempla elocutionis''
* ''Ex parvis saepe magnae res nascuntur.'' (De petits commencements naissent souvent de grandes choses.)
*: ''Commentaire :'' l’ordre croissant ''parvis / magnae'' dessine le mouvement même de la croissance ; la phrase fait presque ce qu’elle dit.
* ''Ex vita discedo tamquam ex hospitio, non tamquam e domo.'' (Je quitte la vie comme une auberge, non comme une maison.) (Cicéron)
*: ''Commentaire :'' comparaison double ; la reprise de ''ex'' structure l’image, et l’opposition entre l’auberge et la maison condense toute une philosophie du détachement.
== suus ==
''suus, sua, suum'' (pron. poss.) : son, sa, leur (réfléchi)
''Exempla gradatim digesta''
# ''Puella suam matrem amat.'' (La jeune fille aime sa propre mère.)
# ''Milites sua sponte pugnam inierunt.'' (Les soldats engagèrent le combat de leur propre initiative.)
# ''Suum cuique tribuere iustitia est.'' (Rendre à chacun le sien, voilà la justice.) Nota : ''suum cuique'', formule juridique.
''Exempla elocutionis''
* ''Sua cuique sunt vitia.'' (Chacun a ses défauts.)
*: ''Commentaire :'' le possessif en tête, joint à ''cuique'', donne au tour une valeur distributive et gnomique ; c’est l’ordre des mots de la sentence, non de la conversation ordinaire.
* ''Inter suos mortuus est.'' (Il est mort parmi les siens.)
*: ''Commentaire :'' ''sui'', substantivé, désigne les proches, la famille ou le groupe d’appartenance ; c’est une substantivation affective, sobre et pudique, fréquente dans le style funéraire.
== ego ==
(pron.) : je, moi
''Exempla gradatim digesta''
# ''Ego sum magister.'' (Moi, je suis le maître.)
# ''Mihi crede: ego te non fallam.'' (Crois-moi : moi, je ne te tromperai pas.)
# ''Ego vero, quamquam fessus sum, laborare pergam.'' (Quant à moi, bien que je sois fatigué, je continuerai à travailler.) Nota : ''ego vero'' marque l’insistance ou la prise de position personnelle.
''Exempla elocutionis''
* ''Ego suscepi, ego gessi, ego confeci.'' (C’est moi qui ai entrepris, moi qui ai mené, moi qui ai achevé.)
*: ''Commentaire :'' le pronom sujet, normalement omis, est ici exprimé et martelé en anaphore ; la phrase prend ainsi une valeur de revendication oratoire.
* ''Non ego hoc dixi.'' (Ce n’est pas moi qui ai dit cela.)
*: ''Commentaire :'' la simple présence de ''ego'' suffit à créer le relief, puisque le latin peut se passer du pronom sujet. Exprimer le pronom, c’est déjà accentuer la personne.
== tu ==
(pron.) : tu, toi
''Exempla gradatim digesta''
# ''Tu es amicus meus.'' (Tu es mon ami.)
# ''Tibi, non aliis, hoc dico.'' (C’est à toi, non aux autres, que je dis cela.)
# ''Te duce, nihil timemus.'' (Sous ta conduite, nous ne craignons rien.) Nota : ablatif absolu sans participe.
''Exempla elocutionis''
* ''Tu, tu hoc fecisti!'' (C’est toi, oui toi, qui as fait cela !)
*: ''Commentaire :'' gémination du pronom sujet dans une apostrophe accusatrice ; la répétition mime le geste de l’orateur qui désigne le coupable.
* ''Tu, si me amas, cras veni.'' (Toi, si tu m’aimes, viens demain.)
*: ''Commentaire :'' ''si me amas'' appartient à la langue familière et épistolaire ; l’expression équivaut souvent à une prière pressante.
== omnis ==
''omnis, omne'' (adi.) : tout, chaque
''Exempla gradatim digesta''
# ''Omnes pueri ludunt.'' (Tous les enfants jouent.)
# ''Omnia mea mecum porto.'' (Je porte avec moi tout ce qui est à moi.) (mot attribué à Bias, cité par Cicéron)
# ''Omnium rerum principia parva sunt.'' (Les commencements de toutes choses sont petits.) (Cicéron)
''Exempla elocutionis''
* ''Omnia perdidit: domum, amicos, famam.'' (Il a tout perdu : sa maison, ses amis, sa réputation.)
*: ''Commentaire :'' ''omnia'' annonce l’ensemble, puis l’asyndète en donne le détail ; le passage du général à l’énumération sèche convient à la déploration.
* ''Non omnia possumus omnes.'' (Nous ne pouvons pas tous tout faire.) (Virgile)
*: ''Commentaire :'' le polyptote ''omnia / omnes'' joue sur deux formes du même adjectif-pronom ; la modestie du sens est renforcée par la densité de la formule.
== ipse ==
''ipse, ipsa, ipsum'' (pron.) : même, en personne
''Exempla gradatim digesta''
# ''Ipse hoc feci.'' (Je l’ai fait moi-même.)
# ''Consul ipse in forum venit.'' (Le consul en personne vint au forum.)
# ''Mors ipsa nihil mali habet, si animus immortalis est.'' (La mort elle-même n’a rien de mauvais, si l’âme est immortelle.) Nota : ''nihil'' + génitif partitif.
''Exempla elocutionis''
* ''Ipse dixit.'' (Le maître l’a dit.) (Cicéron, à propos des pythagoriciens)
*: ''Commentaire :'' ''ipse'', employé absolument, désigne le maître qu’il n’est même plus besoin de nommer ; Cicéron cite la formule pour railler l’argument d’autorité.
* ''Res ipsa loquitur.'' (La chose parle d’elle-même.)
*: ''Commentaire :'' formule juridique moderne en latin ; ''ipse'' supprime tout intermédiaire entre le fait et son interprétation.
== res ==
''res, rei'' (subst. f.) : chose, affaire, fait
''Exempla gradatim digesta''
# ''Haec res facilis est.'' (Cette affaire est facile.)
# ''Rem bene gessit.'' (Il a bien mené l’affaire.)
# ''In rerum natura nihil sine causa fit.'' (Dans la nature, rien ne se produit sans cause.) Nota : ''rerum natura'' = « la nature ».
''Exempla elocutionis''
* ''Rem tene, verba sequentur.'' (Tiens la chose, les mots suivront.) (formule attribuée à Caton)
*: ''Commentaire :'' antithèse fondatrice ''res / verba'', le fond et les mots ; l’impératif ''tene'', suivi du futur ''sequentur'', donne à la formule une rudesse pratique.
* ''Quanta rerum vicissitudo!'' (Quel retournement des choses !)
*: ''Commentaire :'' ''res'' au pluriel peut désigner le cours des événements ou l’état du monde ; l’exclamation nominale, sans verbe, a la brièveté d’un soupir d’historien moraliste.
== aut ==
(coni.) : ou, ou bien
''Exempla gradatim digesta''
# ''Veni aut hodie aut cras.'' (Viens aujourd’hui ou demain.)
# ''Aut verum dic aut tace.'' (Dis la vérité ou tais-toi.)
# ''Aut prodesse volunt aut delectare poetae.'' (Les poètes veulent être utiles ou plaire.) (Horace)
''Exempla elocutionis''
* ''Aut vincendum est aut moriendum.'' (Il faut vaincre ou mourir.)
*: ''Commentaire :'' alternative fermée, sans troisième voie ; le rythme binaire donne à l’ultimatum sa forme lapidaire.
* ''Aut bibat aut abeat.'' (Qu’il boive ou qu’il s’en aille.) (règle de banquet citée par Cicéron)
*: ''Commentaire :'' deux subjonctifs jussifs, ''bibat'' et ''abeat'', forment une règle brève et plaisante ; le tour appartient au registre enjoué du banquet.
== facio ==
''facio, facere, feci, factum'' (v.) : faire
''Exempla gradatim digesta''
# ''Hoc bene fecisti.'' (Tu as bien fait cela.)
# ''Iter per montes fecimus.'' (Nous avons fait route à travers les montagnes.)
# ''Non possum facere quin te admoneam.'' (Je ne peux pas m’empêcher de t’avertir.) Nota : ''non possum facere quin'' + subjonctif.
''Exempla elocutionis''
* ''Quod factum est, infectum fieri non potest.'' (Ce qui est fait ne peut être défait.)
*: ''Commentaire :'' le jeu ''factum / infectum / fieri'' enferme la pensée dans l’irréversible ; la forme même de la phrase renforce la maxime.
* ''Sapientiam magni facio, divitias parvi.'' (Je fais grand cas de la sagesse, peu de cas des richesses.)
*: ''Commentaire :'' ''facere'' + génitif de prix ou d’estime ; les deux génitifs antithétiques, ''magni'' et ''parvi'', suffisent, sans répétition du verbe. L’économie produit la symétrie.
{{AutoCat}}
{{#invoke:Sous-Page|sousPage|taille préfixe=0.7em|taille titre=115%|italique=non}}
3vobmvr392pz5xmglvqqhxn2ppgib4a
767801
767800
2026-06-16T04:05:08Z
PandaMystique
119061
767801
wikitext
text/x-wiki
{{Sous-pages|Latin/Vocabulaire/Verba Latina frequentissima}}
<div style="text-align: center; font-size: 90%;">
[[#et|et]] · [[#sum|sum]] · [[#qui|qui]] · [[#in|in]] · [[#is|is]] · [[#non|non]] · [[#hic|hic]] · [[#ut|ut]] · [[#cum|cum]] · [[#si|si]] · [[#ad|ad]] · [[#quis|quis]] · [[#ille|ille]] · [[#dico|dico]] · [[#a, ab|a, ab]] · [[#sed|sed]] · [[#e, ex|e, ex]] · [[#suus|suus]] · [[#ego|ego]] · [[#tu|tu]] · [[#omnis|omnis]] · [[#ipse|ipse]] · [[#res|res]] · [[#aut|aut]] · [[#facio|facio]]
</div>
== et ==
(coni.) : et, aussi
''Exempla gradatim digesta''
# ''Puer et puella ludunt.'' (Le garçon et la fille jouent.)
# ''Senatus et populus de pace consultaverunt.'' (Le sénat et le peuple délibérèrent sur la paix.)
# ''Et legere et scribere didicit, quod paucis tum contigit.'' (Il apprit à la fois à lire et à écrire, ce qui échut alors à peu de gens.) Nota : ''et... et'' = « à la fois... et », « aussi bien... que ».
''Exempla elocutionis''
* ''Et pater et mater et filii et servi fugerunt.'' (Le père, et la mère, et les fils, et les esclaves s’enfuirent.)
*: ''Commentaire :'' la polysyndète, c’est-à-dire la répétition de ''et'' devant chaque membre, ralentit l’énoncé et fait peser chaque terme ; l’accumulation peut ainsi prendre une valeur pathétique.
* ''Veni et vidi et vici.'' (Je vins, et je vis, et je vainquis.) (d’après César)
*: ''Commentaire :'' ici ''et'' relie trois propositions, là où César écrivit sans liaison : ''veni, vidi, vici''. La coordination répétée étire le temps et donne du poids à chaque étape, au rebours de l’asyndète qui précipite. À comparer avec ''atque'', qui peut marquer une liaison plus appuyée, et avec l’enclitique ''-que'', qui unit étroitement deux termes solidaires, comme dans ''senatus populusque''. Choisir entre ''et'', ''atque'', ''-que'' et l’absence de liaison est déjà un fait de style.
== sum ==
''sum, esse, fui'' (v.) : être
''Exempla gradatim digesta''
# ''Roma magna urbs est.'' (Rome est une grande ville.)
# ''Heri domi non fui.'' (Hier, je n’étais pas chez moi.)
# ''Est sapientis nihil temere affirmare.'' (Il appartient au sage de ne rien affirmer à la légère.) Nota : ''est'' + génitif = « c’est le propre de ».
''Exempla elocutionis''
* ''Est in Sicilia fons aquae dulcis.'' (Il y a en Sicile une source d’eau douce.)
*: ''Commentaire :'' ''est'' en tête de phrase n’est pas ici une simple copule, mais un verbe d’existence, avec le sens de « il y a ». C’est une ouverture fréquente dans la description, en prose comme en poésie.
* ''Omnia praeclara rara.'' (Tout ce qui est remarquable est rare.) (Cicéron)
*: ''Commentaire :'' l’ellipse de la copule donne le ton de la maxime ; trois mots pleins, aucun mot de liaison, et l’écho sonore ''praeclara / rara'' scelle la formule.
== qui ==
''qui, quae, quod'' (pron. rel.) : qui, que
''Exempla gradatim digesta''
# ''Video puerum qui currit.'' (Je vois l’enfant qui court.)
# ''Quae dixisti, vera sunt.'' (Ce que tu as dit est vrai.)
# ''Misit legatos qui pacem peterent.'' (Il envoya des ambassadeurs pour demander la paix.) Nota : relative finale au subjonctif.
''Exempla elocutionis''
* ''Quae cum ita sint, perge quo coepisti.'' (Puisqu’il en est ainsi, poursuis dans la voie où tu t’es engagé.) (d’après Cicéron)
*: ''Commentaire :'' le relatif de liaison en tête de phrase est une articulation typique de la prose oratoire ; il rattache la phrase à ce qui précède sans employer une conjonction autonome.
* ''Urbem quam statuo vestra est.'' (La ville que je fonde est à vous.) (Virgile)
*: ''Commentaire :'' l’antécédent est attiré dans la relative : ''urbem'', attendu comme sujet de ''est'', prend le cas de ''quam''. Le tour est poétique et solennel, bien accordé à la parole d’une reine.
== in ==
(praep. + abl. / acc.) : dans, en ; vers
''Exempla gradatim digesta''
# ''In horto sumus.'' (Nous sommes dans le jardin.)
# ''In Italiam profectus est.'' (Il partit pour l’Italie.)
# ''In eo erat ut urbs caperetur.'' (On en était au point que la ville allait être prise.) Nota : ''in eo esse ut'' + subjonctif = « en être au point de », « être près de ».
''Exempla elocutionis''
* ''In foro, in curia, in templis timor erat.'' (Au forum, à la curie, dans les temples régnait la peur.)
*: ''Commentaire :'' l’anaphore de la préposition scande l’espace et suggère que la peur a gagné tous les lieux publics ; le procédé convient à l’amplification oratoire.
* ''In nova fert animus mutatas dicere formas corpora.'' (Mon esprit me porte à dire les formes changées en corps nouveaux.) (Ovide)
*: ''Commentaire :'' ''nova'' est séparé de ''corpora'' par presque tout le vers ; cette disjonction poétique fait attendre le nom et met en relief le programme même des ''Métamorphoses''.
== is ==
''is, ea, id'' (pron.) : ce, celui-ci ; lui, elle
''Exempla gradatim digesta''
# ''Puer venit; is meus amicus est.'' (Un garçon est venu ; celui-ci est mon ami.)
# ''Eius verba memoria teneo.'' (Je garde ses paroles en mémoire.)
# ''Ea est hominum natura ut libertatem cupiant.'' (Telle est la nature des hommes qu’ils désirent la liberté.) Nota : ''is... ut'' peut introduire une consécutive.
''Exempla elocutionis''
* ''Misit nuntium; is celeriter rediit.'' (Il envoya un messager ; celui-ci revint rapidement.)
*: ''Commentaire :'' ''is'' sert ici de reprise anaphorique neutre : il renvoie simplement au nom précédent, sans l’insistance de ''hic'' ni l’éloignement de ''ille''.
* ''Sibi imperare didicit, id quod difficillimum est.'' (Il apprit à se commander à lui-même, ce qui est très difficile.)
*: ''Commentaire :'' ''id quod'' reprend et évalue l’idée qui précède ; le tour convient bien à la prose morale et philosophique, lorsqu’il s’agit de souligner un paradoxe.
== non ==
(adv.) : ne... pas
''Exempla gradatim digesta''
# ''Non timeo.'' (Je n’ai pas peur.)
# ''Non omnes eadem amant.'' (Tous n’aiment pas les mêmes choses.)
# ''Non is sum qui mortis periculo terrear.'' (Je ne suis pas homme à être effrayé par le danger de mort.) Nota : ''non is qui'' + subjonctif.
''Exempla elocutionis''
* ''Non ignoro quid dicas.'' (Je n’ignore pas ce que tu veux dire.)
*: ''Commentaire :'' litote : la négation du contraire affirme plus fortement que l’affirmation directe. La formule peut être polie, ironique ou simplement prudente selon le contexte.
* ''Non vi sed consilio res gesta est.'' (C’est par la réflexion, non par la force, que l’affaire fut menée.)
*: ''Commentaire :'' ''non'' porte sur le seul mot ''vi'' et prépare l’antithèse ; la négation partielle met en relief le terme corrigé, ici ''consilio''.
== hic ==
''hic, haec, hoc'' (pron.) : ce, celui-ci
''Exempla gradatim digesta''
# ''Hic puer meus filius est.'' (Ce garçon est mon fils.)
# ''Hae litterae mihi gratissimae fuerunt.'' (Cette lettre m’a été très agréable.)
# ''Hoc unum scio: me nihil scire.'' (Je ne sais qu’une chose : que je ne sais rien.) Nota : proposition infinitive en apposition.
''Exempla elocutionis''
* ''Hic, hic est quem quaeritis.'' (Le voici, le voici, celui que vous cherchez.)
*: ''Commentaire :'' la gémination du démonstratif donne à l’énoncé une valeur fortement déictique ; l’écrit conserve comme la trace d’un geste.
* ''Hic ratione, ille cupiditate regitur.'' (Celui-ci est gouverné par la raison, celui-là par la passion.)
*: ''Commentaire :'' le couple ''hic... ille'' oppose deux figures : l’une proche du regard ou du raisonnement, l’autre tenue à distance. Il forme une armature commode pour la comparaison morale.
== ut ==
(coni. et adv.) : pour que ; comme ; de sorte que ; comment
''Exempla gradatim digesta''
# ''Ut vales?'' (Comment vas-tu ?)
# ''Edimus ut vivamus, non vivimus ut edamus.'' (Nous mangeons pour vivre, nous ne vivons pas pour manger.)
# ''Tanta tempestas fuit ut naves portum petere cogerentur.'' (La tempête fut si forte que les navires furent contraints de gagner le port.) Nota : consécutive.
''Exempla elocutionis''
* ''Ut sementem feceris, ita metes.'' (Tu récolteras selon ce que tu auras semé.) (proverbe cité par Cicéron)
*: ''Commentaire :'' le parallélisme ''ut... ita'' donne à la maxime sa netteté proverbiale ; l’image agricole rend la leçon morale immédiatement sensible.
* ''Ut saepe fortuna hominibus illudit!'' (Comme la fortune se joue souvent des hommes !)
*: ''Commentaire :'' ''ut'' exclamatif ouvre une réflexion pathétique sur le sort ; le tour convient à la plainte, à la consolation ou à la méditation morale.
== cum ==
(praep. + abl. ; coni.) : avec ; quand, puisque
''Exempla gradatim digesta''
# ''Cum patre ambulo.'' (Je me promène avec mon père.)
# ''Cum taces, consentire videris.'' (Quand tu te tais, tu sembles consentir.)
# ''Cum Romam venissem, ad te statim scripsi.'' (Comme j’étais arrivé à Rome, je t’ai aussitôt écrit.) Nota : ''cum'' historique + subjonctif plus-que-parfait.
''Exempla elocutionis''
* ''Iam nox erat, cum subito clamor oritur.'' (La nuit était déjà tombée, quand soudain un cri s’élève.)
*: ''Commentaire :'' c’est le ''cum'' dit inversum : la subordonnée porte le fait principal. Avec le présent historique, le procédé donne au récit la vivacité de la surprise.
* ''Cum tacent, clamant.'' (Leur silence est un cri.) (Cicéron)
*: ''Commentaire :'' paradoxe condensé en deux verbes antithétiques ; la brièveté fait la force de la formule.
== si ==
(coni.) : si
''Exempla gradatim digesta''
# ''Si pluit, domi maneo.'' (S’il pleut, je reste à la maison.)
# ''Si hoc feceris, te laudabo.'' (Si tu le fais, je te louerai.) Nota : futur antérieur dans la condition.
# ''Si scirem, dicerem.'' (Si je le savais, je le dirais.) Nota : irréel du présent, au subjonctif imparfait.
''Exempla elocutionis''
* ''Si dives es, time; si pauper, spera.'' (Si tu es riche, crains ; si tu es pauvre, espère.)
*: ''Commentaire :'' parallélisme antithétique avec ellipse de ''es'' dans le second membre ; la structure binaire convient au style sentencieux.
* ''O si illos dies revocare possem!'' (Ah ! si je pouvais rappeler ces jours-là !)
*: ''Commentaire :'' ''o si'' + subjonctif exprime le regret irréalisable ; le tour est lyrique et élégiaque, entre le souhait et la plainte.
== ad ==
(praep. + acc.) : vers, à, auprès de
''Exempla gradatim digesta''
# ''Ad scholam eo.'' (Je vais à l’école.)
# ''Legati ad Caesarem venerunt.'' (Des ambassadeurs vinrent auprès de César.)
# ''Nulla aetas ad discendum sera est.'' (Aucun âge n’est trop tardif pour apprendre.) Nota : ''ad'' + gérondif.
''Exempla elocutionis''
* ''Ad pacem petendam legati missi sunt.'' (Des ambassadeurs furent envoyés pour demander la paix.)
*: ''Commentaire :'' ''ad'' + adjectif verbal exprime régulièrement le but ; le tour convient particulièrement à une prose officielle, administrative ou militaire.
* ''Ad unum omnes perierunt.'' (Tous périrent jusqu’au dernier.)
*: ''Commentaire :'' ''ad unum'' est une formule expressive de totalité ; le décompte aboutit à l’unité, ce qui rend la destruction plus concrète.
== quis ==
''quis, quid'' (pron. interr. et indéf.) : qui ? quoi ? quelqu’un, quelque chose
''Exempla gradatim digesta''
# ''Quis es?'' (Qui es-tu ?)
# ''Quid de hac re sentis?'' (Que penses-tu de cette affaire ?)
# ''Nescio quis venerit.'' (Je ne sais pas qui est venu.) Nota : interrogation indirecte au subjonctif.
''Exempla elocutionis''
* ''Quis hoc credat? quis ferat? quis non doleat?'' (Qui le croirait ? qui le supporterait ? qui n’en souffrirait pas ?)
*: ''Commentaire :'' triple interrogation rhétorique en anaphore ; l’orateur ne cherche pas une réponse, il transforme la question en accusation.
* ''Si quis hoc neget, erret.'' (Si quelqu’un le niait, il se tromperait.)
*: ''Commentaire :'' après ''si'', ''quis'' vaut souvent ''aliquis'' ; c’est un tour fréquent dans la prose logique et philosophique, qui envisage une objection pour l’écarter.
== ille ==
''ille, illa, illud'' (pron.) : ce, celui-là
''Exempla gradatim digesta''
# ''Ille senex sapiens est.'' (Ce vieillard est sage.)
# ''Illo tempore Roma parva erat.'' (En ce temps-là, Rome était petite.)
# ''Ille ipse Cicero, quo nemo eloquentior fuit, errare potuit.'' (Cicéron lui-même, le plus éloquent de tous, a pu se tromper.) Nota : ablatif de comparaison.
''Exempla elocutionis''
* ''Alexander ille Magnus.'' (Le fameux Alexandre le Grand.)
*: ''Commentaire :'' ''ille'' postposé au nom propre peut signifier « le célèbre » ; le démonstratif de l’éloignement devient alors démonstratif de la gloire.
* ''At ille, nihil respondens, abiit.'' (Mais lui, sans rien répondre, s’en alla.)
*: ''Commentaire :'' ''at ille'' relance le récit en changeant de personnage ; c’est une cheville narrative utile dans le dialogue rapporté.
== dico ==
''dico, dicere, dixi, dictum'' (v.) : dire
''Exempla gradatim digesta''
# ''Quid dicis?'' (Que dis-tu ?)
# ''Pauca de pace dixit.'' (Il dit quelques mots sur la paix.)
# ''Dicitur Homerus caecus fuisse.'' (On dit qu’Homère était aveugle.) Nota : construction personnelle du passif + infinitif.
''Exempla elocutionis''
* ''Est haec, ut ita dicam, servitus voluntaria.'' (C’est là, pour ainsi dire, une servitude volontaire.)
*: ''Commentaire :'' ''ut ita dicam'' sert à excuser une expression nouvelle, hardie ou approximative ; c’est une précaution fréquente dans la prose argumentative.
* ''Dictum factum.'' (Aussitôt dit, aussitôt fait.)
*: ''Commentaire :'' la juxtaposition asyndétique de deux participes mime la rapidité qu’elle énonce. Le tour relève du style proverbial et familier.
== a, ab ==
(praep. + abl.) : de, depuis ; par
''Exempla gradatim digesta''
# ''A patre laudor.'' (Je suis loué par mon père.)
# ''Ab urbe condita annos numerabant Romani.'' (Les Romains comptaient les années depuis la fondation de la ville.)
# ''Non ab re erit haec commemorare.'' (Il ne sera pas hors de propos de rappeler cela.) Nota : locution ''ab re'' = « hors de propos ».
''Exempla elocutionis''
* ''Ab amicis, non ab hostibus, deceptus est.'' (C’est par ses amis, non par ses ennemis, qu’il fut trompé.)
*: ''Commentaire :'' l’antithèse des agents, soulignée par la reprise de ''ab'', fait porter tout le poids sur ''amicis'', placé en tête ; le scandale est dans l’ordre des mots.
* ''Ab ovo usque ad mala.'' (De l’œuf jusqu’aux fruits.) (Horace)
*: ''Commentaire :'' métonymie du banquet romain, depuis l’entrée jusqu’au dessert, pour dire « du début à la fin » ; l’expression concrète et familière est mise au service de la critique littéraire.
== sed ==
(coni.) : mais
''Exempla gradatim digesta''
# ''Non hodie sed cras veniam.'' (Je viendrai non aujourd’hui, mais demain.)
# ''Pauper erat, sed honeste vivebat.'' (Il était pauvre, mais il vivait honnêtement.)
# ''Non solum fortis sed etiam prudens fuit.'' (Il fut non seulement courageux, mais encore avisé.) Nota : ''non solum... sed etiam''.
''Exempla elocutionis''
* ''Difficile est; sed temptandum.'' (C’est difficile ; mais il faut essayer.)
*: ''Commentaire :'' après la concession, ''sed'' introduit la résolution ; l’ellipse de ''est'' rend la formule plus abrupte.
* ''Non scholae sed vitae discimus.'' (Nous apprenons non pour l’école, mais pour la vie.)
*: ''Commentaire :'' formule moderne qui inverse le mot de Sénèque, ''non vitae sed scholae discimus''. L’exemple montre que le déplacement des deux datifs suffit à changer entièrement la portée de la maxime.
== e, ex ==
(praep. + abl.) : hors de, de
''Exempla gradatim digesta''
# ''Ex schola venio.'' (Je viens de l’école.)
# ''Unus ex amicis meis aegrotat.'' (Un de mes amis est malade.)
# ''Ex eo intellegi potest quanta sit vis consuetudinis.'' (On peut comprendre par là combien est grande la force de l’habitude.) Nota : interrogative indirecte.
''Exempla elocutionis''
* ''Ex parvis saepe magnae res nascuntur.'' (De petits commencements naissent souvent de grandes choses.)
*: ''Commentaire :'' l’ordre croissant ''parvis / magnae'' dessine le mouvement même de la croissance ; la phrase fait presque ce qu’elle dit.
* ''Ex vita discedo tamquam ex hospitio, non tamquam e domo.'' (Je quitte la vie comme une auberge, non comme une maison.) (Cicéron)
*: ''Commentaire :'' comparaison double ; la reprise de ''ex'' structure l’image, et l’opposition entre l’auberge et la maison condense toute une philosophie du détachement.
== suus ==
''suus, sua, suum'' (pron. poss.) : son, sa, leur (réfléchi)
''Exempla gradatim digesta''
# ''Puella suam matrem amat.'' (La jeune fille aime sa propre mère.)
# ''Milites sua sponte pugnam inierunt.'' (Les soldats engagèrent le combat de leur propre initiative.)
# ''Suum cuique tribuere iustitia est.'' (Rendre à chacun le sien, voilà la justice.) Nota : ''suum cuique'', formule juridique.
''Exempla elocutionis''
* ''Sua cuique sunt vitia.'' (Chacun a ses défauts.)
*: ''Commentaire :'' le possessif en tête, joint à ''cuique'', donne au tour une valeur distributive et gnomique ; c’est l’ordre des mots de la sentence, non de la conversation ordinaire.
* ''Inter suos mortuus est.'' (Il est mort parmi les siens.)
*: ''Commentaire :'' ''sui'', substantivé, désigne les proches, la famille ou le groupe d’appartenance ; c’est une substantivation affective, sobre et pudique, fréquente dans le style funéraire.
== ego ==
(pron.) : je, moi
''Exempla gradatim digesta''
# ''Ego sum magister.'' (Moi, je suis le maître.)
# ''Mihi crede: ego te non fallam.'' (Crois-moi : moi, je ne te tromperai pas.)
# ''Ego vero, quamquam fessus sum, laborare pergam.'' (Quant à moi, bien que je sois fatigué, je continuerai à travailler.) Nota : ''ego vero'' marque l’insistance ou la prise de position personnelle.
''Exempla elocutionis''
* ''Ego suscepi, ego gessi, ego confeci.'' (C’est moi qui ai entrepris, moi qui ai mené, moi qui ai achevé.)
*: ''Commentaire :'' le pronom sujet, normalement omis, est ici exprimé et martelé en anaphore ; la phrase prend ainsi une valeur de revendication oratoire.
* ''Non ego hoc dixi.'' (Ce n’est pas moi qui ai dit cela.)
*: ''Commentaire :'' la simple présence de ''ego'' suffit à créer le relief, puisque le latin peut se passer du pronom sujet. Exprimer le pronom, c’est déjà accentuer la personne.
== tu ==
(pron.) : tu, toi
''Exempla gradatim digesta''
# ''Tu es amicus meus.'' (Tu es mon ami.)
# ''Tibi, non aliis, hoc dico.'' (C’est à toi, non aux autres, que je dis cela.)
# ''Te duce, nihil timemus.'' (Sous ta conduite, nous ne craignons rien.) Nota : ablatif absolu sans participe.
''Exempla elocutionis''
* ''Tu, tu hoc fecisti!'' (C’est toi, oui toi, qui as fait cela !)
*: ''Commentaire :'' gémination du pronom sujet dans une apostrophe accusatrice ; la répétition mime le geste de l’orateur qui désigne le coupable.
* ''Tu, si me amas, cras veni.'' (Toi, si tu m’aimes, viens demain.)
*: ''Commentaire :'' ''si me amas'' appartient à la langue familière et épistolaire ; l’expression équivaut souvent à une prière pressante.
== omnis ==
''omnis, omne'' (adi.) : tout, chaque
''Exempla gradatim digesta''
# ''Omnes pueri ludunt.'' (Tous les enfants jouent.)
# ''Omnia mea mecum porto.'' (Je porte avec moi tout ce qui est à moi.) (mot attribué à Bias, cité par Cicéron)
# ''Omnium rerum principia parva sunt.'' (Les commencements de toutes choses sont petits.) (Cicéron)
''Exempla elocutionis''
* ''Omnia perdidit: domum, amicos, famam.'' (Il a tout perdu : sa maison, ses amis, sa réputation.)
*: ''Commentaire :'' ''omnia'' annonce l’ensemble, puis l’asyndète en donne le détail ; le passage du général à l’énumération sèche convient à la déploration.
* ''Non omnia possumus omnes.'' (Nous ne pouvons pas tous tout faire.) (Virgile)
*: ''Commentaire :'' le polyptote ''omnia / omnes'' joue sur deux formes du même adjectif-pronom ; la modestie du sens est renforcée par la densité de la formule.
== ipse ==
''ipse, ipsa, ipsum'' (pron.) : même, en personne
''Exempla gradatim digesta''
# ''Ipse hoc feci.'' (Je l’ai fait moi-même.)
# ''Consul ipse in forum venit.'' (Le consul en personne vint au forum.)
# ''Mors ipsa nihil mali habet, si animus immortalis est.'' (La mort elle-même n’a rien de mauvais, si l’âme est immortelle.) Nota : ''nihil'' + génitif partitif.
''Exempla elocutionis''
* ''Ipse dixit.'' (Le maître l’a dit.) (Cicéron, à propos des pythagoriciens)
*: ''Commentaire :'' ''ipse'', employé absolument, désigne le maître qu’il n’est même plus besoin de nommer ; Cicéron cite la formule pour railler l’argument d’autorité.
* ''Res ipsa loquitur.'' (La chose parle d’elle-même.)
*: ''Commentaire :'' formule juridique moderne en latin ; ''ipse'' supprime tout intermédiaire entre le fait et son interprétation.
== res ==
''res, rei'' (subst. f.) : chose, affaire, fait
''Exempla gradatim digesta''
# ''Haec res facilis est.'' (Cette affaire est facile.)
# ''Rem bene gessit.'' (Il a bien mené l’affaire.)
# ''In rerum natura nihil sine causa fit.'' (Dans la nature, rien ne se produit sans cause.) Nota : ''rerum natura'' = « la nature ».
''Exempla elocutionis''
* ''Rem tene, verba sequentur.'' (Tiens la chose, les mots suivront.) (formule attribuée à Caton)
*: ''Commentaire :'' antithèse fondatrice ''res / verba'', le fond et les mots ; l’impératif ''tene'', suivi du futur ''sequentur'', donne à la formule une rudesse pratique.
* ''Quanta rerum vicissitudo!'' (Quel retournement des choses !)
*: ''Commentaire :'' ''res'' au pluriel peut désigner le cours des événements ou l’état du monde ; l’exclamation nominale, sans verbe, a la brièveté d’un soupir d’historien moraliste.
== aut ==
(coni.) : ou, ou bien
''Exempla gradatim digesta''
# ''Veni aut hodie aut cras.'' (Viens aujourd’hui ou demain.)
# ''Aut verum dic aut tace.'' (Dis la vérité ou tais-toi.)
# ''Aut prodesse volunt aut delectare poetae.'' (Les poètes veulent être utiles ou plaire.) (Horace)
''Exempla elocutionis''
* ''Aut vincendum est aut moriendum.'' (Il faut vaincre ou mourir.)
*: ''Commentaire :'' alternative fermée, sans troisième voie ; le rythme binaire donne à l’ultimatum sa forme lapidaire.
* ''Aut bibat aut abeat.'' (Qu’il boive ou qu’il s’en aille.) (règle de banquet citée par Cicéron)
*: ''Commentaire :'' deux subjonctifs jussifs, ''bibat'' et ''abeat'', forment une règle brève et plaisante ; le tour appartient au registre enjoué du banquet.
== facio ==
''facio, facere, feci, factum'' (v.) : faire
''Exempla gradatim digesta''
# ''Hoc bene fecisti.'' (Tu as bien fait cela.)
# ''Iter per montes fecimus.'' (Nous avons fait route à travers les montagnes.)
# ''Non possum facere quin te admoneam.'' (Je ne peux pas m’empêcher de t’avertir.) Nota : ''non possum facere quin'' + subjonctif.
''Exempla elocutionis''
* ''Quod factum est, infectum fieri non potest.'' (Ce qui est fait ne peut être défait.)
*: ''Commentaire :'' le jeu ''factum / infectum / fieri'' enferme la pensée dans l’irréversible ; la forme même de la phrase renforce la maxime.
* ''Sapientiam magni facio, divitias parvi.'' (Je fais grand cas de la sagesse, peu de cas des richesses.)
*: ''Commentaire :'' ''facere'' + génitif de prix ou d’estime ; les deux génitifs antithétiques, ''magni'' et ''parvi'', suffisent, sans répétition du verbe. L’économie produit la symétrie.
{{AutoCat}}
{{#invoke:Sous-Page|sousPage|taille préfixe=0.7em|taille titre=115%|italique=non}}
m9p4fz1ex1c149vep8i47bcum9oi8ng
Latin/Vocabulaire/Verba Latina frequentissima
0
83937
767808
767787
2026-06-16T04:19:32Z
PandaMystique
119061
767808
wikitext
text/x-wiki
{{Page de garde|image=Fragmentary inscription.jpg|imagedesc=|description=
Ce manuel liste les mille mots latins les plus fréquents, classés par ordre de fréquence.
|avancement=Ébauche
|cdu=
* {{CDU item|8/807}}
|versions=
{{Moteur}}
{{version imprimable}}
}}
<blockquote>
Hoc enchiridion mille voces Latinas frequentissimas complectitur, ordine frequentiae digestas. Singulis lemmatibus tria praebentur:
# ''sensus'' (interpretatio Francogallica);
# ''exempla gradata'': tres sententiae difficultate crescente (simplex, media, difficilior), saepe cum nota grammatica;
# ''exempla stilistica'': binae sententiae cum commentario, quae ordinem verborum, figuras et genera dicendi illustrant.
: '''Conspectus signorum'''
: Exempla Latina ''litteris inclinatis'' scribuntur. Sententiae sine auctore notato a nobis compositae sunt; ceterae ex auctoribus antiquis sumptae. Nota « d’après » significat locum auctoris leviter aptatum esse, id est decurtatum aut ad rem accommodatum.
</blockquote>
----
{| class="wikitable" style="text-align: center;"
| 001-100 || [[Latin/Vocabulaire/Verba Latina frequentissima/001-025|001-025]] || [[Latin/Vocabulaire/Verba Latina frequentissima/026-050|026-050]] || [[Latin/Vocabulaire/Verba Latina frequentissima/051-075|051-075]] || [[Latin/Vocabulaire/Verba Latina frequentissima/076-100|076-100]]
|-
| 101-200 || [[Latin/Vocabulaire/Verba Latina frequentissima/101-125|101-125]] || [[Latin/Vocabulaire/Verba Latina frequentissima/126-150|126-150]] || [[Latin/Vocabulaire/Verba Latina frequentissima/151-175|151-175]] || [[Latin/Vocabulaire/Verba Latina frequentissima/176-200|176-200]]
|-
| 201-300 || [[Latin/Vocabulaire/Verba Latina frequentissima/201-225|201-225]] || [[Latin/Vocabulaire/Verba Latina frequentissima/226-250|226-250]] || [[Latin/Vocabulaire/Verba Latina frequentissima/251-275|251-275]] || [[Latin/Vocabulaire/Verba Latina frequentissima/276-300|276-300]]
|-
| 301-400 || [[Latin/Vocabulaire/Verba Latina frequentissima/301-325|301-325]] || [[Latin/Vocabulaire/Verba Latina frequentissima/326-350|326-350]] || [[Latin/Vocabulaire/Verba Latina frequentissima/351-375|351-375]] || [[Latin/Vocabulaire/Verba Latina frequentissima/376-400|376-400]]
|-
| 401-500 || [[Latin/Vocabulaire/Verba Latina frequentissima/401-425|401-425]] || [[Latin/Vocabulaire/Verba Latina frequentissima/426-450|426-450]] || [[Latin/Vocabulaire/Verba Latina frequentissima/451-475|451-475]] || [[Latin/Vocabulaire/Verba Latina frequentissima/476-500|476-500]]
|-
| 501-600 || [[Latin/Vocabulaire/Verba Latina frequentissima/501-525|501-525]] || [[Latin/Vocabulaire/Verba Latina frequentissima/526-550|526-550]] || [[Latin/Vocabulaire/Verba Latina frequentissima/551-575|551-575]] || [[Latin/Vocabulaire/Verba Latina frequentissima/576-600|576-600]]
|-
| 601-700 || [[Latin/Vocabulaire/Verba Latina frequentissima/601-625|601-625]] || [[Latin/Vocabulaire/Verba Latina frequentissima/626-650|626-650]] || [[Latin/Vocabulaire/Verba Latina frequentissima/651-675|651-675]] || [[Latin/Vocabulaire/Verba Latina frequentissima/676-700|676-700]]
|-
| 701-800 || [[Latin/Vocabulaire/Verba Latina frequentissima/701-725|701-725]] || [[Latin/Vocabulaire/Verba Latina frequentissima/726-750|726-750]] || [[Latin/Vocabulaire/Verba Latina frequentissima/751-775|751-775]] || [[Latin/Vocabulaire/Verba Latina frequentissima/776-800|776-800]]
|-
| 801-900 || [[Latin/Vocabulaire/Verba Latina frequentissima/801-825|801-825]] || [[Latin/Vocabulaire/Verba Latina frequentissima/826-850|826-850]] || [[Latin/Vocabulaire/Verba Latina frequentissima/851-875|851-875]] || [[Latin/Vocabulaire/Verba Latina frequentissima/876-900|876-900]]
|-
| 901-1000 || [[Latin/Vocabulaire/Verba Latina frequentissima/901-925|901-925]] || [[Latin/Vocabulaire/Verba Latina frequentissima/926-950|926-950]] || [[Latin/Vocabulaire/Verba Latina frequentissima/951-975|951-975]] || [[Latin/Vocabulaire/Verba Latina frequentissima/976-1000|976-1000]]
|}
== Fontes ==
Ordo frequentiae ex operibus infra laudatis ductus est; in exemplis stilisticis Marouzeau secuti sumus.
* Paul B. Diederich, ''The Frequency of Latin Words and Their Endings'', Chicago, University of Chicago Press, 1939.
* Christopher Francese, ''Latin Core Vocabulary'', Dickinson College Commentaries (fondé sur le corpus lemmatisé du LASLA, Université de Liège).
* Jerry Toner, ''Latin Key Words: The Basic 2000 Word Vocabulary Arranged by Frequency'', Cambridge, The Oleander Press, 2017.
* ''Dictionnaire latin-français : les 5000 mots et expressions les plus fréquents'', Andalus Publications, 2024.
* Mark Williams, ''Essential Latin Vocabulary'', CreateSpace, 2013.
* Jules Marouzeau, ''Traité de stylistique latine'', Paris, Les Belles Lettres, 1946 (modèle des ''exempla stilistica'').
babnf2evtjnhdm0v8r693zretbq48nx
Discussion utilisateur:Jean-Jacques MILAN/Livre d'or
3
83942
767794
767781
2026-06-15T14:21:23Z
JackPotte
5426
/* Messages d'utilisateurs */
767794
wikitext
text/x-wiki
Jean-Jacques Milan est mort le {{Date-|12|4|2026}}. Il était passionné de photo et contributeur sur 3 gros projets. Il totalisait {{unité|80000 contributions}} à travers les projets.
== Messages d'utilisateurs ==
<gallery>
File:Candleburning.jpg|Condoléances à Élise, sa femme, et toute sa famille. [[user:Eihel|Eihel]]
</gallery>
----
On a eu des débuts un peu rugueux ^^ (les torts étaient partagés) mais au final, on s'appréciait mutuellement...
[[Utilisateur:Cdang|Cdang]] ([[Discussion utilisateur:Cdang|discussion]]) 15 juin 2026 à 01:31 (CEST)
----
Sincères condoléances. [[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 15 juin 2026 à 16:21 (CEST)
r3pf01g5hhlp4mu9l2ib2kzzb07v3z3
Latin/Vocabulaire/Verba Latina frequentissima/026-050
0
83943
767806
767785
2026-06-16T04:13:19Z
PandaMystique
119061
767806
wikitext
text/x-wiki
{{Sous-pages|Latin/Vocabulaire/Verba Latina frequentissima}}
== habeo ==
''habeo, habere, habui, habitum'' (v.) : avoir, tenir
''Exempla gradatim digesta''
# ''Canem habeo.'' (J’ai un chien.)
# ''Orationem in senatu habuit.'' (Il prononça un discours au sénat.)
# ''Nihil habeo quod scribam.'' (Je n’ai rien à écrire.) Nota : relative au subjonctif après nihil.
''Exempla elocutionis''
* ''Compertum habeo.'' (Je tiens la chose pour établie.)
*: ''Commentaire :'' habere + participe parfait insiste sur le résultat acquis et possédé ; tour expressif qui annonce de loin nos temps composés romans.
* ''Habent sua fata libelli.'' (Les livres ont leur destin.) (Térentianus Maurus)
*: ''Commentaire :'' personnification des livres par le simple jeu du possessif sua ; le vers, détaché de son contexte, est devenu proverbe.
== possum ==
''possum, posse, potui'' (v.) : pouvoir
''Exempla gradatim digesta''
# ''Currere possum.'' (Je peux courir.)
# ''Hoc fieri potest.'' (Cela peut se faire.)
# ''Ut potui, feci; ut volui, non potui.'' (J’ai fait comme j’ai pu ; comme je voulais, je n’ai pas pu.)
''Exempla elocutionis''
* ''Possunt, quia posse videntur.'' (Ils peuvent, parce qu’ils croient pouvoir.) (Virgile)
*: ''Commentaire :'' polyptote possunt / posse ; la confiance crée la force, et la répétition du verbe mime ce cercle. Psychologie de la course en un hémistiche.
* ''Fieri potest ut fallar.'' (Il se peut que je me trompe.)
*: ''Commentaire :'' tour impersonnel de la prudence philosophique ; l’Académicien ne dit pas « je me trompe peut-être » mais met sa propre erreur à distance.
== video ==
''video, videre, vidi, visum'' (v.) : voir
''Exempla gradatim digesta''
# ''Stellas video.'' (Je vois les étoiles.)
# ''Videor mihi felix esse.'' (Il me semble que je suis heureux.) Nota : videor, construction personnelle.
# ''Videant consules ne quid res publica detrimenti capiat.'' (Que les consuls veillent à ce que la république ne subisse aucun dommage.) (formule sénatoriale) Nota : videre ne + subjonctif.
''Exempla elocutionis''
* ''Video meliora proboque, deteriora sequor.'' (Je vois le meilleur et je l’approuve, je suis le pire.) (Ovide)
*: ''Commentaire :'' asyndète adversative au centre du vers ; le déchirement moral (l’acrasie des philosophes) tient dans l’absence même de conjonction.
* ''Errare mihi videris.'' (Tu me sembles faire erreur.)
*: ''Commentaire :'' videor atténue l’affirmation ; l’urbanité du dialogue cultivé consiste à présenter le désaccord comme une impression.
== magnus ==
''magnus, magna, magnum'' (adi.) : grand
''Exempla gradatim digesta''
# ''Domus magna est.'' (La maison est grande.)
# ''Maior pars militum periit.'' (La plus grande partie des soldats périt.)
# ''Magni ingenii est mentem a sensibus revocare.'' (C’est le propre d’un grand esprit de détacher la pensée des sens.) Nota : est + génitif (« c’est le propre d’un grand esprit »).
''Exempla elocutionis''
* ''Magna di curant, parva neglegunt.'' (Les dieux s’occupent des grandes choses, ils négligent les petites.) (Cicéron)
*: ''Commentaire :'' double antithèse en asyndète (magna / parva, curant / neglegunt) ; la symétrie donne à la thèse théologique une allure d’évidence.
* ''Parvo fames constat, magno fastidium.'' (La faim coûte peu, le dégoût coûte cher.) (Sénèque)
*: ''Commentaire :'' ablatifs de prix antithétiques en chiasme avec leurs sujets ; morale frugale de Sénèque, où la syntaxe fait les comptes.
== deus ==
''deus, dei'' (subst. m.) : dieu
''Exempla gradatim digesta''
# ''Dei caelum tenent.'' (Les dieux occupent le ciel.)
# ''Dis hostias immolaverunt.'' (Ils immolèrent des victimes aux dieux.) Nota : dis, datif pluriel contracte.
# ''Natura ipsa docet deos esse.'' (La nature elle-même enseigne que les dieux existent.) Nota : proposition infinitive.
''Exempla elocutionis''
* ''Di immortales!'' (Dieux immortels !)
*: ''Commentaire :'' exclamation-juron du théâtre et des plaidoyers ; la forme contracte di appartient à la langue vive, dei serait livresque.
* ''Deum colit qui novit.'' (Honorer dieu, c’est le connaître.) (d’après Sénèque)
*: ''Commentaire :'' brièveté sénéquienne : relative sans antécédent, cinq mots, pointe finale ; la piété redéfinie en une formule qui tient de l’épigramme.
== do ==
''do, dare, dedi, datum'' (v.) : donner
''Exempla gradatim digesta''
# ''Panem pauperi do.'' (Je donne du pain au pauvre.)
# ''Operam litteris dedi.'' (Je me suis consacré aux lettres.) Nota : operam dare = « s’appliquer à ».
# ''Dant veniam corvis, vexat censura columbas.'' (On pardonne aux corbeaux, la censure s’acharne sur les colombes.) (Juvénal)
''Exempla elocutionis''
* ''Bis dat qui cito dat.'' (Donner vite, c’est donner deux fois.) (d’après Publilius Syrus)
*: ''Commentaire :'' reprise de dat aux deux membres, rime intérieure et rythme de sentence ; la maxime est faite pour la mémoire.
* ''Da mihi, obsecro, hanc veniam.'' (Accorde-moi, je t’en conjure, cette grâce.)
*: ''Commentaire :'' l’incise obsecro suspend la phrase entre le verbe et son objet ; registre de la prière, où le retard de l’objet ménage la supplication.
== atque, ac ==
(coni.) : et, et de plus
''Exempla gradatim digesta''
# ''Pater atque filius adsunt.'' (Le père et le fils sont présents.)
# ''Idem atque tu sentio.'' (Je pense la même chose que toi.) Nota : idem atque = « le même que ».
# ''Simul atque venit, omnia mutata sunt.'' (Dès qu’il arriva, tout changea.) Nota : simul atque = « dès que ».
''Exempla elocutionis''
* ''Difficile est, atque adeo fieri non potest.'' (C’est difficile, et même cela ne se peut pas.)
*: ''Commentaire :'' atque adeo corrige en renchérissant ; gradation rectificative de l’orateur qui feint de s’interrompre pour aller plus loin.
* ''Mens atque animus, consilium atque sententia civitatis posita est in legibus.'' (L’intelligence et l’âme, la pensée et la volonté de la cité résident dans les lois.) (d’après Cicéron)
*: ''Commentaire :'' doublets synonymiques liés par atque ; la plénitude oratoire double chaque notion, non pour préciser mais pour amplifier.
== animus ==
''animus, animi'' (subst. m.) : esprit, cœur, courage
''Exempla gradatim digesta''
# ''Animus meus laetus est.'' (Mon cœur est joyeux.)
# ''Ex animo tibi gratias ago.'' (Je te remercie de tout cœur.)
# ''Animum rege, qui nisi paret, imperat.'' (Gouverne ton cœur : s’il n’obéit pas, il commande.) (Horace)
''Exempla elocutionis''
* ''Animus aequus optimum est aerumnae condimentum.'' (Une âme égale est le meilleur assaisonnement du malheur.) (Plaute)
*: ''Commentaire :'' métaphore culinaire appliquée à la morale ; le mélange du noble et du trivial est la marque du registre comique.
* ''Corpus quasi vas est animi.'' (Le corps est comme le vase de l’âme.) (d’après Cicéron)
*: ''Commentaire :'' quasi signale la métaphore comme approximation ; précaution du philosophe qui traduit en images, utile à qui rédige un lexique de philosophie.
== multus ==
''multus, multa, multum'' (adi.) : nombreux, abondant
''Exempla gradatim digesta''
# ''Multae aves cantant.'' (Beaucoup d’oiseaux chantent.)
# ''Multa de te audivi.'' (J’ai entendu beaucoup de choses sur toi.) Nota : multa, neutre pluriel substantivé.
# ''Multum legendum est, non multa.'' (Il faut lire beaucoup, non beaucoup de choses.) (d’après Pline le Jeune)
''Exempla elocutionis''
* ''Multa paucis dicere ars est.'' (Dire beaucoup en peu de mots est un art.)
*: ''Commentaire :'' antithèse quantitative multa / paucis juxtaposée sans liaison ; l’idéal de brevitas énoncé brièvement, la forme prouvant le fond.
* ''Multis ille bonis flebilis occidit.'' (Il est mort, pleuré de bien des gens de bien.) (Horace)
*: ''Commentaire :'' disjonction multis... bonis qui enserre le vers ; le datif de point de vue fait du deuil collectif l’écrin du défunt.
== nunc ==
(adv.) : maintenant
''Exempla gradatim digesta''
# ''Nunc ludimus.'' (Maintenant nous jouons.)
# ''Nunc demum intellego.'' (Maintenant enfin je comprends.)
# ''Nunc aut numquam agendum est.'' (C’est maintenant ou jamais qu’il faut agir.) Nota : adjectif verbal impersonnel.
''Exempla elocutionis''
* ''Nunc est bibendum.'' (C’est maintenant qu’il faut boire.) (Horace)
*: ''Commentaire :'' nunc en tête, triomphal, libère la joie longtemps contenue (la mort de Cléopâtre) ; l’adverbe de temps devient cri.
* ''Nunc huc, nunc illuc currit.'' (Il court tantôt ici, tantôt là.)
*: ''Commentaire :'' anaphore alternative nunc... nunc ; la répétition peint l’agitation désordonnée, procédé descriptif élémentaire et sûr.
== etiam ==
(adv.) : aussi, même, encore
''Exempla gradatim digesta''
# ''Etiam ego venio.'' (Moi aussi je viens.)
# ''Non solum audivit, sed etiam vidit.'' (Il n’a pas seulement entendu, il a même vu.)
# ''Etiam capillus unus habet umbram suam.'' (Même un seul cheveu a son ombre.) (Publilius Syrus)
''Exempla elocutionis''
* ''Etiam atque etiam rogo.'' (Je le demande instamment.)
*: ''Commentaire :'' gémination figée etiam atque etiam, insistance codifiée de la langue épistolaire ; la politesse romaine répète au lieu d’intensifier.
* ''Non modo pecuniam verum etiam vitam pro patria dedit.'' (Il a donné pour la patrie non seulement son argent mais encore sa vie.)
*: ''Commentaire :'' gradation pleine non modo... verum etiam ; l’ordre croissant des sacrifices est obligatoire, l’inverser serait ridicule.
== per ==
(praep. + acc.) : à travers, par, pendant
''Exempla gradatim digesta''
# ''Per viam ambulo.'' (Je marche sur la route.)
# ''Per totam noctem vigilavit.'' (Il veilla pendant toute la nuit.)
# ''Per me licet: fac quod vis.'' (Pour ma part, je n’y vois pas d’obstacle : fais ce que tu veux.) Nota : per me licet, locution.
''Exempla elocutionis''
* ''Per deos immortales te obtestor!'' (Au nom des dieux immortels, je t’en conjure !)
*: ''Commentaire :'' per du serment et de l’adjuration ; la préposition spatiale devient l’opérateur du sacré. Pathos judiciaire et tragique.
* ''Per varios casus, per tot discrimina rerum tendimus in Latium.'' (À travers tant de hasards, à travers tant de périls, nous marchons vers le Latium.) (Virgile)
*: ''Commentaire :'' anaphore de per qui scande les épreuves ; l’épopée avance préposition par préposition, et le but (in Latium) n’arrive qu’à la fin.
== alius ==
''alius, alia, aliud'' (pron.) : autre
''Exempla gradatim digesta''
# ''Alius puer venit.'' (Un autre garçon vient.)
# ''Alii legunt, alii scribunt.'' (Les uns lisent, les autres écrivent.)
# ''Aliud est dicere, aliud facere.'' (Autre chose est de dire, autre chose de faire.) Nota : aliud... aliud distributif.
''Exempla elocutionis''
* ''Alii aliis subsidium ferunt.'' (Ils se portent secours les uns aux autres.) (d’après César)
*: ''Commentaire :'' tour distributif alius alii, d’une densité intraduisible ; le latin condense en deux mots ce que le français étale en sept.
* ''Aliud clausum in pectore, aliud in lingua promptum habent.'' (Ils ont une chose enfermée dans le cœur, une autre toute prête sur la langue.) (Salluste)
*: ''Commentaire :'' antithèse pectore / lingua portée par l’anaphore de aliud ; la duplicité peinte par la symétrie même de la phrase. Style moraliste de Salluste.
== ne ==
(coni. + subi.) : pour que... ne pas ; de peur que
''Exempla gradatim digesta''
# ''Ne timeas!'' (N’aie pas peur !) Nota : défense au subjonctif.
# ''Moneo te ne hoc facias.'' (Je t’avertis de ne pas faire cela.)
# ''Timeo ne hostes veniant.'' (Je crains que les ennemis ne viennent.) Nota : ne après verbe de crainte = sens positif.
''Exempla elocutionis''
* ''Hominem mortuum in urbe ne sepelito.'' (Qu’on n’ensevelisse pas de mort dans la ville.) (Loi des Douze Tables)
*: ''Commentaire :'' ne + impératif futur, syntaxe des lois archaïques ; sécheresse normative, sans considérant ni justification.
* ''Ne morte quidem terreri potest.'' (Même la mort ne peut l’effrayer.)
*: ''Commentaire :'' ne... quidem encadre exactement le mot nié ; le relief maximal est obtenu par cet étau syntaxique unique en son genre.
== neque, nec ==
(coni.) : et ne... pas, ni
''Exempla gradatim digesta''
# ''Nec legit nec scribit.'' (Il ne lit ni n’écrit.)
# ''Neque hoc dixi neque dicere volui.'' (Je n’ai pas dit cela et je n’ai pas voulu le dire.)
# ''Nec quisquam tam stultus est ut hoc credat.'' (Et personne n’est assez sot pour croire cela.) Nota : nec quisquam = « et personne ».
''Exempla elocutionis''
* ''Neque enim quisquam tam malus est ut malus videri velit.'' (Car personne n’est assez méchant pour vouloir paraître méchant.) (d’après Quintilien)
*: ''Commentaire :'' neque enim, articulation argumentative de la prose d’idées ; la reprise de malus (esse / videri) porte toute la pointe psychologique.
* ''Nec deos timuit.'' (Il ne craignit pas même les dieux.)
*: ''Commentaire :'' nec à valeur de ne... quidem, condensation fréquente en poésie ; un seul mot fait l’économie d’une locution entière.
== tamen ==
(adv.) : cependant, pourtant
''Exempla gradatim digesta''
# ''Pluit; tamen exeo.'' (Il pleut ; je sors pourtant.)
# ''Quamquam senex erat, tamen fortiter pugnavit.'' (Bien qu’il fût vieux, il combattit pourtant avec courage.)
# ''Sera tamen tacitis poena venit pedibus.'' (Tardive, la punition vient pourtant à pas silencieux.) (Tibulle)
''Exempla elocutionis''
* ''Vincemur fortasse; pugnabimus tamen.'' (Nous serons vaincus peut-être ; nous combattrons pourtant.)
*: ''Commentaire :'' tamen rejeté en fin de phrase, position rare et donc expressive ; la résistance est le dernier mot, littéralement.
* ''Ut desint vires, tamen est laudanda voluntas.'' (Même si les forces manquent, la volonté mérite pourtant l’éloge.) (Ovide)
*: ''Commentaire :'' concession ut + subjonctif relevée par tamen ; le pentamètre a fait de cette consolation d’exilé une maxime d’école.
== enim ==
(coni.) : en effet, car
''Exempla gradatim digesta''
# ''Tace: magister enim loquitur.'' (Tais-toi : car le maître parle.) Nota : enim toujours en seconde position.
# ''Nihil enim sine causa fit.'' (Rien en effet ne se produit sans cause.)
# ''Difficile est enim contra naturam pugnare.'' (Il est difficile, en effet, de lutter contre la nature.)
''Exempla elocutionis''
* ''Nemo enim fere saltat sobrius.'' (Car presque personne ne danse à jeun.) (Cicéron)
*: ''Commentaire :'' enim, toujours en seconde position, introduit ici une justification faussement sérieuse ; l’humour d’avocat consiste à argumenter l’anodin.
* ''Pecunia enim nervus belli est.'' (Car l’argent est le nerf de la guerre.) (d’après Cicéron)
*: ''Commentaire :'' métaphore du nerf (nervus, le tendon, la corde de l’arc) ; enim soude la maxime à la démonstration qu’elle vient clore.
== vir ==
''vir, viri'' (subst. m.) : homme, mari
''Exempla gradatim digesta''
# ''Vir in agro laborat.'' (L’homme travaille dans le champ.)
# ''Viri clari de re publica bene meruerunt.'' (Des hommes illustres ont bien mérité de la république.) Nota : bene mereri de = « bien mériter de ».
# ''Viro bono nihil mali accidere potest.'' (À l’homme de bien, rien de mauvais ne peut arriver.) (thèse stoïcienne)
''Exempla elocutionis''
* ''Vir bonus dicendi peritus.'' (Un homme de bien expert en parole.) (Caton)
*: ''Commentaire :'' définition catonienne de l’orateur, sans verbe, sèche comme une fiche de manuel ; vir bonus d’abord, la technique ensuite : l’ordre des mots est une hiérarchie morale.
* ''O virum fortem!'' (Ô le courageux !)
*: ''Commentaire :'' accusatif exclamatif ; l’éloge jaillit sans phrase, la syntaxe minimale de l’émotion.
== homo ==
''homo, hominis'' (subst. m.) : être humain, homme
''Exempla gradatim digesta''
# ''Homines in urbe habitant.'' (Les hommes habitent en ville.)
# ''Homo doctus in se semper divitias habet.'' (L’homme instruit porte toujours ses richesses en lui.) (Phèdre)
# ''Quot homines, tot sententiae.'' (Autant d’hommes, autant d’avis.) (Térence)
''Exempla elocutionis''
* ''Homo sum: humani nihil a me alienum puto.'' (Je suis homme : rien d’humain ne m’est étranger.) (Térence)
*: ''Commentaire :'' polyptote homo / humani ; deux propositions juxtaposées, la seconde déduite de la première sans connecteur. Le manifeste de l’humanisme tient dans une réplique de comédie.
* ''Cicero homo novus consul factus est.'' (Cicéron, homme nouveau, devint consul.)
*: ''Commentaire :'' homo novus, terme socio-politique technique (premier de sa famille à atteindre les magistratures) ; le style n’est pas que figures, c’est aussi un lexique institutionnel précis.
== rex ==
''rex, regis'' (subst. m.) : roi
''Exempla gradatim digesta''
# ''Rex coronam gerit.'' (Le roi porte une couronne.)
# ''Regibus expulsis, consules creati sunt.'' (Les rois chassés, on créa des consuls.) Nota : ablatif absolu.
# ''Stoici dicebant solum sapientem vere regem esse.'' (Les stoïciens disaient que seul le sage est vraiment roi.) Nota : proposition infinitive.
''Exempla elocutionis''
* ''Aut regem aut fatuum nasci oportet.'' (Il faut naître roi ou bouffon.) (adage cité par Sénèque)
*: ''Commentaire :'' alternative comique entre les deux seuls hommes qui disent ce qu’ils veulent ; la sagesse passe ici par la boutade.
* ''Regem eum appellabant, quod nomen Romae invisum erat.'' (On l’appelait roi, nom odieux à Rome.)
*: ''Commentaire :'' rex est, sous la République, un mot chargé négativement ; la stylistique inclut la connotation politique des mots, non leur seul sens.
== pater ==
''pater, patris'' (subst. m.) : père
''Exempla gradatim digesta''
# ''Pater meus agricola est.'' (Mon père est paysan.)
# ''Patres conscripti in curiam convocati sunt.'' (Les sénateurs furent convoqués à la curie.) Nota : patres conscripti = « les sénateurs ».
# ''Patris est filios non solum alere sed etiam educare.'' (C’est le devoir d’un père non seulement de nourrir ses fils mais aussi de les éduquer.)
''Exempla elocutionis''
* ''Cicero pater patriae appellatus est.'' (Cicéron fut nommé père de la patrie.)
*: ''Commentaire :'' pater patriae, titre honorifique ; la figure étymologique pater / patria donne au titre sa résonance, comme si la langue elle-même le justifiait.
* ''O pater, o patria, o Priami domus!'' (Ô père, ô patrie, ô maison de Priam !) (Ennius)
*: ''Commentaire :'' triple apostrophe en anaphore, allitération en p ; la lamentation tragique procède par vagues. Vers célèbre, cité par Cicéron comme modèle de pathétique.
== primus ==
''primus, prima, primum'' (adi.) : premier
''Exempla gradatim digesta''
# ''Primus in ordine sto.'' (Je suis le premier du rang.)
# ''Prima luce castra movimus.'' (Au point du jour, nous avons levé le camp.)
# ''Primus inter pares habebatur.'' (Il était tenu pour le premier entre ses égaux.)
''Exempla elocutionis''
* ''Primus ego in patriam Musas deducam.'' (Le premier, je conduirai les Muses dans ma patrie.) (d’après Virgile)
*: ''Commentaire :'' primus en tête + ego exprimé : double relief pour la revendication de primauté poétique ; topos de l’orgueil littéraire romain.
* ''Primum moneo, deinde rogo, postremo minor.'' (D’abord j’avertis, ensuite je prie, enfin je menace.)
*: ''Commentaire :'' les adverbes ordinaux structurent la gradation ; trois verbes de plus en plus durs, la colère organisée comme un plan.
== bonus ==
''bonus, bona, bonum'' (adi.) : bon
''Exempla gradatim digesta''
# ''Mater bona est.'' (La mère est bonne.)
# ''Meliora speremus!'' (Espérons mieux !) Nota : subjonctif d’exhortation.
# ''Quid sit summum bonum, inter philosophos non convenit.'' (Sur ce qu’est le souverain bien, les philosophes ne s’accordent pas.) Nota : convenit impersonnel.
''Exempla elocutionis''
* ''Boni pastoris est tondere pecus, non deglubere.'' (Un bon berger tond ses bêtes, il ne les écorche pas.) (Tibère, cité par Suétone)
*: ''Commentaire :'' métaphore rustique au service d’une maxime fiscale ; le mot d’empereur emprunte sa force à l’image paysanne, comprise de tous.
* ''Bona verba, quaeso!'' (Pas de mots de mauvais augure, je te prie !) (Térence)
*: ''Commentaire :'' exclamation apotropaïque de la conversation familière ; bona verba relève de la langue religieuse (paroles de bon augure) passée dans l’usage courant.
== dies ==
''dies, diei'' (subst. m./f.) : jour
''Exempla gradatim digesta''
# ''Dies longus est.'' (Le jour est long.)
# ''Die constituta omnes adfuerunt.'' (Au jour fixé, tous furent présents.) Nota : dies au féminin pour une date fixée.
# ''Carpe diem, quam minimum credula postero.'' (Cueille le jour, te fiant le moins possible au lendemain.) (Horace)
''Exempla elocutionis''
* ''Dies diem docet.'' (Un jour instruit l’autre.) (d’après Publilius Syrus)
*: ''Commentaire :'' polyptote dies / diem, sujet et objet du même mot ; l’expérience cumulative dite par la grammaire elle-même.
* ''Amici, diem perdidi.'' (Mes amis, j’ai perdu ma journée.) (Titus, cité par Suétone)
*: ''Commentaire :'' mot historique ; l’apostrophe initiale et la brièveté du constat font le pathétique de ce regret impérial (un jour sans bienfait est un jour perdu).
== nam ==
(coni.) : car, en effet
''Exempla gradatim digesta''
# ''Mane domi: nam pluit.'' (Reste à la maison, car il pleut.)
# ''Noli timere: nam tecum sum.'' (Ne crains rien, car je suis avec toi.)
# ''Nam ut corpus cibo, ita animus litteris alitur.'' (Car de même que le corps se nourrit d’aliments, l’esprit se nourrit des lettres.) Nota : ut... ita corrélatifs.
''Exempla elocutionis''
* ''Nam quid ego de moribus eius dicam?'' (Car que dirais-je de ses mœurs ?)
*: ''Commentaire :'' nam de la prétérition : l’orateur feint de renoncer à un développement qu’il annonce ainsi ; figure d’école, toujours efficace.
* ''Nam tua res agitur, paries cum proximus ardet.'' (Car c’est ton affaire qui est en jeu, quand brûle le mur du voisin.) (Horace)
*: ''Commentaire :'' maxime adossée à une image concrète (l’incendie mitoyen) ; nam articule la leçon générale à l’exemple sensible, démarche de la satire.
{{#invoke:Sous-Page|sousPage|taille préfixe=0.7em|taille titre=115%|italique=non}}
0yjcj5s62hxhayhtdgxv02vgvoz18oy
767807
767806
2026-06-16T04:17:07Z
PandaMystique
119061
767807
wikitext
text/x-wiki
{{Sous-pages|Latin/Vocabulaire/Verba Latina frequentissima}}
<div style="text-align: center; font-size: 90%;">
[[#habeo|habeo]] · [[#possum|possum]] · [[#video|video]] · [[#magnus|magnus]] · [[#deus|deus]] · [[#do|do]] · [[#atque, ac|atque, ac]] · [[#animus|animus]] · [[#multus|multus]] · [[#nunc|nunc]] · [[#etiam|etiam]] · [[#per|per]] · [[#alius|alius]] · [[#ne|ne]] · [[#neque, nec|neque, nec]] · [[#tamen|tamen]] · [[#enim|enim]] · [[#vir|vir]] · [[#homo|homo]] · [[#rex|rex]] · [[#pater|pater]] · [[#primus|primus]] · [[#bonus|bonus]] · [[#dies|dies]] · [[#nam|nam]]
</div>
== habeo ==
''habeo, habere, habui, habitum'' (v.) : avoir, tenir
''Exempla gradatim digesta''
# ''Canem habeo.'' (J’ai un chien.)
# ''Orationem in senatu habuit.'' (Il prononça un discours au sénat.)
# ''Nihil habeo quod scribam.'' (Je n’ai rien à écrire.) Nota : relative au subjonctif après nihil.
''Exempla elocutionis''
* ''Compertum habeo.'' (Je tiens la chose pour établie.)
*: ''Commentaire :'' habere + participe parfait insiste sur le résultat acquis et possédé ; tour expressif qui annonce de loin nos temps composés romans.
* ''Habent sua fata libelli.'' (Les livres ont leur destin.) (Térentianus Maurus)
*: ''Commentaire :'' personnification des livres par le simple jeu du possessif sua ; le vers, détaché de son contexte, est devenu proverbe.
== possum ==
''possum, posse, potui'' (v.) : pouvoir
''Exempla gradatim digesta''
# ''Currere possum.'' (Je peux courir.)
# ''Hoc fieri potest.'' (Cela peut se faire.)
# ''Ut potui, feci; ut volui, non potui.'' (J’ai fait comme j’ai pu ; comme je voulais, je n’ai pas pu.)
''Exempla elocutionis''
* ''Possunt, quia posse videntur.'' (Ils peuvent, parce qu’ils croient pouvoir.) (Virgile)
*: ''Commentaire :'' polyptote possunt / posse ; la confiance crée la force, et la répétition du verbe mime ce cercle. Psychologie de la course en un hémistiche.
* ''Fieri potest ut fallar.'' (Il se peut que je me trompe.)
*: ''Commentaire :'' tour impersonnel de la prudence philosophique ; l’Académicien ne dit pas « je me trompe peut-être » mais met sa propre erreur à distance.
== video ==
''video, videre, vidi, visum'' (v.) : voir
''Exempla gradatim digesta''
# ''Stellas video.'' (Je vois les étoiles.)
# ''Videor mihi felix esse.'' (Il me semble que je suis heureux.) Nota : videor, construction personnelle.
# ''Videant consules ne quid res publica detrimenti capiat.'' (Que les consuls veillent à ce que la république ne subisse aucun dommage.) (formule sénatoriale) Nota : videre ne + subjonctif.
''Exempla elocutionis''
* ''Video meliora proboque, deteriora sequor.'' (Je vois le meilleur et je l’approuve, je suis le pire.) (Ovide)
*: ''Commentaire :'' asyndète adversative au centre du vers ; le déchirement moral (l’acrasie des philosophes) tient dans l’absence même de conjonction.
* ''Errare mihi videris.'' (Tu me sembles faire erreur.)
*: ''Commentaire :'' videor atténue l’affirmation ; l’urbanité du dialogue cultivé consiste à présenter le désaccord comme une impression.
== magnus ==
''magnus, magna, magnum'' (adi.) : grand
''Exempla gradatim digesta''
# ''Domus magna est.'' (La maison est grande.)
# ''Maior pars militum periit.'' (La plus grande partie des soldats périt.)
# ''Magni ingenii est mentem a sensibus revocare.'' (C’est le propre d’un grand esprit de détacher la pensée des sens.) Nota : est + génitif (« c’est le propre d’un grand esprit »).
''Exempla elocutionis''
* ''Magna di curant, parva neglegunt.'' (Les dieux s’occupent des grandes choses, ils négligent les petites.) (Cicéron)
*: ''Commentaire :'' double antithèse en asyndète (magna / parva, curant / neglegunt) ; la symétrie donne à la thèse théologique une allure d’évidence.
* ''Parvo fames constat, magno fastidium.'' (La faim coûte peu, le dégoût coûte cher.) (Sénèque)
*: ''Commentaire :'' ablatifs de prix antithétiques en chiasme avec leurs sujets ; morale frugale de Sénèque, où la syntaxe fait les comptes.
== deus ==
''deus, dei'' (subst. m.) : dieu
''Exempla gradatim digesta''
# ''Dei caelum tenent.'' (Les dieux occupent le ciel.)
# ''Dis hostias immolaverunt.'' (Ils immolèrent des victimes aux dieux.) Nota : dis, datif pluriel contracte.
# ''Natura ipsa docet deos esse.'' (La nature elle-même enseigne que les dieux existent.) Nota : proposition infinitive.
''Exempla elocutionis''
* ''Di immortales!'' (Dieux immortels !)
*: ''Commentaire :'' exclamation-juron du théâtre et des plaidoyers ; la forme contracte di appartient à la langue vive, dei serait livresque.
* ''Deum colit qui novit.'' (Honorer dieu, c’est le connaître.) (d’après Sénèque)
*: ''Commentaire :'' brièveté sénéquienne : relative sans antécédent, cinq mots, pointe finale ; la piété redéfinie en une formule qui tient de l’épigramme.
== do ==
''do, dare, dedi, datum'' (v.) : donner
''Exempla gradatim digesta''
# ''Panem pauperi do.'' (Je donne du pain au pauvre.)
# ''Operam litteris dedi.'' (Je me suis consacré aux lettres.) Nota : operam dare = « s’appliquer à ».
# ''Dant veniam corvis, vexat censura columbas.'' (On pardonne aux corbeaux, la censure s’acharne sur les colombes.) (Juvénal)
''Exempla elocutionis''
* ''Bis dat qui cito dat.'' (Donner vite, c’est donner deux fois.) (d’après Publilius Syrus)
*: ''Commentaire :'' reprise de dat aux deux membres, rime intérieure et rythme de sentence ; la maxime est faite pour la mémoire.
* ''Da mihi, obsecro, hanc veniam.'' (Accorde-moi, je t’en conjure, cette grâce.)
*: ''Commentaire :'' l’incise obsecro suspend la phrase entre le verbe et son objet ; registre de la prière, où le retard de l’objet ménage la supplication.
== atque, ac ==
(coni.) : et, et de plus
''Exempla gradatim digesta''
# ''Pater atque filius adsunt.'' (Le père et le fils sont présents.)
# ''Idem atque tu sentio.'' (Je pense la même chose que toi.) Nota : idem atque = « le même que ».
# ''Simul atque venit, omnia mutata sunt.'' (Dès qu’il arriva, tout changea.) Nota : simul atque = « dès que ».
''Exempla elocutionis''
* ''Difficile est, atque adeo fieri non potest.'' (C’est difficile, et même cela ne se peut pas.)
*: ''Commentaire :'' atque adeo corrige en renchérissant ; gradation rectificative de l’orateur qui feint de s’interrompre pour aller plus loin.
* ''Mens atque animus, consilium atque sententia civitatis posita est in legibus.'' (L’intelligence et l’âme, la pensée et la volonté de la cité résident dans les lois.) (d’après Cicéron)
*: ''Commentaire :'' doublets synonymiques liés par atque ; la plénitude oratoire double chaque notion, non pour préciser mais pour amplifier.
== animus ==
''animus, animi'' (subst. m.) : esprit, cœur, courage
''Exempla gradatim digesta''
# ''Animus meus laetus est.'' (Mon cœur est joyeux.)
# ''Ex animo tibi gratias ago.'' (Je te remercie de tout cœur.)
# ''Animum rege, qui nisi paret, imperat.'' (Gouverne ton cœur : s’il n’obéit pas, il commande.) (Horace)
''Exempla elocutionis''
* ''Animus aequus optimum est aerumnae condimentum.'' (Une âme égale est le meilleur assaisonnement du malheur.) (Plaute)
*: ''Commentaire :'' métaphore culinaire appliquée à la morale ; le mélange du noble et du trivial est la marque du registre comique.
* ''Corpus quasi vas est animi.'' (Le corps est comme le vase de l’âme.) (d’après Cicéron)
*: ''Commentaire :'' quasi signale la métaphore comme approximation ; précaution du philosophe qui traduit en images, utile à qui rédige un lexique de philosophie.
== multus ==
''multus, multa, multum'' (adi.) : nombreux, abondant
''Exempla gradatim digesta''
# ''Multae aves cantant.'' (Beaucoup d’oiseaux chantent.)
# ''Multa de te audivi.'' (J’ai entendu beaucoup de choses sur toi.) Nota : multa, neutre pluriel substantivé.
# ''Multum legendum est, non multa.'' (Il faut lire beaucoup, non beaucoup de choses.) (d’après Pline le Jeune)
''Exempla elocutionis''
* ''Multa paucis dicere ars est.'' (Dire beaucoup en peu de mots est un art.)
*: ''Commentaire :'' antithèse quantitative multa / paucis juxtaposée sans liaison ; l’idéal de brevitas énoncé brièvement, la forme prouvant le fond.
* ''Multis ille bonis flebilis occidit.'' (Il est mort, pleuré de bien des gens de bien.) (Horace)
*: ''Commentaire :'' disjonction multis... bonis qui enserre le vers ; le datif de point de vue fait du deuil collectif l’écrin du défunt.
== nunc ==
(adv.) : maintenant
''Exempla gradatim digesta''
# ''Nunc ludimus.'' (Maintenant nous jouons.)
# ''Nunc demum intellego.'' (Maintenant enfin je comprends.)
# ''Nunc aut numquam agendum est.'' (C’est maintenant ou jamais qu’il faut agir.) Nota : adjectif verbal impersonnel.
''Exempla elocutionis''
* ''Nunc est bibendum.'' (C’est maintenant qu’il faut boire.) (Horace)
*: ''Commentaire :'' nunc en tête, triomphal, libère la joie longtemps contenue (la mort de Cléopâtre) ; l’adverbe de temps devient cri.
* ''Nunc huc, nunc illuc currit.'' (Il court tantôt ici, tantôt là.)
*: ''Commentaire :'' anaphore alternative nunc... nunc ; la répétition peint l’agitation désordonnée, procédé descriptif élémentaire et sûr.
== etiam ==
(adv.) : aussi, même, encore
''Exempla gradatim digesta''
# ''Etiam ego venio.'' (Moi aussi je viens.)
# ''Non solum audivit, sed etiam vidit.'' (Il n’a pas seulement entendu, il a même vu.)
# ''Etiam capillus unus habet umbram suam.'' (Même un seul cheveu a son ombre.) (Publilius Syrus)
''Exempla elocutionis''
* ''Etiam atque etiam rogo.'' (Je le demande instamment.)
*: ''Commentaire :'' gémination figée etiam atque etiam, insistance codifiée de la langue épistolaire ; la politesse romaine répète au lieu d’intensifier.
* ''Non modo pecuniam verum etiam vitam pro patria dedit.'' (Il a donné pour la patrie non seulement son argent mais encore sa vie.)
*: ''Commentaire :'' gradation pleine non modo... verum etiam ; l’ordre croissant des sacrifices est obligatoire, l’inverser serait ridicule.
== per ==
(praep. + acc.) : à travers, par, pendant
''Exempla gradatim digesta''
# ''Per viam ambulo.'' (Je marche sur la route.)
# ''Per totam noctem vigilavit.'' (Il veilla pendant toute la nuit.)
# ''Per me licet: fac quod vis.'' (Pour ma part, je n’y vois pas d’obstacle : fais ce que tu veux.) Nota : per me licet, locution.
''Exempla elocutionis''
* ''Per deos immortales te obtestor!'' (Au nom des dieux immortels, je t’en conjure !)
*: ''Commentaire :'' per du serment et de l’adjuration ; la préposition spatiale devient l’opérateur du sacré. Pathos judiciaire et tragique.
* ''Per varios casus, per tot discrimina rerum tendimus in Latium.'' (À travers tant de hasards, à travers tant de périls, nous marchons vers le Latium.) (Virgile)
*: ''Commentaire :'' anaphore de per qui scande les épreuves ; l’épopée avance préposition par préposition, et le but (in Latium) n’arrive qu’à la fin.
== alius ==
''alius, alia, aliud'' (pron.) : autre
''Exempla gradatim digesta''
# ''Alius puer venit.'' (Un autre garçon vient.)
# ''Alii legunt, alii scribunt.'' (Les uns lisent, les autres écrivent.)
# ''Aliud est dicere, aliud facere.'' (Autre chose est de dire, autre chose de faire.) Nota : aliud... aliud distributif.
''Exempla elocutionis''
* ''Alii aliis subsidium ferunt.'' (Ils se portent secours les uns aux autres.) (d’après César)
*: ''Commentaire :'' tour distributif alius alii, d’une densité intraduisible ; le latin condense en deux mots ce que le français étale en sept.
* ''Aliud clausum in pectore, aliud in lingua promptum habent.'' (Ils ont une chose enfermée dans le cœur, une autre toute prête sur la langue.) (Salluste)
*: ''Commentaire :'' antithèse pectore / lingua portée par l’anaphore de aliud ; la duplicité peinte par la symétrie même de la phrase. Style moraliste de Salluste.
== ne ==
(coni. + subi.) : pour que... ne pas ; de peur que
''Exempla gradatim digesta''
# ''Ne timeas!'' (N’aie pas peur !) Nota : défense au subjonctif.
# ''Moneo te ne hoc facias.'' (Je t’avertis de ne pas faire cela.)
# ''Timeo ne hostes veniant.'' (Je crains que les ennemis ne viennent.) Nota : ne après verbe de crainte = sens positif.
''Exempla elocutionis''
* ''Hominem mortuum in urbe ne sepelito.'' (Qu’on n’ensevelisse pas de mort dans la ville.) (Loi des Douze Tables)
*: ''Commentaire :'' ne + impératif futur, syntaxe des lois archaïques ; sécheresse normative, sans considérant ni justification.
* ''Ne morte quidem terreri potest.'' (Même la mort ne peut l’effrayer.)
*: ''Commentaire :'' ne... quidem encadre exactement le mot nié ; le relief maximal est obtenu par cet étau syntaxique unique en son genre.
== neque, nec ==
(coni.) : et ne... pas, ni
''Exempla gradatim digesta''
# ''Nec legit nec scribit.'' (Il ne lit ni n’écrit.)
# ''Neque hoc dixi neque dicere volui.'' (Je n’ai pas dit cela et je n’ai pas voulu le dire.)
# ''Nec quisquam tam stultus est ut hoc credat.'' (Et personne n’est assez sot pour croire cela.) Nota : nec quisquam = « et personne ».
''Exempla elocutionis''
* ''Neque enim quisquam tam malus est ut malus videri velit.'' (Car personne n’est assez méchant pour vouloir paraître méchant.) (d’après Quintilien)
*: ''Commentaire :'' neque enim, articulation argumentative de la prose d’idées ; la reprise de malus (esse / videri) porte toute la pointe psychologique.
* ''Nec deos timuit.'' (Il ne craignit pas même les dieux.)
*: ''Commentaire :'' nec à valeur de ne... quidem, condensation fréquente en poésie ; un seul mot fait l’économie d’une locution entière.
== tamen ==
(adv.) : cependant, pourtant
''Exempla gradatim digesta''
# ''Pluit; tamen exeo.'' (Il pleut ; je sors pourtant.)
# ''Quamquam senex erat, tamen fortiter pugnavit.'' (Bien qu’il fût vieux, il combattit pourtant avec courage.)
# ''Sera tamen tacitis poena venit pedibus.'' (Tardive, la punition vient pourtant à pas silencieux.) (Tibulle)
''Exempla elocutionis''
* ''Vincemur fortasse; pugnabimus tamen.'' (Nous serons vaincus peut-être ; nous combattrons pourtant.)
*: ''Commentaire :'' tamen rejeté en fin de phrase, position rare et donc expressive ; la résistance est le dernier mot, littéralement.
* ''Ut desint vires, tamen est laudanda voluntas.'' (Même si les forces manquent, la volonté mérite pourtant l’éloge.) (Ovide)
*: ''Commentaire :'' concession ut + subjonctif relevée par tamen ; le pentamètre a fait de cette consolation d’exilé une maxime d’école.
== enim ==
(coni.) : en effet, car
''Exempla gradatim digesta''
# ''Tace: magister enim loquitur.'' (Tais-toi : car le maître parle.) Nota : enim toujours en seconde position.
# ''Nihil enim sine causa fit.'' (Rien en effet ne se produit sans cause.)
# ''Difficile est enim contra naturam pugnare.'' (Il est difficile, en effet, de lutter contre la nature.)
''Exempla elocutionis''
* ''Nemo enim fere saltat sobrius.'' (Car presque personne ne danse à jeun.) (Cicéron)
*: ''Commentaire :'' enim, toujours en seconde position, introduit ici une justification faussement sérieuse ; l’humour d’avocat consiste à argumenter l’anodin.
* ''Pecunia enim nervus belli est.'' (Car l’argent est le nerf de la guerre.) (d’après Cicéron)
*: ''Commentaire :'' métaphore du nerf (nervus, le tendon, la corde de l’arc) ; enim soude la maxime à la démonstration qu’elle vient clore.
== vir ==
''vir, viri'' (subst. m.) : homme, mari
''Exempla gradatim digesta''
# ''Vir in agro laborat.'' (L’homme travaille dans le champ.)
# ''Viri clari de re publica bene meruerunt.'' (Des hommes illustres ont bien mérité de la république.) Nota : bene mereri de = « bien mériter de ».
# ''Viro bono nihil mali accidere potest.'' (À l’homme de bien, rien de mauvais ne peut arriver.) (thèse stoïcienne)
''Exempla elocutionis''
* ''Vir bonus dicendi peritus.'' (Un homme de bien expert en parole.) (Caton)
*: ''Commentaire :'' définition catonienne de l’orateur, sans verbe, sèche comme une fiche de manuel ; vir bonus d’abord, la technique ensuite : l’ordre des mots est une hiérarchie morale.
* ''O virum fortem!'' (Ô le courageux !)
*: ''Commentaire :'' accusatif exclamatif ; l’éloge jaillit sans phrase, la syntaxe minimale de l’émotion.
== homo ==
''homo, hominis'' (subst. m.) : être humain, homme
''Exempla gradatim digesta''
# ''Homines in urbe habitant.'' (Les hommes habitent en ville.)
# ''Homo doctus in se semper divitias habet.'' (L’homme instruit porte toujours ses richesses en lui.) (Phèdre)
# ''Quot homines, tot sententiae.'' (Autant d’hommes, autant d’avis.) (Térence)
''Exempla elocutionis''
* ''Homo sum: humani nihil a me alienum puto.'' (Je suis homme : rien d’humain ne m’est étranger.) (Térence)
*: ''Commentaire :'' polyptote homo / humani ; deux propositions juxtaposées, la seconde déduite de la première sans connecteur. Le manifeste de l’humanisme tient dans une réplique de comédie.
* ''Cicero homo novus consul factus est.'' (Cicéron, homme nouveau, devint consul.)
*: ''Commentaire :'' homo novus, terme socio-politique technique (premier de sa famille à atteindre les magistratures) ; le style n’est pas que figures, c’est aussi un lexique institutionnel précis.
== rex ==
''rex, regis'' (subst. m.) : roi
''Exempla gradatim digesta''
# ''Rex coronam gerit.'' (Le roi porte une couronne.)
# ''Regibus expulsis, consules creati sunt.'' (Les rois chassés, on créa des consuls.) Nota : ablatif absolu.
# ''Stoici dicebant solum sapientem vere regem esse.'' (Les stoïciens disaient que seul le sage est vraiment roi.) Nota : proposition infinitive.
''Exempla elocutionis''
* ''Aut regem aut fatuum nasci oportet.'' (Il faut naître roi ou bouffon.) (adage cité par Sénèque)
*: ''Commentaire :'' alternative comique entre les deux seuls hommes qui disent ce qu’ils veulent ; la sagesse passe ici par la boutade.
* ''Regem eum appellabant, quod nomen Romae invisum erat.'' (On l’appelait roi, nom odieux à Rome.)
*: ''Commentaire :'' rex est, sous la République, un mot chargé négativement ; la stylistique inclut la connotation politique des mots, non leur seul sens.
== pater ==
''pater, patris'' (subst. m.) : père
''Exempla gradatim digesta''
# ''Pater meus agricola est.'' (Mon père est paysan.)
# ''Patres conscripti in curiam convocati sunt.'' (Les sénateurs furent convoqués à la curie.) Nota : patres conscripti = « les sénateurs ».
# ''Patris est filios non solum alere sed etiam educare.'' (C’est le devoir d’un père non seulement de nourrir ses fils mais aussi de les éduquer.)
''Exempla elocutionis''
* ''Cicero pater patriae appellatus est.'' (Cicéron fut nommé père de la patrie.)
*: ''Commentaire :'' pater patriae, titre honorifique ; la figure étymologique pater / patria donne au titre sa résonance, comme si la langue elle-même le justifiait.
* ''O pater, o patria, o Priami domus!'' (Ô père, ô patrie, ô maison de Priam !) (Ennius)
*: ''Commentaire :'' triple apostrophe en anaphore, allitération en p ; la lamentation tragique procède par vagues. Vers célèbre, cité par Cicéron comme modèle de pathétique.
== primus ==
''primus, prima, primum'' (adi.) : premier
''Exempla gradatim digesta''
# ''Primus in ordine sto.'' (Je suis le premier du rang.)
# ''Prima luce castra movimus.'' (Au point du jour, nous avons levé le camp.)
# ''Primus inter pares habebatur.'' (Il était tenu pour le premier entre ses égaux.)
''Exempla elocutionis''
* ''Primus ego in patriam Musas deducam.'' (Le premier, je conduirai les Muses dans ma patrie.) (d’après Virgile)
*: ''Commentaire :'' primus en tête + ego exprimé : double relief pour la revendication de primauté poétique ; topos de l’orgueil littéraire romain.
* ''Primum moneo, deinde rogo, postremo minor.'' (D’abord j’avertis, ensuite je prie, enfin je menace.)
*: ''Commentaire :'' les adverbes ordinaux structurent la gradation ; trois verbes de plus en plus durs, la colère organisée comme un plan.
== bonus ==
''bonus, bona, bonum'' (adi.) : bon
''Exempla gradatim digesta''
# ''Mater bona est.'' (La mère est bonne.)
# ''Meliora speremus!'' (Espérons mieux !) Nota : subjonctif d’exhortation.
# ''Quid sit summum bonum, inter philosophos non convenit.'' (Sur ce qu’est le souverain bien, les philosophes ne s’accordent pas.) Nota : convenit impersonnel.
''Exempla elocutionis''
* ''Boni pastoris est tondere pecus, non deglubere.'' (Un bon berger tond ses bêtes, il ne les écorche pas.) (Tibère, cité par Suétone)
*: ''Commentaire :'' métaphore rustique au service d’une maxime fiscale ; le mot d’empereur emprunte sa force à l’image paysanne, comprise de tous.
* ''Bona verba, quaeso!'' (Pas de mots de mauvais augure, je te prie !) (Térence)
*: ''Commentaire :'' exclamation apotropaïque de la conversation familière ; bona verba relève de la langue religieuse (paroles de bon augure) passée dans l’usage courant.
== dies ==
''dies, diei'' (subst. m./f.) : jour
''Exempla gradatim digesta''
# ''Dies longus est.'' (Le jour est long.)
# ''Die constituta omnes adfuerunt.'' (Au jour fixé, tous furent présents.) Nota : dies au féminin pour une date fixée.
# ''Carpe diem, quam minimum credula postero.'' (Cueille le jour, te fiant le moins possible au lendemain.) (Horace)
''Exempla elocutionis''
* ''Dies diem docet.'' (Un jour instruit l’autre.) (d’après Publilius Syrus)
*: ''Commentaire :'' polyptote dies / diem, sujet et objet du même mot ; l’expérience cumulative dite par la grammaire elle-même.
* ''Amici, diem perdidi.'' (Mes amis, j’ai perdu ma journée.) (Titus, cité par Suétone)
*: ''Commentaire :'' mot historique ; l’apostrophe initiale et la brièveté du constat font le pathétique de ce regret impérial (un jour sans bienfait est un jour perdu).
== nam ==
(coni.) : car, en effet
''Exempla gradatim digesta''
# ''Mane domi: nam pluit.'' (Reste à la maison, car il pleut.)
# ''Noli timere: nam tecum sum.'' (Ne crains rien, car je suis avec toi.)
# ''Nam ut corpus cibo, ita animus litteris alitur.'' (Car de même que le corps se nourrit d’aliments, l’esprit se nourrit des lettres.) Nota : ut... ita corrélatifs.
''Exempla elocutionis''
* ''Nam quid ego de moribus eius dicam?'' (Car que dirais-je de ses mœurs ?)
*: ''Commentaire :'' nam de la prétérition : l’orateur feint de renoncer à un développement qu’il annonce ainsi ; figure d’école, toujours efficace.
* ''Nam tua res agitur, paries cum proximus ardet.'' (Car c’est ton affaire qui est en jeu, quand brûle le mur du voisin.) (Horace)
*: ''Commentaire :'' maxime adossée à une image concrète (l’incendie mitoyen) ; nam articule la leçon générale à l’exemple sensible, démarche de la satire.
{{#invoke:Sous-Page|sousPage|taille préfixe=0.7em|taille titre=115%|italique=non}}
t4bql9mxac2v4zmg57mg6xod7vof7l9
Latin/Vocabulaire/Verba Latina frequentissima/Sommaire
0
83946
767798
767790
2026-06-16T04:02:50Z
PandaMystique
119061
767798
wikitext
text/x-wiki
<div style="text-align: center; font-size: 90%;">[[Latin/Vocabulaire/Verba Latina frequentissima/001-025|001-025]] · [[Latin/Vocabulaire/Verba Latina frequentissima/026-050|026-050]] · [[Latin/Vocabulaire/Verba Latina frequentissima/051-075|051-075]] · [[Latin/Vocabulaire/Verba Latina frequentissima/076-100|076-100]] · [[Latin/Vocabulaire/Verba Latina frequentissima/101-125|101-125]] · [[Latin/Vocabulaire/Verba Latina frequentissima/126-150|126-150]] · [[Latin/Vocabulaire/Verba Latina frequentissima/151-175|151-175]] · [[Latin/Vocabulaire/Verba Latina frequentissima/176-200|176-200]] · [[Latin/Vocabulaire/Verba Latina frequentissima/201-225|201-225]] · [[Latin/Vocabulaire/Verba Latina frequentissima/226-250|226-250]] · [[Latin/Vocabulaire/Verba Latina frequentissima/251-275|251-275]] · [[Latin/Vocabulaire/Verba Latina frequentissima/276-300|276-300]] · [[Latin/Vocabulaire/Verba Latina frequentissima/301-325|301-325]] · [[Latin/Vocabulaire/Verba Latina frequentissima/326-350|326-350]] · [[Latin/Vocabulaire/Verba Latina frequentissima/351-375|351-375]] · [[Latin/Vocabulaire/Verba Latina frequentissima/376-400|376-400]] · [[Latin/Vocabulaire/Verba Latina frequentissima/401-425|401-425]] · [[Latin/Vocabulaire/Verba Latina frequentissima/426-450|426-450]] · [[Latin/Vocabulaire/Verba Latina frequentissima/451-475|451-475]] · [[Latin/Vocabulaire/Verba Latina frequentissima/476-500|476-500]] · [[Latin/Vocabulaire/Verba Latina frequentissima/501-525|501-525]] · [[Latin/Vocabulaire/Verba Latina frequentissima/526-550|526-550]] · [[Latin/Vocabulaire/Verba Latina frequentissima/551-575|551-575]] · [[Latin/Vocabulaire/Verba Latina frequentissima/576-600|576-600]] · [[Latin/Vocabulaire/Verba Latina frequentissima/601-625|601-625]] · [[Latin/Vocabulaire/Verba Latina frequentissima/626-650|626-650]] · [[Latin/Vocabulaire/Verba Latina frequentissima/651-675|651-675]] · [[Latin/Vocabulaire/Verba Latina frequentissima/676-700|676-700]] · [[Latin/Vocabulaire/Verba Latina frequentissima/701-725|701-725]] · [[Latin/Vocabulaire/Verba Latina frequentissima/726-750|726-750]] · [[Latin/Vocabulaire/Verba Latina frequentissima/751-775|751-775]] · [[Latin/Vocabulaire/Verba Latina frequentissima/776-800|776-800]] · [[Latin/Vocabulaire/Verba Latina frequentissima/801-825|801-825]] · [[Latin/Vocabulaire/Verba Latina frequentissima/826-850|826-850]] · [[Latin/Vocabulaire/Verba Latina frequentissima/851-875|851-875]] · [[Latin/Vocabulaire/Verba Latina frequentissima/876-900|876-900]] · [[Latin/Vocabulaire/Verba Latina frequentissima/901-925|901-925]] · [[Latin/Vocabulaire/Verba Latina frequentissima/926-950|926-950]] · [[Latin/Vocabulaire/Verba Latina frequentissima/951-975|951-975]] · [[Latin/Vocabulaire/Verba Latina frequentissima/976-1000|976-1000]]
</div>
e8gj24dye98nk5c29b90zdn4uxi5wau
767799
767798
2026-06-16T04:03:39Z
PandaMystique
119061
767799
wikitext
text/x-wiki
<div style="text-align: center; font-size: 90%;">*[[Latin/Vocabulaire/Verba Latina frequentissima/001-025|001-025]] · [[Latin/Vocabulaire/Verba Latina frequentissima/026-050|026-050]] · [[Latin/Vocabulaire/Verba Latina frequentissima/051-075|051-075]] · [[Latin/Vocabulaire/Verba Latina frequentissima/076-100|076-100]] · [[Latin/Vocabulaire/Verba Latina frequentissima/101-125|101-125]] · [[Latin/Vocabulaire/Verba Latina frequentissima/126-150|126-150]] · [[Latin/Vocabulaire/Verba Latina frequentissima/151-175|151-175]] · [[Latin/Vocabulaire/Verba Latina frequentissima/176-200|176-200]] · [[Latin/Vocabulaire/Verba Latina frequentissima/201-225|201-225]] · [[Latin/Vocabulaire/Verba Latina frequentissima/226-250|226-250]] · [[Latin/Vocabulaire/Verba Latina frequentissima/251-275|251-275]] · [[Latin/Vocabulaire/Verba Latina frequentissima/276-300|276-300]] · [[Latin/Vocabulaire/Verba Latina frequentissima/301-325|301-325]] · [[Latin/Vocabulaire/Verba Latina frequentissima/326-350|326-350]] · [[Latin/Vocabulaire/Verba Latina frequentissima/351-375|351-375]] · [[Latin/Vocabulaire/Verba Latina frequentissima/376-400|376-400]] · [[Latin/Vocabulaire/Verba Latina frequentissima/401-425|401-425]] · [[Latin/Vocabulaire/Verba Latina frequentissima/426-450|426-450]] · [[Latin/Vocabulaire/Verba Latina frequentissima/451-475|451-475]] · [[Latin/Vocabulaire/Verba Latina frequentissima/476-500|476-500]] · [[Latin/Vocabulaire/Verba Latina frequentissima/501-525|501-525]] · [[Latin/Vocabulaire/Verba Latina frequentissima/526-550|526-550]] · [[Latin/Vocabulaire/Verba Latina frequentissima/551-575|551-575]] · [[Latin/Vocabulaire/Verba Latina frequentissima/576-600|576-600]] · [[Latin/Vocabulaire/Verba Latina frequentissima/601-625|601-625]] · [[Latin/Vocabulaire/Verba Latina frequentissima/626-650|626-650]] · [[Latin/Vocabulaire/Verba Latina frequentissima/651-675|651-675]] · [[Latin/Vocabulaire/Verba Latina frequentissima/676-700|676-700]] · [[Latin/Vocabulaire/Verba Latina frequentissima/701-725|701-725]] · [[Latin/Vocabulaire/Verba Latina frequentissima/726-750|726-750]] · [[Latin/Vocabulaire/Verba Latina frequentissima/751-775|751-775]] · [[Latin/Vocabulaire/Verba Latina frequentissima/776-800|776-800]] · [[Latin/Vocabulaire/Verba Latina frequentissima/801-825|801-825]] · [[Latin/Vocabulaire/Verba Latina frequentissima/826-850|826-850]] · [[Latin/Vocabulaire/Verba Latina frequentissima/851-875|851-875]] · [[Latin/Vocabulaire/Verba Latina frequentissima/876-900|876-900]] · [[Latin/Vocabulaire/Verba Latina frequentissima/901-925|901-925]] · [[Latin/Vocabulaire/Verba Latina frequentissima/926-950|926-950]] · [[Latin/Vocabulaire/Verba Latina frequentissima/951-975|951-975]] · [[Latin/Vocabulaire/Verba Latina frequentissima/976-1000|976-1000]]
</div>
6kd9ei8y9s37vxnj9ybsd12symopc2f
767802
767799
2026-06-16T04:05:47Z
PandaMystique
119061
767802
wikitext
text/x-wiki
* [[Latin/Vocabulaire/Verba Latina frequentissima/001-025|001-025]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/026-050|026-050]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/051-075|051-075]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/076-100|076-100]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/101-125|101-125]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/126-150|126-150]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/151-175|151-175]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/176-200|176-200]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/201-225|201-225]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/226-250|226-250]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/251-275|251-275]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/276-300|276-300]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/301-325|301-325]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/326-350|326-350]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/351-375|351-375]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/376-400|376-400]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/401-425|401-425]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/426-450|426-450]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/451-475|451-475]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/476-500|476-500]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/501-525|501-525]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/526-550|526-550]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/551-575|551-575]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/576-600|576-600]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/601-625|601-625]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/626-650|626-650]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/651-675|651-675]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/676-700|676-700]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/701-725|701-725]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/726-750|726-750]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/751-775|751-775]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/776-800|776-800]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/801-825|801-825]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/826-850|826-850]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/851-875|851-875]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/876-900|876-900]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/901-925|901-925]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/926-950|926-950]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/951-975|951-975]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/976-1000|976-1000]]
5mcoi79ffsun9kw8nenyuj0a82meiz1
767803
767802
2026-06-16T04:06:18Z
PandaMystique
119061
767803
wikitext
text/x-wiki
<div style="text-align: center; font-size: 90%;">
[[Latin/Vocabulaire/Verba Latina frequentissima/026-050|026-050]] · [[Latin/Vocabulaire/Verba Latina frequentissima/051-075|051-075]] · [[Latin/Vocabulaire/Verba Latina frequentissima/076-100|076-100]] · [[Latin/Vocabulaire/Verba Latina frequentissima/101-125|101-125]] · [[Latin/Vocabulaire/Verba Latina frequentissima/126-150|126-150]] · [[Latin/Vocabulaire/Verba Latina frequentissima/151-175|151-175]] · [[Latin/Vocabulaire/Verba Latina frequentissima/176-200|176-200]] · [[Latin/Vocabulaire/Verba Latina frequentissima/201-225|201-225]] · [[Latin/Vocabulaire/Verba Latina frequentissima/226-250|226-250]] · [[Latin/Vocabulaire/Verba Latina frequentissima/251-275|251-275]] · [[Latin/Vocabulaire/Verba Latina frequentissima/276-300|276-300]] · [[Latin/Vocabulaire/Verba Latina frequentissima/301-325|301-325]] · [[Latin/Vocabulaire/Verba Latina frequentissima/326-350|326-350]] · [[Latin/Vocabulaire/Verba Latina frequentissima/351-375|351-375]] · [[Latin/Vocabulaire/Verba Latina frequentissima/376-400|376-400]] · [[Latin/Vocabulaire/Verba Latina frequentissima/401-425|401-425]] · [[Latin/Vocabulaire/Verba Latina frequentissima/426-450|426-450]] · [[Latin/Vocabulaire/Verba Latina frequentissima/451-475|451-475]] · [[Latin/Vocabulaire/Verba Latina frequentissima/476-500|476-500]] · [[Latin/Vocabulaire/Verba Latina frequentissima/501-525|501-525]] · [[Latin/Vocabulaire/Verba Latina frequentissima/526-550|526-550]] · [[Latin/Vocabulaire/Verba Latina frequentissima/551-575|551-575]] · [[Latin/Vocabulaire/Verba Latina frequentissima/576-600|576-600]] · [[Latin/Vocabulaire/Verba Latina frequentissima/601-625|601-625]] · [[Latin/Vocabulaire/Verba Latina frequentissima/626-650|626-650]] · [[Latin/Vocabulaire/Verba Latina frequentissima/651-675|651-675]] · [[Latin/Vocabulaire/Verba Latina frequentissima/676-700|676-700]] · [[Latin/Vocabulaire/Verba Latina frequentissima/701-725|701-725]] · [[Latin/Vocabulaire/Verba Latina frequentissima/726-750|726-750]] · [[Latin/Vocabulaire/Verba Latina frequentissima/751-775|751-775]] · [[Latin/Vocabulaire/Verba Latina frequentissima/776-800|776-800]] · [[Latin/Vocabulaire/Verba Latina frequentissima/801-825|801-825]] · [[Latin/Vocabulaire/Verba Latina frequentissima/826-850|826-850]] · [[Latin/Vocabulaire/Verba Latina frequentissima/851-875|851-875]] · [[Latin/Vocabulaire/Verba Latina frequentissima/876-900|876-900]] · [[Latin/Vocabulaire/Verba Latina frequentissima/901-925|901-925]] · [[Latin/Vocabulaire/Verba Latina frequentissima/926-950|926-950]] · [[Latin/Vocabulaire/Verba Latina frequentissima/951-975|951-975]] · [[Latin/Vocabulaire/Verba Latina frequentissima/976-1000|976-1000]]
</div>
jasfyi60l4zxrrah9gbv2c3ry2iwvab
767804
767803
2026-06-16T04:06:43Z
PandaMystique
119061
767804
wikitext
text/x-wiki
* [[Latin/Vocabulaire/Verba Latina frequentissima/001-025|001-025]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/026-050|026-050]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/051-075|051-075]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/076-100|076-100]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/101-125|101-125]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/126-150|126-150]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/151-175|151-175]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/176-200|176-200]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/201-225|201-225]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/226-250|226-250]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/251-275|251-275]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/276-300|276-300]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/301-325|301-325]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/326-350|326-350]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/351-375|351-375]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/376-400|376-400]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/401-425|401-425]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/426-450|426-450]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/451-475|451-475]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/476-500|476-500]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/501-525|501-525]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/526-550|526-550]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/551-575|551-575]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/576-600|576-600]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/601-625|601-625]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/626-650|626-650]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/651-675|651-675]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/676-700|676-700]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/701-725|701-725]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/726-750|726-750]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/751-775|751-775]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/776-800|776-800]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/801-825|801-825]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/826-850|826-850]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/851-875|851-875]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/876-900|876-900]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/901-925|901-925]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/926-950|926-950]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/951-975|951-975]]
* [[Latin/Vocabulaire/Verba Latina frequentissima/976-1000|976-1000]]
5mcoi79ffsun9kw8nenyuj0a82meiz1
Discussion utilisateur:~2026-34853-34
3
83947
767796
2026-06-15T19:34:01Z
JackPotte
5426
Page créée avec « {{subst:Test 1}}~~~~ »
767796
wikitext
text/x-wiki
{|class="WSerieH" class="plainlinks" id="vandale" align="center" style="width:100%;margin-bottom:2em;border:1px solid #8888aa;border-right-width:2px;border-bottom-width:2px;background-color:#f7f8ff;padding:5px;text-align:justify"
|-
|[[Image:Nuvola apps important.svg|64px|Arrêtez de vandaliser Wikilivres !]]
|Bonjour {{BASEPAGENAME}},
Vous avez découvert combien il est facile de modifier Wikilivres. Votre modification a été '''annulée''' en raison de son caractère non constructif. Merci de ne pas réitérer ce genre de contribution. Visitez la [[Aide:Accueil|page d’aide]] afin d’en apprendre plus ou le [[Wikilivres:bac à sable|bac à sable]] afin de faire des tests.
|}
[[Catégorie:Vandales avertis]][[Utilisateur:JackPotte|JackPotte]] ([[Discussion utilisateur:JackPotte|<span style="color:#FF6600">$</span>♠]]) 15 juin 2026 à 21:34 (CEST)
103volyfryg09b6rgbr3ftkxuuzuvjt
Dictionnaire de philosophie/K
0
83948
767820
2026-06-16T11:35:07Z
PandaMystique
119061
Page créée avec « {{DicoPhilo|K}} <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5em; width: 100%;"> <div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);"> :[[Dictionnaire de philosophie/Pierre Kropotkine|Kropotkine, Pierre]] </div> <div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); borde... »
767820
wikitext
text/x-wiki
{{DicoPhilo|K}}
<div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5em; width: 100%;">
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
:[[Dictionnaire de philosophie/Pierre Kropotkine|Kropotkine, Pierre]]
</div>
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
</div>
<div style="padding: 1.5em; background: linear-gradient(135deg, #ffffff40 0%, #e0e4e840 100%); border-radius: 10px; box-shadow: 0 3px 10px rgba(0,0,0,0.1);">
</div>
</div>
{{PhiloRecherche}}
{{autocat}}
btzoh8yvzji4vk4ab17at2hs8bbvuyl