OmniAICreator/Qiita-1.07M huggingface dataset:
MacOSでzshを使う。



# 手順
__1.completionの設定__
`brew uninstall bash-completion`

`brew install zsh-completions`

__2.zshを使用__
`chsh -s /bin/zsh`


__3.bashrcファイル移行__

`cp ~/.bashrc ~/.zshrc`


__4.~/.bash_profileの記述をコピペ__

```~/.bash_profile

# source ~/.bashrc より前の記述は~/.zprofile へ記述します。

source ~/.bashrc

# source ~/.bashrc より後の記述は~/.zloginへ記述します。

```

以上です。

# 参考
## macOS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117099/d046b92a-cb05-ca5c-0c49-d6d53da9c26c.png)


## 参考ページ
https://teratail.com/questions/221637
2分木の探索ー幅優先、行きがけ順(先行順)深さ優先、帰りがけ順(後行順)深さ優先、通りがけ順(中間順)深さ優先探索

応用情報技術者平成29年秋期 午前5

配列A[1]，A[2]，…，A[n]でA[1]を根とし，A[i]の左側の子をA[2i]，右側の子をA[2i＋1]とみなすことによって，2分木を表現する。このとき，配列を先頭から順に調べていくことは，2分木の探索のどれに当たるか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/aa108fbd-97f8-e3bd-14ca-a8d7cfa8dec0.png)


１、幅優先探索
根から近い順に調べていくこと

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/872419b7-341e-d219-4daf-156fd57396ae.png)


２、深さ優先探索
根からできるだけ分岐せずにいちばん深い葉の部分にまで到達してから、ひとつ前の節まで戻り他方の探索を行う方法

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/4796f79d-e0d2-8c75-23e6-cb33582f8bb5.png)


３種類があります：
・行きがけ順(先行順)  **※根から**
　根　→　左の部分木　→　右の部分木　順

・通りがけ順(中間順)　**※葉から**
　左の部分木　→　根　→　右の部分木　順

・帰りがけ順(後行順)　**※葉から**
　左の部分木　→　右の部分木　→　根　順


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/9b6d49e9-1977-dc0a-1660-d4d4eceedeff.png)



参照：

https://www.ap-siken.com/kakomon/26_aki/q4.html

https://qiita.com/shki/items/cc9806564a2690e90fdb

二分木と探索
http://iui.ci.seikei.ac.jp/~takase/wp/wp-content/uploads/2017/05/%E4%BA%8C%E5%88%86%E6%9C%A8%E3%81%A8%E6%8E%A2%E7%B4%A2.pdf
AWSLambdaでPyTorch【EFS編】

#はじめに
本記事はAWSのLambda上でPyTorchを動かして見ようという試みについてのまとめです。DeepLearningタグをつけていますが、学習については触れません。ゴールはLambda上で何かしらの推論を動かしてみるというところまでです。

# ざっくりまとめ
1. EFS使ってみる
2. LambdaでPyTorch
3. slackからも呼ぶ

の三本立てです。


# 背景
AWS Lambdaは非常に構築が楽で便利なのですが、[様々な制限](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-limits.html)があります。機械学習をするときにとくに問題になりそうなのが、デプロイパッケージサイズと`/tmp`領域サイズです。

```sh:デプロイパッケージサイズと/tmp領域サイズ
デプロイパッケージサイズ
50 MB (zip 圧縮済み、直接アップロード)
250 MB (解凍、レイヤーを含む)
3 MB (コンソールエディタ)

/tmp ディレクトリのストレージ
512 MB
```
TensorFlow, PyTorchなどのライブラリも益々巨大化していきますしモデルファイルも大きくなってきています。Lambdaに搭載したいが容量オーバーで諦めるということが往々にしてあります。

