OmniAICreator/Qiita-1.07M huggingface dataset:
東京オリンピックのエンブレムを遊びつくす！(2)〜エンブレムに隠された法則〜

すでに多くの方がエンブレムの作られ方の解説をされていますが、ここではもう一度自分なりにエンブレムの作られ方について整理したいと思います。

![emblem.tif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498495/ba08ab8b-488c-b373-7932-a77adb330352.tiff)


#エンブレムはどうやってできている？
東京オリンピックのエンブレムは幾何学的なエンブレムですよね？となると何か幾何学的な仕掛けがあるのではと考えられます。エンブレムを眺めると、まずどちらのエンブレムも3種類の長方形を組み合わせて作られているということがわかります。
![fig2_2-02.tif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498495/e8a293a8-8f1a-ccc4-4fc9-64bd2beb4f3e.tiff)
取り敢えず三種類の長方形だけを使ってエンブレムチックなものを作ろうとすると、頂点が重ならなかったり、キレイな図形にならなかったりとなかなかうまくいきません。
![fig2_3.tif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498495/0aa3c09b-9702-3819-7986-ae8a0a1801b3.tiff)

何か手がかりが足りない…。そもそもなぜこれではうまくいかないのか考えてみると、図形の頂点を重ねて敷き詰めようとしているからです。頂点で考えると図形をどれくらい傾けるのかも考えなければならず、自由度が大きすぎて制御しきれません。図形を敷き詰めるときはタイルのように辺が重なるように敷き詰めるのがふつうです。
というわけで発想を変えて長方形が頂点が重なるように敷き詰められたのではなく、長方形を格納した図形がタイルのように敷き詰められて作られたと考えてみましょう。
そして色々試行錯誤してみるとエンブレムはひし形が敷き詰められて作られたということがわかります。そして各ひし形の中点を結んだものが私たちが見ている長方形の正体なのです。
![fig2_4-01.tif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498495/e09fbcfb-ebd4-ab70-6ff0-399b458bf492.tiff)


#ひし形の敷き詰め方
エンブレムがひし形を敷き詰めて作られたという事はわかりましたが、それだけではまだ遊びつくせなさそうです。まだどのように敷き詰めるかの手がかりがないからです。
ここで2つのエンブレムを見比べてみると、オリンピックは大きい正十二角形の外枠の中に小さい正十二角形の穴が空いている構造になっています。一方パラリンピックは正十二角形の上がポッカリ開いたような構造になっています。それぞれの穴がなければどちらも正十二角形をひし形で充填させた形ということで理解できそうです。
実際にやってみるとこの穴は同様のひし形で埋めることができます。
![fig2_5-05-05.tif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498495/1bd4d255-8afe-698f-7b63-50e92f0115c9.tiff)

#エンブレムの正体
というわけでエンブレムの正体は
・正十二角形を三種類のひし形で充填し、
・それぞれ何個かのひし形を取り除き、
・各ひし形の中点を結んでできた長方形
という事になります。
![fig2_6-04.tif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498495/3fa96d6b-f5f7-11ae-8453-f8d61f4b25f8.tiff)

エンブレムの正体が分かったところで今回はここまで！
次回はひし形を充填するという事についてさらに詳しく書いていきたいと思います。
[Node.js] express + nodemon + BrowserSync でゲボ楽コーディング

# はじめに
expressを使ってBrowserSyncを使う記事が少なかったので書きます。
nodemon + BrowserSyncでブラウザノータッチの楽々コーディングを目指そう。
# 方法
1. expres側ファイルをnodemonで監視(3000portで起動)
2. BrowserSync を 4000 番ポートで起動、nodemonに接続

これによりクライアント側のファイルはBrowserSyncでブラウザをリロード
nodemonによるサーバ再起動は、再起動後にBrowserSync に通知してもらえるようにする。
#前提
- node + expressは導入済み
- Nodeの側のポートは3000に指定 

# 導入
`browser-sync` のインストール

```
$ npm install --save-dev browser-sync
```

インストールが終わってからbrowser-syncのコンフィグファイルを生成

```
$ npx browser-sync init
```

`bs-config.js`が作られるので、以下のように一部を編集
プロキシを`http://localhost:3000`に指定することで連携可能。
今回はカスタムテンプレートにEJSを使用するために.ejsを指定しているが、適宜対応してください。

```bs-config.js
  "files": [
    "**/*.js",
    "**/*.ejs",
    "**/*.css"
  ],
~中略~
  "proxy": "http://localhost:3000",
  "port": 4000,
```

次に`nodemon`のインストール

```
$ npm install -g nodemon
```

ここまでくればあとはどちらも起動するだけで終わりだが、どうせならまとめて起動したい。
ここでひと手間を加える。

`npm-run-all`のインストール

```
$ npm install --save-dev npm-run-all
```

`package.json`の編集（抜粋）

```package.json
  "scripts": {
    "start": "npm-run-all --parallel start:*",
    "start:nodemon": "nodemon ./bin/www",
    "start:sync": "browser-sync start --config bs-config.js"
  },
```
あとは`npm start`で楽々開発。

# package.json の解説
動きますね！終わり！でもいいがnpm-run-allを使った記述が多少わかりずらいので解説

npm-run-allの詳しい挙動に関してはggってもらって・・・
npm-run-allはシーケンシャルとパラレルの二つの指定方法があります。

今回は`parallel`を指定しなければ、`nodemon` or `browser-sync` どちらかしか動きません。
`nodemon` も `browser-sync`も一度呼び出すと永続するので・・・

    "start": "npm-run-all --parallel←コレ　start:*",

`start:*`に関しては後ろ２行の：以下を表しています。

     "start:nodemon←コレ": "nodemon ./bin/www",
     "start:sync←コレモ": "browser-sync start --config bs-config.js"

他にもいろいろ応用できそう。

