OmniAICreator/Qiita-1.07M huggingface dataset:
レーザースキャナを作ってみる ソフトウェア編

[プロローグとハードウェア編はこちら](https://qiita.com/screwyscrew/items/add1f50fade649b52501)

# Arduinoにソフトを組み込んでみようぜ

さてハードウェアが組み上がってソフトを開発します。
ソフトの開発はライブラリをフル活用しましょう。と言っても組込屋の自分としてはライブラリって思うようにできないことが多くて時々いらっとします。
今回もそれ絡みでいろいろ不都合が発生したのです。

# とりあえず回す！
センサーのVL53L0Xはライブラリ任せで良さそうなので(HW仕様が不明すぎる)、ステッピングモーターを回すことをやってみました。
Arduinoには標準のライブラリでステッピングモーターに対応していると言うではありませんか。
さっそくStepperを試してみました。

### 回る！
回す分には問題ありませんでした。でも今回はぐるぐる回すのではなくチマチマ回したいのです。
Stepperに1ステップずつ送って計測、送って計測を繰り返すわけです。
それをやってみました。

# 振動問題が発覚する
1ステップずつ動かすとめっちゃ振動する！てか振動で脱調するし！
機器の総重量が大きい(慣性モーメントが大きい)ので1ステップの送りが想像以上に難しいということがよくわかります。
またステップ角も1.8度と大きいのが良くなかった。たった1.8度、されど1.8度です。
例えば10cmの箱の真ん中が軸とすると角まで7cm, 2mm強の振れ幅があるわけです。
それが「カッ、カッ」と歯切れよく回るので、これはよろしくない。

## 対策
こういう場合に考えられる対策はいくつか考えられます。
* 励磁のモードを変更するやり方。最初は2-2相だったのを1相にするか1-2相にするか。
ざっくり試してみましたがまあだめですよ。ほとんど変わらない。振動ひどい。

* 電圧を変える
電圧を変えるのは趣味の工作レベルだと難しいですね。安定化電源欲しい。

* マイクロステップをやる
正直やりたくなかった。だって面倒なんだもの。
けれど振動を抑えるにはゆったりと制御するのが一番簡単だし。スピードいらないし。

というわけでマイクロステップを突っ込みました。

# マイクロステップをArduino UNOで実現する
これ、意外と簡単でした。いえ出来はいまいちですが、かけた手間が思ったより少なかったのです。

## マイクロステップを実現する原理
一般的にステッピングモーターのドライバのうちHブリッジを2個のせてあるだけのようなシンプルな構成の場合、1ステップを送るのに必要な処理はAIN1ピンにHighを入力していたところからAIN2ピンをHighにするよう変えます。AIN1ピンはLowになります。

||AIN1|AIN2|BIN1|BIN2|
|:---:|:---:|:---:|:---:|:---:|
|初期|1|0|1|0|
|1ステップ|0|1|1|0|
|2ステップ|0|1|0|1|
|3ステップ|1|0|0|1|
|4ステップ|1|0|1|0|
これが基本です。これが1-2相になると分解能は2倍になります。(ステップ間誤差がある)

||AIN1|AIN2|BIN1|BIN2|
|:---:|:---:|:---:|:---:|:---:|
|初期|1|0|1|0|
|0.5ステップ|0|0|1|0|
|1ステップ|0|1|1|0|
|1.5ステップ|0|1|0|0|
|2ステップ|0|1|0|1|
|2.5ステップ|0|0|0|1|
|3ステップ|1|0|0|1|
|3.5ステップ|1|0|0|0|
|4ステップ|1|0|1|0|
|4.5ステップ|0|0|1|0|
これが1-2相駆動、あるいはハーフステップ駆動です。

このハーフを一部取り出してみます。

||AIN1|AIN2|BIN1|BIN2|
|:---:|:---:|:---:|:---:|:---:|
|0ステップ|1|0|1|0|
|0.5ステップ|0|0|1|0|
|1ステップ|0|1|1|0|

AIN1とAIN2がともに0になるときがあります。
この0～0.5までの間をもっと少数増やそうというのが今回目指すマイクロステップです。

# analogWriteを使う
ずばりこれが簡単だった理由です。
analogWriteはただのPWMです。バーチャルアナログに過ぎません。
しかしPWMはマイクロステップやるうえでの基本。リアルアナログはHブリッジの制御をするうえで役に立ちません。

1->0をanalogWriteで書くと

```
// 3番ピン
analogWrite(3,255);
analogWrite(3,0);
```

となります。ということはその中間は

```
analogWrite(3,127);
```
で簡単ですね。こうしてあっさりとマイクロステップを実装できました。
自前のライブラリが完成、っと。

## しかし地味な問題が一つ
PWMが約490Hzというクソ仕様のためにめっちゃうるさい。A#くらいの音が鳴りまくりました。
汚い言葉使ってごめんなさいくそ。

# これで少しずつ回しながら測定ができる
このライブラリを用いて測定するのですが、この先はまた次の話。

つづく。
Docker+VSCode+リモート接続の環境で、Dash(Flask)をデバッグする方法

仕事中にハマったので個人的メモ。

### 0. VSCode上でDockerコンテナにリモート接続
（既に解説記事が豊富にあるため割愛）

### 1. dash.Dashの`server`オプションに`flask.Flask`で作ったappを指定

```python:app.py
import flask
import dash
_app = flask.Flask(__name__)
app = dash.Dash(__name__, server=_app)
```


### 2. VSCodeのDebug機能→構成を追加→「Python: Flask」を選択
以下の構成がlaunch.jsonに追加される。

```json:launch.json
{
    "name": "Python: Flask",
    "type": "python",
    "request": "launch",
    "module": "flask",
    "env": {
        "FLASK_APP": "app.py",
        "FLASK_ENV": "development",
        "FLASK_DEBUG": "0"
    },
    "args": [
        "run",
        "--no-debugger",
        "--no-reload",
        # 必要に応じて--hostや--portを追加
    ],
    "jinja": true
}
```

### 3.追加した構成を選択しデバッグ
Dashのブラウザ上での挙動（変数の作成＆更新、コールバックなど）をリアルタイムにデバッグすることができる。
Robloxで物を点滅させる

[Robloxで爆弾をつくる](https://qiita.com/PrivateUeno/items/c5679faf1967f96f9513)の続き

# 概要
- 爆弾が出たり消えたりします
- 消えたる爆弾にさわっても爆発します
- 地雷記憶ゲームで作れそうですね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/9676e1b9-73e0-64ee-9dae-89fa8dbcf2d2.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/b6878155-7a00-3f5d-e950-80e78f6fe36d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/ec12600e-764e-9bd3-d130-dd651d24ee69.png)


# プログラミング
- 以前つくったBombScriptに少し追記するだけでOK
- Transparencyが1なら透明、0ならふつうにみえる、0.5なら半透明


``` BombScript.lua
local function explosion(hit)
  local touchObject = hit.Parent
  local humanoid = touchObject:FindFirstChildWhichIsA("Humanoid")
  if humanoid then		
	local exp = Instance.new('Explosion')
		exp.Position = hit.Position
		exp.Parent = workspace
	end
end

Workspace.Bomb.Touched:connect(explosion)

-- ここからが新しく追加したところ
-- ずっとくりかえす
while 1 do
	wait(2)
	-- WorkspaceにあるBombの透明度を1にする、つまり透明になる
	game.Workspace["Bomb"].Transparency = 1
	wait(2)
	game.Workspace["Bomb"].Transparency = 0
end
```

# 元記事
> https://www.youtube.com/watch?v=_K7stCkqFBY
enebularとobnizをつなげて操作してみる

# しくみ

obnizのブロックプログラムで作ったボタンを、enebularから押せるようにします。ボタンを押すとモーターが回るプログラムを作っているので、これでenebularからモータが回せる！

モーター(obnizBoard)　<-----> HTML(ブロックプログラム) <-----> enebular

# obnizの修正

ファイル名を押して、コードを見るからJavaScriptのプログラムを見ます。

<img width="208" alt="スクリーンショット 2019-11-16 1.07.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/8975a752-253c-1040-3d74-60af75a7da7a.png">


内容をコピーして、プログラムの方にコピペしましょう。

<img width="1404" alt="スクリーンショット 2019-11-16 1.07.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/e2283c1d-cd4b-8ce0-c171-c51f9455ccde.png">


enebularとの連携部分を追記します。
今回はボタンを１秒だけ押してくれるプログラムにしました

```javascript

  const sock = new WebSocket("wss://***enebularのurl***/ws");

  sock.addEventListener("open", e => {
      console.log("接続完了");
  });

  sock.addEventListener('message', (event) => {
    let jsonString = event.data;
    let data = JSON.parse(jsonString);
    console.log(data);
    button.touchStart();
    setTimeout(()=>{
      button.touchEnd() 
    },data.duration); 
 });
```


`wss://***enebularのurl***/ws`のところだけは後で変更します。


これをプログラムの真ん中あたりに挿入しましょう。
`var button, xxx`の次の行あたりが丁度いいです。
<img width="712" alt="スクリーンショット 2019-11-16 1.42.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/829bb2a6-8844-c38e-c8de-187e4aa380d4.png">

# enebular側の作製

[enebular](https://www.enebular.com/ja/)にてアカウントを作りログインします


シンプルにInjectionノードでアクションを起こしてみます。

このノードを作りましょう
<img width="489" alt="スクリーンショット 2019-11-16 1.48.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/50098c85-6f1a-db35-20d7-70076ba06f27.png">


まずはenebularにログインして新規フローを作ります。
ノードを２つ持ってきて、ワイヤでつなげて設定をするだけです。

各ノードの設定はこの様になっています。

<img width="792" alt="スクリーンショット 2019-11-16 1.49.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/6146b520-1c43-eaac-ebd7-c2a2e53579f4.png">

<img width="845" alt="スクリーンショット 2019-11-16 1.49.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/64b2c11e-ba51-04ad-8833-e1bba562f966.png">

websocketのプロパティはパスの横の編集ボタンを押すとwebsocket-listenerの設定ができます。
<img width="526" alt="スクリーンショット 2019-11-16 1.50.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/3acaf6d5-4d80-e1da-9926-9083afa1904e.png">


設定が終わったら、右上のデプロイボタンを押した後、その横のinfoボンタンでURLの確認をします。

<img width="357" alt="スクリーンショット 2019-11-16 1.37.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/d28eb582-762f-3552-223c-f182fd2b59f8.png">

このURLのhttps://をwss://にかえて先程のobnizのプログラムへ書きます。
`wss://***enebularのurl***/ws`のところをURLに応じて変更します。

enebularはデプロイ済みですので、obnizのプログラムを実行し、injectionノードのボタンを押してみましょう。



## enebularの変更

このままだと画面上のボタンを押してることには変わりないので,自動化してみましょう、
プログラムを変えて10秒に１度動くようにしてみましょう

Injectionノードをこのように変えます

<img width="851" alt="スクリーンショット 2019-11-16 1.55.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/227015/8d638365-e2fa-910e-3bc5-a60f0736a733.png">




デプロイしたら、obnizのプログラムを実行してみましょう。
【Heroku】デプロイ（1年前の自分へ）| Rails PostgreSQL

## Railsでアプリを作ってこれからデプロイするところからのスタート！！

#### とりあえずHerokuにログイン

```
$ heroku login

// ※windowsの場合
$ heroku login --interactive
```

#### Herokuにアプリを作成

```
$ heroku create

// アプリのURLを変更したい場合
$ heroku create 付けたいアプリのURL
```

#### プリコンパイル
[参考](http://rails.hatenadiary.jp/entry/2013/03/03/125801)

```
$ rails assets:precompile
```

#### HerokuのbuildpackにRuby、nodejsのパッケージをセット

```
$ heroku buildpacks:set heroku/ruby
$ heroku buildpacks:add --index 1 heroku/nodejs
```

#### GitHubのmasterにpush

```
$ git add .
$ git commit -m 'heroku'
$ git push origin master
```

#### Herokuへデプロイ！

```
$ git push heroku master
```

#### Herokuで`db:migrate`

```
$ heroku run rails db:migrate
```

#### アプリへ飛ぶ！

```
$ heroku open
```

完成〜〜〜！！！


## 初めてデプロイする際に使えるコマンド

対象: テストなどで、適当にデプロイを行いたいとき

```
$ heroku create && rails assets:precompile && git add . && git commit -m 'heroku deproy' && git push origin master && heroku buildpacks:set heroku/ruby && heroku buildpacks:add --index 1 heroku/nodejs && git push heroku master && heroku run rails db:migrate && heroku open
```

## 2回目以降のデプロイ

対象

```
$ rails assets:precompile && git push heroku master && heroku run rails db:migrate && heroku open
```

# その他

## master以外のBranchからHerokuへデプロイする場合

```
$ git push heroku ブランチ名:master
```

## Herokuのデータベース削除

まず以下のコマンドを実行

```
$ heroku pg:reset DATABASE
```

次に、赤文字でそのアプリケーションのDB名が表示され、 
**このDBを削除してもいいですか？** 的なノリで最終確認されるので
そのDB名をコピーしてそのままターミナルに貼り付け、Enter

## Herokuのアプリを削除

まず以下を実行して、Herokuに作ったアプリケーションをターミナルに出力

```
$ heroku apps
```

次に削除したいアプリケーションを選択し、以下を書き換えて実行

```
$ heroku apps:destroy --app アプリケーション名 --confirm アプリケーション名
```

参考
https://qiita.com/chihiro/items/5c3ff400f6cb99deb945

## heroku run rake db:migrateができない場合

`$ heroku run rake db:migrate`で以下のエラーが出る場合の対処

```
rake aborted!
PG::ConnectionBad: could not connect to server: No such file or directory
    Is the server running locally and accepting
    connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
```

Herokuにpostgresqlのアドオンを追加して `migrat`

```
$ heroku addons:create heroku-postgresql
$ heroku run rake db:migrat
```

参考
https://qiita.com/suzuki-x/items/b878723080aea1a673ed

## Herokuのテーブルを確認する

#### Herokuのpostgresに接続

```
$ heroku pg:psql
```

#### Herokuのテーブルを出力

```
herokuのアプリ名::DATABASE-> \d
```

参考
https://vavolab.com/article/2018/06/05/00/02/01/heroku-postgres%E3%81%A7%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E4%BD%9C%E6%88%90%E3%83%BB%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95/

## 日本語フォント

```
$ heroku buildpacks:add --index 1 heroku/nodejs
$ heroku buildpacks:add --index 2 https://github.com/hopkinschris/heroku-buildpack-system-fonts.git
$ heroku buildpacks:set https://github.com/CoffeeAndCode/puppeteer-heroku-buildpack.git
```
参考
https://pgmemo.tokyo/data/archives/1061.html

## Heroku app 削除

使用しなくなったHerokuアプリを削除

Herokuアプリの一覧を表示

```
$ heroku apps
```

削除

```
$ heroku apps:destroy --app アプリ名
```

参考
https://qiita.com/chihiro/items/5c3ff400f6cb99deb945
VBA Excel dt ddで表形式になっている場合Excelは表形式で読み込めないため1行ずつ読み込む

<div>
<dl>
  <dt>A</dt><dd>B</dd><dd>C</dd>
</dl>
<dl>
  <dt>A</dt>
  <dd>B</dd>
  <dd>C</dd>
</dl>
</div>

上記をHTMLにすると次のようになる。

```html
<div>
<dl>
  <dt>A</dt><dd>B</dd><dd>C</dd>
</dl>
<dl>
  <dt>A</dt>
  <dd>B</dd>
  <dd>C</dd>
</dl>
</div>
```

#しかしこのタイプの表はExcelは読み込めない
この形式で表示されている表はExcelは読み込めない。
また、データも縦に展開される。
上記のデータも

```powershell
A
B
C
```

のように縦に字が並ぶ

##VBAで解決するか
まず取得したいページでF12を押してHTMLのコードを取得し、テキストファイルに入れます。
この時改行でタグが区切られているという前提になります。

```html
<div>
<dl>
  <dt>A</dt>
  <dd>B</dd>
  <dd>C</dd>
  <dt>A</dt>
  <dd>B</dd>
  <dd>C</dd>
</dl>
</div>
```

すると、3列ですから、3列をカウントしたら縦は1行目に戻り、行が１進むように読んでいけばよいわけです。
ただし、表の中に改行`<br>`が入っているととずれます。
まずADODB.Streamでテキストを全部読み、改行で配列に入れます。
そして正規表現で切り出した行をセルに貼ります。
dtかどうかはReplaceで置換して差がないかで判定します。


```vb
Sub readkan()
Const LordhtmlFile = "C:\hoge\text.txt
Dim wb As Workbook: Set wb = ThisWorkbook
Dim ws As Worksheet: Set ws = ActiveSheet
Dim icol As Long, iRow As Long
Dim ar, br, i As Long
Dim Reg As New RegExp, MC As MatchCollection, sMC As SubMatches, M As Match

Dim sr As New ADODB.Stream
Dim buf As String, str1 As String
Dim bufs As String
sr.Charset = "UTF-8": sr.Mode = adModeReadWrite: sr.LineSeparator = adCRLF: sr.Open
sr.LoadFromFile "E:test.txt"
buf = sr.ReadText(-1)
ar = Split(buf, vbCrLf)
Reg.Global = True
Reg.MultiLine = True
icol = 0: iRow = ws.Range("A" & Rows.Count).End(xlUp).Row
For i = LBound(ar) To UBound(ar)
bufs = ar(i)
Reg.Pattern = "(\<dt\>.*\</dt\>|\<dd\>.*\</dd\>)"
Debug.Print bufs, Reg.Test(bufs)
If Reg.Test(bufs) Then
Set MC = Reg.Execute(bufs)
Set M = MC(0)
''Dtで行が変わる
'<br>で改行する2行にわたる表は対応ができていない
str1 = M.Value
If str1 = Replace(str1, "<dd>", "", 1, -1, vbTextCompare) Then
str1 = Replace(Replace(str1, "<dt>", "", 1, -1, vbTextCompare), "</dt>", "", 1, -1, vbTextCompare)
icol = 1: iRow = iRow + 1
ws.Cells(iRow, icol).Value = str1: str1 = "": icol = icol + 1
Else
str1 = Replace(Replace(str1, "<dd>", "", 1, -1, vbTextCompare), "</dd>", "", 1, -1, vbTextCompare)
ws.Cells(iRow, icol).Value = str1: str1 = "": icol = icol + 1
If icol > 6 Then icol = 1: iRow = iRow + 1 'たまに読めない位置はこれでオーバーを抑える
str1 = ""
End If
End If
Next
sr.Close
End Sub
```
ローカル環境にRailsの環境を構築

<h1>はじめに</h1>
Ruby on Railsの環境構築に関する記事はたくさん存在するので、自分の備忘録的にメモ程度に残す

<h1>なぜ</h1>
Railsチュートリアルをやる上で、AWS Cloud9を使ってたんですが、ローカルにあったほうが便利じゃね？と思った
https://railstutorial.jp/

<h1>環境</h1>
OS：macOS Mojave

<h1>今の環境とRubyの準備</h1>
Rubyはrbenvでいれる。

```bash
$ which ruby
/usr/bin/ruby
$ ruby -v
ruby 2.3.7p456 (2018-03-28 revision 63024) [universal.x86_64-darwin18]
```
こちらを参考に環境構築していきます。
https://dev.classmethod.jp/server-side/language/build-ruby-environment-by-rbenv/

```bash
$ brew install rbenv ruby-build
...
...
...
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
 
$ source ~/.bash_profile
$ rbenv --version
rbenv 1.1.2
```

はいったよ！途中でruby-buildがinstalledって言われたので、
`brew upgrade ruby-build`　
で最新化しました

rubyの安定版2.6.5をインストールする

```bash
$ rbenv install 2.6.5
$ rbenv local 2.6.5 # 念の為、ローカルでつかう。
$ ruby -v
ruby 2.6.5p114 (2019-10-01 revision 67812) [x86_64-darwin18]
```

<h1>Railsのインストール</h1>

```
$ gem install rails
$ rails -v
Rails 6.0.1
```

わーい！
さて、ではチュートリアル再開しますか。

<h1>Heroku</h1>
Herokuのbrewでインスコできる
https://devcenter.heroku.com/articles/heroku-cli
```bash
$ brew install heroku && brew install heroku
```
[UE4]ConsoleVariables.iniの特殊性

#ConsoleVaribels.ini
例えばusfファイルなどをいじる場合、公式などに
Engine/Config/ConsoleVariables.iniのr.ShaderDevelopmentModeの行のコメントを外すべし！
と書かれていたりして、それを編集することが多いと思います。

[シェーダー開発|UnrealEngineDocument](https://docs.unrealengine.com/ja/Programming/Rendering/ShaderDevelopment/index.html)

しかし、チーム開発を行う場合Engine内部のファイルはバージョンコントロールに格納されている場合が多いと思います。
そのため自分だけこのコンソール変数が弄れれば十分なのに、わざわざサーバーに送信してしまわないようにしていたり、
潔くサブミット(コミット)してしまったりということがあると思います。

#iniの階層構造とConsoleVariables.ini

ドキュメントにはコンフィグファイルには階層構造があり、基底のパラメータをオーバーライドできるような記述があります。
[コンフィギュレーションファイル|UnrealEngineDocument](https://docs.unrealengine.com/ja/Programming/Basics/ConfigurationFiles/index.html)

**しかしこの階層構造は ConsoleVariables.ini には存在しません**
そのため、[ProjectPath]/Config/DefaultConsoleVariable.ini や [ProjectPath]/Saved/Config/[Platform]/ConsoleVariable.ini を用意しても
読み込まれません。ぐぬぬ。

※なんでそうなるかはConfigCacheIni.cppを読んでください

#自分だけ設定できればいいのに・・・

ソースを見てみます。

```c++:ConfigCacheIni.cpp
void FConfigCacheIni::LoadConsoleVariablesFromINI()
{
	FString ConsoleVariablesPath = FPaths::EngineDir() + TEXT("Config/ConsoleVariables.ini");

#if !DISABLE_CHEAT_CVARS
	// First we read from "../../../Engine/Config/ConsoleVariables.ini" [Startup] section if it exists
	// This is the only ini file where we allow cheat commands (this is why it's not there for UE_BUILD_SHIPPING || UE_BUILD_TEST)
	ApplyCVarSettingsFromIni(TEXT("Startup"), *ConsoleVariablesPath, ECVF_SetByConsoleVariablesIni, true);
#endif // !DISABLE_CHEAT_CVARS

	// We also apply from Engine.ini [ConsoleVariables] section
	ApplyCVarSettingsFromIni(TEXT("ConsoleVariables"), *GEngineIni, ECVF_SetBySystemSettingsIni);

	IConsoleManager::Get().CallAllConsoleVariableSinks();
}
```

おっ！ ConsoleVariablesとかGEngineIniとかが見えますね。
早速書いてみましょう！

```c:Saved/Config/Windows/Engine.ini
[Core.System]
Paths=../../../Engine/Content
Paths=%GAMEDIR%Content
Paths=../../../Engine/Plugins/2D/Paper2D/Content

...略...

[ConsoleVariables]                 ;追加
r.ShaderDevelopmentMode=4          ;追加
```

そして起動！
**ばっちり設定されています！**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464248/910fe018-837f-e8fd-a536-8435fa562f02.png)

起動ログにもどんなパラメータが読まれたのか書いてあったりします。
LogConfigを探してみてください。

```
LogConfig: Applying CVar settings from Section [Startup] File [../../../Engine/Config/ConsoleVariables.ini]
LogConfig: Setting CVar [[r.DumpShaderDebugInfo:1]]
LogConfig: Setting CVar [[net.UseAdaptiveNetUpdateFrequency:0]]
LogConfig: Setting CVar [[p.chaos.AllowCreatePhysxBodies:1]]
LogConfig: Applying CVar settings from Section [ConsoleVariables] File [D:/dev/UE423projects/TPBP423Config/Saved/Config/Windows/Engine.ini]
LogConfig: Setting CVar [[r.ShaderDevelopmentMode:4]]
```

#まとめ

`[projectpath]/Saved/Config/Windows/DefaultEngine.ini` の `[ConsoleVariables]` セクションに設定することで、
自分の開発環境固有のコンソール変数を適用することができます。
各自の開発環境ごとにあるSavedの下に保存されたiniファイルならCIなどに取り込まれて、慌てることはありません。

逆にプロジェクトとして設定したいものに関しては、
`[projectpath]/config/DefaultEngine.ini` の `[ConsoleVariables]` セクションに記述することで
ゲームの動作設定を最終ビルドに含めることができます。
レーザースキャナを作ってみる ハードウェア編

[ソフトウェア編はこちら](https://qiita.com/screwyscrew/items/ea53f7de346d3c824a0e)
# キャンプをしたいんだ
話はそこから始まりました。
そもそもの目的はキャンプです。そのために道具をちまちまと買い始めました。
なぜキャンプをしたいのか？愛犬と出かけて楽しみたいのです。ゆるキャンしたい...

## キャンプをするために車に荷物を積みたいんだ
愛犬は車でどうにも落ち着きのないタイプなのです。
その愛犬の居住スペースとキャンプの荷物、これらを積み込むにはどうすれば良いか考えたのです。
### 荷台を作って2階建て構造にしよう！
軽の車内の後部座席を倒し、そこに脚付きの板をピッタリと置いて荷台とし、上段に犬のスペースを、下段にキャンプ用品を、と考えたのです。
しかし車の内部の曲線に合わせて板の形状を切るとか無理じゃね？と思っていたところに閃いた。
### 内部に回転スキャナを置いて測定させれば板の形状が決まるのでは！？
というのがプロローグになります。長いな...

# 仕様を決めよう
* スキャニングの方法は？
ステッピングモーターをたまたま持っていたのでこれを使いましょう。

* 計測手段は？
秋月電子のサイトを眺めていたら良いのを発見。Time of Flight 方式のVL53L0X というセンサーモジュールを使うのが良さそうです。そもそも今回の測定とは相性が良さそう。

* マイコンは？
あんまり使ってなかったArduinoならVL53L0Xのライブラリが有りますね。

* 電源は？
ステッピングモーター用に12V、マイコンとセンサーは5Vで良さそうです。
本当は電池でやりたいところです。

* 構造は？
ダイソーの■10cm MDF を箱型にしましょう。

# さっそく組み立ててみた
![IMG_20191116_010406.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403596/0546f4ec-526a-29c5-a352-374b1b8e6539.jpeg)

こんな感じになりました。
ボール盤で溝切してるあたり趣味が出てます。
立板にT型の基板がセンサーモジュール、その横のがターゲットを決めるためのレーザーモジュールです。

![IMG_20191116_010453.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403596/b57530f3-3588-304c-accc-ed3918184473.jpeg)

ステッピングモーターはなんと逆さ設定。土台から上を全部回すという発想！！なんて非常識！
これが残念な現象の原因になるということを、いざ制御開始してから気付いたのです。

づづく。
Bioconductor登録数ランキング

Rのパッケージリポジトリは、**CRAN**と**Bioconductor**に大別される。

CRANの内容は多岐にわたるが、Bioconductorは特に生命科学に特化したものが登録される。

CRANの方で、過去に[CRAN に R パッケージを登録している日本人まとめ #rstatsj](https://qiita.com/hoxo_m/items/ce478bf0debe963d9e40)で、日本人だけを集計したことがあったらしいが、ここでは、Bioconductorの開発者のリストを作成して、ランキングを行った。

↓書いたコード

```r
library(js)
library(rjson)
library(RCurl)
library(DT)

software <- getURL("https://www.bioconductor.org/packages/json/3.10/bioc/packages.js")
annotation <- getURL("https://www.bioconductor.org/packages/json/3.10/data/annotation/packages.js")
experiment <- getURL("https://www.bioconductor.org/packages/json/3.10/data/experiment/packages.js")
workflow <- getURL("https://www.bioconductor.org/packages/json/3.10/workflows/packages.js")

# Parse
software <- unlist(lapply(fromJSON(esprima_parse(software))[[2]][[1]]$declarations[[1]]$init$properties[[1]]$value$elements
, function(x){x$elements[[2]]$value}))
annotation <- unlist(lapply(fromJSON(esprima_parse(annotation))[[2]][[1]]$declarations[[1]]$init$properties[[1]]$value$elements
, function(x){x$elements[[2]]$value}))
experiment <- unlist(lapply(fromJSON(esprima_parse(experiment))[[2]][[1]]$declarations[[1]]$init$properties[[1]]$value$elements
, function(x){x$elements[[2]]$value}))
workflow <- unlist(lapply(fromJSON(esprima_parse(workflow))[[2]][[1]]$declarations[[1]]$init$properties[[1]]$value$elements
, function(x){x$elements[[2]]$value}))

# Remove e-mail address
software <- gsub(" *<.*@.*", "", software) # 1823
annotation <- gsub(" *<.*@.*", "", annotation) # 953
experiment <- gsub(" *<.*@.*", "", experiment) # 385
workflow <- gsub(" *<.*@.*", "", workflow) # 27
total <- c(software, annotation, experiment, workflow)
ranking <- sort(table(total), decreasing=TRUE)
ranking <- cbind(names(ranking), unlist(ranking))
rownames(ranking) <- seq(nrow(ranking))

# Save
write.table(ranking, "ranking.txt",
	row.names=FALSE, col.names=FALSE, quote=FALSE)

# Visualize
datatable(ranking)
```

ランキング結果は、以下のようになった。

<img width="1226" alt="スクリーンショット 2019-11-16 12.02.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17038/ab2c3983-4483-3448-6466-0b01e2a70262.png">

長い間、自分は**Bioconductor Package Maintainer**（Bioconductorのコアチーム）以外で、個人としては自分が一番パッケージを登録していると思っていたが、一人だけ自分よりもパッケージを登録している人がいた（Benilton Carvalho）。マイクロアレイのアノテーションパッケージをプラットフォームごとに登録しているらしい。自分は[MeSH.XXX.eg.db](https://bioconductor.org/packages/release/data/annotation/html/MeSH.Hsa.eg.db.html)で生物種ごとにパッケージを登録していたから、ピーク時には125個登録されていたが、それでも向こうの方がやや多いので、ちょっと悔しい。

DESCRIPTIONファイルに、住所を書く項目が無いため、この先日本にいる人だけをシステマティクにパースする方法が思いつかなかったが、全部目を通した感じだと、Y-h. Taguchi、Itoshi NIKAIDOぐらい？で、その他に日本人ぽい名前の人は見つからなかった。あとCellTreeのDavid duVerleさんは東大津田研だし、HiLDAのZhi Yangさんは国がんの白石さん関係だし、日本にいたり、日本のプロジェクトに関係している外国人を含めるともう少しいると思われる。

同じことをCRANでもやろうかと思ったが、ちょっとMaintainerのところだけをパースするのがめんどくさそうだったので、誰かやってみて欲しい。
https://cran.r-project.org/web/packages/available_packages_by_date.html

CRANと比較して、Bioconductorに登録する日本人が少ないため、みんなでパッケージングして、Bioconductorに登録する[**Bio"Pack"athon**](https://sites.google.com/view/biopackathon/about)という活動を始めたので、興味がある方はぜひ参加登録をお願いします。

[男の価値は作ったパッケージで決まる](https://www.slideshare.net/TokorosawaYoshio/r45lt/2)...良い言葉デスネ^^
サクッとnode.jsでHTTPリクエストを受け取るAPIを作る

#はじめに
今回はNode.jsのフレームワークであるExpressでHTTPリクエストを受け取るアプリケーション？を作りたいと思います。
利用用途としては

 * しっかりリクエスト送れてるの？
 * Expressとかnode.jsでAPIを作ってみたい
 
といったことが想定されます。私の場合は主に、というか9割前者ですね。JMETERでリクエストが正しく送れているか確認したかっただけです。

#実装
##下準備
まず以下のコマンドを実行します。この時、プロジェクトのディレクトリ内で行いましょう。

```
> npm init
```
あとはダイアログに従い、入力するだけです。
すると`package.json`が作成されると思います。

次にExpressをインストールします。

```
> npm install express -save
```
このコマンドをたたけばいろいろダウンロードされ、環境が整います。

##実行するファイルを作る

```index.js
const express = require('express')
const app = express()
// body-parserのおまじない
// 参照:https://expressjs.com/ja/4x/api.html#req.body
const bodyParser = require('body-parser') 
app.use(bodyParser.urlencoded({ extended: true }))

app.listen(3000)
app.get('/get', function (req, res) {
    res.send('Receive Get request')
    console.log('GETリクエストを受け取りました')
})
app.post('/post', function (req, res) {
    res.setHeader('Content-Type', 'text/plain');
    res.send('Receive POST request as ' + req.body.text)
    console.log('POSTリクエストを受け取りました')
    console.log(req.body)
})
```
**body-parserのおまじない** これかなり重要です。これがないとreq.bodyでは表示されません。

#実行してみよう
ここではVScodeのREST Clientを使います。
##GETリクエスト

```
GET http://localhost:3000/get
```

返ってくるレスポンス

```
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 19
ETag: W/"13-XJXW/hqJ3os48dLZM0f0yOQl3GA"
Date: Fri, 15 Nov 2019 16:02:55 GMT
Connection: close

Receive Get request
```


##POSTリクエスト

```
POST http://localhost:3000/post
Content-Type:application/x-www-form-urlencoded

text=テスト送信
```

返ってくるレスポンス

```
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/plain; charset=utf-8
Content-Length: 38
ETag: W/"26-i+FQlfv64fSmWg1IEMiZfpdw9eY"
Date: Fri, 15 Nov 2019 16:03:59 GMT
Connection: close

Receive POST request asテスト送信
```

#注釈
```js
res.send('Receive POST request as ' + req.body.text)
```
のtextの部分を変えることでPOSTリクエストの

```text
text=テスト送信
```
のtextの部分を変えることができます。

#まとめ
ほかにもjson形式のPOSTリクエストを受け取るとかできますが、今回は省略。

##参考
https://qiita.com/kefian1go/items/198d9da2240846e28a48
https://expressjs.com/ja/4x/api.html#req.body
SQL整形フォーマッターOnline リアルタイムSQL整形 ログ出力のSQLに活用

# SQL整形フォーマッターOnline
Javascript式リアルタイムSQL整形、サーバーへ一切送信なし。 参照動画。　

[SQL整形フォーマッター](https://softbase.jp/sqlformat)

![sqlformat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125746/00159133-ad76-1ae3-c91f-cd26b71714ab.gif)
Ciscoルータで簡単なスタティックルーティング構築をしてみる。

Ciscoルータを使って、簡単なスタティックルーティング構築してみる。

#動作環境
Cisco 800M × 2
macOS Catalina

#やりたいこと
![static_route.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154610/d72f32a0-8bfd-f7dd-a841-8b2f78eeddaf.jpeg)


- IPアドレスが192.168.1.254のPCと192.168.3.254のPCをPingで疎通させる。
- ルータを2台使う。


# 構築
- まず、LANケーブルでルータ同士をつなげる。今回は、GigabitEthernet 0/5につなげた。
- 各ルータのGigabitEthernet 0/0にそれぞれのPCをつなげる。
- 192.168.1.254のPCを**A**, 192.168.3.254のPCを**B**とする。

そして、ターミナルで設定を行う。
設定は、以下の通り。

```192.168.1.254(A)
Router# conf t
Router(config)# interface vlan 1
Router(config-if)# ip address 192.168.1.253 255.255.255.0
Router(config-if)# no shut
Router(config-if)# exit
Router(config)# interface GigabitEthernet 0/5   //ルータによっては、FastEthernetの場合もある。
Router(config-if)# ip address 10.1.0.1 255.255.255.0
Router(config-if)# no shut
Router(config-if)# exit
```

```192.168.3.254(B)
Router# conf t
Router(config)# interface vlan 1
Router(config-if)# ip address 192.168.3.253 255.255.255.0
Router(config-if)# no shut
Router(config-if)# exit
Router(config)# interface GigabitEthernet 0/5   //ルータによっては、FastEthernetの場合もある。
Router(config-if)# ip address 10.1.0.2 255.255.255.0
Router(config-if)# no shut
Router(config-if)# exit
```

そして、`ip route`でスタティックルートの設定を行う。

```192.168.1.254(A)
Router(config)# ip route 192.168.3.0 255.255.255.0 10.1.0.2
```

```192.168.3.254(B)
Router(config)# ip route 192.168.1.0 255.255.255.0 10.1.0.1
```

最後に、PC本体の設定を行う。

#### **PC Aの設定**

IPアドレス: 192.168.1.254
サブネット: 255.255.255.0(Win10の場合は、サブネットの長さである**「32」**を記入。)
デフォルトゲートウェイ(Macの場合、ルーター): 192.168.1.253(Vlanで設定したIPアドレス)

#### **PC Bの設定**

IPアドレス: 192.168.3.254
サブネット: 255.255.255.0
デフォルトゲートウェイ: 192.168.3.253



# pingを飛ばしてみる。

```192.168.1.254(A)
*PING 192.168.3.254 (192.168.3.254): 56 data bytes
64 bytes from 192.168.3.254: icmp_seq=0 ttl=62 time=2.990 ms
64 bytes from 192.168.3.254: icmp_seq=1 ttl=62 time=3.086 ms
64 bytes from 192.168.3.254: icmp_seq=2 ttl=62 time=3.017 ms
64 bytes from 192.168.3.254: icmp_seq=3 ttl=62 time=3.183 ms
64 bytes from 192.168.3.254: icmp_seq=4 ttl=62 time=3.128 ms
64 bytes from 192.168.3.254: icmp_seq=5 ttl=62 time=3.012 ms
64 bytes from 192.168.3.254: icmp_seq=6 ttl=62 time=3.088 ms
```

```192.168.3.254(B)
*PING 192.168.1.254 (192.168.1.254): 56 data bytes
64 bytes from 192.168.1.254: icmp_seq=0 ttl=62 time=2.990 ms
64 bytes from 192.168.1.254: icmp_seq=1 ttl=62 time=3.086 ms
64 bytes from 192.168.1.254: icmp_seq=2 ttl=62 time=3.017 ms
64 bytes from 192.168.1.254: icmp_seq=3 ttl=62 time=3.183 ms
64 bytes from 192.168.1.254: icmp_seq=4 ttl=62 time=3.128 ms
64 bytes from 192.168.1.254: icmp_seq=5 ttl=62 time=3.012 ms
64 bytes from 192.168.1.254: icmp_seq=6 ttl=62 time=3.088 ms
```

見事に、疎通できた。
【時短】zshでエイリアスを設定する方法


## はじめに
これまでエイリアスを設定したことがなかったので、自分の備忘録として記載します。

以下３記事を参考にさせて頂き、**内容ほぼコピペ**の構成です。
詳細は各記事をご確認下さい。

[zshにエイリアスとかいう奴入れたら人生の時間がn秒増えて神 - Qiita](https://qiita.com/Ancient_Scapes/items/abfb0673aa5df3274fc6)
[zshのグローバルエイリアス - Qiita](https://qiita.com/hatchinee/items/5f4c815285c0a1464288)
[Dockerのコマンドが長いのでalias設定した - Qiita](https://qiita.com/kulikala/items/f736629497a974ca82cb)

※どれも**非常にわかりやすい**良記事でした！ありがとうございます！

## この記事が役に立つ方
- エイリアスを設定したことがない
- zsh初心者

## この記事のメリット
- zshでエイリアスが設定出来るようになる
- タイプミスが減る
- 時間が浮く

## 環境
- macOS Catalina バージョン10.15.1
- シェル：zsh

## エイリアスとは？
**デフォルトのコマンド**を、**任意のコマンド**と紐付けるショートカットのような設定のこと。
以下のようなコマンドに活用すると効果的。

- 長くてタイプミスしやすい
- 使用頻度が高い

## エイリアスの登録先
使用シェルがzshなので`~/.zshrc`に記述します。
※使用シェルがbashなら`~/.bash_profile`。

## 設定方法
### ・基本構文と設定の読み込み
基本構文は以下のようになります。

```zsh:~/.zshrc
alias 任意のコマンド=‘元のコマンド’
```

このように記述をした後、zshを**再起動**するか以下コマンドを実行し、`~/.zshrc`を読み込みます。

```zsh:~/.zshrc
source ~/.zshrc
```

これで**任意コマンド**を入力すると、シェルが**元のコマンド**に展開してくれる状態になります。

### ・通常のエイリアス：Git関連など
こちらから拝借しました。
[zshにエイリアスとかいう奴入れたら人生の時間がn秒増えて神 - Qiita](https://qiita.com/Ancient_Scapes/items/abfb0673aa5df3274fc6)

Git関連の設定です。
通常のエイリアスの場合、コマンドの最初に入力する必要があります。

```zsh:~/.zshrc
alias gc-b=‘git checkout -b’
alias gc-m=‘git commit -m’
alias gp=‘git push’
```


### ・グローバルエイリアス：grepなど
こちらから拝借しました。
[zshのグローバルエイリアス - Qiita](https://qiita.com/hatchinee/items/5f4c815285c0a1464288)

**zshの機能**。bashでは不可。
`-g`を付けてエイリアスを設定すると、コマンドの任意の場所で展開出来る。

以下のような`|`を挟むコマンドを使用する際に有効。

```zsh:~.zshrc
alias -g @g=‘| grep’
alias -g @l=‘| less’
```

### ・【参考】Docker関連
こちらから拝借しました。
[Dockerのコマンドが長いのでalias設定した - Qiita](https://qiita.com/kulikala/items/f736629497a974ca82cb)

入力がひたすら面倒なので、**かなりの時短**になります。

```zsh:~.zshrc
alias d=‘docker’
alias dc=‘docker-compose’
alias dcnt=‘docker container’
alias dcur=‘docker container ls -f status=running -l -q’
alias dexec=‘docker container exec -it $(dcur)’
alias dimg=‘docker image’
alias drun=‘docker container run —rm -d’
alias drunit=‘docker container run —rm -it’
alias dstop=‘docker container stop $(dcur)’
```

## おわりに
**タイポ減！時短！楽！**でサイコーです！
もう`docker-compose`や`| grep`って打てない身体になりそう。:smirk:笑

各コマンドの理解が前提にはなりますが、もっとこういった時短になる情報は取り入れていかないと損ですね:sweat_smile:

## 参考にさせて頂いたサイト（いつもありがとうございます）
[Dockerのコマンドが長いのでalias設定した - Qiita](https://qiita.com/kulikala/items/f736629497a974ca82cb)
[zshにエイリアスとかいう奴入れたら人生の時間がn秒増えて神 - Qiita](https://qiita.com/Ancient_Scapes/items/abfb0673aa5df3274fc6)
[zshのグローバルエイリアス - Qiita](https://qiita.com/hatchinee/items/5f4c815285c0a1464288)
guard letとif letの使い分け

どちらもnilチェックとして使うと思いますが、使い分け方を学習したので
備忘録としてここに記す。

#guard letの使い方
基本構文

```swift
 guard let test3 = test else {
            // nilの場合の処理
            return
        }
```

nilの時にこれ以上処理を進めたくない場合はguard letを使用する
guard文は、条件を満たさない場合にreturn、break、throwなど、スコープを抜けるための処理を書かないとコンパイルエラーになります。
そのため、想定外の値で処理を続行してしまうというミスがなくなります。

#if letの使い方 
基本構文

```swift
if let hoge = nilValue {
    //nilじゃなかったらー
}
```

```swift
if let poge = controller.navigationController {
    poge.hidesBarsOnSwipe = true
    poge.hidesBarsOnTap = true
    poge.navigationBarHidden = false
    poge.popToRootViewControllerAnimated(true)
}
```

nilだったとしても処理を終わらせずに続行させたい場合はこちらがいいかもです？

#締め
アンラップは忘れずに！
SQLの基本検索

今回は簡単にSQLを使った検索を書きます。

# 基本操作

```bash
  SELECT "フィールド名(カラム名)" FROM "テーブル名" WHERE "条件";

最具体的に書くと
　SELECT "欲しいデータ(名前など)" 
　FROM "対象データベース(人物目録、商品一覧など)" 
　WHERE "1000円以上、10個以下など";

```

## SELECT 
   ```ruby
      SELECT name FROM chara;
      
      SELECT name,level FROM chara;
      「,」で複数指定!

      SELECT * FROM chara
      * で全部指定
   ```

## WHERE

  ```ruby
     SELECT * FROM chara WHERE 30 <= level;
     これで全部のキャラのうち、30level以上を検索することになる。
  ```
閉包テーブル(Closure Table)をナイーブツリー(Naive Trees)に変換してみる

# やったこと

前回記事「[閉包テーブル(Closure Table)で子ノードを取得してみる](https://qiita.com/onmi/items/533d6ccf0dc27fcacd41) 」でやったルートノードからの距離を取得する方法を応用し、閉包テーブルのデータ構造(祖先ノード、子孫ノード)をナイーブツリーのデータ構造（自身のノードと自身の親ノード）に変換してみた。


# 前提条件

前回と同様に閉包テーブルに対して以下の条件を設定

- 親ノードは１つまでとする  
※閉包テーブルのデータ構造は、複数の親ノードを持つこともできるみたいだが今回なし

上記前提がないと問い合わせ結果が正しく得られない

__解説につかうツリー構造のイメージ__
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514634/89354742-765d-8486-86a3-fa7688e74fbd.png)

# 特定のノードと子孫ノードの距離を算出する（のおさらい）

解説につかうツリー構造でルートノードをBとしたとき
Bとの関係性は以下のSQLを実行することで距離の情報が得られる。


__テーブルとカラム__
- `tree`・・・閉包テーブル
- `descendent` ・・・子孫ノード
- `ancestor`・・・祖先ノード

```sql
SELECT t0.descendent
      ,count(*) as depth
  FROM tree t0 
  WHERE EXISTS ( 
      SELECT 1 
        FROM tree t1 
       WHERE t1.ancestor   = 'B(対象ノード)'
	     AND t1.descendent = t0.ancestor
    )
 GROUP BY descendent
```

上記のSQLによって得られる結果は、B自身の距離を1とした以下のような情報が得られる。


| 子孫ノード(descendent)   |距離(depth)  |
|:-----------------|:------------------|
| B                |1                  |
| D                |2                  |
| E                |2                  |
| F                |3                  |
| G                |3                  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514634/66aa6fdb-f2b8-3e23-3aa5-4e6ff07c3566.png)  



# 親子関係を抽出する方法

特定のノードと子孫ノードの距離を算出する方法は、ルートノード自身(B)を含めたルートノードを祖先に持つ子孫ノード（DEFG）が祖先になるデータ(図でいうとDEFGに向かって伸びている矢印)の数を集約している。
よって集約元のデータの中には親子関係を表す情報が含まれているのでこちらを抽出すればよい。

親子関係にあるということは２つのノードが

- 祖先ノード、子孫ノードの関係にある
- 祖先ノードと子孫ノードの距離が１である

という条件を満たす必要があるので距離を集約元の情報（緑矢印）に集約後の距離情報を与えてやると祖先ノードと子孫ノードの距離関係を知ることができる。
この距離情報を

- ルートノードと子孫ノードの距離 = ルートノードと祖先ノードの距離 + 1

となるように条件指定することで親子関係にあるノードの情報を抽出できる。
これらをSQLにまとめると以下のような感じになる。

```sql
-- ① 集約前のデータ（ルートノードに対する子孫ノードの子孫関係）
WITH temp1 AS ( 
  SELECT t0.ancestor
        ,t0.descendent 
    FROM tree t0
    WHERE
      EXISTS ( 
        SELECT 1 
          FROM tree t1 
         WHERE t1.ancestor   = 'B(対象のノード)' 
           AND t1.descendent = t0.ancestor
      )
)
-- ② 集約後のデータ(ルートノードの子孫ノードの距離情報)
, temp2 AS ( 
  SELECT descendent
        ,count(*) as depth
    FROM temp1 
   GROUP BY descendent
)
-- ①の祖先、子孫ノードに②の距離情報を結合し
--「子孫ノードの距離 = 祖先ノードの距離 ＋１」
-- となっているデータを抽出する
SELECT a1.descendent as child
      ,a1.ancestor   as parent
  FROM temp1 a1
  JOIN temp2 a2
    ON a1.ancestor = a2.descendent
  JOIN temp2 a3
    ON a1.descendent = a3.descendent
 WHERE a3.depth = a2.depth + 1

```

実行結果としては以下のような感じになる。

|子ノード(child)   | 親ノード(parent)     |
|:------------------|:-----------------|
|B                  | D                |
|B                  | E                |
|D                  | F                |
|D                  | G                |

図では緑矢印の矢印の元と先の位置の差が1になるもの(青矢印)を抽出している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/514634/65e562c2-3cf6-3900-881c-3141bca3456c.png)
Kotlinで小数末尾の0を取り除く

正規表現（Regex）を使って実装してみる

## ケース1

22.0000のような数値文字列を22にする

```kotlin
fun main() {
    val str = "22.0000"

    val regex = Regex(".0+\$")

    val result = regex.replace(str, "") // 22
}
```

正規表現 `.0+$` を使って `.000000` 部分にマッチさせて空文字にリプレースしてる。
Kotlinの文字列にするときは `.0+\$` のように$をエスケープさせなくちゃいけないことに注意

あと、ついやりがちだけど、 `""".0+$"""` もダメ。今度は `.` が小数点じゃなくて正規表現の意味にとられるから。

## ケース2

22.22200のような数値文字列を22.222にする

```kotlin
fun main() {
    val str = "22.0000"

    val regex = Regex("""0+$""")

    val result = regex.replace(str, "") // 22
}
```

今度は `0+$` を使ってやればおｋ
Robloxで爆弾をつくる

# 画像イメージ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/6a1fbd16-a7be-2635-c57b-c55ffec95512.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/113240c9-3c3a-dfff-6da0-d28f917bb476.png)


- ServerScriptServiceの中にScriptを追加。名前はBombGenerator
- PartでSphereをつくり、名前はBombにする。ServerStorageへ移動させる。
- BombにScriptを追加して、名前はBombScriptにする。
- （完成図は以下の赤いわくのとおり）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206887/86ec7831-f51b-95c6-ae05-259c2f78840b.png)

# プログラミングの中身

``` BombGenerator.lua
local Debris = game:GetService("Debris")
-- ServerStorageの中のBombを取得してbomb変数に入れる
local bomb = game:GetService("ServerStorage").Bomb

while(1) do
  wait(1)	
  -- workspaceにBombオブジェクトが無ければ、新しくクローンする
  local isBomb = workspace:FindFirstChild("Bomb")
  if (not isBomb) then
	  -- 爆弾を1つクローンする
	  local clonedBomb = bomb:clone()
	
	  -- 適当な場所に置く
	  clonedBomb.Position = Vector3.new(-10, 2, 200)
	  clonedBomb.Parent = workspace
	
	  -- Debrisサービスに追加することでマップ上に姿を表す
	  Debris:AddItem(clonedBomb, 20)
  end
end
```

``` BombScript.lua
-- BombにぶつかったPartが、hitという引数に入る
-- Playerは複数のPartで作られています。
local function explosion(hit)
  -- hitの親、つまりPlayerオブジェクトをtouchObject変数にいれます
  local touchObject = hit.Parent
  -- もしぶつかってきたものがHumanoidという子オブジェクトを持っていたら爆発します
  -- PlayerオブジェクトだけがHumanoidという子オブジェクトを持っています
  local humanoid = touchObject:FindFirstChildWhichIsA("Humanoid")
  if humanoid then		
	local exp = Instance.new('Explosion')
		exp.Position = hit.Position
		exp.Parent = workspace
	end
end

-- Workspace内のBombに触れたら、explosion関数が起動する
Workspace.Bomb.Touched:connect(explosion)

```

# 元記事
>https://developer.roblox.com/en-us/recipes/How-to-kill-a-Roblox-character-with-kill
Linux コマンド一覧表


機能に続いてLinuxのコマンドについてまとめようと思います。
# 詳細コマンド
## manコマンド(コマンド内容表示)
基本の前にmanコマンドを書きます。
対象のコマンドの使い方や使用できるオプションを調べることができますので。
最初に知っておくべきです。

```bash
$ man コマンド名
```

## その他詳細内容コマンド

|コマンド|説明|オプションまたは使用例|
|:-:|:-:|:-:|
|whatis|コマンドの簡単な説明を表示|	
|which	|コマンドの保存先を調べる|
|type	|コマンドの保存先を調べる|	-a 全ての保存先を表示|
|apropos|	コマンドをキーワードで検索|	
|find	|ファイルの検索。find ディレクトリ名 -name ファイル名で検索できる。|-name ファイル名<br>-typeタイプ（d: ディレクトリ、f: ファイル、l: シンボリックリンク）<br>-mtime 変更日時（-3で3日前から現在、+3で3日前よりも前）<br>-sizeサイズ|
|cal|	カレンダーの表示	|例） cal 11 2018|
|date|	日付の表示	|
|pwd|	いまいるディレクトリの表示（print working directory）|	



# 基本コマンド(常用コマンド)

| コマンド | 説明 | 使用例  | オプション　|
|:-:|:-:|:-:|:-:|
| cd | ディレクトリ（フォルダ）移動 | cd 移動フォルダ名 |
| ls |フォルダの内容をリスト形式で表示する | 対象フォルダに移動して、ls |-a システムファイル表示<br>-l ロングフォーマット<br>-d 指定のディレクトリ情報のみ表示|
| mv | ファイルを移動 | mv 移動元 移動先　 |
| cp |ファイルやフォルダをコピーする |cp 移動元 移動先　 |-i インタラクティブモード<br>-p ファイルの属性を維持<br>-R 丸ごとコピー<br>-v コピーされたファイル名の表示
| clear | 消さずに画面を綺麗にする | - |
| mkdir | フォルダを作成する　 | mkdir 名 |-p 入れ子のフォルダを一気に作成
| touch | ファイルを作成する |touch 名 |
| rmdir | 空のフォルダを削除する | rmdir 名 |
| rm | ファイルやフォルダを削除する | rm 名 |-r ディレクトリとディレクトリ内の全てのファイルを削除。確認は無し|
| pwd |現在いる位置を表示する |  - |
| find | ファイルの検索をする  | find / -name 名 |
| cat | ファイルの内容を表示する|  cat ファイル名 |-n 行数表示 |
| diff | ファイルとファイルの内容の違いを表示する | diff 旧名 新名 |
| grep | 指定した文字列がテキスト内に存在した場合その行を抽出する  |grep "検索したい文字" * ファイル名 |
| chmod | ファイルやフォルダのアクセス権限を変更する | chmod 権限ファイル名 |
| chown | ファイルやフォルダのオーナーやグループを変更する | chown 変更したいユーザー名 変更したいファイル名 |
| history | コマンドの履歴を表示する | - |
| ln | ファイルやフォルダにリンクを設定する | ln リンク元　リンク先 |
| man | コマンドのマニュアルを表示する | man コマンド |
| apropos | manページの内容を検索する | apropos キーワード |
| less | テキストファイルを閲覧する | less ファイル名 |
| more | ファイルをページ単位で閲覧する | more ファイル名 |

# ユーザー管理
| コマンド | 説明 |
|:-:|:-:|
| useradd/adduser | ユーザーを新規作成する |
| deluser | ユーザーを削除する |
| groupadd | グループを新規作成する |
| groupdel | グループを削除する |
| chfn | ユーザー情報を変更する |

# システム管理
| コマンド | 説明 |
|:-:|:-:|
| free | 空きメモリや、使用中メモリを表示する | 
|last | 最近ログインしたユーザー名を表示する  |
|finger | ユーザー情報を表示する |

#ネットワーク関連を設定したい時
| コマンド | 説明 |
|:--|--:|
| route | ルーティングの表示や設定を行う |
| ftp |ファイルをFTPで転送する |
| ssh |sshでログインする |

# ショートカット
少し違いますが便利な知識です。

| ショートカットキー | 説明 |
|:--|:--|
| ↑ ↓ | コマンド履歴を順に表示 |
| tabキー |フォルダやファイル名の予測変換 |
| Ctr(control) + a | カーソルを先頭に |
| Ctr + e | カーソルを終端に |
| Ctr + b | カーソルを一文字戻す |
| Ctr + f | カーソルを一文字進める |
| Ctr + d | カーソル位置の文字を消す |
| Ctr + h | カーソル位置の左側の文字を消す |
| Ctr + w | カーソル位置の左側の単語を消す |
| Ctr + r | コマンド履歴の中で検索する |
gemってなんなの？ぴえーん（＾_＾）

#gemについて

なんかgemについての説明で、
管理ツールだのパッケージだのライブラリだの色々言ってて意味わかんなかったので
gemについてまとめてみることにしました。ぴえーん




##gemとは

よくgemはパッケージ管理ツールですって説明されてるけど、厳密には違う気がする。
gemとは、Rubyを使うときに役に立つ便利な機能を作ってまとめてくれたもの(ライブラリ)のこと。
パッケージとして配信されたりしてる
わかりやすい例でいうと、deviseはインストールするだけでログイン機能とか作れるし

ちなみにrailsもgem（＾_＾）

######じゃあgemはパッケージ管理ツールですっていうやつは何？


##Rubygems

gemはパッケージ管理ツールっていう説明は間違ってるのかというと、そういうわけではない。
パッケージ管理ツールのgemは、正式には**Rubygems**といって、gem(パッケージ)を作成したり、公開したり、インストールしたりできる。



##bundler

gemを管理するものとして、bundlerというものもある。ちなみに。bundlerもgem!!
Rubygemsとbundlerの違いは、bundlerはgemfileとgemfile.lockにしたがってgemを管理できるやつ。だからgemfileに`gem 'devise'`って書いたらdevise入る(^.^)
**Rubygems**より**bundler**の方が使う！！！！


なぜなら、bundlerはgemとそれに依存してるgemもまとめて管理できるから！


んんんん〜〜〜〜むずかしい！
PythonでC(++)のヘッダファイル(.h)からマクロ定数を取得

「PythonとC++で定数を共有したい，かつC++側の定数はコンパイル時に確定させたい，かつPythonでも同じ変数を使いたい」という特異な例があったのでメモ．

Pythonから.hで定義された

```c++:sample.h
#ifndef _PARAM
#define _PARAM

#define NUM 10
#define epoch 100

#endif
```
と言うような定数を取り出す．今回は，`const int`などで定義したグローバル変数は場合分けがめんどくさいので考えません．

```python
def read_header_and_get_macro(header_filepath):
    with open(header_filepath, mode='r') as f:
        lst = [s.strip() for s in f.readlines()]
    comment_flg = False
    for l in lst:
        items = l.split()
        if len(items) != 0 and items[0] == "/*":
            comment_flg = True
            continue
        if comment_flg == True:
            if len(items) != 0 and items[0] == "*/":
                comment_flg = False
            continue
        if len(items) < 2 or items[0] != "#define":
            continue
        if items[1] in globals():
            if items[2] == 'true':
                globals()[items[1]] = True
            elif items[2] == 'false':
                globals()[items[1]] = False
            else:
                try:
                    globals()[items[1]] = float(items[2])
                except ValueError:
                    try:
                        globals()[items[1]] = int(items[2])
                    except ValueError:
                        globals()[items[1]] = items[2]
```

#やっていること
```python:3行目
    lst = [s.strip() for s in f.readlines()]
```
ファイルを読み込んで行ごとにリストにする．今回は行ごとのリストをとってきてそれをリストで回したけど別に`f.readline()`をfor文回すのは自由

```python:4行目
    comment_flg = False
```
C(++)では`/*`から始まって`*/`で終わるまでの間は全てコメントなので，これを覚えておくためのフラグ．

```python:6行目
        items = l.split()
```
行の中身について，半角スペースなどでわけられているところを分けたリストを取得．

```
['#define', 'NUM', '10']
```
みたいなリストがほしかった．

```python:7行目~13行目
        if len(items) != 0 and items[0] == "/*":
            comment_flg = True
            continue
        if comment_flg == True:
            if len(items) != 0 and items[0] == "*/":
                comment_flg = False
            continue
```
上記の通り，コメントを除く．


```python:14行目~15行目
        if len(items) < 2 or items[0] != "#define":
            continue
```
`#define`から始まらない行はマクロを定義していないので除く．

```python:16行目~28行目
        if items[1] in globals():
            if items[2] == 'true':
                globals()[items[1]] = True
            elif items[2] == 'false':
                globals()[items[1]] = False
            else:
                try:
                    globals()[items[1]] = float(items[2])
                except ValueError:
                    try:
                        globals()[items[1]] = int(items[2])
                    except ValueError:
                        globals()[items[1]] = items[2]
```
今までのもの以外のものが定数のはずです．このとき， `items[1]`には定数名が入っているはずなので，これがグローバル変数として定義されているかチェックするために`items[1] in globals()`をします．もしも定義されていれば， `globals()[items[1]]`でその値がわかるので，変数を強制的に書き換えれば完成．ですが，C++のbool型をPythonにそろえてあげる処理をしているのと，float/int/strの変換も行っています．
Windows環境でVSCodeでのRuby on Railsの開発環境構築手順

※ Rubyの推奨環境はLinux?とはいえWindowsしか持ってないよ！って人向けです

# 1.Rubyのインストール

Rubyで開発する上で、最も必要なものはRubyのインストールなので
https://rubyinstaller.org/downloads/
からRuby + Devkitをダウンロードする

ダウンロードしたらexeファイルを実行してインストールをする

インストールしたら、
```
ruby -v
```
コマンドを実行、バージョンが表示されたならばOK
バージョンが表示されなければ、Rubyをインストールしたパスの下の/binフォルダにパスを通す

2.Git bashのインストール

https://gitforwindows.org/
からgitをダウンロードし、インストールする

3.VSCodeのインストール、環境整備

https://code.visualstudio.com/
より、VisualStudioCodeをダウンロードし
exeファイルを実行してインストールする

EXTENSIONSを選択し、Rubyを選択してこれもインストールする

![rubydevenv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501968/8e87a7b0-ce74-e36b-e774-cb744ef43b96.png)

その後、VSCode左下の歯車をクリック

検索欄に、「terminal.integrated.shell.windows」と入力して
表示される「Edit in setting.json」をクリックする

![rubydevenv2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501968/9824a342-c0cf-16cf-dcb6-92258d336673.png)

```
    "terminal.integrated.shell.windows": "C:\\Program Files\\Git\\bin\\bash.exe"
```

と入力する

すると、VSCode下部のターミナルがGit Bashに変更される

ターミナルから、rails コマンドが実行できるので統合開発環境として活用可能に
![rubydevenv4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501968/9f7cdeee-daa6-6805-9b4b-888e9d69dcee.png)
ラオ・ブラックウェルの定理で決定関数を改善してみる

# 背景
最近はラオ・ブラックウェルの定理というものを勉強していました。これを用いると決定関数を改善出来る可能性があるということらしいです。字面を追っているだけだとよくわからないので、教科書に載っていない例を自分で数値実験してみることにしました。

# ラオ・ブラックウェルの定理とは
ある決定関数$\delta(X)$があるとします。十分統計量$T$を考え、その条件付期待値により計算される$\delta^*(T)=E[\delta(X)|T]$を考えます。$T$に依存しますのでこれもまた統計量です。これについて

$$
E[(\delta^*(T)-\theta)^2]\leq E[(\delta(T)-\theta)^2]
$$
が成立します。これをラオ・ブラックウェルの定理といいます。これを用いて決定関数を改善するためには

1. 決定関数と十分統計量を用意する
2. 条件付期待値により統計量$\delta^*(T)$を作る
3. 標本から$\delta^*(T)$の期待値を得る

という手順を踏めばOKです。

# 数値実験
条件付期待値を計算しなければならないので、以前計算した結果を利用するため、ポアソン分布からのサンプリングを考えます。標本サイズは$2$とします。改良前の決定関数としては$\delta(X)=X_0$を採用します。条件付期待値は

$$
\delta^*(t) = \sum_{x_0=0}^t x_0 p(x|T=t)=\sum_{x_0=0}^t p(x|t) =\sum_{x_0=0}^t x_0\times \frac{1}{x_0!(t-x_0)!}\frac{1}{\sum_{n=0}^t\frac{1}{n!(t-n)!}}
$$

となります（[十分統計量の値をリサンプリングして母分布の概形を得る](https://qiita.com/jajagacchi/items/b99c4cf23238ed31229)の計算結果を利用しました）。
これは明らかに$T$の関数であり、統計量となっています。改良どころか本当にこれで推定出来るんだろうか、不安になってきました・・・。
とにかくやってみます。$\lambda=5$とし、その推定を繰り返します。

```c++
#include <iostream>
#include <random>
#include <vector>
#include <fstream>

int factorial(int k)
{
	int ret = 1;
	for (int i=1; i<=k; i++)
	{
		ret *= i;
	}
	return ret;
}

int main(int argc, char **argv)
{
	double lambda = 5;
	std::mt19937 mt(atoi(argv[1]));
	int Iter = 1000;
	std::poisson_distribution<> poi(lambda);

	double sum = 0;//改良後
	double sum2 = 0;//改良前
	for(int iter=0; iter<Iter; iter++)
	{
		double x0 = poi(mt);
		double x1 = poi(mt);
		double t = (x0+x1);
		double num = 0, den = 0;
		for(int n=0; n<=t; n++)
		{
			num += (double)n/factorial(n)/factorial(t-n);
			den += 1./factorial(n)/factorial(t-n);
		}
		sum += num/den / (double)(Iter);
		sum2 += x0 / (double)Iter;

	}
	std::cout << sum2 << " " << sum << std::endl;
	return 0;
}
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/520857/703c6675-c01d-67e6-5e15-809164c14e1d.png)
紫が改善前、緑が改善後です。改善後も$5$付近が中心となっており、ばらつきが小さくなっていることが確認できました。

# まとめ
ラオ・ブラックウェルの定理により推定方法を改善出来ることが数値的に確認できました。
CircleCI + BackstopJS (Puppeteer) でビジュアルリグレッションテストを継続的に監視する

# Overview
CircleCIとBackstopJSを組み合わせて、『継続的にWebページの視覚的な変化を監視するツール』を作成しました。
https://github.com/Silver-birder/silver-enigma

![backstopjs](https://res.cloudinary.com/silverbirder/image/upload/v1573651959/backstopjs/backstopjs.png)

# Motivation
Webアプリを運用する上で、システム改善は継続的に行われます。
そのシステム改善をリリースする前に、入念なテスト（ユニットテスト、インテグレーションテスト、E2Eテスト）をパスする必要があります。しかし、Webアプリの規模が大きくなるにつれて、**意図せずデグレ**が発生してしまう可能性が大きくなります。
そのデグレを気づくのが『社内部指摘』なのか『エンドユーザからのお問い合わせ』からなのか分かりません。
そこで、**Webアプリを定期的に監視すること**で、予想外なデグレッションを早期に発見できる仕組みが欲しくなりました。

必要とする要件は、次のとおりです。

* スケジューリング実行可能
  * 無料で使えること
* わかりやすい視覚的変化のレポート
* カスタマイズしやすい監視方法

ここから、CircleCI + BackstopJS(Puppeteer)という組み合わせが生まれました。

# Usage
次の手順で構築できます。

```bash:環境
~ $ node -v
v12.9.1
```

1. backstop.jsonに監視したいURLを設定
2. CircleCIに必要な環境変数を設定([README.md](https://github.com/Silver-birder/silver-enigma/blob/master/README.md)参照)
3. CircleCIでJobを実行し、Artifactsにあるレポートを閲覧

Puppeteerを使ってWebアプリへリクエストしています。
そのため、『Javascriptを無効にする』や『Cookieを設定する』といったニーズに対応できます。

# Conclusion
このツールにより、外部からWebアプリの変化を早期に発見できるようになりました。
ただし、リクエストするスケジューリング間隔には十分にお気をつけください。
リクエストをしすぎると、対象Webアプリの負荷が高まってしまいます。
「Office Ribbon Editor 」を使って、リボンUIにマクロ実行ボタン追加

# はじめに
- 現状：マクロを複数作りましたが、マクロファイルばかり増殖して未活用でした。作成したマクロファイルを探して開いて実行するのが億劫で、結局マクロを使わず作業を始めてました。
- 問題点：しかし、作業の生産性がやっぱり悪いです。なんとかしたい。
- 解決策：そこで、リボンUIカスタマイズソフトを利用して、マクロ実行ボタンを作成しました。

# 完成イメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/132e457f-14ef-6ffe-8e8a-250d4f815177.png)
## 動作環境
- Windows10
- Office365 or Office2010

## リボンUIのカスタマイズソフト
カスタマイズソフトは２種類あります。インストール方法はリンク先を参照願います。サポート終了していますが、私は１のOffice Ribbon Editorを利用中

1. Office Ribbon Editor →[インストール方法](https://www.saka-en.com/office/office-ribbon-editor-install/)（サポート終了）
2. Custom UI Editor Tool →[インストール方法と使い方](https://www.saka-en.com/office/custom-ui-editor-tool-install/)

# リボンUI側の作成例
- リボンUIはXMLベースで作れます。
- カスタマイズソフトでは、雛形を自動作成してくれます。あとは、自分好みにカスタマイズ
- 各buttonの「onAction=」後の""内に、実行したいマクロのプロシージャ名を入力します。（例：google）

```xml
<customUI xmlns="http://schemas.microsoft.com/office/2009/07/customui">
	<ribbon startFromScratch="false">
		<tabs>
			<tab id="ad" label="myHome00.85">
				<group id="web" label="link">
					<button id="web_link" label="google" 
					imageMso="G" size="normal" onAction="google" />
					<button id="web_uni" label="Unicode" 
					imageMso="U" size="normal" onAction="The Unicode Consortium" />	
				</group>

				<group id="sagyo" label="作業">				
					<button id="haba_size" label="行列幅自動調整" 
					imageMso="G" size="normal" onAction="行列幅自動調整" />
					<button id="half_size" label="英数仮名→半角" 
					imageMso="S" size="normal" onAction="英数仮名→半角" />
					<button id="uni_do" label="unicode表処理" 
					imageMso="S" size="normal" onAction="unicode表処理" />		
				</group>
<!--省略-->
			</tab>
		</tabs>
	</ribbon>
</customUI>
```

# VBA側の作成例
- プロシージャ名「google」後の括弧（　）内は「***control As IRibbonControl***」と入力します。(お約束)
- 以下は、ボタンを押すとIEでGoogle検索サイトを開くマクロ例です。

```vb
Option Explicit
Sub google(control As IRibbonControl)
    Dim objIE As Object
    Set objIE = CreateObject("InternetExplorer.Application")  
    objIE.Visible = True
    objIE.Navigate ("https://www.google.co.jp/")
End Sub
```

# 動作確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/157498/2b171b7f-1efa-788e-183e-82560bcc9f80.png)
※開きました。

## 補足
- カスタマイズソフトを利用しなくても、自作で作成可能のようですが、ちょっと大変。
PyCharmでSSHトンネル経由でDBに接続する

PyCharm 2019.2で実行しているが、Jetbrains IDEにあるDatabaseを利用しているので、他のでも設定項目はほぼ同じだと思う。

## 設定を作成する

1. `C-S-a` でActionsを開いて、`Database`と入力してDatabaseを開く。
2. `New` -> `Data Source`から目的のDBの種類を選部。

するとこんな感じのウインドウが開く。
![new data source](https://i.gyazo.com/9071803c3acf1f0a9bf47529873a66fc.png)


## SSH/SSLの設定

設定イメージ
![ssh/ssl](https://i.gyazo.com/c3bc6bc58611082504a1fb1d058a66bd.png)

`Proxy host`: 単にSSH接続するホスト。
`Local port`: 入力しないと自動で振ってくれる。 他でもそのトンネルを利用したいのであれば値を入力する。
`Auth type`: 認証方法の選択。 `OpenSSH config and authentication agent` は良く分からん。


## Generalの設定

設定イメージ
![general](https://i.gyazo.com/22db19df7190b202dfc3471c108a534a.png)

`Host`: SSHで接続しているサーバーから見たDBのホスト名。


必要なものが入力し終わったら、Generalにある`Test Connection`を押して接続を確認する。