【COBOL 書き1-12-13】完璧に見えたものは、完璧ではないかもしれない〜確認は重要ね!

🧩今日の学び
・一つの条件で正しい結果が出ても完成とは限らず、偶数・奇数など分岐するすべての条件で同じ設計意図が成立するか確認する必要がある。
・今回の奇数5件では、2で割った商の「2」をそのままLOW-POSとHIGH-POSに使ったため、本来選ぶべき3番目より1つ手前を参照してしまった。
・ロジックの考え方が正しくても、実装の小さなズレは残るため、条件を変えて実行し結果を確かめることが完成への重要な工程になる。

なるお)さ、シンデレラよろしく、いびられていくとしますか。

係長)いびり足りねーよ。

な)あれだけ雑巾の搾り汁とか飲ませておいて!

係)人聞きの悪いこと言うな!

な)そんで、かぼちゃの馬車に乗ってお城の舞踏会に出るのね。

って、シンデレラって王子とチークタイム踊れたんなら、結構遊んでたんじゃね疑惑。

そりゃ、「まぁ!なんてはしたないコなのかしら!よなよな外に出歩いているからそうなるのよ!」てなもんで、親姉妹の再教育始まるっつーの。

でも、「あたい、掃除嫌い」とか言い出したりして、これが積木くずしなのね…

これでは、王子も騙されてお家取り潰しにもなるって話でしょ。

つまり、アントワネットなのね。あのこはアントワネット。スキーがなければスノボをすればいいじゃないとか言ってたんすよ!わかりますか!

係)満足したんなら、さっさとはじめろ。

な)あい…

な)で、なんだっけ?

目次

PROCEDURE DIVISIONだけではまだ完成じゃない

な)あー、実行だった、って、まだPROCEDURE部分しか書いてないじゃない…

📝 COBOL PROCEDURE部
  1       PROCEDURE DIVISION.
  2           SORT SORT-FILE
  3               ON ASCENDING KEY SORT-AMOUNT
  4               USING INPUT-FILE
  5               GIVING OUTPUT-FILE.
  6           OPEN INPUT OUTPUT-FILE.
  7
  8           PERFORM UNTIL EOF-FLAG = "Y"
  9               READ OUTPUT-FILE
 10                   AT END MOVE "Y" TO EOF-FLAG
 11                   NOT AT END
 12                       IF OUTPUT-AMOUNT IS NUMERIC
 13                           AND OUTPUT-AMOUNT > 0
 14                           ADD 1 TO COUNT-LOOPING
 15                       END-IF
 16               END-READ
 17           END-PERFORM.
 18           CLOSE OUTPUT-FILE.
 19
 20           DIVIDE COUNT-LOOPING BY 2 GIVING LOW-POS
 21               REMAINDER REMAIND.
 22           IF REMAIND = 0
 23               COMPUTE HIGH-POS = LOW-POS + 1
 24           ELSE
 25               COMPUTE HIGH-POS = LOW-POS
 26           END-IF.
 27
 28           OPEN INPUT OUTPUT-FILE.
 29           MOVE "N" TO EOF-FLAG.
 30           PERFORM UNTIL EOF-FLAG = "Y"
 31               READ OUTPUT-FILE
 32                   AT END MOVE "Y" TO EOF-FLAG
 33                   NOT AT END
 34                       IF OUTPUT-AMOUNT IS NUMERIC
 35                           AND OUTPUT-AMOUNT > 0
 36                           ADD 1 TO READ-COUNT
 37                           IF READ-COUNT = LOW-POS
 38                               MOVE OUTPUT-AMOUNT TO LOW-VAL
 39                           END-IF
 40                           IF READ-COUNT = HIGH-POS
 41                               MOVE OUTPUT-AMOUNT TO HIGH-VAL
 42                           END-IF
 43                       END-IF
 44               END-READ
 45           END-PERFORM.
 46           CLOSE OUTPUT-FILE.
 47
 48           COMPUTE MEDIAN-VAL = (LOW-VAL + HIGH-VAL) / 2.
 49           DISPLAY "COUNT=" COUNT-LOOPING
 50                   " LOW-POS=" LOW-POS " HIGH-POS=" HIGH-POS.
 51           DISPLAY "MEDIAN IS " MEDIAN-VAL.
 52           STOP RUN.

係)だからさっさとやれって言ってんだろ。

な)むひー、面倒くさいところ残ってた…

ファイルを使うための設定をそろえる

な)まぁIDENTIFICATIONとENVIRONMENTはこんなんでいいでしょと。

📝 COBOL 最初のところ
       IDENTIFICATION DIVISION.
       PROGRAM-ID. NARUO.

       ENVIRONMENT DIVISION.
       INPUT-OUTPUT SECTION.
       FILE-CONTROL.
           SELECT INPUT-FILE
               ASSIGN TO "naruo2.txt"
               ORGANIZATION IS LINE SEQUENTIAL.
           SELECT SORT-FILE
               ASSIGN TO "sortwork.tmp".
           SELECT OUTPUT-FILE
               ASSIGN TO "naruo2_sorted.txt"
               ORGANIZATION IS LINE SEQUENTIAL.

