OmniAICreator/Qiita-1.07M huggingface dataset:
[WIP] WSL で Movidius Neural Compute Stick 使いたい

# Movidius Neural Compute Stick とは

Neural Compute Stick ( 以降、NCS ) は、USB で接続するだけで Deep Learning の高負荷演算のリソースとして利用できるという優れもの。Intel® 社製。

https://developer.movidius.com/

Myriad 2 という VPU ( Vision Processing Unit ) を搭載していて、たった 1W で 100 GFLOPS 以上の性能を持つ。( 凄いのかどうかよく分からんが )

https://www.movidius.com/solutions/vision-processing-unit

## NCS を利用できる Library 

- TensorFlow
- Caffe

## NCS を利用できる Platform

- Ubuntu 16.04
- Raspberry Pi 3 Model B
- MacOS ( Ubuntu 16.04 on VirtualBox )
- Windows ( Ubuntu 16.04 on VirtualBox )

VirtualBox が使えるので、幅広く利用することができる。

# WSL を使いたい理由

しかし、できれば WSL ( Windows Subsystem for Linux ) を使いたい。
理由は一つで、**Docker for Windows のヘビーユーザなので Hyper-V を切る訳にはいかないが、VirtualBox は Hyper-V と共存できない** から。

# WSL でやってみる

何か不安はあるけれど、取り敢えずやってみる。
手順は[公式の通り](https://developer.movidius.com/start)に進める。

## Get Start

```powershell
PS> bash
```

```bash
sudo apt-get update
sudo apt-get install git python3 python-pip python3-pip

git clone https://github.com/movidius/ncsdk.git
cd ncsdk
make install
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/20198/9ce31b2a-ac16-3c4b-01a1-2827a1565828.png)

駄目だった。
ちなみに、エラー部分はこれ。

```sh:install-ncsdk.sh
...
# Update udev rules
echo "Updating udev rules..."
$SUDO_PREFIX cp $SDK_DIR/udev/97-usbboot.rules /etc/udev/rules.d/
$SUDO_PREFIX udevadm control --reload-rules   # <-- ここ
$SUDO_PREFIX udevadm trigger
...
```

実際に実行してみると、

```bash
sudo udevadm control --reload-rules
echo $?

# 2
```

取り敢えず何かの問題が起きている。
そもそも、USB デバイスは見えているのか。

```bash
cd examples/apps/hello_ncs_py/
make run

# making run
# python3 hello_ncs.py;
# Error - no NCS devices detected, verify an NCS device is connected.
```

どうやら、見えて無さそう。

## ひとまず、仲間を見つける

ググったら、全く同じ問題にぶち当たっている人を発見。

https://ncsforum.movidius.com/discussion/515/installation-issue

> Had missed to mention in the earlier post. I am trying to install on Linux Subsystem in Windows. Through the other forums I found that there are some known issues with UDEV in Linux Subsystem in Windows and also the USB drive will not be detected.

諦めた模様。
しかし、`some known issues with UDEV` ってなんだろう。

## 結局、WSL は USB デバイスが使える？

[Serial Support on the Windows Subsystem for Linux](https://blogs.msdn.microsoft.com/wsl/2017/04/14/serial-support-on-the-windows-subsystem-for-linux/)

COM Port にはアクセスできる模様。

[File System Improvements to the Windows Subsystem for Linux](https://blogs.msdn.microsoft.com/wsl/2017/04/18/file-system-improvements-to-the-windows-subsystem-for-linux/)

Block Device としても正常に mount できる模様。

[Add USB Device Support](https://wpdev.uservoice.com/forums/266908-command-prompt-console-bash-on-ubuntu-on-windo/suggestions/16759696-add-usb-device-support)

なんか終わった気になってるけど、『USB Device はまだ繋がらないんだから Close すんなよ』という流れになっている。やっぱり無理か・・・。

# 2/22 時点での対策

## VirtualBox 上から利用

WSL は諦めて、サブマシン ( Windows 10 ) に VirtualBox 入れて構築。

でも・・あれ・・・なんか・・USB デバイスが上手く繋がらない・・・

公式に VirtualBox 対応ってあるのに。

## Raspberry Pi から利用

結局、VirtualBox も諦めて、今は Raspberry Pi に挑戦中。

# 感じたこと

普段使っているマシンに USB ドングル差したら、直ぐに Deep Learning の開発が始められる、みたいなコンセプトだと思っていたんだけど、今の所それを感じる事ができてない。
Raspberry Pi 3 Model BとUSBカメラで撮影した画像をスマホで見る

備忘録のため、ほぼ参考にしたサイトの写経

#参考にしたサイト
https://qiita.com/shin1kt/items/e2f57fcff95f5196cd4d

#手順
- motionのインストール

```ruby
$ sudo rpi-update
$ sudo apt-get update
$ sudo apt-get -y install motion
```

-起動時の設定
ラズベリーパイ起動時にmotionを起動するように設定

```ruby
$ sudo leafpad /etc/default/motion
```

```ruby
# set to 'yes' to enable the motion daemon
# start_motion_daemon=yes ← noからyesに変更します
```
-ウェブブラウザに表示する画像の設定
Webブラウザで表示する画像のサイズや撮影間隔設定

```ruby
$ sudo leafpad /etc/motion/motion.conf
```

```ruby
# Image width (pixels). Valid range: Camera dependent, default: 352
# width 640 ← 横幅を設定します。大きすぎる場合は320や352など
 
# Image height (pixels). Valid range: Camera dependent, default: 288
# height 480 ← 高さを設定します。大きすぎる場合は240や288など
```
1秒間にキャプチャする画像の最大数を設定します。コマを多く撮る場合は数値を大きくする。

```ruby
# Maximum number of frames to be captured per second.
# Valid range: 2-100. Default: 100 (almost no limit).
# framerate 100 ← Webブラウザで見るだけならば2
```
Webブラウザで見る場合のポート番号を指定します。このままでもOK

```ruby
# The mini-http server listens to this port for requests (default: 0 = disabled)
#　stream_port 8081
```

設定が終わったらファイルを保存して、motionを再起動

```ruby
$ sudo /etc/init.d/motion restart
```

-ファイアウォールの設定
ファイアウォールの状態を確認

```ruby
$ sudo ufw status
```

ファイアウォールを有効にしてる場合はカメラの画像をWebブラウザで表示できるように許可

```ruby
$ sudo ufw allow proto tcp from 192.xxx.xxx.xx/24 to any port 8081
```

192.xxx.xxx.xxの部分にはRaspbery PiのIPアドレスを入れる
IPアドレスはデスクトップ右上のネットワーク接続のアイコンにカーソルを合わせると表示される
![IMG_20180222_215640.jpg](https://qiita-image-store.s3.amazonaws.com/0/240139/fc8fbaee-30ba-3c12-ee19-80232bcb731e.jpeg)

IPアドレスは192.xxx.xxx.xxの最後のxxが0にされた、ノーマライズされた値（192.xx.xxx.0）が登録された

外出先からVPN経由で画像を確認する場合はこちらも許可

```ruby
$ sudo ufw allow proto tcp from 10.8.0.0/24 to any port 8081
```

ファイアウォールの状態を再確認

```ruby
$ sudo ufw status
```

- スマホ（PCでもOK）ウェブブラウザで画像を確認する
ただし、同じネットワーク内につながったスマホでないと見られない
 
```ruby
http://192.xxx.xxx.xx:8081/
```
ノーマライズされた値（192.xxx.xxx.0）ではなく、IPアドレスの192.xxx.xxx.xxを使う

##次の目標
- 外部ネットワークからUSBカメラの画像を見る

https://qiita.com/kinpira/items/c9e6dc910e8d96e8c19b
偏りのあるデータをランダムフォレストでクラス分類を行う際は class weight を設定した方がよい

# 概要

言いたいことはタイトルに書いてある通りです（笑）

実際のサービスのデータを用いてデータ分析したり様々な学習モデルを作成していると、だいたいはデータに偏りがあることがほとんどです。
例えば、スパムメールの分類などは良い例なのですが、殆どのメールが正常である中で数少ないスパムの分類をすると、「全部正常だと分類したほうが正解率が上がってしまい表面上は良いモデル」が出来上がってしまい、実用に耐えないものが出来てしまいます。

今回はそういった偏りのあるデータセット（不均衡データといいます）に対してクラス分類モデルを作成する際のポイントを記述します。

分類を行うモデルはランダムフォレストを指定します。しかし、他の分類モデルでも応用できる考え方ですので、これを押さえておくと良いと思います。

[scikit-learnのRandomForestClassifierのドキュメント](http://scikit-learn.org/stable/modules/generated/sklearn.ensemble.RandomForestClassifier.html)によると、 `class_weight` のパラメータを `balanced` を指定するとクラスごとのサンプル数の重みを自動で付けてくれるとのこと。便利ですね。
中身の計算方法は `n_samples / (n_classes * np.bincount(y))` です。

# 実際にデータを用いて確かめる

不均衡なデータに対してclass_weightを考慮しない分類と考慮する分類でどのような差異があるのか見てみましょう。

今回用いたpythonコード( jupyter notebook形式 )： https://github.com/kazuki-hayakawa/RandomForest_imbalanced/blob/master/RandomForest_notebook.ipynb 

スパムの分類のように正しいクラスを正例、誤りなどに用いられるクラスを負例と言ったりしますが、今回はサンプル数の少ない方を負例と呼称します。
今回は正例を7000, 負例を100という不均衡データを用意しました。

```python

# 不均衡データセットの作成
import numpy as np 

np.random.seed(0)

X1 = np.random.rand(7000, 2)  
X2 = np.random.rand(100, 2) *0.2 + 0.9

y1 = np.array([1 for _ in range(7000)])
y2 = np.array([2 for _ in range(100)])
```

正例のラベルを1, 負例のラベルを2としています。

![スクリーンショット 2018-02-22 22.56.38.png](https://qiita-image-store.s3.amazonaws.com/0/175708/00cd5b51-f0ce-ec85-764c-50ce2d9a16c5.png)

計算のためにデータを7:3の割合で訓練データとテストデータに分割します。

```python 
from sklearn.cross_validation import train_test_split

X = np.concatenate([X1, X2])
y = np.concatenate([y1, y2])

# データを 7:3 で訓練用データとテストデータに分割する
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)
```

## 不均衡データを考慮しない分類
ではまずは、不均衡データを考慮しないで普通に分類をしてみます。
（サンプルなのでグリッドサーチなどによるハイパーパラメータの調整は行っていません）

```python
from sklearn.ensemble import RandomForestClassifier

