$shibayu36->blog;

クラスター株式会社のソフトウェアエンジニアです。エンジニアリングや読書などについて書いています。

多様性の力を知る - 多様性の科学を読んだ

タイトルを見てなんとなく興味が惹かれたので読んだ。想像以上に面白くてためになった。

多様性の科学

多様性の科学

Amazon

自分はこの本から多様性が実際に何に役立つかを学ぶことができた。世の中では多様性が大事と非常に多く言われている。しかし自分は多様性の高さによってどのような効果があるかについて理解ができていなかった。この本はいろんな観点から効能について教えてくれる。例えば興味深かったところは

  • 人の物事の捉え方には、ただものを見るという単純な行動にさえ、文化に基づく違いがある。ある問題において、見方が多様な集団を作ることにより、新たな捉え方や落とし穴への気づきが得られる
    • 逆に同質な集団の場合、考えていることが正しいと周りも同意するため、それが間違っていたとしても信じてしまう
    • 賢い個人がいるだけでなく、解決しようとする問題空間の中を網羅するような多様な構成にすべき
  • ある集団の平均値を用いて標準的な何かを作ると、逆に誰にも便利ではないものが出来上がってしまう
    • パイロットのいろんな部位の身体計測をして、それを元に標準的な戦闘機を作ったら、墜落率が高かったみたいな話題。サイズをカスタム可能な戦闘機にすると墜落率が下がった
  • 心理的安全性がない集団では、もともと多様性が高い集団だったとしても、支配的なリーダーの思想に寄っていってしまい、多様性が低い状況になってしまう

これ以外にも色々となるほどなーと思うことが多かったのでおすすめです。

読書ノート

- 人の物事の捉え方には、ただものを見るという単純な行動にさえ、文化に基づく違いがある 26
    - 違う見方をするもの同士が協力し合えば、ひとりの時より多くの発見が得られる 28
    - 同じような人々の集団は盲点も共通しがち。その傾向を互いに強化してしまうため、不適切な判断や完全に間違った判断にも自信を持つようになる 34
- チームで難問に挑む際にまずやるべきことは、問題そのものをさらに精査することではなく、一歩下がってこう考えること。カバーできていないのはどの分野か、無意識のうちに盲点を作ってしまっていないか、画一的な人間ばかりで問題空間の片隅に固まっていないか? 70
    - 問題空間と領域の例
    - 集合知を得るには、賢い個人と、同時に多様性も欠かせない。そうでなければ同じ盲点を共有することになる 76
    - 多様性を満たすためには、対処する問題と密接に関連し、かつ相乗効果を生み出す視点を持った人々を見つけることが鍵になる 83
- 多様性豊かなチームに支配的なリーダーがいた場合、多様性が下がる 115
    - 心理的安全性が高いことは、多様性を下げない利点になる 140
- 多様性を損なわない会議テクニック 143
    - 会議前にまとめたメモを黙読した時間を作り、他人の意見が入る前に個々が考えられる時間を作る
    - 会議が始まったあと、最も地位の高いものが最後に意見を述べる
    - 誰のアイデアかを明らかにしない
- 人は大きなコミュニティに属すると、より狭いネットワークを構築する傾向がある 207
    - 交流できる人の数が多いなら、自分と似ている人の数も多く、細かい選り好みができる
    - 小規模なコミュニティに属すると、逆に多様な人間とのコミュニケーションがなされる
- 平均値が適切に利用されれば複数の人々の視点や意見を活かせる。しかし不適切な場合には、複数の人々に平均的な答えを押し付けることにしかならない 251
    - 気づき: 標準化の罠とも近い
- 「標準的な」「誰にでも当てはまる」食事療法というのは基本的にない 256
- 日常に多様性を取り込むための3つのこと 292
    - 無意識のバイアスを取り除く
        - 採用で履歴書の目隠しをする、など
    - 陰の理事会
        - 重要な戦略や決断について、若い社員が上層部に意見を言える場
        - 上層部にとっては、多様な意見に触れて視野を広げる「テコ入れ」の機会になる
    - 与える姿勢
        - 多様な社会で、自分の考えや知恵を相手と共有する「giver」は、他の人から知恵を受け取る機会を得られ、成功を収めやすい

Goでtemplateファイルをembedして、コードとテンプレートを分離する

Goでtext/templateを使ってコードジェネレータを書いている時、コード内にテンプレート自体を文字列として埋め込むのはコードが見にくくなるため困っていた。例えばPerlのData::Section::Simpleみたいにコードとテンプレートを分離して、見やすくしておきたい。

調べてみるとembedを使うのがシンプルで良さそうだということでやってみた。参考例はこちら

Goのファイルからはgo:embedを使ってファイルからstringに埋め込んでおく。以下のsampleJsonTmplの部分。あとは埋め込んだ変数を利用してtext/templateを使って出力する。

package main

import (
    _ "embed"
    "fmt"
    "os"
    "strings"
    "text/template"
)

//go:embed sample.json.tmpl
var sampleJsonTmpl string

