2010年3月16日火曜日

Google Waveを使わないと人生損する

このブログ記事をはてなブックマークに追加

「Google Waveを使わないと人生損する」…これはちょっと大げさかもしれないが、1年半前に書いたブログ記事「Evernoteを使わないと人生損する」で言及したEvernoteと同じぐらい、Google Waveが重要な技術になると感じたのは本当だ。当初、Google Waveは自分にとって、Google App Engine (GAE)などでプログラミングできる単なるおもちゃだった。しかしながら、今になってやっと、オンラインコラボレーションプラットフォームであるGoogle Waveの潜在能力の高さを知ることになった。

大量のメールに埋もれる情報と予定の立たないミーティング

最近、仕事上のメールのやりとりが頻繁ですぐに流されてしまうことが多く、大事な知らせを失念してしまったり、大量のメールから目的の情報を探し出さなくてはならなくなったりと、メールの扱いに手を焼いていた。さらに、直接顔を合わせるミーティングにおいても、この時期は皆忙しいようで、集まりたいときにすぐに集まれない状況が続き、何かと仕事が滞りがちになっていた。

そこで、昨年にアカウントを取得していたGoogle Waveに目を付けたのだ。今までGoogle Waveを仕事で利用しなかったのは、もともとGAEと連動させてWaveボットなどを開発するのが目的であり、コラボレーションツールとしてはあまり興味を持っていなかったからだ。それに、知人や同僚にもアカウントを持っている人がいなかった。

しかし、メールでのやりとりがひどく非効率に感じられ、必要なときにミーティングもできないというこの状況を打破すべく、Google Waveのアカウントを職場で配ってみることにした。そこでまずは、IT関連の最新技術に明るい同僚に利用してもらい、しばらく一緒に使ってみたのだが、特に問題となるような点もなく、使い勝手もそれほど悪くはなかったので、他のメンバーにもアカウントを配ることにした。

本当に新しいことは理解され難い

Google Waveアカウントを配ったメンバーに早速使ってみてもらったところ、おおむね好評を得られて…というほど甘くはなく、やはり第一印象は「難しい」、「使いづらい」、「メールでいいんじゃないの」という意見だった。誰もGoogle Waveの名前すら聞いたことがないというのだからそれも仕方が無いのだろう。これらの意見については、Google WaveコンプリートガイドによるGoogle Waveの紹介でも全く同じように述べられている。

“Google Wave の最大の欠点は、新しいユーザーが試しに使ってみた場合にあまりに理解しづらくて困惑してしまうことにあるといえます。EasierToUnderstandThanWave.comのようなパロディーサイトでは、炭素年代測定法や新古典派経済学、ポリモーダルな半音階理論といった頭脳を要求する話題でさえ、Wave に比べれば理解しやすいとされています。この冗談が真に迫っているのは、初めて Wave に触れたときにほとんどの人が困惑を経験するといえるからです。あなたがはじめて友人や同僚からうけとる wave は得てして、「なんだこれは」や「これは変なツールだね」といったものになることでしょう。” (Google Waveコンプリートガイドより引用)

そして、難しいと思わせる理由として以下の4つが挙げられている。

  • 「ドキュメントが会話」という前例のない新しいパラダイム
  • 無秩序な木構造の会話、ノンリニアなメッセージスレッド
  • ドキュメントのバージョン管理
  • Waveはまだ未完成、足りない機能の存在

確かにもっともな理由ではあるが、それでも使ってもらわないことには何も始まらないので、自分の関わっているプロジェクトのいくつかについてGoogle Waveを使ってもらうことにした。新しいパラダイムは常に受け入れられがたいものだ。

利用して初めて分かること

まず最初にしたことは、メンバーと共同で進めている自分の仕事の連絡をWaveで管理することだった。

今までは自分の担当分の結果が出たら、その報告と結果データの場所(通常はコンピュータ上のディレクトリ)などをメールで知らせていたのだが、そのやりとりが頻繁になると以前の報告やデータを把握しづらくなってくるし、ある仕事の成果を引き継いで別の仕事を行う場合、その対応付けも大変だった。また、別のメンバーが新たに参加する場合、これまでの進捗を説明するのも一苦労だ。

しかし、Waveを利用することによって、それぞれのメンバーの進捗状況は一目でわかるし、仕事のデータも簡単に取り出せる。画像やPDFなどのファイルもドラッグ&ドロップで簡単に共有できる。さらに、ToDoリストとして使うことで、既にメンバーの誰かが完了していた仕事を別のメンバーが繰り返したり、既にあるユーティリティスクリプトを作成してしまうことがなくなった。車輪の再発明の防止だ。加えて、他のメンバーの状況と照らし合わせて、ここまでは急ぎで行わなければならないとか、これはまだ急がなくても良いだろうとかの判断が、簡単にできるようになった。

