OmniAICreator/Qiita-1.07M huggingface dataset:
CodeBuildのプロビジョニングフェーズでdocker pullの制限を回避する

こんにちは
株式会社Diverseで働いている@python_spameggsです
[Diverse Advend Calendar 2020](https://qiita.com/advent-calendar/2020/diverse)の初日になります
CodeBuildのプロビジョニングフェーズでdocker pullの制限でエラーになってしまうことが多くなってきたのでSecrets Managerを使用して解決しました

# CodeBuildのプロビジョニングフェーズでのエラー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27949/5fab1ed8-b541-7422-8e52-f6de547d9933.png)

* このようにエラーになってしまいます
* プロビジョニングフェーズでのエラーなのでbuildspecにdocker loginを設定しても意味がないので別の方法で回避します

# Secrets Managerを使う
* シークレットの種類は「その他のシークレット」を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27949/7a2fc09d-bfb9-e1cc-7696-7afcce08a7e6.png)

* キーは`username`と`password`で値はdockerhubのユーザ名とパスワードになります
    * 暗号化キーは使いたいものを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27949/4dc53379-f750-e1a6-9df8-fde93c5fc721.png)

* 次に進んでシークレットの名前と説明を入れます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27949/89e7ced3-a866-1415-ec09-2757225a6a10.png)

* 次に進んでシークレットの自動ローテーションを設定します
    * 設定は無効にする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27949/ae5babe6-786d-b992-8832-b0d4979503bc.png)


* 後はレビューして問題なければ保存して作成したシークレットを選択して詳細を見ます
![スクリーンショット 2020-11-30 11.39.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27949/b2c8cc5e-21fe-480f-ded0-a199d2d065d9.png)
* シークレットのARNをコピーします
    * ↑で作ったシークレットの名前と違います、sampleです

# CodeBuildへ
* ビルドプロジェクトのビルドの詳細から環境の項目を編集します
* イメージを上書きを選択すると↓の項目が出てくるので先程コピーしたシークレットのARNをペーストします
    * 残りの空いている項目は今まで通りのものを入れて環境の更新をしてください
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/27949/bf359551-c3e2-e3b2-2afe-a459d91af0bf.png)
* これで完了ですので再度ビルドしてエラーにならないことを確認しましょう

# aws-cliで更新する

### Secrets Managerに登録
```secret.json
{
	"username": "dockerhubのユーザ名",
	"password": "dockerhubのパスワード"
}
```
```
aws secretsmanager create-secret --name dockerhub --secret-string file://secret.json
```

### CodeBuildの更新をする
* 現在の設定を取得する

```
aws codebuild batch-get-projects --names プロジェクト名 > project-info.json
```

* project-info.jsonにSecrets ManagerのARNを追加する

```
  "registryCredential": {
    "credential": "作成したSecrets ManagerのARNを入れる",
    "credentialProvider": "SECRETS_MANAGER"
  }
```

* プロジェクトを更新する

```
aws codebuild update-project --cli-input-json file://project-info.json
```

* これで完了です

# おわり
これでCodeBuildを使うたびにdocker pullの制限でエラーになってしまうことを回避することができました

明日の2日目は@masashi-sutouさんになります！
あまり知られていないGoのスライス/配列の初期化

