スキップしてメイン コンテンツに移動

投稿

2010の投稿を表示しています

ある重さを量るのに使う錘の組み合わせは何通り?

問題: 1, 5, 10, 50, 100, 500グラムの6種類の錘があります。それぞれの錘はいくつでも使うことができます。ある重さを量るときに使う錘の組み合わせは何通りになりますか。それを求めるプログラムを書いてください。ここで量る重さはグラム単位の整数とし、最大で100キログラムとします。10グラムの重さを量る場合、10グラムの錘が1個、5グラムの錘が2個、5グラムの錘1個と1グラムの錘が5個、1グラムの錘が10個の組み合わせになり、全部で4通りとなります。

以下、解答例。

weights.cpp

// 指定した重さを量るのに使う錘の組み合わせの数を求めるプログラム. // 錘は 1g, 5g, 10g, 50g, 100g, 500g の6種類. // 重さ 700,000g 程度までなら桁あふれせずに計算できる. #include <iostream> #include <map> #include <algorithm> #include <cstdlib> using namespace std; const int weights[] = { 1, 5, 10, 50, 100, 500 }; // 錘(昇順). const int N = sizeof(weights) / sizeof(int); // 錘の種類.// 求めた錘の組み合わせの数のメモ. // 下位3ビットは使用する錘(solveのidx)を表す. // 残りのビットは重さ(solveのv)を表す. map<int, unsigned long long> memo; // 指定した重さに対する錘の組み合わせの数を求める. // v : 重さ // idx : 使用する錘 // N-1の場合はweights[0]からweights[N-1]までの錘を使用する(すべての錘). // 2の場合はweights[0]からweights[2]までの錘を使用する(1, 5, 10の錘). // 戻り値: 組み合わせの数 unsigned long long solve(int v, int idx=N-1) { // 既に計算済みであるならその結果を返…

Android端末による自動通訳を一行のPythonコードで実装する

最近このブログではAndroidのSL4Aネタが多いのだけど、それだけ遊べるのだから仕方がない。SL4AのPythonを使えば実質一行で自動通訳プログラムを作ることもできる。日本語で喋った文章が翻訳されて英語の音声で返ってくる。

import android,urllib,urllib2,simplejson;droid=android.Android();droid.ttsSpeak(simplejson.loads(urllib2.urlopen('http://ajax.googleapis.com/ajax/services/language/translate?v=1.0&q=%s&langpair=%s%%7C%s'%(urllib.quote(droid.recognizeSpeech().result.encode('utf-8')),'ja','en')).read())['responseData']['translatedText'])

このプログラムでは日本語を英語に変換するが、コード中の en を変更すれば別の外国語に通訳することもできる。例えば fr に変更すればフランス語に通訳される。ただし、通訳した外国語はGoogleによる翻訳の精度に依存するので、実用的に用いるにはもう少し精度が良くなって欲しいところだ。それでもこれだけ簡単に自動通訳プログラムを作れるのだからAndroidとSL4Aは大したものだと思う。

以下にもう少し分かりやすいコードを示しておく。ついでに翻訳結果をダイアログに表示するように変更してある。

translator.py

# -*- coding: utf-8 -*- import android,urllib,urllib2,simplejson def translator(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(…

SL4AのPythonを使ってAndroid端末に日本語を喋らせてみた

先日、ドコモのGALAXY Sを購入した。丁度1年前に購入したHT-03Aからの機種変更になる。Androidのバージョンは1.6から2.2となり、性能は格段に良くなった。この1年での技術の進歩には驚かされる。GALAXY SでSL4Aが利用できるかは気になるところだが、実は購入する前に既に動作することを確認していたので、その点については心配なかった。もしSL4Aが使えなかったら、多分購入しなかったと思う。

この新しいAndroid機を使って、SL4AのPythonで日本語を喋らせてみることにした。英語であればttsSpeakのAPIを使えば一発なのだが漢字かな混じりの日本語では簡単には行かない。まずは日本語の発音を取得しなくてはならないが、それについてはYahoo! デベロッパーネットワーク日本語形態素解析を使うことにした。これなら助詞の「は」も「わ」という発音であることがわかるし、後々、応用が効くだろう。

