OmniAICreator/Qiita-1.07M huggingface dataset:
JavaScriptをついばむ：オブジェクト

JavaScriptの勉強メモ。

## オブジェクトの生成
* オブジェクトリテラル、コンストラクタ、Object.createによる3種類位の生成方法があるがAirbnbのスタイルガイドを読むとリテラル構文を使うほうが良いらしい。

``` javascript
// bad
const card = new Object();

// good
const card = {};
```

## オブジェクトのロック
* 拡張防止：Object.preventExtensionsメソッド
	* 引数に指定されたオブジェクトを拡張不能にする。
* 保護：Object.sealメソッド
	* 引数に指定されたオブジェクトを保護する。保護するとプロパティの追加、削除、属性変更ができなくなる。
* 凍結：Object.freezeメソッド
	* 引数に指定されたオブジェクトを凍結する。オブジェクトのプロパティを読み込む以外なにもできなくなる。(プロパティの追加禁止、再定義不可能、値の書き込み禁止にするため)


## Mixin
オブジェクトに他のオブジェクトの持っているプロパティをコピーして「混ぜ込む」こと。

``` javascript
function mixin(target, source) {
   for(var propety in source) {
     if(source.hasOwnProperty(propety)) {
       target[propety] = source[propety];
     }
   }
   return target;
}

let item1 = {a: 1, b: 2};
let item2 = {b: 3, c: 4};
let item = mixin(item1, item2);
console.log(item);

// [object Object] {
//   a: 1,
//   b: 3,
//   c: 4
// }
```

## ES6でのオブジェクト拡張
* プロパティ内でのシンボル利用

``` javascript
let item = {};
let s = Symbol("clover");
item[s] =3;
console.log(item); // => Object {Symbol(clover): 3}
```
* オブジェクトリテラルの拡張
 * 算出プロパティ名：`[計算式]： value`
 * プロパティ定義の略記：`{prop}`
 * メソッド定義の略記：`{method() {} }`
 * ジェネレータ定義の略記：`{ * generator() {} }`
JavaScriptをついばむ：DOM操作ードキュメント制御

JavaScriptの勉強メモ。

## DOMについて
DOM(Document Object Model)はJavaScriptなどからHTMLの要素を操作するためのインターフェースのこと。DOMはレンダリングツリーの構成の一部。レンダリングツリーはDOMとCSSOM(CSS Object Model)を組み合わせたもの。
DOMの重要なオブジェクトは次の３つ

### Windowオブジェクト
Webブラウザの１つのウィンドウもしくはタブのこと

### Documentノード
HTML文書全体のこと。文書から要素オブジェクトを取得としり要素を作成したりとHTML文章全体にかかわる機能を提供する

### 要素ノード
HTML文書内の要素を表すオブジェクト

### テキストノード
テキストを表すオブジェクト

## DOM操作
### ノード取得
メソッドを使えばidやタグを指定することによりノードオブジェクトを取得し内容を書き換えることもできる。下記はid名でノードを取得したパターン。

```html
<body>
	<div id='hoge'>おはよう</div>
	<script>
		let element = document.getElementById("hoge");
		element.innerHTML = 'おやすみ';
	</script>
</body>
```

|指定方法 |メソッド|
|---|---|
|id名 | getElementById('hoge') |
|タグ名 | getElementsByTagName('p') |
|class属性 | getElementsByClassName('fuga') |
|name属性| getElementsByName('foo')|
|CSSセレクタ(単一)| querySelector('table > tbody > tr')|
|CSSセレクタ(複数)| querySelectorAll('body')|

### 要素の属性値
要素の属性値を取得したり設定、削除することもできる。

|操作 |メソッド|
|---|---|
|取得|getAttribute|
|設定|setAttribute|
|削除|removeAttribute|


他にもノードの作成や挿入、削除もできる。
ブラウザのバージョンにより使用できないメソッドもあるので注意が必要。
JavaScriptをついばむ：Ajax

## Ajaxとは
Ajaxは「Asynchronous JavaScript + XML」の略称
Webサーバと非同期通信を行いDOMを利用してWebページを書き換えるプログラミングの手法。Webページ全体を再レンダリングせずにWebページの一部のみを変更することができる。

## Ajaxのメリット
* 最小限のデータ通信を行うことにより通信トラフィック、サーバー負荷を抑えることができ処理も高速になる。
* 非同期通信でクライアント側の操作をロックしない
* ページ遷移せずに部分変更を行うため高速に描画できる

## Ajaxの理解に重要なキーワード
* DOM
* JavaScript
* XMLHttpRequest
* XML(JSON)

## 処理の基本的な流れ
1. 非同期通信
	1. XMLHttpRequest オブジェクト生成
	2. サーバーとの通信の処理方法を登録
	3. リクエストを送信して通信を開始
2. レスポンスの読み出し
3. DOM更新
Bitname-Redmine docker コンテイナーでプラグ・インを設置する過程。

常にはRedmineを用いてテスト管理をするコンサルをやっています。その時Redmineのインストールはdockerのイメージがとても便利なのでそれでやっています。

でも場合によってプラグ・インが必要です。bitnami-redmine stackでインストールする場合には一般的なコマンドでできますが、bitnami-redmine-dockerの場合にはそれでできません。bitnami-redmineコンテイナーではredmine運営のための最小のファイルしかないからです。

俺の場合にはAgileプラグ・インとchecklistプラグ・インが欲しかったのでグーグル神様で聞いて見ましたがなかなか返事を見つけませんでした。
ある時一日くらい時間ができちゃったので自分で調査して記録します。

###前提：bitnami-redmine-dockerの設置成功。

* bitnami-redmine-dockerイメージはこれでやりました。<br> https://github.com/bitnami/bitnami-docker-redmine

* mariadbとは分離されて設置されます。

```
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS                    NAMES
07f6484a2359        bitnami/redmine:latest   "/app-entrypoint.sh /"   5 hours ago         Up 40 minutes       0.0.0.0:5001->3000/tcp   root_redmine_1
018c68ebab24        bitnami/mariadb:latest   "/app-entrypoint.sh /"   5 hours ago         Up 40 minutes       3306/tcp                 root_mariadb_1
```

* プラグ・イン・ディレクトリはここです。 

```
/var/lib/docker/volumes/root_redmine_data/_data/redmine/plugins
```

* 欲しいプラグ・インを上のディレクトリでunzipします。
* プラグ・インの設置作業はdockerコンテイナーでやらなきゃいけないので、dockerコンテイナーで接続します。

```
>> docker exec -i -t root_redmine_1 /bin/bash
root@07f6484a2359:/#
```

#### bundle install --no-deploymentの実行

* Redmineのコンテイナーの中には最小限の運営ファイルしかないので ```bundle install```を実行すると様々なエラーを出会います。
* 一応gcc compile環境を築くのが必要です。

> 1．apt-getのアップデート

```
root@07f6484a2359:/# apt-get update
```

> 2．makeの設置

```
root@07f6484a2359:/# apt-get install gcc
```

> 3．pkg-configの設置

```
root@07f6484a2359:/# apt-get install pkg-config
```

* gcc compile環境構築が終わると次々に必要なライブラリーを設置します。

> 4．libxml2の設置
nokogiriのためlibxml2を設置します。

```
root@07f6484a2359:/# apt-get install libxml2
```

> 5．libmysqlclient-dev の設置
mysqlのためlibmysqlclient-devを設置します。

```
root@07f6484a2359:/# apt-get install libmysqlclient-dev 
```


> 6．libpq-devの設置
PostgreSQLのためlibpq-devを設置します。

```
root@07f6484a2359:/# apt-get install libpq-dev 
```


> 7．imagemagick, libmagickcore-dev, libmagickwand-dev の設置
image processingのためimagemagick, libmagickcore-dev, libmagickwand-devを設置します。

```
root@07f6484a2359:/# apt-get install imagemagick libmagickcore-dev libmagickwand-dev
```

さ、必要なライブラリ設置は完了です。redmineのGemfileがある位置に行って ```bundle install```を遂行します。

```
root@07f6484a2359:/# cd /opt/bitnami/redmine/
root@07f6484a2359:/# bundle install --no-deployment
```

正常的に```bundle install```が終わったら以下のコマンドを遂行します。

```
root@07f6484a2359:/# rake redmine:plugins:migrate RAILS_ENV=production
```

#### redmineの再起動

redmineコンテイナー内のredmine再起動が必要です。再起動はコンテイナーのrestartで良いです。mariadbコンテイナーまで再起動すべきです。

```
>> docker restart root_redmine_1 
>> docker restart root_mariadb_1
```
redmineのAdministrationページでPlugInを確認すると下のような結果が出ます。

![](https://t1.daumcdn.net/thumb/R1280x0/?fname=http://t1.daumcdn.net/brunch/service/user/J8k/image/yue7bWvt17fhHaFSHz3ys2QOpbg.png)


:sunglasses:
バイナリーで保存したexcelファイルをRubyXLで展開し書き込む

ブログに全く同じ内容のものをあげてます。
が、Qiitaをメインに書いていたので、こっちにも投稿。
## RubyXLとは
主にexcel書き込み専用のgemです。  
xlsxとxlsmに対応してます(確か)

あとは主なところはgithubを見ていただければ使い方はわかるかと＼(^o^)／  
ここ[https://github.com/weshatheleopard/rubyXL:embed:cite]

僕は読み込みではrooを、書き込みではRubyXL使っています。  
rooにはちょっとした罠があるので、それはまた今度記事として書きたいなと。


## 動作環境

* mac OSX
* Ruby 2.3.1
* Rails 5.0.4

## 本題
ブログのタイトルにあるとおり、DBに登録しているバイナリーデータに対して書き込みを行います。  
実はまだ出力が未検証なので、後日そこは別の記事としてあげたいと思う所存です。

フレームワークはもちろんRuby on Railsです。

ExcelFileというモデルにbinary型のexcel_binカラムが存在するものとして話を進めていきます。  
ファイルサイズ(limit)は特段設けずにそのままで。


## まずバイナリーファイルの保存

適当なexcelファイルを準備します。  ここでは `test.xlsx`とします。  
保存してアクセスしたときに、データがちゃんと取得できているのかどうか確認するために、エクセルファイルのB2に `テスト`、シート名を`テストシート`としておきます。


```rb

excel = File.binread('該当ファイルパス/test.xlsx')
ExcelFile.create(name: 'テストエクセル', excel_bin: excel)
```

`test.xlsx`を置く場所はRailsプロジェクトの中でも別のディレクトリでもどこでもいいです。  
`File#binread`でバイナリーファイルとして読み込むときにファイルパスを指定してあげてください。
(なんの説明もなくExcelFileモデルにnameカラムがありますが、飾りみたいなもんです。気にしないでください。)  

macなら、この状態で**パンケーキと呼ばれるSequel Pro**を使い、該当のバイナリーデータをxlsxで保存すると、 `test.xlsx`と同じ内容のエクセルファイルを取得できるはずです。  
興味のある方はやってみてください。 


## RubyXLを使ってバイナリーファイルを解析

**何をするにしても一次情報を見ろ**とよくいいますが、実感しました。  

というのも、RailsをやっていないPLの下で働いている僕なのですが、PLから教えていただいた一次情報で助けられたからです。  
まだまだカスだなと、ゴミクズだなと実感しましたね。。。  

ここを見せていただきました。PLに感謝です。  
[http://www.rubydoc.info/gems/rubyXL/3.3.21/RubyXL/Parser]


`RubyXL::Parser.parse`でファイルパスを指定してやる方法は知っていたのですが、バイナリーファイルを展開する方法は知りませんでした。  むしろ、バイナリーファイルはRubyXLでは展開できないものと思っていましたが、違いました。  
`RubyXL::Parser.parse_buffer`でバイナリーファイルを展開できるようです。


```rb

excel_bin = ExcelFile.find_by(name: 'テストエクセル').excel_bin
book = RubyXL::Parser.parse_buffer(excel_bin)
worksheet = book[0]
worksheet.sheet_name #=> テストシート
worksheet[1][1].value #=> テスト
```

`RubyXL`では座標を`[y][x]`で指定していきますが、A1が`[0][0]`になります。
なので、B2は`[1][1]`。  
RubyXLで展開ができたので、あとは書き込んで出力するだけです。  
簡単ですね。  

## 最後に

一次情報を見る前には詰んでてどうしようもない状態が続いていたんですが、なんとか実装できました。  
後日、Railsのコードと一緒にまた記事にしたいなと思います。

ではでは。
kerasで「ボケて」を学習させてみる

# ボケてAI

画像識別に使われるCNNと、文章生成等に使われるRNNを組み合わせたニューラルネットワークモデルをkerasで構築する。

* ボケてから収集した「画像-ボケ」セットを学習
  * お題画像を入力すると、それに対するボケを出力してくれるはず

### CNNについて
* [ImageNet](http://www.image-net.org/)学習済みの[VGG16モデル](http://aidiary.hatenablog.com/entry/20170104/1483535144)を使用する
* VGG16はモデルの最終層で1000クラス分類を行うが、この層は利用せず、出力されたベクトルを画像の特徴量としてRNNへの入力に使用する

### RNNについて
* 文章翻訳や対話に使われる、RNN拡張の[LSTM](https://qiita.com/KojiOhki/items/89cd7b69a8a6239d67ca)による[seq2seqモデル](https://qiita.com/halhorn/items/dc10596942ef4be54af5)を使用する
* ネットワークに文章を入力する際は、形態素解析したものをベクトル化して入力する

### 今回の元ネタ
[画像からキャプチャ自動生成](https://github.com/GINK03/keras-image2text)
モデル実装は上記のものをほとんどそのまま流用している


# 開発環境

* mac OSX 10.11.6
* python 3.5(3.6でも動くと思います)
* anaconda 4.4.0

# 環境構築

### 1. anacondaインストール
https://www.anaconda.com/download/

### 2. python仮想環境作成

```
# conda create -n bokete_ai python=3.5
# source activate bokete_ai
# conda info -e
# source deactivate # 終了時
```

### 3. ライブラリ関連インストール

```
# pip install tensorflow
# pip install keras
# pip install scrapy
# pip install Pillow
# pip install pandas
# pip install mojimoji
# pip install matplotlib
```

### 4. mecabセットアップ
* [mecabインストール](http://taku910.github.io/mecab/#install-unix)
  * mecab-ipadic のconfigureはutf8で行う `./configure --with-charset=utf8`
* 新語辞書を追加
  * [Pythonからmecab-ipadic-neologdを使う](https://qiita.com/satzz/items/fec3292a9b552a693728)
* mecabインストール後 `pip install mecab-python3` を実行

### 5. jupyter notebookセットアップ
* anacondaデフォルトで入っているが、作成したpython仮想環境で動かすため仮想環境内に別途インストールする

```
# conda install jupyter
# ipython kernel install --user --name=bokete_ai --display-name=bokete_ai
# jupyter kernelspec list
Available kernels:
  bokete_ai    /Users/username/Library/Jupyter/kernels/bokete_ai
  python3      /Users/username/.pyenv/versions/anaconda3-4.4.0/share/jupyter/kernels/python3
```

# 実行

実行したソースコードは[こちら](https://github.com/teratsyk/bokete-ai)

### 1. 学習データ収集

scrapyでボケてサイトから収集。

```
# cd boketeScrapy/boketeScrapy
# scrapy bokete -o legend.csv
```

* 高品質のボケを求めて /hot, /popular, /select, /pickup, /legendから再帰的に取得したが、400件弱とディープラーニングするには少なかった
* サイトに負荷を掛けないよう10秒間隔で実行


### 2. 学習

jupyter notebookを起動して`vgg_seq2seq.ipynb`を開く。

```
# cd ../
# jupyter notebook
```

notebookの各ステップを実行していく。

##### 2-1. スクレイピングしたデータを加工して学習させる

* 入力となる画像をnp.arrayで読み込む
* 入力画像に対する出力となるボケ文言を、分かち書きしてからone-hotベクトル化する

##### 2-2. モデル構築

* 上記のモデルを流用しパラメータを若干変更した

##### 2-3. 学習実行

* mbp(core-i5/RAM8G)で4日程度かかった
* `loss=1.69, acc=0.6`程度で精度が上がらないまま収束してしまった


### 3. ボケ実行

画像を入力して出力（ボケ）を確認する。

* 新しい画像を入力してみたが、ほとんどがまともな日本語にならない...
* 学習データ内の[ボケ](https://bokete.jp/boke/58079562)に対して、学習モデルが出力したボケは`寝言 そんな 仕事 て`だった...（これでもうまくいった？方）


# 課題

* 学習データが全然足りない。せめて数千は必要？
  * 出力文章の語彙は学習データ量に比例すると思われる
* 1000クラス分類の`ImageNet`を使用しているので、未学習の物体画像（特にイラスト）は同じようなベクトルが出力され特徴量として適切でない？
  * VGG16も再学習させた方がよい？もしくは、もうネットワーク層を少なくしてみた方が特徴が出たりする？
* 画像内の文章に対応するタイプは`画像→文字`でなく、画像内部の文字列をOCRして`文字→文字`のモデルを使う必要がある

# 参考

* Chainerでちゃんと実装されている例
  * [Chainerを用いた"ボケる"ニューラルネットの実装](https://qiita.com/butsugiri/items/ac4d336c65938d9cbe57)
A-Frame.jsでスターウォーズのオープニングのVR版作ってみた


もの（クオリティは低いので脳内補完お願いします）
https://impossible-flock.glitch.me/

コード
https://glitch.com/edit/#!/impossible-flock?path=index.html:1:0


## A-Frameとは
- [公式サイト](https://aframe.io/docs/0.7.0/primitives/a-box.html)
- 基本的にA-Frame.jsを読み込んだHTMLだけでweb-VRが作れるというすぐれもの
- [Glitch](https://glitch.com/~aframe)というプレイグラウンド的なとこで試すのが一番手っ取り早い
- [A-Frame School](https://aframe.io/aframe-school/#/)というやつが基礎を学ぶのにはちょうどいい（英語だけど比較的簡単）

## 基本の抑えどころ
### `<a-box>`などの基本要素（プリミティブズ）に位置や角度などの属性（コンポーネント）を付け足して作っていく
a-boxなどの基本要素はプリミティブズと呼ばれ数十種類はある模様。
a-boxは立方体、a-skyは空全体、a-textは文字など役割がそれぞれ決まっている。
[公式サイト](https://aframe.io/docs/0.7.0/primitives/a-box.html)の左サイドバーの一番下にプリミティブズが羅列されている。
a-boxやa-sphereはわかりやすいが、名前だけではなんの形の物体なのかわからないものもあり面白い。
また、a-entityというのはHTMLでいうdivのようなものであり、要素をグルーピングしたりするのに使える。

属性はコンポーネントと呼ばれ、位置を設定する`position`や角度を設定する`rotation`などがある。
属性をコンポーネントと呼ぶのはおかしな気もするけど、属性をまとめて使いまわせたりするからそう呼んでいるのかも。

### 基本要素のsrc属性に画像のURLを貼ることで画像をVR空間に置ける
a-boxなどの要素のsrc属性に画像を貼った場合は、それらに貼り付くようにして画像が表示されるので、画像だけをVR空間に置きたい場合はa-image要素を使うといい。
また、jpgやpngではなくgltfという拡張子の3Dモデリング用画像？を専用の属性とともに使用するとそのgltfファイルのみでVR空間を表現することができる。

### GlitchのVR表示画面でCtrl+Alt+iでA-Frame用のインスペクタを表示できる
細かい調整はここで可能。

### A-Frame RegistryでA-Frameで使用できるライブラリを探せる
[A-Frame Registry](https://aframe.io/aframe-registry/)
今回のスターウォーズでも使用した宇宙のスターダストを表現したパーティクルや、テキストを動かすアニメーションはライブラリを使用している。
既存のものを使うだけでなかなか面白いことができそうではある。

### クリックなどのユーザーイベントは<a-cursor>要素と組み合わせて行う
普通のマウスカーソルはVR空間とは連携していないので、カーソル要素を作ってその要素とクリックしたい要素が重なったときにクリックすることでイベントが発生する。
例えば、下のURLでは黒い点をパネルに合わせてクリックすると周りの画像が変わるようになっている。
[360° Image Gallery](https://aframe-school-cursor.glitch.me/solution.html)

## まとめ
なのでスターウォーズOPはこれだけでできた。

- ロゴ画像、テキストなどをa-entityでまとめてrotationで斜めにしておく
- ライブラリでa-skyにパーティクル、テキストをまとめたものにアニメーションをかける
DevTools を開いたら人類滅亡

__【追記】__
__Google Chrome 66 より動画の自動再生が制限されてしまいました。__
__そのため、DevTools を開いても自動では地球は滅亡せず、大幅に UX が低下しています。__
__地球滅亡のライブ感を楽しみたい方は、Firefox, Safari など他ブラウザでご利用ください。__

__【追記2】 LT のスライドはこちら__
[<img width="512" alt="Screen Shot 2019-06-02 at 13.36.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38837/1f79dc5e-649c-f8b8-4fad-1c7ba3281694.png">](https://speakerdeck.com/diescake/devtools-wokai-itararen-lei-mie-wang)

# 何をしたの？

Chrome などの DevTools を開くと**[人類が滅亡](https://www.youtube.com/watch?v=YpYaWSj_21g)**するジョークライブラリ作ったよ！

* **devtool-meteor**
  * https://github.com/diescake/devtool-meteor
  * **[デモページ](https://devtool-meteor.firebaseapp.com/)**

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">DevTools を開いたら人類滅亡<a href="https://t.co/DOhhkHBDcG">https://t.co/DOhhkHBDcG</a> <a href="https://t.co/UYOKvTxTgy">pic.twitter.com/UYOKvTxTgy</a></p>&mdash; diescake (@pomeranian_dev) <a href="https://twitter.com/pomeranian_dev/status/952558130650537985?ref_src=twsrc%5Etfw">2018年1月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 俺にも使えるのか・・？

使い方は簡単！！
メソッドとかプロパティとかオプションはない硬派なライブラリだよ！（╹◡╹）

```shell:インストール
$ npm install --save devtool-meteor
```

```js:実装
require('devtool-meteor'); // import でも OK
```

詳細は GitHub の README.md を見てね！

# どんな力を使ったの？

[devtools-detect](https://github.com/sindresorhus/devtools-detect) というライブラリを利用して、
**DevTools の表示/非表示の切り替え**発生時に呼び出される EventListener で、
DOM のクリアと共に **YouTube の人類滅亡動画**をコンテンツエリアいっぱいに引き伸ばして自動再生させています。

## devtools-detect とは一体…？

[devtools-detect](https://github.com/sindresorhus/devtools-detect) は実装自体シンプルなので、興味があれば直接見てもらっても良いですが、
一番重要なのは下記条件文で DevTools の表示/非表示の切り替えを検出している点ですね。

```js
var isLongOuterWidth = (window.outerWidth - window.innerWidth > 160);
var isLongOuterHeight = (window.outerHeight - window.innerHeight > 160);

if (XOR(isLongOuterWidth, isLongOuterHeight)) { // XOR 
  // DevTools 開いている
} else {
  // DevTools 開いていない
}

function XOR(a, b) {
  return ( a || b ) && !( a && b );
}
```

上記コードは説明しやすいように一部改変していますが、
基本的に outerWidth と innerWidth もしくは outerHeight と innerHeight の差分を見て、
**DevTools 分の領域が存在しないか**確認するというロジックで動作しています。

なので、仕組み上 DevTools を別ウィンドウ表示にした場合は検出できず、
また、DevTools 以外にも 160px 以上の領域が生まれた場合誤爆します。

例えば、windows でめちゃくちゃスクロールバー太くしてる環境とか、

8K モニタでブラウザ全画面表示でもスクロールバーの幅が 160px 超えるかも？

固定値っぽいので超えないですね。

他には上部に JWord みたいなツールバーが5~6段にもインストールされてる環境とか、
コンテンツ領域外の要素が幅を利かせてくると怪しい。

あと、スマートデバイスのブラウザでも、
スクロール時にアドレスバーやツールバーが動的に invisible になるタイプであれば、
ブラウザ(JSEngine)の仕様によっては誤爆する環境もありそうです。

<font color="red">**【追記】
Firefox のブックマークサイドバー表示してると誤爆するそうです。
それなりにユーザがいる印象がありますので、ジョーク以外で使うのは難しいかも…**
</font>

ちなみに、このライブラリを真面目にハック対策に利用するのであれば、
DevTools を検出したからといって**目に見える変化は与えず**に、
解析を難航させる内部的な変化を加えるのが良いでしょう。

devtools-detect の回避策はいくらでもあるので、**存在自体を悟らさてはダメ**です。

# 所感＆雑記

一番最初は、DevTools をトリガーに**アナログテレビ風の砂嵐**を表示しようとしましたが、
あんまり SNS 映えしないなー、と思って**人類滅亡**させました。

他のアイデアとしては、

* 貞子が画面から出てくる
* バルバトス「ツールなんぞ使ってんじゃねぇ！！」
* オルガ「覗くんじゃねぇぞ…」

とか色々ありましたが、
やっぱり何度動作確認しても**人類滅亡**が笑えるのでこれに落ち着きました。（╹◡╹）

「[予測可能回避不可能](http://dic.nicovideo.jp/a/%E4%BA%88%E6%B8%AC%E5%8F%AF%E8%83%BD%E5%9B%9E%E9%81%BF%E4%B8%8D%E5%8F%AF%E8%83%BD)」は伊達じゃないですね。
Rspec特定のテストのみを実行する

```rb
Rspec.describe Test, type: :model do
  describe "#testA" do
    context "pattern-a" do
       ...
    end
  end

  describe "#testB" do
    context "pattern-a" do
      ... 
    end
  end
end
```

上記のようなテストがあったときに#testAのみを実行したい場合などがある
その場合

```rb
Rspec.describe Test, type: :model do
  describe "#testA", type: :doing do
    context "pattern-a" do
       ...
    end
  end

  describe "#testB" do
    context "pattern-a" do
      ... 
    end
  end
end
```

`describe "#testA", type: :doing do`のようにタグをつけてあげ、

```sh
$ bundle exec rspec --tag type:doing ファイルパス
```
これで特定のテストのみを実行できる
新しくシステムを作るときのMySQLの設定

#はじめに
実働しているシステムで`root`を使っている人もいるかと思います。しかし、普通に考えてセキュリティ的にはよろしくないですよね。
かくゆう私もこれまで「めんどくさい」、「そんなことまで考えている余裕がない」っていうので、そのまま`root`を使う形でシステムを作っていました。
脱`root`ということでこの記事を書きたいと思います。

決して`root`を使わないということではなく、システムと`root`を切り離すということをお間違え無く。

#ユーザの作成
まずは、`root`でMySQLにログインして下さい。
いつも通りの`mysql -u root -p`です。
ユーザ名を`user`、パスワードを`password`とします。
その場合、ユーザの作成は以下のコードになります。

```
CREATE USER 'user'@'localhost' IDENTIFIED BY 'password';
```

次のコードを実行してユーザが作成されているか確認しましょう。

```
SELECT User, Host FROM mysql.user;
```

#データベースの作成
もしも、使用するデータベースが既に作成されているのならば、このステップは必要ありません。

作成するデータベースを`db`とします。
実行するコードは以下です。

```
CREATE DATABASE `db`;
```

#ユーザの権限の変更
今のままでは、作成したユーザはどのデータベースにもアクセス出来ません。データベースにアクセス出来る様にしましょう。

```
GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, CREATE VIEW, SHOW VIEW ON `db`.* TO 'user'@'localhost';
```

これで、`db`内では`SELECT`、`INSERT`、`DELETE`、`CREATE TABLE`、`CREATE VIEW`、`SHOW VIEW`が出来る様になりました。

もしも、特定のテーブルにおいて権限を外したい場合は、

```
REVOKE 権限 ON `db`.`テーブル名` TO 'user'@'localhost';
```

です。
権限とテーブル名をそれぞれ置き換えて使って下さい。

権限の確認のコードは以下です。

```
SHOW GRANTS FOR 'user'@'localhost';
```

###追記
もしも、外部キーを使うのであれば、権限に`REFERENCES`が必要です。

```
GRANT REFERENCES ON `db`.* TO 'user'@'localhost';
```

このコードで外部キーに関する権限も追加出来ます。
権限の削除と同様、追加する権限のみを書けば大丈夫です。

#さいごに
ここまで終われば、`root`からログアウトして、`user`でログインし直して、一通りの作業が出来るかどうかの確認をお願いします。

ただものが作れただけでなく、少しずつ細かいところにも気を配っていこうと思っています。

#参考リスト
- [MySQLの使い方](https://www.dbonline.jp/mysql/)
- [GRANTリファレンス](https://dev.mysql.com/doc/refman/5.6/ja/grant.html)
TeXを利用してpdfを結合する

TeXを持っているのに、なぜPDFの結合に別のプログラムを導入しなければならないのか？

基本的には[ここ](https://blog.dbrgn.ch/2013/8/14/merge-multiple-pdfs/)を読んだ結果をメモしているだけです。

# 必要条件

1. TeXがインストールされていること
2. TeXに[pdfpages](https://ctan.org/tex-archive/macros/latex/contrib/pdfpages/)パッケージがインストールされていること（Mac用のTeX Liveにはデフォルトでバンドルされているっぽい）

# 使用法
`pdfjam`なるコマンドが使えます。
というかコマンドの使い方そのものです。

```shell:
pdfjam input1.pdf input2.pdf input3.pdf -o output.pdf
```

(2018.2.14追記) 元となるファイルとしては、PDFファイルのほかにもPNGやJPEG形式のファイルも受け付けます。というわけで、スキャンしてつくったJPEGファイルを結合するのにも使えます。

# その他
`GhostScript`には`pdftk`なるコマンドがあるようですが、個人的にコマンドの書き方が恐くて使っていません。詳しくは最初に挙げたページを参照してください。
rsyncの送信先パスにはシンボリックリンクを指定できないらしい

日本語情報が皆無だったので備忘録として残しておく。

## やろうとしたこと

SynologyのNASにファイルをバックアップするため、以下のようなコマンドでバックアップを試みた。
※ホスト名やディレクトリ名は変更している

```bash
rsync -aHvhzcP --no-o --no-g --chmod=a+rwx,Da+rwx \
  --exclude ".*" -e "ssh -p 51764" \
  --iconv=UTF8-MAC,UTF-8 \
  ./data-dir-01976 \
  username@example.local:/var/services/video/my-movies/ -n
```

`data-dir-01976`ディレクトリを、NAS側の`/var/services/video/my-movies/`ディレクトリ内にバックアップするコマンド。

## 問題発生

だがこれを実行したところ、このようなエラーを吐いてしまった

```shell-session
$ rsync -aHvhzcP --no-o --no-g --chmod=a+rwx,Da+rwx \
>   --exclude ".*" -e "ssh -p 59612" \
>   --iconv=UTF8-MAC,UTF-8 \
>   ./data-dir-01976 \
>   username@example.local:/var/services/video/my-movies/ -n
username@example.local's password: 
sending incremental file list
rsync: [sender] write error: Broken pipe (32)
ERROR: module is read only
rsync error: syntax or usage error (code 1) at main.c(1131) [Receiver=3.0.9]
rsync error: error in socket IO (code 10) at io.c(820) [sender=3.1.2]
```

NAS側のsshやrsyncはちゃんと有効にしている。実際、以前まではrsyncでバックアップできていたのだ。

## 原因

タイトルで既にネタバレしてしまっているが、この問題の原因は`/var/services/video/my-movies/`がシンボリックリンクであることが原因である。

SynologyのNASは、データボリュームへのシンボリックリンクが`/var/services`ディレクトリ以下に作成される。

```shell-session
username@ExampleNasServer:/var/services$ ls -l
total 0
lrwxrwxrwx  1 root root 18 Aug 30 01:58 download -> /volume1/@download
lrwxrwxrwx+ 1 root root 14 Jan 14 22:05 homes -> /volume1/homes
lrwxrwxrwx+ 1 root root 14 Aug 30 02:57 music -> /volume1/music
lrwxrwxrwx+ 1 root root 18 Jan 14 21:40 NetBackup -> /volume1/NetBackup
lrwxrwxrwx  1 root root 24 Aug 30 02:36 pgsql -> /volume1/@database/pgsql
lrwxrwxrwx+ 1 root root 14 Aug 30 02:57 photo -> /volume1/photo
lrwxrwxrwx  1 root root 13 Jan 14 22:05 tmp -> /volume1/@tmp
lrwxrwxrwx+ 1 root root 14 Aug 30 02:57 video -> /volume1/video
```

`/volume1/video`が実際のパスだが、`volume1`などといういかにも環境依存しそうな文字列が含まれるため、`/var/services/video`に変更していた。
それが裏目に出てしまったらしい。

## 解決策

解決方法は至極単純である。リンク先の実体パスに変更すればいいのだ。

```bash
rsync -aHvhzcP --no-o --no-g --chmod=a+rwx,Da+rwx \
  --exclude ".*" -e "ssh -p 51764" \
  --iconv=UTF8-MAC,UTF-8 \
  ./data-dir-01976 \
  username@example.local:/volume1/video/my-movies/ -n
```

```diff:差分
  rsync -aHvhzcP --no-o --no-g --chmod=a+rwx,Da+rwx \
    --exclude ".*" -e "ssh -p 51764" \
    --iconv=UTF8-MAC,UTF-8 \
    ./data-dir-01976 \
-   username@example.local:/var/services/video/my-movies/ -n
+   username@example.local:/volume1/video/my-movies/ -n
```

## 参考サイト

* [rsync preserve symlink as destination - Stack Overflow](https://stackoverflow.com/questions/45623419/rsync-preserve-symlink-as-destination)
  シンボリックリンクで指定した宛先パスに送りたいが、リンクが上書きされて新しいディレクトリにされてしまうという質問。2017-08-10の質問だが、今のところ回答が**１件もない**。（2018年1月14日時点）

* [symbolic link - rsync doesn't resolve target symlink to directory - Ask Ubuntu](https://askubuntu.com/questions/723714/rsync-doesnt-resolve-target-symlink-to-directory)
  rsyncがターゲットパスのシンボリックリンクを解決しないという質問。2016-01-21の質問だが、こちらも回答が**１件もない**。（2018年1月14日時点）

## 本当に指定できないの？

少なくとも私が調べた限り、指定できるという情報は見つけられていない。
上述した質問に対する回答が無いことからも、おそらくそんな手段は存在しないのだと思う。
が、もしあるならば、コメント欄で是非教えてほしい。
声優のオープンデータを作ってみた

声優のオープンデータがなかったので、
Linked Open Dataとして作ってみました。

声優とアニメ作品とキャラクターのデータを作りました。

また、声優の一番気になる情報といえば声！
そこで、声優のCV(キャスティングボイス)を解析し、音声の特徴量を解析してデータ化しました。

Linked Open Dataとは構造化されたデータ(Linked Data）のオープンデータです。
Qiita内にLinked Dataについて記事があったのでこちらを参照してください。
<a href="https://qiita.com/pika_shi/items/eb56fc205e2d670062ae">Wikipedia からスクレイピングして… とか言ってる人におすすめしたい，DBPedia からの情報抽出</a>

#データについて
作成するにあたり、Wikipediaのデータを用いました。
WikipediaのページはCC-Byで公開されているので用いました。
　参考：<a href="https://ja.wikipedia.org/wiki/Wikipedia:ウィキペディアを二次利用する">Wikipedia:ウィキペディアを二次利用する</a>
声優のサンプルボイスは、以下の事務所のサイトで公開されているサンプルボイスを基に解析しました。
・EARLYWING
・大沢事務所
・81プロデュース
・アイムエンタープライズ
・マウスプロモーション
・青二プロダクション
・アクロスエンタテインメント
・賢プロダクション
・アーツビジョン

作成したデータのエンドポイントはこちらになります。
http://seiyu-lod.org/sparql

#スキーマ説明
以下がスキーマ図です。
◯はURI、□はリテラルを示しています。
図中で使われているprefixは以下です。
・prefix rdfs:  <http://www.w3.org/2000/01/rdf-schema#> 
・prefix so:    <http://seiyu-lod.org/ontology/> 

<img width="500" alt="スクリーンショット 2018-01-15 0.02.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/230885/bcc9a5e5-8c21-44fa-df62-2cc459ee764a.png">


以下のデータをRDF化しています。
・声優のサンプルボイスの特徴量
・声優が参加したアニメ
　・アニメのスタッフ情報（監督・制作など）
　　　※図中では監督・制作・音響監督のみですが、実際のデータは多数あります
・声優が担当したキャラクター

独自定義したプロパティと説明です。

| プロパティ名 | 説明 |
|:-----------|:------------|
| so:sampleVoice | サンプルボイス |
| so:join |参加した作品 |
| so:voice | 声を担当したキャラクター |
| so:voicedBy |声を担当した人 |
| so:mfcc | メル周波数ケプストラム係数 (MFCC)の数値  |
| so:series |登場する作品 |
| so:staff |アニメ作品のスタッフ |
| so:監督,so:音響,etc |so:staffのサブプロパティ|

#クエリ例
###「上坂すみれ」が参加した作品一覧

```
select distinct ?anime_name where {
 ?seiyu_uri rdfs:label "上坂すみれ"@ja . 
 ?seiyu_uri <http://seiyu-lod.org/ontology/join> ?anime.
 ?anime a <http://seiyu-lod.org/ontology/TVAnime>.
 ?anime rdfs:label ?anime_name.
}
```

※随時追加予定

# 取得した特徴量
音声の特徴量として、メル周波数ケプストラム係数 (MFCC) を取得しました。
MFCCは、人間の音声知覚の特徴を考慮し、声道特性を表す特徴量です。

# 解析方法
MFCCの解析には、[librosa](https://github.com/librosa/librosa)を使いました。
MFCCを扱いやすいよう12次元に圧縮し、音の高さを軸に平均と分散を算出します。

```python:sample.py
import librosa
import numpy as np

args = sys.argv
filepath = './hoge.wav'

y, sr = librosa.load(filepath)
mfcc = librosa.feature.mfcc(y=y, sr=sr, n_mfcc=12)
result = np.zeros((mfcc.shape[0], 2))
result[:,0] = np.mean(mfcc, axis=1)
result[:,1] = np.var(mfcc, axis=1)

print result
```

出力例として、[吉岡茉祐](http://www.81produce.co.jp/list.cgi?lady+7522051161730)さんのサンプルボイス（ナレーション）から取得したMFCCをあげます。

```tsv:result
[[-4.24218419e+02,2.78179371e+04],
[3.16817718e+01,2.48903506e+03],
[-3.86587320e+00,9.25306136e+02],
[1.69041341e+00,7.31437290e+02],
[-1.00446837e+01,4.51986376e+02],
[-7.58551697e+00,2.82802210e+02],
[-4.26236357e+00,1.28497457e+02],
[-1.03372452e+01,2.44193435e+02],
[-1.12978920e+01,1.98538023e+02],
[-2.15735125e+00,8.91169019e+01],
[-1.21181751e+01,2.04762452e+02],
[-2.50601151e+00,1.13155405e+02]]
```
ubuntuでufw使ったらLXDコンテナから外部に接続できなかった件

#サーバ
ubuntu 16.04
LXD 2.21
ufw 0.35

#起きたこと
ufwとかインストールしてLXDコンテナを立ちあげ、
いざコンテナでいろいろうやろうとしたら、外に繋がらなかった！！

#原因
シンプルにufwの設定不足
natの設定が入っていなかった。

#対応内容
nat設定を追加してあげた。

```bash:/etc/ufw/before.rules
～～～省略～～～
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 【コンテナのネットワークアドレス 192.168.1.0とか】/24 -o 【外部につながるインターフェイス eth0とか】 -j MASQUERADE
COMMIT
```

以前iptablesでLXD運用してたときは、自動的に上記設定が入っていたから気づかなかった。。。
MailtrapでLaravelの簡単メール送信テスト

# 概要

ローカル開発環境でのメール送信設定をしようとするとMailcatcherを入れたりとか、いろいろ面倒ですが、Laravelではとても簡単に行えます。
方法はいくつかありますが、Mailtrapのサービスを利用した方法がとても簡単だったのでご紹介。

# Mailtrapの設定

## アカウント作成

https://mailtrap.io

GithubアカウントでSign upできます。
開発用アカウントを集約できてありがたい。

## 認証情報の確認

「Demo inbox」を開くと接続情報が表示されます。

![mailtrap-io-setting.png](https://qiita-image-store.s3.amazonaws.com/0/45374/ed6c99b8-1163-a297-2f74-4ded6e015274.png)


## Laravelの設定

今回はローカル開発環境で使うので　`.env`ファイルに設定します。　

Laravel5.4では初期値はこんなかんじです。

```#.env　初期値
MAIL_DRIVER=smtp
MAIL_HOST=mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
```

設定するのは「MAIL_PORT」「MAIL_USERNAME」「MAIL_PASSWORD」の３つ。

```#.env
MAIL_DRIVER=smtp
MAIL_HOST=[smtp.mailtrap.io]
MAIL_PORT=2525
MAIL_USERNAME=[MailtrapのUsername]
MAIL_PASSWORD=[MailtrapのPassword]
MAIL_ENCRYPTION=null
```

そしてartisanコマンドで設定を反映。

`$ php artisan config:cache`

# Mailableで実際に送信

Laravelのメール送信の実装も簡単です。
メールクラスもコマンドで簡単生成。

`php artisan make:mail TestMail`

するとこんなファイルが生成されます。

```#/app/Mail/TestMail.php
<?php

namespace App\Mail;

use Illuminate\Bus\Queueable;
use Illuminate\Mail\Mailable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Queue\ShouldQueue;

class TestMail extends Mailable
{
    use Queueable, SerializesModels;

    /**
     * Create a new message instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Build the message.
     *
     * @return $this
     */
    public function build()
    {
        return $this->view('view.name');
    }
}
```

メールを送信できるように`build()`メソッドちょい変更。

```
public function build()
{
    return $this
        ->from('example@example.com')
        ->subject('テスト送信完了')
        ->view('emails.test');
}
```

## メールテンプレートファイルの作成

`->view('emails.test')`は`/resources/views/`配下のパスを`.`区切りで表記する規則になっています。

```#/resources/views/emails/test.blade.php
テスト送信の本文
```

## 送信処理の呼び出し

送信先メールアドレスを設定して、送信するメールクラスのインスタンスを`send()`メソッドの引数として呼び出すだけです。

```#/app/Http/Controllers/TestMailController.php
Mail::to('test@example.com')
    ->send(new TestMail());
```

## Mailtrapで送信確認

無事送れていました。

<img width="709" alt="mailtrap-io-send.png" src="https://qiita-image-store.s3.amazonaws.com/0/45374/2fd71e40-b66b-5bb4-2ae3-a6b7d2818feb.png">


## ちょっとハマりどころ
Viewファイルがキャッシュされるのか、最初はこんなエラーが出てうまく送信されず。

```
local.ERROR: View [emails.test] not found.
```

設定ファイルのキャッシュをリセットしたらViewファイルを認識してくれました。

```
$ php artisan config:cache
```
HTMLでdiffを表示させてみる

# [diff.js](https://github.com/kpdecker/jsdiff)と[diff2html](https://github.com/rtfpessoa/diff2html)を用いてdiff画面を表示してみました。

## 概要

[diff.js](https://github.com/kpdecker/jsdiff)を用いて[unified diff](https://ja.wikipedia.org/wiki/Diff#%E3%83%A6%E3%83%8B%E3%83%95%E3%82%A1%E3%82%A4%E3%83%89%E5%BD%A2%E5%BC%8F_(Unified_format))を作成して、それを[diff2html](https://github.com/rtfpessoa/diff2html)に渡して表示しているだけです。


## ソース

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>vue_pager</title>
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/diff2html/2.3.3/diff2html.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jsdiff/3.4.0/diff.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/diff2html/2.3.3/diff2html.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/diff2html/2.3.3/diff2html-ui.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
    const unifiedDiff = JsDiff.createPatch("fileName", "a\nb\nc\d\ne\n\nf", "a\nb\nac\d\ne\n\n\nf", "test", "test");
    const diff2htmlUi = new Diff2HtmlUI({diff: unifiedDiff});
    diff2htmlUi.draw('#app', {inputFormat: 'json', showFiles: true, matching: 'lines'});
});
</script>
</head>
<body>
<div id="app">
</div>
</body>
</html>
```

## 確認

https://jsfiddle.net/ejt9x6wo/

## 参考

* https://github.com/kpdecker/jsdiff#api
* https://github.com/rtfpessoa/diff2html#how-to-use
sedコマンドで正規表現を置換する

#sedコマンド

bashにはファイル内の文字列を置換できるsedコマンドがある.
しかし,正規表現の文字列を置換する場合には少々厄介だ.
備忘録として正規表現の置換方法をまとめておく.

#コマンドの前に

テスト用に以下のスクリプトを用意してみた.

```shell-session:test.c
#include<stdio.h>

int main(void){

        char *filename = "tonarino/kyakuha/yokukaki/kuukyakuda";

        return 0;
}

```

スクリプト中の`tonarino/kyakuha/yokukaki/kuukyakuda`を`namamugi/namagome/namatamago`に置換したいとする.

#%で区切る

上記の置換をsedコマンドで行いたい場合,対象の文字列を%で区切ることで置換可能となる.

```
sed -i -e 's%tonarino/kyakuha/yokukaki/kuukyakuda%namamugi/namagome/namatamago%g' *
```
これで置換できる.

```shell-session:test.c
#include<stdio.h>

int main(void){

        char *filename = "namamugi/namagome/namatamago";

        return 0;
}

```
【js】firefoxでfocusイベントが動かない

#概要
キー入力があった際に、フォーカスを変えるということをしたかったのですが、安直にはいかなかったたので回避策を書く。(考察しながら書いてますが、間違っている部分もあるかと思います。)
#どうしてこうなるのか
firefoxではイベント中に別のイベントを呼び出すことができない模様。
そのため、onkeydown()のイベント中で別のイベントのfocus()を呼び出すことができない。
#回避策
```javascript
setTimeout(function(){
  セレクタ名.focus()
},0);
```
onkeydown()のイベントからfocus()の部分をsettimeoutを使うことで非同期処理にしてあげ、onkeydown()からfocus()が発生する状況を擬似的に回避してあげる。
settimeoutには、0を指定しているが失敗する場合は50や100などにしてfocus()が発生するタイミングを遅らせてあげる。

#参考資料
https://gist.github.com/iguu/5575105
cpuminerを使ってUbuntuでKotoのマイニングをする

# 環境
```
- Ubuntu 16.04 x64
```

# 前提
- KotoのWallet及びKotoのアドレスを持っていること
- （ソロマイニングではなく）mining poolを利用してマイングをする

*Kotoのアドレスはkから始まる文字列：例）k1DHvfdwzJ1rCXTEbhg3PxFAVaR5TRMiw84*

# cpuminer導入手順
aptを更新する。

```
# sudo apt-update
# sudo apt-upgrade
```
gitをインストールする。

```
# sudo apt-get install git
```
cpuminerのレポジトリをcloneする。

```
# sudo git clone https://github.com/noncepool/cpuminer-yescrypt
```
cpuminerのディレクトリに移動する。

```
# cd cpuminer-yescrypt
```
cpuminerをビルドする。

```
# sudo apt-get install build-essential libcurl4-openssl-dev gcc-mingw-w64 automake gcc make
# sudo ./autogen.sh
# sudo ./configure CFLAGS="-O3 -march=native -funroll-loops -fomit-frame-pointer"
# sudo make
```

# cpuminer実行手順
```
# nohup ./minerd -a yescrypt -o stratum+tcp://jp.kotopool.work:3333 -u k1DHvfdwzJ1rCXTEbhg3PxFAVaR5TRMiw84 -p password &
```
*- アドレスは自分のものに置き換える。*
*- この例ではマイニングプールにkotopoolを利用している。*

実行結果はnohup.outに書き込まれる。マイニングが成功すると（yay!!!）が返される。

```
# tail -f nohup.out 
[2018-01-14 03:43:18] 1 miner threads started, using 'yescrypt' algorithm.
[2018-01-14 03:43:18] Starting Stratum on stratum+tcp://jp.kotopool.work:3333
[2018-01-14 03:43:19] Stratum requested work restart
[2018-01-14 03:43:26] Stratum requested work restart
[2018-01-14 03:43:26] thread 0: 3704 hashes, 0.53 khash/s
[2018-01-14 03:43:28] Stratum requested work restart
[2018-01-14 03:43:28] thread 0: 1085 hashes, 0.54 khash/s
[2018-01-14 03:43:29] thread 0: 236 hashes, 0.59 khash/s
[2018-01-14 03:43:29] accepted: 1/1 (100.00%), 0.59 khash/s (yay!!!)
[2018-01-14 03:44:33] thread 0: 35556 hashes, 0.55 khash/s
[2018-01-14 03:44:33] accepted: 2/2 (100.00%), 0.55 khash/s (yay!!!)
```
*この記事の手順は、[Vultr](https://www.vultr.com/?ref=7305700)に構築した下記イメージ上で確認している。*
*- Ubuntu 16.04 x64*
*- 25 GB SSD*
*- 1CPU*
*- 1024MB Memory*
*なお、2018年1月現在、この環境では0.45〜0.6khash/s程度出ている。*
*※ VPSを利用する場合、他の利用者に迷惑がかからないよう、cpulimitなどのツールを利用することで、CPU使用率を抑えるようにすることに留意する。*
【Sublime Text3】 Emmet使用時に ctrl + e での展開と行末への移動を両立させる

#はじめに
Sublime Text3 ではEmmetの展開は ctrl + e と Tab に設定されています。しかし、ctrl + e は行末への移動に使いますし、Tabも別の用途で使っているケースがあると思います（私はオートコンプリートの候補選択に割り当てています）。

解決策として、 ctrl + e を無効化して Tab だけで展開する方法（参考: [EmmetとSublime Textとctrl+e](https://liginc.co.jp/programmer/archives/5352)）や、別のキーに割り当てる方法（参考:[【技術メモ】SublimeTextでEmmetの展開をcommand+eにする](http://monologue.hatenadiary.jp/entry/2013/08/20/003712)）などがありますが、

- なるべくデフォルトのキーを使いたい
- ショートカットで使うキーを増やしたくない

と言う理由で、ctrl + e での展開と行末への移動を両立させることを考えてみます。

環境
OS: MacOS High Sierra
Sublime Text3: Version 3.0, Build 3143
Emmet: VERSION 2017.03.23.21.16.14

#方法
少し考えてみると

- Emmetで展開したいとき、大抵の場合カーソルは行末にある。
- 行末にカーソルがあるときは行末に移動する必要はない。

ということで、カーソルが行末にあるかどうかで条件分けをすれば良さそうです。

まず、Emmetのデフォルトの ctrl + e での展開を無効にします。

メニューから
Sublime Text -> Preferences -> Package Settings -> Emmet -> Setting - Users
を開き、以下のように記述します。

```json:Emmet.sublime-settings
{
	"disabled_keymap_actions": "expand_abbreviation"
}
```

なお、Tabによる展開も無効にしたい場合は

```json:Emmet.sublime-settings
{
	"disabled_keymap_actions": "expand_abbreviation, expand_abbreviation_by_tab"
}
```

とすればよいはずなのですが、私の環境ではなぜか無効にできませんでした。今のところ特に困っていないのでそのままにしています。

次に、カーソルが行末にあるときだけEmmetの展開を行うようにします。

メニューから
Sublime Text -> Preferences -> Key Bindings
を選択すると Default と User の2つの keymap ファイルが開きますが、 User の方に以下の記載を追加します。


```json:Default.sublime-keymap
{
    "keys": ["ctrl+e"],
    "args": {
        "action": "expand_abbreviation"
    },
    "command": "run_emmet_action",
    "context": [
        { "key": "following_text", "operator": "regex_match", "operand": "$" }
    ]
}
```

"context" で、カーソルの後が行末かどうかを正規表現で調べています。

これで、カーソルが行末にないときは行末に移動、行末にあるときはEmmetで展開ができるようになりました。

#終わりに
ちょっとした小ネタですが、自前のショートカットを設定する際、カーソルの位置や状態に応じて処理を分けるのは色々と応用が利くのではないかと思います。
react互換ライブラリnervの開発状況

https://nerv.aotu.io/

>A blazing fast React alternative, compatible with IE8 and React 16.

この謳い文句をどう受け取ればよいのかわからなかったが、この辺をフォローするgithub issueがあった。

- [What's the tradeoff? · Issue \#10 · NervJS/nerv](https://github.com/NervJS/nerv/issues/10)
    - [nervチームの人のレス](https://github.com/NervJS/nerv/issues/10#issuecomment-356913486)が有益

「Infernoのreact互換versionが欲しくて作ったのね」と納得したのでメモ

## react互換ライブラリ

webpackの`config.resolve.alias`にセットするだけで置き換えできるように作られてる

```js
{
  // ...
  resolve: {
    alias: {
      'react': 'nervjs',
      'react-dom': 'nervjs',
      // Not necessary unless you consume a module using `createClass`
      'create-react-class': "nerv-create-class"
    }
  }
  // ...
}
```

## nerv開発の動機

- Reactのライセンスの問題
- IE8サポート
- 既存ライブラリ（preact, inferno）では要件クリアできず

## ライセンスの問題

- nerv開発を考えてるとき、MITライセンスではなかった
    - 現時点ではMITに変わったのでfix済ではないかと
    - [Facebook Dropping Patent Clause \| Matt Mullenweg](https://ma.tt/2017/09/facebook-dropping-patent-clause/)

## IE8サポート

- ~~いまのとこ詳細についてコメントない~~[言及されてた](https://github.com/NervJS/nerv/issues/10#issuecomment-361074342)
    - windows XPとIE8が動くデバイスが結構ある中国ではサポートが必要と判断、と
    - 先進国ならサポート不要、と
- 開発元であるJD.com（中国でのamazonクローンという紹介が多い）がECビジネスやってる関係で必要？

## 既存ライブラリでは要件満たされず

### preact

- preactチームの開発方針が合わず
- react完全互換よりも、ファイルサイズ軽量化に力点
- 重要なPull Requestでも「コード量多い」という理由でrejectされる文化

### inferno

- react互換ではないのでNG
- reactとは独自のecosystemを作ることを選んでる
- react-likeで軽量・高速なライブラリ
- 実装はかなり取り入れてるとのこと
    - diffアルゴリズム、event delegationなど
    - infernoがなければ、現時点でここまでnervは実装できなかった、と回答

####（参考） [Inferno with Dominic Gannaway \| Software Engineering Daily](https://softwareengineeringdaily.com/2017/01/19/inferno-with-dominic-gannaway/)

- Dominicがゲスト回のpodcast
- Fintech系スタートアップに在籍してたときにmobile向けのSPA開発をしてて、reactだと速度とファイルサイズがアプリの要件をクリアできなかったので、Inferno作ったと話をしてる
- Dominicは2016年末にfecebook入りして、Infernoのメイン開発者ではなくなっている



## 英語堪能ではないが故に情報出すスピードが遅い

- 色眼鏡で見られる要因にもなってるがこの辺は共感できた
- READMEで色々間違いしてて申し訳無いとレスしてる
- 「何故IE8サポート」という部分もそのうちupdateされると予想

## TODOの大事そうなやつ

TODOは色々あるがこの２つがクリアされると、検討する人が増えるかと

- react公式のunit testに全部パスすること
- ベンチマークの充実

--
追記。中の人のリプライからいくつか拾った

## diffアルゴリズムは、infernoではくiviのものに影響

- prefixing/suffixingというテクニックと、[LISアルゴリズム](https://en.wikipedia.org/wiki/Longest_increasing_subsequence)がiviのdiffアルゴリズムの高速化を実現している
- nerv初期は、scala.jsで書かれた仮想dom実装（[Meduzz/virtual-dom](https://github.com/Meduzz/virtual-dom)）を使っていたが、iviの方が性能良いので途中かから切り替えた、とのこと
- https://github.com/NervJS/nerv/issues/10#issuecomment-361074342
Eclipseのファイルツリーの部分の文字を手っ取り早く大きくする

#内容
Eclipseのファイルツリーの部分の文字を手っ取り早く大きくする方法について書きます。

[以前の記事](https://qiita.com/shirohanada/items/96ae4a7b05f4675106e4)で書いたように元々ある設定にはこの部分を大きくする設定がなくて困ってました。
この Package Explorer と Outline 部分↓
<img width="1392" alt="スクリーンショット 2017-11-18 11.24.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/0ed796eb-8618-aa1a-a9f2-c972ed7f8c26.png">

きちんとやるにはCSSをいじれば良いということを教えていただいたのですがとりあえず簡易的に治す方法があったので書いておきます。

# 簡単な直し方
### 1. Jeeeyul's Eclipse Themesというプラグインを入れる。
http://marketplace.eclipse.org/content/jeeeyuls-eclipse-themes#group-details
ここにあるんですけどEclipse内のマーケットプレイスから検索して出てこないときはColor IDE Pack というのにセットになっているの丸ごと入れしまうと良いかもしれません。（私はそうしました）
<img width="725" alt="スクリーンショット 2018-01-14 21.12.52.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/f81dc51b-4491-5253-b431-48bfbf6b79f2.png">

### 2. Preferenceからfontの設定を付け加える
Jeeeyul's Eclipse Themesがインストールされたら設定のAppearanceのところにJeeeyul's Eclipse Themesの設定が追加されています。
<img width="686" alt="スクリーンショット 2018-01-14 21.16.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/540b1ac6-df63-5571-3920-084a53e89113.png">

ここのCustomのところに
`.MPart Tree{
  font-size: 13;
}`
と書きます。
<img width="490" alt="スクリーンショット 2018-01-14 21.19.53.png" src="https://qiita-image-store.s3.amazonaws.com/0/147926/465a0f7f-225f-8c18-9faf-c43f6ef53571.png">
書いたらApplyして終わりです。
要するに直接CSSいじればいいところをわざわざThemaプラグイン入れていじってるだけなんですが該当部分を探さなくてもいいので直に設定ファイルいじるの苦手な方とかには良いんじゃないでしょうか。別に上のプラグインにこだわる必要は全くないです。あくまで一例としてご参考になれば幸いです。

ではでは(・ω・)ノシ
中学レベルの数学（まずは言葉の意味から）

社会人になって10年以上。
久しぶりに数学を勉強する。
しかも、中学レベルから。
以下は個人的なメモです。
言葉の定義を完全に忘れているので、まずはそこから勉強します。

### 因数分解
式を積の形に分解すること。
素数の積の形に分解することを`素因数分解`という。
式を構成する一つ一つのものと`因子`または`因数`という。
### 展開
式の積を和の形に展開すること。
式を構成する一つ一つのものと`項`という。

### 恒等式
xにどんな値を代入しても成り立っている式。

### 方程式
xにある数を代入すると成り立つ式。


本当に中学レベルである。
いつの日にか数学検定を受けたい。。。
GoogleアシスタントをAlexa Skillにして「アレクサ、オーケーグーグルで天気を調べて」をGoogleアシスタントの声で応答する

前回「[GoogleアシスタントをAlexa Skillにして「アレクサ、オーケーグーグルで天気を調べて」を実現する](https://qiita.com/moritalous/items/c39fe6b07f57bc0b79f4)」という投稿をしました。

少し改良し、Googleアシスタントの声で応答を返すように改良しました。

こんな感じです。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/iQ97iNKTwp">https://t.co/iQ97iNKTwp</a></p>&mdash; moritalous (@moritalous) <a href="https://twitter.com/moritalous/status/952511586391871488?ref_src=twsrc%5Etfw">2018年1月14日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 処理の流れ

1. Echoに話しかける
2. Skill Kit(AWS Lambda)にリクエストが来る
  1. Googleアシスタントにリクエストを投げる
  2. Googleアシスタントからレスポンス（音声・テキスト）が返却される
  3. 音声を一度tmp領域にファイル出力する
  4. ffmpegでAlexaのフォーマットに変換する
  5. 変換した音声ファイルをS3にアップロードする（バケットはパブリック公開しておく）
  6. S3にアップロードした音声ファイルのURLをaudioタグに入れたSSMLレスポンスを返却する
3. EchoがGoogleアシスタントの声で返事をする

長くなりそうなので、要点だけ解説します。
ソースコードは[こちら](https://github.com/moritalous/Alexa-GoogleAssistant-Skill/blob/master/lambda_function_v2.py)

## Googleアシスタントからのレスポンスをファイルに出力する

Googleアシスタントのレスポンス中の`resp.audio_out.audio_data`が複数に分割されて取得されるので、連結してファイルに出力します。

```python3
response_audio_data = b''
for resp in self.assistant.Assist(iter_assist_requests(),
                                  self.deadline):
    if resp.audio_out.audio_data:
        response_audio_data += resp.audio_out.audio_data
```

```python3
def save_file(output_path, binary):
    with open(output_path, "wb") as fout:          
            fout.write(binary)
```

## 音声ファイルをAlexaのフォーマットに変換する

Googleアシスタントのレスポンスは、mp3で取得できますが、Alexaが求める要件は以下の用になっています。

[音声ファイルをAlexaに適した形式に変換する](https://developer.amazon.com/ja/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html#h3_converting_mp3)

> 必要に応じて、変換ソフトウェアを使用してMP3ファイルを必要なコーデックバージョン（MPEGバージョン2）とビットレート（48 kbps）に変換してください。

丁寧にffmpegのパラメーターの記述もあります。

```sh
ffmpeg -i <input-file> -ac 2 -codec:a libmp3lame -b:a 48k -ar 16000 <output-file.mp3>
```

ffmpegはLambdaの環境には準備されていないので、デプロイパッケージに含める必要があります。
ffmpegは [ここ](https://www.ffmpeg.org/download.html) の「Linux Static Builds」のリンク先から`x86_64 build`のものを取得しました。
取得したファイルの中にある、`ffmpeg`バイナリーのみを、デプロイパッケージのルートに格納されるように圧縮します。

Pythonのプログラム中でffmpegを呼び出す部分はこんな感じです。

```python3
def convert(input_path, output_path):
    try:
        command = './ffmpeg -i '+input_path+' -ac 2 -codec:a libmp3lame -b:a 48k -ar 16000 -af volume=2.0 ' + output_path
        output = subprocess.check_output(
            command, stderr=subprocess.STDOUT, shell=True, timeout=3,
            universal_newlines=True)
    except subprocess.CalledProcessError as exc:
        print("Status : FAIL", exc.returncode, exc.output)
    else:
        print("Output: \n{}\n".format(output))
```


つづく
rails　Herokuでrails db:migrate時に突然エラー発生！！　postgresqlバージョン問題　

#概要
Herokuを利用してアプリを公開しているが、いつも通りモデルを追加してデプロイし、```rails db:migrate```をしたら以下のようなエラーが発生！

```
Gem::LoadError: Specified 'postgresql' for database adapter, but the gem is not loaded. Add `gem 'pg'` to your Gemfile (and ensure its version is at the minimum required by ActiveRecord).
```

herokuでは、mySQLは使用できず、postgresqlを使用することが推奨されている。
そのため、gemfileにはpgを追加して、postgresqlを使用している。
この環境で今まで動いていたのにいきなりエラーを吐くようになってしまった...
確認してもgem にはpgが書かれているし、エラーログを見てもpgのインストール自体は正常にされている。

いろいろ調べた結果、解決できたので記事にまとめます。
参考サイト：[Herokuデプロイ後にdb:migrateが失敗した時の状況とやったこと](http://sakura-bird1.hatenablog.com/entry/2017/03/28/151441)
#原因
原因を簡潔に言うと、pgのバージョンが問題でした。
herokuを使用し始めたときに、gemfileにpgを追加したが、その時にバージョンを指定いていなかった。

```rb:Gemfile.rb
gem 'pg', group: :production
```
こんな感じ。
そして、herokuではデプロイ毎にbundle installが行われる仕様？のようで、いつしかpgのバージョンがアップデートされて、herokuが対応していないものになったらしい。
（ログを確認すると、 ```pg 0.21.0```がインストールされていた。）

なので、対応しているバージョンを指定してインストールする必要があった。
今回は、対応している中で一番最新（っぽい）```pg 0.19.0```をインストールしたらうまくいった。
やり方は、gemfileを以下のように書き替える。

```rb:Gemfile.rb
gem 'pg', '~> 0.19.0', group: :production
```
無事解決！！
いつから問題が起きていたのだろうか...

#感想
herokuを使っていると、たまにこのようなエラーに遭遇して焦る。
そして、いままでは、新しいherokuのアプリを作成してそちらに移行したり、データベースをリセットするなどして無理やり解決してきた。笑

しかし、今回は粘って調べた結果、無事解決することができてよかった。
経験値が増えました。

そして、この記事が同様の問題で困っている人の助けになれば幸いです。
Meltdown 脆弱性と緩和策について

## メモリー保護機能とは

現代のコンピューターシステムには、メモリー保護機能が実装されている。

メモリー保護機能の目的は、

* システムの中核部分を、故意や過失による干渉から保護し、システムの安定性や安全性を確保する

* 複数のユーザーがシステムを使用するような場合、他のユーザーのプライベートな情報にアクセスできないように保護する

というものがある。後者の機能は、個人専用のシステムにおいても、ネットワーク経由からの攻撃を緩和する為に利用されている。

メモリー保護機能は、ＯＳによって実現されるが、現代のプロセッサーではメモリー保護の実装を支援するため、以下のような機能を備えている。

* スーパーバイザーモードとユーザーモード

* MMU


スーパーバイザーモードとは、特権的な命令を実行できるモードで、ＯＳのカーネルコードを実行するモードとして使用されている。そのため、特権モードや、カーネルモードと呼ばれることがある。
また、スーパーバイザーモードでのみアクセスできるメモリーブロックを設定することができるので、カーネルのみで使用できるメモリー (カーネルメモリー) として使用される。
ユーザーモードは、一般のユーザーのコードを実行するモードで、特権命令の実行や、カーネルメモリーへのアクセスは制限される。

MMU は、仮想メモリーを実現する機能で、仮想メモリーと物理メモリーのアドレスを変換して、透過的にメモリーアクセスする能力を持っている。アドレス変換には、マッピングテーブルが使用される。
マッピングテーブルは、プロセスごとに設定できるので、プロセス間で共有するメモリーブロック、プロセス固有で使用するメモリーブロックという設定が可能になっている。
上記のカーネルメモリーの設定も、このマッピングテーブルが使用されている。

アドレス変換はオーバーヘッドが大きい処理であるため、プロセッサーには TLB と呼ばれるアドレス変換専用のキャッシュ機構が搭載されている。


## Meltdown 脆弱性とは

投機実行による領域外メモリーデータ漏洩の可能性については、

Spectre 脆弱性について
https://qiita.com/noumia/items/303e890fb50730bd5115

で解説している。

Meltdown 脆弱性は、このデータ漏洩が、カーネルメモリーにも通用してしまうという問題である。

通常ユーザーモードからは、カーネルメモリーはアクセスできないため、カーネルメモリーにアクセスしようとすると割り込み (例外) が発生し、コードの実行が中断される。

Meltdown 脆弱性のあるプロセッサーでは、投機実行によってカーネルメモリーへの読み込みが行われた後で、割り込み処理が実行される場合がある。
投機実行で読み込まれたデータは破棄されるが、メモリーキャッシュを使用したサイドチャネル攻撃によって、データを推定することが可能となってしまう。

```

probe_memory : [0x100000] uint8

1) probe_memory をキャッシュからフラッシュする

2) x = *(カーネルメモリーの仮想アドレス) // このコードはアクセス違反例外を引き起こす

3) y = probe_memory[x << 12] // このコードが投機実行されるとメモリーキャッシュに痕跡が残る


例外ハンドラー内：

probe_memory をスキャンして、カーネルメモリーのデータバイトを推定する

```


## Meltdown 脆弱性の緩和策

通常、スーパーバイザーモードから、ユーザーモードへ遷移する際、プロセスの持つアドレスマッピングテーブルを操作して、スーパーバイザー専用メモリーブロックのマッピングを外す処理は行われていなかった。

これは、マッピングがそのままでも、ユーザーモードからカーネルメモリーへのアクセスはブロックされるため、問題はないとみなされていたためである。

また、マッピングテーブルの操作は、TLB のキャッシュを無効化することになるため、TLB ミスが頻発することになり、性能に影響するためでもある。


Meltdown 脆弱性の緩和策として、カーネルメモリーのデータ漏洩を防ぐため、ユーザーモードに遷移させるときに、カーネルメモリーへのマッピングを取り除くという手法がとられた。

そのためこの対策を行うと、カーネルモードとユーザーモードの切り替えが頻発すると、前述のように TLB ミスが増加するものと考えられる。

実際、カーネルモードとユーザーモードの切り替えを伴う I/O 操作が中心となる、高負荷のデーターベースサーバー等のワークロードでは、性能に顕著な影響がある模様である。
MacでPowerShellを扱うときに気をつけるべきたった一つの注意事項

# MacでPowerShellを扱うときに気をつけるべきたった一つの注意事項

MacでPowerShell使いたいなんて言う需要なかなかないと思いますがでも僕は使いたかった。
そしてハマった一つのこと。

# コマンドを省略しない。(エイリアス使わない)

つまり「rm」とか「ls」とか使っちゃダメです。
「Remove-Item」とか使いましょう。

## 理由

macのrmとかlsとかと衝突するから。

どうやらpowershell上でもrmはmacのrm優先されるようです。（感じ方には個人差があります。）
特にスクリプトとか書いちゃうとその辺りであれれーおかしいなーうごかないぞー？
となるので正式名称で書きましょう。どうせTABキーとかで補完されるでしょ！！
Unityのyamlからコマンドライン上で値を取り出したい

# Unityのyamlからコマンドライン上で値を取り出したい

普通はないんですけれど自動化していると稀にあります。

大体ProjectSettings/ProjectSettings.assetあたりからとりたくなります。

ハイというわけでとり方（ただし簡易、あとyaml形式になっている必要あり）

## やり方

例えばproductNameを読み込みたいときはこんな形式で書かれているので

 productName: 値 

こんな感じになりました。

```
grep -e "productName" ProjectSettings.asset | sed "s/productName://g" | tr -d " "
```

これだと辞書は読めないから辞書形式のものが読みたければもう少し何とかする必要アリですかね
素直にyaml読むなにかを使うといいと思います。
Instagramの写真をタグ毎に表示する

Instagramに写真を投稿するときにタグをいろいろ付けると思うのですが、**"自分の（特定ユーザーの）投稿の中から" 特定のタグを付けた写真だけを見たいとき**に、公式アプリやサイトだと絞り込みできないので、APIを調べて試してみました。

![スクリーンショット 2018-01-14 19.53.26.png](https://qiita-image-store.s3.amazonaws.com/0/223036/54160056-dee4-69ca-a248-626a2a26be43.png)
※phpをアップする場所がなかったので画面イメージだけ

# Instagram APIについて
APIを使うには、インスタ公式のデベロッパーサイトに登録したりなんやかんや必要です。
Qiitaにアップされている以下の記事が参考になりました。

[Instagram APIの利用方法](https://qiita.com/NoriakiOshita/items/71800502fca62d9ec685)
[Instagram APIを使ってWebページに表示する](https://qiita.com/0084ken/items/f17700a5c094bbc14a21)

Sandboxモードに限るので、最新の投稿20件しかデータを取得できません。目的からするとあまり実用的ではないのでご注意。

また、Sandboxユーザーを追加する際には、追加されるユーザー（招待を受けるユーザー）もデベロッパーサイトへの登録が必要でした（アプリの登録は招待する側のみでOK）。上記の記事にはそこが書かれていなくてちょっとハマりました。

# APIでインスタのデータを取得（PHP）
```php
// アクセストークンと、取得したいユーザーID
$accessToken = "xxxxxxxxxxxxxxxxxxxxxxxx";
$userID      = "xxxxxxxxxx";

// APIからデータを取得
$instaData   = file_get_contents('https://api.instagram.com/v1/users/'.$userID.'/media/recent/?access_token='.$accessToken);
$instaData   = json_decode($instaData);
$instaData   = $instaData->data;

//ユーザー情報
$data_u = array();
$data_u['full_name']       = $instaData[0]->user->full_name;
$data_u['profile_picture'] = $instaData[0]->user->profile_picture;
$data_u['user_name']       = $instaData[0]->user->username;
```
ユーザー情報などは扱いやすいように配列に入れておくと便利です。

# タグ毎にデータを分割する
取得したデータの中に、タグの配列も入っているので、そこから絞り込みたいタグでデータを分けます。

```php
// 初期化
$data_1 = array();
$data_2 = array();
$data_3 = array();
$tag_1  = 'タグの名前';
$tag_2  = 'タグの名前';
$tag_3  = 'タグの名前';

// データを分割
for ($i = 0; $i < count($instaData); $i++) {

	// フラグ初期化
	$flag_1 = false;
	$flag_2 = false;
	$flag_3 = false;

	// 投稿に付いているタグを検索し、フラグを設定
	for ($j = 0; $j < count($instaData[$i]->tags); $j++) {
		if ($instaData[$i]->tags[$j] == $tag_1) {
			$flag_1 = true;
		} else if ($instaData[$i]->tags[$j] == $tag_2) {
			$flag_2 = true;
		} else if ($instaData[$i]->tags[$j] == $tag_3) {
			$flag_3 = true;
		}
	}

	// フラグ毎に対応する配列に格納
	if ($flag_1) {
		$data_1[] = $instaData[$i];
	}
	if ($flag_2) {
		$data_2[] = $instaData[$i];
	}
	if ($flag_3) {
		$data_3[] = $instaData[$i];
	}

}
```

# タグ毎に表示する
HTMLは以下のような感じでタグ毎に一覧表示できます。

```html
<body>
<div id="content">
<div id="profile">
	<p><? echo $data_u['user_name']; ?></p>
	<img src="<? echo $data_u['profile_picture']; ?>" />
</div>

<div id="list_box">
<dl id="list_1">
	<dt><? echo $tag_1; ?></dt>
<?php
	for ($i = 0; $i < count($data_1); $i++) {
		echo '<dd><img src="'.$data_1[$i]->images->standard_resolution->url.'" /></dd>';
	}
?>
</dl>
<dl id="list_2">
	<dt><? echo $tag_2; ?></dt>
<?php
	for ($i = 0; $i < count($data_2); $i++) {
		echo '<dd><img src="'.$data_2[$i]->images->standard_resolution->url.'" /></dd>';
	}
?>
</dl>
<dl id="list_3">
	<dt><? echo $tag_3; ?></dt>
<?php
	for ($i = 0; $i < count($data_3); $i++) {
		echo '<dd><img src="'.$data_3[$i]->images->standard_resolution->url.'" /></dd>';
	}
?>
</dl>
</div>
</div>
</body>
```

# これを使って何がしたかったか
インスタのアカウントを複数作って、読書アカウント、猫アカウント、ゲームアカウントみたいに分けて使っています。

でも、できればインスタアカウントは一つで、投稿時にタグ付けさえちゃんとしておけば、見たいタグの投稿だけ絞り込めるようにしたかったんですが。

Sandboxの制限がある以上は実用的でないので仕方ないですね。なのでやっぱり、アカウント分けてやる方がいいのかなーと思います。