Ir al contenido


Foto

Interrumpir los ciclos. ¿Si, no, cuando?


  • Por favor identifícate para responder
8 respuestas en este tema

Encuesta: ¿Interrumpes los ciclos? (11 miembros han emitido voto)

¿Interrumpes los ciclos?

  1. Si. ¡No me canso de usarlo! (0 votos [0.00%])

    Porcentaje de voto: 0.00%

  2. Si. Si el problema me lo indica (4 votos [36.36%])

    Porcentaje de voto: 36.36%

  3. No. Evito hacerlo lo más posible (3 votos [27.27%])

    Porcentaje de voto: 27.27%

  4. No. Nunca he usado las interrupciones (1 votos [9.09%])

    Porcentaje de voto: 9.09%

  5. Si y no. Según como me sienta (0 votos [0.00%])

    Porcentaje de voto: 0.00%

  6. Si y no. Todo depende... (3 votos [27.27%])

    Porcentaje de voto: 27.27%

Votar Los invitados no pueden votar

#1 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 02 abril 2013 - 07:55

Hola a todos,
Ando un poco curioso. Como dice el título... ¿Interrumpes los ciclos o no?

Como bien sabemos Delphi al igual que muchos otros lenguajes tiene algunas cláusulas de escape para los ciclos... Break y Continue. La primera para forzar prematuramente el ciclo y la segunda para obviar la iteración actual y continuar con la siguiente.

Pues bien. Abro esto a modo de encuesta. Si te enfrentas a un algoritmo que tiene la particularidad de que puedes (y debes) finalizarlo cuando se cumple cierta condición, y que además puedes determinar la cantidad máxima de iteraciones o vueltas posibles... ¿Lo interrumpes con la señal de escape, lo finalizas de forma "legal" o prefieres seguir dejarlo que llegue al final cuando no se llega a cumplir tal condición?

¿Porqué pregunto esto? Simplemente porque he visto muchísimas veces esto:



delphi
  1. for i := valorini to valorfin do
  2. begin
  3.   // hacer algo...
  4.   if Condicion
  5.     then Breack;
  6. end;



Y me tiene por demás intrigado. ¿Que beneficio tiene el añadir un Break?

¿No les parece descabellado eso? Forzar el cierre de un for para dar fin a un ciclo del cual sabemos cuando debe terminar... Mi sentido lógico dice que es más apropiado en realidad hacer justamente algo más natural y no estar obligando a interrumpir el flujo normal:



delphi
  1. i := valorini
  2. repeat
  3.   // algo antes...
  4.   i := i + 1;
  5.   // algo más...
  6. until Condicion or (i = valorfin)



Quizá se malgasta algo de línea de códigos pero me resulta más sano, y quisiera escuchar a ustedes por que alternativas se inclinan.

Como tema relacionado... de entre los ciclos While y Repeat ¿Tienes alguna preferencia de uno sobre el otro? ¿Elijes según el contexto del problema (si lo amerita)? O bien... ¿tomas a uno u otro según tu gusto y sentir del momento?

Saludos,
  • 0

#2 egostar

egostar

    missing my father, I love my mother.

  • Administrador
  • 14.448 mensajes
  • LocationMéxico

Escrito 02 abril 2013 - 09:02

Ya sabes, yo como siempre digo, DEPENDE, DEPENDE, DEPENDE.

A veces es útil usar éste tipo de rupturas en el proceso normal de un ciclo, por eso he votado por la segunda opción.

Saludos
  • 0

#3 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 02 abril 2013 - 09:26

Hola,
Gracias Eliseo por colaborar en la encuesta.

Yo he votado por un No. Evito en lo posible.

Considero que el interrumpir un ciclo con las cláusulas no es nada sano y me parece una práctica que hay que evitar lo máximo posible. A continuación expongo mis argumentos:

En cierto modo es contra natura. Yo trato de verlo desde el aspecto de la lógica. Pongo un ejemplo sencillo para bajar a tierra esto: necesito localizar un dato dentro de un array desordenado del cual se la cantidad total. Al analizar el problema es fácil comprobar cuáles son los dos criterios que llevan a una finalización de un ciclo:
1) Se ha encontrado el elemento y por tanto no tiene sentido alguno continuar. O bien,
2) Se ha llegado al final del arreglo y no se ha detectado que exista una coincidencia del elemento a buscar.

Por 1) y 2) entonces es lógico pensar que existe por tanto un criterio absolutamente formal de como terminar un ciclo. De hecho... el sentido de la lógica todo ciclo por naturaleza tiene explícitamente las condiciones de entrada y salida y no merece uso alguno ir contra esta corriente.

Tal algoritmo adquiere una forma como la siguiente:



delphi
  1. i := 0; encontrado := false;
  2. repeat
  3. encontrado := (ABuscar = Arreglo[i]);
  4. i := i + 1;
  5. until encontrado OR (i = cantidad)
  6. if encontrado
  7.   then writeln('El elemento está en la posición ' i - 1)
  8.   else writeln('No se ha encontrado el elemento');



Naturalmente, si no hay modo de garantizar de saber tal cantidad de ciclos no es posible llevar a buen puerto el algoritmo anterior... si dependiéramos solamente de la variable flag encontrado podríamos incurrir a un ciclo infinito. En este esquema si sería válido, necesariamente, recurrir al uso de algún escape antes de que surjan problemas. Justamente es el UNICO caso del porqué existe el Break... es la salida como último recurso antes de que la papa quemen. Ergo: no hay un planteo y real necesidad llevarlo a la práctica si el problema te da otros medios.

¿Que dicen ustedes?
  • 0

#4 Rolphy Reyes

Rolphy Reyes

    Advanced Member

  • Moderadores
  • PipPipPip
  • 2.092 mensajes
  • LocationRepública Dominicana

Escrito 02 abril 2013 - 09:35

Saludos.

Si amerita el rompimiento lo hago; soy dado a utilizar For y While.

El While, normalmente para recorrer TDataSet es el uso que le doy y el For para iterraciones más simple.
  • 0

#5 poliburro

poliburro

    Advanced Member

  • Administrador
  • 4.945 mensajes
  • LocationMéxico

Escrito 03 abril 2013 - 08:12

Me gusta el planteamiento que haces amigo, no habí puesto especial cuidado en ello. Aunque es sencillo romper los ciclos, me parece más elegante la manera en que lo propones.

Yo uso while y for, repeat no lo uso pues como programo en varios lenguajes pierdo de vista ese estilo de ciclado en Delphi,

y generalmente recorro todo el ciclado a excepción de cuando realizo operaciones que ante una excepción deban detenerse.


Saludox
  • 0

#6 escafandra

escafandra

    Advanced Member

  • Administrador
  • 4.107 mensajes
  • LocationMadrid - España

Escrito 03 abril 2013 - 09:49

En general es mejor diseñar bien el bucle. Si la el límite está en el número de ciclos el bucle for es el indicado generalmente. Si la condición se encuentra al inicio del bucle la elección será el While y si la condición se encuentra al final debe usarse repeat . Dado que en C este último no existe la opción es do...while que es su equivalente. En C el bucle tipo for difiere un poco del de delphi siendo mas potente.

En alguna ocasión si uso continue y break, están por algo en delph y en C esto lo hago en algoritmos mas complejos para no embrollonar con banderas superfluas y ahorrar ciclos si consumen tiempo.

Supongo que en este tema, como en otros, está las apetencias y estilos de cada uno.


Saludos.
  • 0

#7 bigleaguer

bigleaguer

    Advanced Member

  • Miembros
  • PipPipPip
  • 66 mensajes

Escrito 03 abril 2013 - 12:04

Saludos, comparto los comentario de escafandra y  Rolphy Reyes, cuando en ocasiones se necesita romper un ciclo también uso continue o break, tanto para evitar el uso de banderas adicionales como para facilitar la lectura del código.
  • 0

#8 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.295 mensajes
  • LocationArgentina

Escrito 03 abril 2013 - 01:18

Bueno, tengo que confesarles que la 2da opción es totalmente capciosa y tramposa.  :D
Se supone que en realidad ningún contexto de cualquier problema va a sugerir que explícitamente deba romperse un ciclo utilizando una vía de escape como Break  ;)

