OmniAICreator/Qiita-1.07M huggingface dataset:
"potentialFoam" + "applyBoundaryLayer"を使った初期条件の作成

# はじめに
数値解析においては、初期条件、境界条件を適切に設定することが重要です。OpenFOAMでは、特にこの条件が計算安定性に及ぼす影響は大きいです。
OpenFOAMでは初期条件を作成する方法として、`potentialFoam`（完全流体流れ）を使用する方法が主流ですが、デメリットとして、（当然ではありますが）境界層がない、流束を過大評価する、があります。

本記事では、OpenFOAM ver.8環境下で`potentialFoam` + `applyBoundaryLayer`を組み合わせた初期条件の設定方法をまとめます。

# Step 1: potentialFoam
- Tutorial `pimpleFoam/pitzDaily`を作業ディレクトリにコピーします。
- このままでは `potentialFoam` が実行できないので`fvSolution`を編集します。

```c++:system/fvSolution
solvers
{
    Phi 
    {   
        solver          GAMG;
        smoother        DIC;

        tolerance       1e-06;
        relTol          0.01;
    }  
}
potentialFlow
{
    nNonOrthogonalCorrectors 2;
}
```
- Step 2: potentialFoamを実行

下図のような境界層が無い流れ場が`0`ディレクトリに得られます。

![Screen Shot 2021-01-06 at 23.50.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/b67fe408-079e-8948-29d0-1a6e0d623300.png)

# applyBoundaryLayer

`applyBoundaryLayer`は速度場データを元に壁面境界を計算するソルバーになります。
以下はソースの抜粋になります。

```c++:applyBoundaryLayer.C
     // Modify velocity by applying a 1/7th power law boundary-layer
     // u/U0 = (y/ybl)^(1/7)
     // assumes U0 is the same as the current cell velocity
 
     Info<< "Setting boundary layer velocity" << nl << endl;
     scalar yblv = ybl.value();
     forAll(U, celli)
     {
         if (y[celli] <= yblv)
         {
             mask[celli] = 1;
             U[celli] *= ::pow(y[celli]/yblv, (1.0/7.0));
         }
     }
     mask.correctBoundaryConditions();
 
     Info<< "Writing U\n" << endl;
     U.write();
```

ここに記載している通り境界層を__「$1/7$乗則」__で計算します。

使用方法ですが、以下のようにオプションをつけて実行するのみです。

```bash
applyBoundaryLayer <option>
```
- options
 - -Cbl scalar
 - -ybl scalar 
 

前者は壁面からの平均距離（第１層のメッシュ厚さ）にオプションで指定した値を乗じたものを境界層厚さとします。後者は境界層厚さをそのまま指定することになります。


その他、詳細は[ここ](https://www.openfoam.com/documentation/guides/latest/man/applyBoundaryLayer.html)を参考にしていただければと思います。


あとは、`fvSchemes`にwallDistの設定を追記すれば良いです。

```c++:system/fvSchemes
wallDist
{
    method meshWave;

    // Optional entry enabling the calculation
    // of the normal-to-wall field
    nRequired false;
}
```

![Screen Shot 2021-01-06 at 23.48.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227359/01cf414e-a197-ed47-958a-3f0353e751fd.png)


上図が`applyBoundaryLayer`によって得られた速度場の初期条件になります。先の`potentialFoam`の結果と比べて、よりリーズナブルな速度場（境界層があり、かつ、速度の過大評価が是正されている）が得られていることがわかります。

なお、対象が乱流のcaseであれば、乱流パラメーターも計算してくれます。

# さいごに
解析が発散するような場合は、離散化や線形ソルバーの見直しも必要ですが、このような初期条件の見直しも有効だと思います。
PowerToysで簡単にファイル名に接頭辞をつける

PowerToysでエクスプローラーから、簡単にファイル名に接頭辞をつけられました。regexを使って、名前を置き換えられるとは...

# やり方
エクスプローラーで、対象のファイルを選んで

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/75c37ce6-1199-d7cb-1ac9-5fad51e76661.png)

右クリックして、PowerRenameを選んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/7b466b7d-d450-8433-f6b1-6a7f92d24c54.png)

PowerRenameの
検索対象:「^(.*)$」
置換後の文字列:「接頭辞$1」
と入力して、「名前変更」でおしまい！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/245977/0d780f6b-f60c-6eb1-d53b-031f51570605.png)

「検索対象」「置換後の文字列」は保持される模様です。
【ネットワーク用語】リゾルバとは

DNSサーバーにおけるドメイン名・IPアドレスでの紐付け変換を行うためのソフトウェア・プログラム。

リゾルバには**フルサービスリゾルバ**と**スタブリゾルバ**がある。

#####スタブリゾルバ
DNSサーバーへ問い合わせるためのプログラムのこと。(通称：リゾルバ)　


#####フルサービスリゾルバ
自己解決できなかった場合に、他のDNSサーバーへ問い合わせるためのDNSサーバーのこと。
Ubuntu 20.04.1 LTS上にRuby3.0.0とRails6.1.0の開発環境を作ってみる

# はじめに

劇的に進化したRuby3とRails6.1の環境を構築してみました。
普段使いの開発環境にしたいので、
OSは「Ubuntu desktop 20.04.1 LTS remix 日本語版」にしています。

## 環境
- Ubuntu 20.04.1 LTS
- Ruby 3.0.0
- Rails 6.1.0


## 現在の環境を最新の状態にアップデートします。

```zsh
$ sudo apt update -y
$ sudo apt upgrade -y
```

## 開発に必須のパッケージとRuby on Railsで必要なパッケージをインストールします。

```zsh
$ sudo apt-get -y install git curl g++ make libyaml-dev libxml2-dev libxslt-dev sqlite3 libsqlite3-dev nodejs npm
$ sudo apt install build-essential -y
$ sudo apt install -y libssl-dev libreadline-dev zlib1g-dev
```

## Gitのアカウントを設定します。

```zsh
$ git config --global user.name ＜ユーザー名＞
$ git config --global user.email ＜メールアドレス＞
$ rbenv（パッケージ管理ツール）をインストールします。
$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv
```

## 環境変数Pathを設定します。

```zsh
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
$ echo 'eval "$(rbenv init -)"' >> ~/.bashrc
```

## シェルを再起動します。

```zsh
$ exec $SHELL -l
$ ruby-buildをインストールします。
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
```

## Rubyをインストール

```zsh
$ rbenv install 3.0.0
$ rbenv global 3.0.0
```

## yarnのインストール

```zsh
$ sudo apt install curl
```

## Railsのインストール

```zsh
$ gem install -v 6.1.0 rails
```

仕事の兼ね合いもあって、これまでは、Ruby on Rails 3しか使っていませんでした。
今回の環境でRuby3のパフォーマンスと、Rails5.1でサポートされたWebpackerを試してみたいと思います。
まとめ

#Djangoでwebアプリを作ったのでその簡単なまとめ
プログラミング学習のアウトプット用としてPythonとDjangoを使ってwebアプリを制作したのでそのまとめ

#この記事の目的
構成、機能を伝えるため

#アプリケーションの概要#
Youtubeに上がっている動画のタイトル以外の情報で検索し、探せられるアプリ

TOP画面
![top-pc.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009317/962d269d-61f8-b727-1b27-1bec106e2857.jpeg)
検索画面
![search.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009317/d033bc24-db35-b36f-2989-f20eb0dbc9d7.jpeg)
カテゴリー検索画面
![category.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009317/4c5a151c-68a7-1670-c919-c37952d873d6.jpeg)
詳細画面
![detail.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1009317/1b00cc94-87ed-c23b-cf8f-c9c83e0a3e40.jpeg)







#作ろうとした経緯
タイトルに載っている情報以外で、動画を調べたて見たい
→検索要素
例えばYoutubeで「ライバロリ　ルカリオ」と検索した場合、タイトルで書かれていたらヒットして上位にくるが、動画内で使われていてもタイトルに書かれていなければヒットしない。つまり探すことができないのである。
対戦ゲームにおいて有名実況者やランキング上位者が使っているポケモンは話題になりやすく、真似て使う人も多い。
参考にしたい時にウェブサイトで検索したりしても良いが、動画のほうが使用感がわかる。

#開発環境
Python 3.8.5
Django 3.1.4
HTML
CSS
jQuery
Github
Heroku
　→なぜHerokuなのか。AWSについて勉強している最中であり、何度かちょうせんしてみたものの上手く動作しなかったため。デプロイさせることを優先した。

#なぜPython,Djangoなのか
PHP,RubyとそのフレームワークのLaravel,Railsでもほとんど同じ機能を作れると思うが
サムネイル、動画タイトル、リンクなどスクレイピングで情報収集するのにもっとも効率のいい言語がPythonだった。
あとは将来性と、一番初めに触れた言語がPythonだったため。

#主な機能
検索機能、タグ機能、

#主な機能になり得るが不必要だったもの、またその理由
ユーザー登録
ログイン
マイページ
お気に入り
これらはYouTubeに飛べるのでその後でいいねボタンや後で見るができるので省略し、より見やすく使いやすくした。実質的にGoogleアカウントでログインしている。
あくまでも見たい動画を効率よく検索するためのもの。

#その他メモ
今のところ完成度は60％くらい
最新、おすすめ、人気動画をまとめられるなにかを作りたい（知識がないのでどうやってやるのかこれから勉強予定）
検索機能の追加
検索ページの動画の横に入力して検索させるようなものと
カテゴリーを選んで検索できるものを追加したい。

あとスクレイピングが上手く動作できないので情報収集が手動になっているので自動化させたい
けれど、あくまでもメインはウェブアプリの方なのでできたらコードを乗せて制作物として乗せてみたい
不安定なラズパイの作り方、あるいはラズパイの電源の切り方

