CakePHP2実践入門がでました

f:id:kaz_29:20121001100131j:plain

9/29にわたしも共著で執筆に参加した「CakePHP2 実践入門」が発売されました。
安藤さんを筆頭に錚々たるメンバーです。CakePHPを使っている方であれば、ブログや書籍などでほぼ100%お世話になったことがあるのではないかと思います。

執筆環境

今回の執筆環境を書こうと思って書き始めたところで、新原さんがすばらしいまとめをしてくれたので、そちらをご覧ください(^^;。

私は新原さんとは違うツールを使っていたのでそのツールを紹介します。

Mou

f:id:kaz_29:20121001095125p:plain

私はエディタ兼Markdownのプレビューの為に Mou を使いました。リリース当初はちょいちょいハングしたりしていたのですが、バージョンアップを重ねかなり動作も安定してきています。

f:id:kaz_29:20121001095145p:plain

左側が編集画面、右側がプレビュー画面になっていて、編集画面で編集するとプレビューも連動して更新されます。

テキストで原稿を書きながら、プレビューが出来るので、昨年別の書籍を執筆した時よりも全体をつかみやすくとても良かったと思います。

執筆のきっかけ

多分、安藤さんから「CakePHP2本の企画を進めるんだけど、執筆に興味ある人挙手!」というメールが来たのは去年の12月頃の話。

今年一月に技術評論社さんで編集者さんを交えて顔合わせをして以降の慣れない執筆作業は、締め切りが迫って来てドキドキしたり、校正のスケジュールと仕事の締め切りがかち合って寝られなかったり、執筆中に次々にアップデートが公開されて青くなったりとなかなかスリリングでした(^^;。

慣れない作業はなかなかに大変でしたが、執筆作業が(ほぼ)終わってAmazonに載ったり、実際に本が刷り上がって手にとった時はとても胸が熱くなりました(^^。

まとめ

今回の書籍の内容ですが、特に後半部分に関しては執筆に関わった私自身も色々な気づきをもらえたので、かなり濃い内容なのではないかと思います。初学者の方やCakePHP2系へのノウハウの移行をしたいユーザーだけでなく、「CakePHPは結構使いこなせているよ!」という方にもお勧めできる一冊になっていると思います。是非手に取って頂ければうれしいです。

CakePHP2 実践入門 (WEB+DB PRESS plus)

CakePHP2 実践入門 (WEB+DB PRESS plus)

最後に執筆陣がこの書籍について書いたブログ記事をまとめておきます。

とりは市川さんですね!期待してます(^^。

UITableViewの行削除でセクション数が減るとクラッシュする

久々のiPhoneアプリ開発ではまったのでメモ。

行を削除でセクションがなくなるような場合、deleteRowsAtIndexPathsで行を削除しただけでは以下のようなエラーでクラッシュします。


f:id:kaz_29:20120831071434p:plain

*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'

行の削除によりセクションにデータがなくなるような場合は以下の様にセクションも削除する必要がある様です。

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle 
                                            forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        [tableView beginUpdates];

        // self.tableData = NSMutableArray
        [[self.tableData getObject:[indexPath section]] removeObjectAtIndex:[indexPath row]];
        if ([[self.tableData getObject:[indexPath section]] count] == 0) {
            [self.tableData removeObjectAtIndex:[indexPath section]];
        }

        if ([self.tableData count] != [self.tableView numberOfSections]) {
            [self.tableData removeObjectAtIndex:[indexPath section]];
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:YES];
        }
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];

        [tableView endUpdates];
    }
}
  • 2012/8/31 10:20 サンプルコードに問題があったので微修正。

CakePHP2+PostgreSQLでGeoデータを簡単に扱う!?

@tkengoさんから引き続き CakePHP Advent Calendar 14日目の記事です。

