Il 0% ha trovato utile questo documento (0 voti)
17 visualizzazioni

Python.corso.putzu

Caricato da

Nunzio Castaldi
Copyright
© © All Rights Reserved
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
17 visualizzazioni

Python.corso.putzu

Caricato da

Nunzio Castaldi
Copyright
© © All Rights Reserved
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Sei sulla pagina 1/ 411

Laboratorio di Informatica

Corso di Laurea Magistrale in Ingegneria per


l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 00
Introduzione e
Presentazione del corso

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Canali di comunicazione
• Lorenzo Putzu
• Il mio studio si trova al terzo piano del Dipartimento di
Ingegneria Elettrica ed Elettronica (DIEE) edificio M

• Canali di comunicazione
• e-mail: [email protected]
• Microsoft Teams, canale: Laboratorio di Informatica

Lorenzo Putzu Laboratorio D’Informatica 2


Comunicazioni con il docente
• Via e-mail indicare sempre l'oggetto del messaggio
• Specificare che il messaggio è relativo a questo corso iniziare l'oggetto con
“LabINF, ...”
• A seguire nome, cognome e matricola eg. “... Pippo Pero 12345, ...”
• Infine lo scopo dell’e-mail eg. “... Chiarimenti Esericizio1”

• Esempio CONFORME: LabINF, Pippo Pero 12345, Chiarimenti Esericizio1

Lorenzo Putzu Laboratorio D’Informatica 3


Comunicazioni con il docente
• La posta elettronica è un mezzo di comunicazione asincrono
• non sempre riesco a rispondere immediatamente
• non date per scontato che legga la posta a mezzanotte!

• Esempio NON CONFORME

Lorenzo Putzu Laboratorio D’Informatica 4


Comunicazioni con il docente
• Microsoft Teams è anch’esso asincrono ma...
• Permette di comunicare con tutta la classe
• Anche gli studenti possono (provare a) rispondere ad una domanda e il
docente ne deve solo dare conferma
• Permette di vedere le risposte già data ad una domanda (simile FAQ)

• Ovviamente NON E’ UNA CHAT!!!


• Solo domande pertinenti
• Solo risposte coerenti con la domanda

Lorenzo Putzu Laboratorio D’Informatica 5


Obbiettivi del corso
• Fornire le conoscenze su su due specifici strumenti
informatici di interesse per l’ingegneria ambientale:
• Aspetti pratici del linguaggio di programmazione Python e della
programmazione orientata agli oggetti
• I sistemi di gestione di basi di dati relazionali e gli elementi di base
del linguaggio SQL

Lorenzo Putzu Laboratorio D’Informatica 6


Prerequisiti
• E’ richiesta la conoscenza di:
• Informatica di base e dell’architettura dei calcolatori
• Programmazione struttuturata (C, Python, ecc.).

• Potrebbero essere utili conoscenze di:


• Analisi Matematica

Lorenzo Putzu Laboratorio D’Informatica 7


Materiale didattico
• Libri di testo
• Per Python: C. Horstmann, R.D. Necaise, Concetti di informatica e
fondamenti di Python, Maggioli, 2014.

• Per le basi di dati: P. Atzeni, S. Ceri, S. Paraboschi, R. Torlone, Basi di Dati


– Modelli e linguaggi di interrogazione, McGraw-Hill, 3a ed., 2009 (o altre
edizioni).

• Appunti e slide
• Sul mio sito docente
https://www.unica.it/unica/it/ateneo_s07_ss01.page?con
tentId=SHD232124
• su Microsoft Teams

Lorenzo Putzu Laboratorio D’Informatica 8


Strumenti didattici
• Per Python useremo l’ambiente di programmazione
IDLE, disponibile per qualsiasi sistema operativo sul sito
web della comunità italiana degli sviluppatori
Python, www.python.it.

• Per le basi di dati useremo il DBMS open source e


gratuito PostgreSQL, disponibile per i principali sistemi
operativi https://www.postgresql.org/ , molto usato in
campo aziendale e coerente con gli standard ANSI SQL.

Lorenzo Putzu Laboratorio D’Informatica 9


Programma Preliminare
• Python
•Elementi di base (richiami):
•ambiente di programmazione: editor e shell;
•le istruzioni principali: assegnamento, stampa, condizionale, iterativa, e le funzioni di
input;
•tipi di dato semplici, operatori e funzioni predefinite
•definizione di nuove funzioni;
•gestione dei file.
•I tipi di dato stringa, lista, tupla, insieme e dizionario:
• gli operatori, le funzioni e metodi principali;
•L’istruzione iterativa for per stringhe, liste, tuple, dizionari e insiemi;
•Programmazione orientata agli oggetti:
•definizione di nuove classi
•variabili d’istanza
•metodi

Lorenzo Putzu Laboratorio D’Informatica 10


Programma Preliminare
• Basi di dati
• Sistemi di gestione delle basi di dati (DBMS): generalità.
• Il modello logico relazionale per la descrizione dello schema di una base di dati:
tabelle, vincoli d’integrità (di dominio, di chiave primaria, d’integrità referenziale, di
dominio esteso, di tupla); schemi e istanze di una tabella e di una base di dati.
• Progettazione concettuale di una base di dati tramite il modello Entità-Relazione;
• Progettazione logica di una base di dati relazionale: definizione dello schema logico a
partire dallo schema concettuale Entità-Relazione.
• Il linguaggio SQL per la definizione dello schema e per l’interrogazione di basi di dati
relazionali
• Introduzione al DBMS PostgreSQL: generalità, creazione di nuove basi di dati,
definizione dello schema logico
• Libreria python psycopg2 per la connessione ai DB di PostgreSQL

Lorenzo Putzu Laboratorio D’Informatica 11


Calendario
• Giovedì 30/09/2021 15.00-18.00
• Venerdì 01/10/2021 11.00-13.00
..... ……
..... ……

• Giovedì 02/12/2020 15.00-18.00


• Venerdì 03/12/2020 11.00-13.00

Lorenzo Putzu Laboratorio D’Informatica 12


Modalità d’esame
• Metodo I (consigliatissimo)
• Frequenza assidua e impegno costante
• Poco libro e molti appunti
• 1 progetto su entrambe le parti (da consegnare entro il 31 Gennaio)
• + prova orale confirmatoria (opzionale)

• Metodo II
• Frequenza almeno sopra la soglia
• 1 unica prova orale su tutto il programma

Lorenzo Putzu Laboratorio D’Informatica 13


Domande

Lorenzo Putzu Laboratorio D’Informatica 14


Laboratorio di Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 01
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Programmazione
• Algoritmo: insieme finito e ordinato di passi eseguibili in tempo finito e
non ambigui (univocamente definiti), che definiscono un processo che
termina.

• Programma: sequenza di istruzioni elementari che un computer è in grado


di comprendere ed eseguire.

• Programmare: risolvere un problema (reale?) mediante un algoritmo.


• Le capacità di risoluzione dei problemi prescindono dal linguaggio utilizzato.

• Algoritmo (astratto) > Programma (concreto)

Lorenzo Putzu Laboratorio D’Informatica 2


Programmazione
• Aspetti pratici della programmazione:
• Linguaggio Python
• Sintassi dei costrutti
• Stesura del codice
• Comprensione del codice

• Aspetti più generali della programmazione:


• Tecniche di problem solving
• Stile di programmazione
• Efficienza

Lorenzo Putzu Laboratorio D’Informatica 3


Ambiente di sviluppo
• Useremo l’ambiente di programmazione IDLE
• disponibile per qualsiasi sistema operativo www.python.it

• Si compone di
• Shell
• Editor

Lorenzo Putzu Laboratorio D’Informatica 4


Variabili
• Le variabili sono i luoghi in cui vengono memorizzati temporaneamente i
dati di cui il programma ha bisogno per portare a termine il suo compito.

• Ogni variabile è caratterizzata da:


• un nome univoco
• un tipo (tipizzazione dinamica)
• un valore

• In Python non si distingue una fase di dichiarazione e di assegnamento


C vs Python
int variabile = espressione; variabile = espressione

Lorenzo Putzu Laboratorio D’Informatica 5


Nomi Variabili
• Possono essere composti da uno o più dei seguenti caratteri:
• lettere minuscole e maiuscole (anche accentate)
• cifre
• il carattere _ (underscore)

• NON devono iniziare con una cifra;


• NON devono coincidere con i nomi predefiniti delle istruzioni e di altri
elementi del linguaggio.

Lorenzo Putzu Laboratorio D’Informatica 6


Nomi Variabili
catetoUnO
2cateto
QuestaEunaVariabile
nome-casuale
def
print
_underscore_
variable1
Variabile1
Print

Lorenzo Putzu Laboratorio D’Informatica 7


Nomi Variabili
catetoUnO
2cateto (non può iniziare con un numero)
QuestaEunaVariabile
nome-casuale (il trattino viene valutano come simbolo matematico)
def (keyword)
print (keyword)
_underscore_
variable1
Variabile1
Print

Lorenzo Putzu Laboratorio D’Informatica 8


Variabili
• L’istruzione di assegnamento viene eseguita in due fasi:
• l’interprete valuta espressione, cioè ne determina il valore
• il valore di espressione viene assegnato (o associato) a variabile

• L’effetto concreto di un’istruzione di assegnamento è la memorizzazione del


valore di espressione all’interno di una o più celle di memoria.

• Se un’istruzione di assegnamento si riferisce a una varilabile alla quale in


precedenza era già stato assegnato un valore, il nuovo valore sostituirà quello
precedente.

Lorenzo Putzu Laboratorio D’Informatica 9


Espressioni e tipi di dato
• Le espressioni Python possono elaborare e produrre valori appartenenti a tre
categorie principali, dette tipi di dato
• numeri interi
• numeri frazionari
• sequenze (“stringhe”) di caratteri

• La più semplice espressione è un singolo numero

• Python distingue tra due tipi di dato numerici:


• I numeri interi, sia positivi che negativi;
• I numeri frazionari (floating point), sia positivi che negativi

Lorenzo Putzu Laboratorio D’Informatica 10


Espressioni aritmetiche
• Gli operatori disponibili nel linguaggio Python sono i seguenti
• +, -, *, /, // (quoziente intero), ** (potenza), % (modulo)

• Alcune espressioni aritmetiche possono essere


• a = 6;
• b = 8 + 2;
• c = 7 - 2;
• d=6*7
• e = 10/5;
• f = 10%5
• g = 10//5

Lorenzo Putzu Laboratorio D’Informatica 11


Espressioni aritmetiche
• Espressioni aritmetiche più complesse si ottengono combinando
numeri attraverso operatori
• a=b=c
• a = b * c + 5;
• a = c - 7 * 5 + a;

• Valgono le regole di precedenza canoniche. Per alterare l'ordine, si


utilizzano le parentesi tonde:
• v = b * c + a * e;
• v = b * ((c + a) * e);
• v = ((b * c) + a) * e;

Lorenzo Putzu Laboratorio D’Informatica 12


Espressioni che elaborano stringhe
• I programmi Python possono elaborare testi rappresentati come sequenze di
caratteri (lettere, cifre, segni di punteggiatura) racchiuse tra apici singoli o doppi,
dette stringhe. Esempi:
• "Questa è una stringa"
• ’Questa è una stringa’
• "" (una stringa vuota)

• È quindi possibile assegnare una stringa a una variabile; esempi:


• variabile = "Questa è una stringa"

Lorenzo Putzu Laboratorio D’Informatica 13


Espressioni che elaborano stringhe
• Il linguaggio Python prevede alcuni operatori anche per il tipo di dato stringa.
Uno di questi è l’operatore di concatenazione, che si rappresenta con il simbolo +
e produce come risultato una nuova stringa ottenuta concatenando due stringhe
qualsiasi
• variabile = "mappa" + "mondo" → "mappamondo"
• variabile = "Ciao" + " " + "a" + " " + "tutti" → "Ciao a tutti"

Lorenzo Putzu Laboratorio D’Informatica 14


Ingresso/uscita (input/output)
• L'istruzione print consente di stampare nella shell il valore di una
qualsiasi espressione
• Sintassi: print(espressione)
• non devono esserci spazi prima della keyword print
• espressione deve essere una qualsiasi espressione valida del linguaggio
Python (quindi anche variabili)

• È anche possibile stampare i valori di un numero qualsiasi di espressioni,


con la seguente sintassi:
• print(espressione1,espressione2,. . . )
• In questo caso i valori delle espressioni vengono stampati su una stessa riga,
separati da un carattere di spaziatura.

Lorenzo Putzu Laboratorio D’Informatica 15


Ingresso/uscita (input/output)
• Stampa nella shell di una sequenza di valori.
• x=5
• p = "Mappa"
• print(-3.2)
• print(2 + 2)
• print("Ciao")
• print(x)
• print((x + 1)/4.0)
• print("Il valore di x è", x)
• print(p + "mondo")

Lorenzo Putzu Laboratorio D’Informatica 16


Ingresso/uscita (input/output)
• Per inserire in una stringa un apice singolo o doppio è necessario racchiuderla tra apici dell’altro
tipo, oppure far precedere l’apice dal carattere \ (detto backslash), senza spazi tra i due.
• print("L’apostrofo")
• print(’L\’apostrofo’)
• print(’Doppi "apici" in una stringa’)
• print("Doppi \"apici\" in una stringa")
• Per rappresentare un’interruzione di riga (“a capo”, newline) all’interno di una stringa si usa la
sequenza di caratteri \n. Esempio:
• print("Prima riga.\nSeconda riga.")
• Dato il significato particolare del carattere \ nelle stringhe, per stamparlo testualmente si deve
scrivere \\
• print("abc\\def")

Lorenzo Putzu Laboratorio D’Informatica 17


Ingresso/uscita (input/output)
• La funzione input è necessaria quando i valori dei dati da elaborare non sono
noti nel momento della scrittura di un programma, ma devono essere acquisiti
durante la sua esecuzione, attraverso la tastiera
• Sintassi: variabile = input(messaggio)
• Stampa nella shell messaggio (se presente) e consente all’utente, durante
l’esecuzione di un programma, di immettere una qualsiasi sequenza di
caratteri nella shell;
• durante l’esecuzione della funzione input l’esecuzione del programma resta
sospesa alla pressione del tasto INVIO
• la sequenza inserita sarà memorizzata in variabile sotto forma di stringa.

Lorenzo Putzu Laboratorio D’Informatica 18


Ingresso/uscita (input/output)
• Sintatticamente il costrutto input(messaggio) costituisce un tipo particolare di espressione
Python (detta chiamata di funzione, come si vedrà più avanti). Infatti, analogamente alle altre
espressioni, esso ha lo scopo di produrre un valore che dovrà poi essere elaborato dal programma
• nome = input("Inserire il proprio nome: ")
• cognome = input("Inserire il proprio cognome: ")
• età = input("Inserire la propria età: ")
• print("I dati inseriti sono:")
• print(nome, cognome, età)

Lorenzo Putzu Laboratorio D’Informatica 19


La funzione eval
• Se una stringa contiene una qualsiasi espressione valida del linguaggio Python, la
funzione eval consente di ottenere il valore di tale espressione.

• Assumendo che x sia un’espressione di tipo stringa, la sintassi della chiamata di


eval è la seguente:

eval(x)

• Per esempio, l’espressione eval("1+1") produce il valore 2.

• La funzione eval può quindi essere usata per “convertire” in valori numerici i dati
acquisiti mediante la funzione input.

Lorenzo Putzu Laboratorio D’Informatica 20


Esercizio
1. Scrivere un programma che permetta di effettuare la conversione
euro dollari, assegnando alle variabili con l’importo in Euro e tasso
di conversione un valore a piacere e stampare il risultato in output.

Lorenzo Putzu Laboratorio D’Informatica 21


Laboratorio di Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 02
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Istruzioni condizionali
• In tutti i linguaggi di alto livello sono disponibili per questo scopo:
• le espressioni condizionali, che consentono di esprimere
condizioni che possono essere vere o false (per es., a ”= 0)
• l’istruzione condizionale, che consente di eseguire due diverse
sequenze d’istruzioni alternative tra loro, in base al valore di
un’espressione condizionale

Lorenzo Putzu Laboratorio D’Informatica 2


Espressioni condizionali
• Il tipo più semplice di espressione condizionale consiste nel confronto tra due espressioni.
• Sintassi: espressione1 operatore espressione2
• espressione1 e espressione2 sono due espressioni Python qualsiasi
• operatore è un simbolo che indica il confronto da eseguire tra le due espressioni

Lorenzo Putzu Laboratorio D’Informatica 3


Espressioni condizionali
• Il risultato di un espressione condizionale assume il valore logico
• True (vero)
• False (falso)
• Il loro valore può essere assegnato a una variabile o stampato nella shell; per
esempio, assumendo che alla variabile x sia già stato assegnato un valore
numerico:
• risultato = (x > 0)
• print(x > 0)

Lorenzo Putzu Laboratorio D’Informatica 4


Espressioni condizionali composte
• Le espressioni condizionali viste finora si dicono semplici, poiché consistono in un
singolo confronto tra due valori.
• Possiamo costruire espressioni condizionali composte, ottenute combinando
espressioni condizionali qualsiasi (anche a loro volta composte) per mezzo di
operatori logici :
• Sintassi:
• espr-cond1 and espr-cond2
• espr-cond1 or espr-cond2
• not espr-cond
• E’ possibile usare le parentesi tonde per definire l’ordine degli operatori logici

Lorenzo Putzu Laboratorio D’Informatica 5


Istruzioni condizionali
• Le espressioni condizionali sono uno dei componenti delle istruzioni condizionali,
che consentono di esprimere in un programma la scelta tra due diverse sequenze
di istruzioni in base al verificarsi o meno di una certa condizione durante
l’esecuzione dello stesso programma.
• In linguaggio naturale, un’istruzione condizionale esprime la seguente richiesta
all’esecutore di un algoritmo:
• se una data condizione è vera,
• allora esegui una certa sequenza d’istruzioni,
• altrimenti esegui un’altra sequenza d’istruzioni

Lorenzo Putzu Laboratorio D’Informatica 6


Istruzioni condizionali
• Sintassi
if espr-cond :
sequenza di istruzioni 1
else :
sequenza di istruzioni 2

• espr-cond è un’espressione condizionale qualsiasi


• sequenza di istruzioni 1 e sequenza di istruzioni 2 sono due sequenze di una o
più istruzioni qualsiasi e devono essere correttamente indentate (rientri)

Lorenzo Putzu Laboratorio D’Informatica 7


Istruzioni condizionali
• Esempio
• Assumiamo di aver acqusito un input da tastiera e che vanga memorizzato nella
variabile x

if x > 0 :
print("La condizione è vera.")
else:
print("La condizione è falsa.")

• ATTENZIONE alla sintassi e all’indentazione

Lorenzo Putzu Laboratorio D’Informatica 8


Istruzioni condizionali
• Il ramo else è opzionale perciò non deve essere indicata un’istruzione da eseguire
se la condizione è falsa
• A volte invece potrebbe essere necessario verificare più condizioni perciò si
possono aggiungere un numero di rami elif pari alle condizioni da verificare
• Sintassi completa
• if...
• if...else...
• if...elif...
• if...elif...else...

Lorenzo Putzu Laboratorio D’Informatica 9


Istruzioni condizionali nidificate
• Un’istruzione condizionale può contenere al suo interno istruzioni qualsiasi, e
quindi anche altre istruzioni condizionali. Si parla in questo caso di istruzioni
nidificate (o annidate).
• L’uso di istruzioni condizionali nidificate consente di esprimere la scelta tra più di
due sequenze di istruzioni alternative.
• Un’istruzione condizionale nidificata all’interno di un’altra si scrive con la stessa
sintassi mostrata in precedenza, questo implica che:
• le parole-chiave if e (se presente) else devono essere allineate tra loro, ma
con un rientro rispetto a quelle dell’istruzione condizionale che le contiene
• le sequenze di istruzioni che seguono if e else devono essere scritte con un
ulteriore rientro

Lorenzo Putzu Laboratorio D’Informatica 10


Esercizio
1. Un anno è bisestile se è multiplo di 100 e divisibile per 400, oppure se non è
multiplo di 100 ma è divisibile per 4. Questa regola vale solo per gli anni
successivi al 1582. Scrivere un programma che acquisisca un anno, verifichi se è
successivo al 1582, e in questo caso stabilisca se sia bisestile o meno

Lorenzo Putzu Laboratorio D’Informatica 11


Istruzione iterativa
• In molti algoritmi è necessario ripetere una stessa sequenza di operazioni per una
o più volte.
• In tutti i linguaggi di alto livello è presente a questo scopo l’istruzione iterativa,
che consente di esprimere la seguente richiesta all’esecutore di un algoritmo:
• finché una data condizione è vera,
• esegui una certa sequenza di istruzioni

Lorenzo Putzu Laboratorio D’Informatica 12


Istruzione iterativa
• Sintassi
while espr-cond :
sequenza di istruzioni
• espr-cond è un’espressione condizionale qualsiasi
• sequenza di istruzioni consiste in una o più istruzioni qualsiasi
• Un’istruzione iterativa viene eseguita ripetendo ciclicamente (iterativamente) i
seguenti passi:
• 1. viene valutata espr-cond
• 2. se espr-cond è vera, si esegue la sequenza di istruzioni, e si ritorna al punto
1; se invece espr-cond è falsa l’esecuzione dell’istruzione iterativa termina

Lorenzo Putzu Laboratorio D’Informatica 13


Istruzione iterativa
• Esempio
• Assumiamo di aver acqusito un input da tastiera e che vanga memorizzato nella
variabile x

while x < 2 :
print("Python")
x = 3

• ATTENZIONE alla sintassi e all’indentazione

Lorenzo Putzu Laboratorio D’Informatica 14


Istruzione iterativa
• Nella maggior parte dei casi un’istruzione iterativa ha lo scopo di ripetere una
certa sequenza di istruzioni per un numero di volte noto nel momento in cui si
scrive il programma

• A questo scopo si usa comunemente una alla quale prima dell’istruzione iterativa
si assegna un valore scelto dal programmatore (di norma, 1); tale valore viene poi
incrementato di una unità in ogni ripetizione dell’istruzione iterativa;
• l’espressione condizionale verificherà quindi che il valore della stessa variabile sia minore o
uguale al numero desiderato di ripetizioni.

• Poiché le variabili usate in questo modo hanno la funzione di tenere traccia del
(contare il) numero di iterazioni, vengono comunemente indicate con il termine
“contatori”.
Lorenzo Putzu Laboratorio D’Informatica 15
Istruzione iterativa
• Esempio
• Assumiamo di aver acqusito un input da tastiera e che vanga memorizzato nella
variabile x

x = eval(input("Inserire un numero: "))


k = 1
while k <= x :
print("Buongiorno")
k = k + 1

• ATTENZIONE alla sintassi e all’indentazione


Lorenzo Putzu Laboratorio D’Informatica 16
Assegnamenti composti
• Gli assegnamenti composti rendono più compatto il codice nella
scrittura delle operazioni aritmetiche nel caso in cui una variabile
venga utilizzata nella stessa e per salvarne poi il contenuto.
• += > incrementa la variabile che lo precede aggiungendo il valore susseguente;
• -= > decrementa la variabile che lo precede sottraendo il valore susseguente;
• *= > moltiplica la variabile che lo precede per il valore susseguente;
• /= > divide la variabile che lo precede per il valore susseguente;
• //= > divide la variabile che lo precede per il valore susseguente e restituisce il quoziente
intero;
• %= > calcola il modulo tra la variabile che lo precede ed il valore susseguente;

Lorenzo Putzu Laboratorio D’Informatica 17


Assegnamenti composti
• i = i + 1; → i += 1;
• a = a * 3; → a *= 3;
• b = b / 2; → b /= 2;
• y = y % 5; → y %= 5;

• Precedenza più bassa rispetto agli operatori aritmetici.


i *= j + k; → i = i * ( j + k );

Lorenzo Putzu Laboratorio D’Informatica 18


Assegnamenti composti
• L’esempio di prima può quindi essere riscritto come segue

x = eval(input("Inserire un numero: "))


k = 1
while k <= x :
print("Buongiorno")
k += 1

Lorenzo Putzu Laboratorio D’Informatica 19


Istruzione iterativa nidificata
• Come l’istruzione condizionale anche l’istruzione iterativa può contenere al suo
interno istruzioni qualsiasi, quindi anche altre istruzioni iterative e anche in
questo caso si parla di istruzioni nidificate (o annidate).

• L’uso di istruzioni iterative nidificate può essere molto utile quando si lavora su
delle tabelle o matrici che quindi presentano delle righe e colonne

• ATTENZIONE all’efficienza: troppe istruzioni annidate possono influire


pesantemente sui tempi di esecuzione del programma

Lorenzo Putzu Laboratorio D’Informatica 20


Esercizi
2. Scrivere un programma che acquisisca una sequenza di numeri di lunghezza
data e ne calcoli la somma

3. Scrivere un programma che acquisica una sequenza di numeri fino


all'inserimento del valore 0, e ne calcoli la somma

4. Modificare il programma precedente in modo che calcoli anche il numero di


valori positivi inseriti

Lorenzo Putzu Laboratorio D’Informatica 21


Laboratorio di Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 03
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Istruzione break
• Un’istruzione iterativa termina quando, all’inizio di un’iterazione, l’espressione condizionale
risulta falsa.

• Per concludere l’esecuzione di un’istruzione iterativa è anche possibile usare l’istruzione break.
Questa istruzione può essere usata solo all’interno di un’istruzione iterativa, in un qualsiasi punto
della sequenza di istruzioni da ripetere.

• Di norma l’istruzione break viene scritta all’interno di un’istruzione condizionale nidificata in


un’istruzione iterativa, per concludere l’esecuzione di quest’ultima nel caso in cui si verifichi una
data condizione.

• Quando l’interprete incontra l’istruzione break conclude immediatamente l’esecuzione


dell’istruzione iterativa e passa a eseguire l’istruzione successiva.

Lorenzo Putzu Laboratorio D’Informatica 2


Istruzione break
• L’esempio di prima può quindi essere riscritto come segue

x = eval(input("Inserire un numero: "))


k = 1
while True:
print("Buongiorno")
if k > x :
break
k += 1

Lorenzo Putzu Laboratorio D’Informatica 3


Esercizi
• Creare una nuova versione degli esercizi fatti nella lezione precedente
1. Lez02_es02
2. Lez02_es03
in modo che includano un’istruzione break

Lorenzo Putzu Laboratorio D’Informatica 4


Commenti
• È sempre utile documentare i programmi inserendo commenti che indichino
quale elaborazione viene svolta dal programma, quali sono i dati di ingresso e i
risultati, qual è il significato delle variabili o di particolari blocchi di istruzioni, ecc.

• Nei programmi Python i commenti possono essere inseriti in qualsiasi riga,


preceduti dal carattere # (“cancelletto”) e tutti i caratteri che seguono il
cancelletto, fino al termine della stessa riga, sono considerati commenti e
vengono trascurati dall’interprete.

#questo è un commento
print(‘stampa qualcosa’) # anche questo è un commento

Lorenzo Putzu Laboratorio D’Informatica 5


Commenti
• I commenti si possono estendere anche su più righe e per questo scopo si
utilizzano i tripli apici ad entrambe le estremità

'''
Questo è un commento che si estende su più linee
'''

• Questo tipo di commenti si utilizza per una descrizione più generica e globale di
una serie di istruzione che seguono

Lorenzo Putzu Laboratorio D’Informatica 6


Cast implicito ed esplicito
• Spesso capita di fare delle operazioni tra tipi di dati differenti di dati, ad esempio
tra interi e floats. In molti casi l’interprete python converte implicitamente i dati e
si parla appunto di cast implicito

• Ad esempio il risultato prodotto dall’operatore / è sempre rappresentato come


valore frazionario anche quando i valori sono entrambi interi
• 5 / 2 = 2.5
• 4 / 2 = 2.0

• Spesso è necessario e preferibile convertire direttamente le variabili prima


di effettuare delle operazioni e lo si può fare con la seguente sintassi
int(espressione)
float(espressione)

Lorenzo Putzu Laboratorio D’Informatica 7


Cast implicito ed esplicito
• int(numero)
restituisce la parte intera di un numero
• int(stringa)
se stringa contiene la rappresentazione di un numero intero, restituisce il numero
corrispondente a tale valore
• float(numero)
restituisce il valore di numero come numero frazionario (floating point)
• float(stringa)
se stringa contiene la rappresentazione di un numero qualsiasi (sia intero che
frazionario), restituisce il suo valore espresso come numero frazionario

Lorenzo Putzu Laboratorio D’Informatica 8


