Nonostante si parli di uno dei temi fondamentali, questo articolo è scritto per specialisti esperti. L'obiettivo è mostrare quali sono i fraintendimenti comuni tra i neofiti della programmazione. Per i programmatori pratici, questi problemi sono ormai risolti, dimenticati o addirittura non notati. L'articolo potrebbe essere utile se dovessi aiutare qualcuno su questo argomento. Vengono stabilite delle parallele con materiali tratti da vari libri di programmazione di autore come Schildt, Stroustrup e Okulov.
L'argomento dei cicli è stato scelto perché molti abbandonano la programmazione durante questo apprendistato.
Questa metodologia è destinata a studenti poco forti. Di solito, gli studenti più forti non si soffermano su questo argomento e non è necessario inventare metodi specifici per loro. Un secondo obiettivo dell'articolo è quello di traslare questa metodologia dalla categoria "funziona su tutti gli studenti, ma solo con un insegnante" alla categoria "funziona su tutti gli studenti e tutti gli insegnanti". Non pretendo di essere assolutamente originale. Se già utilizzi una metodologia simile per insegnare questo argomento, per favore scrivi in cosa si differenzia la tua versione. Se decidi di applicarla, racconta alla fine com'è andata. Se una metodologia simile è descritta in qualche libro, per favore inviami il titolo.
Ho sviluppato questa metodologia per 4 anni, lavorando individualmente con studenti di vari livelli. In totale, circa una cinquantina di studenti e duemila ore di lezione. Inizialmente, gli studenti si bloccavano per sempre su questo tema e abbandonavano. Dopo ogni studente, la metodologia e i materiali sono stati corretti. Nell'ultimo anno, gli studenti non si bloccano più su questo argomento, quindi ho deciso di condividere le mie esperienze.
Perché tante parole? I cicli sono elementi fondamentali!
Come ho già scritto in precedenza, per i programmatori pratici e per gli studenti più forti, la complessità del concetto di cicli può essere sottovalutata. Ad esempio, si potrebbe tenere una lunga lezione, vedere teste che annuiscono e occhi intelligenti. Ma quando si tenta di risolvere un problema, si blocca e sorgono problemi inspiegabili. Dopo la lezione, gli studenti avrebbero sicuramente una comprensione solo parziale. La situazione è aggravata dal fatto che gli studenti non riescono a esprimere quali siano precisamente i loro fraintendimenti.
Un giorno mi sono reso conto che gli studenti percepiscono i miei esempi come geroglifici. Cioè, come pezzi di testo indivisibili, nei quali bisogna aggiungere una qualche lettera "magica" affinché funzioni.
A volte notavo che gli studenti pensano che per risolvere un determinato problema sia necessaria qualche altra struttura, che semplicemente non ho ancora spiegato. Sebbene per risolvere fosse sufficiente modificare leggermente l'esempio.
Quindi sono arrivato all'idea che l'attenzione principale dovrebbe essere rivolta non alla sintassi delle espressioni, ma all'idea di rifattorizzare il codice ripetitivo utilizzando i cicli. Non appena gli studenti padroneggiano questa idea, qualsiasi sintassi si apprende attraverso piccoli esercizi.
A chi e perché insegno
Poiché non ci sono esami di ammissione, durante le lezioni possono esserci sia studenti forti che molto deboli. È possibile leggere più dettagliatamente sui miei studenti nell'articolo
Ho sempre cercato di far sì che la programmazione fosse accessibile a chiunque desiderasse impararla.
Le mie lezioni si svolgono in modo individuale e lo studente paga di tasca sua per ciascuna di esse. Potrebbe sembrare che gli studenti vogliano ottimizzare i costi e richiedere il minimo. Tuttavia, le persone partecipano a corsi in presenza con un docente dal vivo non solo per acquisire conoscenze, ma per avere la certezza di aver compreso, per percepire il progresso e per ricevere approvazione da un esperto (docente). Se gli studenti non sentono di progredire nel loro apprendimento, se ne andranno. In generale, è possibile strutturare le lezioni in modo che gli studenti percepiscano un progresso nell'aumento del numero di strutture conosciute. Cioè, prima approfondiamo il ciclo while, poi studiamo il for, poi il do while, ed ecco che abbiamo un corso delle mille e una notte, in cui per due mesi si studi solo cicli, e alla fine abbiamo uno studente che ha scritto la libreria standard sotto dettatura. Tuttavia, per risolvere problemi pratici non è necessaria solo la conoscenza del materiale, ma anche l'autonomia nell'applicazione e nella ricerca di nuove informazioni. Pertanto, considero corretto per i corsi in presenza adottare il seguente principio: insegnare il minimo e incoraggiare lo studio autonomo delle sfumature e degli argomenti correlati. Per quanto riguarda i cicli, considero il ciclo while come il minimo. Da esso si può capire il principio. Una volta compreso il principio, è possibile apprendere anche il for e il do-while in modo autonomo.
Per garantire l'apprendimento del materiale da parte di studenti più deboli, non basta descrivere la sintassi. È necessario fornire più compiti semplici ma variegati e spiegare gli esempi in modo più dettagliato. Alla fine, la velocità di apprendimento è limitata dalla capacità dello studente di trasformare le espressioni e cercare le correlazioni. Per gli studenti più brillanti, la maggior parte dei compiti risulterà noiosa. Quando si lavora con loro, non è necessario insistere sulla risoluzione del 100% dei problemi. Puoi vedere il mio materiale su . Tuttavia, il repository assomiglia più a un grimorio di un negromante: nessuno, tranne me, capirà cosa si trova dove, e se fallisci il controllo, potresti impazzire.
La metodologia è orientata alla pratica.
La teoria è spiegata attraverso la risoluzione di problemi. Nelle lezioni di programmazione di base, dove si studiano le diramazioni e i cicli, non è possibile organizzare una lezione utile su un unico argomento per un'ora intera. 15-20 minuti bastano per spiegare il concetto. Le principali difficoltà sorgono nell'esecuzione di compiti pratici.
I docenti principianti possono gettare operatori, diramazioni, cicli e array in un'unica lezione. Peccato che gli studenti si troveranno di fronte al problema di assimilare queste informazioni.
È importante non solo illustrare il materiale, ma anche assicurarsi che gli ascoltatori l'abbiano compreso.
Il fatto di aver assimilato un argomento si determina in base a come lo studente affronta il lavoro autonomo.
Se lo studente riesce a risolvere un problema sull'argomento senza l'aiuto dell'insegnante, significa che l'argomento è stato assimilato. Per garantire un'autovalutazione, ogni problema è accompagnato da una tabella con scenari di test. I problemi seguono un ordine ben definito. Non è consigliabile saltare i problemi. Se il problema attuale è troppo difficile, passare al successivo è inutile. Sarà ancora più difficile. Per consentire allo studente di affrontare l'attuale problema complesso, vengono spiegati alcuni trucchi utilizzando il primo problema come esempio. In effetti, tutto il contenuto dell'argomento si riduce a strategie per superare le difficoltà. I cicli sono, piuttosto, un effetto collaterale.
Il primo problema è sempre un esempio. Il secondo differisce leggermente ed è svolto "autonomamente" subito dopo il primo sotto la supervisione dell'insegnante. Tutti i problemi successivi sono finalizzati a richiamare l'attenzione su varie piccole cose che possono causare malintesi.
La spiegazione dell'esempio consiste in un dialogo in cui lo studente deve attivare il back propagation e la cross-validation per assicurarsi di aver assimilato una porzione di materiale.
Sarò banale e dirò che il primo esempio sull'argomento è molto importante. Se c'è materiale per un ampio lavoro autonomo, le mancanze del primo esempio possono essere corrette. Se non c'è null'altro oltre all'esempio, è probabile che lo studente non padroneggi l'argomento.
While o for?
Uno dei punti controversi è la scelta della struttura per l'esempio: while o for. Una volta, un mio amico sviluppatore pratico, senza esperienza nell'insegnamento, ha passato un'ora a convincermi che il ciclo for è il più semplice da capire. Gli argomenti si riducevano a "è tutto chiaro e in ordine". Tuttavia, la causa principale delle difficoltà per i veri principianti risiede nell'idea stessa del ciclo, e non nella sua scrittura. Se una persona non capisce quest'idea, avrà difficoltà con la sintassi. Una volta compresa l'idea, i problemi di formattazione del codice svaniscono.
Nei miei materiali, l'argomento dei cicli segue il tema delle diramazioni. La somiglianza esterna di if e while permette di fare un'analogia diretta: "quando la condizione nell'intestazione è vera, viene eseguito il corpo". La particolarità del ciclo sta nel fatto che il corpo viene eseguito molte volte.
Il mio secondo argomento è che while richiede meno formattazione rispetto a for. Meno formattazione significa meno errori stupidi con virgole e parentesi mancanti. I principianti non hanno ancora un'attenzione e una scrupolosità tali da evitare automaticamente gli errori sintattici.
Il terzo argomento è che in molti buoni libri, while viene spiegato per primo.
Se uno studente riesce a trasformare le espressioni facilmente, si può parlare di for di passaggio. Lo studente poi sceglierà ciò che preferisce. Se invece le trasformazioni presentano difficoltà, è meglio non distrarre. Lasciate che lo studente risolva tutto prima utilizzando while. Quando ha padroneggiato il tema dei cicli, può riscrivere le soluzioni per esercitarsi nella trasformazione da while a for.
I cicli con post-condizione sono piuttosto rari. Non spendo tempo su di essi. Se uno studente ha compreso le idee di individuazione delle regolarità e trasformazione delle espressioni, potrà affrontarli senza il mio aiuto.
Durante la dimostrazione del primo esempio agli studenti più forti, sottolineo che è importante fissare non solo la soluzione, ma anche tutta la catena di azioni che ha portato al risultato. Gli studenti pigri possono trascurare la scrittura e limitarsi a riportare solo l'algoritmo finale. Bisogna convincerli che una volta si troveranno di fronte a un compito difficile. Per risolverlo, sarà necessario seguire i passaggi proprio come in questo esempio. Ecco perché è importante fissare tutte le fasi. Nei compiti successivi si potrà lasciare solo la versione finale della soluzione.
L'idea principale dell'automazione è che chiediamo al computer di eseguire il lavoro rutinario al posto dell'uomo. Uno dei metodi di base è la scrittura dei cicli. Questo viene applicato quando nel programma vengono eseguite consecutivamente più azioni identiche e ripetitive.
Esplicito è meglio di implicito
Potrebbe sembrare un'ottima idea nel primo compito sui cicli stampare a schermo qualche frase identica più volte. Ad esempio:
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Evviva, funziona!
Questa opzione è scarsa poiché nell'output non si vede il valore del contatore. Questo è un problema per i principianti. Non bisogna sottovalutarlo. Inizialmente questo compito era il primo, mentre il compito sullo stampare una serie di numeri in ordine crescente era il secondo. Dobbiamo introdurre ulteriori termini come "ciclo N volte" e "ciclo da A a B", che essenzialmente sono la stessa cosa. Per non creare entità superflue, ho deciso di mostrare solo l'esempio con l'output di una serie di numeri. Poco riescono a imparare a tener conto del contatore e a modellare il comportamento del programma nella mente senza preparazione. Alcuni studenti affrontano per la prima volta il modellamento "nella mente" proprio sul tema dei cicli.
Dopo un po' di pratica, do il compito di ripetere un testo identico per soluzione autonoma. Se per prima cosa si mostra un contatore visibile e poi invisibile, gli studenti incontrano meno problemi. A volte è sufficiente un suggerimento "non scrivere il contatore a schermo".
Come viene spiegato agli altri?
Nella maggior parte dei materiali didattici disponibili su internet, la sintassi dei cicli è presentata come parte di una "lezione". Ad esempio, su developer.mozilla.org (attualmente) il ciclo while è descritto insieme ad altre costruzioni. In questo modo vengono fornite esclusivamente le stesse costruzioni sotto forma di modelli. Il risultato della loro esecuzione viene descritto a parole, ma l'illustrazione è assente. A mio avviso, un approccio del genere azzera l'utilità di tali materiali. Lo studente può riscrivere il codice ed eseguirlo da solo, ma è comunque necessario avere un riferimento per il confronto. Come fare a capire se l'esempio è stato riscritto correttamente se non c'è nulla con cui confrontare il risultato?
Quando viene fornito solo il modello, senza un esempio, diventa ancora più difficile per lo studente. Come capire se i frammenti di codice sono collocati correttamente nel modello? Si può provare a scrivere qualcosa, e poi eseguire. Ma se non c'è un riferimento per confrontare il risultato, anche l'esecuzione non aiuta.
Nel corso di C++ su Intuit, la sintassi dei cicli è sepolta nella terza pagina della lezione 4 sul tema "operatori". Nella spiegazione della sintassi dei cicli si pone particolare enfasi sul termine "operatore". Il termine viene presentato come un insieme di fatti tipo "il simbolo; è un operatore", "{} è un operatore composto", "il corpo del ciclo deve essere un operatore". A me questo approccio non piace, perché in qualche modo nasconde importanti collegamenti dietro un solo termine. L'analisi del codice sorgente di un programma a questo livello è necessaria per gli sviluppatori di compilatori per implementare la specifica del linguaggio, ma non per gli studenti a un primo approccio. I principianti nella programmazione raramente possiedono la sufficiente meticolosità per prestare così tanta attenzione ai termini. È raro che una persona ricordi e comprenda nuove parole al primo colpo. Praticamente nessuno riesce ad applicare correttamente un termine appena appreso. Pertanto, agli studenti sorgono molti errori come "ho scritto while(a<7);{, e il programma non funziona".
A mio avviso, inizialmente è meglio fornire la sintassi della costruzione fin da subito con le parentesi. La variante senza parentesi andrebbe spiegata solo se allo studente sorge una domanda specifica "perché qui senza parentesi e funziona".
Nel libro di Okulov «Fondamenti di programmazione» del 2012, l'introduzione ai cicli inizia con il modello for, vengono poi date raccomandazioni sul suo utilizzo e subito dopo c'è la sezione sperimentale della lezione. Capisco che il libro sia stato scritto per quella minoranza di studenti molto capaci che raramente partecipano alle mie lezioni.
Nei libri popolari viene sempre mostrato il risultato dei frammenti di codice. Ad esempio, nel libro di Schildt «Java 8. Guida completa» del 2015, prima viene dato il modello, poi un esempio di programma e subito dopo il risultato dell'esecuzione.
Come esempio, consideriamo il ciclo while, in cui viene eseguito un conteggio alla rovescia
a partire da 10, e vengono stampate esattamente 10 righe di «tacche»://Продемонстрировать применение оператора цикла while class While { public static void main(String args []) { int n = 10; while (n > 0) { System.out.println("такт " + n); n--; } } }Dopo l'avvio, questo programma stampa dieci «tacche» nel seguente modo:
passo 10
passo 9
passo 8
passo 7
passo 6
passo 5
passo 4
passo 3
passo 2
passo 1
L'approccio di descrivere il modello, l'esempio di programma e il risultato dell'esecuzione viene utilizzato anche nel libro «Javascript per bambini» e nel corso di js su w3schools.com. Il formato della pagina web consente persino di rendere questo esempio interattivo.
Nel libro di Stroustrup «Principi e pratica con C++» del 2016, l'autore è andato ancora oltre. Prima di tutto viene spiegato quale risultato dovrebbe essere ottenuto e solo dopo si mostra il testo del programma. Inoltre, come esempio non si prende un programma casuale, ma viene fatta un'escursione nella storia. Questo aiuta a mettere in evidenza: «Guarda, questo non è solo un testo inutile. Vedi qualcosa di significativo».
Come esempio di iterazione, consideriamo il primo programma realizzato su una macchina a programma memorizzato (EDSAC). Fu scritto da David Wheeler nel laboratorio informatico dell'Università di Cambridge (Cambridge University, Inghilterra) il 6 maggio 1949. Questo programma calcola e stampa una semplice lista di quadrati.
0 0
1 1
2 4
3 9
4 16
...
98 9604
99 9801
Qui, in ogni riga, è contenuto un numero, seguito da un segno di tabulazione (‘t’) e dal quadrato di quel numero. La versione di questo programma in linguaggio C++ appare così://Вычисляем и распечатываем таблицу квадратов чисел 0-99 int main() { int i = 0; // Начинаем с нуля while(i < 100){ cout << i << 't' << square(i) << 'n'; ++i; } }
Curiosamente, il modello di sintassi in questo libro non viene descritto. Stroustrup nel manuale per l'istruttore () sottolinea che rispetta l'intelligenza dei suoi studenti. Forse la capacità di identificare un modello in diversi esempi è considerata un segno di tale intelligenza.
Come spiego io stesso
L'approccio di Stroustrup: descrivere il risultato, poi risolvere il problema e infine analizzare autonomamente lo studente - sembra il più ragionato. Quindi ho deciso di basarmi proprio su questo, ma di presentarlo con un esempio meno storico: il problema della generazione di un "indice". Esso crea un ancoraggio riconoscibile, così da poter dire "ricorda il problema dell'indice" e gli studenti lo ricorderanno. Nel mio esempio ho cercato di prevenire anche due dei più comuni fraintendimenti. Di seguito parlerò di loro in modo più dettagliato.
In questo compito ci familiarizziamo con le tecniche di risoluzione di problemi complessi. La soluzione iniziale deve essere primitiva e semplice. Dopodiché, possiamo pensare a come migliorare questa soluzione.
Introduzione
Capitolo 1
Capitolo 2
Capitolo 3
Capitolo 4
Capitolo 5
Capitolo 6
Capitolo 7
Conclusione
Dai miei osservatori, l'approccio "modello-esempio-risultato" in varie combinazioni porta comunque a far percepire agli studenti il ciclo come un geroglifico. Ciò si manifestava nel fatto che non capivano perché scrivere una condizione, come scegliere tra i++ e i-- o altre cose che sembrano ovvie. Per evitare questi fraintendimenti, l'approccio alla spiegazione dei cicli deve sottolineare il significato della ripetizione delle stesse azioni e solo dopo - la loro formattazione mediante la costruzione. Pertanto, prima di fornire la sintassi del ciclo, è necessario risolvere il problema "di petto". La soluzione primitiva al problema dell'indice appare così:
Console.WriteLine("Introduzione");
Console.WriteLine("Capitolo 1");
Console.WriteLine("Capitolo 2");
Console.WriteLine("Capitolo 3");
Console.WriteLine("Capitolo 4");
Console.WriteLine("Capitolo 5");
Console.WriteLine("Capitolo 6");
Console.WriteLine("Capitolo 7");
Console.WriteLine("Conclusione");
Come può essere migliorato?
Sostituire le azioni ripetitive con un ciclo.
Quali azioni qui si ripetono consecutivamente senza variazioni?
In questo frammento non ce ne sono. Tuttavia, i comandi per l'output della parola "Capitolo" con il numero sono molto simili tra loro.
Pertanto, il passo successivo è cercare la differenza tra i frammenti. Questo è ovvio solo in questo compito, in seguito le ripetizioni non saranno singoli comandi, ma blocchi di codice di 5 righe o più. Dovremo cercare non solo nell'elenco dei comandi, ma anche nelle costruzioni di ramificazione o ciclo.
Nell'esempio, la differenza tra i comandi è nel numero dopo la parola "Capitolo".
Non appena viene trovata la differenza, è necessario comprendere la regolarità della variazione. Il frammento diverso è un numero? Incrementa o diminuisce costantemente? Come cambia il valore del numero tra due comandi vicini?
Nell'esempio, il numero dopo la parola «Capitolo» aumenta di 1. La differenza è stata trovata, la regolarità è stata identificata. Ora possiamo sostituire il frammento variabile con una variabile.
È necessario dichiarare tale variabile prima del primo dei frammenti ripetuti. Questa variabile viene di solito chiamata I o j o con un nome più esteso. Il suo valore iniziale deve essere uguale al primo valore visualizzato a schermo. Nell'esempio, il primo valore è 1.
Quale valore iniziale deve essere preso per visualizzare la serie di numeri «100, 101, 102, 103, 104, 105»?
In questa serie, il primo numero è 100.
Dopo ogni comando di output, è necessario aumentare il valore di questa variabile di 1. Questo valore è il passo di cambiamento.
Quale passo avrà la serie di numeri «100, 102, 104, 106»?
In questa serie, il passo è 2.
Dopo aver sostituito il frammento variabile, il codice apparirà così:
Console.WriteLine("Introduzione");
int i;
i = 0;
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Conclusione");
Dopo l'applicazione della tecnica «esprimere la regolarità come variabile», il codice contiene diversi gruppi di azioni identiche che vengono eseguite in sequenza. Ora le azioni ripetitive possono essere sostituite con un ciclo.
La sequenza per risolvere un problema in cui è necessario utilizzare cicli consiste in fasi:
- Risolvere «alla lettera» con una serie di comandi singoli
- Trovare la regolarità
- Espressione della regolarità come variabile
- Formulare sotto forma di ciclo
In seguito vengono introdotti nuovi termini, affinché lo studente non si trovi nella situazione di «capire tutto, ma non sapere come esprimersi»:
— contatore — è sempre una variabile necessaria per monitorare il numero di passaggi del ciclo. Di solito è un numero intero che viene confrontato con un limite.
— passo del contatore — descrive la regolarità nella modifica del contatore.
— limite — numero o variabile con cui il contatore viene confrontato, affinché l'algoritmo sia finito. Il valore del contatore cambia in modo da avvicinarsi al limite.
— corpo del ciclo — insieme di comandi che verranno ripetuti. Quando si dice «il comando scritto all'interno del ciclo», si riferisce proprio al corpo.
— iterazione del ciclo — esecuzione singola del corpo del ciclo.
— condizione del ciclo — espressione logica dalla quale dipende se verrà eseguita un'altra iterazione. (Qui può esserci confusione con le strutture di ramificazione)
Bisogna essere pronti al fatto che inizialmente gli studenti utilizzeranno i termini in modo improprio. Questo vale sia per i più forti che per i più deboli. Stabilire un linguaggio comune è tutta un'arte. Adesso dirò brevemente: bisogna porre il compito "individua il frammento di codice con " e usare correttamente questi termini nella conversazione.
Dopo la trasformazione con il ciclo otteniamo il frammento:
Console.WriteLine("Introduzione");
int i = 0;
while (i < 7) {
Console.WriteLine("Capitolo " + i);
i = i + 1;
}
Console.WriteLine("Conclusione");La principale illusione
Una credenza errata comune tra gli studenti è che inseriscono all'interno della struttura del ciclo azioni che devono essere eseguite solo una volta. Ad esempio in questo modo:
;
int i = 0;
while (i < 7) {
Console.WriteLine("Introduzione")
Console.WriteLine("Capitolo " + i);
i = i + 1;
Console.WriteLine("Conclusione");
}
Gli studenti si imbattono costantemente in questo problema, sia all'inizio che in compiti più complessi.
Suggerimento chiave in questo caso:
Quante volte è necessario ripetere il comando: una volta o molte?
I comandi per stampare le parole "Introduzione" e "Conclusione", così come la dichiarazione e l'inizializzazione della variabile i, non assomigliano ad altre azioni ripetitive. Vengono eseguiti solo una volta, quindi devono essere scritti al di fuori del corpo del ciclo.
Nel codice devono rimanere tutte e tre le fasi della soluzione, in modo da poter fare riferimento ad esse in caso di difficoltà. I primi due esempi possono essere semplicemente commentati, in modo che non diano fastidio.
L'attenzione dello studente deve essere rivolta ai seguenti fatti:
— Nella condizione del ciclo di solito si confrontano il contatore e il limite. Il contatore può cambiare all'interno del corpo del ciclo, mentre il limite no. Per violare questa regola, è necessario formulare delle ragioni valide.
— I comandi per stampare le parole "Introduzione" e "Conclusione" si trovano al di fuori del corpo del ciclo. Dobbiamo eseguirli una sola volta. "Introduzione" — prima di ripetere le azioni, "Conclusione" — dopo.
Nel processo di consolidamento di questo tema, nell'apprendimento dei successivi e nella risoluzione delle difficoltà, è utile porre anche agli studenti più forti la domanda: "E quest'azione quanto spesso deve essere eseguita? Una volta o molte?".
Sviluppo di competenze aggiuntive
Durante lo studio dei cicli, gli studenti migliorano anche le loro capacità di diagnosi e risoluzione dei problemi. Per effettuare una diagnosi, lo studente deve presentare il risultato desiderato e confrontarlo con il risultato effettivo. Le azioni correttive dipendono dalla differenza tra i due.
Poiché gli studenti in questa fase hanno ancora una scarsa comprensione del risultato «desiderato», possono fare riferimento ai dati di test. Di solito, in questa fase nessuno comprende effettivamente cosa possa andare storto e come affrontarlo. Pertanto, fornisco una descrizione delle problematiche tipiche e alcuni modi per risolverle da annotare nel taccuino. La scelta del più adatto è un compito dello studente.
La registrazione è necessaria per chiedere «è successo ciò che ci si aspettava?», «Quale di queste situazioni si è realizzata ora?», «La soluzione applicata ha aiutato?».
- Il numero di azioni è 1 in meno o più di quanto atteso. Modi di risoluzione:
— aumentare il valore iniziale del contatore di 1.
— sostituire l'operatore di confronto rigido (< o >) con uno non rigido (<= o >=).
— modificare il valore del limite di 1. - Le azioni nel ciclo vengono eseguite senza fermarsi, all'infinito. Modi di risoluzione:
— aggiungere il comando di modifica del contatore, se è assente.
— correggere il comando di modifica del contatore in modo che il suo valore si avvicini al limite.
— rimuovere il comando di modifica del limite, se è nel corpo del ciclo. - Il numero di azioni nel ciclo è più di 1 in meno o più di quanto previsto. L'azione nel ciclo non è stata eseguita neanche una volta. Prima bisogna determinare i valori effettivi delle variabili immediatamente prima dell'inizio del ciclo. Modi di risoluzione:
— modificare il valore iniziale del limite
— modificare il valore iniziale del contatore
Di solito, il problema 3 è legato all'uso della variabile sbagliata o alla mancata inizializzazione del contatore.
Dopo questa spiegazione, lo studente può ancora avere diverse idee sbagliate sul funzionamento dei cicli.
Per dissipare i malintesi più comuni, propongo esercizi:
- In cui il limite, il valore iniziale del contatore o il passo del contatore vengono inseriti dall'utente.
- In cui il valore del contatore deve essere utilizzato in un'espressione aritmetica. È preferibile che il contatore sia in un'espressione sotto-radicale o nel denominatore, affinché la differenza sia non lineare.
- In cui il valore del contatore non viene visualizzato sullo schermo durante l'esecuzione del ciclo. Ad esempio, per visualizzare un numero specifico di frasi di testo identiche o disegnare una figura utilizzando la grafica tartaruga.
- In cui è necessario eseguire prima alcune azioni ripetitive e poi altre.
- In cui è necessario eseguire altre azioni prima e dopo le azioni ripetitive.
Per ogni compito bisogna fornire dati di test e il risultato atteso.
Per capire quanto velocemente si può procedere, è necessario far leggere le condizioni di questi compiti e chiedere: «in cosa differiscono dall'esempio?», «cosa bisogna cambiare nell'esempio per risolverli?». Se lo studente risponde in modo riflessivo, allora dovrebbe risolvere almeno uno durante la lezione e gli altri a casa da solo. Se la soluzione è corretta, si può iniziare a spiegare le condizioni all'interno dei cicli.
Se ci sono difficoltà nella risoluzione autonoma, è necessario lavorare su tutto in aula. Per evitare che la soluzione del compito somigli al disegno di un gufo, consiglio di risolvere il compito in modo non universale all'inizio. Cioè, in modo che la soluzione superi il primo test e non utilizzi la struttura del ciclo. Solo dopo applicare trasformazioni per ottenere l'universalità della soluzione.
Cicli e ramificazioni
A mio avviso, è utile trattare il tema «cicli all'interno delle ramificazioni» separatamente. In questo modo, sarà chiaro il differente tra il controllo condizionale ripetuto e quello singolo.
I compiti per il consolidamento riguarderanno l'output dei numeri da A a B, che vengono inseriti dall'utente:
— sempre in ordine crescente.
— in ordine crescente o decrescente a seconda dei valori di A e B.
Alla tematica «ramificazioni all'interno dei cicli» bisogna passare solamente dopo che lo studente ha compreso le tecniche: «sostituzione della regolarità con una variabile» e «sostituzione delle azioni ripetitive con un ciclo».
La principale motivazione per l'applicazione delle ramificazioni all'interno dei cicli sono le anomalie nella regolarità. A metà essa viene interrotta a seconda dei dati di partenza.
Agli studenti capaci di cercare soluzioni combinando semplici tecniche, basta dire «le ramificazioni possono essere scritte all'interno dei cicli» e dare un compito «per esempio» da risolvere completamente in modo autonomo.
Compito per esempio:
L'utente inserisce un numero X. Visualizzare in colonna i numeri da 0 a 9 e mettere il segno ‘+’ di fronte al numero che è 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 manca una spiegazione breve per scrivere con il ciclo, allora bisogna trovare una soluzione universale per lo stesso problema senza ciclo.
Ne risulteranno 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);
}
Possibile
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+");
}
Assegno in anticipo un compito simile durante lo studio del tema sui rami.
Se lo studente ha ottenuto un'opzione "possibile", bisogna spiegare che una stessa problematica può avere molteplici soluzioni. Tuttavia, queste differiscono per stabilità rispetto ai cambiamenti dei requisiti. Fai la domanda: "Quanti punti nel codice dovranno essere corretti se sarà necessario aggiungere un altro numero?" Nell'opzione "possibile" bisognerebbe aggiungere un altro ramo e scrivere il nuovo numero in 10 altri posti. Nell'opzione "desiderata" è sufficiente aggiungere solo un ramo.
Formula il compito di riprodurre l'opzione "desiderata", poi trova nel codice la regolarità, esegui la sostituzione della variabile e scrivi un ciclo.
Se hai un'idea su come risolvere questo compito senza ciclo in un altro modo, per favore scrivilo nei commenti.
Cicli all'interno di cicli
In questo tema bisogna prestare attenzione a:
— i contatori per il ciclo interno e quello esterno devono essere variabili diverse.
— il contatore per il ciclo interno deve essere azzerato molte volte (cioè all'interno del corpo del ciclo esterno).
Nei problemi di output del testo, non è possibile scrivere prima una lettera su più righe e poi un’altra. Bisogna prima stampare tutte le lettere della prima riga, poi tutte le lettere della seconda e così via.
La spiegazione del tema sui cicli all'interno dei cicli è meglio iniziare con l'importanza di azzerare il contatore.
Compito per esempio:
L'utente inserisce due numeri: R e T. Stampare due righe di simboli "#". Nella prima riga devono esserci R simboli. Nella seconda riga T simboli. Se uno dei numeri è negativo, stampare un messaggio di errore.
R=5, T=11#####
###########
R=20, T=3####################
###
R=-1, T=6Il valore di R deve essere non negativo
R=6, T=-2Il valore di T deve essere non negativo
È evidente che anche questo problema ha almeno due varianti di soluzione.
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 №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" per stampare la seconda riga è stata utilizzata una seconda variabile. Bisogna insistere sull’uso della stessa variabile per entrambi i cicli. È possibile argomentare questa limitazione dicendo che una soluzione con un solo contatore per due cicli sarà un'illustrazione del termine "azzeramento del contatore". Comprendere questo termine è importante per risolvere i problemi successivi. Come compromesso, si possono mantenere entrambe le soluzioni al problema.
Un problema tipico nell'uso di una variabile contatore per due cicli si manifesta in questo modo:
R=5, T=11#####
######
Il numero di simboli nella seconda riga non corrisponde al valore di T. Se hai bisogno di aiuto con questo problema, devi "mostrare" il riassunto sui problemi tipici con i cicli. Questo è il sintomo №3. Si diagnostica se si aggiunge l'output del valore del contatore direttamente prima del secondo ciclo. Si corregge azzerando. Ma è meglio non dirlo subito. Lo studente dovrebbe cercare di formulare almeno un'ipotesi.
C'è, ovviamente, anche un'altra variante di soluzione. Ma non l'ho mai vista dagli studenti. Nella fase di apprendimento dei cicli, parlare di essa distrae l'attenzione. Possiamo tornarci più tardi, durante lo studio delle funzioni per la manipolazione delle stringhe.
Possibile №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));
Il prossimo compito obbligatorio:
Visualizza sullo schermo i numeri da 0 a 9. Ogni numero deve essere su una linea separata. Il numero di cifre in ogni riga (W) viene inserito da tastiera.
W=10
1
2
3
4
5
6
7
8
9
W=100000000000
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
Se lo studente ha acquisito la tecnica della sostituzione delle variabili, procederà abbastanza rapidamente. Il problema potrebbe risiedere nuovamente nella azzeramento della variabile. Se non riesce a eseguire la conversione, significa che ti sei affrettato e devi affrontare compiti più semplici.
Grazie per l'attenzione. Metti mi piace, iscriviti al canale.
P.S. Se hai trovato refusi o errori nel testo, ti prego di farmelo sapere. Puoi farlo evidenziando una parte del testo e premendo su Mac «⌘ + Enter», e su tastiere classiche «Ctrl / Enter», oppure tramite messaggi privati. Se queste opzioni non sono disponibili, scrivi di eventuali errori nei commenti. Grazie!
Solo gli utenti registrati possono partecipare al sondaggio. , per 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
Hanno votato 10 utenti. Si sono astenuti 5 utenti.
Fonte: habr.com
