OmniAICreator/Qiita-1.07M huggingface dataset:
42種ものデータ変形がブラウザだけでできる『transform』が便利そう

transformは、なんでもデータ変形サービスで、JSONからYAML、HTMLからJSXへの変形はもちろん、JSONやGraphQLのIDLからTypeScriptのinterfaceを生成するようなものまで手広く対応しているサービスだ。

https://transform.tools/


![transform.tools2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/889/06bffa55-694e-b04a-d0c0-e74154154350.gif)

特別なツールをインストールする必要はなくブラウザだけで動作する。

現在、42種類のデータ変形に対応しており、対応している変形パターンは下記のとおり:

1. SVG to JSX
1. SVG to React Native
1. HTML to JSX
1. JSON to React PropTypes
1. JSON to Flow
1. JSON to GraphQL
1. JSON to TypeScript
1. JSON to MobX-State-Tree Model
1. JSON to Sarcastic
1. JSON to io-ts
1. JSON to Rust Serde
1. JSON to Mongoose Schema
1. JSON to Big Query Schema
1. JSON to MySQL
1. JSON to Scala Case Class
1. JSON to Go Struct
1. JSON to YAML
1. JSON to JSDoc
1. JSON Schema to TypeScript
1. JSON Schema to OpenAPI Schema
1. CSS to JS Objects
1. CSS to template literal
1. JavaScript to JSON
1. GraphQL to TypeScript
1. GraphQL to Flow
1. GraphQL to JAVA
1. GraphQL to Resolvers Signature
1. GraphQL to Introspection JSON
1. GraphQL to Schema AST
1. GraphQL to Fragment Matcher
1. GraphQL to Components
1. GraphQL to TypeScript MongoDB
1. JSON-LD to N-Quads
1. JSON-LD to Expanded
1. JSON-LD to Compacted
1. JSON-LD to Flattened
1. JSON-LD to Framed
1. JSON-LD to Normalized
1. Flow to Typescript
1. XML to JSON
1. YAML to JSON
1. Markdown to HTML

## どんなときに使うといいか？

例えば

* Reactコンポーネントを作っていて、素材となるHTMLをJSXにしたいとき。
* JSON APIのレスポンスをTypeScriptで扱う際、レスポンスJSONの型をTypeScriptのinterfaceで定義したいとき
    * ScalaやGoでも同様

こういったシーンで、手っ取り早く仕事を済ますときに使えそう。
Slackで任意のスレッドの通知をなくす方法

自分へのメンションに対してSlackの通知をオンにしている場合、スレッド内で自分へのメンションが含まれるとそのスレッドが更新されるたびに通知がきます。

自分に関係するスレッドであればいいのですが、**スレッドに巻き込まれた場合や、会話が発展してもはや自分がスレッドの内容を追わなくてもいいという場合は毎回スレッドの通知がくるのはわずらわしい**です。

そのような場合は、**『スレッドの通知をオフにする』**とよいです。

## スレッドの通知をオフにする手順

1. 通知を消したいスレッドの先頭のメッセージの右上にカーソルを移動させて『その他』を選択します。
![a83f662c-c056-602d-95e4-6449e35ab06f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/f969972b-9ef7-3478-9f2d-ead10930c657.png)

1. 次に、『スレッドのフォローを終了する』という項目があるのでそれを選択します。
![5fc055bd-085e-7b6d-7359-6c8bc1bc8fef.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140792/f91bfe93-46f7-db37-c361-ae4029a5858b.png)
SQLの副問合せ

今回はSQLの副問合せについて説明します。
副問い合わせとは、SQLの中で入れ子式にSQLを指定することを言います。
説明だけでは分かりづらいので、具体例を出してみましょう。

まず、「出席番号0001の人と同じ学部の人を検索する」ケース。
この場合、副問い合わせを使わずにSQLを書こうとすると、二つの手順を踏む必要があります。

- 出席番号0001の生徒の学部を取得する
- 取得した学部を使って、同一の学部の生徒を取得する

しかし副問い合わせを使えば、この二つの手順を一つにまとめることができます。
書き方は以下の通り。

```ruby:副問い合わせ①
SELECT * FROM T_STUDENT
    WHERE GAKUBU = (SELECT GAKUBU FROM T_STUDENT WHERE NO = '0001')
```

次に、「テストの点数が最も低かった生徒を取得する」ケース。
これについても、やはり以下のように二つの手順があります。

- 最も低い点数を検索する
- 取得した点数を使って、生徒を取得する

```ruby:副問い合わせ②
SELECT * FROM T_TEST
    WHERE SCORE = (SELECT MIN(SCORE) FROM T_TEST)
```

このように、グループ関数と組み合わせて副問い合わせを行うこともできます。
曜日ごとに日替わり画像を表示する

# 準備

日替わり画像にidを指定する

```html:html
<img id="daily_image" src="dummy.jpg" alt="日替わり画像">
```
日替わり画像を挿入するjsを作る

```js:js
(function() {
    "use strict";
    var target_id = "daily_image"
      , image_list = ["sun.jpg", "mon.jpg", "tue.jpg", "wed.jpg", "thu.jpg", "fri.jpg", "sat.jpg"]
      , target = document.getElementById(target_id)
      , weekday = new Date().getDay();

    target.src = image_list[weekday];
}());
```

### 完成形

```html:weekday_test.html
<!doctype html>
<meta charset="utf-8">
<title>日替わり画像のテスト</title>

<img id="daily_image" src="dummy.jpg" alt="日替わり画像">
<script>
    (function() {
        "use strict";
        var target_id = "daily_image"
          , image_list = ["sun.jpg", "mon.jpg", "tue.jpg", "wed.jpg", "thu.jpg", "fri.jpg", "sat.jpg"]
          , target = document.getElementById(target_id)
          , weekday = new Date().getDay();

        target.src = image_list[weekday];

    }());
</script>
```

# 実験

完成形を読み込むと

```html:html
<img id="daily_image" src="dummy.jpg" alt="日替わり画像">
```

の部分が

```html:html
<img id="daily_image" src="wed.jpg" alt="日替わり画像">
```
に変換される
※この記事を書いた日が水曜日であるため、wed.jpgとなっております。
OutsystemsのGoogle Cloud Vision OCRを使ってみた

#はじめに

ある日、プロジェクトでOCRの技術検証をしていました。
いつもの如く、あんまりドキュメントないなーと思ったのでここに記します。

内容としては、Google Cloud Vision OCRの簡単な使い方になります。
既存のDEMOアプリがベースになります。

#想定読者
OutsystemsでOCR使おっかなーって思っている方
Google Vision APIってどうなの？と思っている方

#事前準備
■Forgeから下記モジュールをDL
https://www.outsystems.com/forge/component-overview/1572/googlecloudvisionocr

※ちなみにDLしなくても、「Try Now」ボタンを押下することでWEB上でOCRの検証はできるようになってます。


■Google Vision APIのAPIキーを取得

こちらに詳しくまとめてありました。
[Google Cloud Vision APIで文字認識を試してみる](https://qiita.com/saken649/items/4bfd215bf943c36a52ab)


#できること

Google Vision APIにはいろいろOCRの機能がありますが、このForgeは文字識別のみ対応しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/1449bb51-4593-6a9d-eb04-9e9bb0177a38.png)

今回は文字認識の中でも、下記2つを使ってみました。
※デフォルトは、「TEXT_DETECTION」でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/bdb3a59e-841f-44c2-4615-54c948815d3c.png)



その他の機能はこちらをご確認ください。
https://cloud.google.com/vision/pricing?hl=ja



###①DEMOの画面を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/04b77bab-cc0f-10c1-27bc-bf09df856378.png)

###②事前に用意したAPIキーをセット
![WS000014.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/83ec379a-2b8f-d81f-1f15-a91855711ab7.jpeg)

###③Processボタンを押下して、結果を取得
まぁそこそこ取得できている:D
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/74780062-3eb7-bf16-fd11-b04964cfad85.png)

###④DOCUMENT_TEXT_DETECTIONに変えてテスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/02f59ce0-7633-3734-4a5b-1444ab597dfa.png)

helper.csのtypeを「TEXT_DETECTION」を「DOCUMENT_TEXT_DETECTION」に修正してPublish。

```
var feature = new Feature { Type = "DOCUMENT_TEXT_DETECTION" };
```

・・・・・しかし、結果はTEXT_DETECTIONと変わらず
![akutagawa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/aef7f9a0-f933-5400-52ab-2048829236f1.png)



免許書の写真とかでやってみたら、わずかに差はありました。


###⑥上記の取得した値をフォームなどに自動でセットしたい場合

戻り値はTEXT型で返していました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/130275/e517a4a4-a835-8d81-b1d9-99d366fa9b4b.png)


DEMOアプリを見ると、Extension側の「GetDateAndAmountRegex」アクションでゴリゴリ↑の戻り値をトリムしていました。
なので、そのトリムした値を画面上でセットする流れになります。
※Outsystems側でトリムしてもいけるとは思いますが。

私はこれから、「GetDateAndAmountRegex」アクションを参考にして、トリム処理を拡張していこうと思います。

#終わりに

