Sei sulla pagina 1di 98

Impara a Programmare in Python

Corso Base di Python 3

By MIKE
Corso Base di Python 3
01: Introduzione e Installazione di Python 3.6

Dedico questa serie a tutti coloro che si stanno avvicinando per la prima volta al mondo
di Python, in quanto tratteremo fondamentalmente le basi del linguaggio e le metodologie
necessarie ad imparare a programmare in Python, utilizzando una terminologia semplice e
adatta proprio a tutti.

La prima domanda che mi viene posta quando parlo alla gente di Python e delle sue
mille virtù è: perché scegliere proprio questo linguaggio? Ad ogni conferenza o raduno, il
nome Python esce sempre fuori, accompagnato da acclamazioni calorose. Per
rispondere a questa domanda possiamo quindi dare uno sguardo alla pagina Wikipedia
del suo fondatore, l'olandese Guido Van Rossum

Come possiamo leggere, nel 1999 Van Rossum presentò un progetto chiamato
"Programmazione per tutti" al DARPA, ovvero l'agenzia americana per i progetti di ricerca
avanzata per la difesa, descrivendo Python come:

 semplice, intuitivo e potente


 open source
 facilmente comprensibile e con tempi di sviluppo brevi

Col tempo Python è cresciuto, arrivando alla terza versione, diventando addirittura il
linguaggio di programmazione più popolare per svariati anni di fila, e attorno a lui è
cresciuta una gigantesca comunità di entusiasti e professionisti da ogni parte del
mondo! Questo anche perché grazie al suo parco librerie sconfinato, con la
programmazione Python è possibile fare davvero di tutto, ad esempio sistemi di
automazione, analisi del mercato finanziario e altre grosse moli di dati, creazione di
applicazioni, siti web e tanto tanto altro... e sopratutto è possibile fare tutto questo molto
velocemente e in maniera divertente!

Che vi troviate su un Mac, un computer con Windows o Linux poco importa: Python è
infatti pienamente supportato da tutti questi sistemi operativi. Per quanto io utilizzi in realtà
Linux come sistema operativo, almeno nei primi video di questa serie utilizzerò Windows
10, in modo da semplificare la vita a quelli di voi che utilizzano questo sistema.

Pronti a procedere? per prima cosa è necessario scaricare il pacchetto di installazione di


Python. Potete scaricarlo gratis dal sito ufficiale della Python Software Foundation.

Cliccate dunque su Download Python 3.7 e una volta scaricato il file, installatelo. Ora
disponete sul vostro computer di tutto il necessario per intraprendere questa fantastica
esplorazione di uno dei linguaggi più potenti di sempre. Cliccate su START e cercate
IDLE, e una volta trovato aprite questo programma. Questo interprete dei comandi si
chiama Shell Interattiva, ed è l'ambiente con cui prenderemo familiarità utilizzandolo passo
dopo passo per imparare costruendo.
Ricapitolando:

 Python è un linguaggio semplice, intuitivo, ed estremamente potente


 Python è gratuito e supportato da tutti i sistemi operativi più utilizzati
 Attualmente la versione consigliata è la 3
 Grazie alle sue librerie, l'unico limite a ció che potete fare è dettato dalla vostra
fantasia
02: IDLE e Operazioni Numeriche

Benvenuti alla seconda puntata della serie di tutorial su Python 3.7! In questo episodio
daremo un'occhiata al funzionamento di IDLE e parleremo di Operazioni Numeriche con
Python 3.7.

Iniziamo subito! cliccate su start, cercate IDLE e apritela.

Sarà proprio IDLE(Integrated DeveLopment Environment o Integrated Development and


Learning Environment) l'ambiente che utilizzeremo durante tutto questo corso introduttivo,
ed è bene quindi che ci facciate amicizia al più presto!

La prima cosa che è importanti dire al riguardo di IDLE è che è costituita da due parti: una
shell interattiva, che è la prima parte che vi si presenta all'avvio, ed un editor testuale: per
aprire quest'ultimo cliccate su FILE / NEW FILE.

Per quanto all'aspetto possano apparire simili, queste due parti sono pensate per due
scopi differenti tra di loro.

La shell interattiva o interprete dei comandi, esegue le istruzioni una alla volta, riga per
riga, ed è pensata oltre che per effettuare semplici calcolazioni, per sperimentare ed
imparare cosa fanno le varie istruzioni di Python.

Scrivete:

print('Hello World!')

Non appena daremo INVIO, l'istruzione verrà processata e all'istante ci verrà restituito un
risultato:

'Hello World!'

In questo caso l'istruzione print ci restituisce il famoso Hello World, che è


tradizionalmente il primo programma che viene lanciato in ciascun linguaggio di
programmazione: in Python basta una riga, ma vedeste in altri linguaggi quante righe puó
richiedere...

L'editor testuale invece, è un ambiente pensato e realizzato per la costruzione di veri e


propri programmi strutturati. Ci sono tanti editor testuali pensati per Python o comunque
compatibili... per citarne alcuni Pycharm, Atom e Sublime Text. Per quanto abbiate la mia
completa benedizione qualora decidiate di provare uno di questi editor, in questa serie io
useró comunque l'editor integrato nell'installazione di Python 3.6, perché ha comunque
tutto ció di cui avremo bisogno.

In questo secondo capitolo ci concentreremo interamente sulla shell interattiva, per ora
potete quindi chiudere l'editor testuale.
Essendo pensata per sperimentare e effettuare semplici calcoli, con la shell di Python
possiamo effettuare Operazioni Numeriche. In Python queste sono dette Espressioni, e
sono formate da Valori e Operatori.

In questo caso chiaramente i 2 sono i valori mentre il + è l'operatore:

>>> 2 + 2
4

Lo stesso discorso vale chiaramente per le sottrazioni:

>>> 4 - 2
2

L'operatore per la divisione è lo slash avanti, quindi per fare 9 diviso 3 scriviamo:

>>> 9 / 3
3.0

L'operatore per la moltiplicazione è invece l'asterisco, quindi ad esempio 3 per 3 diventa:

>>> 3 * 3
9

Fate attenzione a non confondere questo l'operatore * con una x a meno che non stiate
andando a caccia di errori! 3 x 3 ci restituisce infatti un errore di sintassi

>>> 3 x 3
SyntaxError: invalid syntax

In caso di espressioni numeriche più complesse, l'ordine di esecuzione segue lo standard


matematico moltiplicazioni e divisioni per prime, con addizioni e sottrazioni a
seguire. Quindi ad esempio:

>>> 2 + 3 * 3
11

ci restituisce 11 perché la prima operazione ad essere stata svolta è la moltiplicazione 3 *


3. Se avete bisogno di stabilire una priorità di esecuzione personalizzata, seguendo lo
standard matematico, anche con Python si utilizzano le parentesi. La stessa
espressione di prima, utilizzando le parentesi potrebbe ad esempio diventare:

>>> (2 + 3) * 3
15
dandoci come risultato 15, perché stavolta la prima operazione ad essere stata svolta è la
somma (2 + 3).

In questi primi esempi abbiamo usato valori appartenenti al primo tipo di dato di Python:
l'Intero, o Integer.

I numeri non interi o in virgola mobile sono invece chiamati Float. Un esempio di Float è il
Pi Greco, che come sapete è approssimato a 3.14. Potete crearli utilizzando un punto al
posto della virgola(3.14 invece di 3,14), così come ottenete un Float effettuando divisioni
tra numeri interi, com'è successo nell'esempio precedente con 9 / 3, che ha restituito 3.0
Supponiamo di avere una variabile x e di assegnarle il valore 47;

>>> x = 47

Mediante la funzione type(), la shell interattiva ci consente di vedere che tipo di dato è
contenuto al suo interno:

>>> type(x)
class 'int'
Chiaramente ci riferisce che si tratta di un intero! Ma proviamo ora a cambiare il valore da
47 a 47.0

>>> x = 47.0

Controlliamo ora ancora una volta il tipo di valore mediante la funzione type():

>>> type(x)
class 'float'

Et voilat! ora ci troviamo proprio un Float.

Oltre alle quattro operazioni fondamentali, Python vi semplifica il lavoro coi numeri
permettendovi di effettuare calcoli esponenziali, quozienti e resti, ciascuno con un
operatore specifico. Per effettuare un calcolo esponenziale usiamo come operatore due
asterischi consecutivi: ad esempio 5 elevato 3 diventa:

>>> 5 ** 3
125

Per ottenere un quoziente usiamo un operatore detto Floor Division, rappresenato da un


doppio slash avanti, ad esempio il quoziente di 30 / 7 diventa:

>>> 30 // 7
4
E infine possiamo ottenere il resto di una divisione utilizzando un operatore chiamato
Modulo, rappresentato dal simbolo della percentuale, ad esempio il resto di 30 / 7 si
ottiene con:

>>>30 % 7
2

Ricapitolando:

 IDLE è composta da due parti: la Shell Interattiva e l'Editor Testuale


 La Shell Interattiva esegue le istruzioni riga per riga ed è pensata per calcolazioni
semplici
 L'Editor Testuale è l'ambiente dove vengono creati i programmi strutturati
 Possiamo decidere la priorità di esecuzione in un'espressione tramite le parentesi ()
 I numeri in virgola mobile, detti Float, si ottengono aggiungendo un punto (47 è un
intero, ma 47.0 è un Float)

Operatori Numerici:

 addizione: +
 sottrazione: -
 divisione: /
 moltiplicazione: *
 esponente: **
 quoziente: //
 resto: %
03: Variabili e Stringhe

In questa nuova lezione introdurremo il concetto di Variabile, e un nuovo tipo di dato


chiamato Stringa, che ci consente di utilizzare del testo nei nostri programmi.

Per cominciare, aprite la nostra ormai familiare Shell Interattiva IDLE e iniziamo subito!

Vi siete mai chiesti come facciano i vostri programmi a salvare valori nella memoria del
Computer e ad accedervi poi in un secondo momento? Questo avviene in parte per mezzo
di quelle che chiamiamo Variabili.

Potete pensare a una variabile come ad una scatola che puó contenere un singolo valore,
e l'inserimento del valore in questa "scatola", avviene tramite un processo
chiamato assegnazione.

Nella shell interattiva scrivete:

>>> spam = 21

Con questo comando è come se aveste creato una scatola nella memoria del computer,
chiamandola spam. All'interno di questa scatola chiamata SPAM avete quindi depositato il
numero 21.

Fino a che lascerete la scatola li, senza metterci nient'altro dentro, potrete riaccedere al
valore assegnatole utilizzando il nome della scatola, quindi della variabile, come
collegamento al valore contenuto. Provate a scrivere il nome della variabile sulla Shell
Interattiva, e date invio:

>>> spam
21

Sorpresa! ecco che ci riappare il numero che avevamo appena depositato.

Una volta che avete richiamato questa variabile, è possibile fare qualsiasi tipo di calcolo
sul valore ad essa assegnato, ad esempio:

>>> spam * 3
63

L'operazione spam * 3 ci restituisce il numero 63, che è il triplo del valore contenuto in
spam.

In Python ci sono delle regole per quanto riguarda i nomi che è possibile dare alle variabili:
questi infatti possono contenere solo lettere, numeri e underscore, ovvero il trattino
basso, ma non possono iniziare con un numero! Venire meno a queste regole comporta la
comparsa di errori di sintassi.
Proviamo a creare una variabile e ad usare come primo carattere del nome un carattere
numerico:

>>> 1esempio = 2
File "stdin", line 1
1esempio = 2
^
SyntaxError: invalid syntax

Per lo stesso motivo sopracitato, otteniamo un errore anche in questo caso:

>>> esem-pio = 5
File "", line 1
SyntaxError: can't assign to operator

Tenete a mente che di norma è importante dare alle variabili nomi specifici, che ci
permettano di identificarne lo scopo all'interno del programma, facilitandone la lettura e la
semplicità complessiva.

Mentre studiate Python noterete che alle variabili vengono spesso assegnati nomi come
"spam", "eggs" oppure "bacon", per tributo a un famoso scatch di Monty Python, la serie
inglese che ispiró Van Rossum mentre era alla ricerca di un nome da dare al suo
linguaggio di programmazione. Se siete interessati a qualche altra curiosità riguardante il
linguaggio, potete dare uno sguardo a questo video Cinque Fatti e Curiosità su Python

Una delle caratteristiche più potenti delle variabili in Python è che potete riassegnarle
quante volte vi pare. Se fin'ora state immaginando le variabili come scatole a cui viene
dato un nome e su cui è possibile inserire un valore, potete anche immaginare che a
seconda del caso ci sia bisogno di inserirvi degli altri valori, giusto? Il discorso è in realtà
un pó più complesso di così ma ei, un passo alla volta no?

Un'altra caratteristiche molto importante che distingue Python da molti altri linguaggi di
programmazione, è che le variabili non sono di un tipo specifico: potete quindi assegnar
loro qualsiasi classe di valore vogliate.

Facciamo un esempio. Utilizzando la funzione integrata type() andiamo a vedere che tipo
di valore è presente nella variabile spam, che abbiamo assegnato prima:

>>> type(spam)
class 'int'

Si tratta chiaramente di un intero.

Proviamo ora ad assegnarle un valore appartenente al secondo tipo di dato di cui abbiamo
parlato fin'ora, ovvero un numero in virgola mobile...

>>> spam = 3.14


Andiamo ora a ricontrollare:

>>> type(spam)
class 'float'

Avendole assegnato il Pi Greco, ora a spam è associato un Float!

Come accennato in precedenza, andiamo ora ad introdurre un nuovo tipo di dato,


le Stringhe: queste non sono altro che valori di tipo testuale, quindi un insieme di
caratteri(numeri e simboli compresi) inseriti tra apici o doppi apici.

Come esempio, creiamo una variabile chiamata frase e inseriamoci dentro la stringa 'Una
volta imparato, Python si dimostra estremamente versatile' racchiusa tra singoli apici:

>>> frase = 'Una volta imparato, Python si dimostra estremamente


versatile'

se ora andiamo ad effettuare un controllo con la funzione type()... notiamo che la classe di
dato contenuta nella variabile frase è appunto una stringa...

>>> type(frase)
class 'str'

Creiamo ora una seconda variabile chiamata frase2 e inseriamoci dentro la stringa
"Python è in assoluto il miglior linguaggio per chi sta iniziando a programmare", ma
stavolta includiamola tra doppi apici.

>>> frase2 = "Python è in assoluto il miglior linguaggio per chi sta


iniziando a programmare"
proviamo a richiamarne il valore sulla Shell...

>>> frase2
'Python è in assoluto il miglior linguaggio per chi sta iniziando a
programmare'

Ma... come mai anche questa stringa ci viene restituita tra singoli apici quando noi
l'abbiamo scritta usando invece doppi apici? Questo semplicemente perché Python è stato
ideato in questa maniera, le stringhe vengono sempre restituite tra singoli apici.
Prendete nota di ció, e procediamo.

Per rigor di logica, ci sono alcuni caratteri che non possono essere inclusi direttamente
nelle stringhe, come ad esempio doppi apici in una stringa definita usando propri questi. In
questo caso ci troveremo quindi impossibilitati a fare ad esempio delle citazioni:

>>> "e Dante scrisse: "Nel mezzo del cammin di nostra vita...""
File "", line 1
"e Dante scrisse: "Nel mezzo del cammin di nostra vita...""
^
SyntaxError: invalid syntax

Per Python, è come se avessimo interrotto la stringa prima della sua stessa fine, e questo
fa si che ci restituisca un errore.

Per ovviare a questo problema possiamo utilizzare gli apici singoli per definire la stringa,
oppure utilizzare un backslash prima dei caratteri "scomodi". Riscriviamo ora la stessa
stringa di prima, ma impiegando i backslash:

>>> "e Dante scrisse: \"Nel mezzo del cammin di nostra vita...\""
'e Dante scrisse: "Nel mezzo del cammin di nostra vita..."'

Le stringhe possono inoltre essere concatenate tra di loro per ottenere delle "fusioni" di
testo:

>>> eggs = 'Meglio un uovo oggi...'


>>> bacon = 'o una gallina domani?'
>>> eggs + bacon
'Meglio un uovo oggi...o una gallina domani?'

Come notate gli spazi non sono inclusi automaticamente, a quello dovrete pensare voi!

>>> bacon = ' o una gallina domani?'


>>> eggs + bacon
'Meglio un uovo oggi... o una gallina domani?'

Ricapitolando:

 Le Variabili ci permettono di salvare dei valori in memoria per riutilizzarli in futuro


 La Funzione type() ci permette di conoscere il tipo di valore presente in una
variabile
 Le Stringhe sono un tipo di dato, formato da caratteri testuali(numeri e simboli
inclusi)
 Una Stringa viene definita tramite l'utilizzo di apici, singoli oppure doppi
 I caratteri "scomodi" possono essere inseriti comunque in una stringa tramite uno \
04: Conversioni di Tipo, Print(), Input() e Primo Programma

Benvenuti a questa quarta lezione della serie di lezioni dedicate alle basi di Python 3.6

In questo episodio parleremo di conversioni tra tipi diversi di dati e di due delle funzioni
integrate in Python più utilizzate, la funzione print() e la funzione input().

