OmniAICreator/Qiita-1.07M huggingface dataset:
VBLINQで直積

```
''' <summary>
''' http://qiita.com/shinaisan/items/d57bc231ac0a9a340184
''' </summary>
''' <remarks></remarks>
Module Module1

    Sub Main()

        Dim grades As String() = {"1年", "2年", "3年"}
        Dim classes As String() = {"A組", "B組", "C組"}

        Dim GradeClass = From g In grades
                         From c In classes
                         Select New With {.grade1 = g, .class1 = c, .text = (g & c)}

        For Each n In GradeClass
            Console.WriteLine(n.text)
        Next
        Console.ReadLine()
    End Sub

End Module
チケットの書き方アンチパターン

チケットを使わない開発現場はありません (と信じている) が、正しく活用できていない現場をよく見かけます。依頼内容が不明だったり、どこまで作業しているのか分からなかったり、山積みのゴミチケットのせいでどれを作業するべきか発見するのに時間がかかったり。

チケットをどのように使えば、チームの生産性が上がり、ナレッジ喪失のリスクも減らせるのでしょうか？

これまでの経験談を元に、アイディアをまとめておきます。


前提となるマインドセット
----
### どれくらいの詳細度にするかはチームのふりかえりで決める

どんな書き方がベストかは、チームによって異なります。定期的なふりかえりで調整しましょう。

例えば、メンバーがすぐ隣にいるチームなら、チケットに不備があってもすぐ聞けます。逆にオフショア開発などでメンバーが離れており、オンデマンドでコミュニケーションが取れない場合は、最初からチケットを詳細に書くほうが早く仕事を進められるでしょう。

ふりかえりの際には、「あの書き方だとわかんないから、次からはこう書いて」と伝えればそれで十分でしょう。

### 一般的にはハイコンテクストよりローコンテクストの方がベター

- *ハイコンテクスト*: 省略された言葉で多くの意味が伝えられる状態
  - 例: 「foo.rb を直す」
- *ローコンテクスト*: 直接的で論理的な説明を求められる状態
  - あいまいさが無いように書く
  - 例: 「foo.rb の10行目の引数に A クラスのインスタンスを渡すのは間違い。 B クラスに変更する」
- ローコンテクストの方がナレッジ喪失のリスクが低いのでベター
  - チーム変更などで、それまでの歴史を知らないメンバーが入った場合でも、当時の依頼内容や作業内容が分かる

### 詳細度とコストはトレードオフ

チケットをローコンテクストで詳細に書くほうが、作業の間違いが減り、1年後のナレッジ喪失リスクが低くなります。一方で、読み書きのコストは高くなります。

どのくらいのバランスで書くべきか、ふりかえりで決めましょう。

### 的確なキーワードを含めることで検索性が上がる

- 修正対象のコンポーネント名や、エラーメッセージ等をチケットに書くと、後で検索しやすくなる
- チケット管理システムによってはタグやラベルといった機能も活用できる


アンチパターン
----
### チケットの説明文を書かない

チケットの件名だけ書いてあって、何をやるか内容が書いていないパターン。具体的になにをやればいいのかや、なぜそのチケットが発生したのかも分かりません。

#### NG な例

> 件名: A メソッドを直す
> 本文: (空)

#### OK な例

> 件名: A メソッドの条件分岐を直す
> 本文: A メソッドに NULL が渡された時は `true` を返すのが正しいのに、 if 分岐内で `false` を返してしまっているので、修正する。

#### 改善ポイント

- 説明文は書きましょう
- 「何を」「いつ」「どのように」変更するかが書かれていると Good

### 作業した内容を書かない

説明文やコメントで、実際にどんな作業をしたのかを書かないと、ナレッジが属人化します。また、システムへどんな変更をしたかの歴史が失われ、後で「なんでこの部分変更されてるの？」といった混乱を招きます。

#### NG な例

> 件名: 同じ記事を別のユーザーが同時に編集すると、先に編集した方の内容が失われる
> コメント: 修正完了 → close

#### OK な例

> コメント: 排他処理を実装。記事を編集開始した時刻から保存する時刻の間に、別の更新が発生した場合、「ほかのユーザーが編集しました」とエラーを出して、上書きするか確認する画面を出すようにした。

#### 改善ポイント:

- 作業内容はできるだけ残しましょう
- 「何を」「どのように」変更したかを確実に書きましょう

### ステータスを更新しない

そのチケットが未着手なのか、進行中なのか、レビュー待ちなのか、完了しているのかが分からないパターン。

この症状が出ている現場は、以下の問題を抱えている可能性があります。

- タスクをひとつひとつ確実に Done する習慣がない
- 大量の「進行中」チケットが慢性的に登録されている

#### 改善ポイント:

- しばらく作業する予定が無いチケットは、「待ち」ステータスにする
  - 他チームのレビュー待ちなど、自チーム内で完結できない状態が長く続いているなら、一度 done にして「他チームのレビューが完了している」など別チケットにしてしまうのもアリ
- 朝会 (デイリースクラム) やスプリント計画で、確実に Done させるべきチケットを選ぶ
- 定期的なイベント (スプリントレビュー) で、チケットのステータスが正しいか確認する

ちなみにカンバンの考え方では、同時進行中の作業を減らし、一つ一つのタスクを素早く完了させる方が、生産効率が上がります。 （参考: [カンバンはどのように動作するか](https://www.infoq.com/jp/articles/how-kanban-works) ）


### 「チケット掃除人」だけが更新している

チームリーダーなど、一部のメンバーだけがチケットを更新しているパターン。

掃除人に管理コストが集中してしまうため、掃除人のリソースが圧迫されます。また、実際に作業したメンバー自身がチケットを書かないせいで、作業内容が正しく記録されません。

#### 改善ポイント:

- 「作業完了したら、チケットをクローズする」という習慣をメンバーに植え付けましょう
  - 理想的なチームは、各メンバーが自律的にタスクを Done します
Polymerで作ったアプリやカスタムエレメントをSelenium Gridを使ってテストできるようにする

## Polymer で作ったアプリやカスタムエレメントをテストする

コマンドラインから実行する場合は、以下のように指定します。

```bash
$ polymer test
$ wct test/index.html
```
`wct` は [web-component-tester](https://github.com/Polymer/web-component-tester)の略で、 `polymer test` も内部で呼び出しています。
Jenkinsなどを使ってテストしたい場合、wctがnode.jsに対応しているので、gulpから呼び出すようなケースもあるでしょう（私はこの方法を使っています）。

## Selenium Grid を使う

Jenkinsからテストする場合、Selenium Gridを使うことが多いのではないでしょうか？
Polymerの公式には、UnitTestは `local` もしくは `remote(Sauce Labs)` というモードがあるものの、Selenium Gridでテスト可能であることは書いていません。
StackOverflowで調べると解決策が出てきます。

[Configure Polymer web-component-tester to use a Selenium Grid server](https://stackoverflow.com/questions/28373910/configure-polymer-web-component-tester-to-use-a-selenium-grid-server)

ここで紹介されている例のとおりで **実行できていました** 。

## Polymer CLI が 1.0.0 になると動かなくなる

先日の Google I/O '17 のツールセッションでも発表がありましたが、CLIツールが1.0になりました。
さっそく1.0にアップグレードしてみると、Selenium Gridでテストが動かなくなっています。

これの原因を調べるのにかなりの時間を要しましたが、web-component-testerのissueにありました。
[WCT ignores the webserver hostname #523](https://github.com/Polymer/web-component-tester/issues/523)

Polymer CLI 1.0でweb-component-testerがv6以上を要求するため、この問題が表面化しました。

詳しくは issue を参照してほしいのですが、今までは最初のstackoverfowのとおり `webserver.hostname` が参照されていたのですが、`localhost`へのハードコーディングに変更となっています。
変更理由は[こちらのチェンジログ](https://github.com/Polymer/web-component-tester/blob/master/CHANGELOG.md#600---2017-05-15)に書かれています。

Selenium Gridでのテストは正式にサポートされているわけではないので、この変更にどうこう言えないのですが、みんなが Sauce Labs使っているわけではないのでね...

そのissueを上げた人は[PR](https://github.com/Polymer/web-component-tester/pull/524)も出していて、マージされないかなーと思っています(`cla:yes` になっているのでマージされると思っている)。

## 現時点の解決策

が、上記修正だと **個人的に** 困るので web-component-tester v5.x と同じ設定で Selenium Gridを実行できるように修正しました。

https://github.com/sizuhiko/web-component-tester/tree/use-webserver.hostname-by-selenium-grid

`npm install` で入れる場合、TypeScriptをコンパイルしたJavaScriptが必要になる(gitignoreされているので通常ではリポジトリにはない)ので、`use-webserver.hostname-by-selenium-grid-4-npm-install`という（コンパイル済みJSファイルを入れた）ブランチを用意しました。以下のコマンドでインストール可能です。

```shell-session
$ npm install https://github.com/sizuhiko/web-component-tester.git#use-webserver.hostname-by-selenium-grid-4-npm-install --save-dev
```

`webserver.hostname` でこれまで通り指定できるようになっています。
Linuxシェル -- 巨大な圧縮ファイルから、SQLを実行する方法例

1_前提

いくつかのMySQLからのダンプファイル（圧縮済み）が存在すること。

```
cd /tmp

