Hvordan man lærer at overvinde vanskeligheder og samtidig skrive loops

Selvom emnet er et af de grundlæggende, er denne artikel skrevet til erfarne fagfolk. Målet er at vise hvilke misforståelser nybegyndere i programmering kan have. For praktiserende udviklere er disse problemer længe blevet løst, glemt eller overhovedet ikke bemærket. Artiklen kan være nyttig, hvis du pludselig skal hjælpe nogen med dette emne. Der trækkes paralleller til materialet fra forskellige bøger om programmering af Schilt, Stroustrup og Okulov.

Emnet om løkker er valgt, fordi mange falder fra, når de lærer programmering.

Denne metode er beregnet til svage studerende. Stærke studerende hænger som regel ikke fast i dette emne, og der er ikke behov for at udvikle særlige metoder til dem. En sekundær mål for artiklen er at oversætte denne metode fra klassen 'virker for alle studerende, men kun hos én underviser' til klassen 'virker for alle studerende, alle undervisere'. Jeg påstår ikke at være absolut original. Hvis du allerede bruger en lignende metode til at undervise i dette emne, så skriv venligst, hvordan din version adskiller sig. Hvis du vælger at anvende den, så del venligst dine erfaringer efterfølgende. Hvis en lignende metode er beskrevet i en bog, så giv venligst navnet.


Jeg har arbejdet med denne metode i 4 år, hvor jeg har undervist studerende på forskellige niveauer individuelt. I alt omkring halvtreds studerende og to tusinde timer med undervisning. I starten sad studerende fast på dette emne og forlod det. Efter hver studerende blev metoden og materialerne justeret. I det sidste år hænger studerende ikke længere fast på dette emne, så jeg besluttede at dele mine erfaringer.

Hvorfor så mange ord? Løkker er jo elementære!

Som jeg nævnte før, kan kompleksiteten af løkkekoncepter undervurderes af praktiserende udviklere og stærke studerende. For eksempel kan man holde en lang forelæsning, se nikkende hoveder og kloge øjne. Men når man forsøger at løse en opgave, opstår der pludselig stød og uforklarlige problemer. Efter forelæsningen har studerende sandsynligvis kun en delvis forståelse. Situationen forværres af, at studerende ikke selv kan udtrykke, hvori deres misforståelse består.
Engang indså jeg, at studerende opfatter mine eksempler som hieroglyffer. Altså som udelelige tekststykker, hvor man skal tilføje et eller andet "magisk" bogstav, så det virker.
Nogle gange lagde jeg mærke til, at studerende tænker, at der til at løse en konkret opgave er brug for et eller andet andet konstruktion, som jeg bare ikke har fortalt endnu. Selvom man kun behøvede at modificere eksemplet lidt.

Derfor kom jeg til ideen om, at fokus ikke skal være på syntaksen af udtryk, men på idéen om refaktorering af gentaget kode med hjælp af løkker. Så snart eleverne mestrer denne idé, kan de ethvert syntaks lære gennem små øvelser.

Hvem og hvorfor jeg underviser

Da der ikke er nogle optagelsesprøver, kan der på lektionerne være både stærke og meget svage studerende. Man kan læse mere detaljeret om mine studerende i artiklen Portræt af deltagerne i aftenkurserne
Jeg stræbte efter, at programmering skulle være tilgængelig for alle, der ønsker det.
Mine lektioner foregår individuelt, og eleven betaler for hvert møde. Det kunne tyde på, at studerende vil optimere omkostningerne og kræve det minimale. Alligevel kommer folk til fysiske lektioner med en levende underviser, ikke kun for selve viden, men for trygheden ved, at de har forstået det, for følelsen af fremgang og for godkendelse fra eksperten (underviseren). Hvis studerende ikke føler, at de gør fremskridt i deres læring, vil de forlade undervisningen. Generelt kan man organisere lektionerne, så studerende føler fremgang ved at øge antallet af kendte konstruktioner. Så først studerer vi grundigt while, derefter for, så do while og så har vi et kursus, der minder om tusinde og én nat, hvor der i to måneder kun studeres løkker, hvilket resulterer i en studerende, der på diktat har skrevet standardbiblioteket. Men for at løse praktiske opgaver kræver det ikke kun viden om materialet, men også selvstændighed i anvendelsen af det og i jagten på ny information. Derfor anser jeg for fysiske kurser, at det er en god princip at lære minimum og tilskynde selvstudium af detaljer og beslægtede emner. I emnet om løkker anser jeg, at minimum er konstruktionen while. På den kan man forstå princippet. Ved at kende princippet kan man også selv lære for og do-while.

For weak students to master the material, it's not enough to describe the syntax. It is necessary to provide more simple yet diverse tasks and to elaborate on examples in greater detail. Ultimately, the speed of learning is limited by the student's ability to transform expressions and to find patterns. For more perceptive students, many tasks will feel boring. When working with them, it's okay not to insist on solving 100% of the problems. You can view my material on my GitHub. Although the repository resembles a sorcerer's grimoire — no one except me understands what is where, and if you fail the verification, you might just go insane.

The methodology is practice-oriented.

Theory is explained through problem-solving examples. In programming basics classes, where branching and loops are studied, it simply won't work to hold a useful lecture on one topic for an entire hour. 15-20 minutes are enough to explain the concept. The main difficulties arise during the practical tasks.
Beginner instructors might dump operators, branching, loops, and arrays in one lecture. However, students will struggle to grasp this information.
It's not just about conveying the material; one must also ensure that the listeners understand it.

The degree of mastery of the topic is determined by how the student performs in independent work.
If a student manages to solve a problem on the topic without the teacher's help, then they have mastered the topic. To ensure independent verification, each task is described with a table of test scenarios. Tasks have a clear order. Skipping tasks is not recommended. If the current task is too difficult, moving on to the next one is pointless. It will be even harder. To help the student tackle the current challenging task, several techniques are explained using the first task as an example. Essentially, the entire content of the topic comes down to techniques for overcoming difficulties. Loops are more of a side effect.

The first task is always an example. The second is slightly different and is completed 'independently' right after the first under the teacher's supervision. All subsequent tasks are aimed at drawing attention to various nuances that may cause misconceptions.

Forklaringen af eksemplet er en dialog, hvor studerende skal anvende back propagation og krydsvalidering for at sikre, at de forstår materialet.

Jeg vil være banal og sige, at det første eksempel på emnet er meget vigtigt. Hvis der er tilstrækkeligt materiale til selvstændigt arbejde, kan manglen på det første eksempel rettes. Hvis der ikke er andet end eksemplet, vil studerende sandsynligvis ikke mestre emnet.

While eller for?

Et af de omstridte spørgsmål er valget af konstrukt for eksemplet: while eller for. En gang overbeviste en ven, der er praktiserende udvikler uden undervisningserfaring, mig i en time om, at for-løkken er den nemmeste at forstå. Argumenterne gik på, at "alt er klart, og det er lagt på plads". Men den grundlæggende årsag til de faktiske nybegynders vanskeligheder ligger i selve ideen om løkken, ikke i selve skrivningen. Hvis en person ikke forstår denne idé, vil de have problemer med syntaksen. Når idéen er forstået, forsvinder problemerne med kodens format automatisk.

I mine materialer følger emnet om løkker efter emnet om forgrening. Den ydre lighed mellem if og while gør det muligt at lave en direkte analogi: "Når betingelsen i overskriften er sand, udføres kroppen." Forskellen ved løkken er blot, at kroppen udføres mange gange.

Mit andet argument er, at while kræver mindre format end for. Mindre format betyder færre dumme fejl med glemte kommaer og parenteser. Nybegyndere har ikke udviklet tilstrækkelig opmærksomhed og detaljeorientering til automatisk at undgå syntaktiske fejl.
Det tredje argument er, at while forklares først i mange gode bøger.

Hvis studerende nemt kan omdanne udtryk, kan man kort nævne for. Studerende vælger selv, hvad de foretrækker. Hvis omdannelsen derimod volder problemer, er det bedst ikke at sprede opmærksomheden. Lad den studerende først løse det hele med while. Når emnet om løkker er mestret, kan løsningerne omskrives for at øve omdannelsen fra while til for.
Løkker med postbetingelse er en ret sjælden størrelse. Jeg bruger slet ikke tid på dem. Hvis den studerende har mestret idéerne om at opdage mønstre og omdanne udtryk, vil de kunne klare sig uden min hjælp.

Når jeg præsenterer det første eksempel for stærke studerende, påpeger jeg, at det i første eksempel er vigtigt at dokumentere ikke kun løsningen, men også hele rækken af handlinger, der førte til resultatet. Dovne studerende kan forsømme dokumentationen og kun overføre den endelige algoritme. De skal overbevises om, at de også en dag vil stå overfor en vanskelig opgave. For at løse den, er det nødvendigt at følge trinene, som i dette eksempel. Derfor er det vigtigt at dokumentere alle faser. I de følgende opgaver kan man nøjes med at præsentere den endelige løsning.

Hovedideen bag automatisering er, at vi beder computeren om at udføre rutinearbejde for mennesket. En af de grundlæggende teknikker er at skrive løkker. Det bruges, når programmet skal udføre flere ensartede, gentagne handlinger.

Det åbenlyse er bedre end det skjulte

Det kan virke som en god idé i den første opgave om løkker at udskrive en ensartet sætning flere gange. For eksempel:

Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!
Hurra, det virker!

Denne tilgang er dårlig, fordi man ikke kan se tællerens værdi i outputtet. Dette er et problem for begyndere. Man skal ikke undervurdere det. Oprindeligt var denne opgave den første, og opgaven om at udskrive en sekvens af tal i stigende rækkefølge var den anden. Det blev nødvendigt at introducere yderligere termer som "løkke N gange" og "løkke fra A til B", som i princippet er det samme. For ikke at skabe unødvendige enheder, besluttede jeg at vise kun eksemplet med udskrivning af en sekvens af tal. Få personer lykkes med at lære at holde en tæller i hovedet og modellere programmets adfærd der, uden forberedelse. Nogle studerende møder for første gang konceptet med at modellere "i sindet" netop i emnet om løkker.
Efter lidt praksis giver jeg opgaven om at gentage den samme tekst til selvstændig løsning. Hvis man først giver en synlig tæller og derefter en usynlig, vil de studerende have færre problemer. Nogle gange er det nok med en henvisning til "skriv ikke tælleren på skærmen".

Hvordan forklares det hos andre?

I de fleste undervisningsmaterialer på internettet gives syntaksen for løkker som en del af en "forelæsning". For eksempel på developer.mozilla.org (i øjeblikket) beskrives flere konstruktioner sammen med while-løkken. Her gives der udelukkende selve konstruktionerne som skabeloner. Resultatet af deres kørsel beskrives med ord, og illustrationer mangler. Efter min mening reducerer en sådan præsentation emnets nytteværdi til nul. Eleverne kan gen skrive koden og køre den selv, men der er stadig behov for en reference til sammenligning. Hvordan skal man forstå, at eksemplet er kopieret korrekt, hvis der ikke er noget at sammenligne resultatet med?
Når der kun gives en skabelon uden eksempel, bliver det endnu sværere for studenten. Hvordan skal man forstå, at kodefragmenterne er placeret korrekt i skabelonen? Man kan prøve at skrive på en eller anden måde, og så køre den. Men hvis der ikke er en standard til sammenligning af resultatet, hjælper det heller ikke at køre den.

I C++-kurset på Intuit er syntaksen for løkken begravet på den tredje side af forelæsning 4 om "operatorer". Under forklaringen af løkkesyntaksen lægges der særlig vægt på termen "operator". Termen præsenteres som et sæt fakta, som "symbolet; det er en operator", "{} er en sammensat operator", "løkkens krop skal være en operator". Jeg kan ikke lide denne tilgang, fordi den skjuler vigtige sammenhænge bag én term. At analysere kildekoden på dette niveau er nødvendigt for compilerudviklere for at implementere sprogets specifikation, men ikke for studerende i første omgang. Nybegyndere i programmering har sjældent den nødvendige grundighed til at forholde sig så omhyggeligt til termer. Kun få mennesker husker og forstår nye ord første gang. Praktisk talt ingen kan anvende en term korrekt, som de lige har lært. Derfor opstår der en masse fejl hos studerende, såsom "jeg skrev while(a<7);{, men programmet fungerer ikke".
Jeg mener, at det i starten er bedre at give syntaksen for konstruktionen med det samme med parenteser. Varianten uden parenteser bør kun forklares, hvis eleven har et konkret spørgsmål som "hvorfor er der ingen parenteser her, og det fungerer".

I bogen af Okulov "Grundlæggende programmering" fra 2012 begynder introduktionen til løkker med skabelonen for, hvorefter der gives anbefalinger til brug, og derefter følger straks et eksperimentelt afsnit. Jeg forstår, at bogen blev skrevet til det lille mindretal af meget dygtige elever, som sjældent kommer til mine lektioner.

I populære bøger skrives resultatet af kodefragmenter altid. For eksempel i Schildts "Java 8. Den komplette guide" fra 2015 gives først skabelonen, derefter et eksempel på et program og straks derefter - resultatet af udførelsen.

Som eksempel ser vi på en while-løkke, hvor der udføres en nedtælling, der begynder fra 10, og der udskrives præcist 10 linjer "takt":
Efter start viser dette program ti "takt" på følgende måde:

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

Den tilgang, der beskriver skabelonen, eksemplet på programmet og resultatet af arbejdet med dette program, anvendes også i bogen "Javascript for børn" og i js-kurset på w3schools.com. Formatet på web-siden gør det endda muligt at gøre dette eksempel interaktivt.
takt 10
takt 9
takt 8
takt 7
takt 6
takt 5
takt 4
takt 3
takt 2
takt 1

I bogen af Stroustrup "Principper og praksis med C++" fra 2016 går forfatteren endnu længere. Først forklares hvad resultatet skal være, og derefter vises teksten af programmet. Desuden tages der ikke bare et tilfældigt program som eksempel, men der gives et kig tilbage i historien. Det hjælper med at henlede opmærksomheden på det: "Se, det er ikke bare en værdiløs tekst. Du ser noget betydningsfuldt."

Som eksempel på iteration ser vi på det første program, der blev udført på en maskine med stored program (EDSAC). Det blev skrevet af David Wheeler i Cambridge Universitets Computer Laboratory den 6. maj 1949. Dette program beregner og udskriver en simpel liste over kvadrater.

Her indeholder hver linje et tal efterfulgt af et tabulator tegn (‘t’) og kvadratet af dette tal. Versionen af dette program i C++ ser således ud:
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

Det er interessant, at skabelonen for syntaksen i denne bog ikke beskrives. Stroustrup lægger i instruktørmanualen (

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

) vægt på, at han respekterer sine elevers intellekt. Måske anses evnen til at identificere skabelonen i flere eksempler for at være et tegn på sådan intelligens.oversættelseSom jeg selv forklarer

Hvordan jeg forklarer

Stroustrup's approach: describe the outcome, then solve the task, and finally have the student analyze it independently — seems the most thoughtful. Therefore, I decided to base my discussion on this, but to illustrate it with a less historical example — the task of outputting a ‘table of contents’. It creates a recognizable anchor so that later I can say ‘remember the task about the table of contents’ and students will recall it specifically. In my example, I aimed to preempt two of the most common misconceptions. I will elaborate on them further.

In this task, we familiarize ourselves with techniques for solving complex problems. The initial solution should be primitive and simple. Only then can we think about how to improve this solution.
Introduktion
Kapitel 1
Kapitel 2
Kapitel 3
Kapitel 4
Kapitel 5
Kapitel 6
Kapitel 7
Konklusion

From my observations, the approach of ‘template-example-result’ in different combinations still leads students to perceive the loop as a hieroglyph. This was manifested in their misunderstanding of why to write a condition there, how to choose between i++ and i—, and other seemingly obvious matters. To avoid these misconceptions, the approach to explaining loops should emphasize the meaning of repeating identical actions and only then — formatting them using the construct. Therefore, before providing the syntax of the loop, one must solve the problem ‘straightforwardly’. The primitive solution to the table of contents task looks like this:

Console.WriteLine("Introduktion");
Console.WriteLine("Kapitel 1");
Console.WriteLine("Kapitel 2");
Console.WriteLine("Kapitel 3");
Console.WriteLine("Kapitel 4");
Console.WriteLine("Kapitel 5");
Console.WriteLine("Kapitel 6");
Console.WriteLine("Kapitel 7");
Console.WriteLine("Konklusion");

How can it be improved?
Replace the repetitive actions with a loop.
What actions are repeated here consecutively without changes?
There are none in this fragment. However, the commands to output the word ‘Kapitel’ with the number are very similar to each other.
Therefore, the next step is to find the difference between the fragments. It is only obvious in this task; later, not individual commands will repeat, but blocks of code of 5 lines or more. Searching will require looking not just in the list of commands, but in branching or loop constructs.
In the example, the difference between the commands is in the number following the word ‘Kapitel’.
Once the difference is found, it is necessary to understand the pattern of change. Is the distinguishing fragment a number? Does it constantly increase or decrease? How does the value of the number change between the two commands adjacent to each other?
I eksemplet stiger tallet efter ordet "Kapitel" med skridtet 1. Forskellen er fundet, der er identificeret et mønster. Nu kan den varierende del erstattes med en variabel.
Sådan en variabel skal deklareres før den første af de gentagne dele. En sådan variabel kaldes normalt i eller j, eller et mere udførligt navn. Dens startværdi skal være lig med den første værdi, der vises på skærmen. I eksemplet er den første værdi 1.
Hvilken startværdi skal tages for at vise rækken af tal "100, 101, 102, 103, 104, 105"?
I denne række er det første tal 100.
Efter hver output-kommando skal værdien af denne variabel øges med 1. Denne 1 er ændringsskridtet.
Hvilket skridt vil der være i rækken af tal "100, 102, 104, 106"?
I denne række er skridtet 2.
Efter at have erstattet den varierende del med en variabel, vil koden se sådan ud:

Console.WriteLine("Introduktion");
int i;
i = 0;
Console.WriteLine("Kapitel " + i);
i = i + 1;
Console.WriteLine("Kapitel " + i);
i = i + 1;
Console.WriteLine("Kapitel " + i);
i = i + 1;
Console.WriteLine("Kapitel " + i);
i = i + 1;
Console.WriteLine("Kapitel " + i);
i = i + 1;
Console.WriteLine("Kapitel " + i);
i = i + 1;
Console.WriteLine("Kapitel " + i);
i = i + 1;
Console.WriteLine("Konklusion");

Efter anvendelsen af metoden "udtryk mønstret som en variabel" resulterer koden i flere grupper af ensartede handlinger, der følger hinanden. Nu kan de gentagne handlinger erstattes med en løkke.

Sekvensen til løsning af opgaven, hvor cykler skal bruges, består af følgende trin:

  1. Løs "direkte" med mange separate kommandoer
  2. Find mønsteret
  3. Udtryk mønsteret som en variabel
  4. Præsenter det i form af en løkke

Dernæst introduceres nye termer, så studerende ikke står i situationen "jeg forstår alt, men kan ikke sige det":
— tæller — altid en variabel, der er nødvendig for at holde styr på antallet af skridt i løkken. Normalt et helt tal, der sammenlignes med en grænse.
— skridtet for tælleren — beskrivelse af mønstret for ændring af tælleren.
— grænsen — tal eller variabel, som tælleren sammenlignes med, så algoritmen er endelig. Tællerens værdi ændres for at nærme sig grænsen.
— kroppen af løkken — sæt af kommandoer, der vil blive gentaget. Når der siges "kommando skrevet inden for løkken", refereres der netop til kroppen.
— iteration af løkken — én enkelt udførelse af løkkens krop.
— betingelse for loop — det logiske udtryk, der bestemmer, om en ny iteration skal udføres. (Her kan der være forvirring med forgreningskonstruktioner)
Man skal være forberedt på, at studerende i begyndelsen vil anvende termerne forkert. Dette gælder både stærke og svage. At etablere et fælles sprog er en kunst. Jeg vil skrive kort: man skal stille opgaven "udvælg kodefragmentet med " og selv bruge termerne korrekt i samtalen.
Efter transformationen med loopet får vi fragmentet:

Console.WriteLine("Introduktion");
int i = 0;
while (i < 7) {
    Console.WriteLine("Kapitel " + i);
    i = i + 1;
}
Console.WriteLine("Konklusion");

Hovedmisforståelsen

En populær misforståelse blandt studerende er, at de inden for loopkonstruktionen placerer sådanne handlinger, der kun skal udføres én gang. For eksempel sådan her:

;
int i = 0;
while (i < 7) {
    Console.WriteLine("Introduktion")
    Console.WriteLine("Kapitel " + i);
    i = i + 1;
    Console.WriteLine("Konklusion");
}

Eleverne støder konstant på dette problem, både i begyndelsen og i mere komplekse opgaver.
Den grundlæggende ledetråd i dette tilfælde:

Hvor mange gange skal man gentage kommandoen: én gang eller mange?

Kommandoerne for at udskrive ordene "Introduktion" og "Konklusion", samt erklæringen og initialiseringen af variablen i, adskiller sig fra de andre gentagne handlinger. De udføres kun én gang, derfor skal de skrives uden for loopets krop.

Koden skal inkludere alle tre faser af løsningen, så man senere kan henvise til dem i tilfælde af vanskeligheder. De første to versioner kan sagtens kommenteres ud, så de ikke forstyrrer.
Studerendes opmærksomhed skal rettes mod følgende fakta:
— I loopets betingelse sammenlignes tælleren og grænsen. Tælleren kan ændres i loopets krop, men grænsen kan ikke. For at bryde denne regel skal der angives gode grunde.
— Kommandoerne til at udskrive ordene "Introduktion" og "Konklusion" er placeret uden for loopets krop. Vi skal kun udføre dem én gang. "Introduktion" — før gentagelse af handlingerne, "Konklusion" — efter.
I processen med at befæste dette emne, lære de næste, samt i forbindelse med vanskeligheder, er det nyttigt selv for stærke studerende at stille spørgsmålet: "Og dette handling, hvor mange gange skal det udføres? Én eller mange?".

Udvikling af supplerende færdigheder

I studerende udvikler endnu deres færdighed til at diagnosticere og løse problemer i forbindelse med læring af loop. For at udføre en diagnose skal studenten forestille sig det ønskede resultat og sammenligne det med det faktiske resultat. Handlingerne for at rette fejl afhænger af forskellen mellem dem.
Da studerende på dette stadium stadig har en begrænset forståelse af, hvad et "ønsket" resultat er, kan de orientere sig efter testdata. Generelt forstår ingen på dette stadium, hvad der kan gå galt, og hvordan man håndterer det. Derfor giver jeg en skriftlig beskrivelse af typiske problemer og flere måder at løse dem på. Valget af den mest passende løsning er studentens opgave.
Notater er nødvendige for at kunne stille spørgsmål som "Fik vi det resultat, vi forventede?", "Hvilken af disse situationer fandt sted nu?", "Hjalp den brugte løsning?".

  1. Antallet af handlinger er 1 mindre eller mere end forventet. Løsningsmetoder:
    — øge den indledende værdi af tælleren med 1.
    — erstatte den strenge sammenligningsoperator (< eller >) med den ikke-strenge (<= eller >=).
    — ændre grænseværdien med 1.
  2. Handlinger i løkken udføres uden stop, uendeligt. Løsningsmetoder:
    — tilføje en ændringskommando for tælleren, hvis den mangler.
    — rette ændringskommandoen for tælleren, så dens værdi nærmer sig grænsen.
    — fjerne ændringskommandoen for grænsen, hvis den er i løkkens krop.
  3. Antallet af handlinger i løkken er mere end 1 mindre eller mere end forventet. Handlingerne i løkken blev ikke udført en eneste gang. Først skal de faktiske værdier for variablerne findes lige før starten af løkken. Løsningsmetoder:
    — ændre den indledende grænseværdi.
    — ændre den indledende værdi af tælleren.

Normalt er problem 3 relateret til brugen af den forkerte variabel eller at tælleren ikke nulstilles.

Efter denne forklaring kan studenten stadig have forskellige misforståelser angående løb.
For at afklare de mest almindelige misforståelser giver jeg opgaver:

  1. Hvor grænsen, den indledende værdi af tælleren eller skridtet for tælleren indtastes af brugeren.
  2. Hvor værdien af tælleren skal bruges i et aritmetisk udtryk. Det er ønskeligt, at tælleren er i nævneren eller i den underliggende del af udtrykket, så forskellen bliver ikke-lineær.
  3. Hvor værdien af tælleren ikke vises på skærmen under udførelsen af løkken. For eksempel at vise et nødvendigt antal ens fragmenter af tekst eller tegne en figur med turtles grafikker.
  4. Hvor man først skal udføre én type gentagne handlinger og derefter en anden.
  5. Hvor der skal udføres andre handlinger før og efter de gentagne.

For hver opgave skal der angives testdata og forventet resultat.

For at forstå, hvor hurtigt man kan bevæge sig, skal man give dem mulighed for at læse betingelserne for disse opgaver og spørge: "hvordan adskiller de sig fra eksemplet?", "hvad skal der ændres i eksemplet for at løse dem?". Hvis eleven svarer meningsfuldt, kan de løse mindst én opgave i timen, mens de andre gør det hjemme. Hvis løsningen er succesfuld, kan man starte forklaringen om betingelserne inden for løkker.
Hvis der er vanskeligheder med selvstændig løsning, skal alt øves i timen. For at løsningen ikke skal minde om at tegne en ugle, anbefaler jeg først at løse opgaven ikke universelt. Det vil sige, at løsningen skal bestå den første test og ikke bruge løkkekonstruktionen. Derefter kan man anvende transformationer for at opnå universel løsning.

Løkker og betingninger

Efter min mening er det nyttigt at give emnet "løkker inden for betingninger" separat. Så man bagefter kan se forskellen mellem gentagen betingelseskontrol og engang kontrollen.
Opgaver til øvelse vil være om at udskrive tal fra A til B, som indtastes af brugeren:
— altid stigende.
— stigende eller faldende afhængigt af værdierne for A og B.

Man skal kun gå videre til emnet "betingelser inden for løkker", efter at eleven har mestret teknikkerne: "erstatning af mønstre med variable" og "erstatning af gentagne handlinger med løkker".
Hovedårsagen til at anvende betingelser inden for løkker er uregelmæssigheder i mønsteret. I midten bliver det forstyrret afhængigt af inputdataene.
Til de studerende, som er i stand til at finde løsninger ved at kombinere enkle teknikker, er det tilstrækkeligt at sige "betingelser kan skrives inde i løkker" og give en opgave "for eksempel" helt til selvstændig løsning.
Eksempelopgave:

Brugeren indtaster tallet X. Udskriv i kolonne tal fra 0 til 9 og sæt et '+' tegn ud for det tal, der svarer til X.

Hvis der blev indtastet 00+
1
2
3
4
5
6
7
8
9

Hvis der blev indtastet 60
1
2
3
4
5
6+
7
8
9

Hvis der blev indtastet 90
1
2
3
4
5
6
7
8
9+

Hvis der blev indtastet 7770
1
2
3
4
5
6
7
8
9

Hvis der mangler en kort forklaring for at skrive med en løkke, så skal der opnås en universel løsning på den samme opgave uden løkke.
Der vil komme en af to muligheder:
Ønsket

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);
}

Mulig

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+");
}

Jeg giver en lignende opgave på forhånd, mens vi lærer emnet om forgrening.
Hvis en studerende har opnået en "mulig" mulighed, skal der fortælles, at der kan være mange løsninger på den samme opgave. Men de varierer i robusthed over for ændringer i krav. Stil spørgsmålet: "Hvor mange steder i koden skal rettes, hvis der skal tilføjes et andet tal?" I den "mulige" mulighed skal der tilføjes endnu en forgrening og at skrive det nye tal i 10 andre steder. I den "ønskede" er det blot nødvendigt at tilføje én forgrening.
Sæt en opgave til at reproducere den "ønskede" mulighed, og find derefter mønsteret i koden, udfør udskiftning af variablen og skriv en løkke.
Hvis du har en idé til, hvordan denne opgave kan løses uden en løkke på en anden måde, så skriv gerne i kommentarer.

Løkker inden i løkker

I dette emne skal der være fokus på, at:
— tællere for den indre og den ydre løkke skal være forskellige variabler.
— tælleren for den indre løkke skal nulstilles mange gange (det vil sige i kroppen af den ydre løkke).
I opgaver med udskrivning af tekst kan man ikke først skrive et bogstav i flere linjer og derefter et andet. Man skal først udskrive alle bogstaver fra den første linje, derefter alle bogstaver fra den anden osv.

Forklaringen på emnet om løkker inden for løkker bør bedst begynde med at forklare vigtigheden af at nulstille tælleren.
Eksempelopgave:

Brugeren indtaster to tal: R og T. Udskriv to linjer af tegn "#". Den første linje skal have R antal tegn. Den anden linje skal have T antal tegn. Hvis et af tallene er negativt, skal der udskrives en fejlmeddelelse.

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

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

R=-1, T=6Værdien af R skal være ikke-negativ

R=6, T=-2Værdien af T skal være ikke-negativ

Det er tydeligt, at denne opgave også har mindst to løsninger.
Ønsket

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;
}

Mulighed nr. 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;
}

Forskellen er, at i den "mulige" løsning blev der brugt en anden variabel til at udskrive den anden linje. Man skal insistere på at bruge den samme variabel til begge løkker. Dette begrænsningsargument kan forklares ved, at en løsning med én tæller til to løkker vil illustrere termen "nulstilling af tælleren". Forståelsen af denne term er nødvendig ved løsningen af de følgende opgaver. Som et kompromis kan man gemme begge løsninger på opgaven.

Et typisk problem ved brugen af én tæller til to løkker viser sig sådan her:
R=5, T=11#####
######

Antallet af tegn i den anden linje stemmer ikke overens med værdien T. Hvis der er brug for hjælp til dette problem, skal man "pege på" noterne om typiske løkkeproblemer. Dette er symptom nr. 3. Det diagnosticeres ved at tilføje udskrift af tælleren lige før den anden løkke. Det rettes ved nulstilling. Men det er bedre ikke at fortælle for meget om det med det samme. Den studerende skal forsøge at formulere mindst en hypotese.

Der er selvfølgelig også denne løsning. Men jeg har aldrig set den hos studerende. I løbet af læringen om løkker vil en fortælling om det forvirre opmærksomheden. Man kan vende tilbage til det senere, når man studerer funktioner til arbejdet med strenge.
Mulighed nr. 2

string 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));

Den næste obligatoriske opgave:

Vis tallene fra 0 til 9 på skærmen. Hvert tal skal stå på sin egen linje. Antallet af tal pr. linje (W) indtastes via tastaturet.

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

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

Hvis eleven har mestret metoden med at erstatte variablen, vil de klare det ret hurtigt. Et muligt problem vil igen være nulstillingen af variablen. Hvis du har svært ved konverteringen, så har du muligvis hastet og skal arbejde med lettere opgaver først.

Tak for opmærksomheden. Giv likes og abonner på kanalen.

P.S. Hvis du finder tastefejl eller fejl i teksten, bedes du give mig besked. Du kan gøre dette ved at markere en del af teksten og trykke på Mac «⌘ + Enter», og på klassiske tastaturer «Ctrl / Enter», eller via personlige beskeder. Hvis de muligheder ikke er tilgængelige, så skriv om fejlene i kommentarerne. Tak!

Kun registrerede brugere kan deltage i undersøgelsen. Log ind, please.

Afstemning for læsere uden karma

  • 20,0%Underviser professionelt, +12

  • 10,0%Underviser professionelt, -11

  • 70,0%Underviser ikke, +17

  • 0,0%Underviser ikke, -10

  • 0,0%Andet0

10 brugere har stemt. 5 brugere har undladt at stemme.

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster