同じことなのに全然見え方が変わること

このエントリーを含むはてなブックマーク hateb
今日は、プログラミングも囲碁もフットサルも関係ない話で、日頃目にしたり経験したりするもののなかで、同じことなのに受け取り方が全然変わるなーと思ったことをいくつかあげてみたいと思います。

1. アルバイトの規定

近所のレンタルビデオ屋にはアルバイト募集の貼り紙がしてあります。
時給850円/時〜
笑顔で接客できる方にはボーナス50円/時

と書いてありました。

うちの会社もフットサルコートの運営をしているので、アルバイトの方をたくさん採用しています。そして、接客に笑顔が必要なのはいうまでもなく、どうしたらスタッフ全員が気持のいい笑顔をできるかいろいろ考えています。そのとき、この貼り紙を見て、直接的ではあるが効果的だなあと思いました。ただこれってよくよく考えると
時給900円/時〜
笑顔で接客できない場合には時給から50円マイナスします

っていうのと全く同じなんですよね。ものはいいようだなぁと。
実際、時給900円にしてしまうと、笑顔がないくらいで50円マイナスすることは労基法的にも難しいと思うけど、上のやりかたなら問題ないと思います。どちらの場合も、ちゃんと働いているスタッフからみたら、時給900円ってことなんですけど、だいぶ印象が変わりますね。

これは、一方は基準を850円にし、もう一方は基準を900円にしているから、見え方がだいぶ変わるだけで、どちらも「笑顔あり、900円」を基準に考えれば、笑顔がなければ50円マイナスということに全くかわりはないわけです。

ちなみに、個人的にはこういう言葉のトリックのようなやり方で、よく見せるっていうのは実はあんまり好きではありません。笑顔ができないことに罰則規定(しかも罰金)を設けたいっていう発想から、上記の貼り紙が生まれたと邪推しちゃうからです。

2. ソーシャルゲームのご褒美の話

ヒットするソーシャルゲームのセオリーの1つに、「継続的に訪問させる仕掛け」というのがあります。よくある形は、一定時間経過してアクセスすると、ちょっとお金がもらえたり、宝箱をあけることができたりとかそういうたぐいのものです。
1時間後にアクセスすると、さらに50円もらえるよ!

これが楽しみで、ちょくちょく訪れるひともいるでしょう。

ところが、僕が先日始めた、ソーシャルのサッカーゲームでは、これを裏返した仕掛けがありました。規定の時間以上アクセスがないと、ペナルティがあるのです。定期的にトレーニングし続けないと体がなまってしまうということで、ステータスが少しさがってしまうんですね。
1時間以上トレーニングしないと、訓練度が50さがります!

これらはゲーム内の経済で言えばまったく同じことです。ご褒美型の方も、例えば2時間あけてアクセスして50円もらったひとは、ちゃんと1時間ごとに2回アクセスして100円(50円 x 2)受け取ったひとより、もらえるお金が50円減ってしまっているので、マイナス50円のペナルティをくらっているのと同じことになるからです。

こっちも結局基準の問題で、ご褒美がもらえてあたりまえの状態を基準に考えれば、規定の時間以上あけてアクセスしてしまうことによる機会損失はステータスが下がるペナルティと同じになるというわけです。

ソーシャルゲームの場合、どちらの感情に訴えかけるもののほうが効果的なのかは僕にはわかりませんけど、最近はペナルティ型もしくは併用型が増えてきている気がしますね。

最近良く思うんです。
ものごとは本質が重要だけど、ひとの行動は本質にたいしてより見かけに対して行われることのほうが多いと。
だから、うわっつらって超重要ですよねって。
| マイニュース | 10:38 | comments(0) | trackbacks(0)

サーバ間通信のデータ詐称回避

このエントリーを含むはてなブックマーク hateb
サーバ間で通信をする場合、その引数の内容が詐称されていないかを判定するためにひと工夫凝らさないといけません。良くある方法としては、サーバ同士お互いに秘密鍵を持ち、通信の引数とその秘密鍵を種にして同じロジックでハッシュを生成しそれを比較するというものがあります。

例えばユーザーIDが712904684のユーザーの残高を200円上げるという処理をサーバ間通信で依頼することを考えると、こんなAPI(URI) を考えるかもしれません。
http://www.example.com/api?uid=712904684&money=200
ところがこれがこのまま通って残高が200円あがるとなると、200の部分を9000に詐称するのも簡単な気がしてきます。
http://www.example.com/api?uid=712904684&money=9000
サーバ間通信を行うアプリケーション以外からでも、例えばこんなURLをブラウザのアドレス欄に入力して実行するだけで簡単にこのユーザーの残高を9000円もあげることができてしまいます。サーバ間通信の内容は普通はユーザーには見えにくいので、こういう問題を気にせず実装されているソーシャルアプリもたくさんあり、巷のソーシャルゲームでチートが横行している一因にもなっています。さて、話を戻して、このような詐称をさせないために、最初にお話したハッシュを比較するという方法をどのように適用するのかみてみましょう。

1. サーバ間通信を行う2者で事前にsecret_key となる文字列を決めておく
2. 引数のkeyをアルファベット順に並び替える
3. その順番でkey=valueという文字列を連結させる
4. その文字列の最後にsecret_key を連結する
5. できた文字列をmd5 でハッシュにする
6. 通信の最後の引数にこのハッシュを付加する

secret_key をa1b23c とします。
PHPで書くとこんな感じでしょうか。
function generate_hash($params_array) {
$secret='a1b23c';
ksort($params_array);
foreach ($params_array as $k=>$v) {
$str .= "$k=$v";
}
$str .= $secret;
return md5($str);
}
これで生成されたhashをx43q98tgaji45asoiとすると、次のようなURI でユーザーの残高をあげるようにリクエストを投げます。
http://www.example.com/api?uid=712904684&money=200&hash=x43q98tgaji45asoi
こうしておいて、リクエストを受け付けたサーバ側でも同じsecret_key を用いて同じロジックでハッシュを計算して、それがhashという引数で渡ってきたもの(x43q98tgaji45asoi)と一致しているかをチェックしてデータが詐称されていないかを調べることができます。

この場合に最初に見たような詐称をするとどうなるでしょう。
http://www.example.com/api?uid=712904684&money=9000&hash=x43q98tgaji45asoi
money=9000の部分の文字列がmoney=200の文字列と異なるため、同じロジックでハッシュを生成しても、できあがるhash がx43q98tgaji45asoiという文字列になりません。そのためリクエストを受け付けたサーバ側ではhash の不一致が発生し、エラーとして処理されます。一方、詐称したいと考える第三者がこのハッシュもちゃんと書き換えたURI を作成しようと考えたとしましょう。しかし、その第三者はあいにくsecret_key を知らないのでそれも不可能です。ここはmd5 が一方通行の変換であるために、正しい通信からsecret_key が逆算されないことを利用しています。詳細は割愛しますが、「正しい通信の内容からもsecret_key は推測できない」というのは大事な部分です。

以上が、サーバ間通信における詐称回避のひとつの解であり、Facebook でもほとんど似た方法が取られています。

自前でセキュアなサーバ間通信を行う場合はデータの詐称というのがなかなか厄介な悩みとなります。第三者に公開しないようなシステムであればアクセス元IP をチェックするというような簡単な方法でも対応できるかもしれませんが、第三者に広く公開する場合はこういう方法を検討するのもいいと思います。その場合、API 利用者をしっかりと管理し、その利用者ごとに別のsecret_key を割り当てるのがまたもう一つ難しいところなのですが。
| Web技術 | 09:59 | comments(0) | trackbacks(0)

パソコンと携帯、どちらで文字を打ちたいか

このエントリーを含むはてなブックマーク hateb
ニコニコ動画より Youtube を使う人の意見を聞いてみた - IT戦記
amachang「なんで、 Youtube ばっか使うの?ニコニコ動画のほうがおもしろい動画多くない?」
知り合い「うーん。そうかなー。」
amachang「そう思うけどなー。」
知り合い「とりあえず検索するじゃん。そのとき、候補が出てくるから楽でいいんだよねー。あと、ニコニコ動画ってログイン必須じゃん、パスワードとメールアドレス打つの大変。」
amachang「え、それってそんなめんどくさいことなん?」
知り合い「いやー。パソコンで文字打つのに慣れてないからさー。みんなお前みたいにパソコンで文字打てると思ったら大間違いだよ。」
amachang「まじでー?」
知り合い「まじでー。」
これを見て、先日電車の中で聞こえてきた会話を思い出しました。

50代くらいの女性2人での会話

A:「最近さ、先生にパソコンでメール打たないといけなくて面倒じゃない?」
B:「うん、パソコン大変...」
A:「でも、あたし、いいこと思いついたの」
B:「ん?」
A:「携帯でメールを書いてね、自分のパソコンのアドレスに送るの」
B:「!!」
A:「そしたら、それをコピーしてすぐにメール送れるのよ」
B:「うわっ、超アタマいいー。私もそうしよー」

一瞬我が耳を疑いました。僕はiPhone に変える前は携帯で文字を打つのがとにかくいやで、それこそ、PC で一度打ったものを携帯にメールするというような使い方をしていたくらいです。ところがまさか、逆の発想とは...

予測変換とか、変換履歴を保持しているところなんかは確かに携帯の方が便利かもしれないとは思いますけど、パソコンより携帯の方が打ちやすいと言うのはなかなか新鮮でした。

自分が常識だと思ってることも常に疑ってかからなければいけないということを改めて再認識しました。また、インターフェイス設計は利用者、対象者をつねに想定しながら行わないといけないということも、再認識できました。
| PC/家電 | 13:12 | comments(1) | trackbacks(0)

[JavaScript]jQuery のイベントとクロージャ

このエントリーを含むはてなブックマーク hateb
以前のエントリ([JavaScript]僕、スコープとかクロージャとか曖昧でした
)で書いた、Javascript のクロージャの話と全く同じことなのですが、あれをjQuery のclick イベントで書くとどうなるかということを、自分用にメモとして残しておきたいと思います。

例えば、div でブロックを3つ作って、それぞれにclick イベントを持たせるとします。そのとき、そのclick に反応して、そのblock が何番目に作られたものなのかをalert するようにしたいとします。

jQuery の.click は第一引数にコールバック関数をとるので、クロージャのことを意識せずに直感的に書くと、次のようなコードになるのではないでしょうか。
var div;
var i;
for(i=0; i<3; i++) {
div = $('<div/>').click( function( e ) {
alert(i)
} );
div.html('click me - ' + i);
div.css('cursor', 'pointer');
$('body').append(div);
}

普段からJavascript を書いているかたであれば、すぐに問題点に気付くと思います。これは例の通り、click me - [i] のところのi は正しくその番号のものが表示されるのですが、実際にそれをクリックしてみても、alert で表示されるi は目的のものとは違うはずです。ここでも前回見た通り、「関数を返す無名関数をすぐに実行する」という方法で対応できます。

考え方としては、まず、「関数を返す無名関数を『すぐに実行する』」というところが重要なので、.click の引数にあたるところで、関数をすぐに実行させます。順を追って書くと、まずこんな感じになります。
.click( function () {} () );

当然、このfunction はすぐに実行されるのですが、.click は引数にコールバック関数をとるものなので、この実行される関数がそのコールバック関数を返さなければなりません。つまり、こう書くことになります。
.click( function () {
return function() {};
}() );

そして、その中に書かれた返されるコールバック関数のところに目的のコードを書くことになります。
.click( function () {
return function() {
alert(_i);
};
}() );

ここで、alert(_i) と書いたのですが、この_i は外側のfor のi とは別物ということをはっきりさせるために_i と書くことにしました。つぎに、この_i に外側のfor でまわされているi を渡したすというのを表現します。
.click( function (i) {
var _i = i;
return function() {
alert(_i);
};
}(i) );

