ずいぶん前にOppai-Detectの精度向上っぷりをtwitterで見せてもらって、やべー使いてーなどと思っていたんですが、いつの間にか公開されてたので、クライアント側でプロキシ動作するフィルタを書いてみました。おっぱい見れません><
会社が白金台に引っ越しました。外苑前と比べると人がすごく少なかったり、オフィスの隣には都内有数の森があったり、窓からその森が見えたり、僕がその窓際に座っていたり、座って作業していると半径10mに人が1人もいなかったり(前のオフィスは30人くらいいた)して、かなりいい感じです。
そんなカッチョいいオフィスで社会と会社と己のマニーのために働いている僕ですが、先日社長が"カッチョいいディスプレイを会社のフロントに置くから、そこでなんかやってよ"などとおっしゃってまして、ちょっとしたデモを作ることにしました。
全く何言ってんのかわかりませんがたまに'きほーんーてーきー'とか'そウCてーもぅUだーCta-'とか言い出して吹きます。
ソースは以下。
人工無能オフというのに行ってきた
人工無能と言うのは要するに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なのよ"みたいなかなりカオスな感じ。嘘です。普通に名刺交換しました。
昨日の続き。
なんで昨日いきなりライフゲームなんぞ実装したかと言うと、なんかglitchに使えそうだったからです。寝る前にふと思いついちゃいました。てなわけで今日ぐっちゃぐちゃになりましたけど、割と構造化を意識した感じのコードにしてたんです。コードグリッチ!
以下詳細。
開発合宿中ですが、ふと理性がなくなって何となくきょうじんスクリーンセーバーをつくりました。ping 理性。
kyoujin.qtz
ダウンロードして、
システム環境設定>デスクトップとスクリーンセーバー>スクリーンセーバー
の画面にドラッグアンドドロップしてください。
mac only!
(追記)
あ、Leopard onlyだった。すみません。
先日"これスコアリングの結果わかりやすく見せらんないかな?"って社長とペアプロ時に言われて、オレオレ変換で色・サイズのタグクラウド作ったら色の方だけ速攻却下喰らった。超くやしい。
と言う訳でちょっと勉強がてら書いてみた。
今一適当なarticleが見つからなかったのでjQueryのHeatColor pluginの中身をそのまんま実装。
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);
すると、大変なことに!!
アイデアとしては単純で、画像情報に落としたあとで全漢字pairに対して全pixelの一致数をカウントするだけ。
これの時にはリアルに全漢字でやろうとしてたんだけど、2万字=>4億ペアなので断念した。常用漢字1945文字を対象とする。
ActiveRecordやら何やら使いたかったけど、普通にやると結構面倒だったのでrailsでプロジェクト作ってscript/runnerした。
正しくは"UTF-8で表現できる"が接頭辞につきます。また、前提として僕はエンコードやらバイナリやらに関してはドがつく素人です。
すべての漢字を取り出す正規表現を以前読んでいて、ちょっと作りたいものがあって全ての漢字の列挙を行いたかったのでこれを参考にやってみた。
多分だけど、Rangeで範囲内の全ての漢字を取り出せるかなあと思って、まずは単純にirbで
("一".."龠").step(1){|s| puts s}>> "一".unpack('C*').map{|i| i.to_s(16)}.join
=> "e4b880"
>> 0xe4b880
=> 14989440
>> "龠".unpack('C*').map{|i| i.to_s(16)}.join
=> "e9bea0"
>> 0xe9bea0
=> 15318688(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
(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
どうも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'
#!/opt/local/bin/ruby -Kurequire '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'
endputs data.to_hash.to_yaml
で、気力切れ。
こういうDSLチックな事って自分でも良くやるんだけど、他人のオレオレ言語はなかなかキャズムを超えられない。苦痛。
素直にmechanize + hpricotしようと思う。
(追記)ちょっと修正
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;
}
$ perl hoge.pl mixi.png
mixi.png: 69.69% 2733060 1904632
$
ちなみにみんなが大好きなはてなのトップページは
$ perl hoge.pl hatena.png
hatena.png: 58.85% 623170 366708
$
きょうじんAPIっぽいものを作った
http://polog.org/lab/kyoujin/kyoujin.cgi
JSONPらしきものを出力してくれるが、よくわかっていないので正しいかどうかは知らない。
ラッパーはcallbackと言う名前、Hash keyはtalk。
まあとにかく僕は今日は舟遊びをして死にそうになっているので寝ます。東京湾最高。
Perlでニコニコ動画のflvとコメントxmlをダウンロードする (Yusukebe::Tech)
perl - 勝手に添削 - ニコニコ動画ダウンローダー (404 Blog Not Found)
と言う訳でRubyの勉強のためにネタをパクってきました。ソースは以下。
#!/usr/bin/env ruby -Ku使い方としては、要mechanizeで、
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
% sudo gem install mechanizeした後、
-をnico.yamlに保存して、
- your@mail.jp
-
- password
- yourpass
% 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が書けないよレベルからニコ動落とせるよレベルになれて嬉しい。あんまり変わってない気もするけど。
javascriptでrssの内容を読み込めないかみたいな話があり、xml parserライブラリあたりかなあと思ってjkl-parsexmlってのを見つけ、適当なスクリプトを組んでみたんだけど、よく考えたらXMLHttpRequestじゃクロスドメインで情報が読めないので、目的に沿わない。
なので表題のGAFAの出番。
随分前に作ったBOTのきょうじんがちょっとだけ流行っているみたいで、制作者としてはとても嬉しい。
元々すごくニッチと言うか、もの凄く俺専用な何かとして制作したものだけど、便利なGreasemonkeyの利用例に使われていたり、twitter検索でkyoujinって検索すると色々な人がきょうじんに話しかけていたりしていて、僕が一人で喜んでいた時に比べると、何やら生命の息吹すら感じるのだ。Followerの数も抜かれちゃったしね。
今僕は僕の中にある(もしあればだけど)クリエイティビティみたいなものの全てを仕事に与えないとやって行けない状態で、もうほんと全然ダメだ。だけど、プライベートでも何かを創発していくエネルギーは、プログラマとして絶対に無くしちゃいけないものだと思う。自分の為に書くコードは例えぐちゃぐちゃでも美しく見える。あー、余裕が欲しい。
どうも、ぺーぺープログラマねぎぽです。
僕は会社ヒエラルキにおける最も下っ端に位置する会社人なので、マネジメントをするしないとかもう全然関係なく完璧に指示を受ける側であります。仕様っぽいものもたまに書くっちゃ書くけど、そんなことはtinyな案件でない限りめったになく、上から横からやってくる画面仕様やらhtmlの形をした仕様やらをフルに想像力を働かせて実装しております。
でもやっぱり、編集部の人は編集語、デザイナさんはデザ語で仕様を回して来るので、マ語をしゃべる僕としては全然分からないんですよね、何が言いたいんだこりゃと。多分最もかっちりしている解決方法は仕様書のフォーマットを全社員の共通言語として策定することなんですが、そこは企業0.2.1ぐらいなうちのこと、ほら、阿吽だよアウン、てな具合です。
僕に今まで回って来た仕様書はどれもこれも「ここには何とかが表示」「これを押すとどうなる」的な事は何とかぎりぎり想像できるようにちゃんと書いてあります。良い。だけど、結構共通して仕様書から読み取れないことが「このリストはどう言う順番で表示するか」。これ、本当に伝わってきません。また、7割方は仕様書を書いた人もどのカラムとどのカラムでソートすることが一番適当かを把握していません。つまり、「このリスト、どう言う順番で並べたいんですか?」って画面を印刷して持って行った時に、正確な答えを得るためには普通にやっちゃうと結構な時間が必要なんですね。
そんな時に良いのが、テストデータを10個分ぐらいぱぱっと書いて、「じゃあこれ、並べ替えてみて下さい」とやること。設計者はちょっと迷いながらぽこぽこナンバリングしてくれるので、僕はそれを見ながら、うわ、ハッシュ必要じゃん、などと呟くのです。
まとめると、
1) みんながみんなホワイトボードを使った表現方法や言語化が得意な訳では無いので、もしそれが必要とされる場面であれば、より低レイヤーなコミュニケーションを行うこと
2) 自分にとって必要な情報がどこにも(自分にそれをやれと言った人の頭の中にも)存在していないことはままあるので、ブレストを相手に強いる手法を考えること
が下っ端的には重要だなあと。
# ちなみに、ある問題を解決しようとCTOに相談したら、上のリストソートの流れと似たようなことをやらされたのが今日最もショックな事です。反省。
職場では入社以来ずっとHHK Lite2を使っていたのだが、今日たまたま行った後輩の家にProfessional刻印モデルが置いてあって、しばし触る->その場で無刻印モデルをネット購入。
かっこよすぎ
まあ間違いなく稼働率が5%は上がるよ。導入2週間は生産性が50%ぐらいになるかもしれないけど :D
弘法筆を選ばずとは言うが、今の僕のテーマは"いかに楽しく仕事をするか"なので、このような自己満足なガジェットの存在は中期的スループットの観点から言って非常に有効だと思う。頑張れ、オレ。負けるな。
hyukiさんとotsuneさんあたりの間で話題に上っていたので触ってみた。Perlソースコード整形ツール。
OS Xにインストールするには、officialのsourceforgeからUnix向けパッケージを持って来て
$ perl Makefile.PL && make && sudo make install
$ perltidy hoge.pl -o 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;
}
$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;
}
業務歴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 }'
母親に以前脳トレと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";
}
...全然答えが返って来ない。
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;
}
perl hoge.pl http://www.asahi.com/national/list.html > hoge.txt
これまじですごく使い易い。覚えておくべき。
# 朝日の記事は後々何かに使う。
先日サービスにアクセス解析を付けることになり、リファラの集合を束ねて欲しいと言われた。つまり、あらゆるURLから同じblogのものであるとか、同じニュースサイトであるとかをグルーピングして欲しいと言う事だ。これって結構ややこしい。
イメージ的には
http://polog.org/0.php
http://polog.org/1.php
http://polog.org/2.php
http://polog.org/index.php
http://polog.org/archives/cat1/
http://polog.org/archives/2007/02/
てな訳で僕のアイデアとしては、まっとうな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";
}
% perl hoge.pl http://blog.goo.ne.jp/hachitori/e/6cef002082f319664aa186b391a8dd51
sablog 18, hachitori, http://blog.goo.ne.jp/hachitori
風邪で朦朧としているので乱文失礼。
(追記)
title足した。
http://twitter.com/yumeno
狂人日記の代わりに青空文庫の"少女地獄"を学習セットにしたもの。実は3日ぐらい前からcronは動いてたんだけどtwitterが重過ぎてユーザ登録できなかったぽ。
設定がちょっと長文派で、意味不明な恐怖感はきょうじんくんの比じゃないっす。
誰も書いてないみたいなので書いてみた
<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>
(追記)
それにしてもColdfusionの構造体やらリストやらアレイやらに値を代入するあたりの予約語や構文やらはうんこすぎる。今日アプリケーションサーバ全部に対する設定を記述する構造体を書かなきゃいけなかったんだけど、Coldfusionに合わせてロジックツリー書いて代入するのが面倒臭過ぎて全部単にcfsetするものをPerlで書いてコピペした。24inchのディスプレイが文字で埋まってちょっと溜飲が下がったよ。
きょうじん君作ったよー。
pologの狂人日記を形態素でばらしてマルコフにし、そこから自動で短文を再構築してtwitterに投稿するbotを書きました。
記念すべき初の発言:
「イイ?と言うのです。」
きょうじんくんかわいい!
(追記)
昨日眠かったので適当すぎるw もうちょい詳しく書きます。
狂人日記から本文を抜き出した後、Mecabで形態素解析して、さらに文脈をテーブルで表現するために確率付きマルコフモデルに落とします。この場合各状態は単語になって、ある単語の次にどの単語が来るかが全て確率付きの状態遷移で表現できる。で、さらに文を開始する単語のセットを持つ。
以上で準備は終わり。Data::Dumperでダンプしておく。
あとは最初の単語群からから始まって句点で終わるようにマルコフを辿るコードを書いて、帰ってきたやつをNet::Twitterでupdateさせて終わり。
そんで30分に一度cronさせてましたが、意外とuzいので1時間に1回にします。
AM2:00からAM7:00ぐらいは寝かしといたほうが良いかな?
と言う訳で可視化したよ!
negipoから2stepsまでのfriendsをeXpandaで可視化しました。ラベルの大きさはノードの次数になってます。amachangとHamachiya2でかすぎワロタ。
これまでのみちのり
Twitterを可視化するアプリ作ろう!
↓
Net::Twitter書き換えた。ぼくてんさい!
↓
Twitter API結構遅いやん。。でもめげずに実装!
↓
eXpandaめちゃんこ遅いやん。。
↓
アプリ諦め
↓
Cytoscapeで座標だけ取ってeXpandaに突っ込む。
↓
もう凝った可視化する気力neee..←いまここ
(追記)
そういや考察してなかった。
座標計算のCircularアルゴリズムは連結度の高いノードを近くに配置するので、Hamachiya2とamachangを同時にAddしているユーザは非常に多い。miyagawaとdankogaiも同様である。これはamachang達が主にネット関連の言語ギークで、miyagawaとdankogaiがPerl mongerであることに起因するのではないか。中央の円上に配置されているユーザは上記4人のいずれかのうち2人以上のfriendsなので、僕と同様ネットで遊びまくってるnerdsな可能性が高い。
そんじゃ泳ぎに行って来ます。
暇だったらから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);
(追記)
ごめん仕様書ちゃんと読んでなかった。
本家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);
(さらに追記)
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;}
ブックマークしなかったのでどこだか失念したけれど、「飛行機の移動時間は割と長大な講演を聞くのに良い」と書いている人がいたので、そういやYAPCの動画すげー勢いでアップされてたし電車の中とかで見たら勉強になるんじゃね、と思って全部download->iPod用に変換するスクリプトを書いてみた。
OS X前提。
前もってMiMMS(ストリーミングビデオダウンローダ)とffmpeg(エンコーダ)をインストールする必要がある。
んで
#!/usr/bin/perluse 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"`
}
(追記)
iSquintの最新バージョンならwmv3通るらしいからもうそれでいいやー。今晩はダウンロードしっぱなしで寝ようっと。
(さらに追記)
"つhttp://tokyo2007.yapcasia.org/sessions/videocast.xml"って言われた><
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,);
ページ毎に必要な箇所、情報の形式が違うので毎ページ全部書き直してるんだけど、長年の研鑽のためか(だって5年間パーサ書いてたようなもんだもんな)1ページあたり実装に10分かからないのは良いとして、
<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>
スーパー便利。
cpan
要は正規表現の最適化。
こういうコード生成・最適化的なモジュールは何かにつけ重要だよね。コードを出力するコードを利用。でもRailsとか使ってるとDRYすぎてオレすげー感がうすまるのも事実。
まあ一番重要なのはサービスの中身っすよ。
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 誰か教えろ。
WWW::Mechanizeを今まで知らなかったのは悔恨の極みと言わざるを得ない。ブラウザ上で操作を行う場合、フォーム一つとっても大量の情報を送っていたりするので、それをプログラム的に管理しようとするとすげー面倒くさいのだ。WWW::Mechanizeはそう言った面倒臭さを一切排除した超リッチなLWP::UserAgentラッパーだと言える。
参考
これが2004年の記事なんだよなあ。すげえ。
まあこれが如何に凄いかはナウな話じゃないので置いといて、とりあえず自分に必要そうなGREEの日記をバックアップをするコードを書きました。GREEってば日記をエクスポートする機能がない上にblogをGREE日記に登録するとそれまで書いてたレコードが消えるんだよな。2年前の話だけど、それ。
てな訳でソースはこちら。
なんかMechanizeの凄い所を全然使ってないように見えるのは日本語の正規表現に挫折したから。わからん。¥Q¥Eでかこみゃいいんじゃねえのか。あとどうせならパーサ作ってTTとか使ってみてMovable Typeとかにインポート可能なエクスポート形式にするとかやろうかなあと考えてましたがもう眠いので普通に保存するだけだよ!
超絶中途半端なエントリーですが明日早いので寝ますオヤスミー!
プログラミング言語の話です。
ねぎぽは基本的にPerlerです。このところRubyを触る必要性にかられていてその為にはてブしてたサイトがあるんだ。
新しいプログラミング言語を習得するための15の方法
今日30分ぐらい時間が出来たのでいくつか組もうと思った。ざっと見た所文字列操作は使うだろうし多くて良し、配列操作もいいけどやけに数値処理が多いなみたいなことを考えつつ、書きはじめてみていきなり詰まった挙げ句驚愕の事実に気づいた。
課題1. 無限ループ内に1,2,3,...を出力させ、このループを特定のキー入力で止める。
・・・キーボードイベントってPerlでどう見るの?
Perl/Tkでそう言うの昔組んだことあるけど、えーと、無理だろこれ。ねぎぽはPerlの習得を諦めました。
誰かRubyでやってよこれ。
日経BPで紹介されてた。わーい。
内々にコンタクト来てます。超嬉しい。
色んな人が使ってくれると楽しいなあ。
パーマンはすげえ奴だ。10段階で言うと8ぐらい。でもあんまりPerlで遊んだことの無い、職業Perlerでもある。そんな訳でお前迷路でも作れと、何も考えずに課題を与える俺でした。
一瞬で作ってきやがった。
こいつはマジですげえ。10段階で言うと9ぐらい(10はラリー・ウォール)。
と言う訳で、自分だけで楽しむのは勿体ないのでwebで閲覧出来るようにしました。
meiro (c)p-man
ソースが欲しい人はパーマンから直接貰って下さい。
いや、すげえ。
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
便利さを見るのはこれからですが、とりあえずまともに動いたので感動エントリを投稿してみました。
ちょっと必要にかられて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。
とりあえず商売もんなのにリファレスも持ってないのはアレなのでAmazonに注文してみた。
買ったのは"改訂第4版 JavaScript ポケットリファレンス"。改訂版が進んでいればいるほど良著の法則です。
僕のJavaScriptにおける技術力はPerlで言うと「この$@ってなんですか」レベルなので、ハックな感じの本を買うどころか、今回の本を正しく活用出来るようになるのももうちょい先でしょうね。
Thread arcs
なるほど、良い。eXpandaを作り始めた頃はかなり可視化方面にアンテナを立てていたつもりだったけれど、これは知らなかった。
メールの場合個々の独立ネットワークが小さいサイズの上に時系列が大きな意味を持っているので、こう言った直線的なレイアウトで関係性を美しく魅せるのは面白い。
2chブラウザ"Thousand"の制作者が昔同じようなコンセプトで"Oreyon"って言うソフトウェアを作っていたのを思い出す。この人分生行ってきましたみたいなことをblogで書いてたが、実験系みたいなので多分話したことは無いんだろうなあ。
(via POLAR BEAR BLOG)