2012年10月21日日曜日

プログラミングのタネ

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
椅子から立ち上がっただけで、激しいぎっくり腰に見舞われた、たなけんです。
本エントリでは、私なりのプログラミングのネタの探し方について記載します。

どう書く?org

はじめに頭に浮かんだのはどう書く?orgです。(久しぶりにのぞいてみるとサーバエラーになっていましたが)
問題の範囲が小さく、様々な言語で解答されているので、とっかかりやすく、他言語の特徴なども知ることができ、新しく覚えた言語を手に馴染ませる際に良く利用していました。

プログラミング本の写経

プログラミングの本、例えばPaul Grahamのon Lispであれば、Common Lispでどう書くか、ということが示されています。僕の場合は、Common LispではなくClojureでon Lispの写経を行いました。(SICPも早く完了したいのですが。。。)
その言語についての知識が全くない状態であれば、ただ写経するだけでも、習慣的な記法が身に付いて良いかと思いますが、私は少し退屈だと感じたのと、Clojureが好きであるという点から、少し言語を変えて写経を行いました。
Ruby on Railsを初めて学んだ際には”RailsによるアジャイルWebアプリケーション開発”という本を黙々と写経(というかコマンドとかもそのまま打ってました)しました。そのころは、Javaで書かれた自社製の独自フレームワークを使って開発することしかしておらず、Railsでは本当に少しのコードで、こんなことができるんだと衝撃を受けました。
写経をしながらだと、開発環境が整えられているためか、フレームワークのソースなどもその場で気になった瞬間に読むことができ、そういった点からも、手を動かさずに読むよりも理解が深まる気がします。
そういった訳で、プログラミング本はプログラミングのネタ供給元としてなかなか優れていると思います。

競技プログラミング

プログラミングコンテストチャレンジブックなど競技プログラミングのお題が紹介されている本やWebサイトも良質なネタの供給元だと考えられます。
しかし、僕自身がそれ程高度なアルゴリズムや実行時のパフォーマンスに関心がないため、競技プログラミングのお題でプログラムを書くことはあまりありません。(Excelの自動操作なんとかして的な、泥臭いけど知識が無いとてこずる系が興味の中心です)

ランサーズ

ランサーズというフリーランスへ仕事を依頼することができるサイトがあるのですが、ここでシステム開発系の依頼もいくつかあるようです。
内容としては、Webサイト構築、データの変換やデータベース構築などです。
その中で下記の2つの依頼が僕の目を引きつけました。

  • Webから商品情報をスクレイピングしてデータベースに登録する
  • 独自性ルールの麻雀ゲームを実装する

これを見た時、『これは職業プログラマ向け、どう書く?orgだ』と感じました。
それほど難しくなく、かつ現実的なスキルセットが必要なプログラムのネタが、ランサーズには転がっています。さらにそのプログラムの市場価値(依頼金額)も見られるので、『自分だったらx時間でできそう』とか、『この分野の依頼が多いから、やったことないけど手を出してみるか』といった自分のスキルの需要と供給についても考えられるので、『プログラム書きたいけど手頃なネタがないなぁ』という方には、ランサーズに出されているお題に取り組んでみることを、是非おすすめします。(個人的には、こういったスキルマッチングの市場がより一般的になるのかどうかなど、プログラムのネタ探し以外の点でもランサーズおよび類似サービスに注目しています)

必要に迫られ系

最後になりますが、やはり最も楽しいのは、自分のプログラムで現実の問題を解決することでしょう。ざっと思い出しただけで、今年は下記のプログラムを留学生活の合間に書いていました。

  • 計算問題自動生成(姪っ子向け、問題数、難易度を選んで計算問題生成)
  • 数独を途中までソルバ(単純に数を当てはめるだけの部分はプログラムに解かせ、推理が必要な部分は自分が楽しみながら解くためのツール)
  • 超簡易ERP(発注、在庫、営業、受注、販売、顧客、採用、給与、財務を管理するRailsアプリ、友人が文房具販売のスモールビジネスを始めるため、夏休み中に作成)
  • レポーティング (ビジネスゲームで得られる膨大なデータをDBに落とし込み、グラフを作成、マーケットシェアなど加工が必要な情報の計算)
  • ビジネスゲームロジック類推(蓄積したデータを変数に、統計モデルを検証し、どのパラメータが何に、どれくらい影響を与えるかを類推。)
  • 簡易OCR(画像データを変換、分割し、必要な箇所の文字を読みDBへ補完)
  • 英単語検索、記録(はじめは自分向けのコンソールツール、同じ単語を何回調べるかとか、類義語が簡単に取得出来るようにするなどをWordNetを使って実装。その後Webアプリとしてリニューアル)
  • オークションの売買履歴自動記録(アマゾンマーケットプレイスの上位1200冊の出品情報を継続的に取得(スクレイピング)記録し、売れるまでの期間、価格とランキングの変遷、売れる本のジャンルなどを求める)
  • 2chまとめの自動取得(スクレイピング)
  • Wordpress.comのブログに自動投稿(Seleniumでブラウザを自動操作)
  • POIを使ってExcelファイル作成(アドホックに良くある)


必要に迫られ系の変種としては、ライブラリの検証が挙げられます。このブログで紹介したDatomicQuartziteWeb-driverなど、新しいライブラリを使う際には、いきなり既存のプロジェクトに組み込むのではなく、検証用プロジェクトを作成し、機能を一通り試しています。厳密には『何を書くか?』というプログラムのネタを供給してはいませんが、『何か書く、できることの幅を広げる』という観点からは、ライブラリの検証もひとつのプログラムのネタと言っても良いかと思います。
ローカルに保存されているプロジェクトの残骸を数えてみると、上記プログラム以外にも30ほどプロジェクトがあり、2週間に1つ以上のベースでは新規ライブラリを試していた様です。(ふと思い出しましたが、今年の頭はcoffeescriptやクライアントサイドMVCにこってりはまっており、spine.jsなどソースをガリガリ読んでいました。こちらも機会を見つけて紹介したいと思います)

まとめ

今年書いたプログラムの総括のようになってしまいましたが、プログラムを書きたいけど何を書けば良いか分からない、という方のヒントになればと思い、本記事をしたためました。
ランサーズを見て、どう書く?orgを思い出したのが事の発端ですが、ブログを書いているうちに、必要に迫られて書いたプログラムの思い出が頭に浮かび、長くなってしまいました。
Clojureを使い続けて3年目です。はじめはファイルの入出力でさえもわざわざ調べて書いていたのですが、今ではDBやWebのプログラミングも手短にできるなど、手に馴染んできました。現実的な問題を解き続ける事で、できることの幅が広がり、達成するまでの労力と時間が短縮されました。
この冬に、学生からソフトウェアエンジニアへと職業が戻りますが、業務内/外にこだわらず、Clojureを使って問題を解決していきたいと思います。
また、ゲームを使った学習についても関心があるので、Javascriptのゲームライブラリであるenchant.jsもClojurescriptのラッパを書くなどして使ってみたいと思っています。

今日の作業は以上、最後までお読み頂き、ありがとうございました。
たなけん(作業時間30分)

2012年10月16日火曜日

ジョブのスケジューリング: Quartzite

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
最近プログラムばかり書いている、たなけんです。
本エントリではClojureのジョブスケジューラであるQuartziteを紹介します。

処理の全自動化のために

プログラムは日常のルーチンタスクを、嫌がることなく、また手動で処理するよりも正確かつ高速に処理してくれます。しかし、そのプログラムを起動するのは私自身だったりします。。。
しかし、処理する情報が定型、処理頻度も定期的なタスクも少なからずあります。「ルーチンワークのために1分とも時間を使いたくない」というニーズから、ジョブスケジューラの調査をしてみました。

Quartziteとは

QuartziteとはClojure製のジョブスケジューラで、JavaのQuartz SchedulerのClojureラッパです。
ジョブスケジューラにはcron(やエンタープライズ用途ではJP1)などがよく使われていますが、「Clojureでどこまでできるか」「ClojureでできることはClojureでやる」の旗印の基、Quartziteを使ってみることにしました。

ソースコード

基本的には、本家サイトの写経となります。

プロジェクトファイル


依存ライブラリに[clojurewerkz/quartzite "1.0.1"]を追記します。(liberatorはWebサービス用のライブラリ、本エントリでは特に利用しません。)

nsマクロ


以下の4つの名前空間の関数(およびマクロ)を利用します。

  • clojurewerkz.quartzite.scheduler: スケジューラそのもの
  • clojurewerkz.quartzite.jobs: ジョブの組み立てに利用
  • clojurewerkz.quartzite.triggers: トリガの組み立てに利用
  • clojurewerkz.quartzite.schedule.simple: トリガの組み立てに利用できる便利な部品を提供。


ジョブの定義


名前空間clojurewerkz.quartzite.jobsのdefjobマクロを用いてジョブを定義します。
ctxはコンテクストと呼ばれるオブジェクトで、別途用意された関数を用いてハッシュのようにキーに対応する値を取り出すことができます。

トリガーの登録



  • qs/initialize関数: スケジューラを初期化する
  • qs/start関数: スケジューラを起動する
  • job/buildマクロ: ジョブクラスおよびスケジューラ内で参照されるキーを付与してジョブを組み立てる
  • job/of-type関数: ジョブクラスをjob/buildマクロに与える
  • job/with-identity関数: ジョブキーをjob/buildマクロに与える
  • job/key関数: 文字列をジョブキーに変換する
  • trg/kye関数: 文字列をトリガキーに変換する
  • trg/buildマクロ: トリガ情報およびスケジューラ内で参照されるキーを付与してトリガを組み立てる
  • trg/with-identity関数: トリガキーをtrg/buildマクロに与える
  • trg/start-now関数: トリガを即座に有効化する(trg/start-at関数であれば、ある時間からトリガが有効になるところ)
  • trg/with-schedule関数: 引数のスケジュールをトリガとする
  • smp/scheduleマクロ: 名前空間clojurewerkz.quartzite.schedule.simpleに定義されている部品からスケジュールを組み立てる
  • smp/with-repeat-count関数: 繰り返し回数を指定する
  • smp/with-interval-in-milliseconds関数: インターバルを指定する


やや冗長な記述となる点が気になったので、ソースを確認したところ、Quartz Schedulerのクラス構成に忠実にインターフェースを用意しているためだと分かりました。SeleniumのラッパであるWeb-diverのtaxi APIのように、一対一対応するインターフェースの上に、よく使う組み合わせで組み上げたインターフェースを用意すると、さらに使いやすくなるのではないか思いました。(使っていく中で、僕なりに用意してみようと思います)


さらに知りたいこと

ジョブスケジューラといえば、下記の機能も欲しいところ(無ければ作ればよいのですが。。。)

  • ジョブフローの分岐
  • ジョブのリカバリ
  • メール等での通知

その辺りの機能についても注目しながら、調査および開発を進めていこうと思います。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間30分)

2012年10月13日土曜日

Clojureアプリのデプロイ: Heroku

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
オーストラリアでの留学生活も終わりが見えて来た、たなけんです。
本エントリではClojureアプリケーションのHerokuへのデプロイについて記載します。

Webアプリケーションの作成

これまでいくつかClojureのWebアプリケーションを作成してきたのですが、Herokuで運用するために何か特別なライブラリが必要なのか等、不明な点が多かったので、Leiningenのプラグインであるheroku/lein-templateのテンプレート機能を利用して、Webアプリケーションの雛形を作成しました。
プラグインは~/.lein/profiles.cljに[heroku/lein-template "0.2.0"]と追記するだけで、インストールが完了します。(次回leinコマンド実行時に、必要なjarなどが自動的にダウンロードされます)
下記コマンドを実行し、Heroku上で動作するWebアプリケーションを生成します。
lein new heroku プロジェクト名

Webアプリケーションの構成

上記コマンドにより、下記の8ファイルが生成されます。

  • .gitignore
  • Procfile
  • README.md
  • web.clj
  • 500.html
  • 404.html
  • web_test.clj
  • project.clj

