OmniAICreator/Qiita-1.07M huggingface dataset:
windowsでiverilog その46

#概要

windowsでiverilogやってみた。
polyphonyでcpu書いてみる。
アセンブラでfizzbuzz書いてみる。
ちなみに、除算が使えないので、一苦労。

#サンプルコード


```
  r0set  0
  r0save 0
  r0save 1
  r0save 2
label_20:
  r0load  2
  r1set  1
  r0 + r1
  r0save  2
  r1set  9
  r0 < r1
  if label_32
  r0load  1
  r1set  1
  r0 + r1
  r0save  1
  r0set  0
  r0save  2
label_32:    
  r0load  0
  r1set	 1
  r0 + r1
  r0save 0
  r0load  0
  r1set	 100
  r0 < r1
  if label_255
  r0load  0
  r1set	 15
  r0 % r1
  if label_120
  r0load  0
  r1set	 5
  r0 % r1
  if label_140
  r0load  0
  r1set	 3
  r0 % r1
  if label_160
  r0load  1
  r0out
  r0load  2
  r0out
  jp label_20
label_120:
  r0set  'f'
  r0out 
  r0set  'i'
  r0out
  r0set  'z'
  r0out
  r0set  'z'
  r0out
  r0set  'b'
  r0out
  r0set  'u'
  r0out
  r0set  'z'
  r0out
  r0set  'z'
  r0out
  r0set  ' '
  r0out
  jp label_20
label_140:
  r0set  'b'
  r0out
  r0set  'u'
  r0out
  r0set  'z'
  r0out
  r0set  'z'
  r0out
  r0set  ' '
  r0out
  jp label_20
label_160:
  r0set  'f'
  r0out
  r0set  'i'
  r0out
  r0set  'z'
  r0out
  r0set  'z'
  r0out
  r0set  ' '
  r0out
  jp label_20
label_255:
  end


```


以上。
【Go】 deferに渡した関数内のエラーを呼び出し元に返す

# はじめに

