係長)・・・
なるお)いやー、ひと仕事終わったあとのクーニャンは格別でしょうね!
係長)そうじゃなくて、全く気づいてないのか?
な)鳥貴族にクーニャンがないこと?
係)違うわ!
な)なんですの…
係)この結果見てなんとも思わなかったのかってことだよ。
な)曇りなき結果じゃないっすか…
係)どう考えても曇ってるだろ!
いいか、これもたまたま結果が正解だったってだけだ。
つまり、どこかに欠陥があるんだよ!
な)でも、うっとり的な…
係)いいから、実行結果を確認してみろ!
中央値は正しいのに件数が合わない
COUNT=07 LOW-POS=03 HIGH-POS=04 LOW-VAL=00900 HIGH-VAL=01500 MEDIAN IS 01200.0
な)このうっとり結果の何が問題なんすか…
むー ………
あれ、COUNT=07? データは6つだったよね?
2025-12-31hoshiimo 02500 2026-01-01gyudon2 00900 2026-01-01curry 01500 2026-01-02gyudon2 00900 2026-01-03hoshiimo 02500 2026-01-04udontenpura 01800
やっぱデータは6個だわ
だったら、COUNT=06だよね…え、どういうこと?
係)ようやく気づいたかよ…
な)なんでこうなるの?
係)これはわかっていないとハマる沼だ。
な)え?じゃ、オレの責任じゃない?
係)お前の責任ではないと言いたいところではあるが、それを前提として作っておくべきことだ。だから、お前の責任だな。
な)あまりにもひどい!
cat -eで最終行の改行を確認する
係)いいから、ターミナルでcat -e 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%
全然猫じゃない!?
係)猫が出てくる余地がどこにあるんだよ…
改行の有無でカウントが変わる
いいか、ここの最後のudon tenpuraの行の最後だけ違うのわかるか?
な)あー%になってますね
いきなり割って100掛けたくなった気分なんすかね。
係)誰がどんな気分になるんだよ!
いいか、ターミナル上において、$ は改行(行の終わり)が入っているという表示で、% は行が終わってない(改行なし)って表示になる。
な)ふむふむ…、でも、だったら、最後が%は改行してないんだから、6になって、$は改行したんだから、7になるんじゃないんすか?
係)まぁ、そう思うだろうな。
いいか、改行は改行しただけであって、行の先頭にデータなければ、その行はデータなしで処理される。
反対に、改行なしの場合、改行無しじゃずっとデータを探してしまうことを避けるために、COBOLが改行を入れてくれるんだ。その行にデータが入っている形でな。
つまり、改行あり($)の場合、次の行がないため、カウントは6行目で止まって、COUNT=6となる。
改行なし(%)の場合、次の行が勝手に現れたため、カウントは一つ増えてCOUNT=7になったというわけだ。
な)むむん、って、こぼるんの余計なお世話の強要じゃないっすか。これ!
係)だからこそファイルについては、明確な規則が必要だって話だ。データの作成形式、保存形式、読込形式などだ。
誰が使うかわからないんだ。その対策はしておく必要があるぞ。
な)めんどくさ!てか、つくもめんどくさ!
係)はぁ?
な)え、七面倒くさいの強化版ですけど?九十九面倒くさいって
係)そうなのか?
な)知らんすけど?
係)知らねーのかよ!
な)でも、そんなのどうやって解決するんすか…
だって、見た目で言えば、改行入ってないんだから、もう示談金払ってる状態なのに、まだむしり取ろうとされてもって話ですよ!蟹工船イヤっすよ!でも蟹食べ放題なんすかね?
係)知らねーよ!
いいか、これはGnuCOBOL側の挙動ともいえるから、他の環境ではこうなるとは限らないな。
な)ぐぬ〜
係)いちいち反応すんな!
な)んじゃ諦めの境地じゃないっすか。やっぱりあの観葉植物の葉が全部落ちたらあたしも一緒に…ね状態じゃないっすか!
係)観葉植物は葉が落ちねーだろ!
だからそれが前提でどうするかを考えないといかんってことだよ!
な)あ、そゆこと
ファイルの揺れを前提にコードで守る
係)ったく。
本来であれば、パッチ処理を行いファイル自体を修正して、読み込みでエラーが生じないように整形することも考えるな。
ただ、そうなるようにコードに仕込んでおけば、リスク回避できるだろ?
な)ほほー
係)…
な)………で??
係)考えろよ。
な)ぎゃふん!
また、仕事放棄っすか!?
係)うるさい!今のコードで考えればわかるだろ!
な)ぎゃぴーん……
これが子離れ言うやつなんですね…
係)違うわ!
お前が親離れしろよ!
な)ぐぬ〜
空のレコードを数えない条件を入れる
な)…大体ここだってのはわかってんのよ。NOT AT ENDのとこでしょ、どうせ
てか、カウントしてるのここだしね
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.
ただ1を足し込んでるだけで、なぜか7行目にいったから、1足されてしまったんだから、ここに勝手に足さないような条件入れるのはどうだろうかしら
この際、7行目に行くのはドンマイ、丼舞として、7行目を参照したときに、データがなかったら、カウントしないでNOT AT ENDを抜けちゃうとしたらどうなのこれ?
NOT AT END
IF OUTPUT-SALE-DATE NOT = SPACES
ADD 1 TO COUNT-LOOPING
END-IF
つまり、7行目に行っちゃうけど、最初の項目の「OUTPUT-SALE-DATE」が空(スペース)だったら、IF無しよと
そんで、空じゃなかったらカウント続ければいいじゃないのってね!
Hey うっとり!!
COUNT=07 LOW-POS=03 HIGH-POS=04 LOW-VAL=00900 HIGH-VAL=01500 MEDIAN IS 01200.0
ぎゃひー!
係長…デパートの屋上から身を乗り出して、警察に止められてきます…
係)まてまて!
死ぬなら迷惑かけずにやれ!
な)そんな慰め方あります!?
係)いい感じに沼にハマってくれるから嬉しいんだよ!
な)はぁ!?
係)改行だよ。
な)改行?
係)改行はいろいろ悪さしてくれるからな。可能性は4つほど考えられるが…
な)いやいやいやいや、4つって!4つですよ!フォーですよ!ベトナムですよ!
係)いらんこと挟むな!
複数の要因が考えられるとしても、今回は余計なレコードがあると返ってきたわけだな。
だったら、その挙動を前提に、有効なデータだけ数える処理にすればいい。
な)安易ですね
係)うるせーよ!
ヒントやったんだから考えろ!
な)あれをヒントと思っているなんて、なんて思い上がり!?人間は思い上がりすぎなんすよ!
森林伐採!環境汚染!宇宙のゴミ放置!火星をテラフォーミング!
係)(無視)
な)なんか言って!!
ぐぬ〜 … 挙動を前提ってなんだっつーのかしら
まんず、7行目ができちゃった婚ってことなのよね?
それは仕方ねーと、認知しろってことかしら?
係長も数え切れないほど認知してきたという自慢の現れかな?
係)巻き込むな!
な)でも、7行目っていうか「作られた最終行」にはデータはないってことなのよね?
だったら、> 0しちゃえばいいんじゃないの、これ!
OPEN INPUT OUTPUT-FILE.
PERFORM UNTIL EOF-FLAG = "Y"
READ OUTPUT-FILE
AT END
MOVE "Y" TO EOF-FLAG
NOT AT END
IF OUTPUT-AMOUNT > 0
ADD 1 TO COUNT-LOOPING
END-IF
END-READ
END-PERFORM.
CLOSE OUTPUT-FILE.
COUNT=06 LOW-POS=03 HIGH-POS=04 LOW-VAL=00900 HIGH-VAL=01500 MEDIAN IS 01200.0
エイドゥリアゥーン!
係)誰だよ!
な)みてみて!ついに係長を超えましたよ!
数値判定と値判定を組み合わせる
係)ふん。
・・・
OUTPUT-AMOUNT > 0にした理由はなんだ?
な)えと…> 0だから数字じゃないとだめなんじゃないかと思って
係)考え方はいいが、それが数字かどうかの判別はしたのか?
な)へ?
数字も何も、価格のところだから数字でしょ?
係)「作られた最終行」だって自分で言ったんだろ?
だったら、そこに数字が入っている保証はあるのか?
な)へ…?
係)> 0の考え方は良いだろう。
しかし、そこに数字である保証も合わせて行わないとエラーになる可能性があるぞ。
数字判別するにはどうするんだった?もう何度もやってるだろ?
な)IS NUMERIC…?
係)つまり、IS NUMERICでの数字判定と>0の判定を同時にしろってことだ。
な)むむん
同時ってことはこう?
OPEN INPUT OUTPUT-FILE.
PERFORM UNTIL EOF-FLAG = "Y"
READ OUTPUT-FILE
AT END
MOVE "Y" TO EOF-FLAG
NOT AT END
IF OUTPUT-AMOUNT IS NUMERIC
AND OUTPUT-AMOUNT > 0
ADD 1 TO COUNT-LOOPING
END-IF
END-READ
END-PERFORM.
CLOSE OUTPUT-FILE.
係)それでいい。
おむすび
な)あふぅ…疲れた…
係)……で、まだ気づいてないのか?
な)へ?
係)終わってないだろ?
な)いや終わってますって!END OF FINですって!
係)ENDかFINかはっきりしろ!
な)また理不尽な…
係)それ終わらないと今日は終わらないからな!
な)へ!?
なるおは「終わる」を詠唱した
係)うるせーよ!とっとと気づけ!
な)傍若無人!?若くもないのに!?
係)そういう意味じゃないだろ!
(まだまだ続く)
係長のワンポイント
ファイル処理は「読み込めたら全部数える」ものじゃない。
本当は、読み込んだレコードが有効なデータかを確認してから使う処理だ。
よくある誤解は、NOT AT END なら正しいデータが入っていると思うことだが、空や不正なレコードが返る場合もある。
だからIS NUMERIC で数値かを確認し、さらに> 0で集計対象かを判定する。
その結果、改行や実行環境の違いで余計なレコードが現れても、件数へ混ぜずに済む。
COBOLはデータを信用して処理する言語ではなく、条件で確かめながら守る言語だ。


コメント