Kuigi teema on põhiline, on see artikkel suunatud kogenud spetsialistidele. Eesmärk on näidata, millised eksimused esinevad programmeerimise algajate seas. Praktiseerivatele arendajatele on need probleemid juba ammu lahendatud, unustatud või täiesti märkamatuks jäävad. Artikkel võib olla kasulik, kui teile tuleb kunagi kellelegi selle teema osas abi anda. Artiklis tehakse paralleele erinevate programmeerimisraamatute, autoriteks Shildt, Stroustrup ja Okulov, materjaliga.
Tsüklite teema on valitud, sest see jätab programmeerimise õppimise käigus paljusid inimesi välja.
See meetod on suunatud nõrkadele tudengitele. Põhiliselt ei jää tugevamad selles teemas kinni ning neile ei vaja erilisi meetodeid välja mõelda. Teine eesmärk on tõlkida see meetod klassist "toimib kõigi tudengite jaoks, kuid ainult ühe õpetaja juures" klassi "toimib kõigi tudengite ja kõigi õpetajate jaoks". Ma ei pretendeeri absoluutsele originaalsusele. Kui kasutate juba sarnast meetodit selle teema õpetamiseks, andke palun teada, kuidas teie variant erineb. Kui otsustate seda rakendada, jagage palun tulemusi. Kui mõni sarnane meetod on kajastatud mõnes raamatus, andke palun raamatu pealkiri.
Olen seda meetodit rakendanud nelja aasta jooksul, õpetades individuaalselt eri tasemel tudengeid. Kokku umbes viiskümmend tudengit ja kaks tuhat tundi tunde. Alguses jäid tudengid selle teema osas igaveseks kinni ja lahkusid. Pärast iga tudengit korrigeeriti meetodit ja materjale. Viimasel aastal ei jää tudengid enam selle teema külge kinni, nii et otsustasin oma teadmisi jagada.
Miks nii palju kirjutada? Tsüklid on ju elementaarsed!
Kuna ma olen juba varem maininud, et praktiseerivatele arendajatele ja tugevatele tudengitele võib tsüklite kontseptsiooni keerukus jääda alahinnatuks. Näiteks on võimalik korraldada pikka loengut, näha noogutavaid pead ja nutikaid silmi. Kuid kui proovida lahendada mõnda ülesannet, algab tardumus ja seletamatud probleemid. Pärast loengut on tudengite arusaam ainult osaline. Olukorda halvendab see, et tudengid ei suuda ise sõnastada, kus täpselt nende eksimus seisneb.
Kord märkasin, et tudengid tajuvad minu näiteid hieroglüüfidena. Ehk nagu jagamatuid tekstilõike, kuhu tuleb lisada mingi "maagiline" täht ja siis töötab.
Mõnikord märkasin, et tudengid arvavad, et konkreetse ülesande lahendamiseks on vajalik mõni teine konstruktsioon, millest ma lihtsalt veel ei ole rääkinud. Kuigi lahendamiseks piisab vaid näite väikestest muudatustest.
Seetõttu jõudsin ideeni, et peamine tähelepanu tuleks suunata mitte väljendite süntaksile, vaid korduva koodi refaktoreerimise ideele tsüklite abil. Niipea kui õpilased omandavad selle idee, tõmmatakse iga süntaks nende väikeste harjutuste kaudu lähemale.
Kellele ja miks ma õpetan
Kuna vastuvõtueksameid ei ole, võivad tundides olla nii tugevad kui ka väga nõrgad tudengid. Rohkem informatsiooni minu tudengite kohta on artiklis
Püüdlesin selle poole, et programmeerimist valdaksid kõik, kes seda soovivad.
Minu tunnid toimuvad individuaalselt ning tudeng maksab iga tunni eest. Tundub, et tudengid peaksid kulude optimeerimiseks nõudma minimaalset. Kuid inimesed käivad silmast silma loengutes elava õpetaja juures mitte teadmiste pärast, vaid selleks, et tunda kindlust, et nad on omandanud vajalikud oskused, kogeda edusamme ja saada heakskiitu eksperdilt (õpetajalt). Kui tudengid ei tunne oma õppimises edusamme, lahkuvad nad. Üldiselt on võimalik tunde üles ehitada nii, et tudengid tunneksid edusamme meie tuttavates konstruktides. Ehk kõigepealt uurime üksikasjalikult while tsüklit, siis uurime for tsüklit ja seejärel do while tsüklit, ja nüüd on meil kursus tuhandeks ja üheks öiseks, kus kahe kuu jooksul õpitakse ainult tsükleid ning tulemuseks on tudeng, kes dikteerimisega kirjutas standardraamatukogu. Kuid praktiliste probleemide lahendamiseks on vajalik mitte ainult materjali tundmaõppimine, vaid ka iseseisvus selle rakendamisel ja uue teabe otsimisel. Seega pean silmas, et silmast silma kursuste puhul on õige põhimõte - õpetada minimaalset ning julgustada iseseisvat süvenemist nüanssidesse ja samateemadesse. Tsüklite teemal olen minimaalseks pidanud while konstruktsiooni. Selle kaudu on võimalik mõista põhimõtet. Olles põhimõtte omandanud, suudab igaüks iseseisvalt valitseda nii for kui ka do-while.
Nõrkade õpilaste aine omandamine ei piirdu vaid süntaksi kirjeldamisega. On oluline pakkuda rohkem lihtsaid, kuid mitmekesiseid ülesandeid ning tuua näiteid põhjalikumalt. Lõppkokkuvõttes piirab omandamise kiirus õpilase võimet väljendeid ümber muuta ja mustreid leida. Nutikate õpilaste jaoks on enamik ülesandeid igavad. Nendega töötades ei pea 100% ülesannete lahendamist nõudma. Minu materjaliga saab tutvuda . Tõsi, see repot on pigem mustkunstniku grimuaari laadne — keegi peale minu ei mõista, mis kus asub, ja kui kontroll läbi kukub, võib hulluks minna.
Metoodika keskendub praktikale
Teooriat selgitatakse ülesande lahenduse näitel. Programmeerimise alaste tundide puhul, kus õpitakse harutusi ja tsükleid, ei ole võimalik ühe teema kohta tervet tundi kasulikku loengut korraldada. 15-20 minutit piisab, et mõistet tutvustada. Peamised raskused tekivad praktiliste ülesannete täitmisel.
Algajad õpetajad võivad esitada operaatorid, harutused, tsüklid ja massiivid ühe loengu jooksul. Kuid õpilased seisavad nende teadmiste omandamise probleemide ette.
Oluline on mitte ainult materjali tutvustada, vaid ka veenduda, et kuulajad on sellest aru saanud.
Teema omandamise tõendamiseks vaadatakse, kuidas õpilane iseseisva tööga toime tuleb.
Kui õpilasel õnnestub teema ülesanne lahendada ilma õpetaja abita, tähendab see, et teema on omandatud. Iseseisva kontrolli tagamiseks on igaühe ülesande juures tabel teststsenaariumidega. Ülesannete järjekord on selge. Ülesandeid ei ole soovitatav vahele jätta. Kui praegune ülesanne on liiga keeruline, on kasutu minna järgmisele. See on veel keerulisem. Et õpilane saaks praeguse keerulise ülesandega toime tulla, selgitatakse talle mõningaid tehnikaid esimese ülesande näitel. Tegelikult, kogu teema sisu koondub kuni probleemide ületamise tehnikateni. Tsüklid on pigem kõrvalnähtus.
Esimene ülesanne on alati näide. Teine erineb vaid veidi ja täidetakse "ise" kohe pärast esimest õpetaja järelevalve all. Kõik järgnevad ülesanded on suunatud erinevate detailide tähelepanu juhtimisele, mis võivad eksitusi tekitada.
Näite selgitamine on dialoog, kus õpilane peaks näitama tagasivoolu ja ristvalideerimist, et veenduda materjali omandamises.
Olgu ma banaalne ja väidan, et esimene näide teema kohta on väga oluline. Kui on olemas piisavalt materjali ulatuslikuks iseseisvaks tööks, siis võib esimest näidet puudutavad puudused parandada. Kui öelda, et midagi muud ei ole, siis tõenäoliselt ei omanda õpilane teemat.
While või for?
Üks vaieldav küsimus on konstruktsiooni valik näite jaoks: while või for. Ükskord veenis üks tuttav praktik, kellel ei olnud õpetamise kogemust, mind kogu tunni jooksul, et for tsükkel on kõige lihtsam arusaadav. Tema argumendid piirdusid väitega, et "kõik on selge ja kohad on paigas". Kuid tõeliste algajate raskuste põhjus peitub tsükli idees, mitte selle kirjutamises. Kui inimene ei mõista seda ideed, siis tal on raskusi süntaksiga. Kui idee on mõistetud, kaovad koodivormistamise probleemid iseenesest.
Minu materjalides järgneb tsüklite teema harutuste teemale. if ja while väline sarnasus võimaldab teha otsese analoogia: "kui tingimus pealkirjas on tõene, siis täidetakse keha". Tsükli eripära seisneb selles, et keha täidetakse mitu korda.
Teine minu argument on, et while nõuab vähem vormistamist kui for. Vähem vormistamist tähendab vähem rumalaid vigu puuduvate komade ja sulgudega. Algajatel ei ole veel piisavalt tähelepanelikkust ja põhjalikkust, et automaatselt vältida süntaktilisi vigu.
Kolmas argument on see, et paljudes heades raamatutes selgitatakse while esimesena.
Kui õpilasel õnnestub väljendeid kergesti ümber vormida, siis saab while kõrvale jätta. Õpilane valib hiljem, mis talle rohkem meeldib. Kui aga ümbervormimisega tekivad raskused, on parem tähelepanu mitte hajutada. Las õpilane lahendab alles kõik while abil. Kui tsüklite teema on omandatud, saab lahendusi ümber kirjutada, et harjutada while'i for'iks muutmist.
Tsüklid koos posttingimusega on üsna haruldased. Selle peale ma aega ei raiska. Kui õpilane on omandanud mustrite tuvastamise ja väljendite ümbervormimise ideed, siis suudab ta toime tulla ilma minu abita.
Esimese näite tutvustamisel tugevatele õpilastele rõhutan, et esimese näite puhul on oluline fikseerida mitte ainult lahendus, vaid ka kogu tegevuste ahel, mis viis tulemuse saavuttamiseni. Laiskadele õpilastele võib jääda mulje, et nad saavad ignoreerida kirjutamist ja jätta endale vaid lõpp-algoritmi. Neid tuleb veenda, et kunagi võib neile ette tulla keeruline ülesanne. Selle lahendamiseks tuleb järgida samme nagu selles näites. Just seepärast on oluline fikseerida kõik etapid. Järgmistes ülesannetes saab jätta vaid lõpliku lahenduse versiooni.
Automatiseerimise põhidee on seda, et usaldame arvutile igapäevase töö tegemise inimese eest. Üks põhilisi meetodeid on tsüklite kirjutamine. Seda kasutatakse siis, kui programmis kirjutatakse järjest mitu sama korduvat tegevust.
Selge on parem kui ebaselge
Esimene ülesanne tsüklite kohta võib tunduda hea ideena, kui ekraanile lõpuks väljastatakse sama fraas mitu korda. Näiteks:
Hurraa, see töötab!
Hurraa, see töötab!
Hurraa, see töötab!
Hurraa, see töötab!
Hurraa, see töötab!
Hurraa, see töötab!
Hurraa, see töötab!
Hurraa, see töötab!
Selline variant on halb, kuna väljundis ei ole nähtav loenduri väärtus. See on algajate jaoks probleem. Seda ei tohiks alahinnata. Alguses oli see ülesanne esimene ja ülesanne järjestikku suurenevate arvude väljastamiseks – teine. Vaja läks tutvustada täiendavaid termineid nagu 'tsükkel N korda' ja 'tsükkel A-st B-ni', mis tegelikult tähendavad sama. Et mitte luua liigseid mõisteid, otsustasin näidata ainult näidet numbrite järjestikuse väljastamise kohta. Harva suudavad inimesed ilma ettevalmistuseta hoida meeles loenduri ja modelleerida programmi käitumist enda peas. Mõned õpilased puutuvad esmakordselt kokku 'meeles modelleerimisega' just tsüklite teemal.
Pärast teatavat praktikat annan ülesande korduva teksti kirjutamiseks iseseisvaks lahendamiseks. Kui anda esmalt nähtav loendur ja seejärel nähtamatu, siis õpilastel on vähem probleeme. Mõnikord piisab vihjest 'ära kirjuta loendurit ekraanile'.
Kuidas selgitatakse teistes?
Enamik internetis olevaid õpikuid esitab tsükli süntaksi 'loengute' osana. Näiteks developer.mozilla.org veebilehel antakse koos while tsükliga teada ka mitmeid teisi konstruktsioone. Samal ajal antakse ainult konstruktsioonid šabloonidena. Nende käivitamise tulemus on sõnaliselt kirjeldatud, kuid illustreerimine puudub. Minu arvates selline teema esitlemine vähendab järsult selliste materjalide kasulikkust. Õpilane võib kopeerida koodi ning käivitada selle ise, kuid võrdlusstandard on ikka vajalik. Kuidas mõista, et näide on õigesti kopeeritud, kui tulemusega pole millestki võrrelda?
Kui antakse ainult šabloon, ilma näiteks, muutub õpilasel veelgi keerulisemaks. Kuidas mõista, et koodifragmendid on šabloonis õigesti paigutatud? Võib proovida kirjutada kuidagi, ja seejärel käivitada. Kuid kui ei ole võrreldavat standardit, ei aita ka käivitamine. kuidagi, ja siis käivitada. Aga kui ei ole võrdluspunkti, ei aita ka käivitamine.
C++ kursusel on tsükli süntaks peidetud neljanda loengu kolmandale lehele teemal 'operatsioonid'. Tsüklite süntaksi selgitamisel tehdakse erilist rõhku terminile 'operatsioon'. Termini esitusele antakse faktide kogum nagu 'sümbol; see on operatsioon', '{} on koosnevad operatsioonid' ja 'tsükli keha peab olema operatsioon'. Mulle ei meeldi selline lähenemine, kuna see justkui peidab olulisi seoseid ühe termini taha. Programmi lähtekoodi jagamine termideks sellisel tasemel on vajalik kompilatsioonide arendajatele, et teostada keele spetsifikatsiooni, kuid kindlasti mitte õpilastele esimeses etapis. Algajad programmist ei oska tavaliselt piisavalt täpselt terminitele tähelepanu pöörata. Harva keegi mäletab ja mõistab uusi sõnu esmakordselt. Peaaegu keegi ei suuda õigesti rakendada terminit, mille just õppis. Seetõttu tekib õpilastel hulk vigu, nagu näiteks 'kirjutasin while(a<7);{, ja programm ei tööta'.
Minu arvates on parem alguses anda konstruktsiooni süntaks kohe koos sulgudega. Variandi ilma sulgudeta selgitamine on sobiv ainult juhul, kui õpilasel tekib konkreetne küsimus 'miks siin on ilma sulgudeta ja see töötab'.
Okulovi raamatus "Programmeerimise alused" 2012. aastal algab tutvustus tsüklitega for šabloonidega, seejärel antakse soovitused selle kasutamiseks ja seejärel järgneb kohe eksperimentaalne osa loengust. Ma saan aru, et raamat kirjutati selle vähese arvu väga andekate õpilaste jaoks, kes harva tulevad minu tundidesse.
Populaarsetes raamatutes on alati antud koodifragmendi tulemused. Näiteks Shildti "Java 8. Täielik juhend" 2015. aasta väljaandest. Esiteks antakse šabloon, seejärel näidatakse programmi näidet ja kohe pärast seda – täitmise tulemus.
Näiteks vaatleme while-tsüklit, kus toimub tagasivaatamine alates 10 ja väljastatakse täpselt 10 rida "takte":
Pärast käivitamist väljastab see programm kümme "takti" järgmiselt://Продемонстрировать применение оператора цикла while class While { public static void main(String args []) { int n = 10; while (n > 0) { System.out.println("такт " + n); n--; } } }Selle programmi kirjeldamise lähenemisviisi kasutatakse ka raamatus "Javascript lastele" ja w3schools.com JS kursusel. Veebilehe formaat võimaldab isegi selle näite interaktiivseks muuta.
takt 10
takt 9
takt 8
takt 7
takt 6
takt 5
takt 4
takt 3
takt 2
takt 1
Stroustrupi raamatus "C++ põhimõtted ja praktika" (2016) läks autor veelgi kaugemale. Esiteks seletatakse, milline tulemus peaks olema, ja pärast seda näidatakse programmi teksti. Samuti võetakse näiteks mitte lihtsalt suvaline programm, vaid antakse ekskurs ajaloosse. See aitab tähelepanu juhtida: "Vaata, see ei ole lihtsalt mõttetu tekst. Sa näed midagi olulist."
Iteratsiooni näiteks vaatleme esimest programmi, mille kirjutas David Wheeler Cambridge'i ülikooli arvutlaboratooriumis 6. mail 1949. See programm arvutab ja printib lihtsa ruutude nimekirja.
Igas reas on number, millele järgneb tabulatsioonimärk ('t') ja selle numbri ruut. C++ keeles näeb selle programmi versioon välja selline:
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801
Huvitav on see, et selle raamatu sünteesimalli ei kirjeldada. Stroustrup rõhutab oma õpetajate juhendis, et austab oma õpilaste intelligentsust. Võib-olla peetakse oskust tuvastada malli mitmest näitest sellise intelligentsuse väljenduseks.//Вычисляем и распечатываем таблицу квадратов чисел 0-99 int main() { int i = 0; // Начинаем с нуля while(i < 100){ cout << i << 't' << square(i) << 'n'; ++i; } }
Kuidas ma ise selgitades lähenenStroustrupi lähenemine: tulemuse kirjeldamine, seejärel probleemi lahendamine, ja lõpuks iseseisev analüüs üliõpilaste poolt — tundub kõige läbimängitum. Seetõttu otsustasin võtta selle aluseks, kuid rääkida vähem ajaloolisest näitest — ülesandest "sisukorra" väljundiks. See loob tuntava ankurduse, et hiljem saaks öelda: "kasu ülesande osas sisukorrast" ja et üliõpilased mäletaksid just seda. Oma näites püüdsin ette tulema ka kahele kõige levinumale eksitusele. Hiljem räägin neist lähemalt.
Selle ülesande raames tutvume keerukate ülesannete lahendamise tehnikatega. Algne lahendus peab olema primitiivne ja lihtne. Seejärel võib mõelda, kuidas seda lahendust parandada.
Minu tähelepanekute kohaselt viib lähenemine "mall-näide-tulemus" eri kombinatsioonides ikka selleni, et üliõpilased näevad tsüklit kui hieroglüüfi. See väljendus selles, et nad ei mõistnud, miks sinna kirjutada tingimus, kuidas valida i++ ja i-- vahel ning muud, esmapilgul ilmselged asjad. Nende eksituste vältimiseks peaks tsüklite jutustamise lähenemine rõhutama korduvate tegevuste mõtet ja seejärel — nende vormistamist konstruktsiooni abil. Seetõttu enne tsükli süntaksi andmist tuleb probleem lahendada "otseselt". Primitiivne ülesanne sisukorra kohta näeb välja selline:
Console.WriteLine("Sissejuhatus"); Console.WriteLine("Pealkiri 1"); Console.WriteLine("Pealkiri 2"); Console.WriteLine("Pealkiri 3"); Console.WriteLine("Pealkiri 4"); Console.WriteLine("Pealkiri 5"); Console.WriteLine("Pealkiri 6"); Console.WriteLine("Pealkiri 7"); Console.WriteLine("Järeldus");
Sissejuhatus
Peatükk 1
Peatükk 2
Peatükk 3
Peatükk 4
Peatükk 5
Peatükk 6
Peatükk 7
Kokkuvõte
Kuidas seda saaks parandada?
Asendada ühtlased tegevused tsükliga.
Millised tegevused korduvad järjestikku muutumatult?
Selles fragmendis ei ole neid. Siiski on käskudest, mis väljastavad sõna "Pealkiri" koos numbriga, väga sarnased.
Seetõttu on järgmine etapp fragmentide erinevuse leidmine. Ainult selles ülesandes on kõik ilmselge, hiljem korduvad mitte üksikud käsud, vaid koodiblokid, mis koosnevad 5 või enamast reast. Otsida tuleb mitte ainult käskude loendist, vaid ka harukonstruktsioonidest või tsüklist.
Näites on käskude vaheline erinevus sõna "Pealkiri" järel oleva numbri osas.
Kui erinevus on leitud, tuleb mõista muutumise seaduspärasust. Kas erinev fragment on number? Kas see suureneb või väheneb pidevalt? Kuidas muutub numbri väärtus kahe käsku vahel, mis asuvad kõrvuti?
Näites suureneb nummer tagasõnade "Pealkiri" järel sammuga 1. Erinevus on leitud, seaduspärasus on tuvastatud. Nüüd saab erineva fragmendi asendada muutuja.
Sellise muutuja kuulutamine peab toimuma enne esimest korduvat fragmenti. Sellist muutuja nimetatakse tavaliselt I või j, või kuidagi laiemalt. Selle algne väärtus peab olema võrdne esimese mis tahes kuvatava väärtusega. Näites on esimene väärtus 1.
Milline algväärtus tuleb võtta numbriseeria "100, 101, 102, 103, 104, 105" kuvamiseks?
Selles seerias on esimene number 100.
Iga väljastamiskäsku järel tuleb seda muutuja väärtust suurendada 1 võrra. See ükstapuha on muutumise samm.
Selles reas on esimene number 100.
Iga väljundkäsku peab selle muutuja väärtust tõstma 1 võrra. See ühik on muutumise samm.
Milline samm on numbrises "100, 102, 104, 106"?
Selles järjestuses on samm 2.
Pärast erineva osa asendamist muutujaga näeb kood välja järgmine:
Console.WriteLine("Sissejuhatus");
int i;
i = 0;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Kokkuvõte");
Rakendades meetodit „mõista seaduspära muutujana“, saadakse koodis mitu järjestikku sama tegevust. Nüüd saab korduvaid tegevusi asendada tsükliga.
Probleemi lahendamise järjekord, kus tuleb kasutada tsükleid, koosneb järgmistest etappidest:
- Lahenda „otseselt” paljude eraldi käskudega
- Leia seaduspära
- Väljenda seaduspära muutujana
- Formuleeri tsüklina
Edasi tutvustatakse uusi termineid, et õpilane ei satuks olukorda „kõike mõistan, aga ei oska öelda“:
— loendaja — alati muutuja, mis on vajalik tsüklis samme jälgimiseks. Tavaline täisarv, mida võrreldakse piiranguga.
— loendaja samm — loendaja muutumise seaduspära kirjeldamine.
— piirang — number või muutuja, millega võrreldakse loendajat, et algoritm oleks piiratud. Loendaja väärtus muutub nii, et see läheneks piirangule.
— tsükli keha — käsu kogum, mis kordub. Kui öeldakse „käsk on kirjutatud tsükli sisse”, mõeldakse just tsükli keha.
— tsükli iteratsioon — tsükli keha korduv teostamine.
— tsükli tingimus — loogiline väljend, millest sõltub, kas tehakse veel üks iteratsioon. (Siin võib esineda segadust haru konstruktsioonidega)
Tuleb olla valmis, et esialgu kasutavad õpilased termineid valesti. See kehtib nii tugevate kui ka nõrkade puhul. Ühise keele loomine on terviklik kunst. Praegu kirjutan lühidalt: tuleb seada ülesanne „erista koodifragmendi <termin>” ja ise kasutada neid termineid vestluses õigesti.
Pärast tsükliga ümberkirjutamist jääb fragment:
Console.WriteLine("Sissejuhatus");
int i = 0;
while (i < 7) {
Console.WriteLine("Peatükk " + i);
i = i + 1;
}
Console.WriteLine("Kokkuvõte");Peamine vale arusaam
Üks levinud vale arusaam õpilaste seas on see, et nad sisestavad tsükli konstruktsiooni tegevusi, mida on vaja teha ainult üks kord. Näiteks nii:
;
int i = 0;
while (i < 7) {
Console.WriteLine("Sissejuhatus")
Console.WriteLine("Peatükk " + i);
i = i + 1;
Console.WriteLine("Kokkuvõte");
}
Õpilased satuvad pidevalt sellise probleemi ette, nii alguses kui ka keerukamate ülesannete juures.
Sel juhul on peamine vihje:
Kui palju kordi tuleb käsu kirjutamist korrata: üks kord või palju?
Käskude väljund sõnade „Sissejuhatus” ja „Kokkuvõte”, samuti muutuja i deklareerimine ja initsialiseerimine ei sarnane teiste korduvate tegevustega. Need teostatakse ainult ühe korra, seega tuleb need kirjutada tsükli kehast väljapoole.
Koodis peavad jääma kõik kolm lahendusetappi, et hiljem saaks neil rasketes olukordades viidata. Esimese kahe variandi piisab kommenteerimisest, et nad ei segaks.
Õpilaste tähelepanu tuleks juhtida järgmistele faktidele:
— Tsükli tingimustes võrreldakse tavaliselt loendajat ja piirangut. Loendaja võib tsükli kehas muutuda, piirang aga ei tohi. Selle reegli rikkumiseks peavad olema tõsised põhjused.
— Käskude väljund sõnade „Sissejuhatus” ja „Kokkuvõte” on tsükli kehas väljas. Me peame need tegema 1 kord. „Sissejuhatus” — enne tegevuste kordamist, „Kokkuvõte” — pärast.
Selle teema kinnistamise, järgmiste valdamise ja raskuste lahendamise käigus on isegi tugevatele õpilastele kasulik esitada küsimus: „Ja seda tegevust kui palju korda tuleb teha? Üks või palju?”.
Täiendavate oskuste arendamine
Tsüklite õppimise käigus treenivad õpilased ka diagnostika ja probleemide lahendamise oskusi. Diagnoosimiseks peab õpilane kujutama ette soovitud tulemust ja võrreldama seda tegeliku tulemusega. Neid erimeelsusi arvesse võttes sõltuvad muutused parandamisest.
Kuna õpilased ei kujuta selle etapi juures hästi ette „soovitud” tulemust, siis võivad nad orienteeruda testandmetele. Tüüpiliselt ei mõisteta sel hetkel veel, mis võib valesti minna ja kuidas sellega toime tulla. Seetõttu annan ma märkmete tegemiseks kirjelduse tüüpilistest probleemidest ja mõned lahendusviisid. Kõige sobivama valimine on õpilase enda ülesanne.
Salvestus on vajalik, et küsida: „Kas saime seda, mida ootasime?“, „Milline neist olukordadest nüüd kujunes?“, „Kas rakendatud lahendus aitas?“.
- Tegevuste arv on 1 vähem või rohkem, kui oodatud. Lahendusvõimalused:
— suurenda algse arvesti väärtust 1 võrra.
— asenda rangem võrdlusoperator (< või >) lõdvemaga (<= või >=).
— muuda piirväärtust 1 võrra. - Tsüklis teostatavad tegevused toimuvad pidevalt, lõputult. Lahendusvõimalused:
— lisa arvesti muutev käsk, kui see on puuduv.
— paranda arvesti muutev käsk nii, et selle väärtus liikuks piirväärtusele lähemale.
— eemalda arvesti muutev käsk, kui see on tsükli kehas. - Tsüklis teostatavate tegevuste arv on rohkem kui 1 vähem või rohkem, kui oodatud. Tsüklis ei teostatud ühtegi tegevust. Esiteks tuleks selgitada välja tegelikud muutuja väärtused tsükli alguses. Lahendusvõimalused:
— muuda piirväärtuse algne väärtus
— muuda arvesti algne väärtus
Tavaliselt on probleem 3 seotud vale muutuja kasutamise või arvesti nullimise puudumisega.
Pärast seda selgitust võivad üliõpilasel endiselt olla erinevad ekslikud arusaamad tsüklite toimimisest.
Levitamaks kõige levinumaid eksiarvamusi, esitan ülesanded:
- Kus piirväärtus, arvesti algne väärtus või arvesti samm sisestatakse kasutaja poolt.
- Kus arvesti väärtust tuleb kasutada mingis aritmeetilises avaldises. Soovitav on, et arvesti oleks seotud juurdumise või nimetajaga, et erinevus oleks mitte-lineaarne.
- Kus arvesti väärtust ei kuvata ekraanil tsükli töö ajal. Näiteks vajaliku arvu sama tekstijuppide väljund või joonistada kujund turtlegraafikaga.
- Kus tuleb esmalt teostada ühed korduvad tegevused ja seejärel teised.
- Kus tuleb teostada teisi tegevusi enne ja pärast korduvaid.
Iga ülesande puhul tuleb esitada testandmed ja oodatud tulemus.
Kuna aru saada, kui kiiresti liikuda, tuleb anda aega ülesannete tingimuste lugemiseks ja küsida: „Kuidas need erinevad näitest?“, „Mida tuleks näites muuta, et neid lahendada?“. Kui üliõpilane vastab mõtestatult, siis võib lasta tal lahendada vähemalt ühe tunni jooksul, ülejäänud aga iseseisvalt kodus. Kui lahendus osutub edukaks, siis võib alustada selgitust tsüklite sees olevate tingimuste kohta.
Kui iseseisva lahendusega on probleeme, tuleb kõik läbi töötada tunnis. Et ülesande lahendamine ei meenutaks öökulli joonistamist, soovitan esmalt lahendada ülesanne mitteüldiselt. See tähendab, et lahendus peab läbima esimese testi ja mitte kasutama tsükli konstruktsiooni. Ainult siis rakendada teisendusi, et saavutada lahenduse universaalsus.
Tsüklid ja harud
Minu arvates on kasulik anda teema „tsüklid harudest“ eraldi. Nii on hiljem näha erinevus korduva tingimuse kontrollimise ja ühekordse kontrollimise vahel.
Harjutused kinnitamiseks, mis käsitlevad numbrite väljundit A-st B-sse, mis sisestatakse kasutaja poolt:
— alati kasvavas järjekorras.
— kasvavas või kahanevas järjekorras sõltuvalt A ja B väärtustest.
Teemaga „harud tsüklites“ tuleks liikuda ainult pärast seda, kui üliõpilane on omandanud tehnikad: „muster muutuja asemel“ ja „korduvaid tegevusi asendada tsükliga“.
Peamine põhjus harude rakendamiseks tsüklites on ebanormaalsused mustrites. Keskel on see rikkunud sõltuvalt sisendandmetest.
Nendele üliõpilastele, kes suudavad lahendust otsida, kombineerides lihtsaid tehnikasid, piisab, kui öelda „harusid saab kirjutada tsüklite sisse” ja anda ülesanne „näitena” täielikult iseseisva lahendusena.
Näidisülesanne:
Kasutaja sisestab arvu X. Kuvada veerus numbreid 0–9 ja asetada märk ‘+’ selle numbri juurde, mis võrdub X-iga.
Kui sisestatud oli 00+
1
2
3
4
5
6
7
8
9
Kui sisestatud oli 60
1
2
3
4
5
6+
7
8
9
Kui sisestatud oli 90
1
2
3
4
5
6
7
8
9+
Kui sisestatud oli 7770
1
2
3
4
5
6
7
8
9
Kui lühike selgitus ei piisa, et kirjutada tsükliga, siis tuleb saavutada universaalne lahendus selle sama ülesande jaoks ilma tsüklita.
Saab üks kahest variandist:
Soovitud
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);
}
Võimalik
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+");
}
Sarnast ülesannet annan ma ette juba teema õppimise ajal, mis käsitleb haru.
Kui üliõpilasel on „võimalik“ variant, tuleks rääkida, et sama ülesande jaoks võib olla mitmeid lahendusi. Need erinevad aga nõudmiste muutustele vastupidavuse poolest. Küsige: „Kui palju kohti koodis tuleb muuta, kui tuleb lisada veel üks number?“ „Võimalikus“ variandis tuleb lisada veel üks haru ja kirjutada 10 teises kohas uus number. „Soovitavas“ piisab ainult ühe haru lisamisest.
Seadke eesmärk luua „soovitav“ variant, seejärel leida koodis mustreid, asendada muutuja ja kirjutada tsükkel.
Kui teil on idee, kuidas selle ülesande lahendamiseks tsüklit mitte kasutada, kirjutage palun kommentaaridesse.
Tsüklid tsüklites
Selles teemas tuleks tähelepanu pöörata sellele, et:
— sise- ja välistsükli loendurid peaksid olema erinevad muutujad.
— sise-tsükli loendur tuleb palju kordi nullida (st välis-tsükli kehas).
Teksti väljastamise ülesannetes ei saa kõigepealt kirjutada ühte tähte mitmesse ritta, seejärel teist. Esiteks tuleb välja anda kõik esimese rea tähed, seejärel kõik teise rea tähed ja nii edasi.
Tsüklite siseskeemide selgitamine on parim alustada loenduri nullimise olulisuse selgitamisega.
Näidisülesanne:
Kasutaja sisestab kaks arvu: R ja T. Väljasta kaks sümbolite rida "#". Esimeses reas peab olema R tükki sümbolit. Teises reas T tükki. Kui mõni number on negatiivne, väljasta veateade.
R=5, T=11#####
###########
R=20, T=3####################
###
R=-1, T=6R väärtus peab olema mitte-negatiivne
R=6, T=-2T väärtus peab olema mitte-negatiivne
On ilmne, et sellel ülesandel on vähemalt kaks erinevat lahendust.
Soovitud
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;
}
Võimalik 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;
}
Erinevus seisneb selles, et „võimalikus“ lahenduses teise rea väljastamiseks kasutati teist muutujat. Tuleks rõhutada, et sama muutuja kasutamine kahe tsükli jaoks. Sellist piirangut saab põhjendada sellega, et ühe loenduri lahendus kahes tsüklis oleks näide „loenduri nullimisest“. Selle termini mõistmine on tähtis järgmiste ülesannete lahendamisel. Kompromissina võib säilitada mõlemad ülesande lahendused.
Tüüpiline probleem ühe loenduri kasutamisel kahe tsükli jaoks avaldub nii:
R=5, T=11#####
######
Teise rea sümbolite arv ei vasta T väärtusele. Kui selle probleemiga on abi vaja, peab „nina ninna“ suunama tsükli tüüpiliste probleemide märkmed. See on sümptom nr 3. Seda diagnoositakse, kui lisada loenduri väärtuse väljund otse enne teist tsüklit. Probleem lahendatakse nullimisega. Kuid sellest ei tasu kohe rääkida. Üliõpilane peaks püüdma formuleerida vähemalt ühe hüpoteesi.
Muidugi on olemas ka selline lahenduse variant. Kuid ma ei ole seda üliõpilastelt kunagi näinud. Tsüklite õppimise etapil selle rääkimine hajutab tähelepanu. Saame sellele tagasi pöörduda hiljem, kui uurime stringide tööfunktsioone.
Võimalik 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));
Järgmine kohustuslik ülesanne:
Väljasta ekraanile numbrid 0 kuni 9. Iga number peab olema oma reas. Reas olevate numbrite arv (W) sisestatakse klaviatuurilt.
W=10
1
2
3
4
5
6
7
8
9
W=100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
Kui üliõpilane on omandanud muutuja asendamise tehnika, siis suudab ta sellega üsna kiiresti hakkama saada. Võimalik probleem võib taas olla muutuja nullimine. Kui muundamisega ei õnnestu hakkama saada, tähendab see, et olete liiga kiirem ja peaksite lahendama lihtsamaid ülesandeid.
Aitäh tähelepanu eest. PangeLike, tellige kanal.
P.S. Kui leiate tekstis trükivigu või vigu, palun andke mulle teada. Seda saab teha, kui valite osa tekstist ja vajutate Macis «⌘ + Enter» ja klassikalistel klaviatuuridel «Ctrl / Enter», või saates isiklikke sõnumeid. Kui need valikud pole saadaval, kirjutage vigadest kommentaarides. Aitäh!
Ainult registreeritud kasutajad saavad küsitluses osaleda. , palun.
Lugemise küsitlus ilma karmita
20,0%Õpetan professionaalselt, +12
10,0%Õpetan professionaalselt, -11
70,0%Ei õpeta, +17
0,0%Ei õpeta, -10
0,0%Muu0
Hääletanud 10 kasutajat. Ükski kasutaja ei hoidunud.
Allikas: habr.com
