Good programming practices

Reading time10 min

En bref

Résumé de l’article

Dans cet article, nous discutons de quelques bonnes pratiques de programmation que vous devriez garder à l’esprit lorsque vous écrivez un programme. Elles vous aident à garder vos codes propres, faciles à mettre à jour, et à éviter les erreurs de programmation.

Points clés

  • Un code doit être lisible, avec une indentation appropriée, des noms et des commentaires adéquats.

  • Évitez d’utiliser des valeurs fixes, privilégiez les variables et les constantes.

Contenu de l’article

Un programme qui fait ce qu’il est censé faire est excellent, mais un programme que vous pouvez partager, étendre et réutiliser est encore mieux. Ce cours introduit des recommandations indépendantes du langage pour écrire des programmes de qualité, avant de se concentrer sur les bonnes pratiques de programmation en Python.

1 — Recommandations universelles

Quel que soit le langage de programmation utilisé pour implémenter vos algorithmes, certaines bonnes pratiques universelles valent la peine d’être suivies pour garantir une haute qualité de code. Cette qualité peut notamment être mesurée selon trois critères.

1.1 — Lisibilité

De nombreuses règles très simples facilitent la lecture du code source. Acquérir ces bonnes habitudes dès les premières étapes de la carrière d’un programmeur est très important. Voici quelques notions stylistiques clés qui influencent la lisibilité du code.

1.1.1 — Indentation

“L’indentation” fait référence à l’utilisation d’espaces ou de tabulations pour matérialiser des blocs d’instructions. Malgré le débat entre 4 espaces ou une tabulation, une utilisation cohérente et constante de l’indentation est très importante pour rendre votre code plus facile à lire.

Exemple

Voici deux exemples de codes Java qui font exactement la même chose, mais avec une différence claire en termes de lisibilité.

/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

/**
 * This is the entry point of your program.
 * It contains the first codes that are going to be executed.
 * 
 * @param args Command line arguments received.
 */
public static void main (String[] args) {
// Work on a string
String input = "aabbccddeeffgghh";
StringBuilder result = new StringBuilder(input);
// Iterate over each character in the string
for (int i = 0; i < input.length(); i++) {
// Check all subsequent characters for repetition
char currentChar = input.charAt(i);
boolean isRepeated = false;
for (int j = i + 1; j < input.length(); j++) {
if (currentChar == input.charAt(j)) {
// Convert repeated characters to uppercase in the result string
isRepeated = true;
for (int k = j; k < input.length(); k++) {
if (result.charAt(k) == currentChar) {
result.setCharAt(k, Character.toUpperCase(currentChar));
}
}
}
}
// Convert the current character to uppercase if it is repeated
if (isRepeated) {
result.setCharAt(i, Character.toUpperCase(currentChar));
}
}
// Print the result
System.out.println("Original string: " + input);
System.out.println("Transformed string: " + result);
}
}
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Work on a string
        String input = "aabbccddeeffgghh";
        StringBuilder result = new StringBuilder(input);
        // Iterate over each character in the string
        for (int i = 0; i < input.length(); i++) {
            // Check all subsequent characters for repetition
            char currentChar = input.charAt(i);
            boolean isRepeated = false;
            for (int j = i + 1; j < input.length(); j++) {
                if (currentChar == input.charAt(j)) {
                    // Convert repeated characters to uppercase in the result string
                    isRepeated = true;
                    for (int k = j; k < input.length(); k++) {
                        if (result.charAt(k) == currentChar) {
                            result.setCharAt(k, Character.toUpperCase(currentChar));
                        }
                    }
                }
            }
            // Convert the current character to uppercase if it is repeated
            if (isRepeated) {
                result.setCharAt(i, Character.toUpperCase(currentChar));
            }
        }
        // Print the result
        System.out.println("Original string: " + input);
        System.out.println("Transformed string: " + result);
    }
}
Information

Nous ne fournissons pas de code Python ici, car l’indentation fait partie de la syntaxe de Python. Nous aborderons ce point plus tard.

1.1.2 — Conventions de nommage

“La convention de nommage” fait référence à l’ensemble des règles utilisées pour déterminer le nom et la casse des fichiers, variables, constantes, modules, classes, fonctions, méthodes. Quel que soit le langage, les noms donnés à ces différents éléments de code doivent être explicites afin que le sens de leur contenu puisse être déduit directement du nom. Le nom d’une constante est généralement en majuscules.

Exemple

Utilisez employee_management.py, result, weight, getPasswordAge() au lieu de prog1.py, a, x1, pwd(), etc.

Information

Cela peut sembler évident pour certains d’entre vous, mais, en tant qu’enseignants, nous avons rencontré des variables dans les programmes des étudiants nommées comme (exemples réels) :

  • li, lili, lilili lililili, etc.
  • papa, maman, etc.
  • x1, x2, x3, x4, x5, etc.

Essayez d’imaginer un de vos amis vous demandant de l’aide pour déboguer son programme, et l’effort mental que cela vous demanderait de comprendre que papa est le total au carré des dépenses clients du mois dernier.

1.1.3 — Évitez généralement l’utilisation directe (ou la réutilisation directe) de valeurs

Évitez l’utilisation directe de valeurs dans vos instructions, et préférez utiliser des variables et des constantes.

Exemple

Considérez le programme suivant. Imaginez maintenant que vous souhaitez changer la taille de la sous-chaîne sur laquelle nous travaillons de 5 à 8. Lequel est le plus facile à mettre à jour ?

# Work on a string
s = "Hello, World!"

# Capitalize the first characters
s = s[:5].upper() + s[5:]

# Change the vowels among the first characters to 'X'
for c in "AEIOUY":
    s = s[:5].replace(c, 'X') + s[5:]

# Reverse the first characters
s = s[:5][::-1] + s[5:]
# Define a variable for the constant
SUBSTRING_SIZE = 5

# Work on a string
s = "Hello, World!"

# Capitalize the first characters
s = s[:SUBSTRING_SIZE].upper() + s[SUBSTRING_SIZE:]

# Change the vowels among the first characters to 'X'
for c in "AEIOUY":
    s = s[:SUBSTRING_SIZE].replace(c, 'X') + s[SUBSTRING_SIZE:]

# Reverse the first characters
s = s[:SUBSTRING_SIZE][::-1] + s[SUBSTRING_SIZE:]
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Work on a string
        String s = "Hello, World!";

        // Capitalize the first characters
        s = s.substring(0, 5).toUpperCase() + s.substring(5);

        // Change the vowels among the first characters to 'X'
        String firstPart = s.substring(0, 5);
        for (char c : "AEIOUY".toCharArray()) {
            firstPart = firstPart.replace(c, 'X');
        }
        s = firstPart + s.substring(5);

        // Reverse the first characters
        StringBuilder reversedFirstPart = new StringBuilder(firstPart).reverse();
        s = reversedFirstPart + s.substring(5);
    }

}
/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Define a variable for the constant
        int SUBSTRING_SIZE = 5;

        // Work on a string
        String s = "Hello, World!";

        // Capitalize the first characters
        s = s.substring(0, SUBSTRING_SIZE).toUpperCase() + s.substring(SUBSTRING_SIZE);

        // Change the vowels among the first characters to 'X'
        String firstPart = s.substring(0, SUBSTRING_SIZE);
        for (char c : "AEIOUY".toCharArray()) {
            firstPart = firstPart.replace(c, 'X');
        }
        s = firstPart + s.substring(SUBSTRING_SIZE);

        // Reverse the first characters
        StringBuilder reversedFirstPart = new StringBuilder(firstPart).reverse();
        s = reversedFirstPart + s.substring(SUBSTRING_SIZE);
    }

}
1.1.4 — Utilisez des variables locales et évitez les variables globales

