🧩今日の学び
・中央値は、件数から中央の位置を求めるだけではなく、並べたデータの真ん中を取る考え方である。
・ファイルをもう一度読み直す場合は、一度CLOSEしてから再度OPENする必要がある。
・データが偶然並んでいれば正解に見えるが、正しい中央値を求めるにはソートという前提条件が必要になる。
なるお)ふぅ
係長)なんだよ、疲れたのか?
な)そりゃもちろん
疲れることに関しては、誰にも負けませんよ!舐めないでくださいよ!
係)誇るなよ!
このまま次行くぞ。
な)えー!
係)次は中央値だ。
な)えー!
係)なんだよ?中央値ぐらいわかるだろ?
な)えー!
係)なんなんだよ!
な)いや、スルーするから!
係)そのままスルーしてりゃ良かったよ…
なら、考えてみろ。
な)えー!
…完全無視っすか…
ま、いいや。
んじゃさっきの珠玉の食データを使うとして…
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ってなもんで!
どっすか!正解でしょ!超正解でしょ!もう超世界でしょ!
係)…
な)あれ?違う…?
係)……ま、それでやってみろ。
な)あーい!
ん…って、係長?どうやってその数に対応したデータを拾ってくるんすか?
係)お前もちゃんと考えるんだな…驚愕だよ。
な)だから、いつも常に毎秒考えてるって言ってるじゃないすか!
今日おやつ持ってくるの忘れたから、今からちょっと遠い団子屋さんに買い行くか、もっと遠くの煎餅屋さんに行くか、考えなくちゃならないんですから!
係)なんで勤務中にそんな遠いところに買いに行こうとしてんだよ!
な)大事だからですよ?
係)さも当然のことのように言うな!
って…なんの話ししてた…?
な)ちょっとー!しっかりしてくださいよ!おやつの話ですよ!
係)違うわ!
中央値のデータを拾う話だわ!ほんと疲れる…。
な)もっかいルーピングかけて、半分の数字のところでルーピングから離脱して、結果を表示したら正解とか?
係)…(あんぐり)
な)あれ、違いました…?
係)い、いや、一つの正解だ…。
な)あひゅー!!
係)うるさいっての…、喜んでないでコード書いていけ。
な)ふぁーい
この前のこの平均出力コード使おうっと
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のところは、割るから小数点いれとこかー、大事なのは雰囲気、雰囲気!
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」は削除して涙の決断!
ほんとに毎回鬼の首取ったみたいにツッコムんだから…飽きないのかしらね
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-LOOPING2とCOUNT-LOOPINGが同一かどうかを確かめて、OKならループ脱出!
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.
んであとは表示っと
1DISPLAY "MEDIAN IS" AMOUNT2. 2 3CLOSE NARUO-FILE. 4STOP RUN.
そんで合体からのうっとりGO!
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の後に
CLOSE NARUO-FILE. OPEN INPUT NARUO-FILE.
として、もっかい開きましょうということよね。
②
んで、FDは二ついらないというのは完全理解右衛門のパーフェクター
余計な気を回す必要が無い、素晴らしき世界線
ほんといつも横のご老人に気を回しすぎて大変なのよ、もー大変たいへん
係)・・・(イラっ)
な)え、えーと
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に変更
DISPLAY "MEDIAN IS" AMOUNT.
ってことで、今回の全体は…こうっちゅ!
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は計算式を書く言語ではなく、正しい前提条件を作ってから処理する言語だ。


コメント