OmniAICreator/Qiita-1.07M huggingface dataset:
CentOSで動作するmailcatcherのserviceシェル

# はじめに
mailcatcherをserviceで起動させようとしたが、[こんな感じ](https://gist.github.com/augustohp/8a94c7b8b456d7a925a6)のDebian系のみ動作するのしか見当たらなかったのでRed Hat系のCentOSで動作するのを作りました

# ソースコード

``` bash
#!/bin/bash

. /etc/rc.d/init.d/functions

mailcatcher=${MAILCATCHER-/usr/local/rbenv/shims/mailcatcher}
prog=mailcatcher
lockfile=${LOCKFILE-/var/lock/subsys/mailcatcher}
RETVAL=0
STOP_TIMEOUT=${STOP_TIMEOUT-10}

start() {
        daemon $mailcatcher --verbose --http-port [http port] --smtp-port [smtp port] --ip 0.0.0.0
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && touch ${lockfile}
        return $RETVAL
}

stop() {
        echo -n $"Stopping $prog: "
        killproc -d ${STOP_TIMEOUT} $mailcatcher
        RETVAL=$?
        echo
        [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile}
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  status)
        status $mailcatcher
        RETVAL=$?
        ;;
  restart)
        stop
        start
        ;;
  *)
        echo $"Usage: $prog {start|stop|restart|status|}"
        RETVAL=2
esac

exit $RETVAL

```

ソースコードの中のhttp port や　smtp portは各自のしたい設定にしていただければ良いと思います
Gitに error: commit ハッシュ is a merge but no -m option was given. と怒られて知った マージをチェリーピックする方法

# 事象 : チェリーピックしたら起こられた
こんな状態の時にbranchCでbranchBの内容が必要になりました。

```text:状態
branchA----●---●---●---●-----☆--●--●--------
　　　　　　　　　　　　　　    ↑Merge(hashZ)
branchB(削除済)--●--●---●--●--┘

branchC--●-----●----●-----●----●---●---●-----
```

なので、cherry-pickしたらエラーになりました。

```shell-session:間違い
$ git cherry-pick {hashZ}
error: commit {hashZ} is a merge but no -m option was given.
fatal: cherry-pick failed
```
ガーン:sob:助けてGoogle先生！

## 理由 : Mergeを普通のCommitと同じようにチェリーピックしたから
> Usually you **cannot cherry-pick a merge** because you do not know which side of the merge should be considered the mainline.
> [Git - git-cherry-pick Documentation](https://git-scm.com/docs/git-cherry-pick)

Merge はちょっと工夫しないと cherry-pick できないことを初めて知りました。
Merge とはいえただのCommitだと思っていた・・・反省。

## 対応 : Merge用のオプションをつけてチェリーピックする

```shell-session:正解
$ git cherry-pick -m 1 {MergeのCommitのハッシュ}
```

やり方はこちらのサイト様に教えて頂きました。
[merge commitをcherry-pickする - Qiita](http://qiita.com/takc923/items/8e2d87d692f840b14464)
共有ライブラリを試す小さなメモ

# 前提
以下の環境を踏襲
静的ライブラリを試す小さなメモ - Qiita http://qiita.com/kure/items/a807b3b95068b407f692

# 手順

```
★ .soファイルができる
# gcc -shared -fPIC -o libsum.so sum.c
# gcc -o test2 test2.c -L . -lsum
★実行例
# LD_LIBRARY_PATH=. ./test2
★共有ファイルをリンカのパスが通った場所に置く
# cp libsum.so /usr/local/lib
★まだ認識されない
# ldconfig -p | grep sum
★1回以下コマンドを打てば
# ldconfig
★認識される
# ldconfig -p | grep sum
        libsum.so (libc6,x86-64) => /usr/local/lib/libsum.so
# ./test2
hello
5
```



# 参考
ほとんど以下記事の抜粋

C: 静的ライブラリと共有ライブラリについて - CUBE SUGAR CONTAINER http://blog.amedama.jp/entry/2016/05/29/222739
omniauth-twitterでemail情報を取得する


omniauth-twitterの[レスポンス例](https://github.com/arunagw/omniauth-twitter#authentication-hash)を確認したところ、あれれ〜emailなんてどこにも書いてないよぅ。

email情報がどうしても取得したかったので調べると[Twitter Developer Documentation](https://dev.twitter.com/rest/reference/get/account/verify_credentials)にこんな記述がありました。

> The “Request email addresses from users” checkbox is available under the app permissions on apps.twitter.com. Privacy Policy URL and Terms of Service URL fields must be completed in the app settings in order for email address access to function. If enabled, users will be informed via the oauth/authorize dialog that your app can access their email address.

以下、私的スーパー簡易翻訳

> ユーザーのemail情報が欲しくば、`Privacy Policy URL`と`Terms of Service URL`を設定せよ。そうすれば道は開かれるであろう。

設定してみた。

![Kobito.ACIMEc.png](https://qiita-image-store.s3.amazonaws.com/0/127115/b2012998-0486-84f8-776e-85aa033b8de6.png "Kobito.ACIMEc.png")

そして上記記述の通り`Permissions`を確認するとこんな欄が。

![Kobito.HK52nJ.png](https://qiita-image-store.s3.amazonaws.com/0/127115/7d3c9b6e-9cd3-06ed-9e1d-f9b9b03c951f.png "Kobito.HK52nJ.png")

チェックをつけて`Update Settings`するとSuccessfully！OK、そういうことだったか。

![Kobito.lL6WAz.png](https://qiita-image-store.s3.amazonaws.com/0/127115/d1e67cbe-ccd2-9db6-710c-e2ae43a5c355.png "Kobito.lL6WAz.png")

これでレスポンスにemailが含まれるようになった。問題は解決した。

レスポンス例

```
{
  :provider => "twitter",
  :uid => "123456",
  :info => {
  	:email => "oauth@example.com"
  	// 以下略
```

だがここでふと思い立ち、`Privacy Policy URL`と`Terms of Service URL`を消した状態で`Permissions` を確認してみた。（下図がその様子）そう、`Request email addresses from users`は初めからずぅぅぅぅぅっと表示されていた。そう見落としていたのだ。

![Kobito.q7otId.png](https://qiita-image-store.s3.amazonaws.com/0/127115/6b11ba07-cab5-31e2-deed-ab64c01fc2b1.png "Kobito.q7otId.png")

この状態でチェックをつけて`Update Settings`するとなんだか見覚えのあるエラーメッセージが表示された。

![Kobito.Pvuv0a.png](https://qiita-image-store.s3.amazonaws.com/0/127115/53b708b0-17cb-bdb4-3865-77f4fbe5d6f9.png "Kobito.Pvuv0a.png")

そう見落としていたのだ。見落としていたのだ。


1時間モッタイナイ！
MySQLの全文検索の性能調査結果

MySQLの全文検索と、like検索を比較し、性能にどのくらい差があるのか検証した。

参考URL：[Amazon RDS for MySQL と全文検索](http://dev.classmethod.jp/cloud/aws/amazon-rds-for-mysql-fulltext-search/)

##検索対象
- 1レコード24000桁の文字データを約9000件入れたテーブルを作成。
- データは青空文庫から取得

##環境
- AWSを利用
- EC2:t2.micro
- RDS:db.t2.micro

## 検証手順
1.テーブルを作成

```sql
CREATE TABLE `search` (	
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,	
  `search_text` text,	
  r_datetime datetime,	
  u_datetime datetime,	
  PRIMARY KEY (`id`),	
  FULLTEXT INDEX search_text (search_text) WITH PARSER ngram	
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
```

2.テーブルにデータを入れる。PHPのプログラムで約5分かかった。
3.データ取得時間を計測

```
SELECT count(*) from search where match(search_text)against('確信にみちみちた' in boolean mode);
```
処理時間：0.03sec

```
SELECT count(*) from search where search_text LIKE '%確信にみちみちた%';
```
処理時間：9.71sec

```
SELECT count(*) from search where match(search_text)against('電車にのった' in boolean mode);
```
処理時間：0.02sec

```
SELECT count(*) from search where search_text LIKE '%電車にのった%';
```
処理時間：0.51sec

LIKEで検索する場合の数十倍の速さで検索できることが検証できた。
Bootstrap4 beta の visible & hidden

`hidden-xs-down` = `d-none d-sm-block`
`hidden-sm-down` = `d-none d-md-block`
`hidden-md-down` = `d-none d-lg-block`
`hidden-lg-down` = `d-none d-xl-block`
`hidden-xl-down` = `d-none` (表示しない)
`hidden-xs-up` = `d-none` (表示しない)
`hidden-sm-up` = `d-sm-none`
`hidden-md-up` = `d-md-none`
`hidden-lg-up` = `d-lg-none`
`hidden-xl-up` = `d-xl-none`
`hidden-xs` = `d-none d-sm-block` (`hidden-xs-down` と同じ)
`hidden-sm` = `d-block d-sm-none d-md-block`
`hidden-md` = `d-block d-md-none d-lg-block`
`hidden-lg` = `d-block d-lg-none d-xl-block`
`hidden-xl` = `d-block d-xl-none`
`visible-xs` = `d-block d-sm-none`
`visible-sm` = `d-none d-sm-block d-md-none`
`visible-md` = `d-none d-md-block d-lg-none`
`visible-lg` = `d-none d-lg-block d-xl-none`
`visible-xl` = `d-none d-xl-block`

[ここ](https://stackoverflow.com/questions/35351353/missing-visible-and-hidden-in-bootstrap-v4)にあった
Google App Maker ー Query を使った検索のテクニック

次の画像のように一覧の上に絞り込むための条件を入れたいみたいなケースがよくある。
その場合のテクニックを紹介する。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/bed69880-54b0-f20b-07f8-d6eefe79419b.png)


そもそも App Maker ってなに？という人は、以下の記事を参照してください。
[Google App Maker とは？ 短期間で Web アプリケーション構築を可能にした理由](https://www.topgate.co.jp/what-is-google-app-maker)


# 用意するモデル
`Name` と `Email` を文字列で保持する Drive Table のモデル。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/0facd269-753c-58e0-3d60-b0759cd65b94.png)


# Query Filter を使う
基本的に絞込を行いたい場合はこれを使えばよいが、問題が発生することがある。

次のコードは `Name` と `Email` に含まれるものを検索しているが、これは `AND検索` になってしまう。
 **Query Filter では OR の指定は出来ない** ので `OR検索` をしたい場合は 次に説明する `Query Buider` を使う必要がある。

```javascript
function useQueryFilter() {
  console.log('useQueryFilter');
  
  var text = app.pages.Users.descendants.FilterText.value;
  app.datasources.User.query.filters.Name._contains = text;
  app.datasources.User.query.filters.Email._contains = text;
  app.datasources.User.load();
}
```


# Query Builder を使う
## 基本的な Query Builder の使い方
Query Builder は次の画像のようにデータソースを作るときに使うのが一般的である。
`:Value` の値は、固定値やバインディングを利用してもよいし、コードから指定することも可能。

問題になるのが、`:Value`の未指定時は一致するものがなくなるため一覧に何も表示されなくなる。
そのため検索のためだけなら問題ないが、**最初は全部表示しておくが、あとから絞り込みをおこないたい** といったケースでは使えない。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/35595/bf10acd4-4498-b499-b179-e9b48bd603a3.png)

## 応用した Query Builder の使い方
実は先程書いたような **条件文は `query.where` で指定が可能。**
これはリファレンスには載っていないので注意。
※ 筆者はエディタのコード補完で気づいた。

次のコードのように、条件が未入力時は `query.where` を空文字にして、入力時は `query.where` で条件を入れてやれば良い。
何も入力していないときは全件表示され、入力したときだけ絞り込まれたレコードが表示されるようになる。

```javascript
function useQueryBuilder() {
  console.log('useQueryBuilder');
  var text = app.pages.Users.descendants.FilterText.value;
  if (text === null) {
    console.log('指定なし');
    app.datasources.User.query.where = '';
  } else {
    console.log('指定あり');
    app.datasources.User.query.where = '(Name contains :Value) or (Email contains :Value)';
    app.datasources.User.query.parameters.Value = text;
  }
  app.datasources.User.load();
}
```


## 参考サイト
[Query Filter](https://developers.google.com/appmaker/scripting/api/client#Query)
[Query Builder](https://developers.google.com/appmaker/models/datasources#query_builder)
配列要素を１個ずつ処理する  javascript

配列の中身を１個ずつ取り出す例。

```
 var name =['木下','田中','渡辺'];
 for(var i =0; i<name.length; i++){
 document.write(name[i] + '様ですね' + '<br>');  

//木下様ですね。
//田中様ですね。
//渡辺様ですね。

  }

document.write('name=' + name +'<br>');  //name=木下、田中、渡辺
```
FIFO（先入れ先出し法） javascript

今度は、先入先出法のFIFO（first in first out）

今度は、
shift()=配列の最初を取り出す
メソッドが重要になってくる。


```
var ary=[];

ary.push('aa');
ary.push('bb');
ary.push('cc');
document.write('ary=' + ary + '<br>');  //ary=aa,bb,cc

var shift1=ary.shift();
document.write('shift1=' + shift1 + '<br>');   //shift1=aa
document.write('ary=' + ary + '<br>');  //ary=bb,cc

var shift2=ary.shift();
document.write('shift2=' + shift2 + '<br>');  //shift2=bb 
document.write('ary=' + ary + '<br>');   // ary=cc

```

プリンターの印刷街などに使用されているらしい。
Pyrhon3.6でDjango環境（Webアプリ開発）を構築

Mac OSならHOMEBREWを使うのが一番簡単。
Gotから直接ダウンロードする方法もあるけど、のちのち依存性解消が難しいので、初心者ならこちらの方法がおすすめ。

```
$ brew install pyenv
$ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
$ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
$ source ~/.zshrc
```

公式サイト通り~/.zshenvへPATHを通すと挙動が変になった。
自分がzsh環境にprezitoのプラグインを使っているのでそのせいだと思う。

ちゃんとインストールできたか確認

```
$ pyenv versions
* system (set by /Users/hiro2/.pyenv/version)
```

とりあえず最新のPythonを入れる。

```
$ pyenv install 3.6.2
```

最新のpythonをデフォルトに設定（システム共通）

```
$ pyenv global 3.6.2
```

Djangoで各プロジェクトを個別で管理できるように仮想環境を構築します。（今ならDockerの方がいいけど、初心者には厳しいので慣れてきたら構築する）

```
$ brew install pyenv-virtualenv
```
pyenv-virtualenvは、先ほどインストールしたpyenvのプラグイン。
HOMEBREWでpyenvを入れたのなら、こちらもHOMEBREWで入れないと何かしら環境依存でトラブルが起こる可能性がある。

.zshrcに下記の2行を追加する。

```
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```
pyenvのインストール時に設定したものより下に書く必要があります。

```
$ vi ~/.zshrc
```
```ruby:.zshrc
export PYENV_ROOT="$HOME/.pyenv"
export PATH="$PYENV_ROOT/bin:$PATH"

# pyenvの設定より下に書く
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"
```

プロジェクト用のディレクトリ作成
```
$ mkdir python_projects
$ cd python_projects
```

下記のコマンドで環境を作成できる
```
$ pyenv vertualenv 「pythonバージョン」　「環境名」
```

例

```
$ pyenv virtualenv 3.6.2 first-web-app
Requirement already satisfied: setuptools in /Users/hiro2/.pyenv/versions/3.6.2/envs/first-web-app/lib/python3.6/site-packages
Requirement already satisfied: pip in /Users/hiro2/.pyenv/versions/3.6.2/envs/first-web-app/lib/python3.6/site-packages
```

※pipのインストールがまだの方はこのコマンドでインストールできます。

```
 $ sudo easy_install pip 
```

環境が作成できたかどうか確認。

```
$ pyenv virtualenvs                                                                                     
3.6.2/envs/first-web-app (created from /Users/hiro2/.pyenv/versions/3.6.2)
first-web-app (created from /Users/hiro2/.pyenv/versions/3.6.2)
```


仮想環境起動

```
$ pyenv activate first-web-app
(first-web-app) ~/python_projects ❯❯❯ 
```
こんな感じでシェルが変われば仮想環境を起動できています。

環境から抜ける時はこのコマンド

```
$ pyenv deactivate
```

仮想環境に入ってから、Djangoをインストールする。

```
(first-web-app) ~/python_projects $ pip install Django 
```

Djangoがインストールされたか確認する。

```
(first-web-app) ~/python_projects $ python -m django --version
1.11.5
```

これでとりあえず開発環境は整いました。
公式のチュートリアルを進められるのでやってみることにします。
LIFO（後入れ先出法）

LIFOという後入れ先出し法（last in first out）
javascriptの配列要素の取り出し方法

最後の格納（push）したデータから取り出される方法

この方法を学ぶために
pop()=配列の最後の要素を取り出すメソッド
が重要になる

例🔻

```
var ary=['aa','bb','cc'];

ary.push('dd');
document.write('ary='+ ary + '<br>');  //ary=aa,bb,cc,dd

var pop1=ary.pop();
document.write('pop1=' + pop1 + '<br>'); //pop1=dd
document.write('ary=' + ary + '<br>');  //ary=aa,bb,cc

var pop2 = ary.pop();
document.write('pop2=' + pop2 + '<br>'); //cc
document.write('ary=' + ary + '<br>');  //aa,bb

ary.push('zz');
document.write('ary=' + ary + '<br>');   //aa,bb,zz

```


LIFOの使い方として、履歴の管理が代表的であるらしい。
戻るボタンをクリックすると、最後に追加された履歴のページから順に表示される方法が、LIFOのやり方で実現できるとの事。
プリント基板エディタpcbeで保存ファイルを書き換えて線の太さを一括変更する

# はじめに
プリント基板エディタのpcbeは複数の線の太さを一括で変更することができない。
これでは使いにくいため、保存されたファイルを編集することで一括で変更する方法を述べる。
ただし、一括編集を目的としたため、柔軟に処理できるわけではないので注意。

# 複数の線（ライン）の太さ（アパーチャ）を変更する
## データ形式
線や穴は [DrawItems] 区分に記録されている。
線はLINEで始まる行である。LINEの形式は、

| 1 | 2 |
|:-:|:-:|
|  XS |  開始X座標 |
|  YS |  開始Y座標 |
|  XE |  終了X座標 |
|  YE |  終了Y座標 |
|  LE |  レイヤー番号 |
|  AP |  アパーチャ（太さ） |

となっている。

## アパーチャ（太さ）の数値
APの数値がアパーチャの数値であるが、そのまま太さ情報が記入されているわけではない。
以下のような形式になっている。

| 1 | 2 |
|:-:|:-:|
|  0～18 |  0を0.1として、1増えるごとに0.05増える。<br>18でちょうど1.000になる。 |
|  19～242 |  19を1.100として、1増えるごとに0.1増える。<br>242で23.400になる。 |
|  243～255 |  [LineDef] 区分で指定された特別な値。 |

## 変更手順
特定のレイヤーの特定の太さの線を一括で変更したい場合は、
**LINEで始まる行の、LEが指定のレイヤー番号の、APが指定の値の行を見つけ、APを書き換える。**
という操作を行えばよい。

### 操作例
レイヤー1の太さ0.7（AP=12）を0.8（AP=14）にする。
sedコマンドを用いる。CygwinやBash on Windowsを使う。
`sed -e 's/\(LINE:.*LE=1.*AP=\)12\(.*\)/\114\2'g`
置換後の文字列は後方参照を利用しているためわかりにくいが、
`\1 14 \2`のように別れている。

# 終わりに
一括変更できると言っているが、グラフィカルに複数選択するというのではなく、数値をもとに変更しているため、「これは変更しなくてもいいのにな」などに対応することができない。

他の情報を書き換える場合も、どの項目の値がどのような意味を持っているのかを調べれば、同様に処理することができると思う。
ニコニコ動画のコメントを動画と連動してターミナル上で再生


# 動機

アマゾンプライムビデオで見られる「干物妹！うまるちゃん」をニコニコ動画のコメントと一緒に見たかった。

ニコニコ動画のコメント自体は、

[Pythonでニコニコ動画のコメントを取得する方法](http://fireflower.hatenablog.com/entry/2016/11/16/130749)

で取得して、`result.xml` というファイルに保存しておく。

下のプログラムの肝は、動画と連動してコメントを表示できることである。もちろん臨場感では本家ニコ動にかなわないが、それなりに楽しめるようになった。

# コード

```python
# -*- coding: utf-8 -*-
# For Python 2
import xml.etree.ElementTree as ET
from operator import itemgetter
import time

def vpos_str(vpos):
    sec = int(vpos / 100)
    return "%02d:%02d:%02d" % (int(sec / 60), sec % 60, vpos % 100)

tree = ET.parse('result.xml')
root = tree.getroot()
chats = [(int(c.attrib["vpos"]), c.text) for c in root.findall("chat") if c.text]
chats = sorted(chats, key=itemgetter(0))
st = int(time.time() * 100)
i = 0
while i < len(chats):
    time.sleep(0.01)
    t = int(time.time() * 100) - st
    while i < len(chats) and chats[i][0] <= t:
        print(u"%s %s" % (vpos_str(chats[i][0]), chats[i][1]))
        i += 1
```

# 実行結果

```
00:01:18 見納め
00:01:55 買った。
00:06:31 !
00:10:91 課金した！
00:11:83 うまるーん
00:14:39 だれ
00:15:79 誰だお前！？
```
github(git)アカウントを複数使用するときに切り替えれるようにしたメモ

# 1.ユーザーを切り替える
`git config --global`で変えることにした。

```
git config --global user.name 'なまえ'
git config --global user.email hoge@email.fuga
```

このコマンドを実行するのは面倒なのでシェルスクリプトを作る


switch-git-user-username1.sh
switch-git-user-username2.sh

見たなのを作る
（いいネーミングがあればコメントしてください。。。）

```
#! /bin/sh
git config --global user.name 'なまえ'
git config --global user.email hoge@email.fuga
```
ファイルごとになまえとメールアドレスは変える

.shファイルには実行権限を付与する

あとは実行。
```
./switch-git-user-username1.sh
```

これで切り替える　
bash/zshの設定でコマンドのようにしたほうがいいかも
今度やろ。。。


# 2.ssh設定

## 鍵を作る
鍵はメールアドレス指定で作成ここの記事を参考に作る
http://chie.hatenablog.com/entry/2012/04/24/011052

## .ssh/config に設定

どこの設定記事でもいいからそれ通りやる
http://qiita.com/merrill/items/80a8d8a152e2483fa587

動作確認は1.でつくったshで切り替えてからやる。

もっとこうしたほうがいいとかあったらコメントよろしくお願いします。
もう疲れた。。。
Prophetでビットコインの価格推移を予測してみる

「[Prophetで遊んでみる](http://qiita.com/namakemono/items/04ed257f8b7c7964a341)」の続きで，ビットコインの価格の推移を予測してみました．

## Datasets

- From: 2017-05-27
- To: 2017-09-08

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/cc45299d-e89d-7368-394b-9f58a92608ea.png)


![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/7b769990-0b0b-0036-be55-3f3f0c464693.png)

- 最近のトレンドとしては上がり調子ということらしい．
- 週ごとの傾向としては「火曜日に買って日曜に売れ」ということらしい．

胡散臭いので，もう少し調べてみる．

## 性能検証

- 訓練データ: 2017-05-27 〜 2017-08-31
- 検証データ: 2017-09-01 〜 2017-09-08

としてSMAPE[^1]で性能を調べてみる．

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/d2533c4f-c338-7448-2314-c7d4736a6832.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/107399/c32015a8-6aa9-a668-f0d3-33573a11508a.png)

- 期間を少し変えるだけで，weeklyの傾向が変わってる．どゆこと？？

#### changepoint_prior_scale=0.05(default)の場合

```python
y_true = forecast["y"].values
y_pred = forecast["yhat"].values
print "FORECAST SMAPE: %.3f" % smape(y_true, y_pred)
# FORECAST SMAPE: 4.238
```

#### changepoint_prior_scale=0.01の場合

```python
y_true = forecast["y"].values
y_pred = forecast["yhat"].values
print "FORECAST SMAPE: %.3f" % smape(y_true, y_pred)
# FORECAST SMAPE: 4.197
```

デフォルトよりは少し改善

#### 検証データの期間中の中央値(参考)

```python
y_median = np.asarray([np.median(y_true)] * len(y_true))
print "MEDIAN SMAPE: %.3f" % smape(y_true, y_median)
# MEDIAN SMAPE: 2.922
```

将来のデータの中央値なんてわかるわけないけど，目安として出す．
中央値を使ったほうが性能は良いので，まだまだ予測の改善は必要そう．

## まとめ

- Prophetを使ってビットコインの価格推移を予測
- weeklyの傾向は，わずかな期間の変動で変わるので当てにならなさそう．
- changepoint_prior_scaleの最適なパラメータ求めることで多少は改善される？

## References

[^1]: [Symmetric mean absolute percentage error](https://en.wikipedia.org/wiki/Symmetric_mean_absolute_percentage_error)
macOSのRe:VIEWでPDF出力時にランタイムエラーになったのでfishのPATHを見直した

---

追記: fishでebbへのPATH指定したら解決しました

> set -U fish_user_paths /Library/TeX/texbin $fish_user_paths

---

macOSのfishシェルを使っていて、Re:VIEWでPDF出力時にランタイムエラーになったのでbashで実行したら解決した（上に追記しているようにfishのPATHでebb指定して解決しました）。


環境は

- ruby: v2.4.1
- mactex-20170524.pkg
- review: v2.3.0

macOSで `review`と `md2review`をインストールしてpdf作成しようと思ったら下記のようなエラーが出た（カレントディレクトリはRakefileや.reファイルがある場所）。

```
➤ bundle exec review-pdfmaker config.yml
compiling iosdc2017guide.tex
bundler: failed to load command: review-pdfmaker (/Users/yimajo/.rbenv/versions/2.4.1/bin/review-pdfmaker)
RuntimeError: failed to run command: ebb cover.jpg
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/lib/review/pdfmaker.rb:42:in `system_or_raise'
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/lib/review/pdfmaker.rb:275:in `block in copy_images'
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/lib/review/pdfmaker.rb:268:in `chdir'
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/lib/review/pdfmaker.rb:268:in `copy_images'
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/lib/review/pdfmaker.rb:235:in `generate_pdf'
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/lib/review/pdfmaker.rb:132:in `execute'
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/lib/review/pdfmaker.rb:86:in `execute'
  /Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/review-2.3.0/bin/review-pdfmaker:18:in `<top (required)>'
  /Users/yimajo/.rbenv/versions/2.4.1/bin/review-pdfmaker:22:in `load'
  /Users/yimajo/.rbenv/versions/2.4.1/bin/review-pdfmaker:22:in `<top (required)>'
yimajo@mbp2016:~/D/i/iosdc2017guide
```

エラーとしては `ebb cover.jpg` で失敗している。ebb自体がツールでそれがインストールされていないかパスが通っていないのかとこのときは思っていた。

コマンド `bundle exec review-pdfmaker config.yml`でなく`bundle exec rake pdf --trace`でも同じらしいので原因を調べる

抜粋すると次のように画面出力されていた

```
rake aborted!
Command failed with status (1): [review-pdfmaker config.yml...]
/Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/file_utils.rb:66:in `block in create_shell_runner'
/Users/yimajo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/file_utils.rb:56:in `sh'
```

`create_shell_runner` はおそらく例外を発生させている箇所だが、要するにシェルが実行できていない様子でebbが見つからなかったらしい。

結局、とりあえずbashに切り替えるか、上に追記しているようにfishでパス指定して解決した。
新しくなったYoutubeの字幕XMLをSRTファイルに変換するツール

Youtubeのある動画の字幕の自動翻訳が気に食わなくて
もう少しマシな翻訳にしたいなと、Chromeのデベロッパーツールで字幕ファイルをダウンロードした。

見たことがない形式だったので、使いやすいSRTファイルに変換しようとしたが現在の字幕ファイルに対応しているツールは見つからなかった。

しかたないので、適当に変換ツールを作ってみました。
[こちら](https://run.plnkr.co/plunks/bI6YETzlcP6aJRomHiwK/)
誰かの役に立てたら幸いです。

ソースコード

```html
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script>
$(function(){
  $("#datafile").on("change", function(){
    var file = $(this).prop('files')[0];
    var fileRdr = new FileReader();
    
    if(!this.files.length){
      return;
    }
    
    fileRdr.onload = function() {
      $("#src").text(fileRdr.result);
    }
    fileRdr.readAsText(file);
  });
  
  $("#execute").on("click", function(){
    var text = "";
    var cnt = 0;
    $($("#src").text()).find("p").each(function(){
      if($(this).text().length > 1 || $(this).text() != "\n"){
        text += (++cnt) + "\n" + tick2time($(this).attr("t")) + " --> " + tick2time($(this).attr("t")*1 + $(this).attr("d")*1) + "\n" + $(this).text() + "\n\n";
      }
    });
    $("#dst").text(text);
  });
  
  function tick2time(tick){
    var h, m, s, ms;
    ms = tick % 1000;
    tick = Math.floor(tick/1000);
    s = tick % 60;
    m = Math.floor(tick / 60) % 60;
    h = Math.floor(tick / 3600);
    return ( "0" + h ).slice( -2 ) + ":" +
           ( "0" + m ).slice( -2 ) + ":" +
           ( "0" + s ).slice( -2 ) + "," + 
           ( "00" + ms ).slice( -3 );
  }
  
});
</script>
<title>timedtext.xml to srt Convertor</title>
</head>
<body>
<h1>timedtext.xml to srt Convertor</h1>
<input id="datafile" type="file" accept="text/plain,text/xml"/>
<br>
<b>source</b><br>
<textarea id="src" rows="10" cols="100"></textarea><br>
<br>
<button id="execute">Convert</button><br>
<b>dest</b><br>
<textarea id="dst" rows="40" cols="100"></textarea><br>
</body>
</html>
```

こんなダサいツールではなく、ちゃんとしたのを誰かが作ってくれることを期待します。(^^;
指定した人物の顔画像を自動収集するプログラムの公開と使い方

###追伸 (17/10/04)
スクレイピング元の仕様で一度に収集可能な枚数が最大60枚までだった為120枚まで対応しました。
###追伸 （17/10/11）
カスケード分類ファイルがなかったので追加しました。
###追伸 (18/04/14)
一度に収集可能な枚数を120枚から無制限にしました。
その部分のコードがin locals()とか使っててちと汚い
#はじめに
人物の顔をテーマにして機械学習でイロイロすることはけっこうあると思うのですが、いちいち拾ったり加工したりするのが面倒臭いので全て自動でやってくれる物をつくりました。
もうすでに誰かが作っていそうな気がしましたがそのまま使える物は無かったのでここに公開します。


[ダウンロード（github）](https://github.com/XXXalice/FaceImageCollector)

#使い方
以下の二つを持っていない場合は入れてください。すいません…
・OpenCV3系列
・BeautifulSoup4系列

インターネットから収集するため実行する端末がネットに接続されているか確認してください。

FaceImageCollector>image_gather>gather.pyを実行してください。
キーワード、枚数、編集モードの順で訊かれます。

![スクリーンショット 2017-09-08 20.38.36.png](https://qiita-image-store.s3.amazonaws.com/0/160607/90931947-505d-e25f-2917-59bb57bada0a.png)

画像ではザッカーバーグの画像を30枚、顔をトリミングする設定にしてみました。
ダウンロードが始まります。

![スクリーンショット 2017-09-08 20.40.04.png](https://qiita-image-store.s3.amazonaws.com/0/160607/dcbbb72f-3261-8c9c-1600-fcb133cac697.png)

指定した枚数終了すると、imgフォルダがimage_gather内に生成されそこに今回指定したキーワードのフォルダが作成されます。

![スクリーンショット 2017-09-08 20.25.34.png](https://qiita-image-store.s3.amazonaws.com/0/160607/21035067-236f-824d-b9e9-232803c00642.png)


#改良内容
・人物以外に物体がキーワードとして入力された際も自動トリミングを行える様にする。
・輪郭描画は未実装のため実装する。（応急措置として検出された顔に四角形を描画するようにしてある）

その他自動で出来たら便利そうなアイデアがありましたらぜひ教えて頂けると嬉しいです！


#おわりに
長いコードではありませんが、時間ができたら解説をします。
ここまでご覧いただきありがとうございました！
メモ: framebufferを利用

* [仮想コンソールで日本語表示 - 01647](01647.hateblo.jp/entry/2014/10/20/141331)

## インストール

```
apt install -y fbterm
```

> $ fbterm
> can't open frame buffer device!
> mmap /dev/zero: Operation not permitted
> Using VESA requires root privilege

## 準備

```rb
$ ls -l /dev/fb0
crw-rw---- 1 root video 29, 0  9月  5 15:04 /dev/fb0
```

* 方法1
    * /etc/group にて video グループに追加

```sh:方法2
sudo gpasswd -a $USER video
```

```sh:方法3
sudo chmod u+s /usr/bin/fbterm
```

## フォント変更

```diff:~/.fbtermrc
- font-size=12
+ font-size=20
```

## uim

```sh:~/.uim
(define uim-pref-suppress-dot-uim-warning-dialog? #t)

(define-key generic-on-key? '("<Control> " "<Control>\\"))
(define-key generic-off-key? '("<Control> " "<Control>\\"))
```

```sh:
apt install -y uim-fep uim-mozc
```

```sh:起動
uim-fep

もしくは

fbterm -- uim-fep -u mozc
```

* `control-space`で日本語入力on/offになります。

## 解像度

* [Linux/Console - matoken's wiki.](http://hpv.cc/~maty/pukiwiki1/index.php?Linux%2FConsole)

```sh
sudo apt install -y hwinfo

# 利用できる解像度一覧
sudo hwinfo --framebuffer
```

* 1920x1080がなかったため他の方法を探す

## 画像表示

```
apt install -y fbi

fbi *.jpg
```

## マウス

```sh:ubuntu17.04は最初からマウス使えたかも
apt install -y gpm

gpm
```

## vnc client

```
apt install -y directvnc

directvnc server:port
```

> Couldn't parse the keyboard mapping file (null). Exiting

が出て接続ができなかった...
termuxで好きなフォントを使う方法

# きっかけ
neovimでpowerlineパッチを当てたフォントで表示したいと思った
（後から気付いたがもともとインストールされているフォントもpowerlineパッチが当たっているものがあった）

# 試した環境
Termux 0.53
Termux:Styling 0.19

# 方法

 `/data/data/com.termux/files/home/.termux/font.ttf`
を置き換えたいフォントで上書き

以上
Activity間のObject引き渡し

# 方法
いくつか方法はあると思うが、
そんなに大したことないものにコードを沢山書きたくないので、
シンプルにobjectにSerializableをimplementsして引き渡す

Gsonを利用した例はコチラ
[Activity間のObject引き渡し（Gson）](https://qiita.com/ijichi_y/items/82d9ed07dbe94a5fd964 "Activity間のObject引き渡し（Gson）")

# 実装

## object
Activity間で引き渡すobject

```DataState.kt
data class DataState(
    val id: Int,
    val name: String
): Serializable
```

## Activity
引き渡し元

```MainActivity.kt
class MainActivity : AppCompatActivity() {

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

        val intent = Intent(this, SecondActivity::class.java)
        val state = DataState(0, "name0")
        intent.putExtra(SecondActivity.KEY_STATE, state)
        startActivity(intent)
    }
}
```

引き渡し先

```SecondActivity.kt
class SecondActivity : AppCompatActivity() {

    companion object {
        val KEY_STATE = "key_state"
    }

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

        val state = intent.getSerializableExtra(KEY_STATE)
        if(state is DataState){
            println(state.id)
            println(state.name)
        }
    }
}
```

# 出力結果

```
0
name0
```

# list objectの引き渡し

## Activity
引き渡し元

```MainActivity.kt
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val states = arrayListOf<DataState>()
        for(i in 0..2){
            val state = DataState(i, "name$i")
            states.add(state)
        }

        val intent = Intent(this, SecondActivity::class.java)
        intent.putExtra(SecondActivity.KEY_STATE, states)
        startActivity(intent)
    }
```

引き渡し先

```SecondActivity.kt
class SecondActivity : AppCompatActivity() {

    companion object {
        val KEY_STATE = "key_state"
    }

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

        val states = intent.getSerializableExtra(KEY_STATE) as ArrayList<*>

        states.forEach {
            if(it is DataState){
                println(it.id)
                println(it.name)
            }
        }
    }
}
```

# list object 出力結果

```
0
name0
1
name1
2
name2
```

# まとめ
とりあえずobjectがSerializableをimplementsしておけば
そのままだろうが、listにしようが引き渡せます。

GitHubに公開しました。
https://github.com/yoshihitoijichi/ActivityIntentObjectSample
phantomJSを1からインストールする

---
※ 【注釈】2017/9/10現在、PhantomJSの開発は公式にメンテナンス停止がアナウンスされているそうです。
JSを用いたスクレイピングであれば「nightmare」「puppeteer」を使用したほうが良いらしい。（Quramy様ご指摘ありがとうございます。）
nightmare ⇨　https://github.com/segmentio/nightmare
puppetter ⇨　https://github.com/GoogleChrome/puppeteer

----

最初はmechanizeでスクレイピングしようとしてました。ただ、JSによって動的に生成されたページに対応できなかった（僕の技術力では）ので、他の方法を探していたところ、phantomJSに出会ったわけです。

## 諸々のインストール
phantomJSを使うのに必要な諸々をインストールしていきます。Homebrewは入っている前提です。

- まずはnode.JSのインストールから。　その前に複数バージョンを管理するためにnodebrewをインストール

```zsh:terminal
$ brew install nodebrew
$ nodebrew setup //これをしないと次のコマンドでエラー吐く。必要なフォルダ等々を生成してくれるらしい
```

- nodebrewのパスを通す

```zsh:terminal
$ nodebrew setup
Fetching nodebrew...
Installed nodebrew in $HOME/.nodebrew

========================================
Export a path to nodebrew:

export PATH=$HOME/.nodebrew/current/bin:$PATH
========================================
```
と出てくるので、言われるとおりにパスをbash_profileに書き込んで、読み込み。

```zsh:terminal
$ echo export PATH=$HOME/.nodebrew/current/bin:$PATH >> ~/.bash_profile //書き込み
$ source ~/.bash_profile //読み込み
```

- （やっと）node.jsのインストール

```zsh:terminal
$ nodebrew install-binary latest //最新版のインストール

//もしくは

$ nodebrew install-binary stable //安定版のインストール
```

- 使用するnode.jsのバージョンを指定

```zsh:terminal
$ nodebrew list
v8.4.0

current: none 
//⇑これが指定されていない状態

$ nodebrew use v8.4.0 //使用するバージョンを指定。

$ nodebrew list
v8.4.0

current: v8.4.0
//⇑無事指定できました
```

- npmの生存確認

```zsh:terminal
$ npm -v
5.3.0 //生きてた
```

- npmを用いたphantomJSのインストール

```zsh:terminal
$ npm install -g phantomjs //ようやっとインストール
```

- phantomjsの生存確認

```zsh:terminal
$ phantomjs -v
2.1.1 //生きてた
```

以上です、次はこれを使っていきたい
Xcode8でiOS11beta端末の動作確認がしたい（iOS11実機ビルドしたい）Could not locate device support files.エラー

# 概要
- そろそろiOS11が正式にリリースされそうですね:runner_tone3:
- Xcode9 betaで計画的に開発を進めている方々もいると思いますが、


:fearful: `「Xcode9&iOS11対応は全然間に合わない・・うぅ・・」`
:mask:` 「とりあえず現状のXcode８でビルドしたPKGがiOS11betaで動くか確認だけしておこう・・」`
っていう人もいると思います。


> →しかし、Xcode８でiOS11を接続してビルドはできません:joy::joy::joy:

## 想定利用パターン
### とりあえずiOS11 beta動作確認しようとしてみる
- ***パターン1***
- →普通にAppStoreに上がってるPKGをiOS11beta端末にインストール

```
「あぁぁああああ！！全然動かないぃいい！！！画面ぶっ壊れてる・・・直したい・・・
↓
「デバックしてみよ」
↓
iOS11beta端末を繋いで、Xcode８でデバックしようとしてみる・・
↓
！！！！！！
```

- ***パターン2***
- →Xcode8にiOS11端末接続してビルド

```
iOS11beta端末を繋いで、Xcode８でビルドしようとしてみる・・
↓
！！！！！！
```


↓↓↓↓↓
<font color="DeepPink">Xcode8はiOS11端末を認識してくれません・・:eye::eye:</font>
***「Could not locate device support files.」***
<img src="https://qiita-image-store.s3.amazonaws.com/0/187252/af027083-c570-0986-634b-e4b634987d8b.png" width=50%>

(昔は、「Could not find Developer Disk Image」とかだったかな？)

# :fist: →裏技 :fist:
以下の手順で、とりあえずできるようになります。
（現状できていますが、今後の保障はできません）

### 事前準備
- Xcode9最新beta版を用意
https://developer.apple.com/xcode/download/
![image.png](https://qiita-image-store.s3.amazonaws.com/0/187252/8c2fb35d-a723-1f6c-a46b-80186e04e5a6.png)

- :writing_hand:インストール方法などわからない人はこちらの記事をどうぞ
→[【初心者向け】Xcode 9 (beta) 入れたい（；；）](http://qiita.com/keroppi0_0/items/8396e05b57e377b9eaa0)

### 作業
- ダウンロードしたファイルとかから、「パッケージの内容を表示」を開く
 <img src="https://qiita-image-store.s3.amazonaws.com/0/187252/d559666e-e9c2-698d-e568-d7901d711dbe.png" width=60%>

↓**以下のファイルを探す** ↓

- **「Xcode-beta.app→Contents→Developer→Platforms→iPhoneOS.platform→DeviceSupport→11.0」**
- `（/Volumes/Xcode/Xcode-beta.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport）`
![image.png](https://qiita-image-store.s3.amazonaws.com/0/187252/a835d5d9-838d-e51c-7446-b0b7c8ca6bcb.png)

↓↓↓↓**その「11.0」フォルダごと、既存のXcode8のフォルダに突っ込む**↓↓↓↓

- Xcode再起動

→これで無事に認識してくれるようになります。

:bow:**おつかれさまでした**:bow:
MinecraftのmoddingでfatJarを作る

#そもそも、fatJarって？
サードパーティー製のライブラリなどを使った時に、そのライブラリも含み、全てを1つのjarファイルにしたもの（だと思っている）。

#今回の環境
1つ目
・IntelliJ IDEA CommunityEdition 2016.3.4
・Forge 1.7.10-10.13.4.1614
・Forge Gradle 1.2

2つ目
・IntelliJ IDEA CommunityEdition 2016.3.4
・Forge 1.11.2-13.20.1.2386
・Forge Gradle 2.2-SNAPSHOT

#どうやるの？
1. build.gradleを開く
2. 以下のソースを追加（もし、minecraft{}などが既にあった場合、そこに追記する形で）
3. buildタスクを実行したらfatJarの完成！

**※<>は書かないでください。
また、minecraft,configrations,dependencies,jarの順番はこのままでお願いします。
下記コードで「ここから」と「ここまで」の間は1.11.2の環境では消してください。**


```gradle
//ここから
minecraft {
    srgExtra "PK: <そのライブラリのルートディレクトリ> <jarファイルにした時のパス>"
}
//ここまで

configurations{
    shade
    compile.extendsFrom shade
}

dependencies {
    <compileをshadeに変更、詳しくは下で>
}

jar {
    configurations.shade.each {dep ->
        from(project.zipTree(dep)){
            exclude 'META-INF', 'META-INF/**'
        }
    }
}
```

#使用例(必要な部分のみ)
```gradle
//ここから
minecraft {
    srgExtra "PK: com/fasterxml/jackson/annotation com/fasterxml/jackson/annotation"
    srgExtra "PK: com/fasterxml/jackson/core com/fasterxml/jackson/core"
    srgExtra "PK: com/fasterxml/jackson/databind com/fasterxml/jackson/databind"
}
//ここまで

configurations{
    shade
    compile.extendsFrom shade
}

dependencies {
    shade group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.9.0'
}

jar {
    configurations.shade.each {dep ->
        from(project.zipTree(dep)){
            exclude 'META-INF', 'META-INF/**'
        }
    }
}
```
menuの一部のアイコンを隠す

# menuについて
画面上部ツールバーに配置する複数存在するボタンをカスタマイズできる

# 実装
カスタムメニュー用xml
今回はメニューを２つ配置

```main_menu.xml
<menu
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item
        android:id="@+id/main_menu_1"
        android:icon="@android:drawable/ic_menu_account_list"
        android:title="menu1"
        app:showAsAction="ifRoom"/>

    <item
        android:id="@+id/main_menu_2"
        android:icon="@android:drawable/ic_menu_add"
        android:title="menu2"
        app:showAsAction="ifRoom"/>

</menu>
```

menu1のみ隠す

```MainActivity.kt
    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.main_menu, menu) // カスタムメニュー設定
        val menu1 = menu?.findItem(R.id.main_menu_1) // menu1取得
        menu1?.isVisible = false　// 隠す
        return true
    }
```
ちょっとずつ読むドメイン駆動設計 第一部 ドメインモデルを機能させる 第ニ章 コミニュケーションと言語の使い方9

# 振る舞いと表現
> メソッドの名前は、あいまいだったり、誤解を招いたり・・・
> 変数名とコードの構成が伝える内容はそうではない。優れたプログラミングの作法によって、このつながりはできるだけ直接的に保たれるが、それは自分を律した結果でしかない。正しいことを**する**だけでなく、正しいことを**言う**コードを書くためには潔癖でなければならない。(第一部 第二章より）

振る舞いというのは、動くので、それ自体が現実です。（正しいかどうかは別として・・・)

ただ、クラス名やメソッド名・変数名などは、たとえあいまいであってもコードは問題なく動作する。

そういう意味で、正しいことをする（振る舞い）だけでなく、正しいことを言う(名前)ことが大事で、そうするためには、『自分を律して』『潔癖』でなければならない、、、ということですね。

どう正しくするか。それは言うまでもなく、ユビキタス言語の言葉を使うこと。その言葉でドメインエキスパートや開発者同士で会話することです。

ただ、動くようにプログラムを書く、または、動かすように頭を使うというのとは全く別の視点の能力が必要になりそうですね。

自分を律して、潔癖にモデルを維持する！
DB Tech showcase Tokyo 2017で登壇しました！

お恥ずかしながら、DB Tech showcase Tokyo 2017にて、JPOUG　15minuteで登壇しました。

その際に使用した資料を公開しましたので、よろしければご覧ください。

https://www.slideshare.net/secret/4ECvEeYRU4BAk5
Faust : 初めてのVSTプラグイン

結論：独特。だけど使える。

[Faust勉強会私的メモ](http://qiita.com/migizo/items/fba5958236476ee93314)を読んでなかなか良さげな感じがしたので、さっそくいじってみました。

お仕事でよく使うnyquistスクリプトがあるのですが、これがVSTプラグインだったらもっと捗るのになあ、と思っていたのです。
今回はそれに 挑戦してみました。

元になるnyquistスクリプト：

```Lisp:
(allpass2 (allpass2 (allpass2 (allpass2 s 250 1.5) 700 4.5) 1250 6.3) 1600 15)
```

中域だけ約2msのディレイがかかるという微妙なエフェクトです。

これをFaustに移します。
FaustLive.appの例からAPFのを持ってきてちょこっと修正。

```Java:
declare name "APFDelay";

import("maxmsp.lib");

APFSt(F,Q) = APF(_,F,0,Q),APF(_,F,0,Q);

process = APFSt(250,1.5):APFSt(700,4.5):APFSt(1250,6.3):APFSt(1600,15);
```

+ 名前をつけて、
+ APFが入ってるライブラリを読み込み、
+ ステレオのAPFを作り、
+ 決った値で四つ直列でかける

できた!
で、VSTでエクスポートして、と...
動いた!
Audacityでnyquistかけるのとほんのちょっと微妙に違ってるけど、十分です。使える。

確かに文法は独特ですが、グラフにして見せてくれるので、別の意味で分りやすい。
なによりこんなに簡単にVSTプラグインが作れるなんてすごすぎます。
法人番号を取得してくるマクロ

##企業名のばらつきを修正する
現在の顧客情報は、企業名そのものにも大きなばらつきがあって、社名が変更されたりするとお手上げになるし、企業ごとの売上の集計もできないのが現状でした
・○○コーポレーション
・○○・コーポレーション
の程度であれば良いのだが、
・○○商事株式会社
・○○商事営業部
・○○商事株式会社営業
・○○商事日本橋営業所
なんていうレベルである（実際はもっとすごい）。

##せっかくなので法人番号を取得して、それを一意のコードと結びつけようと考えた
http://www.houjin-bangou.nta.go.jp/
＊法人番号の利用開始については、[法人番号システムのWeb‐API機能をビジネス活用しよう（申請編）](http://qiita.com/y-okuda/items/c45064f23f7785465372)を参考にさせていただきましたありがとうございます

で、前に使っていた「郵便番号から住所を取得するマクロ」をベースにして作ってみたのがこちら(idのところはｘに置換してます)

```法人番号取得.vba
Option Explicit

Sub run()
'---------------------------------------
Dim CorpName As String
Dim i As Long
Dim arr As Variant
For i = 2 To ThisWorkbook.Sheets(2).Cells(Rows.Count, 2).End(xlUp).Row
CorpName = Cells(i, 2)
On Error Resume Next
arr = CorpCode(URL_Encode(CorpName))

Cells(i, 4) = arr(4)
Cells(i, 5) = arr(9)
Cells(i, 6) = arr(12)
Cells(i, 7) = arr(13)
Cells(i, 8) = arr(14)　
 
Next i
End Sub
```
```データを持ってくる関数.vba
Function CorpCode(CorpName As String) As String()
Dim objXMLHttp As Object
Dim tmp
Set objXMLHttp = CreateObject("MSXML2.XMLHTTP")
    objXMLHttp.Open "GET", "https://api.houjin-bangou.nta.go.jp/2/name?id=xxxxxxxxxxxxxxx&type=02&mode=2&name=" & CorpName, False
    objXMLHttp.Send

    tmp = Split(Replace(objXMLHttp.responseText, """", ""), ",")
    CorpCode = tmp
'---------------------------------------
End Function
```
```UTF-8にエンコードする関数.vba
Function URL_Encode(ByVal strOrg As String) As String
  With CreateObject("ScriptControl")
    .Language = "JScript"
    URL_Encode = .CodeObject.encodeURI(strOrg)
  End With
End Function
```
ExcelはShift-JISでデータを持っているので、URL-Encode関数に放り込んで、jScriptで企業名をUTF-8にエンコードしています
UTF-8じゃないとURLはエラーになってしまうのを防ぎます
CorpCode関数内でGETリクエストを生成してCSVの配列として戻り値を得て、そこから欲しいデータ

4=法人番号
5=法人名
12=都道府県
13=市区町村
14=以下の住所

をセルに展開しています。
Corei3、4GBメモリ、Excel2013の環境で200件が3分くらいのペースでした

##課題
・部分一致でデータを拾っているので、似たような社名だと最初に引っかかった企業名になる
複数のレスポンスがあるはずなのでそこから住所などで更に絞り込む。という方法も考えたのですが、弊社の場合は営業所などで受注していることもあるため、うまくいかないだろうと考えました。法人番号を引けなかったものを含めて、目でチェックする必要性は消えないので、ここは手動で行うことにしました
WindowsでGitをCUIで使いたい人向け


簡単に書いてみた。（といっても、参考になったリンクをペタペタしただけ）
[今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説](https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000)  
GitHubやgit-scmの公式HPに、ユーザーのお気に入りのコンソールでGitを使うための方法は以下リンクに示されているが、コマンド操作や通信方式についての理解が足りないと読み砕くのが少々大変である。上記サイトは、以下のCUI環境でのGitを使うにあたってかなり参考になった。GitとGithubの違いから説明してくれてるのでありがたかった。  
[GitHubHelp Authenticating to GitHub](https://help.github.com/categories/authenticating-to-github/)
[git-scm Git Documentation](https://git-scm.com/docs/git-config)  
慣れてきたらこちらも一度読み返す必要はあるだろう。


# CUI環境を使うメリット
**まずはGitはCUIで使うべし**
Gitを使い始めた頃から今まで、[SourceTree](https://www.sourcetreeapp.com/)を使って視覚的にソース管理を行っていたが、いまいちGit特有の操作について、それぞれの意味と、効果的に使う方法を熟知していなかった。
SourceTreeから離れてCUIを使おうと思い立ったのは、SourceTreeの更新に失敗して、アンインストールも再インストールもできなくなり、どうも困った状況に立たされ、やらなければならないタスクにも期限があるので、新しく「[Git for Windows](https://git-for-windows.github.io/)」を使い始めた次第だ。

主なプロセスは
    1. Git for Windows (Gitシステム+CUI環境)のインストール
    2. Githubのアカウント登録
    3. SSH通信を使ったリモートリポジトリへのアクセス方法（コマンド）
特にSSH通信方式についてのおすすめの設定を以下に記述する。
SSHの理解については、以下のリンクを参考にした。
[公開鍵暗号について理解が足りていなかったのでメモ](http://d.hatena.ne.jp/kasei_san/20120329/p1)
[SSHなるものをよくわからずに使っている人のための手引書](http://qiita.com/kenju/items/b09199c4b3e7203a2867)
[SSH秘密鍵のパスフレーズは（つけるなら）11文字以上にしましょうねという話](http://freak-da.hatenablog.com/entry/20100901/p1)

## Git for WindowsのダウンロードとGitHubアカウントの登録方法
Git for Windowsのダウンロードに関しては、以下のリンクを参考にした。
[今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説](https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000)(再掲)

## SSH通信を使ってリモートリポジトリにアクセスする際の工夫  
[[git for windows] git bash すると ssh-agent を自動で起動](http://d.hatena.ne.jp/himadatanode/20160823/p14)
[ssh-agentを使って公開鍵認証方式のsshパスワード入力を省略する方法](http://www.server-memo.net/server-setting/ssh/ssh-agent.html)

## その他リンク
* 各ホームページ  
[Git HP](https://git-scm.com/)  
[GitHub HP](https://github.com/)  
* Vimを使い始めたので。。。  
[よく使う Vim のコマンドまとめ](http://qiita.com/hide/items/5bfe5b322872c61a6896)  
[クリップボードとvimの間を自由にコピペする方法](http://naoyashiga.hatenablog.com/entry/2013/10/18/224010)
* アクセス権について（秘密鍵の権限変更の際に使った）  
[パーミッションとは？](http://www.purasusikou.com/muras/cgisoft/permission.html)  
* ほしい  
[Shibart](https://shibart.pocke.me/shibas/33)  
* その他  
[正しいコーディングが身につくエンジニア英語の手引き](http://www.find-job.net/startup/english-for-engineers-naming-conventions)  
[GitHub Flow](http://scottchacon.com/2011/08/31/github-flow.html)  
[Pro git](https://git-scm.com/book/ja/v2)
scss-lintのgem名が変わっていてハマった話


# 要約
gemの名前が変わってるよ、ということ。
`scss-lint`ではなく`scss_lint`。
ハイフンがアンダースコアに変わっているので`gem update`とか`gem install`するときは注意しましょう。
~~紛らわしいんじゃﾌｧｯ◯！！~~

# 事の顛末
「そう言えばAtomのpackage更新してなかったなぁ」と思ってまとめて更新かけたらlinter-scss-lintがエラー吐くように…
![スクリーンショット 2017-09-08 18.32.23.png](https://qiita-image-store.s3.amazonaws.com/0/109065/04dc1658-31a5-3f3a-15e6-b334e2e6077d.png "スクリーンショット 2017-09-08 18.32.23.png")

あーはいはい`gem udpate`も必要だよねー

```console
$ gem list
︙
scss-lint (0.38.0)
︙

$ gem update scss-lint
Fetching: scss-lint-0.38.0.gem (100%)
WARNING: `scss-lint` has been renamed to `scss_lint` to follow proper RubyGems naming conventions. Update your Gemfile or relevant install scripts to install `scss_lint`.
Successfully installed scss-lint-0.38.0
Parsing documentation for scss-lint-0.38.0
Installing ri documentation for scss-lint-0.38.0
Done installing documentation for scss-lint after 1 seconds
1 gem installed
```

だがエラーが消えない！！！
なんでや！！！！

Atomの`setting`=>`packages=``linter-scss-lint`で説明を見ると`v0.43.2`以上でないと動かないらしい
![スクリーンショット 2017-09-08 18.40.39.png](https://qiita-image-store.s3.amazonaws.com/0/109065/388d3901-33ad-eaf1-6370-fffb38649635.png "スクリーンショット 2017-09-08 18.40.39.png")
>


しかし`gem uninstall`=>`gem install`やっても入れ直してもversionは`0.38.0`

```console
$ gem uninstall scss-lint
Remove executables:
	scss-lint

in addition to the gem? [Yn]  y
Removing scss-lint
Successfully uninstalled scss-lint-0.38.0

$ gem install scss-lint
Fetching: scss-lint-0.38.0.gem (100%)
WARNING: `scss-lint` has been renamed to `scss_lint` to follow proper RubyGems naming conventions. Update your Gemfile or relevant install scripts to install `scss_lint`.
Successfully installed scss-lint-0.38.0
Parsing documentation for scss-lint-0.38.0
Installing ri documentation for scss-lint-0.38.0
Done installing documentation for scss-lint after 1 seconds
1 gem installed

```


Atom側の`linter-scss-lint`をuninstall=installしても変わらず。
なんでだああああああ、ということでエラーメッセージでググったらドンピシャのissueが
[Old version off scss-lint error message · Issue #160 · AtomLinter/linter-scss-lint · GitHub](https://github.com/AtomLinter/linter-scss-lint/issues/160)

![スクリーンショット 2017-09-08 18.49.51.png](https://qiita-image-store.s3.amazonaws.com/0/109065/5326bf01-91a2-76e7-a687-d22c0c69b39e.png "スクリーンショット 2017-09-08 18.49.51.png")

「`scss-lint`を消して`scss_lint`を入れたら動いたよ」とのこと。



```console
$ gem uninstall scss-lint

$ gem install scss_lint
Fetching: scss_lint-0.54.0.gem (100%)
Successfully installed scss_lint-0.54.0
Parsing documentation for scss_lint-0.54.0
Installing ri documentation for scss_lint-0.54.0
Done installing documentation for scss_lint after 1 seconds
1 gem installed

```

はいったああああああああああああ！！！
はい、`linter-scss-lint`が吐いてたAtomのエラーも消えました。
ということで、gemの名前が変わってたんですねぇ。（issueの上がった日を見るに2016年5月12日近辺で変更があったんですかね。）

確かに`linter-scss-lint`のInstallationにも`gem install scss_lint`って書いてある。。。
にしても紛らわしすぎだろ！！！！


#### 参考

[GitHub - brigade/scss-lint: Configurable tool for writing clean and consistent SCSS](https://github.com/brigade/scss-lint)
Google Cloud ML Engineのメモリを調べてみた

# Google Cloud ML Engineのメモリを調べてみた

https://cloud.google.com/ml-engine/docs/concepts/training-overview

> Even though the exact specifications of the machine types are subject to change at any time, you can compare them in terms of relative capability. The following table uses rough "t-shirt" sizing to describe the machine types.


<img width="795" alt="スクリーンショット 2017-09-08 18.47.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/5704/76d6fba4-5d0b-7e42-f30b-36feaca73d40.png">


ココらへんがいまいち曖昧なので調べてみた

# 調べ方

```python
import os

mem_bytes = os.sysconf('SC_PAGE_SIZE') * os.sysconf('SC_PHYS_PAGES')
mem_gib = mem_bytes/(1024.**3)
print(str(mem_gib)+"GB")

# another
meminfo = dict((i.split()[0].rstrip(':'),int(i.split()[1])) for i in open('/proc/meminfo').readlines())
mem_gib = meminfo['MemTotal']/(1024.**2)
print(str(mem_gib)+"GB")
```

# Results

Scale tier

## BASIC
- single
  - 14.6924285889 GB

## STANDARD_1
- single
  - 7.01322555542 GB
- master
  - 7.01322555542 GB
- ps
  - 14.6924285889 GB
- worker
  - 7.01322555542 GB

## PREMIUM_1
- single
  - 14.0992164612 GB
- master
  - 14.0992164612 GB
- ps
  - 51.1138572693 GB
- worker
  - 14.0992164612 GB

## BASIC_GPU
- single
 - 29.4575538635 GB

# CUSTOM

Machine type

## standard
- 14.6924285889 GB

## large_model
- 51.1138572693 GB

## complex_model_s
- 7.01327514648 GB

## complex_model_m
- 14.0991668701 GB

## complex_model_l
- 28.272064209 GB

## standard_gpu
- 29.4575538635 GB

## complex_model_m_gpu
- 118.048339844 GB

## complex_model_l_gpu
- 118.048339844 GB

# コードはこちら

https://github.com/mainyaa/ml-engine-memory-cat
Ranking learningにおけるデータ変換をRで

一般的に使われている検索結果に対する適合フィードバックにおいて、よく用いられるのはrankingの修正を行うものです。様々な推薦エンジンで活用されているもので、応用も多数ありそうです。
要はユーザーが検索結果に対する評価を直接行い、検索のランキングの礎となる評価関数を修正していくというものです。

[Learning to rank for IR](https://www.slideshare.net/lawmn/learning-to-rankforir)

# Learning from rank 
これ自体は古いトピックで最近はあまり見ないですが、deep learningを適用する例が多いようです。
そもそもアプローチはしておいた方がよいので、単純な方法を試しました。
ランキング学習を通常の識別学習や回帰にマッピングする方法はいくつかあります。

- pointwise
 ランキングの要素１つ１つを独立に識別する。ランキングとして正しいかどうかの指標（学習データ）が必要。

- pairwise
　ランキングの要素の組（１位と２位とか）について、どちらが優位かを識別する。ランキングとしてどちらが上かを示す指標が必要。

- listwise
　ランキングの要素すべてを使い、回帰するもの。ランキングの順位（または評価値そのもの）が必要です。ランキングの完全な修正が必要。

こと、実際のシステムとかになると、ランキングすべての修正情報がユーザーからフィードバックされることは中々なく、複数の候補から一つだけ選ぶというものが多いのではないでしょうか？そうなると、完全なデータがなくても機能するpair wiseのアプローチが良いように思えます。

# list(ranking) -> pair wise変換 

Featuresを k(length of ranking) * nf(feature)の行列とすると、以下のようにすべての組み合わせでペアを生成します。最終列にペアの最初のIDを入れておきます（どのfeatureを元に比較しているかを示すため）

```R
list2pair <- function(Features) {
    k <- nrow(Features)
    nf <- ncol(Features)
    dataset <- matrix(ncol = nf)
    pairs = permutations(v = 1:k, r = 2, n = k, repeats.allowed = F)
    dataset <- cbind(Features[pairs[, 1],] - Features[pairs[, 2],], pairs[, 1])
    return(dataset)
}
```

学習用データを作る際は、１つだけユーザーフィードバックがあった時を想定すると、以下のような感じで、選択されたfeatureとそれ以外のペアを作るだけです。フィーチャーをひっくり返して正負例を作ることができるので、結果的には(k-1)*2の例ができることになります。

```R
selection2pair <- function(Features, selection) {
    k <- nrow(Features)
    nf <- ncol(Features)
    dataset <- matrix(ncol = nf + 1)
    rest <- (1:k)[-selection]
    pairs <- cbind(rep(selection, k - 1), rest)
    rclass <- ifelse(pairs[, 1] < pairs[, 2], 1, -1)
    dfeature <- cbind(rankedFeatures[pairs[, 1],] - rankedFeatures[pairs[, 2],], rclass)
    dataset <- rbind(dataset, dfeature)
    dataset <- rbind(dataset, -dfeature)
    dataset <- dataset[-1,]
    return(dataset)
}
```

# pair wise -> list(ranking) 変換 

それで、ランキングに使う目的関数を求めるには以下のような感じになります。
lapply使えば一発な気がしますが、直感的に。。

```R
pair2obj <- function(model.svm, Features) {
    nf <- ncol(Features) - 1
    pred <- predict(model.svm, Features[,1:nf])
    obj <- data.frame(pred = as.numeric(levels(pred)[pred]), idx = dfeatures[, nf + 1]) %>%
            group_by(idx) %>%
            summarise(obj = sum(pred)) %>%
            ungroup()
    return(obj)    
}
```

SVMを使う場合はRankingSVMというらしく、PythonやRのライブラリとかもあったりするんですけどね。
なんかランキング以外でもいろいろ使えそう。
[Fusion360]休憩時間にfusion360と遊ぶ その4。


こんにちは
どんどん天気が涼しくなってます。

私はFusion360はどんどん楽しくなってです。
一週間の休憩時間でやってますけど
時間を増やしたいです

今週は箱を作ってみました。

#user param

こんなことあるとは！
びっくりしました。

![Screen Shot 2017-09-08 at 6.25.16 PM.png](https://qiita-image-store.s3.amazonaws.com/0/137182/48a31149-7fe9-b299-435a-84fd7935b121.png)

完成した箱のサイズを簡単に変更できました。:metal:

![Screen Shot 2017-09-08 at 6.26.05 PM.png](https://qiita-image-store.s3.amazonaws.com/0/137182/4670f719-b3b5-9e9b-055c-55067e3765b1.png)

#Sheet Metal

![Screen Shot 2017-09-08 at 6.20.52 PM.png](https://qiita-image-store.s3.amazonaws.com/0/137182/466ea98e-aef1-59f2-6098-3b6051a76863.png)

![Screen Shot 2017-09-08 at 6.09.15 PM.png](https://qiita-image-store.s3.amazonaws.com/0/137182/0ab75874-c029-f173-bd2a-315b6b445248.png)

なんか専門的。

![Screen Shot 2017-09-08 at 6.20.24 PM.png](https://qiita-image-store.s3.amazonaws.com/0/137182/b26f8a69-207b-5b17-9099-668e0648a7e8.png)

![Screen Shot 2017-09-08 at 6.09.25 PM.png](https://qiita-image-store.s3.amazonaws.com/0/137182/37f31d5f-9352-d446-77b4-a0b52be8f423.png)


#結果

http://a360.co/2wMz7qP

#サンコウ

1. [Fusion 360: Cardboard Box Design with Sheet Metal Tools](https://www.youtube.com/watch?v=1aDN44__L9E)
faultline-jsでエラーをfaultlineにPOSTしないようにフィルタリングする方法

faultline-jsのベースとなっているairbrake-jsには、あまりトラッキングしなくてよいエラーをPOSTしないようにフィルタリングする機構があります。

faultline-jsでも、airbrake-jsと同様に以下のようにフィルタリングを追加することができます。

```js
var faultline = new faultlineJs.Client({ /** ... ** / });

faultline.addFilter(function(notice) {
    if (notice.context.userAgent.match(/bot/i)) {
        // botによるエラーをフィルタリング
        return null;
    }
    if (!notice.context.url.match(/^https:\/\/production.example.com/)) {
        // 本番以外のエラーをフィルタリング
        return null;
    }
    return notice;
});
```

ご活用下さい