func main() {
    fmt.Println(sampleJsonTmpl)

    tmpl, err := template.New("sample").Parse(sampleJsonTmpl)
    if err != nil {
        os.Exit(1)
    }

    data := map[string]any{
        "Hoge": "hogehoge",
        "Foo":  "barbar",
    }

    var buf strings.Builder
    if err := tmpl.Execute(&buf, data); err != nil {
        os.Exit(1)
    }
    fmt.Println(buf.String())
}

sample.json.tmplはこんな感じ。

{
  "hoge": "{{ .Hoge }}",
  "foo": "{{ .Foo }}"
}

このようにすることで、テンプレートとコードを分離することができ、テンプレートが大きい時にコードが見づらくなってしまう問題が解消できた。

fzfを使ってgit stashを便利に扱えるように

git stashをもっと便利に扱いたいと思い、fzfを使って使いやすくしてみた。以下のURLに載っているものを参考にして自分にとって使いやすいように改変した。

できたこと

  • 今の変更ファイルをfzfを使って選択して、選択したものだけをstash (git-stash-select)
  • stash一覧の中から中身をpreviewしながら選び、apply or deleteする (git-stashes)

現在の変更ファイルから一部を選んでgit stashするコマンド

fzfでGUI選択したファイルをgit stashするシェルスクリプト を参考に、git-stash-selectというコマンドを作った。

#!/usr/bin/env bash

# Get the root directory of the Git repository
git_repo_root=$(git rev-parse --show-toplevel)

# Add instructions to the list of modified files
instructions="Select multiple files by TAB, and then press Enter to stash them."

# Use fzf to select multiple files
selected_files=$(git status --porcelain |
                 fzf --multi \
                     --header="$instructions" \
                     --preview-window='down:70%' \
                     --preview="
                        if [[ {} =~ '^\?\?' ]]; then
                          cat $git_repo_root/{2};
                        else
                          git -C $git_repo_root diff --color=always {2};
                        fi
                     " |
                 awk '{ print $2 }'
                )

# Check if any files were selected
if [ -z "$selected_files" ]; then
    echo "No files selected. Exiting."
    exit 1
fi

# Store the selected files in an array
IFS=$'\n' read -rd '' -a files_array <<<"$selected_files"

# Filter out the instructions from the array
filtered_files_array=()
for file in "${files_array[@]}"; do
    if [[ $file != *"==="* ]]; then
        filtered_files_array+=("$file")
    fi
done

# Prompt for a stash message
echo "Enter a stash message:"
read stash_message

# Stash the selected files
git -C $git_repo_root stash push -u -m "$stash_message" -- "${filtered_files_array[@]}"

工夫ポイントはpreviewの部分だ。git diffなどはUntrackedなファイルの内容表示に弱く、そのままだと表示できない。そのためUntrackedな場合はcatを使うなどの場合分けをしている。

stash一覧の中から選んでapply or deleteするコマンド

git-stash-explore を参考に、git-stashesというコマンドを作った。

#!/usr/bin/env zsh

while out=$(git stash list "$@" |
            fzf --ansi --no-sort --reverse --print-query --query="$query" \
                --expect=enter,bspace \
                --bind="ctrl-space:preview-page-up" \
                --bind="space:preview-page-down" \
                --bind="k:preview-up" \
                --bind="j:preview-down" \
                --preview="echo {} | cut -d':' -f1 | xargs -I {STASH} sh -c 'git stash show --color=always -p {STASH}; git show --color=always --format="" -p {STASH}^3'" \
                --preview-window='down:85%');
do
    # Tokenize selection by newline
    selection=("${(f)out}")

    # Keep the query accross fzf calls
    query="$selection[1]"
    # Represents the key pressed
    key="$selection[2]"
    # Represents the stash, e.g. stash{1}
    reflog_selector=$(echo "$selection[3]" | cut -d ':' -f 1)

    case "$key" in
        # enter applies the stash to the current tree
        enter)
            git stash apply "$reflog_selector"
            break
            ;;
        # backspace will drop the stash
        bspace)
            git stash drop "$reflog_selector"
            ;;
    esac
done

こちらもUntrackedなファイル対策をしている。In git, is there a way to show untracked stashed files without applying the stash? - Stack Overflow によると、あるstashの中のUntrackedなファイルを表示するには git show 'stash@{0}^3'のように^3をつければ良いらしい。そこでgit stash show stash@{0}git show stash@{0}^3の両方を実行することで、stashの中のModifiedとUntrackedの両方を出力するようにした。

applyとdeleteについては、enterとbackspaceが直感的と感じたので、その2つにキーを割り当てている。

またstashの中身を見るときにpreviewのスクロールをしたい。このコマンドは文字列検索をほぼすることがないなと思ったので、tigなどに合わせてjでscroll down、kでscroll upとなるようにした。

まとめ

今回はgit stashをfzfでもっと便利に扱えるように、変更ファイルを選択してgit stashするコマンドと、stashの中から選択してapplyやdeleteをするコマンドを紹介した。便利なので良かったら使ってほしい。