## 初めに
先日、[こちらの動画](https://www.youtube.com/watch?v=elGjixFQLYE&t=1054s&ab_channel=mercaridevjp)で見たことがない配列の初期化をしていたので、それについてわかったことを解説してきます。

## 配列の初期化
動画のほうでは次のような配列宣言をしていました。

```go
package main

var array = [...]int{0, 4:1, 2, 1:1}

func main() {
	println(len(array))
}
```

一般的な配列やスライスの宣言は以下のパターンがあると思います

```go
var slice1 = []int{1, 2, 3, 4}
var slice2 = make([]int, 1, 4)
var array1 = [10]int{1, 2, 3, 4}
var array2 = [...]int{1, 2, 3, 4}
```

これらはよく見かけるパターンですが、`{0, 4:1, 2, 1:1}`というのは見たことがなく、どう読めばよいのかわかりませんでした。
これについて[Hajime Hoshi (星一)](https://twitter.com/hajimehoshi)さんに教えていただきました。結論からいうと以下の処理と同じことをしています。

```go
var array = [6]int{}
array[1] = 1
array[4] = 1
array[5] = 2
fmt.Println(array)
```

## 解説
配列、スライスではインデックスを指定して値をセットできます。
つまり`{0, 4:1, 2, 1:1}`は、`0`番目に`0`、`4:1`は`4`番目に値`1`、`5`番目に`2`、`1`番目に`1`をセットしています。
これは構造体の初期化時にフィールドを指定できるのと同じです。

```go
gorilla := Animal{Name: "gorilla", Age: 28}
```

## 最後に
普通にGoを書いていたらこのような書き方は使わないんですが、構造体の初期化と同じ理屈と考えるとすごく腑に落ちます。
Go、奥が深い。。
Firebase Hosting＋Cloud Functionsでリクエストのドメインを取る方法



## 問題設定

例えば、Firebase Hostingでこれらのドメインをホストしていたとしよう。
一番上が自分で用意したドメインで、下二つはFirebaseがくれたドメインだ。

- example.com
- example.web.app
- example.firebaseapp.com

example.web.appをexample.comにリダイレクトしたいことがある。
これをCloud Functionsで実装することにする。

ところが、Cloud Functionsで受け取るHttp RequestオブジェクトはhostがCloud Functionsのホストになっている。
なので、if (req.header("host") === "example.web.app") ... などと書いてもダメなのだ。

## 結論

x-forwarded-hostを使おう。

```functions.ts
  if (req.header("x-forwarded-host") === "example.web.app") {
    res.redirect(301, "https://example.com/");
    return;
  }
````
Vim　Macで改行に置換させる方法。文字コードとファイルフォーマットの視点から。

改行に置換するとき、`\r`か`^M`を使用する
`Ctrl + v return`を押すと`^M`を入力することができる。
検索の場合は`\n`を入力する。

以下の2つは同じこと

```
:%s/,/,\r/g

:%s/,/,^M/g
```

検索の場合と置換の場合で、改行に該当する文字コードがことなるのは、文字コードの定義と、ファイルフォーマットの定義が異なるから。

## 改行コードは処理系定義

OS|記号|ASCII|プログラム上
---|---|---|---
Windows | \<CR>\<LF> | 0A0D | \r\n
Linux | \<LF> or ^@ | 0A | \n
Mac | \<CR> or ^M | 0D | \r

## 文字コード、ファイルフォーマットの確認方法

vimの編集中に以下のコマンド

### 文字コードの確認

`:set enc?`

### ファイルフォーマットの確認

`:set ff?`


## 参考

[vimで改行への置換を行うには\r、改行を置換するには\nを用いるのは何故か - rohaniのブログ](https://rohani.hatenablog.com/entry/2018/11/30/194604)
なぜRigidbodyオブジェクトをTransformで移動させてはいけないのか

こんにちは。ソウタロウです。
今回は私が駆け出しゲームエンジニアだった時（数年前）にハマった、UnityにおけるRigidbodyオブジェクトの移動制御について書こうと思います。
###単語の定義
弊社は定義するのが好きという話を小耳にはさんだので、まずは本記事に出てくる単語の定義から記載します。

- Rigidbodyオブジェクト：Rigidbodyコンポーネントをつけたオブジェクト

以上

#本記事の概要
UnityではRigidbodyコンポーネントをオブジェクトにつけることで簡単に物理演算が可能になります。
重力、スリープ状態の閾値等のパラメータが簡単に設定できるのでとても便利なのですが、オブジェクトの移動制御に関して、注意しなければならない点があります。
本記事では、Rigidbodyオブジェクトの移動を`transform`で制御してはいけない理由を解説していきます。

#Rigidbodyオブジェクトを`rigidbody.position`で移動させた場合
まずは正しく動作するパターンを紹介します。Rigidbodyコンポーネントをつけた球体に坂を上らせてみましょう。
添付動画のように、意図した挙動で移動を制御できています。
スクリプトは下記のとおりで、Dキーを押しています。

```hoge.cs
void FixedUpdate(){
         if (Input.GetKey(KeyCode.D))
             rb.position += new Vector3(0.15f, 0, 0);
     }
```

![ezgif.com-video-to-gif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920122/792ab449-c650-792a-2fc3-9ad9a200566d.gif)


#Rigidbodyオブジェクトを`transform.position`で移動させた場合
次に、右矢印キーを押して坂を上らせてみましょう。
坂にめり込んでしまっていますね。前述のスクリプトを見ても、意図した挙動でないのは明らかです。
![ezgif.com-video-to-gif-2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/920122/0f48c646-8d1e-6053-42a1-c878b4e719b0.gif)

```hoge.cs
void Update () {
         if (Input.GetKey(KeyCode.RightArrow))
             this.transform.position += new Vector3(0.15f, 0, 0);
     }
```

#なぜめり込んでしまうのか
上記のgifでそれぞれの挙動が異なることは理解できたかと思います。
では、なぜ`transform.position`だとめり込んでしまうのか。
答えは [Unityのスクリプトライフサイクルのフローチャート](https://docs.unity3d.com/ja/2018.4/Manual/ExecutionOrder.html)を読むと分かります。
本記事に関連する部分のみ抜粋すると、「FixedUpdate内の物理演算」→「Update内の演算」→「レンダリング」の順で処理されるイメージです。

つまり、Rigidbodyオブジェクトを`transform.position`で移動させた場合、物理演算が走る前にレンダリングされているということです。
コライダー同士が重なった場合の座標の修正が行われる前にレンダリングされているので、坂にめり込んでしまっていたのですね。

#まとめ
Rigidbodyオブジェクトはrigidbodyを使ってFixedUpdate()内で制御しましょう（例外あり）。

###あとがき的なもの
初めてアドベントカレンダーに参加し、初めてQiitaに投稿しました。大変ではありましたが、私用PCを数か月ぶりに開いて、Unityを起動したときのワクワクは新鮮なものがありました。この機会をくれた同期に感謝です。
ゲーム創りは楽しいことばかりではありません。勉強しなければいけないことが本当にたくさんあります。
現在、私はゲームプランナーとしてゲーム創りをしていますが、プランナーとエンジニアという分野は違えど、本記事が多くのゲームクリエイターの役に立てばと思います。
より良いゲームをたくさん創って、より多くの人にゲームの素晴らしさを届けたいですね。

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
この記事を読んで「面白かった」「学びがあった」と思っていただけた方、よろしければ Twitter や facebook、はてなブックマークにてコメントをお願いします！
また [DeNA 公式 Twitter アカウント @DeNAxTech](https://twitter.com/DeNAxTech) では、 Blog記事だけでなく色々な勉強会での登壇資料も発信してます。ぜひフォローして下さい！
<a href="https://twitter.com/DeNAxTech?ref_src=twsrc%5Etfw" class="twitter-follow-button" data-s>
messaging apiで勤怠管理botを作った。


#はじめに
実家の会社ためにLINEのMessaging APIを使って勤怠管理botを作りました。

#なぜ作ったか
* 最初は給与計算アプリを作ろうと思ったが、勤怠記録の情報がないとそもそも計算できないと気づいた。
* 実家の会社では祖母が手動で給与計算をしているが、最近計算間違いが多くなった。
* LINEのMessaging APIであれば、誰でも簡単に使用できると思った。
* 作成期間：約2週間

#開発環境
* 開発言語
    * Ruby
* フレームワーク
    * Ruby on Rails
*  データベース
    *  sqlite3
*  使用技術等
    *  Linter
        *  rubocop
    *  Ngrok
    *  Messaging API

#基本機能
* ユーザーごとの出勤・退勤時間の登録
ユーザーごとにその日の出勤時間・退勤時間を登録できます。
既にその日の出勤時間を登録してる場合と、出勤時間を登録せずに退勤時間しようとしても登録できないようにしています。
![出勤時間2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784464/1b50ee94-fc2a-7016-c731-a981e40f39a1.gif)

* 今日の勤務記録の修正
勤務記録はその日の記録のみ修正可能です。
出勤時間が登録されていない場合は修正は不可能にしています。
![修正２.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784464/0ca2cafc-9162-2a89-d219-c13b1c267b2b.gif)

* 今日・今月・先月の勤務記録の参照
勤務記録は今日・今月・先月の記録が参照可能です。
記録がない場合は記録なしと表示します。
![確認２.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/784464/62cce7b7-8f7e-36ae-836f-958a960d039f.gif)

#検討している追加機能・改善点
* 退勤時間の登録し忘れ防止機能(時間指定メッセージでいけると思う)
* 早出や残業などの区別(実家の会社ではよほどのことがない限りいらないかも)

#作った感想
Messaging APIを触るのは初めてだったが、思ったよりも簡単な記述で幅広い機能の実装が可能ということがわかった。
LINEが非常に一般的なツールなので、ユーザーの敷居も低く、ユーザーフレンドリーなbotを簡単に作れる点は非常に素晴らしいものだと感じた。

#今後について
今回は、最初は給与計算アプリを作ろうと思ったが、勤怠管理が必要ということで勤怠管理botの作成に至った。今後はこのbotで集めた記録を元に給与計算を作ろうと思っている。
Local by Flywheel の Open Site Shell が使えない時の解決方法

## 概要

Mac BigSur あるいは、M1 Chip の Mac が原因なのか、Open Site Shell でターミナルが開けない場合の解決方法。

- [Localコミュニティで示された解決方法](https://localwp.com/community/t/open-site-shell-not-working-macos-big-sur/22270/12)

なお、上記のURLでは、Localを開発している人が回答しているので、詳しく知りたい人はどうぞ。

## 原因

Macのセキュリティか何からしい。

- macOS BigSur (v11.0)
- Local5.9.3+5100


## 解決方法

ターミナルを開いて、以下のコマンドを実行

```zsh
find ~/Library/Application\ Support/Local/ssh-entry/*.sh -exec grep -H 'echo -n -e' {} \; | sed -E 's/^(.*):.*;(.*)Shell\\.*/\2 @ "\1"/' | column -s '@' -t
```

実行結果に、Local のサイト名と .sh (シェルスクリプト）のリストが出る。

```zsh
toilib2     "/Users/takame/Library/Application Support/Local/ssh-entry/XXXXXXXX.sh"
```

このスクリプトを実行すると、LocalのWordPress（Docker?）にログインできる。なお、Applications Supportの間のスペースをエスケープするために、`\` を入れ忘れないように！

```zsh
/Users/takame/Library/Application\ Support/Local/ssh-entry/XXXXXXXX.sh
```

## しばらく解決しないかもしれないので、エイリアスに登録

.zshrc に以下のように登録する

```zsh

# --- Local by Flywheel ---

# list local shell script path
alias lwp-list="find ~/Library/Application\ Support/Local/ssh-entry/*.sh -exec grep -H 'echo -n -e' {} \; | sed -E 's/^(.*):.*;(.*)Shell\\.*/\2 @ \"\1\"/' | column -s '@' -t"
alias lwp-toilib='/Users/takame/Library/Application\ Support/Local/ssh-entry/XXXXXX.sh'
```

`lwp-list` コマンドで、シェルスクリプトのリストを表示。表示されたものを順次、alias で、簡単にログインできるようにする。

以上です
ひとりでふりかえりをするための様々な「観点」

# この記事について

[ふりかえりAdvent Calendar 2020](https://adventar.org/calendars/5249)の企画の最初の記事になります。
今回は、12月にこれからふりかえりをするために役に立つ、ふりかえりの「観点」をいくつか紹介したいと思います。

# 12月にひとりでふりかえりをするということ

12月。1年の最後の月でもあり、来年から気持ちを新たに始めるための、気持ちを切り替えるために重要な1か月でもあります。
ふりかえりをすると、これまでの学びや気づきをまとめて「成長」として実感できるほか、次の年の目標も立てやすくなります。
是非、この機会にふりかえりをしてみませんか？

[ふりかえりAdvent Calendar 2020](https://adventar.org/calendars/5249)では、まだまだ記事を募集しています。文章は少なくて大丈夫です。ふりかえってみてどうだったか、どう感じたか、という感想だけでも構いませんので、是非ふりかえってみましょう。

これまでふりかえりになじみがなかった人も、記事にしなくても構いません。この機会にふりかえりを一度やってみてください。

# ふりかえりをするための観点

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/221788/595d153c-dd1b-86bc-242e-2a94c65a750f.png)

ふりかえりをするための観点をいくつか紹介します。
ひとりでふりかえりをすると、自分が得意な観点のみでのふりかえりになりがちで、なかなか思い出しやアイデアが広がりにくくなりがちです。
ここで紹介する観点を1つか2つ取り入れてみて、普段の自分にはない観点も追加したうえでふりかえりを進めていきましょう。

代表的な観点を以下のように分類しました。MECE（抜け漏れなくダブりなく）ではないのでご了承ください。

- 1. 事実
    - 1-1. 成功
    - 1-2. 失敗
- 2. 感情
    - 2-1. 感情
- 3. 学び
    - 3-1. 学び
    - 3-2. 気づき
- 4. 時系列
    - 4-1. 過去
    - 4-2. 現在
    - 4-3. 未来
    - 4-4. 理想
    - 4-5. ギャップ
- 5. 視点
    - 5-1. 立場
    - 5-2. 主観
    - 5-3. 客観
- 6. 情報
    - 6-1. 定量
    - 6-2. 定性

## 1. 事実

実際に身の回りで起こった出来事を思い出します。
5W1Hを合わせて思い出してみるとよいでしょう。

- Who：誰か、誰とやったか
- What：何か、どんなことか、何がおこったか
- Where：どこか
- When：いつか
- Why：なぜか、どうしてか、
- How：どのようにしたか

### 1-1. 成功

うまくいった事実を思い出してみましょう。

- うまくいったこと
- 成功したこと
- 何かのきっかけになったこと
- よい変化が起こったこと
- 継続してできていること
- ヒヤッとしたけどなんとかなったもの

### 1-2. 失敗

うまくいかなかった事実を思い出してみましょう。

- うまくいかなかったこと
- 失敗したこと
- ミスしたこと
- しくじったこと
- 「しまった」と思ったこと
- 人に責められたこと

## 2. 感情

事実と合わせて、感情も考えてみると良いでしょう。

### 2-1. 感情

- 嬉しい、楽しい、面白い、わくわくする
- 凄い、いいな、憧れ、羨ましい、感謝したい
- 悲しい、つらい、ストレスがたまる、
- 怒った、嫌な、うんざりした、げんなりした

## 3. 学び

他の情報から学びや気づきを抽出してみましょう。

### 3-1. 学び

- 学んだこと
- 血肉になったこと
- 他の人に伝えたいこと
- やってみたいと思えること
- マネしたいと思えること

### 3-2. 気づき

- 気づき
- 小さな気づき
- ふと思ったこと
- 疑問に思ったこと
- ひっかかったこと

## 4. 時系列

時系列を使ってに情報を集めてみましょう。

### 4-1. 過去

- 長い時間をかけて行ってきたこと
- 印象に残っていること

### 4-2. 現在

- 1年前、半年前、3か月前、1か月前、1週間前、昨日との違い
- 今継続して行っていること
- 行わなくなったこと

### 4-3. 未来

- やりたいこと
- 挑戦したいこと
- 明日、1週間先、1か月先、3か月先、6か月先、1年先の予想

### 4-4. 理想

- 理想
- なっていたい状態
- 避けたい未来

### 4-5. ギャップ

- 過去と現在のギャップ
- 過去と未来のギャップ
- 現在と未来のギャップ
- 予想される未来と理想のギャップ

## 5. 視点

視点を変えると、思い出せる内容や思いつくアイデアにも変化が起こります。

### 5-1. 立場

立場を変えて、その人になり切って考えます。
「その人だったらどう感じるか」「その人はどう行動したか」など。

- チームメンバー
- リーダー、マネージャー
- 上司
- 同僚
- お客様
- ユーザー
- 親友
- 家族

### 5-2. 主観

自分から見えていた情報を思い出します。

- 自分はこう思った
- 自分はこう感じた

### 5-3. 客観

他人から（広く）見えていた情報を思い出します。

- 自分はこう見えていた
- 自分はこう思われていた

## 6. 情報

情報の性質を分けて考えます。
定量/定性の2つを使い分けるとよいでしょう。

### 6-1. 定量

- どのくらい、どれほど
- 具体的な数字

### 6-2. 定性

- どのように
- どんな

# おわりに

いかがでしたでしょうか。様々な観点を組み合わせて、是非、この機会にふりかえりを始めてみてくださいね。
node.jsとserverlessでローカル環境のコードをlambdaにアップする

## はじめに
node.jsで作成したアプリをサーバーレスで動かしたい。

## 環境
node.js v12.18.2

## Lambda関数の作成

#### ディレクトリ作成
```
mkdir serverless-node-sample
cd serverless-node-sample
```

#### npmの初期化
```
npm init
```


#### Serverlessのインストール
```
npm install serverless --save
```

#### Serverlessの動作確認
バージョン確認

```
sls -v
```

以下のように表示されればOK

```
Framework Core: 2.13.0 (local)
Plugin: 4.1.2
SDK: 2.3.2
Components: 3.4.2
```

#### Serverlessのテンプレート生成
今回はnode.jsを使うので `aws-nodejs`を使用、他にも[pythonやruby用のテンプレート](https://www.serverless.com/framework/docs/providers/aws/cli-reference/create/)が用意されている
コマンド実行後、`handler.js` `serverless.yml` `.gitignore`が生成される

```
serverless create --template aws-nodejs
```

#### ディレクトリ構成の確認
確認

```
ls -a
```

きっとこうなっているはず

```
.                       .gitignore              node_modules            package.json
..                      handler.js              package-lock.json       serverless.yml
```

### ローカルでの動作確認

今回のメインファイルとなる`handler.js`の中身を確認。
うまくいけば`Go Serverless v1.0! Your function executed successfully!`が表示するはず。

```javascript

'use strict';

module.exports.hello = async event => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: 'Go Serverless v1.0! Your function executed successfully!',
        input: event,
      },
      null,
      2
    ),
  };

  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
  // return { message: 'Go Serverless v1.0! Your function executed successfully!', event };
};
```
早速コマンドから実行する。
sls invoke はデプロイされた関数を呼び出すコマンド、sls invoke localにしてあげると、ローカル環境で関数を呼び出す。

```
sls invoke local --function hello
```
おお、表示された

```
Serverless: Running "serverless" installed locally (in service node_modules)
{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Go Serverless v1.0! Your function executed successfully!\",\n  \"input\": \"\"\n}"
}
```

### AWSにアクセスするための設定
AWSにアクセスするコマンドを叩く。
`aws_access_key_id` `aws_secret_access_key`はお手持ちのAWSアカウントから取得してもらえれば。

```
serverless config credentials --provider aws --key aws_access_key_id --secret aws_secret_access_key
```

##### 補足：IAM ユーザーのアクセスキーとクレデンシャル情報の取得
AWSマネジメントコンソールの「サービスを検索する」という入力欄で「IAM」と入力すればIAMダッシュボードのページに飛びます。ページアクセス後はサイドバーのアクセス管理のタブからユーザーをクリック。あとはユーザーを追加して新しくアクセスキーを作成するもよし、既存のユーザーから取得するもよし。（[詳しくはこちら](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html#Using_CreateAccessKey)）

#### AWSに関数をデプロイ
以下のコマンドでデプロイは完了
`region`オプションはAWSの東京リージョンにアップするよっていう指定をしてくれる。

```
serverless deploy --region ap-northeast-1
```

#### デプロイした関数を実行

```
sls invoke --function hello --data Hello --region ap-northeast-1
```

先ほどと同じ結果が帰ってきていればOK

```
{
    "statusCode": 200,
    "body": "{\n  \"message\": \"Go Serverless v1.0! Your function executed successfully!\",\n  \"input\": \"Hello\"\n}"
}
```

以上です、やったぜ。
continue,breakに関して(PHP)

<h1>continue,breakに関して</h1>

continueとbreakについてはそれぞれループ処理で使われる。<br>
continueはある特定の条件をスキップして、そのままループ処理を続ける一方で、
breakはある特定の条件でループ処理を中断する。

実際のコードと出力結果については以下の通りとなる。

<h2>continue</h2>

continueは特定の条件で、ループをスキップして、そのままループを続ける。

```
<?php
for ($i = 1; $i <= 10; $i++) {
  if ($i % 3 === 0) {
    continue;
  }
  echo $i . PHP_EOL;
}
?>
```

<b>出力結果<b>

```
1
2
4
5
7
8
10
```

iが３の倍数になる条件でスキップしていて、３の倍数以外で、1から10までの数が出力されている。

<h2>break</h2>

breakの場合はある特定の条件でループ処理が止まる。

```
<?php

