ラベル csv の投稿を表示しています。 すべての投稿を表示
ラベル csv の投稿を表示しています。 すべての投稿を表示

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年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時間)