Buscar este blog

viernes, 12 de julio de 2013

Decisión

Utilizando programación estructurada (la que soporta jC y estamos estudiando aquí), existen tres conceptos que es necesario conocer. Secuencia, Decisión, y Repetición.

La primera ya la hemos visto claramente, se trata tan solo de que cada instrucción se ejecuta una detrás de la otra, en el mismo orden en el que están escritas en el programa.

La estructura de decisión consiste en que, según se cumpla una condición o no, la ejecución continuará por una rama u otra. Para especificar la condición, y las ramas que se puedan ejecutar, jC, como muchos otros lenguajes de programación, utiliza la instrucción if.

if ( <condicion> )
{
    instruccion1;
    instruccion2;
    instruccion3;
    ...
    instruccionn;
} [ else {
    instruccion1;
    instruccion2;
    instruccion3;
    ...
    instruccionn;
} ]

La instrucción if puede llegar a definir dos bloques de instrucciones: el que se sitúa justo detrás de if, y el que aparece a continuación de éste, detrás de la instrucción else. Este segundo bloque de instrucciones es opcional, no es obligatorio (por eso aparece entre corchetes).

De acuerdo, pero... ¿cómo se especifica la condición? En realidad, es muy sencillo: se utilizan los operadores < (menor que), > (mayor que), == (igual a), != (diferente de), <= (menor o igual que) y >= (mayor o igual que). Estos operadores son binarios, es decir, a la izquierda y a la derecha de ellos se acompañan sendos valores. Dado que no tiene mucho sentido comparar dos literales (por ejemplo, 2 < 5 siempre supondrá el mismo resultado), uno de los dos valores debe ser una variable, o al menos, una constante. Todo esto se resume en la siguiente tabla, utilizando una hipotética variable x:

OperadorSignificado
<Menor que: x < 10
>Mayor que: x > 10
==Igual a: x == 10
!=Diferente de: x != 10
<=Menor o igual que: x <= 10
>=Mayor o igual que: x >= 10

Retomando el ejemplo anterior sobre el IMC, sabemos que un índice de masa corporal menor que 20 implica desnutrición, 20 a 25 es normal, 25 a 30 es sobrepreso, 30 a 35 es obesidad leve, 30 a 35 obesidad moderada, y 35 a 40 obesidad mórbida. Así, resumiendo en una tabla:

IMCSignificado
imc < 20Desnutrición
20 <= imc <= 25Normal
25 < imc <= 30Sobrepeso
30 < imc <= 35Obesidad leve
35 < imc <= 40Obesidad moderada
imc > 40Obesidad mórbida

El código anterior es el siguiente:

import std.io;

final def Altura = 1.72;
final def Peso = 92;

def imc = Peso / ( Altura * Altura );

print( "IMC = " );
println( imc );

Podemos pensar fácilmente cómo complementar la información del índice desnudo, con la información de la tabla anterior. La primera es muy sencilla.

if ( imc < 20 ) {
    println( "Desnutrición." );
}

Así mismo, también la última es muy sencilla.

if ( imc > 40 ) {
    println( "Obesidad mórbida." );
}

Y así sucesivamente. El código completo es el siguiente:

/** @name   IMC
  * @brief  Calcula el indice de masa corporal
  * @author jbgarcia@uvigo.es
  * @date   2013-07-11
  */

import std.io;

final def Altura = 1.72;
final def Peso = 92;

def imc = Peso / ( Altura * Altura );

print( "El índice de masa corporal (IMC) es: " );
println( imc );

if ( imc < 20 )
{
 print( "Estás desnutrido!" );
}

if ( imc > 25 ) {
 print( "Tienes sobrepreso." );
}

if ( imc > 30 ) {
 print( "Tienes obesidad leve." );
}

if ( imc > 35 ) {
 print( "Tienes obesidad moderada." );
}

if ( imc > 40 ) {
 print( "Tienes obesidad mórbida." );
}

El problema es que para los valores que se le han dado al programa, sucede que se producen dos salidas:

El índice de masa corporal (IMC) es: 31.09789075175771
Tienes sobrepreso.Tienes obesidad leve.

Efectivamente, no se pueden colocar los if's de manera independiente. Además, estamos comprobando sólo una condición en cada momento. ¡Y ni siquiera podemos indicar que la persona está normal!

Así, al menos parte del problema consiste en las tres condiciones complejas de antes... no podemos poner 20 < imc < 25 dentro de la condición de un if. La única forma de conseguir algo parecido, es subdividir la condición en dos subcondiciones más pequeñas: imc > 20 y imc < 25. La cuestión es: ¿cómo representar esa 'y' que intuitivamente hemos colocado entre ambas condiciones? Pues podemos utilizar juntores lógicos, representados por &&, || y !.