for ($i = 1; $i <= 10; $i++) {
  if ($i === 4) {
    break;
  }
  echo $i . PHP_EOL;
}
?>
```

<b>出力結果<b>

```
1
2
3
```

iが４になった場合にループ処理が止まり、１〜３の数字のみ出力される。
Arduinoのcan't open deviceのエラー（Ultimaker Curaを開いていると発生）

#概要
タイトルのままですが，Ultimaker Curaを開いている状態ではArduinoの書き込みができなくなります．
原因の特定に時間がかかったので，共有します．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/a0976f81-0533-01ef-890c-93e24b7558bf.png)

```
avrdude: ser_open(): can't open device 
```
が
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405484/0f3db784-8248-1237-8253-faf7dc1f9b79.png)
を開いていると発生することに注意しましょう．
テーブルに存在しないデータを探す

以下のテーブルがある

````sql
select * from meetings;

+-----------+--------+
| meeting   | person |
+-----------+--------+
| 第１回    | 伊藤   |
| 第１回    | 坂東   |
| 第１回    | 水島   |
| 第２回    | 伊藤   |
| 第２回    | 宮田   |
| 第３回    | 坂東   |
| 第３回    | 宮田   |
| 第３回    | 水島   |
+-----------+--------+
````

meetingに出席しなかったpersonを取得する。

方法として、全員が解禁したと仮定した場合の集合を作り、
そこから現実に出席した人々を引き算する。

全員が解禁した場合の集合はクロス結合で作れる。

````sql
select
distinct
m1.meeting
,m2.person
from 
meetings m1 
cross join 
meetings m2

+-----------+--------+
| meeting   | person |
+-----------+--------+
| 第１回    | 伊藤   |
| 第２回    | 伊藤   |
| 第３回    | 伊藤   |
| 第１回    | 坂東   |
| 第２回    | 坂東   |
| 第３回    | 坂東   |
| 第１回    | 水島   |
| 第２回    | 水島   |
| 第３回    | 水島   |
| 第１回    | 宮田   |
| 第２回    | 宮田   |
| 第３回    | 宮田   |
+-----------+--------+

````

上記から実際の出席者の集合であるmeetingsテーブルに存在しない組み合わせに限定する。

````sql
select
distinct
m1.meeting
,m2.person
from 
meetings m1 
cross join 
meetings m2
where
not exists
(
    select
    *
    from
    meetings m3
    where
    m1.meeting = m3.meeting
    and m2.person = m3.person
)
order by
m1.meeting

+-----------+--------+
| meeting   | person |
+-----------+--------+
| 第１回    | 宮田   |
| 第２回    | 坂東   |
| 第２回    | 水島   |
| 第３回    | 伊藤   |
+-----------+--------+

````

こちらを参考にさせていただきました。
<a href="https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6SQL%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E7%AC%AC2%E7%89%88-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E3%83%9F%E3%83%83%E3%82%AF-ebook/dp/B07GB4CNKP/ref=sr_1_1?adgrpid=48836428930&dchild=1&gclid=Cj0KCQiA48j9BRC-ARIsAMQu3WSrZJJd4-psCT9_qj0w4f0_fuN9b3Rh3DD8mwgP9UkTOLLapCJzwJwaAsG_EALw_wcB&hvadid=338547693256&hvdev=c&hvlocphy=1009306&hvnetw=g&hvqmt=e&hvrand=10462958271481352436&hvtargid=kwd-335112034228&hydadcr=4076_10899478&jp-ad-ap=0&keywords=%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6sql%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8&qid=1605532234&sr=8-1&tag=googhydr-22">達人に学ぶSQL徹底指南書 第2版 初級者で終わりたくないあなたへ
</a>
Ansible Tips: dictionaryから全てのkeyを取得する

備忘




Ansibleにおいてdictionaryから全てのkeyを取り出すには .keys() か |dict2items|map(attribute="key")|list が使用可能

```yaml
- set_fact:
    foo:
      bar0: baz0
      bar1: baz1

