gestione errori con cicli if

Documenti analoghi
OOP: Object Oriented Programming

Appunti Python. Sakya

Programmazione in Python. Moreno Marzolla

Quando usiamo Python in modo interattivo in genere e' lo shell utilizzato che gestisce l'indentazione e la deindentazione.

19 - Eccezioni. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Corso di Laboratorio di Sistemi Operativi

Il linguaggio Python

Programmazione 2. Introduzione al corso

ancora sui moduli e sulla loro importazione

Laboratorio di Python

Laboratorio di Python (con Linux)

Logica booleana, Costrutto IF

GESTIONE DEGLI ERRORI

Controllo di flusso negli script: if-then-else

Lezione 5: Controllo del flusso e costrutti avanzati

Python. Valerio Perticone

Costrutti condizionali e iterativi

Fondamenti di Programmazione

Introduzione al Python

Introduzione alla programmazione in Python: Parte II

Raccolta di tutorial Python #1: basi e Tkinter dal sito francescomilanese.com SOMMARIO

7 - Programmazione procedurale: Dichiarazione e chiamata di metodi ausiliari

Shell: variabili di sistema. Per visualizzare il valore di tutte le variabili d ambiente si usa il comando set

Laboratorio di Python

CORSO LINUX PER LA CERTIFICAZIONE LPI ESSENTIALS

Input/Output. Console e File.

Avviate l interprete Python selezionandolo dal menu dei programmi. Una volta avviato, l interprete presenta un cursore in cui inserire comandi

Laboratorio di Programmazione Lezione 2. Cristian Del Fabbro

Usare Python in Linux

Asserzioni in Java fondamenti

Eccezioni. Comportamento di default (esempio) Propagazione delle eccezioni

Laboratorio di reti I

Fondamenti di Informatica 1. Prof. B.Buttarazzi A.A. 2010/2011

VBA è un linguaggio di scripting derivato da Visual Basic, da cui prende il nome. Come ogni linguaggio ha le sue regole.

Laboratorio di Informatica

Si può scrivere un programma anche utilizzando un editor di testo (Blocco Note, WordPad, ) ricordandosi comunque di salvarlo con l estensione.py.

STRUTTURE DI CONTROLLO DEL C++

Tecnologie dell'informazione e della Comunicazione

Laboratorio di Python

Gestione delle eccezioni

Programmazione Orientata agli Oggetti e Scripting in Python

OCA JAVA 7 SE PROGRAMMER I DOCENTE: DOTT. FAUSTO DELL ANNO

Ricordiamo come si definisce una funzione

Foglio Elettronico Lezione 1

Rappresentazione degli algoritmi

Laboratorio di Python

18 - Classi parzialmente definite: Classi Astratte e Interfacce

Esercitazione n 2. Obiettivi

Programmazione orientata agli oggetti La classe Object, metodi e classi final, this. Object

Corso di Linguaggi di Programmazione

Input. Il tipo char Alcune modalità di acquisizione di input. Laboratorio di Programmazione - Luca Tesei

Il linguaggio Java. Le eccezioni

RETI DI CALCOLATORI Linguaggio Java: Eccezioni

Metodi Informatici per la Biologia

LABORATORIO DI PROGRAMMAZIONE 1 CORSO DI LAUREA IN MATEMATICA UNIVERSITÀ DEGLI STUDI DI MILANO III Indice

Programmazione orientata agli oggetti: le classi

Programmazione multi threaded in Python. Linguaggi dinamici A.A. 2010/2011 1

Introduzione a. Funzioni di Ingresso e Uscita. Compilazione

I set (iterable, mutable) INDICE

6 - Blocchi e cicli. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Le basi del linguaggio Java

Introduzione al C++ (continua)

osservazione: 1 MCD(m,n) min(m,n) = si provano i numeri compresi tra 1 e min(m,n) conviene iniziare da min(m,n) e scendere verso 1

Sistemi Operativi Anno Accademico 2011/2012. Segnali: Interrupt software per la gestione di eventi asincroni

Numeri e stringhe. Andrea Passerini Conoscenze informatiche e relazionali Corso di laurea in Scienze dell Ingegneria Edile

Gestione delle eccezioni in Java

Ingegneria degli Algoritmi (II parte pratica)

un file in formato FASTA contenente un elenco di sequenze una espressione regolare una indicazione se si tratta di DNA,RNA,proteine

Programmazione ad Oggetti

Introduzione al MATLAB c Parte 3 Script e function

Unità Didattica 2 Linguaggio C. Espressioni, Operatori e Strutture linguistiche per il controllo del flusso

FONDAMENTI DI INFORMATICA C Linguaggio Java: Eccezioni

Programmazione a blocchi. Algobuild Prof. Sergio Roselli

Concetti Base Eccezioni Eccezioni e Metodi Gerarchia di Eccezioni. Java: Eccezioni. Damiano Macedonio

Liste, dizionari e tuple

Programmazione in Java (I modulo)

MATLAB Elementi di grafica Costrutti di programmazione

Python Avanzato. Loris Michielutti. Loris Michielutti

Lezione 6 Introduzione al C++ Mauro Piccolo

Insegnamento di Laboratorio di algoritmi e strutture dati

Tipi di dato strutturati: Array

Laboratorio di Informatica

Programmazione a oggetti

Essendo una sequenza, condivide le operazioni su sequenza viste per le stringhe

Metodi di Analisi dei Dati Sperimentali. AA 2009/2010 Pier Luca Maffettone. Elementi di Matlab

Concetti base programmazione. Antonio Gallo

Un piccolo esempio: script

Un esempio di if annidati

Laboratorio Progettazione Web Il linguaggio PHP Lezione 6. Andrea Marchetti IIT-CNR 2011/2012

28/02/2014 Copyright V. Moriggia

Programmazione Orientata agli Oggetti. Emilio Di Giacomo e Walter Didimo

9 - Array. Programmazione e analisi di dati Modulo A: Programmazione in Java. Paolo Milazzo

Laboratorio di Python (con Linux)

Rendere Python un linguaggio di scripting migliore

Ingegneria degli Algoritmi (II parte pratica)

Informatica B. Sezione D. Scuola di Ingegneria Industriale Laurea in Ingegneria Energetica Laurea in Ingegneria Meccanica

Strutture blocco. Indentazione e istruzione blocco

Introduzione all uso delle funzioni in C++

HOMEWORKS. in modo che il programma stampi N ripetizioni della stringa HelloWorld (su righe diverse), con N inserito dall utente.

Rudimenti di Python. senza rodimenti di Python

Transcript:

INDICE gestione errori con cicli if Le eccezioni... except: c2f con gestione errore generico... except tipoerrore:... esempio esercizio esercizio Gerarchia delle eccezioni sollevare un'eccezione (raise) sollevare un'eccezione di tipo specifico passare il controllo di un'eccezione sollevata da altri Uso degli attributi di un'eccezione assert gestione errori con cicli if consideriamo lo script c2f.py della lezione sulla gestione dei parametri da riga di comando. che riportiamo per intero qui sotto. """ esempio di gestione di un paragrafo da riga di comando con sys.argv """ def c2f(c): return 9.*C/5+32. if name ==' main ': import sys C = float(sys.argv[1]) print(c2f(c)) vediamo cosa succede se invoco lo script senza pasargli parametri: Il messaggio di errore è significativo ed in particolare ci dice: il modulo/script in cui c'e' l'espressione/statement che ha provocato l'errore. il numero di riga del codice sorgente e la riga stessa il tipo di errore (IndexError) Analogamente, se invoco lo script passando come parametro un carattere o una stringa...... l'interprete ci segnala un ValueError Potrei pensare di gestire la situazione con una serie di cicli if. ad esempio per gestire l'index error potrei eseguire un test simile: In [ ]: """ c2f_if.py esempio di gestione di un paragrafo da riga di comando con sys.argv e gestione index error con ciclo if """ def c2f(c): return 9.*C/5+32. if name ==' main ': import sys #Aggiungo questo!!! if len(sys.argv) < 2 : # testo se c'e' almeno un parametro print('specificare almeno un parametro') # se non c'e' stampo un messaggio di errore sys.exit # ed esco

#fine aggiunta C = float(sys.argv[1]) print(c2f(c)) gestire la situazione che porta al ValueError implica un test sul tipo di dato che deve essere compatibile con la conversione a float In [ ]: """ c2f_if_2.py esempio di gestione di un paragrafo da riga di comando con sys.argv e gestione index error con ciclo if """ def c2f(c): return 9.*C/5+32. if name ==' main ': import sys #Aggiungo questo!!! if len(sys.argv) < 2 : # testo se c'e' almeno un parametro print('specificare almeno un parametro') # se non c'e' stampo un messaggio di errore sys.exit(1) # ed esco #fine aggiunta if not sys.argv[1].isnumeric(): #funziona solo con gli interi... print('parametro di comando non numerico') sys.exit(1) C = float(sys.argv[1]) print(c2f(c)) Per una gestione soddisfacente dei parametri passati a float dovremmo prevedere sia il separatore decimale sia un numero passato in notazione scientifica e la questione potrebbe farsi complicata. Sulla base del motto 'è più facile chiedere scusa che chiedere il permesso' sono state introdotte le eccezioni Le eccezioni C'è un altro modo per gestire gli errori, che è indicato come metodo standard ed è preferibile specialmente nel caso di programmi articolati nei quali la gestione di un errore puo'/deve essere effettuata in porzioni di codice distinte da quella in cui l'errore ha avuto origine (cosa non possibile con semplici cicli if). Come si è già detto, le eccezioni fanno riferimento al paradigma di programmazione noto come EAFP che sta per Easier to ask for forgiveness than permission. Cioe' piuttosto che cercare di immaginarsi tutte le condizioni che possono dare luogo ad un errore si gestisce l'errore una volta che questo si è manifestato. Quando si manifesta un errore il normale flusso del programma si interrompe ed il controllo passa al meccanismo di gestione delle eccezioni che cerca il gestore più appropriato per l'errore che si è manifestato.... except: la sintassi del costrutto base per la gestione delle eccezioni è la seguente: except: c2f con gestione errore generico Nella forma di base, quella con except e nessun tipo di errore specificato, qualsiasi errore scaturisca dalle istruzioni dopo try viene gestito dalle istruzioni indentate dopo except: In [ ]: """ c2f_eccezioni_00.py esempio di gestione di un paragrafo da riga di comando con sys.argv e gestione errori con le eccezioni

00 - gestione non diversificata per tipo di errore """ def c2f(c): "funzione di conversione da Celsius a Fahrenheit" return 9.*C/5+32. if name ==' main ': import sys C = float(sys.argv[1]) except: print("errore nel passaggio della temperatura C da riga di comando")#messaggio di errore sys.exit(1)#esco print('{0} C sono {1} F'.format(C,c2f(C))) vediamo cosa succede se non passo alcun parametro o se passo una stringa: la forma... except:... è relativamente poco utilizzata perché gestisce qualsiasi tipo di errore e non permettere una differenziazione di gestione in base al tipo di problema che si verifica.... except tipoerrore:... In realtà il costrutto try... except e' piu' articolato e permette di distinguere per tipologia di errore La sintassi da utilizzare è la seguente: except : except :...... else: finally: vediamo come e' possibile modificare ulteriormente lo script c2f... In [ ]: """ c2f_eccezioni_01.py esempio di gestione di un paragrafo da riga di comando con sys.argv e gestione errori con le eccezioni 01 - gestione diversificata per tipo di errore e blocchi else e finally """ def c2f(c): "funzione di conversione da Celsius a Fahrenheit" return 9.*C/5+32. if name ==' main ': import sys C = float(sys.argv[1]) except IndexError: print("specificare almeno un parametro da riga di comando") except ValueError: print("il parametro specificato non e' un numero") else: print('{0} C sono {1} F'.format(C,c2f(C))) finally: print('fine') vediamo il risultato:

vediamo che tipi di errore definisce Python (se volete provare da shell interattivo usare builtins e non builtin) In [4]: for s in dir( builtin ): if s.find('error')>=0: print(s) ArithmeticError AssertionError AttributeError BufferError EOFError EnvironmentError FloatingPointError IOError ImportError IndentationError IndexError KeyError LookupError MemoryError NameError NotImplementedError OSError OverflowError ReferenceError RuntimeError SyntaxError SystemError TabError TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError ValueError WindowsError ZeroDivisionError Le eccezioni in Python sono realizzate come una gerarchia di classi Se io raccolgo con except una eccezione di un tipo specificato (ad esempio ArithmeticError) in realtà raccoglierò tutte le eccezioni derivate da essa (ZeroDivisionError) esempio In [44]: def dividi(a,b): return a/b def usadividi(a,b): q = dividi(a,b) except ZeroDivisionError: print("errore in dividi({0},{1}): b deve essere diverso da zero".format(a,b)) except TypeError: print("errore in dividi({0},{1}): tipi di operandi non compatibili con la divisione".format(a,b))

else: print('dividi({0},{1}) = {2}'.format(a,b,q)) usadividi(2,2) usadividi(2,0) usadividi('ciao',1) errore in dividi(2,0): b deve essere diverso da zero dividi(2,2) = 1.0 errore in dividi(ciao,1): tipi di operandi non compatibili con la divisione Il precedente esempio illustra la delocalizzazione della gestione di un errore mediante eccezioni. In altre parole l'errore è gestito in una funzione esterna rispetto a quella in cui c'e' l'espressione che fa scaturire l'errore. è da notare che in questo caso non è stato necessario intervenire sul codice della funzione dividi!! ciò è particolarmente significativo nel caso di funzioni molto complesse ed articolate... esercizio consideriamo la formula già utilizzata in un esempio precedente, che esprime la posizione di un punto uniformemente accelerato in funzione dell'istante t, dell'accelerazione a e delle condizioni iniziali v0 e s0 per t=0: In [ ]: def posiz(t,a,v0,s0): return s0 + v0*t + 0.5*a*t**2 creare uno script posiz_eccezioni_00.py che: gestisce i parametri da riga di comando usando sys.argv, fissandone l'ordine non definisce alcun parametro di default e gestisce il caso di argomento mancante usa le eccezioni per gestire il caso di parametro non numerico se tutto va bene restituisce una stringa ('posiz(t={0}, a={1}, v0={2}, s0={3}) = {4}'.format(t,a,v0,s0,posiz(t,a,v0,s0))) prima di uscire stampa comunque la stringa fine esercizio creare uno script posiz_eccezioni_01.py che: gestisce i parametri da riga di comando usando il modulo getopt definisce dei valori di default per i quattro parametri t,v,a,s0 usa le eccezioni per gestire il caso di parametro non numerico usa le eccezioni per gestire il caso di parametro opzione sconosciuta e nel caso stampa a video un messaggio in cui si riassumono le modalità di utilizzo del programma (vedi immagine sotto) se tutto va bene restituisce una stringa ('posiz(t={0}, a={1}, v0={2}, s0={3}) = {4}'.format(t,a,v0,s0,posiz(t,a,v0,s0))) prima di uscire stampa comunque la stringa fine Gerarchia delle eccezioni NB: le gerarchia di classi nell'immagine sottostante non è aggiornata

con il modulo inspect verifichiamo che la figura sopra si riferisce ad una precedente versione di Python... In [1]: Out[1]: import inspect inspect.getmro(zerodivisionerror) (builtins.zerodivisionerror, builtins.arithmeticerror, builtins.exception, builtins.baseexception, builtins.object) sollevare un'eccezione (raise) Il comando raise puo' essere utilizzato i due modi sollevare un'eccezione di tipo specifico posso sollevare una eccezione specifica con il comando raise seguito dall'eccezione: In [2]: raise IndexError('IndexError generato con raise') --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-2-2814c2e16525> in <module>() ----> 1 raise IndexError('IndexError generato con raise') IndexError: IndexError generato con raise passare il controllo di un'eccezione sollevata da altri usando raise senza fargli seguire una eccezione specifica permette di non interrompere la propagazione di un'altra eccezione eventualmente intercettata.

nel seguente esempio si usano entrambe le forme di raise In [5]: def generaindexerror(propaga): #genero l'eccezione raise IndexError('index error') except IndexError:#intercetto l'eccezione localmente if not propaga: print("raccolgo localmente ma non propago l'eccezione") else: print("raccolgo localmente e propago l'eccezione") raise #propago l'eccezione propago l'eccezione In [6]: generaindexerror(propaga=true) except: print("raccolgo globalmente l'eccezione") non propago l'eccezione raccolgo localmente e propago l'eccezione raccolgo globalmente l'eccezione In [7]: generaindexerror(propaga=false) except: print("raccolgo globalmente l'eccezione") raccolgo localmente ma non propago l'eccezione Uso degli attributi di un'eccezione a volte è necessario interagire direttamente con l'entità eccezione. e' possibile farlo associandogli un nome con as quando la si raccoglie con except in tal modo è possibile utilizzare eventuali attributi associati all'eccezione nel momento in cui la si è sollevata. In [10]: #genero un'eccezione passandogli come argomento un dizionario dictinfo={'autore':'nicola','contesto':'lezione 09'} myex = IndexError(dictinfo) raise myex except IndexError as err: #raccolgo l'eccezione e gli associo un nome #uso gli attributi della specifica eccezione raccolta print('dir(err)=',dir(err)) print('args[0]=') for k,v in err.args[0].items(): print(k,' : ',v) dir(err)= [' cause ', ' class ', ' context ', ' delattr ', ' dict ', ' doc ', ' eq ', ' format ', ' ge ', ' getattribute ', ' gt ', ' hash ', ' init ', ' le ', ' lt ', ' ne ', ' new ', ' reduce ', ' reduce_ex ', ' repr ', ' setattr ', ' setstate ', ' sizeof ', ' str ', ' subclasshook ', ' traceback ', 'args', 'with_traceback'] args[0]= autore : Nicola contesto : lezione 09 assert L'istruzione assert si usa in un contesto un po'diverso dalle eccezioni tanto è che viene trascurata dall'interprete quando si usa python in modalità ottimizzata.

Mentre le eccezioni si usano per la gestione degli errori in qualche modo 'attesi', le asserzioni si usano come metodo 'difensivo' in grado di evidenziare situazioni potenzialmente pericolose in un determinato punto del programma. Le asserzioni non si riferiscono ad uno specifico insieme di istruzioni (come quelle nel blocco try di un costrutto per la gestione delle eccezioni). Piuttosto le asserzioni si riferiscono ad una condizione che può (ma non dovrebbe) manifestarsi in uno specifico punto del programma. La sintassi del costrutto assert è la seguente: assert condizione[, espressione] Nel caso la condizione dia luogo a False allora viene sollevato un AssertionError che ha per eventuale argomento l'espressione opzionale. vediamo un esempio: In [7]: #... #x è una variabile che rappresenta una quantità che deve essere positiva #altrimenti qualcosa è andato storto in precedenza e potrebbe andare storto in futuro Ciò equivale a: x = -1 assert x>0,'attenzione: x negativo (x={0})'.format(x) --------------------------------------------------------------------------- AssertionError Traceback (most recent call last) <ipython-input-7-58ed7a6a7cb0> in <module>() 5 x = -1 6 ----> 7 assert x>0,'attenzione: x negativo (x={0})'.format(x) AssertionError: Attenzione: x negativo (x=-1) In [8]: if x<0: raise AssertionError('Attenzione: x negativo (x={0})'.format(x)) --------------------------------------------------------------------------- AssertionError Traceback (most recent call last) <ipython-input-8-787dbc8f3428> in <module>() 1 if x<0: ----> 2 raise AssertionError('Attenzione: x negativo (x={0})'.format(x)) AssertionError: Attenzione: x negativo (x=-1) salvo che per il fatto che l'eccezione viene sollevata anche nel caso di interprete funzionante in modalità ottimizzata. NOTA: l'effetto di assert è quello di sollevare un eccezione e quindi non ha senso usare questo costrutto quando un'eccezione verrebbe comunque ed immediatamente sollevata, come nell'esempio sotto: In [ ]: def indicizza(l,i): assert i>= len(l),'fuori margini di l' ## inutile!! return l[i]