source portable opencobol open cobol logical-operators

portable - cobol open



Problemas con AND y OR(COBOL) (4)

Tengo una tarea que debe entregarse mañana y parece que no puedo hacer bien esta parte. Ver Me dieron un archivo de entrada con varios nombres, algunos de los cuales necesito omitir, con información adicional sobre cada uno. Estaba intentando usar ANDs y OR para omitir los nombres que no necesitaba y se me ocurrió esto.

IF DL-CLASS-STANDING = ''First Yr'' OR ''Second Yr'' AND GRAD-STAT-IN = '' '' OR ''X''

Se deshizo de todas menos una persona, pero cuando traté de agregar otro conjunto de AND y OR el programa comenzó a actuar como las estipulaciones donde ni siquiera estaba.

¿Lo hice demasiado complejo para el compilador? ¿Hay alguna manera más fácil de omitir las cosas?


Como regla, evito el uso de AND si es posible. Los IF anidados funcionan igual de bien, son más fáciles de leer y con un uso juicioso de 88 niveles, no tienen que ir muy profundo. Esto parece mucho más fácil de leer, al menos en mi experiencia:

05 DL-CLASS-STANDING PIC X(20) VALUE SPACE. 88 DL-CLASS-STANDING-VALID VALUE ''First Yr'' ''Second Yr''. 05 GRAD-STAT-IN PIC X VALUE SPACE. 88 GRAD-STAT-IN-VALID VALUE SPACE ''N''.

Entonces el código es tan simple como esto:

IF DL-CLASS-STANDING-VALID IF GRAD-STAT-IN-VALID ACTION ... .


Intente agregar algunos paréntesis para agrupar las cosas lógicamente:

IF (DL-CLASS-STANDING = ''First Yr'' OR ''Second Yr'') AND (GRAD-STAT-IN = '' '' OR ''X'')


Lo primero a tener en cuenta es que el código que se muestra es el código que estaba funcionando, nunca se mostró el código modificado que no dio el resultado deseado. Como una adición, ¿por qué, si solo quedara una persona, sería necesaria más selección? En resumen, la pregunta real no está clara más allá de decir "No sé cómo usar O en COBOL. No sé cómo usar Y en COBOL".

Más allá de eso, hubo dos preguntas reales:

  1. ¿Lo hice demasiado complejo para el compilador?

  2. ¿Hay alguna manera más fácil de omitir las cosas [hay una forma más clara de escribir las condiciones]?

Para el primero, la respuesta es No, está muy lejos de ser difícil para el compilador. El compilador sabe exactamente cómo manejar cualquier combinación de O, Y (y NO, que veremos más adelante). El problema es si el escritor / lector humano puede codificar una condición de manera tal que el compilador sepa lo que quiere, en lugar de simplemente dar el resultado del compilador siguiendo sus reglas (que no tienen en cuenta las posibles interpretaciones humanas de una línea). de código)?

La segunda pregunta por lo tanto se convierte en:

¿Cómo escribo una condición compleja que el compilador entenderá de manera idéntica a mi intención como autor y de forma idéntica para cualquier lector del código con alguna experiencia de COBOL?

En primer lugar, una reorganización rápida del código (de trabajo) en la Pregunta:

IF DL-CLASS-STANDING = ''First Yr'' OR ''Second Yr'' AND GRAD-STAT-IN = '' '' OR ''X''

Y del código sugerido en una de las Respuestas:

IF (DL-CLASS-STANDING = ''First Yr'' OR ''Second Yr'') AND (GRAD-STAT-IN = '' '' OR ''X'')

La segunda versión es más clara, pero (oy) es idéntica a la primera. No hizo que el código funcionara, permitió que el código siguiera funcionando.

La respuesta se refería a la resolución del problema de una condición cuya complejidad aumenta: corchetes / paréntesis (simplificar la complejidad es otra posibilidad, pero sin el ejemplo que no funciona es difícil hacer sugerencias).

El código original funciona pero cuando necesita ser más complejo, las ruedas comienzan a caerse.

El código sugerido funciona, pero no (completamente) resuelve el problema de extender la complejidad de la condición, porque, en menor, repite el problema, dentro del paréntesis, de extender la complejidad de la condición.

¿Cómo es esto?

Una condición simple:

IF A EQUAL TO "B"

Una condición un poco más compleja:

IF A EQUAL TO "B" OR "C"

Una simplificación leve pero no completa de eso:

IF (A EQUAL TO "B" OR "C")

Si la condición tiene que volverse más compleja, con un AND, puede ser simple para los humanos (al compilador no le importa, no se puede engañar):

IF (A EQUAL TO "B" OR "C") AND (E EQUAL TO "F")

¿Pero que hay de esto?

IF (A EQUAL TO "B" OR "C" AND E EQUAL TO "F")

Colocar el AND dentro de los corchetes ha permitido replicar el problema original para los humanos. ¿Qué significa eso? ¿Cómo funciona?

Una respuesta es esta:

IF (A EQUAL TO ("B" OR "C") AND E EQUAL TO "F")

Quizás más claro, pero no para todos, y nuevamente el problema original aún existe, en el menor.

Asi que:

IF A EQUAL TO "B" OR A EQUAL TO "C"

Simplificado, para la primera parte, pero todavía ese problema en el menor (solo agregue AND ...), entonces:

IF (A EQUAL TO "B") OR (A EQUAL TO "C")

Llevando a:

IF ((A EQUAL TO "B") OR (A EQUAL TO "C"))

Y:

IF ((A EQUAL TO "B") OR (A EQUAL TO C))

Ahora, si alguien quiere aumentar con AND, es fácil y claro. Si se hace en el mismo nivel que una de las partes de condición, solo se une a eso. Si se hace en el nivel más externo, se une a ambos (todos).

IF (((A EQUAL TO "B") AND (E EQUAL TO "F")) OR (A EQUAL TO "C"))

o

IF (((A EQUAL TO "B") OR (A EQUAL TO "C")) AND (E EQUAL TO "F"))

¿Qué pasa si alguien quiere insertar el AND dentro de los corchetes? Bueno, porque dentro de los corchetes es simple, las personas no tienden a hacer eso. Si lo que está dentro de los corchetes ya es complicado, tiende a agregarse. Parece que algo que es simple por sí solo tiende a no complicarse, mientras que algo que ya es complicado (más de una cosa, no por sí mismo) tiende a hacerse más complejo sin pensarlo demasiado.

COBOL es un lenguaje antiguo. Man viejos programas escritos en COBOL todavía están en ejecución. Muchos programas COBOL tienen que ser enmendados, o simplemente leídos para comprender algo, muchas veces durante sus vidas de muchos años.

Al cambiar el código, al agregar algo a una condición, es mejor si las partes originales de la condición no necesitan ser "alteradas". Si la complejidad se deja entre corchetes, es más probable que el código deba ser alterado, lo que aumenta la cantidad de tiempo de comprensión (es más complejo) y cambiante (se necesita más atención, se necesitan más pruebas porque se altera el código). .

Muchos programas antiguos serán ejemplos de malas prácticas. No hay mucho que hacer al respecto, excepto tener cuidado con ellos.

No hay excusa para escribir un nuevo código que requiera más mantenimiento y cuidado en el futuro de lo que es absolutamente necesario.

Ahora, los ejemplos anteriores pueden considerarse largos. Es COBOL, ¿verdad? Un montón de tipeo? Pero COBOL ofrece una inmensa flexibilidad en la definición de datos. COBOL tiene, como parte de eso, el Nivel 88, el Nombre de la condición.

Aquí hay una definición de datos para parte de lo anterior:

01 A PIC X. 88 PARCEL-IS-OUTSIZED VALUE "B" "C". 01 F PIC X. 88 POSTAGE-IS-SUFFICIENT VALUE "F".

La condición se convierte en:

IF PARCEL-IS-OUTSIZED AND POSTAGE-IS-SUFFICIENT

En lugar de solo valores literales, todos los valores literales relevantes ahora tienen un nombre, de modo que el codificador puede indicar lo que realmente significan, así como los valores reales que tienen ese significado. Si se agregan más categorías a PARCEL-IS-OUTSIZED, se amplía la cláusula VALOR en el nivel 88.

Si se quiere combinar otra condición, es mucho más simple hacerlo.

¿Es esto verdad? Bueno, sí. Míralo de esta manera.

COBOL opera sobre los resultados de una condición codificada.

If condition

Las condiciones simples pueden combinarse mediante el uso de corchetes, para hacer una condición:

If condition = If (condition) = If ((condition1) operator (condition2))...

Y así sucesivamente, hasta los límites del compilador.

El humano solo tiene que lidiar con la condición que quiere para el propósito que tiene entre manos. Para el flujo lógico general, observe la condición If, para verifique el detalle más bajo, para un subconjunto, observe la parte de la condición relevante para el subconjunto.

Usa condiciones simples. Haga las condiciones simples a través de paréntesis / paréntesis. Realice condiciones complejas, donde sea necesario, combinando condiciones simples. Use nombres de condición para comparaciones con valores literales.

O y Y han sido tratados hasta ahora. NO se ve a menudo como algo para tratar con cautela:

IF NOT A EQUAL TO B IF A NOT EQUAL TO B IF (NOT (A EQUAL TO B)), remembering that this is just IF condition

Así que NO no es aterrador, si se simplifica.

A lo largo, he estado editando espacios. Debido a que los corchetes están ahí, me gusta ponerlos en su cara. Me gusta estructurar y sangrar condiciones, para enfatizar el significado que les he dado.

Asi que:

IF ( ( ( condition1 ) OR ( condition2 ) ) AND ( ( condition3 ) OR ( condition4 ) ) )

(y más esculpido que eso también). Al estructurar, espero que a) Me equivoque menos yb) cuando / si me equivoco, alguien tiene una mejor oportunidad de darse cuenta.

Si las condiciones no se simplifican, entender el código es más difícil. Cambiar el código es más difícil. Para las personas que aprenden COBOL, mantener las cosas simples es un beneficio a largo plazo para todos.


Wow, ha pasado tanto tiempo que ni siquiera puedo recordar si esa sintaxis es válida o no :-) Es posible que desee analizar la expresión abreviada porque la expansión puede no ser lo que usted piensa cuando hay muchas cláusulas. Mucho mejor para ser explícito.

Sin embargo, lo que haría sería usar las 88 variables de nivel para hacer esto más legible: 88 s eran niveles especiales para permitir que las condiciones se especificaran directamente en la división de datos en lugar de usar condiciones explícitas en el código.

En otras palabras, ponga algo como esto en su división de datos (esto es de la memoria ya que mi único compilador COBOL está en el mainframe en el trabajo y me voy hoy).

03 DL-CLASS-STANDING PIC X(20). 88 IS-FIRST-YEAR VALUE ''First Yr''. 88 IS-SECOND-YEAR VALUE ''Second Yr''. 03 GRAD-STAT-IN PIC X. 88 GRAD-STAT-UNKNOWN VALUE '' ''. 88 GRAD-STAT-NO VALUE ''X''.

Entonces puedes usar las 88 variables de nivel en tus expresiones:

IF (IS-FIRST-YEAR OR IS-SECOND-YEAR) AND (GRAD-STAT-UNKNOWN OR GRAD-STAT-NO) ...

Esto es, en mi opinión, más legible y el objetivo de COBOL era parecerse al inglés legible, después de todo.