Le lieu de définition des variables est un des sujets abordés lors de la session 2, mais en résumé, cela concerne le fait que les variables doivent être définies aussi près que possible des instructions qui les utilisent et ne doivent pas être partagées entre différentes parties de votre programme.

1.2 — Maintenabilité

En général, les logiciels, et donc leur code, évoluent dans le temps. Il est donc vital de s’assurer que vous et votre équipe serez capables de comprendre le code dans une semaine, un mois ou même dans un an. Il y a au moins deux leviers cruciaux pour garantir la maintenabilité du code :

  • Commentez votre code – En utilisant un langage naturel, fournissez à vos collaborateurs une description à jour des fonctionnalités et des stratégies d’implémentation de votre code. Les commentaires doivent apparaître à différents endroits dans votre code, pour décrire le contenu global du fichier, chaque fonction et méthode, les instructions avec une logique non triviale. Dans ce cours, nous commentons la plupart des codes que nous vous donnons, donc consultez nos corrections pour des exemples.

  • Structurez votre code – Pour faciliter sa réutilisabilité. C’est aussi un sujet crucial vu lors de la session 2 concernant la manière dont votre code doit être factorisé et structuré pour permettre une réutilisation des fonctionnalités individuelles.

1.3 — Fiabilité

La fiabilité est liée à la confiance que vous pouvez avoir dans la fonctionnalité que vous fournissez à d’autres développeurs ou au reste de vos projets de programmation. La seule façon de fournir un code fiable est de le structurer judicieusement en fonctionnalités atomiques et indépendantes (session 2) et de tester chacune d’elles (session 3). Une autre façon d’améliorer la fiabilité de votre code est d’éviter de réinventer la roue et de réutiliser autant que possible les fonctionnalités intégrées dans le langage. Les fonctions intégrées ont été largement améliorées et testées pour les rendre sûres à réutiliser.

2 — Bonnes pratiques Python

2.1 — Normes de codage

Chaque langage a son propre ensemble de bonnes pratiques en plus des universelles. Celles-ci sont décrites par des normes, telles que les Python Enhancement Proposals (PEP) 8 pour Python. Ces normes décrivent comment votre programme doit être écrit, pour fournir des recommandations globales à tous les développeurs de ce langage.

Typiquement, vous avez peut-être remarqué quelques différences entre les codes Python et Java que nous vous proposons. En Python, une variable doit être nommée my_variable (cela s’appelle le “snake case”), tandis qu’en Java elle doit être myVariable (cela s’appelle le “camelCase”).

Information

Les normes sont faites pour essayer de faciliter le partage de code entre utilisateurs, et les collaborations. Bien que ce soit une bonne idée d’essayer de les suivre au plus près, elles agissent principalement comme un guide.

La partie la plus importante est d’être “consistent” dans vos codes. Ainsi, il est acceptable de s’écarter un peu de la norme tant que vous respectez cela !

2.2 — Commentez et documentez votre code

Les commentaires sont des phrases courtes placées à divers endroits dans votre code pour décrire, expliquer ou clarifier une étape de votre algorithme ou une stratégie d’implémentation particulière. Les commentaires commencent par # et doivent être concis et clairs pour aider les développeurs à comprendre votre code plus rapidement.

Voici deux versions du code qui font la même chose. Prenez 5 minutes pour comprendre l’algorithme en regardant la version brute, qui est ce qui est produit lorsque l’utilisateur tape “AAZERTYYYYYY”. Puis, comparez la lisibilité de cette version brute avec la seconde, qui respecte les conventions stylistiques et inclut des commentaires.

m = input("Enter the message: ")
em = ""
i = 0

while (i <= len(m) - 1):
    c = 1
    ch = m[i]
    j = i
    while (j < len(m) - 1):
        if (m[j] == m[j+1]):
            c = c + 1
            j = j + 1
        else:
            break
    em = em + str(c) + ch
    i = j + 1