# 不均衡データの考慮がない場合
clf = RandomForestClassifier()
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
```

結果は以下の通りです。
（乱数生成なので人によっては違った結果が出てくることがありますが、デモなのでご容赦ください）

```
正解率： 0.993896713615
負例の予測数: 21
実際の負例の数: 30
負例を正しく識別できている割合: 0.7
```

## 不均衡データを考慮する分類

では次にデータの偏りを考慮してclass_weightを明示的に指定して分類を行います。

```python
# 不均衡データの考慮をする場合
clf = RandomForestClassifier(class_weight='balanced')
clf.fit(X_train, y_train)
y_pred = clf.predict(X_test)
```

結果は以下のとおりです。

```

正解率： 0.992018779343
負例の予測数: 25
実際の負例の数: 30
負例を正しく識別できている割合: 0.8333333333333334
```

## まとめ

結果を見比べてみると

| | 不均衡を考慮する | 不均衡を考慮しない |
| ----- | ----- | ----- |
| 正解率 | 0.9920 | 0.9938 | 
| 負例の検出率 | 0.833 | 0.700 |

このように、不均衡を考慮しなくてもそれなりの正解率は出ていますが、これは「ほとんど1のラベルなら全部1とみなしてもほとんど正解してしまう」現象ですね。
しかし、不均衡を考慮することで、負例の検出率が上がっていることがわかると思います。
これはスパムを間違って正しいメールだと誤認識しないというような意味を持ちます。

実際のサービスにおいては負例の検出力が高いモデルが求められている場合がありますので、モデルの用途やデータセットに応じてこういった工夫が必要になるかと思われます。


# 参考にしたサイト
[Scikit-learnによるランダムフォレスト](http://data-science.gr.jp/implementation/iml_sklearn_random_forest.html)
→ RandomForestClassifier の他のパラメータの意味が書かれていて勉強になりました。
KeyCloakを使えるようにするところまで


例によって自分用備忘録。
とりあえず8080番ポートでアクセスできるようになるまで。
KeyCloakのバージョンは3.4.3

##コマンド多いのでrootにスイッチ
```$ sudo su -
```
##必要なコマンドをインスコ
```# yum install -y unzip git wget
```
##jdk8、mavenのインストール
```
# wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jdk/8u131-b11/d54c1d3a095b4ff2b6607d096fa80163/jdk-8u131-linux-x64.rpm
# rpm -ihv jdk-8u131-linux-x64.rpm
# cd /opt
# wget http://ftp.riken.jp/net/apache/maven/maven-3/3.5.2/binaries/apache-maven-3.5.2-bin.tar.gz
# tar xzvf apache-maven-3.5.2-bin.tar.gz
# mv apache-maven{-3.5.2,}
```
##PATHを通す
```
# vi ~/.bash_profile

//最終行に以下を追加
export JAVA_HOME=/usr/java/default/
export PATH=$PATH:/opt/apache-maven/bin

# . ~/.bash_profile
```

##KeyCroakのインストール
```
# wget https://downloads.jboss.org/keycloak/3.4.3.Final/keycloak-3.4.3.Final.zip
# unzip keycloak-3.4.3.Final.zip
```
##KeyCloak起動してアクセス
```
# cd keycloak-3.4.3.Final
# firewall-cmd --zone=public --add-port=8080/tcp --permanent
# firewall-cmd --zone=public --add-port=80/tcp --permanent
# firewall-cmd --zone=public --add-port=443/tcp --permanent
# firewall-cmd --reload
# bin/standalone.sh -b 0.0.0.0
```

##最後らへんに以下のログが表示がされたら起動完了。
```
INFO  [org.jboss.as.server] (ServerService Thread Pool -- 45) WFLYSRV0010: Deployed "keycloak-server.war" (runtime-name : "keycloak-server.war")
INFO  [org.jboss.as.server] (Controller Boot Thread) WFLYSRV0212: Resuming server
INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0060: Http management interface listening on http://127.0.0.1:9990/management
INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0051: Admin console listening on http://127.0.0.1:9990
INFO  [org.jboss.as] (Controller Boot Thread) WFLYSRV0025: Keycloak 3.4.3.Final (WildFly Core 3.0.8.Final) started in 29609ms - Started 545 of 881 services (604 services are lazy, passive or on-demand)
```
___
KeyCroakを終了したいときはCtrl + C で。

ブラウザから以下URLにアクセスしてKeyCloakの画面出てきたらとりあえずオッケー。
```
 http://【IPアドレス】:8080/auth/
```
___
##次回
今回構築したKeyCroakで、SAMLを使ってWordPressとのSSOをやっていく気持ちがある。
もしくはADFSでやってみる気持ちがある。
Windows環境のmakeでこけた備忘

c++で作られた[fastText](https://github.com/facebookresearch/fastText)をWindows環境でコンパイルしようとしたらmakeでこけてはまった話
（fastTextは結果的にあんまり関係ないです。C++コンパイラの話です）

# WindowsでC++のソースをコンパイルしたい
c++で作られたfastTextというものを使いたかったのですが、gitにソースしか落ちてなかったのでコンパイルする必要がありました。

そこでGitをインストールしたときになんか入ってた（Git Bash）MinGWを使えばいけるんじゃね？と思い、[Windows(Bash on Windows)でfastTextを使う](http://tadaoyamaoka.hatenablog.com/entry/2017/04/19/000832)を参考に進めてみました。（Bash on Windowsっつってんだろというツッコミはスルーで）

# はまった経緯
とりあえずgitでDLしてmakeするのね、g++いるのねってことがわかりました。

ここでg++のDLにはMinGWを[正規ルート](http://www.mingw.org/)でインストールしてパッケージ管理画面からg++を追加してインストールする必要があるらしいのでインストールして追加。
ここでmakeとg++はコマンドがきくようになりました。

ということでfastTextをDLしてコンパイルじゃー！


```
$ git clone https://github.com/facebookresearch/fastText.git
$ cd fastText
$ make
```

と思ったらエラーでた。。。。

```
'thread' is not a member of 'std'
```

えーなんで？？？
と思いましたが、どうやらいろいろと調べた結果、MinGWさんはg++をいれてもPthreadが入っていないからできないんだとかなんとか。。むむむ（POSIX のスレッド（pthread）をサポートしてないんだとか）
いろいろ調べて[MinGW用のPthreadをDLして配置](https://sourceforge.net/projects/mingw/files/MinGW/Base/pthreads-w32/pthreads-w32-2.8.0-3/)してみてもうまくいかず、、時間切れでした。

# 解決策
悔しすぎるので帰ってから家のPC（Win）で再チャレンジすることに。

ここでMinGWを使うのをやめました。
そもそもc++の新しいバージョンに対応してなさそうだったので…。。。ちーん

気を取り直して、Pthreadとかも対応しているCygwinを使うことに。

[Cygwin](https://www.cygwin.com/)を公式からインストールし、
以下のパッケージ（Devel下）をDLしました（下の方は適当に選んだので不要だったかも）

* make
* gcc-g++
* ~~cygwin32-gcc-core~~（いらなかった）
* ~~cygwin32-gcc-g++~~（いらなかった）
* ~~mingw64-x86_64-pthreads~~（いらなかった）
* ~~mingw64-x86_64-winpthreads~~（いらなかった）

とりあえずこれでcygwin上でmakeが通ることを確認！！やったー
あー疲れた。。。

（追記）
Cygwin以外にも[msys2](http://www.msys2.org/)でもできるようです。本当はこっちのほうがいいのかも
Python3 正規表現で逆ポーランド記法

タイトル通りです。[AOJの問題](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=ALDS1_3_A&lang=jp)を解く上で、場合分けを減らしたかったので正規表現で書いてみました。[^1]

```python:python3
import re