project.clj

ソースはlein-heroku/lein-templateで公開されているので、要約のみを記載します。
Webのライブラリとしてはオーソドックスにcompojureとringを利用しています。
しかしenvironとdrawbridgeという見慣れないライブラリも利用されていました。
そこで少し調べた所、environは設定情報を管理するライブラリでした(Javaでいう所のpropertyのような物でしょうか)。また、drawbridgeはリモートデバッグのためのライブラリでした。

web.clj

こちらもソースはGit上で公開されていますので、直接の引用は控えたいと思います。
environはHeroku上で設定された環境変数を読み込む為に使われているようです。
(REPLを使う際のユーザ認証。確かに、悪意あるユーザからプロセスを守らないといけないですね)その他、起動ポートや、セッションキーなどHerokuから割り当てられる変数を取得している様です。

Herokuアカウントの取得

さて、デプロイするアプリケーションを用意したところで、次はアカウントを取得します。
アカウントを取得する為には、Herokuのサイトからユーザ登録を選択肢、メールアドレスを入力するだけです。メールアドレスの入力後、確認のメールが送られてくるので、そのメール内のリンクから確認画面へ移動し、パスワードを設定します。
以上で、アカウントを取得する事ができます。

開発ツールのダウンロード、ログイン、アプリケーションの登録

Heroku ToolbeltというHerokuのCLIクライアントをダウンロードし、インストールします。インストール後、heroku loginでHerokuにログインし、アプリケーションルートに移動後、Heroku createでアプリケーションをHerokuに登録します。
あとはGitコマンドをパチパチ打ってソースをコミットし、コミットしたソースをheroku側と同期します。(コンソールでの操作は下記を参考下さい。)


Heroku Toolbeltの操作

プロセスの起動と終了

heroku psコマンドでプロセスの状態を確認する事ができます。
プロセスを起動する際は、下記のようにプロセス名とスケール数を指定します。
heroku ps:scale web=1
また、プロセスを終了する場合は、プロセス名.プロセス番号で終了するプロセスを指定します。
heroku ps:stop web.1

ログの確認

heroku logsコマンドでログを見る事ができます。初回起動時にLeiningenが依存関係の解消の為に必要なライブラリを取得しようとした形跡が見られます。(一度あるリポジトリへアクセスしたものの、そのリポジトリからは目的のライブラリを取得出来なかった際に出されるメッセージがログに残されていました。)
ログレベルの変更や、アプリケーションからのログ出力などは、アプリケーションの運用に必須な項目なので、変更方法等は知っておきたいところです。(調べてブログに書きます。。。)

環境変数の設定

heroku configコマンドで環境変数を設定します。ここで設定した環境変数のキーで、アプリケーション内から環境変数の値にアクセスする事が出来ます。

以上簡単に、Heroku Toolbeltを使ってみました。コマンド体系が直感的で理解しやすいといった感想を持ちました。作成した英単語学習アプリを公開したり、日々PCから実行しているルーチンのタスクをHeroku上のアプリからやらせるなど、いろいろとクラウド上でやってみたいことがあります。
HerokuはClojureを稼働させるのが簡単そうだったので、まず試してみましたが。今後データ量が大きくなりそうなアプリなどもありますので、他のホスティングサービスも試しつつ、ローカルのPCで走らせている日々のルーチンプログラムをクラウド上に移していこうと思います。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間1時間)



2012年10月10日水曜日

マーケットモニタリングアプリの開発(5): スクレイピングTips

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
可能な限り「どのような操作をするか」ではなく「(操作に依存せず)どんな結果を得たいか」をプログラミングしていたい、宣言型プログラミング大好き、たなけんです。
本エントリでは、スクレイピング(Webリソース(e.g. htmlページ)から必要な情報を抽出すること)のTipsを記載します。

FireBug

プログラマであれば、真っ先に思い浮かべるのはFirebugだと思います。御多分に漏れず、私もまずはFirebugでhtmlの構造を(タグを掘り下げながら)解析して行きます。
Firebugの便利な点としては、htmlエディタ(画面下部)上にマウスカーソルを移動させると、対応するhtmlイメージ(画面上部)がハイライトされる点が挙げられます。
スクレイピングしたい部分を画面上部に表示しておき、該当するタグを探って行くことでおおよそ必要な要素を特定することができます。

YQL Console

私がスクレイピングする際に重宝しているもうひとつのツールがYQL Consoleです。
YQLとはYahoo!が開発した『Webリソースに適用出来るSQL』のようなものです。
Firebugで取得したい要素を特定し、enliveのselectorを記述したものの、意図していない結果が返される事が多々あります。なぜならenliveのselectorは該当する要素を全て含んだ結果を返しますが、私が欲しいのはその中の一部だからです。
このような場合、selectorで返される要素を俯瞰し、必要な要素と必要でない要素の違いを見分けるために、私はYQL Consoleを利用します。
具体的には結果をtreeで表示し、必要な要素と必要でない要素を比較します。
理論的にはEmacs上でも結果の比較は可能なのですが、YQL Consoleは階層を可視化して
くれるので、直感的に要素の違いを見分けることができます。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間15分)


マーケットモニタリングアプリの開発(4): ランキングの更新

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
バイト先のレストランからビールを一箱もらってご機嫌の、たなけんです。
本エントリでは、モニタリング対象のランキングの更新について記載します。

ランキング更新の必要性と処理の流れ

取引が成立した理由を探る為には、出品時のランキングだけではなく、実際に売買が成立した時点のランキングも必要だと考えています。(出品後に人気が出て売れたのかどうかを検証するため)
そこで、モニタリング対象の本については、たとえそれが1200位(一括で取得できる上限)以下であっても、日々のランキングを取得する必要があります。
そこで、下記の流れで、ランキング情報を管理します。

  1. 本日のランキング上位1200を取得
  2. 前日までの累積されたISBN(ISBNマスタに登録済み)と比較
  3. 本日のランキング上位1200とISBNマスタとの差分を取得
  4. ISBNマスタに存在せず、本日のランキング上位1200に入ったものは、ISBNマスタに追加
  5. 本日のランキング上位1200に存在しないが、ISBNマスタに存在するものは、個別にランクを取得する


ソースコードと解説

ソースコードは下記の通りです。

ランキングは商品詳細ページに含まれるため、まずは商品詳細ページにアクセスします。(詳細ページのurlはhttp://www.amazon.co.jp/dp/商品コード(ISBN))順位を含むタグから値を取得、また順位が含まれない場合はnilを設定します。ただし、18禁のコンテンツは直接商品詳細ページにアクセス出来ないため、仮置として-1を設定しています。
技術的には特に新規要素は無く、ただenliveを用いて必要な情報を取得しているだけです。
取得した情報はRDBMSのランキングテーブルに追加されます。

今日の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間1時間)

マーケットモニタリングアプリの開発(3): 取引情報取得

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
日本に帰国したら、携帯キャリアは何にしようか決めかねている、たなけんです。
本エントリでは、アマゾンマーケットプレイスの出品情報の取得について記載します。

ブラウザからアクセス

アマゾンの商品詳細ページから、中古の出品リンクをクリックすると、出品情報の一覧が表示されます。その時のurlは下記のようなものでした。
http://www.amazon.co.jp/gp/offer-listing/4121020618/ref=dp_olp_used?ie=UTF8&condition=used
このurlからhttp://www.amazon.co.jp/gp/offer-listing/にISBNを付けると、取引情報の先頭ページにアクセスできることが予想されます。
実際に別のISBNで試した所、予想通り取引情報の先頭ページにアクセスすることができました。
また、先頭ページのhtmlを解析したところ、次ページへのリンクはa要素のidがolp_page_nextであるタグのhrefの値であることが分かりました。

プログラムからスクレイピング

上記の観察に基づき、ISBNから出品情報を取得するため、下記の様な関数を作成しました。


  • condマクロ: JavaなどのCase文のようなもの
  • その他工夫した点: Lispらしく、再帰を利用。次ページがあれば、結果をリストに追加して、再帰。次ペーがなければ結果を返す。

その他は、前回と同様enliveを用いて、販売者ID、販売価格、商品状態を抜き出しています。
抜き出した値は、RDBMSの取引情報テーブルに日付とともに収納しています。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間1時間)

マーケットモニタリングアプリの開発(2): 中古ランキング取得

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
最近少しずつ体重が減少してきた、たなけんです。
本エントリでは、アマゾンマーケットプレイスに出品されている本の、ランキングの取得について記載します。

ブラウザからアスセス

プログラムからアクセスする前に、まずはブラウザからアクセスしてurlを見てみました。
アマゾンのトップ画面から”カテゴリー > 本”を選択し、メニューの詳細をクリック後、条件を入れずに検索すると、左下に状態を選択するリンクが出るので、それをクリックします。さらに右上の並べ替えで『人気度』を選択すると、アマゾンマーケットプレイスに出品されている本のランキングが取得出来ます。さらに下部のリンクから次のページへと移動すると、urlは以下のようなものでした。
http://www.amazon.co.jp/s/ref=sr_pg_2?rh=n%3A465392%2Cp_47%3A2020%2Cp_45%3A0%2Cp_46%3Abefore%2Cp_n_condition-type%3A680579011&page=2&bbn=465392&sort=salesrank&unfiltered=1&ie=UTF8&qid=1349846898
このurlをデコードすると、下記のようになります。
http://www.amazon.co.jp/s/ref=sr_pg_2?rh=n:465392,p_47:2020,p_45:0,p_46:before,p_n_condition-type:680579011&page=2&bbn=465392&sort=salesrank&unfiltered=1&ie=UTF8&qid=1349846898
このurlからrh=以降のパラメータは検索条件、pageはページ番号、sortは並べ替え順であることが推測できます。
pageパラメータの値を3にしたところ、推測通り3ページ目を読み込むことができました。

プログラムからスクレイピング

上記urlのページを変えてアクセスすることで、1ページから100ページまでプログラムからアクセスすることができることが分かりました。各ページ12冊の本が表示されるため、最大で1200位までの本の取引をモニタすることになります。
それでは、ランキングのページからISBNを抽出してみましょう。
ランキングのページのhtmlの構造を解析したところ、div要素の、id=順位 - 1のタグに含まれる事が分かりました。
そこで、スクリプト用ライブラリのenliveを用いて、各ページから順位とISBNを取得する関数を下記のように定義しました。


  • net.cgrand.enlive-html/html-resource関数: 引数のurlをhtmlとして読み込む
  • clj-http.client/get関数: 引数のurlを読み込む。オプション引数は文字コード
  • clj-time.coerce/to-sql-date関数: java.sql.Date型に変換
  • clj-time.core/now関数: 現在時刻を取得
  • net.cgrand.enlive-html/select関数: 指定したタグの値を取得

上記関数で取得したISBNをRDBMSのUSED_RANKテーブル(日付、ISBN、ランキング)に保存し、まずはモニタリング対象となる本を登録することができました。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間1時間)

マーケットモニタリングアプリの開発(1): 概要

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
しばらくマーケットモニタリングアプリの開発に没頭していました、たなけんです。
本エントリでは、マーケットモニタリングアプリの概要について記載します。

事の発端

クラスメイトとの雑談で、古本の流通について話題となりました。そこで私は、日本では個人がアマゾンに本を出品できることを紹介しました。すると友人は、『どんな本が、どれくらいの値段で売れるのか、自動的にデータを取れないかな? データが取れるとどんな本をいくらで出品するのが良いか分かるね。』とアイデアを提案してくれました。
そこで、Clojureでプログラムを作成し、アマゾンマーケットプレイスでどのような本が売れているのかのデータを取る事にしました。

処理の流れ

売れ筋の本の方が、中古本であっても回転が早いだろうと仮定し、まずはベストセラーランキングから本のISBNを取得し、その後、そのISBNをキーに取引情報(sellerIdとisbnで一意に識別)を取得します。
取引情報を継続して取得し、公開されている取引情報が消えた時点で、その取引が成立したと見なし、成立取引一覧に取引情報を移します。
成立取引一覧のISBNから本の属性(ジャンル、出版日)や値引率などを分析し、どんな本がどれくらい売れるのかを求めます。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間15分)

2012年9月29日土曜日

留学生活振り返り(Financial Statistics)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
統計には前から興味のあった、たなけんです。
本エントリでは、留学中に学んだ統計学について記載します。

学んだこと

確率、分散など統計の基礎となる数学から、t検定、χ二乗検定、回帰分析、重回帰分析といった統計手法を学びました。これまでも概念は理解していたのですが、実際に演習で手を動かしたことによって、統計手法を『理解している』から『使える』レベルに引き上げることが出来たと思います。
他の科目でも、統計知識が求められることも多く(学術誌の結果を解釈する際など)、この科目から学んだことは、その後の授業でも非常に役立ちました。

思い出

他の学科の生徒も取得する、共通系科目だったため、200席程ある映画館の様な教室(実際に夜は映画を上映していました)での授業でした。講師は、同年代あるいはやや年下ではないかと思われる、若い男性だったのですが、100人以上の学生を前に、非常に堂々と講義を進めていました。優秀な人間は年齢に関係なく、選抜されて登用されるのだということを印象付けられた講義でした。

授業タイトル一覧


  • Introduction
  • Descriptive statistics
  • Probability
  • Random variables
  • Continuous probability ad distributions
  • Sampling and sampling distributions
  • Estimation
  • Hypothesis testing
  • The comparison of two populations
  • Analysis of variance
  • Chi-squared test
  • Simple liner regression and correlation
  • Multiple regression


今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間15分)

2012年9月28日金曜日

留学生活振り返り(Electronic Commerce for Managers)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
留学前は、ソフトウェアエンジニアをしていた、たなけんです。
本エントリでは、留学中に学んだITの授業について記載します。

学んだこと

授業は下記の3つの要素から構成されていました。
基本的なITシステムの概念(入力、処理、出力)
個別のシステムの説明(Eコマース、SNS、ナレッジマネジメント、ERP、BIなど)
システム導入(セキュリティ、設計、見積もり、プロジェクトマネジメント)
授業名はElectronic Commerce for Managersですが、ECに特に特化しておらず、業務にITシステムを取り入れる際に必要となる知識全般をカバーしている内容でした。
システムの種類が体系的に分類され、それぞれに事例が紹介されたため、既知の知識を再構成することが出来ました。

思い出

事例についてディスカッションが思い出深いです。システムについての知識は他の学生よりもあったので、ディスカッションの中で言いたいことはたくさんありました。しかし、語学力がついていかず、上手く説明出来ないもどかしさに苦しんだことはいまでもはっきりと覚えています。
その時を知るクラスメイトからは『この1年で健太は英語話すの上手になったよね。あの時は何を言っているか95%分からなかったよ。』と言われたりもします。下手なりにも一生懸命話したことから、クラスメイトと仲良くなるきっかけにもなった、そんな授業でした。
最近は英語での議論にも慣れて来ましたが、英語が上手く話せるようになったというよりも、自分のアイデアを簡略化して表現することに慣れたのだと思います。(日本ではA->B->C->Dの順と話していた事をD->Aと結論から先に述べて、簡単な説明でとりあえず済ますイメージ。相手が理解していなければ、さらに質問してくるので、そのタイミングでB、Cの内容は話す。)

授業タイトル一覧

Introduction
Information systems concepts and overview
Managing data and knowledge
Electronic business, E-Commerce and M-Commerce
Communications and social networks
Enterprise and inter-organizational systems
Business intelligence and managing decisions
Risks and security
Design and acquisition
The economics of IT
Information system ethics and impacts

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間15分)

留学生活振り返り(Financial Statements and Reporting)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
複式簿記はわりと得意な、たなけんです。
本エントリでは、留学中に学んだ財務会計について記載します。

学んだこと

財務会計全般をカバーする内容の濃い科目でした。
複式簿記の付け方、そして簿記のデータから損益計算書、貸借対照表およびキャッシュフロー報告書といった財務諸表の作成まで、この授業で叩き込まれました。
会計を学ぶ上で、避けては通れない概念を体得することが出来たと思います。

思い出

とにかく試験が厳しく、『○月○日誰それから材料をつけで購入』などの取引の説明文が60項目あり、それをまず複式簿記で記録、そこから総勘定元帳へ転記し財務諸表を作成するものでした。試験時間も短く、生徒はマシーン状態でひたすら書き続け、計算し続ける、非常に緊張感のある試験でした。
教授によると公認会計士試験より難しくしたとのことでした。教授は『ANUはオーストラリアのトップ校なのだから一般の試験(公認会計士試験)より難しくて当然』仰っていました。オーストラリアの公認会計士の試験は日本ほどは難しくない(学部か大学院で会計を専攻していないと受験出来ないが、合格率は高い)とは言え、厳しかったです。
後日談となりますが、例年と難易度が異なり過ぎた為に生徒からのクレームも多く、その教授は翌年ANUを去ることとなりました。
履修が大変な科目でしたが、結果として、取引内容を見れば即座に、『これは貸方○○で借方××、結果として貸借対照表の負債が増える』と回答できるようになり、会計の感覚を体に染み付けるという意味では有意義な科目でした。

授業のタイトル一覧(1授業で平均2トピック履修)


  • Introduction
  • Financial statements for decision making
  • The accounting equation
  • The basics of double entry accounting
  • Journal entries
  • General ledgers
  • Accounting for GST
  • Adjusting entries
  • Completion of the accounting cycle
  • Accounting for retailing
  • Accounting for inventory
  • Accounting systems
  • Control accounts
  • Accounting for partnerships
  • Accounting for companies
  • Analysis & interpretations of financial statements
  • Cash management
  • Accounting for receivables
  • Accounting for non current assets
  • Regulation and the conceptual framework
  • Accounting for liabilities
  • Presentation of financial statements
  • Preparing the statements of cash flows

本日の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間15分)

2012年9月13日木曜日

第3イテレーションの振り返り

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
肩甲骨のストレッチの効果か、姿勢が良くなったと最近言われた、たなけんです。
本エントリでは、第3イテレーションを振り返ります。

Datomicおよび各種ライブラリを利用した所感

長所

Clojureで書かれている製品である為、クエリにそのままClojureの式(自作の関数も含む)を使う事が出来る

Clojureで書かれている製品である為、Clojureのデータをそのまま収納する事が出来る

原理的にはスケールアウトが可能
クエリおよびデータの追加、変更がほぼClojureのS式である(Clojureネイティブである)点が唯一にして最大の長所だと思います。RDBMSを利用していると、例えばSELECT文ではSQLの書式に従い、SQLの関数を利用して結果を得て、そこからClojureのデータに束縛し直す必要があります。しかし、Datomicではfindの条件にそのままClojureの関数が使えるため、SQLとClojureのデータを行き来するような処理は必要なく、手早く開発することができました。

短所


  • 無料版ではfreeおよびmemプロトコルのみであるため、スケールアウト性能を検証することができない
  • BIツールのように複数のテーブルを結合するなど、様々な角度からデータを解析する方法が確立されていない
  • 集約系の関数など、自力で実装しなくてはならない

RDBMSであればスタースキーマなど、分析対象のデータを多次元的に扱う手法が確立されています。Datomicの柔軟なクエリ構築力を考慮すると、恐らく良い実装方法があるのだろうと、ぼんやりとそのポテンシャルは感じたのですが、今の時点では具体的な方法までは見えていません。

短所としてBIツールの様な多次元表の利用を挙げましたが、「プログラマブルなクエリが書ける、マクロも書ける」というDatomicの潜在能力を引き出せば、SQLを使うよりもスマートにこれらのソフトウェアを実装することができると(根拠は薄弱ですが)直観しています。

Webアプリケーションを一通り書いてみて気付いたこと(およびClojure愛)

これまで、主なClojureの使い道はツール作成でした。しかし、今回はプレゼンテーション層からパーシステント層までClojureを用いて、小さいながらもWebアプリケーションを完成させることができました。そこで気付いたことを振り返りたいと思います。

自転車あるいは糊

Clojureは私にとって最も手に馴染んだプログラミング言語です。そのしっくり来る感じを例えると「自転車」です。気軽に、どこへでも、最短距離で移動できる乗り物です。
他のプログラミング言語を同様に例えるとすれば、Cは飛行機、Javaは鉄道、Pythonはバスでしょうか。それぞれに利点はありますが、家の裏の公園に行く為に、飛行場を作ったり、線路を引くのは、得たい結果に対して労力が釣り合わない気がします。その点Clojureは行きたい場所へ、そこが車さえも入り込めない路地であっても、最短経路でたどり着くことができます。
また、目的地が遠ければ、鉄道や飛行機を乗り継いで行けばいいのです。駅と飛行場の間は自転車で移動し、最後のバス停から終着地点までの間だけ自転車に乗る事もできます。これは必要に応じてCやJavaで書かれたアプリケーションやライブラリをClojureから使って、目的の機能を実現している時の、僕の頭の中にあるイメージです。
実際、ブログでも紹介したTesseractやImagemagickをClojureから操作し、H2 Database Engineへデータを格納後、帳票を出力するツールの実装は、この乗り継ぎの比喩の良い実例と言えるでしょう。そしてWebアプリケーションに関しても、一から書いたコードは少なく、殆どはライブラリが提供する機能をつなぎ合わせたものでした。
多くの人はこう言うでしょう。「それは自転車ではなくて糊だよ」と

マクロ

自転車の例えはまだ続きます。車のエンジンをバラしてまた組み挙げられる人はどれくらい居るでしょうか、またそれに掛かる時間は?工具は?
バラして組み直す事、これはすなわち言語そのもののハックのしやすさの比喩といえます。
Clojureはシンプルです。特殊形式とマクロと関数しかルールが無いと言っても良いでしょう。構造が簡潔であり、なおかつユーザが手を加える余地を十分に残しています。マクロは、簡単に言えば言語の構文を規定し直す機能です。私は多用はしませんが、「いざとなればマクロでなんとでもできる」という信頼感があります。メカニズムを把握していて、そこに手を入れることができる感覚、それは自転車いじりに似ています。自動車のエンジンや、電車のモーターは、固そうですし、私には複雑過ぎます。
マクロの存在がClojureをシンプルかつ柔軟にしており、マクロがあるため僕はClojureを信頼して使い込む事ができています。この感覚が、やはり私にとって自転車なのです。

万人の自転車へ

Clojureが私にとって自転車である事、それは多くの人にとってどうでも良い話だと思います。しかし、Clojureは他の人にとっても自転車となり得る言語だとしたら?
私はJavaのアプリケーションやライブラリを鉄道に例えました。同様にClojureのライブラリは地下鉄や高速道路網と例えても良いかもしれません。多くの人が利用する点から点への移動には、より効率よく移動するための道が敷かれるからです。そして、それら全ての乗り物に、だれでも自転車を携えて乗ることができます。
このブログを読まれた方が、「Clojure使ってみようかな」と思ってもらえるように、これからもClojureの魅力を伝えていきたいと思います。

私に足りないもの

自転車は簡単に乗れますが、奥が深い乗り物です。フォームの善し悪しで、疲労度が大きく変わります。
私はこれまで、全くの我流でコードを書散らしてきました。自転車で言えばがむしゃらに漕いでいる状態です。
Webアプリを設計、開発する中で何度も「どう書くのが関数型言語の特性を活かしているのか?」と自問しつつも、まず動く物を優先して、ここまで漕ぎ進めて来ました。
当初の目標であったプレゼンテーション層からパーシステント層まで実装を終えた今、次に何をすべきかと考えました、私には何が足りないのだろうか?と。
そこで考え至った結論が、フォームの改善です。プログラミングの基礎です。

年内の目標

