2014年9月22日月曜日

gnuplotの出力データが大きすぎる時の対処法




非常に大きなデータを扱う場合、postscriptはファイルサイズが大きくなりすぎて開くことが出来なくなってしまうことがあります。大きくなりすぎたpostscriptはデスクトップで開くことも、プリンタに出力することも、どうすることも出来なくなってしまいます。

 非常にデータ数の多いプロットは開くのにも一苦労。

こういうことがないように、gnuplotの出力はpostscriptだけでなくpng形式でも出すことをお勧めします

postscriptのデータサイズが大きくなってしまうのは、postscriptが情報をベクターデータとして保存するからです。もしgnuplotに入力したデータが1000000点あれば、1000000点とそれを構成する情報を保存しなければならない訳です。この形式の良い所は、後からこのpostscriptを解析して元データを復元しやすいところです。しかしながら、データサイズが入力データの大きさに従って大きくなっていってしまうことが問題点としてあります。

それに対してpng形式はデータを単なる画像として保存します。 ただ600*600の点に色を塗っていくだけです。この形式の利点は、元のデータがどんな大きさだろうともpngファイルの大きさは殆ど変わらないことにあります。ただし、タダの画像になるので、情報は不可逆変換されます。即ちpngファイルから元のデータを取り出すことは非常に難しいです


ので、可能な限りpostscriptで出力をして、もしデータサイズが大きくなってしまったらpngファイルに切り替えるという方法が有用でしょう。pngの復元は出来ないといっても、要は元のデータファイルを残しておけばいいのですから、それほど困ることではないです。


2014年9月21日日曜日

テキスト処理の為に学ぶべき4つの技術

テキスト処理を学ぶべき理由 

コードに限らず、テキストは常に扱う対象になります。
コードを書くことには熱心でもテキスト処理を学ぶことに熱心ではない方は結構います。
しかし、テキストはコードと同様に学ぶべき対象なのです。その理由を2点説明します。

 1. ルーチンワークからプログラミングへ

ログやデータの解析はルーチンワークではありません。

テキストとしてのデータは人間が読める対象である場合が殆どでしょう。
人間が読めるデータですから、一行ずつ直接データを読み、必要な作業を手で行うことはできます。
しかしこれはひどく退屈なルーチンワークにしかなりません。
テキストをプログラミングの対象として扱う方法や技術を学ぶことでルーチンワークを排して楽しいプログラミングをすることが出来ます

2. プログラマの生産性を向上させる

テキスト処理は手作業でやろうとすると思う以上に時間がかかるものです。
プロジェクト全体のコメントのフォーマットを変更する、などは手作業でやることも出来ますが、手作業だと変更し忘れるファイルがあったりすることは良くあります
チェックの時間も含めると手作業による効率はあまりよくないことが分かると思います。




以下で紹介する技術は全て一朝一夕で出来るものではありません。むしろ一生かけて学ぶものの一つを紹介することを目的に記事を書きました。
しかし前述のようにこれらの技術は一生使うに能う理由があります。
是非触って見てください。



1. テキストエディタ



当然ですがテキストエディタを扱うということは最も重要なことになるでしょう。

しかし、テキストエディタは熟練度による生産性の差が明瞭に表れるものの一つでしょう。
ViやEmacsなどのエディタは単純に文字を一つずつ打つという機能だけではありません。
文字列置換や様々なユーティリティがあり、また様々なショートカットキーがあります。
これらの機能は直感的ではない所が結構あったりします。それはこれらのキーが熟練者に最適であるようにデザインされているからであり、入門しやすいようになっている訳ではないからです。
この点が多くのIDEや商業ソフトウェアのUIとの違いでしょう。

入門が簡単なエディタと、熟練者にとって最適なエディタ。
一生プログラミングを続けるなら、どちらを選ぶべきかは自明でしょう。


2. awk

テキスト処理と言えばawkです。
awkはテキスト処理だけの為に開発されたという男らしいプログラミング言語です。manページも3ページしかありません。しかしテキスト処理という点に関しては不足のない言語です。

awkの基本的なアルゴリズムはパターンマッチングです。
入力テキストを行毎に読み込み、その行がパターンに合致していたら処理を行う。
これを最終行に行くまで繰り返す。

非常に簡潔で明解な言語です。文法も簡潔なので殆どの処理は一行(one liner)で済ませることが出来ます。

awk '/error/{print $1, $2}'

とすればerrorの文字列を含む行の1番目、2番目の語を出力するという処理になります。

awkは特にデータの解析に有用です。
gnuplotなどにデータを流し込む前の前処理を行ったり、統計値を取ったり、 データからデータを取り出すような処理に対して威力を発揮します。


参照リンク

The GNU Awk User's Guide
フルドキュメント。非常に詳解なので困ったらこれを見ればいいでしょう。

AWK入門(ドットインストール)
awkの入門の為ならこちらをお勧めします。awkのしっかりとした言語であるという側面と、簡単に記述できるという側面の両方を見ることが出来ます。



3. grep

grepは文字列検索の為のコマンドです。
作業のチェックやログの解析などに用いられます。

例えばプログラム中に埋め込んだTODO:をすべて読み込むには

grep -n TODO: main.cpp

とすれば

118:        // TODO: Array of dynamic sized objects.
124:        // TODO: temporal buffer to store nodes from income buffer.
147:            // TODO: Get nodes from income buffer and put it into open list.
170:            // TODO: minf(int f):
221:            // TODO: incumbent solution.
223:                // TODO: For some reason, sometimes pops broken node.
245:                //                TODO: need it to be atomic.
277:                // TODO: Push items to thread safe income buffer.
289:                // TODO: trylock
372:        // TODO: Time to printing these texts are included in the walltime.
377:        // TODO: pack to a method

のように出力され、進捗状況が概観するのに使えます。
awkと比較すると、grepは出力を編集するためのものではなく、インタラクティブに、テキストがどうなっているのかを把握するために使いやすいように思います。

grepによるパターンの検索(Oracle)


4. Ruby or Python

やや大規模なテキスト処理を行う場合、シェルスクリプトやawkでは表現力が足りなかったり、あるいは読みやすいコードにならない場合があります。しかしテキストデータに対してC++やJavaで書くのはオーバーキルな場合が多いです。

RubyやPythonのような言語を理解しているとこういうちょっとしたプログラムを実装するのにも役に立ちます。





先に述べましたように、これらの技術は小手先技ではなく、一朝一夕に得られるものではありません。しかしスケールアップしていくものです。
一生使える技術を学びましょう。




2014年9月12日金曜日

参加出来るオープンソースプロジェクトを探す3つの方法

オープンソースプロジェクトに参加することはプログラマの楽しみであり、社会貢献であり、確かな実績にもなります。

メジャーなオープンソースプロジェクト・団体の名前を上げるならば、GNU, Linux, Mozilla, Ruby, Python, Boost....毎日使っているオープンソースだけでもいくらでもあるでしょう。ただし、概してこれらのプロジェクトに貢献することは非常に大きな傾注を要します。例えばEmacsやLinuxカーネルへの参加は最も優れたプログラマしか許されず、怪しいコードを書くと袋叩きにあうなどという話があります。袋叩きは冗談としても、そのようなインパクトの非常に大きいコードを書くということは簡単に出来ることではありません。

オープンソースへの貢献が非常にハードルの高いものだと思っている方は先のLinuxカーネルの例を良く出します。しかしオープンソースというのは五万とあり、貢献の機会や方法はいくらでもあります。

しかし、五万とあるプロジェクトからどれにコミットすべきなのか、どのようなプロジェクトがあるのか分からないというのが本音でしょう。以下、そんな行き場のない熱意を持ったプログラマの為の指針を紹介します。



1. 既に使っているオープンソースに貢献する

