OmniAICreator/Qiita-1.07M huggingface dataset:
typescriptでnuxt.jsのerror.vueのlayoutを指定するには

# 目的

- typescriptで書いたnuxt.jsの `layouts/error.vue` でレイアウトを指定したい

# 前提

- nuxt: 2.3.4
- typescript: 3.1.6


# 実装

static プロパティで文字列でレイアウト名を定義するかレイアウト名を返す関数を定義します

```js:layouts/error.vue

<script lang="ts">
import { Vue, Component } from 'nuxt-property-decorator';

@Component
export default class Error extends Vue {
  public static layout = 'CustomErrorLayout';

  // ctxはNuxt Contextです．　型定義は割愛
  public static layout = (ctx: NuxtContext) => {
    return 'CustomErrorLayout';
  };
}
</script>
```

[公式ドキュメント](https://ja.nuxtjs.org/api/pages-layout/) に記載されているのを参考にtypescriptで実装する際，単純にインスタンスのプロパティとして定義しても正しく動きません


```js:layouts/error.vue

<script lang="ts">
import { Vue, Component } from 'nuxt-property-decorator';

@Component
export default class Error extends Vue {
  // ------------ これは動かない
  // staticプロパティで定義しないとnuxt-property-decoratorによってdata() としてデコレートされてしまう
  public layout = 'CustomErrorLayout';
}
</script>
```

これはビルドすると生成される [.nuxt/server.js](https://github.com/nuxt/nuxt.js/blob/b83b5675043ebdfec3398bd83fd27dfe77cdd620/packages/vue-app/template/server.js#L71) を読んでみると `NuxtError.layout` と呼び出しているのが分かります
タブレット版は、もう画面幅固定にする

タブレット版は、もう画面幅固定にして、取り急ぎ対応させていただく際のviewport切り替え。
タブレット版を仮に1060pxにして画面幅を固定にします。

```js
var ua = navigator.userAgent;
if((ua.indexOf('iPhone') > 0) || ua.indexOf('iPod') > 0 || (ua.indexOf('Android') > 0 && ua.indexOf('Mobile') > 0)){
	document.write('<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no">');
} else {
	document.write('<meta name="viewport" content="width=1060">');
}
```

# まとめ
とても楽！！！
JavaScriptの型判定 typeof はもう使用しない！では、何を使ってますか？

#typeof 使ってますか？
typeof って世間一般的に (恐らく) あまり使ってないんじゃないかと思います。

使ってない理由としては私的には以下のような理由です。

- typeof null が "object" になる。
- typeof [] や {} が "object" になる。
- typeof new Number(0) とかも "object" になっちゃう。

まったく、直観的にイメージする判定ができないので使っていません。(…たまに使うかな)

ただ、かなり前ですが小飼弾さんという方が typeof を再定義されていたのでこれを一瞬だけ使ってみたこともあります。
　[javascript - typeof()を再発明する](http://blog.livedoor.jp/dankogai/archives/51755873.html)
　[javascript - 関数名の取得とtypeof()の再々発明](http://blog.livedoor.jp/dankogai/archives/51756459.html)
　(そうとう古い記事なので参考にする場合には時代背景に考慮を)

今なら Array だけは Array.isArray() でいいですけどね。昔は大変でした。

#私なりの型判定方法
今は以下のようにしています。共通で読み込む js の先頭に定義します。
結構古いブラウザでも対応していてIE9でも大丈夫です。

```js
Object.defineProperty(Array   .prototype, 'isArray'   , { value:true, writable:false, enumerable:false, configurable:false });
Object.defineProperty(String  .prototype, 'isString'  , { value:true, writable:false, enumerable:false, configurable:false });
Object.defineProperty(Number  .prototype, 'isNumber'  , { value:true, writable:false, enumerable:false, configurable:false });
Object.defineProperty(Function.prototype, 'isFunction', { value:true, writable:false, enumerable:false, configurable:false });
Object.defineProperty(Boolean .prototype, 'isBoolean' , { value:true, writable:false, enumerable:false, configurable:false });
Object.defineProperty(RegExp  .prototype, 'isRegExp'  , { value:true, writable:false, enumerable:false, configurable:false });
```

これで色々型の判定をしています。

```js
if( ary.isArray ){ ・・・ }

[].isArray
(()=>{}).isFunction
/ /.isRegExp
(99).isNumber
'aiueo'.isString
```
このような感じです。

Object.defineProperty() を使用すれば `for(x in ary)` や `Object.keys()` などでも列挙されないように定義できるので便利になりました。

`.prototype` を汚すのは良くないかなとは思うのですが、あると色々楽になるのでこれだけ例外として使用しています。

---
型判定って良く行うと思うのですが、上記のようなやり方を他で見たことがなかったのでご紹介でした。

もし、この方法では良くない、とか、他にもっと分かりやすいやり方があるよ、とか、二番煎じだよとかあれば教えて頂けるとありがたいです。
レスポンシブのJS切り替え

CSSメディアクエリみたいに、
レスポンシブでJS切り替えを書く。

``` js
//──────────────────────────────────
//レスポンシブJS切り替え
//──────────────────────────────────
$(function() {
	var windowWidth = $(window).width();
	var breakpoint = 768;
	var idTimer = null;
	var eventFlg = "";

	// ──────────────────────────────────
	// 初期実行
	// ──────────────────────────────────
	resizeInit();

	// ──────────────────────────────────
	// リサイズ
	// ──────────────────────────────────
	$(window).on('resize', function() {
		clearTimeout(idTimer);
		idTimer = setTimeout(function() {
			resizeInit();
		}, 300);
	});


	// ──────────────────────────────────
	// リサイズ時に実行
	// ──────────────────────────────────
	function resizeInit() {

		windowWidth = $(window).width();

		// PCの場合
		if (breakpoint <= windowWidth) {
			eventFlg = "pc";
			resetClassPC();

		// SPの場合
		} else if (breakpoint > windowWidth) {
			eventFlg = "sp";
			resetClassSP();
		}

	}


	// ──────────────────────────────────
	// for PC
	// ──────────────────────────────────

	// ──────────────────────────────────
	// リセット処理
	// ──────────────────────────────────
	function resetClassPC() {

	}


	// ──────────────────────────────────
	// それぞれのイベントの始めにif文でどっちか指定するルールだけ踏襲しつつ、
	// あとは好きにSPのコードを書く
	// （関数化するといいかも）
	// ──────────────────────────────────
	// ──────────────────────────────────
	// 例：gnavShow
	// ──────────────────────────────────
	$('.js-gnavBtn').on('click', function() {
		//SP版のみで実行
		if (eventFlg != "sp") return true;

		$('.js-gnav').addClass('is_active');
	});
	$('.js-gnavCloseBtn').on('click', function() {
		//SP版のみで実行
		if (eventFlg != "sp") return true;

		$('.js-gnav').removeClass('is_active');
	});




	// ──────────────────────────────────
	// for SP
	// ──────────────────────────────────

	// ──────────────────────────────────
	// リセット処理
	// ──────────────────────────────────
	function resetClassSP() {

	}


	// ──────────────────────────────────
	// それぞれのイベントの始めにif文でどっちか指定するルールだけ踏襲しつつ、
	// あとは好きにSPのコードを書く
	// （関数化するといいかも）
	// ──────────────────────────────────
	// ──────────────────────────────────
	// 例：gnavShow
	// ──────────────────────────────────
	$('.js-gnavBtn').on('click', function() {
		//SP版のみで実行
		if (eventFlg != "sp") return true;

		$('.js-gnav').addClass('is_active');
	});
	$('.js-gnavCloseBtn').on('click', function() {
		//SP版のみで実行
		if (eventFlg != "sp") return true;

		$('.js-gnav').removeClass('is_active');
	});

});
```


# ポイント

それぞれのイベントの始めにif文でどっちか指定する。
関数化してpc、spを引数で指定してもOK。

```js
$('.selector').on('click', function() {
	//SP版のみで実行
	if (eventFlg != "sp") return true;

	console.log('Hello world!!!');
});
```

PC/SP版でリセットすることがあれば、
`resetClassSP()`という名前でリセット用関数をつくったので、そこで指定。

```js
function resetClassSP() {

}
```
最近のJDKにはJava DBが含まれてなくて半日潰した件(Autonomous Data Warehouse)

休日ですが、せこせこと検証作業をしておりました。

最近、中の人としての担当は外れたのですがOracle Autonomous Data Warehouse（以下Autonomous DW)を引き続きいじってます。

↓の動画、おすすめです。


[Oracle Autonomous Datawarehouse Cloud - Machine Learning with Oracle - Forecasting example](https://www.youtube.com/watch?v=SCSBPqFLBf0&t=643s)

> This video is also a good way to learn how to work with machine learning in Autonomous Datawarehouse Cloud in general. The principles you learn here can be applied to many more machine learning use cases. We'll also cover any required ML theory, so you don't require any previous knowledge on this. 
> 
> After watching this video you will have the basic ingredients to apply ML to your own business cases with Autonomous Datawarehouse Cloud.




さすがにOracleの主力製品の中でも一押しのものなので、どんどん改善が進んでいてスバラシイと思います。これ使っときゃ間違いありません。

# Data Sync インスコしたのに動かない！

そんななかで、定期実行できるデータ投入部分で簡単な方法が無いかなと悩んでいたのですが、Autonomous DWのMachine Learningのデモ動画で使ってる、[Oracle Analytics Data Sync](https://www.oracle.com/technetwork/middleware/oac/downloads/index.html)というのが結構いけてるETLのような気がしたので、これを動かそうとしていました。

WindowsとLinuxで動くと書いてあったので、普段使ってるMacは出番なしです。

そしてインストール自体はインストーラーで簡単だったのですが、、、、エラーを吐いて起動してくれません。


![DataSyncError.PNG](https://qiita-image-store.s3.amazonaws.com/0/96615/e67f0426-4204-477e-a08d-4000c69909b0.png)

org/apache/derby/drda/NetworkServerControl　にあるべきJava DB Serverの起動に失敗したと書いてあります。周りの強そうな人たちにSlackで聞いたのですが、あいにく日曜でした。。。

JAVA_HOMEを設定するのも、Windows 10だとなれてないので非常に面倒です。そんなこんなで数時間。どうやら、JDKはちゃんと設定されてるけれど、Java DBが含まれていないようです。

```
ADWにデータ投入するのにOAC DataSyncを試しているのですが、起動時にjava DBの起動でコケます。
最近のJDKにはJava DBが含まれてないんでしょうか？ 
jdk8_191,192にはJAVA_HOME/db/のディレクトリがそもそもありません。
```


# Java DBって何？

https://www.oracle.com/technetwork/jp/java/javadb/overview/index.html
によれば

> Java DBは、オープンソースのApache Derbyデータベースをオラクルがサポートしたディストリビューションです。
> JDBC APIおよびJava EE APIにより標準のANSI/ISO SQLをサポートします。Java DBは、JDKに含まれています。


JDKに含まれてるらしいのですが、実際にはどう見てもなさげです。仕方ないからapache derbyの[配布元に行って](https://db.apache.org/derby/) インストールを試みます。


# 斜め上の結論にびっくり

ネットを探してたら、サポートページの奥深くでようやく見つけました。

要約すると、[Apache Derbyのオリジナルサイト](https://db.apache.org/derby/derby_downloads.html)から db-derby-\<release\>-bin.zip を落としてきて、JAVA_HOMEの設定をしたJDKのフォルダ内にdbという名のフォルダ名に展開しろということでした。

```
SOLUTION
Download and install the latest Apache Derby:

Go to Apache Derby: Downloads
Download the latest available release for Java 8.  At the time of writing of this document it is 10.14.2.0 (db-derby-10.14.2.0-bin.zip).
Unzip the file to db-derby-<release>-bin and rename the directory to 'db'
Move the 'db' directory to JAVA_HOME (you will need Administrator access)
Start Data Sync
```

つまり、最近のJDKからは、Apache Derbyが取り除かれたようです。

この設定を入れたら、何事もないようにData Syncが起動しました。

つづく
はじめてのClickUp#1

#ClickUpとは？
[asanaのalternativeだと自分で言い張る](https://clickup.com/blog/choose-clickup-over-asana/)プロジェクト管理ツールです。
シリコンバレーのスタートアップで、Nike, Uber, Google, AirBnBなど25000の企業から採用されており実績ありです。

#登録してみた
無料で使用できるので、何はともあれ登録してみましょう。
[clickupのサイト](https://clickup.com/)にアクセスして、右上にある"Sign up free"を選択します。
<img width="314" alt="スクリーンショット 2018-12-03 20.27.37.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/ffd93984-c4d7-b719-74a2-c681d6c56c3e.png">

emailを入力してクリックします。
<img width="1247" alt="スクリーンショット 2018-12-03 20.29.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/f990ef95-d613-e2d9-eedd-77fc68f96507.png">

名前とパスワードを入れて"Play with ClickUp"します。
<img width="674" alt="スクリーンショット 2018-12-03 20.32.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/c3ec8a14-8a6a-a80d-ee2d-a01222417071.png">

コードが送られてきますので、入力して"Verify"します。私の場合なぜか入力してもinvalidになりました、メールのリンクをクリックしたらいけました。

#初期設定してみた
登録完了後、Welcomeされるので、"Let's do it"します。
<img width="290" alt="スクリーンショット 2018-12-03 20.35.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/34f58882-44ba-5f3e-a7a5-a3d436575762.png">

アバターを指定します。いろんな色でも、ドラッグ&ドロップで画像でも指定できます。
<img width="1091" alt="スクリーンショット 2018-12-03 20.39.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/0cd97f53-ed82-7f26-2155-cc4b26c559d7.png">

好きなテーマ色を選びます。
<img width="579" alt="スクリーンショット 2018-12-03 20.41.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/623a9cee-8ebe-6dfa-3549-824d51022dbd.png">

インテグレーションしたいサービスを選択します。今回は何も選択しません。
<img width="699" alt="スクリーンショット 2018-12-03 20.42.39.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/277ff9cb-d084-9c1e-8938-19eb6ea6fed1.png">

個人かチームか選択します。今回は個人を選択します。
<img width="588" alt="スクリーンショット 2018-12-03 20.43.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/ba454429-ea31-2b87-c84f-3d159b747ba2.png">

これで設定は完了です！！1分もかかりませんね。"Play with ClickUp"を選択します。
<img width="698" alt="スクリーンショット 2018-12-03 20.44.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/0e8b5f6c-baa0-3a21-5404-486cf3923d4d.png">

設定完了後、言語に関するポップアップがでてきました。日本語で使ってみたいので、"Enable global font for my language"を選択します。
<img width="568" alt="スクリーンショット 2018-12-03 20.46.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/be4f8869-ad89-e12f-ab4e-e2fc11dadc09.png">

#設定完了！
これで準備完了です！！最初にサンプルのプロジェクトが表示されます。
<img width="1654" alt="スクリーンショット 2018-12-03 20.57.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/231906/9e54a728-4efe-a742-e0f1-b89265cc1c8e.png">

#終わりに

ClickupはFreeプランが充実しており、2018/12時点で100MBまでほぼ全部の機能が使い放題です。
>100MB storage
>Unlimited Users
>Unlimited projects and spaces

登録は簡単ですね。次回[はじめてのClickUp#２](https://qiita.com/uguisu/items/ed095df90831ba11d72f
)は実際にタスクを使ってみたいと思います。
最速で GCP の k8s に クラスター作ってみる by Rancher

# GCP の k8s に 最速（？）でクラスター作成してみる

いや、多分、最速じゃないですけど・・・最速なら GCP の管理画面からポチっとしますｗ
Rancher 2.x でもう一回 GCP の k8s チャレンジというものです。
一度チャレンジしてできはしたのですが、その時の要件には合わず Rancher 1.x に戻したので再チャレンジです。

前回は 2.0 だったのですが、今回は 2.1 ですね。
なんか、let's encrypt のやつが消えてるような気がするのは気のせいかな。。。
SSL は Cloudflare 経由でやると大丈夫になってるぽい。

## とりあえず、Rancher 入れまっしょい

Docker が動いてる適当な Linux サーバで下記を実行します。

```
> sudo docker run -d --restart=unless-stopped -p 80:80 -p 443:443 rancher/rancher
```

なんかうちの Docker 環境では下記のようなエラー出たので、 [こちら](https://qiita.com/miwato/items/9770a2a757d3f5e369a4) 参照して対応しました。

```
Error response from daemon: driver failed programming external connectivity on endpoint nifty_perlman (3d0a24afd0e2e90313bdbf2e86c94705181deaca9e7d71abe2f64596eff1e215):  (COMMAND_FAILED: '/usr/sbin/iptables -w2 -t nat -A DOCKER -p tcp -d 0/0 --dport 443 -j DNAT --to-destination 172.17.0.3:443 ! -i docker0' failed: iptables: No chain/target/match by that name.
)
Error: failed to start containers: bf700e0a364b
```

こんな対応ですね。

```
> sudo mv /var/lib/docker/network/files /tmp/docker-iptables-err
> sudo systemctl restart docker.service
```

これで `docker start` できるようになります。

## Rancher にアクセス

`https://<domain>` or `https://<ip address>`

最初の画面でパスワード設定言われるので、適当に設定しましょう。
設定するとログインできます。

![rancher_001.png](https://qiita-image-store.s3.amazonaws.com/0/318450/aec12fdf-e359-8b0a-8d33-50f5a573eadd.png)

## Cluster を追加する

`Add Cluster` をプチっと押すと、GCP になんかチェックが入った画面が出てきます。

![rancher_002.png](https://qiita-image-store.s3.amazonaws.com/0/318450/ccc2ec5b-5db8-b006-b6c3-ce03f2d6ddc7.png)

`Cluster Name` に適当な名前を打ち込みます。

`Service Account` には、GCP で作成したサービスアカウントの json キーをぺたぺたします。
※必要な権限は書いてあるので、その通りに作れば問題ないはずです。

![rancher_003.png](https://qiita-image-store.s3.amazonaws.com/0/318450/311b3b61-bc2e-7585-bed6-0fdb448a60ba.png)


`Nodes` では、`Zone` は普段使用してるリージョン選んで、`Machine Type` は適当にという感じです。
今回はテストなので、`f1-micro` でやりました。一瞬で終わるつもりなので、とりあえずノード数とかディスクサイズは放置でいきます。

`Create` を押しちゃいます！！

## プロビジョンされたのを確認

問題なければ、 `Provisioning` って出ると思います。

![rancher_004.png](https://qiita-image-store.s3.amazonaws.com/0/318450/2f875353-9bc0-8bee-ec24-a9eb5c255294.png)

`Cluster Name` をクリックすると、ダッシュボードが出てきます。
プロビジョニング中はこんな画面です。

![rancher_005.png](https://qiita-image-store.s3.amazonaws.com/0/318450/04a8ebbd-e373-010f-277e-2e4e82b9ac52.png)

で、終わると、こんな感じになります。

![rancher_006.png](https://qiita-image-store.s3.amazonaws.com/0/318450/5e999863-3d86-873c-f0b6-19738e4ab9ba.png)

一応、GCP側でも確認しときましょう。

![rancher_007.png](https://qiita-image-store.s3.amazonaws.com/0/318450/24fe90a7-7fb8-c64b-e3ed-fa5dc5c5057b.png)

なんか、できてますね。

## まとめ

相変わらずらくちんなのは変わらないですね。
ただ、ネットワークはやっぱり選べないんですかね・・・
とりあえず、さくっと GCP の k8s クラスターを立ち上げる編 by Rancher でした。

## 参照

[Quick Start](https://rancher.com/quick-start/)
Reproを使いやらかしてしまった話 

こんにちは！こんばんは！

昨日の17日目はnakazさんの[グロース初心者がGoogle オプティマイズを使ってABテストを開始するまでの話](https://note.mu/nakaz/n/nfb7f89e0c2a6)でした。
僕のプロダクトでもABテストをやりたい気持ちはありつつできずに悶々としているのでいいなぁ羨ましい気持ちでした！

ではでは今日はやらかした話をします。

#そもそもReproとは
ユーザーの行動分析をしたり、特定の行動をしていない人へ向けてPush通知を送ったり、特定の人にダイアログを出したりできるツールです。
行動を録画することや、録画したくない箇所はモザイクをかけることもできます。
僕のいるプロダクトではファネル分析もReproで行なっていたりととても便利に使わせていただいています。
https://docs.repro.io/ja/


#どんなやらかしをしたの？
他のプロダクトでReproをやめようとしたところ、やめる必要のない僕のいるプロダクトのデータを全て削除してしまった。
Reproの方と電話でオペレーションしていただきながら削除を行なっていきました。
削除に伴い警告アラートなどもちゃんと表示されたが、弊社とRepro側の**認識のズレ**から削除に至ってしまう。
・Diverse側の認識では一部プロダクトでは使い続け、それ以外のプロダクトではReproをやめたい
・Repro側での認識は全てのDiverseの全プロダクトでReproやめる
(※ちなみに削除したのは私ではありません)

#全てってどんなデータ？
- 登録しているPushの証明書(iOS)
- GCMキー(FCM API Key)
- ユーザーのPush配信のためのデータ
- 定期的に送っていたPushのデータ
- ユーザーの行動を録画したもの
- ユーザーのイベントログ
- など

#復旧してもらえたもの
- ユーザーのPush配信のためのデータ
- 定期的に送っていたPushのデータ
- ユーザーの行動を録画したもの
- ユーザーのイベントログ

#まとめ
動画ファイルなどは復旧はできませんでしたがPush配信のためのデータやイベントログは復旧していただけたので、大した問題にはなりませんでした。(本当にありがとうございます！！)
しかしながら、弊社側の問題により慌てることになりました。下記悲しみの事案です。

- AndroidO向けのチャンネル未指定のためPush通知が届かない
 - Reproを導入後にライブラリアップデートなどのメンテナンスをしていませんでした
 - ライブラリの最新化を行い、足りない実装をドキュメントを読みつつ実装していきました。
- iOSの証明書が行方不明事件(証明書の野生化)
 - 前回証明書作成者が退職済みで、更にファイルサーバーや1password内にも証明書がありませんでした。
 - 新しい証明書を発行し、1passwordで証明書の管理をはじめました。
- FCMのキーのアカウントどれだ問題
 - ひたすら1passwordにあるアカウントから発掘作業を行いました。

今回のことがきっかけでアカウント管理という基本的なことから見直すことができ結果よかったのではないかと思います。

その後Reproの勉強会にてこのことを発表する機会がありました。
復旧作業をしてくださりReproのみなさま、ありがとうございました！
これからも使っていきたいと思います！

#明日
明日は@yuki-o さんの **FlareをFlutterだけじゃなくてJSでもFlareった話** です！
Flareった？ふれ合った・・・ふれ・・・。
ルートパラメータ



#ルートパラメータとは

Route::getでは、アクセスする際にパラメータを設定し、値を渡すことができます。

これは以下のように記述します。

```
Route::get('/○○/{パラメータ}',function( $受け取る引数 ){....});
```

第１引数のアドレス部分に、**{パラメータ}**という形でパラメータを用意する。


これでこの**{パラメータ}**に指摘されたテキスト部分がパラメータとして取り出されるようになる。

第２引数の関数では、パラメータの値を受け取る変数を引数として用意しておく。

これは、パラメータ名と同じ名前である必要はない。

**{パラメータ}**で指定したパラメータの値は、そのまま関数に引数に渡される。

パラメータは複数用意することもできる。

関数の引数を複数用意することで、これらの値を受け取れるようになる。

<img width="378" alt="スクリーンショット_2018-12-03_20_30_30.png" src="https://qiita-image-store.s3.amazonaws.com/0/300596/40bcf365-4cb4-9362-f071-835309d8263c.png">

# パラメータを利用する

/hello/のアドレスの後にテキストを追記してアクセスしてみると、アドレスにつか化した部分がパラメータとして取り出され、Webページ内にメッセージとして表示されるようになる。

```
Route::get('hello/{msg}',function ($msg){
$html = <<<EOF
<html>
<head>
<title>Hello</title>
<style>
body {font-size:16px; color:#999;}
h1 {font-size:100px; text-align:right; color:#eee; margin:-40px 0px -50px 0px; }
</style>
</head>
<body>
 <h1>Hello</h1>
 <p>{$msg}</p>
 <p>これは、サンプルで作ったページです</p>
</body>
</html>
EOF;

  return $html;
});
```

こんな感じ！！

<img width="1441" alt="Hello.png" src="https://qiita-image-store.s3.amazonaws.com/0/300596/f9252633-caa9-19d7-eda0-df03b80eb91d.png">

こんな感じでアクセスすると、「eee」の部分がパラメータとして取り出され、Webページにメッセージとして表示される。

#Route::getのパラメータについて

先ほどのコードを見てみると

第1引数 →"hello/{msg}"
第2引数 →"function($msg){...}

となっています。

第１引数では"hello/{msg}というようにして、hello/の後に{msg}というパラメータを用意していますね。

第２引数では、クロージャの引数に$msgというパラメータを用意しています。

これにより、{msg}の値が$msg引数に渡されるようになります。

もちろん複数になっても同じです。

```
Route::get('hello/{id}/{pass}',function ($id, $pass) {...略...});
```

こんな感じで使えます！！

#ちょっと応用（追記）

コントローラでルートパラメータを利用する方法について追記します！！

参考例としてコードを書いてみるのでそれをみてパクってみてください！！（適当）

```routes.
Route::get('アドレス/{パラメータ}}','コントローラ名@アクション名');
```

```Controller.
Class コントローラ名　extends Controller{
   public function index($パラメータ）{
　　　　　    return ~~~~~
   }
}
```

みたいな感じで使うことができます！

もちろん任意パラメータも使うことが出来ます！

雑すぎたかな御免なさい一応自分の頭を整理するのが目的なので、、


##メモ

[パラメータとは](https://wa3.i-3-i.info/word1443.html)
→外から入ってくる値!!

[クロージャとは](https://www.slideshare.net/hajikami/ss-7496551)
→名前のない関数??

---
また、この記事は[PHPフレームワークLaravel入門](https://www.amazon.co.jp/dp/4798052582/ref=asc_df_47980525822542427/?tag=jpgo-22&creative=9303&creativeASIN=4798052582&linkCode=df0&hvadid=295678107984&hvpos=1o2&hvnetw=g&hvrand=15604873734545540909&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028850&hvtargid=pla-526985037105&th=1&psc=1)のアウトプットとして書いてみました。

**自分がまだ理解していない部分を文字で起こすことによって頭の中を整理する**ことが目的です。

ルートパラメータはなんか難しそうだったけど、ただのルートのパラメータなんだなって笑笑

これはルートの外でも使えるのかな？？

進めていけば応用あると思うから楽しみだ！！

最近気付いたのが、難しい単語は分裂させて調べたらわかりやすくなるとゆうこと。

いい気づきを得ました笑笑

終

---

**ちょっと応用（追記）**を追記しました！！　

先ほどの疑問の**「これはルートの外でも使えるのかな？？」**とゆうのを解決できてよかったです！！

朝活中、眠いけど頑張るzzz

おやすみな、、、

終
＜1つの解決策:Mac＞CompilerSelectionError: OO cannot be built with any available compilers.

rbenvをbrewでインストールすると、エラーが出ました（以下）。

```
MacBook-Pro-2:~ user$ brew install rbenv
Updating Homebrew...
==> Installing dependencies for rbenv: ruby-build
==> Installing rbenv dependency: ruby-build
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
Error: An exception occurred within a child process:
  CompilerSelectionError: ruby-build cannot be built with any available compilers.
Install GNU's GCC
  brew install gcc

```



gccが必要なのかと、 gccをbrewでインストールすると、同じようなエラーが。。

```
MacBook-Pro-2:~ user$ brew install gcc
xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun
Error: An exception occurred within a child process:
  CompilerSelectionError: gcc cannot be built with any available compilers.
Install GNU's GCC
  brew install gcc


```
ここで、brewで何かインストールする事自体に不具合が生じていると思い、とりあえず、エラーの他の部分をいくつかググってみました。

すると、
”xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun”
の部分をググってヒットしたリンク
https://qiita.com/ARTS_papa/items/60ba305b23dc967bba87
で、解決。
（以下のコードをターミナルで実行するだけです。）

```
$ xcode-select --install
```
xcodeの何かがインストールされて解決。
（本来Xcodeのなかにgccコンパイラーが入っていて、xcodeの一部か全部が欠落してたっぽい。）
（ブラウザに飛んでインストールされました。）

。問題なくbrewでのrbenvのダウンロードができたとさ。

```
MacBook-Pro-2:~ user$ brew install rbenv
Updating Homebrew...
==> Auto-updated Homebrew!
Updated 1 tap (homebrew/core).
==> Updated Formulae
composer                   fx                         libswiften

==> Installing dependencies for rbenv: ruby-build
==> Installing rbenv dependency: ruby-build
==> Downloading https://github.com/rbenv/ruby-build/archive/v20181106.tar.gz
==> Downloading from https://codeload.github.com/rbenv/ruby-build/tar.gz/v201811
######################################################################## 100.0%
==> ./install.sh
🍺  /usr/local/Cellar/ruby-build/20181106: 420 files, 212.6KB, built in 11 seconds
==> Installing rbenv
==> Downloading https://homebrew.bintray.com/bottles/rbenv-1.1.1.mojave.bottle.1
######################################################################## 100.0%
==> Pouring rbenv-1.1.1.mojave.bottle.1.tar.gz
🍺  /usr/local/Cellar/rbenv/1.1.1: 36 files, 62.8KB

MacBook-Pro-2:~ user$ rbenv version
system (set by /Users/user/.rbenv/version)
MacBook-Pro-2:~ user$ rbenv -v
rbenv 1.1.1
```
Ciscoでよく使うコマンド！（ルーティング編）

▼機器にログインしたらまずは、

```
SWA>enable
```

これは基本ですね！

▼とあるネットワークへのネクストホップを知りたい場合は、

```
SWA#show ip route [調べたい宛先ホストIPまたはネットワーク]
```

の前に、最近ではL3スイッチの内部でVRFが切られていることもあるので、
私はまず、

```
SWA#show vrf
```

でVRFの有無を確認します。
ルーティングテーブルはVRFごとに存在します。

▼VRFがある場合、

```
SWA#show ip route vrf [VRF名]　[調べたい宛先ホストIPまたはネットワーク]
```

とします。

▼VRF名が「hoge-vrf」、調べたい宛先ネットワークが「172.16.6.0」の場合は下記のように指定します。

```
SWA#show ip route vrf hoge-vrf 172.16.6.0
```

▼出力結果の例

```
O     172.16.5.0/24 [110/2] via 172.16.2.2, 00:00:20 Vlan20
```

・この例では先頭のOはOSPFでアドバタイズ（広告）されてきた経路情報であることを意味します。
・EだとEIGRP
・Sはスタティック（手動で設定した経路）
・CはConnected(直接接続されているネットワーク)
です！

・Viaは「●●経由」という意味なので172.16.2.2がネクストホップ
・この径路が広告されてきてからの経過時間は20秒
・そしてinterface Vlan20 の先にネクストホップが存在します。

▼そして下記でインターフェース情報を確認することができます。

```
#show run int Vlan20
interface Vlan20
 description ##SWB##
 ip address 172.16.2.1 255.255.255.0
```

・上記のDescriptionが正しければ、
![図.png](https://qiita-image-store.s3.amazonaws.com/0/130739/f65ee302-e629-6b6c-3cbc-9d653c9d4876.png)

な感じに接続されていることがわかります。
Descriptionの情報は時に古かったり誤っていたりするので、対抗機器の情報は対抗機器に直接ログインして確認するのが最善です。

同じようにネクストホップにログインして`show ip route`すれば、調べたい宛先ネットワークへの径路がわかると思います。

これらはもちろん、経由機器に置いてicmpが許可されていれば`traceroute`コマンドで経由機器を一発確認することも可能です。
scpでファイル転送するメモ

# scpでファイル転送するだけのメモ

ただのメモです。

```
scp 転送するファイル ユーザー名@APアドレスなど:送る場所
↓
scp home/hoge/test.php hoge_user@54.230.444.82 /home/tmp
```

## ディレクトリ以下を再帰的に転送したい！

```
scp -r home/hoge hoge_user@54.230.444.82 hoge.tmp
```

`-r`を付けるとディレクトリ内を再帰的に転送します。
もう上下左右中央揃えでググらない！elm-uiで簡単レイアウト！

[elm-ui](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/)

- [CSSができなくても安心！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/e29a97102df8770a6375)
- [もう上下左右中央揃えでググらない！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/c423af7b8c4b0f9dc200)
- [要素の検証はもういらない！？elm-uiで簡単UIデバッグ！](https://qiita.com/miyamo_madoka/items/9700a4994daa95934d39)


# 「今まで上下左右中央揃えでググった回数を覚えているか？」

整列は大事ですよね。特に中央揃えしようと思って都度都度調べてる人はいると思います

なんとelm-uiなら簡単素直に任意の要素をそろえることができるようになります
では実際にやってみましょう！

# 「まずはrow, columnがあった」

[Ellie](https://ellie-app.com/44q39TM6Rp6a1)で実際のコードと見た目を確認してください

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/2f3d89c1-a200-1c48-0121-b8f275a74a55.png)

```elm
view : Element msg
view =
    row [ width fill, height fill, spacing 16 ]
        [ text "hello", text "world" ]
```

さて、ご覧の通り左寄せの上下中央揃えで要素が表示されています
ちょっと説明のためにexplainを入れてみましょう

[Ellie](https://ellie-app.com/44qkgnjHx6sa1)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/6da3a9bf-68f2-c4e9-d3ae-f96135277f5b.png)

茶色の線が親の`row`、緑？の破線が子要素になります
`row`には`fill`を指定してめいっぱい大きくしてるので広がってます。子要素は何もしなくても上下中央揃えになりましたね

では左右も中央揃えしちゃいましょう

[Ellie](https://ellie-app.com/44qrx33SK4Za1)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/74093/47e5a379-6ce7-1905-e551-918eae6c76ef.png)

```elm
view : Element msg
view =
    row [ width fill, height fill, spacing 16, explain Debug.todo ]
        [ el [ centerX ] <| text "hello"
        , el [ centerX ] <|text "world"
        , el [ centerX ] <|text "🐐🐐🐐🐐🐐"
        ]

```

はい、真ん中に行きました
このように`row` ( `column` ) の中を整列させたい場合、子要素に[ここら辺のattribute](https://package.elm-lang.org/packages/mdgriffith/elm-ui/latest/Element#centerX)を指定するといい感じにできると思います

`row`では左揃え上下中央揃えがデフォルトでしたが`column`では左右中央、上揃えになります

細かい動作に関しては自分で指定して試してください
とりあえずヘッダによくある [左にロゴ右にメニュー](https://ellie-app.com/44qCj9QG4Zqa1) みたいなの置いときます

> note1
「explain Debug.todoって何？」
[ここに](https://scrapbox.io/miyamoen/Element.explain)前書いたけど次回（未定）にQiitaに書きます

> note2
「破線が二重になってるんですが」
仕組みまでは踏み込んで調べてないので書けません。でもなんとなくわかることないです？

# 「justify-contentってこと？」

justify-contentとかalign-itemsなんて知りません。単に`centerY`とか`centerX`ですよ？覚えられましたね？

実際flexboxなのでjustify-contentとかで実装されてるんでしょうが意識したこと（意識しなくてはいけなかったこと）はありません

# まとめ

elm-uiいいぞ

今回はこれくらいにしといて次回（未定です）はelm-uiでのデバッグ（explain）について書こうかと思います

- [CSSができなくても安心！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/e29a97102df8770a6375)
- [もう上下左右中央揃えでググらない！elm-uiで簡単レイアウト！](https://qiita.com/miyamo_madoka/items/c423af7b8c4b0f9dc200)
- [要素の検証はもういらない！？elm-uiで簡単UIデバッグ！](https://qiita.com/miyamo_madoka/items/9700a4994daa95934d39)
systemtap小ネタ

思い付いた/思い出したら追記します。時代はeBPFなのかも知れないけれど、old typeなのでまだまだsystemtapでがんばります。

##begin/endプローブ
beginは、スクリプト起動時に実行される。stapコマンド起動時に-vオプションを忘れると、いつスクリプトの実行が開始されたか分からないので、私はいつもbeginでprintfを実行するようにしている。

endは終了時に実行される。Ctrl-Cで止めたときも実行されるので、統計を溜めておいて適当な時間後にCtrl-Cを押して結果を表示する、という使い方ができる。

```
probe begin {
  printf("Script starting\n");
}

probe end {
  printf("Result: %d\n", counter);
}
```

##コマンドライン引数
stapコマンド起動時に引数を与えられる。第1引数は\$1、第2引数は\$2、...。@1、@2という形式で書くと、文字列扱い。

```arg.stp
probe begin{
  printf("1st arg: %d\n", $1);
  printf("2nd arg: %s\n", @2);
}
```

実行例

```
$ sudo stap arg.stp 1 2
1st arg: 1
2nd arg: 2
```

引数はモジュールに定数として埋め込まれるようで、引数を変えるとスクリプトは再コンパイルされる。同じ引数を与えると、キャッシュが使われる。
フォント

#セリフ体
・飾りがついている文字
・日本語フォントでは明朝体がこれに当てはまる
・セリフは鱗という意味

#サンセリフ体
・飾りがついていない文字
・まっすぐの棒線のみで構成
・サンはフランス語でnoの意味
・日本語フォントではゴシック体がこれに当てはまる


``アルファベットをきれいに見せたいときや文字で魅せたい時に使われているのは有料フォントが多い``
pugファイルにphpを書く

phpのメールフォームを実装するときに
どうしてもpug環境を手放したくなかったので、なんとかしました

# 前提条件
- gulp
- pug


# ディレクトリ構成
基本は拡張子`.html`を使用し、
お問い合わせページだけ`.php`にします

```
index.html
　└─ contact/
　　　└─ index.php
```

# gulp タスク

`gulp-rename`パッケージを入れておいてください

```
$ npm install gulp-rename --save-dev
```

gulpfileでの設定は以下

```js:gulpfile.js

var gulp = require('gulp');
var rename = require('gulp-rename');

/* ─────────────────────────────
/contact/ディレクトリのみ、
.pugを.phpへコンパイル
───────────────────────────── */
gulp.task('pug:toPhp', function () {
	return gulp.src('src/contact/**/*.pug')
		.pipe(pug({
			basedir: 'src',
			pretty: true
		}))
		.pipe(rename({
			extname: '.php' //phpファイルとして書き出し
		}))
		.pipe(gulp.dest('dist/contact/'))
});

/* ─────────────────────────────
.phpで作成したファイルは
そのまま.phpとしてコンパイル（コピー）
───────────────────────────── */
gulp.task('php', function() {
	return gulp.src('src/**/*.php')
		.pipe(gulp.dest('dist/'))
});
```

# pugにphpを書く

基本的に文字を改行したいときと感覚は変わりません

文頭に`|`でコンパイルしてくれます

```php
| <?php print('Hello World!!!!!'); ?>
```

または、
文末に`.`を打ったあとに、インデント一つ落とします

```php
p.
	<?php print('Hello World!!!!!'); ?>
```

## タグの属性値として書く時

`!=`を使用する
（クオテーション気をつけて！）

```php
input(type='text' name='' value!='<?php echo "ここにvalue値を入れる"; ?>')
```



または、
`!=`とインデントの合わせ技で視認性UP！

```php
input(
	type='text'
	name=''
	value!='<?php echo "ここにvalue値を入れる"; ?>')
```


## 長文のときは

長文のphpは外部ファイル化してインクルードすると楽でした

```php
| <?php include('XXX.php'); ?>
```

# まとめ

無理矢理感が否めない。
ハッピーpugライフを！
JSONからKotlinのクラスを生成するPluginを使ってみた

# Pluginのインストール
Preferences　→ Plugins　→　Browse repositoriesボタンを押す
検索窓に「KotlinTo」
<img width="400" alt="スクリーンショット 2018-11-30 19.29.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/46743/32be21cb-5058-dbdc-b76a-006fc4a7b083.png">

# 使い方
1. 対象になるファイルを作成する
2. option ＋ K のショートカットにてプラグインを呼び出す
3. クラス名とJSONを記入する
4. Makeボタンをクリック
<img width="400" alt="スクリーンショット 2018-12-03 21.02.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/46743/1763ce63-7f7c-da6d-feab-dacad6b10408.png">

Gsonのアノテーションを付与した場合のクラス

```kotlin:作成されたクラス
package com.example.s_mori.myapplication
import com.google.gson.annotations.SerializedName

data class User(
    @SerializedName("Option")
    val option: Option?,
    @SerializedName("id")
    val id: Int?, // 12345
    @SerializedName("mail")
    val mail: String?, // test@gmail.com
    @SerializedName("name")
    val name: String? // test
)

data class Option(
    @SerializedName("option1")
    val option1: Boolean?, // true
    @SerializedName("option2")
    val option2: Boolean? // false
)
```

# 対応しているObjectMapper
Gson
Jackson
Fastjson
MoShi
LoganSquare
その他の物でも、カスタムで対応できるようです

# 参考
https://plugins.jetbrains.com/plugin/9960-json-to-kotlin-class-jsontokotlinclass-
【維持費０】Qiitaの派生ツールをまとめた alt-qiits.tk を作りました【個人開発】

この記事は[個人開発 #2 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/private-developmen2)の3日目です。

昨日は @mikkame さんの　「[盛り上がっているQiita記事を見つけるサイト「🔥-qiita.tk」を作りました。](https://qiita.com/mikkame/items/fe788b29ec6ea594030c)」 でした。

# なぜ作ったのか

- 最近Qiita関連のツールばかり作っているのでまとめたくなった。
- 有名どころだと [Qiitaの殿堂](https://qiita.com/youwht/items/9851c2ac9024633fc04e)など、他にも派生物を作ってる人が多い
- 昨日とは違う構成で作ってみたかった
- ~~ネタが尽きた~~
- ~~平日だし時間ないから簡単なものを~~

# できたもの

[https://alt-qiits.tk/](https://alt-qiits.tk/)

です！（画像のアス比がやばいのでそのうち直します）
こういうのって勝手に掲載していいのかな？
何人かの人には掲載していいか聞いているところです。

# 今回の構成

## バックエンド Google Spread Sheet + Google Form

みなさんご存知かと思いますが、Google Formでフォームを作り、送信された内容をSpreadSheetに記録していくことができます。

<img width="858" alt="スクリーンショット 2018-12-03 20.28.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/180411/9c175a54-c85a-e9ff-9e23-1f09022d80f8.png">

このようなフォームを作成し

<img width="1055" alt="スクリーンショット 2018-12-03 20.29.10.png" src="https://qiita-image-store.s3.amazonaws.com/0/180411/9e4358b0-6f9e-e1a1-c967-d3fe0e4e5e3c.png">

このようなシートに連携させます。

一応、荒らし防止のため、status欄にOKを記入すると掲載されるように
（バッチが回ったタイミングで）しています。

## フロントエンド

Nuxtで適当につくりました。１ページだけなのでnuxtである必要がないかもしれません。
netlifyでbuildしたかっただけかも・・・。

## TODO

- 画像のアス比直す
  - 多分imgじゃなくて背景にして調整すればいいはず
- Google SpreadSheetの更新をフックしてNetlifyのビルドを回す
- 掲載内容を増やす


# あとがき
[個人開発 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/private-development) が埋まっていたので #2を勝手に増設したんですが
11月末時点で半分ぐらいしか埋まってなかったので１、２、３と埋めてしまいました。
~~12月に入ってから埋まり始めたので雑な記事で埋める必要なかったのかな~~
結果、ほぼ埋まっているみたいなので嬉しい限りです！

明日は　@sti320a さんの　「Harigami」です！
と思ったらすでに公開されているっぽいのでリンクしておきます！
[ログイン不要／最短15秒でソースコードを共有できるWebアプリ「Harigami」を作った](https://qiita.com/sti320a/items/15435ad6792a7b7b1dd8)


# PS

3日中にリリースし記事も書いて投稿したが、カレンダーに登録するのを忘れた結果、遅刻した形になってしまった
このままはいやだ！成長を止めないための学び方

[SC（非公式） Advent Calendar 2018](https://qiita.com/advent-calendar/2018/unofficial-sc) 4日目！
文系システムエンジニアのkurimegです。

なんとなくアプリは動いたけど、
**「どういう仕組みで動いているのかわからない」**
**「これから何を学べばよいのかわからない」**
こんな壁にぶち当たったときに実践して、今も役立っているなと思うことをまとめました。

自分に合う学び方は人それぞれだと思いますので、少しでも何かのヒントになればと思います！

# 学び方を学ぶ
[総合職で入社した新卒がクックパッドでエンジニアになるまで](https://techlife.cookpad.com/entry/2015/10/30/125405)
[人は一ヶ月でエンジニアになれるのか - 詳細解説]
(https://www.slideshare.net/livesense/ss-46078743)
[とあるエンジニアの技術勉強法 (インターン学生向け)]
(https://www.slideshare.net/iwashi86/ss-58640407)
[学生時代に知っておきたかったWeb技術の学び方の学び方 | リブセンス]
(https://www.slideshare.net/livesense/web-49772012)

こちらの資料を参考に、「まず何をどのように学んでいくか」以下のような方針を立てました。

1. どのような分野があるのか、全体像を把握する 
1. 各分野の理論を学び、実践する

# どのような分野があるのか、全体像を把握する
「アプリがどのように動いているのか」、「学ぶべき分野は何があるのか」を知るために以下を参考にしました。
[コンピュータサイエンスのカリキュラム]
(https://www.is.s.u-tokyo.ac.jp/appli/curriculum.html)
[Webで学ぶ 情報処理概論]
(http://www.infonet.co.jp/ueyama/ip/)
[コンピュータはなぜ動くのか～知っておきたいハードウエア＆ソフトウエアの基礎]
(http://amzn.asia/d/2V2kkyB)
[プログラムはなぜ動くのか　第２版　知っておきたいプログラムの基礎知識]
(http://amzn.asia/d/50LTSWp)
　より詳しく知りたい場合…
　　[コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方](http://amzn.asia/d/cplBqB7)

これらを読み終えてから…

- **歴史を知ることで、なぜその技術が生まれたのか分かった**  
何を解決するために生まれた技術かを知ることで、使いどころや似たような技術との違いが分かりやすくなりました。
- **アプリが動くイメージが具体的になった**  
自分の書いたプログラムがコンパイルされて、機械語になってハードウェアの領域に入って…とアプリが動くイメージが具体的になりました。
- **知識のインデックスができた**  
今までばらばらだった知識がどの分野の知識なのか分かることで、自分の頭の中にインデックスができ、新しい知識も覚えやすくなりました。

# 各分野の理論を学び、実践する
知識も大きく2つに分かれると思います。

1. 理論的　主に書籍から
1. 実践的　主にTwiiterなどWeb、勉強会から

実践的な知識だけあっても、応用が利かないし、
理論的な知識だけあっても業務では役に立たないと思います。

## 理論
私はこちらを参考に、難易度が低いものを各分野満遍なく読んでいきました。
[新卒ソフトウェアエンジニアのための技術書100冊]
(https://techlife.cookpad.com/entry/2015/03/31/093000)

ただ読むだけではなく、要約して、実際にアプリを作ってみたりしながら（題材としては有名なアプリのクローンが良いのかなと思います。）、理解を深めていきました。

中でもこちらは早いうちに読んでおけば、それぞれの概要がつかめたなと思いました！
[コーディングを支える技術]
(http://amzn.asia/d/3Eosalj)
[Webを支える技術 -HTTP、URI、HTML、そしてREST (WEB+DB PRESS plus) ]
(http://amzn.asia/d/gnqlkWb)

## 実践
全体像がつかめて、基礎理論が理解できたら、
その後は自分の好きな分野を学んでいけば良いと思います。
むしろ、自分の好きな分野を見つけるための全体像把握かなと思います！

私は、色々学んでいく中でフロントエンドが好きだなと感じたので、
そういった勉強会に行ったり、Twitterのアカウントをフォローして通勤時間に最新の情報を見るようにしています。

# 最後に
言葉にすると当たり前のようですが、
「学ぶべきものがありすぎで何から手を付けたらよいのか分からない！」状況だった私にとって、ここであげた資料は本当に助かりました！

まだまだ深められていない分野はたくさんあるので、これからもどんどん吸収していきたいなと思います！
VR,ARの情報収集にオススメのサイトまとめ

最近ARにどっぷりはまっているのでよく見るニュースサイトをまとめました。

#1, https://www.moguravr.com/

毎日見てるmoguravr。
日本のサイトでVTuverのニュースも載ってるのが嬉しい。

#2, https://www.watch.impress.co.jp/vr/

こちらも日本のサイト。
幅広く色々載ってて良い。

#3, https://www.roadtovr.com/

英語のサイト。
ゲーム系の記事が多い印象。

#4, https://venturebeat.com/category/arvr/

英語のサイト。
満遍なくいろんな記事がある感じ。


# その他
QiitaにもARKitのAdvent Calendarがありました。
https://qiita.com/advent-calendar/2018/arkit
pixi.jsのイベントを無理やり代入して動かす

この記事は [@HibikineCode 1人 Advent Calendar 2018](https://qiita.com/advent-calendar/2018/hibikinekage-front) の3日目の記事です。

ゲームエンジン [pixi.js](http://www.pixijs.com/) にはドキュメント化されていない機能があります。私が知っているうちの1つ、「on コールバック関数を DisplayObject に代入すると動く」について調べてみました。~~pixiをしばきたい人はどうぞ。~~

# pixi.js のイベント

pixi.jsのイベントは、ドキュメント通りには`on`メソッドで登録します。

```js
const sprite = new Sprite();
sprite.interactive = true;
sprite.on('pointerdown', () => console.log('Clicked!');
```

ところが、これでも登録できます。

```js
const sprite = new Sprite();
sprite.interactive = true;
sprite.pointerdown = () => console.log('Clicked!');
```

この場合は当然1つしか登録できませんので、基本的には前者の方法を使うことになります。

この方法は、[React Pixi Fiber](https://github.com/michalochman/react-pixi-fiber)といったライブラリを使う時に効果を発揮します。

```jsx
const HogeSprite = () => (
  <Sprite
    texture={texture}
    interactive
    pointerdown={() => console.log('Clicked!')}
  />
);
```


# 感想

実は v4 以前の機能としてあって、互換で残ってるのかも。
macOS SierraでFireWall設定

某macOS機で稼働するAFPの提供範囲を特定セグメントのみに限定するため、macOS標準のpfを利用して、ホスト側でファイアウォール設定を行った。

pfの有効化

```bash

$ sudo pfctl -e
Password:
No ALTQ support in kernel
ALTQ related functions disabled
pf enabled
```

設定ファイルの変更

```bash
$ sudo vim /etc/pf.conf 
```

 以下を追記

```vim
# AFPをデフォルト拒否
block in proto tcp from any to any port = 548

# 特定セグメントのみ許可
pass in proto tcp from 192.168.20.0/24 to any port = 548
pass in proto tcp from 192.168.0.0/22 to any port = 548
```

設定確認。シンタックスエラーがでなければOK

```bash
$ pfctl -nf /etc/pf.conf 
pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.
```

設定反映

```bash
$ sudo pfctl -f /etc/pf.conf 
pfctl: Use of -f option, could result in flushing of rules
present in the main ruleset added by the system at startup.
See /etc/pf.conf for further details.

No ALTQ support in kernel
ALTQ related functions disabled
```

あとはnmap等で外形を確認。
セキュリティ的には、まずはblock allしてから個々にポートを開けるのが、多分正しい。
EC2でFlaskアプリを立ち上げる

# はじめに
素人がEC2上でFlaskアプリを立ち上げた時のメモです。
いろいろツッコミどころあるかと思いますが、起動はできるはずです。

厳密にはこの他にAWS側のポートの開放などをやる必要がありますが、それらは省略します。

以下すべてsudoで実行しているのは`port=80`でFlaskアプリを起動しようとすると`permisson denied`になるためです。
もっといい方法はあると思います…

# 環境
インスタンスタイプ: t2.micro
OS: Amazon Linux AMI release 2018.03

# pyenvの導入

まずはyumを最新のものにしておきます

```bash
$ sudo yum -y update
```
gitの導入

```bash
$ sudo yum install git -y
```

pyenvをインストールする

```bash
$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv
```

パスを通します

```bash
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile
```

sudoでもuserのパス設定を引き継げるように設定します

```bash
$ sudo visudo
```

以下の様に修正

```bash
- Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
+ # Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
+ Defaults    env_keep += "PATH"
+ Defaults    env_keep += "PYENV_ROOT"
```

pyenvが使えることを確認します

```bash
$ sudo pyenv -v
pyenv 1.2.8-5-gec9fb549
```

# pythonの導入

pythonに必要な依存関係をインストール

```bash
$ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel -y
```

pythonをインストール

```bash
$ sudo pyenv install 3.6.5
$ sudo pyenv global 3.6.5
$ sudo pyenv rehash
```

pythonが使えることを確認

```bash
$ sudo python --version
Python 3.6.5
```

# Flaskの導入

Flaskをインストール

```bash
$ sudo pip install Flask
```

Flaskがインストールされていることを確認

```bash
$ sudo pip freeze
Flask==1.0.2
```

適当な`app.py`を作成します

```python:app.py
#!/usr/bin/env python
# -*- encoding: utf-8 -*-

from flask import Flask

app = Flask(__name__)


@app.route('/')
def hello():
    return 'Hello World!'


if __name__ == '__main__':
    app.run(host='0.0.0.0', port=80, threaded=True)

```

Flaskアプリを起動

```bash
$ sudo python app.py
```

これで完了です。
[ここ](https://qiita.com/tisk_jdb/items/01bd6ef9209acc3a275f)と[ここ](http://u-kan.hatenadiary.jp/entry/linux-pyenv)を参考にしました。
# おまけ

Flaskアプリを起動するときに

```bash
$ sudo nohup python app.py >> 20181203.txt &
```

みたいにやることでSSHから抜けてもプログラムが終了せず、`20181203.txt`に標準出力が書き出され、ログとしても使えます。

終了したいときは以下のように実行中のプログラムを確認し

```bash
$ ps aux | grep python
root      8216  0.0  0.4 188408  4680 ?        S    10:17   0:00 sudo nohup python app.py
root      8217  0.0  2.8 317804 29060 ?        S    10:17   0:00 python app.py
ec2-user  8540  0.0  0.2 110528  2200 pts/1    S+   10:52   0:00 grep --color=auto python
```

プロセスを終了させます

```bash
$ sudo kill 8217
```

以上です。
【DataDog】forecast functionで二つのグラフを統合できない！！！！【The requested query is invalid.】

#【事象】
Notebook機能を使って、レポート作成をしていた際、ホストのリソースの回帰分析をしようとしたら記述がうまくいかず大変だった。

例えば～、2つのグラフ線を合計して、cpuの使用率をforecast関数で回帰分析しようとしたりした。
・system.cpu.system 
・system.cpu.user
しかし、公式の書き方をしても叱られる!!!!!!!!!!!!!!!!!!!!

**forecast**
 https://docs.datadoghq.com/monitors/monitor_types/forecasts/


```
クエリパターン1
max:system.cpu.idle{env:env,host:hostname} as a
forecast(100 - a ,'linear',1)  
```
```
クエリパターン2
forecast(max:system.mem.total{env:prod,host:hostname}, 'linear', 1) as a
forecast(max:system.mem.used{env:prod,host:hostname}, 'linear', 1) as b
forecast( a + b ,'linear',1)  
```

**DataDog様から頂いたお叱り**
message 
「<font color="OrangeRed">The requested query is invalid.</font>」


#【解決】
計算式を記述する際、forecast関数を先に適用すると、aとbのクエリの値が自動的に検出されないご様子。
先に 足し算(a+b)を書いてから、エイリアスを隠し、forecast関数を書けば無事解決しました。
NoteBook機能は、Dashboard機能と違って、Terraform向けのAPIもまだないみたいで、今はまだ手動作成みたいですね～。


###流れ
コンプラ的にスクショはあげられないのですが、記述の流れも書いておきます。
ざっくりQuery[A][B]を作成した際、Forumulaで計算式を記述したら、Query[A][B]をhideして、forecast関数を記述するようにして下さい。
1.Query[A][B]を記述
2.Formulaにて計算式を記述
　例：(A - B)
3.Query[A][B]をHide
4.forecast関数を適用
　例：forecast(A - B,'linear',1)
　→1本の線グラフ(linear)にまとめる場合。

>Datadog Provider
 https://www.terraform.io/docs/providers/datadog/index.html
 TerraformがNotebook機能にも使える日が来たらめっちゃ楽になるんだけど。。。
ヒアドキュメント

#ヒアドキュメントとは
ヒアドキュメントというのは、PHPで長文テキストを記述するのに使われるもの。

<<<演算子を使い、リスト内に記述されたテキストをまとめて変数などに代入することができる。


```例.
$html = <<<EOF
<html>
<head>
<title>Hello</title>
<style>
body {font-size:16px; color:#999;}
h1 {font-size:100px; text-align:right; color:#eee; margin:-40px 0px -50px 0px; }
</style>
</head>
<body>
 <h1>Hello</h1>
 <p>This is sample page.</p>
</body>
</html>
EOF;

Route::get('hello',function () use ($html){
  return $html;
});
```

<img width="1440" alt="スクリーンショット 2018-12-03 20.04.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/300596/428432a4-d05f-5e7a-be90-a380bd1f4294.png">

**こんな感じで使うことができる！！**

ちなみにドキュメントとは資料のことらしい！！笑笑

[こちら](https://wa3.i-3-i.info/word11505.html)を参照にしました。

---


また、この記事は[PHPフレームワークLaravel入門](https://www.amazon.co.jp/dp/4798052582/ref=asc_df_47980525822542427/?tag=jpgo-22&creative=9303&creativeASIN=4798052582&linkCode=df0&hvadid=295678107984&hvpos=1o2&hvnetw=g&hvrand=15604873734545540909&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1028850&hvtargid=pla-526985037105&th=1&psc=1)のアウトプットとして書いてみました。

**自分がまだ理解していない部分を文字で起こすことによって頭の中を整理する**ことが目的です。

てゆうかルーティング設定しなくてもそのままウェブに返すことできるんだね！！

終
Mobile VisionAPIでの利用方法でみてみる、デザインパターンの実装例

# はじめに

自分が勉強し、Androidなど実務でやって、とてもためになったデザインパターンについて書こうと思います。

# デザインパターンについて

まずデザインパターンとは、`オブジェクト指向における、よく利用される設計のパターン` になります。
設計パターンというと少し難しそうですが、僕は　`クラス同士の協調関係などでよく利用される作り方をパターン化したもの` と捉えています。
GoFが有名で、デザインパターンでググるとたくさん出てきますが、ここでは実際にデザインパターンが使われているAndroidのライブラリをみてみます。具体例を見ることでよりデザインパターンの理解が深まるはず。。！
デザインパターンの一つであるFactory Methodパターンが利用されている、Mobile VisionAPIを見ていきます。

# 事前の知識

- クラス図とオブジェクト指向についての知識が必要です。ただし、ゴリゴリのそんなに深い知識はいりません。スーパークラスとそのサブクラス（継承）なんかがわかっていればおKだと思います。

# Mobile VisionAPIについて

ざざっとこのAPIの説明をすると、
顔や、テキスト、バーコード検出用のAPIになります。
バーコードリーダーの実装はとても便利です。Zxingというライブラリも有名ですが、こちらは同時に複数検出できるという利点があります。
(今はMLKitに取り込まれているようです。)

[Mobile Vision](https://developers.google.com/vision/?hl=JA)

# 利用例

ここのドキュメントを見ていきます。
顔やバーコードを認識し、トラッキングしてカメラのプレビュー画面に表示するようなことができます。

[Track Faces and Barcodes](https://developers.google.com/vision/android/multi-tracker-tutorial?hl=JA)

googleのサンプル例が公開されており、実際にビルドしてみるとこのように認識することができます。

![Screenshot_20181203-181140.png](https://qiita-image-store.s3.amazonaws.com/0/96747/63bca5cb-14c1-4e4e-ef33-8c661e2b28f3.png)


# 実装の流れ

![alt](https://developers.google.com/vision/images/barcode-multiprocessor.png?hl=JA)

上記のドキュメントにある、この図にも書いていますが、簡単に流れを説明します。

AndroidのCameraAPIからimageが流れてきたものを、（ここは図には書いてないが、そうなっている。コマ撮りが次々送られてくる感じ）
BarcodeDetectorがBarcodeを認識するごとに、MultiProcessorに渡され、
MultiProcessorがBarcodeTrackerFactoryクラスを利用し、それぞれの読み取った項目ごとにBarcodeGraphicTrackerを作るという流れになっています。
作成されたBarcodeGraphicTrackerが、この読み取ったQRコードのライフサイクルを管理してくれます。

# 出てくるデザインパターンの考察

上記は具体的なクラス間についての説明になっていますが、スーパークラスとサブクラスの関係は次のようになっています。
ここで、必要のないフィールドやメソッドは省略しています。

![Untitled Diagram (2).png](https://qiita-image-store.s3.amazonaws.com/0/96747/031824de-f344-de48-2ad7-3039767166f9.png)

スーパークラスの関係(Framework部分)を見ると、MultiProcessor.Factoryクラス(インターフェース)がcreate()メソッドによって、Trackerクラスを作成しています。
ここで、create()は抽象的なメソッドで記述され、Itemが渡されたらそこからTrackerクラスを作ることがわかります。
**newを使った具体的なクラス名によるインスタンスを持つことなく**、インスタンス化する抽象的なcreate()メソッドのみを提供しています。create()は抽象的なメソッドで、サブクラスで肉付け(実装される)ことを期待しています。

このスーパークラス同士の関係性の`枠組み`を与えることにより、「Trackerのサブクラス（BarcordeTrackerやFaceTracker）を作るよ。」という、ある程度の強制力をもたせることができています。どんな具体的なTracker(顔やバーコードと認識した物体を追跡するクラスなど)でもこの枠組みを再利用することでインスタンスを作ることができます。まるで製品を作る工場のパイプラインを設計しているようなのでFactory Methodパターンと呼ばれています。

このFactory Methodパターンを知っているか知っていないかでドキュメントやサンプルの読み方も変わってきます。

Factory Methodパターンを知っている人は、

- 「ああ、あるクラスのインスタンスの作り方を規定してるのね。」
- 「具体的なクラスは何を作ってるんだろう。複数の具体的なFactoryが作れるはずだ」
- 「BarcodeTrackerFacotryっていうサブクラスが出てきたけど、スーパークラスをみることでどんなクラスを作るFactoryなのかわかるはずだ。」

といったことが予想できます。

## まとめ

その他、SingltonやBuilderパターンといったものは本当によく出てくるので、知っているだけでドキュメントの読み方や、コードの読み方が変わりますので、覚えておいて損はないと思います。

## 参考

[増補改訂版Java言語で学ぶデザインパターン入門 結城 浩 著](http://amzn.asia/d/bVAdWDO)
OpenShadingLanguage 1.9 の testrender をビルドする

OpenShadingLanguage には `testrender` という OSL のテスト用のレンダラがありますのでこれを使えるようにします.

# 環境

* Ubuntu 16.04
* OpenShadingLanguage 1.9.3
* LLVM 7.0

## OpenImageIO のビルド

boost などは apt で入るのが使えますが, 依存している OpenImageIO は apt で入るのでは古いのでソースからビルドしておきます.

デフォルトではいろいろなライブラリをリンクしようとするので, いろいろ off にしておくとよいです(e.g. OpenCV など). 最低限, apt で入る libtiff と libpng と OpenEXR でビルドできるはずです

ビルドできたらインストールしておきます.

## OpenShadingLanguage のビルド

`make help` には OpenImageIO の設定方法が書いていないので迷うかもしれません.
OpenImageIO は OPENIMAGEIOHOME 環境変数で指定します(Make の引数だと cmake に渡してくれない)

LLVM をインストールしておきます.  http://releases.llvm.org/download.html#7.0.0 のプレビルドパッケージでいけるはずです.

プレビルドや, LLVM の src からのビルドのデフォルトでは `.a` 形式なので, `LLVM_STATIC=1` を指定します.
(そうしないと `LLVM_LIBRARIES` が見つからないというエラーがでる)

`LLVM_DIRECTORY` で LLVM のパスを指定して make します(内部で cmake が呼ばれてビルドが走る)

`OSL_BUILD_TESTS=1`(デフォルト) で `testrender` がビルドされるように設定しておきます.
 　
```
export OPENIMAGEIOHOME=/path/to/oiio
make LLVM_DIRECTORY=/path/to/llvm LLVM_STATIC=1 OSL_BUILD_TESTS=1
```

### 注意

make ベースでは `build` ディレクトリを削除しないため, 設定を変えたら build  を消すのをわすれずに. そうしないと cmake のキャッシュが残ってうまく cmake configure が走りません.

## インストール

```
make install
```

デフォルトでは `dist` にインストールされます. インストールをせずに `oslc` を使おうとすると stdlib.h が見つからないなどのエラーがでます.
 
## testrender を動かす.

`testsuite` ディレクトリにいろいろシーンがあるので適当なのを選びます.

まず, oslc で osl シェーダをコンパイル(.oso が生成される)しておきます.

その後,

```
$ testrender input.xml output.exr
```

でレンダリングが走ります. `ref` にあるリファレンス画像と同じものが生成されたら成功です.

## note

OpenShadingLanguage 2.0 からは OPENIMAGEIOHOME の変数名が変わっていたりするので注意です.
LaravelでChart.jsが描画されない

# LaravelのBlade内に記述したChart.jsが表示されない

**実行環境はPaizaCloudです。**

**Chart.js**
https://misc.0o0o.org/chartjs-doc-ja/

以下はChart.jsのトップにあるサンプルのコピーです。
しかし、これをLaravelのblade.phpに追記しても正しく表示されません（真っ白）。

```sample.js
<canvas id="myChart" width="400" height="400"></canvas>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        labels: ["赤", "青", "黄色", "緑", "紫", "橙"],
        datasets: [{
            label: '得票数',
            data: [12, 19, 3, 5, 2, 3],
            backgroundColor: [
                'rgba(255, 99, 132, 0.2)',
                'rgba(54, 162, 235, 0.2)',
                'rgba(255, 206, 86, 0.2)',
                'rgba(75, 192, 192, 0.2)',
                'rgba(153, 102, 255, 0.2)',
                'rgba(255, 159, 64, 0.2)'
            ],
            borderColor: [
                'rgba(255,99,132,1)',
                'rgba(54, 162, 235, 1)',
                'rgba(255, 206, 86, 1)',
                'rgba(75, 192, 192, 1)',
                'rgba(153, 102, 255, 1)',
                'rgba(255, 159, 64, 1)'
            ],
            borderWidth: 1
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true
                }
            }]
        }
    }
});
</script>
```

##描画タイミングをずらす
Vue.jsというのが最初から入っていて、それがChart.jsの動作を阻害している模様。
一番最後にCanvasの描画を持って来れば解決する。

```sample.js
window.onload = function() {
　　　　　/* ここに先ほどのサンプルを記入する */
}
```

注意：この手法は2つ以上の場所でやると片方（あとで書いた方）しか表示しなくなる。
**2つ以上記入する時は1つのwindow.onload = function()の中に2つの描画処理をいれること。**

##


#参考
**Vue.jsでChart.js使ったらはまった（グラフが出ない）：解決済み**
https://qiita.com/to4king/items/48c74b26603227b85377
ゲームプラットフォームQAの極意　~Part.1 ゲームアプリQAとの差異~

# 前置き
この頁はゲームプラットフォームQAの特徴について記載していく。
対象としては**長期運用**しているプラットフォームであり、新規開発の際のQAでないことは念頭に置いていただきたい。

# ゲームアプリQAとの差異
Part1はゲームアプリQAとの差異について記載する。
両者QAを比較した際に大きく差異の出る要素は下記の2つが挙げられる。
それぞれについて詳細を記載していく。

 - **テストスケジュール**
 - **外的要因**

### テストスケジュール
##### ゲームアプリの場合
例えば月の初めにイベントが発生する、月末にキャンペーンを行うなど
多くのゲームアプリの場合は施策がひと月の周期で実施される場合が多い。
QAもそれら定常の施策への対応がベースとなるため**毎月類似した検証が発生することになる。**

##### ゲームプラットフォームの場合
ゲームプラットフォームの場合、ゲームアプリと異なり毎月イベントやキャンペーンを行うというケースは稀である。
その代わり季節に合わせた大規模キャンペーンなど**施策のサイクルが年単位になる場合が多い。**

### 外的要因
##### ゲームアプリの場合
ゲームアプリが受ける外的要因としては主に**そのアプリが載っているプラットフォームの動向が挙げられる。**
例えばプラットフォームの規約が変更になればその対応が必要になるだろうし
アプリが搭載される機器(スマートフォンやPCなど)に関する新たな技術が登場した場合
アプリ上でその技術を活用した場合のテストを行うことになる。

##### ゲームプラットフォームの場合
ではゲームプラットフォームの場合はどのようなものが外的要因になるか。
上記のスマートフォンやPCなどを含めたプラットフォームの動向はもちろん
ゲームプラットフォームの場合は**各国の法律の動向**にゲームアプリ以上に強く影響を受ける。
特に顕著なのは消費税変更で、ゲームアプリQAの場合はプラットフォームとのつなぎ込み部分のみを確認するのに対し
ゲームプラットフォームQAの場合はPaymentの全機能テストが発生することになる。

# まとめ
ゲームプラットフォームQAはゲームアプリQAと異なり
**毎月同じQAが走ることはなく、ゲームアプリQAとは異なる外的要因に影響を受ける**
そのため月ごとに異なる施策が発生し時には突発的に大規模な検証が必要になるケースもあるため
ゲームアプリQAよりも管理に工数がかかる場合が多い、というのがゲームプラットフォームQAの特徴である。

Part2ではゲームプラットフォームのQAにおけるイレギュラーテストについて記載する。
ヘルスケアサービスを作る際には医行為に抵触しないよう気をつけよう

皆さんは健康管理にスマートフォンやスマートウォッチを利用していますか？
Apple watch series 4 で心電計(ECG)が実装され、盛り上がったのは記憶に新しいところです。
（日本ではしばらく利用できなさそうですが。。。)
IT×ヘルスケアはウェアラブルデバイスの普及により、世界的に盛り上がりを見せつつあります。

そこで「よっしゃ！ヘルスケアサービス作ろう！」と思ったそこのあなた！ちょっと待って！
医師法に抵触しないように気をつけながらサービスを作らないとダメですよってお話。

# 何があったか
私は普段はiOSアプリ作ってるんですが、ひょんなことから医療事業チームに片足を突っ込んでいます。

Aさん「アプリのプッシュ通知とかで血圧高いよって出しちゃダメなんだよねー」
私「え？！そうなの！」
Aさん「お医者さん以外が診断しちゃあかんのよ」
私「ほー（わかってない）」

# 自分で調べてみた
[医師法](http://www.houko.com/00/01/S23/201.HTM)
> 第一七条　医師でなければ、医業をなしてはならない。

ほうほう。。。医業ってなんぞや :thinking:

[「医行為」について](https://www.mhlw.go.jp/shingi/2003/02/s0203-2g.html)
> 医師法第１７条に規定する「医業」とは、当該行為を行うに当たり、医師の医学的判断及び技術をもってするのでなければ人体に危害を及ぼし、又は危害を及ぼすおそれのある行為（「医行為」）を、反復継続する意思をもって行うことであると解している。

ほうほう。

。
。
。


わからん。
ってことで、なんで違反しそうなのかを医療事業担当者に聞いてみました。

# なぜ？
医師でないモノが「**診断**」をしてはいけません。
診断は医行為と見なされます。

今回の例では「血圧が高いです」=「高血圧症である」と診断をしていると捉えられる可能性があるみたい。

「血圧が高い、低いという基準のガイドラインがあるじゃないか。」と思う人もいると思いますが、
あくまでガイドラインであり、その基準値だけを使って単純に高血圧症であるというのは診断できません。
運動直後に測ったなど、体調の問題で血圧が一時的に高くなる要素はいくらでもあります。

# 最後に
AIが病気を診断するっていう記事はちょいちょい見ますが、
（当たり前ですが）絶対に医師が最終判断をするようにするしかサービスは作れず、
AIが単独で病気を診断することは現状、アウトみたいです。

エンジニアとして技術だけじゃなく、自分の担当領域の知識は常にアップデートしていきたいですね。
（技術ブログっぽくなくなっちゃいましたが、書いちゃったのでとりあえず投稿。）
【備忘録】PostgreSQLでselectした結果をinsertするSQL

いつも忘れてしまうのでメモ。

PostgreSQLで、selectした結果をそのまま他テーブルにinsertする方法のSQL。
いつもの insert 文の後に select 文をくっつけるだけでいい。

というわけでSQLのサンプル。

```sql
insert into 宛先テーブル
(
	column1,
	column2,
	column3
)
select
	column1,
	column2,
	column3
from
	移行元テーブル
where
	column3 >= 100
```