def revPolish(f):
    f = re.sub(r'(\-?\d+\.?\d*)\s(\-?\d+\.?\d*)\s([\+\-\*/])(?!\d)',
        lambda m: str(eval(m.group(1) + m.group(3) + m.group(2))),
        f)
    if f[-1] in '+-*/':
        return revPolish(f)
    else:
        return f

if __name__=='__main__':
    print(revPolish(input()))
```

# 解説

## 1. 正規表現部分

`(\-?\d+\.?\d*)\s(\-?\d+\.?\d*)\s([\+\-\*/])(?!\d)`

簡単に言うと、「数値 数値 演算子」に一致させる表現です。

ただ負数がちょっと厄介でした。例えば以下の式があるとして、

```plain
1 2 -3 + +
```

`1 2 -`にマッチしてしまうんですよね…

これを回避するために[否定先読み](http://d.hatena.ne.jp/satosystems/20100519/1274237784)`(?!...)`を使いました。

## 2. 置換用関数

最初専用の関数を別に書いていたのですが、ここにしか使わないので`lambda`にしちゃいました。

正規表現を使っている段階で可読性もクソもないので、間違ったことはしていないと思います。

`lambda m: str(eval(m.group(1) + m.group(3) + m.group(2)))`

`eval`関数便利ですね。こいつがなければ結局場合分け処理になるところでした。

## 3. 再帰部分

上記正規表現のなすままに、計算可能な部分を計算して数値に置き換えて、それを再帰的に処理しています。

式の文字列`f`の最後が演算子かどうかで計算終了判定を行なっています。

最初は`f`内に演算子が残っているかで判断しようと思ったのですが、そうすると結果が負数だと無限ループすることに気づき、

さらに計算が全て終了すると右端の演算子が消えることに気がついた時にはもうこの形に落ち着いていました。

`if f[-1] in '+-*/':`

---

間違いや改善できそうな点があれば是非コメントください。

参考になれば幸いです。m(_ _)m

[^1]: AOJの問題と違い実数除算`/`も想定していますが、0割等のエラー処理は書いてません。
のじゃおじに憧れた社畜が3Dモデルに挑戦してみる

# 僕もVR空間でケモ耳になりたい！
 まぁ現時点ではオキュラスは持ってないしWebカメラすら無いという状況なんですが。
てか3Dモデリングなんてしたことないし絵なんか描けないし下地になるものは何もない！
でも挫折するまでは色々と足掻いていこうかと思います。

Unity→昨日初めてパソコンに入れた

sculptris→昨日初めてパソコンに入れた

今日3Dモデルをかじったことのある同僚に3Dモデルを学ぶためにsculptrisを入れた話をしたら
Blenderの方が使いやすいと言われた。

Blender→さっきパソコンに入れた。

もうね、こんなところからスタートですわ。
とりあえず物は試しと起動してみる

## sculptris
![初起動scuip.png](https://qiita-image-store.s3.amazonaws.com/0/240128/ed45d76f-6f51-1cfb-245a-6e54adec0900.png)

・・・まる？
とりあえず左側のアイコンをいじってみたけどちょっとへこんだり盛り上がったりする。

## Blender
![初起動blenmder.png](https://qiita-image-store.s3.amazonaws.com/0/240128/187e9a04-e425-e32c-57cc-827865b10923.png)
・・・しかく？
何の差があるのかよく分からん。
とりあえず左のアイコンいじってたら四角が回ったり増えたりした。

よし、これからわかりやすい解説サイトを探しに行く！！


Qiitaも初めて投稿してみる。おおぅ初めてばっかりだな。
線形最小二乗解の射影による理解

## 最小二乗解
$ x $ についての（連立）線型方程式
$$ Ax=b $$ を考えます。
$A$が $m \times n$ の実数行列で、$x$ が $n$ 次元のベクトル、$b$ が $m$ 次元のベクトルです。
$A$が正則であれば、$x=A^{-1}b$ と一意に解けますが、工学的な応用では、むしろこれが解けない場合を扱うことが多くあります。

$m>n$（$A$ が縦長）であるすると[^1]、条件の方が変数よりも多く、方程式としては不能（解なし）です。
[^1]: $A$はランク落ちしていないのを前提とする。つまり、$\mathrm{rank}(A)=n$ 。
そこで、$ || Ax-b ||^2 $ が最小になるような $\hat{x}$ を代わりに求めることがよく行われます。
$\hat{x}$ は最小二乗解と呼ばれ、以下の形で与えられることが知られています。
$$\hat{x}=(A^TA)^{-1}A^T b$$ 

最小二乗解の一番正統な（?）導出は、以下のように微分を使う方法です。
$ || Ax-b ||^2 $ を $x$ で微分して 0 とおくと、$ 2 A^T (A x - b) = 0 $ だから、最小二乗解 $\hat{x}$ が満たすべき方程式（正規方程式）は、
$$ A^T A \hat{x} = A^T b $$ と得られる。よって、最小二乗解は $\hat{x}=(A^TA)^{-1}A^T b$ と求められる[^2]。

しかし、最小二乗解は部分空間への射影として得られるという側面があり、これを理解することが、部分空間法やカルマンフィルタなどの応用上重要になります。
そこで、この記事では、最小二乗解の射影による解釈について考えてみます。

[^2]: $A$にランク落ちがなければ$A^TA$は正則で逆行列が存在する。

## 射影行列による理解
$A$ が $3\times2$ 行列として、図を描いて考えてみます。

![projection.png](https://qiita-image-store.s3.amazonaws.com/0/233564/350376c0-cf75-19fc-0db3-71c29eeba1b2.png)

$x$ を動かすと、$Ax$ は平面上の色々なベクトルを取ります。この平面は $A$の像 $\mathrm{Im}(A)$ です。
一方、$b$ は3次元空間上のベクトルであり、この平面外の成分を持つので、$Ax$ は $b$ と一致し得ません。
そこで、$||Ax-b||$ が最小になる場合を考えると、これは図のように、$Ax$ が $b$ を平面へ正射影したベクトルになっているときです。

$b$ を $\mathrm{Im}(A)$ へ正射影したベクトルは射影行列（[前回記事](https://qiita.com/takseki/items/e0de89ab82d4d287a0d7 "射影行列")） $P$ を使えば、
$$b_{\mathrm{Im}(A)} = Pb = A (A^T A)^{-1} A^T b$$ と書けます。
すると、$Ax$ が $b$ の正射影になっているという条件は、
$$A x = A (A^T A)^{-1} A^T b$$ と書けます。したがって、$$\hat{x}=(A^TA)^{-1}A^T b$$であることが分かります。

### 直交原理
$Ax$ が $b$ の正射影である、というのは、言い換えると、$A x - b$ が $A$ の像 $\mathrm{Im}(A)$ に直交することです。
これは、$A$ の列ベクトル $\\{a_i\\}$ を使えば、
$$a_i \cdot (Ax-b) = 0$$ であり、行列でまとめて書くと、
$$A^T (Ax-b) = 0$$ となり、やはり正規方程式が得られます。

$A \hat{x} - b$ が $A$ の像 $\mathrm{Im}(A)$ に直交するという性質は、「直交原理」とも呼ばれ、応用上重要になります。
[ActiveSupport]日付の範囲指定で便利なメソッド

###はじめに
ActiveSupportで便利だなと思った書き方の自分用メモです。
1年、1月、1日単位でループさせたい場合に簡潔に記載できます。

####コード

```ruby
# 現在の日付
today = DateTime.current
# => Thu, 22 Feb 2018 22:06:56 +0900

# 1年 (1月１日 ~ 12月３１日)
today.all_year.each { |d| }
# => Mon, 01 Jan 2018 00:00:00 +0900..Mon, 31 Dec 2018 23:59:59 +0900

# １ヶ月 (2月１日 ~ 2月28日までが範囲となる)
today.all_month.each { |d| }
#=> Thu, 01 Feb 2018 00:00:00 +0900..Wed, 28 Feb 2018 23:59:59 +0900

# 1日 (2月22日 00:00:00 ~ 23:59:59が範囲となる)
today.all_day.each { |d| }
# => Thu, 22 Feb 2018 00:00:00 +0900..Thu, 22 Feb 2018 23:59:59 +0900
```

####おまけ
ActiveSupportの実装の抜粋を記載します。
beginning_of_XX,end_of_XXを使用してさらに直感的で便利になるように考えられているのだと思います。 
もしall系のメソッドをしらなければ、自分で同じこと実装しそうですので、
beginning_of_xxでActiveSupportのソースを検索して確認するのも重要なことですね。
Rangeの範囲指定をeachしていることもわかりますね。


```ruby:active_support/core_ext/date_and_time/calculations.rb
# Returns a Range representing the whole year of the current date/time.
def all_year
  beginning_of_year..end_of_year
end

# Returns a Range representing the whole month of the current date/time.
def all_month
  beginning_of_month..end_of_month
end

# Returns a Range representing the whole day of the current date/time.
def all_day
  beginning_of_day..end_of_day
