Team Geek読んだ

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

Team Geek ―Googleのギークたちはいかにしてチームを作るのか

ずっと読もうと思っていたんだけど,勝手にチーム開発に関する本だと思っていて,後回しにしていた.エンジニア同士で人間関係に悩んだ時にはHRT(謙虚・尊敬・信頼)を大切にしてコミュニケーションしろということが中心に書かれているのはよく言われていて,それだけで読んだ気になってたんだけど想像以上に有益だった.

実際に読んでみると,もちろんチーム開発に関する要素もあるのだけど,それよりも1人のエンジニアとして会社でどう生きるのかみたいな話のほうが印象に残った.

個人的には,自分をよく見せようという個人のエゴをやめて,集団のエゴ(チームの功績.グループの誇り)を考えるようにすると良いという話がためになった.社内の政治についてもいろいろ書かれてたのが好印象だった.

エンジニアは実力勝負の世界ではあるのだけど,他の人とのコミュニケーションを通した自分の価値の高めることの重要さがわかる.

薄くて早く読めるし,エンジニアなら1度は読んでみる価値はあるはず.

Ruboty Slack 入れ方

Rubyで開発されたbotにRubotyというものがある

このRubotyをHerokuで動かしてSlackで使う方法について詳しく書く

1. Slackでチームをつくる

2. XMPPを許可する

RubotyはXMPP通信を用いている.設定は,ここでできる(/admin/settings)

f:id:tsuwatch:20140911152452p:plain

3. bot用アカウントをつくる

4. RubotyをHerokuで動かす

XMPP用のパスワードは,各アカウントごとにここにある(/account/gateways)

$ mkdir mybot
$ cd mybot
$ echo 'source "https://rubygems.org"' >> Gemfile
$ echo 'gem "ruboty"'                  >> Gemfile
$ echo 'gem "ruboty-slack"'            >> Gemfile
$ echo 'bot: bundle exec ruboty'       >> Procfile
$ bundle install
$ git init
$ git add .
$ git commit -m "Initial commit"
$ heroku create
$ git push heroku master
$ heroku scale bot=1
$ heroku config:set ROBOT_NAME=mybot SLACK_TEAM=tsuwatch SLACK_USERNAME=mybot SLACK_ROOM=general SLACK_PASSWORD=XXX

5. 動作確認

f:id:tsuwatch:20140911153916p:plain

6. Redis導入

このままだとRubotyが再起動するごとにruboty-cronなどの情報は失われてしまう.そこでRedisを入れることで永続化することができる.

Redisには無料で使えるこれを使った.

そして,URLを設定する

heroku config:set REDIS_URL=redis://Resource Name:Redis Password@example.com:6379

【参考】

A Tour of Go - 第2回 dwanGo

2回目.

package main

import "fmt"

// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    x, y := 0, 1
    return func() int {
        x, y = y, x+y
        return x
    }
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}
package main

import "fmt"
import "math/cmplx"

func Cbrt(x complex128) complex128 {
    z, z_prev := complex128(2), complex128(0)
    for ; cmplx.Abs(z-z_prev) > 1e-10; {
        z_prev = z
      z = z - (cmplx.Pow(z, 3) - x) / (3*(z*z))
    }
    return z
}

func main() {
    fmt.Println(Cbrt(2))
    fmt.Println(cmplx.Pow(Cbrt(2),3))
}

56

package main

import (
    "fmt"
    "math"
)

type ErrNegativeSqrt float64

func (e ErrNegativeSqrt) Error() string {
    return fmt.Sprintf("cannot Sqrt negative number: %f", e)
}

func Sqrt(f float64) (float64, error) {
    if f < 0 {
        return 0, ErrNegativeSqrt(f)
    }
    z := 2.
    for i := 0; i < 10; i++ {
        z = z - (math.Pow(z, 2) - f) / (2 * z)
    }
    return z, nil
}

func main() {
    fmt.Println(Sqrt(2))
    fmt.Println(Sqrt(-2))
}

58

package main

import (
    "net/http"
)

type String string

type Struct struct {
    Greeting string
    Punct string
    Who string
}

func (s String) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, s)
}

func (s Struct) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, s.Greeting, s.Punct, s.Who)
}

func main() {
    http.Handle("/string", String("I'm a frayed knot."))
    http.Handle("/struct", &Struct{"Hello", ":", "Gophers!"})
    
    http.ListenAndServe("localhost:4000", nil)
}

60

package main

import (
    "code.google.com/p/go-tour/pic"
    "image"
    "image/color"
)

type Image struct{
    Width int
    Height int
}

func (img *Image) ColorModel() color.Model {
    return color.RGBAModel
}

func (img *Image) Bounds() image.Rectangle {
    return image.Rect(0, 0, img.Width, img.Height)
}

func (img *Image) At(x, y int) color.Color {
    return color.RGBA{uint8(x*y), uint8(y-x), 255, 255}
}

func main() {
    m := &Image{100, 100}
    pic.ShowImage(m)
}

61

package main

import (
    "io"
    "os"
    "strings"
)

type rot13Reader struct {
    r io.Reader
}

func (rot *rot13Reader) Read (p []byte) (n int, err error) {
    n, err = rot.r.Read(p)
    for i := range p {
        if ('A' <= p[i] && p[i] <= 'M') || ('a' <= p[i] && p[i] <= 'm') {
            p[i] += 13
        } else if ('N' <= p[i] && p[i] <= 'Z') || ('n' <= p[i] && p[i] <= 'z') {
            p[i] -= 13
        }
    }
    return
}
    

func main() {
    s := strings.NewReader(
        "Lbh penpxrq gur pbqr!")
    r := rot13Reader{s}
    io.Copy(os.Stdout, &r)
}