ひしだまの変更履歴

ひしだまHPの更新履歴。
主にTRPGリプレイの元ネタ集、プログラミング技術メモと自作ソフト、好きなゲームや音楽です。

ScalaでXMLファイルを読み込む方法

2012-04-14 13:06:58 | PG(Scala)

ScalaXMLファイルを読み込むにはXMLオブジェクトのloadFileメソッドを使えばいい。のは以前から一応知っていたが、この方法ではルート要素は読めるけど処理命令は読めない。
デバッグモードでステップ実行しつつ見てみたところ、XMLオブジェクトの継承元であるXMLLoaderを直接使えば処理命令も読めることが分かった。
XMLファイル内のコメントを取得するには、さらにハンドラーとかを用意しなければならないようだけど、これも一応出来た。 

ところで、XMLファイルを読み込むには、ConstructingParserを使う方法もある。
こっちだとファイル内に指定されているエンコーディングも取れるし、DTD(DOCTYPE)も取れる。特に何もしなくても処理命令やコメントも取れる。
遥かに簡単じゃん!なんだよちくしょーw

コメント (1)
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

1から「10のn乗」までの合計を算出するプログラム

2012-03-28 21:18:14 | PG(Scala)

Hadoopで1~100の合計を算出するプログラムを考えてみた訳だが、冷静に考え直すまでもなく、Hadoopの出番じゃないんだよな(爆)
しかし100程度だからいけないのであって、もっと桁数が大きくなればHadoop向きのサイズになるんじゃないか? intの上限(Javaなら32bit)を超える程度だと「longを使えばー?」と言われてしまうので、longは十進数だと18桁まで入るから、19桁の数、つまり「1から10の19乗」までの合計を出すなら、いける!?
JavaならBigIntegerというクラスがあるので、メモリーの許す限りの桁数の整数は扱えるし。

とは言え、1つのMapTaskで10億回(10の9乗)の加算をやるとしても、10の10乗(つまり100億)個のMapTaskが必要となる計算。1000ノードのHadoopクラスターで、1ノード当たり1千万回のタスクを実行か。10コアのCPUだとして、1コア当たり百万タスク。
やっぱり現実的じゃないかもなー(汗)


同じく現実的ではないが、Scalaなら、BigIntegerに相当するBigIntというクラスがあるので、Intでのプログラムと同様にシンプルに書ける。

//Int版
def f0(n: Int) = (1 to math.pow(10, n).toInt).par.sum

//BigInt版

def f1(n: Int) = (BigInt(1) to BigInt("1" + "0"*n)).par.sum

BigIntには初期値としてStringを渡せる。"0"*nは、"0"をn個並べた文字列になるので、10のn乗を作れる。これでばっちり!
と思いきや、toメソッドにはIntの限界があるようで、エラーになってしまった…。

scala> f1(19)
java.lang.IllegalArgumentException: 1 to 10000000000000000000 by 1: seqs cannot contain more than Int.MaxValue elements.

ちなみに、もっと少ない数でもOutOfMemoryになったよ。何故だー?orz

scala> f1(7)
java.lang.OutOfMemoryError: Java heap space


仕方ないので等差数列の和の公式にしてみたら、ちゃんと出来た。
BigIntはIntと同じく*や+が使えるので、コーディングもしやすい。 

def f2(n: Int) = { val m = BigInt("1" + "0"*n); (m * (m+1)) / 2 }


しかし最も短くシンプルなプログラムは、これだと思うw
(自分の中では半端な証明しか出来てないけど、たぶん合ってると思う)

def f3(n: Int) = ("5" + "0"*(n-1)) * 2

この件では、Hadoop君はScalaちゃんに敵わないようだ(笑)

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

Play framework2.0を触ってみた

2012-03-11 22:38:38 | PG(Scala)

前から「ScalaWebアプリを作るとしたらどのフレームワークがいいんだろう?」と思ってたんだけど。
名前を聞いたことあるものだけでもこれくらいある^^;

  • Play framework
  • Lift
  • Scalatra (RubyのSinatraライク
  • Unfiltered
  • Spray (Akkaベース
  • BlueEyes

(jugyoさん訳の紹介を見ると、SprayBlueEyesはWebサービス向けのようだから、ちょっと毛色が違うかも?)

本来だったら全部試して比べてみるのがいいんだろうけど、さすがにそこまで出来ないorz
でも試すとしたらPlayとUnfilteredになるのかな?
Liftはyuroyoroさんのサイトで紹介されているけど、当のyuroyoroさんはScalatraを推してる模様w
でもScalatraはRubyのフレームワークに似ているらしく、ScalaでわざわざRubyっぽいものをやりたいとは思わないので、後回しー。

さらに、自分の周りではPlayを採用していく雰囲気なので、Play framework 2.0を試してみた。


まず、インストールが簡単に出来るのがいいね。
雛形(サンプル)が作られるのでざっと追ってみたけど、分かり易いし。(ビューの呼び出し方は独特なはずだが、簡単に想像できる)

HTMLがそのまま書けて、可変部だけキーワードの様にしてScalaの式を埋め込めるのも便利。つまり、普通のHTMLエディターがそのまま使えるから。
(カスタムタグを使う方式だと、普通のHTMLエディターでは役に立たない。tableタグとかはHTMLエディターが無いとやってられんw)
HTMLに埋め込んだキーワード(Scalaの式)や設定ファイルに間違った記述があると、ブラウザーで画面を開くときにエラー箇所が表示されるので分かり易い。 

wiki(翻訳ドキュメント)も分かり易くて便利。 

なかなか良いんじゃない?(笑)

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

ScalaのREPL上でHadoopのSequenceFileを操作する

2011-10-11 01:08:23 | PG(Scala)

ScalaのREPL上でHadoopのHDFSを操作するツールで、SequenceFileの表示部分を強化した。

Path(ファイル)に対してshowを実行すると、SequenceFileかどうかを自動判別し、SequenceFileであればWritableを文字列化して表示する。
WritableにtoStringが実装されていないときはゲッターメソッドを呼び出してそれらの値を表示する。
AsakusaFWのWritableはtoStringが実装されているのでそのまま表示する)

自分で言うのもナンだけど、超便利!(笑)

また、100件ずつ表示するmoreコマンドを用意。
catは今まで全件表示にしていたけれど、headと同じに変更。件数が多いファイルを不用意に指定すると悲惨なことになるという経験をしたので(爆)
tailはスキップバイト数(行数ではない)を指定できるようにしたので、大きなファイルの末尾でも高速化した。1行当たりのバイト数というのは計算では出せないので、スキップバイト数はユーザーが指定する必要があるけれど…。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

ScalaのREPL上でHadoopのHDFSを操作する

2011-10-02 00:46:24 | PG(Scala)

ScalaのREPL上でHadoopのHDFSを操作してみた(笑)
で、それを便利?に扱うライブラリーを作ってみた。

ちなみに、ソースはGitHub公開してみた。初Git!
まだEclipseからの直接の連携は出来てないけど、ソースを公開するには便利だなー^^


今回作ろうと思ったきっかけは、Pigを使っていて、ファイル名を変数で扱いたいなーと思ったこと。と、ファイルに簡単なデータを直接書き込めればいいのになーと思ったこと。
(Pigはlsとかcdとかgetとかを使ってファイル一覧を見たりするのは便利だけど、プログラミング言語ほどの高機能ではないので。
また、PigもHiveもHueも簡単なデータを入れるような機能は無い)

そこで、我等がScalaの出番(笑)
ScalaはREPLがあるので対話型で使えるし、Hadoopは結局Javaのクラスだから、呼び出せるはず!
という読みがバッチリ当たった。まぁ、意外なところで色々と(バグを踏んだりして)はまったけどね^^;

ただ単にファイルが見られるだけとかだったらPigの二番煎じで大して便利でもないかーと思ってたけど、作ってみたら意外と便利かもしれないと思った。
ちょっとしたテストデータを作ったり見たりするには良さそう。
今はテキストファイルだけしか想定してないけど、シーケンスファイルを読み込むのだって難しい話じゃないもんな。AsakusaFWで作ったファイルを直接見るとかも(クラスパスとインポートだけ追加すれば)出来るかも?


さて、本当は次のステップとしてREPL上で直接Mapper・Reducerを書いてHadoopで実行しちゃうという野望があったんだけど。
Hadoopを実行する際はクラスをjarファイル化する必要があるので、そこがクリアできてない…。

一応、:powerモードを使って、「intp.virtualDirectory」で仮想ファイル一覧が取れて、それを実ファイルシステム上に保存したらclassになるというところまでは発見したんだけど。
これって自分が定義したクラスそのものではない(REPL上での実行用のラッパークラスっぽい)ので、直接は使えなさそうなんだよねー。

なんか良い方法ないかなー。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする