Come insegnare a superare le difficoltà e allo stesso tempo scrivere cicli

Nonostante parleremo di uno degli argomenti di base, questo articolo è scritto per professionisti esperti. L'obiettivo è mostrare quali idee sbagliate hanno i principianti nella programmazione. Per gli sviluppatori praticanti, questi problemi sono stati a lungo risolti, dimenticati o non notati affatto. L'articolo potrebbe tornare utile se improvvisamente hai bisogno di aiutare qualcuno con questo argomento. L'articolo traccia paralleli con materiale tratto da vari libri sulla programmazione di Schildt, Stroustrup, Okulov.

L'argomento dei cicli è stato scelto perché molte persone ne sono escluse quando padroneggiano la programmazione.

Questa tecnica è progettata per gli studenti deboli. Di norma, le persone forti non si bloccano su questo argomento e non è necessario inventare tecniche speciali per loro. L'obiettivo secondario dell'articolo è spostare questa tecnica dalla classe "funziona per tutti gli studenti, ma solo un insegnante" alla classe "funziona per tutti gli studenti, tutti gli insegnanti". Non rivendico l'originalità assoluta. Se stai già utilizzando una metodologia simile per insegnare questo argomento, scrivi in ​​cosa differisce la tua versione. Se decidi di utilizzarlo, raccontaci come è andata. Se una tecnica simile è descritta in un libro, scrivi il nome.


Ho lavorato su questa tecnica per 4 anni, studiandola individualmente con studenti di diversi livelli di formazione. In totale ci sono una cinquantina di studenti e duemila ore di lezione. All'inizio, gli studenti rimanevano sempre bloccati su questo argomento e se ne andavano. Dopo ogni studente, la metodologia e i materiali sono stati adattati. Nell'ultimo anno, gli studenti non sono più rimasti bloccati su questo argomento, quindi ho deciso di condividere le mie scoperte.

Perché così tante lettere? I cicli sono così elementari!

Come ho scritto sopra, per gli sviluppatori praticanti e per gli studenti bravi, la complessità del concetto di loop può essere sottovalutata. Ad esempio, puoi tenere una lunga conferenza, vedere teste che annuiscono e occhi intelligenti. Ma quando si cerca di risolvere qualsiasi problema, iniziano lo stupore e i problemi inspiegabili. Dopo la lezione gli studenti probabilmente avevano solo una comprensione parziale. La situazione è aggravata dal fatto che gli studenti stessi non possono esprimere quale sia esattamente la loro delusione.
Un giorno mi sono reso conto che gli studenti percepivano i miei esempi come geroglifici. Cioè come pezzi di testo indivisibili in cui è necessario aggiungere qualche lettera “magica” e funzionerà.
A volte ho notato che gli studenti pensano che sia necessario risolvere un problema specifico qualcos'altro un design di cui non ho ancora parlato. Sebbene la soluzione richiedesse solo una leggera modifica dell'esempio.

Quindi mi è venuta l'idea che l'attenzione non dovrebbe essere posta sulla sintassi delle espressioni, ma sull'idea di refactoring del codice ripetitivo utilizzando i loop. Una volta che gli studenti hanno padroneggiato questa idea, qualsiasi sintassi può essere migliorata con poca pratica.

Chi e perché insegno?

Poiché non sono previsti esami di ammissione, le classi possono includere sia studenti forti che studenti molto deboli. Puoi leggere di più sui miei studenti nell'articolo Ritratto degli studenti del corso serale
Ho cercato di garantire che tutti coloro che vogliono imparare a programmare possano impararlo.
Le mie lezioni si svolgono individualmente e lo studente paga di tasca propria per ciascuna. Sembrerebbe che gli studenti ottimizzeranno i costi e richiederanno il minimo. Tuttavia, le persone frequentano lezioni in presenza con un insegnante dal vivo non per la conoscenza in sé, ma per la fiducia in ciò che hanno imparato, per una sensazione di progresso e per l'approvazione dell'esperto (insegnante). Se gli studenti non avvertono progressi nel loro apprendimento, se ne andranno. In generale, le lezioni possono essere strutturate in modo che gli studenti avvertano progressi nell'aumentare il numero di strutture familiari. Cioè, prima studiamo in dettaglio, poi studiamo per, poi facciamo mentre, e ora abbiamo pronto un corso da mille e una notte, in cui solo i cicli vengono studiati per due mesi, e alla fine - uno studente che ha scritto una libreria standard sotto dettatura. Tuttavia, per risolvere problemi pratici, è necessaria non solo la conoscenza del materiale, ma anche l'indipendenza nella sua applicazione e nella ricerca di nuove informazioni. Pertanto, per i corsi in presenza, penso che il principio corretto sia insegnare il minimo e incoraggiare lo studio indipendente delle sfumature e degli argomenti correlati. Nell'argomento dei cicli, considero il costrutto while il minimo. Da ciò puoi capire il principio. Conoscendo il principio, puoi padroneggiarli sia per che per farlo da solo.

