うまくいかなかった改善サポートとうまくいかなかったモブワーク #agileradio

アジャイルラジオの後半が公開されましたー!(∩´∀`)∩ワーイ

agileradio.github.io

聞いてくれたら喜びます。感想とかを #agileradio タグをつけてつぶやいてくれたらさらに喜びます!ポッドキャストもあります。

## 話題はこんな感じかなー?

  • 楽天の大阪支社のオフィスツアー
  • 振り返りから形作るスクラム
  • うまくいかなかった改善サポート
  • うまくいったモブワークとうまくいかなかったモブワーク
  • バラバラに作業すると速いのかな?
  • スクラムフェス大阪

楽しかった!

## 楽天大阪支社の様子

↓オープンスペースはこんな感じ

f:id:bufferings:20181211063231j:plain:w600

↓僕が集中してコード書きたいときはここで書いてる。たぐさんが手で「こういう部分がいいよね」って言ってたのはこの椅子の顔の横のところのことですw

f:id:bufferings:20181211063259j:plain:w600

↓写真はこちらのものを使用しました。噂の茶色のホワイトボード?の写真もあります。

www.wantedly.com

## Scrum Fest Osaka 2019

楽天もゴールドスポンサーやらせてもらうことになったスクラムフェスはこちら:

www.scrumosaka.org

セッションはRSGTと同様に公募形式です。一覧はこちらから:

https://confengine.com/scrum-fest-osaka-2019/proposals

まだ募集期間なので、ぜひみんなで応募して盛り上げていきましょうー!

僕も2つ出してるので聞いてみたいなと思ってくれた方は投票お願いします!ハートマークをポチッと。

↓こっちがRSGTと同じ内容で、これまでこういう部分で実際につまづいて・前進してきたよ、のお話で

confengine.com

↓こっちはもうちょっと具体的に僕がどうやってスクラムをやってるかのお話。

confengine.com

他にも沢山面白そうなプロポーザルが出てるから「聞いてみたいなー」と思ったやつに投票してね!

## 前半の話はこちら

bufferings.hatenablog.com

## ありがとー!

アジャイルラジオのスタッフのみなさんありがとうございました!楽しかったです!

マッタネー(๑•̀ㅂ•́)ノシ

Disposable Solutionハッカソンと後輩たちの普段とは違う顔

後輩主催の社内ハッカソンが楽しかった。

## 大阪ハッカソンやろうよ

楽天テクノロジーカンファレンス大阪のスタッフをやってた後輩が10月末のうちあげで「大阪支社で部署を超えてハッカソンをやったら面白そうだと思ってるんですよねぇ」っていうので「ふーん。じゃ、来月でいいかね。3人くらい『ハッカソンを開催したい!』と強く思う人を来週中に集めたらできるよ。僕はメインスタッフというよりは、サポートという感じで関わろうかな」って話をしてたのが、先週開催された。想像以上に面白かった。

ここは @yohhatu メソッド。僕「よーさん、また今度飲みにいきましょうよ」yohhatu「ええなー、来週いつあいてるの?」。

## 目的

「最近は大阪支社の開発部も100人を超えてるし部署も分かれてるから技術的な交流が少ない。色んなスキルを持ったメンバーがいるのにもったいない。そういう場を作りたい」というのが彼のアイデアで、僕は単に「お、それいいね」って言ってた。

ここは @bangucs メソッド。「こういうことやりたいんですよね」って話があると、僕は結構(あれやらなきゃ、これもやらなきゃ、色々大変だなー)って思っちゃうんだけど、bangucsはいつも「それ、面白そうっすね。やりましょう」って言うの。

## Disposable Solution

そこに僕からは「普段の仕事の役に立たないものにしよう」って意見を出したら同意してくれて、数日後に彼がスローガンを持ってきた。「Disposable Solution」。サイコーやね。

サービスエンジニアとサービス開発と3年後 - Mitsuyuki.Shiiba でも書いたけど、僕らは普段「サービス」のことを常に考えて仕事をしてるから、たまにはそういうのを全部忘れて技術的に面白そうなことやろうよ、って意図。

  • ハッカソンが終わった後に誰も未練なく捨てられるソリューションにする
    • 普段自分たちが見てるサービスの役に立ちそうなことは一切やらない
    • 普段の開発だと触らなさそうな技術を利用する

## ざっくり流れ

今回のハッカソンのお題が何かある方が作りやすくていいね、ってなって、じゃ「Integration」にしようと思う。って言うので「いいね!」ってなって。

くじ引きで、いつも一緒に仕事をしている人が同じチームにならないように編成して。

11月の中旬にアイデアソンを開催。半日くらい。帰り際に会った参加者に「どうだった?」って聞いたら「なんの役にもたたないソリューションを出しまくったわー」って笑ってた。

で、12月の頭に1 Dayハッカソンを開催。部署を超えて色々スキル交換してるのが見てて面白かった。

僕「ユニットテスト書いた?ニヤニヤ」みんな「かいてねーわwww」

## 発表

マネージャが「この人、ズル休みしてない?」って聞いたらSNSとかの色々なIntegrationを利用してズル休みの確率を教えてくれる動物を作ってるチームや、アプリをインストールして設定しておいたらGPSとかで自動で遅刻しそうかどうかを判別して「すみません、走って行こうとしてたら思ったより体力がなくなってて遅刻します」って色んなアホな言い訳をつけて連絡を送ってくれるアプリを作ってるチームや、ピタゴラ装置みたいに色んなアプリを無駄にインテグレーションしてアプリをデプロイする装置を作ってたチームがいたりして、ほんとどれもくだらなくて面白かった。

主催者チームはハッカソンには参加してなかったんだけど、彼らは彼らで「採点アプリ」を作って楽しんでたみたいw。

## 気をつけてたこと

僕が気をつけてたのは「意見を否定せずに、できる方法を考える」というところと「怒られるかもなぁって思うことは、僕が引き受けること」くらい。「マネージャたちもメンバーのそういうチャレンジをとても良いことだと考えている」と信頼してるのでそんなに難しくない。

ちょこちょこ怒られるかもなぁと思うところはあったけど、後輩たちが普段とは違う顔を見せてくれたので満足。またやろう。

「エンジニアリングマネージャは必要か?」

昨日はコレに行ってきた。というか、主催側の一人かな。

devlove-kansai.doorkeeper.jp

そのダイアログの前にトイレに行ってたら話す場所がなくなっちゃったから相手してーって @yohhatu のところに行って二人で立ち話をしてた。

「じゃ、ちょっと深掘りしてみる?」みたいな感じで「エンジニアリングマネージャは必要か?」を考えてみようよってなった。

その結果としての僕の考えを書いておく。あとでエンジニアリングマネージャ関係のコミュニティを色々見てみようと思う。色々既に議論されてると思うので。

## 「エンジニアリングマネージャは必要か?」の僕の答え

必要だと思う。

理由は?ってことだけど、その前に僕が必要だと思うマネージャロールを書いておく。

## プロジェクトをやるときのマネージャ

僕はこの4つのマネージャロールがあるよなーって思った。

  • プロダクトマネージャ
  • ディレクター
  • デベロップメントマネージャ
  • プロジェクトマネージャ

### プロダクトマネージャ

プロダクトの方向性を決める人。

### ディレクター

UXとかデザインを決める人。

### デベロップメントマネージャ

技術的なことを決める人。

### プロジェクトマネージャ

プロジェクトの面倒を見る人。

## プロジェクトの外のマネージャ

として、メンバーの育成やキャリアパスの相談とかそういう人の成長のマネージャもいる。これは僕のいる会社ではジェネラルなマネージャと呼ばれてたりする。

## エンジニアリングマネージャはどこ?

って考えたときに。上記のマネージャの中で「今の組織に足りてない部分のマネージメントをやってる人」なんじゃないかなーって思った。

例えば、プロジェクトマネージャをやる人がいないチームで、デベロップメントマネージャがその部分もやってる、みたいな状態。

ふわっと色々やってるけど、僕って何のマネージャだっけ・・・?みたいな気持ちになってるところに「エンジニアリングマネージャ」って言葉が出てきて「あー!それかもー」ってなってるのかなぁって。

ということで、組織の形に合わせて今足りない部分を補いつつ複数のロールを担っている人、のことをエンジニアリングマネージャと呼んでいるのではないかと思った。ので、そういう人は必要だよなー、というかそういう人がいないと何も動かないよなー。って思ったのだった。

サービスエンジニアとサービス開発と3年後

最近何人かからキャリアパスの相談を受けてて、話をしているうちに自分の考えが少し整理できた気がするので忘れる前にメモ。雑記。

## サービスエンジニア

僕の今いる部署に求められてるエンジニアは、技術をコアにしたエンジニアじゃなくて、サービスをコアにしたエンジニアだと思ってる。図の左側。技術を突き詰めて「この技術で何ができるか」というよりも、サービスのことを考えて「このサービスのためにあの技術が使えないか」という感じ。

f:id:bufferings:20181205074057p:plain

## アプリ開発とサービス開発

Webアプリの開発経験が10年以上あります、って人よりも、新卒の2,3年目の人の方が頼りになったりして、どういうところなんだろうなぁ?って思ってたんだけど。アプリ開発スキル、と、サービス開発スキル、が別のスキルってことなのかもしれない。

サービスを開発するときは、アプリの機能を実装するだけじゃなくて、全体のアーキテクチャ、インフラ、ビジネス側の運用、開発側の運用、カスタマーサポートどうするか、社外との連携どうするか、モニタリングどうするか、とか全部含めて考える。それに、そもそもふわっとした要望を元に生み出していくし。正解がないから失敗することを受け入れて前進するしかない。

ので、経験が長くてもアプリ開発だけをやってきた人はサービス開発のスキルがあんまりないし、新卒2,3年目でもサービスを任されてるエンジニアはアプリ開発のスキルが低くてもサービス開発のスキルが身につき始めてる。そして、サービスのことを話すときには、サービス開発スキルがある方が頼りになる。ということなのかなと。

前者の場合も別に悲しむ必要はなくて、むしろ土台がしっかりしてるので、そこを軸足にしてサービス開発スキルに目を向けていけば成長速度は速いと思う。

## エンジニア出身マネージャ

もし、エンジニアの経験を活かしたマネージャになりたかったら、アプリ開発スキルよりも、サービス開発スキルの方が重要になってくるのかなと思った。Java 12でどんな機能が追加されるかまでは知らなくていいけど、サービス全体を見てポイントを押さえる方がメインになりそう。そこに自分の強みを持って、マネージメントのスキルを広げていけば良いのかなと。

## シニアエンジニア

もし、シニアエンジニアになりたかったら、アプリ開発とサービス開発の両方のスキルをのばしていけば良さそう。Java 12の機能は知ってる方がいい。僕はこっち。

## 3年後にはチームを離れるつもりで

とまぁ、キャリアパスのことをぼんやり考えるときには、「3年後には今のチームを離れるつもりで動いた方がいい」と思ってる(「3年は我慢しろ」という意味ではない。我慢するくらいならすぐ異動していいと思う)。その後は好きな領域にFA宣言でもしたらいいかなと。

「そうすると、残された時間はあと2年だよね?」「このチームで学べることがいっぱいあるって言ってたけど、あと2年でFAしようと思うと、あと2,3ヶ月中にはこれくらいは身につけておきたいよね?」みたいなの。それに加えて、そういうつもりで仕事をしてると、時間を無駄にできないし、ドキュメントを残したりナレッジ共有をしたり、後継者を育てることの優先度があがるから、強いチームになるなって。

あと、マネージャもそのつもりでいると、より魅力的なチーム作りをするようになるかなぁと思ったりするけど、それはまた別の話。

今日もいちにちがんばろー(๑•̀ㅂ•́)و✧

怖くないR2DBC その3 spring-data-r2dbc

怖くないR2DBCシリーズ。

bufferings.hatenablog.com

前回までで、この3つを見てきた。

r2dbc-spiがインターフェースで、r2dbc-postgresqlがそのPostgreSQL用実装。r2dbc-clientはr2dbc-spiを使いやすくするためのクライアントライブラリー。という感じだった。

f:id:bufferings:20181118081104p:plain

今日はもうひとつのクライアントライブラリーであるspring-data-r2dbcについて見てみる。

## spring-data-r2dbc?

r2dbc-clientはSpringには依存せずに便利機能を提供してたけど、spring-data-r2dbcはSpringを利用して便利機能を提供するクライアントライブラリーなんだろうなー。

github.com

## ORMじゃないよ

spring-data-r2dbcはORMになろうとはしてない。リアクティブなRDBアクセス用の組み立てキットみたいな感じ。好きなように必要に応じて組み立てることができるようなの。

じゃ、見ていこう。

## DatabaseClient

その中心になってるのはDatabaseClientクラス。こんな風にしてインスタンスを取得する。この前作ったgetPostgresqlConnectionFactory()をそのまま利用しといた:

  DatabaseClient getDatabaseClient() {
    return DatabaseClient.create(getPostgresqlConnectionFactory());
  }

  private PostgresqlConnectionFactory getPostgresqlConnectionFactory() {
    var configuration = PostgresqlConnectionConfiguration.builder()
        .host("localhost")
        .database("postgres")
        .username("postgres")
        .password("mysecretpassword")
        .build();
    return new PostgresqlConnectionFactory(configuration);
  }

で、このDatabaseClientクラスを使って色々やる。

## Generic SQL

まずはGeneric SQLから。汎用的な用途ってことかな。こんな風に書ける。

  private Mono<Integer> genericInsert() {
    var db = getDatabaseClient();
    Mono<Integer> count = db.execute()
        .sql("INSERT INTO weather (city, temp_lo, temp_hi) VALUES($1, $2, $3)")
        .bind("$1", "Osaka")
        .bind("$2", 5)
        .bind("$3", 18)
        .fetch()
        .rowsUpdated();
    return count;
  }

fetch()で実行。rowsUpdated()で結果を取得ってことかな。fetch()の戻り値の型はFetchSpec<Map<String, Object>>になってて、このFetchSpecインターフェースはこんな感じ。面白いなー。

public interface FetchSpec<T> {
    Mono<T> one();
    Mono<T> first();
    Flux<T> all();
    Mono<Integer> rowsUpdated();
}

Selectはこんな風に書けて:

  private Flux<Map<String, Object>> genericSelect1() {
    var db = getDatabaseClient();
    Flux<Map<String, Object>> result = db.execute()
        .sql("SELECT city FROM weather")
        .fetch()
        .all();
    return result;
  }

結果をごにょごにょしたい場合はfetch()の代わりにexchange()を使って、こうするってことなのかな?

  private Flux<String> genericSelect2() {
    var db = getDatabaseClient();
    Flux<String> result = db.execute()
        .sql("SELECT city FROM weather")
        .exchange()
        .flatMapMany(it -> it.extract((r, md) -> r.get(0, String.class)).all());
    return result;
  }

ふむふむ。もうちょっとちゃんとJavadocとかソースを読んだほうが良さそう。

## Insert

今度はGenericじゃないやつ。

  private Flux<String> insert() {
    var db = getDatabaseClient();
    Flux<String> cities = db.insert()
        .into("weather")
        .value("city", "Osaka2")
        .value("temp_lo", 10)
        .value("temp_hi", 13)
        .exchange()
        .flatMapMany(it -> it.extract((r, md) ->
            "city:" + r.get("city", String.class) +
                " temp_lo:" + r.get("temp_lo", Integer.class)).all());
    return cities;
  }

ふーむ。こっちの方がGenericのよりは読みやすいかね。

クラスを使うこともできる。ふーん。

  private Flux<String> insertWithDto() {
    Weather weather = Weather.create("Kyoto", 1, 30);
    var db = getDatabaseClient();
    Flux<String> cities = db.insert()
        .into(Weather.class)
        .using(weather)
        .exchange()
        .flatMapMany(it -> it.extract((r, md) ->
            "city:" + r.get("city", String.class)).all());
    return cities;
  }

  @Table("weather")
  private static class Weather {

    static Weather create(String city, Integer tempLo, Integer tempHi) {
      Weather weather = new Weather();
      weather.city = city;
      weather.tempLo = tempLo;
      weather.tempHi = tempHi;
      return weather;
    }

    public String city;
    @Column("temp_lo")
    public Integer tempLo;
    @Column("temp_hi")
    public Integer tempHi;
  }

## Select

Selectもこんな感じか。

  private Flux<Map<String, Object>> select1() {
    var db = getDatabaseClient();
    Flux<Map<String, Object>> rows = db.select()
        .from("weather")
        .orderBy(Sort.by(desc("temp_lo")))
        .fetch()
        .all();
    return rows;
  }

DTOを使うとこんな感じ。

  private Flux<Weather> select2() {
    var db = getDatabaseClient();
    Flux<Weather> rows = db.select()
        .from(Weather.class)
        .orderBy(Sort.by(desc("temp_lo")))
        .fetch()
        .all();
    return rows;
  }

今日はこのくらいにしとこ。・・・あれ?ここまでSpring関係なく単に便利だなーってだけじゃない???

課題は、MonoとFluxとそれ以前にStreamの使い方を僕がちゃんと分かってないとこだな。勉強しなきゃなー。

リポジトリーは、また次回。リポジトリーはSpring使ってそうよね。

## 今日のソースコード

DIとか使ってごにょっとしといた。

https://github.com/bufferings/hello-r2dbc/tree/07e521fa755f796b0ef78cc0122906dafef60509

娘とGoでプログラミング。FizzBuzzって色々詰まってるんやね。

FizzBuzzのルールを書いてあげたら、こういうのを書いてきたので「お父さんScratch飽きてきたからGoでやろ?」って軽い気持ちで言ってみたんだけど、いざ教えようと思うと結構色々伝えないといけなくて大変だったやw。FizzBuzzって色々詰まってるんやね。

f:id:bufferings:20181202185820j:plain

## RunとKill

A Tour of GoのPrintlnのところを開いて

https://go-tour-jp.appspot.com/welcome/1

へー。こんな風に書くのかーって思いながら(何回かやったことあるけど覚えてなかった)。

package main

import "fmt"

func main() {
    fmt.Println("Hello, 世界")
}

僕「Runを押してみな」

娘「ら・・らん?これ?どういう意味?」

僕「プログラムを動かすっていう意味」

娘「ボタン変わった!」

僕「それはKillだね。殺すって意味」

娘「へっ!?」

僕「あー。プログラムを途中で止めるっていうときに使われるんよ」

娘「へー。あ、動いた(∩´∀`)∩ワーイ」

## Println

僕「この『世界』の部分書き換えて」

娘「OK。み・・・つ・・・ゆ・・・き」

僕「じゃRunしてみ」

娘「『Hello, みつゆき』(∩´∀`)∩ワーイ」(みつゆきは僕の名前です)

僕「プリントラインすると文字がここにプリントされるってこと」

娘「ふーん。プリンターで出てくるみたいなものね。ラインは・・・線?」

僕「ここのラインは行って意味だね」

娘「へー」

## 値と変数

僕「次はforかなぁ」

って、A Tour of Goのfor文のところを開いて

https://go-tour-jp.appspot.com/flowcontrol/1

package main

import "fmt"

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

娘「Runしたら45になった!どういうこと?」

僕「このsumの値が45ってことだね」

娘「あ・・・た・・・い?あたいするってこと?」

僕「んー。sumって変数の中に45って値が入ってるんだけど・・・」

(しばらく色々説明)

娘「ふーん。私の『年齢』って変数の箱に『9歳』って値が入ってるの・・・かな?」

僕「そうね。まぁだいたいで大丈夫」

## インクリメント

僕「ってことで、forの部分の説明ね。このforは『繰り返す』ってこと」

娘「ふーん」

僕「iが0から始まって10未満の間は、この中の処理を繰り返すってこと」

娘「なか???」

僕「あぁ、この括弧と括弧の間の部分。で、一回終わったらiを1増やして、10未満かどうかをチェックして、10未満だったら、もう一回処理を実行するの」

娘「へー。このプラス2つの部分で増えるの?」

僕「そうそう。プラス2つで『インクリメント』って言って・・・んー、言葉はやっぱいいや。まぁ1増やすってこと」

娘「へー。算数のテストで1足すときに書いてみようかな?」

僕「あ、いや、それやめて。お父さんが先生に怒られる。プログラムのときだけね」

## for文

娘「分かんなくなってきた!どうなってるか想像できない!」

僕「じゃ、このiがどうなってるか見るために、forの中にPrintlnを書いてみて?」

娘「はーい」

(しばらく待つ)

娘「こう・・・かな?」

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

僕「実行どうぞ」

娘「へー。0から9まで出たー」

娘「でも、この45って何?」

僕「じゃ、sumも出してみたら?」

## sum

娘「できたー」

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

娘「Runね」

0
0
1
1
2
3
3
6
4
10
5
15
6
21
7
28
8
36
9
45
45

僕「iが0で、sumは0+0だから?」

娘「1かな?」

僕「あほなのかな?」

娘「あほちゃうし。0ね」

僕「そうだね。つぎはiが1になるから・・・(説明)」

娘「45になった!」

僕「そうだね。リモート調子悪いみたいだしローカルでやろうか」

## ローカル環境の準備

娘にあげた古いMacBookAirに

  • Goをインストールして
  • VS Codeをインストールして
  • Hello.goファイルにmain関数とfmt.Println("Hello")書いてあげて
  • ターミナルをVS Codeの下半分に表示しておいて
  • go build Hello.go./Hello実行とやってあげといた。

## 説明

僕「この下半分の方をクリックして矢印の上を2回押したらgo buildって出るからそれでビルドして」

娘「・・・びるど???上2回押してEnterね。できた。」

僕「ほら、このHello.goの隣にHelloってファイルができたでしょ?これが君が初めてビルドして作ったプログラムだね」

娘「(∩´∀`)∩ワーイ」

僕「そのあと上をもう2回押したら./Helloって出るからそれで実行ね」

娘「・・・じっこう???できた。ハロー!」

## forで1から100まで

僕「さっきのforループのプログラムをコピーしてきてちょっと修正しといたわー」

package main

import "fmt"

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

僕「これ実行すると、0から9まで表示されるよね。ほら」

娘「うん」

僕「これで1から100まで表示するようにしてみて?」

娘「100までってことは、101までにすれば良いのね。できたー!」

僕「最初の数字は?」

娘「あ、0だ。じゃ、ここをこうしてっと。できたー!」

僕「いいね」

package main

import "fmt"

func main() {
    for i := 1; i < 101; i++ {
        fmt.Println(i)
    }
}

## if

僕「じゃ、15のときにFizzBuzzって表示するようにしてみようか。それには『もし』っていう意味の『if』を使うんだよ」

娘「『もし』ぶつかったら『ダメージを受ける』ってやりたいのよ!」

僕「それは良いね。お父さんはそれは書けないけど、君は今日のが書けたらそのうち書けるようになると思うよ」

娘「(∩´∀`)∩ワーイ」

僕「じゃif i == 15 {}って書いて」

娘「アイ・・・アイ・・・アイ・・・エフ・・・エフ・・・」

(しばらく待つ)

娘「書けたよー!」

僕「この括弧の中にFizzBuzzってプリントするように書いて?」

娘「はーい。さっきのやつよね・・・f・・・m・・・t」

(しばらく待つ)

娘「できたー!15の次にFizzBuzzが出てきたー!」

func main() {
    for i := 1; i < 101; i++ {
        fmt.Println(i)
        if i == 15 {
            fmt.Println("FizzBuzz")
        }
    }
}

僕「いいね。次は15の倍数のとこ全部の下にFizzBuzzを出そうか?」

## %

僕「パーセントマークを使うよ。if i % 15 == 0に書き換えて?」

娘「はーい」

(しばらく待つ)

娘「できたー」

func main() {
    for i := 1; i < 101; i++ {
        fmt.Println(i)
        if i % 15 == 0 {
            fmt.Println("FizzBuzz")
        }
    }
}

僕「実行してみ?」

娘「わー!15とか30とかのとこ全部にFizzBuzzがついた!」

僕「そう。これは15で割ったあまりが0って意味ね」

娘「ふーん。割ったあまりが・・・ゼロ・・・?分かるような分からないような・・・まいっか」

娘「それよりも、15の次にFizzBuzzを出すんじゃなくて、15のところをFizzBuzzに入れ替えなきゃ」

僕「いいところに気づいたね。じゃ、elseだね」

## else

僕「} else {って書いて、数字を出すやつをそっちに移動してみて。カット&ペーストを教えてあげよう。」

娘「カット・・・?難しいけど便利ね。実行・・・と。あ、15のところがFizzBuzzになったー!(∩´∀`)∩ワーイ」

