Article original : Do You Solve Programming Problems or Complete Exercises? (The Difference Matters.)

Par Amy Haddad

Les gens ont tendance à utiliser les termes « problèmes » et « exercices » de manière interchangeable. Mais il y a une différence — et cela compte.

Le professeur Paul Zeitz fait la distinction.

Prenez 5 × 5. C'est facile, et c'est un exercice. Il en va de même pour 5 490 900 × 496. C'est un peu plus difficile et cela vous prendra plus de temps à résoudre, mais vous savez ce que vous devez faire. C'est le point clé.

« Un exercice est une question mathématique à laquelle vous savez immédiatement comment répondre », explique Zeitz dans une série de conférences sur la résolution de problèmes. « Vous ne pouvez pas y répondre correctement, en fait vous ne pourrez peut-être jamais y répondre correctement... mais il n'y a aucun doute sur la manière de procéder. »

Ce n'est pas le cas avec les problèmes. Selon Zeitz, « un problème est une question mathématique à laquelle vous ne savez pas comment répondre, du moins initialement. »

Il définit les problèmes et les exercices à travers le prisme de la résolution de problèmes mathématiques, mais ils sont également applicables à la programmation.

Chaque jour, nous mettons nos compétences en résolution de problèmes à l'œuvre en tant que programmeurs : débogage de code, apprentissage d'un nouveau sujet, ou même résolution d'un problème. Les exercices ont leur place, mais en tant que programmeur, il n'y a pas de substitut à la résolution de problèmes.

S'exercer avec des exercices

Il y a deux façons de tirer parti des exercices. Tout d'abord, ils sont utiles lors de l'apprentissage d'un nouveau sujet.

J'apprends JavaScript en ce moment et j'utilise un mélange d'exercices et de problèmes pour ce faire. Les exercices m'aident à voir des motifs et à me familiariser avec les concepts et la syntaxe.

Voici un exemple d'exercice issu d'un projet qui m'a demandé d'écrire une fonction prenant un tableau de voitures.

const cars = [
  { id: 1, car_make: "Lincoln", car_model: "Navigator", car_year: 2009 },
  { id: 2, car_make: "Mazda", car_model: "Miata MX-5", car_year: 2001 },
  { id: 3, car_make: "Land Rover", car_model: "Defender Ice Edition", car_year: 2010 },
  ...
 ]

Je devais trier le tableau d'objets par la clé car_model, dans l'ordre ascendant.

Ce n'est pas pour dire que cet exercice était une promenade de santé — ce n'était pas le cas. Cela m'a pris du temps et j'ai eu ma part d'erreurs.

Cependant, cela qualifie comme un exercice car je savais ce que je devais faire dès le départ.

J'avais récemment appris les tableaux en JavaScript. J'étais familiarisée avec le tri de données grâce à mon expérience avec Python, bien que j'aie dû rechercher comment faire cela en JavaScript. Les instructions explicites ont également aidé.

Mais les concepts étaient encore nouveaux. J'avais besoin de pratique pour les assembler, ce qui est pourquoi cet exercice était précieux. La répétition engendre la familiarité, et les concepts ont commencé à se solidifier dans mon esprit.

Maintenir ce que vous avez acquis

Les exercices aident également à garder les informations apprises fraîches.

Alors que j'apprends JavaScript, je ne veux pas oublier tout ce que j'ai appris sur le premier langage que j'ai appris, Python. J'utilise donc Anki, un programme de flashcards, plusieurs fois par jour.

Dans ce contexte, les exercices vous aident à garder une montagne de matériel bien organisée, vous rappellent des concepts importants et vous rendent plus à l'aise avec l'utilisation d'une structure de données ou d'une approche particulière. C'est un travail de maintenance sur le corpus de connaissances que vous avez acquis jusqu'à présent.

J'ai plus de 1 000 cartes remplies de matériel que j'ai vu de nombreuses fois auparavant. Certaines cartes posent des questions sur la syntaxe. D'autres me demandent d'écrire des requêtes SQL ou des commandes en ligne de commande ou Git. Beaucoup d'autres sont remplies d'exercices, comme « faire tourner une liste de nombres vers la droite d'une place de valeur. »

Il est important de noter que cet exercice était autrefois un problème pour moi. Si vous faites un problème suffisamment, il peut devenir un exercice. En même temps, vous pouvez transformer un exercice en problème en ajoutant une contrainte.

Les exercices sont une pente glissante. D'une part, ils sont utiles à des fins d'apprentissage. D'autre part, il est facile de rester dans sa zone de confort en s'en tenant exclusivement aux exercices.

C'est l'inconvénient : rester dans sa zone de confort.

Traiter avec l'ambiguïté

La programmation consiste à résoudre des problèmes. Et résoudre des problèmes vous fera sortir de votre zone de confort. C'est une bonne chose.

