41 votes

Problèmes avec les ET et les OU (COBOL)

Je n'arrive pas à faire cette partie correctement. On m'a donné un fichier d'entrée avec un tas de noms, dont certains que je dois ignorer, avec des informations supplémentaires sur chacun d'eux. J'ai essayé d'utiliser des ET et des OU pour ignorer les noms dont je n'avais pas besoin et j'ai obtenu ce résultat.

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

Il s'est débarrassé de toutes les personnes sauf une, mais lorsque j'ai essayé d'ajouter une autre série de AND et OR, le programme a commencé à agir comme si les stipulations n'étaient même pas là.

L'ai-je rendu trop complexe pour le compilateur ? Existe-t-il un moyen plus simple de sauter des choses ?

143voto

Joel Spolsky Points 22686

Essayez d'ajouter des parenthèses pour regrouper les choses logiquement :

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

31voto

paxdiablo Points 341644

Vous puede Vous devriez envisager d'étendre complètement cette expression abrégée, car l'expansion peut ne pas être ce que vous pensez lorsqu'il y a beaucoup de clauses - il est souvent bien mieux d'être explicite.


Cependant, ce qui I serait d'utiliser le 88 Il s'agissait de niveaux spéciaux permettant de spécifier des conditions dans la division des données directement plutôt que d'utiliser des conditions explicites dans le code.

En d'autres termes, mettez quelque chose comme ceci dans votre division de données :

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

Vous pouvez alors utiliser le 88 dans vos expressions :

IF (FIRST-YEAR OR SECOND-YEAR) AND (GS-UNKNOWN OR GS-NO) ...

C'est, à mon avis, plus lisible et c'est tout l'intérêt de COBOL devait ressembler à de l'anglais lisible, après tout.

1 votes

Je ne suis pas un programmeur COBOL mais cette 88 La syntaxe ne ressemble en rien à de l'anglais lisible pour moi.

3 votes

@Asaph, j'ai ajouté le bout de code (lisible) pour tous les non-COBOL, les 99,99999999999% d'entre vous :-)

0 votes

@paxdiablo : Merci. Cela m'aide. Mais je pense que je vais rester avec Java :)

9voto

Bill Woodger Points 4469

La première chose à noter est que le code affiché est le code qui fonctionnait, et que le code modifié qui ne donnait pas le résultat souhaité n'a jamais été affiché. En complément, pourquoi, s'il ne reste qu'une seule personne, une sélection supplémentaire serait-elle nécessaire ? En résumé, la question réelle n'est pas claire et ne va pas au-delà de "Je ne sais pas comment utiliser OR en COBOL. Je ne sais pas comment utiliser AND en COBOL".

Au-delà de ça, il y avait deux questions réelles :

  1. L'ai-je rendu trop complexe pour le compilateur ?

  2. Y a-t-il un moyen plus facile de passer outre [une façon plus claire d'écrire les conditions] ?

A la première, la réponse est Non . C'est loin d'être difficile pour le compilateur. Le compilateur sait exactement comment traiter toutes les combinaisons de OR, AND (et NOT, sur lequel nous reviendrons plus tard). Le problème est le suivant : l'auteur/lecteur humain peut-il coder une condition avec succès de manière à ce que le compilateur sache ce qu'il veut, plutôt que de simplement donner le résultat du compilateur suivant ses règles (qui ne tiennent pas compte des multiples interprétations humaines possibles d'une ligne de code) ?

La deuxième question devient donc :

Comment puis-je écrire une condition complexe que le compilateur comprendra de manière identique à mon intention en tant qu'auteur et de manière identique pour tout lecteur du code ayant une certaine expérience du COBOL ?

Tout d'abord, un rapide réarrangement du code (fonctionnel) de la question :

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

Et du code suggéré dans l'une des réponses :

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

La deuxième version est plus claire, mais (ou et) elle est identique à la première. Elle n'a pas fait fonctionner ce code, elle a permis à ce code de continuer à fonctionner.

La réponse portait sur la résolution du problème de l'augmentation de la complexité d'une condition : parenthèses/parenthèses (simplifier simplement la complexité est une autre possibilité, mais sans l'exemple non fonctionnel, il est difficile de faire des suggestions).

Le code original fonctionne, mais quand il faut être plus complexe, les roues commencent à tomber.

Le code proposé fonctionne, mais il ne résout pas (complètement) le problème de l'extension de la complexité de la condition, car, en mineur, il répète le problème, à l'intérieur de la parenthèse, de l'extension de la complexité de la condition.

Comment cela se fait-il ?

Une condition simple :

IF A EQUAL TO "B"

Une condition un peu plus complexe :

IF A EQUAL TO "B" OR "C"

Une légère, mais pas complète, simplification de cela :

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

Si la condition doit devenir plus complexe, avec un ET, elle peut être simple pour les humains (le compilateur s'en moque, il ne peut pas être dupé) :

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

Mais qu'en est-il de ceci ?

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

Le fait de placer le ET à l'intérieur des parenthèses a permis de reproduire le problème initial pour les humains. Qu'est-ce que cela signifie, et comment cela fonctionne-t-il ?

Une réponse est la suivante :

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

Peut-être plus clair, mais pas pour tout le monde, et encore une fois le problème original existe toujours, en mineur.

Donc :

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

Simplifié, pour la première partie, mais toujours ce problème dans le mineur (il suffit d'ajouter ET ...), donc :

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

menant à :

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

Et :

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

Maintenant, si quelqu'un veut augmenter avec AND, c'est facile et clair. S'il est fait au même niveau que l'une des parties de la condition, il se rattache uniquement à celle-ci. S'il est fait au niveau le plus externe, il s'attache aux deux (tous).

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

ou

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

Et si quelqu'un veut insérer le AND à l'intérieur des parenthèses ? Eh bien, parce qu'à l'intérieur des crochets, c'est simple, et les gens n'ont pas tendance à le faire. Si ce qui se trouve entre les crochets est déjà compliqué, on a tendance à l'ajouter. Il semble qu'une chose qui est simple parce qu'elle est seule n'a pas tendance à être compliquée, alors qu'une chose qui est déjà compliquée (plus d'une chose, pas seule) a tendance à être rendue plus complexe sans trop de réflexion.

COBOL est un langage ancien. De nombreux anciens programmes écrits en COBOL fonctionnent encore. De nombreux programmes COBOL doivent être modifiés, ou simplement lus pour comprendre quelque chose, et ce plusieurs fois au cours de leur vie de plusieurs années.

Lorsque l'on modifie le code, en ajoutant quelque chose à une condition, il est préférable que les parties originales de la condition n'aient pas besoin d'être "perturbées". Si la complexité est laissée entre parenthèses, il est plus probable que le code doive être perturbé, ce qui augmente le temps de compréhension (il est plus complexe) et de modification (plus de soin est nécessaire, plus de tests sont nécessaires, car le code est perturbé).

De nombreux anciens programmes seront des exemples de mauvaises pratiques. Il n'y a pas grand-chose à faire à ce sujet, si ce n'est d'être prudent avec eux.

Il n'y a aucune excuse pour écrire un nouveau code qui nécessite plus de maintenance et d'attention à l'avenir que ce qui est absolument nécessaire.

Les exemples ci-dessus peuvent être considérés comme longs. C'est du COBOL, non ? Beaucoup de saisie ? Mais le COBOL offre une immense flexibilité dans la définition des données. Le COBOL possède, entre autres, le niveau 88, le nom de la condition.

Voici des définitions de données pour une partie de ce qui précède :

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

La condition devient :

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

Au lieu de se limiter à des valeurs littérales, toutes les valeurs littérales pertinentes ont maintenant un nom, de sorte que le codeur peut indiquer ce qu'elles signifient réellement, ainsi que les valeurs réelles qui portent cette signification. Si d'autres catégories doivent être ajoutées à PARCEL-IS-OUTSIZED, la clause VALUE du niveau 88 est étendue.

Si une autre condition doit être combinée, il est beaucoup plus simple de le faire.

Est-ce que tout cela est vrai ? Eh bien, oui. Regardez-le de cette façon.

COBOL opère sur les résultats d'une condition où elle est codée.

If condition

Les conditions simples peuvent être composées par l'utilisation de parenthèses, pour former une condition :

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

Et ainsi de suite, jusqu'aux limites du compilateur.

L'humain doit juste gérer la condition qu'il souhaite pour l'objectif à atteindre. Pour le flux logique général, regardez la condition If. Pour la vérification, regardez le plus petit détail. Pour un sous-ensemble, regardez la partie de la condition pertinente pour le sous-ensemble.

Utilisez des conditions simples. Rendre les conditions simples à l'aide de crochets/parenthèses. Créez des conditions complexes, si nécessaire, en combinant des conditions simples. Utilisez des noms de conditions pour les comparaisons avec des valeurs littérales.

OR et AND ont été traités jusqu'à présent. NOT est souvent considéré comme un élément à traiter avec prudence :

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

Donc PAS n'est pas effrayant, si c'est rendu simple.

Pendant tout ce temps, j'ai supprimé des espaces. Parce que les parenthèses sont là, j'aime les mettre en évidence. J'aime structurer et indenter les conditions, pour souligner le sens que je leur ai donné.

Donc :

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

(et plus sculptée que ça aussi). En structurant, j'espère a) que je ferai moins de bêtises et b) que si je fais des bêtises, quelqu'un aura plus de chances de s'en rendre compte.

Si les conditions ne sont pas simplifiées, la compréhension du code est plus difficile. La modification du code est plus difficile. Pour les personnes apprenant le COBOL, garder les choses simples est un avantage à long terme pour tous.

2voto

Sean Elgin Points 21

En règle générale, j'évite l'utilisation de AND dans la mesure du possible. Les IF imbriqués fonctionnent tout aussi bien, sont plus faciles à lire et, avec une utilisation judicieuse des 88 niveaux, ne doivent pas aller très loin. Cela semble beaucoup plus facile à lire, du moins dans mon expérience :

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'.

Alors le code est aussi simple que ceci :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X