mojavy.com

GoConveyでGoプロジェクトをブラウザからテストする

November 17, 2013 at 12:30 AM | categories: golang |

GoConvey を試してみたらなかなかよかったので紹介します。

目次

goconveyとは

gopherのためのかっこいいテストツールです。以下のような特徴があります。

  • go testをそのまま実行できる
  • リグレッションテストのための一式
  • 見やすく色付けされた出力
  • 完全に自動化されたWeb UI
  • テストコードジェネレータ
  • デスクトップ通知
  • ターミナル上で動く自動テストスクリプト
  • Sublime Textとの連携

クイックスタート

$ go get github.com/smartystreets/goconvey # install
$ $GOPATH/bin/goconvey

上記コマンドを実行して http://localhost:8080 にブラウザからWeb UIアクセスすると、goconveyを起動したディレクトリ以下のファイルの更新を自動的に検知してテストを起動してくれます。

Web UIの右上にあるベルのアイコンをクリックすると、デスクトップ通知も有効にできます。

また、テストが失敗した場合はその部分をクリックすることで、Sublime Textで直接そこにジャンプできます。1

特定のディレクトリ以下のテストを実行しないようにすることもできます。テストに時間がかかるような大きなプロジェクトでも適当に必要なところだけ有効にできるので、ストレスがたまりにくいと思います。

テストを書く

goconveyのWeb UIはgo testで起動できるテストならなんにでも使えますが2 、goconveyのテスティングフレームワークをつかうとさらにわかりやすい結果を出力できます。

package goconveytest

import (
    . "github.com/smartystreets/goconvey/convey"
    "testing"
)

func TestSpec(t *testing.T) {
    var x int

    // Only pass t into top-level Convey calls
    Convey("Given some integer with a starting value", t, func() {
        x = 1

        Convey("When the integer is incremented", func() {
            x++

            Convey("The value should be greater by one", func() {
                So(x, ShouldEqual, 1)
            })
        })
    })
}

Web UIから文章を入力することでテストコードをある程度自動生成することもできます。

BDDスタイルはあんまり得意ではないので詳細は省略します。

ターミナルから自動テスト

ブラウザなんて立ちあげたくない硬派な人向けにターミナルでファイル監視してテストを起動できるスクリプトも提供されています。 emacsのロックファイルがあると落ちてしまう問題があったのですが、さっきpull requestだしたらすぐマージしてくれました。 https://github.com/smartystreets/goconvey/pull/88

$GOPATH/src/github.com/smartystreets/goconvey/scripts/idle.py -v

tips

  • localhost:8080/latestにアクセスするとjsonでテスト結果がとれます
  • goconveyのWeb UIはGOPATH以下のパッケージのディレクトリで起動する必要があります (例えば、$GOPATH/src/github.com/yourname/packagename)

まとめ

goconveyを簡単に紹介しました。Web UIだけでも試す価値はあると思います。

ビデオでの解説もあります。ぶっちゃけこの記事を読むより動画を見たほうが早いです。

その他参考


  1. 残念なことにemacsやvimには対応していない 

  2. ginkgoやtestifyのテストも実行できます。ただし、ginkgoのテスト結果はデフォルトだとエスケープシーケンスがそのまま表示されてしまいます 



ベイズの定理から見るガン検査

November 12, 2013 at 03:01 AM | categories: statistics |

http://www.huffingtonpost.jp/2013/11/10/cancer-test_n_4252707.html

高校生がすい臓がん発見の画期的方法を開発したという記事が話題になってます。

この検査法の改善が統計的にどういう意味をもつのか実際にベイズの定理をつかって計算してみます。

ここでは以下のような問題を考えることとします。

あるガン検査法は、被験者ががんの場合はp1の確率で陽性になり、被験者ががんでなければp2の確率で陰性になります。被験者ががん患者である確率がp3のとき、がん患者が検査の結果実際に陽性だと判定される確率を求めなさい。

Xを被検査者はガンであるという事象、Yを検査の結果が被検査者はガンであると示す事象として、それぞれ以下のように置き換えることができます。

ただし、 はBが起こったときにAが起こる確率(条件付き確率)、 はAが起こらないという事象(補事象)を表します。

求めたい確率は なので、ベイズの定理より

ここで は検査結果が真陽性となる確率と偽陰性となる確率を足したものなので、

また、

なので、

となります。

以上の結果に実際に値をあてはめてみます。

2008年のすい臓がん推定患者数は29584 1、同年の人口は127692000 2なので、p3=0.23168 * 10^-3。 また、簡単のためにp1, p2をひとまとめに誤検出の確率と仮定してp1=p2=qおくと、P(Y|X)が70%となるようなqは、q=0.99990となります。

このことから、99.99%の精度をもつ検出方法でも実際には30%も見逃してしまうということがわかります。

さらに、「400倍の精度で検査できる」という部分を誤検出の確率が400分の1になったという意味だと解釈して、 q'=1-(1-q)/400とおいてがん患者が検査の結果実際に陽性だと判定される確率を再度計算するとP(Y|X)=0.99892となります。

つまり30%見逃していたのが1%程度まで減ったということです。 これはすばらしい成果といえるのではないでしょうか。

最初は30%も見逃すとかどんなひどい検査だったんだ、などと思ってしまうかもしれませんが、上記の計算で実際はそれほど単純な話ではないことがわかると思います。

3



R Tutorial Part2 Chapter08 (Numerical Measures)

October 28, 2013 at 02:11 AM | categories: note, statistics, R |

これはR Tutorial Part2 Chapter08 (Numerical Measures) のノートです。 slideはこちら

mean, median

  • mean: 平均
  • median: 中央値、中間値。データ数が偶数個の場合は前後の2つの数の平均。
> library(MASS)
> mean(faithful$eruption)
[1] 3.487783
> median(faithful$eruption)
[1] 4

quartile, quantile, percentile

  • first quartile, lower quartile: ソートされたデータの数を1:3に分ける位置の値。 第1四分位
  • second quartile, median: 中間値
  • third quartile, upper quartile: 第3四分位
  • quantile: 変位値
  • percentile: 百分位数
> quantile(faithful$eruption)
     0%     25%     50%     75%    100% 
1.60000 2.16275 4.00000 4.45425 5.10000 
> x = sort(faithful$eruption)
> x[1+floor((length(x) - 1)/4)] + (x[1+ceiling((length(x) - 1)/4)] - x[1+floor((length(x) - 1)/4)]) * 3 / 4
[1] 2.16275
> quantile(faithful$eruption, c(.32, .57, .98))
    32%     57%     98% 
2.39524 4.13300 4.93300 

max, min, range

> max(faithful$eruption)
[1] 5.1
> min(faithful$eruption)
[1] 1.6
> max(faithful$eruption) - min(faithful$eruption)
[1] 3.5

interquartile range

  • interquartile range: 四分位範囲, upper quartile - lower quartile
> IQR(faithful$eruption)
[1] 2.2915
> x = quantile(faithful$eruption)
> x[4] - x[2]
   75% 
2.2915 

box plot

  • boxplot: 箱ひげ図
> boxplot(faithful$eruption, horizontal=TRUE)

boxplot

※ 箱のなかの線はmedian

variance, standard deviation

  • variance: 分散。Rのvar関数は不偏分散
  • standard deviation: 標準偏差
> var(faithful$eruption)
[1] 1.302728
> sd(faithful$eruption)
[1] 1.141371

> var2 <- function(x) { sum((x - mean(x)) ^ 2) / length(x) }   # 普通の分散
> var2(faithful$eruption)
[1] 1.297939

covariance, correlation coefficient

  • covariance: 共分散。2 組の対応するデータ間での、平均からの偏差の積の平均値。
  • correlation coefficient: 相関係数。共分散をそれぞれのデータの標準偏差の積で割ったもの。
> cov(faithful$eruption, faithful$waiting)
[1] 13.97781
> cor(faithful$eruption, faithful$waiting)
[1] 0.9008112

correlation coefficientが1に近いほど正の相関があるといえる

e1071

Functions for latent class analysis, short time Fourier transform, fuzzy clustering, support vector machines, shortest path computation, bagged clustering, naive Bayes classifier

> install.packages('e1071')

http://cran.r-project.org/web/packages/e1071/index.html

central moment

  • central moment: 中心積率。標本分散は2次のcentral moment
> library(e1071)
> moment(faithful$eruption, order=3, center=TRUE)
[1] -0.6149059

skewness, kurtosis

  • skewness: 歪度。対象性の度合いの指標。一般に、skewness < 0 ならばmean < median でそのデータの分散はleft skewed という。skewness > 0 ならばmean > median でright skewed という。
  • kurtosis: 尖度。分布の尖り具合の指標。kurtosis < 0 ならフラットな分布になりplatykurtic(緩尖な)という。kurtosis > 0ならとがった分布になりleptokurticという。正規分布の場合は0になりmesokurticという。
> skewness(faithful$eruption)
[1] -0.4135498
> kurtosis(faithful$eruption)
[1] -1.511605

misc

  • この項は統計でよくつかう関数のまとめになってます
  • 各関数の詳細はhelpを参照


reveal.js をつかってブログ記事からスライドを生成する

October 18, 2013 at 10:00 PM | categories: blog, reveal.js, blogofile |

はじめに

これは以下のような人を対象にしたポストです

  • スライドをmarkdownでつくりたい
  • ブログはmarkdownでかいている
  • ずぼらするためには努力を惜しまない

デモ

とりあえず以下のスライドをみてください。

reveal.jsとは

HTMLでかけるプレゼンツールです。詳細は以下等を参照してください。

static CMS

説明は省略します。このブログはblogofileでできていますが、jekyllやhakyllのようなものでもほぼ同等なことができます。

やり方

reveal.jsのmarkdown埋め込み機能をつかうだけです。reveal.jsのREADMEを読むとめんどうなように見えますが、 revealjs.mako のようにテンプレートを書くだけ。とはいえ多少のコーディングが必要です。

詳細は以下のソースをみてください。

code highlight

コードハイライトつかえます。

#include <stdio.h>

// highlight test

int main(int argc, char *argv[]) {
    printf("hello, world!\n");
    return 0;
}

fragment

fragmentもつかえます。

... to step through ...

  1. any type
  2. of view
  3. fragments

長所

  • ブログ書くついてでにスライドもできる
  • スライドの共有が簡単
  • パワポ不要
  • さりげなくギークっぽさがアピールできる

短所

  • ブログとスライドのそれぞれの完成度を両立した記事にまとめるのは難しい
  • 多少はhtmlを書く必要があるときもある

まとめ

  • blogofileにreveal.jsを組み込んだ話を紹介しました
  • reveal.jsかっこいいです


オーバーフローしにくい組み合わせの数の計算方法

October 17, 2013 at 09:13 PM | categories: algorithms, programming |

Cで組み合わせの数を計算するときに定義通り計算するとすぐにオーバーフローしてしまう。 例えば以下のような実装だと、 程度でも結果がおかしくなってしまう。

#include <iostream>

using namespace std;

uint64_t fac(uint64_t n) {
    if (n > 1)
        return n * fac(n-1);
    else
        return 1;
}

uint64_t combinations(uint64_t n, uint64_t k) {
    return fac(n) / (fac(k) * fac(n-k));
}

int main(int argc, char *argv[]) {
    cout << combinations(5, 3) << endl; // => 10
    cout << combinations(10, 5) << endl; // => 252
    cout << combinations(20, 10) << endl; // => 184756
    cout << combinations(30, 15) << endl; // => 0 !?
    return 0;
}

とりあえず素因数分解してやれば解決するのでいままでそうしてたのだけど、もっとかっこいい方法がないものかと思って探してみたらKnuth先生の本で以下のようなアルゴリズムが紹介されているらしい。1 これはかっこいい。

uint64_t combinations2(uint64_t n, uint64_t k) {
    uint64_t r = 1;
    for (uint64_t d = 1; d <= k; ++d) {
        r *= n--;
        r /= d;
    }
    return r;
}

int main(int argc, char *argv[]) {
    cout << combinations2(30, 15) << endl; // => 155117520
    cout << combinations2(60, 30) << endl; // => 118264581564861424

    cout << combinations2(64, 32) << endl; // これはオーバーフローする
    return 0;
}

結果の値が範囲内ならオーバーフローしないのか、というとそういうわけではないけどナイーブな実装に比べるとずっと計算できる範囲が広いので、値のレンジがあらかじめわかっているのであればこれで十分ですね。



About Me

pic
mojavy

Recent posts






Categories



Badges