🧩今日の学び
・偶数件の中央値は、SORT済みデータの中央に並ぶ2つの位置を求め、その値を平均して算出する。
・COMPUTEでは右辺の式を計算し、その結果を左辺の項目へ代入できる。
・ファイルを読み直す前にフラグとカウンターを初期化し、中央の2件を別々の項目へ保存することが重要である。
係長)よし、じゃ、件数が偶数の時のPROCEDURE DIVISIONをコード化してみろ。
なるお)誰が?
係)お前だよ!
な)なんてこと!
係)まずは流れでいいから考えた結果を伝えろ。いいな。
な)なんてこと!!
って、すぐ自分の仕事しないで!もっと毛布のように暖かく見守って!
………くっ!あれ絶対耳も悪くなってるんだから、もう耳元でハウリングしてもノーリアクションでしょ。
係)(ジロリ)
な)あぅあぅ、え、えーと…
まずはソートして中央値の準備をする
な)とりあえず…ソーティングして、書き出して…んで、件数数えると。それが偶数だって話よね。ここはさっきの話で件数を2で割ったやつとそれに+1したやつが順番になって…順番確定っと。
んで、ソーティングしたファイルを読み込んで、さっきの順番の値をゲット。
んで、抽出した2つの数字を足して2で割って、平均でるからそれが中央値みたいなってやつでしょ。
もういい加減わかってるっつーの。
でもなんか読み込んだりするの多くて大変じゃねこれ…
と、とりあえず、まずはファイルを読み込んで、ソーティングから始まる恋もあるってことで、こうっちゅ!
SORT SORT-FILE
ON ASCENDING KEY SORT-AMOUNT
USING INPUT-FILE
GIVING OUTPUT-FILE.
件数を数えて中央の位置を求める
な)んで、件数数えるからPERFORMでルーピングで、こうっちゅ?
OPEN INPUT OUTPUT-FILE.
PERFORM UNTIL EOF-FLAG = "Y"
READ OUTPUT-FILE
AT END
MOVE "Y" TO EOF-FLAG
NOT AT END
ADD 1 TO COUNT-LOOPING
END-READ
END-PERFORM.
CLOSE OUTPUT-FILE.
ただ、前のやつ持ってきただけだけど、老害にはわかるめぇ…くくく
って、ここまでは、前のがあるからやっつけでいけるんだけど、次なんだよなぁ…
COMPUTEで中央値の位置を計算する
今回は偶数ってことなので、まずはカウントそのままを2で割ると。変数名は今はどうでもいいとして、とりあえず適当につけとこう
COMPUTE SAKI = COUNT-LOOPING / 2.
COMPUTE ATO = SAKI + 1.
ってことじゃね?
コンピート(COMPUTE)は計算してから入れるって話してたから…
あの、係長?
係)なんだできたのか?
な)いえ、全然?
係)できてから喋れよ!
な)それじゃいつまでも喋れないっすよ!
係)…なんだよ…ったく
COMPUTEは「計算して代入する」命令
な)こんなうっとりコードにしたんすけど、コンピートってなんで=で結んでるんですかね?
COMPUTE SAKI = COUNT-LOOPING / 2.
COMPUTE ATO = SAKI + 1.
係)そういうもんだからだ。
な)ぎゃふん!
じゃなくて!ちゃんと説明してくださいよ!最近怠慢ですよ!職務怠慢ですよ!ボーナス削減すよ!
奥さんにボーナスが減らされた理由をLINEしておきますからね!
係)なんでだよ!
お前は単純なくせに単純にそう思っておく、ができないやつだな、ほんと…。
COMPUTEは計算した結果を代入するってのは覚えてたんだろ?
な)ふみ
係)MOVEは英語として読む。
MOVE A TO B ↓ AをBへ入れる
という意味だな。
係)でもCOMPUTEは違う。
COMPUTE A = B + C ↓ B+Cを計算して、その結果をAへ入れる
だからA=B+Cといった数式みたいな形で書くわけだ。その方が人間も見やすいだろ?
な)ふむむ、人によりますね。
係)「そうですね」でいいだろが!
=の右側を全部計算して、左に入れるって考えれば簡単だろ!
な)おー納得感!
んじゃ、次っと!
係)…そもそも、コンピートってなんなんだよ!
もう一度読み込んで中央の2つを取り出す
な)次は、ソーティングのファイルを読み込んで、さっきのSAKIとATOに対応する番目の項目を取り出すんだから…、あ、もう一回ルーピングか。
とりあえず、ファイル読みましょうからはじまって、EOF-FLAGを初期化(N)と。
OPEN INPUT OUTPUT-FILE.
MOVE "N" TO EOF-FLAG.
んでルーピング部はと…一回目のルーピングと同じようなもんだけど、2回数字引っ張ってこないといけないから…抜けるためのAT END、そしてNOT AT ENDの中身は2つになるね。
SAKIのときに数字をSAKIKAZUに入れて、ATOのときの数字をATOKAZUに入れるって感じから・・・こうっちゅ!
PERFORM UNTIL EOF-FLAG = "Y"
READ OUTPUT-FILE
AT END
MOVE "Y" TO EOF-FLAG
NOT AT END
ADD 1 TO READ-COUNT
IF READ-COUNT = SAKI
MOVE OUTPUT-AMOUNT TO SAKIKAZU
END-IF
IF READ-COUNT = ATO
MOVE OUTPUT-AMOUNT TO ATOKAZU
END-IF
END-READ
END-PERFORM.
CLOSE OUTPUT-FILE.
2つの値を平均して中央値を完成させる
んで最後は計算して表示ってわけだから、こうっちゅ!
COMPUTE MEDIAN = (SAKIKAZU + ATOKAZU) / 2.
DISPLAY "MEDIAN IS " MEDIAN.
STOP RUN.
か、完璧すぎる…
才能が開花しすぎて怖すぎる…
係)って、今までやってきたことだろが…
な)いやん
係)どら?ようやく書けるようになってきたか?
な)なんというか、オールうっとり党ですよね。ほんとこれ。
係)なにがオールなんだよ…
な)でも係長もうっとりでそ?だったらオールでそ?
係)だから、ATOとかSAKIとか意味わからんから、変数名はきちんと決めて作れっての!
な)もうそんな細かいところじゃなくって、宇宙規模で俯瞰して!
係)そんなとこから見たら、なにも見えないだろ!
な)屁理屈!?
おむすび
係)いいから、次は、整理して、全体を形にして、実行しろ!
な)もうそんなの若妻を追い詰め続ける姑ですよ!
フスマのサンに指をすーっとやって、ササクレで指切る人ですって!
血だらけになっても「さちこさん、全然お掃除ができなてないザマスわよ」ですよ!
係)どんなやつだよ!
いいからやれっての!
な)OH 無頼漢!!
(次へ続く)
係長のワンポイント
偶数件の中央値は「真ん中の値を1つ探す処理」ではない。
並べたデータから、中央に並ぶ2つの位置を求める処理だ。
よくある誤解は、件数を2で割れば終わりだと思うことだが、必要なのはその位置と次の位置になる。
だからCOMPUTEで位置を求め、再び読み込んで該当する2件を別々に保存する。
その結果、2つの値を平均することで、偶数件の中央値が初めて完成する。COBOLは答えを直接探す言語ではなく、必要な位置と手順を分けて組み立てる言語だ。


コメント