次に、ある商品の名称を決める打ち合わせを例に挙げてみよう。

まずは、Waveを使わない通常のミーティングの場合、メンバー全員を同じ時間に拘束する必要があり、さらに、その時間内で名称候補を考えつかなくてはならない。しかしそれでは考えつくすべての候補が出る前に時間切れとなってしまうかもしれない。では、時間を決めずに各自に考えてもらってそれを持ち寄るのではどうだろうか。これだと、各個人がバラバラに考えているので、別メンバーのアイデアから触発されることはない。実際に自分の場合、ミーティングやメールでアイデアを募ってみたが、ほとんど反応はなかった。ミーティングでは時間が短すぎたし、メールでは良いアイデアを思いつかないまま別の仕事に追いやられてしまうわけだ。

ではWaveを使った場合はどうだろうか。まずはいくつのかの候補の議論がなされ、それに触発されて他のメンバーからも新たな候補が挙がるようになった。それによりさらにアイデアが浮かんでくる。まさにブレインストーミングだ。しかも、Waveであれば、全員が同じ情報を共有し漏れが無く、時間にも拘束されない。進行のまとめもWave上で編集していけばよいし、何かを決めるときには投票などのガジェットも使える。実際に上記で挙がった候補から最終的な名称を決めるために投票ガジェットは大いに役立った。

どれだけWaveが有用に使えるか、使用する前にすべてを見積もっていた訳ではない。車輪の再発明の防止やアイデアの触発などは、実際に導入して初めて実感できたことだった。頭では分かったつもりでも使ってみるまでは本当に分かったことにはならない。

TwitterとEvernoteで相乗効果

iPhoneとツイッターで会社は儲かる」(*1)の著者であるEC Studioの山本氏によると、会社のコミュニケーションは電話、チャット、メール、Twitterで成り立っているそうだ。電話はSkypeでもGoogle Voiceもいいし、Twitterの替りにGoogle Buzzを使ってもいいだろう。しかし、チャットとメールはGoogle Waveに置き換えられていくのではないかと感じている。もちろん、すべてのメールとチャットが置き換わるとは思っていないが、多くの部分でWaveが使われるのではないだろうか。

そして、ここで重要になってくるのが、WaveとTwitterとの共存だ。Twitterは今までにないゆるいつながりのコミュニケーションツールとしての立場を確立してる。実際に自分も使っているが、コミュニケーションツールの他に情報収集の手段としてとても有用だ。しかし、Twitterの情報はノイズが多く発散しやすい。最新の情報を肌で感じることができても、それを保存して加工する目的には向いていない。しかし、Waveを使えばそれを補うことができる。例えば、重要だと思われるTwitterの発言があったらそのポインタだけ示しておけば、その情報を共有できる。そして、それが古くなったりただのノイズだと判断したのならそれを捨てればいいだけだ。編集可能なWaveでは、チャットやメールのスパムのように邪魔になったりしない。リアルタイムの今の情報を共有できるのだ。因みに、Wave上でTwitterを動作させるボットもあるし、特定のキーワードでつぶやきを表示させるガジェットもある。

さらに、Google WaveはEvernoteとも非常に相性が良い。というのもGoogle Wave自体が複数人で共有できるEvernoteのようなものだからだ。もともと個人のWebスクラップノートとして利用されているものだからEvernoteを複数人で共有して利用するのは難しいが、Waveを利用することでその弱点を克服できる。

自分の場合、仕事ごとにEvernoteのノートを作って管理している。そして、ある仕事が共同作業であった場合、Waveを作ってそのURLをEvernoteに貼り付けておく。個人的な細々したメモや形になっていないアイデアなどはEvernoteに書いておき、皆で共有する情報はWaveに書く。Waveには他のメンバーも書き込んだり、編集したりするので情報は常に遷移していくのだが、その遷移する情報のすべてを一つのURLだけで保存できる。そして、EvernoteからWaveの情報にアクセスするのはクリック一つだ。これは画期的だ。因みに、Wave上でEvernoteを動作させるガジェットも存在する。

ここで示したように、Google WaveとTwitterとEvernoteを活用することで、とても大きな効果を期待できるだろう。

使用するにあたって