Una volta spiegati questi concetti scriveremo finalmente il nostro primo programma in
Python 3.6, utilizzando l'editor testuale integrato in IDLE.

Fin'oro abbiamo introdotto tre tipi di dato: Integer, Float e Stringhe: non abbiamo peró
spiegato come fare ad combinare questi tipi di dato differenti tra di loro. Come fare ad
esempio a combinare un numero intero con una stringa? magari state pensando di
utilizzare un operatore come il +, e in questo caso ci siete andati vicini... ma non è così
immediato!

Facciamo delle prove. Definiamo una variabile età e assegnamole un numero intero:

>>> età = 24

Definiamo ora un'altra variabile e assegnamole una stringa:

>>> testo = 'La mia età è... '

Proviamo ora a combinare età e testo e vediamo cosa succede!

>>> età + testo


Traceback (most recent call last):
File "stdin", line 1, in
TypeError: unsupported operand type(s) for +: 'int' and 'str'

come forse alcuni di voi avranno sospettato, la Shell Interattiva ci restituisce un errore.

Python sa che state cercando di effettuare una somma tra tipi di dato diversi, e vi avverte
che l'operatore + non è compatibile per somme tra interi e stringhe. In sostanza vi avverte
che non può effettuare la conversione necessaria ad effettuare la somma, a meno che non
siate voi a chiederglielo in maniera esplicita.

Come chiedere quindi a Python di effettuare una conversione? Per fare questo esistono
delle funzioni integrate che fanno la conversione per noi. Per convertire un intero in
stringa usiamo la funzione str() Come per tutte le funzioni, le passiamo quello che viene
chiamato parametro tra le parentesi, nel nostro caso il parametro sarà la variabile età:

>>> str(età) + testo


'La mia età è... 24'
Analizziamo ora il caso opposto, ovvero il caso in cui abbiamo una stringa composta solo
da simboli numerici, e vogliamo convertirla in numero intero per usarla così in dei calcoli
matematici. Creiamo una variabile chiamata arance_per_sacco e assegniamole una
stringa composta da caratteri numerici, in questo caso un 27 magari:

>>> arance_per_sacco = '27'

Come fare ora ad ottenere il numero totale di arance presenti in tre sacchi? Guardate cosa
succede se proviamo a moltiplicare la variabile per 3:

>>> arance_per_sacco * 3
'272727'

per quanto buone, duecentosettantaduemilasettecentoventisette arance sono davvero


troppe! La funzione che utilizzeremo in questo caso è, come è possibile immaginare per
logica, la funzione int(). Facciamo quindi...

>>> int(arance_per_sacco) * 3
81

ed ecco svelato il nostro quesito matematico, le arance sono 81.

In maniera molto simile potete ottenere un Float tramite la funzione float().

Volendo convertire la variabile età del primo esempio facciamo:

>>> float(età)
24.0

Bene, è arrivato il momento di introdurre quella che è forse la funzione più famosa nel
regno di Python, la funzione print(). Ciò che print() fa è mostrarci in output qualsiasi cosa
le passiamo...

>>> print(str(33)+ ' trentini entrarono a Trento... passando per la


funzione print :) ')
'33 trentini entrarono a Trento... passando per la funzione print :) '

Per andare a capo si utilizza il carattere newline, ovvero \n, in questo modo:

>>> print(' Prima riga \n Seconda riga \n ecc ecc...')


'Prima riga
Seconda riga
ecc ecc...'
Oppure potete direttamente effettuare un print multilinea utilizzando 3 apici, in questo
modo:

>>> print('''prima linea


seconda linea
terza linea...''')
'prima linea
seconda linea
terza linea...'

Print viene usata davvero ovunque, è raro trovare uno script in cui non sia presente
almeno una volta. Faremo degli esempi più complessi man mano che introdurremo nuovi
concetti.

La funzione input() invece ci serve per l'inserimento di dati da parte dell'utente in


esecuzione: questo ci permette di rendere le cose estremamente interattive; ció che
inserirete tramite input() verrà passato a Python sotto forma di stringa. Ad esempio,
definiamo una variabile X ed assegnamole un valore introdotto tramite la funzione input():

>>> X = input()
23

Come possiamo verificare con type(): Definiamo una variabile X ed assegnamole un


valore introdotto tramite la funzione input():

>>> type(X)
class 'str'

Anche se abbiamo inserito apparentemente un numero, questo viene assegnato alla


variabile sotto forma di stringa.

Molto bene gente! entriamo nel cuore della lezione con la scrittura del nostro primo
programma! Per fare questo avremo bisogno dell'editor testuale di cui abbiamo parlato in
uno dei video precedenti, quindi cliccate su file/new file per aprirlo. Nota: per fare in modo
che il codice sull'editor testuale venga eseguito e passato alla Shell, dovete prima salvarlo
come file. Cliccate su file/save as; in questo caso lo salveremo come "esempio". I
programmi scritti in Python sono file di testo salvati con l'estensione py, quindi nel nostro
caso il file salvato sarà esempio.py.

print('Ciao programmatore! Benvenuto nel tuo primo programma in Python!


Come ti chiami?')
nome = input()
print(nome + '... e vuoi imparare a usare Python? ottima scelta!')
età = input('Quanti anni hai? ')
print(età + ' anni. Bene, il giorno in cui ne compirai ' + str(int(età) +
1) + ' ti farò gli auguri!')
Anzitutto salta all'occhio che abbiamo definito due variabili, nome ed età, in cui il
programma andrà ad assegnare il valore che inseriremo tramite la funzione input(). Come
vedete ho impostato input in due modi diversi: per la variabile nome non ho inserito alcuna
frase tra le parentesi di input(), al contrario di età in cui tra le parentesi ho scritto invece
'Quanti anni hai?' Questo breve messaggio comparirà durante l'inserimento dei valori nella
variabile. Come potete notare per la variabile nome ho incluso un "Come ti chiami?" nel
print() precedente. Entrambi le modalità sono corrette, utili e preferibili a seconda del caso
specifico in cui vi trovate. Nell'ultimo print() convertiamo età in intero in modo da poterci
sommare 1, e poi riconvertiamo in stringa in modo da poterlo integrare nel messaggio.

Finalmente: andiamo su run/run module per eseguire il programma. Anzitutto viene


eseguita la prima funzione print(), che ci restituisce la frase:

>>> 'Ciao programmatore! Benvenuto nel tuo primo programma in Python!


Come ti chiami?'

Ora sta venendo processata la funzione input, quindi il programma si aspetta da noi un
valore... inseriamo il nostro nome...

>>> 'Ciao programmatore! Benvenuto nel tuo primo programma in Python!


Come ti chiami?'
Mike

Entra in gioco un'altra funzione print(), che combina stavolta anche il nostro nome...

>>> 'Ciao programmatore! Benvenuto nel tuo primo programma in Python!


Come ti chiami?'
Mike
'Mike... e vuoi imparare a usare Python? ottima scelta!'

Quindi ancora un'altra chiamata input, stavolta che ci chiede da se quanti anni abbiamo,
rispondiamo!

>>> 'Ciao programmatore! Benvenuto nel tuo primo programma in Python!


Come ti chiami?'
Mike
'Mike... e vuoi imparare a usare Python? ottima scelta!'
'Quanti anni hai?'
24

E quindi l'ultima print, leggermente più sofisticata:

>>> 'Ciao programmatore! Benvenuto nel tuo primo programma in Python!


Come ti chiami?'
Mike
'Mike... e vuoi imparare a usare Python? ottima scelta!'
'Quanti anni hai?'
24
'24 anni. Bene, il giorno in cui ne compirai 25 ti faró gli auguri!'

Ricapitolando:

 Provare a combinare tipi di dato diversi tra loro porta spesso alla comparsa di errori
 Per evitare questi errori dobbiamo spesso effettuare delle conversioni
 Per effettuare conversioni usiamo le funzioni str(), int(), e float(), a cui passiamo il
valore o la variabile da convertire
 La funzione print() ci mostra in output qualsiasi cosa le passiamo, e puó essere
impostata per output multiriga
 La funzione input() ci permette di inserire e assegnare valori mentre il programma è
in esecuzione
05: Diagrammi Di Flusso, Logica Booleana e Operatori di Comparazione

Benvenuti alla quinta lezione della serie di Tutorial Python sulle Basi del Linguaggio!

In questo episodio introdurremo il concetto di Algoritmo e quello di Diagramma di


Flusso, spiegheremo gli Operatori di Comparazione di Python e tratteremo le basi
della Logica Booleana.

Nella guida precedente abbiamo scritto il nostro primo programma; chiaramente


trattandosi del primo programma della serie, il livello di complessità era piuttosto basso, e
l'ordine di esecuzione delle istruzioni piuttosto lineare. Normalmente dietro la realizzazione
di ciascun programma è sempre presente una fetta sostanziosa di logica.

Vengono delineati uno o più algoritmi, che sono, citando la pagina Wikipedia
dedicata "procedimenti per risolvere un determinato problema attraverso un numero finito
di passi elementari."

Un algoritmo tavolta puó essere molto complesso: in questi casi, per rappresentarne il
flusso di esecuzione e controllo da un punto di vista visivo, si utilizzano i Diagrammi di
Flusso. Un programmatore si rivolgerà spesso all'utilizzo dei diagrammi di flusso per poter
delineare e visualizzare in maniera logica ed esaustiva cosa il suo programma fa e quale
strategia adottare nella fase di scrittura vera e propria. In sintesi puoi pensare a questi
diagrammi come a una sorta di mappa che ti guida alla comprensione logica del tuo
problema, e quindi del tuo programma.

Uno degli esempi da manuale che viene spesso insegnato quando si inizia a parlare di
Diagrammi di Flusso è l'esempio del giorno di pioggia, ovvero si va a delineare quali
possibili azioni razionali si possano prendere qualora fuori stia piovendo e si voglia restare
asciutti! Andiamo ad analizzare questo scenario e proviamo a stilare i passi di un possibile
algoritmo:

Sta piovendo?
Se si, sta piovendo, ma disponiamo di un ombrello, possiamo decidere di
uscire di casa e affrontare le intemperie;
Se si, sta piovendo, ma non disponiamo di un ombrello, allora sarebbe
meglio restare in casa e aspettare che la pioggia passi, magari
controllando di tanto in tanto;
Se invece non sta piovendo possiamo uscire tranquillamente.

Per quanto la situazione presa ad esempio sia piuttosto semplice, ci rendiamo conto che
analizzarne logicamente tutti questi aspetti a voce potrebbe risultare confusionale, ed è
proprio qui che entrano quindi in gioco proprio i diagrammi di flusso. Le operazioni da
compiere sono rappresentate mediante figure geometriche(rettangoli, rombi etc...), e
ciascuna di esse ha uno scopo preciso.

Andiamo a dare un'occhiata a un possibile Diagramma di Flusso per l'esempio di cui


abbiamo parlato:
Per leggere questo diagramma si parte dal punto di inizio rappresentato da un'ellisse, si
seguono le frecce fino a che non si arriva alla fine dello schema, anch'esso rappresentato
come ellisse, e si possono prendere strade diverse a seconda del verificarsi o meno di
condizioni diverse:
e: queste sono racchiuse all'interno di rombi, mentre le azioni da
compiere sono racchiuse in rettangoli. Mediante questo schema possiamo comprendere a
pieno il ragionamento dietro a questo nostro semplice algoritmo, eliminando ogni ombra
di confusione.

Tenetevi
netevi forte perché la faccenda inizia a farsi davvero interessante...
interessante ora che abbiamo
spiegato che metodologia utilizzare per pensare da programmatore, possiamo iniziare a
pensare di rappresentare questi SI e NO all'interno dei nostri programmi in Python.

E per fare ciò parleremo ora di Logica Booleana: l'Algebra di Boole è quel ramo
dell'Algebra in cui non si utilizzano numeri ma solamente due valori detti Valori di
Verità(proprio ai Vero e Falso che usiamo nei nostri Diagrammi) e che mediante i suoi
Operatori permette di effettuare calcoli logici.

Valori Booleani: True e False

Gli altri tipi di dato di cui abbiamo parlato nei video precedenti, Interi, Float e Stringhe,
hanno un numero illimitatotato di possibili valori, purché questi rispettino le caratteristiche del
tipo: Il tipo di dato booleano invece come abbiamo detto, ha solo due valori possibili, e
questi sono True e False, in italiano Vero e Falso, che rappresentano sostanzialmente i
valori binari 0 ed 1.

True
False

Come per gli altri tipi di valore, anche i valori booleani possono essere assegnati
a variabili. Supponiamo di essere alle prese con la scrittura di un algoritmo che gestisca
l'ingresso di automobili all'interno di un garage; per far si che le macchine possano
entrare, il cancello dovrà essere aperto. In questo caso potremmo avere una variabile
chiamata cancello, a cui assegnamo il valore True qualora il cancello sia aperto,
permettendo così alla macchine di entrare, oppure False in caso contrario:

cancello = True
oppure
cancello = False
type(cancello)
class 'bool'

True e False sono il metodo utilizzato in Python per delineare Si e No dei diagrammi di
flusso; date uno sguardo a questo schema:
Operatori di Comparazione

Ovvero operatori che servono a comparare valori tra di loro, e che ci restituiscono sempre
risultati di natura booleana, quindi True o False. Se affermassi che 5 è uguale a 5,
potremo dire che quest'affermazione è Veritiera, quindi True, mentre se affermassi che 5 è
uguale a 6, l'affermazione sarebbe Falsa.

Gli operatori di comparazione sono 6:


Un'importante distinzione da fare è quella tra "=" e "==": Il primo è il simbolo del processo
di assegnazione (che utilizziamo cioè per assegnare un valore a una variabile), mentre il
secondo è l'operatore di comparazione dell'ugu
dell'uguaglianza.

Facciamo alcuni esempi di utilizzo di questi operatori nella Shell Interattiva, in modo da
rendere più vivido il concetto e mettere a fuoco le idee:

>>> 5 == 5
True
>>> 5 == 6
False
>>> 23 < 50
True
>>> "ciao" != "arrivederci"
True
>>> X = 18
>>> X >= 16
True
>>> 33 = "33"
False
Vi consiglio di esercitarvi qualche tempo sugli operatori di comparazione per prenderci
dimestichezza: forniscono un'elasticità logica senza pari.

Operatori Booleani: AND, OR, NOT


NOT.

Come nell'Algebra classica abbiamo oper


operatori quali + e -,, nell'Algebra Booleana esistono 3
OPERATORI BOOLEANI, e questi sono AND, OR, NOT. Gli operatori booleani sono
utilissimi perché ci consentono di creare espressioni ben più articolate e descrittive di un
semplice 5 == 5. Vengono utilizzati in combinazioni con gli operatori di comparazione
appena descritti. Andiamo ad analizzarne il comportamento tramite quelle che vengono
chiamate Tabelle di Verità,, che rappresentano tutto le possibili combinazioni di questi
operatori e relativi risultati.

Operatore AND:

La logica dietro AND è che affinché un'espressione con questo operatore dia come
risultato True, entrambe le comparazioni devono risultare veritiere, in caso contrario
otterremo sempre un False. Tenendo un occhio sulla tabella di verità di and, scriviamo
sulla Shell degli esempi concreti utilizzando anche gli Operatori di Comparazione:

>>> 2 > 1 and 5 != 7


True
>>> 2 == 2 and 1 > 2
False
>>> 2 < 1 and "asd" == "asd"
False
>>> 23 == 15 and 33 != 33
False
Operatore OR:

Nel caso di OR,, affinché il risultato sia True almeno una delle due comparazioni deve
restituire True e chiaramente, tutti i casi risultano veritieri eccetto l'ultimo, in cui entrambi i
valori sono falsi.

Facciamo degli esempi sulla Shell Interattiva per fissare il concet


concetto:

>>> 25 >= 25 or 23 <= 25


True
>>> "io" == "io" or "io" == "robot"
True
>>> 1 != 1 or 1 == 1
True
>>> 4 == 5 or 5 == 6
False
Operatore NOT:

Parliamo ora dell'ultimo operatore booleano, il NOT, forse il più semplice da capire.
Se una comparazione risulta non Vera sarà chiaramente Falsa, e viceversa.

>>> not "io" == "robot"


True
>>> not 3 == 3
False

Ricapitolando:

 Abbiamo parlato di Algoritmi, Diagrammi di Flusso, Logica Booleana(con Valori e


Operatori Booleani) e Operatori di Comparazione
 Un algoritmo è un procedimento che risolve un determinato problema attraverso un
numero finito di passi elementari
 Un diagramma di flusso è una mappa che ci aiuta a comprendere la logica alla
base di un programma
 A differenza degli altri tipi di dato, il tipo di dato booleano ha solo due valori, True e
False
 Esistono 3 Operatori Booleani, AND, OR, NOT, il cui comportamento è illustrato
nelle rispettive Tabelle di Verità
 Gli Operatori di Comparazione ci servono per effettuare comparazioni
Booleane(che restituiscono quindi True o False) nelle espressioni
06: Controllo di Flusso: if, elif ed else!

Ciao a tutti ragazzi e ragazze e benvenuti a questa nuova lezione della serie di tutorial
Python dedicati alle basi!

Continueremo il discorso sulla gestione del flusso, parlando di tre istruzioni di controllo
molto importanti: if, elif ed else
else.

Per ricollegarci bene al discorso direi di ripartire dal diagramma di flusso analizzato
nella lezione precedente:

Come ricorderete si tratta di uno schema che illustra le possibili azione razionali che una
persona può prendere e in caso di pioggia, qualora il suo scopo sia restare asciutto.
Abbiamo imparato che i Si e No del diagramma sono rappresentati dai due unici valori del
tipo di dato booleano, ovvero True e False.

In questa puntata andremo a fondo col concetto focalizzand


focalizzandoci
oci su come sia possibile
strutturare i diversi blocchi di controllo delle condizioni; Se fin'ora avete pensato ai
diagrammi di flusso come a delle mappe del vostro programma, magari potete immaginare
ció che spiegheremo ora come delle specie di incroci st
stradali
radali su queste mappe.

La prima istruzione di controllo che analizzeremo è l'istruzione IF:


età = 24
if età >= 18:
print('Sei maggiorenne')

Eseguiamo il programma andando su RUN/RUN MODULE oppure cliccando direttamente


il tasto F5

'Sei Maggiorenne'
Analizziamo da vicino i dettagli del funzionamento di questo programma, tramite la lettura
del suo diagramma di flusso:

In Italiano, IF si traduce con SE.

Se la condizione "età >= 18" risulta veritiera, quindi SE il risultato di questa espressione
restituisce valore booleano True, il programma esegue questa porzione di codice e
restituisce la stringa "Sei Maggiorenne". Se invece la condizione fosse risultata falsa,
quindi se età avesse avuto un valore numerico inferiore a 18, il programma sarebbe
saltato direttamente alla fine del programma, ignorando questa porzione di codice.

Verifichiamo questa possibilità andando ad alterare la variabile età, assegnandole ora il


valore 16:

età = 16
if età >= 18:
print('Sei maggiorenne')
run/run module:
(...)

Il programma ignora la porzione di codice col print('Sei maggiorenne') saltando


direttamente alla fine(e quindi senza restituirci nulla in output!), ripetiamolo, perché la
condizione di controllo età >= 18 ha restituito valore booleano False

In Python, i blocchi di codice vengono delineati tramite quella che in programmazione


chiamiamo indentazione, ovvero l'aggiunta di spazi(4/8/12e/ecc spazi bianchi o 1/2/3/ecc
TAB) come delimitatore della nuova porzione di codice. Badate bene che a differenza di
altri linguaggi di programmazione, l'indentazione in Python è obbligatoria, e non
rispettarla comporta la comparsa di errori.