すぐに実行される無名関数に、引数として i をとれるようにしました。ここでは、紛らわしくないように別の変数名(例えばn)を使ってつぎように書くこともできます。この方がi の違いを区別しやすくなるので、わかりやすいというかたもいらっしゃるかもしれません。
.click( function (n) {
var _i = n;
return function() {
alert(_i);
};
}(i) );

これで目的のclick イベントは完成です。jQuery のイベントに渡すコールバック関数では、引数にevent そのものをとることができます。このような書き方をした場合、それはこの内側に書いたコールバック関数で受取れます。次のe のような書き方です(今回の例ではこのe を使うことはありませんが)。
.click( function (n) {
var _i = n;
return function(e) {
alert(_i);
};
}(i) );

以上を踏まえて、最初に書いたものを書き直すと、以下のようになります。
var div;
var i
for(i=0; i<3; i++) {
div = $('<div/>') .click( function( i ) {
var _i = i;
return function(e) {
alert(_i);
};
}(i) );
div.html('click me - ' + i);
div.css('cursor', 'pointer');
$('body').append(div);
}

僕もまだまだ初学者の域をでておりませんので、上記のような思考のもとに書いております。
| JavaScript | 11:42 | comments(0) | trackbacks(0)

[囲碁]新春twitter囲碁部開催のお知らせ

このエントリーを含むはてなブックマーク hateb
小さい頃におじいちゃんに手ほどきを受けるものの、当時は俄然将棋のほうが面白く、大人になるまでまったく碁を打たずに育ちました。ヒカルの碁を読んで、囲碁を取り巻く環境がなんだか面白そうだと感じて、ようやく打ち始め、あれよあれよというまにのめり込みました。しかし、まわりに打てる人がほとんどおらず、人間と囲碁を打つ機会がほとんどなく、鬱々とした日々を過ごすことになりました。しかたなく、僕のまったくの趣味である囲碁を他人に押し付け、少しでも対人戦の機会を増やそうともくろみ、囲碁の啓蒙を徐々にではありますが進めてきたところ、囲碁に興味のある方もたくさんいらっしゃるという手応えを感じました。ただ、それでもやらないのは、やはりまわりに打つ人がいないというのがひとつの原因のようでした。

僕を含めみなさまのニーズを満たすべく、ここにtwitter 囲碁部を開催したいと思います。

■日時
2010年1月8日(金) 19:30 - 21:30
参加者の状況次第では20:00 開始とするかもしれませんので、20:00 からなら来れる!というかたも、その旨を添えて申し込んで頂ければと思います。会場の都合で終了時間は変更できません。

twitter 囲碁部 #1 : ATND

■人数
20人

■場所
千心囲碁クラブ (http://space.geocities.jp/senshin_igo/)
高田馬場 徒歩2分

■対象者
1. 囲碁に興味はあるけど、囲碁のルールもご存じない方
2. ルールは知っているんだけど、打つ機会が少なくて嘆いている方
3. 棋力関係なく、とにかく囲碁のイベントで楽しみたい方
4. 有段だけど、教えるのも好きだから手伝っちゃうよという方

ちなみに、僕は2級くらいの腕前で、そこそこできる人なら1年もかからずに到達できる程度のレベルです。碁会所などに行くと、最弱の部類です。が、小学生向けの指導者免状を持っているので(正確には受講済申請中)一緒に楽しみながら教えるのは、多分できます。上記の1. に該当する方と2. のうちの希望者にはルールの講習実施します(20 - 40min.)。その後、9路盤にて棋力別のペア碁を楽しんで頂く予定です。

■タイムテーブル
19:30 - 20:15 ルール講習会
20:15 - 20:30 質問及び時間があれば簡単な最初のコツを伝授
(ルールのわかる方はこの間にお互いの顔合わせをかねて、ペア碁を1局ほど打って頂きます)
20:30 - 21:30 ペア碁 x 2
組み合わせを変えて、ペア碁を2〜3局打って頂きます。

※本イベントでは9路盤しか使わない予定です。

ATND で募集中ですので、興味のある方はこちらからご登録ください!
twitter 囲碁部 #1 : ATND

よろしくお願いします!
| 囲碁 | 12:05 | comments(0) | trackbacks(0)
| 1/37PAGES | >>