Google Waveの導入について、セキュリティを心配する声を聞く。外部にデータを持つのは不安だという。この点についても問題ない。と言うのも、Waveサーバプロトコルが公開されているからだ。自社サーバでメールサーバを立ち上げるように、Waveサーバを立ち上げることができる。現在はプレビュー版ということもありGoogle以外での実装は見かけないが、将来的には普通に立ち上げることができるだろう。

もっとも、自社でサーバを持つことと、セキュリティが確保できることとは同義ではない。セキュリティを保つためにはそれ相応の技術が必要だ。その点で自社でサーバを管理するよりも、Googleなどのような高い技術を持つ企業に任せた方が安全であるとする見方もある。もし、Gmailなどを仕事で使っているのであれば、Google Waveもそれと同程度にはセキュリティが確保されていると考えられる。

Waveを使用するにあたり、次に問題になるのは、各ユーザが感じる使い勝手だろう。いくら便利だからといって、使い勝手が悪ければ使われない。例えば、SkypeやGmailであればチャットやメールが届いたときにその旨が画面にポップアップして知らせてくれるユーティリティがある。Google WaveにもFirefoxやGoogle Chrome用にブラウザ上で知らせてくれるAdd-onがあるが、それだと常時ブラウザを立ち上げている必要がある。また、新しいWaveが来たときにメールで知らせてくれるオプションもあるが、メールの代わりにWaveを使うという目的からして本末転倒だ。そこで、Google Wave Notifierの使用をお勧めしたい。これを使えば新しいWaveが届いたときにポップアップして通知してくれる。また、Mac OS XやiPhoneならWaveboardというWaveクライアントが利用でき、通知機能もあるようだ。

どちらにしろ現在はまだプレビュー段階であり、リリースまでにはもうしばらくかかるだろう。それまでにはもっと便利でより良い環境が揃ってくることになると思う。

最後に

Google Waveはまだ正式にリリースされたわけではない。まだまだ発展途上のプレビュー版だ。機能も不完全であり、開発環境も安定していない。なので、今すぐにWaveアカウントを手に入れられなくても気にすることはないと思う。将来のGoogle Waveがどのように使えて、どのように便利なのかを知ってもらい、Google Waveが利用されることなく廃れてしまうことが私たちにとってどれだけ「損する」ことなのかを理解してもらうことが、これを記した理由だ。なので、今すぐ使い始めなければ「損する」というわけではない。しかし、それでも今すぐに使いたい方もいると思う。残念ながら自分の持っている招待枠は使ってしまったので、「Waveプレビュー版の招待を得る」などを参考にアカウントを手に入れて欲しい。

参考サイト

Google Waveの最新情報や便利な使い方を知りたい場合には、以下のサイトが参考になる。


紹介ビデオ

Google Waveの使い方が簡潔にまとめられているビデオ(約5分半)。



(*1) 「iPhoneとツイッターで会社は儲かる

ブログクラブより献本して頂いた。Twitterの利点がわかりやすくまとめられており、今回のテーマとも一部共通するので紹介させてもらった。Twitterの利点や利用方法を知りたい方は読んでおいて損はないと思う。個人的には最後の社員アンケートが面白かった。

続きを読む...

2010年3月9日火曜日

Scratchでプログラミングする子供たち

このブログ記事をはてなブックマークに追加

小学2年生の娘にスクラッチアイデアブックを渡したら、あっという間に読み終え、Scratchを使って自由気ままにいろいろなプログラムを作り始めた。書籍を参考にシューティングゲームを作ったり(砲台は戦闘機の替りに何故か女の子)、耳コピの「かえるのうた」を音の制御で鳴らして口パクで歌う女の子たちのアニメーションを作ったり(表情や髪型、足の微妙な動きなど、芸が細かい)、好きなように想像して、好きなように作っていた。保育園に通う息子は、書籍は読めないけど、Scratchで絵を描いたり、プログラムの部品をいじることはできるので、やはり多様な想像力を働かせて、大人では考えつかないようなスプライトを作り、回転させたり、大きくしたり、音を鳴らせたりして、楽しんでいた。

これはたった一日の出来事だ。子供の吸収力は凄いと感心させられる。以前、「Scratchで素数を求めてみた」というブログ記事で、Scratchによるプログラミングが子供の頃に遊んだレゴブロックみたいで楽しいと述べたのだが、その楽しさを表現する能力についてはやはり現役の子供には敵わなかったようだ。それにしても、子供たちが描いた絵が思うさまに動いているのを見ると、自分が子供の頃にもScratchがあったらなぁ、とつくづく思ってしまう。当時、自分で絵を描いたり、ブロックを組み立てたりすることだけでも楽しかったのに、それを好きなように動かせることができたのなら本当にワクワク・ドキドキしたことだったろう。

