OmniAICreator/Qiita-1.07M huggingface dataset:
複数GitHubアカウント持ちのinitからPRまで

## はじめに
個人用と職場や研究室用でGitHubアカウントを複数持つ場面は往往にしてあると思う．そして，サブアカウントを使っているときにエラーが出ることが多いので，サブアカウントでのinitからPRまでの流れを記事にまとめたいと思う．  

## gitリポジトリを始める
gitで管理したいディレクトリにて以下のコマンドを入力

```:command-line
$ git init
Initialized empty Git repository in /Users/.../<git_manage_directory>/.git

$ git config --local user.name "Your Name"
$ git config --local user.email you@example.com
```
Your Nameとyou@example.comはについてはサブアカウントで使ってるものを使用する．
`git config --local`でディレクトリ単位でユーザーを指定できる．
また，`.gitignore`ファイルを作成し，gitの管理に反映させたくないファイルを記載する．

```:.gitignore
.vscode/
.DS_Store
```
## ディレクトリをコミットするまで
```:command-line
$ git add -A
$ git commit -m "first commit(コメントはなんでも良い)"
 [...]
 13 files changed, 200 insertions(+)
 create mode 100644 .gitignore
 [...]
 create mode 100644 requirement.txt
```
## GitHubにコードをプッシュする
https://github.com/new にて`Repository name`を入力し，`Create repository`をクリックする．
<img width="955" alt="スクリーンショット 2019-07-24 0.35.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468274/830a31ca-b2d2-b597-d67b-8508ee3b9d36.png">
<img width="1143" alt="スクリーンショット 2019-07-24 0.43.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/468274/d10b77c9-c58c-8542-3f31-078a972ed899.png">
`Create repository`をクリック後出てくるページにしたがって以下のコマンドを入力しても失敗する．

```:command-line
$ git remote add origin https//github.com/<sub_username>/my-page.git
$ git push -u origin master
remote: Permission to <sub_username>/mypage.git denied to <main_username>.
fatal: unable to access 'https://github.com/<sub_username>/my-page.git/': The requested URL returned error: 403
```
この部分を以下のコマンドにすればエラーなくGitHub上にコードが反映される．

```:command-line
$ git remote add origin https://<sub_username>@github.com/<sub_username>/my-page.git
$ git push -u origin master
[...]
To https://github.com/<sub_username>/my-page.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
```
ただし，一度以下のコマンドを入力するとエラーが起きる．

```:command-line
$ git remote add origin https//github.com/<sub_username>/my-page.git
$ git remote add origin https://<sub_username>@github.com/<sub_username>/my-page.git
fatal: remote origin already exists.
```
これは`origin`を一度削除すると解決する．

```:command-line
$ git remote rm origin
$ git remote add origin https://<sub_username>@github.com/<sub_username>/my-page.git
$ git push -u origin master
[...]
To https://github.com/<sub_username>/my-page.git
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
```
DB(MySQL)から、さらっとデータを取得したい

# pythonスクリプトを起動するだけで、DBからデータを取得できるようにしたい。それも簡単に
最近仕事の終わりに広告活動の一環で会社のTwitterに投稿する業務？をしている。私が主にやるのは定型文のツイートだが、そこに載せるデータは毎日変わるため毎回データを手動で参照してツイートを作って投稿してきた。

いや、Botにしろよ・・・。という指摘はもっともだが、やったことないしプロジェクト３つくらい走ってるし、ぶっちゃけコードを書く時間が取れない。

DB周りの接続の仕方さえわかればこっちのものなのでお家で勉強がてら調査してみることにした。

とりあえず、第一段階として、自動で文を生成するようにしたい。そのためにはDBから最新のデータを取得したい。


# 環境
* MacOS Mojave
* python 3.7.3
* mysql-connector-python 8.0.16

# mysql-connector-python のインストール