Per ottenere la padronanza del materiale da parte degli studenti deboli, descrivere la sintassi non è sufficiente. È necessario fornire compiti più semplici ma vari e descrivere gli esempi in modo più dettagliato. In definitiva, la velocità di sviluppo è limitata dalla capacità dello studente di trasformare le espressioni e cercare modelli. Per gli studenti intelligenti, la maggior parte dei compiti sarà noiosa. Quando studi con loro, non devi insistere per risolvere il 100% dei problemi. Il mio materiale può essere visualizzato su il mio github. È vero, il deposito è più simile al grimorio di uno stregone: nessuno tranne me capirà cosa si trova e dove, se fallisci il controllo, puoi impazzire

La metodologia è orientata alla pratica

La teoria viene spiegata utilizzando l'esempio della risoluzione di un problema. In un corso sui fondamenti della programmazione in cui vengono insegnati rami e cicli, semplicemente non è possibile tenere una lezione utile su un argomento per un'ora intera. 15-20 minuti sono sufficienti per spiegare il concetto. Le principali difficoltà sorgono quando si eseguono compiti pratici.
Gli insegnanti principianti possono snocciolare operatori, rami, cicli e array in una lezione. Ma i loro studenti dovranno affrontare il problema di assimilare queste informazioni.
È necessario non solo raccontare il materiale, ma anche assicurarsi che gli ascoltatori lo capiscano.

Il fatto di padroneggiare un argomento è determinato dal modo in cui lo studente affronta il lavoro indipendente.
Se uno studente è riuscito a risolvere un problema su un argomento senza l'aiuto di un insegnante, l'argomento è stato padroneggiato. Per garantire l'autotest, ogni attività è descritta in una tabella con scenari di test. I compiti hanno un ordine chiaro. Non è consigliabile saltare le attività. Se il compito attuale è troppo difficile, passare a quello successivo è inutile. È ancora più complicato. Affinché lo studente possa padroneggiare l'attuale compito complesso, gli vengono spiegate diverse tecniche utilizzando l'esempio del primo problema. In realtà, l'intero contenuto dell'argomento si riduce alle tecniche per superare le difficoltà. I cicli sono più un effetto collaterale.

Il primo compito è sempre un esempio. La seconda differisce leggermente e viene eseguita “indipendentemente” subito dopo la prima sotto la supervisione di un insegnante. Tutti i compiti successivi mirano a prestare attenzione a varie piccole cose che possono causare idee sbagliate.

La spiegazione dell'esempio è un dialogo in cui lo studente deve richiamare la propagazione e la convalida incrociata per assicurarsi di aver padroneggiato una parte del materiale.

Sarò banale e dirò che il primo esempio sull'argomento è molto importante. Se si dispone del materiale per un ampio lavoro indipendente, le omissioni del primo esempio possono essere corrette. Se non c'è nient'altro oltre all'esempio, molto probabilmente lo studente non padroneggerà l'argomento.

Mentre o per?

Una delle questioni controverse è la scelta della costruzione dell'esempio: while o for. Una volta, un mio amico sviluppatore praticante senza esperienza di insegnamento ha passato un'ora a convincermi che il ciclo for era il più facile da capire. Le argomentazioni si riducevano a “tutto in esso è chiaro e disposto al suo posto”. Tuttavia, la causa principale delle difficoltà per i veri principianti è l'idea del ciclo stesso e non la sua scrittura. Se una persona non capisce questa idea, avrà difficoltà con la sintassi. Non appena l'idea viene realizzata, i problemi di progettazione del codice scompaiono da soli.

