OmniAICreator/Qiita-1.07M huggingface dataset:
Oracle CloudとAWSの機能名対応表（ネットワーク編）

# 概要

Oracle CloudとAWSの機能名の対応表（ネットワーク編）をまとめました。
さまざまなクラウドがある中で特定のクラウドに囚われず、用途に合わせて使い分けていくこともあるかと思います。
その際に各クラウドの機能名の対応表があると理解が進みやすくなるかと思います。

# ネットワーク編

※以下の備考はOracle Cloud視点で記載しています

|Oracle Cloud|AWS|備考|
|:---|:---|---|
|Availability Domain(AD)|Availability Zone(AZ)||
|Virtual Cloud Network(VNC)|Virtual Private Cloud(VPC)||
|ルート表|ルートテーブル||
|インターネットゲートウエイ|インターネットゲートウエイ||
|NATゲートウエイ|NATゲートウエイ||
|フォルト・ドメイン(FD)|-|DC内のハードウェアやインフラの冗長構成<br/>AWSにはこの仕組みはない|
|ネットワーク・セキュリティ・グループ|・セキュリティグループ<br/>・ネットワークACL|・NIC単位にも適用できるファイアウオール<br/>・AWSのセキュリティグループ名での通信許可はここで設定できる<br/>・ステートレスな設定も可能|
|セキュリティ・リスト|・セキュリティグループ<br/>・ネットワークACL|・サブネット単位に適用できるファイアウォール<br/>・ステートレスの設定も可能|
|動的ルーティング・ゲートウエイ|・VPゲートウエイ<br/>・VPCペアリング接続（リージョン間）|リージョン間の通信も動的ルーティング・ゲートウエイを通じて通信をする|
|サービス・ゲートウエイ|VPCエンドポイント||
|ローカル・ピアリング・ゲートウエイ|VPCペアリング接続|同一リージョンのみの疎通|
|FastConnect|AWS Direct Connect||


上記以外の機能やAzure、Googleも含めた対応表もありますので、下記をご覧ください
https://cloud.oracle.com/en_US/iaas/cloud-service-mapping
Commit log や Pull Request を close すると Issue も close する

Issue 駆動開発をしている時に、Commit や Pull Request が Close されたら元の Issue も close したい時がある。

公式には https://help.github.com/en/articles/closing-issues-using-keywords に述べられているが、Commit message や pull request の本文などに Fix `issue URL` or `Issue #` を記載しておけばよい。

下記の動詞の直後に `Issue URL` あるいは `Issue #` を記載する。
close
closes
closed
fix
fixes
fixed
resolve
resolves
resolved

# 例
- `This closes #34, closes #23, and closes example_user/example_repo#42 .`
- 同じレポジトリの 34, 23 及び example_user/example_repo の 42 の Issue を close する
Docker上でSelenium WebDriver が動かない

# 概要
C#で回帰テストを書こうとしたら、詰んだ。

ローカルで詰んだ際は以下で回避した。
[SeleniumがCannot start the driver service on http://localhost:${port} を吐いて死ぬ](https://qiita.com/taito-ITO/items/9f766db5b782b809716d
)

が、今度コンテナ上で動かそうと思ったら同じエラーで再度詰んだ。しかも解決できぬというおまけ付き。

なお、多分プロキシさんのせいです。

# 前提
macOS High Sierra
Docker for Mac
dotnet core 2.2.202

# 実行したいソース

```C#
    var options = new ChromeOptions();
    options.AddArgument(UserAgent);
    options.AddArgument("--headless");

    using (var chrome = new ChromeDriver("ドライバーのパス", options))
    {
        chrome.Url = "対象";
                
        // なにがし
    }
```


# やってみる
ひとつのコンテナで解決しようとしたが無理っぽかったので別にSeleniumサーバーたてることでなんとかなるような気がした

https://github.com/SeleniumHQ/docker-selenium
こちらよりDockerファイルを拝借して、imageを作成。

StandaloneChromeDebugで作成することにしました

```bash
docker build -t chromedebug:1.0 .
```

テストを実行するコンテナ用dockerfile

```dockerfile

ROM mcr.microsoft.com/dotnet/core/sdk:2.2 AS build

WORKDIR # よしなに指定
COPY # ソースを入れる
RUN dotnet restore
```

とりあえずtestイメージとして放置

```bash
docker build -t test:1.0 .
```

でdocker-compose.ymlを書いてみる

```yml
version: '3.7'
services:

  selenium:
    image: chromedebug:1.0
    container_name: selenium
    restart: always
    ports:
      - "4444::4444"

  test:
    image: test:1.0
    container_name: test 
    restart: always
    command: "tail -f /dev/null"
    depends_on:
      - selenium
```

実行

```bash
docker-compose up -d
docker exec dotnet test
```

# ダメでした
ソースも変えましょう
せっかくselenium立てたのに指定すんの忘れてました。以下のように編集します

```C#
    var options = new ChromeOptions();
    options.AddArgument(UserAgent);
    options.AddArgument("--headless");

    // docker-compose.yml で立てたseleniumサーバ
    var uri = new Uri("http://selenium:4444/wd/hub/");

    using (var driver = new RemoteWebDriver(uri, options))
    {
        chrome.Url = "対象";
                
        // なにがし
    }

```

# できました

```bash
docker-compose up -d
docker exec dotnet test
```

これで問題なく実行できました

# まとめ
- 別にサーバ（コンテナ）たてれば動く
- ぶっちゃけこんなことしなくてもプロキシさんさえいなければ普通に動く気もする
深層学習（後編 2）：「終了テスト」

講義やテキストであまり具体的に触れられていない領域の理解が足りず、そこで間違いが多く発生していた。以下主要な間違ポイントを整理する。
ResNet
残差ブロックでは、畳み込み層とSkip Connection層の組み合わせ構造となっており残差写像関数にIdentify関数を加えた値を数式として使用する。
R-CNN
物体候補領域画像をリサイジングして使用する。
FCN
ネットワーク全体が畳み込み層のみで構成されている。
VAE
VAEは事後分布へ近似させる
ニュートン法
ニュートン法では勾配降下法より少ない回数で収束するが、ヘッセ行列の逆行列を繰り返し計算する必要があるため計算コストが高い。
共役勾配法
共役勾配法はニュートン法と比べて計算コストが低いが、勾配降下法と比べて収束が早い
ハイパーパラメータの探索
ハイパーパラメータの探索方法として、グリッドサーチ、ランダムサーチ、ベイズ最適化がある。
マージ済みリモートブランチ一括削除しようとしたらpermission denied

# はじめに
マージ済みリモートブランチを一括削除しようとした時に権限エラーで実行できなったので
対処内容を備忘録としてまとめました。

結局のところリモートリポジトリへのアクセス権限がないので鍵を登録すればOK。

# 環境
Windows 10
SourceTree Version 3.1.3
SourceTree上のターミナルから実行します。
# エラー内容
リモートブランチ一括削除を実行

```bash

$ git branch -r --merged master | grep -v -e master -e develop | sed -e 's% *origin/%%' | xargs -I% git push --delete origin %
```
上記コマンドを実行するとエラーが発生

