2011年6月29日水曜日

えっと…転職するらしいです。

Twitter中毒なので、日頃の出来事をTweetしているので、私をフォローされている方はご存知のことと思いますが、

7月いっぱいで現在の会社を辞め、9月より株式会社トップゲートにて働くことになりました。


転職の経緯

  • Googleのテクノロジーに興味があった(Android/GAE)。特に費用面などの優位性からクラウドというジャンルに未来性を感じていました。
  • エンジニアとしてより高いレベルで仕事をしたいという思いがあった。トップゲートの社員の方々はスキルの高い方が多く、刺激のある環境を期待した。
  • 現在、独身であり、特に金銭的な課題はない。今年で34歳という最後のチャンスと考えていた。プログラマーとして身を立てていくことが、自分のやりたいことであり、それを実現できる環境に身を置きたかった。
といった、理由からトップゲートにて働くことにいたしました。

SIから身を引くこと

もちろん、ネガティブな理由を並べていくと、
いろいろとあるのですが、簡単に申し上げると、

SI的な構造の中でプログラマーとしてやっていくには無理がある

ということです。

もちろん、
こうした構造を改造していくことを目指すのは
選択肢としてありましたが、
これはかなり根気を要する行動であり、
真に強い人間でないとできないと思います。

しかし、私はそれほど強い人間ではありません。
そして、無理をしてでも成し遂げるほどに、
今の会社にも思い入れはありません。

(私の周囲では、私のことを変に高く評価されて、
特に出身大学などの偏見から、
私ならできるという輩もおりますが、
私も一介の人間であり、それほど強いわけではありません。)

合わない環境で頑張るのと、
会う環境で頑張るのとどちらか二択となったときに、
後者のほうが自然な流れだろうと考えました。

会社選定まで

何個か会社の候補は上がっていて、来月くらいから具体的なアクションをとろうと考えていました。

実際に、本当に行動をとろうと考えたのが、2011年6月の中旬でした。

まあ、ある出来事があったのですが、それはおいておきます。
その直後にわかめさん(@vvakame)から
「しゃっちょ~、Androidでテストなクラスタの人間が転職を希望しています」
というツイートがあり、
そのあとトントン拍子に話が進み、9月から働くということで合意を得ました。

なので、転職活動っぽいことは全くしておりません。



新しい会社ではわかめさん以外にも、のとさんなど数人の知り合いがおりますので、新天地というよりはクラス替えという感じに近いです。

フォロワーのみなさまにおかれましても、ファイルサーバーの運用が大変などのお悩みをお抱えの場合にはぜひお声がけいただけると嬉しいです。

というわけで、まぁ、今後とも宜しくお願いいたします。

2011年6月27日月曜日

ちょっとやりたいアプリメモ

やりたいアプリのメモ

  • 恋ゲー的情報処理試験アプリ
  • Chrome Extension : ページ内の一部の文章を選択したら、その部分と、ページのタイトルと、URLをTwitterに投稿する
  • 英語、フランス語、スペイン語から日本語への翻訳英会話Androidアプリ - 大学で三ヶ国語(英語、スペイン語、ラテン語)をやっていたオレにしかできないアプリ

今んとこはこれくらいかな

しかし、昨日、英語での音声出力ができなかったのがショックで、3.は頓挫中。
だれかオレにアドバイスを~(涙)

IntelliJ IDEAでslim3プロジェクトを使用する。

単なるメモ。

IntelliJ IDEAでGAEアプリを作成することはできますが、
Slim3を使用するとなると、結構設定が面倒くさい。

一応、IntelliJ IDEAでSlim3を使ったプロジェクトの
設定ノートを書いておきます。

プロジェクトの作成

Slim3プロジェクトの準備


Slim3-blank-n.n.n.zipを解凍したフォルダをIntelliJ IDEAプロジェクト用の作業スペースにコピーします。


プロジェクトの新規作成


IntelliJ IDEAにて新規プロジェクトの作成を選択します。


既存プロジェクトからのインポート


新規プロジェクトを作成する際に、既存モデルからのプロジェクト作成を選択します。


よしなにやる


よしなにやっていきます。Slim3は元々Eclipseで作成されているプロジェクトですが、既存ソースからプロジェクトを作成するを選択します。

先ほどコピーしておいたプロジェクトのパスと一致するように、強引にプロジェクト名を入力してください。

上書きするかとか聞かれるので、そのまま上書きする。

イエスマンのように、イエ~スと押し続けていく。


…ネクストだったorz

おもむろにFinish!

そうすると、こんな感じでプロジェクトが出来上がる。



プロジェクトの設定を行う。


Ctrl + Sft + Alt + Sでプロジェクトセッティングを表示する。
その際に、まずは「Modules」→「プロジェクト名」→「Sources」→「test」→「Test Sources」と選択していって、testフォルダを認識させる。

Platform Settings→新規設定→名前に「GoogleAppEngine-1.5.0」(2011/06/27時点での最新は1.5.1)→クラスの追加を押してjarファイルを選択する。

この際に入れておくべきjarファイルは以下のとおり。場所はGae-SDKのlibフォルダにあるので、気合で探す。

appengine-local-runtime-shared.jar
el-api.jar
repackaged-appengine-ant-1.7.1.jar
repackaged-appengine-ant-launchar-1.7.1.jar
repackaged-appengine-jasper-6.0.29.jar
repackaged-appengine-jasper-el-6.0.29.jar
repackaged-appengine-tomcat-juli-6.0.29.jar
jsp-api.jar
servlet-api.jar
appengine-jsr107cache-1.5.0.jar
jsr107cache-1.1.jar
datanucleus-appengine-1.0.8.final.jar
datanuclieus-core-1.1.5.jar
datanucleus-jpa-1.1.5.jar
geronimo-jpa_3.0_spec-1.1.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
jdo-api-2.3-eb.jar
appengine-tools-api.jar



また、modulesに戻って、「Modules」→「プロジェクト名」→「Dependencies」→「Add」と選択していく。


