【COBOL 書き1-12-1】中央値を求めるのは簡単?〜運に左右される人生

🧩今日の学び
・中央値は、件数から中央の位置を求めるだけではなく、並べたデータの真ん中を取る考え方である。
・ファイルをもう一度読み直す場合は、一度CLOSEしてから再度OPENする必要がある。
・データが偶然並んでいれば正解に見えるが、正しい中央値を求めるにはソートという前提条件が必要になる。

なるお)ふぅ

係長)なんだよ、疲れたのか?

な)そりゃもちろん

疲れることに関しては、誰にも負けませんよ!舐めないでくださいよ!

係)誇るなよ!

このまま次行くぞ。

な)えー!

係)次は中央値だ。

な)えー!

係)なんだよ?中央値ぐらいわかるだろ?

な)えー!

係)なんなんだよ!

な)いや、スルーするから!

係)そのままスルーしてりゃ良かったよ…

なら、考えてみろ。

な)えー!

…完全無視っすか…

ま、いいや。

んじゃさっきの珠玉の食データを使うとして…

📝 COBOL 珠玉の食データ
  12025-12-31hoshiimo            02500
  22026-01-01gyudon2             00900
  32026-01-01curry               01500
  42026-01-02gyudon2             00900
  52026-01-03hoshiimo            02500
  6

んー…見りゃわかるじゃん!1500よ!こんなの!

っていうツッコミがあるような真ん中の値ですよね?

係)そこまでの前段が丸々いらないのはなんとかならないのか…。

目次

中央値は「真ん中の値」を探す

係)ま、意味合いはそうだな。で、どうやって求める?

な)求めるのをやめる?

係)求めろよ!

な)人間が進化しすぎたんですよ!

人間なんてものは、もっと寝て食って寝るぐらいの余裕がないといけないんすよ!

係)食うことより早く考えろよ!

な)むー

えーと?真ん中にある値だからー、データの数を数えて、その真ん中が何かが分かれば出るってわけで…

まずデータの数を数えるのは、ルーピングで回った数だけカウントする。

これは前にやってるからいいとして…

その真ん中ってことだから割る2っぽいところからして…

データ総数に+1して、2で割れば良いんじゃね?

データ5つだから、5+1して、2で割れば3、1〜5の数字の中央は3ってなもんで!

どっすか!正解でしょ!超正解でしょ!もう超世界でしょ!

係)…

な)あれ?違う…?

係)……ま、それでやってみろ。

な)あーい!

ん…って、係長?どうやってその数に対応したデータを拾ってくるんすか?

係)お前もちゃんと考えるんだな…驚愕だよ。

な)だから、いつも常に毎秒考えてるって言ってるじゃないすか!

今日おやつ持ってくるの忘れたから、今からちょっと遠い団子屋さんに買い行くか、もっと遠くの煎餅屋さんに行くか、考えなくちゃならないんですから!

係)なんで勤務中にそんな遠いところに買いに行こうとしてんだよ!

な)大事だからですよ?

係)さも当然のことのように言うな!

って…なんの話ししてた…?

な)ちょっとー!しっかりしてくださいよ!おやつの話ですよ!

係)違うわ!

中央値のデータを拾う話だわ!ほんと疲れる…。

な)もっかいルーピングかけて、半分の数字のところでルーピングから離脱して、結果を表示したら正解とか?

係)…(あんぐり)

な)あれ、違いました…?

係)い、いや、一つの正解だ…。

な)あひゅー!!

係)うるさいっての…、喜んでないでコード書いていけ。

な)ふぁーい

この前のこの平均出力コード使おうっと

