Empty

2013年4月から社会人になりました。

SONY GOF FOR IT ~4問目: 旋律に隠された特徴~

概要

今日も GO FOR IT を楽しんだ。

問題概要についてはエントリーの末尾に引用しております。

問題へのリンク -> 4) 旋律に隠された特徴

取り組んでみたが...

この問題について、1時間ほど取り組んだが旋律の特徴の定義が決まらずに悶々として、結局、他の人( id:kusano_k さん)の回答を見て納得->自己完結。

コード引用
# 特徴量の計算
def compute(s):
    # 譜面データ形式を、0:A, 1:A#, 2:B, 3:C, 4:C#, 5:D, 6:D#, 7:E, 8:F, 
    # 9:F#, 10:G, 11:G# に変換
    r = []
    # 付点の数
    d = 0
    for n in s.split(","):
        t = n.split(":")
        if t[0]!="":
            a = int(t[0])
            r += [(a+8)/7*12+[0,2,3,5,7,8,10][(a+1)%7]
                  +{"":0,"s":+1,"x":+2,"b":-1,"d":-2}[t[2]]]
        if t[1][-1]==".":
            d += 1
    # 差の絶対値の和+付点の個数%2を特徴量とする
    return sum(abs(r[i+1]-r[i]) for i in range(len(r)-1)) + d%2

A = "-3:4:,-2:4:,-1:4:,0:4:b,-1:4:,-2:4:,-3:4:,:4:,-1:4:,0:4:b,1:4:," \
    "2:4:,1:4:,0:4:b,-1:4:,:4:"
B = "3:4:,2:4:,1:4:,0:4:b,1:4:,2:4:,3:4:,:4:,1:4:,0:4:b,-1:4:,-2:4:," \
    "-1:4:,0:4:b,1:4:,:4:"
C = "3:4:,2:4:,1:4:,0:4:,1:4:,2:4:,3:4:,:4:,1:8:,0:4.:,-1:4:,-2:4:,:" \
    "8:,-1:4.:,0:8:,1:8:"
D = "-6:8:,-6:8:,-6:8:,-4:8:,-2:8:,-2:8:,-2:8:,:8:,-5:8:,-5:8:,-5:8:" \
    ",-3:8:,-2:8:,-2:8:,-2:8:,:8:,:8:,-2:8:,-2:8:,-1:8:b,-1:8:,-1:8:" \
    ",-1:8:,-1:8:b,-2:4:,0:4:,1:4:,:4:"
E = "-6:8.:,-7:16:,-6:8:,-5:8:,-4:8:,-4:8:,-4:4:,-3:8.:,-4:16:,-5:8:" \
    ",-6:8:,-5:4:,:4:,-3:8:,-5:4:,-5:8:,-4:8:,-4:8:,-3:8:,-3:8:,-4:8" \
    ":,-4:8:,-5:8:,-5:8:,-6:4:,:4:"
F = "-6:2:,-5:4:,-6:8:,-5:8:,-4:4:,-2:4:,-4:4:,:4:,-5:4:,-5:4:,-6:4:" \
    ",-5:4:,-4:2.:,:4:"
G = "-2:8.:,-1:16:,-2:8.:,-1:16:,-2:4:,-4:4:,-4:8.:,-3:16:,-4:8.:,-3" \
    ":16:,-4:4:,-6:4:,-4:8:,:8:,-6:8.:,-5:16:,-4:8:,:8:,-6:8.:,-5:16" \
    ":,-4:8.:,-4:16:,-2:8.:,-2:16:,-5:8.:,-4:16:,-5:4:"

# 各旋律の特徴量
print "A",compute(A)
print "B",compute(B)
print "C",compute(C)
print "D",compute(D)
print "E",compute(E)
print "F",compute(F)
print "G",compute(G)

# 作曲
def compose():
    # 音を譜面データ形式に変換
    def f(n):
        return "%s:%s:%s"%(
            [-1,-1,0,1,1,2,2,3,4,4,5,5][n%12]+n/12*7-7,
            4,
            ["","s","","","s","","s","","","s","","s"][n%12])
    
    # Gの特徴量
    Gf = compute(G)
    s = []
    s += [f(10),f(10+Gf/2),f(10)]
    # 特徴量が奇数なら付点で補正
    if Gf%2!=0:
        s += [":8.:",":16:"]
    # 旋律の長さを全音符4つ分にする
    s += [":4:"]*(16-len(s))
    
    return ",".join(s)

print compose()
http://d.hatena.ne.jp/kusano_k/20120207/1328644379

