VOYAGE GROUP エンジニアブログ

voyagegroup_techのブログ
VOYAGE GROUPエンジニアブログです。

【詳細図解】iPhoneの共通モジュールのベストプラクティス(その1)

こんにちは、 株式会社ジェネシックス の徐 廷(@TonnyXu)です。文章が長くなりますので、5回に分けてお届けします。

今回は、1回目となります。

その1

■ 共通プロジェクトを作る

その2

■ コンシューマPJを作る

■ コンシューマPJで共通プロジェクトを引用

その3

■ 引用する後コンシューマPJでの必須設定

その4

■ コンシューマPJを実行する

その5

■ さらに

・ 共通プロジェクトに単体テストを追加

・ オープンソースライブラリを作る

複数のiPhoneアプリを開発する場合、自分が書いたソースコードの中で共通性が高いコードを抽出して共有したくなると思います。特にSubversionなどのでソースコード管理を行っている場合は、共通モジュールのソースコードを分散させるのは大変だと思います。今日はジェネシックスの共通モジュールのベストプラクティスを紹介します。

 

まず、本文中の用語を簡単に説明します。
  • 共通モジュール :複数のプロジェクトに共通の機能
  • 共通プロジェクト :共通モジュールを管理しているプロジェクト
  • コンシューマプロジェクト/PJ :共通モジュールを使用するプロジェクト

さて、共通プロジェクトを作る目的と目標をまとめましょう。

目的
  • 共通モジュールを 管理し易くする ため
目標
  1. 任意のコンシューマプロジェクトで共通モジュールを使える
  2. 共通モジュールの更新はすべてのコンシューマプロジェクトに自動的に反映される
  3. 共通モジュールがSubversionなどのSCMで管理できる。
  4. 単体テストできる。

本文の最後にも書いていますが、この共通プロジェクトの作り方は、オープンソースのライブラリを作るときにも適用できます。

【サンプルコードをダウンロード】

本文で使用しているサンプルコードです。

私のMac OS X Snow Leopardの環境言語は英語に設定しています。画面キャプチャなどもすべて英語表記となっております。何卒ご了承ください。

■ 共通プロジェクトを作る

 

まず、共通モジュールのプロジェクトを作りましょう。Xcodeを開いて、File→New project...を選択すると、下記のような画面が出てきます。
new static library name
図1:共通モジュールのプロジェクトタイプ

 

図1でLibraryカテゴリののStatic Libraryを選択し、次の画面で名前を入力してください。

new static library name
図2:共通プロジェクトの名前

保存をすると、共通プロジェクトが図3のように出来上がります。

new static libaray project.

図3:出来上がった共通プロジェクト

例えば、現在実行しているデバイスがiPadかどうかを判断する共通メソッドを作りたい場合は、まず、新しいクラスを追加しましょう。

new class for static library
図4:新しいクラス

 

新しいクラスは「GCDevice」という名前にしました。ちなみに、GCは G enesix C ommonのという意味です。

new class name for static library
図5:クラスの名前

new class header for common

図6:クラスのヘッダー

図6のように、ヘッダーファイル中に、staticなメソッドを追加します。名前は「 isIPad 」,戻り値は BOOL です。

次はクラス「 UIDevice 」を使うために、「 UIKit.framwork 」をプロジェクトに追加します。

framework UIKit

図7:UIKit.frameworkを追加します。

次は .m ファイルに isIPad のソースコードを追加します。

 

.m file for common lib

図8:.mファイルの詳細

下記は図8のソースコードです。

GCDevice.m

//
//  GCDevice.m
//  Common
//
//  Created by Tonny Xu on 10/05/26.
//  Copyright 2010 genesix, Inc. All rights reserved.
//

#import "GCDevice.h" 
#import <UIKit/UIKit.h>

@implementation GCDevice

#ifndef UI_USER_INTERFACE_IDIOM
@interface UIDevice (ThingsIKnow)
- (int)userInterfaceIdiom;
@end
#define UI_USER_INTERFACE_IDIOM() ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone)
#define UIUserInterfaceIdiomPhone 0
#endif

+ (BOOL)isIPad
{
    static BOOL isPad = NO;
    static BOOL determined = NO;
    if (!determined) {
        isPad = (UI_USER_INTERFACE_IDIOM() != UIUserInterfaceIdiomPhone);
        determined = YES;
    }

    return isPad;
}

@end

これで共通プロジェクトcommonをビルドできるはずです。ビルドしてみましょう。

.m file and compile OK

図9:コンパイル成功

 

コンパイル成功したので、このライブラリを使えるようになりました。では、早速この共通モジュールを使用するコンシューマプロジェクトを作りましょう。

 

勉強会をしよう!

こんにちは。
ECナビの子会社PeXでエンジニアをしているの當銘(トウメ)といいます。
新卒2年目。プログラマー暦も2年に満たない情弱エンジニアです。

突然ですが、皆さんは勉強会に参加したことはありますか?
社内・社外、どちらの勉強会でもかまいません。

ECナビでも、社内外問わず活発的に勉強会を行なっています。
今回は社内勉強会にスポットを当て書いてみたいと思います。

■ECナビ内での勉強会

ECナビでは、主に以下のような社内勉強会を行なっています。

・SICP読書会
→週に2度、「計算機プログラムの構造と解釈(第二版)」をテキストとし、
毎回担当者が持ち回りで発表。
昨年・今年と新卒研修の一環としても行なわれている。
現在は進路のスピードが違うものを、5つ行なっています。

・春山セキュリティ塾
→システム本部の春山さんによるセキュリティ中心の勉強会。

・データマイニング勉強会
  →2、3ヶ月に1回くらいのペースで開催。

・LT(ライトニングトーク)
→社内バーajitoで(飲みながら)2ヶ月に1回くらいのペースで開催。
たまに社外の人やグループ会社の方も参加。

・面白便利ツール発表会
→自分が普段当たり前のように使っているツールやコマンドが
実は他の人からすると目からうろこなものかもしれない!
昼食の会話から生まれたゆるふわ勉強会。
開催は不定期。

・S-1グランプリ
→各事業部の現在やっていることやシステムの構成の情報共有会。

・カンファレンスなどのFB会      etc

他にも大小様々な勉強会が行なわれております。
僕が関わっているものでいうと、
主にプログラマー暦2年弱の若手のみの「Perl勉強会」に参加しています。

■Perl勉強会

ECナビではPHPを使用している部署が多いのですが、バッチ処理はPerlにしているということは少なくありません。

そんな中、同期がバッチ処理を書く機会が多くなったので「どうせならみんなで勉強しよう!」という些細な発言がきっかけでした。

内容としては「初めてのPerl」をテキストとして定時後に読み合わせをしつつ、あーだこーだと語ったり、
実際に書いたプログラムを見せ合う会で、実際のところ結構「ゆるふわな」勉強会だったりします。
業務に追われる中、1人で勉強するにはモチベーションを保つことが難しいこともあるが、仲間と一緒にならやれる。
そんな思いから始まった勉強会です。

また、この会には先輩エンジニアの方も飛び入りで参加されて、
僕ら新人だけではわからなかった内容や詳しい内容も話してくれるという嬉しいハプニングも起きました。
ECナビのエンジニアはこういう勉強会に参加するのが好きな方が多いようで、みなさん積極的に飛び入り参加してくれます。
そういうことも「社内勉強会」ならではなんじゃないかと。

■勉強会をやってみて

社内勉強会に参加していて良いと思うのは以下の点です。

・社内エンジニアの技術力・知識向上
・部署内外のコミュニケーションの活性化
・社内の人間ばかりなので、僕みたいな情弱エンジニアでも気軽に、積極的に参加可能。
・1人では学ぶのが難しいことが学べる

また、勉強会が1つ開催されることによって、連鎖的に勉強会が立ち上がることも稀ではありません。
これはエンジニアという職種に限らず、他の職種の方々の勉強会でもおなじことが言えるでしょう。