### 参考記事
- [browser-syncを使う](https://qiita.com/niki-tstk/items/83631b5c5517abbf0bc4)
- [gulp + node + express で BrowserSync 使おう](http://mid0111.hatenablog.com/entry/2015/08/19/200657)
- [npm run のスクリプトを連続実行・並列実行する (npm-run-all)](https://maku77.github.io/nodejs/npm/npm-run-all.html)
DBSAT 2.2のレポートを日本語化する

Oracle Database Security Assessment(略してDBSAT)は、Oracle Databaseのセキュリティ関連の設定をクイックに確認するOracle公式ツールです。
データベースのパッチ適用有無やユーザーアカウント、権限&ロール、暗号化や監査設定など約80項目をチェックし、レポーティング化してくれます。

使い方は、すでにまとめられているのが役に立ちますね。
[Oracle Databaseのセキュリティ上の問題点を探すDBSATを試す](https://qiita.com/plusultra/items/d391c85c561c6b346cbe)
[DBSATの新バージョンを試す(DBSAT 2.1.0)](https://qiita.com/plusultra/items/347d75858e5498f72660)

DBSATのレポートはすべて英語で出力されるのですが、すべて英語で読むのはなかなか骨が折れます。ということで、レポートをもう少し読みやすくするための日本語化パッチを作成しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/562423/73e85710-3838-0469-2310-d65abc2734c9.png)

ここでは、今一度、レポートを作成する簡単な手順と日本語化するためのパッチ適用について紹介します。
※日本語化パッチは、非公式ですのでご使用は自己責任でお願いします。

## DBSATの公式サイト
https://www.oracle.com/technetwork/jp/database/security/dbsat/downloads/index.html
Download Oracle Database Security Assessment Tool からdbsat.zipをダウンロードする

## DBSATの実行手順
以下は、Oracle Database Cloud ServiceのVMインスタンスで実行した例です

```
#dbsat.zipを実行したいOracle Databaseにコピーする
$ unzip dbsat.zip -d dbsat
$ cd dbsat
$ ls
Discover  dbsat.bat        sat_collector.sql  xlsxwriter
dbsat     sat_analysis.py  sat_reporter.py

#sat_reporter.pyをgithubにある日本語版sat_reporter.pyに置き換える
$ mv sat_reporter.py sat_reporter.py_orig
$ wget https://raw.githubusercontent.com/western24/DBSat2.2_JP/master/sat_reporter.py

#Collect実行 (MTA環境なのでPDBをターゲットに指定する。DBユーザーはSYSTEM)
$ ./dbsat collect system/password@x.x.x.x:1521/servicename pdb

#Report実行
./dbsat report pdb

最終的には、パスワード付きのpdb_report.zipが作成される
```

作成されるHTMLレポートの例は[こちら](https://raw.githubusercontent.com/western24/DBSat2.2_JP/master/pdb1_report.html)

長いレポートなので、漠然の読むよりもポイントを絞ったほうが良いように思います。
私は特に以下の点に気を付けて読みます。

・デフォルト・プロファイルが弱められている or Umilitedになっているものがないか
・アカウントロックが無効化になっていないか
・デフォルトパスワードの使用がないか
・把握できていないアカウント、ロールがないか
・SYS系、DBAロールの強い権限が意図せず付与されていないか
・SELECT ANY TABLE等の強い権限が個別アカウントに付与されていないか
・暗号化しているか
・監査設定の有無、何を対象にしているか

DBATの実行は既存環境への影響はなく、非常に簡単なので、一度実施することをお薦めします
React Nativeでapkをビルドする際に「Could not list contents of 〜」で困ってる人へ

<br>
### 困っていた人、まさに私です。（２回目）
１回目は[こちら](https://qiita.com/krile136/items/1d24dca5c85f2fdffb57)

# とりあえず（直るらしい）対処法
こちらの[記事](https://github.com/facebook/metro/issues/288)を参考に、まずはnode_modulesの再インストールをしましょう

~~~
$ pwd
// アプリのディレクトリにいることを確認（iOSとかandroidじゃダメよ）

$ rm -rf node_modules
// node_modulesを削除

$ npm install
// node_modulesをインストール
~~~
大抵はこれで治るみたいですね。
ただ、私の場合はダメでした。

# インストールの順番の問題
私が参加しているプロジェクトではyarnも使っています。
なのでnode_modulesをインストールしていたときには

~~~
$ npm install
$ yarn install
~~~
としていたのですが、どうもエラーに。
エラー内容はこちら
![error](https://gyazo.com/ee9eebcc7afc7978b318287365e385cb.png)

VScodeのターミナルで実行し、エラーが出ているファイルにカーソルを載せるとcmd+クリックで該当ファイルが開けるので開いてみると・・・

### なんと！空っぽ！

いやーそんなことはないだろうと思ってインストール順を逆にしてみる

~~~
$ yarn install
$ npm install
~~~

### ファイルの中身がちゃんとある・・・だと・・・？

無事ビルド通ってapkファイル書き出せましたv(^^
〇〇って何？シリーズ1-1：伝達関数

# はじめに
こんにちは，watawatavoltageです．今回から，シリーズ企画を始めます．その名も「〇〇って何？」シリーズです．このシリーズは，主に制御工学を学ぶうえでで重要となるキーワードをできるだけわかりやすく説明します．また執筆時には，掲載されているキーワードに関する書籍やサイトを確認せずに，すべてアドリブで説明します．なので，説明に誤りがある可能性があるかもしれません．その際には，ご指摘お願いします．
シリーズ1-1では伝達関数について紹介したいと思います．

# 伝達関数とは？

ラプラス変換領域における入力と出力の比のことです．あるシステム$G(s)$において，システム$G(s)$への入力を$U(s)$,システムの出力を$Y(s)$とすると，
$$Y(s)=G(s)U(s)$$とかけ，
$$G(s)=\frac{Y(s)}{U(s)}$$
となります．
このときの$G(s)$が伝達関数です．伝達関数は$s$の有理関数で表されます．
例えば，$G_{1}(s)=\frac{1}{s +1}$とか$G_{2}(s)=\frac{s^2 + 4s + 5}{s^2 + 3s + 2}$みたいに表現されます．伝達関数表現はシステムのモデリングによく使われます．具体的に言えば，伝達関数の中身をみるだけで，システムの挙動が大体わかります．

# おわりに

今回は，伝達関数について説明しました．すごくざっくりとした説明なので，興味を持たれた方は，ほかの資料や教科書とかで学ぶと良いでしょう．また，コメント欄でも感想，アドバイスなどお待ちしています．
Dockerhubのオートビルドで環境変数を使う方法

Dockerhubのオートビルドでは、プロジェクト固有の環境変数を使うことができます。ただ、設定が結大変だったので、忘備録も兼ねてまとめます。オートビルドで環境変数を使うために必要な工程は、以下の3つです。

1. BUILD ENVIRONMENT VARIABLES
2. hooks/build
3. Dockerfile ARG

#サンプルコード
以下が今回の解説に使うソースコード、Dockerリポジトリです。

ソースコード
https://github.com/kaidouji85/study-three-js

Dockerリポジトリ
https://hub.docker.com/r/kaidouji85/gbraver-burst

このコードは私が趣味で作っている[ゲーム](https://gbraver-burst.com)ですが、遊び方説明動画としてYouTubeを埋め込んでいます。YouTubeのURLをハードコーディングするのも気が引けたので、```HOW_TO_PLAY_URL```という環境変数で設定を外出し出来るようにしました。

#環境変数設定方法
##1. BUILD ENVIRONMENT VARIABLES

<img width="1216" alt="スクリーンショット 2020-03-26 12.07.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26979/189cd2c2-75ad-23a0-181a-689a019a9bcf.png">

dockerhubのオートビルド設定画面を開くと、「BUILD ENVIRONMENT VARIABLES」という項目があります。「Key」に環境変数名、「Value」にその値をセットします。これだけで環境変数が使えそうですが、そうは問屋が卸しません。

##2. hooks/build
[Dockerhub公式サイト](https://docs.docker.com/docker-hub/builds/#environment-variables-for-builds)にさりげなく書いてありますが、前節で設定した項目は```hooks```フォルダ配下のシェルでしか使えません。なので、以下内容でgitリポジトリに```hooks/build```というファイルを追加します。

```sh:hooks/build
#!/bin/bash

docker build -t $IMAGE_NAME --build-arg <環境変数名>=$<環境変数名> . 
```

[サンプルプロジェクト](https://github.com/kaidouji85/study-three-js/blob/master/hooks/build)では、```hooks/build```に以下内容を記載しました。

```sh:サンプルコード
#!/bin/bash

docker build -t $IMAGE_NAME --build-arg HOW_TO_PLAY_URL=$HOW_TO_PLAY_URL .
```

ちなみに複数環境変数を渡したい場合は、面倒臭いですが以下のように書きます。

```sh:環境変数複数指定
docker build -t $IMAGE_NAME --build-arg VAL1=$VAL1 --build-arg VAL2=$VAL2 --build-arg VAL3=$VAL3 .
```

ここから先は踏み込んだ説明なので、やり方だけ知りたいという方は読み飛ばしてください。```hooks/build```はユーザ独自のDockerビルドコマンドを実行したい時に使うシェルです。Dockerビルドに環境変数を渡すやり方は色々あると思いますが、ここでは一般的な方法である```--build-arg```を使っています。また、```$IMAGE_NAME```はdockerhubが予め用意している環境変数名で、dockerイメージ名がセットされます。[dockerhub公式サイト](https://docs.docker.com/docker-hub/builds/advanced/#environment-variables-for-building-and-testing)を見ると、これ以外にも様々な環境変数が事前定義されているようです。

## 3. ARG
以下のように、Dockerfileに```ARG```という項目を追加します。

```dockerfile:Dockerfile
ARG 環境変数名
```

以下が、[サンプルコード](https://github.com/kaidouji85/study-three-js/blob/master/Dockerfile)のDockerfileです。2行目に「ARG」という記載があります。

```dockerfile:サンプルコード
FROM node:12.16.1-slim as builder
ARG HOW_TO_PLAY_URL
WORKDIR /usr/src/app
COPY . /usr/src/app/
RUN npm config set registry http://registry.npmjs.org/ && \
  npm ci && \
  npm run build:production

FROM node:12.16.1-slim as runner
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/ /usr/src/app/
CMD [ "npm", "run", "serve" ]
EXPOSE 3000
```

ちなみにですが、```ARG```とは```--build-arg```で渡された環境変数をDockerfileで使えるようにするための命令です。なので```--build-arg```だけを指定しも、環境変数の受け渡しはできません。
【Charles】スマホでwebページにアクセスできなかった話

# はじめに
スマホの通信をキャッチしたくなったのでCharlesを始めてみようとした時に起きた出来事。

PCとスマホを同じWi-Fiに繋いでプロキシの設定をし証明書をダウンロードしようとしたところ、webページにアクセスできなくなった。

#原因
Wi-Fiの設定がパブリックでスマホからPCを認識できていなかった。
設定をプライベートに直したところうまく繋がった。

#最後に
パブリックのほうが隠されるっていうから安全な感じするじゃん。
それでパブリックのほうがいいと思って選んでたけどこんな罠があったとは。
react-bootstrapでWarning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>

react-bootstrapでこのエラーに遭遇して対処法を調べたのですが日本語の記事が少なくて解決に時間がかかったのでメモとして残しておきます。
# エラーの原因
コンソールには以下のエラーが出力されます

```
Warning: validateDOMNesting(...): <div> cannot appear as a descendant of <p>.
```

原因がわからずググってみたら、[このサイト](https://kenjimorita.jp/reactredux-warning-js36-warning-validatedomnesting-cannot-appear-as-a-descendant-of-see-counter-p-div/)によると`<div>`タグを`<p>`タグでラップしているとこのエラーが起こるようです。
しかし、`<p>`タグを使っている箇所がない、、、

# 解決策
原因となっていたのは以下のコードでした

```tsx

              <Card.Text>
              <Row style={{ clear: "both" }}>
                <SelectButton 
                  isSelected={selectedPictureList.includes(picture)}
                  target={picture}
                  selectedFunc={selectPicture}
                  unselectedFunc={unselectPicture}
                />
                <PicturesCommentNewContainer pictureId={picture.id} />
              </Row>

              </Card.Text>
```

[こちらのサイト](https://www.gitmemory.com/issue/reactstrap/reactstrap/1611/527485530)によると、`<Card.text>`の出力は`<p>`タグになってしまうそうです。
その中のコンポーネント(`PicturesCommentNewContainer`)で`div`タグを返す処理をしていたので、エラーが起こっていたみたいですね...

```tsx

              <Row style={{ clear: "both" }}>
                <SelectButton 
                  isSelected={selectedPictureList.includes(picture)}
                  target={picture}
                  selectedFunc={selectPicture}
                  unselectedFunc={unselectPicture}
                />
                <PicturesCommentNewContainer pictureId={picture.id} />
              </Row>
```

このように、単純に`<Card.Text>`を使わなければエラーは無事なくなりました
bootstrapめんどい！
自分用メモ

# aws configureの読み込み
````
export AWS_CONFIG_FILE="ファイル"
````

# instance ID 取得
```
INSID=`ssh サーバ 'curl http://169.254.169.254/latest/meta-data/instance-id/'`
```

# 再起動しないでAMIを取得して、結果をファイルに吐き出す
```
aws ec2 --region ap-northeast-1 \
 create-image --instance-id インスタンスID \
 --name AMIのタグName-$(date +%Y-%m-%d_%H%M%S) \
 --description 'created by '$(date +%Y-%m-%d_%H%M%S) \
 --no-reboot
```

# 作成したAMIのNameタグに名前入れる
```
aws ec2 create-tags --resources AMIID --tags Key=Name,Value=TAGにつける名前-$(date +%Y-%m-%d_%H%M%S)
```
1行で素数列挙

# はじめに
ふと思いつきで1行で素数を求めるプログラムを書いてみました。効率ではなくコード量重視。

# Ruby

`filter` かと思ったら Range の場合 `select` なんですね。(Ruby 2.5)

```ruby
(2..99).select {|x| (2...x).select {|i| x % i == 0} == []}
```

# Python

`filter` でもいいけれどリスト内包表記の方がすっきり書けます。

```python
[x for x in range(2, 100) if [i for i in range(2, x) if x % i == 0] == []]
```

# Haskell

Haskell は何年たっても勉強中の初心者から抜け出せません。

```haskell
[x | x <- [2..100], [i | i <- [2..(x - 1)], mod x i == 0] == []]
```

# まとめ
リスト内包表記ができないRubyが不利かと思ったら、意外なことにぼくが書いた中では一番短かった。
aws-sdk-php-laravelを利用してファイルアップロード

#aws-sdk-php-laravelとは

[AWS SDK for PHP](https://aws.amazon.com/jp/sdk-for-php/)をlaravelのために使いやすくしたもの

(そもそもAWS SDKとはawsのサービスを使いやすくするソフトウェア開発キットのこと)

#インストール

###aws-sdk-php-laravelをインストールする


######composer.jsonに書く
composerを通じてインストールします

```php:composer.json

{
    "require": {
        "aws/aws-sdk-php-laravel": "~3.0"
    }
}
```

######composer update 
conposer updateを実行する

```
$ composer update
```

######config/app.php

config/app.phpにAWS Service Providerを追加します

`'providers'`と下の方にある`'aliases'`に下のように追加してください

```php:config/app.php
  'providers' => array(
        // ...
        Aws\Laravel\AwsServiceProvider::class,
    )

'aliases' => array(
        // ...
        'AWS' => Aws\Laravel\AwsFacade::class,
    )

```

#設定

######環境変数

デフォルトでは、これらの環境変数が使われます。

```php:.env
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_REGION (default = us-east-1)
```
環境変数の設定方法はこれをみてもらったら早いと思います。
https://qiita.com/tiwu_official/items/ecb115a92ebfebf6a92f


**AWS_DEFAULT_REGION**名前は**AWS_REGION**に変更します。




######aws.config

.envで設定した環境変数はこんな感じで使われてるよーって

```php:aws.config
return [
    'credentials' => [
        'key'    => env('AWS_ACCESS_KEY_ID', ''),
        'secret' => env('AWS_SECRET_ACCESS_KEY', ''),
    ],
    'region' => env('AWS_REGION', 'us-east-1'),
    'version' => 'latest',
    
    // You can override settings for specific services
    'Ses' => [
        'region' => 'us-east-1',
    ],
];
```

#使い方

######画像をアップロード


```php
$s3 = App::make('aws')->createClient('s3');
$s3->putObject(array(
    'Bucket'     => 'YOUR_BUCKET', #s3で登録したbucketの名前
    'Key'        => 'YOUR_OBJECT_KEY', #登録したいファイルの名前
    'SourceFile' => '/the/path/to/the/file/you/are/uploading.ext', #登録したいファイル
));
```

これで画像をアップロードすることができる。


######画像を表示

```php
$s3 = App::make('aws')->createClient('s3');

$key = 'YOUR_OBJECT_KEY'; #取得したいファイルの名前
$bucket = env('AWS_BUCKET'); #bucketの名前

$image = $s3->getObjectUrl($bucket, $key); #getObjectUrlでurlを取得
```

これでviewに表示できます。

#参考
公式のgithub(ほぼこれの日本語訳です)
https://github.com/aws/aws-sdk-php-laravel/blob/master/README.md

超簡単！LaravelでS3を利用する手順
https://qiita.com/tiwu_official/items/ecb115a92ebfebf6a92f
KibanaのCoordinate MapとRegion Mapを使ってみた

# 目的
- 使ったことがないので使ってみたかった
- 位置情報を持っているデータを扱うのが初めてなので
- 役に立ちそう

# マッピング

ホテルの位置情報を入れた。

`Coordinate Map`を使用するために`location`に位置情報、
`Region Map`を使用するために`prefecture`に都道府県を入れた。

```json
{
  "mappings": {
    "properties": {
      "hotel": {
        "properties": {
          "address": {
            "properties": {
              "prefecture": {
                "type": "keyword"
              },
              "location": {
                "type": "geo_point"
              }
            }
          }
        }
      }
    }
  }
}
```

# Kibanaでの準備
インデックスを作成し、データを入れたらKibanaの設定をする。

まず、Kibanaのメニューの歯車を押して`Index Pattern`を作成する。
今回使用するインデックスは`testing-hotels-demo`のみなので以下のように設定。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/542227ff-fa09-78c0-1afa-de699f2fe3af.png)

また、インデックスに時間の情報を入れていないので`I don't want to use the Time Filter`を選択する。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/58248380-5c50-3af9-ec22-01dc3cb7769c.png)

# Coordinate Map
メニューからVisualizeを選び`Create a visualization`をクリック。
`Coordinate Map`をクリックしたら先ほど作成した`testisg-hotels-demo`を選択する。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/01bc3965-c560-4e04-e1cc-005759cedaa5.png)

位置情報が入っているフィールドを設定する。今回の場合は`hotel.address.location`。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/321c4115-56d4-aacd-6f2a-ad6fa2f5b958.png)

設定後、三角マークを押すと以下のようにホテルがどこに集中しているかわかる。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/7abca6c8-5a8d-48ef-f248-1ccef9905cd3.png)

拡大図。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/5053dba4-5635-1a30-4b56-297e79ed656f.png)


# Region Map
メニューからVisualizeを選び`Create a visualization`をクリック。
`Region Map`をクリックしたら先ほど作成した`testisg-hotels-demo`を選択する。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/e06a243e-870e-0e9e-ff01-b3bf530019ea.png)

Aggregationの設定をする。
Dataのタブでフィールドに`hotel.address.prefecture`を指定し、トップ20を出力する設定にする。
今回の都道府県は日本語で入れたのでOptionsのタブで`Japan Prefectures`の`name (ja)`を指定する。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/52b45b91-a157-5dc9-e0ce-e9cefbe2b579.png)![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/2b1a9fc7-4750-3416-53cb-df2a6be14684.png)

設定後、三角マークを押すと以下のようにホテルが多い都道府県トップ20が表示される。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/36ffe6b3-b489-321c-3bcb-3451e0158e3b.png)

逆のホテルが少ない都道府県トップ5。
![Kibana.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74899/a5235e30-aade-57c7-1c52-e00799215670.png)
チャット BOT に必要な機能を考えてみた

## チャット BOT の動き

基本的にチャット BOT って

1. 定期的にメッセージを送る
2. トークされたら自動応答する
3. ボタンを押したり特定のメッセージを送ると必要な情報をくれる

の３パターンですよね（たぶん）

ってことは必要な機能としては

- API を利用するためのトークン認証
- ユーザへのプッシュトーク
- メッセージの受信
- 受信したメッセージに応じた処理
    - ユーザへのリプライ
    - DB や WEB への情報検索
    - DB 等へのデータ登録

ミニマムでこんなところでしょうか？('ω')
なんか、今更当たり前な感じですね。

## LINEWORKS トーク BOT で考えてみた

なんで LINEWORKS トーク BOT かと言いますと、まぁ、私が業務でお世話になっているのと、LINEWORKS は無料のフリープランでもトーク BOT API がいじれるのでおススメしやすいっていうのがあります。(*´Д｀)

それと、前にこんな記事を書いていまして。
[GoogleAppsScript で LINEWORKS のチャット BOT を作る](https://qiita.com/kunihiros/items/a94221ad7c9f4de84cf8)

そのとき、GoogleAppsScript のライブラリを作ったのですが、全然更新していないのですよ。
なので、ライブラリを充実させようと思ったのですよ！('◇')ゞ

GoogleAppsScript ライブラリ名：`LINEWORKS`
script id：`1aLcCr3CWqfenPMyM0_FWIDUgRcTxsit9bO6BTx61NCXrCtkY2zbHBlod`

先ほどのミニマムな機能に照らし合わせると

- [API を利用するためのトークン認証](https://developers.worksmobile.com/jp/document/1002002?lang=ja)（実装しているが独立していない）
- [ユーザへのプッシュトーク](https://developers.worksmobile.com/jp/document/1005008?lang=ja)（一部実装）
- [メッセージの受信](https://developers.worksmobile.com/jp/document/1005009?lang=ja)（ライブラリの範囲外）
- 受信したメッセージに応じた処理
    - [ユーザへのリプライ](https://developers.worksmobile.com/jp/document/1005008?lang=ja)（一部実装）
    - DB や WEB への情報検索（未実装）
    - DB 等へのデータ登録（一部実装）

と、こんな感じでした！

DB や WEB への情報検索やデータ登録は環境によっても異なるのでしょうが、GoogleSpreadSheet か [LINEWORKS の組織連携 API](https://developers.worksmobile.com/jp/document/100300101?lang=ja) を使ってやる感じになりますかねー。

やっぱり「チャット BOT」というのはあくまで道具や手段のひとつで、『何をしたいか』によって作り方も機能も全然変わってきますね。
共通している基本機能なんて、受信して、送信するくらいなものです( ﾟДﾟ)

#おわりに

わかっていたことの再確認な感じになりました。
でも、少し整理がついて次やることが明確になって気がします。

頑張ってライブラリ増やそう～っと。
ではまた！(^^)/

#参考にさせていただきましたm(_ _)m

[GoogleAppsScript 公式サイト](https://developers.google.com/apps-script/reference/)
[LINEWORKS API 公式サイト](https://developers.worksmobile.com/jp/document?lang=ja)
はじめてのQiita（入門編）

##Qiitaの読み方（大事）

Qiita…**キータ**

✗　チータ
✗　クイータ
✗　オーイタ

→呼び方を間違えると恥ずかしいし見下される（気がする）。
→注意してもらえる立場じゃない場合、永遠に陰で笑われる（気がする）。

もう一度口に出して覚えましょう　**聞いた**　です。

##Qiitaとは？

表向きは、

プログラマ向けのブログです。

そして、プログラミングに関する知識を記録・共有するためのサービスです。

実際には、

集中力が切れたときに、仕事したくないときに開くとと時間が瞬く間に過ぎ去る嬉しいサービスです（雇われなら）。

##Qiitaのヒエラルキーは？

- ユーザーランキング上位者
- トレンド上位者
- LGMTを多く集めるひと

ピラミッドの上位にいけば、講演会の依頼や本の出版ができる（かもしれない）。

##LGMTって何？

≒　いいね！

##LGMTの読み方

~~LGMT（Looks Good To Me）…エルジーエムティー~~ 

**いいね！**


##なぜQiitaをやるべきなのか？３つの理由##

###【理由１】記事を書くことで自己成長につながるから。###

記事を書くことは、アウトプットです。

圧倒的に成果を出し続ける人は決まってインプットよりアウトプットを重視しています。

アウトプットしないひと（インプットのみ）は損しています。

逆にアウトプットできているひとは、実際の能力より高く評価される傾向があります。


###【理由２】転職や面接のときに有利なるから（ただしネガティブな記事がない場合に限る）。###

自称プログラマーを何人も見てきました。

できないひと、いきなりとぶひと。

まさに玉石混合です。

残念ながら面接の履歴書だけでは相手を判断する十分な材料ではありません。

そんなときに、実績紹介としてQiitaのような投稿や実績はプラス評価につながります。

プログラマとしての能力だけではなく、面接をスムーズに進める材料を持ってくる、その気遣いに企業側は評価をするのです。

補足ですが、

私は面接終了後に、履歴書からFacebook、Twitter、などSNSからより深い情報を調べます。

面接では誰だって良い顔をするもので、相手のネガティブな面はあまり見えてきません。

素の部分がでるSNSの内容で、あまりにもネガティブな内容や批評が多い人は雇わないようにしています。




###【理由３】他の人に施すことができるから。###

経験から、ノウハウを出し惜しむひとは長い目でみると損している気がします。

それはなぜか？

おそらく彼らは、自己の利益を優先し、他者に利益を共有しないからです。

いつの時代も利己主義者にひとはついていかないのです。

能力があるのに発揮できないひとを数多くみてきました。

残念ながらひととしての魅力がなかったのでしょう。

情けは人の為ならず巡り巡って己が為。
Vagrant での sftp 接続

# Vagrant で sftp 接続するには

[前の記事](https://qiita.com/hotate_chan/items/1c5f754838593af2ad5a)でVagrantについてあれこれと書きましたが、久しぶりに新規でゲストOSを設定しようとしたところ
sftp接続ではまってしまったので備忘のためにこれを書きます。


## sftp がつながらない・・・
CentOS をインストールしたが sftp がつながらない。
SSH 接続は出来るけれど sftp がつながらない。

グーグル先生に聞いて `/etc/ssh/sshd_config` の設定を変えたりしてみたけど sftp がつながらない。

もういっか、あきらめよう、と思ってたところに **ポートは空いてますか** という某質問サイトに書き込みが・・・・

### sftp というものを正しく理解していなかった
[Wikipedia](https://ja.wikipedia.org/wiki/SSH_File_Transfer_Protocol) より
#### SSH File Transfer Protocol

SSH File Transfer Protocol(SFTP)は、信頼性の高いデータストリーム（英語版）上でのファイル転送やファイル管理を提供する通信プロトコルである。Internet Engineering Task Force(IETF)によって　～～～ snip ～～～　**SSHなどのセキュアな通信路**で実行されること

あれ？？SSHは繋がってるのにな・・・

## 結論
Vagrant のデフォルトのSSH用ポートは `2222` です！
`$ vagrant ssh-config`

```
Host default
HostName 127.0.0.1
User vagrant
Port 2222
UserKnownHostsFile /dev/null
~~ snip ~~
```

sftp 用ソフトの設定でポートを `2222` に設定したらサクッと繋がりましたとさ_(┐「ε:)_
GoogleAppEngineでGoogleDomains利用

# 概要

* GoogleDomainsで取得したドメインをAppEngineで利用したい
* さらにAppEngineでSSL証明書を実装したい
* 過去に購入についての投稿
[GoogleDomains購入・設定](https://qiita.com/ezaqiita/items/273fa46f7530836fe259)
* DNSはGoogleDomainsのDNSを使う前提で記載しています
* CloudDNSを使う場合は別途公式マニュアルなど確認してください

# 詳細

## ドメイン購入

* ワイルドカード対応確認。
* 「*.」は入力しなくてよいらしい

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/1595c7c4-0505-66a6-6cd1-4dfa585219a8.png">

* カートに進む

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/50ca4217-cd36-670a-c1e0-66de8ea22da2.png">

* お客様情報を入力

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/4491283d-d792-93e4-2a0a-d4031fc7b629.png">

* 支払い情報を入力

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/a26080e9-67d8-a081-75a0-b388d9147203.png">

* GoogleDomainsに遷移し、管理画面に購入したドメインが表示される

* メールアドレスが正しいことを確認するメールが届いている
* 「メールアドレスを確認」をクリック

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/b29f7d93-90f6-8cfb-4c76-810be7e2785c.png">


## AppEngineカスタムドメイン設定

* 「設定」→「カスタムドメイン」→「カスタムドメインを追加」を選択

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/73688955-5017-a6be-c631-5bb626ae534e.png">

* GoogleDomainsで購入したドメインがプルダウンに表示されている

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/75cff142-6de6-4431-360d-0ec4c571b98c.png">

* サブドメイン付きアドレスが必要な場合はこのように「hoge.huga.com」のような形式で登録する
* マッピングを選択

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/76d9d504-5f94-aab0-59d2-8a653800a9a9.png">

* マッピングが完了すると以下の様になる

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/c3d2af86-52c1-4628-5266-cf874932d44b.png">

* DNSレコードを控えておく

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/4e44286b-6e2b-8a03-7a4a-eb97b05d265b.png">

* カスタムリソースレコードのページへ
* 先程控えたDNSレコードを入力
* サブドメイン付きのレコードはCNAMEで登録

<img width="50%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/17852423-5b7f-9f03-be58-60624e204137.png">

* 以下のように登録される
* この時点で既にSSL証明書は有効になっている
* 有効になるまで1時間くらいかかることもある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57350/bac290b6-932e-13b7-eb6b-44a9e2a6ab5f.png)

## サービスとカスタムドメインを紐付ける

* 以下のようにdispatch.yamlを作成しserviceと紐付けデプロイする
* 「url: "hoge.huga.com/*"」の*は必要だったりするので注意

```
$ cat dispatch.yaml
dispatch:
  - url: "hoge.com/*"
    service: production-service
```

## サブドメインごとに分けたい場合

* 以下のようにdispatch.yaml内で分ける

```
dispatch:
  - url: "hoge.com/*"
    service: production-service

  - url: "www.hoge.com/*"
    service: production-service

  - url: "stg.hoge.com/*"
    service: staging-service
```

* dispatch.yamlを指定してデプロイする
* app.yamlをデプロイしても有効にならないので注意


```
$ gcloud app deploy dispatch.yaml --project [project]
Configurations to update:

descriptor:      [/home/***/***/dispatch.yaml]
type:            [routing rules]
target project:  [project]


Do you want to continue (Y/n)?  Y

Updating config [dispatch]...done.

Custom routings have been updated.
```
Docker のキャッシュデータすべて消しさり、葬り去り、抹消して、スッキリするコマンド

### デバッグしてるけど、間違っているコードが見当たらない。。そこまで修正して手詰まりになったとき、次に疑うのはDockerの仕様です。

あれこれやって、行き詰ったときは

視点を変えて、「根本的なところが原因かもしれない」という考えから

もしかすると、書き換えたコードが反映されていないかもしれないので
きれいさっぱり削除して、再度ビルドしてみましょう。

（きれいさっぱり削除するので、このコマンドの後のビルドは時間がかかります）

```qiita:ターミナル
docker-compose down --rmi all --volumes
docker-compose up -d --build
```

これでも解決しないとき、

自分のコードが間違っています( ；∀；)
焦点を絞るところが明確になったので、やる気出ますねｗ
トラブル事案｜dockerでWordPressを動かしたらlocalhost が転送される事態になった件

localhostへアクセスした際に強制的リダイレクトされて困っている、という方がいらっしゃったら、ご一読いただければと思います。

# 私の場合は...
`localhost`へアクセスしたら`localhost:8080`へ転送されてしまう事象が発生しました。
転送されてしまう前後の行動を思い返しましたところ、**dokerでWordPressを立ち上げる**ことをしておりました。
ただし、転送されてしまう事象が起きた際は、**dokerは停止**しておりました。

# 原因はブラウザのキャッシュ
原因はブラウザのキャッシュでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/17931680-ad55-0ce6-c55b-0b8e374a5cec.png)

ブラウザの開発者ツールのネットワークを確認したところ、301リダイレクト（恒久的な転送）状態になっておりました。

# どうしたか
ブラウザのキャッシュを削除したところ、解決しました。
なおChromeの場合、開発者ツールのネットワークに`Disable cache`（キャッシュの無効化）というオプションがあります。これにチェックをつけたままリロードしたら、転送されなくなりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/283603/236da5cc-8ec4-c7c6-4241-a3ddf4e251e1.png)

# なんで301になったのか
きっとWordPressのせいだと思っています。
dokerでWordPressを起動した際に、WordPressが301のタネをブラウザに仕込んだのかと...

でも、きっとWordPressにとっては大切な機能の一つなんだと思います。

# 学んだこと

* 意図せずに転送されるときは、開発者ツールのネットワークを確認すること（私の先生の教え）
* ローカルでdockerで何かするときは、開発者ツールのネットワークで`Disable cache`をONにした方がいいかもしれない（特にWordPressの場合。もちろんキャッシュを必要としない場合に）
* WordPressはリダイレクトのタネをブラウザに埋め込む

# あとがき
この事象が発生した際、

* ChromeとFireFoxの両方で発生
* dokerは停止中

だったため、ブラウザやdockerが原因である可能性を排除していました。
「ローカル環境の設定に何かしてしまった」「hosts絡み？」とかを考え、「localhost 転送」とか「localhost リダイレクト」とかでググりまくりました（結局、自力解決できず、先生に相談...）

まさか、ブラウザのキャッシュが原因とは...
（ChromeとFireFoxの両方でWordPressを開いた記憶はあります）

**意図しない転送があった場合は、ブラウザのキャッシュも疑ってみて**をお伝えしたく本記事の執筆に至ります。
お役に立てれば幸いです。
URLからパラメータを取得して活用する方法

##目的
URLに設定されてたパラメータを利用できるように配列として取得する。
JQueryは不要。

####コード
```parameter.js
    let param;
    let param_split;
    if(window.location.search){
        param = window.location.search.substring(1,window.location.search.length)
        param_split = param.split("&");
    }
```

####解説
```parameter.js
    //変数宣言
    let param
    let param_split;

    //URLにパラメータが存在する場合
    if(window.location.search){
        //URL内のパラメータを取得(substring(1,~~~)の1はパラメータの最初の文字から1文字目
        param = window.location.search.substring(1,window.location.length);
        //取得したパラメータを&区切りで配列に代入
        param_split = param.split("&");
    }
```
SMS環境構築_Storage Classの設定

本記事はSMS環境構築する際、Storage Classの設定手順を紹介しています。

関連記事は以下を参照してください
1. [事前作業](https://qiita.com/ztc2019/items/78afebb96ad930ccec80)
2. [Storage Classの設定(本記事)](https://qiita.com/ztc2019/items/ae9e322e8400c5743b98)
3. [Storage Groupの設定](https://qiita.com/ztc2019/items/6c6b8ca73b7e65378dbc)
4. [ACS Routineの設定&定義反映](https://qiita.com/ztc2019/items/249b84bf485dbc9a8058)


# Storage Classの定義(1/4)
- ISMF PRIMARY OPTION MENUから5のStorage Classを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/2a7bf8b5-e88a-0f61-a75b-d676718e23c5.png)

# Storage Classの定義(2/4)
- SCDS名とStorage Class名を入力して、3のDEFINEを行う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/1fa2d6fe-f5dc-0db3-9942-5b1543dc4204.png)

# Storage Classの定義(3/4)
- 検証での定義内容は以下のとおり(descriptionは任意で記入）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/bdc0bc50-7ff1-74ec-8395-ea58e0f4a692.png)

# Storage Classの定義(4/4)
- 各パラメータは環境に応じて変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/800269ab-d564-2d98-45dc-646207db3a04.png)
- パラメータ入力後そのままenter

# Strage Crass定義の削除の方法
- メニュー”5 Storage Class”を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/7e98bca0-d0b9-0c20-f9bf-ba4a6b22db7b.png)

- CDS名、クラス名を選択し、オプション#1 List を選択
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/acacb776-821b-86bb-0d20-71224d9de23f.png)

- LINE OPERATORへ”DELETE”を入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/a67eec8c-14c8-564e-f0a0-6875d4feb44d.png)

- “/” を入力して実行。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/ab86d90e-1f72-fbc0-1f03-bd4b8be969b0.png)

- クラスが削除されたことが確認できる
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/e4f77f68-d9f9-7059-4ab6-1dfb390222db.png)


***
次は[Storage Groupの設定](https://qiita.com/ztc2019/items/6c6b8ca73b7e65378dbc)を参照してください。
日本語力

知れば楽しくなることばのお話。間違いやすい日本語、意外な語源、うつくしい季節のことばなどをわかりやすく解説。
あなたの日本語力を高めます。

https://japanknowledge.com/articles/blognihongo/archive.html

はっかく
【発覚】
《名・ス自》隠していたことなどが、現れ出ること。ばれること。


まずは以下の文章をお読みいただきたい。

　「歯みがきしてない犬の多くは８歳頃に、深刻な症状が発覚する。」（西川文二『イヌのホンネ』2015年）

　注目していただきたいのは、文中に使われている「発覚」という語である。この「発覚」の使い方に違和感をもったという人は、かなりいるかもしれない。
　「発覚」は、例えば『日本国語大辞典（日国）』によると、「かくしていた秘密や罪悪、陰謀などがあらわれること。露顕。暴露。」という意味である。そして、そこに引用されている用例は、平安後期の説話文学『江談抄（ごうだんしょう）』（1111年頃）のものが最も古い。

　「致忠男保輔 保昌、兄也 是強盗主也。事発覚繋獄之後」（三）

というもので、「致忠（むねただ）の男児の保輔（やすすけ）〔保昌の兄である〕は、強盗の首領である。事件が「発覚」して獄につながれた後に」という意味だ。この例もそうだが、『日国』で引用されている他の2例、小栗風葉の『青春』（1905～06年）も長塚節（ながつかたかし）の『土』（1910年）も、「小児を山林の奥で獣類同様に育てた」とか、「悪事」とかいった、隠していたよくないことがあらわれるという意味で使われている。
　ところが、冒頭の引用文にある「発覚」はどうだろうか。犬に何か症状が現れるということで、それは深刻なものなのかもしれないが、秘密や罪悪、陰謀があらわれるわけではない。

　「発覚」の「発」は、あばくで、隠れたものごとを表にだすという意味、「覚」は人に気づかれるという意味である。そして「発覚」で、隠していたよくないことがばれてしまうということが本来の意味なのである。

　従って、小型の国語辞典のほとんどは、『日国』同様、隠しごとや悪だくみなどがあらわれることという意味にしている。
　ところが最近、スポーツ紙や週刊誌などで、「熱愛（交際）が発覚」などと書かれた記事をよく見かける。当人達にしてみればそれらは隠そうとしていたことなのかもしれないが、別によくないことでも悪事でもないだろう。これが「不倫」だと違うかもしれないが。

　このような使用例があるからだろう、『明鏡国語辞典　第２版』には、「隠してもいない事柄（特に吉事）に使うのは誤り。『×妊娠［婚約・誕生］が発覚』」とかなり踏み込んだ内容の注がある。確かに、「妊娠・婚約・誕生」は従来「発覚」と一緒に使われなかった語なので、本来の言い方ではない。だが、「誤り」と言い切れるかということになると、いささか疑問がある。ことばの意味が本来のものとは異なるものに変化していくのはよくあること。「発覚」のこの新しい意味がさらに広まる可能性は否定できないのである。好むと好まざるとにかかわらず、辞書ではそれに合わせて、語釈の内容を変えていかなければならない語なのかもしれない。
SMS環境構築_事前作業

本記事はSMS環境構築する際、事前作業の手順を紹介しています。

関連記事は以下を参照してください
1. [事前作業(本記事)](https://qiita.com/ztc2019/items/78afebb96ad930ccec80)
2. [Storage Classの設定](https://qiita.com/ztc2019/items/ae9e322e8400c5743b98)
3. [Storage Groupの設定](https://qiita.com/ztc2019/items/6c6b8ca73b7e65378dbc)
4. [ACS Routineの設定&定義反映](https://qiita.com/ztc2019/items/249b84bf485dbc9a8058)

# SMS用Volumeの初期化

- STGRのオプションを指定してVolの初期化 

```
//ICKINIT JOB MSGCLASS=X,CLASS=A,NOTIFY=&SYSUID                  
//INIT1   EXEC PGM=ICKDSF,REGION=4096K                           
//SYSPRINT DD  SYSOUT=*                                          
//SYSIN    DD  *                                                 
  INIT UNIT(xxxx)             
       PURGE -                                                   
       NOVERIFY -                                                
       DEVTYPE(3390) -                                           
       STGR -                                                    
       VOLID(XXXXX)          
       INDEX(0,1,2) -                                            
       VTOC(0,3,12)                                              
/*                                                               
//     
```

# ISMFを管理者モードに変更
- ISMFの初期設定は、エンドユーザー・モード（EU）に設定されているので、これを管理者モード（SA）に変更する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/74c6cde6-365c-5f70-fb20-26f56c318abf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/06bd0645-e373-86e1-75fb-a388fb385fd5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551954/d889490f-0f9f-42a8-fa48-54830b8ea783.png)

引き続きは[Storage classの定義](https://qiita.com/ztc2019/items/ae9e322e8400c5743b98)を行う。
Python フォルダの作成 既存かチェックあり

##背景
Pythonでフォルダ作成のプログラミングコードはたくさんありますが、
念のため備忘録を作成します。

##サンプルコード

フォルダを作成することはできますが、
そのフォルダが既存だとエラーが出ます。
ifを使って回避します。


```python:make_folder.py
import os

new_path = "demo_folder"#フォルダ名
if not os.path.exists(new_path):#ディレクトリがなかったら
    os.mkdir(new_path)#作成したいフォルダ名を作成
```

##結果
1回目に実行したら、フォルダが作成されます。
2回目に実行したら、すでにフォルダが作成されているため何も起こりません。
Androidアプリの審査に時間がかかるらしいが...@GooglePlayConsole

現在、流行りのコロ助の影響で時間がかかるのだろうか。。
![GooglePlayConsole_longer_than_usual.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152641/0de7a657-b3a3-3cf4-d4d8-29c96b39b2cb.png)

7日以上って、、まあ仕方がないと思いつつリリースしてみると普段通りだった。
内部テストに一日前に上げてから製品版にプロモートする手順でいつも通りリリースしたが、プロモート後、20分ぐらいで公開されたみたい。

Androidアプリってほんとうに審査しているんですかね。
WSL Ubuntu18.04でDockerが起動しない

(2020.3.29) 
そもそもWSL上にdockerを導入することが難しいとのこと。
2020年5月にリリースされるWSL2にはDockerを構築することができるということなのでそちらを待ちます。


~~[前回の記事](https://qiita.com/Jazuma/items/c7fea773a4f9544eb001)でUbuntu18.04にDockerをインストールしたところ、次のようなエラーが発生した。~~

~~```
Cannot connect to the Docker daemon at 
unix:///var/run/docker.sock. Is the docker daemon running?
```~~

~~dockerが起動していないのが原因だと思い、[sudo service docker start]とコマンドを入力すると、 * Starting Docker: dockerと表示されたものの…~~

~~```
 $ sudo service docker status
 * Docker is not running
```~~
~~とdockerが起動していない。docker versionでエラーメッセージを確認すると~~

~~```
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/version: dial unix /var/run/docker.sock: connect: permission denied
```~~

~~エラーメッセージを読む限り/var/run/docker.sockというファイルへのアクセスができないのが問題の様子。[この記事](https://tech.librastudio.co.jp/entry/index.php/2018/07/14/post-1924/)を参照すると、ログイン中のユーザーをdockerグループに追加する必要があるとのこと~~


~~```
$ sudo gpasswd -a (username) docker

Adding user (username) to group docker
``` ~~

~~と、無事にdockerグループにユーザーを追加できた。
ここまでは良かったが、/var/run/docker.sock への書き込み権限を追加しようとすると…~~


~~```
$ sudo chgrp docker /var/run/docker.sock

chgrp: cannot access '/var/run.docker.sock': No such file or directory
```~~

~~書き込みが失敗してしまった。~~
Qiitaの記事を退避（保存）するスクリプト書いた

**しかもCommon Lispでな！！！**

## 使い方

Common Lispの処理系マネージャ・スクリプティング環境の[Roswell](https://github.com/roswell/roswell)スクリプトとして書かれています。
動作確認はSBCL (roswellデフォルトの処理系)で確認しました。CCLではなんか日本語ファイル名がつかえないのか動かなかったです。

ユーザ名`*user*`と保存先ディレクトリ`*target-directory*`は適宜書き換えて実行してください。`ユーザ名 - 記事タイトル.md`のファイル名で保存されます。

## スクリプト自体

```lisp
#!/bin/sh
#|-*- mode:lisp -*-|#
#|
exec ros -Q -- $0 "$@"
|#
(progn ;;init forms
  (ros:ensure-asdf)
  #+quicklisp(ql:quickload '(:jonathan :dexador) :silent t)
  )

(defpackage :ros.script.get-all-qiita-items.3794175262
  (:use :cl))
(in-package :ros.script.get-all-qiita-items.3794175262)

(defparameter *user* "xxxxxxxxxxxxxx")
(defparameter *target-directory* (truename "."))

(defun list-all-items (user)
  (let ((url (format nil "https://qiita.com/api/v2/users/~a/items" user)))
    (jojo:parse (dex:get url))))

(defun get-id-and-title (item)
  (list :id (getf item :|id|)
        :title (getf item :|title|)))

(defun get-item-as-markdown (user item-id)
  (let ((url (format nil "https://qiita.com/~a/items/~a.md" user item-id)))
    (dex:get url)))

(defun save-item (md title)
  (let ((path (merge-pathnames (format nil "~a - ~a.md" *user* title) *target-directory*)))
    (format t "save as '~a'.~%" path)
    (with-open-file (out path
                         :direction :output
                         :external-format :utf-8
                         :if-exists :supersede)
      (write-line md out))))

(defun main (&rest argv)
  (declare (ignorable argv))
  (let ((items (mapcar (lambda (item)
                         (append (get-id-and-title item)
                                 (list :md (get-item-as-markdown *user* (getf item :|id|)))))
                       (list-all-items *user*))))
    (format t "; target articles~%")
    (mapc (lambda (item) (format t "; - ~a~%" (getf item :title))) items)
    (when (yes-or-no-p "save those into ~s? " *target-directory*)
      (loop
        :for item :in items
        :do (save-item (getf item :md) (getf item :title)))))
  )
;;; vim: set ft=lisp lisp:
```

---- 

では、happy hacking!
要素の消滅を待つアクティビティでタイムアウトが発生した

UiPathで以下の様な作業を自動化しようとした際にはまったのでメモ。

# やりたかった事
1. アプリケーションを実行し、ある画面を開く。
2. 開いた画面上で検索を実行し、検索結果をダウンロードする。（画面上に検索ボタンとダウンロードボタンがある）
3. ダウンロードした結果をメールで配布する。

# はまった点
検索処理にかかる時間がまちまちなので、検索ボタン押下～検索結果表示までの間に表示されている検索中ダイアログが表示されているまで待機するように「要素の消滅を待つ(Wait Element Vanish)」アクティビティを設定した。
ところがロボを動かしているとそのアクティビティでエラーが発生した。

> メッセージ: アクティビティのタイムアウトを超過しました
例外の種類: UiPath.Core.Activities.ActivityTimeoutException

# 原因
待つといっても無制限に待つのではなく、アクティビティで設定されたタイムアウト値（デフォルトは30秒）しか待たないから。
無制限に待ってしまうとロボがいつまでも終了できない事態になってしまうので、当然といえば当然の仕様。

ただ待つといってるのに「タイムアウトしました」ってなると混乱するのは仕方ない気がする。

# 対策
## タイムアウトを想定される最大時間まで伸ばす
今回の場合だと検索処理は一番時間のかかるときで10分だった。
なのでタイムアウトを600,000に設定し、それ以上かかる場合はエラーとするようにした。
ただ設定値を変更する場合には設定値を変更する理由を注釈を入れておいた方がいいと思う。（開発環境と実行環境で処理にかかる時間が異なる場合などは特に）

## 要素の有無を検出し続ける
あまりスマートじゃない気もするが、「要素の有無を検出(Elements Exists)」アクティビティをループし続けて、存在しなくなったらループを抜けるという手段もある。
ただこちらの場合、何らの異常があって要素が存在し続けてしまった場合に無限ループとなってしまい、ロボがいつまでも終了できない事態となってしまう。
また前者が1アクティビティなのに対して、こちらは複数のアクティビティが必要になるのでロジック上も複雑になってしまう。
スプレッド構文

##スプレッド構文
**「...」**の形で記述され、配列やオブジェクトの要素を展開する構文です。

```js
const test1 = { a: 1 };
const test2 = { b: 2 };

// test1とtest2が平らな状態でオブジェクトに入れることができます！
const test3 = { ...test1, ...test2};

// スプレッド構文を使わない場合
const test4 = {test1, test2};

// ネストしてい場合
const test_Oj1 = {a: {test: 1}, b: {test: 2}};
const test_Oj2 = {c: {test: 3}, d: {test: 4}};
const test_Oj = {...test_Oj1, ...test_Oj2};

// スプレッド構文を使わない場合
const test_Oj3 = {test_Oj1, test_Oj2};
```

**結果**
<img width="427" alt="スクリーンショット 2020-03-21 3.04.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/6e8c299e-803c-dd64-e0ea-7cea7e218ad6.png">
 
ネストしてい場合はこんな感じになります↓
<img width="442" alt="スクリーンショット 2020-03-21 3.53.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/94a7ff32-07a4-6e98-8f0a-1ee8799965ed.png">

スプレッド構文は配列でも使えます！

```js
const test1 = [1,2];
const test2 = [3,4];

// こちらもtest1とtest2が平らな状態で配列に入れることができます！
const test3 = [...test1, ...test2];
```
**結果**
<img width="405" alt="スクリーンショット 2020-03-21 3.26.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/b02c6e1f-86ea-d3c6-b24d-c839763402fa.png">


## Object.assign
同じように**コピー**することができる**Object.assign**というメソットもあります.
コピー元オブジェクトから列挙可能enumerableかつ直接所有ownのプロパティだけをコピー先オブジェクトにコピーします。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

```js
const test1 = { a: 1 };
const test2 = { b: 2 };

// { ...test1, ...test2}　と同じ結果になります
const test3 = Object.assign({}, test1, test2);
```

**結果**
<img width="509" alt="スクリーンショット 2020-03-21 3.13.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394411/f9971171-4005-b0e9-8553-220c64fbe533.png">
【GCP】インスタンスのMySQLからGCPのSQLに接続する

AWSでもかなり前にやったけど、ほぼ覚えてません。
今後のためにどうやって使うのか試してみました。

インスタンスにMySQLをインストール。
apacheはいれたけど、PHPはめんどくさいので入れなかった。

GCPでSQLを作成するとき、インスタンスで設定したリージョン、ゾーンと合わせる必要がある。
GCEの画面から確認できるので、あらかじめ確認しておく。

承認したIPアドレスからのみSQLへの接続を許可するため、
接続＞新しいネットワークで設定する。
保存を押せば完了。

ローカルのターミナルにて、インスタンスにログイン→以下のコマンドで接続できる。
ipアドレス部分は作成したgcp側のSQLのもの。

＝＝＝
[****@instance-1 ~]$ mysql -h ***.***.***.*** -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 124
Server version: 5.7.25-google-log (Google)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> 
＝＝＝

なお、PHPコード上からDBに接続する際はホスト名にCloud SQLのIPアドレスを設定すれば接続することができます。

【所感】
・AWSで作った時よりも簡単でスムーズにいけたような気がした。
（その当時、サーバー構築の知識が皆無だったので、あまりあてになりませんが。。。）
・サンプルデータなどを使って挙動を確かめたほうが良いと思う。

【参考URL】
http://yebisupress.dac.co.jp/2018/08/23/publish_website_with_google-cloud-platform/
EfficientDetを動かしてみた

# 何をしたいか
- EfficientDetを動かしたい
- COCOでのEvalationまでやると時間がとてもかかるので、１枚の画像の推論まで実行します

# 注意
- [使うレポジトリ](https://github.com/google/automl)はgoogleのものですが、公式のgoogle製品ではないとのことです（[参照](https://github.com/google/automl/tree/master/efficientdet#6-training-efficientdets-on-tpus)）
- コードが急速に更新されているので、この情報もすぐoutdatedになります

# 環境
- Docker 18.09.1
- Ubuntu 16.04
- GTX1080

# こうやると動きました

```bash:とりあえずコンソールから
docker pull tensorflow/tensorflow:latest-devel-gpu-py3
docker run -it --name tensorflow -p 8888:8888 tensorflow/tensorflow:latest-devel-gpu-py3 bash
pip install jupyter
git clone https://github.com/google/automl
cd automl
jupyter notebook --port 8888 --ip=0.0.0.0 --allow-root
# 127.0.0.〜をブラウザで開く
```

```python:ブラウザからtutorial.ipynbを開く
# python3系だとpycocotoolsが動かないので若干修正
# !pip install -U 'git+https://github.com/cocodataset/cocoapi.git#subdirectory=PythonAPI'
# の部分を↓で上書き

!git clone https://github.com/cocodataset/cocoapi
!cd cocoapi/PythonAPI && make
!pip install Cython
!pip install pycocotools
```

あとはShift+Enterを叩いて待つとこんな画像が。

![img.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/207596/a9437a90-fe62-4dce-75ab-a812e64f5e5f.jpeg)
LINE Messaging API: ボットのアイコンを動的に変える

先日 LINE Messaging API のニュースで、「[アイコンおよび表示名が変更できるようになりました](https://developers.line.biz/ja/news/2020/03/17/icon-nickname-switch/)」という面白い内容がアナウンスされました。

# これまで

固定の画像のみで、画像設定していないと以下のような感じでした。

![90982765_230905441444639_2388771556319821824_n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/983a9023-2754-8756-15e5-107fe46b4c79.png)

# 新機能を使うと

状況に合わせてアイコンと名前を変えることができます。
![90879425_658178981583629_6650558808324046848_n.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/e799ed57-22c4-fa83-d430-0108af7563a7.png)

# コードの変更

今回の変更は Breaking Change ではないため、既存のコードはそのまま動きますが、各種メッセージに sender オブジェクトを渡すだけです。
以下 C# の例です。

これまで

```csharp
await Client.ReplyMessageAsync(ev.ReplyToken, textMessage.Text);
```

新しい方法

```csharp
var message = textMessage.Text == "chibi" ?
    new TextMessage(textMessage.Text, sender:
        new Sender("Chibi", "<画像のパス>")) :
    new TextMessage(textMessage.Text, sender:
        new Sender("Mei", "<画像のパス>"));
await Client.ReplyMessageAsync(ev.ReplyToken, new List<ISendMessage>() { message });
```

# C# SDK

今回の新機能に対応した SDK を公開しました。C#er の方は是非お試しください。

https://www.nuget.org/packages/LineDC.Messaging/1.1.0

実装してくれた @himarin269 ありがとう！
Splunkのtime-based lookupを使ってみる

はじめに
---
- SplunkのLookup機能の1つに[time-based lookup](https://docs.splunk.com/Documentation/Splunk/8.0.2/Knowledge/Configureatime-boundedlookup
)があります
- 公式manualとsplunk answerだけでは、いまいち設定の方法が分かりにくく。。
- 試行錯誤した結果を備忘録として残す

やりたいこと
---
- サーバアセットリストに、**タイミングによってよく替わる要素（例：IPアドレス情報やサーバOwner情報など）**を加えたlookupを作成
- ログのサーチ結果に**該当の時間帯**のアセット情報をlookupして表示する

設定方法
---
- lookupテーブルの作成
- 今回のアセットテーブルには、以下テーブルを列挙
    - _time (1時間単位)
    - **host** ←lookup時にマッチングさせるキーフィールド
    - main_sourcetype
![スクリーンショット 2020-03-26 10.25.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/456cc30d-3eb1-e3ab-426f-e00cff261e65.png)

- lookup定義（timebase）の設定
- ポイントは、赤枠の設定です。
    - 時間フィールド値： lookupテーブル内の_timeフィールドを指定
    - 時間フォーマット： **年/月/日 時:分**のフォーマットとして認識できるように設定
![スクリーンショット 2020-03-26 10.29.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/12308c60-68b0-9821-0a04-869a92fd3c88.png)

- サーチでlookupしてみる
![スクリーンショット 2020-03-26 10.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/06537b3f-d90d-fdf7-2313-25edf0486d5e.png)

```sh:サーチのポイント
|lookup demo_asset.csv _time host
※timebaseサーチは、lookup名ではなく、lookup*ファイル名*を指定する必要あり
```
lookup名だとエラー
![スクリーンショット 2020-03-26 10.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185759/fd564fbd-0c5c-3721-d70c-010c69ca58b3.png)

結果
---
- lookupテーブル内の**_time**と**host**の値に同時に該当した場合にのみmain_sourcetypeフィールドが出力されることを確認できました。
WSL Ubuntu18.04にDockerをインストールする

(2020.3.29)そもそもWSL上にDockerを導入することは難しいとのこと。
2020年5月にリリース予定のWSL2では問題なくDockerを導入できるということなので5月以降はそちらを使うと良さげ



~~##【概要】
WSL Ubuntu18.04 ltsにDockerをインストールする。~~

~~##【環境・バージョン】
・OS: WSL Ubuntu18.04
・Arch: amd64
・Docker version: 19.03.8~~

~~##【導入手順】~~

~~① aptのパッケージリストをアップデートする~~

~~```
 sudo apt-get update
```~~


~~② パッケージをインストールする~~

~~ sudo apt-get install -y \
  > apt-transport-https \
  > ca-certificates \
  > software-properties-common ~~


~~③ DockerのGPGキーを追加する~~

~~```
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

OK
```~~

~~入力が正しくできていればOKと表示されます。~~


~~④ リポジトリを追加する~~

```
$ sudo add-apt-repository \
  > "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
  > $(lsb_release -cs) \
  > "stable"
```

~~※[arch=amd64]のamd64の部分は使用しているLinuxのアーキテクチャによって変わります。archコマンドでアーキテクチャを確認可~~

~~リポジトリが追加できたらaptのアップデートも行います。~~

```
$ sudo apt-get update
```

~~これでDockerをインストールする準備が整いました。~~


~~⑤ Dockerをインストールする~~

```
$ sudo apt-get install docker-ce
```


~~インストールができたら以下のコマンドでDockerのバージョンを確認します。~~

~~```
$ docker version
```~~

~~すると…~~

~~```
Client: Docker Engine - Community
 Version:           19.03.8
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        afacb8b7f0
 Built:             Wed Mar 11 01:25:46 2020
 OS/Arch:           linux/amd64
 Experimental:      false
 Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```~~

~~無事インストールできています。ただし下の2行のエラーメッセージを見る限りDockerがまだ起動していないようです。この問題は別のエントリで解決します。~~

~~##【参考資料】~~

~~[プログラマのためのDocker教科書第二2版]~~~~(https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEDocker%E6%95%99%E7%A7%91%E6%9B%B8-%E7%AC%AC2%E7%89%88-%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AB%E3%82%88%E3%82%8B%E7%92%B0%E5%A2%83%E6%A7%8B%E7%AF%89%E3%81%AE%E8%87%AA%E5%8B%95%E5%8C%96-WINGS%E3%83%97%E3%83%AD%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88/dp/4798153222/ref=pd_sbs_14_t_0/357-5789801-8277315?_encoding=UTF8&pd_rd_i=4798153222&pd_rd_r=966c4f81-1911-4e67-8b9b-005338dea134&pd_rd_w=P1ktL&pd_rd_wg=FhRzp&pf_rd_p=ca22fd73-0f1e-4b39-9917-c84a20b3f3a8&pf_rd_r=0BDCYKXWMJ9T9HDAXM43&psc=1&refRID=0BDCYKXWMJ9T9HDAXM43)~~

~~https://qiita.com/soumi/items/5b01d88c187b678c0474~~
Navigation Componentの注意点

Navigation Componentを使っていて嵌ったポイント

**update**
@FKbelm さんから```findFragmentById```を使えば大丈夫だと教えてもらいました。

# ハマったこと
Navigation Componentを使って、ToolbarをActivityに持たせていたら、該当のViewを表示する時に

```
java.lang.IllegalStateException: Activity Caused by: java.lang.IllegalStateException: Activity {Activity} does not have a NavController set on  {nav_host_fragmentのid}
```

が出た。

# 原因
FragmentContainerViewを使って、

```xml
    <com.google.android.material.appbar.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize">

        <androidx.appcompat.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="enterAlways|scroll" />

    </com.google.android.material.appbar.AppBarLayout>

    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_behavior="@string/appbar_scrolling_view_behavior"
        app:navGraph="@navigation/nav_graph" />
```

のように書いてると

```kotlin
toolbar.setupWithNavController(findNavController(R.id.nav_host_fragment))
```

でNavControllerが見つからないと例外が投げられる。

# 対策

~~FragmentContainerViewじゃなくfragmentを使えばいい。~~

```kotlin
val navController = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) 
toolbar.setupWithNavController(navController!!.findNavController())
```
という呼び方をすれば大丈夫そう

## 余談
~~lintでfragmentをFragmentContainerViewに変えろって言われるけど、今は無視するしかなさそう。~~