OmniAICreator/Qiita-1.07M huggingface dataset:
gulpローカル化

過去記事「[gulp初心者のメモ](http://qiita.com/akuden/items/47fd9133b52b8b7607f4)」でグローバルにgulp-cliをインストールしていましたが、時間経過とともに過去の案件などプロジェクト毎にバージョンの整合性を取るのが面倒になるような記事を読んで、グローバルからはアンインストールして、プロジェクト毎のローカルにインストールする方針にしました。

グローバルからgulpをアンインストール。

```ruby:cmd
npm rm --global gulp-cli ※gulpをアンインストール
gulp -v ※gulpコマンドが通らずバージョンが表示されなければアンインストール成功
```

## ローカルにgulpをインストール

```ruby:cmd
cd C:\xampp\htdocs\hoge ※任意のディレクトリに移動
npm init -y ※package.json作成 -yオプション：初期情報入力をスキップ
npm i gulp -D ※gulpインストール -Dオプション：package.jsonに追加する
npm gulp -v ※gulpバージョンを表示
```

グローバルgulpコマンドが使用できないため、package.jsonに下記を追加してnpmコマンドから実行できるようにする。

```ruby:package.json
{
  …省略
  "scripts": {
    "gulp": "gulp",
    "start": "gulp",
  },
  …省略
}
```

gulp実行は次のコマンドで行う

```
cd C:\xampp\htdocs\hoge ※ローカルインストールした階層
npm run gulp
又は
npm start
```

## 参考

- [【gulp】初めてでもできるgulpの導入ととりあえず使ってみるまで](https://blog.mismithportfolio.com/web/20150822gulp-intro)
- [gulp.js を今一度キチンと！gulp.js 導入基礎](https://h2ham.net/gulp-basic)
- [gulpのグローバルインストール派とローカル派、両方派に割れているようですが、 小規模サイト制作ならどちらが良いと思いますか？](https://teratail.com/questions/36750)
- [Gulpで始めるwebpack 3入門](http://qiita.com/tonkotsuboy_com/items/2d4f3862e6d05dc0bea1#%E3%82%BF%E3%82%B9%E3%82%AF%E3%81%AE%E5%AE%9F%E8%A1%8C)

ありがとうございました。
[クイズ]javascriptと仲良くなるための一歩　第１話「関数」

# ①　出力「?」は、何になるか？

```js
function hoge(a,b){
  return a + b
}
var sum = hoge;

sum(3,4)
// => 7
hoge(3,4)
// => ?
```

# ② 出力「?」は何になるか

```js
var sum = function hoge(a,b){
  return a + b
}

sum(3,4)
// => 7
hoge(3,4)
// => ?
```


:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:
:mouse:
:cow:
:tiger:
:rabbit:
:dragon_face:
:snake:
:horse:
:sheep:
:monkey_face:
:bird:
:dog:
:boar:


# ① => 7

```js
function hoge(a,b){
  return a + b
}
var sum = hoge;

hoge(3,4)
// => 7
```

# ② => Uncaught ReferenceError

```js
var sum = function hoge(a,b){
  return a + b
}

hoge(3,4)
// => Uncaught ReferenceError: hoge is not defined
//    at <anonymous>:1:1
```
カンマを区切り文字として、各フィールドの値を抜き出す

# 目的
カンマを区切り文字として、各フィールドの値を抜き出す
`"aaa","bb,1b","ccc"`

期待値
``aaa
bb,1b
ccc``

# 環境
CentOS 7

# コード
`echo '"aaa","bb,1b","ccc"' | awk -F'","' '{print $2}'`

- -F オプションを使用して、","をフィールド区切り文字に指定しています
- awk が print $2 コマンドを実行すると、入力ファイルの各行の 2番目のフィールドが出力されます。つまり、bb,1bが出力されます。
Roswell scriptで良い感じのREPLを書いた（書きたい）

# はじめに
**Common Lispは流行っていません．**流石に数あるLisp方言の中では最も使われている部類と思いますが，それでも流行っているとは言いがたいと思います．**なぜCommon Lispが流行らないか**というと，S式がどうとかカッコがどうとか以前に**インフラストラクチャが整っていない（ように見える）**からだと個人的には考えています．例えばパッケージマネージャのデファクトスタンダードは[Quicklisp](https://www.quicklisp.org/beta/)ですが初心者にとって馴染みやすいものではないと思います．

しかしながら最近は[Roswell](https://github.com/roswell/roswell/)の登場もあってかなり改善されていて，以前に比べればCommon Lispを始めるハードルはほとんど近代的な言語（例えばPython，Ruby）のそれに追いついてきているように思います．また，Roswellのおかげでポータブルなスクリプトも書きやすくなりました．

それではRoswellがもっと浸透すればCommon Lispは流行るのかというとまだ一つ不十分なところがあると考えています．ずばりそれは**REPL**です．Common Lispの開発サイクルにはREPLとの密な連携が不可欠であり，それをまさに体現しているのがSLIMEだと思います．しかしながら，各処理系に標準で付属しているREPLは初見殺しの感が強く，使いやすいものとは思いません．例えばSBCLを初めてインストールした時に**矢印キーを押して`^]]A`とか表示されてなんじゃこりゃとなったり**，On Lispを見ながらREPLで写経していてタイポして**謎の画面(デバッガ)に飛ばされて焦って`ctrl-d`連打したり**というのは初学者の誰もが通る道だと思います．

PythonにはIPythonという高級なREPLがあり，標準のものは貧弱ですがIPythonさえあれば事足ります．Common Lispにはこれに相当するものが（SLIMEがそうなのかもしれませんが）ありません．少なくとも私は知りません．ということで誰か開発してくれれば良いわけですがその兆しもないので試しに自分で作ってみたというのが今回の本題です．

**私のCommon Lisp力は非常に貧弱なので誰かが触発されてより良い物を作ってくれないかなという打算もあります．**というか誰か作ってください…．

# CL-REPL - Common Lisp REPL for Roswell
今回作成したものです．Roswellスクリプトとして書いています．[Github](https://github.com/koji-kojiro/cl-repl)にソースコードを上げています．思いついた端からザッと書いたコードに落としたのでかなり汚いコードですが，そのうち整理すると思います．

作成にあたって注意したポイント（というか私がより良いREPLに求める点）としては以下のとおりです．

- 処理系に非依存．
- 最低限色がついていないと見難い．
- タブ補完とかEmacs的キーバインド（要はGNU Readline的なもので出来てる）
- シェルコマンドを呼べると何かと嬉しい．
- 導入が簡単

一応上記の点はすべて解決しているつもりです．
インストールはRoswellから可能で以下のコマンド一発で入ります．

```shell-session:CL-REPLのインストール
$ ros install koji-kojiro/cl-repl
```
当たり前ですが`ros use 処理系`で実装を入れ変えればちゃんと反映されます．基本的に処理系間でのちがいが極力無いようにしていますが，**エラーメッセージは処理系依存です**．また~~**タブ補完はSBCLだけサポート**~~しています．ちなみにANSIカラーサポートでない端末では鬼のように文字化けするのでご注意ください．

**2017/07/27追記**
なんだか急激にPVが増えているので変更点を書いておきます．

- Roswellのサブコマンド化しました．`ros repl`で動きます．Roswellには`ros-hoge`という名前のスクリプトが`~/.roswell/bin/`に配置されていると`ros hoge`で実行できる機能があるようです．
- TAB補完はSBCL以外でも動くようになりました． 補完関数のregisterを`cl-readline`のAPIを通さずに`cffi`から直に叩くと何故か動きました．謎．  
- SBCLだけの機能としては環境変数`EDITOR`で指定されたエディタを開いての編集を実装しました．IPythonの`%edit`マジックですね．
  

実際に使用している様子が以下になります．見ての通りIPythonとSLIMEをかなり意識しています．本当はシンタックスハイライトも入れたかったのですが力尽きました…．使い方はGithubのREADMEにあります．一応英語ですがほぼ日本語のような英語なのでそちらをご拝読ください．

![cl-repl.gif](https://qiita-image-store.s3.amazonaws.com/0/153686/9b5c622c-8acd-da7b-2ad1-f43db28b0aa3.gif)

拙作CL-REPLの紹介は以上です．よければ使ってみて[不満点を指摘](https://github.com/koji-kojiro/cl-repl/issues)するなり，強Lisperな方は是非より良いREPLを開発してみてください．
ここまで読んでいただきありがとうございました．
pythonの内包表記について

#はじめに
pythonには内包表記という形式があるのですが、
一切使わずに今までやってきたのですがパフォーマンスにも関係するし、そろそろきちんと理解しようかと思いまとめようと思いました。

##リストを作る
1~100までの奇数だけのリストを作ります。
内包表記を使わない作り方は以下の通り

```list1.py
list = []
for number in range(1,101):
    if number % 2 ==1:
        list.append(number)
print(list)
```
次は内包表記を使って同じことをやってみます。プログラムは以下の通り

```list2.py
list = [number for number in range(1,101) if number %2 ==1]
print(list)
```
初めのnumberはlistに格納するnumberになります。for のあとのnumberはfor分の一部のnumberです。

##集合を作る
1~99までの奇数だけの集合を作ります。
リストと同じような感じで内包表記でかけます。

```shugo.py
list = {number for number in range(1,101) if number %2 ==1}
print(list)
```


##辞書を作る
同じように辞書も内包表記を使ってかけます。
wordの文字が何回現れたかカウントするプログラムです

```jisyo.py
word = 'aiueokakiku'
word_count = {x:word.count(x) for x in word}
print(word_count)
```

##タプルについて
リストと同じように作ってみます。

```tuple1.py
tuple = (number for number in range(1,101) if number %2 ==1)
print(tuple)
```

実行すると
```<generator object <genexpr> at 0x101435f6１>```
エラーではないが、()を使ってかくとジェネレータが返ってくる
つまり、**タプルには内包表記がない**わけです。

##パフォーマンス比較
本当に早いのか試してみます。
まずは、内包表記を使わずに1~10000000までの奇数だけのリストを作ってみます

```test1.py
import time
start = time.time()

list = []
for number in range(1,10000001):
    if number % 2 ==1:
        list.append(number)

print("実行時間:{0}",time.time() - start)

```
5回実行した平均は**1.71131701469**となりました

次に同じこと内包表記でやってみます

```test2.py
import time
start = time.time()

list = [number for number in range(1,10000001) if number %2 ==1]

print("実行時間:{0}",time.time() - start)
```
5回実行した平均は**0.88413858413**となりました

##結果
内包表記で書くと早さも約2倍で単純にコード量が減りました。
慣れてくると読みやすくなるらしいので早く慣れるように頑張ろうと思います。
Node-REDでシンプルなウェブサイト - 7. 動画を貼ってみる

初めてNode-REDを使ってみよう、というかたのためのガイドです。
Node-REDを使ってシンプルなウェブサイトを作ってみます。

このステップではウェブサイトに動画を貼ってみます。

# 7.1. Node−REDフローを用意する
- [Node-RED - フローをコピーする方法](http://qiita.com/egplnt/items/00bbda990c5babaeaa86)を参照し、下記のフローをコピペします。
![スクリーンショット 2017-05-03 9.14.53.png](https://qiita-image-store.s3.amazonaws.com/0/125842/a02dcb05-2372-6df2-ae2c-ca6186a7b86f.png)

```:動画掲出用フロー
[{"id":"a1b5d2b3.32b3","type":"http in","z":"2302eb53.652cc4","name":"","url":"/test25","method":"get","swaggerDoc":"","x":90,"y":240,"wires":[["1cb8d38f.db2d74"]]},{"id":"2dba3778.fc6f6","type":"http response","z":"2302eb53.652cc4","name":"","x":590,"y":240,"wires":[]},{"id":"d4c56dbc.0bfb8","type":"comment","z":"2302eb53.652cc4","name":"動画を掲出します","info":"","x":110,"y":200,"wires":[]},{"id":"3aa99b0b.2d240c","type":"template","z":"2302eb53.652cc4","name":"test25.html","field":"payload","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<html>\n  <head>\n    <style type=\"text/css\">\n      {{{payload.css}}}\n    </style>\n  </head>\n  <body style=\"background-color: #EAE5E3; \">\n    <div id='basic'>\n        <div id='a1'><h1>動画を表示するサンプル</h1></div>\n        <div id='b1'>これは動画を表示するサンプルです</div>\n        <div id='c1'>これはc1です</div>\n        <div id='c2'>\n            ここに動画の情報をコピペします\n        </div>\n        <div id='c3'>これはc3ですよ</div>\n        <div id='d1'>これはd1です</div>\n    </div>\n  </body>\n</html>\n","x":410,"y":240,"wires":[["2dba3778.fc6f6"]]},{"id":"1cb8d38f.db2d74","type":"template","z":"2302eb53.652cc4","name":"css","field":"payload.css","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"#basic {\n    font-family: meiryo;\n    width: 1200px;\n    position: absolute;\n    top: 0;\n    left: 0;\n    right: 0;\n    bottom: 0;\n    margin: auto;\n}\n#a1 {\n    background-color:  #98d98e;\n    height: 100px;\n    padding: 20px;\n}\n#b1 {\n    background-color:  #e4de8a;\n    height: 100px;\n    text-align: center;\n    font-size: 18pt;\n}\n#c1 {\n    float: left;\n    background-color:  burlywood;\n    height: 600px;\n    width: 200px;\n    text-align: left;\n    font-size: 18pt;\n}\n#c2 {\n    float: left;\n    background-color:  wheat;\n    height: 600px;\n    width: 800px;\n}\n#c3 {\n    float: right;\n    background-color:  burlywood;\n    height: 600px;\n    width: 200px;\n    font-size: 18pt;\n}\n#d1 {\n    clear: both;\n    background-color:  rosybrown;\n    height: 100px;\n    text-align: left;\n    font-size: 18pt;\n}\n","x":250,"y":240,"wires":[["3aa99b0b.2d240c"]]}]

```

# 7.2.動画を見つける
- YouTubeなどで気に入った動画を探します。
- YouTubeでは動画の下の「共有」メニューから「埋め込みコード」をコピーします。
![スクリーンショット 2017-05-03 8.40.51.png](https://qiita-image-store.s3.amazonaws.com/0/125842/4c41788d-4229-a3bb-0ba3-58c9169ae87e.png)

# 7.3.ウェブページに貼り付けます
- 7.1で準備したフローの`test25.html`テンプレートノード（オレンジ色）を開き、「ここに動画の情報をコピペします」の行に前項でコピーした内容をコピペします。
- 「完了」→「デプロイ」しアプリ名/test25へアクセスして確認します
![スクリーンショット 2017-05-03 8.44.24.png](https://qiita-image-store.s3.amazonaws.com/0/125842/cae313e5-b748-a27f-78b1-75657339dd59.png)
OpenSSL をソースからビルドする

OpenSSLのバージョンが古かったのでソースからビルドしてみた

## 使用環境
|OS・ミドルウェア|バージョン|
|:-----------|:-------|
|OS|CentOS Linux release 7.3.1611 (Core) |
|OpenSSL|OpenSSL 1.1.0h|

## やり方

1. 必要なライブラリをyumでインストールする

    ```shell-session
    # yum -y install perl wget gcc gcc-arm-linux-gnu tcp_wrappers-devel
    ```

2. tarファイルをダウンロードして展開する

    ```shell-session
    # cd /usr/local/src
    # wget https://www.openssl.org/source/openssl-1.1.0h.tar.gz
    # tar -zxf openssl-1.1.0h.tar.gz
    ```

3. 展開してできたフォルダに移動してビルドする

    ```shell-session
    # cd openssl-1.1.0h/
    # ./config --openssldir=/usr/local/ssl
    # make
    # make install
    ```

4. バージョンを確認する

    ```shell-session
    # openssl version
    OpenSSL 1.1.0f  25 May 2017
    ```

5. 不要なファイル・フォルダを削除する

    ```shell-session
    # rm openssl-1.1.0f.tar.gz 
    rm: remove regular file ‘openssl-1.1.0f.tar.gz’? y
    # rm -rf openssl-1.1.0f/
    ``` 

いけたみたい。

### 追記
最初に元々あった OpenSSL を削除する手順がありましたが、他のミドルウェアでそれを参照していたりする場合に影響が出る可能性があるので手順をなくしました。

## 参考
以下のサイトを参考にしました。

* [Compilation and Installation](https://wiki.openssl.org/index.php/Compilation_and_Installation)
* [OpenSSLを最新版へバージョンアップ(＋OpenSSH)](https://bacchi.me/linux/reinstall-openssl/)
* [How to upgrade OpenSSL on Centos 7 or RHEL 7](https://syslint.com/blog/tutorial/how-to-upgrade-openssl-on-centos-7-or-rhel-7/)
Rubyのインスタンス変数・メソッドとクラス変数・メソッドを検証

#Rubyのインスタンス変数・メソッドとクラス変数・メソッドを検証する
Rubyを勉強していて、インスタンス変数・メソッドとクラス変数・メソッドの扱いについて理解するのに時間を要したので、そのときの検証内容を備忘録として記載。
ここではRubyのバージョンは`2.4.1`を利用。

##クラスで検証
まずは基本仕様。

- インスタンス変数はインスタンスメソッドしかアクセスできない
- クラス変数はインスタンスメソッドとクラスメソッドの両方アクセスできる
- クラスインスタンス変数はそのクラス内で定義されたクラスメソッドしかアクセスできない

###Rubyの検証用サンプルコード
```rb
class Test
  @c_i_var = 0
  @@c_var = 10
  var = 'var'

  def initialize
    @i_var = 100
  end

  def test
    @i_var   += 1
    @@c_var   += 1
    self
  end

  def examine1
    p 'Test::examine1'
    p @i_var, @c_i_var, @@c_var
    self
  end

  def Test.examine2
    @c_i_var += 1
    p 'Test::examine2'
    p @i_var, @c_i_var, @@c_var
    Test.new
  end

  def examine3
    Test
  end

  p 'Test::var'
  p var
end

class Test2 < Test
  def Test2.examine2
    p 'Test2::examine2'
    p @i_var, @c_i_var, @@c_var
  end
end

t = Test.new
t.test.examine1
Test.examine2.test.examine1.examine3.examine2

Test2.examine2
```

###サンプルコードの出力結果
```text
"Test::var"
"var"
"Test::examine1"
101
nil
11
"Test::examine2"
nil
1
11
"Test::examine1"
101
nil
12
"Test::examine2"
nil
2
12
"Test2::examine2"
nil
nil
12
```

###判明したこと
- クラス`Test1`のインスタンスメソッド`examin1`とクラスメソッド`examin2`の実行結果から「インスタンス変数はインスタンスメソッドしかアクセスできない」と「クラス変数はインスタンスメソッドとクラスメソッドの両方アクセスできる」が判明。
- クラス`Test1`とクラス`Test2`のクラスメソッド`examine2`の実行結果から、「クラスインスタンス変数はそのクラス内で定義されたクラスメソッドしかアクセスできない」が判明
- クラス内でローカル変数を定義してもエラーにならない。またクラス内で定義されたローカル変数はインスタンスメソッドとクラスメソッドの両方からアクセスできない。`p var`が実行されるのは最初のインスタンス生成時の1度だけ。
- クラス変数とクラスインスタンス変数の値はインスタンス間で共有される
- インスタンス変数はインスタンス間で共有されない

###その他
クラス変数を定義すると"bad code style"という警告がでるので、実際の運用では使わないようにする。


##浅いコピーと深いコピーをしたときのクラス変数とインスタンス変数
[こちら](http://qiita.com/hiroykam/items/51a97b648b4f5eadf3b8#%E3%82%AF%E3%83%A9%E3%82%B9%E5%A4%89%E6%95%B0%E3%81%A8%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E5%A4%89%E6%95%B0%E3%81%AE%E6%A4%9C%E8%A8%BC%E3%81%9D%E3%81%AE3)でPython3で浅いコピーと深いコピーをしたときのクラス変数とインスタンス変数の変化について検証したが、Rubyでの挙動も確認した。
結果は、Python3と同様に深いコピーでもクラス変数の値が変更されている。


###Rubyの検証用サンプルコード
```rb
class Test
  @@c_var = 2

  def initialize(val)
    @i_var = val
  end

  def inspect
    '%d, %d' % [@@c_var, @i_var]
  end

  def examine1
    @i_var += 2
    self
  end

  def examine2
    @@c_var += 2
    self
  end
end

t1 = Test.new(3)
t1.examine1.examine2
p t1
p Test.new(3)

puts '--- shallow copy ---'

t2 = t1.clone
t2.examine1.examine2
p t1
p t2
p Test.new(3)

puts '--- deep copy ---'

t3 = Marshal.load(Marshal.dump(t1))
t3.examine1.examine2
p t1
p t2
p t3
p Test.new(3)
```

###サンプルコードの出力結果
```text
4, 5
4, 3
--- shallow copy ---
6, 5
6, 7
6, 3
--- deep copy ---
8, 5
8, 7
8, 7
8, 3
```
Releaseビルド時にprintによる出力を止める方法

Debugビルド時に出力していた`print`によるログは、Releaseビルド時には垂れ流したくない...


```swift
import UIKit

func print(_ items: Any..., separator: String = " ", terminator: String = "\n") {
    #if DEBUG
        let output = items.map { "\($0)" }.joined(separator: separator)
        Swift.print(output, terminator: terminator)
    #endif
}

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    // ...省略...
}
```

これでOK！
golangのお勉強15+goa


## goaとnode_modules

node_modulesをGOHOMEのプロジェクト内に置いたらgogenが容量不足とエラーを吐いた。
エラーとしては内部の`go install`でエラーになってる。。はて。。

node_modulesをどう含ませるかという問題もあるけど、、
そもそも同じプロジェクトにしない方がいいのかしら。。
開発中は、同じところでやって、あとから移動とかにしたい気がしてしまうが、
その考え方をちょっと転換した方が便利かなあ。。

## goagen jsから吐き出されるjs

jsの話題になってまう。。

* axios.jsでAjax処理
* client.jsにrequireJSの形式でスクリプトが記述（defineでモジュール）されている
* index.htmlにサンプルのロジック

### requireJS

使い方。。

RequireJS使い方メモ - Qiita
http://qiita.com/opengl-8080/items/196213867b859daea719


### axios.js

axiosを乗りこなす機能についての知見集 - Qiita
http://qiita.com/inuscript/items/ccb56b6fc05aa7821c42

superagentとaxiosの使い分け - Qiita
http://qiita.com/nekobato/items/0cd3ed1742310f74653c

### webpack

下記みたいな感じにするために`HtmlWebpackPlugin`へ`filename: '../index.html'`みたいな指定。

js...goagen js吐き出し
pubclic...公開
	js...公開js
	*.html...公開html
src...独自リソース
	js
	css
	*.html

Need to use different output path · Issue #148 · jantimon/html-webpack-plugin
https://github.com/jantimon/html-webpack-plugin/issues/new

## vendoring

プロジェクト内でパッケージと、そのバージョンを管理する。
glideがメジャー。
プロジェクトをまたいで共通のGOPATHで開発してねっていうお話をどこかで見た気もするけどどうだろう。。

Golangのvendor管理周りでちょっとハマった – Wano Developers Blog
https://developers.wano.co.jp/golang%E3%81%AEvendor%E7%AE%A1%E7%90%86%E5%91%A8%E3%82%8A%E3%81%A7%E3%81%A1%E3%82%87%E3%81%A3%E3%81%A8%E3%83%8F%E3%83%9E%E3%81%A3%E3%81%9F/

## golangとdocker

2015年の記事と、古いけどシンプルなdockerを使った例。

Docker: golang 公式のイメージを使う - Sarabande.jp
http://blog.sarabande.jp/post/129683620733

firewallも購入してアラートを抑制できるようになったものの、
やはりdockerで開発するのもありかなという気がしてきた。
開発の脇道が長いと脇道にそれることの敷居が下がる。。

godoというタスクランナーと、golangの公式dockerを使っている事例。よさそうだなあ。。
試して見たらglideが便利そう。。。本筋の話じゃないけど。

Docker内のGo製Webアプリをソース変更後リロードするだけで確認できるようにする | フリップフラップ
http://blog.flup.jp/2016/02/18/golang_docker_hot_reload/

デフォルトは、debianのstretchリリースがベース
alpine linuxもある

golang/Dockerfile at 2a15dfff04accfd31c2a45b3bb7423aa86aa2d60 · docker-library/golang
https://github.com/docker-library/golang/blob/2a15dfff04accfd31c2a45b3bb7423aa86aa2d60/1.9-rc/stretch/Dockerfile

これを真似ればsshできる。。かな。

sshできるdockerコンテナをつくるために最低限必要なこと - kotaroito's notes
http://kotaroito.hatenablog.com/entry/2016/03/07/094423

> なお、sshd を docker コンテナで走らせる必要はない、という議論もあります。 production で使うならこれはその通りだと思います。
PHPにおいてファイルの入出力

#ファイルの入出力onPHP！
COBOLは飽きました。あんなクソみたいな制約の言語なんてやってられるか、俺は自由にクソみたいなコードを書くぞ。記事内でPHPだったりphpだったり表記に揺らぎがありますが気にしたら負け。~~何も考えずに記事書いてる。~~

本題です。既に学習済みなのですが、基礎の復習として文章に書き起こしていきます（基本的にphp.net見てます）

phpにおいて、ファイルを扱う際には<code>fopen</code>という関数でファイルを開き、そこから弄らないといけません。（他に手段があっても知らん！）
<code>fopen</code>関数は、C言語等と同じで<font color=green>返り値としてファイルポインタを返します</font>。
C言語なら代入する変数の型は<code>FILE</code>ではないといけませんが、php
は~~楽。でもこの方法使ったら偉い人に怒られそう。~~<font color=red>いきなり変数に代入しても問題ない</font>です。この気楽さがphpのウリだと思っています。正直これ以外にウリが無いような気もしますが・・・

##ファイルポインタを取得！
かなり話が脱線しましたが、phpでは、先述のように<code>fopen</code>関数でファイルのポインタを取得します。
ちなみに、関数の式としては

```php:fopen
resource fopen (string $filename, string $mode[, bool $use_include_path = false[, resource $context]])
```
(出典:http://php.net/manual/en/function.fopen.php)
となっております。
賢い人ならこれ見ただけで使い方は分かるね。ちなみに私はわかるので解説しません。賢いフレンズなので。

##ファイルを読み込む！
###fread
次はファイルを読み込む方法です。phpではファイルを読み込む際に<code>fread</code>関数を用います。この関数の式は、

```php:fread
string fread (resource $handle, int $length)
```
(出典:http://php.net/manual/ja/function.fread.php)
となっております。<code>$handle</code>はファイルポインタ、<code>$length</code>は読み込む<font color="red">バイト数</font>です。失敗したらfalse返ります。
この方法はガチでファイルを読み込みたい時に用いるっぽいです。
###file_get_contents
先程は<code>fread</code>関数を挙げましたが、単純にファイルの中身を文字列に格納したいだけならこっちの<code>file_get_contents</code>関数を用いた方が<font color=red>効率が良い</font>らしいです。知らなかった・・・
関数の式は次のようになっています。

```php:file_get_contents
string file_get_contents ( string $filename [, bool $use_include_path = false [, resource $context [, int $offset = 0 [, int $maxlen]]]])
```
(出典:http://php.net/manual/ja/function.file-get-contents.php)
賢いフレンズさんたちなら意味はわかりますね。失敗したらfalse返ります。
注意点としては、関数仕様を見る限り引数はファイルポインタではなくてファイルのパスです。あれ？<code>fopen</code>関数いらなくね・・・
##ファイルに書き込む！
###fwrite
ファイルにデータを書き込むには<code>fwrite</code>関数を用います。
この関数の式は

```php:fwrite
int fwrite ( resource $handle, string $string [, int $length] )
```
(出典:http://php.net/manual/ja/function.fwrite.php)
となっています。<code>$string</code>は書き込む文字列です。多分int型の変数とかぶち込んだら自動でstringとして扱われるようになってると思うので無事書き込めます。
また、注意点としては同じファイルポインタに二階書き込みを行うとファイルの末尾に追記されるぽいです。知らん。
##実際のコード例！
###例１(fopen~fwrite~fread)
例1では"Hello"という文字列をファイル<code>test.txt</code>に書き込み読み込んで表示させています。動かしてないけど多分動きます。

```php:sample1.php
<?
    if(($fp = fopen("test.txt","a+")) == false) //"a+"は読み込み＆書き出し両方行える、常に追記
        echo "読み込みエラー！";
    fwrite($fp, "Hello");
    echo fread($fp);
    fclose($fp); //ファイルポインタを閉じる
```
###例2(file_get_contents)
関数<code>file_get_contents</code>と先ほどの例１のコードで生成された<code>test.txt</code>を用いて"Hello"と表示させます。動くかは知らない。

```php:sample2.php
<?
    echo file_get_contents("test.txt");
```
#まとめ
ファイルポインタを開く際は<code>fopen</code>、読み込みは<code>fread</code>、書き込みは<code>fwrite</code>。
別の手段として、ファイルを読み込むだけなら<code>file_get_contents</code>もある。
文字列としてファイルの内容を出力できたら後は適当に加工すればまともに扱えるからこれだけ知っていれば良いみたいな所ある。

この記事は以上です。
記事の長さの割にはまともなこと書いてないし、見るとしたら最後だけでいいです。ちなみにtwitterのIDは@4a9gn_intです。

閲覧ありがとうごさいました。意見は受け付けていません。
Node-RED - フローをコピーする方法

初めてNode-REDを使ってみよう、というかたのためのガイドです。

#Node-REDのフローをコピーします
Node-REDでは簡単にフローをコピーすることが可能です。
1. Node-REDの画面で、ワークプレースを選択して[Cntl]+[A]で全ノードを選択します。各ノードが黄色い線で囲われます。
2. 画面右上の三本線をクリックし、 「Export」から「Clipboard」を選択します。
![スクリーンショット 2016-05-19 8.50.25.png](https://qiita-image-store.s3.amazonaws.com/0/125842/5e2c8adc-fda5-6755-f17f-d81ca46183e6.png)

3. ウィンドウにフローの定義情報が表示されているので、[Cntl]+[C]でクリップボードへコピーします。
![スクリーンショット 2016-05-19 8.50.25.png](https://qiita-image-store.s3.amazonaws.com/0/125842/fb73bcc4-deab-2b06-d77e-6be62f457f80.png)

4. Node-RED画面のワークプレースの右上の「＋」ボタンを押して、新しいワークプレースを開きます。「Flow 2」といった名前になります。
5. 新しいワークプレース画面の右上の三本線を開いて「Import」から「Clipboard」を選択します。
![スクリーンショット 2016-05-19 8.56.24.png](https://qiita-image-store.s3.amazonaws.com/0/125842/adc6cbed-bf75-8d0e-bdd2-4408196d6410.png)

6. 開かれたウィンドウにクリップボードの内容を[Cntl]+[V]で貼付け、「OK」を押します。
![スクリーンショット 2016-05-19 8.56.47.png](https://qiita-image-store.s3.amazonaws.com/0/125842/455941f0-9f70-a847-7aa7-539460a95bd8.png)

7. クリップボードに保存されていたフローの定義がコピーされるので、見やすい位置までドラッグしてきて[Enter]で確定します。
![スクリーンショット 2016-05-19 8.59.20.png](https://qiita-image-store.s3.amazonaws.com/0/125842/4c801393-1b3c-3e03-a648-d1008c66e4b6.png)

8. Deployを押してクラウド上のアプリへ反映します。
golangでffmpegやx264つかってhtml5のMediaRecorderの出力を受けてみる ３日目

# 概要

１日目
http://qiita.com/taktod/items/0d87e511388fde7ffe2d
２日目
http://qiita.com/taktod/items/278255153b6bba68e95f

これらの続き
今日は３日目

今日はttLibGoをつかってちょっとしたサーバープログラム書いてみました。

https://github.com/taktod/websocketPublishTest
できたのがこれです。

## 流れ

html5のgetUserMediaとMediaRecorderを利用してwebmファイルを作成
そのデータをwebsocketでgoに渡す

で、go側で取得データをデコード & エンコードしてfragmented mp4の形で保存してみる

というコードを書いてみました。

今の所とりあえずファイルに保存してるだけですが、h264 & aacにエンコードしたものをrtmpサーバーにpublishしてもいいし
websocketで他の視聴クライアントになげてMediaSourceExtつかって再生して配信してもいいし
mpegtsに書き出してHLSを組んでもいいと思います。

## やってて思ったこと

### 最近のMediaRecorder(chrome)ってh264吐くんですね

MediaRecorderで特に指定せずに書き出しやってみたところ、h264 & opusのwebmになりました。
そういえば、webRTCもh264対応してましたっけ
なんか地味に時代を感じました。

### opusの音声の開始が0からはじまってなかった

はじめつくって録画したデータを聞いてみたところ、なんか音声と映像の同期がずれてました。
調査してみたところpts が0.08あたりから開始してました。
そんなことあるんですね。

https://github.com/taktod/websocketPublishTest/blob/f0e4413e95dcddddaee0c63869b3ed9a71527816/socket.go#L100

### h264データのkeyFrame間隔

writerの動作はkeyFrameがきたらデータを書き込むという処理にしてあるのですが
chromeが出力するwebmのh264データをみていたところ、keyFrameの間隔が非常に長そうでした。
なので、初めはencodeかけずに取得フレームをそのまま利用していたのですが、急遽x264でencodeし直す形に・・・

まぁ、x264Encoderの動作テストできてよかったかな。
ただ、手元のテストでは、生成データのサイズが２倍ほどに大きくなってしまったので、もうちょっと変換パラメーター
調整しないとだめだなぁと思いました。

https://github.com/taktod/websocketPublishTest/blob/f0e4413e95dcddddaee0c63869b3ed9a71527816/socket.go#L145-L165

### FrameのID

chromeが出力するwebmですがopusがtrack1、h264がtrack2になってました。

writerの処理の初期化の関係でh264をtrack1、aacをtrack2にしているので、そこが妙な気分に・・・
かといって、フレームをいくつか取得してからwriterを初期化するのもなんだかな・・・と思ったので
IDを直書きすることにしました。
もちろんこのコードだと、映像のみや音声のみのデータは扱えません。

https://github.com/taktod/websocketPublishTest/blob/f0e4413e95dcddddaee0c63869b3ed9a71527816/socket.go#L39

## つくった感想

まぁ、楽しくかけたかな。
特に大きなトラブルもなくつくれましたし・・・

こういう感じに息抜きにサクッとプログラム書いて
go runで簡単に実行できるのは便利でいいですね。
Googleアカウントでのみ認証するNode.js製はてな匿名ダイアリークローンを公開した



タイトルの通りなのですが、特定のドメインのGoogleアカウントでのみ認証するNode.js製はてな匿名ダイアリーを作ってOSSで公開しました。

|<img width="742" alt="スクリーンショット 2017-07-17 17.07.38.png" src="https://qiita-image-store.s3.amazonaws.com/0/2382/58c1a126-23fe-d679-0f12-87d09e59262a.png">|
| :---: |
|ログイン時の画面|

コードは

- [sifue/tokumei-diary](https://github.com/sifue/tokumei-diary)

で、ISCライセンスで公開してあります。実際に立ててあるインスタンスは、

- [N高 匿名ダイアリー https://n-tokumei.soichiro.org/](https://n-tokumei.soichiro.org/)

です。N高等学校のGmailのドメイン、nnn.ed.jpのGmailアドレスでないとログインできず日記が書けない、はてな匿名ダイアリークローンとなっています。

技術としては

- 認証: Google OAuth2
- 言語: Node.js
- DB: PostgreSQL
- CSSフレームワーク: Materialize

以上を用いています。

N高等学校課外授業/N予備校 プログラミングの入門コースで教えている技術だけで作ってみました。ですので、SPAとかではなく愚直にテンプレートエンジンpugとHTMLフォームだけで作成してあります。SPAじゃないのでスマホでも意外とサクサク動きます。

基本的に全ての技術は、

- [【2017年度】プログラミング入門 Webアプリ](https://www.nnn.ed.nico/courses/170/chapters)

以上で学べる技術となっていますが、CSSフレームワークだけは、入門コース内ではBootstrapですが、今回はMaterializeとなっています。とはいえ利用方法としてはそこまで変わりません。

GitHubのコミットログ見てもらえれば、大体1~2日ぐらいで実装しているのが見てわかると思います。こういうちょっとしたCMSみたいサイトならばこなれてくると短時間で実装できるようになっていきます。

ちなみに現在、N高等学校課外授業/N予備校 プログラミングの入門コースは、以下のコースで一部無料公開されています。

- [【無料体験版】プログラミング入門 Webアプリ](https://www.nnn.ed.nico/courses/236/chapters)

以上の第一章の最初の半分ぐらいを無料で見ることができます。

なお、2017/9/30まで初月無料で体験できますので、ぜひN予備校プログラミングを試していただければと思います。ひとつきたったあとは引き続き月額1000円で学べ、入門コースを終えるとこういうものがサラッと作れて運用できるだけの技術が身につきます。

また入門コースの全4章のうち最初の1章は、「[高校生のための プログラミング](https://www.amazon.co.jp/dp/4046019557/)」として書籍化されておりますので、どうしても紙媒体で学び始めたいというかたはこちらの方も利用下さい。

以下、具体的なアプリケーションの説明。

# 匿名ダイアリーの仕様

単一ドメインのGoogle認証だけを許可する、はてな匿名ダイアリークローン。 全ての日記はパブリックに公開されるほか、匿名性はホスト主によってのみ遵守される仕組みになっている。 トラックバックでバックリンクが作れる他、トラックバックをURLをタイトルに入れる、返信の日記を書くボタン機能を持っている。 自身の日記は編集、削除できる。また、IDで指定された人のみが削除人となり、削除を実施することが可能なようになっている。

現在、各種文言がN高等学校向けにカスタマイズされたものとなっているが、利用する際にはフォークして適切な文言に変更すること。また、著作権はすべて運営者に帰属する内容となっている。その投稿時の承諾事項も利用者の用途に合わせてカスタマイズできる。

# セットアップ

Node.js 6.11.1 以上で動作。Node.jsをインストールの後、クローンして `npm install` で環境用意。ローカルにPostgreSQLのDBを用意する必要がある。 文言、DBの設定、許可ドメインなどカスタマイズできるところはすべて、この`config.js`に集約してあるので適宜編集のこと。 HerokuのPostgreSQLでも大丈夫だが、しっかり運用しようと思うと無料枠では難しそうなので要注意。安いVPSで運用したほうがコスパは良い。

# 起動コマンド
Google Developer Consoleよりアプリケーションを作成して、GOOGLE_CLIENT_IDとGOOGLE_CLIENT_SECRETを発行し、

```
env NODE_ENV=production PORT=8000 GOOGLE_CLIENT_ID=xxxxxxxx-xxxxxxxxxxxxxxxx GOOGLE_CLIENT_SECRET=xxxxxx-xxxxxxxxxxxxxx GOOGLE_CLIENT_CALLBACL_ROOT='https://domain/' npm start 2>&1 | tee application.log
```

以上で起動するだけとなっている。
Node-RED - ファンクションの使いかた

初めてNode-REDを使ってみよう、というかたのためのガイドです。
この項目ではFirefoxを使用することをお薦めします。

#functionノードの使い方
Node-RED画面左側のパレットの「function」欄にはNode-REDで使用可能なさまざまな機能（ファンクション）が用意されています。
![スクリーンショット 2016-05-18 9.28.07.png](https://qiita-image-store.s3.amazonaws.com/0/125842/59233d14-05c9-db46-1d69-1172adb8364e.png)

1. [Node-RED - 入出力の使い方](http://qiita.com/egplnt/items/d2c09ef672122a2ef6cb)で用意したフローを使用します。
2. Node-RED画面左側のパレットの「function」欄の先頭にある「function」ノードをドラッグ＆ドロップでワークスペースに移動します。
3. 移動するとデフォルトではファンクション名は空欄になります。
4. ダブルクリックで開くと、デフォルトで"return msg;"がセットされていることがわかります。
5. 下記を入力します。この項目で、functionノードの編集はFirefoxで行う事で日本語環境でも問題なく操作可能です。またNode-REDはその名の通りnode.jsをベースに稼働しているので、このfunctionノードには好きなjavascriptのコードを書く事が可能です。

```:function
msg.payload = msg.payload + "ございます";
return msg;
```


functionウィンドウ下部の「OK」を押して保存します。
![スクリーンショット 2016-05-18 10.02.31.png](https://qiita-image-store.s3.amazonaws.com/0/125842/286f6adc-df69-aac0-cb8c-6551bc0662d5.png)

#フローの作成
1. [Node-RED - 入出力の使い方](http://qiita.com/egplnt/items/d2c09ef672122a2ef6cb)で用意したinjectノードをダブルクリックし、Stringを選択し、入力文字列として「おはよう」と指定します。
![スクリーンショット 2016-05-18 10.00.01.png](https://qiita-image-store.s3.amazonaws.com/0/125842/c1ee80e9-adf4-a767-4b28-ba7910c68f6f.png)

2. injectノードの右端の白い四角から線を引き出してfunctionノードの左側の白い四角へ接続し、同様にfunctionノードとdebugノードを接続し、画面右上の赤いDeployボタンを押してクラウド上のIoTアプリへ反映します。
3. Deployが成功したら、injectノード左側のボタンを押し、debugタブに「おはようございます」と結果が表示されるのを確認します。
 ![スクリーンショット 2016-05-18 10.08.45.png](https://qiita-image-store.s3.amazonaws.com/0/125842/f8c494b8-4819-220d-d576-f8dce0b7b17f.png)
4. functionノードではもちろん文字列以外のデータも扱う事が可能なので、他の機能も試してみてください。
5. またfunctionパレット（画面左側）には、functionノード以外にも「delay」や「switch」など様々な機能が用意されています。それぞれのノードをドラッグ＆ドロップでワークプレースに置き、画面右側の「info」タブを選択することで、それぞれのノードの使い方についての情報が表示されます。試してみてください。
LinuxMintでUnixBenchを走らせてみた

自作マシンと、SonyのNotePCが家にあったので、LinuxMintの圧倒的性能を測ってみようと思いました。

ググったらUnix系は、UnixBenchがお手軽そうだったので結果を書きます。

### 環境
---

1. 自作マシンにLinuxMintが入っている状態
2. 自作マシンにWindows10が入っていて、VirtualBoxでLinuxMintを動かしている状態
3. Sony-NotePCにLinuxMintが入っている状態

CPU

- 1番：Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz (7200.0 bogomips)
  - 仮想4コア、実コア４コア(計8コア)
- 2番：Intel(R) Core(TM) i7-7700 CPU @ 3.60GHz (7200.0 bogomips)
  - 計4コア設定（VirtualBoxで実コア固定の設定方法を知らないです。。）
- 3番：Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz (5787.0 bogomips)
  - 仮想2コア、実コア2コア(計4コア)

### ベンチマークソフト
---

[byte-unixbench-v5.1.3](https://github.com/kdlucas/byte-unixbench)

### コア数１の場合
---

| コア数                                | 1      | 1      | 1      |
|---------------------------------------|--------|--------|--------|
| Dhrystone 2 using register variables  | 4197.4 | 3947.3 | 3477.9 |
| Double-Precision Whetstone            | 864.4  | 830.1  | 520.4  |
| Execl Throughput                      | 554.7  | 1191   | 1262.2 |
| File Copy 1024 bufsize 2000 maxblocks | 4323.3 | 3526.5 | 3265.5 |
| File Copy 256 bufsize 500 maxblocks   | 2749.5 | 2576.8 | 2291.9 |
| File Copy 4096 bufsize 8000 maxblocks | 6549.7 | 6155.7 | 4990.7 |
| Pipe Throughput                       | 2507.8 | 2234   | 2264.6 |
| Pipe-based Context Switching          | 413.5  | 270.4  | 508    |
| Process Creation                      | 1043.9 | 1076.7 | 1243.2 |
| Shell Scripts (1 concurrent)          | 1846.7 | 3409.3 | 3185.5 |
| Shell Scripts (8 concurrent)          | 9413.3 | 8670   | 5167   |
| System Call Overhead                  | 3710.2 | 3270.5 | 3139   |
| System Benchmarks Index Score:        | 2170.6 | 2212.1 | 2073.2 |

### 複数コア（条件が違うので注意）
---

| コア数                                | 8       | 4       | 4      |
|---------------------------------------|---------|---------|--------|
| Dhrystone 2 using register variables  | 19952.5 | 15611.9 | 6350.8 |
| Double-Precision Whetstone            | 6890.2  | 3251.1  | 1710.4 |
| Execl Throughput                      | 7938.1  | 6284.1  | 3550.9 |
| File Copy 1024 bufsize 2000 maxblocks | 4208    | 4233.7  | 2992.4 |
| File Copy 256 bufsize 500 maxblocks   | 2624.2  | 2685.2  | 1886.7 |
| File Copy 4096 bufsize 8000 maxblocks | 7949.4  | 9128.2  | 5588   |
| Pipe Throughput                       | 11380.8 | 9159.7  | 4339.7 |
| Pipe-based Context Switching          | 5874.6  | 1837.2  | 2329.6 |
| Process Creation                      | 6343.1  | 3133.3  | 2822.5 |
| Shell Scripts (1 concurrent)          | 15972.5 | 12006.5 | 6140.7 |
| Shell Scripts (8 concurrent)          | 14599.5 | 10985.4 | 5565.2 |
| System Call Overhead                  | 6871.3  | 8259.4  | 6852.2 |
| System Benchmarks Index Score:        | 7964    | 5932.7  | 3765.7 |


### 結果と感想
---

表で見ると左が最強、右が最弱となる予定でしたが、１コアのときはほぼ変わらず。VMのWindowsが勝っている状態があるので、たぶん何かおかしいと思いますが、厳密にやってないので雰囲気で見てください。。

１コアで見ると、NotePCのCPUとスコアが余り変わらず。。目に見えた性能の向上が無いのかもしれません。（最後のマルチコアは、全然違いますからね。）

これで見ると、VMのオーバーヘッドって少ないように見えますが、果たして。。
Node-RED - 入出力の使い方

Node-RED使ってみよう、というかたのためのガイドです。

#入力の使い方
Node-RED画面左側のパレットの「input」欄にNode-REDで使用可能なさまざまな入力が用意されています。

![スクリーンショット 2016-05-18 8.45.42.png](https://qiita-image-store.s3.amazonaws.com/0/125842/cd32983b-e884-1e92-8fb0-1b0819b618b0.png)

1. 一番上にある「inject」ノードをドラッグ＆ドロップで画面右側のワークスペースに移動します。
2. 移動するとデフォルトで「timestamp」になります。ダブルクリックで開くと使用可能な入力のオプションが表示されます。
![スクリーンショット 2016-05-18 8.56.21.png](https://qiita-image-store.s3.amazonaws.com/0/125842/712b379c-eb94-30e7-daaf-a25d7124f774.png)
3. 他にもInput欄には様々な入力ノードが用意されているので確認してみてください。

#出力の使い方
前項と同様に、「output」欄にはNode-REDで使用可能なさまざまな出力が用意されています。

![スクリーンショット 2016-05-18 9.04.00.png](https://qiita-image-store.s3.amazonaws.com/0/125842/88afc7a3-84f3-2478-4d5c-a4ccc9e6bd88.png)

1. 先頭にある「debug」ノードをドラッグ＆ドロップでワークスペースへ移動します。
2. 移動するとデフォルトで「msg.payload」になります。ダブルクリックで開くと使用可能な出力のオプションが表示されます。

#入力と出力を接続して画面へ表示
1. 前項で用意したinjectノードの右端の小さい白い四角からドラッグして線を引き出し、debugノードの左端の小さい白い四角へ繋ぎます。
![スクリーンショット 2016-05-18 9.08.58.png](https://qiita-image-store.s3.amazonaws.com/0/125842/a67a8e03-921b-33f3-22e8-4b45c4b7eb51.png)

2. 画面右上の赤い「Deploy」ボタンを押して前項までのブラウザでの定義をクラウド上のIoTアプリへ反映します。Deployが成功すると「Successfull deployed」のメッセージが表示されます。
![スクリーンショット 2016-05-18 9.11.12.png](https://qiita-image-store.s3.amazonaws.com/0/125842/0ee972ff-7b5f-75bc-280b-3fe44b8ec543.png)

3. 画面右上の「debug」タブを選択し、デバッグ出力を見られるようにします。
4. injectノードの左側のボタンを押して、debug出力へタイムスタンプが表示される事を確認します。
![スクリーンショット 2016-05-18 9.15.58.png](https://qiita-image-store.s3.amazonaws.com/0/125842/a34a22a5-737f-8d25-453d-f4e9ef183745.png)

5. injectノードには他にも文字列を送付するString等のオプションもあるので確認してみてください。
Live2D Cubism SDK 3.0をiOSアプリで使うとテクスチャが荒くなる問題を解決する

Live2D Cubism SDK 3.0のおかげで、UnityでLive2Dモデルを扱うのがとても簡単になりました。

しかし、いざプロジェクトをiOSアプリに書き出してみると、なぜかテクスチャが荒くなって、せっかく作った可愛いLive2Dキャラが台無しになってしまいました。PCとAndroidはそんなことないのに・・・本投稿ではその現象の解決方法を書きたいと思います。

## iOS用ビルドでの現象

プロジェクトのBuild SettingをiOSに設定すると、Game画面ではこのようにテクスチャが荒くなります。
![iOS.PNG](https://qiita-image-store.s3.amazonaws.com/0/192478/254d93b4-8bf4-5ef7-8699-dcc46d90186b.png)

**環境**
> Windows 10
> Unity 5.6.1f1
> Cubism 3.0 SDK for Unity R3


## 解決方法

TextureのCompressionを**None**に設定すると直ります。
下記の例では、[SDKサンプル](http://www.live2d.com/ja/products/cubism3#dl)のKoharuちゃんで手順を説明します。

1. Live2Dモデルのテクスチャファイルを探します。
![Capture2.PNG](https://qiita-image-store.s3.amazonaws.com/0/192478/43e4e8cb-0606-3025-2f5c-bb2ccc2d10ae.png)

2. CompressionをNormal QualityからNoneに変更して、Applyで適用します。
![Capture3.PNG](https://qiita-image-store.s3.amazonaws.com/0/192478/df223b3d-4386-4c15-e80c-61b0cd0069b0.png)
![Capture6.PNG](https://qiita-image-store.s3.amazonaws.com/0/192478/58bc3b54-42af-9abf-fca8-8fb9b3901b95.png)

3. ゲームを開始すると、高品質のテクスチャになり、荒い画質が解消されます。
![Capture5.PNG](https://qiita-image-store.s3.amazonaws.com/0/192478/c1845c0b-5b7b-9797-96f2-7e4285011cf2.png)




誰かに役立てば幸いです。

なお、Live2D Cubism SDK 3.0の使い方は[こちら](http://qiita.com/akira581/items/a6ddd28383a681ef9a68
)を参考すると良いと思います。
Headless ChromeでNintendo Switchを買う

# 背景

そろそろ[Splatoon2](https://www.nintendo.co.jp/switch/aab6a/index.html)も発売されるのでNintendo Switch(以下スイッチ)が欲しくなってきましたが、以下の課題にぶち当たりました。

1. どこにも売ってない
2. オンラインショップでたまに販売されるが、監視が難しい。
3. オンラインショップを監視するtwitterボットもあるが、日中そのボットを監視する事自体が難しい

# 素直なスクレイピング

以上の課題を解決してスイッチを手に入れるため、オンラインショップをスクレイピングし、在庫を確認できたらショップ画面を開いてくれるスクリプトを書いてみました。

```js
const CronJob = require('cron').CronJob;
const client = require('cheerio-httpcli');
const opn = require('opn');

function checkYodobashi() {
  const url = 'http://www.yodobashi.com/product/100000001003431565/';
  client.fetch(url, function(err, $, res, body) {
    const status = $('#js_buyBoxMain p').text();
    if (status !== '予定数の販売を終了しました') {
      console.log('Now is the Time!!!');
      opn(url);
    } else {
      console.log('Now is Not the Time...');
    }
  });
};

new CronJob('0 */15 * * * *', function() {
  new Promise(checkYodobashi);
}).start();
```

これを各ショップごとに対応していけば、絶対にスイッチが買える…！と思っていましたが、ここで大きな問題が出てきます。
本家本元マイニンテンドーストアが毎回誤動作するのです。なぜだろうと思い、HTMLのソースを見てみると…

![image.png](https://qiita-image-store.s3.amazonaws.com/0/16913/c694e66c-dfd0-33fb-46e0-a8263e69520b.png)

**在庫状況がJavaScriptで更新されてる！！**
前述の手法では、このページの在庫状況を正しく判断する事はできません。どこから在庫状況を取得してきているのか調べるのが面倒なので[^1]なんとかしたい！

# Headless Chromeの導入

ここで思い出したのが、Chrome 59から導入されている[Headless Chrome](https://developers.google.com/web/updates/2017/04/headless-chrome?hl=ja)の存在です。
Headless Chromeをそのまま扱うのは結構面倒なので、[chromy](https://github.com/OnetapInc/chromy)というライブラリを利用します。

```js
const CronJob = require('cron').CronJob;
const Chromy = require('chromy');
const opn = require('opn');

const shops = {
  nintendo: {
    url: 'https://store.nintendo.co.jp/customize.html',
    name: 'My Nintendo Store',
    checkStore: client => {
      return client.evaluate(() => {
        return document.querySelector('#HAC_S_KAYAA p.stock').innerText !== 'SOLD OUT';
      });
    }
  },
};

async function check(client, options) {
  try {
    await client.goto(options.url);
    const result = await options.checkStore(client);
    if (result) {
        console.log(`Now is the Time!!!`);
        opn(options.url);
      } else {
        console.log(`Now is Not the Time...`);
      }
  } catch(e) {
    console.log(e);
  }
}

async function main () {
  let chromy = new Chromy();
  await check(chromy, shops.nintendo);
  await chromy.close();
}

new CronJob('0 */15 * * * *', main).start();

```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/16913/b1b594a4-d504-e5bc-0ff6-81c00774cc29.png)

在庫状況を正しく取得する事が出来ました！(在庫があった場合の確認はできていません😇)
そしてこれをベースに、様々なショップ情報を追加したスクリプトがこちらとなります。

[iwamatsu0430/switch-watcher](https://github.com/iwamatsu0430/switch-watcher)

これでスイッチを手に入れよう！(転売目的でのご利用はやめてください！)
なお著者はこのスクリプトを作成後、実店舗の抽選販売でスイッチを手に入れる事ができました。

[^1]: この記事を書くために処理をちゃんと追ってみると、在庫状況用を取得するAPIなどは叩いておらず、在庫状況を`display: none;`の要素から引っ張ってきている事が分かった。なぜこんな実装に…。
Processingで内臓カメラを表示するだけのコード

Processingというより、もはやただのjava

投稿してから気づいたが、Matの中身が負値になってしまうので、byteの配列ではなくintの配列を使うべきだった……
Mat.get()オーバーロードされてるじゃん……

```java

import org.opencv.core.*;
import org.opencv.highgui.*;

VideoCapture capture;

void setup(){  
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  capture = new VideoCapture(0);
  fullScreen();
}

void draw(){
  background(0);
   if (capture.isOpened()) {
      Mat video = new Mat();
      capture.read(video);
      
      byte [] b;
      b = new byte[(int)video.size().height * (int)video.size().width*3];
      
      video.get(0,0,b);
      PImage img = createImage((int)video.size().width,(int)video.size().height,ARGB);
      
      for(int i=0;i<(int)video.size().width;i++){
        for(int j=0;j<(int)video.size().height;j++){
          int p = (i+j*(int)video.size().width)*3;
          img.set(i,j,color(fix(b[p+2]),fix(b[p+1]),fix(b[p+0])));
        }
      }
      image(img, 0, 0, (int)video.size().width, (int)video.size().height);
    } 
}

int fix(int val){
  if(val>-1)return val;
  else{
    return 256+val;
  }
}

```

参考
・[cv::Matの基本処理](http://opencv.jp/cookbook/opencv_mat.html)
・[QiitaProcessingでOpenCVを使う(続き)](http://qiita.com/endoh0509/items/2b3fe05288735ac629a3)
Rubyでスクレイピングする時のTips

Rubyでスクレイピングする話をした際にまとめました
<a href="http://slides.com/kyamaguchi/capybara" target="_blank">
<img width="560" alt="web_scraping_capybara.png" src="https://qiita-image-store.s3.amazonaws.com/0/5764/7598cffd-a049-286b-b441-b9e90af169ae.png">
</a>

[Kindleの情報集めるやつ](https://github.com/kyamaguchi/kindle_manager) と[Amazonの注文履歴を集めるやつ](https://github.com/kyamaguchi/amazon_order)
で試せます

ブログ: [“Web Scraping with Capybara”](http://quattro4.hatenablog.com/entry/2017/07/08/221048)
Beautifulsoup でWebページのリンクを抽出する

参考にしたページ
[PythonでWebページのリンクを抽出するスクリプトを書いた](http://qiita.com/oshiro/items/a856fb57824c70ae7d6b)
この例は、python2 用なので、python3 用に書き換えました。
HTTP Error 403: Forbidden を回避するようにしました。

実行結果

```text
$ ./get_url.py  https://ekzemplaro.org
en/ 	 
English
ekzemplaro/ 	 
言語とデータベースの接続プログラムサンプル集
audio_books/ 	 オーディオブック
librivox/ 	 LibriVox の勧め
./audio/ 	 Audio
http://www.hi-ho.ne.jp/linux 	 オープンソース開発
./raspberry/ 	 Raspberry Pi
./storytelling/ 	 ストーリーテリング
./crowdsourcing/ 	 クラウドソーシング
https://twitter.com/ekzemplaro 	 私のツイッター
https://github.com/ekzemplaro/ 	 GitHub
qiita/ 	 Qiita
./test_dir/ 	 テストコーナー
```



```py3:get_url.py
#! /usr/bin/python
# -*- coding: utf-8 -*-
#
#   get_url.py
#
#                   Aug/18/2018
#
# ------------------------------------------------------------------
import requests
import sys
from bs4 import BeautifulSoup
#
url = sys.argv[1]
headers = {"User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:57.0) Gecko/20100101 Firefox/57.0",}
#
try:
	rr = requests.get(url,headers=headers)
	html = rr.content
	try:
		soup = BeautifulSoup(html, "html.parser")
		for aa in soup.find_all("a"):
			link = aa.get("href")
			name = aa.get_text()
			print(link,"\t",name)
	except Exception as ee:
		sys.stderr.write("*** error *** in BeautifulSoup ***\n")
		sys.stderr.write(str(ee) + "\n")
#

except Exception as ee:
	sys.stderr.write("*** error *** in requests.get ***\n")
	sys.stderr.write(str(ee) + "\n")
#
# ------------------------------------------------------------------
# ------------------------------------------------------------------
```

Arch Linux での requests と beautifulsoup4 のインストール方法

```bash
sudo pacman -S python-requests
sudo pacman -S python-beautifulsoup4
```

次のバージョンで動作を確認しました。

```text
$ python --version
Python 3.9.5
```
FedoraでVirtualBoxのGuest Additionsを有効にする


# 環境
- VirtualBox
- Fedora
  - gcc
  - perl


# 追加インストール

追加インストールを行い、一旦電源オフ

```bash
dnf install kernel-devel
halt
```

# Guest Additionsのインストール

1. 対象の仮想マシンを「選択」→「設定」
2. ストレージ  
  「SATA」（又は「IDE」）に「空のディスク」を追加
3. 対象の仮想マシンを起動
4. メニューバーから「デバイス」
5. 「Guest Additions CD イメージの挿入」
6. 『実行する』を選択すると、Guest Additionsのインストールが開始
7. インストール完了後、**電源オフ**
8. 対象の仮想マシンを「選択」→「設定」
9. ストレージ  
  「SATA」（又は「IDE」）から「VBoxGuestAdditions.iso」を除去
10. 起動
MXNetチュートリアル（gluon部）用の環境構築

# TL;DR

- [MXNet Tutorials Building neural networks imperatively with gluon](http://mxnet.io/tutorials/index.html#high-level-interface-gluon)部分をさらうためのDockerfile + 起動法の紹介
  - [公式のインストール法](http://mxnet.io/get_started/install.html) + Jupyter環境
  - 2017/7/17時点でさらうための方法、今後gluonがリリースに取り込まれた際は[公式Dockerイメージ](https://hub.docker.com/r/mxnet/python/)の方が適するハズなので要注意
  - Python3を利用、Beginer部分はコレで大丈夫でした。

**【2017/07/26追記】**
上記gluonを用いたチュートリアルは公式より一旦下げられ、http://thestraightdope.mxnet.io でホストされる模様です。

## Dockerfile
```Dockerfile
FROM ubuntu:16.04 

RUN groupadd mxnet && useradd -m -g mxnet mxnet
RUN apt-get update && apt-get install -y\
    build-essential\
    git\
    libopenblas-dev\
    liblapack-dev\
    libopencv-dev\
    python3-dev\
    python3-setuptools\
    python3-numpy\
    python3-pip\
    graphviz

# MXNetインストール
RUN git clone --recursive https://github.com/dmlc/mxnet
WORKDIR mxnet
RUN make -j $(nproc) USE_OPENCV=1 USE_BLAS=openblas
WORKDIR /mxnet/python
RUN pip3 install --upgrade pip
RUN pip3 install -e .

RUN pip3 install \
    jupyter \
    matplotlib \
    graphviz
    # Python3環境実行

RUN mkdir /home/mxnet/mxnet-tutorials
RUN chown -R mxnet:mxnet /home/mxnet
WORKDIR /home/mxnet/mxnet-tutorials

EXPOSE 8888
USER mxnet

CMD ["/usr/local/bin/jupyter", "notebook",\
    "--notebook-dir=/home/mxnet/mxnet-tutorials",\ 
    "--ip='*'",\
    "--port=8888",\ 
    "--no-browser"]

```
## 起動手順
1. docker環境を事前に構築（[dockerサイト](https://www.docker.com/)など参照）
2. Dockerfileをカレントディレクトリに配置
3. ビルド  
   ```
   docker build -t mxnet-tutorials .
   ```
4. 起動  
   ```
   docker run\
     -v $(pwd):/home/mxnet/mxnet-tutorials\
     -p 8888:8888\
     --rm\
     mxnet-tutorials 
   ```
5. 表示される`localhost:8888/?token=...` へブラウザへアクセスするとJupyterが起動している（ハズ）

# Why
2017/7/17時点でリリースされている[0.10.0](https://github.com/dmlc/mxnet/tree/v0.10.0/python/mxnet)では、[チュートリアル](http://mxnet.io/tutorials/index.html#high-level-interface-gluon)が実行できなかっため構築(公式Dockerイメージもv0.10.0)

## gluonとは

[Gluon Package](https://hub.docker.com/r/mxnet/python/)

> Gluon package is a high-level interface for MXNet designed to be easy to use while keeping most of the flexibility of low level API. Gluon supports both imperative and symbolic programming, making it easy to train complex models imperatively in Python and then deploy with symbolic graph in C++ and Scala.


高レベルインターフェースを提供するパッケージ（まだ実験的なため、変更の可能性ありとのこと…ならチュートリアルトップに載せなくても）

このチュートリアルでは、PyTorchのような実行時に勾配を自動で計算してくれるパッケージ（`autograd`）も利用するのですが、これも0.10.0では対応していない（というのは語弊があり、深い位置に配置されている模様…）ので、2017/7/17現在はmasterブランチからビルドする必要があるようです。

チュートリアルもtypoがちょこちょこあるなど荒削りで、変更されていく可能性は高そうです。試してみる方はご注意ください。
RnD for VSL rev01



```Sample TEST Movie --- Visualize Texture&Fresnel vector ---```
 
https://www.youtube.com/watch?v=k3XUha9x5m8&feature=youtu.be


---
RnD Hip Data
:VSLfor Build Custom Shader

![Rnd_Fresnel.jpg](https://qiita-image-store.s3.amazonaws.com/0/179218/e0adb322-fd3c-294f-84f3-77b331a2837e.jpeg)


 ---VEX Surface Context---
Inline Code
bind

key_function
{
_Vector:space
_fresnel
_textureMap
_uv
}

--- VEX Displace Context ---
None

--- Operation  ---
Change vector:space
_world
_object
_ndc(camera)

textureMap

Shader_DataはUpするかわかりません。
あしからず
ProcessingでOpenCVのVideoCaptureで「native codeは実行できないよ」とエラー出た時の対処法


```java

import org.opencv.core.*;
import org.opencv.highgui.*;
VideoCapture cap;

void setup(){  
  cap = new VideoCapture(0);
  fullScreen();
}
```
を実行時に次のようなエラー出る場合

```
A library relies on native code that's not available.
Or only works properly when the sketch is run as a 32-bit application.
```

JNIを使えるように一行追加してやる必要がある

```java

void setup(){  
  System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
  cap = new VideoCapture(0);
  fullScreen();
}
```

JNIって何？って方は次を参考に。
・[javaを利用したopencvにて System.loadLib](https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14161132069)
PackerでDockerイメージとAMIを構築する


# やりたいこと

環境に合わせたイメージ管理を一元化したい。
ローカル開発をDockerで、本番環境をAWS EC2で構築することを想定。
※ そもそもこの構成がよろしくない説はあります。。本番と開発環境が同環境と言えなくなるので。

# 環境

* Packer 1.0.2
* Docker 17.06.0
* Itamae 1.9.11
* direnv 2.12.1

# ソース

https://github.com/kazuma-ickw/packer-itamae/

全然量がないので、直接読む方が早いと思います。

# 内容

上記の通り、詳しくはソースをという感じなんですが、
注意点や詰まった点などを記しておきます。

## 構成

最低限のところをPackerのProvisionerで行い、それ以降はプロビジョニングツール(今回はItamae)を利用します。
最低限のところ = ruby,itamaeのインストール、itamaeの実行です。

PackerのProvisionerで頑張ってやりきることもできないこともないですが、コマンドを羅列し続けて可読性が良くなく管理しづらくなるので、プロビジョニングツールで対応しています。
Itamaeなのは慣れてるからってだけです。

Itamae側については特に通常と変わることはないです。

## sudo

今回Dockerでは、公式のcentos7のImageを使っていますが、
sudoコマンドが入ってません。
(そもそもコンテナ内ではrootで処理が行われるためだと理解してます。)

これだと他環境でsudoが必要な場面でコマンドを分けないといけないので、共通化があまりできなくなります。
なので、下記のようにdockerの場合のみsudoコマンドのインストールを追加しています。

```json:manifest.json
{
  "type": "shell",
  "inline": [
    "yum -y install sudo"
  ],
  "only": ["docker"]
},
```

## マウントのされ方の違い

```json:manifest.json
{
  "type": "file",
  "source": "{{user `itamae_repo`}}",
  "destination": "{{user `itamae_destination`}}",
  "only": ["amazon-ebs"]
},
{
  "type": "file",
  "source": "{{user `itamae_repo`}}/",
  "destination": "{{user `itamae_destination`}}",
  "only": ["docker"]
},
```

docker側にだけ、sourceの値の末尾に/をつけてます。
マウントのされ方が違くて、こうしないと想定通りのディレクトリ構成にならなかったのでこの形をとっています。

# まとめ

とりあえず、やろうと思ったことはできました。
ただやりたいことのところでも触れましたが、
そもそもコンテナとVMを一緒に管理する必要があるかというと、やってみた結果微妙な印象は受けています。。
個別で処理を分けないといけない部分もそこそこあるので、中身が膨らんできたときにしんどそうなイメージです。
(あくまで1イメージを作るものだからそんなに大きくなることはない？)
また、1コンテナ1プロセスを守ると構成的にズレが出てくるので、本来は分けるべきものかなと思います。

ただ、チームで開発する際にはイメージとして固めた状態で配れると、各メンバーの環境構築の手間と時間はかなり減るのはメリットだと思います。
イメージ作って配って各自で立てる場合だと、マスターのイメージが秘伝のタレになっていくことが懸念されますが、その際にPackerでイメージの作成手順自体がコード管理されているというのは大きな安心感を与えてくれるのかなと思います。
Python 関数の引数に内包表記


```python

nums = [1,2,3]
sum(2*x for x in nums) 

```

と書けることを知らなかったのでメモ。

実際は

```python
(2*x for x in nums) 
```
というジェネラータが作られ、関数に渡されているだけで、

```python
sum((2*x for x in nums))
```

と同じ。
Node の stream を理解する　その１

今日は、Node の Stream をちゃんと理解したいと思ったので、いくつか試してみた。

[stream-handbook](https://github.com/substack/stream-handbook)を流している。ちょっと、今まで私がやってきた言語と違う雰囲気なので、ゆっくり理解したい。

# pipe 

Node の Stream は、unix のような pipe が使えるようす。

```typescript
import * as http from 'http';
import * as fs from 'fs';
var oppressor = require('oppressor');

let server = http.createServer(function (req, res) {
    let stream = fs.createReadStream(__dirname + '/server.ts');
    stream.pipe(oppressor(req)).pipe(res);
});
server.listen(8000);
```

これっを実行すると、8000ポートでサーバが起動されて、このファイル自体を結果として返す。その際、oppressor という stream に対応したライブラリで、zip 圧縮をかけている。

![gizpcompression.png](https://qiita-image-store.s3.amazonaws.com/0/3470/501d5e59-d078-724b-7879-281bff937699.png)

Google の開発ツールで見ると、しっかりgzip がかかっているのがわかる。


# Readable

stream の Readable の、push メソッドで、Readable オブジェクトにデータを送ることができる。それをstdout にパイプして、出力している。

```javascript
let Readable = require('stream').Readable;

namespace readable {

let rs = new Readable;
rs.push("hi ");
rs.push("Now I'm in Las Vegas\n");
rs.push(null);

rs.pipe(process.stdout);

}
```

```
hi Now I'm in Las Vegas
```

`_read` というメソッドを使うと、パイプ先から必要性があるときのみ、オンデマンドで、コールバックが呼ばれる

```javascript
import {Readable} from 'stream';

namespace readable02 {
let rs = new Readable;

var c = 65 - 1;
rs._read = function () {
    if (c > 'Z'.charCodeAt(0)) rs.push(null);
    setTimeout(function() {
    rs.push(String.fromCharCode(++c));
    }, 100);
};

rs.pipe(process.stdout);


process.on('exit', function () {
    console.error('\n _read() called ' + (c - 65) + 'times');
});

process.stdout.on('error', process.exit);
}
```

```
$ node readable02.js | head -c4
ABCD
 _read() called 4times
```

ちなみに、タイムアウトを抜かすと、こんな感じになる。

```
$ node readable02.js | head -c4
ABCD
 _read() called 26times
```

結果は正しいのだが、最後の出力結果がおかしい。これは、どういうことかというと、 _read() はあくまでオンデマンドでコールされるの。最後の、`process.stdout.on('error', process.exit); ` は、head -c4 で、４つのキャラクターを読んでその後不要になったら、SIGPIPE が発生するので、それを検出して、exit イベントを発生させて、それが、`process.on('exit', ...` で検出されてこれが表示される。
　ところが、OS から、SIGPIPE が来るまでのタイムラグがあるので、タイマーで待っている状態だ。

# おまけ

さて、このプログラムをコンパイルする過程で、謎エラーに悩まされた。

```
$ tsc -p .
readable02.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'Readable'.
readble.ts(1,5): error TS2451: Cannot redeclare block-scoped variable 'Readable'.
```

tsファイルを見ても間違いが見つからず苦労したが、同じディレクトリにあるファイルがnamespace を切らずに、同じ定義をしたからだった。

ちなみに、何回typescript の環境構築しても、わすれてしまうので、メモしておく。

```
npm init
npm install -D typescript   // -D = --save-dev
tsc --init // typeconfig.json 作成
npm install @types/node --save-dev
```

今は、typings を使うことはいらない感じね。

まだまだ、Stream がまだまだので、少しづつ試してみる。