end
```
the sample of that put the focus on the next text when you input 2 digit

```html
<!DOCTYPE html>
<!-- [ published at 2018-02-22 20:27:13 ] -->
<html>
<script type="text/javascript">
function test(strText) {

  // AAAA含んでいる場合、
  if(strText.includes("AAAA")){
      // フォーカス元のnameを取得する
      var newstrText=strText.replace('AAAA','');
      // フォーカス元を取得する
      var n = document.getElementsByName(newstrText);
      // 2けた入力すると、
      if(n[0].value.length== 2){  
         // 次のテキストを選択する
          n[0].nextElementSibling.focus();
      }
  }

}
</script>
<head>
<body>

<input type="text" name="test1" class="cheadSeaKey" maxlength="2" value="" onkeyup="test('test1AAAA')" />

<input type="text" name="test2" class="cheadSeaKey" value="b" />


<!-- start dmp -->

</body>
</html>
```
Rails アソシエーション関連のエラー（has_many throughが通らない）

#該当のエラー
ActiveRecord::HasManyThroughOrderError 

Cannot have a has_many :through association 'Micropost#meats' which goes through 'Micropost#post_tags' before the through association is defined.

なかなか検索掛けてもでなかったので後に役立てばうれしい

#事例　

railstutorialからオリジナル派生で飲食関連のアプリケーションを作成中

https://qiita.com/tobita0000/items/daaf015fb98fb918b6b8
↑のありがたい記事を参考に

ポストモデル（micropost）にお肉モデル（meat）をタグ付けする形で投稿したいので
中間モデル（post_tag）を経由して上２モデル間のアソシエーションを結びたい

```rb:micropostモデル
class Micropost < ApplicationRecord
  
 
  has_many :meats , through: :post_tags
  has_many :post_tags , dependent: :destroy
end
```

```rb:中間モデル
class PostTag < ApplicationRecord
    belongs_to :micropost
    belongs_to :meat
    has_one :favorite
    validates :micropost_id , presence: true
    validates :meat_id , presence: true
end
```

```rb:お肉モデル
class Meat < ApplicationRecord
   validates :name , presence: true , length: { maximum: 20}
   has_many :microposts , through: :post_tags
   has_many :post_tags , dependent: :destroy
end

```


で、Micropost#create時にエラー。
どうやら中間モデルより先の目当てのモデルまでthroughしきれてないみたいだ。

#原因
https://github.com/rails/rails/issues/29123
↑参考

同じエラーを持ってる人が結構いた。
事例としては
Rails 5.0.0辺りから5.1.0辺りにアップグレードすると途端にエラーが出る方が多そうな印象。
よって考えられるのはrailsの仕様が変わっている模様。


```rb:micropostモデル
class Micropost < ApplicationRecord
  
 
  has_many :meats , through: :post_tags
  has_many :post_tags , dependent: :destroy
end
```

エラーメッセージにある通り
HasManyThroughOrderError
文字通りの順番（Order）が原因らしい

```rb:micropostモデル
class Micropost < ApplicationRecord
  
 has_many :post_tags , dependent: :destroy
 has_many :meats , through: :post_tags
  
end
```

と、中間クラスとのアソシエーションを定義するコードを、先に書くようにすることが肝らしい。

以上です。
cssで要素の見た目上の順番を変える。 flex order

### flex指定をするとorderが使える。
```css
  display:flex;
  flex-direction:column;
```
### あるオブジェクトにソートしたい値がある場合、直接orderに入れる。要素の挿入順は変わらないが、見た目上の順番は変わる。
```js
   el.style.order = d.value;
```
### 逆順はflex-directionの変更
```css
  flex-direction: column-reverse!important; 
```
### js側の変更は最小限で済む。日付も正せば数値に変更できる。不要なDOM更新を抑える。
注意：order は int型のようで最大値が決まっている。Date.now()を直接いれると全てがintの最大値まで丸められる。1000で割り、秒にすれば2038年まではソート可能。

```js
Date.now(); 
//1519996574455
//2147483647  //order のリミット
//1519997319  //=>parseInt( Date.now()/1000 );//change rate ms => s
```
### 全部

```html
<input type="checkbox" class="flg" id="s"></input>
<label for="s"></label>
<div id="f"></div>
```
```css
#f{
  display:flex;
  flex-direction:column;
}
label{border-bottom:1px solid}
.flg{display:none}
label[for]{cursor:pointer;background-color:orange}
label[for]:before{content:'small'}
#s:checked + label[for]:before{content:'big'}
#s:checked + label + div{
  flex-direction: column-reverse!important; 
}
```
```js
let data=[
  {name:'aaa',value:132}
  ,{name:'bbb',value:-132}
  ,{name:'ccc',value:2}
  ,{name:'ddd',value:13}
  ,{name:'eee',value:200}
  ,{name:'fff',value:1}
]
;
let fn={}
fn.ce=(d=>document.createElement(d));
fn.q =(d=>document.querySelector(d));
let f =fn.q('#f')
;
data.map((d)=>{ 
   let el=fn.ce('label');
   el.innerHTML = JSON.stringify(d);
  //
   el.style.order = d.value;
  //
   return el;
 })
 .forEach((d)=>{f.appendChild(d)})
;
```

### 追加　フロント側で要素順も含めた３種類の順序変更。要素順、昇順、降順。但し難解。
```html
<input type="checkbox" class="flg" id="s"></input>
<label for="s"></label>
<input type="checkbox" class="flg" id="un"></input>
<label for="un"></label>
<div id="f"></div>
```
```css
#f{
  display:flex;
  flex-direction:column;
}
label{border-bottom:1px solid}
.flg{display:none}
label[for]{cursor:pointer;background-color:orange}
label[for="s"]:before{content:'small'}
#s:checked + label[for="s"]:before{content:'big'}
#s:checked + label ~ #f{
  flex-direction: column-reverse!important; 
}

label[for="un"]:before{content:'sortable'}
#un:checked + label[for="un"]:before{content:'fix'}
#un:checked + label ~ #f{
  flex-direction: column!important; 
}
#un:checked + label ~ #f>*{
  order:unset!important; 
}

```
ExcelVBAでIEからユーザID・パスワードを入力してログインする

![image.png](https://qiita-image-store.s3.amazonaws.com/0/185546/5816261b-b3ab-ea7e-2d99-d951e37808e5.png)

Excelにこんな感じでユーザ名/パスワードが書いていて、
ログインボタンでIEからconnpassにログインするVBAを作成しました。

※シート名は「ログイン情報」


#完成版VBAソースコード

作ったVBAは以下の通り

```

Sub login()

　Dim objIE As InternetExplorer 'IEオブジェクトを準備
　Set objIE = CreateObject("Internetexplorer.Application") '新しいIEオブジェクトを作成してセット
 
　objIE.Visible = True 'IEを表示
 
　Dim strUrl As String '次ページのURL
　strUrl = "https://connpass.com/login/"
 
　objIE.navigate strUrl 'IEでURLを開く
 
　Do While objIE.Busy = True Or objIE.readyState < READYSTATE_COMPLETE '読み込み待ち
 
    　DoEvents
 
　Loop
 
 
　Dim strUsername As String
　strUsername = Worksheets("ログイン情報").Range("C3").Value

　Dim strPassword As String
　strPassword = Worksheets("ログイン情報").Range("C4").Value

　Dim htmlDoc As HTMLDocument 'HTMLドキュメントオブジェクトを準備
　Set htmlDoc = objIE.document 'objIEで読み込まれているHTMLドキュメントをセット

　htmlDoc.getElementsByName("username")(0).Value = strUsername 'name="username"にユーザー名を入力
　htmlDoc.getElementsByName("password")(0).Value = strPassword  'name="password"にパスワードを入力
　htmlDoc.getElementById("login_form").submit  'フォームの内容を送信
 

End Sub

```


対象のHTMLは以下の通り

```

<form action="/login/" method="post" id="login_form">
        <h3 class="main_h3">connpassアカウントでログイン</h3>

        

        <p class="em mb_smallest">ユーザー名、またはメールアドレス</p>
        <p class="p text_center">
          <input name="username" class="gray_form" type="text" value="">
        </p>
        
        <p class="em mb_smallest">パスワード</p>
        <p class="p text_center">
          <input name="password" class="gray_form" type="password">
        </p>
        
        <p class="p text_center"><button class="btn btn_default" type="submit">ログインする</button></p>
        <input type="hidden" name="csrfmiddlewaretoken" value="g638HlpAm1I3B7qA9zSv8YpuYU8Tb6HE">
      </form>

```


ソースコード参考にしたサイトはこちら
[【エクセルVBAでIE操作】ユーザー名とパスワードを入力してログインをする](https://tonari-it.com/vba-ie-login/)

↑上記サイトはgetElementByIdメソッドで取得していましたが、Idがなかったので以下を参考にgetElementsByNameメソッドで取得しました
[VBAでIEのテキストボックスに値入力](https://www.vba-ie.net/form/text.html)

#エラーの備忘録

##ユーザ定義型は定義されていません
コンパイルエラー
必要なライブラリが読み込めていないエラーのよう。それではじめはIEを開くことができませんでした。
**対処策：**コード実行を停止後、[ツール］-[参照設定]から必要なライブラリファイルにチェックを入れる  



##オブジェクトは、このプロパティまたはメソッドをサポートしていません 
実行時エラー。
直訳すると、『そんなプロパティorメソッドなんてねーよｗ』とのことらしい。
よくよくみてみると、「getElementByName」になっていて、**s**が抜けていました。
**対処策：**プロパティとメソッド見直そう


#感想
これはパスワードをそのままExcel上に直接書いているので、この前の記事のようにパスワードを伏字にした状態からパスワードを取得し、ログインできるようにしたい。
あとyahooメールのように、ユーザーID入力のあとパスワード入力の画面にうつるようなパターンでもログインできるようにしたい。
[Python3]2次元平面の扇型の内外判定

# 扇型の内外判定
2次元平面の扇型の中心座標，対象の座標，扇型の開始角，扇型の終了角，扇型の半径を与えます．
この時対象は扇型の内部にあるか外部にあるかを判定します．
なお扇型の角度は度数法です．

# 判定方法
第1に扇型の属する円の内部にあるか，外部にあるかを判定します．三平方の定理から判定できます．

第2に開始角に対して対象の座標が左側にあるかを判定します．開始角ベクトルと対象ベクトルの外積を取ります．右手系でZ成分が正であれば左側，負であれば右側です．

第3に終了角に対して対象の座標が右側にあるかを判定します．終了角ベクトルと対象ベクトルの外積を取ります．同様にZ成分が正であれば左側，負であれば右側です．

つまり開始角と終了角が180度未満であれば，開始角の左側かつ終了角の右側であればよく，180度以上であれば，開始角の左側または終了角の右側であれば良い．

# プログラム
```python:Python3
import math

def hit_sector(center_x, center_y, target_x, target_y, start_angle, end_angle, radius):
    dx = target_x - center_x
    dy = target_y - center_y
    sx = math.cos(math.radians(start_angle))
    sy = math.sin(math.radians(start_angle))
    ex = math.cos(math.radians(end_angle))
    ey = math.sin(math.radians(end_angle))

    # 円の内外判定
    if dx ** 2 + dy ** 2 > radius ** 2:
        return False

    # 扇型の角度が180を超えているか
    if sx * ey - ex * sy > 0:
        # 開始角に対して左にあるか
        if sx * dy - dx * sy < 0:
            return False
        # 終了角に対して右にあるか
        if ex * dy - dx * ey > 0:
            return False
        # 扇型の内部にあることがわかった
        return True
    else:
        # 開始角に対して左にあるか
        if sx * dy - dx * sy >= 0:
            return True
        # 終了角に対して右にあるか
        if ex * dy - dx * ey <= 0:
            return True
        # 扇型の外部にあることがわかった
        return False

```

# 参考
[扇形と点の当たり判定](https://qiita.com/shr_em/items/0f1c7cac028a7ac45853)
Sparkでのルート評価の順番

Sparkのルーティング設定はワイルドカードが指定できるため、同じURLでも複数ルートにマッチングする可能性がある。
複数ルートにマッチングする場合は、先に定義したものが優先される仕組みのようだ。

また静的ファイルとも被る可能性があるが、そちらの優先度はJavaプログラムより低い。
のだが、index.htmlだけはなぜか順位が1番高い。この仕様は何なんだろう。

例えば、下記のプログラムがあると、

````java:
public class Main {

  public static void main(String[] args) {

    staticFiles.externalLocation(".");

    get("/", (request, response) -> "hello index");
    get("/sample", (request, response) -> "hello sample");
    get("/sample.html", (request, response) -> "hello sample.html");
    get("/:value", (request, response) -> "this is " + request.params("value"));
    get("/sample2", (request, response) -> "hello sample2"); // これは呼ばれることはない
  }
}
````

ルーティングは下記となる。

/ → 静的ファイルにindex.htmlが存在する場合はそちらが優先される。存在しない場合は "hello index" が表示される。
/index.html → 静的ファイルにindex.htmlが存在する場合はそちらが優先される。存在しない場合は "this is index.html" が表示される。
/sample → "hello sample" が表示される。
/sample2 → "this is sample2" が表示される。
/sample.html → "hello sample.html" が表示される。静的ファイルのsample.htmlは呼ばれない。

結構複雑です。
女性顔学習のpix2pix(encoder-decoder版)の出力はみんな女性顔になりました！

前回の記事「[pix2pixの出現で。。。～検証編2 U-net構造を理解する～](https://qiita.com/MuAuan/items/387cca897fab12f1b6a5)」のつづきを記載します。

ここでは、前回記事の最後のパラメータを使って、いろいろな物体や人、景色から、どんな画像が得られるのかという興味です。

どんな画像になると思いますか？

ウワンは結果にまたまた驚きました！
早速、一つ一つ見ていきます。
#学習したパラメータで出力された画像
###入力：女性顔
gray画像
当たり前にそのまま出てきました
![current_batch_validation2.png](https://qiita-image-store.s3.amazonaws.com/0/233744/8236d9d7-c54a-0b6e-463c-2ba01a5e8f61.png)
輪郭画像
こちらは、u-netだと汚い画像でしたが、これは薄いけど綺麗！
![current_batch_validation3.png](https://qiita-image-store.s3.amazonaws.com/0/233744/af006e64-213a-b308-0bee-870470f4c3a9.png)
###入力：猫・犬画像
gray画像
犬・猫も女性顔が出てきました。
![current_batch_validation3.png](https://qiita-image-store.s3.amazonaws.com/0/233744/048e3406-60f3-65bd-0724-e1e40e93b56a.png)
輪郭画像
薄いけど、やはり女性顔だ
![current_batch_validation3.png](https://qiita-image-store.s3.amazonaws.com/0/233744/6e642eef-8fa3-1ca5-5a50-829764167d9d.png)
###入力：飛行機画像
gray画像
空に浮かぶ女性顔
![current_batch_validation2.png](https://qiita-image-store.s3.amazonaws.com/0/233744/646c4e90-8c96-d491-a10b-c2066e5be377.png)
輪郭画像
こんな絵になるんだね。。
![current_batch_validation1.png](https://qiita-image-store.s3.amazonaws.com/0/233744/28e5d76c-1732-037f-d6de-6bc10eac7a10.png)
###入力：ファッション画像
gray画像
これは、前回出していたのと同じような画像
![current_batch_validation3.png](https://qiita-image-store.s3.amazonaws.com/0/233744/138321f9-2390-4d4b-22b8-e4e7080d2ee4.png)
###入力：男性顔画像
gray画像
一番驚いたのはこの画像！
一部の人は男性というよりきれいな女性顔。
そして、何よりみんなきれいに塗れている！
![current_batch_validation2.png](https://qiita-image-store.s3.amazonaws.com/0/233744/972c53aa-0ad8-3ad4-a761-cb8d5e361333.png)
輪郭画像
男性顔かもだけどきれい、そして何より輪郭をはっきり描いているのでその分、出力画像もはっきり表れている。
![current_batch_validation3.png](https://qiita-image-store.s3.amazonaws.com/0/233744/51e002fb-a7d9-1e22-a99a-baef73935f58.png)
#まとめ
・女性顔を学習したpix2pix(encoder-decoder版)の出力画像はみんな女性顔になりました！

#課題
・ほかのものを学習すると、例えば猫顔、とか犬顔。
　そうするとみんな猫とか犬になるんだろうか？？
・これって、問題領域に自分の探したいものを学習させたDL使うと探し出せそう。。麻薬犬みたいに。。
・もう、アプリ作るっきゃない
kotlinでAlertDialog with Custom Viewを使うときにはまったこと

##kotlin-android-extensionsって？
findViewByIdを使用せずともxmlファイルとkotlinソースコード間でのビューの関連付けを行ってくれるようになり、

```MainActivity.java
Button button = (Button)findViewById(R.id.button)
```

こんなことをひたすらにしていたJavaとはおさらばし、
xmlで指定したidのままkotlinソースコード上で使えるという割と便利なプラグイン

今回は、そのことに気づかずにAlertDialogでハマってしまったので、メモ程度に残しておきたいと思います。


##何にハマったのか

```dialog_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

</LinearLayout>
```

```MainActivity.kt
/* 
package、インポートなどは省略
*/

class MainActivity : AppCompatActivity(), View.OnClickListener {

    private val TAG: String = "MainActivity"

