2015-12-20

MakeAppIcon -- アイコンとリードのジェネレーター

iOS アプリを作るとき、スクリーンのサイズと分解能ごとにアイコンを用意する必要がある。画像の扱いに長けているわけではないし、そもそも面倒な作業である。

MakeAppIcon というウェブサービスを使った。1024x1024 の画像をアップロードすると、iOS と Android のアプリ用アイコンが生成される。iPad Pro 用のアイコンがなかったけれど、1つくらい手動で作るのは苦にならない。

できあがったアイコンセットは、ウェブでダウンロードするのではなくて、メールで受け取る。

MakeAppIcon 側から見ると、

  • iOS/Android のアプリアイコンが必要で、
  • 自力でアイコンを作るのをだるがり、
  • そのための有料ツールを使わない

という特性を持つ人のメールアドレスを集められるということだ。なるほどなぁ。

2015-12-13

多重度・本番・流星 〜 テレビ連動ウェブサービスの勘所

欲しいものを手に入れたり、何かを成し遂げるための心構えや方法論というのがあって、自己啓発書やセミナーで紹介される。何年も前に参加したイベントが、ちょっと意識高めで、そこでも紹介されていた。

「流星理論というのがあってだな」
「何すか、それ?」
「流れ星を見たら、願い事を3回となえるんだ。すると願いが叶う」
「ちょw」
「笑ったね?流れ星が突然見えたとき、とっさに3回も言えるってことは、常にそのことを考えてるってことだよ」

いま考えていることは、成果になる可能性がある。であるならば、考えていることが、誰かに某かの足しなるかも知れない。このところ、テレビ番組と連動するウェブサービスの、要件定義について考えている。

以下は、これまでの経験で、おおざっぱに個人的に認識している課題と解決策の案だ。特定の放送局、制作会社、番組の話ではない。

個数が決まらない


「Facebook Messenger に、いいねスタンプあるじゃないすか」
「ありますね」
「いつからか、長押しすると巨大化するようになりましたね」

あるオブジェクトに関連する、別のオブジェクトの個数のカテゴリーとして、0個か1個、必ず1個、0個以上、1個以上などがある。特に「必ず1個」というのは設計上/実装上、強めの制約条件になるので、チューニングに活用できる。

業務系のアプリケーションでは、目的的に多重度の決定がなされる気がする。顧客管理アプリケーションにおいて、顧客の電話番号をいくつ登録できるのかは、そのアプリケーションで解決したい問題と深く連動しそうだ。

たとえば「ここは Facebook のいいね!と同じ」と言われ、問題ドメインにおけるモデルも Facebook のいいね、と同じだと考えてたとしよう。2週間後、連打でいいねのアイコンが大きくなる、いいね数がポイントとして与えられる、しかも、時間がたったらポイントが消えていく、といったクリエイティブなアイデアが浮上する。

この種の要件は発見的に決まりがちだ。やってみたら、面白かった的な演出要素である。もちろん、演出は問題を解決する手段だけれど、顧客名簿の電話番号と違い、いいねだけを切り出して要件定義をしにくいため、プロセスの構造が少し違う。関わったことはないのだけれど、ゲームも同じような構造がありそうな気がする。

コードシンプリシティでは「未来を予測せずに、未来に備える」ことを提案している。ちょっとした切れ目を入れておくのだ。API が返すデータと、データベース上のデータをガチガチに対応づけないようにする。いいねの数は、内部で get_likes() 関数を経由して取得するとか、getter/setter にしておくとか、そういう基本的なことだ。


Rails のアクティブレコードは楽ちんだけれど、この手の届く距離にデータを置いておくアプローチだけでは、変更対応がしにくくなるのだ。



稼働中の本番環境でテスト


「もう1回」
「だめですよ。もう勝負決まりましたよ」
「さっきのは練習。次が本番」

稼働中の本番サーバーで、副作用のあるリハーサルを要求されることがある。何を言っているか分からないと思うが、私には分かる。本番環境を使うことの意味が、番組制作とウェブサービス開発では異なるのだ。

テレビ局のスタジオから生放送することを考えよう。予算とスケジュールが許せば、本番とまったく同じ物理リソースで、事前にリハーサルができる。セット、カメラ、音響、照明すべてに、本番と同じリソースを使うことは物理的に可能だ。難しいのは、出演者のスケジュールの都合で遅れたり、トイレが我慢できなかったりで、時間がずれるとかの対処だろうか。

スタジオに併設されているサブ・コントロール・ルームでは、本番時もリハーサル時も各カメラからの映像(と、必要であれば録画した映像)がたくさんのモニタに映し出され、ディレクターがどの映像を使うかを指示/選択できる。サブ・コントロール・ルームの出力は、マスター・コントロール・ルームで送信所(東京の地上波ならスカイツリーとか)に出すように切り替えない限り、視聴者が知覚できる副作用は発生しない。

ここに番組宣伝なるものが、カジュアルに提案される。もちろん、いくら宣伝をしたとしても、番組コンテンツの視聴という副作用は発生しない。

ところが「番組宣伝期間中、事前登録をしたユーザーに10ポイントあげる」となると、ユーザーとインタラクションが発生したウェブサービスに、外部から知覚できる副作用が発生する。やっかいである。

リハーサルに開発サーバーを使うと「俺、事前登録したのに、10ポイント入ってないけど」という声があがるのは楽なほうだ。2夜連続放送の2日目のリハーサルで「昨日ゲットしはたはずの牛丼クーポンがなくなってるぞ。大丈夫なの?」とかなるとアレだ。

唐突に聞かされるとやっかいだけれど、事前に分かっていれば対応可能な要件ではある。ひとつの解決策は、サービスの機能として、本番モードとリハーサルモードを用意しておくというものだ。

本番/リハーサルでAPIに渡すパラメータを変更する、リハーサルモードでは過去の本番データを参照するが、未来のデータはリハーサル用の領域に書き込むなどの機能を実装すればよい。あるいはデータが小さければ、スナップショットをとってリストアする処理を、しょっちゅう行うものとして作ってもよい。

おわりに


以上、最近考えていたことを、書き出した。

今年の年末の仕事を請けたときには、放送日が確定していなかったので、参加申し込みをしなかった忘年会がある。結局、放送日と忘年会の日程はぶつからず、惜しいことをした。飲み会や、トライアスロン/マラソンレースのキャンセルに気をもむのが嫌になった、というのも前の仕事を辞めた理由のひとつだったことを思い出した。

「カネカネカネ」
「何すか、急に?」
「いや、ちょうどあのへんに、流れ星…」 


※ 縛り
・題名:「星」を含むこと。(例:「星の王子さま」「きらきら星」など)
・書き出し:書き出しをひらがなにしたとき「ほし」と表記できること。(例:「星空」「干し芋」「保守」など)
・文中に以下の3つの縛りワードを含むこと。
  縛りワード1:「この手の届く距離」
  縛りワード2:「我慢できなかった」
  縛りワード3:「牛」
・結び:「星」で終わる。ただし、句点(。)、疑問符(?)、三点リーダ(…)、その他の文章記号をつけてもOK。

2015-12-05

GPS 誤差の距離のずれを、移動平均で減らす

GPS の電波を拾いにくい市街地で測定した経緯度を、地図上にマッピングしていくと、けっこうずれている。


「けっこう」ってどのくらいだよ、っていう話ではあるけれど。ランニングの記録なので、ばっちりの位置が欲しいわけではない。けれど、このくらいずれると、距離にして 3-5%ずれる。1km あたり 7分ペースで走っている場合、距離が 3% ずれると、1km あたり 6分48秒で走っていることになる。

1km あたり12秒の誤差が、42km 積み重なると、8分半になる。地味に気になる。

念の為に書いておくと、マラソンレースにおける距離は、路肩には30cmぐらいまで迫るのを限度として、最短パスで測られるとかだ。なので、多くのランナーは最短コースを走れないので、GPS の測定誤差が完全にゼロであっても、42.195km よりも長めに走ることになる。閑話休題。

GPSの誤差は、高周波成分をなくせばいいんだろうなぁと思った。緯度と経度を、測定ポイントではなくて、移動平均を扱えばよいだろう。

やってみた結果、時間にして5秒、距離にして10m程度で移動平均をとると、距離の誤差が1%くらいになる。ちなみに iPhone 5 。これ以上、平均を算出するポイント数を多くすると、コーナーがなまりすぎる。




2015-12-02

iOS アプリ全体で navigation の見栄えを変更する UINavigationBar.appearance()

iOS の navigation という UI コンポーネントがある。設定を深入りしていく用途なんかに使う。しかも、ストーリーボードで深入りする方向に画面遷移を定義すると、戻っていく方向の遷移は「< Back」ってラベルまでつけて、自動的に実装してくれて便利。

アプリ全体で、この文字色をカスタマイズするには、AppDelegate.swift に以下のようなコードを書く。

class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let color = UIColor(red: 113/255.0, green: 61/255.0, blue: 150/255.0, alpha: 1)
        UINavigationBar.appearance().tintColor = color
        UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : color]
        return true
    }
    ...
}

tintColor は左右にある「<Back」とかの色、titleTextAttributes は上部中央のラベルの見栄えを指定する。

各画面でこのへんの文字を outlet として参照し、パラメータを変更しても、画面には反映されない。おそらく一旦描画したあとは、参照しないのだろう。

このへんの文字は UILabel のサブクラスっぽいので、UILabel で入れ替えると、見栄えが反映されるらしい。ただ、自動的に追加される「< Back」はデフォルトのままになってしまう。頑張って参照しようと思えばできるのかも。


じゃあナビゲーションをサブクラスにしようかな、という誘惑を思いとどまり、丁寧にググったら、上記のAppDelegate に書いておく方法が見つかった。 

2015-11-22

オブジェクト指向UX、というアプローチ

オブジェクト指向UXという記事を見つけた。原文は Object-Oriented UX 、和訳がオブジェクト指向UX である。

この記事では UXデザインのときに、まず最初に、ユーザーのメンタルモデルを、オブジェクト指向的に分析・定義することを、提案してる。このアプローチを、OOUXアプローチと呼ぼう。

オブジェクト指向やUXの意味は、人によって地味に異なるので、OOUX という言葉は誤解を生むのかも知れない。

要件(と呼ばれるウィッシュリスト)から、ソフトウェアの仕様を定義する立場で仕事を請けているんだけれど、このアプローチは有効だと思った。

[エンジニアは]ワイヤフレームやプロトタイプを見た時に、デザインをリバースエンジニアリングしてオブジェクトを抽出します。そして彼らは、「オブジェクトXはオブジェクトYとどのように通信するのか。オブジェクトAは複数のオブジェクトBで構成されていのか。オブジェクトの属性は何か。このクラスのオブジェクトはあのクラスのオブジェクトを継承するのか。」と思うでしょう。
ユーザのメンタルモデルを模倣するオブジェクトを定義することで、チームのコミュニケーションの土台となります。共通言語を手に入れられるのです。

ソフトウェアが対象にするものが、技術的なレイヤーから見て高ければ高いほど、この種の作業は必要になる。OOUX は、このための共通言語の表記の仕方とアプローチの提案なのだ。

脱 UML


似たようなアプローチとして、ドメイン駆動設計がある。オブジェクト指向的に問題ドメインをとらえることで、要件が分かるしコミュニケーションとれる、という考え方だ。ドメイン駆動設計では UML っぽい図をつかって表記する。これは悪くはないんだけれど、うまく伝わらない感がある。記号にルールがあって説明が必要になるし、後述するけど multiplicity がうまくイメージしてもらえないときがある。

OOUX のアプローチ


手順としては、まず要件のリストのようなものから、オブジェクトを抽出する。たいていは名詞がオブジェクトになるんだけれど、暗黙に想定しているオブジェクトがあったりする。

次に、オブジェクトの属性を挙げていく。さらに、他のオブジェクトを参照するのであれば、それを書いておく。これらを優先順位付けしろ、話はそれからだ、という手順だ。

メソッドやメッセージのやりとりは、ここでは定義しないようだ。これは欲しいなぁと思うので、今後自分が使うときには、なんか記載するようにするかも知れない。

さて、このとき UML を使わない。


  • レシピ
    • 材料
    • 材料
    • 材用
    • ...
    • 手順

  • 材料
    • 名前
    • 説明


みたいに書く。

レシピには1以上の材料が必要だろうから、1..* とかって矢印を引きたくなるんだけど、そうしない。

本当はUMLとやってることは同じだ。けど、1..* よりも具体的に材料、材料、材料、...と書いておくほうがイメージが湧く。

設計するにあたって、あるいは、いざ実装し始めてから、以下の様な会話をして泣いたことが何度もある。

「ここって複数なんですか?」
「ほとんどは、1つしかないよ」
「3つっていうのは絶対にない?」
「たまにある」
「それは表示する必要がある?」
「もちろん」
「100個の場合も?」
「まあね。でも、ほとんどは1つだから、気にしなくていいよ。」

気にしますね。とっても、気にします。たとえ1ケースであっても、99999オブジェクトを参照する可能性があるなら、ちと考えたくなるものです。

SNS を使うようなのは、これがしょっちゅうある。ほとんどのユーザーのフォロワーは100人くらいで収まるけど、たとえば @takapon_jp には 14万人のフォロワーがいる。

UML の 1..* と書いてあるよりも、


  • レシピ
    • 材料
    • 材料
    • 材料
    • ... 最大1000 ...
    • 手順


のほうが、UMLに馴染みがない人にも、可視化できるというわけだ。

実装がオブジェクトになるかどうかは、また別の話。RDB で管理するとか、KVS とかは、今は別の話。開発の工数や、成果物の効果によって、つまり費用対効果を考えて、10個までに制限するとかいう議論はあるけど、今は、その前の話をしている。

発注側が意識しているかどうか別にして、現時点の想定では上限の無い 1..* が、まずは要件の草稿になっていることが明らかになるのだ。

さっそく使ってみた


マーケットプレース(楽天とかね)みたいなのを考えることがあった。このとき店舗オブジェクトを考える。この店舗にいくつか種類があって、abstract 店舗から、concrete 店舗を4種類派生させるような感じだった。けど、UMLにせずに、

通販店舗、デジタル商材店舗、...みたいにあえて、コピペで書いていった。そうしたら、どうもビジネス主体(会社とか)が、複数の店舗を持つことができて、かつ、ビジネス主体ごとに売上を管理する必要がある、みたいなことが明らかになった。最初のウィッシュリストには、どこにもそんなことは書かれていない。

1年ほど前に、似たような状況でUMLを使って説明し、ほんとにこういうの要らないの?と確認したときた時には、完全にスルーされた。あとから会社単位の売上管理が必要だと言い始める、という、だるい展開だった。

1年前と先週の違いは、図の描き方だけではないので、必ずしもOOUXのアプローチの優位性を示さない。けれど、よさそう、という印象を持った。機会があれば、かつ適切そうであれば、今後もこのアプローチを使っていこうと思う。

OOUX が目指していないであろうこと


原文ページのコメント欄や、SNS での言及をみていると、OOUX のスコープを把握できない人がいるように見える。

前提として、この記事は、同じ種類のコンテンツが大量にあるような、ウェブサイトの見え方/体験の設計という意味で、UX デザインという言葉を使っている。選挙(選挙区ごとに結果が出ますね)、レシピ、DIY とか。この種のウェブサイトのコンテンツでは、クラスとインスタンス、という考え方が比較的あてはめやすい。

20年ほどの昔、オブジェクト指向で要求を分析し、オブジェクト指向で設計し、オブジェクト指向で実装すると、分析・設計・実装で共通のオブジェクトを使える、という夢を見ていたことがありました。が、実際には、そうはいかない。

OOUX もドメイン駆動開発も、メンタルモデルをオブジェクトにマッピングしましょう、という考え方だ。決して、いきなり実装しようとはしていない、と私は解釈している。実装するときのモデルとは大きく異なることがあるだろう。

さらに、単純にマッピングできないこともあると思う。当初は想定さえしていなかったような、暗黙のコンセプトが、オブジェクトとして浮き彫りになることもある。

「それは 0以上なのか、1個なのか、N個なのか?」が自分には分からないが、知らなければならないとき、OOUXで紹介された記述の仕方が使えるのだ。

2015-11-16

カレンダーアプリに JavaScript for Automation でアクセスすると遅い

JavaScript for Automation を使って、OS X の Calendar アプリにアクセスするコードを書いているのだけれど、期待より遅い。

var event = Application("Calendar").calendars[0].events[0];
event.summary();

1行目で、カレンダーの予定を取得している。これは、一瞬で終わる。

2行目では、予定の件名を取得している。.summary は参照だけしていて、値であるところの文字列はまだ分からない。summary() で、Calendar アプリと通信をして取得する。これが30秒くらいかかる。

今回は、カレンダーから、どの仕事に何時間使ったかを抽出しようとしている。カレンダーアプリに直接アクセスせずに、ical フォーマットのファイルを直接読み込んで処理することにした。

2015-11-08

OS X の JavaScript for Automation で、外部ライブラリを読み込む

OS X Yosemite 以降オートメーションのスクリプトをApple Script ではなくてJavaScript でも書けるようになった JavaScript for Automation または JXA と呼ぶらしい

単純な自動化だとシェルスクリプトなり Python なりで書けばいいんだけどアプリケーションと通信するときにはオートメーションを使えると便利だたとえばカレンダーアプリや iTunes の API にアクセスするようなとき

今回、JXA で日付文字列のパースやフォーマットがしたくなった。Node.js なんかだと、moment.js なるライブラリがある。

JXA で外部ライブラリを取り込むには、いくつかやりかたがあるらしいけれど、browserify を使うことにした。

手順


まず、browserify と、取り込むライブラリをインストールする。

npm install -g browserify
npm install moment

moment.js を使うコードを書く

// main.js
var moment = require("moment");
console.log(moment().format('MMMM Do YYYY, h:mm:ss a'));
browserify を使って出力したコードを、JXA 環境で実行する。

$ (echo 'window = this;'; browserify main.js; echo ';ObjC.import("stdlib");$.exit(0)') | osascript -l JavaScript
2015-11-08T16:26:55+09:00

実行コードをファイル保存


エラーが出たりすると、どの行だよ!ってなるので、browserify の出力をファイルにする。Makefile で。cake や gulp じゃなくてすみません。

bundle.js: *.js
    (echo 'window = this;'; browserify main.js; echo ';ObjC.import("stdlib");$$.exit(0)') > bundle.js

run: bundle.js
    osascript -l JavaScript bundle.js

JXA 環境特有の調整


Node.js と JXA との環境の違いを吸収するため、 browserify の出力前後に、数行追加してある。

JXA には window がない。ただし、this でグローバルなオブジェクトにアクセスできる。window = this することで、window オブジェクトが使える風にする。今回のスクリプトでは不要。

browserify で生成した関数を実行すると最後に評価された式の値がプリントされる結果を標準出力に出してパイプでつなぐような用途だと困る

ObjC.import("stdlib");
で、なんかライブラリを読み込む。らしい。ObjC.foo または $.foo で、読み込んだ関数にアクセスできる。というわけで、
$.exit(0);
して、何も表示させずに終了している。

2015-10-31

バックグラウンドの Location update で、local notification を出す iOS アプリ

移動中に、地理的な条件によって、ユーザーに指示をだす iOS アプリを作ろとうしている。

地理的な位置を管理する CoreLocation サービスは、バックグラウンドでも動き続けるので、これを使うことにした。いろいろ情報があったけれど、集約してひとつのアプリとして動かすのに時間がかかったのでメモしておく。


  • XCode Version 7.1 (7B91b) on OS X El Capitan 10.11.1
  • Xcode で File → New → Project → iOS Application → Single View Application
  • CoreLocation framework をプロジェクトに追加
  • Background の "Location updates" を有効にする
  • info.plist に NSLocationAlwaysUsageDescription キーを追加。値はユーザーに許可を求めるときの文字列。
  • この例では ViewController.swift には触らない。けれど、以下のコードを ViewController クラスに実装しても動く。
  • AppDelegate.swift を以下のように編集する

import UIKit
import CoreLocation

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate {
    var window: UIWindow?
    lazy var locationManager: CLLocationManager! = {
        let manager = CLLocationManager()
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.pausesLocationUpdatesAutomatically = false
        manager.allowBackgroundLocationupdates = true
        manager.delegate = self
        manager.requestAlwaysAuthorization()
        return manager
    }()

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        let settings = UIUserNotificationSettings(forTypes: [.Alert], categories: nil)
        UIApplication.sharedApplication().registerUserNotificationSettings(settings)
        locationManager.startUpdatingLocation()
        return true
    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let cond = true  // 何か条件判定をいれる。常に true だと通知しまくるので注意。
        if cond == true {
            let notification = UILocalNotification()
            notification.alertBody = "Hello"
            UIApplication.sharedApplication().presentLocalNotificationNow(notification)
        }
    }
    // 他のメソッドはそのまま触らない
}

allowBackgroundLocationupdates を true にすることに気づかなくて長い時間を費やしてしまったデフォルトの false のときアプリが foreground と background のときにはデリゲート関数が呼ばれるけれどsuspend 状態では呼ばれないなので最初は通知が出るがしばらくすると出ないという現象が起こるそのように見えた気がする

ざっとでもいいから、ドキュメントを読む癖をつけねば。

2015-10-24

iOS の UILocalNotification でユーザーに指示を出す

iOS 9.1/Swift で定期的に音とバイブを鳴らすコードを書いた移動中の人間にスマートフォンから音声とバイブで〇〇せよという指示を与えられるかを確認することが目的だ

NSTimer を使って、定期的に関数を呼び出し、その関数の中で AVAudioPlayer オブジェクトの play() メソッドと、AudioServicesPlayAlertSound(SystemSoundID(kSystemSoundID_Vibrate)) を呼び出すコードを書いた。アプリがフォアグラウンドにあるときは、定期的に音もバイブも鳴るのだけれど、バックグラウンドに入ると音もバイブも鳴らない。

iOS アプリの開発経験のある斧さん仮名によると用途次第だが音はともかくバイブを制御できることを期待するなタイマーもだるいから諦めろ」ということだった

今回はあくまで実験なので、UILocalNotification をいくつも作って、スケジューリングすることにする。

さて、ポケットにスマートフォンを入れて、移動してみたところ、バイブが鳴ってることは分かるが、仮に振動パターンを作ったとしても、判別できなさそうだ。

一方、ボリュームを大きくしていると、胸ポケットに入れてても、尻ポケットに入れてても、音声による指示は聞こえる。

// Permission
UIApplication.sharedApplication().registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Sound, .Alert], categories: nil))

// Setup local notifications
let COUNT = 5
Let INTERVAL = 60

for i in 0 ..< COUNT {
    let notification = UILocalNotification()
    notification.alertBody = alert
    notification.timeZone = NSTimeZone.defaultTimeZone()
    notification.fireDate = NSDate(timeIntervalSinceNow: Double(i+1) * INTERVAL)
    notification.soundName = "foo.m4a"
    UIApplication.sharedApplication().scheduleLocalNotification(notification)

2015-10-17

iPhone アプリ開発をかじろうとする

iPhone/Android アプリのディレクション仕様策定ともろもろの意思決定みたいなのをしたことはあるのだけれど実際に作ったことはなかっただいたいが通信やドメインモデル的なデータ構造を主に担当することが多かったわけで

そんなわけで iPhone アプリの作り方を知ろうと思い立った。

だいたい2日もすると、やる気がなくなってしまうので、勢いで本を購入。簡単すぎるくらい簡単なところから、と思って、簡単そうな本を買ってやってみた。基本的に書いたとおりに写経すればいいんだけど、うっかり、Xcode 7 をインストールしてしまって、微妙に違う箇所があったりする。



この本、構成はいいんだけど、たとえがイマイチなので、好きではない。例示ではなくて、たとえ。

とはいえ、書いてあるとおりに書くと、動く。その後で解説がある、という構成は、私にとって分かりやすい。

続いて、Apple のサイトにある iOS 9、 Xcode 7 のチュートリアルもやってみた。ふむふむ。

Swift は言語仕様的に、冗長なところがあって、同じことをするために複数の書き方があるように見える。class があれば struct は要らないだろとか、継承、extension、プロトコルが地味に被ってるようなとか、delegate は機能じゃなくてデザインパターンかよとか。

けれど、誰かが「言語の問題ではくて、OS X や iOS アプリの既存フレームワークを使うために、そのようなことになってしまっている」と話している見て、納得した。

アプリ開発を請け負えるかと言われると、まったくもって無理ではあるけれど、デバッグの手伝いくらいは(ピザを注文する以外にも)できるようになったような気はする。



2015-10-10

知人、Facebook 広告、Yahoo! 知恵袋でインタビュー対象を探す

作ろうとしている製品について、知人にインタビューをしてみた。「顧客はこのような問題を持っているであろう」という仮説の検証を目的にしている。

それとは別に、Facebook 広告を出して、アンケートページに誘導する、というのを試した。けれど、アンケートへの回答率が低かったので、数日で終了。検証インタビューを勧めていた本にも「いきなりアンケートがあると、回答率が下がる」と書いてあったのに、見逃していた。

インタビュー対象を探すのが目的だったので、Facebook 広告の対象は日本在住を設定した。日本語版と英語版を用意したところ、それぞれ傾向が違う。日本語では「私の年収低すぎ!」みたいなネガティブな問題定義がある画像で、ダントツでクリック率が高い。また反応するは 30-50代 の男性が90%以上である。

英語版では「年収が上がった!」みたいなポジティブな結果を連想させるメッセージがついた画像に、比較的クリック率が高い。男女比は 6:4 くらい。ただ英語話者というのは非常に広い文化圏に分布するので、セグメントとしては大きすぎるかも知れない。

ふと思い立って Yahoo! 知恵袋で、質問してみた。自分が言いたいことを書く回答者がいるかもなぁという仮説があったけど、どうせタダなので試してみたわけだ。結果、やっぱり、そういう人がいる、とういうことが分かった。仮説の検証。

2015-10-03

リーン顧客開発を試している

シンディ・アルバレスの「リーン顧客開発売れないリスク」を極小化する技術 (THE LEAN SERIES) を読んで実践しはじめたリーン・スタートアップから派生したシリーズの本で原題は「Lean Customer Development: Building Products Your Customers Will Buy」という副題は「顧客が購入する製品を作る」というところか



売れる製品とは、誰かが金を払うだけの価値を見出しているからだ。つまり、その誰かの課題を解決している。

この本は、課題の設定がそもそも妥当なのか? 解決策は妥当なのか? を検証する方法を紹介している。具体的には、想定顧客へのインタビューを通して、仮説を検証するガイドである。

リーン・スタートアップ関連の本を読んで、いつも「製品を作る前に、潜在顧客に話すの?」と懐疑的だった。けれど、軽い気持ちとは言え、いくばくかの時間をかけて作ったちょっとしたオンラインツールに、ぜんぜんアクセスがないという経験をした。2つ連続で。

需要があるのか? そもそも課題設定も妥当なのか? 妥当だとして、どうやって人を引っ張ってくるんだ? という問に、まったく答えられないことを認めざるをえない。この本にも「製品/サービスの機能よりも、流通、価格、協業あたりにリスクがあることが多い」と指摘されている。おぅふ。

そんなわけで、課題の想定が妥当かのインタビューの準備をしている。インタビューの練習くらいの気持ちで、身近な知人と話しただけで、いきなり学びがあって驚いた。来週も、知人にインタビューのお願いをしてある。

2015-09-28

定期ポスト: 早寝早起

この半年ほど、ニートとバイトの間みたいな生活をしている。世間様という実体のないもの、それから、ちょっと仕事を待ってもらっているクライアントに対して、申し訳ないというプレッシャーを感じながら、マラソンレースに参加してきた。

会場への移動中、村上春樹の「走ることについて語るときに僕の語ること」を読んだ。日々の定常的な創作活動を、ランニングのトレーニングに投影したエッセイだ。彼は経営していたバーをきっぱり辞めて、22時就寝、5時起床の生活サイクルにし、決まった時刻に決まった時間、書き物をするようになったらしい。別の作家もそんなことやってた、とも書かれていた。

早寝早起きと、起きたら重要だときめたひとつのタスクに時間を使う、というのを試してみようと思う。まずは今年いっぱい。そういう贅沢ができる状況なのだから、一度やってみよう。

測れるほうがいいんだろうけど、毎日やるとか、今年中に100日やるとかだと、期間の途中で不達が確定してしまう。これでは、数値目標で得ようとしているはずのインセンティブが、最後まで保たれない。

よい解決策が探していると、あるいは作り出していると、寝る時間がどんどん遅くなりそうなので、細かいことは考えずに、まずは早寝早起きをする、というふんわりしたところから始める。

2015-07-02

原泰久 / キングダム 1〜37巻

ニート生活もだんだん充実してきつつも、ちょこちょこ仕事を請け負っている。その取引先の人に勧められ、読まないがために取引を止められると辛いので、キングダムを読んだ。低い身分の少年の、戦士としての出世物語だ。

春秋戦国時代の末期がベースになっている。何百年もの平衡状態が崩れて、秦が中華を治めるタイミングなので、大きな変化があった時期なんだろう。ストーリーとして、そもそも面白くなる時期なのだと思う。

七国が入り乱れているので、登場人物が多い。主要人物だけでも描き書き分けが難しくなりそうだが、大きな脚色を加えてある。秦の武将だけでも結構な人数なので、王騎はオカマっぽいキャラになっているし、羌瘣や楊端和は女性という設定になってる。そして記録があんまり残っていない李信を、分かりやすい主人公的なキャラクターに仕上げている。キン肉マンや桜木花道のように、考えたことがそのまま発言と行動になるような。

信を主人公として見たキングダムは、大塚英志の「物語の体操」に書いてある(と思うんだけど)、英雄物語の王道ストーリーになっている。英雄が何らかのハンデを背負ってスタートし、ハンデを克服したり、新たなアイテムや仲間を得て、大きな目的を達成していく話だ。

もともと始皇帝が英雄伝説テンプレートに則ってるけど、キングダムは周辺の人物を軸として、英雄物語になっている。他の登場人物もフラクタルのように英雄伝説を生きていて、たとえば王賁はエリートだけど、父にあんまり直接可愛がられてない、とかだ。

史記(の一部)とキングダムの関係は、三国志と三国志演義の関係みたいな感じだろうか。読んだこと無いけど。史実に創作をかぶせている。宇野常寛の「リトル・ピープルの時代」でいうところの、いまどきの創作っぽい。現実に創作をかぶせているとか、主要人物が読者に近いところにいるように見えるところとか。

諸葛亮孔明や劉備玄徳だと、大ボス感がありすぎてビッグブラザー的になってしまう。始皇帝だって大ボスなんだけど、下僕の立場である信と漂から物語がスタート → 漂と瓜ふたつの政(始皇帝)という設定にすることで、一気に近づけてしまっている。信がタメ口をきくから余計に近くなる。リトル・ピープル的というのは、そういう意味で。

羌瘣も政も、過去が少しずつ無理なく明らかになっていく。たとえば羌瘣は、最初はまったく謎の戦士である。そうしないと、信の戦闘物語とごちゃごちゃになってしまうのだと思う。映画「バンテージ・ポイント」みたいに、同じシーンをスピーディーに何度も複数の視点で見せられればいいんだろうけど、漫画では、とくに週刊誌の連載では、くどいくなりし、だいたい進展が遅くなるんだと思う。たとえば、事前に羌瘣が戦から離脱 → 信の戦が一段落 → 羌瘣が復讐を果たす過程で、過去が明らかに、という順序になっている。

国同士の戦闘なので殺人シーンが多いのと、殺せとかいうセリフが多いので、うわぁ... って思ってしまうんだけど、まあ時代的にはしょうがない。アニメ化するときはきっと大変だったんだろう。



というわけで、先週の金、土、日は、抜歯の痛みに耐えながら、キングダム 1〜37巻を読むだけで終わった。ニート生活万歳。交際費として経費にできるかなぁ。


   

2015-03-29

今まで与えられたプレッシャーの量を覚えているのか



「ねーよw」と返事をしたものの、実は話をしたことがあった。そして、会話の内容は、仕事の仕方に、影響を与えていることに気づいた。ありがとうデマルコ先生。

2004年のデベロッパー・サミット、略してデブサミの第1回のとき、会場の廊下にいた。退学と就職の間を彷徨っていた私は、Python ユーザ会のブースの留守番をしていたのだ。

トム・デマルコは、基調講演者だかゲスト・スピーカーとして来日していた。金払っていないので講演は聞いていないし、別にイベント自体の運営には関係なかったのだけど、懇親会の会場に潜り込めた。主催者の翔泳社の人に「デマルコと、話してきていいですよ」と言われて、ひゃっほうってな感じで話しに行った。

とはいえ、別に話すことを準備していたわけではない。ただ、前から気になっていたことを聞いた。

「『プレッシャーを与えても速く考えられるようにならない』というのは、正しそうだが、認めるのは難しいと思う。とくに締め切りのきつい仕事だと。どうやって信じられるようになったのか?」みたいなことを聞いた。すると「私にもそれは難しかった。でもね、君はプレッシャーを与えられたら速く考えられるようになる?」と言われた。当たり前のことなんだけど。「合理的に YES と答えた人は今のところいない。だから信じるしか無い」と。

そのときは「サンキュー・ベリーマッチ」くらいしか返事をしなかったと思う。

それから10年たった。

開発者にたいして、設計/実装/テストをアサインする立場で仕事をすることがある。スケジュールから遅れがあった時でも、プレッシャーを与えたりしない。ということに、さっきのツイートで思い出した。どのくらい意識しているのかわからないけれど「どうしても要るのだ。だから全部しよう」とは、たぶん言っていないと思う。言ってたらごめんなさい。

やりたいことを分解すると、いくつのコンポーネントになるのか? それぞれの規模は? 各コンポーネントの依存関係は? そういうことを聞きながら、ビジネスレイヤーでの価値を最大化するには、何を捨てられるかを考える。開発者が間に合わないと言ったら、十中八九間に合わないだろうという前提を持っている。少なくとも、彼らが想定している成果物と方法では、間に合わないのだ。私の責任は、ビジネスレイヤーに対してアウトプットする付加価値を最大化できるような、技術レイヤーでの取捨選択とプロセスの調整だ。

だいたいこれまでだって私が「それは十中八九無理だ」と思ったことは、十中八九無理だった。スーパーハッカーを連れてきたらできたかも知れないが、たいていそんな時間はない。3日でなんとかしろとか、あと3時間で始まる生放送までになんとかしろ、なのだ。

今、デマルコに会えたら、もっといろんな質問をするだろうし、言いたいこともある。けれど、中退したての私にしては、あの質問は我ながらよい質問だったし、それを10年後の今、活かせていることは光栄だ。あの日、「話してきたら?」と言ってくれた @turky  には感謝している(忘れてたけど)。

2015-02-15

Coplien、 Harrison「組織パターン」 〜 一部を犠牲にして、全体を進める

スケープゴート


組織パターンという本に「誰か一人を犠牲にする」パターンが紹介されている。

どんなに細かくても余計な作業には対処しなければならない。しかし、第一優先のタスクをやるべき時間がとられてしまうことも忘れてはならない。[...]
細かい余分な作業が大量にあると、やりたい仕事ができなくなるのだ。
それゆえ:
誰か一人余計な作業に割り当てて、その作業を終わらせてもらおう。

犠牲とか一人とか言い回しは、おそらく意図的だろう。犠牲になった人の作業が終わったら、元の仕事に戻してあげようとか書いてある。

ここでは、機械的に話を進める。もうすこし抽象化して捉えて、メインのプロジェクトから、派生したプロジェクトを分離し、一時的にリソースを配分する、という風に考える。ひとつのリソースを複数のプロジェクトに割り当てると、たしかに効率が悪いことがある。

余計な仕事が発生


本を閉じると、そこには現実が待っている。ちょうど数ヶ月スパンでプロダクトを開発しているところだ。プロダクトは機能の多さよりも、キャパシティのほうが重要である、という種類ものだ。運用が始まったとき、機能には妥協ができるが、トラフィックに対するキャパシティは妥協やコントロールがしにくいからだ。

現時点で手元には、

  • そこそこのキャパシティで稼働する、機能 A
  • 開発中の機能 B

がある。機能AやBというのは、実際には複数の機能群だ。フルキャパシティで動く部分もあれば、要件半分くらいでしか動かないだろうという部分もある。だが話を単純化しておこう。

このプロダクトのデモを見たい、という仕事が入ってきた。デモという言葉は曖昧なので、よく聞いてみると「プロダクトの機能 A, B, Cを利用したアプリケーション開発と運用を、実験として行う。運用フェーズを想定して、複数のサードパーティが、アプリケーションを開発する」というものだ。

突っ込みたいところや、だるいところがあり、その過程で感情的になり、箸が転がってもブチ切れるという精神状態になったりもしているが、ここでは機械的には話を進めよう。

不足しているものを列挙すると、以下の3つだ

  • 機能 B(作りかけ)
  • 機能 C(次のフェーズで開発する)
  • サードパーティへのサポート(文書、トラブルシュート)
  • アプリケーションの参照実装

である。問題は機能BとCである。機能Bはキャパを考慮して実装中なので、キャパの低い実装に切り替えると、トータルの手戻りが大きい。C は次のフェーズで開発する機能だ。

  • アプリ
  • プロダクト機能 A  + 機能 B と C を追加

えらく変更/追加が多いではないか。急に入ってきた仕事は「プロダクトができること」を見せるものだ。本番運用があるわけでもない。やっつけ仕事だ。けれど、プラットフォームを使う必要がある。

汚れ仕事


とうわけで、汚れ仕事を分離することにした。プロダクトは予定通り開発をすすめる。この仕事用に、別の使い捨てのコンポーネントを用意する。

  • アプリ
  • やっつけラッパー (B + C)
  • プロダクト (A)

アプリから見ると、A, B, C を提供するプラットフォームが存在する。A を提供するプラットフォームは、きちんと存在していて、ラッパーがプロキシする。

機能B と C はやっつけラッパーの中で、やっつけ実装する。

こうやってプラットフォームの開発を、(ほとんど)遅らせることなく、途中で入ってきた依存関係のあるプロジェクトを進めている。あと2週間くらいは、アルコールの摂取量が、高めになるだろうけど、酒を飲む程度の余裕があるということだ。


2015-01-25

Power of 複数案

仕事の合間(つまり、起きている時間の大半)に Twitter を眺めていたら、こんなツイートに辿り着いた。


念のために書いておくと、プロならベストな一案を持っていくべきとか、事前にすりあわせろとか、そういう話をしたいのではない。

自分の役割はなんなのか、相手の役割はなんなのか、という認識を醸成するという話なんだろうなと思った。それによって、前に進ませるのが目的なのだ。

ここで、ちょっと話をずらす。ダン・アリエリーが「予想通りに不合理」で出している例で、雑誌の定期購読の価格設定のエピソードがある。

1. オンライン購読 $59/year
2. 雑誌の定期購読 $125/year
3. オンライン + 雑誌の定期購読 $125/year

2 には、意味がないように見える。けれど、1、2、3 を提示した場合と、 1 と 3 だけを提示した場合では、後者のほうが 3 を選ぶ率が高かったという結果がある。「これは選ばないんじゃないかな」っていうのが入っていると、相対的に欲しいものがより明らかになってくる(あるいは、相対的に魅力的な選択に見えてくる)。

「これだろ」って提案がベストであっても、ちょっと外れた案が見えることによって、本命提案の精度が明らかになり、それゆえ精度を上げていくことができる気がする。



2015-01-10

カズオ・イシグロ「日の名残り」

圧倒的らしい本


quipped の人の「2014年に読んだ本」をながめていたら、カズオ・イシグロの「日の名残り」という本が紹介されていた。

Bezosはこの本を、「たったの10時間、主人公の人生を覗くことで、人生と後悔について教えてくれる本だ」と評していたが(Bezosは後悔最小化フレームワークの提唱者である)、自分の感想は、社畜ライフの最大の悲哀は、社畜であるという自意識の欠乏だということ。今年読んだ小説では、圧倒的に印象に残った。

それほど圧倒的なら、ということで、読んでみた。だが和訳。「わたしを離さないで」(Never Let Me Go) と同じく土屋政雄の翻訳だ。

みんな


家が火事になったらどうする? 家族全員を今に集めて、どの逃げ道が最適か一時間も討論するか? 昔ならそれでよかった、昔ならな。だが、世界はすっかり複雑な場所に変わってしまった。その辺を歩いている人が、誰でも政治学と経済学と世界貿易のことを知っているとは期待できない。

みんなで意見を言い合おうとか、誰の意見にも一理あるとかで、広く意見を集めるというのは、問題解決の手段としては必ずしも適切ではない。とは常々考えている。

基本的な物理現象を理解できない人が、発電所の稼働に反対/賛成だと思うのは勝手だけれど、わたしと意見が同じかどうかに関係なく、直接的な意志決定に関わらないで欲しい。

※ 異なる視点を取り入れること自体に、文句があるのではない。念のため。

後悔


最小化/最大化するという考え方が好きだ。ネガティブなことを完全に無くすのは大変だけれど、最小化するのが現実的なことがある。たとえば、サーバダウンタイムをゼロにするとの、最小化するのは大きな違いがある。

Python 温泉アドベントカレンダーで「プログラマになって、後悔がある」と書いたことに対して、Twitter なんかで反響があった気がする。後悔しないほうがいいけど、わたしはどっちに転んでも後悔はするところまで来ている。子どものころ勉強しなかったとか、高校で合コンにもっと行っとけばよかったとか、取り返しのつかない後悔はいっぱいある。遺憾ではある。なので、今後の人生で、後悔を最小化する方向に倒している。

プログラマになったことにより、いろいろと後悔はある。けれど、プログラマにならなかったら、もっと比べ物にならないくらい、大きな後悔をしただろうと考えている。

A と B を選択があるとき、どちらがより小さな後悔で済むだろう?って考える。ベゾスの後悔とはわたしの後悔は違うかもしれないけれど。

バイアス


この作品の登場人物のひとりが、自己弁護というか、自己肯定というか、とにかく自分がよく思われるように話す。嘘ではないけれど、歪んで伝わってくる。意図しているなら、信頼できない人物である。

問題は、その人物はものすごく大きな感情バイアスが働いてるかも知れない、ということだ。自分が正しいと信じたいがために、歪んで認知しているかも知れない。

後悔を最小化しようとするときには、注意が必要だ。心理的不協和を解決するために、後悔をせずに、これでよかったんだ、肯定してしまうかも知れない。

というわけで


慌てて読んだこともあって、圧倒的な印象は残っていない。読み込めていない感があるので、注意深く再読したい。

2015-01-01

森博嗣「サイタ×サイタ」

ネタバレです。そのつもりで。ミステリーについては言及しません。いつもの小川や真鍋が、素行調査を請け負うのだけれど、その過程で...という話。

「できなくもないっていうのは、できるけれど、それなりに高くつくという意味だ」
「お金ですか?」
「まあ、そう、一般的には……」
「知りたいですけれど、今の仕事とは関係がありませんから、ちょっと無理ですね」

ソフトウェア開発を彷彿とするやりとり。調べる/実装することはできるけれど、時間=お金かかりまっせ。

「つまり、それほど親しくもないけれど、知合いの人物から、恐いから助けてくれ、もう死んだほうがましだ、なんて言われて、放っておいたら自殺しかねない、という状況だったら、ということです」
「うーん、ちょっと待ちなさいって言いますね」
「でも、相手は電話を切ってしまう。どうします? 放っておきますか? 自殺したいなら自殺すれば良いって、そう割り切れますか?」
「うーん」小川は唸った。自分は何を考えているのか、と思った。
「僕は放っておきますよ。」真鍋が横で言った。「死ぬのはその人の自由だと思います。すぐ助けに来て欲しいと言われれば、行くかもしれませんけれど、自殺します、と言われても、たぶん、警察へ電話をするだけですね」

話題が話題だけにセンセーショナルな感じだけれど、究極的には「頼まれもしないことを、するのか?」という話だ。頼まれていないことは、やらないように努めようとしている。頼み方が下手とか、頼みにくい状況というのは考慮するけれど。

先回りして「こういうことを、したほうがいいかも」と思うことがあって、ついやりたくなってしまう。やらないように努めているけれど、ついやってしまう。

気をつけないと「俺がやってやったのに」みたいに思ってしまって、DVとかストーカーとか、そういう方向に行きそうで、恐ろしい。

プレゼントを渡されるのが嫌だ、とよく言っているのは、自分にDVやストーカーのメンタリティがありそうだからだ。頼まれた場合をのぞいて、プレゼントは「喜んでもらいたい」という渡す側の動機でなされる。したがって、喜ぶかどうかの責任は、渡す側に 100% ある。けれど、受け取ったプレゼントを気に入らなかった場合にぞんざいに扱うと、受け取った側に責任が押し付けられる印象がある(せっかくもらったんだから喜べ、的な)。渡す側に動機と責任があっただろう、と。

頼まれもしないことをすると、いろいろややこしいなぁという話でした。