Vogliamo programmatori stupidi e pigri!

Post on 23-Jan-2018

143 views 0 download

Transcript of Vogliamo programmatori stupidi e pigri!

Laziness, Dumbness,

and Functions

“Good Programmers Are Lazy and Dumb”

http://blogoscoped.com/archive/2005-08-24-n14.html

Il programmatore deve essere pigro….● Perché sono così può evitare di scrivere codice lungo, monotono, ripetitivo,

duplicato. ● Perché il codice prodotto motivato dalla pigrizia permette di sviluppare codice

molto più in fretta (lasciando tempo per altre cose)

Il programmatore deve essere stupido….

● Perché se è troppo furbo (o almeno lo crede) smetterà di imparare● Perché se è troppo furbo (o almeno lo crede) smetterà di essere critico verso

il proprio lavoro

Real Life

Come diventare programmatori pigri e

stupidi?

Facendo pratica!“Practice makes perfect”

Primo trucchetto

int max=0;cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; printf(“Il massimo e’%d”,x);

Usare i cicli

int max=0;cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x;cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; printf(“Il massimo e’%d”,x)

int max=0,i=0;while(i<5) {cin>>x; if (max<x) max=x; i++; }printf(“Il massimo e’%d”,x)

Usare i cicli, ancora meglio

int max=0;cin>>x; if (max<x) max=x;cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x; cin>>x; if (max<x) max=x;printf(“Il massimo e’%d”,x)

int max=0,i;for (i=0;i<5;i++) {cin>>x; if (max<x) max=i; }printf(“Il massimo e’%d”,x)

Ma si può fare di meglio….usando le funzioni

A che servono le funzioni - RIUSABILITA’

Una volta scritta, una funzione può essere utilizzata più e più volte. Tanto che molte funzioni sono fornite dai compilatori proprio per questo motivo. Immaginate di NON avere la funzione “radice quadrata”....ogni volta dovreste riscrivere tutto daccapo, con grande noia e rischio di errore. Peggio ancora per funzioni come cin/scanf eccetera.

A che servono le funzioni - ASTRAZIONE Molto spesso i dettagli di una particolare operazione non ci interessano. L’importante non è che una funzione usi un algoritmo particolare, un certo linguaggio, ci importa che funzioni. In particolare dobbiamo sapere

1. Il NOME della funzione2. Che cosa fa.3. Che cosa dobbiamo comunicare alla funzione perché possa operare4. Che tipo di risultati ci restituisce

Esempio: Radice quadrata Molto spesso i dettagli di una particolare operazione non ci interessano. L’importante non è che una funzione usi un algoritmo particolare, un certo linguaggio, ci importa che funzioni. In particolare dobbiamo sapere

1. Il NOME della funzione: sqrt2. Che cosa fa: calcola la radice quadrata3. Che cosa dobbiamo comunicare alla funzione perché possa operare: un

numero positivo4. Che tipo di risultati ci restituisce: un valore (double) che contiene il

risultato.

FormalmenteMolto spesso i dettagli di una particolare operazione non ci interessano. L’importante non è che una funzione usi un algoritmo particolare, un certo linguaggio, ci importa che funzioni. In particolare dobbiamo sapere

1. NOME: sqrt2. DOCUMENTAZIONE: calcola la radice quadrata3. PARAMETRI IN INGRESSO: double (positivo)4. PARAMETRI IN USCITA (return): double

Applichiamolo qui: int main() { double a,b,c,x1,x2,delta; cout<<"Inserisci il valore di A:"; cin>>a; cout<<"Inserisci il valore di B:"; cin>>b; cout<<"Inserisci il valore di C:"; cin>>c; delta = ((b*b)-(4*a*c)); x1 = (-(b)-(sqrt (delta))) /(2*a); x2 = (-(b)+(sqrt (delta))) /(2*a);

if (delta == 0) cout<<"Le soluzioni sono coincidenti: x1:"<<x1<<" x2:"<<x2<<endl; else if (delta < 0) cout<<"Non ci sono soluzioni reali"<<endl; else cout<<"Le soluzioni sono: x1:"<<x1<<" x2:"<<x2<<endl; }

Applichiamolo qui: int main() { double a,b,c,x1,x2,delta; cout<<"Inserisci il valore di A:"; cin>>a; cout<<"Inserisci il valore di B:"; cin>>b; cout<<"Inserisci il valore di C:"; cin>>c; delta = ((b*b)-(4*a*c)); x1 = (-(b)-(sqrt (delta))) /(2*a); x2 = (-(b)+(sqrt (delta))) /(2*a);

if (delta == 0) cout<<"Le soluzioni sono coincidenti: x1:"<<x1<<" x2:"<<x2<<endl; else if (delta < 0) cout<<"Non ci sono soluzioni reali"<<endl; else cout<<"Le soluzioni sono: x1:"<<x1<<" x2:"<<x2<<endl; }

