OmniAICreator/Qiita-1.07M huggingface dataset:
Windowsのネットワークが調子悪いときにコマンドでネットワーク再起動

手元のPCのWindowsで複数のWiFiを切り替え切り替え使ってるとどうもネットワークが調子悪くなる時がある。特にIPv6のアドレスが取れてない時があるので困っていたが、PowerShellでネットワークを再起動する方法を発見。

```
PS C:\Users\zrock> Restart-NetAdapter Wi-Fi
```

`Wi-Fi`の部分はネットワーク名。`Get-NetworkAdapter`で取得できる。

```
PS C:\Users\zrock> Get-NetAdapter
Name                      InterfaceDescription                    ifIndex Status       MacAddress             LinkSpeed
----                      --------------------                    ------- ------       ----------             ---------
イーサネット 2            Realtek USB GbE Family Controller            18 Disconnected XX-XX-XX-XX-XX-XX          0 bps
Wi-Fi                     Intel(R) Dual Band Wireless-AC 8265          13 Up           YY-YY-YY-YY-YY-YY     866.7 Mbps
Bluetooth ネットワーク... Bluetooth Device (Personal Area Netw...       9 Disconnected ZZ-ZZ-ZZ-ZZ-ZZ-ZZ         3 Mbps
```

Wi-FiのオンオフだけだったりいろいろWindowsのUIでやってもうまく初期化できないときに、この方法で有効な場合も。単に私がちゃんとした方法を知らないだけかもしれないけど。^^;
ドメイン駆動設計のための静的型付き言語のすすめ

この記事は[宮崎IT関連勉強会 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/miyazaki)の16日目の記事です。

ドメイン駆動設計も随分と浸透してきたなぁと思うこのごろ。

でも、未だに動的型付き言語で頑張っている（弊社含め）現場も多く、今回は静的型付き言語について語ろうかと。

そもそもWebアプリの業界では単純にPHPやRuby、Pythonなど動的片付け言語で頑張る現場が圧倒的に多いかと思います。

しかし、ドメイン駆動設計を実践していくと、ある事実が襲ってきます。それはドメイン駆動設計は「型」の世界で成り立っているということ。

実践するにあたって、まず最初に乗り越える壁がレイヤアーキテクチャだったりするので、なかなか難しいと思いますが、本質的な部分は当然モデル。EntityであったりValueObjectであるわけです。

もちろん、動的型付きの言語でもモデルは書けます。弊社でもPython3の型ヒントを駆使してモデルを書いています。

ただ、モデルとは何かを考えてみていただきたい。

> モデルとは、プロジェクトに携わる人々の頭のなかで構築された概念の集まりであり、ドメインについての洞察を反映した、用語と概念間の関係性からできている。([エリックエヴァンスのドメイン駆動設計](https://www.amazon.co.jp/dp/B00GRKD6XU/) 第一部第二章 コミュニケーションと言語の使い方 より)

プロジェクトに携わる人々の頭のなかで構築された概念の集まり、すなわち、ソフトウェアが扱う領域のビジネスの知識というのが、モデルとして表現されているということです。

であるならば、当然ビジネスの変化によってモデルも変化するものと考えられると思います。
つまり、モデルは作って終わりではなく、リリース後もずっと変わっていくもの（変わらない＝ビジネスが停滞している=つまり変わり続ける）と言えます。

エヴァンス本の中身が難しいと先に「[実践ドメイン駆動設計](https://www.amazon.co.jp/dp/479813161X)」を読む人も多いかと思いますが、
この本に欠けているのが、この部分の強調。
エヴァンス本には「第三部 より深い洞察へ向かうリファクタリング」として丸々1部をかけて説明しています。

で、頻繁にモデルが変わるとなると、必要なのはリファクタリング。
特にクラス名の変更を多く使うことになります。

実際今自分が携わるプロジェクトも、新しいビジネスモデルを取り入れるにあたり、多くのクラスを変更する必要性が出てきているのですが、Pythonゆえに短時間での対応が難しいという問題に直面しています。
結局後回して、後日時間を取って丁寧に変更していこうという話になっています。。。

動的型付きの言語はここが弱いところ。
違う型が入ってきても動くし、該当のクラスを使用している箇所を探すのも一苦労です。

これが静的型付けであれば、ほぼ一発回答。最近の発達したIDEを使えば楽に変更が効きます。
最悪誤っていればコンパイルが通らないので、テストの実行や検証環境に上げて確認なんてする前に確認ができます。

そして、静的型付き言語はDIが使いやすいので、きれいにレイヤーアキテクチャを組むことも可能です。

WebアプリをPHPやRubyで入った方から見ると、敷居が高いと思われる静的型付け言語。
アプリサーバーとか必要ですしね。
しかし、最近は[SpringBoot](https://spring.io/projects/spring-boot)に代表されるように、
アプリサーバーもセットになり、コマンド一発で実行環境が作れるフレームワークも多いです。

そして、最近はサーバーレスにも対応。AWSであれば、LambdaLayersなども登場し、フレームワークの重さも気にする必要がなくなっていますし、Lambdaの起動が遅い問題も解決されつつあります。

ぜひぜひ一度試してみてはいかがでしょう。
Gitにファイルを追加し忘れる対策がほしい

# なぜファイルを追加し忘れるのか

原因だけは大体分かってますが、適切な対応策が今のところありません。

## まず状況を確認

作業フローとして
1. クローン
2. ブランチを切る
3. 試しにビルドする
4. 新しいファイルを作る
5. ファイルを各所に登録する
6. ビルドする
7. コミットする
8. マージしてプッシュする or ブランチごとプッシュしてからマージしてもらう

こんなところだと思います。

## 追加し忘れたとき
### プルした人からクレームがきて気付く
困ったものです。いえ、困ったやつがいたものです。
### 急いで追加・コミット・プッシュする
ビルドして動作確認出来ているときはこれで解決できます。しかし迷惑をかけた事実は消えません...

## 原因を紐解く
5.ファイルを各所に登録する
このときにGit追加処理をしていないから、そのまま忘れるわけです。

### なぜすぐに追加処理をしないのか
心理的な問題もあるのですが、類似のファイルをコピーして修正しているときに多く発生している気がします。
つまりファイルをコピーして生成した直後は非常に胡散臭い状態であり、その直後にGit追加するのははばかられるわけです。
とりあえずファイルを適切なコードに仕上げてから追加・コミットしよう、と考えてしまいます。
追加とコミットは別なのだから、追加だけしておけば良いのに。

### 対策はもしかして...
本件の対策ですが、案外簡単なのかもしれません。

#### ファイルをコピーしない
完全に空のファイルを作り、仮にmasterへプッシュしてしまっても平気なファイルを追加するのであれば、心理障壁は下がりそうです。

### 追加されていないファイルをコンパイル時に検出する方法はないか？
同じ問題に悩んでいる人は(全く？)居ないようです...バカなので仕方ない、と諦めます...

と思ったのですが、ビルドのバッチに

```
git ls-files --others --exclude-standard *.cpp *.h
```

と入れておけば、ビルドするたびに未追加のファイルが表示されます。
出てきた結果を見て「あっ」となるだけマシになりそうです。
npmやkubectlの補完関数の遅延読み込み

`npm completion` や `kubectl completion` が重いので、 `bash` や `zsh` の起動時に毎回実行したくない、と思って最初の実行時まで遅延させるようにしています。

## npm

最初の補完実行時に読み込むようにしています。
最初の補完は遅延読み込みのみ実行する関係で、補完できません。

`zsh` の場合は fpath に `_npm` がすでに存在するので、それより優先させるためには `compinit` より後にする必要があります。

```zsh
if type npm >/dev/null 2>&1; then
  # overwrite after compinit
  _npm () {
    unfunction _npm
    eval "$(npm completion)"
  }
fi
```

この記事を書くにあたって、現状の `/usr/share/zsh/5.3/functions/_npm` を確認してみたところ、以下のようになっていたので、今だと `zsh` だけなら不要そうで、初回も `_npm_completion` が呼ばれているので、ちゃんと補完できて良さそうです。
以前は `_npm` ファイルに補完処理の内容が書いてあって、実際に使われる `npm` よりも補完内容が古くて不便だった覚えがあります。

```zsh
#compdef npm

# Node Package Manager completion, letting npm do all the completion work

if type npm > /dev/null; then
  eval "$(npm completion)"

  _npm_completion "$@"
fi
```

## kubectl

こちらは補完関数の方ではなく、 `kubectl` の実行時に補完設定をするようにしています。
そのため、シェル起動後の初回実行時は補完がきかないので、引数なしで実行してヘルプ表示だけするとか、履歴から実行するなどして、補完設定することを想定しています。

```bash
if type kubectl >/dev/null 2>&1; then
  kubectl () {
    unset -f kubectl
    # lazy load
    source <(kubectl completion ${SHELL##*/})
    kubectl "$@"
  }
fi
```
wordpressの環境で２MBの制限をうける！（docker編)

あんまりこの編詳しくないので忘れないように覚書。
https://qiita.com/irico/items/64391ef45e5d71dde147
↑上記の手順でwpのローカル環境を構築した場合を想定。

## 2MBの制限
All-in-One WP MigrationでWPの環境をローカルに持ってこようとしたら、
**最大アップロードファイルサイズ:2MB**　の部分で弾かれてしまいます。

##解決法
dockerの中にphp.iniを作る。
そこでファイルアップロード制限の設定部分を変える。
ちなみに雛形があるのでそれを使いましょう。

```
docker exec -it {docker名} /bin/bash
```
でdocker内に入る。

```
cd ../../../usr/local/etc/php/
```
でphp.iniの雛形部分に移動。
`ls`を叩くと　php.ini-developmentとphp.ini-productionがあります。
https://unskilled.site/dokcer%E3%81%AE%E5%85%AC%E5%BC%8Fwordpress%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%AEphp-ini%E3%81%AE%E5%A0%B4%E6%89%80/
のサイトで違いを参照されたし。
php.ini-developmentが色々エラーを出してくれます。でもセキュリティー等を考えると本番で使用するものはphp.ini-productionがいいようです。

```
cp php.ini-production php.ini
```
でphp.iniファイルを作りましょう。

```
vi php.ini
```
で中身を編集。

## viコマンドが見つからない
https://qiita.com/YumaInaura/items/3432cc3f8a8553e05a6e
上記のサイトを参考にしました。
私はMacなので、

```
apt-get update
apt-get install vim
```
でvi/vimコマンドをインストール。

##ファイル編集
`/upload_max_filesize`でupload_max_filesizeが書かれた箇所を検索して、2Mの部分を編集しましょう。
こちらはアップロードの上限容量になります。
`/post_max_size`　でpost_max_sizeも検索し、記述を変更しましょう。
こちらはPOSTデータの上限容量になります。

編集が終わったら、

```
exit
```
でdockerから抜けます。

あとはdockerを再起動すれば2MB制限が無くなります！
さよなら、私の100ドルクレジット… (ELBでやらかした話)

#あらすじ
###前提条件
 - AWS Educate Starter アカウントに申し込んでいたので、100ドルのクレジット(加盟校)が付与されていました。
 - AWS 超初心者で、普段はAzureしか使っていません。

#事の発端
ある日、ふとBilling Management Consoleで、クレジットの残高を確認してみると...
![キャプチャ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/00d45fc8-1aa1-3a60-65f8-8e6aed2aa04b.png)
**えっ？**
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/ac5d3493-f583-5bf4-f85c-666dee20e8d2.png)
**残高0.02ドル？？？？？**  なにに使ったんだ私は...？
99.98ドルという大金を**約2か月**の間に使い果たしてしまっていました。

#まずい…なんで…？
ここで筆者の血の気が引いてきます。
なんでだ...？
12月の一か月間で引かれたクレジットを見てみると
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/51c1872d-2e76-fa5d-7989-06eb2ecb73ba.png)

**えっ！28ドル！？！？**


RDS(MySQL)を利用していたので、もしやつけっぱなしにしていてクレジットが吹っ飛んだか...？
と思い，公式ドキュメントで料金を確認してみても、db.t2.microは0.017USD/時間なので、そんなに多くはない...
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/1fab880c-a618-20d5-2bc9-a154d74f0331.png)
(よかった...4ドルぐらいだ...。)