「Add」ボタンをクリックした後に、何か選択が出てくるので、迷わず「2:library」を選択する。
すると次のような画面が表示されるので、「lib」と「GoogleAppEngine-1.5.0」を選択する。


おめでとう


これで心置きなく、IntelliJ IDEAのパワーを存分に発揮してslim3での開発ができるようになります。

オレは今のところ、slim3本の写経しかしていませんが、半端無く写経の速度は高くなります。
たとえば、「@Test public void testDeleteRootEntity」というテストメソッドを書いていくためには、

pu + Enter
voi + Entet
testDeleteRootEntity



と打っていくだけなので、かなりの速度が体感できます。


プロのプログラマーとしてはお気に入りのIDEも使いこなせるようになっておきたいですね。

2011年6月23日木曜日

Groovyでword count

Groovyでword countをやってみました。
ただ、まあ普通にカウントするだけでは面白く無いので、
@fumokmmさん『今日から始めるGPars』を参考にして、
並列処理でやってみました。

以下、ソースコード

def count(arg){
    withPool{
        arg.parallel
            .map{[it, 1]}
            .groupBy{it[0]}.getParallel()
            .map{it.value=it.value.size();it}
            .sort{-it.value}
            .collection
    }
}

count(words.replaceAll("-\n", "").replaceAll(/[..:.,]/,"").split(/[\s:]/)).each{
    println it
}


実際のカウントの部分のreplaceAll(String, String)は対象となる文章(GoogleのMapReduce論文)に合わせて、適宜文字の調整をするために行っています。

で、これの結果の上位の文字は次のとおりです。
the=484
of=312
a=213
to=197
and=170
is=122
The=104
in=97
MapReduce=87
for=85
that=79
)=76
data=72
reduce=68
(=63
by=60
map=59
on=58
output=58
are=56
function=49
tasks=48
task=48
machines=45
as=41
input=40
it=40
from=38
this=34
computation=33


小文字、大文字の変換をやっていないので、ちょっと微妙ですかね。
また、カッコの数も違っているので、なんか微妙です。

ちなみに、実行速度は以下の条件で、
Intel Xeon 3460
RAM 8.00GB
Groovy 1.8.0
Java 1.6.0-24
約1s程度でした。

2011年6月21日火曜日

Androidでも流れるインターフェース

無駄に流れるインターフェースでOnClickListenerを実装してみた。

まずはアプリの仕様から。

画面仕様
  • 最初の画面はTextViewButtonで構成される。
  • Buttonをクリックすると、次の画面に移動する。
  • 次の画面はTextViewButtonで構成される。
  • Buttonをクリックすると、最初の画面に移動する。

非常に単純な作りですね。
ちなみにこれは次の記事でテストを書くのでよく覚えておいてね。


で、百聞は一見にしかずで、これまた画面の動きをハードコピーしました。


この画面で「push me!」を押すと、


この画面になります。

多分、Androidをやっている人たちなら、この画面簡単に作れちゃうでしょう。
いや実際オレも30分くらいで完成しました。
では、これからオレがdisるコード例を示します。


class MainActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        View view = findViewById(R.id.button);
        view.setOnClickListener(
            new OnclickListener(){
                @Override
                public void onClick(View v){
                    Intent intent = new Intent(this,
                            NextActivity.class);
                    startActivity(intent);
                }
            }
        );
    }
}


読みづらいですね。
まだ、OnClickListenerがひとつだからいいものの、複数のViewにボタンを設定するとなったら、発狂しそうですね。

というわけで、オレが実装したのは次のようなコードです。

class MainActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        Create.activity(NextActivity.class)
            .from(this)
            .listenOn(R.id.button);
    }
}


インターフェースを単純につくっています。
まずはインターフェースから。


interface MoveActivity extends OnClickListener{

    public MoveActivity from(Activity preActivity);

    public MoveActivity to(Class<? extends Activity> nextActivity);

    public MoveActivity listenOn(int view);
}


インターフェースはこれだけです。
前のエントリとほとんど変わりません。変わったのはlistenOn(int view)を付け加えたあたりですね。
したがって、これを実装したクラスのテスト性もほとんど変わりません。

これの実装が頑張りどころです。

class Create implements MoveActivity {

    private Activity preActivity;
    private Class<? extends Activity> nextActivity;

    public static MoveActivity activity(
            Class<? extends Activity> newActivity){
        return new Create()
                .to(newActivity);
    }

    @Override
    public MoveActivity from(Activity preActivity){
        this.preActivity = preActivity;
        return this;
    }

    @Override
    public MoveActivity to(Class<? extends Activity> nextActivity){
        this.nextActivity =  nextActivity;
        return this;
    }

    @Override
    public MoveActivity listenOn(int view){
        preActivity.findViewById(view).setOnClickListener(this);
        return this;
    }

    @Override
    public void onClick(View view){
        Intent intent = new Intent(preActivity, nextActivity);
        preActivity.startActivity(intent);
    }
}


ここのポイントは普通ならgetInstance(Class<? extends Activity>)とやるメソッド名を、activity(Class<? extends Activity>)としている所です。Javaに慣れている方には若干読みづらく感じますが、あまりJavaに詳しくない人でもこれならActivityを組み立てることできますね。

あともうひとつのポイントは返す型はかならずインターフェースにすること。

これはDevLove Hangar Flight で矢野さんがおっしゃっていた、Javaの型とはクラスではなく、インターフェースのことだというインターフェース原理主義に即しています。これなら、Androidのバージョンが変わってAPIが変更されてもActivity部分は変えなくて済みますからね。

2011年6月20日月曜日

日本Androidの会 6月定例会に行ってきたよ

とりあえず、月曜日なので短めに。

表題の件について、駒場に行ってきました。
19時頃の駒場東大前駅の西口はいいですね。
JKが(以下自粛)

では、レポートを…


HoneyCombアプリつくってみたよ
みやけんさんによるHoneyCombアプリ作成のレポートです。

