OmniAICreator/Qiita-1.07M huggingface dataset:
macOS Mojaveでbrew updateができない場合の対処

#バージョン
macOS 10.14
#事象
brew updateでエラー

```
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- mach (LoadError)
	from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /usr/local/Library/Homebrew/extend/pathname.rb:2:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /usr/local/Library/Homebrew/global.rb:3:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /usr/local/Library/brew.rb:15:in `<main>'
```
brew doctorすると

```
deleted:    Library/Formula/saltstack.rb
```
みたいなエラーメッセージがいっぱい。


#対処
こちらの記事を参考にさせてもらいました。

[MacOS High SierraでHomebrewの更新(brew update)ができない場合の対処](https://qiita.com/noraworld/items/ce90783994ce2607a5ca)

Homebrewの再インストールで直るとの事。High Sierraの記事でしたが、同様に再インストールしてみました。

```
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```
もう一度brew updateやってみました。

```
$ brew update
Already up-to-date.
```
直りました。
Qiitaにも初投稿完了。
CakePHP3のSearchプラグインでconcat検索するときのNULL対策

CakePHP:3.6
MySQL:5.7

CakePHP3でfriendsofcake/searchを使って文字列結合(concat)の検索を実装します。
usersテーブルにlast_name、first_nameというカラムがあり、検索項目はname(last_name + first_name)を例にしましょう。

usersテーブルはこのようになっています。
id:3のfirst_nameがNULLのレコードが今回のポイントです。

| id  | last_name | first_name |
|----:|----------:|-----------:|
| 1   |      田中 |     一郎   |
| 2   |      山田 |      太郎  |
| 3   |      田中 |    NULL    |


nameに「田中一郎」と入力してid:1が取得できれば成功です。
実装はcallbackでconcatを利用することで実現できます。

```/src/Template/Users/index.ctp
<?= $this->Form->create(null); ?>
<?= $this->Form->control('name') ?>
<?= $this->Form->submit('検索') ?>
<?= $this->Form->end(); ?>
```
```php:/src/Model/Table/UsersTable.php
$searchManager
->add('name', 'Search.Callback', [
	'callback' => function ($query, $args, $manager) {
		return $query->where(function ($exp, $query) use ($args) {
			$name = $query->func()->concat([
				'last_name' => 'identifier',
				'first_name' => 'identifier'
			]);
			return $exp->like($name, '%' . $args['name'] . '%');
		});
	},
]);
```
しかしこの方法では「田中」と入力したときにid:3のデータは検索に引っかかりません。
理由はMySQLではconcatしたときに片方のフィールドがNULLだと、もう一方の値にかかわらずNULLが返ってくる仕様のためです。

これを回避するにはIFNULL()が使えます。
[[MySQL]nullを含むフィールドのconcat](https://happyquality.com/2009/03/16/877.htm)

CakePHP3のfriendsofcake/searchではこのように書けばOKです。
id:3のデータもちゃんと拾ってくれます。

```php:/src/Model/Table/UsersTable.php
$searchManager
->add('name', 'Search.Callback', [
	'callback' => function ($query, $args, $manager) {
		return $query->where(function ($exp, $query) use ($args) {
			$name = $query->func()->concat([
				'IFNULL(last_name, "")' => 'identifier',
				'IFNULL(first_name, "")' => 'identifier'
			]);
			return $exp->like($name, '%' . $args['name'] . '%');
		});
	},
]);
```
自己紹介と2018年コミュニティ活動まとめ

#自己紹介
ソフトウェア開発販売しているウイングアーク１ｓｔという会社のオオカワです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/178685/f13c0eed-4568-0332-00a7-7b1cd23a7415.png)

弊社、最近では[BIクラウドサービス](http://www.wingarc.com/product/motionboard/scene/iot.html)とか[文書管理＋OCR](http://www.wingarc.com/product/spa/)で注目されている会社です。

そんな会社でデジタルトランスフォーメーションについての情報発信など、いわゆる「エヴァンジェリスト活動」を行っています。肩書はConnected Industriesエヴァンジェリストと言っています。今年は各地商工会議所を中心に約50回、会社と関係ないところで講演を行いました。

また、兼務として以下の役職もやってます。

- [明治大学サービス創新研究所](http://service-innovating.jp/)　客員研究員
- [東京商工会議所「スマートものづくり推進事業」専門家ワーキンググループ](https://www.tokyo-cci.or.jp/page.jsp?id=115010)　座長
- 栃木県「IoT等専門家派遣事業」専門家
- 日本商工会議所「[中小企業活力増強のためのITサービス・レシピ](https://www.jcci.or.jp/news/jcci-news/2018/0420173743.html)」監修者
- ロボット革命イニシアチブ協議会「[スマートものづくり応援ツール・レシピ](https://www.jmfrri.gr.jp/event/seminar/618/694.html)」審査員

さらに、以下のコミュニティの主催もしています。今年は合計14回イベント実施して延べ1800名の方にお越し頂きました。

| コミュニティ名 | 2018年開催数 | 述べ参加者数 |
|:-----------------|------------------:|------------------:|
| ヘルスケアIoTLT | 2回 | 606名 |
| エンタープライズIoTLT | 4回 | 505名 |
| M5Stack User Group Japan<br>（共同主催） | 3回<br>(UserMeetingのみ) | 388名 |
| D Empowerment Lab | 5回 | 323名 |

年々、本当に何が仕事なのか分からなくなってきましたが、来年も頑張るよ！
色々なシェルたち

homebrewとか漁ってて見つけたシェルたちをのっけていきます。
説明とか雑なのは実際に使ってないからだと思います。
名前の記録といった面が高いため、気になったのがあれば探していただけると楽しいと思います〜

---

# メジャーどころ

## sh

言わずと知れたPOSIX SHELL. いろんなシェルの元となっているのでは...??
~~大抵bashとかにlnされてしまっているかわいそうな子なイメージしかない~~

## bash

BASHHHH!!! `Born Again shell`の略称ですね。
私のメインのシェルです。
今やほとんどのOSで標準のシェルになっていると思われます。(例外もあります)


## zsh

bashの強強版...とよく言われるのですが、元はtcsh派生のようです。
あんまり知らない

## csh

C言語の構文で書けるようにしたシェル。bashが出る前は結構人気だったらしい

## tcsh

cshの拡張版？

## ash

名前しか知らない

## dash

ash派生。名前しか知らない


## fish

~~なぜかすっかり忘れていた。~~ @gorilla0513 さんありがとうございます。
どうやらPOSIX非互換らしい (source: [hennin/fish shellが結構良かった話](https://qiita.com/hennin/items/33758226a0de8c963ddf))
しかし`Friendly interactive shell`とのことで使いやすいらしい。
実際公式ページ見にいったら使いやすそうだった。

* [fish](https://fishshell.com/)

# ksh

KornShell

# 言語・環境系

言語や環境/特定のソフトに特化して作られたシェルたちです。

## xonsh

Python用のシェル。

## xmlsh

xml用のシェルだとか...ようわからん...

* [xmlsh/xmlsh1_3](https://github.com/xmlsh/xmlsh1_3)

## metashell

メタ言語用のシェルらしい。
C++とかできるらしい。
うん。
楽しそう。

* [metashell/metashell](https://github.com/metashell/metashell)

## maven-shell

Javaのプロジェクト管理ツール`maven`用のシェル環境

* [jdillon/mvnsh](https://github.com/jdillon/mvnsh)

## tasksh

> Shell wrapper for Taskwarrior commands

Taskwarrior用のラッパーシェルらしい
Taskwarriorってなんなんだろ...

* [tasksh](https://tasktools.org/projects/tasksh.html)

## git-sh

gitコマンドを容易に扱うためのシェル

> Customized Bash environment for git work

* [rtomayko/git-sh]https://github.com/rtomayko/git-sh

# ssh系

sshログイン時等に使えるシェルたち

## ssh

まぁ基本中の基本、ssh。


## mosh



# その他

その他な感じのシェルたち。場合によったら再分類します。

## fizsh

zshのfishライクなフロントエンド。（らしい）
実質的にはzshということなのでこれはシェルとして分類していいのか悩んだけど面白いので。

* [zsh-users/fizsh](https://github.com/zsh-users/fizsh)

## elvish

>Friendly and expressive shell


* [elves/elvish](https://github.com/elves/elvish)

## etsh

> Two ports of /bin/sh from V6 UNIX (circa 1975)


バージョン6のUNIXの時点のshの派生らしい。
少しそこから拡張されている(enhanced)ようですね

* [etsh](https://etsh.io/)

## mksh

~~なんかシェル作れそうな名前~~

MirBSD用のKorn Shellらしいです。

* [mksh](https://www.mirbsd.org/mksh.htm)


## posh

> Policy-compliant ordinary shell


* [clint/posh(debian)](https://salsa.debian.org/clint/posh)

## yash

> Yet another shell: a POSIX-compliant command-line shell

お、ページ見にいったら日本語で書かれている...

* [yash](https://yash.osdn.jp/)


## dsh

> Dancer's shell, or distributed shell

どうやらリモート管理系(つまりsshの類)らしい...??
あまりわからないのでとりあえずその他に放り込んでおきます

* [dsh](https://www.netfort.gr.jp/~dancer/software/dsh.html.en)


## rush

> GNU's Restricted User SHell

ネットワーク経由でアクセスしたユーザーに制限をかけたりするシェルらしいですがこれもよくわからん(読んでないだけ)

* [rush](https://www.gnu.org/software/rush/)
DevOps 用のツール一覧を 元素記号風に・・・

# DevOps のツール一覧を元素記号風に・・・

ちょっと息抜き的にｗ
DevOpsのツールを面白いまとめ方してたとこがあったので、ご紹介したいと思います。

## PERIODIC TABLE OF DEVOPS TOOLS(V3)

なかなか、かっこよくまとまってますね。

![Periodic Table of DevOps Tools.png](https://qiita-image-store.s3.amazonaws.com/0/318450/656f952f-b252-a718-5bf9-993604baebf5.png)

区分けもきれいになっています。
初めて見たのですが、V3ってことは以前から作成してたんでしょうね。

## まとめ

正直、DevOps のツールってありすぎだろうと思います。
どれ使えばいいのとか、迷いどころですよね。
そして、こういうツールって、結構生存競争激しいです。
来年は消えてるとか結構ありそうで、怖いです。。。

ちなみにテスト導入してた監視ツールは、半年くらいしたら、会社のサイトが消えてました・・・

## 参照

[PERIODIC TABLE OF DEVOPS TOOLS](https://xebialabs.com/periodic-table-of-devops-tools/)
PostgreSQLにおけるUNIQUEとUNIQUE INDEX

## UNIQUEとUNIQUE INDEXの違い

UNIQUEは制約とインデックスが作成されるが,UNIQUE INDEXはインデックスのみ作成される。

##確認
以下は、双方確認できる。

```sql:pg_indexes.sql
select * from pg_indexes
```

以下、は制約のみ

```sql:table_constraints.sql
SELECT a1.*                                     
FROM   information_schema.table_constraints a1                
where a1.constraint_type   in ('PRIMARY KEY' , 'UNIQUE')    
```
SQLを実行してもらえればわかるが、インデックスのみの場合、カラムの指定順がCREATE文の形式になっており、
メタ情報として取り扱いにくい、そこで、カラムごと、順序ごと取得する。



```sql:qiita.sql
select  a2.nspname  as namespase
       ,a4.relname  as table_name
       ,a1.relname  as index_name
       ,a5.attname  as column_name
       ,position( cast(a5.attnum as text) in replace(cast (a3.indkey as text) ,' ','')) as index_position --インデックスの定義順特定
from   pg_class     a1
      ,pg_namespace a2
      ,pg_index     a3
      ,pg_class     a4
      ,pg_attribute a5
where  a1.relkind      = 'i'            --インデックスのみ取得
and    a1.relnamespace = a2.oid         --スキーマ（namespase）特定用
and    a1.oid          = a3.indexrelid  --インデックスの情報取得
and    a3.indrelid     = a4.oid         --インデックスが登録されているテーブルの名前特定用
and    a5.attnum       = any(a3.indkey) -- インデックスのカラム特定
and    a5.attrelid     = a3.indrelid
order  by namespase
         ,table_name
         ,index_name
         ,index_position -- インデックスの定義順でソート
```
初心者がパソコン甲子園(プログラミング部門)に出場してみた


# はじめに
この記事は[N高等学校 Advent Calendar 2018 ](https://qiita.com/advent-calendar/2018/n-highschool) 9日目の記事です。
今年の3月から本格的に競プロを始めたN高3年です。
今秋、[パソコン甲子園　プログラミング部門](https://web-ext.u-aizu.ac.jp/pc-concours/2018/programming/index.html)に出場したのでそこで思ったことをまとめます。

# 出場前の不安
学校側から出場生徒募集のお知らせが来て参加を申し込んで、ペアの相手が決まったのですが、

- 一度もリアルで会ったことがない人
- 相方と実装能力が大きく違う

という2点で「自分がいても何の役にも立たないんじゃないか」と思っていました。

#予選本番
実際の予選での私のチームの方針は以下の通りでした。

- 実装は相方に任せる 
- 自分は問題の考察など補助的な作業に回る

実際に解いた結果、

- 細かいミスの発見
- 問題を図表化して考えやすくした

というような形で少しですが得点に貢献することができました。


# 予選を終えて
自分はコードを一行も書きませんでしたが、
終了後、相方から「助かりました」と言われて「貢献した」という実感がわきました。
これからは自分の実装能力を鍛える方向に進もうと思います。
二分法の数理

## はじめに

この記事では**二分法**を扱います。数値計算では良く知られた手法で、簡単に実装できるため教科書でも最初の方に出てくるものでしょう。その解説をします。

## 適用対象

二分法の適用対象は、非線形実数値連続関数です。次の問題を考えます。

区間$I$上で定義された連続関数$f:I \to \mathbb{R}$に関して、$f(c) = 0, c \in I$となる$a$を計算することを考えます。

もちろん一般にこの式は成り立ちません。例えば、 $f(x) = x^2 + 1$としたら実数区間の中でどのように$I$をとっても$f(c) = 0$となることはないでしょう。
逆に$I$の取り方次第では、たくさんあることもあります。例えば、 $f(x) = \cos x$とかなら$f(c) = 0$となる$c$はたくさんありますよね。

## 中間値の定理

二分法の数学的基礎は中間値の定理です。杉浦[^1]の第１章 実数と連続 §8 中間値の定理によれば

> 定理8.1(中間値の定理) $\mathbb{R}$の有界閉区間 $I = [a, b]$で連続な実数値関数$f$は、 $f(a)$と$f(b)$の間の任意の実数$\gamma$を値にとる：$f(c) = \gamma$となる$c \in I$が存在する。
> 定理8.1系１　 $f: I = [a, b] \to \mathbb{R}$が連続で、$f(a) < 0,\ f(b) > 0$(または、$f(a) > 0,\ f(b) < 0$)ならば、$f(c) = 0$となる$c \in I$が存在する。

系1はまさに解きたい問題ですよね。つまり「区間が定義されていて、その端の符号が異なっている」というのが二分法の適用条件です。実は二分法はこの証明そのものといった感じです。次の節で証明します。

## 中間値の定理の証明

定理8.1で $\tilde{f}(x) = f(x) - \gamma$とすれば、系１の仮定を満たすから、系１を証明すれば良い。
ここで$f(a) < 0 < f(b)$としても一般性を失わない。 ここで系列$a_n, b_n, n\in\mathbb{N}$を$a_0 = a, b_0 = b,c_n = \frac{a_n + b_n}{2}$とした時に、

```math
a_{n+1} = a_n, b_{n+1} = c_n\ {\rm if}\ f(c_n) > 0\\
a_{n+1} = c_n, b_{n+1} = b_n\ {\rm otherwise}
```
と定義し、区間$I_n$を$I_n = [a_n, b_n]$で定義する。この時、区間の系列$I_n$は有界閉区間の単調減少列で、その長さは$\frac{b - a}{2^n}$なので$0$に収束する。故に、区間縮小法より$I_n \to \\{c\\}, a_n \to c, b_n \to c$となる。一方、全ての$n$に対して、

```math
f(a_n) \leq 0 \leq f(b_n)
```
が成り立つ。$n=0$の時には仮定から、$f(a_0) < 0 < f(b_0)$であり、系列の構成法から、

```math
f(a_{n+1}) = f(a_n) \leq 0 \leq f(b_{n+1}) = f(c_n)\ {\rm if}\ f(c_n) > 0\\
f(a_{n+1}) = f(c_n) \leq 0 \leq f(b_{n+1}) = f(b_n)\ {\rm otherwise}
```
が成り立つため、帰納法から証明できる。ここで$f$は連続であったから、$f(c) \leq 0 \leq f(c)$より$f(c) = 0$である。
## 解いてみる

さて、せっかくなのでコードを書いて実際に問題を解いてみましょう。今回のコードはpythonで書きました。

```python
def bs_method(f, start, end, N=100):
    if f(start) * f(end) >= 0:
        raise Exception('not satisfying the solvable condition.')
    # 初期化
    a, b = start, end
    s_fa = f(a) > 0
    # 以下をN回(初期値100)繰り返す
    for _ in range(N):
        # 中間の値の取得
        med = (a + b) / 2
        f_med = f(med)
        # もし中間の値が解ならそれを返す
        if f_med == 0:
            return med
        else:
            s_fmed = f_med > 0
        # 符号が同じ方を交換する
        if s_fmed == s_fa:
            a = med
        else:
            b = med
    return med
```

```python
bs_method(lambda x: 2 *  x * x  - 1, 0, 5) ==> 0.7071067811865475
```

このように二分法では繰り返しの回数を指定する必要があります。
この回数は精度に依存します。また、最初に与えた区間の大きさも制度に依存します。
$k$回の繰り返しをしたとして、精度はおおよそ$(b - a)/2^k$になります。
必要な精度で使うと良いです。

## おまけ

さらに微分が計算できる場合、ニュートン法という方法があります。
こちらは収束が基本的には良いですが、解の周りが平らに近い場合、数値が発散しやすいという特徴を持っています。
個人的には、２階微分があり、convexかconcaveかがわかっているならニュートン法やその改良法、そうでないなら二分法という使い分けをします。



[^1]: 杉浦光夫　著, 「解析入門I」 東京大学出版会, 1980
CEDEC+KYUSYU2018行ってきました

# 概要
* 福岡のCEDEC
* 参加したセッション
* 感想

# 福岡のセッション
* 12/1に福岡の「[CEDEC+KYUSYU2018](http://cedec-kyushu.jp/2018/)」に参加してきました。<br>東京のCEDECには毎年参加していたのですが、九州でしか聞くことのできない<br>セッションに興味があり、一泊二日で参加してきました。

# 参加したセッション
* 基調講演 ドラゴンクエスト32年の歩み<br>ドラゴンクエストの生みの親堀井雄二さんと、レベルファイブの日野社長の<br>対談形式でドラゴンクエストの歴史を振り返っていました。
* R&Dことはじめ~ゼロから始める研究開発~<br>ディライトワークスの研究開発部の方の講演です。<br>5年先の技術をメインに研究するということです。<br>詳しくは採用ページに研究内容が書かれているようです。
* UE4のエディター改造！汎用エンジンを自社プロジェクトに最適化<br>サイバーコネクトツーのツールプログラマの方の講演でした。<br>UE4のC++でどのクラスを継承すれば、エディタを拡張していけるか<br>という内容でした。
* 内製レンダリングエンジンにおける採用技術と最適化手法<br>ガンバリオンの社内ライブラリで作られた描画エンジンの紹介でした。<br>東京のCEDECではUE4を使用したアプリの講演でしたが、<br>今回はゲームエンジンに頼らないゲーム開発もしているようです。
* トキメキとは何か　乙女を恋へと導く新たなアプローチ<br>ヘキサドライブが開発した「MakeS おはよう、私のセイ」の<br>開発コンセプトのお話でした。
* .hack//G.U. Last Recode HDリマスターの軌跡<br>PS2からPS4へ移植された「.hack//G.U」がどのような目的を持って開発が行われ、<br>どのような問題が発生したのか講演されていました。

# 感想
* 福岡のセッションは1日間だけでしたが、聞き応えのある十分な内容でした。<br>参加費も東京のCEDECと比べて大分お安いので興味のある方は<br>参加してみてはいかがでしょうか？
ECSのネットワークモード、awsvpcでハマってしまった話

[クラシコムアドベントカレンダー](https://qiita.com/advent-calendar/2018/kurashicom)7日目は @ryosukes です。

最近、検証用のWebアプリをAWSが提供しているコンテナオーケストレーションサービスであるECSを使い構築しました。

そのときに、ECSのネットワークモードとしてコンテナ用に用意されている `awsvpc` を選択したのですが、`curl` がコンテナ上から行えず少しハマってしまいました。

# TL;DR

- ネットワークモードで `awsvpc` を使う場合はプライベートサブネットを使いましょう

# 何が起きていたのか

Webアプリを起動した段階では、ブラウザでURLを叩くとレスポンスが返ってくる状態になっていました。しかし、`curl` を使い外部とのやり取りを行うライブラリが実行されると、まったくレスポンスが返ってこないことに気づきます。

このとき、ログからはタイムアウトが起きてることしか読み取れませんでした。そのため、外部のエンドポイントの問題なのか、ネットワークの設定の問題なのか、それとも別の問題なのか判別してから対処する必要がありました。

# 事象調査

判別するのに、ECSのデータプレーンであるEC2上で `curl` コマンドをCLI上で実行。これは問題なかった。

次に、コンテナ内に実際に入ってみて、 `curl` コマンドを実行。このときに、外部のエンドポイントからまったくレスポンスが返ってこないことに気づきます。

このときに、ネットワークの設定の問題だということにあたりがつきます。

# 原因調査

あたりがついたところで、改めてECSのドキュメントを読み直しました。

[Amazon ECS コンテナインスタンスの起動](https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/launch_container_instance.html)

このページの、8.c〜eらへんがどうやら怪しそう・・・。

8.dで、

> [Subnet] で、使用するサブネットを選択するか、アベイラビリティーゾーンであらかじめ選択されるデフォルトのサブネットを使用します

とあります。デフォルトを僕は選択していました。

次。 8.e。ここに書いてある `自動割り当てパブリック IP` ですが、 ブラウザのAWSコンソール上からは `DISABLED` しか選択できない状態になっています。ここだ。きっとこのあたりが原因だ…！

続いて読むと、 **注記** があります。その中にこう書かれています。

> コンテナインスタンスにパブリック IP アドレスがない場合は、NAT (ネットワークアドレス変換) を使用してこのアクセスを提供する必要があります。

こいつだ！

というわけで、プライベートサブネットを使用していなかったのが原因でした。

# 対応

プライベートサブネットを作成するためには、NATゲートウェイとルートテーブルの作成が必要です。

作成は非常に簡単。

1. AWSのコンソール上から、VPCというサービスを選択
2. サブネットを用意(新規・既存どちらでも)
3. Elastic IPを用意(新規・既存どちらでも)
4. NATゲートウェイを新規作成。2, 3で用意したサブネットIDとElastic IPを指定。
5. 今作ったNATゲートウェイをターゲットにしたルートテーブルを作成
6. プライベートサブネット用にサブネットを用意
7. 6のサブネットのルートテーブルを、5で作ったルートテーブルにする

ここで作ったサブネットを使用するようにしたことで、今回のハマりポイントは解消しました。

# まとめ

VPCやサブネットなどネットワークまわりは、AWSを初めて触るときや久しぶりに触るときは少しハマりやすいポイントかもしれません。

僕の場合は、以前VPCやプライベートサブネットに関してまとめたスライドを作ったことがあります。

[VPCのネットワークまわりをもう一度](https://qiita.com/ryosukes/items/9ad289e1d673899fc628)

これを思い出して、すぐ対応することができました。

VPCやサブネットに関してより詳しく知りたいといった場合、AWSのドキュメントがあるので、この辺を読めば理解できるかと思います。

- [VPCとサブネット](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/VPC_Subnets.html)

おさえておきたいところですね。

以上、ECSを利用するときに地味にハマってしまったところでした(ドキュメントはよく読みましょう…)。

明日のアドベントカレンダー、担当は @kim_kou です！
Git で今いるブランチを簡単に探す

# `git rev-parse` を使う

`--abbrev-ref` オプションをつけるとブランチ名を表示できます。

```bash
$ git rev-parse --abbrev-ref HEAD
master
$
```

これで今いるブランチが出せます。

HEAD の代わりに `@` を使うこともできます。

```bash
$ git rev-parse --abbrev-ref @
master
$
```

正攻法はこれだと思います。rev-parse には他にもオプションありますが、これ以上は触れません。

# `git branch` を使う
rev-parse は覚えられません。しかし、 `*` がついていてもよければ `git branch` でもわかります。

## オプションなし
普通に `git branch` でブランチ一覧が見れます。その中から `*` がついているものを目視すれば見つかります。

```bash
$ git branch
  develop