コンピュータ書の古典"SICP(計算機プログラムの構造と解釈)"の原著が本家サイトから無料で読む事ができます。関数型プログラミングのエッセンスを掴むべく、このSICPの原著を年末までに読み切りたいと考えています。
学習記録をブログに綴る事で、読者の皆様にも関数型言語でのプログラミングの公理のようなものをお伝えできればと考えています。

運用フェーズに向けて

Webアプリの開発フェーズはほぼ終了しましたが、まだこのプロジェクトは終わっていません。そうです、Herokuにデプロイしてサービスを公開、運用ノウハウを蓄積するというタスクが残っています。また、運用しながらメンテナンス性を高める為にリファクタリングしたり、ログ解析ツールそして機能追加など、改修のアイデアはまだまだあります。
SICPリーディングと平行して、Webアプリプロジェクトも継続していきます。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間1時間)


Datomicの利用(3)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
テストコードを書く時、気持ちの昂りを抑えきれない、たなけんです。
本エントリでは、Datomicを利用したClojureアプリケーションのテストについて記述します。

本体の改修

テストコードを実行した際、想定した通りにデータの改廃がされていなかったため、本体コードを改修しました。
元のソースでは、定数connの宣言部で一度だけt/connect関数を呼び、その接続を他の関数内で利用していました。しかし、この場合、データベースが削除されても接続(peer)のキャッシュにデータが乗っているため、検索が可能な状態でした。
テストコードでは、各テストの前にデータベースを削除し、全てのデータを初期化する必要があったため、find-all関数などに含まれている接続オブジェクトも更新(具体的にはt/connect関数の呼び直し)が必要となりました。
そこで、接続オブジェクトを各関数の引数とし、接続オブジェクトの更新が必要無い本体コードでは、一度だけ宣言したconnを、テストコードでは毎回呼び直したオブジェクトを利用する様変更しました。


単体テスト

事前条件として、peerのGC、データベースの削除、追加、スキーマの作成を行っています。その後データ挿入、検索のテスト。再度条件を初期化し、利用制限確認関数の境界値テストを実施するようにしました。


結合テスト

手動でテストを実施しました。
データベースを初期化、限界件数を1にした状態で、画面を操作し、1度目の検索は正常に実行され、2度目の検索でsorryメッセージが表示されることを確認しました。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間30分)

Datomicの利用(2)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
西川きよし師匠の「小さなことからこつこつと」に、とても共感している、たなけんです。
本エントリでは、ClojureアプリケーションでのDatomicの利用について記載します。

仕様

今回のWebアプリケーションでは、利用制限のある外部APIを使用します。そのため、一日の間に、一定回数を超えるアクセスがあった場合、外部APIへの利用を止める処理が必要となります。
そこで、アプリケーションから外部APIへ問い合わせた内容を永続化しておき、次のアクセスの前に、その日のAPIコール回数を(データベース/Datomic)確認し、利用制限を超えている場合は、その旨をユーザに伝えることとします。
APIへの問い合わせ内容として、まずは検索した単語と検索した日時を記録します。
また、調べられている単語や、アクセスされている日時の傾向を把握する為に、入力された全ての履歴を表示する画面も追加します。

実装

実装の大部分は、thearthurさんのgithubのコードを参考にさせて頂きました。

プロジェクトファイル


Datomicのクライアント(Datomic用語でpeer)であるcom.datomic/datomic-freeおよび、時間計算に便利な(Joda Time LibraryのClojureラッパ)ライブラリであるclj-timeを追加しました。

ns マクロ


プロジェクトファイル同様Datomicおよびclj-timeライブラリの利用を宣言します。

  • use節: datomic.apiのうちdbとqは名前空間を付けずに呼び出せ、他の関数は名前空間のエイリアスにdを仕様
  • require節: clj-time.coreおよびclj.time.coerceの名前空間のエイリアスを設定


データベースおよびスキーマの作成(DDL)


データベース及びスキーマを定義します。無料版のDatomicではメモリにデータを保存するmemプロトコルと、H2 Database Engineを内部で利用し、ファイルにデータを保存するfreeプロトコルを利用することができます。
Datomicのスキーマ定義はRDBMSとはやや異なり、属性毎に個別に定義を宣言することでエンティティ全体を組み立てる形式となります。
具体的には、上記ソースでは、エンティティがworkで、wordとtimeがworkの属性として宣言されています。(それぞれ型はstringとinstant(日時))
RDBMSでの定義を(単純化して)考えると、テーブル名がworkとなり、wordとtimeはテーブルworkの中の列となります。
RDBMSのようにトップダウンでスキーマを定義する訳ではなく、逆にボトムアップでスキーマを定義して行きます。
実際、列の型を変えるなど、プログラミングしながら、属性を追加したり、削除したのですが、スキーマ変更に伴い、わざわざ既存のデータを変更(エクスポート&インポート)しなくても良かった点には驚きました。(RDBMSを利用している場合は、スキーマを変更した場合は、データのインポートが必須となるので)
データモデルを固める前に、いろいろと試すことができる、柔軟であるといった意味では、開発時に余計な作業でプログラマの時間を奪わない工夫がされていると感じました。
その一方、データ型が不揃いであることから、検索時の性能劣化、柔軟すぎて不整合が発生しないだろうかなど、運用時に考慮すべき課題も目につきました。

  • d/create-database関数: 引数のurlをアドレスとするデータベースを作成(データベースを作成していないと、コネクション作成時に例外が発生する点に注意が必要)
  • d/connection関数: 引数のurlで指定されたデータベースへの接続を確立する
  • d/transact関数: 引数の式をトランザクションとして実行する


データの追加および検索(DML)


スキーマの定義が管理用領域への(メタ)データの書き込みであるのに対し、データの追加はユーザ領域へのデータの書き込みとなります。(どちらも "d/transact conn データ" と書かれているのはその為です。)
add-a-work関数では、引数に単語と日時を取り、workエンティティを追加します。
find-all関数では、登録されている全てのworkエンティティを取得します。q関数の引数となっているクォートされたベクタがSQLで言う所のSELECT文に相当します。
:findに続く?n ?tは、SQLのSELECTに続く列名の様なものです。しかし、SQLとは異なり属性定義(スキーマ)に紐付いている訳ではなく、任意の文字列が利用可能です(?nameなど)。
?nおよび?tが何を表わしているのかは、続くwhere節で定義されます。
”[?e :work/word ?n]”は「任意のエンティティ?eの属性:work/wordの値は?nである」ということを宣言しています。言い換えると、任意のエンティティ?eは、属性に:work/wordを持ってることになります。つまり「?nは属性に:work/wordをもっているとあるエンティティの:work/wordの値である」ということを表わしています。
"[?e :work/time ?t]"も同様に、「?tは属性に:work/timeをもっているとあるエンティティの:work/timeの値である」となります。
では複数ある:work/wordの値と:work/timeの値が、それぞれ同一エンティティに紐付いていることはどのように示されているのでしょうか?(SQLでテーブルを結合する際に、結合する基準となる列を指定するようなイメージ)
実はDatomicでは特にキーを指定する必要がありません。なぜなら前の式”[?e :work/word ?n]”の?eと、後の式"[?e :work/time ?t]"の?eは、任意ではあるが同一のエンティティと見なすからです。Datomicのクエリで使用される名前(?nなど)は、同じ名前であれば同じオブジェクトを指していると見なされます。この結果、find-all関数の結果として、属性に:work/wordと:work/timeを持っているエンティティの、それぞれの値の集合が返されます。この仕組みをDatomicでは論理プログラミング(Logic programming)と呼んでいます。

  • time/now関数: 現在日時を取得
  • time/within?: 引数のintervalの中に引数の日時が含まれて入ればtrueを返す
  • time-coerce/to-date: Jodaのdatetime型からjava.util.Date型へ変換
  • time-coerce/from-date: java.utils.Date型からJodaのdatetime型へ変換


クライアントからのアクセスのコントロール


外部APIにアクセスする前に、その日のアクセス総数を取得し、制限を超える場合は、検索をせずにsorryメッセージを返すよう、limit?関数を追加、call-api関数を変更しました。

全履歴を取得する管理画面


httpクライアントからfind-allを呼ぶインターフェースを追加しました。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間2時間)

Datomicの利用(1)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
日本語であるにも関わらず、ロシアからのアクセスが最も多いブログを書いている、たなけんです。
本エントリではClojureアプリケーションでのDatomic利用方法(インストールまで)を記載します。

Datomicとは

Datomicとは、私が愛用しているClojureの作者である、Rich Hickey氏が開発している、新しいタイプのDBMSです。
現在では、これまで主に利用されてきたRDBMSだけではなく、KVSなどもごく普通に利用されるようになってきましたが、それらのデータベースと異なる点は何か、少し見てみましょう。

リードに重点を置いたデータ分散システム

データが更新されたタイミングで、クライアント側に持たせているキャッシュが同期されます。そのため、ノードは分散されていますが、検索前に必要なデータに関連するキャッシュを更新し検索するため、高速にデータの読み込みが可能です。その反面、データの一貫性を保証しながら書き込むため、ライトには多少のオーバーヘッドがかかります。

クライアント側でクエリを解析

通常のRDBMSではクライアントから投げられたSQL文をサーバで解釈してから、実行するのですが、Datomicはクエリの解釈をクライアントで行います。その結果、サーバ側の負荷が通常のRDBMSよりも軽くなり、少数のサーバで多数のクライアントからのアクセスを、軽快に捌くことができます。

柔軟なクエリ

ClojureひいてはLispの根本思想である『全てのプログラムはデータであり、全てのデータはプログラムである』をDatomicは体現しています。
先述の通り、クライアント側でクエリを解釈するということもあり、クエリそのものがプログラムであることを許容しています。
プログラム可能なクエリという発想は、識者をして「Datonicは10年先のテクノロジーを先取りしている」と言わしめている理由のひとつかもしれません。

インストールとトランザクタープロセスの起動

Datomicのダウンロードページより無料版をダウンロードし、任意のディレクトリに解凍します。解凍先のディレクトリに移動し、シェルに下記を入力しトランザクタープロセスを起動します。

bin/transactor config/samples/free-transactor-template.properties

デフォルトではポート4334が接続待ち受けポートとなります。
ポートやその他設定を変更するには、config/samples/free-transactor-template.propertiesファイルを編集します。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間30分)

2012年9月5日水曜日

留学生活振り返り(概要)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
奥さんの努力のおかげで、少しずつ体重が減少しつつある、たなけんです。
本エントリでは、留学生活の振り返りとして、学んだ事やキャンベラでの生活について記載します。(書いている時点では、まだ卒業していませんが。。。)
1エントリにまとめるのは難しいので、今回は概要のみ記載したいと思います。

概要

2010年6月にオーストラリアはキャンベラにあるThe Australian National University(通称ANU)に入学し、主に英語、会計そしてマネジメントについて勉強してきました。
留学した動機は、

  • ビジネス面でも専門と言える強みを持ちたい(エンジニアとして働いていましたが、会社自体はITコンサルと呼ばれる業種だったので。。。)
  • エンジニアを続ける上でも英語が出来るようになっておきたい

というものでした。
半年間語学コースで英語を学んだ後、大学院会計学科にて主に会計を、そして選択科目でMBAコースの授業を取得しました。時系列で振り返ると以下のようになります。

2010年6月〜11月(語学コース)

英語(Reading, Writing, Listening, Speaking)

2010年11月〜2011年2月(夏休み)

バイトおよび3度目、4度目の引っ越し
スラムダンクやバガボンドが図書館に置いてあったので、英語の勉強と称して漫画を読みふけっていました。

2011年2月〜11月(大学院一年目)

1年目は学部共通の授業が多かったです。

前期
Financial Statements and Reporting (共通)
Commercial Law (共通)
Electronic Commerce for Managers (共通)
Financial Statistics (共通)

後期
Management Accounting and Cost Analysis (会計)
Business Association Law (会計)
Managing the Global Supply Chain (MBA)
Financial Markets and Systems (共通)


2011年11月〜2012年2月(夏休み)

シドニーのホテル(Sheraton on the park)の財務会計部にてインターンシップ

2012年2月〜11月(大学院一年目)