📝 COBOL average.cob
  1IDENTIFICATION DIVISION.
  2PROGRAM-ID. NARUO.
  3
  4ENVIRONMENT DIVISION.
  5INPUT-OUTPUT SECTION.
  6FILE-CONTROL.
  7    SELECT NARUO-FILE
  8        ASSIGN TO "naruo2.txt" ORGANIZATION IS LINE SEQUENTIAL.
  9
 10DATA DIVISION.
 11FILE SECTION.
 12
 13FD NARUO-FILE.
 1401 NARUO-RECORD.
 15    05 SALE-DATE   PIC X(10).
 16    05 ITEM-NAME   PIC X(20).
 17    05 AMOUNT      PIC 9(5).
 18
 19WORKING-STORAGE SECTION.
 2001 EOF-FLAG PIC X VALUE "N".
 21
 2201 TOTAL-AMOUNT PIC 9(7) VALUE 0.
 23
 24
 2501 COUNT-LOOPING PIC 9(2) VALUE 0.
 26
 27PROCEDURE DIVISION.
 28OPEN INPUT NARUO-FILE.
 29
 30PERFORM UNTIL EOF-FLAG = "Y"
 31    READ NARUO-FILE
 32        AT END
 33            MOVE "Y" TO EOF-FLAG
 34            DISPLAY "SEKAI NO OWARI"
 35        NOT AT END
 36            ADD AMOUNT TO TOTAL-AMOUNT
 37            ADD 1 TO COUNT-LOOPING
 38    END-READ
 39END-PERFORM.
 40
 41DIVIDE COUNT-LOOPING INTO TOTAL-AMOUNT.
 42DISPLAY "AVERAGE AMOUNT: " TOTAL-AMOUNT.
 43
 44CLOSE NARUO-FILE.
 45STOP RUN.

それぞれ2回目のルーピングに関する変数を作っておく感じかな?

もう一回ルーピングするから、FDのところも2個作るのかな? むんむん

あ、フラグのところは、数字用にしておかないとだめ。ってことで

あと、COUNT-LOOPING2のところは、割るから小数点いれとこかー、大事なのは雰囲気、雰囲気!

📝 COBOL madian.cob(検討中)
  1DATA DIVISION.
  2FILE SECTION.
  3
  4FD NARUO-FILE.
  501 NARUO-RECORD.
  6    05 SALE-DATE    PIC X(10).
  7    05 ITEM-NAME    PIC X(20).
  8    05 AMOUNT       PIC 9(5).
  9
 10    05 SALE-DATE2   PIC X(10).  ← 2回目ルーピング用?
 11    05 ITEM-NAME2   PIC X(20).
 12    05 AMOUNT2      PIC 9(5).
 13
 14WORKING-STORAGE SECTION.
 1501 EOF-FLAG  PIC X VALUE "N".
 1601 EOF-FLAG2 PIC 9(1) VALUE 0.   ← 二回目ルーピング判定?
 1701 TOTAL-AMOUNT PIC 9(7) VALUE 0.
 18
 1901 COUNT-LOOPING PIC 9(2) VALUE 0.
 2001 COUNT-LOOPING2 PIC 9(2)V9 VALUE 0.   ← もっかいカウント用?

んで、次に処理部分だわね。

まず一回目のルーピングは、前のままでOKとしておこう、素晴らしい決断に割れんばかりの拍手!割り算だけに!

あ、うるさい人がいるから 「SEKAI NO OWARI」は削除して涙の決断!

ほんとに毎回鬼の首取ったみたいにツッコムんだから…飽きないのかしらね

📝 COBOL madian.cob(検討中)
  1PROCEDURE DIVISION.
  2OPEN INPUT NARUO-FILE.
  3
  4PERFORM UNTIL EOF-FLAG = "Y"
  5    READ NARUO-FILE
  6        AT END
  7            MOVE "Y" TO EOF-FLAG
  8        NOT AT END
  9            ADD 1 TO COUNT-LOOPING
 10    END-READ
 11END-PERFORM.

んで続きの2回目のルーピングはっと、ルーピングの回数に1を足して、2で割るところからスタート

AT ENDは使わないか…CONTINUEじゃ味気ないし「SEKAI NO OWARI」を表示させてっと

COUNT-LOOPINGの値がルーピングを止める回数になるからCOUNT-LOOPING2ルーピングするときにCOUNT-LOOPING2COUNT-LOOPINGが同一かどうかを確かめて、OKならループ脱出!

📝 COBOL madian.cob(検討中)
  1ADD 1 TO COUNT-LOOPING.
  2DIVIDE 2 INTO COUNT-LOOPING.
  3
  4PERFORM UNTIL COUNT-LOOPING = COUNT-LOOPING2
  5    READ NARUO-FILE
  6        AT END
  7            DISPLAY "SEKAI NO OWARI"
  8        NOT AT END
  9            ADD 1 TO COUNT-LOOPING2
 10    END-READ
 11END-PERFORM.

んであとは表示っと

📝 COBOL madian.cob(検討中)
  1DISPLAY "MEDIAN IS" AMOUNT2.
  2
  3CLOSE NARUO-FILE.
  4STOP RUN.

そんで合体からのうっとりGO!

📝 COBOL median.cob(仮)
IDENTIFICATION DIVISION.
PROGRAM-ID. NARUO.

ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT NARUO-FILE
        ASSIGN TO "naruo2.txt" ORGANIZATION IS LINE SEQUENTIAL.

DATA DIVISION.
FILE SECTION.

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

    05 SALE-DATE2   PIC X(10).
    05 ITEM-NAME2   PIC X(20).
    05 AMOUNT2      PIC 9(5).

WORKING-STORAGE SECTION.
01 EOF-FLAG  PIC X VALUE "N".
01 EOF-FLAG2 PIC 9(1) VALUE 0.
01 TOTAL-AMOUNT PIC 9(7) VALUE 0.

01 COUNT-LOOPING PIC 9(2) VALUE 0.
01 COUNT-LOOPING2 PIC 9(2)V9 VALUE 0.


PROCEDURE DIVISION.
OPEN INPUT NARUO-FILE.

PERFORM UNTIL EOF-FLAG = "Y"
    READ NARUO-FILE
        AT END
            MOVE "Y" TO EOF-FLAG
        NOT AT END
            ADD 1 TO COUNT-LOOPING
    END-READ
END-PERFORM.

ADD 1 TO COUNT-LOOPING.
DIVIDE 2 INTO COUNT-LOOPING.

PERFORM UNTIL COUNT-LOOPING = COUNT-LOOPING2
    READ NARUO-FILE
        AT END
            DISPLAY "SEKAI NO OWARI"
        NOT AT END
            ADD 1 TO COUNT-LOOPING2
    END-READ
END-PERFORM.

DISPLAY "MEDIAN IS" AMOUNT2.

CLOSE NARUO-FILE.
STOP RUN.
⚠️ エラー出力 エラー出力
libcob: error: READ after unsuccessful READ/START (status = 46) for file NARUO-FILE ('naruo2_txt' => naruo2.txt)
libcob: warning: implicit CLOSE of NARUO-FILE ('naruo2.txt')

むぎゃ!なんじゃこりゃ!オレのせいじゃねー!

係)どう考えてもお前のせいだろ!

な)えーだって、脳内で考えてることをすべて再現してくれないこぼるんが悪いんですよ…

係)スーパーコンピューターを超えるっての!

な)ついにAIに支配されるんすか!?

係)わくわくすんな!

とにかく一気に行くぞ。

① まずファイルをCLOSE処理してるだろ?もう一回データを読み込ませるなら再度OPENしてからだ。

FDを二つにするというのは間違いだ。データの項目数は3。増やしたということはデータの項目数が6つにしただけであって、そこにはデータがないから、なにも入らないぞ。

じゃ、直せ。

な)がふっ!

全部簡単に言うんだから…まずは称賛しましょうよー

素晴らしいコードだ。やはりなるおだな。最高だ。

係)言葉が幼稚で、大した称賛になってないからな。

な)せめて称賛に努めて!

係)はいはい、がんばれ。

な)心がなさすぎ星人!

あの織姫と彦星を離婚にまで追い込んだ悪名高い不倫厨の無心星人がここに!

係)早くやれ!

な)むー

ファイルをCLOSEしたから、もっかい読み込むときは再度OPENが必要なのね、そうなのね

でも、めんどくさいわねこれ、何回も使わせてくれたほうが早いうまいそこまで安くないじゃないのかしら

ということで、一回目のEND-PERFORMの後に

📝 COBOL median.cob 検討
CLOSE NARUO-FILE.
OPEN INPUT NARUO-FILE.

として、もっかい開きましょうということよね。

んで、FDは二ついらないというのは完全理解右衛門のパーフェクター

余計な気を回す必要が無い、素晴らしき世界線

ほんといつも横のご老人に気を回しすぎて大変なのよ、もー大変たいへん

係)・・・(イラっ)

な)え、えーと

📝 COBOL median.cob 検討
DATA DIVISION.
FILE SECTION.

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

FDはデータの項目分だけでOKだということね。

そうなるとAMOUNT2が消滅するので、最後の表示部分をAMOUNTに変更

