Com ja hem vist als exercicis fets fins ara, és freqüent i fins i tot probable que l'usuari acabi fent alguna cosa que no havíem tingut en compte quan varem escriure el codi. Com a conseqüència d'això, el programa s'atura donant un missatge d'error a la pantalla de l'intèrpret. El nostre objectiu com a programadors és intentar eliminar els casos als que el programa s'interromp sense donar-li a l'usuari la possibilitat de corrergir la seva acció i tirar endavant.
Per fer-ho, haurem de pensar en dues coses:
Controlar totalment (tots els casos) el flux del programa.
Afegir la captura d'excepcions per tots aquells errors no controlables.
Control total del flux
Per entendre aquest aspecte, tornarem a pensar en l'exercici de matrius com a exemple. Es tracta d'entendre que, per molt sofisticat que sigui el menu que hem dissenyat perquè l'usuari triï l'operació desitjada, sempre es podran produir accions que no hem contemplat.
Recordem que la darrera versió de la calculadora de matrius tenia la següent estructura:
Aquest codi espera que l'usuari introdueixi un nombre natural entre 1 i 5. Pero que passa si escriu un "6"? O si escriu "suma" en comptes de "1"? O si pitja intro abans d'introduir cap nombre? Doncs a tots els casos anteriors el programa aturarà la seva execució i treurà per pantalla un missatge d'error que possiblement l'usuari no entendrà.
Per evitar aquest problema, s'ha d'afegir l'opció "else" (que vol dir "a tots els altres casos") al nostre condicional. D'aquesta manera el programa tindrà una opció per continuar l'execució.
Cal notar que el comandament "continue" fa que la present iteració s'aturi i passi automàticament a la següent, a on tornarà a fer la pregunta a l'usuari.
Captura d'excepcions
La captura d'excepcions ens serviex per detectar tot tipus de problemes que poden fer que l'execució del programa s'aturi, donant-li al codi una sortida.
Anem a veure un exemple amb la calculadora de matrius. Utilitza el teu programa per calcular la matriu inversa d'A:
Si tot ha anat com toca, t'haurà aparegut el següent missatge:
a on es pot veure a la darrera línia clarament quin ha estat el problema ("ZeroDivisionError"). La nostra matriu A té un determinant nul, |A|=0. Això vol dir que A és una matriu singular (degenerada) que no té matriu inversa. Per tant, no és que hagi res que no estigui funcionant dins del codi (és un cas matemàticament ben conegut), sinó que el nostre programa no contempla el que ha de passar en aquestes condicions.
És en aquestes situacions quan la captura d'excepcions ens resulta útil, ja que aquests errors es poden "capturar" pel seu tipus abans de que s'aturi el programa, fent que reaccioni enviant un missatge o fent alguna cosa més concreta.
Al nostre cas, per aconseguir que el problema no torni a passar es pot fer el següent:
a on es pot veure que hem modificat les funcions "inv()" i "impr()". La resta del codi no apareix, però ha queadt exactament com estava.
La sintaxi de la captura d'excepcions fa que l'algoritme en primer lloc intenti fer algo ("try") i, si no pot perquè ha aparegut qualque tipus de problema, consulti les possibles excepcions ("except").
Dins la funció "impr()" es pot veure que la paraula clau "except" no apareix acompanyada per cap complement. Això vol dir que, sigui quin sigui el tipus de problema que comparegui, sempre executarà la mateixa instrucció ( print("No hi ha matriu resultant") ).
D'altra banda, dins "inv()" es pot llegir "except ZeroDivisionError", que li indica al programa que, només al cas en que es produeixi un intent de dividir entre una variable que tengui valor nul, s'executi el codi de dins l'excepció. És a dir, només s'executarà si el tipus de l'error coincideix amb el tipus de l'excepció.
De tipus d'execepcions n'hi ha molts. A la següent taula es pot veure un recull dels més freqüents:
Cal notar que als exemples només hi ha una sentència "except", però als nostres programes podem posar tantes com considerem necessàries. Fins i tot, és una pràctica freqüent introduir excepcions de diferents tipus i per finalitzar introduir una genèrica (només la paraula clau "except" sense especificació d'errada), per tal de capturar tots els possibles errors.
Exercicis:
1. Afegeix el codi necessari a la calculadora de matrius i a la de nombres reals per controlar totalment el flux dels programes.
2. Afegeix el codi necessari a la calculadora de matrius i a la de nombres reals per capturar les excepcions que consideris possibles.