* master
$
```

## `--contains` を使う
特定のコミットが所属するブランチを探す `--contains` を使えば、「現在のコミットの所属するブランチ」に絞り込むことができるので、今いるブランチが分かります。（ただし、今のコミットを含むブランチが複数あるときはあんまり意味ないです。当たり前ですが。）

### `HEAD` を渡す
```bash
$ git branch --contains HEAD
* master
$
```

### 何も渡さない

何も渡さないときは `HEAD` で探してくれるみたいです。

```bash
$ git branch --contains
* master
$
```

### なるべく省略する
git のオプションは、被らない範囲まで省略することができます。

`git branch --contains` の場合には `git branch` に `--color` と `--column` などがあるので、 `--con` まで省略可能です。

```bash
$ git branch --con
* master
$
```
ディレクトリごとにBabelの設定を変える

Babelを運用するに当たって、一部のディレクトリだけ設定を変更することができます。

## 必要になった動機

作っているシステムの中でService Workerを導入しようとしたのですが、Service Worker内では`fetch`だけでなく`cache`も非同期実行となっていて、`Promise`だけで書くのも辛くなって、`async-await`を使いたくなってきました。

本体プログラムはIE11も切り捨てずに作っていたため、`@babel/polyfill`の巨大さが気になって`async-await`を取り入れられずにいたのですが、Service Workerは機能自体がIE11に非対応ですし、本質的に「動かなければそれでいい」と割り切れるものなので、「`async-await`をそのまま出力してしまおう」という考えに至りました。

## 複数の`.babelrc`

ドットファイル系の設定ファイルではよくある話ですが、`.babelrc`でも[ディレクトリごとにファイルを置いて、設定変更が可能です](https://babeljs.io/docs/en/config-files#file-relative-configuration)。Babelのサイトには`node_modules`を挟んだ場合の制約などが書いてありますが、1つのプロジェクト内で設定する分には問題となりません。

## 設定を行う

必要な設定は、

* `async-await`の変換を止める
* （ついでに）Service Workerと`async-await`に対応できるブラウザ向けのコードを吐かせる

の2つです。`@babel/preset-env`で一部のプラグインを`exclude`できるとのことだったので、以下のような設定となりました。

```js:.babelrc
{
  "presets": [
    ["@babel/preset-env", {
      "modules": false,
      // ServiceWorkerとasync-awaitが効く最低限
      "targets": {
        "chrome": "55",
        "firefox": "52",
        "ios": "11.4",
        "edge": "17"
      },
      "exclude": ["transform-regenerator"]
    }]
  ]
}
```

という感じとなりました。なお、途中にコメントが入っていますが、`.babelrc`は[JSON5を取り入れているため、途中にコメントが入っても構いません](https://qiita.com/jkr_2255/items/026e0fdb4570c88c4f51)。

## まとめ

ターゲットが限られる場面では、積極的にターゲットを指定すれば、新しいJavaScriptでコンパクトなコードを生成することができます。
テイラー展開の概略

# はじめに

テイラー展開が分からない、という人の為の記事です。数学的に厳密な話は避けるので、曖昧なところがあります。概略を知りたい人向けです。

# x=0で考える（マクローリン展開）

ある関数$f(x)$を考えます。この関数を

```math
f(x) = a_0x^0 + a_1x_1^1 + a_2x_2^2 + a_3x_3^3 + \cdots = \lim_{n \to \infty}\sum_{k=0}^n a_kx_k^k
```

と表そう、というのが目標です。ここで、目標は決まっているのでとりあえず、上のように$f(x)$を表せると仮定してしまいまい、$a_0, a_1, \cdots$を求める方針でいきます。このとき$a_0, a_1, a_2, \cdots$を$f(x)$で表してみます。すると、

```math
a_0 = \frac{f(0)}{0!} \\
a_1 = \frac{f^{(1)}(0)}{1!} \\
a_2 = \frac{f^{(2)}(0)}{2!} \\
a_3 = \frac{f^{(3)}(0)}{3!} \\
\vdots \\
a_k = \frac{f^{(k)}(0)}{k!} \\
```

と表せます。ただし、$f^{(k)}(x)$は$f(x)$の$k$階微分とします。$f^{(0)}(x) = f(x), f^{(1)}=f'(x), f^{(2)}(x)=f''(x)$ということです。

つまり、

```math
f(x) = f^{(0)}(0) + f^{(1)}(0)x + \frac{f^{(2)}(0)}{2}x^2 + \frac{f^{(3)}(0)}{6}x^3 + \cdots =  \lim_{n\to \infty}\sum_{k=0}^n\frac{f^{(k)}(0)}{k!}x^k
```

と表せます。目標達成です。この$x=0$のときの$k$階微分を用いて$f(x)$を$f(x) = a_0x^0 + a_1x_1^1 + a_2x_2^2 + a_3x_3^3 + \cdots$という多項式で表すことを「マクローリン展開」と呼びます。

# x=aのときで一般化する（テイラー展開）

結論から言うと平行移動すればよいです。

```math
g(x-a) = f(x)
```

という関数を考えれば$f(x)$を$-a$だけ$x$方向に並走移動した関数$g(x)$を得られます。試しに$x=a$を代入してみると$f(a)=g(a-a)=g(0)$となることを確認できます。では$g(x)$をマクローリン展開してみます。

```math
g(x) = \lim_{n \to \infty}\sum_{k=0}^n \frac{g^{(k)}(0)}{k!}x^k
```

となります。ここで、$f(x)=g(x-a)$を代入して

```math
f(x) = g(x-a) = \lim_{n \to \infty}\sum_{k=0}^n \frac{g^{(k)}(0)}{k!}(x-a)^k = \lim_{n \to \infty}\sum_{k=0}^n \frac{f^{(k)}(a)}{k!}(x-a)^k
```

となります。これで$f(x)$の$x=a$まわりでのテイラー展開が得られました。

# 最後に

今回はテイラー展開の概略なのでテイラー展開可能性については論じません。

また、Qiitaの記事の方針的に、これは大丈夫なのかな、という微妙なラインな気がするので、流石にこれは違うだろ、ということであればご指摘お願いします。
php-master-changes 2018-12-05

今日はドキュメントの修正、不要コードの削除があった！

# 2018-12-05
## Côme Chilliet: Add LDAP information in UPGRADING
- https://github.com/php/php-src/commit/cb00ca7cfeea8af8083d28d7bc66957c61899732
- [7.3~]
- UPGRADING に LDAP の機能追加を追記
- [PR:2640](https://github.com/php/php-src/pull/2640) あたりの話かな

## nikic: Remove unused import_used_extension utility value
- https://github.com/php/php-src/commit/2a32c1cafdbabba7f0f6141380008fd7e7ad1122
- zend_utility_values の使われていないフィールドの削除

## nikic: Fix unused variable warnings
- https://github.com/php/php-src/commit/3b70dc078fd0e8fb6c3377d5c4969c992f848e63
- ext/spl で、不要変数の削除

## nikic: Remove commented zend_ini_displayer_cb
- https://github.com/php/php-src/commit/7674a542aa870c4cba462cb2a1b68b08f9b0406e
- コメントアウトされていたコードの削除
ksnctf 5 Onion 70pt

#問題

https://ksnctf.sweetduet.info/problem/5

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/084ffc2c-e32f-00eb-516f-34717c041621.png)

#解いてみた

- 問題はもっと下まで続いています。似たような暗号が。
- 最後の文字が=ではなかったけど、とりあえずbase64やっておきたいですよね。
    - Cyberchef https://gchq.github.io/CyberChef/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/6f36c7bd-d717-d4da-4ff0-f1627972d3ae.png)

- base64を1回じゃほとんど変わらなかったけど、10回くらいやるといい感じのものになりました。
- ただこれが何なのかわからないので「begin 666」で検索。
- すると、「uuencode」というのがたくさんヒットしたので、きっとこれだろうと。
- ちなみにuuencode初めて聞いたんですが、バイナリをテキストに変換するコマンドだそうです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/e147d5bf-cf80-eed2-4e41-913878f9ba8b.png)

- ネットでデコードできるサイトを見つけました。
- https://tool-taro.com/uudecode/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/2119dd64-d99e-3fc1-b514-5d8b7992ca9a.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/de6a29bb-e328-f1b3-b232-6e952a09f68a.png)
SARIMAXのexog(外生変数)の入力方法

# 概要
* SARIMAXで電力量を予測する。
* SARIMAXに外生変数を入力する。
* エネルギーデータと外気温度でどの程度変化するか確認する。

<font color='red'>注意</font>
**`exog`のデータ数は、fit時は`endog`と同じ数だけ入力、forecast時は、steps数と同じ数だけ入力する。**



# 実装
```python
import numpy as np
import pandas as pd
import statsmodels.api as sm
import matplotlib as plt
plt.rcParams['font.family'] = 'IPAexGothic'

df = pd.read_csv(r'C:\Users\***\OneDrive\ドキュメント\Study\Qiita\SampleData.csv',
                 engine='python',
                 index_col=[0],
                 parse_dates=[0],
                )
df.index.freq = 'H'

# 予測日を2017年8月3日として、過去3日間のデータをSARIMAXのendogとしました。
# endog,exogは共に３日分のデータです。（exogが外生変数(外気温))
# order,seasonal_orderはコレログラムとか使って推定するのですが、面倒だったのでaicが一番低いものを入れました。

forecastdate = pd.datetime(2017,8,3,0,0)
train_df = df.loc[forecastdate -pd.offsets.Day(3) :forecastdate - pd.offsets.Hour(1),:]
temp_df = pd.DataFrame(df.loc[forecastdate:forecastdate + pd.offsets.Hour(23),'外気温度'])
ele_df = df.loc[forecastdate:forecastdate + pd.offsets.Hour(23),'高圧受電']

fit_with_temp = sm.tsa.statespace.SARIMAX(  endog=train_df.loc[:,'高圧受電'],
                                            exog=train_df.loc[:,'外気温度'],
                                            enforce_invertibility=False,
                                            enforce_stationarity=False,
                                            order=(1,0,1),
                                            seasonal_order=(1,0,0,24)).fit()

fit = sm.tsa.statespace.SARIMAX(endog=train_df.loc[:,'高圧受電'],
                                enforce_invertibility=False,
                                enforce_stationarity=False,
                                order=(1,0,1),
                                seasonal_order=(1,0,0,24)).fit()

result_df = pd.DataFrame({'実績値':ele_df,
                          '予測値_外生変数有':fit_with_temp.forecast(steps=24,exog=temp_df),
                          '予測値_外生変数無':fit.forecast(steps=24)
                         }
                        )

result_df.plot(figsize=(15,5))

```

# 結果
* 外生変数入力の有無で、結果に差が出たか比較する。


![Qiita_20181206.png](https://qiita-image-store.s3.amazonaws.com/0/148213/a3e9f35d-1157-dc89-ac2d-f15f33201c6a.png)


|項目|予測精度(RMSE)|
|------|-------:|
|外生変数有|3.817|
|外生変数無|5.457|

逐次的に処理ができる環境であれば、より精度よく予想できそうであるが、1日1回ではなかなか難しいようである。

```python
fit_with_temp.params

外気温度         1.398241
ar.L1        0.851124
ma.L1        0.108688
ar.S.L24     0.608674
sigma2      22.464773
dtype: float64
```
係数を確認すると、外気温度が上昇すれば、電力量が高くなるようである。
問題は、冬季ではこれが逆転してしまうこと・・・


# まとめ
* 電力量に対して、外生変数（外気温度）を入力することで一定の効果がみられる。
* 予測するデータ分の外気温度の予報値が必要。
* 逐次的に処理すれば、予測精度の改善ができそう
定点観測したいサイトのデザイン変更をCSSのdiffで検知する

この記事は[LIFULL Advent Calendar その3](https://qiita.com/advent-calendar/2018/lifull3)の遅れてきた1日目の記事です。

他のWEB企業でもそうだと思うのですが、SEO等のサイトの改善施策は「これをやれば当たる！」というのが最初から明確に分かるわけではありません。その際に、施策の弾数を増やすために参考となるベースラインとなるサイトをいくつか手動でチェックしていました。

ただ、WEBサイトのチェックには膨大な手間がかかってしまうため、時間や網羅性で問題がありました。そのため、簡単にできて対象サイトに負荷をかけない範囲で、ベースラインにしているサイトをクローリングして、サイトの変更を検知する処理をRubyで実装し、運用しています。

## 基本方針

実装方針は簡単で、基本的に以下の2つの処理を行っているにすぎません。

* CSSを取得してAWSのS3に保存する
* 前日に取得したCSSと比較して、差分があれば通知

CSSの差分を検知することで、テキストファイルの単純比較で変更数が検知できます。他の実装案にはこのようなものがあったのですが、実装や運用が難しかったため諦めました。

そのため、以下のような欠点（制限）があります。

* CSSに影響を与えない差分は検知できない
* A/Bテストを取り逃す可能性がある もしくはA/Bテストの期間中検知され続ける
  * ただし、ベースラインとなるサイトではこの問題は起きていないので対応していません
* JavaScriptが多用されたサイト（PWAなど）には向かない
  * ただ、これはHeadless Chromeなどで対応できると思います 


**①HTMLから不変の要素を取得する**

HTMLから、idやclassのみを抽出して比較しようとしていました。ただ、特に商品一覧ページのような「同じ要素が複数あり、中身のタグ要素が微妙に違う場合のあるもの」を比較する際に、非常にややこしくなってしまったので諦めました。

また、ECサイトでは商品ページが数が多くSEOの観点では重要らしいのですが、商品ごとに表示項目が微妙に違って単純比較できない場合がありました。

**②画面キャプチャを比較する**

画像の差分を撮るのが非常に難しいので諦めました。


## ハマりどころや工夫

発想自体は簡単なのですが、いくつか実装していく中で工夫した点を説明します。

### 商品が消える場合がある

前述のように商品ページはけっこう重要で定点観測したいものらしいのですが、たまに商品自体が消えてしまうことがあるため、ずっと同じページを観測することができません。

そこで、以下のような設定ファイルで記述できるようにし、商品一覧(list)のページをクロールする際に、「ページ内に存在するURLの中から最初に正規表現にマッチしたものを利用する」ように実装しました。

```yaml
:devices:
  pc: '****-bot'
  sp: 'iPhoneのユーザーエージェント'