Modifichiamo il codice precedente togliendo lo spazio davanti al print():

età = 16
if età >= 18:
print('Sei maggiorenne')

Provate ad eseguire; come noterete Python si rifiuta di eseguire il codice perché non
correttamente indentato, perché non rispetta cioè i suoi standard di logica.

Apriamo ora una piccola parentesi per quanto riguarda gli errori: evitate assolutamente di
farvi scoraggiare dalla comparsa di errori! Sopratutto nella prima fase di apprendimento
è normalissimo ricevere tonnellate di messaggi di errore da Python, e questo a differenza
di ciò che qualcuno può pensare è un bene. Sbagliare è utile, perché significa infatti che
state imparando qualcosa! Tutti sbagliano, e i migliori fanno tesoro di ciascun errore
la vita gli ponga davanti per imparare. Come tutti i programmatori, se la shell vi
restituisce un messaggio che non riuscite a capire, semplicemente copiatelo e datelo in
pasto a Google, che si dimostrerà anche in questo caso un preziosissimo alleato,
garantito.

Come fare ad eseguire del codice selezionato qualora la condizione di controllo restituisca
invece False?

Per questo scopo ci viene in aiuto l'istruzione Else, traducibile in Italiano con "Altrimenti"
o "Diversamente".
Come vedete ora, se l'espressione restituisce un valore booleano False, viene eseguito un
altro blocco di codice prima che il programma finisca. Il blocco else è sempre l'ultimo ad
essere analizzato e eseguito solo se tutte le condizioni precedenti ad else sono risultate
false. Modifichiamo il nostro codice in maniera appropriata:

età = 16
if età >= 18:
print('Sei maggiorenne')
else:
print('Sei minorenne')

Eseguiamo:

'Sei minorenne')

...e come vedete, ora ci viene restituita la stringa "Sei minorenne" prima che il programma
finisca!
Fino a qui tutto bene, giusto?
Ci saranno dei momenti in cui i vostri programmi dovranno essere pronti a poter
fronteggiare più di due possibili strade... come un incrocio stradale un pó più complesso.

Per fare questo entra in gioco l'ELIF, che significa "Else IF", ovvero "altrimenti se..." che
come per magia vi permette di aggiungere tanti possibili blocchi di controllo quanti ne
avete bisogno. L'istruzione elif viene eseguita solo se la sua espressione di controllo
restituisce True e l'if o eventuali elif precedenti hanno restituito False.

Ad esempio, rendiamo un pò più complesso il nostro programma, aggiungendo una


variabile patente e l'operatore booleano and:

età = 18
patente = False

if età >= 18 and patente == True:


print('Puoi noleggiare una Ferrari!')
elif età >= 18 and patente == False:
print('Niente patente, niente Ferrari!')
else:
print('Ritorneremo a parlare di macchinoni tra qualche anno...')

In accordo con questo esempio, il diagramma di flusso potrebbe essere simile a questo:
Ricapitolando:

 IF, ELIF ed ELSE sono forse le 3 istruzioni di controllo del flusso più importanti in
Python
 L'Indentazione, ovvero l'aggiunta di spazio bianco all'inizio, è il metodo utilizzato in
Python per separare i vari blocchi di codice
 L'Indentazione in Python è obbligatoria e non rispettarne le regole comporta la
comparsa di errori
 IF è l'istruzione che ci consente di eseguire un blocco di codice associato SE
l'espressione di controllo analizzata restituisce valore booleano True
 ELIF significa "else if" ed è l'istruzione che ci consente di definire tanti blocchi di
controllo quanti ne abbiamo bisogno: il codice associato a ciascun ELIF viene
eseguito se gli IF o ELIF precedenti restituiscono False mentre lui restituisce True
 ELSE(altrimenti, diversamente) è l'ultima istruzione ad essere analizzata e viene
eseguita se tutte le espressioni condizionali precedenti sono risultate False
07: Il Ciclo While e le Istruzioni break e continue

Benvenuti a tutti alla settima lezione della serie!

Anche questa è una puntata dedicata alla gestione del Flusso: introdurremo infatti uno dei
due cicli di Python, il Ciclo While, e due nuove istruzioni associate ai
cicli, Break e Continue.

Nella puntata precedente abbiamo parlato dell'istruzione if: Affinché la porzione di codice
associata all'if venga eseguita la condizione espressa deve risultare True, e viene ignorata
se risulta invece False. Un ciclo While è simile da questo punto di vista: la grandissima
differenza sta nel fatto che stavolta la porzione di codice viene eseguita più e più
volte, fintanto che la condizione richiesta resta True. Una volta che la condizione
restituisce valore False, il ciclo viene interrotto. La parola "while" puó essere tradotto in
italiano proprio come "finché" o "mentre".

Ho preparato due esempi, uno con if e uno con while: la condizione di innesco necessaria
affinché il codice venga eseguito è la stessa in entrambi i casi:

contatore = 0
if contatore <= 10:
print(contatore)
contatore = contatore + 1
contatore = 0
while contatore <= 10:
print(contatore)
contatore = contatore + 1

In entrambi i casi è presente una variabile contatore inizializzata a 0, e la condizione


affinché la sezione di codice venga eseguita è che il valore presente in contatore sia
minore o uguale a 10... Proviamo ad eseguire gli esempi, uno alla volta, partendo da if:

>>> 0
IF controlla se all'interno della variabile contatore è presente un valore minore o uguale a
10... e visto che la condizione risulta True ci viene restituito il valore della variabile
contatore. Viene quindi sommato 1 al contenuto di contatore, e in fine il programma
termina, comporta esattamente come abbiamo studiato fino ad ora nelle lezioni
precedenti.

Proviamo ora a eseguire invece la versione col ciclo while:

>>> 0
1
2
3
4
5
6
7
8
9
10

Che è successo? Semplice!


Come nel caso di if, l'istruzione while controlla se al contatore è associato un valore
minore o uguale a 10: siccome la condizione risulta veritiera, il programma entra nel loop,
mandando in output il contenuto di contatore, e quindi sommandoci 1.

Questo si ripete fintanto che la condizione risulta True, cioé fino a che in contatore non è
presente un valore superiore a 10... caso in cui il ciclo while viene appunto interrotto.

Ma cosa succederebbe qualora ra la condizione di controllo restasse perennemente True? In


questo caso otterremo un infinite loop, ovvero un ciclo infinito...
... proviamo un po:

while 15 == 15:
print('ciclo infinito!!!')

Eseguiamo...

'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
'ciclo infinito!!!'
(...)

Per quanto questo infinite loop non sia un errore del linguaggio di programmazione ma
anzi, si dimostri estremamente utile, qualora vi troviate ad averne innescato uno per
errore, volendo bloccarlo vi basterà cliccare CTRL-C.

Per proseguire, come abbiamo accennato a inizio lezione, ci sono due istruzioni correlate
al ciclo while di cui andremo ora a parlare, e sono l'istruzione break e l'istruzione continue.

L'istruzione break serve per terminare un ciclo while prematuramente: non appena
quest'espressione viene letta e processata all'interno del ciclo, ció che Python fa è
bloccare il loop istantaneamente.

Combiniamo i due esempi usati in precedenza, ma incorporiamo anche l'istruzione break:

contatore = 0
while True:
print(contatore)
contatore += 1
if contatore > 10:
print('Sto uscendo dal loop!')
break
L'espressione "contatore += 1" è una versione abbreviata di contatore = contatore +1...
prendetene nota perché come notate vi fa risparmiare parecchi caratteri, e alla lunga,
tempo! Una volta che nel contatore è presente il numero 10, quando al ciclo successivo
viene aggiunto un 1 portandolo ad 11, la condizione espressa dall'IF diventa TRUE e
viene così processato il BREAK, che blocca il loop infinito all'istante.

L'istruzione CONTINUE invece è simile al break, ma invece di interrompere il ciclo, fa


saltare tutto il codice dopo l'istruzione e fa ripartire Python dalla prima riga del ciclo.

Facciamo un esempio:

contatore = 0
while contatore < 10:
contatore += 1
if contatore == 3:
print('saltato')
continue
print(contatore)

Quindi, contatore sempre inizializzato a 0, a inizio ciclo viene incrementato... se peró


risulta uguale a 3, allora non viene passato a print() ma il ciclo si ripete dall'inizio. Quando
in contatore è presente 9, il valore viene incrementato portandolo a 10, e una volta
mandato in output, il ciclo non risulta più True e il programma si ferma.
Ricapitolando:

 Le istruzioni presenti nel ciclo While vengono eseguite fino a che la condizione di
controllo resta True
 È possibile interrompere un ciclo infinito tramite la combinazione di tasti CTRL-C
 L'Istruzione Break viene adoperata per interrompere un ciclo prematuramente
 L'Istruzione Continue viene usata per saltare un ciclo e far riiniziare il loop dall'inizio
08: Il Ciclo For e la Funzione range()

Benvenuti all'ottava lezione della serie dedicata all'apprendimento delle basi!

In questa puntata andremo ad introdurre il secondo ciclo di Python, l'acclamatissimo ciclo


For, e introdurremo una nuova funzione integrata molto importante, la funzione range().

Il Ciclo For viene utilizzato praticamente per gli stessi compiti per cui viene utilizzato il
Ciclo While di cui abbiamo parlato nella lezione precedente, con questo voglio dire che
potete spesso ottenere lo stesso risultato adoperando entrambi i Cicli, ma le differenze nei
meccanismi di funzionamento ne rendono preferibile uno rispetto all'altro a seconda del
contesto in cui vi trovate.

A livello logico, la differenza col Ciclo While è che invece di eseguire la porzione di codice
interessata fintanto che la condizione di controllo resta True, il ciclo For esegue questa
fetta di programma un numero specifico di cicli. Qui di seguito è presente uno dei
programmi che abbiamo scritto nella lezione precedente, che come bene ricorderete ci da
in output tutti i numeri tra 0 e 10:

contatore = 0
while contatore <= 10:
print(contatore)
contatore = contatore + 1

Riassumendone molto brevemente il funzionamento, abbiamo una variabile contatore


inizializzata a 0, e fintato che il valore associato alla variabile risulta inferiore o uguale a
10, viene ripetuto un ciclo in cui viene mandato in output il suo contenuto, a cui viene poi
sommato 1 prima di ripetere il loop.

Ma cosa mi direste se vi dicessi che possiamo ottenere il medesimo risultato più


velocemente utilizzando stavolta il ciclo for di Python? Per più velocemente intendo che
possiamo eliminare sia la variabile contatore che la riga di codice che serve ad
incrementarne il valore... ...questo perché come abbiamo detto in precedenza, la
particolarità di questo ciclo è che viene eseguito un numero già preimpostato di volte.

Nell'editor testuale scriviamo:

for numero in range(11):


print(numero)

eseguiamolo questo nuovo codice...

0
1
2
3
4
5
6
7
8
9
10

Abbiamo ottenuto lo stesso risultato ottenuto col ciclo while, ma utilizzando stavolta solo 2
righe di codice invece di 4. Bella comodità non trovate? Eppure sono certo che in molti tra
voi si staranno chiedendo: che diavolo è quella funzione range() e come mai le ho passato
11 invece di 10, e sopratutto, allora, com
com'è
'è che funziona questo benedetto Ciclo For?

Quello che la funzione range() fa è impostare un intervallo di numeri tanto ampio quanto il
numero che le passiamo come parametro, senza peró includere il numero passato in se.

Siccome di default range inizia a contare da a partire da 0, per comodità potete pensare
per il momento a questo intervallo come a una sorta di elenco o lista di numeri, in questo
caso 11 elementi, da 0 a 10 inclusi.

Come abbiamo detto, a differenza del ciclo while, il ciclo for esegue la sua porzione di
codice un numero preimpostato di volte, giusto? L'intervallo di range() corrisponde al
numero di iterazioni che verranno eseguite, ovvero al numero di volte che il ciclo for verrà
processato.

Ho preparato un semplice Diagramma di Flusso pe


perr farvi fissare definitivamente il
funzionamento del ciclo for:
Una volta che si entra all'interno del ciclo, il codice indentato viene mandato in loop fino a
che non si arriva alla fine dell'intervallo di range(), momento in cui il ciclo termina.

Ora che
e abbiamo imparato come funziona un ciclo for e a cosa serve range(), vediamo un
pó come poter ottenere il massimo da questa funzione, in quanto dovete sapere
che possiamo passarle ben 3 parametri
parametri.
Questo ci permette di impostare oltre a un punto di inizio dell'intervallo anche un punto di
fine personalizzato, e un passo di avanzamento.

Andiamo a modificare il ciclo for utilizzato prima... impostiamo un punto di inizio, ad


esempio 3, manteniamo il punto di fine come 11, e settiamo anche un passo di 2...

for numero in range(3,11,2):


print(numero)
3
5
7
9

La differenza più grossa è che stavolta il passo dell'intervallo è due, quindi si passa da 3 a
5, da 5 a 7 e da 7 a 9. Come al solito il numero finale dell'intervallo viene saltato.

Grazie alla possibilità di personalizzazione della funzione range(), possiamo anche fare in
modo di ottenere i numeri al contrario... ad esempio al contrario dal 10 all'1...

for numero in range(10,0,-1):


print(numero)
10
9
8
7
6
5
4
3
2
1

Ricapitolando:

 A differenza del ciclo while, il ciclo for viene eseguito un numero di volte
preimpostato
 La funzione range() ci permette di impostare il numero di volte che il ciclo for viene
eseguito
 Alla funzione range() è possibile passare tre parametri, START, STOP e STEP
09: CheckPoint: Costruiamo una Calcolatrice con Python
Benvenuti a questa nona lezione della nostra serie dedicata alle Basi di Python 3!

Questa è una puntata un pó diversa dalle altre, come da titolo si tratta di un episodio "checkpoint",
ovvero un episodio in cui faremo il punto della situazione su ciò che abbiamo appreso fin'ora,
mediante la costruzione di una semplice calcolatrice.

Vi fará piacere sapere che se avete seguito questa serie fino a questo punto, disponete ora di tutti gli
strumenti necessari per poter scrivere questo programma... utilizzeremo infatti:

 Gli Operatori Numerici di Python e le Variabili


 La Funzione print() e la funzione input()
 Le Istruzioni di controllo if, elif ed else
 Alcune funzioni di conversione di tipo, str() e float()
 Il Ciclo While e le istruzioni Break e Continue

Questo è il codice dell'applicazione, seguite il video per tutti i commenti!

