Plus facile à lire avec un fond crème, une teinte, plus de contraste ou un texte plus grand ? Choisissez vos couleurs et votre texte, une fois pour toutes les pages.

Leçon gratuite

Faire refactoriser du code par un assistant

Après cette leçon: Je peux demander un refactoring à un assistant et prouver que le comportement n’a pas changé.

Leçon de 60 min5 commandesLab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Plus propre, mais pareil ?

Un refactoring (une réécriture qui ne change pas le comportement) est l’une des tâches qu’on confie le plus volontiers à un assistant de code. Le résultat est plus court et plus joli.

Le risque est qu’il ne fasse plus la même chose, sans que rien ne casse à la vue. Cette leçon apprend à demander un refactoring par petits pas et à prouver, avec des chiffres, que rien n’a changé.

À la fin de cette leçon

Remarque

Je peux demander un refactoring à un assistant et prouver que le comportement n’a pas changé.

Mots-clés

MotCe que ça veut direExemple
Refactoringchanger la forme du code sans changer ce qu’il fait
Comportementce que le code rend pour chaque entrée
Petit pasun changement qu’on relit en une minute
Entrée au bordune valeur où une règle change9 et 10
Avant et aprèsles sorties du code avant le changement et après

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Un refactoring se fait par petits pas

Demandez un seul rangement à la fois : remplacer une suite de if par une table, ou renommer une fonction. Plus le pas est petit, plus le diff se relit vite.

Dites aussi ce qui ne doit pas bouger : « ne change aucune sortie, n’ajoute aucune règle, ne corrige rien en passant ». Un diff qui range et qui corrige à la fois ne se relit pas.

Une demande possible

Voici une demande possible : « Dans remise.js, remplace la suite de if par une table des paliers. Ne change aucune sortie et ne touche à aucun autre fichier. Garde les tests tels quels. »

L’assistant peut répondre autrement d’une fois à l’autre. Ne regardez pas d’abord si le code est joli, mais si les sorties sont les mêmes.

La preuve est la comparaison avant et après

Avant le changement, notez ce que rend le code pour une liste d’entrées. Après, lancez la même liste et comparez ligne à ligne. Ce sont les mêmes valeurs, ou ce n’est pas un refactoring.

Choisissez surtout les entrées au bord de chaque règle. C’est là qu’un rangement se trompe le plus souvent.

Comparer deux versions en Python

Code: python
def remise_avant(quantite):
    if quantite >= 20:
        return 15
    if quantite >= 10:
        return 10
    if quantite >= 5:
        return 5
    return 0


PALIERS = [[20, 15], [10, 10], [5, 5]]


def remise_apres(quantite):
    for palier in PALIERS:
        if quantite >= palier[0]:
            return palier[1]
    return 0


# Essayez ensuite PALIERS = [[5, 5], [10, 10], [20, 15]] : que voyez-vous ?
for quantite in [0, 4, 5, 9, 10, 19, 20, 25]:
    if remise_avant(quantite) != remise_apres(quantite):
        print("difference pour", quantite)
print("comparaison finie")

Lancer la comparaison dans le labo

Les quatre Run suivants écrivent dans un dossier demo-refactor/ : le code d’avant, une version rangée, une version au piège et un script de comparaison. Ces versions sont écrites à la main, ce ne sont pas des réponses d’un assistant.

Le piège a une table qui a l’air identique, mais rangée dans l’autre sens. Voyons si la comparaison le voit.

Écrire le code d’avant

Commande
docker exec -w /home/node/project agent sh -c "mkdir -p demo-refactor && printf '%s\n' '// Prix de quantite articles, en centimes, avec une remise par paliers.' 'function remise(quantite) {' '  if (quantite >= 20) return 15;' '  if (quantite >= 10) return 10;' '  if (quantite >= 5) return 5;' '  return 0;' '}' 'function prix(quantite, centimes) {' '  const brut = quantite * centimes;' '  return Math.round(brut - brut * remise(quantite) / 100);' '}' 'module.exports = { prix };' > demo-refactor/avant.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire la version rangée

