OmniAICreator/Qiita-1.07M huggingface dataset:
[Ruby]Hashにmapで値を変換したHashを作成する

# 本記事のサマリ
単純なkey->value(数値や文字列)などを管理しているHashに対して、mapを使って値を操作した結果を、配列ではなくHashにしたい場合、Ruby2.1以降ならto_hを使うとうまく表現できますよというお話。

# 対象読者
Hash#mapの結果をHashにしたいRubyistの皆様

# 動作確認バージョン
```
ruby --version
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin15]
```

# 経緯
Hashの全要素に対して、フォーマット変換かけたようなHashを作りたくなったので。

# やってみた
例えば、key1〜key3で値が数値からなるHashがあり、それを全て5桁0埋めにしたいようなケースがあったとします。
その場合は、以下のように、Hashに対して、mapをかけた時に、mapに渡したブロックの戻りを[key,new_value]のような形(ここで、new_valueは、フォーマット変換などをして得られた新たな値にします。)で返し、それをto_hでhashにすると綺麗に書けます。

↓こんな感じ

```rb
hash = { key1: 1000, key2: 300, key3: 10000}
hash.map {|key,val| [key,val.to_s.rjust(5,'0')]}.to_h
```

{
    :key1 => "01000",
    :key2 => "00300",
    :key3 => "10000"
}

地味に使うケースがありそうなので、備忘録として残します。
LINE BOT をrails4とHerokuで

っっもう本当に参考にさせていただきました。もうこれは記念みたいな投稿で。先輩方ありがとうございます。

とりあえずLINE BOT APIでオウムを作ってみた
http://qiita.com/masuidrive/items/1042d93740a7a72242a3

LINE BOT をとりあえずタダで Heroku で動かす
http://qiita.com/yuya_takeyama/items/0660a59d13e2cd0b2516#comment-e6737f3166be32597681

Rails HerokuでLINE BOTを試してみた
http://qiita.com/Arahabica/items/98e3d0d5b65269386dc4

LINE公式
https://developers.line.me/bot-api/getting-started-with-bot-api-trial

PHP + HerokuでLINE BOTを試してみる＆ハマったこと
http://qiita.com/chibi929/items/a368fdc3ef3485302302
Callback URLの反映は、わたしの場合は１、２分くらいだったかな。わりとすぐでした。

動かないときは落ち着いて

```
heroku logs
```
で確認すれば大丈夫。

初心者なのでちょっとはまった。

Rails4のCSRF対策で「Can't verify CSRF token authenticity」エラー
http://qiita.com/chobi9999/items/2b59fdaf3dd8f2ed9268

NameError uninitialized constant class　とかエラーが出たらapplication.rbを編集
https://hackhands.com/rails-nameerror-uninitialized-constant-class-solution/

Undefined Method `strip' とかいうエラーが出たら、なんかstring
じゃなきゃいけない値が違う型になってないか確認
http://stackoverflow.com/questions/2255801/why-am-i-getting-undefined-method-errors-for-strip-and-downcase-when-i-run-r
（わたしはLINE_CHANNEL_IEを数字にしてたw）

ぶじ、うごきました。
C++ラムダ式でクロージャ（ぽいもの）

C++14で追加された汎用ラムダキャプチャ構文（ついでにジェネリックラムダ式も）を利用。

```cpp
auto make_counter = [](auto init_val) {
  return [count = init_val]() mutable {
    return count++;
  };
};

auto c1 = make_counter(1);       // int型/初期値1
auto c2 = make_counter(3.14);    // double型/初期値3.14
std::cout << c1() << std::endl;  // 1
std::cout << c2() << std::endl;  // 3.14
std::cout << c1() << std::endl;  // 2
std::cout << c2() << std::endl;  // 4.14
```

Inspired by

- [C++でクロージャを作る](http://fimbul.hateblo.jp/entry/2013/08/16/104311)
- [C++で無理矢理クロージャを使ってみる](http://torini.hateblo.jp/entry/2016/04/12/C%2B%2B%E3%81%A7%E7%84%A1%E7%90%86%E7%9F%A2%E7%90%86%E3%82%AF%E3%83%AD%E3%83%BC%E3%82%B8%E3%83%A3%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%8B)
Google検索で基数変換をする

# はじめに

基数変換を行う機会があるが、
変換用のサイトを開いたり、変換ツールを作るなど
といったことすら時間がおしいという人も多いと思う。

そんな人にはGoogle検索がおすすめ。

指定されたフォーマットで検索すると基数変換ができる。

# 検索パターン

| 変換パターン| 検索方法 |
|---|---|
| 2進数変換  | 数値 in binary|
| 8進数変換| 数値 in octal |
| 16進数変換 | 数値 in hex (※正式にはin hexadecimal)|
| 10進数変換 | 数値 in decimal|


上記の検索に用いる数値の基数を指定したい場合、
先頭に下記の文字列をつける。

| 数値パターン| 指定方法 |
|---|---|
| 2進数 | 0b |
| 8進数 | 0o |
| 16進数 | 0x |
| 10進数 | なし|

# 例

* 16進数64から10進数100へ変換。

```
0x64 in decimal 
  -> 100
```

* 10進数10から16進数Aへ変換。

```
10 in hex
  -> 0x0A
```


# おわりに
残念ながら、36進数はできないようだ。

http://blogs.yahoo.co.jp/natto_heaven/8111226.html
http://minus9d.hatenablog.com/entry/2014/03/24/214448
Docker hub の java:alpineに入ってたjavaのバージョン


>
\# docker run -it --name java1 java:alpine /bin/sh
\# docker start -a -i java1
\# java -version
openjdk version "1.8.0_77-internal"
OpenJDK Runtime Environment (build 1.8.0_77-internal-alpine-r0-b03)
OpenJDK 64-Bit Server VM (build 25.77-b03, mixed mode)

十分minecraft動きそうで安心してます。

<pre>
# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
dock1               latest              0eeb800006c1        6 hours ago         154.3 MB
ubuntu              latest              b549a0000a66        6 days ago          187.9 MB
java                alpine              70003cec9afb        8 days ago          145.4 MB
java                latest              081c****85db        8 days ago          642.7 MB
alpine              latest              d75413a663c1        11 days ago         4.794 MB
</pre>

でもサイズは150MB以下ですからね。素晴らしい。

```
java                alpine              70003cec9afb        8 days ago          145.4 MB
```
Wordpressを構築するdocker-compose.yml

# はじめに
version 2のdocker-compose.ymlがググっても見当たらなかったので作りました。
docker >= 1.10, docker-compose >= 1.6 でお試しください。

# まっさらなWordpressを構築する

```docker-compose.yml
version: "2"
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "80:80"
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: "db:3306"
    networks:
      - flat-network
    env_file: .env
  db:
    image: mysql:5.7
    volumes:
      - "db-data:/var/lib/mysql"
    networks:
      - flat-network
    env_file: .env
volumes:
  db-data:
networks:
  flat-network:
```
パスワードなどは別のファイルから読み込むようにしました。

```:.env
WORDPRESS_DB_NAME=wordpress
WORDPRESS_DB_USER=wp_user
WORDPRESS_DB_PASSWORD=hogehoge
MYSQL_RANDOM_ROOT_PASSWORD=yes
MYSQL_DATABASE=wordpress
MYSQL_USER=wp_user
MYSQL_PASSWORD=hogehoge
```
この2ファイルを置いた後に下記コマンド実行で、Wordpressのインストール画面までいけます。

```
docker-compose up
```

![wordpress_init.png](https://qiita-image-store.s3.amazonaws.com/0/120222/0e07351b-7167-e793-3272-a5430f8b0a2a.png)

簡単ですね！

# インストール済のWordpressを構築する
既にWordpressのダンプデータがあり、それを`install_wordpress.sql`というファイル名で保存しているとします。
その場合は下記のようになります。`db`の`volumes`2行目で、コンテナ作成時に実行されるSQLファイルを指定しています。

```docker-compose.yml
version: "2"
services:
  wordpress:
    image: wordpress:latest
    ports:
      - "80:80"
    depends_on:
      - db
    environment:
      WORDPRESS_DB_HOST: "db:3306"
    networks:
      - flat-network
    env_file: .env
  db:
    image: mysql:5.7
    volumes:
      - "db-data:/var/lib/mysql"
      - "./install_wordpress.sql:/docker-entrypoint-initdb.d/install_wordpress.sql"
    networks:
      - flat-network
    env_file: .env
volumes:
  db-data:
networks:
  flat-network:
```

# tips
## MySQLコンテナのmysqldump
ちなみに、動作中のMySQLコンテナからdumpを取る場合はこんな感じでいけました。

```
docker exec -it MySQLコンテナID sh -c 'mysqldump wordpress -u wp_user -pXXXXXXXX 2> /dev/null' > install_wordpress.sql
```

## コンテナの削除について

```
docker-compose down
```
としても`volume`は削除されずデータが永続してしまうので、`volume`も含めて削除する時は

```
docker-compose down -v
```
とするとよいです。
Facebook MessengerはLet's Encryptでもおｋ

LINE BOTではLet's Encryptが使えないという話だったのでFacebook Messengerではどうだろう、と試してみた。
結論としては、タイトルの通りLet's Encryptでも問題なく動きます。
以下、簡単に確認手順等

# 確認環境
* Amazon Linux AMI 2016.03.0
* nginx/1.8.1
* PHP 5.5.33
* （過去に取得したままほったらかしになっていたドメイン）

# 1.事前準備
1. EC2インスタンスの立ち上げ（SecurityGroupで80、443番ポートを開けておく）
2. インスタンスへのElasticIPの割り振りとDNS設定
3. nginx,PHP,PHP-FPM等をyumでインストール
4. Let's EncryptでSSL証明書を発行（ここだけ少し詳しく）

```
# install
sudo git clone https://github.com/letsencrypt/letsencrypt
cd letsencrypt
# confirm
./letsencrypt-auto --help

# 事前準備：WebサーバのSTOP（サーバの存在確認に80番ポートを使うので一時的に止める必要あり）
# 証明書の発行
sudo ./letsencrypt-auto certonly -a standalone -d ドメイン名 --debug

# 発行に成功した場合下記パスに秘密鍵とサーバ証明書と中間証明書が結合されたファイルが出力されているのでnginxのSSL設定を変更
# /etc/letsencrypt/live/ドメイン名/privkey.pem
# /etc/letsencrypt/live/ドメイン名/fullchain.pem
```

以降は https://developers.facebook.com/docs/messenger-platform/quickstart （公式）の手順に沿って作業

# 2.Facebookページを作る
> Create a new Facebook App and Page or use existing ones

ってことなので新しくFacebookPageを作成

# 3.Webhookの設定
コールバックを受け取るURLを下記のように設定し

```
https://$your_domain/webhook
```
サーバの当該パスに下記のようなスクリプトを置いておきます。

```
<?php
if($_GET['hub_verify_token'] == 'hogefugapiyo'){
    echo $_GET["hub_challenge"];
}else{
    echo 'Error, wrong validation token';
}
```

アプリの設定画面のWebhookの設定でCallback URLとVerify Tokenを入力し、Verify and Saveを押下。
認証に成功すると次のように'Complete'と表示されます。

<img width="1006" alt="スクリーンショット 2016-04-14 0.05.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/26102/f461ba6e-1107-affe-8140-bd44cf9674ca.png">

# 4.Access Tokenの取得

認証成功後に手順２で作成したページを選択するとAccess Tokenが取得できます。

<img width="1002" alt="スクリーンショット 2016-04-14 0.08.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/26102/02aad9bd-45c6-0b83-c6bd-ee92b8351a77.png">

# 5.BOTを起動

```
curl -ik -X POST "https://graph.facebook.com/v2.6/me/subscribed_apps?access_token=<token>"
```
の```<token>```を手順4で取得したAccess Tokenに書き換えて実行すればBOTが起動して、FacebookPageの更新を受け取れるようになります。

# 6.メッセージの送受信

[こちらの記事](http://qiita.com/betchi/items/539f5e32cd9a9c8d2db4) の[テキスト送信](http://qiita.com/betchi/items/539f5e32cd9a9c8d2db4#%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E9%80%81%E4%BF%A1) をコピペさせてもらってコールバックを受け取るURLに設置

# 7.動作確認

<img width="375" alt="IMG_0766.PNG" src="https://qiita-image-store.s3.amazonaws.com/0/26102/043a09e2-c981-695e-b78e-0437a7406292.png">


おｋ！！！！！

# 8.おまけ

自己証明書で実験
→ 手順3のVerify and Saveのタイミングで"SSL certificate problem: self signed certificate"
→ さすがに自己証明書はNG

# 9.おまけ（2）

BOTが審査に通過する前の状態だと開発者以外に返答することができないので、BOTを作って手っ取り早く知り合いにドヤリングしたい人は「役割」から「テスト担当者」を追加すると良いでしょう。
LD_PRELOADで差し替えた関数から元の関数を呼び出す

# TL;DR
LD_PRELOADで特定関数の差し替えをおこない、かつ場合によっては元の関数呼び出しをできるようにする。
`dlsym` に `RTLD_NEXT` を指定して元の関数の関数ポインタを取得し、それを実行すれば良い。

# 実行方法まとめ
まずは差し替え対象の関数を定義する。今回は `puts` を対象とする。

```c:print.c
#include <stdio.h>

int main(int argc, char const* argv[])
{
    puts("hoge");

    return 0;
}
```
```shell-session:ビルドと実行結果
$ gcc print.c 
$ ./a.out 
hoge
```

LD_PRELOADで差し替えるための関数を定義する。内部で元の関数を呼び出し、その前後でログを出力する。
そのまま `puts` を呼ぶと無限再帰呼び出しになってスタックオーバーフローするので、`dlsym(RTLD_NEXT, "puts")` を使用して、元の関数のの関数ポインタを取得して、そちらを呼び出すようにしている。
(`RTLD_NEXT` は、ライブラリ検索順序の中で現在のライブラリ以降で最初に 関数が現れるところを探す。)

```c:override.c 
#include <stdio.h>
#include <assert.h>
#define __USE_GNU
#include <dlfcn.h>

int puts(const char *__s) {
    fprintf(stdout, "before\n");

    void *handle = dlsym(RTLD_NEXT, "puts");
    assert(handle);

    int (*func)(const char *) = (int (*)(const char*))handle;
    int ret = func(__s);

    fprintf(stdout, "after\n");
}
```

```shell-session:ビルドと実行結果
$ gcc -shared -fPIC override.c -ldl -o liboverride.so
$ LD_PRELOAD=./liboverride.so ./a.out 
before
hoge
after
```

これで対象のバイナリを再ビルドせずにputsの呼び出し前後にログを入れることができた。

# 関連
[LD_PRELOADでprintfを後から差し替える - Qiita](http://qiita.com/koara-local/items/d5205f94decade3ffbf1)

# 参考書籍
『BINARY HACKS』 #HACK 61 : LD_PRELOADで既存の関数をラップする

# 参考
[Man page of DLOPEN](https://linuxjm.osdn.jp/html/LDP_man-pages/man3/dlsym.3.html)
[LD_PRELOADを使ったテスト(C言語編)](http://matsu911.github.io/Testing/2012/02/27/testing-with-ld_preload/)
[[Debug] LD_PRELOAD, dlsym, GCC拡張機能によって共有ライブラリの関数の呼出し前後で任意の処理を実行する - th0x4c 備忘録](http://th0x4c.github.io/blog/2013/06/25/debug-override-a-shared-library-function-by-ld-preload-dlsym-and-gcc-attributes/)
Google Formで問い合わせが来たときに、その内容をGmailに通知する

私が運営しているサイトの問い合わせフォームをGoogle Formにしたのですが、問い合わせが来たときにGmailに通知がいくようにしました。

Google Formにはデフォルトでもメール通知機能がありますが、「新しい回答があります」という内容のメールが来るだけで大変わかりにくいものでした。


# スクリプトエディタを開く
こんな感じのコードを書きます。

```js
function sendForm(e){
  var subject = "問い合わせがありました";  //件名
  var body = "問い合わせ内容\n------------------------------------------------------------\n\n";  //本文
  var to    = "youremail@example.com";
 
  var res = e.response;
  var itemResponses = res.getItemResponses();
  for (var j = 0; j < itemResponses.length; j++) {
     var itemResponse = itemResponses[j];
     
     body += itemResponse.getItem().getTitle() + "\n";
     body += itemResponse.getResponse() + "\n\n";
  }
  MailApp.sendEmail(to, subject, body);   //メールを送信
}
```

# トリガーの設定
<img width="648" alt="スクリーンショット 2016-04-13 23.54.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/106258/8e006728-1f6f-700f-0825-8877154b9c1f.png">
このようにトリガーを設定すればOKです。
フォームに新しい回答がきたときに`sendForm()`が呼び出されるようになります。

# 参考
- https://developers.google.com/apps-script/reference/forms/form-response
CoreOSのインストールのメモ

# VirturalBoxのインストール
- https://www.virtualbox.org から最新版をダウンロードしてインストール

# CoreOSのインストール
- https://coreos.com/os/docs/latest/booting-with-iso.html からisoイメージをダウンロード。ひよってStable Channelを選んだ。
- VMを新規作成。設定は、メモリ1024MB、HDD16GBくらいで適当に。
- 作成後、ネットワークは「ブジッジアダプター」を選択。ブリッジアダプターにすると、PCと独立したIPアドレスを設定できるようになる。
- 最初に起動すると、isoイメージを選択するか聞いてくるので、ダウンロードしたisoイメージを指定。
- もし、聞かれない場合はisoイメージをマウントして再起動。
- isoイメージから起動するので、インストールのためにユーザー「core」としてログインしてパスワードを設定。

```
$ sudo passwd core
```
- PC側からsshでログイン。パスワードは上で設定したもの。

```
$ ssh core@192.168.***.***
```
- スーパーユーザーになる

```
$ sudo -s
```
- cloud-config.yml を作成

```
# vi cloud-config.yml
```
- ファイル内容は下記のような感じ。1行目の「#cloud-config」がなかったり、間違っているとエラーになるので注意。

```
#cloud-config
hostname: "coreos-001"
users:
 - name: "sokotsu"
   passwd: "..."
   groups:
    - "sudo"
    - "docker"
   ssh-authorized-keys:
    - "ssh-rsa AAAA..."