Nei miei materiali, il tema dei loop segue il tema della ramificazione. La somiglianza esterna di if e while ci consente di tracciare un'analogia diretta: "quando la condizione nell'intestazione è vera, il corpo viene eseguito". L'unica particolarità del ciclo è che il corpo viene eseguito molte volte.

La mia seconda argomentazione è che while richiede meno formattazione rispetto a for. Meno formattazione significa meno errori stupidi con virgole e parentesi mancanti. I principianti non hanno ancora sviluppato sufficiente attenzione e meticolosità per evitare automaticamente errori di sintassi.
Il terzo argomento è spiegato in molti buoni libri come primo argomento.

Se lo studente può facilmente trasformare le espressioni, allora puoi parlarne di sfuggita. Lo studente sceglierà poi ciò che gli piace di più. Se le trasformazioni causano difficoltà, è meglio non distrarre la tua attenzione. Lascia che lo studente risolva prima tutto usando while. Una volta che hai imparato l'argomento dei loop, puoi riscrivere le soluzioni per esercitarti nella conversione da while a for.
I loop postcondizioni sono una bestia piuttosto rara. Non ci dedico assolutamente tempo. Se uno studente ha acquisito padronanza delle idee relative all'identificazione di modelli e alla trasformazione delle espressioni, può capirlo senza il mio aiuto.

Nel dimostrare il primo esempio agli studenti forti, attiro l'attenzione sul fatto che nel primo esempio è importante registrare non solo la soluzione, ma anche l'intera catena di azioni che hanno portato al risultato. Gli studenti pigri possono trascurare la scrittura e copiare solo l'algoritmo finale. Hanno bisogno di essere convinti che un giorno si presenterà loro un compito difficile. Per risolverlo, dovrai seguire i passaggi come in questo esempio. Ecco perché è importante registrare tutte le fasi. Nei problemi successivi sarà possibile lasciare solo la versione finale della soluzione.

L'idea principale dell'automazione è che affidiamo a un computer il compito di svolgere il lavoro di routine per una persona. Una delle tecniche di base è scrivere loop. Viene utilizzato quando in un programma vengono scritte più azioni ripetute identiche di seguito.

L'esplicito è meglio dell'implicito

Potrebbe sembrare una buona idea visualizzare la stessa frase più volte nella prima attività in loop. Per esempio:

Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!

Questa opzione non è valida perché il valore del contatore non è visibile nell'output. Questo è un problema per i principianti. Non sottovalutarla. Inizialmente, questo compito era il primo e il compito di derivare una serie di numeri in ordine crescente era il secondo. È stato necessario introdurre i termini aggiuntivi “ciclo N volte” e “ciclo da A a B”, che sostanzialmente sono la stessa cosa. Per non creare entità inutili ho deciso di mostrare solo un esempio con l'output di una serie di numeri. Poche persone riescono a imparare a tenere in testa un contatore e a modellare il comportamento di un programma nella loro testa senza preparazione. Alcuni studenti incontrano per la prima volta la modellazione mentale sul tema dei cicli.
Dopo un po' di pratica, dò il compito di ripetere lo stesso testo da risolvere in autonomia. Se si dà prima un contatore visibile e poi uno invisibile, gli studenti avranno meno problemi. A volte è sufficiente il suggerimento “non scrivere il contatore sullo schermo”.

Come lo spiegano gli altri?

Nella maggior parte dei materiali didattici su Internet, la sintassi del ciclo viene fornita come parte di una "lezione". Ad esempio, su Developer.mozilla.org (attualmente), vengono descritti molti altri costrutti insieme al ciclo while. In questo caso vengono forniti solo i disegni sotto forma di modelli. Il risultato del loro lancio è descritto a parole, ma non ci sono illustrazioni. A mio avviso, una tale presentazione dell'argomento moltiplica per zero l'utilità di tali materiali. Lo studente può riscrivere il codice ed eseguirlo da solo, ma ha comunque bisogno di uno standard per il confronto. Come puoi capire che un esempio è stato riscritto correttamente se non c'è nulla con cui confrontare il risultato?
Quando viene fornito solo un modello, senza un esempio, diventa ancora più difficile per lo studente. Come capire che i frammenti di codice sono posizionati correttamente nel modello? Puoi provare a scrivere in qualche modo, e poi corri. Ma se non esiste uno standard per confrontare il risultato, anche il lancio non aiuterà.

Nel corso C++ su Intuitivo, la sintassi del ciclo è sepolta nella terza pagina della Lezione 4 sull'argomento “operatori”. Quando si spiega la sintassi dei loop, viene posta particolare enfasi sul termine “operatore”. Il termine si presenta come un insieme di fatti come “simbolo; questa è un'istruzione", "{} è un'istruzione composta", "il corpo del ciclo deve essere un'istruzione". Non mi piace questo approccio perché sembra nascondere relazioni importanti dietro un termine. L'analisi del codice sorgente di un programma in termini a questo livello è necessaria agli sviluppatori del compilatore per implementare la specifica del linguaggio, ma non agli studenti in prima approssimazione. I nuovi arrivati ​​​​alla programmazione raramente sono abbastanza meticolosi da prestare tanta attenzione ai termini. È raro che una persona ricordi e comprenda nuove parole la prima volta. Quasi nessuno riesce ad applicare correttamente un termine che ha appena imparato. Pertanto, gli studenti ricevono molti errori come "Ho scritto while(a<7);{, ma il programma non funziona".
Secondo me all'inizio è meglio dare subito la sintassi della costruzione tra parentesi. L’opzione senza parentesi va spiegata solo se lo studente ha una domanda specifica: “perché non ci sono parentesi e funziona?”

Nel libro di Okulov del 2012 “Fundamentals of Programming”, un’introduzione ai cicli inizia con il pattern for, poi fornisce consigli per il suo utilizzo e poi passa immediatamente alla sezione sperimentale della lezione. Capisco che il libro è stato scritto per quella minoranza di studenti molto capaci che raramente vengono alle mie lezioni.

Nei libri popolari, il risultato dei frammenti di codice è sempre scritto. Ad esempio, l’edizione 8 di “Java 2015. The Complete Guide” di Shildt. Innanzitutto viene fornito un modello, quindi un programma di esempio e subito dopo il risultato dell'esecuzione.

Ad esempio, considera un ciclo while che fa il contrario
conto alla rovescia a partire da 10, e vengono visualizzate esattamente 10 righe di “misure”:

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

Una volta eseguito, questo programma genera dieci "cicli" come segue:
такт 10
такт 9
такт 8
такт 7
такт 6
такт 5
такт 4
такт 3
такт 2
такт 1

L'approccio di descrivere un template, un programma di esempio e il risultato del programma è utilizzato anche nel libro “Javascript for Kids” e nel corso js su w3schools.com. Il formato della pagina web consente anche a questo esempio di essere interattivo.

Il libro di Stroustrup del 2016 Principles and Practice Using C++ è andato ancora oltre. Il primo passo è spiegare quale risultato si dovrebbe ottenere, dopodiché viene mostrato il testo del programma. Inoltre, non prendono solo un programma casuale come esempio, ma offrono un'escursione nella storia. Questo aiuta ad attirare l'attenzione: “Guarda, questo non è solo un testo inutile. Vedi qualcosa di significativo."

Come esempio di iterazione, si consideri il primo programma eseguito su una macchina a programma memorizzato (EDSAC). È stato scritto da David Wheeler al Computer Laboratory dell'Università di Cambridge, in Inghilterra, il 6 maggio 1949. Questo programma calcola e stampa un semplice elenco di quadrati.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801

Qui, ogni riga contiene un numero seguito da un carattere di tabulazione ('t') e dal quadrato di quel numero. La versione C++ di questo programma è simile alla seguente:

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

È interessante notare che il modello di sintassi non è descritto in questo libro. Stroustrup nel manuale dell'istruttore (traduzione) sottolinea che essa rispetta l'intelligenza dei suoi studenti. Forse la capacità di identificare uno schema in diversi esempi è considerata una manifestazione di tale intelligenza.

Come mi spiego

L'approccio di Stroustrup: descrivere il risultato, quindi risolvere il problema e quindi un'analisi indipendente da parte dello studente - sembra il più ponderato. Pertanto, ho deciso di prenderlo come base, ma di raccontarlo utilizzando un esempio meno storico: il compito di ricavare un "indice". Forma un'ancora riconoscibile in modo che tu possa poi dire "ricorda il compito relativo al sommario" e in modo che gli studenti ricordino esattamente questo. Nel mio esempio, ho cercato di prevenire altri due malintesi più comuni. Successivamente scriverò su di loro in modo più dettagliato.

In questo compito vengono introdotte le tecniche per risolvere problemi complessi. La decisione iniziale deve essere resa primitiva e semplice. Bene, allora puoi pensare a come migliorare questa soluzione.
Введение
Глава 1
Глава 2
Глава 3
Глава 4
Глава 5
Глава 6
Глава 7
Заключение

Secondo le mie osservazioni, l'approccio "modello-esempio-risultato" in varie combinazioni porta ancora al fatto che gli studenti percepiscono il ciclo come un geroglifico. Ciò si manifestava nel fatto che non capivano perché ci fosse una condizione per scrivere lì, come scegliere tra i++ e i— e altre cose apparentemente ovvie. Per evitare questi malintesi, l’approccio al parlare di cicli dovrebbe enfatizzare il significato di ripetere azioni identiche e solo successivamente formalizzarle utilizzando una struttura. Pertanto, prima di fornire la sintassi del loop, è necessario risolvere il problema frontalmente. Una soluzione primitiva al problema del sommario è simile alla seguente:

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("Заключение");

Come può essere migliorato?
Sostituisci le azioni monotone con un ciclo.
Quali azioni vengono ripetute di seguito senza modifiche?
Non ce ne sono in questo frammento. Tuttavia i comandi per visualizzare la parola “Capitolo” con un numero sono molto simili tra loro.
Pertanto, la fase successiva è trovare la differenza tra i frammenti. È solo in questo compito che tutto è ovvio, quindi non verranno ripetuti singoli comandi, ma blocchi di codice di 5 o più righe. Dovrai cercare non solo nell'elenco dei comandi, ma anche nelle ramificazioni o nelle costruzioni di loop.
Nell'esempio la differenza tra i comandi sta nel numero dopo la parola “Capitolo”.
Una volta individuata la differenza, è necessario comprendere il modello di cambiamento. Il frammento diverso è il numero? Aumenta o diminuisce costantemente? Come cambia il valore di un numero tra due squadre affiancate?
Nell'esempio, il numero dopo la parola “Capitolo” aumenta con incrementi di 1. La differenza viene trovata, lo schema viene rivelato. Ora puoi sostituire il frammento diverso con una variabile.
È necessario dichiarare tale variabile prima del primo dei frammenti ripetuti. Tale variabile è solitamente chiamata I o j o qualcosa di più dettagliato. Il suo valore iniziale deve essere uguale al primo valore visualizzato sullo schermo. Nell'esempio, il primo valore è 1.
Quale valore iniziale dovrebbe essere preso per visualizzare la serie di numeri “100, 101, 102, 103, 104, 105”?
Il primo numero di questa serie è 100.
Dopo ogni comando di output, è necessario aumentare il valore di questa variabile di 1. Questa unità è il passo di modifica.
Quale passo sarà nella serie di numeri “100, 102, 104, 106”?
Passaggio 2 in questa riga.
Dopo aver sostituito il frammento diverso con una variabile, il codice sarà simile a questo:

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("Заключение");

Dopo aver applicato la tecnica “esprimi il modello di una variabile” nel codice, ottieni diversi gruppi di azioni identiche che vanno in fila. Ora le azioni ripetute possono essere sostituite con un ciclo.

La sequenza per risolvere un problema in cui è necessario utilizzare i loop consiste nei seguenti passaggi:

  1. Risolvi "frontalmente" con molti comandi separati
  2. Trova uno schema
  3. Esprimere lo schema di una variabile
  4. Il design come ciclo

Successivamente vengono introdotti nuovi termini in modo che lo studente non si trovi nella situazione di “capisco tutto, ma non posso dirlo”:
— un contatore è sempre una variabile necessaria per tenere traccia del numero di passaggi in un ciclo. In genere un numero intero confrontato con il vincolo.
— controfase — descrizione dello schema delle contromodifiche.
- vincolo: un numero o una variabile con cui viene confrontato il contatore in modo che l'algoritmo sia definitivo. Il valore del contatore cambia per avvicinarsi al limite.
— corpo del loop — una serie di comandi che verranno ripetuti. Quando dicono "il comando è scritto all'interno di un loop", intendono il corpo.
— iterazione del ciclo — esecuzione una tantum del corpo del ciclo.
— condizione del ciclo — un'espressione logica che determina se verrà eseguita un'altra iterazione. (Potrebbe esserci confusione con le strutture ramificate qui)
Devi essere preparato al fatto che all'inizio gli studenti utilizzeranno i termini per altri scopi. Questo vale sia per i forti che per i deboli. Stabilire un linguaggio comune è un’arte. Ora scriverò brevemente: devi impostare l'attività "evidenzia il frammento di codice con <term>" e usa questi termini correttamente nella conversazione.
Dopo la trasformazione con un loop si ottiene il frammento:

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

Il principale malinteso

Un malinteso diffuso tra gli studenti è che inseriscano azioni all’interno di un ciclo che devono essere eseguite una sola volta. Ad esempio in questo modo:

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

Gli studenti incontrano continuamente questo problema, sia all'inizio che in problemi più complessi.
Suggerimento chiave in questo caso:

Quante volte dovresti ripetere il comando: una o più volte?

I comandi per stampare le parole "Introduzione" e "Conclusione" e per dichiarare e inizializzare la variabile i non sono come le altre azioni ripetitive. Vengono eseguiti una sola volta, il che significa che devono essere scritti all'esterno del corpo del ciclo.

Tutte e tre le fasi della soluzione dovrebbero rimanere nel codice in modo da potervi fare riferimento in seguito in caso di difficoltà. È sufficiente commentare le prime due opzioni in modo che non interferiscano.
L'attenzione dello studente dovrebbe essere attirata sui seguenti fatti:
— In una condizione di loop, solitamente vengono confrontati un contatore e un limite. Il contatore può cambiare nel corpo del ciclo, ma il limite no. Per infrangere questa regola, è necessario formulare ragioni convincenti.
— I comandi per visualizzare le parole “Introduzione” e “Conclusione” si trovano all'esterno del corpo del ciclo. Dobbiamo eseguirli 1 volta. "Introduzione" - prima di ripetere le azioni, "Conclusione" - dopo.
Nel processo di consolidamento di questo argomento, padroneggiando quelli successivi e affrontando le difficoltà, è utile anche per gli studenti forti porre la domanda: “Quante volte è necessario eseguire questa azione? Uno o molti?

Sviluppo di competenze aggiuntive

Nel processo di studio dei cicli, gli studenti sviluppano anche la capacità di diagnosticare e risolvere i problemi. Per eseguire la diagnostica, lo studente deve presentare il risultato desiderato e confrontarlo con il risultato reale. Le azioni correttive dipendono dalla differenza tra loro.
Poiché gli studenti in questa fase hanno ancora poca idea del risultato “desiderato”, possono concentrarsi sui dati del test. Di norma, nessuno in questa fase capisce ancora cosa può andare storto e come affrontarlo. Pertanto, scrivo su un quaderno una descrizione dei problemi tipici e diversi modi per risolverli. Scegliere quello più adatto è compito dello studente stesso.
È necessaria una registrazione per chiedere “è successo quello che ci si aspettava?”, “Quale di queste situazioni si è verificata adesso?”, “La soluzione applicata è stata d’aiuto?”

  1. Il numero di azioni è 1 in meno o in più rispetto al previsto. Soluzioni:
    — aumenta il valore iniziale del contatore di 1.
    — sostituire l'operatore di confronto rigoroso (< o >) con uno non rigoroso (<= o >=).
    — modificare il valore limite su 1.
  2. Le azioni in un ciclo vengono eseguite senza interruzioni, indefinitamente. Soluzioni:
    - aggiungi un comando di modifica del contatore se manca.
    — correggere il comando di modifica del contatore in modo che il suo valore si avvicini al limite.
    — rimuovi il comando di modifica del vincolo se si trova nel corpo del ciclo.
  3. Il numero di azioni in un ciclo è più di 1 in meno o in più del previsto. L'azione nel ciclo non è stata eseguita nemmeno una volta. Per prima cosa devi scoprire i valori effettivi delle variabili appena prima dell'inizio del ciclo. Soluzioni:
    — modificare il valore iniziale del vincolo
    — modifica il valore iniziale del contatore

Il problema 3 di solito comporta l'utilizzo della variabile sbagliata o il mancato ripristino del contatore a zero.

Dopo questa spiegazione, lo studente potrebbe avere ancora varie idee sbagliate su come funzionano i cicli.
Per dissipare quelli più comuni, ti assegno i seguenti compiti:

  1. In cui il limite, il valore iniziale del contatore o il passo del contatore vengono immessi dall'utente.
  2. In cui il valore del contatore deve essere utilizzato in qualche espressione aritmetica. È consigliabile utilizzare un contatore nell'espressione radicale o nel denominatore in modo che la differenza sia non lineare.
  3. In cui il valore del contatore non viene visualizzato sullo schermo mentre il ciclo è in esecuzione. Ad esempio, visualizzare il numero richiesto di frammenti di testo identici o disegnare una figura con la grafica della tartaruga.
  4. In cui è necessario eseguire prima alcune azioni ripetitive e poi altre.
  5. In cui è necessario eseguire altre azioni prima e dopo la ripetizione

Per ogni attività è necessario fornire i dati del test e il risultato atteso.

Per capire quanto velocemente puoi muoverti, devi leggere i termini di questi problemi e chiederti: "in cosa differiscono dall'esempio?", "Cosa deve essere cambiato nell'esempio per risolverli?" Se lo studente risponde in modo significativo, lascia che ne risolva almeno uno in classe e il resto a casa da solo. Se la soluzione ha successo, allora possiamo iniziare a spiegare le condizioni all'interno dei loop.
Se hai difficoltà a risolvere i problemi da solo, devi affrontare tutto in classe. Per evitare che la soluzione del problema ricordi il disegno di un gufo, consiglio prima di risolvere il problema in modo non universale. Cioè, in modo che la soluzione superi il primo test e non utilizzi la costruzione ad anello. Bene, allora applica le trasformazioni per raggiungere l'universalità della soluzione.

Loop e rami

A mio avviso è utile trattare separatamente l'argomento “cicli all'interno dei rami”. In modo che in seguito sia possibile vedere la differenza tra controllare una condizione più volte e controllarla una volta.
Le attività di consolidamento riguarderanno l'emissione dei numeri da A a B, che vengono inseriti dall'utente:
- sempre in ordine crescente.
- ascendente o discendente a seconda dei valori di A e B.

L'argomento "ramificazione all'interno di cicli" dovrebbe essere spostato solo dopo che lo studente ha padroneggiato le tecniche: "sostituire un modello con una variabile" e "sostituire azioni ripetitive con un ciclo".
Il motivo principale per utilizzare i rami all'interno dei cicli sono le anomalie nel modello. Nel mezzo si rompe a seconda dei dati iniziali.
Per quegli studenti che sono in grado di cercare una soluzione combinando tecniche semplici, è sufficiente dire “la ramificazione può essere scritta all'interno di cicli” e dare il problema “per esempio” completamente da risolvere in modo indipendente.
Compito di esempio:

L'utente inserisce il numero X. Visualizza i numeri da 0 a 9 in una colonna e metti un segno "+" accanto al numero uguale a X.

Se è stato inserito 00+
1
2
3
4
5
6
7
8
9

Se è stato inserito 60
1
2
3
4
5
6+
7
8
9

Se è stato inserito 90
1
2
3
4
5
6
7
8
9+

Se è stato inserito 7770
1
2
3
4
5
6
7
8
9

Se una breve spiegazione non è sufficiente per scrivere con un loop, è necessario ottenere una soluzione universale allo stesso problema senza loop.
Avrai una delle due opzioni:
Desiderato

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

potenziale

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

Assegnamo un compito simile in anticipo, mentre studio l'argomento della ramificazione.
Se lo studente propone un’opzione “possibile”, allora devi dirgli che possono esserci molte soluzioni allo stesso problema. Tuttavia, differiscono nella loro resistenza ai cambiamenti dei requisiti. Poni la domanda: "Quanti posti nel codice dovrebbero essere corretti se dovessi aggiungere un altro numero?" Nella versione “possibile”, dovrai aggiungere un altro ramo e aggiungere un nuovo numero in altri 10 posti. Nel “desiderato” è sufficiente aggiungere un solo ramo.
Imposta l'attività per riprodurre l'opzione "desiderata", quindi trova uno schema nel codice, esegui una sostituzione della variabile e scrivi un ciclo.
Se hai un'idea su come risolvere questo problema senza loop in qualche altro modo, scrivi nei commenti.

Loop all'interno di loop

In questo argomento è necessario prestare attenzione a quanto segue:
— i contatori per i cicli interno ed esterno devono essere variabili diverse.
— il contatore del ciclo interno deve essere reimpostato più volte (ovvero nel corpo del ciclo esterno).
— nelle attività di output del testo, non è possibile scrivere prima una lettera su più righe e poi la seconda. Devi prima stampare tutte le lettere della prima riga, poi tutte le lettere della seconda e così via.

È meglio iniziare a spiegare l'argomento dei loop all'interno dei loop spiegando l'importanza di azzerare il contatore.
Compito di esempio:

L'utente inserisce due numeri: R e T. Stampa due righe di caratteri "#". La prima riga dovrebbe contenere caratteri R. La seconda riga contiene pezzi a T. Se qualsiasi numero è negativo, visualizza un messaggio di errore.

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

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

R=-1, T=6Il valore R deve essere non negativo

R=6, T=-2Il valore T deve essere non negativo

Ovviamente anche questo problema ha almeno due soluzioni.
Desiderato

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

Possibile n.1

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

La differenza è che nella soluzione "possibile" è stata utilizzata una seconda variabile per emettere la seconda riga. Dovresti insistere sull'utilizzo della stessa variabile per entrambi i cicli. Questa limitazione può essere giustificata dal fatto che una soluzione con un contatore per due cicli sarà un esempio del termine “reset contatore”. Comprendere questo termine è necessario per risolvere i seguenti problemi. Come compromesso, puoi salvare entrambe le soluzioni al problema.

Un tipico problema con l'utilizzo di una variabile contatore per due cicli appare così:
R=5, T=11#####
######

Il numero di caratteri nella seconda riga non corrisponde al valore di T. Se hai bisogno di aiuto con questo problema, devi consultare le note sui problemi tipici con i loop. Questo è il sintomo n. 3. Viene diagnosticato se si aggiunge un valore di conteggio in uscita immediatamente prima del secondo ciclo. Corretto ripristinando. Ma è meglio non dirlo subito. Lo studente dovrà provare a formulare almeno un'ipotesi.

Esiste, ovviamente, un'altra soluzione. Ma non l’ho mai visto tra gli studenti. Nella fase di studio dei cicli, la storia a riguardo distrarrà l'attenzione. Puoi tornarci più tardi quando imparerai le funzioni delle stringhe.
Possibile n.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));