Google Cloud Vision APIの他の機能もForgeで対応してほしい(切実)
精度は思ったほどではなかったですが、使いようによっては使えるかなレベル..
SQL*LoaderでCSVファイルの１フィールドを複数カラムにマップする方法。

# はじめに
ORACLE　SQL*Loaderを利用して、CSVファイルの１フィールド（１データ）を
テーブルの複数カラムにマップする方法がわからなかったので、調べてみました。
SQL*loaderの制御ファイルで以下のように記述することで実現できることを確認しました。
ちなみに動作確認で使用したORACLEのバーションは「11.2」です。

### ・CSVファイルのデータ2行（ファイル名：test_load1.txt、改行コード：CRLF）
![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454141/de7fd251-a25f-f978-e094-3ac101bb690c.png)
### ・ロード先のテスト用テーブル作成
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454141/dfeb5145-628d-e4fe-558d-2c5d0aabcc84.png)
### ・SQL*Loader制御ファイルの記述例(test_load.ctl)
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454141/222e5bec-9fdc-dcec-94e6-611ec84a2c86.png)
### ・SQL*Loaderの実行と結果表示
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/454141/0d1e8901-54d7-ddc7-c05a-fb35dd90d2b6.png)
Unityが非アクティブ時でもバックグラウンドで動作させる方法

Unity実行時にデフォルト設定だとUnityが非アクティブな状態時に
レンダリングと動作が止まってしまいます。
ダウンロード処理とか時間のかかる処理を実行させつつ
ブラウザで調べ物とか別のことをしたい時があります。
そんな時にUnityをバックグラウンドでも動作を止めない設定を教えてもらったのでメモします。

## 設定方法

1. メニュー→「File」→「BuildSettings」
2. 「BuildSettings」→「Player Settings」
3. inspector上で
 
![スクリーンショット 2019-07-24 10.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/127897b3-5dfe-7660-d505-108862efeeb4.png)
を選択

4.「Run In Background」にチェックを入れるとバックグラウンドで動作を継続します

![スクリーンショット 2019-07-24 10.26.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452135/4ddc23c4-1b78-5261-61fa-392b58081362.png)
Talend小技（１）２つの入力を結合させて１つに出力する

#**tUniteコンポーネントの活用**
２つの異なるフォーマットで同じカラムを持つファイルを読み込み、１つのファイルに出力する方法を紹介します。

##**入力ファイル**
２つのファイルはそれぞれ同じ２カラムを持ちますがフォーマットが異なります。
in1.csvは文字コードUTF-8、改行文字LF、区切り文字","、囲み文字ダブルクォーテーションであり、in2.csvは文字コードShift-JIS、改行文字CRLF、区切り文字","、囲み文字なしで設定します。
![tUnite_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463924/1814533b-b7ad-c935-6b10-3b1a1b2bad60.jpeg)

##**コンポーネントの設定と接続**
下図の様に、tFileInputDelimitedコンポーネントでそれぞれのフォーマットに設定し、２つのtFileInputDelimitedコンポーネントからのロウ・メインをtUnite_1コンポーネントに接続し、tUnite_1コンポーネントからのロウ・メインをtFileOututDelimitedに接続します。
tFileOututDelimitedでの出力フォーマットは文字コードUTF-8、改行文字LF、区切り文字","、囲み文字ダブルクォーテーションです。

![tUnite_1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463924/886418ff-06bf-abaa-8579-30eddb9881cf.jpeg)

##**実行結果**
Talend上での実行結果画面は下の様になります。
![tUnite_3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463924/86f24879-c146-c90a-53f7-d2fc08389824.jpeg)

##**ファイル出力結果**
出力先のout.csvには下図の様に出力されます。
![tUnite_4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463924/fde3bf5b-357f-b253-19fd-ab9dde00b189.jpeg)

#**まとめ**
このコンポーネントを活用すれば、カラムが同じであれば異なるデータベースのデータでも結合させることが可能になります。
[AWS]Aurora Serverless for PostgreSQLが休止状態から起動するまでの時間を調べた

# 概要
Aurora Serverless for PostgreSQLがGAになって少し経ちました。
AuroraのAutoScaling対応やRDSのストレージ自動拡張等が実装されProvisionedでもどんどん便利になっていますが、それでもServerLess版の手軽さはとても魅力的ですね。

私のチームでも早速Serverless版を利用しようと思いましたが、
ウリの一つである一定時間アクセスが無いと自動で休止する機能が、実際どの程度影響を及ぼすのか気になりましたので調べてみました。

# 調査方法
Aurora Serverlessが休止状態かどうかは、CloudWatchの「ServerlessDatabaseCapacity」の値で確認できます。
この値を60秒置きにチェックし、0のとき(=休止状態)のみDBに接続、
リクエストが返るまでの時間を記録するシェルスクリプトを作成しました。

Auroraは東京リージョンに作成、接続元は同じ東京リージョン上のEC2からとしました。

# 結果
とりあえず24回取りました。
![result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358513/3078c664-ae90-0f17-c483-ec736b6274fc.png)

|Time|Result(sec)|
|:-----------------|:------------------|:
|2019-07-23T06:51:05|38.095|
|2019-07-23T06:59:36|28.348|
|2019-07-23T07:07:18|23.734|
|2019-07-23T07:15:50|26.829|
|2019-07-23T07:23:20|39.639|
|2019-07-23T07:31:59|27.801|
|2019-07-23T07:40:37|26.824|
|2019-07-23T07:48:11|36.098|
|2019-07-23T07:56:49|34.107|
|2019-07-23T08:04:21|30.995|
|2019-07-23T08:13:51|34.447|
|2019-07-23T08:22:35|28.92|
|2019-07-23T08:30:01|26.74|
|2019-07-23T08:38:35|40.174|
|2019-07-23T08:46:02|22.82|
|2019-07-23T08:54:30|30.375|
|2019-07-23T09:02:55|23.834|
|2019-07-23T09:11:27|24.736|
|2019-07-23T09:20:57|20.693|
|2019-07-23T09:28:23|28.859|
|2019-07-23T09:35:42|26.474|
|2019-07-23T09:48:12|22.746|
|2019-07-23T09:57:45|30.394|
|2019-07-23T10:04:34|29.979|
*※環境とスクリプトが適当だったのでUTCだったり実行間隔がバラバラだったりしますがご容赦*

結果として、実行時間の平均値は「**29.32秒**」となりました。
MySQL版登場時に起動に数十秒～数分かかるという記事があがっていたのもあり、
相当悪いと覚悟してましたが、ギリギリ使えるかなという感じですね。

起動時間が気になる場合は、常時起動しておくこともできますが、
**「真夜中はほとんど接続が来ないが絶対ではない」** というサービスにとって、
本機能のコストメリットは影響度が非常に高いと思いますので、
キャッシュ等も利用してうまく付き合っていきたいですね。

# その他
本稿で調査したとおり、Aurora Serverless for PostgreSQLでは、
一定時間(最短5分最長24時間)未接続だと自動でインスタンスを停止してくれる機能がありますが、
この機能はデフォルトオフなのでご注意ください。（隠れてるので初見時見落とした）

また、Provisionedの感覚でCloudWatch等からヘルスチェック入れると
常時起動状態になってしまうことにも注意してください。

# 参考
https://dev.classmethod.jp/cloud/aws/aurora-serverless-mysql-generally-available/
https://dev.classmethod.jp/cloud/aws/aurora-postgresql-serverless-ga/
たった5分で自分だけのFitbit Clock Faceを作る

# はじめに
数年位前からFitbitの活動量計を愛用しております。
Fitbit Charge HRからはじまりFitbit Charge 2と買い替え、最近Fitbit Versa（と体重計のAria2）を購入しました。

Charge HR/2は画面のカスタマイズはあまりできなかったのですが、Fitbit VersaはスマートウォッチらしくClock Faceのカスタマイズが結構自由にできます。
開発環境の準備から実機インストールまでがとても楽だったことに感動したのでそのご紹介です。

Fitbitってなぁに？という人は公式サイトへGo
https://www.fitbit.com/jp/home

# 目的
5分以内で自分だけのFitbit Versa Clock Faceを作成し、**実機**で確認する。

# 準備するもの

1. Fitbit Versa
Wifiの設定はしておいてください。
（Fitbit Versaセットアップ時にやるのでかかる時間は0秒とします）