print(em)
"""
  This simple script encodes a message using run-length encoding.
  The principle of this simple encoding is to count the number of times a character appears in a row and then append the count to the character.
  Example: AAAZEEERRRR -> 3A1Z3E4R
"""

# Ask user for a string to work on
message = input("Enter the message to encode: ")

# Initialize variables
encoded_message  = ""
i = 0

# Treat each character in the message
while i <= len(message) - 1:
    
    # Count the number of times the character appears in a row
    count = 1
    ch = message[i]
    j = i
    while j < len(message) - 1 and message[j] == message[j+1]:
        count = count + 1
        j = j + 1

    # Append the count and the character to the encoded message
    encoded_message += str(count) + ch
    i = j + 1

# Display the encoded message
print(encoded_message)
import java.util.Scanner;

public class Main
{

    public static void main (String[] args)
    {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter the message: ");
        String m = scanner.nextLine();

        StringBuilder em = new StringBuilder();
        int i = 0;

        while (i <= m.length() - 1)
        {
            int c = 1;
            char ch = m.charAt(i);
            int j = i;

            while (j < m.length() - 1)
            {
                if (m.charAt(j) == m.charAt(j + 1))
                {
                    c++;
                    j++;
                }
                else
                {
                    break;
                }
            }

            em.append(c).append(ch);
            i = j + 1;
        }

        System.out.println(em.toString());
    }

}
// Useful imports
import java.util.Scanner;

/**
 * To run this code, you need to have Java installed on your computer, then:
 * - Create a file named `Main.java` in a directory of your choice.
 * - Copy this code in the file.
 * - Open a terminal in the directory where the file is located.
 * - Run the command `javac Main.java` to compile the code.
 * - Run the command `java -ea Main` to execute the compiled code.
 * Note: '-ea' is an option to enable assertions in Java.
 */
public class Main {

    /**
     * This is the entry point of your program.
     * It contains the first codes that are going to be executed.
     * This simple script encodes a message using run-length encoding.
     * The principle of this simple encoding is to count the number of times a character appears in a row and then append the count to the character.
     * Example: AAAZEEERRRR -> 3A1Z3E4R
     *
     * @param args Command line arguments received.
     */
    public static void main(String[] args) {
        // Ask user for a string to work on
        Scanner scanner = new Scanner(System.in);
        System.out.print("Enter the message to encode: ");
        String message = scanner.nextLine();

        // Initialize variables
        StringBuilder encodedMessage = new StringBuilder();
        int i = 0;

        // Treat each character in the message
        while (i <= message.length() - 1) {
            // Count the number of times the character appears in a row
            int count = 1;
            char ch = message.charAt(i);
            int j = i;
            while (j < message.length() - 1 && message.charAt(j) == message.charAt(j + 1)) {
                count++;
                j++;
            }

            // Append the count and the character to the encoded message
            encodedMessage.append(count).append(ch);
            i = j + 1;
        }

        // Display the encoded message
        System.out.println(encodedMessage);
    }

}

Alors que les commentaires visent à vous aider, vous et vos collaborateurs, à étendre le code, la documentation agit, en plus, comme un guide plus détaillé pour l’utiliser. Les docstrings sont utilisées pour intégrer la documentation dans votre code. Une section docstring est définie comme suit :

"""
Your docstring documentation
"""
/**
 * Your docstring documentation
 */

Lors de la session 3, vous découvrirez comment documenter les constituants clés de votre code, à savoir les fonctions puis les classes, ainsi que des outils pour exploiter automatiquement les docstrings afin de produire des documentations partageables.

Pour aller plus loin

Il semble que cette section soit vide !

Y a-t-il quelque chose que vous auriez aimé voir ici ? Faites-le nous savoir sur le serveur Discord ! Peut-être pouvons-nous l’ajouter rapidement. Sinon, cela nous aidera à améliorer le cours pour l’année prochaine !

Pour aller au-delà