Fondamenti di Informatica - Università degli studi di Parma
Fondamenti di Informatica - Università degli studi di Parma
Fondamenti di Informatica - Università degli studi di Parma
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Dipartimento <strong>di</strong> Ingegneria dell’Informazione<br />
<strong>Università</strong> <strong>degli</strong> Stu<strong>di</strong> <strong>di</strong> <strong>Parma</strong><br />
<strong>Fondamenti</strong> <strong>di</strong> <strong>Informatica</strong><br />
Algoritmi e Programmazione<br />
Monica Mordonini<br />
Alcune domande fondamentali<br />
• L’elaboratore come strumento in grado <strong>di</strong><br />
eseguire un’insieme <strong>di</strong> azioni elementari che<br />
vengono richieste tramite istruzioni scritte in<br />
un particolare linguaggio<br />
2 Quali istruzioni esegue un elaboratore?<br />
2 Quali problemi può risolvere un elaboratore?<br />
2 Che ruolo ha il linguaggio <strong>di</strong> programmazione?<br />
FI - Algoritmi e Programmazione 2<br />
Il problema <strong>di</strong> fondo<br />
Algoritmo<br />
• Descrizione <strong>di</strong> un problema<br />
þin<strong>di</strong>viduazione <strong>di</strong> un algoritmo<br />
‣ come si costruisce la soluzione ad un problema?<br />
‣ Quale è il giusto punto <strong>di</strong> partenza?<br />
‣ Quali metodologie o tecniche utilizzare?<br />
• Dall'arabo al-Khuwarizmi a sua volta dal greco<br />
aritmhós<br />
• Un algoritmo è un metodo generale che risolve in<br />
un tempo finito e con una sequenza finita <strong>di</strong><br />
mosse qualsiasi istanza <strong>di</strong> un dato problema <strong>di</strong><br />
elaborazione.<br />
• Problemi:<br />
q<br />
q<br />
q<br />
risolvibili<br />
non-risolvibili<br />
non-affrontabili<br />
FI - Algoritmi e Programmazione 3<br />
FI - Algoritmi e Programmazione 4<br />
Co<strong>di</strong>fica <strong>di</strong> un algoritmo<br />
• Fase <strong>di</strong> scrittura <strong>di</strong> un algoritmo attraverso un<br />
insieme or<strong>di</strong>nato <strong>di</strong> istruzioni scritte in un<br />
qualche linguaggio <strong>di</strong> programmazione, che<br />
specificano le azioni da completare<br />
Programma<br />
• Testo scritto in accordo alla sintassi e alla semantica <strong>di</strong><br />
un linguaggio <strong>di</strong> programmazione<br />
• Un programma può non essere un algoritmo (basta che la<br />
sequenza <strong>di</strong> mosse non sia finita cioè che il programma<br />
non termini)...<br />
• ... E tuttavia può essere molto utile (es. gestione<br />
semafori)<br />
• Un programma rappresenta l’insieme delle istruzioni che<br />
descrivono un processo espresse in un qualche<br />
linguaggio<br />
• Un processo trasforma un insieme <strong>di</strong> dati iniziali nei<br />
risultati finali me<strong>di</strong>ante una successione <strong>di</strong> azioni<br />
elementari<br />
FI - Algoritmi e Programmazione 5<br />
FI - Algoritmi e Programmazione 6
Esecuzione<br />
Elementi <strong>di</strong> un algoritmo<br />
• L’esecuzione delle azioni nell’or<strong>di</strong>ne<br />
specificato dall’algoritmo consente <strong>di</strong> ottenere<br />
a partire dai dati in ingresso i risultati che<br />
risolvono il problema<br />
• Problema: þ algoritmo þ programma<br />
• Passi elementari: azioni atomiche non<br />
scomponibili in azioni piú semplici<br />
• Processo o anche esecuzione: sequenza<br />
or<strong>di</strong>nata <strong>di</strong> passi<br />
metodo<br />
risolutivo<br />
linguaggio <strong>di</strong><br />
programmazione<br />
FI - Algoritmi e Programmazione 7<br />
FI - Algoritmi e Programmazione 8<br />
Algoritmo<br />
Algoritmo<br />
• Un algoritmo deve avere le seguenti proprietà :<br />
q<br />
q<br />
q<br />
q<br />
Finitezza: composto da un numero finito <strong>di</strong> passi elementari.<br />
Non ambiguità (determinismo): i risultati non variano in<br />
funzione della macchina/persona che esegue l'algoritmo.<br />
Realizzabilità: deve essere eseguibile con le risorse a<br />
<strong>di</strong>sposizione.<br />
Efficienza (auspicabile): eseguire il numero minimo <strong>di</strong><br />
operazioni<br />
• Per definire un algoritmo è necessario:<br />
q Condurre un'attenta analisi del problema ed<br />
eventualmente sud<strong>di</strong>videre il problema in piccoli<br />
sottoproblemi.<br />
q In<strong>di</strong>viduare i possibili ingressi e precisare le uscite<br />
(definizione dei dati).<br />
q Definire completamente e dettagliatamente la<br />
sequenza dei passi che portano alla soluzione.<br />
FI - Algoritmi e Programmazione 9<br />
FI - Algoritmi e Programmazione 10<br />
Algoritmo<br />
• Possiamo “trovare” algoritmi anche per la<br />
risoluzione <strong>di</strong> problemi non strettamente informatici<br />
• Esempi:<br />
q Spiegare un percorso stradale<br />
q Istruzioni per il montaggio <strong>di</strong> un mobile<br />
q Istruzioni per l’esecuzione <strong>di</strong> una torta<br />
• Un algoritmo può non essere l’unica soluzione al<br />
problema<br />
Il crivello <strong>di</strong> Eratostene<br />
• Si vogliono trovare tutti i numeri primi<br />
compresi fra 2 e n (In modo efficiente).<br />
1) Si costruisca una sequenza or<strong>di</strong>nata dei numeri fra<br />
2 e n.<br />
2) Si estragga il primo numero dalla sequenza. E’<br />
necessariamente un numero primo.<br />
3) Si eliminino dalla sequenza tutti i multipli del<br />
numero estratto al passo 2).<br />
4) se la sequenza non e’ vuota si torna la passo 2)<br />
altrimenti si termina.<br />
FI - Algoritmi e Programmazione 11<br />
FI - Algoritmi e Programmazione 12
Il crivello <strong>di</strong> Eratostene: esempio<br />
Il crivello <strong>di</strong> Erastone<br />
• Sequenza iniziale (da 2 a 20):<br />
2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20<br />
2 e’ primo lo elimino con tutti i suoi multipli:<br />
3,5,7,9,11,13,15,17,19<br />
3 e’ primo lo elimino con tutti i suoi multipli:<br />
5,7,11,13,17,19<br />
5 e’ primo lo elimino con tutti i suoi multipli:<br />
…<br />
19 e’ primo, la sequenza e’ vuota, termino.<br />
• Algoritmo<br />
q Finito<br />
q Non ambiguo<br />
q Realizzabile<br />
q Efficiente (si spera)<br />
FI - Algoritmi e Programmazione 13<br />
FI - Algoritmi e Programmazione 14<br />
Algoritmo <strong>di</strong> Euclide<br />
Algoritmo <strong>di</strong> Euclide<br />
• Calcola il massimo comun <strong>di</strong>visore fra due<br />
interi positivi m ed n (supponiamo che n =<br />
m, altrimenti li possiamo scambiare).<br />
• L’ algoritmo si compone <strong>di</strong> 3 passi ripetuti<br />
ciclicamente fino ad una con<strong>di</strong>zione <strong>di</strong><br />
arresto:<br />
• Passo E1 {ricerca del resto} : Sia m = n. Si<br />
<strong>di</strong>vide m per n. Sia r il resto. Allora 0 =<br />
r < n.<br />
• Passo E2 {r = 0?} : Se r = 0 l’ algoritmo e’<br />
terminato e n e’ la risposta finale.<br />
• Passo E3 {scambio} : Se r ? 0 si operano gli<br />
scambi m ? n e n ? r. Si torni al passo E1.<br />
FI - Algoritmi e Programmazione 15<br />
FI - Algoritmi e Programmazione 16<br />
Algoritmo <strong>di</strong> Euclide: esempio<br />
Si voglia l’ MCD fra 30 e 45 (I due numerivanno scambiati)<br />
m<br />
n<br />
r<br />
45<br />
30<br />
15<br />
30<br />
15<br />
0<br />
Algoritmo <strong>di</strong> Euclide: finitezza<br />
• Poiche’ al passo E1 {ricerca del resto} si ha<br />
senpre 0 = r < n, ad ogni scambio il valore <strong>di</strong><br />
n decresce.<br />
• Dopo un numero finito <strong>di</strong> passi si<br />
raggiungera` la con<strong>di</strong>zione r = 0, e la<br />
terminazione dell’ algoritmo.<br />
Poiche’ il restor = o, l’ultimovalore per n e’ l’ MCD<br />
FI - Algoritmi e Programmazione 17<br />
FI - Algoritmi e Programmazione 18
Algoritmo <strong>di</strong> Euclide: correttezza<br />
• Ad ogni passo abbiamo che m = q n + r (con<br />
q intero).<br />
• Se r ?0 ogni <strong>di</strong>visore <strong>di</strong> m,n <strong>di</strong>vide anche<br />
r=m-qn. D’altra parte anche ogni <strong>di</strong>visore <strong>di</strong><br />
n,r <strong>di</strong>vide m=qn+r.<br />
• In pratica la coppia m,n primo e dopo lo<br />
scambio m ? n e n ? r hanno lo stesso<br />
MCD.<br />
• Se r=0 l’ algoritmo termina e n e’ l’MCD.<br />
Algoritmo <strong>di</strong> Euclide<br />
• L’algoritmo descritto non è l’unico per<br />
risolvere il problema del MCD<br />
• Ma è il più efficiente se a priori non conosco<br />
nulla dei due numeri<br />
FI - Algoritmi e Programmazione 19<br />
FI - Algoritmi e Programmazione 20<br />
Calcolo MCD modo 2<br />
Calcolo MCD modo 3<br />
• Problema: dati due numeri determinare il<br />
loro massimo comune denominatore:<br />
q scomporre in fattori primi i due numeri<br />
q considerare solo fattori comuni<br />
q prendere quelli con esponente piú piccolo<br />
q moltiplicarli tra loro<br />
• Problema: dati due numeri determinare il loro<br />
massimo comun denominatore<br />
q costruire insieme <strong>di</strong>visori primo numero<br />
q costruire insieme <strong>di</strong>visori secondo numero<br />
q costruire intersezione fra i due insiemi<br />
q in<strong>di</strong>viduare nell'intersezione l'elemento piú grande<br />
FI - Algoritmi e Programmazione 21<br />
FI - Algoritmi e Programmazione 22<br />
Algoritmo<br />
• Per realizzare un algoritmo con un<br />
calcolatore occorre rappresentare la<br />
sequenza <strong>di</strong> passi che portano alla sua<br />
soluzione con istruzioni appartenenti ad un<br />
linguaggio <strong>di</strong> programmazione.<br />
Diagramma <strong>di</strong> Flusso<br />
(Flow-Chart)<br />
• I <strong>di</strong>agrammi <strong>di</strong> flusso sono un formalismo<br />
grafico per descrivere gli algoritmi.<br />
• I <strong>di</strong>agrammi <strong>di</strong> flusso scompongono in passi<br />
successivi gli algoritmi.<br />
• Un <strong>di</strong>agramma <strong>di</strong> flusso è una descrizione più<br />
efficace e meno ambigua <strong>di</strong> una descrizione<br />
a parole.<br />
FI - Algoritmi e Programmazione 23<br />
FI - Algoritmi e Programmazione 24
Diagrammi <strong>di</strong> flusso<br />
Diagramma <strong>di</strong> flusso<br />
• Le operazioni su cui si basa un <strong>di</strong>agramma <strong>di</strong><br />
flusso<br />
q Ingresso/Uscita dati<br />
q Trasferimento <strong>di</strong> informazione (Assegnamenti)<br />
q Calcolo <strong>di</strong> espressioni aritmetiche e logiche<br />
q Assunzione <strong>di</strong> decisioni<br />
q Esecuzione <strong>di</strong> iterazioni (Cicli)<br />
q Possono contenere costanti e variabili<br />
• Un <strong>di</strong>agramma <strong>di</strong> flusso è costituito da due<br />
tipi <strong>di</strong> entità:<br />
q No<strong>di</strong><br />
q Archi<br />
FI - Algoritmi e Programmazione 25<br />
FI - Algoritmi e Programmazione 26<br />
Strutture <strong>di</strong> Controllo<br />
Programmazione Strutturata<br />
I<br />
I<br />
I<br />
No/Si<br />
Si/No No/Si<br />
Si/No<br />
No/Si Si/No<br />
O<br />
O<br />
O<br />
While - Do Repeat - Until If - Then - Else<br />
• Si compone <strong>di</strong> sequenze, decisioni (if then, if<br />
then else) e cicli (while-do, repeat until).<br />
• Ogni <strong>di</strong>agramma ha esattamente un ingresso<br />
ed una uscita.<br />
• Ogni azione puo essere<br />
q una azione semplice<br />
q una azione composta da altri <strong>di</strong>agrammi<br />
strutturati<br />
FI - Algoritmi e Programmazione 27<br />
FI - Algoritmi e Programmazione 28<br />
Tipi <strong>di</strong> No<strong>di</strong><br />
Esempio: Somma <strong>di</strong> N Numeri<br />
Start<br />
Var1<br />
Var1 ← Espr1<br />
Start<br />
No<br />
I < N<br />
Si<br />
Inizio<br />
Lettura dati<br />
Elaborazione / Assegnamento<br />
N<br />
Stop<br />
Fine<br />
Var1<br />
Scrittura dati<br />
Si<br />
No<br />
Espr1 = Espr2<br />
Espr1 ≠ Espr2<br />
Espr1 > Espr2<br />
Espr1 ≥ Espr2<br />
Espr1 < Espr2<br />
Espr1 ≤ Espr2<br />
I ← 0<br />
Somma ← 0<br />
Somma<br />
Somma ← Somma + Var1<br />
I ← I + 1<br />
Decisione<br />
Stop<br />
FI - Algoritmi e Programmazione 29<br />
FI - Algoritmi e Programmazione 30
Esempio: Somma <strong>di</strong> Tre Numeri<br />
Programmazione Top-Down<br />
Start<br />
Var1<br />
Var2<br />
Somma ← Var1 +Var2 + Var3<br />
Somma<br />
• La programmazione top-down è una tecnica<br />
<strong>di</strong> programmazione per la realizzazione <strong>di</strong><br />
programmi con la scomposizione iterativa <strong>di</strong><br />
un problema in sotto-problemi.<br />
Var3<br />
Stop<br />
FI - Algoritmi e Programmazione 31<br />
FI - Algoritmi e Programmazione 32<br />
Tecniche <strong>di</strong> programmazione<br />
• Programmazione top-down:<br />
q scomposizione iterativa del problema in<br />
sottoproblemi<br />
q i sottoproblemi devono essere in<strong>di</strong>pendenti ed<br />
avere interfacce ben definite<br />
q visibilità dei dettagli <strong>di</strong> ogni sottoproblema solo<br />
all’interno del sottoproblema stesso<br />
Programmazione Top-Down<br />
• La programmazione top-down si presta molto bene<br />
per la definizione <strong>di</strong> algoritmi con i <strong>di</strong>agrammi <strong>di</strong><br />
flusso:<br />
q All’inizio il <strong>di</strong>agramma <strong>di</strong> flusso è rappresentato da un nodo<br />
che rappresenta la soluzione al problema.<br />
q Questo nodo viene scomposto in una rete <strong>di</strong> no<strong>di</strong> in modo<br />
iterativo.<br />
q La scomposizione termina quando i singoli no<strong>di</strong> possono<br />
essere rappresentati da semplici sequenze <strong>di</strong> istruzioni del<br />
linguaggio <strong>di</strong> programmazione scelto.<br />
FI - Algoritmi e Programmazione 33<br />
FI - Algoritmi e Programmazione 34<br />
Esempio: Somma <strong>di</strong> Tre Numeri<br />
Esempio: Somma <strong>di</strong> Tre Numeri<br />
Start<br />
Start<br />
Somma i tre numeri<br />
Stop<br />
Inizializzazione<br />
Leggi e somma i tre numeri<br />
Stampa la somma<br />
Stop<br />
FI - Algoritmi e Programmazione 35<br />
FI - Algoritmi e Programmazione 36
Esempio: Somma <strong>di</strong> N Numeri<br />
Start<br />
No<br />
I < N<br />
Si<br />
Problema della ricorsione<br />
N<br />
I ← 0<br />
Somma ← 0<br />
Somma<br />
Somma ← Somma + Var1<br />
I ← I + 1<br />
Stop<br />
FI - Algoritmi e Programmazione 37<br />
Il calcolo del fattoriale<br />
• La funzione fattoriale, molto usata nel calcolo<br />
combinatorio, è così definita<br />
⎧1<br />
n!<br />
= ⎨<br />
⎩n(<br />
n −1)!<br />
se n = 0<br />
se n > 0<br />
dove n è un numero intero non negativo<br />
Il calcolo del fattoriale<br />
• Ve<strong>di</strong>amo <strong>di</strong> capire cosa significa…<br />
0! = 1<br />
1! = 1(1-1)! = 1·0! = 1·1 = 1<br />
2! = 2(2-1)! = 2·1! = 2·1 = 2<br />
3! = 3(3-1)! = 3·2! = 3·2·1 = 6<br />
4! = 4(4-1)! = 4·3! = 4·3·2·1 = 24<br />
5! = 5(5-1)! = 5·4! = 5·4·3·2·1 = 120<br />
• Quin<strong>di</strong>, per ogni n intero positivo, il fattoriale <strong>di</strong> n è il<br />
prodotto dei primi n numeri interi positivi<br />
FI - Algoritmi e Programmazione 39<br />
FI - Algoritmi e Programmazione 40<br />
La ricorsione nella programmazione<br />
• Si invoca un metodo mentre si esegue lo stesso<br />
metodo<br />
• è un para<strong>di</strong>gma <strong>di</strong> programmazione che si chiama<br />
ricorsione<br />
e un metodo che ne faccia uso si chiama<br />
metodo ricorsivo<br />
• La ricorsione è uno strumento molto potente per<br />
realizzare alcuni algoritmi, ma è anche fonte <strong>di</strong> molti<br />
errori <strong>di</strong> <strong>di</strong>fficile <strong>di</strong>agnosi<br />
In un programma…<br />
• Ve<strong>di</strong>amo la sequenza usata per calcolare 3!<br />
si invoca factorial(3)<br />
factorial(3) invoca factorial(2)<br />
factorial(2) invoca factorial(1)<br />
factorial(1) invoca factorial(0)<br />
factorial(0) restituisce 1<br />
factorial(1) restituisce 1<br />
factorial(2) restituisce 2<br />
factorial(3) restituisce 6<br />
• Si crea quin<strong>di</strong> una lista LIFO (uno stack ) <strong>di</strong><br />
meto<strong>di</strong> “in attesa”, che si allunga e che poi si<br />
accorcia fino ad estinguersi<br />
FI - Algoritmi e Programmazione 41<br />
FI - Algoritmi e Programmazione 42
La ricorsione<br />
• Per capire come utilizzare correttamente la<br />
ricorsione, ve<strong>di</strong>amo innanzitutto come funziona<br />
• Quando un metodo ricorsivo invoca se stesso, la<br />
macchina virtuale esegue le stesse azioni che<br />
vengono eseguite quando viene invocato un<br />
metodo qualsiasi<br />
q sospende l’esecuzione del metodo invocante<br />
q esegue il metodo invocato fino alla sua<br />
terminazione<br />
q riprende l’esecuzione del metodo invocante dal<br />
punto in cui era stata sospesa<br />
La ricorsione<br />
• In ogni caso, anche se il meccanismo <strong>di</strong><br />
funzionamento della ricorsione può sembrare<br />
complesso, la chiave per un suo utilizzo proficuo<br />
è<br />
q <strong>di</strong>menticarsi come funziona la ricorsione, ma<br />
sapere come vanno scritti i meto<strong>di</strong> ricorsivi<br />
perché il tutto funzioni!<br />
• Esistono infatti due regole ben definite che vanno<br />
utilizzate per scrivere meto<strong>di</strong> ricorsivi che<br />
funzionino<br />
FI - Algoritmi e Programmazione 43<br />
FI - Algoritmi e Programmazione 44<br />
La ricorsione: caso base<br />
• Prima regola<br />
q il metodo ricorsivo deve fornire la soluzione<br />
del problema in almeno un caso particolare,<br />
senza ricorrere ad una chiamata ricorsiva<br />
q tale caso si chiama caso base della ricorsione<br />
q nel nostro esempio, il caso base era<br />
if (n == 0)<br />
return 1;<br />
q a volte ci sono più casi base, non è necessario<br />
che sia unico<br />
La ricorsione: passo ricorsivo<br />
• Seconda regola<br />
q il metodo ricorsivo deve effettuare la chiamata<br />
ricorsiva dopo aver semplificato il problema<br />
q nel nostro esempio, per il calcolo del fattoriale <strong>di</strong> n si<br />
invoca la funzione ricorsivamente per conoscere il<br />
fattoriale <strong>di</strong> n-1, cioè per risolvere un problema più<br />
semplice<br />
q<br />
if (n > 0)<br />
return n * factorial(n - 1);<br />
il concetto <strong>di</strong> “problema più semplice” varia <strong>di</strong> volta in<br />
volta: in generale, bisogna avvicinarsi ad un caso<br />
base<br />
FI - Algoritmi e Programmazione 45<br />
FI - Algoritmi e Programmazione 46<br />
La ricorsione: un algoritmo?<br />
• Le regole appena viste sono fondamentali<br />
per poter <strong>di</strong>mostrare che la soluzione<br />
ricorsiva <strong>di</strong> un problema sia un algoritmo<br />
q in particolare, che arrivi a conclusione in un<br />
numero finito <strong>di</strong> passi<br />
• Si potrebbe pensare che le chiamate<br />
ricorsive si possano succedere una dopo<br />
l’altra, all’infinito<br />
La ricorsione: un algoritmo?<br />
• Invece, se<br />
q ad ogni invocazione il problema <strong>di</strong>venta<br />
sempre più semplice e si avvicina al caso base<br />
q la soluzione del caso base non richiede<br />
ricorsione<br />
allora certamente la soluzione viene<br />
calcolata in un numero finito <strong>di</strong> passi, per<br />
quanto complesso possa essere il<br />
problema<br />
FI - Algoritmi e Programmazione 47<br />
FI - Algoritmi e Programmazione 48
Ricorsione infinita<br />
• Non tutti i meto<strong>di</strong> ricorsivi realizzano algoritmi<br />
q se manca il caso base, il metodo ricorsivo continua ad<br />
invocare se stesso all’infinito<br />
q se il problema non viene semplificato ad ogni<br />
invocazione ricorsiva , il metodo ricorsivo continua ad<br />
invocare se stesso all’infinito<br />
• Dato che la lista dei meto<strong>di</strong> “in attesa” si allunga<br />
indefinitamente, l’ambiente runtime esaurisce la<br />
memoria <strong>di</strong>sponibile per tenere traccia <strong>di</strong> questa<br />
lista, ed il programma termina con un errore<br />
Progetto: Torri <strong>di</strong> Hanoi<br />
FI - Algoritmi e Programmazione 49<br />
Torri <strong>di</strong> Hanoi: regole<br />
Torri <strong>di</strong> Hanoi: regole<br />
• Il rompicapo è costituito da tre pile <strong>di</strong> <strong>di</strong>schi (“torri”)<br />
allineate<br />
q all’inizio tutti i <strong>di</strong>schi si trovano sulla pila <strong>di</strong> sinistra<br />
q alla fine tutti i <strong>di</strong>schi si devono trovare sulla pila <strong>di</strong> destra<br />
• I <strong>di</strong>schi sono tutti <strong>di</strong> <strong>di</strong>mensioni <strong>di</strong>verse e quando si<br />
trovano su una pila devono rispettare la seguente<br />
regola<br />
q nessun <strong>di</strong>sco può avere sopra <strong>di</strong> sé <strong>di</strong>schi più gran<strong>di</strong><br />
Situazione iniziale<br />
Situazione finale<br />
FI - Algoritmi e Programmazione 51<br />
FI - Algoritmi e Programmazione 52<br />
Torri <strong>di</strong> Hanoi: regole<br />
Algoritmo <strong>di</strong> soluzione<br />
• Per risolvere il rompicapo bisogna spostare un<br />
<strong>di</strong>sco alla volta<br />
q un <strong>di</strong>sco può essere rimosso dalla cima della torre<br />
ed inserito in cima ad un’altra torre<br />
• non può essere “parcheggiato” all’esterno…<br />
q in ogni momento deve essere rispettata la regola<br />
vista in precedenza<br />
• nessun <strong>di</strong>sco può avere sopra <strong>di</strong> sé <strong>di</strong>schi<br />
più gran<strong>di</strong><br />
• Per il rompicapo delle Torri <strong>di</strong> Hanoi è noto un<br />
algoritmo <strong>di</strong> soluzione ricorsivo<br />
• Il problema generale consiste nello spostare n <strong>di</strong>schi<br />
da una torre ad un’altra, usando la terza torre come<br />
deposito temporaneo<br />
• Per spostare n <strong>di</strong>schi da una torre all’altra si<br />
suppone <strong>di</strong> saper spostare n-1 <strong>di</strong>schi da una torre<br />
all’altra, come sempre si fa nella ricorsione<br />
• Per descrivere l’algoritmo identifichiamo le torri con i<br />
numeri interi 1, 2 e 3<br />
FI - Algoritmi e Programmazione 53<br />
FI - Algoritmi e Programmazione 54
Algoritmo ricorsivo<br />
• Il caso base si ha quando n vale 1, in questo<br />
caso possiamo spostare liberamente il <strong>di</strong>sco da<br />
una torre ad un’altra<br />
• Per spostare n <strong>di</strong>schi dalla torre 1 alla torre 3<br />
1 gli n-1 <strong>di</strong>schi in cima alla torre 1 vengono spostati sulla<br />
torre 2, usando la torre 3 come deposito temporaneo (si<br />
usa una chiamata ricorsiva, al termine della quale la<br />
torre 3 rimane vuota)<br />
2 il <strong>di</strong>sco rimasto nella torre 1 viene portato nella torre 3<br />
3 gli n-1 <strong>di</strong>schi in cima alla torre 2 vengono spostati sulla<br />
torre 3, usando la torre 1 come deposito temporaneo (si<br />
usa una chiamata ricorsiva, al termine della quale la<br />
torre 1 rimane vuota)<br />
Algoritmo ricorsivo<br />
• Si basa sul Principio <strong>di</strong> induzione<br />
• Il principio <strong>di</strong> induzione <strong>di</strong>ce che una<br />
proprietà è vera per qualsiasi valore <strong>di</strong> n<br />
se<br />
q è vera per n = 1, e<br />
q nell’ipotesi che sia vera per un dato valore <strong>di</strong> n<br />
= n’ siamo capaci <strong>di</strong> <strong>di</strong>mostrare che è vera<br />
per n = n’ +1<br />
FI - Algoritmi e Programmazione 55<br />
FI - Algoritmi e Programmazione 56<br />
La “Torre <strong>di</strong> Hanoi”<br />
Algoritmo Hanoi(n, da, a, int)<br />
input: il numero <strong>di</strong> <strong>di</strong>chi n, il<br />
perno <strong>di</strong> partenza, <strong>di</strong> arrivo e<br />
interme<strong>di</strong>o<br />
output: le mosse necessarie<br />
if n = 1 then<br />
muovi (1, da, a)<br />
else<br />
hanoi (n-1, da, int, a)<br />
muovi (n, da, a)<br />
hanoi (n-1, int, a, da)<br />
FI - Algoritmi e Programmazione 57<br />
FI - Algoritmi e Programmazione 58<br />
1<br />
10<br />
30<br />
2<br />
10<br />
20<br />
1<br />
30<br />
20<br />
3<br />
10<br />
30<br />
1<br />
20<br />
10<br />
2<br />
20<br />
30<br />
1<br />
10<br />
30<br />
mosse<br />
10 20 30<br />
Algoritmo ricorsivo<br />
• Si può <strong>di</strong>mostrare che il numero <strong>di</strong> mosse<br />
necessarie per risolvere il rompicapo con<br />
l’algoritmo proposto è pari a:<br />
2 n – 1<br />
• Il tempo necessario alla soluzione è<br />
proporzionale al numero <strong>di</strong> mosse (ogni mossa<br />
richiede un tempo costante) cioe’:<br />
T(n) = 2 n – 1<br />
FI - Algoritmi e Programmazione 59<br />
FI - Algoritmi e Programmazione 60
La torre <strong>di</strong> Brahama<br />
• Torre <strong>di</strong> Hanoi con 64 <strong>di</strong>schi<br />
• Una leggenda narra che alcuni monaci<br />
bud<strong>di</strong>sti in un tempio dell’Estremo Oriente<br />
siano da sempre impegnati nella soluzione<br />
del rompicapo, spostando fisicamente i loro<br />
64 <strong>di</strong>schi da una torre all’altra, consapevoli<br />
che quando avranno terminato il mondo finirà<br />
Quando finirà il mondo?<br />
Dipende..<br />
FI - Algoritmi e Programmazione 61<br />
Torri <strong>di</strong> Hanoi: la leggenda<br />
2 64 −1<br />
• Sono necessarie mosse, che sono circa 16 miliar<strong>di</strong> <strong>di</strong><br />
miliar<strong>di</strong> <strong>di</strong> mosse… cioè circa<br />
18<br />
• Supponendo che i monaci facciamo una mossa ogni minuto,<br />
essi fanno circa 500000 mosse all’anno, quin<strong>di</strong> il mondo finirà<br />
tra circa 30 mila miliar<strong>di</strong> <strong>di</strong> anni…<br />
• Un processore ad 1GHz che fa una mossa ad ogni intervallo<br />
<strong>di</strong> clock (un miliardo <strong>di</strong> mosse al secondo…) impiega 16<br />
miliar<strong>di</strong> <strong>di</strong> secon<strong>di</strong>, che sono circa 500 anni...<br />
1 .6× 10<br />
Linguaggi <strong>di</strong> programmazione<br />
FI - Algoritmi e Programmazione 63<br />
Linguaggi <strong>di</strong> Programmazione<br />
• Un linguaggio <strong>di</strong> programmazione è una<br />
notazione formale per descrivere algoritmi<br />
• Un programma è la descrizione <strong>di</strong> un<br />
algoritmo in un particolare linguaggio <strong>di</strong><br />
programmazione<br />
2 Quali “parole chiave”<br />
2 Quali meccanismi <strong>di</strong> combinazione?<br />
Linguaggi <strong>di</strong> Programmazione: Sintassi<br />
& Semantica<br />
• Sintassi: l’insieme <strong>di</strong> regole formali per la scrittura<br />
<strong>di</strong> programmi in un linguaggio, che dettano le<br />
modalità per costruire frasi corrette nel linguaggio<br />
stesso<br />
• Semantica: l’insieme dei significati da attribuire<br />
alle frasi (sintatticamente corrette) costruite nel<br />
linguaggio.<br />
• n.b. Una frase può essere sintatticamente corretta<br />
e tuttavia non avere significato<br />
FI - Algoritmi e Programmazione 65<br />
FI - Algoritmi e Programmazione 66
Sintassi e Semantica<br />
Sintassi<br />
• Dopo la definizione <strong>di</strong> un linguaggio (con<br />
sintassi e semantica) serve un sistema che<br />
possa eseguire i programmi scritti in tale<br />
linguaggio<br />
• Si parla <strong>di</strong> implementazione <strong>di</strong> un linguaggio<br />
q generalmente è un traduttore verso il linguaggio<br />
dell’elaboratore<br />
• Per definire la sintassi <strong>di</strong> un linguaggio, è<br />
necessario definire le grammatiche<br />
• La grammatica è un insieme <strong>di</strong> regole che<br />
servono per costruire una frase<br />
FI - Algoritmi e Programmazione 67<br />
FI - Algoritmi e Programmazione 68<br />
Grammatica<br />
• La grammatica è definita da:<br />
q un alfabeto <strong>di</strong> simboli terminal (l'alfabeto del linguaggio)<br />
q un alfabeto <strong>di</strong> simboli non terminali<br />
q un simbolo iniziale S (o assioma)<br />
q un insieme finito <strong>di</strong> regole sintattiche<br />
• Data una grammatica, il linguaggio generato è<br />
definito come l'insieme delle frasi derivabili a partire<br />
dall'assioma S<br />
q<br />
Le frasi <strong>di</strong> un linguaggio <strong>di</strong> programma-zione sono dette<br />
programmi<br />
Linguaggi <strong>di</strong> Programmazione<br />
• Diversi tipi <strong>di</strong> linguaggi:<br />
q Imperativi<br />
q Funzionali<br />
q Dichiarativi<br />
• Tutti basati sulla traduzione nell'unico<br />
linguaggio eseguibile dal calcolatore:<br />
il Linguaggio Macchina<br />
FI - Algoritmi e Programmazione 69<br />
FI - Algoritmi e Programmazione 70<br />
Linguaggi <strong>di</strong> Programmazione<br />
• I linguaggi macchina forniscono solo le<br />
operazioni che l'elaboratore può eseguire:<br />
q Operazioni molto elementari.<br />
q Diverse per ogni processore.<br />
q Scritte in linguaggio binario<br />
• Sono più orientati alla macchina che ai<br />
problemi da trattare.<br />
Linguaggi <strong>di</strong> Programmazione<br />
• Una prima evoluzione sono i linguaggi<br />
assemblativi che sostituiscono i co<strong>di</strong>ci binari<br />
con co<strong>di</strong>ci simbolici.<br />
q ancora orientati alla macchina e non ai problemi<br />
q più imme<strong>di</strong>ati da utilizzare<br />
q definiscono variabili, simboli<br />
START: MOV AX, BX<br />
CMP AX, 12h<br />
JZ EQUAL<br />
INT 21h<br />
RET<br />
EQUAL: MOV BL, 82h<br />
FI - Algoritmi e Programmazione 71<br />
FI - Algoritmi e Programmazione 72
Linguaggi <strong>di</strong> Programmazione<br />
Linguaggi <strong>di</strong> Programmazione<br />
• I linguaggi macchina e i linguaggi<br />
assemblativi sono detti linguaggi a basso<br />
livello.<br />
• I cosiddetti linguaggi ad alto livello permettono:<br />
q La descrizione del problema in modo intuitivo,<br />
<strong>di</strong>menticandosi che verranno eseguiti da un calcolatore.<br />
q Una astrazione rispetto al calcolatore su cui verrà eseguito<br />
il programma.<br />
• Ma devono essere tradotti in linguaggio macchina.<br />
FI - Algoritmi e Programmazione 73<br />
FI - Algoritmi e Programmazione 74<br />
Linguaggi <strong>di</strong> Programmazione<br />
Linguaggi Imperativi<br />
• Esistono <strong>di</strong>versi tipi <strong>di</strong> linguaggi ad alto livello:<br />
q<br />
q<br />
q<br />
q<br />
Linguaggi imperativi<br />
Linguaggi logici<br />
Linguaggi funzionali<br />
Linguaggi orientati agli oggetti<br />
• Ognuno provvede le forme espressive appropriate<br />
per alcuni problemi specifici.<br />
• Un linguaggio imperativo è legato all’architettura<br />
della macchina <strong>di</strong> Von Neumann, ma ad un livello <strong>di</strong><br />
astrazione vicino a quello dei <strong>di</strong>agrammi <strong>di</strong> flusso.<br />
• Un programma è una sequenza <strong>di</strong> istruzioni in cui:<br />
q Le istruzioni vengono eseguite in sequenza.<br />
q La sequenza può essere alterata con istruzioni <strong>di</strong> salto.<br />
• Eseguono 3 tipi <strong>di</strong> operazioni:<br />
q trasferimento dati<br />
q operazioni aritmetiche<br />
q alterazione del flusso del programma<br />
FI - Algoritmi e Programmazione 75<br />
FI - Algoritmi e Programmazione 76<br />
Linguaggi Imperativi<br />
Linguaggi Logici<br />
• Le operazioni che effettuano le istruzioni si basano<br />
sul concetto <strong>di</strong> variabile.<br />
• Una variabile è una astrazione del concetto <strong>di</strong><br />
locazione <strong>di</strong> memoria in cui può essere assegnato,<br />
letto e mo<strong>di</strong>ficato un valore.<br />
• Il C, Fortran, Pascal, Cobol e Basic sono i linguaggi<br />
imperativi più <strong>di</strong>ffusi.<br />
• Basati sulla logica<br />
q obiettivo: formalizzare il ragionamento<br />
q caratterizzati da meccanismi deduttivi<br />
• Programmare significa:<br />
q descrivere il problema con formule del linguaggio<br />
q interrogare il sistema, che effettua deduzioni sulla<br />
base delle definizioni<br />
FI - Algoritmi e Programmazione 77<br />
FI - Algoritmi e Programmazione 78
Linguaggi Logici<br />
Linguaggi Logici<br />
• In un linguaggio logico un programma è composto<br />
da una base <strong>di</strong> conoscenza contenente:<br />
q<br />
q<br />
Una descrizione del dominio del problema composta da un<br />
insieme <strong>di</strong> fatti.<br />
Un insieme <strong>di</strong> regole per manipolare l’insieme dei fatti.<br />
• L’esecuzione <strong>di</strong> un programma corrisponde<br />
all’applicazione delle regole sui fatti della base <strong>di</strong><br />
conoscenza:<br />
q L’esecuzione è guidata da un motore inferenziale.<br />
q L’esecuzione è attivata da una interrogazione dell’utente.<br />
q Lo scopo dell’esecuzione è verificare che l’interrogazione<br />
dell’utente è vera o falsa.<br />
• Il linguaggio più conosciuto è il Prolog.<br />
FI - Algoritmi e Programmazione 79<br />
FI - Algoritmi e Programmazione 80<br />
Linguaggi Funzionali<br />
• Linguaggi basati sul concetto <strong>di</strong> funzione e <strong>di</strong><br />
applicazione <strong>di</strong> una funzione ad argomenti; per<br />
questa ragione essi sono anche detti linguaggi<br />
applicativi<br />
• In un linguaggio funzionale un programma è visto<br />
come una funzione matematica.<br />
• L’esecuzione <strong>di</strong> un programma corrisponde alla<br />
valutazione della funzione rispetto ai suoi argomenti.<br />
Linguaggi Funzionali<br />
• La <strong>di</strong>fferenze maggiori con un linguaggio imperativo<br />
sono:<br />
q Non esiste il concetto <strong>di</strong> variabile: il calcolo è basato sul<br />
calcolo <strong>di</strong> valori e non sull'assegnamento <strong>di</strong> valori a variabili<br />
q il risultato è il risultato <strong>di</strong> una funzione, non l'effetto causato<br />
dalla esecuzione <strong>di</strong> una sequenza <strong>di</strong> operazioni<br />
q Sono adatti a elaborazioni simboliche non numeriche.<br />
• Il Lisp (acronimo per LISt Processing) è il linguaggio<br />
più conosciuto, ma non è più molto usato.<br />
FI - Algoritmi e Programmazione 81<br />
FI - Algoritmi e Programmazione 82<br />
Linguaggi Orientati agli Oggetti<br />
• In un linguaggio <strong>di</strong> programmazione orientato<br />
agli oggetti (OOP) un programma consiste:<br />
q Definizione <strong>di</strong> un insieme <strong>di</strong> classi.<br />
q Creazione <strong>di</strong> un insieme <strong>di</strong> oggetti ed esecuzione<br />
dei suo meto<strong>di</strong>.<br />
q Il C++ e Java sono i due linguaggi OOP più<br />
<strong>di</strong>ffusi<br />
Cos’è un oggetto?<br />
• Interagiamo con oggetti <strong>di</strong> uso quoti<strong>di</strong>ano,<br />
conoscendone le funzioni, ma non il funzionamento<br />
interno<br />
q Gli oggetti sono scatole nere dotate <strong>di</strong> interfaccia che<br />
limita l’accesso ai meccanismi interni<br />
q Gli oggetti hanno uno stato<br />
• L’insieme delle proprietà che lo caratterizzano in un dato<br />
istante<br />
q e un comportamento<br />
• L’insieme delle azioni che un oggetto può compiere<br />
• Un oggetto sw è un’astrazione o un modello della<br />
realtà che limita il numero dei dettagli rappresentati<br />
all’essenziale per il contesto considerato<br />
FI - Algoritmi e Programmazione 83<br />
84
Astrazione<br />
• L’astrazione nasconde o ignora dettagli inessenziali<br />
• Un oggetto è un’astrazione<br />
q Non ci preoccupiamo dei suoi dettagli interni per usarlo<br />
q Non conosciamo come funziona il metodo “scrivi a<br />
monitor” quando l’invochiamo<br />
• Effettuiamo astrazioni continuamente<br />
q Possiamo trattare solo poche informazioni<br />
contemporaneamente<br />
q Ma se raggruppiamo le informazioni (come gli oggetti)<br />
allora possiamo trattare informazioni più complicate<br />
• Quin<strong>di</strong>, possiamo anche scrivere software<br />
complesso organizzandolo attentamente in classi e<br />
oggetti<br />
Gli oggetti software<br />
• Lo stato <strong>di</strong> un oggetto sw è descritto e<br />
rappresentato da una o più variabili<br />
q Una variabile è un dato in<strong>di</strong>viduato da un<br />
identificatore<br />
• il comportamento è definito dai meto<strong>di</strong><br />
• Un oggetto sw è costituito dall’insieme delle<br />
variabili e dei meto<strong>di</strong><br />
85<br />
FI - Algoritmi e Programmazione 86<br />
Gli oggetti software<br />
Un insieme <strong>di</strong> dati e funzioni:<br />
Dato<br />
Dato<br />
Dato<br />
Funzione<br />
Co<strong>di</strong>ce<br />
funzione<br />
Co<strong>di</strong>ce<br />
funzione<br />
Co<strong>di</strong>ce<br />
funzione<br />
Funzione<br />
Funzione<br />
Oggetti e classi<br />
• Gli oggetti sono generati da una classe<br />
q Si <strong>di</strong>cono anche istanze della classe<br />
• La classe è uno schema per produrre una<br />
categoria <strong>di</strong> oggetti strutturalmente identici<br />
q La classe costituisce il prototipo<br />
q Una classe è una fabbrica <strong>di</strong> istanze: possiede<br />
lo schema e la tecnica <strong>di</strong> produzione<br />
FI - Algoritmi e Programmazione 87<br />
FI - Algoritmi e Programmazione 88<br />
Classi ed ere<strong>di</strong>tarieta’<br />
Gli oggetti come astrazione<br />
Soldato<br />
• Un oggetto che modella una bicicletta<br />
q Una velocità (20 Km/h), il giro dei pedali (15 g/m) e la<br />
marcia (5°) sono variabili <strong>di</strong> istanza<br />
q proprietà rappresentate in ciascuna bicicletta modellata<br />
FI - Algoritmi e Programmazione 89<br />
FI - Algoritmi e Programmazione 90
Gli oggetti come astrazione – 2<br />
Le istanze<br />
• Definita una classe, si possono creare un<br />
numero arbitrario <strong>di</strong> oggetti appartenenti alla<br />
classe<br />
• Inoltre nel modello rappresentiamo funzioni come frenare<br />
o cambiare marcia, che mo<strong>di</strong>ficano le variabili d’istanza<br />
• Si chiamano meto<strong>di</strong> d’istanza perché hanno accesso alle<br />
variabili d’istanza e le mo<strong>di</strong>ficano<br />
FI - Algoritmi e Programmazione 91<br />
FI - Algoritmi e Programmazione 92<br />
Incapsulamento dei dati<br />
• Nascondere le informazioni fornendo un’interfaccia<br />
• Netta <strong>di</strong>visione fra interfaccia e implementazione<br />
• Le variabili <strong>di</strong> un oggetto, che ne rappresentano lo<br />
stato, sono nascoste all’interno dell’oggetto,<br />
accessibili solo ai meto<strong>di</strong><br />
• Idealmente i meto<strong>di</strong> proteggono le variabili<br />
• Diversi livelli <strong>di</strong> accesso a meto<strong>di</strong> e variabili<br />
q Private: accessibili solo alla classe<br />
q Public: accessibili a chiunque e quin<strong>di</strong> anche alle<br />
sottoclassi<br />
• Consente modularità e flessibilità nel co<strong>di</strong>ce,<br />
impedendo errori nel manipolare gli oggetti e<br />
semplifica la gestione <strong>di</strong> sistemi complessi<br />
I messaggi<br />
• Gli oggetti interagiscono tra loro per ottenere<br />
funzioni più complesse<br />
q La bicicletta appesa in garage è un oggetto e<br />
basta, ci vuole un ciclista che interagisca con lei<br />
perché sia interessante<br />
• Gli oggetti sw per interagire si mandano<br />
messaggi<br />
q Chiedendo <strong>di</strong> eseguire<br />
un certo metodo<br />
(procedura)<br />
FI - Algoritmi e Programmazione 93<br />
FI - Algoritmi e Programmazione 94<br />
I messaggi – 2<br />
• Spesso i meto<strong>di</strong> necessitano <strong>di</strong> informazioni<br />
per poter essere eseguiti: i parametri<br />
• Tre componenti:<br />
q L’oggetto a cui il messaggio è rivolto<br />
q Il metodo da eseguire per ottenere un certo<br />
effetto<br />
q I parametri ,<br />
se necessari al<br />
metodo<br />
FI - Algoritmi e Programmazione 95<br />
I messaggi – 3<br />
• Un oggetto può essere visto come un insieme <strong>di</strong> servizi<br />
che possiamo chiedere <strong>di</strong> eseguire<br />
• I servizi sono definiti dai meto<strong>di</strong><br />
• Il comportamento <strong>degli</strong> oggetti è definito dai suoi meto<strong>di</strong><br />
e il meccanismo <strong>di</strong> invio dei messaggi consente<br />
l’interazione tra gli oggetti<br />
• Ogni oggetto ha in se tutto ciò che gli serve per<br />
rispondere alle chiamate<br />
• Gli oggetti che si scambiano i messaggi possono<br />
anche essere ‘<strong>di</strong>stanti’ tra loro<br />
q Su macchine <strong>di</strong>verse<br />
q Non appartenenti allo stesso modello<br />
FI - Algoritmi e Programmazione 96
Interfaccia<br />
Inviare messaggi<br />
• L’interfaccia è l’insieme dei messaggi che un<br />
oggetto è in grado <strong>di</strong> interpretare<br />
• Un oggetto deve sod<strong>di</strong>sfare la richiesta <strong>di</strong> un<br />
messaggio<br />
• Eseguendo il metodo si sod<strong>di</strong>sfa la risposta<br />
ad un messaggio da parte <strong>di</strong> un agente<br />
nome: carlo<br />
ciclista_A<br />
cambia (marcia)<br />
marcia: 5<br />
vel: 20<br />
bicicletta_rossa<br />
• Il ciclista ciclista_A che vuole cambiare<br />
marcia invia il messaggio all’oggetto<br />
bicicletta_rossa<br />
bicicletta_rossa.cambia(2);<br />
oggetto metodo i parametri<br />
informazioni fornite al<br />
metodo<br />
FI - Algoritmi e Programmazione 97<br />
FI - Algoritmi e Programmazione 98<br />
Approccio OO<br />
• Sono le strutture <strong>di</strong> dati che svolgono le<br />
azioni, non le subroutines<br />
• Il lavoro è svolto dal server, non dal client<br />
• “Cos’ è?” “Com’ è fatto?”<br />
à Data Oriented<br />
• “Cosa può fare per me?”<br />
à Object Oriented<br />
Perché programmare per oggetti?<br />
• Programmare per oggetti non velocizza<br />
l’esecuzione dei programmi...<br />
• Programmare per oggetti non ottimizza l’uso<br />
della memoria...<br />
E allora perchè programmare per oggetti?<br />
• Programmare per oggetti facilita la<br />
progettazione e il mantenimento <strong>di</strong> sistemi<br />
software molto complessi!<br />
FI - Algoritmi e Programmazione 99<br />
FI - Algoritmi e Programmazione 100<br />
Caratteristiche del software non mantenibile<br />
• Rigi<strong>di</strong>tà<br />
q non può essere cambiato con faciltà<br />
q non può essere stimato l’impatto <strong>di</strong> una mo<strong>di</strong>fica<br />
• Fragilità<br />
q una mo<strong>di</strong>fica singola causa una cascata <strong>di</strong> mo<strong>di</strong>fiche<br />
successive<br />
q i bachi sorgono in aree concettualmente separate dalle<br />
aree dove sono avvenute le mo<strong>di</strong>fiche<br />
• Non riusabilità<br />
q<br />
esistono molte inter<strong>di</strong>pendenze, quin<strong>di</strong> non è possibile<br />
estrarre parti che potrebbero essere comuni<br />
Programmazione ad oggetti<br />
• La programmazione ad oggetti, attraverso<br />
l’incapsulazione, consente <strong>di</strong>:<br />
q ridurre la <strong>di</strong>pendenza del co<strong>di</strong>ce <strong>di</strong> alto livello dalla<br />
rappresentazione dei dati<br />
q riutilizzare del co<strong>di</strong>ce <strong>di</strong> alto livello<br />
q sviluppare moduli in<strong>di</strong>pendenti l’uno dall’altro<br />
q avere co<strong>di</strong>ce utente che <strong>di</strong>pende dalle interfacce<br />
ma non dall’implementazione<br />
FI - Algoritmi e Programmazione 101<br />
FI - Algoritmi e Programmazione 102
Meto<strong>di</strong> <strong>di</strong> sviluppo del software<br />
Meto<strong>di</strong> <strong>di</strong> sviluppo del<br />
software<br />
Un metodo comprende:<br />
• Una notazione<br />
mezzo comune per esprimere strategie e decisioni<br />
• Un processo<br />
specifica come deve avvenire lo sviluppo<br />
FI - Algoritmi e Programmazione 104<br />
Strategie <strong>di</strong> sviluppo <strong>di</strong> un progetto<br />
software<br />
• Requisiti: cosa l’utente vuole<br />
• Analisi: la visione dell’informatico dei requisiti<br />
• Disegno: l’aspetto del sistema software<br />
• Produzione: co<strong>di</strong>fica<br />
• Testing: debugging e verifica dei requisiti<br />
• Mantenimento: installazione del prodotto e<br />
controllo del funzionamento per il resto della sua vita<br />
Modello a cascata<br />
Requisiti<br />
Analisi<br />
Disegno<br />
Produzione<br />
Testing<br />
FI - Algoritmi e Programmazione 105<br />
FI - Algoritmi e Programmazione 106<br />
Modello evoluzionario<br />
Confronto fra i modelli <strong>di</strong> sviluppo<br />
Requisiti<br />
A cascata<br />
Evoluzionario<br />
Testing<br />
Produzione<br />
Analisi<br />
Disegno<br />
• Processo lineare (si torna al<br />
passo precedente solo in<br />
caso <strong>di</strong> problemi)<br />
• Confinamento delle attività<br />
in ogni fase<br />
• Facile da gestire (gestione<br />
delle scadenze)<br />
• Difficile da mo<strong>di</strong>ficare<br />
• Prodotto utilizzabile solo<br />
alla fine del processo<br />
• Processo ciclico (brevi<br />
processi completi)<br />
• Attività <strong>di</strong>stribuite su più fasi<br />
• Difficile da gestire<br />
• Facile da mo<strong>di</strong>ficare e<br />
integrare<br />
• Prototipo utilizzabile fin dal<br />
primo ciclo<br />
FI - Algoritmi e Programmazione 107<br />
FI - Algoritmi e Programmazione 108
Requisiti<br />
• Definizione delle richieste da parte dell’utente del<br />
programma (o <strong>di</strong> una sua parte) sul sistema<br />
• Si parla <strong>di</strong> programmazione per contratto perchè<br />
l’utente richiede solamente la definizione del servizio<br />
richiesto NON la metodologia seguita per fornirglielo<br />
q è possibile delegare parte del lavoro richiesto ad<br />
altri<br />
q il sistema è in<strong>di</strong>pendente da chi è il suo utente<br />
INCAPSULAMENTO!<br />
Analisi<br />
• Comprensione e razionalizzazione delle<br />
richieste dell’utente<br />
• Costruzione <strong>di</strong> un modello<br />
q astrazione (semplificazione delle relazioni)<br />
q rilevanza (identificazione <strong>degli</strong> oggetti chiave)<br />
• Da non trascurare: analisi delle soluzioni<br />
esistenti. Può far risparmiare molto tempo!!!<br />
FI - Algoritmi e Programmazione 109<br />
FI - Algoritmi e Programmazione 110<br />
Disegno<br />
Disegno (2)<br />
Definizione<strong>degli</strong> stati<br />
e dell’implementazione<br />
Definizione<strong>di</strong> oggetti<br />
e classi<br />
Definizionedelle<br />
relazioni<br />
Definizionedelle<br />
interfacce<br />
• Dopo ogni ciclo bisogna analizzare i rischi, la<br />
stabilità del <strong>di</strong>segno e la complessità delle<br />
classi<br />
• Se una classe è troppo complessa conviene<br />
<strong>di</strong>viderla<br />
• Ad ogni ciclo il numero <strong>di</strong> mo<strong>di</strong>fiche deve<br />
<strong>di</strong>minuire<br />
• Architetture troppo complesse devono essere<br />
modularizzate<br />
FI - Algoritmi e Programmazione 111<br />
FI - Algoritmi e Programmazione 112<br />
Co<strong>di</strong>fica<br />
Testing<br />
• C’è poco da <strong>di</strong>re…<br />
• Non sopravvalutate questa fase:<br />
Sud<strong>di</strong>visione del tempo per il primo<br />
ciclo<br />
Co<strong>di</strong>fica<br />
15%<br />
Testing<br />
20%<br />
Disegno<br />
35%<br />
Analisi<br />
30%<br />
• Debugging: è ovvio… il co<strong>di</strong>ce non deve dare<br />
errori.<br />
• Use cases: specificano il comportamento del<br />
sistema in una regione.<br />
• Scenarios: sono esempi concreti <strong>di</strong> use cases. Per<br />
definizione se tutti gli scenari sono sod<strong>di</strong>sfatti<br />
correttamente il test è positivo.<br />
FI - Algoritmi e Programmazione 113<br />
FI - Algoritmi e Programmazione 114