- debug:
    var: foo.keys()

- debug:
    var: foo|dict2items|map(attribute="key")|list
```

↓

```
TASK [set_fact] *****************************************************************************************************
ok: [localhost]

TASK [debug] ********************************************************************************************************
ok: [localhost] => {
    "foo.keys()": [
        "bar0",
        "bar1"
    ]
}

TASK [debug] ********************************************************************************************************
ok: [localhost] => {
    "foo|dict2items|map(attribute=\"key\")|list": [
        "bar0",
        "bar1"
    ]
}
```

.keys()は追記
自分で書いていて忘れていたorz
https://qiita.com/hiroyuki_onodera/items/8de685fb64f62e8831f5
Rails findとfind_by


##findメソッド
findメソッドを使用すると、与えられたどのオプションにもマッチする 
`主キー(primary key)に対応するオブジェクト`を取り出すことができる
主キーを複数指定することも可能

###該当するものがない場合
該当するものがないと「エラー」
`ActiveRecord::RecordNotFound例外`が発生する

##find_byメソッド
与えられた条件にマッチするレコードのうち`最初のレコードの１件`だけを返す
検索条件は、主キーだけでなく他のカラム等でも検索することができる
検索条件は、複数指定することも可能

###該当するものがない場合
該当するものがないと「nil」を返す

##参考記事
https://railsguides.jp/active_record_querying.html
https://qiita.com/nakayuu07/items/3d5e2f8784b6f18186f2
https://pikawaka.com/rails/find_by
CloudFunctions+bootstrapでアイキャッチを作る


Twitterとかに投稿した時に表示されるアイキャッチ画像を自動生成したい。
しかし、画像処理とか段組の計算とかイロイロメンドクサイ。
bootstrapでいい感じにできないか試した結果突破できたので書き残す。

## 概要

まず、Cloud Functionsではpuppeteerが動いた。
ということは、HTMLで作れるものは大体画像として作れるということだ！
具体的には、node-html-to-imageというライブラリを使えばいい。


## 注意点

### フォント
まず、そのままだといわゆる中華フォントになる。

### 段組み
bodyのwidthの解釈など、色々ハマりどころが多い。
僕は中央寄せがしたいだけなのに！！
ということで、色々頑張った結果とりあえずまともに動くStyleを特定したので
特にこだわりなければこれをそのまま使ってくれたし。

### メモリ
puppeteerは動くが、そのままではメモリが足りなくてエラーになる。
メモリは多めに確保しておこう

### キャッシュ
当たり前だと思うけど、この処理は結構重い。
上手くキャッシュしよう。
Cloud Functionsは公開キャッシュが可能なので長めに設定しよう。
ここで、古いキャッシュがヒットしてしまわぬようにCloud FunctionsのURL設計を考えたい。
例えば、ユーザー名を表示するアイキャッチを作っていたとする。
この時、引数にユーザーIDを取りFunctionsのなかでDBを参照してユーザー名を表示するよりも、
Functionsの引数にユーザー名をとったほうがCDNフレンドリーだと思う。
ユーザー名の変更に追従する時のめんどくささがなくなるので。

## 成果物

```functions.ts
export const og = functions
    .runWith({
      memory: "1GB",
    })
    .https.onRequest(async (req: express.Request, res: express.Response) => {
      const userName = escape(req.query["user_name"] as string);
      const buffer = await createOg(userName);
      res.header("cache-control", "public, max-age=10000");
      res.write(buffer);
      res.end();
    });

const nodeHtmlToImage = require("node-html-to-image");

export async function createOg(
    userName: string,
): Promise<Buffer> {
  const res = (await nodeHtmlToImage({
    quality: 100,
    type: 'png',
    html: `<html>
<head>
<meta charset="utf-8">
<link href="https://fonts.googleapis.com/css?family=Noto+Sans+JP" rel="stylesheet">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>
<body style="width:700px; height: 500px;font-family: "Noto Sans JP;">
<div style="width:700px; height: 500px" class="bg-primary d-flex align-items-center">

<div class="card mx-auto" style="width: 600px;">
<div class="card-header">
<div class="card-subtitle h6">
<a class="text-dark" href="/">
${userName}さんは
</a>
</div>
</div>
<div class="card-body">
<div class="card-title h5">
今日のお昼ご飯は
<a class="text-dark" href="/">
<h1>豚の生姜焼き定食にしたい</h1>
</a>
</div>
</div>
<div class="card-footer">
と主張しています。
</div>
</div>
</div>

</body>
</html>`,
  })) as Buffer;
  return res;
}

// 
// http://localhost:5001/fam-song/us-central1/og?user_name=%E3%83%AA%E3%82%AF

```


![og.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100021/740fbf48-1b20-b8df-90c2-a66d33a4629d.png)
Progate jQuery中級編

初級編と違ってやはり、複雑になってきました。
Thisの扱いが難しいですね・・。
ただ、しっかりと動作した時はめっちゃ嬉しいですね！
うぉおおおお　すげぇえええ！ってなって心が踊ります。
変数がプログラミングのキーでもあり壁にもなっていくのでしょうか・・・。
道場はひっくり返るくらい難しいんだろうけど、玉砕してきます。
疎通確認が目的のタスク名には ping を入れるとわかりやすい

こんにちは、株式会社ベストティーチャーで元気に働く たわら です。業務駆け出しエンジニアです。

業務に駆け出すと、いろんな学びがあります。今回はpingです。

### とある日

```
先輩　「hogeサーバーから毎日何らかのデータを取ってくるrakeタスクを作ってほしい」
先輩　「諸事情で、通信すること自体が目的なんだ」
ボク　「ハイ！」
```

何とか実装して、タスク名を`request_to_hoge`としてプルリクを出すと、、、

```
先輩　「、、、何をリクエストしてるかわかりずらいですね、、、」
先輩　「後から参画するエンジニアにもわかりやすい名前にしよう」
先輩　「こういうときは ping を変数に入れるといいよ」
```

### ping って？？
対象のコンピューターときちんとつながっているかどうか、を確認するときに使用するコマンドのことです。

例えば、`Raspberry Pi`に`Ubuntu`を入れて、ネットワークを設定して、ホストマシン（Mac）側からssh接続するための前準備として、まず通信接続を確認するときなどに当該IPアドレスを指定して、`ping`コマンドを利用します。

この作業を疎通確認、と言います。

なので、変数に`ping`を入れると疎通確認を目的としたタスクだ、ということが示せます。

```
先輩　「ということで、ping_hoge という名前にしよう」
先輩　「これなら後から参画したエンジニアもタスクの意味が把握しやすいからね」
ボク　「ハイ！」
```

### 最後に
後から参画する方にわかりやすい名前をつける、という気づきがありました。
変数がわかりにくいとコールドリーディングにコストがかかってしまいます。
この瞬間だけではなくて、長い時間のなかでわかりやすい変数の名前をつけるのが大事なのですね。

### 参考文献
用語集「pingとは？」
https://www.cman.jp/network/term/ping/

pingとは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
https://wa3.i-3-i.info/word124.html

pingを知ろう - Qiita
https://qiita.com/masapiko/items/57d6d6f666ee0412383b
MySQL DBとテーブルとカラムの作成方法

# 目的

- ターミナルからMySQLにログインしてDB（データベース）とテーブル、テーブル内のカラムを作成する方法をまとめる

# 実施環境

- ハードウェア環境

| 項目 | 情報 |
| --- | --- |
| OS | macOS Catalina(10.15.5) |
| ハードウェア | MacBook Pro (13-inch, 2020, Four Thunderbolt 3 ports) |
| プロセッサ | 2 GHz クアッドコアIntel Core i5 |
| メモリ | 32 GB 3733 MHz LPDDR4 |
| グラフィックス | Intel Iris Plus Graphics 1536 MB |

- ソフトウェア環境

| 項目 | 情報 | 備考 |
| --- | --- | --- |
| MySQLバージョン | 8.0.19 for osx10.13 on x86_64 | Homwbrewを用いてこちらの方法で導入→[Mac HomebrewでMySQLをインストールする](https://qiita.com/miriwo/items/ef6a064bc545fbea29d9) |

# 前提情報

- 筆者はMacに直接MySQLを導入しターミナルからMySQLにログインして本記事の内容を検証した。
- MySQLへのログインはrootユーザを使用する。（MySQLのrootユーザのパスワードが分からなくなってしまった方はこちら→[Mac ローカル環境の MySQL 8.x のrootパスワードを忘れた時のリセット方法](https://qiita.com/miriwo/items/1880e9d2ebcfd3c0e60d）
- 今回作成するDBとテーブル、カラムの詳細を下記に記載する。
    - DB名: create_test
    - テーブル名: users 
    - カラム

        | カラム名 | データ型 |
        | --- | --- |
        | id | int |
        | name | varchar(255) |

# 概要

1. 準備
1. DBの作成
1. テーブルとカラムの作成
1. 確認

# 詳細

1. 準備
    1. 下記コマンドを実行してMySQLにログインする。

        ```terminal
        $ mysql -u root -p
        ```
1. DBの作成
    1. MySQLにログイン後下記SQLを実行してDBを作成する。（`create database DB名`とするとDBを作成する事ができる。）

        ```sql
        create database create_test;
        ```
    1. 下記SQLを実行して只今作成したDBを選択する。

        ```sql
        use create_test;
        ```
1. テーブルとカラムの作成
    1. 下記SQLを実行してテーブルとカラムを同時に作成する。

        ```sql
        create table users(
            id int, 
            name varchar(255)
        );
        ```
1. 確認
    1. 下記SQLを実行して出力されたテーブル名一覧にusersテーブルがあることを確認する。

        ```sql
        show tables;
        ```
    1. 下記SQLを実行して出力されたusersテーブルのカラムデータが前提情報に記載したものと一致しているか確認する。

        ```sql
        show columns from users;
        ```
簡易HTTPサーバーを起動する魔法のコマンドを軽くまとめてみた

# はじめに

とにかくHTTPサーバーを起動したい要望は時々発生します。
例えば、開発中のツールから生成したHTMLファイルをさくっとレンダリングしたいときや、CDNでjsをインクルードしたHTMLファイルをレンダリングしたりするときなどです。

しかし、この世は広い広い情報の海、適切な情報にぶち当たらないときがあります（先日の私みたいに）。そこで、このページでは、そんな悩みに即座に答えられそうなページを作ろうとおもいたったわけでございます。

# Node.jsの場合

vue.jsをCDNで取り込んだときの動作確認でお世話になりました

## インストール

```
npm install -g http_server # インストール時のみ
```

## 起動

```
http_server
```

参考：[node.js http-serverコマンドでwebサーバーを起動する](https://qiita.com/standard-software/items/1afe7b64c4c644fdd9e4)

# Python2の場合

10年ぐらい前、業務で生成したHTMLをどうやってプレビューしようと悩んでいたときに教えていただいたのがこれ。いやー、これは助かりました。

```
python -m SimpleHTTPServer <port>
```

参考：[pythonでローカルwebサーバを立ち上げる](https://qiita.com/okhrn/items/4d3c74563154f191ba16)

# Python3の場合

```
python -m http.server <port>
```

参考：[pythonでローカルwebサーバを立ち上げる](https://qiita.com/okhrn/items/4d3c74563154f191ba16)


# 最後に

…やっぱり世の中は広い。Rubyの場合のコマンドを調べてみたら先人がいらっしゃいました。素晴らしい世界！
上記の他に、Rubyとかでも例が載っておりますのでぜひご参照ください。

[ワンライナーWebサーバを集めてみた](https://qiita.com/sudahiroshi/items/e74d61d939f18779970d)
1-nの関連モデルでnのデータを取得する場合は1のモデルから取ろうという話

# 前提
※Railsでの話ですが、他のライブラリにも同じことが言えると思います

以下のモデルがあります
User
UserPost
※1-nの関係

以下のURLがあります

```
/posts # 自分の投稿一覧を取得
/users/:user_id/posts # user_idの投稿一覧を取得
```

# Controllerの処理
/postsの例

```ruby
UserPost.where(user_id: @current_user.id)....
```
こんな感じでやったりする人がいますが、これはだめです。
こうしましょう

```ruby
@current_user.user_posts...
```

UserPostからとるようにすると、なんかの手違いでwhere条件を消してしまったりして、userの条件が外れる可能性があります。
userからとるようにしておけば、必ずそのユーザーで絞り込まれるので、その事故を防ぐことができます

/users/:user_id/postsの例も理由は同じです

# 結論
必ず親側のモデルからデータをとるようにするクセをつけるといいと思います
Ruby on Rails ビューで検証エラーに対応する



<h1>ビューで検証エラーに対応する</h1>

登録画面のフォーム部分が次のようになっている場合

```ruby:app/views/tasks/_form.html.slim

= form_with model: task, local: true do |f|
  .form-group
    = f.label :name
    = f.text_field :name, class: 'form-control', id: 'task_name'
  .form-group
    = f.label :description
    = f.text_area :description, rows: 5, class: 'form-control', id: 'task_description'
    = f.submit nil, class: 'btn btn-primary'
```

ここにはまだ検証エラーメッセージを表示する部分がない。
form_withの上に、エラーメッセージを表示するための領域を作りたいので次のように編集。

```ruby:app/views/tasks/_form.html.slim

- if task.errors.present?
  ul#error_explanation
    - task.errors.full_messages.each do |message|
      li = message

= form_with ...

```

上記のコードは、errors_present?を使って検証エラーの有無を調べエラーがある時にエラーメッセージを表示するようにしている。
[PHP] エラー解決 gyp: No Xcode or CLT version detected!

laravelに必要なnpmをインストールをすると 

```
gyp: No Xcode or CLT version detected!
```

というエラーが出たのでそれの解決方法を投稿いたします。
今回はXcodeというAPPをアンインストールをして解決した方法になります。
下記はエラー画面のスクショになります。
![“スクリーンショット” 2020-11-30 12.03.07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/698439/1074ac38-037d-2b22-0b94-57f5c8babde4.jpeg)

#解説

`gyp: No Xcode or CLT version detected!`
これは「XcodeとCLTのバージョンがおかしい」というエラー内容でした。
私自身、Xcodeは暫く使うことはないのでアンインストールを実行したいと思います。

```
//ターミナルにて上から一つずつ実行する
sudo rm -rf /Applications/Xcode.app
sudo rm -rf /Library/Preferences/com.apple.dt.Xcode.plist
sudo rm -rf ~/Library/Preferences/com.apple.dt.Xcode.plist
sudo rm -rf ~/Library/Caches/com.apple.dt.Xcode
sudo rm -rf ~/Library/Application Support/Xcode
sudo rm -rf ~/Library/Developer/Xcode
sudo rm -rf ~/Library/Developer/CoreSimulator
```

無事にアンインストールはできました。しかし、npm installを実行すると

```
(省略)
found 2 vulnerabilities (1 low, 1 high)
  run `npm audit fix` to fix them, or `npm audit` for details
(省略)
```
という脆弱性が見つかりました。次回にて脆弱性が問題なので[こちら]も投稿します。
次の記事のURLは[こちら]になります。
[こちら]:https://qiita.com/yutarou/items/518e422ec71641e86034
MATLABのシンボリック計算

# はじめに

MATLABには，数値計算だけでなく文字式の処理も行うシンボリック計算機能がついている．
これはSymbolic Math Toolboxが必要になる．

# 文字式の定義

この文字はシンボリックですよと宣言する．

```matlab
    syms a b c
    syms x y
```

# 文字式の計算

MATLAB文法で書ける．

```matlab
    z = a*x + b*y + c