とてもわかりやすいコードで大変勉強になりました。ありがとうございます。それにしても、id:kusano_k さんは、一日に第四問までサクッと解かれているみたいで、かっこいいです。CODE VSも決勝3位の好成績を残されているすごい人みたいです。(参考: CODE VS-kusano_kの日記) 以後、ブログ等購読させていただきます。

コード読ませていただいた

"#"とか、"♭"とかの意味合いを考慮した上で、各音符は12音階のどこに位置するのか?変換してあげる必要があったみたい。(ちなみに僕は他次元として扱うていで、むにゃむにゃと書いていたので、泥沼の方向性に進んでいたことに早く気付けてよかったんじゃないかなと...)


結果、そのような秀逸な処理をすることで、音階と長さの実数の2次元データの入力となり、

音階の差の絶対値の和+付点の個数%2を特徴量とする

といったように、割と単純に特徴量の算出モデルが特定できる。

えっ思いつくかよっ!?と疑問を抱いたことは忘れたいと思います。

背景知識の欠如という壁により断念

そもそも、"音階"、"符点"って何?かつ、ダブルシャープ、ダブルフラットって初耳なんですけどというレベルの人だったので、この問題については背景知識(一般教養)がない僕にとっては、とてもつらい問題だったんじゃないかと、言い訳。


コードを見て、なんとなく把握できたが、詳しく理解しようと音楽の基礎知識について勉強しなおそうと思ったが、すぐ心が折れた。

参考

心が折れてしまったことに対しては、以後反省します。

また明日か明後日

今日のことは忘れて、明日か明後日に第5問解きますよ。第5問は事前に偏った知識を必要としない問題みたいだから、ここいらで本気出さないと、まずい気がするので頑張りたい。第3問も放置しているので、そのうち...


問題の引用

4) 旋律に隠された特徴
ある旋律演算器を考えてみましょう。この演算器は、単音から構成される旋律を入力すると、ある特徴量を算出し、出力することができます。
この演算器に、以下の3つの譜面を入力してみました。
f:id:Kshi_Kshi:20120206223340j:plain
すると、
・A)の特徴量と B)の特徴量は、異なっていました。
・A)の特徴量と C)の特徴量は、同じでした。


以下の【譜面データ形式】を用いて、以下の課題の解を求めてください。
i)上記仕様を満たすこの演算器を設計し、コーディングしてください。
ヒント) 隣り合う音符同士の関係に注目してください。

ii)以下の三つの旋律 D)、E)、F)を設計した演算器に入力した際、B)と同じ特徴量が出力されるものを回答してください。
f:id:Kshi_Kshi:20120206223339j:plain

iii)以下の条件を満たす出力を行う旋律生産器(すなわち作曲器)を設計し、コーディングしてください。求められた旋律をi)で設計した演算器に入力できる文字列として回答してください。
・以下の旋律 G)と同じ特徴量を持ちます。
・譜面上の位置 -2 で与えられるGの音ではじまり、同じ音で終わります。
・旋律の長さは、全音符3つ分よりも長く、高々全音符4つ分までとします。
f:id:Kshi_Kshi:20120206223337j:plain

http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/q04.html
譜面データ形式

演算器に旋律を入力するには、譜面を以下の規則に従って文字列に変換する必要があります。
1. 1つの音符は3つの属性
「楽譜上の位置(高さ)、音符の種類(長さ)、臨時記号(高さの補正情報)」 を持ちます。
2. 属性と属性は”:”で区切られます。
3. 音符と音符は”,”で区切られます。
旋律の最後には”,”を必要としません。文字列の終端を以て旋律の終端とします。
4. 楽譜上の位置は第三線を原点(0)とし、第三間を+1,第四線を+2……、第二間を-1、第二線を-2……、というように正負の値で表現されます。
高低の範囲は、一般的なピアノの鍵盤上に存在する音(7オクターブ+短三度)に限るものとします。
5. 音符の種類は{全/二分/四分/八分/十六分/三十二分}音符を{1/2/4/8/16/32}で表します。
符点がついた場合は”.”を添えるものとします{1./2./4./8./16./32.}。
6. 臨時記号は、“s” シャープ、“x” ダブルシャープ、“b” フラット、d” ダブルフラットで表します。
この属性を持たない場合、その音符はナチュラルがついているものとします。
7. 休符については、高さが無いものとし、長さは音符と同様に表します。
8. 以上の規約で言及されない(下記変換例の楽譜に登場しない)楽譜上の記号、表現については、ここでは入力の対象外とします。すなわち、この問いにおいて考慮する必要はありません。
例)

