OmniAICreator/Qiita-1.07M huggingface dataset:
django-ckeditorにコードスニペット機能を追加


django-ckeditorはリッチテキストエディター（多機能な編集機能を持った入力装置？）を提供してくれる便利なライブラリです！

インストール方法は割愛します。（時間があれば別記事で書いてみます！
今回は、ckeditorにコードスニペット（pythonやJSなどのコードをいい感じに表示してくれる機能）を実装する方法をまとめたいと思います。

 

## Step1.  CKEDITOR_CONFIGにプラグインを認識させる。
django-ckeditorの設定をする際に、setting.pyの中に以下のような記述を行っていると思います。

```python:setting.py
CKEDITOR_CONFIGS = {
    'default': {
        'height': 150,  # defaultで高さ150pxに固定という意味
        'width': '100%',  # defaultで親要素の幅に固定　ー＞　便利です。
    },
}

```


少し、設定をいじっていますがこんな感じになっているはずです。

ここでは自作の設定などを追加したりすることができますが、内容が本記事の趣旨と異なりますので別記事で。

続いて、以下のような自作設定に'extraPlugins'という形でコードスニペット機能を追加します。（この他にもdjango-ckeditorはプラグインという形で機能を拡張させることが可能です。

```python:setting.py
CKEDITOR_CONFIGS = {
    'custom_toolbar': {
        'height': 150,
        'width': '100%',
        'toolbar_Custom': [
            ['CodeSnippet'],  # これがコードスニペットの機能
            ['Bold', 'Italic', 'Underline', 'RemoveFormat', 'Blockquote'],
            ['TextColor', 'BGColor'],
            ['Link', 'Unlink'],
            ['NumberedList', 'BulletedList'],
            ['Maximize'],
            ['Styles', 'Format'],
        ],
        'toolbar': 'Custom',
        'extraPlugins': ','.join(['codesnippet']),  # コードスニペット機能のプラグイン

    },
    'default': {
        # 'toolbar': 'Basic',
        'height': 150,
        'width': '100%',
    },
}

```

 

## Step2.  templateでコードスニペットの表示を有効にする。
このままでは、templateにて作成した文章などを呼び出したときコードスニペットが以下のように有効になりません。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400162/28165171-08a7-ffcd-2071-9fe68a2a2b98.png" width="400px">

templateで有効にするためには、以下のJS/CSSファイルの読み込みが必要です。

```html:template
{# テーマに関するcssファイル #}
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">


{# JSファイル＋実行 #}
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>
 
```


これでtemplateでテーマの割当が以下のように行われます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400162/9da0d75f-4116-99d3-fd65-bc3486254440.png" width="400px">

 

## 番外編：テーマを変更する
ちゃんとテーマが割り当てられる用になりましたが、なにか物足りない。。。他のテーマを割り当てたい！というときは以下のサイトから好きなテーマを探して見てください。
各テーマのCDNを利用することができます。

https://cdnjs.com/libraries/highlight.js

 

例えば、monokaiに変更したいときは

```html:template
{# テーマに関するcssファイル #}
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/default.min.css">　-->これを変更

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.15.10/styles/monokai.min.css">　--> 変更後
 
```

上記のように変更したいテーマのcssファイルを指定すれば以下のように好きなテーマを割り当てることが可能です！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/400162/ab7a6ccc-21e7-6933-9495-a91dd0fc7b1d.png" width="400px">


## 終わりに
多くの機能を作成して頂いてありがとうございます。。。先人に感謝です。笑
Cloud FunctionsからPush通知を送信する

