Comment apprendre à surmonter les difficultés tout en écrivant des boucles

Bien que nous parlions d'un sujet de base, cet article est rédigé pour des professionnels expérimentés. L'objectif est de montrer quelles erreurs commettent les débutants en programmation. Pour les développeurs praticiens, ces problèmes sont déjà résolus, oubliés ou même complètement ignorés. Cet article peut être utile si vous devez un jour aider quelqu'un sur ce sujet. Des parallèles sont tirés des matériaux de divers livres sur la programmation de authors tels que Schildt, Stroustrup et Okulov.

Le sujet des boucles a été choisi car il est souvent le point de départ où beaucoup de gens abandonnent lors de l'apprentissage de la programmation.

Cette méthodologie est destinée aux étudiants moins performants. En général, les étudiants forts ne se retrouvent pas bloqués à ce stade et il n'est pas nécessaire d'inventer des méthodologies spéciales pour eux. L'objectif secondaire de l'article est de faire passer cette méthodologie de la catégorie « fonctionne pour tous les étudiants, mais seulement avec un enseignant » à celle de « fonctionne pour tous les étudiants, tous les enseignants ». Je ne prétends pas à l'originalité absolue. Si vous appliquez déjà une méthodologie similaire pour enseigner ce sujet, n'hésitez pas à partager en quoi votre version diffère. Si vous décidez de l'appliquer, faites-nous savoir comment cela s'est passé. Si une méthodologie similaire est décrite dans un livre, merci de mentionner le titre.


J'ai affiné cette méthodologie pendant 4 ans, en travaillant individuellement avec des étudiants de niveaux variés. En tout, près d'une cinquantaine d'étudiants et deux mille heures de cours. Au début, les étudiants restaient coincés sur ce sujet et finissaient par abandonner. Après chaque étudiant, la méthodologie et les matériaux étaient ajustés. Au cours de la dernière année, les étudiants ne demeurent plus bloqués sur cette thématique, c'est pourquoi j'ai décidé de partager mes travaux.

Pourquoi tant de lettres ? Les boucles, c'est élémentaire !

Comme je l'ai déjà mentionné, pour les développeurs praticiens et les étudiants forts, la complexité du concept de boucles peut être sous-estimée. Par exemple, on peut organiser une longue conférence, voir des têtes hocher et des yeux intelligents. Mais lorsqu'il s'agit de résoudre un problème, c'est le blocage et des problèmes inexplicables qui surviennent. Après la conférence, les étudiants n'ont sûrement acquis qu'une compréhension partielle. La situation est aggravée par le fait que les étudiants n'arrivent pas à exprimer eux-mêmes où réside leur méprise.
Un jour, j'ai réalisé que les étudiants voyaient mes exemples comme des hiéroglyphes. C'est-à-dire comme des morceaux de texte indivisibles où il fallait écrire une sorte de lettre « magique » pour que cela fonctionne.
Parfois, je remarquais que les étudiants pensaient qu'il leur fallait une autre construction que je n'avais tout simplement pas encore expliquée. Pourtant, il suffisait de modifier légèrement l'exemple pour résoudre le problème.

C'est pourquoi j'en suis venu à l'idée qu'il fallait se concentrer non pas sur la syntaxe des expressions, mais sur le concept de refactorisation du code répétitif à l'aide de boucles. Une fois que les élèves maîtrisent cette idée, n'importe quelle syntaxe peut être assimilée par de petits exercices.

À qui et pourquoi j'enseigne

Étant donné qu'il n'y a pas d'examens d'entrée, il peut y avoir dans les cours des étudiants à la fois forts et très faibles. Vous pouvez en apprendre davantage sur mes étudiants dans l'article Portrait des auditeurs des cours du soir
Je voulais que tout le monde puisse apprendre la programmation s'il le désirait.
Mes cours se déroulent en individuel et l'étudiant paie de son propre argent pour chaque séance. On pourrait penser que les étudiants chercheraient à optimiser leurs coûts et à demander le minimum. Cependant, les gens assistent à des cours en présentiel avec un enseignant vivant non pas seulement pour acquérir des connaissances, mais pour avoir la certitude de ce qu'ils ont réussi à assimiler, pour ressentir des progrès et recevoir l'approbation d'un expert (enseignant). Si les étudiants ne ressentent pas de progrès dans leur apprentissage, ils partiront. En général, on peut structurer les cours de manière à ce que les étudiants ressentent un progrès dans le nombre de constructions familières. Cela signifie que l'on commence par étudier en détail la boucle while, puis la boucle for, ensuite do while, et voilà, nous avons un cours qui dure mille et une nuits, où pendant deux mois, on n'étudie que les boucles, avec pour résultat un étudiant qui a rédigé la bibliothèque standard sous dictée. Cependant, pour résoudre des problèmes pratiques, il faut non seulement connaître le matériau, mais aussi faire preuve d'autonomie dans son application et sa recherche de nouvelles informations. C'est pourquoi, pour les cours en présentiel, je considère qu'il est juste de suivre le principe d'apprendre le minimum et d'encourager l'étude autonome des nuances et des sujets connexes. Dans le sujet sur les boucles, je considère que le minimum est la construction while. C'est sur cela que l'on peut comprendre le principe. En connaissant le principe, on peut également maîtriser for et do-while de manière autonome.

Pour aider les étudiants en difficulté à maîtriser le sujet, il ne suffit pas de décrire la syntaxe. Il faut offrir davantage de tâches simples mais variées et détailler les exemples. En fin de compte, la vitesse d'apprentissage est limitée par la capacité de l'élève à transformer des expressions et à rechercher des motifs. Pour les étudiants plus vifs, la plupart des tâches s'avéreront ennuyeuses. Lors des cours avec eux, il n'est pas nécessaire d'exiger la résolution de 100 % des problèmes. Vous pouvez consulter mon matériel sur mon GitHub. Pourtant, le dépôt ressemble plutôt à un grimoire de sorcier — personne, sauf moi, ne comprendra où se trouve quoi, et si l'examen échoue, on pourrait en devenir fou.

La méthode est axée sur la pratique.

La théorie est expliquée à l'aide de la résolution de problèmes. Dans les cours d'introduction à la programmation, où l'on étudie les structures conditionnelles et les boucles, il n'est tout simplement pas possible de tenir une conférence utile sur un seul sujet pendant une heure. 15 à 20 minutes suffisent pour expliquer le concept. Les principales difficultés surviennent lors de l'exécution des tâches pratiques.
Les enseignants débutants peuvent aborder les opérateurs, les structures conditionnelles, les boucles et les tableaux en une seule leçon. Cependant, leurs étudiants rencontreront des difficultés pour assimiler ces informations.
Il ne suffit pas seulement de présenter le matériel, il faut également s'assurer que les auditeurs l'ont compris.

La maîtrise du sujet se détermine par la façon dont l'étudiant réussit son travail indépendant.
Si l'étudiant parvient à résoudre le problème sur le sujet sans l'aide du professeur, cela signifie que le sujet a été compris. Pour garantir une auto-évaluation, chaque tâche est accompagnée d'un tableau de scénarios de test. Les tâches suivent un ordre bien défini. Il est déconseillé de sauter des tâches. Si la tâche actuelle est trop difficile, il est inutile de passer à la suivante. Elle sera encore plus difficile. Pour permettre à l'étudiant de maîtriser la tâche complexe actuelle, plusieurs stratégies lui sont expliquées à l'aide du premier problème. En réalité, tout le contenu du sujet se résume à des méthodes pour surmonter les difficultés. Les boucles sont plutôt un effet secondaire.

Le premier problème est toujours un exemple. Le second diffère légèrement et est effectué « indépendamment » immédiatement après le premier sous la supervision du professeur. Tous les problèmes suivants visent à attirer l'attention sur de petites subtilités qui peuvent prêter à confusion.

L'explication d'un exemple prend la forme d'un dialogue, où l'étudiant doit appeler la rétropropagation et la validation croisée pour s'assurer qu'il a assimilé la matière.

Je vais être banal et dire que le premier exemple sur le sujet est très important. Avec du matériel pour un travail autonome approfondi, on peut corriger l'oubli du premier exemple. S'il n'y a rien d'autre que cet exemple, l'étudiant ne réussira probablement pas à maîtriser le sujet.

While ou for ?

Une des questions controversées est le choix de la structure pour l'exemple : while ou for. Un jour, un ami, développeur pratiquant sans expérience d'enseignement, m'a passé une heure à me convaincre que la boucle for est la plus simple à comprendre. Ses arguments se résumaient à "tout y est clair et rangé." Cependant, la véritable racine des difficultés pour les véritables débutants réside dans l'idée même de boucle, et non dans son écriture. Si une personne ne comprend pas cette idée, elle rencontrera des difficultés avec la syntaxe. Dès que l'idée est comprise, les problèmes de mise en forme du code disparaissent d'eux-mêmes.

Dans mes supports, le sujet des boucles vient après celui des branchements. La ressemblance extérieure entre if et while permet d'établir une analogie directe : « lorsque la condition dans l'en-tête est vraie, le corps est exécuté ». La particularité de la boucle est que le corps est exécuté plusieurs fois.

Mon deuxième argument est que while nécessite moins de mise en forme que for. Moins de mise en forme signifie moins d'erreurs stupides dues à des virgules et parenthèses manquantes. Les débutants n'ont pas encore assez développé leur attention et leur minutie pour éviter automatiquement les erreurs de syntaxe.
Le troisième argument est que dans de nombreux bons livres, while est expliqué en premier.

Si l'étudiant parvient facilement à transformer des expressions, on peut passer rapidement à for. L'étudiant choisira ensuite ce qu'il préfère. En revanche, si les transformations posent des difficultés, il vaut mieux ne pas distraire son attention. Qu'il résolve d'abord tout avec while. Une fois qu'il aura maîtrisé le sujet des boucles, on pourra réécrire les solutions pour travailler la transformation de while en for.
Les boucles avec post-condition sont plutôt rares. Je ne perds pas de temps avec ça. Si l'étudiant a compris les idées d'identification des modèles et de transformation des expressions, il pourra s'en sortir sans mon aide.