##事態が発覚
**はっ！EC2だ！！**
そう確信し、EC2の使用量を見てみると...
![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/65bc0504-6894-e62c-0f6d-05f4d060fca4.png)

**こ れ だ**

でっ でも、EC2のt2.micro(無料利用枠に含まれる)を使っていたから、そんなに大きくはないはず...

目線を下のほうにやると...。
![キャプチャ6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/4f9fae20-bf6d-b171-47ff-8db867fd66be.png)
**やりましたわ...これだ原因は...。**
#起った事態をまとめると
はい。お分かりの通り，**ロードバランサを実行しっぱなしにしていた**ので、695時間分のご請求が来ていました。
そこで、AWSの公式ドキュメントで料金を確認してみると
![キャプチャ7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331782/4ff15b3f-562c-5f9a-c221-8b3af5d971b4.png)
ん～1時間あたり0.025ドルだから、695時間で掛けると17.375ドル... これですわ。

AzureのBasic Load Balancerに慣れてしまっているので、てっきり転送量の従量課金だけだろうを思い込んでいました。
#対策
**普段使っていないクラウドサービスを始めて使うときは、絶対の絶対に公式ドキュメントで仕様と料金を確認しましょう。**

大事なことなのでもう一度言いますが、**公式ドキュメントで仕様と料金を確認しましょう。**
#まとめ
クレジットカードに請求が来る寸前で気づいてよかったです。
偉大なる100ドルクレジット...AWSさんありがとうございます。感謝です。

**公式ドキュメントで仕様と料金を確認しましょう。**

以上になります。読みにくい記事だったと思いますが，ここまで読んでくださりありがとうございました。
被災地（水害地）の移動や充電について - グラベルロードバイクのススメ

災害現場での移動は、クライシスマッピングを実行する上で重要なファクターです。

災害現場での空撮といえど、飛行する上での基本ルールは、航空法などの法規に従って撮影を行うことは、当たり前であり、そのような混乱している現場でこそ、自己完結によるルールの遵守は、災害地での作業者モラルをDroneBird隊員は模範となってほしいと思います。

岡山県の真備町での災害が起こった際に、現地対策本部の小学校に到着し、作業を開始しました。

「あれ！道路脇はドロで、駐車できない...仮に駐車したが最後抜け出せないかも...」

これでは、充電しながら、撮影も思うようにできないという経験したわけです。

災害地の移動手段で気をつけたいこと４つ
ー渋滞している
ガソリンを使わない移動ならベター
ー被災者の邪魔をしない
駐車車両が邪魔にならないか、そもそも駐車しなくてもいい手段とは
ー移動がそこそこ早い
時速20km前後での移動が出来ます。
ー撮影機材は最小限に
充電機材が搭載できればベスト

充電拠点へ車移動または、災害対策本部にて充電
そこから自転車で撮影スポットへがベストであろうと思います。

そんな理由で、健康管理もそうですが、日頃から自転車で830mの六甲山（自転車で可能な最高高度）へ登ってトレーニングしているわけです。

![51478148_2398196610223240_7599818654586241024_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/322439/ecde0995-1842-8111-84b3-92ac0ad9cb81.jpeg)

グラベルとは「砂利道」という意味で、マウンテンバイクのタイヤですが、ロードバイクみたいに軽快に走れる。

「じゃ、マウンテンバイクでいいじゃん」

と思うでしょうが、なるべく車体重量も軽いほうが、災害地の状況をみて、持って運ぶことや、タイヤを外すなんてこともやりやすいほうがいいのです。

写真は、Ritewayという会社のSonoma Adventureというグラベルロードバイクです。

最近のロードバイクは多段速で、良いものは前２後ろ１１段の計２２段変速などがあります。
グラベルロードバイクに関しては、ドロや土を走ることからすると多段速になるとメンテナスが行いづらくなるので実用的ではありません。
そんなわけで、コンポーネント（段変速）は後ろ８枚がいいので、クラリスあたりで十分です。
ブレーキは機械式でもいいので、ディスクブレーキがおすすめ。

私のオススメの災害対策用の１０万円前後のグラベルロードバイクは以下のとおりです。

ーFuji 20' FETHER CX (2x8s) 
https://www.fujibikes.jp/2020/products/feather_cx/

ーJamis Renegade Exile
http://www.jamis-japan.com/renegadeseries.html

ーFelt Broam60
https://www.riteway-jp.com/bicycle/felt/bikes/broam60_8081-2/

ーRiteway Sonoma Adventure
https://www.riteway-jp.com/bicycle/riteway/sonoma-adventure

ーDcathlon Triban
https://www.decathlon.co.jp/collections/road-bikes/products/triban-rc-520-cycle-touring-road-bike-cn?

なんかがオススメです。

自転車で200kmの移動は、慣れてないと難しいですが、被災地の近くまで行き、そこから自転車で移動でも渋滞が途中で会った場合に、近くのコインパーキングに駐車して諦めることも重要です。
パンクの修理やその他自己完結に必要な知識もあると、さらに災害に強い隊員となれるでしょう。
AWS 認定高度なネットワーク – 専門知識 受験メモ

先日合格したセキュリティ試験に引き続きネットワーク試験も受験したので、自分が行った受験対策を紹介します。

## 試験範囲

試験ガイドに記載の通りです。
> 「AWS 認定高度なネットワーキング – 専門知識」 (ANS-C00) 試験は、複雑なネットワーキングタスク
を実行する個人を対象としており、大規模な AWS とハイブリッド IT ネットワークアーキテクチャの設
計と実装に関する高度な技術スキルと経験を認定します。

出題範囲は以下の通りです。

|     分野   |       試験における比重 |
|:-----------------|------------------:|
|分野 1: 大規模なハイブリッド IT ネットワークアーキテクチャを設計し、実装する |23%|
|分野 2: AWS ネットワークを設計し、実装する| 29%|
|分野 3: AWS タスクを自動化する |8%|
|分野 4: アプリケーションサービスとネットワークの連携を構成する |15%|
|分野 5: セキュリティとコンプライアンスを設計し、実装する |12%|
|分野 6: ネットワークの管理、最適化、トラブルシューティングを行う |13%|

試験ガイドを詳細にみていくと、「AWS Direct Connect」「Route 53」の記載もあります。

他のプロフェッショナル試験や専門知識同様、170分の試験になります。（受験料：30,000円）

## 受験対策

受験にあたり自分が行った対策は以下になります。
セキュリティ受験後すぐであったため、ネットワーク試験用に費やしたのは1週間ほどです。



### AWSのネットワーク関係のサービスのBlackbeltを読む