深く考えず参加申し込みをしたらダブルヘッダーになってしまいヒーヒー言っているわたなべです(^^;

この記事はCakePHP2系の記事です。


明日にはこんなイベントも開催されるようで、最近は位置情報を扱う機会も多いのではないかと思います。

先月くらいに位置情報に関して色々試していて、CakePHPから扱う場合にいつもと同じように扱いたいなぁということでPostgres Datasourceを拡張してみたので解説したいと思います。

PostgreSQLで扱える位置情報の種類

PostgreSQLで扱える位置情報関連のデータ型には以下のようなものがあります。

型名 表現
point 平面における座標点
line 無限の直線
lseg 有限の線分
box 矩形
path 閉経路
path 開経路
polygon 多角形
circle

幾何データ型

今回は携帯での位置情報を簡単に扱えるようにという目標なのでこの中からデータ型としては 'point'型と'box'型のサポートをしました。

位置情報関連の演算子

下記のマニュアルページを見ていただければ分かる通り、たくさんの演算子がサポートされています。

幾何データ演算子

今回はこの中から以下の演算子をサポートを追加しました。

演算子 説明
@ 含む、または境界上
~= 同等か?
<-> 距離

スキーマ定義

今回の追加機能のテスト用に作成したFixtureは下記になります。

<?php
class PostgresGeoFixture extends CakeTestFixture {

/**
 * name property
 *
 * @var string 'PostgresGeo'
 */
	public $name = 'PostgresGeo';

/**
 * fields property
 *
 * @var array
 */
	public $fields = array(
		'id' => array('type' => 'integer', 'key' => 'primary'),
		'loc' => array('type' => 'point', 'null' => false),
		'rect' => array('type' => 'box', 'null' => false),
	);
}

point型の locとbox型の rect フィールドを作成しています。

使い方

データを保存する場合は、以下の様に座標データを配列形式で設定すればOKです。
box型の場合は左上の座標と、右下の座標を配列で渡します。

<?php

$data = array(
  'loc'	 => array(10.1,10.1),
  'rect' => array(array(10.1,10.2), array(100.1,100.2)),
);

$Model->create();
$Model->set($data);
$result = $Model->save();

特定の円の中に含まれているデータを検索する場合はこんな感じです。

<?php
// @ operator
// compare to circle
$conditions = array(
  'loc @' => array('circle' => array('point'=> array(10.1,10.1), 100)),
);
// order by distance
$order = array(
  'loc <-> point(10.1,10.1)'
);

$result = $model->find('all', array('conditions'=>$conditions, 'order'=>$order));

この例では中心座標 10.1,10.1、半径100の範囲内に含まれるデータが取得できます。また、<->演算子で並べ替えることで、中心座標に近い順に並べ替えることが可能です。

Postgresデータソースのテストを書いてあるのでそちらも見ていただけると、もう少しイメージが湧くかと思います。

誤算

当初この修正を始めたときは、PostgreSQLデータソース内部ですべて解決できそうな気がした(^^; ので、CakePHP2をforkして作業を始めたのですが、実際に作業を進めて見た結果、DboSource(データベース関連データソースの共通クラス)にも手を入れないと実現ができませんでした。

さすがにDatasource固有の演算子サポートのためにDboSourceに手を入れる修正はコアに取り込んでもらえないなぁと思い、今後この機能をプラグイン化できないか調査をしているところです。

実際に動くコードは、GitHubに上がっているのでもし興味がある方は試してみてください。結構便利だと思いますよ。

明日は @scriptwork さんです。よろしくお願いします!

zinniaでお手軽手書き文字認識

@haoyayoi さんから引き続き iOS Advent Calendar 14日目の記事です。

アプリ自体はまだ2本しか出していないわたなべです。
iOS Advent Calendar はそうそうたるメンバーがとても参考になる記事を書かれているのでいろいろ勉強させてもらってます(><)!
こんな私ですが、@k_katsumiさんに背中を押されたので、最近試している手書き文字認識エンジン zinniaについて書いてみます

zinnia ってなに?

zinnia は Taku Kudoさんが作成された「手書き文字認識エンジン」です。このエンジンに文字のストローク座標の連続データを渡すことで、高速に文字を認識することができます。確からしさ順にN個の結果を取得することができるので、変換候補を表示したりも出来ます。

iPhone上で動かすには...

@FLCLjp さんが作成されたサンプルが Githubで公開されているのでそれを見るのが一番だと思います。
実際に動かしてみると以下のようにしっかり認識できるはずです。


f:id:kaz_29:20111214124235p:image:w360

で、これだけだと全く中身がない話になってしまうので(^^; もう少し書きますよ〜。

認識率は...

zinniaのサイト上で配布されれいる 認識用モデルファイル(Zinnia-Tomoe) を使って試用した感じではかなり認識率は高いと思います。ただ画数の少ない文字はどうしても正しく認識してくれないケースが多かったです。まぁ、仕方が無いですね。

ですが、特定の文字種に限って(たとえば数字だけとか...)認識できればいいのであれば、自前で認識用モデルファイルを作ってしまえばかなり認識率を高めることはできそうです。

実際、私を含め身近な数人に数字のストロークを入力してもらい作成した認識用モデルファイルを使うと、ほぼ100%に近い確率で認識できました!

認識用モデルファイル

認識用モデルファイルはS式で記述された学習データを元に、zinnia付属のコマンドで作成します。公式ページにも記述がありますが実際の形式は以下のような形式です。

S式フォーマット

(character
 (value 認識したい文字)
 (width キャンバス幅)
 (height キャンバス高さ)
 (strokes
   ((0画目x 0画目y) ... (0画目x 0画目y))
   ((1画目x 0画目y) ... (1画目x 1画目y))
   ((2画目x 2画目y) ... (2画目x 2画目y))
   ...))


フォーマット自体はとてもシンプルなのですが、このデータを作るには実際に認識させるデバイス上で文字のストローク情報を集める必要があります。おそらくzinniaを使っている方はみんな何らかの文字収集ツールを書いてるんじゃないかなぁと思います。


ということで、自分用にiPhoneで動作するアプリを書いたので解説します。

手書きストローク収集ツール(TegakiStroke)

iPhone-Zinnia-TegakiStroke@GitHub


もともと自分用に収集アプリを書いていたのですが、不特定多数の人のストロークを集めたかったので、データをサーバーに上げる方式で作っていました。これだとお手軽に試してもらうわけにはいかないので、すべてのデータをローカルなsqlitedbに保存する形で作り直しました。テーブル構成は以下のようなとても簡単な作りになっているので、、付属のtemplate.dbを覗いてもらえればわかるかと思います。

モデル情報(models) => モデルに含まれる文字情報(characters) => 実際のストローク情報(strokes)


以下がschema構築用のsqlファイルです。

CREATE TABLE models (
id INTEGER PRIMARY KEY,
name TEXT,
created
);

CREATE TABLE characters (
id INTEGER PRIMARY KEY,
model_id INTEGER,
character TEXT,
created
);

CREATE TABLE strokes (
id INTEGER PRIMARY KEY,
character_id INTEGER,
strokes TEXT,
created
);

INSERT INTO models (name,created) values ('number', '2011/12/13');

INSERT INTO characters(model_id,character, created) values(1,'0','2011/12/13');
INSERT INTO characters(model_id,character, created) values(1,'1','2011/12/13');
... 以下略

実際の動作は...

まず入力するモデルを選んで...

f:id:kaz_29:20111214141228p:image:w360

「文字入力」ボタンを押して....

f:id:kaz_29:20111214141229p:image:w360


実際に文字を入力します....

f:id:kaz_29:20111214141230p:image:w360


登録されている文字の入力が終わると、文字一覧に戻ってくるので「S式書出し」ボタンを押せば完了です。

f:id:kaz_29:20111214141229p:image:w360


書きだしたデータは、Documentsフォルダに保存されていますのでiTunes ファイル共有か何かで取り出してください。


f:id:kaz_29:20111214141231p:image:w360


吐き出された、*.sファイルをzinnia付属の zinnia_learn にかければ実際に使えるモデルファイルが出来上がります。
またアプリ内部で使用している sqliteのファイルもDocumentsフォルダに保存してあるので、適宜モデルや文字を追加するなり、自前でstrokeデータを抜き出して加工するなり、いろいろできるのではないかと思います。

まとめ

zinniaを使うと非常に簡単に手書き文字認識を実装できます。実際のアプリで使うには色々と工夫が必要かと思いますが...。

ソースはGitHubに上げてありますので、試してみてください!
若干やっつけ感が漂っているところもありますが(^^; 、時間ができたら機能を追加していこうと思ってます。

明日は @hIDDEN_xv さんです!

PHP Matsuriに参加しよう!

色々ばったばったしているわたなべです。
このエントリーは、10/15-16に大阪で開催されるPHP Matsuriリレーブログエントリーです!

http://2011.phpmatsuri.net/:image=http://img.f.hatena.ne.jp/images/fotolife/k/kaz_29/20111002/20111002173256.gif

まだ若干の余裕はありますが、急がないと埋まってしまう可能性もあるので後悔したくない人は今すぐ申し込んでしまいましょう!

私は昨年のPHP Matsuriにも参加したのですが、私が感じたこうしたら楽しめた(はず)!という内容を書きたいと思います。

作るものをある程度考えておく

f:id:kaz_29:20101002093601j:image

当日は興味深いセッションやワークショップが盛りだくさんなので、以外にハックの時間がとれないかもしれません。当日作るもの/やる事をある程度考えて事前準備をしておくと良いと思います。開発環境も準備出来る方は事前に準備しておくのも良いと思いますが、期間中に使用可能なインスタンススポンサーさんが貸してくれるとの話もある様なので、環境構築も周りのみんなの構築方法とかを聞きながら色々試すのも面白いと思います。

食事タイムにも交流

f:id:kaz_29:20111003190735j:image
photo by @ichikaway

期間中は、参加者/ゲスト全員で食事をする機会が4回あります。この食事時間も絶好の交流のチャンスです。気になるゲストのそばに陣取るのもいいですね。また、気になる参加者やスタッフをポジションペーパーでチェックして一緒に食事をとるのも楽しいと思いますよ!

疲れたら休憩にして動き回る

f:id:kaz_29:20111003191052j:image
photo by @ichikaway

講演/ワークショップ/ハックに疲れたら、少し休憩にしてうろうろしてみると面白いと思います。昨年は深夜にいきなりゲーム大会が始まったり、ビール片手に海外ゲストと談笑する人、喫煙スペースで延々開発談義をしている方とかもいました。

遅い時間になるとあちこちで「プシュ!」とビールの空く音が....!お酒が飲める人も飲めない人もあちこちで会話に花が咲いていると思います。興味のありそうな話が聞こえたらがんがん捕まえて交流する事をお勧めします。

英語は怖くない!?

f:id:kaz_29:20101002205231j:image

英語は思っているほど怖くありません。中学生レベルの英語で十分コミュニケーションはとれます。別にとって食われる事はないので、海外ゲストにもガンガン話しかけてみましょう。世界が広がるはずです。

と、英語をしゃべれる人にいつも言われているので、私も今回はがんばろうと思います(^^;。

やった事を発表する

f:id:kaz_29:20111003194009j:image
photo by @ichikaway

2日目の午後は参加者それぞれの成果をLT形式で発表する時間になります。「自分が作ったものなんてたいした事無いし...」とか「まだ未完成だから...」とか色々あって躊躇する人も多いとおもいますがそんな人は、@shin1x1さんの勉強会を楽しむなら発表しよう!を読んでみましょう!ここに書かれている、

「君の当たり前に僕らは感嘆させられるんだ」

は本当にその通りだと思います。発表する事で広がるものが絶対にあります!すてきな商品もある様なので、是非!

まとめ

という事でつらつらと書いてきましたが、PHP Matsuriは楽しいので是非参加してみんなでハックして交流しましょう!という事です。さあ、皆さん申し込みましょう!

明日は、上でも紹介した@shin1x1さんです、よろしくお願いしますー!

candycaneをPostgreSQLにも対応させたい!

昨日の夜に社内用 redmine をアップデートしていたのですが、まだCakePHPもgitも覚えたての頃に、CakePHP開発合宿に参加して開発したのを思いだしたのか、急に candycane が気になったので、ちょっといじってみる事にしました。

まずは手始めに、手持ちのMacのPHP+MySQL環境にインストールしてみたのですが、まぁこれが超絶簡単。@yandoさんも書いていますが、本当に3分程度でインストールが完了してしまいました。


f:id:kaz_29:20110817232500p:image


いよいよPostgreSQLに対応する作業ですが、実際にやった作業は以下のような感じ。

  • MySQLの初期状態を元にCakePHPのschemaファイルを作成
  • 上のschemaファイルを使ってPostgreSQL上にテーブルを作成
  • MySQLのダンプファイルを元に初期データをインサート
  • pg_dumpでダンプしたものを整形して初期化用sqlを作成
  • インストーラのDB設定画面にDB選択フィールドを追加
  • インストーラにPostgreSQLの接続確認処理 database.phpに選択されたdriverを書き込む処理を追加
  • 選択されたドライバ毎に初期データ作成用sqlを切り替える処理を追加

とこんな感じです。途中、schema生成時にエラーが出てはまったのですがこれはcandycane開発当初にはまだリリースされていなかったPostgreSQL9.xに依存する問題だったので、CakePHP1.3.10CakePHP1.3.5で対応されたもの組み込んで対応しました。

以下が実際のインストーラのスクリーンショットです。

f:id:kaz_29:20110817235238p:image

インストール完了後に Administration -> informationをみるとこんな感じ。

f:id:kaz_29:20110817235239p:image

ひとまず、無事PostgreSQLで動作させる事ができました。

実際にはいくつかの機能で正常に動作しない部分や、テストが通らない所があるので今後ちょっとづつ手を入れていこうと思ってます。

ソースはgithubにあげてあります

電力使用量を表示するアプリを作りました

先週金曜日(4/8)、計画停電の「原則不実施」の発表日という絶妙のタイミング(^^; でしたが東京電力管内の電力使用量を表示する「電力グラフ」というアプリをリリースしました。

電力使用量を取得するAPIが続々リリースされ始めた3/24頃に、こんな事をつぶやいていたら@basukeにケツ叩かれたので作ってみました(^^;

グラフの描画は s7graphview を使わせてもらっています。また、通信関係の処理は three20 を使っています。
この2つのライブラリのおかげで比較的サクッと作れました。

f:id:kaz_29:20110411102352p:image

主な機能はこんな感じです。

  • 過去7日分の電力使用状況の表示
  • 計画停電の実施状況の閲覧(当日から3日間)
  • 電力/節電に関連する情報の表示
  • 電力/節電に関連するリンク集

使用している情報は下記のAPIを使用しています。

計画停電のスケジュールは東京電力の発表しているデータを元に独自で作成したデータを使っています。この情報はAmazon S3上においてあったりします。

原則的に計画停電は実施されない事になった様ですが、これから夏にかけて電力が不足する事は変わらないと思うので、節電のお供に使って頂ければと思います。

ダウンロードはこちら

*「電力グラフ」で使用している情報は、東京電力の発表に基づき情報を更新しておりますが、反映には時間差が生じます。 最新の情報は東京電力のサイト等でご確認ください。