Commande
docker exec -w /home/node/project agent sh -c "mkdir -p demo-refactor && printf '%s\n' '// Meme calcul, avec les paliers dans une table du plus grand au plus petit.' 'const PALIERS = [[20, 15], [10, 10], [5, 5]];' 'function remise(quantite) {' '  for (const palier of PALIERS) {' '    if (quantite >= palier[0]) return palier[1];' '  }' '  return 0;' '}' 'function prix(quantite, centimes) {' '  const brut = quantite * centimes;' '  return Math.round(brut - brut * remise(quantite) / 100);' '}' 'module.exports = { prix };' > demo-refactor/apres.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire la version au piège

Commande
docker exec -w /home/node/project agent sh -c "mkdir -p demo-refactor && printf '%s\n' '// Une table qui a l’air identique, mais rangee du plus petit au plus grand.' 'const PALIERS = [[5, 5], [10, 10], [20, 15]];' 'function remise(quantite) {' '  for (const palier of PALIERS) {' '    if (quantite >= palier[0]) return palier[1];' '  }' '  return 0;' '}' 'function prix(quantite, centimes) {' '  const brut = quantite * centimes;' '  return Math.round(brut - brut * remise(quantite) / 100);' '}' 'module.exports = { prix };' > demo-refactor/piege.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Écrire la comparaison

Commande
docker exec -w /home/node/project agent sh -c "mkdir -p demo-refactor && printf '%s\n' 'const avant = require(process.argv[2]).prix;' 'const apres = require(process.argv[3]).prix;' '// Les entrees aux bords de chaque palier, plus zero et une grande valeur.' 'const entrees = [0, 4, 5, 9, 10, 19, 20, 25];' 'let differences = 0;' 'for (const quantite of entrees) {' '  const a = avant(quantite, 150);' '  const b = apres(quantite, 150);' '  if (a === b) continue;' '  differences = differences + 1;' '  console.log(\"quantite \" + quantite + \" : \" + a + \" contre \" + b);' '}' 'console.log(differences + \" difference(s) sur \" + entrees.length + \" entrees\");' > demo-refactor/comparer.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Comparer l’avant à chaque version

Commande
docker exec -w /home/node/project/demo-refactor agent sh -c "node comparer.js ./avant.js ./apres.js; node comparer.js ./avant.js ./piege.js"

Affichée ici, non exécutée. Créez un compte gratuit pour appuyer sur Exécuter et la saisir dans le terminal de votre propre labo.

Une erreur fréquente

Attention

Beaucoup pensent que si les tests passent encore après le refactoring, rien n’a changé. Les tests ne couvrent que ce qu’ils vérifient. Comparez aussi les sorties sur les entrées au bord, avant et après : c’est la seule preuve que le comportement est le même.

Exemple travaillé : prix à 150 centimes

ArticlesAvantVersion rangéeVersion au piège
5713713713
9128312831283
10135013501425
20255025502850

Les cellules que les étudiants remplissent restent vides dans cet aperçu.

Plus loin : essayer sur un autre changement

C’est le bon moment pour essayer ces idées sur un autre changement. Ne touchez pas au bogue du labo, qui est le travail de la leçon 6. Demandez plutôt de renommer ou de ranger une fonction de shop.js.

Notez d’abord les sorties de quelques entrées au bord, puis demandez le changement en petit pas, puis comparez. Gardez ce qui a changé, et dites si c’était demandé.

À propos de ce labo et de sa source: Lab agent de code IA : utiliser opencode pour expliquer et corriger du code, et vérifier son travail

Vous enseignez à une classe ? Proposez ce module à vos étudiants avec un guide de l'enseignant, des devoirs corrigés et un laboratoire pour chaque étudiant.