OmniAICreator/Qiita-1.07M huggingface dataset:
magitのログを、コミット時期ではなくコミット時刻で表示したい

Emacsで、Gitのフロントエンドとしてmagitを使う際、magit-logで表示されるコミット日時が、コミット時期(5 weeksとか1 yearとか)で表示されるけど、これをコミット時刻(2018-01-02 03:04:05)で表示させたい。

# 対処法: 以前のmagitの場合

きっと誰かが同じことを考えているはずと思い、ググってみたところ、[magitのログで、コミット日時を時刻で表示させる設定](http://emacs.rubikitch.com/magit-time-format/)が見つかった。これに従って設定してみたけど、magitの作りが変更されているようで、最近のmagitでは動作しない模様。

但し、どのバージョンから動作しなくなったのかまでは未調査。

# 対処法: 最近のmagitの場合
カスタマイズできるように、変数が用意されてないかmagitパッケージのそれらしいlispファイル(`magit-log.el`)を眺めてみた所、見つかった。

```emacs-lisp:magit-log.el
(defcustom magit-log-margin '(t age magit-log-margin-width t 18)
  "Format of the margin in `magit-log-mode' buffers.

The value has the form (INIT STYLE WIDTH AUTHOR AUTHOR-WIDTH).

If INIT is non-nil, then the margin is shown initially.
STYLE controls how to format the committer date.  It can be one
  of `age' (to show the age of the commit), `age-abbreviated' (to
  abbreviate the time unit to a character), or a string (suitable
  for `format-time-string') to show the actual date.
WIDTH controls the width of the margin.  This exists for forward
  compatibility and currently the value should not be changed.
AUTHOR controls whether the name of the author is also shown by
  default.
AUTHOR-WIDTH has to be an integer.  When the name of the author
  is shown, then this specifies how much space is used to do so."
```

ということなので、デフォルトで`age`となっている箇所を、[format-time-string](https://www.gnu.org/software/emacs/manual/html_node/elisp/Time-Parsing.html)に適した文字列で置き換えてあげればよいらしい。

ということで、↓で解決。

```emacs-lisp:init.el
(eval-after-load "magit-log"
  '(progn
     (custom-set-variables
      '(magit-log-margin '(t "%Y-%m-%d %H:%M:%S" magit-log-margin-width t 18)))))
```

ちなみに、`age-abbreviated`に設定すると、設定値が示しているとおり、2d, 9w, 1Yのように、コミット時期が短縮表示されるようになる。

---

確認環境
GNU Emacs 25.3.1
magit 20180304.1221
Azure AppService上のWordpressを、Azure Active Directoryで保護する

# 概要
AppService上に配置したWordpressの一部のURL（ログイン画面、他）をAzure Active Directoryで保護します。

# 前提
- Azure AppServiceでWordpressを配置済み
- Azure Active Diretoryの初期設定は済んでいる

# やり方

## 認証プロバイダーの設定

- AppServiceのブレードから設定したいアプリを選択し、「認証/承認」画面を開きます
- 「App Service 認証」を「オン」にします
- 「要求が認証されない場合に実行するアクション」は「匿名要求を許可する（操作不要）」を選択します（下の図では「Azure Active Directoryでのログイン」を選択してますが、間違いです）
- すると次のブレードが表示されます

![2018-03-07 (5).png](https://qiita-image-store.s3.amazonaws.com/0/213719/3777388c-7780-c737-78b9-ca1c673a0b5d.png)

- アクションを設定したら、「認証プロバイダー」の「Azure Active Directory」を選択します
- 下の画像のように入力（アプリの作成欄は、適宜変更）

![2018-03-07 (6).png](https://qiita-image-store.s3.amazonaws.com/0/213719/52aece1c-485e-9b5a-4f91-ddd75a4ccf06.png)

- 「OK」ボタンを押下後、元のブレードに戻るので、「保存」ボタンを押下
- これでAppServiceでAzure Active Directoryの認証を使うことができるようになります

## 設定したアプリにユーザーを追加

- Azure Active Directoryのブレードを開く
- メニューから「エンタープライズアプリケーション」を選択し、次のブレードを開きます

![2018-03-07 (10).png](https://qiita-image-store.s3.amazonaws.com/0/213719/f24534a9-f164-753f-64fd-2d603c9e638b.png)

- 「すべてのアプリケーション」を開くと、アプリ一覧が開くので、先ほど作成したものを探し、選択します
- 次のブレードが開きます

![2018-03-07 (11).png](https://qiita-image-store.s3.amazonaws.com/0/213719/672a3856-03eb-a847-ba05-40a3cdb56c2b.png)

- 「ユーザーの追加」から、適宜追加します

![2018-03-07 (12).png](https://qiita-image-store.s3.amazonaws.com/0/213719/ba5dc36c-ebf8-4cfb-5870-04fd9e8fec03.png)

## AppServiceへの認証の設定

Kudu（高度なツール）から設定します。Kuduを開いたら、web.configがあるディレクトリまで移動し、`authorization.json`を新規作成します。内容は以下のようにします。かなり厳しくしているので、おそらく普通であれば`/wp-login.php`と`/wp-admin`への設定を行うだけで十分だと思います。

```json
{
  "routes": [
    {
      "path_prefix": "/wp-login.php",
      "policies": {
        "unauthenticated_action": "RedirectToLoginPage"
      }
    },
    {
      "path_prefix": "/wp-admin",
      "policies": {
        "unauthenticated_action": "RejectWith404"
      }
    },
    {
      "path_prefix": "/wp-admin*",
      "policies": {
        "unauthenticated_action": "RejectWith404"
      }
    },
    {
      "path_prefix": "/wp-json",
      "policies": {
        "unauthenticated_action": "RejectWith404"
      }
    },
    {
      "path_prefix": "/wp-json/*",
      "policies": {
        "unauthenticated_action": "RejectWith404"
      }
    },
    {
      "path_prefix": "/xmlrpc.php",
      "policies": {
        "unauthenticated_action": "RejectWith404"
      }
    }
  ]
}
```

`authorization.json`に何を書くかは、以下のブログポスト（英語）が役に立ちます。
https://blogs.msdn.microsoft.com/appserviceteam/2016/11/17/url-authorization-rules/
IEEE1800-2017 SystemVerilog2017

IEEE GET ProgramでIEEE1800-2017のPDFを無償でダウンロードできるようになっていましたので早速入手しました。

章立ては2012年版と変わってないですね。
OperatorのOverloadingがなくなっているのを見つけましたけれどそのほかは2012との違いを見つけられませんでした。

いずれにしても2012と大差はないようです。SVAの部分については特に変更はないということでIEEE1800-2017のPDFをもとにSVAについて何か書いていこうと思っています。
数値のアウトプットをキレイに見せる

初歩的ですが最後の「3列で整地する」を知らなかったのでメモとして。
#改行なし、/をつける、3列にする

```python:qiita.py
num = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # range(10)

#まずは改行なし。
print ('pattern 1 (no end):')
for i in num:
    print (str(i))

#次に、endに'/'をつける。
print ('pattern 2 (with end):')
for i in num:
    print (str(i), end=' / ') # end を指定すると出力した後に改行されない
print() # 改行を入れる
#連続したアウトプットのときはprint()で改行できます。

#3列でキレイに整える。
print ('pattern 3 (3 columns):')
for i in num:
    print (str(i), end='    ')
    if (i + 1) % 3 ==0: # 3 つ処理するごとに改行を入れる
        print()
```
#アウトプット
見づらいのですが、こんな感じになります。

pattern 1 (no end):
0
1
2
3
4
5
6
7
8
9
pattern 2 (with end):
0 / 1 / 2 / 3 / 4 / 5 / 6 / 7 / 8 / 9 / 
pattern 3 (3 columns):
0    1    2    
3    4    5    
6    7    8    
9    

3列バージョンは便利なので覚えておこう。
自宅での技術検証がより楽しくなる？ portainer で Docker コンテナ管理

コンテナを管理する方法は色々あると思うのですが、 自宅で技術検証をするときは portainer が便利そうでした。
公式サイトはこちらです。軽量な管理 UI で、簡単に Docker ホスト、Swarm クラスタを管理できると記載されています。
https://portainer.io/

# よいと感じた点

* GUI で稼働中のコンテナやイメージ、ネットワーク、ストレージを見れます。マウス操作だけでいいので、モニタリングが手軽です。
* 画面もおしゃれだと思いました(人によって好みが違うとは思いますが・・)。
* コンソール接続もできます。```docker exec -ti コンテナ名 bash``` をしなくても接続できるので手軽です。
* 著名なアプリのコンテナテンプレートが用意されていて、GUI 上でポチポチしているだけでコンテナを作れます。今まで触ったことのない技術に触りたくなりました。

# 導入方法

コンテナイメージ「portainer/portainer」をプルして起動します。

脱線しますが、個人的には OS は ubuntu を使うのが楽です。最近のソフトも結構パッケージ化されています。（仕事で Red Hat Enterprise Linux に機械学習の Caffe をインストールしたときは大変すぎました。。）

また、素の Docker を使うよりは Docker Compose を使うのがオススメです。コンテナの起動方法を yaml で書けるので、docker コマンドのオプションを覚える必要がなく、毎回長いオプションを打つ必要もなくなります。

docker compose は次のようにインストールします(Debian 系の場合)。

```
$ sudo apt install docker-compose
$ sudo usermod -aG docker ユーザ名
```

docker-compose.yaml は次の内容にします。

```
$ cat docker-compose.yaml 
version: '2'

services:
  portainer:
    image: portainer/portainer
    ports:
      - 9000:9000
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
```

では、コンテナを起動します。

```
$ docker-compose up
```

# 管理画面

http://localhost:9000 にアクセスするとログイン画面になります。初回はパスワードを設定します。

![2018-03-07 21.54.18 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/885c0437-f108-c9d9-5d0d-4a2dc5efbc03.png)

Local を選択します。

![2018-03-07 21.55.24 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/7020ad1f-1a4b-4d4a-9511-e05607334d04.png)

### ダッシュボード

![2018-03-07 21.57.26 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/6e86d8c8-9d08-8427-7a6d-77a1b5434684.png)

### コンテナ一覧

![2018-03-07 21.58.18 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/57de9dc9-5a5c-cc29-f3d5-1a9ec0e7c374.png)

### コンテナ詳細

コンテナに対して起動、停止、削除のアクションを発行できます。また、リソース使用状況やログの表示もできます。

![2018-03-07 22.50.27 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/f27ecc95-164d-74ad-590d-c7485461cbee.png)

### コンソール接続

[Containers] → [コンテナ名] → [Console] と遷移し、Connect をクリックするとコンソール接続できます。ブラウザ上で作業できます。
```docker exec -ti コンテナ名 bash``` をしなくても接続できるので、ちょっとコンテナの中を確認したい時に便利です。

![2018-03-07 23.06.05 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/8a33b639-6c11-8f21-8d81-9ff8116f1231.png)

### イメージ一覧

![2018-03-07 22.00.10 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/4d358b58-8976-7085-8ef2-19c9eb733b40.png)

### ネットワーク一覧

私の場合は、docker compose がよしなに作ってくれたサブネットがいくつか。裏でツールがしてくれている処理も、こうなっているんだなと実感できます。

![2018-03-07 22.00.27 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/61999446-1ed9-a2e6-84f2-942145b8e90b.png)

### ストレージ一覧

![2018-03-07 22.00.45 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/e1edce22-f2ad-cb6e-72e3-f95d7699eeca.png)

### アプリのテンプレート

著名なアプリのコンテナテンプレートです。これだけ並んでいると、今まで触ったことのない技術のコンテナを触ってみようという気になりました。皆様はいかがでしょう？

![2018-03-07 22.02.59 からのスクリーンショット.png](https://qiita-image-store.s3.amazonaws.com/0/48133/54a39da8-f8f3-ca55-2db2-26946710dfaa.png)
Ubuntu16.04 に Nemesisをインストールする。

初投稿になります。

備忘を込めてNemesisのインストール方法を記載します。

■目的
パケットインジェクションの実験を行います。
そのためにインジェクションツールのNemesisをインストールします。

■手順

１．まず以下のパッケージをインストールします。
$ sudo apt-get install libdnet-dev 
$ sudo apt-get install libpcap-dev

２．次にNemesisのソースをダウンロードします。
$ wget http://prdownloads.sourceforge.net/nemesis/nemesis-1.4.tar.gz
$ tar -xf nemesis-1.4.tar.gz

３．次にlibnetのソースをダウンロードします。
$ wget ftp://ftp.netbsd.org/pub/pkgsrc/distfiles/libnet-1.0.2a.tar.gz
$ tar -xf libnet-1.0.2a.tar.gz

４．libnetをmakeします。
$ cd libnet-1.0.2a
$ ./configure
$ vi Makefile　（以下のように修正する）
```MAN_PREFIX  =   ```
↓
```MAN_PREFIX  =   /usr/share/doc/```
$ make & make install
$ vi include/libnet/libnet-headers.h

```
#if (!__GLIBC__)
struct ether_addr
{
    u_char  ether_addr_octet[6];
};
#endif
```
↓

```
//#if (!__GLIBC__)
struct ether_addr
{
    u_char  ether_addr_octet[6];
};
//#endif
```

５．Nemesisをインストールします。
$ ./configure –with-libnet-includes=../Libnet-1.0.2a/include –with-libnet-libraries=../Libnet-1.0.2a/lib
$ make & make install
$ nemesisとコマンド入力して動いていればOK

終わり。

■参考
Nemesisのインストール手順：
http://theinfodox.blogspot.jp/2012/03/installing-nemesis-on-ubuntubacktrack.html

libnetインストール時のトラブルシュート：
http://www.mehic.info/2013/12/libnet-install-error-no-destination-specified/

NemesisのMake時のトラブルシュート：
（リンクを見失った...）
airflow initdb実行時にImportError(CSRFProtect)が出たときの解決方法

# 事象
`airflow initdb`実行時にこんな感じのエラーが出た

```bash:log
Traceback (most recent call last):
  File "/usr/bin/airflow", line 18, in <module>
    from airflow.bin.cli import CLIFactory
  File "/usr/lib/python2.7/site-packages/airflow/bin/cli.py", line 59, in <module>
    from airflow.www.app import cached_app
  File "/usr/lib/python2.7/site-packages/airflow/www/app.py", line 21, in <module>
    from flask_wtf.csrf import CSRFProtect
ImportError: cannot import name CSRFProtect
```

# 解決方法
以下のコマンドを実行して`flask-wtf`をアップデートする
`pip install --user --upgrade flask-wtf`

# 参考
[Can't import csrf module from within flask_wtf](https://www.pythonanywhere.com/forums/topic/1344/)
Airflow1.9でユーザが作れないときに一時的な対処法

[公式](https://airflow.apache.org/security.html)では以下の手順で作成するように書かれている

```python:公式
import airflow
from airflow import models, settings
from airflow.contrib.auth.backends.password_auth import PasswordUser
user = PasswordUser(models.User())
user.username = 'new_user_name'
user.email = 'new_user_email@example.com'
user.password = 'set_the_password'
session = settings.Session()
session.add(user)
session.commit()
session.close()
exit()
```

しかし`user.password = ...`のところで`AttributeError: can't set attribute`とエラーが出る
パスワード設定時、以下のようにすれば一応作成できる

```python
from flask_bcrypt import generate_password_hash
user._password = generate_password_hash(password, 12)
```

ソースを見るとpython3系を使っている場合はstrでキャストしてあげる必要があるっぽいので注意

# 参考
[ソース](https://github.com/apache/incubator-airflow/blob/master/airflow/contrib/auth/backends/password_auth.py)

# 更新
タイトルにバージョン追加
LaravelのPHPUnitでToo many connections

テストを実行中にmysqlで以下のエラーが出るようになった。([5.5.29](https://github.com/laravel/framework/releases/tag/v5.5.29)ではframework側で対応済みのようです)

```
PDOException: SQLSTATE[08004] [1040] Too many connections
```

# 対応方法

## 同時接続数を増やす

```
[mysqld]
max_connections=数値
```

数値を増やす（デフォルト値151）


## テストケース毎にコネクションを切る

`tearDown`に`DB::disconnect();`を入れる


## `PDO::ATTR_PERSISTENT`を設定する

[接続、および接続の管理](http://php.net/manual/ja/pdo.connections.php)
持続的な接続は、スクリプトが 終了しても閉じられずにキャッシュされ、他のスクリプトが同じ内容の 接続を要求してきた際にそれが再利用されます。

```diff:config/database.php
'mysql' => [
    'driver' => 'mysql',
    'host' => env('DB_HOST', '127.0.0.1'),
    'port' => env('DB_PORT', '3306'),
    'database' => env('DB_DATABASE', 'database'),
    'username' => env('DB_USERNAME', 'user'),
    'password' => env('DB_PASSWORD', 'password'),
    'unix_socket' => env('DB_SOCKET', ''),
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix' => '',
    'strict' => true,
    'engine' => null,
+   'options' => [
+       PDO::ATTR_PERSISTENT => env('DB_PERSISTENT', true),
+   ],
],
```

# 動作確認

挙動がよくわからなかったので以下をいろんなパターンで埋め込んでみた。

```php
var_dump(exec("mysql -u XXXXXXXXXXXX -pXXXXXXXXXXXX -Nse \"show status like 'Threads_connected';\""));
```

## テスト内

* 次のケースに移るとコネクション数が増えた。
（次のテストケースに行くと別コネクションになる？）

Laravelのテストは`setUp`で`\Illuminate\Foundation\Application`を毎回作成しているみたいなのでコネクションも新しいものを作っているのかも？

## 直接呼び出す

* 別プロセスで同じスクリプトを実行してみたら`PDO::ATTR_PERSISTENT`の設定があろうがなかろうがコネクションは増えた。
* テストからの実行ではない場合はコネクションは1つから増えなかった。

とりあえず以上のことから
テストケースの時だけ注意すれば良さそう。

私は`PDO::ATTR_PERSISTENT`で対応しました。

[PDO Too many connections when running test suite](https://github.com/laravel/framework/issues/18471)

↑
5.5.29では修正されているみたいでした。
[Disconnect from the database when refresh is done](https://github.com/laravel/framework/commit/d1fc2787a43c7d3e832e0dd14c3f26b782a3651f)
Python初学者がpyplotでX軸・Y軸の目盛りの使い方をやってみた

こんな使い方があるんだという備忘録としてmatplotlib.pyplotのX軸・Y軸、3つの使い方をまとめます。
※データはあえて入れませんでした。

#使い方1：デフォルトのメモリを使うとき
一番多い使用方法かも。

```ruby:qiita.rb
import matplotlib.pyplot as plt

#subplot_kw に何も指定しない
fix, axis = plt.subplots(2, 2) 
plt.show()
```

#使い方2：メモリが邪魔なとき、箱だけ作りたいとき
あまりないと思いますが、画像を収めたいときなど便利かも。

```ruby:qiita.rb
import matplotlib.pyplot as plt

# subplot_kw に何も表示しないよう指定する
kw = {'xticks':[], 'yticks':[]} 
fix, axis = plt.subplots(2, 2, subplot_kw=kw)
plt.show()
```

#使い方3：メモリを指定したいとき
使い方1に次いで多いかもしれません。

```ruby:qiita.rb
import matplotlib.pyplot as plt

# subplot_kw に目盛りを指定
kw = {'xticks':[0, 0.5, 1.0], 'yticks':[0.2, 0.4, 0.6, 0.8] } 
fix, axis = plt.subplots(2, 2, subplot_kw=kw)
plt.show()
```

#アウトプット
こんな感じです。

<img width="576" alt="xticks_yticks.png" src="https://qiita-image-store.s3.amazonaws.com/0/241427/f0a1507a-40c3-2914-b49a-fbfdae785d75.png">


忘れっぽい私には必要です。
[Azure]WebAppにユーザ認証を掛ける

# AADユーザでWebApp認証
WebAppに認証を掛ける方法のメモ

20180307

## <概要>
Azure Active Directoryを新規に作成して、Webアプリの認証ユーザにする。

今回はかっちょいい名前のAADを作ることにしました。

## <準備>

- カッコいい組織名（Azureポータルの画面右上に表示される）
- イケてる初期ドメイン名（Azureポータルへのサインイン時に入力するユーザ名の@？？？？？.onmicrosoft.comの？？？部分）
- App Serviceを作っておく

## AADを作る

1. ポータルにログオン
1. 新規 > セキュリティ+ID > Azure Active Directory
1. あらかじめ考えておいたイケてる単語を入力して作成ボタン  
![aad1.png](https://qiita-image-store.s3.amazonaws.com/0/242511/660f19e4-646a-7e81-b06b-1655972ac2d3.png)



## AADをそのサブスクリプションのADにする

1. サブスクリプション > サブスクリプション名　> 概要 > ⇒ディレクトリを変更する
1. フェールオーバー先に、先ほど作ったAADに選択し、変更をクリックする。  
![aad2.png](https://qiita-image-store.s3.amazonaws.com/0/242511/a1a8c3d5-468e-4d84-8c1e-758cbbf0d3b2.png)



## AADのユーザを作る

1. Azure Active Directory > 全てのユーザー
1. ユーザを作る。必要に応じてMFA（多要素認証）を設定
1. (サブスクリプション|リソースグループ|App service)に権限(所有者|共同管理者|閲覧者)を与える。  
⇒どこにどれだけの権限を与えるかは都度検討してください。

## アプリ認証に使う

1. App Service > 認証/承認
1. App Service認証を　オン
1. 認証プロバイダーを　Azure Active Directory  
![aad3.png](https://qiita-image-store.s3.amazonaws.com/0/242511/c7a570a4-9d15-97be-63f6-fcc3a4f24639.png)



1. ブレードが開くので　簡易　を選択  
![webapp04.png](https://qiita-image-store.s3.amazonaws.com/0/242511/f27ba462-e006-511c-1213-8e971ad07365.png)


1. アプリのURLを開くと、認証画面にリダイレクトされるのでAADユーザで認証すればログオンできる。
ReactのsetStateで配列の一部を変更する

# 備忘録
Reactの勉強をはじめて２時間詰まったところ↓
reactのstateに配列を設定した時、インデックスを利用して一部を変更したい。
# 解決策
スライスで配列をコピーしてからコピーの中身を変更して、それをsetStateする

```react
constructor(props) {
        super(props);
        this.state = {
            humans: ["あ", "い", "う"]
        }
    }

    change(i) {
        const humans_copy = this.state.humans.slice();
        humans_copy[i] = "変更"
        this.setState({humans: humans_copy})
    }
}
```

結局チュートリアルでした。
WebpackでDynamic importを行ってみる

ES6 Moduleには、`import ～;`と書く静的なものだけでなく、`import()`と関数っぽく書く、動的なものも登場しようとしています。すでに[一部のブラウザに実装されています](https://qiita.com/tonkotsuboy_com/items/f672de5fdd402be6f065)が、Webpackでも利用可能です。

# 事前準備

Webpack本体はバージョン3でもすでに`import()`を使えるようになっていますが、周辺ツールは対応するために事前準備が必要となります。

* `babel` - `import()`をシンタックスエラーとせずスルーさせるために、[babel-plugin-syntax-dynamic-import](https://babeljs.io/docs/plugins/syntax-dynamic-import/)が必要です。
* `eslint` -  標準では`import()`を文法エラーとしてしまうので、`"parser": "babel-eslint"`とする必要があります（もちろん、`babel-eslint`のインストールも必要です）。

# コードを書いてみる
あとは特に設定は必要なく、`import()`で分割するファイルのエントリポイントを読み込めば、ファイル分割まで自動で行われます（もちろん、他の箇所で静的に`import`されているものを動的に`import()`しても、すでにバンドルされているものが使われるので、改めてファイルが発生することはありません）。

`import()`は`Promise`を返しますので（IE11などではPolyfillが必要です）、単純に`.then`をつなげるなり、`Promise.all`で全部揃うまで待つなり、`async`-`await`で待たせるなり、ロード後のタイミングでの実行も問題ありません。

なお、Webpackが読み込むものを決められる必要があるので、`import()`の引数は完全に変数ではなく、文字列リテラルを含む式など、パスの手がかりが得られるものでないといけません。

## 分割後のファイル名を指定する

デフォルトでは、「0.js」のようなファイル名になってしまって、何が何だか分からないし、キャッシュパージも効かないので扱いづらいです。

これを改善するには、まず`import()`の側にコメントを追加します。

```javascript
import(/* webpackChunkName: "qiita" */'path/to/qiita').then(...);
```

こうすることでチャンクに名前が入るので、あとは`webpack.config.js`の`output.chunkFilename`（[リファレンス](https://webpack.js.org/configuration/output/#output-chunkfilename)）で名前のパターンを指定できます。

# 挙動を確認する
まず、全体のエントリポイントの側に、`webpackJsonp`というグローバル関数が用意されます（名前は設定で変更可能です）。そして、`import()`の実行は以下のように処理されます。

0. まず、ロード済みなら適切なライブラリを`require`して成功した`Promise`を返す
1. すでにロードが進行中なら、生成済みの`Promise`を返す
2. タイムアウトしたら失敗、ロードするファイルの`webpackJsonp`が実行されれば成功、というような`Promise`を作成する
3. `<script>`タグを`<head>`に追加
4. `Promise`を返す

ということで、

* 複数回`import()`しても、重複してロードが走ることはありません。
* 分割後のファイルを事前に`<script>`で読み込んであったような場合、読み込みは済むけど、`import()`実行まで中身は実行されません。

# 外部リンク

* [Dynamic import on Webpack]()
* [`import()`の説明 on Webpack](https://webpack.js.org/api/module-methods/#import-)
RubyでNEMのWebSocketを使う

# はじめに
RubyでNEMのWebSocketを扱った前例が無かったので調査しました。WebSocketやSTOMPの仕組みなどの解説はここでは省略します。

# 実装
```ruby
require "json"
require 'websocket-client-simple'
require 'stomp_parser'
require 'securerandom'


host = "http://alice3.nem.ninja"
port = 7778
path = "/w/messages/"
server = format("%0#{3}d", SecureRandom.random_number(10**3))
strings = [('a'..'z'), ('0'..'5')].map { |i| i.to_a }.flatten
session = (0...8).map { strings[rand(strings.length)] }.join

endpoint = host + ":" + port.to_s + path + server.to_s + "/" +session + "/websocket/"

ws = WebSocket::Client::Simple.connect(endpoint)
ws.on :open do
  connect_header = {"accept-version":"1.1,1.0","heart-beat":"10000,10000"}
  stomp_connect = '["' + StompParser::Frame.new("CONNECT", connect_header,"").to_str + '"]'
  ws.send(stomp_connect)
end

ws.on :message do |msg|
  if msg.data[0] == "o"

  end

  if msg.data[0] == "h"

  end
  if msg.data[0] == "a"
    data = msg.data
    data.slice!(0,data.index("[")+2)
    data.slice!(data.rindex("]")-1,data.length)
    data.gsub!("\\n","\n")
    data.gsub!("\\r","\r")
    data.gsub!("\\/","\/")
    data.gsub!("\\u0000","\u0000")
    data.gsub!("\\\"","\"")
    parser = StompParser::Parser.new
    parser.parse(data) do |frame|
      puts "We received #{frame.command} frame with #{frame.body} and headers #{frame.headers}!"
      if frame.command == "CONNECTED"
        blocks_header = {"id":"sub-0","destination":"/blocks"}
        stomp_subscribe_blocks = '["' + StompParser::Frame.new("SUBSCRIBE", blocks_header, "").to_str + '"]'
        ws.send(stomp_subscribe_blocks)
      end
      if frame.command == "MESSAGE"
        result = JSON.parse(frame.body)
        p result["timeStamp"]
      end
    end
  end
end

ws.on :error do |e|
  p(e)
end

loop do

end
```

# 解説
以下のような動作を行っています。

1. 接続先のURLを生成する
    - 接続先はhttp://ホスト名:websocket用のポート/w/messages/3桁の数字で構成された乱数/8桁の小文字の英字と0~5の数字で構成された乱数/となります。

2. WebSocketClientを用いて接続する
    - websocket-client-simpleを使用させていただきました。

3. open時にCONNECTコマンドを送信する
    - 以下のSUBSCRIBEコマンドの場合もですが、STOMPパーサーを使うとハッシュから楽にSTOMPに対応した文字列を生成できます。
    - SockJSの仕様か、生成したフレームは[""]で覆わないとサーバー側からの返信が来ません。

5. サーバーから通知が来たらデータの最初の一文字目で分岐する
    - "o"はサーバーがframeを開いた時に送信されるようです。
    - "h"はサーバーからのハートビートです。
    - "a"は[]内にサーバーからのデータが含まれています。

4. CONNECTEDコマンドを含む通知が来たらSUBSCRIBEコマンドを送信する
    - 受信時のデータは余分なバックスラッシュ等余計なものが多く、そのままではパースできないのでここで綺麗にしています。
    - このプログラムでは最新ブロック高監視を行っています。

5. MESSAGEコマンドを含む通知が来たらbodyをパース後データを表示
    - MESSAGEコマンドを含むフレームのbodyは通常のAPIと同じくjsonで記述されているので、簡単にパースできます。

# 詳細
[こちら](https://5hyn3.github.io/posts/use-nem-websocket-with-ruby/)にWebSocketなどの技術解説や調査方法についてまとめました。
この調査を元にしてrubyでnemのwebsocketを扱えるgemを作りました。詳しくは [こちら](https://5hyn3.github.io/posts/introduction-of-nem-websocket-client/)へどうぞ。

# 参考 
[github - varvet/stomp_parser](https://github.com/varvet/stomp_parser)
[github - shokai/websocket-client-simple](https://github.com/shokai/websocket-client-simple)
[github - sockjs/sockjs-client](https://github.com/sockjs/sockjs-client/blob/master/lib/main.js)
[github - sockjs/sockjs-protocol](https://github.com/sockjs/sockjs-protocol/wiki/Heartbeats-and-SockJS)
[田舎からGeekを目指す - NEMのWebSocket通信を使ってみた](https://ryuta46.com/770)
PHP で最大値・最小値を取り出す

　今回はアルゴリズムを学ぶ一環として、**PHPで「配列の中から最大値・最小値を取り出す」**を題材にして投稿しようと思います。復習も兼ねながらの投稿となります。

　最大値・最小値を取り出す方法としては

**　1.　組込み関数を使う方法
　2.　1.を使わず、素のプログラミングで書く方法**
　
　があるかと思います

それでは順に見ていきましょう


# :pencil2:   組込み関数を使う方法
　最大値・最小値を求める PHP の組込み関数として，`max` `min` があります。
これを使用すると、簡単に最大値・最小値を取り出すことができます。

```php:sample.php
<?php
$array = array(2,6,3,10,4);
echo max($array); //10
echo min($array); //2
?>
```


　それでは、これらを**「用いないで」**最大値・最小値を取り出すにはどうすれば良いのでしょうか。次から見ていきましょう。

# :pencil2:   組込み関数を使わない方法

　いわゆるアルゴリズムを使って最大値・最小値を取り出す方法です。今回は最大値を取り出すアルゴリズムを考えていきます。

#### :arrow_forward:  フローチャート

　1. 配列にデータを用意する
　2. 最大値を配列の最初の値に代入（初期化）
　3. 配列の最初から最後までループして比較。
　4. もし現在の最大値より値が大きければ上書きして変更


以上を踏まえて組んだプログラミングは以下のようになります

```php:sample.php
<?php
$array = array(2,6,3,10,4); //配列を用意する

$max = $array[0]; // 最大値に配列の最初の値を代入して初期化

// 2 つ目から最後まで、ループ処理
for ($i=1;$i<count($array);$i++){
  // 最大値より配列の値が大きければ上書きをする
  if($max<$array[$i]){
     $max=$array[$i];
  }
}
echo $max; //10
?>
```

※ 最小値もほぼ似たような感じです。現在の最小値より値が小さければ上書きするようにすれば最小値を取り出すことができます。
機械学習向けのデータ前処理でデータ分割をするにはどうすれば良いか

# 環境
- macOS
- python3.6 

# 想定ケース
- 機械学習向けのデータフレームを検証データと訓練データで分割したい
    - それぞれランダムサンプリングによる抽出を想定

# やってみる
## データソース
- Kaggleから適当に取得する
    - https://www.kaggle.com/datasets

## ソースコード
```
import pandas as pd

# データの読み込み
# 今回はUSのyoutubeトレンドデータ
df = pd.read_csv("USvideos.csv")

# テストデータをランダムサンプリングで抽出
df_test = df.sample(15000)

# 検証データを抽出
# 元データからdf_testのインデックスに該当するデータを除外する
df_validation = df.drop(df_test.index)
```

# 結果
```
> df_test.info()

Int64Index: 15000 entries, 4985 to 1561
Data columns (total 16 columns):
video_id                  15000 non-null object
trending_date             15000 non-null object
title                     15000 non-null object
channel_title             15000 non-null object
category_id               15000 non-null int64
publish_time              15000 non-null object
tags                      15000 non-null object
views                     15000 non-null int64
likes                     15000 non-null int64
dislikes                  15000 non-null int64
comment_count             15000 non-null int64
thumbnail_link            15000 non-null object
comments_disabled         15000 non-null bool
ratings_disabled          15000 non-null bool
video_error_or_removed    15000 non-null bool
description               14717 non-null object
dtypes: bool(3), int64(5), object(8)
memory usage: 1.6+ MB


> df_validation.info()
nt64Index: 6965 entries, 0 to 21954
Data columns (total 16 columns):
video_id                  6965 non-null object
trending_date             6965 non-null object
title                     6965 non-null object
channel_title             6965 non-null object
category_id               6965 non-null int64
publish_time              6965 non-null object
tags                      6965 non-null object
views                     6965 non-null int64
likes                     6965 non-null int64
dislikes                  6965 non-null int64
comment_count             6965 non-null int64
thumbnail_link            6965 non-null object
comments_disabled         6965 non-null bool
ratings_disabled          6965 non-null bool
video_error_or_removed    6965 non-null bool
description               6829 non-null object
dtypes: bool(3), int64(5), object(8)
memory usage: 782.2+ KB
```
うわっ…私のtrello、丸見え…？（簡易チェックツール付き）

# ググると出てくる誰かのボード

みんな大好きタスク管理ツールのTrello。

先日、Trelloの利用規約を調べようと思って「trello 利用規約」でググったら、公式の利用規約ページよりも誰かの公開ボードがヒットしました・・・
公開ボードになっていると検索エンジンにインデックスされるようで、「trello ○○」でググると色々なボードがヒットします。

恐ろしいググラビリティの高さです。
※悪用を推奨しているつもりではないですが、本当に簡単に色々ヒットしてしまいます。

# 非公開に設定しよう

ボードが公開設定になっていると、検索エンジンにインデックスされてしまいます。

![俺の恥ずかしい公開ボード   Trello.png](https://qiita-image-store.s3.amazonaws.com/0/106949/b2721f17-a983-0e35-c578-b33cba70e671.png)

皆さん、必要が無い限りはボードを非公開にしましょう。
以下のように、簡単に非公開に出来ます。

![俺の恥ずかしい公開ボード   Trello.png](https://qiita-image-store.s3.amazonaws.com/0/106949/d5c918a9-0579-ea3a-199e-a30d6fdaf37b.png)

# 公開ボードがないかチェックしよう

参加しているボードが沢山ある場合、ボードをひとつずつ開いて調べるのは大変なので、簡易チェックツールを作りました。
TrelloのAPI `https://trello.com/1/members/me/boards` を使用して、自分が参加しているボードの一覧を取得し、公開範囲を調べます。

Google ChromeでTrelloのページ上で `F12` か `Ctrl+Shift+i` を押し、Developer ToolのConsoleタブを開いてください。
そこに、以下のコードを貼付けて実行してください。

```javascript
function listup_trello_visibility() {
    $.ajax({
        type: 'get',
        dataType: 'json',
        url: 'https://trello.com/1/members/me/boards'
    }).success(function(response) {
        $.each(response, function(i, board) {
            var public = (board.prefs.permissionLevel === 'public');
            var output = board.name + '(' + board.prefs.permissionLevel + ')';
            if (public) {
                console.log('%c!! Check This Board\'s Permission Level !!\n' + output, 'color:red');
            } else {
                console.log(output);
            }
        });
    });
}
listup_trello_visibility();
```

すると、以下のように公開になっているボードは赤文字で表示されるようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/106949/c1d917e1-f17c-8bb1-e48d-d602e1000cac.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/106949/3c5a5c04-fda3-cafe-3783-83d0fa25e8c3.png)


公開Trelloボードに機密情報を乗っけていて流出した、なんてことがないように皆さんお気をつけ下さい！
PHP/MySQL　独学に使える入門サイト　初心者は何から始めればよいか。

#初心者が初めに学習するのに最適なサイト

##コンテンツサイト

　初心者用の学習サイトを検索するとたくさんヒットするようになってきた。そればもちろんいいことなのだが質的なところで時間の無駄になるサイトもある。初心者が回り道をしないように正しい道順で学習できるサイトとなると、実のところ少ないのではないか？

　ということでたくさんあるサイトの中からおすすめのものを紹介する。

###[世界一やさしいPHP入門](http://tech-beginner.mints.ne.jp/)
![hifhiss.jpg](https://qiita-image-store.s3.amazonaws.com/0/240587/055b4085-5c12-58d6-519f-f5fa4e0fdc53.jpeg)

こちらは初心者がつまずきやすいxamppのインストールなどが最新版で解説されている。コードも学習する意義の高いものを中心に扱っていて、まずやってみるのによい。

 HTMLなどを簡易的に学ぶこともできてPHP以外の言語にも配慮を払っている。また、その後の学習法などに関するアドバイスもあることから迷いなくステップアップできそう。デザインがおしゃれなのも◎

###[2017最新Xamppインストール](https://www.youtube.com/watch?v=HTBXF9drV7A&t=781s)
　こちらは、Xampp7以上のインストールからMySQLの設定までを丁寧に解説している。特にエラーの出やすいインストール時の対処方法などが詳細まで説明されており、初心者ならまず動画にしたがって環境設定すれば詰まることはないだろう。

##質の高い教材を
　初心者だからこそ、質の高い教材にちゃんとお金を払ってもらいたい。上記サイトはひとまず相性を確認するのにやってみるとかそういったレベル。Qiitaに質の高い記事はたくさんあるが、古くて使えない記事や、アマチュアが書いた危険なコードもある。それらを見分けるためにもお金を出して良質なコードから学んでほしいなと思う。お金を出すというのは高額なスクールに通うわけではなく、人気の教則本でよいと思う。いずれにせよ、まずは簡単にサイトで学習してモチベーションを上げてもらうのに上記サイトはぴったりである。
Unityインストール手順(2018年3月版)

Unity Hubを使用したインストール手順を記載します。

Unity Hubは異なるバージョンのUnityをインストール/アンインストール・管理したり、Componentの追加やプロジェクトを開く際のバージョン切り替えが容易に行えるツールです。

※記事投稿時はBeta版なので、不安な人はUnity Hubを使用せず通常の方法でUnityをインストールして下さい。

# 1. Unity Hubのダウンロードとインストール

**ダウンロード**
Unity Blogの以下記事にダウンロードリンクが貼ってあるので、「Windows」か「MacOS」を選択してインストーラをダウンロードします。

- [Unity Blog - Streamline your workflow—Introducing Unity Hub (Beta)](https://blogs.unity3d.com/jp/2018/01/24/streamline-your-workflow-introducing-unity-hub-beta/)
![UnityBlog](https://qiita-image-store.s3.amazonaws.com/0/242340/1f516290-27dd-a683-8302-965a39f74c7b.png)

**インストール**
インストーラを実行し、手順に従ってインストールして下さい。

# 2. Unityのインストール

**Unity Hubの起動**
インストールしたUnity Hubを起動すると以下の様な画面が表示されます。
![UnityHub1](https://qiita-image-store.s3.amazonaws.com/0/242340/a0d866b7-2c3b-93cb-6eb6-ab9faec5211d.png)
**Unityのインストール**
[Installs] - [Official Releases] から Unity 2017.3.1f1(現時点での最新version) の「Download」ボタン →「Done」ボタンをクリックしてUnityをインストールします。
(チェックはそのままで大丈夫です)
![UnityHub](https://qiita-image-store.s3.amazonaws.com/0/242340/2de713e2-6515-b34e-bc97-f91d5f0c3fa1.png)
インストールが完了すると、[Installs] に表示されます。
(他のバージョンをインストールしている場合は一覧で表示されます)
![UnityHub3](https://qiita-image-store.s3.amazonaws.com/0/242340/660c4028-39a5-dcfd-42fb-cc6bccea7b35.png)

# 3. Unityの起動

**プロジェクトの作成**
[新規] を選択してプロジェクトを作成します。
![UnityHub4](https://qiita-image-store.s3.amazonaws.com/0/242340/9f4c8059-805f-4420-d860-4e062303f4cc.png)
以下画面が表示されるので、
![UnityHub5](https://qiita-image-store.s3.amazonaws.com/0/242340/f2cc36db-3979-31f8-26cb-4c8cfa7494e2.png)

- Project Name：プロジェクト名
- Location：プロジェクトの保存パス
- Unity Version：起動するUnityのバージョン
- Template：3D or 2D
- Enable Unity Analytics：Unity Analyticsを使うかどうか(取り敢えずOFFでOK)

を設定して「Create project」ボタンをクリックします。

プロジェクトの生成が完了し、以下の様なウィンドウ(Unity Editor)が起動すれば準備完了です。
![UnityEditor](https://qiita-image-store.s3.amazonaws.com/0/242340/9c171dc6-9852-2d98-9364-f2074e4b8199.png)

# 4. プロジェクトを開く
Unity Hubの [プロジェクト] に作成したプロジェクトの一覧が表示されるので、開きたいプロジェクト名をクリックします。
![UnityHub6.png](https://qiita-image-store.s3.amazonaws.com/0/242340/9bf41319-f744-84f5-a6b2-99ad852eaced.png)

おわり
How to Setup Docker Keycloak Behind Apache2.4 with SSL in AWS?

# 1. Launch EC2(AMI) and RDS(MySQL) in AWS
 - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/install-LAMP.html

# 2. Create database and access user with name "keycloak"

# 3. Launch docker Keycloak
```
# docker run --name keycloak \
-e MYSQL_ADDR=your_aws_rds \
-e MYSQL_PASSWORD=keycloak_user_password \
-e PROXY_ADDRESS_FORWARDING=true \
-e KEYCLOAK_USER=your_keycloak_admin_name \
-e KEYCLOAK_PASSWORD=your_keycloak_admin_password \
-v /opt/jboss/keycloak/themes:/opt/jboss/keycloak/themes \
-p 127.0.0.1:8080:8080 \
-d jboss/keycloak
```

# 4. Download [Keycloak](http://www.keycloak.org/downloads.html)
```
# wget https://downloads.jboss.org/keycloak/3.4.3.Final/keycloak-3.4.3.Final.tar.gz
# tar zxvf keycloak-3.4.3.Final.tar.gz
# cp -R keycloak-3.4.3.Final/themes/* /opt/jboss/keycloak/themes
```

# 5. Modified ssl.conf
```
# vim /etc/httpd/conf.d/ssl.conf
...
...
...
<VirtualHost _default_:443>
...
...
...
# General setup for the virtual host, inherited from global configuration
DocumentRoot "/var/www/html"
ServerName your_domain_name
ServerAlias www.your_domain_name
Protocols h2 http/1.1

<LocationMatch "^/(auth)/*">
    ProxyPass http://127.0.0.1:8080
    ProxyPassReverse http://127.0.0.1:8080
</LocationMatch>
...
...
...
</VirtualHost>
...
...
...
!wq

# service httpd restart
```

# 6. Browse https://your_domain_name/auth

# Ref
- https://hub.docker.com/r/jboss/keycloak/
Windows10の初期セットアップ画面でシャットダウンする方法

リカバリーしたPCを他人に譲渡するとき、セットアップ開始の画面でシャットダウンする方法のメモ

- Shift+F10を押してコマンドプロンプトを表示させる
- shutdown /s /t 0

ちなみにMacはCommand+Q
【Unity】Editor拡張でスクリプトの名前を入れてリフレクションしようとしたらうまく行かなかった話

Editor拡張で自分で作成したスクリプトの情報を表示したい機会があって、一つ一つtypeofしてリフレクションで受け取るより名前を渡してリフレクションするほうが楽だよな～と思ってこんな感じのクラスを

```c#
namespace Assets.Scripts
{
   public class TestType : MonoBehaviour
   {
     ...
   }
}
```

```c#
Type type = Type.GetType("TestType"); 
```

で取得してみようとやってみたらnullが返ってきてあれ？と思い調べてたら解決に時間がかかってしまったので忘備録も含めて記事にしてみました。

#名前空間も入れないといけない
文字列でGetTypeする場合、クラスに名前空間があったらその名前空間も入れないとnullが返ってくるみたいです。
・参考にしたサイト様(http://blog.hiros-dot.net/?p=5520)

今回リフレクションしようと思ったスクリプトは名前空間も含まれていたので、

```c#
Type type = Type.GetType("Assets.Scripts.TestType"); 
```

こんな感じに入れてみましたが、またもやnullが返ってきました…。

#Assemblyを読み込まないといけない
調べていくとStackOverFlowに同じような現象が起きている投稿がありました。

URL:https://ja.stackoverflow.com/questions/1552/type-gettypestring%E3%81%AE%E5%B8%B0%E3%82%8A%E5%80%A4%E3%81%8Cnull%E3%81%AB%E3%81%AA%E3%82%8B

ここを見ると対応してるAssemblyからもGetTypeで型を取得できるみたいです。
なのでまず何のアセンブリがあるのか見てみることにしました。

```c#
var currentAssembly = Assembly.GetExecutingAssembly();
var referenceAssembly = currentAssembly.GetReferencedAssemblies();
```

GetExecutingAssemblyで現在のアセンブリの情報を取得できて、見てみると

```text
Assembly-CSharp-Editor, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
```

と表示されて、Editorのプロジェクトで使われているのがわかりました。
では今回自分が使おうとしているスクリプトはどのAssemblyなのか、Typeクラスを使って見てみました。


```c#
string assemblyName = typeof(TestType).Assembly.FullName;
```

```tex
Assembly-CSharp, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
```

UnityEditorのプロジェクトと自分が作ったスクリプトのプロジェクトは別物なので、GetTypeで読み込めなかったわけですね。なので最終的にこういう形になりました。

```c#
var assembly = Assembly.Load("Assembly-CSharp");
type = assembly.GetType("Assets.Scripts.TestType");
```

うまく読み込めてほっとしました。
Sparkの初期化処理


ちょっとやりたいことがあったので、Sparkの初期化処理を調べてたのだけど、かなり複雑です。
忘れないようにシーケンス図を張っておきます。

## シーケンス図

![sequence.png](https://qiita-image-store.s3.amazonaws.com/0/237238/e3f9aaca-b549-23b2-6faf-ed634a54962f.png)


## 登場人物紹介。

### Spark

Serviceインスタンスをsingletonで保持し、そのインスタンスのメソッドを呼び出すためのwrapperです。


### Service

ルーティングの設定、Serverの初期化などを行います。


### EmbeddedServers

組込サーバーのFactoryを管理します。何もしなければEmbeddedJettyFactoryが生成され、管理されます。


### EmbeddedServerFactroy(EmbeddedJettyFactory)

EmbeddedServerのfactoryです。


### EmbeddedServer(EmbeddedJettyServer)

Jettyなどが提供するServerのadaptorです。


### JettyServerFactory(JettyServer)

JettyのServerインスタンスを生成するためのfactoryです。



## 拡張

事前にEmbeddedServersにEmbeddedServerFactoryを登録しておくことで、独自の処理に差し替えを行うことができます。


````java:

public static void main(String[] args) {

  EmbeddedServers.add(EmbeddedServers.Identifiers.JETTY, new MyEmbeddedServerFactory(new MyJettyServerFactory())); // 今のところキーを変更することはできないので、第一引数はEmbeddedServers.Identifiers.JETTYを指定する必要があります。

  get("/", (request, response) -> "Hello World")
}

````

Jettyの細かい設定を行う場合は、この辺のクラスを拡張して実装を行う必要があります。

参考
https://qiita.com/teekee/items/92ccfa892d6a9d02731c
Windows10 IoT Core上でNode-Redを動かしてみる。

Windows10IoTCore上でNode-Redを動かしてみます。
次のブログを参考にしました。

・[Connecting Raspberry Pi with Windows IoT Core as a Device to Watson IoT using Node-RED](https://developer.ibm.com/recipes/tutorials/connecting-raspberry-pi-with-windows-iot-core-as-a-device-to-watson-iot-using-node-red/)

javascriptエンジンはMS製ChakraCoreを使います。

#ダウンロード&インストール
・ChakraCoreの最新版（win-arm.zip)を[ここ](https://github.com/nodejs/node-chakracore/releases)からダウンロードして解凍しておきます。

・npmを[ここ](https://github.com/npm/npm/archive/master.zip)からダウンロードして解凍します。（最新版をダウンロードしても使えないようです。）

・解凍してできた「npm-master」をそのままIoTCoreのCドライブへコピーしてから、フォルダ名を「node」に変更します。（変更するのは別の名前でも構いません。）

・解凍したChakraCoreフォルダ内の「node.exe」と「chakracore.dll」をnodeフォルダへコピーします。

これで　node.exe cli.js install \<your package name>　と入力することでパッケージのインストールができるようになりました。

続いてNode-Redのインストールを行います。

・PowershellかSSHでIoTCoreにアクセスします。

・nodeフォルダに移動します。

・「node.exe cli.js install node-red」と入力してコマンドを実行します。

・「netsh advfirewall firewall add rule name="Node.js" dir=in action=allow program="C:\node\node.exe" enable=yes」と
　　入力しFirewallの設定を行います。

・「node-red」と入力して起動します。

・ブラウザで「http://{IoTCoreのアドレス}:1880/」にアクセスしてエディタが表示されればインストールは完了です。

#現状
ラズパイのGPIOへのアクセスはできない（ノードがありません。python RPi.GPIOをインストール出来たら使えるのかな）ようです。
ゲートウェイ的な使い方しかできないかもしれません。Raspbianに含まれているNode-Redよりは動作は軽そうなのですが・・・・
何かいい使い道はないでしょうか？

現在Windows IoT Core公式サイトではnode.jsに関するドキュメント及びサンプルコードなどがなくなっています。
node.jsのサポートはなくなったのかな。
gistにユーザ認証が成功したかどうか。fetchで。

### まず、最も正しそうな方法。
https://api.github.com/authorizations
でチェック。ただし、basic認証のみ。

### 簡単な方法。HEADでチェック。
認証が成功するとapiの使用限界が変わる。60=>5000
あるいは status 401が認証に失敗したcodeとしてとりあえず返ってくる。
アクセス先は、gist内ならどこでもいい。
https://api.github.com/gists/public

```js
 let chk=res.headers.get('X-RateLimit-Limit');
 //or res.status ==401 is NOT
``` 

### 全部
```html
<input type="text"></input><input type="password"></input>
<button onclick="auth()">chk</button><label>ret</label>
```
```js
let fn={}
fn.q=(d=>document.querySelector(d))
;
function isAuthGist(str){
  let url ='https://api.github.com/gists/public'
  ,opt ={method:"HEAD",mode:"cors",headers:{"Authorization":str}}
  ;
  return fetch(url,opt).then(res=>{
    let chk=res.headers.get('X-RateLimit-Limit');
    //or res.status ==401 is NOT
    console.log(res.status)
    return (chk && chk!=60)?true :false
  })
}
;
function auth(){
  let u=fn.q('input[type="text"]').value
  ,p=fn.q('input[type="password"]').value
  ,str ='basic '+ btoa(u+':'+p)
  ;
  isAuthGist(str)
    .then(d=>{fn.q('label').textContent=''+d;return d})
  ;
}
;
```
### response header
```
/*NOT*/
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Content-Length:93
Content-Security-Policy:default-src 'none'
Content-Type:application/json; charset=utf-8
Date:Wed, 07 Mar 2018 13:12:26 GMT
Server:GitHub.com
Status:401 Unauthorized
Strict-Transport-Security:max-age=31536000; includeSubdomains; preload
X-Content-Type-Options:nosniff
X-Frame-Options:deny
X-GitHub-Media-Type:github.v3; format=json
X-GitHub-Request-Id:F464:41E2:DE8869:104A905:5A9FE52F
X-RateLimit-Limit:60
X-RateLimit-Remaining:58
X-RateLimit-Reset:1520431935
X-Runtime-rack:0.061018
X-XSS-Protection:1; mode=block
```
```
/*authed*/
Access-Control-Allow-Origin:*
Access-Control-Expose-Headers:ETag, Link, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval
Cache-Control:private, max-age=60, s-maxage=60
Content-Encoding:gzip
Content-Security-Policy:default-src 'none'
Content-Type:application/json; charset=utf-8
Date:Wed, 07 Mar 2018 13:13:20 GMT
ETag:W/"ed8a0671388a83cfa6e5f705c5f2c191"
Link:; rel="next", ; rel="last"
Server:GitHub.com
Status:200 OK
Strict-Transport-Security:max-age=31536000; includeSubdomains; preload
Vary:Accept-Encoding
Vary:Accept, Authorization, Cookie, X-GitHub-OTP
X-Content-Type-Options:nosniff
X-Frame-Options:deny
X-GitHub-Media-Type:github.v3; format=json
X-GitHub-Request-Id:F464:41E2:DE94E1:104ACA4:5A9FE53A
X-RateLimit-Limit:5000
X-RateLimit-Remaining:4997
X-RateLimit-Reset:1520429607
X-Runtime-rack:0.237184
X-XSS-Protection:1; mode=block
```
CircleCI効率化

##背景
私の会社のアプリケーションは、大きく`client/*`と`server/*`に分かれており(SPA構成)、GitHubにpushするごとに全てのテストを回していました。
しかし、テストの量が多くなっていくにつれ、CIが通るまで1回あたりに10分程度かかるようになってしまいました。
そこで、`client/*`と`server/*`のうち、変更があった方（両方変更があったなら両方）のテストのみを回せば効率化できるだろうということで色々記事を探したのですが、意外とハマったりしたので記事にしました。

##今までの実装
CircleCI2.0で登場した`workflows`を使って以下のように実装していました。

```yml:.circleci/config.yml
version: 2

jobs:
  build_client:
    docker:
      xxx
    working_directory: xxx
    steps:
      # パッケージのインストール...
　　　　　　　　　　　　# テスト...etc

  build_server:
    docker:
      xxx
    working_directory: xxx
    steps:
      # パッケージのインストール...
　　　　　　　　　　　　# テスト...etc

workflows:
  version: 2
  build-all:
    jobs:
      - build_client:
          filters:
            xxx
      - build_server:
          filters:
            xxx

```

このコードを
・stepsでの実行コマンドを別スクリプトに移す
・stepsで↑のシェルスクリプトを実行する
・変更の有無によって条件分岐する（ハマりポイント）
ことで、効率化を図りました。

##実行コマンドを別スクリプトに移す
以下の２つのファイルを作成しました。
全ての工程を移すのではなく、特に時間のかかっていた工程を移しました。
（job自体をskipすることができれば一番いいのですが、どうやら無理らしいです。）

```sh:build_server.sh
#!/bin/bash

# Database setup
# run tests
```

```sh:build_client.sh
#!/bin/bash

# install packages
# test
```

##stepsでシェルスクリプトを実行する
```yml:.circleci/config.yml
jobs:
  build_client:
    docker:
      xxx
    working_directory: xxx
    steps:
      - checkout

      - run:
          name: tests
          command: |
            if # clientに変更があれば
              bash .circleci/build_client.sh
            fi
```

##変更の有無によって条件分岐する
はじめ、以下のように実装しました。

```yml:.circleci/config.yml
jobs:
  build_client:
    docker:
      xxx
    working_directory: xxx
    steps:
      - checkout
      
      - run:
          name: tests
          command: |
            compare_url=$CIRCLE_COMPARE_URL
            compare_ids=${compare_url##*/}
            diff=$(git diff --name-only $compare_ids)

            if [[ "${diff}" =~ client/ ]] ; then
              bash .circleci/build_client.sh
            else
              echo 'skip client test'
            fi
```

CircleCIには環境変数が与えられていて、`CIRCLE_COMPARE_URL`もその１つです。
これには、`https://github.com/xxx/xxx/compare/yyy...zzz`というような値が入っています。
ここから比較すべきコミットID（yyyとzzz）を取り出し、変更ファイル名を見て`client/`があればシェルスクリプトを実行、なければskipという意図でした。

大抵はうまくいったのですが、たまに`CIRCLE_COMPARE_URL`の値が
`https://github.com/xxx/xxx/commit/yyy`のようになっていることがあり、うまくdiffを取り出せないことがありました。
（原因はわかっていません。ご存知の方がいましたらコメント欄にてご指摘いただければと思います。）

##改善
結局、コミットIDではなくブランチを比較してテストを回すことになりました。
実行は以下の通りです。

```yml:.circleci/config.yml
jobs:
  build_client:
    docker:
      xxx
    working_directory: xxx
    steps:
      - checkout
      
      - run:
          name: tests
          command: |
            branch=$CIRCLE_BRANCH
            diff=$(git diff --name-only origin/develop...${branch})

            if [[ "${diff}" =~ client/ ]] ; then
              bash .circleci/build_client.sh
            else
              echo 'skip client test'
            fi
```

何はともあれ、回す必要のないテストをskipすることで、CIがサクサク回るので快適です！
Flutter開発にDart2を使用する設定


Android Studio -> Preferences -> Languages & Frameworks -> Flutter に移動して、`Run applications with --preview-dart-2` にチェックを入れて、Android Studioを再起動すれば、Dart2で開発することができます。

Dart2では`new`キーワードがオプションになったので、インスタンス生成している`new MyApp()`のようなコードを`MyApp()`に変更して問題なければ正常にDart2が使えていると考えて良さそうです。

![use-dart2.png](https://qiita-image-store.s3.amazonaws.com/0/18273/c1afc8b7-ca7e-c64b-c0f6-fca81810dffe.png "use-dart2.png")

[参考](https://medium.com/dartlang/announcing-dart-2-80ba01f43b6)
初心者向けプログラミング解説書紹介

随時更新していきます。

#対象
- 新人SE/PG
- SIer勤め
- 新人教育に向いた書籍が知りたい

#自己紹介
2016年に文系大学卒業後、SIerのSEになって毎日プログラミングしてる。
プログラミング歴＝社会人歴。
読んで役にたった〜、これはありがてえ説明だ〜と思ったものを紹介する。

#IT基礎の部分から学ぶ
##[小学生でもわかるプログラミングの世界](http://amzn.asia/9x0ZKO9)
タイトルどおりでわかりやすい。
プログラミングの話よりは、コンピューターの歴史や仕組みの話が多め。
プログラマーの職業についての話もあるため、IT系志望の就活生にもおすすめ。
あとはITに疎い人に対して説明をしなければいけないときの参考になるかも。
全体像をざっくりと掴むにはいい。

<!-- #アルゴリズムを学ぶ -->

#プログラミング全体を学ぶ
##[なるほど！プログラミング](http://amzn.asia/3xMbNYf)
基本情報の問題文見て「はあ？？？？わからぬ〜〜〜」となった人向け。
アルゴリズム重視の内容で、プログラミング思考を身につけるための解説書。
私の苦手な電子回路について懇切丁寧に記述されている。ありがてえ。

##[プログラムの絵本](http://amzn.asia/hz17pMB)
文章で説明されてもいまいちわかりにくい、というときにおすすめ。
絵本というとおり、すべて図解されているのでイメージが理解しやすい。
言語特化の絵本もあるので合わせて読むと良さそう。
01の世界観が詳しく書かれている。ありがてえ。

#C#を学ぶ

##[C#の絵本](http://amzn.asia/egAZjfu)
C#に特化した解説書。
数値型いっぱいあってわからぬ〜〜というC＃初心者向け。
前述の[プログラムの絵本](http://amzn.asia/hz17pMB)同様、if/forの使い方、配列の仕組みなどプログラミングに必要な内容も網羅されている。
初めてのプログラミング言語がC#という人にはおすすめ！！！！

#プログラミング以外のスキルを学ぶ
##[ITエンジニアのための伝わる文章力ドリル](http://amzn.asia/d6JgPZB)
Redmineのチケット書くときや設計書書くときの大いに役立つ。
自分以外の人間とプロジェクトを進めるにあたりまずは押さえておきたい点がたくさんある。
とくに時制や誰が何をすると明記することが大事ということ。
こう書くと当たり前じゃんと思うけど、実際できているかチェックしてみよう。
メンバー全員一読してからプロジェクト始めたいと思うようになった。

##[外資系コンサルのスライド作成術](http://amzn.asia/aTQXHKJ)
このスライドだせえとは思えるけど、ださくないスライドを作り出すことのできないときによい。
スライドの実例があるので、とりあえず真似すればそれっぽくなる。
真似して覚えて身につけていこう。
Windows Mixed Reality ソフトウェアをダウンロードできませんでした。について

##結論から述べるとWindows Updateから最新の更新プログラムをアンインストールしたらループから抜けました。 

当方はこの記事に対し一切の責任を負いかねます。自己責任でお願いします。

###経緯
ポータルを起動したら、

"問題が発生したため、Windows Mixed Reality を開始できませんでした" 

が、表示されたので、公式のトラブルシューティングの手順に従って以下のことを行いました。
https://support.microsoft.com/ja-jp/help/4039262/windows-10-mixed-reality-setup-faq
> 上の手順で問題が解決しない場合は、Windows Mixed Reality をアンインストールしてから再インストールします。[設定] 、[Mixed Reality]、[アンインストール] の順に移動し、[アンインストール] を選択します。次に、コンピューターを再起動します。セットアップ プロセスをもう一度開始するには、ヘッドセットを PC に接続します。

セットアッププロセス（Mixed Reality Portal）の最後の方にダウンロードを行うのですが、77~78%?で一旦止まり、一気に100％になってタイトルの文字列とやり直しボタンが表示されました。もちろんやり直しボタンを押してもループします。

そこで、以下のURLを参考にし試してみました。（解決はしませんでした）
https://answers.microsoft.com/en-us/windows/forum/apps_windows_10-winapps-appscat_photo/how-to-uninstall-mixed-reality-portal-and-viewer/50fd6e00-5fb0-48f6-ba14-3173ca8da284
https://answers.microsoft.com/en-us/windows/forum/apps_windows_10-winapps-appscat_photo/how-to-uninstall-mixed-reality-portal-and-viewer/50fd6e00-5fb0-48f6-ba14-3173ca8da284
https://social.technet.microsoft.com/Forums/windows/en-US/51689328-d2ce-4919-a51a-3959228121f6/how-to-remove-mixed-reality-portal-app-from-windows10-1703?forum=win10itprogeneral
https://www.askvg.com/tip-disable-or-remove-mixed-reality-portal-app-in-windows-10/

上のURLに従って変えたものを一部直しました（消してしまい直せないものもありました）。

最後に藁にもすがる思いで、最新の更新プログラム（下に記載）をアンインストールし、再起動しました。

　2018-02 x64 ベース システム用 Windows 10 Version 1709 の累積更新システム (KB4090913)

Mixed Reality Portalを起動し、セットアップを試したらループから抜けていました。なぜかが特定できてないのでいまいちすっきりしていません。
Rust html解析 スクレイピング

## scraper

神スクレイピングライブラリ

## 宣言

```Rust
extern crate scraper;
use scraper::{Selector, Html};
```

## htmlの用意

```Rust
let html = r#"<html>...</html>#";
```

## htmlのパース

```Rust
let document = Html::parse_document(html);
```

## cssセレクタの用意

```Rust
let css = "head";
```

## cssセレクタのパース

```Rust
let selector = Selector::parse(css).unwrap();
```

## スクレイピング

```Rust
for node in document.select(&selector) {
    //処理
}
```

## node

・文字列として取り出す

```Rust
node.value()
```

・属性を取得

```Rust
node.value().attr("content").unwrap()
```

### 例

```Rust
for node in document.select(&selector) {
    let content = node.value().attr("content").unwrap_or("");
    let i = content.find("charset=");
    let charset = match i {
        Some(i) => {
            &content[i+8..]
        },
        _ => ""
    };
    println!("{}", charset);
}
```

## html取得

[こちらを参照ください。](https://qiita.com/miyagaw61/private/018246556abfd145bb43)

## エンコーディング

[こちらを参照ください。](https://qiita.com/miyagaw61/private/698416c49eaf085e16e7)
Markdown All in One のショートカットとコマンド

Visual Studio Code のプラグイン [Markdown All in One](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one) のショートカットとコマンドについて

## ショートカット

| キー               | 説明                |
| ---------------- | ------------------- |
| <kbd>ctrl + b</kbd>         | ボールド表記のオン/オフ      |
| <kbd>ctrl + i</kbd>         | イタリック表記のオン/オフ     |
| <kbd>ctrl + shift + ]</kbd> | ヘッディングレベルを上げる     |
| <kbd>ctrl + shift + [</kbd> | ヘッディングレベルを下げる     |
| <kbd>alt + c</kbd>          | チェックリストのチェック/アンチェック |

## コマンド

| コマンド                                     | 説明                  |
| ---------------------------------------- | --------------------- |
| Markdown: Create Table of Contents       | TOCの作成              |
| Markdown: Update Table of Contents       | TOCの更新              |
| Markdown: Toggle code span               | 選択したテキストを ``` で囲む  |
| Markdown: Toggle strikethrough           | 選択したテキストを `~~` で囲む |
| Markdown: Print current document to HTML | HTMLに出力             |

## 参考

[Markdown All in One - Visual Studio Marketplace](https://marketplace.visualstudio.com/items?itemName=yzhang.markdown-all-in-one)
[neilsustc/vscode-markdown: Markdown All in One](https://github.com/neilsustc/vscode-markdown)
backlogからWebhookでGitHubにissueを登録

## やりたかったこと

backlogを課題管理に、Githubはエンジニアの内部タスク管理というように、並行利用しています。
backlogでお客さまから依頼が来た際に、手動で内部用のissueを立てていましたが、これを自動化してみました。

## 構成

図解するほどじゃないですが。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/32552/f6c149aa-594c-ab2d-aac3-3606ff7d3e9e.png)

## backlog側

プロジェクト設定->Webhookで、スクリプトのURLを指定
プロジェクトに対する管理者権限がないと、設定できないようです。

## フックするスクリプト

飛んできたJSONを処理して、APIをcurlで叩く


**案件やリポジトリによって変える場所**

```php
const BACKLOG_PROJECT   = "PRJNAME";
const GHE_TOKEN         = "xxxxxxxxxxxxx";
const GHE_ORGANIZATION  = "xx";
const GHE_REPO          = "repository name";
const GHE_URL           = 'https://xxxx.xxx';//GitHub EnterpriseのURLを指定
```

**curlでGithubAPIを叩くところ**
今のところ、新規登録時のみに動かしているため、APIのエンドポイントは
`POST /repos/:owner/:repo/issues`
https://developer.github.com/v3/issues/#create-an-issue

```php
/*
 GHEのAPIを叩く
 */
 $data = [
     'title' => '🔗 backlog - '. $summary,
     'body' => 'from https://[xxxx].backlog.jp/view/' . $projectKey . '-' . $key_id . "\n\n" . $description,//backlogの本文プラスURL
     // 'assignees' => [ 'onuma' ]
 ];
 $header = [
     'Authorization: token '. GHE_TOKEN,  // tokenをヘッダに含める
 ];

//特定のプロジェクトだったら
if( $projectKey === BACKLOG_PROJECT){
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, GHE_URL.'/api/v3/repos/'. GHE_ORGANIZATION. '/' . GHE_REPO . '/issues');//apiのエンドポイント
    curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'POST'); // post
    curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); // jsonデータを送信
    curl_setopt($curl, CURLOPT_HTTPHEADER, $header); // リクエストにヘッダーを含める
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_HEADER, true);

    $response = curl_exec($curl);

    $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
    $header = substr($response, 0, $header_size);
    $body = substr($response, $header_size);
    $result = json_decode($body, true);

    curl_close($curl);
}
```
## GitHub側

認証のためのアクセストークンを生成

## 参考URL
以下を参考にさせていただきました。
https://gist.github.com/hissy/6a114d0d9a85f3338aed
https://qiita.com/re-24/items/bfdd533e5dacecd21a7a
https://developer.github.com/v3/issues/#create-an-issue

## 今後の展開

サーバが必要なのはちょっと今時っぽくないので、Google のCloud functionsで動かすように
書き換えたいと思ってます。
iPhoneだけjQueryのセレクタでシンタックスエラーが出て死ぬ

# コード

```javascript
const name = $('[name="tag[Hoge][name]"]').val();
const address = $('[name="tag[Hoge][address]').val();
```

# 結果

2行目で死にます
2行目はセレクタの末尾に`"]`が足りません
PC, Androidだと何故か期待通りに動きます
iPhoneだとSafariでもChromeでも死にます

# まとめ

罠にはまらないように、セレクタは一目で正しいと分かるものにしよう