OmniAICreator/Qiita-1.07M huggingface dataset:
pythonで二部グラフの判定

#なぜやろうと思ったか
http://code-festival-2017-qualb.contest.atcoder.jp/tasks/code_festival_2017_qualb_c
これを解こうと思ったが,全く解法が思い浮かばず
解説を見てみると「2部グラフ」なるものがあり,グラフ理論が全く分からなかったので,
勉強ついでに自分で組んでみた。

#再帰版
##考え方
色分けを1,-1,0として考える
関数に値を渡す際に色をcとし,再帰時に-cを渡せば
1=>-1=>1と二つの値が周期的に与えられるのを利用する。

##コード
```py3:bipartite_graph.py

u'''
2部グラフの判定を行うプログラム

N := 頂点の数
M := 辺の数

A,B　:= 頂点Aから頂点Bにかけて無向の辺があることを示す

dict := 辺のつながりを格納する
　　　　 collections の　dict　だとValueに配列を格納しやすい

color　:= 頂点が何色で塗られているか

'''
from collections import defaultdict 

N,M = map(int,input().split())
dict = defaultdict(set)

for i in range(M):
    a,b = list(map(int,input().split()))  
    
    dict[a].add(b)
    dict[b].add(a)



color = [0 for i in range(N+1)]
res = 'Yes'

def dfs(v,c,queue=[]):
    u'''
    v : 現在のグラフの頂点
    c : 現在参照するフラグ,1=>-1=>1と使うので渡す必要がある
    queue : 探索したグラフの頂点を入れていく
    res : global変数を使いたくないが,再帰のreturnがよくわからないのでとりあえず
    '''

    global color
    global res 
    queue.append(v)
    
    for i in list(dict[v]):
        if color[i] == c:#隣の頂点が同じ値を与えられている際Falseを返す
            res = 'No'
        elif i not in queue:#探索済みでなければ再帰する
            color[i] = c*-1#0ならcとは異なる値を格納
            dfs(i,-c,queue)#引数に-cとすることで,cが1=>-1=>1を繰り返す


color[1] = 1#始点色分けする
(dfs(1,1))
print(res)            
```
#非再帰版


##考え方
collectionsのdequeを利用した非再帰での深さ優先探索
dequeから参照するグラフの頂点を逐次とりだし,
それと連結している頂点の色分け(Color)を比較,処理し,
連結している頂点が色分けされていないならdequeに追加。

これをdequeの値がなくなるまで繰り返し,途中で同じ色が隣り合わせならFalse
最後まで実行できたらTrueと返すプログラム

##コード
```py3:bipartite_graph_ver2.py

from collections import deque
from collections import defaultdict

N,M = list(map(int,input().split()))
G = defaultdict(set)

color = [0 for i in range(N+1)]

for _ in range(M):
    A,B = map(int,input().split())
    G[A].add(B)
    G[B].add(A)

color[1] = 1
que = deque([1])#始点を追加
bipartite = True

while len(que):
    p = que.popleft()#直近で追加したグラフの頂点を取得
    for q in list(G[p]):#結合しているグラフの頂点を参照
        if color[q] == 0:#塗られていないなら別の色で塗る
            color[q] = -color[p]
            que.append(q)
        elif color[q] == color[p]:#同じ色だったら2部グラフではないと返し終了させる
            bipartite = False
            break

print(concatenation)

```
LINE@内で広告を配信出来るのか

## 結論

BOTとWebページとどちらも作って、
じっくり読むようなコンテンツとかはWebページに
対話型UIが活きるコンテンツはLINEで

## 何故

### 前置き
メッセージング・プラットフォーム上で色んなサービスを展開する予定だが、サービス内で広告を出せると色々やりやすい（資金面が…）

利用するプラットフォームは以下を想定しているが、今の処メインはLINEで考えている
LINE, Messanger(Facebook), Telegram, WeChatとか


### LINEの注意点
LINE@の規約内、禁止事項にこのような記載がある
(禁止事項一覧は下記に)

14.6 **LINE@を第三者のための広告媒体として使用する行為** （第三者の商品、サービスをLINE@を利用して宣伝することを含みますが、これに限りません）

また、事前告知や原因の報告はなく、突然の一発退場になるとのこと

```
http://terms2.line.me/lineat_terms?lang=ja
14. 禁止行為
お客様は、LINE@の利用に際して、以下に記載することを行なってはなりません。
14.1. 法令、裁判所の判決、決定若しくは命令、又は法令上拘束力のある行政措置に違反する行為
14.2. 違法又は違法行為を助長するような行為
14.3. 当社又は第三者の著作権、商標権、特許権等の知的財産権、名誉権、プライバシー権、その他法令上又は契約上の権利を侵害する行為
14.4. 公序良俗に反するおそれのある行為
14.5. 反社会的勢力に対する利益供与その他の協力行為
14.6. LINE@を第三者のための広告媒体として使用する行為（第三者の商品、サービスをLINE@を利用して宣伝することを含みますが、これに限りません）
14.7. アカウントを第三者に譲渡又は貸与する行為、第三者と共用する行為
14.8. 当社又は第三者になりすます行為、意図的に虚偽の情報を流布させる行為又はお申込された業種の運営・維持とはなんら関係のない内容を表示若しくは配信する行為
14.9. 第三者の個人情報、登録情報、利用履歴情報などを、不正に収集、開示又は提供する行為
14.10. 過度に暴力的な表現、露骨な性的表現、人種、国籍、信条、性別、社会的身分、門地等による差別につながる表現、自殺、自傷行為、薬物乱用を誘引又は助長する表現、その他反社会的な内容を含み他人に不快感を与える表現を、投稿又は送信する行為
14.11. 性行為やわいせつな行為を目的とする行為、面識のない異性との出会いや交際を目的とする行為、他のお客様に対する嫌がらせや誹謗中傷を目的とする行為、その他LINE@が予定している利用目的と異なる目的でLINE@を利用する行為
14.12. 利用者又は第三者が、不快又は迷惑と思う内容の配信
14.13. LINE@のサーバやネットワークシステムに支障を与える行為
14.14. 当社によるLINE@の運営又は他のお客様によるLINE@の利用を妨害し、これらに支障を与える行為
14.15. LINE@の不具合を意図的に利用する行為
14.16. 当社に対し不当な問い合わせ又は要求をする行為
14.17. LINE利用規約に抵触する表現・内容の配信
14.18. 当社のロゴ利用ガイドラインの規定に抵触する表現・内容の配信
14.19. 上記14.1から14.18のいずれかに該当する行為を援助又は助長する行為
14.20. その他、当社が不適当と判断した行為
```


### NG

幾つかのサイトを調べてみた処、第三者のサービスを紹介する等の所謂アフィリエイトリンクを貼ると一発退場だそうで
また、アプリのDLリンクもダメ、このアプリがおすすめ等もダメとのこと
当然ながら、著作権・知的財産権等侵害もNG
即ち、コピペコンテンツはダメですよ、と（当たり前だけど）

申し込んだ業種の運営とは関係ない表現、これは申し込んだ時と現状の配信コンテンツが変わっている…なんて状況だとNGになります

### OK
リンクが掲載されたWEBページへのリンク
つまりは、クッションページがあればアフィリエイト内容を送るのは可能
自分のチャンネルのYoutubeに飛ばして、そこから自分のドメインのサイト、そこに商材、なんていうケースは既にあり


しかしまあ、LINE@の登録内容と関係ないサイトのURLはダメでしょうし、SNSに飛ばすとか自社運営のページに飛ばすとかそういう感じになりそう
Internet Explorerでスクロールさせつつlocation.hash動かす時は先にhashを設定すべし

#結論
やるべき事は記事タイトルの通り。
Google Chromeとかと動きが違うので知っとかないとハマる。
ザッと探しても類似情報が見つけられなかったのでメモとして投稿しとく。

#何が問題なのか
古いバージョンは知らないが、IE11ではlocation.hashを変更すると要素のスクロール位置がリセットされる。
縦スクロールの位置（scrollTop）を大雑把にアンカーまで飛ばす程度なら気にならないが、横スクロールの位置（scrollLeft）の制御もやりたい時などはこれでは困る。

##ダメだった例

```js:NG
element.scrollLeft = anotherElem.getAttribute("x");
location.hash = anotherElem.getAttribute("id");
```

何をやろうとしてるか気になる人向けに説明すると、htmlに同居させてるsvg（widthが30000とかある）のx属性値を読んで外側のboxの横スクロールをそこまで持っていこうとしている。
これをIEで実行すると一瞬だけ横スクロールが合った後すぐに左端に戻されてしまう。
（厄介な事にChromeはこれでも上手く行く）

##直った例

```js:OK
location.hash = anotherElem.getAttribute("id");
element.scrollLeft = anotherElem.getAttribute("x");
```

と言う訳で意図した動作をしてくれるのはこっち。
IEガーとか文句垂れる前に挙動をよく観察しような、オレ。

#余談
IEはcanvasもタテ・ヨコ8kまでしか描画してくれなかったりするので注意しておくべき。
MSDNの「CanvasかSVGか」という記事には「大きな画像を描画しなくてはならない場合はSVGを選びます」とは書かれていないので、とても一画面に収まらないようなサイズになるのが分かっているなら対策を考えておこう。

PCモニタが幅8k当たり前になるのはずっと先だろうから、その頃までIEが生きのこっているかまでは心配しなくていい。多分しないと思う。生きのこらないんじゃないかな。ま、ちょっと覚悟はしておけ。
[Survey] Kaggle - The Nature Conservancy Fisheries Monitoring 12位解法まとめ

Kaggle - The Nature Conservancy Fisheries Monitoring[^1]の12位解法[^2]の調査記事です．

Name: Rand Xie
Kaggle Discussion: https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538


### 物体検出

- SSD
- YOLO
- py-rcnn
- py-rfcn(OHEM(Oneline Hard Example Mining)を利用しつつResNet 50, ResNet 101を使用)
- pvanet

### 分類

- Xceptionを利用(画像全体から判断)
- ResNet 50を利用して魚検出器を学習

### 備考

- ボートIDは利用しなかった．(うまく働くとは思えなかったため)
- 画像を回転させて出力の平均を取る．(背景による判断をすくなくするため？)
- ResNet 50, ResNet 101にドロップアウト層を追加
- py-RFCN, pyvanet, Xceptionの合計で最終確率を算出．
- ResNet 50を利用して出力を補正．

## References

[^1]: Kaggle, [The Nature Conservancy Fisheries Monitoring](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring)
[^2]: Rand Xie, [Solution Sharing and Congratulations](https://www.kaggle.com/c/the-nature-conservancy-fisheries-monitoring/discussion/31538)
[python]あるリストが、別のリストの並び替えかを判定する関数

#欲しかったもの
二つのリストが、同じ種類/個数の要素をもつ場合（≒内容が同じか単に順番を並べ替たものの場合）にTrueを、そうでない場合にFalseを返す関数。
例）
[1,2,3],[3,2,1]=>True
["b","a","r"],["b","e","a","r"]=>False
[1,"two",3],[1,"two",3]=>True
[1,1,1],[1,1,1,1]=>False

検索してもよさげなものを見つけられなかったので、サクっと作りました。こんなん組み込みであるだろJKって方がいましたら教えていただきたいです。

```py3:is_reordering
def is_reordering(list1, list2):
    list2 = list2[:]
    for element in list1:
        if element in list2:
            list2.remove(element)
        else:
            return False
    if list2:
        return False
    return True

```

list1の要素を順番に見て、list2にその要素があったらそれを取り除いているだけです(無かったらFalseを返す)。最後のifで、list2が空になったかを判定しています。これがないと、例)の一番最後のような場合にTrueが返ってしまいます。
車輪の再発明をしてしまった感がすごいですが、とりあえずあげておきます。
SRE本まとめ（19章 フロントエンドにおけるロードバランシング）

