IF-ELIF- ELSE

FLOR DE LA JARA EN LAS PINEDAS DE DE DE ACENTEJO, NORTE DE TENERIFE.

      

INTRODUCCIÓN

      

      Las denominadas HERRAMIENTAS DE CONTROL DE FLUJO DE DATOS, conocidas también como SENTENCIAS DE CONTROL, a secas, o aún más simplemente, BUCLES o LOOPS, en inglés, sirven precisamente para eso: para actuar sobre una instrucción o condición concreta a partir de un punto específico en el proceso de ejecución de un programa, detener el flujo de datos y suscitar la aplicación de una o más expresiones ocasionando una bifurcaciones.
Imaginemos que vamos circulando, tragando kilómetros tranquilamente rodeados por otros tantos vehículos de todo tipo y condición, por una flamante autopista en pleno invierno en dirección a una ciudad X de nuestra geografía española. Sin embargo, al llegar con nuestro vehículo al punto kilométrico, 32, por ejemplo, tenemos la opción de desviarnos por la derecha en un primer desvío por una carretera general que pasa por el pueblo Z, que nos permitiría llegar a nuestro destino más rápidamente, pero que sabemos que con el aguanieve que ha caído va a tener un firme deslizante, o recorrer un kilómetro más en la autopista y tomar un segundo desvío, también a la derecha, que nos lleva a una carretera secundaria y que nos conduce igualmente a nuestro destino con cinco minutos más de retraso que si tomáramos el desvío anterior. Traducción: nuestro vehículo es el DATO, la autopista por la que circulamos junto con la carretera general y la carretera secundaria es la EJECUCIÓN normal, corriente y moliente de un PROGRAMA, y la ciudad X es el RESULTADO deseado por el programador si el código que ha diseñado se ejecutara correctamente de principio a fin. ¿Estamos? El punto kilométrico 32 es el PUNTO ESPECÍFICO EN EL PROCESO DE EJECUCIÓN a partir del cual debemos tomar una decisión: o tomamos el primer desvío o tomamos el segundo, es decir, nuestro vehículo-dato tomará un camino o tomará otro abandonado la primorosa autopista por la que habíamos venido circulando hasta ahora (nuestro flujo de datos hasta el momento), A partir de este momento el flujo de datos se DETIENE y, o va por la carretera general o por la secundaria para poder llegar a nuestro destino, en otras palabras, tenemos una BIFURCACIÓN. En programación, el dato "se para"; en nuestra analogía, porque nos obliga el código de circulación, reducimos la velocidad (¡no podemos pararnos en una autopista si no es en el arcén!). Es decir, DETENEMOS EL FLUJO DE DATOS. Aquí valoramos la información: nuestro vehículo-dato tiene las gomas de las ruedas un poco gastadas por lo que debemos circular sobre el asfalto más seco posible. Este es nuestro CONTROL. Y a partir de aquí, hacemos una VALORACIÓN: si tuviéramos los neumáticos en buen estado, optaríamos (bifurcaríamos) por la carretera general, que nos lleva mucho antes a nuestro destino; pero como nuestro CONTROL nos dice que tenemos las gomas desgastadas, optamos (bifurcamos) por la segunda opción, esto es, por tomar el segundo desvío por la carretera secundaria. Efectivamente, tomamos el segundo desvío (ahora nuestro flujo de datos a abandonado la autopista, ha bifurcado y continúa por la carretera secundaria en dirección a la ciudad X) y continuamos con nuestro flujo de datos, la EJECUCIÓN normal, corriente y moliente de un PROGRAMA hasta la devolución final de un resultado esperado y deseado del mismo.
Espero que lo hayamos comprendido, ¿no?
Bueno, seguimos. Las herramientas a las que hacemos referencia son: la sentencia IF-ELIF-ELSE, y los bucles WHILE y FOR/IN. Sobre todo este último lo hemos visto ya en acción en algunos ejemplos anteriores. Además, Python posee también una expresión condicional próxima a la sentencia if que responde al operador ?:.

      LA SENTENCIA IF.


      Veamos a continuación un esquema de su funcionamiento:




A continuación vamos a explicar su sintaxis:

IF EXPRESIÓN_BOOLEANA 1: (recordemos que una expresión booleana es aquélla susceptible de ser descrita por un booleano, en este caso, True o False)
      BLOQUE_DE_CÓDIGO 1 (indentación )
TAJINASTES ROJOS EN FLOR
ELIF EXPRESIÓN_BOOLEANA 2:
      BLOQUE_DE_CÓDIGO 2 (indentación )
.....................................................................................
.....................................................................................
ELIF EXPRESIÓN_BOOLEANA N:
      BLOQUE_DE_CÓDIGO N (indentación )
ELSE:
      BLOQUE_DE_CÓDIGO ELSE (indentación )

Dicho más o menos en cristiano, lo anterior puede leerse como " si (if) tal condición se cumple, entonces debe suceder esto (bloque de código de if). Y si además se cumple también la condición 2 (expresión_booleana 2), se aplicará su bloque de código correspondiente (bloque de código de elif para la expresión_booleana 2). Y si además se cumple también las condiciones propuestas en los sucesivos elif que añadamos en n número se aplicarán los correspondientes bloques de código para cada elif propuesto hasta n (expresión_booleana n). Para todo lo demás (else) sucede esto (bloque de código de else).
Simple, ¿verdad? Algo enrevesadillo como enunciado, pero fácil de comprender cuando lo vemos en funcionamiento. Ya lo veremos.
La declaración if, en Python, es similar a la de otros lenguajes se trata de un "condicional" de tal manera que  "si pasa esto, entonces hacemos esto otro". Veámoslo con una analogía simplísima: imaginemos un juego de cartas, un mazo normal de baraja francesa con sus 4 palos y sus 56 naipes. Y tenemos dos jugadores que reciben cada uno la mitad del mazo, 28 cartas, previamente barajadas, mezcladas y sin mirar, claro, para que no hayan trampas.
Cada jugador, de manera alternativa, van sacando una a una una carta de su mazo y la ponen boca arriba sobre la mesa. Ganará aquél que saque primero el as de picas. Aquí se detiene el juego y el vencedor se lleva el monto de la apuesta. En esta bobería de juego, el proceso, el protocolo de actuación, sus reglas, su mecánica, (dividir el mazo, número de jugadores, barajar, extraer y mostrar las cartas alternativamente, etc.) es el programa, es decir, lo que hay que hacer, el extraer la carta ganadora (el as de picas) es la condición (if); terminar el juego es la consecuencia intrínseca de darse la condición (el programa se detiene o suspende); y ganar la apuesta por parte del afortunado poseedor de la carta es la consecuencia explícita, el "...entonces esto otro", de producirse la condición.
La declaración if contiene en sí misma una declaración lógica con el que se comparan datos (en el ejemplo anterior, cada vez que un jugador mostraba una carta, ésta se compara con la carta condicional, el as de picas: que no es el as de picas, el juego (el programa) continúa. Vuelve a mostrarse una carta y de nuevo se compara. Que sale el as de picas, el juego se detiene: la carta que ha salido coincide con la declaración if (el as de picas) y el juego finaliza; que no existe esa coincidencia, el juego prosigue. Las decisiones se toman de acuerdo en los resultados de las comparaciones.
A través del if se produce un flujo de datos hasta que se da la condición planteada y entonces dicho flujo se detiene. Entonces se produce la bifurcación.


   
      A mi modesto entender perruno, la sentencia if/elif/else funciona haciendo una evaluación de la condición que hemos indicado; en términos lógicos, que es como realiza la comparación a nivel interno sólo se puede admitir una de dos respuestas posibles: si el resultado es el booleano es True, esto es, si la condición descrita se da, se ejecutará la siguiente sentencia o conjunto de sentencias del programa. En caso contrario, que el resultado de la comparación fuera el booleano False, se ejecutará la sentencia o conjunto de sentencias que vayan en el bloque de código de la sentencia else

Los condicionales if en el caso que tratamos, nos permiten comprobar condiciones haciendo que nuestro programa se comporte de una forma u otra dependiendo del resultado de dicha comprobación, que ejecute un segmento de código u otro ==> bifurcación.
Para describir la evaluación que se debe realizar sobre una condición dada se utilizan los OPERADORES RELACIONALES llamados también OPERADORES DE COMPARACIÓN.


Con los OPERADORES DE COMPARACIÓN evaluamos una única condición. Por ejemplo:  si llueve sacamos el paraguas; si el semáforo está en verde no cruzamos la calle; si sacamos el as de picas ganamos la partida; si me queda dinero me compro un libro; etc.
Sin embargo, para evaluar simultáneamente más de una condición debemos recurrir a los llamados OPERADORES LÓGICOS  que irán enlazando las diferentes condiciones que queramos tener en cuenta.


Mostramos abajo otra tabla, dentro de lo que en lógica se denomina tabla de la verdad, donde además incluimos la opción not. Aunque en la tabla superior se muestra la opción xor, ya no existe en Python de cara a clarificar mejor el código.



Finalmente, insertamos una tabla de prevalencia donde mostramos la jerarquía de preponderancia entre los operadores, de menos, desde la base, a más:




Si llueve saco el paraguas y me pongo un chubasquero; si el semáforo está en ámbar me detengo o acelero un pelín más para cruzar antes de que cambie a rojo; si saco el as de picas gano la partida, me quedo con la apuesta y le ofrezco la revancha a mi contrincante; si me queda dinero, o me compro un libro o me compro un dvd con una buena película.

ESPESURA EN EL SOTOBOSQUE DE LA LAURISILVA DE ANAGA, NORESTE DE TENERIFE.

A la condición if/elif/else tenemos que aplicarle un indentado. Esta palabreja, indentado, proviene del inglés "indentation" que se traduce por "sangría", en castellano, la separación de renglones en los saltos de línea, unos de otros, con respecto a un punto de partida.
Esto se hace para establecer una relación de dependencia/pertenencia de manera gráfica,  muy visual, perfectamente discernible a ojos del programador y obligada por la estructura sintáctica de Python, formando parte además del consabido PEP 8 (pepocho), donde la separación entre la línea de código condicional con respecto a la línea de código siguiente se establece en cuatro espacios en blanco, y no en un simple tabulado.
Afortunadamente, nuestro sufrido IDLE realiza la indentación requerida de manera automática.


      Un pequeño apunte con respecto al ejercicio anterior: si lo volvemos a escribir en el IDLE veremos cómo después del if (y a continuación, repitiendo el proceso, con elif y else), el intérprete de Python nos da un indentado mucho mayor que los 4 espacios que muestra entre el bucle for/in y la siguiente línea. No importa, da igual.
manías de Python: el programa funcionará exactamente igual.


Sin embargo, es posible eludir la obligación de sangrado para casos muy simples:


Si se nos presentan distintas posibilidades, diferentes opciones, para llevar a efecto una condición, elijamos siempre la más simple, es decir, la más legible. Es posible, incluso, establecer condiciones complejas con sólo entremezclar las cláusulas if/else y los operadores lógicos.


IMPORTANTE: tengamos en cuenta que toda entrada input() nos devuelve SIEMPRE, por defecto, una string, una cadena. Para poder establecer comparaciones con números debemos cambiar el tipo de dato a entero, int(), o a decimal, float(). Puestos a elegir, es preferible, aunque no ha sido el caso en el ejemplo, usar la función conversora float() porque además de asumir enteros en su versión decimal como entero.00, por ejemplo, 25.00 (= 25), extiende el rango de posibilidades a los números decimales, como 12.98, 0.568, -2.23, etc.


En una declaración condicional puede haber ninguna o más cláusulas elif (en el ejemplo precedente, tan sólo contábamos con cláusulas if), mientras que la cláusula else es opcional.
En otros casos, también es posible simplificar la sentencia if/else mediante una sintaxis simple del tipo:

                                                      EXPRESIÓN_1 IF EXPRESIÓN_BOOLEANA ELSE EXPRESIÓN_2



En el supuesto de que quisiéramos informar de un caso en particular, pero no queramos hacer nada en el supuesto de que tenga lugar la condición podemos utilizar la keyword pass como bloque de bifurcación sin que suceda nada.


También contamos con un recurso común en programación que se apoya en el bucle if para crear un programa o script que asigne un valor por defecto dentro de una variable, para ser luego sustituida por otro, si es necesario, claro,, si dicho valor nos resulta desconocido de antemano, por ejemplo, porque deba introducirlo un usuario. Podemos verlo en el ejemplo que mostramos a continuación:


Imaginemos que queremos mostrar un programa lo más optimizado que podamos a un posible cliente. lo primero que tenemos que hacer es importar de la biblioteca o librería de Python, que más o menos lo mismo da, el módulo sys, como vemos en 1., abreviatura de "system", que refiere al sistema operativo que tengamos instalado en nuestro pc (Windows, Linux, Mac Os, Asturix, Fedora, etc.). En principio, y por si las moscas, empezaríamos ejecutándolo con un modelo de SO de 32 bits (Windows 32, por ejemplo). Pero en el caso de que no pueda ejecutarse en 32, y desconozcamos la versión del SO, empezaremos con Windows (por ser el más común), tal y como pedimos en 2. y en una versión de 64 bits.

VISTA DE SANTA CRUZ DE TENERIFE DESDE EL PINAR DE IGUESTE DE CANDELARIA, EN EL SURESTE DE LA ISLA.
Debemos, sin embargo, ser precavidos cuando recurrimos a una expresión simplificada y usamos parámetros para perfilar mejor las características de una variable. lo veremos muy bien en el siguiente ejemplo extraído de PYTHON 3, Mark Summerfield, ed. Anaya Multimedia, pag. 166:
Queremos configurar una variable width, "anchura",  con 100 píxeles añadiendo 10 píxeles más si se da el caso de  que el margin, "margen", con respecto a los bordes de la pantalla donde visualizamos los contenidos,  es True, es decir, que disponemos de un marco suficiente para que aquéllo que deseamos mostrar sea un poquito (esos 10 píxeles de más sobre cien que pretendemos añadir) más grande, y escribimos lo siguiente:

                                                                               WIDTH = 100 + 10 IF MARGIN ELSE 0

El error en la expresión está en que funciona correctamente siempre y cuando margin sea True, estableciendo efectivamente el valor de width en 110 en lugar de 100. Pero si margin es False, como Python considera '100 + 10' como la 'expresión_1 del condicional, mostrará un width con valor de 0, es decir, no mostrará ancho alguno.
Para evitarlo tenemos que recurrir a los paréntesis codificados en la forma siguiente:

                                                                               WIDTH = 100 + (10 IF MARGIN ELSE 0)

La mayor virtud del uso de los paréntesis estriba en su capacidad para clarificar la comprensión.
Imaginemos ahora que queremos imprimir a la vista del usuario los archivos procesados. Para hacerlo recurrimos a nuestra archiconocida función print(). Pero no querríamos que se imprimiera una solución del tipo "0 file(s)", "1 file(s)", etc. sino un texto... ¿cómo decirlo?... más profesional:
Podríamos optar por el siguiente código:

                                            print("{0} file {1}".format((count if count !=0 else "no"), ("s" if count !=1 else " ")))

Lo cual imprimirá "no files", "1 file", "2 files", ...

LADERA EN PLENO BOSQUE DE LAURISILVA CUBIERTA DE HELECHOS (WOODWARDIA RADICANS), BOSQUE DE ANAGA, NORESTE DE TENERIFE.

La sentencia asociada elif, que viene a ser una contracción de else + if (por ejemplo, en PHP, que es otro lenguaje de programación vinculado al desarrollo de páginas web desde el lado del servidor o backend, la misma sentencia es, exactamente, ésa: elseif), viene a decir algo así como: " y además de lo anterior es esto..." Básicamente, supone añadir operadores and a una misma línea de código o instrucción. Por cuestiones de estética y legibilidad, si en una misma instrucción insertamos un par de operadores and pues bueno, vale, muy bien. Pero si vamos a añadir varias condiciones más en una misma línea de código el asunto ya no queda ni tan estético, ni tan legible, ni tan eficiente. Para circunstancias como ésta, es preferible recurrir a la sentencia elif. Veamos un ejemplo:


Llegado el caso nos podríamos hacer la siguiente pregunta: ¿Por qué no usar solamente if en lugar de elif? Bien. Lo primero que debemos tener en cuenta es que con elif estamos trabajando en el mismo bloque de código que abrimos con if y cerramos con else. Insistimos: el mismo. De este modo, todos los condicionales se relacionan entre sí y se comportan de un modo único y coherente.
Si solo usáramos if, por contra, cada condicional dispondría de un bloque de código exclusivo e independiente de los demás, y la sentencia else del final sólo se aplicaría al primer if que se encontrase por encima, remontando el código, mientras que en el caso anterior, usando elif, la sentencia else cerraría al bloque completo.
Teniendo en cuenta el FLUJO DE CÓDIGO que ya hemos estudiado, con  las instrucciones elif y sabiendo que el flujo de lectura va de arriba a abajo, el intérprete de Python va evaluando la condición que le pasemos condición por condición, obviando las que no correspondan (False) hasta alcanzar aquélla instrucción elif que devenga True, ejecutando a continuación el código que lleve en su interior y deteniendo las evaluaciones por muchas sentencias elif que sobrevengan a continuación, a menos que ninguna se cumpla y ejecute la sentencia else.
Si en lugar de instrucciones elif generamos bloques de independientes de código con instrucciones if, el intérprete de Python evaluaría la condición del primer if. Si no se cumple, pasa al siguiente, y así sucesivamente, instrucción if por instrucción if hasta que se cumpla la condición (devenga True) y ejecute el bloque de código pertinente. Pero seguirá leyendo if de acuerdo al flujo de lectura de arriba a abajo y volverá a evaluar la condición, haciéndolo igualmente por todos y cada uno de los condicionales if que se encuentre por el camino, y aplicará la sentencia else, si es necesario, sólo del último if.
Esta es la diferencia, que tendremos que tener en cuenta en algunos casos a la hora de programar. Veamos un ejemplo:




Una característica interesante de Python es que, bajo ciertas circunstancias, es posible prescindir de la cláusula elif y sustituir ésta por lo que se llama una concatenación  de operadores de comparación. Veámoslo en el siguiente ejemplo:


Aquí se ejecuta una evaluación "en cadena", de izquierda a derecha: Python evalúa primero la condición que se codifica más a la izquierda. En el caso de que sea correcta, pasará a evaluar la siguiente condición que se muestre. Si también es correcta, continuará con la siguiente y así sucesivamente con cuantas condiciones hayamos insertado hasta llegar al final, siempre y cuando todas las condiciones determinadas por su operador correspondiente fueran correctas, esto es, la evaluación devenga True. Sin embargo, en el momento en que Python encuentre una condición que devenga False, detendrá el flujo de lectura y saltará a la cláusula else, ejecutando el código que hayamos transcrito aquí.
También es posible configurar ifs anidados, es decir, sentencias if dentro del bloque de código de otras sentencias if. No es algo que resulte particularmente útil y es necesario planificarlo bien para no suscitar errores en su lectura pero, según en qué ocasiones, podría salvarnos de un dolor de cabeza. Veamos un ejemplo.


Precisamente, la razón de ser de la cláusula elif pasa por evitarnos las posibles complicaciones que nos pueden surgir con los ifs anidados y evitar reiteraciones innecesarias que empañen la lectura del  código.                                                                       


                                                         ELIF => SUSTITUYE => IFs ANIDADOS
                                                 
                                                                                          

                                                      ELIF => MEJOR OPCIÓN => IFs ANIDADOS


Existe en Python una codificación paralela par if/else que se escribe en una misma línea de código, sin indentación, y que parte de una asignación que expresamos delante del condicional para terminar con una segunda asignación que "corrige" ala primera:


Veamos un ejemplo de uso:


Nos viene de maravilla cuando necesitamos modificar el valor inicial de una variable y re-asignarle otro distinto en función de que se cumpla una condición determinada, todo en una misma línea de código. Sin embargo, ¡cuidado! Como acabamos de ver en el ejemplo, sólo podemos introducir valores (tipos de datos) delante de la cláusula else y no la re-asignación completa, con la variable incluida. ¡Ojito!
Con la sentencia break podemos interrumpir conscientemente la ejecución del código de acuerdo a una condición dada. Si la condición se da, se interrumpe la lectura y el flujo de lectura se sale del del bucle. Veámoslo:


La sentencia break sólo funciona con los condicionales if/elif/else y while, pero no con el bucle for/in. En la inmensa mayoría de los casos en los que se la utiliza, como en el ejemplo anterior, tenemos primero un bucle que itera sobre una sentencia y un condicional if que evalúa cada vuelta de bucle, evaluando vez por vez  la condición que hemos puesto.
La sentencia continue evalúa cada iteración una a una, cada vuelta de bucle, vamos, en la que se ha insertado, pero al llegar a la condición que la afecta, la cumple, y sin salirse del bucle, continúa con las iteraciones que no cumplan con la condición exigida.



Pongamos otro ejemplo más de uso de continue:



Como no puede ser menos, vamos a proponer algunos ejercicios que nos ayuden a comprender mejor cómo trabaja el condicional if/elif/else.



T4. BLOQUE DE EJERCICIOS 7. SOLUCIONES.


ARBOLEDA CUBIERTA DE MUSGO ENTRE LA FRAGOSIDAD HÚMEDA Y NEBLINOSA DE LA LAURISILVA DE ANAGA, NORESTE DE TENERIFE.



4 comentarios:

  1. Excelente curso, uno de los mejores y sin duda el más didactico que observe sobre el tema. Puede ser que la seccion de "soluciones" este faltando en varias secciones como la de aquí?

    ResponderEliminar
  2. Muchísimas gracias por tu comentario. Eso es lo que pretendemos: hacerlo lo más didáctico posible, que llegue a la mayor variedad posible de personas interesadas en Python y que les sirva de apoyo y ayuda. Las soluciones se encuentran en el área de entradas, que puedes consultar en el margen derecho de la página principal del blog. Todas ellas, para distinguirlas de otras, llevan la categoría T4 al comienzo. Creemos haber publicado todas, aunque repasaremos por si las moscas. En concreto, la correspondiente al bloque de ejercicios para IF-ELIF-ELSE la tienes aquí: http://conocepython.blogspot.com/2016/07/, es decir, en la entradas correspondientes al mes de Julio del 2016. Aquí encontrarás 2: para el bucle while y para if-elif-else. Saludos.

    ResponderEliminar
  3. excelente y simple de entender, muchisimas gracias, estoy en la carrera de Ingenieria Informatica y me viene genial para la materia Fundamentos de Informatica!!

    ResponderEliminar
    Respuestas
    1. Hola, Isabella. Muchísimas gracias. ¡Qué alegría me ha dado! Que este blog le acompañe a Ud. en su carrera es una satisfación enorme. Todo lo mejor en sus estudios.Saludos.

      Eliminar