社員のスキル向上、コミュニケーションの活性化。
「社内勉強会」は参加するあなたと、あなたの会社に大きなメリットをもたらします。

みなさんは社内勉強会に参加していますか?
もし、社内に勉強会がないという方は、ご自分が中心となって開催してみるのもいいんじゃないでしょうか。

DWHで類似度計算

 こんにちは、ECナビ システム本部 システムソリューショングループの大竹(@tokosa)です。

ECナビではDWHのNetezzaを使用し、データマートを構築しております。

Netezzaに関しては、日本ネティーザのサイトをご覧下さい。

実際Netezzaの性能がどの位なのか?何が出来るのかをご紹介します。

Netezzaを使用して2つの集合の類似度を計る

2つの集合の類似度を計る方法としてTanimoto係数(Jaccard係数の拡張)があります。

式は下記の通り。

==================================================================
Tb = Nc/ (Na + Nb - Nc)
==================================================================
Tb:Tanimoto係数 (二値データ)
Na:Aのアイテム数 
Nb:Bのアイテム数 
Nc:共通集合

Tbは0~1の間で0に近ければ類似度が低く1に近づく程類似度が高くなります。

では、実際にDBで集計を行います。

テーブル構成

NETEZZA => d PUR_TEST

Attribute | Type | Modifier | Default Value -----------------+------------------------+----------+--------------- USER_ID | INTEGER | | ITEM_ID | INTEGER | | DATE | DATE | | distribute key (USER_ID) レコード数:50万 集計対象数(アイテム数):1000

テンポラリーテーブルは作成せず、自己結合でSQLを実行させます。

1.Nc=アイテム共通集合をもとめるSQL
  select m.ITEM_ID as MY_ITEM,o.ITEM_ID as OTHER_ITEM ,COUNT(distinct(o.USER_ID)) as match
  from PUR_TEST m INNER JOIN PUR_TEST o on m.ITEM_ID != o.ITEM_ID
  and m.USER_ID =o.USER_ID 
  group by m.ITEM_ID,o.ITEM_ID

2.Naのアイテム数
  select item_id,count(distinct(user_id)) NA from pur_test group by item_id

3.Nbのアイテム数
   select item_id,count(distinct(user_id)) NB from pur_test group by item_id

4.1~3の結果をTanimoto係数の公式へ。

 select MY_ITEM,NA,OTHER_ITEM,NB,NC,trunc(cast(NC as dec)/(NA+NB-NC),2) as T from (
   select m.ITEM_ID as MY_ITEM,o.ITEM_ID as OTHER_ITEM ,COUNT(distinct(o.USER_ID)) as NC
   from PUR_TEST m INNER JOIN PUR_TEST o on m.ITEM_ID != o.ITEM_ID
   and m.USER_ID =o.USER_ID 
   group by m.ITEM_ID,o.ITEM_ID
 ) ma,
 (select ITEM_ID,count(distinct(user_id)) NA from pur_test group by item_id) na,
 (select ITEM_ID,count(distinct(user_id)) NB from pur_test group by item_id) nb 
 WHERE 
 ma.MY_ITEM =na.ITEM_ID AND
 ma.OTHER_ITEM =nb.ITEM_ID 

単純に計算量はO(n^2)です。

アイテム数が1000位なら一瞬です。

実行時間================
real    0m6.680s
user    0m0.156s
sys     0m0.031s

アイテム数が10000超えると。。

実行時間================
real    29m53.769s
user    1m10.785s
sys     0m3.777s

まとめ

実際にはテンポラリテーブルを作成するべきです、アイテム毎のアイテム数(Na ,Nb) は先に集計しておくと良いでしょう。

Netzzaは自己結合も弱いのでこちらは別にするべきです。

今回はNetezzaの性能計る為、こんなSQLを書いています。

Netezzaにもstddev(標準偏差)、stddev_pop(母標準偏差)、variance(式の分散)、var_pop(母分散)などなど

解析関数が用意されています。協調フィルタリングの相関係数法もできますね。

記事検索
QRコード
QRコード