    private val mContext: Context = this

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.time_table_activity)

        button.setOnClickListener(mContext)
    }

    override fun onClick(view: View?) {
        // customViewとなるViewをinflateして作成
        val customLayout = layoutInflater.inflate(R.layout.component_time_table_dialog, null)
        // inflateしてできたViewから、リソースID参照してEditTextを指定する
        val editText: EditText = customLayout.findViewById(R.id.editText)
        // Builderメソッドで、AlertDialogをビルドする
        AlertDialog.Builder(mContext).apply {
            setView(customLayout)
            setTitle("AlertDialogTutorial")
            setPositiveButton("ACCEPT", DialogInterface.OnClickListener { dialogInterface, which ->
                Toast.makeText(mContext, subject.text.toString(), Toast.LENGTH_SHORT).show()
            })
            setNegativeButton("REJECT", null)
            show()
        }
    }
}
```

こちらが、最終的に完成したコードのサンプルバージョンです。
実際にどこにハマったかというと、

```MainActivity.kt
editText: EditText = customLayout.findViewById(R.id.editText)
```
の部分ですね、

###kotlin-android-extensions
を使っていたので最初はxmlファイルから直接(findViewByIdメソッドを使わず)editTextを用いていました。
しかし、それでは、component_time_table_dialog.xmlから参照しているだけで、AlertDialogのCustomViewとして用いるViewの方からは参照していなかったみたいで、常にIllegalStateExceptionを吐かれました。

考えてみれば、当たり前のことでしたが、同じ過ちを侵さないためにもメモとして残しておきます。
inflateしたViewからはkotlin-android-extensionsは参照しないので、注意してください。
AlertDialogのCustomViewとしてinflateしたViewの方から参照してあげないとエラーを吐かれます。


##最後に
kotlin-android-extensionsを初めて使ってみてハマったエラーなので、何言ってんだこんなの当たり前じゃないかというお声もあるかもしれません…コードの改善点等ございましたらご指摘お願いいたします。もし今回の投稿が誰かのお役に立てましたら幸いです(_ _)
zsh入れようとbrew install したらできなかった時の話

#はじめに
zsh入れようとbrew install したらできなかった時の話です

#zshのインストール
何やらzshがいいらしいので早速入れようと


```
$ brew update
$ brew install zsh
```

したら

```
Error: Could not create /usr/local/Cellar
Check you have permission to write to /usr/local
```

が出てきた
あれ？writeじゃなくてcreate?

```
Error: Cannot write to /usr/local/Cellar
```

は前見たことあったがcreate?ってなってとりあえず調べると
sudoで直接ディレクトリ作ってる人がいたので真似してみる

```
$ sudo mkdir /usr/local/Cellar
```

てやった後にもう一度 brew install したら

```
Error: /usr/local/Cellar is not writable. You should  change the
ownership and permissions of /usr/local/Cellar back to your
user account:
  sudo chown -R $(whoami) /usr/local/Cellar
Error: Cannot write to /usr/local/Cellar
```
て出てきた....なんだこの安心感...okこれなら分かる
エラーに書いてある通りに

```
$ sudo chown -R $(whoami) /usr/local/Cellar
```

を入力してもう一回 brew install したら

```
The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink .
/usr/local/opt is not writable.

You can try again using:
  brew link zsh
==> Summary
```

よし！終わり.....あれ？なんか出てる？

#まだなんか出てる
言われた通りに

```
$ brew link zsh
```
を入力すると

```
Linking /usr/local/Cellar/zsh/5.4.2_3... 
Error: Could not symlink .
/usr/local/opt is not writable.
```

が出てきた.....助けてDoctor!

```
$ brew doctor
Warning: You have unlinked kegs in your Cellar
Leaving kegs unlinked can lead to build-trouble and cause brews that depend on
those kegs to fail to run properly once built. Run `brew link` on these:
  zsh
```

言われた通りにすると

```
$ brew link zsh
Linking /usr/local/Cellar/zsh/5.4.2_3... 
Error: Could not symlink .
/usr/local/opt is not writable.
```
さっきと同じ
調べると

```
sudo chown -R `whoami`:admin /usr/local/opt
```

でいけるらしいがoptなんてないって言われたので
作ってからもう一回やると

```
$ sudo mkdir /usr/local/opt
$ sudo chown -R `whoami`:admin /usr/local/opt
$ brew link zsh
Linking /usr/local/Cellar/zsh/5.4.2_3... 1351 symlinks created

```

やったぜ
Pythonでファイルopenにちょっとつまずいた話

#はじめに
この記事はPythonでopen()関数でパス指定のトラブルシューティングの記録です。
同じようなトラブルを抱えている方への参考になれば幸いです。

#結論
・raw文字列を使おう。
・フルパス、相対パスを意識しよう。


#結論にいたるまで
pythonを学び始めて計算結果をテキストファイルに保存してみようってなったので
ひとまず参考書のコードをPyCharmにポチポチして実行してみる。

```hoge1.py
f = open("C:\py_study\text.txt", "r", encoding="utf-8")
s = f.read()
print(s)
f.close()

#result
#OSError: [Errno 22] Invalid argument: 'C:\\py_study\text.txt'
```


まぁ、何かしらエラーは出ると思ってました。
そこでエラーを確認すると「\text.txt」の「\t」がタブ文字になってることに気づく。。。
解決策としてwindowsのパス指定のときraw文字列が便利って学んだことを思い出して
パス指定にraw文字列を使ってみる。

```hoge2.py
f = open(r"C:\py_study\text.txt", "r", encoding="utf-8")
s = f.read()
print(s)
f.close()

#result
#aaaa
#bbbb
#cccc
#abcd
```

できた。

カレントディレクリにファイルを作成していればraw文字でフルパスを指定しなくてもOK
ちなみにカレントディレクトリは

```
import os
print(os.getcwd())
```

で確認できます。

カレントディレクトリが「C:\py_study」だったので

```hoge3.py
f = open("text.txt", "r", encoding="utf-8")
s = f.read()
print(s)
f.close()
```

でもファイルの中身が確認できました。

おわり。
FreeCADでFEM解析に挑戦してみた。

(参考)無償3D CAD「FreeCAD」でFEM解析に挑戦！ (2/6)
http://monoist.atmarkit.co.jp/mn/articles/1601/14/news022_2.html
＞理論解0.225mmとなります。
オンライン mathematica
http://www.wolframalpha.com/input/?i=%3D(100*0.3%5E3*12)%2F(3*200*10%5E6*0.03*0.02%5E3)

(参考)無償3D CAD「FreeCAD」でFEM解析に挑戦！ (6/6)
http://monoist.atmarkit.co.jp/mn/articles/1601/14/news022_6.html
＞図17の最小欄を見ると、-0.22402とあり、最大変位量は0.224mmであることが分かります。
私が実行すると、最小-0.223911 mmになりました。

－－－－－－－－－－－－－－
【補足】(2018/02/24)
#オンラインソフト
(参考)CANTILEVER STRUCTURAL BEAM WITH CONCENTRATED LOAD AT ANY POINT
http://www.amesweb.info/StructuralBeamDeflection/CantileverBeamConcentratedLoad.aspx
(参考)有限会社武藤設計 － 計算サイト＞慣性モーメント
http://www.mutoh-sekkei.jp/keisan/dan/01.html

#CalculiX
http://open-shelf.appspot.com/CalculiX/ccx-doc/ccx.html
http://open-shelf.appspot.com/CalculiX/Install-on-Windows.html
DroidKaigi2018　スカラーシップにて参加！！

#はじめに
今回私はWantedlyさんのスカラーシップでDroidKaigi2018に参加することができました
ありがとうございます！
この記事は見てきたことをレポートとしてまとめさせていただきます

##Kotlinアンチパターン
kotlinコードの悪い記述（アンチパターン）を紹介するセッション
コード量がJAVAに比べて大幅に減り可読性や作業効率が上がると言われているkotlin
そのkotlinのコードをよりよいものとするためのセッションで非常に参考になりました

##今から始めるAndroid開発
Android開発で必要なことをわかりやすく紹介されたセッション
gradleやXML、マニフェストなどのアプリを作成する基本的なところから
アーキテクチャのような美しいコードの記述方法など、改めて再認識することができました

##DataBindingのコードを読む
DataBindingのコードの内容を解説するセッション
もともとDataBindingに興味はあったものの
学んだことがなかったため少々不安なところもあったのですが
非常に詳しく細かなところまで解説していただき、勉強になりました

##タッチイベントを捕まえよう
タッチイベントの実装方法、違和感のない実装方法を解説するセッション
今までは指定の位置をClicklistenerでタッチイベントを処理していたのですが
座標指定をして違和感のないUIのタッチイベントを実装する方法が様々紹介され
このような技術を導入したアプリを作って見たいと思いました

##実例で理解するMaterial Design Animation
アプリケーションのレイアウトを作成した際の経験を解説するセッション
自分のアプリにあったアニメーション作成
作成したアニメーションにおかしなところがないか、スピードを落としてしっかりみる
他の良いと思ったアニメーションを参考にするなど
実際にスピーカーの方が作成したアプリと交えながらのセッションでとてもわかりやすかったです

##はじめてのkotlinハンズオン
kotlin初心者向けのハンズオンセッション
私自身kotlinはほとんど触れたことがなかったので、ぜひハンズオンをやりたいなと思っていました
基礎的なところの解説と課題を与えられ、初めてのコードを触れるという抵抗が薄れた
またdroidkaigiでセッションされた方々のサンプルコードの多くがkotlinだったため
このセッションを受けたことで他のセッションの理解も捗りました

##Dialogflow for Android
チャットBOT作成などに用いられるDialogflowをAndroidアプリに導入したというセッション
私が何よりも驚いたのは、コードを書かずに言語処理できるという利便性でした
Dialogflowのコンソールの使い方の説明もわかりやすく、様々な使い道がありそうだなと
自分自身で様々なアプリを作成してみたいなと思いました

##体育会系女エンジニアの孤独なアプリ開発教室
一人でアプリ開発をしている中で、どのようにダウンロード数を伸ばすかというセッション
セッション内容もとても楽しく、わかりやすいものでした
ニッチであり需要のあるアプリ、軽い動作、ホットなイベント、チュートリアルは不要な内容など
様々な工夫やアイデアでアプリのダウンロード数は増やすことはできるということでした
自分自身、個人開発が多いので参考になるものが多くあったセッションでした

##Android ThingsとFirebaseで始めるホームセキュリティ
自宅のセキュリティをAndroid Thingsを利用して管理したというセッション
家のドアが空いたのを検知し、FirebaseのRealTimeDatabaseにその情報を飛ばしたり
旅行中に指定した時間のみ電気をつけたりなどをAndroid Thingsにより管理するという仕組み
非常に面白いセッションで、なおかつ私自身Firebaseを使用していたのでこのような使い方もあるのかと
とても参考になりました

##最後に
このたびはWantedlyさんのスカラーシップにてこのような様々な勉強をさせていただきました
DroidKaigiのセッションももちろん、様々なエンジニアの方とお話しさせていただき
とてもいい経験ができました
DroidKaigiに関わった皆様、本当にありがとうございます
そしてDroidKaigiに参加したことによってなによりも感じたことは
早く開発がしたい！！！！！
NodeMCU Amica



![IMG_7316.jpg](https://qiita-image-store.s3.amazonaws.com/0/49910/6b4cc112-436e-6a98-c900-61104bc3e2d4.jpeg "IMG_7316.jpg")



##

[http://arduino\.esp8266\.com/stable/package\_esp8266com\_index\.json](https://github.com/esp8266/Arduino)


### Boards manager link: 
http://arduino.esp8266.com/stable/package_esp8266com_index.json


add Boards
![Kobito.KydXuU.png](https://qiita-image-store.s3.amazonaws.com/0/49910/41083580-d4f0-a7d9-fce9-ba0101722ae1.png "Kobito.KydXuU.png")





## Lチカ

```
/*
 ESP8266 Blink by Simon Peter
 Blink the blue LED on the ESP-01 module
 This example code is in the public domain
 
 The blue LED on the ESP-01 module is connected to GPIO1 
 (which is also the TXD pin; so we cannot use Serial.print() at the same time)
 
 Note that this sketch uses LED_BUILTIN to find the pin with the internal LED
*/

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);     // Initialize the LED_BUILTIN pin as an output
}

