OmniAICreator/Qiita-1.07M huggingface dataset:
深層学習（後編 2）：「Section1 : Tensorflowの実装演習」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/d1b267a9-8303-d11a-25c0-3df366a5fa37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/f59cab55-af6d-5436-9cc4-c62c6abed41c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/46867d91-b76b-d05d-6a9f-7e1b8f883cb7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/aa99857b-7da9-8e1e-e127-11f85278fea0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/07d7ab0d-1fde-d541-04fa-136907e7f7be.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/4e3529cd-39c3-7ef6-8936-796ad6ca5d37.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/e4655d6b-148f-05e6-fd6e-eb43b6907705.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/994fdb7f-190d-39d2-f522-c6c4f9bec4f0.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/dc63a293-b759-0a84-6175-c7bf54fa403d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/5f032939-2967-cc9e-aca4-220598ee38a5.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/51ca96f3-5786-ca1d-7f48-d8965f676c78.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/9e141019-6b84-9a27-dde6-e6c55b72232c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/cb1639e3-d36d-6423-f805-2750a95a1fcb.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/c83ed3f6-2486-6e59-d2a3-97c7122198b2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/d76da379-ed2b-26d1-21b1-30857f693426.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/a7bfe246-5c5d-263c-c78e-35deaf2ed600.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/a39318c0-d3b1-d6b0-e76b-49954982f42a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/be0b8ce1-4d17-e93b-5b6f-e23a55945f19.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/d6c4dab2-379a-ff61-0987-1fc62938a6fc.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/7f1dbf13-43ac-a8c0-6418-8333bcc730aa.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/8923525c-600c-74e9-4e22-330501d512f1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/d3385b0c-4990-7dec-71fd-c748fb90f354.png)
【web開発 PHP】同ページにHTTPを行いたい！

#はじめに
webサービスを開発する際に便利だと思ったので書き起こしています。ButtonやAnchorを用いて同ページに変数を送信(HTTP)したいときに使います。例えば、ページ上のカテゴリボタンを押すとそのページ上でそのカテゴリのみのコンテンツが絞られたものが表示されたり。
以下のコード例では同ページ内に変数を渡す部分を記述しています。

#解決法
こちらではPOST送信で書いておりますが、GETでも可。
PHPファイル先頭に以下を記述。もしPOST送信があればdataを受け取りPOSTデータを削除するだけのシンプルなコードです。

```php
if (isset($_POST["btnid"])) {
  $data = $_POST["btnid"];
  unset($_POST);
}
```
さて、以下のコードが鍵となります。こちらはform要素ですが、画面上には表示されないようになっております。valueには後に送信したい変数を格納するのでデフォルトでは空白。

```html
<form name="form1">
  <INPUT type="hidden" id="btnid" name="btnid" value=""/>
</form>
```
以下のコードではid="id"である要素をクリックするとvalueに送信したい変数を格納して送信するというものであり、これが実行されると、もう一度index.phpの先頭行から処理ををするため\$data変数に$_POST["btnid"]が送信されるというシンプルなものです。

```javascript
$("#id").on("click", function(e){
  $("#btnid").val(data); //送信したいデータをvalue値として登録
    
  let form1 = document.forms["form1"];
  form1.method = "POST"; //HTTP方式の決定
  form1.action = "index.php"; //遷移先を同ファイルに設定
  form1.submit(); //送信
  return false;
});
```

#未解決事項
色々調べてみたものの、一番よく見かけたのはAjaxでの送信でしたが今回はうまく実装できませんでした。AjaxはGoogle検索する時に、文字を少しタイプすると下に検索予想が出てくる機能に使われているようで、常にHTTP方式で送信している感じらしいです。おそらく、今回実装できなかったのは要素がクリックした時にのみ発火されるというものに相性が良くなかったのかなと思いますが、今後の実装でもう一度勉強しようと思います。
dSYMのアップロードはBitrise/fastlaneで自動化しとくといいぞ

# TL;DR
- dSYMの取得とアップロードをするlane作成
- BitriseにWorkflow作成
- Workflowをスケジューリングする

# 前書き
Crashlyticsを利用していると, FabricへのdSYMのアップロードを求められることになります.
これをAppStoreConnectへのリリースの度に手動で行ってもいいのですが, 上げ漏れが起きたり, めんどくさかったり, めんどくさかったり, めんどくさかったりしますよね.
なので, 日次でdSYMのアップロードを行うようにBitrise上でスケジューリングすることで, 煩わしさから解放されましょう.

# FastfileにdSYM関連の処理をするlane作成

```Ruby:Fastfile
desc "Refresh dSYMs"
lane :refresh_dsyms do

  download_dsyms(
    app_identifier: "tihimsm.my_app",
    version: "latest" # 最新のdSYMを取得するように指定
  )

  upload_symbols_to_crashlytics # dSYMをCrashlyticsへアップロード

  clean_build_artifacts # ローカルのdSYMを削除

  slack(message: "dSYMs are refreshed!")

end
```

`download_dsyms`でAppStoreConnectにあるdSYMをダウンロードするのですが, オプションで`version: "latest"`を指定しています.
なにも指定しないとすべてのdSYMを取得して, けっこう時間がかかってしまうので要注意です.
あとでBitriseの方でスケジューリングをするのですが, 毎日このlaneが走るようにしておけば, よほどリリースの頻度が高くない限りは漏れなくアップロードできるはずです.

### 追記(2019/12/02)
> download_dsymsのversionに、"live"を指定すると、
> 公開中アプリのDSYMをStoreからダウンロードできるようになったようです。
> 公開版よりも新しいアプリがTest Flightに存在しても、そのDSYMは無視してくれます。
> (fastlaneの2.134.0以降)

@zigenin さんより情報提供いただきました, ありがとうございます!

`clean_build_artifacts`はローカルにあるdSYMファイルを削除してくれるもので, Bitriseでlaneを走らせる限りはあまり意味がないのですが, ローカルでlane叩く可能性も考えて削除するようにしてます.
ちなみに, 今回はdSYMを削除してくれる`clean_build_artifacts`ですが, 実はとても汎用性の高いactionで, **状況にあわせてよしなに削除してくれる**とても賢いやつです.
詳しくは公式ドキュメントをご参照ください.

