Piccolo manuale di LibreLogo/Incapsulare: differenze tra le versioni

Contenuto cancellato Contenuto aggiunto
Iamarf (discussione | contributi)
Iamarf (discussione | contributi)
Riga 62:
<span style="color:#000000;">Se provassimo ad utilizzarla in un altro </span><span style="color:#000000;">''script''</span><span style="color:#000000;"> allora LibreLogo darebbe un errore. </span><span style="color:#000000;">Ecco il risultato del codice precedente:</span><span style="color:#000000;"> </span>
 
[[File:IncapsulareLO_02IncapsulareLO 02 a.svg|380px|senza_cornice]]
 
In realtà a noi piacerebbe controllare meglio il modo con cui vengono disegnati i quadrati, per esempio determinando la lunghezza del lato. Questo si può fare assegnando degli argomenti alla subroutine:
Riga 71:
Qui, dopo la dichiarazione del nome della subroutine, abbiamo introdotto l'argomento <span style="color:#ff00cc;">'''LATO'''</span>. Nel codice successivo alla subroutine, l'istruzione <span style="color:#ff0000;">'''QUADRATO'''</span> viene invocata con un argomento, pari a <span style="color:#ff00cc;">'''100'''</span> la prima volta e <span style="color:#ff00cc;">'''50'''</span> la seconda.
 
Ricapitolando, quando si fa eseguire il codice, premendo il tasto PLAY [[File:PlayLO.png|senza_cornice]], LibreLogo esegue le prime tre istruzioni, poi “impara” tutte quelle contenute nella subroutine <span style="color:#ff0000;">'''QUADRATO'''</span><nowiki>; quindi esegue le istruzioni sottostanti, invocando </nowiki><span style="color:#ff0000;">'''QUADRATO'''</span> con un valore <span style="color:#ff00cc;">'''LATO'''</span> di <span style="color:#ff00cc;">'''100'''</span>, spontandosispostandosi e poi di nuovo <span style="color:#ff0000;">'''QUADRATO'''</span> con un valore di <span style="color:#ff00cc;">'''LATO'''</span> di <span style="color:#ff00cc;">'''50'''</span>.
|-
|
Riga 103:
Ecco il risultato:
 
[[File:IncapsulareLO_03IncapsulareLO 03 a.svg|380px|senza_cornice]]
 
Così siamo liberi di invocare la nostra nuova funzione QUADRATO ogni volta che ne abbiamo bisogno, specificando liberamente la dimensione: QUADRATO 10, QUADRATO 30 o quello che vogliamo. Ora, a direildire il vero un'istruzione per disegnare i quadrati in LibreLogo esiste già: l'abbiamo incontrata a pag. 21, si chiama SQUARE e funziona allo stesso modo. O quasi, in realtà una differenza c'è: con SQUARE, una volta che il quadrato è stato disegnato, la tartaruga la ritroviamo al suo centro rivolta nella stessa direzione che aveva prima. Nel nostro caso invece la tartaruga rimane dove si trova dopo avere terminato di disegnare l'ultimo lato del quadrato. Effettivamente il comportamento di SQUARE sembra essere preferibile ma non è difficile far fare la stessa cosa alla nostra istruzione QUADRATO, ecco come:
{| class="wikitable"
|-
Riga 113:
SHOWTURTLE
TO QUADRATO LATO
ANGOLO = 90 ; angoli internidi quadratodeviazione
PENUP ; alzo la penna
FORWARD LATO/2 ; mi dirigo su lato che ho di fronte
Riga 127:
FORWARD LATO ; disegno il quarto lato
RIGHT ANGOLO ; giro a destra
FORWARD LATO/2 : ; disegno la metà rimanente dedel quarto lato
RIGHT ANGOLO : ; giro a destra (per tornaredirigersi nelverso il centro del quadrato)
PENUP ; alzo la penna
FORWARD LATO/2 ; torno nel centro del quadrato
LEFT ANGOLO*2 ; mi rigiro nella direzione in cui mi trovavo inzialmenteinizialmente
END
QUADRATO 100
Riga 142:
[[File:IncapsulareLO_04.svg|380px|senza_cornice]]
 
La tartaruga è rivolta a destra perché per disegnare il secondo quadrato ha viaggiato da sinistra verso destra. Per rendere il comportamento dell'istruzione RETTANGOLO proprio identico a quello di SQUARE si dovrebbe intervenire anche sul colore del riempimento, mentre con il codice che abbiamo scritto questo non accade. Potremmo fare anche questo, utilizzando le istruzioni FILL e FILCOLORFILLCOLOR, che abbiamo già visto. Lasciamo questa modifica come esercizio, per chi lo voglia fare.
 
Si può obiettare che tutto questo lavoro sia inutile, visto che serve a fare una cosa che in LibreLogo già esiste. L'intento è primariamente pedagogico: le cose si spiegano bene a partire da esempi semplici; inoltre, è interessante constatare come si possano costruire da soli parti di un sistema che esistono già, perché questo ci aiuta ad acquistare fiducia e, al tempo stesso, a rendersi conto che il sistema che stiamo usando non è chiuso e composto di una materia inaccessibile; infine, ci rendiamo conto di poter contribuire al sistema stesso, magari anche costruendo delle varianti di istruzioni preesistenti – ad esempio, potrebbe esserci utile una versione dell'istruzione SQUARE che oltre alla dimensione del lato accetti anche il colore con il quale questo debba essere dipinto, o magari anche il colore del contorno. Qui si introduce un'altra generalizzazione: possiamo definire subroutine con più di un argomento. Per esempio possiamo provare a definire un'istruzione rettangolo, che possa essere invocata così: RETTANGOLO A B, dove A rappresenta il lato orizzontale e B quello breveverticale. Lasciamo come esercizio le variazioni da apportare alla subroutine QUADRATO vista sopra, per ottenere una subroutine RETTANGOLO, nel modo accennato. Come lasciamo per esercizio la possibilità di introdurre il controllo dei colori, sia nella funzione QUADRATO che RETTANGOLO.
 
Ovviamente, se può avere senso la creazione di varianti di istruzioni esistenti, a maggiomaggior ragione, ne avrà la creazione di nuovi. Non c'è limite a quello che possiamo pensare di incapsulare in una subroutine. Prendiamo per esempio il codice che avevamo scritto a pagina 15 e proviamo a incapsularlo in una subroutine:
{| class="wikitable"
|-
Riga 225:
|}
 
Il codice della subroutine <span style="color:#ff0000;">'''CASA'''</span> è lo stesso di prima eccetto per la presenza dell'argomento <span style="color:#ff00ff;">'''LATO'''</span>. Nello script l'istruzione <span style="color:#ff0000;">'''CASA '''</span>viene chiamata tre volte, sempre con dimensioni diverse. La posizione viene controllata mediante sequenze di istruzioni del tipo '''PENUP POSITION [150, 400] HEADING 0 PENDOWN''': alzo la penna, mi trasferisco nel punto di coordinate [150, 400] (peerper esempio), mmimi dirigo in su, riabbasso la penna. Ecco il risultato:
 
[[File:IncapsulareLO_05.svg|380px|senza_cornice]]
 
Non c'è limite alla fantasia. Non è difficile scrivere una subroutine che disegni un albero e usarla per arricchire così il paesaggio. Lo proponiamo come esercizio dopo, ma prima vediamo un altro esempio più avanzato, intendendo con questo che potrebbe essere utilizzato in un contesto di scuola secondaria superiore (la descrizione che segue è molto dettagliata, chi non è interessato a un contesto del genere e non ha dimestichezza con questo livello di conoscenzaconoscenze matematiche, salti senz'altro l'esempio!). Riprendiamo le successioni di poligoni che avevamo visto a pag. 45 e 46. Lì avevamo rappresentato la successione incolonnando i poligoni. L'idea ora è di sovrapporli anziché incolonnarli, in modo da apprezzare l'evoluzione verso il cerchio al crescere del numero dei lati. Scegliamo di costruire i poligoni inscritti in un cerchio di raggio dato, formando così la successione dei poligoni inscritti nel cerchio. Potremmo egualmente considerare la successione dei poligoni circoscritti al cerchio. Nel primo caso il parametro chiave è il raggio dei poligoni, sempre eguale al raggio del cerchio in cui sono inscritti. Nel secondo sarebbe invece l'apotema, sempre eguale al raggio del cerchio che circoscrivono. L'esempio che segue descrive il primo caso. Il codice che segue è commentato minuziosamente. Ciò nonostante descriviamo puntualmente la struttura del codice e il procedimento.
 
Intanto l'esercizio utilizza, in un contesto un po' più complicato, i tre costrutti fondamentali del software che abbiamo sin qui introdotto: le variabili e le operazioni fra di esse, le ripetizioni di sequenze di istruzioni e l'incapsulamento di sezioni di codice nelle subroutine. Abbiamo mantenuto l'evidenziazione cromatica che abbiamo usato in alcuni degli esempi precedenti, per aiutare la lettura del codice. Nella prima sezione (in nero) si eseguono le operazioni preparatorie: cancellazione del foglio, tartaruga a casa, tartaruga invisibile (sarebbe troppo “invasiva” su un disegno più articolato come questo), penna alzata; inoltre si fissano i parametri necessari per iniziare, ovvero numero dei poligoni che dovranno comporre la successione, e raggio dei poligoni, espresso in punti. Poi viene il codice della subroutine '''POLIGONO''', con le istruzioni in blu, eccetto il nome della subroutine in rosso e i suoi argomenti in viola. La subroutine '''POLIGONO''' richiede 5 argomenti: X0P e Y0P sono le coordinate del centro del poligono, che possiamo quindi piazzare dove vogliamo; N è il numero di lati che deve avere il poligono; R è il raggio del poligono. All'interno della subroutine '''POLIGONO''' si sviluppa la geometria. Si calcola l'ampiezza degli angoli interni '''AI''', l'ampiezza degli angoli supplementari degli angoli '''AI''', che chiamiamo '''A''' e la lunghezza dei lati '''L'''. Qui troviamo una novità, anzi due: '''SIN''' e '''ABS''' sono funzioni matematiche e '''PI''' è una costante. Scopriamo quindi che LibreLogo “sa” un bel po' di matematica! '''PI''' è una variabile speciale, per meglio dire una costante, la più importante della matematica: il '''π''' (pi greco), di cui LibreLogo esprime un'approssimazione con 15 cifre decimali (provare ad eseguire l'istruzione '''PRINT PI''')<ref>Ricordiamo che '''π''' rappresenta il rapporto fra la misura della circonferenza e il raggiodiametro di un cerchio, e che si tratta di numero irrazionale, quindi con un numero infinito di cifre decimali. </ref>. Invece '''SIN''' e '''ABS''' sono funzioni matematiche: '''SIN''' calcola il valore della funzione trigonometrica seno e richiede un argomento espresso in radianti, per esempio '''SIN PI''' fornisce il valore '''0; ABS''' calcola il valore assoluto dell'argomento, ovvero se è positivo lo lo lascia positivo mentre se è negativo lo trasforma in positivo. Successivamente vengono le istruzioni che disegnano il poligono, ovvero il viaggio della tartaruga. In sintesi, la tartaruga va nel centro indicato, di coordinate '''[X0P, Y0P]''', si volge in alto e percorre senza disegnare il raggio, gira a destra di 90° (questa è la direzione della tangente al cerchio circoscritto), poi gira di quanto basta per allinearsi al primo lato del poligono (si poteva girare in un sol colpo verso questa direzione, ma abbiamo lasciato il codice in questa forma sotto-ottimale per chiarire la geometria). A questo punto si abbassa la penna e si iniziano a disegnare i lati in successione, mediante il semplice ciclo '''REPEAT N [FORWARD L RIGHT A]'''. Le istruzioni finali all'interno della subroutine servono a scrivere un'etichetta, poco sotto al centro del poligono, con il numero di lati. Siccome è un codice che ci mette un certo tempo a girare (ovviamente questo dipende anche dal computer che si usa), quando il numero di lati diventa elevato, è utile per sapere a che punto si trova il processo – noi abbiamo provato fino a 500 lati. Da segnalare qui l'uso della variabile riservata (in LibreLogo) di '''REPCOUNT''', che è il contatore di cicli. Inoltre, si usa la funzione '''STR''' che serve a trasformare il valore di '''REPCOUNT''', che è un numero espresso internamente al computer in binario, nell'espressione alfanumerica del medesimo, che possa essere stampata sul foglio come qualsiasi altro testo<ref>Questa è una nozione che a qualcuno può sembrare oscura. Molto in sintesi: una cosa sono i numeri espressi in un formato con il quale il computer possa fare i calcoli e un'altra sono i numeri espressi come caratteri, che possono essere inframezzati in un testo qualsiasi. Nel primo caso si tratta di una codifica per il computer che è binaria, l'unico modo che consenta al computer di fare operazioni matematiche. Nel secondo di tratta di una codifica che serve a rappresentare i caratteri sullo schermo, o in una stampa; questa è una codifica che ha una finalità puramente grafica e che il computer non può usare per fare i calcoli. Esistono molti tipi di codifiche, le più note delladelle quali sono ASCII E UNICODE. Chi desidera chiarimenti si può rivolgere all'autore di questo testo. </ref>. La stampa dell'etichetta è subordinata la fatto che si tratti dell'ultimo poligono. Questo controllo viene effettuato con l'istruzione di controllo '''IF''', descritta nel capitolo successivo. Dopo il codice della subroutine, di nuovo in nero, c'è lo ''script'' vero e proprio, molto semplice. Le tre istruzioni '''HOME''', '''X0P=POSITION[0]''' e '''Y0P=POSITION[1]''' servono per piazzare il centro dei poligoni nel centro del foglio, ma qui potremmo scegliere una qualsiasi altra posizione. Infine, la realizzazione della successione è affidata al ciclo '''REPEAT NP […]'''. Anche qui si usa il contatore di cicli, in questo caso, per chiamare la subroutine '''POLIGONO''' con il giusto numero di lati. Come dicevamo, questo script può richiedere del tempo, se fatto girare con un numero elevato di poligoni, diciamo da 10 in su, indipendenzain dipendenza della velocità del processore che equipaggia il computer. Se capita di farlo partire inavvertitamente con un numero di lati eccessivo, o se lo si vuole fermare per qualsiasi altro motivo, lo si può fare con il tasto STOP [[File:StopLO.png|senza_cornice]]. Se si supera il valore di circa 30 lati, si inizia a vedere un contorno apparentemente circolare. Più che si aumenta il numero di lati e più che la circolarità è “vera”.
{| class="wikitable"
|-
Riga 247:
'''NP = 20<nowiki>; </nowiki>numero poligoni'''
 
'''R <nowiki>= 100</nowiki><nowiki>; </nowiki>raggio poligoni – tengo fissafisso il raggio per tutti i poligoni cosicché risultano tutti inscritti nello stesso cerchio di raggio R'''
<div style="color:#000080;">'''<nowiki>; </nowiki>subroutine POLIGONO'''</div>
<div style="color:#000080;">'''<nowiki>; </nowiki>argomenti:X0P: X del centro del poligono'''</div>