Aller au contenu

Affichages intermédiaires

Les f-string

Depuis la version 3.6 de Python, placer la lettre f devant une chaîne de caractères permet d'intégrer les valeurs de variables dans la chaîne :

>>> n = 5

>>> p = 6

>>> chaine = f"n a pour valeur {n} et p a pour valeur {p}."

>>> chaine
'n a pour valeur 5 et p a pour valeur 6.'

Méthode

Le premier guillemet de la chaîne de caractères doit être précédé de la lettre « f » puis, aux emplacements désirés dans la chaîne, on écrit entre accolades les noms variables dont le contenu sera affiché dans le message.

Cette notation est très pratique pour avoir des messages explicites.

Et avant la version 3.6 ?

Pour une version de Python antérieure à la 3.6, on peut utiliser :

  • La méthode .format() (moins lisible) :

    >>> n = 5
    
    >>> p = 6
    
    >>> chaine = "n a pour valeur {0} et p a pour valeur {1}.".format(n, p)
    
    >>> chaine
    'n a pour valeur 5 et p a pour valeur 6.'
    

  • La concaténation de chaînes et la conversion de type :

    >>> n = 5
    
    >>> p = 6
    
    >>> chaine = "n a pour valeur " + str(n) + " et p a pour valeur " + str(p) + "."
    
    >>> chaine
    'n a pour valeur 5 et p a pour valeur 6.'
    

Fonction print()

La fonction print() permet d'afficher la valeur du contenu d'une variable (et éventuellement un message à l'écran sous forme de chaîne de caractères). Une fonction doit :

  • soit renvoyer une valeur ;
  • soit effectuer un affichage ;
  • soit réaliser un « effet de bord » (sera abordé plus tard dans l'année).

De manière générale, ces trois actions doivent s'exclure mutuellement.

Exemple :

1
2
3
4
5
6
7
8
9
def affichage(nom, age, profession):
    """
    nom - str, chaîne de caractères
    age - int, entier positif ou nul
    profession - str, chaîne de caractères
    Sortie: None - Affiche un texte utilisant nom, age et profession
    """
    print(f"{nom} est âgé de {age} ans et exerce la profession de {profession}.")
    print(f"... il a maintenant rajeuni et son âge est {age//6} ans.")
On exécute :
>>> RESTART --- exemple_fstring.py ---
>>> affichage('Bernard', 48, 'voyageur du temps')
Bernard est âgé de 48 ans et exerce la profession de voyageur du temps.
... il a maintenant rajeuni et son âge est 8 ans.

Utiliser print() pour débuguer

Une boucle while mal programmée peut très vite conduire à une boucle infinie. C'est en faisant des tests réguliers du code, en ajoutant des messages intermédiaires, que l'on arrive à repérer ce type d'erreurs. Voici une méthode « pas à pas » pour repérer une telle erreur :

  1. Code qui comporte une erreur :

    1
    2
    3
    4
    5
    6
    7
    8
    9
    def f(A):
        """
        A - int, entier positif ou nul
        Sortie: int - plus petit entier u tel que u devienne supérieure à A, avec u = 2*u-1.  
        """
        u = 0
        while u < A:
            u = 2*u-1
        return u
    

  2. On appelle ce programme exemple_erreur.py puis on l'exécute :

    >>> RESTART --- exemple_erreur.py ---
    >>> f(10)
    
    Que se passe-t-il ?

    Réponse

    En exécutant f(10), rien ne s'affiche dans la console et celle-ci semble bloquée.

  3. Pour comprendre, on ajoute un affichage intermédiaire sur la valeur de u en ligne 9 puis on ré-exécute le programme :

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    def f(A):
        """
        A - int, entier positif ou nul
        Sortie: int - plus petit entier u tel que u devienne supérieure à A, avec u = 2*u-1.  
        """
        u = 0
        while u < A:
            u = 2*u-1
            print(u)
        return u
    
    On exécute à nouveau :
    >>> RESTART --- exemple_erreur.py ---
    >>> f(10)
    -1
    -3
    -7
    -15
    -31
    -63
    -127
    -255
    -511
    -1023
    -2047
    -4095
    -8191
    ...
    

  4. Les valeurs successives de u sont de plus en plus négatives. Il faut donc :

    1. soit changer le cahier des charges de la fonction (par exemple en recherchant l'entier u tel que u deviennent inférieur à A, avec A entier négatif)
    2. soit changer la valeur initiale de l'accumulateur u.
    Solution a
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def f(A):
        """
        A - int, entier positif ou nul
        Sortie: int - plus grand entier u tel que u devienne inférieur à A, avec u = 2*u-1.  
        """
        u = 0
        while u > A:
            u = 2*u-1
        return u
    
    Solution b
    1
    2
    3
    4
    5
    6
    7
    8
    9
    def f(A):
        """
        A - int, entier positif ou nul
        Sortie: int - plus petit entier u tel que u devienne supérieure à A, avec u = 2*u-1.  
        """
        u = 2
        while u < A:
            u = 2*u-1
        return u
    

Nettoyer son code

Nous l'avons déjà vu, certaines fonctions renvoient une (ou plusieurs) valeurs.

D'autres fonctions ne renverront pas de valeur (on parle alors parfois de procédure plutôt que de fonction). Cela doit apparaître dans le docstring :

1
2
3
4
5
6
7
def nomFonction(parametre1, parametre2):
    """
    parametre1 - type du paramètre, précondition éventuelle
    parametre2 - type du paramètre, précondition éventuelle

    Sortie: None, affiche... (descriptif de l'affichage, lien avec les paramètres)
    """

Le verbe utilisé n'est donc pas « renvoyer » dans ce cas.

Attention !

De manière générale, soit une fonction renvoie une valeur, soit elle effectue un affichage, jamais les deux.
Il est donc obligatoire de nettoyer son code de tous les « print() » qui ont permis de le corriger avant de le rendre à l'enseignant.

On parle ici de fonction avec effet de bord.

Fonction à effet de bord

Le début d'un article wikipedia :

En informatique, une fonction est dite à effet de bord (traduction mot à mot de l'anglais side effect, dont le sens est plus proche d'effet secondaire ) si elle modifie un état en dehors de son environnement local, c'est-à-dire a une interaction observable avec le monde extérieur autre que retourner une valeur. Par exemple, les fonctions qui modifient une variable non locale ou un argument mutable passé par référence, les fonctions qui effectuent des opérations d'entrées-sorties ou les fonctions appelant d'autres fonctions à effet de bord. Souvent, ces effets compliquent la lisibilité du comportement des programmes et/ou nuisent à la réutilisabilité des fonctions et procédures.