1年目は会計の必須科目とMBAの授業が多かったです。

前期
Contemporary Issues in Accounting (会計)
Taxation Law (会計)
Corporate Accounting (会計)
Organisational Behaviour (MBA)

後期

Business Economics (共通)
Auditing and Assurance Services (会計)
Corporate Strategy (MBA)
A Management Framework For Business Projects (MBA)

所感

こうして振り返ってみると、なかなか考えられたカリキュラムですね。
共通科目では会計、法律、統計、財務、経済の基礎を学び、
会計専門科目では、より深く会計と法律について学びました。
MBAの授業は、様々な切り口でビジネスを理論的および実践的に理解することができたと思います。
留学で学んだことの棚卸しとして、各授業の概略を今後振り返ってみようとおもいます。
興味のある方は是非、ご一読下さい。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間15分)

2012年9月2日日曜日

私のClojure情報収集方法(Planet Clojure)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
テスト勉強で机に向かうと、机の隅々まで掃除したくなり、結局あまり勉強時間がとれない、たなけんです。
本エントリでは、私のClojure情報収集方法と、そこで目に留まった情報について記載します。

RSSフィード

RSSフィードの購読は少ない労力で、日常的に情報を摂取するには良い方法かと思います。
多いときは1日1000以上の記事に目を通していた(どんだけ暇。。。)ほどRSSジャンキーだった(※1)私ですが、今はインプットよりもアウトプット、質よりも量を意識して情報を収集および発信しています。
Clojureに関しては、Planet ClojureというサイトのRSSフィードを購読しています。
Planet Clojureの運営者Baishampayan GhoseさんとAlex Ottさんで、内容は彼らが購読しているClojure関係のブログ記事の中から、よりすぐりの記事を転載したものとなっています。
運営者の目利き力のおかげか、自力では到底見つけられない様な記事も、タイムリーに掲載されるため、非常に重宝しています。
Planet Clojureの記事は、主に以下の4カテゴリに分けられると思います。

  • Clojure本体および主要ライブラリのリリース
  • Clojureで作ったサービスの紹介やライブラリのチュートリアルなど実用系
  • On LispやSICPの例題およびProject Eulerの解答などアルゴリズム系
  • 他言語との比較など言語仕様討論系

Planet Clojureの雰囲気を掴んで貰える様、最近記憶に残った記事を手短に紹介したいと思います。

リリースメモ系

Clojure weekly Aug 17-24 2012
この記事ではClojure1.4.0で導入されたinstant literalsマクロ(他4トピックス)を紹介しています。Clojureの標準ライブラリに含まれるマクロで該当する処理ができるにも関わらす、そのマクロの存在を知らずに自分で書いてしまうことがあります。(いわゆる車輪の再発明)
RSSを通じて、こういったリリースメモ系(新規で追加されたマクロなど)に日常的に目を通しておくことで、車輪の再発明を未然に防ぎ、開発効率を高めることができるかと思います。

実用系

Building School Seating Charts in Clojure and Clojurescript
ClojureとClojurescriptを使って、Google App Engine上で稼働するWebアプリケーションを構築した際の、良い点、悪い点、便利だったライブラリを紹介した記事です。
記事の著者と同様、私もClojureとClojurescriptを使ってWebアプリケーションを構築しているので、役に立つ情報満載の記事でした。特に利用したライブラリ一覧の中で紹介されていた、セッション管理ライブラリなどは、「何かいいものないかな」と探していたところだったので、個人的にヒットでした。また、テストライブラリなども今まで知らなかったものが紹介されており、利用候補ライブラリをひとつ(どころが沢山)増やすことができました。

Using the Datomic free edition in a lein based project
こちらはClojureで書かれたデータベースDatomicのチュートリアルです。
知識ゼロの状態からでも理解できるように丁寧な解説されており、参考になりました。
DatomicについてGoogleで検索しても、バズワード的に概念だけを取り上げた記事が多く、公式のドキュメントもまだ出揃っていない状態の中、こうした良質のチュートリアルに出会えたのも、Planet Clojureのおかげだと思います。

アルゴリズム系、言語議論系はさらっと目を通す程度で、あまり読み込んでいないので、
今回は記事の紹介は控えたいと思います。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間30分)



※1 RSSジャンキーだった頃はどうしても全文をRSSリーダで読みたいという欲求がおさえきれず「まるごとRSS」の様な簡易ツールだけではなく、Yahoo pipesを使ったり、webをクロールして記事内容をRSS化するスクリプトを書いたりしていました。。。

2012年8月25日土曜日

画像から文字抽出(ImageMagick Tesseractの利用)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
スクワットのフォームが悪くて、膝を少し痛めてしまった、たなけんです。
本エントリではClojureを用いてシェルを操作し、画像データを加工し、必要となる文字列を抽出する方法を記載します。

事の発端

大学院の授業でシュミレーションゲームを行っており、そのデータをClojureを用いて分析していることを、以前の記事で紹介しました。
その後、あるチームメイトから「このpdfファイルのデータも使えない?」と聞かれ、『pdfなら文字情報を抽出するのも簡単だし、問題ない』と考え、二つ返事でデータの抽出を引き受けたのが、今回の事の発端です。
以前、利用したデータはcvs形式だったので、データ読み取りに何の工夫も必要ありませんでした。今回も、xpdfなど既存のソフトウェアを使えば、文字情報が簡単に取り出せると考えていたのですが、意外な落とし穴がありました。実は
ファイル拡張子はpdfであるものの、実際のデータは画像
だったのです。
(xpdfでテキスト抽出処理をした結果、一文字も抽出されませんでした。不審に思い、その後手動で文字をコピーしようと文字部分をマウスでドラッグしてみて、データが画像であることに気が付きました。。。)
以前より、画像から文字を抽出(OCR)することには関心があったので(※1)、ImageMagickとTesseractを利用して、画像データを抽出することにしました。

実装方針

翌日には結果を渡さないといけないという、時間的制約から、手作業で作業内容を確立し、プログラムでそれを自動化するという方針としました。

  • それぞれの処理(画像加工、OCR)はシェルからコマンドを実行する(作業内容)
  • シェルの起動や、コマンド発行をClojureから行う(自動化)


ImageMagickとTesseractのインストール

どちらもMacPortsからインストールしました。
Tesseractは本体だけではなく、英語バージョンの学習ファイル(辞書)もインストールしました。
特に問題なく、スムーズにインストールすることができました。
(パラメータなどは全てデフォルト値)

作業内容

作業内容および手順は、以下の通り。

  1. 複数ページを含むpdfファイルを、個別の画像ファイルに分割する(同時に解像度も上げる)
  2. 各画像ファイルから抽出対象の文字が含まれる部分を切り取る
  3. 切り取ったファイルの文字情報を読み取る
  4. 読み取った文字情報を整形し、レポートを出力する(本エントリでは記載を省略)


ソースコード

形式変換&ページ分割


ImageMagickのconvertコマンドで複数ページを含むpdfファイルを個別のpngファイルに変換します。(-formatオプションを付けなくてもフォーマット変換出来ました。。。)
解像度指定しなかった場合、画像が荒すぎてOCR精度が落ちるため、-densityオプションで解像度を設定、-unitsオプションで解像度の単位を指定しています。
Clojureで実装した際の注意点としては、clojure.java.shell/sh関数を利用する際、通常(clojure.java.shell/sh コマンド オプション1 オプション2 ...)のように、コマンドのオプションを(リストではなく)第2引数、第3引数...と指定する点があげられます。
今回の実装では、オプションを別関数で生成しているため、apply関数を用い、(apply clojure.java.shell/sh コマンド オプションのリスト)のように実行しました。
またオプションは一続きの文字列ではなく、それぞれのオプション(およびその値)が分割されている必要がある点も注意が必要でした。例えば、"-density 300x300 -units PixelsPerInch"を第2引数に渡すとエラーとなり、正しくは"-density" "300x300" "-units" "PixelsPerInch"をそれぞれ、第2引数、第3引数、第4引数、第5引数として渡さなくてはいけません。
上記の点さえ気をつければ、特に問題なくclojure.java.shell/sh関数を使うことが出来ます。(シェルコマンドをClojureで自動実行できれば、いろいろと便利ですね)

画像切り取り


形式変換&ページ分割と同様、切り取るサイズと位置を指定してconvertコマンドを実行します。ページ毎に切り取り部分が異なるため、ファイル名に応じた切り取りサイズ&位置を渡しています。

文字情報の読み取り


切り取り済みの画像ファイルを順に読み込み、テキストファイルを生成します。
オプションの-psmは画像の中でさらに読み取る部分を指定するオプションです。
画像全体を読み込み対象とするため、-psmに6を指定しています。

捕捉: psm (pagesegmode)一覧


上記のように、一行とみなしたり、円で囲った部分だけ読むなどのオプションがあります。

調査中に見つけたライブラリ

今回は、時間的制約から、プログラムの再利用性(汎用性)よりも、実装の手早さを重視しました。そのため、あまり調査に時間を掛けることはできませんでした。しかし、少しだけ行った調査の過程で、面白そうなライブラリを発見したので、この場を借りて紹介したいと思います。

im4java

ImageMagickのコマンドを網羅したJavaライブラリ。<im4javaのwebサイト>
複雑な処理を自動化するのであれば、使ってみたいといった印象。
学習コスト削減のため、今回は利用しませんでした。

Tess4J

TesseractのJNIラッパー。<Tess4Jのwebサイト>
まだMacでの動作に問題があるようだったので利用を回避。
2012年8月8日にversion 1.0 beta 5がリリースされたばかりの新しいライブラリの様なので、今後の成熟に期待。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間2時間(テキスト抽出後の処理は除く))

※1: OCRを組み込んだ、アプリケーション、サービスについての構想は別エントリにて紹介したいと思います。

2012年8月19日日曜日

第3イテレーションの計画

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
『今やる、すぐやる、出来るまでやる』がモットーの、たなけんです。
本エントリでは、第3イテレーションの計画として、仕様および実装方針を記載します。

第3イテレーション(パーシステント(トランザクション)層)の仕様

外部APIを規定の回数以上使用しないよう、検索語と検索日時をデータベースに記録し、規定回数以上のアクセスがあった場合は、外部APIへアクセスせず、画面にメッセージを表示します。
RDBMSでの実装するのであれば、1テーブルのみ、列は単語と日時といったシンプルな構成となるような仕様です。

実装方針

最終的にHerokuにデプロイしてサービスインする予定ですので、無料で利用可能なDBの選択肢として以下の3つが考えられます。

  • PostgreSQL
  • MongoDB
  • その他組み込み系DB

通常のRDBMSについては帳票処理の際に利用し、特に問題なく利用出来たため、
今回のアプリケーションでは、新たなチャレンジとして

  • MongoDB
  • Datomic(組み込みモード)

を用いて、パーシステント層を実装したいと思います。

テスト方針

下記の4ステップを1サイクルとし、継続的にテストが可能な状態を目指します。

  • テストデータの作成
  • 取り込み
  • テスト
  • テストデータの消去


今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間15分)

第2イテレーションの振り返り

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
肩甲骨周辺の筋肉をほぐすと代謝が上がると聞き、日々肩を回している、たなけんです。
本エントリでは、第2イテレーションを振り返ります。

Clojurescriptおよび各種ライブラリを利用した所感

Clojurescriptの利点

Javascriptに馴染めない、という理由からWebクライアントの開発言語にClojureを採用しました。Google Closure Libraryで提供される関数やオブジェクトを利用する感覚が、通常のClojureからJavaのライブラリを利用する感覚に非常に近く、スムーズに開発を進めることができました。また、DOMやイベントの操作についての関数が十分に整備されていたことも、開発効率の向上につながりました。

Clojurescriptの欠点

多少違和感があった点としては、通常のClojureでは副作用を期待する処理にdoマクロを用いるのですが、Clojurescriptではdoマクロを用いずに次々と式を評価していく点があげられます。ライブラリの読み込みや表の描画など、戻り値を利用しない処理が多く、この点は若干の気持ち悪さがありました。

コンパイルとデバッグ

ClojurescriptからJavascriptへのコンパイルなど、導入前は手間が掛かることを想定していたのですが、lein-cljsbuildを用いることで、コンパイルを意識することなく開発を進めることができました。ただし、デバックについてはFirebugを用いてJavascriptのコードにブレイクポイントを設定し、エラーを解析する必要がありました。この点については、HTML 5で提供されるsource mapを利用することで、解決できるのではと考えています。

repl

Clojurescriptのreplは通常のClojureのreplほど洗練されておらず、若干使い勝手が悪かったです。そのため、Clojurescriptで提供されている関数の動作を確認する程度にしか利用しませんでした。この問題は、Emacsとの連携で解決できそうです。(本家サイトのEmacs連携のWikiページ)

Google jsapi (visualization API)

表や図などのオブジェクトが提供されており、自分でtableタグなど書く手間が省け、開発時間を短縮することができました。また、オブジェクトへのidの付与など、今回は利用しなかったものの、通常の利用では必須となるであろう機能も用意されており、また機を見てAPIを調査したいと思います。

Twitter Bootstrap

正直あまりUIに時間を掛けなかったので、なんとも言えません。
動的にCSSを生成するフレームワークとしてlessを採用しているようですので、こちらも機会を見て掘り下げてみたいと思います。

今後利用してみたいツール、フレームワーク

Clojurescriptについて調査を進める中で、気になるツール、フレームワークがあったので、この場を借りて紹介したいと思います。

lein-cljsbuild (複雑なソースのビルド、テストの自動実行)

今回はコンパイル機能のみを利用したのですが、その他にもClojure(.clj)ファイルとClojurescript(.cljs)ファイルを別ディレクトリに保存しておき、ビルド時に1つのJavascriptを生成する機能や、PhantomJSを起動してテストを自動的に実行する機能などをlein-cljsbuildは持っているようです。
特にビルドに関してですが、クライアント側で実行するコードであっても、純粋なClojureで記述できる部分がcljファイルに保存できると、単体テストの仕組みなどをサーバ側と統一できるため、非常に開発効率が上がると思います。
さらに、cljsソースとcljソースが粗結合となるため、Sinon.jsなども絡めることでcljs(ブラウザの操作などを含む不純なClojurescript)コードのテストもより単純化できるのではと感じました。

Clojure one


Clojure oneはサーバ、クライアントの双方をClojure(Clojurescript)で開発可能にした統合Webアプリケーションフレームワークです。単体テストの仕組みなども組み込まれているようで、非常に便利なのではないかという印象です。便利な反面、何かしら制約があるかもしれませんが、次回ClojureでWebアプリケーションを利用する際には、実際に使ってみようと考えています。

Bishop

BishopはClojureで書かれた、HTTPリクエスト処理ライブラリです。Webmachine互換のAPIを持ちRestfulなWebサービスを実現するために利用することができるようです。
クライアントサイドMVCフレームワークについては後述しますが、Webアプリケーションのあり方として、ロジックはサーバーサイド、描画と操作はクライアントサイドにまとめてしまった方が良いのではないかと個人的には考えています。Bishopは多様なリクエスト処理関数を実装しており、ロジックに特化したサーバサイドのライブラリとして、有用なのではと、密かに目をつけています。

クライアントサイドMVCフレームワーク

Bishopの項でも述べた通り、ブラウザでの描画および操作はクライアントサイドで完結させたいと個人的には考えています。そういった要望に応えるのがBackbone.jsやSpine.jsなどクライアントサイドMVCフレームワークです。
Coffeescriptの練習がてらSpine.jsを利用した感想としては、「何故、今までこれを使わなかったのだろう」と思ってしまったくらいに便利でした。(JavascriptではなくCoffeescriptでモデルなど定義できたからかもしれませんが。。。)
今後、クライアントサイドの処理が複雑なアプリケーションを作成する際には、ClojurescriptとこれらのクライアントサイドMVCフレームワークを組み合わせて実装出来ないか、検討したいと考えています。


今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間30分)

Webクライアントのテスト

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
先日、魔女の宅急便を見ました。映画の最後で語られる「おちこんだりもしたけれど、私はげんきです」のメッセージに、とても励まされた、たなけんです。(ダイエットに挫折しそうになっていたため。。。)
本エントリでは、Webクライアントのテストについて記載します。

Webクライアントのテストの位置づけ

Webクライアントのテストの為に、今回テスト手法やテスト用ライブラリなどを調査しました。その結果、いくつかの興味深いフレームワークやライブラリ、ツールを見つけることができました。
しかし、今回のWebクライアントは

  • ソースコードが実質20行程度と非常に短い
  • 条件分岐がなく一本道のロジックである

ことから、それらのライブラリを利用してテストする程ではないと考えました。
本来であれば、クライアントのメソッド単位で、まずは単体テストを実施し、その後ユーザの操作フローに基づいた結合テストを実施します。また、正常系だけではなく、異常系も漏らす事無くテストするのが本来のテストの姿であると考えています。
しかしながら今回は、Webクライアントの機能が十分すぎる程シンプルであるため、テストの目的を、デグレーションの検出に限定して考えたいと思います。

テストプログラム実装方針

正常系の動作を自動実行し、以上が発生しない事を確認する。
ライブラリとしてSeleniumをラップしたclj-webdriverを利用する。

依存ライブラリのダウンロードの問題

project.cljにclj-webdriverを利用するよう記載し、lein depsを実行したところ、bcprov-jdk15on-147.jarおよびbcpkix-jdk15on-147.jarのダウンロード時に、チェックサム例外が発生し、Leiningen経由では上記2ライブラリがインストールできませんでした。
そこで新規Mavenプロジェクトを作成し、Seleniumの依存ライブラリをインストールしたところ、問題なく上記2ライブラリをインストールすることができました。
私の環境ではLeiningenとMavenでライブラリを共有しているため、この方法で解決をすることができました。
また、Maven利用の前にlein-localrepoによるfloating jarのローカルインストール(Mavenの3rd party jarのインストールのようなもの)を試してみましたが、こちらは上手くいきませんでした。

テストコード



  • doマクロ: 手続き型のプログラミング言語のように、以下のS式を順に処理する
  • clj-webdriver.taxi/set-driver!関数: ブラウザを起動し、引数のurlを開く
  • clj-webdriver.taxi/implicit-wait関数: 指定ミリ秒処理を停止する
  • clj-webdriver.taxi/input-text関数: テキストボックスに引数の文字列を入力する
  • clj-webdriver.taxi/click関数: 引数の要素をクリックする
  • clj-webdriver.taxi/find-element関数: 引数で指定された要素を取得する。要素はxpathなどで指定が可能


clj-webdriverの感想

依存ライブラリのダウンロードで問題が発生するなど、アルファバージョンにつきものの不安定さはありました。
その反面、一度インストールしてしまえば、非常に短いコードでSeleniumを用いたテストを記述することができました。
業務ソフトウェアをClojureで書くよう周囲を説得するのは難しいと思います。しかし、clj-webdriverのように、テストツールとしてClojureを導入するのは、非常に現実的な選択肢ではないかと、clj-webdriverを使ってみて強く感じました。
(通常の単体テストも、JUnitの代わりにテストだけClojureで書くことも出来そうですね)

今後利用してみたい、Javascriptテストの技術要素

今回のテスト(そもそもロジックがない)で利用するにはオーバースペックでしたが、Clojurescript (Javascript)のテストに関連する様々なフレームワークやライブラリ、ツールについても多少調査したため、この場を借りて紹介します。

Jasmine

Javascriptテスティングフレームワークの大本命。
Google Closure Library (Closurescriptを影で支えているJavascriptライブラリ)はJsUnitを公式テストフレームワークとして採用しています。しかし今やJsUnitはメンテナンスされておらず、JsUnitのサイトでもJasmineへの以降を推薦していました。
Clojurescriptをテストする方法が、Odyssomayさんのブログに分かりやすく解説されています。(なぜClojurescriptをビルドするためのスクリプトがPythonで書かれているかは追求しません。。。)

Sinon.js

Javascriptの柔軟性を存分に活かした黒魔術のようなライブラリ。単体テストの際、関連オブジェクトを差し替えてテストしたいといった要望は多々あるかと思います。(テストするクラス以外は、単純にある値を返して欲しいなど)
Sinon.jsはオブジェクトのスタブ化、モック化またフェイクサーバやフェイクタイムなどを提供し、オブジェクトを差し替えたいといった要望に応えてくれます。
モックあるいはスタブ化関数で処理することで、テスト対象以外のオブジェクトは、メソッドインタフェースは普遍のまま、振る舞いをテストに都合の良いように変えることができます。
同じ様なコンセプトのライブラリ、是非ともClojureにも欲しいなあと感じました。(JavaでSpring frameworkなど使えば、同様の機能は実現可能ですが、Clojureの持つ柔軟な言語特性を活かしたライブラリがあればもっと手軽に実現できそうなので)

PhantomJS

Javascriptのテストライブラリはブラウザから実行することが多いのですが、ブラウザの起動や動作までサポートするライブラリはあまりありません。
PhantomJSはコマンドラインから起動でき、読み込んだJavascriptを実行することができるブラウザです。(内部で、WebKitエンジンを利用しています)
PhantomJSを利用することで、コマンドラインからJavascriptをテストすることができ、単体テストの自動実行が容易になるかと感じました。

今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間30分)

2012年8月18日土曜日

画面デザインの改善

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
ダイエットを続けて半年、やっと2キロの減量に成功したものの、気がつけば1キロリバウンドしてしまい、意気消沈のたなけんです。
本エントリではTwitter Bootstrapを利用した、Webページのデザイン改善について記載します。

Twitter Bootstrapとは

Twitter社が提供しているCSSフレームワークです。
デザインが苦手なプログラマでも、見栄えの良いWebサイトが作れるとの評判なので、今回作成中のWebアプリケーションに組み込んでみました。

ナビゲーションの追加

今回の要件では、画面そのものがシンプル極まりないため、デザインを取り入れる要素があまりありません。そこで、機能毎に画面遷移するためのナビゲーションを追加することにしました。
実装方法として、ナビゲーションとiframeからなるindex.htmlを作成し、ナビゲーションのクリックイベントをにより、iframe内のベージがそれぞれの機能のページ(例dictionary.html、spelling.html)に切り替わるようにしました。

実装結果


未だ地味な感じは否めませんが、無味乾燥だった画面が、少しまとまった気がします。

ソースコード



  • 6行目: ダウンロードしたBootstrapのCSSを利用
  • 9-10行目: ナビゲーションへのクリックイベントに対応した動作(jQuery使用)
  • 14-30行目: ナビゲーションの描画
  • 32行目: iframeに各機能のページを割り当て(初期値はdictionary.html)


今回の作業は以上。最後までお読み頂き、ありがとうございました。
たなけん(作業時間45分)

2012年8月12日日曜日

Clojureで帳票処理(csv読み書き、RDBMS利用、グラフ描画、PDF出力)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
授業が始まってからグログ更新が滞っていた、たなけんです。
本エントリでは、Clojureを利用した帳票処理について記載します。

事の発端

現在、大学院で会計を専攻しているのですが、任意科目でいくつかのMBA専攻のクラスを受けています。(前期までに、ほぼ会計は履修したため、今期は75%がMBAのクラス)
その履修しているMBAクラスのひとつに、企業戦略を立案するクラスを履修しています。
面白いことに、このクラスの成績は、シュミレーションゲーム上のスコアにより決定されます。(クラスのメンバーを8チームに分け、チーム間で競争することとなります。)
決定すべき項目として、製品開発(高機能戦略や低価格戦略)、マーケティング(世界を4地域に分け競合の出方を伺いながらどのエリアを攻めるか)、生産(工場の人員配置や設備投資など)、財務(株式発行、社債発行など)などがあり、毎週50項目ほどのパラメータを検討して、事業戦略を実装し、他チームと結果を競い合っています。
各チームが決定する50項目のうち、27項目は年度末(実際は毎週日曜日)に結果とともに全チームに公開され、翌年のパラメータ検討の際の参考資料とすることができます。
他チームが見る事のできるパラメータは27項目なのですが、それがチーム毎(8)、地区毎(4)、四半期毎(4)で公開されるため、結果として毎年3,456(=27*8*4*4)項目に目を通すこととなります。また、年間の比較を考えると、1年(1週間)毎にデータが3,456項目ずつ増えることになりますので、数値だけを見て比較するのは困難であると考えられました。
そこで、数値の変化を、各社、各地域で比較出来るようグラフを作成することとなりました。

仕様

入力: 会社、地域ごとに1csvファイル。行は項目、列は四半期ごとの数値が記載されている。
出力:1項目1ページ、1ページに各地域のグラフを縦に配置、1グラフに8社と平均値を表示、横軸は時間、縦軸は値。

出力例
製品販売価格



数値をグラフにすることにより、各チームの意思決定が比較しやすくなっているのが分かると思います。例えば、EA市場ではほとんどのチームが価格を他の地域より高めに設定していること、また、year7に突然ピンクチームがAP、LA、NA市場で価格を高く設定したことなどがこのグラフから読み取れます。

実装

全ソースはtana-kenのGithubにて公開しています。
興味を持たれた方は是非ご覧になって下さい。
以下、ポイントを絞って、実装内容を紹介します。

nsマクロ

https://gist.github.com/3331553
ライブラリとしてclojure.java.io、clojure.data.csv、clojure.java.jdbc、incanter.core、incanter.chartsを利用します。

csvファイル読み書き


ファイルサイズが十分に小さいため、遅延シーケンスとして処理をせず、doallにより全データをメモリ上に読み込んでいます。

行列入れ替え


元ファイルは、列方向にデータが追加される仕様であったため、行方向にデータが追加されるよう、行と列を入れ替える処理を実装しました。

RDBMS利用


組み込みRDBMSとしてH2 Database Engineを採用しました。
csvファイル読み込み同様、想定される取得データが十分小さいため、doallにより全データをメモリ上に読み込んでいます。
また、今回はテーブルを結合する必要がないため、H2 Database Engineのcsvファイル読み込み機能を利用しました。(csvファイル読み込み -> 整形 -> 1ファイルに結合 -> H2 Database Engineにてテーブルとして利用)

グラフ描画


incanterを通じてjfreechartオブジェクトを作成しています。
RDBMSからグラフ描画に必要なデータセットを取り出し、グラフを描画します。

nsマクロ


incanterで利用しているjarと依存関係で不整合があったため、プロジェクトを分けました。ライブラリにはclj-pdfを利用しています。

内容作成


タグ付けされたベクタにて要素を構成しています。
sort-by関数により、ページを制御しています。

PDF描画


pdfマクロにて、与えられた内容をpdfファイルとして出力します。

今回の作業は以上、最後までお読み頂きありがとうございました。
たなけん(作業時間4時間)

2012年7月29日日曜日

Webクライアントの実装(3)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
鳥のさえずりで、毎日優雅に目覚めている、たなけんです。(私の住んでいるキャンベラは人よりも大型の鳥の方が数が多いようで、叫び声に似た鳴き声で毎日起こされています。)
本エントリでは、Clojurescript(というかClosure Library)でのログ出力の方法および、これまで作成したWebクライアントの、ロジックの分離について記載します。

ログ出力の設定

Closure Libraryではログ出力の為のクラスを提供しており、それをインスタンス化するだけでログを出力することができます。
また、ログの出力先をコンソールにするなど、コンソール環境を整えるクラスのスタティックメソッドを用いて、ログ出力環境を設定することができます。
コードは、本エントリ末尾に掲載します。

ロジックの分離

ロジック分離前のソースコードでは、サーバから渡されたデータをさらにgoogle visualization apiのDataTableクラス用に加工していました。このデータ変換は、クライアント側で行う必要性が薄いため、サーバ側でクライアントが必要するデータの形式に変換するようにしました。
また、clj->js関数については非常に汎用性が高い関数(標準ライブラリに入っていても良さそう)であるため、名前空間my-dictionary-client.utilに移動しました。

ロジック分離後のソースコード(クライアント)


ログの出力設定後、google visualization apiを読み込み、読み込み後にinit関数を呼び出します。init関数でdictionary-button要素のonClickイベントとdictionary-request関数を結びつけ、ボタン押下時にサーバと通信し、結果を表示します。
ロジックを可能な限りサーバ側へ寄せたことで、クライアント側での処理をライブラリの利用準備とユーザの操作への応答のみに限定することができました。
サーバおよびクライアントの全ソースコードは、githubにて公開していますので、関心のある方は是非ご覧になって下さい。

今回の作業は以上。最後までお読みいただきありがとうございました。
たなけん(作業時間30分)

Clojurescriptでrepl

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
Clojurescriptの深みに日々はまっている、たなけんです。
本エントリでは、Clojurescriptでのrepl使用方法を記載します。

Clojurescriptのreplの種類

Clojurescriptでは、以下の2種類のreplを利用することができます。

  • Rihno環境
  • Webブラウザ環境

今回は、ブラウザ上でのClojurescriptの挙動を確認するため、後者のWebブラウザ環境でのreplの使用方法について記載します。
Webブラウザ環境のreplでは、cljsbuildプロセスが入出力を処理し、Webブラウザプロセスが入力されたS式を評価します。

cljsbuildによるrepl利用の準備

cljsbuildはコンパイルだけではなく、replの起動、テストの実行といった機能も兼ね備えています。しかし、Webブラウザ環境でreplを起動するには、接続用のhtmlを読み込むClojurescriptおよび接続用のClojurescriptが必要となります。今回はClojurescriptのwikiを例として取り上げますが、実際に開発しているアプリケーションに、数行付け加えるだけでも、Webブラウザ環境のreplを使用することができます。
下記で示される、コードはClojurescriptのrepl利用の手引きからの引用となります。


htmlファイル


何の変哲も無い、ただ接続用のClojurescriptを読み込むだけのhtmlです。
しかし、1点だけ注意事項があります。それは、必ずボディ部でscript要素を宣言しなくてはいけないということです。
私は当初ヘッド部でJavascriptライブラリの読み込みを宣言しており"Type error: parentElm is null"というエラーに悩まされてしまいました。

接続用のClojurescript


clojure.browser.replを利用し、cljsbuildで起動したポートへ接続します。
clojure.browser.repl/connect関数: 引数のurlへ接続し、replへの入力を受け付ける

起動から接続まで

