退職しました

昨日が最終出社日で3週間ほど有休を使い人生の夏休みに入ります. まだ雇用関係はあるので NEET じゃないですよ? NEET 状態ですけどね.

一般的には元の会社がどーとか, 新しい会社がどーとか書いたりするんでしょうが書きません. 前にいた会社や部署にも良いところはあるし, 移る理由もすごく個人的なことなのでそんな視点で書いても FUD になるだけです. 要はかっこ悪いので書きません.

経緯

なのでどんな経緯で退職に至ったかの流れを話します.

まず, 全ての始まりは「 Hadoopソースコードリーディング第3回 」. @shot6 さん主催, @kkawamura さん会場提供の, Hadoop について勉強する会. ちなみにタイトルに「ソースコードリーディング」と付いていますが, この会ではソースコードは登場しませんでした. (その後もほとんど出ることが無いという不思議な感じでした.)

当時の Twilog を見返すと, 右も左も分かっておらずポカーンとしてる感じが伝わってきます.

その次の 第 4 回 では Twilog のログ が増えています. 勉強会の雰囲気にも慣れ, 内容も少しずつですが理解し始めたからだと思います.

ここらへんから段々と勉強会中継 bot のようになり, そのつぶやきを勉強会 bot としての先輩である yutuki_r さんに RT されていったこともあり, follower が増えてきました. follower が増えると, ふとつぶやいたことにも反応をもらえることがあり, どんどん Twitter でのグラフ構造が広がっていきました.

そして, もともと人に数学を説明するのが好きだったのもあり 第 5 回 の後には [algorithm][Dijkstra] 文系 Hadooper でも分かる Dijkstra アルゴリズム というブログエントリを書き, 今までの記事に比べるとかなりの反響をもらいました. それまでは特に目的も無く, 自分のメモのようなものしか書いていなかったので, 誰かのために書くというのは初めてだったかもしれません. また第 5 回の様子から, この業界に大学数学が分かる人が思った以上に居ないことが分かりました. それはブログの記事の反響からも読み取れました.

これ以降も「分散」というキーワードで勉強会に出たり, Twitter 上でやり取りすることで転職への流れにつながっていきました. この勉強会に私を誘ってくれた, 旧部署が誇る日本語の文章を解し, リンク先の内容も解析し, 光速な公式 RT をすることで follower の TimeLine を潤している RT bot @yutuki_r さんにすごく感謝しています. (あ, ホントは部署の先輩ですよ. 人間として実装されてますよ.) そしてなによりこんなダメ人間に場を用意し, 声を掛けてくれた QB...じゃなくて @okachimachiorz さんに感謝します. (ダメ人間ぶりについてはまたどこかで.)

一技術者として

ここまでは分散処理の話でしたが, ここからはそれとはまた別の OSS コミュニティのような雰囲気のつながりの話をします.

まず, こちらの発端は @gnue さんが開いた 『ガベージコレクションのアルゴリズムと実装』読書会@関東. GC という, アルゴリズムの性能がプログラミング言語の性能に直結する話に強い興味があり, @nari3 さん, 相川さん, 竹内先生の本の読書会に参加しました.

なんでこの会に参加したかは忘れましたが, 大学院のときのゼミのような雰囲気を感じ取り, そこに惹かれて参加したんだと思います.

この勉強会にはそれはそれは濃い人達 @shinh さんとか @isoparametric さんとか @pi8027 さんとか @melponn さんとか @finalfusion さんとか, 主催の @gnue さんとかが参加されており, すごく刺激になりました. もちろん他の方々も総じてレベルは高かったです. ここで名前を挙げたのは, その中でもまだやり取りをしていたり, キャラが立っていたりした人達です :)

この濃くレベルの高い勉強会を知ってしまったために勉強会にハマってしまい, Twitter で興味のある勉強会を見付けては参加していきました.

その中でコミュニティや会社を越えた技術者どうしのつながりが構築され, FOSS の空気のようなものを強く感じるようになりました. その空気は言葉にはしづらいのですが, とにかく会社の中とは違う空気でした.

その後, 自分でも勉強会を開くなどしていき, どっぷりハマっていきました.

Python

