akms道東

ITイベント,勉強会への参加記録や趣味のことが書いてあるブログです.

【 #kamakurago 】kamakura.go#1に参加してきた

2/28(土)に鎌倉のiichiさんのオフィスで開催されたkamakura.goの1回目に参加してきました。

https://instagram.com/p/zo7OBqt5Le/

会場の様子

今回の内容はもくもく会でした。
会場の様子は主催の@さんが投稿されていたようでこんな感じでした。


やったこと

指定したディレクトリの中身をすべて圧縮する機能の作成

  • 圧縮形式は.tar.gz
  • ディレクトリはフルパスで指定
  • 圧縮対象、保存先は固定

作業リポジトリはこちら

作業中のハマりポイント

ハマりの原因や解決方法についてはまた別の機会にまとめようと思います。

集中して作業が進めたので、目標としていた作業はできました。

感想

はじめてのもくもく会への参加でしたが、とても有意義な時間を過ごせました。
また鎌倉も始めて訪れたのですが街のまわりを見れば山が見えたり、電車の車窓から見る景色が自分好みだったりと感激していました。
本当に楽しい1日を過ごせました!次回があればぜひ参加したい!!

振り返りと目標 【2014-2015】

2014年の振り返り

1月~3月まで北海道、4月からは東京を拠点として生活してきました。
1月~3月までの活動については以下にざっくりまとまってます。

上京しました - akms道東

勉強会への参加

上記の最後にPerlとかRubyとかD言語の勉強会に出たいと書いていましたが、
結果としてPerlとGoの勉強会に出ることが多かったです。
PerlPerl入学式のサポーターであったり、YAPCでのLTなどを行ってきました。


YAPC::Asiaに初参加、あとLTしてきた #yapcasia - akms道東


Perl入学式を地方で開催してみたというお話 - akms道東

Goの勉強会ではとくに発表などはしていないのですが、本当に多くの勉強会に参加してきました。
勉強会で学んだおかげで公私ともにGoを活用することができています。

北海道→東京

北海道から東京へ出てやはり勉強会などが多く、
いろいろなエンジニアの方たちと交流することができました。
やはり東京は人が集まる場所だなと改めて感じました。
また北海道へ戻りたいという気持ちが薄れるかというと逆で、
むしろ北海道へ戻りたい気持ちは高まっていきました。
やはり生活面などで東京より北海道がいいなというのが正直な感想です。

2015年の目標

さて2015年ですが技術面では更なる向上というのは常に思っているのことなのですが、
改めて意識しながら1年を過ごしていきたいと思います。
今後もこのブログでいろいろ学んだことをアウトプットしていく。
その回数も増やそうと考えています。

また仕事をしていく上で感じたのが「0から1を生み出す場でのファシリテーション
というのが難しく、この部分を伸ばしていけたらなと思います。
今は漠然と難しいという経験しかないのですが、この問題についても後日まとまったときに
ブログなどでアウトプットできればなと考えています。

おわりに

今年最初の勉強会を以下のように開催します。
1月7日という急な日程ですが、参加できるかたいらっしゃいましたらぜひ!

ゆるいITべんきょうかい in 帯広 - connpass

Goでinterface{}を扱うときの忘備録:型コンバートについて

昨日(2014/12/23)同期とあつまりハッカソン的ななにかを開催したのですが、
お題もとくに決まってなかったのでhipchatのapiを使って遊んでいたので、
その中で学んだことの忘備てきななにかです。


hipchatのAPIについては上記の公式ドキュメントを見ると
様々な言語で作成された便利なライブラリなどがあります。
今回はその中で私が現在勉強しているGoのclient libraryを使ってみることにしました。


履歴の出力時に学んだこと

特定の部屋の会話履歴を最高30件分取得して、
とくに加工整形せずに出力する場合は下記のようなコードを書きます。

c := hipchat.NewClient(authToken string)
historyRq := &hipchat.HistoryRequest{MaxResults: 30}
  history, _, err := c.Room.History(room_name string, historyRq)
  if err != nil {
    log.Fatal(err)
  }
  for _, item := range history.Items {
    fmt.Println(item)
  }

そのままの内容を載せることはできないので加工してありますが出力結果はこんな感じ

{2014-12-23Thh:mm:ss.0123456+00:00 map[id:012345 links:map[self:https://api.hipchat.com/v2/user/012345] mention_name:test name:TestUser] abcdefg-1234567-a12b3c4d [] テスト  message}
{2014-12-23Thh:mm:ss.0123456+00:00 map[id:012345 links:map[self:https://api.hipchat.com/v2/user/012345] mention_name:test name:TestUser] abcdefg-1234567-a12b3c4d [] テストテスト  message}

これはhistory.Itemsからmessage構造体の配列を受け取り
各message構造体の要素を出力しています。要素の詳細は下記リンク参照
hipchat - GoDoc

とにかく分かり難い。履歴の中でほしい情報は発言者の名前とその内容。
他には時間くらいだと思います。
そこで加工整形して出力するようにしたところ発言内容はitem.Messageとして簡単に取り出せました。
ただし発言者の名前の要素がmessage構造体のFromにあり
Fromの型がinterface{}型という問題にぶち当たり、思うままに結果を取り出せませんでした。
以下のようにしても発言者の名前は取り出せず。。。

for _, item := range history.Items {
   fmt.Printf("%s :%s",item["name"],item.message)
  }

型のコンバート

そこでいろいろ調べたところinterface{}の型を
コンバートするとnameを取り出せるところにたどり着きました。

map[id:012345 links:map[self:https://api.hipchat.com/v2/user/012345] mention_name:test name:TestUser]

上記は先ほどの出力からFromの部分のみを抜き出したもの
コンバートするために最初はmap[string]stringかなと思い下記のようにして実行しました。

  from := item.From.(map[string]string)

しかし、正しく動作せずに出力されたエラーにはmap[string]interface{}の文字が。
どうやらFromはmap[string]interface{}にコンバートできるようでした。
そこで下記のようにしたところ実際に動作しました。

  from := item.From.(map[string]interface{})

Fromの形式が様々問題

しかしこれで全てが解決したわけではありませんでした。
なんとFromのコンバートができないitemが存在しました。
詳しく調べたわけではないのですがおそらくbotからのpostの場合は
Fromにある情報がnameだけのようでした。
そこでコンバートを実行した場合に成功の可否を受け取ることができたので、
下記のように実装しました。

 for _, item := range history.Items {
    var from map[string]interface{}
    var ok bool
    if from,ok = item.From.(map[string]interface{}); ok {
      fmt.Printf("%s :%s\n",from["name"],item.Message)
    }else{
      fmt.Printf("%s :%s\n",message.From,item.Message)
    }
  }

これにより出力結果は「発言者の名前:発言内容」というようになりました。

以上ざっくり自分メモと素振りの成果。

Perl入学式を地方で開催してみたというお話

はじめに

この記事はPerl入学式アドベントカレンダー20日目の記事です。
Perl入学式ではたまにサポータをやっております。タケウチです。

現在は東京、大阪、福岡の3都府県で開催されているPerl入学式の歴史についてはpapix校長が下記リンク先で綴っております。
2014年12月02日 : Perl入学式 公式ブログ
2014年12月09日 : Perl入学式 公式ブログ
2014年12月18日 : Perl入学式 公式ブログ
ですが、おそらくこの歴史の中で出て来ることはないであろう、簡易出張版Perl入学式in釧路について
今回は書いていきたいと思います。

田舎でPerl入学式

そもそもpapix校長とは現在の会社の内定者時代に知り合いそこでPerl入学式というものを知り、
当時のwebサイトを見たりしていました。
そこでは以前からPerl入学式で使用している資料が公開されていて、勉強には絶好の題材でした。

最初は独学で学んでいたのですが、ちょうどその頃私が参加していたITコミュニティで言語を一つ勉強したいという話があがっていました。そこで私はPerl入学式の資料を使ってみんなで勉強するチャンスだと思い早速提案しました。
もちろんpapix校長に資料の使用について確認をしてから使用しました。

そこからPerl入学式の資料を使わせていただきながらの勉強会を3、4回ほど開催したころ、
papix校長を北海道に呼ぼう計画が私のなかでふと、起こり本人に打診、実際に校長来道ということになりました。

勉強会では簡易出張版Perl入学式としてAPIクライアントの開発というテーマで開催することができました。
下記はpapix校長の開催感想ブログです。
釧路で「Perl入学式出張版」をやってきた - Masteries

さてここまで書いてきましたが、言いたかったことは一つ。
東京、大阪、福岡だけでなく北海道の片田舎でもPerl入学式は開催できました!
せっかくPerl入学式の素晴らしい資料が公開されているので、もちろん参加した人が復習などに使うのはもちろんですが、既存の入学式に参加するのが地理的に困難な人たちが集まって、自分たちで開催することは可能です!

また声を上げれば校長がやってくる!?
そして簡易版が開催できる!?

ということで以上で今日の記事はここまでです。
明日はぼくの尊敬する先輩の担当ということでとても楽しみです!
それではまたPerl入学式で楽しく学びましょう!

Goでテストを実行する時の備忘録

Goでテストを回すには

最近Goで実装するものがあった。そこでテストを回すときの自分メモ兼今日の素振りの成果
とりあえず下記公式のページでTestingの箇所を見れば大まかにわかる
How to Write Go Code - The Go Programming Language

公式ページではリモートリポジトリに対するテストもやっているが今回はローカルに対してのみ
例としては以下のようなパッケージ構成を想定する

fizzbuzz
 |-- fizzbuzz.go
 |-- fizzbuzz_test.go

またfizzbuzz_test.goの内容は以下のように想定

package fizzbuzz
import(
    "testing"
)
func TestFizz(t *testing.T){
...
}
func TestBuzz(t *testing.T){
...
}

作成しているパッケージ内でまるっとテストを回すときは以下のようにする

> go test
  PASS
  ok      fizzbuzz 123.456s

テストを1つずつ結果を見ながらすすめる

> go test -v
  === RUN TestFizz
  --- PASS: TestFizz (xxx.xx seconds)
  === RUN TestBuzz
  --- PASS: TestBuzz (xxx.xx seconds)
  PASS
  ok       command-line-arguments xxx.xxxs

その他の実行方法

複数ファイルの場合

次の例として以下のように細かくファイルが分かれている場合

fizzbuzz
 |-- fizz.go
 |-- fizz_test.go
 |-- buzz.go
 |-- buzz_test.go

対象ファイルを指定して実行

> go test fizz.go fizz_test.go

自分がやってしまったミス

> go test fizz_test.go

上記の場合テストは以下のようにテストを実装する必要がある。ただしこのテストはどうなんだろう

package fizzbuzz
import(
    "testing"
    "fizzbuzz"
)
func TestFizz(t *testing.T) {
    fizzbuzz.Fizz()
    ...
}

パッケージが階層でわかれている場合

fizzbuzz
  |--fizz
  |   |-- fizz.go
  |   |-- fizz_test.go
  |-- buzz.go
  |-- buzz_test.go

以下のようにすると再帰的にテストを実行する

> go test ./...

Makefileを作成してある場合

Makefileを作成してテストについて記述しておくと以下のようにも実行できる

> make test

以上ざっくり自分メモと今日の素振りの成果。

YAPC::Asiaに初参加、あとLTしてきた #yapcasia

今更ですが8月29、30日の2日間開催されていたYAPC::Asiaに初めて参加してきまた。またLTしてきました。

1日目は参加することができなかったので、2日目からの参加でした。

当日は午前中から会場にいたのですがとても緊張していたので発表を聴きにいってもあまり頭に入ってきませんでした。
なので公開されている発表動画で復習してます。

以下に当日行ったLTのスライド載せておきます。
すぐ緊張するたちで、さらに会場は満員状態。
伝えたいことがちゃんとみなさんに伝わったか不安だったのですが、感想などをいただくと概ね伝わったかなと思いました。


最後になりましたが、運営スタッフのみなさまへYAPC初参加でしたがとても楽しかったです。ありがとうございました!

WordCount実装でGolang入門

久しぶりの更新は技術ネタです。

Golangはじめました

ちょうど勉強会でGolangの話を聴いて興味がわいたので触ってみた。
まずA Tour of Goというブラウザだけで学習できるチュートリアルから始めてみた。
その中で41ページ目(この表現であってるか微妙だが)にある、WordCount関数の実装問題がGolangの実装の入門にちょうど良いなと思った。

WordCount関数
func WordCount(s string) map[string]int {
    return map[string]int{"x": 1}
}

これがWordCount関数の初期状態。引数は文字列1つ。
キーが文字列で要素が数値のmapが返り値となっている。

とりあえず実装

下記はこの実装問題にたどり着くまでに行った演習と問題ページにあるヒントから単純に書いた回答。
これでも問題なく動作する。

func WordCount(s string) map[string]int {
    str := strings.Fields(s)
    m := make(map[string]int)
    for i := range str { 
      m[str[i]] += 1
    }
    return m
}

Golangでは『var hoge string = "fuga"』のように
var宣言、変数名、型、初期化子というように変数を宣言する。
また関数内では以下のように『:=』でvarの代わりに暗黙的な型宣言で代入ができる。
関数内だしvar宣言して書かなくていいならこっち使おうという安直な考えで記述。

str := strings.Fields(s)
m := make(map[string]int)

Golangでは繰り返し文はforのみ。
条件はwhileのような書き方もできる。また条件を指定しないと無限ループになる。
また今回のようにrangeを使うことで変数のインデックス分繰り返すといった処理ができる。
ここでも『:=』で代入。そしてループが終了するとmを返す。

for i := range str {
  m[str[i]] += 1
}
return m
リファクタリング

一度はこれで良いかと思ったが、動けば良いというものでは全く勉強にならない。
そこで改めて自分のコードを書き直してみた。

まず初めにword_mapというキーが文字列で要素が数値のmapを返すことを明示した。

func WordCount(s string) (word_map map[string]int) {

次に『:=』では『strings.Fields(s)』が何を返すのかリファレンスを見なければ確認できなかった。
そこで一目で分かるようにvar宣言、変数名、型、初期化子という形で記述した。

var str []string = strings.Fields(s)

rangeを使うと実は変数からインデックスと値の両方が返ってくる。
今回は処理的にインデックスは不要だった。
そこで『_』に代入することでインデックスを破棄し、値のみをループの中で使用した。
最後にreturnだけで終了してるが、前述の通りword_mapという
キーが文字列で要素が数値のmapを返すことを明示しているのでこの一行で終了することができる。

for _,key := range str {
   word_map[key] += 1
}
return 

以下はここまで説明したものを一つにまとめたものである。
一番最初に提示した回答例と違い、処理内容が初見でも理解しやすくなっていると思う。

func WordCount(s string) (word_map map[string]int) {
    var str []string = strings.Fields(s)
    word_map = make(map[string]int)
    for _,key := range str {
        word_map[key] += 1
    }
    return 
}

こうして一つ一つを理解していくなかでとくに『_』を使ったインデックスの破棄や、
最初に変数名と型を宣言しておくことで『return』と書くだけでその値が返ることなど面白いなと感じた。

今後の学習予定

とりあえずA Tour of Goを完了させる。
また今週末から来週にかけてGolangの勉強会に3回ほど参加する予定なのでとても楽しみだ。