今回は難しいことせずに、さらっとDBから値を取得するのが目的なので簡単そうだった、[mysql-connector-python](https://pypi.org/project/mysql-connector-python/)を使う。

```bash
$ pip install mysql-connector-python
```

上記ではpipでインストールしたが、私はPyCharmを使っているので

Preferences > Project:yourappname > Project Interpreter > (左下の+ボタン)

から上記packageを検索してinstallして使っている。

## ソースコード

```python:test.py
import mysql.connector


def main():
    connection = mysql.connector.connect(
        host='0.0.0.0', # 接続先
        port='3306',
        user='username', # mysqlのuser
        password='password', # mysqlのpassword
        database='databasename', 
        use_pure=True,
    )

    # コネクションが切れたときに再接続してくれるように設定
    connection.ping(reconnect=True)

    # 接続できているかの確認
    print(connection.is_connected())

    cur = connection.cursor()

    cur.execute("SELECT * from test_table")

    # 全てのデータを取得
    rows = cur.fetchall()

    for row in rows:
        print(row)

    # DB操作が終わったらコネクションを閉じる
    cur.close()
    connection.close()


if __name__ == '__main__':
    main()

```

### 結果
テスト用に作ったDBから値を取得できていることが確認できた

```bash
$ python test.py
(1, '山田太郎', None, None)
(2, '山本太郎', None, None)
```

ここまでできれば、自動化もすぐできそう。

## 参考
* https://basicincome30.com/python3-mysql-connector
* https://stackoverflow.com/questions/53385113/django-db-utils-operationalerror-2026-ssl-connection-error-ssl-ctx-set-tmp
v4.0.0 対応: 5分でデスクトップ版のSlackにDark Themeを適用する（Windows版）

#はじめに

**重要 v4.0.1からこの方法は使えなくなりました。正常に動作しなくなりますのでご注意ください。白背景眩しいよ:sob:**

@kazuki1213さん、@shokenさん、@taiponrockさん、分かりやすい記事に感謝します。

#環境
Windows 10 64bit
Slack v4.0.0

#背景
@shokenさんと同じく@kazuki1213さんの[5分でデスクトップ版のSlackにDark Themeを適用する](https://qiita.com/kazuki1213/items/bfc85bc847caa1617c18) を参考に黒背景で快適にSlackを使っていましたが、ある日突然白背景に変わっており、「アップデートが来たんだな。また@kazuki1213さんの記事を元に黒背景にしなきゃ」と思いましたが、該当の場所にssb-interop.jsがなく、困っていたところに@shokenさんの[v4.0.0 対応: 5分でデスクトップ版のSlackにDark Themeを適用する](https://qiita.com/shoken/items/4f0bbba9b5d911657b5a)を見つけ、Windows環境で作業しました。
Windows環境用にコマンドなど書き直しましたのでご参考までに。

#Windows版Slack v4.0.0にDark Themeを適用する
##1.Windowsにnpmをインストールする
@taiponrockさんの[Node.js / npmをインストールする（for Windows）](https://qiita.com/taiponrock/items/9001ae194571feb63a5e)を参考に作業しました。

##2.asar コマンドをインストールする
```
npm install -g asar
```

##3.Slack.app から app.asar , app.asar.unpacked をコピーする
```
mkdir tmpslack
copy C:\Users\ユーザ名\AppData\Local\slack\app-4.0.0\resources\app.asar tmpslack
xcopy /e C:\Users\ユーザ名\AppData\Local\slack\app-4.0.0\resources\app.asar.unpacked tmpslack\app.asar.unpacked\
```

##4.asar を展開する
```
cd tmpslack
asar extract app.asar app
```

##5.ssb-interop.bundle.js の先頭に以下を挿入
メモ帳でssb-interop.bundle.jsを開く

```
call notepad.exe app/dist/ssb-interop.bundle.js
```

```ssb-interop.bundle.js
document.addEventListener('DOMContentLoaded', function() {
  $.ajax({
    url: 'https://cdn.rawgit.com/laCour/slack-night-mode/master/css/raw/black.css',
    success: function(css) {
      $("<style></style>").appendTo('head').html(css);
    }
  });
});
```

##6.asar を作成する
```
asar pack app app.asar
```

##7.作成したapp.asarを元のSlackのフォルダに上書きする
```
copy /y app.asar C:\Users\ユーザ名\AppData\Local\slack\app-4.0.0\resources\
```

##8.動作確認する
Slackを起動して黒背景になってるか確認する

##9.一時作業用に作成したフォルダを削除する
```
cd..
rd /s /q tmpslack
exit
```

##10.Have fun :)
Herokuにデプロイしたcreate-react-appに環境変数を設定する

`create-react-app` と [create-react-app-buildpack](https://github.com/mars/create-react-app-buildpack) を組み合わせるとHeroku上に簡単にReactアプリケーションをデプロイすることが出来ます。
ただ、SPAのWEBアプリケーションは必ず外部サーバーとの接続を行う必要があり、サーバーの接続先URLを記述する必要があります。
環境依存情報なのでコードに直接記述することはできないのでビルド時やデプロイ時に埋め込む、もしくは起動時に反映する必要があります。
ここではHeroku APPの環境変数を利用したユースケースを紹介します。

## Heroku APP の環境変数設定
[ create-react-app-buildpackのドキュメント](https://github.com/mars/create-react-app-buildpack/blob/master/README.md#user-content-set-vars-on-heroku) に記載されていますが、Heroku APPに環境変数をセットするだけです。
なお、反映されるのはReactの仕様から `REACT_APP_`　という接頭辞の値だけになります。

### Heroku APP の環境変数設定例
![環境変数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/d73edffc-5993-a3ab-7dd3-2c169c7c36f4.png)

## Reactの表示とサンプルコード
設定した環境変数は　`process.env.X` で参照するだけなのですが、参考までにサンプルコードと表示例を紹介します。
なお、 `NODE_ENV` は自動的にセットされます。

### サンプルコード
```js
import React from 'react';

class EnvironmentForm extends React.Component {
  render() {
    return (
      <div style={{marginLeft : '20px', width: '600px'}}>
        <h2 style={{marginBottom : '5px'}}>環境変数</h2>

        <div style={{marginLeft : '5px'}} className='enclosed-area'>
          <div style={{marginBottom : '10px'}}>
            <b>process.env.NODE_ENV:</b> {process.env.NODE_ENV}
          </div>

          <div style={{marginBottom : '10px'}}>
            <b>process.env.REACT_APP_API_URL:</b> {process.env.REACT_APP_API_URL}
          </div>

          <div style={{marginBottom : '10px'}}>
            <b>process.env.REACT_APP_X:</b> {process.env.REACT_APP_X}
          </div>

          <div style={{marginBottom : '10px'}}>
            <b>process.env.REACT_APP_Y:</b> {process.env.REACT_APP_Y}
          </div>
        </div>
      </div>
    );
  }
}

export default EnvironmentForm;
```

### 表示例
![react.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/106217/a1499a5f-7509-8f42-117a-f3c779d741cc.png)
PHPでSSHをバックグラウンドで実行、停止

# はじめに
PHPで踏み台通してMySQLに接続する際にやったこと。
PECLだと専用関数あるらしいが、ない環境だったためシェルつかってバックグラウンドでやることに。

# バックグラウンド実行
変数に格納しているのは、停止のときに使うためです。

```php:php
$cmd = "ssh -f -i /tmp/key.txt ssh_user@host_name";
exec($cmd);
```

## オプション

- [ -f ] バックグランドで実行する
- [ -i ] 秘密鍵を使用する

# バックグラウンドの停止
さっきのコマンドを元にPIDを取得して、killする。

```php:php
//開始時に使ったコマンドを元に調べる
$_cmd = "ps aux | grep '[0-9] ".$cmd."' | awk '{print $2}'";
exec( $_cmd ,$output ,$return_var );

//$ouput[0]にPID入っているのでkill
exec('kill '.$output[0]);
```
Windwos10 で ADALM2000 を使ってみる

ADALM2000 は，アナデバの出しているUSB接続の測定モジュールです．カタログを見る限り，機能的には Analog Discovery 2 とほぼ一緒のようですが，値段が1万円ちょいとだいぶお安くなっています．また，どうもリモートでも制御できそうな気配．

箱を開封したところ，中に入っていたのは本体とUSBケーブルとリボンケーブルのみ．マニュアル類は一切なしというシンプルなパッケージです．制御ソフトを入れたかったのですが名称もわからず，しばらく悩んだあげく[秋月の通販ページ](http://akizukidenshi.com/catalog/g/gM-14068/) を見たところあっさり解決．Scopy という名前だそうで，ちゃんとリンクが張ってありました．[Scopy Wiki](https://wiki.analog.com/university/tools/m2k/scopy) を読みながら進めていけばよいようです．

Scopy for Windows をインストールしてPCを再起動したのですが，ADALM2000 が認識されませんでした．が，よく [Scopy Wiki](https://wiki.analog.com/university/tools/m2k/scopy) を読んでみると，

>In order to have Scopy working with ADALM2000 please make sure that the Device Drivers are installed. A guide on this topic can be found in the section: 
> ADALM2000 for End Users.

ということでした．[ここ](https://wiki.analog.com/university/tools/pluto/drivers/windows)からデバイスドライバをインストールすると，無事認識されました．

めでたしめでたし．

ちょっと触った感じだと，Analog Discovery のほうが使いやすい（というか測定器に近い）感じがしていますが，そのあたりは追い追い．
Ruby yieldとは

## yieldとは
ブロック付きメソッドでブロックを呼び出すことができます。

## ブロックとは
do~end や {} で囲まれた処理のかたまり
以下の処理だと「puts i」の部分をブロック
「|i|」をブロックパラメータと呼ぶ

```rb
(1..10).each do |i|
  puts i
end
```

## 例1
ブロックを実行する

```rb
def hoge
  yield
end

hoge do
  puts "^o^"
end

=>^o^
```

```rb
def fuga
  yield
end

fuga{
  puts ";o;"
}

=>;o;
```

## 例2
yieldを複数回記述すると複数回実行される

```rb
def hogehoge
  yield
  yield
end

hogehoge do
  puts "hoge"
end

=>hoge
  hoge
```

## 例3
ブロックなしでyieldを利用した場合

```rb
def fugafuga
  yield
end

fugafuga

=>LocalJumpError (no block given (yield))
```
Githubでファイルを開く、該当行のPullRequestを開くRubyスクリプトを作った

## 背景

業務で下記のようなことをしたい！、というような場面ってありませんか？

- 今エディタで開いているファイルをGithub上で開きたい
- 今エディタで見ている行を変更したPullRequest（以下PR）を確認したい
  - PRを確認しないと、なぜそういう変更になったのか等の背景が分からないですよね
  - PRが分かれば、だいたい元issueにもたどり着けますよね

VSCodeだと簡単にGithubに飛べますよね。
しかし、私は普段Emacsを使用しているのです。
Emacsでも同じようなことがしたいと思い、ネットの情報を参考にさせていただきながらスクリプトを作りました。

本当はEmacsLispで作ろうと思ったのですが、~~妥協して~~ Rubyで実装しちゃいました。

以下その紹介です。


## ソース

https://github.com/ckona/gh_operation

## 使い方

READMEに書きましたが改めて説明を。

### Githubでファイルを開く

```
$ ruby open_file_on_gh.rb <file_path> <line_number>
```

`open_file_on_gh.rb`

- 第一引数: Githubで開きたいファイルのパス
- 第二引数: 行番号

これで、Githubでファイルが開けます。

### GithubでPRを開く

```
$ ruby open_pr_on_gh.rb <file_path> <line_number>
```

`open_file_on_gh.rb`

- 第一引数: 対象のファイルパス
- 第二引数: 行番号

これで、対象ファイルの該当行を変更した直近のPRが開けます。

## Emacs側の設定

上記のスクリプトを任意の場所に置いて、それを呼ぶだけです。
私の場合、Git系はhydraで `M-g` に設定してあるので、
`M-g o` でファイルをGithubで開く、
`M-g P` でPRを開く、
というようにしています。

```elisp
(defun open-file-on-github ()
  (interactive)
  (shell-command (concat
                  "ruby ~/projects/gh_operation/open_file_on_gh.rb "
                  buffer-file-name
                  " "
                  (number-to-string (line-number-at-pos)))))

(defun open-pr-on-github ()
  (interactive)
  (shell-command (concat
                  "ruby ~/projects/gh_operation/open_pr_on_gh.rb "
                  buffer-file-name
                  " "
                  (number-to-string (line-number-at-pos)))))
```

## コードの大まかな内容

### open_file_on_gh.rb

- 対象ファイルがあるディレクトリを取得し、そのディレクトリに移動する
- そこで `git remote get-url origin` コマンドを実行し、Githubのアカウント名、リポジトリ名を取得する
- 対象ファイルのrootディレクトリ（Railsでいうと `Rails.root` ）を取得し、pathを作成する
- 作成したパスを `hub` コマンドで叩く！

### open_pr_on_gh.rb

- 対象ファイルがあるディレクトリを取得し、そのディレクトリに移動する
- そこで `git remote get-url origin` コマンドを実行し、Githubのアカウント名、リポジトリ名を取得する
- `git blame` コマンドを駆使し、コミットハッシュを取得する
- `git log` コマンドとコミットハッシュを駆使し、PRの番号を取得する
- Githubアカウント名、リポジトリ名、PR番号を元にURLを作成
- そのURLを `hub` コマンドで叩く！

## 注意点

- `Ruby` がインストールされていることが必須
- `hub` コマンドがインストールされていることが必須
- 行番号の指定によっては開かない。。
- `https` プロトコルだと動かない

ナドナド

## あとがき

時間あるときに、`git blame` で何をしているのか等、コードの詳細の追記をしたいと思います。
ちなみに、このスクリプトを呼ぶだけでなので、Vimでも使用できると思います。

## 参考

https://blog.shibayu36.org/entry/2018/05/08/193000
ML-AgentsのデモはUnity 2017.4.**じゃないとダメっぽい件

# はじめに
当初はML-Agentsを使ってUnity × 強化学習を学ぼう！って
息まいてたけど、ハマリにはまってようやく解決したので
タイトルを変えて今後のためのメモとして残す。

# 結論
ML-Agentsのデモは、Unity 2019.1.10f1（2019/7/24時点最新）だと動作しないため
デモを試したいなら2017.4.30f1（2019/7/24時点でとれたバージョン）で起動する必要がある。
結構Unityのバージョンも気を付けないといけないんだなぁ…と
ブログ書いてる人が頻繁にバージョンを書いて解説しているのはこういうことなのか…と
色々と勉強になった。

2019/7/25追記：
最新のUnityでもデモが実行可能とのこと。
ひょっとしたらバージョンが問題ではなく別の要因かもしれない。。。というメモ残します。
（nosadaMCさん情報ありがとうございます）

# とってきたデモのファイル
https://github.com/Unity-Technologies/ml-agents/blob/master/docs/Installation-Windows.md
に記載のリンクからzipでもらった。

直リンクはコチラ。
https://github.com/Unity-Technologies/ml-agents/archive/master.zip
解凍して、ローカルに保存した。

# で、どんな感じに失敗するのか？について

まずは、Unity 2019.1.10f1をNewProjectで起動。
File > Open SceneでデモのSceneファイルを開く。
↓↓実際に開いたファイルがコレ。
C:\Users\watya\ml-agents-master\UnitySDK\Assets\ML-Agents\Examples\3DBall\Scenes\3DBall.unity

Scene開いた直後の画面がコレ。すでに真っ赤なエラーログが出てる…

![コメント 2019-07-23 235900.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/c63724cb-0b10-c365-9ea8-524facf2e058.gif)

再生ボタンを押した結果がコチラ。
残念なくらいボードが動かないし、ボールもポロリと落ちて終了。。。

![ML-Agents失敗.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/ba445d2a-1266-74ac-a916-01da240bc54c.gif)

# うまくいったらどうなるの？

こちらは、
C:\Users\watya\ml-agents-master\UnitySDK\Assets\ML-Agents\Examples\3DBall\Scenes\3DBall.unity
をダブルクリックして起動。
起動待ち中に↓↓のウィンドウが出る。のでContinueをクリックすると
保存したときのバージョン（2017.4.30f1)で起動してくれる。
![コメント 2019-07-23 235637.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/d989d4bd-2ccc-4136-b38e-90c6f1e837dd.gif)

起動直後の画面がコチラ。
エラー一つなく起動してくれた。いい感じ。
![コメント 2019-07-23 235058.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/88603ef0-a05f-4dea-dd7a-255f6de65904.gif)

再生ボタンをクリックした結果がコチラ。
プルプル震えながらボールが落ちないように頑張ってる。
コレコレ！この結果が欲しかった！
![ML-Agents成功.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/17de2225-5858-0c80-d7cf-9dbdc27d2f8f.gif)

# 反省点
今振り返ると、アセットをインポートしたときもなんか似たようなウィンドウが出ていたのを思い出した。
バージョンがどうとかこうとか。最新のバージョンは互換性あるからうまくいくっしょ！
なんて感じでごり押してたけど、やっぱりよくないんだね、反省。。。
次回は改めてML-Agentsの良さを確認する検証がしたい。

# おわりに
Unityの結果は動いてなんぼ！ってのもあり、ついに重い腰を上げて
gif動画作成ツールを使って動画も残すようにした。
それにしても今はいいツールがあるもんで、ほんと作りやすかった。
せっかくなので紹介。

ScreenToGif 2.18
https://all-freesoft.net/mm9/animationcapture/screen-to-gif/screen-to-gif.html

とっても役に立ちました。作ってくれた人サンキュー！
DateTime項目を含むJSONシリアライズ


# 例えば

```csharp
public class Master {
	public Master(string ID, string Name, DateTime Join) {
		UserID = ID;
		UserName = Name;
		Joined = Join;
		Leaved = DateTime.MinValue;
	}

	public string UserID { get; set; }

	public string UserName { get; set; }

	public DateTime Joined { get; set; }

	public DateTime Leaved { get; set; }
}
```

こんなクラスがあったとしましょう。
ぶりぶりに使い込んで良い感じのシステムの一部として組み込まれていると思ってね。

# ところで

諸々の要件が上がってきて、CS間でJSONデータのやり取り、ってのが必要になったとするじゃないですか―
　　　　　　　　　　　　**なったんですよ、いいですね？**

まぁ、MasterクラスをJSON対応すれば良いんですけど。
こんな感じに…

```csharp
[DataContract]
public class Master {
	public Master() { }

	public Master(string ID, string Name, DateTime Join) {
		UserID = ID;
		UserName = Name;
		Joined = Join;
		Leaved = DateTime.MinValue;
	}

	[DataMember(Order = 0)]
	public string UserID { get; set; }

	[DataMember(Order = 1)]
	public string UserName { get; set; }

	[DataMember(Order = 2)]
	public DateTime Joined { get; set; }

	[DataMember(Order = 3)]
	public DateTime Leaved { get; set; }



	public static Master CreateInstance(string json) {
		using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(json))) {
			DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(Master));
			return (Master)serializer.ReadObject(stream);
		}
	}

	public string Serialize() {
		using (MemoryStream stream = new MemoryStream()) {
			DataContractJsonSerializer serializer = new DataContractJsonSerializer(this.GetType());
			serializer.WriteObject(stream, this);
			return Encoding.UTF8.GetString(stream.ToArray());
		}
	}
}
```

# でも、落とし穴が

例えば、

```csharp
    Console.WriteLine(new Master("0000", "Toraja", DateTime.Today).Serialize());
```
みたいな感じでJSONが得られると思うじゃないですか、普通。
でもでも、

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136132/38714181-cddf-c0a9-ec40-ccb3905d79c7.png)

って怒られちゃいます。

あっちこっちでそういう状況が発生しているらしいので、皆さん解説して下さっていますので、詳しくはググってみて下さい。

一応簡単に言うと、DateTimeをシリアライズする際にその値をUTCに変換しようするんですが、その値がMinValueだった場合マイナス９時間した際にアンダーフローを起こす、と云う事らしいですけどじゃぁどうすれば良いんだよって感じです。

で、識者の意見によれば、JSONの定義にはDateTime型は含まれていないので、日付をJSONに入れたい場合には文字列として扱え！
と云うのが正論らしいです。

# どう対応するか

いやーでも、ぶりぶりに使い込んでるんですよ。
今更クラス定義のDateTimeをstring型に変更しちゃったら、影響範囲がどこにまで及ぶか…
<br>
って事で、考え方を反転させるのが良いのかなぁ、と。
こう云う感じ（着目部分だけ括り出しました）。

```csharp
	[IgnoreDataMember]
	public DateTime Joined { get; set; }

	[IgnoreDataMember]
	public DateTime Leaved { get; set; }

	[DataMember(Order = 2, Name = "Joined")]
	private string StringJoined {
		get { return $"{Joined:yyyyMMddHHmmss}"; }
		set { Joined = DateTime.ParseExact(value, "yyyyMMddHHmmss", CultureInfo.CurrentCulture, DateTimeStyles.None); }
	}

	[DataMember(Order = 3, Name = "Leaved")]
	private string StringLeaved {
		get { return $"{Leaved:yyyyMMddHHmmss}"; }
		set { Joined = DateTime.ParseExact(value, "yyyyMMddHHmmss", CultureInfo.CurrentCulture, DateTimeStyles.None); }
	}
```
内側のDatetime型のプロパティはJSONには出さないようにして、JSONに出す側のプロパティをprivateのstring型として新設します。序に名前をちょこっと変えといてあげればイイ感じかも…

で、結果は以下。

```json
{"UserID":"0000","UserName":"Toraja","Joined":"20190723000000","Leaved":"00010101000000"}
```

# あ、ひょっとして

グリニッジより西にある諸国では、こう云うややこしい目に合わないんだろうねぇ
きっと
【自分用メモ】Progate 3日目

# HTML & CSS 学習コース 初級編

進捗65%

### 学んだこと
- CSSでは各要素(\<h1>など)での表示の仕方を指定することができる。要素を「セレクタ」変更項目を「プロパティ」と呼ぶ
- CSSでスタイルの指定の仕方等
【golang環境構築】Modulesでpackage管理をする

[【golang環境構築】とりあえずhello worldまで](https://qiita.com/fox777/items/5decc35ef07df694e24c) の続き。

## goのpackage管理に何を使うか
2019年7月現在だとModulesで良さそう。
他の選択肢としては[dep](https://github.com/golang/dep)がありますが、Modulesはgo1.11から導入が開始され、go1.13にてデフォルトで有効になります。
今後はModulesが標準になっていきそうなので特に理由なければModulesでいきましょう。

## 使い方
[公式wiki](https://github.com/golang/go/wiki/Modules)

#### 1. GO111MODULEをonにする
公式ではGOPATHの外でやれ、と書いていますが、`$GO111MODULE=on`にしてやればGOPATH内でも大丈夫です。
ちなみにgo1.13ではデフォルトでonになります。

```:.zshrc

export GO111MODULE=on
```

#### 2. go mod init
プロジェクトディレクトリを作り、`go mod init`しましょう。
go.modが生成されます、npmでいうpackage.jsonです。

```
$ cd ~/workspace/go/src
$ mkdir hoge
$ cd hoge
$ go mod init hoge
```

#### 3. コードを書く

```
$ vim hello.go
```

```go:hello.go
package main

import (
    "fmt"
    "rsc.io/quote"
)

func main() {
    fmt.Println(quote.Hello())
}
```

#### 4. buildする
あとは`go build`でOK。
それだけで自動的にモジュールのダウンロードもやってくれます。
また、ここでgo.sumというファイルが生成されます、npmでいうpackage-lock.jsonです。

```
$ go build
$ ./hoge
こんにちは世界。
```
apt-get update時に「公開鍵を利用できないため、以下の署名は検証できませんでした」と出た場合

sudo apt-get updateをしたときに


~~~~
2,667 kB を 1分 3秒 で取得しました (42.2 kB/s)
パッケージリストを読み込んでいます... 完了
W: 署名照合中にエラーが発生しました。リポジトリは更新されず、過去のインデックスファイルが使われます。GPG エラー: http://packages.ros.org/ros/ubuntu xenial InRelease: 公開鍵を利用できないため、以下の署名は検証できませんでした: NO_PUBKEY F42ED6FBAB17C654
~~~~

と出た場合，公開鍵が足りていない．そのため
NO_PUBKEYの後の F42ED6FBAB17C654（これは人による）を以下のように追加してやれば良い

~~~
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F42ED6FBAB17C654
~~~

とコマンドを打って

~~~
sudo apt-get update
~~~

してやれば解決する．


参照記事
http://kowaimononantenai.blogspot.com/2013/06/w-gpg-httpppalaunchpadnet-lucid-release.html
BlenderPoly アドオンを Blender 2.8 対応するにあたって引っかかったところ

　Blender 2.8 の正式リリースが近づいて来たのを自作の [BlenderPoly](https://github.com/satoyuichi/BlenderPoly) アドオンを 2.8 に対応させました。その際に引っかかったところをまとめました。

# 参考になるドキュメント
- [Blender 2.80: Addon API
](https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API/Addons) ：公式ドキュメント
- [[Blender] Blender2.7xのアドオンをBlender2.8へ移植する](https://qiita.com/nutti/items/e86fd072c9500bc9345a)：@nutti さんによる日本語の丁寧な記事

# 対応差分
　今回の対応の差分は https://github.com/satoyuichi/BlenderPoly/pull/17/files の通りです。 2.8 対応とは直接関係ない部分や上記のドキュメントで済んでしまった部分に関しては割愛します。

## user_preferences の書き換え
　BlenderPoly の場合は API キーをアドオンの設定から保存できるようになっているのですが、それの保存先を `user_preferences` から `preferences` に書き換えました。

## .obj ファイルのインポート API の変更
　`bpy.ops.import_scene.obj()` のキーワード引数 `global_clamp_size` を `global_clight_size` に変更しました。

## アイコンの変更
　`SAVE_PREFS` アイコンが廃止されたようなので、 `PREFERENCES` に変更しました。適当なアイコンを探す際には `Icon Viewer` が便利です。アドオンを有効にして `Icon Viewer` ボタンをクリックします。
![スクリーンショット 2019-07-23 15.07.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13938/3c135586-4249-baa4-5a4f-99ec20dbf70b.png)

　するとアイコンが列挙されるので、それっぽいキーワードで絞り込むか、適当なアイコンをクリックして名前を調べましょう。

![スクリーンショット 2019-07-23 15.09.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13938/737c380f-1887-e082-bf49-97824d329913.png)

# まとめ
　こう書いてみると大したことやってないですね…。時間を取られたのはむしろ既出のもので、単純に自分が読み落としてただけというものが多かったです。(`bl_region_type = 'TOOLS'` を `bl_region_type = 'UI'` にするとか)
Azure DevOps Pipelines(パイプライン)の超概要

Azure DevOps全体の概要については、こちらをご覧ください。
https://qiita.com/mstakaha1113/items/1cf45a5119e1397d0315

"Pipelines(パイプライン)"は、生産物を成果に変換するサービスです。
DevOpsを実施するなら要となるサービスですし、アジャイル開発を支えるテクノロジーでありウォーターフォール開発であってもぜひご利用いただきたいサービスです。
サービスとして何があるのかご紹介します。
超概要なので、具体的な画面の説明はありません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/69b23d00-b1c2-b60d-c3b3-35741bd0f711.png)

# "Pipelines" のメニュー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/831f4651-53a9-5f60-3d60-b5444b5da5b6.png)

かなりザックリした説明になります。あえて抽象的な言葉で説明しています。

- Builds : デスクトップアプリケーションならexeを作るまでの作業です。Javaアプリケーションなら例えばjarファイルに梱包するまでの作業です。PCを準備して必要なライブラリをインストールし、ソースコードを持ってきてビルドします。必須ではありませんが（DevOpsでは本来必須ですが）、ここで単体テストや結合テストも自動化して実施します。
- Releases : デスクトップアプリケーションならインストーラー作成およびインストール、JavaのWebアプリケーションならWebサーバーを準備してミドルウェアをインストールしてjarファイルを展開するまでの作業です。Azureですと例えばWeb AppsというPaaSのWebサービスを作成し、そこにBuildsで作成した生成物を展開する作業を実施します。
- Library : アプリケーションを展開していく際に、必要だけど色々な人に見られたら困る値というのがあると思います。そのような値をここに登録していきます。
- Task groups : BuildsやReleasesは、現実問題として何度も同じ設定を書き込むことが多くあります。例えば開発と検証と本番という環境に対してデプロイ先は異なるけど実施する作業は同じというような状況です。このようなタスクは何度も同じ設定をしなければならないという問題もありますが、それ以上に変更が入った際に同様のタスクに対して展開漏れが起こるという問題があります。このような問題を回避するため、そのようなタスクをTask groupsに登録して、これを全環境で使いまわします。Task groups上のタスクへの変更は、それを利用しているすべてのBuildsやReleasesに適用されます。（が、最初から使うことは少ないと思います。）
- Deployment groups : Releasesの展開先が複数存在する場合(例えば複数のVirtual Machine)に、それらを１つのグループとして登録しておく機能です。Releasesでは、ここで登録したデプロイメントグループに対してのリリースタスクを一括実行させることができます。（が、あまり使う機会はないと思います。）

# Pipelinesの機能は大きく分けて２つ、CI(継続的インテグレーション)とCD(継続的デリバリー)

Pipelinesは、いわゆるビルド職人やデプロイ職人、マニュアル作業の自動化とお考え下さい。
システム開発をしていると、以下のようなことが起こります。

- わたしのパソコンではビルドできる
- リリースが近づくバタバタしたときに限ってビルド専用PCが壊れる
- Aさんがいないとどのライブラリを使うのかわからない
- マニュアル通りにやってもうまくいかないがBさんが夜中にデプロイするとキレイに本番リリースできる
- 新人がマニュアル通りにデプロイするという慣例がある

これらは概ね不必要なコストや管理できるリスクです。
必要な時に最新の環境でビルドしてテストして利用可能であることが証明されるとしたらいかがでしょうか？それも毎日。
誰も冷や汗をかくことなく、適切なタイミングで適切な機能を本番リリースできたらいかがでしょうか？それもなんだったら毎日。
このようなことを実施するのが継続的インテグレーション(CI : Continues Integration)と継続的デリバリー(CD : Continues Delivery)です。

## CI : Continues Integration
必要とあればソースコードがリポジトリに反映される度に、そのソースコードの確からしさを機械的に確認するのがCIです。
Azure DevOps のPipelinesではBuildsが担当します。
登録されたパイプラインを"Build Pipeline"と呼びます。
CIでは、主にビルドとテストを実施します。ビルドするためには対象となる環境が必要ですので、環境準備をします。
ビルドすればコンパイル時のアラートやエラーを検知できます。また自動化されたテストを準備していれば、ここで実施が可能です。

## CD : Continues Delivery
コンパイルしテストが終わっている"機械的には文句のつけようが無い"生産物を、実際に稼働する環境にデプロイ（配置）するのがCDです。
Azure DevOps のPipelinesではReleasesが担当します。
登録されたパイプラインを"Release Pipeline"と呼びます。
CDでは、主にデプロイを実施します。デプロイするため、必要に応じてデプロイ先の環境を構築します。
デプロイしてしまえば、その環境を使って例えば人間が受け入れテストを実施することができます。また場合によっては負荷テストの実施が可能です。

# まとめ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439826/d3b16f09-99a5-ca8a-3598-c5b9c0503115.png)
Pipelinesをうまく利用することで、いつも正しく動作するものを具体的に作成する、いつも正しく動作する環境を具体的に作成することができます。
要不要にかかわらず、これが存在することは大切です。チカラを発揮するのは問題が起きた時です。問題が起きた時、昨日組み込んじゃった問題であればエンジニアの記憶にある内容ですし、その問題に引きずられるソースコードも少なくて済みます。
結果としてエンジニアもマネージャーもユーザー(プロダクトオーナー)もエンドユーザーもハッピーになります。
Qiitaで1日1投稿を1ヶ月実践してみて

#はじめに
この記事は、アウトプットとしてQiitaに1日１投稿した結果、自分自身にどんな変化があったのかを記録したものです。
(投稿期間は、2019年6月24日〜7月23日です。)
そもそもなぜ1日1投稿しようと思ったのかというと…今までアウトプットがほぼ皆無だったからです。
数ヶ月前に未経験からエンジニア転職し、日々膨大なインプット量にあたふたしていました。
しかし膨大なインプット量に追われ、浅くなんとなく調べて次！みたいなことをしてしまっていたのです:scream:
その為、次に同じ内容に直面した時に、当然**忘れているし根本までしっかり理解が出来ていない**ことに何度も気が付きました。
そこで危機感をもち、アウトプットの重要性に目を向けた結果Qiitaに辿り着いたのです。
なぜその中でQiitaへの投稿をアウトプットとして選んだのか。それは以下の点に魅力を感じたからです。

**●Qiita自体が集客力のあるサイトであり、フィードバックが得られやすい**
**●多くの人に見られる環境だからこそ適当なことは書けないので、しっかり調べる癖がつく**
**●投稿した内容は、自分自身のメモとしても管理しやすい**

そして6月24日、twitter上で宣言します！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419062/0f57f289-1272-9ebd-80a6-261828bec188.png)

自分自身を甘やかさない為にあえてフォロワーさんに宣言しました！これで後には戻れません。
とりあえず勢いだけでスタートした1日１投稿ですが…
**無事に1ヶ月間継続することができました！**

そしてこの経験で得たものを以下にまとめます！

#やってみて良かったこと
##①深掘りして調べる力がついた！
わからないことがあった時にどこまで調べていますか？
特に学習をはじめたばかりの方にありがちですが、
***調べてみて解決できそうなコードがあったからとりあえずコピペ！***
***めんどくさいから詳しい内容はあとででいーや！***
てな感じで、とりあえずエラーを解決して満足していませんか？
でもこれでは根本で理解できていないので、次同じエラーが出た時にまたわからない状態になると思います。

こういったわからない内容を、"Qiitaに投稿する"ようにしたことで、
どんどん深掘りして調べるので幅広く知識もつくし、自分で文章に起こした分確実に覚えます！
Qiitaは自分だけが見るものではなく、他人も見るものです。
いい加減なことは絶対に書けないので、投稿内容に関してとことん調べ尽くします。

##②わかったようでわかっていなかったことが浮き彫りに！
わからないと感じていたことだけではなく、**ある程度理解をしていると思っていた知識**に関してもアウトプットしてみました。
しかしわかっていると思っていたはずが、**文章で説明しようとすると全然うまくいかない**んです！
つまりは、①と同じですが、**ちゃんと理解できてなかった**ということ。
これに気が付けたのも大きなメリットでした！
今までの知識をブラッシュアップ出来たのと同時に、やはり調べ方の甘さを痛感できました。

##③見てるよ！の言葉やファボでモチベーションがUP！
投稿を始めた当初は特に、全然投稿慣れもしていないし、文章力もデタラメでした。
その状況であるにも関わらず、強メンタルな私は、１投稿目からtwitterに毎日投稿記事を載せていました。
そんな中、フォロワーの皆さまにファボやコメントで応援して頂いたり、インプットとして活用してくださる方がいらっしゃったり。
これがすごく励みになり、そしてアウトプットのやりがいを感じることができました。
最初は私自身の為に行なっていたアウトプットですが、**少しでも他の方の役に立てていることが嬉しかった**です。

##④プライベートでの学習時間の確保が定着化した！
勤務後はたまにだらけて全く勉強しない！なんてことが何日も続いていたりしたのですが、
退勤後も、Qiita投稿のために（半強制的にですが）勉強するというライフサイクルが確率されました。
そして1ヶ月続けるともはや普通のことであり、勉強全くしない日の方が違和感な状態になりました。

##⑤間違った内容は指摘してもらえる！
もちろん間違った内容を投稿するのはダメです。
しかしちゃんと調べたつもりでも認識が違っていたり…ということが何回かありました。
その度にコメントでご指摘頂いたり、また追加の知識を投稿してくれる方もいらっしゃり、自分の誤った知識の修正にも役立ちました！

#最後に
###1日1Qiitaはやはりとても大変でした(笑)###
記事を作成するのに、どれだけ早くても1時間はかかっていました。
それを毎日継続するのはやはり大変。
とても疲れた日や急に飲み会が入った日など。何度挫折しようと思ったことか。笑
でもtwitterで宣言したおかげでしっかり自分の甘さを制御でき何とか達成できました！
1日1Qiitaとはいかなくても、１週間1Qiitaでも良いかもですね！



###そして何より、大変だったけど確実に成長できました！###
1ヶ月続けてみて、上記であげたたくさんのメリットを実感できました。
実際にこの1ヶ月で自分自身が成長出来た実感がとてもあります。
なのでやってよかった。頑張った自分を褒めたいです。笑

皆さんもぜひ、1日１投稿までいかなくても定期的にQiita投稿でアウトプットしてみてください！
時間をかけた分必ず知識は定着しますよ:relaxed:

今後はアウトプットの方向性を、オリジナルのサイト作成の方に注力していきたいので、毎日投稿はやめます。
しかし、必要だと思う内容は積極的に投稿していきたいと思います。
そして今まで投稿してきた内容をもう一度見直して、もっとわかりやすい文章だったり追加知識を肉付けできればなと考えています:woman_tone1:

そして最後に！応援して頂いた皆さん、本当にありがとうございました！
皆さんのおかげでモチベーションがとても上がり、継続できたと思っております:relaxed:
Auth0のデフォルトのトークンの生成アルゴリズムはHS256なので注意

## Auth0のデフォルトのトークンの生成アルゴリズムはHS256なので注意
タイトルの通りです。GoogleのOauthの場合はRS256なので注意してください。

この記事が参考になれば幸いです。
## 終わりに
私は現在、Web3のサービスの開発をしています。詳しくはこちらの記事をご覧下さい。
        [無料でイーサリアムが当たる、Web3時代の寄付サイトを作った話](https://note.com/kenroda/n/n814347fbdcd7)
LTC1660CNをArduinoで動かす

[秋月電子で購入したDAコンバータのLTC1660CN](http://akizukidenshi.com/catalog/g/gI-02794/)のArduino MEGAからの使い方のメモです。
多分MEGAじゃなくとも大丈夫でしょう。

**僕の状態：**
DAコンバータの初心者
ビット演算わからない→[ここ調べながら](https://www.sejuku.net/blog/24512#ltlt)
マイコン間のシリアル通信をするのは初めて

**本記事の内容：**
下記の参考記事の内容を元に、LTC1660CNの出力をArduino IDEのシリアルモニタの入力から自由に変えられるようになることを目指します。

**参考記事：**
[LTC1660CN (軍鶏乃記録)2012.6.18](https://hiyohiyo.blogspot.com/2012/06/ltc1660cn.html)
[A Library for LTC1665/LTC1660 (Kerry D. Wong)2010.5.2](http://www.kerrywong.com/2010/05/02/a-library-for-ltc1665ltc1660/)

# どんなコードでDACは動かせるのか
[Kerry D. Wangさんの記事](http://www.kerrywong.com/2010/05/02/a-library-for-ltc1665ltc1660/)にはこのようなコードが載っていました(一部抜粋)。

```cpp:
// Kerry D. Wang氏のコードより一部抜粋
// http://www.kerrywong.com/2010/05/02/a-library-for-ltc1665ltc1660/
// コメントの和訳:みくに（訳は1660バージョン、意訳）
// コメントの追加:みくに


// デジタルアナログ変換を行わせる
void output(long chn, long val)
{
  // 16桁のビット列を送る
  // 上位４桁は出力を行うDACのアドレス
  long t = chn << 12; // 16桁のうちchnの4桁を先頭に置く（シフト演算で後ろに１２桁の'0'を加える）
   
  //下位２桁は無視するのでシフト演算で'0'を後ろに２つ加える。
  t = t | val << 2;
  
  // ここからデータの転送をするためのコード
  digitalWrite(pinCSLD, LOW); // どうやらpinCSLDをLOWにすると転送を開始するらしい。
  for (long i = 15; i >= 0; i--)
  { 
    long b = (t >> i) & 1;
    digitalWrite(pinIN, b);
    digitalWrite(pinSCK, HIGH); // どうやらpinSCKがHIGHになった時のpinINを読み取るらしい
    digitalWrite(pinSCK, LOW);  
  }
   
  digitalWrite(pinCSLD, HIGH); // どうやらpinCSLDをHIGHにすると転送を終了するらしい。
}
```

SPI通信がどのような手順で行われているか、僕の推測でコード内にコメントを追加しました。
（間違いがわかり次第、修正していきます。）

それを用いてloop(){}の中にプログラムを実装していけばLTC1660CNを動かすことができるみたいです。

コードを読解して初めて、[データシート](http://akizukidenshi.com/download/ltc1660cn.pdf)８ページ目のTIMING DIAGRAM(下図)の意味が理解できました。
[<img width="773" alt="スクリーンショット 2019-07-23 21.54.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209959/51d27bab-8ffc-a91f-4a8e-f6e5f5ba8b39.png"><br>Linear Technology LTC1665/LTC1660 data sheet](http://akizukidenshi.com/download/ltc1660cn.pdf)


# シリアルモニタから入力した数値を出力させる
[Kerryさんの記事](http://www.kerrywong.com/2010/05/02/a-library-for-ltc1665ltc1660/)のコードをそのまま実行するとchn=1,output=64/1024で出力されるようなので、とりあえず、そのまま書き込んで実行してみようと思います。配線は[Kerryさんの記事中の画像](http://www.kerrywong.com/2010/05/02/a-library-for-ltc1665ltc1660/)の通りにします。

またloop(){}内のコードは以下のように書きました。

```cpp
void loop()
{ // カッコ内のコードをKerryさんの記事のコードのloop(){}のカッコの中に書き入れた状態にする
  if ( Serial.available() > 0 ) {
  delay(20);
  deg = Serial.parseInt();
  }
  if ( deg > 0 && deg < 1024) // 0を除外したのは改行を区別して除外するのが面倒だったから
  {
    output(1,long(deg));
  }
  delay(1000);
  Serial.println(analogRead(pinAnalogOut));
}
```

これを書き込んでシリアルモニタを起動し適当な数字を入れてみます。
すると、だいたい近い値が検出されました。

入力値-3くらいの数値がシリアルモニタに表示されたので、だいたいうまくいっているはずです。
厳密にコントロールしたいときは1~1023を入れてそれぞれ出力値がどうなるか調べて対応関係を調べておくといいと思います。
laravel5.8のログをrsyslogで出力する

laravel5.8のログをrsyslogで出力するよう設定したのでメモ

##laravel側設定
laravel5.8では下記のログ出力方法が指定可能です。

| 名前 | 説明 |
|:-----------|------------:|
| stack | 「マルチチャンネル」チャンネルを作成するためのラッパー機能 |
| single | シングルファイル／パスベースのロガーチャンネル（StreamHandler） |
| daily | RotatingFileHandlerベースの毎日ファイルを切り替えるMonologドライバ |
| slack | SlackWebhookHandlerベースのMonologドライバ |
| papertrail | SyslogUdpHandlerベースのMonologドライバ |
| syslog | SyslogHandlerベースのMonologドライバ |
| errorlog | ErrorLogHandlerベースのMonologドライバ |
| monolog | サポートしているMonologハンドラをどれでも使用できる、Monologファクトリドライバ |
| custom | チャンネルを生成するため、指定したファクトリを呼び出すドライバ |


今回は下記のようにsyslogを設定します。

```config/logging.php
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            //'channels' => ['daily'],
              'channels' => ['syslog'],
            'ignore_exceptions' => false,
        ],
```

キャッシュをクリアします。

```
# php artisan config:cache
```


##rsyslog設定
rsyslogのルールは上から順番に読み込まれるため、RULESの一番上にルールを追記します。
下記の例では**programname**が**laravel**の場合**/var/log/laravel.log**に出力する事を意味します。
laravelのログのprogramnameはデフォルトでは**laravel**です。
また以降のルールでログが出力されないように**& stop**を使用しています。

```/etc/rsyslog.conf
#### RULES ####
:programname, isequal, "laravel" /var/log/laravel.log
& stop
```

最後にrsyslogを再起動します。

```
# service rsyslog restart
```

laravelのログが指定したログファイルに出力されるようになった。

```
# ls -l /var/log/ |grep laravel.log
-rw------- 1 root  root      891 Jul 23 23:05 laravel.log
```


（参考）Laravel 5.8 ログ
https://readouble.com/laravel/5.8/ja/logging.html

（参考）rsyslog のメモ
https://ngyuki.hatenablog.com/entry/2016/04/18/220724
Oracle FunctionsでTensorFlowによる画像分類

Oracle FunctionsでTensorFlowを使用して簡単な画像分類を実行します。

Oracle Functionsって？という方は[こちら](https://qiita.com/y-araki-qiita/items/f73f815ea60a93978cac)。

↓のフリーの猫の画像(cat.jpg)をファンクションで分類関数に渡してみます。
![cat.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/103ae580-4b72-d0d6-1077-85d2fa68dce3.jpeg)

## 前提
Oracle Functions開発、実行環境が構築されていること。
　⇒[・Oracle Functionsセットアップ](https://qiita.com/y-araki-qiita/items/d1ed0551d8943adc3bb5)

## ファンクションを用意
今回こちらを使用します。
https://github.com/abhirockzz/fn-hello-tensorflow

Oracle Functions開発用サーバにて作業します。

```
ソースをクローン
git clone https://github.com/abhirockzz/fn-hello-tensorflow.git

移動
cd fn-email-deliver
```

OCIコンソールでPhoenixリージョン、Oracle Functionsの画面に遷移します。
https://console.us-phoenix-1.oraclecloud.com/functions
Create Applicationより
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/51cd466f-543d-62cd-12e8-8779eee1aec6.png)
NAME: fn-email-app
VCN: Fn用に作成したVCN
SUBNETS: PHX-AD-1から3まで選択
上記で「create」を押します。

## デプロイ
```
※TensorFlowバージョン1.12.0を使用する場合
fn -v deploy --app fn-tensorflow-app

※TensorFlowバージョン1.11.0を使用する場合
fn -v deploy --app fn-tensorflow-app --build-arg TENSORFLOW_VERSION=1.11.
```

そして猫の画像(cat.jpg)をサーバまで転送します。

## ファンクション実行
```
cat.jpgをcatでファンクションに渡します。
# cat cat.jpg | fn invoke fn-tensorflow-app classify

すると↓と表示されました。
"This is a 'tabby' Accuracy - 67%"
```

tabbyって何？？？

そう思いネット辞書で調べてみると、
<img width="202" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/170634be-578f-3bbe-1a12-3cecb5dc927f.png">

すごいですね！ただの猫じゃなくて、とら猫ってところが。

こんなおもしろいこともOracle Functionsでできます。
今回は遊びみたいなもので、もう少し実用的なものも載せていきます。

## 関連記事
[・Oracle Functionsに関するメモ](https://qiita.com/y-araki-qiita/items/f73f815ea60a93978cac)
[・Oracle Functionsセットアップ](https://qiita.com/y-araki-qiita/items/d1ed0551d8943adc3bb5)
[・Oracle FunctionsでAPEXのRestful Serviceと連携](https://qiita.com/y-araki-qiita/items/03e67f5bca570c526a7c)
[・Oracle FunctionsでEmail Deliveryと連携しメール送信](https://qiita.com/y-araki-qiita/items/5a580bb739b37198300d)
[・Oracle FunctionsでObject Storage操作](https://qiita.com/y-araki-qiita/items/e55bfe111794feda7716)
[・Fn Project - Fn Server構築 (Oracle Linux7.6)](https://qiita.com/y-araki-qiita/items/e11369243723792d1a6e)
[・Oracle FunctionsでOCI Go SDKを使いインスタンス操作](https://qiita.com/y-araki-qiita/items/c927aea9e743a4468c61)
情シスもIT技術系コミュニティには参加した方が良いよなー

と呟いてみたら、思いのほか反響を頂きました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">SIerに限らず、社内SE(いわゆる情シス)もIT技術系コミュニティには参加した方が良いよなー、と思う。もはや、外注丸投げで何とかなる時代は終わった。自らも技術に積極的に関わって業務をすべきだと思うんですよね。 <a href="https://t.co/S2UCe5TUcH">https://t.co/S2UCe5TUcH</a></p>&mdash; Motuo@8/8は松戸でWatsonハンズオン (@motumotuo) <a href="https://twitter.com/motumotuo/status/1142744694767550464?ref_src=twsrc%5Etfw">June 23, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

私自身SIerから社内SEに転身した立場なので、何となく双方の気持ちがわかるような気がします。
折角なので、なぜ反響があったのか、自分自身の解釈をまとめてみました。
※あくまでも個人の見解です

## SIerの思い
それはそれは、情シスにはかなりの頻度で振り回されます。
要求が論理的に破綻していたり、過去の要求と異なる事を言われるのは日常茶飯事です。
しかも、言われてカチンとくるものの、自らも会社員である以上、正々堂々と喧嘩を買うこともできず…なんてことは私自身の経験としても身に覚えがありすぎるくらいあります:scream:

この原因として下記のことがあるのではないかと思います。

* 情シス自身、自分の言っていることが滅茶苦茶だということに気づいていない
* 気づいていても、結局は事業部門のユーザーの言いなり
* SIerはITに関して**スキのない**プロフェッショナルだという妙な思い込み<br>
    ※裏を返すと、システムの設計はSIerが全て提案すべきで、その責任はSIerが全て負うべきだという発想

SIerからすると、**「お前の会社の事だろ。丸投げせずにしっかりしろ！」**と言いたいシーンもあるのでしょう。
ただ、前向きに捉えるならば、技術系コミュニティに一緒に参加して技術のトレンドやアーキテクトをしっかり学んで**パートナー**として、良いシステムを作り上げていこうよ、という解釈もできるかもしれません。

## 情シスの思い
一方で、情シスだって当然ながらサボっているわけではなく、一生懸命に仕事をしているわけで…
この背景としては

* 情シスは全社から見ると明らかに異端。もはやオタク集団と思われている可能性もあり。故に業務を改革する権限などある訳もなく、エンドユーザーには逆らえない
* 基幹系システムのお守・パソコンのヘルプデスクなど、現行のシステムを動かすだけで手一杯。新しいことを学習する余裕がない。
* そもそも何を学習すべきかわからないし、モチベーションも上がらない

があると考えています。

[経産省のDXレポート](https://www.meti.go.jp/shingikai/mono_info_service/digital_transformation/20180907_report.html)には
> 我が国企業のIT関連費用の８０％は現行ビジネスの維持・運営（ラン・ザ・ビジネス）に割り当てられている。

だの

> 経営層の関与が薄く、改修して利用し続けた方が安全であると判断される割合が多い

という文言がありました。私個人の実感としても、割と妥当な見解なのではないかと思います。
情シスにも自社のIT環境に対して危機感を感じている方がいるのではないかと思います。
そのような方々の、**もっと技術を身に着けて、自分の会社を良くしたい**という声だったり、**技術を身に着ける有用性を経営層にもわかってほしい！**という思いがあったのかな、と勝手に解釈しています。

## 最後に
IT技術系コミュニティは技術に触れる機会であることはもちろんですが、SIerも情シスも飛び越えて色々な立場の人々が交わる機会があります。飛び込んでみると、自社に閉じこもっていては見えなかった知見が得られることは間違いないと思います。

技術系のコミュニティは一部のギークな人たちの物ではありません。一発で自分に合うコミュニティには出会えないかもしれませんが、情シスに属している方の拠り所となる場所はきっと存在するはずです。
はじめの一歩はハードルが高いかもしれませんが、勇気を出して一歩を踏み出すことをお勧めします。
AtCoderのページ遷移を簡単にするChrome Extensionを公開してみた

AtCoderの過去問を練習するときに、例えばひたすらD問題を解きたい時などがある。

しかし、AtCoder内では「次へ」のようなボタンが無いので、例えば132回のD問題（ https://atcoder.jp/contests/abc132/tasks/abc132_d ）の次に133回のD問題
のページへ行くためには、URLの数字を手打ちで132→133と変更してhttps://atcoder.jp/contests/abc133/tasks/abc133_d
にアクセスする必要があり結構面倒です。
※他の賢い方法があれば教えてください！

そのため、ボタン一つで次の問題に遷移できるChrome Extensionを作ってみた。
Next Page: https://chrome.google.com/webstore/detail/nextpage/mhhmddcnnehdkpclpjpmidpeejohlmfb

もしかしたら自分の他にも同じようなことで困っているかもということで、せっかくなので公開してみました。
もしご意見、要望等ありましたらコメントください。
mysqlの予約語に注意

あまり深く考えずにカラムを定義してしまっ。
そしたら今日シンタックスエラーで怒られた。
調べたら予約語だった。
本番稼働前でよかったー。

未経験のときにも予約語で怒られたのを思い出し、懐かしく思ったのでメモ

mysqlの予約語(バージョン5.6)
https://dev.mysql.com/doc/refman/5.6/ja/reserved-words.html


カラム名を変更するにはこちら
https://www.dbonline.jp/mysql/table/index18.html#section1

Laravelのmigrationを使う場合はこちら
https://readouble.com/laravel/5.5/ja/migrations.html
相転移・臨界現象, 宮下 精二, 2002

岩波講座-物理の世界 統計力学〈3〉相転移・臨界現象―ミクロなゆらぎとマクロの確実性, 宮下 精二, 2002
![51J47G565FL._SX322_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/3c648140-941c-fe1e-f3a3-5b3d365e5cee.jpeg)
https://www.amazon.co.jp/dp/4000111167/

#参考文献
###1
熱力学・統計力学

###2
熱力学の基礎
###3
熱力学
###4
統計力学
###5
熱・統計力学
###6
L.E. Reichl, A modern course in statistical physics, University of Texas Press, 1980
現代統計物理　上下
###7
磁性体の統計物理
###8
相転移の統計熱力学
###9
H.G. Stanley, Introduction to Phase Transitions and Critical Phenomena, Oxford University Press, 1971
相転移と臨界現象
###10
繰り込み群の方法
###11
L.P. Kadanoff, statistical Physics, Statics, Dynamics and Renormalization, World Scientific, 2000
###12
相転移と臨界現象
###13
三角格子状の物理
###14
N.S. Mermin, Rev. Mod. Phys. 51, 1979, 591
###15
R.J. Baxter, Exact Soluble Models in Statistical Mechanics, Academic Press, 1982
###16
量子群とヤン・バクスター方程式
###17
共形場理論と１次元量子系
###18
統計物理学
###19
非平衡系の統計力学
###20
非平衡系の統計力学
###21
複雑系を解く確率モデル
###22
G. Nicholas
散逸構造
###23
確率論とその応用
###24
###25
ランジュバン方程式
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
ViewModelとXMLの結びつき

まずはActivity

```java
class ViewModelActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // Obtain the ViewModel component.
        UserModel userModel = ViewModelProviders.of(getActivity())
                                                  .get(UserModel.class);

        // Inflate view and obtain an instance of the binding class.
        UserBinding binding = DataBindingUtil.setContentView(this, R.layout.user);

        // Assign the component to a property in the binding class.
        binding.viewmodel = userModel;
    }
}
```

上がActivity

次に,XML（レイアウト）

```xml

<CheckBox
    android:id="@+id/rememberMeCheckBox"
    android:checked="@{viewmodel.rememberMe}"
    android:onCheckedChanged="@{() -> viewmodel.rememberMeChanged()}" />
```


そして最後に、ViewModel

```java:ViewModel
/**
 * A ViewModel that is also an Observable,
 * to be used with the Data Binding Library.
 */
class ObservableViewModel extends ViewModel implements Observable {
    private PropertyChangeRegistry callbacks = new PropertyChangeRegistry();

    @Override
    protected void addOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.add(callback);
    }

    @Override
    protected void removeOnPropertyChangedCallback(
            Observable.OnPropertyChangedCallback callback) {
        callbacks.remove(callback);
    }

    /**
     * Notifies observers that all properties of this instance have changed.
     */
    void notifyChange() {
        callbacks.notifyCallbacks(this, 0, null);
    }

    /**
     * Notifies observers that a specific property has changed. The getter for the
     * property that changes should be marked with the @Bindable annotation to
     * generate a field in the BR class to be used as the fieldId parameter.
     *
     * @param fieldId The generated BR id for the Bindable field.
     */
    void notifyPropertyChanged(int fieldId) {
        callbacks.notifyCallbacks(this, fieldId, null);
    }
}

```
以上が、ViewModel
XMLがViewModelと結びつき、それをActivityやFlagmentが結びつけている。
Python　ラムダ式　map

#Reference
`map`関数について調べる際、以下のサイトを参照しました。
[map()関数とfilter()関数](https://python.atelierkobato.com/map/)
`lambda`については以下に解説が記載されています。
[Pythonのlambdaって分かりやすい](https://qiita.com/nagataaaas/items/531b1fc5ce42a791c7df)
#map,lambda
pythonを勉強中、mapとlambdaなるものが出てきた。
いまいちラムダ式が分かっていないので自分用にまとめ。

jupyter notebook で`Shift + tab` でドキュメントを確認すると以下のような説明。

```
#jupyter notebook より引用

Init signature: map(self, /, *args, **kwargs)
Docstring:     
map(func, *iterables) --> map object
```

調べてみると、`map`関数とはイテラブルオブジェクトの各要素を関数に渡して処理する関数らしい。
返り値として`map`オブジェクトが返ってくる。

 - イテラブルオブジェクトとは...文字列`"abc"`、リスト`[a,b,c]`、タプル`(a,b,c)`のように、繰り返しの処理で1つずつ要素を取り出せるオブジェクトのこと。

```python 
def function(x):
    ans = x * 2
    return ans

nums = [1,2,3,4,5]

result = map(function, nums)
print(result)

#結果
<map object at 0x110599860>
```
試しにトライすると`map`オブジェクトが返ってきてしまった。
`list`に変換すると上手くできていることが分かった。

```python

print(list(result))

#結果
[2, 4, 6, 8, 10]
```

次に、`map`と`lambda`を組み合わせて用いる。
同じ結果を得ることができた。`lambda`式を用いるとだいぶすっきりと書ける。

```python
nums = [1,2,3,4,5]
result2 = map(lambda x:  x*2 ,nums)
print(list(result2))

#結果
[2, 4, 6, 8, 10]
```

文字の入れ替えにも挑戦してみた。
`replace`関数を使うことで、 `/`を`,`に置換した。
csvファイルのヘッダー部分の編集等で使用できそう。

```python
timelist = ["year/month/day/day of the week/time"]
result3 = map(lambda y: y.replace("/", ",") , timelist)
print(list(result3))

#結果
['year,month,day,day of the week,time']
```




----------
※引用・参照部分に問題がございましたら、ご連絡をお願いいたします。
Bootstrap の グリッドシステム で row クラスの中 の 表示順 を 変えたい とき

# 目的
- Bootstrapのグリッドシステムでの表示でrowクラスの中の表示順を左右で変更したときの方法をまとめる。

# 前提条件
- Bootstrapの設定が読み込まれるようになっている
- Bootstrapのテンプレートを使用してHTMLファイルをコーディングしている。  
※Bootstrapの設定を反映させるためのテンプレートは[こちら](https://getbootstrap.jp/docs/4.2/getting-started/introduction/)のスターターテンプレート内のコードをコピーする。

# 押さえるポイント
- Bootstrapで既に定義された内容を設定したい時はHTMLファイルのクラス名に定義名を記載する。
- 左右の表示順を変更したいときはcolクラスのdivに優先順位をつける。
- 優先順位はクラス名に`order-数字`とする。
- 優先順位は比較対象すべてに指定する。
※数字が小さいほど優先順位が高い

# 書き方の例
- 本来先に記述した内容が左側の領域を使用し、次の記載が先に記載した領域の終了箇所から使用する。
- 下記の画像①の表示をコードの大幅な変更をしないで画像②の状態にしたい。
- 左側に記載したい内容のdivにクラス名でorder-1としてその次に左側に寄せて記載したい内容のdivのクラス名にorder-2とする。

画像①
![グリッドシステム3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/55ae861e-9d63-aff1-1224-8948aefa7f3d.png)

画像②
![グリッドシステム4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/469131bf-18bd-bf1a-d275-7002b38bf722.png)

- 下記に画像①のHTMLファイルの内容を記載する

``` html
          <div class="row">
            <div class="col-8">
              <p>こんにちは</p>
            </div>
            <div class="col-4">
              <p>おはよう</p>
            </div>
          </div> 
        </div>
```

- 下記に画像②のHTMLファイルの内容を記載する

``` html
          <div class="row">
            <div class="col-8 order-2">
              <p>こんにちは</p>
            </div>
            <div class="col-4 order-1">
              <p>おはよう</p>
            </div>
          </div> 
        </div>
```
量子輸送現象　家 泰弘, 2002

岩波講座-物理の世界 物質科学の展開〈2〉量子輸送現象, 家泰弘, 2002
![514DX90FWAL._SX322_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/d3fa1bf7-0b03-d6f5-da3e-8ceae2450ca8.jpeg)
https://www.amazon.co.jp/dp/4000111256/



#参考文献

###1
メゾスコピック系の物理 シリーズ-物性物理の新展開, 福山秀敏
https://www.amazon.co.jp/dp/462104236X/
###2
メゾスコピック系の物理学新物理学シリーズ, 川畑有郷, 培風館, 1997
https://www.amazon.co.jp/dp/4563024317/
###3
メゾスコピック系の物理 パリティ物理学コース クローズアップ, 岩渕修一, 
![41VWNH3WZCL._SX331_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/b481c843-c219-821c-7a61-10c821155225.jpeg)
https://www.amazon.co.jp/dp/462104494X/

###4
C.W.J. Beenakker and H. van Houten, Quantum Transport in Semiconductor Nanostructures, Solid State Physics vol. 44, eds. H. Ehrenreich and D. Turnbull, Academic Press, 1991
###5
メゾスコピック伝導 (実験物理科学シリーズ 4) 1999/11/25 田沼 静一 , 家 泰弘 
![41HZDVHMBSL._SX334_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/2f5350dd-283c-b882-a882-9d593ad57a2d.jpeg)

https://www.amazon.co.jp/dp/4320033795/

###6

物理学最前線 (2) アンダーソン局在　福山秀敏 1982/12
![41GF7BSq5SL._SX336_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/53372c51-4cc8-d2fb-8329-c9d2f4839c07.jpeg)
https://www.amazon.co.jp/dp/4320031849/
###7
物理学最前線 (13)アンダーソン局在のスケーリング理論　共立出版, 1986
https://www.amazon.co.jp/dp/4320031954/
###8
局在・量子ホール効果・密度波【現代物理学叢書】 (岩波オンデマンドブックス) 2016/8/16
長岡 洋介, 安藤 恒也, 高山 一
![41qEWjITpTL._SX351_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/c3122b1c-c387-2569-1ef8-ca4eac32e488.jpeg)

https://www.amazon.co.jp/dp/4007304602/

###9
S. Datta, Electronic Transport in Mesoscopic Systems, Cambridge University Press, 1995
###10
量子ホール効果【新物理学選書】 (岩波オンデマンドブックス) 2016/2/10 吉岡 大二郎 
![41SCkd9eSBL._SX351_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/b35c9dd6-9d0b-f227-9169-a288046ef771.jpeg) 
https://www.amazon.co.jp/dp/4007303649/

###11
分数量子ホール効果 (多体電子論)  1999/3 青木 秀夫, 中島 龍也 
![51RB5PP1Z5L._SX337_BO1,204,203,200_-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/65115b16-66b3-322d-ce77-df10fe0a94c8.jpeg)

https://www.amazon.co.jp/dp/4130606042/
### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。
#### Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
外部キー制約に触れて

#外部キー制約とは
要するに**カラムに入れる値を一定の範囲（別テーブルにある何かしらのカラム）のデータから選べという制限を設ける**ことである。

具体的に言うと、usersテーブルとpostsテーブルがあり、postsテーブルにuser_idという投稿したユーザーのidを格納する外部キーのカラムがあったとする。

この場合、postsテーブルのuser_idカラムに格納できるデータをusersテーブルのidカラムのみに限定するということである。

#外部キー制約のメリット、デメリット

この項目は不完全な内容なので、時間があるときに直す。
###~~メリット~~
~~外部キー制約をする場合はreference型がよく使われるが、このreference型には二つのメリットがある。~~

- ~~インデックスを自動的に貼り付けてくれる。~~
- ~~userではなくuser_idというカラム名を作成してくれる。(「外部キー制約の書き方」の部分を参照)~~


###~~デメリット~~
~~**外部キー制約を定義すると参照整合性が保証される**こと。~~

~~参照整合性というのは外部キーテーブルのデータへのリンクが無効になるような変更を主キーテーブルのデータに加えることができない、ということ。~~

~~つまり、**主キーのない外部キーはあってはならない**
もっと嚙み砕くと**外部キーを残したまま主キーを消そうとするとエラーになる**ということだ。~~


###~~デメリットへの対応~~
~~has_many(親テーブルにあたる)の部分にdependentオプションを追加~~

~~「外部キー制約とは」で引き合いにした例でコードを書くと以下の通りになる。~~

```
class User < ApplicationRecord
  has_many :posts, dependent: :destroy
 
end
```

#外部キー制約の書き方
reference型を使わずに外部キー制約を付ける方法もあるが、コードやファイルの量が多くなるので今回はreference型を使わない方法は割愛する。

reference型を使ったコードを書いてみる。
ここでは「外部キー制約とは」で提示した例を使用する。また、Railsのバージョンは5.2.3とする。

```
class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      t.references :user, foreign_key: true
    end
  end
end
```

重要なのは以下の2点だ。

- referece型だけでは外部キー制約にならず、「foreign_key: true」を付けて初めて外部キー制約として成立する。
- カラム名を書くところが「user_id」ではなく、「user」と書かれているがこれで「user_id」にカラム名がなっている。

一応、「add_foreign_key」を使用した書き方も載せる。

```
class CreatePosts < ActiveRecord::Migration[5.2]
  def change
    create_table :posts do |t|
      t.references :user
    end
　　add_foreign_key :posts, :users
  end
end
```

また、「add_column」では以下のようなコードになる。

```
class AddColumn < ActiveRecord::Migration[5.2]
  def change
    add_reference :posts, :user, foreign_key: true
  end
end
```

#まとめ
外部キー制約にはメリット・デメリットがあるので使う場合は、よく吟味すべきである。

個人的には、親テーブルの主キーがほとんど削除されないような場合に使うべきではないかと感じた。

また、外部キー制約を使う際には以下のこ2点に気を付けるべきだ。

- インデックスは自動で貼り付けてくれる。
- reference型だけではなく、「foreign_key: true」のコードが必須。

#参考

[Railsの外部キー制約とreference型について](https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47)
[外部キー制約でハマったので(rails)](https://qiita.com/kemako/items/e98174b9747e0b2c75a6)
[外部キー制約とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](https://wa3.i-3-i.info/word17575.html)
[主キー制約と外部キー制約バージョンを選択 - SQL Server | Microsoft Docs](https://docs.microsoft.com/ja-jp/sql/relational-databases/tables/primary-and-foreign-key-constraints?view=sql-server-2017#FKeys)
[Active Record の関連付け - Rails ガイド](https://railsguides.jp/association_basics.html#has-many%E9%96%A2%E9%80%A3%E4%BB%98%E3%81%91%E3%81%AE%E8%A9%B3%E7%B4%B0)