Evitar elif y ELSE IF Ladder and Stairs Problem

Este artículo se enfoca en discutir el problema de escaleras y escaleras elif y else if y la solución para el mismo en los lenguajes de programación C y Python.

El ELIF y ELSE IF Ladder and Stairs Problem

Hay programadores que rehúyen las secuencias largas de IF, ELSE IF, ELSE IF, ELSE IF , etc. que normalmente terminan con una cláusula ELSE final. En lenguajes con sintaxis ELSE IF o   elif , el patrón se denomina «escalera ELSE IF». En lenguajes sin ELSE IF o elif , cada ELSE IF conceptual se escribe como un IF colocado dentro de la  parte ELSE  de su predecesor. Con sangría, parece como descender una escalera al revés.

  • Esto forma una estructura de programación indeseable, difícil de leer, peor de mejorar y propensa a errores. 
  • Con sangría, el código de escalera cae del lado derecho de la pantalla. 
  • Para algunos programadores, el problema es la estética, mientras que otros se preocupan por la mantenibilidad. 
  • A veces, la sintaxis realmente se interpone en la forma de expresar la lógica que debe expresarse. 

Fundamentalmente, este patrón expresa tanto la priorización como un cortocircuito: 

  • La priorización es que las declaraciones se procesan solo para el primer VERDADERO entre un conjunto de condiciones. 
  • El cortocircuito es que después de que se determina que la primera condición es verdadera, ni siquiera se evalúan más expresiones de condición de prueba. Esto es importante porque las expresiones de condición pueden invocar algunas funciones, como IF (42 < somefunction( x ) ). . . , donde algunas funciones pueden tener estado y tener efectos secundarios. 

Cualquier alternativa debe mantener esta semántica. Además, a veces hay declaraciones que deben ejecutarse solo si fallan algunas condiciones anteriores, pero deben ejecutarse para todas las condiciones posteriores. 

Ejemplo: 

C

// Many people find this code 
// undesirable to work with.
if (a < b) 
{
    // a<b statements
}
else if (b < c) 
{
    // b<c statements
}
else if (c < d) 
{
    // Statements before every 
    // remaining possibility
    a = 45;
    
    // c<d statements
}
else if (d < e) 
{
    // Statements before every 
    // remaining possibility
    a = 45;
    
    // d<e statements
}
else if (e < f) 
{
    // Statements before every 
    // remaining possibility
    a = 45;
    
    // e<f statements
}
else 
{
    // Statements before every 
    // remaining possibility
    a = 45;
    
    // else statements
}

Python3

# Many people find this code 
# undesirable to work with.
  
if (a < b):
    # a<b statements
      
elif (b < c):
    # b<c statements
      
elif (c < d):
    # statements before every 
    # remaining possibility
    a = 45
      
    # c<d statements
      
elif (d < e):
    # statements before every 
    # remaining possibility
    a = 45
      
    # d<e statements
      
elif (e < f):
    # statements before every 
    # remaining possibility
    a = 45
      
    # e<f statements
      
else:
    # statements before every 
    # remaining possibility
    a = 45
      
    # else statements
      
# end of IF-ELIF-ELSE   
pass  
  
# Contributed by David A. Kra

Tenga en cuenta que esta repetición de declaraciones que se aplican a cada una de las posibilidades posteriores ( a = 45 ) viola el principio «No se repita» (DRY). Cualquier cambio debe repetirse después de cada condición.

Enfoque de dos pasos para eliminar ELSE IF y ELSE 

En lugar del código ELSE IF y ELSE anterior, el siguiente enfoque elimina la necesidad de ellos, mientras mantiene la priorización y la semántica de cortocircuito:

  1. Coloque un conjunto de sentencias IF independientes dentro de un ciclo de una sola iteración. No utilice ninguna sintaxis  ELSE IF o ELSE .
  2. Agregue una declaración de salida de bucle como la última de las declaraciones dentro de cada   IF .  Se prefiere   BREAK a CONTINUE . El código de Python ofrece una versión for y while del bucle. BREAK debe usarse con la versión while del ciclo.

Ejemplo:

C

// This is the ELSEless equivalent.
do 
{ 
  // This is a one pass WHILE loop.
    if (a < b) 
    {
        // a<b statements
        break;
    }
    if (b < c) 
    {
        // b<c statements
        break;
    }
  
    // Statements for every remaining 
      // possibility
    a = 45;
  
    // More conditions
    if (c < d) 
    {
        // c<d statements
        break;
    }
    if (d < e) 
    {
        // d<e statements
        break;
    }
    if (e < f) 
    {
        // e<f statements
        break;
    }
  
    // else statements
    q = 75;
  
    // break unnecessary. 
    // Already at end of loop.
} while (0); 
  
// Once was enough. Do not repeat it.

Python3

# This is the ELSEless equivalent.
  
# for version # !!!! Use any one and 
# only one value in the iteration set. !!!!
# forversion="""for i in ("once - elseless"):"""
  
# while version # !!!! requires a BREAK 
# at the bottom !!!!
# whileversion="""while(True):"""
while (True):
    
     if (a < b):
         # a<b statements
         break  
            
     if (b < c):
         # b<c statements
         break   
  
     # statements for every remaining 
     # possibility indenting aligns
     # with the if's above
     a = 45
      
     if (c < d):
          # c<d statements
          break   
            
     if (d < e):
          # d<e statements
          break   
            
     if (e < f):
          # e<f statements
          break   
       
     # else statements
     # indenting aligns with the if's above
     q = 75
        
     # for version: break unnecessary. 
     # Already at end of one-pass loop.
     # while version: break absolutely 
     # required for the while version
     break # required for the while version
      
pass  # past end of else-less IF-ELIF-ELSE
  
# Contributed by David A. Kra

Explicación: Rara vez, o nunca, codificamos intencionalmente un ciclo que siempre se usará exactamente para una iteración, pero aquí lo hacemos. La mayoría de los lenguajes de programación proporcionan una declaración de control de bucle, como BREAK para salir de un bucle por completo, o CONTINUE , para saltar a la siguiente iteración del bucle. Sin embargo, en este uso de bucle de un solo paso, no habrá ni debe haber ninguna iteración siguiente. 

Esta solución explota estas declaraciones de iteración en lugar de ELSE IF y ELSE . La instrucción BREAK o CONTINUE hace que se omitan todas las demás instrucciones dentro del bucle. Cuando el ciclo se especifica para tener solo una iteración, incluso una instrucción CONTINUAR lleva a salir del ciclo. 

En el ejemplo de código, CONTINUE o BREAK funcionarán con la versión C o la versión de bucle for en python. La versión de python del ciclo while requiere el uso de la declaración break , incluida una después de las declaraciones finales equivalentes a else. 

Además, entre las declaraciones IF , puede haber declaraciones adicionales que se ejecuten antes de probar cualquiera de las condiciones posteriores.  

Costo de procesamiento o gastos generales: la versión de python experimenta los gastos generales mínimos de configurar el bucle. La sobrecarga en C es incluso menor, y si se usa un compilador de optimización inteligente, es posible que no haya sobrecarga en absoluto.

Resumen

A primera vista, este modismo parece un truco innecesario. Tras una consideración más cuidadosa, hace que la aplicación sea más fácil de entender y mantener. Lo usaría con lenguajes compilados, especialmente con un compilador optimizador. También lo usaría en idiomas interpretados, excepto en un punto de acceso crítico para el rendimiento. Incluso allí, lo usaría inicialmente y volvería a if, elif, elif, elif… else solo después de la depuración completa de la aplicación.

Publicación traducida automáticamente

Artículo escrito por dakra137 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *