Проблемы с AND и OR (COBOL)

Кажется, я не могу правильно понять эту часть. Мне дали входной файл с кучей имен, некоторые из которых мне нужно пропустить, с дополнительной информацией о каждом. Я пытался использовать И и ИЛИ, чтобы пропустить имена, которые мне не нужны, и придумал это.

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

Он избавился от всех, кроме одного человека, но когда я попытался добавить еще один набор И и ИЛИ, программа начала вести себя как оговорки, которых даже не было.

Я сделал это слишком сложным для компилятора? Есть ли более простой способ пропустить вещи?


person Kimmy1235    schedule 03.12.2010    source источник


Ответы (4)


Попробуйте добавить круглые скобки для логической группировки:

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

person Joel Spolsky    schedule 03.12.2010

Вы можете полностью расширить это сокращенное выражение, поскольку расширение может быть не таким, как вы думаете, когда есть много предложений - часто гораздо лучше быть явным.


Однако, что я сделал бы, так это использовал бы переменные уровня 88, чтобы сделать это более читабельным — это были специальные уровни, позволяющие указывать условия непосредственно в разделе данных, а не использовать явные условия в коде.

Другими словами, поместите что-то вроде этого в свой раздел данных:

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

Затем вы можете использовать переменные уровня 88 в своих выражениях:

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

Это, на мой взгляд, более читабельно, и весь смысл COBOL в конце концов был в том, чтобы выглядеть как читабельный английский.

person paxdiablo    schedule 03.12.2010
comment
Я не программист на COBOL, но этот синтаксис 88 не похож на читабельный английский для меня. - person Asaph; 03.12.2010
comment
@Asaph, добавил (читаемый) бит кода для всех людей, не использующих COBOL, всех 99,99999999999% из вас :-) - person paxdiablo; 03.12.2010
comment
@paxdiablo: Спасибо. Что помогает. Но я думаю, что я буду придерживаться Java. :) - person Asaph; 03.12.2010
comment
к сожалению, Grad-Stat является входным файлом, и, таким образом, и X будут в том же месте, где он читается. - person Kimmy1235; 03.12.2010
comment
Уровень 88 — это COBOL-способ выполнения перечисления. - person Paul Morgan; 03.12.2010
comment
@ Кимми, все в порядке, 88 - это отдельные биты одного символа, просто способ упростить условия. Это GRAD-STAT-IN, который занимает один символ, 88 предназначены для проверки конкретных значений. - person paxdiablo; 03.12.2010
comment
Гораздо более приятное решение, чем буквальные чеки. - person Joe Zitzelberger; 03.12.2010
comment
@Paul: 88-уровневые уровни COBOL не совсем такие же, как перечисления C. Уровень 88 может иметь несколько значений, например 'X' 'Y' 'Z' или 90 THRU 100. Более точной моделью была бы функция, возвращающая bool, которая возвращает true, если совпадают какие-либо значения. Именно так я написал это в своем преобразователе объявлений COBOL-to-C++ (но также предоставил перечисление, если это возможно). - person dan04; 26.02.2011

Первое, что нужно отметить, это то, что показанный код — это код, который работал, а измененный код, который не дал желаемого результата, так и не был показан. В качестве дополнения, почему, если остался только один человек, потребовался бы дополнительный отбор? Подводя итог, фактический вопрос неясен, если не сказать: «Я не знаю, как использовать OR в COBOL. Я не знаю, как использовать AND в COBOL».

Кроме того, было два актуальных вопроса:

  1. Я сделал это слишком сложным для компилятора?

  2. Есть ли более простой способ пропустить вещи [есть ли более четкий способ написать условия]?

На первый ответ Нет. Это совсем не сложно для компилятора. Компилятор точно знает, как обрабатывать любые комбинации ИЛИ, И (и НЕ, к чему мы вернемся позже). Проблема в том, может ли писатель/читатель-человек успешно закодировать условие, чтобы компилятор знал, чего он хочет, а не просто выдавал результат от компилятора, следуя его правилам (которые не учитывают множественные возможные человеческие интерпретации строки). кода)?

Таким образом, второй вопрос становится следующим:

Как мне написать сложное условие, которое компилятор будет понимать так же, как я задумал как автор, и так же, как для любого читателя кода, имеющего некоторый опыт работы с COBOL?

Во-первых, быстрая перестановка (рабочего) кода в вопросе:

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

И предлагаемого кода в одном из ответов:

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

Вторая версия понятнее, но (или и) идентична первой. Это не заставило этот код работать, оно позволило этому коду продолжать работать.

Ответ касался решения проблемы увеличения сложности условия: скобки/круглые скобки (простое упрощение сложности - еще одна возможность, но без нерабочего примера трудно делать предложения).

Исходный код работает, но когда нужно усложнить, начинают отваливаться колеса.

Предложенный код работает, но он не решает (полностью) проблему увеличения сложности условия, потому что в второстепенной форме он повторяет проблему увеличения сложности условия в круглых скобках. состояние.