その勉強会の中でも Python との出会いは今の自分に大きく影響しています. InfoTalk という AIIT で毎月やっている勉強会で, エキスパートPythonプログラミング の訳者4人のうち2人 @methane さんと @shibukawa さんが発表されるというので InfoTalk#21: Python Summer に行きました. (仕事で Jython を使ったこと Python 自体には触れてはいました. 今考えると筋が悪いし, レベルも低いですが.)

この本は気になっていたのでさっそく購入し, 懇親会にて @t2y さん含め4人中3人のサインをいただけました. アイドルなどにハマったことはないので, 誰かのサインを求めたのはこれが初めてでした. お願いする手が震えていたのをよく覚えています.

4人中3人まで集めたので後は1人, 師匠の @shimizukawa さんのサインが足りません. どうもこの本の読書会をやっており, そこに行けばサインをもらえるだろうと考え エキスパートPythonプログラミング読書会03 に参加しました. 01, 02 でやった内容は簡単な文法なので途中からでも大丈夫だろうと, サイン目当てで飛び込んでみました. 本も面白いし, @shimizukawa さんの話も実務に沿った内容で, 単なる理想論以上のものが聞ける会だったので, その後はほぼ全部の回に出てぎゃーぎゃー言ってます. (継続中) それは http://togetter.com/t/expertpython ここらへんの togetter を見てもらえば分かると思います. 内容まとめ & 疑問投げ bot と化しています.

また読書会03の懇親会では InfoTalk でサインをいただいた @t2y さん, 世界の @tk0miya さん, @shimizukawa さんという, 今振り返るとすごく濃いメンバーに囲まれ楽しく会話をしビールを飲んできました.

この流れのまま Python にどんどんのめり込んでいき, Pythonista の方々と交流を広げ深めたり, CPython 3.2 ソースコードリーディング <http://partake.in/events/4fbc22d9-67ad-4c2e-a5e7-01e05c6eb04c> を開催したりしていきました. (他にも色々やってますが, きりが無いので省略.)

まとめっぽいもの

こんなふうに主に人との出会いを通してこの数年で自分が変わっていって, その結果転職という道を選び, その先へ進もうとしているのだと思います.

今振り返ってみて, これが1年4ヶ月ほどの期間の出来事だったことに正直驚いています. 自分も変わり, 周囲とのつながりも変わり, 周囲からの評価も変わり, すごく不思議な気持ちです. 人と出会うということはそういう変化を伴うものなんだと思います. (もちろん何かをアウトプットして周囲に情報を与えていくことは前提ですよ.)

気持ちとしては, 同期と話しててふと口から出た「卒業」という表現がピッタリ来ます. 「私の戦場はここじゃない」というセリフがピッタリきます.

変わったことが良かったかどうかは5年から10年後の評価を待たないといけないですが, 私に変化をもたらし, 前に進めてくれた人達みんなに感謝します. (これを読んでるあなたですよ, あなた.)

次の会社は知ってる人は知っていますが (バレバレですね^-^;), またそのとき記事を書きます.

まずは3週間の人生の夏休みを楽しもうと思います. 娯楽的にも数学的にもプログラミング的にも. なにより家族との時間を大切に.

素因数分解の暗算高速化

誰の役に立つのか, 何の役に立つのか良く分からないが, 中学生くらいのときから数字を見るたびに素因数分解に挑んできた俺が使っている, 暗算で素因数分解をする方法を紹介します.

方針

簡単に計算できるように, 1桁の掛け算と2桁の足し算くらいしか使わないことにします.

11で割る

まず, 一番簡単な11から.

11 = 10 + 1 を利用して, 11の倍数をどんどん引いていきます. 残りが0になったら11の倍数, そうでなかったら11の倍数でない, と分かります.

具体例

135 から始めます.

  1. 135 を 13 と 5 に分解.
  2. 13 - 5 を計算して 8.
  3. 11 で割れないので終了.

簡単ですね.

7で割る

7 * 3 = 21 を利用します.

具体例

1113 から始めます.

  1. 1113 を 111 と 3 に分解.
  2. 111 - 3 * 2 = 105.
  3. 105 を 10 と 5 に分解.
  4. 10 - 5 * 2 = 0. よって7で割り切れる.

色んな数で割る

せっかくなので, 41 くらいまでは揃えてみましょう. そうしておけば, 42^2 = 1764 までの数に出会ったときに素因数分解で困ることは無いです(誰得

3で割る

各桁の数字を足す. 有名なのですぐ分かる.

5で割る

下1桁見れ.

7で割る

既出

11で割る

既出

13で割る

13 * 3 = 39 を利用して,

  1. 下1桁と上の残りに分解
  2. 上の残りに下1桁の4倍を足す

で, 13で割った余りを変えずに数を小さくできる.

17で割る

17 * 3 = 51 を利用して, 下1桁の5倍を上の残りから引けば良い.

19で割る

下1桁の2倍を上の残りに足せば良い.

23で割る

23 * 3 = 69 なので, 下1桁の7倍を上の残りに足す.

29で割る

3倍を足す.

31で割る

3倍を引く.

37で割る

37 * 3 = 111 なので, 11倍を引く. 37の倍数で2桁のものは, 37 と 74 しかないので覚える.

41で割る

4倍を引く.

まとめ

非常に誰得なエントリですが, こういうネタが好きな人が居れば嬉しいです. というか変態です.

43 は素直にやると13倍を足さなきゃいけないので面倒です. 誰かもっと良い方法教えて.

それでは.

Google Code Jam 2011 反省

総括

A -> C -> B の順に解いていった. D はちゃんと読んでないけど, 読んですぐ解けるのを選んでいった.

問題読むのにも時間かかるのでこの方針は間違ってないはず.

Problem A

順調に解け問題無し. 細かい計算をもっと速く実装できるように鍛錬.

Problem C

英語の読み間違いにより時間をロス. 英語をすらすらと読めるようになろう.

素数がらみの問題だと分かったが, 素数生成で手間取る. こういうのは予めメモリサイズや速度を考慮したライブラリを自分で作っておくべき. 去年と同じく Big の方でメモリサイズを考えずにプログラムを走らせ, swap しまくりで遅くなり expired. 無念.

終わってから大きい方の素数について無駄な計算をしていることに気付く. 枝刈りの感覚重要.

Problem B

総当たりっぽかったのでいったん避けたが, やっぱり総当たりしか方法が無さそう. 最初から解けば良かった.

Python で解いていたが, debug に手間取り時間切れ.

追記

他の人のつぶやきを見ていて気付いたこと.

Problem B で総和を何度も求めているが, そこのコスト計算をしてなかった. 範囲を変えて総和を求める場合のチューニング方法を知っておくべき. 先頭からの和を取って事前処理をしておけば, 部分的な総和は O(1) で求まる.

Python C/API Tutorial 3.1.1 Numbers

今日も C/API で遊んでいます. 最後の round に苦労したけど, おかげでモジュールあたりに詳しくなりました.

#include <Python.h>

void code1()
{
    PyObject *result;

    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2));
    PySys_WriteStdout(">>> 2+2\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    // This is a comment
    PySys_WriteStdout(">>> # This is a comment\n");
    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2));
    PySys_WriteStdout("... 2+2\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    result = PyNumber_Add(PyInt_FromLong(2), PyInt_FromLong(2)); // and a comment on the same line as code
    PySys_WriteStdout(">>> 2+2  # and a comment on the same line as code\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));


    result = PyNumber_Divide(PyNumber_Subtract(PyInt_FromLong(50),
                                               PyNumber_Multiply(
                                                   PyInt_FromLong(5),
                                                   PyInt_FromLong(6))),
                             PyInt_FromLong(4));
    PySys_WriteStdout(">>> (50-5*6)/4\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    // Integer division returns the floor:
    PySys_WriteStdout(">>> # Integer division returns the floor:\n");
    result = PyNumber_Divide(PyInt_FromLong(7), PyInt_FromLong(3));
    PySys_WriteStdout("... 7/3\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    result = PyNumber_Divide(PyInt_FromLong(7), PyInt_FromLong(-3));
    PySys_WriteStdout(">>> 7/-3\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    return;
}

void code2()
{
    PyObject *width = PyInt_FromLong(20);
    PySys_WriteStdout(">>> width = 20\n");

    PyObject *height = PyNumber_Multiply(PyInt_FromLong(5), PyInt_FromLong(9));
    PySys_WriteStdout(">>> height = 5*9\n");

    PyObject *result = PyNumber_Multiply(width, height);
    PySys_WriteStdout(">>> width * height\n");
    PySys_WriteStdout("%ld\n", PyInt_AsLong(result));

    return;
}

void code3()
{
    PyObject *x, *y, *z;

    x = y = z = PyInt_FromLong(0); // Zero x, y and ...

Python C/API Tutorial

http://docs.python.org/tutorial/introduction.html

Python Tutorial を C/API で書いてみるとどうなるか? という実験です. 2章までは Python そのものの紹介なので3章から. 本文とかは飛ばして, コードサンプルの C/API への翻訳に注力します. (もしかしたらそのうち文書もちゃんと書いて公開するかも.)

コンパイル

コンパイル方法は以下を参考に

こんな感じでやりました.

# ライブラリ
$ gcc -Wall -fPIC -c hello.c -I/usr/local/Cellar/python/2.7.1/include/python2.7/ -lpython2.7
$ gcc -shared -o hello.so hello.o -lpython2.7

# 実行バイナリ
$ gcc -Wall -I/usr/local/Cellar/python/2.7.1/include/python2.7/ -lpython2.7 chap3.c -o chap3

今使っている Python は homebrew でインストールしたものなので, そのヘッダファイルのあるディレクトリを -I (<-large ai) オプションで指定. ライブラリは /usr/local/lib/libpython2.7.dylib にあるので, -l (<-small el) オプションの指定だけで読めたみたい.

最初のコンパイルで PyArg_ParseTuple 云々で警告が出るけど, いったん無視.

3. Python のくだけた紹介

#include <Python.h>

int main(void)
{
    Py_Initialize();
    // this is the first comment
    PyObject *SPAM = PyInt_FromLong(1); // and this is the second comment
                                        // and now a third!
    PyObject *STRING = PyUnicode_FromString("// This is not a comment.");
    Py_Finalize();
    return 0;
}

これで作った chap3 を動かしても何も出ません. 出力ロジック書いてないから当たり前ですが.

とりあえず今日はここまで.

CPython 3.2 ソースコードリーディング 第 2 回

http://partake.in/events/752c6759-83b0-4b96-a1ee-95e220977990

先月に引き続き CPython のソースを読んでいきました. 今回もやや言語処理系寄りの話になっています. Python でそういう方面の勉強会は無いからまぁいいかな? と思いつつ, 今後の方向性についてはまだ検討中です.

俺も発表しましたが, 俺以外の人の発表も楽しく聞いていました. 言語の中心部分を深く知ること自体がやっぱり楽しいです. わくわくします. 「ソースコードリーディング」というキーワードで勉強会をやると, そういう人達が集まって濃いマニアックな話ができて嬉しいです.

それと同時に集まってきてくれている人達に何か渡せているものはあるのか? と悩み考えることも多いです.

「Hack-a-thon っぽくその場で C/API を使って何か実装する」「できるだけ速い実装をする」とかいう案ももらったので, 何か変化球を入れたいなぁとも思っています.

そういう悩みの機会になる, という意味でも良い経験を積んでいるのかな, と思います.

それでは.

TAPL 読書会 第 6 回

5/7 は TAPL 読書会の第 6 回でした.

その場で読み合わせだと進みが遅くなってしまうので, 自分が発表してきました. 発表資料はここです. (未完成)

PDF

pLaTeX ソース

準備はそれなりに大変ではあるのですが, 深く理解することができるのと終わった後のビールが美味しいので, けっこう悪くないものです.

それでは.

Python mini Hack-a-thon #7

「ブログ書くまでが勉強会」らしいので書いておきます. ツッコミなどなど歓迎です.

出発

11:00開始の会なのに, そもそも出発が13:00とかいうふざけたダメ人間っぷりを発揮したのですが, これには一応理由があるのです.

まず6:00ごろ娘 (10ヶ月) に起こされ相手をしていたのですが, 10:00ごろになり眠くてしようがなくなり居眠りを. そして11:00くらいに動き出して風呂入ったりなんだりノソノソ用意していたらこのざまでした.

基本的にダメ人間ですね.

Hack の内容

最近は Python 系では CPython についてソースコード読んだり, 調べたりしています. そもそも言語処理系に強い興味がある人なのでそれだけで楽しいし, CPython を改造できたりしたら cool だと思うので, CPython Reading という勉強会も主催しています.

今回は dict の話をしようということで dict の C API を使って何か作ってみることにしました.

すぐ思い付くネタとして「双方向辞書」を作ろうという話にしてみました.

PyPI デビュー?

その双方向辞書を Reversible Dictionary (revdict) と名付け開発を開始したので, ついでに PyPI に上げられる形に整えることにしました.

清水川先生に, module 名どうするか? だとか, setup.py ってどう書くんでしたっけ? とかアドバイスをいただきながら作業してました. 時間内に setup.py が書けなかったのでデビューは先送りになりましたが, revdict が完成したら PyPI に公開します.

Hack-a-thon も終わって

参加時間が短かったので成果はあまりありませんでしたが, 色んなとこに首を突っ込んで Hack な話をして, ある意味正しい Hack-a-thon の楽しみ方をしてきました.

どうも終わってすぐ帰られたようで, @atsuoishimoto さんに挨拶できなかったのが残念.

懇親会では引き続き楽しく盛り上がってさまざまなお喋りをしてました. 他の会社の人の話を聞くのは, 新卒で入った今の会社の内部しか知らない自分にとっては, 新鮮で刺激的で非常に面白いです. ただ「PyPI, PyPI」と大きめの声で発言してしまい周囲に誤解を与えたんじゃないか? というのが唯一の反省点です.

次回は 5/14 ということで CPython Reading の前日なので, 家族的な面で参加が厳しいかなぁ? と思います. また次々回の mini Hack-a-thon に参加しようと思います.

それでは.

TAPL 読書会 第 5 回

今日は TAPL 読書会の第 5 回でした. 型の話をひたすらしてきました.

PARTAKE http://partake.in/events/9e460004-25c1-4c0b-b6a9-a2aa0443ab23

今日は余裕が無く会場に向かう電車の中でのみ予習した, という酷い状態で参加してきました. 9 章が型付き lambda 計算の話で, 今までの章の内容の組み合わせのような章だったのでなんとかその場で読めました. いつも 1 章分終わるかどうか, というペースなのですが, 今回は延長して終わらせました.

以下は kencoba さんのメモです. 話しいてる内容をその場でメモっていただいているので, 細かいとこまでメモしてあって助かります.

http://d.hatena.ne.jp/kencoba/20110409/1302330632

最後の Curry-Howard のあたりで話題に出した住井さんの記事というのは以下の IT Pro の記事です. なんと「型から実装が決まる」というめちゃくちゃ面白い話です.

http://itpro.nikkeibp.co.jp/article/COLUMN/20071005/283903/?ST=develop

言語処理系にはすごく強い興味があるのもあって読書会はすごく面白いのですが, それよりなにより型に引き寄せられる人に面白い (というかマニアックな) 人が多く, 濃いメンツが集まっていて楽しいです. 懇親会も行きたかったのですが事情により不参加. こっちの事情の方が大事ですし.

また来月にあるので, ゴールデンウィークもあることだし今度は予習をしていこうかと思います. 発表形式の方がスムーズなのは確かなんですよね. 他にも色々忙しいですが, そんなこと言わずに発表準備をしようと思います.

bloggart でのエラーとその解消

記事が書けない

1ヶ月前くらいのある時期から, このブログのブログエンジンである bloggart で新しい記事が書けない状態が続きました. 新しく記事を書こうとすると TaskAlreadyExistsError が起きてしまい処理が止まってしまっていました.

今までちゃんと書けてたのに何故? と調べてみると, 実はそのエラーは今までも出ることがあって, その都度握り潰していました. (この対応がいいかどうかはさておき) なぜそのエラーが出てくるようになったかと言うと, Google App Engine の API が変更されパッケージが変更されていました. 具体的には google.appengine.api.labs.taskqueue.TaskAlreadyExistsError から google.appengine.api.taskqueue.TaskAlreadyExistsError に変更になりました.

Google App Engine に不慣れで, なんでエラーが出るのか分からず解決に時間がかかってしまいました. ちゃんとエラーとソースを読めば良かったんですが, それでも API の変更までは想像が及びませんでした. Google App Engine SDK のバージョンアップがあった場合は気を付けないといけないですね.

Licenses