Android3.0からはAndroid Tab対応になったのはご存知だと思いますが、UI部分がかなり変わってきています。
Android2.xではひとつのActivityがひとつの画面に対応していましたが、HoneyCombアプリではActivityの中にフラグメントとよばれる要素が加わり、複数の画面で構成できるようになったとのことです。(嘘いっているかもしれませんが…)

というわけで、今までのようにActivityの中に、Viewはもとより、ModelもControllerも突っ込んでいたアプリは作り方そのものを見直さないといけないようです。

そうなるとMVCとかMVVM(あまりよく知っていない)とかの話になるのかと思ったのですが、そこまで突っ込んだ話にはなりませんでした。

あとHoneyCombアプリを作成する際に気をつけたいのが
  • とにかくスペックのいいマシンで開発する
  • 活きの良いHoneyCombタブを用意する。
  • やっぱりEclipse
です。

一つ目については、その通りで、スペックのいいマシンでないと、指が止まる→考えていたことを忘れる→何をコーディングしていたのか曖昧になるという悪循環になります。
SIerの悪口を言うのはアレですが、SIerの偉い人はこのあたりのことをあまり理解していないことが多い。そのSIerがExcelからAndroidアプリのコードを作り出すとかやろうとしだしたら、ちょっとやばいことになると思う。

二つ目はAndroid3.0のエミュレーターは重たいので、端末を接続してやるのが多分最適解だと思っています。かなり同意しました。

三つ目ですが、これはどうなんだろう。
IntelliJ IDEAを使っていますが、Androidに関してはEclipseの方がサポートが強い感じがします。テストの実行に関してはAntが一番速いらしいし、融通が効くので(@SmallTest/@MediumTest/@LargeTestアノテーションを有効活用できる)、こちらをおすすめしたいところですが…

ChromeOS/Chromebookについて
丸山先生によるChromeOS/Chromebookの報告。

結論から先に述べると、

Don't buy Chromebook

だそうです。

一応、Googleがかなり本気を入れているらしいのが、ビジネスマシンのクラウド化で、Chromebookはそれをもろに狙っているターゲットマシンという位置づけだそうです。

まあ、確かに業務なんてブラウザだけでできますからね。Chromebookはそれだけの用途にはうってつけだと思います。

セキュリティなどの対策もChromebookではしっかりやっているそうです。

そのなかで、ちゃんとGoogleが企業のデータを預かってちゃんと運用できるのかといったコンプライアンス(?)的なあたりが、冒頭の結論に導かれたようです。

WWDC報告
結構、しゃべってはいけないことが多いらしく、基調講演の内容を主に解説されていました。

個人的には○○○のエミュレーター機能は面白いと思いました。

Windows Phoneについて
興味がわかなかったので、ほとんど右から入って左に抜けていました。
すみません。

ただ、気になったのが、WP7とWP-mangoって何が違うのかよくわからなかったのと、日本では電波法の関係からまだデバッグ用に使える端末がないらしく、ちょっと暗雲が立ち込めていますね。

台湾の報告
台湾のAndroid端末市場についての報告。

向こうではAndroidタブが流行っているそうですが、そのほとんどがAndroid2.2系のものが主流だそうです。

オレ的にはChromeOSの話が聞ければ満足だったので、まあ、参加してよかったと思います。

2011年6月19日日曜日

Android埼玉でJUnitのセッションをしてきました。

Android埼玉でJUnitについてセッションの時間を設けていただいたので、私見ながらJUnitの紹介をしてきました。

まず、その前に、Android埼玉、オレ遅刻してきましたorz
ひどいですね。発表者なのに…
進藤さんご迷惑をおかけいたしました。

埼玉Androidの会の方は藤原さん(@zegenvs)さんが主催するモクモク会をメインに参加していて、定例会の方は実は二回目でした。
というのも、埼玉Androidの定例会はたいていテスト部MTGとかぶることが多くて、テスト部メインなオレは泣く泣く埼玉Androidに参加できなかったのです。(半分ウソつきました。)

以下、今回セッションの時間をいただけた経緯です。
  • 社内用にJUnitの資料をGoogle Docsで作成
  • 特に秘匿にする必要性を感じなかったので、Twitterでアドレス付きでつぶやいた
  • 埼玉支部長の進藤さんから埼玉Androidの会でぜひと…
という感じですね。
30分時間をいただけるなんて光栄です。
ありがとうございます。