ls -la

aaa.dump.gz
bbb.dump.gz
ccc.dump.gz
```

2_以下に記述

```shell-session
ls | xargs zcat -f | mysql -uAAAAAA -pXXXXXX --default-character-set=utf8 DB_Name
```
Heroku: worker のプロセスを増やす（並列処理する）には

先に結論です。

並列化は、「Procfile で worker を複数のプロセスとして起動します」

PHP なら以下で、複数プロセス(例では3件）を起動できます。

```
worker: php worker.php | php worker.php | php worker.php
```

分かってみれば、実に単純な設定です…。
Heroku のドキュメントに載せてくれてもいいようなものですが、ありません（見つけられませんでした）…。

このあたりは、サーバ・エンジニアの知識があれば当然のことかも知れませんが…。
Paas を使う開発者にとっては、そのあたり、ドキュメントがないと非常に不利と思いました。

詳しくは長文になるのでブログ（[「Heroku: worker のプロセスを増やす（分散）する方法(for RabbitMQ)」](https://web-atelier-midori.com/blog/rabbitmq/2279/)）を見てください。
RabbitMQ　で行う処理を、1つの Worker で並列処理できないかということで調査した結果になります。
Linuxシェル -- MySQLの各テーブルをダンプファイルから順次戻す例

以下に、記述

```sh
#!/bin/sh

echo "## Start recover."

# variable.
DUMP_DIR="/home/user_abc/dump"
HOST="12.34.56.78"
DATABASE="db_abc"
USERNAME="db_user_abc"
PASS="xxxxxxxx"

SQL_LIST=(
"table_a"
"table_b"
"table_c"
)

for i in ${SQL_LIST[@]}
do
nice -n 19 mysql -h ${HOST} -u ${USERNAME} -p${PASS} ${DATABASE} --default-character-set=utf8 < ${DUMP_DIR}/${i}.sql
done

```
Cognosレポートで職位に応じてデータをマスキング

##概要
LDAP上のユーザー属性である「職位」を元に、特定のデータアイテムをマスキング表示する方法です。
同じレポートを実行しても、マネージャーは各社員の給与が表示され、一般社員だと給与はマスキングされて表示されます。
![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/57430190-07bc-b4bc-e0b1-b9088ba82cc5.png)

##実装方法

**LDAP上での作業**
LDAPでユーザーの職位を設定します。

・一般社員のケース
![002.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/b1da9570-a0ca-4e54-8e70-4d4c592fff0b.png)

・マネージャーのケース
![003.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/b0e1f5cd-ab4a-d433-0c9e-d7f6fed0fca7.png)


**Framework Manager上での作業**
Framework Manager上で給与明細の表を、クエリー・サブジェクトに取り込みます。
![007.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/12fcd9b4-c6d1-e841-ef7f-1daeb00c6813.png)

給与の定義を下記のように設定します。
if(#sq($account.parameters.title)# = 'manager' )
then ( [TESTDB].[CONFSALARY].[SALARY])
else (999999999999)

![008.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/2e028fa7-7131-9674-ecf1-6d543c503055.png)

パッケージを発行します。

**Report Authoringでの作業**
下記のようにクエリーを追加します。
![009.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/36e21cd7-75a7-90c0-5068-8f8df5b6bde1.png)

「ツールボックス」から「データ・アイテム」を追加します。
名前を入力し、「式の定義」で下記のように設定します。
'---'

![010.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/81f5e145-d89d-8d1f-5176-3e9f801fb4c3.png)

リストの列タイトルを選択し、「ラベル」を「給与」に設定します。
![012.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/38580871-a622-5e0a-f9e4-3825d3df256a.png)

給与列を選択し、「条件付きスタイル」を設定します。
![013.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/c44c5a43-8bd9-9bf5-720e-1b1f5c4c1935.png)

以下のように条件を定義し、鉛筆マークで「ボックスのタイプ」を「なし」に設定します。
![016.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/51882543-57b6-5b24-4578-3a16d612e302.png)

次に給与ダミーの列の「条件付きスタイル」を設定します。
![018.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/cc4608e0-ebc8-e035-d60b-9e8d0bb0d89e.png)

下記のように、給与が999999999999の時はそのまま通常表示、残りの値は鉛筆マークで「ボックスのタイプ」を「なし」に設定します。
![019.PNG](https://qiita-image-store.s3.amazonaws.com/0/147246/e68fa90b-b2bf-0381-9904-08db4f5ef342.png)

マネージャーと一般ユーザーでレポートを実行して、動作を確認して下さい。

マスキングという要件が出てきた時に、是非思い出して頂ければ幸いです。
NeDB でドキュメントの暗号化


afterSerialization と beforeDeserialization オプションを追加する。

```javascript
import Datastore from 'nedb'
import crypto from 'crypto'
import path from 'path'

let password = 'hogehoge'

const db = new Datastore({
  // 引数で受け取った文字列を暗号化して返す（改行コード \n は使用禁止）
  afterSerialization: doc => {
    const cipher = crypto.createCipher('aes-256-ctr', password)
    let encrypted = cipher.update(doc, 'utf8', 'hex')
    encrypted += cipher.final('hex')

    return encrypted
  },
  // 復号化した文字列を返す
  beforeDeserialization: encrypted => {
    const decipher = crypto.createDecipher('aes-256-ctr', password)
    let doc = decipher.update(encrypted, 'hex', 'utf8')
    doc += decipher.final('utf8')

    return doc
  },
  filename: path.join(__dirname, 'documents.db')
})
```
【FileMaker】FileMaker 16のcURL+JSONで楽天ブックス検索

[前回](http://qiita.com/tyuma/items/72055b3d4184714a456a)、[前々回](http://qiita.com/tyuma/items/9a130b2689e8337ff976)と2回にわたり、FileMaker 16新機能であるJSONを扱って、単純ですがcURLを使ってJSON形式でデータ取得を行うという動きを見ていきました。

今回は、もう少し実践的（前回のも割と実践的ですが）に、楽天APIを使って、楽天サイトで展開しているデータを取得していくサンプルをご紹介です。
ほんとはAmazon APIにしようかと思ったのですが、楽天APIのページの方がわかりやすかったので、楽天APIにしました。
Amazon APIのページ、なんであんなにたらい回しにされるんですかね。。。＞愚痴です。

楽天API、サービス名は、「[楽天ウェブサービス](https://webservice.rakuten.co.jp/guide/)」と言います。
楽天のウェブサービスで提供しているAPIを使って、楽天の様々な情報を取得できますし、何と言ってもネットショッピング（死語）している人なら大抵アカウントを持っているので、楽天APIを利用する上で必要な申請がスムーズに行えます。

ということで、楽天APIを利用する準備として、
・[アプリ登録](https://webservice.rakuten.co.jp/app/create)
が必要になります。
楽天アカウントが必要になりますので、アカウントを持っていない方は、
アカウント申請→アプリ登録
という順序になります。
さすが楽天、アカウントがない状態でアプリ登録のページに素直に行っても、ちゃんと登録ページに回されます。

※利用規約は、きちんと読んでくださいね。

前回の郵便番号検索APIでは、アプリ登録のような申請はありませんでしたので、ちょっと敷居が高いかもしれませんが、その後のやっていることはほぼ同じです。

以降のテスト実装では、すでにアプリ登録が済んでいることを前提に進めます。

# 楽天ブックスを検索する

## 動きの確認
[https://youtu.be/eYeXJ-z7FGw](https://youtu.be/eYeXJ-z7FGw)

↑のyoutubeで、動きを公開しています。

前回と同じようにURLを指定しますが、パラメータとしてキーワードとアプリIDを付加しています。
<img width="1002" alt="FM16JSON3_0.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/cc385db3-6a71-9f8b-1794-bd8daa8bbe7a.png">

結果は、JSON形式で、retStringに返ってきます。
<img width="996" alt="FM16JSON3_1.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/9736168a-2831-3b4c-aaac-1b735191b016.png">
JSONを分解して、サマリ情報を取得します。
今回の「国立科学博物館」というキーワードで検索すると、4件ヒットしたということがわかります。

では、ヒットした4件を分解して、レコードにセットします。
<img width="1057" alt="FM16JSON3_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/f0932a8e-dc5c-4a4b-9c90-952d382eccb8.png">
新規レコードで、4件出来上がっているのがわかります。
今回は、取得したmediumImageUrlリンクから、画像も出してみました。

動きは、郵便番号検索とほぼ同じです。

## 実装してみる

さて、まずは、フィールド作成です。
検索URLに付加するパラメータと、返ってくるデータ、返ってきたデータの全体情報をグローバルフィールドとして定義しました。
この辺は、利用するシーンによって、また、開発ポリシーによっては実装方法が色々あると思います。
今回はテストなので、簡単に。
<img width="724" alt="FM16JSON4_3.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/d6d1e6c1-962c-c2c2-db6b-1f9731c83c25.png">

検索ボタンへは、楽天APIで指定されたURLを指定します。
<img width="910" alt="FM16JSON4_4.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/1a886b2e-4027-5e13-7498-7b1482aac3b7.png">
利用するAPIによって、パラメータは変わりますが、アプリIDは必ず指定します。

アプリIDの直書きは、悪用を防ぐため、絶対にNGデスヨ！


今回サンプルで利用した楽天ブックス総合検索APIの仕様は、[こちら](https://webservice.rakuten.co.jp/api/bookstotalsearch/)から確認できます。
サンプルでは、必要最低限のオプションしか設定していませんので、ご利用環境に応じてオプションを変更してください。

その他のボタンの動きは、[前回](http://qiita.com/tyuma/items/72055b3d4184714a456a)、[前々回](http://qiita.com/tyuma/items/9a130b2689e8337ff976)と同様です。

レコードにセットするところも同じようにJSONGetElementを利用して分解しています。
以下のスクリプトを参考までにどうぞ。
<img width="1068" alt="FM16JSON4_5.png" src="https://qiita-image-store.s3.amazonaws.com/0/60538/2a9f2506-a6a4-cc92-4ea5-3109be92bd28.png">

楽天APIでは、1回に取得できるデータを30件となっています。
サンプルでは30件未満のヒット数を予め調べてキーワードを入れました。
30件以上のデータが返ってくる場合は、出力パラメータのcount,page,first,endなどの全体情報を見て、再度リクエストを投げることで、次のページを取得することができます。
逆に、前ページ、次ページのようなページ遷移もデータ取得となりますので、レスポンスが遅い環境だったり一度取得したデータは取りに行かないというような場合は、先にFileMakerのレコードへ全部セットしてから画面遷移をするなどの工夫が必要です。
また、エラー処理もそれなりに用意しておかないと、思った動きが期待できないなど詰まることもあるかと思います。
API仕様を読み込んで実装していってくださいね。

では、簡単ですが楽天APIをFileMakerから操作したサンプルのご紹介でした。
ローカルからAWSのLambda関数を編集する

サーバーレスとはいえ、バージョン管理したいので。

直接AWSの画面からインラインで更新すると、履歴が追いにくいので、下記のようなスクリプトを作った。

```bash:deploy-lambda.sh
#!/bin/bash

set -eux

zip -r bundle.zip .

aws lambda update-function-code \
  --function-name arn:aws:lambda:ap-northeast-1:*************:function:*************** \
  --zip-file fileb://bundle.zip

rm bundle.zip

echo ''
echo 'OK.'
```

編集頻度が高ければ、CircleCIとかにやらせるのが吉。
そういえばHTMLはプログラミング言語じゃなかった

先日、SEの友人と話をしていたときの話です。
「そういえば、HTMLでもPerlでも要素って単語自体は出てくるけど意味が違うよね」
みたいな感じの話題に。

空要素という概念を説明するのにも確かに違和感だなーと思ったのですが、
**そういえばHTMLってプログラミング言語じゃなくてマークアップ言語だったんですよね。**

**プログラミング言語**……コンピュータに処理させる指示を書くもの
**マークアップ言語**……文書の構造を記述するもの

要素という単語ひとつであっても、プログラムで処理するための要素と、記述された文書の構造を示す要素であったら話は違ってきます。
HTML単体で見れば、変数や引数もなかったですね。\<script>とかを使うとそれは別の言語を使っているわけで。

そういえば、と気が付いたので残しました。
一般的にHTMLがプログラミング言語と勘違いされるのはきっとパソコンで打った英語の文章が別の形になって出てくるイメージからなのかな、と思いつつ。

確かに自分も全く知らない人へ説明するときはプログラムのようなもんですよとか言ってしまう。それ以外に端的に説明する方法があればいいけど、全く知らなければ全部同じに見えるんだろうなぁ……
Laravel5.7: ビューをレイアウトと個別ビューに分ける

全ページで共通する部分をレイアウトとして抜き出し、それを各ページのビューが継承するようにします。

# 親記事
[Laravel 5.7で基本的なCRUDを作る - Qiita](http://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)


# レイアウトを作る
練習用のレイアウトを作ります。

:link: readouble.com: [Bladeテンプレート](https://readouble.com/laravel/5.7/ja/blade.html)

```php:resources/views/layouts/foo.blade.php
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>@yield('title')</title>
    </head>
    <body>
        <h1>練習用レイアウト</h1>
        {{-- 個別ページの内容はここに挿入される --}}
        @yield('content')
    </body>
</html>
```

# 個別ビューを作る
レイアウトを継承した個別ビューを作ります。

```php:resources/views/foo/foo4.blade.php
@extends('../layouts/foo')
@section('title', $title)
@section('content')
    {{-- 個別ページの内容 --}}
    <h2>{{ $title }}</h2>
    <p>{{ $body }}</p>
@endsection
```

```php:app/Http/Controllers/FooController.php
    // foo4アクションを追加
    public function foo4()
    {
        return view('foo.foo4', [
            'title' => 'Foo4',
            'body' => 'Hello World!'
        ]);
    }
```

```php:routes/web.php
// ルートを追加
Route::get('foo/foo4', 'FooController@foo4');
```

![005.png](https://qiita-image-store.s3.amazonaws.com/0/27816/7066ad76-c3da-c532-682a-42da0738ca7a.png)
Sierra の標準機能でキーリマップする

Technical Note TN2450: Remapping Keys in macOS 10.12 Sierra)
https://developer.apple.com/library/content/technotes/tn2450/

Sierra といえば Karabiner が使えず、キーカスタマイザにとっては鬼門のアップデートでしたが、標準でこんな機能が用意されていました。

要点をまとめると、

- 1 キー対 1 キーの単純なリマップ
- システム終了すると設定がリセットされる （つまり起動時に毎回設定が必要）
- 設定に管理者権限は必要ない
- デバイスごとに設定可能
- PC キーボード固有のキー（変換、無変換など）にも設定可能

といったところです。デバイスごとの設定について上記 Technical Note には何も書かれていませんが、hidutil の仕様により、

```sh
hidutil property --filter '{"ProductID":0x4545,"VendorID":0x4d9,}' --set '...'
```

というような形式で書くことができます。

PC 固有のキーは一覧には載っていませんが、リンクされている pdf には記載されていてちゃんと使えます。


## それ Hammerspoon でやろうぜ

一旦設定を煮詰めてしまえば実行するだけですが、引数は冗長だしキー定義が独自[^1]でかなり書きづらいです。 [Hammerspoon](https://github.com/Hammerspoon/hammerspoon/) を使っているならば実行のタイミングを任せられるし、Lua で組み立てることができるので都合が良いのではないかと configuration を書きました。

foundation_remapping 
https://github.com/hetima/hammerspoon-foundation_remapping

これを利用すれば、init.lua に、

```lua
local FRemap = require('foundation_remapping')
local remapper = FRemap.new({vendorID=0x4d9, productID=0x4545})
remapper:remap('Muhenkan', 0x66):remap('Henkan', 'f18')
remapper:remap('PCKana', 'rcmd')
remapper:remap('lalt', 'lcmd'):remap('lcmd', 'lalt')
remapper:remap('Application', 'escape')
remapper:register()
```
と、簡便に書けます。普段使っている方の keyCode やラベルで設定できます。上記の設定で、

```sh
/usr/bin/hidutil property \
 --filter '{"ProductID":17733,"VendorID":1241,}' \
 --set '{"UserKeyMapping":[ \
 {"HIDKeyboardModifierMappingSrc":30064771211,"HIDKeyboardModifierMappingDst":30064771217}, \
 {"HIDKeyboardModifierMappingSrc":30064771210,"HIDKeyboardModifierMappingDst":30064771181}, \
 {"HIDKeyboardModifierMappingSrc":30064771208,"HIDKeyboardModifierMappingDst":30064771303}, \
 {"HIDKeyboardModifierMappingSrc":30064771298,"HIDKeyboardModifierMappingDst":30064771299}, \
 {"HIDKeyboardModifierMappingSrc":30064771299,"HIDKeyboardModifierMappingDst":30064771298}, \
 {"HIDKeyboardModifierMappingSrc":30064771173,"HIDKeyboardModifierMappingDst":30064771113}, \
 ]}'
```

というコマンドを実行します。

以上、半分は Hammerspoon と自作スクリプトの宣伝でした。



[^1]: [Cosmo_USB2ADB.c](https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-870.50.33/IOHIDFamily/Cosmo_USB2ADB.c) に定義されていました。~~ADB 由来の値でしょうか~~ 普段使ってる方が ADB 由来のようですね
Angular2（TypeScript） で jQuery を使用する方法

# 概要
Angular2 の TypeScript で jQuery を使いたい場合の手順です。
※あまり使うことはないかもしれませんが使いたくなったことがあったので一応メモとして残しておきます。

# 環境
- VSCode 1.12.2
- Angular2 4.0.0 かな。。。
- TypeScript 2.1.0

# 手順
1.jQueryの型定義ファイルをnpmでインストール

```
> npm install --save @types/jquery
```

2.以下のインポート文を追加

```ts
import { Component, Input  } from '@angular/core';
import * as $ from "jquery";
```

3.VSCode で 以下のように入力した際にコード補完されればOK

```ts
$('').~
```

※通常のjQuery と同様に $ が使用できるようになります。

これで jQuery のプラグインなどの資産が使えるのではないかと思います。

説明が抜けていましたがテンプレートの方で以下のように jQuery を参照していないと駄目なので忘れないように！！

```html
  <body>
    <my-app><p>Loading ...</p></my-app>
    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <!-- Include all compiled plugins (below), or include individual files as needed -->
    <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
  </body>
```

私の場合 index.html に bootstrapとjQuery を参照しています。

以上
[MySQL] "Cannot truncate a table referenced in a foreign key constraint" 外部キー制約でtruncate tableできなかった時の対応

あんまりtruncate tableする機会がいままでなかったのですが、mysqlでtruncateしようとしたら、外部キーの制約があるからできませんってエラーが出てきたとき、どうしてもtruncateしたい場合は次の様に外部キーチェックを一度キルトいいようです。

```
mysql> truncate table messages;
ERROR 1701 (42000): Cannot truncate a table referenced in a foreign key constraint (`database_name`.`table_name`, CONSTRAINT `foreign_key_name` FOREIGN KEY (`foreign_key_culumn_name`) REFERENCES `database_name`.`target_table_name` (`id`))
```

```sql
mysql> set foreign_key_checks = 0;
mysql> truncate table table_name;
mysql> set foreign_key_checks = 1;
```
Laravel5.7: 簡単な画面表示を試す

Laravelに慣れるため、簡単な画面表示を作ってみます。

# 親記事
[Laravel 5.7で基本的なCRUDを作る - Qiita](http://qiita.com/sutara79/items/ef30fcdfb7afcb2188ea)


# ルーティングを試す
:link: readouble.com: [ルーティング](https://readouble.com/laravel/5.7/ja/routing.html)
ルートを追加します。

```php:routes/web.php
Route::get('foo', function () {
    return 'Foo!';
});
```

ブラウザで`https://(アプリ名)/foo`にアクセスすると`Foo!`と表示されます。
![001.png](https://qiita-image-store.s3.amazonaws.com/0/27816/4d0e3285-de7b-b132-47f5-c0bb81fed9f4.png)


# コントローラを試す
:link: readouble.com: [コントローラ](https://readouble.com/laravel/5.7/ja/controllers.html)

Artisanコマンドでコントローラを生成します。

```txt:PowerShell
> php artisan make:controller FooController
```

生成したファイルに`foo1`アクションを追加します。

```php:app/Http/Controllers/FooController.php
    public function foo1()
    {
        return 'Foo1!!';
    }
```

ルートを追加します。

```php:routes/web.php
Route::get('foo/foo1', 'FooController@foo1');
```

ブラウザで`https://(アプリ名)/foo/foo1`にアクセスすると`Foo1!!`と表示されます。
![002.png](https://qiita-image-store.s3.amazonaws.com/0/27816/4494fa4d-bcac-2259-0428-46fc60d6d183.png)



# ビューを試す
:link: readouble.com: [ビュー](https://readouble.com/laravel/5.7/ja/views.html)

`resources/views/`に`foo/`を作り、その中に`foo2.blade.php`を作ります。

```php:resources/views/foo/foo2.blade.php
<h1>{{ $title }}</h1>
<p>{{ $body }}</p>
```

コントローラに`foo2`アクションを追加します。

```php:app/Http/Controllers/FooController.php
    public function foo2()
    {
        return view('foo.foo2', [
            'title' => 'Foo2',
            'body' => 'My first Laravel.'
        ]);
    }
```

ルートを追加します。

```php:routes/web.php
Route::get('foo/foo2', 'FooController@foo2');
```
![003.png](https://qiita-image-store.s3.amazonaws.com/0/27816/a8fe9633-3caa-b35a-3215-7d22a8acf425.png)


# DBからデータを取得する
[以前の記事](https://qiita.com/sutara79/items/e19fb386451ab9a4a5fa)で作成したデータベースのusersテーブルから一人の情報を取得します。

Userモデルはデフォルトで`app/User.php`に存在しています。
コントローラで`App\User`をインポートします。
また、`foo3`も追加します。

```diff:app/Http/Controllers/FooController.php
  namespace App\Http\Controllers;
 
  use Illuminate\Http\Request;
+ use App\User;
 
  class FooController extends Controller
  {
+     public function foo3()
+     {
+         $user = User::find(1);
+         return view('foo.foo3', [
+             'user' => $user
+         ]);
+     }
```

:link: readouble.com: [1つのレコードを取得する find() について](https://readouble.com/laravel/5.7/ja/eloquent.html#retrieving-single-models)

ビューを作ります。

```php:resources/views/foo/foo3.blade.php
<ul>
    <li>Name: {{ $user->name }}</li>
    <li>Email: {{ $user['email'] }}</li>
</ul>
<hr>
@php
    var_dump($user);
@endphp
```

:link: readouble.com: [ビュー内で純粋なPHPを実行する @php について](https://readouble.com/laravel/5.7/ja/blade.html#php)

ルートを追加します。

```php:routes/web.php
Route::get('foo/foo3', 'FooController@foo3');
```

ブラウザで`https://(アプリ名)/foo/foo3`にアクセスして、ユーザー名とメールアドレス、そしてユーザー番号1番のオブジェクトの中身が表示されれば成功です。

![004.png](https://qiita-image-store.s3.amazonaws.com/0/27816/43fcc5b9-27ec-fd68-cf99-64ee3de722c5.png)
Angular4 で Google Chart を使う手順

プロジェクトを作成する

```
ng new practice-google-chart && cd $_ 
```

index.html を修正

```html
<script src="https://www.gstatic.com/charts/loader.js"></script>
<script> 
    var googleLoaded = false;
</script>
```

`src/app/component.ts` を修正

```typescript
import { AfterViewInit, Component, ViewChild } from '@angular/core';

declare var google: any;
declare var googleLoaded: any;

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  template: `
    <div style="width:800px;height:400px;">
      <div #myChart></div>
    </div>
  `,
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  @ViewChild('myChart') myChart

  ngAfterViewInit() {
    if(!googleLoaded) {
      googleLoaded = true;
      google.charts.load('current', {'packages':['corechart']})
    }

    google.charts.setOnLoadCallback(drawChart);
    const elm = this.myChart.nativeElement;

    function drawChart() {
      var data = new google.visualization.DataTable();
      data.addColumn('string', 'Topping');
      data.addColumn('number', 'Slices');
      data.addRows([
        ['Mushrooms', 3],
        ['Onions', 1],
        ['Olives', 1],
        ['Zucchini', 1],
        ['Pepperoni', 2]
      ]);
      var options = {'title':'How Much Pizza I Ate Last Night',
                     'width':400,
                     'height':300};
      var chart = new google.visualization.PieChart(elm)
      chart.draw(data, options);
    }
  }
}
```
mysqlのデータをCSVで出力する方法

#欲しいカラムを指定し、csvデータの先頭にカラム名をつける方法

idとpriceカラムの取り出し（例）

```
mysql> select 'id', 'price' union select < col_name >, < col_name > into outfile "test.csv" fields terminated by ',' optionally enclosed by "" from < table_name >;
```

##そのファイルを開く

```
$ open /usr/local/var/mysql/< db_name >/test.csv 
```
phosphorusを使ってみる

# phosphorusってなに？
phosphorusはScratch2.0で作成したプロジェクトをJavaScriptで動かせるようにするサービスです。

## なぜphosphorusを使うのか？
現在Scratch2.0の実行画面は Flash で動いてるため、少々重い処理になってしまいます。
それをJSで動かせるため少しだけ軽くなります。

# 使い方
[phosphorus](https://phosphorus.github.io/)に移動して、![phos_.JPG](https://qiita-image-store.s3.amazonaws.com/0/154299/2e4e254b-ec15-6bdd-f754-70a0f4cc1514.jpeg)にScratchのプロジェクトURLを入力してください。

## 例
[実用例](http://hotapro.blog.fc2.com/blog-entry-22.html)
こんなかんじですね。

# メリットとデメリット
## メリット
- 高速
- 軽い
- 簡単

## デメリット
- ペンが汚い
- クラウド変数の更新ができない
- 共有していないプロジェクトでも見れてしまう（？）
- 一部のハッキングブロックが使えない

# <script></script>でサイトに埋め込む
ページをスクロールしていくと以下の様なものが出てきます。

![](https://qiita-image-store.s3.amazonaws.com/0/154299/bdcaa6ba-7c90-f852-d86c-4f0d3d675588.png)

`<script sr...`という所をコピーして自分のWebサイトのソースに書き込めばOKです。

JavaScriptなのでJSが動く環境じゃないといけません。

# まとめ

やっぱりScratchについてる iframe生成機能のほうがいいのかな・・・
Scratchの重いプロジェクトトを実行したい人におすすめです。
PowerShellのRead-Host  -AsSecureString はバグってる？

#連打！
異なる文字を混ぜて連打すると落ちます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/106424/8806c24e-0b49-a0b2-6cc1-a8457e34859c.png)
#クリップボードから貼り付け
どんな内容でも落ちます。先頭1文字分だけ*が表示されます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/106424/0bd7011b-ef0b-8ef7-0010-2afc58620e5e.png)

**いずれもまともに入力完了できませんでした。w**
iOSアプリで特定のSDKを使わずにOAuth認証をiOSのみで完結させたい場合

アプリの人からSDK無いサービスの場合にOAuthどうしようという相談を受けて解決したのでメモ
問題はwebでのOAuthであればcallbackURLに普通にアクセスできるが、iOSアプリだとサーバーではないので戻りが取れないという事

## 解決手順(雑)

1. 認証画面開くブラウザをsafariではなくweb viewに設定する
2. oauthAPIに対してリクエストを送信する
3. ユーザが特定(Twitter,GitHub)のoauthページでパスワード入力などで認証を行う
4. 本来はここでサービスに登録したcallbackUrlにリダイレクトするがweb view側でリダイレクトを検知した場合、その処理をキャンセルしリダイレクトしようとしたURLを取得する
5. 大抵はcallbackURLの中にcodeやtokenというパラメータが付与されているのでそのコードを使ってaccess_tokenを取得するAPIにリクエストする

もっと良い解決方法があるのかもしれない
web viewじゃなくてアプリ内safariの方法とかあったりするのかどうなのか
SDKが提供されているサービスは素直にそっち使ったほうが良い


### 参考
[iOSアプリにおけるOAuth連携の実装](http://qiita.com/yimajo/items/30c518abd0609c80c741 "iOSアプリにおけるOAuth連携の実装")
Wordnet Affectをプルチックの感情の輪に従って分類するプログラムを書いた

ソースは[Github](https://github.com/RINDO/PlutchikWordnetAffectJP)で公開しています。

### なにを作ったか

Wordnetという概念データベースを元に作られたWordnetAffectという感情にフォーカスしたデータベースを日本語化したものをプルチックの感情の輪で分類するプログラムを作りました。

この成果物を用いることにより、wordnet affectの単語を8つの基本感情 + 25個の複合感情 + 1個の感情(自分で作成した)に分類することが可能になります。

* Wordnetについては[こちら](https://wordnet.princeton.edu/)
* Wordnet Affectについては[こちら](http://wndomains.fbk.eu/wnaffect.html)

##### プルチックの感情の輪

[Robert Plutchik](https://en.wikipedia.org/wiki/Robert_Plutchik)という人が作成した感情の輪というものがあります。
これは、人間の感情は喜び, 信頼, 心配, 驚き, 悲しみ, 嫌悪感, 怒り, 予測の8つから成るというのを提唱したものです。
更に、これらの感情を組み合わせることによって合計33種類の感情が表現できます。 (更に強度などを考慮していくと結構な数になりますね)

![7e52890a.jpg](https://qiita-image-store.s3.amazonaws.com/0/29844/c6c482ab-49ea-bc21-5ad8-2c6491387e99.jpeg)

### 機能

Wordnet Affectには、感情を表すカテゴリがいくつか定義されています。
しかし、今回プルチックの感情の輪に乗っ取って語彙を分類する必要があったので全てのカテゴリを `独断と偏見` で33種類の感情に分類しました。

各感情の名前がついたCSVファイルにカテゴリを追加していくと、Wordnet Affectの語彙が分類されるという簡単なものです。

### これから

まだまだ精度もできてないので、これから進化させていくつもりです！

### 参考

* [Wordnet A lexical database for English](https://wordnet.princeton.edu/)
* [WordNet Domains - Wordnet Affect](http://wndomains.fbk.eu/wnaffect.html)
* [日本語 Wordnet - NICT](http://nlpwww.nict.go.jp/wn-ja/)
* [感情の一覧 - Wikipedia](https://ja.wikipedia.org/wiki/%E6%84%9F%E6%83%85%E3%81%AE%E4%B8%80%E8%A6%A7)
* [Contrasting and categorization of emotions - Wikipedia](https://en.wikipedia.org/wiki/Contrasting_and_categorization_of_emotions)
* [プルチックの感情の輪 - だって君がいないから](http://blog.livedoor.jp/tellstv/archives/22099187.html)
「MediaDevices.getUserMedia() 」について

#はじめに

WebRTCを実装するにあたり、カメラやマイクにアクセスする必要があるので、
```navigator.getUserMedia()```を調査し、メモとして__Qiita__に投稿してみる。

#いざ、本題へ

さっそくGoogle検索をかけてみると、
[MOZILLA DEVELOPER NETWORK(Navigator.getUserMedia)](https://developer.mozilla.org/ja/docs/Web/API/Navigator/getUserMedia)に
たどり着きました。

ん？なにやら様子がおかしい。。。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/dd23a334-2bae-7356-2f60-8d05c2bbefb4.png)

赤枠部分にご注目いただきたい、

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180432/4a76db90-5c24-e0b0-dced-65ae5624a68e.png)

という訳で、```navigator.getUserMedia```はいつの間にかWeb標準から廃止されているみたい。

#新しくなったMediaDevice.getUserMedia()について調べてみる。

##主な変更点

- navigator.getUserMedia()　→　navigator.mediaDevices.getUserMedia()
- ベンダープレフィクスが不要になった
- コールバックではなく```Promiseベース```になった

##実装方法
__[旧 : navigator.getUserMedia()]__

```sample.js
navigator.getUserMedia = navigator.getUserMedia ||
                         navigator.webkitGetUserMedia ||
                         navigator.mozGetUserMedia;

if (navigator.getUserMedia) {
   navigator.getUserMedia({ audio: true, video: { width: 1280, height: 720 } },
      function(stream) {
         var video = document.querySelector('video');
         video.src = window.URL.createObjectURL(stream);
         video.onloadedmetadata = function(e) {
           video.play();
         };
      },
      function(err) {
         console.log("The following error occurred: " + err.name);
      }
   );
} else {
   console.log("getUserMedia not supported");
}
```

__[新 : navigator.MediaDevices.getUserMedia()]__

```sample2.js
navigator.mediaDevices = navigator.mediaDevices || ((navigator.mozGetUserMedia || navigator.webkitGetUserMedia) ? {
   getUserMedia: function(c) {
     return new Promise(function(y, n) {
       (navigator.mozGetUserMedia ||
        navigator.webkitGetUserMedia).call(navigator, c, y, n);
     });
   }
} : null);

if (!navigator.mediaDevices) {
  console.log("getUserMedia() not supported.");
  return;
}

// Prefer camera resolution nearest to 1280x720.

var constraints = { audio: true, video: { width: 1280, height: 720 } };

navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
  var video = document.querySelector('video');
  video.srcObject = stream
  video.onloadedmetadata = function(e) {
    video.play();
  };
})
.catch(function(err) {
  console.log(err.name + ": " + err.message);
});
```

ざっくりとこんな感じ。

navigator.getUserMediaを使うとブラウザに怒られるので、
今後は、```navigator.mediaDevices.getUserMedia()```を使用したいと思います。
ValueAnimatorを使って、TextViewのtextColorをアニメーションさせる方法


# 目的

TextViewのtextColor(文字色)をValueAnimatorでアニメーションさせたい。
例えば、背景色を黒から白にフェードアニメーションさせた時、テキスト色も白から黒にフェードさせるような動きをつけたり、
テキストをゆっくりとした点滅(明滅)させるような動きをつけたい。

# 実装

こんな感じで実装できる。(Activityにある場合)

```java
final TextView textView = findViewById(R.id.textView);
int color1 = ResourcesCompat.getColor(getResources(), R.color.white, getTheme());
int color2 = ResourcesCompat.getColor(getResources(), R.color.black, getTheme());
ValueAnimator animator = new ValueAnimator(); // (1)
animator.setIntValues(color1, color2); // (2)
animator.setEvaluator(new ArgbEvaluator()); // (3)
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator anim) {
		int color = (Integer) anim.getAnimatedValue();
       textView.setTextColor(color);
    }
});

animator.setDuration(300);
animator.start();
```

## 補足

(1) ObjectAnimatorを使うよりもValueAnimatorの方がまとまる
(2) color1, color2は、getColorした値。colorのIDではない。
(3) ArgbEvaluatorをつかうことで、ARGB各値がアニメーションされる。

# アニメーション途中で色を変える場合

トグルのボタンとか、アニメーション中にアニメーションが変わるときはこんな感じ。

```java
private ValueAnimator mAnimator;

void changeColor(int colorId) {
	if (mAnimator != null) {
		mAnimator.cancel() // (4)
	}
	final TextView textView = findViewById(R.id.textView);
	int currentColor = textView.getCurrentTextColor(); // (5)
	int targetColor = ResourcesCompat.getColor(getResources(), colorId, getTheme());
	mAnimator = new ValueAnimator(); 
	mAnimator.setIntValues(currentColor, targetColor);
	mAnimator.setEvaluator(new ArgbEvaluator());
	mAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
	    @Override
	    public void onAnimationUpdate(ValueAnimator anim) {
			int color = (Integer) anim.getAnimatedValue();
	       textView.setTextColor(color);
	    }
	});
	
	mAnimator.setDuration(300);
	mAnimator.start();
}
```

## 補足

(4) 再生中のAnimatorを止める
(5) 今の文字色を取得する

# Lolipop以降

API21以降（Lolipop以降）はコード省略できる。

```java
// Android(API21未満)
ValueAnimator animator = new ValueAnimator();
animator.setIntValues(color1, color2);
animator.setEvaluator(new ArgbEvaluator());
```

```java
// Android(API21以降)
ValueAnimator anim = ValueAnimator.ofArgb(color1, color2)
```

## 参考

https://stackoverflow.com/questions/18216285/android-animate-color-change-from-color-to-color
BIG-IP VE 12.1をVirtualbox上で動かしたい

~~# こっちのほうが楽だった
2018/3/15追記
https://github.com/f5devcentral/f5-vagrant-files
ここにVagrantイメージが置かれていたので、こっちでやるのが楽そうでした...~~
VEではなくて物理機器のOSをVagrantで動かすみたいな感じでした。
そして更新も止まってて上手く動かなかったので削除しました。

# 背景

* [こちら](http://qiita.com/mashumashu/items/f2b6cea0307c8084768b)の記事を参考にしてみたがv12系だとインポートでこけてしまった
	* ストレージ周りがおかしい模様？
* 手元にMacしかねえ！
* VMware Fusion Pro たけえ！
* iControl REST使ったローカル環境作りたいなー


# 環境

* macOS Sierra (10.12.2)
* Virtualbox 5.1.22
* BIGIP-12.1.2.0.0.249.ALL-ide.ova

# 手順

## OVAダウンロード

割愛
環境に書いてあるOVAを拾ってきましょい

## OVA解凍

適当なアーカイバツールで解凍しましょう
(OVAはZIPなようです)

## 中身いじいじ

### `BIGIP-12.1.2.0.0.249-ide.mf` を削除

存在するとインポート時にファイルのハッシュチェックとかをしてくれるようですが、
何故か中身を修正しても怒られてしまうのでそっと削除

### `BIGIP-12.1.2.0.0.249-ide.ovf` を編集

ストレージ周りの設定を以下のような感じにいじる
Address周りをよしなな感じに編集しているだけです。

```
381c381
<         <rasd:Address>1</rasd:Address>
---
>         <rasd:Address>0</rasd:Address>
383c383
<         <rasd:ElementName>ideController1</rasd:ElementName>
---
>         <rasd:ElementName>ideController0</rasd:ElementName>
388c388
<         <rasd:Address>0</rasd:Address>
---
>         <rasd:Address>1</rasd:Address>
390c390
<         <rasd:ElementName>ideController0</rasd:ElementName>
---
>         <rasd:ElementName>ideController1</rasd:ElementName>
399c399
<         <rasd:Parent>4</rasd:Parent>
---
>         <rasd:Parent>3</rasd:Parent>
407c407
<         <rasd:Parent>3</rasd:Parent>
---
>         <rasd:Parent>4</rasd:Parent>
```

## OVAインポート

あとは[こちら](http://qiita.com/mashumashu/items/f2b6cea0307c8084768b)の記事にあるようにVirtualbox側の設定を操作してあげると、
それっぽく動くようになります

おつかれやまでした

# 他

INOPERATIVEになり続けちゃう時は↓のコマンド叩くといい感じになる

`create net vlan EXT interfaces add { 1.1 }`
MacOS Sierra/High SierraにしたらAndroidStudioでビルドができなくなったのを解決


# 問題

MacOS Sierra / High Sierraにしたら、AndroidStudioでこれまでビルドできてたプロジェクト（NDK含む）がビルドできなくなってしまった。

## エラー
```
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
```

## 調査

調べて見たらよくあることのよう。
http://qiita.com/Ys_Jn/items/f7ff03f7a890329c3e2a

## 解決方法

terminalで下記コマンドを実行。xcode-selectをインストールする。
```
xcode-select --install
```
PHP Manual 読書会(3回目)(変数)

PHPに慣れる為に週1ぐらいで更新していきます。PHP Manualを読んで実験して行きます。

前回: [PHP Manual 読書会(2回目)(型)](http://qiita.com/amesho/items/9ba5b8ca8058271acd42)

## 基本的な事

### 無効な変数名を使用しようとした場合。

```php
<?php

$3hoge = 'hoge';
```

```sh
PHP Parse error:  syntax error, unexpected '3' (T_LNUMBER), expecting variable (T_VARIABLE) or '{' or '$'
```

こんな感じでエラーが出ます。
ちなみに、ソース落として確認したところ、scanner周りにT_LNUMBERがあったのでその辺でしょうか。

気になるところは、初期化してない変数の問題が書かれていて、
> 初期化されていない変数のデフォルト値に依存すると、そのファイルを include している別のファイルで同名の変数が使用されていた場合などに 問題を起こします。

これは知らないでいると痛い目を見るところでした。


### 初期化されてない変数を使用した場合

当然エラーになります。こう記述されています。

> 初期化されていない変数を使用すると、 E_NOTICE レベルのエラーが発生します

php意外と初期化しなくてもエラーにならないかと思っていたので確認出来て良かったです

```php
<?php

echo $hoge;
```

```sh
PHP Notice:  Undefined variable: hoge
```

## 定義済みの変数

これは、そんなに多くないので以下のリンク先を確認すればいい。

+ [定義済の変数](http://php.net/manual/ja/reserved.variables.php)


## 変数のスコープ

本日一番驚いたところで、

> スコープの範囲は、 includeやrequireにより読みこまれたファイルも含みます

というところです。
つまり、以下の様になります。

```php
<?php

$hoge = "hoge";

include 'other.inc' // $hogeは、ここのスクリプトの中でも利用が可能
```

関数はスコープになり得るので、基本関数単位で有効範囲を絞った方が良さそうです。


### 静的変数の使用

静的変数の定義が、

> 静的変数はローカル関数スコープのみに 存在しますが、プログラム実行がこのスコープの外で行われるようになっ てもその値を失わないません。

Cのstatic変数と同じ挙動なんですね。


```php
<?php

function hoge()
{
    static $count = 0;
    $count++;
    echo $count . PHP_EOL;
}

hoge();
hoge();
```

結果

```sh
1
2
```

## 可変変数

> 可変変数は、変数の値をとり、変数の名前として扱います

と書かれているので、実際にやるとこうなります。
動的に変数名を変えたい場合とかに便利です。（あまり多用するとまずそうですが）

```php
<?php

$name = 'hoge';
$hoge = 'aaaaa';

echo $hoge . PHP_EOL;

$$name = 'bbbbb';

echo $hoge . PHP_EOL;
```

```sh
aaaaa
bbbbb
```
PHPでPriorityQueueを使ってみる

とあるプログラミングコンテスト（AtCoder）の解説で、
「これはPriorityQueueを使って実装すると解ける」
とあったので、
「そんな便利なモンはPHPにはねーだ」
と思ったんですが、調べてみたら[あった](http://php.net/manual/ja/class.splpriorityqueue.php)。

具体的には、優先度（プライオリティ）を指定したデータをどんどこ追加していくと、勝手に優先度順に並ぶというステキなもの。

ただ、調べてみるとちょっとクセがあって、作ったPriorityQueueの中身を参照していく（先頭からしかできない）と、参照する度にデータとしてはpopして消えていってしまう。
（[ここに詳しい](http://qiita.com/rana_kualu/items/267d818a424d5a508a8a)）

問題は[こんな感じ](http://arc074.contest.atcoder.jp/tasks/arc074_b)で、解答は

```php:
<?php
ini_set('error_reporting', E_ALL & ~E_NOTICE);
 
fscanf(STDIN, "%d", $N);
$a = explode(" ", trim(fgets(STDIN)));
$b = array_reverse($a);
 
$ans = -PHP_INT_MAX;
 
$queue1 = new SplPriorityQueue();
$queue2 = new SplPriorityQueue();
 
$queue1->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
$queue2->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY);
 
for ($i = 0; $i < $N; $i++) {
    $queue1->insert('', PHP_INT_MAX - $a[$i]);
    $totalA += $a[$i];
    $queue2->insert('', $b[$i]);
    $totalB += $b[$i];
}
 
for ($i = $N; $i <= $N * 2; $i++) {
 
    $sumX[$i] = $totalA;
    $sumY[$i] = $totalB;
 
    $queue1->insert('', PHP_INT_MAX - $a[$i]);
    $queue2->insert('', $b[$i]);
 
    $pop1 = PHP_INT_MAX - $queue1->extract();
    $pop2 = $queue2->extract();
 
    $totalA += ($a[$i] - $pop1);
    $totalB += ($b[$i] - $pop2);
}
 
for ($i = $N; $i <= $N * 2; $i++) {
    $tmp = $sumX[$i] - $sumY[$N * 3 - $i];
    $ans = max($ans, $tmp);
}
 
echo $ans . PHP_EOL;
```

優先度つきキューというだけあって、優先度の高いものから降順でデータが整理されるので、昇順として使うためには上記のような工夫（`PHP_INT_MAX - x` として登録・取り出しを行う）が必要になる。

ともあれ、自作のコードではTLEを食らったものが、無事ACしたので良しとしたい。
Let's encrypt How To ２ （運用編）

[前回初期設定](http://qiita.com/vintersnow/items/6a4e9011ed8b9e1b15e0)を行ったが、このままだと面倒なことが多いので改善していく。

# 問題点

+ 証明書の更新を手動でしないといけない
+ 更新時にnginxを止める必要がある

これらを解決していく

# webroot化

前回standaloneを使ったが、これは80番ポートにbindするのでnginxが動いてると実行できない。
そこで、実際ホストしてるルートフォルダを使って認証をするようにしてnginxを止めずに認証出来るようにする。
（最初からwebrootを使って認証した場合このプロセスは不要）

```shell-session
$ sudo letsencrypt certonly --webroot -w /var/www/html -d vintersnow.tk --agree-tos --force-renewal -n
IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at
...
```

`--force-renewal`を使って強制的に更新する。

`--dry-run`を使ってnginxが起動したままでも動くのか確かめる。

```shell-session
$ sudo letsencrypt renew --dry-run --agree-tos
Processing /etc/letsencrypt/renewal/www.example.com.conf
** DRY RUN: simulating 'letsencrypt renew' close to cert expiry
**          (The test certificates below have not been saved.)

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/www.example.com/fullchain.pem (success)
** DRY RUN: simulating 'letsencrypt renew' close to cert expiry
**          (The test certificates above have not been saved.)
...
```

webrootを行うにはlocationのフォルダを指定する必要がある（`/var/www/html`など）
プロキシなどでルートフォルダがない場合、プロキシする前に以下のようにlocationを設定しておくと良い。

```nginx:/etc/nginx/sites-available/default
    location ^~ /.well-known {
       default_type "text/plain";
       root         /var/www/html;
    }
```

## トラブルシューティング

### renewal時に接続できない
ubuntu 14.04, certbot-autoのバージョンは0.14.1

certonlyで--force-renewalは出来るのになぜかrenewコマンドは実行できないという問題。
正直原因がわからないが、以下のようにrenewからweb_pathをコメントアウトしたら直った。

```:/etc/letsencrypt/renewal/www.example.com.conf
# Options used in the renewal process
[renewalparams]
authenticator = webroot
installer = None
account = *******************************
#webroot_path = /var/www/html,
[[webroot_map]]
www.example.com = /var/www/html
```


# 自動更新

毎回手動で更新するのは怖いのでcronで自動に更新するようにしておく。

```bash:cert-renew.sh
#!/bin/sh

LOGFILE=/var/log/update_sslcert.log
COMMAND=letsencrypt
WEBSERVER_RESTART_COMMAND="service nginx restart"

MAILTO=youmail@gmail.com

echo "===== Update SSL Cert =====" >> ${LOGFILE}
echo "`date` Update SSL Cert start" >> ${LOGFILE}

${COMMAND} renew \
  --post-hook "$WEBSERVER_RESTART_COMMAND" \
  --agree-tos \
  --non-interactive >> ${LOGFILE}

if [ "$?" != 0 ]; then
    STATUS='Failed'
else
    STATUS='Successed'
fi

echo "Update SSL Cert $STATUS" >> ${LOGFILE}
echo "Update SSL Cert $STATUS [$(date)]" |\
mail -s "Update SSL Cert in `hostname`" ${MAILTO}

echo "`date` Update SSL Cert end" >> ${LOGFILE}
```

失敗したか、成功したかをメールで送るためにsendmailコマンドが必要。
メールでなくても、slackに通知とかでも良いと思う。

フェイルセーフとして、letsencryptに設定したメールアドレスに期限切れが近いとメールがいくはずである。（試したことないので分からない。）

cronに設定する。

```bash
0 3 1 * * /home/ubuntu/script/cert-renew/cert-renew.sh
```

毎月１日３時に更新するようにした。

# その他

他にすべきこととして、以下が考えられる。（暇な時にでも書く、かも）

+ ハードニング
+ バックアップ
Node.jsのUglifyJSとUglifyJS-Webpack-Pluginを使っているプロジェクトでビルドが通らなくなって難儀した件について

# ビルドに失敗
しばらく触っていなかった、angular+phpなプロジェクトのコードを修正し, いつも通りステージ環境にデプロイしたところ, エラーが発生しデプロイ失敗してしまいました.
ログを調べたところ, 

```
npm run bundle
```

でエラーが発生しているようなので, ローカルの開発環境でbundleを実行してみると,

```
Error: Cannot find module 'uglify-js'
```

というエラーが発生していることが確認される.
そもそも, ```npm install```の時点で

```
npm WARN uglifyjs-webpack-plugin@0.2.2 requires a peer of uglify-js@^2.7.5 but none was installed.
```

というワーニングが発生してしまっているので, やはり`uglify-js`が見つからない様子.

`package.json`の　`uglify-js`について見てみると

```package.json
        "uglify-js": "git://github.com/mishoo/UglifyJS2#harmony", 
        "uglifyjs-webpack-plugin": "^0.2.0", 
```

となっており, 実際にこのリポジトリとブランチは存在し(https://github.com/mishoo/UglifyJS2#harmony), バージョンも3.0.11となので
pluginの要求する要件は見たいしているはず.
謎は深まるばかりであった.

# 意外な事実
設定は問題ないはずなんだけどな～, と思いつつnode_modulesディレクトリをlsしてみると...


```
▶ ll node_modules
合計 416K
drwxr-xr-x 593 vagrant vagrant  20K  5月 23 23:01 .
drwxr-xr-x   4 vagrant vagrant 4.0K  5月 23 23:03 ..
drwxr-xr-x   2 vagrant vagrant 4.0K  5月 23 23:01 .bin
...
...
drwxr-xr-x   5 vagrant vagrant 4.0K  5月 23 23:00 ua-parser-js
drwxr-xr-x   5 vagrant vagrant   87  5月 23 23:00 uglify-es  # <- ???
drwxr-xr-x   3 vagrant vagrant  116  5月 23 23:00 uglify-to-browserify
drwxr-xr-x   4 vagrant vagrant   95  5月 23 23:00 uglifyjs-webpack-plugin
drwxr-xr-x   2 vagrant vagrant  119  5月 23 23:00 uncontrollable
...
...

```

なんということでしょう, 事実`uglify-js`は存在せす, 代わりに`uglify-es`というディレクトリが作られているではないですか！！

ことの経緯を調べてみたところ, 

- もともとuglify-jsはJSのES2015には非対応のライブラリだった.
- そこで, harmonyブランチを作り,　そちらでES2015対応版の開発を進めていた.
- ES2015への対応は完了したということで, v3.0リリースとともに, 名前を`uglify-js`から`uglify-es`に改めた

という話のようです.

開発が進んで機能が充実するのは大変すばらしいことだと思いますが, 公開済みの名前を変えるっていうのはちょっと...

# 対応策
現象は分かったけどどう対応するべきかといろいろ調べてみたところ, stackoverflow(urlは紛失)に

```package.json
        "uglify-js": "git://github.com/mishoo/UglifyJS2#harmony", 
```

を

```package.json
        "uglify-js": "git://github.com/mishoo/UglifyJS2#harmony-v2.8.22", 
```

とすれば, 名前が変わる前のバージョンのものが取得できるという情報が見つかりました.
真似してpackage.jsonを編集し, 無事ライブラリのインストールからbundleまで実行することができました.


おそらく, uglify-webpack-pluginの方がそのうち対応するかとは思うのですが, 
同じ問題にぶつかって悩んでいる方の助けになったら幸いです.
Kotlinの小技

気がついたら、追記していきます。
何か間違っていることなどあれば、コメントをいただけると嬉しいです。

# static field , method（っぽいもの）の定義
```kotlin
class Hoge {
  companion object {
    @JvmField
    val hoge: String = "HOGE"

    @JvmStatic
    fun HogeHoge() { ... }
  }
}
```
companion object の中で変数や関数を定義すれば、Kotlin上でstaticなメンバとして扱える。 
Javaでもstaticなメンバとして扱えるが、Companionオブジェクトを介したアクセスになるらしい。 
`@JvmField`や`@JvmStatic`と言ったアノテーションをつけることで、Companionオブジェクトを介さなくなるみたい。


# Kotlinのコレクション
kotlinのコレクション（List, Set, Map）には、読み取り専用のものと、書き込み可能なものがある。 
List, Set, Mapは読み取り専用、要素の追加等をする場合には、各インターフェースの頭に'Mutable'とついたクラスを使用する。 
また、各インターフェースのインスタンスを作る際には、`~Of()`と言うファクトリ関数を使用する。 
 
```kotlin
  // 読み取り専用
  val list: List<Int> = listOf(1, 2, 3)
  // 書き込みも可能
  val mutableList: MutableList<Int> = mutableListOf(1, 2 ,3)

  // OK
  mutableList.add(4)
  // NG
  // list.add(4)
```
## 読み取り専用 ≠ immutable
Kotlinのmutableではないコレクションは、読み取り専用ではあるが、完全なImmutable（作成後に、状態を変更できないオブジェクト）と言う訳ではないらしい。  

```kotlin
val mutableList = mutableListOf(1, 2, 3)
val list: List<Int> = mutableList // mutableを読み込み専用に代入
mutableList.add(4)

println(list) // 出力 >> [1, 2, 3, 4]
```
`Mutable ~ `系インターフェースは読み込み専用インターフェースも継承しているので、そのインスタンスは`List`等に代入できてしまう。 
結果、後からMutableインターフェース経由で、書き換えられる可能性があるためImmutableではないとのこと。

## Mutable(List, Map, Set) <=> (List, Map, Set)
`to ~ ()`メソッドを使用する  

```kotlin
// MutableList => List
val mutableList: MutableList<Int> = mutableListOf(1, 2, 3)
val list: List<Int> = mutableList.toList()

// List => MutableList
val list: List<Int> = listOf(1, 2, 3)
val mutableList: MutableList<Int> = list.toMutableList()
```

# 複数メソッドをもつインターフェースの実装の仕方
OnClickListenerのように、メソッドを１つしか持たないインターフェースであれば、SAM変換を使うことで簡潔に書くことができるが、 
AdapterViewのOnItemSelectedListenerのような、メソッドを２つ以上持つインターフェースではSAM変換は使えない。
複数メソッドを持つインターフェースは、object式を用いて実装を行う。

```kotlin
// setOnClickListener
button.setOnClickListener {
    // 何らかの処理
}

// OnItemSelectedListener
val listener = object: AdapterView.OnItemSelectedListener {
    override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
        // 何らかの処理
    }

    override fun onNothingSelected(parent: AdapterView<*>?) {
        // 何らかの処理
    }
}

// リスナーの登録
spinner.onItemSelectedListener = listener
```
これで実装はできるが、Javaっぽいコードになるのが欠点。
何かいい設計はないものか...

# if else をスコープ関数で実装

#### 通常
```kotlin
if (hoge) {
  // true action
} else {
  // false action
}
```

#### スコープ関数
```kotlin
hoge?.let {
  // true action
} ?: run {
  // false action
}
```

# スコープ関数使い方

## apply, also, let, run
他に良い記事があるので省略

# takeIf
- 渡したラムダの中では、レシーバはthisで呼び出せる
- ラムダの返り値はBoolean
- 返り値がtrueであればレシーバを返し、falseであればnullを返す

```
val hoge: String = hoge

hoge.takeIf {
  hoge == "hoge"
}?.let {
  print("hoge is hoge")
} ?: run {
  print("hoge is not hoge")
}
```

バリデーション処理に使えそう

## takeUnless
takeIfとほとんど同じ
返り値の判定が逆になり、falseであればレシーバを返し、trueであればnullを返す

```
val hoge: String = hoge

hoge.takeUnless {
  hoge == "hoge"
}?.let {
  print("hoge is not hoge")
} ?: run {
  print("hoge is hoge")
}
```
Thinkpad X240 メモリ交換

4GB -> 8GB にグレードアップ。

低電圧版を買えば良いらしい。

Transcend ノートPC用メモリ PC3L-12800 DDR3L 1600 8GB 1.35V (低電圧) - 1.5V 両対応 204pin SO-DIMM (無期限保証) TS1GSK64W6H

https://www.amazon.co.jp/gp/product/B008JIVN3I/ref=oh_aui_detailpage_o02_s00?ie=UTF8&psc=1
zsh | カレントパスをターミナルの右側に表示する ( RPROMPT="%~" )

`$RPROMPT` を設定すれば良い。
( Rはたぶん「右」っていう意味 )

```:~/.zshrc
RPROMPT="%~"
```

```
$ source ~/.zshrc
```

# 結果

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/eea4cb3b-c997-c45f-bd0c-324ea12d4b6d.png)

# 環境

- zsh 5.3.1 (x86_64-apple-darwin16.3.0)








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
YAMAHA RTX1100逆引きメモ

必要に迫られたYAMAHA RTX1100関連の逆引きメモになります。

# 時刻確認

```
show environment
```

※機器設定表示に表示される。

# 静的DNSの設定

## ホストの設定

```
ip host local.example.jp 192.168.0.1
```
## DNSキャッシュのクリア

```
clear dns cache
```

# 外部端末(アドレス不定)からVPN接続

## 手順

1. ネットボランチの設定
2. L2TP/IPSecの設定
3. 外部からの接続確認

## 躓いたポイント

### Windowns10でVPN接続出来ない。

Windowns10の端末で接続設定しても`ユーザーおよびパスワード認証の際にリモートコンピューターにより接続が拒否されました`とメッセージが出て接続出来ない状態に。
コントロールパネルからVPNの接続プロパティを開いて`チャレンジハンドシェイク認証プロトコル`のチェックを入れると接続に成功。

### 外部からのVPNの接続は出来るがルータの向こう側に有る端末にpingが通らない。

症状としてはルータにはpingが通るけど、その先に有る端末に届かなかった、
ネットで調べると`Proxy ARP`の設定が漏れているらしかったので`ip lan1 proxyarp on`を設定。

## 参考

[YAMAHA RTX1100 ネットボランチDNS](http://horie.net/rtx/1100-20.php)
[複数のL2TPクライアント(アドレス不定)の接続を受け付ける場合](http://www.rtpro.yamaha.co.jp/RT/docs/l2tp_ipsec/#setting2)
[Windows10でVPNに接続できなくなったときの備忘録 - 情報技術で日々を楽しく！](http://knkryo.blogspot.jp/2016/09/windows10vpn.html)
[VPN接続しようと思った - 日々量産](http://d.hatena.ne.jp/ryousanngata/20121126/1353915696)
自己署名証明書の生成方法

## 概要

今やLetsEncryptもあるのであまり必要なくなりましたが、自己署名の証明書(オレオレ証明書)を作ろうと思うといつもopensslのコマンドが分からずネットで検索していたので備忘録として残します。

CA無しのパターンとCAも生成するパターンで、CA無しはワンライナーで書きました。
普段はCA無しでも「秘密鍵」を作って、「CSR」を作って、「証明書」を作るという3段階だったんですが、よくよくコマンドを見るとそれを一括でやれるようになってることを知ったので、ワンライナーにしてみました。

## CA無しの自己署名証明書(ワンライナー)

```bash
$ openssl req -nodes -newkey rsa:2048 -keyout privkey.pem -x509 -sha256 -days 1 -out chain.pem -subj "/C=JP/ST=Tokyo/L=Shinjuku-ku/O=EXAMPLE CORPORATION/OU=EXAMPLE DEPARTMENT/CN=`curl ifconfig.co`"
```

1. `openssl` の `req` コマンドを使います
    * 秘密鍵と証明書を一度に生成します
    * 使いまわすわけではないので、証明書が出来てしまえばCSRは不要なので生成しません
1. `-nodes` は `node` の複数形ではなく、 `no DES` = **秘密鍵を暗号化しない** です
1. `-newkey rsa:2048` で `RSA` で `2048bit` の秘密鍵を生成を指定します
1. `-keyout privkey.pem` で生成した秘密鍵の保存先の指定します
1. `-x509` で証明書の生成を示す
    * `req` コマンドはデフォルトだと `CSR` 生成
1. `-sha256` で `SHA256` の証明書が生成されます
    * デフォルトだと `SHA1` なので気をつけてください
1. `-days 1` で有効日数を指定する
    * 0日や1日未満での指定はできないけど `-days -1` とすれば遡った指定もできる(必要性はないだろうけど)
1. `-out chain.pem` で生成した証明書の保存先を指定します
1. `-subj "/C=.../ST=.../L=.../O=.../OU=.../CN=..."` はCSRを生成する場合に指定するのと同じで証明書の情報です

## CA有りの自己署名証明書

```bash
$ # (2017/05/25 更新)

$ #echo -n "00" > /etc/pki/CA/serial # 要らなくなりました
$ #echo -n "" > /etc/pki/CA/index.txt # 要らなくなりました

$ # オレオレ中間CAの生成
$ openssl req -x509 -sha256 -days 3650 -subj "/C=JP/ST=Tokyo/L=Shinjuku-ku/O=EXAMPLE CORPORATION/OU=EXAMPLE DEPARTMENT/CN=My Private CA" -nodes -newkey rsa:2048 -keyout cakey.pem -out chain.pem

$ # 自身のIPに対するCSRと秘密鍵の生成
$ openssl req -subj "/C=JP/ST=Tokyo/L=Shinjuku-ku/O=EXAMPLE CORPORATION/OU=EXAMPLE DEPARTMENT/CN=`curl ifconfig.co`" -nodes -newkey rsa:2048 -keyout privkey.pem -out csr.pem

$ # オレオレ認証局による証明書の生成
$ openssl x509 -req -sha256 -days 3650 -in csr.pem -CA chain.pem -CAkey cakey.pem -set_serial 1 -out fullchain.pem
```

~~本来、初めの2つのコマンドは最初に一度だけ実行するもので、証明書を生成する度にこれらのファイルの内容が更新されていきます。
ただ `ansible` に組み込むときはそれが地味に面倒なので、毎回初期化しちゃえばいいと思います。
それで困ることってほとんど無いかなって思ってますがどうなんでしょうか..?~~
→ オプションでシリアルNo指定する方法(`-set_serial 1`)があったので2つのコマンドはコメントアウトしました(2017/05/25)

~~あと今回はCAと証明書でCSRを使いまわしてるからこういうコマンドになってますが、普通はCAと証明書は違うCSRだと思います~~
→ CSR使いまわさないで作るように修正しました(2017/05/25)