OmniAICreator/Qiita-1.07M huggingface dataset:
WebブラウザからgRPCの双方向通信は可能なのか調べた

最近WebブラウザからgRPCを呼び出せるようになったようです。
[gRPC-Webが正式リリース。WebブラウザからgRPCを直接呼び出し可能に](https://www.publickey1.jp/blog/18/grpc-webwebgrpc.html)

Unary RPCでの呼び出しはできるようですが、双方向通信は対応してるのか調べてみました。  
どうやらgrpc-webというと、2種類あるようで

* https://github.com/grpc/grpc-web
* https://github.com/improbable-eng/grpc-web

前者は上記記事で紹介されているもので、後者は名前が同じでやりたいことは同じでも実現方法が異なっているものです。
やりたことはWebブラウザからの双方向通信ができるかなので、どちらも調べてみました。

ちなみにこの2つのプロダクトの違いは下記に記載してあるので、興味がある方は読んでみてください。
https://github.com/improbable-eng/grpc-web/issues/199

**自分の解釈により、間違えている可能性もあるのでその場合はご指摘お願いします。**

## 結論
結論から言うと、どちらもgRPCの双方向通信は対応していません。

### 未対応理由
どちらも同じ理由なのですが、ブラウザネイティブからストリーム通信ができないためです。
https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-WEB.md

>Bidi-streaming, with flow-control
>
>・Pending on whatwg fetch/streams to be finalized and implemented in modern browsers
>・gRPC-Web client will support the native gRPC protocol with modern browsers

[whatwg/streams](https://github.com/whatwg/streams)というブラウザネイティブのAPIがあるのですが
それがモダンブラウザで実装されない限り双方向通信は出来ないようです。

## 調査
### grpc/grpc-web
このリポジトリでの双方向通信の議論はこちらで行われていました。
https://github.com/grpc/grpc/issues/8682
https://github.com/grpc/grpc-web/issues/24

内容としては上記結論の内容です。
WebSocketで対応する案が出ていたようですが、どうやらやってない様子？

### improbable-eng/grpc-web
どうやらWebSocketでは双方向通信をサポートしているようです。
https://github.com/improbable-eng/grpc-web/issues/94

が、純粋な意味でのgRPCでの双方向通信はサポートされていないので、結論としては「対応していない」としました。
【Git】ファイルが重くてpushできないときの対策

#ファイルが重くてpushできない問題
画像処理とかを間違ってコミットしてしまって、不覚にもファイルが肥大化してしまい、pushしたら以下のようなエラーが出ました。。
>
error:RPC failed;curl 56 LibreSSL SSL_read:ERROR_SYSTCALL,errno 60
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly
Everything up-to-dage

「リモートが予期せずハングアップしました」と出たので、とりあえずこのエラーメッセージでググる。すると良さげな記事がいっぱい。
[Qiita : Git push エラーの対処](https://qiita.com/cointoss1973/items/29ca635937bf9eced999)

```
$git config http.postBuffer 52428000
```
これでもダメなら、

[stackoverflowより](https://stackoverflow.com/questions/46232906/git-clone-error-rpc-failed-curl-56-openssl-ssl-read-ssl-error-syscall-errno)

```
$git config --global http.postBuffer 1048576000
```
私はこれで解決できました。

一人で開発する際にファイルが大きくてpushできないというケースはあまりないかと思いますが、画像がファイルが大きすぎたりすると起こり得るようです。

一応画像ファイルとかは極力大きくても1MB以下に抑えることを心がけるといいと思います。
全ての画像がjpeg形式になっているか確認して、macのプレビューでサイズを小さくしたり、[tinypng](https://tinypng.com/)とかを使ったりするといいです。
NginxでHTTPSリバースプロキシを構築する際の設定メモ



## リバースプロキシ関連の共通設定
以下のファイルを作成する。

```rproxy-ssl.conf
listen 443;

ssl on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets on;
ssl_protocols TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;

proxy_set_header        Host    $host;
proxy_set_header        X-Real-IP       $remote_addr;
proxy_set_header        X-Forwarded-Host        $host;
proxy_set_header        X-Forwarded-Server      $host;
proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header        X-Forwarded-Proto https;
proxy_max_temp_file_size 10240m;
client_max_body_size 10240m;
proxy_redirect off;

add_header Strict-Transport-Security 'max-age=31536000';

server_tokens off;
```

上記ファイルは、リバースプロキシさせたいドメイン(FQDN)のserverディレクティブ内でincludeする。

```
server {
        include /etc/nginx/include/rproxy-ssl.conf;
        server_name example.local;
        ssl_certificate /etc/letsencrypt/live/example.local/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.local/privkey.pem;

        location / {
                proxy_pass http://10.12.34.56;
        }
}
```
ReactのPropTypesがundefinedの対処法

```javascript
import React, {Component, PropTypes } from 'react';
```

のような書き方でエラーがでた。

## 解決方法

[こちら](https://reactjs.org/blog/2017/04/07/react-v15.5.0.html)
バージョンアップで書き方が変わったようなので、以下のようにする

```javascript
import PropTypes from 'prop-types';
```
LC4RI(Literate Computing for Reproducible Infrastructure)に関するメモ

# 概要

LC4RI(Literate Computing for Reproducible Infrastructure)について、ちょくちょく自分でも調べるのでメモ。

# 開発の中心、NII Cloud Operation Team

- [NII Cloud Operation Team](https://github.com/nii-cloud-operation)


# 読み物関係

ここにいろいろ書いてある。
どの順番で読むか

[Literate Computing \- 文芸的な 機械化 あるいは Automated Operation](https://scrapbox.io/Literate-Computing/)

# 発表とかスライドなど（日時など順不同）

- [NIIオープンハウス 2018 \- イベント \- 国立情報学研究所 / National Institute of Informatics](https://www.nii.ac.jp/event/openhouse/) これの A17とA18
    - [オープンハウス2018：ポスターセッション \- YouTube](https://www.youtube.com/playlist?list=PLKzfdUM-RtgxGcDZ5BkArOmNCL_rsm7qu)
    - ポスター [A17\-2018 クラウド基盤の見える化による、確かなシステム運用](https://www.nii.ac.jp/event/openhouse/2018/upload/A17-2018.pdf)
    - ポスター [A18\-2018 独自拡張したJupyter Notebookによる「実行できる手順書」](https://www.nii.ac.jp/event/openhouse/2018/upload/A18-2018.pdf)
- [Literate Computing for Reproducible Infrastructure as of 2016 Nov \- YouTube](https://www.youtube.com/watch?v=xyfdufiibQk) 紹介動画(５分ほど)
- [Collaboration and Automated Operation as Literate Computing for Reproducible Infrastructure \- YouTube](https://www.youtube.com/watch?v=4HZ7m7ReZjc) JupyterCon 2017 での政谷先生のプレゼン動画（約４０分ほど）
-  [第2回 HPC OPS 研究会](https://bit.riken.jp/2018/06/2nd-hpc-ops-mtg/)での政谷先生の発表
  - [HPCOPS@20180702 \- 「NIIでの計算機環境の運用及び、Literate Computing for reproducibl…](https://www.slideshare.net/nobu758/hpcops-20180702pub-106398220)
  - 変換の関係で文字がでていないところもある。
- [Literate Computing for Reproducible Infrastructure :: JANOG41](https://www.janog.gr.jp/meeting/janog41/program/sp8lcri) 長久先生の発表
  -  [janog41\-sp8lcri\-nagaku\-01\.pdf](https://www.janog.gr.jp/meeting/janog41/application/files/3915/1672/2025/janog41-sp8lcri-nagaku-01.pdf)

# 実際に、LC4RIを docker を使ったはじめかた

今回調べて一番良かったのは、この記事を発見できたことで、はじめて自分で環境をセットアップできそう。
これまでは、用意されているものをつかっているだけだった。

- [Jupyter\+Ansibleを使ったインフラ運用のはじめかた \- Qiita](https://qiita.com/yacchin1205/items/809f715a00e170a9583f)
inputに対して、JQueryで値を変更を検知する方法（応用）

掲題に対するメモ

//キーイベントの細かいところまで披露

```javascript
// inputの中身の変化をリアルタイムで検知
$('body').on('keyup compositionend', '#post input',function() {
	myfunc();
}););	
```

//hidden要素などの変更検知

```html:index.html
<input id="test" type="hidden" name="name" value="Your name" onchange="myfunc()">
<input type="submit" name="name" value="Your name" onclick="dataChange();">
```

```javascript:javascript.js
function dataChange(){
	$('#test').val('my name').trigger('change');
}
```
iframeが変更された時の処理(onload)

#iframeが変更された時の処理

iframe内の内容によってイベントを発動させる

```javascript:script.js

$(window).on("load", function(e){
  var iframes = document.querySelectorAll("iframe");
    iframes[0].onload = function() {
        alert(this.src);
    };

});
```

##参考
http://kimizuka.hatenablog.com/entry/2015/09/16/000000
Atomでbracket-matcherが動かなくなってしまった時の対処法

## atomを再起動したらbracket-matcherが動かない

why??

と思って調べてみたところ

こちらの記事の方法の通りにやったところ
[https://discuss.atom.io/t/problem-with-html-brackets-matcher/59878/2](https://discuss.atom.io/t/problem-with-html-brackets-matcher/59878/2)

解決しました。

### 手順1
atomを開く

### 手順2
command + shift + pを押して、settingと検索

### 手順3
一番上にあるCoreをクリック

<img width="932" alt="スクリーンショット 2018-11-01 17.38.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/76779/f9070e27-4c25-40d0-2c72-d29353e4bca9.png">

### 手順4
少し下にスクロールして
Use Tree Sitter Parsersのところに付いているチェックを外す
<img width="938" alt="スクリーンショット 2018-11-01 17.40.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/76779/7e23cd74-28a2-e5bf-0f1d-d26c35ea6443.png">

以上で動いてくれるようになりました。

急に動かなくなったので焦りました。
GCPでLet's EncryptのマネージドSSL証明書(無料)が簡単に使えるようになってたのでここで一旦整理する

2018年10月にマネージドのSSL証明書がパブリックベータでリリースされました。

[GCPのHTTPロードバランサ用のマネージドSSL証明書がリリースされたので試してみた](https://blog.jicoman.info/2018/10/gcp-managed-ssl-certificates/)

先程確認したところ、ロードバランサーのコンソール画面から簡単にマネージドSSL証明設定できるようになっていました。早速、使ってみようと思っているので周辺を整理しました。

![スクリーンショット 2018-11-01 16.40.14.png](https://qiita-image-store.s3.amazonaws.com/0/20307/cc243748-7c92-2474-4808-8147c74aa1f4.png)


## そもそもSSLってなに
SSL暗号通信時に使う証明書。SSL暗号通信の目的は以下の2つ。

1. 通信の暗号化
2. 認証局によるwebサイトの認証

詳しくは: [改めて知ろう、SSLサーバー証明書とは？](https://knowledge.sakura.ad.jp/2813/)

## SSL? TLS?
調べるとSSL証明書とTLS証明書って呼ぶ人がいることに気づく。
結論どっちも同じものを指している。
元々はSSLが普及したが、2014年に重大な脆弱性が見つかり、SSLを元にしてTLSが開発された。
今は主要ブラウザではSSLは無効化されおりTLSが使われている。
正確にはTLSだが、名残でSSLと呼ばれていることが多い。
参考: [TLS について](https://dc.cybertrust.co.jp/ssl/tls.html)



## 認証局によるwebサイトの認証には3種類ある

- Domain Validation(DV):  Web サイト（サーバー）のドメインについて、確かに使用する権利があることのみを認証したもの
- Organization Validation(OV): DVに加え、運営する組織を認証したもの
- Extended Validation(EV): OVより更に踏み込んで組織の存在を認証するもの

![ssl_table.png](https://qiita-image-store.s3.amazonaws.com/0/20307/1a405394-5ea5-1897-b7da-dbf8c1aaf707.png)


画像&参考: [改めて知ろう、SSLサーバー証明書とは？（第二回）](https://knowledge.sakura.ad.jp/2988/)

## SSL証明書の発行方法

認証局で発行できる。
詳しくは:  [SSL証明書の発行方法・手順まとめ(旧来の手作業で発行)](https://qiita.com/cyborg__ninja/items/876c3d648a13831523e3)

上の方法だと有料だし、手間なのでLet's Enxryptを使った無料のSSL発行がよく行われていた。
詳しくは: [Let's Encryptで無料SSL証明書を取得する](https://qiita.com/shojimotio/items/4fa82b21390e8a6d8446)

ただ、Let's Encryptも2018/10までは90日毎に更新しなければいけなくて面倒だった。
今回のリリースでフルマネージドなSSL管理を無料で行えるようになった。
詳しくは: [Working with Google-managed SSL certificates](https://cloud.google.com/load-balancing/docs/ssl-certificates#managed-certs)


## Let's Encryptってなに？
証明書を発行や更新を自動で無料でできる便利なやつ
詳しくは: [Let's Encrypt 総合ポータル] (https://letsencrypt.jp/)


## Let's Encryptって安全なの？
運用で無料な分、セキュリティの質は少し落ちる。

Let's EncryptはDVの発行できるが、OVやEVは発行できない。
つまり、接続先サーバーがそのドメイン名に適切に紐づけられていることについては保証するが、証明書の所有者については保証しない。

いろんな議論はされているので目を通して、リスクを考慮して採用すべき。
参考: [上場企業やgo.jpドメインでもLet's Encryptのサーバ証明書の利用が広がる](https://security.srad.jp/story/18/06/07/0535217/)
ネイティブC++とOpenSiv3Dで音ゲーを作った話

## はじめに
はじめまして， shirryです．長野で高専生をしています．今回初めてadvent calenderに投稿させていただきます．

今年の学校の文化祭で，OpenSiv3Dを使って音楽ゲームを友達と合作したときの話をしたいと思います．

参考までに:僕の[Github](https://github.com/shirry0129)     友達の[Github](https://github.com/Yamamoto0773)
今回作った音ゲーのリポジトリ:https://github.com/shirry0129/miditone

## 事の始まり
企画係:クラス企画なにする?
僕:音ゲーやりたい

クラス投票を経て...

企画係:音ゲーに決まりました

## 開発
一緒に開発をした友達が，過去に一人で音ゲーを作っていたので，そのときの知見を借りて作成しました．

### システム
ノートの判定クラスや譜面の読み込みクラスといったI/Oまわりや，ノートの描画位置を決定するためのクラスなどの下請けクラスはネイティブC++を使って友達に書いてもらいました．任せっきりなので正直よく分かってない…

### 描画/データ構造
シーン遷移や各シーンの描画，読み込んだデータの管理の部分は僕が作りました．
判定エフェクトの部分は友達が作ってくれました．

#### シーン遷移/データ管理
HamFrameworkのSceneManagerを使用させていただきました．(hamukun様ありがとうございます)
各シーンでのデータの共有も，HamFrameworkのSceneManagerが提供する機能を用いて行いました．

#### 各シーンの描画
今回の音ゲーはアーケードのものと似たシステムで作ったので，次のようなシーン構成で各シーンを作成しました．

```
タイトル
選曲
パラメータ設定
プレイ
リザルト
トータルリザルト
エンディング
```

基本的に画像を用いて描画を行い，スコアなどの可変な値のみ`String`を用いて動的に表示を行いました．
プレイシーンでは，ノートの降ってくるレーンを画面奥に消失点を置いて描画したので，つねに同じ速度で移動をしていると錯視?で速さが変わっているように見えてしまい，それを減らすための処理(速度，高さを1次関数で制御)しました．しかし，そのときの最適なパラメータが分からず苦労しました．
<img width="2032" alt="スクリーンショット 2018-12-07 23.55.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/145501/82d9458e-c161-9618-bd81-57a9e8adc966.png">
(念のため曲情報にぼかしを入れています)

また，文字列を表示する場所では，`Glyph`を使って文字幅を変化させることで枠内に収まるように表示させることができました．`Glyph`すごく便利．

他にも，選曲画面などで今選択されているものをハイライトするのに`Rect`のメソッドで移動/拡大をしたり，Siv3Dにめちゃくちゃお世話になりました．
<img width="2032" alt="スクリーンショット 2018-12-07 23.54.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/145501/69ccfc02-1c69-87fc-3c5d-ab33bb7bbd76.png">
(パラメータ設定画面．まわりの1回り小さい四角はscaledとTransformer2Dでスケールを縮めている)

#### データ管理
実は開発の時点で`AudioAsset`が存在していることに気付いていなくて，毎回ファイルを読んでいます()
これが原因かどうかは分かりませんが，Windowsへ持っていって動かすとオーディオファイルのロードがかかるタイミングで落ちたり落ちなかったりして，本番中にリアルタイムデバッグをするはめになっていた(もうしたくない)
macだと落ちることなく動いたのはなんでだろう…

また，選曲画面で用いたジャケット写真をpngファイルで1つ1つ用意していたんですが，ID3タグ情報から直接引っぱってこれたらなー，とか思って音ゲー製作が終わった後でそれ用のクラスを作ろうとしています．

### 悩んだこと
#### 視覚効果の軽減
先述したプレイシーンでの速さの変化の違和感をうまく無くす方法が全く分からず，あてずっぽうな実装になった．今思えば`Easing`使ったらうまく行ったんだろうか．

#### データ管理
`AudioAsset`なんで無いと思ってたんだろうか．それと，ディレクトリ構造をどうするべきかいい解が分からず，音源用，ジャケット写真用とだけしか分けていなくて，各データは曲idで名前を付けてしまったのですごく分かりづらくなってしまった．

### 得られたこと
ここまで大きなプログラムを書いたことは無かったので，オブジェクト指向のありがたみがすごく分かった．C++つえー．
あとは**経験って大事**だということ．
実際に自分で書いてみることで，ここはこうすればきれいだな，とか，ここもっと効率よく書きたいな，とかの新たな発見や疑問が出てきて，それによって次のコードがきれいに書けるようになるし，次の開発ではこの経験をふまえての試行錯誤が出来るようになると思った．

## 最後に
開発をいっしょにしてくれた友達ことnanamin,そして素晴らしいフレームワークを開発して下さったReputeless様，すごく便利なSceneManagerを作成してくれたhamukun8686様，ありがとうございました．
作者のReputeless様には夏に長野に来ていただき，直にお話を聞かせてもらうことができ，開発の大きな助けとなりました．
この場を借りてお礼申し上げます．
おかげで自分1人では出来ないことが簡単にでき，それによってさらにプログラムをやりたいと思えるようになりました．

今回の開発を通して，自分1人でやりたい，作りたいと思うものが出来たので，今度はそれをやっていこうかなと．
Siv3D関連でいえば，ID3タグが読めるようにしてプルリクエストを投げてみようかなと思っていたり(いつになることやら)，SwiftにSiv3Dを移植してみたいな，ともぼんやり思ってたりします．

拙い文章ではありましたが，ここまで読んでいただきありがとうございました．
railsからvueに配列を渡すと文字列になって困った時の解決方法

# railsからvueに配列を渡したい。

```slim
request-form ids=@array_instance
```

この `ids` をvue側で値確認するとこうなる

```
"[12, 13, 14]"
```

ちゃんと受け取り側でArrayと指定しているのに文字列で受け取る、非常に辛い。

```javascript
export default {
  props: {
    ids: {
      type: Array,
      required: true
    }
  }
}
```


## 問題の原因は `v-bind` を利用していないから

rails側からvueに値を渡す時には `v-bind`　を使おう

### 公式解説記事
> 文字列だけではなく、式はオブジェクトまたは配列を返すことができます。
https://jp.vuejs.org/v2/guide/class-and-style.html


### 解決コード

渡したい値のキー名の直前に `v-bind:` を入れる。
シンプル。

```slim
request-form v-bind:ids=@array_instance
```

これでめでたく

```
[12, 13, 14]
```


と値を受け取ることができた。
【Ubuntu】Ubuntu16.04にPython環境インストール （後半）

【はじめに】
前半に続いて行きます。
[【Ubuntu】Ubuntu16.04にPython環境インストール （前半）](https://qiita.com/wb_seo/items/4a5156be897b1e67c5ba)

【環境】
OS:Ubuntu 16.04
【レビュー】
前半はOpenCVをインストールするのに必要な環境を準備しました。
画像処理にはやっぱOpenCVが必須なのでぜひやってみて下さい。

【インストール】
今回のインストールには[OpenCVリポジトリ](https://github.com/opencv/opencv)で最新バージョンをダウンロードします。

```linux:command
cd ~
wget -O opencv.zip https://github.com/Itseez/opencv/archive/3.3.0.zip
unzip opencv.zip
```

次に、OpenCV_contribをインストールします。

```linux:command
cd ~
wget -O opencv_contrib.zip https://github.com/Itseez/opencv_contrib/archive/3.3.0.zip
unzip opencv_contrib.zip
```

Pythonのパッケージマネージャーをインストールします。このpipを利用して様々なPythonのライブラリをダウンロードすることができます。

```linux:command
wget https://bootstrap.pypa.io/get-pip.py
sudo python get-pip.py
```

ここからはPythonの仮想環境構築です。

```linux:command
sudo pip install virtualenv virtualenvwrapper
sudo rm -rf ~/.cache/pip
```

次に、```~/.profile```に```virtualenv```のパスを追加します。

```linux:command
echo -e "\n# virtualenv and virtualenvwrapper" >> ~/.profile
$ echo "export WORKON_HOME=$HOME/.virtualenvs" >> ~/.profile
$ echo "source /usr/local/bin/virtualenvwrapper.sh" >> ~/.profile
```
profileに追加したパスがちゃんと通ったのかを確認してみます。

```linux:command
source ~/.profile
```

次に、コンピュータビジョン開発に使用するPython仮想環境を作成します。

```linux:command
mkvirtualenv my_env -p python2
mkvirtualenv my_env -p python3
```
ちなみに特定のPythonのバージョンを指定したい時は以下のコマンドで出来ます。

```linux:command
mkvirtualenv my_env --python=/usr/bin/python2.x
mkvirtualenv my_env --python=/usr/bin/python3.x
```

ここまでできたら環境に入ってみます。

```linux:command
source ~/.profile
workon cv
```

どうですか？ちゃんと入りました？ユーザー名の前に```(cv)```これが表示されればオッケーです。

次にはPythonで行われている多くな開発の中でほぼDefaultだと思われるライブラリのNumpyをインストールします。

```linux:command
pip install numpy
```

もう少しやれば終わりです。頑張りましょう～！！(実は僕が疲れました…)
でも元気出します。

次はOpenCVのコンパイルとインストールです。

```linux:command
cd ~/opencv-3.3.0/
mkdir build
cd build
cmake -D CMAKE_BUILD_TYPE=RELEASE \
  -D CMAKE_INSTALL_PREFIX=/usr/local \
  -D INSTALL_PYTHON_EXAMPLES=ON \
  -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib-3.3.0/modules \
  -D BUILD_EXAMPLES=ON ..
```

これが終わったら画面上でpython2 or python3の何かの情報が表示されるはずです。

はい！コンパイルします。

```linux:command
make -j4
```

これ結構長いです。コーヒーでも飲みながら待ちましょう。

最後です。ここまでの長い旅お疲れさまでした。やっぱ環境設定って長いですね...無駄な時間にはしたくないです！
ちなみに自分の環境はPython3.5なのでこれでやります。

```linux:command
ls -l /usr/local/lib/python3.5/site-packages/
```

```linux:comand
cd /usr/local/lib/python3.5/site-packages/
sudo mv cv2.cpython-35m-x86_64-linux-gnu.so cv2.so
```

```linux:command
cd ~/.virtualenvs/cv/lib/python3.5/site-packages/
ln -s /usr/local/lib/python3.5/site-packages/cv2.so cv2.so
```

本当最後です。ちゃんとインストールされたのか確認してみます。

```linux:command
source ~/.profile 
workon cv
python
```

```python:command
import cv2
```

これでOpenCVのバージョンが表示されるとオッケーです。

【まとめ】
これで全ての環境設定は終わりました。次からは画像処理の記事になるんじゃないかなと思います。
あくまでも僕の勉強の目的なので皆さんにはつまらないかもしれませんが、世の中にはまだ初心者さんたちがたくさんいらっしゃると思うので一緒に頑張りましょう。
エンジニア・ノマドワーカーにカラオケ屋を推奨したい

エンジニアの『開発環境を整える』と言えば、パソコン上のシステムを整えることが多いと思います。そうではなく、リアルの世界でも素敵な開発環境を提案します。

リアルの世界の開発環境というと、『スタバで開発するよ～』とか、『コワーキングスペースで開発するよ～』という方がほとんどでしょう。そして、だいたい耳には外音を遮るためにイヤホンを付けていることでしょう。

鼓膜揺らすだけじゃ物足りない！！音楽は体で音を感じなきゃ！！！

ということで  
今回提案するのは『カラオケ屋で好きな音楽を爆音響かせ、体揺らして開発しよう！』です。

#準備するもの
・6.3 mm ⇔ 3.5 mm ステレオケーブル（ https://www.amazon.co.jp/gp/product/B015XHD4KW/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1 ）←アフィじゃないので安心してください。
・イヤホンジャックが挿せる端末
・好きな音楽

たったこれだけです。

#やってみよう
今回用意したいケーブルはこちら。
![1.JPG](https://qiita-image-store.s3.amazonaws.com/0/35783/281fa46a-f8ea-df3e-3984-c7d352e9af70.jpeg)

機械を壊してしまわないように、『音量』と『マイクの音』と『エコー』をすべてゼロにしておきます。
![2.JPG](https://qiita-image-store.s3.amazonaws.com/0/35783/3d92e9ce-e02b-1683-2519-96cde07b84dc.jpeg)

購入したケーブルの大きな端子をマイク端子に入れます。
![3.JPG](https://qiita-image-store.s3.amazonaws.com/0/35783/7cb23e17-c1d0-0bd9-7442-dfaf52229ac9.jpeg)

好きな音楽を流しておきます。
![5.JPG](https://qiita-image-store.s3.amazonaws.com/0/35783/ec1a5a7a-7ce5-87f8-fed3-a65336a0d550.jpeg)

少しずつ音量を上げていきます。
![4.JPG](https://qiita-image-store.s3.amazonaws.com/0/35783/e3ddaae6-ffc5-b797-442d-15bd9e9e8191.jpeg)

#たったこれだけ！！
たったのこれだけで最高の環境で開発ができます。
テンション上げて生きていきましょう！
機械学習まわりの用語をざっくりイメージする (随時更新ノート)

## この記事について
この記事は、機械学習まわりの用語をざっくりイメージするために、いろんな方向から噛み砕いて、解釈してみようという試みです。

## 用法
ざっくりイメージする試みなので、ここでは正確性は犠牲にします。正しく扱わないとモゾモゾする方は、これ以上読み進めないほうがいいかもしれません。

それでは書いてみましょう

# 機械学習
> Machine Learning

という訳ですが、

> Computational Learning

のほうがしっくり来る気がします。

画像 / テキスト / 信号などのデータをコンピュータで演算して、
その結果を記憶しておく。これを学習と呼んでます。

ニンゲンも、よくわからない図形を100回くらいノートに書いて、
形状、読み方、意味、成り立ちを記憶して、扱えるようになりました。
漢字の学習ですね。

その際に、形の似ているものを発見したり、読み方が似ているものを発見したり、
なんかこの部位は人の形にみえるなぁ・・などと捉えていました。
そうです。それが **特徴量** です。

たとえば、りんごの特徴。
赤い / 大きさこのくらい / 重さこのくらい / 甘い / 酸っぱい / パイにする
様々な特徴を挙げることができます。

(なんだかこれって、オブジェクトのモデリングに似ていますよね)

# ニューラルネットワーク
神経細胞(ニューロン)の発火と伝達を参考に、コンピュータで計算できる形にしたものがニューラルネットワークです。

まずは、入力層と出力層を持っています。

これだけでは、入力がそのまま出力されて変化がないので、脚色演算をする層を追加します。これを隠れ層と呼んでいます。

これらの計算がニューラルネット中を伝搬して伝わって、
出力層にでてくるというしくみです。

抽象化をするときによく使う方法ですが、しくみを点と接続に分解します。
逆に言えば、点と接続でしくみを作る、ともいえます。

ある層の**点をノード**、**接続をエッジ**と呼びます。
点は**活性化関数**を持ちます。エッジは**重み**をもちます。

重みを活性化関数にあらかじめ入れ込むこともできるのですが、
あとで、「あーここの活性化は無効にしたいな・・」とか、調整の余地を残しておくためにも、重みは係数として独立させておいたほうが扱いやすいです。

賢い人はここで「重みも学習を反映させて自動調整したらよくない？」とか気づくらしいです。

# CNN (Convolution Neural Network)
畳み込みニューラルネットワーク

畳み込みってなんでしょう？？
**たたむ**はわかります。

あなたの手元に紙片あれば、4つ折りに畳んでみましょうか。
もうすこしいけます？もう４つ折りに。。硬いですよね、紙。もとは木ですもんね。
これが畳むという行為です。

大きいものを、小さくたたむ。
コンピュータが大きなデータをたたむために、演算する。

CNNは、画像処理でよく使われる手法らしいです。
ざっくりイメージしてください。

> 画像を、
> モザモザにしたら、
> 肌色多い

精細な画像から、ある特徴を抽出できませんでした！？いま。

もうひとつ

> 画像を、
> モザモザにして、
> 赤色だけ取り出したら
> 肌色の長方形の両端に２つ

なんかまた、この画像の特徴を抽出できましたよね。

フィルタ処理、活性化関数、畳み込み処理でモザモザ。
モザモザから特徴を抽出したものが、プーリング処理。

CNNでは、これを繰り返し行います。

# RNN (Recurrent Neural Network)

画像は１枚絵なのでよかったんですが、
動画 / 音声波形 / 文章はくりかえし同じような信号が入力されます。
なので、隠れ層の値を時系列にしたがってどんどん更新することにしました。

ただまあ、そう都合よく計算し続けられることばかりではないので、
オーバーフローもアンダーフローもありますし、メモリも有限です。

そこで LSTM (Long Short-Term Memory) が生まれました。

# LSTM (Long Short-Term Memory)
しらべてきます！


## おわりに
機械学習の本をなんど読んでもイマイチイメージがわかない人は、
コード書いてちゃんと遊んでみるとか、
この記事のように、ちょっとぼんやり遠くからあいまいさをもって眺めてみて、
もちまえの知識との結合をはかるとか、いいかもしれませんね。

このノートは更新を続けます。
こういうときに個人でなく、有志みんなで編集できると心強いのですが。
合成数列の和アドベントカレンダー Ruby 編

合成数列の和アドベントカレンダー Advent Calendar 2018 の 1 日目です

## ルール
* 入力として正の整数 N を与えたら 4 から始まる [合成数](https://ja.wikipedia.org/wiki/%E5%90%88%E6%88%90%E6%95%B0) の数列の 1 番目から N 番目からの合計を出力してください
* N は最大で 100 とします

## プログラム(Ruby)
```ruby
require "prime"

without_prime = Enumerator.new do |y|
  a = 1
  loop do
    a += 1
    loop { a.prime? ? a += 1 : break }
    y << a
  end
end

puts without_prime.take(ARGV.first.to_i).sum
```

## 出力例
```
$ ruby test.rb 2
10
$ ruby test.rb 4
27
$ ruby test.rb 10
112
$ ruby test.rb 100
7059
```

## メモ
この問題は [ずんだ問題](https://qiita.com/tbpgr/items/3a4169b370f1a317ece0) の番外編です
Qiitaアカウント新規登録時に選択するタグについて

# 初期表示されてるタグ
![Qiita初期タグ一覧.PNG](https://qiita-image-store.s3.amazonaws.com/0/309488/6bdbc765-f844-21b5-ed93-f0ff5fde9c06.png)

~~JavaとBashとUbuntuとVimについての情報が欲しかったのに初期選択肢にないのですが。。。~~
~~これはどういう基準で初期表示タグが選ばれているんですかね？~~

投稿テストも兼ねたくだらない話題。
ROS2でturtlebot2_demo動かした

#ROS2のturtlebot2_demoを動かすときにハマったこと
ROS2の公式ページのtutrialsの中にturtlebot2のデモをやっと動かせたので、そのときにハマったことを残しておきます。

環境はUbuntu18.04です

##とりあえず、公式通り動かしてみる
```
launch `ros2 pkg prefix turtlebot2_teleop`/share/turtlebot2_teleop/launch/turtlebot_joy.py
```
動きませんでした。
ということで、もう一つの起動方法を試しました。

端末を立ち上げて、以下を入力

```
$ ros2 run turtlebot2_drivers kobuki_node
```
もう一つ端末を立ち上げて

```
$ ros2 run joy joy_node
```

これも、エラーは出ないけど動きませんでした。

##解決方法

launchファイルを読んでみると、ros2 runでの起動時に立ち上げてたのは、

- turtlebotの起動
- コントローラーのドライバーみたいなやつ（間違ってたらごめんなさい）

の2つで、コントローラーからturtlebotにメッセージを送るノードが足りてなかったようです。

以下に、起動できたときのコマンドを残しておきます。

1つ目の端末

``` 
$ export ROS1_DISTRO=melodic && source /opt/ros/$ROS1_DISTRO/setup.bash
$ source ~/ros2_ws/install/local_setup.bash
$ ros2 run turtlebot2_drivers kobuki_node
```
2つ目の端末でコントローラーを接続

```
$ sudo ds4drv
```
3つ目の端末

```
$ export ROS1_DISTRO=melodic && source /opt/ros/$ROS1_DISTRO/setup.bash
$ source ~/ros2_ws/install/local_setup.bash
$ ros2 run joy joy_node
```
4つ目の端末

```
$ export ROS1_DISTRO=melodic && source /opt/ros/$ROS1_DISTRO/setup.bash
$ source ~/ros2_ws/install/local_setup.bash
$ ros2 run teleop_twist_joy teleop_node 
```

なお、以下の2つは毎回打つのがめんどくさければ、.bashrcに書いてしまって問題ないと思われる。

```
$ export ROS1_DISTRO=melodic && source /opt/ros/$ROS1_DISTRO/setup.bash
$ source ~/ros2_ws/install/local_setup.bash
```

端末に入力するときに、1つ目を打ったあと、2つ目を打つと、何か出るかもしれないが、もう一度入力すれば、問題ない。

##最後に
今回、デモを動かすのにPS4コントローラーを使いました。
PS4コントローラーではR1ボタンを押しながら右スティックで操作できましたが、非常に使いづらいかったです。
今後、コード読みながらPS4コントローラーに対応させれたらなとおもいます。（もうあるかもしれない）
Delegataを簡単に説明。あとプロトコルとか。

理解に苦しんでいるdelegateとプロトコル(swift)の説明を自分なりに
解りやすく、振り返りようでまとめました。

**間違いや誤った表現箇所等があればコメントで教えてくれると嬉しいです。**
**これも忘れないでね！ってことがあれば一緒にご教示ください。**

# Delegateの定義
>Delegation is a design pattern that enables a class or structure to hand off(or delegate) some of its responsibilities to an instance of another type.

「デリゲートは、デザインパターンです。」
ここはマッハで無視します。

陥りやすいパターンとして、「Delegate」という英語をそのまま「デリゲート」理解しようとするとそもそもの概念の理解が難しくなることがあると思うので、英語の意味も調べます。

>delegate toとは
権限などを〉〔…に〕委任[付与]する、〈人を〉(代表者[使節]として)〔…に〕特派[派遣]する
(複合動詞)

ふむふむ、権限などを付与する(継承)とのことですね。
つまりdelegateは**「クラスを別のクラスへ継承できる、そして継承されたクラスの中で継承元のクラス内の情報を付与する動詞」**

少し乱暴ですが、大まかな的は得てるかと思います。
# 具体的な使い方の説明
ここでプロトコルが現れます。
一応英語での意味も調べます。
>protocolとは
(外交上の)儀礼、典礼、条約原案、議定書、プロトコル、(国家間の)協定、(実験・治療の)実施要綱

ふむふむ、つまり「決まりごと」または「お約束」ってな感じですね。
それでは具体的な説明に入ります。

登場人物は3人です。

- 処理を依頼する、のび太くんクラス
- 処理を担当する、ドラえもんクラス
- のび太くんがドラえもんへの依頼時に使用する携帯(プロトコル)

```swift:のび太くんクラス
// プロトコルを作る。
// プロトコルを作る。
protocol 助っ人Delegate: AnyObject {
    func 助けを呼ぶ(呼んでる人: のび太) //助っ人を呼ぶ宣言
}

// のび太クラス
class のび太 {

    // ここで、プロトコルを継承するクラスのインスタンスを用意する。
    weak var delegate: 助っ人Delegate?

    func イジメられた() {
        delegate?.助けを呼ぶ(呼んでる人: self)
    }
}

// 助っ人Delegateプロトコルに準拠したドラえもんクラスを定義
class ドラえもん: 助っ人Delegate {
    func 助けを呼ぶ(呼んでる人: のび太) {
        print("\(のび太)待って！ドラえもんが来るよ！")
    }
}

let メガネ = のび太()
let どら焼き = ドラえもん()
メガネ.delegate = どら焼き  
メガネ.イジメられた()    // "のび太待って！ドラえもんが来るよ！"
```
# まとめ
自分として理解に苦しんだ理由としては、delegate = クラスの継承 = delegateっていう考え方をしていたことが第一の理由で、
第二の理由としては、クラスの概念を理解していなことが大きかったです。
C++でポインタ引数をdeleteする時の注意

ポインタ引数が参照型で無い限りSAFE_DELETE()などしても元のポインタはNULL初期化されてませんのでご注意を。

```main.cpp
#define SAFE_DELETE(x) if (x) { delete (x); (x) = NULL; }

void foo(int* a)
{
	SAFE_DELETE(a);	// NULL初期化されてるのは引数変数
}

void main()
{
	int* a = new int;
	foo(a);
}
```
Vue.js童貞がネコ本読んで得たもの①

## はじめに

どうも、Vue.js童貞です。
JavaやRubyでバックエンドをずっと開発してきて、「センスがないから」とか「UIとか笑使えればええやん」とか言いながら逃げ続けてきたフロントエンドの領域ですが、どうやら抱えているプロダクトの影響でそろそろ逃げきれなくなりそうなので、初心に立ち返って０から勉強し直しています。
その過程で通称「ネコ本」を購入して自己学習をシコシコしてきたので、そこで学んだことを本稿に寄せることで、学んだことの知識の定着を測ろうかと考えた次第です。

### ネコ本とは？
Mio様の名著「基礎から学ぶ Vue.js」です。
https://www.amazon.co.jp/dp/B07D9BYHMZ


## Vue.jsとは？

2014年にリリースされたJavaScriptのフレームワークですね。

「学習コストが低い」「柔軟性が高い」「日本語ドキュメントが豊富」という特徴があります。
「日本語ドキュメントが豊富」←ここ大事ですね。英語ができないエンジニアにとっては死活問題です。

### 競合は？

React、Angularあたりですかね。よく知らないので差別化できる特徴はわからないです。
Angularはまだ触れていないのでわからないですが、Reactは少し触れてみてVueと比較して習得まで高いハードルを感じました。
こいつは仲良くなれそうにないですね。ちょっとVue.jsを習得してからまたチャレンジしてみたいと思います。


## 童貞卒業までの道程

- 基本
- データバインディング、条件分岐、繰り返し  // ←今日はここまで
- ハンドラ
- 算出プロパティ
- ウォッチャ
- コンポーネント、VueCLI、単一ファイルコンポーネント
- Vuex
- Vue Router

## 基本

Vueクラスのインスタンスの生成テンプレート

```javascript
vue = Vue.new({
  el: '#app',
  data: {
    message: "Hello Vue.js"
  },
  computed: {
    computedMessage: function(){ 
      return this.message + "!"
    },
  },
  created: {
  // アクションフック
  },
  methods: {
    myMethod: function(){
    },
  },
})
```

## データバインディング

Vueのデータバインディングを行うにはデータを全て「リアクティブ」なデータとして定義する必要がある。

一般的に、リアクティブとは「反応できる」とか「反応的な」という意味だが、
vue一度定義したデータを、呼び出したり、変更したりした際に様々なフック処理を呼び出すような状態であることを指す。

Vueインスタンスのdataオプションに定義することで、その文字列や配列、オブジェクトはリアクティブなデータとなる。

```javascript
Vue.new({
  el: '#app',
  data: {
    message: "Hello Vue.js", // こいつがリアクティブなデータとして登録された文字列
    ok: true,
    items: [
      ''
    ]
    error : null
  }
})
```

バインディングしたデータを描画したい場合、以下のように二重の波線括弧で囲む

```html
<div id="app">
  <p>{{ message }}</p>
</div>
```

属性に対してバインディングしたい場合は、`v-bind:`もしくは省略形として`:`と記載する。

```html
<div id="app">
  // これでは動かない
  <input type="text" value={{message}}>
  // これなら動く
  <input type="text" v-bind:value="message">
  // これでも動く
  <input type="text" :value="message">
</div>
```

## 条件分岐

`v-if`を使う

```html
<div id="app">
  <p v-if="ok">okはtrue</p>
  <p v-else>okはtrue</p>
</div>
```


描画に伴うものだけであれば、`v-show`も使えるが、htmlソースから消えるわけではない。

```html
<div id="app">
  <p v-show="ok">ok</p>
</div>
```


### 繰り返し
`v-for 繰り返し中の変数 in 対象の配列`を使う

```html
<div id="app">
  <ul>
    <li v-for="item in items">{{item}}</li>
  </ul>
</div>
```

的な感じで。


## 終わりに
初めてqiita記事書いたけど疲れたよ(´ཀ`」 ∠)_ 

次回に続く
AndroidStudioで実機にadbコマンドで文字入力できるはずだった話

こんにちは。私です。

アプリ作ってると文字入力範囲に文字数制限かけることってよくあると思うんですけど
テストの時入力するの大変じゃないですか？

##例：とある入力欄(文字数1000文字以内)
1001文字打つの大変じゃないですか？
といいますか、何文字打ったか数えられないですよね？
私案件で遭遇した時「はて？」ってなりました。

##adbコマンドを使おう！
>(私の)前提条件
*Android端末がデバッグモードで起動している
*カーソルが入力したいところに当たっている

先輩に相談し、教えてもらいました！
AndroidStudioのTerminalで
`adb shell input text (文字列)`
実行で文字が！ひとりでに！入ると！！！
ん…？…入らないな…？

##adb…インストールされてないね…？
そう。上記やり方で、カーソル当たっている入力欄に文字が格納されるはずだったが
まさかのadb未インストールのためコマンドが実行できない！！
Terminalで`adb`実行するとコマンドエラー…なるほど…
お主…存在しないんだな…？

##adb、ダウンロードしましょう。
※事前にAndroid SDKの場所を確認しておきます。
[File] → [Other Settings] → [Default Project Structure…]

<img width="812" alt="301.png" src="https://qiita-image-store.s3.amazonaws.com/0/217071/8143e58b-6a60-c231-d634-bc63396392fd.png">



1.コマンドでbash_profileを開きます。
`$vi ~/.bash_profile`

2.事前に確認したAndroid SDKの場所を記入します。
! 実際はご自身のパスを記入してください。
! $PATH:以降は例です。実際のものとは異なります。
`export PATH=$PATH:/Users/nono410/Library/Android/sdk/platform-tools`

3.bash_profileを再度読み込みます。
`$source ~/.bash_profile`

最後にTerminalで`adb`でエラーが出なければインストール完了です！

##その後もう一度やってみる
`adb shell input text (文字列)`を実行したところ無事に実機アプリ内入力項目に入力されました！

##ちなみに
文字数指定して入力するのに[文字列ジェネレーターさん](https://lazesoftware.com/tool/strgen/)を使用させていただきました。
文字数と文字種別指定したら文字列作ってくれるので入力数テストの際に重宝しました…。

##まとめ
コマンドとか使いこなすともっと作業効率上がるんだねっと再認識したお話でした。
結末は「AndroidStudioで実機にadbコマンドで文字入力できたお話」となりました。

では、皆様もよいadbライフを٩( 'ω' )و
LXDコンテナからコンテナ外へポートフォワーディング

## 方法１：LXDのProxyを使う (LXD >= 3.0)
Ubuntu 18.04 LTSの場合、デフォルトでLXD3.0がインストールされますので、こちらの方法が簡単でおすすめです。
### 追加 
```
$ lxc config device add <コンテナ名> <デバイス名> proxy listen=tcp:0.0.0.0:<ポート番号> connect=tcp:127.0.0.1:<ポート番号> bind=host
```

- ```<デバイス名>``` は、識別するためのラベルのようなもので、任意の名称を指定することが出来ます。
- ```listen=tcp:0.0.0.0:<ポート番号>``` は、転送先（ホスト）に関する設定です。0.0.0.0の場合、全てのNICに割り当てられたIPアドレスが転送先（待ち受けIPアドレス）となります。特定のIPアドレスを指定した場合、指定されたIPアドレスが転送先となります。
- ```connect=tcp:127.0.0.1:<ポート番号>``` は、転送元（コンテナ）に関する設定です。127.0.0.1の場合、コンテナのlocalhostが転送元となります。127.0.0.1以外の場合、指定されたIPアドレスが転送先となります。
- ```bind=host``` の場合、コンテナが転送元、ホストが転送先となります。

### 削除
```
$ lxc config remove <コンテナ名> <デバイス名>
```

### 参考
- LXDのproxyを使ってポートフォワーディング
 - https://hnakamur.github.io/blog/content/post/2018/07/05/port-forwarding-using-lxd-proxy/
- Container configuration Type: proxy
 - https://lxd.readthedocs.io/en/latest/containers/#type-proxy

## 方法２：iptablesを使う
```
# iptables -t nat -A PREROUTING -d <ホストのNICのIPアドレス/32> -p tcp -m tcp --dport <転送先ポート番号> -j DNAT --to-destination <コンテナのIPアドレス:ポート番号>
```

- 転送元となるコンテナのIPアドレスは、```lxc list```コマンド等で事前に確認します。
- ホストに割り当てられたIPアドレスが複数存在する場合、転送先としたいNICのIPアドレス（あるいはエイリアスのIPアドレス）を指定します。
- iptablesの設定を永続化させたい場合は、```service iptables save```や```/sbin/iptables-save```, ```netfilter-persistent save```など（コマンドはディストリビューションにより異なります）を実行し、設定を保存します。

## 方法３：HAProxyを使う

``` /etc/haproxy/haproxy.cfg
# globalとdefaultsは省略します。

frontend forward_service
  bind *:<転送先ポート>
  mode tcp
  default_backend forward_server

backend forward_server
  server forwardsv01 <コンテナのIPアドレス:ポート番号> check
```

- ```bind *:<転送先ポート>``` の``` * ```は、ホストに割り当てられた全てのIPアドレスが転送先（待ち受け先）ポートとなります。特定のIPアドレスを転送先とする場合は、``` *```を転送先とするIPアドレスに変更します。
- サービスのコネクションが頻繁に切断される場合は、転送するサービスに応じて、```timeout connect``` ```timeout server``` ``` timeout client```などのパラメータを設定します。
playground株式会社を退職しました

約1年半、CTOとして勤めていたplayground株式会社を退職しました。

# playgroundってどんな会社？
playground株式会社は、主に電子チケット「QuickTicket」を運営するベンチャー企業です。
西武ライオンズさん、サンリオピューロランドさんなどに導入されています。
電子チケットというと、音楽のライブなどをイメージされる方が多いと思いますが、QuickTicketは主に野球、ラグビー、バレーなど主にスポーツ興行で導入されています。
音楽関連も全くやっていないわけではなく、実は安室奈美恵さんの衣装展のチケットとして導入されています。
あまり目立ってはいませんが、実は今かなり勢いに乗っているベンチャーです。

スポーツ、ライブなどに興味のあるエンジニア募集中です！
https://www.wantedly.com/projects/225321

私が退職を決めたのは、playgroundに不満があるというよりは、会社や事業との向き合い方を考えたいということが一番の理由です。
辞める際になって言うのもなんですが、playgroundは非常に良い会社で、私はエンジニア採用、新規事業開発など多くのことについて広く裁量を持って関わることができました。
今後望んでもなかなか手に入らないだろうと思うくらいには良い環境でした。

# 私がCTOを辞めた理由

私はエンジニアのキャリアについて考える機会が多いのですが、エンジニアにはまず大きく分けて２つのパターンがあると思っています。

1. 技術が好きで、新しい技術などを積極的に使いたい。何を作るかよりも、どう作るかに興味がある。
2. 事業、サービスが作りたい。そのための手段として技術を使っている。技術が嫌いというわけではないが（むしろ好きだが）、新しい技術の利用よりも、サービスの拡大、事業の推進に興味がある。

これは、どちらが良い、悪いという話ではないです。
とりわけ、エンジニアは1の人が多いと思います。

私は完全に2で、技術は好きですが、事業を作ることに興味があります。
エンジニアのキャリアとして、2というのは非常に難しい人生をたどると思います。
時間が有限である以上、技術を極めつつ事業づくりもエキスパートになるのは非常に困難で、
エンジニアとして、どう会社や事業と関わるべきか、という話については、特に2に分類される人には難しいです。
1に分類される人は、技術を極め、それを事業でどう使うかを考えていくという比較的シンプルな役割分担ができるのですが、2の人は会社への関わり方を考える機会が多いと思います。

私はCTOという職種は、基本的には1が求められると思っています。
つまり、技術を極め、技術を利用して事業やサービスの運営を助けていくことです。

ただ、私はCTOよりは、事業自体を作る人間になりたいと思いました。
そのため、CTOは辞めて、一人でサービスを作っていくという道を選びます。

今後どうなるかはわかりませんが（9割方失敗するでしょう）、
自分で考えたサービスを自分で作るということを、できる限りやっていきたいなと思います。
mysql phpmyadmin 連番振り直し

auto increment の連番を振り直したい。
phpmyadmin の SQL にて


```sql

SET @i := 0 ;
UPDATE users SET id = (@i := @i +1) ;
ALTER TABLE users AUTO_INCREMENT = 10000

```
これで users テーブルの 連番が 10000 から振り分けられるようになる。
DockerとHexoを使ってgithub-pagesのローカル環境を構築する

# 困りごと
- ローカル環境にnpm入れて構築しても良いけど、バージョン混在したり、汚れそう
- UbuntuベースのDockerイメージが多い。サイズが700MB超え
- メンテナンス放置されてて上手く動かない
- volumeの永続化したり…コマンド長いのよね…マシンが変わった時、コマンド履歴辿れない事を考えると不安

# やりたい事
- Alpine linuxベースの軽量イメージ
- Volumeの永続化とか、ポート設定とか諸々、docker-composeに書いて省力化
- Hexo-adminプラグインで、WEBブラウザからマークダウン記事の作成編集、プレビューする
- Hexo-git-deployerプラグインで、github-pagesへの投稿も省力化
- ブログソース、テーマ、設定をgitリポジトリ管理、githubにアップ

# ソース

[davyyy/docker-hexo](https://github.com/davyyy/docker-hexo)をForkして、作成することにした。

ソース：[tknxn/docker-hexo](https://github.com/tknxn/docker-hexo)

- Hexo-adminを入れれば、webブラウザから記事の追加・編集、マークダウンのプレビューができる
- Hexo-deployer-gitを入れて、ごにょごにょすれば、circle CIを経由せずに静的ファイルをgithubにpushして、github-pagesにホスティングすることもできる
WordPressの管理画面にIntercomのウィジェットを出す時のスニペット

結局やらなかったのでコード供養。
MSP的な運用などで、WordPressを運用している人のサポートにIntercomを使いたい時にどうぞ。

```php
<?php
/*
Plugin Name: Admin Intercom Widget
Plugin URI: https://gist.github.com/hideokamoto/c0b9002ad73f145e1c6d6bc3b99f2b7b
Description: 管理画面にIntercomのWidget出すプラグイン
Author: hideokamoto
Version: 0.0.1
*/
final class My_IntercomWidget {
	/**
	 * Show intercom widget in the WordPress Dashboard
	 */
	public function show_intercom_widget () {
		?>
		<script>
		const APP_ID = "YOUR_APP_ID";
		
		window.intercomSettings = {
				app_id: APP_ID
			};
		(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/' + APP_ID;var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()
		</script>
		<?php
	}
}

add_action('admin_footer', array('My_IntercomWidget', 'show_intercom_widget'));
```
【Ubuntu】Ubuntu16.04にPython環境インストール （前半）

【はじめに】
どうもどうも記事書くのは２回目です。
前回はUbuntuにDockerをインストールしてみました。いかがでしたか?うまくいきましたか?まだ足りない知識なんですけれども少しでも役に立ちたいです。

【概要】
UbuntuにPython3.5環境を入れて画像処理やデータ分析いわゆる機械学習の処理を動かせるような環境を作るのが今回の目的です。

【環境】
OS:Ubuntu 16.04

【引用】
今回の記事は[pyimagesearchのドキュメント](https://www.pyimagesearch.com/2016/04/18/install-guide-raspberry-pi-3-raspbian-jessie-opencv-3/) こっちの方法でインストールしてみます。僕も結構この手順でやりました。

【準備】
まずはインストールができる環境を準備します。
パッケージをアップグレード＆アップデートします。

```linux:command
sudo apt-get update && sudo apt-get upgrade
```

後のOpenCV設定に役に立ついくつかの開発ツールをインストールします。

```linux:command
sudo apt-get install build-essential cmake pkg-config
```

次に、ディスクから様々なイメージファイル形式を読み込むことができるイメージI/Oパッケージをインストールします。

```linux:command
sudo apt-get install libjpeg-dev libtiff5-dev libjasper-dev libpng12-dev
```

次に、様々なビデオ形式を読み込むことができるI/Oパッケージをインストールします。

```linux:command
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev libv4l-dev
```

```linux:command
sudo apt-get install libxvidcore-dev libx264-dev
```

OpenCVライブラリには、  画像を画面に表示し、基本的なGUIを構築するために使用されるhighguiというサブモジュールが付属しています。highgui   モジュールをコンパイル するには、GTK開発ライブラリをインストールする必要があります

```linux:command
sudo apt-get install libgtk2.0-dev
```

OpenCVを最適化するためのいくつかの依存関係をインストールします。

```linux:command
sudo apt-get install libatlas-base-dev gfortran
```

最後に、Python 2.7とPython 3の両方のヘッダファイルをインストールして、OpenCVをPythonバインディングでコンパイルできるようにします。

```linux:command
sudo apt-get install python2.7-dev python3-dev
```

【まとめ】
これまでかかる時間は大抵1時間前半だと思います。
引用した記事はRaspberryPiなんですけどLinuxっていう共通点があると思うので問題はないと思います。(実際これで約9ヶ月間画像処理をやりました)前半でインストールに必要な準備は終わったので後半はスピード感出して行きたいと思います。

追加
[【Ubuntu】Ubuntu16.04にPython環境インストール （後半）](https://qiita.com/wb_seo/items/dc76e63372e801cddec2)
AWS DevDay 2018/11/01 のGraph Database and Amazon Neptuneに参加してきた

# 目的

+ 弊社では既にOrientDBを使っているものの、バグを踏むことが多く、別のGraphDBでいいものがないか探しに行った

# 内容

## 基本的なこと

|向いてる関係性|DB|
|----|----|
|多対多|GraphDB|
|多対一|RDBMS|
|一対一|KVS|

## GraphDB でいける可能性があるもの

+ SQL を書いてみたら、`connect by` とか`with` とか出てきたら可能性あり
+ 個人にカスタマイズされたレコメンデーションやナレッジグラフとかも可能性あり


## Neptune の特徴

+ Traversal に特化
    + ノートを起点に同時多発的に情報を探す
+ Analytics には向いていない
    + 全体を見てのクラスタリング等
+ スケーリング、可用性に特徴あり
    + 15個のリードレプリカを立ち上げると10万/秒のクエリ発行が可能
+ インスタンスの性能をあげれば線形にパフォーマンスがあがる
+ トランザクションがある

## Neptuneの注意事項

+ 可視化機能がない
+ public ip は付与されないのでVPC内に構築すること
+ 東京リージョンにはまだない（2018/11/01時点）

# 感想

+ 現在、OrientDBをSQLで使っているけど、他のGraphDBとの互換性を考えるとGremlin を使ったほうが良さそう
+ OrientDB のOSS版だからバグを踏みまくってる可能性もあるので、AWSのSAがいるNeptuneのがもしかすると安心かもしれない
インスタ 画像 インスタ ストーリ保存方法シンプル


インスタントグラムは、世界中のユーザー数が10億人に達したと発表しました。毎日IGにアップロードされる画像やビデオの数が非常に多いと考えられます。 検索機能を使用してたくさんの美しい写真を見つけましょう。個人のコレクションとしてダウンロードして保存したい場合があります。 Saveigの無料IGダウンロードサービスは簡単かつ便利ですが、一度に複数の画像や動画をダウンロードできます。

Saveは無料のIGダウンロードサービスを提供し、URLを添付してインスタントグラムイメージやビデオを保存したり、IGユーザー名を入力して、ユーザーの投稿内容を確認またはパッケージ化することができます。...

https://saveig.com/ja/

すべてのポートレートを選択してダウンロードするには、IGのユーザー名を入力してください

<img width="1206" alt="Screen Shot 2018-11-01 at 1.41.39 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/309438/5be55134-05e4-0bbb-53c3-7d326068ac3d.png">

インスタ ストーリー保存
<img width="1084" alt="Screen Shot 2018-11-01 at 1.54.10 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/309438/4b0d070b-2504-62c4-aca1-b759a055ce5f.png">
3段も4段もへっちゃら多段SSH簡単鍵認証

# 概要
「どんだけセキュリティ意識高めなの！？」というのは冗談で、 様々な事情があり４段SSH接続しなければいけない状況になった。
とてもやっていられないのでSSH鍵認証を駆使してコマンド一発で4段目まで入れるようにしたメモ。
多分来年には状況が変わっているので2018年版。

# 環境(登場人物)
- ローカル
- 1段目:踏み台サーバ1(step1)
- 2段目:踏み台サーバ2(step2)
- 3段目:踏み台サーバ3(step3)
- 4段目:目的地サーバ(step4)

実は鍵は共通でも良いけど上司に怒られるので予防の為に分けておく。

# ポイント
- ~/.ssh/config書くのはローカルのみ
- 秘密鍵はローカルでのみ管理
- 経由するサーバは公開鍵を置くだけ


# 手順
```
cd ~/.ssh/
```
作業はここで行うのが楽。

ローカル環境で鍵作成。

```
ssh-keygen -C "step1の鍵" -f step1key -t ecdsa -b 256 -N ""
ssh-keygen -C "step2の鍵" -f step2key -t ecdsa -b 256 -N ""
ssh-keygen -C "step3の鍵" -f step3key -t ecdsa -b 256 -N ""
ssh-keygen -C "step4の鍵" -f step4key -t ecdsa -b 256 -N ""
```

パスフレーズなし。
楕円曲線暗号256bitが使えない環境の場合は「-t rsa -b 4096」辺りで。

step1key,step1key.pub
step2key,step2key.pub
step3key,step3key.pub
step4key,step4key.pub
が作成されます。  

ローカルの.ssh/config設定。

```bash:.ssh/config
Host step1
  HostName step1.jp
  User username1
  IdentityFile ~/.ssh/step1key

Host step2
  HostName step2.jp
  User username2
  ProxyCommand ssh -W %h:%p step1
  IdentityFile ~/.ssh/step2key
  ForwardAgent yes
  ForwardX11 yes
  ServerAliveInterval 300
  ForwardX11Timeout 596h
  ControlMaster auto
  ControlPath ~/.ssh/mux-%C
  ControlPersist 10

Host step3
  HostName step3.jp
  User username3
  ProxyCommand ssh -W %h:%p step2
  IdentityFile ~/.ssh/step3key
  ForwardAgent yes
  ForwardX11 yes
  ServerAliveInterval 300
  ForwardX11Timeout 596h
  ControlMaster auto
  ControlPath ~/.ssh/mux-%C
  ControlPersist 10

Host step4
  HostName step4.jp
  User username4
  ProxyCommand ssh -W %h:%p step3
  IdentityFile ~/.ssh/step4key
  ForwardAgent yes
  ForwardX11 yes
  ServerAliveInterval 300
  ForwardX11Timeout 596h
  ControlMaster auto
  ControlPath ~/.ssh/mux-%C
  ControlPersist 10
```

step1に公開鍵配置。

```
ssh-copy-id -i step1key.pub step1
```
まだ鍵置いてないので最初はパス聞かれます。

同様にstep2,step3,step4と置いていく。

```
ssh-copy-id -i step2key.pub step2
```
```
ssh-copy-id -i step3key.pub step3
```
```
ssh-copy-id -i step4key.pub step4
```

ssh-copy-idが使えない場合はこれで代用。

```
cat step1key.pub | ssh username1@step1 "mkdir -p ~/.ssh; cat >> ~/.ssh/authorized_keys"
```

設定完了。

```
ssh step4
```
これで4段目に入れます。
便利すぎてもう仕事終わった気分。

# 鍵認証されない時
## permissionを疑う
~/.ssh は 700
~/.ssh/authorized_keys は 644
~/.ssh/秘密鍵 は 600
/home/username は 755
## /etc/ssh/sshd_config の「ForwardX11 no」になってない？
設定変更してsshd再起動。できない場合、管理者に頼む。駄目なら諦めてローカルからはコマンド2発になるけどそこから鍵認証設定する。


# 参考URL

ssh-keygenをパスフレーズの確認なしで作成する
https://qiita.com/genreh/items/acfa49f569f665c8f024

SSH keyを4096bitで作成する
https://qiita.com/hietahappousai/items/a7fae4838e510136fc08

Wokashi: サーバに新たなSSH公開鍵を追加する
http://mironal-memo.blogspot.com/2012/07/ssh.html

多段sshを行うときに、ローカルの秘密鍵を参照し続ける
https://qiita.com/himo/items/5eb833ad757bd8b3e6c3

ProxyCommandによるsshの多段接続について -- ぺけみさお
https://www.xmisao.com/2013/10/08/ssh-proxy-command.html

Fix unix_listener too long for Unix domain socket
https://gist.github.com/andyvanee/bcf95b1044b80e72b4a42933549a079b

OpenSSHのセッションを束ねるControlMasterの使いにくい部分はControlPersistで解決できる - Dマイナー志向
http://d.hatena.ne.jp/tmatsuu/20120707/1341677472

SSH 多段接続で三段先のサーバに接続する - らくがきちょう
http://sig9.hatenablog.com/entry/2016/07/05/230000
[React Nativeレイアウト覚書] flexとwidth/heightの適用優先度を確認

# 1.普通のflex

```
<View style={{backgroundColor: 'red', width: 100, height: 100}}>
  <View style={{backgroundColor: 'blue', flex: 1}}/>
</View>
```

背景redである親要素の内側を背景blueの要素で満たす
<img width="79" alt="スクリーンショット 2018-11-01 14.28.23.png" src="https://qiita-image-store.s3.amazonaws.com/0/39330/344ef0b5-54fd-6aea-3509-c3dbd88e87fe.png">


# 2.width, heightを加える

```
<View style={{backgroundColor: 'red', width: 100, height: 100}}>
  <View style={{backgroundColor: 'blue', flex: 1, width: 50, height: 50}}/>
</View>
```

値を指定したwidthは効くが、heightは効かず、flexが有効となりストレッチする。これは親要素のflexDirection(デフォルトcolumn)が関係している。
 => 次で説明
<img width="67" alt="スクリーンショット 2018-11-01 14.31.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/39330/28606af7-6a49-e2a9-ee06-e705cd20fb1a.png">


# 3.flexDirectionを変更する

```
<View style={{backgroundColor: 'red', width: 100, height: 100, flexDirection: 'row'}}>
  <View style={{backgroundColor: 'blue', flex: 1, width: 50, height: 50}}/>
</View>
```

2とはwidthとheightの効きが逆転する。
これは子要素のflex=1が親要素のflexDirectionの向きに対してストレッチするため。
<img width="69" alt="スクリーンショット 2018-11-01 14.33.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/39330/2b6d6731-59fa-6e2a-0a06-a24dba136ce0.png">
プログラミング独学者がkaggleで自立するための第一歩〜ランダムフォレストを学ぶ〜

# kaggleとは
　データサイエンティストと企業や政府を繋ぐコンペサイトです。
　データ解析の正答率をスコアとして参加者同士でスコアの高さを競い合います。
　企業から出されたテーマに対して上位入賞者に賞金と引き換え（！）にデータセットを買い取るという意欲的な仕組みです。

# なぜkaggleで学ぶのか
　私の現職は通常のPGとは違って少し特殊で、小中学向けプログラミング教育の講師を勤める傍ら、数学・現代文の講師と内製アプリケーション専門のPGをやっております。
　なので経験値をアピールする機会がとても少ない……という悲しい事態に直面しておりその対策として何か実力を証明できるものはないだろうかというものを探している中でkaggleを見つけました。
　ちょうど社内でマーケティングの役割が必要なのではないかと話をしていたところだったのでいい機会だということでkaggleを始めました。
　様々なバックグラウンドを持っている人間でも自由に出入り出来、また、データサイエンスの世界ではある程度の市民権があることもkaggleのいいところだと思います。

# 第一歩
・第一歩の手順は以下の二つです
① ランダムフォレストを学ぶ
今回はこの内容を学びました。
https://www.codexa.net/kaggle-mercari-price-suggestion-challenge/

### 開発環境
MacOS v10.13.6

### 行程
#####1.開発環境を整える
Kaggleのカーネルを利用し、直接書いていきました。

#####2.参考サイトの手順に沿って学習を始める
今回はランダムフォレストを用いて機械学習を行なっていたのでここではランダムフォレストの概要を簡単に説明したいと思います。

ランダムフォレストとは……
決定木を複数組み合わせ、各決定木の予測結果を多数決することによって結果を得る。

以下にアルゴリズムを示します。
1.ランダムにデータを抽出する
2.決定木を成長させる
3.1と2のステップを繰り返す
予測結果を多数決することによって分類閾値を決定する。

決定木を複数個作る必要があるのでどうしてもデータ量が必要なので使いどころが限られそうです。

#####【参考サイトの概略】
●データセットの確認
・CSVを読み込んで内容を確認する
・元データ と testデータ の簡単な統計情報とサイズも確認する
・pandasのdescribe()を使って各データセットの基本統計量も確認する
・データタイプを文字列からCategoryに変更する
・ユニーク値の確認
・データセットの欠損の確認する
●データセットの事前処理
・trainとtestのデータを連結させる
・連結させたDataFrameの文字列のデータ形式を「cateogry」へ変換
・文字列を数値へ値を変換
・訓練用データの「price」をnp.log()で処理
・ランダムフォレスト用にxとy（ターゲット）で分ける
●アルゴリズムにデータを流し込む
・決定したアルゴリズムにデータを流し込む

3.完成
お疲れ様でした。

# まとめ
データセットの確認は前回とほぼ変わらずだったのでここはデータサイエンスをやるにあたってのルーティン的な内容になるのでしょう。
今回はアルゴリズムにランダムフォレストを使いましたが重要なのはどのタイミングでどのアルゴリズムを利用すべきかを考えておくことだと思っています。前回のタイタニックの時はデータ数が少なく、ランダムフォレストを使用することは難しいところがあったのでしょう。
使用されるアルゴリズムの幅というのはその時々で変わりそうです。であればどのタイミングでどのアルゴリズムを利用すべきかというのは非常に重要な問題だと考えられます。

なのでもう少し機械学習の手順を学んだ後にアルゴリズムチートシートの学習に移りたいと思います。
jsで要素の高さとか計算する処理をテスタブルに書くとどうなるだろうか

# jsで要素の高さを計算する処理を純粋関数型っぽく書きたいとき

## 普通に書くならこう

```javascript
const calculateHogeSize = () => {
  return $('.js-hoge').innerHeight() - ($('.js-foo').innerHeight() + $('.js-fuga').innerHeight() + parseInt($('.js-bar').css('margin-top')) + 50);
};

$(window).on('resize', () => {
   const hogeSize = calculateHogeSize();
   $('.js-target').css({height: hogeSize});
});
```

## テスタブルに書くならこう？

```javascript
const calculateHogeSize = (hogeSize, fooSize, fugaSize, barMargin) => {
  return hogeSize - (fooSize + fugaSize + barMargin + 50);
};

$(window).on('resize', () => {
  const hogeSize = $('.js-hoge').innerHeight();
  const fooSize = $('.js-foo').innerHeight();
  const fugaSize = $('.js-fuga').innerHeight();
  const barMargin = parseInt($('.js-bar').css('margin-top'));

  const hogeSize = calculateHogeSize(hogeSize, fooSize, fugaSize, barMargin);
  $('.js-target').css({height: hogeSize});
});
```

## 意図したこと

`calculateHogeSize`関数をテストしやすい
複数ファイルをファイル単位にgrepでフィルタしてwcで行数を数える

ただ合計を数えるだけではなくて、ヒストグラムを作りたいときとか、各ファイルの行数を数えたい場合で、かつ、grepでフィルタもしたいとき。たとえば、特定のIPアドレスを除外してアクセスログの行数を数えるとか。

```shell
$ find . | xargs wc
```

すぐに思いつくのはこれです。これでファイルごとの行数が数えられますが、grep条件は加味されていない数値です。

```shell
$ find . | xargs grep -v 'xxx' | wc
```

これにgrepをつけると、フィルタ条件を満たすのですが、数値は合計だけになってしまい、ファイルごとの数値がわかりません。

両立させる方法はこんな感じです。

```shell
$ find . | xargs -n 1 sh -c 'echo -n $0; grep -v "xxx" $0 | wc'
```

xargsの出力をいったんShellに渡すことで、複数のコマンドを並列できるようになります。前半でファイル名を表示して、後半で集計しています。

xargsのnオプションでの1指定は、入力を1個ずつ渡すって宣言です。渡されたものはShellなので$0とかで受け取ります。-I{}でも同じことができます。

echoのnオプションは改行しないってものです。
CollectionViewのcellとview.xibのサイズを一致させたい

# xibファイルのViewをCellにフィットさせよう
以下の画像のFollow Readable Widthにチェックマークを入れる．これだけ．

![スクリーンショット 2018-11-01 14.20.35.png](https://qiita-image-store.s3.amazonaws.com/0/241421/c87fcd97-22a1-4d3f-9fe9-a3682675b3ed.png)
pytorch/accimageで高速に画像読み込み

## はじめに
PyTorchの公開しているRepositoryの中にaccimageという高速に画像を読み込むためのライブラリがあります．torchvisionのDatasetクラスの中でもaccimageが使えるなら使うようになっているので，accimageをインストールすることで画像読み込みを高速化することができます．画像データを使う場合は読み込み速度はそこまで問題にならないかもしれませんが，動画を扱うときには読み込みがボトルネックになることが割とあるのでここが速くなると嬉しいんです．

意外とaccimageを使い方やどのくらい速くなるのかの情報が見つからなかったので，自分で試してみました．

## accimageのインストール

accimageのRepositoryはこちら．https://github.com/pytorch/accimage
事前にIPPをインストールしておいてから，```python setup.py install --user```とすればいいようです．

IPPなどのインストールもanacondaで簡単にやりたかったので，forkしてRepositoryを作りました．
https://github.com/kenshohara/accimage
必要なものはipp-develとlibjpeg-turboでした．

```
conda install ipp-devel -c intel
conda install libjpeg-turbo -c conda-forge
```

あとはsetup.pyの中でanacondaでインストールしたライブラリを探しに行くように少しだけ変更しました．
```anaconda_dir```を手動で設定するという適当なやり方ですが，とりあえずこれでインストールできます．

```
# modify anaconda_dir in setup.py
python setup.py install --user
```

## 読み込み速度の比較

### accimage
#### 使用コード

```
%%time

% import accimage

for i in range(n_iter):
    x = accimage.Image(file_path)
```

#### 結果

313x234, 15KBの画像，n_iter=1000
CPU times: user 644 ms, sys: 38.6 ms, total: 682 ms
Wall time: 686 ms

5120x2880, 502KBの画像，n_iter=10
CPU times: user 1.21 s, sys: 94.9 ms, total: 1.31 s
Wall time: 1.31 s

### PIL

#### 使用コード

```
%%time

% from PIL import Image

for i in range(n_iter):
    with open(file_path, 'rb') as f:
        with Image.open(f) as img:
            x = img.convert('RGB')
```

#### 結果

313x234, 15KBの画像，n_iter=1000
CPU times: user 2.6 s, sys: 60.6 ms, total: 2.67 s
Wall time: 2.68 s

5120x2880, 502KBの画像，n_iter=10
CPU times: user 4.23 s, sys: 201 ms, total: 4.43 s
Wall time: 4.45 s

### OpenCV

#### 使用コード

```
%%time

% import cv2

for i in range(n_iter):
    x = cv2.imread(file_path)
```

#### 結果

313x234, 15KBの画像，n_iter=1000
CPU times: user 2.73 s, sys: 105 ms, total: 2.83 s
Wall time: 2.85 s

5120x2880, 502KBの画像，n_iter=10
CPU times: user 4.24 s, sys: 132 ms, total: 4.37 s
Wall time: 4.39 s

### 比較まとめ

Wall Timeで比較

||accimage|PIL|OpenCV|
|---|---|---|---|
|小画像 * 1000回|0.69s|2.68s|2.85s|
|大画像 * 10回  |1.31s|4.45s|4.39s|

## まとめ

accimage使うとやっぱりjpg読み込みが速いですね，という結果でした．動画認識だと1サンプル16フレーム，バッチサイズ128とかで学習を回したりするので，読み込みが速いくなると嬉しいです．PyTorchのDataLoader使ってマルチスレッドで読込みすればそこまで問題にはならないんですが，速いに越したことはないですね．

今回は純粋に読み込み部分の速度比較だけしましたが，データ読み込み時にはaccimageもしくはPILのImageからTensorに変換する作業も入ってきます．torchvisionのToTensorの実装を見るとPILの場合はtransposeする必要があり，そこに読み込み処理の80%の時間がかかっているようです．もしtorchvisionでaccimageを使う場合，そのtransposeをスキップすることで今回の検証以上に速くなるかもしれません．
Integerとintの等値判定


 ・オフジェクトの等値判定は==ではなくequalsを使用する.等値判定が必要なクラスにはequalsが定義してある(はず).

 ・Stringの等値判定を==で行っているプログラムを見ることがあるが、見ていると貧血になりそうである。一応デバッグが通っている。これが動作する理由は、代入で回していればtrueとなるから.

 ・Integerでも同じだが、プリミティブ(int)があるので、少しだけ複雑になる.

 ・常識的なことも含めて確認してみる.

 ・結果として注意しなければならないのはInteger同士の等値判定で==を使用した場合.等値判定の時に対象の変数がIntegerかintかを一々確認したりはしない.そして大部分では==が使われる.これは危険....

 ・だがしかし、両方ともIntegerであるという確率は非常に少ないと思われる.よかった、よかった.


```Tips0048.java
package jp.avaj.lib.algo;

import jp.avaj.lib.test.ArTest;
import jp.avaj.lib.test.L;

public class Tips0048 {
  public static void main(String[] args) {
    // テストケースを開始する
    ArTest.startTestCase("Tips0048");

    L.p("\n==== IntegerとIntegerの等値判定");
    {
      Integer i0 = new Integer(5);
      Integer i1 = i0;
      Integer i2 = new Integer(5);
      //
      // これは代入なのでtrueとなる.
      ArTest.isTrue("i0 vs i1","result",(i0 == i1));

      // これはfalse ⇒ ★これだけが危ない
      ArTest.isFalse("i0 vs i2","result",(i0 == i2));
    }
    L.p("\n==== Integerとintの等値判定");
    {
      Integer integer = new Integer(5);
      int int0 = 5;
      //
      // equalsによる判定
      ArTest.isTrue("Integer.equals(int)","result",integer.equals(int0));
      // == による判定
      ArTest.isTrue("Integer == int","result",integer == int0);
    }
    L.p("\n==== intとintの等値判定 ⇒ 省略");
    //
    L.p("\n==== IntegerとIntegerの大小判定");
    {
      Integer integer0 = new Integer(5);
      Integer integer1 = new Integer(4);
      ArTest.isTrue("Integer > Integer","result",integer0 > integer1);
    }
    L.p("\n==== Integerとintの大小判定");
    {
      Integer integer0 = new Integer(5);
      ArTest.isTrue("Integer > int","result",integer0 > 4);
    }
    L.p("\n==== intとintの大小判定 ⇒ 省略");


    L.p("\n==== 番外");
    // これら両方ともfalse。当たり前とは言え、非常に違和感がある。
    L.p((new Integer(1)).equals(new Long(1))+"");
    L.p(((new Boolean(true)) == (new Boolean(true)))+"");

    L.p("");
    // テストケースを終了する
    ArTest.endTestCase();
  }
}
```
実行結果は次のとおり。

```Tips0048-result
**** Tips0048 start ****

==== IntegerとIntegerの等値判定
OK i0 vs i1:result=true
OK i0 vs i2:result=false

==== Integerとintの等値判定
OK Integer.equals(int):result=true
OK Integer == int:result=true

==== intとintの等値判定 ⇒ 省略

==== IntegerとIntegerの大小判定
OK Integer > Integer:result=true

==== Integerとintの大小判定
OK Integer > int:result=true

==== intとintの大小判定 ⇒ 省略

==== 番外
false
false

**** Tips0048 summary ****
test count = 6
success    = 6

```