Skip to content

Python – Chaines de formatage

10 décembre 2014

En Python, quand on veut afficher plusieurs valeurs de types différents sur une même ligne, il existe plusieurs manières de le faire.

1re méthode

On peut concaténer toutes les valeurs ensemble pour faire un seul paramètre pour la fonction print().
Rappel : La concaténation est l’opération qui consiste à « coller » des chaînes de caractères pour en former une seule. Elle se fait en Python grâce à l’opérateur +
Évidemment, avant de pouvoir concaténer les valeurs qui ne sont pas des chaînes, il faut d’abord les convertir, grâce à la fonction str.
Exemple :

print("La somme de " + str(a) + " et " + str(b) + " est " + str(a+b))

Autre façon de faire

La fonction print() accepte plusieurs paramètres (séparés par des virgules) qui peuvent être de n’importe quel type. Elle les affiche en les séparant par une espace par défaut (ou par un autre séparateur si l’on a spécifié le paramètre sep).
Exemple :

# Cet exemple montre l'intérêt du formatage
# version du 08/12/2014 (sans formatage)

# affectations
prod1, prix1 = "oeuf", 12 # nom et prix du produit N°1
prod2, prix2 = "pain", 8
prod3, prix3 = "camembert", 160
prod4, prix4 = "pistache", 1250

# affichage
print("Alimentation Générale")
print("=" * 21)
print()  # affiche une ligne vide
print(prod1, "coûte", prix1, "DA")
print(prod2, "coûte", prix2, "DA")
print(prod3, "coûte", prix3, "DA")
print(prod4, "coûte", prix4, "DA")

On remarque au passage dans cet exemple que certaines lignes contiennent le caractère #. Quand l’interpréteur Python rencontre ce caractère, il l’ignore lui et tout ce qui suit dans cette ligne, et passe directement à la ligne suivante. Ce qui suit un caractère # est un commentaire.

On remarque aussi à la ligne 13 une instruction print() sans rien entre les parenthèses. La fonction print(), quand elle est utilisée sans paramètre, sert seulement à sauter une ligne.

À l’exécution, on obtient l’affichage suivant :

Alimentation Générale
=====================

oeuf coûte 12 DA
pain coûte 8 DA
camembert coûte 160 DA
pistache coûte 1250 DA

Utilisation des chaînes de formatage

Le programme de l’exemple précédent fonctionne bien mais ne donne pas un affichage très régulier. Si l’on préfère que les prix soient alignés, il va falloir utiliser un autre moyen.
La 3e méthode proposée ici est la plus compliquée, mais aussi la plus intéressante quand on veut maîtriser l’affichage. C’est celle qui utilise les chaînes de formatage.
Une chaîne de formatage est une chaîne de caractères qui contient des codes de format aux endroits où l’on veut mettre des valeurs.
Par exemple au lieu d’utiliser une chaîne comme celle du 1er exemple :

"La somme de " + str(a) + " et " + str(b) + " est " + str(a+b)

Nous pouvons utiliser la chaîne de formatage "La somme de %d et %d est %d" qui contient le message à afficher avec des codes %d à la place des valeurs, puis on utilise l’opérateur de formatage de chaînes % (ce n’est pas le même que l’opérateur % qui permet d’obtenir le reste de la division de deux entiers, mais il s’écrit de la même façon) que l’on fait suivre de la liste des valeurs à insérer dans la chaîne. Ce qui donne :

>>> a, b = 36, 6
>>> "La somme de %d et %d est %d" % (a, b, a + b)
'La somme de 36 et 6 est 42'

(Dans un programme nous utiliserions print() pour l’affichage)
Nous avons mis le code de format %d car il sera remplacé par une valeur entière. Suivant le type de valeur que l’on veut formater, on utilise différents codes de format :

  • %d ou %i pour un entier (int)
  • %f pour un réel (float)
  • %s pour une chaîne (str)
  • etc.

Il en existe beaucoup (ce sont les mêmes que ceux du langage C) mais les plus utiles pour l’instant sont les trois ci-dessus.

Remarquons que les valeurs doivent être mises entre parenthèses et séparées par des virgules. S’il n’y en a qu’une seule les parenthèses ne sont pas obligatoires. Exemple : "Cher Monsieur %s, bonjour." % nom

Attention, si l’on ne met pas autant de codes de format qu’il y a de valeurs, on obtient un message d’erreur :

>>> "La somme de %d et %d est %d" % (a, a + b)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: not enough arguments for format string
>>> "La somme de %d et %d est " % (a, b, a + b)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: not all arguments converted during string formatting

Transformons notre programme :

# Cet exemple montre l'intérêt du formatage
# version du 08/12/2014 avec formatage

# affectations
prod1, prix1 = "oeuf", 12 # nom et prix du produit N°1
prod2, prix2 = "pain", 8
prod3, prix3 = "camembert", 160
prod4, prix4 = "pistache", 1250

# affichage
print("Alimentation Générale")
print("=" * 21)
print()  # affiche une ligne vide
print("%s coûte %d DA" % (prod1, prix1))
print("%s coûte %d DA" % (prod2, prix2))
print("%s coûte %d DA" % (prod3, prix3))
print("%s coûte %d DA" % (prod4, prix4))

Essayez-le. Pour l’instant, le résultat est exactement le même que celui de la 1re version.
Alors pourquoi s’est-on cassé la tête :-/ ?
Attendez ! Nous n’avons pas fini : l’intérêt de ce formatage de chaîne est que les codes de format sont réglables.
On veut aligner l’affichage. Pour cela, il va falloir spécifier que les noms des produits doivent occuper toujours le même nombre de caractères. C’est possible en ajoutant dans le code de format %s, entre le % et le s, ce nombre de caractères.
Comme le nombre de lettres du plus grand nom de produit est 9, changeons les lignes d’affichage ainsi :