あと、資料の誤りを指摘してくださった、千葉Androidの会(#chibandroid)のnouzui2007さんありがとうございます。



で、他の方の発表ですが、一人未完の資料をどう持っていくか作戦を練っていて
モクモクしていやがったので、左耳から入って右耳から出て行っててあまり覚えていません。
あいかわらず失礼なやつだ、オレ。

一応、記憶に残っているプレゼンで以下の二つがあります。

めーめー会
@chocokanpanさんが2~3ヶ月に一度開催する、ジンギスカンを食べる会のLTです。
実は埼玉Androidの会でLTするのが実は二回目で、その初回が第二回埼玉Androidの会だったそうです。
で、それの何が印象に残っているかというと、オレの勉強会デビューがまさにその第二回埼玉Androidの会だったわけです。
そして、埼玉Androidの会のセッションデビュー日とめーめー会の二回目のLTが重なるあたり、奇遇だな~と感心していた次第であります。

スマフォビジネスの事情
Androidアプリ開発者の皆様ならご存知のアプリ紹介サイト[アンドロイダー]を運営するトリワークスさんによるスマートフォンのビジネスモデルのおはなしです。

Androidアプリでビジネスを展開するための非常に有益な情報が提供されたと思います(スルーっと解説)。
で、実はトリワークスさんも埼玉Androidの会で講演するのは二回目でして、その初回はなんと、第二回埼玉Androidの会。これまた偶然ですね。トリワークスさんも@chocokanpanさんに「奇遇ですね」とおっしゃっていました。

そいで、私のプレゼンですが、
いつものTwitter口調でずっとやっていました。
そして、人生初のライブコーディングしましたが、あれは、練習が必要ですね。
内容はすでに頭の中にあるんですけど、手が追いつかないのと、クビが痛いのと、焦るのとで、、、いい経験させてもらいました。
資料はこんな感じです。




オレとしては珍しく、懇親会に参加しました。
土曜日サイコー!

主だった話は埼玉Androidの会でロゴマークを作るということで、
おざわ(@osa030)さんのロゴの話題になりました。

おざわさん曰く、

タマといえば「○んたま」でしょ!


かなり大爆笑でした。

愉快な方達がいる埼玉Androidの会、とても楽しかったです。
埼玉Androidの皆様、今後とも宜しくです。

2011年6月18日土曜日

第16回 G*ワークショップ+JGGUG総会に行ってきました。

第16回 G*ワークショップ+JGGUG総会に行ってきました。

まあ、内容についてはTogetterにまとめられているので、こちらを参照ください。@kimukou_26さんグッジョブです。

以下、所感つーか、簡単な内容紹介。

2010年度JGGUG総会

Japan Grails / Groovy User Groupの活動の報告です。
内容をざっくばらんに言うと、「JGGUGは2010年、頑張ったよ」とのことです。

「レッツゴーデベロッパー2011」レポート
@bikisukeさんによる、仙台でおこなわれたイベントの報告です。
5セッション中、2セッションがGroovyという盛況ぶりだそうです。(Groovyから見て)

なかでも「モデルを書いてください」というお題が出されたそうです。これに会場の皆さん真剣に考えたようで、会場全体で各テーブル(2人で1テーブル)で山ができている(二人が向い合っていろいろ考えている)様子は壮観でした。関東、というか東京のtoo shy boy達ではとてもお目にかかれない光景ですね。

今日からはじめるGPars
@fumokmmさんによる、GParsの紹介。

GParsは簡単に言うと、Groovyの並列処理ライブラリーです。
  • 並列処理ですので、単純なシングルスレッドよりもCPUを効率よく割り当てられます。
  • Map/Fork/Reduceなどの処理もできます。
  • Actorを使うと他のスレッドにメッセージを送ることもできます。

というわけで、Hadoopなどの並列処理プログラミングを検討していて、サンプルでプログラムを書きたい時に非常に便利な感じがしました(正確に言うとHadoopのMap/Reduceとは異なりますが…)。現在(2011/06/18)のバージョンは0.12です。なお、Groovy1.8には0.11がバンドルされているとのことですので、ぜひともそのパワーを体感してみてください。というか、オレがまず体感したい!

ちなみに@fumokmmさんはプログラマーですか?いいえ、猫です。

(2011/06/18 9:12追記)テストの分散実行をGParsでやるとか、サーバーの負荷試験とかそういった用途にも気軽に使えそうですね。

Groovy 1.8の新機能 ~ま、まさか、今までのGroovyが予告だったとでも言うのか…~
@uehajさんによる、Groovy1.8の新機能の紹介です。

参加者の殆どがすでに1.8を触っているという、すごい状況の中でさらにコアな解説をしていただきました。





Groovy始めたときには既に1.8が出ていたオレには何がどう違うかよくわかりませんでした…orz
なお、現在はGroovy1.9の開発も始まっているらしく、Java7の機能が取り込まれるそうです。
オレの勝手な憶測で、秋くらいには1.9出るのではと思っています。

そういえば、時間の都合上かなり詳細な情報は省かれていました。それらについては、『プログラミング Groovy』を買ってくださいということだそうですって、おいこら、これ宣伝じゃねーか…orz

Java SE 7 Launch イベント全国キャラバン開催
寺田さんによるJava SE 7 Launch イベント全国キャラバンの宣伝です。

2011/7/28にJava SE 7がリリースされます。そのLaunchイベントで寺田さんが全国各地で行脚するそうです。
(↑2011/06/18 12:06訂正しました。関係者の皆様ごめんなさい)

早速会社で登録しましたが、登録完了のメールがhtmlメールなのにプレインテキストとして届いていて、読めない…orz

第二部LT大会
LTの時間です。

1: ksky 2: なひ 3: 速水康晴 4: kyon_mm 5: tyama 6: mkawa 7: 杉浦孝博 8: jack 9: nobeans
の順番で行われました。

  • kiy0takaさん GroovyConsoleの拡張をした→失敗した
  • なひさん JRuvyJRubyの紹介とJRuby会議の宣伝
  • 速水さん : 覚えてない←失礼だろ
  • きょんさんうさみみ付けて一言、「GroovyはprivateにアクセスできるJavaです」
  • tyamaさん : Grails1.4-M1の話 = 真剣に使うのはやめましょう。あとで安定版が出るとがっかりするので。ちなみにオレはM1使っているorz
  • mkawaさん : MCViewのお話
  • 杉浦さん : 『もしトラ』の話(『もしも女子高生がバートランド・メイヤーの『契約プログラミング』を読んだら』)
  • jackさん : 一句「Groovy Javaにほんのり 薄化粧」
  • nobeansさん : 「とりあえず、猫出しときゃよろこぶ」。釣れた人はこちら

という感じでした。
コーラが切れかかっていたので、コーラ非常に助かりました。

勉強会といえば、普段はTwitterなどでしかお話をしない人との対話ですが、今日もいろいろな方とお会いいたしました。
メインセッションでGParsのお話をされた猫のふもさんと、『達人プログラマーを目指して』@ryoasai74さん、下の名前が同じだった@absj31さん、これまた猫のtyuki39さん

みなさん見識もあり、技術もあり、人格者であり、素晴らしいですね。
私などは口だけのSE(すべてExcel)なので、もっともっと勉強しなければいけないなと思いました。

それと、

Groovy ネコのアイコン 多いぃぞ


猫だらけ、ネコまっしぐら…Groovy道

2011年6月16日木曜日

Groovyでenumで遊んでみる。

Groovyでenumで遊んでみた。

まずは簡単なコードから。

enum Fruit{
    APPLE, ORANGE, BANANA, MANGO
}
Fruite.each(){
    println it
}


これの出力結果は次のとおりです。

APPLE
ORANGE
BANANA
MANGO


つぎは、『Effective Java』の項目30「int定数の代わりにenumを使用する」から写経してみました。


enum Planet{
    MERCURY(3.302e+23, 2.439e6),
    VENUS  (4.869e+24, 6.052e6),
    EARTH  (5.975e+24, 6.378e6),
    MARS   (6.419e+23, 3.393e6),
    JUPITER(1.899e+27, 7.149e7),
    SATURN (5.685e+26, 6.027e7),
    URANUS (8.683e+25, 2.556e7),
    NEPTUNE(1.024e+26, 2.477e7);
    
    private final double mass;   // kg
    private final double radius; // metre
    private final double surfaceGravity; // m / s*s
    // Gravitational Constant
    private static final double G = 6.67300E-11
    
    // Constructor
    Planet(double mass, double radius){
        this.mass = mass
        this.radius = radius
        surfaceGravity = G * mass / (radius * radius)
    }
    
    public double surfaceWeight(double mass){
        mass * surfaceGravity
    }
}

Planet.each(){
    println "${it.toString()}"
    println "mass -> ${it.mass}"
    println "radius -> ${it.radius}"
    println "surfaceGrabity -> ${it.surfaceGravity}"
    print "surfaceWeight -> "
    println "${it.surfaceWeight(20.0 / Planet.EARTH.surfaceGravity)}"
    println ""
}

println 20.0 / Planet.EARTH.surfaceGravity


私、これ書いていて気付いたんですけど、enumってコンストラクター持てるんですね。

実行結果は以下のとおりです。

MERCURY
mass -> 3.302E23
radius -> 2439000.0
surfaceGrabity -> 0.0
surfaceWeight -> NaN

VENUS
mass -> 4.869E24
radius -> 6052000.0
surfaceGrabity -> 0.0
surfaceWeight -> NaN

EARTH
mass -> 5.975E24
radius -> 6378000.0
surfaceGrabity -> 0.0
surfaceWeight -> NaN

MARS
mass -> 6.419E23
radius -> 3393000.0
surfaceGrabity -> 0.0
surfaceWeight -> NaN

JUPITER
mass -> 1.899E27
radius -> 7.149E7
surfaceGrabity -> 0.0
surfaceWeight -> NaN

SATURN
mass -> 5.685E26
radius -> 6.027E7
surfaceGrabity -> 0.0
surfaceWeight -> NaN

URANUS
mass -> 8.683E25
radius -> 2.556E7
surfaceGrabity -> 0.0
surfaceWeight -> NaN

NEPTUNE
mass -> 1.0239999999999999E26
radius -> 2.477E7
surfaceGrabity -> 0.0
surfaceWeight -> NaN

Infinity


どうも、surfaceWeightの値がNaNになるので、調べてみたら、20 / Planet.EARTH.surfaceGravityが無限だったようで、そりゃNaNになるわな。

2011年6月13日月曜日

97 things Every Project Manager Should Know を読んでみた(3)

A Word Can Make You Miss Your Deadline

たかが言葉、されど言葉


第三回目です。
いつもどおり、ゆる~く翻訳、意訳します。逐語訳ではないです。

プロジェクトのマネージメントについて。
これを読むと日本のプロジェクトマネージメントと
考え方が若干違うなと思いました。

だからアメリカ発祥のPMPだやらの考えを
日本に適用しても無理だと思う気がしました。

では、以下本文

WHICH WORD CAN MAKE YOU MISS YOUR DEADLINE? The answer is "any word." When you are developing a product that will be released in languages other than English, you are adding numerous new risks and constraints to your project.



Some are technical and obvious. For example, if your product will be released in Japanese, it has to support the appropriate fonts. If it doesn't, the Japanese version won't work, even if the English one works perfectly. But font compatibility is not under your control. You and your team need to be aware of translation quirks and consider them before coding. Make sure that the development practices follow international standards that will eliminate such issues.



However, the mere need for alternate language versions also constrains what decisions you can make and when. Typically, localization (Japanese, Swedish, German, etc.) happens in parallel with English development, with a certain lag. It can be a few days, weeks, or even months. However, at some point the translation of the foreign version has to "catch up" with the English version.



You need to make sure during testing and reviews that:
- What is in the English version can be properly translated
- What is translated truly corresponds to the English version
- The translated product works flawlessly
Here's the catch. These three things may be tested after the English version is finished and signed off on. During the testing and reviewing of a localized version, you will always find at least one challenging issue that can't be solved except through a change to the English product.



簡単なActivityInstrumentationTestCase2の書き方

Androidのプログラムの作成方法については、いろいろなサイトで有用な情報が得られます。
しかし、テストとなるとあまり情報が多くありません。

というわけで、
簡単なActivityInstrumentationTestCase2<T extends Activity>の書き方を
記事にしました。

今回のテスト対象のアプリケーションはこんな感じです。
概要
  • EditViewButtonTextViewで構成されている。
  • EditViewに文字を入力して、Buttonを押すと、TextViewに「Hello, + [EditViewの文字]」が表示される。



まあ、百聞は一見にしかずなので、画面イメージ出しましょう。
これが最初の画面です。


そして、これに文字を入れて、ボタンを押すとこうなります。






















では、早速テストを書きましょう。
まずは、コンストラクターとsetUp()から。


class HelloAndroidTest
        extends ActivityInstrumentationTestCase2<HelloActivity>{

    private Activity activity;

    private Instrumentation instrumentation;

    public HelloAndroidTest(){
        super(HelloActivity.class);
    }

    @Override
    public void setUp() throws Exception {
        super.setUp();
        activity = getActivity();
        instrumentaion = getInstrumentation();
        setActivityInitialTouchMode(false);
    }        
}


まず、ここのポイントは
  • コンストラクター
  • setUp()中にあるActivityInstrumentationTestCase2#getActivity()
  • 同様にsetUp()中にあるActivityInstrumentationTestCase2#getInstrumentation()
ですね。

コンストラクターではテスト対象のアクティビティ・クラスをActivityInstrumentationTestCase2に渡してやります。「総称型(ジェネリクス)でクラスを指定しているんだから、なんでわざわざクラスを通知してやる必要があるの?」という声も聞こえそうですね。すこしだけ解説すると、タイプパラメーター<T>というのは、ただただタイプとして機能するだけで、java.lang.Class<?>オブジェクトのような機能や、役割を一切持ちません。

したがって、

        Class clz = T.class;

とか、

        boolean isInstance = object instanceof T;

とか、

        T object = T.newInstance();

などはすべてコンパイルエラーになります。

これよりも詳しい説明は私が説明するよりも他にもっと優れた解説があります。Java総称型メモなどを参考にしてください。

話を元に戻すと、ActivityInstrumentationTestCase2で、テスト対象のアクティビティを起動するために、そのクラスの情報が必要なわけですね。さて、これジェネリクスで指定したクラスと異なるクラスを渡したらどうなるのか?わかりませんねぇ。あとでやってみましょう。まぁ、予想できる結果として、この後の解説で述べる#getActivity()java.lang.ClassCastExceptionが発生するように思います。

setUp()中にあるActivityInstrumentationTestCase2#getActivity()はActivityを起動して、参照を返すメソッドです。これにより、テストコードはテスト対象のアクティビティをそのコンテクスト上で起動することが可能になります。テストはそれ自体でひとつのアプリケーションですが、テストアプリケーションとは別のスレッド上にテスト対象のアプリケーションが起動するのです。これをsetUp()に置くことで、毎回のテストがアクティビティを起動した状態で実行できます。

最後に、setUp()中にあるActivityInstrumentationTestCase2#getInstrumentation()です。このInstrumentationは、アクティビティの起動とは何の関係もありませんが、アクティビティのUIスレッドと同期をとるような場合や、UIに対して操作を行う場合に必要になるオブジェクトです。今回のテストアプリケーションでも使いますので、最初にその参照を取得しておきます。

では、テストコードをどうぞ。


    public void testPressButton() {
        // EditText にフォーカスを当てる ---- (1)
        EditText editText = (EditText)activity.findViewById(
                orz.mikeneck.hello.R.id.edit_text);
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                editText.requestFocus();
            }
        });
        // UIとの同期をはかる ---- (2)
        instrumentation.waitForIdleSync();
        // UIにキーを送る ---- (3)
        sendKeys(KEYCODE_SHIFT_LEFT);
        sendKeys(KEYCODE_A);
        sendKeys(KEYCODE_N);
        sendKeys(KEYCODE_D);
        sendKeys(KEYCODE_R);
        sendKeys(KEYCODE_O);
        sendKeys(KEYCODE_I);
        sendKeys(KEYCODE_D);
        // 前提条件の確認 ---- (4)
        assertEquals("Android", editText.getText().toString());
        // Button をクリックする ---- (5)
        Button button = (Button)activity.findViewById(
                orz.mikeneck.hello.R.id.button);
        activity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
                button.performClick();
            }
        });
        // UIとの同期をはかる ---- (6)
        mInstrumentaion.waitForIdleSync();
        // TextView の値をテストする ---- (7)
        TextView textView = (TextView)findViewById(
                orz.mikeneck.hello.R.id.edit_text);
        assertEquals("Hello,Android", textView.getText());
    }


大雑把な解説ですが、
  • EditTextにフォーカスを当てます。これはUI上の操作に当たるので、Activity#runOnUiThread(java.lang.Runnable)を使用します。
  • UIとの同期をはかります。別スレッド(アクティビティ)との同期はInstrumentationwaitForIdleSync()を用います。
  • UIにキーを送ります。android.view.KeyEventをstatic importしておいてください。
  • EditTextにキーを送ったので、それが反映されていることをテストします。想定される値は「Android」です。
  • Buttonをクリックします。これはUI上の操作に当たるので、Activity#runOnUiThread(java.lang.Runnable)を使用します。
  • UIとの同期をはかります。別スレッド(アクティビティ)との同期はInstrumentationwaitForIdleSync()を用います。
  • Buttonをクリックしたので、仕様通りにTextViewのテキストが変更されているかテストします。想定される値は「Hello,Android」です。
となります。

ポイントは
  • UI上の操作は必ずActivity#runOnUiThread(java.lang.Runnable)を使用する。
  • UI操作後はInstrumentationwaitForIdleSync()を用いる。
です。

#runOnUiThread(java.lang.Runnable)を使わないとUIが操作できないのは、他のアプリケーションからいくらでも値を変更するなどの改変が行われてしまうからというセキュリティ的な側面があるのかと思われます。(Javaそんなに詳しいわけではないので、そのあたりを突っ込んでくれる人、大募集)

二番目のInstrumentationwaitForIdleSync()ActivityInstrumentationTestCase2の真骨頂です。UIスレッドとの同期をはかりスムーズにテストを実行出来るようなオブジェクト類が提供されており、それがActivityInstrumentationTestCase2です。別スレッドのUIと同期するこの能力はテストの実行においてかなり強力な機能です。



こんな感じで、非常に簡単なテストでしたが、みなさまもUI上で不具合を発見したら、なるべくテストコードを書いて、それらを再現できるようにしてみてください。きっと、素晴らしいUIをもつアプリケーションが作成できると思います。

2011年6月9日木曜日

会社でJUnit勉強会をやってみたよ

会社でJUnit勉強会なるものを開いてみました。


JUnit勉強会と言っても、なんか高度なことをやる意図は持ってなく、単純にJUnitの使い方、実際のプログラムへの適用、TDDのやり方の紹介みたいな感じでやってみました。

資料はここを参照

で、結果ですが、

かなり失敗だった


と思います。

原因
  • JUnitの動作を図解したほうが分かりやすかったと思われる。
  • 最初のテストをHello Worldにしたのがまずった。
  • さらにボウリングスコアの計算というTDD定番のネタで研修したあたりがまずった。

1.については対象者がJavaを始めて1ヶ月というAさんと、入社3年目でJava経験2年のBさんであり、まだ、Javaのmainメソッドからの起動を追いかけるというレベルでのsetUpなどの動きを伝えるには、やや高度であったあたりが、厳しかったという感じです。