```

新たに`z`という変数が定義されたが，これはシンボリック変数から定義されたので，これもまたシンボリック変数として扱われる（`syms z`が必要ではない）

# 線形代数の演算

行列計算も得意．
まず，適当な行列$A$とベクトル$b$を用意しておく．

```math
    A = \begin{bmatrix}
        a_{11}    & a_{12}  & a_{13}\\
        a_{21}    & a_{22}  & a_{23}\\
        a_{31}    & a_{32}  & a_{33}
    \end{bmatrix},\quad
    B = \begin{bmatrix}
        b_{11}    & b_{12}  & b_{13}\\
        b_{21}    & b_{22}  & b_{23}\\
        b_{31}    & b_{32}  & b_{33}
    \end{bmatrix},
```
```math
    b = \begin{bmatrix}
        b_{1}\\
        b_{2}\\
        b_{3}
    \end{bmatrix},\quad
    c = \begin{bmatrix}
        c_{1}\\
        c_{2}\\
        c_{3}
    \end{bmatrix}.
```

要素をシンボリック変数として定義し，行列とベクトルを作る．書き方は通常のMATLAB構文と同じ．

```matlab
    syms a11 a12 a13 a21 a22 a23 a31 a32 a33
    syms b11 b12 b13 b21 b22 b23 b31 b32 b33
    syms b1 b2 b3
    syms c1 c2 c3
    A = [a11, a12, a13; a21, a22, a23; a31, a32, a33];
    B = [b11, b12, b13; b21, b22, b23; b31, b32, b33];
    b = [b1; b2; b3];
    c = [c1; c2; c3];
```


## 加減算

```matlab
    b + c   % ベクトルの加算
    b - c   % ベクトルの減算
    A + B   % 行列の加算
    A - B   % 行列の減算
```

## 乗算

```matlab
    2 * b       % ベクトルをスカラー倍
    2 * A       % 行列をスカラー倍
    A * B       % 行列同士の乗算
    A * b       % 行列とベクトルの乗算
    b.' * A * c % 二次形式（.'で転置を表す）
    dot(b,c)    % ベクトルの内積
    cross(b,c)  % ベクトルの外積
```

転置は`a'`ではなく`a.'`で表されることに注意しよう．

### 逆行列

逆行列は`inv(A)`で求められる．

```matlab
    inv(A)      % 単純に逆行列を求める
    inv(A)*b    % 逆行列とベクトルの積(1)
    A\b         % 逆行列とベクトルの積(2)
```

`inv(A)`を計算してからベクトル`b`にかけるよりも，`A\b`と書いたほうが計算が速いらしい．

# 方程式を解く

解ける方程式であれば，`solve(方程式，変数)`が根をシンボリックに返してくれる．

例：2次方程式

```matlab
    eq = a * x^2 + b * x + c;
    solve(eq, x)
```

結果は

```matlab
ans =
 
 -(b + (b^2 - 4*a*c)^(1/2))/(2*a)
 -(b - (b^2 - 4*a*c)^(1/2))/(2*a)
```

# 関数として保存

`matlabfunction`を使うことで，シンボリック計算の結果をMATLAB関数として保存できる．これでシンボリック計算と数値計算の橋渡しができる．

```matlab
matlabFunction(return_value,'file','filename','vars',{arg1, arg2, arg3});
```
Windows10をカスタマイズする前にしておくことのメモ

Windowsをカスタマイズする時にやっていることをまとめます。
#Administratorユーザーを追加
管理者権限を与えている状態でcmdかPowerShellで以下のコマンドを入力するとAdministratorユーザーを追加できます。

```
net user administrator /active:yes
```
##無効化する場合
やらかすと危ないので使わないときは無効化しておいた方がいいでしょう。

```
net user administrator /active:no
```

#レジストリの手動バックアップ
Microsoftは現在レジストリを復元する場合は復元ポイントを使用することを推奨しているようです。
「復元ポイントの作成」を開いて作成をクリックします。

他になにかあったら追記したり...
[Delphi] Android の Back ボタンでアプリを終わらせない方法

# Delphi 製 Android アプリ

Delphi で Android のアプリを作ると「バックキー」でアプリ終わっちゃうんだよね！

Android 使いなら解ってくれると思うけど、ホームキーはあんまり押さないで、バックキーを連打するじゃないですか！え、しませんか！？
で、バックキーを連打で終わらせると Delphi のアプリ、次に起動した時またスプラッシュから～！？となり割とイラッとするので、僕が作るアプリは基本終わらないようにしています。

# 終わらせないコード

* バックキーは [TForm.OnKeyUp](http://docwiki.embarcadero.com/Libraries/Sydney/ja/FMX.Forms.TCommonCustomForm.OnKeyUp) イベントで取得可能
* [Activity#moveTaskToBack](https://developer.android.com/reference/android/app/Activity#moveTaskToBack(boolean)) を呼ぶとアプリを裏に回す（ホームキーを押した時と同じ動作）

この２つを合せて↓下記の様にします。

```pascal
uses
  Androidapi.Helpers;

procedure TForm1.FormKeyUp(
  Sender: TObject;
  var Key: Word;
  var KeyChar: Char;
  Shift: TShiftState);
begin
  {$IFDEF ANDROID}
  if Key = vkHardwareBack then // Android バックキーの仮想キーコード
  begin
    // Key, KeyChar を 0 にしないとデフォルトの動作が呼ばれ Activity が閉じてしまう
    Key := 0;
    KeyChar := #0; 
    // アプリを裏に回す
    TAndroidHelper.Activity.MoveTaskToBack(True);
  end;
  {$ENDIF}
end;
```

実質たった８行だけで Activity が閉じなくなるので常に書いておくことをオススメします。
これで、アプリがメモリにある間は起動しても前回の続きから表示されます。

# 戻ってきたとき再描画させる

ただ、これだけだとたまに戻ってきたときにアプリの内容が表示されない（真っ白の画面が表示されるような状態）場合があります。
これを防ぐためには [IFMXApplicationEventService](http://docwiki.embarcadero.com/Libraries/Sydney/ja/FMX.Platform.IFMXApplicationEventService.SetApplicationEventHandler) を使います。
[TForm.OnCreate](http://docwiki.embarcadero.com/Libraries/Sydney/ja/FMX.Forms.TCommonCustomForm.OnCreate) などで設定しておくと良さそうです。

```pascal
uses
  FMX.Platform;

procedure TForm1.FormCreate(Sender: TObject);
begin
  var Service: IFMXApplicationEventService;
  if
    TPlatformServices.Current.SupportsPlatformService(
      IFMXApplicationEventService,
      Service
    )
  then
    // 下の AppEvent を登録
    Service.SetApplicationEventHandler(AppEvent); 
end;

function TForm1.AppEvent(
  iAppEvent: TApplicationEvent;
  iContext: TObject): Boolean;
begin
  Result := False;

  case iAppEvent of
    // これからアクティブになるよというイベント
    TApplicationEvent.BecameActive: 
    begin
      // Form の Invalidate メソッドを呼んで再描画をうながす
      Invalidate; 
    end;
  end;
```

# 最後に
Activity#moveTaskToBack() と Activity#finish() のどちらをバックキーのデフォルトの動作にするかプロパティで選べるようになってたら良いのになあ（Android 単体の話だから無理かな）
RubyとPythonの構文比較まとめ

#はじめに
ひとつのプログラミング言語を学ぶと、他のプログラミング言語にも応用できると言われています。
そこで、言語の壁を超えて、基本的な構文を比較しながらまとめてみました。

#投稿者のスキルセット
・RailsでWebアプリケーションを作成したことがある
・ProgateやRailsチュートリアルで、Rubyを学んだ経験がある
・ProgateでPythonを学習中

#対象者
・Rubyを学んでいて、Pythonに興味を持っている方
・逆にPythonを学んでいて、Rubyにも興味を持っている方

#環境
・MacOS Catalina 10.15.7
・Ruby 2.7.1
・Python 3.8.6

#構文
###「Hello, World!」を出力する

```hello.rb
puts 'Hello,world!'
```

```hello.py:
print('Hello, World!')
```
putsとprintで言語の違いがありますが、おおむね同じですね。


###コメント

```comment.rb
# これはコメントです
```

```comment.py
# これはコメントです
```

コメントの付けかたは、『#』で変わりません。

###条件文

```if.rb
def check(number)
    if number % 4 == 0
        puts('number is divisible by 4')
    elsif number % 3 == 0
        puts('number is divisible by 3')
    elsif number % 2 == 0
        puts('number is divisible by 2')
    else
        puts('number is not divisible by 4, 3, or 2')
    end
end
```

```if.py
def check(number):
    if number % 4 == 0:
        print('number is divisible by 4')
    elif number % 3 == 0:
        print('number is divisible by 3')
    elif number % 2 == 0:
        print('number is divisible by 2')
    else:
        print('number is not divisible by 4, 3, or 2')
```

Rubyでは『elsif』ですが、Pythonでは『elif』なところに注意が必要です。
また、Pythonでは条件文の末尾に`:`が必要ですが、Rubyでは不要です。


#おわりに
今回は、分かりやすい一例をご紹介しました。
基本的には、一つの言語を学べば、他の言語にも活かせると言えそうです。
まずは基礎となる言語の理解をしっかりと深めるところから始めましょう！

#参考
・ゼロから学ぶ Python
https://rinatz.github.io/python-book/
Cloud9 "VFS connection does not exist"と表示されるときの対処法

Railsチュートリアルの1.3.2 rails serverを進めていたとき、サーバーを立ち上がっても
”Oops VFS connection does not exist"と表示されてしまうエラーについてです。

https://blog.proglus.jp/3893/#VFS_connection_does_not_exist
↑参考資料

チュートリアル通り進めていても、エラーが出たので焦ってしまう人も多いと思います。

解決方法として

①Webサーバーの再起動

②使用ブラウザの確認

③EC2インスタンスの再起動

④OSのバージョンの更新

⑤Cookie設定

⑥広告ブロッカーやセキュリティソフト使用の有無

があるようです。私の場合、④と⑤を改善することで、サーバーを立ち上げることができました。ご参考までに。
brew doctor 実行後、Unexpected header files の削除を推奨された時の対処

## 環境
- macOS Big Sur バージョン11.0.1
- Homebrew 2.5.12
- nodebrew 1.0.1

### 問題となっている状況

```
$ brew doctor

Warning: Unbrewed header files were found in /usr/local/include.
If you didn't put them there on purpose they could cause problems when
building Homebrew formulae, and may need to be deleted.

Unexpected header files:
  /usr/local/include/node/js_native_api.h
  /usr/local/include/node/js_native_api_types.h
  /usr/local/include/node/libplatform/libplatform-export.h
  /usr/local/include/node/libplatform/libplatform.h
  /usr/local/include/node/libplatform/v8-tracing.h
  /usr/local/include/node/node.h
  /usr/local/include/node/node_api.h
  /usr/local/include/node/node_api_types.h
  /usr/local/include/node/node_buffer.h
  /usr/local/include/node/node_object_wrap.h
  /usr/local/include/node/node_version.h
  /usr/local/include/node/openssl/aes.h
  /usr/local/include/node/openssl/archs/BSD-x86/asm/crypto/buildinf.h
  /usr/local/include/node/openssl/archs/BSD-x86/asm/crypto/include/internal/bn_conf.h
  /usr/local/include/node/openssl/archs/BSD-x86/asm/crypto/include/internal/dso_conf.h
  /usr/local/include/node/openssl/archs/BSD-x86/asm/include/openssl/opensslconf.h

　.....予期しないヘッダーファイルの羅列.....

```

### 原因
- homebrewを使わずにnode.jsを導入したため。
- 具体的には、DockerでWordPress開発環境構築のためnode.jsをインストールしていたが、homebrewからnodebrewを導入しnodeの安定版をインストールした。

### 実行したこと
- 問題となっている**フォルダごと削除**
- パスワードを求められるので入力して実行

```
$ sudo rm -R /usr/local/include/node
```

### brew doctor で確認
- Unexpected header files が全てクリアになり解決しました。

## 参考
- [brew doctor したらUnbrewed header files were found in /usr/local/include. と言われたから消そうとしたけど消せなかった話](https://qiita.com/rinimaruranran/items/2d8d930ad846fa41b9e6)
VSコードで便利な拡張機能☆

Material Theme
→Set Color Themeからいくつか選ぶことができる機能
https://marketplace.visualstudio.com/items?itemName=Equinusocio.vsc-material-theme

Material Icon Theme
→拡張子に合わせて、アイコンを表示してくれる機能
https://marketplace.visualstudio.com/items?itemName=PKief.material-icon-theme

Bracket Pair Colorizer 2
→対応する括弧を色分けして表示してくれる拡張機能
https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2

indent-rainbow
→インデントを虹色にしてくれるい機能
https://marketplace.visualstudio.com/items?itemName=oderwat.indent-rainbow

zenkaku
→全角スペースを強調して表示してくれる拡張機能
https://marketplace.visualstudio.com/items?itemName=mosapride.zenkaku

Code Spell Checker
→スペルミスを減らしてくれる機能
https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker

Auto Rename Tag
→ペアになっているHTML/XMLタグの名前を自動的に変更する拡張機能
https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-rename-tag

Auto Close Tag
→HTML/XMLの終了タグを自動的に追加してくれる拡張機能です。
https://marketplace.visualstudio.com/items?itemName=formulahendry.auto-close-tag

Path Intellisense
→ファイルパスを補完してくれる拡張機能
https://marketplace.visualstudio.com/items?itemName=christian-kohler.path-intellisense




拡張機能の探しかた
https://marketplace.visualstudio.com


wikipediaのワードを使った連想ゲームアプリを作ってみた【Node.js+express】

このアプリはいたってシンプルで、**wikipediaからランダムに取得したワードに関連した言葉を３つ入力するアプリ**です。
（めちゃくちゃ簡単なアプリです。ご承知おきください。）

# 実装環境
ubuntu：18.04.5 LTS
node.js ：v10.14.2
express : 4.16.0

+ github：https://github.com/Sparrow42/associate-app

#アプリの使い方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/2bfa560c-144b-de48-b98b-5a17eddee4be.png)
こちらがトップ画面です。「岐阜中警察署」と出ています。思いついたものなんでもいいので、３つ入力します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/8381095e-bb69-09fc-9f90-babd77e7d69b.png)
中学校なのか、警察署なのか、どちらなのでしょうか…？
あとは岐阜から連想しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403809/4aa2a3dd-41a1-6222-3d22-b0a90595e5c1.png)

送信を押すと、また新しいワードが出てきます。「光原逸裕」って誰でしょうか。何回もやっていると「この人誰だよ」っていう人物名がめちゃくちゃ出てきます。笑
本当に知らないものが多いので、**高度な連想力が試されます。**

# 技術紹介
今回は、**[random-word-wikipedia](https://www.npmjs.com/package/random-word-wikipedia)**というAPIを使いました。**Wikipediaのあらゆるページからランダムに単語を引っ張ってきてくれるもの**です。
## 使い方
まず``random-word-wikipedia``をインストールします。

```
$ npm install random-word-wikipedia
```

そして、requireでモジュールを読み込み、thenによって取得できます。下のコードは[公式ドキュメント](https://www.npmjs.com/package/random-word-wikipedia)のusageです。

```JavaScript
const randomWordWikipedia = require('random-word-wikipedia');
 
randomWordWikipedia().then(console.log);
//=> [ 'Saxifraga spathularis' ]
 
randomWordWikipedia('ja', 2).then(console.log);
//=> [ 'ジョン・イサーク・ブリケ', '月は闇夜に隠るが如く' ]
```

## ソースコード
実際にこのAPIを使用したコードの抜粋です。

```JavaScript:index.js
const randomWordWikipedia = require('random-word-wikipedia');

function wrap_randomWordWikipedia(callback){
  randomWordWikipedia('ja').then((value) => {
    callback(value);
  })
}

router.get('/', function(req, res, next){
  function callback(param){
    var data = {
        theme: param,
    }
    res.render('index', data);
  }

  wrap_randomWordWikipedia(callback);
  
});

router.post('/add', (req, res, next) => {
  function callback(param){
    console.log('callback: ', param);
    var ans1 = req.body['ans1'];
    var ans2 = req.body['ans2'];
    var ans3 = req.body['ans3'];
    var data = {
      theme: param,
      ans1: ans1, 
      ans2: ans2, 
      ans3: ans3
    }
    res.render('index', data);
  }
  wrap_randomWordWikipedia(callback);
})
```

```pug:index.pug
extends layout

block content
  h1= "Output three objects"
  p 「#{theme} 」に関連したものを入力してください
  form(method="post" action="/add")
    input(type="text" name="ans1")
    input(type="text" name="ans2")
    input(type="text" name="ans3")
    input(type="submit" name="送信")
  
  p #{ans1} #{ans2} #{ans3}
```

# 苦戦したポイント
``random-word-wikipedia``が非同期で動くモジュールという点に苦戦しました。
後から動くモジュールをどうレンダリングするか色々試行錯誤しましたが、結局コールバック関数を使うことにより同期処理を非同期処理の後に実行させました。
もっといい書き方があればご教授いただけると幸いです。

解決方法を書いていたら長くなったので、別記事にします。（アップ次第、こちらにリンク貼ります。）

# これを作った意図
人と会話するときに、何にも話題とか返答が思いつかないことってありませんか？
私はよくあるので、頭の体操になるんじゃないかという軽い思いつきで作りました。

# 最後に
まだデータベース接続もしておらずとても簡単なつくりですが、とりあえずアウトプットしました。
ちょっとだけ作るつもりでしたが、作り出すと色々発想が生まれてきて、タイム計測やオリジナル問題など色々機能追加しようかと考え中です。やっぱ自作アプリは楽しいですね。

最後までご覧いただきありがとうございました！
もし参考になったという方がいれば、LGTMお願いします！
composerとは／活用方法

composer = PHPのパッケージ管理システム

大抵の場合は、PHP関数のみではなくフレームワークやライブラリの活用を行う。
その際に、毎回それらをインストールするのは面倒。
composerは使うたびに名前を列挙するだけで呼ぶ出すことができる優れもの。

●⚪︎●　実際の流れ　●⚪︎●

新しいプロジェクトの中で、ログライブラリのmonologを使いたい場合。



１、PHPアプリケーションを作成するディレクトリに、JSONファイルを入れる。

```
{
    "require": {
        "monolog/monolog": "1.0.*"
    }
}
```
composer.json は、アプリケーションで利用するパッケージ(ライブラリ)を列挙します。 ここに列挙したパッケージが、Composer による管理の対象になる。

２. composer.json に列挙したパッケージをインストール(ダウンロード)してみます。 composer install コマンドを実行する。

```
composer install
```


3.すると、vendor というフォルダが作成される。 この vendor というフォルダの中を表示してみると、プロジェクトで必要とする monolog がダウンロードされたことがわかる。
こんな感じ。

```
ls -l vendor
-rw-r--r--  1 OSCA staff 183 9 23 15:45 autoload.php
drwxr-xr-x 10 OSCA staff 340 9 23 15:45 composer
drwxr-xr-x  3 OSCA staff 102 9 23 15:45 monolog
```

4.vendor フォルダの直下には、autoload.php というファイルも生成される。 この PHP ファイルには、 composer.json で列挙したライブラリを読み込む処理が書かれてるので、実際にコーディングを始める際には、つぎのように vendor/autoload.php を読み込めば、全てのライブラリが利用できるようになる。

```
require_once("vendor/autoload.php");
```
Homebrewでよく使うコマンド

|brew --version|Homebrewのバージョンを見る|
|---|---|
|brew|サブコマンドの表示
|brew search|Homebrewのパッケージを一覧表示
|brew search キーワード|キーワードが含まれるbrewのパッケージを検索
|brew info|Homebrewでインストールした統計の情報を表示
|brew info パッケージ名|パッケージについての情報を表示
|brew install パッケージ名|パッケージをインストール
|brew update|Homebrewと全てのパッケージ定義(Formula)をアップデート
|brew upgrade|Homebrewとパッケージをアップグレード
|brew list|インストールされているパッケージを表示
|brew config|Homebrewシステム構成を表示
|brew doctor|Homebrewの問題をチェック
|brew commands|brew commands
|man brew|Homebrewについてのマニュアルを表示。
Dockerインストール時に起こったエラー(one of the sub-processes failed)の解決策

# はじめに
やりたいことがあり、今更ながらDockerをインストールしようとしたのですが、
躓いた点があったので共有しておきます。

# エラーメッセージ
今回受けたエラーメッセージは以下の通りです。

```
one of the sub-processes failed: com.docker.driver.amd64-linux -addr fd:3 -debug (pid: 989)
```

状況としては、
[Docker](https://www.docker.com)のホームページよりインストーラをDLしてインストール→`open /Applications/Docker.app` で立ち上げたところ、上記メッセージを確認しました。

# 対応策
こういった場合は基本的に[Dockerの初期化](https://tookikimie.hatenablog.com/entry/2019/06/29/223054)をするようなのですが、それでは解決せず。
**どうやら使っているOSが古い(macOS High Sierra v10.13.6)のが原因**だったようです。
対応として、[こちらのページ](https://docs.docker.com/docker-for-mac/release-notes/)から古いバージョンのDockerをインストールすれば解決しました。

とりあえず現在はv2.4.0.0で動作させています。
(ただし毎回起動時に以下の警告は受けます。)

```
OS X 10.13 is not supported 
There is an update but you are on OS X 10.13 or an earlier version.
Upgrade to the latest version of macOS to install it.
```

# 最後に
諸事情でmacOSのアップデートはしたくないのですが、
こういうエラーが多くなってくるとHighSierraも潮時な感じがしてきました。
本記事が誰かの助けになれば幸いです。enjoy!!
SlackのメッセージをGASでGoogleスプレッドシートに集積する

本記事は，[サムザップ Advent Calendar 2020 #2](https://qiita.com/advent-calendar/2020/sumzap2) の12/11の記事です．


# はじめに
株式会社サムザップのとあるプロジェクトで開発環境の構築を担当しています．
この記事では，Google Apps Script（以下、GAS）でSlackのメッセージをGoogleスプレッドシートで集積する例を紹介します．
予め定義しておいたタグをメッセージの先頭に含めておくと，定期的にスプレッドシートに自動集積することができます．

# 使用例
私のエンジニアチームでは週末にKPTを実施しています．
メンバーはKPT項目をSlackでメッセージで流しておき，スプレッドシートに集めたメッセージのうち，該当週の日付でフィルタリングして確認しています．
<img width="1000" alt="集積使用例.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/c86063ca-7357-06d7-6619-d61cf9719989.png">

# GASコード
https://github.com/akihisamikami/gas_projects/tree/main/slack_messages_to_gss

# 使用手順
### ①スプレッドシートを用意する
画像のような構成のスプレッドシートを用意します．
<img width="750" alt="集積シートサンプル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/58d8d283-a1b6-9f34-d692-804cc55abcff.png">
<img width="500" alt="タグマスタシートサンプル.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/a23a649b-7df0-36b1-6297-7559605eb0a8.png">

タグマスタシートには「名前付き範囲」を設定しておいて，タグ列の「データの入力規則」の条件に指定しておきます．
<img width="750" alt="名前付き範囲指定.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/ef7bc126-6469-898c-2e85-88c7d84c6132.png">
<img width="750" alt="データ入力規則設定.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/7d88a271-0665-6c69-9b15-a77e5b6aab2d.png">

集積シートのカラムにフィルタを追加しておきます．
<img width="750" alt="集積シートカラムにフィルタ追加.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/c5902885-0225-1785-8906-9ba290feca73.png">

### ②GASプロジェクトを作成する
[前述のGASコード](https://qiita.com/mikami_akihisa/private/ac87ec83458c76b84658#gas%E3%82%B3%E3%83%BC%E3%83%89)をコピペして，
slack.gs
spreadsheet.gs
の定数に値を入力しましょう．

### ③main関数を定期実行するトリガーを設定する
プロジェクトに時間ベースのトリガーを追加して，定期的に集積が実行するようにしましょう．
<img width="500" alt="プロジェクトにトリガーを追加.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/f5567404-69cc-1dec-454a-32df657fad2b.png">


### ④Slackでメッセージをポストして，スプレッドシートに集積されることを確認する
<img width="200" alt="Slackにメッセージを投稿.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/7f10dca9-b8e5-9c83-c314-db3eb2554e63.png">
<img width="750" alt="集積結果を確認.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/fab045ed-34b1-fcbd-c946-5dc205815a49.png">


メニューからも集積することが可能です．
<img width="750" alt="集積開始.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212116/986dbe10-ba5f-4b66-ded5-44ed6334347c.png">



# まとめ
GASでSlackのメッセージをGoogleスプレッドシートで集積する手法を紹介しました．
Slackのメッセージを記録として残したり，フィルタリングして集計したりといった用途に利用していただければと思います．

明日は @ohbashunsuke  さんの記事です．
Firebase Realtime DatabaseでUserIDフィールドの値を本人のUserIDに限定するrule

ユーザーID自体はContextから取れるし、編集が可能なデータかどうかなどによって考慮点が増えるので、あんまり単体では意味のない知識だけど、ある日役に立ったので書き残しておく。

```rule.json
{
  "rules": {
    ".read": false,
    ".write": false,
    "hoge" : {
      ".read" : false,
      ".write" :true,
      "$req_id" : {
        "userID": {
          ".validate" : "newData.val() === auth.uid"
        },
        ".validate": "newData.hasChildren(['userID'])"
      }
    }
  }
}
```

## これでどうなるのか
この時のuserIDの値を本人のauth.uidに限定できる。

```data.json
{
  "hoge" : {
    "data1" : {
      "city": "tokyo",
      "userID": "taro",
    },
    "data2" : {
      "city": "osaka",
      "userID": "jiro",
    }
  }
}
```
【Android】TabLayoutのIndicator色をtabごとに設定

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/694762/e33017e7-b523-5beb-5f3f-008670a2df78.gif" width=50%>


`setSelectedTabIndicatorColor`が非推奨になったので、`addOnTabSelectedListener`を使用。

```MainActivity.kt
        tab_layout.addOnTabSelectedListener(object : TabLayout.OnTabSelectedListener {
            override fun onTabReselected(p0: TabLayout.Tab?) {}
            override fun onTabUnselected(p0: TabLayout.Tab?) {}
            override fun onTabSelected(p0: TabLayout.Tab?) {
                tab_layout.setSelectedTabIndicatorColor(
                    ContextCompat.getColor(
                        applicationContext,
                        when (p0?.position) {
                            0 -> R.color.red
                            1 -> R.color.blue
                            else -> R.color.green
                        }
                    )
                )
            }
        })
```