pologでタグ development が指定されているエントリー

2008年07月27日

Oppai-Detect 2でコンテンツフィルタリング

ずいぶん前にOppai-Detectの精度向上っぷりをtwitterで見せてもらって、やべー使いてーなどと思っていたんですが、いつの間にか公開されてたので、クライアント側でプロキシ動作するフィルタを書いてみました。おっぱい見れません><

画面的にはこんな感じ。

2008年05月03日

会社周辺のレストラン情報をGoogle Earth上でだら見する

会社が白金台に引っ越しました。外苑前と比べると人がすごく少なかったり、オフィスの隣には都内有数の森があったり、窓からその森が見えたり、僕がその窓際に座っていたり、座って作業していると半径10mに人が1人もいなかったり(前のオフィスは30人くらいいた)して、かなりいい感じです。
そんなカッチョいいオフィスで社会と会社と己のマニーのために働いている僕ですが、先日社長が"カッチョいいディスプレイを会社のフロントに置くから、そこでなんかやってよ"などとおっしゃってまして、ちょっとしたデモを作ることにしました。

2008年03月31日

muxtapeに音声botを作った

http://kyoujin.muxtape.com/

全く何言ってんのかわかりませんがたまに'きほーんーてーきー'とか'そウCてーもぅUだーCta-'とか言い出して吹きます。
ソースは以下。

2008年02月17日

人工無能オフというのに行ってきた

人工無能オフというのに行ってきた
人工無能と言うのは要するにchat botで、チャットソフトやマイクロブログ上で動作して勝手に喋ったり返信したりするもの
僕が作った奴
http://twitter.com/kyoujin
http://twitter.com/yumeno
人工無能オフだと言うから前日に1時間で作った↓
http://twitter.com/DaDaDaJunji
他参加者
http://twitter.com/ha_ma
http://twitter.com/dabesa
http://twitter.com/medachon
http://twitter.com/meitanteikun
http://twitter.com/koc
予想はしてたけど自己紹介時に"どーも、きょうじんです""あ、ha_maなのよ"みたいなかなりカオスな感じ。嘘です。普通に名刺交換しました。

2008年01月30日

ライフゲームでグリッチ

昨日の続き。
なんで昨日いきなりライフゲームなんぞ実装したかと言うと、なんかglitchに使えそうだったからです。寝る前にふと思いついちゃいました。てなわけで今日ぐっちゃぐちゃになりましたけど、割と構造化を意識した感じのコードにしてたんです。コードグリッチ!
以下詳細。

2008年01月19日

きょうじんスクリーンセーバー

開発合宿中ですが、ふと理性がなくなって何となくきょうじんスクリーンセーバーをつくりました。ping 理性。
kyoujin.qtz
ダウンロードして、
システム環境設定>デスクトップとスクリーンセーバー>スクリーンセーバー
の画面にドラッグアンドドロップしてください。
mac only!

(追記)
あ、Leopard onlyだった。すみません。

2007年12月24日

数値をサーモグラフィーっぽく色変換する

先日"これスコアリングの結果わかりやすく見せらんないかな?"って社長とペアプロ時に言われて、オレオレ変換で色・サイズのタグクラウド作ったら色の方だけ速攻却下喰らった。超くやしい。
と言う訳でちょっと勉強がてら書いてみた。
今一適当なarticleが見つからなかったのでjQueryのHeatColor pluginの中身をそのまんま実装。

2007年12月20日

myminicityを核戦争後の世界みたいにする方法

myminicityがちょうおもしろくていろいろいじってます
では以下方法
1)Firebugが入ってるFireFoxでhttp://polog.myminicity.com/に行く
2)Firebugのconsoleに以下の内容を記述

$('client').style.display="none";var a=document.createElement('embed');a.width=600;a.height=400;a.flashvars="";a.type="application/x-shockwave-flash"; a.src="http://data.myminicity.com/swf/client.swf?v=0&name=polog&pop=1000000&ind=100000&tra=100000&sec=100000&env=100000&com=100000&k=3b8b1";a.allowscriptaccess="always";a.menu="false";a.name="client";a.scale="noscale";a.id="client";$('swf_client').appendChild(a);


3)実行

すると、大変なことに!!


2007年12月15日

漢字を類似度検索可能にする

アイデアとしては単純で、画像情報に落としたあとで全漢字pairに対して全pixelの一致数をカウントするだけ。
これの時にはリアルに全漢字でやろうとしてたんだけど、2万字=>4億ペアなので断念した。常用漢字1945文字を対象とする。
ActiveRecordやら何やら使いたかったけど、普通にやると結構面倒だったのでrailsでプロジェクト作ってscript/runnerした。

2007年12月01日

Rubyで全ての漢字を列挙する

正しくは"UTF-8で表現できる"が接頭辞につきます。また、前提として僕はエンコードやらバイナリやらに関してはドがつく素人です。


すべての漢字を取り出す正規表現を以前読んでいて、ちょっと作りたいものがあって全ての漢字の列挙を行いたかったのでこれを参考にやってみた。
多分だけど、Rangeで範囲内の全ての漢字を取り出せるかなあと思って、まずは単純にirbで

("一".."龠").step(1){|s| puts s}

ってやった所、数百文字で止まり、しかも途中からは漢字ではない??みたいなのが出力されている。おかしい。どれくらいの範囲が確保されていて、どれくらい漢字でないものが含まれているんだろう。
unpackしてバイト列に直したものを10進数に変換してみる。
>> "一".unpack('C*').map{|i| i.to_s(16)}.join
=> "e4b880"
>> 0xe4b880
=> 14989440
>> "龠".unpack('C*').map{|i| i.to_s(16)}.join
=> "e9bea0"
>> 0xe9bea0
=> 15318688

ワオ、1文字3byteで、30万種類以上の漢字が詰め込めることになってる。多過ぎだろ漢字。ひょっとしたら詰め込み方にパターンがあるかもしれないので、とりあえず該当する文字と各バイトコードを全て取り出して、傾向を見てみる。今度は最初のコードみたく止まらずに出力された。
(14989440..15318688).step(1) do |i|
chr_a = i.to_s(16).scan(/../).map{|s| eval("0x#{s}")}
puts "#{chr_a.map{|i| i.chr}.join}\t#{chr_a.join(',')}"
end

出力ファイル (5MBあるから開かない方が無難)
首尾よくパターンを見つけた。第2・第3バイトは128から191までしか使われていない。
(14989440..15318688).step(1) do |i|
chr_a = i.to_s(16).scan(/../).map{|s| eval("0x#{s}")}
next unless(
chr_a[1] >= 128 &&
chr_a[1] <= 191 &&
chr_a[2] >= 128 &&
chr_a[2] <= 191
)
puts "#{chr_a.map{|i| i.chr}.join}\t#{chr_a.join(',')}"
end

出力ファイル
20897文字。とりあえず目的のものが得られた。
隙間があるのは将来増える文字達の為なのかなとか思いつつ、128とか191とかをフックにして調べてみたら何となく分かって来た。UTF-8はもともとUnicodeのサブセットなので、Unicodeと同等の情報量を3バイトで表現する為に第1バイトの頭4ビット、第2、第3バイトの頭2ビットが固定されているって感じかな。
この辺のエンコードのストラテジな話はRuby会議で外人さんが喋っていた気がするが、当時興味が無かったので聞き飛ばしてしまった。回り道をしない為にもその内ちゃんと勉強しようと思う。

2007年11月11日

scRubytをちょこっと触ったけど挫折

どうもDSLが気持ち悪くて。。スンマセン。
dependencyにRubyInlineの3.6.3があるので、普通にgemやるとエラーが起きます。

% sudo gem install scrubyt
% sudo gem install RubyInline --version '= 3.6.3'
% sudo gem uninstall RubyInline --version '=3.6.5'

なんか間違ってる気がするけど気にせず小さなコードを書いてみた。tumblrのfollowings url list。
#!/opt/local/bin/ruby -Ku

require 'rubygems'
require 'scrubyt'
require 'yaml'

login = YAML.load_file('login.yaml')

data = Scrubyt::Extractor.define do
fetch 'http://www.tumblr.com/login'
fill_textfield 'email', login['email']
fill_textfield 'password', login['password']
submit
fetch 'http://www.tumblr.com/following'
url '//ul[@id="following"]/li/a[1]/@href'
end

puts data.to_hash.to_yaml


返り値はそのままじゃ使えないけどto_hashすると普通にアクセスできるハッシュになる。to_xmlな例しかWEBにないのはなんでなんだぜ?

で、気力切れ。
こういうDSLチックな事って自分でも良くやるんだけど、他人のオレオレ言語はなかなかキャズムを超えられない。苦痛。
素直にmechanize + hpricotしようと思う。


(追記)ちょっと修正

2007年10月07日

mixiが白い件

GD::Imageでピクセルカウンターみたいなのを作って白ピクセルを数えてみた。

#!/opt/local/bin/perl -w
use strict;
use GD::Image;

for my $file (@ARGV){
my $pxcount = 0;
my $wpxcount = 0;
my $img = GD::Image->newFromPng($file);
my ($w,$h) = $img->getBounds();
my $white = ($file eq 'terada.png') ? '252253252' : '255255255';

for my $x (0..$w){
for my $y (0..$h){
$pxcount++;
$wpxcount++ if $white eq join '', $img->rgb($img->getPixel($x, $y));
}
}

printf "$file:\t%.2f\%\t%d\t%d\n", ($wpxcount / $pxcount) * 100, $pxcount, $wpxcount;
}


1024 x 768なOS X FireFoxでPearl Crescent Page Saverを使って画面をキャプチャした後、上記のコードを用いると
$ perl hoge.pl mixi.png
mixi.png: 69.69% 2733060 1904632
$

って訳で、大体7割近くがホワイトピクセル。余白の大きさとか捨てスペースも気になるんだけど、個人的に一番気に入らないのは枠外が白い点で、はなからリキッドを捨てているんだったら枠外は枠外でそれとわかるようにして欲しいです。

ちなみにみんなが大好きなはてなのトップページは

$ perl hoge.pl hatena.png
hatena.png: 58.85% 623170 366708
$

6割弱。

2007年08月07日

きょうじんAPI

きょうじんAPIっぽいものを作った
http://polog.org/lab/kyoujin/kyoujin.cgi
JSONPらしきものを出力してくれるが、よくわかっていないので正しいかどうかは知らない。
ラッパーはcallbackと言う名前、Hash keyはtalk。
まあとにかく僕は今日は舟遊びをして死にそうになっているので寝ます。東京湾最高。

2007年08月05日

mechanize.rbでニコニコ動画のflvをダウンロード

Perlでニコニコ動画のflvとコメントxmlをダウンロードする (Yusukebe::Tech)
perl - 勝手に添削 - ニコニコ動画ダウンローダー (404 Blog Not Found)

と言う訳でRubyの勉強のためにネタをパクってきました。ソースは以下。

#!/usr/bin/env ruby -Ku
require 'yaml'
require 'rubygems'
require 'mechanize'
require 'cgi'

video_id = ARGV.first.scan(/sm\d+$/).first

agent = WWW::Mechanize.new
agent.post('http://www.nicovideo.jp/login', YAML.load_file('nico.yaml'))

agent.get_file('http://www.nicovideo.jp/watch/' + video_id)
content = agent.get_file('http://www.nicovideo.jp/api/getflv?v=' + video_id)
params = content.scan(/([^&]+)=([^&]*)/).inject({}){|h, v| h[v[0]] = v[1]; h}
video_url = CGI.unescape(params['url'])

puts "downloading url : " + video_url
video_file = open(video_id + '.flv', 'w')
video_file.print agent.get_file(video_url)
video_file.close

使い方としては、要mechanizeで、
% sudo gem install mechanize
した後、
- 
- mail
- your@mail.jp
-
- password
- yourpass
をnico.yamlに保存して、
% ruby nicodown.rb sm673443
な感じ。
% ruby nicodown.rb http://www.nicovideo.jp/watch/sm673443
もok。

以下思った点。
1) mechanizeをログイン状態の保持だけに使うのは、狐狩りにミサイル持ってくるようなもんだと思うんだけど、何が適当なんだろ。
2) mechanizeでpostの引数がArray of Arrayなのが気持ち悪い。
3) まだ全然よく分かってない(ファイルの書き出しが分からなくてリファレンス引いたww)

まあでも2ヶ月でFizzBuzzが書けないよレベルからニコ動落とせるよレベルになれて嬉しい。あんまり変わってない気もするけど。

2007年07月29日

Google AJAX Feed API

javascriptでrssの内容を読み込めないかみたいな話があり、xml parserライブラリあたりかなあと思ってjkl-parsexmlってのを見つけ、適当なスクリプトを組んでみたんだけど、よく考えたらXMLHttpRequestじゃクロスドメインで情報が読めないので、目的に沿わない。
なので表題のGAFAの出番。

2007年07月21日

kyoujin++

随分前に作ったBOTのきょうじんがちょっとだけ流行っているみたいで、制作者としてはとても嬉しい。
元々すごくニッチと言うか、もの凄く俺専用な何かとして制作したものだけど、便利なGreasemonkeyの利用例に使われていたり、twitter検索でkyoujinって検索すると色々な人がきょうじんに話しかけていたりしていて、僕が一人で喜んでいた時に比べると、何やら生命の息吹すら感じるのだ。Followerの数も抜かれちゃったしね。
今僕は僕の中にある(もしあればだけど)クリエイティビティみたいなものの全てを仕事に与えないとやって行けない状態で、もうほんと全然ダメだ。だけど、プライベートでも何かを創発していくエネルギーは、プログラマとして絶対に無くしちゃいけないものだと思う。自分の為に書くコードは例えぐちゃぐちゃでも美しく見える。あー、余裕が欲しい。

2007年07月06日

相手の意図を汲み取る方法

どうも、ぺーぺープログラマねぎぽです。
僕は会社ヒエラルキにおける最も下っ端に位置する会社人なので、マネジメントをするしないとかもう全然関係なく完璧に指示を受ける側であります。仕様っぽいものもたまに書くっちゃ書くけど、そんなことはtinyな案件でない限りめったになく、上から横からやってくる画面仕様やらhtmlの形をした仕様やらをフルに想像力を働かせて実装しております。
でもやっぱり、編集部の人は編集語、デザイナさんはデザ語で仕様を回して来るので、マ語をしゃべる僕としては全然分からないんですよね、何が言いたいんだこりゃと。多分最もかっちりしている解決方法は仕様書のフォーマットを全社員の共通言語として策定することなんですが、そこは企業0.2.1ぐらいなうちのこと、ほら、阿吽だよアウン、てな具合です。
僕に今まで回って来た仕様書はどれもこれも「ここには何とかが表示」「これを押すとどうなる」的な事は何とかぎりぎり想像できるようにちゃんと書いてあります。良い。だけど、結構共通して仕様書から読み取れないことが「このリストはどう言う順番で表示するか」。これ、本当に伝わってきません。また、7割方は仕様書を書いた人もどのカラムとどのカラムでソートすることが一番適当かを把握していません。つまり、「このリスト、どう言う順番で並べたいんですか?」って画面を印刷して持って行った時に、正確な答えを得るためには普通にやっちゃうと結構な時間が必要なんですね。
そんな時に良いのが、テストデータを10個分ぐらいぱぱっと書いて、「じゃあこれ、並べ替えてみて下さい」とやること。設計者はちょっと迷いながらぽこぽこナンバリングしてくれるので、僕はそれを見ながら、うわ、ハッシュ必要じゃん、などと呟くのです。
まとめると、
1) みんながみんなホワイトボードを使った表現方法や言語化が得意な訳では無いので、もしそれが必要とされる場面であれば、より低レイヤーなコミュニケーションを行うこと
2) 自分にとって必要な情報がどこにも(自分にそれをやれと言った人の頭の中にも)存在していないことはままあるので、ブレストを相手に強いる手法を考えること
が下っ端的には重要だなあと。

# ちなみに、ある問題を解決しようとCTOに相談したら、上のリストソートの流れと似たようなことをやらされたのが今日最もショックな事です。反省。

2007年06月24日

HHK Professional2

職場では入社以来ずっとHHK Lite2を使っていたのだが、今日たまたま行った後輩の家にProfessional刻印モデルが置いてあって、しばし触る->その場で無刻印モデルをネット購入。
かっこよすぎ
まあ間違いなく稼働率が5%は上がるよ。導入2週間は生産性が50%ぐらいになるかもしれないけど :D


弘法筆を選ばずとは言うが、今の僕のテーマは"いかに楽しく仕事をするか"なので、このような自己満足なガジェットの存在は中期的スループットの観点から言って非常に有効だと思う。頑張れ、オレ。負けるな。

2007年06月17日

Perltidy入れてみた

hyukiさんotsuneさんあたりの間で話題に上っていたので触ってみた。Perlソースコード整形ツール。


Perltidy


OS Xにインストールするには、officialのsourceforgeからUnix向けパッケージを持って来て

$ perl Makefile.PL && make && sudo make install

で普通に入る。
それではなぜかホームディレクトリにあったくそてきとうなソースを放り込んでみよう。
$ perltidy hoge.pl -o tidy.pl

hoge.pl :
$str = do $ARGV[0];

for(0..$ARGV[1]){
my $line = &MakeASentence($str);
print $line;
print "\n" if($line =~ /¥.$/);
}

sub MakeASentence{
my $str=shift;
my @hash_array = @{$str->{hash}};
my $data = $str->{data};
my $sentence_seed = $hash_array[int rand($#hash_array)];
# print $sentence_seed , "\n";

my @sentence = split /_/, $sentence_seed;
my $ret_sentence = undef;
for my $hinshi (@sentence){
my $seed = rand();
my $ratesum = 0;
for my $a (keys %{$data->{$hinshi}}){
$ratesum += $data->{$hinshi}->{$a}->{rate};
if($ratesum > $seed){
$ret_sentence .= $a;
last;
}
}
}
return $ret_sentence;
}


tidy.pl :
$str = do $ARGV[0];

for ( 0 .. $ARGV[1] ) {
my $line = &MakeASentence($str);
print $line;
print "\n" if ( $line =~ /¥.$/ );
}

sub MakeASentence {
my $str = shift;
my @hash_array = @{ $str->{hash} };
my $data = $str->{data};
my $sentence_seed = $hash_array[ int rand($#hash_array) ];

# print $sentence_seed , "\n";

my @sentence = split /_/, $sentence_seed;
my $ret_sentence = undef;
for my $hinshi (@sentence) {
my $seed = rand();
my $ratesum = 0;
for my $a ( keys %{ $data->{$hinshi} } ) {
$ratesum += $data->{$hinshi}->{$a}->{rate};
if ( $ratesum > $seed ) {
$ret_sentence .= $a;
last;
}
}
}
return $ret_sentence;
}


目diffすると差が歴然。良い。

2007年06月11日

Ruby Kaigi 2007

業務歴3ヶ月のぺーぺープログラマねぎぽです。土日はフルで日本 Ruby会議2007に参加してました。参加費は会社持ち!社長いつもありがとうございます :D


結論から言うと、今回のRuby Kaigiのテーマは"愛"。
会場にいると"俺はRubyを愛しているぜ"って言う参加者の熱気がもの凄かった。実際の所、僕はプログラミング系のでかいカンファレンスに参加した経験は今まで無かったのだけれど、YAPC::Asia 2007のビデオとかを見る限り、少なくともPerlに比してRubyコミュニティのプログラミング言語に対する愛は勝っている様に思う。Rubyを愛していないと、Rubyでバイナリいじって変態的プレゼンソフトなんて作れないだろうしゴールデンゲートブリッジを見て「Ruby色ですねえ」なんて感想は出て来ない
そして当然だけれど、Ruby愛は宗教じゃない。Dave Thomasさんが述べているように、みんながRubyを愛するのは、Rubyが自分を愛することを求めるのであれば、Rubyを愛することが必要だからである。そこには宗教的な無償の愛や熱狂ではなく、Rubyを愛することによって創出される筈の、より良いプロダクトに対する期待があるのだ。
Ruby愛以外に何か付け加えるものがあるとするならば、あとは、覚悟


僕はまだペーペーで、RubyじゃFizzBuzzもかけないプログラマだ(剰余ってどうやるんだっけ、%? ワンライナーを行う為のオプションは?)。だけど今回のカンファレンスでは、良いプロダクトを生産する為に何が必要なのか、と言う事を、魂に刻みこまれたように思う。プレゼンの上手さとか、プロダクトの凄さとかにも感動したけれど、それより重要なことを学んだ。社内ノウハウがないからなんだ。俺はやってやるぜ(たぶん)。


(余談)
"RubyじゃFizzBuzzもかけないプログラマ"のままじゃヤバいのでwとりあえず書いた

ruby -e '(1..100).each{|i| puts i%3==0 ? i%5==0 ? "FizzBuzz" : "Fizz" : i%5==0 ? "Buzz" : i }'

あれ、こんなに長かったっけ。とりあえずrubyじゃ0はtrueなことは学んだ。

2007年06月03日

レイトン教授と水汲み問題とブルートフォースなねぎぽ

母親に以前脳トレとDSを買い与えたのだが、すっかりはまったのか、自分で大量にソフトを購入するようになった。その中に"レイトン教授と不思議な町"と言うものがある。一見逆転裁判のような推理系のようだが、推理を要する部分など全く無く、全面、これパズルとなぞなぞである。
で、今日。
もの凄く暇だった僕は手に取って始めてしまった訳だ、レイトン教授を。んでホイホイと今5時間で80程謎を解いた所なのだけれど、もうさっきから20分ぐらいある問題で詰まっている。曰く「16リットル、9リットル、7リットルの瓶があり、16リットルの瓶にはいっぱいに水が入っている。これを16リットルと9リットルの瓶に8リットルずつに分けて欲しい」と言った内容だ。

残念ながら僕はこの手の問題がもの凄く苦手である。はっきり言って諦めた。
諦めたので力技で解いてやろうと思っていそいそとPowerBookを取り出した。

my $a = {
0 => {
max => 16,
now => 16
},
1 => {
max => 9,
now => 0
},
2 => {
max => 7,
now => 0
}
};

my $i = 1;
while($a->{0}->{now} != 8 or $a->{1}->{now} != 8 ){
my $x = int rand 3;
my $y = int rand 3;
while($a->{$x}->{now} == 0){
$x = int rand 3;
}
while($y == $x or $a->{$y}->{now} == $a->{$y}->{max}){
$y = int rand 3;
}

my $move = ($a->{$y}->{max} - $a->{$y}->{now} > $a->{$x}->{now}) ?
$a->{$x}->{now} :
$a->{$y}->{max} - $a->{$y}->{now};

$a->{$x}->{now} -= $move;
$a->{$y}->{now} += $move;
print $i++, " : $a->{$x}->{max} => $a->{$y}->{max}\n";
}


もう完璧なまでの力技。再帰とか書かない書かない。エレガントさのかけらも無し。
もーこれでいいだろと思って実行した。

...全然答えが返って来ない。

2007年05月24日

Web::Scraperでasahi.comの記事一覧から記事を取得

Web::Scraper
スクレイピングとかしょっちゅうやってる気がするけど最近なかなかネタがなかったので使わず仕舞いだった。
今日ちょっと思いついた事があったので使ってみるよ。


#!/usr/bin/perl
use strict;
use URI;
use Web::Scraper;
use Data::Dumper;

my $articles = &GetArticles(shift);
print Dumper($articles);

sub GetArticles(){
my $url = shift;
my $asahi_list = scraper {
process 'ul.list>li',
'articles[]' => scraper{
process 'li>a', url => '@href';
};
result 'articles';
}->scrape(URI->new($url));
my @articles = ();
map{ push @articles, &GetArticle($_) } @{$asahi_list};
return \@articles;
}


sub GetArticle(){
my $str = shift;
my $url = 'http://www.asahi.com'.$str->{url};
my $title = $str->{title};
my $asahi_article = scraper {
process 'h1#cap', title => 'TEXT';
process 'p#date', date => 'TEXT';
process 'div.kiji', content => 'TEXT';
result qw/title date content/
}->scrape(URI->new($url));

$asahi_article->{url} = $url;

return $asahi_article;
}


記事リストのul class="list"の中のliの中のaタグから単体記事へのリンクを取得して、さらに単体記事からタイトル、更新日時、本文を取得し保存する。ul.list>liとli>aはこの組み合わせ以外だとなんかうごかず(ul.listとaとかだとだめ)。
んで実行。
perl hoge.pl http://www.asahi.com/national/list.html > hoge.txt

$VAR1 = [
{
'date' => '2007年05月24日01時09分',
'url' => 'http://www.asahi.com/national/update/0524/OSK200705230096.html',
'content' => '  スポーツ用品大手のアシックス(神戸市)は、バスケットボールシューズ「ゲルバースト アップセット」の2種類で、靴底が一部はがれる恐れがあるとして、24日から回収を始める。全国で約2万6000足を出荷し、うち約1万7000足が売られたとみられる。けがをしたなどの報告はないという。  同社によると、地面と接触する靴の裏部分の設計ミスが原因という。問い合わせは同社(0120・770・108)へ。 ',
'title' => 'バスケットシューズ欠陥 アシックス回収へ'
},
...


これまじですごく使い易い。覚えておくべき。
# 朝日の記事は後々何かに使う。

2007年05月20日

blogの各エントリーURLからauthorとblog homeのURLを決定する

先日サービスにアクセス解析を付けることになり、リファラの集合を束ねて欲しいと言われた。つまり、あらゆるURLから同じblogのものであるとか、同じニュースサイトであるとかをグルーピングして欲しいと言う事だ。これって結構ややこしい。
イメージ的には

http://polog.org/0.php
http://polog.org/1.php
http://polog.org/2.php

とかあったら、"http://polog.org/"で束ねられるじゃん、とか言われそうだが、そうも行かない。
blogにはありとあらゆる階層にページがあるので
http://polog.org/index.php
http://polog.org/archives/cat1/
http://polog.org/archives/2007/02/

URLだけではリファラ群を束ねるのが難しいのだ。voxならドメイン、fc2なら第一階層がユーザのルートディレクトリだ。

てな訳で僕のアイデアとしては、まっとうなblogサービスならrel="alternate"でrss付いてる筈なので、その中身をパースしてルートディレクトリをチェックすれば良い。authorも分かるしアクセス解析を閲覧するユーザには分かり易い。そして以降同じrssのurlを見ているページはまとめてしまえば良い。
などと言ったんだけどもう面倒くさいから第一階層(http://hoge.com/hoge/)でまとめようと言う話になってしまった。そんな。

前置きが長くなったけど以上のアイデアを実行するPerlコードを書いた。


use LWP::Simple;
use strict;
my $url = $ARGV[0];
$url =~ m%(http://[^/]+)(/.*/)?%;
my $domain = $1;
my $base = $1.$2;
my $html = get($url);
if($html =~ m%<link rel="alternate".+?type="application/(?:atom|rss)¥+xml".+?href="(.+?)".*?>%){
my $rss_url = $1;
$rss_url = ($rss_url =~ m%^http:%) ? $rss_url :
($rss_url =~ m%^/%) ? $domain. $rss_url :
$base.$rss_url;
my $rss = get($rss_url);
my $author = ($rss =~ m%<dc:creator>(.+?)</dc:creator>%) ? $1 :
($rss =~ m%<author>[^<]*?<name>(.+?)</name>[^<]*?</author>%) ? $1 :
'';
my $home = ($rss =~ m%<link>(.+?)</link>%) ? $1 :
($rss =~ m%<link rel="alternate".+?type="text/html".+?href="(.+?)".*?>%) ? $1 :
'';
my $title = ($rss =~ m%<title>(.+?)</title>%) ? $1 : '';

print "$title, $author, $home¥n";
}


alternateがあったら読みに行き、rss2,atom関係なくauthorとblogホームの情報を引っ張る。当たり前だけどxml tree作るのは面倒なのでgetして正規表現。

% perl hoge.pl http://blog.goo.ne.jp/hachitori/e/6cef002082f319664aa186b391a8dd51
sablog 18, hachitori, http://blog.goo.ne.jp/hachitori

これ書いたの20分ぐらいだと思うんだけど、現場でやらせて下さいって言っちゃったらColdfusion使って実装なんだこれが。Coldfusionでrobotて。

風邪で朦朧としているので乱文失礼。

(追記)
title足した。

2007年05月17日

夢野久作でバロウズカットアップ

http://twitter.com/yumeno
狂人日記の代わりに青空文庫の"少女地獄"を学習セットにしたもの。実は3日ぐらい前からcronは動いてたんだけどtwitterが重過ぎてユーザ登録できなかったぽ。
設定がちょっと長文派で、意味不明な恐怖感はきょうじんくんの比じゃないっす。


きょうじんはこちら
手法

2007年05月16日

FizzBuzz on Coldfusion

誰も書いてないみたいなので書いてみた


<cfoutput>
<cfloop from="1" to="100" index="aI">
<cfif aI MOD 15 EQ 0>
FizzBuzz
<cfelseif aI MOD 5 EQ 0>
Buzz
<cfelseif aI MOD 3 EQ 0>
Fizz
<cfelse>
#aI#
</cfif>
</cfloop>
</cfoutput>

うーんそれにしても書き慣れん。ざっくり3分ぐらい。
と思ったら日本人でもう書いてる人がいたw 世の中広いなあ。

(追記)
それにしてもColdfusionの構造体やらリストやらアレイやらに値を代入するあたりの予約語や構文やらはうんこすぎる。今日アプリケーションサーバ全部に対する設定を記述する構造体を書かなきゃいけなかったんだけど、Coldfusionに合わせてロジックツリー書いて代入するのが面倒臭過ぎて全部単にcfsetするものをPerlで書いてコピペした。24inchのディスプレイが文字で埋まってちょっと溜飲が下がったよ。

2007年05月11日

狂人日記@twitter

きょうじん君作ったよー。


http://twitter.com/kyoujin


pologの狂人日記を形態素でばらしてマルコフにし、そこから自動で短文を再構築してtwitterに投稿するbotを書きました。
記念すべき初の発言:
「イイ?と言うのです。」
きょうじんくんかわいい!

(追記)
昨日眠かったので適当すぎるw もうちょい詳しく書きます。
狂人日記から本文を抜き出した後、Mecabで形態素解析して、さらに文脈をテーブルで表現するために確率付きマルコフモデルに落とします。この場合各状態は単語になって、ある単語の次にどの単語が来るかが全て確率付きの状態遷移で表現できる。で、さらに文を開始する単語のセットを持つ。
以上で準備は終わり。Data::Dumperでダンプしておく。
あとは最初の単語群からから始まって句点で終わるようにマルコフを辿るコードを書いて、帰ってきたやつをNet::Twitterでupdateさせて終わり。
そんで30分に一度cronさせてましたが、意外とuzいので1時間に1回にします。
AM2:00からAM7:00ぐらいは寝かしといたほうが良いかな?

2007年05月04日

twitterで広がる友達の輪!

と言う訳で可視化したよ!

negipoから2stepsまでのfriendsをeXpandaで可視化しました。ラベルの大きさはノードの次数になってます。amachangHamachiya2でかすぎワロタ。

これまでのみちのり
Twitterを可視化するアプリ作ろう!

Net::Twitter書き換えた。ぼくてんさい!

Twitter API結構遅いやん。。でもめげずに実装!

eXpandaめちゃんこ遅いやん。。

アプリ諦め

Cytoscapeで座標だけ取ってeXpandaに突っ込む。

もう凝った可視化する気力neee..←いまここ

(追記)
そういや考察してなかった。
座標計算のCircularアルゴリズムは連結度の高いノードを近くに配置するので、Hamachiya2とamachangを同時にAddしているユーザは非常に多い。miyagawaとdankogaiも同様である。これはamachang達が主にネット関連の言語ギークで、miyagawaとdankogaiがPerl mongerであることに起因するのではないか。中央の円上に配置されているユーザは上記4人のいずれかのうち2人以上のfriendsなので、僕と同様ネットで遊びまくってるnerdsな可能性が高い。

そんじゃ泳ぎに行って来ます。

2007年05月04日

Net::Twitterで任意の人物のfriendsを取得

暇だったらからtwitterの可視化でもしようと思ってid/screen_nameからfriendsとfollowers取得出来るようにNet::Twitter書き換えた


56,57c56,58
< my ( $self ) = @_;
< my $req = $self->{ua}->post($self->{apiurl} . "/followers.json");
---
> my ( $self , $id ) = @_;
> my $p = ( defined $id ) ? "?id=$id" : "";
> my $req = $self->{ua}->post($self->{apiurl} . "/followers.json" . $p);
63,64c64,66
< my ( $self ) = @_;
< my $req = $self->{ua}->post($self->{apiurl} . "/friends.json");
---
> my ( $self, $id ) = @_;
> my $p = ( defined $id ) ? "?id=$id" : "";
> my $req = $self->{ua}->post($self->{apiurl} . "/friends.json" . $p);

んだけどどうも動かないんだよね。試しに友達のIDでやってみたら取得できたんだが、その後どんな値を引数に入れても返り値が変わらない。自分のfriendsも取得できない。キャッシュされてる?
ていうわけで進展したら報告します。てかちょっとだれかデバッグしてくれ。

(追記)
ごめん仕様書ちゃんと読んでなかった。
本家API仕様書

Parameters:
id. Optional. The ID or screen name of the user for whom to request a list of friends. Ex: http://twitter.com/statuses/friends/12345.json or http://twitter.com/statuses/friends/bob.rss

と言う訳で最終的なパッチはこれ。


63,64c63,65
< my ( $self ) = @_;
< my $req = $self->{ua}->post($self->{apiurl} . "/friends.json");
---
> my ( $self, $id ) = @_;
> my $path = ( defined $id ) ? "/friends/$id.json" : "/friends.json";
> my $req = $self->{ua}->post($self->{apiurl} . $path);

どうやら任意の人物のデータを取得出来るのはfriendsだけみたい。隠れパラメータあるのかもだけど指定の仕方が分からん。

(さらに追記)
show(あるユーザのステータス取得)してくれるモジュール無かったんで書き足したよ。


sub show {
my ( $self, $id ) = @_;
return if not defined $id;
my $req = $self->{ua}->post("http://twitter.com/users/show/$id.json");
return ($req->is_success) ? JSON::Any->jsonToObj($req->content) : undef;

}


適当な所にいれておいてちょ。

2007年04月23日

まるごとYAPC

ブックマークしなかったのでどこだか失念したけれど、「飛行機の移動時間は割と長大な講演を聞くのに良い」と書いている人がいたので、そういやYAPCの動画すげー勢いでアップされてたし電車の中とかで見たら勉強になるんじゃね、と思って全部download->iPod用に変換するスクリプトを書いてみた。
OS X前提。
前もってMiMMS(ストリーミングビデオダウンローダ)とffmpeg(エンコーダ)をインストールする必要がある。
んで


#!/usr/bin/perl

use strict;
use LWP::Simple;

my $url_base = 'http://www.i-revo.jp/yapcasia/archive/';

for my $num (1..43){
my $html_num = sprintf "%02d", $num;
my $html_content = get($url_base . $html_num . '.html');
my @wvx = $html_content =‾ m%param name="filename" value="(http://.+?.wvx)"%;
next if ($wvx[0] eq '');
my $wvx_content = get($wvx[0]);
my @wmv = $wvx_content =‾ m%ref href = "(mms://.+?.wmv)"%;
`mimms -o YAPC-$html_num.wmv $wmv[0]`;
`ffmpeg -y -i "YAPC-$html_num.wmv" -title "YAPC-$html_num" -bitexact -vcodec mpeg4 -s 320x240 -r 29.97 -b 768 -acodec aac -ac 2 -ar 48000 -ab 64 -f ipod "YAPC-$html_num.MP4"`
}


一気に書いて動かしてみたはいいけど手元のffmpeg、wmv3からのコンバート出来ないんだよね。
めんどくなってきた。

(追記)
iSquintの最新バージョンならwmv3通るらしいからもうそれでいいやー。今晩はダウンロードしっぱなしで寝ようっと。

(さらに追記)
"つhttp://tokyo2007.yapcasia.org/sessions/videocast.xml"って言われた><

2007年04月23日

pretty print test

google-code-prettyfyを入れてみたのでテスト。
内容はeXpandaのサンプルスクリプト。

#!/usr/bin/perl
use warnings;
use strict;
use eXpanda;


# eXpanda Demo Script No 8
# "Visualizing Social network."

my $str = do 'sns_net.str';
bless $str, 'eXpanda';

### Analysis ####
$str->Analyze(
-method =>"degree",
);

### Initialize graphics ####
$str->Apply(
-object => 'node:graohics:fill',
-value => '#d39800',
);

$str->Apply(
-object => 'node:graohics:w',
-value => '15',
);

$str->Apply(
-object => 'edge:graohics:stroke',
-value => '#c3d825',
);

$str->Apply(
-object => 'edge:graohics:width-stroke',
-value => '#c3d825',
);

### Apply Score to Graohics ###
$str->Apply(
-object => 'node:graohics:fill',
-from => 'node:score:degree',
-value => {'#f39800' => '#e2041b'},
);

$str->Apply(
-object => 'node:graohics:w',
-from => 'node:score:degree',
-value => {'15' => '40'},
);

### Output ###
$str->out("sample08.svg",-no_node_label=>1,);

2007年04月22日

wikipediaのパーサを書いている

ページ毎に必要な箇所、情報の形式が違うので毎ページ全部書き直してるんだけど、長年の研鑽のためか(だって5年間パーサ書いてたようなもんだもんな)1ページあたり実装に10分かからないのは良いとして、


  • start trigger

  • どの行から読み込み始めるか
  • end trigger

  • どの行で読み込み終えるか
  • regexp

  • どういう正規表現でオブジェクトを取得するか

だけで一応汎用化出来る気がした。最後の正規表現がミソで、上手くすれば一行に複数の取得したいオブジェクトがあっても配列化が行える筈、なんだけどどうすりゃいいのかね。
例えば
食文化に関する用語の一覧
だったら
<p><a href="/wiki/%E8%96%AC%E5%91%B3" title="薬味">薬味</a> <a href="/wiki/%E8%96%AC%E7%BC%B6" title="薬缶">やかん</a> <a href="/wiki/%E9%A3%B2%E8%8C%B6" title="飲茶">飲茶</a> <a href="/wiki/%E6%9C%89%E6%A9%9F%E8%BE%B2%E7%94%A3%E7%89%A9" title="有機農産物">有機農産物</a></p>

から
qw(薬味 やかん 飲茶 有機農産物)
のリストを取得するregexpが欲しい訳だ。当然欲しいオブジェクトの数は各行毎に可変である。
普段の僕だったら堅実にm%^<p>(.+?)</p>$%した上でs%</?a.*?>%%g;してsplit /¥s/なんだけど、一行で書くとしたら
@arr = $line =~ m%<p>(?:<a.*?>(.+?)</a>\s?)+</p>%
こうか?
うーん最後のマッチしか返してくれないなあ。どうやるんだろ。
逃げるんならregexp triggerとしてm%^<p>(.+?)</p>$%してregexpはwhile($line =~ m%<a.*?>(.+?)</a>\s?%){ ... }かな。

2007年04月19日

Regexp::Assemble

スーパー便利。
cpan
要は正規表現の最適化。
こういうコード生成・最適化的なモジュールは何かにつけ重要だよね。コードを出力するコードを利用。でもRailsとか使ってるとDRYすぎてオレすげー感がうすまるのも事実。
まあ一番重要なのはサービスの中身っすよ。

(via 404 Blog Not Found)

2007年04月09日

crawler / indexer

Webクローラーを作るのは大変な作業だと僕は思う。ちょっとした定型のマークアップランゲージから必要な情報を取得することですら結構面倒なのに、人間が記述した、時たま破綻するような殆ど自然言語ライクなタグのかたまりを、その論理構造を無視する事無く、超高速に、超Massで、やってのける訳だ。そう言うコードを書く人達を僕は尊敬する。
さて先程食後に紅茶を飲みながら、暇だなと思ってpolog.orgのアクセスログを眺めていた。開設後一ヶ月はGoogleやYSTばかりだったが、最近はMSN Live Searchやgoo、livedoor(独自検索エンジンだっけ?)のbotがちょくちょくやってくる。へぇ、とかおおこんな記事が人気なのかとか思いつつDocomoや中部地方の大学(だれ?)のhostの合間に見つけたのがコレ↓

worio.com | Mozilla/5.0 (compatible; worio bot heritrix/1.10.0 +http://worio.com)

コロンビア大のソースコードサーチエンジンらしい。今時pure academicにそんなのやるのかと驚愕。まだオープンベータだが頑張って欲しい。
あと一つ思ったのがblogへのコードの貼付け方。現状は数行のモノでない限り別ファイルだが、これちょっと模索しないと上手い感じに世の中にcommitできないので、そのうちリサーチして良い手法を手に入れようと思う。or 誰か教えろ。

2007年03月18日

WWW::MechanizeでGREE日記のバックアップ

WWW::Mechanizeを今まで知らなかったのは悔恨の極みと言わざるを得ない。ブラウザ上で操作を行う場合、フォーム一つとっても大量の情報を送っていたりするので、それをプログラム的に管理しようとするとすげー面倒くさいのだ。WWW::Mechanizeはそう言った面倒臭さを一切排除した超リッチなLWP::UserAgentラッパーだと言える。
参考
これが2004年の記事なんだよなあ。すげえ。


まあこれが如何に凄いかはナウな話じゃないので置いといて、とりあえず自分に必要そうなGREEの日記をバックアップをするコードを書きました。GREEってば日記をエクスポートする機能がない上にblogをGREE日記に登録するとそれまで書いてたレコードが消えるんだよな。2年前の話だけど、それ。

てな訳でソースはこちら。

なんかMechanizeの凄い所を全然使ってないように見えるのは日本語の正規表現に挫折したから。わからん。¥Q¥Eでかこみゃいいんじゃねえのか。あとどうせならパーサ作ってTTとか使ってみてMovable Typeとかにインポート可能なエクスポート形式にするとかやろうかなあと考えてましたがもう眠いので普通に保存するだけだよ!
超絶中途半端なエントリーですが明日早いので寝ますオヤスミー!

2007年03月16日

言語を学ぶ為に

プログラミング言語の話です。
ねぎぽは基本的にPerlerです。このところRubyを触る必要性にかられていてその為にはてブしてたサイトがあるんだ。
新しいプログラミング言語を習得するための15の方法
今日30分ぐらい時間が出来たのでいくつか組もうと思った。ざっと見た所文字列操作は使うだろうし多くて良し、配列操作もいいけどやけに数値処理が多いなみたいなことを考えつつ、書きはじめてみていきなり詰まった挙げ句驚愕の事実に気づいた。

課題1. 無限ループ内に1,2,3,...を出力させ、このループを特定のキー入力で止める。

・・・キーボードイベントってPerlでどう見るの?
Perl/Tkでそう言うの昔組んだことあるけど、えーと、無理だろこれ。ねぎぽはPerlの習得を諦めました。
誰かRubyでやってよこれ。

2007年03月08日

eXpanda

日経BPで紹介されてた。わーい。
内々にコンタクト来てます。超嬉しい。
色んな人が使ってくれると楽しいなあ。

(追記)
cytoscape公式からもリンク貼られました。

2007年02月22日

meiro

パーマンはすげえ奴だ。10段階で言うと8ぐらい。でもあんまりPerlで遊んだことの無い、職業Perlerでもある。そんな訳でお前迷路でも作れと、何も考えずに課題を与える俺でした。

一瞬で作ってきやがった。
こいつはマジですげえ。10段階で言うと9ぐらい(10はラリー・ウォール)。

と言う訳で、自分だけで楽しむのは勿体ないのでwebで閲覧出来るようにしました。
meiro (c)p-man
ソースが欲しい人はパーマンから直接貰って下さい。
いや、すげえ。

2007年02月20日

dreamhostでPlagger

Plaggerの新しいトピックなんて数ヶ月出ていない状況ですが、自由に使えるサーバも手に入ったことだし、また必要にかられたのでとりあえずインスコしてみることにしました。
dreamhostはsudo出来ないことに留意しながら、まずはcpanのインストール。

DreamHost で CPAN を使う方法
最高です。殆どこのままで行けましたが、シェルがcshなのでこんな感じにPATHとPERL5LIBを設定。

setenv PATH $HOME/local/bin:$PATH
setenv PERL5LIB $HOME/local/lib/perl5/5.8.8:$HOME/local/lib/perl5/site_perl/5.8.8

okok。でとりあえずcpanシェルに入って。

install Plagger

...



AVIF/Time-Duration-1.04.tar.gz : make_test NO

DCLINTON/Cache-Cache-1.05.tar.gz : make_test NO

RICKM/DateTime-Format-Strptime-1.0700.tar.gz : make_test NO

ABH/XML-RSS-1.22.tar.gz : make_test NO

ok ABW/Template-Toolkit-2.18.tar.gz : install NO

OLAF/Net-DNS-0.59.tar.gz : make_test NO

KELLAN/DateTime-Format-W3CDTF-0.04.tar.gz : make_test NO

DROLSKY/DateTime-0.36.tar.gz : make_test NO

DROLSKY/DateTime-Format-Mail-0.30.tar.gz : make_test NO

DROLSKY/DateTime-Locale-0.33.tar.gz : writemakefile NO '/home/.mewler/negipo/local/bin/perl Makefile.PL' returned status 512

うーん。
えい。

force intall Plagger

ポチ(ほんとはダメです)。

で、インストールのチェックの為に適当なサンプルを動かしてみました。
Plaggerはじめました
cacheがどうたら言ってたけどgmailをチェック。okok :D
便利さを見るのはこれからですが、とりあえずまともに動いたので感動エントリを投稿してみました。

2007年02月19日

flickr downloader

ちょっと必要にかられてflickrのダウンローダを作ってみました。ダウンロードしたら拡張子変えてちょ。
Perlの実行環境とFlickr::API::Photosetsが必要で、あとflickr API keyは自分で取得して下さい(要flickrアカウント)。
動作仕様としては (1)フォトセット全部 (2)あるユーザの写真全部 (3)あるユーザのあるタグの写真全部 をインポート可能です。

使い方はこんな感じ:

% ./flickrdown.pl --key [your-api-key] --url http://www.flickr.com/photos/goodgrief/tags/Glamour/ --dir ./down --limit 100
or
% ./flickrdown.pl -k [your-api-key] -u http://www.flickr.com/photos/goodgrief/
or
% ./flickrdown.pl -k [your-api-key] -u http://www.flickr.com/photos/goodgrief/sets/1396354/

url指定するだけなのはクレヴァかも。
ソースのパラメータ初期化の所書き換えれば--keyは指定しなくてok。

2007年02月12日

JavaScriptリファレンス

とりあえず商売もんなのにリファレスも持ってないのはアレなのでAmazonに注文してみた。
買ったのは"改訂第4版 JavaScript ポケットリファレンス"。改訂版が進んでいればいるほど良著の法則です。
僕のJavaScriptにおける技術力はPerlで言うと「この$@ってなんですか」レベルなので、ハックな感じの本を買うどころか、今回の本を正しく活用出来るようになるのももうちょい先でしょうね。

2007年02月11日

IBM研のメール可視化技術

Thread arcs
なるほど、良い。eXpandaを作り始めた頃はかなり可視化方面にアンテナを立てていたつもりだったけれど、これは知らなかった。

メールの場合個々の独立ネットワークが小さいサイズの上に時系列が大きな意味を持っているので、こう言った直線的なレイアウトで関係性を美しく魅せるのは面白い。
2chブラウザ"Thousand"の制作者が昔同じようなコンセプトで"Oreyon"って言うソフトウェアを作っていたのを思い出す。この人分生行ってきましたみたいなことをblogで書いてたが、実験系みたいなので多分話したことは無いんだろうなあ。

(via POLAR BEAR BLOG)