以下の手順によりreplを起動し、入出力プロセスと評価プロセスを接続します。

  1. コンソールを起動、cljsbuildを利用しているプロジェクトのルートへ移動
  2. コンソールから、lein trampoline cljsbuild repl-listenと入力し、replを起動
  3. Webブラウザを起動し、接続用htmlを読み込む
  4. 同じWebブラウザからurl(デフォルトlocalhost:9000)へアクセスし、cljsbuildのreplと、Webブラウザの接続を確立(接続用のhtmlファイル名がindex.htmlではない場合(例. not-index.html)、urlはhttp://localhost:9000/not-index.htmlのようになる)

replの利用

接続が確立された後は、コンソールから評価したい式を入力することで、ブラウザのdom要素等を操作することができます。
また、load-namespace関数を使うことで、クラスパス内の任意のClojurescriptファイルを読み込むことができます。

今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん(作業時間45分)

2012年7月27日金曜日

Webクライアントの実装(2)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
新学期が始まり、そろそろ会計とマネジメントの授業に集中せねばとプレッシャーを感じている、たなけんです。
本エントリでは、Google visualization APIを利用したUIの実装について記載します。

Webクライアントの実装(2)

Closure Libraryでは多彩なUIコンポーネントが用意されています。しかし、Closure LibraryのUIコンポーネントはややオーバースペックであるため、Google visualization APIを利用し、表形式で結果を表示したいと思います。

htmlへの追記


Google jsapiを利用するため、下記の内容をindex.htmlのヘッダ部に追記しました。

データの変換


JSONをClojureオブジェクトへ変換する関数です。
semperosnのgistで公開されていた関数をコピーさせて頂きました。

google visualization API読み込み


ライブラリを読み込み、読み込み後にinit関数を実行するよう設定します。

  • google/loadメソッド: ライブラリを読み込む
  • google/setOnLoadCallbackメソッド: ライブラリ読み込み後に実装する関数を指定


表データの作成


サーバから返された値から、google.visualization.Tableクラスのコンストラクタが要求する形式のデータを作成します。

表の描画


div要素resultに表を描画します。
  • js/クラス名 特殊形式: 指定されたクラスをJavaScriptのオブジェクトとして利用する
  • google.visualization.Tableクラス: テーブルを描画するクラス。引数に、描画する位置となる要素を指定する
  • google.visualization.DataTableクラス: データを司るクラス。引数にデータとなるJSONを指定する

今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん(作業時間45分)

2012年7月25日水曜日

クライアント/サーバ間通信でのトラブル

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
最近になってビリーズブートキャンプに入隊した、たなけんです。
本エントリでは、クライアント/サーバ間通信でのトラブルとその解決方法について記載します。

現象の整理

Webクライアントからサーバにアクセスした際、あるブラウザ(Safari)では期待通りの結果が表示されるが、他のブラウザ(Chrome、Firefox)では期待通りの結果が表示されませんでした。
表示されない原因として、サーバから返されるhttpレスポンスのボディ部に、ブラウザ毎で下記の違いがありました。

  • Safari: httpレスポンスのボディ部にサーバから返されたデータが設定されている
  • Chrome & Firefox: httpレスポンスのボディ部に何も設定されていない


クライアントを疑う

ClojurescriptでのWebクライアントの実装は初めてだったため、もしかしたら何かバグを踏んでいるのではないかと思い、極力シンプルな2つのテストを実施しました。

  • ブラウザから直接アクセス: すべてのブラウザで期待した結果が得られた(リクエストのボディ部に設定したJSON文字列が表示された)
  • jQueryを用いたAjaxクライアントの利用: Clojurescriptと同様、Safariと他のブラウザで異なる結果となった

クライアントコード

これらの結果から、問題はクライアントの実装ではないと判断しました。

サーバ側を変更してみる

Compojureとブラウザ側のXmlHttpRequestとの相性問題などの可能性を考え、2つの異なるhttpサーバを用いたコードを作成し、各Webブラウザより先述したクライアント(jQuery版)からアクセスしたところ、下記の様な結果となりました。

  • Bishop (clojure/ringベースの別のwebサーバ(Web Machineクローンで、Webサービス提供用に機能を特化している)): Clojurescriptと同様、Safariと他のブラウザで異なる結果となった
  • restify (node.js上で動作するWebサーバ用ライブラリ): すべてのブラウザで期待した結果が得られた

Compojure同様clojure/ringベースの別のwebサーバであるBishopを用いても問題は解決せず、node.jsベースのrestifyでは問題なく動作することが分かりました。

トラブルの原因と解決方法

ブラウザからローカルのファイルにアクセスする場合には、ブラウザの起動オプション等を変更する必要があるという様な話は以前より知っていましたが、今回の現象はローカルのWebサーバへのアクセスなので、ブラウザの起動オプションを変更しても問題は解決されませんでした。
通常の開発と今回のとの相違として、httpサーバにアクセスしてindex.htmlを取得し、それをブラウザから操作するのではなく、ローカルで作成したindex.htmlをブラウザから直接開いて操作しているという点に思い至りました。つまり、サーバとしては自分がホストしているドメインとは異なるドメインからアクセスを受けたと認識している訳です。
そこで、外部ドメインからのアクセスを許可するようサーバ側のコードを変更しました。具体的にはhttpヘッダに"Access-Control-Allow-Origin" "*"を追加するよう改修しました。
改修の結果ChromeおよびFirefoxでも期待通りの結果を得ることができました。
今後クライアントサイドMVCフレームワークの流行等で、サーバとクライアントを切り離して開発することも増えるかと思います。その際、同様の問題が発生した場合には、サーバ側でAccess-Control-Allow-Originが適切に設定されているかどうかを確認すると良いという貴重な教訓を得ることができました。


今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん(作業時間120分(トラブルシュート含む))

Webクライアントの実装(1)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
昨日美味しい生牡蠣を腹一杯食しご機嫌の、たなけんです。
本エントリでは、Clojurescriptを利用したWebクライアント開発について記載します。

Clojurescriptとは

Clojurescriptとは、ClojureでJavaScriptアプリケーションを開発するためのライブラリ群です。CoffeeScriptやJSX同様、書かれたプログラムをJavaScriptにコンパイルすることによって、アプリケーションをJavaScriptが動作する環境(webブラウザやnode.jsなどのサーバ上)で動作させることができます。

なぜClojurescriptなのか

JavaScriptの言語仕様(変数スコープ、プロトタイプ方式オブジェクト指向など)に馴染めないこと、Clojureスタイルでのプログラミングが私にとって最も効率が良いということからClojurescriptを利用することにしました。
また、ClojurescriptはGoogle Closure Toolsを利用しているため、Closureが提供するクラス方式のオブジェクトシステムや、多彩なUIコンポーネントが利用できる点も魅力でした。

Clojurescriptの導入

ひなたねこさんの記事を参考にlein-cljsbuildを導入しました。lein cljsbuild auto としておけば、core.cljsを更新したタイミングでJavaScriptにコンパイルされます。(他のツールは必要なく、lein-cljsbuildだけで完結している点が素晴らしいです)
また、emacsのClojurescript-modeはELPA経由でインストールしました。
Clojurescript用のreplもemacsから利用可能な様でしたが、今回は出力されたJavaScriptを見てデバッグを行いました。(時間を見つけて、Clojurescriptのreplも試そうと思います)

Webクライアントの実装(1)

プロジェクトファイル


プラグイン部でlein-cljsbuildの利用を宣言します。また、closure compilerで用いるコンパイルオプションをcljsbuild部で指定します。今回は生成されるJavascriptの可読性を重視したため、最適化はしない方針としました。

index.html


ヘッダ部でJavaScriptファイルを指定し、ボディ部の最後でmain関数を呼び出しています。また検索語を入力するフォーム、確定ボタン、結果表示用のdiv要素を宣言しました。

nsマクロ


通常のClojureとの違いとして、ClojureからJavaのクラスを利用する場合は:requireではなく:importを使用するのですが、ClojurescriptからClosure Libraryのクラスを利用する場合もClojureのライブラリ同様:requireで良いという点があります。
nsマクロでは、以下のライブラリの利用を宣言しました。
  • clojure.browser.event: ブラウザのイベントを操作するClosure Libraryのクラス群の薄いラップしたライブラリ
  • clojure.browser.dom: ブラウザのDOMを操作するClosure Libraryのクラス群の薄いラップしたライブラリ
  • goog.net.XhrIo: Closure Libraryが提供するJacascriptのhttpXmlRequestオブジェクトを操作するクラス


main関数


確定ボタンのクリックイベントをトリガーにdictionary-request関数を呼びます。

  • clojure.browser.event/listen関数: 引数に指定された要素、イベントによって第3引数で指定された関数が呼び出されるよう設定
  • clojure.browser.dom/get-element関数: 引数に指定されたシンボルのidに合致する要素を取得

生成されたJavaScript


dictionary-request関数


httpのGETメソッドによるリクエストを送信し、結果を引数にコールバック関数を呼び出します。
  • goog.net.XhrIo/sendメソッド: 引数のurlにhttpのGETメソッドによるリクエストを送信
  • clojure.browser.dom/get-value関数: 引数に指定された要素の値(今回の場合、フォームquery-wordに入力された文字列)を取得
生成されたJavaScript


dictionary-callback関数


httpレスポンスからJSONオブジェクトを取得し、create-list関数を用いて結果を変換し、変換された結果をdiv要素の子要素として追加します。
  • .-プロパティ名 特殊形式: JavaScriptオブジェクトのプロパティにアクセス(今回の場合entriesプロパティ)
  • goog.net.XhrIo/getResponseJsonメソッド: 取得されたレスポンス内のデータをJSONオブジェクトとして取得
  • clojure.browser.dom/append関数: 第1引数に指定された要素に、第2引数に指定された要素を子要素として追加
生成されたJavaScript

create-list関数


JSONオブジェクトを引数に取り、textプロパティから値を取得し、<ul><li>textプロパティの値</li> ... </ul>形式のdom要素を作成します。

  • clojure.browser.dom/html->dom関数: html形式の文字列からDOMツリーを生成


生成されたJavaScript

意外な落とし穴

実装を終えて早速クライアントからサーバへの疎通を確認しようと、ブラウザからアクセスしたところ、Safariでは問題なくレスポンスが処理されるが、Firefoxではレスポンスのボディ部が0バイト(サーバ側で設定したはずの値が、ボディ部に含まれていない)様な挙動を見せ、想定した通りの処理をすることができませんでした。
ブラウザ毎に異なる挙動はClosureライブラリで吸収されているはず、と思いながらも、ここから問題解決まで思ったよりも時間が掛かってしまいました。。。(次回に続く)


今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん (作業時間90分)

2012年7月23日月曜日

第2イテレーションの計画

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。
『今やる、すぐやる、出来るまでやる』がモットーの、たなけんです。
本エントリでは、第2イテレーションの計画として、仕様および実装方針を記載します。


第2イテレーション(プレゼンテーション層/Webクライアント)の仕様

第2イテレーションで実装する機能の仕様は以下の通り。
  • 定義を取得したい単語をhttpリクエストを送信する
  • 外部APIからの抽出結果をhttpレスポンスとして受信する
  • 受信したデータを整形して

実装方針

  • クライアントはWebブラウザとし、Ajax通信によりサーバへ問い合わせる
  • クライアントプログラムの実装には、Clojurescript / Google Closure Libraryを用いる
  • CSSの作成にSCSS(Sass)を用いる

テスト方針

  • JsUnitを用いて単体テストを実施する
  • PhantomJSを用いて単体テストを自動化する
  • Seleniumにより結合テストを実施する


今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん (作業時間10分)

2012年7月15日日曜日

第1イテレーションの振り返り

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。、たなけんです。本エントリでは、第1イテレーションを振り返ります。


第1イテレーションの振り返り

普段はツール開発にClojureを利用していましたが。今回のアプリケーション開発では、堅牢なアプリケーション開発のために以下の点を意識しました。

  • ライブラリの利用
  • ツールの利用
  • 実装


ライブラリの利用

多数のライブラリを利用しましたが、その中でも下記のライブラリについて利用した感想を簡単に紹介したいと思います。

  • clojure.tools.logging: ログ出力。副作用のある処理なのでdoと合わせて使うと便利
  • clj-xpath: xpath問い合わせ。完結かつ柔軟にxmlノードを抽出できて便利
  • clojure.test: テストコード定義。Leiningenからもテストが実行可能で便利


ツールの利用

実際にツールを利用した感想を以下に記します。

  • IDE: emacs。起動、終了が高速かつ、replを利用しながらテスト可能でありEclipceよりも使い勝手が良い印象
  • バージョン管理: git。特別な利用をしていないためSubversionなどと同様な印象
  • 継続的インテグレーション: Jenkins。まだ運用方法が未確立



実装

実装時に様々なClojureの機能や関数を利用しましたが、その中でも便利だったものを以下に紹介します。


  • 例外処理: gen-classを使用。Exceptionを継承することでアプリケーション例外を定義
  • 関数の公開範囲: 他の名前空間から呼ばれない関数はdefn-で定義
  • reduce関数: ネストされたハッシュから値を抽出する際に利用




今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん (作業時間30分)

アプリケーションのテスト(3)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。夜6時以降は炭水化物を摂取しない、たなけんです。本エントリでは、アプリケーションのテスト(3)について記載します。

アプリケーションのテスト(3)

関数の機能を変更したため、テストコードも変更しました。
テスト事項は以下となります。
  • interface-for-clientのテスト
  • call-apiのテスト
  • 抽出関数のテスト
また、以下のテストデータを追加しました。
  • test/data/test-dictionary.xml
  • test/data/test-thesaurus.xml
  • test/data/test-slang.xml
  • test/data/test-etymology.xml
  • test/data/test-example.xml
  • test/data/test-questionanswer.xml
  • test/data/test-synonym.xml
  • test/data/test-random-dictionary.xml
  • test/data/test-random-thesaurus.xml
  • test/data/test-spelling.xml
  • test/data/test-wotd.xml

interface-for-clientのテスト


httpのGETリクエストからcall-apiを呼び出し、正常に処理されることを確認します。

call-apiのテスト


url、パラメータ及び抽出関数を引数に、call-apiが期待する動作をするかどうかを確認します。

抽出関数のテスト


与えられたxmlから、期待される値が抽出されることを確認します。
また期待される値を定数として定義します。

テストデータの登録


Dictionary.comの各APIにアクセスした際に取得されるxmlを定義します。

今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん (作業時間30分)

2012年7月14日土曜日

クライアント向けインターフェースの実装(2)

はじめに

おはようございます。当ブログにアクセス頂き、ありがとうございます。好きな言語は?と聞かれたら、Clojureと即答する、たなけんです。本エントリでは、プレゼンテーション層とアプリケーション層とをつなぐ、クライアント向けインターフェースの実装について記載します。

クライアント向けインターフェースの実装(2)

前回リストアップした以下の項目に従い、各関数を修正します。
  • interface-for-clientへのリクエストの処理を追加
  • 関数を引数に取り、抽出結果のJSON文字列を生成する関数の追加
  • 利用APIに対応した抽出関数の追加

interface-for-clientへのリクエストの処理


urlリソースと関数を関連付けます。例えば、http://localhost/dictionary/testへアクセスすると、引数のwordに"test"が拘束された状態で、call-apiが呼び出されます。

  • compojure.core/defroutesマクロ: urlリソースを定義
  • compojure.core/GETマクロ: http GETメソッドによりアクセスされる節を構成
  • call-api関数: url、パラメータリストおよび抽出関数を引数に取り、JSON文字列を生成


抽出結果のJSON文字列を生成する関数


抽出関数を引数に取り、Dictionary.comから取得したxmlから必要な情報を抽出した結果のJSON文字列を生成します。

  • ->マクロ: 左の関数を評価した結果を右の関数の引数とし、順次関数を実行
  • build-url-with-prms関数: urlパラメータのリストからurl文字列を生成
  • get-body関数: 引数のurlへhttpリクエストを送信し、そのhttpレスポンスのbody要素を取得
  • extract-function(引数): 関数呼び出し時に指定される抽出関数
  • clj-json.core/generate-string関数: clojureオブジェクトをJSON文字列に変換

抽出関数


xpathによりxmlからノードを取得し、さらにそこから指定した要素を抽出します。

  • safety-xpath-call関数: xpathによりxmlからノードを取得する。指定したxpathが取得出来なかった場合、handle-exception関数を呼び出す
  • get-result関数: safety-xpath-call関数により取得したxmlノード(ネストした状態のハッシュ
  • )から、順にキーを指定して、求める値を取得する
  • get-query-word関数: xml内に含まれる、問い合わせ単語を取得する。具体的にはxpathが(/*)[1]のノードから、キー:attrs :queryの値を取得する。
  • extract-dictionary関数: 英英辞書APIから取得したxmlから、問い合わせ単語と定義を抽出する。
  • extract-example関数: 例文辞書APIから取得したxmlから、問い合わせ単語と例文を抽出する。
  • extract-random関数: ランダムAPIから取得したxmlから、単語を抽出する。
  • extract-spelling関数: 綴り時APIから取得したxmlから、問い合わせ単語と綴り字の候補を抽出する。





今回の作業は以上。最後までお読み頂きありがとうございました。
たなけん (作業時間120分)