「AWS クラウドサービス活用資料集」の「Networking & Content Delivery」に分類されているサービスのBlackbeltに全て目を通しました。

- Elastic Load Balancing (ELB)
- Amazon VPC
- Amazon CloudFront
- Amazon CloudWatch
- Amazon Route 53
- AWS Transit Gateway
- AWS Direct Connect

YouTubeにある「VPC」「Route 53」などは通勤中に聞いていました。

### ベストプラクティスを読む
以下はセキュリティのホワイトペーパーですが、ネットワークのセキュリティなども記載されていますので、再度確認しました。
https://d1.awsstatic.com/International/ja_JP/Whitepapers/AWS_Security_Best_Practices.pdf

### サンプル問題を解く

https://d1.awsstatic.com/training-and-certification/docs-advnetworking-spec/AWS_Certified_Advanced_Networking_Specialty_SampleExam.pdf

公式サンプル問題は10問で、回答もあります。(ただし英語です)

### 模擬試験が無い？

いつもの流れで模擬試験を受験しようと思ったのですが、なんと模擬試験の提供はありません。

AWS試験ではネットワークとビッグデータのみ模擬試験が提供されていないようです。


# その他
この試験は受講後にスコアレポートが渡されます。通常AWSの試験の場合スコアレポートは後日WEBからになりますが、この試験の場合は現地で手渡しでした。
（受付の方に聞いたらスコアレポートを渡す試験が2つあるらしいです。）


セキュリティ試験から1週間ほどの学習でネットワーク試験も突破することができました。
個人的にはDirectConnect構築を含めた案件に携わったことがあり、そこのでのアドバンテージも大きかったと思います。
コンテナデバッグの底力を感じてください　〜VSCodeの品格

## 概要
Dockerfileを用意して**コンテナ上で開発**するときの話。

- コンテナ内にローカルのフォルダをマウントして、ローカルファイルを編集してもいいけど、コンテナ内のファイルを直接触りたい。でもvimでいつも触ってます。。

- コンテナ内のC++ファイルをVSCodeでデバッグできたら嬉しいけど、結構めんどくさかったから諦めてしまいました。。


**そんなあなたに朗報！！！**
マイクロソフト大先生がすごい拡張機能を出してくれました！！素敵やん！！


## VSCodeによる デバッグ環境の構築
ここでは、**VSCode**を使って、

1. **コンテナ内にアクセス**して、ローカルファイルと同じ感覚で編集する。
2. 上の環境で**C++のソースコードをデバッグ**（ブレークポイントなど）する。
ことを目標とします。

### 1 コンテナにリモートアクセス
まず、以下のマイクロソフトの```Remote Development``` という拡張機能をインストールしてください。

![vsremote.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/030019be-09e4-ab25-5430-86dcbb55783f.png)


インストールするとVSCodeの左下に緑の`Open a remote window`というボタン（下図）が出てくるので、クリックし、つなぎたいDockerコンテナを選択します。
![vsremote1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/7133bb3c-c782-845e-72a7-36d240ee0bdd.png)

すると、新しいウィンドウが開き、ここで編集するとコンテナ内のファイルを直接編集できます。
めっちゃ簡単やん、、すばらしい、、、、

### 2 C++ のデバックをVSCodeで行う
F1を押して、tasksと入力すると、`configure tasks` みたいなのが出てくるので、クリックすると`tasks.json` に飛びます。
そして、`tasks.json` を

```tasks.json
{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "echo",
            "type": "shell",
            "command": "自分がいつもc++ファイルをビルドするときに打つコマンドを書いてください〜　例）cmake. && make とか",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

```

上のように編集します。このとき、コマンドは.vscodeフォルダがあるところからの相対パスで書くことに注意！
`tasks.json` を実行してc++のファイルをビルドしたいときは、`Ctrl + Shift + B` で実行できます。

さらに、F1から、`launch`とすると、`launch.json` を作ることができます。そこに、

```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "デバッグしたいビルド後のファイルへのパスを書きましょう〜",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}
```

上のようにlaunch.jsonを書くと、左の虫のマークから、デバッグができます。（いつものように、F5から実行。）
このとき、コンテナ内に`gdb`が入っていることを確認してください。入っていないときは、

```bash

apt-get install gdb
```
で簡単にインストールできます。

###結果　コンテナ上でC++のデバッグ簡単にできるやん！！
![vsremote2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519792/bba928ce-bd0a-c356-0f31-e9064c6fe813.png)


**マイクロソフト先生ありがとう....**



おわり。
AWSのアラームをAWS ChatbotでSlackに通知する

AWSのアラームをSlackに通知するにはlambdaとかを設定する必要があるのですが、AWS Chatbotを使えば簡単に設定できるようです。ということで試してみました。
## 前提
以下の設定はできているものとします。
- Slackでアラートを通知させたいチャンネルの作成
- Cloudwatchでのアラーム作成
- Amazon SNSの設定

## 設定方法
AWS Chatbotを開き、Configure new clientをクリック。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538049/1c3cb0c9-bc1f-7b9b-0086-37f2e248dd77.png)


Slackを選択します。
![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538049/27c1b470-2179-462a-790f-17d70d40f685.png)


Slackが立ち上がるので**許可する**を選択します。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538049/1f2d8d65-e1f9-3724-e4f7-40a16aa21cb8.png)


成功すればこんな画面になります。
Slack Channelは通知するチャンネルを指定します。
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538049/e535c235-a583-5600-3753-3622a3103bb8.png)


次にパーミッションの設定ですが、既存のIAMロールを利用するか、自動で作成されるIAMロールを利用するか選択します。
今回はテンプレートから作成を選択し、Role nameを入力します。
ポリシーはデフォルトでNotification Permissionsが選択されている状態です。特に変更はしません。
![005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538049/eed68cdd-6cb0-73ac-49cf-3b97f5c6f719.png)


NotificationではSNSのトピックを選択します。
![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538049/08be752e-7f9e-b694-3104-5e33bbdb7c88.png)


AWS Chatbot側の設定は以上です。
次にSlackに戻って、通知するチャンネルで`/invite @aws`を入力します。
問題なく連携できていれば`@aws help`でヘルプが表示されます。

アラームを発生させるとこんな感じで通知がきます。
![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538049/cb65a7ce-3d83-fdd9-b0ef-5a069d611726.png)

以上です。
2019年CodeForKusatsu　ゆるーい活動記録

##毎月第二水曜日or木曜日に定例会を開催

