• Non ci sono risultati.

Sviluppo del programma

Nel documento Pensare da informatico (pagine 67-70)

A questo punto sei gi`a in grado di leggere funzioni complete e capire cosa fanno. Inoltre se hai fatto gli esercizi che ti ho suggerito hai gi`a scritto qualche piccola funzione. A mano a mano che scriverai funzioni di complessit`a maggiore comin-cerai ad incontrare qualche difficolt`a soprattutto con gli errori di semantica e di esecuzione.

Per fare fronte a questi programmi via via pi`u complessi ti suggerisco una tecnica chiamata sviluppo incrementale. Lo scopo dello sviluppo incrementale `e evitare lunghe sessioni di debug, aggiungendo e testando continuamente piccole parti di codice alla volta.

Come programma di esempio supponiamo che tu voglia trovare la distanza tra due punti conoscendone le coordinate (x1, y1) e (x2, y2). Con il teorema di Pitagora sappiamo che la distanza `e

distanza =p(x2− x1)2+ (y2− y1)2 (5.1) La prima cosa da considerare `e l’aspetto che la funzione DistanzaTraDuePunti deve avere in Python chiarendo subito quali siano i parametri che si vogliono passare alla funzione e quale sia il risultato da ottenere: quest’ultimo pu`o es-sere tanto un valore numerico da utilizzare all’interno di una espressione o da assegnare ad una variabile, tanto una stampa a video o altro.

Nel nostro caso `e chiaro che le coordinate dei due punti sono i nostri parametri, e la distanza calcolata un valore numerico in virgola mobile.

Possiamo cos`ı delineare un primo abbozzo di funzione: def DistanzaTraDuePunti(x1, y1, x2, y2):

return 0.0

Ovviamente questa prima versione non calcola distanze, in quanto ritorna sem-pre 0. Ma `e gi`a una funzione sintatticamente corretta e pu`o essere eseguita: `e il caso di eseguire questo primo test prima di procedere a renderla pi`u complessa. Per testare la nuova funzione proviamo a chiamarla con dei semplici valori: >>> DistanzaTraDuePunti(1, 2, 4, 6)

0.0

Abbiamo scelto questi valori cos`ı che la loro distanza orizzontale `e 3 e quella verticale `e 4. Con il teorema di Pitagora `e facile vedere che il valore atteso `e pari a 5 (5 `e la lunghezza dell’ipotenusa di un triangolo rettangolo i cui cateti sono 3 e 4). Quando testiamo una funzione `e sempre utile conoscere il risultato di qualche caso particolare per verificare se stiamo procedendo sulla strada giusta. A questo punto abbiamo verificato che la funzione `e sintatticamente corretta e possiamo cos`ı cominciare ad aggiungere linee di codice. Dopo ogni aggiunta la testiamo ancora per vedere che non ci siano problemi evidenti. Dovesse presen-tarsi un problema almeno sapremo che questo `e dovuto alle linee inserite dopo l’ultimo test che ha avuto successo.