:robots:
  pc: https://www.homes.co.jp/robots.txt
  sp: https://www.homes.co.jp/robots.txt
:nodes:
  - name: top
    type: top
    url:
      pc: https://www.homes.co.jp/
      sp: https://www.homes.co.jp/smp/
  - name: chintai-top
    type: top
    url:
      pc: https://www.homes.co.jp/chintai/
      sp: https://www.homes.co.jp/smp/chintai/
  - name: chintai-list
    type: list
    url:
      pc: https://www.homes.co.jp/chintai/tokyo/list/
      sp: https://www.homes.co.jp/smp/chintai/tokyo/list/
    childs:
      - name: chintai-detail
        type: detail
        url_regexp: !ruby/regexp /^https?:\/\/www.homes.co.jp\/chintai\/b-\d+\//
```

前述の通り、「yamlを簡単に記述できる実行ファイルとして利用する」という発想は、ワークフローエンジンの[DigDag](https://github.com/treasure-data/digdag)から得ました。

ちなみに、クローラーの実行前にテストコードを動かし、robots.txtを参照してクローリングが禁止されていないことをきちんとチェックしています。その際に[robotex](https://github.com/chriskite/robotex)というgemが便利でした。

### baseタグのhref指定

CSSのパスに相対パスが指定されていた場合、そのページ自身のURIを基準としてページを取得します。ただし、[baseタグの中で、相対パスの基準となるURIを指定することができ](https://developer.mozilla.org/ja/docs/Web/HTML/Element/base)るため、その対応を忘れないようにする必要があります。

### diffのわかりやすい表示が難しい

当初、Rubyでうまく差分の通知を行おうと思っていたのですが、案外人間に読みやすい形で表現するのが難しかったです。結局シェルスクリプトのdiffコマンドに適当なオプションをつけて実行するようにしました。

### キャッシュバスターの処理

CSS等の末尾に日付などの文字列が付加されている場合があり、これらをファイル名やファイルの内容からうまく除去した上でないと比較できません。これを除去するためにけっこう愚直で泥臭い実装をしています。

これは[キャッシュを除去するために付加されている](https://qiita.com/yaju/items/d0ff9771de4cd854654d)らしく、キャッシュバスターと呼ばれるそうです。


## 今後の展望

CSSの差分が検知され、変更箇所のヒントはあるものの、基本的にレポーティングは手動です。その運用やアナウンスもけっこう手間なので、少しずつ自動化していきたいと思っています。

当初、こういう要望があると聞いて業務の合間にサクッと作ってしまったのですが、意外に社内でも参考にしてもらえているようです。その際に他の人でもメンテナンスしやすいよう、社内で普及しているRubyを採用しました（が、システム面は結局自分がメンテナンスしてしまっています）。

例えば、レポーティングが簡単に行えるよう、画面キャプチャを撮って、前日分と左右に並べて保存することはそれなりに簡単にはできると思います。
家でのWindowsOS用キーボードとマウスの話

学生時代にHHKBを使い始め、その時はWindowsXPだった。
社会人生活になり、心身ともに疲弊したため、関東を引き払い、実家にこもることになった。
そうなる前に、まさか契約を打ち切られるとは思わなかったため、大盤振る舞いにハイスペックなWindowsマシンを買ってしまっていた。
それとこれとは無関係であり、現在はHHKBをMac用に使っている。
そのため、Windows用にキーボード選びの旅が始まった。





# キーボード
半年もしない間に、数十万円をキーボードにつぎ込んだほどキーボード探しに迷走し、今までの貯蓄を食いつぶしている。
しかし、未だに手に馴染むキーボードに出会っていない。
helixは未だにゴミのままだし・・・。




# マウス
エレコムのゲーミングマウスを買ったが、重くて使用を断念した。
生産中止と聞いたため、急いで2台目を買ったのに、使わないままタンスの肥やしになってしまった。
大変残念だ。

![trackball.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/a0ecdf8e-9cf5-c157-1310-2a238f3e26fe.jpeg)



# トラックボール
学生時代に、ケンジントンを使い始めた。これのマウスも持っていたが、手に触れる部分のゴムがベタつくようになったため、今では机の上でホコリをかぶっている。

このトラックボールのボール部分はかなり重いため、少し軽いトラックボールを探した。
どうせならと、ボタンの多いトラックボールを探すことにした。
如何せん、なぜかボールの回転に引っかかりがあり、全く持って使い物にならなかった。
返品できるものはしたが、遠方で購入したのはどうにもならず、これまたタンスの肥やしになった。

ロジクール製品のトラックボールは、すごく使い勝手がよく、ワイヤレスなので取り回しが楽なのは気に入っている。
しかし、ワイヤレスゆえのスリープ機能が頻繁に働き、使いたいときに一時的な待機があるという弱点がある。

仕方ないが、今はロジクール製品に落ち着いている。

ちなみに、ケンジントンのトラックボールは、ビリヤード玉に置き換えて使えていたはずだが、できなくなっている。
残念だ。

![billiard.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/29125a46-4dc6-f091-1329-a82152e7a317.jpeg)


そして、旧版のは、昔懐かしPS/2変換コネクタ付き^^

![プレステ2ではない.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/5c044a3b-fadc-10ea-ceea-9ee261be91bc.jpeg)


できることならば、ケンジントンのトラックボールを使いたいと願ってやまない。ボールの重さが病みつきになる。



## Bluetooth接続方法
Windows10によるBluetooth接続で、デバイスの電源管理が出来るオプションを切る。
接続しっぱなしにしておけば、使いたいときに待機時間が無くなるだろうと目論んでいる。

![windowsの設定.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/9f1924d6-92e3-7e42-34ef-4f4dfcca7f73.jpeg)

設定の検索欄で「デバイスマネージャ」を検索する。

![wireless.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/7a1084de-bd2b-021d-869d-5bc6adf04a13.jpeg)

ワイヤレスBluetoothのプロパティで、電源オフのチェックボックスからチェックを外す。

![property.jpg](https://qiita-image-store.s3.amazonaws.com/0/82414/82d30077-ae47-1729-d7b3-001cf0423921.jpeg)

結論は、あまり意味が無かった。
待機時間が発生してしまう。
しかし、設定前よりは、待機時間の間隔が長くなったように思う。







# 珈琲
自宅で珈琲を飲むことはない。

# 懸念点
色々キーボード探しをしているが、HHKBに落ち着いたら嫌だな・・・。



以上
8946 Take#２５

#問題

http://www.hackerschool.jp/hack/take25.php

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/72e49bcf-4e30-7b6b-6d18-c05c1e1a5368.png)

#解いてみた

- ハッシュ値の逆引き的な問題です。
- ハッシュ値は不可逆なので、逆引きはできません。
- 問題のハッシュ値をネットで調べてみましたが、ありませんでした。
- プログラムを組むしか。。。
    - MD5算出しやすいPHPを選択しようかなと、ただ環境がないのでネット上の環境で。
    - ideone.com https://ideone.com/

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/3650841c-2067-6ec0-8ddd-c2d43ba848af.png)

- 答えはちへむゆ。
    - ちなみに問題文にも書いていますが、セッションごとにハッシュ値は異なるので、同じ答えとは限りません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/17681/d11e676f-b541-7396-f9cd-d3975a29960d.png)

- なんでTake23を解いたことになってるんでしょう？？？
SteamVRでのVIVEトラッカーのセッティング

詰まったので共有

1,SteamVRを起動します

2,HMDとコントローラー二つを認識させます
(これをやらないとトラッカーにコントローラーを持っていかれたりする)

3,トラッカーをUSBで接続します

4,SteamVRでHMDなどのアイコンとともにトラッカーのアイコンが出ることを確認する

5,トラッカーから接続を抜き、VIVEトラッカーのドングルに差し込む

6,SteamVRの色が消えた（灰色）のトラッカーアイコンを右クリックし、ペアリングをする。

7,ペアリング中にトラッカーの真ん中の三角部分を押して電源をつけ（この時水色のランプが点灯する）そのあとに二秒ほど三角部分の電源ボタンを押す（この時のランプは点滅）

8,しばらくすると接続が完了


※複数のトラッカーを使うとき、左から接続の順番になっている
DockerとVirtualBoxの違い

DockerとVirtualBoxは自分のPC(OS)に仮想環境を構築するもの。その違いについて。

## VirtualBoxとは

- VirtualBoxを使うためには仮想環境を自動で設定するVagrantを使ったりする
- ホストOS(Mac)で仮想環境を構築してゲストOS(例 Windows)を立ち上げてIEを開く
- IEで作業したものをゲストOSを伝ってホストOSに反映される
- ゲストOSで作業したものを保存する。ゲストOSを立ち上げる度に保存してたものを呼んで構築
- ホストOSにエミュレーターを起動して作業

よって立ち上げが遅い。作業が遅い。

## Dockerとは

- Mac(OS)にコンテナ(WordPress、MySql)がある
- ```$ docker-compose up```でDockerコマンドを実行

よって立ち上げが早い。作業が早い。

## コンテナとlocalのデータ管理

-  volumeを設定するとlocalのファイルとコンテナのファイルが同期される
- local上で```git pull```したりして変更すると、コンテナ上でマウントしているファイルも変更される

## WordPressのコンテナの場合

``` command:terminal
# var/www/htmlはWPのコンテナが参照しているディレクトリ
$ docker run -v /host/path:/var/www/html wordpress
```

``` yaml:docker-compose.yml
volumes:
  - /host/path:/var/www/html
```

localで管理している「/host/path」とコンテナの「/var/www/html」が同期

## 参考サイト

- [「Vagrant」と「Virtual Box」の違い](https://qiita.com/andrew954/items/1d9f460558da7b84768f)
npm i -gしたコマンドが使えなくなったら

過去に `npm i -g` でインストールしたコマンドが、ある日突然使えなくなってしまったときの原因と対処法を書いていきます。

## `npm i -g` のインストール先を調べる

```bash
❯ npm prefix -g

usr/local/Cellar/node/11.2.0
```

https://docs.npmjs.com/cli/prefix

`npm install --global` や `npm i -g` では、上記のコマンドを叩いて表示されるパスの先にインストールされます。


## インストール先がどうなっているかを見る

```bash
❯ ls $(npm prefix -g)

AUTHORS               LICENSE               etc/                  libexec/
CHANGELOG.md          README.md             include/              share/
INSTALL_RECEIPT.json  bin/                  lib/
```

コマンドは `bin` の配下にあります。

```bash
❯ ls $(npm prefix -g)/bin

bin/      lib/      ncc       node      now       npm       share/
```

このコマンドが実行できないということは、ここにパスが通っていないことになります。


## パスを通す

```bash
export PATH="$PATH:$(npm -g prefix)/bin"
```

を `.bashrc` や `.zshrc` に追加すれば、コマンドが使えるようになります！


## まとめ

実は、ある日突然に僕のShellで、コマンドが使えなくなってしまいました。
同じような事件に遭遇した人のために、その時の対処法を記事にしたものです。
僕は `usr/local/Cellar/node/11.1.0` にインストールされていました。
それが、nodeのバージョンを変えたタイミングかなにかでインストール先が変わってしまったのが原因だと思います。
パスを `$(npm -g prefix)/bin` で指定するよりもっとマシな方法があると思うので、知っている人はコメント欄などで教えてくださると助かります :pray:
XCTestを始めるときにつまづいたこととその解決法

既存のプロジェクトにXCTestを導入しようとしたら色々つまづいたので、その内容と解決法をシェアします。どなたかのお役に立てば幸いです。

# 環境:computer:
* Xcode：10.1
* macOS：10.14.1

# 前提:pushpin:
* Unit test targetがある
* Build Settings > Defines Modulesの項目が`Yes`になっている
 * 参考：[Quick/SettingUpYourXcodeProject.md at master · Quick/Quick · GitHub](https://github.com/Quick/Quick/blob/master/Documentation/ja/SettingUpYourXcodeProject.md)

# BridgingHeader問題:warning:
Testファイルに`@testable import App名`しようとしたら、BridgingHeaderのエラーが出てimportできず。（BridgingHeaderにはいつも悩まされている気がします。）

## 解決策:pick:
以下で欠けているものがあればやる。

**①podfileに下記を追加して`pod update`**

```
target 'YourProductTests' do
    inherit! :search_paths
    # Pods for testing
end
```

**②Test Targetの Build Setting > Swift Compiler -Code Genration > `Objective-C Bridging Header` にbridging-headerのパスを追加**

* Main targetにすでに記載があればコピペする
* なければ`$(SRCROOT)/$(PRODUCT)/Bridging-Header.h`みたいな感じで追加する
     * パスについて参考：[Swift: Bridging-Header 作成・設定方法（Xcode 7.2 対応）](http://www.sirochro.com/note/swift-bridging-header-generate/) 

**③Test Targetの Build Setting > Search Pathの`Framework Search Path`、`Header Search Paths`、`Library Search Path`の3つに対して、Main targetと同じものを追加**

→これらをすべてやることで、Testファイルで`@testable import App名`が呼べるようになりました。


# Main Thread Checker問題:warning:
いざTestを実行すると、`must be used from main thread only`というエラーでクラッシュ。
少し調べると**Main Thread Checker**というワードが。
参考：[iOS 11 Xcode 9で“だいぶまとも”に！新機能をまとめてみた ｜ DevelopersIO](https://dev.classmethod.jp/smartphone/iphone/xcode-9-new-features/#main-thread-checker)

下記の記事にもあるように、Main Thread Checkerを無効にするのはあまり良いやり方ではなさそうです。
[Xcode 9 環境 で GoogleAnalytics を動かすまでの軌跡 - Qiita](https://qiita.com/ogwmtnr/items/a63a0375899d38fd5bff)

## 解決策:pick:
PodのFirebaseのバージョンを4.x系に上げる。（Firebaseが古いのが原因）

```
pod 'Firebase' , '~> 4.0'
pod 'Firebase/AdMob' , '~> 4.0'
pod 'Firebase/RemoteConfig' , '~> 4.0'
```

`pod update`すると以下のようなエラーがたくさん出ますが、頑張ってポチポチやって解消します。
> 'FIRAnalytics' has been renamed to 'Analytics'
> Extraneous argument label 'withName:' in call
> kFIRParameterItemID' has been renamed to 'AnalyticsParameterItemID

→これでテストが通りました。やっとTest Succeededのマークが出てめっちゃうれしい。

# 参考になったサイト
* [ios - added unit testing target to Xcode - failed to import bridging header won’t go away - Stack Overflow](https://stackoverflow.com/questions/28343493/added-unit-testing-target-to-xcode-failed-to-import-bridging-header-wont-go-a)
* [Xcode 9 環境 で GoogleAnalytics を動かすまでの軌跡 - Qiita](https://qiita.com/ogwmtnr/items/a63a0375899d38fd5bff)
* [個人アプリを Xcode9 Swift4 対応した時にやったこと - star__hoshi’s diary](https://starhoshi.hatenablog.com/entry/2017/09/18/%E5%80%8B%E4%BA%BA%E3%82%A2%E3%83%97%E3%83%AA%E3%82%92_Xcode9_Swift4_%E5%AF%BE%E5%BF%9C%E3%81%97%E3%81%9F%E6%99%82%E3%81%AB%E3%82%84%E3%81%A3%E3%81%9F%E3%81%93%E3%81%A8)
MemoryCacheにUpdateCallbackを設定するとAbsoluteExpirationよりキャッシュの寿命が延びる

# 前置き

System.Runtime.Caching の MemoryCache はキャッシュの寿命を AbsoluteExpiration or SlidingExpiration で設定できます。
ただし実際には期限が切れても即座にキャッシュが削除されるわけではありません。
実際にキャッシュが削除されるタイミングは次の２つです。

1. 決められた polling 間隔 (30s) で期限切れのキャッシュを削除
2. キャッシュを Get した時点ですでに期限切れの場合、値を返す前に削除 (AbsoluteExpiration のみ)

このタイミングの時のみキャッシュが削除され、設定していれば RemovedCallback が呼ばれます。
SlidingExpiration を設定している場合は期限切れでもキャッシュが実際に削除される前に Get すればまた寿命が延長されます。
AbsoluteExpiration の場合は polling を待たずとも Get した時に期限切れで削除されるので（RemovedCallback を考慮しなければ）設定した期限通りの時間だけキャッシュが生存します。

2 のコード: https://github.com/Microsoft/referencesource/blob/60a4f8b853f60a424e36c7bf60f9b5b5f1973ed1/System.Runtime.Caching/System/Caching/MemoryCacheStore.cs#L243

# 本論

UpdateCallback を設定した場合、上記の 2 が無効になります。
そのため実際に設定した期限よりも長くキャッシュが残ります。その時間は最大で polling 間隔 (30s) と同じです。

# 問題

実際に期待するキャッシュ時間よりも polling 間隔を待つだけの時間、キャッシュの寿命が長くなります。
特にキャッシュ時間と polling 間隔が変わらないあるいは短い場合は顕著な影響が発生することが考えられます。

# 解説

Set() で UpdateCallback を設定した場合、下記のように別の Set() が呼ばれます。

https://github.com/Microsoft/referencesource/blob/60a4f8b853f60a424e36c7bf60f9b5b5f1973ed1/System.Runtime.Caching/System/Caching/MemoryCache.cs#L574

この中で cache entry が作成されるのは次の場所からです。

https://github.com/Microsoft/referencesource/blob/60a4f8b853f60a424e36c7bf60f9b5b5f1973ed1/System.Runtime.Caching/System/Caching/MemoryCache.cs#L627

見てわかる通り cache entry が 2 つ作成されています。通常の cache entry と sentinel entry です。
Expiration を設定しているにもかかわらず cache entry は寿命が無限です。設定した Expiration は sentinel entry の方に設定されています。
sentinel entry が実際に削除された時、下記の sentinel entry の RemovedCallback が呼ばれ、そこから本来の UpdateCallback が呼び出されるわけです。

https://github.com/Microsoft/referencesource/blob/60a4f8b853f60a424e36c7bf60f9b5b5f1973ed1/System.Runtime.Caching/System/Caching/MemoryCache.cs#L98

つまり cache entry が削除されるにはまず sentinel entry が削除される必要があります。
ここで前置きのキャッシュが削除されるタイミング 2 を思い出します。
"Get 時にキャッシュが期限切れなら値を返す前に削除する"わけですが、Get するのは通常の cache entry。これは寿命が無限なので、MemoryCache に与えた AbsoluteExpiration を過ぎていても削除されません。
sentinel entry にアクセスする手段はありません。そのために削除タイミング 2 は期待できず、1 を待つしかありません。
結果として polling を待つだけの時間、キャッシュの寿命が延長されることになります。

# 回避方法

AbsoluteExpiration を使わず自前でキャッシュの寿命を管理すれば回避できます。
暗号化について

#暗号化について
これはユアマイスターアドベントカレンダー2018の6日目の記事です
https://qiita.com/advent-calendar/2018/yourmystar

##暗号化とは？　
　データの中身を第三者に見られたくない場合や、他者と通信する際に通信相手を保証する場合などに用いる技術です。暗号化したデータを見るために元(平文)に戻すことを復号化と言います。

##共通鍵暗号方式
　共通鍵暗号方式とは暗号化と復号化に使う鍵に同一のものを使う方式のことです。処理が早いという特徴はありますが、同じ鍵で暗号化してしまうと他のユーザに見られる危険性が出てくるのでユーザごとに鍵を生成する危険性があります。

##公開鍵暗号方式
　公開鍵暗号方式とは共通鍵暗号方式とは異なり、暗号化に使う鍵と復号化に使う鍵は別物です。各ユーザに送る鍵は同一の鍵（公開鍵）でよく、復号化する鍵を秘密鍵として保持しておく方式です。処理が遅いというデメリットはありますが、公開鍵の受け渡しは容易であるというメリットがあります。

##SSL通信
　SSL通信とは共通鍵暗号方式と公開鍵暗号方式を用いた通信です。クライアントはサーバーに公開鍵暗号方式で暗号化した共通鍵のデータをサーバーに送信します。サーバーは秘密鍵を用いて共通鍵のデータを復号化します。その共通鍵を用いて暗号化通信を行うのがSSL通信です。

##ハッシュ化
　厳密にいうと、暗号化とハッシュ化は違いますが今回はハッシュ化についても説明させていただきます。ハッシュ化とはデータを不可逆変換する方式です。暗号化と違い復号化はできないのが特徴です。ユーザのパスワードやクレジット情報を保持する時などに用いられます。データベースに平文のパスワードを保存すると情報が漏れたときに悪用される危険性がありますが、ハッシュ化したデータなら復号はできないので安全性は高まります。ユーザがパスワードを入力したさにハッシュ化した値とデータベースに保存してあるデータを照合するということに使われます。
railsエラーログをslackに連携する


amazon-linuxにfluentdを入れて、ログを監視して、slackに投げるよ
railsじゃなくても使える

# インストール
```
# curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent2.sh | sudo sh
curl -L http://toolbelt.treasuredata.com/sh/install-amazon2-td-agent3.sh | sudo sh
sudo td-agent-gem install fluent-plugin-slack
```

# webhook_urlの取得
ここから
https://slack.com/services/new/incoming-webhook

# td-agent.confにログとslackを設定
sudo vi /etc/td-agent/td-agent.conf

```
# 適当な箇所に挿入
<source>
    type tail
    path /path/to/production.log
    pos_file /var/log/td-agent/logfile.log.pos
    tag hoge.error
    # ログの形式に合わせて、正規表現
    format /^\[(?<level>[A-Z]+)\] (?<log>.*?)$/