Lors de la démonstration du premier exemple à des étudiants brillants, je souligne que dans le premier exemple, il est important de noter non seulement la solution mais aussi toute la chaîne d'actions qui a conduit au résultat. Les étudiants paresseux peuvent négliger les écrits et ne conserver que l'algorithme final. Il faut les convaincre qu'un jour, ils seront confrontés à une problématique complexe. Pour la résoudre, il leur faudra procéder étape par étape comme dans cet exemple. C'est pourquoi il est essentiel de fixer toutes les étapes. Dans les exercices suivants, on ne pourra laisser que la version finale de la solution.

L'idée principale de l'automatisation est que nous confions à l'ordinateur le travail routinier à la place de l'homme. L'une des techniques de base consiste à écrire des boucles. Elle est utilisée lorsque plusieurs actions identiques et répétées doivent être exécutées en série dans le programme.

L'explicite est mieux que l'implicite

Cela peut sembler être une bonne idée, dans le premier exercice sur les boucles, d'afficher à l'écran une phrase identique plusieurs fois. Par exemple :

Hourra, ça fonctionne !
Hourra, ça fonctionne !
Hourra, ça fonctionne !
Hourra, ça fonctionne !
Hourra, ça fonctionne !
Hourra, ça fonctionne !
Hourra, ça fonctionne !
Hourra, ça fonctionne !

Cette option est mauvaise car la valeur du compteur n'est pas visible à l'écran. C'est un problème pour les débutants. Il ne faut pas sous-estimer cela. Au départ, cet exercice était le premier, et celui d'afficher une série de nombres par ordre croissant était le deuxième. Il a fallu introduire des termes supplémentaires tels que « boucle N fois » et « boucle de A à B », qui sont en réalité identiques. Pour éviter de créer des entités superflues, j'ai décidé de ne montrer que l'exemple d'affichage d'une série de nombres. Peu de gens parviennent sans préparation à garder un compteur en tête et à modéliser le comportement du programme mentalement. Certains étudiants sont confrontés pour la première fois à la modélisation « dans leur tête » précisément sur le sujet des boucles.
Après un certain temps de pratique, je donne la tâche de répéter le même texte à résoudre de manière autonome. Si l'on commence par un compteur visible, puis un invisible, les étudiants rencontrent moins de problèmes. Parfois, il suffit de donner l'indice « ne pas écrire le compteur à l'écran ».

Comment cela est-il expliqué chez les autres ?

Dans la plupart des matériaux d'apprentissage en ligne, la syntaxe des boucles est donnée dans le cadre d'une « leçon ». Par exemple, sur developer.mozilla.org (actuellement), la boucle while est accompagnée de plusieurs autres constructions. Cependant, seules les constructions elles-mêmes sont fournies sous forme de modèles. Le résultat de leur exécution est décrit par des mots, et l'illustration est absente. À mon avis, cette approche réduit à néant l'utilité de tels matériaux. L'étudiant peut réécrire le code et l'exécuter lui-même, mais une référence pour comparaison est toujours nécessaire. Comment savoir si un exemple a été correctement réécrit, sans rien avec quoi comparer le résultat ?
Lorsqu'un seul modèle est fourni, sans exemple, il devient encore plus difficile pour l'étudiant. Comment être sûr que les fragments de code sont correctement disposés dans le modèle ? On peut essayer d'écrire d'une manière ou d'une autre, puis de l'exécuter. Mais s'il n'y a pas de référence pour comparer le résultat, l'exécution ne sera pas d'une grande aide non plus.

Dans le cours de C++ sur Intuit, la syntaxe de la boucle est enterrée à la troisième page de la leçon 4 sur le thème « opérateurs ». Lors de l'explication de la syntaxe des boucles, une attention particulière est portée au terme « opérateur ». Ce terme est présenté sous forme d'un ensemble de faits tel que « le symbole ; c'est un opérateur », « {} c'est un opérateur composé », « le corps de la boucle doit être un opérateur ». Je n'aime pas cette approche car elle cache des relations importantes derrière un seul terme. L'analyse du code source du programme à ce niveau est nécessaire pour les développeurs de compilateurs afin de mettre en œuvre la spécification du langage, mais pas pour les étudiants dans un premier temps. Les débutants en programmation n'ont que rarement la minutie nécessaire pour faire attention aux termes de cette manière. Peu de gens se souviennent et comprennent de nouveaux mots du premier coup. Pratiquement personne ne peut appliquer correctement un terme qu'il vient tout juste d'apprendre. C'est pourquoi les étudiants commettent de nombreuses erreurs telles que « j'ai écrit while(a<7);{, et le programme ne fonctionne pas ».
À mon avis, il est préférable de donner d'abord la syntaxe de la construction immédiatement avec des accolades. L'option sans accolades ne doit être expliquée que si l'élève pose une question concrète « pourquoi ici sans accolades et ça fonctionne ».