2. Fitbitのユーザアカウント
(Fitbitの利用者なら既にあるはずなのでかかる時間は0秒とします）

3. CSSの知識
（身に着けておいてください。0秒。）


# 作業開始！

## Fitbit Studioへのアクセス（所要時間1分）

https://studio.fitbit.com
![Top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/3a0efadd-bbb8-effc-1311-37e47d72831c.png)

右側のStartからFitbitのユーザアカウントでログインしてください

## Projectの作成（所要時間30秒）

![List.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/1d80ef70-6246-c140-c03c-df8de8d21133.png)
New Projectを押下し、

![Create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/b97a6888-600f-4f45-2328-ae78e0c66842.png)
Nameに適当な名前をいれて、
TemplateはDigital Clockを選び
Createを押下

![ide.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/3c5debf1-5090-9e65-d7ba-7df4a169ae43.png)

こんな画面がでてきたらOK！!

テンプレートとWebのIDEが準備されているのですごく楽ですね

## 自分だけのClock Faceを作る（所要時間30秒）

![css.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/bac3b7f9-24f0-82b1-3f64-d99a3f77f2bb.png)

時間がないのでresources/styles.cssのbackgroundのviewport-fillを適当に変えましょう！
redからblueに変えてみました。

## 実機にインストールする(所要時間3分）
Fitbit Versa実機の設定にあるDeveloper Bridgeを押下し、
[Disconnected]から[Connecting to Server]を経て[Connected to Server]になるまで待つ

Connected to Serverになったら、Web IDEの画面上部のデバイス選択部分から[Versa]が選択できるようになるので、
Versaを選択して[Run]を押下！！！！

![install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/893d4b11-bb4f-a108-f696-e9467e71bd6b.png)

十数秒かかるので気長に待ちましょう。

## 完成！
おつかれさまでした。
手元のVersaにはあなたオリジナルのClock Faceが表示されていることでしょう。

（イメージ画像）
![クリップボード01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/58a6317e-7152-1e89-8f80-2a6142b48e37.png)

# まとめ

- テンプレートが用意されていて楽！
- WebのIDEが用意されていて楽！
- 実機にインストールするのもボタン2つくらいで楽！
- （完成のところでチラッとみせた）Fitbitのシミュレータもあるので検証が楽！

簡単に作れるからキミも作ろう！

# To be Continued...?
上記をベースに某ゲームに登場するハンドヘルド端末風なClock Faceを作りました。（著作権とかｺﾞﾆｮｺﾞﾆｮなので非公開）
開発をしていく中でFitbitならではのできること、できないことがわかってきたのでTIPSとしてまとめるかもしれません。

![image.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/116002/a12a4ee6-10f7-ef00-c226-a4a008b09949.gif)


それではよきFitbitライフを
Gitがドチャクソ有能だった話

# ある日の弊社
ワイ「ああ、**昨日までに**Reactの環境構築をせなあかんかったのに、**Elmで遊んでもうた**・・・」
ワイ「環境構築できてへん・・・」

イケメン君（後輩）「やめ太郎さん、僕が構築しておきましたよ！（キラッ）」

ワイ「おお・・・！おおきにやで」
ワイ「（中身までイケメンやん）」
ワイ「（**鼻につくわぁ・・・**）」

リーダー「（やめ太郎、相変わらずクズやな・・・）」

# コンポーネント作り開始
ワイ「よっしゃ、そしたら次はコンポーネント作りや」
ワイ「ワイは**Reactよう分からん**から**北海道支社**の新人君にお願いしよか」
ワイ「早速Slackでお願いや」

> ワイ「おーい、北海道新人くん」
ワイ「Reactの環境構築**しといた**から」
ワイ「北海道新人くんは、コンポーネントの作成を頼むで！」
ワイ「サンプルとして**Example**っていうコンポーネントを（イケメン君が）作ったから」
ワイ「それを元に頼むわ！」

ワイ「よっしゃ、送信、と」

> 北海道新人くん「了解です！」
北海道新人くん「React案件はじめてなので、まずはExampleコンポーネントを色々いじってみますね！」

ワイ「うむうむ」
ワイ「よっしゃ、ワイは**Elmでもやろか**」

# ところが
リーダー「おい、やめ太郎」
リーダー「ディレクトリ構成は**Atomic Design**を参考にしろっていうたのに」
リーダー「全然なっとらんやんけ」

ワイ「（そういえばそんなこと言ってはった・・・！）」

イケメン君「この構成の方がいいじゃないですか！（キラッ）」

リーダー「ぐぬぬ」

ワイ「わ、分かりましたで」
ワイ「ワイがディレクトリ構成を修正しておきますわ」

# ディレクトリ再構成開始
ワイ「ええと、ほな**Exampleコンポーネント**のファイル一式は」
ワイ「**atoms**っていうディレクトリに移動させて、と」
ワイ「これでGitコミットや」
ワイ「ポチッ、と」

#### ワイ「しまった！！！」

ワイ「そういえば北海道新人くんが」

> 北海道新人くん「Exampleコンポーネントを**色々いじってみますね！**」

ワイ「って言うてたやん・・・！」
ワイ「なのに、Exampleコンポーネント関連のファイルを**移動してGitコミットしてもうた・・・**」
ワイ「これはGit君がマージしたときに、Exampleコンポーネントが**2つに増えてまう**感じか・・・？」
ワイ「めんどくさいわぁ・・・」
ワイ「どないしよか・・・」
ワイ「とりあえず**Elmでも勉強しよか・・・**」

リーダー「（**他言語の勉強！？今！？**）」

# 1時間経過
ワイ「やっぱElmは**シンプルに書けてええなぁ**・・・」

リーダー「（ほんまに他言語の勉強してるやん・・・）」

ワイ「・・・そんでReactのコンポーネントの件、結局どうなったんやろ」
ワイ「SourceTreeでリポジトリを覗いてみよか」
ワイ「あ、北海道新人くんがExampleコンポーネントを修正した分がコミットされてる・・・」
ワイ「やっぱExampleコンポーネントは2つに増えてもうたんやろか・・・？」

# ところが
ワイ「**！？**」
ワイ「2つに増えてへんわ・・・！」
ワイ「Exampleコンポーネントに、ちゃんと**北海道新人くんの修正も反映されとる**し」
ワイ「ちゃんと**ディレクトリも移動しとる**・・・！」
ワイ「そんなところまで上手いことマージしてくれるんか・・・！」

# 結論
**Gitドチャクソ有能でした。**
OpenOffice basicでテキストファイル書き出しのあれこれ

OpenOffice basicでテキストファイル書き出しに際しての情報をまとめておきます。

# Printステートメントを使った書き方
テキストファイルに1行ずつ出力する書き方です。この書き方をすると、1行ごとに改行コード(LF)が自動で付加されます。

## 基本文法

テキストファイルに1行ずつ出力する際には、下記のような形で書けばよいです。
これは最も良く知られている方法ですので、ほとんどのケースはこれで問題無いと思います。

``` VB:macro.vb
Dim FileNum As Integer
Dim CurrentLine As String
Dim Filename As String

FileNum = Freefile               ' ファイルハンドルを初期化 
Filename = "C:\temp_data.txt"    ' ファイルの場所

 
Open Filename For Output As #FileNum 'ファイルオープン
Print #FileNo, "Hello world!"    'Line1
Print #FileNo, "Goodby world!"   'Line2
Close #FileNo                    'ファイルクローズ
```

出力結果

```
Hello world!
Goodby world!
```

参考ページ：
https://wiki.openoffice.org/wiki/JA/Documentation/BASIC_Guide/Files_and_Directories_(Runtime_Library)

## 改行をコントロールする

Print文で改行をコントロールするには、セミコロンを使えば良いです。
セミコロンを使うと、内部バッファに一旦格納され、セミコロンが無いPrint文が実行された所で一気に出力されます。

``` VB:macro.vb
Dim FileNum As Integer
Dim CurrentLine As String
Dim Filename As String

FileNum = Freefile               ' ファイルハンドルを初期化 
Filename = "C:\temp_data.txt"    ' ファイルの場所

 
Open Filename For Output As #FileNum 'ファイルオープン
Print #FileNo, "Hello ";     'Line1（セミコロンが付いているので、この時点では出力されず内部バッファに格納される）
Print #FileNo, "world! ";    'Line2（セミコロンが付いているので、この時点でも出力されず内部バッファに格納される）
Print #FileNo, "Yes!"        'Line3 (ここでようやく出力される）
Close #FileNo                    'ファイルクローズ
```

出力結果

```
Hello world! Yes!
```

出力結果を見ると分かりますが、内部バッファに格納されたタイミングでは改行コードが付与されません。
3番目のPrint文が実行されたタイミングで文字と一緒に最後にLFが付いて出力されます。

参考ページ：
https://help.libreoffice.org/3.5/Basic/Print_Statement_Runtime/ja

# TextInputStream ステートメントを使った書き方
より柔軟に書き込みを行う場合には、TextInputStream を使います。
例えば、ファイルの最後を改行で終わらせたくない場合などです。（他にメリットがあれば教えてください）

## 基本文法

``` VB:macro.vb
Dim oFileAcc As Object
Dim oOutputStream As Object
  oFileAcc = CreateUnoService("com.sun.star.ucb.SimpleFileAccess")
  oOutputStream = CreateUnoService("com.sun.star.io.TextOutputStream")
Dim vData As Variant
  vData = oFileAcc.openFileWrite("C:\temp_data.txt" ) 'ファイルの場所
  oOutputStream.setOutputStream(vData) 
  oOutputStream.setEncoding( "UTF-8" ) 'エンコードの設定
 
oOutputStream.writeString( "Hello " ) '文字の書き込み（改行は自動で付与されない)
oOutputStream.writeString( "world!" )

oOutputStream.closeOutput() 'ファイルを閉じる
```

出力結果

```
Hello world!
```

# まとめ

Excel VBAとは違ってOpenOffice basicは文献が少ないかつ、同じことを実現しようと思っても随分勝手が違います。
そのため、今後も調べたことは少しでも記しておこうと思います。
IntelliJ IDEA Community Edition(無料版)をインストールする方法(日本語化も)

# IntelliJ IDEA Community Edition をインストールする方法
既に出ているかもしれませんが、Kotlinの良さを広めたいから

## ダウンロード

下記サイトにアクセスして「DOWNLOAD」をクリック
https://www.jetbrains.com/idea/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/34efcb7a-8f3c-6b60-8eb0-b63af605c23e.png)

緑で囲った方の「DOWNLOAD」をクリックして、ダウンロードでしたEXEを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/efc53a4d-3dea-9300-d0b3-af6b11499c81.png)


