第50回Kotlin dojoを開催した

今週は第50回を開催しました!

引き続きKotlin Hands-onをすすめています。

 

前回の様子はコチラ↓

kdnakt.hatenablog.com

 

 

[第50回の様子]

2021/2/3に第50回を開催した。

 

参加メンバーは自分をいれて3名。久しぶりに自分がドライバーを担当した。

 

勉強会本編の内容としては、前回に続いてIntroduction to Coroutines and Channelsハンズオンを進めた。第2章の途中からはじめて、演習問題のタスクを1つ実施した。

 

[学んだことや疑問点]

  • Introduction to Coroutines and Channels: 2. Blocking request
    • logRepos関数とlogUsers関数に関する説明が書かれていた。
    • ログにはアプリ起動から経過したミリ秒、ログ出力元のスレッド、ログメッセージ本体が記録されている
    • 前回実施したブロッキング処理のログを見ると、全て同じスレッドからログが出力されている
    • そのスレッドはSwingのUIメインスレッドである:ゆえに、リクエストが処理されている間、アプリのUIがフリーズしてしまうという問題がある
    • ここからが演習問題のタスクの話
    • 現時点でアプリ上に表示されるユーザー名とコントリビューション数はリポジトリごとなので、同じユーザー名が複数表示されることがある
    • これをユーザーごとにコントリビューション合計数を表示するように修正する
    • 対象のコードは以下の通り
List<User>.aggregate() =
    this
      次のテストが用意されているので、これが通るように実装すればよい
@Test
fun testAggregation() {
    val actual = listOf(
        User("Alice", 1), User("Bob", 3),
        User("Alice", 2), User("Bob", 7),
        User("Charlie", 3), User("Alice", 5)
    ).aggregate()
    val expected = listOf(
        User("Bob", 10),
        User("Alice", 8),
        User("Charlie", 3)
    )
    Assert.assertEquals("Wrong result for 'aggregation'", expected, actual)
}
      やることは2つ、各ユーザーのコントリビューション数を合計する、と合計の降順にソートする。
      まずは簡単そうな降順ソートのテストを以下のように実装した
@Test
fun testSortDescending() {
    val actual = listOf(
        User("Alice", 8),
        User("Bob", 10),
        User("Charlie", 3)
    ).aggregate()
    val expected = listOf(
        User("Bob", 10),
        User("Alice", 8),
        User("Charlie", 3)
    )
    Assert.assertEquals("Wrong result for 'aggregation'", expected, actual)
}
    • ソートのやりかたとか忘れてしまったので、Koansの問題をみて思い出すことに。

play.kotlinlang.org

    • sortedByを使えば良さそう、と思ったが昇順にソートされてしまった。
    • なにかフラグなどを渡せないか、と思ってみたがコードのサジェストでsortedByDescendingを発見。

f:id:kidani_a:20210204142123p:plain

    • これを使うことで無事testSortDescending()をパスすることができた
    • 次に、コントリビューション数の合計のロジックを考える
    • ここでちょっと詰まってしまったので、ナビゲータからのアドバイスを聞きつつ、mapValues()関数などをうまく組み合わせて、最終的には以下のコードで全てのテストを通過することができた。
List<User>.aggregate() =
    this.groupBy { it.login }
        .mapValues { it.value.sumBy { user -> user.contributions } }
        .toList()
        .map { User(it.first, it.second) }
        .sortedByDescending { it.contributions }
    • ここで時間がなくなってしまったので、答え合わせはまた次週……。

  

[まとめ]

モブプログラミング・スタイルで、Introduction to Coroutines and Channelsハンズオンを進めた。

Coroutineの話はまだ出てこないが、久しぶりにCollectionの処理をする関数を復習できてよかった。

 

今週の進捗は以下のプルリクエストにまとまっている。

github.com