Как это так?

Простое условие:

IF A EQUAL TO "B"

Чуть более сложное условие:

IF A EQUAL TO "B" OR "C"

Небольшое, но не полное упрощение этого:

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

Если условие должно стать более сложным, с И, оно может быть простым для людей (компилятору все равно, его нельзя обмануть):

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

Но что из этого?

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

Помещение И внутри скобок позволило воспроизвести первоначальную проблему для людей. Что это значит и как это работает?

Один ответ таков:

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

Возможно, понятнее, но не всем, и опять же исходная проблема все же существует, в миноре.

So:

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

Упрощенно, для первой части, но все же эта проблема в второстепенной (просто добавить И...), так что:

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

Ведущий к:

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

И:

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

Теперь, если кто-то хочет увеличить с помощью AND, это легко и понятно. Если это делается на том же уровне, что и одна из частей условия, оно прикрепляется только к ней. Если это делается на самом внешнем уровне, оно присоединяется к обоим (всем).

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

or

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

Что делать, если кто-то хочет вставить И внутри скобок? Ну, потому что внутри скобок все просто, а люди так не делают. Если то, что находится внутри скобок, уже сложно, оно, как правило, добавляется. Кажется, что нечто простое, существующее само по себе, обычно не усложняется, в то время как нечто уже сложное (более чем одно, не само по себе) имеет тенденцию усложняться без особых дальнейших размышлений.

COBOL — старый язык. Многие старые программы, написанные на языке COBOL, все еще работают. Многие программы на языке COBOL должны быть изменены или просто прочитаны, чтобы что-то понять, и это много раз в течение многих лет их существования.

При изменении кода, добавляя что-то к условию, лучше всего, если исходные части условия не нужно "тревожить". Если сложность оставлена ​​в скобках, более вероятно, что код нуждается в нарушении, что увеличивает количество времени на понимание (он более сложен) и изменение (требуется больше внимания, необходимо больше тестирования, потому что код нарушен) .

Многие старые программы будут примерами плохой практики. С этим ничего не поделаешь, кроме как быть осторожным с ними.

Нет никакого оправдания написанию нового кода, который потребует в будущем больше обслуживания и заботы, чем это абсолютно необходимо.

Теперь приведенные выше примеры можно считать многословными. Это КОБОЛ, верно? Много печатать? Но COBOL дает огромную гибкость в определениях данных. COBOL имеет, как часть этого, уровень 88, имя условия.

Вот определения данных для части вышеперечисленного:

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

Условие становится:

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

Вместо просто литеральных значений все соответствующие литеральные значения теперь имеют имена, так что кодировщик может указать, что они на самом деле означают, а также фактические значения, которые несут это значение. Если в PARCEL-IS-OUTSIZED необходимо добавить больше категорий, предложение VALUE на уровне 88 расширяется.

Если нужно совместить еще одно условие, то сделать это гораздо проще.

Это все правда? Ну да. Рассмотрим этот вариант.

COBOL работает с результатами закодированного состояния.

If condition

Простые условия можно составить с помощью скобок, чтобы получилось условие:

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

И так далее, до пределов возможностей компилятора.

Человек просто должен иметь дело с состоянием, которое он хочет для поставленной цели. Для общего логического потока посмотрите на условие If. Для проверки посмотрите на самую нижнюю деталь. Для подмножества посмотрите на часть условия, относящуюся к подмножеству.

Используйте простые условия. Упростите условия с помощью скобок/круглых скобок. Создавайте сложные условия там, где это необходимо, комбинируя простые условия. Используйте имена условий для сравнения с литеральными значениями.

ИЛИ и И лечились до сих пор. NOT часто рассматривается как нечто, к чему следует относиться с осторожностью:

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

Так что НЕ страшно, если сделать просто.

Повсюду я редактировал пробелы. Поскольку там есть скобки, мне нравится делать их прямо на лице. Мне нравится структурировать условия и делать отступы, чтобы подчеркнуть значение, которое я им придал.

So:

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

(и более скульптурный, чем это). Структурируя, я надеюсь, что а) я ошибаюсь меньше и б) когда/если я ошибаюсь, у кого-то больше шансов это заметить.

Если условия не упрощаются, то разобраться в коде сложнее. Изменить код сложнее. Для людей, изучающих COBOL, сохранение простоты является долгосрочной выгодой для всех.

person Bill Woodger    schedule 31.12.2013

Как правило, я избегаю использования AND, если это вообще возможно. Точно так же работают вложенные ЕСЛИ, их легче читать, и при разумном использовании 88-уровней не нужно слишком углубляться. Это кажется намного легче читать, по крайней мере, по моему опыту:

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

Тогда код такой же простой:

IF DL-CLASS-STANDING-VALID
    IF GRAD-STAT-IN-VALID
        ACTION ...  .
person Sean Elgin    schedule 21.11.2017
comment
Это касается и других языков. И для регулярного выражения. Разбивайте сложные части на множество более простых частей. - person Peter Mortensen; 12.04.2020