![1518699657888.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/fddc1f6a-a9a8-480c-cad2-b95815501d9c.png)
いつも、ゆるーい話をしています。その中で出た活動アイデアを、「のり」で実現していくというパターンです。コードを書けるメンバーはきわめて少ないため、いつも、周りに助けをもとめてお手伝いいただいています。
メンバーは集まれる人が集まる。誰が来るかわからないときも多い。そんな定例会です。市長が来ることおあります。他府県からの参加もあり、中高生も参加します。多様なメンバーの集まりです。そして、1回きたらCodeForのメンバーです。（名簿はありません）
##3月10日　チャレンジオープンガバナンス(COG)最終審査
**[COG2018](http://park.itc.u-tokyo.ac.jp/padit/cog2018/)**で「オープンガバナンス総合賞」を受賞しました。[資料](http://park.itc.u-tokyo.ac.jp/padit/cog2018/final/39_Idea_COG2018_presentation.pdf)
![53285583_2225992487480338_2502356819775586304_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/f8aaa9a5-0186-d2b1-b018-4be1f26d84b6.jpeg)
##4月7日オープンデータソン＠京都に参加
諸国・浪漫さんが主催するオープンデータソンに参加して、ＯＳＭとWikipediaTownを体験しました。2019年はCodeForKusatsu主催で草津市でオープンデータソンを開催するという企画に補助金がついたので、その勉強のために参加しました。![56697154_1301915433292334_6785726806428221440_o.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/770bdb46-c973-a503-4846-c1937a959f93.jpeg)

##4月28日　奥村先生　受章記念大バーベキュー大会＠琵琶湖
奥村先生の勲章受章をネタに、みんなでBBQ大会を琵琶湖で開催。シビックテックの仲間も全国から駆けつけてくださり、大いに盛り上がりました。**これぞ、CodeForKusatsuの得意とするところです(^_^;)**
![58383580_854065584944884_1565302218301636608_n (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/74a1de41-6d8b-b9b0-f626-5d8e2aa85c56.jpeg)
![59138341_854065791611530_5422074342055870464_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/6c6e16be-611e-54bc-06bf-1c72c2b35f5f.jpeg)
####番外編
終了後に、BBQに飛び入り参加された嘉田（前滋賀県知事・現参議院議員）さんの自宅へおっさん3人組で行くことになり、琵琶湖の橋板から琵琶湖水を飲むという貴重な体験をしました。全国のみなさん、琵琶湖のみずは直接飲めるんですよ！![IMG_6913.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/c482008d-528a-ed07-892d-bc7c883b1521.jpeg)

##7月1日　ＵＤＣキックオフイベント参戦
アーバンデータチャレンジ 2019 キックオフ・イベント、「UDCセカンドステージへ！〜裾野を広げ、デジタルスマートシティの先鞭となるために〜」
（土木学会インフラデータチャレンジ2019との共催）に、滋賀県の拠点としてCodeForKusatsuで参加しました。何が何かわからないまま、勢いで参加したので、今後の展開については、日々検討中ですが、アイデアとしては、行政の税務課（固定資産税）が持っている**航空写真**のオープンデータ化に取り組もうかなと思っています。
![01.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/479cf3a0-37c4-f1e2-41b4-cac0a6952e37.jpeg)
##9月27日[CodeforJapanSummit2019幕張](https://summit2019.code4japan.org/)参加
登壇者として、スタッフとして、参加者として、C4Kから5名で参加しました。![IMG_20190928_124404.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/e198358d-6b15-6e35-3088-7ffd66673044.jpeg)
##12月8日　「みんなでまちの事典&地図を作ろう！～草津市民総マッパー化計画～」草津オープンデータ村！
CodeForKusatsu・ＵＤＣ・草津コミュニティ事業団の共催、草津市立図書館・街道交流館・教育委員会の後援で開催。諸国浪漫のメンバーの方や、さいたま・岐阜・千葉から応援にきていただき、市長も駆けつけていただき、無事に楽しく面白く開催できました。次の開催は2020年2月予定、目指せ草津市民総マッパー計画＆ウィキペディアタウン草津！![79650138_2699899666715391_8657018901671968768_n.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501152/b84f0d66-86bd-1f79-6424-35cc60a6b7ea.jpeg)

####2019年もCodeForKusatsuは、多くのシビックテックのみなさんに助けられて活動することができました。これからも見捨てずに、みなさんよろしくお願いいたします。
恋人を自動で見つけてくれる「恋のキューピットAI」をつくった話

# はじめに
こんにちは。
クリスマスも近づき、人肌が恋しくなる時期になりました。

ですが、街で可愛い人を見かけても声をかける勇気があるわけはないし、**SNSで気の合いそうな人が偶然恋人を募集していても連絡を送る勇気は当然ありません。**

そこで、

**じゃあ勝手に、性格の合いそうな恋人探し中の人同士をマッチングさせちゃおう！！**

と思い、今回開発したのが[「恋のキューピットAI」](https://twitter.com/love_and_loveee)です!

~~（本当は、「#Twitter転職」を活用して新しい職を探している人と、企業をマッチングさせるTwitter Botを作りたかったが、どう上手に企業と転職希望者をツイート内容から区別するかが見えず、アドベントカレンダーの担当日も近く、諦め、恋人探しの方にしました）~~

# 何をつくったか

<img width="400" alt="スクリーンショット 2019-12-18 13.06.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200298/e7372d2d-24a9-2a98-9790-2b9205d6c844.png"><img width="400" alt="スクリーンショット 2019-12-18 12.57.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200298/cf1d8e1a-db83-84b3-451e-56ccfafe3560.png">

恋のキューピットAIはこのように、すでに稼働していて、毎時間ひたすらTwitterユーザーをマッチングさせています。
これで、自分から絡みに行きづらい人でも**「なんかよくわからいけど、AIがオススメしているみたいだし、クリスマス一緒に過ごしませんか？」**と誘えるようになるわけですね！！


プログラムの具体的な手順は、以下の通りです。

**① 「彼女欲しい」と最近ツイートした人を何人か集める**
**② 「彼氏欲しい」と最近ツイートした人を何人か集める**
**③ 自己紹介や過去のツイートなどの情報から、最も相性の良さそうなペアを１組抽出する**
**④ 両者のTwitter IDを含んだツイートをアカウントでツイートをする**



# 技術的な説明
![スライド1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/200298/02f51cb5-b838-c35f-bf19-dff58affdd75.png)

こんな感じで、
まず、Twitter APIを使ってそれぞれの対象ユーザーを集めてきます。（前回プログラムを動かした時間以降に呟いた人たちを集められれば良いです）
ただし、このままだと怪しいボット（特に「彼氏欲しい」ツイートしているアカウントに多い）なども一緒に集めてきてしまうので、それらを出来るだけスクリーニングします。
こうして残されたアカウントたち同士で、自己紹介欄やら過去のツイートやら（ここはまだ試行錯誤中）を比較し、相性の良さそうなペアを探していきます。
最後にそのペアをツイートすれば完了です！

自分は[コアサーバー](https://www.coreserver.jp/)に自分のレンタルサーバーを持っていたのでそこに、このプログラムと実行するシェルスクリプト ファイルを置いて、CRONジョブを設定し、毎時間動くようにしています（このCRONジョブの設定が１番時間かかった）。

まだ、相性の評価方法は試行錯誤中ですが、プログラム自体は全部で4時間ほどで開発完成しました。
（Twitter APIも申請したら数秒で取得できました。）

# 懸念点
## Twitterからスパム扱いされないか
何よりもこれが気になります。
この恋のキューピットAIは、ツイートするときに、対象者に直接メンション（@Twitter ID）を飛ばすので、相手に通知を送ってしまいます。
最近Twitterさんは、なにやら規制が厳しそうですし、怪しいボットとして消されないか怖いです。



## ツイートしない時がある
サーバーのCRONジョブが正常にプログラムを実行していても、ちゃんとツイートしてくれないことがよくあります。
おそらく、Twitter APIの規制的に毎時間ツイート検索して、ツイート投稿することに制限が掛けられているのかと推測しています。


## 相性の評価方法
[本体](https://twitter.com/love_and_loveee/)を見てもらえばわかると思いますが、まだまだきちんと相性のあってそうな人同士をマッチングできている訳ではありません。
精度がガバガバです。
どうやって評価しようか考えています。
是非、皆さんの意見をご教授頂きたいです。

# 終わりに
~~求人マッチングのボットを作りたかったのを妥協してつくったわりには、~~
結構個人的にこのボットは気に入っています。
実は、過去にこんなもの（「[落合陽一っぽいツイートを自動生成してツイートさせてみた](https://qiita.com/ahpjop/items/9f532a72ac4666b9083a)」も作ったことがありましたが、同じくらい気に入ってます。
特に、

- **Twitterという１番その人のことがわかる情報を元にマッチングさせる点（マッチングアプリのプロフは嘘とサクラだらけ）**
- **「彼女欲しい」となんとなくツイートした人と、同じく「彼氏欲しい」と似た時間になんとなくツイートした人がマッチングされる感じがすごいエモい**
- **マッチングアプリでは、自分から（特に男は）能動的にアクションを起こさなくてはいけなかったものが、これだと受動的にマッチングできる点**

が、なかなか新しいんじゃないかなと思っています。

ぜひ、皆さん[フォロー](https://twitter.com/love_and_loveee/)して意見ください！（特に相性の精度向上のところ困っている）


あ！
それと、**[前回の記事](https://qiita.com/ahpjop/items/928e9220de166d364671)に対してTwitterで意見をくれた方々改めまして本当にありがとうございました！**

意見をもらっておいて、こんなTwitter Botをアップデートよりも先に開発してしまってすみません！
自分でも**今自分がやるべきことはこれじゃないだろおおお！**と分かってはいたのですが、思いついたら作らずにはいられない体質なので、先にこれをつくってしまいました。

大変申し訳ございませんでした。

開発者に対する意見、お叱りに関してはすべて[こちら](https://twitter.com/ahpjop)に送りください。

それでは！！
Slackで参加者のユーザーIDとスクリーンネームを取得する

IDとnameだけ欲しかったのでとりあえず

```.py
import requests
import json

url = "https://slack.com/api/users.list"
token = ""

userlist = {}
payload = {"token": token}
response = requests.get(url,params=payload)
user_json = response.json()
for i in user_json["members"]:
  userlist[i["id"]] = i["name"]
print(userlist)
```

ここから色々と絡めていく
マンガでわかる Memento

![30FF9A6B-DE63-4F33-A982-44F3F818D51A.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11525/5eafa59a-c3ca-97a9-a47b-83056237ce66.png)

まったく、現代っ子は Ctrl + Z があって当たり前だと思ってるんだから。

Memento という英単語は馴染みのない方も多いかもしれませんが、これ意味としては、「思い出の品」です。事実そのものは後に残せなくても、記念品があれば代わりになる、みたいな感じ。

リバーシやってて、気づくのが遅れたら 1 手戻しただけじゃ勝ち目ないような状況に追い込まれてたなんて、よくある話ですね。ぜんぶの手を記録しておけば、1 手戻しでは勝てないなら 2 手 3 手戻して... と、スマホのカメラをアンドゥスタックとして使えば、いつか必ず勝てます。

リバーシの盤面は originator と呼ばれます。リアルな事象であり、アンドゥ機能以外は、それ単体で完全に成立する系です。

めもりーちゃん(のスマホ)の部分は caretaker です。適切なタイミングで写真を撮ってる、状況のお世話をする役です。

お世話の結果何ができるかというと、複数の memento である写真のスタックができます。写真は実際の物理盤面よりはるかに軽量なオブジェクトだというのがポイントです。そうでないと、いくらでもアンドゥできるほど大量には保存できませんから。

originator には普段使わない一括書き戻しメソッドがあります。それは caretaker に対してのみ、アクセスが公開されているのが望ましいでしょう。他の誰かが、過去実在しなかった状態に改ざんできてしまうのは危険ですから。

デスクトップ GUI のアンドゥ専用か関係ないなと思う方もいるかもしれませんが、最近は Web のユーザーインターフェースも、本当にやりますか確認から、即実行して間違っていたら「戻す」でキャンセルできるものも増えてきました。

それにみなさん、いつもメメントにお世話になってるじゃないですか。Git でいえばこれ、ワークスペースとリポジトリとコミットの関係ですよね。デザインパターンみたいだなと認識しておいて、損はないと思いますよ。
Cloud Foundry で Front と BFF を別アプリにして Socket.IO で通信する方法

## 概要

Frontendの静的ファイルをNginxのアプリで配信し、Socket.IOの通信はBFFの別アプリへproxyする方法です。

## 前提

複数インスタンスでSocket.IOを使う場合、同一クライアントからの通信は同一インスタンスへ流れるように固定しないと、最初のハンドシェイクで失敗します。

## FrontendとBFFが同じアプリの場合

ドキュメントにある通り、アプリからJSESSIONIDを発行すればルーター側でVCAP_IDを発行して以降の通信を最初のインスタンスに固定してくれます。
https://docs.cloudfoundry.org/concepts/http-routing.html#sessions

## 本題：FrontendとBFFが別アプリの場合

### 方針

Frontendはnginx-buildpackで静的ファイルを配信、Socket.IOの通信はproxyしてBFFへ流す。

### 問題

BFF側のルーターから発行されたVCAP_IDが、Front側のルーターを経由する時に上書きされてしまい、BFFへの通信が固定できない。

### 対策

FrontendのNginxを経由する時にJSESSIONIDとVCAP_IDのCookie名を変更する。
なおCookie名の書き換えにLuaライブラリを使うので、こちらを参考に実行バイナリをOpenRestyに変更してください。
https://qiita.com/proyuki02/items/431dd297804ad53f2717

```nginx.conf（ポイント以外は省略）
http {
  server {
    header_filter_by_lua_block {
      local cookies = ngx.header.set_cookie 
      if not cookies then return end
      if type(cookies) ~= "table" then cookies = {cookies} end
      local newcookies = {}
      for i, val in ipairs(cookies) do
          val = string.gsub(val, "JSESSIONID=", "JID=")
          val = string.gsub(val, "__VCAP_ID__=", "VID=") 
          table.insert(newcookies, val) 
      end 
      ngx.header.set_cookie = newcookies 
    }

    location /socket.io/ {
      proxy_pass https://{{env "REDIRECT_HOST"}}/socket.io/;
      proxy_set_header Host {{env "REDIRECT_HOST"}};
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";

      set $new_cookie $http_cookie;
      if ($new_cookie ~ "(.*)(^|;)(\s*)JID=(.*)$") {
          set $new_cookie "$1$2$3JSESSIONID=$4";
      }
      if ($new_cookie ~ "(.*)(^|;)(\s*)VID=(.*)$") {
          set $new_cookie "$1$2$3__VCAP_ID__=$4";
      }
      proxy_set_header Cookie $new_cookie;
    }
  }
}
```

以上です。
Docker for Windowsで "error during connect~" のエラーが出たときの対処法

Docker for WindowsをインストールしているWindows PCにて、PC起動時などに以下のダイアログが表示されることがあります。これの対処法。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129526/6ba71c7a-add7-dde8-febe-c76764fbe5b9.png)

## 誤った対処法
1. とにかく「Reset to factory defaults」をクリックする
2. 画面に従って処理を続ける

このボタン配置だと押したくなりますよね？私は押したくなる。「Upload crash Report」では何も解決しなそうだし、まさかQuitで何もせずに終了するはずもなく。
この「Reset to factory defaults」ボタン、要はdockerの初期化ボタンです。結果的に目先のエラーは直りますが、そもそも**イメージとかビルドされたコンテナとかも全部なくなります**。
今までこちらの方法で対処してました。
ただ、コンテナ復活させるのにかなりの時間がかかります。

## 正しい対処法
1. "Quit"を押してダイアログを閉じる
2. WindowsのサービスからDockerサービス[^1]を再起動する

これでだいたい直る、そうです。(ソースは[こちら](https://success.docker.com/article/docker-for-windows-fails-with-a-daemon-not-running-message))
どうしても直らなかったら「Reset to factory defaults」が必要かもしれませんが、まずはサービスの再起動で直るかどうかを確認してみましょう。

## まとめ
ダイアログが表示されてボタンがあるとつい押したくなってしまいますが、ボタンを押すのが必ずしも正とは限りません。
エラーのダイアログが表示されても冷静に対処しましょう。

[^1]: 私の環境では"com.docker.service"という名前でした
オブジェクト指向を雑に解釈してみる〜カレーのレシピに落とし込んだ〜

はいっ今回はですね
~~いい加減ネタも尽きてきて~~

オブジェクト指向をカレー作りに例えて雑に！！！！！解釈したものを！どっかどっかと！記述しようかと！思います！
（自分の頭の中整理・言語化が主な目的です。）

## 前提
オブジェクト指向というのはあくまで「概念」であって、特に正解は無いんじゃないかなと思ってます。
人によって捉え方はマチマチなので、この記事も
「この人はこういう風に捉えてるんだな」・「こういう考え方も確かにできるね」と思っていただけると。

間違ってたら**優しく**コメントください。

もう一度復唱しましょう、はい、一緒に。せーの。

**や　さ　し　く**

では、いっていみよう

## 誰向け
私（初心者）向けです。
もし勘違いがあったら**優しく**教えてください。

## オブジェクト
オブジェクトというのは「物」と捉えてください。とにかく「物」です。
今回はカレーの材料としましょう。

とすると、以下がオブジェクトになるでしょう。

* 豚バラブロック
* にんじん
* 玉ねぎ
* じゃがいも
* カレールー
* 水
* サラダ油
* 米

ここでは上記を定義しましたが、定義によってはカレーライスもオブジェクトになったりします。
とりあえず、「物」です。

## クラス
ここではクラスを「役割ごとに分類したもの」とします。
今回は「カレーができあがるまでの工程の1つ1つ」を役割と定義し、分類します。

そうすると

* 具材を揃えるクラス
* 調味料を揃えるクラス
* 道具を揃えるクラス
* 調理クラス
* 盛り付けクラス

ざっとこんなもんでしょうか。
こんな感じで雑に分類します。
（実務では雑に分類しちゃだめですよ！）

## プロパティ
プロパティはオブジェクトの説明です。
今回で言うところの「材料の説明」になります。

```
class にんじん {
  色 = オレンジ色;
  味 = 少し甘い;
  産地 = 国産;
  量 = 1本;
}
```

## メソッド
メソッドは、実際の命令(function)に値するかと思います。
具体的な動作（何をどうするか）を指定し、カレーを作っていきます。

```
class 調理 {

	function 野菜を切る {
		具材を揃えるクラス呼び出して切る
	}
	function 具材を炒める {
		具材を揃えるクラスを呼び出して切る
	}
	function 煮込む {
		水を入れてカレールーを入れて20分煮込む
	}
}

class 盛り付け {

	function しゃもじを取り出す {
		しゃもじ出す
	}
	function ルーをごはんにかける {
		調理クラスを呼び出してご飯にかける
	}
}

盛り付け();
```

![uploading-0]()


最後に盛り付けてカレーライスの完成です。

## おまけ?インスタンス

カレーが1週間とか続いたらしんどいと思うんです。
だから、カレールーを再利用しましょう。

ということで、インスタンス（オブジェクトもメソッドも）で再利用します。
カレーうどんでも作りましょうか。

```
new(カレーうどん).調理 {
	function カレーうどん作る {
		調理クラスを呼び出し、だし汁と麺追加
	}
}
```


## 結局何が言いたいのか

今回は雑of雑にオブジェクト指向を紹介しました。
言いたいことは3つ。

* 定義や分類の仕方はまちまち。これが正解でも不正解でも無いと思ってます。
* オブジェクト指向は使い回しや再利用できて便利。
* 優しくして

結局は実際にDB設計であったりコードに落とし込んで実践的にやったほうが
なるほどなとなると思います。文章だけではなかなか難しいです。

## 参考URL
以下のURLを参考に書かせていただきました！ありがとうございます。

* [オブジェクト指向が5000%理解できる記事](https://qiita.com/it-hero/items/b2f8e39d7cc23ad505f9)
* [【swift】オブジェクト指向について簡単にまとめてみた【初心者向け？】](https://qiita.com/narukun/items/063be69218a2806c4ab7?fbclid=IwAR2jmx4dAlIMt98r6-w_W62YQoI4u0EscNKtgrHOAuWLNvfk5UWLN3F6aeg)
【Beanstalk】 import uuidでエラーが出た時の対処法

### エラー
- デプロイ時、`import uuid`で`...138 if not 0 <= time_low < 1<<32L`のようなエラーが出る
- その後、デプロイしようとしても失敗してしまう

### 原因
`requirements.txt`に`uuid`が含まれた状態でデプロイすると、環境が壊れてしまう（らしい）

### 対処法
1. `Beanstalk`のコンソール画面から`Action > 環境の再構築`
2. `requirements.txt`から`uuid`を削除
3. 再デプロイ

### 参考
- https://stackoverflow.com/questions/44421761/flask-beanstalk-deployment-errors
PlayCanvas対応ミドルウェアを紹介(2019年12月時点)

# 何
PlayCanvasに対応しているミドルウェアをひたすら紹介するだけの記事です

## photon
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148084/2f37a5fa-1063-ef55-a277-ac2ed7af0748.png)
ExitGames(国内代理店はGMOクラウド)が提供するマルチプレイ向けのネットワークエンジンです
ネットワークを介したマルチプレイが簡単に実装できます
[PlayCanvasでPhotonを使う | Qiita](https://qiita.com/utautattaro/items/d754b9c0fcb50dc1100a)
[photon-starterkit | PlayCanvas](https://playcanvas.com/project/433966/overview/photonstarterkit)

## adx 2
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148084/14825aa3-1035-7264-fa5b-61cee4aa4e7a.png)
CRI middlewareが提供するサウンドミドルウェアです
3Dサウンドやインタラクティブミュージック的なことが簡単にできます
[統合型サウンドミドルウェア CRI ADX2](https://game.criware.jp/products/adx2/)
[ADX2Demo | PlayCanvas](https://playcanvas.com/project/586603/overview/adx2demo)

## H2MD
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148084/d70c5c50-a174-1c13-928f-8c0efde468f4.png)
AXELL CORPORATIONが提供するアルファムービーミドルウェアです
テクスチャにアルファ付き動画を貼り付けることができます
[H2MD | HTML5向けムービー再生ライブラリ](https://h2md.axell-embedded.com/)
[H2MD Movie Texture Sample | PlayCanvas](https://playcanvas.com/project/630378/overview/h2md-movie-texture-sample)

## Effekseer
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148084/fcae013b-9591-6f64-ecc2-18d6c983df60.png)
オープンソースのエフェクトミドルウェアです
エディタで作成したエフェクトをPlayCanvas上で再生することができます
[エフェクト制作ツール「Effekseer」](https://effekseer.github.io/jp/)
[EffekseerSimpleSample | PlayCanvas](https://playcanvas.com/project/649529/overview/effekseersimplesample)

## spine
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148084/58476a78-29f6-26e0-a8b1-8ae8b3821035.png)
Esoteric Softwareが提供する2Dアニメーションミドルウェアです
2Dイラストのボーンアニメーションをエディタで作成し、PlayCanvas上で再生することができます
[Spine ゲーム用2Dアニメーション](http://ja.esotericsoftware.com/)
[playcanvas-spine | github](https://github.com/playcanvas/playcanvas-spine)

## 8th wall
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148084/74c43886-6661-17c4-0c7d-e98a162106f1.png)
8th wallが提供するWebARミドルウェアです
マーカーARやマーカーレスARがPlayCanvas上で作成できます
[8th Wall | Augmented Reality](https://www.8thwall.com/)
[8th Wall | PlayCanvas](https://playcanvas.com/the8thwall)
SwiftUIでScrollViewが更新されない時の対処法

ScrollView（ForEach）で参照している配列の値をCombineを使って動的に更新した際に、Viewが反映されない事象が起きた。
データの送受信でバグがあるのかとも考えたが、Listにしたところ問題なく反映されたので色々調べたがピンポイントな解決策がなかなか見つからなかったのでQiitaにも残しておく。

# 環境

Xcode 11.3(11C29)

# 解決策

結果的に空配列ではなく、なにかしらの初期値をセットしておくことで動的に更新されるようになった。


```swift
@Published var items: [String] = [""]
```


以下のStack Overflowの回答で解決した :pray: 

ios - SwiftUI ForEach not correctly updating in scrollview - Stack Overflow
https://stackoverflow.com/questions/59316078/swiftui-foreach-not-correctly-updating-in-scrollview

--
WebでLaravel のサンプルプログラムを動かせる Tinkerwell


# Tinkerwellとは
* Web上で実行できる Laravel対応のコードスペニット
* Laravel のコードをブラウザで動かして コードをURLで共有できます。
* 勉強やコードレビューなどで、実際に動くものを見せたりするのに便利そうです。

# 実行画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21391/d1094e4f-2ffe-5300-6267-174b63eeb394.png)

* 右上の Save を押すと共有URLが 発行されます。
  - https://web.tinkerwell.app/#/snippets/c6e09635-71d4-4073-882a-96a89b9a08d9


## あれこれ

* 初回開くと Loadingにめっちゃ時間かかります。今後の改善されることを期待。
* embed 対応してくれるとめっちゃ良いですね！
* デスクトップ版（有料）があるようです。 未調査です。


* Laravel の Tinker を調べていたら、たまたま発掘したので、ご紹介でした。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">💫Say hello to Tinkerwell Web!<br><br>It is Tinkerwell right in your browser - packed with code snippets from the <a href="https://twitter.com/laravelphp?ref_src=twsrc%5Etfw">@laravelphp</a> documentation. <br><br>Learning Laravel never was easier. <br><br>Tinker with code, save snippets and share them with others.<a href="https://t.co/gH9sPj4T98">https://t.co/gH9sPj4T98</a> <a href="https://t.co/iJNy319ACD">pic.twitter.com/iJNy319ACD</a></p>&mdash; Marcel Pociot 🎆 (@marcelpociot) <a href="https://twitter.com/marcelpociot/status/1205490572489830400?ref_src=twsrc%5Etfw">December 13, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
テキストエディタを開くときにできる一時ファイルを再帰的に削除するスクリプト

# はじめに
Linuxのエディタ(vim,emacs)などでは、デフォルトの設定だとファイルを開いたときに、バックアップ用として末尾に~(チルダ)がついたファイルが自動的に作成されます。

diffコマンド実行時に、チルダファイルが差分として出てしまい不便だったので、差分とならないように当該フォルダでチルダファイルを再帰的に削除するスクリプトを作成しました。

# 実行環境
- OS: CentOS 7.0

# 免責事項
スクリプトの実行は自己責任でお願いします。
このスクリプトを使って何らかの損害が発生しても、作者は責任を負いません。

# スクリプト
```rec_clean.sh
#!/bin/sh

function sub_func {

    \rm -f ${1}/*~
}

function rec {

    sub_func ${1}

    for FNAME in `ls ${1}`
    do
        local FPATH=${1}/${FNAME}

        if [ -d ${FPATH} ]; then
            rec ${FPATH}
        fi
    done
}

# main

rec `pwd`
```

# 使い方
実行したいディレクトリへ移動し、スクリプトを実行する。

```
$ cd 実行したいディレクトリ
$ ./rec_clean.sh
```

# 拡張案
sub_funcに対象コマンドを追加すれば、合わせて削除できます。
例えば、末尾に.bakが付いたファイルはsub_funcへ下記のコマンドを追加すれば実現できます。

```
 \rm -f ${1}/*.bak
```
glslでフィボナッチ数列

# 概要
glslでフィボナッチ数列を作る

フィボナッチ数列のアルゴリズムは山ほどありますが、
https://qiita.com/rana_kualu/items/49a60a4076e63ac6e399
現在は最適化された一般項があるのでそれを使います。

[wikipedia](https://ja.wikipedia.org/wiki/%E3%83%95%E3%82%A3%E3%83%9C%E3%83%8A%E3%83%83%E3%83%81%E6%95%B0)より

```glsl
const float SQRT_5 = sqrt(5.);
const float PHY    = (1.+SQRT_5)*.5;

float fib(float n){return sign(n)*floor(pow(PHY,abs(n))/SQRT_5+.5);}
```

※ wikipediaの負数対応は微妙だったので、最適化してます。

# フィボナッチ数列で円形グラデーション
美しい！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135381/bf3f8f3b-63f1-c0cb-c185-b8c1ce57df95.png)

```glsl
precision mediump float;
uniform vec2  m;       // mouse
uniform float t;       // time
uniform vec2  r;       // resolution
uniform sampler2D smp; // prev scene

const float SQRT_5 = sqrt(5.);
const float PHY    = (1.+SQRT_5)*.5;

float fib(float n){return sign(n)*floor(pow(PHY,abs(n))/SQRT_5+.5);}

void main(void){
	vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
	float c = fib(length(p)*15.)/600.;
	gl_FragColor = vec4(vec3(c), 1.0);
}
```
グロウしてもいいですね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135381/9aba32b2-bc46-8767-5427-4bd73f6a569b.png)

```glsl
precision mediump float;
uniform vec2  m;       // mouse
uniform float t;       // time
uniform vec2  r;       // resolution
uniform sampler2D smp; // prev scene

const float SQRT_5 = sqrt(5.);
const float PHY    = (1.+SQRT_5)*.5;

float fib(float n){return sign(n)*floor(pow(PHY,abs(n))/SQRT_5+.5);}

void main(void){
	vec2 p = (gl_FragCoord.xy * 2.0 - r) / min(r.x, r.y);
	float c = fib(length(p)*15.)/600.;
	gl_FragColor = vec4(vec3(.1/c), 1.0);
}
```
# 関連
* [フィボナッチで螺旋](https://www.shadertoy.com/view/3llGD7)
iPhoneで簡単３Dモデル作成

## この記事の目的
* AR開発の際に使う３Dモデルを手軽に安く作る方法の共有

## なぜ3Dモデルが必要となったのか
* 現在弊社では、ARの事業研究を行っていてその際に３Dモデルが必要になったため。
## なぜわざわさ３Dモデルを自作したのか？
* ARの開発を今後行って行くにあたり他の方が作成した３Dモデル以外のデータが必要になると思ったため

## なぜこのアプリを選んだのか
* iPhoneのみで完結出来る他のアプリが見つからなかったため

* 他にこんなアプリがあるよーというのがありました教えていただきたいです＞＜

## 必要な物
* iPhone
* プリンター

## 方法
* 公式サイトよりアプリをダウンロード

* URL:[Qlone, the all in one tool for 3D Scanning](https://www.qlone.pro/)

* アプリダウンロード後物体の位置を計測するためのシートを印刷する!
* 以下の２パターンの印刷用紙がある

![iOS の画像 (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267072/7d5f2625-6708-8406-607a-dc3764b35e7a.png)

![iOS の画像.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267072/d9e89c74-f642-f251-1e50-27e6df3c6b98.png)


* 上記の紙を印刷後以下の方法で簡単作成

* 動画URL:https://youtu.be/oT1keq4wUe4

## 使ってみて感じたこと
* ３Dモデル作成する際に、紙を回しながら作成していたのですがすぐ手でモデルが隠れてしまい３Dモデルが上手く作れないことがあったのでこれを自動化（床が自動で回るろくろ的なのがほしい…）したいところ
* この３Dモデル作成キットを買って試してみたいところ…
* ３DスキャナーURL:https://www.kickstarter.com/projects/kiriinnov/phiz-3d-scanner-on-smartphone-or-laptop?lang=ja
【AWS】EC2動きっぱなしで請求きたよのお話

#一度目の通達
11月中旬AWSからいきなり「もうすぐで設定していた金額超えるよ」というメールが携帯に飛んできた。
急いでAWSにログインし、確認するとEC2インスタンスの無料枠80%使用していた。
おー怖い怖いと思い、EC2インスタンス削除し安心しきっていた。
#二度目の通達
12月中旬またAWSから「もうすぐで設定していた金額超えるよ」というメールが携帯に飛んできた。
「ん？EC2インスタンスは止めたぞ」と思いbilldingを見に行くと、またEC2インスタンスの無料枠80%使用していた。さらには、先月分は8$請求が確定していた。
「え？」
そう思いEC2画面にいってもインスタンスはない。
EC2以外もcloud9など使用していたサービス全部を削除した。
これで安心しきっていた。
#次の日
次の日も念のためAWSを見に行くことに。
すると..EC2の利用時間が増えていやがる！！！！
#解決
どのサービスも使ってないのに...途方に暮れた私はカスタマーサポートに連絡することに。
すると「他のリージョンで使用していないですか？」とのこと
あ！！！！！！！！
そう。別のリージョンでインスタンスが立ち上がっていました。
それらすべて停止して万事休す。
#原因
今回の原因はリージョンの違いでしたが、なぜそのようなことが起きたのかというと
普段は東京リージョンを使っていたのですが、なにかのタイミングで北米リージョンに切り替わっていたことに気付かなかったことです。
なぜ変わったのかはわかりませんが、リージョンは常に確認しといたほうがいいかもしれません。
#まとめ
私と同じように「え！全サービス止めているのになんで！！！」となった方の参考になればと思います。
私はリージョンなんていじっていない！でも請求がくるという方はカスタマーサポートに連絡しましょう。無料で24時間対応してくれます。
ちなみにカスタマーサポートはできるなら電話したほうが早く対応してくれます。
pdfmakeの日本語対応

pdfmakeを使うとJSで簡単にPDFファイルを作成できますが、デフォルトのままだと日本語フォントに対応しておらず、文字化けが発生してしまいます。
pdfmakeを日本語フォントに対応させるためには、適当な日本語フォントを追加し、vts_fonts.jsを読み込ませる必要があります。

pdfmakeの基本的な使い方に関しては同じ会社のエンジニアの方が別の記事で書いているので、こちらを見てください。
→ [JavascriptでPDFを作成する](https://qiita.com/shuhei_sakiyama/items/ef68d49b7199d50a853b)


## pdfmakeのダウンロード
とりあえずpdfmakeをクローン。
クローンする場所は適当で大丈夫です。

```
git clone https://github.com/bpampuch/pdfmake.git
```

## pdfmakeに日本語フォントを追加する
今回は源真ゴシック（GenShinGothic-Normal.ttf）を使用します。
pdfmakeで使用するフォントは「pdfmake/examples/fonts」に入っているので、すでに入っているフォント（Roboto-Italic.ttf、Roboto-Medium.ttf、Roboto-MediumItalic.ttf、Roboto-Regular.ttf）を削除して、代わりにGenShinGothic-Normal.ttfを入れておきます。

## pdfmakeのフォント情報を更新
日本語フォントを追加したら、pdfmakeのフォント情報を更新します。

**① pdfmakeディレクトリに移動**

```
cd pdfmake
```
**② Node.jsモジュールを更新**

```
npm install
npm run build
```
ここでエラーが出る場合はnodeのバージョンが低い可能性があるので、nodeのバージョンを上げてみてください。

**③ フォントの更新**

```
gulp buildFonts
```
gulpを使うので、あらかじめgulpをインストールしておいてください。
ローカルのgulpを動かすためにグローバルにgulpがインストールされている必要があるみたいなので、グローバルにもgulpをインストールしておきます。

gulp buildFontsを実行すると「pdfmake/build/」に「vfs_fonts.js」がビルドされるので、これをpdfmakeに読み込ませれば日本語フォントに対応することができます。
JavaScriptで3Dを描画する際に使用するライブラリのサンプルを紹介[PlayCanvas]

# はじめに
PlayCanvasのバージョンが先日v1.24.2にアップデートされました。それにより公式examplesが拡充されましたので紹介します。



### PlayCanvasについて

PlayCanvasはGitHub ★5000↑のWebGL/ゲームエンジンのJavaScriptライブラリです。開発についてはPlayCanvas社がGitHub上でOSSとして開発しています。



https://github.com/playcanvas/engine

### PlayCanvasのサンプル集


いままでの公式サンプルと比べてかなり見やすくなりました。

![](https://i.imgur.com/JrYXi1W.png)


ソースに関しては、こちらの、GitHub Pagesがホストされています。

https://github.com/playcanvas/playcanvas.github.io


マテリアルの設定や
![](https://i.imgur.com/1947aa3.jpg)

ポストエフェクトを入れた際のサンプルなどもあります。
![](https://i.imgur.com/PAcmvXT.jpg)


#### サンプル集
https://playcanvas.github.io


#### その他 3Dライブラリのリンクも

Three.js

https://threejs.org/examples/#webgl_animation_cloth


Babylon.js

https://doc.babylonjs.com/examples/

<font color="OrangeRed">
PlayCanvas開発で参考になりそうな記事の一覧です。
</font>
<font color="OrangeRed">
入門

- [PlayCanvas入門- モデルの作成～ゲームに入れ込むまで](https://qiita.com/yushimatenjin/items/2a2c35fe7b1d08f9e361)
- [JavaScriptでスロットを実装する。【PlayCanvas】](https://qiita.com/yushimatenjin/items/e84c42da74df1eb07386)
- [3Dモデルのビューワーを3分で作る【初めてのPlayCanvas】](https://qiita.com/yushimatenjin/items/4b09c9e2076a0b2a6933)
</font>
<font color="OrangeRed">
応用
</font>

- [PlayCanvasのコードエディターでes6に対応する](https://qiita.com/yushimatenjin/items/a61a21c64c1c1a550dd4)
- [Gulpのプラグインを書いたらPlayCanvasでの開発がめちゃくちゃ便利になった](https://qiita.com/yushimatenjin/items/5f0f178e8a4ba4a5ee57)
- [PlayCanvas Editorに外部スクリプトを読み込む新機能が追加されたので開発方法を考える。- Reduxを組み込む](https://qiita.com/yushimatenjin/items/7a64220cceac66843d7d)
</font>
<font color="OrangeRed">
その他の記事はこちらになります。

- [React Native + PlayCanvasを使ってスマートフォンゲームを爆速で生み出す](https://qiita.com/yushimatenjin/items/7c7ad5d35473c11f32f2)
- [PlayCanvasのエディター上でHTML, CSSを組み込む方法](https://qiita.com/yushimatenjin/items/814b4a32db53397219df)
- [【iOS13】新しくなったWebVRの使い方 ](https://qiita.com/yushimatenjin/items/344d86b3d193e0a88567)
</font>

<font color="OrangeRed">
その他関連
- [PlayCanvasタグの付いた記事一覧](https://qiita.com/tags/playcanvas)
</font>


### PlayCanvasのユーザー会のSlackを作りました！
少しでも興味がありましたら、ユーザー同士で解決・PlayCanvasを推進するためのSlackを作りましたので、もしよろしければご参加ください！

[日本PlayCanvasユーザー会 - Slack](https://t.co/IdSRIfJhN5?amp=1)
RxSwiftのconcatMapはsubsequenceを得る処理自体を待つわけじゃない

## やりたいこと

非同期処理のトリガー `PublishRelay<Int>` によって、非同期処理 `Single<Int>` が行われる。
トリガーは非同期処理が終わる前にも叩かれうるが、前の非同期処理が終わるまで、次の処理は待機したい。

## 方針

- 非同期処理が同時に走らないようにしたい
    - つまり `flatMap` は使えない
- トリガーが叩かれた回数と同じ回数だけ非同期処理自体は行いたい
    - イベントを捨てる `flatMapFirst` `flatMapLatest` は使えない
- 処理順を制御するのに適切なoperatorは `concatMap`

## 悪い実装

```悪い実装.swift
func doSomething(_ i: Int) -> Single<Int> {
    print("start [\(i)]")
    return Single<Int>.just(1)
        .delay(.seconds(2), scheduler: MainScheduler.instance)
        .do(onSuccess: { _ in print("end [\(i)]") })
}

let trigger = PublishRelay<Int>()
_ = trigger
    .concatMap { doSomething($0) }
    .subscribe()

_ = Observable<Int>
    .interval(1, scheduler: MainScheduler.instance)
    .bind(to: trigger)
```

```期待.log
start [0]
end [0]
start [1]
end [1]
start [2]
end [2]
...
```

```実際.log
start [0]
start [1]
start [2]
end [0]
start [3]
start [4]
end [1]
...
```

## 何が悪いか

RxSwiftの `concatMap` は、
❌️前のsubsequenceがcompleteするまで**subsequenceを得るselectorの実行を**待つ
⭕️selectorによって得られたsubsequenceの**subscribeを**待つ

```適切な実装.diff
 func doSomething(_ i: Int) -> Single<Int> {
+    Single.just(()).flatMap {
         print("start [\(i)]")
         return Single<Int>.just(1)
             .delay(.seconds(2), scheduler: MainScheduler.instance)
             .do(onSuccess: { _ in print("end [\(i)]") })
+    }
 }

 _ = trigger
     .concatMap { doSomething($0) }
     .subscribe()
```

```結果.log
start [0]
end [0]
start [1]
end [1]
start [2]
end [2]
...
```

## 結論

`concatMap` に限った話ではなく、「ストリームを作る」と「ストリームが購読・実行される」のタイミングの違いは意識しましょうねという話に一般化できます。
foreachの中身だけ違う関数が複数ある場合の共通化

```php

<?php
class SomeForeach
{
  const SOME_LIST = [
    ['key'=>1],
    ['key'=>3],
    ['key'=>5],
    ['key'=>7]];

  public static function newList()
  {
    $returnList = [];
    foreach(self::SOME_LIST as $v) {
      $returnList[] = $v['key'];
    }
    return $returnList;
  }

  public static function newList2()
  {
    $returnList = [];
    foreach(self::SOME_LIST as $v) {
      $returnList[] = $v;
    }
    return $returnList;
  }
}

var_dump(SomeForeach::newList());
var_dump(SomeForeach::newList2());

class SomeForeach2
{
  const SOME_LIST = [
    ['key'=>1],
    ['key'=>3],
    ['key'=>5],
    ['key'=>7]];

  public static function newList()
  {
    return self::common(function($v) {return $v['key'];});
  }

  public static function newList2()
  {
    return self::common(function($v) {return $v;});
  }

  private static function common(callable $callback)
  {
    $returnList = [];
    foreach(self::SOME_LIST as $v) {
      $returnList[] = $callback($v);
    }
    return $returnList;
  }
}

var_dump(SomeForeach2::newList());
var_dump(SomeForeach2::newList2());
```
【WordPress】カスタム投稿タイプでコラム記事を作る

この記事は[MAMPを使って手軽にWordPress環境を構築する方法](https://qiita.com/TakumiIt0/items/7f07a080c460d6f890a9)の続編です

「ブログを運営する」と一口に言っても、
時にはSEO対策としてユーザーに役立つコラムやブログ記事をWordPressのデフォルトで備わっている通常の投稿口とは別で用意したい場面もあるのではないでしょうか。
今回は、そんな時に役立つ「カスタム投稿タイプ」を使用してコラム記事を投稿できる状態にしていきたいと思います。
※ デザインは特に用意していないのでコラム記事の体で進めていきます

#カスタム投稿タイプとは
WordPressで記事投稿をする際は「投稿」から記事を投稿しますが、これが通常の投稿タイプです。
これだけだと投稿口が一つですが、別で任意の投稿タイプのコンテンツを作成することができます。
それを「カスタム投稿タイプ」と呼びます。

#カスタム投稿タイプの作り方
作り方は2種類あります。
1つ目は「プラグイン」の導入
2つ目は「テンプレートファイル」に記述を追加
です。

#実際に作ってみる
今回は、
/Users/ユーザー名/Desktop/qiita/wp/wp-content/themes/テーマ名/functions.php
に記述を追加して実際に作っていきたいと思います。

```php
/**
 * カスタム投稿タイプ
 */
function create_post_type_column() {
  $Supports = [
    'title',
    'editor',
    'thumbnail',
  ];
  register_post_type( 'column',
    array(
      'label' => 'コラム',
      'labels' => array(
      'all_items' => 'コラム一覧'
      ),
      'public' => true,
      'has_archive' => true,
      'menu_position' => 5,
      'supports' => $Supports
    )
  );
}
add_action( 'init', 'create_post_type_column' );
```

こちらを丸ごと追加すると以下の画像の赤枠のように
「コラム」が追加されるかと思います。

![img01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229249/bdae1266-99de-452e-4fb0-6b118bfbdb07.png)


実際にコラムの投稿口から新規で記事を投稿してみましょう。
記事の投稿が確認できたら完了です。

#表示されない...
パーマリンクを表示してもnotfoundになる場合は、「パーマリンク設定」を見直してみましょう。
共通設定の「基本」にチェックを入れてもおそらく表示されますが、今回は
![img02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229249/1018f072-3215-cbd0-f4ac-d12b2441fe18.png)
こちらの画像の赤枠内と同じ形にしておいてください。
次回以降の記事で重要になります。

#最後に
一連の流れが問題なく完了したら、なんとなくは理解できたと思うのでソースの関数内で何をしているのかなどは興味があれば調べてみるといいかもしれません。

ただ、このままだと「別の投稿口から投稿できるだけ」なので
次回は[コラムに階層構造（3階層）を持たせてパーマリンクを整える](https://qiita.com/TakumiIt0/items/e7ac318c45565d762961)を書いていきます。
SwaggerでAPI仕様を管理したらめちゃくちゃ便利だった

この記事は[フォトクリエイト Advent Calendar 2019](https://qiita.com/advent-calendar/2019/photocreate) 22日目の記事です。
本記事はフロントエンドエンジニアの私@ttmd と @ysap2 さんが共同で執筆しています。

# はじめに
2019年8月29日(木)にリニューアルした[スナップスナップ](https://snapsnap.jp/)のAPI設計でSwaggerを導入した結果、サーバーサイドエンジニア、フロントエンドエンジニア双方が幸せになったので、その事例を紹介します。

# これまでのAPI設計

API開発者がスプレッドシートに仕様を書き込み、Schemaの相談をフロントエンドエンジニア・サーバーサイドエンジニアが口頭で密にコミュニケーションをとり実装を進めていました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553084/847a7e43-a920-8f68-0b2b-315dbcf2f8f2.png)


この運用を続けていて

- API仕様の決める際、オフラインでのエンジニア間のやりとりが多くなってしまう
- 通常の開発フローでスプレッドシートを触ることがなく、わざわざシートを更新することが面倒に感じる
- サーバーサイドがAPIを作るまではフロントエンドも開発ができない（時間的な制約が出来てしまう）

といったコストの高さや運用のし辛さを感じていました。
# APISpec管理ツール導入
前述の課題をクリアするべく[Swagger](https://swagger.io/)の導入に至りました。

## Swaggerについて
REST APIを定義するためのオープンソースフレームワークです。
サードパーティ製のツールも豊富にあります。
弊社では[Swagger UI](https://swagger.io/tools/swagger-ui/)も採用。

##Swagger Specの記述
記述には[OpenAPI Initiative](https://www.openapis.org/)の定める[OpenAPI Specification v3.0](https://swagger.io/specification/)のフォーマットを利用します。
慣れない書き方なので、学習コストは発生しますがメリットのほうが大きいです。

# Swaggerを使って良くなったこと
## ドキュメントが見易くなった
SwaggerUI を導入した結果、スプレッドシートと比較すると格段に見やすいドキュメントになりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/553084/f04c1a8f-cd10-899f-5468-dd753094fcff.png)
※上のイメージはサンプルのため[petstore.swagger.io](http://petstore.swagger.io/)から引用しています。

SwaggerUIはローカルから環境を立ち上げて確認することもできますが、Dockerを用いて社内の環境にホストすればローカルに環境構築ができていないメンバーに共有することも可能です。
他にもUI上で必要なパラメータを入力してAPIを呼び出せ、そのレスポンスを確認することができるという点も素晴らしかったです。

## API設計がバージョン管理できるようになった

今回のSwagger運用を進めるにあたり、APISpecのみのGit Repositoryを作成しました。
Git管理に切り替わったことでAPI設計がバージョン管理されたドキュメントとして残せるメリットもありました。

## エンジニア間の認識の齟齬を無くせた
ドキュメント生成系ツールで運用する際、更新のし忘れで実装したコードに齟齬があり修正に余計な工数がかかることがありました。

導入後はAPI設計のプルリクエストの承認にフロントエンドエンジニアとサーバーサイドエンジニアそれぞれ1名以上のApprovementを必須にすることで、安全なAPI設計を行えました。

## バックエンドの実装を待たずにフロントの実装が進められた
Swaggerを活用したモックサーバーを活用することで、バックエンドの進捗を気にせずフロントエンドの実装を進めることができました。

## TypeScriptの型定義が楽になった
APIのリクエストデータやレスポンスデータなど、TypeScriptの型定義に苦労していました。
snapsnapチームではSwaggerと連携できるnode moduleを活用し、APIに紐づいた型定義の生成を自動化することができました。

# さいごに
今回Swaggerの具体的な導入方法は紹介していませんが
気になった方は[公式ページ](https://swagger.io/)をご覧になってください。

フォトクリエイト社では共に働くエンジニアを募集しております。
日々急速な進化を続けているweb業界で、サービスの成長に最適な技術を導入していきます。
挑戦する姿勢にとても寛容な環境ですので
少しでもご興味をお持ちいただけたようでしたら、人事部門の担当者 [twitter: @tetsunosuke](https://twitter.com/tetsunosuke) へお知らせください。