作成したソースコードは最後に示してあるが、短いコードで簡単に実装できた。使い方も簡単で、入力ダイアログから喋らせたい文章を入力するだけだ。それを形態素解析のWeb APIでXMLとして取得し、Beautiful Soupで解析している。取得した平仮名をその発音に近い英語に直すだけだ。ローマ字に置き換えるだけでは日本語として正しく発音されないので、適当にいじってある。

実用的なプログラムにしたければ、Galatea Projectなどを利用して、ちゃんとした日本語を喋らせるようにしたほうが良いのだろうけど、形態素解析を使ってみたかったし、英語を無理やり日本語にするところも面白かったので、今回はこれで良しとした。やっぱり自分が楽しめないとね。

例によって、このプログラムを使って子供相手に遊んでみた。元の文章を知っていれば問題なく聞き取れるのだが、知らないと思ったよりも聞き取れないことを逆手に取って、何を喋っているかを当てるゲームをしてみた。こんな単純なことなのだが、子供たちは思いのほか楽しんでいたようだ。インチキ外国人ぽい雰囲気が面白いらしい。

作成したソースコードは以下の通り。

speak_ja.py

# -*- coding: utf-8 -*- import android import sys,os,urllib,urllib2 from B…

Android端末上に電子掲示板システムを構築する方法

最近になって日本においてもAndroid端末が続々と発表されて巷で賑わいを見せている。ドコモからはGALAXY S、auからはIS03、ソフトバンクからはDesire HDと立て続けに発売される。このほかにも年末までにタブレット端末を含めた複数のAndroid端末が発売されるようで結構なことだ。


Androidも盛り上がってきたし、Android端末を使って手軽で役に立つことができないか考えてみた。そこで今回、Android端末をウェブサーバにして、そこに電子掲示板システム(BBS)を構築してみた。これさえあれば不意にプライベートなBBSを使いたくなったときにいつでも利用することができる。たとえばライトニングトークやセミナーなどのようなイベントの参加者からその場でちょっとしたアンケートや感想を貰いたいときに便利ではないかと思う。ちょっとした話題作りにもなるかも。

電子掲示板システムの作成に必要なものはAndroid端末とSL4A/Pythonだけ。あとは今回作成した android_bbs.py を使えばいい。そして、SL4Aを使ってサーバを立ち上げてから、android_bbs.pyを起動すれば完了だ。SL4Aによるサーバの起動方法とアドレス取得についてはPythonを使ってAndroid端末を5分でリモートカメラにする方法で書いたのでそちらを参考にして欲しい。

今回の電子掲示板システムはPythonを使って即席で作ったこともあってエラー処理などを入れずに30行ちょいのシンプルな作りになっている。sqlite3モジュールによるSQLiteデータベースで記事を管理し、wsgiref.simple_serverモジュールを使ってウェブサーバ構築した。簡単だ。ただ、Android独自の機能は使っていないのでAndroid端末専用というわけではないけど。Android独自の機能を入れるとしたら、たとえばTwitterなどの投稿者の位置情報表示に対抗して、投稿者ではなくサーバの位置、さらに向きや速度も一緒に表示されるようにするとか。誰得な機能だけど。

以下にソースコードを示す。

android_bbs.py

# -*- coding: utf-8 -*- import cgi,sqlite3,datetime from wsgiref.simple_server im…

Pythonを使ってAndroid端末を5分でリモートカメラにする方法

Android端末をリモートカメラにしてしまう方法「Spycam」という記事経由でTurn your Android Phone Into a Remote Spy Camera with Ruby in 15 Minutesを知った。SL4AのJRubyを使ってAndroid端末を15分で遠隔操作のスパイカメラにしてしまえるらしい。これは面白い。そこで、Rubyが15分ならPythonを使って5分でリモートカメラにしてしまおうと思い立った。

まず、Pythonでは標準モジュールのSimpleHTTPServerやwsgiref.simple_serverを使って簡単にWebサーバを構築することができる。そしてSL4Aを使えばAndroid端末をそのままサーバとして起動させることができる。これを組み合わせればできたも同然だ。

それで書いたのが以下のコードだ。10行そこそこでAndroid端末をWebサーバに仕立て上げ、Webブラウザ経由で写真を撮ることができる。こんなちっこい端末がWebサーバになるなんて世の中進歩したものだ。

remote_camera.py

import android from wsgiref.simple_server import make_server droid=android.Android() pic='/sdcard/snapshot.jpg' def camera(env,res): if env['PATH_INFO']=='/': droid.cameraCapturePicture(pic) res('200 OK',[('Content-type','image/jpeg')]) return [file(pic).read()] httpd=make_server('',9998,camera) httpd.serve_forever()