問題は次のところだからして…

INPUT・SORT・OUTPUTのレコードを定義する

まずは、SORT FILEの用意でSDだからその準備しとこか。

値をソートするとして、あとあとINPUT-FILEとOUTPUT-FILEがでてきて同じようなかんじになるから、それとあわせておくとして、SDといっしょにFDも設定しちゃおう

優秀すぎて怖いわ

📝 COBOL sample.cob
       DATA DIVISION.
       FILE SECTION.
       FD INPUT-FILE.
       01 INPUT-RECORD.
          05 INPUT-SALE-DATE PIC X(10).
          05 INPUT-ITEM-NAME PIC X(20).
          05 INPUT-AMOUNT    PIC 9(5).

       SD SORT-FILE.
       01 SORT-RECORD.
          05 SORT-SALE-DATE PIC X(10).
          05 SORT-ITEM-NAME PIC X(20).
          05 SORT-AMOUNT    PIC 9(5).

       FD OUTPUT-FILE.
       01 OUTPUT-RECORD.
          05 OUTPUT-SALE-DATE PIC X(10).
          05 OUTPUT-ITEM-NAME PIC X(20).
          05 OUTPUT-AMOUNT    PIC 9(5).

ってかんじかなぁ

処理に必要な変数をWORKING-STORAGEにそろえる

な)ほんでもって次、WORKING-STORAGEいっちゃいましょう。

ここ、多くてやだな…脳にダイレクトに繋いで、思い描いたものがそうなる変数をそろそろ開発してっての!

とりあえず、処理部分から抜き出した変数どもはこれら

📝 COBOL sample.cob
EOF-FLAG
COUNT-LOOPING
READ-COUNT
REMAIND
LOW-POS
HIGH-POS
LOW-VAL
HIGH-VAL
MEDIAN-VAL

調整するとして、EOF-FLAGはNをいれておいて、あとは数字で0を入れておけばいいかしらね

あ、余り(REMAIND)は一桁しか無いからそうしておこう

MEDIAN-VALは割り物にもなるから、クーニャンってことで、小数点が必要な場合もあるかなってもんで、こうRUSH!

秀ですぎだわ!

📝 COBOL sample.cob
       WORKING-STORAGE SECTION.
       01 EOF-FLAG      PIC X VALUE "N".
       01 COUNT-LOOPING PIC 9(2) VALUE 0.
       01 READ-COUNT    PIC 9(2) VALUE 0.
       01 REMAIND       PIC 9    VALUE 0.
       01 LOW-POS       PIC 9(2) VALUE 0.
       01 HIGH-POS      PIC 9(2) VALUE 0.
       01 LOW-VAL       PIC 9(5) VALUE 0.
       01 HIGH-VAL      PIC 9(5) VALUE 0.
       01 MEDIAN-VAL    PIC 9(5)V9 VALUE 0.

すてき!

全部を合体して偶数データで実行する

な)もう合体しかないわ!エロい意味においてさえも!