</source>
<filter hoge.error>
	# errorとfatalだけ連携
    type grep
    regexp1 level ERROR|FATAL
</filter>
<match hoge.error>
    @type slack
    webhook_url https://hooks.slack.com/services/XXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    channel hoge_channel
    username hoge-name
    icon_emoji :heavy_exclamation_mark:
    flush_interval 10s
    message_keys level,log
    message "[%s] %s"
</match>
```

# 権限設定
sudo vi /lib/systemd/system/td-agent.service
ログへアクセスできない場合、実行ユーザを変更する

```
User=root
Group=root
```

# 起動するよ
sudo service td-agent start

# fluentdのログを確認するよ
sudo tail -f /var/log/td-agent/td-agent.log

# 自動起動
sudo systemctl enable td-agent.service
Herokuにローカルでprecompileしてデプロイする

# Herokuへオリジナルアプリをデプロイする
自作のアプリを公開する際に、僕のような初学者はHerokuを重宝しています。
ただ、アプリの表示速度をあげる「アセットパイプライン」をHerokuで利用するための設定、方法が少し複雑だったので備忘録として残しておきます。

# 前提条件
Ruby 2.5.0
Rails 5.2.0

## ローカルでプレコンパイルし、Herokuにアップしてみる

`bundle exec rails assets:precompile RAILS_ENV=production`
これでpublic/assets以下にプレコンパイルされたファイルができる。
このフォルダーが僕の環境ですと、.gitignoreに記述されていたのでHerokuにあげるために
記述を削除しておく

```text:.gitignore
...略
/public/assets　←これ消す
.byebug_history
...略
```

でherokuにアップロードした。

##　アップロード後の更新
先程作成したapp/public/assetsを見に行ってしまうので、app/assets/以下を変更しても反映されない。
一度作成したpublic/assetsを削除する。
`bundle exec rails assets:clobber RAILS_ENV=production`

で、もう一度プレコンパイルすればいいみたい。

## 動的プレコンパイル設定
解決方法を検索中に多かったのが、特に理由も明記されずにconfig/environment/production.rb中の
`config.assets.compile = false`
をtrueに書き換えるというもの。
重くなるらしいし、やめとけって書いてあるのもありました。
[サーバ側でassets:precompileしたくない](http://interfirm.hatenablog.com/entry/2014/07/09/185836)

## 正直まだわからない。そのうち頭良くなったら...
面倒な手順だし、調べてるときに自動的にコンパイルしてくれる方法を紹介しているものもありました。
まだ半分も理解できていない...
勉強続けて理解がすすんだら記事書き直していきます。
でもHerokuにgitからあげるときにコンパイルしたファイルが含まれない！ってときはこの記事読んで
基本的なことに気づいていただければ幸いです。
JupyterHubによる社内共用分析環境の構築（GPUも使えるよ）

[aptpod Advent Calendar 2018](https://qiita.com/advent-calendar/2018/aptpod) 7日目は南波がお送りします。

## tl; dr

- 社内のマシンで[JupyterHub](http://jupyter.org/hub)を動かしてます
    - （社内で運用している）GitLabの情報で認証できるような設定にしているため、アカウント管理などが楽です
    - GPU使えるため、はやりのディープラーニングも動かせます
    - （社内用の設定では）自社製品のSDKを使用できるようDockerfileをカスタマイズしているため、Jupyter Notebook立ち上げるだけでIoTデータの分析ができます

[GitHubにコード置いた](https://github.com/aptpod/jupyterhub-docker-gpu-gitlab)ので、何かの機会にご利用いただければ幸いです

## 背景

日常の業務では、お客様が集めたIoTデータの活用（e.g. 機械学習など）を促進するための活動を中心にお仕事しています

具体的には、弊社[intdash](https://www.aptpod.co.jp/products/intdash/)というプラットフォームのなかの "Analytics Services" という製品(群)に含まれるPython用のSDKを用いて、収集済みのデータやリアルタイムに流れているデータの分析を行うコードを書き、「こんなこともできるんですよ！」とみなさんに伝えていくようなお仕事です

## 課題

分析の中にはGPUを使用したいようなネタもあるため、その際は社内のGPUを積んだサーバーに繋いでJupyter Notebookを立ち上げて作業をしていました

しかしながら、

- あまり環境を汚したくない
    - 分析用途以外にも使用されているサーバーのため
- 自社製品のPython用SDKが一般公開されてない(PyPIに登録されていない)ので、 `pip install hogehoge` だけでは使用できない（一手間必要）
- 同じ環境を使用するメンバーが増えた際にごちゃごちゃしそう

あたりの怪しさがあり、どうにかしたいなと思っていました

## 解決方法と効果

Jupyter Notebookのユーザー管理ができる[JupyterHub](http://jupyter.org/hub)を導入しました

具体的には、[jupyterhub/jupyterhub-deploy-docker](https://github.com/jupyterhub/jupyterhub-deploy-docker)をベースにカスタマイズを加えた[aptpod/jupyterhub-docker-gpu-gitlab](https://github.com/aptpod/jupyterhub-docker-gpu-gitlab)を利用することで、

- すべてDocker上で動作するようにしたことで、環境が汚れない
- GitLabの情報で認証するようにしたことで、別途のアカウント管理が（基本的に）不要
- ユーザー毎に立ち上がるJupyter Notebook用のDockerfileをカスタマイズしたことで、 `import hogehoge` だけで自社製品のPython用SDKを利用できる
    - （上記のリポジトリからはこの設定は削除していますが、 `COPY HOGEHOGE /tmp/HOGEHOGE`, `RUN pip install -e /tmp/HOGEHOGE` といったコマンドを追記することで、イメージビルド時にローカルに持っている任意のライブラリのインストールを含めることができるかと思います）

などの効果を得ることができました

### 副次的な効果

基本的には「GPU積んだサーバーで分析処理するメンバーが幸せになること」を対象にした環境構築でしたが、GitLabの情報で認証できるようになったことにより社内のだれでも「オールインワンの分析環境」をブラウザ一つで利用できるようになりました

これまでも「ディープラーニングを試したければ[Colaboratory](https://colab.research.google.com/)」「自社製品のPython用SDKを試したければこのコマンド（もしくはこのDockerfile）」と伝えることはできましたが、両方を備えた環境を用意できたことでより広いバックグラウンドのメンバーに「こんなこともできるんですよ！」と伝えやすくなったかなと思っています

## まとめ

JupyterHubをカスタマイズして利用しているというお話でした

たいへん便利に使えてますので機会があればご利用ご検討ください（そしてもしそのコードを公開いただけたりすると僕のメンテコストが減って幸せになるのですごくすごくありがたいです）

（社内で運用しているコードに修正加えて公開しているので、もし動かないなどあればコメントやissueお願いします :bow: ）

## 注記

社内のプライベートネットワーク内だけでの利用を前提としているため、**TLSまわりの設定をオフ**にしています

```python
# c.JupyterHub.port = 443
# c.JupyterHub.ssl_key = os.environ['SSL_KEY']
# c.JupyterHub.ssl_cert = os.environ['SSL_CERT']
```

上記のコードをご利用になることあれば、十分にご注意ください :pray:
帰宅bot

# 問い
皆さん個人開発やっていますか？頭の中で思い浮かべたりはしますが中々実行には移せなかったりしますね。
そこでハードルを下げて[自分が普段使う物](https://blog.nabettu.com/entry/single-develop)にスコープを絞って考えてみました。

# 問題
帰宅時に毎日家の人にLineを送っています。
家の駐車場の構造上、先に帰っている父の車と私の車の入れ替えが必要なのです。

* 毎日父に「帰宅するよ」とメッセージを送るのがめんどくさい
* メッセージを送りたいが車で走行中はスマートフォンを触わることができない

**ということで毎日の無駄なルーティンを自動化します**
#実現したいこと

家に近づいたら父にメッセージが届く


#設計
以前に[Heroku](https://jp.heroku.com/)と[LineMessagingAPI](https://developers.line.biz/ja/services/messaging-api/)を使ったことがあるので
そのノウハウを生かしてPython(開発で使ったことない言語)とかで作ろうとしましたが、もっと楽に作れた(~~手抜き~~)ので紹介します。
**[IFTTT](https://ifttt.com/)というアプリのみでで完結できることがわかりました。。。すごい**

## IFTTTとは
* 様々なサービス同士を連携させるアプリ、サービスです。
* https://ifttt.com/


# フロー
1. 自宅に近づく
2. IFTTTが発火
3. LINENotifyで通知を受取る
4. メッセージが送信される
5. 親父気づく
6. 車を入れ替える

といったフローで実装していきます

#IFTTの設定
## IFTTT起動
* 右下端の`My Applets`をタップして右上の+ボタンで作成開始します。
    
![IMG_0425.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/ec484f3a-394f-7433-e5d3-da99c6a84cab.png)

## 　トリガーの設定
1. thisをタップしてトリガーを設定します。
![IMG_0426.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/e1ea34f4-da48-662b-79f3-de4bf8eac8b4.png)

2. 現在地が自宅に近づいた時をトリガーにしたいのでLocationをタップします
![IMG_0427.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/646fc5cd-7722-124d-4895-ae858865f4a5.png)

3. You enter an areaをタップします
![IMG_0428.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/f0780071-b52e-1190-c055-2628b0425e2a.png)

4. 青い範囲内に入ったら発火するよう位置を設定して右上のSaveをタップします
![IMG_0430.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/d16504e7-66c7-1a47-5da7-1da4046ede10.png)

## 処理の設定
1. Thenをタップ

![IMG_0431.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/1311663a-09ad-35bf-956c-a3b3f49e6720.png)

2. Lineを選択してSend messageをタップします
![IMG_0433.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/a76855c6-016b-c198-013d-0e43e0e1cb32.png)

3. Recipientで投稿するグループを選択します。
    * (予めLineで「きたくするよ」というグループを作成しておきました。)

![IMG_0435.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/1121c835-66f6-772c-2cf6-fbf8219aaca6.png)

4. Create actionをタップして作成 
![IMG_0437.PNG](https://qiita-image-store.s3.amazonaws.com/0/47337/a94a53bf-1d1c-c2a1-9598-2cc13602d530.png)

5. LineNotifyをグループに招待する
    * Lineを開いて先程選択したグループにLineNotifyを招待します。

# 完成
**あとは設定したエリアに侵入すると**

![IMG_68EA4535BACD-1.jpeg](https://qiita-image-store.s3.amazonaws.com/0/47337/7f5602f6-5859-12b8-74bf-e1fabba6a6db.jpeg)

# まとめ
* 自分が欲しい、使いたいと思っている機能だとモチベーションを保ちやすいなと思いました。(開発ではなくライフハックっぽくなってしまいましたが)
* 僕のような特別な理由がなくとも、お家の人に帰宅を知らせたい時にも活用できるテクニックかと思います。
* 設定をいじれば会社エリアからでたら通知が飛ぶとかもできます。
* 誤差が若干あるので
* ゆくゆくは自宅のアレクサと連携して照明やエアコンも自動化できればなと思っております。
Dockerについてさらっとまとめてみた

初投稿です。
#Dockerについてまとめてみる
##なぜ今まとめるのか
つい最近サイバーエージェントさんのインターンに参加し、Kubernetesについて学び「Dockerについてほわっとした知識しかないな～」と思ったから自分なりにまとめてみようと思います。
間違いなどが散見されると思うので、見つけたら優しくコメントしてください（笑）
##Dockerってなによ？
DockerはDocker社が開発している仮想環境のプラットフォームです。
私は、仮想環境って聞くとVMとかVirtualBoxとかをよく想像して、「何が違うの？」「慣れてるからVMでいいじゃん」などと考えていました。
けどVMなどはホスト型仮想環境であり、**ホストOSの上にゲストOSを配置する**もので、
Dockerはコンテナ型仮想環境であり**ホストOS上に仮想的な区画を作り**そのうえで動くものという違いがあります。
##使うメリットは？
ホスト型のものと比べてDockerの何がいいのかは以下の通りです。

* 処理が速い
* 環境の移築や共有が簡単
* 起動が速い

等があります。
まだまだいろいろあるのですが大きなところはここらへんだと思います。
**処理が速い**
　これはホスト型と違いゲストOSがないのが理由です。
　ゲストOSにリソースを持っていかれないところがいいですね。
**環境の移築や共有が簡単**
　Dockerfileというものがあり、ここに環境のレシピが書いてあるのでコマンド一つで同じ環境を作れるのが理由です。
　これで「俺の環境では出来たのに」問題が解決しますね！
**起動が速い**
　これもゲストOSの起動がないからです

##まとめ
Dockerは**処理が速くて簡単に環境を準備できるすごいやつ**

今回の記事はさらっと備忘録的に書いたので内容薄いのが反省点(-_-;)

##今回参考にさせていただいた記事
@rawHam様の[Dockerについてなるべくわかりやすく説明する](https://qiita.com/rawHam/items/80ba13d2d2d56dba411e)
Nuxt.jsをGAEにSSRとしてデプロイする際の注意点

## はじめに
先日、GAEがNode.js 10に対応に対応されました。
https://cloud.google.com/appengine/docs/standard/nodejs/

Qiita記事を見ると、Nuxt.jsをGAEにデプロイする際の `app.yaml`ファイルの記述が単純でそのままSSRとしてデプロイしてしまうとすぐにメモリ不足で落ちて500エラーとなります。

```app.yaml
runtime: nodejs8
env: standard
```

## 解決方法
以下のapp.yamlにするとある程度のメモリ不足は回避出来ます。

app.yamlに関する情報はこちらに記載されています。
https://cloud.google.com/appengine/docs/standard/nodejs/config/appref

```app.yaml
runtime: nodejs10

