HomebrewでMySQLをインストール
何だか一発で上手くいかなかったのでメモ。最終的にはこれでうまく行った。
# これが効いたかどうかわからない sudo chown -R `whoami` /usr/local brew install mysql # インストール後の説明では mysql_install_db にいろいろオプション与えてるけど、無くてもよさげ。 cd /usr/local/Cellar/mysql/5.5.10 scripts/mysql_install_db # 起動用 launchctl load -w /usr/local/Cellar/mysql/5.5.10/com.mysql.mysqld.plist
これ真似した http://solutions.treypiepmeier.com/2010/02/28/installing-mysql-on-snow-leopard-using-homebrew/
「定本 解析概論」の誤植 (P12)
定本 解析概論のP12下の方、
任意のに対して.
となってるが正しくは
任意のに対して.
だと思う。じゃなくて。
- 作者: 高木貞治
- 出版社/メーカー: 岩波書店
- 発売日: 2010/09/16
- メディア: 単行本(ソフトカバー)
- 購入: 1人 クリック: 49回
- この商品を含むブログ (14件) を見る
Capybara+Seleniumのユニットテストで使うブラウザを変更する方法
昨日 の続きです。
最新版(まだ開発版)のCapybaraを使うと簡単にSelenium経由でFirefoxを使ったユニットテストができると書きましたが、その仕組みが謎だったので調べました。
Seleniumで使うブラウザをFirefoxからChromeに変える
spec/spec_helper.rb に以下の設定を書きます。
require 'capybara/rspec' Capybara.register_driver :selenium_chrome do |app| Capybara::Driver::Selenium.new(app, :browser => :chrome) end Capybara.javascript_driver = :selenium_chrome
- Configuring and adding driversのところに書いてあります。
- Sporkを使う場合、Spork.each_run do ... end の中に書いても、sporkプロセスを再起動しないと反映されないみたいです。
新しいSeleniumはどうやって動いているか
以前のSelenium (Selenium RC)の場合、RCのプロセスを先に立ちあげておく必要があったと思いますが(うろ覚え)、新しいSelenium (Selenium 2.0 and WebDriver)では特に面倒な設定・準備なしで使えるようです。
以下、CapybaraがどのようにSeleniumを起動しているか調べた事をまとめます。
まず、JavaScriptの試験をCapybara+Seleniumを使って行いたい場合、:js => true オプションを渡します。
describe "POST /articles", :js => true do # ... end # または it "JSのテスト", :js => true do # ... end
Capybaraはこのオプションを見るとテストを実行するドライバを入れ替えます。javascript_driverのデフォルトは:seleniumです。
# capybara/lib/capybara/rspec.rb Capybara.current_driver = Capybara.javascript_driver if example.metadata[:js]
CapybaraのSelenium driverは、selenium-webdriverというライブラリを使ってSeleniumを操作します。これはSeleniumの新しいAPIを使ったライブラリのようです。詳しくはSeleniumの本家にいろいろ書いてあります。
ここで、Seleniumで使うブラウザのデフォルトは:firefoxになっています。
# capybara/lib/capybara/driver/selenium_driver.rb require 'selenium-webdriver' class Capybara::Driver::Selenium < Capybara::Driver::Base DEFAULT_OPTIONS = { :resynchronize => true, :resynchronization_timeout => 10, :browser => :firefox }
ついでに selenium-webdriver を眺めてみると、他にもいろいろなブラウザに対応したドライバがあります。
# selenium-webdriver/lib/selenium/webdriver.rb module Selenium module WebDriver Point = Struct.new(:x, :y) Dimension = Struct.new(:width, :height) autoload :Android, 'selenium/webdriver/android' autoload :Chrome, 'selenium/webdriver/chrome' autoload :IE, 'selenium/webdriver/ie' autoload :IPhone, 'selenium/webdriver/iphone' autoload :Remote, 'selenium/webdriver/remote' autoload :Firefox, 'selenium/webdriver/firefox'
RSpec+Capybara+SeleniumでJavaScriptのテスト
WEB+DB PRESS Vol.61の「Rails3テスト最前線」が話題のようです。
最新のRailscastsでちょうどRequest Specs and Capybaraが取り上げられていたので、WEB+DB PRESSの記事に載っていない部分を簡単にまとめてみます。
関連記事: WEB+DB PRESS vol.61 Rails3テスト最前線がすばらしい - tech-kazuhisa's blog
結論から言うと
Capybaraの最新版を使うと、SeleniumでJavaScriptのテスト簡単に書けます。
やり方
Gemfileで、capybaraの最新版を使うようにgitリポジトリを指定します。JavaScriptとDBを同時に使う機能のテストをする場合はdatabase_cleanerも必要です。
group :development, :test do gem 'rspec' gem 'rspec-rails' gem 'capybara', :git => 'git://github.com/jnicklas/capybara.git' gem 'database_cleaner' end
spec/spec_helper.rbでcapybara/rspecを読み込みます。
require 'capybara/rspec'
database_cleanerを使う場合はspec/spec_helper.rbに設定を追加します。Seleniumを使ったテストを行う場合、デフォルトの "use_transactional_fixtures = true" ではDBを使ったテストは失敗します。
config.use_transactional_fixtures = false # for selenium config.before(:suite) do DatabaseCleaner.strategy = :truncation end config.before(:each) do DatabaseCleaner.start end config.after(:each) do DatabaseCleaner.clean end
JavaScriptを使うテストに ":js => true" を付ければ完了です。テストはFirefoxで実行されます。*1
describe "POST /articles", :js => true do # ... end # または it "JSのテスト", :js => true do # ... end
:js => true なテストはブラウザが立ち上がるのでとても遅いです。JavaScriptを使わないテストだけを実行したい場合は、
rspec -t '~js' spec
とすれば良いでしょう。(sporkを使うと -t '~tag' は無視されるような気がするけどなんでだろう)
おまけ
WEB+DB PRESSの記事には載っていないようですが、capybaraを使ったインテグレーションテストのひな形を生成するには以下のコマンドが使えます。(r は rails のエイリアス、articleはテストするモデル名)
r g integration_test article
これを実行すると、spec/requests に下のようなファイルが生成されます。
require 'spec_helper' describe "Articles" do describe "GET /articles" do it "works! (now write some real specs)" do # Run the generator again with the --webrat flag if you want to use webrat methods/matchers get articles_path response.status.should be(200) end end end
サンプルコード
githubに置きました。
参考
やってみた: (1 2 3 4 5)が与えられたとき( (1 2) (2 3) (3 4) (4 5) )を返すような関数の定義
答え見ないでやってみた
vallog: [1,2,3,4,5] が与えられたとき [[1,2][2,3][3,4][4,5]] を返すような関数を定義せよ
#!/usr/bin/env gosh (use srfi-1) (use util.list) (use gauche.test) ;; 1 だけならこれ (define (slices* lis) (zip lis (cdr lis))) ;; 2 だとこれ。効率わるいかも。 (define (slices* lis :optional (n 2)) (let loop ((lis lis) (r '())) (if (or (null? lis) (null? (cdr lis))) (reverse r) (loop (drop* lis (- n 1)) (cons (take* lis n) r))))) (test* "1" '((1 2) (2 3) (3 4) (4 5)) (slices* (list 1 2 3 4 5))) (test* "2" '((0 1) (1 2) (2 3) (3 4) (4 5) (5 6) (6 7) (7 8) (8 9)) (slices* (list 0 1 2 3 4 5 6 7 8 9) 2)) (test* "3" '((0 1 2) (2 3 4) (4 5 6) (6 7 8) (8 9)) (slices* (list 0 1 2 3 4 5 6 7 8 9) 3)) (test* "4" '((0 1 2 3) (3 4 5 6) (6 7 8 9)) (slices* (list 0 1 2 3 4 5 6 7 8 9) 4))
答えみたけど素敵な解法いろいろある!
それよりtransposeってこんなに簡単に書けるのか!に感動した。
(define (transpose m) (apply map list m)) (transpose '((0 1 2 3)(4 5 6 7)(8 9 10 11)(12 13 14 15))) ;; -> ((0 4 8 12) (1 5 9 13) (2 6 10 14) (3 7 11 15))
数学勉強記録
4章むずい。しばらく別の本読んだ後、また4章からやり直そう。
- 作者: 佐武一郎
- 出版社/メーカー: 裳華房
- 発売日: 1974/01/20
- メディア: 単行本
- 購入: 1人 クリック: 12回
- この商品を含むブログ (26件) を見る
Canvasでコッホ曲線描いてHerokuで公開してみた
id:keyesberry さんの記事 CanvasアニメーションをHerokuで公開しようよ! - hp12c を見て面白そうだったので作ってみました。
コッホ曲線を書くだけのものです。クリックすると細かい曲線になっていきます。ある程度までいくとまた粗くなっていって最終的に直線になります。ただそれだけ。
これ http://fractals.heroku.com/
アプリケーションの構成
JavaScript以外はほぼ丸パクリですが一応書くと
具体的なWebアプリケーションの作り方は id:keyesberry さんが詳しく書いてくれているのでそちらを参照して下さい。
以下、雑な解説。
fractals.js
メインのJavaScriptコードです。
var canvas = {}; $(document).ready(function() { canvas.c = $("#fractals"); canvas.ctx = canvas.c[0].getContext('2d'); canvas.width = canvas.c.width(); canvas.height = canvas.c.height(); canvas.ctx.save(); clearCanvas(); var iteration = 1, limit = 7, delta = 1; drawKoch(iteration); $(canvas.c).click(function() { clearCanvas(); iteration += delta; drawKoch(iteration); if (iteration >= limit || iteration <= 0) { delta = -1 * delta; } }); }); function clearCanvas() { canvas.ctx.restore(); canvas.ctx.clearRect(0, 0, canvas.width, canvas.height); canvas.ctx.save(); canvas.ctx.translate(canvas.width/2, canvas.height*3/4); }
この辺は元のコードとだいたい同じです。
座標系の変換を少し変えました。コッホ曲線のベースの直線をx軸上とし、またx軸をCanvasの下から1/4に置きます。
Canvas上の原点は左上でx軸、y軸の正の向きはそれぞれ右方向、下方向です。上のようにして変換後の原点がCanvasの中央、上端から3/4の位置にくるようにします。
Canvasのクリア方法ですが、座標を変換したままクリアするのは面倒なので、restore()で座標変換前の状態に戻してからクリアするようにしました。
jQueryでクリックイベントの処理を書きます。
function kochify(start, end) { var ps = trisect(start, end); var vertex = rotate60(ps[1], ps[2]); return [ps[0], ps[1], vertex, ps[2], ps[3]]; } function trisect(start, end) { var p1 = [start[0] + (end[0]-start[0])*1/3, start[1] + (end[1]-start[1])*1/3]; var p2 = [start[0] + (end[0]-start[0])*2/3, start[1] + (end[1]-start[1])*2/3]; return [start, p1, p2, end]; } function rotate60(start, end) { var v = [end[0] - start[0], end[1] - start[1]]; var rotated =[ v[0] * Math.cos(-Math.PI/3) - v[1] * Math.sin(-Math.PI/3), v[0] * Math.sin(-Math.PI/3) + v[1] * Math.cos(-Math.PI/3) ]; return [ start[0] + rotated[0], start[1] + rotated[1] ]; } function flatten() { var points = []; for (var i = 0, l = arguments.length; i < l; i++) { var ps = arguments[i]; for (var j = 0, m = ps.length; j < m; j++) { points.push(ps[j]); } } return points; }
この辺は補助関数です。
trisect()は始点と終点を受け取り、直線を3等分する4つの座標を返します。
rotate60()は同じく始点と終点を受け取り、それをベクトルと見て、60度回転した終点の座標を返します。回転行列を使う例のやつですね。
気を付けないといけないのは、y軸が下向きなため逆向きに(-60度)回転する必要があることです。はまりました。
変な名前のkochify()は、上の関数を使ってコッホ関数を描くのに必要な5つの座標を返します。
function drawKoch(iteration) { var left = -canvas.width/2; var right = +canvas.width/2; var start = [left,0], end = [right,0]; var points = koch(iteration, start, end); var ctx = canvas.ctx; ctx.strokeStyle = "black"; ctx.lineWidth = 1; for (var i = 0, len = points.length; i < len - 1; i++) { var s = points[i]; var e = points[i+1]; ctx.beginPath(); ctx.moveTo(s[0], s[1]); ctx.lineTo(e[0], e[1]); ctx.stroke(); } } function koch(iteration, start, end) { var points = []; var recur = function(iter, s, e) { if (iter === 0) { points.push([start, end]); } else if (iter === 1) { points.push(kochify(s, e)); } else if (iter > 0) { var ps = kochify(s, e); recur(iter-1, ps[0], ps[1]); recur(iter-1, ps[1], ps[2]); recur(iter-1, ps[2], ps[3]); recur(iter-1, ps[3], ps[4]); } else { throw "must not happen"; } }; recur(iteration, start, end); return flatten.apply(null, points); }
drawKoch()はkoch()関数を呼び出して実際の描画を行います。koch()関数は点の座標を配列で返します。
koch()関数は、指定された回数に従って、線分を分割し再帰的に座標を計算します。変数pointsを破壊的に変更するのが何だか気に入らないかも。
以上、こんな説明で通じるかどうか分かりませんが終わりです。
久しぶりにカビの生えた幾何学脳をフル回転させて楽しかったです。
サイト名がfractalsと複数形なのは、今後また他のフラクタル図形を描くかもしれないから。
本当はマンデルブロ集合を描きたかったけど、とりあえず簡単なのからやってみました。