これが出来れば万々歳ですね。使っているうちに、不便な所や、バグを発見したり、あるいは日本語のドキュメントが不足しているなぁと感じることがあると思います。

機能を足して行くタイプのプロジェクトならどんどんパッチを書いていけるし、バグの発見はそれだけで評価されることでしょう。issueに症状を書いて、こういう原因じゃないかと推測し、あわよくばパッチ案を出せれば完璧でしょう。そこまでじゃなくても、バグについて説明があるだけでプロジェクトとしては大きな前進です。

日本語化というのは重要な貢献だと思います。ローカライズというのはどのプロジェクトでも困るものです。概してローカライズの効果は非常に大きいです。英語は共通言語ですが、母国語が英語である人が殆どという訳では全くありません。プロジェクトに依りますが、ローカライズするしないで製作物の影響する範囲は全く異なります。しかし、ローカライズはその言語を母語などにしている人が必要であり、そしてそのクオリティはプロジェクトの運営者には(その人の母語でない限り)分かりません。そうするとローカライズは限られた人しか出来ず、かつ泥臭い作業だけでなく運営部分まで関わることが出来ます。そういう意味でローカライズは価値が大きいです。


2. 日本発のプロジェクトに貢献する

日本発のプロジェクトはドキュメントが英語化されていなかったりするので人の出入りが少ないことがあります。人手が少ないプロジェクトへの参加は当然ありがたがられるし、パッチを当てる機会も多いでしょう。オープンソースというと国籍は関係ない、という話はありますが、実際日本人にとっては日本のプロジェクトの方がやりやすいことは多いと思いますし、ローカライズの重要性は誰もが知っていることでしょう。
やや古いですが、日本のオープンソースという記事があります。ここから探すのも手でしょう。あと有名なのはenchant.jsでしょうか。

3. スタートアッププロジェクトに貢献する

まだ1.0に到達していないプロジェクトもあります。未完成なのでやるべきことは沢山あります。かつ、歴史が短いので参加者も少ないです。ではスタートアッププロジェクトはどうやって見つければいいのでしょうか。プロジェクトのメンバーは様々な所で宣伝して、人を集めているはずです。アンテナを高く張っていればそれを見つけることもできるでしょう。或いはGitHubで検索してみるのも手です

  star:"100..500"

のように検索すれば中規模のプロジェクトが沢山見つかります。また、GitHubは最近のコミットの頻度が表示されます。これを見れば、今まさに伸びてきているプロジェクトなのか、既に沈静化したプロジェクトなのかも判断することが出来ます。



改めて。オープンソースへの貢献=パッチのコミットと狭義に捉えるべきではないと思います。オープンソースにおける成功とは参加することである、と言います。

パッチが最も直截的な貢献のように思えますが、ドキュメントを書いたり、テストを書いたり、宣伝したり、プロジェクトを成立させる為の要素はいくらでもあります。特に職人気質なエンジニアはこういう努力をしたがらない傾向にあります。

恐らく、こういう良く見せる為の工夫というのに拘るというのはあまりアジアにある文化ではないのでしょう。そもそもオープンソースというのがアジアの文化にそぐわないものかもしれません。

泥臭い作業も重要な貢献です。それを無碍にされることはないでしょう。また、ドキュメントやテストを書くことは必ず次につながります。 パッチを書くための下準備であったり、コミュニティの雰囲気を知ったり。



とにかく何でもいいから参加する。コミュニケーションを取る。それがオープンソースにおける成功といいます。

2014年9月7日日曜日

Torqueでジョブの終了をプッシュ通知する

Torqueに大量にジョブを投げる場合、ジョブの終了を通知する仕組みがあると便利です。
しかしドキュメントが意外と少なく苦労したのでここにまとめます。

・Array Job

まず、大量にジョブを投げる場合はloopではなくarray jobを使いましょう。

#PBS -t 1-100

で100個のジョブを投げることが出来ます。

あるいは他のパラメータ同様qsubで

qsub -t 1-100 ./myJob.sh

として指定することも出来ます。

