Condicionales. Concepto
Vistos los principales tipos y operadores, nos enfrentamos a la decisión de seguir la lógica de programación, que nos lleva a tratar sobre las funciones que se pueden aplicar a cada uno de los tipos, o a la lógica pedagógica, que nos lleva a hablar de las principales estructuras que permiten el tratamiento de datos.
Dado el objetivo de este blog, he considerado conveniente seguir la segunda vía, dejando para más tarde el tema de las funciones y su uso respecto a los tipos simples. De este modo podremos apreciar mejor la utilidad de los lenguajes de programación para la creación de algoritmos.
Empezaré por las estructuras condicionales más básicas y su concreción en pseudocódigo y en los lenguajes OOo Basic y Python.
Aunque responde al tratamiento de cualquier variable, un condicional está relacionado funcionalmente con el resultado de la aplicación de los operadores lógicos y relacionales, dado que se basa en la valoración en términos de V/F respecto al contenido de la variable (la proposición que implica) y/o a la comparación entre dos proposiciones (y las variables que las representan).
La estructura del condicional más simple (SI condicional) permite responder V/F a la validez del enunciado al que se refiere: Si vA = x es V (True), entonces y -> Fin del condicional. Si aV = x es F (False), entonces Fin del condicional. Este razonamiento se expresa gráficamente mediante este flujograma:
Una segunda formulación del condicional incluye la alternativa para el caso en que la proposición valorada resulte ser falsa. Esa opción se desarrolla como sigue: SI Proposición es V Entonces A -> Fin del condicional; en caso contrario (Proposición es F), entonces B -> Fin del condicional. La representación mediante flujograma es la siguiente:
Aunque aparentemente hayamos considerado la existencia de un único elemento-opción en cada rama de la estructura, observa que lo denominamos como bloque (de opciones), lo que da a entender que es posible tanto que ese bloque se reduzca a un único elemento, como que esté formado por n elementos. Si bien esto hace más complejo el contenido, esa complejidad se limita a la estructura del propio bloque, pero no afecta a la estructura del condicional.
Ahora bien, conforme vayamos considerando un número mayor de opciones, esa estructura condicional se va haciendo más compleja, por lo que es necesario disponer de formulaciones condicionales que hagan posible esta complejidad. Esto es posible mediante el anidamiento de condicionales y/o mediante condicionales múltiples.
El anidamiento consiste en la inclusión de un condicional (o varios) dentro de otro condicional. Si forma más simple sería la que representamos en este flujograma...
... que no da idea de la complejidad que puede llegar a alcanzar una estructura de opcionalidad basada en condicionales anidados.
Los condicionales múltiples se basan en la posibilidad de que la condicional inicial pueda ser múltiple (no dicotómica), por lo que no es suficiente con las instrucciones if y else. Para cubrir esta función contamos con la instrucción Else If (elif y otras formulaciones), que suponiéndose como alternativas a If se sitúan a su mismo nivel y mantienen entre sí la misma relación de oposición/complementariedad que mantienen con el If inicial. Dicho de otro modo: no son condicionales anidados, aunque sea posible suplirlos por condicionales anidados y, a la vez, también lo sea la combinación de ambos procedimientos.
El siguiente flujograma representa una estructura condicional múltiple que, en sentido estricto no se formula en términos de Si...entonces, sino en términos de En caso de...
En algunos lenguajes (OOo Basic, por ejemplo), además de la opción If...Else If...Else, también existen estructuras específicas tipo Select Case/Switch case, que obedecería, en sentido estricto al flujograma anterior, pero otros (como Python, por ejemplo) no cuentan con esta estructura específica, siendo necesario utilizar la estructura if compleja (if...elfi...else) que, aunque sea homologable a Selec case, también en sentido estricto, puede entenderse como una especie de anidamiento en cascada, por lo que la representación mediante flujograma podría ser más bien la siguiente:
NOTA: Como veremos en la entrada que sigue, en Pseudocódigo (concretamente en PSeInt) se utilizan dos estructuras condicionales: la simple (Si...SiNo) y la compleja (Según(caso)...Hacer), pero no la estructura compleja derivada de la simple (Si...SiNo_Caso...SiNo) por considerar que ésta es equivalente a la anterior.
Dada la complejidad y la opcionalidad existente en estructuras condicionales y en lo que éstas revelan (la posibilidades de bifurcación del algoritmo), es conveniente explorar las posibilidades que ofrece la conceptualización de la condicionalidad en términos de teoría de conjunto. Evidentemente, esto es posible en cualquier situación en la que se plantee la opcionalidad, pero especialmente cuando ésta resulte ser especialmente compleja.
Debemos partir, para entender esta conceptualización, de la asimilación de la tarea/opción como elemento de un conjunto N formado por los n elementos u opciones. A partir de aquí, podemos entender ese conjunto N como subconjunto perteneciente al universo (conjunto U) de las opciones posibles y, en consecuencia, también la posible existencia de otro conjunto N' que mantiene con N relaciones de complementariedad, si bien no en sentido estricto, ya que es posible la existencia de un subconjunto NN' intersección de N con N' diferente del conjunto vacío. No obstante, si U está formado por dos subconjunto, a efectos prácticos el subconjunto NN' puede considerarse al margen de la opcionalidad, dado que, al pertenecer tanto a N como a N' no son objeto de decisión/elección, de lo que se deriva que N y N' pueden considerarse complementarios a los efectos de la opcionalidad (y por tanto definirse como opuestos N vs ¬N).
Este planteamiento permite conceptualizar las diversas estructuras de opcionalidad, formalizarlas y representarlas gráficamente mediante diagramas de Venn, complementarios ambos al pseudocódigo y a los flujogramas. Repito que cuando la estructura de opciones es simple (aunque pertinente) esta conceptualización no es necesaria, pero se vuele muy útil cuando se incrementa la complejidad, ya que es fácil perderse en la multiplicidad de opciones condicionadas que se presentan en estos casos.
Podremos complementar este análisis con el resultante de la relaciones entre los contenidos de las opciones, que pueden entenderse (y formalizarse) desde la óptica del producto cartesiano como marco general y las relaciones (y tipos de relación) que se establecen entre los elementos (opciones) que conforman los conjuntos de que se derivan de la opcionalidad. Pero este es un segundo tipo de análisis, aunque relacionado con el primero (el estructural).
Por el momento, parece suficiente con lo comentado aquí para iniciar el trabajo con las estructuras condicionales. Te recomiendo continuar con pseudocódigo (PSeInt), antes de adentrarte en su formulación en lenguajes de programación. Así tendrás una visión general, complementaria de lo que esta entrada te pueda haber aportado, y ya más próxima a la elaboración de algoritmos.