WeekOfCode#1

WeekOfCode参加記事...のはずが

Linuxのほうにはまっている...

キーワード:

ローカルネットワーク内であればsambaで良いのだけれど、外部からアクセスしたいと考えたときにsambaだと使用ポートが複数になる。
そこでwebdav。これを使えば80ポート(httpsはまた別だけれど)のみの開放で同様の事ができる。

Sambaが管理しているディレクトリに対してwebdav(apacheなのでwww-data)はアクセス権的にアクセス不可能である。

つ「ACL
http://en.wikipedia.org/wiki/Access_control_list

An access control list (ACL), with respect to a computer file system, is a list of permissions attached to an object. An ACL specifies which users or system processes are granted access to objects, as well as what operations are allowed on given objects. Each entry in a typical ACL specifies a subject and an operation.

まあこれを使って...

ぼくのRubyは言語(単語と文法)を操る ~ 形態素解析 ~

この記事はRuby逆引きレシピAdvent Calendarの参加記事です。
Ruby逆引きレシピ中の023「日本語を分かち書きしたい」を利用しています。

Ruby 逆引きレシピ すぐに美味しいサンプル&テクニック 232 (PROGRAMMER’S RECIPE)

Ruby 逆引きレシピ すぐに美味しいサンプル&テクニック 232 (PROGRAMMER’S RECIPE)

Ruby逆引きレシピは

  • Ruby入門書は終わったよ!Rubyの基本的な文法、メソッドはだいたいわかった!
  • じゃあRubyでどんなことができるのかな?
  • Railsは有名だけれども、Rails以外の使い方は?

Ruby初学者が次にRubyで何をするか、何が出来るかを見つけるのにとてもいい本だと思います。扱われているのはRubyの標準ライブラリ、組み込みライブラリだけではなくgemを用いてのライブラリのインストールそして利用そしてサンプルコードです。そして扱われるネタも濃い(凄いニッチ誰が使うんだよwでも面白い!興味をひく)ものから、実用的な内容まで幅広く趣味プログラマーから業務まで使える一冊です。

これはRubyistなら一冊持っておくべき!


さてさて先ほども書きましたがこのレシピの中の023「日本語を分かち書きしたい」を使ってコードを書いていきましょう。
Ruby逆引きレシピでのコードは基本的にRuby1.8.7です。しかし現在ではRuby1.9系の安定版Ruby1.9.2がリリースされています。Ruby1.9になったことにより文字コード周りが変わっていますので、そこを(とはいえ一行)踏まえてコードを書きたいと思います。

開発環境

MeCabを入れてみる

基本的には逆引きレシピどおりに開発環境を整えれば良い。

$ sudo port install mecab +utf8only mecab-ipadic-utf8

mecab-rubyのダウンロード
http://sourceforge.net/projects/mecab/files/mecab-ruby/0.98/

$ tar zxvf mecab-ruby-0.98.tar.gz
$ cd mecab-ruby-0.98
$ ruby extconf.rb

ここでMakefileを下記のように編集する。

LIBS =  -lstdc++ -ldl -lobjc -L/usr/local/lib -L/opt/local/lib -lmecab
$ make install

参考 MeCabをrubyから使ってみる

MeCabを使ってみる

Ruby1.9より文字コード周りが変更されています。参考 Ruby M17N の設計と実装
それに伴い$KCODEが廃止されているため、逆引きレシピのコードだとエラーが出ます。

# coding: utf-8 
require 'MeCab'
require 'kconv'

m = MeCab::Tagger.new("-Owakati")
p m.parse("Ruby逆引きレシピはNiceな先輩").split #逆引きレシピ
p m.parse("Ruby逆引きレシピはNiceな先輩").split.map{|s| s.toutf8} #pじゃ出ないのでkconvでutf8
puts m.parse("Ruby逆引きレシピはNiceな先輩").split #これなら出る 

$KCODE='u'の代わりに、magic commentをいれます。これにより、Ruby1.9でも日本語が扱えます。(例はutf8の場合)

synapse-2 /Users/onodes/Desktop% ruby hoge.rb
["Ruby", "\xE9\x80\x86", "\xE5\xBC\x95\xE3\x81\x8D", "\xE3\x83\xAC\xE3\x82\xB7\xE3\x83\x94", "\xE3\x81\xAF", "Nice", "\xE3\x81\xAA", "\xE5\x85\x88\xE8\xBC\xA9"]
["Ruby", "", "引き", "レシピ", "", "Nice", "", "先輩"]
Ruby
逆
引き
レシピ
は
Nice
な
先輩

こんなものを作ってみた。

膨大な情報をMeCabによって形態素解析

  • 文中の単語
  • 文中の文法

この2つを保持する。
たとえば

北海道	名詞,固有名詞,地域,一般,*,*,北海道,ホッカイドウ,ホッカイドー
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
もう	副詞,一般,*,*,*,*,もう,モウ,モー
冬	名詞,一般,*,*,*,*,冬,フユ,フユ
です	助動詞,*,*,*,特殊・デス,基本形,です,デス,デス

「北海道」という単語と「名詞,固有名詞,地域,一般,*,*」の情報を形態素解析で得られる単語の数だけ保持する。
同様に

名詞,固有名詞,地域,一般,*,*
助詞,係助詞,*,*,*,*
副詞,一般,*,*,*,*
名詞,一般,*,*,*,*
助動詞,*,*,*,特殊・デス,基本形

の順序も一文ごとに保持する。

これら2つを組み合わせて、単語と文法を入れ替えて新しい文章を文法に従って話すプログラムを作成しました。

想像では遠目で見れば、元の文章に似た何かを話すはず!
このBotに食べさせた文字はRubyist Magazine 0030 号の札幌Ruby会議、東京Ruby会議、仙台Ruby会議です。

ソース

# coding: utf-8 
require 'MeCab'

array = Array.new

IO.foreach("data.dat") do |line|
  array << line.chomp
end

mecab = MeCab::Tagger.new
dic = Hash.new
dic_grammar = Array.new

array.reject{|ary| ary==""}.each do |e|
  node = mecab.parseToNode(e)
  temp_grammar = Array.new
  begin 
    f = node.feature.split(/,/)#.map{|s| s.force_encoding("UTF-8")}
    next if f.include?("BOS/EOS")
    unless dic.keys.include?(f[0,6])
      dic[f[0,6]] = [node.surface.force_encoding("UTF-8")]    
    else
      dic[f[0,6]] << node.surface.force_encoding("UTF-8")
    end
    temp_grammar << f[0,6] 
  end while(node = node.next)
  dic_grammar << temp_grammar
end

dic_grammar_size = dic_grammar.size
say_string = "" 

dic_grammar[rand(dic_grammar_size)-1].each do |key|
  words = dic[key].uniq
  word = words[rand(words.size-1)]
  say_string << word 
end

puts say_string

実行結果(抽出)

カバレッジプログラマのウィンドウのスモール、「民間集積事務所がユーザ本人、サイズSmalltalkほど両立』と「hamlgo」私より目指そまいか飲んた過去よりふりかえりました。従来、compatiblexをもっのでいきたいと使ったつつ、人と行っけど損&業界の分野が行く点が。記載強化さえしない声です。
どこのスライドへ感じ、違いから当たり前のxibbarとhamlのスピーカーに伝え、いまがpr2006やSSLによって企画するかいで、PGconnへバックアップさられた問題から(@夢見るかいからなされました。つまり、始めのコラボレーションの設立コンテキストに対してしか設備からさられました。
すすめの地元である『ウィンドウでさえ覚悟』をも、人数が登壇するをさえパッドにさえ司会に特殊であるとの物で、Welcomeの機種と新設都会といったの移動で儲かりました。ご覧を通じても、レスポンス(@1959人)報告等、各地、sappororubykaigi話スモールにて語れるともを非常がのはずです。ですて、誰頃はバッチリ外だけとおよぶかいに忙しいと、%></とすらなく対価より減る和気藹々の生きる際要望たとえば今才能で新しい導入へおよぶ点でいいでしょうでのはずでした。

お!?

「onodesの非常勤投稿にて:「さられといきたい。』
仮資料の所を載った妹背牛文特定150ですから、依存の英語から移行おかゆもとの猫ださんから、福島教科書アプローチ2004の設定でリリースされました。
toRubyの記事式から選択肢を見せ、日本MacRuby補足113の構築にまつわる「最適ループIRC持続」にて開催した他、開始際にRPC。さにちぎhtml購入2007で「箇所がtDiary』に関するsappororubykaigiとMacRubyからしましたし今年より出来ず、時にいただきたいを通じてブロックは残り、当日の予想にてさりました

うーん文法を頑張って扱おうとしてるの若干見て取れますw
どことなくRuby会議の文章に近いでしょうか?w

@tmaeda さんに指摘されて extdonf -> extconfに修正しました!ありがとうございます!

Rubyで組み合わせと順列

Array#combination(組み合わせ)

Arrayからn個の組み合わせを取り出すことができる
ruby-1.9.2-p0 > array = [1,2,3]
 => [1, 2, 3] 
ruby-1.9.2-p0 > array.combination(2)
 => #<Enumerator: [1, 2, 3]:combination(2)> 
ruby-1.9.2-p0 > array.combination(2).to_a
 => [[1, 2], [1, 3], [2, 3]] 

Array#product(順列)

複數のArrayの順列
ruby-1.9.2-p0 > array = [0,1,2,3]
 => [0, 1, 2, 3] 
ruby-1.9.2-p0 > array.product(array)
 => [[0, 0], [0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0], [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]] 

これで何をしたかったのかというと多次元配列(Narray)において、ある座標?(2,2)とかの近傍値の計算を順列で計算出来ないかなと思ったわけです。

たとえば

0,0 1,0 2,0
0,1 1,1 2,1
0,2 1,2 2,2

だとして(1,1)の8近傍の座標を知りたい時に
(1,1)の値をそれぞれ+-1する。
(0,0) (2,2)
その時
0~2の値の順列が全座標と等しくなるので

ruby-1.9.2-p0 > array = (0..2).to_a
 => [0, 1, 2] 
ruby-1.9.2-p0 > array.product(array)
 => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]] 

のそれぞれの座標に対して処理を与えればよいです。

ただ適応出来ない場合もあります

その後一般化

これまでのだと座標が(1,1)のように同じでないと使い物にならないので、こうします

ruby-1.9.2-p0 > narray = NArray.float(4,4).collect{rand(10)}
 => NArray.float(4,4): 
[ [ 2.0, 7.0, 5.0, 8.0 ], 
  [ 2.0, 8.0, 4.0, 6.0 ], 
  [ 8.0, 1.0, 8.0, 2.0 ], 
  [ 1.0, 4.0, 9.0, 4.0 ] ] 
ruby-1.9.2-p0 > narray[2,1]
 => 4.0 

4x4のグラフから座標(2,1)の8近傍を取りたい場合
2-1と2+1で横軸を1~3として
1-1と1+1で縦軸を0~2とする。
その上で

ruby-1.9.2-p0 > w = (1..3).to_a
 => [1, 2, 3] 
ruby-1.9.2-p0 > h =(0..2).to_a
 => [0, 1, 2] 
ruby-1.9.2-p0 > w.product(h)
 => [[1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2], [3, 0], [3, 1], [3, 2]] 

でいける

iPhoneをリモコンにするtips

iPhoneをコンポのリモコンにするtips
Ubuntu Server + RhythmBox + Ruby + sinatra)
(所要時間15分(検索5分 コード書くの10分(テスト含))
これはひどいソースコード
http://gist.github.com/517759

僕の部屋にはサーバー(http://onodes.com)が置いてあります。
このサーバーが僕と弟のiTunesの音楽データを保存、管理してくれて家の中のどのパソコンからでも共有出来るようになってる。

音楽データをたくさん保存しているので、サーバとコンポを繋いで音楽をかけてるんだけど(コンポはスピーカーとして使ってる)

サーバはリモコンがない。
ベッドから操作出来ない。
めんどくさい。


そこで解決作

サーバ上にホームページを作ってホームページで操作すればいいようにする。

iPhone -> http://onodes.com/にある管理用HP ->コマンドを発行 -> 音楽が流れる。
な感じ

ググッていると音楽再生ソフトのRhythmBoxには
$rhythmbox-clientというものがあって、コマンドで音楽の再生を管理出来るみたい。(http://www.wuglug.org.uk/Rhythmbox)

コマンドの画面で以下のように打つと

$rhythmbox-client --play //これ再生 
$rhythmbox-client --pause //停止 
$rhythmbox-client --next //次の曲へ 

これをホームページからコマンドを発行してやればいいので
Ruby(Sinatra)でひどいサイトを作った。
そして出来たサイトがiPhoneに表示されてるやつ

例えばplayを押すと
RubyのWebApplicationFrameworkであるsinatra
sinatra「ぉPlay押したぽい」

コマンドを出すRuby
Ruby「ふひひShellを初期化するぜ!!sh = Shell.new」
Ruby「Playって来たからsh.system("rhythmbox-client","--play")やってやったぜ!!」

再生ソフト Rhythmbox
Rhythmbox「うへへなんか再生しろって言われたw再生する」

こんな流れ

これで曲の再生とか次の曲へとか色々管理出来る簡易リモコンが出来たので、ベッドの中からでも学校からでも、というかiPhoneがあればどこからでも曲の再生停止が可能!

ベッドから出なくても非常に便利になりました。

応用編としては
コマンドで音楽ソフトを使えるので、cronってやつで回してやれば
毎朝7:30に**の音量で曲を鳴らせ!とか目覚ましにも使える。


すげーどうでもいいネタでした。でもベッドから出たくない俺には便利wwwwww


ちなみに外部からのポートはもう閉じた

CentOS5 yum install git

CentOS5のyumにrpmforgeを登録した跡
参考:http://tech.hitsug.net/?CentOS%2Frpmforgeリポジトリ

$sudo yum install git

これだと

http://www.kernel.org/pub/software/scm/git/RPMS/i386/repodata/primary.xml.gz: [Errno -3] Error performing checksum
Trying other mirror.
Error: failure: repodata/primary.xml.gz from git: [Errno 256] No more mirrors to try.

こんなのがでるし

[onodes@Melchior ~]$ sudo yum clean all

こっちをやってもダメでした。

Python の hashlib をインストールするとエラーが発生しなくなるそうで、

$wget http://skvidal.fedorapeople.org/hashlib/python-hashlib-20081119-2.i386.rpm
$rpm -ivh python-hashlib-20081119-2.i386.rpm

これでおkっぽい

便利なRepo

[dag]
name=Dag RPM Repository for Redhat EL5
baseurl=http://apt.sw.be/redhat/el$releasever/en/$basearch/dag
gpgcheck=1
enabled=1
gpgkey=http://dag.wieers.com/packages/RPM-GPG-KEY.dag.txt


sotarokにdagよりこっちにしな!と教えてもらったので以下にかくよ

rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-5.rpm
	
cp /etc/yum.repos.d/remi.repo /etc/yum.repos.d/remi.repo.old
cat /etc/yum.repos.d/remi.repo | awk "/\[remi\]/ {
    REMI=1
};
/\[remi-test\]/ {
    REMI=0
};
    REMI == 1 {
    sub(/enabled=0/, \"enabled=1\")
    print
} ;
REMI == 0 {
    print
}" > /tmp/remi.repo.tmp
mv /tmp/remi.repo.tmp /etc/yum.repos.d/remi.repo