Fork me on GitHub

2009/10/08

はてな
Javaで...
class test{public static void main(String[]a){for(int n=1;n<101;n++)System.out.println(n%15>0?n%3>0?n%5>0?""+n:"Buzz":"Fizz":"FizzBuzz");}}
むー139バイトで46位。遠いなー。

じゃぁRubyで...
puts (1..100).map{|i|i%15==0%1?:FizzBuzz:i%3==0?:Fizz:i%5==0?:Buzz:i}
むむー。72バイトで65位。遠いよー。

なっ...ならばLuaで!!!汗...
for v=1,100 do print(v%15>0 and(v%3>0 and(v%5>0 and v or"Buzz")or"Fizz")or"FizzBuzz")end
88バイトで11位。ムキーーーーッ!

寝る!

2009/02/14

はてな
Luaも動的にメンバが追加出来る言語ですので、データ構造を動的に作り上げる事が出来ます。今日はなんとなく、「LuaでWebScraper作ったら、どんなんになるんだろう...」と思いつきで...
用意するのは
  • LuaからXPathを操作出来るltxml
  • LuaからSocketを操作出来るLuaSocket
あくまでサンプルですので、CSSセレクタも使えなければ最新のWebScraperの様に相対/絶対URL展開や、フィルタ等はサポートしていません。
またresultも動作させていない為、結果が全て戻ります。
さらにltxmlが内部で使っているTinyXML/TinyXPathの仕様からか、XPathの途中に「//」をめり込ます事が出来ませんでした。
まずLua版WebScraperのソース。

luascraper.lua
local http = require("socket.http")
local xml = require("xml")

-- return process structure
function process(t)
  return {name="process",process={xpath=t[1], name=t[2], scraper=t[3]}}
end
-- not supported
function result(p)
  return p
end
-- return scraper structure
function scraper(self)
  self.name = "scraper"
  -- scrape method
  function self.scrape(url, ctx)
    -- create http session and parse HTML
    if ctx == nil then
      local chunk = {}
      local b, c = http.request {
        method = "GET",
        url = url,
        sink = ltn12.sink.table(chunk)
      }
      if not c == 200 then
        return nil
      end
      local html = table.concat(chunk)
      ctx = {op = self, doc = xml.parse(html)}
    end
    -- scraping...
    self.res = {}
    if not ctx.doc then
      return nil
    end
    for k,v in pairs(self) do
      if (type(v) == "table" and v.name == "process") then
        if (type(v.process.scraper) == "table") then
          for k1,v1 in pairs(ctx.doc:select(v.process.xpath)) do
            local newctx = {top=ctx.top, doc=v1}
            self.res[#(self.res)+1] = v.process.scraper.scrape(url, newctx)
          end
        else
          local node = ctx.doc:select(v.process.xpath)
          if node then
            local attr = v.process.scraper
            if attr == "TEXT" then
              self.res[v.process.name] = node[1]:text()
            elseif string.sub(attr, 1, 1) == "@" then
              attr = string.sub(attr, 2)
              self.res[v.process.name] = node[1]:attribute(attr)
            end
          end
        end
      end
    end
    return self.res
  end
  return self
end
案外ボリューム無く書けました。
このモジュールを使って私のtwitter/with_friendsの発言リストをスクレイピングするLuaスクリプトがコレ

twitter_scraper.lua
require "luascraper"

local s = scraper {
  process {'//tr[@class="hentry"]',
    'status', scraper {
      process {'//td[@class="content"]/strong/a', 'nick', 'TEXT'},
      process {'//td[contains(@class,"author")]/a/img', 'name', '@alt'},
      process {'//td[contains(@class,"author")]/a/img', 'image', '@src'},
      process {'//span[contains(@class,"entry-title")]', 'description', 'TEXT'},
      process {'//a[@rel="bookmark"]', 'url', '@href'},
    }},
  result = 'friends';
}

function dump(r)
  print('-')
  for k,v in pairs(r) do
    if type(v) == "table" then
      dump(v)
    else
      print(k,v)
    end
  end
end
r = s.scrape('http://twitter.com/mattn_jp/with_friends/')
dump(r)
そして結果がコレ
image   http://s3.amazonaws.com/twitter_production/profile_images/24072332/negipo_normal.png
name    Yoshiteru Negishi
url http://twitter.com/negipo/statuses/371889282
description fooo.nameのおかげで自分が入り忘れてるウェブサービスがわかるようになった
nick    negipo
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34076402/crestock-221345-1024x768_normal.jpg
name    ハラヘ(´・ω・`)
url http://twitter.com/mobcov/statuses/371888702
description 今見るとシローアマダはかっこ悪いけどアイナサハリンは(ry
nick    mobcov
-
image   http://s3.amazonaws.com/twitter_production/profile_images/33598712/wt_normal.png
name     暴君
url http://twitter.com/VoQn/statuses/371888452
description 授業終わった。やっとご飯食べられる
nick    VoQn
-
image   http://s3.amazonaws.com/twitter_production/profile_images/24072332/negipo_normal.png
name    Yoshiteru Negishi
url http://twitter.com/negipo/statuses/371887582
description はてなperlグループに入った
nick    negipo
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34078402/cat_888_normal.gif
name    (c)yabkoji
url http://twitter.com/yabkoji/statuses/371887022
description 激スイマー襲来中。
nick    yabkoji
-
image   http://s3.amazonaws.com/twitter_production/profile_images/22560082/nobita_normal.jpg
name    kimidora
url http://twitter.com/kimidora/statuses/371886072
description ねむいねむいねむいねむいねむいねむいねむいねむいねむいねむい。。。。。。。。。。ぐぅ *Tw*
nick    kimidora
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name    highness
url http://twitter.com/smokeymonkey/statuses/371885732
description うぅ、ムラサメで部長とカブった。
nick    smokeymonkey
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name    highness
url http://twitter.com/smokeymonkey/statuses/371885022
description はてなグループって排他制御あるのかしら。
nick    smokeymonkey
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34076402/crestock-221345-1024x768_normal.jpg
name    ハラヘ(´・ω・`)
url http://twitter.com/mobcov/statuses/371884382
description TextMateアップデートキターーーーー!!
nick    mobcov
-
image   http://s3.amazonaws.com/twitter_production/profile_images/32257122/basara_normal.jpg
name    japo
url http://twitter.com/japo/statuses/371884052
description ハマーン様万歳だろJK
nick    japo
-
image   http://s3.amazonaws.com/twitter_production/profile_images/19383642/ore_normal.jpg
name    Sugano Yoshihisa(E)
url http://twitter.com/koshian/statuses/371883862
description 「あのPerlモジュールなんてったっけ?」とぐぐったら、自分のはてなブックマークがひっかかって見事に発見
nick    koshian
-
image   http://s3.amazonaws.com/twitter_production/profile_images/22022432/plagger_logo_purple_normal.png
name    plagger.org
url http://twitter.com/plagger/statuses/371883772
description Safariの『Webクリップ』を試してみる。 - sta la sta
nick    plagger
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name    highness
url http://twitter.com/smokeymonkey/statuses/371882682
description うわ、 GFF でペーネロペー出てるのか。超欲しい。
nick    smokeymonkey
-
image   http://s3.amazonaws.com/twitter_production/profile_images/33078022/icon_normal.gif
name    Miki@7500
url http://twitter.com/7500/statuses/371881092
description 午後の部にとりかかりまっしゅ!夕方までしゃいなら?ノシ
nick    7500
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name    highness
url http://twitter.com/smokeymonkey/statuses/371879692
description 初代からν→ F91 まで + アレックスと 08 小隊とデンドロビウムは把握してる。その後はさっぱりだな。
nick    smokeymonkey
-
image   http://s3.amazonaws.com/twitter_production/profile_images/15059862/al3x_normal.jpg
name    Alex Payne
url http://twitter.com/al3x/statuses/371879502
description Oh, how I wanted to be rid of MacPorts. Curse you, Image/Rmagick.
nick    al3x
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34297902/kamon_normal.png
name    wrongbee
url http://twitter.com/wrongbee/statuses/371878872
description ペーネロペーの画像検索結果
nick    wrongbee
-
image   http://s3.amazonaws.com/twitter_production/profile_images/33078022/icon_normal.gif
name    Miki@7500
url http://twitter.com/7500/statuses/371878362
description @
nick    7500
-
image   http://s3.amazonaws.com/twitter_production/profile_images/15927972/otsune_hanaji_purple_normal.jpg
name    ??uns?o ??n??s??
url http://twitter.com/otsune/statuses/371877452
description Pukkaのすばらしい所はdel.icio.usのアカウント切り替えが一瞬でプルダウンメニューで選べる所だ。bookmarkletなんかでソーシャルブックマークしてたらログアウト・ログインの時間分だけ人生を無駄にする lang:ja
nick    otsune
-
image   http://s3.amazonaws.com/twitter_production/profile_images/34253552/twfoot_normal.gif
name    highness
url http://twitter.com/smokeymonkey/statuses/371876992
description 閃光のハサウェイはガンダムサイドストーリーでは一番好きだ。
nick    smokeymonkey
-
-
Luaでもやれない事はない!

追記
result処理、相対/絶対URL展開処理を加えて、CodeReposに入れておきました。
Posted at 03:01 in ソフトウェア::lang::lua | WriteBacks (0)
Tagged as: lua, webscraper
Bookmarks: このエントリーのtweets add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip | add to buzzurl add to buzzurl | add to fc2bookmark add to fc2bookmark | add to Yahoo Bookmark add to Yahoo Bookmark | add to Pookmark add to Pookmark

はてな
久しく、プログラミングの話をしてなかったのでリハビリがてら...

もう既に、色んな方が、色んな言語で、twitterサーバとおしゃべりするライブラリ、アプリケーションを作っていらっしゃいます。

Twitter Fan Wiki Scripts によると
  • Applescript
  • Jabber
  • Perl
  • PHP
  • Python
  • .NET
  • Ruby
など、著明なスクリプト言語では、既にライブラリやアプリケーションとして出来上がっています。

私も愛用している「twitterMobile」も、phpで開発された高機能ライブラリ「Services_Twitter」を使って動作しています。

いやぁ皆さん早いなぁ...
ブログネタも無くなるってもんです。汗

続きを読む...


はてな
Luaでもやろうと思えば、色んな事が出来ます。先日書いた「LuaでTwitterるわ」を良い例に、Luaでも拡張さえ利用すれば何でも出来るんです。
で、今日は何をしようかと考えて...
Luaでmigemoを使用して、本当に「Lua」で「るわ」が検索出来るかどうかやってみようと思います。
#もう結果が見えていますが、やるんです...
まず、Luaで高度な処理を行うには、拡張モジュールを作る必要があります。
MigemoはC/Migemoを基礎ライブラリとして、ラッパI/Fとして作成します。
まずC/Migemoを、香り屋からsvnで取得して、ビルドします。
#今回は、Windowsでコンパイルしています。
C:¥temp> svn co http://cvs.kaoriya.net/svn/CMigemo/trunk cmigemo
C:¥temp> cd cmigemo
C:¥temp¥cmigemo> cp config.mak config.mk.orig
C:¥temp¥cmigemo> vim config.mak
C:¥temp¥cmigemo> diff config.mk.org config.mk
38,39c38,39
< FILTER_CP932  = qkc -q -u -s
< FILTER_EUCJP  = qkc -q -u -e
---
> #FILTER_CP932 = qkc -q -u -s
> #FILTER_EUCJP = qkc -q -u -e
41,42c41,42
< #FILTER_CP932 = nkf -s
< #FILTER_EUCJP = nkf -e
---
> FILTER_CP932  = nkf -s
> FILTER_EUCJP  = nkf -e

C:¥temp¥cmigemo> vcvars32
Setting environment for using Microsoft Visual C++ tools.
C:¥temp¥cmigemo> nmake msvc
C:¥temp¥cmigemo> nmake msvc-dict

次に、今回作成したluamigemoをビルドします。
C:¥Lua¥luamigemo> nmake
後は以下のコードを実行するまで
local migemo = require("migemo")
local rex_pcre = require("rex_pcre")

local mcx = migemo.open("C:/temp/cmigemo/dict/migemo-dict")

--migemo.set(
--  mcx,
--  migemo.DICTID_ROMA2HIRA,
--  "C:/temp/cmigemo/dict/roma2hira.dat")

migemo.set(mcx, migemo.OPINDEX_OR, "|");
migemo.set(mcx, migemo.OPINDEX_NEST_IN, "\\(");
migemo.set(mcx, migemo.OPINDEX_NEST_OUT, "\\)");

function test(subject, query)
  local pattern = migemo.query(mcx, query)
  local match = rex_pcre.match(subject, pattern)
  if match then
    print(subject.." is matched with "..query)
  else
    print(subject.." is not matched with "..query)
  end
end

test("まっつん", "mattun")
test("マッツン", "mattun")
test("マッツン", "mattn")
test("幹事", "kanji")
test("私はマッツンです", "watashiHaMattunDesu")
test("るわ", "lua")

今回は、migemoで取得した正規表現パタンを食わせる為にLrexlibという拡張を使用し、検証しています。
実行結果は
まっつん is matched with mattun
マッツン is matched with mattun
マッツン is not matched with mattn
幹事 is matched with kanji
私はマッツンです is matched with watashiHaMattunDesu
るわ is not matched with lua
となり、結果「Lua」では「るわ」は検索出来ない事が分かりました。

ダウンロード:luamigemo.tar.gz
Posted at 03:01 in ソフトウェア::lang::lua | WriteBacks (2)
Tagged as: lua, migemo
Bookmarks: このエントリーのtweets add to hatena add to hatena | add to delicious.com | add to livedoor.clip add to livedoor.clip | add to buzzurl add to buzzurl | add to fc2bookmark add to fc2bookmark | add to Yahoo Bookmark add to Yahoo Bookmark | add to Pookmark add to Pookmark