2020年6月の[アップデート](https://aws.amazon.com/jp/blogs/news/new-a-shared-file-system-for-your-lambda-functions/)でLambdaがAmazon Elastic File System(EFS)をマウントすることができるようになりました。
これにより以下のような恩恵があります。

- /tmpで使用可能な容量（512MB）より大きいデータを処理またはロードする。
- 頻繁に変更されるファイルの最新バージョンをロードする。
- モデルやその他の依存関係をロードするためにストレージ容量を必要とするデータサイエンスパッケージを使用する。
- 呼び出し間で関数の状態を保存する（一意のファイル名またはファイルシステムロックを使用）。
- 大量の参照データへのアクセスを必要とするアプリケーションの構築。
- レガシーアプリケーションをサーバーレスアーキテクチャに移行する。
- ファイルシステムアクセス用に設計されたデータ集約型ワークロードとの相互作用。
- ファイルを部分的に更新する（同時アクセス用のファイルシステムロックを使用）。
- アトミック操作でファイルシステム内のディレクトリとそのすべてのコンテンツを移動する。

特に今回の場合は、`モデルやその他の依存関係をロードするためにストレージ容量を必要とするデータサイエンスパッケージを使用する。`が該当するでしょうか。

# EFSを用意
EFSの準備は、[先行事例](https://qiita.com/rtaguchi/items/f2b39572299b5399df76)を大いに参考にさせてもらいます。

## EFSの作成とアクセスポイントの準備

## PyTorch用のEC2を準備
Python3.7を使用するつもりなので、AmazonLinuxを指定します。（Python3.8ならAmazonLinux2を利用しましょう。）
Python2系しか入っていないのでPython3.7をインストールします。[この記事](https://qiita.com/hitomatagi/items/e63dd8c4b879de156628)はPython3.8用ですがPython3.7に読み替えておきます。

## EFSをEC2にマウント
[EFSのマウント](https://docs.aws.amazon.com/ja_jp/efs/latest/ug/mounting-fs.html)にEFSマウントヘルパーが必要なので、

```sh
$ sudo yum install -y amazon-efs-utils
```
で入れておきます。

EFSのセキュリティーグループにEC2のセキュリティグループを追加しておきます。
インバウンドルールにタイプを`NFS`とプロトコルに`TCP`、ポート範囲`2049`を指定してソースにEC2インスタンスのセキュリティグループを指定しておきます。

EC2にログインして以下のコマンドを叩きましょう。

```sh
$ sudo mount -t efs [ファイルシステムID]:/ /mnt
```

## EC2で必要なライブラリをインストール
必要なライブラリをインストールします。

```sh
$ sudo pip3 install torch==1.6.0+cpu torchvision==0.7.0+cpu -f https://download.pytorch.org/whl/torch_stable.html
```

これでEFSにPyTorchがインストールできたので、次回Lambdaから読み込みます。([Lambdaでimport編](https://qiita.com/myonoym/items/9f549f010081aeae2cf9))
TextMeshProでアンダーラインが表示されない時の対処方法

## 起きたこと
TextMeshProで、FontStyleにUnderlineを指定しても、アンダーラインが表示されませんでした。

## 原因と対処法
TextMeshProではアンダーラインを表示するために、`_`(アンダースコア)を使っているため、生成したフォントアトラスに`_`が含まれていないとアンダーラインを表示できません。

`Window>Text Mesh Pro>Font Asset Creator>Custom Character List`へ`_`を追加してからフォントアトラスを生成すると解決しました。

## 参考文献
[TextMesh Pro - TMP Fallback font underline bug - Unity Forum]( https://forum.unity.com/threads/tmp-fallback-font-underline-bug.632371/ )
Dockerで使い捨てPHP


## 環境
* Windows 10
* Docker Toolbox

## 目的
使い捨てのPHP環境を構築するため

## 手順

## ディレクトリ構成
```
[d]
┗ [docker]
  ┗ [php73]
    ┣ Dockerfile
    ┗ [src]
      ┗ index.php
```

### Dockerfile作成
ベースイメージはあらかじめ dockerhub で検索しておく。

```dockerfile:Dockerfile

FROM php:7.3.22-apache-stretch
COPY src/ /var/www/html

RUN apt-get update
```

### Dockerfileからイメージをビルドする
```bash
$ cd /d/docker/php73
$ docker build --tag=hellophp .
```

### イメージの一覧を表示してビルドがあるか確認
```bash
$ docker image ls
```

### イメージからコンテナを起動する
```bash
$ docker run -p 5000:80 --name myphp -d hellophp
```

### DockerマシンのIPアドレスを確認する
Docker-Toolbox は localhost ではない。
DockerマシンのIPアドレスを確認する必要がある。

```bash
$ docker-machine ls
```

### 動作確認
確認したIPアドレスとコンテナ起動時のホスト側のポート番号の組み合わせでアクセスできる。

```
http://{IPアドレス}:5000
```

### あと片付け
コンテナのIDを確認して停止させる。

```bash
$ docker ps
$ docker stop {CONTAINER ID}
```

### その他
使わなくなったコンテナは削除もできる。

```bash
$ docker ps -a
$ docker rm {CONTAINER ID}
```
1%のガチャを100回やっても36%は外れる、じゃあ何回回せばいいのって話【確率】

## 何回やればいいって？
1%のガチャを当たるまで引く場合、
確率を95%にするには**299回**
確率を99%にするには**459回**
やればよい。
**何億回やっても100%にはならない。**

## 別の確率のガチャなら？

|  ガチャ確率 | 当たるまで引く回数 | ||
|-------:|------------:|---------:|-----------:|
|         |      95%ライン| 99%ライン | 99.9%ライン |
| 100.00% |            1 |         1 |           1 |
|  10.00% |           29 |        44 |          66 | 
|   1.00% |          299 |       459 |         688 |
|   0.10% |         2995 |      4603 |        6905 |
|   0.01% |        29956 |     46050 |       69075 |
|  0.001% |       299572 |    460515 |      690773 |

上記の表を見ればわかるとおり、結論から言えば、 
**$1/n$の確率で当たるガチャを当たるまで回す場合、
$3×n$回ガチャを回せば95%の確率で少なくとも1回当たる。** 
**$4.61×n$回ガチャを回せば99%の確率で少なくとも1回当たる。**

個人的に95%の場合を **「回数三倍の法則」** と私は呼んでいる。だいたい確率の3倍ぐらいの回数を見込んでガチャやくじ引きはやるとよいからだ。（注：正式な数学用語ではない）
例えば、1/2000の確率で当たるガチャなら約6000回回せば95%の確率で出てくる。

## 以下蛇足

### なぜこの数式になるのか？
以下、高校程度の数学の知識を前提とする。

確率$p$で当たるガチャを、$k$回引いて少なくとも1回は当たる確率$F_p(k)$は、計算すると
$$ F_p(k)=1-(1-p)^k $$となる。（ちなみに、これは[幾何分布](https://ja.wikipedia.org/wiki/%E5%B9%BE%E4%BD%95%E5%88%86%E5%B8%83)の累積分布関数に等しい。）
上記の確率は、「$k$回引いても連続で外れる」確率が$(1-p)^k$であり、それが起こらない確率を求めたいので$1-(1-p)^k $となるのである。
例えば、$p=0.01$の場合、
$$ F_{0.01}(k)=1-0.99^k $$
となるので、例えば$k$に数値を入れると
$$ F_{0.01}(10)=1-0.99^{10} \fallingdotseq 0.095$$$$ F_{0.01}(100)=1-0.99^{100} \fallingdotseq  0.634$$$$ F_{0.01}(300)=1-0.99^{300} \fallingdotseq  0.951$$$$ F_{0.01}(461)=1-0.99^{461} \fallingdotseq  0.990$$$$ F_{0.01}(1000)=1-0.99^{1000} \fallingdotseq  0.999$$となる。

そして、例えば95%ラインについて考える場合、$F_p(k)≧0.95$という条件を満たせばよいので、$$ F_p(k)=1-(1-p)^k ≧0.95 $$$$ 1-0.95 ≧(1-p)^k $$両辺の対数をとって$$ \log(1-0.95) ≧k\log(1-p) $$$1-p<1$なので$\log(1-p)<0$なので$$ \frac{\log(1-0.95)}{\log(1-p)} ≧k $$となるような最大の自然数$k$を求めればよい。
ここで、確率$p=1/n$とおき、$n$が十分大きいという仮定でローラン展開すると、
$$ \frac{1}{\log(1-1/n)} \fallingdotseq  -n + \frac{1}{2} + \frac{1}{12n}+… > -n $$より、
$$-n*\log(1-0.95) >k $$という数式が得られる。計算すると$\log(1-0.95)=-2.9957…$となるので、
$$-n*\log(1-0.95) < 3n $$より
$$ k < 3n $$という数式が得られる。これが「回数三倍の法則」の証明である。
99%ラインを考えるとき、$\log(1-0.95)$をそのまま$\log(1-0.99)$に置き換えればよいので、$\log(1-0.99)=-4.605…$より
$$ k < 4.61n $$
が得られるのである。

## まとめ
**$1/n$の確率で当たるガチャを当たるまで回す場合、
$3×n$回ガチャを回せば95%の確率で少なくとも1回当たる。** 
**$4.61×n$回ガチャを回せば99%の確率で少なくとも1回当たる。**

ガチャは期待値の3倍のお金を考慮して、計画的に回しましょう。

<!--
なぜ100%にならないのか？

これは簡単で、「ガチャは引ききることがない」かつ「何回引いても確率が一定」からだ。
前者は俗に「青天井」と呼ばれている性質で（数学用語ではない）、
後者は「無記憶性」という性質である。
-->
【Node.js】dotenvを使用して環境変数を設定&設定した環境変数をHerokuにも適用する方法

node.jsで環境変数を設定する場合、
「dotenv」を使用すれば楽に設定することができる
色々と遠回りというか勘違いをして時間がかかってしまったのでメモ

#手順
1. ルートディレクトリに「.env」という名前のファイルを作成
2. ターミナルにて`` $npm install dotenv --save ``を実行
3. 1で作成した.envに環境変数として使用したいkey&valueを以下のように記載

```js:.env
NODE_USER_ID=12345678
NODE_PASSWORD=abcdefgh
```
4.環境変数を使用したい箇所に以下のように記載

```js:app.js
require('dotenv').config();
let userId = process.env.NODE_USER_ID;
// 12345678
console.log(userId);
```

以上の手順で環境変数を設定できます。
※.gitignoreに .envを追記するのを忘れないようにしてください。
記載済みであれば大丈夫です。

あくまでもローカル上での設定となりますので、
Herokuにデプロイしているアプリに対して環境変数を適用する方法を以下に記載しました。

#Herokuにデプロイする場合
便利ですよね、heroku。
Githubとherokuを連携している場合、.envファイルをプッシュしていないのでどうしたものかと・・・。

##Config Varsを設定する
1.heroku上部メニューより、Settingsへ遷移
![heroku_menu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656690/7f32f99b-1898-e8a4-d10c-332c37b06b6c.png)

2.「Reveal Config Vars」ボタンをクリック
![reveal_config.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656690/9933dd23-e036-357b-7a8f-bb16f9e2e14a.png)

3.お誂え向きなKEYとVALUEを入力できるフォームが出てくるので、
.envに記載している内容と同等のものを記載し、ADDをクリック
![key_value.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656690/5c318913-07a8-b5c4-63a9-52433c9615b5.png)

以上で、.envをgitに上げなくてもHerokuにデプロイしたアプリから、
環境変数を呼び出すことが可能となります。
私がQiitaに月10本以上投稿する理由

#はじめに
私はIT初心者ですが、今年の６月からQiitaに月10本以上投稿しています。今回はその理由を紹介したいと思います。

#きっかけ
SNS上のフォロワーであるエンジニアさんと話をしていた時、「資格の勉強しているなら、その勉強したことをQiitaでアップすればポートフォリオ代わりにもなるしいいんじゃない？数日に一回のペースで投稿してみたら？」という話になりました。

インフラ系での転職活動を考えていたのですが、そうすると開発系とは違い、なかなかポートフォリオを作成しづらいです。

SNS上のフォロワーさんの中には毎日Qiita投稿される方がいらして、その方は実際転職活動を成功されていました。仕事をしながら毎日の投稿は流石に厳しいと思ったのですが、月10本程度であれば週数回程度なので自分でもできそうと思い、「月10本以上投稿」を目標にして取り組むようになりました。

#投稿する理由
前述のきっかけとも被っていますが、以下の通りです。
##ポートフォリオ代わりになる
特にインフラ系だと開発とは違い、成果物を見せづらいです。
口頭で説明するのにも限度がありますし、そもそも書類選考だと直接説明することはできません。しかしQiitaで日々の成果物をアップロードすれば、技量の判断材料にもなり、さらにはドキュメント作成能力を示すことも可能です。

##理解が深まる
対外的にアップロードする以上相手にわかりやすく、かつ正確に書く必要が出てきます。自分で作るだけなら雰囲気でできてしまうことがありますが、人に説明する場合、他の人にもわかりやすい説明をしなければいけません。記事を書くための情報収集や検証をすることで、より理解が深まると感じました。

##勉強した証明になる
単純に月１０本以上投稿するとなると、常に情報収集や勉強をして、ネタを探さなければいけません。未経験や経験浅い人などポテンシャル採用だと「この人は勉強習慣があるのか？」といった観点も見られるところかと思いますが、Qiitaの定期的な投稿によって、継続した勉強ができるということを証明する１つの材料になるかと思います。

##自信がつく
普通に勉強しただけだと「本当に実力がついたのかな？」と不安になることもありますが、投稿することで自分の実力を可視化することができ、実績にもつながるので自信を持つことができるのではないかと思います。

#注意点
##内部情報の漏洩
企業によってはQiitaの投稿をすることで内部情報の漏洩につながるのではないかと不安になる企業もあるみたいです。そのため、あくまでも自己学習の範囲の内容を投稿をするのがいいかと思います。

##情報の被り
オーソドックスな内容だと、記事の内容が被ることが多くなります。
Qiitaだと同じような内容の記事を投稿することは推奨されていないので、できる限りオリジナリティのある内容を出す必要があります。また著作権や情報公開などの配慮も必要です。

私が行っていることとしては、英語の内容を訳したり、エラーなどで詰まった内容をあげるなどです。
どうしても情報の被りやマサカリが気になれば、他のプラットフォームで投稿するのも１つの手かなと思います。

##無理しすぎない
最初から壮大なものを書こうとすると挫折するので、短い記事から書くのがいいかと思います。
例えば私が過去投稿した記事「[【個人メモ】VScodeのエラー、Expected commajsonc(514)の意味](https://qiita.com/blackpeach7/items/da184a4fa43f8a9e2d47)」のようにすごくシンプルな記事でも、 LGTMついてます。ちょっとしたtipsでも役立つことがあります。

投稿数もネックですが、作業や勉強していたら疑問やつまるところが出てくると思います。肩肘張らずに勉強していたら、自然にアイディアが出てくると思うので、そういった内容を投稿すればいいかと思います。


#まとめ
IT初心者の方には投稿するのが不安な方や初心者が記事を投稿することに反論もあると思いますが、初心者だからこそ出せる記事もあると思います。最初から上手に記事を書ける人はいないので、投稿しながら技術のスキルアップや実績に繋いで行くのがいいかと思います。
Architecture - MVC, MVP, MVVM

https://windsuzu.github.io/learn-android-architecture-pattern/
https://dotblogs.com.tw/regionbbs/2011/09/29/compare_to_mvp_mvc_mvvm
https://medium.com/@shawnloveapp/design-pattern-mvp-4c795729b2e3
https://developer.aliyun.com/article/264718
https://www.ruanyifeng.com/blog/2015/02/mvcmvp_mvvm.html
【Vue.js】何気なく使っているthisとかcontextとかって結局なんなの？？




|オブジェクト|指すもの|使う場面
|:--|:--|:--
|this|Vueインスタンス|現Vueインスタンスを指定する時
|context|・Vueインスタンス生成前のインスタンス・Storeインスタンス|・まだVueインスタンスが作られる前にVueインスタンスを使いたい時。・Storeメソッドを使いたい時。

#thisオブジェクト

###data
Vueインスタンスを指す

```javascript:
data () {
  return {
    email: ''
  }
},
methods: {
  into () {
    this.email = 'foo@bar.com'
  }
}
```

###Vueメソッド
Vueインスタンスを指す

```javascript:
methods: {
  async login () {
    const res = await this.$axios.$get('/login')
  }
}
```



#contextオブジェクト

###asyncData
仮のVueインスタンスを指す

```javascript:
async asyncData(context) {
  const posts = await context.$axios.$get('/posts')
  return { posts }
},
```

<details><summary>`{ posts }`とは</summary>`{ posts: posts }`の略</details>

```javascript:
async asyncData (context) {
  const res = await context.$axios.$get('/posts/' + context.params.id)
  return { post: res.data }
}
```

###Vuexのstoreメソッド
Storeインスタンスを指す

```javascript:
export const actions = {
  async login (context) {
    await context.commit('switchLogin')
  })
}
```
ネットワーク（設計まとめ）

##今回やること
業務で、サーバだけでなくネットワーク側の**L3,FW**の設計知識も必要になりそうだったので、
勉強してまとめたいと思います。
概要レベルでしかわかっていないので、どのように設計するか等、まとめられればと思います。

##各フェーズまとめ
ネットワークを運用に運ぶまでの流れを簡単にまとめます。
**※**ざっくりベースなので言葉足らずですが、ご容赦ください。

恐らくどの分野でも基本的な流れは同じかと思います。

|フェーズ|内容|
|:-----|:-----|
|①　要件定義|顧客からRFPをもらい、要件をヒアリング後、要件定義書を作成する。|
|②　基本設計|簡単に言うとネットワークのルール決め。決まったものを基本設計書に落とす。|
|③　詳細設計|各機器のパラメータを決める。決めたパラメータを詳細設計書に落とす。|
|④　構築|詳細設計書をもとに、機器を設定していく。|
|⑤　試験|作成した試験仕様書をもとに正常試験と障害試験をする。|
|⑥　運用|構築が終わったシステムを安定的に提供する。|

こんな感じでしょうか。

ひとくちに基本設計と書いてますが、基本設計をもっと細かくすると
ボリュームとしてはかなりのものになります。
基本設計に限った話ではないですが。

物理設計だったり、論理設計だったり、セキュリティの設計だったりと、やることが多いですね。

今回は論理設計とセキュリティ設計にフォーカスしていきます。

##論理設計
論理設計って何するの？となったのでまとめてみます。

|設計項目|概要|
|:-----|:-----|
|論理設計方針決め|論理設計の全体的な方針決め　|
|VLAN設計|どのようにVLANを割り振りしていくか決める|
|IPアドレス設計|どのようにIPを割り振りするか決める|
|ルーティング設計|どのようにルーティングするか決める|
|アドレス変換方式|主にNATの設定（インかアウトか）|

ざっくりとこんな感じでしょうか。

####まずVLAN数を洗い出す
必要なVLAN数を洗い出していくことからスタート。
顧客環境で使用する機器だったり、機能だったり、セキュリティだったり様々な要因で
変わってくるので基礎知識が本当に大事だと思っています。

一概には言えないかもしれませんが、
一般的にISPの指定に応じる形でVLANを割り当てるらしいです。

ISPと顧客の境界に設置するCEルータだったりスイッチだったりを
ISPからレンタルで設置するケースも増えてきているそうな。

このケースだとISP側次第でVLANの割り当てが変わるそうです。

といっても、割り当てはL3スイッチの外側と間と内側なので、設計する人が気にするのは
内側のVLANになりそうですね。

####CEスイッチとファイアウォール
ファイアウォールの外側のVLANでL3スイッチに接続するのが一般的みたいです。
ファイアウォール自体は外側と内側でVLANを分けるのが一般的なようです。

ファイアウォールの機器で色々変わってくるかとは思います。
というより、構成自体で全部変わっちゃうので一概には言えない部分ですね。

Ciscoの**ASAシリーズ**だと冗長構成時に別でVLANが欲しかったり、
ジュニパーの**SSGシリーズ**だと別VLANは必要ないように、それぞれで変わってきますね。

設計者は機器の特徴を調べないといけない点が非常に重要になってくるように感じます。

今のご時世、仮想化環境が多いと思うので、そちらの知識を重点的につけていきたいところです。

##まとめ
今回の記事には論理設計の中のL3とFWについて書いてみました。
他にもNATの設計のことを勉強していましたが、理解があまりできていないので
文におこせない状況でした。

NATの理解も必須になると思うので、勉強を引き続き行って、
文におこせるレベルにもっていきたいと思います。

以上となります。
UTF-7、UTF-8、UTF-16、UTF-32

応用情報技術者平成29年秋期 午前4


UTF-8の説明に関する記述として，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/b839e1a2-f115-e5a3-adc4-d8ade06dd1e3.png)


１、UTF-8は、
ASCIIと同じ文字は1バイト、その他の文字については2～6バイトを用いて世界中の文字を表現する文字符号化形式です。ASCIIの上位互換であるため、従来のシステムとの親和性が高く、またASCII主体のテキストであればデータ量をそれほど増加させずに多言語対応の恩恵を受けられる利点があります。UTF-8は世界中で使用されていますが、特にWebページを記述する際の文字コードとしてはスタンダードと呼ばれるほど普及しています。
UTF-8は可変長なので先頭のビット"1"が連続する個数で、その文字のバイト数がわかるようになっています。なお漢字を含む日本語の文字は3バイトで表現されます。


２、UTF-7の説明
ASCII文字だけを使用することが前提の電子メールで利用するために，7ビットで表現する。


３、1文字を2バイトで符号化する　UTF-16(UCS-2)
2バイトで表現する領域に収まらない文字は，上位サロゲートと下位サロゲートを組み合わせて4バイトで表現する。


４、1文字を4バイトで符号化する　UTF-32(UCS-4)の説明
各符号位置が4バイトの固定長で表現される符号化形式である。


参照：
https://www.ap-siken.com/kakomon/29_aki/q4.html
Laravelの配列操作ラッパー、Collectionを単品で使用してみる

## 概要

Laravelのcollectionが便利なので単品で使いたい
[コレクション -Laravelドキュメント](https://readouble.com/laravel/7.x/ja/collections.html#introduction)

## install
```
% composer require illuminate/support
```

## code
sample.php

```php
<?php
require_once "vendor/autoload.php";

$array = ['key' => 'value'];
$collection = collect($array);
var_dump($collection);
```

## 結果
```
% php sample.php 
object(Illuminate\Support\Collection)#3 (1) {
  ["items":protected]=>
  array(1) {
    ["key"]=>
    string(5) "value"
  }
}
```

できた！

## 参考
* [LaravelのORM、Eloquentを単品で使用してみる](https://qiita.com/igayamaguchi/items/16bad23bd4e4cbed337a)
* [Packages from illuminate](https://packagist.org/packages/illuminate/)
* [Dockerにcomposerをインストールする方法の正解](https://blog.hanhans.net/2019/01/08/docker-composer/)

## おまけ

docker-compose.yml

```docker
version: '3'
services:
  php:
    container_name: php-collection
    build:
      context: .
      dockerfile: docker/php/Dockerfile
    volumes:
      - ./php:/var/www
    tty: true
    working_dir: /var/www
    env_file:
      - ./.env
```

Dockerfile

```dockerfile
FROM php:7.4

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

RUN cp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime \
    && apt-get update \
    && apt-get install -y zip unzip
```

build & 起動 & 実行

```
docker-compose build php
docker-compose up -d
docker exec -it php-collection /bin/bash

composer require illuminate/support
vi ./sample.php
php ./sample.php
```
FlutterでTextFieldのフォーカスを正しく外す方法

# 環境

Flutter 1.20.3


# 方法


```
return Scaffold(
  body: GestureDetector(
    onTap: () {
      final FocusScopeNode currentScope = FocusScope.of(context);
      if (!currentScope.hasPrimaryFocus && currentScope.hasFocus) {
        FocusManager.instance.primaryFocus!.unfocus();
      }
    },
      child: TextField(),
  ),
);
```

参考：
https://github.com/flutter/flutter/issues/54277

# 余談

ググるとstackoverflowとかトップ辺りに出てくる情報だと、大体下記の方法を紹介されています。

```
return Scaffold(
    body: GestureDetector(
        onTap() {
            FocusScope.of(context).unfocus();
        },
        child: TextField(),
    ),
);
```

ただ、この方法だとGitHubのissuesにあるように、Drawerを閉じたときに再度TextFieldがフォーカスされキーボードが開いてしまいます。どうやら少し古いバージョンであればこれでも問題なかったようです。

日本語でこのことに関して説明された記事等がなさそうだったので、備忘録も兼ねて書いておきます。


# 2022/10/03 追記
コードをNNBDに対応したものに変更しました。
javascript関数ドリル　初級編initial関数の実相のアウトプット

##initial関数の課題内容
詳細はこちら
　　　↓
https://js-drills.com/blog/initial/

##initial関数の取り組む前の状態
配列の一番初めに何かをするのかと思った

##initial関数に取り組んだ後の状態
popメソットが配列の最後を取り除くことが分かった

##initial関数の実装コード（答えを見る前）
実行できませんでした

##initial関数の実装コード（答えを見た後）

```js
function initial(array) {
  const copiedArray = [...array];
  copiedArray.pop();

  return copiedArray;
}

const numbers = [1, 2, 3];
console.log( initial(numbers) );
// => [1, 2]

console.log('number : ', numbers);
```
【PHP】TrueとFalseを出力する

![<LABEL>-<MESSAGE>](https://img.shields.io/badge/PHP -7.3.11-<COLOR>)

# やりたいこと
trueはtrue、falseはfalseと出力したい。

## うまくいかなかった方法
配列をtrueとfalseで初期化し、値を出力した。

```php
$tf = array(true,false,true,false);

for($i = 0;$i < 4;$i++){
    print $tf[$i]."<br>";
}
```

### 結果
trueは1、falseは""と出力される

```php
1

1
```

## うまくいった方法
出力の際にvar_exportを使った。

```php
$tf = array(true,false,true,false);

for($i = 0;$i < 4;$i++){
    print var_export($tf[$i])."<br>";
}
```
### 結果
trueはtrue、falseはfalseと出力される。

```php
true
false
true
false
```

# まとめ
PHPはtrueとfalseがそのまま出力されないため、var_exportが必要。
【Kotlin】"AES/CBC/PKCS7Padding"での暗号化・復号化

### 暗号化

```Kotlin
fun String.encrypt(): String {
	//それぞれ16文字にする
	val secretKey = "abcdefghijklmnop"
	val initializationKey = "ABCDEFGHIJKLMNOP"
	val key = SecretKeySpec(secretKey.toByteArray(), "AES")
	val iv = IvParameterSpec(initializationKey.toByteArray())

	val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
	cipher.init(Cipher.ENCRYPT_MODE, key, iv)

	val byteResult = cipher.doFinal(this.toByteArray())

	return Base64.encodeToString(byteResult, Base64.NO_WRAP)
}
```

### 復号化

```Kotlin
fun String.decrypt(): String {
	//それぞれ16文字にする
	val secretKey = "abcdefghijklmnop"
	val initializationKey = "ABCDEFGHIJKLMNOP"
	val key = SecretKeySpec(secretKey.toByteArray(), "AES")
	val iv = IvParameterSpec(initializationKey.toByteArray())

	val cipher = Cipher.getInstance("AES/CBC/PKCS7Padding")
	cipher.init(Cipher.DECRYPT_MODE, key, iv)

	val byteResult = cipher.doFinal(Base64.decode(this, Base64.NO_WRAP))

	return String(byteResult)
}
   ```
QGISの基本操作

## はじめに
先日、PostGIS機能でジオメトリ型のデータを作成して、それをQGIS上で表示する手順をまとめたので([こちら](https://qiita.com/smiler5617/items/220050cb06ae9a71c0ed))、今回はその続きとして自分が良く使うQGISでの基本操作をまとめてみた。

## 実行環境
【PC環境-OS】
　　・Windows 10 Pro　

【ソフトウェア-バージョン】
　　・PostgresSQL 10.13
　　・PostGIS 2.5
　　・QGIS 3.10.6

## 今回やる事

１．今回のサンプルデータの中身
２．QGIS上でシェープファイルを開く
３．QGISの基本操作


### １．今回のサンプルデータの説明

以下のデータをサンプルとして用意。
※今回、QGISからの読み込み先データソースはPostgreではなくシェープファイル（[Git](https://github.com/Smiler5617/for_qiita/tree/master/sample_shape)）
![Qiita-no007_img01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/f3e342e0-d772-66e4-cff8-13f368a54aa6.jpeg)
（postgreのテーブルからシェープファイルをエクスポートする方法は[こちら](http://mf-atelier.sakura.ne.jp/mf-atelier/modules/tips/index.php/software/postgreSQL-postGIS/postGIS_shp.html)のサイトを参考）


### ２．QGIS上でシェープファイルを開く
上記Gitから5つのファイルを全て同じディレクトリにダウンロードすると、以下の様にレイヤとして表示される。
![Qiita-no007_img02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/c359dac4-2ee6-b82f-6789-7a4d6c478008.jpeg)
ダブルクリック or ドラッグ＆ドロップでレイヤのキャンバスの方に持っていけばOK！
（背景として、XYZ Tilesのどれかもレイヤに持っていく。）


### ３．QGISの基本操作
デフォルトはこんな感じになっている思うので、これを簡単に加工してみる。
（下図の背景はGoogleMap。）
![Qiita-no007_img03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/bd0ba923-4982-b2f8-16be-a4b89a3b5175.jpeg)

・右クリック『プロパティ』を選択。＜シンポロジ＞より違うマークにしたり、枠線をつけたり、透明度を変えたりできる。
![Qiita-no007_img04.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/2f6f249d-0bc8-3a77-2324-b4e8cfc6c435.jpeg)


・右クリック『フィルター』より元のデータに対して絞り込みをする。下の図は "A社" のみにした場合。
![Qiita-no007_img05.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/0611b2ca-66d0-3fc6-a9d1-b583facce764.jpeg)


・右クリック『プロパティ』を選択。＜シンポロジ＞より【連続値による定義】に変更。
![Qiita-no007_img06.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/ac7aa273-a453-bb63-a316-2026ef194a5d.jpeg)
下図の<font color="red">赤枠</font>部分を設定して『OK』をクリック。（さっきのフィルターは外している）
![Qiita-no007_img07.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/22fba885-e6fd-49f1-3474-8ead15ee22d9.jpeg)


・「プロパティ＞シンポロジ」より【ルールによる定義】にして、会社毎にマークを変えてみる
![Qiita-no007_img08.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/2f67bffe-5063-c057-58df-1ec29b3598b3.jpeg)
<font color="red">赤枠</font>部分の設定を行い『OK』をクリック
（ラベルの追加・削除は＜シンポロジ＞画面の『＋』『－』で行える。）
![Qiita-no007_img09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/064d06d3-5d6e-00f5-4002-d0a863433a09.jpeg)
上図の様に設定した状態で地図を見てみる。
![Qiita-no007_img010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/fccfefb7-7bb9-f6d6-0187-f3f643126bb4.jpeg)


・レイヤのエクスポート
右クリック『エクスポート ＞ レイヤ定義ファイルとして保存』をクリック。
![Qiita-no007_img011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/75f09c5e-a824-9dcd-f62d-90956eb387b3.jpeg)


・レイヤのインポート
![Qiita-no007_img012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/654767/8a26514f-d899-b6d8-5bbf-0dc315a48854.jpeg)


**以上、QGISの基本的な操作でした！**


## まとめ
今回はQGISの基本操作についてまとめました。
また時間がある時にこれらの操作を応用した表現の仕方なども整理したいと思います。
IBM  Cloud Kubernetes Clusterをインストールする(Classic Infrastructure)

# この記事は
VPC Gen 2上にIKSを作成したところ、インストールしたいHelm chartが対応していないことが判明したので、Classic Infrastructure上にIKSを構築し直します。

# IKSのセットアップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445368/41a99037-692c-d160-4665-318d031b3f50.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445368/05348d61-de1f-63a3-abb3-3ddf6d92a0c3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445368/2ecc09bd-9ae4-800c-3303-53c4f67cd7b9.png)
multiple zoneで使用するにはVRFかVLANスパニングを有効にしてくださいと書かれているので、あとでVLANスパニングを有効化するようにします。

# VLANスパニングの有効化
https://cloud.ibm.com/docs/vlans?topic=vlans-vlan-spanning#manage-vlan-spanning
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445368/ea9a680c-0d7f-7144-1790-835a0e3b794a.png)

# サンプルアプリのデプロイ
手抜き

下記URLの手順を実施して、サンプル・アプリをデプロイします。
[Deploying an app to your cluster](https://cloud.ibm.com/docs/containers?topic=containers-getting-started#deploy-app)
【iOS】Fastlaneのincrement_build_numberがビルドナンバーを取れずにエラーになる際の対処法

結論から言うと、**プロジェクトディレクトリの中に複数のプロジェクトファイルが存在しているとエラーになります。余計なプロジェクトファイルを消せば解決します。**

以下は経緯。

---------------------------------------

プロジェクトのビルドナンバーをインクリメントしたいときに便利なのが、Fastlane Actionの[increment_build_number](https://docs.fastlane.tools/actions/increment_build_number/)ですが、なぜか自分の環境だけ、以下の様なエラーが出ました。

```
-> % bundle exec fastlane run increment_build_number
[✔] 🚀 
[16:22:33]: ------------------------------------
[16:22:33]: --- Step: increment_build_number ---
[16:22:33]: ------------------------------------
There are multiple projects in this directory.  agvtool does not work with multiple projects in the same directory.

agvtool - Apple-generic versioning tool for Xcode projects
  usage:
    agvtool help
    agvtool what-version | vers [-terse]
    agvtool [-noscm | -usecvs | -usesvn] next-version | bump [-all]
    agvtool [-noscm | -usecvs | -usesvn] new-version [-all] <versNum>
    agvtool [-noscm | -usecvs | -usesvn] tag [-force | -F] [-noupdatecheck | -Q] [-baseurlfortag]
    agvtool what-marketing-version | mvers [-terse | -terse1]
    agvtool [-noscm | -usecvs | -usesvn] new-marketing-version <versString>


[!] Apple Generic Versioning is not enabled in this project.
Before being able to increment and read the version number from your Xcode project, you first need to setup your project properly. Please follow the guide at https://developer.apple.com/library/content/qa/qa1827/_index.html
```

opps... バージョンナンバーが取れてませんね。

よくみると、以下の様なエラー文言が出ています。

> There are multiple projects in this directory.  agvtool does not work with multiple projects in the same directory.

avgtoolはプロジェクトディレクトリ直下に複数のプロジェクトがある場合動かなくなるとのこと。

というわけで、プロジェクトディレクトリの中に、**他に余計なプロジェクトファイルが紛れてないか確認してみましょう。もしあれば削除してみましょう。**

早速、削除した後に叩いてみると無事実行されました。

```
-> % bundle exec fastlane run increment_build_number
[✔] 🚀 
[16:28:00]: ------------------------------------
[16:28:00]: --- Step: increment_build_number ---
[16:28:00]: ------------------------------------
Current version of project *** is: 
    2751

/Users/hoge/iOS/***
[16:28:01]: $ cd /Users/hoge/iOS/*** && agvtool next-version -all && cd -
[16:28:01]: ▸ Setting version of project *** to:
[16:28:01]: ▸ 2752.
[16:28:01]: ▸ Also setting CFBundleVersion key (assuming it exists)
[16:28:01]: ▸ Updating CFBundleVersion in Info.plist(s)...
[16:28:01]: ▸ Updated CFBundleVersion in "***.xcodeproj/../***/SupportingFiles/***-Info.plist" to 2752
[16:28:02]: ▸ Updated CFBundleVersion in "***.xcodeproj/../***1/Info.plist" to 2752
[16:28:02]: ▸ Updated CFBundleVersion in "***.xcodeproj/../***2/Info.plist" to 2752
[16:28:02]: ▸ Updated CFBundleVersion in "***.xcodeproj/../***3/Info.plist" to 2752
[16:28:02]: ▸ /Users/hoge/iOS/***
[16:28:02]: Result: 2752
```

同じエラーにお悩みの方はぜひ参考に。( [＠koiwai2020](https://qiita.com/koiwai2020) さん教えてくれてありがとうございます。)

こんな記事もどうぞ

[GoogleスプレッドシートとFastlaneでApp Store説明文を自動更新する方法](https://zenn.dev/kurarararara/articles/6d198bc9337edf)
Elasticsearchチートシート

# この記事は
筆者の備忘です。

--------

nwstatsがインデックス
pingがタイプ(mapping type)

### クラスタの状態表示

```
GET /_cluster/state?pretty=true
```

テンプレート設定なども表示される

### インデックスの概要表示

```
GET /nwstats/
```

### マッピングの表示

```
GET /nwstats/mapping?pretty
```

### 特定インデックス内の検索

```
GET /nwstats/_search?q=*&pretty
```

```
POST /nwstats/_search?pretty
{
    "query": { "match_all": {} }
}
```

### ドキュメントを取得

```
GET /nwstats/ping/1
```

### ドキュメントを作成(IDを指定しない)

```
POST /nwstats/ping
{
    "field1": "追加したいドキュメント"
}
```

### ドキュメントを作成(IDを指定する)

```
PUT /nwstats/ping/1
{
    "field1": "追加したいドキュメント"
}
```

### インデックス削除

```
DELETE /nwstats/
```

### ドキュメント削除(id指定)

```
DELETE /nwstats/ping/3pHMVnIB63fHpZH4OBtV
```
ブラウザの戻るをKonyで禁止する方法

#目次
1. はじめに
2. 実装方法
3. まとめ

##はじめに
今回はWebアプリで、横スクロールで情報を表示したい場合に
Mac等の場合は、横スワイプするとそのまま前の画面に戻ってしまうことがあるかと思います。

戻る気がなかったのに、またログイン画面からやり直しするなんて面倒ですよね、、:sweat_smile:
そんな時に、前の画面に戻ることを禁止するための実装方法をご紹介したいと思います！

##実装方法

方法だけ知りたい方のために結論からご紹介します！
戻るを禁止したいフォームの、`onDeviceBack`アクションに下記のコードを記載するだけです。

戻るを禁止したいフォームのコントローラに`onDeviceBack`アクションを作成

```onDeviceBack.js
  onDeviceBack : function(){}
```

Kony Visualizerの右メニューのonDeviceBackアクションを選択し、
![onDeviceBack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/77b4ed57-cb8c-eb6f-29bf-448738154c85.png)



Invoke functionで`onDeviceBack`を選択
![スクリーンショット 2020-09-16 12.05.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/1f94575b-be9f-9380-db8b-fe1d188bcb13.png)


ログイン→メイン画面に遷移するWebアプリがあるとして、
メイン画面からログイン画面に戻る画面遷移を禁止したい場合は、
メイン画面の`onDeviceBack`にアクション設定を行えば完了です！

簡単ですね！

〜〜〜〜〜〜〜〜〜〜〜〜〜〜補足〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

`onDeviceBack`アクションは、名前の通り
戻るボタンを押下したときに発動するアクションです。

今回はWebで作成しましたが、Web以外にもAndroid等のデバイスでも利用が可能です。  
【対応デバイス】

-  Android / Androidタブレット
- BlackBerry
- BlackBerry 10
- デスクトップウェブ
- SPA（iPhone / Android / BlackBerry / Windows NTH)
  
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜



<blockquote class="twitter-tweet"><p lang="und" dir="ltr"><a href="https://t.co/0UOMbhgM50">pic.twitter.com/0UOMbhgM50</a></p>&mdash; Kony (@Kony12763790) <a href="https://twitter.com/Kony12763790/status/1306068463044050945?ref_src=twsrc%5Etfw">September 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


ログイン後、何度も横スワイプや戻るボタンを押下していますが、
メイン画面のまま戻れていないことが確認できますね！

##まとめ
ちょっとした機能ではありますが、横スクロールなどのWeb画面を実装している場合は、
この機能があるだけでユーザーが利用しやすいアプリになると思いますので、是非活用してみてくださいね:laughing:

##参考
[onDeviceBackアクション](https://docs.kony.com/konyonpremises/Subsystems/Widget_User_Guide/Content/Form_Events.htm#onDevice)
javascript関数ドリル　初級編indexOf関数の実相のアウトプット

##indexOf関数の課題内容
詳細はこちら
　　　↓
https://js-drills.com/blog/indexof/

##indexOf関数の取り組む前の状態
見てなんとなくわかった

##indexOf関数に取り組んだ後の状態
return -1以外は分かった

##indexOf関数の実装コード（答えを見る前）

```js
function indexOf(array, value, secoundIndex = 0) {
  for(let i = secoundIndex; i < array.length; i++) {
    if(array[i] === value) {
      return i;
    }}}
```


##indexOf関数の実装コード（答えを見た後）

```js
function indexOf(array, value, fromIndex = 0) {
  for(let i = fromIndex; i < array.length; i++) {
    if(array[i] === value) {
      return i;
    }
  }

  return -1;
}

// console.log( indexOf([1, 2, 1, 2], 2) );
// => 1

// Search from the `fromIndex`.
console.log( indexOf([1, 2, 1, 2], 3, 2) );
// => 3
```
Terraform の foreach で resource を作る方法

```
resource "RESOURCE_TYPE" "RESOURCE_NAME" {
  for_each = toset(local.hoge)
  aaa = each.value
}

locals {
  hoge = [
    "fuge",
    "hage"
  ]
}
```

でやると、

```
RESOURCE_NAME["fuge"]
RESOURCE_NAME["hage"]
```

とかの resource_name の resource ができる。
VSCode Live Share+Flutterでのリモートモブプログラミングの現状


## モチベーション
* もともとオフラインでのモブブロの仕事スタイル（以後**リアルモブ**と呼ぶ）
* コロナウイルスにより弊現場は3月から好むと好まざるとフルリモートにせざるえなくなる
* リモートモブになって約５ヶ月経過したので、現在まで達成できてる事/課題を紹介。

## モブプログラミング環境

### ツール/SaaS類
* 画面共有/音声通信は`Discord`（未課金勢）
* コーディングは`VSCode Live Share`
* カンバンは`Trello`
* ふりかえり等は`Jamboard`
* デザインや図の共有は`Figma`
  * 資料等は`Google Spread Sheet`を使うこともある
* リポジトリは`GitHub Enterprise`
* CI/CDは`Bitrise`

### モブプロのスタイル
* 基本的には**ドライバー1名**、残りは**ナビゲーターとサポーター**
  * 人数は2名〜5名まで試験。
  * 5名の場合、一番知見のある人を専属ナビゲータにして4人で回すのもありかも。
  * この辺はリアルモブと変わらない
* うまく回ってると、サポーターにより次の実装に必要な情報（公式リファレンス、Blog記事、githubのサンプルコード)がDiscordにペタペタはられる
  * ドライバーは**ひたすら書き続けるキーボード奴隷化**
* ハマったり、解決方法が誰もわからないと**皆で試行錯誤**
* ドライバーは**10分交代で1時間あたり10分は休憩**を入れる
  * 試した結果、5分ではせわしなく、15分では長すぎたので10分に収斂した。 
* 手分けできる作業（複数ファイルにわたるソースコードの変更)などは**短時間なら全員で直し**にかかったりする。
  * 「このメソッドの引数増やさんとだめだ」→「呼び出し部分書きかえてくる」「じゃぼくは中身を」みたいな
  * そしてシームレスに合流
  * ***カーソルが複数あるのってすごい***
* めっちゃ疲れるので**午前３セット、午後3セットぐらいが限界**（途中13-14時がお昼休み）
  * 経験則的に、ノッてても***休憩を意図的に入れないと集中力が続かない***
  * トイレ行きたかったり宅急便も来るのでドライバー手番をパス等はよくある。
  * ***厳密に手番通り回す必要はない***

## TIPS/課題

### ビルド速度がホスト依存
* **一番早いマシン持ってる人**がホストをやる
  * 最大でVSCode Live Share+Android Emulator+コンパイル+Discord画面配信という負荷になるので、結構なパワーがいる
    * Macbook Pro松でもキツい
* 弊現場ではiMac 5Kを配布。家庭環境的に設置できない人はMacbook Pro。
  * ちなみに僕はMac Proをどさくさにまぎれて奪取。***非常に快適。***

### GuestだとGo To Definition動かない問題
* Guest側だと⌘+Clickでクラスやメソッドの定義に飛べない
* ホストを⌘+クリック奴隷にして、自分はホストのカーソルに追従すれば飛べるけど、**ぶっちゃけダルい**
* 機能的にできないのでなく、本来は動くはずだが、**どうもTS以外動かないというバグっぽいので今は一旦我慢**
  * issueはこちら→https://github.com/rust-analyzer/rust-analyzer/issues/5644
  * とりあえず「同じソースコードを別のディレクトリにおき、Android Studioで開いておいて対応」
  * 大抵は調べごと＆元の実装を見たいパターンなのでなんとかなる
 
### Guestだとエミュレータ触れない問題
* 実行すると実機やエミュレータは、当然ホストマシン上でしか動かない
* エミュレータの画面そのものはDiscord経由で見れる
  * Hot Realoadでの画面デザイン修正はわりと困らない
* しかし操作ができない
  * ***ホストが操作奴隷になるしかない***

### Debug Session動かない問題
* ゲストとDEBUG CONSOLEの共有できない
  * GuestにDEBUGメッセージ等がみれない 
* しかし共有ターミナルから起動はできる
  * DEBUGメッセージも読める
  * そうするとBreakPoint等が動かない
* ***ガチハマりしたらAndroid Studioでデバッガ動かした方が残念ながら早い***

## 所感

### リアルモブに対してスピードはどうなの？
* 議論は**遅くなった**（コミュニケーションの高コスト化）
* コーディングは**早くなった**（ツールによる問題解決）

### メンバー欠けに対する強い靭性
* 本来チームは固定したいが、家庭事情やら体調やらで現実には毎週フルタイム同じメンバーでやるのは難しい
* しかし、このモブスタイルによって、全休＆短時間抜け等でもタスク進捗に影響が出にくい
  * とはいえ知見者が抜けたときにハマると遅くなることはあるが、誰もわかならい、みたいな状況にはならない。
    * **少々スピードが遅くなってもタスクが進むということは重要**

### リモートモブはリアルモブプロのサブセットではなくスーパーセットになる
* 従来のモブに比べると***「すべてのツールが同時に操作可能」***であることは、従来とはかなり違う開発体験となる。 
  * 単一のタスクに対して、複数のソースコードを複数の人間がリアルタイムに書き換えていくというパラダイムシフト
  * もはや最大のネックは「OSが単一のユーザしか想定していない事」 になっている

### 指示待ち型のチームには向かない
* Discordでは1->Nのコミュニケーションが主体になる（1<->1の会話を複数同時にはできない）ため、**リーダーが音声によって全員に細かく逐次指示するコストが非常に高い**
* したがって、ナビゲーターやサポーターは、タスクの先を見据えて、ぐいぐい先回りして仕事をしていくスタイルが要求される。
* 自律型のチームでないと、お見合い＆指示待ちが発生してしまう。
* 全員がリードしまくるぐらいの、***積極的なチームワークが重要***

### ほんとに仕事できんの？
* できたよ
[Phaser3] How to load assets under directories automatically

# TL; DR

- There is no feature in default
- Use Webpack plugin [phaser-assets-webpack-plugin](https://www.npmjs.com/package/phaser-assets-webpack-plugin)

# Loading in default

```js
preload () {
  this.load.image('logo', 'img/logo.png')
  this.load.spritesheet('player', 'img/player.png', { frameWidth: 16, frameHeight: 32 })
}
```

This is okay if it is game has less assets, but it become difficult if the game is not so. 

So I wanted to load assets under my assets directories automatically.

That is impossible in default because client side JS can not scan files of server.

So the files should be scanned with Node.js before build, and the assets data need to be defined in static into built JS.

# Spritesheet

```js
{ frameWidth: 16, frameHeight: 32 }
```

Also I don't like to define size of sprite of spritesheet in pixel.

The reason why the size should be defined in pixel is client side JS is only able to know the size after loaded.

# I've made a WebpackPlugin to that

phaser-assets-webpack-plugin
https://github.com/laineus/tile-extrude-webpack-plugin

You just need to define directory structure, then the assets data can be imported like this.

```js
import assets from 'assets'
conosle.log(assets)
// -> {
  image: [
    ['title', '/img/title.png']
  ],
  spritesheet: [
    ['player', '/img/player.png'. { frameWidth: 16, frameHeight: 16, startFrame: 0, endFrame: 3 }]
  ],
  audio: [
    ['bgm', ['/audio/bgm.m4a', '/audio/bgm.ogg']]
  ]
}
```

Then it will be reloaded automatically when added or removed files while webpack is watching.


Also if you load spritesheets, just define num of horizontal and vertical for each spritesheet into JSON file located same dir as assets.

```json
[
  ["player.png", 3, 4]
]
```

Take a look GitHub to see usage.
javascript関数ドリル　初級編head関数の実相のアウトプット

##head関数の課題内容
詳細はこちら
　　　↓
https://js-drills.com/blog/head/

##head関数の取り組む前の状態
できました

#head関数に取り組んだ後の状態



##head関数の実装コード（答えを見る前）
```js
function head(array) {
  return array[0];
}

console.log( head([1, 2, 3]) );


console.log( head([]) );

```

##head関数の実装コード（答えを見た後）
```js
function head(array) {
  return array[0];
}

console.log( head([1, 2, 3]) );
// => 1

console.log( head([]) );
// => undefined
```
cos類似度行列の実装【Pytorch, Tensorflow】

SimCLRなどの対照学習(Contrastive Learning)の手法で，特徴量空間における類似度の指標として用いられるものの一つにCos(コサイン)類似度があります．

Tensorflow，Pytorchそれぞれで実装を行ったので，メモ程度に記録しておきます．（参考までに）

# Pytorch
```
# input_sizeは (batchsize*次元数)

def cosine_matrix(a, b):
    dot = torch.matmul(a, torch.t(b))
    norm = torch.matmul(torch.norm(a, dim=1).unsqueeze(-1), torch.norm(b, dim=0).unsqueeze(0))
    return dot / norm
```

# Tensorflow

```
def cosine_matrix(a, b):
    a_normed, _ = tf.linalg.normalize(a, axis=-1)
    b_normed, _ = tf.linalg.normalize(b, axis=-1)
    matrix = tf.matmul(a_normed, b_normed, transpose_b=True)
    return matrix
```
javascript関数ドリル　初級編flatten関数の実相のアウトプット

##flatten関数の課題内容
詳細はこちら
　　　↓
https://js-drills.com/blog/flatten/

##flatten関数の取り組む前の状態
全然わからなかった

##flatten関数に取り組んだ後の状態
スプレッド演算子（配列を展開するもの）は配列をコピーして配列で返すものだと勘違いしていたことに気づけた。
json.stringfyが分からなかったです。（よければ教えてください。）

##flatten関数の実装コード（答えを見る前）
分かりませんでした。

##flatten関数の実装コード（答えを見た後）

```js
function flatten(array) {
  const flattendedArray = [];
  for(let i = 0; i < array.length; i++) {
    const value = array[i]
    if( Array.isArray(value) ) {
      flattendedArray.push(...value);
    } else {
      flattendedArray.push(value);
    }
  }

  return flattendedArray;
}

const numbers = [1, [2, [3, [4]], 5]];
const result = flatten(numbers);

console.log( JSON.stringify( result ) );
// => [1, 2, [3, [4]], 5]

console.log( JSON.stringify( numbers ) );
// => [1, [2, [3, [4]], 5]]
```
SQL Server: 拡張イベントを使ってクエリベースでブロッキング発生状況を後追いする

# 背景
[こちら](https://qiita.com/maaaaaaaa/items/637cf149e56bda68d61a)の記事で、拡張イベントを使ってブロッキングを後追いできる仕組みの整え方をご紹介しました。

後追いの方法がGUIベース、もしくはシンプルなクエリベースでの方法だけを紹介していたため、本記事ではクエリベースでより便利に後追いする方法をご紹介します。

# クエリ
[github](https://github.com/masaki-hirose/SQLServer-Info/blob/master/%E6%8B%A1%E5%BC%B5%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88/%E3%83%96%E3%83%AD%E3%83%83%E3%82%AD%E3%83%B3%E3%82%B0%E3%81%AE%E5%BE%8C%E8%BF%BD%E3%81%84%E3%82%AF%E3%82%A8%E3%83%AA.sql)にてクエリを公開しています。

クエリのポイントとしては、生データだと解釈が最初は難しいため、みやすく加工している点です。

適宜編集する必要のある個所だけ説明します。

```sql
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED

DECLARE @xe_filename nvarchar(255) = N'blocked_process_and_deadlock_report*.xel' --modify here
DECLARE @begin_time datetime
DECLARE @end_time datetime
set @begin_time = '2020/08/20 07:50:00' --modify here
set @end_time = '2020/08/20 08:10:00' --modify here
```

#### ファイル名
@xe_filenameには、拡張イベントのイベントを保存しているファイル名を指定します。
ファイル名の確認は、拡張イベントの該当セッションを右クリックしてプロパティを開き、「データストレージ」ページにて確認できます。（赤枠内）
フルパスで書かれている場合はフルパスで書いた方が良かった気がします（うろ覚えですみません）
ワイルドカード「*」と拡張子「.xel」も含めましょう。ファイル名＋「*.xel」でOKです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/1ab3dce4-6b9f-5a12-24c3-707b96ad5ab6.png)

#### 時間帯
@begin_time/@end_timeをそれぞれ指定します。
拡張イベントのtimestampはutcなのですが、クエリ内で+9時間で変換しているため、普通に日本時間で絞り込みたい時間帯を指定してもらえればOKです。

# 取得結果例
指定した時間帯でブロッキングが発生していると、以下のようなレコードセットが取得できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/6ad2799f-6ab6-acc4-46be-f0e734f38c4e.png)

右にスクロールしていくと以下のようなカラムを確認できます。
各ブロッキングレポート（＝各レコード）で確認すべきは、ざっくりいうと「どのクエリが、どのクエリにブロックされていたか」となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148310/4a942656-9cac-bfaf-b5b7-c5454644d004.png)

#### ①blocking_waitresource
ブロッキングしているプロセスが、何らかの要因で待っている場合は、ここにresourceの情報が表示されます。たとえばブロッキングツリーが形成されていて、blockingなクエリもほかのクエリにブロックされている場合なとです。

#### ②blocking_spid
ブロッキングしてるクエリのセッションIDです。

#### ③blocking_query
ブロッキングしているクエリです。ストアドプロシージャ名またはSQLで表示されます。

#### ④waitresource
ブロックされているプロセスがどのリソースにロックをかけたくて待たされているかが表示されます。
具体的な後追いの方法はここでは割愛します。

#### ⑤blocked_spid
ブロックされているクエリのセッションIDです。

#### ⑥blocked_query
ブロックされているクエリです。ストアドプロシージャ名またはSQLで表示されます。

#### ⑦event_data
元の拡張イベントのデータです。フルフルで詳細に確認したい場合はこちらをクリックして生データを確認できます。

#### ざっくりとした見方
「⑤blocked_queryが、③blocking_queryにブロックされていた」という解釈ができます。
また、該当時間帯で大量にブロッキングが発生している場合は、ブロッキングの大本「head blocker」を特定する必要したい場合があると思います。

その場合は、「該当時間帯で一番最初にブロッキングのレポートが上がったレコード」をチェックすると、そのレコードにおけるblocking_queryが「head blocker」である可能性が高いです。

#まとめ
ブロッキングの情報を拡張イベントからクエリベースで後追いする方法をご紹介しました。
少なくとも、該当時間帯でブロッキングが発生していたかを後追いすることは簡単にできると思います。
また、head blockerの特定についても慣れてくれば今回の方法を使ってできるようになるかと思います。
構造体のインスタンス作成時に&を付ける必要がある時

Goでhttp.Clientを使う際に

```
transport := &http.Transport{}
```

なんで＆付けないとダメなのだろうと調べてみた。
付けないと

```
client := http.Client{
    Transport: transport, // ここでエラーが出る
}
```

> cannot use transport (type http.Transport) as type http.RoundTripper in field > value:
> 	http.Transport does not implement http.RoundTripper (RoundTrip method 
> has pointer receiver)

怒られる。

> RoundTrip method has pointer receiver

interfaceを実装する構造体で、メソッドにポインタレシーバを使うと
構造体を作成する際に、ポインタを取らないとダメらしい。

```
type Hoge interface {
	SetName(name string)
	GetName() string
}

type Sample struct {
	Name string
}

func (s *Sample) GetName() string {
	return s.Name
}

func (s *Sample) SetName(name string){
	s.Name = name
}

func main() {
	// var s Hoge = Sample{} これだと動かない
	var s Hoge = &Sample{} // これは大丈夫
	s.SetName("三井直樹")
	fmt.Println(s.GetName())
}

```

気を付けよう。
AutoHotkeyの\Kはクソ便利

皆さまにおかれましては快適なAutoHotkeyライフをエンジョイされてますかー？


#便利なんだ\Kが😲

###AutoHotkeyと言えば[正規表現](https://www.autohotkey.com/docs/misc/RegEx-QuickRef.htm)

が[PCRE](http://www.pcre.org/pcre.txt)互換で非常に非常に強力ですが、戻り読み(look-behind)が量化子をサポートしていないという**謎の制約**があり、これはきっと計算量が爆発するからだろうとテキトーに受け止めて少し不便に思いつつ諦めてました。
> Look-behinds are more limited than look-aheads because they do not support quantifiers of varying size such as *, ?, and +. 
[Regular Expressions (RegEx) - Quick Reference](https://www.autohotkey.com/docs/misc/RegEx-QuickRef.htm)

しかし、よく試行錯誤してみると
###\K

>The escape sequence \K is similar to a look-behind assertion because it causes any previously-matched characters to be omitted from the final matched string. For example, foo\Kbar matches "foobar" but reports that it has matched "bar".
[Regular Expressions (RegEx) - Quick Reference](https://www.autohotkey.com/docs/misc/RegEx-QuickRef.htm)

を使えばそういう制約はないようです。これはVim特有のありがたーい正規表現である\zsのようなもので、肯定戻り読みの略記という理解でだいたいあってると思いますが、実際には戻り読む処理が入らないという点で別物と言えるでしょう(たぶん)。\zsのsはstartのsですが、\KはKoko(でマッチして！)のKですねちがうね。


#🚀🚀🚀コーディング例🚀🚀🚀

[Edit v2.0](https://www.autohotkey.com/boards/viewtopic.php?f=6&t=5063)を用いています。


```autohotkey:MyEditor.ahk
;(ほにゃほにゃ)
Gui, Add, Edit, hwndMyEdit
;(うにょうにょ)

; 括弧を飛ばしてその行の最初の文字の手前に移動
^0::
lstart := Edit_LineIndex(MyEdit, -1)
pos := Edit_FindText(MyEdit, "
    (LTrim
    x)
    (
        \(.+?\)|
        （.+?）|
        \[.+?\]|
        ［.+?］|
        〚.+?〛|
        〘.+?〙
    `)*\K
    )", lstart, -1, "RegEx")
Edit_SetSel(MyEdit, pos, pos)
return

```
ReactNative with Expo で画像の縦横サイズを取得する

# はじめに
ReactNative with Expo 構成で画像の縦横比を取得するのが思いのほか簡単だったので共有します。

# 結論
Imageコンポーネントで画像サイズを取得するメソッドが提供されています。

```sample.js
// Imageコンポーネントを取得
import {Image} from 'react-native';

// uriに任意の値を格納
Image.getSize(uri, (width, height) => {
  return({width, height})
});
```
tableView画面クラッシュ

tableViewの画面がクラッシュする

【エラー】
Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.


【対応】
テーブルビューのリロード部分
self.rankingTableView.reloadData()
を

DispatchQueue.main.async {
  self.rankingTableView.reloadData()
}

と囲むとクラッシュしなくなりました。



【参考】
swift初心者がiOS13対応でメインスレッド以外でUI更新をしてクラッシュさせてしまった話
https://qiita.com/rymiyamoto/items/7ace750172b84a2ff809


https://www.it-swarm.dev/ja/ios/gtレイアウトエンジンへの変更は、メインスレッドからアクセスした後、バックグラウンドスレッドから実行しないでください%E3%80%82/811797116/
Phaserで指定ディレクトリのAssetsファイルを自動で読み込む

# TL; DR

- 標準ではそんな機能無い
- [プラグイン](https://github.com/laineus/phaser-assets-loader)を作ったので使って下さい

# 普通の読み込み方

```js
preload () {
  this.load.image('logo', 'img/logo.png')
  this.load.spritesheet('player', 'img/player.png', { frameWidth: 16, frameHeight: 32 })
}
```

アセットが数個の小規模なゲームなら、↑のように読み込んでいけばいいけど、アセットの量が多いゲームだとかなりしんどくなってきます。

ディレクトリの中に置いたファイルを勝手に読み込んで使えるようにしたいです。

標準でそれができない理由としては、Webフロントエンドからは、サーバーにあるディレクトリをスキャンできないためです。

なので、ビルド前にNode.jsなどでスキャンし、ビルド後の時点ではファイル一覧が静的にリストアップされている必要があります。

# スプライトシート

```js
{ frameWidth: 16, frameHeight: 32 }
```

ついでにスプライトシートをピクセルをしないと行けないのもつらいです。

縦横の枚数ではなくピクセルで指定しないといけない理由としては、描画しないと大きさを取得できないからだと思います。

# WebpackPluginを作りました

phaser-assets-loader
https://github.com/laineus/phaser-assets-loader

ディレクトリと読み込むアセットの種類などを定義すると、以下のようなアセットの一覧を自動で変数として読み込めるようになります。

```js
import assets from 'assets'
conosle.log(assets)
// -> {
  image: [
    ['title', '/img/title.png']
  ],
  spritesheet: [
    ['player', '/img/player.png'. { frameWidth: 16, frameHeight: 16, startFrame: 0, endFrame: 3 }]
  ],
  audio: [
    ['bgm', ['/audio/bgm.m4a', '/audio/bgm.ogg']]
  ]
}
```

Webpack監視中にファイルが増減すると、自動で再読込します。

スプライトシートについては、同一ディレクトリに縦横の枚数を指定したjsonファイルを設置すると、ピクセルに変換されます。

```json
[
  ["player.png", 3, 4]
]
```

使い方はGitHubをご覧ください！
conf.d配下のファイルの備忘録

　vhosts.confを作ってVHを設定することで有名なconf.dですが、ほかのconfファイルもちらっと調べてまとめてみました。

- [ ]  mod_dnssd.conf
　DNS Service Discoveryの略？ネット診断ツールのようですがよくわかりません。。

- [ ]  welcome.conf
　中身は以下の感じです.
＜LocationMatch "^/+$"＞
　　Options -Indexes　　　　　　　　　　　　　　　　－①
　　ErrorDocument 403 /error/noindex.html　　　　　　－②
＜/LocationMatch＞

　①コメント状態でドメイン名またはIPアドレスでアクセスすると以下のようなディレクトリインデックス画面が表示される.
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227569/8debbaa6-64b3-30ea-fd06-e1ac1b991609.jpeg)
　②コメントを外していればエラーだった時にちょっとリッチな画面が返ってくる.

　※とはいえsudo付けても読み取り専用ファイルなのでいじれないような...

- [ ]  ssl.conf
　SSL接続するかどうか設定するとこ.
　詳しくは→<URL:http://httpd.apache.org/docs/2.2/mod/mod_ssl.html>

　他にもwebalizer（WEBアクセスログ解析ソフト）とかwsgi（Web Server Gateway Interface）などありますが、割愛！
ECサイトの店舗名を表示させたい　ミスの箇所はコンソールで確認出来る

ふるさと納税のようなサイトをイメージして、サイトのTopページに商品とその商品を出品している店名表示をさせようとした所、NoMethodErrorが出てしまいました。
備忘録兼ねて、こういう所を見ると良いのかと勉強になりましたので記載致します。

![スクリーンショット 2020-09-10 21.12.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660239/88b2631b-19aa-a4fd-f890-b355367cb16c.png)

現状は
・itemとclientは既にモデル上でアソシエーションは構築済み。
（itemが子でclientが親）
・clientにはshop_nameのカラム持たせている。
・Adminコントローラーには@items = Items.allでを指定済み

原因が思い当たらず、ターミナルにてコンソール（$rails c）で確認。![スクリーンショット 2020-09-10 22.27.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660239/d75ed46b-4674-9f29-cbe3-fad61b9e5e98.png)

表示が小さくて大変恐縮ですが
3行目に「Unpermitted parameters」という表示があります。
右記の"shop_name","shop_name_kana","last_name_kana","first_name_kana",
"telephone_number"の項目は許可されてませんよ、という意味のようです。

新規登録時に関わってくるのは基本的にdeviseかapplicationコントローラーで
自身で触っていたのはapplicationコントローラーだったのでそちらをチェック。

![スクリーンショット 2020-09-11 14.57.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660239/29d4ecf8-8c3f-d8d4-a3b2-ccb806d88629.png)

parametersの中には見事に弾かれていた項目の記載が抜けていました…。
なので、項目を追加して
![スクリーンショット 2020-09-11 15.02.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660239/1b5f8bb1-e02a-6693-84d0-55402d826c9b.png)

コンソールで再度チェックをしてみた所、Unpermittedという言葉は消え無事に店名表示が出来ました！

![スクリーンショット 2020-09-10 22.29.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/660239/521011af-bd23-f962-b84d-7b74062bf35c.png)

コンソールでこういった箇所にまで確認が行き届いていなかったので記載させていただきました。
簡単ですが、以上となります。
開発環境でゆるふわにec2 spotインスタンスを使ってコストを下げよう

## 目次

* 対象読者
* 現在のspotインスタンスの仕様
* 実際のオペレーション
* 稼働率、実際の適用効果

## 対象読者

* クリティカルではない開発環境(～数人利用、落ちても許される環境)のユーザ
* 開発環境のコスト管理責任者
* 部下にawsのコストの使い方が妥当か詰めたい管理者

## 現在のspotインスタンスの仕様

過去のspotインスタンスの仕様は、下記のようなもので使用者を非常に選ぶものでした。

* AWS都合、自己都合でも停止すると再開不能
    * DISKを残しておくことは可能だが、DISKの状態を引き継ぎたい場合はAMIを作ってVM作り直し、、
* CI/CD等で自動構成されるようにしておかないと使いかってが悪い
    
しかし、現在のspotインスタンスの仕様は、通常のec2にかなり近いものになっています。

* spotインスタンスを通常のオンデマンドインスタンスと同じように停止、再開が可能
    * 当然、DISKの状態は引き継がれる
  
よって、**spotインスタンスを時々aws都合で落ちる可能性があるだけのインスタンス**として利用することができます。
コンテナ、ci/cdに無縁な昔ながらのがっつり手動構築、OSに状態持ちまくりの案件でもスポットのメリットを享受することが可能です。

## 実際のオペレーション

ec2を作るときに、下記のようなオプションを設定するだけとなります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/4d3070d9-c8fc-d074-2db8-a66486ebe769.png)

これだけで、不要な時はec2を止めつつ

* **windowsはm5で4割引き**
* **linuxはm5で7割引き**

のコストメリットを受けることができます。
また、今までお使いの電源管理スクリプトをそのまま使い、夜間、休日は今まで通り停止が可能です。

参考：3か月のコスト推移

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/fc4f3501-11de-1d7c-4835-58f5f2bb3862.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/2484a2ca-5ea9-2add-e4ac-9875c3adc254.png)


## spot稼働率

正確なデータを取っているわけではありませんが、AWS調べによると

**キャパシティー不足による停止は5%未満**

とのことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/5fdf6c9d-9135-9e1e-49e5-88ee6822f05c.png)
出典:aws summit 2019:SpotInstance のより効率的な活用を目指して。Spot Instance Update
https://pages.awscloud.com/rs/112-TZM-766/images/L2-08.pdf

また、リージョン、インスタンスタイプごとの詳細は、
https://aws.amazon.com/jp/ec2/spot/instance-advisor/
で確認することができ、

インスタンスタイプごとに停止可能性のあたりをつけることが可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/6c7ce625-9a76-dfaf-2d5f-83247bcdaec1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692046/28a0871a-037c-5bce-ee51-0b6ed4184c3c.png)

機械学習で人気のp系、レガシーすぎる、m1,t2系はある程度の停止リスクがあるのでec2 spot instanceの中断を意識したまともなspotインスタンスが必要でしょう。
しかし、spotインスタンスの種類を適切に選べば、中断リスクは非常に下がるため、環境によっては難しいことを意識せずに通常のインスタンスの代替として使用が可能です。

私は、m5,m4,m3を中心に使っており、停止を食らったことはほぼありません。
とくに、古い不人気商品(m3)は落ちにくいだろうという目算で、特に落ちてほしくないシステム等で使っておりましたが、半年以上何もなく動き続けていたこともありました。

## まとめ

現状のspotインスタンスは、停止リスクがある普通のec2として使う選択肢があります。
また、停止リスクはインスタンスタイプによりかなりコントロール可能なため、非常に限られた停止リスクで、

* **windowsで4割コスト削減**
* **linuxでで7割コスト削減**

ができる非常に強力な武器です。

ということで、ゆるふわが許される環境では、ぜひ、spotインスタンスをご検討してみてください。