📝 COBOL sample.cob
  1       IDENTIFICATION DIVISION.
  2       PROGRAM-ID. NARUO.
  3
  4       ENVIRONMENT DIVISION.
  5       INPUT-OUTPUT SECTION.
  6       FILE-CONTROL.
  7           SELECT INPUT-FILE
  8               ASSIGN TO "naruo2.txt"
  9               ORGANIZATION IS LINE SEQUENTIAL.
 10           SELECT SORT-FILE
 11               ASSIGN TO "sortwork.tmp".
 12           SELECT OUTPUT-FILE
 13               ASSIGN TO "naruo2_sorted.txt"
 14               ORGANIZATION IS LINE SEQUENTIAL.
 15
 16       DATA DIVISION.
 17       FILE SECTION.
 18       FD INPUT-FILE.
 19       01 INPUT-RECORD.
 20          05 INPUT-SALE-DATE PIC X(10).
 21          05 INPUT-ITEM-NAME PIC X(20).
 22          05 INPUT-AMOUNT    PIC 9(5).
 23
 24       SD SORT-FILE.
 25       01 SORT-RECORD.
 26          05 SORT-SALE-DATE PIC X(10).
 27          05 SORT-ITEM-NAME PIC X(20).
 28          05 SORT-AMOUNT    PIC 9(5).
 29
 30       FD OUTPUT-FILE.
 31       01 OUTPUT-RECORD.
 32          05 OUTPUT-SALE-DATE PIC X(10).
 33          05 OUTPUT-ITEM-NAME PIC X(20).
 34          05 OUTPUT-AMOUNT    PIC 9(5).
 35
 36       WORKING-STORAGE SECTION.
 37       01 EOF-FLAG      PIC X VALUE "N".
 38       01 COUNT-LOOPING PIC 9(2) VALUE 0.
 39       01 READ-COUNT    PIC 9(2) VALUE 0.
 40       01 REMAIND       PIC 9    VALUE 0.
 41       01 LOW-POS       PIC 9(2) VALUE 0.
 42       01 HIGH-POS      PIC 9(2) VALUE 0.
 43       01 LOW-VAL       PIC 9(5) VALUE 0.
 44       01 HIGH-VAL      PIC 9(5) VALUE 0.
 45       01 MEDIAN-VAL    PIC 9(5)V9 VALUE 0.
 46
 47       PROCEDURE DIVISION.
 48           SORT SORT-FILE
 49               ON ASCENDING KEY SORT-AMOUNT
 50               USING INPUT-FILE
 51               GIVING OUTPUT-FILE.
 52           OPEN INPUT OUTPUT-FILE.
 53
 54           PERFORM UNTIL EOF-FLAG = "Y"
 55               READ OUTPUT-FILE
 56                   AT END MOVE "Y" TO EOF-FLAG
 57                   NOT AT END
 58                       IF OUTPUT-AMOUNT IS NUMERIC
 59                           AND OUTPUT-AMOUNT > 0
 60                           ADD 1 TO COUNT-LOOPING
 61                       END-IF
 62               END-READ
 63           END-PERFORM.
 64           CLOSE OUTPUT-FILE.
 65
 66           DIVIDE COUNT-LOOPING BY 2 GIVING LOW-POS
 67               REMAINDER REMAIND.
 68           IF REMAIND = 0
 69               COMPUTE HIGH-POS = LOW-POS + 1
 70           ELSE
 71               COMPUTE HIGH-POS = LOW-POS
 72           END-IF.
 73
 74           OPEN INPUT OUTPUT-FILE.
 75           MOVE "N" TO EOF-FLAG.
 76           PERFORM UNTIL EOF-FLAG = "Y"
 77               READ OUTPUT-FILE
 78                   AT END MOVE "Y" TO EOF-FLAG
 79                   NOT AT END
 80                       IF OUTPUT-AMOUNT IS NUMERIC
 81                           AND OUTPUT-AMOUNT > 0
 82                           ADD 1 TO READ-COUNT
 83                           IF READ-COUNT = LOW-POS
 84                               MOVE OUTPUT-AMOUNT TO LOW-VAL
 85                           END-IF
 86                           IF READ-COUNT = HIGH-POS
 87                               MOVE OUTPUT-AMOUNT TO HIGH-VAL
 88                           END-IF
 89                       END-IF
 90               END-READ
 91           END-PERFORM.
 92           CLOSE OUTPUT-FILE.
 93
 94           COMPUTE MEDIAN-VAL = (LOW-VAL + HIGH-VAL) / 2.
 95           DISPLAY "COUNT=" COUNT-LOOPING
 96                   " LOW-POS=" LOW-POS " HIGH-POS=" HIGH-POS.
 97           DISPLAY "MEDIAN IS " MEDIAN-VAL.
 98           STOP RUN.
 99           

SO CUTE!! and GO AHEAD!!

💻 ターミナル出力 実行結果
COUNT=06 LOW-POS=03 HIGH-POS=04
MEDIAN IS 01650.0

キャッホリング!

naruo2.txt
2025-12-31hoshiimo            02500
2026-01-01gyudon2             00900
2026-01-01curry               01500
2026-01-02gyudon2             00900
2026-01-03hoshiimo            02500
2026-01-04udontenpura         01800

1500 (LOW-POS: 3)と1800 (HIGH-POS: 4) だからして、

(1500+1800)/2 = 1650

OH!マイニング!!

係)うるさいっての!

な)いやー完璧すぎてですね。うっきうきハイキングですよ!今から行きます?

係)なんでお前とハイキングに行くんだよ!

偶数で正しくても、奇数でも確認する

係)どうでもいいが、奇数でも計算してみろ。

な)えー、そんな無駄なことをしなくても、完璧はパンケーキなんですよ。

係)やれって言ってんだよ。

な)あい…

naruo2.txt 奇数版
2025-12-31hoshiimo             02500
2026-01-01gyudon2             00900
2026-01-01curry                   01500
2026-01-02gyudon2             00900
2026-01-03hoshiimo            02500
💻 ターミナル出力 実行結果
COUNT=05 LOW-POS=02 HIGH-POS=02
MEDIAN IS 00900.0

ほらー!パンケーキ………あれ?

係)なにがパンケーキだって?

な)いや、はちみつとメイプルシロップがたっぷりかかった…

係)なんでそうなったと思う?

な)え…と…?

係)今まで考え方は正しかったのにな。

まぁ、にらめっこして、間違いを正せ。いいな。

な)む、むふーん…

(次へ続く)

係長のワンポイント

統合したコードは「一つのケースが通れば完成」じゃない。
本当は、分岐するすべての条件で同じ設計意図が成立するか確認して初めて完成だ。
よくある誤解は、偶数で正しい結果が出れば奇数も同じように動くと思うことだが、位置計算の違いは残っている。
今回も5件を2で割った商の「2」をそのまま使ったため、本来3番目を選ぶべき奇数処理が1つ手前にずれた。
その結果、ロジックの考え方が正しくても、境界条件を試さなければ小さなズレを見逃してしまう。
COBOLは動いたことを確認する言語ではなく、条件を変えて正しさを確かめる言語だ。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする

CAPTCHA


目次