Migliorare la leggibilità
• Nel linguaggio Python è possibile suddividere una istruzione in più righe,
inserendo il carattere \ (backslash) nel punto in cui si interrompe una riga.

• Questa possibilità può essere sfruttata per suddividere in due righe


un’espressione condizionale troppo lunga o anche l’esprezzione presente in
un’istruzione print.

• Nella prosecuzione di una riga si può inserire un rientro qualsiasi (anche


nessuno). Per garantire la leggibilità del programma è però buona norma usare
un rientro coerente con il contenuto della riga precedente.
if x >10:
print(‘stavo scrivendo una stringa da stampare a schermo ma mi \
sono accorto che era troppo lunga e peggiorava la leggibilità’)

Lorenzo Putzu Laboratorio D’Informatica 9


Struttura dei programmi
• In generale un programma prevede:
• l’acquisizione dei dati da elaborare (attraverso la tastiera con la funzione
input, o con altri meccanismi che saranno presentati più avanti) e il loro
assegnamento a opportune variabili
• l’elaborazione dei dati d’ingresso e degli eventuali risultati intermedi fino a
ottenere i risultati desiderati, per mezzo di opportune sequenze di istruzioni
(in particolare, i risultati intermedi dovranno essere memorizzati in opportune
variabili)
• la stampa dei risultati sullo schermo per mezzo della funzione print (oppure il
loro invio ad altri dispositivi periferici, come si vedrà più avanti)

Lorenzo Putzu Laboratorio D’Informatica 10


Esercizi
3. Calcolare il fattoriale di un dato numero non negativo 𝑛:
𝑛! = 1 × 2 × ⋯ × 𝑛 − 1 × 𝑛, se 𝑛 > 0
𝑛! = 1, se 𝑛 = 0

4. Calcolare la somma dei primi 𝑛 termini della serie armonica per un dato intero non negativo 𝑛:
𝑛
1 1 1 1
෍ = 1 + + +⋯+
𝑘 2 3 𝑛
𝑘=1

5. Per un dato 𝑥 ≥ 0 trovare il più piccolo intero 𝑛 tale che:


𝑛
1
෍ >𝑥
𝑘
𝑘=1

Lorenzo Putzu Laboratorio D’Informatica 11


Funzioni predefinite
• Finora abbiamo visto e utilizzato delle funzioni messe a disposizione del programmatore
come parte integrante dell’ambiente di programmazione, che non sono altro che un
insieme di programmi che eseguono operazioni di utilità generale

• Sono dette funzioni predefinite, o built-in e l’insieme di tali funzioni viene detto libreria.

• Sono caratterizzate dalla capacità di elaborare un determinato insieme di valori di


ingresso e di produrre un risultato in uscita
• La disponibilità di tali funzioni evita agli utenti di dover scrivere propri programmi per
realizzare operazioni di utilità generale
• Ci possiamo focalizzare su COSA fanno piuttosto che sul COME lo fanno

Lorenzo Putzu Laboratorio D’Informatica 12


Funzioni predefinite
• Il linguaggio Python comprende un vasto insieme di funzioni di libreria, disponibili
in qualsiasi ambiente di programmazione. Alcune funzioni predefinite sono
direttamente accessibili dalla shell e dai propri programmi. Le altre sono
suddivise in diverse categorie, dette a loro volta librerie
• La descrizione completa è disponibile nel sito http://docs.python.it
• Anche se utilizzeremo principalmente
• le funzioni matematiche
• Ie funzioni per la generazione di numeri casuali

Lorenzo Putzu Laboratorio D’Informatica 13


Funzioni predefinite
• A ogni funzione è associato un nome e può elaborare un determinato numero di
valori di ingresso, detti argomenti e restituire un valore di un determinato tipo,
come risultato dell’elaborazione svolta
• Ogni volta che abbiamo la necessità di eseguire una funzione effettuiamo una
chiamata di funzione
• Sintassi: res = nome-funzione (arg1, arg2, . . . , argn)
• arg1, . . . , argn sono espressioni Python, i cui valori costituiranno gli argomenti della
funzione il cui tipo e numero dipende dalla specifica funzione:
• il tipo e il numero di argoment deve coincidere con quello previsto dalla funzione
altrimenti si otterrà un messaggio d’errore
• res costituisce il valore restituito dalla funzione

Lorenzo Putzu Laboratorio D’Informatica 14


Funzioni predefinite
• Come casi particolari, esistono anche funzioni che
• non ricevono nessun argomento
• non restituiscono nessun risultato
• possono gestire un numero di argomenti che non è determinato a priori

Lorenzo Putzu Laboratorio D’Informatica 15


Funzioni predefinite
• Come casi particolari, esistono anche funzioni che
• non ricevono nessun argomento
• non restituiscono nessun risultato
• possono gestire un numero di argomenti che non è determinato a priori

• La funzione input può non ricevere argomenti, oppure può riceverne uno
• input() oppure input(arg)
• restituisce un valore di tipo stringa.

• La funzione print consente di stampare nella shell i valori di una o più espressioni:
• print(espressione) oppure print(espressione1,espressione2,. . . )
• non restituisce nessun valore: il suo unico scopo è stampare valori nella shell.

Lorenzo Putzu Laboratorio D’Informatica 16


Funzioni predefinite
• Altre funzioni predefinite di utilità generale sono le seguenti:
• len(stringa)
restituisce il numero di caratteri di una stringa
• abs(numero)
restituisce il valore assoluto di un numero
• str(espressione)
restituisce una stringa composta dalla sequenza di caratteri corrispondenti
alla rappresentazione del valore di espressione (che può essere di un
qualsiasi tipo: numero, stringa, valore logico, ecc.)

Lorenzo Putzu Laboratorio D’Informatica 17


Funzioni predefinite
• La chiamata di una funzione è un’espressione, e quindi deve rispettare le stesse
regole sintattiche:
• può comparire come operando di una qualsiasi espressione più complessa
• può comparire nell’espressione di un’istruzione di assegnamento
• può comparire nelle espressioni condizionali all’interno di istruzioni
condizionali e iterative

• Gli argomenti di una chiamata di funzione sono a loro volta espressioni


• possono quindi essere espressioni Python qualsiasi purché producano un
valore di un tipo previsto dalla funzione (in caso contrario si potrebbe
ottenere un messaggio
• possono altre chiamate di funzione (chiamate nidificate).

Lorenzo Putzu Laboratorio D’Informatica 18


Librerie di funzioni predefinite
• Molte funzioni predefinite fanno parte di specifiche librerie Python, che a loro
volta sono identificate univocamente da un nome simbolico.
• Le funzioni matematiche fanno parte di una libreria di nome math e sono
descritte in dettaglio nel sito https://docs.python.org/3/library/math.html.
• Alcune di queste sono:
• ceil(numero) # restituisce il più piccolo intero maggiore o uguale a numero (arrotonda
per eccesso)
• floor(numero) #restituisce il più grande intero minore o uguale a numero (arrotonda
per difetto)
• pow(numero1, numero2) # restituisce la potenza di numero1 elevato numero2
• sqrt(numero) #restituisce la radice quadrata di numero

Lorenzo Putzu Laboratorio D’Informatica 19


Librerie di funzioni predefinite
• Oltre alle varie funzioni le librerie presentano anche le definizioni di variabili.
• Ad esempio nella libreria math sono definite delle variabili che contengono il
valore (approssimato) delle costanti matematiche
• pi (3,14. . . )
• e (la base dei logaritmi naturali: 2,71. . . )
• Dato che si tratta di variabili (come suggerisce il nome) il loro valore può essere
modificato con istruzioni di assegnamento, anche se ciò non è consigliabile
(PERCHE’ FARLO!!).
• Ovviamente tale modifica è ‘visibile’ solamente all’interno del programma o
blocco del programma in cui tale modificata viene eseguita, ma non nella libreria

Lorenzo Putzu Laboratorio D’Informatica 20


Librerie di funzioni predefinite
• La libreria di random comprende varie funzioni per la generazione di numeri casuali e
sono descritte in dettaglio nel sito https://docs.python.org/3/library/random.html
• Ogni chiamata di tali funzioni produce un numero pseudocasuale, indipendente (in
teoria) dai valori prodotti dalle chiamate precedenti.
• Alcune di queste sono:
• random() genera un numero reale nell’intervallo [0, 1) da una distribuzione di probabilità
uniforme in cui ogni valore di tale intervallo ha la stessa probabilità di essere “estratto”
• uniform(a,b) deriva dalla funzione random, alla quale possiamo passare come
argomenti i valori dell’intervallo dal quale estrarrà un qualsiasi numero
• randint(a,b) anch’essa deriva dalla funzione random, alla quale possiamo passare
come argomenti solamente dei valori interi per definire l’intervallo dal quale estrarrà un
numero intero

Lorenzo Putzu Laboratorio D’Informatica 21


Librerie di funzioni predefinite
• Prima di chiamare una funzione di libreria o delle costanti matematiche è
necessaria l’istruzione per importare la libreria in cui è definita la funzione o
costante di nostro interesse, altrimenti ogni chiamata a tale funzione restituirà
un errore
• Sintassi:
• from nome-libreria import nome-fun/const
• nome-libreria è il nome della libreria in cui è definita la funzione
• nome-fun/const può essere
• il nome di una specifica funzione o costante di tale libreria (questo consentirà di usare
solo tale funzione o costante)
• il simbolo * indicante tutte le funzioni e costanti di tale libreria

Lorenzo Putzu Laboratorio D’Informatica 22


Librerie di funzioni predefinite
• Ciononostante l’uso del simbolo * è considerata una cattiva abitudine
• bassa leggibilità del codice
• non è possibile stabilire con certezza da quale libreria è stata importata una determinata
funzione
• possibili conflitti con funzioni o costanti di altre librerie o definite dall’utente
• possibilità concreta di nascondere dei bug

• Preferibile importare le singole funzioni e rinominarle


• from nome-libreria import nome-fun/const as nuovo-nome

• Oppure importare l’intera libreria ed effettuare le chiamate di funzione come


segue
• import math
• math.sqrt(numero)

Lorenzo Putzu Laboratorio D’Informatica 23


Funzioni definite dall’utente
• Tutti i linguaggi di programmazione consentono inoltre ai programmatori di
definire nuove funzioni che sono sono dette definite dall’utente (user-defined) e
permettono di avere numerosi vantaggi:
• consentono di semplificare la scrittura di programmi complessi suddividendoli
in più parti (funzioni), ciascuna delle quali svolge un compito distinto dalle
altre, e può essere sviluppata in modo indipendente da esse
• l’esecuzione di una funzione può essere richiesta in diversi punti di uno stesso
programma, senza dover scrivere più volte le sue istruzioni
• una stessa funzione può essere usata in programmi diversi

Lorenzo Putzu Laboratorio D’Informatica 24


Funzioni definite dall’utente
• La sintassi della chiamata di tali funzioni è identica a quella delle funzioni predefinite.
• La definizione di una nuova funzione avviene attraverso l’istruzione def e si compone di:
• instestazione della funzione (la prima riga contenente il nome della funzione e dei parametri)
• corpo della fuzione che contiene la sequenza di istruzioni che dovrà eseguire

• Sintassi:
• def nome-funzione (par1, . . . , parn) :
corpo della funzione
• nome-funzione è un nome simbolico scelto dal programmatore, con gli stessi vincoli a cui sono soggetti
i nomi delle variabili
• par1, . . . , parn sono nomi (scelti dal programmatore) di variabili, dette parametri della funzione, alle
quali l’interprete assegnerà i valori degli argomenti che verranno indicati nella chiamata della funzione
• corpo della funzione è una sequenza di una o più istruzioni qualsiasi, ciascuna scritta in una riga
distinta, con un rientro di almeno un carattere, identico per tutte le istruzioni

Lorenzo Putzu Laboratorio D’Informatica 25


Funzioni definite dall’utente
• Tipicamente il corpo della funzione si conclude con l’istruzione return, che indica
anche il valore che la funzione dovrà restituire come risultato della sua chiamata
• Sintassi: return espressione
• dove espressione è un’espressione Python qualsiasi.
• Questa istruzione può essere usata solo solo all’interno di una funzione.
• Se una funzione non deve restituire nessun valore:
• l’istruzione return può essere usata, senza l’indicazione di nessuna espressione, per
concludere l’esecuzione della funzione
• se non si usa return, l’esecuzione della funzione terminerà dopo l’esecuzione dell’ultima
istruzione del suo corpo

Lorenzo Putzu Laboratorio D’Informatica 26


Funzioni definite dall’utente: chiamata
• L’esecuzione di un programma che contiene la definizione di una funzione non comporta
l’esecuzione delle istruzioni della funzione: tali istruzioni verranno eseguite solo
attraverso una chiamata della funzione.

• Come per le funzioni predefinite, anche per quelle definite dall’utente il numero di
argomenti indicati nella chiamata dovrà corrispondere al numero di argomenti previsti
nella definizione, cioè al numero dei parametri indicati nell’intestazione.

• L’interprete esegue la chiamata di una funzione nel modo seguente:


• copia il valore di ciascun argomento nel parametro corrispondente (quindi tali variabili
possiedono già un valore nel momento in cui inizia l’esecuzione della funzione)
• esegue le istruzioni del corpo della funzione, fino a incontrare l’istruzione return oppure
l’ultima istruzione del corpo
• se l’eventuale istruzione return è seguita da un’espressione, restituisce il valore di tale
espressione come risultato della chiamata

Lorenzo Putzu Laboratorio D’Informatica 27


Definizione di nuove funzioni: esempio
• Volendo definire una funzione che restituisce il più grande tra due numeri ricevuti in
input. Scegliamo massimo come nome della funzione, e a e b come nomi dei suoi
parametri. La funzione può essere definita come segue:
def massimo (a, b) :
if a > b :
return a
else :
return b
• Le variabili (parametri) a e b della funzione massimo avranno già un valore nel momento
in cui inizierà l’esecuzione delle istruzioni del corpo della funzione, periò non devono
essere definiti per mezzo di istruzioni di assegnamento nel corpo della funzione, ma
vengono definiti nella chiamata della stessa funzione.

Lorenzo Putzu Laboratorio D’Informatica 28


Funzioni senza argomenti o risultato
• Come caso particolare è possibile definire funzioni che non ricevono argomenti
oppure funzioni che non restituiscono un risultato.
• Se si vuole definire una funzione che non riceve argomenti, nell’intestazione si
dovranno solo scrivere le parentesi tonde, senza il nome di alcun parametro al
loro interno. In modo analogo, ci si comporterà nella chiamata alla funzione
• Se si vuole definire una funzione che non restituisce un risultato, non si dovrà
usare nel suo corpo nessuna istruzione return
def saluto() :
print (Buongiorno)

• Cosa succede se effettuo delle chiamata di funzione s = saluto() oppure


saluto(‘ciao’) ?

Lorenzo Putzu Laboratorio D’Informatica 29


Esercizi
6. Definire una funzione che riceva come argomento un numero
intero non negativo 𝑛 e ne restituisca il fattoriale

7. Definire una funzione che riceva come argomento un numero


intero non negativo 𝑛 e restituisca la somma dei primi 𝑛 termini
della serie armonica

Lorenzo Putzu Laboratorio D’Informatica 30


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 04
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Definizione di più funzioni nello stesso file
• È possibile scrivere in uno stesso file la definizione di più funzioni, cioè una
sequenza di istruzioni def, perciò dopo aver eseguito il file tutte le funzioni al suo
interno saranno disponibili nella shell, e potranno essere chiamate

• Nelle istruzioni del corpo di una funzione possono comparire chiamate di altre
funzioni, sia predefinite che definite dall’utente. Se si vuole chiamare una
funzione predefinita appartenente a una delle librerie Python sarà necessario
inserire prima della chiamata la corrispondente istruzione from-import.

• Di norma l’istruzione from-import viene inserita all’inizio del file che contiene la
definizione delle proprie funzioni, non nel corpo di una di esse.

Lorenzo Putzu Laboratorio D’Informatica 2


Definizione di funzioni con chiamate di funzioni
• Per poter chiamare dall’interno di una funzione un’altra funzione definita dall’utente sono
disponibili due alternative:
• la definizione delle due funzioni deve trovarsi nello stesso file
• le due funzioni possono essere definite in file diversi, ma tali file dovranno trovarsi in una
stessa cartella, e nel file che contiene la chiamata dell’altra funzione si dovrà inserire
l’istruzione from nome-file import nome-funzione, dove:
• – nome-file è il nome del file che contiene la definizione dell’altra funzione (senza
l’estensione .py)
• – nome-funzione è il nome di tale funzione

Lorenzo Putzu Laboratorio D’Informatica 3


Variabili locali e globali
• I parametri di una funzione e le eventuali altre variabili alle quali viene assegnato
un valore all’interno di essa sono dette locali, cioè vengono “create”
dall’interprete nel momento in cui la funzione viene eseguita (con una chiamata),
e vengono “distrutte” quando l’esecuzione della funzione termina.
• In particolare, se la chiamata della funzione viene scritta nella shell, e prima della
chiamata è stata definita nella shell una variabile con lo stesso nome di una delle
variabili della funzione:
• le due variabili vengono associate a celle di memoria distinte
• durante l’esecuzione della funzione l’interprete potrà accedere solo alla variabile associata
alla funzione, e non potrà quindi usare o modificare il valore della variabile avente lo stesso
nome definita nella shell, che manterrà il valore originale

Lorenzo Putzu Laboratorio D’Informatica 4


Variabili locali e globali
• Anche le variabili definite in funzioni diverse e aventi lo stesso nome sono variabili locali.

• Questo significa che se una funzione è chiamata da istruzioni che si trovano nel corpo di un’altra
funzione, ognuna di esse potrà accedere solo alle proprie variabili, e non potrà accedere a quelle
dell’altra funzione, né modificarle.

• Il fatto che le variabili definite in una funzione siano locali consente di definire nuove funzioni
senza preoccuparsi dell’eventuale presenza di variabili con lo stesso nome nei programmi che le
useranno.

• Analogamente, quando si scrive un programma che chiama funzioni predefinite o definite


dall’utente non ci si deve preoccupare dei nomi dei parametri e delle eventuali variabili definite in
tali funzioni.

Lorenzo Putzu Laboratorio D’Informatica 5


Variabili locali e globali
• Se invece all’interno di una funzione il nome di una variabile (che non sia uno dei
parametri) compare in un’espressione senza che in precedenza nella funzione sia
stato assegnato a essa alcun valore, tale variabile è considerata globale, cioè
l’interprete assume che il suo valore sia stato definito nelle istruzioni precedenti
la chiamata della funzione (scritte nella shell o in un programma); in caso
contrario si ottiene un messaggio d’errore.

• In questo modo le istruzioni di una funzione possono accede al valore di variabili


definite nella shell o nel programma chiamante. Tuttavia è preferibile evitare
l’uso di variabili globali nelle funzioni, poiché la loro presenza rende più difficile
assicurare la correttezza di un programma e comprenderne il funzionamento.

Lorenzo Putzu Laboratorio D’Informatica 6


Struttura dei programmi: update
• In un file è anche possibile scrivere un programma (cioè una sequenza di istruzioni) che
contenga sia istruzioni def per la definizione di funzioni, che altre istruzioni che chiamano
tali funzioni.
• L’unico vincolo è che ogni chiamata compaia dopo la definizione della funzione
corrispondente. Perciò di norma le definizioni di funzioni vengono scritte all’inizio del file.

from math import pi

def circ (raggio) :


circonferenza = 2*pi*raggio
return circonferenza

r = input ("Inserire il raggio: ")


print "La circonferenza è", circ(r)

Lorenzo Putzu Laboratorio D’Informatica 7


Struttura dei programmi: update
• Come si è detto in precedenza, nei linguaggi di alto livello la definizione di nuove
funzioni consente di strutturare un programma suddividendolo in diversi
“sottoprogrammi” (funzioni), ciascuno dei quali esegue un’operazione distinta e
indipendente dagli altri.
• Questo stile di programmazione è detto modulare.
• In particolare, è buona norma cercare di suddividere un programma in funzioni
che siano il più possibile brevi.
• La programmazione modulare presenta diversi vantaggi:
• semplifica la scrittura, la comprensione e la modifica dei programmi
• rende più facile l’individuazione di eventuali errori
• consente di usare una stessa funzione in programmi diversi

Lorenzo Putzu Laboratorio D’Informatica 8


Struttura dei programmi: update
• Un programma Python può essere strutturato suddividendolo in una o più funzioni e in una
(breve) sequenza di istruzioni da eseguire all’avvio del programma.

• Le funzioni e le istruzioni del programma “principale” potranno trovarsi in uno o più file. Nel caso
di più file si dovranno prevedere opportune istruzioni from-import.

• Per eseguire il programma si dovrà eseguire il file che contiene le istruzioni del programma
“principale”.

• In alternativa, anche le istruzioni del programma “principale” potranno essere scritte sotto forma
di funzione. In questo caso il programma potrà essere avviato chiamando dalla shell tale funzione.

Lorenzo Putzu Laboratorio D’Informatica 9


Esercizi
Scrivere un programma modulare che utilizzi le funzioni definite per gli
esercizi della lezione precedente (Lez03_es06, Lez03_es07). Il
programma dovrà chiedere all’utente di inserire un numero 𝑛 e dovrà:
• verificare se si tratta di un numero intero non negativo
• restituire il valore del fattoriale per 𝑛
• restituire la somma dei primi 𝑛 termini della serie armonica
• stampare a video entrambi i risultati

Testare tutte le soluzioni analizzate


1. Funzioni e programma principale in un unico file
2. Funzioni e programma principale in file separati

Lorenzo Putzu Laboratorio D’Informatica 10


Tipi di dati strutturati
• I tipi di dato vengono classificati a loro volta in:
• tipi semplici
• tipi strutturati
• Un tipo semplice è composto da valori che non possono essere “scomposti” in
valori più semplici ai quali sia possibile accedere attraverso operatori o funzioni
del linguaggio.
• Esempi di tipi semplici sono i numeri interi, i numeri frazionari e i valori
Booleani.

Lorenzo Putzu Laboratorio D’Informatica 11


Tipi di dati strutturati
• Un tipo strutturato è invece composto da valori che sono a loro volta collezioni o
sequenze di valori più semplici.
• Le stringhe sono un tipo strutturato: sono infatti composte da sequenze
ordinate di caratteri a ciascuno dei quali è possibile accedere
individualmente, come si vedrà più avanti.

• Oltre alle stringhe, due dei principali tipi strutturati del linguaggio Python sono:
• le liste, che consentono di rappresentare sequenze ordinate di valori
qualsiasi
• i dizionari, che consentono di rappresentare collezioni (non ordinate) di valori
qualsiasi

Lorenzo Putzu Laboratorio D’Informatica 12


Le liste
• In molte applicazioni i dati da elaborare sono costituiti da sequenze ordinate di
valori più semplici.
• Per esempio, le coordinate di un punto o gli elementi di un vettore in un dato
sistema di riferimento possono essere rappresentati come una sequenza ordinata
di numeri reali.
• Nei programmi è conveniente poter rappresentare dati di questa natura come
singoli valori composti, per esempio associando le coordinate di un punto in uno
spazio a tre dimensioni a una singola variabile invece che a tre variabili distinte.
• Come si è già visto, nel caso particolare delle sequenze di caratteri questo è reso
possibile dal tipo di dato stringa.

Lorenzo Putzu Laboratorio D’Informatica 13


Le liste
• Il tipo lista fornisce questa possibilità per sequenze ordinate di valori che possono
appartenente a tipi qualsiasi, anche diversi tra loro.
• Una lista si rappresenta nei programmi Python come una sequenza ordinata di
valori scritti tra parentesi quadre e separati da virgole
• Esempi:
• [7, -2, 4]
una lista composta da tre numeri interi
• [-5.3, 6, True]
una lista composta da un numero reale, un numero intero e un valore logico
• []
una lista vuota
Lorenzo Putzu Laboratorio D’Informatica 14
Le liste
• Una lista può essere assegnata direttamente ad una variabile come una qualsiasi espressione
• vettore = [7, -2, 4]
• E può anche essere acquisita attraverso la tastiera
• v = eval(input("Inserire una lista: "))
• Poiché gli elementi di una lista possono essere valori di un tipo qualsiasi, possono a loro volta
essere delle altre espressioni o delle altre liste: inquest’ultimo caso si parla di liste nidificate. Per
esempio dopo l’esecuzione delle seguente sequenza di istruzioni:
• x=2
• y = -5
• z = [y**2 + 1, “ciao”,x == 3, ["a", "b"]]
• la variabile z sarà associata ad una lista di quattro elementi: un numero intero, una stringa,
un valore logico ed una lista di due elementi: [26, "ciao", False, ["a", "b"]]

Lorenzo Putzu Laboratorio D’Informatica 15


Le liste: indicizzazione
• Come per gli altri tipi di dato, anche per le liste il linguaggio Python mette a
disposizione dei programmatori diversi operatori e funzioni predefinite.
• In particolare, essendo le liste un tipo strutturato, alcuni operatori consentono
l’accesso ai singoli elementi di una lista. Dato che la lista è una sequenza ordinata
ogni elemento è identificato univocamente dalla sua posizione
• L’operatore di indicizzazione consente di accedere a ogni singolo elemento di una
lista, per mezzo dell’indice corrispondente
• Sintassi: lista[indice]
• lista indica il nome di una variabile alla quale sia stata in precedenza assegnata una
lista
• indice deve essere un’espressione il cui valore sia un intero compreso tra 0 e la lunghezza
della lista meno uno.

Lorenzo Putzu Laboratorio D’Informatica 16


Le liste: indicizzazione
• Il risultato dell’operazione di indicizzazione è il valore dell’elemento di lista nella
posizione corrispondente al valore di indice. Se il valore di indice non corrisponde
a una delle posizioni della lista si otterrà un messaggio d’errore.

• L’operatore di indicizzazione consente anche di modificare i singoli elementi di


una lista, attraverso un’istruzione di assegnamento.
• Sintassi: lista[indice] = espressione
• dove espressione indica una qualsiasi espressione Python
• Percio l’elemento di lista nella posizione corrispondente a indice viene sostituito
dal valore di espressione.

Lorenzo Putzu Laboratorio D’Informatica 17


Le liste: slicing
• L’ operatore di slicing in modi simile all’operatore di indicizzazione è basato sull’uso di indici, ma
restituisce non solo un elemento della lista ma una lista composta da una sottosequenza della
lista originale
• Sintassi: lista[indice1:indice2]
• dove indice1 e indice2 sono espressioni i cui valori devono essere numeri interi compresi tra
0 e la lunghezza di lista.
• Il risultato è una lista composta dagli elementi di lista aventi indici da indice1 a indice2 - 1
(l’elemento all’indice indice2 non viene incluso nel risultato).
• Anche l’operatore di slicing consente di modificare gli elementi di una lista, attraverso
un’istruzione di assegnamento.
• Sintassi: lista[indice1:indice2] = lista2
• dove lista2 indica un’ulteriore lista, che non deve avere necessariamente le stesse dimensioni
dello spazio indicizzato dallo porzione selezionata

Lorenzo Putzu Laboratorio D’Informatica 18


Le liste: inserimento e cancellazione
• Dato che le dimensioni delle porzioni delle liste non deve coincidere vuol dire che
possiamo ingrandire o rimpicciolire la lista
• Possiamo anche assegnare ad una porzione di lista una lista vuota, il che significa
cancellare quegli elementi dalla lista, ad esempio con le istruzioni
Lista = ['a', 'b', 'c', 'd', 'e', 'f']
Lista[1:3] = []
• daremo vita ad una lista con i seguenti elementi ['a', 'd', 'e', 'f’]
• Allo stesso modo possiamo anche assegnare nuovi elementi ad una porzione di
lista ‘vuota’, ad esempio con l’istruzione
Lista = ['a', 'd']
Lista[1:1] = ['b', 'c’]
• daremo vita ad una lista con i seguenti elementi ['a', 'b', 'c', 'd']

Lorenzo Putzu Laboratorio D’Informatica 19


Le liste: concatenazione
• Questo operatore è analogo al corrispondente operatore del tipo di dato stringa.
• Sintassi: lista1 + lista2
• La concatenazione produce una nuova lista composta dagli elementi di lista1
seguiti da quelli di lista2, disposti nellostesso ordine in cui si trovano nelle due
liste.
• Le liste originali non vengono modificate.

Lorenzo Putzu Laboratorio D’Informatica 20


Le liste: confronto
• Gli operatori == e != consentono di scrivere espressioni condizionali (il cui valore
sarà True o False) consistenti nel confronto tra due liste.
• Sintassi:
• lista1 == lista2
• lista1 != lista2
• dove lista1 e lista2 indicano due liste, che sono considerate identiche se sono
composte dallo stesso numero di elementi, e se ogni elemento ha valore identico
a quello dell’elemento che si trova nella stessa posizione nell’altra lista.

Lorenzo Putzu Laboratorio D’Informatica 21


Le liste: in e not in
• Questi operatori consentono di scrivere espressioni condizionali che hanno lo
scopo di verificare se un certo valore sia presente o meno all’interno di una lista.
• Sintassi:
• espressione in lista
• espressione not in lista
• dove espressione indica una qualsiasi espressione Python e se il valore di
espressione è presente tra gli elementi di lista l’operatore in produce il valore
True; in caso contrario produce False. Il comportamento dell’operatore not in è
quello opposto. La ricerca non viene estesa agli elementi di eventuali liste
nidificate all’interno di lista.

Lorenzo Putzu Laboratorio D’Informatica 22


Le liste: funzioni predefinite
• Alcune funzioni predefinite di utilità generale sono le seguenti:
• len(lista)
restituisce la lunghezza di una lista
• min(lista)
restituisce l’elemento più piccolo di una lista composta da numeri
• max(lista)
restituisce l’elemento più grande di una lista composta da numeri
• sum(lista)
restituisce la somma di una lista composta da numeri

Lorenzo Putzu Laboratorio D’Informatica 23


Le liste: costruzione per concatenazione
• In molti programmi è necessario costruire una lista composta da valori che dovranno essere acquisiti
durante l’esecuzione degli stessi programmi. La lista non può quindi essere scritta in modo esplicito al loro
interno, ma dovrà essere ottenuta come risultato di un’opportuna sequenza di operazioni. Per esempio, è
possibile costruire una lista attraverso l’operatore di concatenazione, partendo da una lista vuota.
• Esempio
print("Inserire cinque numeri.")
lista = [ ]
k = 1
while k <= 5 :
elemento = input("Prossimo valore: ")
lista = lista + [elemento]
k = k + 1
print("La lista è:", lista)

Lorenzo Putzu Laboratorio D’Informatica 24


Le liste: funzioni predefinite
• Le liste contenenti numeri sono le più comuni e per questo motivo Python fornisce un
modo semplice per crearle
• La classe range infatti restituisce un ‘oggetto’, composto da una sequenza immutabile
di numeri, che può essere facilmente trasformato in una lista
• Sintassi:
• range(a)
se a > 0, crea un oggetto con numeri nell’intervallo [0, a)
• range(a, b)
se a e b > 0, crea un oggetto con numeri nell’intervallo [a, b)
• range(a, b, s)
se a e b > 0, crea un oggetto con numeri nell’intervallo [a, b) distanziati tra loro di s
• list(range(..))
restituisce una lista con numeri nell’intervallo definito da range

Lorenzo Putzu Laboratorio D’Informatica 25


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 05
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Le liste: funzioni iterative
• L’uso di variabili per rappresentare gli indici di una lista consente di esprimere in
modo conciso, attraverso un’istruzione iterativa, la ripetizione di una stessa
sequenza di istruzioni su tutti gli elementi di una lista.
• Questo è possibile usando una variabile nel ruolo di indice e la funzione len, che
consente di applicare la sequenza di istruzioni anche a liste delle quali non è nota
la lunghezza nel momento in cui si scrive il programma.
k = 0
while k < len(lista):
istruzioni che coinvolgono lista[k]
k = k + 1
• Notare anche la condizione k < len(lista) nell’istruzione while: il valore dell’indice
dell’ultimo elemento è infatti pari alla lunghezza della lista meno uno.
Lorenzo Putzu Laboratorio D’Informatica 2
Le liste: funzioni iterative
• Come altri linguaggi, anche Python include una versione alternativa dell’istruzione
iterativa while che è l’istruzione for.
• Nel caso di Python l’istruzione for consente di esprimere un iterazione in modo molto più
conciso accedendo iterativamente a tutti gli elementi di una sequenza (stringa o lista)
• Sintassi
for v in s :
sequenza di istruzioni
• v deve essere il nome di una variabile che non sia già usata per memorizzare dati
all’interno dello stesso programma
• s deve essere un’espressione avente come valore una sequenza (una lista o una stringa)
• sequenza di istruzioni è una sequenza di una o più istruzioni qualsiasi che di norma
eseguono un’operazione sulla variabile v

Lorenzo Putzu Laboratorio D’Informatica 3


Le liste: funzioni iterative
• La sequenza di istruzioni viene eseguita per un numero di volte pari alla lunghezza di s.
• Nella i-esima iterazione, prima dell’esecuzione di sequenza di istruzioni viene assegnato alla
variabile v il valore dell’i-esimo elemento di s; la sequenza di istruzioni può quindi elaborare tale
valore accedendo a v.
• L’istruzione for non richiede l’uso esplicito degli indici per accedere agli elementi di una sequenza,
controllo che con l’istruzione while è demandato al programmatore
• Esempio
lista = list(range(0, 50, 5))
print("I suoi elementi sono:")
for elemento in lista :
print(elemento)

Lorenzo Putzu Laboratorio D’Informatica 4


Le liste: funzioni iterative
• Tuttavia, v contiene una copia degli elementi di s: questo significa che, se s è una
lista, non sarà possibile modificare i suoi elementi assegnando nuovi valori a v.

• Non sarà comunque possibile modificare il valore di un elemento di una lista,


attraverso un’istruzione di assegnamento che richieda l’uso esplicito degli indici
come lista[k] = valore

• Non si potrà accedere nello stesso passo di un’iterazione a più di un elemento di


una sequenza, per esempio per confrontare i valori di due elementi adiacenti
come if s[k] != s[k + 1] :

Lorenzo Putzu Laboratorio D’Informatica 5


Le liste: funzioni iterative
• È comunque possibile, anche con l’istruzione for, accedere agli elementi di una
sequenza s usando una variabile come indice: a questo scopo l’istruzione for
deve essere applicata non a s, ma ad una sequenza s2 che contenga i valori degli
indici di s, nell’ordine desiderato, secondo lo schema seguente:
for k in s2 :
istruzioni che accedono a s[k]
• In particolare, se si vuole accedere a s dal primo all’ultimo elemento, la sequenza
s2 dovrà contenere gli interi da 0 alla lunghezza di s meno uno, e quindi può
essere ottenuta usando la funzione predefinita range già vista in precedenza:
for k in range(len(s))
istruzioni che accedono a s[k]

Lorenzo Putzu Laboratorio D’Informatica 6


Le liste: funzioni iterative
• Un’ulteriore alternativa consiste nell’uso della funzione predefinita di Python enumerate, che
permette di scorrere contemporanemente gli elementi della lista e i corrispondenti indici
• Sintassi
for i, v in enumerate(s) :
sequenza di istruzioni
• i contiene gli indici corrispondenti agli elementi v nella sequenza s
• v come prima contiene una copia degli elementi di s

• Esempio
for i, v in enumerate(lista) :
print("indice :", i)
print("elemento :" ,v)

Lorenzo Putzu Laboratorio D’Informatica 7


Esercizi
1. Definire una funzione (analoga a range) che, dato un intero 𝑛,
restituisca una lista composta da tutti gli interi da 0 a 𝑛 − 1, se 𝑛 è
positivo, oppure una lista vuota
2. Definire una funzione (analoga a sum) che, data una lista composta
da numeri, resituisca la loro somma. Definire due versioni della
funzione: usando while e usando for
3. Definire una funzione che, date due liste composte da numeri e
aventi la stessa lunghezza, restituisca una lista della stessa
lunghezza contenente le somme dei loro elementi. Esempio:
[4, 1, 2], [0, -3, 7] → [4, -2, 9]

Lorenzo Putzu Laboratorio D’Informatica 8


Le liste: ulteriori funzioni predefinite
Altre funzioni (metodi) di utilità generale sono le seguenti:
• lista.append(espressione)
aggiunge espressione come ultimo elemento di lista
• lista.insert(index,espressione)
aggiunge espressione in lista alla posizione indicata da index
• lista.index(espressione)
se espressione esiste restituisce il suo indice altrimenti da un errore
• lista.count(espressione)
restituisce il numero di volte in cui espressione appare nella lista

Lorenzo Putzu Laboratorio D’Informatica 9


Le liste: ulteriori funzioni predefinite
Altre funzioni (metodi) di utilità generale sono le seguenti:
• lista.remove(espressione)
se espressione esiste lo rimuove dalla lista altrimenti da errore
• lista.pop(index)
rimuove e restituisce l’elemento alla posizione indicata da index
• lista.clear()
svuota la lista
• lista.sort()
riordina la lista in ordine crescente
• lista.reverse()
Inverte l’ordine degli elementi della lista

Lorenzo Putzu Laboratorio D’Informatica 10


Le liste e le stringhe: similitudini
• Le stringhe e le liste sono tipi di dato che hanno in comune il fatto di essere
costituite da sequenze ordinate di un numero qualsiasi di elementi. Per questo
motivo sono entrambe indicate in linguaggio Python con il termine più generale
di sequenze.
• Alcuni operatori e alcune funzioni predefinite che operano su sequenze ordinate
possono essere applicati sia alle liste che alle stringhe (come si è già visto per
l’operatore di concatenazione):
• operatori: in e not in, indicizzazione, slicing

Lorenzo Putzu Laboratorio D’Informatica 11


Le liste e le stringhe: differenze
• Liste e stringhe presentano però una differenza fondamentale:
• attraverso l’istruzione di assegnamento e l’operatore di indicizzazione si è
visto che è possibile modificare i singoli elementi di una lista: le liste sono
perciò dette sequenze mutabili
• non è invece possibile modificare i singoli caratteri delle stringhe, che per
questo sono dette immutabili (il tentativo di modificare un elemento di una
stringa produce un errore)

Lorenzo Putzu Laboratorio D’Informatica 12


Le stringhe
• Esistono delle ulteriori funzioni predefinite per le stringhe che sono molto utili per la loro
eleborazione, in particolare quando si acquisiscono stringhe da tastiera o (come vedremo più
avanti) da file di testo.
• La funzione predefinita split ad esempio suddivide una stringa in corrispondenza dei caratteri di
spaziatura (incluso il newline) e restituisce una lista contenente le corrispondenti sottostringhe,
nelle quali non vengono inclusi i caratteri di spaziatura (la stringa originale non viene modificata)
• La sintassi della chiamata è diversa da quella vista in precedenza (vedremo in seguito il motivo)
• Sintassi
stringa.split()
• Ad esempio con le istruzioni
stringa = "Questa è una frase."
stringa.split()
• daremo vita ad una lista con i seguenti elementi ["Questa", "è", "una", "frase."]
Lorenzo Putzu Laboratorio D’Informatica 13
Le stringhe
• É inoltre possibile suddividere una stringa in corrispondenza di una sequenza di uno o più
caratteri qualsiasi che non siano il carattere di spaziatura o il newline, tale sequenza dovrà essere
indicata (sotto forma di una stringa) come argomento di split, con la seguente sintassi:
stringa.split(caratteri)

• Per esempio, se la variabile stringa contenesse una stringa composta da una sequenza di numeri
separati da una virgola (senza spazi), potremmo suddividere la stringa con le seguenti istruzioni
stringa = "15,1,25,9,6,21"
stringa.split(",")
• otterremo la lista ["15", "1", "25", "9", "6", "21"]

Lorenzo Putzu Laboratorio D’Informatica 14


Le stringhe: funzioni predefinite
• Alcune funzioni predefinite di utilità generale sono le seguenti:
• len(stringa)
restituisce la lunghezza di una stringa
• str(espressione)
restituisce espressione sotto forma di stringa
• stringa.count(stringa2)
restituisce il numero di volte in cui stringa2 appare nella stringa
• stringa.find(stringa2)
restituisce la posizione in cui stringa2 appare per la prima volta nella stringa
• stringa.isnumeric()
restituisce True se tutti i caratteri nella stringa sono numerici

Lorenzo Putzu Laboratorio D’Informatica 15


Le stringhe: funzioni predefinite
• Altre funzioni predefinite utili per l’elaborazione e il confronto tra stringhe:
• stringa.replace(stringa2,stringa3)
rimpiazza le occorrenze di stringa2 con stringa3
• stringa.lower()
converte la stringa in minuscolo
• stringa.upper()
converte la stringa in maiuscolo
• stringa.capitalize()
converte il primo carattere della stringa in maiuscolo

Lorenzo Putzu Laboratorio D’Informatica 16


Esercizio
4. Modificare il programma della lezione precedente (Lez04_es01)
• aggiungendo un ulteriore funzione per il calcolo della circonferenza dato il raggio 𝑛
• richiedere un’ulteriore parametro di tipo stringa all’utente in modo che possa decidere che
calcolo effettuare, quindi i possibili valori potrebbero essere: circonferenza, fattoriale e serie
armonica
• modificando la funzione per il controllo del numero inserito dall’utente, in modo che verifichi
se si tratta di un numero intero non negativo 𝑛 se il calcolo richiesto è uno tra fattoriale e
serie armonica, oppure possa essere un float o intero se il calcolo richiesto è la circonferenza

• Plus: l’utente potrebbe anche chiamare la funzione principale (ad esempio ‘calcola’) come
segue
>>> calcola(‘fattoriale’,6)

Lorenzo Putzu Laboratorio D’Informatica 17


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 06
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Sequenze nidificate
• Dato che gli elementi di una lista possono essere valori di tipi qualsiasi, possono essere quindi
anche dei dati strutturati, come stringhe o altre liste.
• L’operatore di indicizzazione consente di accedere anche agli elementi di strutture nidificate.
• Se s è una variabile a cui è stata assegnata una lista, e l’elemento di indice i è a sua volta una
sequenza (lista o stringa), sarà possibile accedere all’elemento di indice j di quest’ultima con la
seguente sintassi:

s[i][j]

• Una delle possibili applicazioni delle liste è la rappresentazione di vettori e analogamente, le liste
nidificate possono essere convenientemente usate per rappresentare matrici, cioè entità
bidimensionali.

Lorenzo Putzu Laboratorio D’Informatica 2


Liste nidificate
• È possibile rappresentare una matrice con una lista nidificata, in modo da ottenere una corrispondenza
diretta e intuitiva tra gli indici di riga e colonna di un elemento della matrice e quelli dello stesso elemento
della lista.
• Questo risultato si ottiene considerando una matrice come una sequenza ordinata di m righe, ciascuna delle
quali è a sua volta una sequenza ordinata di n valori semplici (numeri reali). Ogni riga può quindi essere
rappresentata con una lista di n numeri, mentre l’intera matrice sarà rappresentata da una lista di m liste
(righe della matrice).
• In questo modo l’elemento della matrice nella i-esima riga e nella j-esima colonna corrisponderà
all’elemento della lista avente indici i - 1 e j - 1.

−3 1 4
2 5 −1
= [[-3, 1, 4], [2, 5, -1]]

Lorenzo Putzu Laboratorio D’Informatica 3


Esercizi
1. Scrivere una fuzione che data una matrice memorizzata in una lista nidificata, stampi il contenuto della
matrice
2. Stampare la tavola pitagorica dei numeri da 1 a 10 sotto forma di una matrice:

1 2 3 ... 9 10
2 4 6 ... 18 20
... ... ...
10 20 30 ... 90 100

3. Definire una funzione che acquisisca come argomento una lista 𝐿 e restituisca una nuova lista contenente
tutti gli elementi che compaiono in 𝐿 una sola volta. Esempio: [3, 1, 5, 1, 6, 2, 9, 6] → [3, 5, 2, 9]

Lorenzo Putzu Laboratorio D’Informatica 4


Dizionari
• Le liste consentono di rappresentare dati strutturati i cui valori siano composti da
una sequenza ordinata di valori più semplici.

• Un altro caso comune nella pratica è quello in cui i valori dei dati da elaborare
siano rappresentabili come collezioni (insiemi) di valori più semplici e non
ordinati, ciascuno dei quali abbia un significato che possa essere descritto con un
nome simbolico.

• Un esempio sono le informazioni anagrafiche su una persona come nome,


cognome, data e luogo di nascita, codice fiscale, ecc.

• I dati aventi tali caratteristiche possono essere rappresentati in Python per mezzo
del tipo strutturato dizionario.

Lorenzo Putzu Laboratorio D’Informatica 5


Dizionari
• Il tipo di dato dizionario è costituito da collezioni non ordinate di un numero
qualsiasi di elementi, ciascuno dei quali è composto da un valore di un tipo
qualsiasi, e da una chiave che lo identifica univocamente

• In altre parole, un dizionario è un insieme di coppie chiave–valore non ordinate,


alle quali si può accedere solo attraverso la chiave corrispondente.

• Le chiavi devono essere scelte dal programmatore, e possono essere valori


numerici o Booleani, oppure nella maggior parte dei casi si tratta di stringhe.
Nella scelta delle chiavi è buona norma usare simboli mnemonici.

Lorenzo Putzu Laboratorio D’Informatica 6


Dizionari
• Le sequenze di coppie chiave–valore possono essere definite in maniera schematica
racchiudendole tra parentesi graffe e separate tra loro dalla virgola ‘,’ mentre in ogni coppia, la
chiave e il valore sono separati dal carattere ‘:’
• Sintassi
{chiave1:valore1, chiave2:valore2, . . . }
• Ad esempio un dizionario che contiene informazioni anagrafiche su una persona: nome, cognome
ed età può essere definito come
{"nome":"Maria", "cognome":"Bianchi", "eta":28}
• Un dizionario che contiene le coordinate di un punto nel piano cartesiano
{"x":-1.2, "y":3.4}
• Un dizionario che contiene una data (giorno, mese e anno)
{"giorno":1, "mese":6, "anno": 2017}
• infine un dizionario vuoto:
{}

Lorenzo Putzu Laboratorio D’Informatica 7


Dizionari
• Anche i valori di tipo dizionario costituiscono espressioni Python. È quindi possibile:
• scrivere un dizionario nella shell: dopo la pressione del tasto INVIO, il dizionario verrà
mostrato nella stessa shell
• stampare un dizionario con l’istruzione print, per esempio:
print({"x":-1.2, "y": 3.4})
• assegnare un dizionario a una variabile, per esempio:
punto = {"x":-1.2, "y": 3.4}
• acquisire un dizionario attraverso la tastiera, per esempio:
d = eval(input("Inserire un dizionario: "))
• Nota: quando un dizionario viene mostrato nella shell le coppie chiave/valore compaiono in un
ordine che non può essere controllato dal programmatore.

Lorenzo Putzu Laboratorio D’Informatica 8


Dizionari
• Così come per le liste, anche i valori degli elementi di un dizionario possono
essere indicati attraverso espressioni. Per esempio, dopo l’esecuzione della
seguente sequenza di istruzioni:
n = "Maria"
c1 = "Ros"
c2 = "si"
a = 5
persona = "nome":n, "cognome":c1 + c2, "età":a**2
• la variabile persona sarà associata al seguente dizionario: "nome":"Maria",
"cognome":"Rossi", "età":25

Lorenzo Putzu Laboratorio D’Informatica 9


Dizionari
• Inoltre, anche i valori degli elementi di un dizionario possono appartenere a un tipo qualsiasi, e
quindi possono essere valori strutturati come stringhe, liste e dizionari (nidificati).
• Per esempio, il dizionario seguente contiene il nome, il cognome e la data di nascita di una
persona (giorno, mese e anno):
persona = {"nome":"Maria", "cognome":"Rossi", "g":1, "m":1, "a":1995}
• Le stesse informazioni possono essere memorizzate in una forma più strutturata con due dizionari
nidificati:
data = {"g":1, "m":1, "a":1995}
persona = {"nome":"Maria", "cognome":"Rossi", "data_nascita":data}

Lorenzo Putzu Laboratorio D’Informatica 10


Dizionari: indicizzazione
• Anche per i dizionari esistono diversi operatori e funzioni predefinite.
• L’operatore principale è quello che consente l’accesso ai valori dei singoli elementi. Il
nome (indicizzazione) e la sintassi sono identici a quelli dell’analogo operatore per le
liste, con la differenza che gli elementi di una lista sono ordinati e quindi identificati
univocamente dalla loro posizione (indice), mente gli elementi di un dizionario non
hanno un ordine predefinito ma sono identificati dalla loro chiave.
• L’operatore di indicizzazione consente di accedere al valore di ogni elemento di un
dizionario, per mezzo della chiave corrispondente.
• Sintassi:
dizionario[chiave]
• dizionario deve essere un’espressione che produca un dizionario (di norma, il nome di
una variabile)
• chiave deve essere un’espressione il cui valore corrisponda a una delle chiavi del
dizionario

Lorenzo Putzu Laboratorio D’Informatica 11


Dizionari: indicizzazione
• Il risultato dell’operatore di indicizzazione è il valore dell’elemento di dizionario
associato a chiave. Se il valore di chiave non corrisponde a una delle chiavi del
dizionario si otterrà un messaggio d’errore.
• L’operatore di indicizzazione consente anche di:
• modificare il valore associato a una chiave esistente
• aggiungere una nuova coppia chiave–valore, la cui chiave non sia presente nel
dizionario
• Sintassi:
dizionario[chiave] = valore
• Se chiave fa parte di dizionario, il valore corrispondente viene sostituito da valore;
altrimenti viene aggiunto al dizionario l’elemento chiave:valore

Lorenzo Putzu Laboratorio D’Informatica 12


Dizionari: costruzione
• Questo vuol dire che possiamo costruire un dizionario attraverso l’operatore di indicizzazione, a
partire da un dizionario vuoto.
• In molti programmi è necessario costruire un dizionario avente un insieme di chiavi predefinito
dal programmatore, alle quali dovranno essere associati valori acquisiti durante l’esecuzione del
programma.
• Ad esempio quando è necessario memorizzare i dati di un nuovo utente (che non conosce il
linguaggio Python) possiamo demandare all’utente stesso di inserire i propri dati e memorizzarli
un dizionario opportuno. Ad esempio con la seguente sequenza di istruzioni
persona = {}
print("Inserire i seguenti dati anagrafici:")
persona["nome"] = input("Nome: ")
persona["cognome"] = input("Cognome: ")
persona["età"] = eval(input("Età: "))
print("I dati inseriti sono:", persona)

Lorenzo Putzu Laboratorio D’Informatica 13


Dizionari: operatori di confronto
• Gli operatori == e != consentono di scrivere espressioni condizionali (il cui valore
sarà True o False) consistenti nel confronto tra due dizionari.
• Sintassi:
dizionario1 == dizionario2
dizionario1 != dizionario2
• dove dizionario1 e dizionario2 indicano espressioni che abbiano come valore un
dizionario.
• Il risultato della prima espressione condizionale è vero (quindi i dizionari sono
considerati identici) se contengono le stesse coppie chiave/valore,
indipendentemente dal loro ordine.
• {"x":-1.2, "y":3.4} == {"y":3.4, "x":-1.2} → True

Lorenzo Putzu Laboratorio D’Informatica 14


Dizionari: in e not in
• Questi operatori consentono di scrivere espressioni condizionali che hanno lo
scopo di verificare se una certa chiave sia presente o meno all’interno di un
dizionario.
• Sintassi:
• espressione in dizionario
• espressione not in dizionario
• dove espressione indica una qualsiasi espressione Python e se il valore di
espressione è presente tra le chiavi del dizionario l’operatore in produce il valore
True; in caso contrario produce False. Il comportamento dell’operatore not in è
quello opposto.

Lorenzo Putzu Laboratorio D’Informatica 15


Dizionari nidificati
• Si è già detto che anche i valori associati alle chiavi di un dizionario possono
appartenere a qualsiasi tipo di dato, e possono quindi essere a loro volta dati
strutturati, cioè stringhe, liste e dizionari.
• Gli elementi di dati strutturati contenuti in un dizionario sono a loro volta
accessibili attraverso l’operatore di indicizzazione, con la stessa sintassi già
descritta per il caso di strutture nidificate all’interno di una lista.
• In particolare, se d è una variabile a cui è stato assegnato un dizionario, e
l’elemento d[chiave] è un valore strutturato (una sequenza o un altro dizionario),
sarà possibile accedere all’elemento di tale valore avente indice (se si tratta di
una sequenza) o chiave(se si tratta di un dizionario) k con la seguente sintassi:
d[chiave][k]

Lorenzo Putzu Laboratorio D’Informatica 16


Dizionari: funzioni predefinite
• Alcune metodi e funzioni predefinite di utilità generale sono le seguenti:
• len(dizionario)
restituisce la lunghezza di un dizionario
• dizionario.keys()
restituisce le chiavi di un dizionario
• dizionario.values()
restituisce i valori di un dizionario
• dizionario.items()
restituisce gli elementi di un dizionario come un insieme di coppie chiave/ valore
• dizionario.pop(key)
se esiste elimina e restituisce il valore dell’elemento con chiave key,
altrimentirestituisce un errore

Lorenzo Putzu Laboratorio D’Informatica 17


Dizionari: funzioni iterative
• Come per le liste anche per i dizionari è possibile usare l’istruzione for
accedendo iterativamente a tutte le chiavi del dizionario
• Sintassi
for k in d :
sequenza di istruzioni
• k deve essere il nome di una variabile che non sia già usata per memorizzare dati
all’interno dello stesso programma
• d deve essere un’espressione avente come valore un dizionario
• sequenza di istruzioni è una sequenza di una o più istruzioni qualsiasi che di
norma eseguono un’operazione sulla variabile k

Lorenzo Putzu Laboratorio D’Informatica 18


Dizionari: funzioni iterative
• Tuttavia, a differenza delle liste k contiene la chiave del dizionario perciò questo
significa che sarà possibile modificare i suoi elementi assegnando nuovi valori a d
inserendo nella sequenza di istruzioni un assegnamento del tipo
d[k]= espressione
• dove espressione è una qualsiasi espressione del linguaggio python
• E’ comunque possibile eseguire delle iterazioni sui dizionari richiamando
contemporaneamente la chiave e il valore, sfruttando il metodo items
for k, v in d.items() :
sequenza di istruzioni
• k come prima contiene le chiavi del dizionario d
• v contiene una copia del valore corrispondente in d

Lorenzo Putzu Laboratorio D’Informatica 19


Strutture dati
• La scrittura di un programma si compone di due fasi fondamentali:
• la formulazione di un algoritmo
• la scelta delle strutture dati per rappresentare i dati da elaborare

• La scelta delle strutture dati più opportune è un passo fondamentale in quanto influenza la
complessità del programma che si scriverà o ne pregiudica la codifica.

• Volendo memorizzare un singolo utente (come visto prima) la scelta di un dizionario potrebbe
essere sufficiente, ma dovendo memorizzare n utenti tale scelta diventerebbe troppo dispersiva,
dato che sarebbero necessarie n variabili di tipo dizionario
• inoltre n potrebbe non essere noto a priori
• l’uso di istruzioni iterative non sarebbe possibile

Lorenzo Putzu Laboratorio D’Informatica 20


Strutture dati
• Per memorizzare i dati di un utente avrei potuto utilizzare anche una lista, dato che può
contenere anche dati eterogenei

• Un dizionario però è preferibile in questo caso in quanto ad ogni valore corrisponde un’etichetta
chiara che consente infatti al programmatore di ricordare facilmente il significato di ciascun elemento
attraverso la chiave corrispondente, purché si usino chiavi mnemoniche

• L’uso di una lista invece richiederebbe una costante attenzione per ricordare (o consultare la porzione di
codice in cui è definita la lista) a quale componente equivale un determinato indice della lista
• persona_a = {"nome":"Ada", "cognome":"Neri", "età":25}
• persona_b = ["Ada", "Neri", 25]

Lorenzo Putzu Laboratorio D’Informatica 21


Esercizi
4. Definire una funzione che riceva come argomenti tre numeri
rappresentanti una data (giorno, mese e anno) e restituisca un
dizionario contenente i tre valori associati alle chiavi "giorno",
"mese" e "anno".
Esempio: {"giorno":8, "mese":10, "anno":2019}

5. Definire una funzione che, dato un numero di persone, acquisisca


nome, cognome ed età di ciascuna di esse e memorizzi tali dati in
una lista di dizionari aventi chiavi "nome", "cognome", "eta'".
Esempio:
{"nome":"Ugo", "cognome":"Gui", "eta'":25}

Lorenzo Putzu Laboratorio D’Informatica 22


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 07
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Sets
• Un set o insieme è una collezione non ordinata di oggetti e può essere visto come
un dizionario che contenga solo chiavi e non valori. Anche in questo caso gli
elementi di un set possono essere valori numerici o Booleani, oppure nella
maggior parte dei casi si tratta di stringhe.

• Lo stesso elemento non puo comparire più di una volta, per cui creare un insieme
a partire da una lista o una sequenza equivale ad eliminarne i duplicati

• Anche gli insiemi come i dizionari sono sequenze non ordinate

Lorenzo Putzu Laboratorio D’Informatica 2


Sets
• Un set puo essere creato come elenco di oggetti tra parentesi graffe e separati tra loro tramite la
virgola, come ad esempio
frutta = {"mele", "pere", "banane", "susine"}
insieme = {"persone", 10, "numeri", False}
• Oppure può essere creato passando alla funzione set una sequenza ordinata (stringa o lista)
set(range(10))
set([10,"persona",False])
• Un set vuoto puo essere creato usando la funzione set senza argomenti (ricordiamoci che {} crea un
dizionario vuoto).
• ATTENZIONE però all’uso della funzione set in quanto per definizione accetta un solo parametro di
input e il suo comportamento cambia notevolmente in base al tipo di dato passato in input. Ad
esempio le istruzioni che seguono hanno un esito completamente diverso
• set("ciao")
• set(["ciao"])

Lorenzo Putzu Laboratorio D’Informatica 3


Sets: unione
• L’operazione di unione tra due insiemi restituisce un nuovo insieme composto dagli elementi
presenti nel primo insieme più gli elementi presenti nel secondo insieme
• Sintassi: set1 | set2
• In alternativa si può usare anche la seguente sintassi più mnemonica
• Sintassi: set1.union(set2)
• Per esempio la sequenza di istruzioni
frutta = {"mele", "pere", "banane", "susine"}
fruttasecca = {"arachidi","noci","nocciole"}
frutta.union(fruttasecca)
• Darà vita ad un nuovo insieme che comprende gli elementi di entrambi insiemi (dato che non ci
sono elementi uguali)
• Da notare che gli insiemi originali non vengono intaccati

Lorenzo Putzu Laboratorio D’Informatica 4


Sets: intersezione
• L’operazione di intersezione tra due insiemi restituisce un nuovo insieme composto dagli elementi
presenti in entrambi gli insiemi
• Sintassi: set1 & set2
• In alternativa si può usare anche la seguente sintassi più mnemonica
• Sintassi: set1.intersection(set2)
• Per esempio la sequenza di istruzioni
char = {"a", "p", "b", "s"}
char2 = {"a","n","b"}
char.intersection(char2)
• Darà vita ad un nuovo insieme che comprende gli elementi comuni ad entrambi gli insiemi
• Anche in questo casi gli insiemi originali non vengono intaccati

Lorenzo Putzu Laboratorio D’Informatica 5


Sets: differenza
• L’operazione di differenza tra due insiemi restituisce un nuovo insieme composto dagli elementi
presenti nel primo insieme ma che non sono presenti nel secondo insieme
• Sintassi: set1 - set2
• In alternativa si può usare anche la seguente sintassi più mnemonica
• Sintassi: set1.difference(set2)
• Per esempio la sequenza di istruzioni
char = {"a", "p", "b", "s"}
char2 = {"a","n","b"}
char.difference(char2)
• Darà vita ad un nuovo insieme che comprende gli elementi del primo insieme che non sono
comuni anche al secondo
• Anche in questo casi gli insiemi originali non vengono intaccati

Lorenzo Putzu Laboratorio D’Informatica 6


Sets:confronto
• Gli operatori == e != consentono di scrivere espressioni condizionali (il cui valore
sarà True o False) consistenti nel confronto tra due set.
• Sintassi:
• set1 == set2
• set1 != set2
• dove set1 e set2 indicano due insiemi, che sono considerati identici se
presentano gli stessi elementi

Lorenzo Putzu Laboratorio D’Informatica 7


Sets: in e not in
• Anche per gli insiemi si possono utilizzare le espressioni condizionali che hanno lo
scopo di verificare se un elemento sia presente o meno all’interno di un insieme
• Sintassi:
• espressione in set
• espressione not in set
• dove espressione indica una qualsiasi espressione Python e se il valore di
espressione è presente tra gli elementi di set l’operatore in produce il valore
True; in caso contrario produce False. Il comportamento dell’operatore not in è
quello opposto.

Lorenzo Putzu Laboratorio D’Informatica 8


Sets: issubset
• A volte però è necesario verificare che più di un elemento o espressione sia
presente o meno all’interno di un insieme, o anche verificare se un certo insieme
sia un sottinsieme di un altro insieme. Per questo scopo si usa il metodo issubset
con la seguente sintassi
• Sintassi:
• {espressione1,espressione2,...}.issubset(set)
• set1.issubset(set)
• se il valore di tutte le espressioni o se il set1 è un sottoinsieme di set il metodo
issubset produce il valore True; in caso contrario produce False.

Lorenzo Putzu Laboratorio D’Informatica 9


Sets: iterazioni
• Anche per gli insiemi è possibile utilizzare le funzioni iterative così come le abbiamo viste
per liste e diionari con la seguente sintassi
for v in s :
sequenza di istruzioni
• v deve essere il nome di una variabile che non sia già usata per memorizzare dati
all’interno dello stesso programma
• s deve essere un’espressione avente come valore un insieme
• sequenza di istruzioni è una sequenza di una o più istruzioni qualsiasi che di norma
eseguono un’operazione sulla variabile v
• Tuttavia, nella maggior parte dei casi le istruzioni iterative sono semplicemente usate
per scopi di stampa a video o su file, dato che anche in questo caso v contiene una copia
degli elementi di s . Ma soprattutto dato che la maggior parte delle operazioni sugli
insiemi possono essere fatte sull’insieme intero ma non su singoli elementi (non è
indicizzabile)

Lorenzo Putzu Laboratorio D’Informatica 10


Sets: funzioni predefinite
• Alcune metodi e funzioni predefinite di utilità generale sono le seguenti:
• len(set)
restituisce la lunghezza di un set
• set.add(elemento)
aggiunge elemento ad un set
• set.remove(elemento)
se elemento esiste lo rimuove dal set altrimenti da errore
• set.discard(elemento)
se elemento esiste lo rimuove dal set altrimenti il set rimane invariato
• set.clear()
rimuove ogni elemento dal set
Lorenzo Putzu Laboratorio D’Informatica 11
Esercizi
1. Definire una funzione che riceva come argomento una lista e
determini se in essa siano presenti valori duplicati (cioè valori che
occorrono più di una volta), restituendo True oppure False

2. Modificare la funzione dell’esercizio della lezione precedente


(Lez06_es03) in modo da evitare istruzioni iterative nidificate.

Lorenzo Putzu Laboratorio D’Informatica 12


Tuple
• Una tupla è un tipo di dato molto simile alle liste in quanto permette di
memorizzare una sequenza ordinata di valori che possono appartenente a tipi
qualsiasi, anche diversi tra loro.
• A differenza delle liste le tuple (come le stringhe) sono immutabili perciò i loro
valori non possono essere modificati.
• Una tupla si rappresenta nei programmi Python come una sequenza ordinata di
valori scritti tra parentesi tonde e separati da virgole
• Esempi
(-5.3, 6, True)
(2*10, False, 'ciao’)
()

Lorenzo Putzu Laboratorio D’Informatica 13


Tuple
• Anche le tuple possono essere create per conversione utilizzando la funzione
tuple a partire da un altro tipo di dato quindi ad esempio da una lista o da un
intervallo creato con la classe range.
• Esempi
tuple(range(10))
tuple([10, True, ‘ciao’])

• Come le stringhe e le liste è un tipo sequenza per cui si possono utizzare tutte le
operazioni che abbiamo visto in precedenza per questo tipo di dato.

Lorenzo Putzu Laboratorio D’Informatica 14


Tuple: indicizzazione
• L’operatore di indicizzazione consente di accedere a ogni singolo elemento di una
tupla, per mezzo dell’indice corrispondente secondo la Sintassi:
tupla[indice]

• Anche in questo caso è possibile utilizzare lo slicing per ottenere una porzione
della tupla

• Ovviamente trattandosi di un tipo di dato immutabile non è possibile assegnare


un nuovo valore al corrispondente indice o alla porzione selezionata della tupla.
• Questo non vale per gli elementi nidificati all’interno della tupla: perciò nel
caso una tupla contenga una lista gli elementi della lista potranno essere
modificati
Lorenzo Putzu Laboratorio D’Informatica 15
Tuple: concatenazione
• Questo operatore è analogo al corrispondente operatore del per stringhe e liste.
• Sintassi: tupla1 + tupla2
• La concatenazione produce una nuova tupla composta dagli elementi di tupla1 seguiti da quelli di
tupla2, disposti nellostesso ordine in cui si trovano nelle due tuple. Ovviamente le tuple originali
non vengono modificate.
• Ad esempio le seguenti istruzioni
tupla = (1,-5,4)
tupla + (1,2)
• Daranno vita ad una nuova tupla con i seguenti elementi (1, -5, 4, 1, 2)
• Inoltre è possibile creare una tupla che replicare gli elementi dela tupla originale con l’istruzione
tupla * 2

Lorenzo Putzu Laboratorio D’Informatica 16


Tuple: funzioni predefinite
• Alcune funzioni predefinite di utilità generale sono le seguenti:
• len(tupla)
restituisce la lunghezza della tupla
• tupla.count(espr)
restituisce il numero di volte in cui espr appare nella tupla
• tupla.index(espr)
restituisce la posizione in cui espr appare per la prima volta nella tupla

Lorenzo Putzu Laboratorio D’Informatica 17


Tuple: nidificate
• Anche le tuple come le liste possono contenere al loro interno delle altre tuple e in questo caso si
parla di tuple nidificate. Possono essere create semplicemente dichiarando una tupla all’interno
di un’altra tupla come già visto per le liste. Ad esempio con le istruzioni seguenti:
tupla = (5,10)
tupla1 = (1, True, (3, "ciao"))
tupla2 = (1, tupla)

• Vengono create due tuple (tupla1 e tupla2) che contengono una tupla nidificata. Un ulteriore
modo per creare delle tuple nidificate è quello che viene chiamato impacchettamento in tupla, ad
esempio con l’istruzione
tupla3 = tupla, 10
• creiamo una nuova tupla che contiene una tupla nidificata. La stessa operazione si può usare per
impacchettare dati semplici in una tupla
tupla4 = 10, True

Lorenzo Putzu Laboratorio D’Informatica 18


Sequenze spacchettamento
• Il procedimento inverso, chiamato spacchettamento di tupla si può utilizzare per
estrarre dalle tuple sdei singoli valori. Perciò se abbiamo una tupla che definisce
le coordinate di un punto possiamo estrarre i valori con una singola istruzione, ad
esempio
x, y = tupla

• In generale questo tipo di operazione si può eseguire su tutti i tipi sequenza e


prende il nome di spacchettamento di sequenza. L’unico vincolo è che la lista di
variabili a sinistra abbia un numero di elementi pari alla lunghezza della
sequenza.
• Si noti che l'assegnamento multiplo è in realtà solo una combinazione di
impacchettamento in tupla e spacchettamento di sequenza!

Lorenzo Putzu Laboratorio D’Informatica 19


Sequenze spacchettamento
• Grazie a questa procedura di impacchettamento e spacchettamento nel
linguaggio Python è possibile creare delle funzioni che restituiscono più valori in
modo molto semplice con la sintassi
• return(valore1, valore2,…)
• Ovviamente la chiamata di funzione dovrà prevedere la memorizzazione dei
valori restituiti in un numero uguale di variabili
• (var1, var2,…) = funzione(…)
• altrimenti se il numero di variabili è superiore verrà restituiro un errore, mentre
se in numero di variabili è inferiore l’operazione potrebbe andare in porto ma i
valori rimarranno impacchettati nelle tupla

Lorenzo Putzu Laboratorio D’Informatica 20


Funzioni di utilità generale
• La funzione type restituisce il tipo del dato che gli viene passato come argomento. Il suo utilizzo principale è
in fase di debugging ma anche per fare alcuni controlli, come ad esempio:
type(espressione) is list
type(espressione) is not tuple

• La funzione dir invece permette di visualizzare l’elenco degli attributi e dei metodi disponibili per un
determinato tipo di dato che gli viene passato come argomento, come ad esempio
dir([]) #restituisce l’elenco dei metodi e attributi di una lista
dir({}) #restituisce l’elenco dei metodi e attributi di un dizionario

• La funzione help fornisce delle informazioni più precise su uno specifico metodo come ad esempio
help([].insert)
help(().count)

Lorenzo Putzu Laboratorio D’Informatica 21


Esercizi
3. Definire una funzione che, data una lista 𝐿, restituisca due nuove liste:
• una ottenuta facendo "scorrere" di una posizione verso destra gli elementi di 𝐿 e spostando
l'ultimo elemento nella prima posizione. [3,-2,4,20] → [20,3,-2,4]
• l’altra ottenuta facendo "scorrere" di una posizione verso sinistra gli elementi di 𝐿 e
spostando il primo elemento nell’ultima posizione. [3,-2,4,20] → [-2,4,20,3]
4. Definire una funzione che, data una lista di dizionari come il seguente,
contenenti i dati sugli studenti che hanno sostenuto un certo esame:
{"matricola":"12345", "cognome":"Gui", "nome":"Ugo",
"voto":27}, restituisca il numero e la media aritmetica dei voti degli
studenti che hanno superato l'esame, e la posizione nella lista degli studenti
che hanno conseguito il voto 30 con lode (rappresentato dal valore 31).

Lorenzo Putzu Laboratorio D’Informatica 22


Esercizi Ripasso
5. Definire una funzione che riceva come argomento una stringa
contenente una frase (che si assume non contenere caratteri di
punteggiatura) e stampi nella shell tutte le parole presenti in essa in
ordine crescente della loro lunghezza
6. Scrivere una funzione che restituisca una lista contenente tutti i numeri
primi compresi tra 2 e un dato intero 𝑛 ricevuto come argomento,
usando il metodo detto crivello di Eratostene: partendo dalla sequenza di
tutti i valori tra 2 e 𝑛, si eliminano prima i multipli di 2, poi i multipli del
valore successivo (tra quelli rimanenti), e così via
7. Scrivere una funzione che riceva come argomento una lista di numeri e
restituisca il secondo valore maggiore presente in essa.
Esempi: [3, 6, 1, 5] → 5, [4, -2, 7, 5, 7, 1] → 7

Lorenzo Putzu Laboratorio D’Informatica 23


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 08
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Accesso ai file
• L’unico meccanismo di acquisizione dei dati d’ingresso (input) da parte di un
programma Python visto finora è basato sulla funzione input, che consente di
acquisire sequenze di caratteri scritte attraverso la tastiera (mentre il programma
è in esecuzione) nella finestra della shell.

• Similmente, per comunicare all’utente i risultati delle elaborazioni svolte da un


programma (output) si è usata la funzione print, che consente di stampare nella
finestra della shell il valore di qualsiasi espressione.

• Oltre a queste modalità di input/output ne esistono altre, per esempio l’uso di


interfacce grafiche e sistemi di puntamento (mouse, ecc.), e l’uso dei file della
memoria secondaria.

Lorenzo Putzu Laboratorio D’Informatica 2


Accesso ai file
• L’uso dei file della memoria secondaria è una modalità fondamentale sia per l’input (per acquisire
dati precedentemente memorizzati in un file, per esempio da un utente o da un altro
programma) che per l’output (per memorizzare in un file i risultati prodotti da un programma).

• Dal punto di vista di un programma Python un file consiste in una sequenza ordinata di valori. Più
precisamente, un file può essere:
• una sequenza di byte, che possono essere visti come numeri interi con valori nell’insieme {0,
1, . . . , 255}
• una sequenza di caratteri, che sono i classici file di testo che prenderemo in considerazione
in questo corso

Lorenzo Putzu Laboratorio D’Informatica 3


Accesso ai file
• Nel linguaggio Python l’accesso ai file è reso possibile attraverso diverse funzioni
di libreria, le quali consentono di eseguire su un file di testo due tipi di operazioni:
• Iettura: acquisizione dati dal file, sotto forma di una stringa
• scrittura: memorizzazione nel file sotto forma di una stringa
• Quindi per entrmabe la conoscenza delle funzioni per l’elaborazione di stringhe è
fondamentale e entrambe si compongono di tre fasi:
• apertura del file, per mezzo della funzione predefinita open
• esecuzione di una o più operazioni di lettura o scrittura
• chiusura del file, per mezzo della funzione predefinita close

Lorenzo Putzu Laboratorio D’Informatica 4


Accesso ai file
• La funzione open consente di indicare il nome del file al quale si vuole accedere e
la modalità di accesso desiderata (lettura o scrittura): tale operazione viene detta
“apertura” del file.

• Da un file aperto in modalità di lettura è possibile solo acquisire dati; su un file


aperto in modalità di scrittura è invece possibile solo scrivere dati. Il tentativo di
scrivere dati su un file aperto in modalità di lettura, o di acquisire dati da un file
aperto in modalità di scrittura, produce un errore.

• La funzione close “chiude” il file, cioè impedisce di eseguire ulteriori operazioni di


lettura o scrittura su di esso (fino a che non venga eventualmente riaperto con
un’altra chiamata di open).

Lorenzo Putzu Laboratorio D’Informatica 5


Accesso ai file: apertura
• La funzione open restituisce un valore di un tipo predefinito contenente alcune
informazioni sul file. Tali informazioni dovranno essere usate in ogni successiva
operazione sullo stesso file, inclusa la chiusura, perciò è fondamentale assegnarle
ad una variabile. La sintassi è la seguente:
• Sintassi:
variabile = open (nome-file, modalità)
• variabile: il nome della variabile che verrà associata al file
• nome-file: una stringa contenente il nome del file
• modalità: una stringa che indica la modalità di apertura (lettura o scrittura)

Lorenzo Putzu Laboratorio D’Informatica 6


Accesso ai file: apertura
• Il nome del file che si desidera aprire deve essere passato come argomento della
funzione open sotto forma di stringa e può essere:
• assoluto, cioè preceduto dalla sequenza (detta anche pathname) dei nomi
delle directory che lo contengono a partire dalla directory radice del file
system, scritta secondo la sintassi prevista dal sistema operativo del proprio
calcolatore
• relativo, cioè composto dal solo nome del file: questo è possibile solo se la
funzione open è chiamata da un programma o da una funzione che si trovi
nella stessa directory che contiene il file da aprire

Lorenzo Putzu Laboratorio D’Informatica 7


Accesso ai file: apertura
• Per esempio, nel caso di un file di nome dati.txt che si trovi nella directory
C:\Users\Lorenzo\ di un sistema operativo Windows:
• il nome assoluto è C:\Users\Lorenzo\dati.txt
• il nome relativo è dati.txt

• Se un file con lo stesso nome (dati.txt) è memorizzato nella directory


/Users/Lorenzo/ di un sistema operativo Linux oppure Mac OS:
• il nome assoluto è /Users/Lorenzo/dati.txt
• il nome relativo è ancora dati.txt

Lorenzo Putzu Laboratorio D’Informatica 8


Accesso ai file: apertura
• Per i sistemi operativi Windows, nella stringa contenente il nome assoluto di un file il linguaggio
Python consente di usare come separatore il carattere / (separatore nei sistemi Unix like) invece
del carattere \ (separatore nei sistemi Windows).

• Questo consente di evitare ambiguità nel caso di nomi di file o directory che iniziano con il
carattere n, dato che nella stringa corrispondente comparirebbe la sequenza "\n" che Python
interpreta come newline, altrimenti si dovrebbe scrivere come nome del file assoluto:
"C:\\Users\\Lorenzo\\dati.txt“

• In alternativa (solo nel caso di funzioni non da Shell) si può usare il nome del file relativo, che nel
caso in cui la funzione che lo richiama sia scritta in un file memorizzato nella stessa directory
nella quale si trova il file da aprire, sarà
"dati.txt“

Lorenzo Putzu Laboratorio D’Informatica 9


Accesso ai file: apertura
• È possibile aprire in modalità di lettura solo un file esistente. Se il file non esiste si
otterrà un errore.

• La modalità di scrittura consente invece anche la creazione di un nuovo file. Più


precisamente, attraverso la modalità di scrittura è possibile:
• creare un nuovo file
• aggiungere dati al termine di un file già esistente
• sovrascrivere (cancellare e sostituire) il contenuto di un file già esistente

Lorenzo Putzu Laboratorio D’Informatica 10


Accesso ai file: apertura
• Nella chiamata di open la modalità di accesso è indicata (come secondo
argomento) da una stringa composta da un singolo carattere:
• "r" (read): lettura (se il file non esiste si ottiene un errore)
• "w" (write): (sovra)scrittura se il file non esiste viene creato ma se il file esiste
viene sovrascritto, cancellando i dati che contiene
• "a" (append): scrittura (aggiunta) anche in questo caso se il file non esiste
viene creato mentre se il file esiste i nuovi dati saranno aggiunti dopo quelli
già presenti

Lorenzo Putzu Laboratorio D’Informatica 11


Accesso ai file: apertura
• Consideriamo ancora il file dati.txt presente nella directory C:\Users\Lorenzo\. Per aprire tale file in modalità
di lettura, memorizzando il valore restituito da open in una variabile di nome f, si dovrà scrivere l’istruzione:
f = open("C:/Users/Lorenzo/dati.txt", "r")
• oppure se la chiamata di open non è scritta nella shell, e il programma che la contiene si trovi nella stessa
directory del file.
f = open("dati.txt", "r")
• Consideriamo ancora la directory C:\Users\Lorenzo\. Per creare un nuovo file di nome dati2.txt al suo
interno e associarlo a una variabile di nome nf si potrà usare una qualunque delle due modalità di scrittura:
nf = open("C:/Users/Lorenzo/dati2.txt", "w") oppure
nf = open("C:/Users/Lorenzo/dati2.txt", "a")
• Anche in questo caso è possibile usare il nome relativo del file (sempre sotto le stesse ipotesi):
nf = open("dati2.txt", "w") oppure
nf = open("dati2.txt", "a")

Lorenzo Putzu Laboratorio D’Informatica 12


Accesso ai file: apertura
• Se invece si volesse aprire in scrittura il file già esistente dati.txt nella directory C:\Users\Lorenzo\
cancellando automaticamente gli eventuali dati in esso presenti, si dovrà usare la modalità "w"
fw = open("C:/Users/Lorenzo/dati.txt", "w")
• Se invece si volesse aprire in scrittura un file già esistente per aggiungere dati dopo quelli eventualmente già
presenti (senza cancellare questi ultimi) si dovrà usare la modalità "a".
fw = open("C:/Users/Lorenzo/dati.txt", "a")
• Anche in questo caso è possibile usare il nome relativo del file, nelle condizioni indicate in precedenza.

Lorenzo Putzu Laboratorio D’Informatica 13


Accesso ai file: chiusura
• Quando le operazioni di lettura o scrittura su un file sono terminate, il file deve essere chiuso
attraverso la funzione predefinita close. Questo impedirà l’esecuzione di ulteriori operazioni su
tale file, fino a che esso non venga eventualmente riaperto.
• Sintassi:
variabile.close()
• dove variabile deve essere la variabile usata nell’apertura dello stesso file attraverso la funzione
open

• Perciò assumendo che un file di nome dati.txt sia stato aperto in lettura con l’istruzione
f = open("dati.txt", "r")
• esso dovrà essere chiuso con la chiamata:
f.close()

Lorenzo Putzu Laboratorio D’Informatica 14


Accesso ai file
• Se lo si desidera è anche possibile aprire più file contemporaneamente. A questo scopo nel
momento dell’apertura è necessario associare ogni file a una diversa variabile.
• Per esempio, se si volesse aprire in lettura un file esistente di nome dati.txt, e creare un nuovo file
di nome risultati.txt da aprire in scrittura, associandoli rispettivamente alle variabili f_dati e
f_risultati, le operazioni di apertura e chiusura sarebbero le seguenti:
f_dati = open("dati.txt", "r")
f_risultati = open("risultati.txt", "w")
...
f_dati.close()
f_risultati.close()

Lorenzo Putzu Laboratorio D’Informatica 15


Accesso ai file: scrittura
• In un file di testo che sia stato aperto in scrittura (in modalità "w" oppure "a") è
possibile scrivere dati sotto forma di stringhe attraverso la funzione predefinita
write.
• Sintassi:
variabile.write(stringa)
• variabile è la variabile associata al file
• stringa è una stringa contenente la sequenza di caratteri da scrivere nel file

• Mentre un file è aperto in scrittura la funzione write può essere chiamata più
volte per scrivere nel file diverse sequenze di caratteri. Qualsiasi chiamata di
write scrive la corrispondente sequenza di caratteri al termine del file, cioè dopo
gli eventuali caratteri già presenti al suo interno.

Lorenzo Putzu Laboratorio D’Informatica 16


Accesso ai file: scrittura
• L’esecuzione di un programma contenente la seguente sequenza di istruzioni:
f = open("testo.txt", "w")
f.write("Prima riga.\nSeconda riga.")
f.close()
• crea un file di nome testo.txt nella stessa directory del programma (se il file esiste
ne cancella il contenuto) e scrive al suo interno la stringa indicata.
• Aprendo successivamente il file con un qualsiasi editor di testi si osserverà il
seguente contenuto:
Prima Riga
Seconda Riga

Lorenzo Putzu Laboratorio D’Informatica 17


Accesso ai file: aggiunta
• Se successivamente si riapre il file in scrittura in modalità "a" sarà possibile aggiungere del testo
al termine dello stesso file, senza cancellare il testo esistente.
• Per esempio, dopo l’esecuzione del seguente programma, anch’esso memorizzato nella stessa
directory del file testo.txt:
f = open("testo.txt", "a")
f.write("\nTerza riga.")
f.close()
• il contenuto del file sarà il seguente:
Prima Riga
Seconda Riga
Terza Riga

Lorenzo Putzu Laboratorio D’Informatica 18


Accesso ai file
• Se successivamente si riaprisse il file in scrittura in modalità "w" il suo contenuto verrebbe
cancellato.
• Per esempio, si memorizzi ancora nella stessa directory il seguente programma, e lo si esegua:
f = open("testo.txt", "w")
f.write("Nuova riga.")
f.close()
• Il contenuto del file sarà ora il seguente:
Nuova Riga

Lorenzo Putzu Laboratorio D’Informatica 19


Accesso ai file: lettura
• Le operazioni di lettura da un file possono essere eseguite attraverso tre diverse
funzioni predefinite:
• read
• readline
• readlines
• Tutte e tre le funzioni restituiscono una parte del contenuto del file, o l’intero
contenuto, sotto forma di una stringa oppure di una lista di stringhe.
• Il valore restituito da tali funzioni deve di norma essere memorizzato in una
variabile per poter essere successivamente elaborato.

Lorenzo Putzu Laboratorio D’Informatica 20


Accesso ai file: lettura
• La funzione read acquisisce l’intero contenuto di un file, che viene restituito sotto
forma di una stringa. Le eventuali interruzioni di riga presenti nel file vengono
codificate con il carattere newline "\n".
• La sintassi della chiamata di questa funzione (così come quella di readline e
readlines) è analoga a quella della funzione close:
variabile.read()
• dove variabile è la variabile associata al file.
• Come si è detto in precedenza, di norma la stringa restituita da read deve essere
memorizzata in una variabile per poter essere successivamente elaborata.

Lorenzo Putzu Laboratorio D’Informatica 21


Accesso ai file: lettura
• Si consideri un file di nome testo.txt scritto manulamente con un editor di testo classico e
contenente le seguenti righe di testo:
Prima riga.
Seconda riga.
Terza riga.
• Si memorizzi ora il seguente programma nella stessa directory di tale file, e lo si esegua:
f = open("testo.txt", "r")
s = f.read()
f.close()
• Il risultato sarà la memorizzazione della seguente stringa nella variabile s, come si potrà osservare
valutando l’espressione s nella shell:
"Prima riga.\nSeconda riga.\nTerza riga."
• Si noti la codifica delle interruzioni di riga con il carattere newline.
Lorenzo Putzu Laboratorio D’Informatica 22
Accesso ai file: lettura
• La prima chiamata di read dopo l’apertura (in modalità di lettura) di un file ne acquisisce
sempre l’intero contenuto. Questo significa che dopo aver chiuso e riaperto (in lettura)
uno stesso file sarà possibile riacquisirne il contenuto con una chiamata di read.
• Se invece si eseguono due o più chiamate di read mentre un file è aperto (senza
chiuderlo e riaprirlo prima di ognuna di tali chiamate), ogni chiamata successiva alla
prima restituirà una stringa vuota, poiché l’intero contenuto del file è già stato acquisito.
• Modificando quindi il programma precedente ed eseguendolo nuovamente:
f = open("testo.txt", "r")
s = f.read()
s2 = f.read()
f.close()
• La variabile s2 conterrà una stringa vuota

Lorenzo Putzu Laboratorio D’Informatica 23


Accesso ai file: lettura
• La funzione readline acquisisce una singola riga di un file, restituendola sotto
forma di una stringa.
• Per “riga” di un file s’intende una sequenza di caratteri fino alla prima
interruzione di riga, oppure, se il file non contiene interruzioni di riga, l’intera
sequenza di caratteri contenuta in esso.
• Nel primo caso anche l’interruzione di riga, codificata con il carattere newline,
farà parte della stringa restituita da readline.
• La sintassi è la seguente:
variabile.readline()
• dove variabile indica come al solito la variabile associata al file.

Lorenzo Putzu Laboratorio D’Informatica 24


Accesso ai file: lettura
• La prima chiamata di readline dopo l’apertura (in lettura) di un file acquisisce sempre la prima riga ed ogni
eventuale altra chiamata di readline (prima che il file venga chiuso) acquisisce la riga successiva a quella
acquisita dalla chiamata precedente.
• Se tutte le righe di un file sono state acquisite da una sequenza di chiamate di readline, ogni chiamata
successiva restituirà una stringa vuota.
• Considerando sempre il file testo.txt degli esempi precedenti e si esegua il seguente programma dopo
averlo memorizzato nella stessa directory di tale file:
f = open("testo.txt", "r")
a = f.readline()
b = f.readline()
c = f.readline()
d = f.readline()
f.close()
• Le variabili corrispondenti ad a, b, c e d conterranno rispettivamente le tre righe del file e una stringa vuota:

Lorenzo Putzu Laboratorio D’Informatica 25


Accesso ai file: lettura
• La funzione readline è utile quando si desidera acquisire ed elaborare una singola riga alla volta di
un dato file.
• Questo si può ottenere attraverso una sequenza di chiamate di readline all’interno di
un’istruzione iterativa, che dovrà terminare non appena readline restituirà una stringa vuota (che
indica che l’intero contenuto del file è già stato acquisito) come nel programma seguente
f = open("testo.txt", "r")
print("Il file contiene le seguenti righe:")
riga = f.readline()
while riga != "" :
print(riga)
riga = f.readline()
f.close()

Lorenzo Putzu Laboratorio D’Informatica 26


Accesso ai file: lettura
• Questo programma funziona anche su file che presentano righe “vuote” seguite da altre righe,
infatti le prime righe “vuote” contengono in realtà un’interruzione di riga, cioè il carattere
newline, e quindi non sono realmente vuote.
• Per questo motivo l’iterazione del programma precedente termina non quando s’incontra la
prima di tali righe, ma quando si è raggiunta l’effettiva fine del file.
• E’ anche possibile chiamare la funzione read dopo una o più chiamate di readline, ma in questo
caso read acquisirà il contenuto del file a partire dalla riga successiva all’ultima acquisita da
readline, e fino al termine del file.
• In generale per ogni operazione di lettura valgono le seguenti regole:
• l’acquisizione inizia dal punto in cui si era conclusa la precedente operazione di lettura
• se l’intero contenuto del file è già stato acquisito dalle operazioni precedenti, viene restituita
una stringa vuota

Lorenzo Putzu Laboratorio D’Informatica 27


Accesso ai file: lettura
• La funzione readlines acquisisce l’intera sequenza di caratteri contenuta in un file,
e la restituisce sotto forma una lista di stringhe, ciascuna delle quali contiene una
riga del file (incluso il carattere newline).
• La sintassi è la seguente:
variabile.readlines()
• dove variabile è ovviamente la variabile associata al file.
• Anche la funzione readlines è utile quando si desidera elaborare separatamente
ogni riga di un dato file, ma a differenza di readline consente l’acquisizione
dell’intero file con una sola chiamata.

Lorenzo Putzu Laboratorio D’Informatica 28


Accesso ai file: lettura
• Considerando ancora il file testo.txt e il seguente programma
f = open("testo.txt", "r")
righe = f.readlines()
f.close()
• Dopo l’esecuzione la variabile righe conterrà la lista:
["Prima riga.\n", "Seconda riga.\n", "Terza riga."]

• Per poter eleborare ogni singola riga sarà quindi necessario un’istruzione iterativa
in modo simile a quanto visto per l’elaborazione delle liste

Lorenzo Putzu Laboratorio D’Informatica 29


Accesso ai file: lettura
• Il comportamento della funzione readlines e’ simile a quello di read:
• la prima chiamata di readlines dopo l’apertura (in modalità di lettura) di un
file ne acquisisce sempre l’intero contenuto
• se si eseguono due o più chiamate di readlines mentre un file è aperto (senza
chiuderlo e riaprirlo prima di ognuna di tali chiamate), ogni chiamata
successiva alla prima restituirà una lista vuota, poiché l’intero contenuto del
file è già stato acquisito

Lorenzo Putzu Laboratorio D’Informatica 30


Accesso ai file: lettura
• Le tre funzioni viste finora sono equivalenti dal punto di vista dell’acquisizione di
dati da un file di testo. In altre parole, qualsiasi operazione di lettura si possa
svolgere con una di esse si potrà svolgere anche con le altre due.
• Tuttavia una data operazione potrebbe richiedere programmi di diversa
complessità a seconda della funzione che si intende usare. È quindi importante
individuare la funzione più appropriata da usare in un dato contesto.
• Per esempio, se s’intende elaborare separatamente ciascuna riga di un file è
consigliabile usare readline o readlines, dato che entrambe suddividono
automaticamente le righe del file; usando read sarà invece il programmatore a
dover scrivere ulteriori istruzioni per individuare il termine di ciascuna riga, in
corrispondenza dei caratteri newline.

Lorenzo Putzu Laboratorio D’Informatica 31


Esercizi
1. Scrivere un programma che utilizzi la funzione già scritta nel esercizio
Lez06_es05, che riceva una lista di dizionari contenenti ciascuno nome,
cognome ed età di una persona
• definire una funzione che scriva tali dati in un nuovo file di nome
dati_anagrafici.txt (una riga per persona). Per esempio, i dati del
dizionario:
{"nome":"Ugo", "cognome":"Gui", "eta'":25}
dovranno corrispondere alla riga:
Ugo Gui 25
• definire una funzione senza argomenti che acquisisca i dati dal file e li
memorizzi nella lista di dizionari e restituisca tale lista

Lorenzo Putzu Laboratorio D’Informatica 32


Esercizi di riepilogo: campionato di basket
2. Un file di testo di nome partite.txt contiene i risultati di tutte le
partite giocate nel corso di un campionato di pallacanestro. Ogni riga
corrisponde a una partita, per esempio:
Milano Venezia 80 75
Trento Sassari 82 95
• scrivere una funzione senza argomenti che restituisca un dizionario contenente la
classifica del campionato (2 punti per una vittoria, 0 per una sconfitta), e avente per
chiavi i nomi delle squadre; per esempio:
{"Milano":20, "Trento":24, ...}
• Scrivere una funzione che, dato un dizionario come quello precedente, stampi sulla
shell la classifica in ordine decrescente di punteggio; esempio:
Trento 24
Milano 20
...

Lorenzo Putzu Laboratorio D’Informatica 33


Esercizi di riepilogo: campionato di basket
Suggerimento:
• memorizzazione della classifica in un dizionario:
• acquisire il contenuto del file con readlines
• scandire le partite (le righe del file) e costruire un dizionario avente per chiavi i nomi
delle squadre e zero (punti) come valore associato a ciascuna chiave;
esempio:{"Milano":0, "Trento":0, ...}
• scandire una seconda volta le partite e aggiungere nel dizionario due punti alla
squadra vincente di ogni partita
• stampa della classifica:
• costruire due liste contenenti una le chiavi (nomi delle squade), l'altra i valori (i punti
delle stesse squadre) del dizionario, usando le funzioni (metodi) keys e values,
che restituiscono chiavi e valori di un dizionario nello stesso ordine
• ordinare le due liste, per esempio con l'algoritmo di ordinamento per selezione

Lorenzo Putzu Laboratorio D’Informatica 34


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 09
Il linguaggio Python

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Struttura dei programmi: update
• Abbiamo già visto in precedenza i vantaggi della programmazione
modulare, che, in particolare al crescere della complessità dei programmi
da sviluppare, rende più semplici le operazioni di modifica e di testing del
codice prodotto.

• La programmazione ad oggetti rappresenta un ulteriore sviluppo rispetto


alla programmazione modulare. Il programma può essere visto come un
insieme di oggetti che interagiscono tra loro.

• In questo tipo di programmazione si fa uso di un nuovo tipo di dato, la


classe, che serve appunto a modellare un insieme di oggetti

Lorenzo Putzu Laboratorio D’Informatica 2


Struttura dei programmi: update
• Una classe è uno strumento che ci permette di raggruppare variabili e
funzioni nei nostri programmi in maniera logica e riutilizzabile il che ci
consente di gestire progetti anche di grosse dimensioni in maniera molto
semplice.

• Python è un linguaggio multi-paradigma, che supporta sia la


programmazione procedurale (che è quella che abbiamo visto finora e che
fa uso delle funzioni) sia la programmazione ad oggetti.

• Mentre nella programmazione procedurale le funzioni (o procedure) sono


l’elemento organizzativo principale, nella programmazione ad oggetti
l’elemento organizzativo principale sono gli oggetti.

Lorenzo Putzu Laboratorio D’Informatica 3


Struttura dei programmi: update
• Nella programmazione procedurale, i dati e le funzioni
sono separate, e questo può creare una serie di
problemi, tra cui:
• è necessario gestire dati e funzioni separatamente;
• è necessario importare le funzioni che vogliamo usare;
• è necessario passare i dati alle funzioni;
• è necessario verificare che i dati e le funzioni siano
compatibili;
• è più difficile estendere e modificare le funzionalità;
• il codice è più difficile da mantenere;
• è più facile introdurre bug.
Lorenzo Putzu Laboratorio D’Informatica 4
Struttura dei programmi: update
• Nella programmazione ad oggetti, gli oggetti svolgono la
funzione di racchiudere in un’unica unità organizzativa
sia i dati che e funzioni. Questo ha diversi vantaggi:
• dati e funzioni sono raggruppati;
• è facile sapere quali operazioni possono essere eseguite sui
dati;
• non è necessario importare funzioni per eseguire queste
operazioni;
• non è necessario passare i dati alle funzioni;
• le funzioni sono compatibili con i dati;
• è più facile estendere e modificare le funzionalità;
• il codice è più semplice da mantenere;
• è più difficile introdurre bug.
Lorenzo Putzu Laboratorio D’Informatica 5
Classi e oggetti
• Le classi quindi permettono di modellare la realtà in maniera efficiente e
riutilizzabile, infatti possiamo definire le proprietà di ciascuno oggetto in
un modello generico, chiamato classe e da qui far derivare ciascun singolo
individuo assegnandogli i suoi attributi personali.
• Ciascun oggetto creato a partire da questo modello generico viene
chiamato Istanza.

• Esempio la fabbrica di biscotti:


• lo stampo per i biscotti è il modello
• ogni biscotto è un’istanza di quel modello
• Però per avere un’idea più precisa sulle potenzialità di una classe bisogna
immaginare uno stampo che può dar vita a biscotti con caratteristiche differenti,
assegnando differenti valori delle sue variabili di istanza o attributi.

Lorenzo Putzu Laboratorio D’Informatica 6


Classi e oggetti:esempio

Lorenzo Putzu Laboratorio D’Informatica 7


Classi e oggetti
Le classi quindi sono usate per definire le caratteristiche di un oggetto, i
suoi attributi e i suoi metodi ma non si riferiscono a nessun oggetto
specifico, in quanto rappresentano un modello che può essere usato
per creare istanze.

Le istanze sono oggetti creati a partire da una classe. Quindi un’istanza


di una classe si riferisce a uno specifico oggetto. Una classe può essere
usata per creare diverse istanze dello stesso tipo ma con attributi
diversi.

Lorenzo Putzu Laboratorio D’Informatica 8


Definizione di classe
• Le classi introducono un pò di nuova sintassi e alcuni nuovi costrutti. La
definizione di una nuova classe viene effettuata tramite la keyword class con la
seguente sintassi
class nome_classe :
sequenza di istruzioni
dove nome_classe indica il nome che vogliamo dare alla classe
• La sintassi è molto simile a quella usata per la definizione di funzioni manca
solamente la lista di argomenti in input. Mentre la sequenza di istruzioni può
includere:
• la definizione di nuovi metodi
• la definizione di un metodo speciale chiamato _init_
• la definizione di variabili di istanza
• la definizione di variabili di classe

Lorenzo Putzu Laboratorio D’Informatica 9


Instanziare una classe
• Una volta che abbiamo definito in maniera opportuna una nuova classe possiamo
creare degli oggetti e quindi instanziare la classe con la seguente sintassi:
• Sintassi
nome_instanza = nome_classe(valore1, ...)

• dove nome_instanza indica il nome che vogliamo dare all’oggetto che stiamo
creando e invece nome_classe fa riferimento al nome che era stato assegnato
alla classe in precedenza
• valore1 invece indica un possibile argomento di input che verrà gestito
all’interno della classe
• Il numero di argomenti di input dipende dalla definizione della classe è può anche
essere vuoto

Lorenzo Putzu Laboratorio D’Informatica 10


I metodi
• I metodi descrivono il comportamente dell’oggetto, sono simili alle funzioni
ma sono specifici per ogni classe
class nome_classe :
...
def nome_metodo(self):
...
• Come si può notare:
• la loro definizione si trova indentata all’interno della classe
• la sintassi usata per definire i metodi è uguale a quella usata per definire le funzioni
• devono includere un parametro aggiuntivo che per convezione è chiamato self

Lorenzo Putzu Laboratorio D’Informatica 11


I metodi
• self è un argomento che si riferisce all’istanza, e anche se i metodi devono
dichiararlo esplicitamente, non è necessario passarlo esplicitamente, infatti
immaginando di aver instanziato la classe precedente con
nome_instanza = nome_classe(...)
• possiamo invocare il metodo semplicemente come
nome_instanza.nome_metodo(...)
• Python in realtà risale in automatico alla classe di appartenenza di nome_instanza
ed esegue
nome_classe.nome_metodo(nome_instanza,...)
• Per questo motivo ogni metodo definito nella classe deve presentare come primo
argomento self

Lorenzo Putzu Laboratorio D’Informatica 12


I metodi
• Le classi supportano anche diversi metodi “speciali” che sono identificati dalla presenza di due
underscore prima e dopo il nome. Questi metodi non vengono chiamati direttamente con
nome_instanza.__nome_metodo__, ma vengono in genere chiamati automaticamente in situazioni
particolari
• Uno di questi metodi speciali è il costruttore definito come __init__ chiamato automaticamente ogni
volta che un’istanza viene creata:
class nome_classe :
def __init__(self,...):
...
• Gli argomenti passati durante la creazione dell’istanza vengono ricevuti da __init__. Questo ci
permette di creare automaticamente istanze diverse in base agli argomenti passati in quanto in genere
vengono utilizzati per definire quelli che sono gli attributo o variabili di un’istanza

Lorenzo Putzu Laboratorio D’Informatica 13


Attributi
• Gli attributi di istanza sono i più comuni e si dichiarano all’interno di un metodo
(in particolare l’init)
• Gli attributi di classe invece sono meno comuni in quanto sono legati alla classe, e
perciò ogni instanza di tale classe avrà in comune tali attributi
class nome_classe :
self.attributo = espressione
def __init__(self,valore,...):
self.attributo = valore
...
...

Lorenzo Putzu Laboratorio D’Informatica 14


Esempio
• Definiamo una classe che rappresenta un rettangolo generico
class Rettangolo:
def __init__(self, base, altezza):
self.base = base
self.altezza = altezza

def calcola_area (self):


return self.base * self.altezza

def calcola_perimetro (self):


return (self.base + self.altezza)*2

• Possiamo creare un’instanza della classe Rettangolo con l’istruzione


rettangolo1 = Rettangolo(10,20)

Lorenzo Putzu Laboratorio D’Informatica 15


Esempio
• Una volta create l’instanza possiamo accedere a tutti i suoi attribute
d’istanza che sono base e altezza
rettangolo1.base
rettangolo1.altezza

• E possiamo richiamarne i metodi calcola_area e calcola_perimetro


rettangolo1.calcola_area()
rettangolo1.calcola_perimetro()

• Da notare che, a differenza di una funzione generica, non dobbiamo


passare nessun parametro ai metodi, che invece utilizzando gli attributi
dell’istanza

Lorenzo Putzu Laboratorio D’Informatica 16


Caratteristiche degli oggetti
• Le istanze sono mutabili perciò possiamo modificarne lo stato agendo direttamente su uno dei
suoi attribute e assegnandogli un nuovo valore, come ad esempio
rettangolo1.base = 30

• Possiamo passare un'istanza come parametro ad una funzione nel solito modo. Ad esempio per
una stampa dei suoi attributi
def StampaRettangolo(rettangolo):
print(‘base’, rettangolo.base)
print(‘altezza’,rettangolo.altezza)

• Allo stesso tempo possiamo anche restituire un’istanza come valore di ritorno di una funzione, ad
esempio
def RaddoppiaRettangolo(rettangolo):
rettangolo.base *= 2
rettangolo.altezza *= 2
return rettangolo

Lorenzo Putzu Laboratorio D’Informatica 17


Uguaglianza tra istanze
• Anche se due istanze hanno gli stessi attributi, nel nostro esempio hanno la stessa
base e altezza, non è detto che siano uguali.
• Se assegniamo ad una variabile il rettangolo che avevamo creato in precedenza
allora si tratterà di un alias dello stesso oggetto perciò l’uguaglianza sarà
verificata.
• Altrimenti dati due rettangoli, anche se hanno le stesse coordinate non fanno
riferimento allo stesso oggetto ma a due oggetti diversi. Per verificare che due
oggetti abbiamo lo stesso contenuto è necessario fare un confronto tra il loro
attributi

def ConfrontaRettangoli(ret1, ret2):


return (ret1.base==ret2.base) and (ret1.altezza==ret2.altezza)

Lorenzo Putzu Laboratorio D’Informatica 18


Esercizi
1. Definire una classe di nome Persona le cui istanze contengano il nome, il cognome e
la data di nascita (giorno, mese e anno, rappresentati come numeri interi) di una
persona. Tali valori devono essere specificati come argomenti del costruttore della
classe (ovvero del metodo __init__). Definire inoltre i metodi per accedere a tali
valori; la data di nascita dovrà essere restituita dal metodo corrispondente sotto forma
di stringa, nel formato gg/mm/aaaa
2. Definire una classe di nome Conto_Corrente per memorizzare informazioni sui
conti correnti di una certa banca. Ogni istanza deve contenere il codice IBAN di un
conto (27 caratteri alfanumerici), il nome, il cognome e il codice fiscale del titolare, il
saldo e lo scoperto (il massimo saldo passivo ammesso). Tutti questi valori dovranno
essere specificati come argomenti del costruttore della classe; i valori di default
(predefiniti) di saldo e scoperto devono essere entrambi zero. Definire inoltre i metodi
per accedere a ciascuno di tali valori, per assegnare un nuovo scoperto, per modificare
il saldo dopo un versamento, e per modificarlo dopo un prelievo; quest'ultimo metodo
dovrà consentire solo prelievi che non portino il saldo oltre lo scoperto, e dovrà
restituire il valore dell'importo prelevato, se consentito, oppure 0

Lorenzo Putzu Laboratorio D’Informatica 19


Esercizi
3. Definire una classe di nome Studente le cui istanze contengano il nome, il
cognome, il codice fiscale, il numero di matricola (cinque cifre) e la data
d'immatricolazione (sotto forma di dizionario con chiavi 'g', 'm' e 'a') di un
certo studente a un certo corso di studio universitario, e tutti gli esami da lui
superati (codice dell'insegnamento – cinque cifre –, data dell'esame – una
stringa nel formato gg/mm/aaaa – e voto – un intero tra 18 e 30, oppure 31
per codificare ``30 con lode''). Tutti questi valori, eccetto le informazioni sugli
esami, dovranno essere specificati come argomenti del costruttore della classe.
Le informazioni sugli esami dovranno essere memorizzate come una lista di
dizionari (un dizionario per esame), il cui valore iniziale dovrà essere una lista
vuota. Definire i metodi per accedere alle informazioni su ciascuno studente:
nome, cognome, codice fiscale, numero di matricola, data d'immatricolazione
(da restituire sotto forma di stringa nel formato gg/mm/aaaa) ed elenco degli
esami (che dovrà essere stampato sullo schermo); definire inoltre un metodo
per registrare un nuovo esame, avente per argomenti il codice, la data (una
stringa, si veda sopra) e il voto (con la stessa codifica numerica indicata sopra)

Lorenzo Putzu Laboratorio D’Informatica 20


Esercizi
4. Definire una classe per rappresentare un mazzo di 52 carte da gioco, composte
dai quattro semi Cuori, Quadri, Fiori, Picche, e dai valori 2, 3, ..., 10, J, Q, K, A.
Ogni carta dovrà essere rappresentata da un dizionario con due chiavi (seme e
valore, i cui valori dovranno essere stringhe), e il mazzo dovrà essere
rappresentato come una lista di dizionari. Il mazzo iniziale dovrà contenere le
52 carte ordinate per seme (C, Q, F, P) e, all'interno di ciascun seme, per valori
crescenti (2, ..., A). Definire quindi i metodi che eseguano le seguenti
operazioni:
• stampare le carte del mazzo nel formato (seme,valore), (seme,valore), ...
• mescolare il mazzo (cioè disporre le carte in un ordine casuale)
• "tagliare" ("alzare") il mazzo rispetto alla posizione centrale
• estrarre e restituire (sotto forma di dizionario) la prima carta (rimuovendola dal mazzo)
• estrarre e restituire (sotto forma di dizionario) una carta qualsiasi (rimuovendola dal mazzo)

Suggerimento: usare le funzioni della libreria random (shuffle, randint, ...)

Lorenzo Putzu Laboratorio D’Informatica 21


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 10
Basi Di Dati

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Argomenti
● Progettazione concettuale
– il modello Entità-Relazione

– definizione dello schema Entità-Relazione


● Progettazione logica
– il modello logico relazionale

– definizione dello schema logico relazionale

● Il linguaggio SQL
– creazione dello schema di una base di dati

– definizione di interrogazioni su una base di dati

2
Sistemi informativi e basi di dati
● Sistemi informativi
– dati (testuali/numerici), strumenti di archiviazione e gestione,
utenti, procedure di accesso, ...
– esempi: università, aziende, enti pubblici,
sistemi informativi geografici (GIS)
● Basi di dati (BD)
– strumenti informatici per la gestione di sistemi informativi

Lorenzo Putzu Laboratorio D’Informatica 3


Basi di dati
• Una Base di Dati (Database) è un insieme organizzato di dati.

• Una base di dati è un insieme di dati che può essere gestito da un sistema DBMS
(Data Base Management System).

• Un DBMS è un sistema software composto da sequenze di dati interconnessi tra


di loro, e da programmi applicativi che consentono di effettuare su tali dati
operazioni di:
• accesso
• modifica
• interrogazione (query di ricerca).

Lorenzo Putzu Laboratorio D’Informatica 4


Basi di dati
• Problemi principali:
– quantità dei dati (risorse hardware, efficienza, ...)
– molti utenti di diverse tipologie
– procedure di accesso complesse
– requisiti critici: accesso in tempo reale, accesso concorrente,
ecc.
– sicurezza dei dati (limitazioni all'accesso)
– ridondanza
– ripristino da crash e guasti

Lorenzo Putzu Laboratorio D’Informatica 5


Basi di dati
• Ogni SI (Sistema Informativo) è suddiviso generalmente in settori o sotto-sistemi, ognuno dei quali
svolge varie funzionalità ed esegue vari processi su una base di dati spesso condivisa.
• Possono essere molteplici le applicazioni che utilizzano gli stessi dati o stesse porzioni della base di dati
condivisa dal SI.

• Se la base di dati non è ben progettata, possono verificarsi problemi di integrità, ridondanza o
incoerenza, a cui è necessario provvedere attraverso appositi metodi di riconciliazione dei dati:
• Integrità: di solito dovuti ad errore umano o incompletezza nell’immissione di dati (referenziati tra
di essi) all’interno del database.
• Ridondanza: informazioni ripetute all’interno del database.
• Ambiguità: incoerenza; differenti descrizioni di uno stesso dato o informazione non coincidono.

Lorenzo Putzu Laboratorio D’Informatica 6


Basi di dati
• Un DBMS supporta diversi livelli di astrazione sui dati, a differenza di altri sistemi informativi
analoghi non informatizzati (elenco telefonico, registro anagrafico cartaceo ecc.).
• Livello Fisico
• Livello Logico/Concettuale
• Livello Esterno

• Un DBMS deve essere in grado di gestire basi di dati di grandi dimensioni (Big Data), persistenti
(cioè con un ciclo di vita indipendente dal programma che le utilizza) e condivise da più
utenti/sistemi/applicazioni.

• Un DBMS deve inoltre prevedere modalità di controllo differenziato di accesso ai dati, per
garantire la privacy e la sicurezza di eventuali dati sensibili, riservati e/o personali.

Lorenzo Putzu Laboratorio D’Informatica 7


Architettura di un DBMS

Lorenzo Putzu Laboratorio D’Informatica


Utenti di una base di dati
• DBA - Database Administrator. Utente amministratore che ha il controllo
completo del sistema.
Le altre tipologie di utenti possono essere classificate in base alla loro
esperienza nell’uso delle varie funzionalità del sistema.
• Utente Inesperto. Utente finale, non ha conoscenza della struttura dei
modelli e/o dei linguaggi del sistema, quindi vi accede ed interagisce solo
mediante opportune interfacce grafiche fornite dal DBMS
• Programmatore Applicativo. Progettano software al cui interno viene
integrato un DBMS per la gestione dei dati
• Utente Sofisticato. Interviene direttamente sul DBMS, formulando query
oppure agendo sui dati
• Utente Specializzato. E’ un utente sofisticato che utilizza il sistema per
scopi di test (prestazioni del DBMS, controllo di applicazioni ecc.)
Lorenzo Putzu Laboratorio D’Informatica 9
DBMS: vantaggi e limiti
• I vantaggi nell’uso di un DBMS sono molteplici:
• Accesso ai dati indipendente dalla loro rappresentazione e memorizzazione.
• Tecniche di accesso ai dati ottimizzate (anche attraverso l’uso di strutture
aggiuntive, come gli indici), per migliorare le performance delle
interrogazioni.
• Possibilità di controllo dell’integrità e della completezza dei dati.
• Possibilità di controllo dell’accesso ai dati e modalità di accesso multi-utente.

• Alcuni limiti:
• Non permettono visualizzazioni grafiche dei dati o delle strutture dati.
• Implementano funzionalità matematiche e statistiche elementari di base.

Lorenzo Putzu Laboratorio D’Informatica 10


Linguaggi dei DMBS

• Due funzionalità:
– Data Definition Language (DDL)

– Data Manipulation Language (DML)

• Linguaggio standard (ANSI) dal 1999:


Structured Query Language (SQL)

Lorenzo Putzu Laboratorio D’Informatica 11


Obbiettivi del corso
● Punto di vista
– utente avanzato di una BD (interazione con i progettisti)

– progettista/amministratore di piccole BD

● Conoscenze di base
– progettazione concettuale: modello Entità-Relazione

– progettazione logica: modello relazionale


– principali comandi del linguaggio SQL per la definizione (DDL) e
l'interrogazione (DML) di BD

Lorenzo Putzu Laboratorio D’Informatica 12


DBMS esistenti
● Commerciali
– IBM

– Oracle
– Microsoft
– ...

● Open-source
– PostgreSQL

– MySQL
– ...

Lorenzo Putzu Laboratorio D’Informatica 13


Ambiente di lavoro
● Useremo il sistema open-source PostgreSQL
● consiglio la versione 10.18, disponibile per ogni sistema operativo
https://www.postgresql.org/

● Durante l’installazione
dovrete inserire una password
della quale dovete tener
traccia in quanto verrà
richiesta in seguito
• Il programma pgAdmin fornisce
l’interfaccia grafica al DBMS
Lorenzo Putzu Laboratorio D’Informatica 14
Ambiente di lavoro
• L’interfaccia è composta da tre pannelli. In particolare,
il pannello a sinistra mostra l’organizzazione gerarchica
del DBMS PostgreSQL (il contenuto di ogni elemento
può essere mostrato o nascosto selezionando il simbolo
> alla sua sinistra):
• un gruppo di server predefinito di nome ‘Servers’
• un server predefinito nel gruppo ‘Servers’, di nome
‘PostgreSQL’
• Per poter accedere al contenuto di ‘PostgreSQL’ è
necessario inserire la password scelta durante
l’installazione se sceglierete di memorizzare
la password non verrà più richiesta in futuro.
Lorenzo Putzu Laboratorio D’Informatica 15
Ambiente di lavoro
• Dopo l’avvio del server ‘PostgreSQL’, al suo interno (nel pannello a
sinistra) verrà mostrato l’elemento ‘Databases’, che contiene le basi
di dati da esso gestite.

Lorenzo Putzu Laboratorio D’Informatica 16


Ambiente di lavoro
• Dopo l’avvio del server ‘PostgreSQL’, al suo interno (nel pannello a
sinistra) verrà mostrato l’elemento ‘Databases’, che contiene le basi
di dati da esso gestite.
• Espandendo l’elemento ‘Databases’ verrà mostrata una base di dati
predefinita, di nome ‘postgres’. Espandendo i suoi elementi si potrà
vedere che una base di dati in PostgreSQL è composta da un insieme
di schemi (‘Schemas’), di cui uno predefinito di nome ‘public’, che può
contenere la definizione di un insieme di tabelle (‘Tables’). Dopo
l’installazione, la base di dati ‘postgres’ è vuota (non contiene
nessuna tabella).

Lorenzo Putzu Laboratorio D’Informatica 17


Ambiente di lavoro
● Per creare una nuova base di dati, fare click con il tasto
destro del mouse sull’elemento ‘Databases’ e scegliere
la voce ‘Create’ dal menu a tendina e poi ‘Database…’.
● Nella nuova finestra che compare sarà sufficiente
inserire il nome del database che si vuole creare.
● Anche questo nuovo database comparirà nell’elenco dei
database nel pannello a sinistra

Lorenzo Putzu Laboratorio D’Informatica 18


PostgreSQL
● Il nome:
– origine: University INteractive Graphics REtrieval System (INGRES)
– University of California, Berkeley, 1982: sviluppo di un DBMS open-source
"post-Ingres": Postgres
– Introduzione del supporto per SQL: PostgreSQL

● Object-relational DBMS
● Architettura client-server
● Componenti principali:
– server (gestione DB, utenti)
– strumento di amministrazione: pgAdmin
Lorenzo Putzu Laboratorio D’Informatica 19
PostgreSQL: architettura client / server

client client
...
host client host client

client
pgAdmin ...
(amministratore)
client

PostgreSQL server

BD
host server
Lorenzo Putzu Laboratorio D’Informatica 20
Architettura di un DB PostgreSQL
server

Base di dati ... Base di dati

...

schema1 ... schemam ...

tabella1 ... tabellap ...

colonna1 ... colonnaq vincoli ...

Lorenzo Putzu Laboratorio D’Informatica 21


IL MODELLO LOGICO
RELAZIONALE

Lorenzo Putzu Laboratorio D’Informatica 22


Esempio
● L'azienda XYZ è organizzata in dipartimenti: ognuno ha un nome e un codice numerico univoci,
una o più sedi (ognuna in una diversa città), ed è diretto da uno dei dipendenti a partire da una
certa data
● Ogni dipartimento controlla un insieme di progetti: ogni progetto ha un nome e un codice
numerico univoci e viene gestito da una delle sedi di un singolo dipartimento
● Ogni impiegato ha nome, cognome, sesso, data di nascita, CF, indirizzo (città, via, numero),
stipendio annuale, supervisore (un altro impiegato), e un dipartimento di afferenza; può lavorare
su uno o più progetti (anche gestiti da altri dipartimenti), a ciascuno dei quali dedica un certo
numero di ore settimanali
● Per scopi assicurativi ogni impiegato può avere familiari a carico, dei quali si memorizza nome e
cognome, sesso, data di nascita, e rapporto di parentela con l'impiegato (si assume che non
possano esistere due familiari omonimi di uno stesso impiegato, con la stessa data di nascita)

23
Esempio
● Il corso di laurea in ABC eroga diversi insegnamenti che hanno un nome (es.:
Analisi Matematica 1), un codice univoco di cinque caratteri assegnato dalla
segreteria studenti, e un numero di crediti
● Al corso di laurea possono essere iscritti diversi studenti. Per ogni iscritto si
vogliono memorizzare nome, cognome, codice fiscale, data di nascita e numero di
matricola (una sequenza di cinque caratteri che identifica univocamente ogni
studente)
● Ogni studente ha un proprio piano di studi
● Per ogni esame superato da ogni studente si vogliono conoscere il voto (un intero
tra 18 e 30, oppure 30 e lode) e la data; un esame superato non può essere
ripetuto

24
Il modello logico relazionale
• Ideato negli anni ‘70 è tuttora il modello più utilizzato per rappresentare i
database
• Fondamenti: teoria degli insiemi.
• Componenti:
● base di dati relazionale: insieme di tabelle (relazioni) identificate da un nome

univoco
● tabella: insieme di righe (record, "tuple"), suddivise in un insieme di colonne
(campi, attributi) identificate da un nome univoco; ogni riga contiene dati su
un elemento di un dato insieme; l'ordine delle righe e delle colonne non è
definito; non possono esistere righe identiche
● valori di ogni colonna: appartengono a un dominio

Lorenzo Putzu Laboratorio D’Informatica 25


Esempio
Studenti
Matricola Codice Fiscale Cognome Nome Data di nascita

00001 RSSMRA... Rossi Maria 1/1/1990


00002 VRDFRA... Verdi Francesca 3/2/1991
00003 NRIGVI... Neri Giovanni 5/7/1990
00004 BNCMRA... Bianchi Maria 10/11/1990
00005 SMTJOH... Smith John 12/12/1991

Insegnamenti Esami
Nome Codice Crediti Studente Esame Data Voto Lode
Analisi I AMI01 9 00003 GEO01 10/9/2013 28 falso
Geometria GEO01 6 00001 AMI01 15/9/2013 24 falso
Fisica I FISI1 6 00003 AMI01 30/09/2013 27 falso
Chimica CHI01 6 00002 GEO01 28/9/2013 30 vero
Informatica INF01 6 00004 CHI01 19/9/2013 27 falso

Lorenzo Putzu Laboratorio D’Informatica 26


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 11
Basi Di Dati

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


IL MODELLO LOGICO
RELAZIONALE

Lorenzo Putzu Laboratorio D’Informatica 2


Esempio
● L'azienda XYZ è organizzata in dipartimenti: ognuno ha un nome e un codice numerico univoci,
una o più sedi (ognuna in una diversa città), ed è diretto da uno dei dipendenti a partire da una
certa data
● Ogni dipartimento controlla un insieme di progetti: ogni progetto ha un nome e un codice
numerico univoci e viene gestito da una delle sedi di un singolo dipartimento
● Ogni impiegato ha nome, cognome, sesso, data di nascita, CF, indirizzo (città, via, numero),
stipendio annuale, supervisore (un altro impiegato), e un dipartimento di afferenza; può lavorare
su uno o più progetti (anche gestiti da altri dipartimenti), a ciascuno dei quali dedica un certo
numero di ore settimanali
● Per scopi assicurativi ogni impiegato può avere familiari a carico, dei quali si memorizza nome e
cognome, sesso, data di nascita, e rapporto di parentela con l'impiegato (si assume che non
possano esistere due familiari omonimi di uno stesso impiegato, con la stessa data di nascita)

3
Esempio
● Il corso di laurea in ABC eroga diversi insegnamenti che hanno un nome (es.:
Analisi Matematica 1), un codice univoco di cinque caratteri assegnato dalla
segreteria studenti, e un numero di crediti
● Al corso di laurea possono essere iscritti diversi studenti. Per ogni iscritto si
vogliono memorizzare nome, cognome, codice fiscale, data di nascita e numero di
matricola (una sequenza di cinque caratteri che identifica univocamente ogni
studente)
● Ogni studente ha un proprio piano di studi
● Per ogni esame superato da ogni studente si vogliono conoscere il voto (un intero
tra 18 e 30, oppure 30 e lode) e la data; un esame superato non può essere
ripetuto

4
Il modello logico relazionale
• Ideato negli anni ‘70 è tuttora il modello più utilizzato per rappresentare i
database
• Fondamenti: teoria degli insiemi.
• Componenti:
● base di dati relazionale: insieme di tabelle (relazioni) identificate da un nome

univoco
● tabella: insieme di righe (record, "tuple"), suddivise in un insieme di colonne
(campi, attributi) identificate da un nome univoco; ogni riga contiene dati su
un elemento di un dato insieme; l'ordine delle righe e delle colonne non è
definito; non possono esistere righe identiche
● valori di ogni colonna: appartengono a un dominio

Lorenzo Putzu Laboratorio D’Informatica 5


Esempio
Studenti
Matricola Codice Fiscale Cognome Nome Data di nascita

00001 RSSMRA... Rossi Maria 1/1/1990


00002 VRDFRA... Verdi Francesca 3/2/1991
00003 NRIGVI... Neri Giovanni 5/7/1990
00004 BNCMRA... Bianchi Maria 10/11/1990
00005 SMTJOH... Smith John 12/12/1991

Insegnamenti Esami
Nome Codice Crediti Studente Esame Data Voto Lode
Analisi I AMI01 9 00003 GEO01 10/9/2013 28 falso
Geometria GEO01 6 00001 AMI01 15/9/2013 24 falso
Fisica I FISI1 6 00003 AMI01 30/09/2013 27 falso
Chimica CHI01 6 00002 GEO01 28/9/2013 30 vero
Informatica INF01 6 00004 CHI01 19/9/2013 27 falso

Lorenzo Putzu Laboratorio D’Informatica 6


Schema e istanza di una base di dati relazionale

● Schema: struttura della BD, definita in fase di progettazione, costante nel tempo
– schema di una BD: schema delle sue tabelle, vincoli d'integrità tra tabelle
– schema di una tabella:
● nome della tabella

● nome e dominio di ciascuna colonna, vincoli d'integrità

● Istanza: dati contenuti nella BD in un dato istante di tempo


– modificabile dagli utenti
– operazioni: aggiunta, cancellazione, modifica di righe di una o più tabelle

Lorenzo Putzu Laboratorio D’Informatica 7


Vincoli d'integrità
● Vincoli sui valori che possono essere memorizzati nella BD, per garantirne la
correttezza
● Definiti in fase di progettazione (schema)
● Applicati automaticamente dal DBMS in fase di aggiunta e modifica delle righe
delle tabelle
● Tipologie di vincoli:
– di dominio
– di chiave
– d'integrità referenziale (chiave esterna)
– di dominio esteso, di tupla (check), asserzioni (su più tabelle)

Lorenzo Putzu Laboratorio D’Informatica 8


Vincolo di dominio
• Definisce l'insieme di valori che una colonna potrà assumere.
• Nel linguaggio SQL esistono sia domini predefiniti che domini definibili dall'utente. Principali
domini predefiniti:
● numeri interi
● numeri reali
● stringhe di caratteri (incluso il numero massimo di caratteri)
● date (giorno, mese, anno)
● istanti di tempo (ore, minuti, secondi)
● valori logici Booleani (vero/falso)
• È anche possibile non inserire nessun valore in una colonna.
• È obbligatorio specificare il vincolo di dominio per ogni colonna.
Lorenzo Putzu Laboratorio D’Informatica 9
Vincolo di dominio: esempio
Studenti
Matricola Codice Fiscale Cognome Nome Data di nascita

stringa di stringa di stringa di stringa di data


5 caratteri 16 caratteri 50 caratteri 50 caratteri

Insegnamenti
Nome Codice Crediti

stringa di stringa di intero


50 caratteri 5 caratteri

Esami
Studente Esame Data Voto Lode

stringa di stringa di data intero Booleano


5 caratteri 5 caratteri
Lorenzo Putzu Laboratorio D’Informatica 10
Vincolo di chiave
• Nelle BD relazionali ogni tabella deve avere almeno un insieme di una o più colonne che
non potranno assumere valori identici in righe diverse (si ricordi che una tabella è un
insieme di righe). Tali colonne devono essere individuate tenendo conto della natura e del
significato dei dati memorizzati nella tabella.
• Ogni sottoinsieme minimale (cioè composto dal minor numero possibile di colonne) di tali
colonne è detto chiave candidata.
• Una delle chiavi candidate deve poi essere obbligatoriamente scelta come chiave
primaria attraverso il vincolo di chiave. La chiave primaria ha la funzione di:
– identificare univocamente le righe di una tabella
– rendere più efficienti le interrogazioni
• Tutte le colonne della chiave primaria sono inoltre vincolate a dover sempre contenere un
valore.

Lorenzo Putzu Laboratorio D’Informatica 11


Vincolo di chiave: esempio
Studenti
Matricola Codice Fiscale Cognome Nome Data di nascita

00001 RSSMRA... Rossi Maria 1/1/1990


00002 VRDFRA... Verdi Francesca 3/2/1991
00003 NRIGVI... Neri Giovanni 5/7/1990
00004 BNCMRA... Bianchi Maria 10/11/1990
00005 SMTJOH... Smith John 12/12/1991
00006 BRNMRO... Bruni Marco 28/2/1991

Due chiavi candidate: Matricola e Codice Fiscale.


Una delle due dovrà essere scelta come chiave primaria.

Lorenzo Putzu Laboratorio D’Informatica 12


Vincolo di chiave: esempio
Insegnamenti
Nome Codice Crediti
Analisi I AMI01 9
Geometria GEO01 6
Fisica I FISI1 6
Chimica CHI01 6
Informatica INF01 6

Assumendo che il codice identifichi univocamente ogni insegnamento:


• una chiave candidata, che costituirà la chiave primaria: Codice

Lorenzo Putzu Laboratorio D’Informatica 13


Vincolo di chiave: esempio
Esami
Studente Esame Data Voto Lode
00003 GEO01 10/9/2013 28 falso

00001 AMI01 15/9/2013 24 falso


00003 AMI01 30/09/2013 27 falso
00002 GEO01 28/9/2013 30 vero

00004 CHI01 19/9/2013 27 falso


Assumendo di voler memorizzare nella tabella Esami solo gli esami sostenuti con esito
positivo, e che l'esame per un dato insegnamento possa essere sostenuto non più di una
volta con esito positivo da uno stesso studente:
• una chiave candidata, che costituirà la chiave primaria, composta da due colonne:
(Studente, Esame)
Lorenzo Putzu Laboratorio D’Informatica 14
Vincolo di chiave: notazione grafica
Di norma le chiavi primarie sono evidenziate con la sottolineatura dei nomi delle colonne corrispondenti.
Studenti
Matricola Codice Fiscale Cognome Nome Data di nascita

00001 RSSMRA... Rossi Maria 1/1/1990


00002 VRDFRA... Verdi Francesca 3/2/1991
... ... ... ... ...
Insegnamenti Esami
Nome Codice Crediti Studente Esame Data Voto Lode
Analisi I AMI01 9 00003 GEO01 10/9/2013 28 no
Geometria GEO01 6 00001 AMI01 15/9/2013 24 no
Fisica I FISI1 6 00003 AMI01 30/09/2013 27 no
Chimica CHI01 6 00002 GEO01 28/9/2013 30 sì
Informatica INF01 6 00004 CHI01 19/9/2013 27 no

Lorenzo Putzu Laboratorio D’Informatica 15


Vincoli d'integrità referenziale
• Una BD contiene dati suddivisi nelle righe di diverse tabelle.
• È possibile mettere in corrispondenza le righe di tabelle diverse facendo in modo
che le righe di una tabella referenziante contengano un riferimento alle righe di
una tabella referenziata.
• Nelle BD relazionali questo è possibile attraverso la condivisione di colonne tra la
tabella referenziante e quella referenziata.

Lorenzo Putzu Laboratorio D’Informatica 16


Vincoli d'integrità referenziale
• Per mettere in corrispondenza le righe di due tabelle:
● si aggiungono alla tabella referenziante le colonne (dette chiave esterna) corrispondenti alla
chiave primaria della tabella referenziata; tali colonne dovranno avere lo stesso dominio (ma
possono avere nomi diversi)
● si definisce un vincolo d'integrità referenziale che lega le colonne della chiave esterna della
tabella referenziante a quelle della chiave primaria della tabella referenziata
• Il vincolo d'integrità referenziale impone che non sarà possibile inserire nella tabella
referenziante righe contenenti valori della chiave esterna che non compaiono nelle righe
dell'istanza attuale della tabella referenziata.
• Consente inoltre di specificare le azioni da svolgere nel caso di modifiche alla tabella
referenziata (si veda più avanti) che potrebbero comportare la violazione dello stesso vincolo.

Lorenzo Putzu Laboratorio D’Informatica 17


Vincoli d'integrità referenziale: esempio
Studenti
Matricola Codice Fiscale Cognome Nome Data di nascita

00001 RSSMRA... Rossi Maria 1/1/1990


00002 VRDFRA... Verdi Francesca 3/2/1991
00003 NRIGVI... Neri Giovanni 5/7/1990
00004 BNCMRA... Bianchi Maria 10/11/1990
00005 SMTJOH... Smith John 12/12/1991
00006 BRNMRO... Bruni Marco 28/2/1991
Insegnamenti Esami
Nome Codice Crediti Studente Esame Data Voto Lode
Analisi I AMI01 9 00003 GEO01 10/9/2013 28 no
Geometria GEO01 6 00001 AMI01 15/9/2013 24 no
Fisica I FISI1 6 00003 AMI01 30/09/2013 27 no
Chimica CHI01 6 00002 GEO01 28/9/2013 30 sì
Informatica INF01 6 00004 CHI01 19/9/2013 27 no
Lorenzo Putzu Laboratorio D’Informatica 18
Vincoli d'integrità referenziale: esempio

• Nell'esempio precedente, il vincolo d'integrità referenziale tra la colonna


"Studente" della tabella "Esami" e la colonna "Matricola" della tabella "Studenti":
● può essere definito solo se le due colonne hanno lo stesso dominio

● impone che nella prima potranno essere inseriti solo numeri di matricola che

si trovano già nella seconda (in altre parole, si possono memorizzare solo
esami sostenuti da studenti che compaiono nella tabella "Studenti")
• Analogo discorso vale per il vincolo tra la colonna "Esame" della tabella "Esami" e
la colonna "Codice" della tabella "Insegnamenti".

Lorenzo Putzu Laboratorio D’Informatica 19


Vincoli d'integrità referenziale
• Come caso particolare, la tabella referenziante e quella referenziata possono coincidere.
• Esempio: una tabella che contiene dati anagrafici su un insieme di persone, tra i quali il codice fiscale
(chiave primaria), e il padre di ciascuna persona (la colonna "Padre", che corrisponde alla chiave
esterna).
• Se le informazioni sul padre di qualche persona non sono contenute nella tabella, il corrispondente
valore della colonna "Padre" sarà assente.
Persone
Padre Codice Fiscale Cognome Nome Data di nascita

RSSMRO... RSSMRA... Rossi Maria 1/1/1979


RSSMRO... RSSFRA... Rossi Francesca 3/2/1991
NULL NRIGVI... Neri Giovanni 5/7/1950
NULL BNCMRA... Bianchi Maria 10/11/1962
NRIGVI... NRILCA... Neri Luca 12/12/1991
NULL RSSMRO... Rossi Marco 28/2/1961
Lorenzo Putzu Laboratorio D’Informatica 20
Altri vincoli d'integrità
● Vincolo di dominio esteso: limita ulteriormente i valori che possono essere
assunti da una colonna a un sottoinsieme del suo dominio. Esempi:
– voto di un esame: numero intero (dominio), compreso tra 18 e 30 (vincolo di
dominio esteso)
– si può anche imporre che il valore di una colonna non possa essere assente
(nota: tale vincolo è sempre implicito per tutte le colonne della chiave
primaria)

● Vincolo di tupla: limita i valori che possono essere assunti da due o più colonne in
una stessa riga.
Esempio: colonne "Voto" (intero tra 18 e 30) e "Lode" (sì/no) di un esame: la lode
può essere assegnata (sì) solo se il voto è 30

Lorenzo Putzu Laboratorio D’Informatica 21


Altri vincoli d'integrità
● Vincolo di unicità (su una o più colonne): definisce un sottoinsieme di colonne di
una tabella, diverso dalla chiave primaria, che non potrà assumere lo stesso valore
in righe diverse
● Esempio: se nella tabella "Studenti" si sceglie "Matricola" come chiave primaria, sulla colonna
"Codice fiscale" potrà essere imposto un vincolo di unicità (questo impedirà l'inserimento di
uno stesso codice fiscale per studenti diversi)

● Asserzioni: vincoli che coinvolgono più tabelle

Lorenzo Putzu Laboratorio D’Informatica 22


Il vincolo di unicità
• Un vincolo di unicità imposto su due o più colonne impone che non potranno esistere righe con
valori identici in tutte le colonne coinvolte (analogamente al vincolo di chiave primaria).
• Esempio:
● un vincolo di unicità sulle colonne "Nome" e "Cognome" della tabella "Studenti" impedisce di
inserire studenti omonimi, aventi cioè sia lo stesso nome che lo stesso cognome, ma non
impedisce di inserire studenti che abbiano identico solo il nome o solo il cognome (es.: Marco
Rossi e Francesco Rossi)
● due vincoli di unicità distinti sulle stesse colonne impongono una condizione più restrittiva:
non solo impediscono di inserire studenti omonimi, ma anche studenti che abbiano identico
solo il nome (per es., Marco Rossi e Marco Bianchi), oppure solo il cognome (per es., Mario
Neri e Giovanni Neri)

Lorenzo Putzu Laboratorio D’Informatica 23


Schema logico relazionale: notazione
informale
• Studenti (Matricola: stringa di 5 caratteri,
Codice fiscale: stringa di 16 caratteri,
Cognome: stringa di 50 caratteri,
Nome: stringa di 50 caratteri,
Data di nascita: data)
• Insegnamenti (Nome: stringa di 50 caratteri,
Codice: stringa di 5 caratteri,
Crediti: intero)
• Esami (Data: data,
Voto: intero,
Lode: Booleano,
Studente: stringa di 5 caratteri,
Esame: stringa di 5 caratteri)
• Vincoli d'integrità referenziale (chiavi esterne):
● Studente (tab. Esami, referenziante) → Matricola (tab. Studenti, referenziata)
● Esame (tab. Esami, referenziante) → Codice (tab. Corso, referenziata)
• Altri vincoli:
● Tabella Esami: 18 ≤ Voto ≤ 30 (vincolo di dominio esteso)
● Se Voto < 30, Lode non può essere 'vero' (vincolo di tupla)

Lorenzo Putzu Laboratorio D’Informatica 24


Il linguaggio SQL

Lorenzo Putzu Laboratorio D’Informatica 25


Basi di dati e linguaggio SQL
● Base di dati: una collezione di schemi
● Ogni schema:
– è identificato da un nome

– è associato a un utente (proprietario)


– contiene una collezione di descrittori di:
● tabelle
● vincoli
● domini definiti dall'utente
● autorizzazioni per l'accesso ai dati da parte degli utenti
● ...
Lorenzo Putzu Laboratorio D’Informatica 26
SQL: funzionalità principali
● Definizione dello schema di una BD: tabelle, colonne, vincoli, ecc. (data definition
language, DDL)
● Accesso all'istanza di una BD (data manipulation language, DML)
– modifica dell'istanza di una BD (inserimento di righe, modifica di righe,
cancellazione di righe)
– estrazione di dati da una BD (interrogazione)