自分の理解を深めるためにまとめてみました。[18章](https://qiita.com/bassbone/items/d59cc01c8ddf2743e599)の続きです。

## 19章 フロントエンドにおけるロードバランシング

### DNSを使ったロードバランシング
DNSのレスポンスとして複数のAもしくはAAAAレコードを返し、クライアントに任意のIPアドレスを選んでもらう。シンプルではあるが、以下の課題がある。

- クライアントの挙動がほとんど制御できない。
    - 理論的にはSRVレコードを使ってレコードの重みや優先順位を指定できるが、SRVレコードはまだHTTPには採用されていない。
- 通常はクライアントに最も近いアドレスを判断できないということから生じる。
    - 権威DNSサーバにエニーキャストアドレスを使い、DNSのクエリが最も近いアドレスに流れることを利用すれば問題は軽減される。

DNSは最もシンプルなロードバランシングの方法であるが、レスポンスを512バイトに収めないといけないというRFC1035の影響で、1つのDNSレスポンス内に収めることのできるアドレス数には上限ができてしまい、その値はGoogleのサーバ数を下回ってしまう。

### 仮想IPアドレスでのロードバランシング
仮想IPアドレスはユーザからは単一のIPアドレスに見えるが、裏側では多くのデバイスで共有されている。実際にはネットワークロードバランサーで行われている。
リクエストの振り分け方としていくつかパターンがある。

- 最も負荷の低いバックエンドを選択する。
    - ステートフルなプロトコルの場合は破綻する。
- セッションIDを使って同一のバックエンドを選択する。
    - バックエンドの故障に対して弱い。
    - コンシステントハッシュ法によって上記課題は解決できる。

ロードバランサーはどのようにしてバックエンドにパケットをフォワードするのか。解決策はいくつかある。

- 変換テーブルを保持して、ネットワークアドレス変換を行う。
- データリンク層（レイヤ2）の情報（MACアドレス）を書き換える。（DSR）
    - ロードバランサから直接端末が接続できる必要があるため大規模な環境では使えない。
- 別のIPアドレスパケットで元のパケットをカプセル化してしまう。
    - 大きな柔軟性を持っているが、パケットサイズが大きくなってしまうことでパケットが分割されてしまう点が課題。

（[20章](https://qiita.com/bassbone/items/1648d904a40b7ff4aef9)に続く）
ハイゼンベルグの運動方程式をPythonを使って解けないか？

[QuTiP](http://qutip.org/)を使えという話ですが，NumPyやSympyをつかって第二量子化したハミルトニアンのハイゼンベルグの運動方程式を立式できないだろうかというのが気になったのでやってみる。
sympyの演算子などのドキュメントが英語しかなかったので，それも含めてちょうどいいかなと思った。（ただpythonを使って第二量子化した演算子を取り扱おうとしていて，日本語しか読めないなんて人はまずいないだろう）

anacondaにデフォルトで入ってる，sympyモジュールにはブラケットを定義，ブラケットの内積や外積，交換関係を計算してくれるモジュールがあったので，テストしてみた。

# 計算モデル

ただの２準位系を想定して計算をする。ハミルトニアンを
$$\mathcal{H}=\hbar\omega|1\rangle\langle 1|$$
と定義して，例えば$|0\rangle\langle1|$の運動方程式が導出できるかやってみる。ここで，$|0\rangle$, $|1\rangle$はそれぞれ２準位系の基底状態と励起状態で，$\hbar,~\omega$は換算プランク定数と２準位系の共鳴周波数。

# sympyのモジュールを利用したハミルトニアンの記述

$|0\rangle$, $|1\rangle$を定義してみる。

```py3

from sympy.physics.quantum import Ket

up=Ket('1')
low=Ket('0')

print(up,low)
```
を実行すると，期待通りに

```
|1> |0>
```

が返ってきたので，外積モジュールを利用してハミルトニアンを作成する。

```py3

from sympy.physics.quantum import Dagger,Ket, OuterProduct
from sympy import Symbol
up=Ket('1')
low=Ket('0')
freq=Symbol('omega')
plank_const=Symbol('hbar')
H=plank_const*freq*OuterProduct(up,Dagger(up))

print(H)
````
を実行して，

```py3
hbar*omega*|1><1|
```

ここで利用したsympyモジュールDaggerは複素共役を計算してくれるもので，OuterProductでブラとケットの外積の計算をしてくれる。

ここまででハミルトニアンをpython上で書くことができた。

# ハイゼンベルグの運動方程式を解いてみる

本題

Commutator($\mathcal{O}$,$\mathcal{H}$)で計算を行ってくれることを期待した。


```py3
    from sympy.physics.quantum import Commutator, Dagger
    from sympy.physics.quantum import Ket, OuterProduct
    from sympy import Symbol
    up=Ket('1')
    low=Ket('0')
    freq=Symbol('omega')
    plank_const=Symbol('hbar')

    
    upper=OuterProduct(up,Dagger(low))
    H=plank_const*freq*OuterProduct(up,Dagger(up))
    result=-1/plank_const*Commutator(upper,H)

    print(result)
```
ここでupperは上昇（生成？）演算子の$|1\rangle\langle 0|$で，最終行は単なるハイゼンベルグの運動方程式（のつもり）だ。結果は

```
-omega*[|1><0|,|1><1|]
```

となって，計算が出来ていない。[sympyのドキュメント](http://docs.sympy.org/latest/modules/physics/quantum/commutator.html)を読んでいると

```py3
.expand(commutator=True).doit()
```
をつければよいと書いていたので，実行してみる。

```
-omega*(|1><0|*|1><1| - |1><1|*|1><0|)
```
無事に途中まで計算ができた。状態は直行しているので，一つ目の項が0になるはずだが，sympyのブラケットの定義だけでは自動でクロネッカーのデルタに書き換えてくれないみたい。

何やらいい方法があれば教えてほしい。[QuTip](http://qutip.org/)を使えばいいんだろうなあ
[Unity]UIのテキストのサイズがなぜか変わらない

<h1>起こったこと</h1>
fontsizeをいじってサイズを変えようとしたら、数値を何にしてもテキストのサイズが変わらなくなった。
他のテキストはサイズが変わるのに、とあるテキストだけサイズが変わらず焦った。(Rect TransformのScaleをいじるとさすがに変わるが、、、)

<h1>解決方法</h1>
Textコンポーネントの中に「Best Fit」というフラグがある。
そこにチェックが入っていた。
これにチェックを入れると、フォントサイズが固定になるのだろう。
って思ってたけど、「設定されたフォントサイズ内で表示可能な一番大きなフォントサイズに自動的に変更する機能です」というコメントをいただいた。
このフラグをオフにしたらサイズが変更できるようになった。

<h1>感想</h1>
いろんな機能あるんだなぁ
AWS OpsWorksで特定のLayerだけ別ブランチからソースを取得する方法

## 概要

AWS OpsWorksの場合custom Chef cookbooksの設定がStackに入ってるLayerすべてに同じ設定が適用される。
検証などで特定のレイヤーだけ別のブランチを使いたい場合はLayerのCustom JSONに設定を書くことで別ブランチを使うことができる。

## 別ブランチのcustom Chef cookbooksを使う方法

![スクリーンショット 2017-10-11 23.06.15.png](https://qiita-image-store.s3.amazonaws.com/0/21172/8d9a6c76-30f4-72fb-6486-30aa2d74b91a.png)

General SettingsのCustom JSONに設定する。

```json
{
  "opsworks_custom_cookbooks": {
    "scm": {
      "revision": "<branch name>"
    }
  }
}
```

## Appで別ブランチのソースを取得するようにする方法

Appも同様に同じStackに入ってるLayerすべてで同じ設定が適用されるため、特定のLayerだけ別ブランチのソースを使いたい場合はLayerのGeneral SettingsのCustom JSONに設定する。

```json
{
  "deploy": {
    "<app name>": {
      "scm": {
        "revision": "<branch name>"
      }
    }
  }
}
```
PowerShellで、セッションを次のリクエストに渡す方法

PowerShellでは、Webのリクエストを実行するコマンドレットがあります。
それらを使う際、セッション情報をリクエストで引き継ぐ方法を書きます。

## 用途
PowerShellで、ログイン→何らかのリクエスト→ログアウトのような処理をする際、ログインで得たセッションを引き継いで利用する。

## 対象のコマンドレット

|コマンド名|処理|公式|
|---|---|---|
|`Invoke-WebRequest`|ヘッダー等がついた、そのままのHTMLを返す|[リンク](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-webrequest?view=powershell-5.1)
|`Invoke-RestMethod`|レスポンスがJSON等なら、その状態で返す|[リンク](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/invoke-restmethod?view=powershell-5.1)|

どちらも、リクエストを実行して、結果を取得する点では共通です。
例として、`Invoke-RestMethod`を使用しますが、どちらのコマンドレットでも使用できます。

## セッションの取得
ログインのAPIを呼び出すとします。下記のURL等は適当で、随時読み替えてください。
また、ログイン処理は、`JSON`でユーザーID等を渡すものとします。

```ps1:executor.ps1
# ルートのURL
$hostUrl = "https://hogeService.com/"
# ログインAPIのパス
$login = "rest/login"

$hosturi = New-Object System.Uri ($hostUrl)
$url = New-Object System.Uri ($hosturi, $login)

# ログイン情報
$inputs = @{
    username = "userName";
    password = "pass";
}

$json = $inputs | ConvertTo-Json;
$headers = @{ #何かあれば }

$res = Invoke-RestMethod -uri $url.AbsoluteUri `
    -Method Post `
    -Body $json `
    -ContentType "application/json" `
    -Headers $headers `
    -SessionVariable loginSession # loginSessionに、セッション情報が格納される
```

`-SessionVariable`を付与し、上記のように書くと、`$loginSession`という変数が使えるようになります。これがセッションです。


##セッションを使う
次のリクエストに、セッションを付加します。

```ps1:executor.ps1
# 処理APIのパス
$search = "rest/search"

$url = New-Object System.Uri ($hosturi, $search)

# 検索情報
$inputs = @{
    date = Get-Date -Format "yyyy-MM-dd";
    title = "hogehoge";
}

$json = $inputs | ConvertTo-Json;

$res = Invoke-RestMethod -uri $url.AbsoluteUri `
    -Method Get `
    -Body $json `
    -ContentType "application/json" `
    -Headers $headers `
    -WebSession $loginSession
```
渡すときは、`-WebSession`パラメータを使います。

## 利用上の注意
`REST API`を呼び出す場合は、そのAPI仕様をよく見ましょう。
そこに、セッションを渡すとか、ログインの戻り値の一部をヘッダーに含めろ等の指示があると思います。
それを見て、セッションを渡せ、と書いてある場合は、上のようにしてセッションを引き渡しましょう。
[git]ERROR: Authentication error: Authentication required: You must have push access to verify locksというエラー

でかいサイズのものをアップロードしようとしたら、
「ERROR: Authentication error: Authentication required: You must have push access to verify locks」
とエラーが出た。

ググっても日本人の記事が出てこなくてよく分からなくなった。
翻訳したら、「認証が必要。ロックエラー」のようだ。

<h1>解決方法</h1>
解決といってもプッシュできるようになるわけではない。
調べたら、Githubは一か月に1GB以上のpushができないようだ。(無料プランだから)
pushしたかったら、一か月待つか課金するしかないようだ。

<h1>感想</h1>
当然すべてのゲームは無課金でやってきてるマンなので、課金という選択肢は僕にはなかった(セリフ調)
そんな話はおいといて、他に解決方法などあれば教えていただけると助かります。
mysqldump で出力した tsvを Redshift に import

mysqldump で出力したTSVには下記のような特徴があって扱いがめんどくさいですが、Redshiftのオプション指定することで 無加工で Redshift に取り込めます。

- nullは \N になる
- フィールド内のタブ(\t) は、 \\\t になる (\でエスケープされる)
- フィールド内の改行(\n) は、 \\\n になる (\でエスケープされる)


### mysqldump で tsv として dumpする

```
mysql> select * from users into outfile '/var/lib/mysql-files/users.txt';
```

### s3 に上げる

```
$ aws s3 cp /var/lib/mysql-files/users.txt s3://bucket_name/
```

### Redshift にロード


```
$ psql -U $user $db_name --host=$host --port=5439

# copy table_name from 's3://bucket_name/users.txt'
iam_role 'arn:aws:iam::000000:role/HogeRole'
blanksasnull
emptyasnull
delimiter '\t'
escape
;
```

#### オプション

- delimiter は タブ文字 \t を指定する
- escape オプションつけることで、エスケープされた改行とタブをそのまま取り込める
- csv オプションは指定しない
- emptyasnull blanksasnull はなくても大丈夫と思う
VisualStudio2017 + Ionic2テンプレートでデバッグするとフリーズする現象を解決する

**[このサイト](https://blogs.msdn.microsoft.com/visualstudio_jpn/2016/08/03/create-high-quality-mobile-apps-with-ionic-visual-studio/)**をお手本にVisualStudio2017にIonic2テンプレートをインストールしてデバッグ実行するとフリーズしてしまった。

Cordova起動でコケてるようだったので[ツール]→[オプション]の「Cordova キャッシュのクリア」を行うとデバッグできるようになった。

![this.png](https://qiita-image-store.s3.amazonaws.com/0/119455/bc7bea42-bc21-f96a-e057-efb5161aed8c.png)
Cloud9 を iPad Pro の物理キーボードからつかう

## 本記事の対象となる環境

- iPad Pro 10.5 inch WiFi モデル 64GB
- iOS 11.0.2
- bluetooth キーボード：EC Technology 3つ折りキーボード タッチパッド搭載
- Cloud9 無料アカウント

## 問題

- Cloud9 のエディタ(ace editor)は iOS デバイスでアクセス時、物理キーボードのカーソルキーおよび Esc キー、Ctrl キー、Alt キーからの入力を受け付けない。さらに、Caps Lock キーに Ctrl キーを割り当てる(重複する)。
  - Default キーバインドではキャレットの移動ができない。
  - Emacs キーバインドでは、Ctrl キー機能が物理キーボードの Caps Lock キーに割り当てられているため、キャレットの移動が困難である。
     - 筆者が Emacs キーバインドに詳しくないのも理由の一つ。😓
  - Vim キーバインドでは挿入モードから抜けるとき、Caps Lock を強要される。
     - Esc キーが効かないため、`<C-[>` で挿入モードから抜けるが、Ctrl キーが Caps Lock キーに割り当てられており、Caps Lock キーは iOS 側で生きているので、Caps Lock が有効になってしまうため。

## 解決策

- Vim キーバインドを使いつつ、Cloud9 のエディタに Esc キー入力相当のキーバインドを登録する。

### 操作手順

1. Cloud9 のエディタを開く。
1. メニューより、「Cloud9」をタップ。
1. プルダウンメニューより、「Open Your Init Script」をタップ。init.js をエディタで開く。
1. 次のコードを記述する。この記述で、Vim キーバインドの挿入モード時、「`~~`」と入力すると`<Esc>`キーを押したときと同じ動きをさせる。
 >require(["plugins/c9.ide.ace.keymaps/vim/keymap"], funciton (vim) {
>　vim.map("~~", "&lt;Esc&gt;", "insert")
>})

1. init.js を上書き保存する。
1. Caps Lock(Ctrl キー相当) + Enter を押して init.js の内容をエディタの設定に反映させる。
1. メニューより、「Edit」→「Keyboard Mode」→「Vim」を選択する。

## 問題点

そもそも vim のキーバインドがわからないと、この解決方法では問題を解決できない。

参考：Qiita「[Vimをメモ帳程度に使うために覚えておくべきコマンド](https://qiita.com/honeniq/items/201156650310c4968c3a)」@honeniq 様の記事
JavaScript の関数は変数として扱えるの巻

## 事の発端

同僚プログラマが「ヘイ、こんなコードを書いたけど意図した動作をしないんだ！」と言って次のようなコードを持ってきました。

```javascript
window.addEventListener("unload", alert("よろしいですか？"))
```

確かに、これを実行すると `unload` がトリガーになっているにも関わらずロード時にアラートが表示されてしまいます。
この場合は次のように直せば意図したように動作します。

```javascript
window.addEventListener("unload", function() { alert("よろしいですか？") })
```

しかし、何故後者は正しく動くのでしょうか？

最初に結論を書いてしまうと前者はメソッドの実行結果（ちなみに常に `undefined` を返します）が `addEventListener` の第二引数として渡されてしまうためです。

これだけ読んでもよく分からないぞ、という方のために順番に説明していきます。

## 詳しい解説

### alert とは何なのか？

正確には `window.alert` で `window` オブジェクトのメソッドです。実行すると皆さんご存知の通りアラートウインドウが表示されて `undefined` を返します。

### メソッドとは関数ではないのか？

メソッドはオブジェクトが持つプロパティの内、関数オブジェクトを参照しているものの総称です。

```javascript
var func = function () { alert("test") }
var obj = {}
// メソッドの登録
obj.myFunc = func
```

### 関数オブジェクトとは？

JavaScript では関数もオブジェクトとして扱います。

```javascript
var i = 1
var func = function () { alert("test") }
```

これはどちらも正しく動作します。

```javascript
console.log(i)
console.log(func)
```

一方でコンソールから中身を確認すると、ブラウザにより多少の差はあると思いますが後者では関数のオブジェクトが表示されると思います。

このように JavaScript では関数オブジェクトそのものも変数として参照させる事が可能です。

### 関数の実行について

ここで先ほどの例を少し書き換えてみます。

```javascript
var func = function () { alert("test") }
var obj = {}
// 関数名の後ろに () がついているのに注目
obj.myFunc = func()
```

このコードを動作させると `obj.myFunc = func()` の行が実行された瞬間にアラートが表示されると思います。なぜなら `()` をつけると関数が実行された結果を右辺に代入しようとするためです。

```javascript
var func = function () {
  return alert("test")
}
```

が実行される事になるので `alert()` が呼び出されて `obj.myFunc` には `undefined` が登録されます。関数オブジェクトそのものを参照させたい時は `()` をつけずに使います。

### 無名関数について

今までの例では `func` という名前の変数を用意していましたが、無名関数を用いる事もできます。

単なる数値の計算ではいちいち変数を作らず行う事がよくあると思います。

```javascript
// 変数にしなくても整数が表示できる
console.log(1 + 2)
```

繰り返し述べているように関数も変数として扱えるので、整数を書く感覚でメソッド登録時に関数オブジェクトを直接記述する事ができます。

```javascript
var obj = {}
obj.myFunc = function() { alert("test") }
```

### 振り出しに戻る

では、改めて最初の動作したコードを見てみましょう。

```javascript
window.addEventListener("unload", function() { alert("よろしいですか？") })
```

ここまで書いて来た内容をまとめると

```javascript
var func = function() { alert("よろしいですか？") }
window.addEventListener("unload", func)
```

を無名関数で書いたんだな、という事

```javascript
window.addEventListener("unload", alert("よろしいですか？"))
```

と書いてしまうと `alert("よろしいですか？")` の実行結果が第二引数になってしまう事が、それぞれお分かり頂けたでしょうか。

### addEventListener の実装を確認する

最後に、念のため `addEventListener` の実装を確認してみます。

https://developer.mozilla.org/ja/docs/Web/API/EventTarget/addEventListener

第二引数 `listener` については「指定されたタイプのイベントが発生するときに通知を受け取るオブジェクト」と書かれており、サンプルの中でも `modifyText()` として定義した関数オブジェクトそのものを第二引数に引き渡しています。
EC2上にS3をマウントする方法

# s3fs-fuseインストール

```
sudo apt-get update

sudo apt-get install build-essential git libfuse-dev libcurl4-openssl-dev libxml2-dev mime-support automake libtool
sudo apt-get install pkg-config libssl-dev

git clone https://github.com/s3fs-fuse/s3fs-fuse

cd s3fs-fuse/
./autogen.sh
./configure --prefix=/usr --with-openssl

make
sudo make install
```

# 参照先s3バケットの設定

```
sudo touch /etc/passwd-s3fs

sudo vi /etc/passwd-s3fs
# 以下を設定
---
s3パケット名:aws_access_key:aws_secret_key
---

sudo chmod 640 /etc/passwd-s3fs
```

# マウント
```
sudo mkdir /mnt/s3fs

sudo s3fs s3バケット名:/参照ディレクトリ名 /mnt/s3fs -o allow_other -o use_cache=/tmp
```

>【参考】
https://github.com/s3fs-fuse/s3fs-fuse/wiki/Installation%20Notes#tested-on-ubuntu-1404-lts
http://www.mori-soft.com/2008-08-15-01-36-37/os/215-s3-s3
Laravel でモックを使ったメール送信のテストが簡単だった

## はじめに
モックを使ったメール送信のテストが意外と簡単にできたのでメモ。
アサートメソッドが充実していて、キューを使ったメール送信のテストも簡単にできてしまう。

## 環境
PHP 7.1
Laravel 5.5

## サンプル

```MailTest.php
class MailTest extends TestCase
{
    public function testMailSend()
    {
        Mail::fake();

        $email = 'test@gmail.com';

        // 任意の実際のリクエスト処理
        $this->put(
            "test/mail",
            [
                'mail_to' => $email,
            ]
        );

        // 1回送信されたことをアサート
        Mail::assertQueued(MailBuilder::class, 1);

        // メールが指定したユーザーに送信されていることをアサート
        Mail::assertQueued(
            MailBuilder::class,
            function ($mail) use ($email) {
                return $mail->to[0]['address'] === $email;
            }
        );
    }
}
```

### 解説
- `Mail::fake()` で実際にメールが送信されるのを防ぐことができる
- `MailBuilder` は `php artisan make:mail MailBuilder` で生成した任意の Mailable クラス
- メール送信の前にキューに入れているので `assertQueued` を使用しているが普通に送信するなら `assertSent` を使う

## あとがき
当たり前だが、ユーザーにメールが到達しているかどうかまではテストできないので、処理がメール送信まで到達していることまでが担保できる範囲。
Eclipse Class Decompiler へのマルウェア混入について

ダウンロードランキングで常に上位に位置していた有名な Eclipse 逆コンパイラープラグイン Eclipse Class Decompiler (作者は中国の方) にマルウェアが混入しているとして、Eclipse Foundation の判断により、マーケットプレースから強制的に削除されました。使用されている方は以下の対処を強く推奨します。

# 対処方法
###自分で Eclipse Class Decompiler をインストールされた方
1. メニュー > ヘルプ (Mac は Eclipse) > Eclipse について > インストールの詳細
1. 該当のプラグインを選択 > アンインストール

### PAO Eclipse 4.7.0.v20170628 または 4.7.1a.v20171011 を使用
PAO (Pleiades All in One) を使用している場合は、dropins/EclipseClassDecompiler ディレクトリを削除、または [4.7.1a.v20171012](http://mergedoc.osdn.jp/pleiades_distros4.7.html) 以降にバージョンアップしてください。現在のバージョンは PAO をインストールしたディレクトリにある pleiades-4.7.0-java-win-64bit_20170628 のようなファイル名に含まれる日付で確認できます。PAO 4.6 以前の同プラグインには該当の実装が含まれていないことを私のほうで確認済みですが、不安な場合は dropins の同ディレクトリを削除してください。

# 代替プラグイン
同プラグインがフォークされ、マルウェアに該当するコード部分のみを取り除いた Enhanced Class Decompilerが公開され、すでにマーケットプレースにも登録されています。Pleiades All in One 4.7.1a.v20171012 以降では、このプラグインに変更されています。

Enhanced Class Decompiler 更新サイト:
https://ecd-plugin.github.io/update

# 経緯
このプラグインからユーザ情報などが送信されていると Eclipse マーケットプレースに最初の報告があり、Eclipse メンバーにより調査され、環境変数などの送信や、100 クラス逆コンパイルすると広告 1 クリックするなどの動作と思われる実装が見つかりました。しかし、このプラグインは GitHub に公開されているソースコードには該当コードが含まれておらず、配布されているバイナリにのみ含まれていることが判明しました。

その結果、Eclipse マーケットプレースから強制削除され、同プラグインの配布サイトとなっている cpupk.com のドメインレジストラにも無効要求が提出されています。並行して作者にも、この内容は報告され、問題のコードを除去するためのプルリクエストも送られましたが対応されず、今でも作者のサイトでバイナリが配布されています。気に入らない方はアンインストールしてくださいとのことです。
DockerHubでDockerfileのRUNコマンドのエラーを無視する

Dockerhubに登録した際にRUNに書いたコマンドが
0以外の終了値を返すためにビルドに失敗していたので回避するためのTips

```
RUN (終了コードが0以外のコード) ; exit 0
```

` ; exit 0` を追加してあげればOK


参考 : https://stackoverflow.com/questions/30716937/dockerfile-build-possible-to-ignore-error
Rxで非同期処理とプログレス表示切り替えを分離する

雑記事です。

1. 画面遷移時に画面にプログレスを表示して、データ取得待ちを表示したい
2. `SwipeRefreshLayout`で画面をリフレッシュできるようにしたい

この2つを満たしつつ、2種類のプログレスの表示制御をするのがめんどくさくねというところから始まりました。

1は**画面にプログレスを出したい**、2は**`SwipeRefreshLayout`のプログレスを利用したい**という感じです。
非同期処理自体は全く同じですが、トリガーが違うみたいな状態。

```
public class FooFragment extends Fragment {

    FragmentFooBinding dataBinding;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        dataBinding = DataBindingUtil.inflate(inflater, R.layout.fragment_foo, container, false);

        // adapterとかの初期化

        dataBinding.swipeRefreshLayout.setOnRefreshListener(() -> {
            refresh().subscribe(dataBinding.swipeRefreshLayout::setRefreshing);
        });

        return dataBinding.getRoot();
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        refresh().subscribe(loading -> {
            dataBinding.progress.setVisibility(loading ? View.VISIBLE : View.GONE);
        });
    }

    private Subject<Boolean> refresh() {
        Subject<Boolean> loadingSubject = BehaviorSubject.create();
        
        mApiService.topics()
                .compose(bindUntilEvent(FragmentEvent.DESTROY_VIEW))
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .doOnSubscribe(disposable -> loadingSubject.onNext(true))
                .doFinally(() -> loadingSubject.onNext(false))
                .subscribe(
                        response -> {
                            adapter.setData(response.topics);
                        },
                        throwable -> Log.e(TAG, "fetch: ", throwable)
                );

        return loadingSubject;
    }
}
```

`Observable`の進捗を通知してやって`Subject`で返せば、処理を共通化しつつ、呼び出す側でプログレスを制御できるんじゃないかなっていうアプローチです。
【メモ】社内環境管理兼CI業務のために調査したツール群


CentOs7でyumができないとき
http://zero-config.com/centos/gnome-0001.html
yumでパッケージをインストールする下準備
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230875/

Dockerとは
https://thinkit.co.jp/story/2015/08/05/6284

Vagrantは何が便利か
https://dev.classmethod.jp/server-side/virtual-box-vagrant/

サーバ管理ツール　Chefとは
http://knowledge.sakura.ad.jp/tech/867/

kibanaとは
https://www.ossnews.jp/oss_info/Kibana

Elastic Searchとは
https://www.ossnews.jp/oss_info/Elasticsearch

【そのほか】
資料作成
http://blog.shin1x1.com/entry/improve-the-presentation-skills-for-beginners
SourceTreeで remote invalid username or password となってGithubと接続できない時の対策

表題通り。
新しいMacBookProの環境構築時におこったのでメモ。

# 環境
* macOS Sierra
* HTTPS でGithubに接続
* GithubのPrivateRepositoryへアクセスできない。
    * `remote invalid username or password` ってエラーが出る
* Preference(ja: `環境設定` ?) の Account (ja: `アカウント` ?)で、GithubへのログインはHTTPSでOK。
* Githubへは二段階認証を設定してある
* MacBookProには、GPGが設定されている

# 対策1 - Gitのバージョンアップ

[Sourcetree remote: Invalid username or password](https://stackoverflow.com/questions/45622960/sourcetree-remote-invalid-username-or-password) より、Gitの不具合である可能性がある

Gitの　バージョンアップは以下が参考になった。
https://qiita.com/suzutan/items/44bcf20df711675c525c
※ 僕は2.10.x 系で治りました。


# 対策2 - 再ログイン / 再設定

1. Accountから削除。
2. RepositoryのREMOTESから削除。
3. SourceTree再起動
4. 治っているか確認


# 確認 - Repository Browser での表示確認

ログイン出来ていれば、GithubのPrivateRepositoryが参照できるはず。
Fetchするより早く確認ができる。


# MEMO
上記すべてをきちんとやると大丈夫になった。
原因はGitの不具合でないかと疑ってる。
GitとSourcetreeについての備忘録

※画像も載せたかったですが、一部仕事上問題ありますのでテキストだけです。

#GitとSourcetreeが使いづらい件
Backlogを通して、Gitを使ったバージョン管理を行おうとした際。
どこをどう調べても、「サルでもわかる」のサイトを見てすらも、上手くいかなかった為、最終的にターミナルからいろいろやって使えるように至った経緯です。
(サルでもわかるのに僕にはわからなかった件......orz)

#僕の環境
使用PC:　MacBook Air
プロセッサ:　2.2 GHz Intel Core i7
メモリ:　8 GB 1600 MHz DDR3
グラフィック:　Intel HD Graphics 6000 1536 MB

各バージョン
・git: 2.14.1
・Sourcetree: 2.6.3

#やりたかったこと
上でも触れていますが、Backlogにリモートリポジトリがあるので、そこからクローンしてきてブランチ切って作業したかった訳です。
でも、URLからクローンしようとすると「パスが正しくない」という旨のエラーが出て先に進めない・・・
「git ブランチ」やら「git cloneできない」やら、思いつく限りのワードで検索したサイトでは以下のような解決方法が上がっていました。

・Git、あるいはSourcetreeそのものの不具合。
　バージョンダウンすれば上手くいった。

他にPC側のOSとの関係に触れている記事もありましたが......まぁ、僕はこれらでは改善しませんでした。

#実際に取った方法
**手順1.**
ターミナルで、クローンしてきたファイルを置きたいところまで移動。

```
~ user $ cd ~クローン先~
```
なお、「cd」はチェンジディレクトリの意ですが、これ、一足飛びにはいけません(いや、行く方法もあるのかもですが)。

```
~ user $ ls
Applications	Downloads	Music		ls
Desktop		Library		Pictures	ls.pub
Documents	Movies		Public
~ user $ cd Desktop
Desktop user$ 
```
というように「ls」で次行けるところ(現在の場所から開けるフォルダ)を確認してあげると行きやすいと思います。

**手順2.**
そちらまで到達したら、以下のコマンドを打ちましょう。

```
$ git clone "クローンしたいリモートリポジトリのURL"
```
※「""」は不要です。backlogでコピーしたURLをそのまま貼り付けましょう。

すると、仮に「git-practice」という名前のフォルダに「practice」という名前のリモートリポジトリからファイルをクローンしてきたとすると、リモートリポジトリに入っていたすべてのファイルが「git-practice」には入ります。
ターミナルで見ると以下のようになるわけですね。

```
$ pwd (←現在地を調べるコマンド)
..(userやDesktopなど)/git-practice
$ ls
practice
```

**手順3.**
Sourcetreeを起動し、上にある「新規...」をクリックしましょう。

「ローカルリポジトリを作成」をクリックすると配置する場所を聞かれますので、先ほどクローンしてきたフォルダ(**「git-practice」ではなく、クローンされてその中に入った「practice」**)を選びます。

それでローカルリポジトリは完成です。

**手順4.**
Gitでバージョン管理をするにあたり、一人で作業しているなら問題ありませんが、複数人で作業をしている場合、絶対にやってはいけないこと。
**「masterへのpush」**です。
なので、いの一番にやるべきことがあります。
ブランチを切りましょう。

完成したローカルリポジトリをダブルクリックして開くと、開いたSourcetree画面の上の方に「ブランチ」というスイッチがあります。
そちらを押して、自身の名前のブランチを作成してください。

その後、左にある、最初はmasterしか表示されていないブランチ欄にあなたの名前のブランチが作られます。
それをダブルクリック(「ブランチをチェックアウトする」と言います)しましょう。

**手順5.**
これでコミットするまでの準備は完了です。
もし、リモートの欄が空......つまり未登録になっていたら、この後プッシュするためにも、右上の設定からリモートを登録してあげてください。

ここまできたら、一回何らかの変化をコミットしてあげるとプッシュできるようになりますので、**プッシュ先がoriginになっていることを確認してからプッシュ**しましょう。

Backlog上のブランチのページで見れば、あなたの名前(設定したブランチ名)のブランチが作成されているはずです。


###PS.もし、ローカルリポジトリを何らかの理由でいじってしまい、Sourcetreeに入れなくなった場合

僕はフォルダ名をいじったら「どこか行ったか、削除されてしまいました」として入れなくなりました。
この時、普通に移動、または変更したフォルダを指定しても上手くいきません。
(僕の場合はそうでしたが、必ずしもそうとは限りません)

ですので、管理していたフォルダ、ファイルの内容を一旦別フォルダに退避させ、新しく空フォルダを用意してそこにまたターミナルでクローン。

そのフォルダをローカルリポジトリとして、またSourcetreeで設定。
Sourcetreeを起動し、左のリモートの欄を確認。
origin以下のところに自分のブランチが残っていると思います。
これをダブルクリックすると追跡するか、みたいなことを聞かれますのでOKします。
これで、今までの状態に戻ります(ローカルリポジトリの内容は別)。

その後普通にフォルダを開いてあげて、退避しておいたファイルで、クローンして元に戻ってしまっている内容を置き換えます。
するとSourcetreeの方で「変更があった数とその内容」が表示されますので、コミットして、プッシュしましょう。

これで本当に終了！
元のリモートリポジトリと繋がった、新たなローカルリポジトリの完成です。
　

ローカルリポジトリのフォルダ名はよく考えてから設定して、変えないようにしましょう(^_^;)
　

僕は同じような名前のフォルダを量産してしまって整理していたらそんなことになってしまいました......
覚書：PHPとRubyの文法互換

# クラス定義

## クラス●●とは
インスタンス個別ではなくクラスで共有されるものを指す言葉としてここでは用いる

## インスタンス●●とは
クラス共通ではなくインスタンスごとに区別されるものを指す言葉としてここでは用いる

```php:php

class NewClass extends SuperClass
{
    # クラス定数
    const CONST_VAR = null;

    # クラス変数
    public static $staticVar = null;
    # インスタンス変数
    public $instanceVar = null;

    /***************************************
     * コンストラクタ
     ***************************************/
    public function __construct()
    {
        /*********************************************
         * クラスメソッド・インスタンスメソッド共通の事柄
         *********************************************/
        // クラス定数へのアクセス
        echo(static::CONST_VAR);
        // クラス変数へのアクセス
        echo(static::$staticVar);
    }

    /***************************************
     * インスタンスメソッド
     ***************************************/
    public function publicFunc()
    {
        // インスタンスメソッド -> インスタンス変数へのアクセス
        $this->instanceVar = null;
        
        return $this->instanceVar;
    }

    /***************************************
     * クラスメソッド
     ***************************************/
    public static function publicStaticFunc($var1, $var2 = null)
    {
        return $var;
    }
}

// インスタンス生成
$obj = new NewClass();

// クラス定数の参照
NewClass::CONST_VAR;

// クラス変数の参照
NewClass::staticVar;

// クラスメソッドの呼び出し
NewClass::publicStaticFunc(1);

```

```ruby:ruby

class NewClass < SuperClass
  # クラス定数
  # クラス宣言中（メソッド内を除く）で、先頭が[A-Z]で宣言された変数は、クラス定数となるらしい
  CONST_VAR = nil

  # クラス変数
  @@staticVar = nil

  # これはクラスインスタンス変数といって、PHPでいうインスタンス変数ではないらしい。
  # その差異の最たる性質として、例えばインスタンスメソッドからは利用できないということだ。
  # ややこしそうなので使わないでおこう。
  #@classInstanceVar

  ##########################################
  # コンストラクタ
  ##########################################
  def initialize()
    ##############################################
    # クラスメソッド・インスタンスメソッド共通の事柄
    ##############################################
    # クラス定数へのアクセス
    puts CONST_VAR
    # クラス変数へのアクセス
    puts @@staticVar

  end

  ##########################################
  # インスタンスメソッド
  ##########################################
  def publicFunc()
    # インスタンスメソッドの中でこう書くと、インスタンス変数になるらしい。
    # インスタンスメソッド -> インスタンス変数へのアクセス も当然こうなる。
    # 未定義のインスタンス変数へアクセスした場合、nilが返るらしい。
    @instanceVar = nil

    return 
  end

  ##########################################
  # クラスメソッド
  # self.* で実現
  ##########################################
  def self.publicStaticFunc(var1, var2 = nil)
    return var1
  end
end

# インスタンス生成
obj = NewClass.new()

# クラス定数の参照
NewClass::CONST_VAR

# クラス変数の参照
NewClass::staticVar

# クラスメソッドの呼び出し
NewClass.publicStaticFunc(1)
# もしくは
NewClass::publicStaticFunc(1)

```

# コメント

```php:php

// 一行コメント
# 一行コメント

/*
    複数行
    コメント
*/

```

```ruby:ruby

# 一行コメント

=begin

  複数行コメント。
  ただし開始/終了の修飾子は行頭に書かないといけないので、インデントが崩れるっぽい。
  なのでこっちは使わず一行を駆使した方がよさそう。
  複数行が簡単にできないと、コメントつけるのをサボりがちになるので気をつけたい。

=end

```

# エラー処理

```php:php

try {
    ;
} catch (Exception $e) {
    throw $e;
} finally {
    ;
}

```

```ruby:ruby

begin
  
rescue StandardError => e
  raise e
  # もしくは
  raise $!
ensure
  
end

```
ip指定で接続できるが、pingが通らないときに、確認することメモ

# 概要

現状把握するための、リスト

# まとめ

ネットワークがつながっているかの切り分け

```
ping www.google.com
ping 8.8.8.8
```

DNSがどうなっているか（もっと詳しく調べたほうが良いかもしれない）

```
cat /etc/resolv.conf
```

現在のipの確認

```
ip a
/sbin/ifconfig
```

現在の route の確認

```
route -n
```

# その他、参考情報

非常におもしろかったので、ぜひ読んでみてもらいたいです。

* [「ネットワークの調子が悪い」ときの原因の見つけ方 – ymyzk’s blog](https://blog.ymyzk.com/2017/12/how-to-find-network-connectivity-problems/)
初めての自動テストを読んで

#　どんな本
- - -
- [オライリー本](https://www.oreilly.co.jp/books/9784873118161/)
- WEBシステムための自動テストの入門書
- ターゲットは、主にプログラマーとテスター

- - -
- UI、統合、ユニットテストを解説
   - ピラミッド構造になっている
   - 上から順に、UI、結合、ユニットテストの層となっている
   - UI、統合、ユニットの順で解説している

- - -
![ピラミッド.png](https://qiita-image-store.s3.amazonaws.com/0/77089/6341b853-bfb3-4e96-1c88-bafa350286ec.png)
- - -
# テストの定義
- - -
## UIテストとは

- アプリをエンドユーザーが操作するのと同じようにテストするためのスクリプト
- クリック、タップ、選択、ログインなど、直感的にイメージできる
- アプリの全ての層を通過して、エンドツーエンド動く点が良いところ

- - -
## UIテストいろいろ
- スモークテスト
- CSSを使った要素の選択
- レガシーシステムにUIテストを追加する
- etc


- - -
## 結合テストとは
- 複数の層を一つにつなげるテスト全般のこと

- - -
## 結合テストいろいろ
- つながりのテスト
- UIテストでは見つけにくい下位レベルの不具合を発見する
- UIテストの堅牢生とユニットテストの機動性のバランスをとってくれる

- - -
##　ユニットテストとは
- メソッドレベルの小さなテスト
- 開発者が作成するテスト

- - -
##　ユニットテストいろいろ
- 細部のテスト
- 高速に実行でき、的が絞られており、手軽に実行できる
- 正しく動くことを保証する

- - -
# etc
- - -
- レガシーシステムにUIテストを追加する
- RESTfulなWebサービスの結合テスト
- jsを使ったブラウザ上のユニットテスト
- プログラミング初級講座
- 効果的なモックの活用
- テストファースト

- - -
# topic
- - -
## 親指の法則
1. UIよりもユニットテストを優先すること
2. ユニットテストで埋められない部分を結合テストでカバー
3. UIテストは限定的に使うこと

- - -
#　記載されている主な技術
- - -
- ruby,js,html
- Rails,jQuery
- test framework
  - Jasmine
  - RSpec
JobSchedulerの定義ファイルを手書きする

# JobSchedulerと他のツールの比較

バッチの実行にJobSchedulerを使っているのですが、わりかしこれが使いやすい。

## cron

新人時代はcronを使っていたりしましたが  

* 実行時のパスを通すのが面倒
* 再実行が面倒だったり
* いつジョブが実行されるかわかりにくい（未来のスケジュールが把握しにくい）

という面があります。

## Jenkins

Jenkinsでもいいのですが、こちらは自由度が高い反面

* いつジョブが実行されるかわかりにくい（未来のスケジュールが把握しにくい）
    * これについては [Next Executions](https://wiki.jenkins.io/display/JENKINS/Next+Executions) というプラグインがあります

は同様の不便さがあります、また

* ジョブの定義がGUIで決まるので、テキストファイルでジョブを管理できない
* 重い

みたいな問題もあります

# 定義ファイルの書き方

* 参考のため、標準出力にHelloなどと出すだけのジョブを作ってみました

必要なファイルは以下の通りです。

```
sample
├── sample.job.xml
├── sample.schedule.xml
├── sample_chain,sample.order.xml
└── sample_chain.job_chain.xml

0 directories, 4 files
```

## 定義ファイルの中身

気になったところのみコメントします

* ジョブ本体
    * `job order="yes"` にすると、そのジョブはジョブのオーダー単位でしか動かせなくなります（本番用）
    * `job order="no"` にすると、そのジョブは単体でも動きます。テストではとても有効です

```xml:sample.job.xml
<?xml version="1.0" encoding="ISO-8859-1"?>


<job  order="yes" stop_on_error="no">

    <script  language="shell">
        <![CDATA[
echo "Hello, JobScheduler !!!"
        ]]>
    </script>

    <delay_order_after_setback  setback_count="1" is_maximum="no" delay="00:01"/>

    <delay_order_after_setback  setback_count="2" is_maximum="yes" delay="0"/>

    <run_time />
</job>

```

* スケジュール設定ファイル
    * いろいろスケジュールを設定できます
    * `<day>` のタグは月～日が１～７までの数値で表されます

```xml:sample.schedule.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<schedule>
    <weekdays>
        <day day="1 2 3 4 5 6 7">
            <period single_start="13:32" when_holiday="ignore_holiday"/>
        </day>
    </weekdays>
</schedule>
```

* オーダー設定ファイル [XML Element \<run_time\>](http://www.sos-berlin.com/doc/en/scheduler.doc/xml/run_time.xml)
    * ここで初めてタイムゾーンが設定できます、サーバ設定時間がUTCでも動くので楽です
    * `<run_time schedule="スケジュール設定ファイル">` でジョブの実行時間をスケジュール設定ファイルに委任します

```xml:sample_chain,sample.order.xml
<?xml version="1.0" encoding="ISO-8859-1"?>

<order >
    <run_time schedule="sample" time_zone="Asia/Tokyo" />
</order>
```

* ジョブチェイン設定ファイル
    * 実際はこの中で連続したジョブを設定したりするのですが、今回はサンプルなのでほぼ空です 

```xml:sample_chain.job_chain.xml
<?xml version="1.0" encoding="ISO-8859-1"?>


<job_chain orders_recoverable="yes" visible="yes">

    <job_chain_node  state="sample" job="sample" next_state="end" error_state="end" on_error="setback"/>

    <job_chain_node  state="end"/>

</job_chain>
```
GKE で永続化ストレージに SSD を使う

# はじめに

* Google Container Engine で永続ボリュームである PsersistentVolume 及び、永続ボリュームのプロビジョニングを行う PersistentVolumeClaims 及び、状態を持った Pod のプロビジョニングを行う StatefulSet の volumeClaimTemplates オプションでそれぞれ SSD を使用してみる。

# StorageClass の定義

* SSD 用の StorageClass を定義する

```yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1beta1
metadata:
  name: ssd
  annotations:
    storageclass.beta.kubernetes.io/is-default-class: "false"
  labels:
    kubernetes.io/cluster-service: "true"
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd
```

# PsersistentVolume で SSD を使う

* `storageClassName` に先ほど定義した `ssd` を指定すると SSD を使えるようになる

```yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: ssd
```

# PersistentVolumeClaims で SSD を使う

* こちらも同様に `storageClassName` に先ほど定義した `ssd` を指定すると SSD を使えるようになる

```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mypvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: ssd
  selector:
    matchLabels:
      release: "stable"
```

# StatefulSet で SSD を使う

* StatefulSet の volumeClaimTemplates 定義で SSD を使う場合はアノテーションで StorageClass を指定する

```yaml
apiVersion: apps/v1beta1
kind: StatefulSet
metadata:
  name: mystatefulset
spec:
  ...略...
  volumeClaimTemplates:
  - metadata:
      name: data
      annotations:
        volume.beta.kubernetes.io/storage-class: "ssd"
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 100Gi
```

# SSD を使えているか確認する

* 下記のコマンドを実行し結果が `0` なら SSD を使えており、`1` なら HDD を使っている
* 以下はマウントしたディスクが `/dev/sda` の場合

```
cat /sys/block/sda/queue/rotational
```
Jupyter NotebookでPythonの練習

Jupyter notebookを使ってPythonの練習をしてみます

#2. Jupyter Notebookを使ってPythonの基本を確認する
-[githubのPythonの練習サンプル](https://github.com/eggplnt/python_basic)を開き、画面右上の緑の「Download ZIP」ボタンを押してzipファイルをダウンロードします

<img width="1005" alt="スクリーンショット 2017-10-12 17.03.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/125842/844297a3-4879-d409-110f-ede085e8090f.png">

- Python3.6を使用するなどPython実行に仮想環境(virtualenvなど）を使用している場合、まだactivateしていない（`(xx)`プロンプトが表示されていない）場合、`source xx/bin/activate`でPython実行用仮想環境をactivateします。プロンプトに`(xx)`が表示されます

```:Python実行用仮想環境をactivateする
MacBook-Pro:tftest tohru$ source py3/bin/activate
(py3) MacBook-Pro:tftest tohru$ 

```

- `jupyter notebook`と入力し、jupyter notebookを起動させます。
- jupyterを未インストールの場合、Python2.x 環境であれば`pip install jupyter`で、Python3.x環境であれば`pip3 install jupyter`ででインストールします

```
(py3) MacBook-Pro:Python_basic tohru$ ls
Python_basic.ipynb
(tf) MacBook-Pro:Python_basic tohru$ jupyter notebook

```

- Jupyter notebookのメニューが表示されるので、「Python_basic.ipynb」を選択して実行します。


<img width="404" alt="スクリーンショット 2017-10-12 17.03.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/125842/74ebe3d1-7cfa-07ff-4d64-45934179451d.png">

<img width="1158" alt="スクリーンショット 2017-10-12 17.04.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/125842/c4d967b7-0f5d-8a37-2a96-75c596a42434.png">


　- このjupyter notebookの内容は[https://github.com/eggplnt/python_basic/blob/master/python_basic/Python_Basic.ipynb](https://github.com/eggplnt/python_basic/blob/master/python_basic/Python_Basic.ipynb)で確認できます
　<img width="507" alt="スクリーンショット 2017-10-17 7.46.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/125842/399b160f-a437-c1af-271e-293c92b4840b.png">
Unityで内部解像度を引き上げる・引き下げる

# 概要
ゲームを作ってるとたまに内部解像度を上げたり下げたりしたくなる時があります
BF4で言う解像度スケールとか他では内部レンダリング解像度とか言われるものですね
50%等下げればFPS稼ぎに使えますし、200%とかにすれば非常にキレイな描画が期待できます

UnrealEngineではPostProcessにScreen Percentageという項目があるのですがUnityには見当たりませんでした…（あったらコメント欄にて指摘頂けると幸いです）

Screen.SetResolutionだとスマホだと良いかもしれないけどPC環境だとウィンドウごと小さくなるし
けどフルスクリーンにはしたくないし…というちょっとニッチな層向けの解説になります

# 方法
凄い悩んだ割に超簡単にできました

### RenderTexture作成
新しくRenderTextureを用意します、RenderTextureの設定で内部解像度にしたいサイズに変更してください(4k解像度にしたい場合は3840x2160等)
![RenderTexture作成](https://qiita-image-store.s3.amazonaws.com/0/131480/e07e5ca3-02c0-d0d3-7686-dd9a1381cd95.png)
### カメラの設定変更
メインカメラのTarget Textureに先程作成したRenderTextureを指定します
![RenderTexture指定](https://qiita-image-store.s3.amazonaws.com/0/131480/ddccfed5-51bd-7720-27a3-95ebe89a5787.png)
### RawImage作成
Hierarchy内部を右クリックしてUI→RawImageで新しくRawImageを作成します
![RawImage作成](https://qiita-image-store.s3.amazonaws.com/0/131480/8db0833a-c7f9-fc3f-f757-aeb3bab895b4.png)
### RawImage設定変更
RawImageが画面いっぱいになるように調整した後表示する画像に先程作成したRenderTextureを指定します
![RenderTextureを指定](https://qiita-image-store.s3.amazonaws.com/0/131480/10fdbe0d-2b39-da8b-a69d-463714508e00.png)
### 終わり

# 結果
低解像度(640x400) : FPS180
![LowRes.png](https://qiita-image-store.s3.amazonaws.com/0/131480/21369449-5fe8-34e3-b635-d1b1c08b37de.png)
---
中解像度(1920x1080) : FPS80
![MidRes.png](https://qiita-image-store.s3.amazonaws.com/0/131480/4eb1dfb0-429d-d417-5b98-919b0898bb07.png)
---
高解像度(3840x2160) : FPS30
![HiRes.png](https://qiita-image-store.s3.amazonaws.com/0/131480/b2917832-e942-f82c-e10a-811dbe78a7f8.png)
---

こうしてみると結構違います＆FPSの差も割りとありますね

# 解説
メインカメラの映像をRenderTextureの解像度で描画してUIのRawImageとして表示しているだけになります。
一応低解像度にしたらｼﾞｬｷﾞｼﾞｬｷﾞ＋FPS値が上がるのを確認し、4Kとかにすると高精細＋FPS値が低くなったので一応目的の挙動は達成できたと思います
但しRenderTextureに一度転送した後に表示しているので微妙にコストが掛かりそうな予感がします…
スマホ向け等少しパフォーマンスにシビアな場合は素直にScreen.SetResolution等を使いましょう

# 2017/11/16追記 問題点
**この方法を使用した場合マウスやタップした位置をワールド座標に変換する処理などで問題が発生する場合が有りますので注意してください**
ubuntu14.04 + GTX TITAN X に cuda + cudnn をインストール

# 動作確認済み
Ubuntu 14.04 + GeForce GTX TITAN X
Ubuntu 14.04 + GeForce GTX 1070


# 事前準備
環境はまっさらな方がいい.
cudaを入れるとnvidia driverも一緒に入るので、
nvidia driverは消しておいたほうがよい。

```
sudo apt-get remove --purge nvidia-375 nvidia-375-dev nvidia-modprobe nvidia-opencl-icd-375 nvidia-prime nvidia-settings -y
```

# cudaをダウンロード&インストール
https://developer.nvidia.com/cuda-toolkit-archive

CUDA Toolkit 8.0 GA2　を選択（9.0は、要16.04）.
Linux -> x86_64 -> Ubuntu -> 14.04 -> deb (local)
と進み、
Base installerをダウンロードして、instructionに書いてある通り以下を実行.

```
sudo dpkg -i cuda-repo-ubuntu1404-8-0-local-ga2_8.0.61-1_amd64.deb
sudo apt-get update
sudo apt-get install cuda
```

以下を.bashrcに記述.cudaのバージョンは自分の環境を確認し適宜変更.

```
export PATH=/usr/local/cuda-8.0/bin:$PATH
export LD_LIBRARY_PATH=/usr/local/cuda-8.0/lib64:$LD_LIBRARY_PATH
```

## cudaの確認
```
$ nvcc --version
```
を実行して, 

```
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2016 NVIDIA Corporation
Built on Tue_Jan_10_13:22:03_CST_2017
Cuda compilation tools, release 8.0, V8.0.61
```
みたいに表示されたらok

# cudnnをダウンロード&インストール.   
https://developer.nvidia.com/cudnn
7.0以上はまだ対応していないもの(chainerなど)も多いため、6.0が推奨(2017/10/12)

Download -> アカウント作成 -> 同意 -> 
-> Download cuDNN v6.0 (April 27, 2017), for CUDA 8.0
-> cuDNN v6.0 Library for Linux


解凍して、cudnn関係のファイルを, /usr/local/以下にcpしてパスを通す.

```
cd Downloads
tar zxvf cudnn-8.0-linux-x64-v6.0.tgz 
sudo cp cuda/include/* /usr/local/cuda/include/
sudo cp cuda/lib64/* /usr/local/cuda/lib64/
```

# cudnnの確認
```
/usr/local/cuda/include/cudnn.h
```
の

```
#define CUDNN_MAJOR      6
#define CUDNN_MINOR      0
#define CUDNN_PATCHLEVEL 21
```
で、versionが確認できる.
ASP.NETでCookieの有効期限を本日限りに設定

開発メモ

    //有効期限を設定
    var expires = DateTime.Today.AddDays(1);

    var cookie = new HttpCookie("hoge")
    {
        Value = "本日限り",
        Expires = expires,
        HttpOnly = true
    };
    HttpContext.Response.Cookies.Add(cookie);

　
FireFoxで確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/187859/a2f08c75-cf79-26a6-9aa9-6e4f223f74cf.png)
iPhone Simulator 関連自分用メモ 

・インストール済みのシュミレーターリストを表示
xcrun instruments -s

・シュミレーターを起動
xcrun instruments -w "リストで表示されたID"

・シュミレーターに他のシュミレーターの.appを追加
xcrun simctl install booted ".appのpath"

・シュミレーターのpath
/Library/Developer/CoreSimulator/Devices
Gliffyダイアグラムで矢印がくっつかないオブジェクトに矢印をくっつける裏ワザ

Atlassian社でお馴染みのConfluenceに「Gliffyダイアグラム」というマクロがあります。
このマクロ、ExcelのようでExcelでない、なかなか難儀なものなのですが
慣れてくると色々な図を作ることができて便利です。
UML作成などに利用されている方も多いかと思いますが
特にイライラしがちな
「特定オブジェクトに矢印がくっつかない現象」
の裏ワザ的解決方法を思いついたので手順をまとめました。

※基本的には、UML系オブジェクトには矢印がくっつくようになっています。
　今回の対象は画像系オブジェクトです。

みなさんのストレス解消になれば幸いです。

1.「コンテナコンテンツ」など矢印をくっつかないオブジェクトのXY座標および縦横幅を覚えておく
![WS000482.JPG](https://qiita-image-store.s3.amazonaws.com/0/198920/70c18f04-dbaa-8852-5394-c2196c25b128.jpeg)

2.上段メニューにある「長方形ツール」などで適当な長方形オブジェクトを生成する
![WS000483.JPG](https://qiita-image-store.s3.amazonaws.com/0/198920/9f9c14b4-1cfc-9796-25dd-0a5dc87a5035.jpeg)

3.手順2で生成した長方形オブジェクトのXY座標および縦横幅を手順1で覚えておいたXY座標および縦横幅と同じにする
　※または縦横幅を少し大きめにすると良いと思います。
![WS000484.JPG](https://qiita-image-store.s3.amazonaws.com/0/198920/43a74814-7a61-d3ba-41dc-d732984029d6.jpeg)

4.長方形オブジェクトの背景を透明に、枠線の色を白など目立たない色にする
![WS000485.JPG](https://qiita-image-store.s3.amazonaws.com/0/198920/7da309a4-147f-21d1-8bff-46c82ecf026f.jpeg)

5.長方形オブジェクトを選択して「後ろへ送る」ボタンで矢印がくっつかないオブジェクトの背面に移動する
![WS000486.JPG](https://qiita-image-store.s3.amazonaws.com/0/198920/f15f0f20-7b0b-8acf-662b-8aba4d34fec0.jpeg)

6.長方形オブジェクトと矢印がくっつかないオブジェクトを選択してグループ化する
![WS000487.JPG](https://qiita-image-store.s3.amazonaws.com/0/198920/475bde3d-b1de-8f7e-24f3-6f789619eebd.jpeg)

7.矢印がくっつかなかったオブジェクトに矢印がくっつくようになる！
![WS000488.JPG](https://qiita-image-store.s3.amazonaws.com/0/198920/968aa08f-e1ee-cca7-5a64-a9c14171315a.jpeg)
【環境構築編】pythonで日本語言語解析入門 多分コピペでだいたい動くよ((φ(-ω-)

# brew install pyenv
これで既存のpythonと干渉しなくなる

``` bash:bash.rc
eval "$(pyenv init -)"
```

pythonと解析プログラムであるmecabインストール
anacondaは統計や数学系統のライブラリ詰め合わせ

```bash:commands
brew install pyenv
pyenv install 3.6.3
pyenv global 3.6.3
pyenv global anaconda3-5.0.0
brew install mecab
brew install mecab-ipadic
pip install mecab-python3
touch mecab_01.py
```

プログラム書くよ(｀・ω・´)

```python:mecab_01.py
import MeCab
mecab = MeCab.Tagger("-Ochasen")
print(mecab.parse("この銀河を統括する情報統合思念体によって造られた対有機生命体コンタクト用ヒューマノイド・インターフェース、それがわたし。"))
```

実行するよ((φ(-ω-)

```bash:commands
python mecab_01.py
```


終わり、簡単、楽しいヾ(呂╹◡╹✿)ﾉ”

![image.png](https://qiita-image-store.s3.amazonaws.com/0/69647/6b6ccea4-7c94-f465-a7f9-c5c8df4f88bc.png)
初心者：30行目にエラーがでます。どこを直せばいいかわかりません。

以下の文で、30行目にエラーがでます。どなたかわかるかた教えていただけないでしょうか？
※30行目に☆がしてあります。

import java.util.Scanner;

class Main {
  public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    
    System.out.println("名前：");
    String firstName = scanner.next();
    System.out.println("名字：");
    String lastName = scanner.next();
    System.out.println("年齢：");
    int age = scanner.nextInt();
    System.out.println("身長(m)：");
    double height = scanner.nextDouble();
    System.out.println("体重(kg)：");  
    double weight = scanner.nextDouble();
    
    sub(firstName,lastName,age,height,weight);
  }  
    
  public static void sub(String firstName, String lastName, int age, double height, double weight)
  {
    System.out.println("名前は"+firstName+" "+lastName+"です");
    System.out.println("年齢は"+age+"歳です");
    if(age>=20){System.out.println("成年者です");}
    else{System.out.println("未成年者です");}
    System.out.println("身長は" +height+ "mです");
    System.out.println("体重は" +weight+ "kgです");
    System.out.println("BMIは" + Math.round(bmi(weight,height)) + "です");
☆   if (isHealthy(bmi)){System.out.println("健康です");}
    else{System.out.println("健康ではありません");}
    
    
  }
    
  public static double bmi(double weight, double height){
   return weight / height / height;
  }
  
  public static boolean isHealthy(double bmi){
    return bmi>=18.5&&bmi<25;
    
  }
  
}
PHP学習でわからなかった関数（sprintf）

#sprintf関数
第二引数の値を第一引数の形式に指定する

参照　https://secure.php.net/manual/ja/function.sprintf.php

http://www.php-ref.com/bapi/02_sprintf.html

上記より、「%d」で10進法の整数として形式が指定される
（『%』の後に、フォーマットのルールを書いていきます）
ニフティクラウドL４ロードバランサをNAPTルータっぽく使ってみる

# はじめに
普段負荷分散目的でL４ロードバランサを利用するのですが、ポートのカスタマイズとフィルタリングを利用することによってSSHやFTP等のアクセス振分けを実装することができます。

例えば、
x.x.x.x（ロードバランサVIP）:10001のアクセスをサーバ#1:22とし、
x.x.x.x（ロードバランサVIP）:10002のアクセスをサーバ#2:22とする
のようなことです。

ただし1ロードバランサあたりのポート設定数が３つまでの制約があるのであっという間に埋まってしまいますが。。。

# 前提条件
* 仮想サーバ（インスタンス）を立てていること  
※今回は便宜上apacheをインストール済

# 手順
1.ロードバランサを作成
ニフティクラウドコントロールパネルからロードバランサ作成画面へ遷移し作成します。
![スクリーンショット 2017-10-12 14.10.19.png](https://qiita-image-store.s3.amazonaws.com/0/23761/6331b91e-28ee-2eb8-ad69-515efd43fa25.png)
とりあえずデフォルトのまま作成します。
![スクリーンショット 2017-10-12 14.12.57.png](https://qiita-image-store.s3.amazonaws.com/0/23761/ae2bf181-1290-73d5-2fd1-ea1a5b7379d4.png)

2.ロードバランサの受けポート追加
SSH用に受けポートを追加します。ここでは10001 -> 22にします。
![スクリーンショット 2017-10-12 14.20.14.png](https://qiita-image-store.s3.amazonaws.com/0/23761/405f7eec-d151-8a5c-a047-2d4ce642b9cf.png)


次に[設定変更]から、[フィルター設定]へ進み、接続元アクセス制限を掛けます。
このままこ確認画面まで進み完了します。
![スクリーンショット 2017-10-12 14.31.01.png](https://qiita-image-store.s3.amazonaws.com/0/23761/62b1c11d-ae94-bb7b-49ef-692c957d87d7.png)

次に[サーバ接続]から接続先のサーバを指定します。
![スクリーンショット 2017-10-12 14.33.27.png](https://qiita-image-store.s3.amazonaws.com/0/23761/e5db24d6-ea78-4690-a5d9-63bb1f68ae3a.png)

完了後、ヘルスチェックのステータスが緑になっていればOK
![スクリーンショット 2017-10-12 14.34.48.png](https://qiita-image-store.s3.amazonaws.com/0/23761/a8950fac-5091-445f-f460-f0806304fec6.png)

3.FW追加設定
このままだとFW側で弾かれてしまうので許可設定を追加します。
![スクリーンショット 2017-10-12 14.25.26.png](https://qiita-image-store.s3.amazonaws.com/0/23761/1bd7233e-1ea1-4b70-5571-e235536e04f1.png)

4.接続確認
最後に接続確認をしてみます。
※鍵ファイル、ユーザ名、IPアドレス（またはホスト名）は適宜変えてください。

```:command
$ssh -i /path/to/keyfile -p 10001 [username]@[LBのipアドレス]
Last login: Thu Oct 12 14:29:51 2017 from [LBのipアドレス]
[username@localhost ~]# 
```
ログインできた。
# 最後に
ファイアウォール側の設定もロードバランサのIPのみ許可にすると外部からのアクセスが絞られるので、
セキュリティの向上が少し見込まれるのではと感じております。
過不足等ありましたら指摘いただけると幸いです。


# 参考
http://cloud.nifty.com/service/lb_l4.htm