2.についても同様で、Aさんはもちろんですが、レガシープロジェクトで育ったBさんにも、インターフェースを使ったプログラムの記述を説明するのはなかなか厳しかった。(もちろんこれは覚えてもらわないといけないと思っていますが…)

3.についてはTDDの考え方、というか動き方、これを説明しておかなければならなかったというのがあります。

とはいっても、みなさんテストコードの重要性は理解していただいているので、(毎日オレがうるさくテストコード、テストコードと言っているうちに、テストコードマンセイになった)徐々に実力を向上させていきたいと思う次第であります。

それと同時にIntefaceを介在させることの説明について、
まだまだ自分がうまく説明出来ていないというのを
発見できたので、今後自分ももっと噛み砕いて説明できるようになりたいと思う次第であります。

というわけで、明日はより高度なAndroidのActivityInstrumentationTestCase2<? extends Activity>の
勉強会をやりたいと思います。


つ~か、ActivityInstrumentationTestCase2<? extends Activity>はジェネリクスを使っているあたりで、説明が頓挫しそうな予感がする。

さらに、JUnit勉強会資料を公開した瞬間に@ryu_compin(日本Androidの会埼玉支部、支部長)さんから、埼玉Androidの会でセッションやってというオファーが来ました。30~40分枠をいただけるということで、なんとも光栄の至りでございます。

ん~、でも皆さん、あくまで単なるJUnitでございますよ…

2011年6月7日火曜日

第2回テスト駆動開発入門読書会(ペアプロ写経大会)に参加してきたよ

第2回テスト駆動開発入門読書会(ペアプロ写経大会)に参加してきました。

会場は早稲田大学で、実は人生初早稲田。
会場についたのは30分前でしたが、
まだ誰もいませんでした…orz

さて、開始からですが、
微妙に手際が悪くて10分遅れでスタート。

席の配置を円形に直して、
適当に座ったとなりの人とペアを組むという感じでスタートでした。

オレとペアを組んだのは組込み系に勤める今年一年目の社員の方で、
ノパソに入っていたEclipseが完全にまっさらで、
とてもビックリしました。
(よくある…)

なんか真新しいEclipseにこれから汚いコードをゴリゴリコードを書いていって
いいのか、やや戸惑いつつも、まあいずれ書くんだから
新鮮なテストが書かれていればいいじゃんという感じでやり始めました。

やったのは
  • ペアプロ
  • TDD本を一章から写経する
  • Kent Beckの本の内容を読みつつ、半分納得する。(三角測量はオレが簡単に説明)
  • 2~3章ごとに交代する
という感じです。

オレが最初にナビゲーターになりましたが、
とりあえず、操作がおぼつかないので、
「Ctrl + N」とか言いながら(ゴメンね…とはあまり思っていない)、
ショートカットを覚えてもらいました。

でも、やはりペアの方は若いので、
ショートカットをどんどん覚えるし、
少し羨ましい感じがしました。
(オレのように老いると、物覚えが悪くなって頑固になるのよ…)

2章を終わったあたりで、
ドライバーとナビゲーターを交代しました。

いつものボッチのような感じで、
ブツブツつぶやきながらコードを書きました。
なるべくナビゲーターに身を委ねつつ。

で、Dollar#equals(java.lang.Object)メソッドの
オーバーライドで、
どうしても気になって仕方がないので、nullのパターンを実装してしまいましたが、
これは本質出来ではありませんね。
ToDoリストに記載しておいて、
TDDではないテストコードを記述するときに、別途実装するべきでした。

この辺はナビゲーターの方にToDoに記録してもらいたいのですが、
ナビゲーターの真に難しいとろこは、
二人してコーディングにのめり込んでしまうあたりですね。

この点については、残り20分程度の感想戦で、
議論させていただきました。

頂いたアドバイスとしては、
  • ToDoに記録しておくかどうかはともかく、ポイントはドライバーとナビゲーターが対話をすることである
  • ナビゲーターが距離を少し置くためにポスト・イットを活用する
などがありました。

ぜひ、今後試させていただきたいと思います。

あと、気になった議論として、SIerの現場に同普及するべきかというのがありました。

たしかにSIのプロジェクトの現場ではペアプロする = 二人の稼働でひとり分の成果しかでない
と考えてしまうので、正直のところ導入には非常に慎重的な態度になります。

とは言うものの、SIerの現場にてよく見る光景で、
  • 御前レビュー会議 : えらい人だけが発言・指摘するだけの5~6人による1.5h程度のレビュー - 約7.5hの稼働の無駄
  • デバッグ、皆で考え込む症候群 : なんかうまく動かないが、どこが動かないかわからない(特に新人などが引き起こす)ので、なぜか2~4人が集まってきて2~3時間くらいあ~だこ~だ議論して、なんかよくわからないけど動いて、「あ~よかった」とか言って終りにしてしまうやつ - やっぱり7.5hの稼働の無駄

こう言うのがあるわけで、
意外と無駄に時間を過ごしているパターンは多いわけです。

だったら、無駄な7.5hを二回に分けてペアプロをするだけで、より進むと考えれば、
御前レビューとか、謎の動かない症候群よりも効果はあるように思います。

ま、現場のエロイエライプロマネの方々は、
こんなことを言っても(゚Д゚)ハァ?って顔しますがね。


次回は再来週あたりを想定しているとのことです。
ので、今回参加されなかった皆さんも参加してみてはいかがでしょう。