Un passo logico per risolvere il nostro problema `e quello di trovare le differenze x2− x1 e y2− y1. Memorizzeremo queste differenze in variabili temporanee chiamate dx e dy e le stamperemo a video.

def DistanzaTraDuePunti(x1, y1, x2, y2): dx = x2 - x1

dy = y2 - y1

print "dx vale", dx print "dy vale", dy return 0.0

Se la funzione lavora correttamente, quando la richiamiamo con i valori di prima dovremmo trovare che dx e dy valgono rispettivamente 3 e 4. Se i risultati coincidono siamo sicuri che la funzione carica correttamente i parametri ed elabora altrettanto correttamente le prime righe. Nel caso il risultato non fosse

48 Funzioni produttive

quello atteso, dovremo concentrarci solo sulle poche righe aggiunte dall’ultimo test e non sull’intera funzione.

Proseguiamo con il calcolo della somma dei quadrati di dx e dy: def DistanzaTraDuePunti(x1, y1, x2, y2):

dx = x2 - x1 dy = y2 - y1

DistQuadrata = dx**2 + dy**2

print "DistQuadrata vale ", DistQuadrata return 0.0

Nota come i due print che avevamo usato prima siano stati rimossi in quanto ci sono serviti per testare quella parte di programma ma adesso sarebbero inutili. Un codice come questo `e chiamato codice temporaneo perch´e `e utile durante la costruzione del programma ma alla fine deve essere rimosso in quanto non fa parte delle funzioni richieste alla versione definitiva della nostra funzione. Ancora una volta eseguiamo il programma. Se tutto funziona dovremmo trovare un risultato pari a 25 (la somma dei quadrati costruiti sui cateti di lato 3 e 4). Non ci resta che calcolare la radice quadrata. Se abbiamo importato il modulo matematico math possiamo usare la funzione sqrt per elaborare il risultato: def DistanzaTraDuePunti(x1, y1, x2, y2):

dx = x2 - x1 dy = y2 - y1

DistQuadrata = dx**2 + dy**2

Risultato = math.sqrt(DistQuadrata) return Risultato

Stavolta se tutto va bene abbiamo finito. Potresti anche stampare il valore di Risultatoprima di uscire dalla funzione con return.

Soprattutto all’inizio non dovresti mai aggiungere pi`u di poche righe di pro-gramma alla volta. Man mano che la tua esperienza di propro-grammatore cresce ti troverai a scrivere pezzi di codice sempre pi`u grandi. In ogni caso nelle prime fasi il processo di sviluppo incrementale ti far`a risparmiare un bel po’ di tempo. Ecco gli aspetti chiave del processo di sviluppo incrementale:

1. Inizia con un programma funzionante e fai piccoli cambiamenti: questo ti permetter`a di scoprire facilmente dove siano localizzati gli eventuali errori. 2. Usa variabili temporanee per memorizzare i valori intermedi, cos`ı da

po-terli stampare e controllare.

3. Quando il programma funziona perfettamente rimuovi le istruzioni tempo-ranee e consolida le istruzioni in espressioni composite, sempre che questo non renda il programma difficile da leggere.

Esercizio: usa lo sviluppo incrementale per scrivere una funzione chiamata Ipotenusa che ritorna la lunghezza dell’ipotenusa di un triangolo rettangolo, passando i due cateti come parametri. Registra ogni passo del processo di sviluppo man mano che esso procede.

5.3 Composizione

`

E possibile chiamare una funzione dall’interno di un’altra funzione. Questa capacit`a `e chiamata composizione.

Scriveremo ora una funzione che accetta come parametri il centro ed un punto sulla circonferenza di un cerchio e calcola l’area del cerchio.

Il centro del cerchio `e memorizzato nelle variabili xc e yc e le coordinate del pun-to sulla circonferenza in xp e yp. Il primo passo `e trovare il raggio del cerchio, che `e equivalente alla distanza tra i due punti: la funzione DistanzaTraDuePunti che abbiamo appena scritto servir`a proprio a questo:

Raggio = DistanzaTraDuePunti(xc, yc, xp, yp) Il secondo passo `e trovare l’area del cerchio e restituirla: Risultato = AreaDelCerchio(Raggio)

return Risultato

Assemblando il tutto in una funzione abbiamo: def AreaDelCerchio2(xc, yc, xp, yp):

Raggio = DistanzaTraDuePunti(xc, yc, xp, yp) Risultato = AreaDelCerchio(Raggio)

return Risultato

Abbiamo chiamato questa funzione AreaDelCerchio2 per distinguerla dalla fun-zione AreaDelCerchio definita in precedenza. Non possono esistere due funzioni con lo stesso nome all’interno di un modulo.

Le variabili temporanee Raggio e Risultato sono utili per lo sviluppo e il debug ma quando il programma funziona possiamo riscrivere la funzione in modo pi`u conciso componendo le chiamate alle funzioni:

def AreaDelCerchio2(xc, yc, xp, yp):

return AreaDelCerchio(DistanzaTraDuePunti(xc, yc, xp, yp)) Esercizio: scrivi una funzione Pendenza(x1, y1, x2, y2) che ri-torna il valore della pendenza della retta passante per i punti (x1, y1) e (x2, y2). Poi usa questa funzione in una seconda funzione chia-mata IntercettaY(x1, y1, x2, y2) che ritorna il valore delle or-dinate quando la retta determinata dagli stessi punti ha X uguale a zero.

Nel documento Pensare da informatico (pagine 67-70)

Documenti correlati