instance_class: F2

handlers:
  - url: /_nuxt
    static_dir: .nuxt/dist/client

  - url: /(.*\.(gif|png|jpg|ico|txt))$
    static_files: static/\1
    upload: static/.*\.(gif|png|jpg|ico|txt)$

  - url: /.*
    script: auto
    secure: always
```

### app.yamlの記述について
#### runtime
Nuxt.js v2だと思いますので、`nodejs10`にしましょう。

#### instance_class
Nuxt.jsでSSRする際はデフォルトのインスタンス`F1` だと厳しいので `F2` にしましょう。
詳しい料金表はこちらです。
https://cloud.google.com/appengine/pricing

#### handlers
handlersオプションを使用して、静的ファイルをCDN配信する事が出来ます。
※ここ凄い重要です。

handlersについて
https://cloud.google.com/appengine/docs/standard/python/config/appref#handlers_element

これでも厳しいって方は `scaling_elements` 等を設定して試行錯誤する必要があると思います。
https://cloud.google.com/appengine/docs/standard/python/config/appref#scaling_elements
Heroku のアプリを複製する

Heroku のアプリを複製する方法です。

ログイン

```bash
heroku login -i
```

アプリの一覧

```bash
heroku apps
```

ex01 というアプリがあったろして、それをダウンロード

```bash
heroku git:clone --app ex01
```

設定されている環境変数を確認

```bash
heroku config
```

ex02 という名前のアプリを作成する
>.git というフォルダーを削除する必要があります。

```bash
mv ex01 ex02
cd ex02
rm -rf .git
heroku login -i
git init
git add .
git commit -m "init"
heroku create ex02
git push heroku master
```

環境変数の設定

```bash
heroku config:set SECRET_KEY=hello
heroku config:set AAA_KEY=good123
heroku config:set AAA_SECRET=morning999
```