OmniAICreator/Qiita-1.07M huggingface dataset:
ボクセルデータをPythonでデータ拡張する

データ拡張とは機械学習モデルを作成するとき、モデルの汎化性能を向上させるための追加データとして、元データに加工を施してデータを増やすことです。

例えば画像の場合には、元画像を反転する、水平・垂直にピクセルを移動させる、ノイズをピクセル値に加える等の方法が典型的です。

3Dデータの一種にはボクセルデータ(x, y, zの3次元格子をもつ、2次元画像データの拡張)があり、CADモデルやCTスキャンのデータがこの形式で表されることがあります。
このボクセルデータを対象にして、3D CNNで分類やセグメンテーションを行う、といったケースに用いられています。

本記事では、Pythonのscipyとnumpyを使ってボクセルデータの拡張データを生成してみます。
(拡張データを使った学習は本記事では扱いません。)

# 拡張元データ
PRINCETON MODELNETの10クラスのものを使用しています。
http://modelnet.cs.princeton.edu/

MODELNETのデータを32 × 32 × 32のサイズのarray型にして用いています。

```Python
print(type(data))
# >>> <class 'numpy.ndarray'>

print(data.shape)
# >>> (1, 32, 32, 32)
```

各格子は、0(物体が存在しない) or 1(物体が存在する)のどちらかの整数の値を持ちます。
下図はサンプルと、図に対応する各軸の方向です。

<img src="https://qiita-image-store.s3.amazonaws.com/0/285894/4d0cfdac-8fc2-d949-61bd-c3df5ebf681d.png" width=50% height=50%
<img src="https://qiita-image-store.s3.amazonaws.com/0/285894/ac68cf3a-ce3b-3b58-aa6d-477b65fcdbdb.png" width=25% height=25%>

※環境
Python 3.6.2
scipy 0.19.1
numpy 1.13.3

# 反転
各軸方向に反転

```python
import numpy as np
# flip: x axis
np.flip(data, 1)

# flip: y axis
np.flip(data, 2)

# flip: z axis
np.flip(data, 3)
```

![flip1.png](https://qiita-image-store.s3.amazonaws.com/0/285894/cf1c76ac-57d7-8f5f-258f-4b7e3a1dcfd3.png)


# シフト
各軸正方向に1辺の長さの0.3割ずつシフト

```python
from scipy.ndimage.interpolation import shift

# shift: x axis
shift(data, shift=[0, 0.3, 0, 0], cval=0)

# shift: y axis
shift(data, shift=[0, 0, 0.3, 0], cval=0)

# shift: z axis
shift(data, shift=[0, 0, 0, 0.3], cval=0)
```

![shift1.png](https://qiita-image-store.s3.amazonaws.com/0/285894/bb0ca7d1-872f-9252-2141-c84bd2a5676e.png)

# 拡大・縮小

**拡大**
各軸方向を1.5倍に拡大

```Python
from scipy.ndimage.interpolation import zoom

# zoom: x axis
zoom(data, zoom=[1, 1.5, 1, 1], cval=0)

# zoom: y axis
zoom(data, zoom=[1, 1, 1.5, 1], cval=0)

# zoom: z axis
zoom(data, zoom=[1, 1, 1, 1.5], cval=0)
```
zoomで返却されるデータは各軸方向に拡大率分サイズが大きくなるので、32×32×32になるように切り出しを行ったのが以下の図

![expand_1.png](https://qiita-image-store.s3.amazonaws.com/0/285894/8787c684-bc8a-f68a-4d25-0fc2017546ec.png)

**縮小**
各軸方向を0.5倍に縮小

```Python
from scipy.ndimage.interpolation import zoom

# zoom: x axis
zoom(data, zoom=[1, 0.5, 1, 1], cval=0)

# zoom: y axis
zoom(data, zoom=[1, 1, 0.5, 1], cval=0)

# zoom: z axis
zoom(data, zoom=[1, 1, 1, 0.5], cval=0)
```

zoomで返却されるデータは各軸方向に縮小率分サイズが小さくなるので、32×32×32になるように切り出しを行ったのが以下の図

![shrink.png](https://qiita-image-store.s3.amazonaws.com/0/285894/2f589be3-a1e0-cf5e-a266-fd03d4b06398.png)

# 回転

```Python
from scipy.ndimage import rotate

# Rotate: x axis
rotate(data, axes=(2,3), angle=45, cval=0.0, reshape=False)

# Rotate: y axis
rotate(data, axes=(3,1), angle=45, cval=0.0, reshape=False)

# Rotate: z axis
rotate(data, axes=(1,2), angle=45, cval=0.0, reshape=False)
```

![rotate_1.png](https://qiita-image-store.s3.amazonaws.com/0/285894/d9dd1597-ba65-39ab-c2eb-9102ee2dac68.png)


以上です。
scipyの多次元データライブラリーとnumpyを使って、ボクセルデータのデータ拡張ができました！
妖精で考えるMとVとVMとCとP

# はじめに
ぽえむ。
各説明に文献的根拠はありません。


# 本題

- MVVM
	- M:システム内の妖精さん。
	- VM:M妖精さんの中でも、Vという道具を持つM妖精さん。<br>
	その道具の力で外部に自身を見せたり、外部から命令を聞くことができる妖精さん。
	- V:VM妖精さんの持ち物。妖精さんが外部I/Oを可能とする道具。窓みたいな物。<br>
	これを持つことでM妖精さんからVM妖精さんにジョブチェンジできる。<br>
	~~最近は道具のくせに自我を持ちはじめ、VM妖精さんの居場所を占拠し、妖精さんに対して危害を加える事が可能な存在になった。危害を加えられないよう祈るしかない。~~
- MVC
	- M:システム内の妖精さん。
	- C:外部から命令を聞き、M妖精さんとV妖精さんを駆動させる妖精さん。<br>
	命令が無ければ動かないオペレーション型妖精さん。
	- V:外部へ自身を見せる妖精さん。<br>
	外部へ見せる時は、M妖精さんかC妖精さんの助言を聞いたりする。
- MVP
	- M:システム内の妖精さん。
	- P:自我のままにM妖精さんとV妖精を駆動させる妖精さん。<br>
	自己駆動型妖精さん。
	- V:外部へ自身を見せる妖精さん。<br>
	外部へ見せる時は、M妖精さんかP妖精さんの助言を聞いたりする。
Swift4.2 でのHome Indicatorの非表示

prefersHomeIndicatorAutoHiddenがメソッドからプロパティになったようです。

4.2以前

```swift
    @available(iOS 11, *)
    override func prefersHomeIndicatorAutoHidden() -> Bool {
        return true
    }
```

4.2

```swift
    @available(iOS 11, *)
    override var prefersHomeIndicatorAutoHidden: Bool {
        get {
            return true
        }
    }
```
Appium in Mac for iOSのトラブルシュート

#はじめに
[こちらの記事](https://qiita.com/emurin/items/a9ef9674308dd5cfcbac)を参考に進めたが、いろいろ嵌ったのでメモ。
#環境
| 環境 | バージョン |
|:--:|:--:|
|macOS|10.13.6|
|Xcode|9.4.1|
|Appium|1.9.0|
|iOS|11.4|
#UDIDの設定
iTunesのシリアル番号を使うという情報があったけど、自分の環境ではだめだった。

```
selenium.common.exceptions.WebDriverException: Message: An unknown server-side error occurred while processing the command. Original error: Unknown device or simulator UDID: '(シリアル番号)'
```

####解決方法
Xcodeを起動して、Window > Devices and Simulators > Identifierの値を設定する。
#test runに失敗

```
~/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent $ xcodebuild -project WebDriverAgent.xcodeproj -scheme WebDriverAgentRunner -destination 'id=$udid' test
(省略)
Testing failed:
	Signing for "WebDriverAgentRunner" requires a development team. Select a development team in the project editor.
	Code signing is required for product type 'UI Testing Bundle' in SDK 'iOS 11.4'
** TEST FAILED **

The following build commands failed:
	Check dependencies
(1 failure)
```

####解決方法
１）Xcodeから```WebDriverAgent.xcodeprj```を開く
２）TargetsからWebDriverAgentRunnerを選択
３）Generalタブ > Signingの```Automatically manage signing```にチェックを入れて、Teamは開発用のAppleIDを選択
４）Build Settingsタブ > Signing > Code Signing Identityは全て```iOS Developer```となるように設定
５）Provisioning Profileは```Automatic```のまま
６）macOSを再起動(これめっちゃ重要)

#Appium接続エラー

```
[Xcode] 2018-09-18 17:52:12.476 xcodebuild[2548:64487] Error Domain=IDETestOperationsObserverErrorDomain Code=6 "Early unexpected exit, operation never finished bootstrapping - no restart will be attempted" UserInfo={NSLocalizedDescription=Early unexpected exit, operation never finished bootstrapping - no restart will be attempted, NSUnderlyingError=0x7f8948a03d40 {Error Domain=NSCocoaErrorDomain Code=260 "The file “WebDriverAgentRunner-Runner.app” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Users/debug/Library/Developer/Xcode/DerivedData/WebDriverAgent-brdadhpuduowllgivnnvuygpwhzy/Build/Products/Debug-iphoneos/WebDriverAgentRunner-Runner.app, NSUnderlyingError=0x7f89489303f0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}}}
[Xcode]
[Xcode]
[Xcode] Testing failed:
[Xcode]
[Xcode] 	Signing for "WebDriverAgentRunner" requires a development team. Select a development team in the project editor.
[Xcode] 	Code signing is required for product type 'UI Testing Bundle' in SDK 'iOS 11.4'
[Xcode] 	Early unexpected exit, operation never finished bootstrapping - no restart will be attempted
[Xcode] ** TEST EXECUTE FAILED **
[Xcode]
[Xcode]
[XCUITest] xcodebuild exited with code '65' and signal 'null'
```

####解決方法
Appiumのdesired capabilityに```agentPath```と```bootstrapPath```を追加する

```
desired_capabilities={
    'app': 'com.apple.mobileslideshow',
    'udid': '$udid',
    'platformName': 'iOS',
    'platformVersion': '11.4',
    'deviceName': 'iPhone 6',
    'agentPath': '/Users/debug/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent/WebDriverAgent.xcodeproj',
    'bootstrapPath': '/Users/debug/node_modules/appium/node_modules/appium-xcuitest-driver/WebDriverAgent'
})
```
ひさしぶりにROOTを使ってみた

# はじめに

- 高エネルギー物理学分野で使われている解析フレームワーク ``ROOT`` を使ってみる
- ひさしぶりに使うので、とりあえずインストールからデモで遊ぶところまで

# ROOTのインストール

```bash:ROOTのインストール
$ brew install root

Because ROOT depends on several installation-dependent
environment variables to function properly, you should
add the following commands to your shell initialization
script (.bashrc/.profile/etc.), or call them directly
before using ROOT.

For bash users:
  . /usr/local/bin/thisroot.sh
For zsh users:
  pushd /usr/local >/dev/null; . bin/thisroot.sh; popd >/dev/null
For csh/tcsh users:
  source /usr/local/bin/thisroot.csh

Emacs Lisp files have been installed to:
  /usr/local/share/emacs/site-lisp/root
```

- ``Homebrew``を使ってインストールできた（とても簡単になってる！）
- 環境変数とかを設定する必要があるので、``bash``ユーザなどは書かれたとおりの設定ファイルを読み込む
- 僕は``fish``ユーザなので、よく分からない。けど、このまま進める
- ``Emacs``ユーザのための補完用``Lisp``もある


# ROOTの起動

```bash
$ root
   ------------------------------------------------------------
  | Welcome to ROOT 6.14/04                http://root.cern.ch |
  |                               (c) 1995-2018, The ROOT Team |
  | Built for macosx64                                         |
  | From tags/v6-14-04@v6-14-04, Aug 23 2018, 17:00:44         |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' |
   ------------------------------------------------------------
root [0]
```

- ``root``と打つと、青っぽい画面が表示され、ターミナルに上のガイドが表示される

# デモの起動

```bash
root [0] .demo
root [1]
```

- ``ROOT``の中で``.demo``と入力した
- ディスプレイの左端にメニューバーが表示された
- ``Help Demos``をクリックしたら以下の画面（``TCanvas``）が表示された


![chelp.png](https://qiita-image-store.s3.amazonaws.com/0/273122/f538875a-5c7c-bcd7-ed3a-f6607fe63895.png)


1. ``hsimple``を最初に実行する。あとはお好きな順番で。
2. 左クリックでデモを実行
3. 右クリックでデモのタイトルを表示
4. ...などなど


# デモを実行する前に

- デモを実行するといくつかファイルが生成されるので、デモ用のディレクトリを作成したほうがよい
【Excel】VBAを使わずにセルの内容によって表示する画像を変更したいときのやり方

エクセルを使っているとき、
「ココの表示は、セルの内容で分岐したい！」って時には、IF文で分岐しますよね。では、
「ココの画像は、セルの内容で分岐したい！」って時には、どうしますか？
答えは、
「画像を貼り付けた箇所のセルに名前をつけ、その名前で分岐した式に名前をつけ、その式の名前を図形オブジェクトに式として渡す」です！
今回は、1～5点の点数に応じて、1～5個の星を表示する方法を例として、解説していきます。

※この記事の内容は、Microsoft Office 365のExcelを対象としています。

# 0.サクッと準備
こんな感じのシートを用意しました。画像のとおりです。
![006.PNG](https://qiita-image-store.s3.amazonaws.com/0/137405/c4b849b9-6d79-36be-b7b3-556eeef0a864.png)
今回は、B3で星の数をコントロールしたいと思います。

# 1.Excelに画像を貼り付け、貼り付けた箇所に名前をつける
はい、文字で書くと面倒臭そうですが、やることは簡単です。
「images」という名前のシートを作成し、そのシートに![001.PNG](https://qiita-image-store.s3.amazonaws.com/0/137405/c8401ee3-bb44-a9f3-1c09-b1aff416ed2c.png)
こんな感じで画像を貼り付けてください。上から星5→星1ということになります。
貼り付けが終わったら、「A1～U5」までのセルを選択し、数式タブの「定義された名前」グループから「名前の管理」をクリックしてください。
にゅっとウィンドウが表示されると思うので、その中の「新規作成」をクリック。
下記のように入力してください。

|名称|入力内容|
|:-----------------|:------------------|
| 名前 | 星5|
| 範囲 |ブック |
| コメント |星5個のエリアです |
| 参照範囲 |=images!\$A\$1:\$U\$5|

※多分、範囲と参照範囲は最初から入力されていると思います。あと、コメントは入力なしでもいいです。名前はお好みで。
※A1～U5というのは、5個の星の画像をすっぽりと覆うようにセルを指定しているということです。


入力が完了したら、「OK」を押してください。
上記を星4個～星1個の場所までやってください（下の画像のようになっていればOKです）
![002.png](https://qiita-image-store.s3.amazonaws.com/0/137405/3113bf96-ec35-6306-7812-0388688ea965.png)


はい！これで第1ステップ「画像を貼り付けた箇所のセルに名前をつけ」が完了です。

# 2.分岐式に名前をつける
Excelでは、分岐にIF文を使用します。なので、文字列で星5～星1を分岐するには、こんな感じになります。
`=IF(B3 = 5, "星5個だよ", IF(B3 = 4, "星4個だよ", IF(B3 = 3, "星3個だよ", IF(B3 = 2, "星2個だよ", "星1個だよ")))) `

上の式の文字列の部分を、さっきつけた名前に置き換えます。
`=IF(B3 = 5, 星5, IF(B3 = 4, 星4, IF(B3 = 3, 星3, IF(B3 = 2, 星2, 星1)))) `

最後にこの式を名前をつけて登録します。
さっきと同じように、名前の管理から新規登録してください。


|名称|入力内容|
|:-----------------|:------------------|
| 名前 | 星表示分岐|
| 範囲 |ブック |
| コメント |星の出し分けを行います |
| 参照範囲 |=IF(B3 = 5, 星5, IF(B3 = 4, 星4, IF(B3 = 3, 星3, IF(B3 = 2, 星2, 星1))))|

下の図のようになっていればOKです！
![003.png](https://qiita-image-store.s3.amazonaws.com/0/137405/85bc28ad-7e73-68f0-e5cc-aeb9bce18063.png)


はい！これで第2ステップ「その名前で分岐した式に名前をつけ」が完了です。

次でいよいよ最後です！
# 3.画像を出し分ける
最後に実際に表示するエリアを作成していきます。
適当なセルを選択してコピーしてください。その後、右クリックして、「リンクされた図」ペーストをしてください。
※分かりづらいと思うので、図を貼っておきます。![003.png](https://qiita-image-store.s3.amazonaws.com/0/137405/05079ceb-2f43-d476-e329-2d2cc2df0da3.png)
ペーストすると、リンクされた図形オブジェクトが表示されます。
その図形オブジェクトを選択し、数式バーに
`=星表示分岐`
と入力すると、B3に入力されている数と同じ数の星が表示されると思います。
![004.PNG](https://qiita-image-store.s3.amazonaws.com/0/137405/eb0e0404-3dfe-7478-efd1-f12280effc05.png)

# ・・・なんか汚くね？
はい、なんかマス目が汚いですね。なので、少し調整をば。
imagesシートに移動して、表示タブの表示グループの「目盛線」のチェックを外してみてください。
戻ってくるとあら不思議、キレイに見えちゃうんです！![005.PNG](https://qiita-image-store.s3.amazonaws.com/0/137405/9aa1493e-c35e-02ce-67a6-cb8ff218b3be.png)

この状態で、B3の数字を変えれば、自由に星の数を出し分けることが出来ます。
また、imagesシートの画像を変えれば、いろいろな出し分けができるのです。

#最後に
この記事、Excel以外のタグが思いつかんのです。なにかいいタグがあったら教えてプリーズ！
それでは(`・ω・´）ﾉｼ
at coder beginner 023

今回は 23 回目の AtCoder Beginner Contest です。今回のコンテストは 5 月に開かれています。
高橋君は 23 という整数を見て、十の位と一の位に分割して足し合わせることによって、2+3=5 と現在の月と等しい数となることに気が付きました。
このことに興味を持った高橋君は、手元にあった 2 桁の正整数 X の各位の和を計算することにしました。
あなたの課題は、正整数 X の各位の和を求めることです。

```
#include<iostream>
#include<string>
using namespace std;
int main() {
	string X;
	cin >> X;
	int num = 0;
	for (int i = 0; i < X.size(); ++i) {
		num += X[i]- '0';
	}
	cout << num << endl;
	return 0;
}
```
一般化した。
B
高橋君は趣味でアクセサリーを作っている。
アクセサリーは a, b, c のいずれか 1 文字が書かれたブロックを横 1 列に並べることで作成できる。
高橋君は、以下の手順でアクセサリーの作成を行う：
手順 0 : 高橋君は b 1 文字からなるアクセサリーを作成する。
以降の手順では、既にあるアクセサリーの両端にブロックを 1 つずつ追加することでアクセサリーを改造する。
手順 3n+1(n≧0) : 手順 3n で完成したアクセサリーの左端に文字 a が書かれたブロックを、右端に文字 c が書かれたブロックを付け足す。
手順 3n+2(n≧0) : 手順 3n+1 で完成したアクセサリーの左端に文字 c が書かれたブロックを、右端に文字 a が書かれたブロックを付け足す。
手順 3n(n≧1) : 手順 3n−1 で完成したアクセサリーの左端に文字 b が書かれたブロックを、右端に文字 b が書かれたブロックを付け足す。
高橋君はアクセサリーの作成を好きな手順の直後に終了することができる。終了した場合、アクセサリーには、アクセサリーを構成するブロックに書かれた文字を左から右に読んだものと同じ名前が付けられる。
例えば、手順 0, 1, 2, 3 それぞれの直後にアクセサリーの作成を終了した場合、アクセサリーの名前は順に、b, abc, cabca, bcabcab となる。
文字列 S が与えられるので、その文字列がアクセサリーの名前として考えられるかを判定し、考えられるなら何番目の手順の直後にアクセサリーの作成を終了したのかを求めよ。


```
#include<iostream>
#include<string>
using namespace std;
int main() {
	int N;
	string S;
	cin >> N;
	cin >> S;
	int num = (N - 1) / 2;
	string b = "b";
	if (S == "b") {
		cout << 0 << endl;
	}
	else {
		for (int i = 1; i <= num; ++i) {
			if (i % 3 == 1) {
				b = "a" + b + "c";
			}
			else if (i % 3 == 2) {
				b = "c" + b + "a";
			}
			else {
				b = "b" + b + "b";
			}
		}
		if (S == b) {
			cout << num << endl;
		}
		else {
			cout << -1 << endl;
		}
	}
    return 0;
}
```

C
```
#include <iostream>
#include<vector>
#include<algorithm>
using namespace std;
using ll = long long;
int main() {
	int R, C, K, N;
	cin >> R >> C >> K;
	cin >> N;
	vector<int>a(N);
	vector<int>b(N);
	vector<vector<int>>vec(R, vector<int>(C, 0));
	for (int i = 0; i < N; ++i) {
		cin >> a.at(i) >> b.at(i);
		a.at(i)--; b.at(i)--;
		for (int j = 0; j < C; ++j) {
			vec.at(a.at(i)).at(j)++;
		}
		for (int k = 0; k < R; ++k) {
			vec.at(k).at(b.at(i))++;
		}
	}
	for (int i = 0; i < N; ++i) {
		vec.at(a.at(i)).at(b.at(i))--;
	}
	int count = 0;
	
	for (int i = 0; i < R; ++i) {
		for (int j = 0; j < C; ++j) {
			if (vec.at(i).at(j) == K)
				count++;
		}
	}
	cout << count << endl;
	return 0;
}
```
すべてのマスについて何個飴を取得できるか調べた。部分点解法。満点解法になるためには少しひねらなきゃあかんっぽい
Java で CSV をヘッダの名前ベースでデシリアライズする

コードは Kotlin だけどよしなに読み替えてください。

## 前提

* Excel は便利なのでこれを使ってまとめて書きたい。どかっと記述して CSV で取り込みたい。
* とにかくフィールドが多い、可変かもしれない、増えるかもしれないし減るかもしれない。

## やっていく

jackson-dataformat-csv を使えばできる。
https://github.com/FasterXML/jackson-dataformats-text/tree/master/csv

ドキュメントがかなりふわっとしていて難解だがやればできる。

```kotlin
import assertk.assert
import assertk.assertions.isEqualTo
import assertk.assertions.isNotNull
import com.fasterxml.jackson.annotation.JsonProperty
import com.fasterxml.jackson.annotation.JsonUnwrapped
import com.fasterxml.jackson.dataformat.csv.CsvMapper
import com.fasterxml.jackson.dataformat.csv.CsvSchema
import org.junit.Test

class DeserializeTest {
    enum class Country {
        JP,
        US
    }

    class Profile {
        @JsonProperty("age")
        val age: Int = 0

        @JsonProperty("country")
        val country: Country = Country.JP
    }

    class User {
        @JsonProperty("_id")
        val id: Int = 0

        @JsonProperty("name")
        val name: String = ""

        @JsonUnwrapped(prefix = "profile.")
        val profile: Profile? = null
    }

    @Test
    fun deserialize() {
        val mapper = CsvMapper()
        val schema = CsvSchema.emptySchema().withHeader()

        val reader = mapper.readerFor(User::class.java).with(schema)
        val users = reader.readValues<User>("""
name,_id,profile.age,profile.country
foo,3,17,JP
bar,2,21,US
        """.trim()).readAll()

        assert(users[0].id).isEqualTo(3)
        assert(users[0].name).isEqualTo("foo")
        assert(users[0].profile).isNotNull {
            assert(it.actual.age).isEqualTo(17)
            assert(it.actual.country).isEqualTo(Country.JP)
        }

        assert(users[1].id).isEqualTo(2)
        assert(users[1].name).isEqualTo("bar")
        assert(users[1].profile).isNotNull {
            assert(it.actual.age).isEqualTo(21)
            assert(it.actual.country).isEqualTo(Country.US)
        }
    }
}
```

ポイントは CsvSchema に型情報を与えないこと。
ここで型情報を渡すととにかくカラムの順序ベースでしかデシリアライズしてくれなくてはまる。
`@JsonUnwrapped` が地味にすごい。便利。
JavaBeans を要求されるので Kotlin で書いているなら non-null については諦めてください。悲しいですね。
dockerでさくっとJupyter-Notebookを試す

dockerでJupyter-Notebookをサクッと試すメモ

# まずはdocker pull
docker search したときにスターが最も多かった「jupyter/datascience-notebook」を使います。

```
$ docker pull jupyter/datascience-notebook
```
*※6.07GBもあったので時間かかります*

# コンテナの起動
```
$ docker run --rm -it -v $(pwd):/w -p 8888:8888 jupyter/datascience-notebook /bin/bash
```

* -v $(pwd):/w **ローカルのファイルをコンテナ上の/wにマウントする**
* -p 8888:8888 **Jupyter-Notebookのデフォルトポートが8888なのでローカルとコンテナのポートを割り当てる**

# Jupyter-Notebookの起動
```
$ cd /w
$ jupyter notebook
```
以下が表示される

```
    Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://(コンテナID or 127.0.0.1):8888/?token=XXXXXXXX
```
ブラウザから
http://127.0.0.1:8888/?token=XXXXXXXX
に接続すればJupyter-Noteのトップページが表示される
あとは色々試すだけ
Swiftでデザインパターン　アダプターパターン


# アダプターパターン

クラスが既にある状態で、それに手を加えずに実装を追加する方法
既存のクラスに手を加えないので、非破壊的な実装ができる

## 前提事項

- sayHelloの `こんにちは` の最後に、 `!` を付け足したい要望がきた場合
- 他の箇所でも使われているため、直接修正はできない

```swift

class Person { // 既存のクラス
    func sayHello() -> String {
        return "こんにちは"
    }
}
```

## アダプターパターンを使う（継承バージョン）

```swift

protocol ShoutProtocol {
    func shout() -> String
}

class LoudVoicePerson : Person, ShoutProtocol {
    func shout() -> String {
        return super.sayHello() + "!"
    }
}

let loudVoicePerson = LoudVoicePerson()
print(loudVoicePerson.shout())
```

これでできました。既存のクラスに影響がないため、安全です（リリース間際でも心配しなくてすみます）

ただ、個人的には継承を使うやり方はswiftらしくないと思っており、下記のextensionを使ったほうが好きです。

```swift
// extensionを使って、このように実行することも可能
 
 extension Person : ShoutProtocol {
    func shout() -> String {
        return super.sayHello() + "!"
    }
 }
```
iOS11向けアプリ作成で見た記事まとめ

# 概要
個人用メモです。
都度メモしていくスタイル。

## 通信系ライブラリ
### [Apikit](https://github.com/ishkawa/APIKit)
* https://qiita.com/nukotsuka/items/4957f1388f11b5b454d5
* https://qiita.com/sensuikan1973/items/e20c16bb35fef1f1d976

## グラフ描画
### [Charts](https://github.com/danielgindi/Charts)
* https://qiita.com/takumi-n/items/4423197ca0a417cd8251

公式に書いてあるけど、アニメーションとかさせたい場合こんな感じ。割と良い感じに動く。

```swift
pieChartView.animate(xAxisDuration: 1, yAxisDuration: 1, easingOption: .easeInOutCirc)
```

## その他
### iPhoneX対応
* https://qiita.com/rd0501/items/18fe132d8ddf8ac4b589

### 環境ごとの設定切り替え参考
* https://qiita.com/Todate/items/a2e6a26731c79bd23e02

### 環境ごとのFIREBASE設定切り替え参考
* https://qiita.com/i_terasaka/items/8faf5518be7c24bd5501
RSpec + capybara で SessionStorage クリアする

各 `it` 毎にブラウザの `SessionStorage` の内容をクリアしたい。
ソースコード追ったときのメモ。

## JavaScript 経由でクリアするパターン


```ruby
RSpec.configure do |config|
  config.prepend_after(:each, type: :feature) do
    Capybara.execute_script 'localStorage.clear()'
  end
end
```

参考: [Capybara driver for Selenium needs to clean localStorage between tests](https://github.com/teamcapybara/capybara/issues/1702#issuecomment-219483444)


## Capybara のメソッドで削除するパターン

`Capybara.reset_sessions!` を使う。 

```ruby
RSpec.configure do |config|
  config.prepend_after(:each, type: :feature) do
    Capybara.reset_sessions!
  end
end
```

`reset_session!` は `reset!` のエイリアス。
https://github.com/teamcapybara/capybara/blob/master/lib/capybara/session.rb#L124-L133

[reset!](https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selenium/driver.rb#L102-L138) 自体は内部で `clear_browser_state` を呼び出し

- クッキー
- SessionStorage
- LocalStorage

の削除をしている。
https://github.com/teamcapybara/capybara/blob/master/lib/capybara/selenium/driver.rb#L262-L274


なお、Storage関連はオプションでクリアを有効にしないと処理がスキップされる。

- `clear_session_storage`
- `clear_local_storage`

https://gist.github.com/nruth/864dc9875b4feb183b7b10ddbd25c7f4#file-selenium-rb-L43-L55
踏み台サーバー(CentOS,OpenSSH)からNW機器(JuniperSSG)へSSHでログインしようと思ったら認証エラーでログインできない

本事象は他にも記事がありますが部分的なところがありましたので、対処までの一連の流れを書き留めておきます。

環境はCentOS release 6.10 (Final)です。
OpenSSHの詳細は以下です。

```
[hoge~/.ssh $  ssh -V
OpenSSH_7.7p1, OpenSSL 1.0.1e-fips 11 Feb 2013
```

##1.事象
こちらを踏み台サーバーにしているのですがある日、脆弱性対応としてOpenSSHのupdate行った後SSHでNW機器(JuniperSSG5)にログインしようとしたらエラーが発生しました。


```
[hoge~/.ssh $  ssh admin@xxx.xxx.xxx.xxx
Unable to negotiate with xxx.xxx.xxx.xxx port 22: no matching key exchange method found. Their offer: diffie-hellman-group1-sha1
```
##2.対策(diffie-hellman-group1-sha1)
sshのdiffie-hellman-group1-sha1が使えないのでアクセスできないと言っています。
こちらはユーザーの.sshのconfigファイルに以下を追加して解決しました。

```
[hoge~/.ssh $ more config
host *
KexAlgorithms +diffie-hellman-group1-sha1
```
<font color="DeepPink">hostはアスタリスクで全部IP指定にしていますが、必要に応じて変更お願いします。
##3.対策(暗号認証DAS)
これでsshできるかな、と思ったらまた違うエラーが発生。

```
[hoge~/.ssh $  ssh admin@xxx.xxx.xxx.xxx
Unable to negotiate with 119.254.113.118 port 22: no matching host key type found. Their offer: ssh-dss
```

今度のエラーは暗号認証のDAS鍵を使ったSSH接続をOpenSSH7.0以降は非推奨にしていることに起因しているそうです。
参考URL：https://blog.keinos.com/20170703_2635

こちらも同じく.sshのconfigファイルにDAS鍵を使った接続ができるようアルゴリズムを追加します。

```
host *
KexAlgorithms +diffie-hellman-group1-sha1
HostKeyAlgorithms +ssh-dss                  ←追加行
```
##4.対策(暗号認証方式)
これで接続できるようになったら思ったらまたエラーが発生。

```
[hoge~/.ssh $  ssh admin@xxx.xxx.xxx.xxx
Unable to negotiate with xxx.xxx.xxx.xxx port 22: no matching cipher found. Their offer: 3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc
```
認証方式が対応していません、というエラーのようです。
こちらは/etc/ssh/ssh_configの認証方式の行を有効化して対応します。

```
# Host *
#   ForwardAgent no
#   ForwardX11 no
#   PasswordAuthentication yes
#   HostbasedAuthentication no
#   GSSAPIAuthentication no
#   GSSAPIDelegateCredentials no
#   BatchMode no
#   CheckHostIP yes
#   AddressFamily any
#   ConnectTimeout 0
#   StrictHostKeyChecking ask
#   IdentityFile ~/.ssh/id_rsa
#   IdentityFile ~/.ssh/id_dsa
#   IdentityFile ~/.ssh/id_ecdsa
#   IdentityFile ~/.ssh/id_ed25519
#   Port 22
#   Protocol 2
    Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-cbc,3des-cbc →ここの#を削除
#   MACs hmac-md5,hmac-sha1,umac-64@openssh.com
#   EscapeChar ~
#   Tunnel no
#   TunnelDevice any:any
#   PermitLocalCommand no
#   VisualHostKey no
#   ProxyCommand ssh -q -W %h:%p gateway.example.com
```
これでようやくFWにログインできました。

##5.FW確認

ログインして見てみると

```
hoge-fw-> get ssh host-key
DSA fingerprint:
finger_print = f7:a3:18:86:d2:db:b2:b4:bb:79:d9:2e:1c:82:96:7d
```
FWにDSA鍵が存在してました。
NW機器は古い機器でもUpdateせずにそのまま運用しがちですが、ワールドワイドのIT技術はどんどん新しくなっていくので、UPdateが必要だと思い知らさせました。
Vue.jsとfirebaseでクラウドメモアプリを作ってみた


※追記 2018/09/23 PWA対応してみた！

なんか気づいたら前回の投稿から2年半が過ぎてた。やばい。
そしてあまりに仕事がなくて暇だったので、前々から気になってたVue＆firebaseで何か作ってみようと思った次第。

で、何となくメモアプリを選択した。

## 自分なりの要件

- レスポンシブ対応
- ログイン認証（メール・パスワード、Google認証）
- メモの追加、編集、削除
- パスワード変更
- パスワードリセット
- アカウント削除

上記に加えてMarkdown対応してもよかったけど、周囲には「Markdown？何それ？」って人（事務さんとか営業さんとか）の方が多いのでスルーした。あえてね。

## 成果物

https://mymo.yuking11.net/

## ソース

https://github.com/yuking11/mymo

## 感想

- Vue楽しすぎぃ
- firebase便利すぎぃ

次はToDoアプリ作ろうかな。

## 参考

- https://qiita.com/renowan/items/bf1747aabc874bfd85ab
- https://qiita.com/sin_tanaka/items/ea149a33bd9e4b388241
- https://github.com/nabettu/mymarkdown

## 追記 2018/09/23 PWA対応してみた！

せっかくののでPWA対応もしてみました。良い・・・。
あと若干ロゴも修正。

### 参考

[Vue.jsで作ったサイトをPWAに対応させてみる](http://jyuko49.hatenablog.com/entry/2018/04/29/135513)
主要なIaaSのDNSサービスについて、意外とまとまってない情報のまとめとか ver 20180919


# この記事について
* 毎回調べるのも面倒すぎたので、かなりのメモ感が強いです。
* 公式ドキュメントには当然乗っておらずな感じだったので、取りあえずのまとめです。

# 表とか

| 項目 | 公式サイト | NSレコードのFQDN | エイリアスレコード機能 | 加重リソースルーティング |
|---|---|---|---|---|
|Amazon Route 53|[公式サイト](https://aws.amazon.com/jp/route53/)|`ns-****.awsdns-**.(com net org co.uk)`|○ (Route53内のレコードかAWSサービス内のFQDNに対して)|○|
|Google Cloud DNS|[公式サイト](https://cloud.google.com/dns/)|`ns-cloud-**.googledomains.com`|？|？|
|Microsoft Azure DNS|[公式サイト](https://azure.microsoft.com/ja-jp/services/dns/) |`ns(1-4)-**.azure-dns.(com net org info)`|？|？|

# 補足とか

## Route53にある エイリアスレコード機能とは

* DNSにはCNAMEという`とあるドメインから別のドメインに飛ばすレコード` が便利レコードが存在するが、このレコードの制約として **同じドメインに他のレコードは存在してはいけない** というルールが存在する。
* ドメインによっては、どうしてもCNAMEレコード以外が存在してしまうパターンが出てしまうため、これを回避する手として、**あらかじめ、転送先のAレコードを取得して、それを代わりに返す** という機能がある。これをAWSではエイリアスレコードと呼ぶ。

## Route53 にある 加重リソースルーティング 

* 人によっては **重み付けDNSラウンドロビン** と称するところがある。
* 重要なのが「DNSラウンドロビン not = 加重リソースルーティング」であること。
* 加重リソースルーティングは、以下の機能を持つ。
    * 同じドメインにて、**複数の同種類レコードを設定している**
    * 各レコードには、**重みづけの数字が付与されている**
    * 実際にDNSのアクセスがあった場合、**同じドメインの重みづけの割合によって1つだけレコードを返す** 動作をする。
        * DNSラウンドロビンは**存在するレコード全てを返す** ので、ここが大きな違い。


# 書いてて思ったこと
* GCP,Azureは、AWSと同じ、ゾーン転送受け入れない割には、機能がRoute53の劣化版という意味合いにしか見えないのが辛いなぁ…と。
* ゾーン転送＋重みづけのルーティングができるDNSサービスがあれば最高ではあるんですが…

# 参考記事

* Amazon Route 53（クラウド DNS - ドメインネームサーバー） | AWS https://aws.amazon.com/jp/route53/
* Amazon Route 53 がパブリックホストゾーンに作成する NS レコードと SOA レコード - Amazon Route 53 https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/SOA-NSrecords.html
* Cloud DNS - スケーラブルなネームサービス  |  Cloud DNS  |  Google Cloud https://cloud.google.com/dns/
* クイックスタート  |  Cloud DNS のドキュメント  |  Google Cloud https://cloud.google.com/dns/quickstart?hl=ja
* DNS | Microsoft Azure https://azure.microsoft.com/ja-jp/services/dns/
* チュートリアル - Azure DNS でドメインとサブドメインをホストする | Microsoft Docs https://docs.microsoft.com/ja-jp/azure/dns/dns-delegate-domain-azure-dns
Ubuntuで.bashrc使う話

##Ubuntuで今まで使えてたエイリアスが効かなくなった

ある日Ubuntuの表示の文字が白くなってしまった...

今まで自分はUbuntuを起動したときカレントディレクトリが青文字だったりしていたわけですが、この度真っ白がデフォになってしまった。

こうなると今までちまちま作ってきたエイリアスが効かなくなってフラストレーションがたまってしまう。

結果として２～３日真っ白な表示のまま過ごしました。

##bashって打つだけで解決できた

試しに起動状態からbashって打ってみたら普通に表示が変化！

白い世界からカラフルな世界に戻りました。

.bashrc呼び出したいならbashってまず打ちましょうって話

でも自分はまだ全然調べられてないのでこれで一時的に回避できたってだけで、原因やちゃんとした解決の理由、はたまたデフォでエイリアス使う方法がわからない。

調べてまたまとめます。
vmstatをdaemon化して継続的なログを記録する

サーバーのリソース状態を記録しておくための方法。

## shファイルを作成
仕様：60秒ごとにログを取得。結果を日時とともにファイル（/tmp/vmstat.log）に書き込む。

```/tmp/resource_log.sh
#!/bin/bash
exec /usr/bin/vmstat 60 | awk '{print strftime("%y/%m/%d %H:%M:%S"), $0} {fflush() }' >> /tmp/vmstat.log
```

shファイルは/tmpディレクトリに置いてありますが、どこでもよいです。

## サービスファイル作成
実行用のサービスファイルを作ります。（/etc/systemd/system/配下）
ExecStartのところで、先ほど作ったshファイルを指定します。

```/etc/systemd/system/resource_log.service
[Unit]
Description=VMSTAT as a Service

[Service]
Restart=on-failure
RestartSec=10
ExecStart=/tmp/rec_resource.sh

[Install]
WantedBy=basic.target
```

## 起動
以下のコマンドを実行。（systemctlに変更を通知　→　実行）

```
$ sudo systemctl daemon-reload
$ sudo systemctl start resource_log.service
```

## 確認

```
$ cat /tmp/vmstat.log

18/09/19 16:35:22 procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
18/09/19 16:35:22  r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
......
```
こんな感じで記録されていればOK。
「あなたにとってAIとは？」自然言語処理でAidemyに聞いてみた

#1.概要
Aidemyの機械学習概論の文章にWord2Vecを使い、「AI」と関連性が高い単語を調べました。

#2.はじめに
Aidemyで「[自然言語処理でニュース記事をカテゴリ分けしてみよう！](https://aidemy.net/routemaps/2)」の受講ルートを勉強したので、Aidemy noteへの投稿記事として書きました。

Word2Vecというツールを使えば、文章中のある単語と関連性が高い単語を調べることができます。

ところで、NHKの「プロフェッショナル　仕事の流儀」という番組で、「プロフェッショナルとは」という質問をするシーンがありますよね。Word2Vecを使えば、番組中での発言を解析してプロフェッショナルと関連性が高い単語を調べることができます。プロフェッショナルと関連性が高い単語が番組での答えと一致したらおもしろいなと思いました。

特に、本田圭佑さんの「プロフェッショナルとは、ケイスケ・ホンダ」という発言が話題になっていたのでそれを解析してみたかったのですが、文字起こしされているものを見つけられませんでした。

そこで、AIプログラミング学習サービス「[Aidemy](https://aidemy.net)」で無料公開されている「[機械学習概論](https://aidemy.net/courses/2010)」の文章を解析して、「AI」と関連性が高い単語を調べてみました。

#3.データ集め
Aidemyの機械学習概論のサイトから左の説明文をコピペしました。

![aidemy2.png](https://qiita-image-store.s3.amazonaws.com/0/257093/64ee38dc-4f50-9220-476f-7bb644acd32f.png)

Webスクレイピングで文章をダウンロードすればスマートだったかもしれません。しかし、コピペでもそんなに大変ではなく直感的で初心者の方にもわかりやすいかなと思ったのでコピペにしました。

#4.実行環境
Ubuntu 16.04.3 LTS
Python 3.5.5

#5.コード
文章を変数に代入しておくファイルです。

```python:text.py

#1ページ目の文章
#本当はもっと長い
text1 = "機械学習はそもそもなぜ大きく注目されるのでしょうか。主な・・・"

#2ページ目の文章
text2 = "そもそも機械学習の言葉の意味はなんでしょうか。簡単に・・・"

#省略

#22ページ目の文章
text22 = "まず、適合率と再現率について・・・"

text = text1 + text2 + ... + text22
```

Word2Vecを実行するファイルです。

```python:word2vec.py

from gensim.models import word2vec
from janome.tokenizer import Tokenizer
from aidemy_document import *

t = Tokenizer()
tokens = t.tokenize(text)
word=[]

for token in tokens:
        part_of_speech = token.part_of_speech.split(",")[0]

        if part_of_speech == "名詞":
            word.append(token.surface)

documents = [word]
model = word2vec.Word2Vec(documents, size=200, min_count=3, window=15)
similar = model.most_similar(positive=["AI"])
print(similar)
```
関連性を調べる単語の品詞を名詞・動詞・形容詞・形容動詞にしていたら、「し」とか「する」とか抽象的な単語が多くなったので、名詞だけに限定しました。

#6.結果
関連性が高い順に10個の単語が出力されます

1. 教師　　0.8957939743995667
2. ラベル　0.8951122164726257
3. 割合　　0.894281804561615
4. 人　　　0.8937101364135742
5. 再現　　0.893358588218689
6. 以下　　0.8926076292991638
7. 状態　　0.8924640417098999
8. 必要　　0.8920382261276245
9. 顧客　　0.8914119601249695
10. クラス　0.8912531137466431

#7.おわりに
「教師」は「教師あり学習」、「教師なし学習」の教師ですね。「AI」と関連性が高い単語で「人」が出てくるのもおもしろいですね。

Aidemyの「[自然言語処理を用いた質問応答](https://aidemy.net/courses/6120)」を勉強すると、ニューラルネットワークを使った自然言語処理ができるようになり精度も高くなるようです。そこまで勉強したらまた記事を書いてみようと思います。

QiitaやTwitterに感想やアドバイスなどのコメントをいただけると嬉しいです。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Aidemyの文章に自然言語処理を使って、「AI」と関連性が高い単語を調べました<br><br>NHKの「プロフェッショナルとは」的なやつです笑<br><br>拡散してもらえるとうれしいです😁<a href="https://twitter.com/hashtag/Aidemynote?src=hash&amp;ref_src=twsrc%5Etfw">#Aidemynote</a><br>「あなたにとってAIとは？」自然言語処理でAidemyに聞いてみた <a href="https://t.co/JHdxWwygng">https://t.co/JHdxWwygng</a> <a href="https://t.co/kiplLtD7NK">pic.twitter.com/kiplLtD7NK</a></p>&mdash; IT暇人@AIプログラマ,ニート (@it31415) <a href="https://twitter.com/it31415/status/1042342652291637248?ref_src=twsrc%5Etfw">2018年9月19日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
AWS EC2のNameタグをインスタンスのホスト名として設定する方法

# 前提条件

- curlとawscliが当該インスタンスにインストールされていること
- 当該インスタンスにec2 describe-instances可能なIAMロールが設定されていること

````
#!/bin/sh
TMPDIR=/tmp

# 自分自身（インスタンス）のIDを取得する
curl 'http://169.254.169.254/latest/meta-data/instance-id' > ${TMPDIR}/instance-id.txt

# 自分自身（インスタンス）のホスト名を取得する
aws ec2 describe-instances \
--query 'Reservations[].Instances[].{Name:Tags[?Key==`Name`].Value}' \
--filter "Name=instance-id,Values=`cat ${TMPDIR}/instance-id.txt`" \
| jq -r .[0].Name[0] > ${TMPDIR}/hostname.txt

# ホスト名をセットする
hostname `cat ${TMPDIR}/hostname.txt`
````
JavaScript の class 構文とプロトタイプチェーン

# この記事は

JavaScript の [class](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes) 構文を使った場合に、プロトタイプチェーンがどのようになるかを把握したかったので図にまとめてみた。似たような記事はたくさんあるが、あくまで備忘録として。

# コード

```js
class Person {
  constructor(name) {
    this.name = name;
  }
}

class Girl extends Person {
  speak() {
    console.log(`わたし、${this.name}。よろしくね！`);
  }
}

const madoka = new Girl('鹿目まどか');
madoka.speak(); // わたし、鹿目まどか。よろしくね！

const kyoko = new Girl('佐倉杏子');
kyoko.speak = function() {
  console.log(`${this.name}だ。よろしくな！`);
};
kyoko.speak(); // 佐倉杏子だ。よろしくな！
```

# 図

<img width="503" alt="スクリーンショット 2018-09-23 20.14.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/6697/d5fc1f70-35cb-4314-2d10-2af4b3e616be.png">


オブジェクトだけでなく、コンストラクタ関数もチェーンになっているのは知らなかった。そのおかげで [static](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Classes/static) なメソッドも継承できるのか。

```js
Girl.__proto__ === Person; // true
Girl.__proto__.__proto__ === Function.prototype; // true
```

# 参考

* [継承とプロトタイプチェーン](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain)
[rails]webpackerでforemanの設定とeslintの設定をした

# railsプロジェクトでwebpackerでforemanとeslintを設定した話
railsプロジェクトでwebpackerを使ってforemanとeslintを設定しました。
途中苦戦しながらやったため、確実ではないうろ覚え程度なので
間違っているとこあったらコメントください。
あと、若干省略してるとこもあるかと。。。
お願いします。。

## webpackerを入れる
まずはgemfileに

```
gem 'webpacker'
```
を記述し、bundle installを実行。
app/配下にjavascriptディレクトリができる(できたはず。)
javascript/packsにapplication.jsがあり、ここがエントリーポイントらしい。

## foremanの設定
foremanもgemfileに。

```
gem 'foreman'
```
bundle installして
プロジェクト配下にProcfileを作成する。
中身は以下↓

```
rails: rails s --port=3000
webpack: bin/webpack-dev-server
```

## eslintの設定
ここら辺から曖昧。。
色々試していて、エラーが出まくって
エラー内容に従ってyarn installとnpm installをした。

その後、ターミナルで

```
$yarn add -D eslint eslint-loader
```
を実行し、

config/webpack/loaders/配下にeslint.jsファイルを作成。
中身は以下↓

```rb

module.exports = {
  test: '',
  loader: 'aslant-loader',
  enforce: 'pre',
  options: {}
}
```

その後、config/webpack配下のenvironment.jsファイルを編集
中身は以下↓

```rb

const { environment } = require('@rails/webpacker');
const eslint =  require('./loaders/eslint');

environment.loaders.append('eslint', eslint);
module.exports = environment;
```

その後、プロジェクト配下に.eslintrc.jsonファイルを作成
中身は以下↓

```rb
{
  "extends": [
    "eslint:recommended",
    "plugin:vue/recommended"
  ],
  "rules": {
    "semi": "error",
    "indent": ["error", 2],
    "quotes": ["error", "single"]
  },
}
```

## 確認
foreman startを実行し、動くことを確認できた。

package.jsonファイルに以下を追加

```
{
  "scripts": {
        "lint": "yarn run eslint --ext .vue --ext .js app/frontend"
  }
}
```
ターミナルで

```terminal
$yarn run lint
```
を実行すると
lintが動いているのがわかる。

## まとめ
途中苦戦して色々試しながらやっていたため、
雑なまとめになってしまいました。。
今度もう一回新規プロジェクト立ち上げる時にこれ見ながら
本当にいけるか確かめて見たいと思います。
puppeteerでjsやcss、画像の読み込みをさせず高速化する方法

## 概要
自分がやりたくて結構調べたのですがあまり日本語の記事がなかったのでメモ程度に残しておきます。
やりたいことにもよりますが、静的なページのテキストを取得するだけ、POST結果を取得したいだけの時などは必要のない読み込みをすると速度に影響が出てしまいます。必要のない読み込みは制御したほうがいいでしょう。

## ページ読み込み時のファイル読み込み無効化

```javascript
page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', (request) => {
    if (['image', 'stylesheet', 'font', 'script'].indexOf(request.resourceType()) !== -1) {
        request.abort();
    } else {
        request.continue();
    }
});
```
- image:画像読み込み
- stylesheet:CSS読み込み
- font:フォント読み込み
- script:scriptタグの読み込み(JavaScript)

それぞれページ読み込み時に読み込まないようにします。
だいたいこれで早くなるはずです。

# 他に試したこと

## JavaScriptの無効化のみ
使ってみた感じページ読み込み時のscriptタグ制御と変わらなそうです。

```javascript
await page.setJavaScriptEnabled(false)
```

## puppeteer.launchのargsにフラグを渡す方法
正直こっちは効果あるかわからないです。フラグの数が多すぎて把握しきれていません。
[puppeteer.launchのargsに渡せるflag一覧](https://peter.sh/experiments/chromium-command-line-switches/)
ここに書いてあるdisable関係をうまく使えば早くできそうです。

```javascript:URL下のバーを表示させない
  browser = await puppeteer.launch({
    args: ['--disable-infobars']
  });
```


## 参考記事
[Don't load images, CSS and JS #1913](https://github.com/GoogleChrome/puppeteer/issues/1913)
`sign_and_send_pubkey: no mutual signature supported` が出た時の対処

# 問題

sshでログインしようとしたら`sign_and_send_pubkey: no mutual signature supported` が出た

# 環境
ssh のバージョン

``` sh
> ssh -V
OpenSSH_7.8p1, OpenSSL 1.0.2p  14 Aug 2018
```

# 原因
新しいOpenSSHでは、古い暗号方式を拒否するらしい(ssh-dss)

# 対策
大人の事情により暗号化方式を変えれないので `~/.ssh/config` に以下を追記して回避

``` sh:~/.ssh/config
Host nantoka-kantoka.com
  HostKeyAlgorithms ssh-dss
  PubkeyAcceptedKeyTypes ssh-dss
```

別途 `Cipher` で暗号化方式を指定している場合は `+` をつける必要ある

``` sh:~/.ssh/config
Host nantoka-kantoka.com
  HostKeyAlgorithms +ssh-dss
  PubkeyAcceptedKeyTypes +ssh-dss
```

# 参考
- [sign\_and\_send\_pubkey: no mutual signature supported oder Was möchte mir SSH sagen?](https://nerdware.de/sign_and_send_pubkey-no-mutual-signature-supported-oder/)
- [OpenSSH: Legacy Options](https://www.openssh.com/legacy.html)
TypeScript の小ネタ集

## 型のプロパティをすべて非必須にする

`Partial<T>`

### 利用例

既存の必須項目がある型を流用する際などに利用できます。

## 型のプロパティをすべて必須にする

`Required<T>`

### 利用例

とある型から mapped type で型を生成している際に、元の型のシェイプの変更への追従が容易になります。

```ts
interface O1 {
    p1: any;
    p2?: any;
}
type O2 = Required<O1>;
type F<T> = { [K in keyof T]: () => void };
type F1 = F<O1>; // = { p1: () => void; p2?: () => void; }
type F2 = F<O2>; // = { p1: () => void; p2: () => void; }
const f1: F1 = {
    p1: () => {},
    // p2 がないがエラーにはならない
};
const f2: F2 = {
    p1: () => {},
    p2: () => {}, // p2 がないとエラーになる
};
```

## 型のプロパティをすべて読み取り専用にする

`Readonly<T>`

### 利用例

ある型のプロパティの変更を明示的に防ぐことができます。

```ts
interface O1 {
    p1: any;
    p2?: any;
}
type O2 = Readonly<O1>;
const o2: O2 = {
    p1: 'v1',
    p2: 'v2',
}
o2.p2 = 'v3'; // エラー
```

## とある型のプロパティの一部を切り出した型を生成する

`Pick<T, K extends keyof T>`

### 利用例

既存の型の一部を流用する際に利用できます。

```ts
interface O1 {
    p1: any;
    p2: any;
}

interface O2 extends Pick<O1, 'p2'> {
    p3: any;
    p4: any;
}

const o2: O2 = {
    p2: '',
    p3: '',
    p4: '',
}
```

また、ある部分で一部の項目だけしか取り扱えないようにするといったことにも利用できます。

```ts
interface O {
    p1?: any;
    p2?: any;
}
function setToP2(o: Pick<O, 'p2'>): void {
    o.p1 = 'value'; // エラー
    o.p2 = 'value';
}
const o: O = {};
setToP2(o);
console.log(o); // = { p2: 'value' }
```

## キーのセットから型を生成する

`Record<K extends keyof any, T>`

### 利用例

```ts
type Alignment = 'left' | 'center' | 'right';

type AlignmentFuncs = Record<Alignment, () => void>;

const alignmentFuncs: AlignmentFuncs = {
    left: () => { /* do left */  },
    center: () => { /* do center */  },
    right: () => { /* do right */  },
};
```

## 代入可能なものを除外した型を生成する

`Exclude<T, U>`

### 利用例

`Pick` と `Exclude` を組み合わせることで、ある型から一部の項目を除外した型を作ることができます。抜き出したい項目が多い場合は、こっちを使った方が簡単になります。

```ts
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;

interface O1 {
    p1: any;
    p2: any;
}

type O2 = Omit<O1, 'p2'>; // = { p1: any }
```

## 型から null と undefined を取り除く

`NonNullable<T>`

### 利用例

`Required<T>` と同じような使い方になります。

## 関数の戻り値の型を取得する

`ReturnType<T extends (...args: any[]) => any>`

### 利用例

標準で用意されているものですが、使い道がまだ見つかっていません...どなたかいい使い道があったらご教授ください。

## コンストラクタ関数の戻り値を取得する

`InstanceType<T extends new (...args: any[]) => any>`

### 利用例

標準で用意されているものですが、使い道がまだ見つかっていません...どなたかいい使い道があったらご教授ください。

## 配列の要素の型を取り出す

`T[number]`

### 利用例

配列自体ではなく配列の型に対して何らかの処理を行いたい時に利用できます。

```ts
type ElementType<T> = T extends any[] ? T[number] : never;
```

以下のやり方もあります。

```ts
type ElementType<T> = T extends (infer U)[] ? U : never;
```
Serverless deployで躓いた時（プロキシのせい）

sls deployがタイムアウトになってデプロイできなかった。
調べてみると、どうやらプロキシのせいのよう。（結構たくさんの人がプロキシと戦っているようだ）
[会社のファイアウォールから展開する](https://translate.googleusercontent.com/translate_c?depth=1&hl=ja&prev=search&rurl=translate.google.co.jp&sl=en&sp=nmt4&u=https://github.com/serverless/serverless/issues/3256&xid=17259,15700021,15700124,15700149,15700186,15700190,15700201,15700214&usg=ALkJrhgZHqV92nY58-Ru31xNdG1JVWJ65Q)
[プロキシの背後にあるJavaScript用AWS SDKの使用](https://aws.amazon.com/jp/blogs/developer/using-the-aws-sdk-for-javascript-from-behind-a-proxy/)

aws-sdkとproxy agentをインストールし、コマンドプロンプトで環境変数にプロキシを設定したら処理が進んだ。
[AWS SDK for Node.jsをProxy環境で使う](https://qiita.com/toshihirock/items/fcaf2bbd001c7508a2c6)
```
set https_proxy=http://proxy.XXXX.co.jp:8080
set http_proxy=http://proxy.XXXX.co.jp:8080
```

ユーザーのプロファイルに指定しても良いが、" が必要な処理系もあったりするので、都度指定した方が良いらしい。
NODE_MODULE_VERSION が違うといわれて npm run dev 等できない時の対策

メモ。
エラーメッセージを読んで理解できればすぐわかるけど、 理解が浅いため「Node.jsのバージョンがNODE_MODULE_VERSIONと関連している」と思っておらず、エラーを読んですぐ対策にたどり着かなかった。（Node.jsとNODE_MODULE_VERSIONを別で用意する必要があると思っていたなど）

## エラー：

```
Error: The module '/BOKU/NO/APPLICATION/node_modules/scrypt/build/Release/scrypt.node'
was compiled against a different Node.js version using NODE_MODULE_VERSION 64. This version of Node.js requires NODE_MODULE_VERSION 57. Please try re-compiling or re-installing the module (for instance, using `npm rebuild` or `npm install`).
```

なお、 `Please try re-compiling or re-installing the module (for instance, using npm rebuild or npm install).` と書いてある通り、 僕のプロジェクトを `npm rebuild` や `npm install` しただけではだめだった。（後から読んだら、もしかしたらscryptをrebuildしろという意味だったかもしれないと気が付いた。主語が抜けているせいでよく分からない。）


## 原因

* エラーが出たときに使っていたNode.jsのバージョンは10.0であった。
* 使用している `scrypt` で利用すべき NODE_MODULE_VERSION が 57 であった。
* Node.js 10.0 の NODE_MODULE_VERSION は 64 であった。
* そのため、 NODE_MODULE_VERSION のバージョンが異なり、上記に書いてあるエラーがでた。

## 対策（もう一度Buildする方）

Electronを使っている場合は、プロジェクトのフォルダで以下を実行すればよい。

```terminal
$ ./node_modules/.bin/electron-rebuild
```

1度やって治らなければ、 `./node_modules` 以下を一度削除してからもう一度npm installなりyarnなりして、rebuildすれば治る（僕の場合は）

## 対策（Node.jsのバージョン変える方）

Node.jsのバージョンを変更すればよい。（変更後、`node_modules`内を削除した方がよいみたい）

具体的には、 [Node.jsのリリース一覧](https://nodejs.org/ja/download/releases/) で、 NODE_MODULE_VERSION が 57のNode.jsを選べば良い。
（別のバージョンを指定されている場合は、その数字にあったものを選べば良い）

以下はnodebrewを利用しているときの例：

```terminal

$ nodebrew list
v10.0.0

current: v10.0.0

 15:09:52  keisuke@MBP15-YKEISUKE  ~  ♦️ 2.3.3  🐍 2.7.14  ⬡ v10.0.0 
$ nodebrew install 8.12.0
Fetching: https://nodejs.org/dist/v8.12.0/node-v8.12.0-darwin-x64.tar.gz
######################################################################## 100.0%
Installed successfully

 15:15:42  ✘  keisuke@MBP15-YKEISUKE  ~  ♦️ 2.3.3  🐍 2.7.14  ⬡ v10.0.0 
$ nodebrew list
v8.12.0
v10.0.0

current: v10.0.0

 15:15:45  keisuke@MBP15-YKEISUKE  ~  ♦️ 2.3.3  🐍 2.7.14  ⬡ v10.0.0 
$ nodebrew use 8.12.0
use v8.12.0

 15:15:59  keisuke@MBP15-YKEISUKE  ~  ♦️ 2.3.3  🐍 2.7.14  ⬡ v8.12.0 
$ node --version
v8.12.0
```
STS Webプロジェクト作成後にWelcome画面へアクセスできない

#開発環境
- Windows10 64bit
- Java8
- Spring5
- Maven 3.5.4
- Spring Tool Suite Version: 3.9.5

#HTTPステータス 404
Spring Webプロジェクト作成後、「Maven install」をしてtc Serverにプロジェクトを追加する。
ブラウザで「localhost:8080/プロジェクト名」とWelcome画面へアクセスするとHTTPステータス404になった。
![sts_http_404.png](https://qiita-image-store.s3.amazonaws.com/0/289168/2afbe865-3408-4a4b-95b7-785e209d3d5b.png)

一度、STSを閉じてから「C:\Users\ユーザー名\\.m2\repository」配下にあるフォルダ類(ライブラリー群)を全部削除した。
STSを起動しなおし、「Maven install」でライブラリー群を再ダウンロード後にブラウザアクセスするとWelcome画面へアクセス成功した。
![sts_http_200.png](https://qiita-image-store.s3.amazonaws.com/0/289168/2abfa269-87ea-19db-8268-c81a48b3dbf9.png)
原因はライブラリー群のダウンロードに失敗していたようだ。
「いいね」ボタンお願いします。
chaliceで複数API作る時に考えるプロジェクト構成

chaliceの記事は日々増えてきており、情報を集めるには苦労しなくなってきた。
ただ、どれも1APIを作る部分の説明のみで、プロジェクトを続けていく中で複数APIを作る時にどんな構成を組んでるか記載されているものが少なかった。

少しハマったので、書いて残しておく。

# 基本の流れ
### プロジェクト作成
```
chalice new-project api_1
```
これでAPIのプロジェクトを作成し、app.pyにコーディングしていく。
しかしこのプロジェクトに全部詰め込むのも管理し辛いので、API毎にファイルを分けたい。

### デプロイ
```
chalice deploy
```
作成したプロジェクト内でデプロイのコマンドを叩くと、`.chalice/config.json`及び`.chalice/policy-prod.json`の設定に沿ってデプロイが実行される。
実行すると、`deployed`、`deployments`が作成される

# gitプロジェクトの構成
```
├── README.md
├── api_1
│   ├── app.py
│   ├── requirements.txt
│   ├── chalicelib -> ../lib
│   ├── vendor
│   ├── .chalice
├── api_2
│   ├── app.py
│   ├── requirements.txt
│   ├── vendor
│   ├── .chalice
・・・
・・・
```
こんな感じにしたい。
api_1だけデプロイしたいとか当然あるし。

# 必要なこと
### 1. `.chalice/config.json`の"app_name"をそれぞれ独自のものにする
よくよく考えれば当たり前だが、app_nameはそれぞれのプロジェクト毎に独自に設定する
（api_1なら"api_1"、api_2なら"api_2"等）

```:config.json
{
  "version": "2.0",
  "app_name": "api_1",
  "stages": {
    "prod": {
      "api_gateway_stage": "prod",
      "manage_iam_role":false,
      "iam_role_arn":"arn:aws:iam::prod",
      "environment_variables": {
        "DEVELOP": "false"
      }
    },
    "dev": {
      "api_gateway_stage": "dev",
      "manage_iam_role":false,
      "iam_role_arn":"arn:aws:iam::dev",
      "environment_variables": {
        "DEVELOP": "true"
      }
    }
  }
}
```

### 2. 初回デプロイ時は`deployed`、`deployments`は削除する
これも当たり前の話なんだけど、デプロイ実行で作成されるファイルはそのプロジェクト用なので、他のプロジェクトにコピーしちゃダメ。気付かずに時間だけ食ってしまった。

### 3. lambdaとAPIGatewayの関係を一対一にする
実装・デプロイを繰り返していると、lambdaとAPIGatewayの関係が歪になることをあるかもしれない。
作業中、何故か一つのAPIGatewayに複数のlambdaが乗っていた時があって、api_1をデプロイするとapi_2が`502`のエラーを返すようになった。

```
"ChaliceError": Execution failed due to configuration error: Malformed Lambda proxy response
```

その時は一度lambdaを削除してデプロイし直して、APIGatewayとの関連付けを一対一にする。

# まとめ
chaliceはデプロイ周りが本当に楽で、ロジック作成に集中出来るので便利だが、いくつものAPIを作成するような大きなプロジェクトでは向いているのか正直まだ分からない。

が、気軽にサーバレスでAPIを作るにはもってこいなフレームワークであることは間違いない



# 余談
自作ライブラリを追加する場合は、同プロジェクト内のchalicelibに格納するのがセオリー。
[docs](https://chalice.readthedocs.io/en/latest/topics/packaging.html?highlight=chalicelib)にも記載されてる

```
├── api_1
│  ├── app.py
│  ├── chalicelib
│  │   └── utils.py
```
でもこれだとapi毎に用意しなければならないので、共通処理とか用意する時に不便。


### [シンボリックリンクでもいける]
```
├── api_1
│  ├── app.py
│  ├── chalicelib -> ../lib
├── api_2
│  ├── app.py
│  ├── chalicelib -> ../lib
├── lib
│  └── utils.py
```
Azure FunctionsをMATLABから利用する

## 1. 新しいAzure Functionを作成
下記を参考に、HTTP trigger function を作成します。
言語は何でもOK

「Azure Functionsで "hello world" 関数を作成してみた」
https://qiita.com/minatomirai117/items/b0f2bdceaa910107b070

## 2. MATLABコード


```MATLAB
url = '「</> 関数の URL の取得」でコピーしたURL';
options = weboptions('RequestMethod', 'post');
webread(url, 'name', 'MATLAB TEST', options)
```

MATLABコマンドウィンドウに次の表示が出れば成功です。
ans = 'Hello MATLAB TEST'


##参考
MATLABドキュメンテーション： RESTful Web サービスからのコンテンツの読み取り
https://jp.mathworks.com/help/matlab/ref/webread.html

以上
vue.js　ページ遷移、トランジション

https://ja.nuxtjs.org/examples/routes-transitions/

https://coliss.com/articles/build-websites/operation/javascript/native-like-animations-for-page-transitions.html

https://qiita.com/yasuaki0206/items/4c4d96319a921eefd5da

https://vuejsexamples.com/responsive-image-content-comparison-slider-built-with-vue/

https://codepen.io/koca/pen/xJqYpR
LINEbotのオウム返しをコピペしたらエラー吐かれた話。

#とりあえずこちらの記事を参照にしてオウム返しを作る。

全くの未経験でとりあえずProgateでJavaScriptを勉強したものの何が作れるのかは分からず色々ぐぐってたらLINEBotいいらしいというのを見つけたのでとりあえずここから手を付けてみることにした。

大変参考にしたページ↓
https://www.takeiho.com/messaging-api-gas
概要から何からまとまってて大変分かりやすかった。ありがとうございます。

##なぜかエラーが出た。
と思ったのだけどコピペしただけなのでエラーが出た。曰く
「プロパティ リストの後に } がありません。（行 31、ファイル「コード」）」とのこと。

記事中でアクセストークン発行したのをそのまま貼り付けたらOK！とのことだったけどなぜ・・・。
ググってみてもなんか特に得られる情報はない。
みんなこんなエラーは出ないのか・・・マジか・・・。

コードを読んでみても当たり前だけど特に不自然な点は無く途方に暮れるなどした。

###とりあえず違和感のあるところをいじる。
明らかに悪いのは自分だし、どう考えても記事中のChannnelAccessTokenを弄った自分に原因があるのでは？となって再度アクセストークンをコピペして（単純に範囲選択ミスの可能性をつぶしたかった。）再度実行するも同じエラー・・・。

で、ほかのサイトみても同じような導入とコードが多かったのだけど
ふろ””でアクセストークン囲ったら解決した！万歳！
思いついたら本当に当たり前だけど！知らんやん！そんなん！あほ！

####結論「”Channnel Access Token”」

ぐぐり力を発揮してもイマイチ出てこなかったのでログで残しておきます。
PHPで0011と11はtrueでは無い話（進数が変わる）

##`1 == 0001`はtrueなのに、`11 == 0011`はfalseになる！？
アホと笑われるかも知れませんが私はこの仕様に踊らされました。
idが0001であると表示されていたのでバカ正直に`$id == 0001`の
構図になる様に書いてバグを生み出していたようです。

[初めに答えを知りたい方はこちら- PHPリファレンス](http://php.net/manual/ja/language.types.integer.php)
→結論：進数が変わってます。

####0011はfalseになる！？
本当は11とtrueであってほしかったんですが...
しかも不思議なことに0001は1とtrueだって！？どう違うんだ！！

```php
$ids = [0001, 0011];

foreach ($ids as $id) {
  if ($id == 1) {
    // 0001はここに入る
    echo '1とtrue';
  }
  else if ($id == 11) {
    echo '11とtrue';
  }
  else {
    echo 'falseです';
  }
}

//結果（1とtrue, falseです）
```

####0011は9とtrue！！
と言うわけで調べました。

```php
$id == 0011;

if ($id == 11) {
   echo '11とtrue';
}
else if ($id == 9) {
  // ここに入る！ 
  echo '9とtrue';
}
else {
  echo 'falseです';
}

// 結果（9とtrue）
```

##先頭に0などをつける事で進数が変わる

- 先頭`0b`で2進数
- 先頭`0`で8進数
- 先頭`0x`で16進数

```php
// 0bが先頭につくと2進数
if (0b11 == 3) {
    echo "\n2進数：true";
}

// 0が先頭につくと8進数
if (011 == 9) {
    echo "\n8進数:true";
}

// 0xが先頭につくと16進数
if (0x11 == 17) {
    echo "\n16進数：true";
}

// 結果
// 2進数：true
// 8進数:true
// 16進数：true
```
最後に…1は2進数でも8進数でも16進数でも1なのでtrueだったみたいですね！
これからもこのツンデレPHPちゃんとイチャイチャしよう！！

###ちなみに
`===`でやれよ！！って言われたので載せときます。
他の言語仕様がわからないのでPHPで～って書いてますが、他言語ではどんな仕様になってるんでしょうね？

```php
if (0011 === 11) {
    echo '11とtrue';
}
else if (0011 === 9) {
    echo '9とtrue';
}

// 結果（9とtrue）
```
UnityアプリでTHETA Vの画像を天頂補正する方法

# はじめに
* THETA Vの静止画から角度情報を取得して画像を正しい向きにする（天頂補正）際に実施した内容（回転編）
    * Unityアプリでの使用を前提としています

# 概要
* THETA Vの静止画に含まれている角度情報（Pitch, Roll）は、Sphereに貼り付けたEqui画像を正しい向きにするために回転をするための情報
* この角度情報をどのように使えばよいか（どの軸に対してどの順番でどの向きで回転）書いている場所がない（見つけられなかった？）ので成功するパターンを記述しておきます
    * 利用するSphereや向き、テクスチャに応じて条件は変わります

# 前提条件
（前提条件が変わると正しい結果にならないので注意してください）

* Sphere100を使用
    * こちらからダウンロード
        * [UnityとOculusで360度パノラマ全天周動画を見る方法【無料編】](http://warapuri.com/post/131599525953/unity%E3%81%A8oculus%E3%81%A7360%E5%BA%A6%E3%83%91%E3%83%8E%E3%83%A9%E3%83%9E%E5%85%A8%E5%A4%A9%E5%91%A8%E5%8B%95%E7%94%BB%E3%82%92%E8%A6%8B%E3%82%8B%E6%96%B9%E6%B3%95%E7%84%A1%E6%96%99%E7%B7%A8)
* Sphere100のパラメータ
    * Position（x:0、y:0、z:0）（中心）
    * Rotation（x:0、y:0、z:0）（回転させない。初期向きが変わると成立しない）
    * Scale（x:-100、y:100、z:100）（大きさは任意。x軸がマイナスなのは反転した画像を正しくするため）

# PitchとRollの回転順序と向き
* Pitchをｚ軸で値をマイナス反転して回転 → Rollをｘ軸で回転

# 実際のコード
```c#:Sphere100に画像の貼り付けと天頂補正を行っている部分

	// _mainScreen：Sphere100のGameObject
	// _tex：全天球画像をテクスチャにしたもの
	// _pitch：取得した角度情報（pitch）
	// _roll：取得した角度情報（roll）


	public void ShowMainScreen()
	{
		_mainScreen.GetComponent<Renderer>().material.mainTexture = _tex;

		setMainScreenZenith();
	}

	void setMainScreenZenith() {
		_mainScreen.transform.rotation = new Quaternion(0.0f, 0.0f, 0.0f, 0.0f);

		_mainScreen.transform.Rotate(new Vector3(0, 0, 1), -_pitch);
		_mainScreen.transform.Rotate(new Vector3(1, 0, 0), _roll);
	}
```
* 実際には、元テクスチャの破棄などを行っていますが必要な部分だけ残しました

# さいごに
* テストする際はTHETAの向きを全方位にして確認したほうが良いです
    * 全方位（８方位）
        * 本体縦・正常向き／逆さ向き
        * 本体横・レンズ左右・シャッターボタン手前・電源ボタン上／下
        * 本体横・レンズ左右・シャッターボタン奥・電源ボタン上／下
        * 本体横・レンズ上下・ボタン上／ボタン下
    * 一部の方位は正しい向きになる（ようにみえる）けど、他の方位で成功しないというパターンが多々あり頭を抱えました

# さいごのさいごに
* （こんな苦労するなら）使用するTHETA画像は天頂補正済を使用するほうがいいですｗ

# 参考資料
* https://qiita.com/maruo2/items/add701f02b878f3f4eff
Gradleでファイルをリネーム（移動）する。

検索するとcopyタスクのrenameを使う方法が出てきますが、単一のファイルをリネームするだけなら、antのmoveタスクを使うのが一番簡単かと。

```Groovy
// test.xmlをtest.xml.tmpにリネーム(上書き許可)
ant.move file: 'test.xml', tofile: 'test.xml.tmp', overwrite: true

// test.xmlをtest.xml.tmpにリネームしてtmpディレクトリに移動(上書き禁止)
ant.move file: 'test.xml', tofile: 'tmp/test.xml.tmp', overwrite: false
```

参考
https://ant.apache.org/manual/Tasks/move.html