// the loop function runs over and over again forever
void loop() {
  digitalWrite(LED_BUILTIN, LOW);   // Turn the LED on (Note that LOW is the voltage level
                                    // but actually the LED is on; this is because 
                                    // it is active low on the ESP-01)
  delay(3000);                      // Wait for a second
  digitalWrite(LED_BUILTIN, HIGH);  // Turn the LED off by making the voltage HIGH
  delay(2000);                      // Wait for two seconds (to demonstrate the active low LED)
}

```

![IMG_7316.jpg](https://qiita-image-store.s3.amazonaws.com/0/49910/81805029-6fc1-c139-b482-52c7f668534a.jpeg "IMG_7316.jpg")


![IMG_7317.jpg](https://qiita-image-store.s3.amazonaws.com/0/49910/8589a166-5975-4cc0-bec3-b317723fda71.jpeg "IMG_7317.jpg")



## 
error: espcomm_open failed
error: espcomm_upload_mem failed
error: espcomm_upload_mem failed

FLAHボタンを押しながらリセットで書き込みモードに入る
それでもダメならFLASHボタンおしっぱなし


## 参考


[Arduino IDE に Stable \( Staging \)版 ESP8266 ボードをインストールする方法 \| mgo\-tec電子工作](https://www.mgo-tec.com/esp8266-board-install01-html)


[Comparison of ESP8266 NodeMCU development boards • my2cents](https://frightanic.com/iot/comparison-of-esp8266-nodemcu-development-boards/)

![esp8266-nodemcu-dev-kit-v1-pins.png](https://qiita-image-store.s3.amazonaws.com/0/49910/98ca5960-f4b9-b47e-cdfc-8860ec2e56ca.png "esp8266-nodemcu-dev-kit-v1-pins.png")



[NodeMCUを使ってみる](http://nopnop2002.webcrow.jp/NodeMCU/Amica.html)

[Espressif ESP8266 Arduino互換でスケッチが使える ESP\-12Eモジュール基板 \(Espressif ESP8266 ESP\-12\-E NodeMCU V1 ESP12 CP2102\)](http://www.neko.ne.jp/~freewing/hardware/espressif_esp8266_esp_12e/)
VRChatで素早くハンドジェスチャーするためのガイドを自作する

## はじめに

[VRChat](http://store.steampowered.com/app/438100/VRChat/)とは現在Steamで配信されている、その名の通りVR（仮想現実）環境でチャットするだけのゲームです。
最近話題のバーチャルユーチューバーの[方](https://youtu.be/L5sy3wgNwaI?t=3m11s)[々](https://youtu.be/KTr6EC8QVbI)の動画で知った方も多いと思います。（筆者もそのひとり）

VRChatではHTC ViveやOculus RiftなどのVR機器を使うことで頭と両手（+追加でセンサを購入すれば腰や両足）を現実世界の身体とリンクさせてゲーム中で動かすことができるのですが、特にViveを用いた際の「指の動き」に難点があります。
というのも、デフォルトで6種類ある指の動きを親指付近にあるタッチパッドひとつで選択する必要がある([参考](http://bibinbaleo.hatenablog.com/entry/2017/12/30/125933))のです。丸いタッチパッドのタッチした箇所が微妙に違うだけで出したいハンドジェスチャーを出せないと~~ネカマ~~バーチャル美少女としては支障がでてしまいます。
もちろんプレイ中はHMDを被っているためタッチパッドの正確な位置を目で確認することはできません。

![gesture_sample.png](https://qiita-image-store.s3.amazonaws.com/0/237246/3670a336-be6f-e5c6-eeb8-9a935c3b02d8.png)
**鍛練の末、それらしき手の動きを習得した筆者(アニメーションPNG)**

ということで、VRChatをViveでプレイする際に簡単にタッチすべき箇所が分かるパーツを3Dプリントしてみました。

## 提案手法
### 設計

まずタッチパッドのどの箇所をタッチすると所定のハンドジェスチャーが出るのかを検証します。
今回は「Viveコントローラに紙を張り付けてタッチペンで叩く」という非常に原始的な方法で計測しました。

![sekkei.png](https://qiita-image-store.s3.amazonaws.com/0/237246/62e7a0bd-2531-caa5-75df-2c587fee4ef2.png)
**検証結果@左手、角度は大まかなもの**

結果です。中央がグー（トリガーを引いた場合と共通）、円周に5種類のジェスチャーが割り当てられています。
実際にプレイしてみるとわかりますが、bのモーションが親指を伸ばした時に触れる右上に割り当てられているなど、配置については細かい配慮がなされています。
これをもとにサクッとモデルに起こします。

![vrchat_guide.png](https://qiita-image-store.s3.amazonaws.com/0/237246/9ef54cce-b9ae-cdaf-3fbf-1ad835712f44.png)
**付けたときのイメージ**

![vrchat_guide_combined_double.png](https://qiita-image-store.s3.amazonaws.com/0/237246/77eb35cf-dfc1-79ed-7bc8-11c03752381d.png)
**発注するモデル(左右のパーツを結合したもの、裏返し)**

ViveコントローラのモデルはSteamVRをインストールした際に一緒にダウンロードされる([参考](https://qiita.com/broken55/items/47fe3d0ed5b990a1423c))ため、これにフィットする形でモデリングしました。
コントローラは取っ掛かりとなる突起が少ない形状であることに加え、ほかのゲームを遊ぶ際に簡単に取り外せるようにしたいため、輪ゴムで固定する方式にしました。

### 発注+テスト

[DMM.make](https://make.dmm.com/print/)に発注して[ナイロン](https://make.dmm.com/print/material/5/)でプリントしてもらいました。今回は両手分のガイドをランナーで1モデルに結合したため、両手合わせて800円くらいでした。

![attached_noexif.png](https://qiita-image-store.s3.amazonaws.com/0/237246/e30a4feb-48a6-fe46-93b2-cd34dc56ffc4.png)
**取り付け後**

装着後はこんな感じ。指でガイド部分を触ればどこに指を置くべきかがすぐ分かるので迷わず美少女ポーズがとれます。

---

今回作ったモデルは以下で公開しています。
https://github.com/y23586/vrchat-vive-touchpad-guide

各種3Dプリントサービスにアップロード・発注することに関しては筆者の許諾は不要ですので、バーチャル美少女になる際にはぜひご利用ください！
httpkitで、ドツボにはまった話

httpkitのclient (http://www.http-kit.org/client.html) を使っていて、ドツボにはまりました。解決したので、忘れないように要点を書いておきます。

バージョンは、[http-kit "2.2.0"]です。

上記のページのサンプルを見ればイメージをつかみやすいと思いますが、org.httpkit.client/requestに渡す値によって、サーバから返って来るのに成功したり失敗したりしてハマりました。原因を絞り込むのに時間を浪費しました。

分かってしまえば、なーんだという感じです。

```clojure
  (def options  {:url "http://hogehoge.com/foo/bar"
                 :method :delete
                 :headers {"Token" "asdlfksdfjkasjlfkjaksfasfjasdfjk"
                           "Content-Type" "application/json; charset=UTF-8"
                           }
                 :body "{\"foo\":\"something\",\"bar\":1"
                 })