Es decir que en realidad el problema y el contexto les está indicando las salidas formales del ciclo, pero que por una cuestión de análisis del momento, y sobre todo en las etapas iniciales, no han sido descubiertas.

Creo que resulta más evidente el porqué NUNCA usaría un Break en un FOR si tenemos algo como esto dentro del ciclo:



delphi
  1. if CumpleCondicion Break;



Nótese que este if es una fuerte señal del verdadero criterio de salida que espera el problema. El recorrido del for podrá completarse si nunca se llega a cumplir tal condición, pero este criterio de finalización es débil frente al if.
Por tanto el sentido común debiera de sugerir entonces que el planteo del for no está del todo pulido. Si en un for vemos tal secuencia de escape entonces es momento de plantearse si no es más conveniente hacer vistosa la condición de salida REAL esperada y no ocultarla dentro.

Esto nos lleva entonces al uso de While o de un Repeat (sobre todo este último diría yo). Como señala Escafandra, y todos sabemos lo que diferencia a un ciclo MIENTRAS-HACER (While) de un ciclo REPETIR-HASTA (Repeat/Do Wile) está en que el primero evalúa primero y luego ejecuta las instrucciones, y el segundo por su parte hace lo inverso: ejecuta y posteriormente evalúa. Esto nos lleva a que podamos garantizar de que un Repeat se ejecutará al menos una vez y que para poder entrar en un While se debe garantizar de que la condición se cumpla inicialmente, de otro modo NUNCA se podrá entrar.

Hay algoritmos que se encaran mejor en un While y otros mejor en un Repeat. Pero en lo que he notado es como si hubiera cierto desprecio por este último... Como si lo dejaran de lado y no existiera. Tan al punto que hasta incluso hay jóvenes que ante una pregunta (que yo haría en un examen) sobre cuantos ciclos hay responden que dos: el "DESDE-HASTA" o For y el MIENTRAS-HACER o While.

Consideraría el uso de las cláusulas de escape solamente en aquellos algoritmos en donde existieran demasiadas y complejas condiciones de salida y/o varios ciclos anidados. Tal como comenta Escafandra, pero en mi opinión, primero trataría de estudiar la posibilidad de hacer un algoritmo más simple o de aplicar algo de "Divide y vencerás".
Pero para algoritmos tan elementales como el del ejemplo inicial me parece una práctica por demás inútil, sin sentido y un atentado contra la cabeza... Y lo más raro es que ese código lo he detectado en varios puntos de la VCL.

Por todo esto, aún yo considero la opción de No. Y en lo posible evitarlo. Veo en un Break una mala práctica... y al igual que usar el Assert en evaluaciones positivas cuando hay mejores opciones y válidas como el try.

¿Que dicen ustedes? ¿Será que me enrosqué de nuevo?  :p

Saludos,
  • 0

#9 cadetill

cadetill

    Advanced Member

  • Moderadores
  • PipPipPip
  • 994 mensajes
  • LocationEspaña

Escrito 04 abril 2013 - 01:05

Buenas,

El uso del Break/Continue es lo mismo que el uso del Exit (para salir de un procedimiento/función/método). Personalmente uso los tres (que para algo los da el lenguaje) si para ellos logro una legibilidad mayor del código.

Imaginemos un procedure que sea algo así



delphi
  1. procedure MiForm.MiProcedure(parametros);
  2. begin
  3.   if condición then
  4.   begin
  5.     // todo un código aquí
  6.   end;
  7. end;



Para mi es más legible algo como



delphi
  1. procedure MiForm.MiProcedure(parametros);
  2. begin
  3.   if not condición then Exit;
  4.  
  5.   // todo un código aquí
  6. end;



Lo mismo pasa con los bucles, si el uso de Break/Continue me facilita la lectura de código (if anidados y demás) no tengo problema en su uso.

Coincido con escafandra en la forma de usar las diferentes formas de iteración (for para límites conocidos, while para condicionales de entrada y repeat/do..while para condicionales de salida).

Nos leemos
  • 0




IP.Board spam blocked by CleanTalk.