```
- passwd は```$ openssl passwd -1```で生成（実は不要かもしれないけど確認してない、、、）。
- ssh-authorized-keys は ```$ ssh-keygen -t rsa```で生成した```~/.ssh/id_rsa.pub``` を貼り付け。
- cloud-config.yml のチェック。

```
# coreos-cloudinit -validate=true -from-file=./cloud-config.yml
```
- チェックでエラーがなければインストール。```/dev/sda```は設定をいじっていたらそれに合わせて変更。

```
# coreos-install -d /dev/sda -C stable -c cloud-config.yml
```
- インストール完了したら再起動。その時、isoイメージのアンマウントを忘れずに。
- 再起動したらSSH host KeyやIPアドレスが表示されるので、PC側からsshでログイン。
- CoreOSのアップデート

```
$ sudo update_engine_client -update
```
MacでTCP/UDPポートを開いているアプリを確認する

OSに標準で付属しているlsofコマンドを使用する。
-iオプションを使用すると、対象のプロトコルやポート番号を指定できる。
たとえば、TCPの443ポートを使用しているアプリを調べるには、以下のように入力する。
```lsof -iTCP:443```

以下のような感じで結果が表示され、この例ではDropboxがd.v.dropbox.com:443にアクセスしていることが分かる。
> COMMAND   PID  USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
> Dropbox   694 hoge   34u  IPv4 0x5db8a84b2cd36acf      0t0  TCP 192.168.xxx.xxx:51743->d.v.dropbox.com:https (ESTABLISHED)

このままでも目的は達成できるが、IPアドレスから名前を引きにいったり、ポート番号がサービス名に置換されるため、結果が表示されるまでに時間がかかる。
```lsof -n -P -iTCP:443```
とすると置換処理が抑制されて結果がスグに表示される。
[短文メモ][初級記事]std::cinから整数受け取るのは、エラーチェックしないと怖くて使えないね

CodeIQさんの問題に、いつもPython使ってるのでたまにはC++を、と思ったらハマったのだけど。
原因がようやく分かった。std::cinでの読み込みが失敗していた。失敗しても例外とか投げずに静かに失敗するので、分からないんですね。

例：整数のみからなるテキストがstdinに渡される、としよう。行数は、前もって分からない。
これをvectorに読み込みたい。

```cpp:よくない例
#include <iostream>
#include <vector>

int main(){
    int t;
    std::vector<int> v;

    while(!std::cin.eof()){
        std::cin >> t;
        v.push_back(t);
    }
    for(auto it=v.begin();it!=v.end();++it){
        std::cout << *it << std::endl;
    }
}
```

普通に、このように書いて、以下のように入力したら。

```txt:stdinにこれを入力
1
2
3
```
こうなった。

```txt:実行結果
1
2
3
3
```

原因は、空行を整数として解釈しようとして、できなかったので、tを何も変更しなかったことと思われる。

```cpp:改善
int main(){
    int t;
    std::vector<int> v;

    while(!std::cin.eof()){
        std::cin >> t;
        if(std::cin.fail()) break;  // エラーチェックを付け加えた
        v.push_back(t);
    }
    for(auto it=v.begin();it!=v.end();++it){
        std::cout << *it << std::endl;
    }
}
```

こうしたら、3がダブらずに済む。
せっかくwhileの中にループ抜ける条件書いてるのに・・・・

ちなみに、整数ではなく間違えて文字を入力してしまったときは、tには0が入力され、また、
`std::cin.clear()`でエラーをクリアし、`std::cin.ignore()`で読み捨てないといけないみたい。

お手軽にできるのかと思いきや、結構めんどくさいのですね。
ansible-playbook内でもYAMLのマージ記法が使えます! Cisco ios_commandモジュールなどでどうぞ。

## はじめに
AnsibleのplaybookはYAML形式で記述するので重複する行などを
以下の通りYAMLのマージ記法(`<< : &`,`<< : *`)で表現できます。
重複を排除できるのでスマートに書けます。

以下はCisco機器への`ios_command`モジュールでの使用例です。

なお、AnsibleでのCisco関連のモジュールの使い方については
同僚の[記事](http://qiita.com/onifinger/items/4fdc70706dbbff595310)も参照してください。

## 環境
+ Ansible version:2.1.0 (gitでインストール)
+ CentOS6.7 / OSX Yosemite

```
[root@ansible cisco]# ansible --version
ansible 2.1.0 (devel 81788e627d) last updated 2016/03/14 06:41:49 (GMT +000)
  lib/ansible/modules/core: (detached HEAD c86a0ef84a) last updated 2016/03/14 02:09:35 (GMT +000)
  lib/ansible/modules/extras: (detached HEAD 33a557cc59) last updated 2016/03/14 02:09:54 (GMT +000)
  config file = /opt/cisco/ansible.cfg
  configured module search path = Default w/o overrides
```

+ Cisco
   + IOS version 12.2
   + Catalyst3560-E


+ インベントリファイル
hosts

``` hosts
[cisco]
192.168.1.1
192.168.1.2

[cisco:vars]
cisco_enable_secret=cisco
ansible_user=ansible
ansible_password=ansible
```

``` ios_command.yml 
---
- hosts: cisco
  gather_facts: no
  tasks:
   - name: sh run by cisco ios_command module
     local_action:
       module:   ios_command
       commands: sh run
       << : &IOS_INFO
         host:     "{{ inventory_hostname }}"
         username: "{{ ansible_user }}"
         password: "{{ ansible_password }}"
         authorize: true
         auth_pass: "{{ cisco_enable_secret }}"
     register: result
   - debug: var=result.stdout_lines
   - name: sh int by cisco ios_command module
     local_action:
       module:   ios_command
       commands: sh int
       << : *IOS_INFO
     register: result
   - debug: var=result.stdout_lines
 ```
composerとは

composerとはPHPのパッケージ管理システムである。

## なんでそんなものを使う必要があるのか。

パッケージ管理システムがない環境では、メンバーがそれぞれ必要なライブラリの公式サイトにアクセスし、zipファイルをダウンロードし、ローカルに展開する。
DB接続用に○○、ログ出力用に△△等々、さまざまなライブラリが必要になる。

パッケージ管理システムはそれらを個人の裁量に依存せずに導入できる仕組みを提供する。

以下のようなデメリットというかイニシャルコストが必要になるが、いまどきのPHPプロジェクトでは必須である。
- パッケージ管理システム自体のインストールが必要
- パッケージ管理システムの使い方の理解が必要（コマンドオプション、設定ファイルの記述方法）

composerを使えば、コマンド一発で必要なパッケージをすべてインストールできる。

- composerはPackagistからパッケージを取得する。
 - Packagistはインターネット上に公開されているメインリポジトリである。
- パッケージAをインストールするときに、Aに依存するB,C,Dも自動的にインストールしてくれる


## 実際に使ってみる

composerをインストール

下記からComposer-Setup.exeをDLして普通にインストールする。
（Windowsの場合）
https://getcomposer.org/download/

するとコマンドライン（cmd.exe）でcomposerが使えるようになる

任意のフォルダに下記のとおりcomposer.jsonをおく

```composer.json
{
	"require": {
		"ircmaxell/random-lib": "1.0.0",
	}
}
```

- composer.jsonのrequire内にあるパッケージをインストールする。
- パッケージ名は"ベンダー名/プロジェクト名"となっている
- バージョンを固定で指定してもよいし、範囲を指定してもよい。
 - "1.0.0"とすれば1.0.0が固定でインストールされる。
 - "1.0.*"のようにワイルドカードを指定すれば、その範囲で最新がインストールされる。

ちなみにこのライブラリはこれです。

https://packagist.org/packages/ircmaxell/random-lib

ランダムな数値や文字列を生成してくれます。

今回はサンプルなので、これひとつですが、使いたいライブラリがあればドンドンcomposer.jsonに追加していきます。

composer.jsonが配置されているディレクトリでcomposer installします。

```
c:\tmp>composer install
You are running composer with xdebug enabled. This has a major impact on runtime performance. See https://getcomposer.or
g/xdebug
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing ircmaxell/security-lib (1.0.0)
    Downloading: 100%

  - Installing ircmaxell/random-lib (v1.0.0)
    Downloading: 100%

Writing lock file
Generating autoload files
```

下記のとおりパッケージがダウンロードされ、ファイルが配置されます。

```
C:.
└─vendor
    ├─composer
    └─ircmaxell
        ├─random-lib
        │  ├─lib
        │  │  └─RandomLib
        │  │      ├─Mixer
        │  │      └─Source
        │  └─test
        │      ├─Mocks
        │      │  └─Random
        │      ├─Unit
        │      │  └─RandomLib
        │      │      ├─Mixer
        │      │      └─Source
        │      └─Vectors
        │          └─Random
        └─security-lib
            ├─lib
            │  └─SecurityLib
            │      └─BigMath
            └─test
                ├─Mocks
                └─Unit
                    └─Core
                        └─BigMath
```

はじめてcomposer installをすると、composer.lockが生成される。

composer.lockはチーム内で同じバージョンを共有するための仕組み。
 文字通りバージョンを固定（ロック）する。

composer.lockが存在する状態でcomposer installをすると、composer.lockに記されたバージョンのパッケージがインストールされる。

composer updateをすると、composer.lockに記されたバージョンを無視して、composer.jsonに記載の範囲で最新版に更新される。

パッケージはvendor配下に配置される。

オートローダが自動的に配置される。

composer updateをすれば追加分が最新が反映される。

次は、インストールしたパッケージを使用します。

```sample.php
<?php
require_once 'vendor/autoload.php';

$factory = new RandomLib\Factory;
$generator = $factory->getMediumStrengthGenerator();

$randomInt = $generator->generateInt(5, 15);
echo $randomInt;

echo "\n";

$randomString = $generator->generateString(32, 'abcdef');
echo $randomString;
?>
```

autoload.phpをrequireすればcomposerでインストールしたクラスを自動的にロードしてくれます。


実行結果はこんな感じです。

```
c:\tmp>php sample.php
13
cccdcbdfbdcbdfdaafdebdbbbffacbbc
```
PHP + HerokuでLINE BOTを試してみる＆ハマったこと

BOT API Trial Account が提供されていると聞いて試してみました。
既に1週間経っているため、皆様の記事を参考にさせていただきました。
特にHello World的な作業ではなく、何箇所かハマったのでそれを書きます。

# 開発環境
Heroku + FIXIE
PHP

FIXIEはHerokuのアドオンとなっているため、無料ですがクレジットカードの登録が必要です。

# LINE BOT → Heroku へのコールバック

## コールバックURL

BOTアカウントを作成したら、
LINE DevelopersのページにコールバックURLを設定します。

Herokuで動かす場合のコールバックURLですが、
色々調べていると多数の設定方法がありました。

> ・`https://xxxxx.herokuapp.com`
> ・`https://xxxxx.herokuapp.com:443/linebot/callback`
> ・`https://xxxxx.herokuapp.com:443/callback`

などなど、色々な設定が記載されていましたが、
私は **「 `https://xxxxx.herokuapp.com:443/callback` 」** に落ち着きました。

## 設定から反映までに時間がかかる

コールバックURLを設定後、
`heroku logs -t` でログを見ながらBOTに話かけてみましたが、
うんともすんとも反応せず。

HerokuアプリのURLをブラウザで直接叩いてみるとログが出力されるので動いてはいる。
が、BOTからは叩かれていない模様。

私も **すぐには反映しないかもしれない** の情報通り、時間が解決してくれました。

**(追記)**
**私の場合は、だいたい20分〜30分は放置していました。**
**※その間離れてしまっていたので、詳しい反映時間は不明です。**

# Heroku → LINE BOT API → LINE

Herokuを使ってる人はFIXIEで指定されたIPをホワイトリストに登録していると思います。
私も登録しました。

しかし、どうもPOSTに失敗している模様。
`curl_exec()` の戻り値をログにちゃんと出力して確認すれば問題なく解決できるはず。
`CURLOPT_RETURNTRANSFER` の設定もお忘れなく。

私の場合は以下の通り、
ホワイトリストに登録されていないIPアドレス で叩いていました。

```
{"statusCode":"427","statusMessage":"Your ip address [xxx.xxx.xxx.xxx] is not allowed to access this API."}
```

原因は、FIXIEのproxyURLの設定をせずにリクエストしてしまったため、
IPがproxy経由のアウトバウンドIPではなく、herokuアプリのIPになってしまっていたようです。
**`CURLOPT_HTTPPROXYTUNNEL` , `CURLOPT_PROXY` , `CURLOPT_PROXYPORT` の辺りを設定してあげる**ことで解決しました。

# 終わり

ということで、
ここまでで、LINE BOTが動くようになりました。

<img width="375" alt="Evernote Camera Roll 20160413 222437.png" src="https://qiita-image-store.s3.amazonaws.com/0/53393/99ab3769-0ba1-62fa-8f7a-6d1801b72f40.png">
※画像は適当に拾ってきたやつです。

## ソースコード

https://gist.github.com/chibi929/fcf065322cd6435ac5cdc109e1cc0cd7

# 参考サイト

最後に参考にさせて頂いた記事です。
皆様ありがとうございました。

- [LINE BOT をとりあえずタダで Heroku で動かす](http://qiita.com/yuya_takeyama/items/0660a59d13e2cd0b2516)
- [LINE BOT API Trialでできる全ての事を試してみた](http://qiita.com/betchi/items/8e5417dbf20a62f2239d)
- [PHP+HerokuでLINE BOT作ってみた](http://qiita.com/qckanemoto/items/7c148fcc595cec4aa59a)
- [LINE BOT APIを利用した地獄のミサワBOTの作り方](http://qiita.com/srea/items/58ba0f7d870a6ee3da2a)
- [LINE botでオウム返しを作る全手順【初心者向け】(Cloud9+heroku+git)](http://www.sakana.tech/entry/2016/04/12/112700)
- https://www.panzee.biz/archives/9115
SwiftのArrayをRealmのListに変換

Swift RealmのListを初期化するのに以下のようなコードを書いて悲しい気持ちになってたんだけど、

```
let users = List<User>()
users.append(User(name: 'alice'))
users.append(User(name: 'bob'))
```

reduceを使うと1行で書けて少しうれしい。（けど本当はもっと短く書きたい）

````
let users = [User(name: 'alice'), User(name: 'bob')].reduce(List<User>()) { $0.append($1); return $0 }
````

## 追記

nova_gtさんからもっといい方法を教えてもらいました。そうそう、コレが欲しかったんやー。

```
let users = List([User(name: "alice"), User(name: "bob")])
```
レスポンシブ対応でカオスになった時


javascriptでアクセスしてきた端末をpc/spに振り分けて、bodyにクラスを追加

```javascript:javascript
if ((navigator.userAgent.indexOf('iPhone') > 0 && navigator.userAgent.indexOf('iPad') == -1) || navigator.userAgent.indexOf('iPod') > 0 || navigator.userAgent.indexOf('Android') > 0) {
	$('body').addClass('env-sp');
} else {
	$('body').addClass('env-pc');
}
```

たとえばtopページなら・・・

```scss:top.scss
/*
共通部分
画像、変数、mixinなど
*/

@import 'pages/top-pc', 'pages/top-sp';

```

```scss:top-pc.scss
/* ======================================
 * pc
 * ====================================== */
.env-pc{
	
}

```

```scss:top-sp.scss
/* ======================================
 * sp
 * ====================================== */
.env-sp{

}

```

もしくはpc.cssとsp.cssを用意しておいて、jsでlinkタグを生成する。

```javascript
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text.css';
link.href = 'css/pc.css';
document.getElementsByTagName('head')[0].appendChild(link);
```

domは用意してあるけどspでは表示しない場合

```scss
.env-sp{
	.sp-none{
		display: none;
	}

}
```


> 参考
端末判定
http://html5-css3.jp/smartphone/pc-iphone-android-php-javascript-htaccess.html



## spサイト基本知識

- font-size 14~16px
- line-height 1.4~1.6
- 左右の余白10px
- リンクやボタンは縦幅44pxがタップしやすい
- 操作が多いサイトではユーザーのズームを制限した方が良い
- 横幅は320pxが基準
- retina対応で画像は2倍サイズを用意
- iPhone,iPadではスクロールバーが表示されないので、` overflow-y:auto; `とか使う  
[PhoneやiPadでスクロールバーを表示する](https://www.netimpact.co.jp/hp-story/21138/)
- spでpcのmouseoverと同じ動きをしたい場合  
[iPhone/iPadでPCと同じJavaScriptのイベントを実装する](http://blog.webcreativepark.net/2010/08/13-205903.html)
Salesforceで自動再割り当て機能を実装してみた話

# 経緯
Salesforceには承認プロセスというものがあり、あらかじめ承認フローを決めておくことで承認業務を手軽に行うことができます。
ただ、何かの都合で承認申請をチェックすることができなかったりするとそこで止まってしまうことが度々あります。
Salesforce標準の機能で代理承認者や手動での再割り当てには以下のような特徴があります。

| 機能名 | メリット | デメリット |
|:--|:--|:--|
| 代理承認者 | 正式な承認者以外にもう一人承認が行える | ホーム画面に未承認申請として出てこない |
| 手動での再割り当て | 任意のタイミングで再割り当て先を選んで割り当てができる | 手動なので忘れるといつまでもそのまま |

承認申請を確認しきれていないことで溜まってしまうことを解消したかったので、今回は自動で再割り当てを行う機能を作ってみることにしました。

# 未承認申請はどこにある？
そもそもSalesforceの中で「未承認申請」はどうやって管理しているのか分からなかったので探してみると、公式リファレンスの中に以下の記述がありました。

>#ProcessInstanceWorkitem
ユーザの保留中の承認申請を表します。

どうやらこれが「未承認申請」のようなので、このオブジェクトの中で割り当て先を管理しているようです。

公式リファレンスを見ると、ProcessInstanceWorkItemオブジェクトの中には以下の項目が設定されています。

| 項目名 | 内容 |
|:--|:--|
| ActorId | 現在承認申請が割り当てられているユーザのID |
| ElapsedTimeInDays | 承認申請が割り当てられてから経過した時間（日単位） |
| ElapsedTimeInHours | 承認申請が割り当てられてから経過した時間（時間単位） |
| ElapsedTimeInMinutes | 承認申請が割り当てられてから経過した時間（分単位） |

今回は時間単位でチェックするので、「ActorId」と「ElapsedTimeInHours」項目を使用しました。

# 実際に作ってみる
未承認申請を表すオブジェクトが見つかったところで、実装に取り掛かりました。
今回作ったものは以下のような機能のプログラムです。

1. １時間に１回、未承認申請をチェックする
2. 申請から５時間以上経過した未承認申請を別の人に割り当てる

処理の大まかな流れは以下のようになっています。

1. 特定の承認プロセスの未承認申請(ProcessInstanceWorkItem)をSOQLで取得する
2. 取得したレコードの経過時間をチェックする
3. 経過時間が５時間以上の未承認申請の承認者(ActorId)を承認者のマネージャに変更する

実際に書いたものは下記のようになりました。

```Apex:AutoReAllocateSample.cls
public class AutoReAllocateSample implements Schedulable{
    global void execute(SchedulableContext SC){
        // 変更対象の未承認申請を取得
        List<ProcessInstanceWorkitem> updList = [SELECT Id, 
                                                        ActorId 
                                                   FROM ProcessInstanceWorkitem 
                                                  WHERE ProcessInstance.ProcessDefinition.DeveloperName = 'SampleProcess'
                                                    AND ElapsedTimeInHours >= 5];
        // 承認者情報の検索・取得用
        Set<Id> ids = new Set<Id>();
        for(ProcessInstanceWorkitem p : updList){
            ids.add(p.ActorId);
        }
        
        // 承認者とマネージャ
        Map<Id, Id> tIdMap = new Map<Id, Id>();
        for(User u : [SELECT Id, ManagerId FROM User WHERE Id = :ids]){
            tIdMap.put(Id, ManagerId);
        }
        
        // 承認申請再割り当て
        for(ProcessInstanceWorkitem p : updList){
            p.ActorId = tIdMap.get(p.ActorId);
        }
        
        update updList;
    }
}
```

これで再割り当てを行うプログラムができました。
あとはこれをスケジュール実行すれば定期的にチェックして再割り当てを行ってくれます。

```Apex:scheduleSample.cls
AutoReAllocateSample a = new AutoReAllocateSample();
String sch = '0 0 * * * ?';
String jobID = system.schedule('自動再割り当てサンプル', sch, a);
```

これで未承認申請がたくさんたまってしまうことを避けられるかもしれません。

# 参考資料
今回の機能を実装するにあたり以下を参考にしました。
[Salesforce および Force.com のオブジェクトリファレンス](https://developer.salesforce.com/docs/atlas.ja-jp.object_reference.meta/object_reference/sforce_api_objects_processinstanceworkitem.htm)
sedで末尾-1行目に追記する

# 目的

```json
[
  {"data": "2016-01-05", "weight": "65.3"}
  ,{"data": "2016-01-06", "weight": "65.6"}
  ,{"data": "2016-01-08", "weight": "67.1"}
  ,{"data": "2016-01-12", "weight": "66.3"}
]
``` 

なjsonファイルの末尾に新しくデータを追記したい。
CSVファイル等なら`echo hogehoge >> weight.csv`などとやればいいのだが、jsonの場合は単純に末尾に追加するのではなく、`]`の前にデータを追加する必要がある。
わざわざjsonをパースして要素を追加し、ファイルに書きだすのは面倒臭い。

# 解決法

こういう時はsedをつかい

`sed -i -e '$i\  ,{"data": "2016-04-13", "weight": "70.0"}' weight.json`

としてやれば良い。

```json
[
  {"data": "2016-01-05", "weight": "65.3"}
  ,{"data": "2016-01-06", "weight": "65.6"}
  ,{"data": "2016-01-08", "weight": "67.1"}
  ,{"data": "2016-01-12", "weight": "66.3"}
  ,{"data": "2016-04-13", "weight": "70.0"} <--追加行
]
``` 

sedにはいくつか実装があり、`sed -i -e '$-1i 追加文字列'` とすべき場合もあるらしい。

# 環境
gnu-sed 4.2.2
Vagrant 上でアプリケーションを開発している時にファイルの変更がうまくいかない問題の解決策

Vagrantの共有フォルダをWebroot 直下に設定し、ローカルからファイルをアップロードしている時に、　　
ファイルの更新がうまく反映されないという問題が起きた。 
今回はJSファイルを編集中に問題が起きたが、過去にCSS でも同様の問題が起きたことがあるらしい。

##出来事  
図1:エラー画面のスクリーンショット
![error.png](https://qiita-image-store.s3.amazonaws.com/0/115634/c663d36e-1483-0bb3-45f8-9650c23b3281.png)  

こんなコード書いた覚えが無かったので慌ててエディタをカクニン！
図2:図1の状況が起きた時のエディタのスクリーンショット
![Editor.png](https://qiita-image-store.s3.amazonaws.com/0/115634/515b9cba-0ba1-8823-639d-09c62e699124.png)
ちゃんとある！！！

##解決法

httpd.conf の一番下に以下の２行を追加

    `EnableMMAP Off`
    `EnableSendfile Off`
ｰ>apache の再起動
`sudo systemctl restart httpd`
###ちなみに・・・  
上記の方法が分かる前に試してみた解決策
1 Vagrant を再起動する。
2 めっちゃリロードする。

###試してみた解決策の問題点
めっちゃ時間がかかる。

##原因を調べてみた  

上記2つの設定をOFFにしたのだから、それらの設定が鍵を握っているに違いない。
ということで、調べた。
 公式ドキュメント [enablemmap](http://httpd.apache.org/docs/2.4/ja/mod/core.html#enablemmap)
 公式ドキュメント [enablesendfile](http://httpd.apache.org/docs/2.4/ja/mod/core.html#enablesendfile)


公式ドキュメントにこのように記載されている。

> NFS マウントされた DocumentRoot では、httpd がメモリマップしている間に
ファイルが削除されたり短くなったりしたときに起こるセグメンテーションフォールトのために 
httpd がクラッシュする可能性があります。
~Apache 2.2 公式ドキュメント~


###NFS (Network File System) マウント
Linuxが動作するPC(環境？)と別のPCのディレクトリを共有するときに使う手法の一つ
ちなみにVagrant はNFS を使う（らしい）  

ということで、Vagrant 環境で開発する際は、  

    `EnableMMAP Off`
    `EnableSendfile Off`
が重要という話でした。

参考リンク
[公式ドキュメント](http://httpd.apache.org/docs/2.4/ja/mod/core.html)
[参考にした記事](http://www.trapon.jp/log/201310/donot_read_file_use_vagrant_shared_folder.html)

環境  
CentOS7.1
Apache 2.4
（ちなみにApache 2.4に特有の現象というわけではないらしいです。[Apache 2.2 公式ドキュメント](http://httpd.apache.org/docs/2.2/ja/mod/core.html#enablemmap)）
リマインド★-[PHP]Object比較

今日は、韓国人イ・ドヒョンと申します。
本当に短な内容なので、すみません。

最近、CakePHP3からObjectでよく開発しながら、Objectを比較する場合がありました。
PHPでObjectの比較するのもメモリアドレスを比較するので、注意する必要があります。

##⊙PHPのオブジェクト比較
#####・「==」の場合、型比較とメンバー変数を比較
#####・「===」の場合、メモリアドレスだけ比較
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/d573fb10-8d03-e05e-92e8-4c0633aebff3.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/108364/b80e24aa-9c2c-0f94-f8e8-fe29611d7e0c.png)
Pythonでクラスやモジュールのメソッド引数情報をリストアップする

仕事で、あるPythonモジュールに属するすべてのメソッド引数をリストアップする必要があったので調べてみました。
すごくニッチな作業だとは思いますが、メモ代わりに(^_^;)

## 方針

inspectモジュールでトップレベルのクラスやモジュールのメタ情報から探っていく。

inspectモジュールの詳細 -> https://docs.python.org/2/library/inspect.html

### inspect.getmembers(object)

引数に与えたオブジェクトに属するすべてのメンバを、tuple('name', 'value')という形式のリストで返却する。

### inspect.getargspec(func)

引数に与えたファンクションの引数情報を、tuple(args, varargs, keywords,　defaults)という形式で返す。argsに引数のリストが入っている。


以下、例です。

openstackのDBaaSであるTroveのpythonclientが例となっています。
（troveへのAPI発行するI/Fのすべての引数を調べたかった。）

troveclient.v1.client.Client
のクラスのインスタンス変数に、様々なクラスのインスタンスを持っているという構造
それぞれのインスタンスが持っているメソッドの引数を調べるコードが以下

```py
import inspect
import troveclient.v1.client as dbcli


cli = dbcli.Client('', '', '')
cli_info = inspect.getmembers(cli)
for rds_info in cli_info:
    if rds_info[0][0] != "_":
        # Above if statement is for removing private class
        for info in inspect.getmembers(rds_info[1]):
            if inspect.ismethod(info[1]):
                if info[0][0] != "_":
                    # Above "if" statement is for removing private method
                    for arg in inspect.getargspec(info[1]).args:
                        print rds_info[0], info[0], arg
```

以下はCLIのI/Fを調査するコード
getmembersは本当にすべての属性をとってきてくれるので
デコレータで宣言されている属性なんかもとれました。

```py
 import inspect
 import troveclient.v1.shell as rdscli

 for i in inspect.getmembers(rdscli):
     if inspect.isfunction(i[1]):
         for j in inspect.getmembers(i[1]):
             if j[0] == 'arguments':
                 # Above if statement is for retrieving decorators attribute. 
                 for k in j[1]:
                     required = 'y'
                     default = 'None'
                     helpstr = k[1].get('help')
                     if 'default' in k[1].keys():
                         required = 'n'
                         default = k[1].get('default')
                     if default is None:
                         default = 'None'
                     if helpstr is None:
                         helpstr = 'None'
                     if isinstance(default, list):
                         default = "[" + ",".join(default) + "]"
                     print(i[0] + "|" + k[0][0] + "|" + required +
                           "|" + default + "|" + helpstr)
```
リマインド★-[PHP]Vr.5.5以上のOOP構成整理

今日は、韓国人イ・ドヒョンと申します。
最近、PHP vr.5.5以上でプロジェクトを行う場合が増えて、
vr.5.5以下のバージョンのOOPの構成でするとよく間違って場合がありました。

で、PHP vr.5.5以上のOOP構成を整理したいと思いました。

##⊙ PHPのOOP構成 
:o:メンバー(変数(properties)、メソッド)
:o:生成者
:o:消滅者
:x:Construct block
:x:Overloading 
　　　ㄴ :loudspeaker:(magic functionを適用する)
:o:Extend 
　　　ㄴ :o:メンバーだけを引き継ぐ
　　　ㄴ :x:生成者が上から連鎖的に呼ぶ。
　　　　　　ㄴ :loudspeaker:親を呼ぶ場合は、自分自身に生成者が定義されていない場合
　　　　　　ㄴ :loudspeaker:PHPには生成者がなくてむ良い
　　　　　　ㄴ :loudspeaker:PHPに生成者がprivateで設定されている場合、生成者を無視してオブジェクトができない
　　　ㄴ :o:Overriding
　　　ㄴ :o:アクセス制御者で「public, protected, private」がある
　　　ㄴ :x:アクセス制御者で「default」がある
　　　ㄴ :x:Package
　　　ㄴ :o:static
　　　　　　ㄴ :loudspeaker:インスタンスメンバー、クラスメンバーに全部つけることも可能
　　　ㄴ :o:単一相続
　　　ㄴ :x:多重の相続
:o:Polymorphism (OOPの花！)
　　　ㄴ :o:動的バインディングのせいで意味なし、型自体がない)
:o:Abstract Class
:o:Interface 
　　　ㄴ :loudspeaker:定数とAbstractメンバーで構成
:o:Exception Handling
　　　ㄴ :x:throws



:o:特定の父、子を歌って使うことのできる関数
:o:object lteration (オブジェクトを一度回りもの)
:o:comparing objects (オブジェクトを比較すること)
:o:オブジェクト直列化
:o:Traits
:o:Object Copy
:o:Object match-up
:o:Object Auto
:o:Type Hinting
:o:Namespace

以上です。
今度、ちょっと詳しく、綺麗に整理します。
Errbotをローカルで動かすメモ

「Python製のチャットボットないかなー」と探してた際に見つけたので、しばらく使ってみる。

http://errbot.io/

# マニュアル斜め読み

ドキュメントから雑に確認した際の、自分の理解集

* Slack, Hipchat などの、いくつかのチャットサービス用のバックエンド機構が最初から同梱されている(hubotのアダプターに相当するもの)
* 話しかけてきた相手が管理者かどうかを判定して動くことが可能っぽい？
* プラグイン（ボットの振る舞い）を検証するためのローカル動作モードがある模様
* 「n分間隔で喋る」ような仕組みはあるっぽい
    * ただし、cronみたいな毎日n時に喋るはまだ見つけられてない


# インストール

## 想定環境

* pyenv利用して構築

## インストールまで

```shell-session:インストールしてみる
$ pyenv virtualenv 3.5.1 errbot
$ pyenv shell errbot
$ pip install errbot slackclient
$ mkdir mybot
$ cd mybot
$ python -c "import errbot;import os;import shutil;shutil.copyfile(os.path.dirname(errbot.__file__) + os.path.sep + 'config-template.py', 'config.py')"
```

## 設定を追加

「とりあえず動作確認」のために修正した方がいいところ

```py3:config.py
# L66
# データ保存用フォルダ。相対パスの方が挙動確認が楽
BOT_DATA_DIR = './data'
# L85
# カスタムプラグインを置く場所。デフォルトはNoneで使わないが、どうせ作るなら、相対パスで
BOT_EXTRA_PLUGIN_DIR = './plugins'

```

### 実行してみる

```shell-session:とりあえず、テキストでバックエンドで起動させてみる
$ vi config.py
$ errbot -T
22:30:14 INFO     errbot.err                Config check passed...
22:30:14 INFO     errbot.err                Selected backend 'Text'.
(中略)
22:30:15 INFO     errbot.errBot
22:30:15 INFO     errbot.errBot             Notifying connection to all the plugins...
22:30:15 INFO     errbot.plugins.ChatRoom   Callback_connect
22:30:15 INFO     errbot.errBot             Plugin activation done.

>>>
```

## ざっくり、挙動解説

デフォルトでは、`!`を先頭に持つテキストをbotへの命令として認識します
試しに、ヘルプを呼び出してみるとこうなります。

```shell-session:errbot
>>> !help

╌╌[MD  ]╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
### All commands

╌╌[HTML]╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
<h3>All commands</h3>

╌╌[TEXT]╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
All commands

╌╌[IM  ]╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
_All commands_

╌╌[ANSI]╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
All commands

╌╌[BORDERLESS]╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
All commands

>>>
```

出力量がとてつもなく多いので省略しましたが、Markdown,HTML,プレーンテキストなど様々な種類のフォーマットでレスポンスを返してくれます。
例えばSlackを反応するように起動させると、HTML形式になるように返してくれます。

ちょこちょこいじって遊んでいる最中なので、ちょこちょこ投稿したいと思います。
Swift で Strideable な独自タイプを実装してみる


Swift 3.0 で C言語スタイルの for ループが廃止されるので、その書き換え方法のまとめ
http://qiita.com/codelynx/items/899c26dd2cbdba7d2b00

にも書きましたが、飛び石になる `for` ループを実装した場合は、`Strideable` プロトコルを実装してあげるのが良さそうです。そこで、`Int` や `Double` とかではなく、独自のタイプの場合どう書けば `Strideable` を実装できるか試してみる事にしました。

その型の名前は考えたあげく `Score` にしました。単に、整数 `value` を持つだけです。 `Strideable` に適合する為には、`distanceTo()` と `advancedBy()` を実装するのと、さらに `Comparable`, `Equatable` のプロトコルも実装してあげます。


```.swift
struct Score: Strideable, CustomStringConvertible {

	typealias Stride = Int
	var value: Int

	init(_ value: Int) {
		self.value = value
	}
	
	func distanceTo(other: Score) -> Int {
		return other.value - value
	}
	
	func advancedBy(n: Int) -> Score {
		return Score(self.value + n)
	}
	
	var description: String {
		return String(value)
	}
}

func < (lhs: Score, rhs: Score) -> Bool {
	return lhs.value < rhs.value
}

func == (lhs: Score, rhs: Score) -> Bool {
	return lhs.value == rhs.value
}
```

では、0 から 100 未満まで 25 づつ stride してみましょう。

```.swift
for score in Score(0).stride(to: Score(100), by: 25) {
	print(score)  // 0, 25, 50, 75
}
```

0 から 100 以下まで 25 づつ stride してみましょう。

```.swift
for score in Score(0).stride(through: Score(100), by: 25) {
	print(score) // 0, 25, 50, 75, 100
}
```

できました。うまく動くようです。個人的には by の値が Score で指定できないのは、少し引っかかりますが、まぁ良しとします。浮動小数点数を扱いたい場合は…　是非試してみてください。

この記事を書く間に何度も、「Strippable」と打ってスペースキーを押すと「Strippable」に自動変換してくれるのが驚きでした。Appleさん。

では、皆さん Have a happy coding!!

```.console
swift --version 
Apple Swift version 2.2 (swiftlang-703.0.18.1 clang-703.0.29)
```

（参考資料）
https://ez-net.jp/article/24/eO3YibBI/bKdTpaUfz0Ou/
Swift のインデックス型を理解する
exeからjavaを起動する際にエラーが出たんだが！怒

以前javaで作ったアプリが、Windows8.1にインストールしても動かないと連絡があったので、調査した。
※JavaFX使ってる

手元にWindows8.1が無いので、7と10に入れて動作確認してみた。
フツーに動く。

8.1で起きたエラーの話を聴くと
例外 C0000005
が出ていたと言う。

色々と、試したり、検索したりたところ
で引っかかったのが
https://github.com/eivindveg/HotSUploader/issues/30

結局、pathに全角文字が使われているとエラーになるらしい。
opneJdkのバグだとか

Windows機ではアリガチだな・・・

とりあえず、インストールフォルダに全角を使用しないことで対処する予定だが、継続調査必要ね。。。


追記：
ーーーー　win7でエラーダイアログに出ていた内容　ーーーーーーー
問題の署名:
  問題イベント名:	APPCRASH
  アプリケーション名:	●○●○.exe
  アプリケーションのバージョン:	0.0.0.0
  アプリケーションのタイムスタンプ:	5679c668
  障害モジュールの名前:	packager.dll
  障害モジュールのバージョン:	0.0.0.0
  障害モジュールのタイムスタンプ:	5679c679
  例外コード:	c0000005
  例外オフセット:	000000000001d6f0
  OS バージョン:	6.1.7601.2.1.0.768.3
  ロケール ID:	1041
  追加情報 1:	23e2
  追加情報 2:	23e2b71f4deb1cd1e181414bc17f0b2d
  追加情報 3:	a35d
  追加情報 4:	a35dffbe894250071c05c0ab6e123d70

オンラインのプライバシーに関する声明をお読みください:
  http://go.microsoft.com/fwlink/?linkid=104288&clcid=0x0411

オンラインのプライバシーに関する声明が利用できない場合は、プライバシーに関する声明をオフラインでお読みください:
  C:\Windows\system32\ja-JP\erofflps.txt
ーーーーーーーーーーーーーーーーーーーーーーーーーーー
Live2D物理演算解析　２

[前回](http://qiita.com/Ganeesya/items/238fb68b11442c3ef39b)は物理演算に対する入力の鋭さとその影響をチェックし、
その結果から振り子モデルが一周する現象を確認した。
今回は大回転現象を足がかりに振幅を小さく予定スケールに落とし込む方法を探っていく。

#探したい2つのアプローチ
出力を予定スケールへと落とし込むとき、二つの方法が考えられる
モデルと比較するとわかりやすいが
・振幅自体を小さくする方法と
・振幅表記を小さくする方法だ
**大きな違いは大回転現象を起こすか否かである。**
これを判定に使っていく。
表記が小さくされているならば大回転現象を起こし、
振幅自体が小さくなっていれば大回転現象が収まるはずだ。

#テストパラメーター候補
実験項目として考えてみたが今後のこともあるので、
実験はすべての要素について0.1にした曲線を作成する。
またX,Yなどの要素の変更もチェックする
<img width="485" alt="リスト.png" src="https://qiita-image-store.s3.amazonaws.com/0/117475/8c9cf6df-7de5-52c8-bd00-200c0c8d62dc.png">

・質量
・長さ
・ゆれ減衰
・入力タイプX,Y,Angle
・入力移動量
・入力影響量
・出力タイプA,Ag
・出力移動量
・出力影響量

入力データは前回の1fのモノを使用し、All1と波形を比較する形で検証する。

#注目データ
☆質量
![質量.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/3beea2d9-d331-0757-6e8f-116c2f05998a.png)
振れ幅の操作に使い易そうだったが大問題なパラメーター
0.1のラインをみるとわかるが何らかの抵抗を受けてるのか羽が舞い降りるように振動しなくなる。
振幅操作とは別物と捉えた方が良い

☆入力移動量、影響量
移動
![入力移動.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/e5cb8b5f-1596-72f7-d77b-c0fe17009da6.png)
影響
![入力影響.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/6db7cc7d-725d-1036-0dd5-ccd67565fa70.png)
大回転現象が収まってるところを見ると振幅自体を小さくするならばこの方法が良さそう。
しかし移動量と影響量、作用方法に違いがあるようで要検証。

☆出力移動量、影響量
移動
![出力移動.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/2a3ff216-430e-8b51-2564-97e1b9f87985.png)
影響
![出力影響.PNG](https://qiita-image-store.s3.amazonaws.com/0/117475/d4e1e3cd-bac8-2501-25ae-24e2e50104f2.png)
大回転現象が小さくなっても収まらない。
出力される振幅だけ小さくしたいならば間違いなくコチラ。
移動と影響でほぼ同じ反応を示しているが他の物理演算が噛んだときの反応用で別れてるはずなので
通常時は移動量で絞るのが正しそう。

#今回のマトメ
・思ったよりも空気抵抗のようなものが存在する。ふわりとした物理演算も可能。
・振れ幅を小さくするならば入力をいじるのがよさげ
・出力表記はAngleの表示通り角度で来る。絞るのは出力移動量がよさげ

次回は他のテストデータを見ていき物理演算の全体イメージを詰めていきたい。
DeviceClient.SendEventAsyncでUnauthorizedExceptionが出る


Windows IoTをインストールしたRaspberry Pi 2でAzure IoT Hubにメッセージを送ろうとしたら次のような例外が出た。

    string uri = "<Azure IoT Hub URI>";
    string deviceId = "<DeviceID>";
    string deviceKey = "<DeviceKey>";
    
    var deviceClient = DeviceClient.Create(
        uri,
        new DeviceAuthenticationWithRegistrySymmetricKey(deviceId, deviceKey),
        TransportType.Http1);
        
    var message = new Message(Encoding.UTF8.GetBytes("Test Message"));
    await deviceClient.SendEventAsync(message);



**例外：Microsoft.Azure.Devices.Client.Exceptions.UnauthorizedException**
**メッセージ：{"Message":"The specified SAS token is expired"}**

どうもこの例外はWindows IoTデバイスの時刻が大きくずれていると発生するようだ。

https://social.msdn.microsoft.com/Forums/en-US/2635c745-ba09-4164-b68b-35631bdcddc3/the-specified-sas-token-is-expired?forum=WindowsIoT


# 対処方法
デバイスの時刻を正しいものにすればいいので、下の自分の記事にあるように時刻同期を行ったら正常にメッセージを送れるようになった。

[Windows IoTで時刻を同期する - Qiita](http://qiita.com/locatw/items/1b8150a8209c3e8afc9b)
ｐｈｐ勉強１日目

今日したこと

・プログラミング仕事についてネットで調べる
・ｐｈｐに対象を絞る
・ドットインストールにろぐいん



（できたこと）
・ＸＡＭＭＰ入れた
・↑について知る
・ＰＨＰについて理解を深める


やりたいこと
ＰＨＰでかんたんなプログラムかく
メソッド参照の挙動


同じ記述によるメソッド参照でも、別インスタンス・別クラス（匿名クラス）となる。

```java
final Runnable a = this::run;
final Runnable b = this::run;

System.out.println(String.valueOf(a.equals(b))); // false
System.out.println(String.valueOf(a.getClass().equals(b.getClass()))); // false
```
Mybatisのクエリをlogbackで出力する

### 設定
クエリ内容の出力は、作成したMapperをnameとしてDEBUGレベルで出力されるよう。
なのでlogback.xmlはこんな感じ。

```xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration>
<configuration>
	<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
		<encoder>
			<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
		</encoder>
	</appender>

    <!-- MapperのあるパッケージをDEBUGレベルに -->
	<logger name="com.example.mappers" additivity="false">
		<level value="DEBUG" />
		<appender-ref ref="STDOUT" />
	</logger>

	<root level="info">
		<appender-ref ref="STDOUT" />
	</root>
</configuration>
```
### 出力イメージ
1クエリに付き2行。
```
==>  Preparing: [クエリ本体]
==> Parameters: [パラメータ1]([型]), [パラメータ2]([型]), ...
```

パラメータが多いと結構重いので、パッケージでひとまとめに括るより見たいMapperだけを指定したほうが良いかもしれない。
Windowsバッチ オフセット付き現在時刻取得用ワンライナー

### 概要
他のプログラムの引数にオフセット付き時間を渡すための設定値で、デフォルトを現在時刻にしたかった。
標準だとそんなAPIはなさそうなので、JScriptを呼び出して```Date#getTimezoneOffset()```を利用することに。

### コード
```bat
for /f "usebackq delims=" %%0 in (`mshta "javascript:window.onunload=function(){function f(d){function c(V,S){return ('00'+V).slice(-1*S)}var o=d.getTimezoneOffset();return c(d.getFullYear(),4)+'-'+c(d.getMonth()+1,2)+'-'+c(d.getDate(),2)+' '+c(d.getHours(),2)+':'+c(d.getMinutes(),2)+':'+c(d.getSeconds(),2)+'.'+c(d.getMilliseconds(),3)+' '+(o<0?'+':'-')+c(Math.abs(o)/60,2)+':'+c(Math.abs(o)%% 60,2)}new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).WriteLine(f(new Date()))};close()"`) do @set "OFFSET_DATETIME=%%0"
```

### ポイント
* mshtaでJScriptを起動してワンライナー。
* new Date()で生成した現在時刻から各パラメータを切り出して標準出力に吐き出す。
    * formatくらい標準でほすぃ。
* mshtaは512文字?までしかスクリプトを受け付けてくれないので、収まる程度に手動でminify。もっと見やすくもできるかもしれないけど、とりあえず目的に適うのでこれで。
* getTimezoneOffset()はオフセットを分単位で返す上に符号が直感と逆なので注意。
    * +09:00は-540。
* あとはバッチのforで環境変数に展開。
Windows IoTで時刻を同期する


Windows IoTではw32tmというコマンドで時刻同期ができる。

確認した環境は次の通り。

* デバイス：Raspberry Pi 2 Model B
* Windows IoT バージョン：10.0.10586

また、デバイスのIPアドレスは"192.168.0.1"とする。

# PowerShellでWindows IoTに入る

PowerShellのコンソールを開き、次のコマンドを実行してWindows IoTが動いているデバイスに接続する。

    > Set-Item WSMan:\localhost\Client\TrustedHosts -Value 192.168.0.1
    > Enter-PSSession -ComputerName 192.168.0.1 -Credential 192.168.0.1\Administrator

# 時刻を同期する

まずは時刻同期先を設定する。同期先はtime.windows.comにした。

    > w32tm /config /update /manualpeerlist:time.windows.com /syncfromflags:manual
    
設定したらサービスを再起動する

    > net stop w32time
    > net start w32time

時刻同期を実行する。

    > w32tm /resync

# 参考
* [Use PowerShell to connect to a Windows 10 IoT Core device. - Windows IoT](http://ms-iot.github.io/content/en-US/win10/samples/PowerShell.htm)
* [Windows-NTPコマンド設定  CapmNetwork](http://capm-network.com/?tag=Windows-NTP%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E8%A8%AD%E5%AE%9A)
リマインド★-[JS]parsing (Array→JSON)

今回、NodeでCLIソリューションズを実装するプロジェクトがありました。
いろいろな処理の結果をJSONで出力する要望があってパースする必要がありました。
※パースとは、 **「加工されていないデータで希望する特定の文字列を取り出す作業」**ということです。

JavascriptにはJSONでパースするため、**”JSON”**というオブジェクトを使っています。
そして、いろいろなライブラリーをダウンロードして、利用するのもできます。

※JSON-js ライブラリー
https://github.com/douglascrockford/JSON-js

##よく利用するJSONオブジェクト
```
・JSON.parse(text [, reviver])
  ㄴ  json → Array
・JSON.stringify(value [, reviver] [, space])
  ㄴ Array → json

※ パラメーター
1. text[必須] : JSON 文字列
2. reviver[選択] : 結果を返還する関数です。 この関数はオブジェクトのそれぞれのメンバーに対して呼ばれます。
```
例）![スクリーンショット 2016-03-17 17.27.53.png](https://qiita-image-store.s3.amazonaws.com/0/95799/dd971463-68d1-5bb9-b1d6-ca29bae37ade.png)

しかし、stringifyメッソドとparseメッソドが動作した結果だけ見ると・・・
率直に、「何が変わった？」と・・・
私が実にJSON形式のデータはこんな姿なのにですね。
![スクリーンショット 2016-03-17 17.28.34.png](https://qiita-image-store.s3.amazonaws.com/0/95799/d829e632-9f33-1860-0382-0b678e41ab77.png)

##オブジェクトバース
で、少し探して見ると、意外に簡単でした。
オブジェクトを一つ定義して、
`[ 配列[キー] = オブジェクト[要素] ] & [ 配列[値] = オブジェクト[値] ]`
で内容を構成します。
そして、そのオブジェクトをJSON.stringifyメッソドでJSON形式にバースすると終わり！

![スクリーンショット 2016-03-17 17.30.53.png](https://qiita-image-store.s3.amazonaws.com/0/95799/da2b2138-bdd9-4593-7d55-788e1e2a14f9.png)
GoogleBooksAPIでISBNコードを使って書籍を検索するときのワナ

##はじめに

GoogleBooksAPIを使うと様々な条件で書籍の検索ができます。
ややこしい登録や認証が不要なのでとても使いやすいです。
ですがISBNコードで書籍を検索するときはちょっと注意が必要という話です。

##忙しい人のために

ISBNで検索するときは、

```
https://www.googleapis.com/books/v1/volumes?q=search+isbn=[ISBN10]
```
じゃなくて

```
https://www.googleapis.com/books/v1/volumes?q=isbn:[ISBN10]
```
で検索しよう。


##説明

[GoogleBooksAPI](https://developers.google.com/books/docs/v1/using#PerformingSearch)によると検索APIの基本形は以下のようになっています。

> https://www.googleapis.com/books/v1/volumes?q=search+terms

この"terms"の部分に検索パラメータを当てはめればOKということらしいです。
例えばISBN10で検索したいときは次のURLになるわけです。

https://www.googleapis.com/books/v1/volumes?q=search+isbn=489471194X

ですがこのURLでリクエストを送ると書籍が４つも返ってきます（実際の結果は上記URL参照）。

|Title |ISBN10  |
|---|---|
|C++ FAQ|489471194X|
|雲の王| 4087453405 |
|エキスパート Cプログラミング| 4756116396 |
|C言語ポインタ完全制覇| 4774111422 |

ISBNでちゃんと検索できているのは最初の一冊だけです。
「雲の王」というのは普通の小説なので関連性もありません。

なぜ固有IDであるはずのISBNで複数の本が引っかかるのかというと、どうやらレスポンスの"PreviewLink"という項目の値に検索対象のISBNと同じ文字列が入っているからのようです。

> "previewLink":http://books.google.co.jp/books?id=QRkPswEACAAJ&dq=search+isbn%3D489471194X&hl=&cd=2&source=gbs_api

結局のところISBNで正しく検索するためのURLは次の形式になります。

```
https://www.googleapis.com/books/v1/volumes?q=isbn:[ISBN10]
```

今度はちゃんとISBNで検索できます。

https://www.googleapis.com/books/v1/volumes?q=isbn:489471194X

- ISBN10じゃなくてISBN13を使ってももちろんOKです。
- 他の検索パラメータでも同じ事象があるかもしれませんが、試していません。