• Interfacce:
– a "riga di comando" (es.: psql)
– grafiche (es.: pgAdmin)

Lorenzo Putzu Laboratorio D’Informatica 27


Principali domini predefiniti in SQL
● integer oppure int: numero intero
● real: numero reale
● character varying(n) oppure varchar(n):
stringa di non più di n caratteri
● date: data, nel formato AAAA-MM-GG (sono ammessi solo valori che corrispondono a
date valide, per es., 1≤MM≤12, ecc.)
● time: ore, minuti e secondi, nel formato hh:mm:ss
(valori ammessi: 00≤hh≤24, 00≤mm≤59, 00≤ss≤59)
● boolean: valore logico Booleano, con valori "vero" e "falso" indicati dai simboli TRUE e
FALSE (es.: colonna "Lode" riferita al voto di un esame)

Lorenzo Putzu Laboratorio D’Informatica 28


Definizione di una tabella
• Principale comando SQL di tipo DDL: definizione dello schema di una tabella.

• Sintassi:
CREATE TABLE "nome_tabella" (
"nome colonna" dominio ,
...
"nome colonna" dominio ,
PRIMARY KEY ("nome colonna", ..., "nome colonna")
);

Lorenzo Putzu Laboratorio D’Informatica 29


Esempio
CREATE TABLE "Studenti" (
"Cognome" varchar(50) ,
"Nome" varchar(50) ,
"Matricola" varchar(5) ,
"Data di nascita" date ,
"Codice fiscale" varchar(16) ,
PRIMARY KEY ("Matricola")
);