- [download_dsyms](https://docs.fastlane.tools/actions/download_dsyms/)
- [upload_symbols_to_crashlytics](https://docs.fastlane.tools/actions/upload_symbols_to_crashlytics/)
- [clean_build_artifacts](https://docs.fastlane.tools/actions/clean_build_artifacts/)

# BitriseにWorkflowを設定
Workflowはとても簡単です.
リポジトリをCloneしてきてfastlaneで`refresh_dsyms`を起動させるだけです.
![スクリーンショット 2019-07-16 3.41.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142392/58db4c69-114c-cf1d-9413-ab0899b84542.png)

# Workflowをスケジューリングしよう
`Builds`タブの画面右上の方に`Start/Schedule a Build`というボタンがあるので, そこからスケジューリングの設定を行います.
![スクリーンショット 2019-07-16 3.42.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142392/d06d7ce6-6369-8a17-5147-d68ca8d80f68.png)
上のような画面で設定が行えます.

- 時間
- 曜日
- ブランチ
- Workflow
を設定することで, 自動でWorkflowが起動できます.
上の例だと`毎日AM01:00`に起動するようになっています.

これで毎日AppStoreConnectの最新のdSYMを取得して, Crashlyticsへアップロードを自動で行うことができるようになります.

# まとめ
いかがでしょうか?
地味な内容でしたが, 毎度手作業でやってると意外とめんどくさかったり漏れがあったりしますし, 人がやらなきゃいけない作業でもないので, こういう類のものは自動化してしまうに限ります.

簡単に設定できるわりに, 毎日SlackにdSYMがアップロードされた通知が来るので「うんうん, 今日もdSYMアップロードご苦労」という気分になれます笑
コスパ良くてけっこうおすすめなので, 設定してない方はぜひやってみてください!
AWS LambdaでPython Pillowを使うための手順　

# 環境
macOS Mojave
versin 10.14.5

# 目的とゴール
AWS Lambda上でPillowライブラリを使えるようにすることをゴールとします。

AWS LambdaでPython3.7で画像ファイルを操作する関数を開発していたところ、python Pillowのライブラリのimportに失敗しました。

```lambda_function.py
from PIL import Image
```

```
from PIL import Image
Response:
{
  "errorMessage": "Unable to import module 'lambda_function'"
}
```

ローカル環境にインストールしたpython Pillowを「.zipファイルをアップロード」にてAWS Lamabda上にはインストールしていました。
python PillowのライブラリはインストールしたOS環境に依存するらしく、AWS Lambda上で動作するPillowはAmazon Linux環境にインストールしたpython Pillowが必要ということがわかり、その手順を本記事に残します。



# 手順
1. Dockerをインストール
2. DockerにAWS Linuxの環境を用意する
3. Docker環境にPythonとPythonのPillowライブラリをインストール
4. AWS Lambda上に「.zipファイルをアップロード」でインストール


# Dockerのインストール
こちらの記事を参考にさせていただきました。
**Dockerインストールメモ**
https://qiita.com/n-yamanaka/items/ddb18943f5e43ca5ac2e


Dockerのバージョンを表示、インストールされたことを確認します。

```
docker version
```


# AWS Linuxの環境を用意する

Amazon ECRからAmazon Linux コンテナを取得する方法がありますが、今回はより手軽な方法である、公開されたamazonlinuxからイメージを取得しコンテナを作成します。

amazonlinuxのdockerイメージ
https://hub.docker.com/_/amazonlinux

```
docker pull amazonlinux
```
にてイメージをダウンロードします。

# Docker環境にPythonとPythonのPillowライブラリをインストール

こちらの記事を参考にさせていただきました。
**AWS Lambda で Pillow を使おうとしたらハマった**
https://michimani.net/post/aws-use-pillow-in-lambda/

Dockerfileとdocker-compose.yml、ディレクトリ構成は参考にさせていただいた記事と同等のものにしました。
また、requirements.txtには以下としました。

* requirements.txtの中身

```
Pillow
```


Dockerfileの階層に移動して、コンテナをビルド・立ち上げします。

```
docker-compose up --build 
```


```
$ docker-compose up --build
Removing docker_test_app_1
Building app
Step 1/3 : FROM amazonlinux:latest
 ---> b94321659aca

省略

app_1  | WARNING: Running pip install with root privileges is generally not a good idea. Try `pip3 install --user` instead.
app_1  | Collecting boto3 (from -r /home/deploy/requirements.txt (line 1))
app_1  |   Downloading 

省略

docker_test_app_1 exited with code 0
```

distにライブラリが出力されていることを確認できました。

（WARNINGが出たので、docker-compose.ymlのcommandをpip3 install --userに差し替えて叩いてみましたが、解消しませんでした。原因特定はできず）


（ちなみに、docker環境に直接ログインして、
yum install python3 -y
mkdir /home/deploy
pip3 install Pillow -t dist/
を実行して、手に入れたPillowライブラリは、エラー"Unable to import module 'lambda_function'"が解消しませんでした。こちらも原因特定はできず）

# AWS Lambda上にPython Pillowをインストール

distに出力されたライブラリをzip圧縮し、コードエントリタイプ「.zipファイルをアップロード」を選択してインストールします。
ここで画面で動かしていたlambda_function.py、他コードがあれば、バックアップを取りライブラリと一緒にzipファイルに含めてください。
そうしないと、「.zipファイルをアップロード」したタイミングで消えてしまいます。
また、zipファイルはlambda_function.py、ライブラリを直接選択した状態で圧縮する方法で作成します。lambda_function.py、ライブラリが保存されているディレクトリを圧縮してzipファイルの場合は展開に失敗しました。


# 参考サイト

**Dockerインストールメモ**
https://qiita.com/n-yamanaka/items/ddb18943f5e43ca5ac2e
**AWS Lambda で Pillow を使おうとしたらハマった**
https://michimani.net/post/aws-use-pillow-in-lambda/
【SQL Server】DB内のテーブル、カラム、拡張プロパティの検索をする

(初投稿です。至らない点あったら教えてください・・・。)

新しい会社に入社した時、
新しいDBを触る時、
テーブル／カラムの多さに驚き、
絶望することがあると思います。（私はありました）

そんな時に少しだけ活躍するSQL Server用のスクリプトがこちら

```sql:DBinfoScript
select
sys.tables.name as table_name,
sys.columns.name as column_name,
sys.extended_properties.value as properties,
sys.types.name as typename,
sys.columns.max_length as max_length
from
sys.tables
left outer join sys.columns on sys.tables.object_id = sys.columns.object_id
left outer join sys.extended_properties on sys.columns.column_id = sys.extended_properties.minor_id and sys.tables.object_id = sys.extended_properties.major_id
inner join sys.types on sys.columns.system_type_id = sys.types.system_type_id and sys.columns.system_type_id = sys.types.user_type_id

where
sys.tables.name like '%%'
and
sys.columns.name like '%%'
and
(
	convert(nvarchar,sys.extended_properties.value) like '%%'
	or
	convert(nvarchar,sys.extended_properties.value) is null
)

order by sys.tables.name,sys.columns.column_id
```
### 表示項目
①テーブル名称
②カラム名称
③カラムの拡張プロパティ
④カラムのデータ型
⑤カラムの最大値（長）

### 使用sysテーブル
- sys.tables
 - テーブルに関する情報
- sys.columns
 - カラムに関する情報
- sys.extended_properties
 - 拡張プロパティに関する情報
- sys.types
 - データ型に関する情報

### 検索条件
①テーブル名
②カラム名
③拡張プロパティ内容

### 並び順
①テーブル名
②カラム名

拡張プロパティは設定しない場合nullになるので、
nullのカラムが消えないようにしています。
また、曖昧検索ができるようにconvertしています。

もしも使える場があれば使って下さるとありがたい・・・。
splunkで正規表現を使って形態素解析ぽい事をする


今回は、Slackやtwitter などの文章データを取り込んだあとに、単語ベースで分析したい場合に、英語だと単語がスペースで区切られているので解析しやすいのですが、日本語の場合品詞分解が非常に複雑で手間がかかるかと思います。
一般的には MeCabなどのツールを使って形態素解析するのがいいかもしれませんが、Splunkではデフォルトではそのようなツールが入っていないので、形態素解析した後に、Splunkに取り込む必要があります。

そこで、今回はMeCabなどのツールほど正確に形態素解析はできませんが、**もどき**の方法を正規表現を使ってやってみたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/e58b6ef6-8975-aecc-5aba-7ca0d44da7cc.png)


##正規表現で日本語を識別して取り込むには？

Splunkはデフォルト Unicodeで取り込まれますが、Unicodeスクリプトを使って簡単に漢字やひらがななどにマッチングさせて取り込むことができるようです。
http://module.jp/blog/regex_unicode_prop.html

| 正規表現 | 識別ターゲット |
|:--|:--|
| \p{Katakana} | カタカナ |
| \p{Hiragana} | ひらがな |
| \p{Han} | 漢字 |
| \p{Latin} | 英数字 |

## Splunkで正規表現を使って、文章を分解してみよう。

上記の正規表現を使って、単語に分解して、その出現回数をカウントしてみたいと思います。
ただし、漢字同士が続いたりすると同一単語と認識されてしまうので、正確性にはかけますので、その点はご容赦ください。


```
source=slack* 
| rex field=text max_match=100 "(?<Hira>\p{Hiragana}+)" 
| rex field=text max_match=100 "(?<Kanji>\p{Han}+)" 
| rex field=text max_match=100 "(?<Kata>\p{Katakana}+)" 
| rex field=text max_match=100 "(?<Latin>\p{Latin}+)" 
| eval word = mvappend(Latin,Kanji, Hira, Kata) 
| mvexpand word
| top limit=20 word
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/3231a874-54bb-f668-715c-1e9e0550169c.png)



時系列で表示してみたり

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/23bff8eb-ac5d-710e-f867-bc58280d6a1c.png)

Wordcloud で可視化してみたり
https://splunkbase.splunk.com/app/3212/


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392303/74e082ad-fd21-e472-a23a-a7256b536e80.png)



## さいごに

今回は、日本語メッセージでも非常にシンプルにできる**形態素解析もどき**をご紹介しました。
ScalaTestでテストケースを指定する。

## TL;DR
`sbt 'testOnly **.WhatYouWantToTest -- -z "someMethod should"'` のように指定してやると、
テストクラス `WhatYouWantToTest` の中で `someMethod` についてのテストケースのみ走らせることが出来る。
（今回はFlatSpec利用を想定していますので、他の記法を利用している場合は `-z` で指定する文字列は適宜調整してください）

## ScalaTestで、テストクラス内の特定のテストケースのみを走らせたい

FlatSpecで以下のようなテストメッセージが出るものを想定した際、 `someMethod` に対応したテストケースのみテストしたいとします。

```
someMethod
- should なんかやります1
- should なんかやります2
- should なんかこの時は駄目です1
- should こういうときは限界だとエラーを吐きます。
fugaMethod
- should hogehoge1
- should fugafuga
 :
```

その際は `sbt 'testOnly **.WhatYouWantToTest -- -z "someMethod should"'` のように、
`-z` にわたす文字列に `someMethod should` と指定してやれば、 上のメッセージにおいて

```
someMethod
- should なんかやります1
- should なんかやります2
- should なんかこの時は駄目です1
- should こういうときは限界だとエラーを吐きます。
```

に該当する箇所のみテストが走ります。(上はFlatSpecでのテスト例になります。他の記法では適宜文言を調整してください)


## 補足

### ScalaTestで特定のテストクラスをテストする。
`sbt 'testOnly org.example.HogeSpec'` や
`sbt 'testOnly org.example.*'` や
`sbt 'testOnly **.HogeSpec'` というような指定の仕方をしてやればよい。[^1][^2]


### 特定のテストクラス内の特定のテストケースのみを走らせたい

どうやら、 `--` の次に好きなオプションを指定できるらしい。[^2]
> you can also pass arguments for individual runs by using test-only and placing them after --, like this:

選択可能なオプション[^3]の中でテストケース指定に便利そうなのは、 `-z` オプション[^1]であり、

上で述べたように、  `sbt 'testOnly **.WhatYouWantToTest -- -z "someMethod should"'` というふうに、
ScalaTestの記法にマッチさせるようにしてやるとより便利です。



[^1]: https://qiita.com/suin/items/0294a53d6babd69f29a9
[^2]: http://www.scalatest.org/user_guide/using_scalatest_with_sbt
[^3]: http://www.scalatest.org/user_guide/using_the_runner
Rails6 のちょい足しな新機能を試す53（tiff 編）

# はじめに

Rails 6 に追加されそうな新機能を試す第53段。 今回は、 `tiff` 編です。
Rails 6 では、`variant` メソッドが `tiff` フォーマットの画像ファイルをサポートするようになりました。

Ruby 2.6.3, Rails 6.0.0.rc1, Rails 5.2.3 で確認しました。Rails 6.0.0.rc1 は `gem install rails --prerelease` でインストールできます。

```shell
$ rails --version
Rails 6.0.0.rc1
```

# 準備

今回は、 [Rails6 のちょい足しな新機能を試す15（Active Storage編）](https://qiita.com/suketa/items/2daad87d8c22737f5582) を元にして作業を進めます。

# Gemfile に MiniMagick を追加する

画像を変換するために MiniMagick を使用します。

```ruby:Gemfile
...
gem 'mini_magick'
...
```

# show ページを修正する

show ページで、 `variant` メソッドを呼び出して画像ファイルをリサイズしてみます。
元の画像ファイルと、 50x50 に変換した画像を表示します。

```erb:app/views/users/show.html.erb
  ...
  <% if @user.avatar.attached? %>
    <h2>original size</h2>
    <%= image_tag @user.avatar %>
    <h2>50x50 size</h2>
    <%= image_tag @user.avatar.variant(resize: "50x50") %>
  <% end %>
  ...
```

# ユーザー登録して確認する

ブラウザからユーザーを登録します。
このとき画像ファイルとして tiff ファイルを選択します。
詳細画面を表示するとサイズを変換した画像が表示されます。

なお、 tiff ファイルは、 IE や Safari であれば表示できますが、 Firefox や Chrome では表示できないようです。
ですが、サイズ変換した画像は、 PNG フォーマットになるので、変換した画像は、 Chrome でも表示できました。
下は、Chrome のスクリーンショットです。

![variant.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209941/6defc7d5-2030-74bd-3cee-4339e99e01be.png)



# Rails 5 では

`ActiveStorage::InvariableError` が発生します。

# 試したソース

試したソースは以下にあります。
https://github.com/suketa/rails6_0_0rc1/tree/try053_accept_tiff_by_variant


# 参考情報

* [What is new in Rails 6.0](https://bogdanvlviv.com/posts/ruby/rails/what-is-new-in-rails-6_0.html)
* [[ActiveStorage] Allow `variant` method to be called by `TIFF` images](https://github.com/rails/rails/pull/34824)
* [ActiveStorage::Variant](https://edgeapi.rubyonrails.org/classes/ActiveStorage/Variant.html)
* [ActiveStorage::InvariableError](https://edgeapi.rubyonrails.org/classes/ActiveStorage/InvariableError.html)
VSCodeでNo source control providers registerd （有効なソース管理プロバイダがありません）と言われた

# VSCodeでNo source control providers registerd 

ある日ふと気づくと、VSCodeの左端のメニューのsource controlタブが一切反応していなかった。

↓これである
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273745/44b4d0c2-21f9-c2cc-2c77-f500e5efe611.png)

タブを開いて、git管理されているディレクトリいじっていてもNo source control providers registerd の表示だけで一切反応なし。

で、基本はコマンド打ちながらやっていたので不便はなかったのですが、人に教えなくちゃいけないとなって使ってみようと思った時に、使えない。。。

しばらくググってみると、[パスを通す方法](https://qiita.com/atsuyuuki/items/9ef6ccc31c718342c2b4)とかあったんですが、超簡単な理由でした。

## 解決方法： extensionで`@builtin Git`を検索 → 有効化

何らかの操作の時に無効化していたのかも。。。ここから検索してビルトインのGitを有効化してあげればOK!!

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273745/26735a31-7279-09cc-7f67-500c8c812d28.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273745/dc513c89-8a22-ee4e-3ad7-c52eb6911494.png)
Nest.js + OpenAPI(Swagger)を試してみる

前回、前々回でサーバーサイドのTypescript化およびDBアクセスまでできるようになりました。

前々回：[Nest.js を使ってみる](https://qiita.com/teracy55/items/83cae05eed027a510a7e)
前回：[Nest.jsでSequelizeを使ってみる](https://qiita.com/teracy55/items/2cea15e6abd560a4cea6)

今回はクライアントサイドからアクセスする部分を作ります。
Nest.jsデフォルトでも良いのですが、RestAPI標準規格（になると噂）のOpenAPI（旧Swagger）を導入したいと思います。

(2019/12/11追記)
最新のnestjs/swaggerではOpenAPI（Swagger3.0）に対応しているため、このページの内容は古くなっています。
nestjs/swagger4系についての記事も書いていますので、そちらを参照ください。
[nestjs/swagger 3系（Swagger2.0）⇒4系（Swagger3.0(OpenAPI)）へのバージョンアップ](https://qiita.com/teracy55/items/c47a5ad7f4171d84e124)


# OpenAPI(Swagger)とは

OpenAPI - Swagger：https://swagger.io/docs/specification/about/


これを導入すると、API仕様書を出力してくれるだけではなく、APIのテストができたりとかなり便利なツールです！
さらに[openapi-generator](https://github.com/OpenAPITools/openapi-generator)を使うことでクライアントサイドからアクセスするためのAPIクライアントも自動生成できる(Angular用のコード出力もできます)ため、開発工数をぐっと減らすことができます:grin:

# 導入

[Nest.js公式に導入方法](https://docs.nestjs.com/recipes/swagger)が書いてありますので、それに従います。

## @nestjs/swaggerのインストール

```
npm install --save @nestjs/swagger swagger-ui-express
```

## main.tsでSwaggerのセットアップ

```src/main.ts
import { NestFactory } from '@nestjs/core';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ApplicationModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(ApplicationModule);

  const options = new DocumentBuilder()
    .setTitle('Cats example')
    .setDescription('The cats API description')
    .setVersion('1.0')
    .addTag('cats')
    .build();
  const document = SwaggerModule.createDocument(app, options);
  SwaggerModule.setup('api', app, document);

  await app.listen(3000);
}
bootstrap();
```

準備はこれだけです！


# 起動してみる

`docker-compose up`で起動し、ブラウザで`/api`にアクセスしてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/53f21825-3724-e696-91b8-a1532d6a1571.png)

めちゃくちゃ簡単です！！！

## JSON形式で出力

`/api-json`にアクセスすると、JSON形式で出力することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325108/50f81f1e-3b57-232d-eadd-d6f8aaca2579.png)
[AWS] AWSソリューションアーキテクトアソシエイト合格までにしたこと

# AWSソリューションアーキテクトアソシエイト

先日受験し無事合格することができました
受験対策として自分が行ったことを記録して置こうと思います

> AWSソリューションアーキテクトアソシエイトは長いので、「SAA」と略します

## SAAとは

- AWS認定の一つ
- AWS のテクノロジーを使用して安全で堅牢なアプリケーションを構築およびデプロイするための知識を効果的に証明できる、とされている

## 対象者

- 可用性、優れたコスト効率、耐障害性を備え、スケーラブルな AWS 上での分散システムの設計に関して、少なくとも 1 年の実務経験のある方が対象

## 詳しくは

- 公式HPをご参照
- https://aws.amazon.com/jp/certification/certified-solutions-architect-associate/

# 合格までの事前知識とスケジュール

## 事前知識

- AWSは「少し触ったことがある」程度
- EC2、S3などの有名サービスは「知っている」程度
- どのように組み合わせたらシステムが構築できるかについては全く無知
- 初心者

## スケジュール

- 4月
    - 対策本を読む
- 5月
    - Udemy講座をひたすら見る
- 6月
    - Udemy講座をひたすら見る
    - `Architecting on AWS` の受講
    - 問題集を解く
- 7月
    - 受験&合格

# 合格までにしたこと&合格貢献度

1. 対策本
2. Udemy講座
3. `Architecting on AWS` の受講
4. AWS公式模擬試験

## 1. 対策本

- [徹底攻略 AWS認定 ソリューションアーキテクト – アソシエイト教科書](https://www.amazon.co.jp/dp/4295005495)

まず上記書籍を購入しAWSとは何か、AWSソリューションアーキテクトアソシエイトとは何かを勉強しました

この本で得られたことは

- SAAでカバーすべきサービスが分かる
- 構成図も載っているのでサービスをどのように組み合わせてシステム構成すればよいか分かる
- AWSベストプラクティス「5つの柱」について章別に記載されているのでそれぞれについてしっかり学べる
- 各章末に確認問題があるので知識確認になる
- 模擬問題がDLでき本番試験にかなり似た問題を事前に解いて感覚を養える

まず手始めにAWSを知る、SAAを知るには丁度良いかと思います
ページ数も膨大、というほどではないので早い人だと数日で読み終えられると思います

## 2. Udemy講座

- [これだけでOK！ AWS 認定ソリューションアーキテクト – アソシエイト試験突破講座（初心者向け21時間](https://www.udemy.com/share/100YZsB0oeeF5QRX4=/)

上記講座は、様々な合格記事を拝見している中でオススメされていたので自身でも購入
結果、この講座にて合格できたと言っても過言ではないくらいにお世話になった

本講座で得られたことは

- ハンズオンによりAWSを実際に触りながら対象のサービスを理解できる
- 細かく章立てされているので移動時間に必要な箇所だけを見られる
- 噛み砕かれた説明を聞くことで理解がしやすい
- 問題集が「3回分」ついていて　かつ　内容がかなり本番に近い

この講座がなければ合格は無理だったなと振り返って思います
「問題集」がかなり役に立ちます
本番にかなり似た問題が出題されるので知識確認をするのに最適です
この問題でしっかりと点を取れるようになれば合格は近いと思います

## 3. `Architecting on AWS` の受講

- [Architecting on AWS](https://aws.amazon.com/jp/training/course-descriptions/architect/)

縁あって上記コースを受講することができました
3日間のコースとなっています

本講座でえられたことは

- 3日間集中してみっちりと学習することができる
- AWSマスターのような方々から直接学ぶことができ得るものが大きい
- 「AWSの考えた」を学ぶことができる

AWS公式だけあってとても内容の濃い講座でした
2日座学、1日ハンズオンでしたが、座学の濃さに頭破裂する寸前でしたｗ
この講座で最も学びがあったのは「AWS」がどのように考えて様々なサービスや機能を作っているか、を知ることができたことです
これをしっかり意識しているかどうかでかなり差が出ると感じます

## 4. AWS公式模擬問題

公式の模擬問題です
オンラインで受験可能で「25問」の問題を解くことができます
点数ではなく%で結果が通知されます

模擬問題で得られたことは

- 試験のリハーサルになった
- 自身の実力を知ることができた

問題は本番と比べるとかなり簡単でした
ですので模擬問題でしっかりと点が取れてないと合格はかなり厳しいと感じます

# 振り返り

自分がなぜ合格できたかを振り返ってみます

- 良質な学習コンテンツを通して学べた
- 問題集を繰り返し解いた

## 良質な学習コンテンツを通して学べた

Udemy講座は本当に役立ちました
この講座だけで本当に合格ラインまではいけると思います
（オススメし過ぎて回し者みたいですね、、、）


`Architecting on AWS` は「AWSの考え」を知れたとても良い講座でした
ただし非常に高額ですので無理に受講する必要はないかと思います
SAA合格に必須ではないでしょう

## 問題集を繰り返し解いた

対策本（1回分）、Udemy講座（3回分）、計4回分の問題を解きました
本番試験の問題と遜色ないレベルの問題で非常に有益でした
4回分全てを繰り返し解き合格点が取れるようにしました

# あとがき

簡単ですが自分の合格に関するまとめです
問題を解くことで合格に近づきましたが、
それに加えて「AWSだからこの場合はこうする」「これは○○のパターンだ」といういった考え方でできたら合格はすぐだと思います
微力でもお役に立ったらと思います
CSSでひし形の蛍光ペン風の下線を引く方法

最近、CSSでひし形の下線（透過版）を引く事があって意外と難しかったので、忘れないようメモしておく。

# 簡単に蛍光ペン風の下線を引く場合
通常、CSSで蛍光ペン風の下線を引く際は以下の情報を見る事が多いのではないだろうか。

~~~html:htmlの記述
<p>募集すると<span class="decorate">反響大</span></p>
~~~

~~~css:css部分の記述
.decorate {
  background: linear-gradient(transparent 70%, #f97b0b 70%);
}
~~~

■ブラウザ表示イメージ
<img width="220" alt="old下線.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/60c3cbf4-f073-d433-c897-2b02f49d7b38.png">

# ひし形の蛍光ペン風の下線を引く場合

~~~html:htmlの記述
<p>募集すると<span class="decorate">反響大</span></p>
~~~

~~~css:css部分の記述
.decorate {
  position: relative;
}

.decorate::before {
  background-color: #f97b0b;
  content: '';
  position: absolute;
  bottom: 3px;
  display: inline-block;
  opacity: 0.75;
  width: 75px;
  height: 5px;
  transform:skewX(-50deg);
  z-index: -1;
}
~~~

■ブラウザ表示イメージ
<img width="284" alt="下線.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429583/f668b2a6-635c-4614-9d66-5d2f981a08d5.png">

■解説
・下線の位置を擬似要素`before`で調整するため、spanタグのclassである`decorate`は、
　`position: relative;`を設定。

・擬似要素`before`を表示する場所として、まずは `position: absolute;` を設定。

・一部のみ下線を引くため、`display:inline-block;`を設定。

・下線を表示するため、`width`、`height`、`background-color`、`content: '';`を設定。

・蛍光ペン風の色合いを出すため、`opacity`を設定。

・下線位置を調整するため、 `top`、`left`、`right`、`bottom`を使い、
　今回は `bottom`のみを設定。

・下線の上に文字が表示されるようにしたいので、`z-index`を設定。

・下線をひし形にするため、`transform:skewX(-50deg);`を設定。
→ transformプロパティのskew(要素を傾斜変形させる)を利用。今回、X軸のみ傾斜させれば良いためskewXを活用。
ROS2レクチャー:初級 -ROS1 style-

[ROS2関係トップページへ](https://qiita.com/NeK/items/7ac0f4ec10d51dbca084)

# 項目

1. [ROS2に関する基本情報](https://qiita.com/NeK/items/ef40cf01637c2b98b4ec)
- [ROS2プロジェクトの作成](https://qiita.com/NeK/items/067bc227f706d7b8a2f3)
- [ROS2最小構成プログラム](https://qiita.com/NeK/items/c9ba8aa3a005087762e2)
- [ROS2のpublisher/subscriber概要](https://qiita.com/NeK/items/bb21b9e24f89f3182d05)
    - ROS1 style，class style共通の情報
- [ROS2の最小構成subscriber](https://qiita.com/NeK/items/2e4e1f78e76594891fc7)
- [ROS2における時間管理・Rate系とTimer系](https://qiita.com/NeK/items/bcf518f6dd79f970bb8e)
    - ROS1 style，class style共通の情報
- [ROS2の最小構成publisher](https://qiita.com/NeK/items/12faa483de71eb55162f)
- [ROS2独自メッセージの作成](https://qiita.com/NeK/items/26751b8ed12976ff977d)
    - ROS1 style，class style共通の情報
- [独自メッセージを用いたROS2 publisher/subscriber](https://qiita.com/NeK/items/f4f186af2401aa4dc13d)
- [ROS2の最小構成service/client](https://qiita.com/NeK/items/bcc938a05a871afe17b0)
- [ROS2のparameter概要](https://qiita.com/NeK/items/556a38782ce65bb81340)
    - ROS1 style，class style共通の情報
- [ROS2の最小構成parameter](https://qiita.com/NeK/items/8206a39a7a2077ef8e4a)
- [YAMLファイルによるROS2のパラメータ設定](https://qiita.com/NeK/items/15bf1e657d8d694592ed)
【都度更新】用語集~覚えてもすぐ忘れてしまう自分のために

#A
## アドエクスチェンジ( AdExchange )
広告枠の入札市場のこと。アドネットワークはクリック課金やインプレッション課金など複数の課金方式があるが、それを広告枠単位(CPM)課金方式で統一し、複数のアドネットワークを対象に配信が可能になる。
これらの処理はユーザーのインプレッションごとに行われている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181254/78c448a4-4093-4550-ff65-5d1c162f2e5e.png)
### news source
+ [アドエクスチェンジの仕組みと特徴](https://dmlab.jp/adtech/adex.html)
+ [Satoriマーケティングブログ](https://satori.marketing/marketing-blog/ad-technology/ad-exchange/)
+ [Web解析士協会](https://www.waca.associates/jp/materials/glossary/ad-exchange/)

追加：07/17/2019
更新：-

---
#D
## ドッグフーディング ( Dogfooding )
自社製品を自社内で使うこと。「Eat your own dog food」が語源とされ、80年代にマイクロソフトから広まったとされる
### news source
+ [シマウマ用語集](https://makitani.net/shimauma/dogfooding)
+ [Weblio辞書](https://ejje.weblio.jp/content/dogfooding)
+ [日経新聞](https://www.nikkei.com/article/DGXMZO81018150X11C14A2X12000/)

追加：07/16/2019
更新：-

---
【JavaScript】voidについて

今日、`void`というものを初めて見知ったので、調べたことをまとめてみます。

##voidとは？
`void`演算子は、式を評価して、絶対に`undefined`を返します。
一体どういうところで使うんでしょうか。
>この演算子は、「戻り値が undefined であってほしい場所に、それ以外の戻り値を持つ式を挿入したい場合」に有用です。
［参考:MDN］(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/void)

ふむふむ。
...?
ということで、実際の使用例をみてみます。

```html:voidの活躍場所
<a href="javascript:void(0)">リンク</a>
```

##javascript:擬似プロトコル
これは`http：`とか`file:`とかと同じ**URIスキーム**の１つです。

> javascript: から始まる URI をサポートしたブラウザに於いて、それは、URI 内のコードを評価し、戻り値が undefined でなければ、返された値にページコンテンツを置き換えます。
［参考:MDN］(https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/void)

リンク内でJavaScriptが実行できちゃうんですね。
MDNでは控えめなイベントハンドラ以外多用しない方が良いと書かれていることにも留意しておきます。

つまり上の例の`javascript:void(0)`でアンカータグ本来の動きを抑制しています。
わざわざイベントハンドラで`preventDefault`を設定しなくて良いので楽ですね。

##ギモン:javascript:undefinedじゃだめ？
これは昔の仕様では`undefined`が予約語じゃなかった為、
undefinedに値を定義したりできてしまっていたからみたいです。

```javascript:昔のundefined
var undefined = 5;  //最悪
var num = 5;
if(num === undefined){
  alert('未定義です');       //定義してるのに実行されちゃう
}
```

昔のものと互換性をつけるために、
`void(0)`で本来のundefinedを保証しています。

なのでこの例に限らず、確実に`undefined`を保証したい場合は、
`void(0)`に置き換えたほうが良いんじゃないかと思います。
Google AIY Kits: Maker向け AI 自作キット, 購入する

#### AIY Projects：Maker向け AI 自作キット

![微信截图_20180829113847.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/8ac5044c-a994-9768-b7b6-52602239bc1a.png)


AIY Projects を使えば、人工知能を活用して、「人とマシンのやりとり」を「人と人のやりとり」に近づけることができます。今後、一連のリファレンス キットがリリースされる予定ですが、その第 1 弾が音声認識です。この最初のプロジェクトである音声認識機能は、次の用途に利用できます。 

###### Google AIY Vision Kit ビジョンキット

![微信截图_20190509183032.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/83108c45-34c8-6d52-024d-a3bcf666a9e2.png)


Raspberry Piの新世代開発ボードを使用すると、Kitsはメーカーが機械学習分野に簡単にアクセスし、成長し、革新し、そしてあらゆる種類の人工知能プロトタイプ製品を完成させるのを支援することができます。
内蔵の機械学習フレームワークであるTensorFlowモデルコンパイラは、業界をリードするテクノロジであり、独自のモデルを追加したり、新しいモデルのトレーニングを開始してVisionキットで完全に機能させることができます。
低エネルギーの人工ニューラルネットワークプログラミング用に設計されたIntel Movidius MA2450プロセッサを搭載し、画像処理速度が30FPSであるため、Vision Kitに優れた画像処理機能を提供します。
組み立てプロセスは、切断やはんだ付けのステップが含まれていないので非常に安全であり、子供たちが関与し、直感的に人工知能技術を体験し、探求することに非常に適しています。
Vision Kitは、軽量で便利なように設計されているため、さまざまな小さなスペースに収まり、既存の製品プロトタイプに適応できます。あなた自身の想像力を使って、Vision Kitをより芸術的で好ましい外観にしてください。

##### Google AIY Voice Kit V2.0 グーグルAIY ボイスキット2.0

![maxresdefault6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448511/688b46b6-e28b-e48e-d418-2107e9222139.jpeg)


スマート スピーカー（AIスピーカー）自作キットGoogle AIY Projects 「Voice Kit」が Raspberry Pi Zero WHとセットになって生まれ変わりました！ より簡単に、すぐにAIを体験できるように、設定もAndroid Appliで行えるように進化しています。

【OK Google】 話題のスマートスピーカーをRaspberry Piで自作しよう！既製品とは違う自作キットだからこそ、自由にカスタマイズ！AIを体験しよう！
【お得なセット】 Raspberry Pi Zero WHとセットとのお得なセットに！ さらに、OS書込済み8GB microSDも付属！あとはスマホ用などのmicroUSB電源を用意するだけ。
【新バージョン】 Pi Zero WH用になり、さらに小型にスタイリッシュに、組立も簡単になりました。セットアップもスマホから行えてより手軽になりました。
【無限の可能性】 赤外線LEDを繋げて、テレビやエアコンを会話で操作！？アイデアと工作しだいですべての家電や機器をコントロール！「暑いなぁ」と語りかければ、エアコンの設定温度を下げてくれる！
【Google AIY Projects】 Voice Kitは、Googleが世界中の人々により手軽に、簡単にAIを利用できるようにと開発したキットです。

既製品ではないので、ユーザーが組み立て、セットアップなどを行う必要がありますが、作りながら、楽しみながら、より深くAIデバイスが理解できます。 はんだ付けなどの必要が無く、小学校低学年ほどのお子さまでも自作いただけます。

###### Google AIY Kits 購入する：https://store.gravitylink.com
コマンドラインだけでMavenリポジトリから直接Jarパッケージをダウンロードして実行する方法

# 概要
- コマンドラインのみでMavenリポジトリから直接Jarパッケージをダウンロードします
- ダウンロードしたJarパッケージをコマンドライン上で実行します

## 何が嬉しいか
- ツール系のJarなどを使いたいとき、POM.xmlなど作成不要で、コマンドラインだけで完結できる

## 環境
- [Maven 3.6](https://maven.apache.org/install.html)

# やりかた

例：groupIdがorg.riversun、artifactIdがrandom-forest-codegen、versionが1.0.0のパッケージをダウンロードしてきて実行したいとき


**1.現在のディレクトリにjarファイルをダウンロードする**

```shell
mvn dependency:get -Dartifact=org.riversun:random-forest-codegen:1.0.0 -Ddest=./
```

（-Ddestを省略すると、ローカルのMavenリポジトリ**.m2**にダウンロードされる。）

**2.jarを実行する**

```shell
java -cp random-forest-codegen-1.0.0.jar org.riversun.rfcode.RandomForestCodeGen
```

(org.riversun.rfcode.RandomForestCodeGenは実行したいメインクラス。省略するとデフォルト指定のメインクラスが実行される）

# まとめ
Jar単体でも動作するツール系をMavenリポジトリから直接ダウンロードし、すぐ実行できて便利です
Asus C434 で GalliumOS を使う

Asus C434 に GalliumOS をインストールしたのですが、再起動時に ctrl + L が使えず、GalliumOS を使えないという状態になりました。

そこで、chroot を使って GalliumOS を使うという手を試してみました。
次のページを参考にしました。
[ChromebookのデュアルブートでGalliumOSが立ち上がらなくなった時の対処](https://qiita.com/Yatima/items/955b68347127eacd4e6d)

1) bash を起動します。

2) sudo bash でルートになります。

```bash
mkdir /tmp/a
GALLIUMOS_ROOT=/dev/mmcblk0p7
mount $GALLIUMOS_ROOT  /tmp/a
mount -o bind /proc    /tmp/a/proc
mount -o bind /dev     /tmp/a/dev
mount -o bind /dev/pts /tmp/a/dev/pts
mount -o bind /sys     /tmp/a/sys
mount -o bind /run     /tmp/a/run

chroot /tmp/a /bin/bash
```

3) cat /etc/os-release の結果です。

```text
root@localhost:~# cat /etc/os-release 
NAME="GalliumOS"
VERSION="3.0 (Bismuth)"
ID=galliumos
ID_LIKE="ubuntu debian"
PRETTY_NAME="GalliumOS 3.0"
VERSION_ID="3.0"
HOME_URL="https://galliumos.org/"
SUPPORT_URL="https://galliumos.org/"
BUG_REPORT_URL="https://https://github.com/GalliumOS/galliumos-distro/issues"
VERSION_CODENAME=bismuth
UBUNTU_CODENAME=bionic
root@localhost:~#
```

4) ネットワークも使えます。

```text
root@localhost:~# ping -c 3 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=52 time=17.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=52 time=16.5 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=52 time=19.5 ms

--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2004ms
rtt min/avg/max/mdev = 16.522/17.878/19.512/1.245 ms
root@localhost:~#
```

5) DNS が使えないので、IP を直撃ちすれば、ssh も使えます。
Java tips GreenMail をJunit5に導入する

# GreenMail をJunit5に導入する
単体テスト用のメール通信ライブラリ「GreenMail」を導入しようと思って調べてみると、
Junit4の@Ruleを使用したサンプルが多くて、JUnit5でどうすればいいのか少し悩んだので
備忘録としてまとめます。

## サンプルソース
Junit5でGreenMailを使用して問題なくSMTP通信できた方法は以下のような書き方です。

```java
class SampleTest {

  // SMTP通信クラス（仮想サーバみたいなもの）
  private GreenMail smtp =
    new GreenMail(new ServerSetup(3025,"localhost",ServerSetup.PROTOCOL_SMTP));
  
  @BeforeEach
  void before() {
    // 仮想サーバ開始
    smtp.start();
  }

  @AfterEach
  void after() {
    // 仮想サーバ終了
    smtp.stop();
  }
}
```

自分でローカルにメールサーバを立ち上げて、開始と終了をソースで明示的に書くようなイメージでしょうか。

## まとめ
JUnit5でも問題なくGreenMailを使えます。
Alibaba Cloud の DataV のデータソースにTable Storeを指定してデータを持ってくる

こんにちは。寺尾です。

Alibaba CloudのダッシュボードプロダクトDataVのデータソースにTable Storeを使う場合の指定方法が日本語のドキュメントになっていないので簡単に書いてみます。



# データソースの追加

英語のドキュメントですがここに書いて有るとおりです。
https://www.alibabacloud.com/help/doc-detail/97683.htm

AKでアクセスをして、インスタンスのインターネットアドレスを指定します。

# DataVのデータソースとして使う

値を取ってくる方法は値を一つだけとってくる方法( `getRow` )と、範囲でとってくる方法( `getRange` )があります。

Table StoreのTableを使う場合は、SQLでは無くJSONで条件を指定します。
ここが非常につかみづらい点でした。

## getRow

値を一つだけ取ってくる場合は、getRowを使います。たとえばこのようなSQLを書きたい場合を考えます

```
select id,test from test where id=2;
```

JSONで書くと以下のようになります

```
{
  "table_name": "test",
  "rows": {
    "id": 2
  },
  "columns": [
    "id",
    "test"
  ]
}
```

`table_name` : テーブル名を指定します
`rows` : フィルタリング条件を指定します。指定するフィールドはインデックスが張ってある必要があります。通常はPKを使います。
`columns` : 応答するデータに含んで欲しいフィールド名を記述します。

## getRange

複数の範囲を検索するのに使います。

また、SQLで例示してみます。

```
select id,test from test where  "InfMin" <= id AND id < 3  limit 4; 
```

このようにキーとなるidにたいして、加減と上限を指定します。また、件数の上限も指定出来ます。 `InfMin`については後で説明します。

```
{
  "table_name": "test",
  "direction": "FORWARD",
  "columns": [
    "id",
    "test"
  ],
  "range": {
    "limit": 4,
    "start": {
      "id": "InfMin"
    },
    "end": {
      "id": 3
    }
  }
}
```

JSONで書くとこのような形になります。

新しく出てきたフィールドを説明します。

`direction` : クエリシーケンスを指定するそうです。良く分かりませんが例の通り "FORWARD"を指定しましょう
`range` : フィルタリング条件を指定します。指定するフィールドはインデックスが張ってある必要があります。通常はPKを使います。 startとendで範囲を指定します。

`limit`：表示される最大行数
`start`：表示結果の開始列です。関連列には索引を作成する必要があります。(この値を含みます)
`end`：表示結果の最後の列です。関連列には索引を作成する必要があります。(この値を含みません)

注意したいのは、startで指定する値は含んだものが返され、endで指定した値は含まない範囲を返します。SQLで指定したものを見ると分かりやすいですが、`"InfMin" <= id AND id < 3` こういう感じなので注意しましょう。

また、特殊な指示詞を紹介します。`InfMin` と `InfMax` は、最小値と最大値を指定できます。最新の値が分からなくても最大と最小が指定出来るので便利です。


## getRange (二つのPKを指定する場合)

二つのPKがあってそれで絞り込みたい場合はどうすれば良いでしょうか。

```
{
  "table_name": "test",
  "columns": [
    "id",
    "id2",
    "test"
  ],
  "range": {
    "limit": 4,
    "start": {
      "id": "InfMin",
      "id2": "InfMin"
    },
    "end": {
      "id": 3,
      "id2": 8
    }
  }
}
```

やることは簡単で、startとendにid2の条件を付加します。

```
select id,id2,test from test where ("InfMin" <= id AND id < 3) AND  ("InfMin" <= id2 AND id2 < 8) limit 4;
```

# まとめ


- Table Storeをデータソースに指定するには、AKでアクセスをする。インターネット経由になる。
- 値を取ってくる方法は値を一つだけとってくる方法( `getRow` )と、範囲でとってくる方法( `getRange` )がある
- 検索方法はSQLでは無く独自のJSON形式
- 検索はインデックスが張ってあるフィールドが必要
- 二つのフィールドを指定して検索することも可能
アイキャッチ画像を簡単に作れる無料ツール[canva]

Twitter、FacebookのヘッダーなどSNSアカウント用の画像や、
Youtubeやブログなどでよく目にすることがあるアイキャッチ画像を作りたい時ってありませんか？
デザイナーでなくても簡単に作れるツールをご紹介します。

# Canva　（基本無料で使えます）
https://www.canva.com/

## 手順
- 詳細な手順はブログにまとめましたのでご覧ください。
 
https://www.wow-creators.com/2019/06/07/おすすめアイキャッチ画像の作り方/

## 作ってみたもの

![3718f83a5620106341ac21f89fea72f8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/77534c92-bf7f-2a8f-3270-c5772411e90b.png)
Pandasでテーブルデータの数値・カテゴリ変数をヒストグラムで一括で表示

# モチベーション
Pandasで読み込んだテーブルの中の数値の列に対しては、histメソッドですべての列をヒストグラムで表示できますよね。一方でカテゴリ変数はちょっと面倒だなと感じたので、もろもろを一発で表示してくれる関数を実装しました。実は簡単にやる方法があるのかもと思いつつも投稿します。

# ソースコード
以下が実装した機能の本体です。

```python

import matplotlib.pyplot as plt
import pandas as pd

def histgram(df, bins=20, ignore_columns=[], fontsize=18):
    nulls = df.isnull().sum()
    
    for column in df:
        if column in ignore_columns:
            continue
            
        column_type = str(df.dtypes[column])
        fig = plt.figure(figsize=[15, 4])
        ax = fig.add_subplot(111)

        if "int" in column_type or "float" in column_type:
            df[column].hist(bins=bins, color="#44ff89")
        else:
            df[column].value_counts().plot(kind="bar")
            
        plt.title(column, fontsize=fontsize)
        plt.tick_params(labelsize=fontsize)
        plt.grid(False)
        ax.yaxis.grid(linestyle='--', lw=1, alpha=0.4, color='lightgray')
        plt.show()
        print("The number of nulls in {} is {}.".format(column, nulls[column]))
```

以下のようなdfというDataFrameがあったときに、histgram(df, ignore_columns=["D"])のような形で呼び出します。ignore_columnsに指定したカラム名は表示するときに無視します。idなどを示した列はこれに指定しましょう。

```python

df = pd.DataFrame({"A": [1,1,2,2,2,3],
                   "B": ["katsuo", "tarao", "wakame", "tarao", "tarao", "wakame"],
                   "C": [1,1,1,2, np.nan, np.nan],
                   "D": [1,2,3,4,5,6]})
histgram(df, ignore_columns=["D"])
```

上記の実行結果は以下の通り。
<img width="878" alt="スクリーンショット 2019-07-16 10.52.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295140/123e05b5-6122-4f22-e05b-fabe2de2e570.png">
<img width="871" alt="スクリーンショット 2019-07-16 10.55.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295140/b92214c9-f567-a13f-c11d-cec4064577f7.png">
<img width="871" alt="スクリーンショット 2019-07-16 10.52.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295140/895112e2-cbec-6abb-7c9c-4f830a74e9ed.png">
DataFrameに含まれるNaNの数も欲しくなるので、ヒストグラムの下に出力しています。
reactのソースをビルドして公開する

## 作業ログ

```aidl
$ npx create-react-app react-build-sumple --typescript
$ npm run build
```

とやってbuildディレクトリに生成されたindex.htmlをブラウザで開くと真っ白になる。

package.jsonにhomepageというプロパティを追加

```aidl
  "name": "react-build-sumple",
  "version": "0.1.0",
  "private": true,
  "homepage": "./",
```

再度ビルドするとブラウザで表示出来るようになりました。

## 参考
- [ReactでTODOリスト（build）](https://iwjp.net/blog/2018/09/26/react_build/)
POSTでデータを送信＆バリエーション機能のコード集

未来電子テクノロジーでインターンをしているもーなです。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

```
<input type="hidden">
```

画面表示させないが、サーバにデータを送りたい場合に使用

```
input
```

inputとは、<form>タグで作成したフォームの中でテキスト入力欄やボタンなどの部品を作成する要素です。

```
input type
```
部品の形式を表します

```
input name
```
部品の名前を指定します

```
input value
```
部品の初期値を指定します

```
required
```
バリエーション機能の未入力

```
placeholder="半角数字"　
```
バリエーション機能の半角数字
[豆知識?]突然死したEC2インスタンスは停止から起動で蘇生できる

# 概要

掲題の通りにEC2インスタンスが突然死し、ホスティングしているサービスがダウン、SSHログイン不可、各種メトリクス取得不可、AWSコンソールからのインスタンスの再起動でも改善されないという時に以下の手順を実行してみてください

この突然死は事前に過度な負荷があったわけでもなく、なにか作業しているわけでもなく、ほんとうに突然ぽっくりとお亡くなることを指します

# 結論

一旦「**停止**」してから「**開始**」することで復活します

# なぜなのか

上記のケースはインスタンスのホスト障害による可能性があります。（最終的にはサポートに確認することをお勧めします）
一旦停止し、再度起動することで**正常なホスト上でインスタンスが起動される**仕組みのようです（サポート担当者から教えて頂きました）
DonkeyCar カメラ画像をVNC経由でホストPCに表示する

(1)Raspbian はLite版ではなくDesktop版を使用する．
デスクトップのメニューかターミナルのraspi-configでVNCを許可する．
(2)ホストPCにVNC Viewer をインストールする．
#ラズパイのmycar/manege.py を編集する
##class DriveMode: を修正
###追加
import cv2
###V.startの前に追加
    class Disp:
        def __init__(self):
            cv2.namedWindow('DonkeyCamera', cv2.WINDOW_NORMAL)

        def run(self, image):
            try:
                tmp = image.copy()
                cv2.imshow('DonkeyCamera', tmp[:,:,::-1])
                cv2.waitKey(1)
            except:
                pass

    V.add(Disp(), 
          inputs=['cam/image_array'])
##drive起動の次に追加
        cv2.destroyAllWindows()
#manage.pyの起動
VNC経由で起動する事．
SSH接続で起動は不可．
Macのネットワーク環境（プロファイル）をコマンドから切り替える

## はじめに

この記事ではMacのネットワーク環境（プロファイル）をコマンドから切り替える方法を説明します。

ネットワーク環境は「システム環境設定 - ネットワーク」で表示される以下の部分の設定です。

<img width="663" alt="スクリーンショット 2019-07-16 9.52.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/67384/6b0529e5-6865-da65-3540-79d1da9ecf09.png">

## なぜコマンドから切り替えたいのか

そもそも普通の人はネットワーク環境をいじる必要はないのですが、僕の場合会社ではProxy経由が必要でありそのためにいくつかの設定をしています。

この設定を行うと社外でネットワークを繋ぐときにある問題が生じることがわかりました。
それはWifiなどでポップアップ認証（同意ボタンを押すようなもの）が必要な場合に、ポップアップが表示されないという問題です。
\# 現在JALさんのWifiに繋いでいますが、ポップアップ認証でした

そういったときは"手動で"ネットワーク環境を切り替えてるのですが、毎回手動は億劫なのでコマンドで済ましてしまおうというのが今回の趣旨です。

## 方法

`networksetup`を使えば簡単に行なえます。

ざっとコマンドから必要そうなオプションを以下に抜き出しました。

- `networksetup -listlocations`: ネットワーク環境リストを表示する
- `networksetup -getcurrentlocation`: 現在のネットワーク環境を表示する
- `networksetup -switchtolocation [location]`: ネットワーク環境を`[location]`に切り替える

以下が切り替えの手順になります。

```bash
# 僕の環境では「Proxy」、「NoProxy」の２つが設定されています
$ networksetup -listlocations           
Proxy
NoProxy
# 現在の「Proxy」が設定されています
$ networksetup -getcurrentlocation                                                                                
Proxy
# 「NoProxy」に切り替えてみます
$ networksetup -switchtolocation NoProxy
found it!
# きちんと切り替わりましたね
$ networksetup -getcurrentlocation      
NoProxy
```

## おわりに

Proxy環境、非Proxy環境では環境変数の設定も書き換えないといけないことがほとんどだと思うので、今回のネットワーク環境の切り替えも含めた一連の処理をシェルスクリプトにまとめるととても便利になるかと思います。
KerasでマルチGPUで学習するときに発生したエラー「Check failed: cudnnSetTensorNdDescriptor」への対応

## ある日のこと

- 新しい深層学習モデルを試すためにモデルを書き換えたところ、1エポック終了後に以下のエラーが発生した。

> 2019-07-16 10:01:06.027332: F tensorflow/stream_executor/cuda/cuda_dnn.cc:503] Check failed: cudnnSetTensorNdDescriptor(handle_.get(), elem_type, nd, dims.data(), strides.data()) == CUDNN_STATUS_SUCCESS (3 vs. 0)batch_descriptor: {count: 0 feature_map_count: 64 spatial: 16 144 256  value_min: 0.000000 value_max: 0.000000 layout: BatchDepthYX}
中止 (コアダンプ)

## 対応

fitの引数に指定してあるvalidation_dataのサンプル数がミニバッチの倍数になっていなかったのをミニバッチの倍数になるように修正したら動いた。

## 謎

めんどくさいことに上の条件を満たしていなくても動いてしまうことがある。

## 参考情報

- [Crash when using multi_gpu_model and n_sample is not a multiple of batch_size](https://github.com/keras-team/keras/issues/11434)
- [\`Check failed: cudnnSetTensorNdDescriptor\` when transfer learning with pretrained Keras model
](https://stackoverflow.com/questions/54122858/check-failed-cudnnsettensornddescriptor-when-transfer-learning-with-pretraine)
第９回　Raspberry Pi で監視カメラを作ろう！　～静止画配信(HTTP)編～

Raspberry Piと専用のカメラモジュールを使用し、ONVIF対応の監視カメラを作成する[シリーズ記事](https://qiita.com/lis-hanzomon/items/cc1f7f316fbeb9579b28)です。
本記事は[リンク情報システム株式会社](https://www.lis.co.jp/)の有志が作成しています。

---

前回の章で静止画をJPEG形式で取得する事ができましたので、その画像をネットワーク経由で参照できるようにしたいと思います。
後述のONVIFの仕様に従うため、HTTPプロトコルで静止画を配信できるように実装します。

#静止画配信 (HTTP)
###mongooseを使用してHTTPサーバー構築
Apacheやnginx等のHTTPサーバーを別途インストールし、公開対象のフォルダに対して画像ファイルを出力する事で、HTTPによる静止画配信は実現できるかと思いますが、ここでは、mongooseと言うオープンソースのWEBサーバーを利用してみたいと思います。

mongooseを使用することで、HTTPサーバーのポートの設定や起動・終了の制御を自分で容易に制御できるようになります。
※Apache等のサーバーを利用した場合は、設定ファイルの書き換えをプログラムの中から実行する等、少し煩雑な仕組みが必要になります。

mongooseは以下のサイトからダウンロードできます。
参考元：[https://github.com/cesanta/mongoose](https://github.com/cesanta/mongoose)

examples/simplest_web_server/simplest_web_server.c を元に、HTTPサーバー実装時のポイントとなる処理を抜粋して解説します。

静止画配信(HTTP)処理の流れは以下のようになります。
　1. 初期化とサーバー設定
　2. リクエスト受信開始
　3. リクエスト受信
　4. レスポンス送信

#####1.初期化とサーバー設定 (main関数)
待ち受け対象のポート番号を指定し、HTTPサーバーを初期化します。

```c
mg_mgr_init(&mgr, NULL);
mg_bind(&mgr, s_http_port, ev_handler);

mg_set_protocol_http_websocket(nc);
```

#####2.リクエスト受信開始 (main関数)
mg_ngr_pollを繰り返し呼び出すことで、クライアントからのリクエストを受信します。 

```c
for (;;) {
    mg_mgr_poll(&mgr, 1000);
}
```

#####3.リクエスト受信 (main関数)
リクエストを受信すると、mg_bindで設定したev_handlerが実行されます。

```c
static void ev_handler(struct mg_connection *nc, int ev, void *p) 
{
    if (ev == MG_EV_HTTP_REQUEST) 
    {
        /* リクエスト受信 */
        struct http_message* hm = (struct http_message *)p;

        char uri[255];
        mg_vcpy(&(hm->uri), uri, sizeof(uri));
        printf("uri = %s\n", uri);

        /* uri に従い処理を実施 */
        /* 処理内容の例は4.レスポンス送信を参照ください。 */
    }
}
```
uriや指定されたパラメータに従った、処理を実装します。

#####4.レスポンス送信 (main関数)
テキストデータを送信したい場合は、以下のようにmg_send_head関数でヘッダを、mg_printf_data関数でテキストデータを送信します。

```c
mg_send_head(nc, 200, strlen("test"), "Content-Type: text/html; charset=utf-8");
mg_printf_data(nc, "test");
```

画像データの場合は、以下のようにmg_send関数でバイナリデータを送信します。

```c
unsigned char* data      = aaa; /* 画像データ */
int            data_size = bbb; /* 画像データのサイズ */

mg_send_head(nc, 200, data_size, "Content-Type: image/jpeg; charset=utf-8;\r\nCache-Control: no-store\r\ninline; filename=test.jpg");
mg_send(nc, data, data_size);
```

###まとめ
最近はクラウドサービスといった、HTTPプロトコルでAPIを提供するサーバーがありますが、mongoose.c / h を組み込み、上記のような処理を実装するだけで、そのようなサーバーも簡単に作成する事ができます。
実際に使用する場合は、セキュリティ上のリスクを十分に検証する必要がありますが、IOT用として、このような軽量なHTTPサーバーが、とても重宝します。

---
[インデックス記事へ](https://qiita.com/lis-hanzomon/items/cc1f7f316fbeb9579b28)
[第８回記事へ](https://qiita.com/lis-hanzomon/items/d5bbd68c7e1ab38efdad)
[第10回記事へ](https://qiita.com/lis-hanzomon/items/055ebf703026734cd97f)

---
[リンク情報システム株式会社](https://www.lis.co.jp)では一緒に働く仲間を[随時募集](https://www.lis.co.jp/employ_top)しています！
また、お仕事のご依頼、ビジネスパートナー様も募集しております。[お気軽にご連絡](https://www.lis.co.jp/inquiry)ください。
プログラミングスキルを上げるためにやるべき事


# プログラミングスキルを上げるためにやるべき事

## そんなの人それぞれ

　人間は各々で適性が異なります。得意なことも異なれば、その時点で持っている知識量も違い、地頭力や集中力もまったくバラバラです。そんな大きさも形もバラバラな人間を一括りにして「こうすれば良いんだ」と言ったところで、それは暴言も良いところです。

　「それを言ったら始まらないよ」ということで、自分に合ったやり方を紹介していこうと思います。


## 基本的な考え方

- 勉強はしない   
 日進月歩で進んでいくこの業界で勉強しても苦痛なだけです。だから勉強なんてしてはいけません。新しいテクノロジーに興味を持って、手元で使えるものはイジり倒すだけです。知りたいと思ったらとことん調べましょう。それを勉強だと思った時点で試合終了です。もちろん努力するなんてとんでもない話です。

- セミナーや学校で得られるもの  
　学校は勉強をする場ではありません。きっかけをもらう場所です。どうせ時間が限られているのです。そこで知識として得られるものなど高が知れています。講師が紹介している手法があるとしたら、それを頭の中で自分なりに最適化して、常により良い方法を考えるわけです。そして家に帰ってから自分なりの方法で実装し直します。そこで上手くいったら、「よし勝った」とほくそ笑むのも良いでしょう。
　その他、セミナーで得られるのはIT技術面以上に、プレゼンテーションの仕方です。うまい人なら参考になるし、下手なら反面教師です。

- 作りたいものを作る  
　自分が作りたいと思ったものをとことん作りましょう。初めて触る言語でもなんでも、とにかく作り始めましょう。言語仕様は作りながら確認すれば良いだけです。逆に、最初に攻略法を頭に叩き込んむと知識は身につきますが、スキルの成長度が確実に落ちます。準備など適当に済ませて、手と頭を動かしましょう。

- 一通り出来るようになったら入門書を読む  
　作りたいものを作っていると、それなりにスキルが上がり、使用した言語や環境、アーキテクチャの知識が向上しています。ここで関連の入門書を読むと、色々とすっぽ抜けていた知識が確認できます。そこに達する前に入門書を丁寧に読んでしまうと、試行錯誤するという重要な工程が無くなってしまいます。  
　結果として、今後起こりえる大きな壁の突破が困難になります。内容がまとまっていてだれからも評価の高い入門書は、最終的な到達点を考えた場合、まったくオススメできません。ゲームを始める前からそのゲームの攻略本を手にする人は、攻略本の無いゲームに出会ったときに対処が困難になるのです。

- 自分のスキルが上がったと思った時点でIT系の資格試験を受ける    
 資格試験は実務スキルには直接結びつきません。そのため、何も無い状態から始めるのは全く無意味です。よくある事例で、未経験でIT系の資格試験の勉強を始める、これほど時間の無駄遣いはありません。何にも分かっていないのに試験対策しても、タダの暗記にしかならず、身につく部分が極わずかです。  
　では何のために資格試験を受けるのかと言えば、自分がすっ飛ばしてしまった知識を確認するためです。自分の知識と一般常識の擦り合わせが必要なのです。自分なりのスキルなり知識を身につけた後にこそ必要なものなのです。
　
## まとめ

　最初に書いた通り、スキルを向上させる上で、誰にでも適用できる万能な方法などありません。世の中には誰かに指示されないと何をやって良いか分からない人や、苦痛だけど食うために仕方なくやっている人もいるわけです。そういう人に、自分でテーマを見つけて研究しろと言ったり、好きにならなければ上達しないと言うのは、言っている側の無理解です。人間は色々な性質や考え方、相性を持っています。自分の得意分野で偉そうにしていたところで、不得意分野に放り込まれた途端にタダの雑魚なのです。雑魚になった状態で同じ事が言えるかと言えば、もちろん言えないでしょう。

　結局のところ、自分に合った方法は自分で見つけるしかありません。人から指示されるのが苦痛だから自分から動くという人もいれば、指示が無いと不安で仕方ないという人もいます。人から定期的に課題をもらって指示通りに進めた方が上手くいく人もいますが、指示が細かいと能力を発揮しきれない人もいるわけです。

　運が良ければ誰かが、自分に合った方法を見つけてくれるかもしれません。ただし、誰かに見つけてもらう場合もゼニゼニしているメンターやスクール業者に気をつけてください。

　人それぞれです。自分に最適なもの、そんな方法が見つかると良いですね。




※以下、[k73i55no5](https://qiita.com/k73i55no5)さんからいただいたものを追記

- 不本意な勉強はしない
 日進月歩で進んでいくこの業界で自分が望まない勉強をしても苦痛なだけです。そういう勉強はしてはいけません。新しいテクノロジーに興味を持って、手元で使えるものはイジり倒すだけです。知りたいと思ったらとことん調べましょう。自分が不必要だと捉える技術を習得するために努力するなんてとんでもない話です。

- 何でも一括りにして批判しない
　知見が狭い人は、大抵そのタイプです。学生時代にそういう人であったパターンは多いのではないでしょうか。ただ、社会人にもなって公の場でそういう発言は、あまりにも恥ずかしいのでやめましょう。万が一誤解を招きうる発言として指摘されたとしても、それを受け入れるかどうかはさておき、皮肉で返すなんて子供じみたことをしてはなりません。
深層学習（後編 1）：「演習課題」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/c0df785a-eaa7-5ea6-8eff-d61088be9bf7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/73d3ae61-6d21-2bf0-a5ea-f22b28e37b06.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/d6810a12-e50d-c9bd-4b3d-1d73796321d9.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/3cafd13e-04a1-cdc5-738a-4dc1ddbb214a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/4f8f06c1-1496-7af3-1633-e29b225a6f02.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/309cd302-d7f7-56c3-48e0-cf5087e6c11e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415265/4afbbbba-eda9-dcec-2aac-eba77281afd2.png)
「ModuleNotFoundError: No module named」の１つの解決方法

#はじめに
こんにちは。
私は、大学4回生で、プログラミングを勉強しています。
現在、未来電子テクノロジーでプログラミング開発コースでインターンを行なっています。
今回は、Dockerの仮想環境の立ち上げ、djangoを使用した際に出たエラーについてお話しします。
プログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してください。

#エラー内容
まず初めに、dockerの仮想環境を立ち上げ、djangoのインストール、接続も問題なく行えました。
djangoの設定に成功すると、ロケットが打ち上げの画面が出てきます。
この後に問題が起こりました。
それは、URLの設定時でした。
urls.pyに以下のようなコードを書きました。

```
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blogs.urls')),
]
```

このコード内で、「from django.urls import path, include」内にエラーが出ました。
ターミナル上では、「ModuleNotFoundError: No module named 'blogs'」のエラーです。


#解決方法
解決方法を求めるために、問題点を探しました。
それは、以下の２つでした。
１、dockerのバージョンが古い
２、古い使っていないimagesが誤作動を起こしている

１は、docker compose の際に、違うサイトで探した方法で仮想環境を作っている際に、古いバージョンのdjangoをインストールをしてしまったからです。
確認方法は、以下です。

```
>>> import django
>>> django.get_version()
```

２は、何回も失敗していたことが仇となっていました。
未使用イメージの削除は、以下です。

```
$ docker rmi `docker images -q`
```

#まとめ
よくわからないエラーを解決するためには、問題点を見極めることを知りました。
これからに生かせればいいなと思います。
Slackのbot用Webサーバーの不正利用を防止する

Slackでbotを作成するには、Slackからのメッセージを受け取れるようにするため、インターネット上にwebサーバーを公開する必要があります。
URLを特定されないかぎりは、勝手に他者に利用されるようなことは基本的には無いはずですが、万が一にも勝手にbotの機能を使われることがないように対策する必要があります。
公式ドキュメントを見た限りでは、Slack側のIPが公開されていないようなのでIP制限で不正アクセスを防止する方法は無いようです。

以前は`Verification Token`という機能で正当なリクエストかどうかをチェックする機能がありましたが、今は非推奨になったようです。 ( https://api.slack.com/docs/token-types#verification )


代わりに以下のページにて、SlackからのHTTPリクエストが正当なものであることを検証するための機能が紹介されています。

* Verifying requests from Slack | Slack
  * https://api.slack.com/docs/verifying-requests-from-slack

ざっくりと仕組みを説明すると以下が成立すれば正当なリクエストとみなすというものです。

* 利用する情報
  * SigningSecret値 (BotのSlackAppの設定画面で取得できる秘密の文字列)
  * SlackからのHTTPリクエストにつけられた`X-Slack-Request-Timestamp` HTTPヘッダーの値
  * SlackからのHTTPリクエストにつけられた`X-Slack-Signature` HTTPヘッダーの値

* 以下の両方の条件が成立すること
  * `X-Slack-Request-Timestamp`の値の時刻が現在時刻より一定時間（５分とか)以内であること
  * 以下が真になること

```
  signature = "v0=" + HMAC-SHA256ハッシュ化(
     "v0:" +  `X-Slack-Request-Timestamp`の値 + ":" + リクエストのボディ,
     SiginingSecret値
  )

  // タイミング攻撃を防止する等号判定をすること。pythonなら `hmac.compare()`をつかう
  signature == `X-Slack-Signature`の値
```

上記は処理のイメージを掴むための説明ですので、実際の実装方法は前述の公式文書を参照してください。

この検証方法は、HTTPリクエストの情報だけで行うことができるので、Botサーバーそのものでなくても、そのサーバーの前段のApacheなどのProxyサーバーで検証だけを行うようにすることもできそうです。

そこで、動作保証なしですが、nginx + luaを使った検証実装を以下で作ってみました。

https://gist.github.com/namutaka/861ec6b55ec9f9c22a95ff5584e463e8

会社などでBotを活用する場合は、上記をBotゲートウェイとして検証だけを集中的に行うようにすると、安心して誰でもBotを手軽に実装できる環境が作れるかもしれません。


なお、`Signing Secret`の値は外部に漏れてしまわないように管理する必要があるのは当然ですが、会社において社員や退職者が自宅からアクセスしたりすることもできてしまうので、定期的に再生成して入れ替えた方がいいかもしれません。


関連記事:

* Slack Botの種類と大まかな作り方 - Qiita
  * https://qiita.com/namutaka/items/233a83100c94af033575