はじめまして。Go初学者です。
[Gopher道場#8](https://gopherdojo.connpass.com/event/178532/)や自身の勉強にて、気づいた学びを共有しています。

今回は、`defer`内でのエラーハンドリング方法と、名前付き戻り値の利用方針についてまとめました。

# 結論から

**[deferに渡した関数のreturnは無視される](https://golang.org/ref/spec#Defer_statements)ので、deferに渡した関数のエラーは `名前付き戻り値` に代入して呼び出し元に戻す。**

> If the deferred function has any return values, they are discarded when the function completes. (See also the section on handling panics.)

> deferred関数に戻り値がある場合は、関数が完了したときに破棄されます。

# defer

## is 何

[詳細は公式ドキュメントへ](https://golang.org/ref/spec#Defer_statements)

いわゆる `Finally` 句の様なもので、関数が終了する前に呼ばれます。
`defer` キーワードの後に関数を渡すと、渡した順にスタックされていき、最後から順に実行されていきます。

```go
func main() {
	defer func() {
		fmt.Println("defer 1")
	}()
	defer func() {
		fmt.Println("defer 2")
	}()	
	
	fmt.Println("hoge")
}
```

```
hoge
defer 2
defer 1
```

panicの場合でも、きちんと呼ばれてくれます。

```go
func main() {
	defer func() {
		fmt.Println("defer 1")
	}()
	defer func() {
		fmt.Println("defer 2")
	}()	
	
	panic("panic!")
}
```

```console
defer 2
defer 1
panic: panic!

goroutine 1 [running]:
main.main()
	/tmp/sandbox481037905/prog.go:15 +0x68

Program exited: status 2.
```

以下の様に、ファイルのクローズ処理などによく用いられるそうです。

```go

func main() {
	file, _ := os.Create("hoge.txt")
	defer file.Close()
	
	// 書き込み処理
}
```

## defer内での`return`は無視される

下記の様な記述では、呼び出し元は`err`を受け取る事ができません。

```go
func main() {
	if err := hoge(); err != nil {
		fmt.Fprint(os.Stderr, err)
		os.Exit(1)
	}
	os.Exit(0)
}

func hoge() error {
	defer func() error {
		return fmt.Errorf("error occured!")
	}()
	
	return nil
}
```

では、先ほどの例でファイル操作をしている場合などに、エラー判定を呼び出し元に返すにはどのようにしたらよいのか？
この際に、名前付き戻り値を利用します。

# 名前付き戻り値

## is 何

[詳細は公式ドキュメントへ](https://golang.org/ref/spec#Return_statements)

Goでは戻り値に名称をつける事ができます。
また、付けられた名称は変数として関数内で利用する事が可能です。
名前付き戻り値を利用すると、`return`のみでも名前を付けた変数が返却することができます。


```go
func square(i int) (squared int) {
	squared = i * i
	return
}
```

## 良い所

戻り値に名前をつける事が出来るので、関数の利用者は作成者が何を返したいのかより明確になります。
IDEなどでも以下の様に表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/317515/f52f586f-3018-7211-6309-705d81d8da65.png)

ただ、そもそも関数名、引数名と引数の型、戻り値の型などを使って戻り値の意味が連想できないのはBadかなとは思いますが...

## 気になる所

私個人的には、`return`で省略できる点については、ソースの可読性を下げる恐れがあると感じています。
なので、実際は`return squared`の様に、明示的に記載することにしています。

# deferに渡した関数内のエラーを呼び出し元に返す

本題です。
以下の様に、defer内で名前付き戻り値にエラーを設定することで、エラーを呼び出し元に返却する事が可能になります。

```go
func main() {
	if err := file("hoge"); err != nil {
		fmt.Fprint(os.Stderr, err)
		os.Exit(1)
	}
	os.Exit(0)
}

func file(fileName string) (err error) { // errorに名前をつける
	file, _ := os.Create(fileName)
	defer func() {
		err = file.Close() // errに処理結果を代入
	}()

	// 書き込み処理

	return nil
}
```

# おわりに

基本的に名前付き戻り値は使わずに実装が可能ですが、上記のパターンの場合は使わずに返却することは難しいようでした。
名前付き戻り値の使い所はこういうパターンもあるんですね:thinking_face:

# 参考 

- [【オンライン】Gopher道場#8](https://gopherdojo.connpass.com/event/178532/)
- [Gopher道場#8 Github](https://github.com/gopherdojo/dojo8/pull/2)
rails の API doc作成ツール apipie-rails

rails で RESTful APIを作るに当たって、ドキュメンテーションツールを導入してみました

https://github.com/Apipie/apipie-rails

# 背景

rails でフロントとバックエンドと別々の担当者が作業しようとしたときに、フロントから受け渡されるべきパラメーターはなんで、その結果どんな結果がわたるのかどうやってドキュメントしようかなと。。

javadocみたいに定番の書式があるわけではなさそうなので、gem周りで検索してみました。

さらに、世の中の定番としては こんなかんじなのかな
https://qiita.com/jian-feng/items/c79955713e6dd8b5244a


結果としてたどり着いたのが、 apipie-rails です

## 何が出来るのか

1. ソースコード上にDSLを使ってAPIインターフェースを定義できる
2. Webサーバー経由でHtmlドキュメントとして可視化された情報にアクセス出来る
3. 引数のバリデーションをする → ArgumentError exception が上がる

## 導入

1. "gem 'apipie-rails'" を追加（一旦、開発環境のみに導入されるように設定する）
2.  bundle install 後、rails g apipie:install で以下が追加されました
    a. routes.rb に apipie ルートが追加
    b. config/initializers/apipie.rb が追加
3.
[React] <Component {...props} /> なpropsの渡し方



## tl;dr

タイトルのようなpropsの渡し方でも無駄に再レンダリングが起きることはない、ということの確認の記事。

## code

スプレッド演算子でオブジェクトを展開すると「新しいオブジェクト」が生成される。なので、レンダリング最適化の観点で、無駄に再レンダリングが起きそうにも見える。

だが、実際は「新しいオブジェクト」が生成されるだけで、要素については新しい値なわけではない。

```ts
const func = () => console.log('hello world')
const props = { func }
const newProps = { ...props }
props.func === newProps.func // => true
```

なので、レンダリング最適化されていれば、この渡し方でも無駄にレンダリングが起きることはない

```tsx
// count が増加してもChildが再レンダリングされることはない
const App = () => {
  const [count, increment] = React.useReducer(prev => ++prev, 0)
  const func = React.useCallback(() => console.log('hello world'), [])
  const props = { func }
  return(
    <div>
      <button onClick={increment}>increment({count})</button>
      <Child {...props} />
    </div>
  )
}

const Child = React.memo(({func}) => <button onClick={func}>CLICK_ME</button>)
```

https://codepen.io/snamiki1212/pen/JjGLgEq
Azure上に仮想マシンを立てる

#Azure Linux VM作成と管理　備忘録
本ページはAzure上でLinuxの仮想マシンを動かせるまでを行う作業内容を備忘録的に書いたもの。
ここでやった作業はこちらの[参考ページ](https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/tutorial-manage-vm)を基にしたもの。というかまんま。


##1. [Azure Cloud Shell](https://docs.microsoft.com/ja-jp/azure/cloud-shell/overview)を使う
Azure Portalの上部に常駐しているボタンから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112640/176019e0-bec1-59bd-6edf-6621576052a2.png)
赤く囲ったアイコンをクリックしてAzure Cloud Shellを起動し、BashかPowerShellのどちらのシェルを使用するか決める。（この選択は後で変えられるみたい）

選択すると、下記のポップアップが表示されることもある模様。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/112640/bcc4ad15-73b7-bdd2-386e-16ce09f15cf6.png)
ストレージの作成を押して待つ。1、2分ほど。

##2. リソースグループを作成する
リソースグループというのが必要なので、それを作成します。（細かい話は割愛・・・）
az group createコマンドを使用する

```text:リソースグループの作成用コマンド
az group create --name (A) --location (B)

A：リソース名
B：az account list-locationsを実行して得られるlocationリストからnameを指定。
　　⇒私はここで”eastasia”を指定
```
Succeededのステータスが表示された完了

##3. 仮想マシンの作成
az vm createコマンドを使用する

```text:仮想マシンの作成用コマンド
az vm create \
    --resource-group myResourceGroupVM \
    --name myVM \
    --image UbuntuLTS \
    --admin-username azureuser \
    --generate-ssh-keys
```
公式サイトを引用すると、
>次の例では、Ubuntu Server を実行する myVM という名前の VM を作成します。 VM には、azureuser という名前のユーザー アカウントが作成されます。また、既定のキーの場所 ( ~/.ssh) に SSH キーが存在しない場合は、SSH キーが生成されます。

とのこと。

今回、リソースグループには「2」で作成したリソースグループを指定。
また、仮想マシンはRedHatを使用したかったため、”RHEL”を使用。
**※`--image`で指定できる仮想マシンのリストは、コマンド”az vm image list”を使用して確認可能**

Finishedが出たら完了

##4. 仮想マシンへの接続確認
作成したVMへの接続を試みる。
「3」でFinishedしたときに表示される、`"publicIpAddress"`がVMのIPアドレスになる模様。
公式の手順に従って、sshで接続してみる。

```text:仮想マシンへSSHでの接続
ssh (A)@(B)

A：仮想マシン作成時に指定したadmin-username
B：`"publicIpAddress"`
```




---

 一旦仮想マシンはこれで立つ。
Azureすごいな。

次回は仮想マシン上にApacheを立てる。
GCP上のデータを利用してAzureMachineLearningを実行する_その3_GBQ

## 概要

以下の記事のGoogle Big Query (GBQ)での手順です。

[GCP上のデータを利用してAzureMachineLearningを実行する_その1_まとめと環境設定](https://qiita.com/ryoma-nagata/items/de16c37e3b683ed42ef0)

本記事は下記のGitHubでソースコードを公開しています。
[GCP上のデータを利用してAzureMachineLearningを実行する_その3_GBQ](https://github.com/ryoma-nagata/MyQiitaDocs/blob/master/AzureMachineLearning/GCP%E4%B8%8A%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6AzureMachineLearning%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B_%E3%81%9D%E3%81%AE3_GBQ/source/03_GBQ_Azure_ML_Remote.ipynb)

## 構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/adbac660-03f6-ad16-069d-52452041abe6.png)


## 手順概要

1. GBQ準備
2. ローカル実験によるテスト
3. AMLのリモート実験
4. GBQ データ削除

## 1.GBQ準備
jupyter notebookで[01_GBQ_Create_Table.ipynb]を実行します。<br>

利用ファイル：
- 01_GBQ_Create_Table.ipynb
- project_folder/サービスアカウントキー作成で出力したjsonファイル

## 2. ローカル実験によるテスト
jupyter notebookで[02_GBQ_ML_Local.ipynb](https://github.com/ryoma-nagata/MyQiitaDocs/blob/master/AzureMachineLearning/GCP%E4%B8%8A%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6AzureMachineLearning%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B_%E3%81%9D%E3%81%AE3_GBQ/source/02_GBQ_ML_Local.ipynb)を実行します。<br>

利用ファイル：
- 02_GCS_ML_Local.ipynb
- project_folder/サービスアカウントキーを作成で出力したjsonファイル

## 3. AMLのリモート実験

jupyter notebookで[03_GBQ_Azure_ML_Remote.ipynb](https://github.com/ryoma-nagata/MyQiitaDocs/blob/master/AzureMachineLearning/GCP%E4%B8%8A%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6AzureMachineLearning%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B_%E3%81%9D%E3%81%AE3_GBQ/source/03_GBQ_Azure_ML_Remote.ipynb)を実行します。<br>

利用ファイル：
- 03_GCS_Azure_ML_Remote.ipynb
- project_folder/サービスアカウントキーを作成で出力したjsonファイル
- project_folder/train_breast_cancer.py

## 4.GBQ準備

課金が発生するので、不要な場合は、jupyter notebookで[04_GBQ_Delete_Data.ipynb](https://github.com/ryoma-nagata/MyQiitaDocs/blob/master/AzureMachineLearning/GCP%E4%B8%8A%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6AzureMachineLearning%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B_%E3%81%9D%E3%81%AE3_GBQ/source/04_GBQ_Delete_Data.ipynb)を実行して削除します。
GCP上のデータを利用してAzureMachineLearningを実行する_その2_GCS

## 概要

以下の記事のGoogle Cloud Storage(GCS)での手順です。
[GCP上のデータを利用してAzureMachineLearningを実行する_その1_まとめと環境設定](https://qiita.com/ryoma-nagata/items/de16c37e3b683ed42ef0)

本記事は下記のGitHubでソースコードを公開しています。
[GCP上のデータを利用してAzureMachineLearningを実行する_その2_GCS](https://github.com/ryoma-nagata/MyQiitaDocs/blob/master/AzureMachineLearning/GCP%E4%B8%8A%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6AzureMachineLearning%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B_%E3%81%9D%E3%81%AE2_GCS/README.md)

## 構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/281819/bcc72480-676a-f9f8-efa6-355842049ec6.png)


## 手順概要

1. GCS準備
2. ローカル実験によるテスト
3. AMLのリモート実験

## 1.GCS準備
jupyter notebookで[01_GCS_Create_Bucket.ipynb]を実行します。<br>

利用ファイル：
- 01_GCS_Create_Bucket.ipynb
- project_folder/サービスアカウントキー作成で出力したjsonファイル
- data/breast_cancer.csv

## 2. ローカル実験によるテスト
jupyter notebookで[02_GCS_ML_Local.ipynb](https://github.com/ryoma-nagata/MyQiitaDocs/blob/master/AzureMachineLearning/GCP%E4%B8%8A%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6AzureMachineLearning%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B_%E3%81%9D%E3%81%AE2_GCS/source/02_GCS_ML_Local.ipynb)を実行します。<br>

利用ファイル：
- 02_GCS_ML_Local.ipynb
- project_folder/サービスアカウントキーを作成で出力したjsonファイル

## 3. AMLのリモート実験

jupyter notebookで[03_GCS_Azure_ML_Remote.ipynb](https://github.com/ryoma-nagata/MyQiitaDocs/blob/master/AzureMachineLearning/GCP%E4%B8%8A%E3%81%AE%E3%83%87%E3%83%BC%E3%82%BF%E3%82%92%E5%88%A9%E7%94%A8%E3%81%97%E3%81%A6AzureMachineLearning%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%99%E3%82%8B_%E3%81%9D%E3%81%AE2_GCS/source/03_GCS_Azure_ML_Remote.ipynb)を実行します。<br>

利用ファイル：
- 03_GCS_Azure_ML_Remote.ipynb
- project_folder/サービスアカウントキーを作成で出力したjsonファイル
- project_folder/train_breast_cancer.py
PHP strcmp関数について（文字列の大小って何？）

PHP7の初級試験の勉強を開始した矢先にstrcmp関数で詰まったのでメモ。
初心者のため間違い等あったら教えてほしいです。

## strcmp関数は、文字列の大小を比較する？
**string compeare**（文字列比較）の略で`strcmp`です。引数で与えられた２つの文字列を比較し、

- 一致すれば「0」
- 第一引数が大きければ「１より大きい数字」
- 第一引数が小さければ「１より小さい数字」

を返します。ここで疑問に思いました。文字列の大小って何だ？と。

## 文字列の大小とは、「同一でない文字」の「バイト列の差」のこと
文字列の大小とは、 **「同一でない文字」** の **「バイト列の差」** のことを言っています。その比較方法として、文字列の頭から順に比較し、同一でなかった時点で処理を停止して、その文字の「バイト列の差」を返してくれます。

```php5
strcmp("ABCD", "ABBE");

# 1
```

ここでは、strcmp関数で第一引数`"ABCD"`と第二引数`"ABBE"`を比較しています。
一文字目の`'A'`から比較していき、3文字目の`'C'`と`'B'`で同一でなくなります。ここで処理は停止し、それ以降の文字（`'D'`と`'E'`）は無視されます。
結果として、出力は`'1'`となります。その理由が３文字目の　 **「バイト列の差」** になります。
同一でなくなった３文字目`'C'`と`'B'`のバイト列の大きさを比較し、第一引数である'C'の方が第二引数である'B'よりもバイト列の値が1大きいため、その差の`'1'`を返却していることになります。

## 数字も文字として扱われる
strcmp関数は、数字も文字列として扱い、比較します。数字の大小を比較するものではないです。
数字の場合でも文字列と同様に１文字目から比較し、不一致の時点で停止、その文字のバイト列の差を返す、ということです。
例えば、第一引数"12330"と第二引数"1234"を比較する場合。

```php5
strcmp("12330", "1234");

# -1
```

数字の大小で言えば確かに"12330"の方が大きいです。しかしstrcmp関数では、頭の一文字目から比較し、4文字目の'3'と'4'が不一致になったところで処理を停止して、この文字同士のバイト列の差を返却します。
結果として、'3'の方がバイト列が１小さいため、strcmp関数は'-1'を返却します(５文字目以降は無視されます)。

## 上記以外のパターン（同一の文字が存在無い場合）
例えば次のパターンですと、一文字目の'a'は一致していますが、2文字目が第二引数に存在しないため、処理が変わってきます。

```php5
strcmp("acccc", "a");

# 4
```

この場合は、第一引数の'a'以降の文字数の分だけ返します。シングルバイト文字１文字につき、'１'を返すので、この場合cが４つで'4'を返します。マルチバイト文字（全角文字）の場合は、１文字につき'3'を返します。
このあたりの仕様については、すみませんがよくわりませんでした。が、挙動の記録として一応残しておきます。

## 参考
- [PHPによる文字列比較の基本形～確実な比較と落し穴ポイント～](https://www.ritolab.com/entry/152)
- [PHPマニュアル strcmp](https://www.php.net/manual/ja/function.strcmp.php)

上記サイトを参考の上検証してみました。

strcmp関数で検索してみると、「文字列の長さ」を比較している、というような情報が目に入ったりしますが、そうではないようです。
情報に振り回されないよう、初心者の私も気をつけていきます。目指せPHPマスター！
PHP: Starttls でメールの送信

こちらと同じことを PHP で行いました。
[Python3: Starttls でメールの送信](https://qiita.com/ekzemplaro/items/c248b52a6f36947af080)
hi-ho.ne.jp で試しました。

次のページを参考にしました。
[symfony / mailer](https://github.com/symfony/mailer)

ライブラリーのインストール

```bash
composer require symfony/mailer
composer require vlucas/phpdotenv
```

```php:hi-ho.php
#! /usr/bin/php
<?php
// ------------------------------------------------------------------
//	hi-ho.php
//
//					Dec/17/2023
//
// ------------------------------------------------------------------
require_once 'vendor/autoload.php';
use Symfony\Component\Mailer\Transport;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Mime\Email;

fputs (STDERR,"*** 開始 ***\n");

$dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
$dotenv->load();


$mailer_dsn = $_ENV['MAILER_DSN'];

$from = $_ENV['FROM'];
$to = $_ENV['TO'];

date_default_timezone_set('Asia/Tokyo');
$today = date ("Y-m-d");
$now = date( "Y年m月d日 H時i分s秒" );

$transport = Transport::fromDsn($mailer_dsn);
$mailer = new Mailer($transport);

$email = new Email();
// 4. メッセージの作成
$str_out = "";
$str_out .= 'This is TEST.' . PHP_EOL;
$str_out .= 'こんにちは。' . PHP_EOL;
$str_out .= '晴れています。' . PHP_EOL;
$str_out .= 'Dec/17/2023' . PHP_EOL;
$str_out .= 'PM 12:14' . PHP_EOL;
$str_out .= $today . PHP_EOL;
$str_out .= $now . PHP_EOL;

$email
	->from($from)
	->to($to)
 	->subject('Time for Symfony Mailer!')
	->text($str_out)
       	;

$mailer->send($email);

fputs (STDERR,"*** 終了 ***\n");
// ------------------------------------------------------------------
?>
```

```text:.env
MAILER_DSN=smtp://user:password@hi-ho.mose-mail.jp:587
FROM = '****@hi-ho.ne.jp'
TO = 'sample@example.com'
```

実行結果

```text
$ ./hi-ho.php 
*** 開始 ***
*** 終了 ***
```
Gatsby + Contentful マークダウン内の画像を表示する

#やりたいこと

Contentfulでリッチテキストではなく、マークダウンを使用した際に
本文中の画像埋め込みを表示したい

そのままGraphQLで下記のようにHTMLを取得したものを表示することもできますが最適化出来ていません


```graphql
query {
    allContentfulBlogPost(sort: { fields: [publishDate], order: DESC }) {
      edges {
        node {
          content {
            childMarkdownRemark {
              html
            }
          }
        }
      }
    }
  }
```

#やりかた

`gatsby-remark-images-contentful`を用いる
https://www.gatsbyjs.org/packages/gatsby-remark-images-contentful/

なお、`gatsby-remark-images`があると
画像が表示されなくなりますので、プラグインから外しておきましょう
https://github.com/gatsbyjs/gatsby/issues/24830

```react:gatsby-config.js
{
      resolve: `gatsby-transformer-remark`,
      options: {
        plugins: [
          {
            resolve: `gatsby-remark-images-contentful`,
            options: {
              // It's important to specify the maxWidth (in pixels) of
              // the content container as this plugin uses this as the
              // base for generating different widths of each image.
              maxWidth: 590,
              withWebp: true,
            },
          }
     ]
}
```

あとは`gatsby-config.js`に追記して再度ビルドしましょう
Apache JMeterをインストールする

# 最終更新日

2020年7月8日

検証を行ったOS/JDKのバージョンは下記です。

- macOS Catalina 10.15.5
    - 未検証ですが、Windowsでも手順は同様のはずです
- AdoptOpenJDK 11.0.7
    - インストール方法は別記事で紹介しています（[Windowsの場合](https://www.youtube.com/watch?v=tWU0oUjosBo)・[macOSの場合](https://qiita.com/suke_masa/items/f9af0fb84ad9447ae961)）

インストールするもののバージョンは下記です。

- Apache JMeter 5.3

> この記事が古くなった場合、下記の手順は最新のインストール手順とは異なっている可能性があります。その場合は[公式ドキュメント](http://jmeter.apache.org/download_jmeter.cgi)をご確認ください。

# JMeterのインストール
(1) http://jmeter.apache.org/download_jmeter.cgi にアクセスして、apache-jmeter-5.3.zipをダウンロードしてください。

![スクリーンショット 2020-07-08 17.10.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58650/47b2da43-d0bb-96c7-9d10-a9328a176845.png)

(2) ダウンロードしたZIPファイルを、適当なフォルダに展開してください。

(3) 環境変数 `PATH` に `JMeterを展開したフォルダ/bin` を追加してください（例： `/Users/user01/apache-jmeter-5.3/bin` ）。

(4) ターミナル（orコマンドプロンプト）で `jmeter --version` を実行してください。

```bash
jmeter --version
WARNING: package sun.awt.X11 not in java.desktop
    _    ____   _    ____ _   _ _____       _ __  __ _____ _____ _____ ____
   / \  |  _ \ / \  / ___| | | | ____|     | |  \/  | ____|_   _| ____|  _ \
  / _ \ | |_) / _ \| |   | |_| |  _|    _  | | |\/| |  _|   | | |  _| | |_) |
 / ___ \|  __/ ___ \ |___|  _  | |___  | |_| | |  | | |___  | | | |___|  _ <
/_/   \_\_| /_/   \_\____|_| |_|_____|  \___/|_|  |_|_____| |_| |_____|_| \_\ 5.3

Copyright (c) 1999-2020 The Apache Software Foundation
```
Linuxで大文字・小文字を区別しないでディレクトリ名前を検索したい


##
```
find ./ -iname phpMyAdmin -type d
```

-iname　を使えば大文字・小文字を区別しない。

-type d　ディレクトリ


大文字と小文字を区別しないことを、ケース・インセンシティブ（英：case-insensitive）と言う。

逆にケース・センシティブ（英：case-sensitive）とは、コンピューターの分野において、文字列の大文字と小文字を区別して扱うことである。
SolidWorks2019+GeforceRTX2070s→Realview

SolidWorks2019上でGeforceRTX2070superを使ってRealviewを有効化した備忘録です。

※レジストリをいじります。何らかの不都合を生じても当方は一切の責任を負いませんので、自己責任でよろしくお願いいたします。

###ことのはじめ
SolidworksにはRealview Graphicsという素晴らしい表示機能がありますが、この表示機能はQuadroとFireProにしか許されていません。
そこで、レジストリをちょちょいといじってGeforceでもこの機能を使えるようにしてしまおう、というのが本稿の目標です。

そもそもこんな方法があると知ったのが、
[【SOLIDWORKSを快適に使おう】GEFORCEでもREALVEIWを有効にする方法](https://keiorogiken.wordpress.com/2017/12/12/%E3%80%90solidworks%E3%82%92%E5%BF%AB%E9%81%A9%E3%81%AB%E4%BD%BF%E3%81%8A%E3%81%86%E3%80%91geforce%E3%81%A7%E3%82%82realveiw%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
の記事によるところが大きいです。

###やり方
[【SOLIDWORKSを快適に使おう】GEFORCEでもREALVEIWを有効にする方法](https://keiorogiken.wordpress.com/2017/12/12/%E3%80%90solidworks%E3%82%92%E5%BF%AB%E9%81%A9%E3%81%AB%E4%BD%BF%E3%81%8A%E3%81%86%E3%80%91geforce%E3%81%A7%E3%82%82realveiw%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95/)
ほとんど、こちらの記事と同じです。
ただ、上記の記事ではR420フォルダ内にキーを作成していましたが、R420ではRealviewは有効になりませんでした。
そもそもR420フォルダはAMDのFirePro系のレジストリのハズなので、R420と同じヒエラルキにあるNvidia系レジストリのNV40フォルダ内に全く同じ方法で、キーを作成しました。

キーに登録したDWORDは「30408」です。

###まとめ
上記の方法で、SW2019＋Geforce2070sでRealviewを有効化できました。
記事の頭でも言いましたが、レジストリを編集するので全て自己責任でお願いします。
visualstudio 2019 で、pylintが動作しない

vs2019に、python開発環境をセットアップして
pylintを実行したところ、次のようなエラーで
動作しない。

No module named pylint.lint.__main__; 'pylint.lint' is a package and cannot be directly executed

そこで、
power shell から
py -m pip list
で、確認するとpylintのバージョンが2.5.3だった。

py -m pip uninstall pylint
として、一旦パッケージを削除し
py -m pip install 'pylint==2.4.4'
で、他の環境で動いているバージョンを
指定して再インストールした。

無事にpylintが実行出来た。
ESP32でPythonを使ってサーボを動かす (Windows)

事前に[前記事](https://qiita.com/nobody_gonbe/items/1c9211e0f889988a98ec)にてESP32にMicroPythonを入れている。

##サーボとESP32を繋ぐ
今回はG2ピンに繋ぐことにした。使用可能なピンについては[ピンとGPIO](https://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.html#pins-and-gpio)を参照。
買ったサーボの必要電圧が4.8V~6Vだったため5Vに接続している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666820/4f88dcd8-a395-34b1-de64-98e387d0f9ce.png)

##サーボの確認をPuTTYで行う
[PuTTYの使用方法](https://qiita.com/nobody_gonbe/items/1c9211e0f889988a98ec#%E8%BF%BD%E8%A8%98)は前記事の追記に記載。

PuTTYでコマンドを1行ずつ記入してEnterを押しサーボの可動域を確認していく。

PWMパルスとGPIOピンを使用する宣言
`from machine import PWM, Pin`

ピン2の周波数を50としてservo1と名前を付けた。
周波数の強さによって回転速度が決まるようだ。
`servo1 = PWM(Pin(2), freq = 50)`

サーボのデューティ比とやらを変更。
これで何度も角度を調整して可動域を確かめる。
大体30～120の範囲で微調整するといい。
周波数を100にした時は60～240となるようだ。

`servo1.duty(30)`

※パルスの無いフリー状態。回し過ぎてデットロックされたら一度0にして手動で押し戻すとよい。
`servo1.duty(0)`

回しながら確認したところ自分のサーボでの最小最大の限界は25～130だった。

##コードを書く
main.pyという名前を付けて下記の簡単なコードを書きデスクトップに保存した。
sleepは大事。これがないと無限ループが起こりESP32に新たなコードが上書きできなくなる。
上書きできなくなった時はフラッシュを消去してMicroPythonを入れなおす必要あり。

```main.py
# -*- coding: utf-8 -*-

from machine import PWM, Pin
import time

servo1 = PWM(Pin(2), freq = 50)

# 角度30（最小）と角度120（最大）を2秒ごとに繰り返す
while True:
    servo1.duty(30)
    time.sleep_ms(2000)
    servo1.duty(120)
    time.sleep_ms(2000)
```


##コードをESP32に送る
コードを送るためのツールをコマンドプロンプトからインストール
`pip install adafruit-ampy`

ampyのコマンド確認は
`ampy`
と打つと確認できる。


main.pyをデスクトップに保存したのでデスクトップ下に移動
`cd Desktop`


main.pyファイルをESP32に送る。COM3の部分は自分の繋いでいるポートに変更する。
※PuTTYが立ち上がっていると送信できないので落としておく。
`ampy -p COM3 put main.py`



無事に動いた。






##参考
▼Fritzing用のESP32パーツ
<https://qiita.com/XZ_Manj/items/8bbdef59eeac4286e4f8>

▼ピンとGPIO
<https://micropython-docs-ja.readthedocs.io/ja/latest/esp32/quickref.html#pins-and-gpio>

▼はだメモ　パルス幅の調整でサーボを動かす
<https://scrapbox.io/hada/ESP32%E3%81%A7%E3%82%B5%E3%83%BC%E3%83%9C%E3%83%A2%E3%83%BC%E3%82%BF%5B2018%2F10%2F29%5D_22:09:36>
[Docker][Rails] 新しくGemを導入した後の３コマンド

# これはなに
Railsでアプリ開発中新しくGemを導入した後、若干躓いたので備忘録として残します。
ご指摘等あれば頂けると幸いです。

# ３コマンド


```
gem bundle install
```

```
docker-compose run web bundle install
```
参考記事
[Docker Compose + Railsでイメージ内でbundle installしているはずなのにgemが無いとエラーがでる。](https://qiita.com/hokita222/items/49f4ca54835e08fdd6b2)


```
docker-compose restart
```
参考記事
[dockerの起動、停止、再起動](https://qiita.com/tanakin_prog/items/6e6219a62e7a05eb22c2)

以上です！ありがとうございました！
【Rails】editアクションでのエラー解決

##本記事を書いた理由

* 今回引っかかったエラーに対してどのように解決をしたのかを記録として残すことで同じミスをしないようにするため

##目次

* どんなエラーが出たのか
* 考え方の道筋(実際にやってみたこと)
* 反省点

##参考記事

* [pikawaka: form_forの使い方をマスターしよう](https://pikawaka.com/rails/form_for#%E3%82%A2%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%90%8D%E3%81%A7%E8%A8%98%E8%BF%B0%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86)

##どんなエラーが出たのか
todoアプリで編集機能をつけようとしたがうまく動かない。
具体的にはeditボタンという編集ページに飛ぶボタンを押すとエラー画面が出てくる状態。

<img width="600" alt="スクリーンショット 2020-07-08 16.00.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517816/281be22a-571a-41eb-b38d-c963abed1a35.png">

エラー画面
<img width="700" alt="スクリーンショット 2020-07-08 16.04.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517816/e068e786-a0c8-ba06-232b-60b266aa34bc.png">

##考え方の道筋(実際にやってみたこと)

**`結論`**
**edit.html.erbのform_forの記述にパスを指定してあげる必要があった**


**`実際にやってみたこと`**

* エラー画面をみてeidt.html.erbに問題があると考える

* コントローラの記述に誤りはないのか(編集したい情報をきちんと持ってきてこれているのか）

* 改めてedit.html.erbを見てみる(記述に変更を加えてみた)


###エラー画面をみてeidt.html.erbに問題があると考える

<img width="900" alt="スクリーンショット 2020-07-08 16.37.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517816/a345e1d5-c22a-c6bf-4a63-3b81a908912a.png">


* エラー画面からパスに問題があると推定した
* しかしこの時点でパスの何を直せばいいのかよくわからないので他のサイトからform_forの記述方法を調べて誤りがないか調べてみた。結果として特に誤りがないと判断した

###コントローラの記述に誤りはないのか(編集したい情報をきちんと持ってきてこれているのか）

<img width="371" alt="スクリーンショット 2020-07-08 16.06.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517816/7d91930c-8c60-5736-4f37-2149a6908175.png">

* コントローラの記述に誤りがないかどうか確認をした(特に問題なし)

<img width="720" alt="スクリーンショット 2020-07-08 16.42.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517816/6c1dd731-b470-6e1e-4c33-821fa7c7f0c4.png">

* 確認のために`binding.pry`を使って編集したい情報が持ってこれているか確認をした(特に問題なし）
* この時点でルーティングに問題がないと判断した(コントローラがしっかりと動いていることが確認できたため)

###改めてedit.html.erbを見てみる(記述に変更を加えてみた)

* ルーティングとコントローラに問題がない時点でビュー(edit.html.erb)に問題があることを再確認した
* そうなるとエラー画面の通りform_forの記述方法に問題がある可能性が高いので改めて確認をした
* 結果としてform_forは自動的にcreateアクションやeditアクションを分けてくれる。しかしうまくいかない時もあるのでその時は直接アクション名(パス)を書いてあげることで解決できるらしい。(以下のように編集)

<img width="967" alt="スクリーンショット 2020-07-08 16.50.54.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517816/c9f23996-93dc-fb27-4738-57d39f0dd735.png">

* 上記のようにパスを新しく指定することでエラーが解決できました。
*`action="index"`になっていますが実際はpatchを入れて編集内容を保存します。

エラー解決後の画面
<img width="600" alt="スクリーンショット 2020-07-08 16.14.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517816/396bf088-4d52-9f92-31b7-e4ff2596fe46.png">

##反省点

* エラー画面の詳細をもう少しみてそこから解決できる方法を考えるべきだった(最初のエラー画面の時点で意味がよくわからないのでコントローラの方などに原因があると考えてしまった)
* 上記のようなことをしなかったので解決までに時間がかかってしまった
ネコネコパズル



## 導入
今回の最終課題をやるにあたって時間もあるのでせっかくだから難しいものを作りたいと思いネコのパズルを作ってきました


---

## 動かした様子
- 難易度は3つあったけど今回はeasy(4色)だけ作りました
- 縦・横・斜めの向きに3個並べれば消えます
- どれか一列でも上に届けばGAME OVER です
![nako douga.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638206/650f22c2-0f03-4a1c-70b2-9ac621d4aaf3.gif)


---

## 苦労したこと 気づいたこと
- ifやelse、elifなど字下げしなければならないものが多く、どこまで下げるかをよく間違えたこと
- 頻繁に：を忘れていたので何回もエラー出したこと
- 理解が曖昧だったグローバル宣言についていつ使って、いつ使わなくてよいかというのをしっかり確認できた


---
 
## 改良

元のコードではウインドウの高さが背景の写真よりも小さかったので、20(768→790)くらい引き上げました

```python:neko.pzl.py
root = tkinter.Tk()
root.title("落ち物パズル「ねこねこ」")
root.resizable(False, False)
root.bind("<Motion>", mouse_move)
root.bind("<ButtonPress>", mouse_press)
cvs = tkinter.Canvas(root, width=912, height=790)
cvs.pack()
```
---

##　感想
- しっかりと動いたときはとても感動しました
- この本は夏休み中に完走したいと思います

---

## 参照[Pythonでつくるゲーム開発入門講座](http://www.sotechsha.co.jp/sp/1239/) p.172~p.214 
廣瀬　豪（ひろせ　つよし）
私のための忘備録③(プロセスの生成、監視、終了・プロセスの実行優先度の変更・正規表現を使用してのテキストファイル検索)

##uptime = top
システムの稼働時間や負荷平均などを表示するコマンド
topはプロセスの稼働状況を一定時間ごとに更新して表示するコマンド

##pgrep
実行中のプロセスの中から特定の名前をもつプロセスIDを検索することができる。
grepは文字列の検索

##kill,killall,pkill
プロセスに終了や再起動などのシグナル（命令を）送る。

![名称未設定.pngs.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620109/00a0ac8b-a298-df0b-8159-9947c70a3e7c.png)



##ps
現在進行中のプロセスを確認することができる
-lとl　親プロセスのPIDや実行優先度を決定するnice値なども合わせて表示
a 他のユーザのプロセスも表示
-pとp　ID　指定したPIDのプロセス情報を表示する。
f　プロセスの親子関係をツリー状で表示
-f 完全なフォーマットで表示
-e　全てのプロセスを表示
u　プロセスの実行ユーザも表示

![名称未設定.pngえ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620109/88a3c162-7dfc-ec41-f1e8-6ba0983fde26.png)
:eyes:なお、killall、pkill(およびkill)コマンドでシグナルを指定しない場合は、デフォルトでこのシグナルが使用されます。

:eyes:killコマンドでシグナルを指定しない場合は、デフォルトでTERM(SIGTERM)が使用されます。



##bg
一時停止中のジョブをバッググラウンド動作に切り替えるコマンド

##topとfree
メモリやスワップ領域の使用状況を表示するコマンドはfree
topは一定時間ごとに更新して表示するコマンドそれで領域とかも含まれているって訳か。

##nohup
バックグラウンドでジョブを実行中にログアウトすると、シェルと同時にそのシェルの子プロセスであるジョブも終了してしまう。ログアウトのあともジョブを実行させたいならnohupコマンドを使う。

バッググラウンドで実行するにはコマンドラインの末尾に＆をつけて実行する。
nohup ping localhost > ping.txt &
です。

##pstree
動作中のプロセスの親子関係をツリー状で表示するコマンド
psコマンドで現在実行中のプロセス確認もする事ができる。→axfでね・

普通のtreeはプロセスではなく、ディレクトリやファイルの親子関係をツリー状で表示するコマンド。

##シグナル
HUP　１　ハングアップ（再起動）
INT　２　割り込みによる終了
CONT 18 一時停止のプロセスを再開
STOP １９　一時停止
TSTP 20 端末から入力された一時停止

##top
プロセス稼働状況を一定時間事に更新して表示するコマンド
CPUやメモリの使用状況を確認する事ができる。デフォは5秒事に。　qコマンドを押すと終了する。

##jobs
現在バックグラウンドで動作しているジョブと一時停止のジョブを表示するコマンド
fg　バッググラウンドで動作中もしくは一時停止中のジョブをフォアグラウンド動作に切り替える
bg 一時停止中のジョブをバッググラウンド動作に切り替える

##renice
niceは実行優先度を指定してコマンドを実行する。
すでに起動しているプロセスのnice値を変更するコマンド
プロセスIDなどを指定して、実行中のプロセスの優先度を変更するコマンドです。複数のプロセスを同時に指定することも可能です。

nice値は-20〜１９まである。優先度が低いのが１９、高いのが-20.
デフォルトは0 0~-20に関してはrootのみ変更可能

niceコマンドの書式は以下のとおりです。

nice [-n nice値] コマンド
または
nice [-nice値] コマンド
niceで何も書いてない場合は、デフォルトとして10が設定されている。

renice [-n] nice値 オプション
-u　指定したユーザが所有する全てのプロセスnice値を変更
-p PID　指定したプロセスIDのnice値を変更する。

-u ユーザ名　指定したユーザが所有する全てのプロセスのnice値を変更する
-p PID 指定したPIDのプロセスのnice値を変更
(ーpは省略することもOK）

プロセスのnice値を表示するコマンド→top / ps l

##fg,fg2
バックグラウンドで動作中、または一時停止中のジョブをフォアグラウンドに切り替えるには、fgコマンドでしょ。
![名称未設定.pngっっl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620109/1fdbfd5d-0e0a-2d1f-473c-fa59bb6b7a1b.png)

##jobs
現在バッググラウンどで動作しているジョブと、一時停止中のジョブを表示するコマンド。
「Running」はバックグラウンドで動作中、「Stopped」は一時停止中のジョブを表します。

##仮想端末
Linuxはマルチユーザー、マルチタスクのOSであり、複数人で同時に接続して操作できるよう制御されています。それぞれの入力（キーボードやマウス）、出力（ディスプレイ）環境のことを「端末（またはターミナル：Terminal）」と呼びます。

通常Linuxの管理などで作業する際にはリモートから端末プログラム（TeraTerm, Putty、telnetなど）を使って接続を行います。実機の実キーボード、ディスプレイを操作する場合でも、OS上の端末プログラム（gettyなど）が入出力制御を行っています。
ですが、作業内容によっては処理状況を見ながらコマンドを実行するなど、複数の端末を使いたい場合があります。この場合、多数の端末プログラムを使用するのではなく、仮想端末を制御するプログラムを動作させることで、一つの端末上で複数の端末を利用できるようになります。

また、仮想端末制御プログラムを使うことで、開いている仮想端末をサスペンド状態で切り離し（デタッチ）、再度別の環境から仮想端末に接続する（アタッチ）、端末画面を分割して複数の仮想端末画面を同時に表示する事ができるなどのメリットがあります。

仮想端末制御プログラムとして、screenやtmuxがあります。
dockerのマウントについて　初学者なりに考えた。  自分用のメモ

#マウントについて

##バインドマウント（bind）
Dockerホストのファイルやディレクトリをコンテナ上にマウントする機能
バインドマウントを行うと、コンテナの外にあるファイルを、コンテナの中から読み書き可能になります。

##ボリュームマウント（volume）
Docker が管理するデータ領域を コンテナ上にマウントする機能です。

バインドマウントとの違いは、バインドマウントが「Dockerが管理するデータ領域以外もマウント可能である」ことに対し、ボリュームマウントは「Dockerが管理するデータ領域内でのマウントのみ可能である」という点です。

ホストマシン上に新たなディレクトリが生成され、そこが Dockerの保存ディレクトリとなります。 そしてDockerはそのディレクトリ内の内容を管理していきます。コンテナが破棄させるとvolumesに保存される。ホストのデータが更新され、コンテナを立ち上げれば、volumeの既存データもupdateされる。


##一時ファイルシステムのマウント（tmpfs）
Dockerホストにファイルとして保存したくないデータを一時的に利用できるようにする（データ領域をメモリ上に置く）機能。


##ホストマシンとは　

ホストマシンとコンテナでディレクトリを同期させることができるが、 注意しておきたいのが, ここでいうホストマシンとはMacのことではない。
Mac上で起動しているのはdockerの仮想Linuxマシンであること。そもそもコンテナというものはLinuxカーネルに使われている技術。したがってMacでコンテナ技術を使うためには, 間に仮想Linuxマシンをはさまなくてはならない。
Macとコンテナはデータのやりとりができないのかというとそうではない。 仮想Linuxマシンからは, Mac全体が/Macとして参照できるらしい。
つまりMac全体が仮想Linuxマシンにマウントされているとのこと。 他にもMac上の/Usersが仮想Linuxマシンからも/Usersでアクセスできる。


実際にdocker run コマンドを使用しバインドマウントを行って見た。
Hostディレクトリ構成


```bash
docker run -it -d -p 8080:80 -v /Users/hamadayuuta/Desktop/test_dk/test3/:/var/lib/test/ nginx:latest 
```
バインドマウント先は任意のコンテナ内のディレクトリが作成可能。

/User~ : まではホストのターゲットpath
/var/lib/ → dockerコンテナ内のpath。環境はlinux環境
/test/は任意のディレクトリを作成。　ここがマウント領域になる。

docker exec -it nginx:latest /bin/bashで見にいくと

```bash
root@b00e211eff2b:/# cd ./var/lib/test/
root@b00e211eff2b:/var/lib/test# ls
index.html
```
マウントを確認。

docker inspectで確認すると

```bash
"Mounts": [
            {
                "Type": "bind",
                "Source": "/Users/hamadayuuta/Desktop/test_dk/test3",
                "Destination": "/var/lib/test",
```

マウントを確認できました。

コンテナはlinuxのプロセス空間を用いて作成したものであるから、 マウントをする際はlinuxのディレクトリ構造をイメージして作成しないといけないかな。→間違えてたらすみません。
substringで指定範囲だけ大文字にする。(substringの使い方）

```java
/*
substringは文字を抜き出す。
引数には文字のインデックスが入る。
※インデックスは０から
*/

/*
引数が二つの場合
例:
String str = "012345";
substring(開始位置, 終了位置);
substring(0, 3)
抜き出される文字は[012]
※終了位置は3であるが抜き出される文字には含まれない。

引数が１つの場合は開始位置とする。
例：
String str = "012345";
substring(開始位置);
substring(3);
抜き出される文字は[345]
*/

/*
※空白はインデックスに含まれる
String str = "0 12345";（半角の空白）
substring(開始位置);
substring(3);
抜き出される文字は[2345]になる
*/

import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        
        int a = sc.nextInt();
        int b = sc.nextInt();
        sc.nextLine();
        String str = sc.nextLine();
        
        System.out.println(str.substring(0, a - 1) + str.substring(a - 1, b).toUpperCase() + str.substring(b));
    }
}
【C#】アクセシビリティ レベル

###アクセシビリティ

|アクセシビリティ|内容|
|:---|:---|
|public|アクセス制限なし|
|protected|クラス内、派生クラス内からのみ|
|internal|同一プロジェクト内のクラスからのみ|
|protected internal|同一プロジェクト内のクラス内、または派生クラスの内部からのみ|
|private protected|同一プロジェクト内のクラス内かつ派生クラス内からのみ|
|private|クラス内からのみ|
【Go言語】 time.Time - t.Sub(u)はu→t の実際の経過時間を返さない（かもしれない）

# 問題

[time.TimeのSubメソッド](https://golang.org/pkg/time/#Time.Sub)を利用すると、２つのtime.Time間のDurationを取得することが出来ます。

例えば↓なカンジで処理時間を計測したりします。

```Go
start := time.Now()

(何か処理)

elapsed := time.Now().Sub(start)

fmt.Println(elapsed)
```

このコード自体間違いではないですが、今回実行していて明らかに実際の経過時間を返していない事象に遭遇し、軽くハマりました。
9:02にスタートし9:10に終了しているのに、elapsedに `3m` などと出力されたり。

startとnowも出力↓
> start:2020-07-08 09:02:00.243095 +0900 JST m=+0.003321332
> now:2020-07-08 09:10:25.388989 +0900 JST m=+222.388991487
> elapsed:3m42.385670155s

startとnowも確かに正しい日時が入っています。何が起きているのでしょうか・・・ 🤔
（鋭い人はこのログでピンと来てそうですね）



# タネあかし

ログを見ると `m=+222.388991487` みたいな出力が見られます。
これの単位を秒とみなすと、nowとstartの差分がちょうどelapsedと一致します。

これは実はmonotonic clockと呼ばれるものです。time.Timeは時刻を表す情報（**wall clock**）とは別に時間計測に使う為の情報（**monotonic clock**）を持つことが出来ます。`time.Now()` で作成したtime.Timeは内部にmonotonic clockを持ちます。

Subメソッドの様な時間経過を得る為の関数[^1]はwall clockよりmonotonic clockを優先的に使用して計算を行います。それにより、例えば処理中にOS時刻を変更されたりしても、正しく経過時間を取得することが出来ます。

[^1]: 他にtime.Since(start)、time.Until(deadline)、time.Now().Before(deadline)などが同様にmonotonic clockを利用します。

さてここまで見る限り処理時間の計測方法としては正しいと思われる（実際正しい）のですが、なぜズレが生じてしまったのでしょうか。

公式ドキュメントにそのものズバり書かれていました(-ω-;
https://golang.org/pkg/time/#hdr-Monotonic_Clocks

> On some systems the monotonic clock will stop if the computer goes to sleep. On such a system, t.Sub(u) may not accurately reflect the actual time that passed between t and u.

「いくつかのシステムではコンピューターがスリープした場合monotonic clockが停止して、t.Sub(u)が実際の経過時間を返さないことがある」とのことでした。

そうです。今回私は実行中に何度かスリープ→回復していたのです。[^2]

[^2]: 実行環境はMacBook Pro（macOC10.15.5）です。

明示的にwall clockで計算したい場合は、t.Sub(u)のt、uどちらかのmonotonic clock情報を削除すればOKです。
monotonic clock情報は `t = t.Round(0)` の様にすれば削除出来ます。

# 最後に

monotonic clockについては、今まで「時間計測に使用される」、「monotinic timeが違うと同時刻のt.Timeを==演算子で比較してもfalseになる」くらいの曖昧な知識しかありませんでした。

time.Timeのドキュメント見ると真っ先にmonotonic clockの説明が書かれているのに、全然読んでませんでした（猛省）。
公式ドキュメントはちゃんと読まなきゃですね。。


# 参考にした記事

* [Go1.9から使える Monotonic Clocks を試してみた](https://shogo82148.github.io/blog/2017/06/26/go19-monotonic-clock/)
【C#】用語集

自分が学習する際に調べた用語集  ※随時更新

★オブジェクトとは
・操作や処理の対象になる実体を表す。
・オブジェクトの作成には「new」する。

```C#:Test1.cs
var testObject = new Test();
```

---
★クラスとは
・プロパティ(属性)とメソッドを定義するモノ。

---
★インスタンスとは
・クラスを基に具現化されたモノ(newされたモノ)。

---
★コンストラクターとは
・インスタンスを正しく初期化するためのメソッド。
・型名と同じ名前でメソッド定義が可能。
・戻り値を返すことは不可。

 ```C#:Test2.cs
class SampleConstructor
{
    SampleConstructor()//コンストラクター
    {
        //インスタンスの初期化用コードを記述
    }
}
```

---
★型推論とは
・変数宣言にvarキーワードを使用し、右辺に設定された方を自動で決定する。

---
★匿名クラス
classを定義することなく名前なしクラスの使用が可能。

---
★メンバー変数とは
・クラス内で宣言される変数。

```C#:Test3.cs
アクセシビリティ 型 変数名;
(例)
private int Sample;
```
アクセシビリティのレベルは[こちら](https://qiita.com/sasami_dc2/items/284315e3e221a0f1733c#%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B7%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3)

---
★「this.」とは
・現在のインスタンスを指定する。

```C#:Test4.cs
public TestClass(string testThis)
{
    this.testThis = testThis;
}
```

---
★デリゲートとは
・引数として関数を1つ受け取れるデータ型(参照型)の分類。

```C#
delegete 戻り値の型 デリゲート名 (関数の仮引数1[,~2,~3]); 
```

---
★ラムダ式とは
・メソッドを変数と同様に扱える
・デリゲードやLINQなどのメソッド記述を簡潔にするための式。

---
★LINQとは
・コレクションの要素を処理するメソッドを集めたライブラリ。
・for文やforeach文を使ったループ処理を簡潔に置き換えることが可能。
※パラメーターの場合は「()」、変数が複数の場合は「,」が必要

```C#:Test5.cs
sahen => uhen  //基準
() => uhen  //変数なし
a1 => uhen  //単一変数
(a1,a2[,a3,a4……]) => uhen  //複数変数
(int a1, int a2[,int ……]) => uhen  //型宣言ありの変数
```
LINQの詳しい使い方に関しては[こちら](https://qiita.com/sasami_dc2/items/c0e6121859f3c9b8248f)

---
★イベントハンドラとは
・イベント発生時に呼び出される処理[^1]


[^1]: JavaScriptの場合は「イベント発生した際に○○の処理へ引き渡す処理」となるので注意
【AmazonConnect】エージェント階層

#はじめに
弊社社内電話をAmazonConnectへ移行しました。
学んだことを記載していきます。
#エージェント階層-概要
エージェント階層は、レポート作成のために**エージェントをチームやグループに整理する方法**です。
5階層までエージェント階層を定義することができ、いずれかの階層にエージェントを紐づけることができます。
以下、エージェント階層作成手順を記載します。

【必要なアクセス許可】
エージェント階層を作成するには、セキュリティプロファイルに [表示 - エージェント階層] アクセス許可が必要です。

※Adminはデフォルトで必要なアクセス許可が付与されてます。
※注記
エージェント階層には場所とスキルセットのデータが含まれる場合があるため、エージェント階層情報をリアルタイムメトリクスレポートで表示するためにも、このアクセス許可が必要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/6496a314-ed38-c8d5-ce3e-3f749ce78ee8.png)
その他、詳細はAWS公式ドキュメントをご参照ください。
AWS > ドキュメント > Amazon Connect > 管理者ガイド >[エージェントのセットアップ階層](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/agent-hierarchy.html)

#エージェント階層-作成
①、[ユーザー]、[エージェント階層] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/ac98bc7a-a93f-0862-70e0-499b279ae8f9.png)
②、名前を入力し、[+] を選択して、階層の最初のレベルを作成します。
　※名前は任意です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/97028818-cdd6-6d27-7f79-a54f66323c37.png)
③、[+] を選択して、階層にレベルを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/cd5eb990-6f75-faa0-54db-ead89ab34f82.png)
④、[保存] を選択して、変更を適用するか、[キャンセル] を選択して元に戻します。

　ヒント
　[保存] ボタンがアクティブでない場合は、エージェント階層を作成または編集するアクセス許可がありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/2ba275bf-ffc1-b0bd-0a9b-d4664deea9ed.png)

#エージェント階層-階層追加
階層を作成したら、グループ、チーム、およびエージェントを上から順に追加できます。
各ユーザーの階層への紐づけは、ユーザー管理画面で紐づけます。

①、[ユーザー]、[エージェント階層] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/680573d4-d5c5-ce72-8d01-42984efbfe9b.png)

②、[+]追加ボタンをクリック。階層に追加したい名前を入力し、レ点をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/afdb0465-6cd8-2f0b-39a9-8a6df6b39897.png)
補足：level5階層まで追加したイメージ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/5fe71da4-947c-3185-bd3b-8e68a2cd5b27.png)

③、ユーザー管理にてユーザーと階層を紐づけるため、ユーザーの編集画面を表示する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/487058a4-7b05-1dcc-d5b1-e650bb92dd81.png)

④、ユーザと紐づけたい階層を選択し、保存ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/1274953e-e3af-89e1-fe2d-7277a25a09a9.png)
#まとめ
AmazonConnectを使用するうえで必須の機能ではありませんが、エージェントの場所およびスキルセットに基づいて整理すると、検索時やレポート出力の際に活用できるのでとても便利です！
Adaloで検索機能を実装する方法

AdaloというNocodeツールで検索機能を実装する際に少し手間取ったので、
備忘録としてQiitaに記します。

この記事はNocodeツールに触り始めたばかりの自分に向けて記載しています。

<img width="225" alt="add-component-textinput.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669022/f24226c1-7244-8eeb-94b5-83b5cda6dc74.png">

まずAdaloというロゴの下の+ボタンを押し、Form&Fieldsカテゴリの中からText Inptを選択します。
そしてページの良きところに配置します。

<img width="647" alt="searchの置き所.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669022/2e896cca-b928-28de-3ce3-d1ac9b0cfb58.png">

先ほど配置したText Inputを選択し、TypeをNormal・Placeholderにユーザーが入力する前に表示しておきたい文を入力します。
Default Valueは空のままで大丈夫です。

<img width="652" alt="custom-filter.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669022/504f45b6-377d-c2f0-6098-e668ed1e7bfe.png">

検索の対象にしたいListを選択し、ADD ANOTHER FILTERからCustom Filterを選択します。
Select column...と記載されているところを選択し、データの何を検索の対象にするか選択します。
次に、Contains・is equal to・is not equal toの中からContainsを選択します。（※部分一致にする場合）
最後にEmptyとなっているところを選択し、Form Inputs→Inputを選択します。

以上で検索機能の実装終了です！
お疲れさまでした！
Sequel pro 反映されない

Sequel Proでクエリからデータを入力した時に値が反映されず、困っていた時の解決法です
# 解決法
内容ボタンを押して、一度適当なテーブルに移動してから、データを入力したテーブルに戻る

実は、きちんと反映されていたらしく、他のテーブルに移動しないと表面上では、反映が映らないみたいです、、
How to use wrap_content with a maximum width?

# How to use wrap_content with a maximum width?

###Androidのレイアウトの問題

wrap_contentのViewに最大幅を設定するにはどうしたらいいか？

![画面サンプル](https://i.stack.imgur.com/TKnp3.png)
↑この例で言えば、吹き出しのところの幅はwrap_contentで内容に合わせて伸縮させたいが、右側の日付の幅を引いた幅を最大値にしたい時。

[StackOverflow: How to use wrap_content with a maximum width?](https://stackoverflow.com/questions/32032468/how-to-use-wrap-content-with-a-maximum-width)

吹き出し（TextView）、日付（TextView）をLinearLayoutに入れて、layout_weightをそれぞれ、1と0にする。

![](https://i.stack.imgur.com/6c3HP.png)
Ruby: Starttls でメールの送信

こちらと同じことを Ruby で行いました。
[Python3: Starttls でメールの送信](https://qiita.com/ekzemplaro/items/c248b52a6f36947af080)
hi-ho.ne.jp で試しました。

ライブラリーのインストール

```bash
gem install mail
gem install dotenv
```

```rb:hi-ho.rb
#! /usr/bin/ruby
# -*- encoding: utf-8 -*-
#
#	hi-ho.rb
#
#					Jul/08/2020
#
# ---------------------------------------------------------------------
require "mail"
require "dotenv"

STDERR.puts	"*** 開始 ***"

Dotenv.load
server = ENV['SERVER']
port = ENV['PORT']
usr = ENV['USR']
password = ENV['PASSWORD']
from = ENV['FROM']
to = ENV['TO']
#
puts server
puts port

str_out = "Good Morning\n"
str_out += "こんにちは。\n"
str_out += "Jul/08/2020\n"
str_out += "PM 15:58\n"

mail = Mail.new do
  from    from
  to      to
  subject "Hello from Hi-ho PM 15:58"
  content_type 'text/plain; charset=UTF-8'
  body    str_out
end

mail.delivery_method(:smtp,
  address:        server,
  port:           port,
  authentication: :login,
  user_name:      usr,
  password:       password
)

mail.deliver

STDERR.puts	"*** 終了 ***"
# ---------------------------------------------------------------------
```

```text:.env
SERVER = 'hi-ho.mose-mail.jp'
PORT = 587
USR = '****@hi-ho.ne.jp'
PASSWORD = '****'
FROM = '****@hi-ho.ne.jp'
TO = 'sample@example.com'
```

実行結果

```text
$ ./hi-ho.rb 
*** 開始 ***
hi-ho.mose-mail.jp
587
*** 終了 ***
```

次のバージョンで確認しました。

```text
$ ruby --version
ruby 3.0.4p208 (2022-04-12 revision 3fa771dded) [x86_64-linux]
```
【CSS】インライン要素の行間を調整しながら、CSSでマーカーを引く

linear-gradient　を使って、マーカー風のCSSをつけることがよくあるのですが、インライン要素の場合、line-heightが効かずに戸惑うことがちょこちょこあったので、メモ。

####親要素にline-heightを設定する

親要素に line-height を設定することで、小要素の line-height が設定できる様になります。

例：

```HTML

<div class="parent">
  <p class="child">テキストテキストテキスト</p>
</div>
```

```CSS

.parent {
  line-height: 1;
}

.parent .child {
  display: inline;
  line-height: 1.8; <- きく！
  background: linear-gradient(transparent 60%, #faaa1e 60%);
}
```
【AmazonConnect】クイック接続(問い合わせの転送の設定)

#はじめに
弊社社内電話をAmazonConnectへ移行しました。
学んだことを記載していきます。
#クイック接続-概要
クイック接続は、通話転送機能のことです。
転送先のリストを事前作成することで、エージェントが通話時に転送リストを利用し転送することが可能です。

クイック接続を作成するときは、次のいずれかの宛先を指定できます。

・[エージェント] — 問い合わせフローの一部として特定のエージェントに転送されます。
コントロールパネル (CCP) のクイック接続のリストに個別に表示する場合は、各エージェントを手動で追加する必要があります。
・ [キュー] — 問い合わせフローの一部としてキューに転送されます。
・ [外部] — 外線番号を直接入力することで、外部へ転送されます。

【重要】
・エージェントとキューのクイック接続は、エージェントが問い合わせを転送するときにのみ CCP に表示されます。
・CCPに表示するには以下ステップ1、ステップ2の作業が必要です。

その他、詳細はAWS公式ドキュメントをご参照ください。

- AWS > ドキュメント > Amazon Connect > 管理者ガイド >
[問い合わせの転送の設定(クイック接続)](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/transfer.html)

以下、ステップ１より作成手順を記載していきます。
#ステップ 1: クイック接続を作成する
1.クイック接続を作成するには
[ルーティング]、[クイック接続]、[新規追加] の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/5548aa21-38fb-f376-6b18-a19fb4e90fa8.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/39a88bca-7001-2692-b76e-9ad921b7e359.png)
2.接続の名前を入力します。タイプを選択し、宛先 (電話番号やエージェント名など)、問い合わせフロー (該当する場合)、説明を指定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/e0d96179-3e30-10e8-bcde-4050b05e794d.png)
問い合わせフローのタイプにご留意ください。

3.クイック接続をさらに追加するには、[新規追加] を選択します。
4.[保存] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/4053434c-cf83-ccf9-25f1-6f64b0603f76.png)

#ステップ 2: エージェントがクイック接続を確認できるようにする
エージェントが問い合わせを転送したときに CCP でクイック接続を確認できるようにするには
1.クイック接続を作成した後で、[Routing]、[Queues] に移動し、問い合わせのルーティング先として適切なキューを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/ee946676-e464-7b90-8f37-70445b1acc59.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/f19d666c-2861-51cd-7eaf-4bdb37bf86e5.png)
2.[キューの編集] ページの [クイック接続] ボックスで、作成したクイック接続を検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/5e6aa137-678d-5570-ba1b-2356ad16876c.png)
3.クイック接続を選択し、[保存] を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/fd514adf-b727-5ed0-7ca9-47acbe6e64d7.png)

ヒント
エージェントには、ルーティングプロファイル内にあるキューのすべてのクイック接続が表示されます。
#クイック接続-通話の転送管理
転送が開始されると、お客様は保留になり、転送先に接続されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/afc0b61b-1df1-6e94-94b0-3285c02691b4.png)

#まとめ
予めクイック接続(転送リスト)を作成しておくと、スムーズに担当者へ転送することが可能になるのでお勧めです！
Docker ComposeのMySQLに初期データを設定する

# 初期データ

`initdb.d`フォルダを作成して`init.sql`と`pet.txt`を配置する。

`init.sql`の内容は**テーブル削除、作成**と**データ挿入**を記述

```sql:init.sql
drop table if exists pet;
create table if not exists pet (
       name varchar(20)
       , owner varchar(20)
       , species varchar(20)
       , sex char(1)
       , birth date
       , death date
);
load data local infile '/docker-entrypoint-initdb.d/pet.txt' into table pet;
```

`pet.txt`の内容はテーブルに挿入するデータをcsv形式で記述

```csv:pet.txt
Fluffy	Harold	cat	f	1993-02-04	\N
Claws	Gwen	cat	m	1994-03-17	\N
Buffy	Harold	dog	f	1989-05-13	\N
Fang	Benny	dog	m	1990-08-27	\N
Bowser	Diane	dog	m	1979-08-31	1995-07-29
Chirpy	Gwen	bird	f	1998-09-11	\N
Whistler	Gwen	bird	\N	1997-12-09	\N
Slim	Benny	snake	m	1996-04-29	\N
```

# 設定

`docker-compose.yml`の`volumes`に初期データフォルダを記述する。
ローカルの`initdb.d`フォルダをコンテナ内に`docker-entrypoint-initdb.d`フォルダで配置する。
[dockerhub - mysql](https://hub.docker.com/_/mysql/)

```yml:docker-compose.yml
version: '3.8'

services:
  mysql:
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      - db_data:/var/lib/mysql
      - ./initdb.d:/docker-entrypoint-initdb.d
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: my_test
      MYSQL_USER: mysql
      MYSQL_PASSWORD: mysql

volumes:
  db_data: {}

```

# 起動

いつも通りにコンテナを起動する。

```sh
$ docker-compose up -d
```

 終わり


# 起動後にデータを入れ直す

コンテナを`down --volumes`して再度`up`すれば良いんだろうけど。。。
別の方法と言うことで、

コンテナ内に入る。

```sh
$ docker-compose exec mysql /bin/bash
```

コンテナ内でmysqlコマンドをバッチモードで実行する。

```sh
# mysql -u mysql --password=mysql my_test < /docker-entrypoint-initdb.d/init.sql
```

コンテナ内から出る。

```sh
# exit
```

 ほんとに終わり
Cloak for Visual Studio Codeの使い方

## はじめに

[Cloak for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-cloak)は、[Visual Studio Code（以下、VSCode）](https://azure.microsoft.com/ja-jp/products/visual-studio-code/)を使ってプレゼンテーションや配信、録画をする場合に`.env`ファイルに保存されている接続情報やID/パスワードを意図せず漏洩してしまうことを防ぐための拡張機能です。使い方について[拡張機能のページ](https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-cloak)をもとに日本語でまとめました。

## インストール方法

VSCodeを開き __[拡張機能]__ - __Cloak__ で検索し、インストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176280/6b65c544-cda5-a46d-b00d-47348bb0dbb7.png)

## 使い方

1. `.env`ファイルを開く
2. コマンドパレットを開く（`F1`）
3. `Cloak`と入力
4. `Cloak: Hide Secrets` を選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176280/4d218ce3-27d5-6e1f-9736-aa660a5e0c6d.png)


`.env`ファイルに保存されている環境変数が隠されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176280/417fd1e4-4c12-f7b7-0307-cd999964fce6.png)
説明を読むと、Cloakはファイルを変更したり、値を別の所に退避させているわけではなく、文字の色（Foreground color）の透明度を00とすることで透明になり隠されているように見えるようにしているとのことです。

## 非表示のカスタマイズ

文字の透明化は`settings.json`に定義されている`cloak.environmentKeys`に定義されている[TextMateRule](https://macromates.com/manual/en/language_grammars)スコープに基づいて行われています。
例えば、

```json:settings.json
{
    "cloak.environmentKeys": "string.quoted.double.env,string.quoted.single.env,source.env,constant.numeric.env",
    "cloak.environmentComments": "comment.line.number-sign.env"
}
```
を次のように変更すると、

```json:settings.json
{
    "cloak.environmentKeys": "string.quoted.double.env,source.env,constant.numeric.env",
    "cloak.environmentComments": "comment.line.number-sign.env"
}
```

シングルクォートで囲まれた値が透明化の範囲から外れることになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176280/371460c4-f2ed-600e-5f5a-71ccd3686e26.png)

設定をデフォルトに戻す場合は、`Cloak: Restore default scopes`を使用します。

## まとめ
現時点では`.env`ファイルのみに対応しているとのことですが、VSCodeを使ってデモや配信、録画をする方は必須と言っても良い拡張機能ではないでしょうか。

- [Cloak](https://marketplace.visualstudio.com/items?itemName=johnpapa.vscode-cloak)
- [Githubリポジトリ](https://github.com/johnpapa/vscode-cloak)