Lorenzo Putzu Laboratorio D’Informatica 30


Definizione di una tabella
• Oltre ai vincoli di dominio e di chiave primaria (obbligatori) è possibile definire
ulteriori vincoli, con i seguenti comandi:
● vincoli di dominio esteso su una colonna:
– NOT NULL (il valore della colonna non può essere assente)
– CHECK condizione (specifica una condizione che dovrà essere rispettata dai valori della colonna)
● vincolo di unicità su una o più colonne:
UNIQUE ("nome colonna", ...)
● vincolo di chiave esterna su una o più colonne:
FOREIGN KEY ...
● vincolo di tupla su una o più colonne: CHECK condizione

• È anche possibile indicare un valore di default per una colonna:


DEFAULT valore
Lorenzo Putzu Laboratorio D’Informatica 31
Definizione di una tabella
• Sintassi:
CREATE TABLE "nome_tabella" (
"nome colonna" dominio [NOT NULL] [DEFAULT valore] ,
...
[ UNIQUE ("nome colonna", ..., "nome colonna") , ]
[ FOREIGN KEY ("nome colonna", ..., "nome colonna")
REFERENCES "tabella referenziata"("nome colonna"), ... , ]
PRIMARY KEY ("nome colonna", ..., "nome colonna")
);

Lorenzo Putzu Laboratorio D’Informatica 32