Dans le livre d'Okulov « Les Fondements de la programmation » de 2012, l'introduction aux boucles commence par le modèle for, suivi de recommandations pour son utilisation, puis s’enchaîne avec une section expérimentale. Je comprends que ce livre a été écrit pour cette minorité d'élèves très talentueux qui viennent rarement à mes cours.

Dans les livres populaires, on indique toujours le résultat des fragments de code. Par exemple, dans le livre de Schildt « Java 8. Guide complet » publié en 2015. On commence par donner le modèle, puis un exemple de programme et immédiatement après — le résultat de l'exécution.

Prenons comme exemple une boucle while qui effectue un compte à rebours
à partir de 10, affichant exactement 10 lignes de « battements » :

//Продемонстрировать применение оператора цикла while
class While {
    public static void main(String args []) {
        int n = 10;
        while (n > 0) {
            System.out.println("такт " + n);
            n--;
        }
    }
}

Après son lancement, ce programme affiche dix « battements » de la manière suivante :
tact 10
tact 9
tact 8
tact 7
tact 6
tact 5
tact 4
tact 3
tact 2
tact 1

L'approche consistant à décrire le modèle, l'exemple de programme et le résultat de ce programme est également utilisée dans le livre « Javascript pour les enfants » et dans le cours js sur w3schools.com. Le format de la page web permet même de rendre cet exemple interactif.

Dans le livre de Stroustrup « Principes et pratique avec C++ » de 2016, l'auteur va encore plus loin. Tout d'abord, il explique quel résultat doit être obtenu, puis montre le texte du programme. De plus, comme exemple, il ne prend pas juste un programme aléatoire, mais offre un aperçu historique. Cela aide à attirer l'attention sur le fait que « Regarde, ce n'est pas juste un texte inutile. Tu vois quelque chose de significatif ».

Prenons comme exemple l'itération de la première programme exécuté sur une machine à programme stocké (EDSAC). Elle a été écrite par David Wheeler dans le laboratoire informatique de l'Université de Cambridge (Cambridge University, Angleterre) le 6 mai 1949. Ce programme calcule et imprime une simple liste de carrés.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

Ici, chaque ligne contient un nombre, suivi d'un caractère de tabulation (‘t’) et du carré de ce nombre. La version de ce programme en C++ ressemble à ceci :

//Вычисляем и распечатываем таблицу квадратов чисел 0-99
int main()
{
    int i = 0; // Начинаем с нуля
    while(i < 100){
        cout << i << 't' << square(i) << 'n';
        ++i;
    }
}

Il est intéressant de noter que le modèle de syntaxe n'est pas décrit dans ce livre. Stroustrup, dans le manuel de l'instructeur (traduction) souligne qu'il respecte l'intelligence de ses étudiants. Peut-être que la capacité à identifier le modèle dans plusieurs exemples est considérée comme une manifestation de cette intelligence.

Comme je l'explique moi-même

L'approche de Stroustrup : décrire le résultat, ensuite résoudre le problème, puis analyser de manière autonome par l'étudiant — semble être la plus réfléchie. J'ai donc décidé de me baser sur celle-ci, mais d'expliquer à travers un exemple moins historique — le problème de l'affichage d'une « table des matières ». Cela crée une ancre reconnaissable, permettant de dire ensuite « souviens-toi du problème de la table des matières » pour que les étudiants s'en rappellent précisément. Dans mon exemple, j'ai essayé de prévenir deux des idées fausses les plus courantes. J'en parlerai plus en détail ensuite.

Avec ce problème, nous nous familiarisons avec les techniques de résolution de problèmes complexes. La solution initiale doit être faite de manière primitive et simple. Ensuite, on peut réfléchir à la manière d'améliorer cette solution.
Introduction
Chapitre 1
Chapitre 2
Chapitre 3
Chapitre 4
Chapitre 5
Chapitre 6
Chapitre 7
Conclusion

D'après mes observations, l'approche « modèle-exemple-résultat » dans différentes combinaisons conduit toujours à ce que les étudiants perçoivent la boucle comme un hiéroglyphe. Cela se manifestait par le fait qu'ils ne comprenaient pas pourquoi il fallait écrire une condition, comment choisir entre i++ et i— et d'autres choses apparemment évidentes. Pour éviter ces idées fausses, l'approche pour expliquer les boucles doit souligner le sens de la répétition des mêmes actions, puis — leur mise en forme à l'aide de la construction. Par conséquent, avant de donner la syntaxe de la boucle, il faut résoudre le problème « à la volée ». La solution primitive du problème de la table des matières se présente comme suit :

Console.WriteLine("Introduction");
Console.WriteLine("Chapitre 1");
Console.WriteLine("Chapitre 2");
Console.WriteLine("Chapitre 3");
Console.WriteLine("Chapitre 4");
Console.WriteLine("Chapitre 5");
Console.WriteLine("Chapitre 6");
Console.WriteLine("Chapitre 7");
Console.WriteLine("Conclusion");

Comment peut-on l'améliorer ?
Remplacer les actions répétitives par une boucle.
Quelles actions se répètent ici consécutivement sans changements ?
Il n'y en a pas dans ce fragment. Cependant, les commandes pour afficher le mot « Chapitre » avec un numéro se ressemblent fortement.
Ainsi, la prochaine étape consiste à chercher la différence entre les fragments. Ce n'est que dans ce problème que tout est évident, ensuite, il s'agira non pas de commandes individuelles mais de blocs de code de 5 lignes ou plus. Il faudra chercher, non seulement dans la liste des commandes, mais dans des constructions de branchement ou de boucle.
Dans l'exemple, la différence entre les commandes réside dans le nombre qui suit le mot « Chapitre ».
Une fois la différence trouvée, il faut comprendre la régularité des changements. Le fragment distinct est un nombre ? Augmente-t-il ou diminue-t-il constamment ? Comment la valeur du nombre change-t-elle entre deux commandes côte à côte ?
Dans cet exemple, le nombre après le mot « Chapitre » augmente par paliers de 1. La différence a été trouvée, la régularité a été identifiée. Vous pouvez maintenant remplacer la partie variable par une variable.
Vous devez déclarer une telle variable avant le premier des fragments répétitifs. Cette variable est généralement appelée i ou j, ou d'une manière plus développée. Sa valeur initiale doit être égale à la première valeur affichée à l'écran. Dans cet exemple, la première valeur est 1.
Quelle valeur initiale faut-il prendre pour afficher la série de nombres « 100, 101, 102, 103, 104, 105 » ?
Dans cette série, le premier nombre est 100.
Après chaque commande d'affichage, il faut augmenter la valeur de cette variable de 1. Cette unité correspond à l'incrément.
Quel sera l'incrément pour la série de nombres « 100, 102, 104, 106 » ?
Dans cette série, l'incrément est 2.
Après avoir remplacé le fragment variable par une variable, le code ressemblera à ceci :

Console.WriteLine("Introduction");
int i;
i = 0;
Console.WriteLine("Chapitre " + i);
i = i + 1;
Console.WriteLine("Chapitre " + i);
i = i + 1;
Console.WriteLine("Chapitre " + i);
i = i + 1;
Console.WriteLine("Chapitre " + i);
i = i + 1;
Console.WriteLine("Chapitre " + i);
i = i + 1;
Console.WriteLine("Chapitre " + i);
i = i + 1;
Console.WriteLine("Chapitre " + i);
i = i + 1;
Console.WriteLine("Conclusion");

Après avoir appliqué la méthode « exprimer la régularité par une variable », le code se compose de plusieurs groupes d'actions identiques, qui se suivent. Les actions répétitives peuvent maintenant être remplacées par une boucle.

La séquence de résolution d'une tâche où il faut utiliser des boucles se compose des étapes suivantes :

  1. Résoudre « directement » avec de nombreuses commandes séparées
  2. Trouver la régularité
  3. Exprimer la régularité par une variable
  4. Formuler sous forme de boucle

Ensuite, de nouveaux termes sont introduits pour que l'étudiant ne se retrouve pas dans la situation « je comprends tout, mais je ne peux pas le dire » :
— compteur — toujours une variable qui est nécessaire pour suivre le nombre d'étapes de la boucle. Généralement un nombre entier, qui est comparé à une limite.
— pas du compteur — description de la régularité du changement du compteur.
— limite — nombre ou variable avec laquelle le compteur est comparé pour que l'algorithme soit fini. La valeur du compteur change de manière à se rapprocher de la limite.
— corps de la boucle — ensemble de commandes qui vont être répétées. Quand on dit « la commande est écrite à l'intérieur de la boucle », il s'agit précisément du corps.
— itération de la boucle — exécution unique du corps de la boucle.
— condition de boucle — une expression logique qui détermine si une autre itération sera exécutée. (Il peut y avoir confusion avec les constructions de branchement.)
Il faut être prêt à ce que, dans un premier temps, les étudiants utilisent les termes de manière incorrecte. Cela concerne à la fois les forts et les faibles. Établir un langage commun est tout un art. Pour faire court : il faut poser la tâche « mets en évidence le fragment de code avec » et utiliser ces termes correctement dans la conversation.
Après la transformation avec la boucle, on obtient le fragment :

Console.WriteLine("Introduction");
int i = 0;
while (i < 7) {
    Console.WriteLine("Chapitre " + i);
    i = i + 1;
}
Console.WriteLine("Conclusion");

La principale idée reçue

Une idée reçue populaire parmi les étudiants est qu'ils placent dans la construction de boucle des actions qui ne doivent être effectuées qu'une seule fois. Par exemple comme ceci :

;
int i = 0;
while (i < 7) {
    Console.WriteLine("Introduction")
    Console.WriteLine("Chapitre " + i);
    i = i + 1;
    Console.WriteLine("Conclusion");
}

Les élèves rencontrent constamment ce problème, tant au début que dans des tâches plus complexes.
L'astuce clé dans ce cas :

