{{category lifehack}} 久々に学生さんの仕事に直接触れて、感じたことを整理しておきます。 !プログラミング言語について *どの言語で書くのも自由だが、ある言語を選んだら、その言語らしい書き方を習得すべし。例えば、C++で書いているけど中身はほとんどFortranだとか、fortran90のプログラムなのに書き方はほぼFortran77だとか。 *毎年新しい言語が生まれてくるのはなぜか。新しい言語のほうが速く走るわけではない。新しい言語は、必ず人間の負担を減らすために生まれてくる。C++やPythonでできることはがんばれば必ずFortranでもできるが、開発時間と、できあがったプログラムの読み易さは比較にならない。その言語が生まれた背景を知り、その言語の特徴を生かしたプログラムを書かなければ、その言語を選ぶ意味がない。 !入出力について *入出力ファイルのフォーマットが変わるたびに、プログラムをコピーすると、同じ機能を持つ複数のプログラムをメンテナンスしなければならなくなる。もしプログラムの基幹部分にバグがあった場合、いくつものプログラムを間違いないく修正する必要があり全く無駄な手間である。 *それを回避するためには **ひとつのプログラムが、複数の入力ファイル形式を受けいれられるようにする。 **ファイル形式をあらかじめ変換する小さいプログラムを別に作っておく。 *ファイル出力する時には、人間が読みやすいように出力するのではなく、プログラムが読みやすいように出力する。固定幅出力は人間には読みやすいが、機械は可変幅のほうが読みやすい。行数がわからないデータは機械には扱いにくいので、最初に行数を出力する。 *数字を出力する時には、その数値の意味がわかるようにコメントも一緒に出力するか、出力フォーマットを文書化しておく。未来の自分が、今の自分と同じ記憶をもっていると過信してはいけない。 *バイナリ形式は使うべきではない。汎用コンピュータの時代には、出力速度を高め、ファイルサイズを小さくするためにバイナリ形式が推奨されたが、それはUnixの文化ではない。機械と人間の両方が読みやすいように、必ずテキストファイルにすること。数値を出力する時は、桁数をけちらないこと。倍精度なら17桁以上必要。ファイルを保管する場所の問題がある場合には、圧縮するという手もある。 *無闇にフォルダを分けない。makeが最も性能を発揮できるように、多段階の処理フローは同じフォルダの中で行う。 !開発フローについて *単一プログラムで何でもできるようにするのは生産的でない。機能ごとに分割した小さなプログラムを書くのが良い。 *多段階の処理を一つのプログラムで行うべきではない。これも機能ごとに分割する。 *Fortranで書く場合、6番以外の出力は使うべきではない。出力ファイル名が固定化されるため、同じフォルダで複数のプログラムを走らせた時にファイル名の衝突が起こる。どうしても6番以外を使わなければいけない場合は、open文でファイル名を指定すること。 *上の項と関連するが、一つのプログラムで、多数のファイルを処理しようとしないこと(あなたがスケジューリングの天才でなければ)。プログラムは小さくし、多数のファイルをくりかえし処理する作業はシェルスクリプトにまかせる。スクリプト言語(特にシェルスクリプト)をマスターする。なんでもかんでも高級言語で書かない。 *逆に、なんでもかんでもシェルスクリプトでやろうとするのも無用な苦労を生む。処理の速さと、複雑さの折りあいをつけるには、スクリプト言語(awk, perl, python, rubyなど)を覚えるとよい。 *makeを学ぶべし。多段階・並列の処理フローはmakeにまかせる。たいていの人の処理フローでは、10000件の同時処理を100個のCPUにやらせようとすると破綻する。データ処理も、コンパイルも、makeにまかせる。 *中間ファイルを消さない。データはCPU時間の対価として得られる。消したデータを再生するには同じだけのCPU時間が必要になる。現代のストレージは安い。データを消して得られるディスク容量と、データそのものの価値を天秤にかけると、必ず後者のほうが高い。 *rmコマンドをタイプする癖をつけてはいけない。 rm *.data と書くつもりで、 rm * data と書いてしまったら?シェルのヒストリー機能でコマンドを選ぶ時に、1行間違えて、 rm * と書いてある行を選んでしまったら?こういうことは、疲れてくるとかならず起こる。ファイルを消さざるをえない場合は、消すファイルを別ディレクトリに移動し、一晩寝てから、消してもいいか自問自答するぐらいの慎重さが必要。Unixにも「ごみ箱」があればいいのに。