```bash

git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

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

# 解消手順

#### 1. 鍵を作成

3つの質問はそのままEnterでも大丈夫です
-C オプションはなくても大丈夫です

```bash
# 鍵を作成する。 (メールアドレスはgitアカウントのメールアドレス)
$ ssh-keygen -t rsa -C xxx@xxx.com
Enter file in which to save the key (/c/Users/（ユーザー名）/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
```


```bash
# id_rsa.pubを開いて公開鍵をコピー  
$ less ~/.ssh/id_rsa.pub
```
#### 2. githubに公開鍵を登録する
#### 3. 接続確認
githubに公開鍵を登録すれば設定完了だが一応確認

```bash
$ ssh -T git@github.com
Hi (account名)! You've successfully authenticated, but GitHub does not provide shell access.
```
`Hi (account名)!...` で返ってきたら正常に接続できているので再度一括削除を実行

# 参考リンク
- [【git エラー解決策】Permission denied (publickey). fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists. が出た時の解決方法](http://tusukuru.hatenablog.com/entry/2018/08/29/021651)
- [GitHubでssh接続する手順~公開鍵・秘密鍵の生成から~](https://qiita.com/qwertytoki/items/6c5bde142b25293cd6d2)
- [gitでマージ済みの(リモート|ローカル)ブランチを全て削除](https://gist.github.com/miukoba/fc3c10a25c1c675c1e97)
プロキシ下のWindowsでhyper-pokemonする

# どうしてもhyper-pokemonしたい!
Windows環境で、Terminalアプリを探していたところ[Hyper™](https://hyper.is/)と言うTerminalを発見した。
さらにHyperをピカチュウ仕様にする[hyper-pokemon-plugin](https://github.com/klauscfhq/hyper-pokemon)まであるらしい😊

早速Hyperをインストールしてプラグインを有効にしようとしたら、いつも邪魔するアイツ・・・そうプロキシサーバーに阻止された。いつものことですが、軽く絶望します。


```powershell
PS C:\Users\xxxxxx> hyper i hyper-pokemon
connect ECONNREFUSED xxx.xxx.xxx.xxx:443
Plugin check failed. Check your internet connection or retry later.
```

どうしてもピカチュウにしたかったので、頑張ってインストールしてみました😀

# npmを利用できるようにしてチャレンジ
調査したところ、すでに解決されている方がいた。
どうやら、hyperは内部でnpmコマンドを呼んでいるらしいとの情報があり、プロキシの設定ができるとのこと。
すぐにNode.jsをインストール。

* [HyperターミナルをWindows環境に導入した時にハマった話](https://qiita.com/keigo0502/items/b3707c6e3e89b0f804a4)
* [Node.js / npmをインストールする（for Windows）](https://qiita.com/taiponrock/items/9001ae194571feb63a5e)

参考にさせていただき、プロキシの設定をして・・・

```powershell
npm config set proxy "http://[プロキシ]サーバ:[ポート]"
npm config set https-proxy "http://[プロキシ]サーバ:[ポート]"
npm config set registry "https://registry.npmjs.org/"
```


再度、hyperコマンドを叩くも。。。相変わらずプロキシの壁は高し😫

```powershell
PS C:\Users\xxxxxx> hyper i hyper-pokemon
connect ECONNREFUSED xxx.xxx.xxx.xxx:443
Plugin check failed. Check your internet connection or retry later.
```

# npmコマンドでインストールする
少々途方に暮れていたが、[npmリポジトリ](https://www.npmjs.com/package/hyper-pokemon)でhyper-pokemonは公開されているので、試しにnpmコマンドでhyper-pokemonをインストールしたら、あっさりインストールできた。
hyperコマンドは動かないが、npmコマンドはちゃんとプロキシを越えてくれた😲

```powershell
PS C:\Users\xxxxxx> npm install hyper-pokemon

+ hyper-pokemon@0.4.6
added 11 packages from 15 contributors and audited 12 packages in 7.819s
found 0 vulnerabilities
```

なお、この後hyperを立ち上げてもやっぱりポケモンとはならなかった・・・
ちゃんとプレグインディレクトリにインストールしないといけない。

プラグインのフォルダは。
[hyper公式サイト](https://hyper.is/)のExtensionsにパスが書いてあったのでやってみたらできた。
``` $Env:AppData/Hyper/.hyper_plugins. ```

```powershell
PS C:\Users\xxxxx\AppData\Roaming\Hyper\.hyper_plugins>> npm install hyper-pokemon

+ hyper-pokemon@0.4.6
added 11 packages from 15 contributors and audited 12 packages in 6.112s
found 0 vulnerabilities
```

この後、.hyper.jsを修正して、プラグインを読み込むようにしたら動きました:relaxed:
なお、最初の起動時に選ばれたポケモンは・・・ヤドンでした・・・少しかなしい:imp:

# 参考にしたサイト
* [klaussinani/hyper-pokemon: Tailor-made Pokémon themes for your Hyper terminal](https://github.com/klauscfhq/hyper-pokemon)
* [hyper-pokemon  -  npm](https://www.npmjs.com/package/hyper-pokemon)
* [HyperターミナルをWindows環境に導入した時にハマった話](https://qiita.com/keigo0502/items/b3707c6e3e89b0f804a4)
* [Node.js / npmをインストールする（for Windows）](https://qiita.com/taiponrock/items/9001ae194571feb63a5e)
macでルーティングテーブルを確認

同一セグメントへの通信はできるが，他セグメントへの通信ができないといった不具合が発生した際にmacでルーティングテーブルの確認方法。下は結論だけ。

``` bash
$ netstat -rn

Internet:
Destination        Gateway            Flags        Netif Expire
default            192.168.1.1        UGSc           en0
127                127.0.0.1          UCS            lo0
127.0.0.1          127.0.0.1          UH             lo0
169.254            link#6             UCS            en0      !
192.168.1          link#6             UCS            en0      !
192.168.1.1/32     link#6             UCS            en0      !
192.168.1.174/32   link#6             UCS            en0      !
224.0.0/4          link#6             UmCS           en0      !
255.255.255.255/32 link#6             UCS            en0      !
```

オプションをつけているが詳細については下記

-r : ルーティング・テーブルに関する情報を表示する
-n : ホスト名，ポート番号，ユーザー名などを名前解決せずに表示する

|項目|概要|
|---|----|
|Destination|宛先IPアドレス|
|Gateway|ゲートウェイIPアドレス|
|Flags|フラグ|
|Netif|インターフェイス|
|Expire|

「宛先IPアドレス」が、それぞれのサブネットにおける経路
サブネット形式で記載されているものもある。
複数にマッチするさいはロンゲストマッチの法則に従いパケットを転送します。
ロンゲストマッチとはパケットを転送するための宛先ネットワークがルーティングテーブルに複数ある時、宛先ネットワークのアドレスビットが最も長く一致する宛先ルートをパケットの転送先として選択するルール

フラグについて

|フラグ名|概要|
|------|---|
A|アクティブ・デッド・ゲートウェイ検出が経路で使用可能である
U|稼働中
H|経路はネットワークではなくホストを宛先にしている
G|経路はゲートウェイを宛先にしている
D|経路がリダイレクトによって動的に作成されている
M|経路がリダイレクトによって変更されている
L|リンク・レベル・アドレスが経路エントリーの中にある
c|この経路へのアクセスはクローン経路を作成する
W|経路はクローン経路である
1|プロトコル固有経路指定フラグ #1
2|プロトコル固有経路指定フラグ #2
3|プロトコル固有経路指定フラグ #3
b|経路はブロードキャスト・アドレスを表す
e|バインディング・キャッシュ・エントリーを使用している
l|経路はローカル・アドレスを表す
m|経路はマルチキャスト・アドレスを表す
P|ピン固定経路
R|ホストまたはネットワークに到達できない
S|手動で追加
u|経路は使用可能

## 参考

https://www.infraexpert.com/study/routing.html
https://www.ibm.com/support/knowledgecenter/ja/POWER7/p7hcg/netstat.htm
Coral USBアクセラレータを始めよう

Coral USB Acceleratorは、Edge TPUをコンピュータのコプロセッサとして提供するUSBデバイスです。 Linuxホストコンピュータに接続すると、機械学習モデルの推論が高速化されます。

このページは始めるためのあなたのガイドです。 USBアクセラレータを接続するホストコンピュータに、Edge TPUランタイムとPythonライブラリをダウンロードするだけです。 その後、TensorFlow Liteモデルの実行を開始できます。

![微信图片_20190531135204.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/04d1952e-c8ba-a45d-55ed-49236e1b7582.jpeg)

> `USB Acceleratorはこちらから購入できます:  https://store.gravitylink.com `

####必要条件
USBポートを備えたすべてのLinuxコンピュータ
- Debian 6.0以降、またはその派生物（Ubuntu 10.0以降など）
- ARMv8命令セットを使用したx86-64またはARM32 / 64のシステムアーキテクチャ
はい、これはRaspberry Piがサポートされていることを意味します。 ただし、Raspbianを実行しているRaspberry Pi 2/3 Model B / B +のみが正式にサポートされています。 非公式には、Raspberry Pi Zeroもサポートされています（以下のものの代わりに、GitHubからTARをPi Zeroにインストールしてください）。

推論速度を最高にするにはUSB 3.0ポートを使用する必要があることにも注意してください（残念ながら、Raspberry PiにはUSB 2.0ポートしかありませんが、それでも機能します）。

###LinuxまたはRaspberry Piにセットアップする

はじめに、USBアクセラレータに接続するLinuxマシンまたはRaspberry Piで以下の手順を実行してください。

1. Edge TPUランタイムとPythonライブラリをインストールします。

``` 
cd ~/

wget https://dl.google.com/coral/edgetpu_api/edgetpu_api_latest.tar.gz -O edgetpu_api.tar.gz --trust-server-names

tar xzf edgetpu_api.tar.gz

cd edgetpu_api

bash ./install.sh
```

注意：インストール中に、「最大動作周波数を有効にしますか？」という質問が表示されます。 このオプションを有効にすると推論速度は向上しますが、操作中にUSBアクセラレータが非常に熱くなり、やけどをする可能性があります。 パフォーマンスを向上させる必要があるかどうかわからない場合は、Nを入力してEnterキーを押し、デフォルトの動作周波数を使用します。 （インストールスクリプトを再実行するだけで後で変更できます。）

2.付属のUSB 3.0ケーブルを使用してアクセラレータを接続します。 （すでに接続している場合は、削除してから再接続すると、インストールされたばかりのudevルールが有効になります。）

#### Edge TPUでモデルを実行する

USBアクセラレータがセットアップされたので、Edge TPUでTensorFlow Liteモデルの実行を開始できます。 これらの手順に従って、コンパイル済みのモデルとサンプルスクリプトを使用して画像分類を実行します。

まず、鳥の分類モデル、ラベルファイル、写真をダウンロードします。

```
cd ~/Downloads/

wget https://dl.google.com/coral/canned_models/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
https://dl.google.com/coral/canned_models/inat_bird_labels.txt \
https://coral.withgoogle.com/static/docs/images/parrot.jpg
```
サンプルスクリプトを共有したディレクトリに移動し、オウムの画像を使って画像分類を実行します（図1を参照）.

![parrot.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/95462b1a-27cf-fee9-975b-4e5e39123219.jpeg)

```
# on Debian/Ubuntu Linux:
cd /usr/local/lib/python3.6/dist-packages/edgetpu/demo

# on Raspberry Pi:
cd /usr/local/lib/python3.5/dist-packages/edgetpu/demo

python3 classify_image.py \
--model ~/Downloads/mobilenet_v2_1.0_224_inat_bird_quant_edgetpu.tflite \
--label ~/Downloads/inat_bird_labels.txt \
--image ~/Downloads/parrot.jpg
```

あなたはこのような結果を見るはずです：

```
---------------------------
Ara macao (Scarlet Macaw)
Score :  0.761719
```

おめでとうございます。 Edge TPUで推論を実行しました。

このデモでは、Edge TPUで画像分類やオブジェクト検出の推論を簡単に実行できるように作成したPython APIを使用します。
MacOSをアップデートしたらGitでエラーが発生した

## VSCodeでエラー発生

VSCodeでGitを使おうと思ったら、エラーが表示されていました。

```
Git not found. Install it or configure it using the 'git.path' setting.
```

Gitが見つからないらしいですが、以前から使用できていたのでおかしい。
下記のコマンドで実行できるか試してみると、新たなエラーが表示されました。

```shell-session
$ git --version
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```

## エラーの対応

調べてみると、MacOSをアップデートした後に発生するエラーのようです。
下記の記事を参考にxcodeをインストールだけでエラーがなくなりました！
[High Sierraへアップデート後のgitエラー](https://qiita.com/tmf16/items/046cdcc5aaa36a3e76d7)

xcodeをインストール。

```shell-session
$ xcode-select --install
```

インストールが完了したらgitを確認。

```shell-session
$ git --version
git version 2.20.1 (Apple Git-117)
```

## 終わりに

xcodeは以前から使用していなかったんですが、なぜエラーが起きたのか謎です。。。
Pythonの自作モジュールをimportしたいならsys.pathを設定しよう

本記事は下記の続編です。しかし、読んでいなくても差し支えありません。
[【日記】Pythonで上位階層のモジュールを力技によりimportさせたい](https://qiita.com/Anaakikutsushit/items/f469e6883ee066c66f49)

かつて`__init__.py`と相対インポートによってモジュールをimport出来ていたかに見えた私のPythonスクリプト。
しかしその後、実行する環境とか設定とかによって上手くいったり行かなかったりするのでした。

---

モジュールの別のインポート方法が無いかなあと探していたところ、`sys.path`なるパラメータにパスを格納すればいいことが判明。
しかもこれは、スクリプト内から追加することで開発環境をヘンにいじくり回さずに実現できることも判明。私には嬉しい仕様です✨

私のプロジェクトは次のような構成をしております。

```ディレクトリ構成.
(ルート)
├─code
│  │  main_system.py
│  │
│  ├─library
│  │  ├─analyzers
│  │  │  ├─main_process
│  │  │  │  │  identify_gears_name.py
(その他 省略)
```

**`main_system.py`から`identify_gears_name.py`を呼びたい！予備隊！**
そう思ったならば、main_system.pyに次の記述を入れましょう。

```main_system.py
import sys
sys.path.append('code/library/analyzers/main_process')
import identify_gears_name

# 以下 コード
# identify_gears_name.hogeのようにしてメンバを呼び出せる
```

なんとこれだけ！カンタン！
私のIDEだと`Unable to import 'import_image'`だとか`Import "import import_image" should be placed at the top of the module`というpylintが出てきて少し鬱陶しいのですが、問題なくimportしてスクリプトを実行できます。
もっと早くこの方法でやればよかった！
おしまい
UnderstandAPI(python)を使うためのチュートリアル

#Understandってなんですか？
Understandはソースコード解析ソフトです。
大規模だったり~~誰も手を付けたくないような~~複雑なソースコードを解析して、制御フローを把握するのに便利です。
https://www.techmatrix.co.jp/product/understand/

#前提
前提とする環境は
- Windows10
- Understandインストール済み
になります。

#はじめに
まず、最初にpythonとVSCodeのインストールを行います。
https://qiita.com/aki34/items/6d5e4f5d6036b9bcd63e

**注意点**
Understandのdllが64bit版しかないため、Pythonは32bitではなく64bitを選ぶ必要があります。
pythonのHP上部のダウンロードのタブからWindowsを選択し、64bitのインストーラーをダウンロードしてください。
Versionは3.7.4になります。
web-baseとexecutableはどちらでも良いです。

また、VSCodeの自動整形機能を有効にするとかなり快適に作業ができますので時間があれば設定しておくことをオススメします。
https://qiita.com/psychoroid/items/2c2acc06c900d2c0c8cb

#Understandのdllについて
各種インストールが終わったらUnderstandのdllが使用できるようにdllのコピーを行います。
Understandのインストールフォルダを仮に%Understand%
pythonのインストールフォルダを仮に%python%
とします。

%Understand%\bin\python\
にunderstand.pydがありますのでそれをコピーし
%python%\dll\
に張り付けます。

これで基本的には動作します。

#PyQt5について
一部のAPIではQtをしようするものがありますので、そちらのインストールも行います。
VSCodeのコンソール上で
`pip install PyQt5`
と入力することでインストールが行われます。
インストールが終わったら環境変数を設定します。

環境変数：QT_QPA_PLATFORM_PLUGIN_PATH
パス：%python%\Lib\site-packages\PyQt5\Qt\plugins\platforms

#おわりに
何か不明点や足りない部分がありましたらご指摘お願いします。

#参考
https://github.com/pyqt/python-qt5/issues/2
手順書サンプル

##H2見出し
こんな感じで見出しも入れられます。
 
*イタリック体*や**太字**なんかも簡単。
 
>引用なんかも
>簡単に入れられます
 
非順序リスト
 
+ リストアイテム1
+ リストアイテム2
+ リストアイテム3
 
順序リスト
 
1. リストアイテム1
2. リストアイテム2
3. リストアイテム3
 
テーブル
 
| Left align | Right align | Center align |
|:-----------|------------:|:------------:|
| This       |        This |     This     |
| column     |      column |    column    |
| will       |        will |     will     |
| be         |          be |      be      |
| left       |       right |    center    |
| aligned    |     aligned |   aligned    |
python エラー (hackerrank day1)

hackerrankを解いている最中に躓いてしまった箇所があったので、まとめておこうと思います。

##データの型変換
pythonは変数を定義する時、必ずintやfloatなどで型変換する必要があるわけではありません。
しかしprintなどで出力する際はきちんとデータ型を一緒にしないといけないのです。

・float：数字を少数点まで出力したいときに使う。

・int：数字を小数点まで出す必要がないときに使う。

・str：文字列を出力する時に使う。
""で囲んでいる文字列に数字を入れたい場合はstr(数字の変数)というように使う。

##input()を使うと文字列のデータ型になる
これはどういう意味かというと、

```
e = input()
d = input()

print(e + d)
```
これでeに100、dに50を入れたとしても、データ型が文字列になって出力されなくなります。
この際はint(input())と記述して、変数を定義する時にint型で定義すると解決できます。

以上になります。
何か間違いや指摘があればお願いします。




even：偶数
variable：変数
ZabbixでOCI Dbaas監視 - SQLで監視項目の取得

SQLを作成しOCI Dbaasの情報を取得して、Zabbixで表示させる設定。

## 前提
 - 対象ノードで[ZabbixでOCI Dbaas監視 - エージェント設定](https://qiita.com/y-araki-qiita/items/f25e02182c7f279c0199)が完了していること。
 - 手順はASMのデータ使用率を取得する例(上記リンクの手順でインポートするZabbixテンプレートには既にASM使用率の監視アイテムが含まれています)。  

ASMについて: ociのDbaaSは、ASM(Oracle Automatic Storage Management)という技術が使われており、ストレージ管理に使用されています。データファイルや、RedoログファイルなどASMに格納されているため、使用率など監視する必要があります。


## SQLの配置

### zabbixエージェント (ノード) にログイン。

### SQLの作成、配置
以下pathに監視情報を取得するSQL配置する。SQLファイル名は任意で、ここではdb_asmdata.sqlとする。

```
# vi /etc/zabbix/scripts/agentd/zabbix-oci-dbaas/sql/db_asmdata.sql
```

### 監視情報取得のSQLについて
以下templateで"SQL文を記載"の箇所に、監視したい情報を取得するSQLを記載する。
・取得したい値のみが表示されるSQLにすること (SET～ で書式部分を非表示、where句で値をひとつに絞ること)。
・値は整数、浮動小数点、文字列等どれでもよいが、zabbixの監視アイテム設定時にデータ型を合わせること。
・最後にQUIT;を必ず記載する。でないと実行エラーとなる。

### template
```sql
SET pagesize 0
SET heading OFF
SET feedback OFF
SET verify OFF

"SQL文を記載"

QUIT;
```

### templateをもとに、ASMのデータ使用率取得SQLを作成  (db_asmdata.sql)
```sql
SET pagesize 0
SET heading OFF
SET feedback OFF
SET verify OFF

SELECT
ROUND(((total_mb-free_mb)/total_mb*100))
FROM v$asm_diskgroup
WHERE NAME in ('DATA');

QUIT;
```

## Zabbixコンソールで監視アイテム設定 
### zabbixコンソールにログイン

###  設定 > テンプレート より Template_OCI_Dbaas を選択。
<img width="709" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/b53a60e7-c688-8c97-b484-2356bde02f16.png">


### アイテム > アイテムの作成 をクリック。
<img width="727" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/1d11e7e3-d89e-fea8-6bb6-334cdaefb91c.png">


### 各項目を入力して更新。
<img width="543" alt="キャプチャ3.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/614796cf-672f-352a-2eca-eb6b4d73773b.png">

[項目]
名前: [Oracle]に続けて監視項目のアイテム名を記載。
タイプ: Zabbixエージェントのまま
キー: zabbix-oci-dbaas[{$ORACLE_SID},db_asmdata,1] ⇒ db_asmdataの部分は、SQLファイル名(db_asmdata.sql)の.sql以前を記載する。
データ型: 数値(整数)のまま。
監視の値が小数で、ここが浮動小数点型でないとエラーになるので、ちゃんと合わせること。
単位: ここでは%
監視間隔: 600
ヒストリの保存期間: 7d
トレンドの保存期間: 15d
アプリケーション: Oracleを指定

### 監視データ > 最新データ より値が取得できていることを確認する。
![Inkedキャプチャ4_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/e344a467-b3bf-64a2-d75c-1a3874552282.jpeg)

## 関連記事
[・ZabbixでOCI Dbaas監視 - エージェント設定](https://qiita.com/y-araki-qiita/items/f25e02182c7f279c0199)
[・GrafanaでOCI Monitoring メトリクスのダッシュボード作成手順](https://qiita.com/y-araki-qiita/items/e6b4d10e9c49627c0f97)
[・GrafanaでZabbixとOCI Monitoringのメトリクスを一元化](https://qiita.com/y-araki-qiita/items/fe02197a6cb3f2ad84e9)
GitHub Pagesを使って、10秒でWebページを公開する

# はじめに
GitHub Pagesめっちゃすごい！！:laughing:
簡単にWebページを公開することができたから、手順の保存と共有！

# 環境
- Windows 10 home
- **GitHubのアカウントを持っている前提**
- **Webページのファイル作成済み**




# 公開の手順

![素材1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/5410a453-3944-7606-2e78-6d31114bc0d9.png)

GitHubにログインするとこのページになると思います。
右上の＋ボタンを押して、<font color="Red">**「New repository」**</font>を作成しましょう。


![素材2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/4b2fc699-d200-7672-24b8-17327c2b4633.png)

この画面になったら、Repository nameに<font color="Red">**「ユーザ名.github.io」**</font>と入力しましょう。
私の場合はmichimichix521.github.ioと入力しています。


![素材3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/a804c803-f13a-93e4-7750-0ad7a4b40637.png)

次に、赤丸の<font color="Red">**「uploading an existing file」**</font>をクリックしてください。



![素材4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/75b388d6-6a3b-1937-e072-98a8d05e3b03.png)

公開したいWebページのファイル（<font color="Red">**ファイル名はindex.html**</font>）をドラッグ&ドロップまたは、choose your filesから持ってきてください。
そして、下の方にある緑のボタンの<font color="Green">**Commit changes**</font>を押します。


![素材5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309633/fc85667d-3af3-7f2d-c29a-2bb463dade5c.png)

```
https://ユーザ名.github.io
```


上記のURLが公開したWebページのURLになります。


# おわりに
以上で終了になります。
ここまで読んでいただき、ありがとうございました。
Ubuntu18.10でapt updateのエラーを解決した方法

#はじめに
Vagrantで、Ubuntu18.10のボックスを作り、Node.jsをインストールしたいが、エラーでインストールできず
`sudo apt install -y nodejs npm`
で、エラー発生

##エラー内容
>Ign:1 http://archive.ubuntu.com/ubuntu cosmic-updates/main amd64 gcc-8 amd64 8.3.0-6ubuntu1~18.10.1
Ign:2 http://archive.ubuntu.com/ubuntu cosmic-updates/main amd64 g++-8 amd64 8.3.0-6ubuntu1~18.10.1
Err:1 http://security.ubuntu.com/ubuntu cosmic-updates/main amd64 gcc-8 amd64 8.3.0-6ubuntu1~18.10.1
  Connection failed [IP: 91.189.91.13 80]
Err:2 http://security.ubuntu.com/ubuntu cosmic-updates/main amd64 g++-8 amd64 8.3.0-6ubuntu1~18.10.1
  Connection failed [IP: 91.189.91.13 80]
E: Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/gcc-8_8.3.0-6ubuntu1~18.10.1_amd64.deb  Connection failed [IP: 91.189.91.13 80]
E: Failed to fetch http://security.ubuntu.com/ubuntu/pool/main/g/gcc-8/g++-8_8.3.0-6ubuntu1~18.10.1_amd64.deb  Connection failed [IP: 91.189.91.13 80]
E: Unable to fetch some archives, maybe run apt-get update or try with --fix-missing?

`sudo apt update`
で回避できるはずだったが、これまたエラー発生。
>Err:1 http://security.ubuntu.com/ubuntu cosmic-security InRelease
  Connection failed [IP: 91.189.92.201 80]
Err:2 http://archive.ubuntu.com/ubuntu cosmic InRelease
  Connection failed [IP: 91.189.91.13 80]
Err:3 http://archive.ubuntu.com/ubuntu cosmic-updates InRelease
  Connection failed [IP: 91.189.91.13 80]
Err:4 http://archive.ubuntu.com/ubuntu cosmic-backports InRelease
  Connection failed [IP: 91.189.91.13 80]
Reading package lists... Done

#回避した方法は２つ
- タイムゾーンを合わせしたこと
- proxyの設定をしたこと

##タイムゾーンの設定
`date`
で時間を確認するとタイムゾーンが設定されていなかったので、再設定した
`timedatectl set-timezone Asia/Tokyo`
実際は、この設定なくても問題はないと思ってます

##proxyの設定
プロキシーサーバの用意は省略します
下記の<プロキシ―サーバ>には、用意したプロキシサーバのホスト名かIPアドレスを指定します。
`sudo vi /etc/environment`
>http_proxy="http://<プロキシ―サーバ>/"
https_proxy="http://<プロキシ―サーバ>/"

#調査しながら、いらなかった設定
/etc/hostsに`security.ubuntu.com`などを追加したが、回避できず
/etc/resolv.confに、`nameserver 8.8.8.8`を追加したが、回避できず

#原因って何だろう
vagrantのマシンからubuntu.comへhttp接続できない原因は、いまだに不明。
理由は、aptコマンドで、どこでどのようなことをしているのか理解していないため。

とりえず、自前のプロキシーで、DNSがきちんと引けたことで回避することができた。

#参考サイト
Ubuntuに最新のNode.jsを難なくインストールする
https://qiita.com/seibe/items/36cef7df85fe2cefa3ea
このn packageは便利
特定のページでのみjsを発火させる方法

###はじめに
jsを特定のページでのみ発火させたいと考え、調べたことについてまとめる。

###やり方
やり方はとてもシンプルで、

```edit.js
if(document.URL.match(/edit/)){
  　　発火させたいjsの内容
```

これだけでjsを発火させるページを指定できます。
この場合はurlに’edit’という文字が入っているページでのみjsが発火します。

###欠点
指定した文字の入ったurlが複数あると複数のページでjsが発火してしまいます。
どのページとも被っていない文字を指定する必要があります。
Mac版のM5Burnerはダウンロードディレクトリではファームウェアがダウンロードできないので注意

# TL;DR
タイトルの通りです。
ApplicationディレクトリなどにM5Burnerを移動してから実行しましょう。

(追記)
コメントで @inasawa さんに教えていただいたのですが、`macOS Sierraから導入されたGatekeeper Path Randomizationという仕組み`のためらしく、アプリケーションディレクトリじゃなくてもよかったそうなので、当初はアプリケーションディレクトリにと書いてましたがタイトルを修正しました。(感謝)
https://qiita.com/kk2170/items/64913beeeb23927aef20#comment-404a45cb35e0fa56805d


# 本文
MicroPythonとかを使うためにesptoolを使って書き込んでいたりしましたが、最近だとM5Burnerを利用して簡単に書き込めるという情報を見て試してみたのですが、うまくいかなくてはまってしまったので共有します。

M5Burnerをダウンロードして実行してみたのですが、下のgif画像の様に書き込みたいfirmwareを選択してダウンロードボタンを押しても何も反応しない状態になってしまい、どうしたら良いのだろうと言う気持ちになりました。

![ダウンロードできない](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12680/7016ee8c-ef62-40d0-44ea-3c82b1076222.gif)

こちら原因はシンプルで単発で動かす予定だったので、横着してダウンロードフォルダで実行していたのが原因でした。
アプリケーションフォルダに移動して、実行し直すと以下のようにダウンロードができました。

![Jul-18-2019 16-43-48.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12680/e08708ec-5313-717a-b04d-11efababc8c7.gif)

上記の様に現在は、 ~~アプリケーションディレクトリ以外~~ ダウンロードしてきたフォルダで実行しようとするとfirmwareがダウンロード出来ないので注意をしてください。

と言うわけで無事使えるようになったのですが、M5Burnerこれめっちゃ便利ですね！
ASP.NET CoreでNew Relic Browserモニタリングを有効化する

以前書いた記事で.NET CoreのエージェントではBrowserモニタリングを自動で有効化することができないと書きました。

[Linux Docker コンテナに New Relic .NET Coreエージェントをインストールする方法](https://qiita.com/takayoshitanaka/items/6eef46d821704a7384dc)

そのため有効化するコードを埋め込む必要があります。こちらのドキュメントに紹介されていますが、エージェントAPIを使う方法とコピーペーストで貼り付ける方法があります。

[エージェントを他のNew Relic製品に接続する](https://docs.newrelic.co.jp/docs/agents/net-agent/installation/compatibility-requirements-net-core-agent#digital-intelligence-platform)
[New Relic Browserエージェントをインストールする](https://docs.newrelic.co.jp/docs/browser/new-relic-browser/installation/install-new-relic-browser-agent#copy-paste-app)

今回はこの２通りの方法を紹介します。

### エージェントAPIを使う方法

この方法は、.NET Coreサーバーサイド側でエージェントAPIを利用して埋め込むJavaScriptコードを取得し、Viewに埋め込む方法です。
まずエージェントAPIのライブラリをプロジェクトの参照に追加します。.NET Core CLIを使う場合はこちらのコマンドです。

```
dotnet add package NewRelic.Agent.Api --version 8.16.567
```

次にRazorビュー側で`<head>`タグの出来るだけ先頭の方にタグを挿入します。例えば、Razorのプロジェクトテンプレート（`dotnet new webapp`で作成される)であれば、`Pages/_Layout.cs.html`に追加すると全ページで有効にできます。下の例ではEnvironmentがDevelopmentでない場合のみ追加しています。これにより、Development環境を指定したローカルデバッグの時はBrowserモニタリングを無効化にすることができます。`GetBrowserTimingHeader`の返り値を`@Html.Raw`で囲うことを忘れないでください。

```xml
<!DOCTYPE html>
<html>
<head>
    <environment exclude="Development">
        @Html.Raw(NewRelic.Api.Agent.NewRelic.GetBrowserTimingHeader())
    </environment>
```

以上で手順は完了です。リクエストを生成して、ダッシュボードに表示されることを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405931/7a8771b5-5d12-e375-0154-7fc1cb918de8.png)


### コピーペーストによる方法

サーバーサイドでレンダリングできない場合（例えばSPAなど）、headタグにコピーペーストでコードを埋め込むことができます。まずBrowserのダッシュボード(`https://rpm.newrelic.com/accounts/<アカウントID>/browser`)に移動し、右上の`Add more`をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405931/31340db3-8a5b-ab7d-4793-f5151f285ff5.png)

すると次のようなウィザードが表示されるので`Copy/Paste Javascript code`を選択し、次にモニタリングの種類を選択します。選択可能な方法はご契約のサブスクリプションに依存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405931/8e385ba0-3963-4411-55cb-5ff1d591b02e.png)

次にアプリケーションの名前を指定します。もしAPMですでにモニタリングしていればYesを選んで表示されるアプリケーションから指定してください。すると、`<script>`タグで囲まれたコードが表示されるので、このコードをHTMLのheadタグの出来るだけ先頭に挿入します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/405931/da9dea6a-4b2c-ae40-7ebe-d1f8d36e74a2.png)

あとはアプリケーションを配置して、トラフィックを生成すると、先ほどと同じようにダッシュボードに表示されるはずです。
Calendarで1週間の最初の日(firstWeekday)を変更する際の罠

`firstWeekday`を変更した後に`locale`を変更してしまうと、そのロケールに依存して`firstWeekday`が変更されるので注意！

<img width="413" alt="スクリーンショット 2019-07-18 16.39.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/92771/4e7d154c-ea19-5ee6-fdff-34a4c6b83037.png">
論文まとめ：Manifold Mixup: Better Representations by Interpolating Hidden States

# はじめに 

ICML 2019 より以下の論文
[1] V. Verma, et. al. "Manifold Mixup: Better Representations by Interpolating Hidden States"
を超簡潔にまとめ。

arXiv:
https://arxiv.org/abs/1806.05236

# 概要
1. mixup をhidden 層にまで拡張させたら汎化性能がよくなった

# 手法 
まず用語の定義から
$g\_k(x)$ ：入力データ $x$ の $k$ 層におけるfeature map。
$f(x) = f\_k (g\_k(x))$ ：feature map $g\_k(x)$ からの出力。
$(x,y)$ および $(x',y')$ データとtarget のペア。
$\lambda \sim {\rm Beta}(\alpha, \alpha)$ ：$\lambda$ はベータ関数 $(\alpha, \alpha)$ に従う定数。
${\rm{Mix}}\_{\lambda} (a, b) = \lambda \cdot a + (1-\lambda) \cdot b$ ：データ $a$ と $b$ との mixup。

以上を用いて manifold mixup は

```math
(\tilde{g_k}, \tilde{y}) := ({\rm{Mix}}_{\lambda} (g_k(x), g_k(x')),{\rm{Mix}}_{\lambda} (y, y'))
```

として、hidden 層 $k$ においてminibatchを作成するだけ。

そしてこれの出力に対するloss

```math
L(f) = \mathbb{E}_{(x,y) \sim P} \mathbb{E}_{(x',y') \sim P} \mathbb{E}_{\lambda \sim {\rm Beta}(\alpha, \alpha)} \mathbb{E}_{k \sim \mathcal{S}} l (f_k ({\rm Mix}_\lambda(g_k(x),g_k(x'))), {\rm Mix}_\lambda(y,y'))
```

を最小化する。

ただし、実用上はminibatch ごとに $\lambda$ と適応するhidden層 $k$ を固定する。こうしても精度は変わらないらしい。

# 効果

<img width="703" alt="manifold_mixup_img01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116706/602e9c0e-8d59-d5eb-ea4f-94ba0541ea02.png">

図(a)と(d)が本手法を用いない場合で、(b)と(e)が用いた場合。

(a)と(b)は２次元入力データの分布だが、用いない(a)と比べて用いる(b)はデータの境界面が滑らかになっている

(d)と(e)はhidden 層の 分布だが、用いない(d)と比べて用いた(e)は綺麗にわかれている。

(c)は１層目のsingular value、(f)は３層目のsingular valueだが、用いた場合は flattenになっている。
自動Windows Updateのメモ

参考URL
http://www.vwnet.jp/Windows/PowerShell/FullAutoWU.htm
ありがたや、ありがたや。

本当にただのメモだけです。


後日追記：
これがよさそう。拾い物です。

```
Install-PackageProvider -Name NuGet -Force
Install-Module PSWindowsUpdate -Force
Add-WUServiceManager -ServiceID 7971f918-a847-4430-9279-4a52d1efe18d
Install-WindowsUpdate –AcceptAll –AutoReboot
```
【Unity】exeのタイトルバーを非表示にする

タイトルバー消したい。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306317/b726b39b-851e-a8b4-24ba-6a15d195ab77.png)

##① WindowController.cs
シーン上の好きなオブジェクトにアタッチします。

```C#
using UnityEngine;
using System.Collections;

using System;
using System.Runtime.InteropServices;

namespace Utils {

    public class WindowController : MonoBehaviour {

        private string windowName = "windowname";
        private int x = 0;
        private int y = 0;
        private int width = 1920;
        private int height = 1080;
        private bool hideTitleBar = true;

        [DllImport("user32.dll", EntryPoint = "SetWindowPos")]
        private static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);

        [DllImport("user32.dll", EntryPoint = "FindWindow")]
        public static extern IntPtr FindWindow(System.String className, System.String windowName);

        // Sets window attributes
        [DllImport("user32.dll")]
        public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        // Gets window attributes
        [DllImport("user32.dll")]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        // assorted constants needed
        public static int GWL_STYLE = -16;
        public static int WS_CHILD = 0x40000000; //child window
        public static int WS_BORDER = 0x00800000; //window with border
        public static int WS_DLGFRAME = 0x00400000; //window with double border but no title
        public static int WS_CAPTION = WS_BORDER | WS_DLGFRAME; //window with a title bar

        void Awake () {
            var window = FindWindow(null, windowName);
            if(hideTitleBar) {
                int style = GetWindowLong(window, GWL_STYLE);
                SetWindowLong(window, GWL_STYLE, (style & ~WS_CAPTION));
            }
            SetWindowPos(window, 0, x, y, width, height, width * height == 0 ? 1 : 0);
        }
    }
}
```
`private string windowName = "windowname";`・・・windowのタイトル名
`private int x = 0;`・・・ウィンドウの左上端座標x
`private int y = 0;`・・・ウィンドウの左上端座標y
`private int width = 1920;`・・・ウィンドウの幅
`private int height = 1080;`・・・ウィンドウの高さ
`private bool hideTitleBar = true;`・・・**タイトルバーを隠すか**

##② user32.dll
Assets/Plugins下にそのまま置いてください。

```dll
extern "C" __declspec(dllexport) int Add(int a, int b)
{
     return(a + b);
}
```
※コード内容に深い意味はありませんので、もっといいコードがあればどなたか。

##③ Player Settings
Player Settings > Player > Resolution and Presentation > Resolution
・**Fullscreen Mode**　を　**Windowed**にする。
・**Resizable Window**　チェックを外す。
![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306317/1d3a8b39-b0bd-0df9-6140-b6cd38c19704.png)

##コード引用元
・[Is there a way to set the position of a standalone unity window?](http://answers.unity3d.com/questions/13523/is-there-a-way-to-set-the-position-of-a-standalone.html)
・[Removing the Title bar of external application using c#
](http://stackoverflow.com/questions/2825528/removing-the-title-bar-of-external-application-using-c-sharp)
Rails アソシエーションについて　メモ

#アソシエーションとは
Railsの機能の一つで、モデル間の関係を定義しておくことで
モデル間でのデータのやり取りを簡単にすることができる。


##定義の仕方
アソシエーションの機能を利用するにはモデルクラスファイルに
モデル同士の関係性を定義する必要がある。

例えば、tweetをするアプリケーションにおいて
アソシエーションを利用する場合は
あるユーザーに対してツイートは複数存在し、
あるツイートに対してはユーザーが一人存在する
という関係性になるので、

userのモデルファイルに対しては

~~~ruby:user.rb
class User < ApplicationRecord
    has_many :tweets　#userは複数のtweetを持っている
end
~~~

tweetのモデルファイルに対しては

~~~ruby:tweet.rb
class Tweet < ApplicationRecord
    belongs_to :user #tweetはあるuserに属している
end
~~~

と記述する。
ただし条件があり、
所属する側のテーブルに所属するクラス名_idというカラムが必要。
上記の場合だとtweetｓテーブルにusers_idのカラムが必要。

| モデル名           |       モデルクラスファイル |    テーブルカラム    |
|:-----------------|------------------:|:------------------:|
| User             | has_many :tweets |        ー       |
| Tweet            | belongs_to : user |       user_id       |
初めてテスト書いたのでGoにおけるユニットテストについて備忘録

これまでは従業員手ずから温かみのあるテストを行っていました。
今回初めてテストコードを書いたので、Goでテストコード書くときに学んだことを残します。
指導らしい指導のない環境で独学で書いたのでマサカリください。

## 基本
- テスト対象のfuncと対になるテストは同一パッケージに含めていい
- テスト関数はテスト対象関数の接頭辞としてTestをつける。例えば`func Hoge()`のテストは`TestHoge(t *testing.T)`
- "Test"+対象関数テスト+識別子で同一関数に複数テストを定義できる。例えば、`TestHogeSuccess()`と`TestHogeFailed()`など。
- テストは`testing`パッケージをimportする
- テストの実行は`go test`でカレントにあるテスト関数を全部実行
- テストに使うデータは./testdata以下に置く

命名規則を守らないとテストと識別されず、`no test to run`と言われます。
実行結果はPassになるが、実際は何もテストしていないので当然である。

## テストのログについて
テストのログはtestingパッケージのLogを使います。`t.Log("hogefuga")`等と書きますが、このログは-vをオプションにテストを実行した時以外表示されません。
また、`Log()`のほかに`Error()`と`Fatal()`があり、`Error`はテスト失敗としてログを出すが、以降のテストも継続され、`Fatal`はテスト失敗としてログを出して終了します。

## ディレクトリ生成を含む機能のテストについて
ファイル入出力を伴う機能のテストについてはBufferを使うなどの知見が多くみられましたが、ディレクトリ生成についてはあまり見かけませんでした。
普通はその粒度のテストはしないよということなのか、単に私の考え方が間違っているのか？

結論として、`ioutil.TempDir()`を使います。

golang.orgで調べると、`ioutil.TempDir()`は第一引数が空文字の場合、一時ファイルに使用するデフォルトディレクトリに、第二引数から始まるディレクトリが生成されます。
私の環境では、`ioutil.TmpDir("", "sample")`とすると、`/var/folders/4y/6np86wk926v81_9kh1gkry6r0000gn/T/sample700856606`というディレクトリが生成されました。
この場合は、一時ファイルに使用するデフォルトディレクトリが`/var/folders/4y/6np86wk926v81_9kh1gkry6r0000gn/T/`で、第二引数から始まるディレクトリが`sample700856606`になります。
MacOSにおいて`/var/folders`配下はキャッシュディレクトリで、特に/Tは短期記録用で再起動でOSに消去されていたらしい（最近は仕様が変わったみたい？）です。
なお`ioutil.TempDir()`によって作成されたディレクトリの消去は呼び出し側に責任があるので、最後に忘れずに`defer os.RemoveAll()`して消去します。
以下、簡略化しましたが概ねこんな感じのテストを書きました。

```sample.go
package sample

import (
    "io/ioutil"
)

var src string

func Sample() {
    ioutil.MkdirAll(src)
}
```

```sample_test.go
package sample

import (
    "testing"
    "path/filepath"
    "os"
)

func TestSample(t *testing.T){
    // 一時領域にディレクトリを生成する
    tmp, err := ioutil.TempDir("", "sample")
    if err != nil {
        t.Errorf("failed: %v", err)
    }
    // 最後に消す
    defer os.RemoveAll(tmp)

    testdir := "sample1/sample1-1"

    // tmpのサブディレクトリとしてディレクトリ生成を含んだテストを行う
    src = filepath.Join(tmp, testdir)

    Sample()

    // ファイルの存在確認
    _, err := os.Stat(src)
    if os.IsNotExist(err) {
        t.Errorf("failed: %v", err)
    }
}
```

## まとめ
テスト特有のデータをテスト対象関数にどうやって渡すのかで凄く悩んみました。
最終的にグローバル変数としてテスト関数から`src`を上書き指定しているが、妥当かどうかという点ではちょっとモニョっています。
アーキテクチャの種類しらべてみた

最近になってVIPERアーキテクチャの案件にアサインしていただき、
遅ばせながらアーキテクチャがどんなものなのか、初めて知りました。
そんな初心者がアーキテクチャについて調べてみた内容をまとめます。
間違い等あるかもしれませんが勉強中なので悪しからず。。。。。

## アーキテクチャとは
直訳すると「「「建築」」」
調べてみると。。。。「コンピュータシステムの論理的構造」
うーん、、、難しい、、(ソモソモ ヨコモジ ムズカシイ。。。。。)
要するに、「プロジェクト自体の構造、とか構成」とかっぽい！
もうちょっと調べてみると
**「アプリケーションを綺麗に実装するための設計方法」**
わかりやすい！！！

## アーキテクチャのメリット・デメリット
●メリット
- テストがしやすい
- アサインされた時にどこに何が書いてあるのかが分かる
etc....

●デメリット
- クラスの肥大化
- 役割分担がしにくい
- どこになにが書いてあるのかすぐにわからない
etc....

## アーキテクチャの種類：いっぱいあるようです！
●GUI Architecture：サブsystemが対象
- (1979~) MVC
- (2009~)DCIArchitecture(MVCっぽいもの)
- (1999~)MVC Model2
- (1990~) MVP(Supervising Controller)
- (2006~) MVP(Passive Views)
- (2009~)MVVM
　→Microsoft発祥
- (2014~)Flux
　→Facebook製のデータフローモデル

●System Architecture：system全体が対象
- Layered Architecture
- (2008~)Onion  Architecture
- (2012~)Clean Architecture
- (2013~)VIPER
- (2014~)MVA
- (2016~)MVVM-C

## 参考URL
https://medium.com/@rockname/clean-archirecture-7be37f34c943
https://qiita.com/hicka04/items/09534b5daffec33b2bec
https://qiita.com/star__hoshi/items/f28095542f56a1b05e34
個人的にオススメ、すごく面白い。。。わかりやすい↓
https://speakerdeck.com/takasek/10fen-tezhen-rifan-rusohutoueaakitekutiyafalseli-shi-2017
俺とお前と大五郎

#これは何？

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">1994年頃のCM 俺とおまえと大五郎 02 協和焼酎大五郎 昔の友は今も友 <a href="https://t.co/GK3Psy4NCl">https://t.co/GK3Psy4NCl</a> <a href="https://twitter.com/YouTube?ref_src=twsrc%5Etfw">@YouTube</a>さんから</p>&mdash; _obuchi3 (@_obuchi3) <a href="https://twitter.com/_obuchi3/status/1151744990655045632?ref_src=twsrc%5Etfw">2019年7月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# つまり

* `俺`、`お前`、`大五郎`をランダムで出力して、`俺とお前と大五郎`になったら終了する。
* 今回はTypeScriptで書いてみる。~~TypeScript要素無かった。~~

```typescript
const words: Array<string> = ['俺', 'お前', '大五郎'];
const getWord = (): string => words[Math.floor(Math.random() * 3)];

const values: Array<string> = [];
let count: number = 0;

while (true) {
  values.push(getWord());
  if (values.length === 3) {
    count++;
    console.log(`${count}\t${values.join('と')}`);
    if (JSON.stringify(values) === JSON.stringify(words)) {
      break;
    } else {
      values.splice(0, values.length);
    }
  }
}
```
https://github.com/obuchi3/daigoro

# 実行結果

<pre>
1       大五郎とお前と大五郎
2       俺と俺とお前
3       俺と俺と俺
4       大五郎と大五郎とお前
5       お前と大五郎と俺
6       お前とお前と俺
7       俺と大五郎と俺
8       大五郎と俺と俺
9       大五郎とお前と大五郎
10      俺と俺とお前
11      大五郎と俺とお前
12      俺とお前と俺
13      お前とお前と俺
14      大五郎と大五郎とお前
15      俺と俺と大五郎
16      お前とお前と大五郎
17      お前と俺とお前
18      大五郎と大五郎とお前
19      大五郎と俺と大五郎
20      大五郎とお前と俺
21      お前と俺とお前
22      俺とお前と大五郎
</pre>

# 結局のところ、これは何？

懐かしいですよね。
MSSQL_日付

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381112/9025e40f-c9f8-876a-b6da-31dfafe40245.png)


DECLARE @Date DATETIME = GETDATE();
SELECT    CONVERT(NVARCHAR, @Date, 111) AS '111',-- yyyy/mm/dd
          CONVERT(NVARCHAR, @Date, 11) AS '11',-- yy/mm/dd
          CONVERT(NVARCHAR, @Date, 112) AS '112',-- yyyymmdd
          CONVERT(NVARCHAR, @Date, 12) AS '12',-- yymmdd
          CONVERT(NVARCHAR, @Date, 108) AS '108',-- HH:mi:ss
          CONVERT(NVARCHAR, @Date, 114) AS '114';-- HH:mi:ss:mmm 


![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381112/07a29493-e973-18b8-87b2-443b419e0db6.png)
現在時刻 15:50 ,下記は「14」を出力する 
select convert(char(2),DateAdd(hour,-1,GETDATE()),108) --一時間前の時間を数字で返す

SELECT 
  GETDATE(),
  YEAR(GETDATE()),  --年を数字で返す
  MONTH(GETDATE()), --月を数字で返す
  DAY(GETDATE())    --日を数字で返す 

SELECT 
  YEAR('2015/04/15'),  --2015
  MONTH('2015/04/15'), --4 　← 文字列の 04 ではなく数字の 4
  DAY('2015/04/15')    --15 

DATEADD（年・月・日・時間・分・秒を加算・減算する）
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/381112/48874909-18d4-1b08-4405-48049d6057a0.png)
MacOS Mojave の開発環境構築（Ruby on Rails 編）

# はじめに
MacBook Pro 2018 での開発環境を構築した際の記録です。
随時、加筆修正致します。

# 記事作成時の環境
・Model: MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports)
・OS: macOS Mojave 10.14.4
・rbenv 1.1.2
・Ruby 2.6.3
・Bundler 2.0.1
・Rails 5.2.3
・MySQL 5.7（8.0）

# まずやること
**これをやらないと、bundle install 時でエラーになってしまい、ハマってしまいます（汗）**

このラインより上のエリアが無料で表示されます。
Command Line Tools のインストール

1. https://developer.apple.com/download/more/ にアクセスし、AppleIDとパスワードを入力する。
2. 左上の検索のところでCommandで検索すると、Command Line Toolsが色々出てくるので、自分にあったバージョンをダウンロードする。
3. .dmgをダウンロードしたら、クリックしてインストールする。

以下のコマンドを打ってライセンスが表示されたら正常にインストール完了です。

`$ sudo xcodebuild -license`
MacOS Mojave の開発環境で bundle install を実行すると、以下のエラーが発生する。

`Gem::Ext::BuildError: ERROR: Failed to build gem native extension.`
原因は、MacOS Mojave 用の CommandLineTools がベータ版のため、インストーラから macOS_SDK_headers_for_macOS_10.14.pkg が呼び出されていないため。

解決方法は、

open コマンドより、command-line-tool のパッケージフォルダを開く。

`open /Library/Developer/CommandLineTools/Packages/`
macOS_SDK_headers_for_macOS_10.14.pkg が存在するので、インストールする。

あとは、以下を順番にやっていくだけ。

# rbenv のインストール
rbenv は Ruby のバージョン管理システムになります。
プロジェクトごとに Ruby のバージョンを切り替えることができるようになります。

`$ brew install rbenv`

`$ rbenv -v`
`rbenv 1.1.2`
初期設定をします。

`$ rbenv init`
.zshrc に環境変数を設定します。

`$ echo 'eval "$(rbenv init -)"' >> ~/.zshrc`

`$ echo 'export PATH="~/.rbenv/shims:/usr/local/bin:$PATH"' >> ~/.zshrc`

`$ source ~/.zshrc`

# ruby のインストール
インストール可能な Ruby のリストを確認します。

`$ rbenv install --list`
2019/5/13 現在 2.6.3 が最新安定版なのでこちらをインストールします。

`$ rbenv install 2.6.3`
デフォルトで利用する Ruby のバージョンを指定します。

`$ rbenv global 2.6.3`
設定できているかを確認します。

`$ ruby -v`
`ruby 2.6.3p62 (2019-04-16 revision 67580) [x86_64-darwin18]`

# bundler のインストール
`$ gem install bundler`

`$ bundle -v`
`Bundler version 2.0.1`

# rails のインストール
`$ gem install rails`

`$ rails -v`
`Rails 5.2.3`

以上
PATHの変更でcommand not foundになってしまった場合の直し方

.bash_profileに変なPATHを間違えて設定してしまい、
ほとんどのコマンドがcommand not foundになってしまって、
めちゃくちゃ焦ったのでその時の対処メモ。

スマートな直し方では無いかもしれませんが。。

##解決方法

とりあえず、まずはコマンドを使えるようにするためにPATHを設定

```
$ export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
```

それから

```
$ vi ~/.bash_profile
```

で間違えて設定したPATHを削除

これで直りました。

##参考

https://qiita.com/noraworld/items/4556f91bc31f641d187d
lego で Let's Encrypt

## はじめに

公式の `certbot` がありますが、本内容は `lego` を使用します。
https://github.com/go-acme/lego

バージョン：`lego version 2.6.0 linux/amd64`

なお、本手順では、認証ファイル方式の説明になります。

## Apache

バーチャルホストの設定に認証ファイル用のエイリアスを追加します。
この辺は、好みの問題なので、ドキュメントルート配下に直接置く場合は、設定不要です。

```apache
    Alias /.well-known /etc/lego/webroot/.well-known
    <Directory "/etc/lego/webroot/.well-known">
       Order deny,allow
       Allow from all
    </Directory>
```

## 証明書リクエスト&生成

```bash
lego --accept-tos \
     --path /etc/lego/.lego/ \
     --http \
     --http.webroot /etc/lego/webroot/ \
     --domains "your-domain.com" \
     --email your-mail@gmail.com \
     run
```

`/etc/lego/.lego/certificates/` に鍵ファイルや証明書が出力されます。

## 証明書を破棄

```bash
lego --accept-tos \
     --path /etc/lego/.lego/ \
     --http \
     --http.webroot /etc/lego/webroot/ \
     --domains "your-domain.com" \
     --email your-mail@gmail.com \
     revoke
```

## 証明書を更新

```bash
lego --accept-tos \
     --path /etc/lego/.lego/ \
     --http \
     --http.webroot /etc/lego/webroot/ \
     --domains "your-domain.com" \
     --email your-mail@gmail.com \
     renew \
     --days 30
     --renew-hook "/bin/systemctl reload httpd"
```

※「--days 30」は、「renew」に対してのオプションなので、指定する位置に気をつける。

## 中間証明書について

以下コマンドでファイルを分割する

```bash
cd /etc/lego/.lego/certificates
csplit -z -f your-domain.com. -b "%02d.pem" your-domain.com.crt '/BEGIN CERTIFICATE/' '{*}'
rm ./your-domain.com.00.pem
mv ./your-domain.com.01.pem ./your-domain.com.chain.pem
```

https://letsencrypt.org/certificates/
CircleCIからCodePipelineを開始させる

# 背景
先日会社のステージング環境をEC2からFargateにリプレイスし、
CodePipelineを使ってFargateへの自動デプロイがされるようにしました

その際にCIはCircleCIをそのまま使ってCDをCodeDeployに任せたかったのですが
`develop`ブランチの変更をトリガーにCodePipelineを開始すると
CircleCIと並行して走ってしまうためCircleCIが正常終了した時のみCodePipelineが実行されるようにしました

いろいろ調べて「これだ」っていうのがなかったので自分の考えたこの方法が同じ状況の人に参考になったら嬉しいな〜と

# 概要
ざっくり書くと

```
CircleCI -> S3 -> CodePipeline -> CodeBuild -> CodeDeploy
```

CircleCIからS3へ`buildspec.yml`とコミットハッシュを持つファイル(`commit`)を送り
その`buildspec.yml`と`commit`を使ってビルド、デプロイしていきます

あらかじめCodeBuildには環境変数で`git clone`できるように認証情報入れておき
`buildspec.yml`の中身は`git clone`して`commit`をもとにチェックアウトしてビルド
といった感じにします

# S3の設定
適当に非公開のバケットを作ります
仮でバケット名は`sample-deploy-hook`としておきます

<img width="1051" alt="スクリーンショット 2019-07-18 15.02.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236978/9fa74917-4fd4-8da0-018d-6b06ecbe0ecc.png">

# IAMの設定
S3のポリシーをアタッチしたユーザを作成して`アクセスキーID`と`シークレットアクセスキー`をメモっておきます

<img width="1088" alt="スクリーンショット 2019-07-18 15.04.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236978/c5b54178-8ff4-454b-8f1b-804b609450a4.png">

# CircleCIの設定
## 環境変数を設定
IAMでユーザを作った際にメモった`アクセスキーID`/`シークレットキー`を
それぞれ`AWS_ACCESS_KEY_ID`/`AWS_SECRET_ACCESS_KEY`という環境変数で設定する

## `.circleci/config.yml`を設定
### jobを追加
```yml
deploy-staging:
    docker:
      - image: circleci/python:3.7
    working_directory: ~/project
    steps:
      - checkout
      - run:
          name: Install awscli
          command: |
            sudo pip install awscli
      - run:
          name: Setup AWS credentials
          command: |
            mkdir -p ~/.aws
            printf "[default]\nregion = ${AWS_REGION}\naws_access_key_id = ${AWS_ACCESS_KEY_ID}\naws_secret_access_key = ${AWS_SECRET_ACCESS_KEY}" > ~/.aws/config
            printf "[default]\naws_access_key_id = ${AWS_ACCESS_KEY_ID}\naws_secret_access_key = ${AWS_SECRET_ACCESS_KEY}" > ~/.aws/credentials
            chmod 600 ~/.aws/*
      - run:
          name: Create commit hash file
          command: echo -n $CIRCLE_SHA1 > /tmp/commit
      - run:
          name: Create zip for deploy
          command: zip -j build buildspec.yml /tmp/commit
      - run:
          name: Upload zip to s3 for hook deploy staging
          command: aws s3 mv ./build.zip s3://sample-deploy-hook/build.zip
```

内容的には
- `awscli`をインストール
- AWSのcredential情報をファイルに吐き出す
- コミットハッシュを持つファイル(`commit`)を作成
- `buildspec.yml`と`commit`をzipに固める
- zipをS3へアップロード

# workflowへjobを追加
```yml
- deploy-staging:
  requires:
    - rspec
    - rubocop
    - db_seed
```
rspecやrubocopなどが正常に終了することを条件とするためにrequiresしてます

# CodePipelineの設定
最初のステージの`アクションプロバイダー`を`ソース > Amazon S3`を選び、
バケットは上で作ったもの
検出オプションは`CloudWatch`に任せます
S3オブジェクトキーは任意のファイル名(CIからアップするzipと同名)にします

<img width="1259" alt="スクリーンショット 2019-07-18 14.57.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236978/a7499487-70c9-9d54-6373-b7a6bfa5a0d3.png">

これでCIが通った時にS3にzipがアップされ、それをトリガーにCodePipelineが走るようになります
【備忘録】setStateはすぐにstateに反映させるものじゃないから気をつけろ

ハマったのでメモ書き。
若干の謎は残ってるので誰か神が下りてくることを待っている。（自分でも調べてる）

###問題のソース
https://github.com/sakaku193/p_react_web/blob/branch/todo_app/src/App.js

###何が問題だったか
タイトル通りです。
すぐに反映されないため、コメントアウトしている書き方はダメです。

```
//NG
localStorage.setItem("todos", JSON.stringify(this.state.todos))
//OK
localStorage.setItem("todos", JSON.stringify(todos))
```

参考資料
[[React.js] setStateしても直ちにstateは変更されない](https://likealunatic.jp/2015/07/reactjs-setstate)

###何が謎か
今回

```
todos = [...todos, newTodo]
```
としているが。

```
todos.push(newTodo)
```
とすると何故かNGの書き方でも意図したとおりに動いた。
React的には即反映はされないのが正しく、あえて制御しているものだと考えられるため
pushを使ってNGの書き方をするのは良くないんじゃないかと考えている。
stateは即時反映されるものではないと考えながらコードを書いていくのが良いのではないだろうか。

###謝辞
この問題が気になり、いろいろな方に聞きました。
お忙しいにも関わらずお力を貸していただきました。
おかげで様々な知見を得られました。
大変助かりました。ありがとうございます。
【VSCode｜Jest】VSCodeでJESTをデバッグする最小構成

vscodeでjestのデバッグをする時に少し躓いたのでメモ。

```launch.json
{
    "version": "0.2.0",
    "configurations": [
        {
          "type": "node",
          "request": "launch",
          "name": "JEST",
          "cwd": "${workspaceFolder}/etc/", // jest.config.jsなどがワークスペースルートにない時に指定してあげる
          "program": "${workspaceFolder}/etc/node_modules/.bin/jest",
          "protocol": "inspector",
          "args": [ "--runInBand" ],
      }
      ]
}

```

ポイント： `cwd` で `jest.config.js` ファイルなどが存在するディレクトリを指定する
DatadogのDashboard(Timeboard)が便利！

# 概要
Datadogは柔軟にダッシュボードを作成することができますが、
ダッシュボードを作成しようとすると選択肢が２つ出てきます。

<img width="833" alt="スクリーンショット 2019-07-18 14.12.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95324/afd8c8f9-cddf-200a-ea7c-07a64d020e84.png">

最初はこの2つの違いをよく理解できていないかったので、どっちを使えばいいだ？ってなってましたが、
使ってるうちに**「 `Timeboard`  便利やん！」**となったのでご紹介です。

# ダッシュボードの概要

## Screenboardについて
`For status boards and sharing data` とあるようにサービスのステータスがパッと一目で把握できるためのダッシュボードとして使っています。
例えば、各プロダクトごとのSLOの達成状況や外形監視(Synthetics)の結果、レスポンスタイム、エラーレイトといった値を可視化し、パッと見ただけでサービスの異常がざっくりと分かる作りにしています。


少し話がそれますが、最近[SLOの機能](https://www.datadoghq.com/blog/slo-monitoring-widget/)がリリースされたので、このSLOの達成状況をダッシュボードで表示してたりします。

例 SLO）
![スクリーンショット 2019-07-18 14.58.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95324/adcb040c-f60b-ecba-0dc5-f2ab7341da99.png)



## Timeboardについて
`For troubleshooting and correlation` とあるように主にトラブルシューティング時のダッシュボードとして使用しています。
AWSをDatadogで監視している場合、ALB、EC2、RDSのメトリクスを取っているかと思いますが、それをこのTimeboard上に配置してます。

例 EC2のメトリクス）
<img width="1592" alt="スクリーンショット 2019-07-18 14.28.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95324/edad2a9e-ed4c-10c2-ae2b-edc0247b3eee.png">

# Timeboardの何がうれしいか
ここがいいなと思ったところなんですが、Datadog上で発生したイベントの発生時刻をTimeboard上の各種メトリクスにオーバーレイすることができます。

例えば、Dagtadogで設定した「Response Time」のアラートが発生した場合、そのアラートを検索窓で検索することで各種メトリクス上に発生時刻をオーバーレイします。

例　検索窓）
<img width="413" alt="スクリーンショット 2019-07-18 14.39.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95324/8bce6069-8aa7-b078-ae71-dac28623d42f.png">


例　Response Timeの検索結果）
<img width="1282" alt="スクリーンショット 2019-07-18 14.42.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95324/bb38021b-2909-d5ad-5301-cdc3543d8226.png">

この例だと、左のピンク線がアラート発生時刻で、右のピンクの線がアラート復旧時刻となります。
このTimeboard上にEC2やRDSといった関連しそうなメトリクスを配置しておけば、アラート発生・復旧時刻と各種メトリクスがオーバーレイされ、相関が可視化できるため、トラブルシューティング時に役に立つことがあります。

# まとめ
今まであるようでなかったこの機能、トラブルシューティングにとても役に立ちます。
トラブルシューティング時に役に立ったメトリクスをどんどん追加して、育てていく感じで徐々にブラッシュアップしていくことをオススメします。