MIA 勉強会: 開発環境構築

Mahout in Action の "1.4.1 Installing Mahout" には 0.5 をダウンロードしてきて IDE で開けって書いてあるけどよくわからないので本家サイトの方法を試します。

Quickstart (https://cwiki.apache.org/confluence/display/MAHOUT/Quickstart)

このページの Download and Installation はBuldingMahout (https://cwiki.apache.org/confluence/display/MAHOUT/BuildingMahout) にリンクされてる。まずビルドしろってことですね

ソースコードダウンロード

Latest (Recommended) だそうなのでこっち

svn co shttp://svn.apache.org/repos/asf/mahout/trunk mahout

pom.xml の version によると 0.6-SNAPSHOT とのこと

コンパイル & インストール

mvn -DskipTests install

時間節約のためテストスキップした方がよさそう

% ls -1 ~/.m2/repository/org/apache/mahout/                                            
commons
mahout
mahout-buildtools
mahout-collections
mahout-core
mahout-distribution
mahout-examples
mahout-integration
mahout-math

いろいろできた

たぶん続く

Unfiltered on Heroku

Heroku で Scala がサポートされたので Unfiltered を動かしてみました。

https://github.com/akr4/heroku-unfiltered

package net.physalis.herokuunfiltered

import unfiltered.request._
import unfiltered.response._
import unfiltered.netty._
import util.Properties
import grizzled.slf4j.Logging

object Hello extends cycle.Plan with cycle.ThreadPool with ServerErrorResponse
  with Logging {
  def intent = {
    case Path(Seg("hello" :: Nil)) & Params(params) => {
      debug(params)
      ResponseString("Hello %s".format(params("name").headOption.getOrElse("Unfiltered")))
    }
    case Path(_) => ResponseString("Hello from Unfiltered!")
  }
}

object Main extends App with Logging {
  val port = Properties.envOrElse("PORT", "8080").toInt
  info("started on port:%d".format(port))
  unfiltered.netty.Http(port).plan(Hello).run()
}

Netty バインディングを使いました。

リッスンするポートを

Properties.envOrElse("PORT","8080")

で取得するのがポイントのようです。


Scala on Heroku についてはこちらが参考になります。
http://devcenter.heroku.com/articles/scala


git push したらデプロイできるし簡単でいいですねー。

github で dotfiles 管理はじめました

https://github.com/akr4/dotfiles

整理しながら少しずつ追加していくつもりです。

rake install 

シンボリックリンクを作ります。erb でメールアドレスなどを置換するようにしています。
こちらの方のを参考にして作りました。
https://github.com/ryanb/dotfiles

コレクションの sliding()

sliding() はコレクションをウィンドウをずらしながら参照する Iterator を返します。

scala> (1 to 5).iterator.sliding(3).toList
res19: List[Seq[Int]] = List(List(1, 2, 3), List(2, 3, 4), List(3, 4, 5))

これの存在を最近知りました。
Daimon.scala (http://sites.google.com/site/daimonscala/) で Scala99 やった回にあったら便利だろうなあと思って同じものを作ろうとして時間切れになっていたのでした。


たとえば Scala99 Problem#8 は連続する同じ値の要素を 1 つにまとめる関数 compress を実装します。

scala> compress(List('a, 'a, 'a, 'a, 'b, 'c, 'c, 'a, 'a, 'd, 'e, 'e, 'e, 'e))
res0: List[Symbol] = List('a, 'b, 'c, 'a, 'd, 'e)

sliding を使えばこんな感じで。

def compress[A](list: List[A]): List[A] = {
  if (list.size < 2) list
  else list.head :: (for (List(a, b) <- list.sliding(2); if (a != b)) yield b).toList
}

連続する要素が異なる場合だけ結果リストに追加します。


本家の模範回答はこちら
http://aperiodic.net/phil/scala/s-99/p08.scala

3 つめの模範回答のように foldRight で結果の head と比較してもいいんですけど、ウィンドウを動かしながらの方が個人的には理解しやすいです。

コレクションの iterate()

コレクションクラスのコンパニオンオブジェクトに定義されている iterate が便利ですね〜
このエントリ[Scala][joda-time] 期間でループ - Secret Staircase on はてなで 1 日ごとの Stream を作りましたが、iterate 使えばもっとシンプルに書けます。

Stream.iterate(LocalDate.today, 7)(_ + 1.days).foreach(println _)

Stream の場合は長さ指定のないのもあるから無限リスト作って takeWhile とかもおk

Stream.iterate(new LocalDate(2011, 1, 1))(_ + 1.days).takeWhile(_ < LocalDate.today).foreach(println _)

と、まあ基本的なことなんだろうけど知らないことばかりだなあ

logback-classic

ちゃんと理解していなかったので整理。

ロギングフレームワークとして Logback を使うときは

が必要。maven なら logback-classic だけ指定しておけば依存性が解決される。

logback-classic の名前からわかりにくいけどこれがいわゆるロギングフレームワークで、他にも Tomcat や Jetty と組み合わせて使う logback-access がある。

legacy とか deprecated とかそういうものかと思えて気持ちわるかった。悪い意味じゃなくて Log4J など実績があって "古典的" なものと同様っていう意味の classic かな?