Prossima attività richiesta:

Visualizza i numeri da 0 a 9. Ogni numero deve trovarsi su una riga separata. Il numero di cifre in una riga (W) viene immesso dalla tastiera.

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

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

Se uno studente ha imparato la tecnica di sostituzione di una variabile, se la caverà abbastanza rapidamente. Un possibile problema sarà nuovamente nel reimpostare la variabile. Se non riesci a gestire la trasformazione, significa che avevi fretta e dovevi risolvere problemi più semplici.

Grazie per l'attenzione. Metti mi piace e iscriviti al canale.

PS Se trovate errori di battitura o errori nel testo, fatemelo sapere. Questo può essere fatto selezionando parte del testo e premendo “⌘ + Invio” su Mac e “Ctrl/Invio” sulle tastiere classiche, oppure tramite messaggi privati. Se queste opzioni non sono disponibili, scrivi gli errori nei commenti. Grazie!

Solo gli utenti registrati possono partecipare al sondaggio. AccediPer favore.

Sondaggio per lettori senza karma

  • 20,0%Insegno professionalmente, +12

  • 10,0%Insegno professionalmente, -11

  • 70,0%Non insegno, +17

  • 0,0%Non insegno, -10

  • 0,0%Altro0

10 utenti hanno votato. 5 utenti si sono astenuti.

Fonte: habr.com

Aggiungi un commento