Applichiamolo qui: int main() { double a,b,c,x1,x2,delta; cout<<"Inserisci il valore di A:"; cin>>a; cout<<"Inserisci il valore di B:"; cin>>b; cout<<"Inserisci il valore di C:"; cin>>c; delta = ((b*b)-(4*a*c)); x1 = (-(b)-(sqrt (delta))) /(2*a); ….

double inserisci() {double valore;cout <<"Inserisci il valore: "; cin>>valore; return valore;}

Applichiamolo qui: int main() { double a,b,c,x1,x2,delta; a=inserisci(); b=inserisci();c=inserisci();delta = ((b*b)-(4*a*c)); x1 = (-(b)-(sqrt (delta))) /(2*a); ….

double inserisci() {double valore;cout <<"Inserisci il valore: "; cin>>valore; return valore;}

Applichiamolo qui: int main() { double a,b,c,x1,x2,delta; a=inserisci(); b=inserisci();c=inserisci();delta = ((b*b)-(4*a*c)); x1 = (-(b)-(sqrt (delta))) /(2*a); ….

double inserisci(char lettera) {double valore;cout <<"Inserisci il valore: "<<lettera<<” ”; cin>>valore; return valore;}

Applichiamolo qui: int main() { double a,b,c,x1,x2,delta; a=inserisci(‘A’); b=inserisci(‘B’);c=inserisci(‘C’);delta = ((b*b)-(4*a*c)); x1 = (-(b)-(sqrt (delta))) /(2*a); ….

double inserisci(char lettera) {double valore;cout <<"Inserisci il valore: "<<lettera<<” ”; cin>>valore; return valore;}

Pensarci prima, durante o dopo?...dipende...

Prima: approccio top-down (metodo “Hitler”)Si prende un problema e si cerca di “spaccarlo” un problema difficile in tanti problemi più facili, scomponendo il problema principale in problemi che sappiamo risolvere.

Se un passo è troppo difficile, scomponiamolo ancora. Molto intuitivo.

Modello di sviluppo tradizionale, tipico del C e dei linguaggi procedurali (Fortran, Pascal, C/C++)

Richiede di aver capito bene il problema generale. Può generare passi inutili o si rischia di perdersi.

Stampa la media di N numeri interi

leggi_N;

leggi N numeri e calcolane la somma;

calcola media;

stampa_risultato;

Stampa la media di N numeri interi

leggi_N;

leggi N numeri e calcolane la somma

calcola media;

stampa_risultato;

Stampa la media di N numeri interi

leggi_N;

leggi N numeri e calcolane la somma

calcola media;

stampa_risultato;

int leggi_N();

int leggi_somma(N);

double c_media(N,somma);

void stampa(media);

Stampa la media di N numeri interi

leggi_N;

leggi N numeri e calcolane la somma

calcola media;

stampa_risultato;

int leggi_N();

int leggi_somma(N);

double c_media(N,somma);

void stampa(media);

void main() {int n; double somma,media;n=leggi_N();somma=leggi_somma(N);media=c_media(n,somma);stampa(media);

}

Dopo: approccio bottom-up (metodo “Minecraft”)Si considera un problema esaminando un singolo aspetto in grande dettaglio. “Per fare un tavolo ci vuole il legno, per fare il legno ci vuole l'albero, per fare l'albero ci vuole il seme…”

I componenti sono poi combinati per ottenere strumenti più complessi. Molto spesso i risultati sono riutilizzabili in altri programmi.

Modello di sviluppo a oggetti, tipico di Java, C#, Ruby

Spesso non si ha una visione di insieme. Mettere assieme i pezzi può risultare difficile.

Stampa la media di N numeri interi

stampare messaggi

calcolare il totale di una sequenza di N numeri

calcolare media

leggere un intero

Stampa la media di N numeri interi

stampare messaggi

calcolare il totale di una sequenza di N numeri

calcolare media

leggere un intero

void s_inserisci_numero;void st_media(double media);

double sommasequenza(int N);

double c_media(somma,N);

int leggi_intero(int N);

Stampa la media di N numeri interi

stampare messaggi

calcolare il totale di una sequenza di N numeri

calcolare media

leggere un intero

void s_inserisci_numero;void st_media(double media);

double sommasequenza(int N);

double c_media(somma,N);

int leggi_intero(int N);

void main() {int somma, n; double, media;s_inseriscinumero();n=inserisci_numero();somma=sommasequenza(n);media=c_media(n,somma);st_media(media);

}

Durante: approccio iterativo (metodo “Chaos”)Si crea una soluzione, che “più o meno va” e risolve “alcuni” problemi. Fatto questo, si migliora la soluzione (a) aggiungendo più risultati (b) risolvendo casi speciali/complicati (c) rendendo il codice più semplice.

Modello di sviluppo agile, utilizzato soprattutto nelle startup. Nella versione peggiore, si trasforma nel “Cowboy programming”, assolutamente da evitare.

Si tratta di un metodo che può confondere molto i programmatori principianti, per cui vi sconsiglio di applicarlo...per il momento. Ne riparleremo l’anno prossimo. O tra due. Remember, Chaos rulez!

Esercizi...per le vacanze!Prendete uno di questi problemi DIFFICILI. Scegliete un approccio TOP-DOWN o BOTTOM-UP. Scrivete quindi la strutturazione in funzioni, indicando anche i parametri. NON DOVETE SCRIVERE CODICE. Vi voglio pigri e stupidi (ma non troppo).

● Programma che gestisce il gioco dell’oca a 4 giocatori.● Programma che stampa tutte le tessere del domino, da ritagliare per giocarci. ● Programma che sceglie la miglior carta da giocare di una partita di briscola,

come primo o secondo giocatore, sapendo ○ Le carte in mano○ Le carte sul tavolo (incluso la briscola sul tavolo, e quante carte mancano)○ Quanti punti ho fatto○ Se sono il primo o il secondo giocatore.