Juntor lógicoSignificado
&&AND (y). Ambas condiciones deben cumplirse. Normal:
imc >= 20 && imc <= 25
||OR (o). Alguna de las dos condiciones debe cumplirse. Necesita reajuste:
imc < 20 || imc > 25
!NOT (no): La condición no debe cumplirse. Desnutrición:
!( imc > 20 )

A la vista de estos descubrimientos, podemos decir, para una persona normal:

if ( imc >= 20 && imc <= 25 ) {
    println( "Es un IMC normal." );
}

Para una persona con sobrepreso:

if ( imc > 25 && imc <= 30 ) {
    println( "El IMC indica sobrepreso." );
}

Las condiciones complejas es mucho más conveniente colocarlas de tal manera que cada subcondición ocupe una sola línea. De esta manera, es mucho más sencillo leerlo.

if ( imc >= 20
  && imc <= 25 )
{
    println( "Es un IMC normal." );
}

if ( imc > 25
  && imc <= 30 )
{
    println( "El IMC indica sobrepreso." );
}

Así, el código completo queda como sigue:


/** @name   IMC
  * @brief  Calcula el indice de masa corporal
  * @author jbgarcia@uvigo.es
  * @date   2013-07-11
  */

import std.io;

def altura = 1.72;
def peso = 92;

def imc = peso / ( altura * altura );

print( "El índice de masa corporal (IMC) es: " );
println( imc );

if ( imc < 20 )
{
 println( "Estás desnutrido!" );
}

if ( imc >= 20
  && imc <= 25)
{
 println( "Normal." );
}

if ( imc > 25
  && imc <= 30 )
{
 println( "Tienes sobrepeso." );
}

if ( imc > 30
  && imc <= 35 )
{
 println( "Tienes obesidad leve." );
}

if ( imc > 35
  && imc <= 40 )
{
 println( "Tienes obesidad moderada." );
}

if ( imc > 40 ) {
 println( "Tienes obesidad mórbida." );
}

Ahora todo funciona bien. Sólo queda una cuestión, y es que todas las condiciones se están comprobando en todos los casos. Por ejemplo, si la persona tiene un IMC menor que 20, ya no tiene sentido comprobar si está entre 20 y 25, o 25 y 30, etc.

Para solucionar esto, se puede emplear la posibilidad else de una estructura if.

if ( imc < 20 )
{
 println( "Estás desnutrido!" );
} else {

 if ( imc >= 20
   && imc <= 25)
 {
  println( "Normal." );
 } else {
 
  if ( imc > 25
    && imc <= 30 )
  {
   println( "Tienes sobrepeso." );
  } else {
  
   if ( imc > 30
     && imc <= 35 )
   {
    println( "Tienes obesidad leve." );
   } else {
   
    if ( imc > 35
      && imc <= 40 )
    {
     println( "Tienes obesidad moderada." );
    } else {
     println( "Tienes obesidad mórbida." );
    }
   }
  }
 }
}
De esta manera, en cuanto se opta por una rama de la decisión, se descartan todas las demás, puesto que en caso de entrar en el primer bloque de código (cuando la condición es verdadera), nunca se entra en el segundo bloque de código (y viceversa). Otra consecuencia es que la última condición ya no es necesario comprobarla, puesto que, cuando se llega al final de la secuencia de decisiones, es imposible que imc no sea mayor que 40.

El código finalmente queda como sigue:


/** @name   IMC
  * @brief  Calcula el indice de masa corporal
  * @author jbgarcia@uvigo.es
  * @date   2013-07-11
  */

import std.io;

def altura = 1.72;
def peso = 92;

def imc = peso / ( altura * altura );

print( "El índice de masa corporal (IMC) es: " );
println( imc );

if ( imc < 20 )
{
 println( "Estás desnutrido!" );
} else {

 if ( imc >= 20
   && imc <= 25)
 {
  println( "Normal." );
 } else {
 
  if ( imc > 25
    && imc <= 30 )
  {
   println( "Tienes sobrepeso." );
  } else {
  
   if ( imc > 30
     && imc <= 35 )
   {
    println( "Tienes obesidad leve." );
   } else {
   
    if ( imc > 35
      && imc <= 40 )
    {
     println( "Tienes obesidad moderada." );
    } else {
     println( "Tienes obesidad mórbida." );
    }
   }
  }
 }
}

No hay comentarios:

Publicar un comentario