mojavy.com

Goのtemplateパッケージ簡易チートシート

November 19, 2013 at 07:19 PM | categories: golang |

goに標準でついてるtemplateパッケージは便利なのだけど、マニュアルが長すぎるのでよく使う機能だけまとめておく。

そろそろだれかテンプレートエンジンを標準化してほしい。

基本

package main

import (
    "os"
    "text/template"
)

func main() {
    tmpl := "Hello, {{.template}}!"
    t := template.New("t")
    template.Must(t.Parse(tmpl))
    t.Execute(os.Stdout, map[string]string{"template": "World"})
}

ちなみに、template.Must(t.Parse(tmpl))は以下のショートカット

_, err := t.Parse(tmpl)
if err != nil {
    panic(err)
}

変数展開

通常はmapのキーかstructのメンバを.Keyのようにドット付きで指定するとでその値が展開される。 ただし、該当するキーが見つからなかった場合、mapでは<no value>という文字列が出力されるが、structではエラーになる。

type T struct {
    Name string
}

tmpl := "Hello, {{.Name}}!\n"
t := template.New("t")
template.Must(t.Parse(tmpl))

t.Execute(os.Stdout, map[string]string{"Name": "map"})
t.Execute(os.Stdout, T{Name: "struct"})
t.Execute(os.Stdout, &T{Name: "struct reference"})

.のようにドットだけを渡すと変数それ自体が展開される。

tmpl := "Hello, {{.}}!\n"
t := template.New("t")
template.Must(t.Parse(tmpl))
t.Execute(os.Stdout, "World")

関数呼び出し

関数はシェルのパイプのように連結させて呼びだせる。テンプレート内で呼ぶ関数はtemplate.FuncMapで渡す。

tmpl := `Now {{now}}, {{"hello" | toupper}}`
t := template.New("t")
t.Funcs(template.FuncMap{
    "now":     func() string { return time.Now().String() },
    "toupper": strings.ToUpper,
})
template.Must(t.Parse(tmpl))
t.Execute(os.Stdout, nil) // => Now 2013-11-19 19:17:51.378063751 +0900 JST, HELLO

ループ

組み込みのrange Actionをつかえばよい。

type T struct{ Name string }
tmpl := `
{{range .}}- {{.Name}}
{{end}}
`
t := template.New("t")
template.Must(t.Parse(tmpl))
t.Execute(os.Stdout, []T{
    {Name: "Alice"},
    {Name: "Bob"},
    {Name: "Charlie"},
    {Name: "Dave"},
})

その他、条件分岐等のActionは マニュアルのActionsの 参照

組み込み関数

こちらも マニュアルのFunctionsの項 を参照



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



About Me

pic
mojavy

Recent posts






Categories



Badges