func main() {
    for i := 1; i < 101; i++ {
        if i % 15 == 0 {
            fmt.Println("FizzBuzz")
        } else {
            fmt.Println(i)
        }
    }
}

## else if

僕「次はどうしよう?」

娘「3の倍数をFizzにしたい」

僕「いいね。じゃelse ifって書いて?」

娘「はーい」

僕「その後は『3の倍数のときだけ』ってつけて?分かるかな?」

娘「んー。パーセントかな・・・。こう・・・かな?」

package main

import "fmt"

func main() {
    for i := 1; i < 101; i++ {
        if i % 15 == 0 {
            fmt.Println("FizzBuzz")
        } else if i % 3 == 0 {
     
        } else {
            fmt.Println(i)
        }
    }
}

僕「実行してみなー」

娘「うん。あれー?3のところ消えた!」

僕「どうしてかな?」

娘「あ!書いてなかった!こうやって・・・できたー!」

## 5の倍数

娘「あとは5の倍数ね・・・else ifして・・・% 5して・・・」

func main() {
    for i := 1; i < 101; i++ {
        if i % 15 == 0 {
            fmt.Println("FizzBuzz")
        } else if i % 3 == 0 {
            fmt.Println("Fizz")
        } else if i % 5 == 0 {

        } else {
            fmt.Println(i)
        }
    }
}

僕「実行してみようか?」

娘「え!まだPrintln書いてないから!」

僕「どうなると思う?」

娘「え?5の倍数が消えるはず!」

僕「やってみよう?」

娘「うん・・・あれ?」

1
2
Fizz
4
Fizz
7
8
Fizz
11
Fizz

娘「5の倍数がFizzに・・・なった・・・?」

僕「えっ?あー。ふふふ。よーく見てみて?」

娘「あ・・・れ・・・?あー!5が消えてるんだ!分かりにくいわ!」

## Buzz

娘「じゃ、Buzzを書いて・・・こうだな!できたー!!!」

package main

import "fmt"

func main() {
    for i := 1; i < 101; i++ {
        if i % 15 == 0 {
            fmt.Println("FizzBuzz")
        } else if i % 3 == 0 {
            fmt.Println("Fizz")
        } else if i % 5 == 0{
            fmt.Println("Buzz")
        } else {
            fmt.Println(i)    
        }
    }
}

娘「ありがとうございました!」

僕「いえいえ(ヽ´ω`)グッタリ」

娘「ママー!プログラム書いたよ!ビルドして実行したらね、ほらFizzBuzzが動くよ!」

妻さん「び、びるど・・・?実行?ふぃず・・・ばず・・・?なんか全然分からないけど、す、すごいねー!」

娘「(∩´∀`)∩ワーイ」

スクラムマスターの評価って? #RSGT2019 の好きなとこ。僕が手伝うとスケジュールが遅れる話。 #agileradio

アジャイルラジオで喋ってきたー!うれしいー!ポッドキャストもあるよ。よかったら聞いてください!

agileradio.github.io

トピックはこんな感じ。

聞いてくれた人は #agileradio タグつけて感想つぶやいてくれたら喜びます。後半もお楽しみにー。マッタネー٩( 'ω' )و