この時、myJob.shでは100個のジョブを識別するのに$PBS_ARRAYIDというパラメータが渡されます。これを用いてジョブ毎の固有の実装をすることが出来ます。


そして全てのジョブが終わった時の通知はこのArray Jobを用いて行います。


・Job Dependencies

Torqueのジョブは依存関係を指定することが出来ます。例えば、このジョブが終了してから、など。

 JOB1=`qsub ./myJob1.sh`
qsub -W depend=after:$JOB1 ./myJob2.sh

このように、qsubの返し値としてジョブIDが出るので、それを用いて依存先を指定できます。

ただし100個の仕事に依存する場合これで書くのは面倒です。そこでArray Jobを使います。

ARRAYJOB = 'qsub -t 1-100 myJobs.sh'
qsub -W depend=afterokarray:$ARRAYJOB[] ./mail.sh

・Array jobの場合はジョブの名前の後に配列を表す括弧を加える必要がありますのでご注意。

これによって、全ジョブ終了後に実行されるジョブを定義することが出来ます。
そして、その仕事としてmailを指定することでプッシュ通知が可能になります。

メールだけではなく、その場で結果の統計を取ったりしてからメールを送ることもできます。
Torqueのメール機能を使ってもいいと思いますが、自由な形式でメールを送るにはスクリプトにした方がわかりやすいと思いますので。

2014年9月6日土曜日

AI-RTS 人工知能によるリアルタイムストラテジー

Web上で簡単に人工知能を実装してモンスターと戦わせるゲームを実装中です。



まだインターフェイスやデザインを作っていないので見た目がへぼい・何が起きているのか分からん・内容が薄いですがコアとなる内部ロジックが完成したのでデプロイしました。


AI-RTS

Html5 & JavaScriptなのでInternet Explorer以外では動くと思いますが未確認です。

リアルタイムストラテジーと書きましたが、リアルタイムに戦略を考えるのは人工知能です。
コンセプトは、プレイヤーは人工知能をセットして、実際の戦闘は眺めるだけ、という感じです。
AIを書くウィンドウはこんな感じ。

http://ai-rts.appspot.com/

見た目はおいおい考えます。
言語はJavascriptです。


プレイヤーがセットしたコードはフレーム毎に呼ばれ、キャラはそれに従って攻撃したり移動したりします。

戦闘画面はこんな感じ。


......今のところデザインとかグラフィックスは適当なので何が何やら分からない感じになっています。
開発中の画面というのはこういうものです。



あと、成長要素みたいなのも取り入れて、技をアップグレードするみたいなシステムも実装予定です。


ちなみに私のPCだとデバッグ用にbombの攻撃力を100にしていたりします。



こういう類のゲームは中身よりも外見の方が大事だというのは分かっているので、デザインを誰かに頼む予定です。




プログラミングの理論 計算機プログラムの構造と解釈

プログラミングの勉強というと、どういうことを思い浮かべますでしょうか。
実践的には言語の仕様やSTLを学ぶというのは大切でしょう。情報科学としてはアルゴリズムとデータ構造、あるいは情報数学のようなものになるでしょうか。

もちろん言語・STLの仕様とは科学者工学者の英知の結晶でありますから、吸収できるものはたくさんありますし、アルゴリズム等を知ることは実装の幅を広げてくれるでしょう。しかしそのどちらもプログラミングの理論かといわれると、少し遠いように思えます。

Just let me code.
プログラミングは理論というより手を動かすものじゃないかと思っていたのですが、そんなときに「計算機プログラムの構造と解釈」(Structure and Interpretation of Programming)という本に出会いました。これはまさしく「プログラミングの理論」といえる内容の本です。

プログラムを実装するに当たってどう考えればいいのか、何を考慮しなければならないのか、良いコードとは何か。言語仕様等に依存せずに、抽象化、構造化、関数型プログラミング、オブジェクト指向、論理プログラミングといった考え方を学ぶことが出来ます。詳しい内容はAmazonのレビューに任せ、何故この本が良いのかに絞ってお話をします。

こういう洋書のいい所は、言葉だけで説明するのではなくちゃんとコードでも説明して、なおかつ練習問題を用意してくれることに思えます。(練習のためのコードはschemeですが、その文法を学ぶことを通じてソフトウェア工学を学べるというつくりになっています。)学術書一般において和書に比べて洋書が厚い・高いのはこういう寄り添った説明があるからでしょう。

この本はMITの一年生の1学期の教科書として書かれ、今は多くの大学でも初年時のプログラミングの教科書となっています。初年時の教科書ですからプログラミングを始める人も読めますし、プログラミング経験が豊富な方もこの本で理論を学んではいかがでしょうか。

ひたすらにコードを書くだけでは学べないものが学べます。特にプログラマを目指す人は必ず読むべきだと思います。


2014年9月5日金曜日

Windows版Guake, Qonsoleの使い方

以前紹介しましたGuakeのWindows版, Qonsoleを紹介します。
Qonsole Icon


QonsoleはWindows上でドロップダウン式に呼び出すことの出来るターミナルです。見た目はこんな感じ。




デフォルトではWin+Cでターミナルを呼び出すことが出来ます。
Windowsのターミナルといえばコマンドプロンプトですが、他のターミナルも呼び出すことが出来ます。こんな感じの画面で設定できます。
コンソールの大きさ、透明度、シェルの種類、呼び出しコマンドなどなど、自由にカスタマイズすることが出来ます。



Windowsではターミナルを使わない、と言う方もいるかと思います。まぁUnixと比較して使い辛いことは間違いないでしょう。しかしGUIよりもCUIの方が効率が良い場面はいくらでもあるでしょう。Qonsoleは非常に手軽に起動出来ますから、これを機会にWindowsにも触ってみてはいかがでしょうか。

2014年9月3日水曜日

コピーしたsshキーを使う(Linux, Ubuntu)

デュアルブートなどをしていると、sshキーを共有して使いたいということは多いと思います。

しかしsshキーを他のOSやPCからコピーして使う場合は、単純に.sshにコピーするだけでは使えません。



1. 権限を変える
sshキーとして使うには権限が必要です。

chown usr:usr ~/.ssh/id_rsa*          (usrにはユーザーの名前を入れる)
chmod 0600 ~/.ssh/id_rsa
chmod 0644 ~/.ssh/id_rsa.pub


2. ssh-add
sshキーが変更・追加されたことをsshコマンドに伝える必要があります。

ssh-add

これで動きます。

一台のPCの複数のユーザー・OSでsshキーを共有することはそんなにセキュリティ上問題ありません(一つ割れば何でも出来ますので)。しかし複数台のPCで共通のキーを作るべきではありません。それがssh-copyなどのコマンドがない理由です。

2014年9月1日月曜日

C++初心者が中級者になるための5冊の本

C++は非常に「巨大な」言語です。

とりあえずプログラムが書けるようになるというのと、C++を「理解した」ということは大きな差があるでしょう。思うにC++は、彷徨える初心者が最も多い言語じゃないでしょうか。

C++は沢山の良書と、それ以上に沢山の悪書があります。
そして残念ながら、C++を始めたばかりの方にはそれを見分けることは出来ないでしょう (出来るなら初心者ではないでしょう)。

constとかstaticとか意味は分かるけど、何の為に使うのかが分からない。 ポリモーフィズムもコードは読めるけど、どういう時にどうクラスを設計したらいいのか分からない。

そういう方にお勧めの本を5冊紹介します。



***

Effective C++ (Scott Meyers)

「C++2冊目の本」として確立した名著。
1冊目で文法を学んだら、次にこのEffective C++を読んで間違いないです。
この本は文法そのものに対する解説は深くはしませんが、何故constをつけるのかを考えることによってconstなどの文法への理解が深まります。
C++自体への理解を深めると同時に、50のルールとして、実際のプログラミングに役立てられるようにまとめられています。


More Effective C++ (Scott Meyers)

C++という名前の由来は、Cをインクメントしたものなので、Cをその一部として含みます。しかしCがその大部分を占めているかというと、必ずしもそうではありません。

大まかにC++はC、オブジェクト指向、テンプレート、STLの4つの集合にゆるやかにまとめることが出来ると言われております。Cとは大きく異なる言語です。Cにちょっと機能を足した、というものではありません。(ちなみにC++は++CではなくC++なので、返し値はCだというジョークがあります。)

MoreEffective C++は主にオブジェクト指向の部分と例外について扱います。何故エラーコードではなく例外を投げるのかなど、オブジェクト指向としてのC++について丁寧に解説されています。多くのプロジェクトはオブジェクト指向でしょうから、とりあえずこの本は優先的に読むべきかもしれません。javaでのオブジェクト指向の経験のある方も、C++固有の事情が結構あるので参考になると思います。


C++ Coding Standard (Herb Sutter and Andrei Alexandrescu)

前書きにこの本の真髄が述べられている。標準化(Standardize)の重要性とその方法について解説した本です。標準化というと自由度が損なわれるという意味だと思われる方は是非この本を読むべきでしょう。この本のもう一つの主張は標準というのは自由である、ということです。

プロジェクトメンバーとお作法を統一するなどという狭い意味ではなく、C++の言語の設計思想や言語実装と照らし合わせ、最もスマートな方法(標準)を知ることでパフォーマンス・移植性・頑強性のトレードオフを高い水準で保つことが出来る、という本です。

標準化の方法について、101のルールにまとめて明文化してあります。


Effective STL (Scott Meyers)


 More Effective C++で述べた4つの集合のうち、STLについて解説した本です。
 
STLはオブジェクト指向とテンプレートに内包された集合ですが、それらに比較して重要度が小さいということではありません。また、オブジェクト指向を先に学ばなければならないということでもありません。STLを学ぶべき理由をいくつかあげると、


1. プロジェクト中に実装するデータ構造の殆どはSTLを利用する

2. オブジェクト指向やテンプレートの勉強になる

3. アルゴリズムとデータ構造について学ぶことが出来る


といったことが挙げられます。

Effective STLはプロジェクトにSTLを使うためのTipsをまとめてあります。それらのTipsを知ることは1のプロジェクト中に実装する為の知識となります。また、Scott Meyersは必ずWhyについて言及します。何故そのようにコードを書くべきなのか。それを理解することで2, 3の知識を得ることが出来る、という構成の本になっています。


C++ Template: Complete Guide
(David Vandevoorde and Nicolai M. Josuttis)


Complete Guideの名の通り、全ての方向からテンプレートプログラミングを解説した本。テンプレートの概念的な説明から入り、それがどのように実装されているかも詳述してあります。テンプレートを実装する際の様々なテクニックをリファレンス的に紹介し、テンプレートメタプログラミングの導入と、STLがどのように実装されているかなどの実例も収録されています。

テンプレートがそうであるように、非常に内容の大きい本です。
この本一冊読めばテンプレートの本質とその実装が出来るようになります。テンプレートの魅力を理解できるようになる一冊です。


***


これらの本をすべて(或いは一部)読んだならば、一通りのオープンソースのコードを読みこなすことが出来ると思います。習うより慣れろというのはプログラミングの鉄則ですから、上記の本を読みつつ、オープンソースのコードを読んだり、自分で何か作ったりしてみてはいかがでしょうか。

5冊合わせると約1550ページ(索引除く)ですので、Introduction to Algorithmを越すページ数です。C++は、それくらい大きな言語です。そして、それらを理解してもまだまだ深い世界があるのです。テンプレートメタプログラミングや並列処理など、まだまだトピックはいくらでもあります。

Peter NorvigのTeach Yourself Programming in Ten Yearsという記事があります。
C++に限った話ではないですが、C++は10年かけて学ぶ価値のあるものだというのは皆の共通見解でしょう。