使い方は次の通り。まず、SL4Aを起動し、メニューボタンから"View"を選ぶとダイアログが出てくるので"Interpreters"を選択する。


再度、メニューボタンから今度は"…

Android端末で青空プログラミング! SL4Aの導入からアプリケーションの作成・公開まで

以前、Android上でPython、Lua、JavaScriptなどを実行するスクリプティング環境ASE (Android Script Environment)について記事にした。現在ASEはSL4A (Scripting Layer for Android)に変更され、機能がさらに進化している。APIの充実やインターフェイスの改良、スクリプト環境は独立になり、HTMLインタプリタ導入やAndroidパッケージ(APK)の作成などもできるようになった。そこで改めてSL4Aのインストール方法、使い方、Pythonによるアプリケーションの作成、QRコードによるソースコードの公開方法などを紹介する。

導入

まず、SL4Aの公式サイトで最新版のSL4Aをダウンロードする。現時点ではsl4a-r2.apkだが、頻繁に更新されるので注意すること。さらに必要なスクリプト環境をダウンロードする。BeanShell, JRuby, Lua, Perl, Python, Rhino (JavaScript)などがあるが、ここではPythonを選んだ。現時点での最新版はpython_for_android_r1.apkになる。SL4Aとスクリプト環境は独立しているのでそれぞれをインストールする。

これらのAndroidパッケージは公式のものではないので、ダウンロード後インストールするためには、Android端末の設定で「アプリケーション」の「提供元不明のアプリ」にチェックを入れておく必要がある。


これでSL4AでPythonを使用するための準備は整った。

スクリプトの作成

SL4Aをインストールすると左のようなアイコンが出てくるのでそれをタップして起動する。Pythonスクリプトファイルの作成するには、メニューボタンから"Add"を選択し(スクリーンショット左側)、表示されるダイアログから"Python"を選ぶ(スクリーショット左から2番目)。そうすると、Pythonスクリプトの雛形を伴った編集画面になるので(スクリーンショット中央)、それを更新して作成する(スクリーンショット右から2番目)。ファイル名は自由に付けることができ、作成したスクリプトファイルは"Save & Run"ですぐに起動できる(スクリーンシ…

アルゴリズムの素晴らしさに気付かせてくれたのはエラトステネスの篩だった

Haskellによるエラトステネスの篩(sieve of Eratosthenes)の美しい実装を見て、初めてアルゴリズムの素晴らしさに気付かせてくれたのがエラトステネスの篩だったことを思い出した。たしか中学生の頃だ。そこで、当時を懐かしみながら簡単な実装を書き留めておくことにした。とりあえず、Haskell, C++, Pythonの実装を以下に示す。コードは比較的短いが、実行効率を優先させているわけではない。

Haskell

これはHaskellのサンプルコードでよく出てくる無限リストと遅延評価による実装だが、とても分かりやすいし、美しいコードだと思う。

primes = sieve [2..] sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0]

以下のように関数takeを使って必要な分だけ素数を取り出すことができる。ただし、実行効率はあまり良くない。

take 10 primes [2,3,5,7,11,13,17,19,23,29]

C++

次にC++を使って実装してみた。ここではC++0xを使っている。そのほうが簡潔で分かりやすく書けるし、これからはC++0xがより使われ、普及して欲しいという意味もある。因みにgccではバージョン4.5以降、Intelコンパイラではバージョン11.0以降、Visual C++では2010(16.0)以降でコンパイルできる。

std::vector<int> primes; for (int i = 3; i < 100; i += 2) primes.push_back(i); auto end = primes.end(); for (auto x = primes.begin(); *x * *x <= *(end-1); ++x) end = std::remove_if(x + 1, end, [&x](int p){ return p % *x == 0; }); primes.erase(end, primes.end()); for (auto p = primes.begin(); p != primes.end(); ++p) std::cout << *p << "…

Pythonワンライナーで数独を解いてみた

GIGAZINE数学のエキスパートが3ヶ月かけて作成した「世界一難しい数独」なるものがあったので、即席でPythonワンライナー(一行プログラム)を作ったら1秒かからず解けた。問題を作るのは大変でも解析プログラムで一瞬とは儚い。

python -c "import sys;L=[];S=lambda D:(0in D)and[L.append(D.index(0)),[(D.__setitem__(L[-1],i),S(D),D.__setitem__(L.pop(),0))for i in set(range(1,10))-set(D[L[-1]/9*9:L[-1]/9*9+9]+D[L[-1]%9:81:9]+[d for n in(0,1,2)for d in D[L[-1]/27*27+L[-1]%9/3*3+n*9:L[-1]/27*27+L[-1]%9/3*3+n*9+3]])]]or([sys.stdout.write('%d'%d+('\n'if i%9==8 else' '))for i,d in enumerate(D)],sys.exit());S([int(c)if c!='.'else 0for c in'..53.....8......2..7..1.5..4....53...1..7...6..32...8..6.5....9..4....3......97..'])"

コードの最後のリスト内の文字列が9行9列の数独の問題となっていて、上の行の数字から順に入っている。未知の部分はドット(.)で表している。上記のコードではGIGAZINEの問題となっている。

因みにPythonによるもっと効率の良いアルゴリズムについてはSolving Every Sudoku Puzzleが参考になるかも。

以下、ワンライナーによる出力結果。

1 4 5 3 2 7 6 9 8 8 3 9 6 5 4 1 2 7 6 7 2 9 1 8 5 4 3 4 9 6 1 8 5 3 7 2 2 1 8 4 7 3 9 5 6 7 5 3 2 9 6 4 8 1 3 6 7 5 4 2 8 1 9 9 8 4 7 6 1 2 3 5 5 2 1 8 3…

日本全国ハンバーガーショップ分布地図

以前、Processingを使って日本全国のコンビニ店舗の分布地図を作成したが、今回はハンバーガーショップの分布地図を作成してみた。

個人的にハンバーガーショップには小さい頃から思い入れがあって、小学生の頃、初めてマクドナルドのハンバーガーを食べたときに「なんて美味しいんだろう」と感動した覚えがある。しかし、今でこそ安価な食べ物という認識だが、当時は他の食べ物に比べて割高であまり頻繁に食べられなかった。

その後はだんだんとハンバーガーから離れていったが、モスバーガーと出会ったときに二度目の感動を覚えた。冷たくてジューシーな野菜と熱々のハンバーグが絶妙にマッチしてそれまで食べたことのないハンバーガーだった。少々食べにくくはあったが、逆にそれが溢れる美味しさを表現していたようにも思う。

最近気に入っているハンバーガーは、アトレヴィ 秋葉原2階にあるChelsea Marketのアボガドバーガーだ。少々値は張るが、普通のチェーン店に比べて味は飛び抜けていると思う。チェーン店ではないハンバーガー専門店なら他にも美味しいハンバーガーがいろいろとありそう。

閑話休題。以下に作成したプログラムを示す。



左上の店名をクリック: 分布の表示・非表示を切り替える。起動時はマクドナルドのみ表示。 右クリックしたままマウス移動: 地図を平行移動する。 左クリックしたままマウス上下移動: 地図を拡大・縮小する。

プログラムの作成方法は前回のコンビニ店舗分布地図を作成した方法とほとんど変わらない。まず、住所をネットから取得する。それをGoogle Maps APIで緯度経度変換し、さらにPythonスクリプトでUTM図法に合わせてXY座標変換する。そのデータをtar/gzipでアーカイブし、Processingを使って読み込み、日本地図に表示する。ブログへの貼り付けはProcessingでJavaアプレットにエクスポートできるのでそれを使う。

今回の分布地図を見て、マクドナルドよりもかなり後に出てきたモスバーガーの店舗が思ったより多く、全国的に展開していて驚いた。また、子供の頃に食べた森永LOVEは既に存在せずロッテリアに買収されたことも今回作成する過程で知った。他には東京に最近出現してきたバーガーキングや沖縄のみに存在するA&Wがやや気になった。沖縄のA&Wへは簡…

2次元セルオートマトンとエントロピー