## セットアップ
EXEファイルを実行すると、「ユーザーアカウント制御」が出たら「はい」をクリックして、
下記画面に遷移します。「Next」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/fc2ad4df-a3cb-0505-2daa-50bd2fe72e9b.png)

インストール先フォルダー
変更がなければ、「Next」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/5cb51964-48c1-c76f-bef5-376f1f4b2c23.png)

オプション選択
特にチェックを入れなくてもよい、「Next」をクリック
(自分は、デスクトップにショートカットが欲しかったので1つチェック)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/3d6b380e-5933-7611-184d-5da0860b5e0b.png)

スタートメニューフォルダー
ここも変更がなければ、「Install」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/37efd14a-2eb2-3215-5233-593d506a4200.png)

「Finish」で終了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/0bc0cfed-502c-32b8-1180-f0eb7a7ce667.png)

## 日本語化
下記サイトにアクセスして、緑で囲った「ダウンロード」クリックして、ダウンロードでしたZIPを解凍します。
http://mergedoc.osdn.jp/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/0de89e91-4f54-f69a-eeae-62f3a0e58b47.png)

解凍後に「setup」のフォルダーをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/89979c0f-1903-4a11-aad1-aa41b3b21c46.png)

「setup-pleiades.exe」を実行します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/37daa47a-af89-41f4-0196-41490cc1c537.png)

下記の画面が出てきたら「選択...」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/a2ed186d-016a-2070-f431-b6de6185df7f.png)

インストールした、利用する方の(idea.exeは32bit版/idea64.exeは64bit版)を選択(開く)します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/114e1a2e-16a6-4ca4-4e17-0d957f901934.png)

「日本語化する」で日本語化ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/186b7542-143f-931d-be93-0c2253067b94.png)

下記の画面になれば終了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269756/414c3ed3-5e6a-ca03-ef6a-189268b4f332.png)
ruby で nl80211を使う

ruby からLinuxのnl80211を使ってみました。

nl80211を使ってWi-Fiのチャンネル設定をしてみました。