Pour moi, les problèmes ont deux qualités distinctives. La première est l'ambiguïté. La résolution de problèmes consiste largement à savoir comment traiter efficacement l'ambiguïté.

  • Un message d'erreur apparaît chaque fois que votre programme s'exécute. Pourquoi ? Que se passe-t-il ? Où se trouve le bug ? Comment pouvez-vous le corriger ?
  • Vous ouvrez un nouvel énoncé de problème. Vous le lisez et le relisez. À première vue, vous n'avez aucune idée de ce qui se passe, et encore moins de ce que vous devez faire pour le résoudre. Vous pouvez même ressentir la sensation du « cerf dans les phares » accompagnée d'un creux au fond de l'estomac. (Vous avez choisi un bon problème !)
  • Vous devez apprendre les bases de données relationnelles. C'est assez large. Comment allez-vous vous y prendre ? Sur quoi vous concentrer en premier ? Qu'est-ce qui compte le plus ? Que devez-vous vraiment savoir maintenant ?

Ces exemples impliquent tous de l'ambiguïté. Et tous nécessitent de résoudre des problèmes, qu'il s'agisse de trouver et de dépanner un bug, de résoudre un problème réel ou d'apprendre un nouveau sujet.

Pour progresser, vous faites des recherches, vous expérimentez, vous extrayez les faits, vous créez un plan et vous appliquez une variété de tactiques de résolution de problèmes. En bref, vous apprenez à comprendre. Plus vous passez de temps avec un problème et plus vous gagnez de perspectives différentes, plus il révèle de couches et plus vous vous approchez du moment « aha ».

Embrasser la lutte

L'autre différence avec les problèmes est la lutte. Elle est réelle.

La résolution de problèmes mettra à l'épreuve votre endurance mentale et votre patience. Les progrès peuvent être lents et le processus fastidieux. J'ai peiné sur des problèmes pendant des heures, des jours, et même des semaines.

Ce n'est pas pour dire que les exercices ne vous défieront pas. Ils peuvent le faire. C'est une chose lorsque vous savez que vous devez utiliser une méthode particulière ; vous devez simplement la faire fonctionner correctement. C'est un défi, qui peut parfois être carrément frustrant.

Mais c'est quelque chose de tout à fait différent lorsque vous n'avez aucune idée de ce que vous devez faire dès le départ, ce qui peut arriver plusieurs fois lors de la résolution d'un problème. Pour moi, les problèmes sont une lutte.

La meilleure solution est de l'endurer et de vous débloquer. Dans mon expérience, la lutte signifie que j'apprends beaucoup et que la percée est généralement proche.

Alors que vous traversez l'inconfort mental, vous vous retrouverez à penser de manière créative et à concevoir des solutions auxquelles vous n'aviez jamais pensé auparavant. (Vous vous surprenez et vous impressionnez — vous en savez plus que vous ne le pensez !) Vous devenez un programmeur plus fort.

Vous vous retrouverez même à vous amuser. La résolution de problèmes est certainement difficile, et même frustrante à certains moments. Mais c'est aussi incroyablement gratifiant.

C'est comme franchir la ligne d'arrivée d'un semi-marathon. Sans aucun doute, les 13,1 miles passés étaient éprouvants, mais franchir la ligne d'arrivée en valait la peine et je le referais. Résoudre un problème donne la même sensation.

Problèmes ou exercices ?

Lorsque vous ouvrez votre ordinateur portable, allez-vous résoudre des problèmes ou compléter des exercices ?

Les exercices ont des avantages, et il est bien de les incorporer dans vos sessions de programmation. J'utilise les exercices comme échauffement avant une session de programmation. Je feuillette un jeu de flashcards Anki pendant dix ou quinze minutes et je travaille sur quelques exercices. Si j'apprends quelque chose de nouveau, comme JavaScript, je peux avoir une session de programmation entière consacrée aux exercices.

Cependant, je consacre du temps chaque jour à résoudre des problèmes — peu importe ce que j'apprends ou construis. Même les jours où j'alloue une grande partie de mon temps aux exercices, je consacre également beaucoup de temps à résoudre des problèmes.

Alors, lorsque vous êtes sur le point de commencer une session de programmation, soyez conscient de ce que vous vous apprêtez à faire : des exercices ou des problèmes. Et quoi qu'il en soit, prenez le temps de résoudre des problèmes.

La résolution de problèmes est une compétence qui demande beaucoup de pratique et de temps pour se développer. La seule façon de s'améliorer est de travailler dessus chaque jour. C'est aussi important, et pour une bonne raison.

Nous résolvons des problèmes chaque jour en tant que programmeurs, et de diverses manières. Prendre le temps de résoudre des problèmes est une évidence ; notre travail en tant que programmeurs en dépend.

Je parle de l'apprentissage de la programmation et des meilleures façons de s'y prendre (amymhaddad.com).