```
これだと、httpステータスは200でOKなのですが、


```clojure
  (def options  {:url "http://hogehoge.com/foo/bar"
                 :method :delete
                 :headers {"Token" "asdlfksdfjkasjlfkjaksfasfjasdfjk"
                           "Content-Type" "application/json; charset=UTF-8"
                           }
                 :body "{\"foo\":\"something\",\"bar\":1"
                 :query-params {}
                 :form-params {}
                 })
```
こっちだと、400のBadRequestが返って来てNGです。


```clojure
  (def options  {:url "http://hogehoge.com/foo/bar"
                 :method :delete
                 :headers {"Token" "asdlfksdfjkasjlfkjaksfasfjasdfjk"
                           "Content-Type" "application/json; charset=UTF-8"
                           }
                 :body "{\"foo\":\"something\",\"bar\":1"
                 :query-params nil
                 :form-params nil
                 })
```

これだとhttpステータスは200でOKです。


```clojure
  (def options  {:url "http://hogehoge.com/foo/bar"
                 :method :delete
                 :headers {"Token" "asdlfksdfjkasjlfkjaksfasfjasdfjk"
                           "Content-Type" "application/json; charset=UTF-8"
                           }
                 :body "{\"foo\":\"something\",\"bar\":1"
                 :query-params {}
                 :form-params nil
                 })
```

これでもOK。

* form-paramsが{}だと、contet-typeがcontent-type application/x-www-form-urlencodedで、content-lengthが0が返って来ます。
* form-paramsがnilだと、contet-typeがcontent-type application/json; charset=UTF-8で、content-lengthが26が返って来ます。
* 
期待しているのは、form-paramsがnilの方です。もしくは指定しなくてもよい。

以下のものも多少は関係ありそうみたいです。
https://github.com/http-kit/http-kit/issues/112



以上、プロキシーサーバを作っていて微妙なところにハマったという話でした。
Elasticsearch の API リクエストにつける refresh についてまとめた

Elasticsearch のリファレンスを見ながら動かしていて、API リクエストに refresh をつけている箇所があって気になったので調べてみました。
この記事を書いている時の Elasticsearch のバージョンは 6.2.2 です。

内容としては以下のドキュメントをまとめたものになります。
[?refresh](https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-refresh.html)

### どの処理で使えるのか？
Index
Update
Delete
Bulk API

### 何のための設定か？
APIリクエストして処理させた結果が検索対象として反映されるタイミングを制御するための設定。

### 設定可能な値
* 値なし、または true  
処理の中で即座にプライマリシャードとレプリカシャードに反映される。  
なお、このリフレッシュは他の処理にも影響する。  
パフォーマンスに問題がないか十分に検証してから設定すること。
* wait_for  
index.refresh_interval の設定値（デフォルトだと1秒）に達するか、index.max_refresh_listeners の設定値以上までこのパラメータが付いたリクエストが溜まるまで待って反映させるが、Refresh API が使われた場合はその時点で反映される（ただし Refresh API は全てのシャードをリフレッシュすることに注意が必要）  
この設定がついたリクエストにのみ影響する。
* false（デフォルト）  
反映させない。

### 設定の勘所
refresh=wait_for が必要と判断される場合を除いて、基本的には refresh=false を設定するのが無難。
refresh=true にした場合非効率なシャードが積み上がっていって、最終的に効率的なシャードにマージするコストが上がる。
refresh=wait_for をつけたリクエストは連続して実行せずに Bulk API などでまとめて実行すること。ただし index.refresh_interval が小さい場合は refresh=true にした場合と同じ問題が発生する。

### 実行サンプル
```
$ curl -H "Content-type: application/x-ndjson" -X POST http://localhost:9200/shop/goods/_bulk?refresh --data-binary @request_bulk.json
$ curl -H "Content-type: application/x-ndjson" -X POST http://localhost:9200/shop/goods/_bulk?refresh=wait_for --data-binary @request_bulk.json
$ curl -H "Content-type: application/x-ndjson" -X POST http://localhost:9200/shop/goods/_bulk?refresh=false --data-binary @request_bulk.json
```

### index.max_refresh_listeners を設定した場合の挙動（2018.3.9 更新）
以下のように index.refresh_interval を -1 、index.max_refresh_listeners を 5 に設定してインデックスを作成する。

```
curl -X PUT 'localhost:9200/shop' -H 'Content-Type: application/json' -d'
{
    "settings": {
        "index": {
            "number_of_shards" : 1,
            "number_of_replicas" : 0,
            "refresh_interval" : "-1",
            "max_refresh_listeners" : 5
        }
    }
}
'
```

その後、個別に端末を立ち上げて以下のようにインデクシングする。

```
curl -X POST 'localhost:9200/shop/goods/?pretty&refresh=wait_for' -H 'Content-Type: application/json' -d'
{
    "name" : "test"
}
'
```

同様に端末を立ち上げてインデクシングしていくと、6回目のリクエストの際に全てのリクエストがリフレッシュされた。


### 参考になった記事
[Where are my documents?Refreshing news...](https://www.elastic.co/blog/refreshing_news)
config/environments/staging.rb はアンチパターン！

Rails では、`config/environments/*.rb` に、実行環境ごとに異なる設定を書けます。

`rails new` で新規作成すると、以下の3種類が生成されています。

* `production.rb` (本番環境)
* `development.rb` (開発環境)
* `test.rb` (CI環境)

どの環境としてアプリを起動するかは、環境変数 `RAILS_ENV` で指定できます。

そして、`config/environments/*.rb` は、独自に追加することができるので、
ステージング環境（本番デプロイ前にテストする環境）の設定を

* `staging.rb`

に書いている。・・・というプロジェクトは多いと思いますが、私は **staging.rb はアンチパターン** だと思います。

# なぜ、アンチパターンだと思うのか？

**テストは本番と同じコード・設定・環境でする**のが基本です。本番と違うものを動かして問題がなかったとしても、それはテストにはならないのです。当たり前ですが。

そのため **`staging.rb` は `production.rb` は同一の内容でなければならない**はずです。

しかし、**別ファイルにしている時点で、同一内容か保証し続けるのは難しい**のです。
コードレビューなどでチェックすることも考えられますが、きっと起きます。
「ステージング環境では問題ないのに本番環境では起動すらできない。実は production.rb を修正し忘れていていた」事件が。

# 代わりにどうすればいいか？

**ステージング環境でも production.rb を使いましょう！**同じ設定を使うのだから、必ず本番環境と同じ動作になります。

もちろん、ステージング環境と本番環境ではホスト名やAWSアカウントなどが異なることも多く、その差異を何らかの方法で吸収しなければなりませんが、大きく分けて、

1. 差異をインフラ層で吸収する
1. 環境変数で設定する

の、２種類の方法があります。

## 1. 差異をインフラ層で吸収する

例えば、本番とステージングでSMTPサーバーのホスト名が異なるなら、ステージング環境の `/etc/hosts` に以下のような設定を追加します。

```
# /etc/hosts
#
# 本番環境のSMTPサーバーのホスト名が smtp.xyz.com で、
# ステージング環境のSMTPサーバーのIPが192.168.2.18のとき、
# ステージング環境のRailsサーバーに以下のような設定を追加。

192.168.2.18 smtp.xyz.com
```

こうすることで、このサーバー内では（アプリケーションのコードは変えていないのに） smtp.xyz.com で本番ではなくステージング環境のSMTPサーバーにアクセスするようになります。サーバーの台数が増えていくと`/etc/hosts`よりDNSで管理した方がいいかもしれません。

もちろん、**インフラ層が原因で別の問題が起きる**可能性も生じます。例えば「/etc/hosts のIPを間違えて別のサーバーに接続しちゃった！」とか。しかし、経験上、インフラの設定ミスが起きる頻度は、アプリの不具合よりずっと低い。

ただし、今後のDocker化などを見据えると「2. 環境変数で設定する」の方が発展性があるかもしれません。

## 2. 環境変数で設定する

例えば、本番とステージングでSMTPサーバーのホスト名が異なるなら、それぞれ `SMTP_HOST` という環境変数にホスト名を指定しておくようにします。

```ruby
# config/environments/production.rb
Rails.application.config do

  ...

  # 本番とステージングで、SMTPサーバーのホストが異なる場合の例：
  config.action_mailer.smtp_settings = {
    address: (ENV['SMTP_HOST'] || raise '環境変数 SMTP_HOST が定義されていません'),
    port: 2525
  }

  ...

end
```

なお、環境変数を使う方法には、**アプリのDocker化がしやすくなる**おまけのメリットがあります。

従来のオンプレミス環境では、サーバーのホスト名やポート番号は、基本的に変化しないものでした。しかし、Kubenetesなどの環境では、ホスト名やポート番号は動的に変化するので、外部からアプリに設定を注入する必要があります。その注入方法としては環境変数を使うものが多いようです。

また、SaaS開発の方法論である [The Twelve-Factor App](https://12factor.net/ja/) でも、「設定を環境変数に格納する」と明確に指定されています。

# staging.rb が許容される場合

ごく小規模な、他のサーバーとほとんど通信しないようなアプリで、Docker化の予定も無いということであれば、staging.rb を書くのが手っ取り早いかもしれません。

しかし、私としては最初から production.rb と環境変数を使うことをオススメします。