全然読書会の雰囲気が表現できていませんが、
全体的にはまったりしていましたよ。

2011年6月5日日曜日

97 things Every Project Manager Should Know を読んでみた(2)

Avoid Whack-a-Mole Development

モグラたたき開発から逃げろ


開発する早さの評価に関するエッセイ。
日本のSIerではバーニーさんの方が評価される傾向にありますね。
ものづくり日本という標語が盛んに叫ばれたりしています。
でも、なんか年末になるといらない工事とかがあったりして、
作りっぱなし日本という標語が適切な気がしなくもないです。
だからこそ、読んでほしい一節です。

ちなみに、前回と同じく、翻訳の詳しいところはいい加減です。
翻訳はノリが大事です。
多分怪しいところは満載なので、ツッコミ歓迎です。
それと、オレには突っ込まないけど、オレだけ知ってウッシッシな人はGoogle 翻訳にでもかけてください。

SOFTWARE PROJECT MANAGERS faces a lot of pressure to deliver fast. Time is of the essence. How can you get things done fast?



Imagine you have two programmers on your team, Bernie and Rob. Both are capable, have the same amount of domain knowledge, and have equal language skills. During development, you find that Bernie finishes his feature implementations much faster than Rob.



While Bernie focuses on getting the code completed quickly, Rob spends time writing code and then refactoring it. He names the variables and methods better. Once he gets things working, he breaks the code into smaller pieces. Now he writes tests to make sure each piece of his code does what he meant it to do. When he's reasonably satisfied, he declares the coding of that functionality done.




But assume you don't know these details. If you only look at the speed with which the functionalities are declared done, clearly Bernie is the better man, right?



A few weeks go by, and you demonstrate the features to your customer. As usual, the customer loves your completed features, but now wants you to change and improve them. You ask your developers to make those code alterations. When you take the new and improved functionality back to your customer, they try out the features that Rob implemented and are pleased with the changes.



Unfortunately, they discover something odd with the features that Bernie implemented. While Bernie has programmed in the new functions fine, now a few things that worked before don't work anymore. The customer marks these as defects, and you ask Bernie to fix them. The customer tests the features again. Now even newer, stranger things seem to be broken. What's going on here?



If you have a child, you know what is happening. Bernie has created a Whack-A-Mole application. Whack-A-Mole is a toy. Kids are given a wooden hammer to strike moles that pop up at random. It's fun for them to be surprised by which mole pops up next. However, fixing applications with broken code popping up at random places is not fun. It is frustrating, unpredictable, and it slows your product development. Bernie was sprinting initially, but he was running in the wrong direction.



While Rob appeared slower at the outset, he was actually creating superior code. His pace proved sustainable. The better quality of his initial code helped him make workable changes quickly. Plus, the test he wrote in the beginning gave him instant feedback regarding whether or not his new code was compatible with other parts of the application where the code was used.



When measuring time for a feature implementation, do not consider only the time it takes to write it in the first place. Add the time it takes to enhance, fix, and improve the code. Writing good quality code and tests takes time. It appears to be a short-term loss. However, it comes with a long-term gain.

Ask yourself if you want speed, or if you want to savor sustainable progress.



ま、このブログを読む人なんて、えらいプロジェクトマネージャーなんかいないだろうけどね。
それと、お客さんに同じ機能のテストをさせるなんて、どう考えたってムダでしかない。
ソフトウェアを作りっぱなしで、お客さんになんども同じことをさせるのはどうかと思う。

2011年6月2日木曜日

97 things Every Project Manager Should Know を読んでみた(1)

表題のとおり、読んで、勝手に訳してみた。

今回はその最初のエッセイ『Get Users Involved As Early As Possible』。

ちなみに、オレの翻訳はかなり適当感満載なので、
各自Google先生に正しい訳を求めること。

オレが提供するのは英文が醸し出している雰囲気のみ。



PAST PATTERNS OF SOFTWARE DEVELOPMENT involved getting user requirements and then going off to do the coding and testing under a veil of great secrecy. After all, the users wouldn't understand what we were doing anyway, right? At the end of the project, our magician's magic cloth was whisked away and the user was expected to "ooh" and "ahh" at the brilliance of what we had produced. However, all too frequently the reaction was, "Well, I know you went to a lot of work, but what I really wanted was...".



Today, the secret to project success is to involve the users almost as soon as there is anything visible to show them. How much better it is to find out that there are problems with what we are developing early on, rather than after the project is complete!



Costs for changes become increasingly high the further along we are on the project schedule timeline. The time to recode, retest, and rework the immediate software, as well as to test integration with all the peripheral code involved, can delay the project substantially. And both time and cost baselines are jeopardized if a change is so major that it has to go through a lengthy Change Control Board process for approval.



Programming decisions over very minor issues, which make perfect sense to the software developer and the project manager, may create chaos back at the workstation when the software goes into use.



以下、2011/06/04に追記

I know of a large training company that spent $5 million redesigning its ordering software. Previously, the item numbers matched the product being ordered in a logical way. For example, 4125 might be a student manual, 4225 was the accompanying student exercise disk, 4325 could represent the instructor manual, 4425 was the course outline for marketing purposes, and so on. You could order all the items in the 4X25 series on the same screen



Each day, administrative coordinators in 140 locations around the world ordered the same kinds of materials over and over and soon memorized the item numbers. Once you knew the number for a student manual, you could immediately key in the numbers for the other items without looking them up, and ordering went quickly.



In the redesign, somehow the project team forgot to consider the way the ordering process was used by the real people doing it. Under the new design, there was no logical relationship between items. Item 6358 might be the same student manual that once was 4125, the accompanying student exercise disk was now 8872, and the instructor manual for the same class was 3392.




Not only did the user have to look up each item and try to "forget" the old numbers and system, but also each type of item was now on a separate page.

Administrative coordinators were furious. Ordering slowed to a crawl. The project far exceeded its time and cost baselines.

As a project manager, you should get the users talking to the software developers early and often.