この記事は [Firebase Advent Calendar 2019 4日目](https://qiita.com/advent-calendar/2019/firebase) の記事になります。


今回はCloud FunctionsからPush通知を送信する方法に書きます。


## FCMのPush通知について

FCMには <b>「トークンに対してPush通知を送信する」</b> 方法と、 <b> 「トピックに対してPush通知を送信する」 </b> の２種類があります。

使い分けとしては

- トークンに対してPush通知を送信する
    - →ユーザー一人一人に割り当てられたトークンを使ってPush通知を送信する。ピンポイントで一人にPush通知を送信したりする場合に使用する

- トピックに対してPush通知を送信する
    - →ユーザーが購読しているTopicに対してPush通知を送信する。ある特定のグループに対してPush通知を送信する場合によく使われる。


自分の経験上トピックに対してPush通知を送信するパターンは実装したことがないので、基本的にトークンに対してPush通知を送信することが一般的なのかもしれません。


## Tokenに対してPush通知を送信する

トークンの取得方法は公式ドキュメントを参照ください。

- Android → https://firebase.google.com/docs/cloud-messaging/android/client
- iOS → https://firebase.google.com/docs/cloud-messaging/ios/client

ここで保存されたトークンを使ってPush通知を送信します。

```javascript
    const payload = {
      notification: {
        title: "タイトル",
        badge: "1",
        sound: "default"
      }
    };

    const option = {
      priority: "high"
    };

    await admin.messaging().sendToDevice("トークン", payload, option);

```

これでPush通知が送信できます。

## トピックに対して送信する

トピックの購読方法は公式ドキュメントを参照ください。

- Android → https://firebase.google.com/docs/cloud-messaging/android/topic-messaging
- iOS → https://firebase.google.com/docs/cloud-messaging/ios/topic-messaging


```javascript
    const payload = {
      notification: {
        title: "タイトル",
        badge: "1",
        sound: "default"
      }
    };

    const option = {
      priority: "high"
    };

    await admin.messaging().sendToTopic("トピック名", payload, option);

```


以上です。
XCode11でiOS12とiOS13に対応する方法

今開発しているアプリがiOS12以降対応で開発するということで、XCode11で開発を始めました。
iOS12とiOS13でAppDelegateやSceneDelegateで添付の様な画像の様に処理をしています。

AppDelegate
<img width="1067" alt="Screen Shot 0001-12-03 at 21.54.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8433/c644e259-1939-3390-4d25-1593b15d671f.png">
SceneDelegate
<img width="1066" alt="Screen Shot 0001-12-03 at 21.54.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8433/9a9c6116-39f0-5b03-919b-c3dd2490d0a6.png">

これでとりあえず新規に作ったプロジェクトでTargetをiOS12以上としてもiOS12とiOS13で動くようになります。

自分がハマったのはOS12のModalの動作と13の動作で違っている部分でした。

以下のように該当部分のsegueのPresentationを Full Screen か Current Context に変更するとiOS12以前のModal遷移になります。

<img width="254" alt="Screen Shot 0001-12-03 at 22.33.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8433/20ac3c03-fd47-05f1-0a95-077d9256a73a.png">

これで自分の問題だったiOS13でDissmissするとブラックアウトする問題が解決できました。
調べてもなかなか情報として無かったので、他の自分と同じように問題を抱えている人のためになればと思い記事を公開してます。
【Laravel】基本的なルーティングのまとめ


#はじめに
現在Laravelについて学習しています。
その学習の履歴として今回はルーティングについてまとめました。
ざっくりとまとめているので、大枠を掴むためや復習のために見ていただけると幸いです。

#ルーティングについて
今回はHTTPメソッドgetについてまとめます。
全部で9種類です。
ルーティングは下記の形式です。

```php:
Route::get('URL', '処理');
```

処理がクロージャとアクションの場合に分けて説明します
クロージャとは`function(引数)`のことで無名関数という意味です。
アクションとはMVCのコントローラに含まれるものです。
クロージャの場合は６種類で、アクションの場合は3種類です。

#クロージャーの場合
処理がクロージャの場合について解説します
##1. URLからテンプレートをレンダリング
URLからテンプレートにレンダリングする場合について解説します。

```php:routes/web.php
Route::get('/', function () {
	return view('welcome');
});
```

`/`にアクセスすると
view関数により`resources/views/welcome.blade.php`をレンダリングする

##2. URLからHTMLを直書き
レンダリングするだけでなくHTMLのソースコードを直書きすることもできます。

```php:routes/web.php
Route::get('hello', function () {
	return '<html><body><h1>Hello</h1></body></html>';
});
```

`/hello`にアクセスすると
`<html><body><h1>Hello</h1></body></html>`を表示します

##3. 返すHTMLを変数として扱う（ヒアドキュメント）
上記の直書きの場合、HTMLが長くなるとソースが見にくくなります。
変数に代入して、見やすくしましょう

```php:routes/web.php
$html = <<<EOF
<html><body><h1>Hello</h1></body></html>
EOF;

Route::get(‘hello‘, function ()  use ($html){
	return $html;
});
```

`/hello`にアクセスすると、
`$html`を表示します。

```:ヒアドキュメント
<<<EOF
~~
EOF;
```

`~~`の部分を変数に代入できるようにするために、EOFで挟みます。

##4. URLにパラメータを挿入する
URLにルートパラメータを記載する方法を説明します。

```php:routes/web.php
Route::get('hello/{msg}', function ($msg) {
$html = <<<EOF
<html>
<body>
<h1>Hello</h1>
<p>{$msg}</p>
</body>
</html>
EOF;
	return $html;
});
```

ルートパラメータに`$msg`を指定します。

##5. ルートパラメータを２種類にする場合
ルートパラメータを２種類にする場合について説明します。

```php:routes/web.php
Route::get('hello/{msg}/{pass}', function ($msg,$pass) {
});
```

URLの部分にパラメータを記述し、処理の部分に引数にルートパラメータを設定しましょう。

##6. パラメタの入力を任意にする場合
上記の記述方法だとルートパラメータが必須とになります。
そのため、任意のパラメータにする方法を説明します。

```php:routes/web.php
Route::get('hello/{msg?}', function ($msg='no_message') {
});
```

注意する部分は二つです。
- URL部分のルートパラメータに？をつける。
- 処理の引数の部分に初期値を設定する。

#コントローラの場合
まず、コントローラを作成

```:ターミナル
php artisan make::controller HelloController
```

次に、コントローラにアクションを追加する

```php:app/Http/Controllers/HelloController.php
public function index(){
	Return <<<EOF
		<html>
		<body>
			<h1>Hello</h1>
			if (count($msg)>0){
				<p>{$msg}</p>
			}
		</body>
		</html>
		EOF;
}
```

##1. ルーティングでアクションを指定する
処理をアクションに指定しましょう

```php:routes/web.php
Route::get(‘hello’, ‘HelloController@index’);
```

`/hello`にアクセスすると`HelloController`の`index`アクションに飛びます

##2. ルートパラメータの利用
ルートパラメータを設定します。
設定のやり方は上で説明したものと同じです。
入力を任意にするために`?`をつけています。

```php:routes/web.php
Route::get(‘hello/{msg?}’, ‘HelloController@index’);
```


```php:app/Http/Controllers/HelloController.php
public function index($id= ‘noname’, $pass=‘unknown’){}
```
##3. シングルアクションコントローラ
シングルアクションコントローラ（1つのアクションしかないコントローラ）の場合について説明します。

```php:routes/web.php
Route::get{'hello', 'HelloController'}
```

上記の場合はアクション名の指定はいりません。

```php:app/Http/Controllers/HelloController.php
public function __invoke() {}
```

コントローラが少しだけ特殊です。
`__invoke()`が必要です。


以上で基本的なルーティングの説明は終わります。

**疑問、気になるところがございましたら、質問、コメントよろしくお願いします！！！**
無停電電源装置ってなんなの

Qiitaの書き方に四苦八苦していた。

[1日目：[初心者向け]色んなサーバ達の役割を知る](https://qiita.com/ECOHOHOHOO/items/5afee6f8d4827aebb0a4)
↑とても良い記事でしたね。特に3年目以下の若手の方なんかは復習の意味でも読んでみるといいですね。
[2日目：Nginx で WEB サーバを構築してみる](https://qiita.com/guromityan/items/6bc813c7b7587e6a8876)
↑Dockerは食わず嫌いしているのでこの機会に触ってみます。


技術的な話ではないですが停電時対策として使用される無停電電源装置について書いてみます。
インフラをやってる人はいつか触れる機会がくるとおもいます。
（絵は一切準備できなかったので一生懸命想像してね）

# 無停電電源装置ってなんなの
停電が発生するとサーバ達にも電気がこなくなりますよね？
そうなるとブツンとサーバの電源が落ちてしまう＝ぶっ壊れるリスクがあるわけです。
そんなときのために使用されるのが無停電電源装置（UPS：Uninterruptible Power Supply）。

# 使用する目的
停電時にサーバ達へ給電し、サーバを安全にシャットダウンする時間を稼ぐため。
あくまで「安全にシャットダウンするため」であり「電気が復旧するまで踏ん張るため」ではない。

※ちなみに、踏ん張れてもせいぜい数十分程度だし、踏ん張れる時間が長いUPSは高価になる。

# 順番が大事
サーバ上では当然サービスやアプリが動いているはず。
そいつらを正常終了した後にサーバをシャットダウンしないと本末転倒ですね。
電源が復旧したら逆の順番で上げないといけない。
なので↓

- 落とす順番
    - サービス・アプリ→サーバ
- 上げる順番 
    - サーバ→サービス・アプリ

（仮想マシンがある場合はどうなる？考えてみよう）

# そのほかにも色々気を付けることが
- 電源が復旧してもすぐにはサーバへ電気を流さない
    - 復旧してすぐにまた停電したら・・・って考えるといっそのこと20分くらいあげない！としておく。

- サーバが複数あるときはサーバ間の順番も
    - サーバAのあとにサーバBを落とさないと困るの！なんてこともある（特にDBが絡んでくると）

# おわり
初めてのQiitaでしたありがとうございました。
ユーザー視点のプログラムを書くために(1)

# ユーザー視点のプログラムってなんだろう？
今日もシステムは稼働しています。
さて、どうでしょう。
もし、ログインしてとある画面を操作してみたら、なかなか応答が返ってこないなぁ、、、
ということが起きたら。

これにはいくつかの影響が考えられるでしょう。

- プログラムの処理が終わっていない
- メモリ枯渇によるDBの応答不能、エラー
- 上記原因によるWebサーバの停止
- ホスティングサービス上の障害、メンテナンス
- etc

そして最悪なのが、自分が書いたプログラムがその原因だったのパターンですよね。

そうならないようにユーザー視点のプログラムを書けるようになりましょう。
そうすれば、自分の書いたプログラムが常に生きている状態となり、
ユーザーに喜んでもらえるシステムを維持することができます。

# （私的）良いプログラムの3点セット
- プログラム行数が短い
- 処理時間が短い
- メモリ使用が最適化されている
まずはこの3つを意識すれば、大体運用上死なないプログラムになります。
コードレビューやリファクタリングする際も、
この視点を持つことでより良いプログラムにできると思います。

※プログラムの行数を短くするのはリファクタリングのテクニックが
該当するので[リーダブルコード](https://www.amazon.co.jp/dp/4873115655)を読むといいよ！

# 処理時間を短くする
## 文字連結時にはStringではなくStringBuilderを使う
### Stringで文字列する場合

```java

String name = "クアッカ";
name += "ワラビー";
name += "様";
```
コンパイル時

```java

String name = new StringBuilder("クアッカ").toString();
name += new StringBuilder(name).append("ワラビー").toString();
name += new StringBuilder(name).append("様").toString();
```
このように、各オブジェクトが無駄に生成されてしまうことがわかります。
つまりメモリの使用量が一時的に増えます。
※実際はこのぐらいの文字列であれば大差ないですが、
もし巨大な文字列出力する際に、Stringを使ってしまえば、
サーバー上のメモリを逼迫してしまうことになるでしょう。

# 突然訪れるメモリ切れ

俺たちの戦いはこれからだ…！
来週に続かせてもらおうと思います。
2019年phpカンファレンス③～改善失敗して学ぶ、 レガシープロダクトに立ち向かうチーム作り。～

2019年phpカンファレンスでの『改善失敗して学ぶ、 レガシープロダクトに立ち向かうチーム作り。』の講演について、思ったことをまとめてみました。

# 講義資料
https://speakerdeck.com/oogfranz/gai-shan-shi-bai-sitexue-bu-regasipurodakutonili-tixiang-kautimuzuo-ri

# 話を聞いてみて
組織づくりには土台の考え方を固めることが重要なのだと感じました。

失敗を恐れない、挑戦をする。

これは良く言う話ですが、それ以上に「改善する」というフェーズや考えを持てるかがすごく重要なのだと感じました。

# 真似してみたい施策
### 技術負債箱
あ！これ治したい！！
けど、、、今じゃない、、、、、、

っていう負債は結構多く見かけます。
今じゃないけど、「あれ、3時間ぐらい猶予出来たんじゃない？」って時に触って、ちょこっと直して、対応したいというものを準備しておくのは意外と重要かもしれません。

あと負債を洗い出しておけば、負債が再度発生することを抑制できるのではないか。
これって負債だよねという意識をみんなで持っておくと、次に同様の処理を書こうとしたときに、「こういう風にしたほうがいい」という意見が出てきて、負債を作らないということが出来そうだなと思いました。


### スクラム開発での振り返り
何事においても振り返りはすごく重要だと思います。
ただスクラム開発をすると、すぐに次の要件が来て、次々と対応しないといけない。となりかねません。

そういう時こそ細かく振り返る癖付けは重要だと。

一回癖や習慣にしてしまえば、初めの時は大変でも、徐々にそのあたりも自然とできるようになっていくものだと（自分に言い聞かす）。



### 対立していた部署との対話
これはどこでも発生しうるし、結局は売り言葉に買い言葉なんだと思います。

「開発チームのもやもやしか」解決しないようなものだと相手は不快に思います。
みんなハッピーとなるような改善案を常に出して、それの伝え方や進め方も相手をリスペクトした進め方にしていけば、おのずと物事は進むんじゃないかなぁと思います。


### 意識の統一
バイブルを作ろう。

今回の講義だと「リーダブルコード」が挙げられていたが、一例に過ぎないのかなぁと思います。
ほかの本でもいいと思いますし、人でもいいかと思います。

ただみんなが一定の基準で議論ができる土壌を作ってあげると、それを元に会話が広がっていくため、かなり有意義に、かなり有効的に話が進んでいくのだと感じました。

# 重要なこと
改善を恐れない土壌づくり

これが本当に大切なのだと改めて感じました。

今回あげた「真似してみたい施策」ですが、これはあくまで、実際にやったこと。
それをやることが目的ではなく、土壌づくりを目的にしないと、最終的にプロジェクトを進められる組織は作れないのではないかと思います。

それぞれがそれぞれをリスペクトし、また本気で改善していきたいと思わないとなかなか進まないのではないか。
ただ改善はちょっとするだけで、大幅にコスト削減となり、それを次の開発リソースへつなげられたりします。


改善と失敗はなかなかきついものですが、それでもそれを続けること、それに対してどんどん挑戦していく環境こそが本当に大切なことです。
共通テーブル式と一時テーブルの参照可能な範囲の違い

# 一人アドカレ

| 日 | ポスト |
|---:|:------|
|  1 | [一時テーブルが存在していたら削除する](https://qiita.com/sotoattanito/items/10e65399caf34fae3017) |
|  2 | [何度も使う中間テーブルに名前をつけてクエリを見やすくする](https://qiita.com/sotoattanito/items/673fb0ceb543fdd391e2) |
|  3 | [共通テーブル式と一時テーブルの参照可能な範囲の違い](https://qiita.com/sotoattanito/items/9fa81e9acc9af915600f) |
|  4 |       |
|  5 |       |
|  6 |       |
|  7 |       |
|  8 |       |
|  9 |       |
| 10 |       |
| 11 |       |
| 12 |       |
| 13 |       |
| 14 |       |
| 15 |       |
| 16 |       |
| 17 |       |
| 18 |       |
| 19 |       |
| 20 |       |
| 21 |       |
| 22 |       |
| 23 |       |
| 24 |       |
| 25 |       |

# 共通テーブル式と一時テーブルの参照可能な範囲の違い

## 課題
`WITH`句による共通テーブル式と一時テーブルの参照可能な範囲を調べる

## 準備
### 実行環境
 * SQL Server 2017 Standard
   * 2008 R2 Express, 2012 Standardでも確認した
 * SQL Server Management Studio 2017

## 結果
### 共通テーブル式
```sql
-- WITH句による共通テーブル式はその後に続くSELECT文でのみ参照が可能.
WITH [commonTableName] AS (
     SELECT [hoge] AS [column1]
          , [fuga] AS [column2]
       FROM [someTable]
      WHERE [piyo] = 'some-text' )
SELECT [column1]
     , [column2]
  FROM [commonTableName];

-- WITH句が記載されていないステートメントで参照しようとしてもエラーとなる.
SELECT *
  FROM [commonTableName];
```

### 一時テーブル
```sql
/* 一時テーブル名はテーブル名の先頭にシャープがつく.
 * 一時テーブルは同じセッションの中であり、かつ作成したあとであれば
 * CREATE TABLE文前でも参照が可能.
 * (Management Studio上でエラーの赤波線が出たり、クエリ読む人が混乱したりするので避けたい)
 */
SELECT *
  FROM [#temporaryTableName];

-- 一時テーブルの作成.
CREATE TABLE [#temporaryTableName] (
       [id]   INT         NOT NULL
     , [name] VARCHAR(15)     NULL );

INSERT [#temporaryTableName] ( [id], [name] )
VALUES ( 1, 'kapibarasan' )
     , ( 2, 'howaitosan'  )
     , ( 3, 'kapijii'     );

-- CREATE TABLE文のあとなので問題なく参照可能
-- （Management Studioでもエラー表示されないためスッキリ）.
SELECT *
  FROM [#temporaryTableName];
```

クエリ中のコメントに書いてあるので重複となりますが、共通テーブル式は`WITH`句に続く文中でのみ参照可能であるのに対し、一時テーブルは同一セッション中であれば複数の文で参照可能です。

この特徴から私は、ある一文でのみ中間テーブルが必要な場合は共通テーブル式を使い、複数の文中で同じ内容の中間テーブルが必要な時は一時テーブルを使っています。なお、一時テーブルを使う際は同時に『[一時テーブルが存在していたら削除する](https://qiita.com/sotoattanito/items/10e65399caf34fae3017)』で記載した内容も利用し、いちいち一時テーブルを削除する手間を省いています。

### 注意
ここでいう一時テーブルは**ローカル一時テーブル**です。
Transact-SQLには**グローバル一時テーブル**というのもあります。
私は全然使いませんので何も言える立場にありませんので、[こちら](https://docs.microsoft.com/ja-jp/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver15#database-scoped-global-temporary-tables-azure-sql-database)をご確認ください。

## 感想
自分の中の中間テーブルの使い方について言葉にできたのでスッキリ。一度言葉にできると今後の方針もブレずに済みそう。

## 参考
 * [CREATE TABLE(Transact-SQL)#一時テーブル](https://docs.microsoft.com/ja-jp/sql/t-sql/statements/create-table-transact-sql?view=sql-server-ver15#temporary-tables)
EtherCATスレーブに使える半導体 (1)

この記事は [EtherCATについて語る Advent Calendar 2019](https://adventar.org/calendars/4097) の3日目です。

昨日は@kikuyutaさんの [温故知新 IEEE802シリーズで EtherCAT を眺め直す](https://qiita.com/kikuyuta/items/84d891fc1c435cda8537) でした。

さて、今日の内容は・・・

EtherCATスレーブ対応の半導体ICについてです。

調査日は2019年12月です。

今後多くの半導体が出てくると思われるが、ひとまずまとめていきます。
足りないもの、新しいものが出てきた際はコメント頂ければ幸いです。

#マイコン外付けEtherCATスレーブIC

マイコン無し実装というのは、EtherCATの機能をIC一つで機械的に処理をし、実際のデータの扱い方は別のマイコンで行うという、EtherCAT機能だけをICに落とし込んだもの。
チップ自体はEtherCAT以外では使えない専用性があるが、EtherCATの規格に沿っており、更に処理速度も速いので著者はメチャメチャオススメする仕組み。後日この話をまとめます。

## ベッコフオートメーション（Beckhoff Automation）
![スクリーンショット_2019-12-03_23-29-29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/1ec4f4b8-0c72-b794-7113-ebbcef5c3be1.png)

- [ET1100](https://www.beckhoff.co.jp/jp.asp?ethercat/et1100_et1200.htm?id=177466179510)
- [ET1200](https://www.beckhoff.co.jp/jp.asp?ethercat/et1100_et1200.htm?id=177466179510)
 
EtherCATの原型とも言う半導体。
全ての規格はこのICから生まれているようなもの。
OMRONやpanasonicのEtherCAT筐体も確かこのICが使われていたはず。
EtherCATを仕事で利用するなら原典なので間違いないIC。

## Microchip
![スクリーンショット_2019-12-03_23-30-22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/6dc2114f-978e-12a1-28cf-52bab96d8868.png)

- [LAN9252](https://www.microchip.com/wwwproducts/en/LAN9252)

ET1100のコピーに近いサードパーティーIC。
産業用規格で専用ASICを作るってすごい時代なぁ。
Microchipなので、ダイレクトショップで購入が出来た。
あとQFPパッケージがあるのが嬉しい。無事に実装が出来ました。
LANと続く型番は、歴史あるネットワーク関連半導体メーカーSMSC社が関わるIC。
Microchipに買収されてもLANシリーズが継続されて開発されてるの素晴らしい。

## ASIX
![スクリーンショット_2019-12-03_23-30-51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/91856cd2-ccb0-c5a5-2450-182dee006137.png)

- [AX58100](https://www.asix.com.tw/products.php?op=pItemdetail&PItemID=263;77;124)

亜信電子股份有限公司　が漢字表記で、亜って字が良いなぁって個人的に思って居る。
このメーカーは台湾の半導体メーカーで、Youtubeに動画が沢山あるが詳細は良くわからない。
台湾のEtherCAT扱う方に「何でこのメーカーのにしなかったの？」と聞かれる位、向こうでは有名らしい。


## TRINAMIC
![スクリーンショット_2019-12-03_23-31-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12499/64f02f72-9b13-11bd-2d7a-d42a40c3f903.png)

- [TMC8462-BA](https://www.trinamic.com/products/integrated-circuits/details/tmc8462-ba/)

ベッコフオートメーションと同じドイツのメーカー。
情報はあまりないが、スペック的に良さそう。
ただBGAパッケージなので使いどころに悩みそう。



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

以上、４社しか見当たらない件！
やはり半導体で出荷するには敷居が高いのだろうか・・・
その辺り、Microchip(旧SMSC)の先見の目は凄いと思う。
むしろ著者がEtherCATに手を出したのもMicrochip(旧SMSC)がやるなら俺もやる！という同調心なんだ。

さて、あれ？あのメーカーは？このメーカー忘れているでしょ！と思う方も居るでしょう。

Renesas [EC-1]
infineon [XMC4300]
TexasInstruments 

などは、後日マイコン有りEtherCAT半導体として紹介しようと思います。

それでは、今日はここまで！

ありがとうございました！

北神（@nonnoise)

### 宣伝

ここで紹介した **LAN9252** を使用した評価基板をスイッチサイエンスにて販売しております。
https://www.switch-science.com/catalog/5917/
よろしければご覧頂ければと思います。

## 追記

公式サイトにもっとわかりやすい資料がありました。
https://www.ethercat.org/jp/downloads/downloads_70CA98412F1440E695C5AA1D2BC2418F.htm
まとめる必要なかった説！！汗
【3日目】シンプルデータベース実装①

# まえがき
それではさっそくシンプルデータベースの実装に入ります。目標は以下の機能を実装することです。

* テーブルを作成する
* データを挿入する
* データを取得する
* データを更新する
* データを削除する
* テーブルを削除する

## テーブルデータの保持形式
テーブルデータをシステム内部でどのように保持するか。今回はデータが挿入されたら少し加工してから保持する。挿入性能は落ちるが、検索性能が上がるはず。テーブルにデータを挿入した時の内部の動作は↓みたいになる。

1. データが挿入される
2. オブジェクトIDを振り出す
3. オブジェクトIDをキー、挿入されたデータをバリューとして保存する（キーバリューストア）
4. 各カラムの値をキー、オブジェクトIDをバリューとして保存する(インデックスを張る)
5. データ挿入完了

3番と4番が内部にデータを保存する操作になる。例として、挿入したいデータは果物の値段で、[りんご,100円]、[みかん,80円]、[ぶどう,300円]の3レコードとする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201287/75c8a299-af5b-df56-3417-635351a945ee.png)

まず、これらのデータはそれぞれオブジェクトIDを振り出して、オブジェクトIDをキー、果物の値段をバリューとするキーバリューストアに保存する。（3番の操作）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201287/4e7b2071-49f7-d55d-f489-e815c952da36.png)

次に、各カラムごとにカラムの値をキー、オブジェクトIDをバリューとするカラムインデックスを作成する。（4番の操作）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201287/45372d50-d2ac-ff64-8540-e8b96c95755a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201287/baae180f-6d15-6f57-486e-87d29e54015d.png)

お分かりとは思いますが、検索するときはカラムインデックスからオブジェクトIDを取得して、キーバリューストアにデータを探しにいく、という流れになります。

# まとめ
挿入されたデータはオブジェクトIDによるキーバリューストアに格納され、各カラムに張られているインデックスから、オブジェクトIDを特定してアクセスするという構成としてみました。
今回は挿入と検索のところだけ説明しました。
B - ROT N

過去問やっていきます
AtCoder Beginner Contest 146
Aは流石にやらなくていいかな
#問題
https://atcoder.jp/contests/abc146/tasks/abc146_b
<img width="1105" alt="スクリーンショット 2019-12-03 22.57.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/5a81bf06-169d-24f0-fd5f-b2bc59df74c8.png">

#1回目
##回答
```ruby
N = gets.to_i
S = gets.chomp

alf = ['A','B','C','D','E','F','G',
  'H','I','J','K','L','M','N','O','P',
  'Q','R','S','T','U','V','W','X','Y','Z']

result = ''
for c in S.chars
  x = alf.index(c)
  x = ( x + N ) % 26
  result += alf[x]
end

puts result
```
##結果
<img width="1088" alt="スクリーンショット 2019-12-03 22.59.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/9b0326e2-4bd0-47b0-3e12-42cb279d6b71.png">

#2回目
##回答
```ruby
N = gets.to_i
S = gets.chomp

N.times do |i|
  S = S.tr('A-Z', 'B-ZA')
end
puts S
```
##結果
<img width="1088" alt="スクリーンショット 2019-12-03 23.00.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/68693a55-1dd2-04ab-5443-fe3982b6e7e2.png">

#感想
流石にAからZ書かなくてもいい方法あるよな〜と思ったけど、書き方が分からなかった。。。
メモリ使用量9割くらい減ったな。。。

#追記
コメントを頂いて、もう一回やりました！ありがとうございます！
あと alphabet の頭をとったつもりが alf となっていたのめっちゃ恥ずかしい
(alfabet はポーランド語らしい。へえ〜)
##回答
```ruby
N = gets.to_i
S = gets.chomp
a = [*"A".."Z"]
puts S.tr(a.to_s, a.rotate(N).to_s)
```
##追記2

```to_s``` では配列の文字を繋げられないとのご指摘を頂きました。
今回はたまたま上手くいきましたが、
本来の想定では以下のコードの挙動になる予定でしたので、
追記しておきます！

```ruby
N = gets.to_i
S = gets.chomp
a = [*"A".."Z"]
puts S.tr(a.join, a.rotate(N).join)
```
##結果
<img width="1089" alt="スクリーンショット 2019-12-04 13.02.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307024/2abb09b1-0968-0201-54ff-ae667f7fe3a1.png">
Flutterのwidgetについて、build完了直後コールバックが欲しい時に使えるやつ

#結論

```dart
WidgetsBinding.instance.addPostFrameCallback((_) => ここに関数とか処理置けば良い);
```

Flutterの1.8.4から実装された機能らしいです。
逆に何でそれまでは無かったんですかね、ってぐらい有り難い。


引用元：
https://stackoverflow.com/questions/49466556/flutter-run-method-on-widget-build-complete

##何でこれが必要になったかの事例メモ
http.post() 通信で受け取ったJSONデータで
UIに表示する内容を変えるタイプの画面を作成する形のアプリを作っている。
普通に表示するだけならまぁ、FutureBuilderで全部作っちゃえば良い。
ところが、追加仕様が発生した。

```
仕様1. 有効期限付きのセッショントークンを通信ごとにサーバーから発行
仕様2. トークンが有効期限切れだったら、どの画面の通信でもかならずログイン画面に戻す
```

この段階でFutureBuilderは使えないことが確定した。
**FutureBuilderの builder 内で Navigator の関数を使うとエラーになる**のである。
仕様2.に対応するには、異常系の時に必ず Navigator.pushAndRemoveUntil を実行する必要がある。

というわけで、こういう実装にした。
今の所ちゃんと動いたので、これでいいと思う。多分。

1. 通信時に、ローディング表示用Widgetを追加表示
2. ↑のWidgetにて、WidgetsBinding.instance.addPostFrameCallback で future を実行
3. future 完了結果を取得
4. 正常系、異常系それぞれで Navigator を使って別画面に遷移する
【Swift】UI自動化テストフレームワークEarlGreyを使ってみた

この記事は、[TECOTEC Advent Calendar 2019](https://qiita.com/advent-calendar/2019/tecotec) の4日目の記事です。

開発環境：Xcode:10.2.1
開発言語：swift4.0

# UI自動化テストフレームワークEarlGreyとは
Googleが作ったネイティブiOS用のUI自動化テストフレームワークです。
[Google公式のGitHub](https://github.com/google/EarlGrey)
XCTestを拡張してありXcodeまたはコマンドラインにて実行が可能。

# EarlGreyを選んだ理由
Androidと一緒に開発することが多いので、
Espressoと（たぶん）対になってるEarlGreyを使ってみようと思った。
あとはただの好奇心！

## いざ導入！
しようと思ったら、まず記事が少ない！
2016年とかの記事ばっかりでそもそも情報少なくて心が折れかけながら
公式の[Install and run](https://github.com/google/EarlGrey/blob/master/docs/install-and-run.md)を見ながらとりあえず入れてみる。

そして案の定詰まった。。。

【原因】
流し読みしてたせいでstep2のAdd EarlGrey as a framework dependencyという部分を、実行し損ね2時間ぐらい無駄にしながらなんとか無事に導入完了。

## UITest書いてみる

Googleが用意してくれた[チートシート](https://github.com/google/EarlGrey/blob/master/docs/cheatsheet/cheatsheet.png)とにらめっこしながらそれっぽいものを探して、
ボタンを押して表示されるテキストが正しいかチェックするテスト書いてみた。

```swift:sample.swift
import XCTest
import EarlGrey
    
@testable import test

class testTests: XCTestCase {

    func testExample() {
        // ボタンをタップする
        EarlGrey().selectElementWithMatcher(grey_accessibilityID("testButton")).performAction(grey_tap())
        // TESTというテキストが表示されていることを確認する
        EarlGrey().selectElementWithMatcher(grey_text("TEST")).assertWithMatcher(grey_sufficientlyVisible())
    }
}    
```
とりあえず問題なく動いた。

## 2、3日遊んでみての感
・EarlGreyはシステムアラートのテストができない。（結構致命的）
・別にandroidに合わせてフレームワーク使う意味もない気がしてきた
・XcodeのXCUITestの方が記事がたくさん出てくる（当たり前）
・実は[EarlGrey2](https://github.com/google/EarlGrey/tree/earlgrey2)がある。。。

【ちょっとだけEarlGrey2について】
EarlGreyの時にはテストできなかったアラートなどもテストできる用になっているので、今から触るなら断然EarlGrey2がオススメしたいが・・・
まだベータ版なので、試しに使うのはいいが本番稼働に使うのは微妙。
結構Issuesもあるし、毎日のようにコミットが走っているのでなんとも言えない。。。
そして案の定記事はほぼないのでそこがネック。
ただgoogleなので公式サンプルはそこそこある（全てが最新とは言わない）。

個人の感想ですが、XCUITestでいいかなーと思いました。
データマネジメント導入・推進のヒント（ADMC2019より）

#はじめに
2019年11月12日、ADMC2019（Asian Data Management Conference 2019）というイベントに行ってきました。

※ADMC公式サイト：http://www.dama-japan.org/ADMC2019.html

『データクオリティ海外最前線』と題したデータ品質に主眼を置いたテーマでありながら、当日はデータマネジメント全体の話も含まれていました。講演の話を私なりに6つにまとめてみました。

題して、、


###企業にデータマネジメントを導入・推進するためのヒント6選！



1. 日本企業は、トップダウンによるデータマネジメントの導入が難しい、どうすればよい？
2. データマネジメント導入の第一歩は？
3. データマネジメントを拡大していくには？
4. どんな人財を揃える必要がある？
5. 自社だけでは厳しいので、外部に協力をお願いしたいんだけど・・・
6. データマネジメントって、、例えばどんな取り組みが大事？

こんな疑問や悩みに答えていきます。


#1. 日本企業は、トップダウンによるデータマネジメントの導入が難しい、どうすればよい？？
###A. ストーリーで経営陣を説得しましょう

今や新聞を開けば必ずデータ関連のニュースがある。日本企業の経営陣もデータの重要性に気づいてはいる。しかし、データマネジメントの必要性までは理解できておらず、そのための予算や人員の確保に消極的になりがちなことがある。これに対しては、経営陣にデータマネジメントの必要性を理解してもらうための「ストーリーを語る」というのが良いという。

つまり、経営陣と話す機会がある度に、他社の事例や身近な出来事を例に根気強く分かりやすく伝える、ということだ。例えば、扇風機を買いに行った際に店員の端末情報では在庫切れとなっていたが、実際に置き場へ行ったところその欲しい扇風機は存在していた、という身近な出来事を話した。つまり**データ品質管理の不徹底により、顧客の信用が失われ、売上の機会損失に繋がった**、というストーリーだ。

トップの説得に画期的な方法は存在せず、具体的なストーリーを常々語るという日々の草の根運動が大切なようだ。


#2. データマネジメント導入の第一歩は？
###A. Small Startで始めましょう
データマネジメントの導入はSmall Startが良い。例えば今ある組織をベースに小さく始め、小さな成功を重ね、その実績を周囲に宣伝して知ってもらい、少しずつ味方を増やして活動を拡大していく。失敗したときは、痛みから学び、改善のループに取り入れて次に活かしてく。

最初から全社規模の完璧な体制構築と施策実行を目指すのではなく、**小さな成功体験を積み重ねて認知させるという、急がば回れの精神が大切なのだ。**

#3. データマネジメントを拡大していくには？
###A. データマネジメントの活動に関わる組織と人に対して、適切な権限と責任を与えましょう

具体的には、データマネジメントを拡大していくための要素として、次の5つが紹介された。

- データマネジメントを担う人のキャリアパスを考え、役割分担と責任の明確化を行う
- データマネジメントの正式な責任者であるデータオフィサーのポストを作る
- これまでの成果を組織で共有する
- データ戦略の意思決定に携わることができる組織を作る
- データマネジメントを推進する際の基本方針やポリシーの制定を行う

#4. どんな人財を揃える必要がある？
###A. 好奇心と人間性の高い人を確保しましょう
具体的には、データマネジメントの推進に必要な人財として、次の5つの特性が大事だ。

- データに興味があり、実際のデータを触ることを厭わない
- 他者の気持ちに寄り添い、共感的なコミュニケーションができる
- 組織の変革に積極的な考えを持っている
- 企業の戦略策定や意思決定などに関わりたいという意欲
- 常にオープンで好奇心があり、高い学習意欲を持っている

こんな人財いるのか？と疑問を抱く人もいるかもしれないが、潜在的には多いと感じる。導入段階ではスキルはそこまで必要ない。むしろ、熱意ある中堅や若手をきちんと掘り出せるかどうか、余計な組織のしがらみが邪魔してないか、適切な権限と責任を与えることができるか、ここが大事だ。

#5. 自社だけでは厳しいので、外部に協力をお願いしたいんだけど・・・
###A. 適切なメンター役を見つけましょう

データマネジメントの学習には時間がかかるので、直近では外部の専門家の力を借りて良い。ただし協力を依頼する際は、「適切なメンター役」になってくれる人に頼みましょう。

データマネジメントの悩み相談に乗りながら適切な助言や指導を行い、自社の人材育成を支援してくれる専門家ならいいが、そうではない人も多い。専門家は現場の声に耳を傾けて、組織が抱える問題や症状に適したアドバイスを提供しなければならない。確かに、素晴らしいツールの導入を薦めてきても、真のニーズを満たさないことはよくある。

机上だけの理想論的な助言は不要であり、ある程度時間をかけても現場に深く眠る本当の課題を引き出す役割がメンターに求められることなのだろう。


#6. データマネジメントって、、例えばどんな取り組みが大事？
###A. データ標準化の重要性が高まっています

多くの企業で、データの整合性維持に多くの時間が割かれている。需要が高いデータサイエンティストを高報酬で雇っても、データの前処理に作業時間の8割が費やされている会社もある。

データが標準化されていれば、その8割の時間を本来の分析・解析作業に充てられる。その結果生まれる発見は重要な意思決定の材料にもなり得るし、企業の成長戦略を支えることにもなるはずである。

#最後に
イベント参加者は100名を超えており、まだまだデータマネジメントは陽の当たらない分野ではありますが、確実に認知は広がっていると感じました。

今後もこのようなイベントに参加して、レポートとして知見をまとめてQiitaで共有できたらなと思います。

(記事内容は個人の見解であり、会社とは関係ありません)
Lambda x MySQLでデータを更新してもクエリ結果が変わらない（キャッシュされているような振る舞いをする）

## 問題
表題の通りだが、Lambda x MySQL(RDS)でレコードを変更しても、Lambda上でDBに対するSELECT結果が変わらないという問題が起きた。その場しのぎとしてLambdaのコードを変更するとデータ変更が反映されるため、その方法で運用をしている環境だった（または、少し時間を空けて再クエリーしていた）。問題の解消法がわかったので載せておく。ただし原因はよくわかっていない。

## 解消方法

StackOverflowで同様の現象で困っている人がいて、回答の通り、Connection確立時に <b>autocommit=True</b> とすることで問題を解消できた。または各SELECT後にcommitしても解消できるかと思う。

[stackoverflow: why is an aws lambda python call to a mysql rds being cached](https://stackoverflow.com/questions/50359668/why-is-an-aws-lambda-python-call-to-a-mysql-rds-being-cached)

以下はpymysqlというライブラリの例

```query.py
# Connect to the database
connection = pymysql.connect(host='localhost',
                             user='user',
                             password='passwd',
                             db='db',
                             charset='utf8mb4',
                             cursorclass=pymysql.cursors.DictCursor,
                             autocommit=True)  # これを追加
```


## 疑問
問題を回避できたのは良いが、今回の問題がLambda起因なのかMySQL起因なのかすらよくわかっていない。

pymysqlのgithub issuesでは以下のように書いてあった。

> Autocommit off can mean you are seeing a shadowed copy of the data in which case you will not see outside changes until you rollback/commit the transaction

オートコミットがオフであることが意味することは、データのシャドウドコピーを見ることであり、その状況では、コミット/ロールバックしない限り外部の変更を見ることができないだろう、と。

どなたか、何が起きているのか教えてください:bow:

## 参考
- [pymysql github issues](https://github.com/PyMySQL/PyMySQL/issues/76)
Python3.6に更新したらAzure CLIが動かなくなった。どうするの。

## Azure IoT Hub はPython3.5以降じゃないとコマンド実行できない。
環境：CentOS7, Python3.4
コマンド[az iot hub monitor-events]を実行するとメッセージ(↓)が表示される。
"Python version 3.5 or higher required for this functionality."
だからPython3.4 → Python3.6 にアップデートした。そしたら。

## Azure CLI が動かなくなった。
「AttributeError: module 'enum' has no attribute 'IntFlag'」というエラーが発生する。

```
$ az
Traceback (most recent call last):
  File "/usr/lib64/python3.6/runpy.py", line 183, in _run_module_as_main
    mod_name, mod_spec, code = _get_module_details(mod_name, _Error)
  File "/usr/lib64/python3.6/runpy.py", line 109, in _get_module_details
    __import__(pkg_name)
  File "/usr/lib64/az/lib/python2.7/site-packages/azure/__init__.py", line 1, in <module>
    __import__('pkg_resources').declare_namespace(__name__)
  File "/usr/lib64/az/lib/python2.7/site-packages/pkg_resources/__init__.py", line 24, in <module>
    import re
  File "/usr/lib64/python3.6/re.py", line 142, in <module>
    class RegexFlag(enum.IntFlag):
AttributeError: module 'enum' has no attribute 'IntFlag'
```
## どうするの？
Azure CLI をダウングレードしたら動くようになった。

```
$ sudo yum downgrade azure-cli-2.0.64

Resolving Dependencies
--> Running transaction check
---> Package azure-cli.x86_64 0:2.0.64-1.el7 will be a downgrade
---> Package azure-cli.x86_64 0:2.0.72-1.el7 will be erased
--> Finished Dependency Resolution

Dependencies Resolved

===========================================================================================
 Package                         Arch                         Version              
===========================================================================================
Downgrading:
 azure-cli                       x86_64                       2.0.64-1.el7                          ===========================================================================================
Downgrade  1 Package

Removed:     azure-cli.x86_64 0:2.0.72-1.el7
Installed:   azure-cli.x86_64 0:2.0.64-1.el7

Complete!

$ az --version
azure-cli                         2.0.64 *
```

## つづく
現在の環境：CentOS7, python 3.6.8, Azure CLI 2.0.64
とりあえずAzure CLIが動くようになったのでIoT Hubの確認を続行します。
機械学習の学び方　考えるな！感じるんだ！

# はじめに

この記事では、私の機械学習勉強法について述べます。

# 勉強法

## 百聞は一見に如かず

まずは本を読みました。

機械学習に限らず、専門書は比較的高価です。1冊1万円するものもありますね。

「高いから買わない」という人も少なくないですが、私はもったいないと思います。

本から得られる情報の質と、自分が同じ情報を独力で入手しようとしたときのコストを天秤にかけると、むしろ安いとさえ言えます。

以下の本は私が読んだなかでも比較的わかりやすい機械学習（一部統計学）の本です。

- 初級
    - [石村貞夫; 石村友二郎. 入門はじめての時系列分析. 東京図書, 2012.](https://amzn.to/2LgdYw0)
- 中級
    - [多田智史; 石井一夫. あたらしい人工知能の教科書 プロダクト/サービス開発に必要な基礎知識. 翔泳社, 2016.](https://amzn.to/35WuZTT)
    - [太田満久, et al. 現場で使える! TensorFlow 開発入門 Keras による深層学習モデル構築手法. 翔泳社, 2018.](https://amzn.to/380B9Ez)
    - [クジラ飛行机, Pythonによるスクレイピング&機械学習 開発テクニック BeautifulSoup,scikit-learn,TensorFlowを使ってみよう, 2016.](https://amzn.to/2YaQQ7w)
- 上級
    - [井手剛; 杉山将. 異常検知と変化検知. 講談社, 2015.](https://amzn.to/2PbxlYe)

## 習うより慣れろ

本についてきたサンプルプログラムはどんどん実行しました。

「学ぶ」という言葉の語源は「真似る」と同じです。何事も、できる人の真似をすること、技術を身につける近道です。

書籍付属のサンプルプログラム以外にも以下のような解説記事やチュートリアルを参考にしました。

- 解説記事
    - [Python3の環境でTensorflowのサンプルを動かす](https://qiita.com/acecrc/items/4bf5f986d950af26044f)
- チュートリアル
    - [TensorFlow Core Tutorials](https://www.tensorflow.org/tutorials)

## 鶏口となるとも牛後となるなかれ

人の真似をするとたしかに早くスキルが身につきます。とはいえ、それだけでは面白くない。

まだだれも使っていないような先端的なライブラリもどんどん学びました。青田買いです！

例えば以下。

- [強化学習フレームワーク Google Dopamine をつかってみた。](https://qiita.com/kannkyo/items/2fe683d2aa5db21b1206)
- [自然言語ライブラリGiNZAの最速レビュー](https://qiita.com/kannkyo/items/2472cf3d82a61fb8584e)

## 自分の土俵で戦う

機械学習は裾野の広い分野です。私が昔組み込み開発で使ったFPGAが、今ではデータセンターのサーバに組み込まれて、機械学習等の用途に積極的に使われているそうです。

機械学習そのものを学ぶだけでなく、自分がすでに知っている分野をベースに機械学習を学びました。

例えば以下。

- [ソフトウェア開発者向けのFPGA最新動向のまとめ](https://qiita.com/kannkyo/items/0927114c3fa2545e9d76)

# まとめ

私の機械学習勉強法を紹介しました。
皆さんのお役に立てば幸甚です。
【自分用メモ】supertestとpassport-stubをmochaテストに組み合わせる

##supertestとは
supertestはmochaと組み合わせて使うのですが、ExpressのRouterモジュールのテストを行うことができます。
例えば以下の例では、`/`にアクセスしたらindexRouterが処理されるかテストしてくれます。
もちろん、`/login`も`/logout`もテストしてくれます。

```JS:app.js
app.use('/', indexRouter);
app.use('/login', loginRouter);
app.use('/logout', logoutRouter);
```

##passport-stubとは
passport-stubは、passportモジュールを利用した認証システムを、テストする際に役に立ちます。
例えば、
「facebook認証などのテストをしたいけど、facebookアカウントを持っていない！」
といった時に役に立ちます。


##テストの例
```JS:test.js
//supertestの読み込み
const request = require('supertest');
//supertestで使う、app.jsの読み込み
const app = require('app');
//passport-stubの読み込み
const passportStub = require('passport-stub');

//ログイン（/login）のテストであることを明示
describe('/login', () => {
  //before、afterはmochaの機能
  before(() => {
    //テストの前にpassportstubモジュールでログイン
    passportStub.install(app);
    //'testuser'としてログイン
    passportStub.login({ username: 'testuser' });
  });
  after(() => {
    //テストの後にpassportstubモジュールでログアウト
    passportStub.logout();
    passportStub.uninstall(app);
  });

//以下の記法は、supertestの記法
　//テストの内容を指定
  it('ログインのためのリンクが含まれる', (done) => {
    //request(app).get('/login') で、 /login への GETリクエストを作成
    request(app)
      .get('/login')
      //文字列を2つ引数として渡すとヘッダのテスト
      .expect('Content-Type', 'text/html; charset=utf-8')
      //正規表現を1つ渡すとHTMLのテスト
      .expect(/<a href="\/auth\/facebook"/)
      //期待されるステータスコードの整数と、テスト自体の引数に渡されるdone 関数を渡すと、レスポンスヘッダのテスト
      .expect(200, done);
  });

  it('ログイン時はユーザー名が表示される', (done) => {
    request(app)
      .get('/login')
      .expect(/testuser/)
      .expect(200, done);
  });
});

//ログアウト（/logout）のテストであることを明示
describe('/logout', () => {
　//テスト内容を明示
  it('ログアウト後に / にリダイレクトされる', (done) => {
    ////request(app).get('/logout')で、/logoutへのGETリクエストを作成
    request(app)
      .get('/logout')
       // `/`へリダイレクトされるかのテスト
      .expect('Location', '/')
　　　　// ステータスコードがリクエストであるかのテスト
      .expect(302, done);
  });
});
```

>`describe`、`it`、`before`、`after`はmochaの書き方。
>`request(app).get`、`.expect`はsupertestの書き方
>`passportStub.install(app)`、`passportStub.login`はpassport-stubの書き方


##テスト結果
![スクリーンショット 2019-12-03 22.47.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374924/943cde81-fb36-65a4-ff81-63c360642279.png)
なぜなに？ Deep Learning 機械学習概要 編

# 目次
 * 機械学習とは
 * 機械学習の種類
 * 参考文献

# 機械学習とは
AIの一種。
与えられたデータ(訓練データ)から自動的に学習するもの。
一つの学習アルゴリズムを作れば、その後はコードを書かなくても自動で更新する。


#### 機械学習が得意な問題
* 大量な調整作業やルールリストの更新 (ex. スパムメールの自動フィルタリング)
* 今までの手法では解決できない問題を新しい手法で解決すること(ex. 自動運転)
* 変動が激しい環境でも、直ぐに学んで対応すること
* 複雑なシステムや大量データから新しい知見を獲得すること

#機械学習の種類
大きく分けて3つに分類できる。

* 教師あり学習 
* 教師なし学習 
* 強化学習

それぞれの学習に説明をする。
###教師あり学習
ラベル付き訓練データ(※)とテストデータを与えて学習させる。
例えるなら、生徒(機械)に問題(正解/不正解)を見せ続けて、確認テストで学習の成果を確認するようなもの。
ニューラルネットワークやディープラーニングは、これに当てはまる。

(※)ラベルとは、訓練データにあらかじめ分類した名札のようなものである。
例えば、花の分類なら花の名前を、動物の分類なら動物の名前をラベリングしてデータに添付する。
###教師なし学習
ラベルがない訓練データをデータを与え学習させるシステム。
データからパターンやルールを見つけさせるシステム。
クラスタリング(データを仕分け)や異常検知(パターンから推測する)などに使われる。

###強化学習
与えられた環境に対して、良い成果を上げることを目的とした学習システム。
**エージェント**(プレイヤー)が**行動**を起こして、その行動によって**環境**が返す**報酬**(結果)を受け取り学習するシステム。
ゲームのスーパーマリオに例えるなら、
機械が操作する**マリオ(エージェント)**が、**敵・地形を含めたマップという環境**に対して、良い**スコア(クリアタイムやコイン獲得数)**を取るように繰り返し学習するようなもの。


####他にも色々な機械学習がある 
* オンライン学習
* バッチ学習
* モデルベース学習
* インスタンスベース学習



#参考文献
 + scikit-learnとTensorFlowによる実践機械学習
 + ゼロから作るDeep Learning
 + Pythonで動かして学ぶ！ あたらしい 機械学習の教科書
Libreofficeによるシステム手帳のカレンダーの作成〜3Dプリンタによるシステム手帳の自作続編1〜

#こんにちは！
こんにちは。たいちゃんです。
今年ももう1ヶ月切りました。
そこで今回は前回の『3Dプリンタによるシステム手帳の自作』の続編として、
来年のシステム手帳のカレンダーの作成について投稿してみたいと思います。
前回の投稿についてはこちらにリンクを貼っておきます。

[3Dプリンタによるシステム手帳の自作](https://qiita.com/toshita172/items/d4cb43733ac9e06d40f1)

#前回の課題
前回は今後の課題として
>・4ページをA4に一度に印刷するとやはりズレてしまうので、A4を予め4等分してA6として
リフィルを印刷した方が潔いと思います。

と記載しました。そこで今回はA4を4等分してA6の用紙を作成し、カレンダーを印刷することにしました。
因みに前回の原稿の画面はこちらとなります。

![Writer_Personal_Organiser6_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/e93e63be-8eb4-0b8d-4295-88f74b2ade57.png)

対して、今回の原稿は以下の通りです。
![Writer_Personal_Organiser6_01_191203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/9a22624b-159e-bb46-5a63-a016e46eafef.png)
上図は来年1月の見開き向かって左の部分です。そして次が同右の部分となります。
![Writer_Personal_Organiser6_02_191203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/6b700277-7cba-95b7-cc12-ae0073c86493.png)

カレンダーのマス目はLibreOffice Writerの「表-表の挿入」を利用しています。片側に曜日の欄を含めて
7行4列の表を作ります。カレンダーは私の愛用のDebianのカレンダーを見ながら作りました。只、それでは
祝祭日がわからないので、前回同様祝祭日は内閣府のホームページを参考にしました。見開きの左側の画像の
左上に鏡餅が描いてありますが、これはシェイプを使ってその月に関連が深そうなイラストを手前味噌ですが
描いてみました。

#それでは印刷してみましょう。
![KIMG0415_retouch.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/32b3e056-7431-bca0-9efa-c49fa79f9d02.jpeg)
こちらが来年1月のカレンダーです。左右対称にする為、更にメモをより多く取りやすくするため、
「備考」欄を設けてあるのが私のカレンダーの特徴です。
![KIMG0417_retouch.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/6462dfdb-6c6c-d74a-e98b-5fda0059ebfa.jpeg)
こちらは同年2月のカレンダーです。次に示します今年の2月分と比べると、A6で印刷した分左右のページの
ズレが大幅に緩和されたのがわかるかと思います。
![KIMG0263_retouch.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/c224435c-bdcc-e631-93a8-059859060853.jpeg)

![KIMG0418_retouch.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/c180c191-ab23-7d2d-17fb-9146e120a1ed.jpeg)
年の真ん中辺りの6月もいい感じで印刷できたと思います。
![KIMG0420_retouch.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/246e3dda-82eb-8b28-ccc8-b249d4f9ccc6.jpeg)
年の終わりの12月です。シェイプで描いたクリスマスツリーのイラストは私にしては割とよく出来た方だと思います。

#作り終えて
A4両面に1枚ずつ印刷するのは印刷自体は一度にできるので楽ですがズレ易く、また、A4内でのレイアウトも
下の図のように大変ややこしいものでした。
![Writer_Personal_Organiser6_03_191203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319826/3c675141-1150-47f8-3a9f-0f7f2e4d2b4b.png)
今回A6とは言え、レイアウトは1ページずつ設定すればいいので、割と楽でした。
もっとも、A4の用紙をまとまった数カッターで精確に切るのが、慣れてない私には大変でした。1、2枚なら
問題なかったのですが・・・。
とは言えこのA4をA6にして印刷する改善案はうまくいったと思います。今後は少しずつですが、
LibreOffice等のオープンソースソフトウェアを出来るだけ駆使してこの『自作のシステム手帳』を改良して
いきたいと思います。
railsアプリではクラスインスタンス変数の注意する

# クラスインスタンス変数の注意

右辺の実行結果をキャッシュするために以下の手法が使われる事があると思います。
1回目のメソッド実行時に実行結果をインスタンス変数`@foo`でキャッシュしておいて、2回目のメソッド実行時にはインスタンス変数の中身を返しています。

```
Class Foo
  def
    @foo ||= bar
  end
end
```
インスタンスメソッドの場合、インスタンス変数はFooクラスのオブジェクト毎に保持されます。
railsアプリ内のコードでこれをクラスメソッド内で使用する場合は注意が必要です。

```
Class Foo
  self.def
    @foo ||= bar
  end
end
```

クラスメソッド内でインスタンス変数はClassクラスのオブジェクト毎に保持され、
Classクラスのオブジェクトはrailsアプリケーション起動時から同じものを使い続けます。
その為、DB問合せ結果をキャッシュしてしまったりすると、**アプリケーション起動後DBに初めて問い合わせした値を保持し続けてしまう**為、その後別のリクエストでDBを更新しても、反映されない問題が発生します。
第三回Try English LT! for engineers 発表資料まとめ

# Try English LT! for engineersとは？

エンジニア向けの英語のみのLTイベントを行なっています！
毎回、LTのスピーカー募集してます！エンジニア向けの内容であればテーマは自由です。
英語でLTをやるとなると、中々ハードルが高く、 参加者が海外の人ばかりだと、なおさら難しく感じると思います。
ちょっと自信はないけど、 英語のLTにチャレンジしてみたいという人にぜひ発表してもらいたいです。
英語が好きなエンジニア同士で交流できるイベント運営ができればと思っています。

第三回イベントページ
https://try-english-lt.connpass.com/event/152272/

## 発表資料
・Nobu
Test code of JavaScript
JavaScriptのテストコード
https://docs.google.com/presentation/d/1sQ9hXuTYzDSCaO91KGgSFtN6PVW33t9fCIfyQxd1HDA/edit?usp=sharing


・Toshi さん
LaaI - LT as an Icebreaking
https://drive.google.com/file/d/11qbaI9Gz0EjzYhf_n8fVO9zTkuGZztl0/view?usp=sharing

・EmiYaegashi さん
KPI and chart library
KPIとチャートライブラリ
https://speakerdeck.com/eyaegashi/kpi-and-chart-libary

・HiromuNakamura さん
If you are suddenly assigned to work on k8s
もしいきなりk8sを使う作業を任されたら
https://speakerdeck.com/po3rin/if-you-are-suddenly-assigned-to-work-on-k8s

・anchor_cable さん
I highly recommend Active Book Dialogue!
Active Book Dialogueの紹介
https://speakerdeck.com/anchorcable/i-highly-recommend-active-book-dialogue

・naoki85 さん
A story about replacing my blog to a severless architecture
私のブログをサーバーレス構成に置き換えた話
https://speakerdeck.com/naoki85/a-story-about-replacing-my-blog-with-serverless-architecture

・nunulk さん
Design It!" in a nutshell.
"Design It!" を簡単にご紹介します
https://speakerdeck.com/nunulk/design-it-in-a-nutshell

・Qaiyyum さん
Cultivating a code review culture
コードレビューの文化を作る
https://drive.google.com/file/d/13gO1DQO_WJZnkqbVtLhJAxW7Lk4-Dcpu/view?usp=sharing
シェルスクリプト : コマンド

: コマンドは、何もしないのでヌルコマンドとも呼ばれる。
#### 無限ループ
: コマンドは終了ステータス「0」を返すだけのコマンドであるため、true コマンドと似ている。
以下のように、while コマンドの繰り返し条件として、true の代わりに : コマンドをつかうことができる。

```bash:null-command1.sh
while :
do
  echo "Hello world!!"
done
```

#### 引数チェック
第一引数 $1 が未指定の場合、設定を促すメッセージが表示される。
未指定だった場合、その次の行は実行されない。

```bash:null-command2.sh
: ${1?"Please set argument."}
echo ${1}
```

#### 変数のデフォルト設定
対象の変数が未設定だった場合のみ、そこで指定した値が代入される。

```bash:null-command3.sh
: ${VAL='ABC'}
echo ${VAL} # ABC
: ${VAL='XYZ'}
echo ${VAL} # ABC
```

#### ファイルの中身を消去
これだけで、hello.txt の中身が空っぽになる。
（ヌルをリダイレクトしているようなイメージ）

```bash:null-command4.sh
:> hello.txt
```
C#/WinRT - Windows.Data.Pdfを使ってみた

このサンプルでは、PDFを読み込んでページ数を出力します。

環境 Windows10 (Visual Studioいれてないとダメかも)

# ソースコード

※await/asyncを使い慣れていないので、良い書き方かどうかは自信はないです。

```cs

using System;
using System.Collections.Generic;
using System.Threading.Tasks;

using Windows.Data.Pdf;

namespace MyPdfTest
{
    public class MyPdf
    {
        public static async Task<uint> LoadPdfFile(string fileName)
        {
            Windows.Storage.StorageFile sampleFile = await Windows.Storage.StorageFile.GetFileFromPathAsync(fileName);
            uint t = LoadPdfDocumentAsync(sampleFile).Result;
            return t;
        }

        static async Task<uint> LoadPdfDocumentAsync(Windows.Storage.StorageFile pdfFile)
        {
            PdfDocument _pdfDoc = await PdfDocument.LoadFromFileAsync(pdfFile);
            return _pdfDoc.PageCount;
        }
        
        [STAThread]
        static void Main(string[] args)
        {
            Task<uint> t = LoadPdfFile(@"C:\SvnLocal\trunk\Pdf_WinRT\PDF32000_2008.pdf");
            uint t2 = t.Result;
            Console.WriteLine(t2);
        }
    }
}
```


# コンパイル用バッチファイル

`compile.bat ソースファイル名.cs` でコンパイル

```text:compile.bat

csc /r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.WindowsRuntime\v4.0_4.0.0.0__b77a5c561934e089\system.runtime.windowsruntime.dll ^
/r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime.InteropServices.WindowsRuntime\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.InteropServices.WindowsRuntime.dll ^
/r:C:\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Runtime\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Runtime.dll ^
"/r:C:\Program Files (x86)\Windows Kits\8.1\References\CommonConfiguration\Neutral\Annotated\Windows.winmd" %*
```

# 実行結果

```

C:\SvnLocal\trunk\Pdf_WinRT>PdfWinRT_Test.exe
756
```

以下はAdobe Reader DCで確認したページ数。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438183/d038ce48-d5e2-74f2-daeb-248c523b486f.png)

正しいページ数が得られている。


# 参考サイト

1. https://www.atmarkit.co.jp/ait/articles/1310/24/news070.html
2. https://docs.microsoft.com/en-us/uwp/api/windows.storage.storagefile.getfilefrompathasync

# 追記

参考サイト1によると、ページを画像として抽出するのには使えそうだが、テキストを抽出するのには使えなさそうである。ILSpyでメンバーとかみた感じ、その通りっぽい。

# 追記その２

続編：[C#/WinRT - PDFを画像に変換して保存する](https://qiita.com/kob58im/items/5207da5d06b3ebb4f8c3)
Excelシート整頓マクロ


#はじめに
初心者エンジニアです。
日々勉強して学んだこと、教わったことをメモ書きのように書き残す感じで書き残していきたいと思ってます。

#本題
今回は、現在の上長から教えてもらった「めっちゃ便利！」と思ったVBAマクロです。

これは、日々の業務でドキュメントや一覧表などを作成、変更などをした場合に編集直後のままで保存していた際に教わった整頓マクロです。
次にそのExcelファイルを開いた人のためを思い、全シートのアクティブセルの位置を「A1」に移動させ、最初のシートに戻ってくるマクロです。

```selectA1.bas
Sub SelectA1()

    'エラーは無視
    On Error Resume Next
    
    Call BeforeSelectA1
    
    Dim wb As Workbook
    Dim ws As Worksheet
    '選択中のブックが対象
    Set wb = ActiveWorkbook
    
    For Each ws In wb.Worksheets
        ws.Activate
        ws.Cells(1, 1).Activate
    Next
        
    Call AfterSelectA1
        
    wb.Worksheets(1).Activate
End Sub
'----------------------------------------
Function BeforeSelectA1()
    
    With Application
        .EnableEvents = False
        .DisplayAlerts = False
        .Calculation = xlCalculationManual
    End With

End Function
'----------------------------------------
Function AfterSelectA1()

    With Application
        .EnableEvents = True
        .DisplayAlerts = True
        .Calculation = xlCalculationAutomatic
        .CutCopyMode = False
    End With

End Function
```

マクロ起動直後にエラーが起きても無視して最後まで処理を通すようにしています。

```
    'エラーは無視
    On Error Resume Next
```

また、処理を行う前に自動イベントや自動計算、メッセージの表示が発生しないようにしています。(処理後に戻します。)
他のマクロや計算を一時的に止めて処理を軽くする効果があるそうで。
エラーが発生しないようにしつつ、途中で止まらず最後まで処理がスムーズに通るようにしているそうです。

```
Function BeforeSelectA1()    
    With Application
        .EnableEvents = False
        .DisplayAlerts = False
        .Calculation = xlCalculationManual
    End With
End Function
```
```
Function AfterSelectA1()
    With Application
        .EnableEvents = True
        .DisplayAlerts = True
        .Calculation = xlCalculationAutomatic
        .CutCopyMode = False
    End With
End Function
```
本処理としては簡単。
選択中のブックのシートをFor文で回して全シートのアクティブセルをA1に移動させているだけです。


##おわりに
作成物を確認してもらうことや共有物を更新することもあり、多少なりともエクセルを開いた瞬間の見栄えは良い方がいいと思うし、次開くのが自分でも開いた瞬間が整っていた方がいいです。
実際に教えられてから大活躍してます。
マクロにショートカットキーを割り当てれば楽々です。
教えてくれた上長に感謝です。
rubyワンライナーでwebサーバーを立てるTips

mockサーバとかサッと作成したい時に使うTipsです。
rubyコマンドを使ってワンライナーでwebサーバーを起動します。


# 手順
## 1. レスポンスボディのファイルを用意します。

```ruby:response.rb
"Hello"
```

## 2. `response.rb`ファイルが配置されているパスで`ruby -run -e httpd ./response.rb -p 3333`実行します。
```shell
$ ls -la
response.rb

$ ruby -run -e httpd ./response.rb -p 3333
```

-> これでwebサーバーが起動します。

## 3. 確認してみる

curlで確認してみます。
ブラウザでも`localhost:3333`にアクサスしたら`response.rb`の中身が返ってきます。

```shell
$ curl localhost:3333
"hello"
::1 - - [03/Dec/2019:20:18:36 JST] "GET / HTTP/1.1" 200 8
- -> /
```
Swift Network.framework Study 20191203

# Study

Network.framework
Study：Client側

## 環境

Client：Swift、Xcode
Server：Java、NetBeans

# Client Source Swift

```swift
import Foundation
import Network

func startConnection() {
    let myQueue = DispatchQueue(label: "ExampleNetwork")
    let connection = NWConnection(host: "localhost", port: 7777, using: NWParameters.tcp)
    connection.stateUpdateHandler = { (newState) in
        switch(newState) {
        case .ready:
            print("ready")
            sendMessage(connection)
        case .waiting(let error):
            print("waiting")
            print(error)
        case .failed(let error):
            print("failed")
            print(error)
        default:
            print("defaults")
            break
        }
    }
    connection.start(queue: myQueue)
}

func sendMessage(_ connection: NWConnection) {
    let data = "Example Send Data".data(using: .utf8)
    let completion = NWConnection.SendCompletion.contentProcessed { (error: NWError?) in
        print("送信完了")
    }
    connection.send(content: data, completion: completion)
}

startConnection()

while true {
    sleep(1)
}
```

最後のループとか格好悪い。

# Server Source Java

```java
package example.java.network;

import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class ExampleServerSocket {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket = new ServerSocket(7777);
            System.out.println("socket create");
            Socket socket = serverSocket.accept();
            System.out.println("accept");
            Scanner scanner = new Scanner(socket.getInputStream());
            while(scanner.hasNext() == true) {
                System.out.println(scanner.nextLine());
            }
        }
        catch(Exception e) {
            System.out.println(e);
        }
    }
}
```

久々でScannerのhasNext()条件を忘れている。確認して改良しないと。
ThenIncludeメソッドで関連データが指定できない

特定の条件で、ThenIncludeメソッドで指定する、コンテキストのプロパティがVisual Studioのインテリセンスに表示されないことがあったので、検証してみました。

##結論
ThenInclude(colection => corection.×××)のように、コレクションの関連データを読み込もうとするとインテリセンスに表示されません。インテリセンスのバグだそうです。

##対策
インテリセンスに頼らず手動で指定する。

##検証
```ruby:使用するモデル（必要な個所だけ抜粋）
   public class User
    {
        public int UserId { get; set; }
        public string UserName { get; set; }

        public List<Books> UserBooks { get; set; }
    }

    public class Books
    {
        public int UserId { get; set; }
        public int CategoryId { get; set; }
        public string Title { get; set; }

        public List<BookCategory> BookCategories { get; set; }
    }

    public class BookCategory
    {
        public int CategoryId { get; set; }
        public int CategoryName { get; set; }
    }
```

###ThenIncludeでコレクションの関連データを読み込む
![コメント 2019-12-03 220121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337557/847cf0f7-7719-2b47-ddfd-fea3e6d76991.png)
本来はここでBooksクラスの関連データのプロパティである「BookCategories」がインテリセンスに出てきてほしいが、出てこない。
出てこないが、直接プロパティを打ち込めばエラーなく読み込むことができる。
![コメント 2019-12-03 220342.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337557/f7f8f49e-ae94-aafa-eb81-aeaf6149503c.png)


###上記画像のようにプロパティ名を指定してから「userBooks.」まで消して、プロパティ名を打つとなぜか表示される
![コメント 2019-12-03 221135.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/337557/32b0187f-44e8-abfc-30cd-a5994c9e4b20.png)

なぜかインテリセンスに出てくるが、一回全部消してからもう一回打つと出てこなくなる。

######インテリセンスに出てこないからThenInclude使えないわーと思ってたけど、実は使えるんです。


##参考
https://github.com/aspnet/EntityFrameworkCore/issues/6560#issuecomment-248716253