1.2. Formatage des affichages#
Dans tout langage, il est essentielle de pouvoir formater les sorties, c’est-à-dire de pouvoir décider et fixer comment les nombres sont affichés (que ce soit dans un fichier ou dans le terminal).
Formater signifie donner un format. Cela a plusieurs intérêts :
écrire plus joliement en permettant par exemple d’aligner correctement les nombres \(\Rightarrow\) cela facilite la lecture ;
avoir un format identique et prévisible pour les grands tableaux de nombres écrits dans des fichiers \(\Rightarrow\) cela facilite l’automatisation.
Le formatage consiste à donner une règle à python
pour transformer les données à afficher en une chaîne de caractères. Plusieurs possibilités, plus ou moins anciennes, existent : nous utiliserons la méthode la plus moderne et la plus efficace, les fstring
.
1.2.1. Les fstring
#
Une fstring
est une chaîne de caractères précédée du caractère f
. Par exemple f"toto"
. Il est alors possible d’afficher une fstring
à l’aide de la commande print
(nous verrons plus loin comment remplacer print
pour écrire directement dans un fichier).
ma_fstring = f"toto"
print(ma_fstring)
toto
L’intérêt des fstring
est qu’il est possible d’affichier des variables facilement en les entourant par {
et }
. Voici un exemple
x = 10
print(f"La valeur de 3*x est {3*x}")
La valeur de 3*x est 30
Il est alors possible de formater l’affichage de la variable x
en faisant suivre dans les accolades la valeur à afficher par :
puis par le format choisi. Par exemple, pour afficher un nombre entier int
, on peut choisir de l’afficher en base 10 (d
), en base 8 (o
), en base 2 (b
) ou en base 16 (x
). On fait également précédé ce symbole du nombre 5 pour imposer la réservation de 5 cases pour l’affichage.
print("-"*33)
print("| d | b | o | x |")
print("-"*33)
for n in range(25):
print(f"| {n:5d} | {n:5b} | {n:5o} | {n:5x} |")
print("-"*33)
---------------------------------
| d | b | o | x |
---------------------------------
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 2 | 10 | 2 | 2 |
| 3 | 11 | 3 | 3 |
| 4 | 100 | 4 | 4 |
| 5 | 101 | 5 | 5 |
| 6 | 110 | 6 | 6 |
| 7 | 111 | 7 | 7 |
| 8 | 1000 | 10 | 8 |
| 9 | 1001 | 11 | 9 |
| 10 | 1010 | 12 | a |
| 11 | 1011 | 13 | b |
| 12 | 1100 | 14 | c |
| 13 | 1101 | 15 | d |
| 14 | 1110 | 16 | e |
| 15 | 1111 | 17 | f |
| 16 | 10000 | 20 | 10 |
| 17 | 10001 | 21 | 11 |
| 18 | 10010 | 22 | 12 |
| 19 | 10011 | 23 | 13 |
| 20 | 10100 | 24 | 14 |
| 21 | 10101 | 25 | 15 |
| 22 | 10110 | 26 | 16 |
| 23 | 10111 | 27 | 17 |
| 24 | 11000 | 30 | 18 |
---------------------------------
Il est également possible de remplir les espaces avec des zéros et d’aligner les nombres. Voici des exemples que vous pouvez tester.
print("-"*(10*4+1))
print("| d | b | o | x |")
print("-"*(10*4+1))
for n in range(25):
print(f"| {n:^7d} | {n:>7b} | {n:07o} | {n:07x} |")
print("-"*(10*4+1))
-----------------------------------------
| d | b | o | x |
-----------------------------------------
| 0 | 0 | 0000000 | 0000000 |
| 1 | 1 | 0000001 | 0000001 |
| 2 | 10 | 0000002 | 0000002 |
| 3 | 11 | 0000003 | 0000003 |
| 4 | 100 | 0000004 | 0000004 |
| 5 | 101 | 0000005 | 0000005 |
| 6 | 110 | 0000006 | 0000006 |
| 7 | 111 | 0000007 | 0000007 |
| 8 | 1000 | 0000010 | 0000008 |
| 9 | 1001 | 0000011 | 0000009 |
| 10 | 1010 | 0000012 | 000000a |
| 11 | 1011 | 0000013 | 000000b |
| 12 | 1100 | 0000014 | 000000c |
| 13 | 1101 | 0000015 | 000000d |
| 14 | 1110 | 0000016 | 000000e |
| 15 | 1111 | 0000017 | 000000f |
| 16 | 10000 | 0000020 | 0000010 |
| 17 | 10001 | 0000021 | 0000011 |
| 18 | 10010 | 0000022 | 0000012 |
| 19 | 10011 | 0000023 | 0000013 |
| 20 | 10100 | 0000024 | 0000014 |
| 21 | 10101 | 0000025 | 0000015 |
| 22 | 10110 | 0000026 | 0000016 |
| 23 | 10111 | 0000027 | 0000017 |
| 24 | 11000 | 0000030 | 0000018 |
-----------------------------------------
Il est possible d’automatiser tout cela en imbriquant les fstring
:
# format
# N : le nombre de cases à réserver
# d : pour avoir un entier écrit en écriture décimale
# {variable:Nd}
x = 5
print("-"*((x+3)*4+1))
print(f"| {'d':^{x}} | {'b':^{x}} | {'o':^{x}} | {'x':^{x}} |")
print("-"*((x+3)*4+1))
for n in range(25):
print(f"| {n:{x}d} | {n:{x}b} | {n:{x}o} | {n:{x}x} |")
print("-"*((x+3)*4+1))
---------------------------------
| d | b | o | x |
---------------------------------
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |
| 2 | 10 | 2 | 2 |
| 3 | 11 | 3 | 3 |
| 4 | 100 | 4 | 4 |
| 5 | 101 | 5 | 5 |
| 6 | 110 | 6 | 6 |
| 7 | 111 | 7 | 7 |
| 8 | 1000 | 10 | 8 |
| 9 | 1001 | 11 | 9 |
| 10 | 1010 | 12 | a |
| 11 | 1011 | 13 | b |
| 12 | 1100 | 14 | c |
| 13 | 1101 | 15 | d |
| 14 | 1110 | 16 | e |
| 15 | 1111 | 17 | f |
| 16 | 10000 | 20 | 10 |
| 17 | 10001 | 21 | 11 |
| 18 | 10010 | 22 | 12 |
| 19 | 10011 | 23 | 13 |
| 20 | 10100 | 24 | 14 |
| 21 | 10101 | 25 | 15 |
| 22 | 10110 | 26 | 16 |
| 23 | 10111 | 27 | 17 |
| 24 | 11000 | 30 | 18 |
---------------------------------
Les formats possibles sont
d
: entier en base 10 signé
o
: entier en base 8 non signé
x
: entier en base 16 non signé (lettres en minuscule)
X
: entier en base 16 non signé (lettres en majuscule)
e
: réel en format exponentiel (e en minuscule)
E
: réel en format exponentiel (E en majuscule)
f
ouF
: réel en format nombre à virgule
g
: choisi entree
etf
selon l’exposant du nombre
G
: choisi entreE
etF
selon l’exposant du nombre
c
: un unique caractère qui peut être un entier ou un caractère
r
: chaine de caractère (en utilisant la fonction membrerepr()
)
s
: chaine de caractère (en utilisant la fonction membrestr()
)
NB : pour les formats qui permettent d’afficher des nombres à virgules (F
, E
, G
), il est possible d’imposer à la fois la place réservée et le nombre de chiffre après la virgule. Par exemple, le format 10.7F
réserve 10 cases avec 7 chiffres après la virgule pour un nombre flottant.
Autre exemple, le format 10.3E
réserve 10 cases avec 3 chiffres après la virgule pour un nombre au format exponentiel.
n = 3
x = 3.14
print(f"L'entier n vaut {n:d}.")
print(f"L'entier n vaut {n:2d}.")
print(f"L'entier n vaut {n:02d}.")
print(f"Le réel x vaut {x:f}.")
print(f"Le réel x vaut {x:4.2f}.")
print(f"Le réel x vaut {x:10.7f}.")
print(f"Le réel 1000x vaut {1000*x:10.3e}.")
print(f"Le réel .001x vaut {.001*x:10.3e}.")
L'entier n vaut 3.
L'entier n vaut 3.
L'entier n vaut 03.
Le réel x vaut 3.140000.
Le réel x vaut 3.14.
Le réel x vaut 3.1400000.
Le réel 1000x vaut 3.140e+03.
Le réel .001x vaut 3.140e-03.
Il est possible d’ajouter des caractères spéciaux comme \n
pour aller à la ligne ou \t
pour faire une tabulation.
print(f"L'entier n vaut \t{n:02d}.\nLe réel x vaut \t\t{x:4.2f}.")
L'entier n vaut 03.
Le réel x vaut 3.14.
import math
x = -math.sqrt(2)
print(f"x = {x:12.1F}|")
print(f"x = {x:12.9F}|")
print(f"x = {x:12.5E}|")
x = -1.4|
x = -1.414213562|
x = -1.41421E+00|
1.2.2. Autres méthodes#
Même si vous respectez la nouvelle norme de formatage des chaînes de caractères, vous pourrez rencontrer des syntaxes plus anciennes. Voici quelques exemples à savoir lire mais surtout pas à reproduire !
a = 1
x = 3.14
grand_nombre = x*1.e17
petit_nombre = x*1.e-17
s = "Je peux afficher un entier %2d ou un réel %10.7f" % (a, x)
print(s)
s = "Un grand ou un petit nombre %10.3e, %10.3e" % (grand_nombre, petit_nombre)
print(s)
Je peux afficher un entier 1 ou un réel 3.1400000
Un grand ou un petit nombre 3.140e+17, 3.140e-17
s = "Je peux afficher un entier %2d ou un réel %10.7f".format(a, x)
print(s)
s = "Un grand ou un petit nombre %10.3e, %10.3e".format(grand_nombre, petit_nombre)
print(s)
Je peux afficher un entier %2d ou un réel %10.7f
Un grand ou un petit nombre %10.3e, %10.3e