while True:
print('''
Benvenuto al programma calcolatrice!
Creata da: Mike
Di seguito un elenco delle varie funzioni disponibili:

-Per effettuare un'Addizione, seleziona 1;


-Per effettuare una Sottrazione, seleziona 2;
-Per effettuare una Moltiplicazione, seleziona 3;
-Per effettuare una Divisone, seleziona 4;
-Per effettuare un Calcolo Esponenziale, seleziona 5;
-Per uscire dal programma puoi digitare ESC;
''')

scelta = input('Inserisci il numero corrispondente all\'operazione


selezionata ---> ')
if scelta == "1":
print('\nHai scelto: Addizione\n')
a = float(input('Inserisci il Primo Numero -> '))
b = float(input('Inserisci il Secondo Numero -> '))
print('Il risultato della Somma è: ' + str(a + b))
elif scelta == "2":
print('\nHai Scelto: Sottrazione\n')
a = float(input('Inserisci il Primo Numero -> '))
b = float(input('Inserisci il Secondo Numero -> '))
print('Il risultato della Sottrazione è: ' + str(a - b))
elif scelta == "3":
print('\nHai scelto: Moltiplicazione\n')
a = float(input('Inserisci il Primo Numero -> '))
b = float(input('Inserisci il Secondo Numero -> '))
print('Il risultato della Moltiplicazione è: ' + str(a * b))
elif scelta == "4":
print('\nHai scelto: Divisione\n')
a = float(input('Inserisci il Primo Numero -> '))
b = float(input('Inserisci il Secondo Numero -> '))
print('Il risultato della Divisione è: ' + str(a / b))
elif scelta == "5":
print('\nHai scelto: Calcolo Esponenziale\n')
a = float(input('Inserisci la Base -> '))
b = float(input('Inserisci l\'Esponente -> '))
print('Il risultato del Calcolo Esponenziale è: ' + str(a ** b))
elif scelta == "ESC":
print('''L'applicazione verrà ora chiusa!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'''
)
break

loop = input('\nDesideri continuare ad usare l\'applicazione? S/N ')


if loop == "S" or loop == "s":
print('''Sto tornando al Menù principale!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'''
)
continue
else:
print('''Grazie e arrivederci!

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'''
)
break

Ti stai forse chiedendo: "come mai non ha usato una funzione?" tranquillo, ne parleremo nelle
prossime lezioni! ;)
10: I Moduli della Standard Library

Ciao a tutti brava gente e benvenuti a questa decima puntata della nostra serie dedicata
all'apprendimento delle basi di Python 3.6.

Ciascun programma che scrivete in Python puó includere un set di istruzioni integrate,
come ad esempio la funzione print() e la funzione input() che abbiamo utilizzato nei
programmi scritti fin'ora. In aggiunta a queste funzioni Python dispone di un insieme
di Moduli in quella che viene chiamata la Standard Library.

Ciascun modulo è un programma scritto da altri programmatori, e contiene un insieme di


funzioni associate progettate per svolgere compiti comuni come ad esempio la
generazione di numeri casuali nel caso del modulo random o funzioni matematiche come
nel caso del modulo math, espressioni regolari col modulo RE e interfacciamento col
sistema operativo nel caso del modulo OS.

La Standard Library contiene decine e decine di moduli, e ciascun modulo contiene a sua
volta tantissime funzioni... date uno sguardo a questa pagina del sito della Python
Foundation per farvi un'idea di quanto sia sconfinato il suo potenziale...

Prima di potere utilizzare queste funzioni all'interno dei vostri programmi dovrete importare
questi moduli, e il modo più comodo per fare ciò è utilizzare il comando import da
scrivere in cima al programma.

# questo programma ci fornisce 10 numeri casuali tra 1 e 50

import random
for numero in range(10):
valore = random.randint(1,50)
print(valore)

Ciò che ho appena fatto è stato quindi anzitutto importare il modulo chiamato
random mediante il comando import. Quindi ho utilizzato la funzione randint del modulo
random per associare alla variabile valore un numero casuale ad ogni ciclo di FOR,
compreso tra 1 e 50. Testiamo il programma mandandolo in esecuzione...

7
27
22
9
19
11
31
4
36
32
C'è un'altra tipologia di import che può essere utilizzata per importare solo uno funzione
specifica di un modulo, facciamo un esempio con la funzione sqrt del modulo math, che si
occupa di effettuare radici quadrate.

from math import sqrt

Quando importate una funzione in questa maniera, come vedete non è necessario ripetere
il nome del modulo di provenienza.

>>> sqrt(25)
5.0

Un altro modo per importare le funzioni e richiamarle senza dover necessariamente


riscrivere il nome del modulo ogni volta include l'utilizzo di un asterisco:

from math import *

Potremo in questo modo richiamare tutte le funzioni matematiche incluse nel modulo
math... ma sopratutto se state pensando di lavorare ad un progetto importante e vasto, è
decisamente meglio utilizzare la prima o la seconda modalità che vi ho spiegato.

Esiste inoltre un sistema che ci consente di installare moduli che non fanno parte della
standard library, e questo tramite il programma PIP, di cui già disponete perché integrato
nel pacchetto di installazione di Python. Ma di PIP e di come fare per installare Moduli
esterni parleremo più avanti!

Ricapitolando:

 I Moduli sono programmi scritti da altri programmatori che contengono svariate


funzioni
 I Moduli di Python si racchiudono in quella che viene chiamata Standard Library
 Per poter utilizzare una funzione dobbiamo prima importarla tramite il comando
import
 I modi preferibili per usare import sono import NomeModulo o from NomeModulo
import NomeFunzione
11: Scrivi le Tue Funzioni

Uno dei concetti comuni a tutti i linguaggi di programmazione è il concetto di riutilizzo del
codice.

Più un programma è complesso più saranno le righe di codice che lo compongono, e


affinché sia possibile tenere il tutto sempre aggiornato è molto importante evitare
ripetizioni superflue.

Fin'ora abbiamo visto alcune delle possibili metodologie applicabili per rendere il codice
scritto riutilizzabile, ovvero i cicli di controllo e l'utilizzo di moduli e funzioni della Standard
LIbrary.

In aggiunta alle funzioni integrate offerte da Python, potete scrivere le vostre


funzioni per fargli fare ciò che desiderate.

L'idea dietro al concetto di funzione è quella di assegnare una porzione di codice e delle
variabili chiamate parametri ad un nome, e mediante questo nome che funge da
collegamento potete richiamare tutto il codice associato.

In una scala di molto ridotta il concetto è simile a quello di variabile che abbiamo visto
nella lezione numero 3.

Per lo stesso motivo per cui quando scrivete un programma e lo salvate in modo da
eseguirlo in un secondo momento, potete pensare alle funzioni come a dei mini
programmi all'interno dei nostri programmi, che chiamiamo ogni volta dobbiamo
utilizzare le funzionalità associate.

Le funzioni sono fantastiche quindi per fare in modo di ridurre il numero di volte che un
pezzo di codice deve essere scritto in un programma.

Per definire una funzione utilizzate la parola chiave def, che informa istantaneamente
Python di ciò che stiamo facendo, seguita dal nome che volete dare a questa funzione.
Cercate di dare sempre dei nomi che siano rappresentativi dello scopo della funzione.

Il nome viene seguito da una coppia di parentesi, e all'interno delle parentesi metteremo i
parametri, ovvero delle variabili necessarie al funzionamento della funzione. Ma non tutte
le funzioni necessitano di parametri, in questo primo esempio lasceremo le parentesi
vuote.

def print_tre_volte():
print('Ciao!')
print('Ciao una seconda volta!')
print('Ciao una terza volta!')

Seguendo la logica di Python, il codice che viene inserito all'interno della funzione deve
essere Indentato.

All'interno della funzione potete aggiungere tutto il codice che vi pare... le combinazioni
sono infinite.
Se ora andiamo ad eseguire questo codice... F5... ci rendiamo conto che non succede
ancora niente. Come mai?

Per eseguire la funzione dobbiamo richiamarla, e per fare una chiamata alla funzione
possiamo semplicemente utilizzare il suo nome, all'interno della Shell Interattiva, o
direttamente dall'editor testuale.

print_tre_volte()
def print_tre_volte():
print('Ciao!')
print('Ciao una seconda volta!')
print('Ciao una terza volta!')

print_tre_volte()

Definiamo una funzione sommatrice a cui passeremo due numeri e che ci restituirà la
somma tra i due:

def sommatrice(a,b):
print('Questa è la funzione somma.')
print('Fornisce la somma di due numeri passati come parametri.')
risultato = a + b
print('Il risultato della somma è ' + str(risultato))

Andiamo ad eseguire la funzione mediante la chiamata al suo nome e passiamoli due


numeri come argomento tra parentesi.

sommatrice(15, 5)

L'argomento è il nome che viene dato al valore passato per essere depositato nella
variabile parametro. Quindi i parametri in questo caso sono a e b, e gli argomenti dei
parametri 15 e 5.

Questa è la funzione somma.


Fornisce la somma di due numeri passati come parametri.
Il risultato della somma è 20

Non ci sono dei limiti al numero di parametri che è possibile passare, ma badate di
sceglierli sempre con cura e di dargli anche in questo caso dei nomi specifici. Talvolta ci
troveremo in una situazione in cui è necessario avere dei parametri opzionali alle nostre
funzioni, ovvero fare in modo che queste funzionino con o senza l'aggiunta di valori in
questi specifici parametri. Per rendere questo possibile, a questi parametri è associato
sempre un valore di default.

Immaginate che stiate andando a comprare un laptop nuovo. Due caratteristiche da tenere
sott'occhio sono sicuramente RAM e modello della CPU, che quindi sceglieremo. Come vi
sarà capitato, vi viene chiesto se volete acquistare anche un pacchetto antivirus, e voi
potete scegliere se lo volete oppure meno.

Proviamo a portare questo esempio in una funzione:

def laptop_nuovo(ram,cpu, antivirus = False):


print('Il nuovo laptop avrà le seguenti caratteristiche:')
print('ram: ' + ram)
print('cpu: ' + cpu)
if antivirus == True:
print('Hai comprato anche un antivirus')

Quindi qualora non ci interessi acquistare l'antivirus possiamo semplicemente ignorare


questo parametro a cui è stato dato il valore di default False:

>>> laptop_nuovo("16gb","i7")
Il nuovo laptop avrà le seguenti caratteristiche:
ram: 16gb
cpu: i7

Diversamente se vogliamo l'antivirus ci basta passare True al parametro:

>>> laptop_nuovo("16gb", "i7", antivirus=True)


Il nuovo laptop avrà le seguenti caratteristiche:
ram: 16gb
cpu: i7
Hai comprato anche un antivirus

Vorrei ora che però prestasse attenzione ad un dettaglio. Nella nostra funzione
sommatrice, per fare in modo di mandare in output il risultato della somma abbiamo
utilizzato una seconda funzione, ovvero la funzione print, a cui abbiamo passato il risultato
dell'operazione. Proviamo a togliere tutti i print e lasciare solo la variabile risultato...

def sommatrice(a, b):


risultato = a + b

... e richiamiamo quindi la funzione...

sommatrice(3, 3)

Come immaginabile, la funzione non ci restituisce nulla!

In questo caso la funzione ha passato alla Shell un tipo di dato nullo, il None Type.

Per fare in modo che la nostra funzione restituisca il risultato in maniera autonoma
dobbiamo utilizzare il comando return.
def sommatrice(a,b):
risultato = a + b
return(risultato)

Proviamo a richiamare la funzione...

sommatrice(3, 6)
9

...ed ecco che ora ci restituisce il contenuto di risultato.

Ricapitolando:

 Lo scopo principale di una funzione è di poter riutilizzare il codice più volte ed


evitare duplicazioni
 Una funzione è definita usando la parola chiave def
 Alle funzioni possiamo passare dei valori chiamati argomenti in delle variabili
chiamate parametri, tra le parentesi della funzione
 Possiamo creare dei parametri opzionali passando a loro un valore di default
 L'output di una funzione è il valore del suo return
 Tutte le funzioni hanno un return, e se non è visibile il tipo di dato passato dal return
sarà None
12: Variabili Globali e Variabili Locali

Fin'ora abbiamo detto che possiamo immaginare le variabili come delle scatole in cui
depositiamo dei valori.

Possiamo quindi richiamare e modificare questo valore utilizzando il nome della variabile.

x = 3
x += 1
x
4

Abbiamo inoltre parlato di funzioni, e abbiamo visto che anche qui possiamo e siamo
incoraggiati ad utilizzare le variabili: si tratta di uno degli elementi indispensabili di Python
e della programmazione in generale.

Ma fino a dove ci possiamo spingere nell'utilizzo delle variabili? Fino a che punto è
davvero possibile utilizzarle e modificarle nei nostri programmi? Per rispondere a queste
domande andremo ora ad approfondire il tema parlando di Variabili Globali e Variabili
Locali.

Partiamo da un esempio sull'editor testuale.

x = 15

def funzione_esempio():
return(x)

print(funzione_esempio())
15

La nostra funzione esempio ci restituisce quindi il valore assegnato alla variabile x.

Proviamo peró ora a modificare leggermente la nostra funzione... diciamo che vogliamo
aggiungere 2 al 15 presente in "x".

x = 15

def funzione_esempio():
x += 2
return(x)

print(funzione_esempio())
>>>UnboundLocalError: local variable 'x' referenced before assignment
Come mai abbiamo ottenuto questo errore? Python ci informa del fatto che ci stiamo
riferendo a una variabile prima di averla dichiarata e assegnata... eppure nell'esempio
precedente tutto ha funzionato a meraviglia e la variabile x è proprio li!

La chiave di lettura di questo comportamento apparentemente bizzarro è la seguente,


prestate attenzione: In Python il codice e quindi anche le variabili, possono essere salvati
in due ambienti diversi, l'Ambito Locale e l'Ambito Globale, chiamati in inglese Global
Scope e Local Scope.

Potete pensare a questi due ambienti come a dei contenitori distinti in cui vengono definite
e assegnate le variabili, un contenitore Globale e un contenitore Locale. Quando uno di
questi contenitori viene distrutto, quindi quando uno di questi ambiti viene distrutto, lo
stesso accade per i valori delle variabili in esso salvate che vengono quindi dimenticati.

La distinzione tra i due ambiti è la seguente:

Un Ambito Locale viene creato ogni volta che una funzione viene chiamata, e distrutto
dopo che la funzione restituisce un valore con return. È come se ogni volta che una
funzione viene processata, Python le fornisse un contenitore e le dicesse: bene, metti le
tue variabili e il tuo codice quà dentro. Le variabili dichiarate all'interno di qualsiasi
funzione, quindi dell'Ambito Locale della funzione, sono chiamate Variabili Locali.

Possono esistere quindi tanti Local Scope quante funzioni abbiamo in esecuzione.

Dall'altro lato invece, esiste e può esistere un unico Ambito Globale, che viene creato
automaticamente da Python all'avvio del programma e distrutto alla chiusura del
programma. È l'ambito principale: tutte le variabili che vengono dichiarate all'esterno di
una funzione sono chiamate proprio Variabili Globali, e restano pertanto in vita dall'avvio
alla chiusura del programma principale.

È possibile accedere alle Variabili Globali da qualsiasi parte del programma, mentre è
possibile accedere alle Variabili Locali solamente dall'Ambito Locale della funzione in cui
sono contenute.

Nel nostro esempio, x è proprio una variabile Globale, e otteniamo un errore perché
seppur è vero che un Ambito Locale può accedere alle variabili del Global Scope, il loro
utilizzo all'interno della funzione è limitato.

Ad esempio per poter modificare il valore di una Variabile Globale dall'interno di una
funzione, come abbiamo provato a fare con la nostra x, dobbiamo prima dichiarare alla
funzione le nostre intenzioni mediante l'istruzione global. Andiamo a modificare l'esempio
precedente...

x = 15

def funzione_esempio():
global x
x += 2
return x
print(funzione_esempio())
17

Ed ecco che ora ci è possibile modificare il valore della variabile x, perché Python sa che
ci stiamo riferendo alla x presente nell'Ambito Globale!

Un altro modo per poter utilizzare il valore di una Variabile Globale in maniera più
complicata all'interno di una funzione è creando una Variabile Locale a cui assegnamo il
valore della Variabile Globale. Potremo quindi poi modificare la nostra nuova Variabile
Locale, aggirando così la limitazione.

Tenete a mente che volendo potete dare a questa nuova Variabile Locale anche lo stesso
nome della Globale, perché Python le distinguerà comunque come variabili differenti per
via dell'ambito di provenienza.

Per facilitare questo esempio io utilizzerò però un nome differente:

x = 15

def funzione_esempio():
y = x
y += 2
return y

print(funzione_esempio())
17

Come accennato inoltre, al contrario delle Globali, è possibile accedere alle Variabili Locali
solamente dall'Ambito Locale della funzione in cui sono contenute, quindi non è possibile
accedervi dal global scope o dal local scope di un'altra funzione... otterremo un errore
qualora provassimo a forzare questa regola. Ad esempio:

def mia_funzione():
spam = 24
print(spam)

eggs = spam + 6
>>> NameError: name 'spam' is not defined

Potete utilizzare le variabili di una funzione solo se queste ci vengono passate dal return
della funzione... ad esempio facciamo una piccola modifica:

def mia_funzione():
spam = 24
return spam

eggs = mia_funzione() + 6
print(eggs)
30

Ed ecco che ora possiamo effettuare una somma con spam dall'ambito principale del
programma.

È bene imparare la distinzione tra Ambito Locale e Ambito Globale perché si tratta di
concetti estremamente importanti.

L'esistenza degli ambiti è utilissima ad esempio per ridurre il numero di bug e aumentare
la robustezza dei programmi!

Pensate a che caos se in un programma complesso tutte le variabili fossero globali, e per
colpa di un errore in una della tante funzioni del programma i valori delle variabili fossero
perennemente sballati, causando un crash sistematico.

Inoltre restando in memoria fino alla fine del programma, in programmi complessi le
Variabili Globali sono sinonimo di pesantezza e spreco di risorse.

L'utilizzo di Variabili Locali è quindi estremamente incoraggiato, e quello di Variabili


Globali decisamente SCONSIGLIATO!

Ricapitolando:

 Esistono due ambienti distinti in cui vengono salvati codice e variabili, l'Ambito
Locale e l'Ambito Globale
 L'Ambito Globale è il principale, creato all'avvio del programma e distrutto solo alla
sua chiusura
 Le Variabili definite nell'Ambito Globale sono chiamate Variabili Globali
 L'Ambito Locale è quello interno a una funzione, viene creato quando la funzione è
chiamata e distrutto al return
 Le Variabili definite nell'Ambito Locale sono chiamate Variabili Locali
 È possibile accedere alle Variabili Globali da qualsiasi parte del programma, mentre
è possibile accedere alle Variabili Locali solamente dall'Ambito Locale della
funzione in cui sono contenute
 L'utilizzo di Variabili Globali è generalmente sconsigliato per evitare bug e
preservare la robustezza del programma
13: A prova di crash - Come gestire gli Errori

Ciao a tutti e benvenuti a questa tredicesima lezione della serie dedicata alle basi di
Python 3!

Come il titolo vi avrà suggerito, questa è una lezione dedicata alla gestione intelligente e
produttiva degli errori che si possono verificare durante l'esecuzione dei nostri programmi.
Parlando di errori mi riferisco in realtà a quelle eccezioni che quando si manifestano,
comportano il crash del programma e l'interruzione istantanea dell'esecuzione del codice.

Un'eccezione tipica è quella che si manifesta quanto proviamo ad effettuare una divisione
per zero, che restituisce appunto un ZeroDivisionError:

>>> 3/0
ZeroDivisionError: division by zero

Un'altro messaggio di errore ci viene presentato se proviamo ad utilizzare una variabile


non dichiarata...

>>> z * 5
NameError: name 'z' is not defined

Questi messaggi di errore sono piuttosto comodi per noi sviluppatori, prima di tutto
per risolvere i vari bug che inevitabilmente si presentano. Inoltre il livello di dettaglio che
ci viene fornito da Python è davvero impressionante se paragonato a tanti altri linguaggi di
programmazione, e questo è uno dei tantissimi vantaggi del linguaggio più bello del
mondo. Anche molti moduli vengono ideati e pubblicati con un certo livello di dettaglio nel
caso si manifesti un'eccezione.

È importante gestire questi errori perché oltre a causare il crash del programma sono
esteticamente poco gradevoli e incomprensibili sopratutto a chi sta utilizzando un
programma scritto da qualcun'altro.

Per gestire queste eccezioni utilizziamo due istruzioni utilissime: try ed except, che
significano "prova" e "eccetto" o "a accezione di".

Volendo potete immaginarli un pò come degli if / else ideati per la gestione delle eccezioni.

Il codice inserito nel try verrà eseguito qualora tutto andasse come pianificato, senza
errori,mentre il codice inserito nell'except verrà eseguito solamente qualora si verifichi
l'errore ad esso associato.

Apriamo l'editor testuale e facciamo un esempio in cui gestiremo l'eccezione


"ZeroDivisionError".

def divisore(a, b):


try:
risultato = a / b
print('Il Risultato della divisione è: ' + str(risultato))
except ZeroDivisionError:
print('Hai effettuato una divisione per Zero... causando così un
errore!')

Uno dei momenti in cui le istruzioni try ed except risultano quasi indispensabili è proprio
quando si richiede all'utente di introdurre dei valori.

Facciamo un altro esempio, stavolta con una moltiplicazione:

def moltiplicatore():
a = int(input('Inserisci il valore di a: '))
b = int(input('Inserisci il valore di b: '))
risultato = a * b
print(risultato)

Proviamo ad eseguire il codice... e a forzarlo introducendo dei caratteri non numerici


all'interno delle variabili a e b:

>>> moltiplicatore()
Inserisci il valore di a: asd

ValueError: invalid literal for int() with base 10: 'asd'

Abbiamo ottenuto un ValueError, ovvero un errore di valore, perché la funzione int() non è
in grado, ovviamente, di convertire la stringa "asd" in un numero intero.

Andiamo a modificare il programma in modo da poter gestire questa eventualità...

def moltiplicatore():
try:
a = int(input('Inserisci il valore di a: '))
b = int(input('Inserisci il valore di b: '))
risultato = a * b
print(risultato)
except ValueError:
print('Hey amico! solo caratteri numerici, grazie!')

E rieseguiamo il tutto...

>>> moltiplicatore()
Inserisci il valore di a: asd
Hey amico! solo caratteri numerici, grazie!

Quindi qualora siate in fase di progettazione di un programma, e notate che ci sono delle
eventualità in cui, per quanto il programma sia ben strutturato, si arriva comunque a dei
crash, come appunto in questi casi presentati, semplicemente copiate il nome dell'errore e
usatelo assieme ad except per poter gestire questa eccezione. Così facendo il programma
avrà tutto un altro livello di professionalità!

Un'altra istruzione di cui è bene parlare è l'istruzione finally, traducibile in questo caso
come "alla fine" o "infine".

Come il nome stesso suggerisce, il codice definito nel blocco di finally verrà eseguito alla
fine del programma, qualsiasi cosa succeda, ovvero che si manifesti un errore oppure no.
Andiamo a modificare la nostra funzione moltiplicatore():

def moltiplicatore():
try:
a = int(input('Inserisci il valore di a: '))
b = int(input('Inserisci il valore di b: '))
risultato = a * b
print(risultato)
except ValueError:
print('Hey amico! solo caratteri numerici, grazie!')
finally:
print('Grazie per aver utilizzato questa applicazione!')

E proviamo ad eseguirla facendo apparire sia l'eccezione che no: Come vediamo, la
stringa 'Grazie per aver utilizzato questa applicazione!' viene mandata in output qualsiasi
cosa succeda!

Ricapitolando:

 Per quanto utili in fase di sviluppo, gli errori sono scomodi e causano il crash del
programma
 Possiamo gestire questi errori mediante l'utilizzo delle istruzioni try ed except
 Il codice nel blocco di except viene eseguito solo in caso un errore si manifesti
 Mediante l'istruzione finally possiamo delineare del codice che verrà eseguito
qualsiasi cosa succeda
14: Liste e Tuple

Come da titolo, in questa puntata introdurremo due nuovi tipi di dato in Python, le Liste ed
i Tuple,, che sono simili tra loro ma allo stesso tempo molto diversi. Capirete cosa intendo
a breve.

N.B. In questa lezione, e in generale durante tutto il corso, mi riferisco al tipo di dato
"Tuple" utilizzando la versione al maschile "i Tuple". È però necessario precisare che in
Italia ci si riferisce a questo tipo di dato al femminile col nome "Tupla", quindi si dice
spesso "Le Tuple". La versione "i Tuple" da me utilizzata è quindi in verità più di matrice
inglese. Tenete questo bene a mente, e proseguiamo con la lezione!

Le Liste sono un tipo di dato che contiene al suo interno un insieme di dati uguali o diversi
tra di loro, ordinati in base ad un indice proprio della Lista.

Facciamo degli esempi, creiamo una variabile e assegnamole una lista:

elenco = [2, 5, "bacon", 3.14, "eggs"]

Così come una Stringa viene definita utilizzando apici o doppi apici, una Lista viene
definita utilizzando una coppia di parentesi quadre.. Gli elementi della Lista vengono
quindi separati tra loro da delle
e virgole.

Per ottenere in output la lista completa di tutti gli elementi, anche qui, come visto per gli
altri tipi di dato studiati fin'ora, ci basta semplicemente utilizzare il nome della variabile:

>>> elenco
[2, 5, 'bacon', 3.14, 'eggs']

Abbiamo detto che gli elementi sono ordinati in base ad un indice proprio di ciascuna
Lista: ciò significa che a ciascun elemento è associato un numero che ne rappresenta la
posizione nell'elenco. Questo è fondamentale se vogliamo richiamare un elemento
specifico, avremo infatti bisogno del suo indice corrispondente in modo da potervi
accedere in maniera rapida e precisa.

Badate bene che il primo valore della Lista ha sempre come indice 0.

Quindi in questo caso 2 avrà indice 0, 5 avrà indice 1, 'bacon' avrà indice 2 e così via...

Volendo richiamare 'bacon' possiamo quindi fare:

elenco[2]
'bacon'

Volendo richiamare 'eggs':

elenco[4]
'eggs'

Se utilizziamo invece un indice negativo possiamo accedere agli elementi della lista dalla
fine all'inizio, utilissimo ad esempio in caso di Liste particolarmente lunghe. L'ultimo
elemento ha indice -1, il penultimo -2 e così via..

Per richiamare il 3.14 possiamo fare:

elenco[-2]
3.14

Un'altra caratteristica particolarmente interessante di questo sistema di indicizzazione è


che avete la possibilità di accedere a una fetta di elementi da voi scelta, impostando un
punto iniziale e un punto finale nell'indice.

Creiamo una nuova Lista... facciamo stavolta una Lista di soli numeri magari:

primi = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
>>> primi[4:10]
[11, 13, 17, 19, 23, 29]

Quella che vedete è di fatto una nuova Lista creata a partire dalla Lista dei Numeri Primi, e
volendo possiamo associare questa nuova Lista a una variabile:

fetta = primi[4:10]
>>> fetta
[11, 13, 17, 19, 23, 29]

Come forse alcuni di voi avranno notato, questo sistema di suddivisione a fette funziona
un pò come la funzione range() vista nella lezione 8: l'ultimo elemento del Range non
viene incluso nella nuova lista creata.

Possiamo impostare questo indice variabile anche in modo da farlo iniziare, o terminare,
con l'inizio oppure la fine della lista, utilizzando due punti:

Per ottenere tutti i numeri dal 5o all'ultimo nella nostra lista possiamo fare:

>>> primi[4:]
[11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]

Ho utilizzato il 4o perché partendo dall'indice 0, il 5o elemento nella Lista sará appunto


quello con indice 4.

Parallelamente possiamo inoltre ottenere tutti gli elementi a partire dal primo fino ad una
soglia da noi scelta in questo modo:

>>> primi[:5]
[2, 3, 5, 7, 11]

Tornando a fare un'analogia con range(), abbiamo visto che questa funzione è utilissima in
combinazione con i cicli For.

ad esempio:

for numero in range(5):


print(numero)

0
1
2
3
4

Allo stesso modo possiamo utilizzare i For Loop con le stringhe... ad esempio,
considerando la lista di numeri primi utilizzata in precedenza:

for primo in primi:


print(primo)

2
3
5
7
11
13
17
19
23
29
31
37
41
43
47

Possiamo quindi creare Liste a partire dalla funzione range() mediante la funzione di
supporto list(), che converte elementi in Liste, ad esempio:

lista_numerica = list(range(99, 300))

richiamiamola:

>>> lista_numerica
[99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
127,
128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141,
142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155,
156,
157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170,
171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184,
185,
186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199,
200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213,
214,
215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228,
229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242,
243,
244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257,
258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271,
272,
273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286,
287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299]

Ed ecco a noi tutti i numeri tra 99 e 299, che possiamo ora utilizzare per effettuare i calcoli
più disparati.

Questo tipo di dato è così flessibile che una Lista puó contenere al suo interno anche una
o più liste:

>>> lista_multipla = ["spam", "eggs", 23, "bacon", [1, 2, 3, 4, 5], 3]


>>> lista_multipla
["spam", "eggs", 23, "bacon", [1, 2 ,3, 4, 5], 3]

Chiaramente per ottenere questa sottolista ci basta richiamarla con l'indice corrispondente
all'interno della Lista contenitore:

>>> lista_multipla[-2]
[1, 2, 3, 4, 5]

Se vogliamo ottenere un elemento specifico della sottolista possiamo usare un doppio


indice, ad esempio per ottenere l'ultimo elemento della sottolista:

>>> lista_multipla[-2][-1]
5

Utilizzando gli indici possiamo anche sostituire un elemento della Lista! ad esempio se
volessimo sostituire la parola "bacon" con la parola "pancetta" potremo fare:

>>> lista_multipla[3] = "pancetta"


>>> lista_multipla
['spam', 'eggs', 23, 'pancetta', [1, 2, 3, 4, 5], 3]

E per eliminare un elemento dalla Lista utilizziamo del. Volendo eliminare tutta la sottolista
possiamo fare:

>>> del lista_multipla[-2]


>>> lista_multipla
['spam', 'eggs', 23, 'pancetta', 3]

Vi invito a testare i limiti di queste istruzioni esercitandovi, perché si possono fare davvero
tante cose utilissime.

Parliamo ora molto brevemente dei Tuple.

Come le liste si tratta di un gruppo, un insieme di elementi, definiti stavolta utilizzando una
coppia di parentesi tonde, oppure senza alcuna parentesi:

>>> tupla = (2, 4, 9, 15, 23)

tupla
(2, 4, 9, 15, 23)
>>> tuple2 = 7,8,9

tuple2
(7, 8, 9)
Possiamo accedere agli elementi del Tuple utilizzando l'indice anche stavolta:

>>> tupla[0]
2

Ma la più grande differenza è che una volta creati, i Tuple NON si possono modificare,
come invece accade per le Liste.

>>> del tupla[0]


TypeError: 'tuple' object doesn't support item deletion

Vorrete quindi utilizzare un Tuple invece di una Lista in quelle situazioni in cui è molto
importante che un elenco sia immutabile, e tenete a mente anche che l'iterazione
all'interno di un Tuple avviene molto più velocemente che in una Lista, e questo è un bel
punto a vantaggio dei Tuple.

Ricapitolando:

 Le Liste sono un tipo di dato che contiene svariati valori, anche tutti diversi tra di
loro
 Per accedere ai valori delle Liste possiamo usare il sistema di indicizzazione della
Lista
 L'indice parte da 0, e si possono usare numeri negativi per accedere dalla fine
all'inizio
 Si puó inoltre impostare un intervallo utilizzando i due punti per l'inizio o la fine del
range
 L'indice si usa inoltre per sostituire un elemento, o eliminarlo con l'istruzione DEL
 I Tuple sono anch'essi degli elenchi di valori indicizzati, ma una volta creati sono
immutabili
15: Similarità tra Liste e Stringhe

In questa lezione continueremo a parlare del nuovo tipo di dato introdotto nella lezione
precedente, le Liste, facendo un confronto necessario con un altro tipo di dato studiato
nelle puntate precedenti, le Stringhe.

Definiamo due variabili spam ed eggs, e assegnamo loro delle stringhe:

spam = "La pratica"


eggs = "rende perfetti!"

Come abbiamo già visto è possibile effettuare delle concatenazioni tra queste stringhe
utilizzando un semplice +, e moltiplicarle utilizzando un *

spam + eggs
'La pratica rende perfetti!'

spam * 3
'La pratica La pratica La pratica '

Lo stesso discorso vale per le Liste: possiamo effettuare concatenazioni e moltiplicazioni


nella stessa maniera!

Definiamo due variabili A e B e assegnamole delle liste...

a = [1, 2, 'tre']
b = [4, 5, 'sei']

a + b
[1, 2, 'tre', 4, 5, 'sei']

a * 3
[1, 2, 'tre', 1, 2, 'tre', 1, 2, 'tre']

Una funzione estremamente utile, comune sia a Liste che Stringhe è la funzione len(), che
ci restituisce la lunghezza dell'elemento passato:

len(spam)
11

len(a)
3

Possiamo utilizzare gli operatori in e not in per controllare se un elemento o un carattere


è presente all'interno di una Lista o Stringa. Questi operatori restituiscono valori Booleani,
True o False.
Riassegniamo le variabili a e b:

a = [1, 2, 3, 4]
b = "qwerty"

1 in a
True

6 in a
False

"q" in b
True

"z" in b
False

Potete utilizzare il sistema di accesso ad indice anche nelle stringhe, come visto nella
puntata precedente con le Liste:

alfa = "abcdefghijklm..."

Facciamo un esempio, diciamo che vogliamo capovolgere questa stringa... scriviamo


quindi una piccola funzione che lo faccia per noi!

def reverser(stringa):
indice = (len(stringa) -1)
nuova_stringa = ""
while indice >= 0:
nuova_stringa += stringa[indice]
indice -= 1
print(nuova_stringa)

reverser(alfa)

...mlkjihgfedcb

Possiamo inoltre ottenere una porzione di stringa utilizzando un indice doppio, proviamo
ad esempio ad eliminare i 3 punti di sospensione:

>>> alfa[:-3]
'abcdefghijklm'

Infine, possiamo convertire una Stringa in Lista utilizzando la funzione list(): questa
dividerà una stringa in una lista formata da tutti i caratteri che formano la stringa.

>>> list(alfa)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', '.',
'.', '.']

Ricapitolando:

 Liste e Stringhe possono essere gestite in maniera identica sotto molti aspetti
 La funzione len() ci restituisce la lunghezza di una Lista o Stringa passata come
parametro
 Per verificare se un elemento o un carattere è presente in una Lista o Stringa
usiamo gli operatori IN e NOT IN
 Possiamo utilizzare la funzione list() anche per dividere una stringa in una lista di
caratteri
16: I Metodi delle Liste

In questa puntata andremo a concludere il discorso iniziato nella lezione numero 14 sulle
Liste, introdurremo infatti svariati metodi legati a questo tipo di dato in modo da poter
ottenere il massimo da questo potentissimo strumento.

Questi metodi vanno ad aggiungersi a funzioni quali la funzione len() che abbiamo visto
nella lezione precedente, e alle altre modalità di gestione delle Liste utilizzate fin'ora.

Iniziamo anzitutto definendo una Lista, chiamiamola magari inventario, e andiamo ad


inserirci alcuni oggetti come se fossimo in un gioco di ruolo:

inventario = ["torcia", "spada", "pane elfico", "arco"]

I metodi delle liste si usano in questa maniera:

nome_lista.nome_metodo(eventuali parametri)

Metodo append()

Possiamo aggiungere elementi al nostro inventario mediante append() che andrà ad


aggiungere un nuovo elemento passato direttamente alla fine dell'elenco, in questo modo:

inventario.append("frecce")
Se andiamo ora a controllare l'inventario vediamo che abbiamo ora anche le frecce:

>>> inventario
["torcia", "spada", "pane elfico", "arco", "frecce"]
Possiamo combinare append() con la funzione input e riempire così il nostro inventario fin
che ci pare... creiamo una piccola funzione riempi_inventario():

def riempi_inventario():
inventario = []
oggetto = ""
while True:
oggetto = input('Cosa vuoi aggiungere all\'inventario? ')
if oggetto == "terminato":
break
else:
inventario.append(oggetto)

print("Gli oggetto presenti nell'inventario sono: " +


str(inventario))

riempi_inventario()
Metodo extend()

Supponiamo di avere due liste, chiamate lista_a e lista_b, e di voler aggiungere gli
elementi di lista_b a quelli presenti in lista_a. Possiamo utilizzare il metodo extend() per
questo scopo:

>>> lista_a = ["pippo", "pluto", "giacobbe"]


>>> lista_b = ["spam", "eggs", "bacon"]
>>> lista_a.extend(lista_b)

>>> lista_a
['pippo', 'pluto', 'giacobbe', 'spam', 'eggs', 'bacon']

Metodo remove()

Al contrario della funzione append() possiamo eliminare invece elementi dalla lista
mediante la funzione remove() utilizzando il valore dell'elemento che vogliamo rimuovere.

Creiamo una nuova lista:

>>> monty = ["spam", "eggs", "bacon", "bob", "alice", "pluto"]

Al contrario dell'istruzione del, in cui possiamo eliminare degli elemanti da una Lista a
partire dal loro indice:

>>> del monty[0]

>>> monty
["eggs", "bacon", "bob", "alice", "pluto"]

Utilizziamo quindi remove() in questa maniera:

>>> monty.remove("pluto")

>>> monty
["eggs", "bacon", "bob", "alice"]

Possiamo inoltre utilizzare pop() per eliminare l'ultimo elemento della lista:

>>> eggs = ["e","t","w","z"]


>>> eggs.pop()
'z'
>>> eggs
['e', 't', 'w']

Metodo sort()

Il termine "sort" è traducibile in Italiano come ordinare, o classificare. Questo metodo ci


consente di ordinare i valori all'interno di una Lista mediante ordine alfabetico in una lista
alfabetica, o numerico in caso di una lista numerica:

>>> alfabeto = ["z", "u", "a", "c", "v"]


>>> alfabeto.sort()
>>> alfabeto
['a', 'c', 'u', 'v', 'z']
>>> numeri = [32, 1, 15, 2, 22, 23, 56, 88]
>>> numeri.sort()
>>> numeri
[1, 2, 15, 22, 23, 32, 56, 88]

Potete anche ordinare gli elementi al contrario tramite il parametro reverse da passare a
sort(), così:

>>> numeri.sort(reverse=True)
>>> numeri
[88, 56, 32, 23, 22, 15, 2, 1]

O utilizzando direttamente reverse():

>>> spam = [1, 2, 3]


>>> spam.reverse()
>>> spam
[3, 2, 1]

Badate peró che sort() non è in grado di gestire una lista mista tra numeri e lettere... in
caso provassimo a fare ció otterremo un errore, provare per credere!

Metodo index()

Il metodo index() ci restituisce invece l'indice di un dato passato, contenuto all'interno della
lista; Sempre restando sulla lista numeri:

>>> numeri.index(22)
4
oppure

>>> numeri.index(88)
0
Metodo insert()

Infine parliamo ora del metodo insert(), che ci consente di aggiungere un valore a un dato
indice nella lista; i valori della lista si sposteranno quindi di posizione per fare spazio a
questo nuovo valore. Insert ci fornisce quindi un maggiore controllo rispetto al metodo
append().

Creiamo una nuova lista:

>>> feste = ["capodanno", "pasqua", "ferragosto", "natale"]

Al momento nella lista feste, all'indice 1 troviamo "pasqua". Volendo aggiungere


"carnevale" all'indice numero 1, usando insert() facciamo quindi:

>>> feste.insert(1,"carnevale")
>>> feste
['capodanno', 'carnevale', 'pasqua', 'ferragosto', 'natale']

...ed ecco che ora ad indice 1, troviamo carnevale!

Ricapitolando:

 Utilizziamo i Metodi associati alle liste per poterle gestire nel migliore dei modi
 Il Metodo append() ci consente di aggiungere un elemento alla fine della lista
 Il Metodo extend() ci consente di "estendere" una lista, con l'aggiunta di valori
provenienti da una seconda lista
 Il Metodo remove() invece di consente di rimuovere un elemento, a partire dal suo
valore
 Il Metodo pop() ci consente di eliminare l'ultimo elemento della lista
 Il Metodo sort() ci consente di riordinare gli elementi di una lista
 Il Metodo reverse() ci consente di invertire l'ordine degli elementi di una lista
 Il Metodo index() ci permette di ottenere l'indice di un elemento passato
 Il Metodo insert() ci consente di aggiungere un valore in una posizione prestabilita
17: I Dizionari

In questa lezione parleremo dell'ultimo tipo di dato della Serie, i Dizionari!

I dizionari sono un pò come le Liste che abbiamo visto nei capitoli precedenti, ma a
differenza delle Liste in cui a ciascun valore dell'elenco corrisponde un numero indice
progressivo, quindi da 0 in su, nei Dizionari ad ogni valore è associato un indice
particolare chiamato chiave, e siamo proprio noi a impostare questa chiave che potrà
essere di un qualsiasi tipo di dato eccetto liste e altri dizionari.

Per ogni valore all'interno del Dizionario avremo quindi una coppia chiave-valore: più che
considerarli come un tipo di dato in se, è bene considerare i Dizionari come una struttura
di dati.

Si tratta sicuramente della tipologia più complessa rispetto a tutte quelle analizzate fin'ora!

Andiamo a fare un esempio pratico in modo da rendere l'idea da un punto di vista visivo; i
Dizionari vengono definiti utilizzando parentesi graffe:

mio_dizionario = {"mia_chiave_uno": "mio_valore", "età": 24, 3.14:


"pi_greco", "primi": [1, 2, 3, 5, 7]}

Quindi con questa azione abbiamo definito una struttura di dati, contenente quattro di
quelle che abbiamo chiamato coppie chiave-valore, associate al nome "mio_dizionario".

>>> mio_dizionario
{"mia_chiave_uno": "mio_valore", "età": 24, 3.14: "pi_greco", "primi":
[1, 2, 3, 5, 7]}

Come vedete abbiamo utilizzato diversi tipi di valori, stringhe, interi e liste, associati
ciascuno ad una chiave univoca. Le chiavi nei Dizionari sono proprio il corrispettivo degli
indici nelle Liste: usiamo le chiavi per richiamare i valori ad esse associati.

Per ottenere il valore associato alla chiave "mia_chiave_uno" facciamo in questo modo:

>>> mio_dizionario["mia_chiave_uno"]
'mio_valore'

Stesso discorso vale per tutti gli altri valori presenti, richiamabili tramite le loro chiavi.
Proviamo a richiamare il valore associato alla chiave 3.14:

>>> mio_dizionario[3.14]
'pi_greco'

Per aggiungere una nuova coppia chiave-valore al nostro Dizionario facciamo in questa
maniera:
>>> mio_dizionario["nuova_chiave"] = "nuovo_valore"

>>> mio_dizionario
{'mia_chiave_uno': 'mio_valore', 'età': 24, 3.14: 'pi_greco', 'primi':
[1, 2, 3, 5, 7], 'nuova_chiave': 'nuovo_valore'}

Allo stesso modo possiamo sostituire il valore associato ad una chiave già presente nel
dizionario:

>>> mio_dizionario["età"] = 99
>>> mio_dizionario
{'mia_chiave_uno': 'mio_valore', 'età': 99, 3.14: 'pi_greco', 'primi':
[1, 2, 3, 5, 7], 'nuova_chiave': 'nuovo_valore'}
Facciamo ora una precisazione: a differenza delle Liste, in cui l'insieme di valori è un
insieme ordinato, i Dizionari sono elenchi di valori non ordinati.

Python riconoscerà quindi due dizionari come uguali se questi conterranno le stesse
coppie chiave-valore, anche se apparentemente non si trovano stesso ordine.

Per verificare se una chiave è presente o meno all'interno di un Dizionario possiamo


utilizzare gli operatori in e not in:

>>> "età" in mio_dizionario


True

>>> "zen" in mio_dizionario


False

Per eliminare una coppia chiave-valore possiamo utilizzare l'istruzione del:

>>> del mio_dizionario["mia_chiave_uno"]


>>> mio_dizionario
{'età': 99, 3.14: 'pi_greco', 'primi': [1, 2, 3, 5, 7], 'nuova_chiave':
'nuovo_valore'}

Definiamo ora un nuovo Dizionario, chiamiamolo ita_eng e inseriamoci proprio valori tipici
di un dizionario, ad esempio di un dizionario Italiano - Inglese:

ita_eng =
{"ciao":"hello","arrivederci":"goodbye","uova":"eggs","gatto":"cat","aran
cia":"orange"}

Esistono tre metodi associati ai Dizionari che ci consentono di ottenere in output una Lista
di tutte le chiavi presenti, o una Lista di tutti i valori presenti, o di entrambi allo stesso
tempo.
Questi metodi sono il metodo keys(), il metodo values() e il metodo items(): vediamo un pó
come utilizzarli:

Metodo keys()

Keys è letteralmente traducibile come "chiavi", ed è proprio il metodo che ci consente di


ottenere una Lista di tutte le chiavi presenti. Quindi per ottenere una Lista di tutte le chiavi
presenti nel nostro Dizionario ita_eng facciamo:

>>> ita_eng.keys()
dict_keys(['ciao', 'arrivederci', 'uova', 'gatto', 'arancia'])

Metodo values()

Values significa proprio valori; utilizziamo quindi questo metodo per ottenere una Lista di
tutti i valori presenti. Per ottenere una Lista di tutti i valori nel nostro Dizionario facciamo
quindi:

>>> ita_eng.values()
dict_values(['hello', 'goodbye', 'eggs', 'cat', 'orange'])

Metodo items()

Infine utilizziamo il metodo items() per ottenere una Lista di tutte le coppie chiavi-valore
presenti.

>>> ita_eng.items()
dict_items([('ciao', 'hello'), ('arrivederci', 'goodbye'), ('uova',
'eggs'), ('gatto', 'cat'), ('arancia', 'orange')])
Utilizzando questi metodi, ció che ci viene restituito è da considerare come un oggetto di
tipo "dict_keys", "dict_values", "dict_items"

Se abbiamo bisogno di una lista vera e propria possiamo utilizzare anche qui la nostra
cara funzione list():

>>> parole_eng = list(ita_eng.keys())


>>> parole_eng
['ciao', 'arrivederci', 'uova', 'gatto', 'arancia']

Possiamo inoltre utilizzare questi metodi in combinazione con un ciclo for, ad esempio per
far ciclare il nostro for per tutte le chiavi del dizionario facciamo:

>>> for chiave in ita_eng.keys():


... print(chiave)
...
ciao
arrivederci
uova
gatto
arancia

Ma cosa succederebbe qualora provassimo a richiamare un valore associato a una chiave


che non esiste nel nostro Dizionario? Be come è facile intuire, otterremo un errore, in
questo caso un'eccezione "KeyError", che comporterà il crash del programma:

>>> ita_eng["birra"]
Traceback (most recent call last):
File "stdin", line 1, in module
KeyError: 'birra'

Alcuni di voi a questo punto staranno sicuramente pensando: be abbiamo visto sia gli if e
gli else, che i try ed except, perché non utilizzare quelle istruzioni in combo con gli
operatori in e not in, per evitare il crash del programma?

Ad esempio:

>>> if "birra" in ita_eng.keys():


... print(ita_eng["birra"])
... else:
... print("Chiave non trovata!")
...
Chiave non trovata!

Be, il metodo funziona, ma è piuttosto lungo e noioso, sopratutto una volta che sappiamo
che i Dizionari dispongono di un metodo specifico, ideato proprio per situazioni come
queste: il Metodo get().

Richiamiamo il metodo get() sul nostro Dizionario ita_eng e passiamoli proprio la chiave
"birra":

>>> ita_eng.get("birra","Chiave non trovata, mi spiace!")


'Chiave non trovata, mi spiace!'

Proviamo anche a chiamare il metodo passandoli una chiave stavolta esistente:

>>> ita_eng.get("ciao","Chiave non trovata!!!")


'hello'

Quindi ció che il metodo get() fa è restituirci un valore di default come una sorta di
"paracadute d'emergenza", qualora la chiave richiesta non esista nel nostro Dizionario.
Parallelamente al metodo get(), ci saranno dei momenti in cui a seconda della complessità
di ciò che stiamo facendo, potremo avere la necessità di creare una coppia chiave valore
qualora una chiave non sia già presente e associata a un valore nel Dizionario.

Mi spiego meglio: sempre restando sull'esempio precedente, supponiamo di voler


verificare se è presente la chiave "birra" nel nostro Dizionario, che come sappiamo ora
non è presente:

>>> ita_eng
{'ciao': 'hello', 'arrivederci': 'goodbye', 'uova': 'eggs', 'gatto':
'cat', 'arancia': 'orange'}

Ma diciamo che stavolta vogliamo aggiungerla al dizionario assieme alla traduzione e in


maniera rapida!

Per fare questo possiamo usare il metodo setdefault():

>>> ita_eng.setdefault("birra", "beer")


"beer"

Quindi ció che setdefault() ha fatto è stato cercare la chiave "birra" all'interno del nostro
dizionario "ita_eng", e visto che la chiave non esisteva ha creato una coppia chiave-valore
col valore "beer" da noi passato.

>>> ita_eng
{'ciao': 'hello', 'arrivederci': 'goodbye', 'uova': 'eggs', 'gatto':
'cat', 'arancia': 'orange', 'birra': 'beer'}

Avremo anche in questo caso potuto creare un ciclo for, ma sarebbe stato piuttosto
macchinoso e superfluo, una volta che si conosce il metodo setdefault().

Ricapitolando:

 I Dizionari sono delle strutture di dati non ordinate, contenenti coppie


(chiave:valore)
 Sia Chiave che Valore sono scelti da noi in maniera arbitraria
 Conoscendone la Chiave, possiamo modificare, richiamare o eliminare il valore
associato
 Usiamo i metodi keys(), values() e items() per ottenere rispettivamente gli elenchi
delle chiavi, dei valori, o delle coppie chiave-valore
 Il metodo get() ci consente di ottenere un messaggio di default qualora la chiave
richiesta non esista, aggirando eventuali errori
 Il metodo setdefault() ci permette invece di creare una coppia chiave-valore qualora
la chiave passata non esista già
18: Metodi per Stringhe e Formattazione Avanzata

In questa nuova lezione approfondiremo la nostra conoscenza del tipo di dato testuale di
Python, le Stringhe.

Vorrei anzitutto iniziare da una nuova tipologia di concatenazione tra testo e variabili che è
appena stata introdotta in Python 3.7, chiamata in Inglese Formatted String Literals, che
va a migliorare il sistema di formattazione già presente in Python 3, rendendolo davvero di
una potenza sconvolgente!

Fin'ora quando abbiamo dovuto concatenare delle variabili con delle stringhe, abbiamo
utilizzato l'operatore + per unire i valori tra di loro, ad esempio:

>>> nome = "Jack"


>>> "Ciao " + nome
'Ciao Jack'

Per poter unire dei valori numerici inoltre, abbiamo sempre dovuto utilizzare la funzione di
supporto str()

numero = 18
>>> "Ciao " + nome + " questa è la lezione n" + str(numero)
'Ciao Jack questa è la lezione n18'

Piuttosto confusionale non vi pare? Ma tranquilli, con questo metodo che vi spiegheró ora
potrete tirare un sospiro di sollievo e cimentarvi nelle concatenazioni più disparate.

Per utilizzare questo nuovo sistema di formattazione, dovete iniziare la nuova stringa con
una f, che significa appunto formatted, e che informa Python di come deve interpretare le
istruzioni successive. Tutte le variabili che volete passare le passate tra parentesi graffe:

>>> f"Ciao {nome}, questa è la lezione n{numero}! Benvenuto!"


'Ciao Jack, questa è la lezione n18! Benvenuto!'

Fantastico non trovate? La facilità di utilizzo e di letture è a mio avviso sconvolgente!


Chiaramente potete anche utilizzare questa formattazione per assegnare questa
concatenazione di valori a una variabile:

>>> saluto = f"Ciao {nome}, questa è la lezione n{numero}! Benvenuto!"


>>> saluto
'Ciao Mike, questa è la lezione n18! Benvenuto!'

Possiamo inoltre effettuare operazioni numeriche in maniera veramente semplice:

>>> z = 5
>>> f"Il quadrato di {z} è {z * z}"
'Il quadrato di 5 è 25'

Esercitatevi e provate a vedere fino a dove è possibile utilizzare questa metodologia di


concatenazione! Ne rimarrete stupiti, garantito!

Andiamo ora a fare un elenco dei metodi per stringhe che troverete utilissimi e che vi
permetteranno di risparmiare tempo e codice.

>>> messaggio = "Fate il vostro gioco"

Direi anzitutto di iniziare con quelli che sono forse i miei metodi preferiti, mi riferisco
a startswith() e endswith().

Ció che questi due metodi fanno è controllare se la Stringa in analisi inizia oppure finisce,
con una parola o lettera passata come parametro. Questi metodi restituiscono valori
Booleani, quindi ricordiamolo, True o False.

>>> messaggio.startswith("Fate")
True
>>> messaggio.startswith("F")
True
>>> messaggio.starstwith("x")
False

>>> messaggio.endswith("gioco")
True
>>> messaggio.endswith("gioc")
False

Parliamo ora di isupper() e islower(): questi metodi controllano se tutte le lettere nella
stringa analizzata sono maiuscole o minuscole, e anche stavolta restituiscono valore True
o False in base al risultato dell'analisi:

>>> nome = "alice"

>>> nome.islower()
True

>>> nome = "BOB"


>>> nome.isupper()
True

>>> cane = "Lucky"


>>> cane.islower()
False

>>> cane.isupper()
False
Parallelamente potete ottenere la versione con le lettere tutte in maiuscolo o tutto in
minuscolo grazie ai metodi upper() e lower():

>>> nome.lower()
'bob'

>>> cane.upper()
LUCKY

Ma tenete a mente che in questo caso vi viene fornita una nuova versione della stringa, e
non una modifica alla stringa stessa:

>>> cane
'Lucky'

Questo perché le stringhe sono valori immutabili.

Parleremo bene dei dettagli tecnici su questo tipo di dato in un altro video più avanti, per
ora tenete a mente che volendo modificare il contenuto vero e proprio, dovete riassegnare
la variabile:

>>> cane = cane.upper()

>>> cane
'LUCKY'

Andiamo avanti introducendo isalpha() e isdecimal(): come i nomi suggeriscono, questi


metodi controllano se una stringa è composta da sole lettere o soli numeri rispettivamente:

>>> parola = "asd"


>>> parola.isalpha()
True

Se avessimo aggiunto anche solo uno spazio nella stringa, isalpha() avrebbe restituito
False:

>>> parola = "asd "


>>> parola.isalpha()
False

>>> num = "123"


>>> num.isdecimal()
True

Per verificare se invece la stringa è composta o da numeri o da lettere allo stesso tempo
usiamo isalnum():
>>> spam = "asd123q"
>>> spam.isalnum()
True

Questi metodi sono fantastici se implementati in un ciclo For.. ad esempio, supponiamo di


avere una stringa composta da svariati caratteri e di voler estrarre solo lettere e numeri:

>>> eggs = "@qwe54!?+"


>>> for carattere in eggs:
... if carattere.isalnum() == True:
... print(carattere)
...
q
w
e
5
4

Per verificare se una stringa o un carattere è invece uno spazio bianco, usiamo isspace():

>>> bacon = "qwe rty"


>>> bacon[3].isspace()
True

Bene, passiamo ora agli ultimi due metodi che analizzeremo in questo video, split() e
join():

Il metodo join() è utilissimo quando ci troviamo con una Lista di stringhe o parole, e
vogliamo unirle tra di loro per formare una nuova stringa risultante.

>>> compiti = ["portare il cane a passeggio", "finire di studiare", "fare


la spesa", "lavare i panni"]

Anzitutto il metodo join viene chiamato su una stringa, che vogliamo utilizzare come
collante diciamo tra le varie parole o stringhe vogliamo unire:

>>> ", ".join(compiti)


'portare il cane a passeggio, finire di studiare, fare la spesa, lavare i
panni'

>>> da_fare = "oggi devo: " + ", ".join(compiti)

>>> da_fare
'oggi devo: portare il cane a passeggio, finire di studiare, fare la
spesa, lavare i panni'
Possiamo anche chiamare join() su un carattere newline per separare i vari elementi con
una nuova riga:

>>> da_fare = "\n".join(compiti)

>>> print(da_fare)
portare il cane a passeggio
finire di studiare
fare la spesa
lavare i panni

Al contrario, col metodo split() possiamo dividere una stringa su cui viene richiamato, in
una lista di stringhe, in questo modo:

>>> serie_numerica = "1492-1984-123311-555"


>>> serie_numerica.split("-")
['1492', '1984', '123311', '555']

Quindi stavolta tra le parentesi di split() mettiamo il carattere o parola o stringa insomma,
che segnala a split() dove effettuare questa suddivisione.

>>> citazione = "Nel mezzo del cammin di nostra vita"


>>> citazione.split(" ")
['Nel', 'mezzo', 'del', 'cammin', 'di', 'nostra', 'vita']

Ricapitolando:

 Possiamo effettuare interpolazioni tra variabili e stringhe mediante il sistema


"Formatted String Literals"
 Come per le Liste, anche le Stringhe dispongono di tantissimi metodi associati
 startswith() e endswith() restituiscono True se la stringa inizia o finisce in una
determinata maniera
 Usiamo isupper() e islower() per verificare se una Stringa è composta solamente da
maiuscole o minuscole
 Usiamo upper() e lower() per ottenere una versione della Stringa tutta in maiuscolo
o minuscolo
 Con isalpha() e isdecimal() verifichiamo se una stringa è composta da sole lettere o
soli numeri
 Con isalnum() verifichiamo se una stringa è composta solamente da lettere e
numeri
 Con isspace() verifichiamo la presenza di spazi bianchi
 Usiamo join() e split() rispettivamente per unire varie stringhe in una nuova, o
dividere una stringa in una lista di stringhe
19: Come Creare, Leggere e Scrivere un File Testuale

Benvenuti a tutti a questa lezione numero 19, in questo episodio parleremo di Files,
ovvero di come sia possibile leggere e scrivere da e su un file di testo salvato nel nostro
Computer.

Dovete sapere che esistono due modalità di scrittura in Python e queste


sono write e append.

Utilizzando write, ogni volta che andiamo ad aggiungere del contenuto, tutto ció che era
precedentemente salvato all'interno del file andrà perso, mentre utilizzando append, che
significa proprio aggiungere, il contenuto aggiunto si sommerà a quanto già presente nel
file.

Iniziamo partendo dalla prima modalità. Anzitutto ci serve qualcosa da scrivere, quindi:

contenuto = "Oggi è una bellissima giornata!"

Ció che dobbiamo fare ora è specificare il file testuale su cui vogliamo scrivere, e per fare
questo facciamo:

file1 = open("esempio1.txt","w")

open() è chiaramente una funzione, e i parametri che le passiamo sono il nome del file su
cui vogliamo scrivere e la modalità di scrittura, in questo caso "w" da write appunto.

Il nome del file puó essere preceduto dal suo percorso all'interno del sistema, ad
esempio file1 = open("C:\\esempio1.txt","w")

Nella definizione del percorso utilizziamo due slash e non uno, in quanto come ricorderete
dalle lezioni precedenti questo è il carattere escape, e quindi per essere interpretato
correttamente ha bisogno di essere a sua volta giustificato.

Visto che noi abbiamo specificato solamente il nome, Python andrà a cercalo nella sua
cartella di lavoro di default. Se il file non esiste, come in questo caso, open() lo creerà per
noi.

Ora che Python sa a che file ci stiamo riferendo possiamo effettuare la scrittura vera e
propria, usando il nome della variabile associata ad open(), nel nostro caso file1:

file1.write(contenuto)
file1.close() # ricordatevi sempre di chiudere i vostri file

Andando a controllare nel nostro file esempio1.txt, ecco che troviamo la frase appena
scritta, "Oggi è una bellissima giornata!"
Utilizziamo ora la seconda modalità di scrittura, append, per aggiugnere del testo a quello
già presente. Creiamo del nuovo materiale da aggiungere:

nuova_stringa = "python è una bomba"

La procedura è la stessa rispetto a quella mostrata fin'ora, l'unica cosa che va a cambiare
è il secondo parametro passato a open():

file1 = open("esempio1.txt", "a")


file1.write(nuova_stringa)
file1.close()

Andando a ricontrollare nel nostro file di testo, ecco che ora troviamo la nostra nuova
aggiunta:

"Oggi è una bellissima giornata!python è una bomba"

Come vedete Python non va a capo automaticamente, dovrete specificarlo voi mediante
un carattere newline:

file1 = open("esempio1.txt","a")
file1.write("\nNuova_riga")
file1.close()

Questo è tutto ció che vi serve sapere per iniziare a scrivere sui file, passiamo ora alla
terza e ultima parte di questa lezione, la lettura da file; ad open() verrà passato stavolta il
parametro "r", da read:

var_lettura = open("esempio1.txt","r").read()
print(var_lettura)
"Oggi è una bellissima giornata!python è una bomba
Nuova_riga"

Volendo, invece di leggere tutto il contenuto del file come un'unica stringa, potete ottenere
una lettura per righe apportando una piccola modifica a quanto abbiamo scritto in
precedenza:

var_lettura = open("esempio1.txt","r").readlines()
Grazie a readlines(), ora in var_lettura è presente una lista composta
dalle varie righe del file:
var_lettura
["Oggi è una bellissima giornata!python è una bomba","\nNuova_riga"]

Prima di chiudere vi do delle info bonus, iniziamo importando il modulo della Standard
Library dedicato al sistema operativo, il modulo os:
import os

Tra le tante funzionalità presenti in questo modulo potete verificare la cartella su cui
Python sta lavorando mediante:

os.getcwd()

e cambiarla con:

os.chdir(/percorso/file)

Questo vi faciliterà in maniera considerevole il lavoro... specialmente se state lavorando


con più di un file per volta!

Ricapitolando:

 Per leggere o scrivere su un file dobbiamo prima aprirlo mediante al funzione


open()
 Ad open() passiamo due parametri: il nome e percorso del file + la modalità di
accesso ("w", "a", "r")
 Il contenuto di un file aperto in modalità "w" verrà eliminato
 Dopo aver aggiunto del contenuto, i file vanno sempre chiusi mediante close()
20: i Files: Come Copiarli, Spostarli, Rinominarli o Cancellarli

Parleremo di come sia possibile Copiare, Spostare, Rinominare o Cancellare qualsiasi tipo
di File nei vostri programmi Python.

Anzitutto utilizzeremo delle funzioni presente nel modulo shutil, abbreviativo di Shell
Utilities:

import shutil

Anzitutto vediamo un pò come possiamo copiare i file, supponiamo di voler copiare un file
chiamato "1492.txt" da una cartella chiamata "lezione20", ad una sottocartella chiamata
"storia".

Per fare questo usiamo la funzione copy di shutil:

shutil.copy("C:\\lezione20\\1492.txt", "C:\\lezione20\\storia")

Dobbiamo specificare due parametri, primo, il nome del file che vogliamo copiare con
relativo percorso, e secondo la cartella di destinazione.

Supponiamo ora di voler spostare invece un file chiamato "napoleone.txt", dalla cartella
"lezione20" alla sottocartella "storia". In questo caso usiamo la funzione move di shutil:

shutil.move("C:\\lezione20\\napoleone.txt", "C:\\lezione20\\storia")

Per poter rinominare oppure cancellare un file usiamo invece funzioni presenti nel modulo
os:

import os

Supponiamo di avere, sempre nella cartella "lezione20", un file "cancellami.txt", possiamo


fargli compiere il suo destino mediante la funzione unlink() di os. State attenti quando
utilizzate unlink() perché si tratta di una funzione potentissima, il file verrà infatti
permanentemente eliminato dal vostro hard disk:

os.unlink("C:\\lezione20\\cancellami.txt")

Ed ecco che il file è sparito! Volendo invece di unlink() potete utilizzare remove(), che è la
stessa cosa!

Supponiamo inoltre di avere anche un file "rinominami.txt", e possiamo rinominarlo tramite


la funzione rename():

os.rename("C:\\lezione20\\rinominami.txt", "file_rinominato.txt")
Ricapitolando:

 I Moduli os e shutil contengono le funzioni necessarie a lavorare coi file


 shutil.copy() ci consente di copiare un file
 shutil.move() ci consente di spostare un file
 os.uplink() [oppure os.remove()] ci permette di eliminare un file in maniera definitiva
 os.rename ci permette di rinominare un file
21: Come Usare le Cartelle

I moduli necessari sono os e shutil:

import os, shutil

Anzitutto è bene sapere in che cartella ci troviamo, per fare questo facciamo:

os.getcwd() # getcwd == Get Current Working Directory

Che restituisce la cartella di lavoro in cui ci si trova attualmente: se provate questo


comando su Windows, otterrete la cartella di lavoro di Default di Python.

Una volta che sappiamo in che cartella ci troviamo, è utile conoscerne il contenuto, che
possiamo ottenere grazie a os.listdir(). Questa funzione ci mostra un elenco degli
elementi e delle sottocartelle presenti nella cartella in cui stiamo operando.

Possiamo spostarci da una cartella all'altra utilizzando:

os.chdir("C:\\") # chdir == CHange DIRectory

Possiamo creare una o più cartelle con os.makedirs():

os.makedirs("C:\\nuova__cartella")

os.makedirs("C:\\lezione21\\informatica")
os.makedirs("C:\\lezione21\\sistemi")
os.makedirs("C:\\lezione21\\security")

Anche rinominare è facilissimo grazie a os.rename():

os.rename("nuova__cartella","lezione21")

Per spostare una cartella con relativi file, utilizziamo la funzione shutils.move():

shutils.move("C:\\lezione21\\security", "C:\\lezione21\\informatica\\")

"C:\\lezione21\\informatica\\security"

Mentre volendo invece copiare una cartella con relative sottocartelle facciamo:

shutil.copytree("C:\\lezione20","C:\\lezione21\\lezione20copia")
Alla funzione passiamo stavolta il nome di una nuova cartella in cui vogliamo effettuare la
copia, e copytree() creerà eventuali cartelle intermedie.
Infine la funzione più potente di tutte!

Volendo eliminare un intero albero di cartelle e relativi file usiamo shutil.rmtree():

shutil.rmtree("lezione21\\lezione20copia")
22: Come Navigare il File System

Ciao a tutti e benvenuti a questa lezione numero 22, parleremo oggi di una delle modalità
più pratiche per navigare il filesystem del nostro computer con Python, grazie al modulo os
e alla funzione os.walk().

Fin'ora abbiamo visto che volendo controllare il contenuto di una cartella, possiamo
utilizzare la funzione listdir(), che però non fa distinzione tra file e sottocartelle, presenti nel
percorso passato.

E in quelle situazioni in cui dobbiamo scansionare una parte sostanziosa del sistema,
magari alla ricerca di un determinato tipo di file con cui vogliamo operare, potremo
combinare listdir() e altre funzioni, ma il procedimento diventerebbe abbastanza lungo.

Una delle modalità più veloci e pratiche per fare ciò è utilizzare invece la funzione walk()
del modulo os, capirete bene come funziona a breve.

Questa analizza il percorso passato in maniera ricorsiva, cioè dove ogni analisi viene
suggerita da quella precedente, cercando sottocartelle e file.

La funzione os.walk() viene usata in combinazione con i cicli for: ad ogni ciclo, abbiamo 3
elementi: la cartella in cui ci troviamo al momento, una lista delle sottocartelle presenti, e
una lista dei file, al ciclo successivo la funzione entrerà in una delle sottocartelle e ripeterà
il processo, questo prosegue fino a che non si arriva alla fine dell'albero.

Immaginiamo di voler scansionare la cartella in cui ci troviamo, e vogliamo avere un


elenco esaustivo di file e sottocartelle e di tutti i file e le altre cartelle presenti al loro
interno:

import os

for cartella, sottocartelle, files in os.walk(os.getcwd()):


print(f"Ci troviamo nella cartella: '{cartella}'")
print(f"Le sottocartelle presenti sono: '{sottocartelle}'")
print(f"I files presenti sono: {files}")
print()

Con questi file e sottocartelle potete poi fare tutto quello che volete, ad esempio:
Supponiamo di voler andare alla ricerca di tutti i file .py presenti in questa sezione, e di
ottenere quindi in output solamente un elenco di questi file, tralasciando tutti gli altri che
verranno incontrati:

for cartella, sottocartelle, files in os.walk(os.getcwd()):


print(f"Ci troviamo nella cartella: '{cartella}'")
print(f"Le sottocartelle presenti sono: '{sottocartelle}'")
for file in files:
if file.endswith(".py"):
print(file)
print()
Io qui ho effettuato un esempio piuttosto semplice, ma capirete di certo che le potenzialità
di questa funzione sono altissime!

Arrivati a questo punto della serie vi trovate con tantissimi strumenti a vostra disposizione,
vi invito quindi ad esercitarvi cercando di essere creativi!
23: Installare Moduli di Terze Parti con PIP

Impareremo come estendere le funzionalità di Python installando Moduli Esterni creati da


terzi, presenti nel Python Package Index, e faremo ció sia su Windows che su Linux.

Nella pagina principale sono in evidenza gli ultimi moduli che sono stati caricati o
aggiornati, e abbiamo quindi data/nome/descrizione funzionalità.

Per una ricerca più accurata cliccate su Browse Packages, che vi restituirà un elenco in
cui potrete scegliere in base alla categoria di appartenenza.

I moduli del Python Package Index vengono installati da terminale, tramite un programma
chiamato PIP, che già avete nel vostro computer in quanto è presente nel pacchetto di
installazione di Python che abbiamo installato nella prima lezione della serie.

Su Windows, apriamo quindi il prompt dei comandi(CMD) e navighiamo fino alla cartella
Scripts di Python e una volta dentro facciamo:

pip install Django

In questo caso pip starà scaricando e installando Django, uno dei Web Framework più
famosi di Python, con cui sono scritti servizi famosi come Instagram.

Ora verifichiamo la presenza di Django e la versione installata, aprendo la Shell di Python


e importando il Modulo:

import Django
django.VERSION

Passiamo ora su Linux, e questa procedura dovrebbe funzionare senza problemi anche su
Mac OS:

Qui la questione è ancora più semplice che su Windows: ci basta aprire un terminale e
digitare lo stesso comando usato su Windows, solo che ora non abbiamo bisogno di
essere nella cartella degli Scripts:

pip install ipython

Attenzione: su sistemi Linux e Mac capita spesso di avere 2 versioni di Python installate
nel proprio sistema (2.X e 3.X) e per questo motivo, a seconda della vostra personale
configurazione di sistema potreste dover usare il comando "pip3" invece di "pip" per
installare moduli utilizzabili con Python 3.
24: Come Inviare eMail con Python

ATTENZIONE: a seguito dell'aggiornamento delle politiche di sicurezza di Google,


per poter utilizzare quando descritto nel tutorial seguente potreste aver bisogno di
aggiungere un'eccezione per l'utilizzo di applicazioni esterne dalle impostazioni del
vostro account di posta!

Ciao a tutti ragazzi e ragazze! Oggi impareremo quanto è facile automatizzare l'invio di
eMail all'interno dei nostri programmi in Python.

Ci sono varie situazioni in cui questo torna utile, specie in programmi importanti o che
girano su macchine che stanno sempre connesse, capita che ci sia la necessità di essere
notificati in tempo reale, e pensate a quanto tempo tra copia e incolla vi fa risparimare
quando vi trovate con dei file pieni di indirizzi a cui dovete poi inviare un messaggio.

Tutto questo è reso possibile grazie al modulo smtplib, che quindi importiamo all'istante:

import smtplib

Questo modulo rappresenta l'implementazione in Python del protocollo SMTP, che sta per
Simple Mail Transfer Protocol.

Creiamo del contenuto che ci interessa inviare:

oggetto = "Subject: Urgente! da leggere subito!\n\n"


contenuto = "connettiti al Server che è meglio..."
messaggio = oggetto + contenuto

Volendo avreste potuto scrivere oggetto e contenuto nella stessa variabile, ma penso che
così sia più pulito.

Quindi dobbiamo specificare il server SMTP del servizio a cui vogliamo connetterci, e la
relativa porta di servizio associata, in questo Tutorial useremo gMail:

email = smtplib.SMTP("smtp.gmail.com", 587)

Ora possiamo connetterci al server, con:

email.ehlo()

A questo punto avviamo un canale criptato tramite:

email.starttls()
dove tls sta per Transport Layer Security, ovvero il protocollo crittografico che mette in
sicurezza la nostra comunicazione col Server.

A questo punto possiamo effettuare il Login vero e proprio usando i nostri Username e
Password:

email.login("username", "password")

Ora siamo pronti per inviare la nostra eMail:

email.sendmail("mittente","destinatario",messaggio)
Una volta che il messaggio è inviato, interrompiamo la connessione col Server:

email.quit()

Chiaramente tutta la potenza di questi comandi viene liberata quando vengono utilizzati
all'interno di uno script, che potrete poi salvare e richiamare ogni volta che vi serve!
25: Come Usare Archivi Zip in Python

Utilizzeremo due moduli della Standard Library, il modulo os per navigare nel sistema, e il
modulo zipfile che si occuperá di comprimere e decomprimere.

import os, zipfile

Iniziamo partendo dalla creazione di un archivio, ovvero vediamo come si crea un archivio
zip nei nostri programmi in Python. In maniera simile a quanto visto nella lezione sui file di
testo facciamo:

# creazione/apertura in modalità scrittura


archivio = zipfile.ZipFile('mio_archivio.zip', "w")

# aggiunta file e compressione


archivio.write("/file/da/comprimere/urls.py",
compress_type=zipfile.ZIP_DEFLATED)

# chiusura
archivio.close()

Tentare di aggiungere del contenuto ad un archivio già esistente, utilizzando il parametro


"w" ne cancellerebbe tutto il contenuto. Per aggiungere file in maniera sicura si utilizzata il
parametro "a", da append:

# apertura in modalità aggiunta


archivio = zipfile.ZipFile('mio_archivio.zip',"a")

archivio.write("manage.py", compress_type=zipfile.ZIP_DEFLATED)

archivio.close()

Ricordate: l'archivio va sempre chiuso!

Passiamo ora all'estrazione del contenuto di un archivio zip, facciamo ciò grazie a
extractall();

# apertura dell'archivio per estrazione


archivio = zipfile.ZipFile('mio_archivio.zip')

# estrazione di tutti i file


archivio.extractall("/percorso/dove/estrarre/volendo/nuova/cartella")

# chiusura
archivio.close()

Potete anche estrarre un singolo file usando extract() invece di extractall():


# apertura dell'archivio per estrazione
archivio = zipfile.ZipFile('mio_archivio.zip')

archivio.extract("file","/percorso/dove/estrarre/volendo/nuova/cartella")

archivio.close()

Infine possiamo leggere delle preziose informazioni riguardo al contenuto di un file zip,
qualora ci serva visionarlo dall'interno dei nostri programmi per poter effettuare delle azioni
specifiche con ciascun file presente:

# apertura dell'archivio per lettura


# archivio = zipfile.ZipFile('mio_archivio.zip')

# effettua una lista del contenuto del'archivio


archivio.namelist()
["manage.py","urls.py"]

urlsinfo = archivio.getinfo("urls.py")
urlsinfo.filesize
urlsinfo.compress_size

# chiusura
archivio.close()
26: Come Leggere File CSV

In questo nuovo tutorial spiegheremo come fare a leggere file CSV tramite Python.

Per chi non conoscesse questa tipologia di file, CSV sta per Comma Separated Values:
si tratta di una delle estensioni più utilizzate sopratutto in ambito scientifico o quando si ha
comunque a che fare con grosse quantità di dati.

Si tratta in sostanza di tabulati stile foglio di calcolo e per questo motivo vi sarà
probabilmente capitato di lavorarci su Excel o Calc.

Nel sito italiano dedicato agli open-data è possibile scaricare i vari database anche e
spesso proprio in questo formato.

Per questa lezione ho appositamente scaricato il database dei monumenti italiani, quindi
lavoreremo proprio con uno di questi file CSV, un database contenente dati sui vari
monumenti della nostra nazione.

Per chiudere questa breve parte introduttiva, aggiungo che per quanto la traduzione
letterale del nome sia: "Valori Separati Da Virgole", si tratta di un formato un pó bizzarro,
in quanto il carattere delimitatore può essere sia una virgola o un punto e virgola o un
altro carattere:

Ad esempio, se creo un file di testo e ci inserisco:

1,mattino,colazione
2,pomeriggio,pranzo
3,sera,cena

E poi lo salvo con estensione CSV, questo potrà essere interpretato anche da CALC
proprio come un tabulato, in cui i valori sono stati separati appunto da virgole. Volendo
avrei potuto utilizzare ad esempio dei punti e virgola o dei trattini, o dei TAB.

Non tutti i file CSV saranno quindi necessariamente uguali, ma fintanto che hanno
quest'estensione, potete lavorarci su Python: facciamo questo tramite un modulo apposito
che ci viene fornito dalla Standard Library, il modulo CSV:

import csv
Anzitutto dobbiamo aprire il nostro file, e facciamo questo con la funzione open():

import csv
with open("./mappa_monumenti_italia.csv", newline="", encoding="ISO-8859-
1") as filecsv:

Abbiamo quindi il percorso del nostro file, specifichiamo il carattere newline come una
stringa vuota, e poi ho aggiunto anche la codifica dei caratteri con encoding="ISO-8859-1":
quest'ultimo parametro potrebbe non essere necessario a seconda del file e del sistema
con cui state lavorando, io l'ho aggiunto per aggirare un errore che mi veniva restituito
dalla console.

Ora che abbiamo il nostro bel file sotto tiro, possiamo finalmente iniziare ad utilizzare il
modulo CSV.

Per leggerlo utilizziamo la funzione reader() che restituisce un oggetto di tipo reader,
ovvero lettore, che cicla per tutte le righe del nostro file CSV.

Alla funzione reader() passiamo due parametri: il file da leggere e il delimitatore delle
colonne del file:

import csv
with open("./mappa_monumenti_italia.csv", newline="", encoding="ISO-8859-
1") as filecsv:
lettore = csv.reader(filecsv,delimiter=";")
print(lettore)

<_csv.reader object at 0x7f1a5fe10198>

Ora possiamo iniziare a fare tutto ció che vogliamo col nostro file. Vediamo un pó da cosa
è composto l'header, ovvero la prima riga del nostro file:

import csv
with open("./mappa_monumenti_italia.csv", newline="", encoding="ISO-8859-
1") as filecsv:
lettore = csv.reader(filecsv,delimiter=";")
header = next(lettore)
print(header)

['Longitudine', 'Provincia', 'Comune', 'Tipo', 'gid', 'Anno inserimento',


'Nome', 'Latitudine', 'Identificatore in OpenStreetMap', 'Data e ora
inserimento', 'Regione', '']

Come vedrete si tratta semplicemente di una lista di stringhe: ciascuna stringa


rappresenta quindi una colonna della nostra tabella.

Supponiamo di voler ottenere l'elenco di tutti i monumenti presenti nella regione Toscana,
e le corrispondenti coordinate, così da poter poi controllare istantaneamente la posizione
su Google Maps.

Possiamo isolare le varie colonne che ci servono tramite il sistema di indicizzazione delle
liste: possiamo creare quindi una sottolista d'interesse a partire da questi colonne, molto
semplicemente:

import csv
with open("./mappa_monumenti_italia.csv", newline="", encoding="ISO-8859-
1") as filecsv:
lettore = csv.reader(filecsv,delimiter=";")
# header = next(lettore)
# print(header)
dati = [(linea[10],linea[6],linea[7],linea[0]) for linea in lettore
if linea[10]=="Toscana" and linea[6] != ""]

E una volta che abbiamo la nostra sottolista, possiamo utilizzare un pó di formattazione


per rendere i dati più human friendly:

import csv
with open("./mappa_monumenti_italia.csv", newline="", encoding="ISO-8859-
1") as filecsv:
lettore = csv.reader(filecsv,delimiter=";")
# header = next(lettore)
# print(header)
dati = [(linea[10],linea[6],linea[7],linea[0]) for linea in lettore
if linea[10]=="Toscana" and linea[6] != ""]
for monumento in dati:
print (f"{monumento[:2]} -- Coordinate:
{monumento[2]},{monumento[3]}")

Ora possiamo aprire google maps e semplicemente copiare le coordinate del monumento
che ci interessa, oppure effettuare ulteriori analisi!

Come vedete potete fare proprio tutto quello che volete con questi database una volta che
ne avete ottenuto accesso. Inoltre, una volta appreso questo semplice sistema per la
lettura dei CSV, anche il lavoro d'ufficio sarà estremamente semplificato, garantito!

Vi invito quindi a farvi un giro per il sito italiano dedicato agli open-data e cercare i dataset
che più ritenete interessanti e provate ad esercitarvi.
27: Passare parametri da riga di comando con SYS.ARGV

In questa lezione spiegheremo come passare parametri al nostro script tramite riga di
comando, usando la funzione argv del modulo sys.

argv sta per "argument variable": si tratta semplicemente di una lista di stringhe
contenente i parametri che vengono passati allo script quando lo state richiamando. Se
avete utilizzato degli script in Python in passato, con buona probabilità sapete chiaramente
a cosa mi sto riferendo!

Avete presente quando, all'avvio di uno script da riga di comando, date qualche opzione
tipo:

python nome_script.py yes -b

Be, con buona probabilità, quello script sta utilizzando il modulo sys.

Il primo parametro della lista argv, quindi il valore ad indice 0, è sempre il nome dello
script.

Il resto dei valori è ordinato secondo l'ordine in cui sono stati passati.

Facciamo una prova:

import sys
print(sys.argv)

Ora salviamo il file e richiamiamolo da riga di comando:

>>> python lezione_26.py primo_parametro secondo_parametro 3

['lezione_26.py', 'primo_parametro', 'secondo_parametro', '3']

Una volta capito questo concetto, possiamo fare qualcosa come:

import sys
nome_script, primo, secondo = sys.argv

print(f"""
Il nome dello script è: {nome_script}
Il primo parametro passato è: {primo}
Il secondo parametro passato è: {secondo}""")

E ottenere quindi:
>>> python lezione_26.py alfa bravo

Il nome dello script è: lezione_26.py


Il primo parametro passato è: alfa
Il secondo parametro passato è: bravo

Di norma è bene controllare che allo script siano stati passati abbastanza parametri prima
di assegnarli ad eventuali variabili, quindi tenendo a mente che il primo parametro è
sempre il nome dello script possiamo fare:

if len(sys.argv) < 3:
print("Devi passare due parametri allo script!")
print("Sto uscendo...")
sys.exit()

Una volta che avete i parametri potete chiaramente farci tutto quello che vi pare. Ad
esempio:

if primo == "info":
print("Questa è la lezione 26, dedicata a SYS.ARGV")

oppure:

# nel file lezione_26.py

def sommatoria(a,b):
somma = int(a) + int(b)
print(f"La somma dei due valori è: {somma}")

sommatoria(primo,secondo)
# richiamiamo il file lezione_26.py

>>> python lezione_26.py 12 24


La somma dei due valori è: 36
INDICE

 01: Introduzione e Installazione di Python 3.6


 02: IDLE e Operazioni Numeriche
 03: Variabili e Stringhe
 04: Conversioni di Tipo, Print(), Input() e Primo Programma
 05: Diagrammi Di Flusso, Logica Booleana e Operatori di Comparazione
 06: Controllo di Flusso: if, elif ed else!
 07: Il Ciclo While e le Istruzioni break e continue
 08: Il Ciclo For e la Funzione range()
 09: CheckPoint: Costruiamo una Calcolatrice con Python
 10: I Moduli della Standard Library
 11: Scrivi le Tue Funzioni
 12: Variabili Globali e Variabili Locali
 13: A prova di crash - Come gestire gli Errori
 14: Liste e Tuple
 15: Similarità tra Liste e Stringhe

 16: I Metodi delle Liste


 17: I Dizionari
 18: Metodi per Stringhe e Formattazione Avanzata
 19: Come Creare, Leggere e Scrivere un File Testuale
 20: i Files: Come Copiarli, Spostarli, Rinominarli o Cancellarli
 21: Come Usare le Cartelle
 22: Come Navigare il File System
 23: Installare Moduli di Terze Parti con PIP
 24: Come Inviare eMail con Python
 25: Come Usare Archivi Zip in Python
 26: Come Leggere File CSV
 27: Passare parametri da riga di comando con SYS.ARGV

Potrebbero piacerti anche