print("%10s coûte %d DA" % (prod1, prix1))
print("%10s coûte %d DA" % (prod2, prix2))
print("%10s coûte %d DA" % (prod3, prix3))
print("%10s coûte %d DA" % (prod4, prix4))

On obtient :

      oeuf coûte 12 DA
      pain coûte 8 DA
 camembert coûte 160 DA
  pistache coûte 1250 DA

C’est beaucoup mieux, non ?
Ce que l’on a obtenu, c’est que les valeurs des noms de produits qui ne font pas 10 caractères ont été complétées à gauche par des espaces pour qu’elles en occupent 10. Ainsi, 6 espaces ont été ajoutées avant oeuf et pain, une espace avant camembert et 2 avant pistache.
Mais il reste des problèmes :

  • Les DA ne sont pas alignés. Pour cela il faudra régler le code de format des prix pour qu’ils occupent tous le même nombre de caractères, disons 5 : nous mettrons alors %5d
  • Les noms sont alignés à droite ; ce serait mieux s’ils étaient alignés à gauche. Pour cela, il suffit de changer le réglage de %s et mettre une valeur négative, c’est-à-dire : %-10s

Voici les changements à faire :

print("%-10s coûte %5d DA" % (prod1, prix1))
print("%-10s coûte %5d DA" % (prod2, prix2))
print("%-10s coûte %5d DA" % (prod3, prix3))
print("%-10s coûte %5d DA" % (prod4, prix4))

Et voici le résultat :

oeuf       coûte    12 DA
pain       coûte     8 DA
camembert  coûte   160 DA
pistache   coûte  1250 DA

C’est beaucoup plus présentable, n’est-ce pas ?

Ce n’est pas fini. Nous avons fait une petite erreur dans le programme : le pain ne coûte pas 8 DA mais 8,50 DA ! Arrangeons cela :

prod2, prix2 = "pain", 8.50

À l’exécution, on obtient :

oeuf       coûte    12 DA
pain       coûte     8 DA
camembert  coûte   160 DA
pistache   coûte  1250 DA

O_o pourquoi a-t-on obtenu la même chose ? Parce que %d permet d’afficher la valeur sous la forme d’un entier ! Il faut donc mettre %f à la place :

print("%-10s coûte %5f DA" % (prod1, prix1))
print("%-10s coûte %5f DA" % (prod2, prix2))
print("%-10s coûte %5f DA" % (prod3, prix3))
print("%-10s coûte %5f DA" % (prod4, prix4))

Cela devrait marcher maintenant :

oeuf       coûte 12.000000 DA
pain       coûte 8.500000 DA
camembert  coûte 160.000000 DA
pistache   coûte 1250.000000 DA

Mais pourquoi y a-t-il autant de zéros ??? Cela n’est pas très joli, mais c’est parce que le code de format %f donne par défaut 6 chiffres après la virgule.
Heureusement, il existe un deuxième réglage pour les codes de format %f, c’est justement le nombre de décimales. Pour le régler à 2, il suffit de mettre %5.2f :

print("%-10s coûte %5.2f DA" % (prod1, prix1))
print("%-10s coûte %5.2f DA" % (prod2, prix2))
print("%-10s coûte %5.2f DA" % (prod3, prix3))
print("%-10s coûte %5.2f DA" % (prod4, prix4))

Remarque : On peut utiliser le réglage des décimales tout seul (sans régler le nombre de caractères occupés) avec juste %.2f

Cette fois, le résultat est :

oeuf       coûte 12.00 DA
pain       coûte  8.50 DA
camembert  coûte 160.00 DA
pistache   coûte 1250.00 DA

Les deux premiers prix sont alignés mais pas les autres. C’est parce que le réglage de tout à l’heure n’est plus valide : les deux derniers prix occupent plus de 5 caractères maintenant (le plus grand prix en occupe 7), donc le réglage de la taille occupée a été ignoré pour eux (il était trop petit).

Finalement, voici la version définitive :

# Cet exemple montre l'intérêt du formatage
# version finale du 08/12/2014 avec formatage

# affectations
prod1, prix1 = "oeuf", 12 # nom et prix du produit N°1
prod2, prix2 = "pain", 8
prod3, prix3 = "camembert", 160
prod4, prix4 = "pistache", 1250

# affichage
print("Alimentation Générale")
print("=" * 21)
print()  # affiche une ligne vide
print("%-10s coûte %8.2f DA" % (prod1,prix1) )
print("%-10s coûte %8.2f DA" % (prod2,prix2) )
print("%-10s coûte %8.2f DA" % (prod3,prix3) )
print("%-10s coûte %8.2f DA" % (prod4,prix4) )

Et voici son résultat :

Alimentation Générale
=====================

oeuf       coûte    12.00 DA
pain       coûte     8.50 DA
camembert  coûte   160.00 DA
pistache   coûte  1250.00 DA

Dernière remarque :
La réduction du nombre de décimales affichées pour un réel (float) est utile pour masquer les « défauts » de ce type de valeurs.
En effet, il nous est arrivé quand nous essayions des opérations sur des réels de tomber sur des résultats imprécis. C’est parce que les valeurs de ce type sont représentées en binaire avec un certain degré d’imprécision (voir cette page du tutoriel Python pour l’explication).

Voici un exemple :

>>> somme = 0.1 + 0.2
>>> print("la somme est", somme)
la somme est 0.30000000000000004
>>> print("la somme est %.2f" % somme)
la somme est 0.30

Publicités
One Comment

Trackbacks & Pingbacks

  1. L1ST – Informatique1 : chapitre 3 (1-89) | nh2's blog

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

%d blogueurs aiment cette page :