Esempio
CREATE TABLE "Studenti" (
"Cognome" varchar(50) NOT NULL ,
"Nome" varchar(50) ,
"Matricola" varchar(5) ,
"Data di nascita" date ,
"Codice fiscale" varchar(16) ,
UNIQUE ("Codice fiscale"),
PRIMARY KEY ("Matricola")
);

Lorenzo Putzu Laboratorio D’Informatica 33


Esempio
CREATE TABLE "Insegnamenti" (
"Nome" varchar(50) NOT NULL,
"Crediti" int ,
"Codice" varchar(5) ,
PRIMARY KEY ("Codice")
);

Lorenzo Putzu Laboratorio D’Informatica 34


Esempio
CREATE TABLE "Esami" (
"Voto" integer NOT NULL ,
"Lode" boolean DEFAULT FALSE ,
"Data" date ,
"Studente" varchar(5) ,
"Esame" varchar(5) ,
PRIMARY KEY ("Studente", "Esame"),
FOREIGN KEY ( "Studente" )
REFERENCES "Studenti" ("Matricola") ,
FOREIGN KEY ( "Esame" )
REFERENCES "Insegnamenti" ("Codice") ,
CHECK ("Voto" >= 18 AND "Voto" <= 30) ,
CHECK (NOT ("Voto" < 30 AND "Lode" = TRUE))
);

Lorenzo Putzu Laboratorio D’Informatica 35


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 12
Basi Di Dati

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Vincolo d'integrità referenziale
• Le modifiche a una tabella referenziata che violerebbero il vincolo di integrità
referenziale (cancellazione di righe o modifica dei valori della chiave primaria)
vengono impedite da un DBMS, a meno che non si specifichi un'azione diversa
nella definizione dello stesso vincolo, attraverso le clausole:
● ON DELETE (azioni da eseguire in caso di cancellazione)
● ON UPDATE (azioni da eseguire in caso di modifica)

Lorenzo Putzu Laboratorio D’Informatica 2