Combien de fois faut-il répéter l’écriture de la commande : une fois ou plusieurs ?

Les commandes pour afficher les mots « Introduction » et « Conclusion », ainsi que la déclaration et l'initialisation de la variable i, ne ressemblent pas aux autres actions répétées. Elles ne s'exécutent qu'une seule fois, donc elles doivent être écrites en dehors du corps de la boucle.

Le code doit contenir toutes les trois étapes de la solution afin de pouvoir s'y référer en cas de difficultés. Les deux premières variantes peuvent être simplement commentées pour ne pas interférer.
L’attention de l’étudiant doit être attirée sur les faits suivants :
— Dans la condition de boucle, on compare généralement le compteur et la limite. Le compteur peut changer dans le corps de la boucle, mais la limite ne peut pas. Pour violer cette règle, il faut formuler de bonnes raisons.
— Les commandes pour afficher les mots « Introduction » et « Conclusion » sont en dehors du corps de la boucle. Nous devons les exécuter une fois. « Introduction » — avant de répéter les actions, « Conclusion » — après.
Dans le processus de maîtrise de ce sujet, de l'acquisition des suivants, ainsi que lors des clarifications en cas de difficultés, même les étudiants les plus forts bénéficient de poser la question : « Et cette action, combien de fois doit-elle être exécutée ? Une fois ou plusieurs ? ».

Développement de compétences supplémentaires

Lors de l'exploration des cycles, les étudiants développent également leurs compétences en matière de diagnostic et de résolution de problèmes. Pour effectuer un diagnostic, l'étudiant doit imaginer le résultat souhaité et le comparer au résultat réel. Les actions à entreprendre pour corriger la situation dépendent de la différence entre ces deux résultats.
Comme les étudiants ont encore du mal à se représenter le « résultat souhaité » à ce stade, ils peuvent se baser sur des données de test. En général, personne ne comprend encore à ce stade ce qui pourrait mal tourner et comment y faire face. C'est pourquoi je fournis une description des problèmes typiques et quelques solutions possibles à noter dans leur carnet. Le choix de la solution la plus appropriée est la tâche de l'étudiant lui-même.
Cette prise de note est nécessaire pour poser les questions : « Est-ce que le résultat souhaité a été atteint ? », « Quelle de ces situations s'est produite ? », « La solution appliquée a-t-elle été efficace ? ».

  1. Le nombre d'actions est supérieur ou inférieur de 1 à ce qui était attendu. Méthodes de résolution :
    — augmenter la valeur initiale du compteur de 1.
    — remplacer l'opérateur de comparaison stricte (< ou >) par un opérateur de comparaison non stricte (<= ou >=).
    — modifier la valeur de la limite de 1.
  2. Les actions dans la boucle s'exécutent sans interruption, de manière infinie. Méthodes de résolution :
    — ajouter une commande pour modifier le compteur, si elle est absente.
    — corriger la commande de modification du compteur afin que sa valeur se rapproche de la limite.
    — supprimer la commande de modification de la limite, si elle est dans le corps de la boucle.
  3. Le nombre d'actions dans la boucle est supérieur ou inférieur de plus de 1 à ce qui était attendu. Aucune action dans la boucle ne s'est exécutée. Il est d'abord nécessaire de déterminer les valeurs réelles des variables juste avant le début de la boucle. Méthodes de résolution :
    — modifier la valeur initiale de la limite
    — modifier la valeur initiale du compteur

En général, le problème 3 est lié à l'utilisation d'une mauvaise variable ou à l'absence de réinitialisation du compteur.

Après cette explication, l'étudiant peut encore avoir diverses idées fausses concernant le fonctionnement des cycles.
Pour dissiper les idées fausses les plus courantes, je propose des exercices :

  1. Dans lequel la limite, la valeur initiale du compteur ou l'étape du compteur est saisie par l'utilisateur.
  2. Dans lequel la valeur du compteur doit être utilisée dans une expression arithmétique. Idéalement, en utilisant le compteur dans l'expression sous le radical ou dans le dénominateur, afin que la différence soit non linéaire.
  3. Dans lequel la valeur du compteur n'est pas affichée à l'écran pendant le déroulement de la boucle. Par exemple, afficher un certain nombre de fragments de texte identiques ou dessiner une figure avec la programmation turtle.
  4. Dans lequel il faut d'abord effectuer certaines actions répétitives, puis d'autres.
  5. Dans lequel il faut effectuer d'autres actions avant et après les répétitions.

Pour chaque tâche, il faut fournir des données de test et le résultat attendu.

Pour comprendre à quelle vitesse on peut avancer, il faut faire lire les conditions de ces tâches et demander : « Qu'est-ce qui les distingue de l'exemple ? », « Que faut-il changer dans l'exemple pour les résoudre ? ». Si l'étudiant répond de manière réfléchie, alors qu'il résolve au moins une tâche en classe, et les autres à la maison de manière autonome. Si la solution réussit, alors on peut commencer à expliquer les conditions à l'intérieur des boucles.
S'il y a des difficultés avec la résolution autonome, il faut tout travailler en classe. Pour que la résolution d'une tâche ne ressemble pas à un dessin de hibou, je recommande d'abord de résoudre la tâche de manière non universelle. C'est-à-dire de sorte que la solution réussisse le premier test et n'utilise pas de structure de boucle. Ensuite, on applique des transformations pour obtenir l'universalité de la solution.

