OmniAICreator/Qiita-1.07M huggingface dataset:
【Unity入門】OculusGo⇐⇒Flask連携；Textをもらって盛って表示する♬～OculusGoの独立と新しいサービスの予感？！

![flask-Unity-OculusGo.jpg](https://qiita-image-store.s3.amazonaws.com/0/233744/638fba71-e304-bf7e-e80c-672ce6e564af.jpeg)

概念図は上記のとおり

今回は、[アプリは前回の記事](https://qiita.com/MuAuan/items/b61f4ff9253a0a2b8532)のとおりで、結線変えて遊んだ話です。

つまり、OculusGoって、一度アプリを転送してしまえば独立に動くんじゃないか
ということでやってみました。

やったこと
（１）flaskを動かすサーバー（マシン）を変更する
（２）GetTextが見に行くURLを変更する
（３）UnityでBuild&Runして、OculusGoにアプリ転送する
（４）OculusGoのUSBケーブルを分離して独立させて、動かす
　　　同時にapp.pyを動かしたり、止めたりする
###（１）flaskを動かすサーバー（マシン）を変更する
まんまです。
ただし、今はWiFi環境内で動かしています。
実際、[ルーティングの話は、以前の参考見てください](https://qiita.com/MuAuan/items/b3abd4cff2f39aa1f2d0)。
※単に参考記事に飛んでるだけでやっていませんが、。。
ここで大切なのは、そのマシンのIPアドレスです。
これを取得してください。。。
###（２）GetTextが見に行くURLを変更する
Unityのスクリプト、GetTextの見に行くwwwのURL（以下の★の部分）を上記のflaskのWebサーバーのIPアドレスに変更します。
Unityで動かす場合も、これで問題なく動きます。。。

```GetText.cs
IEnumerator Start()
    {
        WWW www = new WWW("http://192.***.***.★★★:5000/");
        yield return www;
```
これで準備ができました！
###（３）UnityでBuild&Runして、OculusGoにアプリ転送する
これもまんまです。
正しくOculusGoとUnityのマシンをUSBで繋いでください。
ここで一度、OculusGoで確認するといいと思います。
もちろん、flaskマシンでapp.pyを実行しておいてください。
実行していなくとも以下のようなDefault表示が出ますが、今回はこれはwwwと通信した証拠にはならないので注意です。
###（４）OculusGoのUSBケーブルを分離して独立させて、動かす
さてさてクライマックスです。
USBケーブルの結線をはずして、OculusGo内のアプリを動かします。
これは、「ナビゲーションーライブラリー提供元不明ーアプリ」の順に選んでください。
一度、クリックするとフラッシュします。
そして、二度目のクリックで起動します。
ここで、app.pyが動いていないと、Unityのそれぞれで設定されているDefaultが表示されます。
今回のアプリでは
Old Text
New Text
Button
と表示されます。
そして、この状態からapp.pyを動かすと、
Hello Unity
Hello Unity
Hello Unity
に変わります。
さらに、app.pyを停止すると
Unknown Err
Hello Unity
Hello Unity
に変わりました。
これは、Canvasを二種類とButtonを配置していて、下のCanvasとButtonはUnityアプリのStart時点でのみWWWにアクセスしてデータ取得する設定にしていますが、上のCanvas内のTextでは逐次アクセスしてデータ取得しているためです。
因みに、最初Unityアプリを起動時、app.pyは停止していてDefault表示はOKですが、その後app.pyを起動した時点で正しくHello　Unityが表示されるのは、やはり IEnumerator Start()であるため、"こと"が発生するまでStart()で待っていると考えられます。
【参考】
[IEnumerator](https://docs.unity3d.com/jp/530/Manual/Coroutines.html)

###まとめ
（１）OculusGoに取り込んだアプリはOculusGo独立で動かすことができました。
（２）flask-OculusGo連携が確立しました

⇒つまり、ブラウザにアクセスする方法としてブラウザだけじゃなく、OculusGoのようなもので直接連携できるということです

***Flask－OculusGo連携はVRの世界が主流になる次の世界では流行るかもしれない（笑）***
ここで大切なことは、OculusGoのブラウザでも"Hello Unity"の文字は見えるんだけど、Unityで開発した新たな付加価値がついた形（VR・ARや３Dや物体検出・認識・追跡や。。Avatorや。。。なんかの付加価値等）で提供できるサービス（今回はボタン表示やPanelと浮いてる文字だけど。。）がそこにある。。。最後盛ってみました（笑）

<a href="http://www.youtube.com/watch?feature=player_embedded&v=a5Ufg-I-BfA
" target="_blank"><img src="http://img.youtube.com/vi/a5Ufg-I-BfA/0.jpg" 
 </a>
※画像をクリックするとYouTube動画につながります
[OculusGoのUnityからの独立；falsk-OculusGoの直接連携？！](https://youtu.be/a5Ufg-I-BfA) 
※YouTubeに前回と同じ動画と判定されて上書きされてしまった。。まあ長さは少し違うけど^^;
4年前のMacと買いたてのMacでクリーンビルドして速度比較【cocoapods】

# 前書き
2014年に購入したMacbookAirくんがそろそろご臨終で、Xcodeがまともに動かなくなってきたので買い換えた。スペック重視でiMacをフルカスタムして買った。

「こんなけ高いPC買ってXcodeのビルド遅かったらいやだなー。」と思ったので検証した。

# 検証内容
cocoapodsで重たそうな依存性をpod installした後、クリーンビルドをかけてビルド終了までの時間を計測

利用したライブラリは以下。選定理由は普段使っててビルドが特に遅いと感じたやつ。

- RealmSwift
- RxSwift
- RxCocoa

以下のコマンドをターミナルで打ち込んでビルド時間がわかるようにした。

```
defaults write com.apple.dt.Xcode ShowBuildOperationDuration YES
```

# スペック
| マシン |  利用年数 | 購入時価格(円)　| RAM | プロセッサ | GPU |
|:-----------|:------------|:------------|:------------|:------------|:------------|
| MacBook Air (11-inch, Early 2014) | 4年0ヶ月 | 20万強| 8GB 1600 MHz DDR3 | 1.7 GHz Intel Core i7| Intel HD Graphics 5000 1536 MB |
|iMac (Retina 5K, 27-inch, 2017) | 0ヶ月（買いたて） | 50万弱 |64 GB 2400 MHz DDR4 | 4.2 GHz Intel Core i7 | Radeon Pro 580 8192 MB |

# 検証結果
| マシン |  クリーンビルド |
|:------------|:------------|
| MacBook Air | 172.623s |
|iMac | 41.124s |

検証ソースはこちら
https://github.com/syatyo/SpeedTesting

# 感想
さすがにはえー。４倍弱スピードアップしてる。よかったよかった。
でも、できる限り `Carthage` 使うようにしよう。

# PS
もうちょっとこんなこと試して！ってのあればコメントしていただけたら試します。
ラズパイにnpmでfirebaseをインストールしようして苦戦した

# 環境

ラズパイ3 + nでnpmインストール済み

```
$ lsb_release -a
No LSB modules are available.
Distributor ID:	Raspbian
Description:	Raspbian GNU/Linux 9.4 (stretch)
Release:	9.4
Codename:	stretch

$ n --version
2.1.7

npm -v
5.6.0

node -v
v9.10.1
```

プロジェクト名は`firebase-realtime-database-watcher`とします。

# やろうとしたこと

`firebase-tools`ではなく`firebase`の方を入れようとした。

```
sudo npm i　-S firebase
```
sudo を付けないとエラーになる

sudoを付けても以下が延々と流れてインストールが終わらない

```
gyp WARN EACCES user "root" does not have permission to access the dev dir "/home/pi/dev/firebase-realtime-database-watcher/node_modules/grpc/.node-gyp/9.10.1"
gyp WARN EACCES attempting to reinstall using temporary dev dir "/home/pi/dev/firebase-realtime-database-watcher/node_modules/grpc/.node-gyp"
.
.
.
延々とループ
```


# 結論

### プロジェクトディレクトリをroot権限にする
 
```
sudo chown -R root firebase-realtime-database-watcher/
```

sudo 付けないと`可されていない操作です`と怒られます。

### node-gypをインストールする

```
sudo npm i -g node-gyp
```

これで準備完了

改めてインストール

```
sudo npm i firebase
```

無事インストールできた！

### 備考
firebaseだけインストールしても`firebase-tools`がないと意味なかったので、結局`firebase-tools`もインストールした。

# 追記
~~node-gypが必要かと思ってたが改めて作業すると関係なかった~~
必要でした、`node-gyp`インストールを追加。
Node-REDのフローを一時的に無効にする（止めておく）方法

Node-REDのフローについて、「削除はしたくないけど、止めておきたい」ということがありますよね。

最新のNode-REDでは、フローを簡単に無効化することができます。
小ネタですが、ググってもヒットしないようなので書いておきますね。

以下の画面はRaspberry Piですが、IBM Cloudでも手順は同じです。

## 環境
Node-RED v0.17.4

## 手順
「情報」タブに注目してください。
Statusがフローの状態を表します。
![スクリーンショット 2018-06-16 10.38.39.png](https://qiita-image-store.s3.amazonaws.com/0/122917/1883741d-74ac-7a1c-42fe-8ae314d71a4e.png)

右上のハンバーガーメニューから、フロー > フロー名を変更 を選びます。
または、フローのタブをダブルクリックします。
![スクリーンショット 2018-06-16 10.39.03.png](https://qiita-image-store.s3.amazonaws.com/0/122917/0f8bd8de-0470-0575-cd50-0ea9cbec06da.png)

「状態」を無効に変更して「完了」をクリックします。
![スクリーンショット 2018-06-16 10.39.33.png](https://qiita-image-store.s3.amazonaws.com/0/122917/8e9b7433-ba01-295b-2714-768696a2f675.png)

Status = Disabled になり、フロー名の左にアイコンがつきます。
![スクリーンショット 2018-06-16 10.39.45.png](https://qiita-image-store.s3.amazonaws.com/0/122917/2a8fb9d9-c66c-b152-3b73-5c162101a6e4.png)

あとはデプロイするだけです！
ブラウザのスクロールバーを表示させない。CSSでできるらしい。

![スクリーンショット 2018-06-16 10.29.50.png](https://qiita-image-store.s3.amazonaws.com/0/76843/bc6f607a-4c60-67ec-6a30-ed42c448a84e.png)

こういう風になりたくなかったので、
ブラウザのスクロールバーを表示させない方法を調べました。
Jsかなとググっていたら、なんとCSSでできるっぽい。

```css:sample.css

/*　縦のスクロールバーを表示させない場合　*/
body[
   overflow-y: hidden;
}

/*　横のスクロールバーを表示させない場合　*/
body[
   overflow-x: hidden;
}

/*　縦横のスクロールバーを表示させない場合　*/
body[
   overflow: hidden;
}

```

これでできました！よっしゃ
MATLAB > Link > Supported and Compatible Compilers

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04.4 LTS desktop amd64
TensorFlow v1.7.0
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
scipy v0.19.1
geopandas v0.3.0
MATLAB R2017b (Home Edition)
ADDA v.1.3b6
gnustep-gui-runtime v0.24.0-3.1
PyMieScatt v1.7.0
```

https://disordered-photonics.github.io/celes/
を読んでいると、MATLABでサポートされているC++ Compilerを使うとのこと。

対応Compilerは下記のリンクで紹介されている。
https://jp.mathworks.com/support/compilers.html

2018年6月16日現在最新のR2018aより古いバージョンのMatlabの場合、右上の「View compiler support for previous release」からたどればいい。
(自分の環境ではR2017a)
C# のファイルパスや正規表現の記述には@（逐語的リテラル）を使う

## `@`（逐語的リテラル）は読みやすい

`@`記号を文字列の先頭につけると見たままの出力になります。
他の言語だとヒアドキュメントなどと呼ばれるものです。（※コメント参照）


`@`を使うとリテラル内の`\`記号はエスケープ文字として扱われないため、読みやすいです。

- ファイルパス

```csharp
using System.IO;
⋮
var path = @"C:\temp\sample.txt";
if (File.Exists(path)) { ... }
```

- 正規表現

```csharp
using System;
using System.Text.RegularExpressions;
⋮
// 重複した単語を探す
var pattern = @"\b(\w+?)\s\1\b";
var text = "This this is a nice day. What about this? This tastes good. I saw a a dog.";
foreach (Match match in Regex.Matches(text, pattern, RegexOptions.IgnoreCase))
    Console.WriteLine($"{match.Value} (重複 '{match.Groups[1].Value}') 位置 {match.Index}");

```

## `@`を使わないと...

- ファイルパス

```csharp
var path = "C:\\temp\\sample.txt";
```

- 正規表現

```csharp
var pattern = "\\b(\\w+?)\\s\\1\\b";
```

`\`だらけで書く時にはミスりそうですし、読みにくいです。

## 参考

[実戦で役立つ C#プログラミングのイディオム/定石&パターン](https://www.amazon.co.jp/実戦で役立つ-C-プログラミングのイディオム-定石-パターン/dp/4774187585)
Proxy環境下で「apt update」ができないときのメモ

Ubuntuをインストールし使おうとするも「apt-get install」できない！
proxy設定しているはずなのに接続しない！！ネットには繋がっているのに！！
「vim」すら使えない！！！

以上のような状況を解決した時の方法です。

＜作業環境＞
Ubuntu 16.04


参考サイト様
1) [Proxy環境でのapt-get、またはaptitude ](https://usado.jp/spdsk/2017/01/06/post-1098/)
2) [apt-getコマンドをProxy経由で使用するAdd Stara-san](http://d.hatena.ne.jp/mrgoofy33/20100726/1280154695)
3) [端末で使うテキストエディタ nano](https://sites.google.com/site/linuxnomemo/mint-use/nano)


# Proxy設定の確認
まず proxyの現状を確認します
↓をターミナルで実行してください
> `printenv http_proxy https_proxy`

```python:結果
http://proxy server:port/
http://proxy server:port/
```

何も出なかった または 経由したいproxyじゃなかった場合は↓を実行してください
> `export http_proxy="http://proxy server:port/"`
> `export https_proxy=$http_proxy`


ここで↓を実行して、接続できるか確認してください
（　もしかしたら↑のだけでも動くかも　）
> `sudo apt-get update`



#apt.confファイルにProxy設定を追加
次に、apt.confファイルにProxy設定を追加します
「vim」が使えないため必然的に標準エディタ？のnanoを使用します
> `sudo nano /etc/apt/apt.conf`

「apt.conf」が開くので、そこに↓を記述してください

```python:apt.conf
Acquire::http::Proxy "http://proxy server:port";
Acquire::https::Proxy "http://proxy server:port";

```

ちなみにnanoでの保存は「Ctrl＋O」で、終了は「Ctrl＋X」です
終了したら↓を実行して、接続できるか確認してください
> `sudo apt-get update`



私の場合は以上で動くようになりました！
Paper > SVM (Support Vector Machine) > Applying machine learning to estimate the optical properties of black carbon fractal aggregates by Luo et al. 2018 JQSRT

### 論文リンク

https://www.sciencedirect.com/science/article/pii/S0022407317309238

### 内容

- 処理時間が長い厳密な数値計算手法と比べて、処理時間を短くできるSVM(Support Vector Machine)を使う
- 結果は厳密なMSTMと比較
    - multiparticle sphere T-matrix (MSTM) method [15, 16]
- 計算対象
    - black carbon fractal aggregates
        - 葡萄の房のような形状の粒子
        - 構成粒子(葡萄のつぶ)をmonomerと言う
    - Df = 1.8 to 2.2
        - Df: fractal dimension
    - n_s = 3000まで
        - n_s: number of monomers
    - m = 1.95 + 0.79i
        - m: complex refractive index
            - 光学定数、複素屈折率、などの呼び名
            - 化学的組成に対応
        - 以下の値も検討 (Fig10)
            - from Bond and Bergstrom [11]
            - 1.75 + 0.63i
            - 1.80 + 0.67i
            - 1.85 + 0.71i
            - 1.90 + 0.75i
    - $\lambda$ (nm)
        - wavelength
- 比較項目
    - Qext; extinction efficiency
    - Qabs; absorption efficiency
    - Qsca; scattering efficiency
    - ASY; asymmetric factor
        - gという記載もされている
- 比較したところ、以下の精度を得られている
    - 2.3% (Qext)
    - 1.4% (Qabs)
    - 5% (Qsca)
    - 4.8% (ASY)
- 波長変化での比較 (Fig3)
- n_s (number of monomers)変化での比較 (Fig4, 6, 7, 9など) 

### SVM 

SVMに関する部分の抜粋。

$\epsilon - SVR$ (epsilon support vector regression)を使用。

> Due to the nonlinear correlation between optical properties and fractal parameters, the radial basis function (RBF) [54] was used in this study.

[LIBSVM](https://www.csie.ntu.edu.tw/~cjlin/libsvm/) 使用。

下記のXとYの関係をSVMにて学習。

```math
X = [ D_f \space k_0 \space \lambda \space n_s ]
```

```math
Y = [ Q_{ext} \space Q_{abs} \space Q_{sca} \space g ]
```

### 私見

MSTMのような厳密計算では膨大な計算時間、計算資源(メモリ、CPU)が必要である。
その緩和策としてはEffective Medium Theory(EMT)という球形近似手法が広く使われてきたように思われる。

本論文におけるSVMはそのような近似手法ではなく、MSTM自体の計算結果の学習を行って、その誤差について紹介されている。

精度はMSTMよりは劣るが、Black carbon fractal aggregateの光学特性を広いパラメータ範囲（波長特性、monomer数特性）で論じる上ではEMTより有用ではないかと感じた。
Ubuntu 14.04 の Google Chrome でタブやアドレスバーのフォントを変更する

愛着がある Ubuntu 14.04 をいまだに使っている（そろそろアップグレードしなければならないのだが。悲しい）。素晴らしいのだが、唯一の欠点は、Google Chrome をインストールした直後、そのタブやアドレスバーのフォントが汚いこと。

Linux を長く使われた方はよくご存知のとおり、Linux をデスクトップ利用したときの鬼門の一つがフォント。超賢い方はともかく、私のような凡人は、フォント設定にいつも苦労をする。

Google Chrome では、タブやアドレスバーのフォントを変更する簡単な方法がなさそうだ（ネットをひたすら検索したのだが方法が見つからなかった）。

そこで超邪道な解決方法を考えた。つまり、Google Chrome のタブ・アドレスバーのデフォルトフォント名を見つけ出し、そのフォントのバイナリーを自分の好きなフォントのバイナリーで置き換えてしまえばいいのではないか、と（もっとマシな方法があれば教えてください。マジで）。

調べてみたところ、`DroidSansFallbackFull.ttf` というのがそのフォントらしい。私は `TakaoPGothic.ttf` が好きなので、それで置き換えてみた。

```sh
cd /usr/share/fonts/truetype/droid
sudo rm *
sudo cp ../takao-gothic/TakaoPGothic.ttf DroidSansFallbackFull.ttf
```
としてPCを再起動する。

これで Google Chrome のタブやアドレスバーが自分の好みのフォントで表示されるようになる。

当然ながら、もともとの `DroidSansFallbackFull.ttf` のフォントは表示できなくなる。その点は注意すること。
元に戻したければ、 `fonts-droid` というパッケージを apt で入れなおせば良い。
WSLでUbuntu18をセットアップ(1)導入編

# 前口上
以下雑く行きます。
当方、大分前からノートPCにlubuntuなど入れて開発マシンとして使っていたりするので割と分かっている前提で書きますが、ハマりやすいポイントは意識して書いていきます。
# Windows10にUbuntu18をインストール
[Windows 10でLinuxプログラムを利用可能にするWSL（Windows Subsystem for Linux）をインストールする（バージョン1803対応版）](http://www.atmarkit.co.jp/ait/articles/1608/08/news039.html)
を参考にWindows10にStore経由でUbuntu18をインストールします。
この記事では「プログラムと機能」を選ぶのがまどろっこしい手順になってます。
エクスプローラーで
>コントロール パネル\プログラム\プログラムと機能

と選ぶほうが早くたどり着けます。

Ubuntuについては正直なところまだUbuntu18はまだ不安定でパッチ当てたり、色んなパッケージが未対応だったりするので今時点(2018/6/16）ではUbuntu16を選んだ方が無難かもしれません。

Windows StoreからUbuntu18インストール後、Ubuntuの初回起動でセットアップにかなり時間がかかります。多分Storeでカーネルだけインストールして、起動後に必要なパッケージをインストールしているっぽい。テザリング環境でやったらパケ死する気がします。
ユーザ、パスワードの設定をしたらようやくUbuntuが使えるようになります。

# Ubuntu18向けのパッチを当てる
2018/6/16時点では Ubuntu on WSL 起動後「apt update」しようとするとエラーになるので

`wget -O - https://gist.githubusercontent.com/Zenexer/10bc12fa5c99848b4b2150184f6beee5/raw/ubuntu-fix.sh | sh -s`

をやる必要があります。

[Ubuntu 18.04 on WSL で ebtable のアップデートがエラーになる備忘録](https://www.labohyt.net/blog/microsoft/post-2737/)

# apt update & upgrade
最初に言っておきますがUbuntu14以降Ubuntuのパッケージ管理は「apt」が推奨になっています。よく記事で「apt-get」が記載されていますがapt-getだとパッケージ依存を解決しないので思わぬところでハマったり、入れたり下手すると10個のパッケージをずらずらインストールしているのがaptだと1パッケージインストールするだけで一発で入るようになるのでaptで入れるようにしましょう。
でも、ベンダとかの公式パッケージでも導入手順に apt-get で記載されてたりするんだよなぁ…。

前置き長くなりましたが、一つ前のパッチを当てたら
`sudo apt update`
`sudo apt upgrade`
して必須のパッケージをインストールして下さい。
これも結構時間がかかります。

# 日本語設定
WSLでUbuntu入れている人が硬派かどうか分かりませんが、日本人は日本人らしく日本語でおｋな環境にします。
[WSL その14 - ロケールを日本語に設定する](https://kledgeb.blogspot.com/2016/05/wsl-14.html)

# 最後に感想とか
これでとりあえずWindows上でUbuntuが使えるようになります。
ところで、WSLでUbuntu使えることでVMより早かと思っていたんですが今の所そうじゃないそうで…。
[WSL vs VM for 開発作業]
(https://qiita.com/satoru_takeuchi/items/a54812806bba0eb48f02)
ファイルアクセスがボトルネックでVMで動かすよりWSLで動かいた方が遅いというのはなかなか衝撃的…。

とはいえ、Word,Excel見ながら開発することは多いと思いますのでWSL関連はもうちょっとやっていきます。会社で支給されるのがWinマシンというのが普通にあると思うので。

えっ？じゃあMacでいいじゃんって？ **俺Mac嫌いなんだよ！**

あのお作法押し付けられた上にVer.変わるたびにUIとかコロコロかあるの嫌いだしMacBookPro高いし。

今フリーランスで行っている職場はマシン持ち込み必須になってますが、Thinkpadにxubuntu入れて開発してます…。
個人事業主は10万以上の買い物すると確定申告で経費精算が面倒なんです…。
Python requests で SSLError が起きて毎回ググってるのでまとめた

Python で REST API を叩く時は requests ライブラリを使うが、最近の REST API は HTTPS をメインに使うようになった。これに伴い SSLError というよくわからんエラーが出るように。

このエラーは何を意味するのか。どう回避すればいいのか。その辺を知るヒントとして、requests 公式ドキュメントを意訳したもの+α をまとめてみた。

# requests ドキュメントの意訳

## SSL Cert Verification
[Advanced Usage — Requests 2.18.4 documentation](http://docs.python-requests.org/en/master/user/advanced/#ssl-cert-verification)

SSL 認証に絡む挙動や使い方。

- requests はウェブブラウザみたくSSL認証(SSL証明書を用いた認証)を行う
- デフォでは SSL 認証は有効になってて、認証にしくじったら SSLError 例外を投げる

SSL 認証の指定は verify 引数にて行う。

- verify 引数が False だと認証を行わない
- verify 引数が True だと認証を行う（デフォルト）
- verify 引数が「認証局によって認証された CA_BUNDLE ファイルパス」だとそれを使って認証を行う
  - あるいは `REQUESTS_CA_BUNDLE` 環境変数に指定してもいい
- verify 引数が「認証局によって認証された CA_BUNDLE ファイル、のあるディレクトリ」だと [OpenSSL の c_rehash 関数](https://www.openssl.org/docs/man1.0.2/apps/c_rehash.html) と同じ動きで認証を行う
  - 要するにディレクトリ中の証明書ファイル達を使う、というやり方もできるということ

## Client Side Certificates
[Advanced Usage — Requests 2.18.4 documentation](http://docs.python-requests.org/en/master/user/advanced/#client-side-certificates)

SSL 認証とは話が逸れるが「クライアント認証」についての話。

SSL 認証は「クライアントが、サーバーに対して、"あなたは信頼できる相手なんですよね?"」を知るための仕組みだが、クライアント認証はその逆で「サーバーが、クライアントに対して "あなたは信頼できる利用者なんですよね?"」を知るための仕組み。つまりは相互認証という、より堅固な認証のお話であって、SSL 認証とは関係が無い話題。

- [mutual authentication （相互認証）](https://www.symantec.com/ja/jp/security_response/glossary/define.jsp?letter=m&word=mutual-authentication)

## CA Certificates
- [Advanced Usage — Requests 2.18.4 documentation](http://docs.python-requests.org/en/master/user/advanced/#ca-certificates)
- [Python requestsライブラリは認証局の証明書をどう管理する? ｜ Developers.IO](https://dev.classmethod.jp/server-side/python/how-to-manage-ca-root-certs-for-requets-library/)
  - こっちが詳しい

requests が証明書ファイルをどうやって管理しているかという話。

まず昔の話:

- 昔(v2.16以前) は Mozilla が作ってる証明書ファイルをバンドルしていた
- でもこの方法だと、Mozilla 側の更新を取り込めない（requests にバンドルしてる側の証明書ファイルはどんどん古くなっていく）

更新を取り込むにはどうしたらいい？と考えて、requests が取ったのは以下の仕組み。

- 証明書ファイル更新の仕組みを certifi という別パッケージに分離した
- requests は certifi を使って証明書ファイルをゲット＆更新している
- 証明書ファイルを更新したい場合、自分で certifi パッケージをアップデートしてね
  - コマンドで言うと `pip install -U certifi`

# Q: 結局 SSLError を逃れるためには要するにどうすればええの？

## 解1: verify=False をセットする
てっとり早い方法。

ただしこれは「SSL 認証はしません」というやり方であるため、通信先が本当に信用できる場合以外は使わないこと。もし信用しちゃいけない相手に対して verify=False しちゃうと（もっと言うとその先の HTTPS 通信でプライベートなデータを渡しちゃうと）最悪、通信先の悪者に悪用されちゃう。

## 解2: verify='SSL証明書のパス' をセットする
SSL証明書、サーバ証明書、ルート証明書、など呼び方は色々あるが、とにかく「SSL認証で使う証明書」を指定する。そうしたら、指定したその証明書の範囲で SSL 認証をしてくれる。

証明書は CA_BUNDLE という「信頼できる証明書のリスト」的なデータを使うのがてっとり早い。もし会社業務などで別途証明書のインポートを指示されてるなら、その証明書も追加してやる。

証明書ファイルは大体 .pem ファイルか .crt ファイル。中身は公開鍵の羅列。

ああ、あと CA_BUNDLE の入手先はたとえば以下。

- https://mkcert.org/generate/
- http://curl.haxx.se/ca/cacert.pem

# おわりに
[SSLやら証明書やら自体のお勉強ノートははてなブログに書いた](http://stakiran.hatenablog.com/entry/2018/06/12/213727)

これでもう迷わないはず……。
GPSの研究　その11

#概要
GPSを理解したかった。
NMEAをパースして、KMLを作って見た。

#写真

![m6.jpg](https://qiita-image-store.s3.amazonaws.com/0/18104/14f7cb63-983a-dd74-37b4-a9692b0f868c.jpeg)

#サンプルコード


```
import micropyGPS
from lxml import etree
from pykml.factory import KML_ElementMaker as KML
from pykml.factory import GX_ElementMaker as GX

gps = micropyGPS.MicropyGPS(9, 'dd')
f = open("test10.nmea")
pm = ""
while True:
	line = f.readline()
	if not line:
		break
	if (line[0 : 6] == "$GPGGA"):
		for x in line:
			gps.update(x)
		name = "{}:{}".format(gps.timestamp[1], gps.timestamp[2])
		lat, lon = gps.latitude[0], gps.longitude[0]
		alt = gps.altitude
		pm += "{},{},{} ".format(lon, lat, alt)

doc = KML.kml(
	KML.Placemark(
		KML.name("nmea"),
		KML.LineString(
			KML.extrude(1),
			GX.altitudeMode("relativeToSeaFloor"),
			KML.coordinates(
				pm
			)
		)
	)
)
print (etree.tostring(doc, pretty_print = True).decode())
f = open('micro6.kml', 'w')
f.write(etree.tostring(doc, pretty_print = True).decode())
f.close()

```

以上。
Raspberry Piでカメラが認識しない際の対処法

Raspberry Piでカメラモジュールが動かなくなった際のメモ。

`$ raspistill -o test.jpg`のように撮影してみたところ、
以下のようなエラー文が出ました。

```
mmal: mmal_vc_component_enable: failed to enable component: ENOSPC
mmal: camera component couldn't be enabled
mmal: main: Failed to create camera component
mmal: Failed to run camera app. Please check for firmware updates
```

`$ vcgencmd get_camera`でカメラの状況を確認したところ、
`supported=1 detected=1`と返ってきました。

supportedは、Raspberry Pi 本体のインターフェース設定でカメラが有効化されているかどうかを表します。0→無効　1→有効です。
detectedはそのまま、カメラを検知しているかどうかです。
detectedが0の場合、カメラモジュールがきちんと接続しているか確認します。

カメラが無効になっている場合は、`$ sudo raspi-config`で、5番のInterfacing optionから
![Screen Shot 2018-06-16 at 6.26.04.png](https://qiita-image-store.s3.amazonaws.com/0/206282/45d00bf7-8946-06f5-0e6b-d54c9e4b92e0.png)

カメラを選択し、
![Screen Shot 2018-06-16 at 6.22.55.png](https://qiita-image-store.s3.amazonaws.com/0/206282/86768395-abf5-ff5e-0b90-eac1dff9ec09.png)

Yesを選択してenableにします。
![Screen Shot 2018-06-16 at 6.23.05.png](https://qiita-image-store.s3.amazonaws.com/0/206282/d39e0b36-d4ac-168d-e0b2-3b0608f65b4e.png)



今回の場合、カメラの設定は有効になっていて、接続もちゃんとしており、ソフトウェアに問題があるようです。
`$ sudo rpi-update`でファームウェア等のアップデートを行い、`$ sudo reboot`で再起動したら治りました。
Android のリストをスワイプして削除する #あれどうやるの？

<img src="https://qiita-image-store.s3.amazonaws.com/0/49585/732bd762-1892-290d-7eab-5795bea60376.gif" width=300 />

# 用語

- 「リスト」は RecyclerView の話です。
- 「あれ」とはGmailアプリやInboxアプリで実装されている横にスワイプしてリストアイテムを削除(アーカイブ)するという動作のことです。

https://github.com/shts/SwipeToDismissSample/blob/master/img/image.gif

# 結論

`ItemTouchHelper.SimpleCallback` を使う

# 詳細

リストアイテムをスワイプすること自体割と簡単でした。

## スワイプの実装

`ItemTouchHelper.SimpleCallback` は引数を取るのですが、2つ目の引数にスワイプする方向を設定してあげます。
今回は左右にスワイプしたいので `ItemTouchHelper.RIGHT` と `ItemTouchHelper.LEFT` を設定します。
第一引数は上下の移動を設定しますが、今回は使わないので `0` を設定します。

```kotlin
ItemTouchHelper.SimpleCallback(0, (ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT))
```

## リストを削除

`ItemTouchHelper.SimpleCallback` には `onSwiped` という関数が用意されています。
スワイプした後にコールされるのでここでリストを削除します。

## アイコンを表示する

`ItemTouchHelper.SimpleCallback` には `onChildDraw` という関数が用意されています。

```kotlin
override fun onChildDraw(
        c: Canvas?,
        recyclerView: RecyclerView?,
        viewHolder: RecyclerView.ViewHolder?,
        dX: Float,
        dY: Float,
        actionState: Int,
        isCurrentlyActive: Boolean
```

こちらもスワイプ時にコールされますが、 `onSwiped` と異なり、この関数は指を移動させるごとにコールされます。
また、パラメーターに `Canvas` が渡されるのですが、これはスワイプされたリストの裏側に描画するための `Canvas` になります。なのでこの `Canvas` に表示させたい絵を書きます。
 `Canvas` の扱いは少し面倒ですが、ユーザーにスワイプをしたらどうなるのかを想起させることができるのでぜひやりましょう。

少し戻りますが、 `ItemTouchHelper` に `ItemTouchHelper.RIGHT` と `ItemTouchHelper.LEFT` を設定したのでリストアイテムは左右のスワイプができるようになっています。
しかしこの関数は左右どちらに移動した時もコールされるのでユーザーが左に動かしているのか、右に動かしているのかを判断する必要があります。
そこで `dX` というパラメータをみてどちらに移動しているかを判断できます。左方向に移動している時、 `dX` はマイナスの値を取るので以下のような条件式で判断が可能です。

```kotlin
val isLeftDirection = dX < 0
```

イメージですが、このように背景に色塗ります。

```kotlin
background.color = leftBackgroundColor
background.setBounds(itemView.right + dX.toInt(), itemView.top, itemView.right, itemView.bottom)
```

アイコンはこのように描画します。

```kotlin
// Calculate position of delete icon
val deleteIconTop = itemView.top + (itemHeight - deleteIconIntrinsicHeight) / 2
val deleteIconMargin = (itemHeight - deleteIconIntrinsicHeight) / 2
val deleteIconLeft = itemView.right - deleteIconMargin - deleteIconIntrinsicWidth
val deleteIconRight = itemView.right - deleteIconMargin
val deleteIconBottom = deleteIconTop + deleteIconIntrinsicHeight

// Draw the delete icon
deleteIcon.setBounds(deleteIconLeft, deleteIconTop, deleteIconRight, deleteIconBottom)
deleteIcon.draw(c)
```

以上です。サンプルコードを [Github](https://github.com/shts/SwipeToDismissSample) に作成しました。

# リンク
http://yuki312.blogspot.com/2015/06/recyclerview-itemtouchhelper.html
https://medium.com/@kitek/recyclerview-swipe-to-delete-easier-than-you-thought-cff67ff5e5f6
[AutoHotKey]ウィンドウを近い方に端寄せする関数（はみ出しも対応）


## 動機
- 右とか左とかじゃなくとりあえずピタっとしてほしい時がある
- ウィンドウサイズを変数するスクリプトとかで、はみ出したら端寄せもしてほしい

## 実装
とりあえず、ウィンドウがスクリーンよりでかくなってる場合は考えない。
（考える場合は、`A_screenwidth < AW`とかで分岐したらいい）

左右どっちに近いかは、「左端からの距離」「右端からの距離」それぞれの絶対値を比較する。

```txt:sample1.ahk
; ウィンドウを左右近いほうに端寄せする関数
moveToNearSide(){
    WinGetPos, AX, , AW, , A
    If (av(AX) < av(A_ScreenWidth-(AX+AW)))
        WinMove, A, , 0,
    Else
        WinMove, A, , (A_ScreenWidth - AW),
}
; ウィンドウを上下近いほうに端寄せする関数
moveToNearEnd(){ ; タスクバーが下にある前提
    WinGetPos, , AY, , AH, A
    WinGetPos, , , , tbHeight, ahk_class Shell_TrayWnd ; タスクバーの高さ取得
    If (av(AY) < av(A_ScreenHeight-(AY+AH)))
        WinMove, A, , , 0,
    Else
        WinMove, A, , , (A_ScreenHeight - AH - tbHeight)
}
; 数値を絶対値(AbsoluteValue)に直す関数
AV(Value)
{
    If Value > 0
        Return, Value
    Else
        Return, -(Value)
}
```

ウィンドウがはみ出してるかどうか判定するスクリプト、はこんな感じ。

```txt:sample2.ahk
WinGetPos, AX, AY, AW, AH, A
WinGetPos, , , , tbHeight, ahk_class Shell_TrayWnd
If (AX < 0) or (A_ScreenWidth < (AX+AW))
    moveToNearSide()
If (AY < 0) or (A_ScreenHeight-tbHeight < (AY+AH))
    moveToNearEnd()
Else
    MsgBox, , %A_scriptname%, はみだしてません
Exit
```

本当はツールタスクバーの位置や表示有無での判定も入れるべきなのだが、自分は下固定なので諦めました。

<!--
```
WinGetPos, X, Y, Width, Height, ahk_class Shell_TrayWnd ahk_exe explorer.exe
```
で、タスクバーの座標は得られる。

-->
wordpressで謎の改行(&nbsp)が入る問題と対処方法

#2連スペースがあると&nbspに変換される？
コピペを駆使しながらwordpressの自作テーマを書いていたら、妙な改行が発生することに気づいた。
調べると、2連スペースなどは自動的に&nbspに変換されるようで、それが原因らしい。
たしかに表示されるサイトのソースを見ると、自分では書いていない&nbspがあった。

#2連スペースなんて使ってないけど・・・？
そう、使ってるつもりはサラサラないのだが、コピペなどした部分を見ると、tabによるインデントではなくスペースによるインデントとなっている部分がいくつかあった。これが原因か？？？と思い、全部tabで統一、さらに行末のスペースにも注意を払い消すと、謎の改行はなくなった。

#あとがき
我がマンションの回線が128kbyte以上のアップロードを受け付けないとかいうゴミ環境なのもあり、ワードプレスのエディタ(ブラウザ内)を用いて編集していた都合でスペースに気づけなかった。普通のエディタを使っている人は、スペースを"・"で表示するなどの設定があるはずなので、ぜひおすすめする。個人的にはスペースでインデントする派とは宗教的な対立がある。。。
プリンシプルオブプログラミングまとめ(第１章、第２章)

#**はじめに**#
[プリンシプル オブ プログラミング3年目までに身につけたい一生役立つ101の原理原則](https://www.amazon.co.jp/%E3%83%97%E3%83%AA%E3%83%B3%E3%82%B7%E3%83%97%E3%83%AB-%E3%82%AA%E3%83%96-%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B03%E5%B9%B4%E7%9B%AE%E3%81%BE%E3%81%A7%E3%81%AB%E8%BA%AB%E3%81%AB%E3%81%A4%E3%81%91%E3%81%9F%E3%81%84%E4%B8%80%E7%94%9F%E5%BD%B9%E7%AB%8B%E3%81%A4101%E3%81%AE%E5%8E%9F%E7%90%86%E5%8E%9F%E5%89%87-%E4%B8%8A%E7%94%B0-%E5%8B%B2/dp/4798046140/ref=pd_sim_14_3?_encoding=UTF8&pd_rd_i=4798046140&pd_rd_r=07800e45-70be-11e8-ad58-df0a85132d74&pd_rd_w=SAUyE&pd_rd_wg=cn75y&pf_rd_i=desktop-dp-sims&pf_rd_m=AN1VRQENFRJN5&pf_rd_p=7990452376513976631&pf_rd_r=ZE22S3100GP1ND37X1WK&pf_rd_s=desktop-dp-sims&pf_rd_t=40701&psc=1&refRID=ZE22S3100GP1ND37X1WK)を読んだので第１章と第２章の内容をまとめました。

#**第１章　前提　〜プログラミングの変わらない真実〜**

##**1.プログラミングに銀の弾丸はない**
ソフトウェア(プログラミングの成果物)は本質的に困難であり、以下の４つの性質を持ちます。

　1. 複雑性：構成要素間の複雑な依存関係がある。
　2. 同調整：複雑な実世界に接続するため同調しなければならない。
　3. 可変性：ユーザの要求に対応し変更しなければならない。
　4. 不可視性：ソフトウェアは概念の集合なので目に見えない。

よってプログラミングは**本質的に困難なもの**なので、**簡単に上達するものではありません**。

##**2.コードは設計書である**##
![flow.png](https://qiita-image-store.s3.amazonaws.com/0/156302/e45f5b4a-773b-3a67-1d00-84db6d5bd9a8.png)
ハードウェアとソフトウェアの開発の手順はこのようになっています。
ハードウェアにおける設計図はソフトウェアのコードに対応します。
つまりコードは設計書であるので、プログラミングを始めるときは設計に長い時間を掛けず、**できるだけ早くコードを書き始めましょう**。

##**3.コードは必ず変更される**##
プログラムを書いたあとに、そのコードは必ず修正されます。

例えば、
　・ユーザの要望
　・障害の発生
　・新規開発のプログラミング(前日のコードの修正)
などです。

特に前日のコードの修正は毎日訪れるので、**変更に強い(読みやすい)コード**を書くようにしましょう。


#**第２章　原則〜プログラミングのガイドライン〜**

##**1.KISS(Keep It Short and Simple)**##
コードはシンプルに保ちましょう。

シンプルなコードとは、
　・構成する要素がシンプル
　・各要素が担う責務が最小限
　・各要素同士の関連がシンプル
なコードのことです。

コードにおいて**「より少ないことは、より豊かなこと」**であるので、今書いているコードは本当に必要かを考えてシンプルなコードを書きましょう。

##**2.DRY(Don’t Repeat Yourself)**##
コードを抽象化し、コードのコピペをしないようにしましょう。
具体的な抽象化方法としては、オブジェクト指向やデザインパターンです。
また、抽象化した関数などについてですが、**「一つの場所に一つの事実」**という考えをもつことが大事です。

##**3.YAGNI(You Aren’t Going to Need It)**##
コードは必要最低限作るようにしましょう。
つまり、汎用性よりも**単純性**を意識しましょう。

##**4.PIE(Program Intently and Expressively)**##
コードを書くときは、「書きやすさ」よりも**「読みやすさ」**を重視しましょう。
読みやすいコードを書くと、コメントで説明しなくても分かりやすいコードになります。コメントを書く場合、コードは「What」と「How」を伝えるものなので、コメントは「Why」を伝えましょう。

##**5.SLAP(Single Level of Abstraction Principle)**##
![func.png](https://qiita-image-store.s3.amazonaws.com/0/156302/94d8145c-6a38-f46a-1564-63fc509fa4ff.png)
コード(関数等)のレベルを合わせることで**「要約性」**と**「閲覧性」**をもたらします。
具体的には関数を構造化し、自身より１段低いレベルの関数を呼び出すようにします。**最も低水準な関数は、名前で意図を伝えるためなら１行でもOKです。**行数の少ない低水準な関数をたくさん作ったほうがいいと思います。

##**6.OCP(Open-Closed Principle)**##
コードの変更を波及させないように、複数のコードの間にはインタフェースを作るようにしましょう。

##**7.名前重要(Naming is important)**##
コードで命名は最重要課題です。
プログラミングで一番大変なのは命名といっても過言ではないかもしれません。

名前の付け方としては、
　・より多くの情報を詰め込む。
　・他の意味と誤解されないようにする。
　・名前は「効果」と「目的」を説明する。
　・命名したものを使用するテストを先に書く。
　・発音可能なものにする。
　・検索可能なものにする。
などがあるようです。

具体的な命名方法は、頻出の英単語をまとめているサイトや[codic](https://codic.jp/)を参考にするといいと思います。

#**まとめ**#
適当にプログラムを書いていると、「半年前に書いたプログラムが読めない！」などの事態が起こるかもしれないので良いプログラムを書きましょう。
ElixirでExcelと同様のデータ処理をしてみた

（この記事は、「[fukuoka.ex x ザキ研 Advent Calendar 2017](https://adventar.org/calendars/2873)」の2日目です）
昨日は @hisaway さんの[「Elixirのリストの仕様をまとめてみた」](https://qiita.com/hisaway/items/dd25158b2a51832109c7)でしたね。

#はじめに
ザキ研メンバーとして「fukuoka.ex x ザキ研 Advent Calendar」に参加させていただくことになりました、ザキ研の@TakeshiKoguといいます。これからfukuoka.exのアドバイザーとキャストの方々とElixirを盛り上げていけるように精一杯頑張ります。どうぞよろしくお願いします。

今回は@piacereさんの記事を参考にさせていただき書いてみました。(https://qiita.com/piacere_ex/items/6714e1440e3f25fb46a1)

#数値の並び替えをしてみる
Enum.sort()を用いてデータの「並び替え」をします。
まずはじめに「iex」コマンドを起動しElixirのコードをインタラクティブに実行できる状態にします。

```elixir
idx
Interactive Elixir (1.6.5) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
```

iex内で、Enum.sort()を用いたコードを打ってみると、

```elixir
iex> Enum.sort([100, 270, 50, 130])
[50, 100, 130, 270]
```

このように簡単に数値を昇順化することができました。
またこのように書き換えることも可能です。

```elixir
iex> [100, 270, 50, 130] |> Enum.sort
[50, 100, 130, 270]
```
0以下の処理や小数点以下の処理にも対応していることも確認できました。

```elixir
iex> [-2.2, 1.6, 0.1, -4.5, 0, 0.1, 1.1] |> Enum.sort
[-4.5, -2.2, 0, 0.1, 0.1, 1.1, 1.6]
```

#データの数を数えてみる
Enum.count()を用いてデータの数を数えます。

```elixir
iex> [100, 270, 50, 130] |> Enum.count
4
```

並び替えと同様にEnum.countを用いるだけで数えることができました。

#フィルタをかけてみる
Enum.filter()を用いてデータに「フィルタ」をかけます。

```elixir
iex> [100, 270, 50, 130] |> Enum.filter(fn(n) -> n != 50 end)
[100, 270, 130]
```

「fn」は、関数 (function) を意味しており、「->」から「end」の間に処理する内容を記述することでデータの処理が行われます。
今回は50がデータの中にあるか確認し、50でない値が返されるようにフィルタをかけたことになりました。

```elixir`
iex> [-20, 160, 35, -100, -25, 40, 200, 10] |> Enum.filter(fn(n) -> n <= 0 || n == 40 end)
[-20, -100, -25, 40]
```

このように処理の条件を複数つけることも可能です。

# まとめ

今回行った処理を組み合わせることで、あるデータの中に0以下の値が幾つ含まれているか調べることも容易に可能となります。

```elixir`
iex> [-20, 160, 35, -100, -25, 40, 200, 10] |> Enum.sort |> Enum.filter(fn(n) -> n <= 0 end) |> Enum.count
3
```

このようにEnumを使うことでデータの様々な処理が簡単に行うことができました。パイプライン演算子を使うことで一度に全ての処理を行うことが可能となりました。
今回行った処理以外にもEnumを使ってのデータの処理は多く存在します。

ElixirでEnumを使うことでExcelでしている処理が想像以上に簡単にでき、私はこれからもっとElixirについて学び知識を向上させ、研究につなげていこうと思えました。

明日は @zumin さんの[「Elixirで一千万行のJSONデータで遊んでみた」](https://qiita.com/zumin/items/d27cdcf66807f57a6cec)です。お楽しみに！
sealedトレイトを階層化してパターンマッチ

# 動機

ある対象`target: T`に対してバリデーションを行い、

* バリデーションをパスしなかった場合
    * バリデーションをパスしなかった理由でハンドリングしたい
* バリデーションをパスした場合
    * バリデーションをパスした場合の`target: T`の状態でハンドリングしたい

みたいな動機があって、
`def validate(target: T): Either[UnPassed, Passed]`
のようなバリデーションの為の関数を実装した際に、返り値全体を同じグループとして表現したかった。

# 実例

以下の様にsealed traitを継承し、階層化します。階層化はあまり珍しくないかと思います。

```scala

sealed trait Result
object Result {

    sealed trait Passed extends Result
    object Passed {

        case object Status1 extends Passed
        case object Status2 extends Passed
        ...
        case object StatusN extends Passed

    }

    sealed trait UnPassed extends Result
    object UnPassed {
        
        case object Reason1 extends UnPassed
        case object Reason2 extends UnPassed
        ...
        case object ReasonN extends UnPassed

    }

}
```

`sealed trait`以外にも、Scalaの列挙型なら継承によって階層化することができます。
例えば、以下の様に`final case class`を用いると、特定の理由の時には特定の値を返す様なことができます。

```scala
final case class Reason(value: V) extends UnPassed
```

意味のまとまりが生まれるのが階層化を行う一番のメリットだと思います。

# パターンマッチを行う

階層化した列挙型は、階層的な`sealed`の恩恵を得ることができます。
マッチ対象の型を一番上の`Reason`とすれば、`match`式のパターンマッチでは`Reason`を継承する全ての要素をマッチしなければなりません。その下の`Passed`または`UnPassed`をマッチ対象にすると、それぞれを継承する全ての要素をマッチする必要があります。

例えば、マッチ対象を`Result.Passed`にすれば、バリデーションを通過した全ての状態をハンドリングすることができます。

```scala
val handler: Result.Passed => V = (status: Result.Passed) =>
    status match {
        case Result.Passed.Status1 => ???
        case Result.Passed.Status2 => ???
        ...
        case Result.Passed.StatusN => ???
    }
```

仮に、`Result.Passed.Status1`のケースを登録しない様な`PartialFunction`を作成しようとすると、

```scala
warning: match may not be exhaustive.
It would fail on the following input: Status1
```

の様に警告を出してくれます。

## Eitherとの組み合わせ

やり方は色々あると思いますが、実際にEitherと組み合わせて使う場合には以下の様になります。

```scala
def validate(target: T): Either[UnPassed, Passed]

def statusHandler(status: Passed): V
def reasonHandler(reason: UnPassed): V

validate(target) match {
    case Right(status) => statusHandler(status)
    case Left(reason) => reasonHandler(reason)
}
```

もっと良い方法もあるかと思いますので、何かあればおしらせください。
Heroku トラブル「We're sorry, but something went wrong」と言われたら

# はじめに

リリースしようと思ってデプロイしたら

```bash
$ git push heroku master
```

こんなん出ました。

![スクリーンショット 2018-06-16 01.16.54.png](https://qiita-image-store.s3.amazonaws.com/0/14191/db1eea20-c30e-0639-5db3-1bfe3ef7aaba.png)

# 解決法

色々調べたら、今回のリリースで、自分、新しいモデルやデータベースを作成していました。なので、再度、**PostgreSQLのアドオンの追加**してみました。

## PostgreSQL アドオンの追加

```bash
$ heroku addons:create heroku-postgresql:hobby-dev
```

- `heroku addons:create` はアドオンを追加するコマンド
- `hobby-dev` は`heroku-postgresql`の唯一の無料プラン
    - 1万レコードまでしか保存できないなどいくつか制限がある

## マイグレーションのやり直し

```bash
$ heroku run rails db:migrate
```

## 結果

動作確認したら、正常に動きました。

ですが、今思えばモデルは`push`されていたから、マイグレーションのやり直し他だけでよかったかも。。

# 参考
- https://qiita.com/beta_chelsea/items/34ccd2b7ad48163c55f8
JavaScriptでワンライナーでいけるようなif文をささっと書きたい時のショートハンド(？)


```javascript:ワンライナーで書きたい
  const isAdmin = true;
  if (isAdmin) deleteAllUser();
```

```javascript:短絡評価を使う
  const isAdmin = true;
  isAdmin && deleteAllUser();
```

:moyai: 「...if文の方が可読性ええな」
Docker にパックした SPA に環境変数を埋め込む

SPA を Docker でホストするときによく思うことが、Environment Variables をSPA に渡したい！と思うことだ。例えば、バックエンドサーバーの URL 等だ。実際にこれは出来ない。なぜかというと、動作するのはあくまでユーザのブラウザ上だからだ。通常は、CIでそれらをインジェクトしてデプロイする。

そのインジェクションを Docker build の時にやってしまいたいので、そういうコードを書いてみた。

# 環境変数のビルド時におけるインジェクション

## インジェクト用のシェルファイル

例えば Angular だったら、`src/environments/environment.ts` 等を書きかえる。

_environment.ts_

```typescript
export const environment = {
  production: false,
  backendUrl: "https://somethingfunctionapp.azurewebsites.net/api/SomeStatus"
};
```

これを`FUNCTION_NAME` という環境変数で上書きされるようにスクリプトを書いておく。ここでポイントは、正規表現の記述が `/` ではなく `|` を使っていること。これは、`somethingfunctionapp/$FUNCTION_NAME` だと、ディレクトリ名と区分けがつかなくなり、`somethingfunctionapp//somename` などに変換されるため。

_inject.sh_

```sh
#!/bin/sh

grep -l 'somethingfunctionapp' src/environments/*.ts | xargs sed -i.bak -e "s|somethingfunctionapp|$FUNCTION_NAME|g" 

```

## Dockerfile

通常だと、実行しているシェルの環境変数は引き継がれない。`ARG` を用いる。

```dockerfile
FROM node:8-alpine AS build
WORKDIR /usr/src/app
RUN npm i -g @angular/cli
COPY . .
ARG FUNCTION_NAME
RUN sh inject.sh
RUN npm install --silent
RUN npm run build

FROM nginx:1.13.12-alpine
WORKDIR /app
RUN rm -rf /usr/share/nginx/html
# COPY ./dist /usr/share/nginx/html # Useful for local builds
COPY --from=build /usr/src/app/dist /usr/share/nginx/html
```

こうしておくと実行時に次のようにして環境変数を渡すことができる。

```sh
docker build --build-arg FUNCTION_NAME="$FUNCTION_NAME" . -t abc
```

あとはこの `docker build` を実行すると無事に実行時すれば完了。

# あとがき

ちなみに、これを作り終えてから気が付いたが、このファイル書き換えの方法をスタートアップスクリプトを作って、それが環境変数をインジェクトするようにすると、docker コンテナの環境変数でもインジェクトできることに気が付いた。こんかいのユースケースではそこまで不要なのでやってないが、そっちのほうがカッコいいかも。
ヒストグラム平坦化

#はじめに
自分が論文を読んでいて、急に「ヒストグラム平坦化」というものが登場した。初めてのものであったので、今回は自分の備忘録も兼ねて、まとめておく。

#ヒストグラム平坦化とは
画像のヒストグラムを描くと、画像全体の明暗に関する状態が得られる。

たとえば、次の画像について考えてみよう。
![traingray.jpg](https://qiita-image-store.s3.amazonaws.com/0/221972/2c1fa689-ab73-061f-861e-48e62cbe9a6d.jpeg)

この画像を明るくしたり暗くしたり、コントラストを高めたり低くしたりした４つの画像を用意した。
![スクリーンショット 2018-06-15 14.22.59.jpg](https://qiita-image-store.s3.amazonaws.com/0/221972/6444dd12-415e-8f9c-022c-bf7a84edde78.jpeg)
これらについて、ヒストグラムを描くと次のようになる。
![compare.jpg](https://qiita-image-store.s3.amazonaws.com/0/221972/dc401647-446f-8c93-2abd-1ef863551bb5.jpeg)
ここから考察し、次のような性質がある。
> [1]画像が「暗い」場合　→　ヒストグラムは「左側」に偏る
[2]画像が「明るい」場合　→　ヒストグラムは「右側」に偏る
[3]画像の「コントラストが高い」場合　→　ヒストグラムの中央部が平坦になる
[4]画像の「コントラストが低い」場合　→　ヒストグラムは「中央」に偏る

つまり、コントラストが高い、もっともメリハリのついた画像が欲しければ、ヒストグラムが全体的に平均化(平坦化)されるように画素値を変換してあげればよい。また、ニューラルネットワークに入れて学習させる画像に対して**ヒストグラム平坦化**を施すと、精度が上昇する場合がある。

ヒストグラム平坦化を数式で表すと次のようになる。
>【Def.】ヒストグラム平坦化
$I(x,y)$:画像中の座標$(x,y)$での入力画像の画素値
$H(x,y)$:画素値の度数$H(x,y)$
$I_{max}$:入力画像の画素値の最大値
$S$:入力画像の画素数の総和
に対して、以下の式を用いると出力画像の画素値$\hat{I}$が求められる。
$$\hat{I}=\dfrac{I_{max}}{S}\sum_{i=0}^{I(x,y)}H(x,y)$$

#実際につかってみた
ここでは、アメリカ国立衛生研究所(NIH)が公開しているオープンデータ「ChestX-ray14」の中にある胸部レントゲン写真を使ってみよう。
![x-ray.png](https://qiita-image-store.s3.amazonaws.com/0/221972/bf410360-804c-8886-f817-133d3abc748e.png)
　レントゲン写真を解析したいとき、患部がどこにあるかハッキリ診る必要がある。レントゲン中には骨や臓器、患部が白い影として表示される。骨や臓器は(個人差が激しいんだけどだいたい)同じ場所にあるので、健康な人だと写っていない白い影が写っていると、その領域に疾病の可能性がある、と判断される。
　そういった背景から、白と黒のコントラストが強くついている方が疾病がハッキリ見やすい。このとき、今回の**ヒストグラム平坦化**が使えるのである。

```python
import cv2
import numpy as np

#画像の読み込み
img = cv2.imread('x-ray.png',1)

#画像をRGBからグレースケールに変更
gray_img = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

#ヒストグラム平坦化
hist_img = cv2.equalizeHist(gray_img)

#処理後の画像を保存
cv2.imwrite('x-ray_hist.png', hist_img)
```
ここでは、OpenCVを使ってヒストグラム平坦化をした。OpenCVにおいて、ヒストグラム平坦化を行う関数は*equalizeHist( image )*である。

ここで気をつけるポイントとしては、*equalizeHist( image )*に入れる画像imageは、１チャンネルであるということである。RGBのものは入れることができないので、これを使う前にimageをグレースケールなどの１チャンネルに変換する必要がある。今回は*cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)*を使い、RGBからグレースケールへと変換を施している。

さて、この作業を経て得られる画像は次である。
![x-ray_hist.png](https://qiita-image-store.s3.amazonaws.com/0/221972/73c30fef-626e-d0d0-e88b-6dcd790639d2.png)
先ほどと比べて、画像右下部分のモヤがハッキリと写っているように見える。モヤがハッキリと見えるということは、そこに潜む疾病もわかりやすくなる、ということである。(こうした画像をCNNに入れて学習をさせ、レントゲン写真の自動診断をする、という研究が最近始まったという事実もある。ちなみに僕はそっちの人。)

#おわりに
ヒストグラム平坦化をすると、画像のコントラストがついて、ハッキリ見えるようになる。単純ながらも大事そうで、活用分野が非常に広そう。
amChartsのライセンスについて


*本内容は2018年3月末ごろに確認した情報です。*
*正式な手続きを経て得た情報ではありませんので、自己責任でご活用ください。*
## amChartsのライセンス形態
計測した温度データを可視化するために、グラフライブラリをいくつか試してみました。
`highcharts`の仕様が抜群に洗練されていて素晴らしいなと思ったのですが、商用利用にはライセンスが必要とのことで断念。`c3.js`は完全無料ですが少し使いづらいし、見た目がちょっと・・・と決定打に欠けます。
そんな中、`amCharts`が見た目、使いやすさともに秀逸で大変魅力的に感じました。ただし、ライセンスの形態がはっきりしません。

『amCharts ライセンス』で検索してたどり着いた日本語の個人サイトには、「linkware license（無料だが、グラフの右下にリンクが表示される）は商用利用不可」との解説がありました。
それならちょっと高額でも`highchatrs`のライセンス購入の方が良いかなぁと半ば諦めかけたのですが、ふと[amcharts.com](https://www.amcharts.com/download/)からダウンロードしたファイルに同梱されている`licence.txt`を開いてみると次のような記載があります。


>*********************************************************************************
>This AmCharts software is free under a linkware license.
>
>This means you may not remove or hide in any other way link to amcharts
>web site - www.amcharts.com.
>
>If you wish to remove the link, you should purchase commercial license.
>
>You may not redistribute, sublicense or sell this program without written
>permission of Antanas Marcelionis, the author of amcharts software.
>
>This software is provided without warranty.
>*********************************************************************************
>A commercial version (without link) is available at amCharts's website:
>http://www.amcharts.com/online-store/
>*********************************************************************************


英語が苦手なのでなんだかよくわかりませんが、「`www.amcharts.com`へのリンクを外したければライセンスを購入してね」と書いてありますが 、「linkware licenseは商用利用不可」とは記載されてはいないように思います。

英語が苦手な人間が深く考えてもよくわからないので、サポートに直接メールで聞いてみることにしました。

↓やり取りのメール文面
![screenshot_05.jpg](https://qiita-image-store.s3.amazonaws.com/0/264410/5719dd92-cfc9-b128-ca67-f4530dbf3126.jpeg)


>【質問＠以下のような文面のつもり】
>商用的な企業のイントラネットに導入する際、「linkware（無料ライセンス）」を利用することができますか？

>【回答＠超意訳】
>はい、私たちのサイトへのリンクがそのまま維持されている限り、どのようなサイトでも「linkware」を利用することができます。

「商用的な企業のイントラネット」という若干控えめな条件で質問したのですが、「linkwareならどのようなサイトでもOK」という太っ腹な回答をいただきました（・・・って意味ですよね？）。

うーむ。やはりリンクを消さない限り、商用サイトでも無償で利用してよいみたいです。
ということで、今後は`amCharts`メインで検討することにします。
angular-notifyで通知が自動で非表示にならないようにする方法

## angular-notifyとは

angular-notifyは、通知の表示処理についてのangularjs拡張ライブラリーです。  
[デモページ](https://cgross.github.io/angular-notify/demo/)があるのでこちらで動作を試してみると分かりやすいです。  
ソースコードは[github](https://github.com/cgross/angular-notify)上にあります。

## angular-notifyの使用方法
`notify()`を呼ぶことで通知を表示することができます。  
引数には`string`または`object`を取ることができます。  
objectのパラメータにはたとえば以下のものを指定できます。  
パラメータを引数として渡すことで通知の表示の仕方を変えることができます。
 - `message` - 通知に表示するテキストを指定できます。
 - `duration` - 通知が表示される時間（ミリ秒）を指定できます。
 - `position` - 通知の表示される位置を指定できます。値には`right`, `center`, `left`のみが指定できます。

他にも引数として渡せるパラメータがあるので詳細はREADME.mdを見てください。

## 通知が自動で非表示にならないようにする方法

それでは本題に入ります。  
README.mdを読むと通知を非表示にしないためには`duration`に`0`を指定するとありました。  
しかし`0`にセットしたのに通知が自動的に非表示にされてしまいうまく行きませんでした。

仕方がないのでソースコードを読んでみると、  
どうやらangular-notify.jsの21行目が上手くいかない原因のようでした。

```js
args.duration = args.duration ? args.duration : defaultDuration;
```

`0`は`false`として評価されるため、`args.duration`に`0`ではなくデフォルト値が入ってしまっていました。  
これを回避するには`0`の代わりに`"0"`を使用するなどが考えられます。  
`Boolean(String)`は`true`として評価されるため`"0"`を指定すれば`args.duration`に`"0"`が入ります。  

実際に表示を自動的に消す処理は104~108行目にあり、

```js
if (args.duration > 0){
  $timeout(function(){
    scope.$close();
  },args.duration);
}
```

`"0" > 0`は`false`として評価されるので$timeoutがセットされず自動的に非表示にならないようになります。
Vue.js2+Vuefire+firebaseその他もろもろで欲しいもの管理アプリ

##概要
Vue.jsの勉強がてら、あったらいいなと思っていた欲しいもの管理アプリを作成しました。
折角なのでアウトプット！ということでQiita初投稿です。
##使ったもの
1.Vue.js2(vue-cli)
2.Vuefire
3.firebase
4.vue-router
5.その他css一部コピペ
最初はライブラリ無しでやろうと思ったのですがfirebaseとVueのバインディングやデータプッシュ時のkeyの管理がとても面倒なのでVuefireというライブラリを使用しました。また画面遷移もVueオフィシャルでVue-routerという素晴らしいものがあったので利用しました。
##機能
ログイン、新規登録（FirebaseのAuth認証）
新規欲しいものの登録、編集、削除（カードにマウスオーバーでボタンが出ます）
ログアウト
RTBDにデータを常に同期
##成果物
firebaseのホスティングでそのまま公開しました。
<a href="https://vue-fire-todo.firebaseapp.com/#/">成果物</a>
accountの新規作成もできますがデモ用のアカウントもよういしてあるのでご自由にお使いください。
email:demo@demo.com
pass:demodemo
最初簡単なTodoのつもりで作ってたのでプロジェクト名がTodoなのは気にしないでください。
コード→<a href="https://github.com/unotovive/VFire">設計図共有サイト</a>
##感想と詰まったところ
Vueすごい
.vueで一つにまとまったコンポーネントになるのがとても便利だった
→親子間コンポーネント同士でのイベントの発火やデータの受け渡しは若干面倒だった印象（Anguarとかよりはマシ。。？）
<b>Vue1系とVue2系で仕様が全然違うので調べながら描くのにとても時間がかかった＋Vuefireのドキュメントもちょくちょく変わってて使えない所とかがあった</b>のが一番今回で苦労した点でした。
でもVueすごい
##展望
割と実用性のあるものが作れたのでしっかりとアラートなど実装してもう少し機能増やせたらなと思います。あとほしい！って思ったときにPCの前にいるよりスマホ持ってることのが多そうなのでレスポンシブ対応もしたいです。
##さいごに
初投稿のため至らない所も多かったと思いますが読んでいただきありがとうございます。
バグ、指摘、機能追加の要求などなんでもお気軽にお申し付けください。

Author：unotovive
c++で画像処理〜メディアンフィルタ作ってみた〜

# メディアンフィルタとは
メディアンという名の通り、中央値を利用した平滑化フィルタのことである。**ノイズ除去**に利用される。

ノイズを除去する方法には他に、平均化フィルタの利用などが挙げられる。
両者の最大の相違点はエッジが残るか残らないかだ。

平均化フィルタは画素値の合計をフィルタ数で割るため、エッジがぼやけてしまう。
しかし、メディアンフィルタではフィルタ内画素の中央値を利用するため、**エッジが残りやすい**。

画像のノイズ処理をしたい。だけどエッジはぼやけさせたくない。
そんな時に活躍するだろう使いやすそうなフィルタである。

#実装に至った動機
洗いざらいに話すとテスト対策。

# 開発環境・使用言語など
- 使用言語 : c++
- 開発環境 : Xcode version9.4
- Opnecvを利用。



#ソースコード
```cpp:median_blur.cpp
#define FILE_NAME "/*お好きなように*/"
#define M 1

//中央値を取得する関数
int getMedian(int array[], int num){
    //最初に配列を並び替える maxソートで行った
    int damy = num;
    int i;
    int v;
    
    for(i=0; i<num; i++){
        for(v=0; v<damy-1; v++){
            if( array[v] < array[v+1]){
                int tmp = array[v+1];
                array[v+1] = array[v];
                array[v] = tmp;
            }
        }
        damy = damy - 1;
    }
    int median;
    return  median = array[num/2+1];
}

int main(int argc, const char * argv[]) {
    cv::Mat src_img = cv::imread(FILE_NAME,0);
    cv::Mat dst_img = cv::Mat(src_img.size(),CV_8UC1);

    if(src_img.empty()){
        cout << "File is not opened." << endl;
        return -1;
    }
    
    
    //注目画素をフィルタの中央値で置き換える処理
    int array[(M*2+1)*(M*2+1)] = {0};
    for(int i=0; i<src_img.rows; i++){
        for(int v=0; v<src_img.cols; v++){
        //画像端は黒く塗りつぶす。
            if( i < M || v < M || src_img.rows - 1 - M < i || src_img.cols - 1 - M < v){
                dst_img.at<unsigned char>(i,v) = 0;

            }else{
                int count=0;
                for(int y=(-M); y<=M; y++){
                    for(int x=(-M); x<=M; x++){
                        array[count] = src_img.at<unsigned char>(i+y,v+x);
                        count = count + 1;
                    }
                }

                //注目画素を中央値で置き換える
                dst_img.at<unsigned char>(i,v) = getMedian(array, (M*2+1)*(M*2+1));

            }
        }
    }
    
    
    //画像の表示
    cv::imshow("median", dst_img);
    cv::imshow("input", src_img);
    cv::waitKey();
    
    return 0;
}
```

おそらく、中央値の求め方、画像端の処理の方法、フィルタの画素にどうアクセスするかがわかっていれば書けるだろう。

プログラムを組む過程においてつまづいたところはgetMedian関数のreturn値だ。

`array[num/2];`

これではいけなかった。
なぜならフィルタ配列の要素数は奇数であることが前提だからだ。
偶数であるならば問題ないが、奇数だと切り捨てが発生してしまう。
例えば9/2なら4だ。フィルタサイズが3x3だった時、中央値は5番目の要素の値になるのでこれでは間違っている。
正しくは上記プログラムの通り、こうだ。

`array[num/2+1];`

これでちゃんと中央値が取れる。

###出力画像はないの？
出力画像については著作権がどうなってるかわからないので、掲示しない方向で。
確認が取れたら載せようと思う。

#Opencvでメディアンフィルタ
一応Opencvのメディアンフィルタも載せておく。

`cv::medianBlur(src_img, dst_img, filter_size);`

引数はそれぞれ、入力画像、出力画像、フィルタサイズだ。
3x3のフィルタであれば、fileter_sizeは3となる。

#まとめ
- メディアンフィルタはエッジを残したまま平滑化できる。
PythonでIPアドレスのフォーマットをチェックする

PythonでIPアドレス(IPv4)のフォーマットをチェックする場合の一例です。

```python
import socket

def check_ipaddr_format(ipaddr):
    msg = ""
    result = True
    try:
        socket.inet_aton(ipaddr)
    except socket.error:
        msg = "Bad IP address (%s) " % ipaddr
        result = False
    return result, msg
```

# 補足
* socketモジュールのinet_atonメソッドは本来、IPアドレスの文字列を32ビットのバイナリ形式に変換する用途で使用するメソッドですが、上記の例では、inet_atonメソッドがIPアドレスの形式に不正がある場合、例外エラー(socket.error)を返却する動作を利用しています
* 上記の方法はIPv6のアドレスはチェック出来ません
分からない人に読んで欲しい！ 超ざっくりMakefile

# 何の話？
Makefileについて超ざっくり説明したもの。

**「Makefileが分からん」**
**「解説を読んでもやっぱり良く分からん」**

という人に読んで欲しい（私がそうだった・・・今でも分からんことは多いが）。

# Makefileって何？
「作りたいもの」、「材料」、「作り方」が書かれたファイル。
**イメージは料理のレシピ。**

# 書き方は？
超ざっくり以下のように書けば良い。
「作り方」の前にはスペースではなく**タブ**を入力。

```Makefile:Makefile
作りたいもの: 材料
        作り方
```

例えば「hello.cからhelloというプログラムを作りたい」という場合は以下のようになる。

| 超ざっくり用語 | 今回の例 |
|:-:|:-:|
| 作りたいもの | プログラム（hello） |
| 材料  | ソースコード（hello.c） |
| 作り方 | ビルドコマンド |

```:Makefile
hello: hello.c
        gcc -o hello hello.c
```

上のMakefileを3行でまとめるとこんな感じ。

 - helloを作る時の材料はhello.cだよ
 - 作り方は「gcc -o hello hello.c」だよ
 - **材料が揃ったら**作り方を実行してね

Makefileが出来上がったらmakeコマンドを実行するとhelloが作られる。

# 材料が足りない時は？
前述の通り、Makefileでは材料がそろってから作り方が実行される。
ただし、作りたいものの材料は揃っていないことだってある。
そういう時は「材料の作り方」もMakefileに書いてあげる。

ということで、さきほどのMakefileを少しだけ変えて説明する。

```:Makefile
hello: hello.o
        gcc -o hello hello.o

hello.o: hello.c
        gcc -c hello.c
```

helloの材料がhello.cからhello.oに変わった。
当初はhello.cからhelloを作りたかったので、hello.oという材料はない。
この場合、make実行時にどういう挙動になるのかをまとめてみる。

 1. helloの材料はhello.o
 2. hello.oという材料は存在しないのでhelloの作り方は実行できない
 3. Makefileの中にhello.oの作り方が書いてないか探す
 4. hello.oの材料はhello.cと書いてある
 5. hello.cは存在するのでhello.oの作り方（gcc -c hello.c）を実行する
 6. hello.oが出来上がった
 7. ようやくhelloの材料が揃ったのでhelloの作り方（gcc -o hello hello.o）を実行する
 8. helloが出来上がる
 
# おわりに
Makefileについてイメージしやすい言葉で書いたつもりですが、いかがだったでしょうか。
Makefileを勉強していて「ターゲット」、「依存ファイル」と言われても中々覚えられなかった
私ですが、料理のレシピをイメージすると理解しやすかったので、同じように悩んでいる人の
役に立てればと思い、書いてみました。

Makefileに詳しい人から「違うぞ！」と怒られそうですが、
分からない人向けなので勘弁してください m(_ _)m
PythonでMACアドレスのフォーマットをチェックする

PythonでMACアドレスのフォーマットチェックを行う場合の一例です。

```python
import re

def check_macaddr_format(macaddr):
    msg = ""
    result = True
    macaddr_format = "[0-9a-f]{2}([-:])[0-9a-f]{2}(:[0-9a-f]{2}){4}$"
    if not re.match(macaddr_format, macaddr.lower()):
        msg = "Bad MAC address (%s)" % macaddr
        result = False
    return result, msg
```
uGUIにTransformを持つオブジェクトがあった場合にUnitiyEditorとAndroidでは挙動が違った

*unity vestion: 20181.1.1*

地味にはまった、uGUIのでの話。

`Canvas>EmptyObject>Target`

という階層でオブジェクトを作ろうとしたときに、`EmptyObject`を(誤って)普通のTransformのオブジェクトにしてしまった。
このときUnityEditor上では、問題なく意図したポジションで`Target`は表示される。
しかし、**実機Androidでは位置が崩れる**。

解決方法はもちろん`EmptyObject`をRectTransformのuGUIオブジェクトにする。

*余談*
なぜEmptyObjectが普通のTransformのオブジェクトだったかというと、スクリプト上で`new GameObject()`して作っていたから。
Pure-FTPdでポート変更をしたい。

#概要
Pure-FTPdでポート変更をしたいと思った。それ以上でもそれ以下でもない。Ubuntu 16.04でやってみます。
#設定方法
```shell:設定
#ポート810、なおかつバインドするIPを指定しない。（0.0.0.0がバインドされる）
echo ",810" > /etc/pure-ftpd/conf/Bind

#アドレス、192.168.1.10でなおかつポート1919でバインド。
echo "192.168.1.10,1919" > /etc/pure-ftpd/conf/Bind
```
あいにくドメインでバインドできる記載はありませんでした。

```shell:適用
service pure-ftpd-mysql restart
```
#れふぁれんす
https://www.howtoforge.com/community/threads/how-change-pure-ftpd-port-21-to.43452/
【入門者向け解説】短時間で理解するDocker

Dockerは私のようなシステム(特にインフラ系)に弱い人間にとって、その弱さを補ってくれるツールです。なので、ちょっと寄り道とも思えますが学習しました。
Docker関連の参考記事として下記も書いています。

- [Windows 8.1でDocker ToolboxをインストールしてDockerを動かす](https://qiita.com/FukuharaYohei/items/a913f5ef5a5aa550f46a)
- [初心者用Docker基本コマンド一覧(新旧スタイル対応)](https://qiita.com/FukuharaYohei/items/ef5cf790b5269e73cdb3)

#概要と用途
Dockerは軽量な仮想化ツールです。

- 開発・テスト環境を素早く構築：[Docker Hub](https://hub.docker.com/)という様々なDockerのイメージを公開している場所があるので、それを使うことで簡単に環境構築ができます。また、公開しない形のファイルからも環境構築が可能。とにかくお手軽です！
- 開発・テスト環境を他の人と共有：自身やチームの環境を保存でき、他の人と共有ができます。個人個人で環境差異がなくなるのがいい点です。

#システムアーキテクチャ
システムアーキテクチャをお絵かきしました。左がDockerで、右がVMwareなどによる仮想化です。(よくも悪しくも)Dockerの方が独立性が低く、コンテナ間でいろいろなリソースを共有してくれます。
![10.DockerAndVirtual.JPG](https://qiita-image-store.s3.amazonaws.com/0/134273/03aa8a98-109f-db7d-7c50-b27d63dadbbf.jpeg)

Windowsでの使い方については[「「Windows Serverコンテナ」「Hyper-Vコンテナ」「Linuxコンテナ」「Docker」の違いとは？」](http://www.atmarkit.co.jp/ait/articles/1611/04/news028.html)を参照ください。

#Dockerfileでのイメージ共同管理
Dockerfileを使うことで他人とイメージの共同管理ができます。Dockerfileの作り方は記事[「効率的に安全な Dockerfile を作るには」](https://qiita.com/pottava/items/452bf80e334bc1fee69a)が参考になりました。作り方によって大きくイメージの容量などが異なるので[公式サイトのDockerfile ベストプラクティス](http://docs.docker.jp/engine/articles/dockerfile_best-practice.html)に書かれていることが重要です。
Dockerfileからのイメージ作成は[「初心者用Docker基本コマンド一覧(新旧スタイル対応)」](https://docs.docker.com/engine/reference/commandline/build/)を参考にしていください。
Linux備忘録

#####ルートユーザー
`$ sudo su` => root@id:/home/ubuntu#
#####離脱
`$exit` =>`~$`


・ファイル作成
`echo` "hello world" `>` hello.txt
・ファイル出力
`cat` hello.txt 
・ファイルのコピー
`cp` hello.txt morning.txt
。ファイル名称変更
`mv` hello.text new.text
ーーーーーーーーーーーーーーーーーーーーーーーーーー
・ディレクトリ作成
`mkdir` hello
・ファイル名を変更してコピー
`cp` hello.txt hello/morning.txt
・ディレクトリ名変更
`mv` hello morning