Vincolo d'integrità referenziale
• Le azioni principali disponibili in SQL sono:
● SET NULL: si assegna NULL alla chiave esterna in corrispondenza delle righe
cancellate o modificate nella tabella referenziata (è possibile solo se la chiave esterna
non fa parte anche della chiave primaria della tabella referenziante)
● SET DEFAULT: si assegna il valore di default alla chiave esterna (se non si è specificato
tale valore nel comando CREATE TABLE, si assegna NULL)
● CASCADE: la modifica alla tabella referenziata viene propagata a quella
referenziante: nel caso ON DELETE si eliminano le righe corrispondenti nella tabella
referenziante; nel caso ON UPDATE si aggiorna il valore della chiave esterna
● NO ACTION: la modifica viene impedita (azione predefinita, non è necessario
specificarla esplicitamente)

Lorenzo Putzu Laboratorio D’Informatica 3


Vincolo d'integrità referenziale
• Sintassi completa della clausola FOREIGN KEY:

...
FOREIGN KEY ("nome colonna", ...)
REFERENCES "tabella referenziata" ("nome colonna", ...) ,
[ ON DELETE CASCADE / SET NULL / SET DEFAULT /
NO ACTION , ]
[ ON UPDATE CASCADE / SET NULL / SET DEFAULT /
NO ACTION , ]
...

Lorenzo Putzu Laboratorio D’Informatica 4


Esempio
CREATE TABLE "Esami" (
...
FOREIGN KEY ("Studente")
REFERENCES "Studenti" ("Matricola"),
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY ("Insegnamento")
REFERENCES "Insegnamenti" ("Codice")
ON UPDATE CASCADE ON DELETE CASCADE ,
...
);
Lorenzo Putzu Laboratorio D’Informatica 5
Esercizio (1/3)
• Si consideri una BD, di nome "Circolo nautico", che debba contenere alcuni
dati sui velisti soci di un circolo nautico, sulle barche gestite dal circolo e
sulle loro prenotazioni da parte dei soci.
• Una barca può essere prenotata da un solo socio alla volta, e la
prenotazione dura un intero giorno.
• Ciascun socio e ciascuna barca sono identificati univocamente da un codice
denominato rispettivamente "vid" e "bid" (in entrambi i casi, un numero
intero).
• L'esperienza nautica di ciascun socio è rappresentata con un valore da 1
(minima) a 10 (massima).

Lorenzo Putzu Laboratorio D’Informatica 6


Esercizio (2/3)
• Un esempio di istanza della BD (i vincoli d'integrità referenziale sono indicati
dalle frecce)
Velisti
vid vnome esperienza età
22 Dustin 7 45.0
31 Lubber 8 55.5
Barche
58 Rusty 10 35.0
bid bnome colore
Prenotazioni 101 Interlake blu
vid bid giorno 102 Interlake rosso
22 101 10/10/96 103 Clipper verde
58 103 11/12/96 104 Marine rosso

Lorenzo Putzu Laboratorio D’Informatica 7


Esercizio (3/3)
• Schema logico:
• Velisti (vid: intero, vnome: stringa(20), esperienza: int., età: reale)
• Barche (bid: intero, bnome: stringa(25), colore: stringa(10))
• Prenotazioni (vid: intero, bid: intero, giorno: data)
• Vincoli d'integrità referenziale:
● vid(Prenotazioni) → vid(Velisti); tutte le modifiche alla tabella Velisti devono essere propagate alla tabella
Prenotazioni
● bid(Prenotazioni) → bid(Barche); come sopra per le modifiche
• Vincoli di dominio esteso:
● esperienza ∈ {1,...,10}
● età ≥ 18
● il nome di ogni velista e di ogni barca devono sempre essere specificati

• Scrivere i comandi SQL per la creazione della BD.


Lorenzo Putzu Laboratorio D’Informatica 8
Soluzione
CREATE TABLE "Velisti" (
"vid" int,
"vnome" varchar(20) NOT NULL,
"esperienza" int,
"età" real,
PRIMARY KEY ("vid"),
CHECK ("esperienza" >= 1 AND "esperienza" <= 10),
CHECK ("età" >= 18)
);

Lorenzo Putzu Laboratorio D’Informatica 9


Soluzione
CREATE TABLE "Barche" (
"bid" int,
"bnome" varchar(25) NOT NULL,
"colore" varchar(10),
PRIMARY KEY ("bid")
);

Lorenzo Putzu Laboratorio D’Informatica 10


Soluzione
CREATE TABLE "Prenotazioni" (
"bid" int,
"vid" int,
"data" date,
PRIMARY KEY ("bid", "vid", "data"),
FOREIGN KEY ("bid") REFERENCES "Barche"("bid")
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY ("vid") REFERENCES "Velisti"("vid")
ON UPDATE CASCADE ON DELETE CASCADE
);

Lorenzo Putzu Laboratorio D’Informatica 11


Interrogazioni
• Operazioni che:
– modificano l'istanza di una BD

● inserimento di una nuova riga in una tabella


● cancellazione di una riga da una tabella
● modifica dei valori di una o più colonne di una riga di una tabella
– estraggono dati dall'istanza di una BD

• I comandi SQL che le realizzano fanno parte del data manipulation language
(DML).

Lorenzo Putzu Laboratorio D’Informatica 12


Interrogazioni
• In una BD relazionale il risultato di un'interrogazione è definito come:
● una nuova istanza della BD, per operazioni di modifica (che non violino
nessun vincolo d'integrità)
● una nuova tabella (fittizia, non memorizzata nella BD), per operazioni di
estrazione di dati

Lorenzo Putzu Laboratorio D’Informatica 13


Esempi
• Esempi di interrogazioni per l'estrazione di dati dalla BD "Circolo Nautico":
● Trovare i nomi dei velisti che hanno prenotato la barca numero 103

● Trovare i nomi e le età di tutti i velisti

● Trovare i nomi dei velisti che hanno prenotato almeno una barca

● Trovare i codici dei velisti che hanno prenotato una barca rossa, oppure una

barca verde

Lorenzo Putzu Laboratorio D’Informatica 14


Interrogazioni: il comando SELECT

• Forma elementare:
● SELECT "nome_colonna", ..., "nome_colonna"
FROM "nome_tabella" ;
estrae da tutte le righe di una tabella i valori delle colonne indicate
● SELECT * FROM "nome_tabella" ;
restituisce l'intera tabella
• Esempi:
● Trovare il codice e il nome di tutti i velisti:
SELECT "vid","nome" FROM "Velisti";
● Trovare i dati su tutte le barche:
SELECT * FROM "Barche";

Lorenzo Putzu Laboratorio D’Informatica 15


SELECT: la clausola WHERE
• Per estrarre i valori delle colonne indicate, dalle sole righe di una tabella che
soddisfano una data condizione:

• SELECT "nome_colonna", ..., "nome_colonna"


FROM "nome_tabella"
WHERE <qualificazione (condizione)> ;

Lorenzo Putzu Laboratorio D’Informatica 16


SELECT: la clausola WHERE
• Le condizioni (qualificazioni) più semplici sono:
– confronto tra il valore di una colonna e un valore costante dello stesso
dominio
– confronto tra i valori di due colonne aventi lo stesso dominio

• Si possono usare i seguenti operatori di confronto:


< <= = > >= <>

• Si possono inoltre definire condizioni composte combinando altre condizioni


(semplici o a loro volta composte) con gli operatori logici AND, OR, NOT.

Lorenzo Putzu Laboratorio D’Informatica 17


SELECT: la clausola WHERE
• Nota:
● i nomi delle colonne devono essere racchiusi tra doppi apici, per es.:

"Cognome"
● i valori costanti devono essere racchiusi tra apici singoli, per es.:

"Cognome" = 'Rossi'
"Data di nascita" >= '1990-01-01'
"età" > '25'
● i valori numerici (integer e real) possono anche essere scritti senza

racchiuderli tra apici singoli, per es.: "età" > 25

Lorenzo Putzu Laboratorio D’Informatica 18


Esempi
● Trovare i nomi dei velisti con più di 40 anni:
SELECT "vnome"
FROM "Velisti"
WHERE "età" > 40;

● Trovare i nomi dei velisti con più di 40 anni, oppure con esperienza maggiore
di 7:
SELECT "vnome"
FROM "Velisti"
WHERE "età" > 40 OR "esperienza" > 7;

Lorenzo Putzu Laboratorio D’Informatica 19


Esercizi
• Si consideri la BD degli esempi mostrati in precedenza, composta dalle
tabelle "Studenti", Insegnamenti" ed "Esami" (denominata da qui in poi
"Segreteria Studenti"):
1)Trovare nomi e cognomi degli studenti nati il 1 gennaio 1991
2)Trovare nomi e cognomi degli studenti nati tra il 1 e il 31 gennaio 1991
3)Trovare i nomi degli insegnamenti da 6 crediti
4)Trovare le matricole degli studenti che hanno conseguito la votazione di 30
in qualche esame

Lorenzo Putzu Laboratorio D’Informatica 20


Soluzioni
1) SELECT "Nome", "Cognome"
FROM "Studenti"
WHERE "Data di nascita" = '1991-01-01';
2) SELECT "Nome", "Cognome"
FROM "Studenti"
WHERE "Data di nascita" >= '1991-01-01'
AND "Data di nascita" <= '1991-01-31';
3) SELECT "Nome"
FROM "Insegnamenti"
WHERE "Crediti" = 6;
4) SELECT "Studente"
FROM "Esami"
WHERE "Voto" = 30;

Lorenzo Putzu Laboratorio D’Informatica 21


La clausola DISTINCT
• Contrariamente alle tabelle definite con CREATE TABLE, la tabella risultato di
un'interrogazione può contenere righe identiche.
• Per es., nella BD "Circolo Nautico":
• SELECT "colore" FROM "Barche";
• restituisce:
colore
blu
rosso
verde
rosso

Lorenzo Putzu Laboratorio D’Informatica 22


La clausola DISTINCT
• Per eliminare le eventuali righe duplicate (se queste non sono utili):
• SELECT DISTINCT "nome_colonna", ...
FROM "nome_tabella"
WHERE <qualificazione (condizione)> ;
• Esempio:
• SELECT DISTINCT "colore" FROM "Barche";
• restituisce:
colore
blu
rosso
verde

Lorenzo Putzu Laboratorio D’Informatica 23


Interrogazioni su più tabelle
• Esempio: tovare i nomi dei velisti che hanno prenotato la barca numero 103.
• I dati richiesti si trovano in tabelle diverse

Velisti
vid vnome esperienza età
22 Dustin 7 45.0
31 Lubber 8 55.5 Barche
58 Rusty 10 35.0 bid bnome colore
Prenotazioni 101 Interlake blu
vid bid giorno 102 Interlake rosso
22 101 10/10/96 103 Clipper verde
58 103 11/12/96 104 Marine rosso

Lorenzo Putzu Laboratorio D’Informatica 24


Interrogazioni su più tabelle
• Intuitivamente, si può seguire questa procedura:
• 1) Schema della tabella risultato: una colonna (vnome):
SELECT "Velisti"."vnome" ...
• 2) In quali tabelle si trovano le informazioni richieste? Velisti e Prenotazioni:
SELECT "Velisti"."vnome" FROM "Velisti", "Prenotazioni" ...
• 3) Quali condizioni devono essere rispettate? Analizzare tutte le possibili combinazioni di
righe delle tabelle in esame, ed estrarre vnome da una riga di "Velisti", se il vid della
stessa riga coincide con il vid della riga di "Prenotazioni", e il bid di quest'ultima è 103:
• SELECT "Velisti"."vnome"
FROM "Velisti", "Prenotazioni"
WHERE "Velisti"."vid" = "Prenotazioni"."vid"
AND "Prenotazioni"."bid"= 103;

Lorenzo Putzu Laboratorio D’Informatica 25


Interrogazioni su più tabelle
• Nota: per distinguere le colonne di tabelle diverse, il nome di ogni colonna
deve essere preceduto da quello della tabella, e i due nomi devono essere
separati da un punto.
• Se il nome di una colonna compare in una sola tabella, e quindi non genera
ambiguità, può essere scritto senza il nome della tabella corrispondente.
Tuttavia questo rende l'interrogazione meno leggibile.

Lorenzo Putzu Laboratorio D’Informatica 26


Variabili di range
• Per semplificare un'interrogazione su più tabelle, i nomi di queste ultime
possono essere sostituiti da variabili di range, cioè nomi simbolici scelti
dall'utente e indicati nella clausola FROM subito dopo il nome di ciascuna
tabella.
• L'esempio precedente può essere riscritto come segue, associando alle
tabelle "Velisti" e "Prenotazioni" le variabili di range V e P:
• SELECT V."vnome"
FROM "Velisti" V, "Prenotazioni" P
WHERE V."vid" = P."vid" AND P."bid"= 103;

Lorenzo Putzu Laboratorio D’Informatica 27


Esempio
• Trovare i cognomi degli studenti che hanno sostenuto l'esame avente codice
AMI01:
• SELECT S."Cognome"
FROM "Studenti" S, "Esami" E
WHERE E."Esame" = 'AMI01' AND
S."Matricola" = E."Studente";

Lorenzo Putzu Laboratorio D’Informatica 28


Strategia di valutazione concettuale
• Algoritmo per eseguire interrogazioni su più tabelle, descritto in precedenza in
modo informale:
1.eseguire il prodotto cartesiano delle tabelle (insiemi di righe) indicate nella
clausola FROM, ottenendo una nuova tabella P (ogni riga di P corrisponde a una
combinazione di righe delle tabelle originali)
2.selezionare le righe di P che soddisfano la qualificazione (la condizione nella
clausola WHERE)
3.proiettare le righe selezionate sulle colonne indicate nella clausola SELECT (cioè
eliminare tutte le altre colonne)
4.se è presente la clausola DISTINCT, eliminare le eventuali righe duplicate

Lorenzo Putzu Laboratorio D’Informatica 29


Esempio Velisti
SELECT V."vnome" vid vnome esperienza età
FROM "Velisti" V, "Prenotazioni" P 22 Dustin 7 45.0
WHERE V."vid" = P."vid" AND P."bid" = 103; 31 Lubber 8 55.5
58 Rusty 10 35.0
Prenotazioni
vid bid giorno
22 101 10/10/96
58 103 11/12/96

Lorenzo Putzu Laboratorio D’Informatica 30


Esempio Velisti
SELECT V."vnome" vid vnome esperienza età
FROM "Velisti" V, "Prenotazioni" P 22 Dustin 7 45.0
WHERE V."vid" = P."vid" AND P."bid" = 103; 31 Lubber 8 55.5
58 Rusty 10 35.0
Prenotazioni
vid bid giorno
1. Prodotto cartesiano delle tabelle
22 101 10/10/96
nella clausola FROM:
58 103 11/12/96

V.vid V.vnome V.esperienza V.età P.vid P.bid P.giorno

22 Dustin 7 45.0 22 101 10/10/96


22 Dustin 7 45.0 58 103 11/12/96
31 Lubber 8 55.5 22 101 10/10/96
31 Lubber 8 55.5 58 103 11/12/96
58 Rusty 10 35.0 22 101 10/10/96
Lorenzo Putzu 58 Rusty 10Laboratorio
35.0 D’Informatica
58 103 11/12/96 31
Esempio Velisti
SELECT V."vnome" vid vnome esperienza età
FROM "Velisti" V, "Prenotazioni" P 22 Dustin 7 45.0
WHERE V."vid" = P."vid" AND P."bid" = 103; 31 Lubber 8 55.5
58 Rusty 10 35.0
Prenotazioni
vid bid giorno
2. Selezione delle righe che soddisfano
22 101 10/10/96
la qualificazione:
58 103 11/12/96

V.vid V.vnome V.esperienza V.età P.vid P.bid P.giorno

58 Rusty 10 35.0 58 103 11/12/96

Lorenzo Putzu Laboratorio D’Informatica 32


Esempio Velisti
SELECT V."vnome" vid vnome esperienza età
FROM "Velisti" V, "Prenotazioni" P 22 Dustin 7 45.0
WHERE V."vid" = P."vid" AND P."bid" = 103; 31 Lubber 8 55.5
58 Rusty 10 35.0
Prenotazioni
vid bid giorno
3. Proiezione sulle colonne indicate
22 101 10/10/96
nella clausola SELECT:
58 103 11/12/96

vnome
Rusty

Lorenzo Putzu Laboratorio D’Informatica 33


Esercizi
1)Trovare i nomi dei velisti che abbiano prenotato almeno una barca
2)Trovare i colori delle barche prenotate da qualche velista di nome Lubber
3)Trovare i cognomi degli studenti che abbiano sostenuto almeno un esame
4)Trovare il nome degli insegnamenti dei quali qualche studentessa di nome Maria
Bianchi abbia sostenuto l'esame

Lorenzo Putzu Laboratorio D’Informatica 34


Soluzioni
1) SELECT V."vnome"
FROM "Velisti" V, "Prenotazioni" P
WHERE V."vid" = P."vid";

1) SELECT B."colore"
FROM "Velisti" V, "Prenotazioni" P,
"Barche" B
WHERE V."vid" = P."vid" AND
P."bid" = B."bid" AND
V."vnome" = 'Lubber';

Lorenzo Putzu Laboratorio D’Informatica 35


Soluzioni
3) SELECT S."Cognome"
FROM "Studenti" S, "Esami" E
WHERE S."Matricola" = E."Studente";
4) SELECT I."Nome"
FROM "Insegnamenti" I, "Esami" E,
"Studenti" S
WHERE I."Codice" = E."Esame" AND
E."Studente" = S."Matricola" AND
S."Nome" = 'Maria' AND
S."Cognome" = 'Bianchi' ;

Lorenzo Putzu Laboratorio D’Informatica 36


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 13
Basi Di Dati

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Una o più interrogazioni?
• Esempio: trovare le matricole di tutti gli studenti e i codici di tutti gli
insegnamenti. Interpretandola come una singola interrogazione, si potrebbe
scrivere:
SELECT S."Matricola", I."Codice"
FROM "Studenti" S, "Insegnamenti" I;
• Ma il risultato non è quello desiderato. Si tratta in realtà di due interrogazioni
indipendenti:
• Trovare le matricole di tutti gli studenti:
SELECT "Matricola" FROM "Studenti";
• Trovare i codici di tutti gli insegnamenti:
SELECT "Codice" FROM "Insegnamenti";

Lorenzo Putzu Laboratorio D’Informatica 2


Operatori insiemistici
• Dato che:
● ogni tabella è un insieme di righe
● il risultato di un'interrogazione è una tabella
• segue che:
● è possibile combinare in un'unica tabella i risultati di più interrogazioni,
usando gli operatori insiemistici di unione, intersezione e differenza, purché
tutte le interrogazioni producano tabelle con schemi identici (nome, dominio
e ordine delle colonne)
• Nota: le eventuali righe duplicate vengono eliminate automaticamente (non è
necessario aggiungere la clausola DISTINCT).
Lorenzo Putzu Laboratorio D’Informatica 3
Operatori insiemistici
• Esempio: trovare i codici dei velisti che hanno prenotato qualche barca rossa,
oppure qualche barca verde. Una soluzione già nota:
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND
(B."colore" = 'rosso' OR
B."colore" = 'verde');
• Una soluzione alternativa: si potrebbero estrarre separatamente (con due
interrogazioni distinte) i codici dei velisti che hanno prenotato qualche barca
rossa, poi i codici dei velisti che hanno prenotato qualche barca verde, e infine
eseguire l'unione tra i due insiemi di codici.

Lorenzo Putzu Laboratorio D’Informatica 4


Operatori insiemistici
• Se due tabelle (insiemi di righe), ottenute come risultato di due interrogazioni Q1
e Q2, hanno lo stesso schema (numero e domini delle colonne) e lo stesso ordine
tra le colonne, è possibile scrivere interrogazioni che combinino le loro righe
attraverso tre operatori insiemistici, con la seguente sintassi:
Q1 UNION Q2 ; (unione)
Q1 INTERSECT Q2 ; (intersezione)
Q1 EXCEPT Q2 ; (differenza)

Lorenzo Putzu Laboratorio D’Informatica 5


Operatori insiemistici
• Riprendendo l'esempio precedente, i codici dei velisti che hanno prenotato qualche
barca rossa oppure qualche barca verde si possono ottere come unione dei codici dei
velisti che hanno prenotato qualche barca rossa, e di quelli che hanno prenotato qualche
barca verde:
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND B."colore" = 'rosso'
UNION
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND B."colore" = 'verde';
• Nota: la prima interrogazione non deve terminare con ;

Lorenzo Putzu Laboratorio D’Informatica 6


Operatori insiemistici
• Esempio: trovare i codici dei velisti che hanno prenotato qualche barca rossa e
qualche barca verde. Senza usare operatori insiemistici, si può essere tentati di
scrivere:
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND
(B."colore" = 'rosso' AND
B."colore" = 'verde');
• Ma il significato di questa interrogazione non è quello desiderato; è invece:
"trovare i codici dei velisti che hanno prenotato qualche barca che è sia rossa che
verde" (e quindi il risultato sarà una tabella vuota).

Lorenzo Putzu Laboratorio D’Informatica 7


Operatori insiemistici
• Nell'esempio precedente, una soluzione corretta si ottiene tramite l'intersezione
tra i codici dei velisti che hanno prenotato qualche barca rossa, e i codici dei
velisti che hanno prenotato qualche barca verde:
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND B."colore" = 'rosso'
INTERSECT
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND B."colore" = 'verde';

Lorenzo Putzu Laboratorio D’Informatica 8


Operatori insiemistici
• Esempio: trovare i codici dei velisti che hanno prenotato qualche barca rossa, ma
non barche verdi
• Una possibile soluzione: sottrarre dall'insieme dei codici dei velisti che hanno
prenotato qualche barca rossa i codici di quelli che hanno prenotato qualche
barca verde:
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND B."colore" = 'rosso'
EXCEPT
SELECT P."vid"
FROM "Barche" B, "Prenotazioni" P
WHERE P."bid" = B."bid" AND B."colore" = 'verde';
Lorenzo Putzu Laboratorio D’Informatica 9
Esercizi
• Scrivere le seguenti interrogazioni con una singola istruzione SELECT, senza
usare operatori insiemistici:
1)Trovare nome e codice di tutti i velisti che abbiano esperienza pari a 10 o che
abbiano prenotato la barca 104
2)Trovare cognome e matricola di tutti gli studenti nati prima del 1/1/1990, o
che abbiano sostenuto l'esame avente codice AMI01

Lorenzo Putzu Laboratorio D’Informatica 10


Esercizi
• Scrivere le seguenti interrogazioni usando operatori insiemistici:
3)Trovare nome e codice di tutti i velisti che abbiano esperienza pari a 10 o che
abbiano prenotato la barca 104
4)Trovare cognome e matricola di tutti gli studenti nati prima del 1/1/1990, o che
abbiano sostenuto l'esame avente codice AMI01
5)Trovare i codici delle barche che siano state prenotate da qualche velista con
esperienza pari almeno a 8, e da nessun velista con età maggiore di 35 anni
6)Trovare i codici degli insegnamenti i cui esami siano stati sostenuti da qualche
studente nato prima del 1/1/1990, e da nessuno studente nato prima del
1/1/1985

Lorenzo Putzu Laboratorio D’Informatica 11


Soluzioni
1)SELECT DISTINCT V."vnome", V."vid"
FROM "Velisti" V, "Prenotazioni" P
WHERE V."esperienza" = 10 OR
(P."vid" = V."vid" AND P."bid" = 104);

1)SELECT DISTINCT S."Cognome", S."Matricola"


FROM "Studenti" S, "Esami" E
WHERE S."Data di nascita" < '1990-01-01' OR
(E."Studente" = S."Matricola" AND
E."Esame" = 'AMI01');

Lorenzo Putzu Laboratorio D’Informatica 12


Soluzioni
3)SELECT "vnome", "vid" FROM "Velisti"
WHERE "esperienza" = 10
UNION
SELECT V."vnome", V."vid"
FROM "Velisti" V, "Prenotazioni" P
WHERE P."vid" = V."vid" AND P."bid" = 104;
4)SELECT "Cognome", "Matricola"
FROM "Studenti"
WHERE "Data di nascita" < '1990-01-01'
UNION
SELECT S."Cognome", S."Matricola"
FROM "Studenti" S, "Esami" E
WHERE E."Studente" = S."Matricola" AND
E."Esame" = 'AMI01';

Lorenzo Putzu Laboratorio D’Informatica 13


Soluzioni
5)SELECT P."bid"
FROM "Prenotazioni" P, "Velisti" V
WHERE P."vid" = V."vid" AND
V."esperienza" >= 8
EXCEPT
SELECT P."bid"
FROM "Prenotazioni" P, "Velisti" V
WHERE P."vid" = V."vid" AND V."età" > 35;
6)SELECT E."Esame"
FROM "Esami" E, "Studenti" S
WHERE S."Matricola" = E."Studente" AND
S."Data di nascita" < '1990-01-01'
EXCEPT
SELECT E."Esame"
FROM "Esami" E, "Studenti" S
WHERE S."Matricola" = E."Studente" AND
S."Data di nascita" < '1985-01-01';

Lorenzo Putzu Laboratorio D’Informatica 14


Operatori insiemistici
e interrogazioni nidificate
• Nella clausola WHERE di un'interrogazione Q è possibile esprimere la condizione
che i valori di una o più colonne c1,...,cn debbano essere uguali a quelli di qualche
riga (o diversi da quelli di tutte le righe) di una tabella T' ottenuta come risultato
di un'altra interrogazione Q', purché T' contenga n colonne con gli stessi domini
di c1,...,cn (nello stesso ordine):
● SELECT ... FROM ...

WHERE ... c1,...,cN IN (Q') ;


● SELECT ... FROM ...

WHERE ... c1,...,cN NOT IN (Q') ;

Lorenzo Putzu Laboratorio D’Informatica 15


Operatori insiemistici
e interrogazioni nidificate
• Esempio: Trovare i nomi dei velisti che hanno prenotato la barca n. 103. Una
soluzione già nota:
SELECT V."vnome"
FROM "Velisti" V, "Prenotazioni" P
WHERE V."vid" = P."vid" AND P."bid" = 103;
• Una soluzione alternativa: selezionare "vnome" da "Velisti", se il valore di "vid"
appartiene all'insieme dei codici dei velisti che hanno prenotato la barca 103:
SELECT "vnome" FROM "Velisti"
WHERE "vid" IN (SELECT "vid"
FROM "Prenotazioni"
WHERE "bid" = 103);
Lorenzo Putzu Laboratorio D’Informatica 16
Operatori insiemistici
e interrogazioni nidificate
• Esempio: trovare i nomi dei velisti che non hanno prenotato la barca n. 103. Senza
usare IN/NOT IN si può essere tentati di scrivere:
SELECT V."vnome"
FROM "Velisti" V, "Prenotazioni" P
WHERE V."vid" = P."vid" AND P."bid" <> 103;
• Ma il significato reale di questa interrogazione SQL è "trovare i nomi dei velisti che
hanno prenotato anche barche diverse dalla n. 103". La soluzione corretta si può
ottenere con l'operatore NOT IN:
SELECT "vnome" FROM "Velisti"
WHERE "vid" NOT IN (SELECT "vid"
FROM "Prenotazioni"
WHERE "bid" = 103);

Lorenzo Putzu Laboratorio D’Informatica 17


Esercizi
1)Trovare i cognomi degli studenti che hanno sostenuto l'esame avente codice
AMI01
2)Trovare i nomi degli esami in cui qualche studente ha conseguito la
votazione di 30

Lorenzo Putzu Laboratorio D’Informatica 18


Soluzioni
1)SELECT "Cognome"
FROM "Studenti"
WHERE "Matricola" IN
(SELECT "Studente" FROM "Esami"
WHERE "Esame" = 'AMI01');
2)SELECT "Nome"
FROM "Insegnamenti"
WHERE "Codice" IN
(SELECT "Esame" FROM "Esami"
WHERE "Voto" = 30);

Lorenzo Putzu Laboratorio D’Informatica 19


Operatori insiemistici
e interrogazioni nidificate
• Nella clausola WHERE di un'interrogazione Q è possibile esprimere la condizione
che il valore di una colonna debba essere maggiore, minore, ecc. di qualcuno dei
valori, o di tutti i valori, contenuti in una tabella ottenuta come risultato di
un'altra interrogazione Q', avente una sola colonna con lo stesso dominio:
● SELECT ... FROM ...

WHERE ... "colonna" operatore-confronto ANY (Q') ;


● SELECT ... FROM ...

WHERE ... "colonna" operatore-confronto ALL (Q') ;


• dove operatore-confronto è uno degli operatori già noti:
• < <= = => = <>

Lorenzo Putzu Laboratorio D’Informatica 20


Esempio
• Trovare le matricole degli studenti che hanno ottenuto il voto più alto nell'esame
AMI01 (cioè, un voto maggiore o uguale a quello di tutti gli altri esami dello
stesso insegnamento):

SELECT "Studente" FROM "Esami"


WHERE "Esame"='AMI01' AND "Voto" >= ALL
(SELECT "Voto" FROM "Esami"
WHERE "Esame"='AMI01');

Lorenzo Putzu Laboratorio D’Informatica 21


Esempio
• Trovare tutti i dati sui velisti la cui esperienza è maggiore di quella di qualche
velista di nome Lubber:

SELECT *
FROM "Velisti"
WHERE "esperienza" > ANY
(SELECT "esperienza"
FROM "Velisti"
WHERE "vnome" = 'Lubber');

Lorenzo Putzu Laboratorio D’Informatica 22


Esercizi
• Scrivere le seguenti interrogazioni usando gli operatori ANY e ALL:
1)Trovare i codici dei velisti più esperti
2)Trovare nome ed età dei velisti più anziani
3)Trovare i cognomi degli studenti più giovani
4)Trovare le matricole degli studenti che non hanno ottenuto il voto
più basso nell'esame AMI01 (cioè, che hanno ottenuto un voto
maggiore rispetto a qualche altro studente)

Lorenzo Putzu Laboratorio D’Informatica 23


Soluzioni
1)SELECT "vid" FROM "Velisti"
WHERE "esperienza" >= ALL
(SELECT "esperienza" FROM "Velisti");
2)SELECT "vnome", "età" FROM "Velisti"
WHERE "età" >= ALL
(SELECT "età" FROM "Velisti");
3)SELECT "Cognome" FROM "Studenti"
WHERE "Data di nascita" >= ALL
(SELECT "Data di nascita" FROM "Studenti");
4)SELECT "Studente" FROM "Esami"
WHERE "Esame"='AMI01' AND E."Voto" > ANY
(SELECT "Voto" FROM "Esami"
WHERE "Esame" = 'AMI01');

Lorenzo Putzu Laboratorio D’Informatica 24


Operatori di aggregazione
● Consentono di esprimere interrogazioni che calcolano un valore aggregato:
– il numero di righe di una tabella che soddisfano una data condizione; esempi:

● trovare il numero di soci del circolo nautico


● trovare il numero dei soci aventi 35 anni
– la somma, la media, il minimo o il massimo dei valori di una colonna;
esempio:
trovare l'età media di tutti i velisti

● Restituiscono un numero, contenuto in una tabella con una sola colonna e una
sola riga

Lorenzo Putzu Laboratorio D’Informatica 25


Operatori di aggregazione
• Nella clausola SELECT:
● COUNT (*): conta le righe selezionate dall'interrogazione (se sono coinvolte

più tabelle, s'intendono le righe selezionate nel loro prodotto cartesiano)


● COUNT (DISTINCT "colonna", ...): conta le righe contenenti valori distinti delle

colonne indicate
● SUM ([DISTINCT] "colonna"): calcola la somma dei valori di colonna nella

righe selzionate (se è presente DISTINCT, i valori duplicati vengono contati una
sola volta)
● AVG ([DISTINCT] "colonna"): come sopra (valor medio)

● MAX ("colonna"): come sopra (valore più grande)

● MIN ("colonna"): come sopra (valore più piccolo)

Lorenzo Putzu Laboratorio D’Informatica 26


Esempi
● Trovare il numero dei velisti soci del circolo nautico:
SELECT COUNT (*) FROM "Velisti";
● Trovare l'età media di tutti i velisti:
SELECT AVG ("età") FROM "Velisti";
● Trovare il numero di valori distinti di esperienza dei velisti:
SELECT COUNT (DISTINCT "esperienza")
FROM "Velisti";
● Trovare l'età media dei velisti con esperienza 10:
SELECT AVG ("età") FROM "Velisti"
WHERE "esperienza" = 10;

Lorenzo Putzu Laboratorio D’Informatica 27


Operatori di aggregazione
e interrogazioni nidificate
• Esempio: trovare nome ed età dei velisti più anziani (cioè di quelli con età pari
all'età più grande tra tutti i velisti).
• Una soluzione con l'operatore ALL:
SELECT "vnome", "età " FROM "Velisti"
WHERE "età " >= ALL (SELECT "età " FROM "Velisti");
• Una soluzione alternativa con un operatore di aggregazione:
SELECT "vnome", "età " FROM "Velisti"
WHERE "età " = (SELECT MAX ("età ")
FROM "Velisti");

Lorenzo Putzu Laboratorio D’Informatica 28


Esercizi
• Scrivere le seguenti interrogazioni usando operatori di aggregazione:
1)Trovare i cognomi degli studenti più giovani
2)Trovare i nomi dei velisti più esperti
3)Trovare le matricole degli studenti che non hanno ottenuto il voto
più basso nell'esame AMI01

Lorenzo Putzu Laboratorio D’Informatica 29


Soluzioni
1)SELECT "Cognome" FROM "Studenti"
WHERE "Data di nascita" =
(SELECT MAX ("Data di nascita")
FROM "Studenti");
2)SELECT "vnome" FROM "Velisti"
WHERE "esperienza" =
(SELECT MAX ("esperienza")
FROM "Velisti");
3)SELECT "Studente" FROM "Esami"
WHERE "Esame" = 'AMI01' AND "Voto" >
(SELECT MIN ("Voto") FROM "Esami"
WHERE "Esame" = 'AMI01');

Lorenzo Putzu Laboratorio D’Informatica 30


Laboratorio d'Informatica
Corso di Laurea Magistrale in Ingegneria per
l'Ambiente e il Territorio
A.A. 2021/2022
Docente: Lorenzo Putzu

Lezione 14
Basi Di Dati

E' vietata la copia, la rielaborazione, la riproduzione in qualsiasi forma dei contenuti e immagini
presenti nelle lezioni. E' inoltre vietata la diffusione, la redistribuzione e la pubblicazione dei
contenuti e immagini, incluse le registrazioni delle videolezionicon qualsiasi modalità e mezzo non
autorizzate espressamente dall'autore o da Unica

Lorenzo Putzu Laboratorio D’Informatica 1


Il Modello E-R

Lorenzo Putzu Laboratorio D’Informatica 2


Modello Entità-Relazione (E-R)
● Entità
● Attributi
– dominio di un attributo

– attributi semplici e composti


– identificatori

● Relazioni (associazioni)
– grado

– vincoli di cardinalità

● Entità deboli

Lorenzo Putzu Laboratorio D’Informatica 3


Entità
• Insiemi di individui o di oggetti (concreti o astratti).
• Si indicano con rettangoli, identificati da un nome.
• Esempi:
● l'insieme degli impiegati dell'azienda
● l'insieme dei dipartimenti dell'azienda

Impiegato Dipartimento

Lorenzo Putzu Laboratorio D’Informatica 4


Attributi
• Sono caratteristiche possedute da ciascun elemento di un'entità. Per un
dato elemento, ogni attributo può assumere un solo valore appartenente
a un dato dominio.
• Esempio di possibili attributi dell'entità Impiegato:

Impiegato Data_nascita
CF
Stipendio
Nome_batt
Sesso
Cognome Città Via N_civico

Lorenzo Putzu Laboratorio D’Informatica 5


Attributi
• Più attributi legati da un nesso logico possono essere rappresentati come
un singolo attributo composto.
• Esempio: nome di un impiegato (inteso come insieme di nome di
battesimo e cognome), e indirizzo di residenza (nome della città, nome
della via e numero civico).

Impiegato
CF Data_nascita

Nome Sesso Indirizzo Stipendio

Nome_batt Cognome
Città Via N_civico

Lorenzo Putzu Laboratorio D’Informatica 6


Attributi
• Un sottoinsieme minimale di attributi i cui valori identificano univocamente gli elementi di
un'entità è detto identificatore.
• Esempio: per l'entità Impiegato l'identificatore è CF e si rappresentano come indicato in
figura.
• Un'entità può avere più di un identificatore, e ciascun identificatore può essere composto
da uno o più attributi.
Impiegato
CF Data_nascita

Nome Sesso Indirizzo Stipendio

Nome_batt Cognome
Città Via N_civico

Lorenzo Putzu Laboratorio D’Informatica 7


Altre entità e attributi dell'esempio
Progetto Dipartimento Sede

Nome Numero Nome Numero Nome_città

Persona_a_carico
Note: per le entità Progetto e Dipartimento
esistono due identificatori distinti. L'entità
Sesso
Persona_a_carico non ha invece un
Nome Data_nascita Parentela
identificatore.

Nome_batt Cognome

Lorenzo Putzu Laboratorio D’Informatica 8


Relazioni
• Alcune informazioni coinvolgono elementi di entità diverse. Esempi:
l'afferenza di un impiegato a un dipartimento, il direttore di un
dipartimento (uno degli impiegati), la città in cui un dipartimento ha sede.
Queste informazioni devono essere rappresentate da una relazione (o
associazione) tra le entità coinvolte.
• Di norma le relazioni coinvolgono solo due entità, e per questo sono dette
binarie. In casi particolari può essere necessario usare relazioni ternarie.
Relazioni di grado superiore sono molto rare.
• Esempio: il dipartimento di afferenza di ogni impiegato può essere
rappresentato come l'insieme delle coppie di elementi (i,d), tali che i ∈
Impiegato, d ∈ Dipartimento, e d corrisponde al dipartimento di afferenza
di i. Questa relazione binaria è un sottoinsieme del prodotto cartesiano
Impiegato×Dipartimento.

Lorenzo Putzu Laboratorio D’Informatica 9


Relazioni
• Rappresentazione grafica (diagramma di Venn) della relazione che indica
l'afferenza degli impiegati ai vari dipartimenti, denominata Lavora_per,
come insieme di coppie (impiegato, dipartimento). In questo esempio si
assume che gli impiegati i1 e i2 lavorino nel dipartimento d1, i3 nel
dipartimento d2, i4 e i5 nel dipartimento d3
Impiegato Dipartimento

i1 i2 i3 i4 i5 d1 d2 d3

i2 d1 i4 d3
Lavora_per i1 d1 i3 d2 i5 d3

Lorenzo Putzu Laboratorio D’Informatica 10


Relazioni
• Rappresentazione di una relazione tra due entità (relazione
binaria) nello schema E-R.

Impiegato Lavora_per Dipartimento

... ...

Lorenzo Putzu Laboratorio D’Informatica 11


Relazioni
• Altre relazioni nell'esempio considerato:
● il direttore di ogni dipartimento

● il supervisore di ogni impiegato (che è a sua volta un impiegato): esempio di

relazione binaria tra coppie di elementi di una stessa entità


● i familiari a carico di un impiegato

● ... (si veda di seguito lo schema E-R completo)

Lorenzo Putzu Laboratorio D’Informatica 12


Relazioni
• Anche le relazioni (intese come insiemi di oggetti) possono avere attributi.
Esempio: la data nella quale il direttore di un dipartimento ha preso servizio può
essere considerata un attributo di ciascuna coppia (direttore, dipartimento), cioè
di ciascun elemento della relazione corrispondente.

Impiegato

Data_inizio_direzione
Dirige

Dipartimento
Lorenzo Putzu Laboratorio D’Informatica 13
Relazioni (associazioni)
• Una relazione può anche sussistere tra elementi di una stessa entità. Tali
relazioni si dicono ricorsive. Ad esempio: il supervisore di un impiegato è
anch'esso un impiegato dell'azienda.
• Per chiarezza, nelle relazioni ricorsive è utile indicare esplicitamente il ruolo di
ogni elemento dell'entità corrispondente (per es., usando frecce per legare la
relazione alle entità).
Impiegato
è supervisore di
Impiegato i1 i2 i3 i4 i5

In questo esempio si usa la convenzione che la


Supervisore freccia vada dal supervisore all'impiegato sottoposto
è supervisionato da
Lorenzo Putzu Laboratorio D’Informatica 14
Vincoli di cardinalità
• Indicano eventuali vincoli (ricavati dall'analisi dei requisiti) sul numero di
elementi di ciascuna delle entità che partecipano a una data relazione. Sono
utili per la definizione dello schema logico relazionale della BD.
• Nel caso di una relazione binaria R, per ogni entità X coinvolta è necessario
indicare il numero minimo e massimo di elementi dell'altra entità con i quali
un singolo elemento di X può trovarsi nella relazione R.
• I valori di interesse sono: zero, uno, o più di uno (quest'ultimo è indicato con
il simbolo N).

Lorenzo Putzu Laboratorio D’Informatica 15


Vincoli di cardinalità
• Esempio: relazione Lavora_per tra Impiegato e Dipartimento:
● Un dato impiegato con quanti dipartimenti può trovarsi nella relazione

Lavora_per? Cioè, in quanti dipartimenti può lavorare un impiegato?


Minimo: 1; massimo: 1
● Un dato dipartimento con quanti impiegati può trovarsi nella relazione

Lavora_per? Cioè, quanti impiegati possono lavorare in un dipartimento?


Minimo: 1; massimo: N

Impiegato Lavora_per Dipartimento


(1,1) (1,N)

Lorenzo Putzu Laboratorio D’Informatica 16


Vincoli di cardinalità
• Specificano il numero minimo e massimo di istanze della
relazione a cui un’istanza dell’entità può partecipare
• (1,1) :obbligatoria, una sola volta
• (1,N) :obbligatoria, n volte
• (0,1) :opzionale, una sola volta
• (0,N) :opzionale , n volte

Lorenzo Putzu Laboratorio D’Informatica 17


Vincoli di cardinalità
• Si noti che i vincoli si possono stabilire correttamente solo se è ben
chiaro cosa rappresentano le diverse entità (analisi della realtà!)

Persona Residenza Città


(1,1) (1,N)

Persona Proprietà Automobili


(0,N) (0,1)

Persona Lavora Città


(0,N) (0,N)

Lorenzo Putzu Laboratorio D’Informatica 18


Vincoli di cardinalità
• Si noti che i vincoli si possono stabilire correttamente solo se è ben
chiaro cosa rappresentano le diverse entità (analisi della realtà!)

Studente Frequenta Corso


(1,N) (0,N)

Comune Ubicato Provincia


(1,1) (1,N)

Montagna Scalata Alpinista


(0,N) (1,N)

Lorenzo Putzu Laboratorio D’Informatica 19


Cardinalità delle relazioni ricorsive
• Può essere indicata in modo non ambiguo riferendosi al ruolo degli elementi in relazione
tra loro, sfruttando la notazione suggerita in precedenza. Esempio: la relazione
Supervisore tra coppie di elementi di Impiegato:
● un dato impiegato di quanti impiegati può essere il supervisore? minimo: 0;

massimo: N
● un dato impiegato quanti supervisori può avere?

minimo: 0 (per es., il direttore dell'azienda); massimo: 1

è supervisore di
Impiegato
(0,N)

(0,1)
Supervisore
è supervisionato da

Lorenzo Putzu Laboratorio D’Informatica 20


Entità deboli
• Un'entità X può non avere un identificatore tra i propri attributi, per esempio l'entità Persona_a_carico. Ciò è
ammissibile, purché:
● esista una relazione R tra X e un'altra entità Y dotata di un identificatore (per es., Y = Impiegato)
● la cardinalità minima e massima di X rispetto a R sia 1
• In questo caso ogni elemento di X può essere identificato univocamente dall'unione dell'identificatore di Y
(cioè, dall'unico elemento di Y ad esso associato: nell'esempio, il CF dell'impiegato) e di alcuni attributi di X
(nell'esempio: nome e data di nascita del familiare a carico). In particolare:
● X è detta entità debole
● Y è detta entità proprietaria
● R è detta relazione identificante
• Nota: ogni entità non debole è detta forte.

Lorenzo Putzu Laboratorio D’Informatica 21


Entità deboli
• Esempio: Persona_a_carico è un'entità debole, Familiare è la relazione identificante e Impiegato
è l'entità proprietaria. L'identificatore dell'entità debole è composto dagli attributi Nome e
Data_nascita di Persona_a_carico, e da quelli dell'indentificatore di Impiegato, cioè CF;
graficamente si indica come in figura.

Impiegato Familiare
(0,N) Parentela
... (1,1)

CF
Persona_a_carico

Nome
Data_nascita Sesso

Nome_batt Cognome
Lorenzo Putzu Laboratorio D’Informatica 22
Schema E-R completo dell’azienda Città
(1,N) (1,1)
Lavora su Progetto Gestione
Ore
(1,N)
(1,N) Sede
Nome Codice
(0,N) (0,1) (1,1) (1,N)
Direzione (1,N)
Supervisore Impiegato (1,N)
Dipartimento Sedi
Data
(0,1)
(1,1) (1,N)
Afferenza
Nome CF Nome Codice
Stipendio Sesso Data_nascita Indirizzo

Nome_batt Cognome
(0,N)
Via Città N_civico Data_nascita
Familiare
(1,1) Nome_batt
Persona_a_carico
Parentela Cognome
Nome
Lorenzo Putzu Laboratorio D’Informatica Sesso 23
Schema E-R completo del corso di laurea

(0,N) (0,N)
Studente Esame Insegnamento

Nome
Matricola CF Data_nascita Voto Data Titolo Codice CFU

Cognome

Nome_batt
Lorenzo Putzu Laboratorio D’Informatica 24
Progettazione logica
• La progettazione logica può essere eseguita a partire al modello E-R,
traducendo quest'ultimo in un modello logico attraverso una sequenza di tre
passi:
1. traduzione delle entità forti
2. traduzione delle entità deboli
3. traduzione delle relazioni
• Il passo 3 dipende dal tipo di ciascuna relazione

Lorenzo Putzu Laboratorio D’Informatica 25


Tipi di relazioni
• Esistono tre tipi di relazioni, definiti in funzione delle cardinalità
massime delle entità coinvolte. Nel caso di relazioni binarie:
● (..., 1), (..., 1): uno a uno

esempio: relazione Dirige


● (..., 1), (..., N): uno a molti

esempio: relazione Lavora_per


● (..., N), (..., N): molti a molti

esempio: relazione Lavora_su

Lorenzo Putzu Laboratorio D’Informatica 26


1. Traduzione delle entità forti
• A ogni entità forte E viene associata una tabella T.
• Ogni colonna di T corrisponde a uno degli attributi semplici di E, con
un dominio SQL appropriato.
• Se e ha un solo identificatore, la chiave primaria di T corrisponde a
tale identificatore.
• Se E ha più identificatori, uno solo di essi deve essere scelto come
chiave primaria di T; per ciascuno degli altri sarà opportuno definire
un vincolo di unicità.

Lorenzo Putzu Laboratorio D’Informatica 27


2. Traduzione delle entità deboli
• A ogni entità debole E si associa una tabella T.
• Ogni colonna di T corrisponde a uno degli attributi semplici di E.
• La chiave primaria di T corrisponde all'unione degli attributi che fanno
parte dell'identificatore di E, e di quelli che compongono la chiave
primaria dell'entità proprietaria; su questi ultimi si impone un vincolo
d'integrità referenziale (sono cioè chiavi esterne nella tabella T).

Lorenzo Putzu Laboratorio D’Informatica 28


3. Traduzione delle relazioni uno a uno

• Una relazione R di tipo uno a uno tra le entità E1 e E2, associate alle tabelle T1 e T2,
può essere tradotta in tre modi (di seguito si indicano con c1 e c2 le cardinalità
minime di E1 e E2 in R):
• aggiungendo a T1 le colonne corrispondenti agli eventuali attributi semplici di R e
alla chiave primaria di T2 (suggerito se c1 = 1 e c2 = 0);
• aggiungendo a T2 le colonne corrispondenti agli eventuali attributi semplici di R e
alla chiave primaria di T1 (suggerito se c1 = 0 e c2 = 1);
• costruendo una nuova tabella T, con colonne corrispondenti agli eventuali
attributi semplici di R e alle chiavi primarie di T1 e T2 (suggerito se c1 = c2 = 0);
una qualsiasi delle chiavi esterne sarà la chiave primaria di T.
• Se c1 = c2 = 1, una qualsiasi delle scelte 1) e 2) è adeguata. I criteri indicati hanno lo
scopo di evitare la presenza di colonne in T1 o in T2 il cui valore sia NULL in qualche
riga.
Lorenzo Putzu Laboratorio D’Informatica 29
3. Traduzione delle relazioni uno a molti

• Una relazione R di tipo uno a molti tra le entità E1 e E2 (assumendo che la


cardinalità massima di E1 in R sia 1 e quella di E2 sia N), associate alle tabelle T1 e
T2, può essere tradotta in due modi (di seguito si indica con c1 la cardinalità
minima di E1 in R):
● aggiungendo a T le colonne corrispondenti agli eventuali attributi semplici di
1
R, e alla chiave primaria di T2 (scelta suggerita se c1 = 1)
● costruendo una nuova tabella T, con colonne corrispondenti agli eventuali

attributi semplici di R, e alle chiavi primarie di T1 e T2 (scelta suggerita se c1 =


0, per evitare la presenza in T1 di colonne il cui valore sia NULL in qualche
riga); la chiave esterna riferita a E1 sarà anche la chiave primaria di T

Lorenzo Putzu Laboratorio D’Informatica 30


3. Traduzione delle relazioni molti a molti

• Una relazione R di tipo molti a molti tra le entità E1 e E2, associate alle tabelle T1 e
T2, si traduce costruendo una nuova tabella T, con colonne corrispondenti agli
eventuali attributi semplici di R, e alle chiavi primarie di T1 e T2.

• Entrambe le chiavi esterne costituiranno la chiave primaria della tabella T.

Lorenzo Putzu Laboratorio D’Informatica 31


Schema logico azienda
• Schema logico corrispondente allo schema E-R visto in precedenza, per semplicità non
verrà indicato il dominio delle colonne

• Tabelle:
● Impiegato (Nome_batt, Cognome, Sesso, Data_nascita, CF, Via, Città, N_civico, Stipendio, Dipartimento,
Supervisore)
● Dipartimento (Nome, Numero, Direttore, Data_inizio_direzione)
● Sede (Città)
● Progetto (Nome, Numero, Dipartimento, Sede)
● Persona_a_carico (Nome_batt, Cognome, Sesso, Data_nascita, Impiegato, Parentela)
● Sedi (Città, Dipartimento)
● Lavora_su (Impiegato, Progetto, Ore)

Lorenzo Putzu Laboratorio D’Informatica 32


Esempio: azienda
• Vincoli di chiave esterna:
● Dipartimento in Impiegato referenzia Numero in Dipartimento
● Supervisore in Impiegato referenzia CF in Impiegato
● Direttore in Dipartimento referenzia CF in Impiegato
● Dipartimento in Progetto referenzia Numero in Dipartimento
● Sede in Progetto referenzia Città in Sede
● Impiegato in Persona_a_carico referenzia CF in Impiegato
● Città in Sedi referenzia Città in Sede
● Dipartimento in Sedi referenzia Numero in Dipartimento
● Impiegato in Lavora_su referenzia CF in Impiegato
● Progetto in Lavora_su referenzia Numero in Progetto

Lorenzo Putzu Laboratorio D’Informatica 33


Schema logico corso di laurea
• Schema logico corrispondente allo schema E-R visto in precedenza, per semplicità non verrà indicato il
dominio delle colonne
• Tabelle:
● Studente (Nome_batt, Cognome, Matricola, Data_nascita, CF)
● Insegnamento (Titolo, Codice, CFU)
● Piano_di_studi (Studente, Insegnamento)
● Esami (Studente, Insegnamento, Data, Voto)
• Vincoli di chiave esterna:
● Studente in Piano_di_studi referenzia Matricola in Studente
● Insegnamento in Piano_di_studi referenzia Codice in Insegnamento
● Studente inEsami referenzia Matricola in Studente
● Insegnamento in Esami referenzia Codice in Insegnamento
Lorenzo Putzu Laboratorio D’Informatica 34
Esercizio
• Definire uno schema E-R per rappresentare le seguenti informazioni su una casa
discografica, e tradurlo in uno schema logico relazionale (indicando solo le tabelle
e i vincoli di chiave e di integrità referenziale).
• I dischi sono provvisti di un codice identificativo, un titolo e un anno d'incisione.
Ogni disco è composto da più brani, ognuno dei quali ha un titolo e una durata (in
secondi). Ogni disco può essere inciso da uno o più autori, ognuno dei quali ha un
nome, un cognome, una data di nascita, e un nome d’arte. Si assuma che non
esistano autori diversi con lo stesso nome d'arte, e che uno stesso disco non possa
contenere più brani con lo stesso titolo.

Lorenzo Putzu Laboratorio D’Informatica 35


Soluzione: schema E-R
• Nota: poiché uno stesso disco non può contenere più brani con lo stesso
titolo, è possibile rappresentare l'insieme dei brani di tutti i dischi come
un'entità debole, la cui entità proprietaria è Disco.
(1,1)
(1,N) Titolo
Contiene Brano
Durata
Disco

Codice Anno Inciso_da Autore


(1,N) (1,N)
Titolo
Nome_arte Nome Data_nascita

Nome_batt Cognome
Lorenzo Putzu Laboratorio D’Informatica 36
Soluzione: schema logico
• Tabelle:
● Disco (Codice, Titolo, Anno)
● Autore (Nome_batt, Cognome, Nome_arte, Data_nascita)
● Inciso_da (Autore, Disco)
● Brano (Titolo, Durata, Disco)

• Vincoli d'integrità referenziale:


● Autore in Inciso_da si riferisce a Nome_arte in Autore

● Disco in Inciso_da si riferisce a Codice in Disco

● Disco in Brano si riferisce a Codice in Disco

Lorenzo Putzu Laboratorio D’Informatica 37


Esercizio
• Rappresentare con uno schema E-R i seguenti dati su un ospedale
● L'ospedale è suddiviso in reparti identificati sia da un nome che da una sigla, e aventi un certo
numero di posti letto. In ogni reparto lavora un certo insieme di medici. Ogni medico lavora in un
solo reparto. Ogni reparto è diretto da uno dei medici che vi lavorano
● I pazienti possono essere ricoverati una o più volte, e hanno codice fiscale, numero della tessera
sanitaria, nome, cognome, data di nascita. Ogni ricovero è associato a un reparto, a una data
d'ingresso (uno stesso paziente può essere ricoverato non più di una volta in uno stesso giorno) e
a una data di dimissione (se già avvenuta), e a un medico responsabile
● I medici sono identificati da un numero di matricola e hanno cognome, nome, e una
specializzazione conseguita in una certa data
● Ogni paziente può essere sottoposto a uno o più visite, caratterizzate dalla data, dal tipo di visita
(per es., visuta cardiaca) e dai medici che l'hanno eseguita. Uno stesso tipo di visita può essere
eseguito su uno stesso paziente non più di una volta in uno stesso giorno

Lorenzo Putzu Laboratorio D’Informatica 38


Soluzione: schema E-R (1,1) Nome Nome_batt
(0,1)
Nome Dirige Cognome
Posti_letto Reparti Medici specializzazione
Lavora in data_spec
Sigla (1,N) (1,1)
(0,N) (0,N) Matricola

In_reparto Ricoveri Responsabile (0,N)


(1,1) (1,1)

data_ingresso (1,1) data_dimissione Eseguita_da

Degenza
CF (1,N)

tessera_SSN (1,N) (0,N) (1,1) Tipo


data_nascita Pazienti Controllo Visite
Data
Cognome
Nome_batt Nome
Lorenzo Putzu Laboratorio D’Informatica 39
Soluzione: schema logico
• Tabelle:
● Reparti (Sigla, Nome, Posti_letto, Direttore)

● Medici (Matricola, Nome_batt, Cognome, Specializzazione, Data_spec,

Reparto)
● Pazienti (Nome_batt, Cognome, CF, Tessera_SSN, Data_nascita)

● Ricoveri (Paziente, Reparto, Responsabile, Data_ingresso, Data_dimissione)

● Visite (Data, Tipo, Paziente)

● Eseguita_da (Data, Tipo, Paziente, Medico)

Lorenzo Putzu Laboratorio D’Informatica 40


Soluzione: schema logico
• Vincoli d'integrità referenziale:
● Direttore in Reparti referenzia Matricola in Medici
● Reparto in Medici referenzia Sigla in Reparti
● Paziente in Ricovero referenzia CF in Pazienti
● Reparto in Ricovero referenzia Sigla in Reparti
● Responsabile in Ricovero referenzia Matricola in Medici
● Paziente in Visita referenzia CF in Pazienti
● Data in Eseguita_da referenzia Data in Visite
● Tipo in Eseguita_da referenzia Tipo in Visite
● Paziente in Eseguita_da referenzia Paziente in Visite
● Medico in Eseguita_da referenzia Matricola in Medici

Lorenzo Putzu Laboratorio D’Informatica 41

Potrebbero piacerti anche