3. Estructures de control
3.1. Sentències
Les sentències són cadascuna de les ordres que es donen a un programa. Si recordem un algorisme és una seqüencia de passos, doncs be, una sentència especificarà un (o diversos) d'aquests passos per transcriure un algorisme a un programa.
Les sentències poden ser de distint tipus, ateses a la seua naturalesa:
- Importació. Són les sentències (habitualment a l'inici del programa) que indiquen quines llibreries del programa van a fer-se servir. Com ja hem vist, les llibreries són un conjunt de funcions que ja estan a punt per a fer-se servir.
| Text Only | |
|---|---|
- Declaratives. Són les sentències que es fan servir per a indicar alguna cosa. No representen cap acció dins d'un programa. Per exemple destaquen la declaració de variables o les de funcions:
| Text Only | |
|---|---|
- Assignacions o Instruccions sequencials. Són les instruccions propiament dites. Serveixen per a fer un càlcul i assignar-lo a una variable. El càlcul es pot fer amb qualsevol dels operadors estudiats, i habitualment guardar el valor calculat en una variable. També poden simplement fer una acció sense guardar-la en cap lloc, com puga ser mostrar alguna cosa per pantalla (
print), emetre un so o esborrar un fitxer. - Sentències de control. És el que estudiarem en aquest tema. Són aquelles instruccions que ens permeten moure el fluxe continuo o de dalt cap avall d'un programa, permetent-nos prendre desicions i repetir una sèrie d'intruccions les vegades que calga. Es tracta de les bifurcacions i dels bucles
3.2. Sentències alternatives
3.2.1. Condicions simples
Com ja em comentat, l'ordre en el fluxe del programa és de dalt cap avall i d'una en una.
Si volem alternar entre un o altre camí deurem de fer alguna mená de pregunta o condició, de manera que si passa una condició farem una cosa i cas que no pase farem altra. La sintaxi en Python és:
Bifurcacions simples en Python
On:
condicio1icondicio2son expressions relacionals, que ens donen com a resultatTrueoFalse. Si s'acompleix lacondicio1s'executa les sentencies indentades desprès dels:(sentencies 1,2,...). Molt important el tabular be aquelles sentències dins de cadaif- Si la
condicio1ha donat com ha resultatFalsellavors s'avalua lacondicio2, dins delelif.elifve a ser la contracció deelse - if. Si lacondició2ésTruellavors s'executa el bloc indentat (sentencies a, b ,...). Poden apareixer molts o cap blocelif, per la qual cosa és opcional. - Sinó s'ha acomplit cap condicio (ni
ifnielif) finalment s'executarà el blocelse, com alternativa a niguna de les anteriors. Aquest bloc també és opcional.
L'equivalent en Java és el següent:
Bifurcacions simples en Java
| Java | |
|---|---|
Exercici resolt Demanar un numero a l'usuari i indicar si el número és positiu.
Exercici resolt Demanar un numero a l'usuari i indicar si el número és positiu o negatiu.
Exercici resolt Indicar la situació administrativa d'una persona (estudiant, treballador o jubilat) depenent de la seua edat.
3.2.2. Condicions compostes
Com s'ha anomentat, desprès del if o del elif ha d'aparèixer una condició, la qual ha d'avaluar-se a True o False. La condició pot ser simple, però també la podem fer composta i més complexa mitjançant els operadors and, or i not, seguint les taules de la veritat que vegerem als temes anteriors.
Exercici resolt Demanar un numero a l'usuari i indicar si parell i està entre 10 i 20 (incloses)
3.2.3. Condicions niuades
Si tenim diverses condicions que complir, com hem vist abans les podem composar amb els operadors lògics. El tema és que, sinó es compleix la condició no sabrem si és per la primera condició o per la segona (mirar l'exemple anterior). Llavors en aquests cassos el que podem fer és posar condicions simples niuades (una dins de l'altra).
Programa alternatiu a la solució anterior:
3.3. Bucles
De vegades a un programa ens interessarà pel motiu que siga repetir un conjunt d'instruccions. El nombre de repeticions pot saber-se a priori o no. Cas de saber-ho, direm que estem en bucles incondicional, i cas de no saber-ho en bucles condicionals, ja que la repetició es farà fins que s'acomplisca una condició.
3.3.1. Bucles condicionals. while
Imaginem la següent situació. A un programa volem calcular l'àrea i el cercle d'una circumferència, per la qual cosa hem de demanar el radi de la mateixa.
Primera solució
Aquest programa semble correcte a priori, perà que passa si a l'executar li donem al radi un valor de -4, per exemple:
Quin rang de valors és acceptable per al radi? La resposta és nombres majors que zero. Anem a intentar solucionar-ho amb el que sabem.
Segona solució:
Com vegem ara sols fem el càlcul quan el radi és positiu. El problema és que quan és negatiu el programa acaba. Llavors el que podem fer quan l'usuari pose un radi negatiu és tornar-lo a demanar. Què pot passar? que el tornen a posar negatiu 😞...
La gran pregunta és quants cops caldrà demanar el radi fins assegurar-nos que el radi siga positiu?. Resposta: No ho sabem. Llavors haurem de demanar el radi fins tenir un valor positiu,
Tercera solució
Vist aquest exemple, les conclussions són:
- Farem servir un bucle condicional o
whilequan el número de repeticions no depenguen del programador ni del problema, sinó de l'usuari o de les condicions d'execució, que cada cop son distintes. - Abans d'escriure la condició haurem d'inicialitzar la varible(s) que apareixen a la condició. En aquesta inicialització la condició ha de ser
True, de manera que puguem entrar al bucle. - Dins del bucle haurem de modificar d'alguna manera eixa variable, de manera que en algun moment la condició sigui
False, per poder eixir del bucle. - Mai sabrem a priori quantes vegades s'executarà
Sintaxi de bucle whileen Python:
S'avalua la condició, ocòrre que:
- La condició és
True→ entrem al bucle, s'executen totes les accions, des de la1fins lan. En acabar es torna a avaluar la condició. - La condició és
False→ s'acaba el bucle, i llavors s'executaacció_fora_del_bucle.
Convergencia
Com s'ha comentat abans, l'execució del bucle acaba quan la condició és False. Observa els següents exemples i intenta pensar que passa quan s'executen:
0 per sempre:
Això ocorre perquè no hem escrit cap ordre que modifica la n (no hem modificat la condició). Això ens provoca un bucle infinit. Modifiquem-ho:
Ja hem modificat la n, i per tant la condició, però la sortida ara és:
En aquest cas la condició és que n<100, sent n=0. Nosaltres (per error 🙃) modifiquem la n restant-li un en cada iteració. Llavors és impossible que mai arribe a ser igual o superior a 100. Tornem a estar en bucle infinit. Solucionem-ho
Finalment s'imprimeix:
El que tenim que observar és que la variable que controla la condició (n) ha de convergir al valor final (100). Observar també que el numero 100 no s'imprimeix, ja que quan n==100 la condició és False, i ja s'ix del bucle.
3.3.2. Bucle incondicional. Bucle for
Aquest tipus de bucles es fa servir quan sabem a priori el numero de vegades que volem repetir les instruccions que formen part del bucle. En aquest tipus de bucles hi ha una variable índex que ens permet portar un compte del nombre de repeticions que portem. En Python aquest bucle ha canviat bastant respecte a altre llenguatges com Java, llavor anem a explicar-ho en els dos llenguatges.
3.3.3. for en Java
En Java el for te 3 apartats. Es fa servir una variable que s'inicia a un valor inicial. Desprès es posa una condició, com si fos un while i finalment es posa un increment que es farà cada cop que s'executen les accions. El bucle anirà repetint-se fins que la condició siqui false
aquest bucle imprimeix del 0 al 9 (recorda que el 10 ja no forma part, ja que no acompleix la condició)
aquest bucle imprimeix del 0,2,4,6 i 8. L'increment en aquest cas es fa de 2 en 2
aquest bucle mostrarà 30,25,20,15,10,5,0. Comença de 30 i va baixant de 5 en 5 fins a 0 (inclòs)En Python existeix també una variable que controla el bucle. La diferència és que hem d'indicar la seqüencia de valors que volem que prenga dita variable en forma de llistat o tupla. Parlarem de les tuples o llistats més endavant. Tot això s'aconsegueix amb la funció range(), que és molt completa i admet molts argument, per la qual cosa anem a fer un miniapartat per a explicar-la.
range()
La seua sintaxi és range([start,] stop[, step]):
start→ indica des de quin número comença la seqüencia. Si no s'indica s'escomença desde0.stop→ indica fins a quin límit arribarem. La seqüencia acaba en l'anterior astop.step→ indica de quant en quan es modifica la seqüencia. Si no es posa res va de 1 en 1 de manera ascendent. Aquest atribut no pot ser zero
Example
3.3.4. for en Python
Vista la funció range() podem veure el bucle for en Python:
Es repeteix el bucle executant-se les accions on la varaible pren com a valor cada element de la llista. Si volem que la llista sigui una serie de números, ho substituirem per la funció range() vista anteriorment. Vegem els següents exemples, comparant-ho amb Java.
Exercici resolt Imprimir la taula de multiplicar de 3
Exercici resolt Imprimir els numeros parells des del 40 fins al 0 (no inclòs)
Veurem més avantages del for quan estudiem els vectors o tuples.
3.3.5. Bucles infinits
Com hem vist abans, moltes vegades per error podem escriure bucles infinits, cosa que pot portar el sistema informàtic a inestabilitats. Però, moltes vegades ens interessarà programa un bucle infinit i, de fet, és fan servir moltíssim. Pensem per exemple en un caixer automàtic. El programa està en una espera infinita a que algun usuari vaja a executar algun procediment. Quan un usuari va i posa la targeta el programa propiment dit l'aten. Quan l'usuari acaba d'operar, el caixer es torna a posar en dita espera infinita. Vejam l'algorsime:
Com aconseguim programar un per_sempre que hem indicat. La resposta es senzilla però no evident. Posar una condició que sempre siga certa i que sigui inmutable (que no es modifique)
D'aquesta manera entrem al bucle i passe el que passe dins de les accions, el True com és una constant no serà mai modificat, i llavors no eixirem del bucle.
NOTA: No te sentit fer en algun lloc while False:, ja que en eixe bucle no s'entra mai (millor no escriure res).
Ruptura de bucles. break, continue i else als bucles
Tot això dels bucles infinits està molt be, però com podem eixir d'un bucle infinit? La resposta ens la dona la sentència break, que ens permet eixir d'un bucle (independentment de la condició, siga infinit o no):
breakinterromp l’execució del bucle i seguim per la instrucció seguent fora del bucle.continuefa que el programa comence altra iteració, encara que no s’haja acabat l’actual. Per tant les línies que hi han dins d’un bucle per davall del continue no s’executen. Cas d’estar dins d’unfor, anirem a l’increment de la variable comptadora o al següent element de la llista.elses'afig un bloc adicional a un buclewhileque s'executarà quan hem eixit del bucle debut a la falsetat de la condició del mateix, i no quan hem eixit per unbreak. No és gaire intuitiu.
!!! Example Exemple
| Python | |
|---|---|
Aquest programa sols te sentit acadèmic, per entendre que farà cada cosa:
- Imprimim el numero.
- Si els numeros son inferiors a 10 passem al següent nuúmeo (
continue). Fixa't que ens botem tot el que queda dins del bucle - Si es parell ho mostrem
- En arribar al 15 acabem el bucle (
break), de manera que del 16 al 19 ja no es fa res més.
| Text Only | |
|---|---|
!!! notes NOTES:
- Les sentències
breakicontinuesempre es posaran dins d'unif, ja que sinó s'executaran sempre dins del cos del bucle. - El
breakpermet eixir del bucle més niuat que hi ha. Si per exemple estem dins de un bucle niuat i volem acabar en tots els bucles, necessitarem dosbreak(un per cada bucle)
3.3.6. Bucle de demanar dades
Una de les parts més importants a l'hora de programar és demanar dades a l'usuari, i penseu que l'usuari serà una gran font d'errors del nostre programa. Penseu que dins del sistema informàtic, qui més errors provoca és l'usuari, ja que fa clic on no toca, posa lletres quan correspon números i mai llig la documentació ni els misstges d'error dels programes. És per això que deguem de ser molt cautelosos a l'hora de validar la informació que ens dona. Par a practicar-ho anem a fer un exemple complet i ens servirà també per a introduir el concepte d'excepcions.
Exercici resolt Volem fer un programa que demana un número i calcula el doble del mateix. Volem forçar que el número sigui positiu. En acabar preguntarà a l'usuari si vol eixir o no, tinguent com a possibles respostes so n. Cas de no voler sortir repetirem el mateix procés.
Solució 1 Fem el programa que demana un número i calcula el doble del mateix
Mirem que passa a l'executar:
| Text Only | |
|---|---|
Ocórre que:
- si podem tenir números negatius,
- el programa demana un número, fa l'operació i acaba.
Millora 1 Preguntem a l'usuari si vol acabar
Per a fer aquesta millora anem a fer un bucle infinit, on posarem al cos del bucle el que hem programat anteriorment, afegint la pregunta a l'usuari si vol acabar o no, i en cas de voler acabar, trencarem el bucle.
| Python | |
|---|---|
A l'executar apareix:
| Text Only | |
|---|---|
Ocórre que:
- Encara permet números negatius
- Permet tot tipus de lletres com a resposta. Amb la 's' eixim, però seguim amb la
n, laki altres.
Millora 2. Validació dels inputs Per a fer aquesta millora anem a fer un bucle per a cada entrada de dades, fins permetre valors vàlids: números positius en la primera entrada i unas s o n en la segona.
A l'executar comprovem que tot està funcionant de manera correcta:
3.3.7. else en bucles
La sentència else normalment va precedida d'un if com hem vist al seu moment, però en Python pot anat precedida d'un bucle. Quan es fa servir amb bucles les ordres que posem al else s'executaran sempre que no s'haja executat un break. És una manera de controlar si el bucle ha acabat per ell mateix o per un break
| Text Only | |
|---|---|
La part del else s'executarà sols quan el bucle ha acabat de manera normal:
- En un
whileper que la condició ésFalse - En un
forper que s'han recorregut els elements de la llista - Sols te sentit posar
elseen bucles que tinguenbreak. Sinó tenenbreakeixe codi s'executa sempre
3.3.8. La sentència pass
La sentència pass és fa servir quan volem deixar alguna zona del programa sense codi, be perquè estem a les fases inicials del programa i ho deixem per a desprès, be per millorar la llegibilitat. Simplement és una sentència que no fa res. Exemples:
else, però de moment l'escric i més endavant veurem.
pass es fa servir allí on cal posar una sentència de manera obligatòria però no volem posar res. Apareix molt en la POO (Programació Orientada a Objectes), per a crear classes i/o mètodes buits: