OmniAICreator/Qiita-1.07M huggingface dataset:
よし, じゃあVagrantで作った環境にnginxをぶちこんでやるぜ!

季節外れのAdventCalendar2日目はいよーいスタート
前に勉強がてらに試しにやってみたやつの備忘録

## 目次
* Vagrantの導入
* CentOS7の作成
* CentOSの設定
* ポートフォワードの設定



#1. Vagrantの導入
[公式ページ様](https://www.vagrantup.com/)からダウンロードしインストールします.

なにも難しくない

バージョンの確認

```
-> % vagrant -v
Vagrant 2.1.2
```

#2. CentOS7の作成
今回は, CentOSでやります.

仮想マシン用のディレクトリを適当に作成し移動します.

仮想マシンの初期化

```
-> % vagrant init centos/7
```

設定ファイルのVagrantfileができてるはずです.

起動する. 

```
-> % vagrant up
```
初回は, Boxのダウンロードがあるので時間がかかります.

状態確認

```
-> % vagrant status
Current machine states:

default                   running (virtualbox)

The VM is running. To stop this VM, you can run `vagrant halt` to
shut it down forcefully, or you can run `vagrant suspend` to simply
suspend the virtual machine. In either case, to restart it again,
simply run `vagrant up`.
```
runningとでていれば正常に起動しています.

Vagrantfileのconfig.vm.network~のコメントアウトを外す

```
# Create a private network, which allows host-only access to the machine
  # using a specific IP.
   config.vm.network "private_network", ip: "192.168.33.10"
```

ssh-config内のホストを書き換えます.


```
-> % vagrant ssh-config --host 192.168.33.10
Host 192.168.33.10
```

これでssh接続できるようになります.

```
-> % ssh vagrant@192.168.33.10
```

# 3. CentOSの設定
これを参考に設定
https://qiita.com/ktkiyoshi/items/bf920b4df02d98b570e3

nginxは, 最新のやつが入らなかったので以下の方法で

/etc/yum.repos.d/nginx.repoに以下の設定を追加

```
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
```

インストール

```
$ sudo yum -y --enablerepo=nginx install nginx
```


# 4. ポートフォワードの設定
そのままだと外部から繋がらないのでVagrantfileのポートフォワードの設定をする.

```
# NOTE: This will enable public access to the opened port
   config.vm.network "forwarded_port", guest: 80, host: 10022
```
これでlocalhost:10022でマシン側につながるはずです.
【React】react-quillを使った空行が反映されない

6月からreactを用いたサービスを運営する会社にてインターンを始めたので、ログを残しておきます。

# react-quillを使った空行が反映されない
react-quillを使って、htmlをデータベースに保存していたが空行が反映されないので原因を究明してみた。

1. 考えた経緯
2. 原因を模索
3. 解決方法



## 1.考えた経緯
以下のように思考した。

### 一旦chromeの検証ツールで見てみる

【正常な箇所】

```html:sample.html
<p><br></p>
```

【異常な箇所】

```html:sample.html
<p><span style="color: rgb(0, 0, 0); background-color: transparent;"></span></p>
```

## 原因を模索
考えられる原因を色々と試してみる。

- react-quillのバグ
- 保存する際に何かが原因で空行が変換されている。
- その他違う原因

### react-quillのバグ

 react-quill blank lineで検索
-> それらしい記事は見当たらない

### 保存する際に何かが原因で空行が変換されている。
-> 実際の症状を再現しようと試みるも、データベースには正常に保存されているため症状の再現が不可能。

### 一旦実際の症状を再現しようと色々と試みる
-> 原因がわかった


## 原因
空行を入れる際に空行の先頭にスペースを入れると

``` html
<p><span style="color: rgb(0, 0, 0); background-color: transparent;"></span></p>
```

このようになって保存されてしまうため。
スペースの分が認識されずにspanタグが入れられてしまうため保存する際の見た目では、空行が入るが出力すると空行が入らない。

結局不具合が多いので、
[Draft.js](https://draftjs.org/)
を用いることになりました。
【Drupal8】phpunitテストでデータベースやモジュールを使いたい

Drupalで作っているシステム、自作モジュールのユニットテストを書いておこうと思ってやりだしたら思いの外手こずったのでコツをメモ書き。

## 継承する元クラスによってできることと速さとが違う
参考 : https://www.drupal.org/docs/8/testing/types-of-tests-in-drupal-8

Drupal8が用意しているテストには大きく分けて三種類あるらしい。
* ユニットテスト
* カーネルテスト
* ブラウザテスト

これらはphpunitモジュールを使う。
phpunitモジュールの他にもシンプルテストというのが検索すると出てくるが、これはどうも古いやり方らしく「もう使わないでね！phpunit使ってね！」というドキュメントに行き着くので調べてない。

今回はユニットテストとカーネルテストを書いたのでこのふたつについてわかったことを。

## ユニットテスト
* Drupal\Tests\UnitTestCase を継承して作る。
* そのモジュール内で完全に完結する処理のテストに使う。
* Drupal処理で普通に使えるサービスやモジュール（データベースやコンフィグ）が使えない。
* 動作がすごく早い。

## カーネルテスト
* Drupal\KernelTests\Core\Entity\EntityKernelTestBase を継承して作る
    * Drupal\KernelTests\KernelTestBase を継承してもいいらしい。両者の違いはまだよくわからない。
* データベースが使える
* 単体テストに比べて動作が遅い。
* モジュールのインストールもできる。nodeなんかはモジュールをインストールしないと使えない。
* 参考 : https://drupal.stackexchange.com/questions/230306/what-to-set-up-in-a-kernel-test-to-get-custom-content-type-to-be-available

```
<?php

namespace Drupal\Tests\my_custom_module\Kernel;

use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
use Drupal\node\Entity\Node;

class MyXxxxTest extends EntityKernelTestBase {

  /**
   * Modules to install.
   *
   * @var array
   */
  public static $modules = ['my_custom_module', 'node', ];

  /**
   * {@inheritdoc}
   */
  protected function setUp() {
    parent::setUp();
    $this->installConfig(['my_custom_module', 'node', ]);
  }

  …
```

## SQLを書く際の注意点
* カーネルテストでは、テストごとにトークン文字列がサフィックスとして付いたテーブルが生成されてそこでテストが実行されるらしい。
* 自作処理内でデータベースを扱う箇所で、SQLクエリを直接書いてる箇所があったら書き方によってはテストとうまく連動しないので注意する。
  * SQLクエリにテーブル名を記述する際、「 {table_name} 」というふうに{}で囲む。こうするとテスト時に動的にそのテスト用のテーブル名に置き換えてくれるようだ。
E2Eテストについて調べてたら訳が分からなくなった話

# 言いたいこと
掲題の通りです。

## 対象読者
- E2Eテストは重要だと思う
- きっちりやったことはない
- seleniumって単語は知ってる


## E2Eテストとは
まずE2Eテストについて簡単に説明します。

E2E(End to End)テストとは、ユーザーの視点から実際にwebブラウザを通して一通りの処理をテストすることをさします。
（Example...フォームにuser名とpasswordを入力してログインボタンを押すとログイン画面が出る）
重要ですね。
とはいえ、何かリリースがあるたびに、あるいは30分に一回など、人間が全機能を手で試すなんてとてもじゃないですがやってられません。
そこでE2Eテストも自動化の波にさらわれている訳です。

## 前置き
E2Eテストの自動化が大切なのはわかったけどどうやってやるの？って話ですね。
ここでおそらくSeleniumという単語が検索に引っかかりまくります。
ふむふむなるほどSeleniumというのを使えばwebブラウザをソースコードで操作できるのですね。便利です。
ではSelenium以外に手段はないのか？と調べた結果、私は掲題の状態になりました。
ならなかったプログラミングできるマンである諸兄はここまでお付き合いいただきありがとうございました。

## よく見る名前
おそらくこのような名前が検索で引っかかります。
- Selenium
- Nightwatch.js
- puppeteer
- WebdriverIO
- Nightmare
- WebDriver
- etc...

本記事ではこれらがどういった関係性なのかを紹介し、未来ある子羊たちが自分と同じ道をたどることのないようにしていきたいと思います。


## 本題
そもそも私がなぜよくわからくなったかというと、Nightwatch.jsのサイトで説明を見ていると、こんな記述があったためです。

```
Selenium Server Setup
```

つまり、Nightwatch.jsを利用するにはSeleniumが必要と。
なんでやねん。
なぜこれに疑問を覚えたかというと、私は上であげたようなツール群を全て並列な存在に捉えていたためです。
つまり、Seleniumの代わりにNightwatch.jsが使えるという理解だったのです。

実際には

```
Nightwatch.js puppeteer WebdriverIO Nightmare などなど
↓                         ↓
Selenium WebDriver など　　 　　 ↓
↓　　　　　　　　　　　　　　　　　　　　　　　　             ↓
Chrome FireFox Electron Chromium （実際の操作対象になるブラウザ） などなど
```

という流れなのですね。
つまりNightwatch.jsやWebdriverIOはSeleniumをより使いやすくしてくれているwrapperのようなライブラリだったという訳です。

## あとがき
厳密にはSeleniumとWebDriverは別物ののようです（W3Cがどうとかかんとか）
ともあれここがわかればあとは調べてなんとかなるかと思われます。
世間の波に乗りたいので頑張って調べます。
RaspberryPi+NOOBS+python3セットアップ

個人メモ

## Download NOOBS for Raspberry Pi

[Download NOOBS for Raspberry Pi](https://www.raspberrypi.org/downloads/noobs/)

## インストール

- キーボードはUS配列設定
- 日本時間
- 日本語設定

## アップデート

```
sudo apt-get update
```

## python3

python3はすでに入っている。

```
sudo apt-get install python3-pip
```


## pythonライブラリ

- scikit-learn

```
sudo apt get install python-sklearn
```

- numpy

入ってた

-  pyaudio

[PyAudio: PortAudio v19 Python Bindings](https://people.csail.mit.edu/hubert/pyaudio/)

```
sudo apt-get install python-pyaudio python3-pyaudio
```


- Matplotlib


[Matplotlib: Python plotting — Matplotlib 2\.2\.3 documentation](https://matplotlib.org/)

```
sudo pip3 install matplotlib
```

また増やすかも
async/await で複数の非同期処理を待つときに注意したいこと

本投稿のサンプルコードを GitHub に用意しました。
[im36-123/multiple_await | GitHub](https://github.com/im36-123/multiple_await/tree/master)

# 概要
async/await を使うとで非同期処理を同期処理のように記述できますが、複数の非同期処理を待つときに気をつけたいことを紹介します。
複数のリクエスト送信して、それらのレスポンスからページを構成するときなどに役立つかもしれません。

今回は `Fetch API` を使って複数のリクエストを送信する場合を考えてみます。

# 普通に async/await を使う
まずは、ひとつだけリクエストを送信する場合を考えてみます。

```js:ひとつだけリクエストを送信する
function get(url) {
  return fetch(url);
}

async function fn() {
  const res = await get(`https://hoge/api`);
  console.log(res);
}

fn();
```

`fn()` が実行されると、 `https://hoge/api` へリクエストを送信します。
レスポンスがあるまで、 `fn()` 内の処理は停止します。
特に問題ありませんね。

次は本題の複数のリクエストを待つ場合を見てみましょう

# 複数のリクエストを待つ
それでは2つ以上のリクエストを送信するときを考えてみます。

## 良くない書き方
先程のコードのリクエストを送信する部分を2つにしました（実際は for文などで loop させるかと思います。）。

```js:良くないawait
function get(url) {
  return fetch(url);
}

async function fn() {
  const res1 = await get(`https://hoge/api`);
  const res2 = await get(`https://fuga/api`);
  console.log(res1);
  console.log(res2);
}

fn();
```

こちらのコードは問題なく動作しますが、パフォーマンスが落ちてしまいます。
というのも、`res1` に結果が代入されるまで `fn()` 内の処理が止まってしまうためです。

developer tool の Network タブを見てみると、確かに1つ目のリクエスト結果の後に、2つ目のリクエストが送信されています。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280341/ebe84af4-0a4b-0b8d-2f7d-26c1fd5abb8f.png)
(※ 上図では Qiita の api にリクエストを送信しています。)
## 良い書き方
`res1` の結果が `res2` のリクエストに影響しない場合は、次のように複数のリクエストが並列して処理されるようにします。

先程のコードを修正して、2つのリクエストが並列して処理されるようにしました。
また、 `Promise.all` を使ってすべてのリクエスト結果の返却を待ちましょう。

```js:良いawait
function get(url) {
  return fetch(url);
}

async function fn() {
  const results = [];
  const urls = ['https://hoge/api', 'https://fuga/api'];
  for (const url of urls) {
    results.push(get(url));
  }
  console.log(await Promise.all(results));
}

fn();
```
こちらも developer tool の Network タブから確認してみましょう。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/280341/7d0c5420-a423-88b5-02c4-b9bbc5b70daf.png)

今回は、2つのリクエストが並行して処理されているのがわかります。


# まとめ
業務で async/await を使っているときに ESLint に注意されたので書きました。

# 追記
@41semicolon さんよりコメントをいただきました…！！
`fn()` に関してですがコメントで頂いた下記のコードの方がスマートで素敵です。

```js
async function fn() {
  const urls = ['https://hoge/api', 'https://fuga/api'];
  console.log(await Promise.all(urls.map(get)));
}
```

呼び出し側で await するなどのときはこちら。

```js
fn = (urls) => Promise.all(urls.map(get))
```
詳しくはコメントを参照お願いします。
# 参考
[no-await-in-loop - Rules - ESLint - Pluggable JavaScript linter](https://eslint.org/docs/rules/no-await-in-loop)
[async function - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)
[await - JavaScript | MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/await)
よく迷子になるから人工衛星"みちびき"を使って現在地を簡単に取得してみた①

#はじめに
みなさんIoTライフ楽しんでますか？
RHEMS技研荒木です

今回は**一家に一台必要と言われているArduino**と、誰でも活用できる**人工衛星みちびき**を使って現在地を取得し、自分がどこを何時に通過したかを確認できるようにします

**夢がありますね！！**

１回目となる今回は、Arduino・GY-NEO6MVの接続方法、使用方法を説明します

#使用した機器

・Arduino UNO
・ESP-WROOM-02 開発ボード
・GY-NEO6MV2(みちびきと交信するやつ)

おおよそはこれだけです!



#せつめい

GY-NEO6MV2の説明をします

電源を入力して、GNDにつなぐだけ
これだけでみちびきと交信して現在地とUTC(協定世界時)が取得できます

あとはTX・RXを所定のピンに指すだけでArduinoで現在地等を確認できます

接続するとこんなかんじ

![IMG_1671.jpg](https://qiita-image-store.s3.amazonaws.com/0/269207/676820d6-d647-eb3f-b640-1349f4b573fd.jpeg)

簡単ですね！


確認するコードはこちら

```
#include <SoftwareSerial.h>

SoftwareSerial serialConsole(10, 11); // RX=10ピン, TX=11ピン

//電源入力時に一度だけ読まれる部分
void setup() {
  //シリアルコンソールを準備
  Serial.begin(57600);
  while (!Serial) {
    ;
  }
  Serial.println("GPS Console　Complete!");

  serialConsole.begin(9600);
  serialConsole.println("Hello World!");
}

//メイン部分
void loop() {
  //なんらかの値が読み取れればそれを読む
  if (serialConsole.available()) {
    Serial.write(serialConsole.read());
  }
  //読み込んだのをシリアルコンソールに表示する
  if (Serial.available()) {
    serialConsole.write(Serial.read());
  }
}
```

簡単なコードなっています
そして取得できたデータがこちら
![IMG_12814AB15411-1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/269207/67db8abe-296c-b518-51b0-76041278b0ff.jpeg)

モザイクがかかっていますが、読もうと思って読めるものではないとわかりますね
気合を入れると読んで理解できるのですが、そんなことしたくないのでArduinoにライブラリを用意します

今回導入するライブラリは[TinyGPS++](http://arduiniana.org/libraries/tinygpsplus/)です
導入方法は他のライブラリと同じです
これを使うことによって難なく読むことができるようになります

みちびきから送られてきたデータを読むコードはこちら

```
#include <TinyGPS++.h>
#include <SoftwareSerial.h>

SoftwareSerial serialConsole(10, 11); //RX=10ピン, TX=11ピン
TinyGPSPlus gps;

void setup() {
  Serial.begin(57600);
  while (!Serial) {
    ;
  }
  Serial.println("GPS Console　Complete!");

  serialConsole.begin(9600);
  serialConsole.println("Hello World!");
}

void loop(){
  while (serialConsole.available())
  {
    //入力されたデータを読めるように翻訳する
    gps.encode(serialConsole.read());
  }
  if (gps.location.isUpdated())
  {
    //緯度を表示
    Serial.print("LAT:");  Serial.println(gps.location.lat(), 6);

    //経度を表示
    Serial.print("LNG:"); Serial.println(gps.location.lng(), 6);

    //時間を表示(UTCで取得されるので+9時間して日本の時間に)
    Serial.print("HOUR:");  Serial.println(gps.time.hour() + 9);

    //分を表示
    Serial.print("MINUTS:");  Serial.println(gps.time.minute());

    //秒を表示
    Serial.print("SECOND:");  Serial.println(gps.time.second());

    Serial.println("");
  }
}
```

取得→翻訳したものがこちら

![IMG_FBCF62B9669A-1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/269207/9f4a174a-12af-c654-3386-37d672b27fb0.jpeg)


これで読めるようになりましたね
現時刻もしっかり取得できています


#おわりに

いかがでしたでしょうか
たった4ピン指すだけで簡単に現在地を取得できる日が来るなんて思ってもいなかったですよね？
ですが、緯度・経度が座標で取得されているのでパッと見だとどこにいるかわからないですね
なので次回は取得したデータをAPIに投げ、次次回そのデータをなんらかのMapにプロットします
~~現在誠意開発中なので更新が遅れると思われますがあしからず~~
②公開しました！ぜひご覧ください！
[https://qiita.com/Akijin/items/00aa775ff6f1a9931f1d](https://qiita.com/Akijin/items/00aa775ff6f1a9931f1d)

ではよきIoTライフを！！
英語版のUbuntu18.04にて日本語入力できるようにする。

#Mozcのインストール

```
#インストール
$sudo apt-get install ibus-mozc

#ibusの再起動
$killall ibus-daemon
$ibus-daemon -d -x &
```

#入力設定
Settings > Region & Language > Input Sources に『Japanese(Mozc)』を追加し、先頭に移動する。

Super + Space キーを押すと『Japanese』と『Japanese(Mozc)』がスイッチすることを確認できる。
『Japanese(Mozc)』の状態で、半角/全角 キーを押すと日本語入力できる。
sessionの記述があるコードをHerokuにデプロイする際の留意点

###Herokuにデプロイした際にエラー

```
We're sorry, but something went wrong.
If you are the application owner check the logs for more information.
```

そもそもアプリが表示されないエラーに対する解決コードは[【Rails5】ローカルでは動くが、Herokuで動かない。](https://teratail.com/questions/84556)より

```
heroku pg:reset DATABASE
heroku run rake db:migrate
```
を打つことで解決。

###特定のページを開くとエラー

```
The page you were looking for doesn't exist.
You may have mistyped the address or the page may have moved.
```
セッション情報が既に存在し、それに対応するデータベースが存在している段階では問題なく動いていたものの、コードの記述変更やsession情報が空であった際の処理などを記述した後で

```
git push heroku master
```
を実行した際に接するエラーがこれ。
Heroku公式サイト open app右のバーより、logsを確認すると
dbをリセットしてmigrateした為にデータベースが存在しないにも関わらず

```
session[:id]に対応するデータベースカラムが見つかりません！
```
というエラーを吐いていることが確認できる。

###ローカル環境で再現
herokuで問題が起きている原因はデータベースがないにも関わらず、それを参照しているsessionが引っかかっていることによって起きているので、ローカル環境でもデーターベースをリセットする。
すると、全く同じエラーが発生していることに気がつく。
sessionが存在しない情報を保持していることが問題なので

```erb
<% session[:任意] = nil %>
```
をエラーを吐くページ及び、session情報を送信するページに記述することでsession情報を空にする。
すると問題なく、データベースが存在しない際に、データは空ですと記述を加えたページがエラーなく表示されるようになる。

###なぜエラーが起きたのか
上記に書いた通り、一連のエラーは全てsessionが原因である。
「sessionは一時的にCookieのように働く仕組み〜・・」的な曖昧な知見で利用すると、発生したエラーを特定するまでにしばらくかかりました・・。
パスもコードも正しく記述出来ている筈なのに、なぜ表示されないのだろうとググって拾ったコードを試してみても解決されない場合は、まずlogsを確認して問題点を見つけるのが大事だと学びました。
ASP.NETで特定のリクエストに動的にHTTPヘッダを設定する方法

#概要
　全てのリクエストに対してHeaderを追加する場合は、Web.configに\<customHeaders\>を追加すれば済みます(下記)。しかし、リクエストに応じてヘッダを設定したい場合は使えないです。

```xml:Web.config
<configuration>
 <system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>
</configuration>
```
　Viewを返すControllerでHeaderを追加すれば済む話ではありますが、いちいち追加するのはあまり綺麗でない上に静的に配信するファイルに対しては有効でないです。
　今回は、Moduleを用いてリクエスト毎に実行されるイベントを作成することで用いて実現します。
#Moduleとは
　Moduleを使用すると、各要求の途中段階で処理を割り込ませることが可能です。これにより、要求に対して特定の動作をすることが可能です。
#ソースコード
```c#
using System;
using System.Web;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace App.Modules
{
    public class HTTPHeaderModule : IHttpModule
    {
        public void Init(HttpApplication context)
        {
            context.PreSendRequestHeaders += AddHeaderFromURL;
        }

        /// <summary>
        /// HeaderをURLに応じて追加する
        /// </summary>
        private void AddHeaderFromURL(object sender, EventArgs e)
        {
            HttpRequest request = (HttpRequest)sender.GetType().GetProperty("Request").GetValue(sender);
            HttpResponse responce = (HttpResponse)sender.GetType().GetProperty("Response").GetValue(sender);
            //リクエストのURL
            var url = request.Url;
            //リクエストの絶対パスの先頭が/apiだったら            
            if (Regex.IsMatch(url.AbsolutePath, "^/api", RegexOptions.IgnoreCase))
            {
                if (request.Headers.AllKeys.Contains("Origin"))
                {
                    //リクエスト元(オリジン)のURL
                    Uri hostUrl = new Uri(request.Headers["Origin"]);
                    if (IsAllowedHost(hostUrl.Host))
                    {
                        //リクエストのオリジンを許可
                        responce.Headers.Add("Access-Control-Allow-Origin", hostUrl.GetLeftPart(UriPartial.Authority));
                    }
                }
            }
        }

        public void Dispose(){}

        private bool IsAllowedHost(string host)
        {
            return Regex.IsMatch(host, ".*twitter\\.com", RegexOptions.IgnoreCase);
        }
    }
}
```

```xml:Web.config
<configuration>
  <system.webServer>
    <modules>
      <add name="HTTPHeaderModule" type="App.Modules.HTTPHeaderModule" />
    </modules>
  </system.webServer>
</configuration>
```
#やっていること
　Initでヘッダ送信前に実行されるよう、AddHeaderFromURL関数を登録しています。
AddHeaderFromURL関数では、senderにリクエストやレスポンスが入ったオブジェクトが渡されるので、それをReflectionで取り出してあげています。([HttpContext.Current](https://msdn.microsoft.com/ja-jp/library/system.web.httpcontext.current)にもリクエストやレスポンスが入っていて、それを用いても同様の動作をします。しかし、ApiControllerを用いてレスポンスを返す際にはnullになることがある [^1] ようなので、senderから取得しています。)
分かりにくいですが、Reflectionで取り出したものも参照をコピーしてきているだけなので、これの中を変更してもsenderは変更されます。よって、特定の条件にマッチした場合、取り出したレスポンス内のheaderに追加しています。

[^1]: ![null.PNG](https://qiita-image-store.s3.amazonaws.com/0/216639/d4e01204-ce04-ac6e-0d82-56d993fc63fa.png)
網頁排版教學 By 彭彭

★網頁排版

```ruby:qiita.rb

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8"></meta>
	<title>britney spears</title>
	<style type="text/css">
	.head{
		background-color:#003300;
		color:white;
		font-weight:bold;
		font-size:30px;
		text-align:center;
		padding:5px;
	}
	.content{
		width:1000px;
		margin-left:auto;
		margin-right:auto;
	}
	/*	區塊不斷行 inline-block
		垂直對齊 vertical-align
	*/
	.box{
		width:280px;padding:10px;margin:10px;background-color:white;
		display:inline-block;vertical-align:top;
		text-align:center;
		height:300px;
		line-height:20px;
	}
	.title{
		font-weight:bold;}
	</style>
</head>
<body style="margin:0px;background-color:#eeeeee">
	<div class="head">britney spears</div>
	<div class="content">
	
		<div class="box">
			<div class="title">if you want something</div>
			<div>go get it</div>
			<div>period</div>
		</div>
		<div class="box">
			<div class="title">if you think you can</div>
			<div>you can</div>
			<div>believe in yourself</div>
		</div>
		<div class="box">
			<div class="title">whatever you are facing today</div>
			<div>you are stronger than you know</div>
		</div>
	</div>
</body>
</html>
```

★回應式排版設計(手機排版)

```ruby:qiita.rb
	<!-- 手機的縮放設定 -->
	<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />

	@media screen and (max-width:600px){
		.content{width:100%;text-align:center;}
	}
```
PuppeteerでWordPressのインストールを実行した

WordPressの環境作成をCIする場合に、一応セットアップまで見ておくかというときに。

## Puppeteerをインストール

- [GoogleChrome/puppeteer: Headless Chrome Node API](https://github.com/GoogleChrome/puppeteer)

```
$ yarn install puppeteer
```

## Puppeteerスクリプト

Passwordの入力周りがJavascriptなので、waitをしておくのが無難だった。

```javascript:wpsetup.js
const puppeteer = require('puppeteer');

(async () => {
  try {
    const browser = await puppeteer.launch({
      // headless: false, // デバッグ用
      ignoreHTTPSErrors: true
    });
    const page = await browser.newPage();
    // 言語選択がデフォルトのenでよければ、いきなりstep=1に飛んでOK
    await page.goto(
      process.argv[2] + '/wp-admin/install.php?step=1',
      {waitUntil: 'networkidle0'}
    );
    await page.type('#weblog_title', 'PUPPETEER')
    await page.type('#user_login', 'admin')
    // それなりに複雑なパスワード
    await page.type('#pass1-text', 'Pass00+345+Word')
    await page.type('#admin_email', 'test@example.com')
    await page.click('#blog_public')
    await page.click('#submit')

    browser.close()
  } catch(e) {
    console.log(e)
    process.exit(1)
  }
})();
```

`node wpsetup.js https://127.0.0.1:8443`のように実行する。

実行はCircleCIでやってるので、Fromイメージには`circleci/node:8-browsers`を使いました。
なんか動かないなーというときは`DEBUG=puppeteer:session`環境変数をつかいます。
ECS LIVA ZにDebian 9 stretchをインストール

# 買ったもの

* 2018年8月2日購入
    * [ECS LIVA Z N4200 アウトレット ¥19,434](https://www.amazon.co.jp/dp/B01MS4M6NT)
    * [Transcend TS120GMTS420S ¥5,980]([https://www.amazon.co.jp/dp/B076P63R3N/)
    * [サンワサプライ SKB-KG3BKN ¥1,256](https://www.amazon.co.jp/dp/B016U0VM5A/)

# LIVA ZにSSD取り付け

1. 4隅のネジを取り外す
1. VESAマウントのネジを取り付け
![IMG_20180807_131803.jpg](https://qiita-image-store.s3.amazonaws.com/0/240188/0ce1bab0-8495-d441-300a-f4d1c51e5d64.jpeg)
1. ネジを引っ張ってケースのふたを取り外す
![IMG_20180807_131822.jpg](https://qiita-image-store.s3.amazonaws.com/0/240188/2d300721-dc8d-503b-f15e-79ef0ffe164f.jpeg)
1. SSDを取り付ける
![IMG_20180807_132049_1.jpg](https://qiita-image-store.s3.amazonaws.com/0/240188/bf4ebe0e-b9d1-e0b8-4aab-4e1abba98a48.jpeg)
1. ふたを閉じる

# macでDebian USBメモリ作成

1. [debian を入手するには / インターネット経由の debian のインストール / 小さな CD または USB メモリ](https://www.debian.org/distrib/netinst#smallcd) から「debian-9.5.0-amd64-netinst.iso」をダウンロード
1.  dmgに変換

    ```console
$ hdiutil convert -format UDRW -o ~/Downloads/debian-9.5.0-amd64-netinst.dmg ~/Downloads/debian-9.5.0-amd64-netinst.iso 
```

1.  USBメモリを接続してデバイス名を確認

    ```console
$ diskutil list
/dev/disk0 (internal, physical):
（略）
/dev/disk1 (synthesized):
（略）
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *15.8 GB    disk2
   1:             Windows_FAT_32 Transcend               15.8 GB    disk2s1
```

1. USBメモリをアンマウントしてddで書き込み

    ```console
$ diskutil umountDisk /dev/disk2
$ sudo dd bs=8192 if=~/Downloads/debian-9.5.0-amd64-netinst.dmg of=/dev/disk2
```

1. 「セットしたディスクは、このコンピュータで読み取れないディスクでした。」画面で「取り出す」ボタンを押す

* 参考
    * [MacからDebianのUSBインストーラーを作成する - satomi-sanのブログ](http://satomi-san.hatenablog.com/entry/2017/06/26/231330)
    * [macでdebianのインストールusbメモリを作る - komagataのブログ](http://docs.komagata.org/5209)

# Debianインストール

1. USBメモリ、キーボード、TVをLIVA Zに接続
1. LIVA Zの電源ON
1. deleteキーを押してBIOS画面表示
1. 「ブート／オペレーションシステムの選択／Windows 8.x/10」を「Linux」に変更
![IMG_20180807_142110.jpg](https://qiita-image-store.s3.amazonaws.com/0/240188/c7ba3c3a-9619-75c9-8207-7ee4c4f5e1d4.jpeg)
1. 「終了／変更を保存してリセット」を実行
1. 「Graphical Install」を選択したところ、マウスが必要そうだった＆手持ちのマウスがなかったため、LIVA ZのACアダプターを外して電源ONして「Install」を選択
![IMG_20180807_142259.jpg](https://qiita-image-store.s3.amazonaws.com/0/240188/b0e24ecc-e7f6-a479-47d4-20d07ec69109.jpeg)
1. LIVA Zを電源OFF

    ```console
$ su -
# shutdown -h now
```

1.  TV、キーボードを外して設置場所に移動、電源ON

* 参考
    * [LIVA Z USER MANUAL](http://www.links.co.jp/wp-content/uploads/2017/09/LIVAZPro_Quick-Guide.pdf)

# macからdebianにリモート接続

```console
$ ssh -l ユーザー名 サーバーのIPアドレス
```
* 参考
    * [Mac OS Xでsshでサーバーへ接続 - Qiita]( https://qiita.com/kazukichi/items/2781ff1b0d2b0e23b37b)

# ルーター環境構築

* これから

# zabbix環境構築

* これから
【DjangoGirls】Djangoモデル「makemigrations blog」でエラーが出る

Django girlsのチュートリアル（日本語版：https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/content/ ）
の「Djangoモデル」トピックで
```TypeError: __init__() missing 1 required positional argument: 'on_delete'
```
というエラーが出る場合の対処法を簡単にメモ。。。

Django2.0以降のバージョンで作業していると起こるエラーです。
blog/models.pyの５行目
```
author = models.ForeignKey('auth.User')
```
を
```author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
```
とするとエラーが解消されます。
Django 2.0からはForeignKeyのon_deleteが必須になったそうです。
herokuのデータベースをリセットした際の留意点

###herokuのデータベースをリセット

```
heroku pg:reset DATABASE
```
上記コマンドにて、heroku上のデータベースをリセットできるが、このままの状態でherokuのアプリを開くと

```
We're sorry, but something went wrong.
If you are the application owner check the logs for more information.
```
となり、アプリを開いてもエラーが帰って来る。

###解決策

```
heroku run rake db:migrate
```
確かにrailsでもデータベースを弄った後は更新していたので自然な流れのようにも感じる。
上記コードを叩くことで無事にサイトが表示されるようになります。
Microsoft Azure IoTに関するまとめや違いなど

一つ一つの詳しい使い方などはのちほど個別の記事にしようかと。
個人の感想も含まれていますが間違っていたらごめんなさい。

#Windows 10 IoT Core Services
OS、デバイスドライバ、OEM固有のアプリケーションや各種ファイルの更新等を管理。
Windows Long-Term Servicing Channel（LTSC）を使用すると、10年間サポートが受けられる。
Device Health Attestation（DHA）が利用可能。

#IoT Hub
エッジデバイスとバックエンドの双方向の通信を仲介するサービス。
**主な特徴**
**・メタデータの管理**
　デバイスツインと呼ばれ、JSON形式で保存。
　エッジデバイスとバックエンド側で書き込み・参照可能な領域が異なる。
　どちらかで更新された場合、更新イベントをフックすることが可能。
**・各種プロトコルへ対応**
　MQTT, HTTPS,AMQP
**・各種開発言語へ対応**
　GitHubでSDKが公開されている
 　.NET, Java, C, Node.js, Python
細かい話は一旦以前のスライドを参照。
**概要**
https://speakerdeck.com/motoriderse/azure-iot-hubfalsesusume-gai-yao-bian
**デバイス管理編**
https://speakerdeck.com/motoriderse/azure-iot-hubfalsesusume-debaisuguan-li-bian

#IoT Edge
エッジデバイス上でAzureのサービスを利用可能にする。
実態はコンテナを管理するサービス。クラウドで作成されたStream AnalyticsやML、自作のモジュール等をコンテナ化して各エッジデバイスへデプロイし、そこで実行させる。
手軽に始めるにはIoT Hubが軽量でお勧めだが使い込んでいくと各モジュールのアップデートを管理したりするのが面倒で作りこみも大変なのでこちらを利用する方が手っ取り早い。
自分はこれに近いものを随分前ではあるが苦労して独自実装したので若干後悔している。
以前発表したスライドはこちら。
https://speakerdeck.com/motoriderse/azure-iot-edge-shallow-dive

#IoT solution accelerators
以前はAzure IoT Suiteと呼ばれていた。
一般的なシナリオで活用される各種OSSなどをまとめて作成してくれるサービス。
あくまでテンプレート的なものなのでカスタマイズ可能。
WebのUIも用意されている。
但し、何も知らずに作ってしまうと身に覚えの無い高額な費用請求が来るので注意が必要

#IoT Central
solution acceleratorsと違い、こちらはフルマネージドのSaaS。
solution acceleratorsは専門的な知識が無いと運用が辛いが
こちらはフルマネージドなのでその辺は楽になっている。

#Device Provisioning Service
通称DPS。
IoT Hubとセットで作成する必要がある。
NFVなどでよく言われるZero Touch Provisioningが行える。
実際にこれを使ってプロビジョニングすると意外に簡単でちょっと感動。

#Stream Analytics
Event HubsやIoT Hubに接続しておいて、デバイスから飛んできたメッセージをSQLライクな言語で処理する。
フィルター、ソート、集計、結合などが行える。
処理後、結果をData Lake Store、CosmosDB、SQL DB等に入れたりAzure Functionsを実行したりできる。
クラウドで作成済みのものをIoT Edgeへデプロイも可能。

#Machine Learning
StudioというWebのGUIが用意されていてドラッグアンドドロップで気軽に作成可能。
各種アルゴリズムもデフォルトで用意されている。
どのアルゴリズムを使うべきかわからなくてもcheat sheetが用意されているので
それに従って作成することも可能。

#Time Series Insights
時系列データを管理したり視覚化してくれるサービス。
ストレージとBIがセットになったようなもの。
とりあえずIoT HuBとセットで作成すると手軽にデータが視覚化出来る。
その反面、意外に安くないので注意。

#Cosmos DB
グローバルに分散可能なDB。
documentDBはこちらに統合された。（デバイスツインがこれっぽい）
APIはSQL、Gremlin（グラフ）、MongoDB、Cassandra、Table Storage などが選べる。

#Event Hubs
ざっくり言うと、いわゆるQueとして使える。
IoT Hubが登場する以前はデバイスから飛ばす先はこちらが主流だった。
とはいえクラウド側ではまだまだ利用用途は多い。

#Azure Sphere
MS製のIoT向けデバイス用Linuxディストリビューション。
対応デバイスは201809以降に発売とのこと。
FastlyでESI(Edge Side Includes)を利用する

FastlyではESI(Edge Side Includes)を利用できます。
CDN側でパーツ化されたHTMLやJSONなどを結合してレスポンスとして返してくれます。
SEO要件などでAjaxを利用できない場面、キャッシュ切れのタイミングが異なる情報で利用できる場面があるかと思います。

## Paid Accountではない状態でESIを利用する

無料の状態だとクライアントへのレスポンスをCDN側でgzip圧縮することができません。
また、Originへのレスポンスが圧縮されていると、ESIを利用することはできません。

VCL Snippet

```
sub vcl_fetch {
  esi;
}
```

OriginのHTML

```html:index.html
<!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>test</title>
    </head>
    <body>
        <h1>Hello ESI</h1>
        <esi:include src="/child.html" /><br>
        <esi:include src="/hoge.txt"></esi:include>
    </body>
</html>
```

```html:child.html
<b>child</b>
```

```text:hoge.txt
hoge
```

クライアントにレスポンスされるHTML

```html:index.html
<!DOCTYPE html>
    <head>
        <meta charset="utf-8">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>test</title>
    </head>
    <body>
        <h1>Hello ESI</h1>
        <b>child1</b>
<br>
        hoge

    </body>
</html>
```

## Paid AccountでTLSの契約をした状態でESIを利用する

今まではESIを利用した状態でクライアントへのレスポンスをCDN側でgzip圧縮することはできませんでしたが、サポートに連絡することによりESIを利用した状態でもgzip圧縮できるようにしてもらえます。
本機能を有効にしてもらうとCDNからのレスポンスの圧縮をbrotliも対応してくれるようです。 2018/08/17追記
[詳しくはコミュニティの情報を参考にしてください。](https://community.fastly.com/t/conditionally-disabling-gzip-in-order-to-serve-esi/464)

また、Originへのレスポンスが圧縮されていると、ESIを利用することはできません。

VCL Snippet

```
sub vcl_fetch {
  if (beresp.http.Content-Type ~ "htm") {
    esi;
  }
#FASTLY fetch
}

sub vcl_miss {
  unset bereq.http.accept-encoding;
#FASTLY miss
}

sub vcl_pass {
  unset bereq.http.accept-encoding;
#FASTLY miss
}

sub vcl_deliver {
  if (req.is_ssl) {
    set resp.http.x-compress-hint = "on";
  }
#FASTLY deliver
}
```

## 参考文献
* https://docs.fastly.com/guides/performance-tuning/using-edge-side-includes
Android Studioのビルドでfinished with non-zero exit value 1の原因を調べる


## 開発環境
```
Android Studio 3.2 Beta 5
Build #AI-181.5281.24.32.4913314, built on July 26, 2018
JRE: 1.8.0_152-release-1136-b04 x86_64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
macOS 10.12.6
```


## 現象

コード書いてビルドしたら見慣れぬエラーに遭遇

```
Process 'command '/Users/ikemura/Library/Android/sdk/build-tools/27.0.3/aapt'' finished with non-zero exit value 1
```

なんだこれは、、、原因が分からん！

詳細なログも出てこない！

Build > Clean Project してもダメ

File > Invalidate Caches / Restart してもダメ

## エラー検索方法

Android StudioのTerminalを開いて以下を実行

```
./gradlew assembleDebug --info
```

するとズラズラとログが出てくる

BUILD FAILED
と表示されて完了したっぽいのでログを遡って眺めると...

```
info_card.xml:23: error: Error parsing XML: duplicate attribute
```

`info_card.xml`が原因っぽい

info_card.xmlを見てみると

```xml
<?xml version="1.0" encoding="utf-8"?>
<layout 
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    >

    <data>
    </data>

    <android.support.v7.widget.CardView 
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
```

`xmlns:app`タグが２つもある...

`xmlns:tools`を補完機能から追加した時に、なぜか`xmlns:app`が自動で再度追加されたようだ。

そういうことだったのか

2番目の`xmlns:app`を消してエラーは解決できたが、このエラーはビルドログに出てこないんだな。

## 結論

xmlのエラーは厄介なので気をつけよう

ログを見て分からないエラーに困ったら

```
./gradlew assembleDebug --info
```
を実行しよう
Data studioにHeroku postgresを接続しようとしてハマったメモ

Data studioからHerokuのpostgresに接続しようとしたところ、

> Access denied, please check your username and password.

とのこと。

結論SSL接続が必要だった。

```
openssl req -newkey rsa:2048 -nodes -keyout client.key -x509 -days 365 -out client.crt
```
でオレオレ証明書を作成。common nameはpostgresのホスト名を設定。

下記pythonのソースを拝借し、実行。
https://raw.githubusercontent.com/thusoy/postgres-mitm/master/postgres_get_server_cert.py

```
python postgres_get_server_cert.py {heroku-postgres-host}:{port} > heroku-cert.crt
```

それぞれ出力されたファイルをアップロードする。
PHPでフォームから値を受け取り、$_GETで新しい別のページに値を受け渡して表示する

htmlのformに入れた値を、次に遷移するページへ受け渡す方法です。
実際にソースを書く時には、「空欄の時はリンク先へ飛ばない」、「テキストしか受け付けない」などの記述を追加する必要があります。

# 送信する側

```php
<html>
 <head>
  <title>タイトル</title>
 </head>
 <body>
  	<h1>入力画面</h1>
 	<form action = "result.php" method = "get">
	 	<input type = "text" name = "result" placeholder = "keywords"></br>
	 	<input type = "submit" value = "Go">
 	</form>
</body>
</html>
```

# 受信する側

```php
<html>
 <head>
  <title>受け渡し結果</title>
 </head>
 <body>
  	<h1>受け渡し結果</h1>
	<p>
		<?php
			$result = $_GET["result"];
			echo htmlspecialchars($result, ENT_QUOTES, 'UTF-8'); //文字列に変換
		?>
	</p>
</body>
</html>
```
GitHub コマンド　Tips 

# GitHubのコマンドでつかうTips

### リモートリポジトリに何が設定されているか確認

```
git remote -v
```

###### プッシュの時など　Originalを指定する時に確認する際に使う
### 変更をadd

```
git add .　
```
### ログを表示

```
git log　
```
コミットのログを表示してくれます。

### helpを表示

```
git --help
```
コマンドの一覧を表示してくれます。[Hubインストール済みの場合はHubのヘルプも表示されます]

```
git help pull
```
helpの後にコマンド名を指定するとコマンドのヘルプ画面が表示されます。


###### コミットをする前に必ず実行（modified:というエラー発生時は必須）拡張子指定可　**例** `git add *.css` 


# GitHubの基本コマンドでつよくつかうコマンド
### プルPULL(取得)

```
git pull origin develop
```

### コミット

```
git commit -m 'commmandtest'
```

### プッシュ

```
git push origin develop:develop_0806 
```

**第1引数** origin 
git cloneした時に「origin」という名前でリモートリポジトリが設定されているのでそのまま指定
 
**第2引数** develop
ローカルのリポジトリ名

**第3引数** develop_0806
リモート先にプッシュするブランチ名

```
λ git push origin develop:develop_0808
Counting objects: 3, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 313 bytes | 104.00 KiB/s, done.
Total 3 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 2 local objects.
To https://github.com/●●●●/training
 * [new branch]      develop -> develop_0808
```
こんな感じで実行されます。


### プルリク【hubが必須】

```
git pull-request -b develop -h develop_0808 -m 'マージプリーズ【自動プルリク】' -r yamadatarou

```
例　-b　はbaseマージ先ブランチ名
　　-h　はマージしたいブランチ名(主に修正したもの）
　　-m  コミットメッセージ
　　-r  レビューワ名

*レビューワーはプルリクユーザー本人は基本設定できません。*

### バッチ内でGit　pull-requestを使った時のエラー

```
git pull-request -b develop -h develop_0808_1252 -m testコメント
git: 'pull-request' is not a git command. See 'git --help'.
```
git pull-requestはコマンドでたたく時はうまくいったのですが
バッチ内に含めるとうまく実行されませんでした
ので　hub pull-request で実行！解決！

---
HubインストールにはGOのインストールが必須
[Goのインストール](https://golang.org/dl/)
CSS 表格樣式 - 詳細使用介紹 By 彭彭

★ css 表格樣式 詳細介紹

```ruby:qiita.rb
<DOCTYPE html>
<html>
<head>
<meta charset="utf-8"></meta>
<title>CSS 表格樣式</title>
<style type="text/css">
body{
	background-color:#708090;
}
table{
	width:300px;border:1px solid #ffffff;
	border-collapse:collapse;
}
td{
	border-bottom:1px solid #888888;padding:2px;
}
/* 表格中的第一對 tr */
tr:nth-child(1){
	background-color:#ffffff;color:#000000;
}
/* 表格中的第偶數對 tr */
tr:nth-child(even){
	background-color:#ffeeff;
}
</style>
</head>
<body>
	<table>
		<tr>
			<td>郭</td>
			<td>少</td>
			<td>芸</td>
		</tr>
		<tr>
			<td>大</td>
			<td>寶</td>
			<td>貝</td>
		</tr>
		
	</table>
	<hr />
	<img src="florence.jpg" />
</body>
</html>
````
athrill2のTOPPERS/ATK2ハードウェア要求仕様準拠割合調査結果

#概要
[athrill2](https://qiita.com/kanetugu2018/items/b43c5715124f42a0393d)がTOPPERS/ATK2カーネルの実機レス環境対応していることを客観的(定性的に)にチェックしておくことは，今後のathrill2の機能拡張方向を示す上で有意義である．そのため，「[次世代車載システム向けRTOSハードウェア要求仕様書 Ver.3.0.1](https://www.toppers.jp/docs/tech/ngka_req-02-301.pdf)」に対して，athrill2の仕様準拠割合を調査した結果を以下に示す(SC1については100％であるため省略)．

#TOPPERS/ATK2ハードウェア要求仕様の準拠割合

|スケーラビリティクラス|MR(最小要求)|SR(標準要求)|AR(性能改善要求)|
|---|---|---|---|
|SC2|100%(2/2)|50%(1/2)|0%(0/1)|
|SC3|100%(10/10)|50%(1/2)|0%(0/2)|
|SC1-MC|100%(5/5)|67%(6/9)|17%(1/6)|
|SC2-MC|80%(4/5)|9%(1/11)|14%(1/7)|
|SC3-MC|100%(6/6)|64%(7/11)|13%(1/8)|

#TOPPERS/ATK2ハードウェア要求仕様の準拠調査結果

|要件レベル|要件番号|athrill2対応|要件レベル|要件番号|athrill2対応|
|---|---|---|---|---|---|
SR|【HW001】|〇|MR|【HW021】|〇
SR|【HW002】|〇|MR|【HW022】|〇
SR|【HW003】|〇|MR|【HW023】|×
MR|【HW004】|〇|SR|【HW024】|×
SR|【HW005】|×|SR|【HW025】|〇
SR|【HW006】|〇|SR|【HW026】|×
AR|【HW007】|〇|SR|【HW027】|×
AR|【HW008】|×|AR|【HW028】|×
SR|【HW009】|〇|MR|【HW029】|〇
AR|【HW010】|×|MR|【HW030】|〇
MR|【HW011】|〇|MR|【HW031】|〇
SR|【HW012】|×|MR|【HW032】|〇
AR|【HW013】|×|MR|【HW033】|〇
AR|【HW014】|×|MR|【HW034】|〇
SR|【HW015】|×|MR|【HW035】|〇
MR|【HW016】|〇|MR|【HW036】|〇
MR|【HW017】|〇|MR|【HW037】|〇
SR|【HW018】|〇|SR|【HW038】|〇
AR|【HW019】|×|SR|【HW039】|×
MR|【HW020】|〇|AR|【HW040】|×
||||AR|【HW041】|×


#見解

|要件番号|対応有無|見解|
|----|----|--------|
|1|〇|設計上はN(>=2)個のコアを搭載可能|
|2|〇|v850e2mの命令セット/エンディアンのコアをもつ|
|3|〇|いずれのコアからもアクセス可能な共有メモリをもつ|
|4|〇|v850e2mのCAXI命令により実現|
|5|×| Compare and Swapは，CAXI命令が相当する．ただし，コア数が３個以上の待ち問題はこれだけでは解決できないと思われるので，×とした．|
|6|〇|CAXI命令はアトミック命令であり，本命令がアクセスを許されるメモリの容量の分だけロック単位を設定可能ということになり，個数の面での問題はない．|
|7|〇|CAXI命令はアトミック命令であり，本命令がアクセスを許されるメモリの容量の分だけロック単位を設定可能ということになり，個数の面での問題はない．|
|8|×|未搭載|
|9|〇|v850e2mのPEID（プロセッサ・エレメント ID）レジスタにより実現|
|10|×|未搭載|
|11|〇|いずれのコアからもアクセス可能な共有メモリをもつ|
|12|×|未搭載|
|13|×|未搭載|
|14|×|未搭載|
|15|×|データキャッシュは未搭載|
|16|〇|v850esfk3の割り込みマスク・レジスタ(IMR0-IM07)により割り込み要因毎にマスク可能|
|17|〇|v850e2mのコア間割り込みにより実現．(割り込み番号0=core0割り込み, 割り込み番号1=core1割り込み)|
|18|〇|v850e2mの割り込みコントローラ仕様に準拠し，コア毎に割り込みコントローラを割り当て，割り込み発生すると両コアに割り込みが発生する．そのため，起動時にコア毎に割り込みマスク設定することで，特定コアのみに割り込みを発生させることができる．|
|19|×|未搭載|
|20|〇|v850esfk3の以下のタイマをサポート(TAAnCH0～TAAnCH3)|
|21|〇|左記機能を実現するタイマを合計４個用意している．|
|22|〇|左記機能を実現するタイマを合計４個用意している．|
|23|×|未搭載|
|24|×|未搭載|
|25|〇|左記機能を実現するタイマを合計４個用意している．|
|26|×|未搭載|
|27|×|未搭載|
|28|×|未搭載|
|29|〇|v850e2mのメモリ保護機能を実現(命令保護領域数：最大５個, データ保護領域数：最大６個)|
|30|〇|v850e2mプロセッサ保護設定レジスタにより，特権モードにおいて，動的に設定内容を変更可能．|
|31|〇|v850e2mのメモリ保護機能を実現(命令保護領域数：最大５個, データ保護領域数：最大６個)|
|32|〇|v850e2mの仕様準拠し，CPU例外(ノンマスカブル)として実現されている|
|33|〇|v850e2mプロセッサ保護設定レジスタにより，特権モードにおいて，動的に設定内容を変更可能．|
|34|〇|v850e2mプロセッサ保護設定レジスタにより，データ保護領域は読み/書きのアクセス禁止/許可が可能|
|35|〇|v850e2mプロセッサ保護設定レジスタにより，命令保護領域は読み/実行のアクセス禁止/許可が可能|
|36|〇|v850e2mのメモリ保護機能を実現(命令保護領域数：最大５個, データ保護領域数：最大６個)|
|37|〇|v850e2mのメモリ保護設定レジスタは，コア毎に設定可能であり，メモリ保護違反例外は当該コアに対してのみ発生する．|
|38|〇|v850e2mプロセッサ保護設定レジスタにより，データ保護領域は読み/書きのアクセス禁止/許可が可能|
|39|×|未搭載|
|40|×|未搭載|
|41|×|未搭載|
Qiitaの通知一覧からユーザーページに直リンするUserscriptを作った

#はじめに
Qiitaで自分の書いた投稿がいいねされると、やっぱり嬉しいですよね。
どんな方がいいねしてくれたのか気になって、その人のユーザーページを見に行くこともあります。
ただその際不便なのが、通知のリンク先がいいねしてくれたユーザーのページではなく、いいねされた記事になっているんですよね…:expressionless:
ということで勝手にリンクを書き換えるユーザースクリプトを作成しました。

#使い方
ユーザーネームの部分を新たにリンクにして、そこをクリックするとユーザーページに遷移します。
![qiita_link.png](https://qiita-image-store.s3.amazonaws.com/0/104983/5ce74788-2c19-de85-06e3-3abcd69786b4.png)


#環境
Chrome + Tampermonkey
10年前くらいは、グリモンを始めとしたユーザースクリプト界隈が非常に盛り上がってた気がしますが、最近はあまり見かけない気がします。なんででしょうかね…？

#コード
JQueryでDOM操作をしているだけです。
このレベルでJQueryを使ってたら、Qiita警察の方に怒られそうですが許してください…:pray:

なお「あなたの投稿がツイートされました」の通知の場合は、リンクさせる先がありませんので、処理がスキップされるようにしています。

```javascript:
// ==UserScript==
// @name         Qiita user link
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  Qiitaの通知欄から直接ユーザページに遷移できるようにする。
// @author       Sinhalite
// @match        https://qiita.com/notifications*
// @require      https://code.jquery.com/jquery-3.3.1.js
// @grant        none
// ==/UserScript==

(function() {
    'use strict';
    $('.notification_actionWrapper > span:first-child').each(function() {
        if($(this).next().text() === 'ツイート'){
            return;
        }
        const user_name = $(this).text();
        $(this).wrap('<a />');
        $(this).parent('a').prop({'href':user_name,'target':'_parent'});
    });
})();
```

#おわりに
なんやかんや、JQuery便利じゃない？
Ubuntu 16.04 LTSでElixirインストール→Welcome to Phoenixするまでの手順

<img src="https://qiita-image-store.s3.amazonaws.com/0/227776/e8b7b6eb-616c-1c0b-7bc7-17b39f41b8c8.png"> <img src="https://qiita-image-store.s3.amazonaws.com/0/227776/b984df58-e41c-bfe3-8df0-7753c117f338.png"width="300px">

Keiです。最近福岡(~~Twitter?~~)を中心にElixir界隈が賑やかになってきているようだったので、「ちょっと触るだけ...」と思って自分もUdemyでElixir+Phoenixの勉強始めてみたのですが、Elixir自体の環境構築は超絶簡単な一方、そのフレームワークであるPhoenixはPostgre SQLの導入が必要だったり(Ubuntu/Debianユーザーについては)敢えてLegacy版のNode.jsを入れる必要があったりと、サンプルアプリの動作確認までにそれなりに面倒な手順を踏む必要があったので、備忘録も兼ねて環境構築の手順をまとめておきます。

以下実行環境はUbuntu 16.04 LTSです。

##|> Elixir & Erlangのインストール
ターミナルで以下のコマンドを順に打ち込めばOK。

```bash
wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && sudo dpkg -i erlang-solutions_1.0_all.deb
sudo apt-get update
sudo apt-get install esl-erlang
sudo apt-get install elixir
```
正しくインストールされていれば```elixir -v```でElixirのバージョンが確認でき、

```bash
elixir -v
Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe]
Elixir 1.7.0 (compiled with Erlang/OTP 20)
```

```iex``` でElixirのインタラクティブシェルが立ち上がります。


```bash
iex
Erlang/OTP 21 [erts-10.0] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [hipe]

Interactive Elixir (1.7.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 
```

##|> Phoenixインストール→サンプルアプリ起動
同じくターミナルで以下のコマンドを順に打ちこんでください。

```bash
### 諸々インストール
mix local.hex
mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez                                        
apt-get install nodejs-legacy   # Ubuntu/Debianは普通のNodeだと動かないらしい。詳しくは→https://stackoverflow.com/questions/21168141/cannot-install-packages-using-node-package-manager-in-ubuntu    
sudo apt-get install inotify-tools
sudo apt install npm
npm install -g bower
sudo apt-get install build-essential libreadline-dev zlib1g-dev flex bison libxml2-dev libxslt-dev libssl-dev

### Postgresの導入とパスワード設定
sudo apt-get install postgresql postgresql-contrib   # Postgresインストール
sudo service postgresql start   # Postgres起動
```
最後のコマンドでPostgresが起動するので、ひとまず初期パスワードを設定してサンプルアプリ用のDBを作成します。

```sql
--- Postgresの設定
psql (9.5.13)
Type "help" for help.

postgres=# \password postgres   
Enter new password:             --ひとまず"postgres"と入力しておく
Enter it again: 
```
これでCtrl+d でPostgresを出ます。
再度ターミナルで以下のコマンドを打つとローカルでWebサーバーが立ち上がるので、http://0.0.0.0:4000 にアクセスして"Welcome to Phoenix!"の画面が見れれば完了です。お疲れ様でした。

```bash
sudo -u postgres createdb mydb
mix phx.new hello  # Phoenixプロジェクト作成
#mix phx.new hello --no-ecto　とすればDBを使わないプロジェクトに出来ます
mix ecto.create    # DB作成
mix phx.server     # サーバ起動
```

<img src="https://qiita-image-store.s3.amazonaws.com/0/227776/91efcad0-815f-c050-bd48-19c3bfb7eacf.png">


### |> 参考
Elixir公式: https://elixir-lang.org/install.html#unix-and-unix-like
Phoenix公式: https://hexdocs.pm/phoenix/installation.html
Railsのルーティングでid以外の数値カラムをURLに使うときの注意点

# 前提

```
User
  id:   integer (uniq)
  name: string  (uniq)
  code: integer (uniq)
```
というモデルに対してshowアクションを作成する際、

通常、 `routes.rb`で

```ruby
resources :users, only: :show
```

を書くことで

`users/:id`なルーティングが作成されますが、
idカラムではなくname(string)やcode(integer)をURLに使用する方法を↓に書きます


# name:stringをURLに使いたい場合
まずベーシックなやり方から。

## routes.rb

```ruby
resources :users, only: :show, param: :name
```

これで `users/:name`でアクセスできるようになります。

## users_controller.rb
パラメータが:idから:nameにかわるのでコントローラでも対応が必要です。

元がこんなコードなら

```ruby
def show
  @user = User.find(params[:id])
end
```

↓こんなかんじに変えます

```ruby
def show
  @user = User.find_by!(name: params[:name])
end
```

※
`find`はレコードが見つからない場合 `ActiveRecord::RecordNotFound`がraiseされますが、
`find_by`はレコードが見つからない場合 `nil`が返るだけなので、
例外キャッチして404などを表示するために、 `ActiveRecord::RecordNotFound`がraiseされる `find_by!`を使います


↓find_byとfind_by!の実装

```ruby
def find_by(arg, *args)
  where(arg, *args).take
rescue ::RangeError
  nil
end

def find_by!(arg, *args)
  where(arg, *args).take!
rescue ::RangeError
  raise RecordNotFound.new("Couldn't find #{@klass.name} with an out of range value",
                           @klass.name)
end
```



## user.rb

このままだとlink_to等のヘルパーメソッドでidが使用されるため、モデルで `to_param`をオーバーライドします

```ruby
def to_param
  name
end
```

(わざわざ説明する必要があるかわかりませんが、わかりやすく書くと)

```ruby
def to_param
  return self.name
end
```

と同じです。

---

以上がid以外のstringのカラムをURLに使用する際の常套手段ですが、
integerのカラムを使用する場合はひと手間増えます。

# code:integerをURLに使いたい場合
## routes.rb

```ruby
resources :users, only: :show, param: :code, constraints: { code: /\d+/ }
```

上の例と違うのは、数値のみを受け付けるconstraintsを足している点です。
これを設定しないと、 `users/1hoge`等でアクセスしても `users/1`にルーティングされてしまいます。

原因は調べてないのでしりませんが、
多分内部的にintegerのカラムを検索する際に `#to_i`をしているはずで、
`String#to_i`は先頭から数値部分だけを数値に変換するという挙動をするから・・だと思います

```ruby
'100'.to_i        # => 100
'100hoge000'.to_i # => 100
```

## users_controller.rb

ここは一緒です

```ruby
def show
  @user = User.find_by!(name: params[:code])
end
```



## user.rb

```ruby
def to_param
  code.to_s
end
```

カラムはintegerなので `to_s`する必要があります。



# おわり

constraintsで数値以外を弾くのは結構わすれがちなので、
id以外の数値カラムをURLに使用したい場合はご注意。
Go言語でトランプのパッケージを作成してみた

[こちらの記事](https://qiita.com/hirossyi73/items/cf8648c31898216312e5)を見て、Go言語でブラックジャックを作ってみようとなった際に、どうせならトランプの処理の部分をパッケージ化してしまおうと思い、作ってみた。

パッケージは https://github.com/x-color/gocard にMITライセンスで置いてあるので、ご自由にお使いください。
一応、パッケージの中のexampleディレクトリの中にシンプルなブラックジャックを実装したものも入れてあります。

インストールは

```bash
$ go get github.com/x-color/gocard
```

# 実装されている機能

実装されている機能は、

- カードの生成
- カードの強弱の判定
- カードのソート
- カードの強弱の変更
- 52枚組のデッキの生成
- デッキのシャッフル
- デッキからのドロー
- カードをデッキの一番上に置く
- カードをデッキの一番下に置く

## カードの生成

スペードの1を生成するには

```go
card := gocard.Card{
  Rank: gocard.ACE,
  Suit: gocard.SPADES,
}
```

## カードの強弱の判定

カードを比較し、強弱を判定する。`CompareByRank()`は数字優先で判定を行い、`CompareBySuit()`はマーク優先で判定を行う。

戻り値は、card1 > card2でr > 0、card1 == card2でr = 0、card1 < card2でr < 0となる。

例えば、このようなカードを用意した場合、

```go
card1 := gocard.Card{Rank: gocard.JACK, Suit: gocard.DIAMONDS} // ダイヤの11
card2 := gocard.Card{Rank: gocard.FIVE, Suit: gocard.SPADES} // スペードの5
```

比較結果は、

```go
r := gocard.CompareByRank(card1, card2) // r > 0
r := gocard.CompareBySuit(card1, card2) // r < 0
```

## カードのソート

カードのソートを行う。`SortByRank()`は数字優先でソートを行い、`SortBySuit()`はマーク優先でソートを行う。

例えば、このようにカードリストを用意した場合、

```go
cards := gocard.Cards{
  card1, // スペードの1
  card2, // クラブの5
  card3, // ハートの11
}
```

ソートは以下のようになる。

```go
gocard.SortByRank(cards) // cards=[card2, card3, card1]
gocard.SortBySuit(cards) // cards=[card2, card3, card1]
```

## カードの強弱の変更

RankとSuitのスライスを作成して、`SetRankingOfRanks()`、`SetRankingOfSuits()`に渡すことで、カードの強弱を変更することができる。
この例では、数字の大きさがそのまま強さとなるようにし、マークはスペード、クラブ、ハート、ダイヤの順に強くなるように設定している。

```go
ranks := []gocard.Rank{gocard.ACE, gocard.TWO, gocard.THREE, gocard.FOUR, gocard.FIVE, gocard.SIX, gocard.SEVEN, gocard.EIGHT, gocard.NINE, gocard.TEN, gocard.JACK, gocard.QUEEN, gocard.KING}
suits := []gocard.Suit{gocard.SPADES, gocard.CLUBS, gocard.HEARTS, gocard.DIAMONDS}

gocard.SetRankingOfRanks(ranks)
gocard.SetRankingOfSuits(suits)
```

## 52枚組のデッキの生成

52枚組のデッキを生成する。

```go
deck := gocard.NewDeck()
```

## デッキのシャッフル

デッキをシャッフルする。

```go
dek.Shuffle()
```

## デッキからのドロー

デッキの一番上から一枚ドローする。戻り値には、引いたカードとデッキが空の時に引いた際に発生するエラーを返す。

```go
card, err := deck.Draw()
```

## カードをデッキの一番上に置く

デッキの一番上にカードを置く。

```go
deck.PutTop(card)
```

## カードをデッキの一番下に置く

デッキの一番下にカードを置く。

```go
deck.PutBottom(card)
```

# おわりに

初めてのGo言語でのパッケージ作成なので、どんなふうに実装するべきかと悩んだりして、こんな小規模なのに意外と時間がかかってしまった...
PC-98 フロッピーIPL作成ツール

MASM32などで作ったIPL用comファイルから2HDフロッピー（ベタ形式）を作る。PC-98エミュレータ Neko Project II で読み込み可能。

```iplfd.cpp
/*
	Visual Studio Community 2017 / Visual C++
*/

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
	// セクタサイズ * セクタ数 * ヘッド数 * シリンダ数
	static char buf[1024 * 8 * 2 * 77];

	if (argc != 2) {
		fprintf(stderr, "usage: iplfd filename\n");
		return 1;
	}
	char *path_in = argv[1];
	char path_out[_MAX_PATH];
	sprintf_s(path_out, "%s.dup", path_in);

	FILE *file_in;
	if (fopen_s(&file_in, path_in, "rb")) {
		perror(path_in);
		exit(1);
	}
	fread(buf, 1, sizeof buf, file_in);

	FILE *file_out;
	if (fopen_s(&file_out, path_out, "wb")) {
		perror(path_out);
		exit(1);
	}
	fwrite(buf, 1, sizeof buf, file_out);

	_fcloseall();
	return 0;
}
```
Qiitaのmarkdown注意点

qiitaのmarkdownはgithubのとちょっと違うところがあるので覚書として投稿
順次追加予定．

## 1. コード
バッククォートで囲んだ部分がmarkdown文法にかかわらずそのまま表示される...はずである．
\`\` \` hogehoge \` \`\` →　`` `hogehoge` ``

\`\`\`\` \`\`\`hugahuga \`\`\` \`\`\`\` →　```` ```hugahuga ``` ````
となるところまでは正しいが，
\`\`\`\` 
\`\`\`hegohego 
\`\`\` 
\`\`\`\` 
↓　

```` 
```hegohego 
``` 
````
```
のように，外枠のバッククォートの数より少ないバッククォートにかかわらず閉じてしまっている．
対策として，
\`\`\`\` 
\`\`\`hegohego 
x\`\`\` 
\`\`\`\` 
↓　

```` 
```hegohego 
x``` 
````
のように，おかしな挙動をするバッククォートの前に何かの文字を置くことで回避できなくもない．














## 2. 数式の斜字体の太字
```
二つのベクトル$\boldsymbol{u}_1$　と$\boldsymbol{v}_2$があり．．．
```
と書いたとき，
>二つのベクトル$u_1$と$v_2$があり．．．

という文章がuとvが$\boldsymbol{u}$, $\boldsymbol{v}$のような**太字**になって描画されるべきなのだが，
実際には
>二つのベクトル$\boldsymbol{u}_1$　と$\boldsymbol{v}_1$があり．．．

と表示される．
これは，すくなくとも以下の3つの条件が揃うと生じる．
・同じ行事複数のインライン数式を入れる
・その数式の中で複数が\boldsymbolを使っている
・その数式の中で複数が\boldsymbolの括弧外で下付きの添字をつけている

そのため，斜字体でなくなってしまうが，直立体の太字\mathbfを使う必要がある．
```
二つのベクトル$\mathbf{u}_1$　と$\mathbf{v}_1$があり．．．
```

↓
>二つのベクトル$\mathbf{u}_1$　と$\mathbf{v}_1$があり．．．
Scalable Sequenceを試す （Oracle Database 18c）

Oracle Database 18c の新機能 Scalable Sequence を検証します。

# Scalable Sequence とは
SEQUENCE オブジェクトは一意な数値を生成するオブジェクトです。指定された番号と増分により NEXTVAL と CURRVAL 疑似列を使って値取得することができます。
　テーブルの主キーとして自動採番用に SEQUENCE を使い、データの一括ロードを行う場合、順序値として近い値が大量に生成されることがあります。近い値が大量に挿入されると、インデックスの同一ブロックに書き込みが集中するといった問題があります。

Oracle Database 18c では、従来の SEQUENCE を拡張し、シーケンス値にインスタンス番号とセッション番号を付加することでセッション単位に離れた値を生成することができるようになりました。

# Scalable Sequence の作り方
拡張されたSEQUENCEを作成するには、CREATE SEQUENCE 文に SCALE 句を指定します。START WITH で指定された値の上位ビットにセッション番号から生成された数値が付加されます。

```
SQL> CREATE SEQUENCE seq_scale1 START WITH 1 SCALE;

Sequence created.

SQL> SELECT TO_CHAR(seq_scale1.NEXTVAL) FROM DUAL;

TO_CHAR(SEQ_SCALE1.NEXTVAL)
----------------------------------------
1010190000000000000000000001

```

別セッションからシーケンス値を取得すると、大きく異なる値が取得できることがわかります。

```
SQL> SELECT TO_CHAR(seq_scale1.NEXTVAL) FROM DUAL;

TO_CHAR(SEQ_SCALE1.NEXTVAL)
----------------------------------------
1013930000000000000000000002

```

デフォルトでは、SEQUENCE オブジェクトが使う領域の上位６桁をセッション単位に更新します。拡張領域を従来の SEQUENCE の「範囲外」に持つ設定が CREATE SEQUENCE 文の SCALE EXTEND 設定です。下記の例では SCALE EXTENDED を指定した SEQUENCE の桁数が増えていることがわかります。

```
SQL> CREATE SEQUENCE seq_extend START WITH 1 SCALE EXTEND;

Sequence created.

SQL> SELECT TO_CHAR(seq_extend.NEXTVAL) FROM DUAL;

TO_CHAR(SEQ_EXTEND.NEXTVAL)
----------------------------------------
1010190000000000000000000000000001

```

ALTER SEQUENCE 文で属性を変更することもできます。EXTEND 句を解除するには ALTER SEQUENCE SCALE NOEXTEND 文を実行します。SCALE 句を解除するには ALTER SEQUENCE NOSCALE 文を実行します。

```
SQL> ALTER SEQUENCE seq_scale1 NOSCALE;

Sequence altered.

SQL>  ALTER SEQUENCE SEQ_EXTEND SCALE NOEXTEND;

Sequence altered.

```

# 確認方法
設定の確認は、ALL_SEQUENCES ビュー（DBA_SEQUENCE / USER_SEQUENCE）の　SCALE_FLAG　列（SCALE 句の指定 = 'Y'）と、EXTEND_FLAG 列（EXTEND　句の指定 = 'Y'）で確認できます。

```
SQL> SELECT SEQUENCE_NAME, SCALE_FLAG, EXTEND_FLAG FROM USER_SEQUENCES;

SEQUENCE_NAME                  S E
------------------------------ - -
SEQ_EXTEND                     Y Y
SEQ_SCALE1                     Y N
```


マニュアルには CREATE SEQUENCE 文に SCALE 句を指定する場合には ORDER 句と併用しないことを推奨していますが、SQL 文としては実行可能です。

```
SQL> CREATE SEQUENCE seq_not_recommended SCALE ORDER;

Sequence created.
```
「IAM認証によるRDS接続を試してみた」が失敗する

#概要
[IAM認証によるRDS接続を試してみた](https://dev.classmethod.jp/cloud/aws/iam-auth-rds/)
等を参考に
MYSQL(5.7.22)でMYSQLクライアントとPython(mysql-connector-python+sqlarchemy)
から接続しようと試行しましたが
どうやっても接続時「Access denied for user ・・・」に。

#原因と解決策
aws rds generate-db-auth-tokenでトークンはとれているので
接続の問題と思い、いろいろ試した結果・・・
バージョン5.7.22から5.6.40に下げたところ
全く同じ設定で接続に成功しました。

追試したところ、5.7.16だとうまくいくので、どこかのバージョンから
何かオプションが追加でいるのか、コネクタ関連のバージョンが合っていないのか
ちょっとつかめていませんが、取り急ぎご報告まで。

バージョン5.7.22でうまくいっているよ！！って方いましたら
接続時の設定を教えてもらえないでしょうか。

* * *
8/14追記
[Amazon RDS での MySQL](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/CHAP_MySQL.html)によると
5.7.19 以前と5.7.21以降で接続のSSLがyaSSLからOpenSSLに替わっているようなので
その影響かもしれません。
5.7.19では接続できましたので、しばらくこれで運用することにします。