今回一つ思ったことは、子供たちには最小限のことだけを教えておいて、後は子供たちだけで何とかさせるというスタンスがとても良さそうであるということだ。疑問に思ったことは試行錯誤で解決しようとするし、それでも分からなければ本で調べる。ネットで調べてもいいのだけど、Scratchは日本語のまとまった資料が少ないのでそれが難しい。今後、多くの子供たちにScratchに触れてもらい、たくさんの人たちにScratchを知ってもらいたい。

以下に、参考サイトを挙げておく。

Scratch公式サイト - 想像・プログラム・共有
子どもたちがOSS活動、プログラミング言語「Scratch」が開く未来
非プログラマのためのプログラミング講座
こどもプログラミングサークル‘スクラッチ’
小学生にプログラミングの楽しさを伝えてみた

最後に、娘の作ったScratchプログラムの一つを載せておく。スペースキーを押せば始まるが、音が出るので注意して欲しい。

このプロジェクトについてもっと知る

続きを読む...

2010年3月7日日曜日

Google Wave Robots API v2でボットを書き直してみた

このブログ記事をはてなブックマークに追加

先日、Google WaveRobots APIバージョン2がリリースされた。更新内容の概要は「Google Wave Robot API v2のリリースエントリを翻訳しました」が分かりやすい。そこで、以前に作成した「てめーはおれを怒らせた」ボットをバージョン2のAPIで書き直してみることにした。しかし、すぐに修正できるだろうとナメていたら意外と時間が掛かってしまった。

初っ端でいきなり動かない。ほとんどチュートリアルと同じ程度に削っても動かない。エラーを頼りにAPIのソースコードなどを読んだりしているうちに、自分のプログラムの問題ではないんじゃないかと思い、動作確認していた環境をSandboxからPreviewに変更してみたら、問題なく動くようになった。ここでかなりの時間ロス。さらに、インターフェースも大きく変わっていて、新しいAPIでどのように実装するのか調べるだけでも結構時間を取られた。

書き直したソースコードは以下の通り。本当にこれで良いのか自信はないが、ちゃんと動作するようだ。因みに、ボットのアカウントはbillowlet@appspot.comだ。Google WaveのContactsパネルから登録すれば使うことができる。

慣れていないので手こずってしまったが、以前のバージョンに比べて、できることは増えているし、APIの構成も分かりやすくなっている。それに、ちゃんとGoogle Wave Robot Python API v2のドキュメントが整備されているのが嬉しいところ。何か面白いボットを作ってみたいな。

追記(2010/3/15):

Sandboxでも正常に動作するようになったみたい。

billowlet.py

#!/usr/bin/env python # -*- coding: utf-8 -*- """billowlet.py by nox, 2010.3.6""" import re, urllib, urllib2, random from google.appengine.ext import db from waveapi import events from waveapi import robot from waveapi import blip from waveapi import appengine_robot_runner from waveapi import simplejson HIRAGANA = u"あいうえおかきくけこさしすせそたちつてとなにぬねのはひふへほまみむめもやゆよらりるれろわをん" KATAKANA = u"アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワヲン" class UserData(db.Model): user = db.StringProperty(multiline=False) status = db.StringProperty(multiline=False) def OnWaveletParticipantsChanged(event, wavelet): participants = event.participants_added for participant in participants: if participant != "billowlet@appspot.com": wavelet.reply(u"%s、おれを怒らせるなよ。" % participant.split("@")[0]) def OnWaveletSelfAdded(event, wavelet): wavelet.reply(u"おれはbillowlet。よろしくな。") def Translate(text, from_lang, to_lang): url = "http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=%s%%7C%s" % (urllib.quote(text.encode("utf-8")), from_lang, to_lang) data = simplejson.loads(urllib2.urlopen(url).read()) return data["responseData"]["translatedText"] def BeCat(text): text = re.sub(u"。", u"にゃ。", text) text = re.sub(u"?|\?", u"にゃぁ?", text) text = re.sub(u"!|\!", u"にゃっ!", text) text = re.sub(u"な", u"にゃ", text) if text[-1] not in (u"。", u"?", u"?", u"!", u"!"): text += u"にゃ" return text def DotMarks(text): from_kana = u"かきくけこさしすせそたちつてとはひふへほカキクケコサシスセソタチツテトハヒフヘホ" to_kana = u"がぎぐげござじずぜぞだぢづでどばびぶべぼガギグゲゴザジズゼゾダヂヅデドバビブベボ" for f, t in zip(from_kana, to_kana): text = text.replace(f, t) return text def Laugh(text, ch): for i in range(len(text), 0, -1): text = text[:i] + ch + text[i:] return text.replace(u"。", u"").replace(u"、", u"") + ch * random.randint(3, 10) def Kana(idx): return HIRAGANA[idx] + u"|" + KATAKANA[idx] def OnBlipSubmitted(event, wavelet): blp = event.blip user = blp.creator opq = wavelet.get_operation_queue() data = UserData.all().filter("user =", user).get() if data: status = data.status else: status = None text = blp.text.strip() if status and re.match(u"ごめんなさい|ゆるして", text): json = opq.blip_create_child(blp.wave_id, blp.wavelet_id, blp.blip_id) child_blp = blip.Blip(json, wavelet.blips, opq) child_blp.append(u"ゆるしてやる。やれやれだぜ。".encode("utf-8")) if data: data.delete() st = (u"ネコになれ。", # 0 u"英国紳士になれ。", # 1 u"台湾に住め。", # 2 u"インチキ日本人になれ。", # 3 u"大事なことは2回言え。", # 4 u"笑え。", # 5 u"濁れ。", # 6 u"逆さまになれ。", # 7 u"どもれ。", # 8 u"うざくなれ。") # 9 fn = {st[0]: BeCat, st[1]: lambda (text): Translate(text, "ja", "en"), st[2]: lambda (text): Translate(text, "ja", "zh-TW"), st[3]: lambda (text): Translate(Translate(text, "ja", "en"), "en", "ja"), st[4]: lambda (text): text + text + u"\n大事なことなので2回言いました。", st[5]: lambda (text): Laugh(text, u"w"), st[6]: DotMarks, st[7]: lambda (text): text[::-1], st[8]: lambda (text): (text[0] + u"、") * 3 + text, st[9]: lambda (text): Laugh(text, u"っ")} angry = range(len(HIRAGANA)) random.shuffle(angry) if status: text = fn[status](text) blp.range(1, len(blp.text)).replace(text.encode("utf-8")) else: userdata = UserData() for i in range(len(st)): if re.search(Kana(angry[i]), text): status = st[i] break if status: json = opq.blip_create_child(blp.wave_id, blp.wavelet_id, blp.blip_id) child_blp = blip.Blip(json, wavelet.blips, opq) text = u"てめーはおれを怒らせた。%s" % status child_blp.append(text.encode("utf-8")) userdata.user = user userdata.status = status userdata.put() def main(): myRobot = robot.Robot("billowlet", image_url="http://billowlet.appspot.com/assets/icon.png", profile_url="http://billowlet.appspot.com/") myRobot.register_handler(events.WaveletParticipantsChanged, OnWaveletParticipantsChanged) myRobot.register_handler(events.BlipSubmitted, OnBlipSubmitted) myRobot.register_handler(events.WaveletSelfAdded, OnWaveletSelfAdded) appengine_robot_runner.run(myRobot) if __name__ == "__main__": main()

続きを読む...

2010年3月1日月曜日

AndroidからPythonでTwitterに投稿する

このブログ記事をはてなブックマークに追加

AndroidにASE (Android Scripting Environment)を入れてから楽しくてちょくちょくいじっているのだけど、Pythonに初めからtwitterモジュールが入っていることに気が付いたので使ってみた。

普段はAndroid端末(HT-03A)のTwitterクライアントとしてTwidroidを使っているのだけど、最初の立ち上げでタイムラインを取得しに行くのでちょっとだけ待たされる。あまり気にはならないけど、つぶやきをサクっと投稿したいだけならタイムライン取得は無駄なので、投稿専用のスクリプトを組んでみることにした。以下がそのコードだ。起動するとダイアログが出るのでつぶやきを書いて送信するだけだ。送信が完了したら画面に投稿したつぶやきが表示されて終了する。

# -*- coding: utf-8 -*- import android, twitter droid = android.Android() t = droid.getInput(u"Tweet", u"いまどうしてる?")["result"].strip() if t: api = twitter.Api("username", "password") api.PostUpdate(t) droid.makeToast(t)

これはすべてAndroid上でコーディングしたものだ。短いし、せいぜい数分もあれば書ける。書き終わったらそれをそのままホーム画面にショートカットアイコンとして登録すればいい。他にも、bit.lyのAPIを使って短縮URLを実装したり、サービスとして起動させ、特定のキーワードに引っかかったときにAndroidに通知させたり、メールを送信させたりすることも簡単だろう。やはり、スクリプトが使えるといろいろできて面白いな。

続きを読む...