N=1

主にコンピュータ技術関連のことを投稿。 / 投稿は個人の意見であり所属団体の立場を代表するものではありません。

「アンダースタンディング コンピュテーション」演習環境を整える

この本は、情報系の大学の、オートマトンと計算理論にあたる部分を自習できる教材である。具体的にはRubyのREPL環境で、コンピュータを作っていくことになる。ただ、Ruby標準のREPLであるirbはコーディングには貧弱なので、少し準備してみた。

irbの代わりにpryを使おう

pryはirbと比べて以下の点で有利だった。

  • シンタックスハイライト
  • 入力補完
  • 途中、vimで編集可能
  • コードのインポート、エクスポート

Home · pry/pry Wiki · GitHub

$ gem install pry

pryコマンドで開始できる。

pryの出力方法を変更する

pryでそのまま実行しても、本と同じ出力を得られない。本では構文木構築の結果をirbの実行結果として

<<1 * 2 + 3 * 4>>

のように表示させるのだが、pryだと各オブジェクトの詳細まで出力してしまって、

=> #<struct Add
 left=
  #<struct Multiply
   left=#<struct Number value=1>,
   right=#<struct Number value=2>>,
 right=
  #<struct Multiply
   left=#<struct Number value=3>,
   right=#<struct Number value=4>>>

となってしまう。

元のirbと同じように出力するには、~/.pryrcに以下を記述する。

Pry.config.print = proc { |output, value| output.puts "=> #{value.inspect}" }

元ネタ: IRB Like Output in Pry

途中で中断したり、再開したりしたい

この本では、最初は空のクラスを作って、徐々に
モンキーパッチングで機能を追加->確認、追加->確認というふうに繰り返す。だから、クラスの全体像がわかるコードは登場しない。また、一旦REPL環境を閉じてしまうと、また最初から書き直しになってしまう。

方法A. モンキーパッチングによる追記はvimで、確認はpryで行うようにする。

いくつかやりかたがあるが、この方法の場合、クラスの書き間違いを修正しやすい。

1. vimを呼び出せるようにする

~/.pryrcに追記

Pry.config.editor = "vim"
2. 先にファイルを作る
$ touch simple.rb
3. 読み込む
pry(main)> require './simple'

または、pry起動時のオプションで渡す:

$ pry -r './simple'
4. クラスの追記
pry(main)> edit simple.rb

これでvimが開く。本のように、モンキーパッチング的にclass Numberを何回も書いていってもいいだろうし、class Number 〜〜 endの中に追記していってもいい。

(元から別ウィンドウで編集しててもOKな気がする。)

この時、ファイルを上書きするたびに読み込み直されてしまうので、クラス二重定義エラーが出る。

class Number < Struct.new(:value)
end

class Add < Struct.new(:left, :right)
end

class Multiply < Struct.new(:left, :right)
end
pry(main)> edit simple.rb
TypeError: superclass mismatch for class Number

仕方ないので、最初のスーパークラスを持たせる部分だけはInclude guard的なことをしておく。23ページのコードだったらこんな感じ。

unless defined? Number
  class Number < Struct.new(:value)
  end
end

unless defined? Add
  class Add < Struct.new(:left, :right)
  end
end

unless defined? Multiply
  class Multiply < Struct.new(:left, :right)
  end
end

class Number
  def to_s
    value.to_s
  end

  def inspect
    "<<#{self}>>"
  end
end

class Add
  def to_s
    "#{left} + #{right}"
  end

  def inspect
    "<<#{self}>>"
  end
end

class Multiply
  def to_s
    "#{left} * #{right}"
  end

  def inspect
    "<<#{self}>>"
  end
end

こうしておけば、editコマンドによる編集後の自動再読みでエラーは出なくなり、

pry(main) > edit simple.rb

さらに、クラス名を指定して編集できるようになっている。