（ラズパイの赤と緑のLEDの挙動を変える方法について、別記事を書きます。）
2021年2月20日追記：書きました。
「ラズパイの赤LED、緑LEDの挙動を変える方法」
https://qiita.com/naohiro2g/items/d5385a4e660fd72711b2

## ラズパイには電源ボタンがない

コンピューターには電源ボタンがありますが、いきなり押して切るのがダメなのは、常識ですね。
最近のは、きちんとシャットダウン処理を自動的にやってくれる物も多いですが。

ラズパイも同じなのですが、ラズパイには電源ボタン自体、ありません。では、いつ電源ケーブルを引っこ抜けばよいのか？？

## なぜ、いきなり電源を切ってはいけないのか？

コンピューターの電源ブチ切りをやると、ファイルの一部が壊れる可能性があります。どこが壊れるかわからないし、全く壊れない可能性もあります。

### では、ファイルの一部が壊れた場合、どうなるのか？

破損箇所がシステムの起動に必要な部分だった場合：
最悪のケースでは、起動すらしなくなります。

あるアプリのプログラムの一部だった場合：
アプリが立ち上がらなくなったり、ある機能を使おうとするとフリーズしたり、おかしな動作になったりします。いわゆる「不安定」な感じになる。

そして、フリーズしたり、おかしな動作になると、電源のブチ切りと同じ事が起こり、ファイルの一部が壊れることがあります。

## 不安定なコンピューターの作り方（ラズパイに限らず）

つまり、電源のブチ切りを一度やると、コンピューターが不安定になり、さらに、どんどん不安定になる、ということです。不安定なコンピューターは、だいたい、こういうふうに作られます。

不安定なアプリを使う事も不安定なコンピューターを育てる「正しい」やり方でもありますが、不安定になりかけたときに、更にしつこくクリックしたり、いじめるとダメです。生活習慣病のように、コンピューターを不安定にする方法／習慣、が存在します。


## 本題：ラズパイの電源の切り方

デスクトップからの場合、画面左上のラズベリーアイコンから、一番下の非常口アイコンのShutdownを選び、さらに、Shutdownのボタンを押します。
ターミナルからの場合、```sudo halt```と入力します。

このあと、緑LEDをよく見ていること。緑LEDは、普段はマイクロSDカードの読み書きの際にチカチカ点滅していますが、シャットダウンのとき、以下のような挙動になります。

 - 9回点滅して、
 - 最後に点灯、
 - しばらくして消灯（ラズパイ4は10回目も点滅！ 改悪だ。。）

このタイミングでHDMIからの信号も無くなり、ディスプレイに「信号がありません」「ケーブルを確認してください」などと表示されます。

はい、これで、電源を安全に切ることができます。

## 要注意

問題は、緑LEDが10回点滅するまでに3分くらいかかる時があることです。更に問題なのは、赤LEDはシャットダウン後も消灯しないので、シャットダウン完了したかどうかが判別できないことです。
これが、緑LEDをよく見ていないといけない理由です。ラズパイ4では、点滅最後、長めの点灯がなくなってしまったので、さらによく見ていないといけない。

## 赤LEDはどうした！ なんで点灯したままなの？

赤LEDは、電源電圧監視用として働いていて、電流が流れすぎたときなど消灯、点滅することがありますが、電源が切れたあとは点灯したままなのです。

緑LEDの10回点滅の動作はGPUのシャットダウンシーケンスの中で実行されているので、同じく、赤LEDも最後に消灯するようにできそうですが、それには、ファームウェアを書き換えて、コンパイルしなおさないと。つまり、簡単には無理。気を長くして改善に期待しましょう。
RSGT2021 セッションメモ～アジャイルコーチとVPoE、あるいはEMの間にあるもの～

