OmniAICreator/Qiita-1.07M huggingface dataset:
Maxwellを使ってMySQLのバイナリログをJSON形式で出力する

Maxwellを利用し、MySQL／Auroraのバイナリログ（binlog）を読み込み、JSON形式で出力することが可能です。

#Maxwellのダウンロード
以下のサイトからMaxwellをダウンロードできます。
https://github.com/zendesk/maxwell/releases/download/v1.10.8/maxwell-1.10.8.tar.gz

```bash
$ curl -sLo - https://github.com/zendesk/maxwell/releases/download/v1.10.8/maxwell-1.10.8.tar.gz | tar zxvf -
```

#MySQL/Aurora側の設定
１．バイナリログ形式を「ROW」（行に基づくロギング）に変更する。

```bash
$ vi my.cnf

[mysqld]
server-id=1
log-bin=master
binlog_format=row
```

RDSを利用する場合、パラメータグループを変更します。
![2017-10-22_124048.jpg](https://qiita-image-store.s3.amazonaws.com/0/123138/5cef38ff-bd1d-83a7-d335-9447841e6b6a.jpeg)

２．MySQL/AuroraにてMaxwellユーザを作成し、権限を付与します。

```bash
mysql> CREATE USER 'maxwell' identified by 'password';
mysql> GRANT SELECT, REPLICATION CLIENT, REPLICATION SLAVE on *.* to 'maxwell' identified by 'password';
mysql> GRANT ALL on maxwell.* to 'maxwell';
```
#Maxwellの起動
以下のコマンドを利用し、STDOUT（標準出力）モードでMaxwellを起動します。

```bash
$ cd maxwell-1.10.8
$ bin/maxwell --user='maxwell' --password='password' --host='xxxxxxxx.rds.amazonaws.com' --producer=stdout
```

#JSON形式binlogの出力
動作確認としてMySQL側以下のSQLを発行します。

```bash
mysql> INSERT INTO user_info VALUES (0, 'admin', 'password', 'admin@myApp.com');
Query OK, 1 row affected (0.01 sec)

mysql> update user_info set username='user', email='user@myApp.com';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> delete from user_info;
Query OK, 1 row affected (0.01 sec)
```
以下のJSONが出力されます。

```json
{"database":"test_db","table":"user_info","type":"insert","ts":1508315079,"xid":929,"commit":true,"data":{"id":0,"username":"admin","password":"password","email":"admin@myApp.com"}}
{"database":"test_db","table":"user_info","type":"update","ts":1508315160,"xid":1012,"commit":true,"data":{"id":0,"username":"user","password":"password","email":"user@myApp.com"},"old":{"username":"admin","email":"admin@myApp.com"}}
{"database":"test_db","table":"user_info","type":"delete","ts":1508315171,"xid":1018,"commit":true,"data":{"id":0,"username":"user","password":"password","email":"user@myApp.com"}}
```

#引用
http://maxwells-daemon.io/quickstart/
vimのカラースキームに「molokai」を設定する

# はじめに
vimのカラースキーマを`molokai`に設定する手順です。忘れることが多いので手順にしました。

# 前提条件
 - `git`コマンドが利用できること

# 手順
githubからmolokaiを取得する。

```
[root@ca035c198d1f ~]# git clone https://github.com/tomasr/molokai.git molokai
Cloning into 'molokai'...
remote: Counting objects: 148, done.
remote: Total 148 (delta 0), reused 0 (delta 0), pack-reused 148
Receiving objects: 100% (148/148), 26.92 KiB | 0 bytes/s, done.
Resolving deltas: 100% (35/35), done.
```

**molokai**ディレクトリを**.vim**に変更する。

```
[root@ca035c198d1f ~]# mv molokai/ .vim
[root@ca035c198d1f ~]# ll -a
total 64
dr-xr-x--- 1 root root 4096 Oct 22 02:56 .
drwxr-xr-x 1 root root 4096 Oct 17 13:04 ..
-rw------- 1 root root 1513 Oct 17 15:07 .bash_history
-rw-r--r-- 1 root root   18 Dec 29  2013 .bash_logout
-rw-r--r-- 1 root root  176 Dec 29  2013 .bash_profile
-rw-r--r-- 1 root root  176 Dec 29  2013 .bashrc
-rw-r--r-- 1 root root  100 Dec 29  2013 .cshrc
drwxr----- 3 root root 4096 Oct 22 02:54 .pki
-rw-r--r-- 1 root root  129 Dec 29  2013 .tcshrc
drwxr-xr-x 4 root root 4096 Oct 22 02:54 .vim
-rw------- 1 root root 6221 Oct 21 09:32 .viminfo
-rw-r--r-- 1 root root   86 Oct 19 13:30 .vimrc
-rw------- 1 root root 3407 Sep 11 15:53 anaconda-ks.cfg
-rw------- 1 root root 3221 Sep 11 15:53 original-ks.cfg
drwxr-xr-x 3 root root 4096 Oct 21 09:32 work
```

**.vimrc**にカラースキーマを設定する。.vimrcは、ホームディレクトリにあります。.vimrcがない場合は作成してください。

```
1 syntax on
2 colorscheme molokai
3
4 set number
5 set cursorline
6 set showmatch
7 set laststatus=2
8
9 set expandtab
10 set tabstop=2
```

余計な設定まで入っていますが、1行目と2行目のみで問題ないです。

## 追記
カラースキーマの設定方法についてご指摘をいただきましたので、カラースキーマの設定方法について追記いたします。

gitから取得したディレクトリ(今回は、molokai)を.vimにリネームしていますが、ディレクトリを修正せずに、.vimrcに`runtimepath`を追加することで設定を反映することが可能です。

`runtimepath`については、以下に詳細があります。
[runtimepath](http://vim-jp.org/vimdoc-ja/options.html#'runtimepath')

```
  1 set runtimepath+=~/molokai
  2
  3 syntax on
  4 colorscheme molokai
  5 以下、省略
```
Firebaseの基本：ウェブページからDBの値を読む

# これは何？
Firebaseをウェブから使う基本です。何度もやってる気はするのですが、毎回忘れる（正確には更新が頻繁だから追いつけていない？）のでこの機会に書いておきます。

# 参考にしたサイト
- YouTube: [Getting Started with Firebase on the Web - Firecasts](https://www.youtube.com/watch?v=k1D0_wFlXgo&t=77s)
- Document: [Installation & Setup in JavaScript](https://firebase.google.com/docs/database/web/start)

# 実装
## Firebase側の設定
### Databaseへの読み書きの指定
お試しなので、設定はズバリ**ザル**！
<img width="600" alt="Screen Shot 2017-10-21 at 8.25.46 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/61221/7b9b7f06-f115-db4b-c7fa-256f9033c007.png">

### Databaseの定義
1つだけカラムを作成。`text`という名前で`Hello Firebase!!`と記入して、青色の「ADD」ボタンを押して追加します。お約束ですね🙂
<img width="600" alt="Screen Shot 2017-10-21 at 8.29.55 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/61221/0cda4b50-e29a-1b57-0eaf-eae7cf0f1299.png">

### HTMLとJavaScript
以下のコードをローカルでよいのでウェブサーバで動かします。サンプルではユーザ固有のキー等は別ファイル `key.js` に書き込んでいます。よってこのコードには含まれていませんのでご注意ください。

````Html
<!DOCTYPE html>
<html>
  <head>
    <meat charset="utf-8" />
    <title>Getting Started with Firebase on the Web</title>
  </head>
  <body>
    <h1 id="bigOne"></h1>
    <script src="./keys.js"></script> <!-- 別ファイルに保存しました -->
    <script src="https://www.gstatic.com/firebasejs/4.6.0/firebase-app.js"></script>
    <script src="https://www.gstatic.com/firebasejs/4.6.0/firebase-messaging.js"></script>

    <script src="https://www.gstatic.com/firebasejs/4.6.0/firebase.js"></script>

    <script type="text/javascript">
     firebase.initializeApp(config);

     let bigOne = document.querySelector('#bigOne');
     let dbRef = firebase.database().ref().child('text');
     dbRef.on('value', (snap) => bigOne.innerText = snap.val() );
    </script>
  </body>
</html>
````
### ユーザ固有のキー等の調べ方
左ペインのメニューのトップにある[Overview]をクリクして、「Add Firebase to your web app」という画面右側の赤丸で囲われた「**</>**」をクリックすると表示されます。（表示方法は他にもいくつかあります）
<img width="600" alt="Screen Shot 2017-10-21 at 8.35.58 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/61221/0087fda8-bdbe-8997-c696-1f8352e47a5d.png">

## ユーザ固有のキー等の画面
これをコピーして「HTMLとJavaScript」の先頭辺りに貼り付ければよいです。
<img width="600" alt="Screen Shot 2017-10-21 at 8.38.06 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/61221/71d25982-bbab-0d5d-ec98-60b68aa471d2.png">

# 動作させてみる
## 画面
非常にシュール・・・
<img width="600" alt="Screen Shot 2017-10-21 at 8.46.58 PM.png" src="https://qiita-image-store.s3.amazonaws.com/0/61221/e259d6b8-7501-722e-67d7-eaef258c74b2.png">

## せっかくなのでリアルタイムを体感する
左側がFirebaseで右側がブラウザ表示させた先程のHTMLとJavaScriptのページです。
![Oct-21-2017 20-56-26.gif](https://qiita-image-store.s3.amazonaws.com/0/61221/3b38959e-e00a-c601-853e-ed7912e3b35e.gif)

## サーバに関して
`firebase serve`
を使って動かしました。
[この辺り](https://firebase.google.com/docs/functions/local-emulator)に設定方法あり。

# まとめ
とても簡単にリアルタイムなデータベースができてしまいました👍
Vimのカーソル移動を10倍速くする


## これを設定ファイルに書くだけ！
設定ファイルは自分で特に何も変えてなければ`~/.vimrc`にあるはず。
なくても作れば勝手に読まれるはず。

```vim
nnoremap <S-k> 10<UP>
nnoremap <S-j> 10<DOWN>
nnoremap <S-h> 10<LEFT>
nnoremap <S-l> 10<RIGHT>

vnoremap <S-k> 10<UP>
vnoremap <S-j> 10<DOWN>
vnoremap <S-h> 10<LEFT>
vnoremap <S-l> 10<RIGHT>
```

これを反映してカーソル移動を`h`, `j`, `k`, `l`ではなくて`H`, `J`, `K`, `L`で行うと、**カーソルがいつもの10倍動きます！！**

![15085980506lzwCv0EmkoWHCi1508597909.gif](https://qiita-image-store.s3.amazonaws.com/0/113398/2a7c6658-e28e-a9aa-c6e3-5526e71a0851.gif)

## 以下蛇足
### 設定内容
`nmap`は`normal`モードの、`vmap`は`visual`モードのキー設定を示していて、`<S-k>`は`shift + k`を意味しています。
`<UP>`はカーソルを上に動かすことを意味していて、vim は数字を付けるとその回数分繰り返されるので`10<UP>`でカーソルが 10 動きます。

設定ファイルを書かなくても、普通に vim を起動して`normal`モードで`15j`とかやれば下に 15 カーソルが動きます。
それだけです。

### これの強力さ
少し意識して vim を使う様にすると、案外１単語足したい消したいとか`()`の中だけ消したいとかが自然と出来る様になります。

例えば本当によくある操作として

+ `public void foo(...`に`static`を入れて`public static void foo(...`にしたい
+ `String foo(String x)`の引数を消して`String foo()`にしたい

とかがあります。

これって一例ですけど

+ `public`のどこでも良いからカーソルを乗せる -> `e`と押すとカーソルが`public`の`c`の部分に行く -> `a`でカーソルの右に字を書く（つまり`e`, `a`）
+ `void`のどこでも良いからカーソルを乗せる -> `b`と押すとカーソルが`void`の`v`の部分に行く -> `i`でカーソルの左に字を書く（つまり`b`, `i`）
+ `(String x)`のうちカーソルをとりあえず`()`の中に移動する -> `di(`で括弧の中を全部消す

みたいな操作でスカっと出来ちゃいます。本当です。

vim は単語や括弧の中身を扱ったり最寄りの半角スペースまで云々とかがものすごい得意なので、カーソルは割と雑に合わせても処理の起点として全然問題にならないからです。

### なんで 10 か
いろいろ試してそうなっただけ。

ただ横移動は上にあるようにテキトーに単語に乗れば良いので、5 だとちょっと足りなかった。
イメージとしては`xxxxxxx yyyyyyy zzzzzzz`で先頭から`L`, `L`として全単語に１度ずつ乗るくらいにしたかった。

上下移動は 4 行くらいなら目測でわかるから`4k`とか出来るし、それよりパッと見大きければ`K`して`jjj`とかすれば良い。

だから上下とも 10 が丁度良かった。

### 本来の`H`, `J`, `K`, `L`
本来のコマンドを潰してることになるので一応ふわっと解説。
ちなみに`tab h H`とかやるとマニュアル開くよ。

+ `H` -> カーソルが vim に映ってる範囲の一番上に行く感じ
+ `J` -> カーソル行の改行を無くして下の行と連結する感じ
+ `K` -> マニュアルを開く感じ
+ `L` -> カーソルが vim に映ってる範囲の一番下に行く感じ

個人的には全部潰して良いので問題なし
arduinoでVGA

#概要
arduinoでVGAやってみた。
VGAの調査してみた。

#VGA
Video Graphics Array（ビデオ グラフィックス アレイ、VGA）は、IBMが1987年に発表した表示回路規格である。
IBMのパーソナルコンピューターであるIBM PS/2に初めて搭載された。
代表的な表示モードに 640×480 ピクセル・16色がある。

#仕組み

![crt.PNG](https://qiita-image-store.s3.amazonaws.com/0/18104/c3a23c89-18ba-11fa-8ddb-b225970938d1.png)


CRTディスプレイは、電子ビームで左上から1ラインずつ描画していきます。右端まで描いたら、左に戻ります。この時はビームを消します。次のラインを描きます。それを繰り返し、最後のラインを描画したら、左上に戻ります。右端は、Hsyncで、終端は、Vsyncで判断します。

#タイミング
水平同期周波数は、31.469kHz固定。
640x480ドットで考えると、

水平フロントポーチ 16パルス
水平同期パルス長 96パルス
水平バックポーチ 48パルス
アクティブピクセル 640パルス
合計800パルス
ピクセルクロック周波数は、
31.469kHz ×　800　＝　25.1752MHz

16MHzのarduinoでは、無理。

垂直フロントポーチ 10パルス
垂直同期パルス長 2パルス
垂直バックポーチ 33パルス
アクティブピクセル 480パルス
合計525パルス
垂直周波数は、
31.469kHz ÷　525　＝　59.941Hz

#結論
320x240辺りが、狙い目。

以上
クラス内のPromiseでundefined

## 問題
サンプル

```js
class Sample {
    constructor() {
        this.some = 10;
    }

    Start() {
        Promise.resolve()
        .then(this.TaskA)
        .then(this.TaskB)
        .then(this.TaskC)
        .catch((e) => console.log(e));
    }

    TaskA() {
        return new Promise((resolve, reject) => {
            resolve(Math.random());
        });
    }

    TaskB(number) {
        return new Promise((resolve, reject) => {
            resolve(this.some * number);
        });
    }

    TaskC(number) {
        return new Promise((resolve, reject) => {
            console.log(number);
            resolve();
        });
    }
}

const s = new Sample();
s.Start();

```

`TypeError: Cannot read property 'some' of undefined` とかなる。thisが参照できてないのでメンバ変数が見えてない。

## 解決
https://stackoverflow.com/questions/35481367/the-this-object-is-undefined-when-using-promise を参考に解決すると

```js
    Start() {
        Promise.resolve()
        .then(this.TaskA)
        .then(this.TaskB.bind(this))
        .then(this.TaskC)
        .catch((e) => console.log(e));
    }

```

this参照したい箇所はbindでthisを束縛する。answer内の `Promise.bind(this)` でやってみる方は解決しなかった。  
Typescriptで記述してるときは、 `Promise.bind(this)` で始めたとしてもメソッドの方は関数型の変数に変えると動いた。

```js
TaskB = (number) => {
	return new Promise((resolve, reject) => {
    	resolve(this.some * number);
    });
}
```
SQLAlchemy+PyMySQLを使おうとしたらSHOW VARIABLES LIKE ‘sql_mode'でエラー

SQLAlchemyからPyMySQLを使ってMySQL操作をしようしたらエラーが出て動かなかったのでメモ

以下の記事を参考に(というかほぼそのまんま)PyMySQLとSQLAlchemyをインストールして、コードを書いて実行してみましたがエラー
[SQLAlchemy + MySQL を使ってみる（その１）](https://qiita.com/nskydiving/items/88377d57040db17281fe)


エラーメッセージをよく見てみると以下のSQLでエラーが出てるみたい
`SHOW VARIABLES LIKE ‘sql_mode'`

実際にMySQLにログインして同じSQLを打ってもエラーが起きるので調べてみると以下がヒット
[mysql Table 'performance_schema.session_variables' doesn't existのエラー](https://qiita.com/_am_/items/032a08aca07f06e81c8b)
書いてある通りに実行してみる

```
mysql_upgrade -u root -p --force

mysql.server restart
```

これで再度実行すると、ちゃんとMySQLからデータを取ってくることが出来ました
【ブクマ】ユーザーアカウント制御 (UAC)

# 🔖1

> ユーザーアカウント制御 (UAC; User Account Control) は、Windows Vista以降より導入されたセキュリティの基盤となる技術である。許可のない限りアプリケーションを標準ユーザーの権限で動かすことで、不用意にマルウェアなどがオペレーティングシステム (OS) に変更を加えられないようにする狙いがある。

[ユーザーアカウント制御 - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E5%88%B6%E5%BE%A1)

# 🔖2

> 管理者権限の利用を制限する機能

> たとえAdministratorsグループやDomain Adminsグループに所属するアカウントでログオンしていても、UACによる確認ダイアログに明示的に同意しないと、管理者権限が利用できない

[Windows OS入門：第7回　特権的な操作を制限するUAC（ユーザーアクセス制御） (1/2) - ＠IT](http://www.atmarkit.co.jp/ait/articles/1503/19/news131.html)

# 🔖3

> sudo と同じようなシステムに Windows の UAC (User access control)があります。
> よく sudo = UAC みたいな誤解が多いのですが、ユーザビリティも実際の実装も全く異なります。 

> まず、UACの場合は「認証する」というモデルではありません。
> あくまでも「これから行う作業はシステムに重大な影響を及ぼしますがよろしいですか?」の Yes/No クエスチョンにすぎません。(ユーザがAdministrationグループにいないときにはパスワードを聞きますが..)
> そもそも、一般ユーザが重大な操作を及ぼすようなコンテクストで「認証操作」しかも「自分のパスワードを入力する」という手続きの意味付けが正しく理解できるとはあまり思えません。
> いっそ UAC のような Yes/No クエスチョンのほうが親切だし、直感的です。 

> Unixのセキュリティモデルは権限を「ユーザ」という単位で切り分けます。ですので、重大操作を行うには別のユーザ(主に root)にユーザを切り替える必要があります。
> 一方, UACは同じユーザ内での権限レベル(正確には integrity level, 整合性レベル) の変更です。重大な作業が必要なプロセスの時に、Yes/No クエスチョンで聞いた後にintegrity level high でプロセスを実行します。ユーザを変えないので、この操作はelevation(昇格)と呼ばれます。
> 実行権限の制御とユーザ認証を分離している点で Windows のセキュリティモデルの方が柔軟性があります。 

> 別のマルウェアが勝手に Yes ボタンをクリックしないように、UACダイアログはセキュリティ的に隔離された空間で実行させる必要があります。
> VistaのUACがブラックアウトしている理由は、視覚的な効果もありますが、別の隔離されたデスクトップを作りそこで実行させているからです。

[きまぐれ日記: sudo のGUIダイアログはセキュリティ的に大丈夫なのか?](http://chasen.org/~taku/blog/archives/2009/09/sudo_gui.html)

# 🔖4

> 「管理者に変身する？」って聞いてくる機能のこと

[ユーザアカウント制御 (UAC)とは｜「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典](http://wa3.i-3-i.info/word1159.html)

# 🔖5

* [ユーザー アカウント制御 (Windows 10) | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows/access-protection/user-account-control/user-account-control-overview)
* [ユーザー アカウント制御のしくみ | Microsoft Docs](https://docs.microsoft.com/ja-jp/windows-server/security/user-account-control/how-user-account-control-works)
vi bind

command mode
-------------
# 行移動
|コマンド|動作|覚え方？|
|:--|:--|:--|
|0|行先頭|数字の最初|
|^|行先頭|なんとなく？|
|$|行末端|なんとなく？|
|+|下行先頭|行を+方向に|
|-|上行先頭|行を-方向に|


# 画面移動
|コマンド|動作|覚え方？|
|:--|:--|:--|
|Ctl u|半画面上|up|
|Ctl d|半画面下|down|
|Ctl b|1画面上|back|
|Ctl f|1画面下|foword|
|gg|ファイル先頭|go back?|
|G|ファイル末端|go?|
|{|前段落|?|
|}|後段落|?|

# 単語移動
|コマンド|動作|覚え方？|
|:--|:--|:--|
|w|単語分移動|word|
|b|単語分戻る|back word|
|e|単語分移動。カーソルは末端|end word|
|ge|単語分戻る。カーソルは末端|end word?|
Visual Studio Code で PHPDebug を利用するために anyenv + phpenv で環境構築する手順


Visual Code Studio で PHPDebug を利用するには PHP7 を入れておく必要があるのですが、ローカルでバージョンを振り分けられるようにしたかったので anyenv からインストールしていこうと思ったらハードルが想定外に高かったのでまとめました。

## この記事で書かれていること
* anyenv から PHP7 をインストールするまでの流れ

## この記事で割愛されていること
* anyenvの説明
* phpenvの説明
* homebrewの説明、利用方法

Visual Studio Code でPHPコードのデバッグをするまでに必要な手順。

## anyenv
```
$ git clone https://github.com/riywo/anyenv ~/.anyenv
$ echo 'export PATH="$HOME/.anyenv/bin:$PATH"' >> ~/.your_profile
$ echo 'eval "$(anyenv init -)"' >> ~/.your_profile
$ exec $SHELL -l
```
## phpenv
```
$ anyenv install phpenv
```

注意点は、php-builidとphpenv-composerも一緒にインストールされること。場所は以下の通り。

```
~/.anyenv/envs/phpenv/plugins
```

インストールできるPHPバージョンを確認。

```
$ phpenv install --list
```

インストールするために必要なものを入れておく。

```
$ brew install openssl libxml2 mcrypt gcc re2c libmcrypt autoconf automake libiconv
```

ちゃんとインストールされているか確認。ここはopenssl、libxml2、mcryptを対象に。

```
$ echo -e "--with-openssl=$(brew --prefix openssl)\n--with-libxml-dir=$(brew --prefix libxml2)\n--with-mcrypt=$(brew --prefix mcrypt)"
--with-openssl=/usr/local/opt/openssl
--with-libxml-dir=/usr/local/opt/libxml2
--with-mcrypt=/usr/local/opt/mcrypt
```

https://qiita.com/kawakami-kazuyoshi/items/bd148312815fb75818ee

## rbenv

Ruby 2.3 が必要だと言われるのでインストール。ruby-buildも一緒にインストールされる。

```
$ anyenv install rbenv
$ exec $SHELL -l
$ rbenv install 2.3.5
```

## ビルドオプションを利用してphpenvからインストールしてみる

https://qiita.com/hnw/items/62380e713d318906f0cd

```
PHP_BUILD_CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl) --with-libxml-dir=$(brew --prefix libxml2)" PHP_BUILD_EXTRA_MAKE_ARGUMENTS=-j4 phpenv install 7.0.24
```
しかし以下のエラーでインストールできない。

```
ld: file not found: /usr/lib/system/libsystem_darwin.dylib for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
```

## Xcodeのバグらしい

以下の記事を参考にして対処。
https://qiita.com/mk2/items/932105d0633feb2f3d37

サンプルの10.12を10.13に変更して実行。

```
sudo /usr/bin/sed -i.backup -E -e 's@/usr/lib/system/libsystem_symptoms.dylib(, )?@@' \
$(grep -ril /usr/lib/system/libsystem_symptoms.dylib \
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/lib)
```
しかし改善せず。

さらに調べて参考を発見。こちらの対処方法を試してみる。
https://qiita.com/grohiro/items/a5f2ccd8a4c8ca8ac7d8

## 最終のphpenvによるインストールコマンド

すごいことになった。

```
$ PHP_BUILD_CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl) --with-libxml-dir=$(brew --prefix libxml2)" PHP_BUILD_EXTRA_MAKE_ARGUMENTS=-j4 LDFLAGS="-L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/system" phpenv install 7.0.24
```
コマンドを間違えるたびに美少女に罵られたい！

# コマンドを間違えるたびに美少女に罵られたい！

コマンドを間違えるたびに美少女に罵られてみたい、と誰しも思ったことはありませんか？
そんな長年の夢を叶えましょう！！！

# 結果

![k.png](https://static.katio.net/image/1f4d9b9a-81f9-4f68-78b4-0a646fba53ef.png)

罵ってくれました。

# 方法

## jp2aを導入する

任意のJPEG画像をアスキーアートにして表示してくれるパッケージです。
たぶん以下でインストールできます。

```bash
$ sudo apt install jp2a # for Debian,Ubuntu
$ brew install jp2a     # for MacOSX,Linuxbrew
```

## 画像を用意する

可愛い女の子の画像を用意しましょう。また、グレースケールにしておくと表示が綺麗になります。

## シェルにフックを登録する

コマンドを間違えたときに呼ばれる関数があるので、それを使いましょう。
jp2aを使い画像を表示し、その後にメッセージを表示します。

Bashの場合

```bash:bashrc
function command_not_found_handle(){
  if [ -e /usr/bin/jp2a ];then
    if [ -e ~/kirino.jpg ];then
      jp2a ~/kirino.jpg -i
    fi
  fi
  echo "ハァ…？$1とか何言ってんの？\nコマンドもろくに覚えられないなんて、アンタどうしようもないクズね。"
}
```

ZSHの場合

```bash:zshrc
function command_not_found_handler(){
  if [ -e /usr/bin/jp2a ];then
    if [ -e ~/kirino.jpg ];then
      jp2a ~/kirino.jpg -i
    fi
  fi
  echo "ハァ…？$1とか何言ってんの？\nコマンドもろくに覚えられないなんて、アンタどうしようもないクズね。"
}
```

---
fishの場合

@QUANON さんから、以下のようなコメントを頂きました！ありがとうございます！！

>僕は fish を使っているのですが、このシェルでも次の function を定義することで実現できました。

```sh
function command_not_found_handler --on-event fish_command_not_found
    if type -q jp2a; and test -e ~/kirino.jpg
        jp2a ~/kirino.jpg -i
    end

    echo ハァ…?$argv[1]とか何言ってんの?
    echo コマンドもろくに覚えられないなんて、アンタどうしようもないクズね。
end
```

bashとzshで'handle'と'handler'の違いがあるので注意です。また画像のパスは適宜変更してください。
また、jp2a自体のオプションを弄ることで、表示するときの行や列を指定することができます。
デフォルトでは、白に近い部分を表示させますが、ぼくの場合白黒にしてほとんど白となってしまい、見づらかったので、あえて黒の部分を表示させるために`-i`を付けています。

```bash
$ jp2a hoge.jpg --width=100 # 横幅を100列固定で表示
$ jp2a hoge.jpg --height=100 # 横幅を100列固定で表示
$ jp2a hoge.jpg -i # 白黒反転で表示
```

これで一通りの手順は完了です。

![k.png](https://static.katio.net/image/1f4d9b9a-81f9-4f68-78b4-0a646fba53ef.png)

# もっと高解像度で罵られたい。というかもう動画がいい。

そう思った方、とても良い考え方だと思います。同士です。
次は、アスキーアートだけではなく、本当の画像やgifアニメを表示させたいと思います。

### iTerm2.appの場合

> コメント欄にて、@kuzukuzu1gou さんがiTerm2でimgcatを使う方法を教えてくれました。

![k.png](https://static.katio.net/image/2e706e67.png)

jp2aの部分を、そのまま`imgcat`というコマンドに置き換えれば表示できます。

```bash
$ imgcat hoge.jpg
```

### xterm mltermの場合

img2sixelというパッケージを使えば、画像の表示や、gitアニメの再生ができます。

```bash
$ img2sixel hoge.jpg
$ img2sixel hoge.gif -l disable # -l disableを付けないとアニメがループしてプロンプトが帰ってこない
```

また、任意のyoutubeや動画ファイルをgitアニメにするには以下を参考にしてください。
[Linuxで、コマンドだけでyoutubeから動画をダウンロードして任意の時間を切り出してgitアニ化する](https://qiita.com/onokatio/items/40b12a2c50b4f9cc3e75)

![k.png](https://static.katio.net/image/7fbe3061-c702-8347-ccc5-eba72f469119.png)

![demo.gif](https://static.katio.net/image/e95b7085-6ebd-9a22-214b-d69ab05c5663.gif)


ゾクゾクしちゃいますね。
これで楽しいシェルライフを送りましょう！
DashでJava SE 11 日本語ドキュメントを利用する方法

![jdk11japanese.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8846/255614b0-715c-f226-7ac9-9beb4e559ae6.png)

macOSを使っている開発者ならきっとみんな使ってる便利なAPIビューア [Dash](https://kapeli.com/dash) でJava SE 11のドキュメントを見る方法を紹介します。

なお[Java APIドキュメントのライセンス](https://www.oracle.com/java/technologies/redistribution-policy.html)で、ドキュメントのインターネットでの再配布は許可されていないため、私がDash用Docsetの再配布をする予定はありません ( `The Java SE API Specification is not redistributable.` )。このためこの記事を最後まで読んでもご自身でdocsetを作成していただく手順の紹介だけで、ダウンロードリンクはないとを予めご了承ください。
ライセンスに `API specifications can be redistributed internally without special permission.` とあるので、作ったDocsetを他者に個人的に渡したりと、インターネットに誰でもアクセス可能な形で公開しなければよいようです)。

※ この記事は [Java SE 8日本語ドキュメントのDocset作成方法](http://mtgto.hatenablog.com/entry/2014/08/26/014246) のJava SE 11 版です。

# 手順

1. zip書庫になっているJava SE 11 ドキュメントをダウンロード
1. docsetを作成
1. Dashに取り込む

## 1. zip書庫になっているJava SE 11 ドキュメントをダウンロード

日本語版ドキュメントをダウンロードします。

http://www.oracle.com/technetwork/jp/java/java-sun-1440465-ja.html

執筆時点ではこのURLですが、将来変わっているかもしれません。

`Java Platform Standard Edition 11` のリンクをクリックしてzipをダウンロードします。

zipを展開すると `F12202_01` というフォルダが生成されます。

## 2. docsetを作成

次に日本語版ドキュメントからdocsetを生成します。生成にはDash公式のGitHubリポジトリに [javadocset](https://github.com/Kapeli/javadocset) というコマンドラインツールがありますのでそれに日本語ドキュメント対応のパッチを当てたものを利用します。

まず [私のjavadocset forkのリリースページ](https://github.com/mtgto/javadocset/releases/tag/java11) から `javadocset` をダウンロードして適当なところに配置、実行権限を付加します。

```console
chmod +x /path/to/javadocset
```

次に `javadocset` コマンドを使って docset を作成します。作成は先程展開したzipの中の `docs/` ディレクトリ内で行います。

```console
cd F12202_01/docs
/path/to/javadocset 'Java SE 11' api
```

3分ほどで完了し、 `Java SE 11.docset` というdocsetファイルが作成されます。私の手元では `Java SE 11.docset` のファイルサイズは495.9MBありました。

なお、 https://github.com/mtgto/javadocset (`japanese` ブランチ) にJava SE 11 日本語ドキュメントに対応した変更を入れているので自分でビルドすることも可能です。ビルド方法は最初の方の「Java SE 8編」をご参照下さい。

## 3. Dashに取り込む

あとは適当なフォルダに `Java SE 11.docset` を移動/コピーしてダブルクリックすればDashに取り込まれます.

※私は `~/Library/Application Support/Dash/DocSets/Java SE 11 ja/Java SE 11.docset` というパスにおいてますが、 `~/Documents` でもどこでもいいと思います。

もしすでに英語版Java SE APIをDashにインストールしていたらアンインストールしておいたほうがディスク容量に優しいでしょう。

以上で終わりです！ここまで読んでいただきありがとうございました。
Bloom Filter

+ データの有無を効率的に判断できるアルゴリズム

```rb
require "murmurhash3"

class BloomFilter

  SEED_BASE = 0xFBA4C795

  attr_reader :bits
  attr_reader :hash_funcs
  attr_reader :tweak

  def initialize(n, k, tweak)
    @bits = Array.new(n, 0) # ビット列
    @tweak = tweak          # 乱数
    @hash_funcs = k         # ハッシュ関数の数
  end

  # フィルタに要素を追加
  def add(data)
    calc_index(data).each do |i|
      bits[i] = 1
    end
  end

  # フィルタに要素が登録されているかを確認
  def contains?(data)
    calc_index(data).map{|i| bits[i]}.find{|i| i == 0}.nil?
  end

  private

  def calc_index(data)
    list = []
    hash_funcs.times do |i|
      seed = (i * SEED_BASE + tweak) & 0xffffffff
      hash = MurmurHash3::V32.str_hash(data, seed)
      list << hash % bits.length
    end
    list
  end

end

filter = BloomFilter.new(10, 2, 123456)

filter.add("bitcoin")
filter.add("monacoin")

filter.contains?("bitcoin")
# =>true

filter.contains?("litecoin")
# =>false

filter.contains?("bitcoin4")
# =>true
```
リモートノードとのハンドシェイク

```rb
require "bitcoin"
require "eventmachine"

Bitcoin.network = :testnet3

class Connection < EM::Connection
  attr_reader :host, :port, :parser

  def initialize(host, port)
    @host = host
    @port = port
    @parser = Bitcoin::Protocol::Parser.new(self)
  end

  def post_init
    puts "connected."
    on_handshake_begin
  end

  def receive_data(data)
    parser.parse(data)
  end

  def on_handshake_begin
    puts "handshake begin."
    params = {
      block: 0,
      from: "127.0.0.1:18333",
      nonce: Bitcoin::Protocol::Uniq,
      to: "#{host}:#{port}",
      user_agent: "/bitcoin-ruby:#{Bitcoin::VERSION}/",
      version: 70015,
      time: Time.now.tv_sec
    }
    send_data(Bitcoin::Protocol.version_pkt(params))
  end

  def on_version(version)
    puts "receive version. Version:#{version.version}, UserAgent:#{version.user_agent}"
    send_data(Bitcoin::Protocol.verack_pkt)
  end

  def on_verack
    puts "receive verack. handshake complete."
  end

end

EM.run do
  EM.connect("localhost", 18333, Connection, "localhost", 18222)
end
```

```
$ ruby handshake.rb
connected.
handshake begin.
receive version. Version:70015, UserAgent:/Satoshi:0.15.99/
receive verack. handshake complete.
```
Pythonによる数値計算-半減期(Euler法)

# はじめに
　入門を卒業していよいよ数値計算らしい問題を扱っていこうと思っています。今回のテーマは**半減期**です。不安定な放射性物質は放射線を出しながら崩壊を繰り返して安定な物質へと変化します。放射性物質の安定化に伴って放射能の強さは減少するわけですが、この放射能の強さが半分になる時間を半減期と呼びます。この半減期を数値計算で求めてみましょう。
　Pythonによる数値計算入門-Part1でも書きましたが、まずは数値計算の手法で解くことのできる数式を用意します。放射性物質の個数Nは時定数$\tau$の割合で減少すると仮定し、次の一階の常微分方程式を得ます。

```math
\begin{equation}
\frac{dN}{dt} = -\frac{N}{\tau} \tag{1}
\end{equation}
```
これは式変形なしで数値計算の手法を適用できます。今回はEuler法という数値計算の手法を用いて、この一階の常微分方程式を解いてみましょう。ちなみに人間的な方法でこれを解くと次のようになります。グラフに書き出してみるとわかるでしょう。

```math
N(t) = N_{0}e^{-t/\tau} \tag{2}
```


#Euler法
時刻tにおける放射性物質の$N(t)$が時間$\Delta t$後に$N(t+\Delta t)$になっているとすると、これは$\Delta t$で展開できて

```math
N(t+\Delta t) = N(t) + \frac{dN(t)}{dt}\Delta t + O({\Delta t}^{2}) \tag{3}
```
式(1)を代入すると

```math
N(t+\Delta t) = N(t) - \frac{N(t)}{\tau}\Delta t + O({\Delta t}^{2}) \tag{4}
```
式(4)の第三項$O({\Delta t}^{2})$は$\Delta t$が十分小さければ無視できます。このようにして時間$\Delta t$後の放射性物質の個数を時刻$t$での放射性物質の個数から計算することができるようになりました。これをEuler法と言います。
 　Euler法を使って数値計算するわけですが、プログラム的には次のようになります。

```
for i in range(steps-1):
    t[i+1] = t[i] + dt
    n[i+1] = n[i]-n[i]/tau*dt
```
変数stepsは前回も説明した分割数です。分割して計算してその結果を逐次リストに格納します。時間リストtには一つ前の時刻からdtを足すことで次の時刻を定義します。粒子数リストnにはEuler法によって一つ前の時刻での粒子数から求めることができるので、その値を計算して格納します。

# 計算
　では全体のプログラムをみてみましょう。

```decay.py
import math, pylab

#①
n_0 = 100
tau = 1
dt = 0.01
t_max = 5
steps = int(t_max/dt)
n = [0.0]*steps
t = [0.0]*steps

#②
t[0] = 0.0
n[0] = n_0

#③
for i in range(steps-1):
    t[i+1] = t[i] + dt
    n[i+1] = n[i]-n[i]/tau*dt


#④

pylab.plot(t, n)
pylab.show()
```
　プログラム内ではまず①で初期値を設定します。Pythonによる数値計算入門ではグラフを描くことを目標としていたので定義域を設定するという表現を用いていましたが、一般にはこれはパラメータの初期値を設定することに対応しています。②では生成した時間リストtと粒子数リストnに初期値を格納しています。③は先ほども説明したようにEuler法を使った計算です。④でグラフを書き出しています。
　半減期を出力したい場合は③のしたに次のようなプログラムを入れると標準出力されるはずです(コマンドプロンプト上に表示されること)。

```
for i in range(steps-1):
    if int(n[i]) == n_0/2:
        print(t[i])

```
粒子数リストをint型に変換しておおよそ半分になっている時間を求めて出力しています。

#最後に
 　Euler法が有効なのは$\Delta t$が十分に小さいときのみであることに注意してください。そうでない場合は収束性が保証されません。Euler法は学習目的には最適ですが、本格的な数値計算にはあまり適していません。
　しかし、Euler法は数学的にもプログラム的にも理解しやすいと思いますので、このプログラムを拡張して遊んでください。標準入力から数値を代入できるようにしたり二粒子系にするなどが考えられます。あるいは別の一階線形微分方程式を持ってきてそれを解いてみるのもいいと思います。
AndroidサンプルのビルドでminSdkVersionのエラーが出たときの対処(Android初心者)

AndroidStudioを使っていて、サンプルをダウンロードしてビルドしてみようとしたときに出たエラーの対処です。

エラー:Execution failed for task ':Application:processDebugManifest'.
> Manifest merger failed : uses-sdk:minSdkVersion 9 cannot be smaller than version 14 declared in library [com.android.support:gridlayout-v7:26.1.0] C:\Users\use\.android\build-cache\a30df1b586f055c7d0852106c9f9f75e253c4101\output\AndroidManifest.xml
	Suggestion: use tools:overrideLibrary="android.support.v7.gridlayout" to force usage

とりあえずよくわからないので、Suggestion: use ... to force usage(強制的に...を使え)と出てきたのでAndroidManifest.xmlに以下のuses-sdk要素の記述を追加してみましたが、エラーは...を変えて際限なく続きます。

    <uses-sdk xmlns:tools="http://schemas.android.com/tools"
        android.support.v7.gridlayout,
        tools:overrideLibrary="android.support.v7.cardview,
        android.support.coreutils,
        ...際限なく
        "/>

全くよくわかっていなかったのですが、どうやらbuild.gradleという設定ファイルの以下のエントリを14以上にすることで解決するものでした。

    defaultConfig {
        minSdkVersion 14 //ここ 9から14に変更
        targetSdkVersion 26
    }
初めて Apple Watchアプリをリリースするまでにハマったこと

# はじめに
　先日、初めての Apple Watch アプリ「乗るまで何分」をリリースできましたが、ネット情報を頼りに手探りで Watch アプリを開発するまでにハマったことを、書いておきます。それらは判ってしまえば、なぁんだ！といったことですが、解決するまでは必死で調べたので、これから始める人には役にたつかもしれないと思います。
　開発環境は Xcode 9 を MacBook Air 13 です。

# 最初のつまづき
　まず、Xcode で File → New → Xcode Project で、WatchOS タブの iOS App with WatchKit App を選択して新しいプロジェクトを作ります。
　これも、後からわかったことですが、普通に iOS の Master-Detail App など該当するスタイルのプロジェクトを選んで作成してから、File → New → Target... で、WatchKit App を追加する方法があって、この方が、iOS 側のアプリの自由度があって良いと思います。

## Watch のシュミレーターが開かない
　作成したばかりの WatchKitt App を含むプロジェクトを、そのままシュミレーターで動かしてみようとしたら、iPhone のシュミレーターだけが起動して、Apple Watch のシュミレーターが起動しない。はて？
シュミレーターの選択メニューに + Apple Watch.... が出てこない。
![スクリーンショット 2017-10-22 6.31.28.png](https://qiita-image-store.s3.amazonaws.com/0/16491/0c1c5a7c-2de7-2b60-5ead-4726c9828e82.png)

ネットでググってみたり、プロジェクトの設定を調べたりしたがよくわからない。
で、偶然、ターゲットの部分（この機能すら知らなかった）を誤ってクリックしたら、WatchKit を選ぶと iPhone + Apple Watch... が選択できるようになることが判って、見事 Apple Watch のシュミレーターが起動できました。
![スクリーンショット 2017-10-22 6.31.59.png](https://qiita-image-store.s3.amazonaws.com/0/16491/c0b8fea3-9572-1979-7441-9490528912e9.png)

# 途中のつまづき
　とりあえずシミュレーターでのデバッグができるようになったので、のサンプルをネットで探しながら実装を始めると、Swift のバージョンが古い時期のものが多数あって、そのまま利用するとエラーになるものが続出。大概は Xcode のエラーメッセージを見て、場合によっては Fix ボタンで修正してくれるのでなんとかなりましたが、最後に苦労したのが iPhone から Watch に情報を送信するあたり。最終的にはこの Qiita にあった最新の情報が参考になった。いっぱいありすぎて忘れたのと、この辺りは学習用のプロジェクトで試行錯誤して勉強していくしかないかと。

# 最後のつまづき
　シュミレーターでのデバッグも、実機でのデバッグもできて、いよいよ App Store にアップロードしようとしたら、署名ファイルのエラーが出て、何故なのかわからず悶々と無駄に時間を過ごしましたが、ネット上に解決のありました。それは、配布用証明書はiPhoneアプリだけでなくて WatchKit、WatchKit Extention にも必要だということでした。（恥ずかしながら、iPhone アプリにくっついているので、iPhoneアプリ用に配布用の証明書を作成しただけで良いと思い込んでいたのでした）
　iPhoneアプリ（本体）の Bundle Identifier で証明書を作成した他に、WatchKit 用に .watchkitapp を追加したものと、WatchKit Extension 用に .watchkitapp.watchkitextension を追加したもの、合計3個の配布用証明書を作成する必要があるのでした。
　iTunesconnect のサイトでは、一個（iPhone用のもの）を用意するだけで、アップロードできます。

# リリースしたアプリ
　私が Apple Watch アプリとして初めてリリースしたは「乗るまで何分」というアプリです。
時刻表と連動して次に乗れそうな便までの残り時間をカウントダウンします。また、次の便、その次の便の発時刻も表示します。時刻表は iPhone 側で最大5つまで登録でき、Watchで表示する時刻表はデジタルクラウン（竜頭）を回して選択します。
![AppleWatchSCnorumade.png](https://qiita-image-store.s3.amazonaws.com/0/16491/df02a063-bb42-d196-3780-38763ddf65ae.png)

有償アプリ（240円）ですが、ご興味ありましたら以下のサイトをご覧ください。

紹介サイト： http://ynomura.com/home/?page_id=263
App Store で見る： https://itunes.apple.com/jp/app/乗るまで何分/id1296168550?mt=8%3Cbr%20/%3Ehttps://itunes.apple.com/jp/app/乗るまで何分/id1296168550?mt=8
ubuntu - ruby - headless chrome でスクレイピングするのに使ったコマンドの覚書

```
echo "deb http://dl.google.com/linux/chrome/deb/ stable main" | sudo tee -a /etc/apt/sources.list
wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo apt-get update
sudo apt-get install google-chrome-stable
sudo apt install ruby
sudo gem install bundler
sudo apt-get install ruby-dev
sudo apt-get install zlib1g-dev
wget http://chromedriver.storage.googleapis.com/2.33/chromedriver_linux64.zip
unzip chromedriver*.zip
mv chromedriver ~/.local/bin
rm chromedriver*.zip

mkdir ruby && cd ruby
bundle init
echo 'gem "nokogiri"' >> Gemfile
echo 'gem "selenium-webdriver"' >> Gemfile
bundle install
```
PHPでNgram（バイグラム）

# 経緯
MySQLでの全文検索用をしたかったので知らべていたところ以下の記事
でNgram(バイグラム)の実装が必要になりそうだったので作成してみました。

**MYSQL5.7以降だと既に日本語のNgramパーサーが入っているそうなのでMYSQL5.7以降は[こちら](https://qiita.com/horikeso/items/8b946e6679c5e3839327#%E5%85%A8%E6%96%87%E6%A4%9C%E7%B4%A2%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%81%AF57%E4%BB%A5%E4%B8%8A)。
但し[こんな動作](https://yoku0825.blogspot.jp/2016/07/mysql-57ngram.html?m=1)もあるらしいです。**

http://blog.wackwack.net/entry/2016/03/21/221821

以下の設定は忘れやすいので注意

```
[mysqld]
innodb_ft_min_token_size=2
```

# 概要
CMSでhtmlを保存するのとは別に検索用カラムを用意して検索用文字列として使用する想定です。

# コード
```php
class Bigram
{
    /**
     * 文字列を登録・検索用バイグラムに変換する
     *
     * @param string|null $string
     * @param boolean $for_search_flag
     *     false:DB保存時に使用する変換方法 あいう→あい いう う
     *     true:検索時に使用する変換方法 あいう→あい いう　1文字の場合は空文字を返します（そもそも2文字以上で検索しないとヒットしないので構わない）
     * @return string|null
     */
    public function convert_to_bigram(string $string = null, bool $for_search_flag = false)
    {
        if (is_null($string))
        {
            return null;
        }

        $string = str_replace(array(" ", "　", "\r", "\n", "\t"), "", $string);
        $string = strip_tags($string);
        $character_list = preg_split("//u", $string, -1, PREG_SPLIT_NO_EMPTY);// 1文字づつ配列に分ける

        $bigram = '';// バイグラム

        $glue = '';
        foreach ($character_list as $index => $character)
        {
            if (isset($character_list[$index + 1]))
            {
                $bigram .= $glue.$character.$character_list[$index + 1];
            }
            else
            {
                if ($for_search_flag === false)
                {
                    $bigram .= $glue.$character;
                }
            }
             $glue = ' ';
        }

        return $bigram;
    }

}

$string = "<p><div><a>あ い\t う　え\nおか</a></div></p>";
$bigram = new Bigram();
var_dump($bigram->convert_to_bigram($string));
var_dump($bigram->convert_to_bigram($string, true));
```

# 結果
```
string(38) "あい いう うえ えお おか か"
string(34) "あい いう うえ えお おか"
```

# 確認
http://sandbox.onlinephpfunctions.com/code/c19755ed0c4e24b889069c286a1e6ec190ca4804

# その他
for_search_flagで結果を分けたのは検索時用のバイグラムが必要になったためです。
※バイグラムで検索する際は2文字以上で検索すること

「あいうえおか」から「うえお」で検索する例
DBで持つのは「あい いう うえ えお おか か」

```
match(`bigram`) against('+"うえ えお" in boolean mode')
ではヒットするが

match(`bigram`) against('+"うえ えお お" in boolean mode')
だとヒットしない
```
youtube data API v3 categoryId 一覧

`YouTube Data API v3`で取得できる`categoryId(videoCategoryId)`気になったので調べてみた。

| categoryId | 名前 |
|:-:|:-:|
| 1 | 映画とアニメ |
| 2 | 自動車と乗り物 |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | 音楽 |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | ペットと動物 |
| 16 | |
| 17 | スポーツ |
| 18 | |
| 19 | 旅行とイベント |
| 20 | ゲーム |
| 21 | |
| 22 | ブログ |
| 23 | コメディー |
| 24 | エンターテイメント |
| 25 | ニュースと政治 |
| 26 | ハウツーとスタイル |
| 27 | 教育 |
| 28 | 科学と技術 |
| 29 | 非営利団体と社会活動 |
| 30 | アニメーション |
| 31 |  |
| 32 |  |
| 33 |  |
| 34 |  |
| 35 |  |
| 36 |  |
| 37 |  |
| 38 |  |
| 39 |  |
| 40 |  |
| 41 |  |
| 42 |  |
| 43 | コメディー,エンターテイメントニュース |
| 44 | なし(映画予告) |
| 45 |  |
| 46 |  |
| 47 |  |
| 48 |  |
| 49 |  |
| 50 |  |
rubyの::について

Rubyのコロンを使用した書き方(「::」)について、分かりやすいと思ったコードを備忘録的に残しておきます。
コロンを使用した書き方では、メソッドの呼び出し以外に定数の呼び出しにも利用され、下記は定数の扱い例です。

> ```ruby:sample.rb
A = "::A"
class Foo
    A = "Foo::A"
    class Bar
        A = "Foo::Bar::A"
        p A         # => "Foo::Bar::A"
        p Foo::A    # => "Foo::A"
        p ::A       # => "::A"
    end
end
```

上記サンプルコードは次のサイトから頂きました。
[stack overflow](https://ja.stackoverflow.com/questions/2446/ruby-%E3%81%A7%E3%82%AF%E3%83%A9%E3%82%B9%E5%90%8D%E3%81%AE%E5%85%88%E9%A0%AD%E3%81%AB-%E3%81%8C%E3%81%A4%E3%81%8F%E3%81%A8%E3%81%8D%E3%81%AE%E6%84%8F%E5%91%B3%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)
ESP-WROOM-32でLチカ (Windows)

#はじめに
ESP-WROOM-32 を購入したので試運転

#ハード
- ESP32-DevKitC ESP-WROOM-32
Amazonで安かったので買ったのですが、GPIOのピン番号が印字されていないのはだめですね。開発ボードの意味が無いです。勉強になりました。

- LED
- 抵抗
- ブレッドボード
- microUSBケーブル
- Windows10マシン

#ソフト
- Windows10 母艦
- ArduinoIDE 1.8.5
- ESP32 ボードマネージャ espressif/arduino-esp32

#インストール
ArduinoIDE は、Windows10はストアアプリにもありますし、[ここ](https://www.arduino.cc/en/Main/Software)からWindows版をダウンロードしてインストールするだけです。

ESP32のボードマネージャは自力でファイルを配置してからのインストールらしいでの[ここ](https://qiita.com/rukihena/items/6a904368700eb1c7d2a3)を参考にしました。

1. [GitHub espressif/arduino-esp32](https://github.com/espressif/arduino-esp32)からZIP版をダウンロードします。(緑のボタン)
2. ZIPを解凍して「スケッチブックの保存場所：」に配置します。環境設定の中にありますのでそこを見てください。[スケッチブックの保存場所：]\hardware\espressif\esp32 の下に解凍したものを置いてください。フォルダが無ければ作ってください。
3. 配置した中の tools\get.exe を実行。コンソールが開きインストールが始まります。

#組み立て
ブレッドボードに以下のように設置。LEDは向きに注意。抵抗は適当Ωで良いと思います。

```text
               +---------------+
PC ==microUSB=== ESP-WROOM-32  |
               +   IO4    GND  |
               +----|------|---+
                   LED    R10k
                    +------+

```

#ソース
```C:sketch_oct22a.ino
void setup() {
  pinMode(4, OUTPUT);
}

void loop() {
  digitalWrite(4, HIGH);
  delay(250);
  digitalWrite(4, LOW);
  delay(250);
}
```

#実行
- [ツール]-[シリアルポート]で接続されているポートを選択。
- [マイコンボードに書き込む]

なんかエラーが出てますけどBLE関係みたいなのでとりあえず放置(^_^;)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/203949/1ebef1f0-f424-5b5c-72eb-286f997fb1c7.png)


無事点灯式完了
![IMG_0821.png](https://qiita-image-store.s3.amazonaws.com/0/203949/e418f1a6-e79c-d87a-cb62-c9ed48291c98.png)

#次回は
WiFiを使います。これを使わないと。

SpecialThanks!!
https://qiita.com/rukihena/items/6a904368700eb1c7d2a3
https://qiita.com/mascii/items/4c366ad4709469d5fda9
Bash on Ubuntu on Windows で trash-cli を叩いた際のごみ箱パス

# trash-cliって?
Ubuntu使ってる人からしたら便利なコマンド．
`rm foo.bar`とかでファイルを，`rm -r foobar.d`とかでディレクトリを削除できる．
しかし，`rm`コマンドで削除したファイルは，ファイルシステムから完全におさらばなわけで……

`trash`コマンドを用いるととりあえずごみ箱に対象ファイルをぶち込んでくれる便利なコマンド．
やってることは`mv "path to trash"`に近しい事を行ってる．

# Bash on Ubuntu on Windows(以下BoUoW) で trashコマンド叩いたら困った…
Ubuntuでは確か`$HOME/.local`とかにごみ箱ディレクトリがあった……はず……
けどBoUoWではそれが無いじゃん!?

とりあえず`trash-list`をUbuntuのシステムにマウントしているCドライブ上で実行してみたら…

`/mnt/c/.Trash/1000`

とか出てきました．

# とりあえずリンク張りました
参考までに…

`ln -s /mnt/c/.Trash/1000/files $HOME/Trash`
なんかのコマンドを実行して、その結果に特定の文字列が含まれる場合に表示するだけのプログラムをPythonで書いてみた

Pythonに閉じない処理をさせながら、結果をPythonで処理したい時のテンプレになるといいかなと思いつつ。
dirコマンドの結果に"xml"という文字列が含まれてたら、該当行を出力という風情。
os.popen()使ってもよかったんだけど、subprocess.Popen()使って書いてみたり。
…例によって残骸付きですｗ

```command.py
#
# coding: utf-8
#
# コマンド実行して、特定の文字列が含まれていたら表示するだけのプログラム。
#

import sys

import os
import subprocess

def main():
    p = subprocess.Popen("dir", shell=True, stdout=subprocess.PIPE,  stderr=subprocess.STDOUT)
    for line in iter(p.stdout.readline, b''):
        if("xml" in line):
            line = line.replace('\n','')
            line = line.replace('\r','')
            print(line)

if (__name__ == "__main__"):
    main()
```
キャラに追従するカメラ



## キャラを用意

Colliderの形状がカプセルなどの場合は、転がってしまわないように、Rigidbodyの`Freeze Rotation`のx,zにチェックを入れる。


## カメラをキャラの子要素にする

```
Chara
　└ MainCamera
```

![camera.gif](https://qiita-image-store.s3.amazonaws.com/0/136286/6b88bdf7-5c9f-8d34-bc21-299a540898ac.gif "camera.gif")



## スクリプトで操作する

カメラに以下のスクリプトをアタッチ

```c:CameraController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraController : MonoBehaviour {
    public Transform target;
    public float smoothing = 5f;
    private Vector3 offset;

    void Start () {
        offset = transform.position - target.position;
    }

	void Update () {
        Vector3 targetCamPos = target.position + offset;
        transform.position = Vector3.Lerp(
            transform.position,
            targetCamPos,
			Time.deltaTime * smoothing
        );
    }
}
```

![cameraControl.gif](https://qiita-image-store.s3.amazonaws.com/0/136286/f30ee905-c014-0dc1-9b1f-c9fd4ceb03e0.gif "cameraControl.gif")



## 汎用スクリプトを使う

`Scripts > UnityStandardAssets.Utility > Smooth Follow`

もしくは

`Scripts > UnityStandardAssets.Utility > Smooth Target`


> 参考
[Unityでカメラの設定とキャラクターの追従をさせる](https://gametukurikata.com/camera/chasechara)


## 常にプレイヤーの進行方向後ろから追従させる

背面ベクトルを何倍かさせてカメラの位置ベクトルを決定する。

```c
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ChaseCamera : MonoBehaviour {

	private GameObject player;
	private Vector3 prevPlayerPos;
	private Vector3 posVector;
	public float scale = 3.0f;
	public float cameraSpeed = 1.0f;

	void Start () {
		player = GameObject.Find ("CameraTarget");
		prevPlayerPos = new Vector3 (0, 0, -1);
	}

	void Update () {
		Vector3 currentPlayerPos = player.transform.position;
		Vector3 backVector = (prevPlayerPos - currentPlayerPos).normalized;
		posVector = (backVector == Vector3.zero) ? posVector : backVector;
		Vector3 targetPos = currentPlayerPos + scale * posVector;
		targetPos.y = targetPos.y + 0.5f;
		this.transform.position = Vector3.Lerp (
			this.transform.position, 
			targetPos, 
			cameraSpeed * Time.deltaTime
		);
		this.transform.LookAt (player.transform.position);
		prevPlayerPos = player.transform.position;
	}
}
```

正面ベクトルをとれば前から撮影するカメラに変わる。

```c
void Update () {
	Vector3 currentPlayerPos = player.transform.position;
	Vector3 frontVector = (currentPlayerPos - prevPlayerPos).normalized;
	posVector = (frontVector == Vector3.zero) ? posVector : frontVector;
	Vector3 targetPos = currentPlayerPos + scale * posVector;
	targetPos.y = targetPos.y + 0.5f;
	this.transform.position = Vector3.Lerp (
        this.transform.position,
        targetPos, 
        cameraSpeed * Time.deltaTime
    );
	this.transform.LookAt (player.transform.position);
	prevPlayerPos = player.transform.position;
}
```
イベントハンドラについての備忘録

簡単なメモ書き。

複数イベントをまとめる方法など。


```csharp:イベントハンドラの操作

public MainWindow()
{
    InitializeComponent();
 
    this.btn1.Click += btn_Click;
    this.btn2.Click += btn_Click;

    //直接メソッドを書く方法。
    this.btn3.Click += (sender, e) => MessageBox.Show("Button3だよ");
}


private void btn_Click(object sender, EventArgs e)
{
    Button btn = sender as Button;

    //ボタンの種類によって処理を変更
    switch (btn.Name)
    {
        case "btn1":
            MessageBox.Show("Button1だよ");
            break;

        case "btn2":
            MessageBox.Show("Button2だよ");
            break;
    }
}
```

ちなみに```this.btn1.Click += btn_Click;```の部分では、
Buttonがデリゲート型のClickプロパティを持っており、
btn_Clickメソッドを委譲している。
別スレッドからのUI操作についての備忘録

簡単なメモ書き。

通常、非同期メソッド内からUI操作をしようとすると
Exceptionが発生します。
以下が回避の方法になります。

```csharp:別スレッドからのUI操作

private async Task HeavyProcessingAsync()
{
    if (this.InvokeRequied)
    {
        //別スレッドによるUI操作
        this.Invoke((MethodInvoker)(() => TextBox.Text = "hoge"));
    }
    else
    {
        //UIスレッドからのUI操作
        TextBox.Text = "hoge";
    }
}
```

まずInvokeする必要があるかを判定して、
必要ならばInvokeメソッドとMethodInvokerデリゲートを利用します。

---
参考：[スレッド セーフなコントロールの呼び出し](https://so-zou.jp/software/tech/programming/c-sharp/thread/thread-safe-call.htm)
logstash jdbc plugin で oracle を利用するための環境設定

- 概要
  - debian 上の logstash jdbc plugin で oracle を利用するための環境設定
- 環境
    - debian jessie
    - oracle-instantclient11.2
    - logstash 5.2.x
- ザックリ手順
    - Oracle instant client を公式サイトから取得しdeb化しインストールする
    - logstash jdbc plugin で oracle からデータを採取してみる
- 参考
    - http://blog.suz-lab.com/2007/06/oraclelibaioso1.html
    - http://qiita.com/takashi0314/items/7b8a36682780652e9ab2
- 関連
    - [ELK5.2 + beats + jdbc による可視化 - 1](https://qiita.com/colion/items/e75ce4278c323ec41136)

# Oracle instant client の deb化

```bash
$ sudo apt-get install alien
$ alien -d oracle-instantclient11.2-basic-11.2.0.4.0-1.x86_64.rpm
$ alien -d oracle-instantclient11.2-devel_11.2.0.4.0-2_amd64.rpm
$ alien -d oracle-instantclient11.2-sqlplus_11.2.0.4.0-2_amd64.rpm
$ ls
oracle-instantclient11.2-basic_11.2.0.4.0-2_amd64.deb
oracle-instantclient11.2-devel_11.2.0.4.0-2_amd64.deb
oracle-instantclient11.2-sqlplus_11.2.0.4.0-2_amd64.deb
$
```

# Oracle instant client の install

```bash
$ sudo aptitude install libaio1
$ sudo dpkg -i oracle-instantclient11.2-basic_11.2.0.4.0-2_amd64.deb
$ sudo dpkg -i oracle-instantclient11.2-devel_11.2.0.4.0-2_amd64.deb
$ sudo dpkg -i oracle-instantclient11.2-sqlplus_11.2.0.4.0-2_amd64.deb
$ sudo sh -c "echo "/usr/lib/oracle/11.2/client64/lib" > /etc/ld.so.conf.d/oracle.conf"
$ sudo ldconfig
```
 
# oracle への CLI 接続確認

```bash
$ sqlplus64 USER/PASSWORD@HOSTNAME:PORT/DBNAME
???
SQL> quit
Oracle Database 11g Release 11.2.0.4.0 - 64bit Production???
$
```

# logstash jdbc plugin

```bash:oracle-jdbc.conf
## http://qiita.com/tsgkdt/items/4c90e87ae00982f6b608
$ sudo ln -s /usr/lib/oracle/11.2/client64/lib/ojdbc6.jar /usr/share/logstash/bin/odjbc6.jar
$ sudo vi /etc/logstash/conf.d/oracle-jdbc.conf
$ cat /etc/logstash/conf.d/oracle-jdbc.conf
input {
  jdbc {
    jdbc_driver_library => "ojdbc6.jar"
    jdbc_driver_class => "Java::oracle.jdbc.driver.OracleDriver"
    jdbc_connection_string => "jdbc:oracle:thin:@HOSTNAME:PORT/DBNAME"
    jdbc_user => "USER"
    jdbc_password => "PASSWORD"
    schedule => "*/15 * * * *"
    statement_filepath => "SQL_STATEMENT_FILE_PATH"
    last_run_metadata_path => "./jdbc_last_run.dat"
  }
}
output {
  elasticsearch {
    hosts => "ELASTICSEARCH_HOST:9200"
    manage_template => false
    index => "INDEXNAME-%{+YYYY.MM.dd}"
    document_type => "%{[@metadata][type]}"
#    user => "elastic"
#    password => "changeme"
  }
}
$
```

SQL文はファイル化したものを statement_filepath で参照する方法を採っています。

```sql:SQL_STATEMENT_FILE_PATH
select
  row1,
  row2
from
  some_table
```
PythonでOCR

# TL;DR

tesseractをpyocrから呼び出して使う方法。

# OCRツールを入れる

今回はtesseractを入れる。
こちらの記事から各環境向けの入れ方を参照すること。
https://github.com/tesseract-ocr/tesseract/wiki

## Windows向け

執筆時最新版は4.0.0αのWindows Installer made with MinGW-w64

Choose Componentsにて、Additional language dataからJapaneseを選択する。

インストール後、"C:\Program Files (x86)\Tesseract-OCR"をPathに追加する。

# pyocrを入れる

```
pip install pyocr
```

Windowsの場合は、事前にAnacondaなどを入れておくと楽。

# pyocrからtesseractを呼び出せるか確認

pyocrの公式ページのコードで確認する。
https://github.com/openpaperwork/pyocr

```py
from PIL import Image
import sys

import pyocr
import pyocr.builders

tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)
# The tools are returned in the recommended order of usage
tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))
# Ex: Will use tool 'libtesseract'

langs = tool.get_available_languages()
print("Available languages: %s" % ", ".join(langs))
lang = langs[0]
print("Will use lang '%s'" % (lang))
# Ex: Will use lang 'fra'
# Note that languages are NOT sorted in any way. Please refer
# to the system locale settings for the default language
# to use.
```

```:Output(Example)
Will use tool 'Tesseract (sh)'
Available languages: eng, equ, jpn, osd
Will use lang 'eng'
```

# 文字認識

> 認識したい画像( iroha.png )

![iroha.png](https://qiita-image-store.s3.amazonaws.com/0/31245/4ce8c456-baf7-ddb3-476e-61afe2faf927.png)


```py3
from PIL import Image
import sys

import pyocr
import pyocr.builders

tools = pyocr.get_available_tools()
if len(tools) == 0:
    print("No OCR tool found")
    sys.exit(1)
# The tools are returned in the recommended order of usage
tool = tools[0]
print("Will use tool '%s'" % (tool.get_name()))
# Ex: Will use tool 'libtesseract'

langs = tool.get_available_languages()
print("Available languages: %s" % ", ".join(langs))
lang = langs[0]
print("Will use lang '%s'" % (lang))
# Ex: Will use lang 'fra'
# Note that languages are NOT sorted in any way. Please refer
# to the system locale settings for the default language
# to use.

txt = tool.image_to_string(
    Image.open('iroha.png'),
    lang="jpn",
    builder=pyocr.builders.TextBuilder(tesseract_layout=6)
)
print( txt )
# txt is a Python string

```

```:Output
い ろ は に ほ へ と ち り ぬ
```

# 覚え書き

解像度低い文字画像だと認識上手くいかない。少なくとも、slackのemojiの解像度じゃダメだった。

# 参考
OCRツール「Tesseract OCR」をインストールしてPythonで使う http://73spica.tech/blog/tesseract_for_python/
PHPのjson_decodeがNULLになる

# 何が起きたか
どこぞのAPIで取ったJSONっぽい文字列をPHPのjson_decodeに入れてみたら、NULLが返ることがあった。

##試したこと１
Online JSON Viewer (http://jsonviewer.stack.hu/) にJSONをそのまま入れてみる。
残念ながら正常に変換できてしまう。JSONの構文的には問題なさそう。

##試したこと２
Best Online JSON Viewer (https://codebeautify.org/jsonviewer) にも入れてみる。
何かおかしいみたいだけど、矢印の部分には何もない。

```
Error: Parse error on line 1:
...ventory":"1","name":"\u3010T\u30DD\u30A4
-----------------------^
Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '[', got 'undefined'
```

##試したこと３
JSON整形サービス (http\://www\.ctrlshift\.net/jsonprettyprinter/ )に入れてみた。[^1]

```
Error: Invalid \escape: line 1 column 413 (char 412)
```

おー、ついに具体的なヒントをゲット

#答え
×（算数の掛ける記号）が**\xD7**にエスケープされていると、json_decode関数はエラーになる。json_last_error_msg()で返ってくる情報はJSON_ERROR_SYNTAXで、ほぼノーヒント状態で調べるのも大変だった。

掛ける記号をPHPのjson_encodeで変換すると**\u00d7**になる。しょうがないので**\xD7**を**\u00d7**に変えてあげたらうまくいった。

```
$json = str_replace('\xD7', '\u00d7',$json);
```

#追記
\xD7だけでなく\xA7なんてのも出てきて、1つ1つ退治している場合ではなかった。\xで始まる16進数2つまでなら、全部置き換えてしまう。こっちのほうが幸せになれそう。

```
$json = preg_replace('/\\\\x([0-9a-f][0-9a-f])/i', '\\u00$1', $json);
```

#教訓
リンク先を見ると、\xD7はJavascript向けのエスケープでした。つまり、Javascriptで処理するために作られたJSONを横取りしてPHPで処理しようとしたから悪いんだ。APIがJavascriptで処理する前提で返しているときは、気を付けよう。

#リンク
http://www.charbase.com/00d7-unicode-multiplication-sign


[^1]: 2018/5/22 上記サービスは追記時点でアクセスできなくなってしまいました。