Boucles et conditionnelles

À mon avis, il est utile de donner le sujet « boucles à l'intérieur des conditionnelles » séparément. Ainsi, on pourra voir ensuite la différence entre une vérification conditionnelle multiple et une unique.
Les tâches de consolidation porteront sur l'affichage des nombres de A à B, qui sont saisis par l'utilisateur :
— toujours de manière croissante.
— de manière croissante ou décroissante selon les valeurs de A et B.

On ne doit passer au sujet « conditionnelles à l'intérieur des boucles » qu'après que l'étudiant a maîtrisé les techniques : « remplacer une régularité par une variable » et « remplacer les actions répétées par une boucle ».
La principale raison d'appliquer des conditionnelles à l'intérieur des boucles est qu'il peut y avoir des anomalies dans la régularité. Elle est perturbée en fonction des données d'entrée.
Pour les étudiants capables de rechercher une solution en combinant des techniques simples, il suffit de dire « les conditionnelles peuvent être écrites à l'intérieur des boucles » et de donner une tâche « par exemple » entièrement à résoudre de manière autonome.
Tâche par exemple :

L'utilisateur saisit un nombre X. Afficher sous forme de colonne les nombres de 0 à 9 et mettre un signe ‘+’ à côté du nombre qui est égal à X.

Si 0 a été saisi0+
1
2
3
4
5
6
7
8
9

Si 6 a été entré0
1
2
3
4
5
6+
7
8
9

Si 9 a été entré0
1
2
3
4
5
6
7
8
9+

Si 777 a été entré0
1
2
3
4
5
6
7
8
9

Si l'explication courte est insuffisante pour écrire avec une boucle, il faut alors trouver une solution universelle à cette même tâche sans boucle.
Il en résultera une des deux options :
Désiré

string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
    Console.WriteLine(0 + "+");
} else {
    Console.WriteLine(0);
}
if (x==1) {
    Console.WriteLine(1 + "+");
} else {
    Console.WriteLine(1);
}
if (x==2) {
    Console.WriteLine(2 + "+");
} else {
    Console.WriteLine(2);
}
if (x==3) {
    Console.WriteLine(3 + "+");
} else {
    Console.WriteLine(3);
}
if (x==4) {
    Console.WriteLine(4 + "+");
} else {
    Console.WriteLine(4);
}
if (x==5) {
    Console.WriteLine(5 + "+");
} else {
    Console.WriteLine(5);
}
if (x==6) {
    Console.WriteLine(6 + "+");
} else {
    Console.WriteLine(6);
}
if (x==7) {
    Console.WriteLine(7 + "+");
} else {
    Console.WriteLine(7);
}
if (x==8) {
    Console.WriteLine(8 + "+");
} else {
    Console.WriteLine(8);
}
if (x==9) {
    Console.WriteLine(9 + "+");
} else {
    Console.WriteLine(9);
}

Possible

string temp;
temp = Console.ReadLine();
int x;
x = int.Parse(temp);
if (x==0) {
    Console.WriteLine("0+n1n2n3n4n5n6n7n8n9");
}
if (x==1) {
    Console.WriteLine("0n1+n2n3n4n5n6n7n8n9");
}
if (x==2) {
    Console.WriteLine("0n1n2+n3n4n5n6n7n8n9");
}
if (x==3) {
    Console.WriteLine("0n1n2n3+n4n5n6n7n8n9");
}
if (x==4) {
    Console.WriteLine("0n1n2n3n4+n5n6n7n8n9");
}
if (x==5) {
    Console.WriteLine("0n1n2n3n4n5+n6n7n8n9");
}
if (x==6) {
    Console.WriteLine("0n1n2n3n4n5n6+n7n8n9");
}
if (x==7) {
    Console.WriteLine("0n1n2n3n4n5n6n7+n8n9");
}
if (x==8) {
    Console.WriteLine("0n1n2n3n4n5n6n7n8+n9");
}
if (x==9) {
    Console.WriteLine("0n1n2n3n4n5n6n7n8n9+");
}

Je donne une tâche similaire à l'avance, lors de l'étude du sujet sur les branchements.
Si l'étudiant obtient une option « possible », il faut expliquer que pour un même problème, il peut y avoir plusieurs solutions. Cependant, elles diffèrent par leur stabilité face aux changements de exigences. Posez la question : « Combien d'endroits dans le code devront être modifiés si l'on doit ajouter un autre nombre ? » Dans l'option « possible », il faudra ajouter une autre branche et écrire le nouveau nombre à 10 autres endroits. Dans l'option « désirée », il suffit d'ajouter une seule branche.
Posez la tâche de reproduire l'option « désirée », puis de trouver la régularité dans le code, de réaliser un remplacement de variable et d'écrire une boucle.
Si vous avez une idée pour résoudre cette tâche sans boucle d'une autre manière, veuillez écrire dans les commentaires.

Boucles à l'intérieur des boucles

Dans ce sujet, il faut faire attention à ce que :
— les compteurs pour la boucle interne et externe doivent être des variables différentes.
— le compteur pour la boucle interne doit être réinitialisé plusieurs fois (c'est-à-dire dans le corps de la boucle externe).
Dans les tâches d'affichage du texte, il est impossible d'écrire d'abord une lettre sur plusieurs lignes, puis une autre. Il faut d'abord afficher toutes les lettres de la première ligne, puis toutes les lettres de la deuxième, et ainsi de suite.

Il est préférable de commencer l'explication du sujet sur les boucles imbriquées par expliquer l'importance de réinitialiser le compteur.
Tâche par exemple :

L'utilisateur saisit deux nombres : R et T. Affichez deux lignes de caractères "#". La première ligne doit contenir R caractères. La seconde ligne doit contenir T caractères. Si l'un des nombres est négatif, affichez un message d'erreur.

R=5, T=11#####
###########

R=20, T=3####################
###

R=-1, T=6La valeur de R doit être non négative

R=6, T=-2La valeur de T doit être non négative

Il est évident que ce problème a également au moins deux solutions possibles.
Désiré

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
    Console.Write("#");
    i = i + 1;
}
Console.WriteLine();
i = 0;
while (i < T)
{
    Console.Write("#");
    i = i + 1;
}

Possibilité n°1

string temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
int i = 0;
while (i < R)
{
    Console.Write("#");
    i = i + 1;
}
Console.WriteLine();
int j = 0;
j = 0;
while (j < T)
{
    Console.Write("#");
    j = j + 1;
}

La différence est que dans la solution «possible», une deuxième variable a été utilisée pour afficher la seconde ligne. Il faut insister sur l'utilisation de la même variable pour les deux boucles. On peut justifier cette limitation par le fait qu'une solution avec un seul compteur pour deux boucles sera une illustration du terme «réinitialisation du compteur». Comprendre ce terme est nécessaire pour résoudre les problèmes suivants. En tant que compromis, on peut conserver les deux solutions au problème.

Un problème typique avec l'utilisation d'une seule variable compteur pour deux boucles se manifeste de cette manière :
R=5, T=11#####
######

Le nombre de caractères dans la seconde ligne ne correspond pas à la valeur de T. Si une aide est nécessaire avec ce problème, il faut «pointer du doigt» le résumé sur les problèmes typiques avec les boucles. C'est le symptôme n°3. Il est diagnostiqué en ajoutant l'affichage de la valeur du compteur juste avant la seconde boucle. Cela se corrige par une réinitialisation. Mais il vaut mieux ne pas le dire tout de suite. L'étudiant doit essayer de formuler au moins une hypothèse.

Il y a bien sûr une autre solution possible. Mais je ne l'ai jamais vue chez les étudiants. Lors de l'apprentissage des boucles, en parler disperserait l'attention. On peut y revenir plus tard, en étudiant les fonctions de manipulation des chaînes.
Possibilité n°2

chaine temp;
int R;
int T;
temp = Console.ReadLine();
R = int.Parse(temp);
temp = Console.ReadLine();
T = int.Parse(temp);
Console.WriteLine(new String('#', R));
Console.WriteLine(new String('#', T));

La prochaine tâche obligatoire :

Affichez les chiffres de 0 à 9. Chaque chiffre doit être sur sa propre ligne. Le nombre de chiffres par ligne (W) est saisi au clavier.

W=10
1
2
3
4
5
6
7
8
9

W=100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999

Si l'étudiant a maîtrisé la technique de substitution de variable, il s'en sortira assez rapidement. Le problème potentiel sera encore une fois l'initialisation de la variable. S'il ne parvient pas à effectuer la transformation, cela signifie que vous vous êtes précipité et qu'il faut résoudre des tâches plus simples.

Merci de votre attention. Aimez, abonnez-vous à la chaîne.

P.S. Si vous trouvez des fautes d'orthographe ou des erreurs dans le texte, veuillez me le faire savoir. Vous pouvez le faire en sélectionnant une partie du texte et en appuyant sur «⌘ + Entrée» sur Mac, ou sur les claviers classiques «Ctrl / Entrée», ou via des messages personnels. Si ces options ne sont pas accessibles, veuillez signaler les erreurs dans les commentaires. Merci !

Seuls les utilisateurs enregistrés peuvent participer au sondage. Connectez-vous, s'il vous plaît.

Sondage pour les lecteurs sans karma

  • 20,0%J'enseigne professionnellement, +12

  • 10,0%J'enseigne professionnellement, -11

  • 70,0%Je n'enseigne pas, +17

  • 0,0%Je n'enseigne pas, -10

  • 0,0%Autre0

10 utilisateurs ont voté. 5 utilisateurs se sont abstenus.

Source : habr.com

Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS 🔥 Acheter un hébergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster