Hur man lär ut hur man övervinner svårigheter och samtidigt skriver cykler

Trots att vi kommer att prata om ett av de grundläggande ämnena, är den här artikeln skriven för erfarna proffs. Målet är att visa vilka missuppfattningar nybörjare har inom programmering. För praktiserande utvecklare har dessa problem länge varit lösta, glömda eller inte uppmärksammats alls. Artikeln kan komma till nytta om du plötsligt behöver hjälpa någon med detta ämne. Artikeln drar paralleller med material från olika böcker om programmering av Schildt, Stroustrup, Okulov.

Ämnet om cykler valdes eftersom ganska många människor är uteslutna från det när de behärskar programmering.

Denna teknik är designad för svaga elever. Som regel fastnar inte starka människor i detta ämne och det finns ingen anledning att komma med speciella tekniker för dem. Det sekundära målet med artikeln är att flytta denna teknik från klassen "fungerar för alla elever, men bara en lärare" till klassen "fungerar för alla elever, alla lärare". Jag hävdar inte absolut originalitet. Om du redan använder en liknande metod för att lära ut detta ämne, skriv gärna hur din version skiljer sig. Om du bestämmer dig för att använda den, berätta hur det gick. Om en liknande teknik beskrivs i en bok, skriv namnet.


Jag arbetade med denna teknik i 4 år och studerade individuellt med elever på olika utbildningsnivåer. Totalt är det ett femtiotal elever och tvåtusen timmar lektioner. Till en början fastnade eleverna alltid i detta ämne och gick. Efter varje elev justerades metodiken och materialet. Under det senaste året har eleverna inte längre fastnat för detta ämne, så jag bestämde mig för att dela med mig av mina resultat.

Varför så många bokstäver? Cykler är så elementära!

Som jag skrev ovan, för praktiserande utvecklare och för starka studenter, kan komplexiteten i begreppet loopar underskattas. Du kan till exempel hålla en lång föreläsning, se nickande huvuden och intelligenta ögon. Men när man försöker lösa något problem börjar stupor och oförklarliga problem. Efter föreläsningen hade eleverna förmodligen bara en delvis förståelse. Situationen förvärras av att eleverna själva inte kan uttrycka vad deras vanföreställning är.
En dag insåg jag att eleverna uppfattade mina exempel som hieroglyfer. Det vill säga som odelbara bitar av text där du behöver lägga till någon "magisk" bokstav och det kommer att fungera.
Ibland märkte jag att elever tycker att man behöver lösa ett specifikt problem något annat en design som jag bara inte har täckt ännu. Även om lösningen bara krävde en liten modifiering av exemplet.

Så jag kom på idén att fokus inte skulle ligga på syntaxen för uttryck, utan på idén att omfaktorera repetitiv kod med loopar. När eleverna har bemästrat denna idé kan vilken syntax som helst förbättras med lite övning.

Vem och varför undervisar jag?

Eftersom det inte finns några inträdesprov kan klasser innehålla både starka och mycket svaga elever. Du kan läsa mer om mina elever i artikeln Porträtt av kvällskursstudenter
Jag strävade efter att se till att alla som vill lära sig programmering kan lära sig det.
Mina lektioner hålls individuellt och eleven betalar sina egna pengar för varje. Det verkar som om studenter kommer att optimera kostnaderna och kräva ett minimum. Men människor går till lektioner ansikte mot ansikte med en levande lärare, inte för kunskapen i sig, utan för förtroendet för vad de har lärt sig, för en känsla av framsteg och för godkännande från experten (läraren). Om eleverna inte känner framsteg i sitt lärande kommer de att lämna. I allmänhet kan klasserna struktureras så att eleverna känner framsteg i att öka antalet välbekanta strukturer. Det vill säga, först studerar vi medan i detalj, sedan studerar vi för, sedan gör vi medan, och nu har vi en kurs i tusen och en natt redo, där enbart cykler studeras i två månader, och i slutet - en student som skrev ett standardbibliotek under diktering. Men för att lösa praktiska problem behöver du inte bara kunskap om materialet, utan också oberoende i dess tillämpning och i att söka efter ny information. Därför, för kurser ansikte mot ansikte, tror jag att den korrekta principen är att lära ut minimum och uppmuntra oberoende studier av nyanser och relaterade ämnen. När det gäller slingor anser jag att while-konstruktionen är ett minimum. Du kan förstå principen utifrån det. Genom att känna till principen kan du bemästra både för och göra-medan du själv.

För att svaga elever ska kunna behärska materialet räcker det inte med att beskriva syntaxen. Det är nödvändigt att ge enklare men varierande uppgifter och beskriva exempel mer i detalj. I slutändan begränsas utvecklingshastigheten av elevens förmåga att omvandla uttryck och söka efter mönster. För smarta elever kommer de flesta uppgifter att vara tråkiga. När du studerar med dem behöver du inte insistera på att lösa 100% av problemen. Mitt material finns att se på min github. Det är sant att förvaret är mer som en trollkarls grimoire - ingen utom jag kommer att förstå vad som är var, och om du misslyckas med kontrollen kan du bli galen

Metodiken är praktikinriktad

Teorin förklaras med hjälp av exemplet på att lösa ett problem. I en grundkurs i programmering där grenar och loopar lärs ut är det helt enkelt inte möjligt att hålla en användbar föreläsning om ett ämne under en hel timme. 15-20 minuter räcker för att förklara konceptet. De största svårigheterna uppstår när man utför praktiska uppgifter.
Nybörjarlärare kan skramla bort operatörer, grenar, loopar och arrayer i en föreläsning. Men deras elever kommer att möta problemet med att tillgodogöra sig denna information.
Det är nödvändigt att inte bara berätta materialet, utan också att se till att lyssnarna förstår det.

Att bemästra ett ämne bestäms av hur studenten klarar av självständigt arbete.
Om en elev lyckades lösa ett problem i ett ämne utan hjälp av en lärare, då har ämnet bemästrats. För att säkerställa självtestning beskrivs varje uppgift i en tabell med testscenarier. Arbetsuppgifterna har en tydlig ordning. Att hoppa över uppgifter rekommenderas inte. Om den aktuella uppgiften är för svår är det meningslöst att gå vidare till nästa. Det är ännu mer komplicerat. För att eleven ska kunna bemästra den aktuella komplexa uppgiften, förklaras flera tekniker för honom med hjälp av exemplet med det första problemet. Egentligen handlar hela innehållet i ämnet om tekniker för att övervinna svårigheter. Cykler är mer av en bieffekt.

Den första uppgiften är alltid ett exempel. Den andra skiljer sig något och utförs "självständig" omedelbart efter den första under överinseende av en lärare. Alla efterföljande uppgifter syftar till att uppmärksamma olika små saker som kan orsaka missuppfattningar.

Förklaringen till exemplet är en dialog där eleven behöver ringa tillbaka spridning och korsvalidering för att försäkra sig om att han behärskar en del av materialet.

Jag kommer att vara banal och säga att det första exemplet på ämnet är väldigt viktigt. Om du har materialet för ett omfattande självständigt arbete kan utelämnanden i det första exemplet rättas till. Om det inte finns något annat än exemplet, kommer studenten sannolikt inte att bemästra ämnet.

Medan eller för?

En av de kontroversiella frågorna är valet av konstruktion för exemplet: medan eller för. En gång tillbringade en praktiserande utvecklarvän till mig utan undervisningserfarenhet en timme för att övertyga mig om att for-slingan var lättast att förstå. Argumenten kokade ner till "allt i det är klart och lagt ut på sin plats." Men grundorsaken till svårigheter för riktiga nybörjare är idén om själva cykeln och inte dess skrivning. Om en person inte förstår denna idé, kommer han att ha svårt med syntaxen. Så fort idén förverkligas försvinner problemen med koddesign av sig själva.

I mina material följer temat slingor temat förgrening. Den externa likheten av om och medan tillåter oss att dra en direkt analogi: "när villkoret i rubriken är sant, då exekveras kroppen." Den enda egenheten med cykeln är att kroppen avrättas många gånger.

Mitt andra argument är att medan kräver mindre formatering än för. Mindre formatering innebär färre dumma misstag med saknade kommatecken och parenteser. Nybörjare har ännu inte utvecklat tillräckligt med uppmärksamhet och noggrannhet för att automatiskt undvika syntaxfel.
Det tredje argumentet förklaras i många bra böcker som det första argumentet.

Om eleven lätt kan omvandla uttryck, då kan man prata om för i förbigående. Eleven väljer sedan det han gillar bäst. Om transformationer orsakar svårigheter, är det bättre att inte distrahera din uppmärksamhet. Låt eleven först lösa allt med medan. När du har bemästrat ämnet loopar kan du skriva om lösningarna för att öva på att konvertera medan till för.
Postcondition loopar är en ganska sällsynt best. Jag lägger ingen tid på det alls. Om en elev har bemästrat idéerna att identifiera mönster och omvandla uttryck, kan han lista ut det utan min hjälp.

När jag demonstrerar det första exemplet för starka elever, uppmärksammar jag det faktum att det i det första exemplet är viktigt att inte bara registrera lösningen, utan också hela kedjan av åtgärder som ledde till resultatet. Lata elever kan försumma skrivandet och kopiera endast den slutliga algoritmen. De måste övertygas om att en dag kommer en svår uppgift att dyka upp. För att lösa det måste du följa stegen som i det här exemplet. Därför är det viktigt att spela in alla stadier. I följande problem kommer det att vara möjligt att endast lämna den slutliga versionen av lösningen.

Huvudidén med automatisering är att vi anförtror en dator att göra rutinarbete för en person. En av de grundläggande teknikerna är att skriva loopar. Det används när flera identiska upprepade åtgärder skrivs i ett program i rad.

Explicit är bättre än implicit

Det kan verka som en bra idé att visa samma fras flera gånger i den första loopningsuppgiften. Till exempel:

Hurra, det funkar!
Hurra, det funkar!
Hurra, det funkar!
Hurra, det funkar!
Hurra, det funkar!
Hurra, det funkar!
Hurra, det funkar!
Hurra, det funkar!

Det här alternativet är dåligt eftersom räknarvärdet inte är synligt i utgången. Detta är ett problem för nybörjare. Underskatta henne inte. Till en början var denna uppgift den första, och uppgiften att härleda en serie tal i stigande ordning var den andra. Det var nödvändigt att införa ytterligare termer "cykel N gånger" och "cykel från A till B", som i huvudsak är samma sak. För att inte skapa onödiga enheter bestämde jag mig för att bara visa ett exempel med utdata av en serie nummer. Få människor lyckas lära sig att hålla en disk i huvudet och modellera ett programs beteende i huvudet utan förberedelser. Vissa elever möter först mental modellering på ämnet cykler.
Efter lite övning ger jag uppdraget att upprepa samma text som ska lösas självständigt. Om du först ger en synlig disk och sedan en osynlig kommer eleverna att få färre problem. Ibland räcker tipset "skriv inte räknaren på skärmen".

Hur förklarar andra det?

I de flesta utbildningsmaterial på Internet ges cykelns syntax som en del av en "föreläsning". Till exempel, på developer.mozilla.org (för närvarande) beskrivs flera andra konstruktioner tillsammans med while-loopen. I det här fallet ges endast designen i sig i form av mallar. Resultatet av deras lansering beskrivs i ord, men det finns ingen illustration. Enligt min åsikt multiplicerar en sådan presentation av ämnet användbarheten av sådant material med noll. En elev kan skriva om koden och köra den själv, men han behöver fortfarande en standard för jämförelse. Hur kan man förstå att ett exempel har skrivits om korrekt om det inte finns något att jämföra resultatet med?
När endast en mall ges, utan exempel, blir det ännu svårare för eleven. Hur förstår man att kodfragmenten är korrekt placerade i mallen? Du kan försöka skriva på något sätt, och kör sedan. Men om det inte finns någon standard för att jämföra resultatet, så hjälper inte lanseringen heller.

I C++-kursen om Intuitiv är loopsyntaxen begravd på tredje sidan av föreläsning 4 om ämnet "operatörer". När syntaxen för loopar förklaras, läggs särskild vikt vid termen "operatör". Termen presenteras som en uppsättning fakta som "symbol; detta är en sats", "{} är en sammansatt sats", "slingans kropp måste vara en sats". Jag gillar inte detta tillvägagångssätt eftersom det verkar dölja viktiga relationer bakom en term. Att analysera källkoden för ett program i termer på denna nivå krävs av kompilatorutvecklare för att implementera språkspecifikationen, men inte av studenter som en första approximation. Nykomlingar inom programmering är sällan noggranna nog för att ägna så stor uppmärksamhet åt termer. Det är en sällsynt person som kommer ihåg och förstår nya ord första gången. Nästan ingen kan korrekt tillämpa en term de just lärt sig. Därför får eleverna många fel som "Jag skrev while(a<7);{, men programmet fungerar inte."
Enligt min mening är det i början bättre att ge konstruktionens syntax omedelbart med parentes. Alternativet utan parentes bör endast förklaras om eleven har en specifik fråga: "varför finns det inga parenteser och det fungerar."

I Okulovs bok "Fundamentals of Programming" från 2012 börjar en introduktion till slingor med for-mönstret, ger sedan rekommendationer för dess användning och går sedan omedelbart till den experimentella delen av lektionen. Jag förstår att boken skrevs för den minoritet av mycket duktiga elever som sällan kommer till mina klasser.

I populära böcker skrivs alltid resultatet av kodfragment. Till exempel Shildts "Java 8. The Complete Guide" 2015-utgåva. Först ges en mall, sedan ett exempelprogram och omedelbart efter det - resultatet av exekveringen.

Som ett exempel, överväga en while-loop som gör det omvända
nedräkning från 10, och exakt 10 rader med "mått" visas:

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

När programmet har körts utmatar det tio "cykler" enligt följande:
такт 10
такт 9
такт 8
такт 7
такт 6
такт 5
такт 4
такт 3
такт 2
такт 1

Tillvägagångssättet att beskriva en mall, ett exempelprogram och programmets resultat används också i boken "Javascript for Kids" och i js-kursen på w3schools.com. Webbsidesformatet tillåter till och med att detta exempel är interaktivt.

Stroustrups bok 2016 Principles and Practice Using C++ gick ännu längre. Det första steget är att förklara vilket resultat som ska erhållas, och efter det visas programmets text. Dessutom tar de inte bara ett slumpmässigt program som exempel, utan ger en utflykt till historien. Detta hjälper till att uppmärksamma det: "Titta, det här är inte bara någon värdelös text. Du ser något meningsfullt."

Som ett exempel på iteration, betrakta det första programmet som körs på en lagrad programmaskin (EDSAC). Den skrevs av David Wheeler vid Computer Laboratory vid Cambridge University, England den 6 maj 1949. Detta program beräknar och skriver ut en enkel lista med kvadrater.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

Här innehåller varje rad ett tal följt av ett tabbtecken ('t') och kvadraten på det numret. C++-versionen av detta program ser ut så här:

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

Intressant nog beskrivs inte syntaxmönstret i den här boken. Stroustrup i instruktörshandboken (översättning) betonar att den respekterar sina elevers intelligens. Kanske anses förmågan att identifiera ett mönster i flera exempel vara en manifestation av sådan intelligens.

Som jag förklarar mig själv

Stroustrups tillvägagångssätt: att beskriva resultatet, sedan lösa problemet och sedan göra en oberoende analys av eleven - verkar mest genomtänkt. Därför bestämde jag mig för att ta det som grund, men berätta det med ett mindre historiskt exempel - uppgiften att härleda en "innehållsförteckning". Den bildar ett igenkännbart ankare så att man sedan kan säga ”kom ihåg uppgiften om innehållsförteckningen” och så att eleverna kommer ihåg exakt detta. I mitt exempel försökte jag förhindra ytterligare två av de vanligaste missuppfattningarna. Härnäst kommer jag att skriva mer om dem.

I denna uppgift introduceras vi till tekniker för att lösa komplexa problem. Det första beslutet måste göras primitivt och enkelt. Tja, då kan du fundera på hur du kan förbättra den här lösningen.
Введение
Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6
Глава 7
Заключение

Enligt mina observationer leder tillvägagångssättet ”mall-exempel-resultat” i olika kombinationer fortfarande till att eleverna uppfattar cykeln som en hieroglyf. Detta yttrade sig i att de inte förstod varför det fanns ett villkor att skriva där, hur man kan välja mellan i++ och i— och andra till synes självklara saker. För att undvika dessa missuppfattningar bör tillvägagångssättet att prata om cykler betona innebörden av att upprepa identiska handlingar och först därefter formalisera dem med hjälp av en struktur. Innan du ger loopsyntaxen måste du därför lösa problemet direkt. En primitiv lösning på innehållsförteckningsproblemet ser ut så här:

Console.WriteLine("Введение");
Console.WriteLine("Глава 1");
Console.WriteLine("Глава 2");
Console.WriteLine("Глава 3");
Console.WriteLine("Глава 4");
Console.WriteLine("Глава 5");
Console.WriteLine("Глава 6");
Console.WriteLine("Глава 7");
Console.WriteLine("Заключение");

Hur kan det förbättras?
Ersätt monotona handlingar med en cykel.
Vilka åtgärder upprepas i rad utan ändringar?
Det finns inga i detta fragment. Men kommandona för att visa ordet "Kapitel" med ett nummer är väldigt lika varandra.
Därför är nästa steg att hitta skillnaden mellan fragmenten. Det är bara i denna uppgift som allt är uppenbart, då kommer inte enstaka kommandon att upprepas, utan kodblock på 5 rader eller mer. Du måste söka inte bara i listan med kommandon, utan i gren- eller loopkonstruktioner.
I exemplet är skillnaden mellan kommandona i numret efter ordet "Kapitel".
När skillnaden har hittats måste du förstå mönstret för förändring. Det olika fragmentet är numret? Ökar eller minskar det hela tiden? Hur förändras värdet på ett nummer mellan två lag sida vid sida?
I exemplet ökar siffran efter ordet "Kapitel" i steg om 1. Skillnaden hittas, mönstret avslöjas. Nu kan du ersätta det olika fragmentet med en variabel.
Du måste deklarera en sådan variabel före det första av de upprepade fragmenten. En sådan variabel brukar kallas I eller j eller något mer detaljerat. Dess initiala värde måste vara lika med det första värdet som visas på skärmen. I exemplet är det första värdet 1.
Vilket initialvärde ska användas för att visa nummerserien "100, 101, 102, 103, 104, 105"?
Den första siffran i denna serie är 100.
Efter varje utmatningskommando måste du öka värdet på denna variabel med 1. Denna enhet är ändringssteget.
Vilket steg kommer att vara i nummerserien "100, 102, 104, 106"?
Steg 2 i denna rad.
Efter att ha ersatt det olika fragmentet med en variabel kommer koden att se ut så här:

Console.WriteLine("Введение");
int i;
i = 0;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Глава " + i);
i = i + 1;
Console.WriteLine("Заключение");

Efter att ha tillämpat tekniken "uttrycka en variabels mönster" i koden får du flera grupper av identiska åtgärder som går i rad. Nu kan upprepade åtgärder ersättas med en loop.

Sekvensen för att lösa ett problem där du behöver använda loopar består av följande steg:

  1. Lös direkt med många separata kommandon
  2. Hitta ett mönster
  3. Uttryck mönstret för en variabel
  4. Design som ett kretslopp

Därefter introduceras nya termer så att eleven inte hamnar i situationen "Jag förstår allt, men jag kan inte säga det":
— en räknare är alltid en variabel som behövs för att spåra antalet steg i en loop. Vanligtvis ett heltal som jämförs med begränsningen.
— räknarsteg — beskrivning av mönstret för räknarändringar.
- begränsning - ett tal eller en variabel som räknaren jämförs med så att algoritmen är slutgiltig. Räknarvärdet ändras för att närma sig gränsen.
— loop body — en uppsättning kommandon som kommer att upprepas. När de säger "kommandot är skrivet i en slinga" menar de kroppen.
— loop iteration — engångsexekvering av loopkroppen.
— loop condition — ett logiskt uttryck som bestämmer om ytterligare en iteration kommer att exekveras. (Det kan finnas förväxling med förgreningsstrukturer här)
Du måste vara beredd på att eleverna till en början kommer att använda termer för andra syften. Det gäller både de starka och de svaga. Att etablera ett gemensamt språk är en konst. Nu ska jag skriva kort: du måste ställa in uppgiften "markera kodfragmentet med <term>" och använda dessa termer själv korrekt i konversationen.
Efter transformation med en slinga erhålls fragmentet:

Console.WriteLine("Введение");
int i = 0;
while (i < 7) {
    Console.WriteLine("Глава " + i);
    i = i + 1;
}
Console.WriteLine("Заключение");

Den huvudsakliga missuppfattningen

En populär missuppfattning bland elever är att de placerar åtgärder i en loop som bara behöver göras en gång. Till exempel så här:

;
int i = 0;
while (i < 7) {
    Console.WriteLine("Введение")
    Console.WriteLine("Глава " + i);
    i = i + 1;
    Console.WriteLine("Заключение");
}

Elever stöter på detta problem hela tiden, både i början och i mer komplexa problem.
Nyckeltips i det här fallet:

Hur många gånger ska du upprepa kommandot: en eller många gånger?

Kommandon för att skriva ut orden "Introduktion" och "Slutsats" och deklarera och initialisera variabeln i är inte som andra repetitiva åtgärder. De exekveras endast en gång, vilket innebär att de måste skrivas utanför loopkroppen.

Alla tre stegen i lösningen bör finnas kvar i koden så att du kan hänvisa till dem senare vid problem. Det räcker med att kommentera de två första alternativen så att de inte stör.
Elevens uppmärksamhet bör uppmärksammas på följande fakta:
— I ett looptillstånd jämförs vanligtvis en räknare och en limit. Räknaren kan ändras i slingans kropp, men gränsen kan inte. För att bryta mot denna regel måste du formulera övertygande skäl.
— Kommandon för att visa orden "Introduktion" och "Slutsats" finns utanför slingans kropp. Vi måste utföra dem 1 gång. "Introduktion" - innan du upprepar åtgärderna, "Slutsats" - efter.
I processen att konsolidera det här ämnet, bemästra nästa, samt hantera svårigheter, är det användbart för även starka elever att ställa frågan: "Hur många gånger behöver den här åtgärden utföras? En eller många?

Utveckling av ytterligare kompetens

I processen att studera cykler utvecklar eleverna också färdigheten att diagnostisera och lösa problem. För att utföra diagnostik behöver eleven presentera det önskade resultatet och jämföra det med det faktiska resultatet. Korrigerande åtgärder beror på skillnaden mellan dem.
Eftersom eleverna i detta skede fortfarande har liten aning om det "önskade" resultatet, kan de fokusera på testdata. Som regel är det ingen som i detta skede ännu förstår vad som kan gå fel och hur man hanterar det. Därför skriver jag i en anteckningsbok en beskrivning av typiska problem och flera sätt att lösa dem. Att välja den lämpligaste är elevens uppgift.
En post behövs för att fråga "hände det som förväntades?", "Vilken av dessa situationer hände nu?", "Hjälpte den tillämpade lösningen?"

  1. Antalet åtgärder är 1 mindre eller fler än förväntat. Lösningar:
    — öka räknarens initiala värde med 1.
    — ersätt den strikta jämförelseoperatorn (< eller >) med en icke-strikt (<= eller >=).
    — ändra gränsvärdet till 1.
  2. Åtgärder i en loop utförs utan stopp, på obestämd tid. Lösningar:
    — lägg till ett räknarändringskommando om det saknas.
    — fixa räknarändringskommandot så att dess värde blir närmare gränsen.
    — ta bort kommandot för ändring av restriktioner om det finns i slingans kropp.
  3. Antalet åtgärder i en loop är mer än 1 mindre eller fler än förväntat. Åtgärden i loopen utfördes inte ens en gång. Först måste du ta reda på de faktiska värdena för variablerna precis innan loopen startar. Lösningar:
    — ändra startvärdet för begränsningen
    — ändra utgångsvärdet för räknaren

Problem 3 handlar vanligtvis om att använda fel variabel eller att inte nollställa räknaren.

Efter denna förklaring kan eleven fortfarande ha olika missuppfattningar om hur loopar fungerar.
För att skingra de vanligaste ger jag dig följande uppgifter:

  1. Där gränsen, initialt räknarvärde eller räknarsteget anges av användaren.
  2. I vilket räknarvärdet måste användas i något aritmetiskt uttryck. Det är lämpligt att använda en räknare i det radikala uttrycket eller i nämnaren så att skillnaden är olinjär.
  3. Där räknarvärdet inte visas på skärmen medan slingan körs. Till exempel att visa det nödvändiga antalet identiska textfragment eller rita en figur med sköldpaddsgrafik.
  4. Där du först måste utföra några repetitiva åtgärder och sedan andra.
  5. Där du måste utföra andra åtgärder före och efter upprepande

För varje uppgift måste du tillhandahålla testdata och det förväntade resultatet.

För att förstå hur snabbt du kan röra dig måste du läsa villkoren för dessa problem och fråga: "hur skiljer de sig från exemplet?", "Vad behöver ändras i exemplet för att lösa dem?" Om eleven svarar meningsfullt, låt honom då lösa minst en i klassen och resten hemma på egen hand. Om lösningen är framgångsrik kan vi börja förklara förhållandena inuti slingorna.
Om du har problem med att lösa problem på egen hand måste du arbeta igenom allt i klassen. För att undvika att lösa problemet påminner om att rita en uggla, rekommenderar jag att du först löser problemet på ett icke-universellt sätt. Det vill säga så att lösningen klarar det första testet och inte använder slingkonstruktionen. Tja, tillämpa sedan transformationer för att uppnå universalitet av lösningen.

Slingor och grenar

Enligt min mening är det användbart att ge ämnet "cykler inom grenar" separat. Så att du senare kan se skillnaden mellan att kontrollera ett tillstånd flera gånger och att kontrollera det en gång.
Uppgifterna för konsolidering kommer att handla om att mata ut nummer från A till B, som skrivs in av användaren:
- alltid i stigande ordning.
- stigande eller fallande beroende på värdena för A och B.

Ämnet "förgrening inom loopar" bör flyttas vidare först efter att studenten har behärskat teknikerna: "ersätta ett mönster med en variabel" och "ersätta repetitiva handlingar med en cykel."
Den främsta anledningen till att använda grenar inuti slingor är anomalier i mönstret. I mitten går det sönder beroende på initialdata.
För de elever som kan leta efter en lösning genom att kombinera enkla tekniker räcker det att säga "förgreningar kan skrivas inuti slingor" och ge problemet "till exempel" helt att lösa självständigt.
Exempel på uppgift:

Användaren anger talet X. Visa siffrorna från 0 till 9 i en kolumn och sätt ett '+'-tecken mittemot talet som är lika med X.

Om 0 angavs0+
1
2
3
4
5
6
7
8
9

Om 6 angavs0
1
2
3
4
5
6+
7
8
9

Om 9 angavs0
1
2
3
4
5
6
7
8
9+

Om 777 angavs0
1
2
3
4
5
6
7
8
9

Om en kort förklaring inte räcker för att skriva med en loop, måste du uppnå en universell lösning på samma problem utan en loop.
Du får ett av två alternativ:
Önskad

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

Möjlig

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

Jag ger en liknande uppgift i förväg medan jag studerar ämnet förgrening.
Om eleven kommer på ett "möjligt" alternativ måste du berätta för dem att det kan finnas många lösningar på samma problem. De skiljer sig dock åt i deras motstånd mot förändringar i krav. Ställ frågan: "Hur många platser i koden skulle behöva korrigeras om jag måste lägga till ytterligare ett nummer?" I den "möjliga" versionen måste du lägga till ytterligare en gren och lägga till ett nytt nummer på 10 andra platser. I den "önskade" räcker det att bara lägga till en gren.
Ställ in uppgiften att återskapa det "önskade" alternativet, hitta sedan ett mönster i koden, utför en variabelbyte och skriv en loop.
Om du har en idé om hur du löser detta problem utan en loop på något annat sätt, skriv gärna i kommentarerna.

Slingor inom slingor

I det här ämnet måste du vara uppmärksam på följande:
— Räknare för de inre och yttre slingorna måste vara olika variabler.
— Räknaren för den inre slingan måste återställas många gånger (det vill säga i den yttre slingans kropp).
— i textutmatningsuppgifter kan du inte först skriva en bokstav på flera rader och sedan den andra. Du måste först skriva ut alla bokstäverna i den första raden, sedan alla bokstäverna i den andra, och så vidare.

Det är bäst att börja förklara ämnet loopar inom loopar genom att förklara vikten av att nollställa räknaren.
Exempel på uppgift:

Användaren anger två siffror: R och T. Skriv ut två rader med "#" tecken. Den första raden ska innehålla R-tecken. Den andra raden innehåller T-stycken. Om någon siffra är negativ, visa ett felmeddelande.

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

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

R=-1, T=6R-värdet måste vara icke-negativt

R=6, T=-2T-värdet måste vara icke-negativt

Uppenbarligen har detta problem också åtminstone två lösningar.
Önskad

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

Möjligt #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;
}

Skillnaden är att i den "möjliga" lösningen användes en andra variabel för att mata ut den andra raden. Du bör insistera på att använda samma variabel för båda slingorna. Denna begränsning kan motiveras av det faktum att en lösning med en räknare under två cykler kommer att vara en illustration av termen "räknareåterställning". Det är nödvändigt att förstå denna term när du löser följande problem. Som en kompromiss kan du spara båda lösningarna på problemet.

Ett typiskt problem med att använda en räknarvariabel för två slingor ser ut så här:
R=5, T=11#####
######

Antalet tecken på den andra raden motsvarar inte värdet på T. Om du behöver hjälp med detta problem, måste du titta på anteckningarna om typiska problem med loopar. Detta är symptom #3. Det diagnostiseras om du lägger till ett räknarvärde direkt före den andra cykeln. Korrigerat genom återställning. Men det är bättre att inte berätta det här direkt. Eleven ska försöka formulera minst en hypotes.

Det finns naturligtvis en annan lösning. Men jag har aldrig sett det bland studenter. I stadiet av att studera cykler kommer historien om det att distrahera uppmärksamheten. Du kan komma tillbaka till det senare när du lär dig om strängfunktioner.
Möjligt #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));

Nästa obligatoriska uppgift:

Visa siffrorna från 0 till 9. Varje nummer ska stå på sin egen rad. Antalet siffror på en rad (W) skrivs in från tangentbordet.

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

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

Om en student har behärskat tekniken att ersätta en variabel, kommer han att klara sig ganska snabbt. Ett möjligt problem kommer återigen att vara att återställa variabeln. Om du inte kan hantera förvandlingen betyder det att du hade bråttom och behöver lösa enklare problem.

Tack för din uppmärksamhet. Gilla och prenumerera på kanalen.

PS Om du hittar stavfel eller fel i texten, vänligen meddela mig. Detta kan göras genom att markera en del av texten och trycka på "⌘ + Enter" på Mac och "Ctrl / Enter" på klassiska tangentbord, eller genom privata meddelanden. Om dessa alternativ inte är tillgängliga, skriv om fel i kommentarerna. Tack!

Endast registrerade användare kan delta i undersökningen. Logga in, Snälla du.

Enkät för läsare utan karma

  • 20,0%Jag undervisar professionellt, +12

  • 10,0%Jag undervisar professionellt, -11

  • 70,0%Jag undervisar inte, +17

  • 0,0%Jag undervisar inte, -10

  • 0,0%Övrigt0

10 användare röstade. 5 användare avstod från att rösta.

Källa: will.com

Lägg en kommentar