pry(main) > edit Number       #vim起動時に自動でclass Numberの行まで移動
5. エディタを閉じて、実行してみる

リロード操作は不要

pry(main)> Add.new(
                         Multiply.new(Number.new(1), Number.new(2)),
                         Multiply.new(Number.new(3), Number.new(4))
                       )
=> ...(出力)...

4, 5の工程の繰り返しで作業していく。

参考: Ruby - Pry上でreload!要らずのファイル編集 - Qiita

方法B. 実行履歴を保存、リロードする

この方法の場合、書いたクラスの完全版がわかるコードは得られないので注意。REPLの臨場感は損なわないのでサクっと進みたい人はいいかも。

デフォルトでpryは~/.pry_historyに履歴を溜め込んでいる。

History · pry/pry Wiki · GitHub

historyを眺め、hist --replay [m..n]というコマンドで再生できる。別ファイルに保存したい場合はhist --save [m..n] FILENAME で保存できる。

Levelopができるまで

4月くらいから開発に参加していたプロジェクトが公開されました。

Levelop.org


練習メニュー共有サービスです。クックパッドのスポーツ版のようなものですね。機能が充実してきたらスポーツ以外にも、楽器や勉強法なども扱えるようにする予定です。

エンジニアとして参加したので作業プロセスや技術的側面にフォーカスして、公開までの道のりを紹介しようと思います。

プロジェクト参加

2014年3月末に、新しいウェブサービス立ち上げを構想しているという二瓶氏に誘われて参加しました。その時点で二瓶氏はすでに開発中のプロジェクトがあり、それの機能追加などをする予定でした。二瓶氏は企画、開発、運用のスキルがありますが一人では作業量が多いので、ちょいちょい声をかけた人に手伝ってもらうというスタイルでした。その時点では他にデザイナーの方がいらっしゃいました。

私はいくつか開発のアルバイトの経験はありましたが、企画から実装、運用まで一切の不満無くできるかというと結構難しいです。しかし、スタートアップ的にやっていくなら、進行方法に対して直接議論すればいいし良い経験になりそうだと思い、喜んで引き受けました。人数が少ないがゆえ好きな領域でスキルを試せるのも良いです。

プラットフォーム

  • レンタルVPS
  • Ruby on Railsバックエンド
  • AngularJSフロントエンド


作業ツール

  • Google Drive: 調査資料、ミーティング資料
  • KanbanFlow: タスク管理
  • Bitbucket: リポジトリや全体のプロジェクト管理

自分の担当箇所

  • SeleniumによるE2Eテストや実施方法,どこまで網羅するかの検討


基本はリモート作業です。週1,2回、大学のフリースペースを借りたりして対面で開発やミーティングをしました。

何回かに一度は知人の学生数人を呼んで、テスト方法について議論したりしていました。E2Eテスト、ユニットテスト、コストのトレードオフなどをまとめられ、かなり有意義でした。

f:id:ishn:20140426142257j:plain

毎回対面で作業する都度、新しいサービスの企画を考えて日々記録していくという遊びも取り入れました。

いったん破棄して再度ブレインストーミング

で、途中まで作業してたのですが、サービスのモデルに致命的な欠陥が見つかり、一旦破棄されました。

何本かアイディアをストックしていたし、既存OSSを応用させてすばやく開発しようという方針になり、改めて5人くらい知人を集めて新サービスのブレインストーミングから始めました。

  1. ソースを応用できそうな既存OSS調査(CMSみたいなのとか)
  2. ターゲットになりそうなユーザー層の調査
  3. OSSとユーザー層の組み合わせのうち最も集客が見込めるところは?

というプロセスを経て、何本か実践できそうなのが見え、そのうちのひとつがLevelopだったわけです。Levelop以外にも、開発リソースさえあればいけそうなアイディアもストックできました。

このころから体制がおおよそ以下のようになってきました。

  • 主力の企画/開発 - 二瓶氏
  • デザイナー x 1
  • フロントエンドエンジニア x 1
  • インフラエンジニア x 1

私はミドルウェアの運用をしたかったので意向を汲んでもらい、インフラエンジニア的な部分を担当することになりました。やったね!

開発

クックパッドライクなCMSレシピブック をforkして作りこみました。これはDjangoで記述されていたので自動的にDjangoプロジェクトになりました。

AngularJSの学習コストが高かっただけに、言語ごと変わってしまったのは大変ですが、二瓶氏が技術よりもサービスに主眼を置いているのでほとんどモチベーション低下を起こすことはありませんでした。この姿勢は大事だと思いました。

コミュニティ機能の実装、新しいモデルに対するテストの調整などがアプリケーションのほうのタスクになりました。

フロントエンドはJSライブラリによるCacooみたいな作図機能の導入がありました。低い実装コストで、見栄えの良い機能ができました。

私は継続して

  • 機能追加
  • 負荷テスト方法の検討
    • 調査資料から、ピーク時のセッション数、運用するとDBはどれくらいのデータを保持するか、sqliteは十分な速度を出せるか?などを考慮

などを行いました。まだ負荷テストは実施できてないんですけどね。

公開の準備

私は直前で

  • デプロイ方法のドキュメント化
  • サポート用のメールサーバー
  • SSL設定
  • Facebookページの作成

なんかを行いました。

プログラム的な部分はあまり貢献できなかったのですが、SSL設定とか普段触れることない部分が経験できました。

課題

作業時間をいかに取るか

研究で忙しい時期は週2度も集まれませんから、毎日30分作業するという方式を導入しました。しかし夜は疲れてしまってほとんど作業にならないという日が続きました。今は週2回を使えるのでいいですが、今後も工夫が必要です。

仕様の共有

現在、ER図をCacooで管理しています。CacooやGoogle Driveのようなツールが充実していて、情報共有の方法はかなり簡単になりました。しかしフルタイムで時間を使えないので、ソースコードリーディングだけで結構時間がかかってしまい中々実作業に入れませんでした。一方でコミット前に各種UMLを書くというのはオーバーヘッドが大きすぎる。

RDocのような仕様書自動生成ツールを導入してみればいいのでしょうか?仕様共有のうまい方法は調査したいですね。

今後

練習メニューの種目は現時点で少ないですから、フィードバックをもとに機能拡充をしていきますが、それ以外で行いたいのは、

  • 負荷テスト生成して、今のVPSプランでどれくらいのアクセスがさばけるか
    • 結果によって別のプランにする
  • Djangoがアレなのでまるごと書き直したい(時間かかりそう)

です。

DjangoWordpressのような思想で設計されていて、tumblrやpinterestのような、毎日の記事投稿を管理するようなモデルに向いています。Levelopは割とアプリケーション然としているので、今後拡充していくうちにDjangoは不利になりそうです。また、APIとフロントエンドの分離も行いたいのですね。

ゆくゆくはMEAN(Mongo, Express, Angular, Node)スタックでの完全書き直しができたらなぁと思ってます。ただ、これは開発リソースが磐石にならないと難しいですね。

あと最近は
tecoビジネスカフェ というコワーキングスペースをみつけたので利用しています。

今後はLevelopで使っている技術ネタをもう少し具体的に書いていこうと思います。

NRIのOSS開発合宿に参加してきた

イベントレポートです。

開催要項

  • OSS開発合宿2014
  • 日程: 2014年6月20日-22日
  • 場所: 神奈川県 マホロバマインズ三浦 というホテル
  • 人数: 30人くらい?
  • やること: 1チーム4人前後で、20時間くらいで好きなものを作って発表するだけ

感想

WebRTCとか流行りの技術を使ったチームとか、パターン認識、フィルタなどを応用したチームが多くとてもレベルが高くて楽しかったです。具体的にどのようなチームがあったか、あとでThinkITで記事になるそうなので、そちらをご覧ください。

あと私は就職したことがないけれど、大企業のお仕事ってどんな感じなのか直接聞くことができたのはよかったと思います。

NRIの人々は、途中で投げ出さないで真剣に相手の話を聞き、検証する姿勢を全員持ってて、とても元気になれました。学生同士にはないスリルがありますね。

宿泊の関係上、参加費は安くないですが、また来年も行きたいと思ってます。

成果物

AWS上で動かしてたものです。


アプリのログからテスト生成するシステム

ishikuro/devcamp2014_teambeko · GitHub


別のWebアプリケーションサーバーを監視,管理するWebアプリケーションです。未完成。

帰宅後まだ再現できていないという。書きかけだけど自分でも使いたいものだったので暇をみつけて開発続行したいですね。

やったこと(日記帳)

写真をとり忘れたのでほとんど文字だけです。

OBの先輩に誘われて参加することができました。交通や現地でのコーディネートなどほとんどやっていただいてたので、とてもありがたいことです。

[20日昼]移動

会津から高速バスと電車で三浦まで行きました。神奈川は初めてでしたが、緑が多いし陽射しが明るくて過ごしやすそうなところでしたね。開催地のホテルには夕方ころ着いて、休んでました。

[21:00]開場

参加者まばらに集合です。NRI現職の方々がお仕事で半数くらい定刻に集合できなかったことが印象深いです。業務で忙しい上に合宿でがっつり作りますからね。むしろ凄い。

[23:00]開催

はじめ、前回のあらすじ、開催要項の説明の後、各チーム数分で作りたいもの発表を行いました。

チームについて

最初7人のチームに入れさせてもらってたのですが、準備段階からさらに2チーム(4:3)に分かれて別々なものを作ることになってました。
が、さらにそれから2分割(3:1)し、それがさらに2分割(2:1)になり、気づいたら、いとうたかゆきさんと私二人のチームになってました。これから徐々に合宿では仲間割れチームとして認知されていきます。

今回予定してたやつ: アプリのログからテスト生成するシステム

f:id:ishn:20140703134840p:plain
このようなやつです。作りたかったのは、別のWebアプリケーションサーバーを監視,管理するWebアプリケーションです。

  • Rails等の対象アプリケーションのログをfluentdで監視
  • MongoDBに放り込んでおく
  • MongoDBから当該テスト生成システムがデータを抽出して、視覚化
  • HTTPメソッド, パラメータ, それに対する応答を元にワンクリックで、負荷テストスクリプト生成, 簡単なRSpec生成ができる

[21日未明]環境構築

いとうさんがAWSを用意してくれたので、手分けして

  • デモ用Railsアプリ(ログ監視対象になる)
  • fluentdでRailsのログをパースする準備

などの環境構築をしていました。

主に私はデモ用Railsアプリを探してました。URL失念しましたが、Twitterクローンのようなものを使いました。最終的には負荷のログも必要なデータだったので、負荷テスト生成もしたかったのですが時間がなくてできませんでした。

この日はこの作業を終わらない限りは俺たちの朝は来ないというつもりでやってましたが、朝食の時間ころにやっと終わりました。ご飯の前の朝風呂が気持ちよかったです。

[7:30くらい]朝食、仮眠

ビュッフェ形式の朝ごはんを食べたあと、仮眠しました。どこで寝たのかは覚えていませんね。

[10:00くらい]再開

f:id:ishn:20140621125302j:plain

正規表現をOBの先輩にやってもらったおかげで、fluentd側からRailsのログをパースする仕組みが動き始めました。

Railsのログ -> fluentd -> 必要な情報を構造化してMongoDBに保存

ここまでできています。後半は、

MongoDB -> Node.jsでNVD3用にデータ加工 -> フロントエンドで受け取り描画

