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

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

36 голосов
/ 03 декабря 2010

У меня есть домашнее задание, которое нужно сдать завтра, и я не могу понять, что это одна часть правильно.Смотрите, мне дали входной файл с кучей имен, некоторые из которых мне нужно пропустить, с дополнительной информацией о каждом.Я пытался использовать AND и OR, чтобы пропустить ненужные имена, и придумал это.

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

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

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

Ответы [ 4 ]

134 голосов
/ 03 декабря 2010

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

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

28 голосов
/ 03 декабря 2010

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

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

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

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

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

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

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

8 голосов
/ 31 декабря 2013

Первое, на что нужно обратить внимание, это то, что показанный код - это код, который работал, исправленный код, который не дал желаемого результата, никогда не показывался. Как дополнение, почему, если бы остался только один человек, был бы необходим дополнительный отбор? Подводя итог, реальный вопрос неясен, если не сказать: «Я не знаю, как использовать ИЛИ в Коболе. Я не знаю, как использовать И в Коболе».

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

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

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

Во-первых, ответ - нет, компилятору это совсем не сложно. Компилятор точно знает, как обрабатывать любые комбинации OR, AND (и NOT, о чем мы поговорим позже). Проблема в том, может ли писатель / читатель-человек успешно кодировать условие, чтобы компилятор знал, чего он хочет, а не просто давать результат от компилятора, следуя его правилам (которые не учитывают множественные возможные интерпретации строки человеком кода)?

Поэтому второй вопрос становится:

Как мне написать сложное условие, которое компилятор будет понимать идентично моему намерению как автора и идентично любому читателю кода, имеющему некоторый опыт работы с 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")

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

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")

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

Итак:

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

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

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"))

или

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, для проверки посмотрите на самую низкую деталь, для подмножества, посмотрите на часть условия, относящуюся к подмножеству.

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

ИЛИ И И до сих пор лечили.НЕ часто воспринимается как нечто осторожное:

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

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

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

Итак:

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

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

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

1 голос
/ 21 ноября 2017

Как правило, я избегаю использования AND, если это вообще возможно.Работы с вложенным IF так же легко читаются, и при разумном использовании 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 ...  .
...