Bonnes pratiques de programmation

Temps de lecture10 min

En bref

Résumé de l’article

Cet article est un rappel : un programme qui fonctionne ne suffit pas, et écrire du bon code obéit à des règles. La vidéo ci-dessous, issue du même MOOC que les articles des séances suivantes, passe en revue les principales, qu’un code soit lisible, maintenable et fiable. Ce sont aussi les critères sur lesquels vos livrables seront évalués tout au long du projet.

Points clés à retenir

  • Un code se lit bien plus souvent qu’il ne s’écrit : indentation régulière, et noms explicites pour les fichiers, les variables et les fonctions.

  • Les valeurs écrites en dur sont à éviter : une constante nommée se comprend à la lecture, et se modifie à un seul endroit.

  • Un code se reprend, par vos coéquipiers comme par vous-même des mois plus tard : commentez ce qui n’est pas évident, et documentez vos fonctions.

  • Un code se structure en fonctions courtes et indépendantes, que l’on peut réutiliser et tester une par une.

  • Chaque langage a ses propres conventions, décrites par une norme : en Python, c’est la PEP 8.

Contenu de l’article

Vidéo

Veuillez consulter la vidéo ci-dessous (en anglais, affichez les sous-titres si besoin). Nous fournissons également une traduction du contenu de la vidéo juste après, si vous préférez.

Information
Cliquez ici pour afficher la traduction de la vidéo.

Introduction

Bonjour, et bienvenue dans cette leçon. Nous allons nous intéresser aujourd’hui aux bonnes pratiques de programmation.

Pourquoi adopter de bonnes pratiques de programmation ?

Programmer ne consiste pas seulement à écrire des lignes de code les unes après les autres. C’est une activité complexe et exigeante, qui demande une certaine maîtrise. Je vais vous présenter quelques bonnes pratiques importantes, à garder en permanence à l’esprit lorsque vous codez.

Ne pas optimiser directement

Tout d’abord : n’optimisez pas tout de suite ! Comme nous le verrons dans les semaines à venir, programmer revient souvent à chercher le meilleur compromis entre la correction du code et sa rapidité.

Le problème, c’est que la rapidité s’obtient en exploitant des structures de données adaptées, des algorithmes élaborés, et parfois même des astuces de bas niveau pour accélérer les calculs. Bien souvent, ces optimisations pèsent sur la lisibilité du code, et il devient plus difficile de voir ce qu’il fait.

Commencez donc toujours par obtenir un programme correct : la rapidité n’a pas à être un critère à ce stade, et les optimisations pourront venir plus tard. Il est toujours bien plus simple de déboguer un code écrit pour être correct qu’un code écrit pour être rapide.

Structurer le code

Programmer est difficile, et ce n’est un secret pour personne. Pourquoi ? Parce que les langages de programmation ne sont pas faits pour être compris facilement par des humains, mais pour être traités facilement par des machines.

Écrire du code, c’est décrire explicitement et sans ambiguïté les détails d’une méthode donnée. Autrement dit, c’est décrire cette méthode à l’aide des notions élémentaires offertes par un langage de programmation.

La plupart du temps, un(e) programmeur(se) ne raisonne pas au niveau du langage lui-même : il ou elle s’appuie sur des couches d’abstraction.

Prenons l’exemple de la recherche d’un plus court chemin dans un graphe : il n’existe pas de fonction find_the_shortest_path en Python. Nous allons donc la programmer, pour pouvoir ensuite nous en servir dans des tâches plus complexes.

Programmer, c’est empiler des couches de plus en plus abstraites, jusqu’à ce que votre programme puisse s’écrire à l’aide de quelques fonctions seulement.

Dans ce cours, nous utiliserons la théorie des graphes pour jouer dans un labyrinthe. Nous commencerons par trouver des chemins, puis le plus court d’entre eux, puis plusieurs plus courts chemins, et enfin nous tiendrons compte de l’adversaire.

C’est ce que l’on appelle structurer le code, et un code devrait toujours être structuré. En règle générale, essayez d’écrire des fonctions qui ne dépassent pas une quinzaine de lignes : au-delà, il est sans doute temps de découper votre fonction en plusieurs sous-fonctions.

Factoriser le code

Un(e) programmeur(se) ne devrait jamais, au grand jamais, utiliser le copier/coller pour développer un code.

Si l’envie vous en prend malgré tout, créez plutôt une sous-fonction contenant les lignes que vous vouliez dupliquer.

C’est très important, car un jour vous voudrez modifier votre code, le faire évoluer pour prendre en compte de nouvelles entrées, ou en optimiser une partie. Tout est bien plus simple quand ce qu’il faut mettre à jour se trouve à un seul endroit.

Une source d’erreurs fréquente est de modifier des lignes dupliquées en oubliant les autres occurrences présentes dans le code.

Pas de constantes mystérieuses

Tout ce qui paraît arbitraire dans un code est à éviter. Par exemple, vous pourriez vouloir utiliser l’infini dans votre code, mais une telle valeur n’existe pas dans la mémoire d’un ordinateur.

Une astuce consiste à utiliser à la place un grand nombre, disons 100 000, défini une seule fois au début de votre code sous un nom explicite, comme infinity_value. Lorsque vous relirez ce code, peut-être des années plus tard, il sera bien plus facile de comprendre ce qu’est infinity_value que ce qu’est 100 000.

Des entrées/sorties explicites et des commentaires

Enfin, écrivez toujours votre code en pensant qu’il sera lu par quelqu’un d’autre. C’est évidemment le cas si vous travaillez en équipe, mais même seul(e), ajouter des commentaires est un bon moyen de vous assurer que ce que vous faites est correct.

Une bonne façon d’utiliser les commentaires est de les écrire d’abord, puis d’ajouter le code avec parcimonie entre eux. Si vous ne savez pas quels commentaires écrire, commencez par une description explicite de la fonction avant d’écrire le code correspondant : une courte description de son fonctionnement, le détail de ses paramètres et de ses sorties, et des remarques sur ses conditions de correction.

Programmer n’est pas, et ne devrait jamais être, une question de nombre de lignes écrites par minute. S’il faut une heure pour écrire une ligne, qu’il en soit ainsi : peut-être cette ligne sera-t-elle utilisée par des centaines ou des milliers de programmeur(se)s, et elle vaudra alors chaque instant que vous y aurez passé.

Si vous suivez tous ces principes, vous avez toutes les clés pour devenir un(e) excellent(e) programmeur(se). Merci d’avoir suivi cette leçon, et à la prochaine fois !

Pour aller plus loin

La PEP 8, la norme de style de Python

Les règles de la vidéo sont volontairement indépendantes du langage. En Python, elles sont précisées par une norme, la PEP 8 (Python Enhancement Proposal), écrite par les concepteur(rice)s du langage. Elle tranche ce que la vidéo laisse ouvert :

  • 4 espaces par niveau d’indentation, jamais de tabulation ;
  • snake_case pour les variables, les fonctions et les modules, CamelCase pour les classes, MAJUSCULES_AVEC_UNDERSCORES pour les constantes ;
  • des lignes courtes, une ligne vide entre les fonctions, deux entre les classes ;
  • des espaces autour des opérateurs, mais pas à l’intérieur des parenthèses ;
  • les imports en tête de fichier, un par ligne.

Sa cousine la PEP 257 fait de même pour les docstrings, c’est-à-dire pour la documentation que vous écrivez à l’intérieur de vos fonctions et de vos classes.

Information

La PEP 8 n’est pas un règlement, et elle le dit elle-même : “a foolish consistency is the hobgoblin of little minds”. S’en écarter est légitime quand la suivre rendrait le code moins lisible.

En revanche, dans un travail à trois, c’est elle qui évite de trouver trois styles différents dans le même dépôt. Fixez-la comme convention commune dès la première séance, plutôt que d’uniformiser le code la veille du livrable.

Faire vérifier son code automatiquement dans VSCode

Ces règles n’ont pas à être vérifiées à la main. Deux familles d’outils s’en chargent :

  • Les formateurs réécrivent le code pour le rendre conforme : indentation, espaces, retours à la ligne, guillemets. Ils ne changent pas ce que le programme fait.

  • Les linters, ou vérificateurs statiques, lisent le code sans l’exécuter et signalent ce qui s’écarte de la norme ou ce qui ressemble à une erreur : variable déclarée puis jamais utilisée, import inutile, docstring manquante, nom non conforme…

Dans VSCode, ces outils s’installent comme des extensions, et leurs remarques apparaissent soulignées dans l’éditeur et listées dans l’onglet Problems :

Extension Ce qu’elle apporte
Ruff Un formateur et un linter à la fois, très rapide. Le plus simple pour commencer.
Pylint Un linter plus bavard, qui note votre code sur 10 selon les écarts à la PEP 8.
Mypy Type Checker Vérifie que les types annoncés dans vos fonctions sont cohérents avec leur usage.

Pensez également au réglage Editor: Format On Save, vu en environnement : le formatage devient automatique à chaque sauvegarde, et cesse d’être un sujet de discussion dans le groupe.

Enfin, vous pouvez lancer ces outils sans rien installer, depuis votre pyrat_workspace :

​
uvx ruff check .    # signale les écarts et les erreurs probables
uvx ruff format .   # met le code en forme
Important

Ces outils ne jugent que la forme. Un fichier noté 10/10 par un linter peut rester incompréhensible : aucun d’eux ne vous dira que a est un mauvais nom pour une table de routage, qu’un commentaire ne correspond plus au code qu’il décrit, ou qu’une fonction de 200 lignes mériterait d’être découpée.

Ils sont là pour retirer le bruit, afin que votre relecture (et la nôtre) porte sur le fond.

Pour aller encore plus loin

  • Dans cet article, nous discutons de quelques bonnes pratiques de programmation que vous devriez garder à l'esprit lorsque vous écrivez un programme.

    10 min de lecture

  • Python est devenu l'un des langages de programmation les plus populaires, notamment grâce à sa flexibilité et la simplicité de sa syntaxe.

    10 min de lecture