告知が遅くなりましたが、iPhoneアプリの第二弾をリリースしました。その名も「Calculate10」。連続して表示される10個の数字を計算していくだけのアプリです。
単純だけど、なかなか難しいですよ。まぁ経理をやっている友人にハードモードを瞬殺されましたが。w
日本人はそろばんやってるひとが多いので、そういう人には簡単みたいです。
現在、すでに「スーパーハード」と「ベリーベリーハード」なモードの追加中です。
ぜひお試しください。
告知が遅くなりましたが、iPhoneアプリの第二弾をリリースしました。その名も「Calculate10」。連続して表示される10個の数字を計算していくだけのアプリです。
単純だけど、なかなか難しいですよ。まぁ経理をやっている友人にハードモードを瞬殺されましたが。w
日本人はそろばんやってるひとが多いので、そういう人には簡単みたいです。
現在、すでに「スーパーハード」と「ベリーベリーハード」なモードの追加中です。
ぜひお試しください。
先日のOpenCVを利用したARコンテンツで書いたアフロジェネレータを公開してみようかと。
先にお伝えしておきます。精度はぜんぜんまだまだです。顔の位置判定にしくじることも結構多いです。が、まずは実績として公開してしまおうと思いました。
「そんなもん公開すんなボケ」という方、ごめんなさい。
使い方は簡単。afro-gen[at]tt-house.comに写真を添付してメールするだけです。アフロヘアーになった写真が返信されてきます。(さすがにスパムが怖いのでアットマークは伏せました。[at]をアットマークに替えてください。)
ごめんなさい、現在公開停止中です。
左側がアフロ後、右側がアフロ前。これは手での修正は入れてません。100%ツールによるものです。写真によっては結構うまくいくんですよねー。(オバマ大統領の写真、まずいかなぁ。FBIとか家に来たらどうしよう)
あ、ちなみに送っていただいたメールアドレスは保存してません。ので、後から広告メールが配信されるとかスパムが配信されるとかはないです。Gmailでしかテストしてないので、クライアントによっては件名が化けるかもしれません。あと、本文にはなにもないメールで、写真だけが添付されています。
何種類かヘアスタイル用意しておいてルーレット、っていうのも面白いかもですね。
もしお試しいただけて、さらに気が向いたら感想なんかいただけると非常にうれしいです。ただの罵詈雑言だと泣き崩れるのでできれば勘弁してください。
OpenCVというのは「Open Computer Vision Library」の略でして、画像の変換だったり、ヒストグラムの抽出だったり、画像の判定だったりができちゃうもので、インテルが開発したOSSです。
で、ヒストグラムの抽出ができると、「色合いが似た画像」を抽出できます。
画像の判定は学習させることができるので、風船が写った写真1,500枚と写ってない写真1,500枚で「風船」というものを抽出するパターンを学習させて、学習結果から写真の中から「風船がある場所の座標、大きさ」を抽出することができるんです。
風船の場所、大きささえわかれば、その風船にフェイスマークをプログラムで書き足すこととかは可能ですよね。
世の中に出回ってるARコンテンツって、こういう技術の活用なんじゃないかなと。
ハセテツはOpenCVを使って顔の位置を判定、事前に用意しておいたアフロヘアーの画像をかぶせることに成功したのであります。つまり、アフロジェネレータ。w
メールで自分の写真を添付するとアフロになって返ってくる。アフロヘアーな自分。
別にアフロヘアーになりたかったわけではないんです。これができたということは、美容院向けのARコンテンツができる、ちゅーことなんです。ホットペッパーにでも営業しようかな。
さらに、リアル着せ替え人形も可能ですよね。自分の写真使っていろんな服着てみるの。フランス王朝風だったり、十二単だったり、現実では着ることのできない試着が可能です。楽天にでも営業しようかな。
なんて、いろいろとやりたい思いだけがつのる今日この頃でした。アフロジェネレータはもうちっとクオリティを上げてから公開しよう思います。
以前のエントリーで集計クエリを利用する方法を説明しましたが、それだとDatetimeのフィールドを「年月」ごとに、っていう集計はできませんでした。購買履歴データを月別に件数集計したいときなんかは非常に困るんですよね。ので、それを解決する方法です。
select_column = {“d_column”: ”DATE_FORMAT(pub_date, ‘%%Y%%m’)”}_list = PurchaseRecord.objects.extra(select=select_column)
_list = _list.values(“d_column”).annotate(cnt=Count(‘id’))
上記はMySQLを利用しているケースの書き方です。
あ、横長になると見難いから2行に分けただけで、1行で大丈夫ですからね。
「ORマッパー使ってるのにデータベースに依存ってなによ」
な感じではありますが、extraを使っている部分は直接クエリが流れるみたいですね。
つまり、「DATE_FORMAT(pub_date, ‘%%Y%%m’)」の部分は
select *,DATE_FORMAT(pub_date, ‘%Y%m’) as d_column
from app_purchaserecord
といった風に、追加されるのです。で、追加されたカラムを使って集計、という流れですね。うっかりミスりやすいのが「%」を二つにする点でしょうか。
あと、データベースを変えたら「select_column~」の部分に修正が必要です。使用するデータベースに依存した書き方になります。ここは要注意ですね。
例えば組織図なんかのmodelを構築する際に、「属する部門」を表現するには再帰的なリレーションを使うことになると思います。「部門が属する部門」ですね。
class Div(models.Model):
name = models.CharField(max_length=100)
upper = models.ForeignKey(Div)
だと、syncdbの時に「Divなんてありません」と怒られてしまいます。そりゃそうだ。
ので、
class Div(models.Model):
name = models.CharField(max_length=100)
upper = models.ForeignKey(‘self’)
と書きます。
Python2.5、Django1.1.1でのお話でした。
DjangoでMySQLを利用する場合、初期状態だとMyISAMでテーブルが作成されます。まぁ後からalterすればよい話ではあるのですが、なんかそれだと違うかなぁと。
一昔前はInnoDBはMyISAMほどパフォーマンスが優れず、更新系のテーブルと参照系のテーブルでストレージエンジンを使い分けたものですが、今はストレージエンジンによるパフォーマンスの差も少ないため、行レベルロックができるInnoDBを積極的に採用するケースが増えてるみたいですね。まぁ数千万行をレコードから数ミリ秒でレスポンスを返さないといけないケースとかではどうなるのかわかりませんが。
DATABASE_OPTIONS = {“init_command”: “SET storage_engine=INNODB”,}
settings.pyに上記を記載するだけでsyncdbするときにInnoDBでテーブル作成してくれます。が、この記述はテーブル作成が終わって運用にはいったら削除するように、とのことです。
MySQLとの接続が確立された後にわざわざストレージエンジンを指定するコマンドを送っているっぽいので、普段は無駄な処理が発生しちゃうっていうことなんですかね。
NSString* _str = @”hoge”;if([_str isEqualToString:@"hoge"]){NSLog(@”match!”);}
PHPではprint_rでArrayの内容を出力できますが、smartyの場合どうしたらよいものかと。まぁループして書き出せばよいのですが、それは面倒だなと。
{$array|@debug_print_var}
これで出力できます。簡単ですね。
最近ものすごく久しぶりにPHPを書いていますが、Array関連のメソッドが非常に豊富で、便利だなぁと。
やっと初めてのiPhoneアプリをリリースすることができました。
iPhoneアプリが作りたくてmac買ったのにiPhoneの母艦としてしか使わずに早一年。実際の開発期間は一ヶ月以下という情けないだらしなさです。申し訳ない。
単純なパズルゲームです。3秒間の間にパネルの場所覚えてめくっていくだけ。ノーマルモードだと1から順番に9までめくっていきます。ハードモードの場合はめくる順番をランダムに指定されます。ハセテツはハードモードをクリアしたことがありません。w
リリースしてから24時間程度ですが、アメリカですでにレビューを書いていただけました。2件あって、両方とも五つ星!最高にうれしいです。開発屋にとって、こういうのが最高の報酬なんだろうなと思う瞬間です。
「It’s a great memory game for all ages!」
「Very simple, but it’s a nice memory exerciser.」
感涙です。
このまま勢いに乗って調子に乗って、次のアプリ開発に着手します。次はタスク管理アプリ。タスク管理はシンプルじゃないと意味がないんですよ。偉い人にはそれがわからんのです。
OAuthを使えるようになっておけば今後いろいろなマッシュアップに便利だろうと思い、試してみました。RoRで書いたのは、最近ご無沙汰過ぎてあまりに覚えてなかったのでリハビリを兼ねたわけです。
class TwitterAuth
require ‘oauth’def self.consumer
OAuth::Consumer.new(
[Consumer key],
[Consumer secret],
:site => “http://api.twitter.com”
)end
def self.request_token(_token, _secret)
OAuth::RequestToken.new(
consumer,
_token,
_secret
)end
def self.access_token(_token, _secret)
OAuth::AccessToken.new(
consumer,
_token,
_secret
)end
end
まずは上記のクラスを作成。OAuth関連の処理はこっちにやらせます。で、次がコントローラー。
require ‘rubytter’
class AuthController < ApplicationController
def index
request_token = TwitterAuth.consumer.get_request_token(:oauth_callback => “http://#{request.host_with_port}/auth/callback”)
session[:request_token] = request_token
redirect_to request_token.authorize_urlend
def callback
_token = session[:request_token]
request_token = TwitterAuth.request_token(_token.token, _token.secret)
access_token = request_token.get_access_token(
{},
:oauth_token => params[:oauth_token],
:oauth_verifier => params[:oauth_verifier]
)
session[:request_token]=nil
_account = {
:user_id => access_token.params[:user_id],
:token => access_token.token,
:secret => access_token.secret
}
session[:account] = _account
redirect_to :action => “timeline”end
def timeline
_account = session[:account]
token = TwitterAuth.access_token(_account[:token] , _account[:secret])
_twitter = OAuthRubytter.new(token)
@user_timeline = _twitter.user_timeline(_account[:user_id],:count => 100)end
end
def timelineが自分のタイムラインを取ってくるところで、「:count=>100」と指定しているのは「新着100件取ってきて」っていうことです。ここを指定しないでおくと規定値では20件取得してくれます。def callbackでセッションに入れたuser_id、token、secretをデータベース等に保存しておけば次回以降はこれらだけで認証とツイートの取得ができます(というか認証自体はtokenとsecretだけでOK)。
Twitterのアプリケーション登録申請で登録する際、コールバックURLを指定しないとWebアプリケーションとして登録されません。「開発中だからURLなんて決まってないよ」っていうケースでも、適当なURLを登録しておいてください。どうせ実際のコールバックURLはRubyのスクリプトで指定しなおしています。ハセテツはここに気が付かず、そこそこの時間を浪費しました。
で、タイムラインを表示するviewは
<ul>
<% for item in @user_timeline do -%>
<li><%= item.text %></li>
<% end -%>
</ul>
こんな感じです。