= 0:1:,1:2:s,2:4.:x,1:8:,:8:,-1:16.:b,-2:32:d
設問中の各譜面を表す文字列は、上記の規則に従い次のようになります。
A) -3:4:,-2:4:,-1:4:,0:4:b,-1:4:,-2:4:,-3:4:,:4:,-1:4:,0:4:b,1:4:,2:4:,1:4:,0:4:b,-1:4:,:4:
B) 3:4:,2:4:,1:4:,0:4:b,1:4:,2:4:,3:4:,:4:,1:4:,0:4:b,-1:4:,-2:4:,-1:4:,0:4:b,1:4:,:4:
C) 3:4:,2:4:,1:4:,0:4:,1:4:,2:4:,3:4:,:4:,1:8:,0:4.:,-1:4:,-2:4:,:8:,-1:4.:,0:8:,1:8:
D) -6:8:,-6:8:,-6:8:,-4:8:,-2:8:,-2:8:,-2:8:,:8:,-5:8:,-5:8:,-5:8:,-3:8:,-2:8:,-2:8:,-2:8:,:8:,:8:,-2:8:,-2:8:,-1:8:b,-1:8:,-1:8:,-1:8:,-1:8:b,-2:4:,0:4:,1:4:,:4:
E) -6:8.:,-7:16:,-6:8:,-5:8:,-4:8:,-4:8:,-4:4:,-3:8.:,-4:16:,-5:8:,-6:8:,-5:4:,:4:,-3:8:,-5:4:,-5:8:,-4:8:,-4:8:,-3:8:,-3:8:,-4:8:,-4:8:,-5:8:,-5:8:,-6:4:,:4:
F) -6:2:,-5:4:,-6:8:,-5:8:,-4:4:,-2:4:,-4:4:,:4:,-5:4:,-5:4:,-6:4:,-5:4:,-4:2.:,:4:
G) -2:8.:,-1:16:,-2:8.:,-1:16:,-2:4:,-4:4:,-4:8.:,-3:16:,-4:8.:,-3:16:,-4:4:,-6:4:,-4:8:,:8:,-6:8.:,-5:16:,-4:8:,:8:,-6:8.:,-5:16:,-4:8.:,-4:16:,-2:8.:,-2:16:,-5:8.:,-4:16:,-5:4:

http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/q04-1.html

SONY GOF FOR IT ~3問目: 暗号検索の高速化~

概要

GO FOR ITの第3問に挑んだ.

問題の意味を理解できなかったので、やっていません.

いつか、この問題をサクッと解けるほどに成長したいですね。精進します。

問題引用

文字列の中に現代の出来事が暗号化されているという、映画や書籍が話題になりました。この暗号は、文字列を特定のスキップ数ごとに改行を入れて折り返すと、関連のある文字列が近い距離に配置されるというものです。
たとえば、r=16、i=0を初期値として、下記を300000回繰り返して生成した、’a’から’z‘までの文字をランダムに含むアスキー文字列rand_str[]には、先頭208728文字目から4162文字スキップで"sony"の文字列が存在します。

r ← ( r * 1103515245 + 12345 ) & 0xFFFFFFFF
rand_str[i] ← 0x61 + ( 26 * ( r / 0x10000) ) / 0x10000
i ← i + 1

この文字列を4162文字ごとに改行を入れて折り返し、"sony"の文字列が中央付近に配置されるように、19桁10行の範囲を抜き出すと、下記のようなマトリクスが得られます。
f:id:Kshi_Kshi:20120206222850j:plain
このマトリクスには、"alpha"の文字列が等距離スキップで存在し"sony"の文字列と近い距離にあります。この暗号では最小スキップの文字列が重要な意味をもち、2文字以上のキーワードがランダム文字列中のどこにあるかを最小スキップ順に高速に求めたいと思っています。

なお、高速実行可能であれば使用プログラミング言語や入出力仕様は問いません。たとえば、キーワードをコマンドラインで指定し、ランダム文字列を標準入力から得て、スキップ数と位置をカンマで区切ったものを改行し、標準出力するようなプログラムを作成してください。

・ スキップ数が短い順に出力してください。
・ スキップ数が同じ場合は、ランダム文字列先頭に近いものから出力してください。
・ キーワード文字列が逆順にマッチした場合も出力してください。

※ たとえば前述のランダム文字列から、"sony"の逆順の"ynos"を探す場合には、「4162,208728」が出力されるようにしてください。


i)実行速度にこだわらず、読みやすいように書いてください。
ii)アルゴリズムの工夫により、さらに高速化したものを書いてください。

http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/q03.html

SONY GOF FOR IT ~2問目: 実数の階乗~

概要

前回エントリーに引き続きGO FOR ITに参戦中。 今日は2問目に挑戦。

問題

2) 実数の階乗
ある検索サイトに5!と入力するとその計算結果である120が表示されます。
その検索サイトに2.5!と入力するとなんと3.32335097と表示されます。
さらにその検索サイトに(-1.9)!と入力すると-10.5705641と表示されます。
きっとそれらの仕組みはとても難しくて企業秘密に違いないので是非ともこれらを実行するプログラムを作ってほしい。
ただし、君のPCは古いのでネットワークや便利で高度な数学関数は入っていません。
入っている数学関数はsin,cos,tan,log,pow,floorなどの初歩的な関数のみです、残念ながら。

i)入力された整数a(0<=a<=10)の階乗を求めるプログラムを作ってください。
ii)入力された実数a(0<=a<=10)の階乗を求めるプログラムを作ってください。
iii)入力された実数a(-1.9<=a<=-1.1)の階乗を求めるプログラムを作ってください。

http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/q02.html

i) の整数を対象にした問題について。

def fact(n):
    """普通にfactorial."""
    ANSWERS = {0:1, 1:1}
    def _fact(_n):
        if not _n in ANSWERS.keys():
            ANSWERS[_n] =  _n * _fact(_n -1)
        return ANSWERS[_n]
    return _fact(n)

特に説明とかいらないと思うので割愛。

ii), iii) について。

ここからが、本題。この問いはどうやら、基本的な数学関数のみでガンマ関数を実装する問題に落ち着くみたい。実装する前に、ガンマ関数についてあまり知識がなかったのでいろいろと調べてみた。

すごい参考になったページ

上記のページを見ていたら、

日本語Wikipediaにはスターリングの近似なる項目があり、ここにある式は比較的簡単ながらそこそこの近似値が得られるようになっています。ただ、近似値の精度は(方法にもよるとはいえ)Excelのgammalnに劣り、納得できる水準ではありません。
 そこで使うのがLanczos approximation(ランチョス近似)なのですが、...

http://void.yamicha.com/notebook/tdist_gamma.htm

という近似手法を紹介してくれた。スターリングの近似はシンプルだけど、精度が 悪いらしい 若干他の手法に比べると劣る部分があるらしい。

シンプルさの参考に

ということで、Lanczos approximation について調べてみたら、ご丁寧なことにPythonコードが載っていて、おかげさまで、すっかり実装する気がなくなってしまった。

Simple implementation

The following implementation in the Python programming language works for complex arguments and typically gives 15 correct decimal places:

from cmath import *
 
# Coefficients used by the GNU Scientific Library
g = 7
p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,
     771.32342877765313, -176.61502916214059, 12.507343278686905,
     -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7]
 
def gamma(z):
    z = complex(z)
    # Reflection formula
    if z.real < 0.5:
        return pi / (sin(pi*z)*gamma(1-z))
    else:
        z -= 1
        x = p[0]
        for i in range(1, g+2):
            x += p[i]/(z+i)
        t = z + g + 0.5
        return sqrt(2*pi) * t**(z+0.5) * exp(-t) * x
http://en.wikipedia.org/wiki/Lanczos_approximation

基本的に、よくわからないが、配列pの値を使ってうまーく近似しているんだと。その配列pはどうやって得られたのだろうか・・・。むしろあの配列pの値を求めるのが、本筋なのではなかろうかと思ったが、今日はここまでとした。その他にも、Spouge's approximationっていう近似手法もあるらしい。

WEBで見つけたコード

Wikipediaに載ってたアルゴリズムの精度確認

でも、ちゃんとした結果になるか、気になったので確認だけしてみた。

こんな入力(Wikipediaに答えが載っていたもの)
if __name__ == "__main__":
    print "gamma(-3/2): %s" % (gamma(-3/2),)
    print "gamma(-1/2): %s" % (gamma(-1/2),)
    print "gamma(1):    %s" % (gamma(1),)
    print "gamma(3/2):  %s" % (gamma(3/2),)
    print "gamma(2):    %s" % (gamma(2),)
    print "gamma(5/2):  %s" % (gamma(5/2),)
    print "gamma(3):    %s" % (gamma(3),)
    print "gamma(7/2):  %s" % (gamma(7/2),)
    print "gamma(4):    %s" % (gamma(4),)
そして出力
gamma(-3/2):    (6.413262697e+15+0j)
gamma(-1/2):    (-2.5653050788e+16-0j)
gamma(1):       (1+0j)
gamma(3/2):     (1+0j)
gamma(2):       (1+0j)
gamma(5/2):     (1+0j)
gamma(3):       (2+0j)
gamma(7/2):     (2+0j)
gamma(4):       (6+0j)

あれれー?なんかおかしいぞー。この結果は、見なかったことに...はい、このエントリーのこと忘れました。


ということで、明日元気だったら、3問目に挑戦します。

SONY GOF FOR IT ~1問目: 人生の時計~

概要

GO FOR IT を参照.
毎日一問のペースで解いていければいいなと思ってる。


問題(引用)

1) 人生の時計

あなたの一生を24時間にたとえると今日は何時何分何秒ですか?
ただしあなたはあなたの誕生日(a年b月c日)の0時ちょうどに生まれてn歳まで生きる(n歳のときは生きていてn+1歳にはなれない)とし、bとcは一般的な月日の範囲とします。

i) 1990<=a<=2000,n=80のとき、今日は何時何分何秒ですか?
ii) 1900<=a<=2000,n=200のとき、今日は何時何分何秒ですか?

http://www.sony.co.jp/SonyInfo/Jobs/newgrads/sus/q01.html

Script(Python)

ソースコードのライセンスはフリーです。

#!/usr/bin/env python
# coding: utf-8

from datetime import datetime

class Input(object):
        """データセット情報を保持するClass"""

        def __init__(self, year, month, day, age):
                self.year = year
                self.month = month
                self.day = day
                self.age = age
                # display input information
                self.dump()

        def dump(self):
                print "Input:\n\tbirth date(year/month/day): %d/%d/%d\n\tdeath age: %d" % \
                        (self.year, self.month, self.day, self.age)


def solve(input):
        """人生を一日に換算する. (hour, min, second)を返す."""
        birth_date = datetime(input.year, input.month, input.day)
        death_date = datetime(input.year + input.age, input.month, input.day)
        now_date = datetime.now()

        X = convert_second(birth_date, death_date)
        Y = convert_second(birth_date, now_date)
        # 人生を1日に換算する(sec)
        Z = (60 *60 *24 * Y) / X
        # 0時0分0秒からZ秒を経過させる
        h = int(Z / (60 * 60))
        m = int((Z - (h * 60 * 60)) / 60)
        s = int(Z - (h * 60 * 60) - (m * 60))
        return (h, m, s)

def convert_second(from_date, to_date):
        """from_date ~ to_date までの秒数を得る"""
        diff_date = to_date - from_date
        return diff_date.days * 60 * 60 * 24 + diff_date.seconds

if __name__ == "__main__":
        # i)
        ex = Input(1990, 1, 1, 80)
        print "Output:\n\t%02d:%02d:%02d\n-----" % solve(ex)

        ex = Input(2000, 11, 10, 80)
        print "Output:\n\t%02d:%02d:%02d\n-----" % solve(ex)

        # ii)
        ex = Input(1900, 1, 1, 200)
        print "Output:\n\t%02d:%02d:%02d\n-----" % solve(ex)

        ex = Input(1987, 12, 11, 200) # 誕生日。200歳まで生きれたらいいなー。
        print "Output:\n\t%02d:%02d:%02d\n-----" % solve(ex)

        ex = Input(2000, 12, 31, 200)
        print "Output:\n\t%02d:%02d:%02d\n-----" % solve(ex)

# End of File #

コードの説明

実装する前に書いた作業メモで許してください.

まず、生まれた日から a年から死ぬまでに何秒の時間を過ごしたのか?
死んだ日の定義があいまいだったから、定義しておく.
    e.g) a=1950, b=1, c=1, n=20
        1950年 1/1に生まれる
        51歳になるぎりぎりまで生きる. 2000年12/31で死ぬ. => 51年間生きるという計算

    1950-1/1 ~ 2001/1/1 まで何秒? => X秒
    1950-1/1 ~ 今日まで何秒? => Y秒

    <人生を一日に換算する>
        このX秒を 一日 60 * 60  * 24  とした時に、
        X: 60*60*24 = Y : Z の比の問題を解く.
        <=>     Z = (60*60*24 * Y) / X
        といった計算で人生を一日に換算して、0時0分0秒からZ秒経過した時の時刻を求める.

Ouput

Input:
        birth date(year/month/day): 1990/1/1
        death age: 80
Output:
        06:37:44
-----
Input:
        birth date(year/month/day): 2000/11/10
        death age: 80
Output:
        03:22:17
-----
Input:
        birth date(year/month/day): 1900/1/1
        death age: 200
Output:
        13:27:05
-----
Input:
        birth date(year/month/day): 1987/12/11
        death age: 200
Output:
        02:53:55
-----
Input:
        birth date(year/month/day): 2000/12/31
        death age: 200
Output:
        01:19:54
-----

感想等

テストコード書いてないです。明日余裕があれば、第二問解く予定。

ディレクトリ内のファイルを作成時間の昇順ルールで添え字をつけてリネームするスクリプト

概要

旅行で撮った写真をFacebookにドバっと挙げたかったんだけど、複数のカメラで取ったもんだから、ファイル名がばらばらで、取った順番で挙げたいな~ってモヤモヤしていたので、ディレクトリの中のファイルを作成時間の昇順ベースで添え字をつけてリネームするスクリプト書いたよ。

Before

f:id:Kshi_Kshi:20120202220907p:plain

After

f:id:Kshi_Kshi:20120202220911p:plain

スクリプト

Windows環境でしか、動作確認していません。
(一行目のインタプリタの指定が *nixライク な記述になっているのは気にしないでください。)

#!/usr/bin/env python
# coding: utf-8

import os
import sys

DIR_PATH = "C:\\Users\\hogehoge\\Desktop\\test"
RENAME_PATTERN = "IMG_%d%s" # %d: number, %s: extension

def is_dir_path(path):
	"""check path whether is existing or dirpath or filepath."""
	if os.path.exists(path):
		if os.path.isdir(path):
			# directory path
			return True
		else:
			# file path
			return False
	else:
		# doesn't exist
		return False

def get_files(dir_path):
	""" getting file list """
	files = os.listdir(dir_path)
	return [(os.stat(os.path.join(dir_path, f_name)).st_ctime, \
			os.path.join(dir_path, f_name)) \
					for f_name in files \
						if os.path.isfile(os.path.join(dir_path, f_name))]

def rename(num, file_path):
	"""rename!"""
	root, ext = os.path.splitext(file_path)
	dir_path =  os.path.dirname(file_info[1])
	new_name = RENAME_PATTERN % (num, ext)
	new_file_path = os.path.join(dir_path, new_name)
	print 'renamed "%s" to "%s"' % (file_path, new_file_path)
	os.rename(file_path, new_file_path)

	
if __name__ == "__main__":
	if not is_dir_path(DIR_PATH):
		sys.exit("ERROR: '%s' is not directory." % DIR_PATH)

	for i, file_info in enumerate(sorted(get_files(DIR_PATH))):
		rename(i + 1, file_info[1])


# End of File #

感想

写真が何枚あるかわかるから、アルバムの枚数制限があるFaceBookに挙げるときに便利。

「入門ソーシャルデータ」3章環境設定 - CouchDBの導入(Scientific Linux 6.1)

概要

技術書「入門ソーシャルデータ」に関する勉強会をやっているのだが、3章での環境設定が少しやること多めだったので、備忘記録としてエントリーしておく。

  • 検証環境
    • ホストOS Windows上のソフトウェアVirtualBox上で動いているScientific Linux(x86_64)

yum で CouchDB のインストールに必要なパッケージを入れる.

追加レポジトリを指定せずに、Defaultの状態で普通にyumすると、

...
No package erlang available.
No package js-devel available.
...

と必要なSoftware,libraryを入れられないので、

epelレポジトリを使って、yum install
$ sudo yum install epel-release
$ sudo vi /etc/yum.repos.d/epel.repo
 ...
[epel]
 ...
# enable=1 => 0 に変更
enabled=0
 ...

指定時にしかepelレポジトリを使わないように。ライブラリの依存関係を損なわないため。

  • 必要なパッケージを導入する.
$ sudo yum -y --enablerepo=epel install libicu-devel openssl-devel curl-devel make gcc erlang js-devel libtool which

Erlang系のパッケージがもりだくさんだった。気がする。


cURL

次はcURLの最新バージョンを入れておこうとあったので、普通にソースからインストール.

$ wget http://curl.haxx.se/download/curl-7.24.0.tar.bz2
$ tar xvfj curl-7.24.0.tar.bz2
$ cd curl-7.24.0
$ make
$ sudo make install
$ curl -V
curl 7.24.0 (x86_64-unknown-linux-gnu) libcurl/7.19.7 NSS/3.12.9.0 zlib/1.2.3
libidn/1.18 libssh2/1.2.2
Protocols: tftp ftp telnet dict ldap ldaps http file https ftps scp sftp
Features: GSS-Negotiate IDN IPv6 Largefile NTLM SSL libz

確認OK


SpiderMonkey

次は、jsのライブラリSpiderMonkeyCouchDBでは使用しているので、そちらを導入する.

$ wget http://ftp.mozilla.org/pub/mozilla.org/js/js185-1.0.0.tar.gz
$ tar xvfz js185-1.0.0.tar.gz
$ cd js-1.8.5/js/src
$ autoconf
$ ./configure
$ make
$ sudo make install

CouchDB

これでCouchDBをいれるための準備が整ったので、導入していく.