また、フロントエンドから"テスト実行"ボタンを押すと、対象Railsアプリへなんらかのアクセスを飛ばす部分も作ります。

[12:00]中間報告と昼食

チーム細分化の報告をここで改めてしました。

[13:00]大詰め

MongoDBからのJSONをパースしてNVD3が読めるような形に送り出す部分で久々にプログラミングしたなぁという気持ちになりました。伊藤さんにフロントエンドと仕上げとプレゼン作成してもらってました。

[19:00]開発終了, 宴会

宴会場にプレゼンを持っていって、およそ10組のチームがプレゼンしました。どのチームもレベルが高いし、見せ方もうまかったですね。とにかく笑いがあって腹筋が痛かった。その上技術的にも高度だったり、丁寧に作りこんだりしてました。

[夜]7人チーム再会しておしゃべり

ホテルのチーム別個室に戻りました。

この7人チーム、実は私以外はNRIの同期チームなのです。仕事や技術のことについてガチトークが何時間も続いていました。

部外者の私も快く輪に入れていただいて、少し打ち解けられました。

[21日10:00]結果発表

つれてきていただいたOBの先輩のプロジェクトが努力賞取れました。レッドブルTall * 24本セットだったのですが、彼はエナジードリンク飲まない派だったので分配してました。

[12:00]BBQ

あとは浜辺でBBQでした。いろいろな技術的バックグラウンドをもった方と話せて満足です。

[13:30]会津へ戻る

あとはまた高速バスで帰りました。会津着は23:00でした。

- おわり -

Jekyllを試してみた

Jekyll基本チュートリアル

参考: http://melborne.github.io/2013/05/20/now-the-time-to-start-jekyll/

インストール

$ rbenv exec gem install jekyll

開発サーバの起動とファイル監視

$ mkdir tut
$ cd tut
$ rbenv exec jekyll serve --watch

生成

以下は作成、変更するたびに自動的にコンパイルされる。

最小
$ vim index.md
---
---
#Hello World
レイアウト作成

index.md (---に囲まれた部分はYAML)

---
layout: default
title: hi
---
# Welcome

_layouts/defaults.html

<!DOCTYPE html>
<head>
  <meta http-equiv="Content-type" content="text/html; charset=utf-8">
  <title>{{ page.title }}</title>
</head>
<body>
  {{ content }}
</body>
設定

_configに書く。

慣れてきたら

開発

開発マシン
$ rbenv exec gem install jekyll
$ rbenv exec jekyll new mysite
$ cd mysite
$ rbenv exec jekyll serve --watch #しながら、ファイルを編集

デプロイ

https://www.digitalocean.com/community/tutorials/how-to-deploy-jekyll-blogs-with-git

サーバ側
$ cd ~/
$ mkdir -p repos/mysite.git
$ cd repos/mysite.git
$ git init --bare

hooks/post-receive

#!/bin/bash -l
GIT_REPO=$HOME/repos/mysite.git
TMP_GIT_CLONE=$HOME/tmp/git/mysite.git
PUBLIC_WWW=/var/www/nginx-default

git clone $GIT_REPO $TMP_GIT_CLONE
jekyll build --source $TMP_GIT_CLONE --destination $PUBLIC_WWW
rm -Rf $TMP_GIT_CLONE
exit

./hooks/post-receiveを実行してみてうまく行くか試してみる。パッケージの不足やパーミッション設定の見直しが必要になるかもしれない。

開発マシン側
$ git init
$ git add .
$ git commit -m “initial commit”
$ git remote add mysite [repository] #書式はgit help remoteに書いてる
$ git push mysite 

ブロック図作成

要件

  • eps等、TeXで扱える形式に変換できること
  • UNIX系OSで動き、メンテナンスされていること。Windowsにしかないフリーソフトとかダメ
  • 今作りたい図(チャート的なもの)がかけること。読者には伝わらない要件である

候補

  • Graphviz 有向グラフが得意
  • blockdiag ブロック図特化

Graphvizにしてみよう。

Graphviz

install

epsを扱うために必要かもしれないのでUSEにpostscriptを追加してみた。

# USE="postscript" emrege graphviz

DOT言語

Graphviz チュートリアル

digraph flow {
  rtl [shape = box, label = "RTL Design"];
  syn [shape = box, label = "Synthesis"];
  par [shape = box, label = "Place and Route"];
  post_sim [shape = box, label = "Post P&R Simulation"];

  rtl -> syn -> par -> post_sim;
}

compile

$ dot -Tgtk design-flow.dot
(GUIで確認できたりする)
$ dot -Teps design-flow.dot -o design_flow.eps

出力形式一覧: Output Formats
f:id:ishn:20140306180509p:plain

TeXに組み込む

このままTeXで扱おうとしたらうまくいかなかった。
最近だと、pdfを最終形にしたい場合は、画像もepsではなくpdfで生成しておくほうがいいらしい。

$ dot -Tpdf design_flow.dot -o design_flow.pdf
\documentclass[a4j]{jarticle}
\usepackage[dvipdfmx]{graphicx}
\begin{document}
\includegraphics[width=5cm]{design-flow.pdf}
\end{document}

また、ツールの設定も必要。
Linux Mint の TeX Live で画像挿入するノウハウ - 余白の書きなぐり
/usr/share/texmf-dist/web2c/texmf.cnfを上記サイトと同様に編集する。

これでplatexを通せばできる。

EmacsとTexとレポート(3) Texでソース貼り付け

listings

TeXでソースコードを綺麗に表示する | SanRin舎

TeXソースコードを載せるためのパッケージにlistingsがある。これは日本語を扱えないのでjlistingを新規にインストールしなければならないらしいが、、
しかし試したところ、日本語はきちんと表示できている気がする。そもそもソースコード中に日本語を混ぜたくないので、jlistingの導入は見送る。

使い方

\documentclass[a4j]{jarticle}

\usepackage{listings}
\usepackage{color}

% 全体の設定はこのように書く
\lstset{
  basicstyle=\small,
  breaklines=true,
  keepspaces=true 
}

\begin{document}

% 個別の設定は[]内に書く

% 外部ファイルを埋め込む場合
\lstinputlisting[caption=ソースコード1, language=c]{foo.c}

% その場で書く場合
\begin{lstlisting}[caption=ソースコード2, language=PHP]
<?php
echo "Hello";
\end{lstlisting}

\end{document}

EmacsとTexとレポート(2) Texとか

つづき

TeX Live

TeX Live - Gentoo Wiki

install

/etc/portage/package.use にtexliveのUSEフラグを追加
science, tex4htは使うかわからないけど念の為

app-text/texlive cjk dvipdfm graphics png truetype science tex4ht

その後emerge

# emerge texlive

dvi -> pdfで日本語を扱う場合は以下のパッケージが必要。

# emerge dvipdfmx
how to use

foo.texを書く。a4jは日本のA4サイズ。jarticleは'Reference'が'参考文献'とかになってくれるらしい。

\documentclass[a4j]{jarticle}
\begin{document}
\title{タイトル}
\author{ishikuro}
\maketitle
本文
\end{document}

pdfにする。

$ platex -kanji=utf8 foo.tex
$ dvipdfmx foo.dvi
(PDFが生成されるのでビューアで見る)
$ evince foo.pdf

Makefileを作ると便利かも

TARGET=foo

view: $(TARGET).pdf
	evince $(TARGET).pdf

all: $(TARGET).pdf

$(TARGET).dvi: $(TARGET).tex
	platex -kanji=utf8 $(TARGET).tex

$(TARGET).pdf: $(TARGET).dvi
	dvipdfmx $(TARGET).dvi

clean:
	rm -f $(TARGET).pdf $(TARGET).dvi $(TARGET).log $(TARGET).aux