RSGT(https://2021.scrumgatheringtokyo.org)
で自身が参加したセッションのメモ&ふりかえりです。
ふりかえりの手法は、びばさんが配信しているPodcastである、ふりかえりAM ep.4(カンファレンス用のふりかえりをする例)で紹介されていたFun Done Learnを参考にしています。

# 概要

- Kazuyoshi Takahashiさん
- Day2(15:40～16:00)
- 10年前から5年前まで、アジャイルコーチとして2,000人以上の開発組織を抱える企業のアジャイルトランスフォーメーションに挑戦していました。
  現在はその立場を離れ、事業会社のVPoEとして開発組織の運営をしています。
  アジャイルコーチとVPoE、両方の経験からチームを見る視点にどのような違いがあるのか、アジャイルコーチの先にどのようなキャリアがあるのか、個人的な経験を交えながらお話します。
  RSGT2020 Closing Keynote「NEXT→ACTION」の後日談でもあります。 

# 気になった内容メモ

- 高橋さんの感覚的には、アジャイルコーチの人が凄い増えた実感がある。
  - セッション中のアンケートでも10人！
- アジャイルコーチを高橋さんが辞めた理由
  - 寂しさや孤独感を感じた
  - 第三者的立場でしか関わりがない
- アジャイルコーチからEM/VPoEに戻る苦悩
  - 自分の意見を中々言えない(常に第三者的目線で引いた目線になる)
  - 自分自身の意見を構築する力の衰え
- アジャイルコーチからEM/VPoEに戻る際、アジャイルコーチで養って生きた経験
  - ファシリテーションスキル
  - 人事
  - ...
- アジャイルコーチとEM/VPoEの違い
  - 組織への向き合い方
    - アジャイルコーチは外から、EM/VPoEは中から
  - プロダクトへの向かい方
    - アジャイルコーチは間接的。EM/VPoEは直接的
  - 職務と職責
    - EM/VPoEの方が広い。プロダクトマネジメントやテックブランディング, 採用, 計数管理...もやらないといけない
  - スキルとコンピテンシー
    - アジャイルコーチのカバーするスキルが大きくてポータビリティが高い
    - ロジカルシンキング, クリエイティブシンキング, アジャイル開発理解...
- アジャイルコーチの存在意義って何だろう？
  - チームに対する客観性
  - チーム外を含む組織に対する客観性
  - プロダクトの意思決定に関する客観性
- アジャイルコーチは、チームの中からだと見えていない事実に目を向けさせ、機会損失を小さくする
- チームにとってアジャイルコーチは面倒くさい人
- アジャイルコーチとEM/VPoEは兼任できるものでない
- アジャイルコーチとEM/VPoEどちらについても、それぞれに傾倒すればするほどもう一方の立場に戻るのが難しくなる

# 楽しかったこと

- 冒頭の昨年のふりかえりと感謝が素敵だった
- プレゼンが上手で聞きやすかった
- 淡々とした事実の中に情熱を感じられる

# やったこと

- アウトプットを意識しながら話を聞いた
- 昨年のkeyNoteの内容を見返した

# 学び

- 立場を変えて物事を考えるというのは、相当大変だということが実感できた。
- 必要なスキルの話が、自分の今後のキャリアを考える上で参考になる話が多かった
- 客観的に見るという言葉の解像度が上がった。
Regional Scrum Gathering Tokyo 2021 Day 2 「Scrumチームに「テストは単純作業ではなく創造的な活動だ」という意識を浸透させて良品質＆低コストの製品を作るようになるまでの物語」

202/01/07に開催されたRegional Scrum Gathering Tokyo 2021での発表です。
https://confengine.com/regional-scrum-gathering-tokyo-2021/proposal/14632/integrate-your-cycle-with-ooda-extended-edition-of-scrum-x-army-at-rsgt2020

# チーム参加してきました

[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム7人で参加して、その場で実況しつつ、記事も作っています。


- 「テスト」という言葉から想像するもの
	- テストは作業ではない
- 「テスト」の目的とは何か？
	- バグを作りこまないようにする

# 早い段階で入り込み、壁を壊す
## 1.価値あるリファイメントを行った話
- 開発者に開発終了後にテストを依頼してもいいかといわれた
- とりあえず、開発の前後両方でテストをしてみることを提案し、初回リファイメントの段階で入り込めた。
- 実装前にテストの考え方を取り入れる効果
	- リファイメントで問題を指摘されたことによって、テストでバグが発生しなかった。
	- 作り直したり、再テスト行う必要がなくなり、工数の短縮に繋がり、品質が高まった。

## 2.開発者主催のMTGにQAが参加
- テスト行うまでの準備
	- テスト分析
		- 何をテストするか
	- テスト設計
	- テスト実装
	- テスト実行
- どうやったらテストを減らせるのか？テスト作成の段階でQAを行い、不必要なテストを省いた。

- **リファインメントのポイント**
	- 実例を伴って質問する
	- 開発とQAの距離が近い状態で質問する

## 様々なロールの人が集まって、ロールを行う
- 開発者
	- 実装の難しさがわかる
- PO
	- 優先度がわかる
- QA
	- どんなテストができるかわかる

QAがいる組織において、QAが早い段階でかかわってテスト活動することで、
テスト項目や工数の削減に繋がり、品質が高まる。

# QA? SM? PO?
QAとSM/POは別物で、キャリアアップではなく、キャリアチェンジである。

QA・SM・POそれぞれにとって重要な考え方、とらえ方があり、
QAはチームにとっての品質の接着剤である。


# 感想
- QAのそもそ仕事のやり方を変えることで、テストの品質を上げ工数の短縮に成功したことがすごいと思いました。
- 今後テストを行う際にこの手法でやってみたい。
FileMakerをNginxでリバースプロキシする

## 参考
https://qiita.com/Hi_Noguchi/items/82bc17913b646bd6583f

## 謎のログが大量に出る

```
192.168.11.209 - - [07/Jan/2021:01:46:34 -0500] "GET /fmi/webd/PUSH?v-uiId=1&v-pushId=0cb42d4b-f1fe-4b2a-a301-4697dcd02bf8&X-Atmosphere-tracking-id=c9a3b90b-1456-492d-8c2c-9cd3e64fe4eb&X-Atmosphere-Framework=2.3.2.vaadin1-javascript&X-Atmosphere-Transport=long-polling&X-Atmosphere-TrackMessageSize=true&Content-Type=application%2Fjson%3B%20charset%3DUTF-8&X-atmo-protocol=true&_=1610001997197 HTTP/2.0" 200 43 "https://stb.vamdemic.net/fmi/webd/GrimEntry" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.52" "-"
```

## 対処方法

```nginx
    server {
        listen       443 ssl;
        listen       [::]:443 ssl;
        server_name  stb.vamdemic.net;
        root         /usr/share/nginx/html;

        ssl on;
        ssl_certificate     "/etc/nginx/cert/cert.pem";
        ssl_certificate_key "/etc/nginx/cert/private.pem";

        location / {
            proxy_pass https://192.168.11.254:443;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_http_version 1.1;  # これ必須
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-Server $host;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_cache_bypass $http_upgrade;
        }

        error_page 404 /404.html;
            location = /40x.html {
        }

        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
    }
```

## proxy_http_version 1.1

https://qiita.com/smallpalace/items/26bdf6fcff64ce0b9be6https://qiita.com/smallpalace/items/26bdf6fcff64ce0b9be6

http://www2.matsue-ct.ac.jp/home/kanayama/text/nginx/node59.html

- デフォルトだと1.0
- バックエンドでKeepAliveを利用する場合1.1が推奨のよう
Regional Scrum Gathering Tokyo 2021 Day 2 「 NTTみたいな企業で新アプリをスクラム開発してみんなが笑顔になった」

202/01/07に開催されたRegional Scrum Gathering Tokyo 2021での発表です。
https://confengine.com/regional-scrum-gathering-tokyo-2021/proposal/14648/ntt

# チーム参加してきました

[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム7人で参加して、その場で実況しつつ、記事も作っています。

# アジャイルスクラムの取り組み
「シンプルな購買活動」を目指したサービスから、多様な購買形態に対応するサービスを開発するためにアジャイルな組織になろうと決心した。しかし最初は周りは興味なし。
個の話は、急ピッチでアプリ提供を行ったところ炎上した経験を踏まえ改善した記録。

## プロセスの改善

「BE AGILE」を合言葉に

- 心理的安全：占有ルールで共同作業
- ユーザ価値：インセプションデッキを策定
- スプリント
- 体制

をテコ入れした。半年くらいで短期スパン化し、スプリント見積もり・1週間スプリント導入など愚直に取り組んだ結果高い品質を実現できるようになった！

## 乗り越えられない壁

インセプションデッキに書いた、一番やりたいことになかなかたどり着けなかった。

無理やり作ったせいで全然関係ない機能に改修影響が出るように....
少しずつ直したけど、限界に。

売上やスプリントのベロシティなど頑張ってあげたけど、さらなる要求がくるようにくるように....

試験の自動化が進まない。改善の余地が見えなくなってきた。

このまま続けてもどうしようもない
→アプリの刷新を決意


# 工夫
## 開発プロセスの工夫
- 旧アプリに平行して新アプリ開発
- 機能は少しずつ作ったらリリースするように
（バックアップだけの機能から、画像保存、削除、動画対応…）
- 各プロセスの進め方は旧アプリ刷新という形で進めた
	- アプリを刷新する判断：ステークホルダーに許可をもらう
	- 伴う開発の仕方審議・開発とテスト：旧アプリの機能改善という位置付けで許可

- 新アプリ開発は慎重に

ソーシャルプラクティスと技術プラクティスのそれぞれに顧問をつけて改善。

## チームでの工夫

- 大企業ならではの技術顧問陣の支援を活用
- ペア/モブ作業の定着
- 発言者の偏り是正→ランダム性を持たせる
- 開発メンバへの啓発活動→イベント時に全体共有

## 品質管理への取り組み

- スピード最優先に、透明性をもって進める。
- 品質に対する考え方をルール化する。
- 失敗したとしてもすぐ戻せる、安心安全の体制をとる。

## CI/CDの取り組み
- コードに触れるな、という教えもあるが、動くものに触れながら文化を変えるように
- 試験自動化しやすい設計/実装、Unit Testの自動化を検討。
- 可能な限りtestableなコードを書く
- モブプロ

## コロナ禍での開発
- 平時からクラウドツールを活用
- 開発作業やコミュニティに影響が出なかった

メンバーは遊牧民のような状態で、皆家から作業ができる状態に。

# 効果
## 機能面
- バックアップの高速化
Amazon Cloud photo より速いスピードで
- バックアップした写真などの確認

# 学び
「スコープを削る」ことが大事

# チームメンバーの声
- こういうやり方でも良いんだ、という気づき
- プレッシャーからの解放
- スピード感あった

# スクラムコーチからの声

数々のポジティブな効果が表れた

# これから目指す姿

さらなる高速化、課金、チームの姿としての横展開


# さいごに
未来を変える権利はみんな平等にあるんだよ！

# 感想

- 大企業あるあるに共感しつつ、難しい状況から変わっていくストーリーを聞くことができて面白かったです。
- アジリティ高く軌道修正していく様子が新鮮でした。40分ほどのセッションでしたが、変革時の葛藤などもっと聞いてみたいと思いました。
githubでssh: connect to host github.com port 22エラーが発生した

私は普段githubにはsshで接続を行っているのですが、port22で接続できないネットワーク環境の際にgithubと通信を行うとエラーが発生しました。
その時の対処法。

## 何が起こったか

カフェのWIFIにつないでgithubにいつもどおりアクセスしようとしたところ下記のエラーが発生した。

```
$ git push origin master
ssh: connect to host github.com port 22: Operation timed out
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

どうやらここのWIFIはport22での接続を許容していないらしい。

## port443でssh接続を行う

対処法は[こちらの公式ドキュメント](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/using-ssh-over-the-https-port)に書いてあるままなのですが、以下の手順で行いました。

接続できるか確認。

``` 
$ ssh -T -p 443 git@ssh.github.com
The authenticity of host '[ssh.github.com]:443 ([18.181.13.223]:443)' can't be established.
RSA key fingerprint is SHA256:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '[ssh.github.com]:443,[18.181.13.223]:443' (RSA) to the list of known hosts.
Hi username! You've successfully authenticated, but GitHub does not provide shell access.

```

configを公式に従って編集

```
$ vi ~/.ssh/config

//以下を記載して保存
Host github.com
   User git
   Hostname ssh.github.com
   Port 443
   IdentityFile ~/.ssh/id_rsa
```

ssh接続を確認する

```
$ ssh -T git@github.com
Hi username! You've successfully authenticated, but GitHub does not provide shell access.
```

できました〜〜〜〜！

## セキュリティ的な問題とか

この辺よくわからんかったので、@mikkame さんに聞きました。

原理上はHTTPSを使っているわけではなく、HTTPSのportを使ってssh接続をしているだけなので問題が起こる可能性は限りなく低いとのことです。

なので、configファイルはこのままでも問題なさそうでしたが、なんとなく自宅で接続する際に不要なものが含まれてるのも気持ち悪いので、そのカフェを出る際にconfigファイルは元の設定に戻しました。

@mikkame さんSpecial Thanks！:pray: :pray: :pray:
JavaScript Primer「オブジェクト」#深いコピー（deep copy）の例題を理解する

JavaScript Primer 第一部：基本文法「オブジェクト」の[#オブジェクトの複製](https://jsprimer.net/basic/object/#copy)の*深いコピー（deep copy）*が何をしているのか理解できませんでした。学習の過程においては、そんなにこだわるところではなかったかもしれませんが、理解できなくて気持ち悪かったので整理。

以下、JS Primerの解説を引用しておきます。
>逆にプロパティの値までも再帰的に複製してコピーすることを、深いコピー（deep copy）と呼びます。 deep copyは、再帰的にshallow copyすることで実現できます。 次のコードでは、deepCloneをshallowCloneを使うことで実現しています。

>このように、JavaScriptのビルトインメソッドは浅い（shallow）実装のみを提供し、深い（deep）実装は提供していないことが多いです。 言語としては最低限の機能を提供し、より複雑な機能はユーザー側で実装するという形式を取るためです。



```js
// 引数の`obj`を浅く複製したオブジェクトを返す
const shallowClone = (obj) => { //(5)
    return Object.assign({}, obj);
};
// (3)
// 引数の`obj`を深く複製したオブジェクトを返す
function deepClone(obj) {
    //(4)
    const newObj = shallowClone(obj); // => {level: 1, nest: {level: 2}}
    // プロパティがオブジェクト型であるなら、再帰的に複製する
    // (6)
    Object.keys(newObj) //引数内のオブジェクトのキー（左側）を一つずつ抜き出してくる（forEachに似てる？）
        .filter(k => typeof newObj[k] === "object") // (7)
        .forEach(k => newObj[k] = deepClone(newObj[k])); // (8)
    return newObj;
}
//(1)
const obj = { 
    level: 1,
    nest: {
        level: 2
    }
};
//(2)
const cloneObj = deepClone(obj);
// (9)`nest`オブジェクトも再帰的に複製されている
console.log(cloneObj.nest === obj.nest); // => false
```

以下、実際のプログラムの動きとは違うと思いますが、入門者の自分が理解しやすいように流れを整理してみます。

1. obj変数にオブジェクトが代入される
- cloneObj変数に、1のobj変数を引数に渡すdeepClone関数が代入すると宣言される。
- 2.で呼ばれたdeepClone関数を実行していく。
- shallowClone[関数式](https://jsprimer.net/basic/function-declaration/#function-expression)を呼び、引数にobjを渡し、newObjに代入する。（関数式はその変数名で参照できる）
- shallowClone関数式の無名関数を実行する。Object.assignメソッドで第一引数のからオブジェクト`{}`にobjを合体させ（クローンする）、それを返す。
- Object.keysで仮引数内のオブジェクト（newObj）のキーを１つ１つ展開する。
- [Array.filter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)で引数に与えられた関数でnewObjのキーを一つ一つ検査し、該当するプロパティだけで新しい配列を作り、返す。（→if文みたい！）検査内容は、そのキーのデータ型が"object"かどうか（「は？」と思った入門者は下図1参照）。つまり`{level: 2}`だけの配列ができる。
- それに対してforEachを仕掛けて、一つ一つのプロパティに引数内の無名関数を実行する。deepClone関数（自分）を実行し（自分を呼ぶから再帰的と呼ぶ）、newObjオブジェクトのキー`k`のプロパティにその結果を代入する。x-yの処理が`{level: 2}`に対して再度行われる。newObjを返す。
- オリジナルのobjのキー`nest`とクローンしたcloneObjのキー`nest`を比較し、falseとなるので、複製されたオブジェクトとわかる。

図1：
![スクリーンショット 2021-01-07 15.13.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/645077/6e8acdee-edbb-6577-1f3d-1cd20136578f.png)

以上です。
てか、コピーと謳うのであれば、プログラムのコードでもCloneではなく、Copyとしてくれればよかったのに、と思うのは私だけでしょうか。
Eloquentのall()ってなんなの？　いきなりget()しちゃダメなの？

# はじめに

LaravelでDBからデータを取り出す処理を書いているときに、大体`all()`ってやるじゃないですか。

```php
$hoges = Hoge::all()
```

で、自分で書いておきながら「あれ？　全件取り出しの時`all()`って書いたのなにげに初めてじゃね？」って思ったんですね。実際、他のところではいきなり`get()`してました。

```php
$fugas = Fuga::get();
```

で、この2つ、同じ動きをするわけなんですが、何が違うんじゃ？　と思った次第です。

# `all()` のコードを見てみよう

公式ドキュメント見ても何がどう違うのか書いてはいなかったので、コードを見てみることにしました。

```php:vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(454-465)
    /**
     * Get all of the models from the database.
     *
     * @param  array|mixed  $columns
     * @return \Illuminate\Database\Eloquent\Collection|static[]
     */
    public static function all($columns = ['*'])
    {
        return static::query()->get(
            is_array($columns) ? $columns : func_get_args()
        );
    }
```

どうも、普通に`get()`を呼んでいるだけのようです。
ただ、違うところは取得するカラムを引数で指定できるようになっているのですが、配列、もしくは可変長で取れる様になっているところみたいです。

つまり、

```php
$hoges = Hoge::all(['id', 'updated_at']);
```

```php
$hoges = Hoge::all('id', 'updated_at');
```

は同じ動きをするってことですね。
`get()`の場合は引数が１つの配列、もしくは文字列しか取れないので

```php:動かない例
$hoges = Hoge::get('id', 'updated_at');
```

これは動きません。

# 結論

* いきなり `get()` でも良さそう
* 全件取得してるよ！ってのを明示的にしたければ `all()` を使う感じかな？
error: You have not concluded your merge


# 事象 : git pullしたら怒られた
- 環境
    - Windows10 Pro バージョン1909
    - git version 2.25.0.windows.1

```bash
$ git pull
error: You have not concluded your merge (MERGE_HEAD exists).
hint: Please, commit your changes before merging.
fatal: Exiting because of unfinished merge.
```

```bash:こうなるまでの経緯は...
# 1. プルしないでローカルを変更してコミットした
$ git commit -m 'プルしないでローカルを変更してコミットした'
#...省略...

# 2. プッシュしようとしたらプルしろって怒られた
$ git push
To https://github.com/username/repo.git
 ! [rejected]          feature/braname -> feature/braname (fetch first)
error: failed to push some refs to 'https://ponsuke:keyval@github.com/username/repo.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

# 3. だからフェッチしたらリモートに変更があった
$ git fetch --all --prune
Fetching origin
remote: Enumerating objects: 29, done.
remote: Counting objects: 100% (29/29), done.
#...省略...

# 4. プルしたらマージが発生して、
$ git pull
hint: Waiting for your editor to close the file...

# 5. コメント用にエディタが開いたが、うっかりそのエディタを閉じてしまった・・・
$

# 6. 再びプルすると怒られた
$ git pull
error: You have not concluded your merge (MERGE_HEAD exists).
#...省略...
```

## 原因 : コミットしていないマージがあるから

```bash:メッセージのざっくり訳
エラー:マージが完了していません(MERGE_HEADが存在します)。
ヒント:マージする前に変更をコミットしてください。
fatal:マージが完了していないため終了します。
```

### 対応 : マージをリセットする
ちょっとよくわかんなくなったので、取り敢えずマージをリセットしてやり直すことにした

```bash:マージをリセットする
$ git reset --merge
```

```bash:プルからやり直す
# 再びプルしてエディタでマージコメント書いて
$ git pull
hint: Waiting for your editor to close the file... error: There was a problem with the editor '"C:\apps\Sublime Text 3\sublime_text.exe" -w'.
Not committing merge; use 'git commit' to complete the merge.
Merge made by the 'recursive' strategy.
#...省略...

# コミットしろとメッセージにあるのでコミットして
$ git commit
On branch feature/braname
Your branch is ahead of 'origin/feature/braname' by 2 commits.
#...省略...

# プッシュしていないコミットがマージ分と自分の変更の2つあることを確認して
$ git log origin/feature/braname..feature/braname
commit b9... (HEAD -> feature/braname)
Merge: e2... e5...
#...省略...

commit e2...
#...省略...

# プシュる
$ git push
Enumerating objects: 16, done.
Counting objects: 100% (14/14), done.
#...省略...
```
疑問に感じたことを勉強してまとめてみた

#何を疑問に感じていたのか

<dl>
<dt>enum class, companion object, lateinit var, init</dt>
<dd>→上記4つを深く理解しないで使っていたので、勉強しました。</dd>
</dl>

##enum class 

####このクラスを使うメリットは二つあります。

######一つ目→あらかじめ決まっているものを打ち込むのでミスが少ない。
######二つ目→引数が明確なので、可読性が高まる。

![スクリーンショット (379).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975701/f1412969-1d64-bf71-bab2-85781f589f2a.png)

enum class に決まった名前を持たせておけば呼び出しに応じて enum class の中身を持ってくることができる。

![スクリーンショット (380).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975701/7669a44c-9a43-d52f-1f36-4901eaab8077.png)

引数として様々な型が渡せる→渡すものが明確なのでコードの可読性を上げてくれる。

#####→確かに、何を渡そうとしているかがわかる。

勉強させていただいた学習記事URL→https://www.sejuku.net/blog/102670

##companion object

####この機能を使うメリット

#####・Javaでいうところのstaticなので、インスタンス化前に実装したいことをコードすることができる。
#####・Singleton を作成できること。


<dl>
<dt>Singletonはどんな時に必要??</dt>
<dd>→インスタンスが必ず一つであるとき(インスタンスが複数存在してはいけないとき)</dd>
</dl>

![スクリーンショット (382).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975701/8b441be6-3c93-a3a5-8533-34ecb63d1119.png)

これは、RoomDatabaseを使った時のコードです。
このデータベースのインスタンスは、Singletonである必要があるので次の確認が必要

<dl>
<dt>staticなのでインスタンス化前に存在の確認ができる。</dt>
<dd>→個人的には、companion objectはこれ以外の使い道があるのか?と考えるくらい必要性に納得してしまいました。</dd>
</dl>


##lateinit var
#####この機能を実装するメリットは、プロパティの初期化を遅らせることです。

######以下の制約があります。
<dl>
<dt>プリミティブ型をしてできない</dt>
<dt>non-nullであること。</dt>
</dl>

![スクリーンショット (384).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975701/2f672570-6207-307b-778a-f6e9f4a40b8c.png)

参考にした記事→https://qiita.com/u-dai/items/a31c5c2a7d5c7ed2cc47


##init

#####コンストラクタで処理しきれないことをinitブロックで処理を実行する。
<dl>
<dt>プロパティは、initブロックの前に書く</dt>
<dt>→以下のようなミスが減らせる</dt>
</dl>

![スクリーンショット (385).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/975701/6b431bf5-d72f-edf9-786c-3c613e38076f.png)

初期化が行われる前に引数に渡しても最初のinitブロックでは、初期化が行われないので注意が必要

<dl>
<dt>プライマリコンストラクタで処理できなかった内容を初期化</dt>
<dt>→Javaに比べてコンパクトに、コンストラクタに渡して処理ができるがコンストラクタに渡せないものも出てくるので、initブロックにその処理を書いて初期化しよう</dt>
</dl>

参考記事→https://qiita.com/alt_yamamoto/items/f5df6434e122859f2d65




####今回は、これまで勉強してきた中でよく理解していなかったものを改めて復習してみました。
####引き続き勉強と開発を頑張ります。
RSGT2021 セッションメモ～開発者とスクラムマスターの兼任～

RSGT(https://2021.scrumgatheringtokyo.org)
で自身が参加したセッションのメモ&ふりかえりです。
ふりかえりの手法は、びばさんが配信しているPodcastである、ふりかえりAM ep.4(カンファレンス用のふりかえりをする例)で紹介されていたFun Done Learnを参考にしています。

# 概要
- Ryohei Sekiさん
- Day2(15:15～15:35)
- ソフトバンク社員が「情報革命で人々を幸せに」を実現するために、日々、邁進していることは言うまでもありませんが、我々、IT 本部は、いわゆる情報システム部門で、主に通信事業に必要な IT サービスを提供するためシステムを開発・運用している組織となります。
  ソフトバンクと言うと、フットワークの軽い、チャレンジングなイメージがあるかと思いますが、通信事業は皆さまの生活を支える重要なインフラですので、これまで堅牢、堅実なシステム開発が主流でした。一方で、我々 IT 本部では 2017 年から、アジャイル開発に取り組んできており、これまでにいくつかの成功と挫折を乗り越えて現在に至っています。
  私が所属しているスクラムチームは、プロダクトオーナー1人、開発者4人、開発者兼スクラムマスター4人という構成になっています。
  開発者兼スクラムマスターは 4 人のうち 3 人は最近スクラムマスターの資格を得たばかりで、実際に業務として開発者とスクラムマスターを兼任しているのは 1 人です。
  開発者とスクラムマスターを兼任することは賛否両論ありますが、実際に開発業務を行う中で得られた知識や感想、兼任することの利点、欠点について紹介していこうと思います。
  開発者とスクラムマスターを兼任している方と共感していただいて互いによりよいチームを作るためのきっかけになればいいなと思っています。

# 気になった内容メモ
- チーム構成 : LEVEL3(SCRUM MASTER THE BOOK)のスクラムマスター+PO+開発者兼スクラムマスター3人+開発者3人
- 開発者とスクラムマスターを兼任したい理由
  - 若手の育成(スクラムマスターを担う若手が出てきて欲しい)
  - スクラムマスターを若手が担うと、開発力がつかない...
  - 同期で溝を生みたくない(スクラムマスターにAさんは任命されたのにBさんは任命されていない...)
  - なるべく多くの人がスクラムを知っている状態にしたい
- 開発者とスクラムマスターを兼任するメリット
  - 業務に関与できるので信頼が得られやすい
  - チームの弱点を見れる
- 開発者とスクラムマスターを兼任するデメリットと対応
  - スクラムマスターの責務を全うできない
    - LEVEL1(SCRUM MASTER THE BOOK)であれば全うできる
    - LEVEL3は厳しい…
  - チェンジマネジメントのスキルを欠く
    - チーム内の開発者兼スクラムマスターの人と協力している
  - チームの能力向上に気が回らない
    - 学ぶ方向性を決める。レベル指標の定義
- やってみた感想
  - スクラムマスターと開発者を兼務するのはLEVEL1相当であればチームは問題なく回る
  - ただ、スクラムの知識が足りていないことは実感

# 楽しかったこと
- 新卒二年目でカンファレンスでこれだけの内容発表していて刺激になった

# やったこと
- アウトプットを意識しながら話を聞いた

# 学び
- スクラムマスターと開発者を兼任するメリットデメリットが再確認できた。
- コンテキストが違うと思うので一概にすべて鵜蜷桙ﾝにはできないが、実際に兼任してみた感想を聴くのは貴重な機会だと思うので、話が聴けて良かった(いわゆるアンチパターンなので、中々実験する人が少ない)
windowsでiverilog その82

#概要　

windowsでiverilogやってみた。
4bitのcpu書いてみる。


#サンプルコード

```


module cpu4(input clk, input rst, input [3:0] inport, output reg [3:0] outport);
	reg [3:0] a,
		b,
		pc;
	reg [7:0] mem[14:0];
	wire [7:0] code;
	wire [3:0] op;
	wire [3:0] opland;
	assign code = mem[pc];
	assign op = code[7:4];
	assign opland = code[3:0];
	always @(posedge clk, negedge rst)
	begin
		if (!rst)
		begin
			mem[0] <= 8'h51;//out 1
			mem[1] <= 8'h52;//out 2
			mem[2] <= 8'h54;//out 4
			mem[3] <= 8'h58;//out 8
			mem[4] <= 8'h66;//ifajmp 6
			mem[5] <= 8'h2f;//jmp f
			mem[6] <= 8'h54;//out 4
			mem[7] <= 8'h52;//out 2
			mem[8] <= 8'h51;//out 1
			mem[9] <= 8'h41;//ifbjmp 1
			mem[10] <= 8'h00;//add 0
			mem[11] <= 8'h00;//add 0
			mem[12] <= 8'h00;//add 0
			mem[13] <= 8'h00;//add 0
			mem[14] <= 8'h00;//add 0
			a <= 4'h0;
			b <= 4'h0;
			pc <= 4'h0;
		end
		else
		begin
			case (op)
			4'h0://add
			begin
				a <= a + opland;
				pc <= pc + 1;
			end
			4'h1://lda
			begin
				a <= opland;
				pc <= pc + 1;
			end
			4'h2://jmp
			begin
				pc <= opland;
			end
			4'h3://ldb
			begin
				b <= opland;
				pc <= pc + 1;
			end
			4'h4://ifbjmp
			begin
				if (inport[1] == 1)
					pc <= opland;
				else
					pc <= pc + 1;
			end
			4'h5://out
			begin
				outport <= opland;
				pc <= pc + 1;
			end
			4'h6://ifajmp
			begin
				if (inport[2] == 1)
					pc <= opland;
				else
					pc <= pc + 1;
			end
			4'h7://eqjmp
			begin
				if (a == b)
					pc <= opland;
				else
					pc <= pc + 1;
			end
			endcase
		end
	end
endmodule

module test;
	reg clk,
		rst;
	reg [3:0] inport;
	wire [3:0] outport;
	cpu4 u(.clk(clk), .rst(rst), .inport(inport), .outport(outport));
	initial
	begin
		$monitor("%b", outport);
		clk = 0;
		rst = 1;
		inport = 4'h0;
		#2
			rst = 0;
		#2
			rst = 1;
		#30
			$finish;
	end
	always
		#1
			clk = ~clk;
endmodule




```

#実行結果

```


xxxx
0001
0010
0100
1000



```


以上。
CakePHP3でパスワードチェックが必要になった

#要約すると
DefaultPasswordHasherクラスのcheck()メソッドで照合する。


#序章
CakePHP3で作成したサイト。
例えばパスワードの変更時に、現在のパスワードをチェックしたいときー（©551）
下記の風味ののページを作りたい、と。

![abcd.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/241095/01d8b13e-fc2a-6a92-a380-af257fa65493.jpeg)

んで、このときに、どうやって現在のパスワードのチェックを行えばよいのでしょうか？ってなったんですよ。

###条件
・ユーザー登録時に、DefaultPasswordHasher->hash()しています。
・現在のパスワード欄にあるinputのnameは、old_passwordだとします。

#混迷期
あ、そうか。
ログインのところでやってるわ。

```php
$this->Auth->identify();
```

の1行で処理されてる？？
IDとパスワードをPOSTしたら、この1行でデータベースと照合してくれるの？？
マジ簡単。

でも、俺がやりたいのはそういうことじゃない。

#一筋の光明
ググる。ググる。くくる（それはたこ焼き屋）。
そしてたどり着いた。

また、__DefaultPasswordHasher__のcheckメソッドを使うんだねグーグル先生！？じゃなくて、記事書いた人！ありがとう、丸パクりする！！

#成果物
controllerにこんな感じで書いた。
モデルでどうとかいう記事があったけど、俺にはそんな高尚な処理書けない！
MVCモデルが破綻してるけど気にしない！って豪胆な性格の人はどうぞ。

```php
// クラスの先頭の方で
use Cake\Auth\DefaultPasswordHasher;

～中略～

// 元のパスワード。ハッシュ化されているもの
$db_password = DBからパスワードを取ってくるメソッド();
// 入力された現在のパスワード
$inputed_password = $this->request->getData('old_password');

$hasher = new DefaultPasswordHasher();

// パスワードが一致してたらtrueが返る！
return $hasher->check($inputed_password, $db_password);

～後略～
```

できてよかった。
Regional Scrum Gathering Tokyo 2021 Day 2 「プランニング会議は実験室 ！チームと顧客に支えられるスクラムマスターの日々の試み」

# Regional Scrum Gathering Tokyo 2021 Day 2 「プランニング会議は実験室 ！チームと顧客に支えられるスクラムマスターの日々の試み」

202/01/07に開催されたRegional Scrum Gathering Tokyo 2021での発表です。
https://confengine.com/regional-scrum-gathering-tokyo-2021/proposal/14791

# チーム参加してきました

[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム7人で参加して、その場で実況しつつ、記事も作っています。

# CI＆Tの通常のプランニング会議 
1チームの1SprintのキャパシティをBurnという。

# CI＆T通常の日々のメトリックス
開発チームは毎日進捗を確認
BCP（Business Complexity Points）はソフトウェアの複雑性を計る単位
両方一緒に監視することで、時間の消費とストーリが完了していることを管理できる。

両方のチャートが同時に下がるのが理想で、チャートが下がっていない場合はチーム内で分析を行う。

# 突然の提案
上司から違うやり方（**日にち単位プランニング**）でプランニングを行っているチームがブラジル本社にいるとお話しを聞かされた。
当初は難しいように感じたが、ブラジル本社の方のレクチャーを聞き、興味がわいてきた。改善点が面白いと感じた。

# 変更の承認
やり方をビデオ会議で学び、参加していたプロジェクトのPMとチームにお話しをした。
チームも実行できると自信がついた後に顧客の承諾を得た。

# 新しいプランニング会議
プランニング会議の参加者はかわらず実施。

- スクラムマスター
- アーキテクト
- 開発者
- テスター

JiraやSpredsheetを活用しながら実施した。
顧客にも資料を共有し、コメントをもらったり遅延の説明がスムーズになったりという効果があった。

# 新しいメトリクス
時間だけじゃなく、タスクのバーンダウンチャートを追加。
新しいタスクにも時間がかかる・かからないタスクがあるので、メトリクス、スプリントロードマップを見ながらチームと会話してスプリントの状況確認を行った。


# 変更後どうなったか
- 「タスクが遅延してるのは誰、なぜ？」から「チームはなぜこのストーリーのデリバリーが遅れたか」に変化した
- 「正確な見積もりを出す、納期を守る」→「品質の良いシステムを作る」というマインドセットの変化があった
- 日々のコミュニケーションが改善された
- 決まった時間内でこのタスクを完了できないならSMやアーキテクトに声をかけ、チームで解決策を探した
- 時間単位だと詳細にチームを監視できるが、日にち単位はSMと連携しないと遅れてるように見える場合がある
- チームとPMとPOとの信頼関係がないとできない手法


チームとしても日付単位の見積もりがよい、というFBをくれた。


# 実験結果
1時間単位 vs 1日単位の見積もりそれぞれメリット・デメリットがあり、チームにあうやり方を探すのが大切。

レクチャーの中で印象に残った言葉。
> 「プロセスはツールであり、すべて解決してくれる魔法ではない」

アプリケーション全体を見られるようになった、チームのモチベーションがあがった、という様々なプラスの効果が得られた。問題へのアプローチを変えて、チームの姿勢を変えられた。

> どんなプロジェクトでも、状況に適したルートを選び、チームをガイドすることがスクラムマスターとしてのチャレンジ


# 感想
- 長く続けたやり方を変えるというのは勇気のいることだと思いますが、チームによりあった方法をとる決断、実験をしていて結果を出しているのがすごいなと思いました。
- 実験を行うことは、変化を生む起点になると感じました。
- プランニングの手法については、あまり今まで実験したことがなかったと思うので、これからいろいろ試してもいいのかなと思うことができました。
HerokuでPGBackupsを使う

# はじめに
Herokuでデータベースのバックアップを取るコマンド、PGBackupsを使ってみる。
使い方は公式サイトにそのままあるので、ご参考下さい。
https://devcenter.heroku.com/articles/heroku-postgres-backups

# 環境
Rails 5.2.4.2
Vagrant + Ubuntu 16.04.5 LTS

# やってみた事
Herokuにログインします。

```
$heroku login --interactive
```

バックアップ対象のアプリ名を確認します。

```
$heroku apps
```

アプリ名を指定して、手動でバックアップを取ります。

```
$heroku pg:backups:capture --app アプリ名
```

ステータスを表示して、バックアップが取れている事を確認する。手動で取ったバックアップの場合、ダンプファイルにはbで始まるIDが付番され、スケジューラから作成されたバックアップには、aで始まるIDが付番されるようです。タイムスタンプは9時間の時差で表示されるので注意。

```
$heroku pg:backups --app アプリ名
```

ここで、Webアプリを立ち上げて、適当にデータを更新してみます。この後、リストアしてデータが元に戻っている事を確認します。

バックアップファイルをリストア（復元）します。b002を指定していますが、バックアップを取ったIDになります。プロンプトが出てくるので、アプリ名を入力する事になります。

```
$heroku pg:backups:restore b002 --app アプリ名
> アプリ名を入力する
```

Webからアプリを立ち上げて、先ほど、適当に更新したデータが元に戻っている事を確認します。

作成したバックアップダンプは削除しておきます。

```
$heroku pg:backups:delete b002 --app アプリ名
> アプリ名を入力する
```

再び、ステータスを表示して、IDがb002のバックアップダンプが削除されている事を確認します。

```
$heroku pg:backups --app アプリ名
```

Herokuからログアウトして終了。

```
$heroku logout
```
Regional Scrum Gathering Tokyo 2021 Day 2 「# Regional Scrum Gathering Tokyo 2021 Day 2 「アジャイル戦略論 「チーム作りの巻」～すべての基礎はチーム作りにあり。 」

202/01/07に開催されたRegional Scrum Gathering Tokyo 2021での発表です。
https://confengine.com/regional-scrum-gathering-tokyo-2021/proposal/14776

# チーム参加してきました

[aslead Agile](https://aslead.nri.co.jp/solution/aslead_agile.html) のチーム「[オキザリス](https://speakerdeck.com/viva_tweet_x/huesudeyong-qi-wode-taxin-gui-timugashi-yan-wozao-rifan-sitejin-nizhi-rumadefalsewu-yu?slide=3)」にて参加してきました。
チーム7人で参加して、その場で実況しつつ、記事も作っています。

発表資料は[こちら](https://speakerdeck.com/yosuke_matsuura/agile-strategy-team-building?slide=7)です。

# チーム作りの６つのプロセスと本セッションの流れ
1. 一人目の仲間を作る
2. 話し合いながらアウトプットする
3. ものの置き場を確保する
4. 成果をアピールする
5. やったことをふりかえる
6. 技術的負債を解消する

# 成果の上がるチームを作り、長期に存続させるには
- 継続的なカイゼン文化
- 信頼関係の構築
- 成功体験の積み上げ


# よくあるチームづくりの誤解
アジャイルチームを作ったが定着せず苦労

# 一人目の仲間を作る
現在取り組んでいる仕事がある中でどのようにして時間を作れるか？
→昼休みを活用（ランチョンテクニック）

「他人と過去は変えられないが、自分と未来は変えられる」

## Before
社内イベントはROM線

## After
積極的に参加

**押し売りでは継続的な関係は難しい**

## 関係性の構築が一番目の重要ポイント
一緒に仕事がしたいと思ってもらえるような日々の行動と言語化
- コンセプト
- ビジョン
- 目的
- メリット


# 成功循環モデル
**Bad Cycle**
結果が出ないところからスタートすると関係の質やモチベーションがダウンする

**Good Cycle**
関係性を構築するところからスタート　→　関係性もモチベーションもアップしケイン説的な議論につながる

失敗含めた経験からカイゼンのサイクルを回すのが重要


# 室の探求
- WF
	- はじめから100点を目指す
- アジャイル
	- 早いフィードバックサイクルをもとに質を向上していく


# 新規事業を総シュルするときのアイデアの出し方のTips
- Step.1 たくさんアイデアを出す
- Step.2 カテゴライズ
- Step.3 投票（自分たちの価値観を元に投票基準を決める）

皆の納得感が大切
単純に多数決ではなく、皆の納得度を共有しつつ決めていく

# 準備８割を心だける
準備を制するものは仕事を制する


# ランチ会で工夫したこと
最新情報を収集できる環境を整えた。
実例：最新の技術情報サイトへのアクセスを会社で制限されていた　→　申請を通してアクセス可能に！


# 簡単に話せる３つのコツ
- 否定禁止
- 笑顔でうなずく
	- 安心感を生み出す
- プラストーク
	- 明るい言葉が明るい空気を作る

Tips: サンクストーク、最初はありがとうから始める


# 人は自分への関心が一番強い　→　拡張話法を活用
- 感銘の表現
- 反復
- 感情を込めて理解を示す
- 相手を評価する
- 相手の話を中心に展開させていく


# 整頓の基本は見える化
オフラインなら壁がおそらく最強
オンラインなら環境や教育に投資が重要。よりよいアウトプットから成果を出せる

## 三定
- 置く場所を決める
- 置く量を決める
- 置くものを決める
トヨタ生産方式内で

## ワーキングアグリーメントをつくる
継続的に実行できるルールをチームメンバー全員で作ることがポイント
実はアジャイルチームの最初の支援としてものの置き場やワーキングアグリーメントを決めることがよくある。

# 期待されている成果を事前に確認する
状況や立場によって期待は変わる。目的"Why"から始めるのが大事。"What"から始めがちだが、見失ってしまう。

## SMARTな設定目標
Specific
Measurable
Achievable
Realistic
Time-bound
小さな成功体験を積み重ねることで、少しずつ周りを味方につけていく。最終的には経営層も。

## 定量的・定性的評価をもとに継続的に改善する
ブランディングKPIから始め、最終的に営業KPIにつなげていく。
スモールスタートが大事。



# やったことをふりかえる

ふりかえりとは過去を棚卸してそこから得られた気づきをもとに今後へ活かすこと 

心理的安全性を高める
- 感謝を伝える
- 平等に意見を言えるようにする
- 間違えても大丈夫

## ファシリテーターのミッション
会議やミーティング参加者の学びの最大化

**Tips: 全員が話してから対話に入る**


# 技術的負債を解消する
## よくある話
技術的負債を理解していないと、チームの持続が難しくなっていく。
関係者にトレードオフの理解と合意を求めておくのが重要。
トレードオフスライダーを用いるなどして可視化するのがポイント


## 継続的に健康状態を計測
健康状態を継続的確認する。
ビジネスサイドの方には、可視化やコスト換算した影響を説明すると技術的負債の返済に理解してもらいやすい。


# まとめ

成果の上がるチームを作り、長期に存続させるには
- 継続的なカイゼン文化
- 信頼関係の構築
- 成功体験の積み上げ

# 感想
- ポイントが端的にまとめられている内容でわかりやすかったです。
- 特に成功体験の積み上げは大切で、スタートが悪いとその後のモチベーションも上がりづらいというのは共感しました。
iOS14.3のiOSシミュレータでNavigationBarが黄色くなってしまう場合の対処方法

追記（2021/3/1）

Xcode 12.4以降でこの症状は解消されています
https://developer.apple.com/documentation/xcode-release-notes/xcode-12_4-release-notes

```
iOS simulated devices no longer display an incorrect yellow tint in translucent UI elements. 
Certain GPUs may continue to display the tint with some tvOS simulators. (71203015)
```



# 問題点

iOS14.3のiOSシミュレータでiOSアプリをビルドして起動すると、NavigationBarなどの表示が本来は半透明のところが黄色くなってしまいます。
全体の雰囲気がわからなくなるので元にもどしたい。

## スクリーンショット
<img width="200" alt="iOSSimulator" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5497/7d3f62fd-c2a5-4a7e-9ea3-b08fdd608f36.png">


# 対処法

1. iOSシミュレータのメニューからGPUの設定を変更する
  - 変更前 [File] -> [GPU Selection] -> [Automatic]
  - 変更後 [File] -> [GPU Selection] -> [**Prefer Integrated GPU**]
2. iOSシミュレータを再起動する

![スクリーンショット 2021-01-07 14.35.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5497/bcfcbec2-39d6-9aee-c0b4-9be607d8371a.png)


# 変更後

- 下記のスクリーンショットのように元の半透明に戻っていることが確認できます

## スクリーンショット

<img width="200" alt="iOSSimulator" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/5497/274f078b-f5de-684b-f6be-23358238b265.png">


参考URL
https://stackoverflow.com/questions/65299337/xcode-12-3-ios-14-3-simulators-yellow-dock-yellow-translucent-issues
XAMPPでPHP8からPHP7へバージョンを下げる

#XAMPPでPHP8からPHP7へバージョンを下げる

###使用環境
* XAMPP 8.0 (PHP 8.0)
* windows10

##背景
PHP7で開発していたLaravelアプリを別のPCで(PHP8)でも開こうと思ったら開けない！composer installがエラーになった。どうやらPHPのバージョンが違うぞ！と怒られたっぽい。ということでPHPをダウングレードすることにした。

##XAMPPのApacheは消しておく
起動したまま操作しない方が良いみたい。

##PHP7をダウンロードする
公式ページからPHP7をダウンロードする。今回、使用したのは**VC15 x64 Thread Safe (2021-Jan-05 18:10:24)**というファイル。
[PHPダウンロード](https://windows.php.net/download#php-8.0)

##XAMPP内のPHPディレクトリをバックアップする
コピーでもOKなのですが、私はディレクトリ名を**PHP → PHP8**に変更した。

##ダウンロードしたPHP7のディレクトリをPHPディレクトリとしてXAMPPディレクトリ内に移動
PHPディレクトリを新しく作って、その中に解凍したPHP7関連のファイルを全て放り込む。

##PHP8で使用していたphp.iniをPHP7(PHPディレクトリ)にコピー
コピーしてそのまま使用。

##ApacheのPHP設定を編集する
```C:\xampp\apache\conf\extra\httpd-xampp.conf``` 内のPHP8と書かれているところを全てPHP7に変換。

##Apacheを起動
と思ったら、Apacheが起動しない！！！！
シャットダウン時に予期せぬエラーが発生した...みたいなことが書いてある！？
嫌な予感。MySQLが起動しないパターンでXAMPPを再インストールした過去があるのですごく嫌な予感。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/b0359c2b-f39d-63e2-604c-b9d515ea95dc.png)

##PHPのバージョン確認してみる
コマンドプロンプトで```php -v``` を入力してみる。
エラーが発生。なんかファイルが無いっぽいことをいってる。

```
PHP Warning:  Cannot open 'C:\xampp\php\extras\browscap.ini' for reading in Unkno
wn on line 0

Warning: Cannot open 'C:\xampp\php\extras\browscap.ini' for reading in Unknown on
 line 0
PHP Fatal error:  Unable to start standard module in Unknown on line 0

Fatal error: Unable to start standard module in Unknown on line 0
```

よくわからないけどPHP8のディレクトリに
```xampp\php\extras\browscap.ini``` があったのでコピーしてPHP7の```xampp\php\extras```に置いてみた。
###もう一度バージョン確認

XAMPPのshellを起動して```php -v``` と入力すると、きちんとPHP8からPHP7にバージョンが変わっている。

##さぁ、Apacheの起動だ
と思ったら、再度エラー。起動しない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/615830/b0359c2b-f39d-63e2-604c-b9d515ea95dc.png)


調べていくとコンパイラとか違ったら設定ファイルとか使いまわせないみたいなことが出てきた。
さらに調べてみるとどうやらSAPIモジュールというものが変更されているらしい。

##Apache2Handler
>PHP モジュールの名前が php7_module から php_module に変更されました。
[PHP公式ドキュメント](https://www.php.net/manual/ja/migration80.other-changes.php)

ということで
```xampp\apache\conf\extra\http-xampp.conf``` 内の**php_module**と書かれているところを**php7_module**に変更。全部で4か所あった。

正直、どれが作用しているのかはわからない。


##3度目の正直、Apacheの起動
今回は無事、起動できた。
Pythonで学ぶアルゴリズム　第15弾：並べ替え（選択ソート）

# #Pythonで学ぶアルゴリズム< 選択ソート >

##はじめに
基本的なアルゴリズムをPythonで実装し，アルゴリズムの理解を深める．
その第15弾として選択ソートを扱う．今回からしばらく並べ替えについてのアルゴリズムを学ぶ．

##なぜソートのアルゴリズムを学ぶのか？
・ライブラリの利用が一般的だが，その**実装を知ることは大切**
・ソートの考え方は**ほかのプログラムを作るにあたって参考になる**部分が多い
・ループや条件分岐，リストの扱い，関数の作成，再帰呼び出しといったプログラミングの基本を学べるだけでなく，**計算量の比較やその必要性を示す理想的な問題**
・それぞれの処理はシンプルで，実装にそれほど時間がかかるわけでもなく，**実用的なプログラム**である

##選択ソート
リストの中で最小値を探し，その最小値と先頭の場所を入れ替える．続いて，2番目を基準として，先頭を除いた最小値を探しまた入れ替える．これを繰り返すことで，昇順(小さいもの順)に並べ替えることができる．そのイメージ図を次に示す．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/951300/b5d8c881-43f1-4e96-8c42-d694a49961d3.png)
上図のように，最小値と入れ替える基準を変えていくことで，昇順に並べ替えができることが分かる．

##実装
先ほどの手順に従ったプログラムのコードとそのときの出力を以下に示す．

#####コード

```python:select_sort.py
"""
2021/01/07
@Yuya Shimizu

選択ソート
"""

def select_sort(data):
    """選択ソート：自分よりも小さな値と場所を入れ替えて，昇順に並べ替える"""
    for i in range(len(data)):
        Min = i     #入れ替え対象をセット
        for j in range(i+1, len(data)):
            #セットした値よりも小さな値があれば，その位置を最小値として記録
            if  data[j] < data[Min]:
                Min = j
        #いまの位置と最小値を入れ替え ⇒ 結果，左から小さい順に並ぶ
        data[i], data[Min] = data[Min], data[i]
        
    return data     #並べ替えを終えたデータを返す

if __name__ == '__main__':
    DATA = [6, 15, 4, 2, 8, 5, 11, 9, 7, 13]
    sort = select_sort(DATA.copy())     #後に比較するため，リストが変更されないようにcopyしたものを引数にする

    print(f"{DATA}  →  {sort}")
```

#####出力
```
[6, 15, 4, 2, 8, 5, 11, 9, 7, 13]  →  [2, 4, 5, 6, 7, 8, 9, 11, 13, 15]
```

ちゃんと昇順に並べ替えられていることが分かる．
今回は並べ替える前後での比較をしたいがために，あえて``sort``という変数に結果を格納し，さらに関数への引数は``DATA.copy()``というようにcopy関数により，引数に影響が出ないようにしている．並べ替えるだけなら，そのような操作は必要でなく，``select_sort(DATA)``とすればよい．


##選択ソートの計算量
最後に計算量について触れる．
1つ目の最小値を探すには残りの$n-1$個の要素との比較が必要で，同様に2つ目，3つ目では，$n-2$回，$n-3$回の比較が必要になる．したがって，全体での比較回数は$(n-1) + (n-2) + ... + 1 = \frac{n(n-1)}{2}$となる．$\frac{n(n-1)}{2} = \frac{1}{2}n^2 - \frac{1}{2}n$となるが，$n$が大きくなると第1項に対して第2項は十分小さく無視できるため，**計算量はオーダー記法で表すと，$O(n^2)$**となる．


##感想
特に難しいことはなく，今までの復習も併せてできそうだと感じた．今回は並べ替え1つ目選択ソートということで他との比較はできないが，これから学ぶほかの並べ替えアルゴリズムが楽しみであり，士気が高められる．また，オーダー記法についても慣れてきた気がする．

##参考文献
Pythonで始めるアルゴリズム入門　伝統的なアルゴリズムで学ぶ定石と計算量
　　　　　　　　　　　　　　　　　　　　　　　　 増井 敏克　著　　翔泳社
iOS14.4のIDFAまとめ

iOS 14.4
Xcode Version 12.3 (12C33) で検証

# 結果

| OS | isAdvertisingTrackingEnabled | trackingAuthorizationStatus | uuidString |
|:-----------:|:------------:|:------------:|:------------:|
| iOS13 | true | - | 取得できた |
| iOS13 | false | - | 00000000-0000-0000-0000-000000000000 |
| iOS14.4 | true | notDetermined | 取得できた |
| iOS14.4 | false | denied | 00000000-0000-0000-0000-000000000000 |
| iOS14.4 | true | authorized | 取得できた |
| iOS14.4 | true | denied | 00000000-0000-0000-0000-000000000000 |

# その他注意点

- isAdvertisingTrackingEnabled = false の場合 iOS14以降でもアラートが表示されずに denied 扱い
- requestTrackingAuthorization の completion は、アラートが表示されなくても呼ばれる
- アラートで選択肢を選ばずに無理やり電源を切った場合は denied 扱い
- restricted はよくわかりませんでしたが denied と同じ扱いで良さそう？
- isAdvertisingTrackingEnabled の値が iOS14 でもちゃんと取れるようになってるっぽい
- 今の所アラート出さないほうがIDFA取得できちゃいそう...
- ただ短い期間で動きが変わりがちなので安心できない...

# 備考

- iOS14.2とiOS14.4で調べましたが同じ挙動でした(2021/01/07)
- 使用コード

```swift
        if #available(iOS 14, *) {
            print(ATTrackingManager.trackingAuthorizationStatus)
        } else {
            // Fallback on earlier versions
        }
        print(ASIdentifierManager.shared().isAdvertisingTrackingEnabled)
        print(ASIdentifierManager.shared().advertisingIdentifier)
```
Python の nan チェック

# TL;DR

`a is np.nan` じゃなくて `np.isnan(a)` を使おう。

# nan

nan (Not A Number) です。nan「数値」じゃなくて、その比較についてはIEEE754で定義されています。これは何と比較しても等しくならない。`nan == nan` すら`False` です。Python の場合、`math.nan` と `np.nan` があります。(他にもあるかも知れないけれど。)

# 一部で流通している誤解: 「`a is np.nan` でチェックできるよ」

`a` が `nan` の場合、`a == np.nan` ではチェックできません。なぜならば上述のとおり、IEEE754でそう決められているから。で、どうするかと言うと、いくつかのサイトでは `a is np.nan` とすればいいよ、とあります。確かに多くの場合これでうまく行くのですが、これはどうやらnumpyやmathの実装上、**たまたまうまく行く(同一のnanオブジェクトを参照するようになっている)ことが多い** だけのようで、基本的に間違ったチェック方法と断じたいと思います。

というわけで反例。

```Python
# 以下は Python 3.91 + numpy 1.19.4 で試しました。math の nan でも基本的に同じです。
import numpy as np
a = np.nan
b = a * 2
print(a)             # => nan
print(b)             # => nan
print(a is np.nan)   # => True (これがよく使われる。これはok)
print(b is np.nan)   # => False (こういうことが起こる。)
```

`nan` に対して演算をしてしまうことはありますよね？ その結果はやはり(当然?) `nan` です。ここで `is` で比較をしてしまうと、参照先が異なるようで `Flase` になってしまいます。だから **`a is np.nan` は(nan かどうかのチェックとしては)誤り**。

# 正解は？

素直に `np.isnan()` を使うのが良いでしょう。わかりやすいし。定義を逆手に取った裏技(?)として自身との比較 `a == a` (が `False` だったら `nan`) というのもあるのですが、混乱するのでぼくは遠慮しときます。

# 悪者は誰か？ (個人の感想です。あまりツッコまないでください。)

Python です（バッサリ）。`is` なんてモノを導入したのが諸悪の根源だと。こういう「直観的な機能が曖昧なbe動詞」に「参照先の比較」という大切な働きをさせるから混乱が生じる。さらに悪いことに、`is` の式は読みようによっては（意味を勘違いしたままでも）英文的にわかりやすいので広まっちゃう。`is` なんかなくたって、`id()` があるんだから、それ使えば簡潔・正確・誤用防止といいことづくめなのに…。
Java - Jersey Framework vs Spring Boot


# Annotation differences

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/150367/4f583ac6-e1bc-7b10-4359-a7025665bdbb.png)


https://stackoverflow.com/questions/42944777/difference-between-jax-rs-and-spring-rest
https://stormpath.com/blog/jax-rs-vs-spring-rest-endpoints
AWS CloudShell上にfdcloneをビルドしてインストールする


AWSでも2020/12からCloudShellが利用できるようになりました。
あくまでリモートShell環境であって、標準でインストールされているツール等は少なめです。

初期状態では開発環境や居城として利用するには少し不便ですが、
ここではfdcloneをビルドしてインストールする方法を紹介します。

## gccとncursesライブラリのインストール

fdcloneのビルド＆実行には以下の３つの追加インストールが必要です。


* **gcc(fdcloneのビルドに必要)**
* **gcc-core(fdcloneの実行に必要)**
* **ncurses-devel(fdcloneの実行に必要)**

初期状態ではインストールされていませんが、yum で追加インストールすることができます。

```
[cloudshell-user@ip-10-XX-XX-XX ~]$ sudo yum install gcc
[cloudshell-user@ip-10-XX-XX-XX ~]$ sudo yum install gcc-core
[cloudshell-user@ip-10-XX-XX-XX ~]$ sudo yum install ncurses-devel
```

## fdcloneのソースをダウンロード


* **FDclone なページ - Vector**<br>
https://hp.vector.co.jp/authors/VA012337/soft/fd/

から、ソースファイル一式を入手します。wgetでダウンロードしましょう。

```
[cloudshell-user@ip-10-XX-XX-XX ~]$ wget https://hp.vector.co.jp/authors/VA012337/soft/fd/FD-3.01j.tar.gz
```

ダウンロードが終わったら、ファイルを解凍し、カレントディレクトリを移動します。

```
[cloudshell-user@ip-10-XX-XX-XX ~]$ tar zxvf FD-3.01j.tar.gz 
[cloudshell-user@ip-10-XX-XX-XX ~]$ cd FD-3.01j
```

## fdcloneのビルド

fdcloneをビルドします。ビルドが終わったら``fd``が生成されているか確認しておきます。

```
[cloudshell-user@ip-10-XX-XX-XX FD-3.01j]$ sudo make
...
...
[cloudshell-user@ip-10-XX-XX-XX FD-3.01j]$ ls -al
[cloudshell-user@ip-10-XX-XX-XX FD-3.01j]$ ls -al fd
```

## fdcloneの起動確認

ビルドに成功し、``fd``が生成されているようでしたら、起動できるか確認しましょう。

```
[cloudshell-user@ip-10-XX-XX-XX FD-3.01j]$ ./fd
```

## fdcloneのインストール

make installします。(/usr/local/binにコピーされます。）

```
[cloudshell-user@ip-10-XX-XX-XX FD-3.01j]$ sudo make install
```

## ~/.fd2rcの配置

また、必要に応じて、_fdrc を ~/.fd2rc にコピーしておきます。
必要に応じてカスタマイズしておいてください。

```
[cloudshell-user@ip-10-XX-XX-XX FD-3.01j]$ cp -p _fdrc ~/.fd2rc
```
Ansible Tower ユーザの追加

## 1. Ansible Tower にログイン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/3b733c39-0e47-6f92-356d-606cb67ce2ff.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/2eed978a-1d6e-f698-940e-30607e1d4094.png)

## 2. ユーザ
左のメニューから「ユーザ」を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/80720855-ea2b-f7e0-a31a-f1d9c2e50849.png)

## 3. 新規ユーザの追加
右上の＋ボタンを選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/097cd441-2228-6790-5302-26e7f7ea8e89.png)

## 4. ユーザ情報の入力
フォームにユーザ情報を入力し、保存を選択する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/1ffc5420-1064-eae5-3645-fca4269a076b.png)

## 5. ユーザ一覧
正常に登録されると、中央下のユーザ一覧に登録したユーザが表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/d375d3db-1aaf-70d3-4842-5fc785e4984f.png)

## 6. ログアウト
画面右上の電源マークよりログアウトする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/6df60d11-dba1-b775-1c45-97f8ea25c6b1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/797fa244-4bdd-c14d-321d-2325938a3012.png)

## 7. 登録ユーザでログイン
登録したユーザでログインしてみる
正常にログインできると、以下のような画面が表示される
- 一般ユーザのログイン後画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/7c772088-231e-9034-5448-9130a025f8e2.png)
- 監査ユーザのログイン後画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/c925416d-6d9a-60be-b2c6-fa9aa7835a24.png)
- 管理者ユーザのログイン後画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/658425/1e236fc9-4a21-653f-a1be-030d90da76e9.png)
chsh -s /usr/local/bin/fish をするな



（予防策は @nitaking さんからです🙇‍♂️🙇‍♂️）

# 要約

- fishの導入記事で`chsh -s /usr/local/bin/fish`が紹介されてるけどけっこう危ない
- 誤って`brew uninstall fish`とかやるとshellが使えなくなる（なった）
- mac標準のターミナルやiTerm2でシェル指定ログインが可能なので、そこから入って再インストールした
- デフォルトがbashの場合、.bash_profileの最後で任意のシェルにログインするコマンドを入れておき、デフォルトは変えない方が良い


（OS: MacOS Catalina 10.15.7）

## やらかしの顛末🐟
インターン入社初日、支給されたMacの環境構築に勤しんでた際、brewでインストールしたmysqlやredisのバージョンをいったん変える必要があったため、`brew uninstal ~~~`をやっていたときにやらかしが発生。

fishを使い始めて日が浅かったこともあり、Tabキーでサジェストを適用できるのが便利で無駄にペシペシしていたところ、いつの間にか`brew uninstall fish`が入力されており、それに気付かぬままEnter。気づいた時にはすでに何も実行できない状態になってました。
適当にググって見つけた記事で紹介されていた`chsh -s /usr/local/bin/fish`で、**デフォルトのログインシェル自体をfishに変更していた**ため、各種ターミナルは起動したそばからログイン失敗→プロセス終了。コマンドが打てなきゃログインシェルも変えられない、といった感じ

以下、解決した方法と予防策について書きます。

## 解決策: Mac標準ターミナルやiTerm2でログインシェルを指定して開く

今回の問題を解決した方法です。
#### Mac標準ターミナルの場合
ターミナルを開き、 
**[環境設定]→[一般]**
に入って**「開くシェル」をコマンド（完全パス）で指定（例: bash→`/bin/bash`）**したのち、新規ウィンドウ/タブを開く

#### iTerm2の場合
**[Preference]→[Profile]**
で、**Commandを「Custom Shell」**に変更、任意のシェルでログインする設定にした上で、新規ウィンドウ/タブを開く

## 予防策: .bash_profileで立ち上げ時に都度シェルを変更する

fishの導入について書かれている記事では、chshコマンドを使ってログインシェルをfishに変更しているものが少なくありません。

```bash
$ chsh -s /usr/local/bin/fish
```

しかし、以下のような理由でfishが使えない場合、コマンドが叩けない事態に陥ります。

- fishを誤ってuninstallした場合（今回のやらかし）
- installしたfishがうまく動かないのを確認せずchshを叩いた場合

その場合は後ほど示すやり方で違うシェルを開くことができるのですが、**デフォルトシェルは変えずに.bash_profileにてターミナルのセッション立ち上げ時に都度fishへ変更する**ことで、fishに入れない場合でもデフォルトシェルのまま続行できます。

```bash
echo exec fish >> ~/.bash_profile
```
or 

```bash
sudo nano ~/.bash_profile 
```

``` ~/.bash_profile
# ~既存の記述たち

# fish起動
fish
```

書き終えたら`^x`→`Y`で保存

`.bashrc`だと、bashへのログインに都度反応して記述内容の反映を行ってしまうため、`.bash_profile`に書き込みます

# おしまい
雑ですいません
入社初日に心臓潰すくらい焦った　なおせてよかった