📝 COBOL median.cob 検討
DISPLAY "MEDIAN IS" AMOUNT.

ってことで、今回の全体は…こうっちゅ!

📝 COBOL median.cob
  1IDENTIFICATION DIVISION.
  2PROGRAM-ID. NARUO.
  3
  4ENVIRONMENT DIVISION.
  5INPUT-OUTPUT SECTION.
  6FILE-CONTROL.
  7    SELECT NARUO-FILE
  8        ASSIGN TO "naruo2.txt" ORGANIZATION IS LINE SEQUENTIAL.
  9
 10
 11DATA DIVISION.
 12FILE SECTION.
 13
 14FD NARUO-FILE.
 1501 NARUO-RECORD.
 16    05 SALE-DATE    PIC X(10).
 17    05 ITEM-NAME    PIC X(20).
 18    05 AMOUNT       PIC 9(5).
 19
 20WORKING-STORAGE SECTION.
 2101 EOF-FLAG  PIC X VALUE "N".
 2201 EOF-FLAG2 PIC 9(1) VALUE 0.
 2301 TOTAL-AMOUNT PIC 9(7) VALUE 0.
 24
 2501 COUNT-LOOPING PIC 9(2) VALUE 0.
 2601 COUNT-LOOPING2 PIC 9(2)V9 VALUE 0.
 27
 28
 29PROCEDURE DIVISION.
 30OPEN INPUT NARUO-FILE.
 31
 32PERFORM UNTIL EOF-FLAG = "Y"
 33    READ NARUO-FILE
 34        AT END
 35            MOVE "Y" TO EOF-FLAG
 36        NOT AT END
 37            ADD 1 TO COUNT-LOOPING
 38    END-READ
 39END-PERFORM.
 40
 41CLOSE NARUO-FILE.
 42OPEN INPUT NARUO-FILE.
 43
 44ADD 1 TO COUNT-LOOPING.
 45DIVIDE 2 INTO COUNT-LOOPING.
 46
 47PERFORM UNTIL COUNT-LOOPING = COUNT-LOOPING2
 48    READ NARUO-FILE
 49        AT END
 50            DISPLAY "SEKAI NO OWARI"
 51        NOT AT END
 52            ADD 1 TO COUNT-LOOPING2
 53    END-READ
 54END-PERFORM.
 55
 56DISPLAY "MEDIAN IS" AMOUNT.
 57
 58CLOSE NARUO-FILE.
 59STOP RUN.

んで、うっとりGO!

💻 ターミナル出力 実行結果
MEDIAN IS01500

おー!キャシー!

係)誰だよ・・・

な)いやーイケてる男には美女が集まるのってコブラを読めばわかりますし!

係)どこに集まってるんだよ…

まず、この結果は見づらいだろ。

💻 ターミナル出力 実行結果
MEDIAN IS01500

な)なんてこと!

係)もう少し変数名をわかりやすくしろよ。

な)哀しみ!

でも、結果正解出たんだから、100点すよね!

係)そうだな。

な)おお!

係)1000点満点中のだな。

な)なんてこと!

係)3つ目が中央値というのはまぁわかる。だが、それが全データの3つ目にくるかどうかがわかるか?

な)ふみ?

係)データ数に1を足して、2で割るところが中央値はとりあえず良しとして、データをSORTしないと並んでないだろ?

な)ふみみ?

係)今回はたまたま真ん中にあったってだけだ。ただの運だ。

な)なんてグッドラック!!

これは日曜の競馬が楽しみですね!

係)お前はギャンブルやりすぎだっての!

そんな運に任せるんじゃなくて、ちゃんとSORTしてデータ揃えてから、中央値を出せって話だよ!

な)なんてバッドラック!?

(次回へ続く)

係長のワンポイント

中央値は「真ん中の番号」を探す計算ではない。
本当は“並べたデータの真ん中”を探すための考え方だ。
よくある誤解は件数を数えて中央の位置を取れば終わりだと思うことだが、それでは順番が保証されない。
だからデータが偶然並んでいれば正解になるし、並んでいなければ間違った中央値になる。
その結果、計算式より先に「どんな状態のデータを扱うか」が重要になる。
COBOLは計算式を書く言語ではなく、正しい前提条件を作ってから処理する言語だ。

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

この記事を書いた人

コメント

コメントする

CAPTCHA


目次