2状態の2次元セルオートマトン(Cellular Automaton)をActionScript 3.0 (AS3)で作ってみた。2次元セルオートマトンで最も有名なのはライフゲーム(Conway's Game of Life)だろう。プログラムでは初期ルールをライフゲームとしている。初めにC++で書こうと思ったのだけど、Web上でグラフィカルに操作できないとつまらないと思い、AS3でFlashとして作成しwonderflに登録することにした。ついでに時間的なエントロピー変化を視覚的に認識できたら面白そうだと思ったので、それについても実装した。

今回、セルオートマトンのコードを書こうと思ったのはTCO Marathon Round 2の問題として出されたからだ。2次元セルオートマトンのサイズと初期配置、それにルールが与えられ、指定した世代で生存セルが最大になるように初期配置を変更しろという問題だ。そして、問題を解くために色々と調べているうちにセルオートマトンが面白く感じられたのでブログ記事にしてみた。とは言っても今回のコードはコンテストのような特別なチューンなどはしていない。ビット配列や剰余テーブルなどは使っているがどちらかというと読みやすさを優先させている。

作成したプログラムを以下に示す。

Cellular Automaton - wonderfl build flash online
1-9 : ルール設定 - セルの周りの生存セル数(0-8)に対応 : '.' 死亡, '&' 変化, '+' 誕生, '=' 維持 SPACE : 一時停止 ENTER : リセット V : メッセージ表示/非表示 Z : 初期生存セルの割合を減少 X : 初期生存セルの割合を増加

最初に実行されるルールはライフゲームだ。つまり、セルの回りに2つの生存セルがあった場合、そのセルは現状「維持」となり、3つの生存セルがあればそこに生存セルが「誕生」する。生存セルが1つ以下か4つ以上の場合は死亡セルとなる。また、上端と下端、右端と左端は繋がっていて周期境界条件となっている。現在のルール設定はFlash画面の左下に[..=+.....]と表示される。[]内の9つの文…

小学3年生の授業参観でアルゴリズムに出会った

小学3年生の娘の日曜授業参観に行ってきた。算数の授業だ。授業の後半、以下のような問題が出された。

問題: ゴマダラチョウとトノサマバッタがあるゲームをしている。0から9までの数字の書かれたカードがそれぞれ一枚ずつ全部で10枚あって、それを使って3桁の数を2つ作り、その差をできるだけ小さくした方が勝ちとなるゲームだ。ただし百の位は0にできない。できるだけ小さくするにはどのようにカードを選べばよいだろうか。

これを約30人の生徒に考えさせていた。解き方を先に教えるということはしない。生徒が問題を考えている間、先生は生徒たちを見回り、質問などに答える。しばらくするといろいろと答えが挙がってきた。自分の娘は以下のように考えたようだ。

百の位は差が1であればどの数字でも良いので、まず十の位を最小にする数字を考えてみると、最小の数字0から最大の数字9を引いた場合が最も小さくなる。同様に一の位では0と9以外の最小・最大の数字を選ぶ。つまり1から8を引いた場合が最小になる。百の位は残りの数字カードから差が1となるものを選ぶ。解答例は「501-498」や「701-698」となり、差は3になる。

これはまさにアルゴリズムだ。Pythonであれば以下のコードと同じだろう。

digits = range(10) ten = (digits.pop(), digits.pop(0)) one = (digits.pop(), digits.pop(0)) idx = random.randrange(len(digits) - 1) hund = (digits.pop(idx), digits.pop(idx)) a = reduce(lambda x, y: x * 10 + y, map(array, (hund, ten, one))) print "%d - %d = %d" % (a[1], a[0], a[1] - a[0])

出力例:

601 - 598 = 3

小学3年生の算数だと思ってそれほど期待せずに観に行ったのだが、生徒たちはみな楽しそうに問題に取り組んでいたし、なかなか面白い授業をしているようで何だか安心した。因みに、今回のようなクラス全員で考える問題は普段からよく行っているとのことだった。

スーパーコンピュータとプログラミング言語

世の中には星の数ほどのプログラミング言語があるかもしれないが、スーパーコンピュータで利用するとなるとかなり限られてくる。ライフサイエンス分野のデータの処理にはPython、Ruby、Perlなどのいわゆるスクリプト言語はよく使われるし、データベース関連だとJavaなどもあるだろう。しかし科学技術計算に限れば、FortranやC/C++が多数を占めると思う。やはり実行効率と既存資産の存在は大きい。

数値計算プログラムでは、とにかく速さが求められる。どれだけの速さがあれば十分かだって? この質問はナンセンスだと思う。たとえ現在の最高速度を誇るスーパーコンピュータの1億倍の速度があったとしても十分ではない。使える資源でできる範囲の計算をするだけなのだから。

自分の携わる分野では一回の計算に半年かかることもざらなので、計算速度は死活問題だ。1分で終わる処理なら倍に高速化したとしても差は30秒でしかない。しかし、半年となるとその差は3ヶ月にもなる。だから、Fortranを使うにしても、よりモダンなFortran90/95だけではなく、古めかしいが実行速度の速いFORTRAN77もよく使われる。まあ、最近は速度差も縮まってきているのでそこまでFORTRAN77にこだわらなくなってきているけど。本当にクリティカルな部分にはアセンブリ言語なども使われている。

また、汎用コンピュータのコンパイラに比べてスーパーコンピュータに最適化されたコンパイラではバグの入っていることが多く、C++でもBoostなどの外部ライブラリは避けた方が無難だ。使うにしてもGoogleのC++コーディング規約のように一部に限定して使う方が良い。実際にBoost絡みのコンパイラバグによる混乱を見るに、STLなどの標準ライブラリのみをシンプルに利用していた方がまだ安全だ(それでもバグるけど)。そうは言ってもBoostは便利なのでできるだけ早くC++0xの標準化がされてほしい。標準化されていればコンパイラベンダも言い訳できないしね。

そういえばFortressなんて言語もあるね。面白い試みではあるけれど現状で利用するのは難しいような気がするなぁ。特に冒頭でも述べた、Fortranと同程度の実行効率が出せるかという点と既存資産の代替が存在するのかという点で。因みにFortressでの"Hello, …

OAuthを使ってAndroidからPythonでTwitterに投稿する

以前、ASE (Android Scripting Environment)を使って「AndroidからPythonでTwitterに投稿する」という記事を書いたが、来月末にTwitterのBASIC認証が廃止されるので使えなくなる。そこで、OAuthを利用するコードに書き直してみた。最近はAndroidのtwiccaがとても使いやすいのでPythonスクリプトによるTwitterへの投稿もあまりないかもしれないが、Android端末単体でOAuthを利用したTwitterの認証ができることを示す意味でも公開することにした。

まず、「コマンドラインで動作するOAuth対応TwitterクライアントをPythonで作ってみた」という記事で用意したoauth.pyとoauthtwitter.pyをAndroid機の/sdcard/ase/scripts/ディレクトリにコピーする。これはadb pushでコピーしてもいいし、SDカードに直接コピーしてもいい。oauthtwitter.pyは一部修正してあるので上述記事の該当箇所を参照して書き直して欲しい。

次に、それらのライブラリを利用して以下のようなコードを書いた。赤字で示した認証コードの部分はTwitterのサイトのOAuthクライアント登録で取得する必要がある。

tw_oauth_ase.py

#!/usr/bin/env python # -*- coding: utf-8 -*- import os, pickle, time, android from oauthtwitter import * CONSUMER_KEY = "CONSUMER_KEY" CONSUMER_SECRET = "CONSUMER_SECRET" KEY_FILE = "/sdcard/ase/scripts/twitter_key.dat" droid = android.Android() def twitter(): if os.path.isfile(KEY_FILE): access_token = pickle.load(file(KEY_FILE)) else: tw = OAuthApi(CONSUMER…

C++0xでYコンビネータ

stackoverflow.comFixed point combinators in C++ (C++による不動点結合子)に載っていたC++とboostで書かれたYコンビネータ(Y combinator)のサンプルコードをC++0xを使って書き直してみた。C++0xだと標準ライブラリだけでこれだけ簡潔に書ける。

#include <iostream> #include <functional> using namespace std; // Y-combinator for the int type function<int(int)> y(function<int(function<int(int)>, int)> f) { return bind(f, bind(&y, f), placeholders::_1); } int main() { // Y-combinator compatible factorial auto fact = [](function<int(int)> f, int v){ return v == 0 ? 1 : v * f(v - 1); }; auto factorial = y(fact); cout << factorial(5) << endl; return 0; }

一行でテキストに含まれるURLをすべて短縮URLに変換するPythonスクリプト

テキストに含まれるURLをすべてbit.lyの短縮URLに変換するPythonワンライナーを書いた。使用しているモジュールはre、urllib、urllib2、simplejson。コードに一行追加するだけだし、Twitterなどのメッセージを処理するのに便利だと思う。

for link in sorted(re.findall(r"(http(?:s?)\:\/\/(?!bit\.ly[\/\ ])[^\/\ ]+\/?.*?)(?:[\ <>\"\{\}\|\\\^\[\]\`]|$)", msg), reverse=True): msg = (lambda x: re.sub(re.escape(x), (lambda y: str(simplejson.loads(urllib2.urlopen("http://api.bit.ly/shorten?version=2.0.1&longUrl=%s&login=BITLY_ID&apiKey=BITLY_API_KEY" % urllib.quote(y)).read())["results"][y]["shortUrl"]))(x), msg))(link)

bit.lyのAPIキーは別途取得しておく必要がある。

msg = u"ここのブログのURLはhttp://handasse.blogspot.com/ です。記事のURLはhttp://handasse.blogspot.com/2010/05/urlurlpython.html です。"

としてURLを含むメッセージを処理すると以下のように変換される。

print msg ここのブログのURLはhttp://bit.ly/PQa9F です。記事のURLはhttp://bit.ly/cVRVu6 です。

上記のコードを展開したものが以下のコード。簡単なエラー処理を追加してある。

def bitly(x): try: data = urllib2.urlopen("http://api.bit.ly/shorten?version=2.0.1&longUrl=%s&am…

コマンドラインで動作するOAuth対応TwitterクライアントをPythonで作ってみた

6月末にTwitter APIのBASIC認証が終了してしまうので、OAuth対応のTwitterクライアントを作ってみることにした。とりあえず最もシンプルだと思われるコマンドラインで動作するクライアントをPythonで作成してみた。

まず、Twitterクライアントを作成する前に、TwitterのサイトでOAuthクライアントの登録を行わなくてはならない。ここで、「アプリケーーション名」、「アプリケーションの説明」、「アプリケーションのウェブサイトURL」を記入する必要がある。また、今回はPC上で実行するクライアントで読み書きを行いたかったので、「あなたの招待状」には「送信」、"Default Accdess type"には"Read & Write"を選択した。

登録を済ますと、"Application Details"のページで"Consumer key"と"Consumer secret"が与えられるので、これを作成するアプリケーションで利用する(CONSUMER_KEY, CONSUMER_SECRET)。

次にコーディングだが、できるだけ短くシンプルに作りたかったので、Python外部モジュールのtwitteroauthoauthtwitterを利用させてもらうことにした。ただ、作者のページのコードでは途中でエラーになってしまうので、 oauthtwitter.pyのOAuthApiクラスのgetAccessTokenメソッドの下に以下のgetAccessTokenWithPinメソッドを追加した。

def getAccessTokenWithPin(self, pin, url=ACCESS_TOKEN_URL): token = self._FetchUrl(url, parameters={"oauth_verifier": pin}, no_cache=True) return oauth.OAuthToken.from_string(token)

今回作成したTwitterクライアントの使い方だが、

tw.py

で最新のタイムラインを表示する。取得件数はここでは20件にしているが、ソースコー…

Google App EngineとSafe Browsing APIを利用して短縮URLチェッカーを作ってみた

最近、Twitterやはてなブックマークなどを使うことが多くなり、字数制限付きのコメントを書くことが増えた。コメント中にURLを入れたいこともままあるのだが、長いURLだと字数をオーバーしてしまう。そのため短縮URLを使っているが、コメント内に直接短縮URLを入れるのがやっかいだった。そこで、Google App Engine (GAE)を使ってシンプルで高速な短縮URL変換ツールを作成してみた。

しかし、短縮URLは悪意のあるサイトの判別が難しいという欠点がある。見た目で判断できないので開くのを躊躇してしまう。そこで、今回作成したツールでは、短縮URLに変換するだけではなく、それを元のURLに戻す機能も追加した。さらに、Google Safe Browsing APIを利用してフィッシングサイトなどの悪意あるサイトの判別も試みている。

短縮URLチェッカー

使い方はシンプルで、テキストボックスに変換したいURLを入力すればbit.lyの短縮URLがテキストボックス表示され、bit.lyの短縮URLを入力すればもとのURLが表示される。テキストボックスをクリックすれば表示されているURLが選択されるのでクリップボードへのコピーも簡単だ。テキストボックスの下には展開されたURLがリンク付きで表示されるが、もしフィッシングサイトだと疑われる場合は、以下のように警告してくれる。


さて、今回のコード作成だが、bit.lyによる短縮URLの変換は簡単だった。というのも以前にPythonスクリプトで作ったことがあるからだ。それをそのままGAEに載せればいい。しかし、Safe Browsing APIによる悪意あるサイトの検出は思ったよりも面倒だった。まず、APIの使い方がよく分からない。使う前は任意のURLをAPIで確認するのかと思っていたのだが、そうではなく、MD5でハッシュ化したリストをダウンロードして、調べたいURLをハッシュ化してそれと照らし合わせなくてはならない。今回問題になったのはそのダウンロード容量で、フィッシングサイト用データが700KB程、マルウェア用データが10MBを超えていた。GAEでは一回のダウンロード容量の上限が1MBと決まっており、フィッシングサイト用データは何とかダウンロードできても、マルウェア用データは途中で切れてしまった。仕方がないので今回…

一つのGoogle App Engineアプリケーションで複数のWaveボットを作成する

Google App Engine (GAE)では現在10個までのアプリケーションを登録することができる。そして、GAEを利用してGoogle Waveのボットを作成することができる。しかし、多種多様な利用方法が存在するWaveボットをGAEアプリケーションとして登録していてはすぐに上限に達してしまうだろう。そこで、一つのGAEアプリケーションで複数のWaveボットを作成するためのいくつかの方法を利用することになる。サブドメインを利用する方法が一般的だろうか。

しばらく前からサブドメインを利用して複数のWaveボットを作成しようと思っていたのだが、ちょっと面倒に思えて手を付けていなかった。そうしたら、technohippy氏によるappengine_multi_robot_runnerというライブラリが公開され、それがとても便利そうだったので簡単なWaveボットを作成してみた。ただし、Google Wave Robots API v2が3月30日にアップデートされて実装の一部が変更されたことにより、appengine_multi_robot_runner.pyがそのままでは動作しなかったので該当箇所を修正した。それについては最後に記述しておく。

追記(2010/4/15): 現在、appengine_multi_robot_runnerは最新版に更新されているので、後述の修正は必要無くなっている。

作成したのはインチキ日本語ボット(fake-japanese.robotic-wave@appspot.com)とインチキ英語ボット(fake-english.robotic-wave@appspot.com)の二つのWaveボットだ。インチキ日本語ボットでは、書き込んだ日本語を一度Googleにより英語に翻訳し、それを再度日本語に翻訳し直して表示する。インチキ英語ボットは、日本語を英語に翻訳したものを表示する。インチキと書いたが、特にでたらめにするために細工しているわけではない。現在の翻訳技術ではインチキっぽく見えてしまうというだけである。因みに、これらのボットのアイコン画像はAtnet Japan!を利用させてもらった。

どのように動作するか、以下の例文を実際に入力して動作を見てみよう。

「花便り」
「ここ数日は暖かな日が続いていますが、その後いかがお過ごしでし…

Android Scripting Environment (ASE) Python API簡易リファレンス

Android Scripting Environment (ASE)について、「Android上でPython、Lua、JavaScriptなどを実行するスクリプティング環境が凄い」で紹介した。今回はAndroid端末の機能を利用するためのPython APIの使い方をリファレンスとしてまとめてみた。Python 2.6の標準モジュールは最初から利用できる。また、twitterモジュールなど、いくつかの標準外のモジュールがデフォルトでインストールされている。詳細については利用する環境で確認して欲しい。

ASE上のPythonスクリプトの編集画面でメニューボタンを押し、そこから"API Browser"で簡単なリファレンスを読むことができる。また、ASEのWikiとしてWiki pages - android-scripting、サンプルプログラムとしてtest.pyが参考になる。

以下にASE Python APIの簡易リファレンスを示すが、APIのすべてを記しているわけではない。足りない部分については随時追加していく予定だ。

Androidモジュールを使用する

import android droid = android.Android()

現在のクリップボード取得と貼り付け

clip = droid.getClipboard()["result"] droid.setClipboard("Hello, world!")

GDataの使用

import gdata.docs.service client = gdata.docs.service.DocsService() # クライアント. client.ClientLogin(username, password) # 接続. feed = client.GetDocumentListFeed() # ドキュメントリストのAtomをフィード.

GPSで現在の位置情報を取得

droid.startLocating() # 開始. location = droid.readLocation()["result"] lat = location["network"]["latitude"] …

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の名前すら聞いたことがないというのだからそれも仕方が無いのだ…