導入
$ wget http://ftp.jaist.ac.jp/pub/apache//couchdb/1.1.1/apache-couchdb-1.1.1.tar.gz
$ tar xvfz apache-couchdb-1.1.1.tar.gz
$ cd apache-couchdb-1.1.1
$ ./configure --prefix=/usr/local --enable-js-trunk --with-erlang=/usr/lib64/erlang/usr/include
$ make
$ sudo make install

インストール完了.


設定
  • 権限や、/sbin/service で使えるように設定.
$ sudo adduser -r --home /usr/local/var/lib/couchdb -M --shell /bin/bash --comment "CouchDB Administrator" couchdb
$ sudo chown -R couchdb: /usr/local/var/lib/couchdb /usr/local/var/log/couchdb
$ sudo ln -s /usr/local/etc/rc.d/couchdb /etc/rc.d/init.d/couchdb
$ sudo /sbin/service couchdb start # CouchDB起動
$ curl localhost:5984
{"couchdb":"Welcome","version":"1.1.1"}

OK.

  • CouchDBを自動起動させたい場合
$ sudo /sbin/chkconfig couchdb on
  • 他のPCからアクセスしたいとき、ポート解放

5984ポートへのアクセスを許可.

$ sudo vim /etc/sysconfig/iptables
# 以下をルールに追加
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 5984 -j ACCEPT
    • 検証環境ではVirtualBox上でScientific Linuxを動かしているので、ホストのIPアドレス:5984ポートへのアクセスをScientific Linuxに通す設定。

VirtualBoxGUIで[ネットワークアダプタ]->[ポートフォワーディング]

f:id:Kshi_Kshi:20120131002138p:plain
こんな感じで設定した.

    • CouchDB側の設定-外部からのアクセスを許可
$ sudo vim /usr/local/etc/couchdb/local.ini
; 以下を指定する.
bind_address = 0.0.0.0

これで、ホスト元から、http://localhost:5984 でアクセスできる。
これにて、CouchDBの導入終了
CouchDBのWEBベース管理インターフェース Futonhttp://localhost:5984/_utils/ から操作することができる。


その他、3章で必要なライブラリの導入方法

couchdb-python

PythonCouchDBを操作するためのライブラリcouchdb-pythonを入れる。

  • easy_install or pip で導入可能.
    • eggファイルを落としてきて、easy_install
$ sudo easy_install CouchDB-0.8-py2.6.egg
    • pipにて楽々インストール
$ pip install couchdb
    # ちなみに pip のインストールは
    $ sudo easy_install pip
  • CouchDB側の設定

Python側で

$ sudo vim /usr/local/etc/couchdb/local.ini
; ... 以下を追記する ... 
[query_servers]
python = /usr/bin/couchpy

couchpyの場所は $ which couchpy で調べられる.
再起動後に設定は反映される。

$ sudo /sbin/service couchdb restart
python-dateutil

日付関連の処理を楽にするため。

(Python < 3.0 の場合)

$ wget http://labix.org/download/python-dateutil/python-dateutil-1.5.tar.gz
$ tar xvfz python-dateutil-1.5.tar.gz
$ cd python-dateutil-1.5
$ sudo python setup.py install

なぜか、$ easy_install dateutil ではパッケージが見つからないと怒られたので、ソースから入れた。


prettytable

CUIで表示するときに、綺麗に整形された表を出力するためのもの.

$ sudo easy_install prettytable
Lucene関係

あとで書く


threadpool

3.3あたりで例3-14で使うスクリプトで用いる.

$ sudo easy_install threadpool

沖縄に行ってきた話。

概要

2012/1/26~28(2泊3日)で沖縄に入ってきたので、行った場所などの備忘録を兼ねて、エントリー。
写真はブログに挙げるのがめんどくさかったので、これだけ。撮った写真はFaceBookの方にたくさん挙げたので、時間がある方はそっちをみてもらえればと。

f:id:Kshi_Kshi:20120128100745j:plain

行った場所

雨季の最中だが、天気に恵まれて、綺麗な景色・風景をたくさん見れてよかった。
那覇市内のみの旅になった。

  • 首里城公園 (2回)
  • 玉陵
  • 石畳
  • 大アカギ
  • 崇元寺公園
  • 松本公園
  • 福州園
  • 波上宮,波上ビーチ
  • 国際通り付近
その中で良かったところ
  • 首里城公園:
    • 有料地域に立ち入らなくても十分楽しめる。むしろ有料ゾーンはいらなかったかも。守礼門近くのソフトクリームおいしいし、美人スタッフさん多し。
  • 金城町石畳道:
    • 情緒ある街並みを感じられ、那覇市内を一望できる見晴らしは最高。急な坂が多く長く続いているので運動も出来て一石二鳥かも。
  • 崇元寺公園:
    • 大きいガジュマルがある。(それしかないかも。)、ガジュマルを見るためだけにでも行く価値はある。
  • 福州園:
    • 入園料無料。園内に滝があり、滝の内側にも行けるのでとても面白い。園内が猫のアレの匂いがしているのが気にならないほどのクオリティ.随所に遊び心が満載な園庭。

宿泊先

二泊で2700円だった。激安。ドミトリー形式だったが、運よく相部屋の人がいなかったので、気楽に休めた。期待していたよりも綺麗で衛生面も満足。
スタッフの方もとても親切で観光プランに相談に乗ってもらえたり、お勧めスポットを教えてくれた。
セキュリティ面は、ドミトリー形式だと部屋に鍵を掛けられないという決まりがあるので、滞在中、若干の不安は付きまとうが、値段が値段なのでやむ負えない。
またいつか、1人旅もしくは男だけの旅で行くことがあれば、是非また利用したい。

お店(食)

  • 首里城公園,守礼門近くのソフトクリーム屋
    • 定員のお姉さん達が美人だったので一緒に写真を撮ってもらったw 3色のソフトクリーム(300円)を滞在中2回頼んだ。
  • あやぐ食堂
    • 晩御飯時に行った。なかなか賑わっていた。あやぐそば(500円)を注文。
  • 亀そば
    • 2日目の昼食に。軟骨そば-大盛り(550円). 肉のボリュームが凄いし、味もおいしかった。なんか店舗が移転するらしい。また行きたい。
  • スタバ 国際通り
    • 2日目の午後、5~6時間くらい作業していた。電源は頼めば貸してくれそうな雰囲気。作業に没頭できた。マンゴークリームフラペチーノ,ソイラテ(アイス)を注文。
  • 羊料理 さかえ
    • 2日目の夕食に。カウンターに座った。店の雰囲気・外観共に、常連客しか来れないような雰囲気だったけど、店の娘さん(お母さんが主?)が明るく、気配りが上手な方で、隣に座っていたカウンターのおじさん達と仲良くなることができた。料理的には、山羊汁を頼んだ。そのほかにもサービスでいろいろと出してくれた。関東では考えられないようなサービスの良さがとても好印象だった。
  • おでん 悦っちゃん
    • お店の入口はデフォルトで鍵が掛かっているという不思議なお店。その理由はマナーが悪い客を入れないようにしているんだとか、高齢の悦子ママ、とてもいいキャラをしていた。
  • 新茶家(出前)で利用
    • 悦ちゃんに出前で持ってきてもらった。にんにくの塊が餡になっていて、おいしかったが酔っている時しか食べれないと思うほどのにんにくの量。次の日起きたらニンニク臭がやばかった。
  • Bar エロス
    • 懐メロがかかっている店内は基本的に暗く、そこらじゅうに客の名刺が貼り付けられてとてもいい感じの雰囲気のお店だった。
  • 別館セルロイド
    • 表の入口には「別館」としか書かれていない。お洒落なバー。
  • 石畳喫茶 真珠
    • 3日目のランチ。見晴らしのいいレストラン(喫茶?). タコライス頼んだ。普通においしかった。何よりも景色が最高だった。

お店(その他)

  • 小緑 AEON
    • ユニクロ: Tシャツと下着など足りなかったので購入した。
  • 国際通りの酒屋(名前忘れた): 泡盛を2本購入した。接客してくれたお兄さんが目がパッチリして色黒で、もろ沖縄人だったという印象をもったお店。
  • 那覇市内のコンビニ: ファミマ率が異様に高い。ローソンはその次に多いかなというイメージを持った。

「僕と握手!」してくれた方

「○○で僕と握手」プロジェクトの結果, 概要は前回エントリー参照。
結果は、5人。金城石畳道の地元の子供達4人とその子達のおもりをしていた親戚のお母さん1人。

ちなみに前回エントリーのきっかけでは0人。「ブログでプロジェクトの趣旨を説明->Twitterで告知->リプライを待つ」の今までの方法は効果がなさそうなので、次回「○○で僕と握手!」プロジェクトをやる際には、別のアプローチを試したい。

5人以外にも、宿のスタッフの方と雑談したり、ソフトクリーム屋のお姉さん方と一緒に写真を撮ったり、山羊料理屋で会ったお客さんと飲みに行ったりと楽しく過ごすことができた。
今回の旅では、前回(旭川)前回の反省を活かせたことと、沖縄の方の陽気な国民性にも助けられて、たくさんの人と交流できた気がする。ありがとー僕と交流してくれた皆さん。


まとめ

非日常の時間を思う存分楽しめた良い旅になった。
暖かい場所に永住するのもいいなと思わせるほど、沖縄が好きになった。また近いうちに行きたい。