[Ruby で Linux の NETLINKを使う](http://qiita.com/eggman/items/9848606a87c74d5dfcdd)の続きです。

nl80211はgenric netlinkという仕組みを使います。

# socket生成

optionにNETLINK_GENERICを指定します。

```
require 'socket'
module Linux
　　　　NETLINK_GENERIC　　　　= 16
end

class Socket
  PF_NETLINK    = 16    unless defined? Socket::PF_NETLINK
  AF_NETLINK    = PF_NETLINK  unless defined? Socket::AF_NETLINK
end

s = Socket.new(Socket::AF_NETLINK, Socket::SOCK_DGRAM, Linux::NETLINK_GENERIC)
```

# リクエスト生成

チャンネル設定の場合、リクエストはnlhdr, genlhdr, IFINDEXのアトリビュート、 WIPHY_FREQのアトリビュート、 WIPHY_CHANNEL_TYPEのアトリビュートを含みます。

IFINDEXが4, 周波数が　6ch (2437MHz), バンドが2.4GHzの場合のリクエストです。

```
nlhdr = [24, 0x16, Linux::NLM_F_REQUEST | Linux::NLM_F_ACK, 0, 0].pack("ISSII")
genlhdr = [Linux::NL80211_CMD_SET_WIPHY, 0, 0].pack(SSI)
if = [8, NL80211_ATTR_IFINDEX, 4].pack(SSI)
freq = [8, NL80211_ATTR_WIPHY_FREQ, 2437].pack(SSI)
freq_type = [8, NL80211_ATTR_WIPHY_CHANNEL_TYPE, 0].pack(SSI)
```

# リクエスト送信、レスポンス受信

```
s.send(nlhdr+genlhdr+if+freq+freq_type, 0)
resp = s.recv(4096)
```

# 調査方法

iw を　--debug 付きで動かしてみるのが良いです。

```
root@kali:~# iw --debug dev wlan0 set channel 6
-- Debug: Sent Message:
--------------------------   BEGIN NETLINK MESSAGE ---------------------------
  [NETLINK HEADER] 16 octets
    .nlmsg_len = 44
    .type = 22 <0x16>
    .flags = 5 <REQUEST,ACK>
    .seq = 1495358371
    .port = 1413498624
  [GENERIC NETLINK HEADER] 4 octets
    .cmd = 2
    .version = 0
    .unused = 0
  [PAYLOAD] 24 octets
    08 00 03 00 04 00 00 00 08 00 26 00 85 09 00 00 ..........&.....
    08 00 27 00 00 00 00 00                         ..'.....
---------------------------  END NETLINK MESSAGE   ---------------------------
-- Debug: Received Message:
--------------------------   BEGIN NETLINK MESSAGE ---------------------------
  [NETLINK HEADER] 16 octets
    .nlmsg_len = 36
    .type = 2 <ERROR>
    .flags = 0 <>
    .seq = 1495358371
    .port = 1413498624
  [ERRORMSG] 20 octets
    .error = 0 "Success"
  [ORIGINAL MESSAGE] 16 octets
    .nlmsg_len = 16
    .type = 22 <0x16>
    .flags = 5 <REQUEST,ACK>
    .seq = 1495358371
    .port = 1413498624
---------------------------  END NETLINK MESSAGE   ---------------------------
```

ドキュメントがないので地道にしらべないと理解できないです。


あとで調査するかも
* authenticate
* associate
* send_mlme
* set_ap_wps_ie
iOSアプリの起動方法を判別する

## 概要
アプリがホーム画面から起動されたのか、スキーム起動されたのかなど起動時の状態をアプリで判別する方法

## 活用ケース
- ホーム画面からの起動の場合のみ何か処理を行う
- アプリの起動方法を厳密に判定して処理を行う

## 実装
`AppDelegate`の`didFinishLaunchingWithOptions`の引数である`launchOptions`にて判別を行います。
ホーム画面からアプリを起動した際には`nil`となっています。

```swift
func application(_: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // launchOptionsで起動方法を判別する
}
```
See: https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1622921-application
See: https://developer.apple.com/documentation/uikit/uiapplication/launchoptionskey

## Sample
#### ホーム画面から起動した場合のlaunchOptions
```
nil
```

#### Safariからスキーム起動した場合のlaunchOptions
```
[__C.UIApplicationLaunchOptionsKey(_rawValue: UIApplicationLaunchOptionsURLKey): hoge://fuga?a=b
 __C.UIApplicationLaunchOptionsKey(_rawValue: UIApplicationLaunchOptionsSourceApplicationKey): com.apple.mobilesafari]
```


## 補足
起動時の振る舞いとなるため、デバッグにはConsoleを用いる必要があります。
下記を参考ください。
https://qiita.com/m_orishi/items/c5593878e1ab55d5c3f2

## さいごに
ニーズがあるように感じたのですが、意外とまとまった記事がなく。
もっと良い判定方法があるよ！この方法だとこんな問題があるよ！など知見がありましたら教えて頂ければ嬉しいです。
【Git】リモートリポジトリのURLを変える

## 目的

- 外部サーバにあるソースコードをbitbucket経由でローカルリポジトリにいれる
- 既存のリモートリポジトリ(git cloneしてきたリポジトリ)を変更

## 前提

- リモートリポジトリ作成済み
- ローカルリポジトリとすでに同期済み
- 外部サーバのソースコードフォルダは別のリモートリポジトリで管理されていた
- 外部サーバのソースコード優先
- ローカルで変更したものは無視していい

## 外部サーバで
git管理されているかどうか確認

```
$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
```
リモートリポジトリのURLを確認

```
$ git remote -v
origin	git@bitbucket.org:hogehoge/hugahuga.git (fetch)
origin	git@bitbucket.org:hogehoge/hugahuga.git (push)
```

リモートリポジトリを変更

```
$ git remote set-url origin https://piyopiyo@bitbucket.org/piyopiyo/nyaanyaa.git
$ git remote -v
origin	https://piyopiyo@bitbucket.org/piyopiyo/nyaanyaa.git (fetch)
origin	https://piyopiyo@bitbucket.org/piyopiyo/nyaanyaa.git (push)
```

コミットしてpushします

```
$ git push origin master
Password for 'https://piyopiyo@bitbucket.org': 
```

httpsなのでpasswordが必要（外部サーバなので結果オーライ）

```
To https://piyopiyo@bitbucket.org/piyopiyo/nyaanyaa.git
 ! [rejected]        master -> master (fetch first)
error: failed to push some refs to 'https://piyopiyo@bitbucket.org/piyopiyo/nyaanyaa.git'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first merge the remote changes (e.g.,
hint: 'git pull') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
```

リモートリポジトリにはすでにローカルで行なっていた変更が記録されているため、マージか強制上書きしないといけないようです<br>
なので強制上書き`-f`オプションをつけてpush

```
$ git push -f origin master
```

今度はうまくいきました

## ローカル（自分のマシン）で
```
$ git pull
remote: Counting objects: 422, done.
remote: Compressing objects: 100% (213/213), done.
remote: Total 422 (delta 196), reused 422 (delta 196)
Receiving objects: 100% (422/422), 1.60 MiB | 1.13 MiB/s, done.
Resolving deltas: 100% (196/196), done.
From https://bitbucket.org/piyopiyo/nyaanyaa
 + a38b3bb...dabba87 master     -> origin/master  (forced update)
fatal: refusing to merge unrelated histories
```
エラーになってしまったので`--allow-unrelated-histories`をつけてpullします

```
$ git pull --allow-unrelated-histories
```

通りました

これからは外部サーバでソースコードを変更してもリモートリポジトリとローカルで同期できます

向き間違えないようにしないと（汗
mincraft を ubuntu / debian に入れる

サーバーを建てる話じゃないです。java版です。システム標準のjava (`default-jre`)を使います。

* `sudo apt-get install default-jre equivs gdebi-core`
* 以下のファイルを作る

```text:dummy.equivs
Package: oracle-java8-installer
Version: 99:99
Maintainer: Nam <email@address>
Architecture: all
Description: dummy oracle java 8 package
 A dummy package with a version number so high that the real gnome packages
 will never reach it.
```

* `equivs-build dummy.equivs`
* `sudo dpkg -i oracle-java8-installer.deb` (`Mincraft.deb` がJava 8を必要としているが最近のDebian / Ubuntu には無いためダミーパッケージを入れる）
* 公式から`Minecraft.deb`をダウンロードしてきてから `sudo gdebi Minecraft.deb`

実メモリー 4GBだと固まることがあった。
月70万PVウェブメディアをconcrete5からhugo(静的html)に移行させた話

ウェブメディア[自動計算](https://calculator.jp/)を、今まで concrete5 で運営していたものを Hugo に置き換えた話です。

concrete5 や WordPress などの CMS が広まる前(2002～2007年ぐらい)は、自分で Hugo のような html ジェネレータを作っていました。もちろん Hugo と比較すると機能はたいしたことなく、メニューのリンクを自動で作る、ぐらいのものでしたが。
この経験があったので、Hugo にはスムーズに慣れた気がします。

## スクレイピングで記事を移行する
concrete5からHugoへデータインポートは難しそうなので、phpQueryというライブラリを使いました。詳細は→ [【php】webサイトから、欲しい情報を3行で取得する方法](https://qiita.com/dia/items/3cf963fa89b08b87e8ef)

記事のメイン部分(div#main-content)を指定してスクレイピングする、という方法です。記事は200件ぐらいだったので、記事URLを配列に書いておき、ループで繰り返しスクレイピングさせる、という方法で取得しました。

## テーマはHugoのものに変更した
concrete5のときは、concrete5の公式サイトからテーマを入手していました。特にテーマにこだわりがあったわけではないので、Hugo移行するときに、Hugoのテーマに変更しました。

## Bootstrapのバージョン違い
concrete5で構築を始めたのが2016年で、Bootstrap3系でした。移行時にテーマを変更して、Bootstrap4系にしました。
このため、gridの表示などが異なりました。

    col-xs-** → col-**

などです。ここはエディタで置換していきました。詳細は[Migrating to v4. Bootstrap](https://getbootstrap.com/docs/4.3/migration/)をごらんください。

## Hugo の嬉しいところ
地味ですが、かゆいところに手が届くようになっているのが嬉しかったです。

### Hugo ローカルプレビュー
Hugo では、コマンドラインから

    hugo server

と入力するとローカルサーバーが立ち上がってプレビューできます。ファイルを変更して保存すると、プレビューも自動で書き換えて表示してくれます。この機能のおかげで、Bootstrapのバージョン変更作業が楽でした。

### minifyができる
コンパイル時に、

    hugo --minify

と ```--minify``` オプションを付けると、改行などを削ったhtml出力をしてくれます。

![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31643/4d149644-8fea-cab8-9397-6f64ffaec9d4.png)

### scssがコンパイルできる
Hugo では、scssがコンパイルできます。(ただし、テーマがscssに対応した作りになっていることが前提っぽいです。)


## 表示スピードの改善
7月19日の早朝に静的htmlに移行しました。その結果が↓です。
![Hugo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31643/fa8d845e-cd1e-a1e5-aa93-3e0609a30224.png)
2019-07-24 C++ Builder 10.2 Tokyo > forum (バグの報告先が不明)

10.2 Tokyoのバグを報告しようとしていた。

バグ報告先は不明だが、下記のフォーラムは見つけた。
https://community.idera.com/developer-tools/platforms/

Embarcaderro Developer Networkの[Quality Portal](https://quality.embarcadero.com)はつながらない(2019-07-24現在)。

> quality.embarcadero.com のサーバーからの応答が一定時間以内に返ってきませんでした。

上記のフォーラムにバグ報告もしている例があるが、バグの報告先はここでいいのだろうか？


### 関連

- [C++ Builder 10.2 Tokyo + Windows 10 v1903 > 不具合 > TDatePicker, TTimePicker > 見当違いのところに表示される](https://qiita.com/7of9/items/38035b6afc044a249617)
IT技術者が名古屋で仕事を見つける方法（１）日本全体と比較して

T技術者が名古屋で仕事を見つける方法（１）日本全国と比較して

名古屋（愛知）と全国を20年ほど前、産業比較したことがあります。
その時、特徴的だったのは、産業で１割を超えるのが、製造業と印刷業だったことです。

現在でも、製造業は
 あいちの概要/産業構造　全国に対する主な1位業種
https://www.pref.aichi.jp/ricchitsusho/gaiyou/structure.html

輸送機械はじめ１１業種で、断トツの輸送機械以外は、１位業種でも15%から10%です。

愛知県で全国の10%を締めれば、1位、2位、3位くらいに入る重要産業だということがわかります。

人口は、岐阜県、三重県も含めれば、全国の１割ちょっとです。

愛知県　https://www.pref.aichi.jp/soshiki/toukei/0000088835.html
>2019年6月1日現在の愛知県の人口（推計）は、上記のとおり、7,549,594人(男3,778,768人、女3,770,826人)となり、前月に比べ2,355人増加し、前年同月に比べ13,602人の増加となりました。

岐阜県　https://www.pref.gifu.lg.jp/event-calendar/c_11111/jinko201906.html
>令和元年6月1日現在の岐阜県の人口は、1,991,390人となり、5月中に928人減少しました。

三重県　http://www.pref.mie.lg.jp/DATABOX/000228267.htm
>1,781,948人（男　869,827人　女　912,121人）前月に比べ 440人の減少


あいちの産業と労働Q&A 2019
https://www.pref.aichi.jp/sangyo-seisaku/qa/pdf/all.pdf

製造業系のIT産業が圧倒的かもしれません。
製造業といっても、社内システムもあれば、顧客販売システムもあれば、在庫管理もあれば、輸送管理もある。通信カーナビのように、クラウドサービスもある。

昔は、工場ごとに、取引先のIT企業が違い、たくさんの中小企業が工場のシステムを構築してきました。
発注側も、受注側も、それではIT技術が工場で閉じてしまい発展の阻害になっているのではないかと、いろいろな手を打たれているようです。

新しい提案をしようとしている会社が、狙い目かもしれません。
そういう企業には、東京からも提案が来ているかもしれません。
競争相手をしらないと、最後に逆転されるかもしれません。

名古屋で就職しても、結果東京勤務になる可能性も、、、。

# 文書履歴(document history)
ver. 0.01 初稿 20190724
ver. 0.04 URL追記　20230227

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
openFrameworks 0.10.1 / Windowsで配布しやすいアプリケーションを作成する

## ``of_v0.10.1_vs2017_release`` ターゲットRelease/x64でのやりかた
### 1
 - アプリケーションプロジェクトのプロパティ
 - openframeworksLibのプロパティ

にて、``C/C++`` -> ``コード生成`` -> ``ランタイムライブラリ`` を``/MT``にする。

### 2
https://www.dropbox.com/sh/oakofuoccawtvfd/AADD2W7uncOTtrF0K1Hvg7Xja?dl=0
から
``libboost_static_libs_for_of_v0.10.1_vs2017_release_libs_boost_lib_vs_x64.zip``
をダウンロードし、中身の4ファイルを
``of_v0.10.1_vs2017_release\libs\boost\lib\vs\x64``
に配置する。

## 説明

  WindowsのopenFrameworks``of_v0.10.1_vs2017_release``でアプリケーションをRelease/x64でビルドし、アプリケーションの.exeファイル入りbinフォルダーを配布する際、配布した先でVisual Studioをインストールしてないと、``MSVCP140D.dll``がないといわれて実行できません。Visual Studioのランタイムを別途インストールすればよいのですが、インストールしなくても動いてほしい。

のびっこさんの解説、

[Visual C++で作成したEXEを、ランタイムDLL無しに単体で起動できるようにするには]
(https://qiita.com/nobikko/items/370378b303e129706fd6)

にある通り、プロジェクトのプロパティにて、 

``C/C++`` -> ``コード生成`` -> ``ランタイムライブラリ`` を``/MT``にする

ことで解決。。
するかと思いましたが、openframeworksLibプロジェクトも同じ設定をする必要があります。

しかし``libboost_filesystem-vc141-mt-s-1_64.dll``がないよ、とリンクエラーが出ます。

スタティックリンク用のboostのdllが``of_v0.10.1_vs2017_release``に入ってないことが原因です。

sourceforgeにあるboostをビルドしたバイナリを入手します。

https://sourceforge.net/projects/boost/files/boost-binaries/1.64.0/

にある、``boost_1_64_0-msvc-14.1-64.exe``
をダウンロードして、中に入ってる以下の4ファイルを見つけます。

- ```libboost_filesystem-vc141-mt-s-1_64.dll```
- ```libboost_filesystem-vc141-mt-sgd-1_64.dll```
- ```libboost_system-vc141-mt-s-1_64.dll```
- ```libboost_system-vc141-mt-sgd-1_64.dll```

上記ファイルを``of_v0.10.1_vs2017_release\libs\boost\lib\vs\x64``フォルダに配置すると、リンクエラーが出なくなります。

sourceforgeのファイルはいろいろ入ってて大きいので、必要な上記の4ファイルだけ以下にまとめておきました。
https://www.dropbox.com/sh/oakofuoccawtvfd/AADD2W7uncOTtrF0K1Hvg7Xja?dl=0


なおopenframeworksLibプロジェクトのランタイムライブラリを``/MT``にすると、アプリケーションプロジェクトも全部``/MT``にしないとリンクできなくなりますので、配布用ビルドの用が済んだら``/MD``にもどしとくのがいいかと。

##参考

 oF forumの参考スレ [Static linking not building needed Boost version in VS 2017?](https://forum.openframeworks.cc/t/static-linking-not-building-needed-boost-version-in-vs-2017/32009/4)
vscode 保存時にelm-formatを効かせる方法

## 1. pluginsの導入

以下3つを入れておきます

<img width="480" alt="Screen Shot 2019-07-24 at 9.21.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/2ba1fe21-4637-0b46-65b2-2e72703d1997.png">
<img width="480" alt="Screen Shot 2019-07-24 at 9.23.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/1308438a-0765-832e-0a97-93ab5ed8f1d6.png">
<img width="484" alt="Screen Shot 2019-07-24 at 9.23.44.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170241/b39c5c64-3539-81a2-d9f4-b5d7e3829069.png">



## 2. settings.jsonへの記述
`cmd + ,` を打ち`settings.json`を表示して以下を追記します

```json:settings.json
"editor.formatOnSave": true
```

上記の場合、全ての言語において保存時にprettierによる整形がされるのでelmだけに行いたい場合は以下を追記します

```json:settings.json
"editor.formatOnSave": false,
"[elm]": {
  "editor.formatOnSave": true
}
```

## 3. elm-formatのglobalインストール

elmの整形の場合、prettierは内部で`elm-format`コマンドを叩いているため`elm-format`コマンドを使えるようにします

```shell:
$ npm install -g elm-format
```

以上。

## 参考
https://github.com/Krzysztof-Cieslak/vscode-elm/issues/175#issuecomment-353789956
MarkDownで書いた表がGitHubで表示されない時

VSCode、Atom等のテキストエディタではMarkDownで書いた表がプレビューでは正しく表示されるが、
GitHubにpushすると表が正しく表示されない・・という事象が発生した事があった。
備忘のために、その時に確認・対応した事を書き記す。


## 表のアラインメント行(2行目)のハイフン

Markdownで書いた表の2行目はアラインメント（左寄せ、中央揃えなど）を指定する行であり、ここではハイフン('---')を記載するが、
GIthubでMarkDownを表示させるときは、このハイフンの数が3つ以上という制約があるため、ハイフンを３つ以上にする

（参考： [Markdownでtable作ってもうまく表示できない時](https://qiita.com/risagon/items/7d75c221d672b94d4481)）


## 表中に制御文字が入ってないか調べる

MarkDownのファイル内に制御文字が入って表が認識されないという場合もある。
そこで、MarkDownファイルを制御文字も表示させるようにして開いてみる。
方法は多種ある（使用しているエディタ等で各々設定する方法があるはず）が、
一例としてMacなどvimが使える場合はターミナルからvimを使いオプション「-b」をつけて開くことで、制御文字も表示することができる。

```
$vim -b （MarkDownファイル）
```

自分の場合はMarkdownで書いた表の中に```^H```（バックスペース）や```^@```（ヌル文字）が入っている箇所があった。
調べたところ、**Macでエディター等を使いファイルを編集した時、制御文字が入り込む場合がある**との事。
（参考： [Macで不可視な文字が入力されてしまう問題への対処法](https://blog.right-apps.com/develop/2018/post-62/)）
そのため、Markdownファイルを制御文字も表示させ、削除して再度pushしたところ、Github上でMarkDownの表が表示されるようになった。
plunkerでvue その6

#概要

plunkerでvueやってみた。
じゃんけん、やってみた。

#参考にしたページ

https://qiita.com/Mitsuzara/items/039cb367c4de7683d2d0

#成果物

https://embed.plnkr.co/BPxmnQbWVQfD0zOs5rQU/

以上。
Swiftでタイムアウト処理を実装する。

## URLSessionを使用しているとき

``` swift:timeout.swift
let path = "https://XXXXXXX"
let url = URL(string: path)!
var request = URLRequest(url: url)

// タイムアウトの時間を設定する
request.timeoutInterval = 600

let task = URLSession.shared.dataTask(with: request) { data, response, error in

　　// レスポンス処理
}
task.resume()
```

下記から引用しています。
[swiftで処理のタイムアウトを実現したい](https://teratail.com/questions/115375)
Spring boot メモ書き(1)

# Spring Boot とは

> Spring Framework は Java プラットフォーム向けのオープンソースアプリケーションフレームワークであり、 Webアプリケーションに限らず、広範囲のJavaアプリケーションを開発できる

## 特徴
> DI ( Dependency Injection ) コンテナから始まった経緯があり、 現在でもこのフレームワークのコアになっている機能が DI です。この DI コンテナから始まり、数々の機能を備え、現在ではWebアプリケーションフレームワークとして広く使われ、 コミュニティーも盛んです。

> モジュール間のバージョンを決めてくれたり、 Spring FrameworkではXMLで記述する必要があった設定を Java のコードとして記載できたり、 TomcatなどのWebアプリケーションコンテナを内蔵して手早くアプリケーションが動く

## 脆弱性はあるのか
> Spring Boot に深刻な脆弱性が存在

> 以下のバージョン
1): Spring Boot 1.x  
2): Spring Boot 2.x  

> ※Pivotal Softwareより公式発表がないため、上記の中でも影響を受けないマイナーバージョンがある可能性があります。今回は注意喚起も含めて、広くバージョンを記述しています。

[https://www.shadan-kun.com/news/20190426_2/](
https://www.shadan-kun.com/news/20190426_2/)

> 参考にした記事↑(19/4/26)

# インストールからSTS起動について
[https://eng-entrance.com/java-springboot](https://eng-entrance.com/java-springboot)

> ↑ここのサイトが分かりやすいかと！

> 新規Springスタータープロジェクト作ってブラウザ表示まであり
Raspbian GNU/Linux 10 BusterにDockerをインストールする

ref: https://github.com/docker/for-linux/issues/709

にissueが上がっている通りで2019/07/23時点ではRaspbian busterにdocker-ceはそのままではインストールできない。よって

```shell-session
curl -sSL https://get.docker.com/ | sed 's/"buster"/"stretch"/' | sh
```

として、`buster`としてではなく、`stretch`用のをインストールすることで回避できる。workaroundなやり方なので正式対応が来たらアップデートしましょう。
最速の開発環境が欲しい。RamDisk編

開発環境を快適にするためには、SSDより速いRamDiskを構築すべきだ！！

#RamDiskとは
メインメモリの一部をストレージのようにドライブとしてマウントする
メモリなのでとても速い
SSDがかなり高速になったので、HDD時代ほどはメリットがないが
SSDの書き換え回数を減らすというメリットもある

しかし、メモリなので電源OFFをするとデータが消える
（たいていのソフトは、データをストレージに保存するオプションがある）

RamDiskソフトにより速度などが違うので何個かためしてみた
環境は Windows10 64ビット。

##まず NVMe SSDの速度
![NVMe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/42b4fff4-2043-9c00-fd66-2cb6c2f9005c.png)



##ROG Ramdisk
Max?GB。上限はわからないが、かなり大きなサイズを確保できる
NTFSでの保存も可能
複数ドライブ作成可能
![ROK.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/03f7b618-d5d9-607d-8e9d-fa03c16f6c5e.png)

やはりSSDより速い。圧倒的に


##Dataram RamDisk
Fat32
Max1GB
その他色々設定
![Dataram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/cf4213e2-d6e1-7094-d6d5-de0232e142aa.png)

上記のROG Ramdiskに比べると圧倒的に遅い
ファイルフォーマットの差かもしれないが
しかも1GBまでしか使えない



##SoftPerfect
NTFS
Max?GB
複数ドライブ作成可能
永続化をドライブごとに選べる
また、実行中時ドライブサイズを変更可能
![SoftPerfect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/21d2a6cb-64d1-440c-22ae-222988936593.png)

ROG Ramdiskより多少速いし、動的にサイズ変更できるのが素晴らしい！
ので、これを採用する事にした


##Buffalo
Max 1344MB
サイズが小さいし、インストールしたらブルースクリーン

##その他
色々とインストールしたがROG Ramdisk、SoftPerfectに勝るものがなかった
もっと良いものをみつけたらそれに変更します
結局 SoftPerfectを採用

#SoftPerfect
羊マークのあれ
https://www.softperfect.com/products/ramdisk/
使用期間30日。個人利用なら3140円、ビジネスなら5310円だが
古いバージョンでは個人利用は無料
バージョン上がると機能も増えているので、パーツと違い半永久的に使えるので安いかと思う

##設定
インストールは普通にインストールする。
RamDiskの内容を毎回バックアップするかどうかでディスクの作り方が違ってくる
保存する場合は　イメージの作成と仮想ディスク->イメージの作成 で、
ディスクイメージを作成し、RAMディスクメニューからマウントを行う

保存が不要な場合は直接RAMディスクメニューからマウントを行う
起動時にマウントする場合は、RAMディスクメニューの起動時にマウントされるRAMディスク で作成

![SnapCrab_RAMディスクの追加編集_2019-7-24_7-34-3_No-00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/13916/07f5d4fe-cef2-7ab5-4a98-7b809f99e82f.png)

RamDiskの容量を決める。用途次第だがあとで変更可能なので適当でも大丈夫。
最低でも500MBぐらいほしいかなあ？　私は4GBぐらいにしている

色々設定はあるけど、普通に使うにはこれで十分


##キャッシュ化
###Temp
WindowsのTempをRamDiskにするのは定番だ
環境変数変更するなり、ショートカット張るなり好きにしよう
基本的に最近のインストーラーはTempに値を保持しないはずなので、このデータはイメージ保存必要ない

###ブラウザキャッシュ
ブラウザのHTMLキャッシュをRamDiskに入れるのも定番だ
やり方は色々なページで書かれている
わたしはシンボリックリンクをRamDiskに張った
このデータはイメージ保存必要ない

###ダウンロード
どうしてもダウンロードがたまってしまう私・・・
ダウンロードフォルダをRamDiskにしてイメージ保存をしなければ、毎回きえてくれるぞ！
後でほしいものだけコピーしている
メリットとしては、Zip圧縮されたものをオンメモリで解答出来る事だ
速度メリットというよりはSSDの書き込み寿命のためというか。
もちろん大きなファイルのダウンロードは他のドライブに入れるか、領域を大きくする必要がある
あえてイメージ保存しない

###動画や画像ソフトのTemp
これもわかりやすい。ただしある程度の大きさが必要である
このデータはイメージ保存必要ない

###ビルド時の中間ファイル
C++とかをビルドするときの中間ファイルをRamDiskにすることもあったが
今は面倒なので行ってない。。
が、ソース丸ごとRamDiskに入れてコンパイルする事はある
例えばBoostとか大きい奴は 8GBぐらいのRamDiskで丸っとビルドする事がある

###Docker等
DockerとかをRamDisk上で実行させると便利である
例えばテストだったりRamDisk上で全部完結されされれば・・・
とても有効ではないかと思うが、今はDocker on Ramdiskの研究中！

###その他
便利な使い方があったら教えてください！！
ハードリンクとシンボリックリンク

ハードリンクとシンボリックリンクについてのメモ

#ハードリンク
- すでにあるファイルを別のファイル名(パス)で参照できるようにするもの
- 既存のiノードを参照するディレクトリエントリを追加するもの
- それぞれのディレクトリエントリのiノードは同じ
    - iノードは同一ファイルシステム内にのみ一意である
- 作成されるとiノード内の情報(リンクされている数)が増える
- リンク元と同一のiノード番号を指している


#シンボリックリンク
- 同じようにすでにあるファイルを別のファイル名(パス)で参照できるようにするもの
- ただし、iノードから指定せずにパス名から指定するため、別のファイルシステムからでも参照可能
    - そのため、iノード番号は違う
- リンク元のポインタ(パス名)を指している
令和時代にJava言語の採用を考える〜無難なSDKの選び方

# 本記事のターゲット
今までWebアプリケーションをJavaで開発してけれど、最近有償化されたの？商用では使えない？など、お悩みの方。

# Javaの有償化？ざっくりと概要
## Oracle JDKの料金形態
公式ページよりざっくり要約すると「Webサービスの場合１プロセッサ = 月額3,000円」です。
AWSなどのクラウド環境でも大体料金は同じです。EC２では細かく言うとハイパースレッディングの有効／無効で金額が違いますが、JavaでデプロイするようなWebアプリケーションサーバでハイパースレッディングを考えることはあまりなさそうです。
https://www.oracle.com/technetwork/jp/java/javaseproducts/overview/javasesubscriptionfaq-4891443-ja.html
https://www.oracle.com/jp/corporate/pricing/mcpu-189131-ja.html
https://www.oracle.com/technetwork/jp/java/eol-135779-ja.html
http://www.oracle.com/us/corporate/pricing/cloud-licensing-070579.pdf

# Oracle JDK以外
## OpenJDK
こちらもOracleがビルド。6ヶ月毎にアップデート。サポートも６ヶ月。６ヶ月に一回アップデートが必要。

## Amazon Corretto 
Amazonが新しく提供をはじめたJDK。
JDK8互換は2023年6月まで無償サポート。
JDK11互換は最短2024年8月まで無償サポート。

## 他にもいっぱい
こちらのスライドに丁寧なまとめがありました。
https://www.slideshare.net/TakahiroYamada3/how-to-choose-the-best-openjdk-distribution-201905

# どうする？
## 既存のサーバ環境をあまりいじれない場合
### Javaのアップデートにリリース計画が必要だったり、JDKのバージョンアップ自体がプロジェクト化されるような規模な会社や部署の場合
有償化といえども「１プロセッサ = 月額3,000円」なので、人経費を掛けて移行するよりも、Oracle JDKを契約したほうが殆どの場合安上がりになりそうです。

### それ以外
Amazon CorrettoはAmazon Linux以外もWindows、MacやDebian系LinuxのCentOSなどもサポートしており、ベンダーロックインにはなりません。MacやWindowsのインストーラも付随しており、Webアプリケーションの利用であればAmazon Correttoがおすすめです。
javaで配列を使わずにmapする

先日こんな記事を書いた。

ネストしすぎの()を何とかしたい
https://qiita.com/tkturbo/items/04960f4e3e7226de3b46

ここで書いた、

```javascript
// using custom object
const applier = (val)=>{
  const  o={
    value : val,
    apply : (unary)=>{ o.value=unary(o.value); return o; }
  };
  return o;
};
console.log(applier(name).apply(f0).apply(f1).apply(f2).value);
```

今日はこれをjava化してみる。


```java:Applier.java
public class Applier<T> {
  private T value;
  public Applier(T value) {
    this.value = value;
  }
  // import java.util.function.Function;
  public <R> Applier<R> apply(Function<? super T, ? extends R> appliable){
    return new Applier<R>(appliable.apply(this.value));
  }
  public T get() { return this.value; }
}
```

java.util.function.Functionインタフェースを使えばこの通り。

キモになるのはこの1行。

```java
  public <R> Applier<R> apply(Function<? super T, ? extends R> appliable){
```

これがあるので、入力と出力で型が違っても処理可能となる。

例えば、

```java
System.out.println(
  new Applier<String>("0001")
    .apply(v->Integer.parseInt(v,10))
    .apply(v->v+1)
    .apply(v->String.format("%04d", v))
    .get()
);
```

こんな風に使える。

個人的には、

```java
    return new Applier<R>(appliable.apply(this.value));
```

この1行に違和感あるので、こう書きたい所。

```java
public class Applier<T> {
  private T value;
  public Applier(T value) {
    this.value = value;
  }
  public <R> Applier<R> apply(Appliable<? super T, ? extends R> appliable){
    return new Applier<R>(appliable.applyTo(this.value));
  }
  public T get() { return this.value; }
  @FunctionalInterface
  public static interface Appliable<T, R> {
    public R applyTo(T value);
  }
}
```
public staticなインタフェースを使ってるのは名前空間の汚染を抑止するため。
PRからのIssuesの自動closeはデフォルトブランチ宛しか動かない【個人メモ】

GitHubの使い方を勉強がてら、ちょっと大きめの追加を行うためにエピックブランチ運用を試してみたところ、
Pull requestsからIssuesの自動Closeは向き先がデフォルトブランチでないと動かないらしいことが判明。

[Closing issues using keywords (GitHub Help)][official-help]

> When the pull request is merged into your repository's **default branch**, the corresponding issue is automatically closed.

(太字部分に明記あり)

エピックブランチを都度デフォルトに変えれば自動closeできるけど、それはそれで戻し忘れとか手間な気が。。。\_(:3」∠)_

----

## 参考

- [Closing issues using keywords (GitHub Help)][official-help]
- [GitHubのIssuesを閉じる方法](https://ushumpei.hatenablog.com/entry/2016/12/20/025249)
    - GitLabっぽくpr-issuesが連携して閉じられるのか検索していて見かけたサイト。
    - いくつかの方法を検証して記載してくれていた。

[official-help]: https://help.github.com/en/articles/closing-issues-using-keywords
Redashで「条件を満たすレコードが1件でもあったらアラートを通知したい」と「アラートが通知されたら条件を満たすレコードの一覧を見たい」を同時に実現する方法

Redashで

1. 条件を満たすレコードが1件でもあったらアラートを通知したい
2. アラートが通知されたら条件を満たすレコードの一覧を見たい

という要望を実現したい時にどうすればいいかという話。

普通に

```sql
select
    count(*)
from
    some_table
where
    some_column = "xxx"
;
```

のようなクエリを書いてしまうと、
アラートメッセージに含まれるURLからRedashに飛んだ時にレコードの件数しかわからず要望2を実現できない。

そこで自分は

```sql
select
    *,
    1 as "alert_flag"
from
    some_table
where
    some_column = "xxx"
;
```

のようなクエリを書いて、
アラートの設定でValue columnを「alert_flag」、Opを「equals」、Referenceを「1」にしている。
こうすれば要望1と要望2を同時に実現することができる。
なお、一覧にはalert_flagを表示したくないので、クエリのVisualization Editorで非表示にしている。

以上、とってもダサい気がするので、もっとスマートな方法ないですかね…？
WSLとwindows間のファイル連携

# tl;dr
WSL(Windows Subsystem for Linux)からWindowsファイルシステム（要はCドライブ等）へのアクセス、またはその逆でWindows側からWSLのファイルシステムへのアクセス方法です。
※Windows10 1903以降が対象です。

# WSLからWindowsファイルシステムへのアクセス

`/mnt/{ドライブ名}`からアクセスできます。cドライブの場合は、`/mnt/c`です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395902/d1eeeea8-e305-aa57-e30f-29b4739f8cb5.png)


# windowsからWSLファイルシステムへのアクセス
エクスプローラを開き、パスに`\\wsl$`を入力すると、WSLのディストリビューション毎のファイルシステムにアクセスできます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395902/51767e90-002f-a94d-24e7-a817a815fa23.png)

ちなみにPowerShellでは、`\\wsl$`直下は見れず、その下のディストリビューション名以下を確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395902/13743a29-1eec-6036-118f-9bed9cdd9900.png)

なお、コマンドプロンプトでは確認できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/395902/2747a9f7-29ba-c3df-4afc-2a853ae869fd.png)
これは今後修正されそうです。

# 他
WSL内で、`explorer.exe`を実行すると、Windowsのexplorerが起動します。
`explorer.exe .`を実行すると、Windowsのexplorerが、WSLファイルシステムのカレントフォルダで起動します。
少しひねって`explorer.exe /mnt/c`とやると、Cドライブ直下が開きそうですが、ユーザーのDocumentsフォルダが開きます。たぶんバグです。
M5StickVにとりあえず触れてみる

#研究室にM5StickVが届いた
![IMG_20190723_155528.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/89e1adb4-d789-3343-94b6-e1e6378a9601.jpeg)
スイッチサイエンスから研究室にやってきた。いい機会だしQiitaに投稿する練習も兼ねて触れてみようと思う。
#とりあえず何も考えずにUSBをぶっ刺してTeraTermで開いてみる
スイッチサイエンスのHPを見てみると「購入時に入っている顔認識スクリプトはboot.pyです。（2019/07/12現在）」とのこと。ほーん
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/d6cc354f-78b2-4b96-7b63-6dc1fdc5883c.png)
とりあえず、何も考えずに一緒に入ってたUSBでPCとM5StickVをつなげCOM番号を確認し、TeraTermを用いてどんな感じか覗いてみる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/00b40fb8-afb1-5e2b-396e-11fe57bfa02d.png)
COMポート番号もあってるし、これで良し。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/9855d827-7c2f-962a-471c-e96b5d77c531.png)
あら、文字化けしてる...こういう時ってだいたいシリアルポートの速度が間違ってるんだよね...（経験談）でも、肝心のスピードが分からないので心当たりのある数字を手あたり次第打ち込んでみる。（設定＞シリアルポート＞スピード）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/0bd2bac0-5b6f-26e4-76e4-4f495eedffe6.png)
どうやら115200みたい。読めるようになった。
#撮影会
「顔認識スクリプト」って言ってるんだから顔認識ができるんだろうと思い、~~何故か~~研究室に置いてあったフィギュアにカメラを向けてみる。
![IMG_20190723_171132.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/e8c47ba3-3b9c-5a48-8287-a7fc6c0faa8e.jpeg)
**※実験です（震え声）**
ちょっと見辛いかもしれないがM5StickVの画面の中の顔にあたる部分に白い四角が表示されているはず...見えるかな...？
TeraTermを見てみるとおお、データが取れてる取れてる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/88b2694f-3321-f641-397d-0fbaa354d71d.png)
json形式ですね...（知ったかぶり）
偶然分かったことだが、2つの顔を認証した際に一番右の列の"objnum"の数値が2となったのでこやつは認識した顔をカウントしてるんだろう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391954/40d5fdf8-be75-0333-13c4-020fcd1f82e3.png)
あとは...左2つはx座標、y座標なんだろうけど...何だこりゃ...？

次までに調べておきます...。

#引用
>[スイッチサイエンスHP　M5StickV](https://www.switch-science.com/catalog/5700/)
秘密鍵を使ったSSHでPDO接続

# はじめに
業務で踏み台経由でDBへ接続する必要があった時やったこと。
PDOはSSH接続する方法はないっぽいので、SSHトンネルをバックグランドで実行しといて、
それ宛にPDOで接続する。

バックグランド実行の方法は[こちら](https://qiita.com/MARCHXXX/items/0711c90968f354d75913)

# 環境
```
[クライアント] ---- [ 踏み台サーバー] ---- [データベース]
・Mac　  　　　　　　・ユーザー　　　　　　　・アクセスは踏み台からのみ許可
・PHP　　　　　　　　・パスワード
　　　　　　　　　　 ・秘密鍵
```

#コード
## バックグラウンドでSSHトンネリングの実行
-N 指定してリモートでコマンド実行できないようにしています。
停止のときに使うため、変数に格納しています。

```php:php
$cmd = "ssh -f -N -L 13306:dbhost:3306 sshuser@sshhost -i key/id_rsa";
exec($cmd);
```
```
[クライラント] -> [このトンネルへ13306で接続] -> [sshuser@sshhostとしてデータベースの3306へ転送] -> [データベース]
```
## PDO接続
SSHトンネリングを実行した状態で。

```php:php
//ローカルの13306へ向けて
$dsn = 'mysql:dbname=db;host=127.0.0.1;port=13306';
$user = 'root';
$password = 'root';

try {
    $dbh = new PDO($dsn, $user, $password);
    echo "接続成功\n";
} catch (PDOException $e) {
    echo "接続失敗: " . $e->getMessage() . "\n";
    exit();
}

```
## SSHトンネリングの停止

```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]);
```


## 実装
DB設定やらポート設定はかくじで。

```php:SSHTunneling.php
class SSHTunneling{

    private static $pids = array();
    private static $cmd;

    public static function start(){
        self::$cmd = 'ssh -f -N -L '.$tunnel_port.':'.DBConfig::$host_name.':'.DBConfig::$port.' '.$ssh_user.'@'.$ssh_host.' -i '.$private_key;
        echo "SSHトンネリングを開始します。".PHP_EOL;
        exec( self::$cmd ,$output ,$return_var );
        if( $return_var != 0) throw new Exception( $output[0] );
        self::set_pid();
    }

    private function set_pid(){
        $_cmd = "ps aux | grep '[0-9] ".self::$cmd."' | awk '{print $2}'";
        exec( $_cmd ,$outputs ,$return_var );
        if( $return_var != 0) throw new Exception( $outputs[0] );
        foreach ((array)$outputs as $output) {
            self::$pids[] = $output;
        }
    }

    public static function stop(){
        echo "SSHトンネリングを終了します".PHP_EOL;
        foreach (self::$pids as $pid) {
            $_cmd = 'kill '.$pid;
            exec( $_cmd ,$output ,$return_var );
            if( $return_var != 0) throw new Exception( $output[0] );
        }
    }
}
```

```php:php
$dsn = 'mysql:dbname=db;host=127.0.0.1;port='.$tunnel_port;
$db_user = 'root';
$db_password = 'root';

try {
    SSHTunneling::start();
    $dbh = new PDO($dsn, $db_user , $db_password);
    echo "接続成功\n";
} catch (PDOException $e) {
    echo "接続失敗: " . $e->getMessage() . "\n";
}finally{
    SSHTunneling::stop();
    exit;
}
```