OmniAICreator/Qiita-1.07M huggingface dataset:
Vue-routerでコンポーネント側のpropsの値に応じてURLを変更したい

##やりたいこと
- Vue-routerのルーティングで使われるComponent側のpropsの変更でもURLを変更したい

##課題
- ```<router-view>```に```v-bind:paramName.sync="$route.params.paramName"```と渡してもURLは変更されない。値は変わっているが検知されない
    - ただし、URLを変更して```$route.params.paramName```が変更された場合は検知され、コンポーネントのpropsも変更される
- 仮に上記方法で出来たとしても、ルーティングが増えればそれだけコンポーネントも増え、渡す値も増えるので```v-bind```でやると破綻が見えている

```js:てきとうなSPAアプリ
var News = Vue.extend({
    props:{
		newsId:{
			type:Number,
			default:1
		}
	}
});
var Mail = Vue.extend({
    props:{
		mailId:{
			type:Number,
			default:1
		}
	}
});
var Todo = Vue.extend({
    props:{
		todoId:{
			type:Number,
			default:1
		}
	}
});
var router = new VueRouter();
router.map({
	'/News/:news_id':News,
	'/Mail/:mail_id':Mail,
	'/Todo/:todo_id':Todo
});
/*
 この時v-bindでpropsと結びつけようとすると、View側の<router-view>に
 <router-view :news_id="$route.params.news_id" :mail_id="$route.params.mail_id" :todo_id="$route.params.todo_id"></router-view>
 とかやらなきゃならず、コンポーネントが増えれば増えるほど、各々のコンポーネントから見れば要らないものを結びつけようとする
*/

```

- と言ってComponent内で```$route.params```を使うと密結合になってしまう

##とりあえずの方法
- router.mapでルーティングにコンポーネントを割り当てる際に予め定義したコンポーネントをextendしてwatchとcreatedで値をsyncさせる

##サンプル
http://jsdo.it/hadakadenkyu/uizq

```js
// URLパラメータはStringなので数値型に変換
Vue.filter('int',function(val){return parseInt(val);});
var App = Vue.extend();
var router = new VueRouter();
var Component = Vue.extend({
    template:"<p>Current route params: {{$route.params | json}}</p><p>pageNum: <input v-model='pageNum' type='number' number></p>",
    props:{
        pageNum:{ // 1. この値に応じてURLを変えたい
            type:Number,
            default:1,
            twoWay:false // trueにしても意味がない。$route.paramsはdefinePropertyでプロパティを設定していないから見張れない
        }
    }
});
// 2. 疎結合ならrouterの存在はComponentは知らない筈なので・・・
router.map({
    '/page/:pagenumber': {
        component: Component.extend({ // 3. routerの中でComponentを割り当てる時にwatchでpageNumを見張るよう設定する
            watch:{
                'pageNum': function (val, oldVal) {
                    router.go('/page/'+val);
                },
                '$route.params.pagenumber':function(val,oldVal){
                    this.pageNum = parseInt(val);
                }
            },
            created:function(){ // 4. 初期値はv-bindでなくこっちで入れないとrouter-viewタグに全部書く羽目になる
                this.pageNum = parseInt(this.$route.params.pagenumber);
            }
        }),
        // 5. 例えばこう書ければいいのに
        /*
        bind:{'pagenumber':{
                name:'pageNum',
                sync:true // changing pageNum invokes router.go
            }
        }
        */
    }
});
router.start(App, '#app',function(){
    router.go('/page/5');
});
```
## 疑問点
- もっとシンプルに書けないものか
- イベントドリブンにしてComponentから```$dispatch```してAppでrouter.goするのとどっちが良かろうか
docker + laravelの環境構築

## 事前準備
### DockerToolBox
https://www.docker.com/docker-toolbox
### direnv
※brew install go等で予めインストールしておくこと。

https://github.com/direnv/direnv
```
$ git clone https://github.com/direnv/direnv
$ cd direnv
$ make install
$ # or symlink ./direnv into the $PATH
```

#### Zshを使っているなら~/.zshrcに追加してください

```
eval "$(direnv hook zsh)"
```

#### Bashを使っているなら~/.bashrcに追加してください
```
eval "$(direnv hook bash)"
```

## Docker Machineの構築

`--virtualbox-hostonly-cidr` を指定して、他のDocker MachineとNWが被らないようにする。この例では`192.168.93.100`とします。

```
$ docker-machine create --driver virtualbox --virtualbox-hostonly-cidr "192.168.93.1/24" laravel
```

## laradockでの環境構築
今回、laradockを使用したので、下記を参考にしました。
・http://qiita.com/niisan-tokyo/items/d4485b8bb4fbfcfcc6be

laradock/workspace配下にて、
```
docker-compose up -d workspace
```
すると、下記が出力されます。
```
Starting laradock_volumes_source_1
laradock_workspace_1 is up-to-date
```

```
docker ps
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS               NAMES
4a160037d5c4        laradock_workspace   "/sbin/my_init"     4 days ago          Up 10 minutes                           laradock_workspace_1
```
```
docker-compose ps
          Name                 Command      State                     Ports
---------------------------------------------------------------------------------------------

laradock_nginx_1            nginx           Exit 0   0.0.0.0:443->443/tcp, 0.0.0.0:80->80/tcp
laradock_php-fpm_1          php-fpm         Exit 0   9000/tcp
laradock_volumes_data_1     true            Exit 0
laradock_volumes_source_1   true            Exit 0
laradock_workspace_1        /sbin/my_init   Up
```

`laradock_workspace_1`のコンテナに入るために下記のコマンドを実行します。
`docker exec -it laradock_workspace_1 /bin/bash`

## スケルトンプロジェクトの作成
`docker-compose.yml`を確認し、
workspaceコンテナ上で、`composer create-project laravel/laravel testapp`
を実行し、プロジェクトを作成する

ローカルPCに戻って、workspaceのcomposeをstopする
```
exit
docker-compose stop 
```

## テストプロジェクトの起動
`docker-compose.yml`のvolumesを変更し、下記コマンドを実行
docker-compose up -d php-fpm nginx mysql

作成が完了すると、以下のコマンドでDocker Machineへのアクセスに必要な環境変数を取得できます。

```
$ docker-machine env laravel
# 取得される情報の例
export DOCKER_TLS_VERIFY="1"
export DOCKER_HOST="tcp://192.168.93.100:2376"
export DOCKER_CERT_PATH="/Users/sato/.docker/machine/machines/laravel"
export DOCKER_MACHINE_NAME="laravel"
```
RPG ツクール MV 製のブラウザゲームはなぜ「重い」と言われるのか、その対策

昔から RPG ツクール のファンなので、twitter の `#ツクールMV` ハッシュタグが付いたツイートをよく見ているのですが、とにかく「RPGツクールMV製のブラウザゲームは重い」という声が多いです。
なぜ重いのでしょうか？ というのと、その対策を、エンジニアの視点から **非エンジニア向けに** 噛み砕いて書いてみます。

## 重い理由

* 今までの RPG ツクール製ゲーム
* iPhone の App Store からダウンロードできるゲーム
* Android の Google Play Store からダウンロードできるゲーム

これらは「ゲームのダウンロード時に、素材を最初にすべて端末にダウンロードする」という形式をとっています。

対して RPG ツクール MV 製の **ブラウザゲーム** は、「必要な素材をマップが切り替わるたびに都度ダウンロードしている」というスタイルを採っています。

なのでマップが切り替わるたびに、次のマップで必要な素材をダウンロードするため、 `Loading...` 画面でユーザーは待たされます。これが重いと言われる所以だと私は考えています。

その他に、CPU スペックの低いスマートフォン端末の場合、グラフィックの描画に時間がかかることも重さの一要因と思われます。しかしこれは、 **RPG ツクール MV v1.3.0（というか pixi.js のアップグレード）でかなり改善された** ようです。RPG ツクール MV v1.3.0 対応は必ずするべきでしょう。

## 対策

動作を軽くするには、 **ブラウザゲーム版で提供するのではなく、 PC ならダウンロード版として、スマートフォンならストアからダウンロードするアプリ版として提供する** のが対策の１つであるといえるでしょう。これによって、マップが切り替わるたびに「外部サーバーから」素材をダウンロードしなくなるため、マップ切り替え時に待たされる時間はある程度短縮できると思います。

ただしこの方法にはデメリットがあります。それは、ブラウザゲーム版と異なり、 **ユーザーにゲームをダウンロードしてもらう必要が当然ながら生じる** ことです。 **ダウンロードが面倒に感じるユーザーには遊んでもらえなくなる** でしょう。

### プリロード系プラグインについての私見

マップが切り替わるたびに素材のダウンロードで待たされる問題への対策として、素材をゲーム起動時にプリロードするプラグイン（いろいろあります）を利用する作者さんが（ Twitter を見ている限り）多いようですが、この方式は個人的にはあまりおすすめできません。

その理由は、素材を最初に大量にダウンロードすることにより、メモリ使用量がドカッと増え、スマートフォンで動作が非常に不安定になる（落ちやすくなる）ことです。

この理由から、 **ブラウザゲーム版で提供する場合、かつスマートフォン版ユーザーもがっつりターゲットにしたい場合は、プリロード系プラグインの導入は悪手であると言えるでしょう。**

## まとめ

* ダウンロード版を提供することで、重さはある程度解消されるでしょう。
  * ただし、「ダウンロードが億劫なユーザーには遊んでもらえなくなる」、「ユーザーに、ブラウザの URL バーから URL をコピーして SNS 等で紹介してもらうことができなくなる」等のデメリットがあることに注意
  * **逆に言うと、ブラウザゲーム版は「ダウンロードが億劫なユーザーにも遊んでもらえる」「ユーザーが手軽に SNS で紹介できる」メリットがあることから、１人でも多くのユーザーに遊んでもらいたい場合は、多少の重さを許容してでもブラウザゲーム版に重きを置くのが得策と言えるでしょう。**
    * もちろん、両方を提供するという手もあると思います。
* プリロードプラグインを使うのはスマートフォンの動作が不安定になるのでおすすめしません。
* **描画を早くするために、RPG ツクール MV v1.3.0 対応は必ず行いましょう。**
PlayでWebサーバーを作るときのメモまとめ


（※随時更新予定です。）

## 概要

仕事、趣味でPlay framework（Scala）を触ってきているので、「playでコレどうやるんだっけ？」というのをまとめて共有しようと思います。

## Environment

- Play2.5.x
- Scala2.11.ｘ
- （フロントはReactを使う）

## Contents

TBD

- [Play2で非同期Actionを試す](http://qiita.com/uryyyyyyy/items/a26c081d8907b70cd6e3)
- [Play2のGuice DIを使う＆テストも書く](http://qiita.com/uryyyyyyy/items/969acafb3b9b2f11bb60)
- [Play2のstackable-controllerを使ってみる](http://qiita.com/uryyyyyyy/items/5fa520cd38574284f8c5)
- [Play2-authを使ってみる - 認証/Authentication編](http://qiita.com/uryyyyyyy/items/37788ff980268558c1cc)
- [Play2-authを使ってみる - 認可/Authorization編](http://qiita.com/uryyyyyyy/items/9216ebead22495670a92)
- play-jsonでjsonを扱う
- play-wsでhttpClientを作る
- [Play2でのSPAコンテンツの配信の仕方](http://qiita.com/uryyyyyyy/items/0719dc4b25512b3d3e5f)
- [Play2で認証機能ありのSPAを扱う](http://qiita.com/uryyyyyyy/items/56acf16ef1d29aaf1bec)
- SPAでCSRF対策
- OAuthで認証・認可をする
- urlのパラメータを取得する
- ファイルのDownload/upload
- chunk get/post
- Routing
- distでzipに固める時の作法
- [swagger-playでAPIドキュメントを自動生成する](http://qiita.com/uryyyyyyy/items/192c06d561cf441ba2b0)
EMRでのSparkに割り当てられるメモリ・コアの上限メモ


随時変わる可能性があります。（僕自身も検証中です）

試した環境
EMR5.0
Spark2.0



### m4.large

- core
  - 物理core: 2
  - executor-core: 4
- memory
  - 物理memory: 8g
  - executor-memory: 5g

### m4.xlarge

- core
  - 物理core: 4
  - executor-core: 8
- memory
  - 物理memory: 16g
  - executor-memory: 10g

### r3.xlarge

- core
  - 物理core: 4
  - executor-core: 8
- memory
  - 物理memory: 30.5g
  - executor-memory: 20g

### r3.4xlarge

- core
  - 物理core: 16
  - executor-core: 16
- memory
  - 物理memory: 122g
  - executor-memory: 70g

### c4.2xlarge

- core
  - 物理core: 8
  - executor-core:8
- memory
  - 物理memory: 15g
  - executor-memory: 9g
EC-CUBE3でログ出力したいならMonologを使うと良い

2016/8/12現在最新のEC-CUBE3.0.10には[Monolog](https://github.com/Seldaek/monolog)がデフォルトで使える。
デバッグなどの際、[dumpを使う](http://ec-cube.github.io/tips.html#link5)ことで画面上に出力することもできるのだけど、ログ出力したい場合にはMonologを使うと良い。

# 簡単な使用例
```php
use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$log = new Logger('LogName');
$log->pushHandler(new StreamHandler('../app/log/foobar.log', Logger::DEBUG));

$log->debug('Foo');    // --- (1)
$log->info('Bar');     // --- (2)
$log->warning('Hoge'); // --- (3)
$log->error('Huga');   // --- (4)
```

# ざっくりと解説
StreamHandlerコンストラクタの第一引数にはログファイルのパス、第二引数には出力するログレベルを与える。
上記の使用例では、`app/log/`に`foobar.log`というログファイルを出力する形になり、ログレベルが`DEBUG`なので(1)〜(4)すべてのメッセージが出力される。

仮に、ログレベルに`WARNING`を指定すると、(1)および(2)は出力されず、(3)と(4)のみが出力されるようになる。
Rx の SelectMany について勘違いしていた

Rxは便利すぎるのですが、まだ不慣れな私です。
ReactivePropertyを用いてMVVMパターンを組み立てていたところ、以下のようなシーンに遭遇しました。
以下、単純化したサンプルです。

```example.cs
using System;
using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using Prism.Mvvm;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;

namespace ConsoleExample
{
    class Model1 : BindableBase
    {
        private int _number = 0;
        public int Number
        {
            get { return _number; }
            set { SetProperty(ref _number, value); }
        }
    }

    class Model2 : BindableBase
    {
        private Model1 _model1 = null;
        public Model1 Model1
        {
            get { return _model1; }
            set { SetProperty(ref _model1, value); }
        }
    }

    class ViewModel
    {
        public Model2 Model2 { get; }
        public ReactiveProperty<int> Number { get; }

        public ViewModel()
        {
            Model2 = new Model2();
            Number = Model2
                .ToReactivePropertyAsSynchronized(m2 => m2.Model1)
                .Where(m1 => m1 != null)
                // ここのSelectMany
                .SelectMany(m1 => m1.ToReactivePropertyAsSynchronized(x => x.Number))
                .ToReactiveProperty(0);
        }
    }

    class View
    {
        private ViewModel _viewModel;

        public View(ViewModel viewModel)
        {
            _viewModel = viewModel;
            _viewModel.Number.Subscribe(x => Console.WriteLine(x));
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var viewModel = new ViewModel();
            var view = new View(viewModel);
            
            var model1_1 = new Model1();
            var model1_2 = new Model1();
            Observable.Timer(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1)).Subscribe(x => model1_1.Number = (int)x);
            Observable.Timer(TimeSpan.FromSeconds(0), TimeSpan.FromSeconds(1)).Subscribe(x => model1_2.Number = (int)(x * 10));
            viewModel.Model2.Model1 = model1_1; // 1, 2, 3...
            Thread.Sleep(5500); // 5.5秒待つ
            viewModel.Model2.Model1 = model1_2; // 10, 20, 30...

            Console.ReadLine();
        }
    }
}
```

出力は以下のようになります。

```
0
1
2
3
4
5
50
60
6
70
7
80
8
90
9
100
10
```

このように、model1_1とmodel1_2の内容が混ざり合っています。
私は当初、以下のようにmodel1_1からmodel1_2へ切り替わると思っていました。

```
0
1
2
3
4
5
50
60
70
80
90
100
```

しかし、そうはなっていません。
SelectManyは、以下の処理と同じだったのです。

```example.cs
Select(m1 => m1.ToReactivePropertyAsSynchronized(x => x.Number)).Merge()
// ↑SelectMany(m1 => m1.ToReactivePropertyAsSynchronized(x => x.Number))と同じ結果
```

model1_1とmodel1_2が混ざり合わずに切り替わるようにするためには、以下のようにします。

```example.cs
Select(m1 => m1.ToReactivePropertyAsSynchronized(x => x.Number)).Switch()
```
curl: (7) Failed to connectではまった話

#curl: (7) Failed to connectでハマッタ話

curl: (7) Failed to connect ~~~~~~~ No Route to host とか怒られました。
結論から言うと、proxyで参照しているipとDockerでブリッジしているipが競合していたからでした。
１時間程度ハマッてしまったので、同様の現象が起こってしまった人のためにメモを残しておきます。


### 現状把握
---
`ping www.google.com`
pingコマンドでは、正常どおり動いていることを確認。  

`curl www.google.com`
curlコマンドでは、curl: (7) Failed to connnect　'設定しているproxy'になることを確認。
私の場合、指定したproxyで接続できないことがわかる。  
そこで、自分の指定したproxyのIPアドレス以外に競合するIPアドレスがないか疑い、原因を特定することにしました。

### 何が原因か特定する
---
 1. `ifconfig`または`ip addr`を行い、現状のIP使用状況を確認  
`inet addr:`と記載されている部分を確認し、現状使用しているIPの状況を見る。  
 2. `nslookup '設定しているproxy'`を行い、IPアドレスを調べます。  
ビンゴ！今回はDockerでブリッジした時のIPアドレスとダブっているので、競合しているようです。  
（ちなみに`route`で見るのも当然OK）

一応、確認は大切です。競合していたIPアドレスにアクセスできるかどうか、確認します。
`ping '競合しているIP'`　　
繋がりません。IPアドレスの競合によりアクセスできないことが分かります。

### 解決策に向けて
---
DockerでブリッジしているIPアドレスを変更します。<Font color="red">（ここにトラップあり）</Font>

とりあえず、本当にdocker側のIPがダブっているか確認します。
`docker network ls`で使用一覧をみる。
`docker network inspect templates_default`でデフォルトのテンプレをみる。
こいつが競合しているようなので、`docker network rm templates_default`で削除する。
動作確認。`curl www.google.com`。動いた良かった・・・

めでたし。めでたし？

トラップカード発動！！
新しく、dockerでcretaeすると同様の現象が起きます。
やってみましょう.
`docker network create sample`で作成
`docker network inspect sample`でIPアドレスをみる。
IPダブってる。ふざけ・・・ん。

では、このトラップを華麗に解決しましょう。

とりあえず、作成してしまったゴミ（sample）をデリートしましょう。  
`docker network rm sample`  

そして、使用しない用という意味で'unused'を作りましょう。
`docker network create unused`
`docker network inspect unused`

`docker network create sample`
`docker network inspect sample`するとIPアドレスがずれている.  
どうやらDockerでcreateする度にIPアドレスがずれていく仕様なのかな？
まぁ、メデタシ。  (いらないから、忘れずに`docker network rm sample`しておきましょう)


最後の仕上げとして、もともとDockerでブリッジしていたヤーツの使用しているipをデリート。
`sudo ip l del ブリッジ名`　　
`curl www.google.com`
繋がる.
そして、平和が訪れた。
obj['propname']とobj.propname

JavaScriptのオブジェクトのプロパティにアクセスするには`.`を使う式と`[]`を使う方法があるわけですが、プロパティ名に`.`を含む場合にそれぞれの式によって取得・設定される値が異なります。

```js
var a = {
  aa: {
    aaa: 3,
    aaaa: 4,
    aaaaa: 5
  }
};

console.log(a.aa.aaaa); // -> 4
console.log(a['aa.aaaa']); // -> undefined

a['aa.aaaa'] = 'Four A';

console.log(a.aa.aaaa);    // -> 4
console.log(a['aa.aaaa']); // -> 'Four A'
```

`a.aa.aaaa`という式では「a の aa の aaaa」というプロパティを表します。対して`a['aa.aaaa']`という式では「a の aa.aaaa」というプロパティを表します。

考えてみたら当たり前なんですけどね。
VagrantとCoreOSでkubernetesをMacで使ってみる　①環境構築編

####今回使用した環境は下記の通りです
- OSX El Capitan ver.10.11.6

####必要なもの
- curl
- git
- Homebrew-cask
- Vagrant
- VirtualBox
- CoreOS
- Kubernetes

#Vagrantの導入
Vagrantは仮想マシンの構築と共有をコマンドや定義ファイルを使って簡単に行うことができるツールで、VirtualBox、VMWare上に仮想マシンを複数同時に構築し、必要な設定をすべて行った上で起動できたりします。

①VagrantはHomebrew-caskを使ったインストールがオススメです。

Homebrew-caskを導入してない場合は先に導入します。

```bash
$ brew install caskroom/cask/brew-cask
```

②Vagrantをインストールします。

```bash
$ brew cask search vagrant
==> Exact match
vagrant
$ brew cask install vagrant
```

※serchでvagrantが出ることを確認できない場合は[Download Vagrant - Vagrant](https://www.vagrantup.com/downloads.html)からダウンロードしてインストールしてください。

③VirtualBoxをインストールしていない場合は、この段階でインストールをします。

```bash
$ brew cask install virtualbox
```

※VirtualBoxをインストールされている方は最新版にアップデートしてください。

#CoreOSでクラスタ構築
今回は手元に必要最低限のクラスタを簡単に構築するためにメンテナンスがよくされている[Multi-node cluster using cloud-config and Vagrant](https://github.com/pires/kubernetes-vagrant-coreos-cluster)を使います。

①リポジトリをクローンしてmasterを１台、nodeを２台構築します。

```bash
$ git clone git://github.com/pires/kubernetes-vagrant-coreos-cluster.git
$ cd kubernetes-vagrant-coreos-cluster
$ vagrant up master node-01 node-02
```

※途中で管理ユーザーのパスワードを求められる場合があります。

②きちんと仮想マシンが構築されて起動されているか確認をします。

```bash
$ vagrant global-status
id       name    provider   state   directory
----------------------------------------------------------------------------------
91a29ff  master  virtualbox running /Users/user/kubernetes-vagrant-coreos-cluster
0c1207e  node-01 virtualbox running /Users/user/kubernetes-vagrant-coreos-cluster 
0cd28e4  node-02 virtualbox running /Users/user/kubernetes-vagrant-coreos-cluster 
```

３つのマシンが全てrunningになっていることを確認してください。
確認できたら```Vagrant　ssh-config```の設定をしておくと楽なので、設定しちゃいましょう。

```bash
$ vagrant ssh-config >> ~/.ssh/config
```

#####ここまで出来たら、```$ cd ~/```で1度ユーザーのルートディレクトリに戻ります。

#kubernetesを準備
①kubernetesを操作するためのCLIである、kubectlをインストールします。

```bash
$ curl -k -o kubectl https://kuar.io/darwin/kubectl && chmod +x kubectl && sudo mv kubectl /usr/local/bin/
```

②kubernetesをGitからMacに持ってきます。

```bash
$ git clone git://github.com/GoogleCloudPlatform/kubernetes.git
```

③最後にnodeの確認をしてみます。

```bash
$ kubectl get nodes
Name           STATUS    AGE
172.17.8.102   Ready     1d
172.17.8.103   Ready     1d
```

#####２つのnodeの確認とSTATUSがReadyになっっていることを確認できたら、環境構築は完了です。お疲れさまでした！

**[サンプル実行編はこちら](http://qiita.com/Clip-glass/items/61077a66693c8daa0bdd)**
「オフラインリアルタイムどう書く第1回(Tick-Tack-Toe)」の問題を解いてみた


[横浜へなちょこプログラミング勉強会](https://yhpg.doorkeeper.jp/)にて過去に出題された[Tick-Tack-Toe](http://nabetani.sakura.ne.jp/hena/1/)を解いてみた。
回答にかかった時間はおよそ30分前後。

ボードを2次元配列にしたが、実装し終えてから文字列にしたほうがやりやすかったのではないかと感じた。
ボードの広さを`Board`のインスタンス作成時に指定するようにしているため五目並べだろうが十目並べだろうがやれるようになっているが、明らかに無駄である。
設問では三目並べとなっているのだから素直に9マスのボードのみ考えておけばいいものの、今回はほとんど影響がないとは言え明らかにタイムロスとなり得る箇所である。

```ruby
class Board
  class Foul < StandardError; end

  attr_reader :width
  def initialize width
    @width = width
    @board = @width.times.map{Array.new(@width)}
  end

  def set player, x, y
    if @board[y][x].nil?
      @board[y][x] = player
    else
      raise Foul
    end
  end

  def check player
    all_player = -> (n) {n === player}
    case1 = @board.select{|line| line.all? &all_player}.size > 0
    case2 = @width.times.select{|x| @width.times.map{|y| @board[y][x]}.all? &all_player}.size > 0
    case3 = @width.times.map{|w| @board[w][w]}.all?(&all_player) || @width.times.map{|w| @board[w][@width - w - 1]}.all?(&all_player)
    case1 or case2 or case3
  end
end

class Game
  def initialize width
    @board = Board.new width
  end

  def start input
    [@board.width**2, input.length].min.times do |n|
      player = (n % 2 === 0) ? "o" : "x"
      coordinate = point_to_coordinate input[n].to_i
      begin
        @board.set player, *coordinate
      rescue Board::Foul => e
        target = (n % 2 === 0) ? "x" : "o"
        return "Foul : #{target} won."
      end

      if @board.check player
        return "#{player} won."
      end
    end
    "Draw game."
  end

  def point_to_coordinate point
    x = (point - 1) % @board.width
    y = (point - 1) / @board.width
    [x, y]
  end
end

require 'minitest/autorun'
describe 'Tick-Tack-Toe' do
  [
    ["79538246", "x won."],
    ["35497162193", "x won."],
    ["61978543", "x won."],
    ["254961323121", "x won."],
    ["6134278187", "x won."],
    ["4319581", "Foul : x won."],
    ["9625663381", "Foul : x won."],
    ["7975662", "Foul : x won."],
    ["2368799597", "Foul : x won."],
    ["18652368566", "Foul : x won."],
    ["965715", "o won."],
    ["38745796", "o won."],
    ["371929", "o won."],
    ["758698769", "o won."],
    ["42683953", "o won."],
    ["618843927", "Foul : o won."],
    ["36535224", "Foul : o won."],
    ["882973", "Foul : o won."],
    ["653675681", "Foul : o won."],
    ["9729934662", "Foul : o won."],
    ["972651483927", "Draw game."],
    ["5439126787", "Draw game."],
    ["142583697", "Draw game."],
    ["42198637563", "Draw game."],
    ["657391482", "Draw game."]
  ].each do |test|
    input, expect = test
    it input do
      game = Game.new 3
      assert_equal game.start(input), expect
    end
  end
end
```
PHPにPECLでSolr extentionを導入する

# 概要

`Apache Solr`をPHPから操作するSolr Extensionを導入します。
`Apache Solr`自体の導入は解説しません。
Solr Extensionの使い方も解説しません。[^1]

# 環境

* CentOS7 64bit 
* PHP5.4

# 必要ライブラリの`yum install`

通常は`pecl install`のときにエラーとしてインストールを促されます。
不要なものをインストールしたくない方は`pecl install`を先に試して、エラーメッセージの指示に従うのもOKです。

`yum install libcurl-devel`
`yum install libxml2-devel`

ない場合は`libcurl`を再インストールしてね、と言う風に読めるエラーがでますが、インストールするのは`*-devel`です。
ビルドするときに必要なのでしょうが、ぺちぱーの中にはビルドの概念が薄い方もいらっしゃるのではないでしょうか。私のことです。


# Solr Extension インストール

`pecl install solr`
を実行する。
入力はデフォルトのままでよい。

```sh:導入時エラー例
[root@localhost ~]# pecl install solr
WARNING: channel "pecl.php.net" has updated its protocols, use "pecl channel-update pecl.php.net" to update
downloading solr-2.4.0.tgz ...
Starting to download solr-2.4.0.tgz (256,316 bytes)
.....................................................done: 256,316 bytes
64 source files, building
running: phpize
Configuring for:
PHP Api Version:         20100412
Zend Module Api No:      20100525
Zend Extension Api No:   220100525
Enable Solr Debugging (Compiles solr in debug mode) [no] :
libcURL install prefix [/usr] :
libxml2 install prefix [/usr] :
(中略)
configure: error: Please reinstall the libcurl distribution -
        easy.h should be in <curl-dir>/include/curl/
ERROR: `/var/tmp/solr/configure --with-php-config=/usr/bin/php-config --enable-solr-debug=no --with-curl=/usr --with-libxml-dir=/usr' failed
```

# Solr Extension 有効化

インストールしただけではまだ使えず、PHPに読み込ませなくてはいけない。
`php.ini`に書くべきものは、Extensionを探すパス(include Path)と、Extensionファイルの名前だが、Extensionファイルの作成先がすでにパス指定されているので、パスの指定は追加しなくてもよい。

```
[root@localhost ~]# php -i | grep 'extension'
This extension makes use of Bstrlib available at http://bstrlib.sf.net
extension_dir => /usr/lib64/php/modules => /usr/lib64/php/modules
```

```
[root@localhost ~]# ll /usr/lib64/php/modules/solr.so
-rw-r--r-- 1 root root 1302950 Aug  2 17:34 /usr/lib64/php/modules/solr.so

```

ファイル名を記述するだけで良いのだが、`php.ini`に書かずとも、`/etc/php.d/`に書かれたものも読み込まれるので、綺麗にできる。
むしろExtensionは`/etc/php.d/`に書かれているので、Solrもここに書く。

`echo 'extension=solr.so' > /etc/php.d/solr.ini`

これで有効化が完了した

```
[root@localhost ~]# php -i | grep 'Solr'
Solr Support => enabled
```

Apacheなどは再読み込みが必要。
`systemctl restart httpd.service`

[^1]: むしろ誰か解説してくださいお願いします。
Cocos2d-x Androidビルド用のNDKバージョン

cocos2d-x-3.12で、Androidビルド用に、
NDKのバージョンandroid-ndk-r12bを使用した場合、ビルドできませんでした。
そこで、
NDKのバージョンandroid-ndk-r9dに変更したら、ビルドできました。

■
Cocos2d-xのサイト
http://www.cocos2d-x.org/wiki/Cocos2d-x
の
Build Requirementsの項目に、
NDK r9d is required to build Android games
と記載されていました。

■Android NDK r9d
https://dl.google.com/android/ndk/android-ndk-r9d-windows-x86.zip
https://dl.google.com/android/ndk/android-ndk-r9d-windows-x86_64.zip
http://dl.google.com/android/ndk/android-ndk-r9d-darwin-x86_64.tar.bz2
http://dl.google.com/android/ndk/android-ndk-r9d-linux-x86_64.tar.bz2

■
NDKの過去のバージョンのダウンロードurl
http://stackoverflow.com/questions/6849981/where-do-i-find-old-versions-of-android-ndk
TensorFlowのインストールをテスト

https://www.tensorflow.org/versions/r0.10/get_started/os_setup.html#test-the-tensorflow-installation

```
$ python
>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
Hello, TensorFlow!
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42
>>>
```

[TensorFlowを Mac にダウンロードとセットアップ](http://qiita.com/yoshiweb/items/7dd078b3d0934e0429cb)
Mac OS X に TensorFlowをインストール

https://www.tensorflow.org/install/install_mac



## インストールするTensorFlowを決定する

* CPUのみをサポートするTensorFlow
* GPUをサポートするTensorFlow



## TensorFlowのインストール方法を決定する

* virtualenv
> 他のPython開発から隔離された仮想的なPython環境
同じマシン上の他のPythonプログラムを妨げたり、影響を受けたりすることはない。
公式サイトお勧め！

* Native pip
> コンテナや仮想環境システムを経由せずにTensorFlowをシステムに直接インストールします。
ネイティブのpipインストールは壁が切られていないので、pipインストールは、システム上の他のPythonベースのインストールを妨げたり、影響を受ける可能性があります。

* docker
> 完全にあなたのマシン上の既存のパッケージからTensorFlowインストールを隔離します。
Dockerコンテナには、TensorFlowとそのすべての依存関係が含まれています。
※ Dockerは現在、CPUをサポートするTensorFlowのみをサポート

* Anaconda
> 仮想環境を作成するためにcondaを使用できます。
ただし、Anacondaでは、pip install コマンドではなく conda installでTensorFlowをインストールすることをお勧めします。
※ condaパッケージはコミュニティでサポートされており、公式にはサポートされていません。

* ソースからインストール


## virtualenvでインストールする

VirtualenvでTensorFlowをインストールするには、以下の手順を実行します。

1.端末（シェル）を起動します。このシェルでは、後続のすべての手順を実行します。
2.次のコマンドを発行してpipとvirtualenvをインストールします。

```
$ sudo easy_install pip 
$ sudo pip install --upgrade virtualenv
```

3.次の形式のコマンドを発行して、仮想環境を作成します。

```
$ virtualenv --system-site-packages ターゲットディレクトリ
```





4. 次のコマンドのいずれかを発行して、virtualenv環境をアクティブにします。

```
$ source ターゲットディレクトリ/bin/activate      # If using bash, sh, ksh, or zsh
$ source ターゲットディレクトリ/bin/activate.csh  # If using csh or tcsh
```

前述のsourceコマンドは、プロンプトを次のように変更します

```
(tensorflow)$
```

5.システムにpipバージョン8.1以降がインストールされている場合は、次のいずれかのコマンドを実行して、TensorFlowおよびTensorFlowがアクティブなVirtualenv環境に必要とするすべてのパッケージをインストールします。

```
$ pip install --upgrade tensorflow      # for Python 2.7
$ pip3 install --upgrade tensorflow     # for Python 3.n
$ pip install --upgrade tensorflow-gpu  # for Python 2.7 and GPU
$ pip3 install --upgrade tensorflow-gpu # for Python 3.n and GPU
```


### TensorFlowの使用が終了したら、次のコマンドを実行して環境を非アクティブにする

```
(tensorflow)$ deactivate
```


### TensorFlowをアンインストール

```
$ rm -r ターゲットディレクトリ
```
vagrant1.8.5でvagrant upするとエラーになる

## 概要

vagrantでboxを追加し、いざ`vagrant up`しようとすると、下記のようなエラーが出て先に進めません。
その原因と、私の行った対応について備忘録的に書いておきます。

```エラー内容
default: Inserting generated public key within guest...
default: Removing insecure key from the guest if it's present...
default: Key inserted! Disconnecting and reconnecting using new SSH key...
default: Warning: Authentication failure. Retrying...
default: Warning: Authentication failure. Retrying...
...
```

こんな感じで、認証に失敗するというエラーが連続してしまいます。

## 環境

* ホストOS
    * Mac OS X 10.11.3
* vagrant 1.8.5
* VirtualBox 5.1.2

### 原因

vagrant1.8.5のバグらしい。

https://github.com/mitchellh/vagrant/issues/7610


### 対応

私は、VirtualBoxから直接仮想マシンにログインして、`~/.ssh/authorized_keys`のパーミションを変更することで解決しました。

1. VirtualBoxから仮想マシンにログイン(ID/PWは、`vagrant/vagrant`です)
2. `chmod 600 /home/vagrant/.ssh/authorized_keys`
3. 再度、ホストOSから`vagrant up`

他にも良い方法があればご教示頂きたく・・！ :bow:
Qiita > 要望 > 編集履歴 > 変更があったところへのジャンプ機能 / 変更のみの表示機能

Qiita記事の編集履歴を見る時、どの場所が変更されたかはスクロールで探すことになる。

記事が長いもの、かつ編集が多いと、その時の編集履歴でどの部分が編集されるかを探すのに時間がかかる。

SourceTreeやgithubのcommitなどVCSと同じように変更が分かりやすければいいと思う。

- 変更があったところへジャンプする機能
- 変更があったところだけ表示機能

いずれが使い勝手がいいかは使ってみないと分からないが、上記のどちらかがあれば閲覧者の時間節約に貢献する。


## 編集履歴の変更 > 本文の変更

@asahina_dev さん
コメントいただいたので補足します。

「編集履歴」の「本文の変更」が今は以下のように文章全部が記載された中で変更が色付けされている状態です。この表示の場合、変更箇所はスクロールして探さないといけない、というのが記事で伝えたかったことです。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/b38b5c81-fee9-75d2-ec98-761c7526dd30.png)
年代順・主なJava書籍リスト

※網羅的ではありません。またAndroid本は触れてません。良いとか悪いとかの評価もしません。版を重ねている本は最初に出た版しか載せていません。

## 1996年
(それなりの数のJava紹介本が出始める)

## 1997年
* プログラミング言語Java
* Java言語仕様
* Javaプログラムデザイン

## 1998年
* Java Press Vol.1
* Javaとピザとデザインパターン

## 1999年

* Java言語プログラミングレッスン
* JavaServlet最新サーバープログラミング
* 独習Java
* XMLとJavaによるWebアプリケーション開発

## 2000年

* WEB+DB PRESS　Vol.1
* やさしいJava
* Javaスレッドプログラミング―並列オブジェクト指向プログラミングの設計原理

## 2001年

* サーブレット&JSPではじめるJavaサーバサイドプログラミング
* iモードJavaプログラミング - スタンドアロン・アプリケーション編
* Java言語で学ぶデザインパターン入門
* やさしいUML入門―Javaオブジェクト・モデリング
* Enterprise JavaBeans開発ガイド
* Effective Java
* Javaチュートリアル第3版 (The Java series)

## 2002年

* J2EEパターン
* J2EEチュートリアル
* Javaの絵本―Javaが好きになる9つの扉
* Jakartaプロジェクト徹底攻略―WEB+DB PRESS Special Issue


## 2003年

* マスタリングJakarta Struts
* Java+MySQL+Tomcatで始めるサーバーアプリケーション開発入門
* Eclipseパーフェクトマニュアル Vol. 1
* Javaを独習する前に読む本
* JBoss入門　オープンソース Java・EJB
* サーバーサイドJAVAアンチパターン

## 2004年

* Eclipseプラグイン開発
* Head First Java
* JUnitによるテストファースト開発入門
* 軽快なJava―Better,Faster,Lighter Java
* Java魂―プログラミングを極める匠の技
* なぜ、あなたはJavaでオブジェクト指向開発ができないのか―Javaの壁を克服する実践トレーニング

## 2005年

* 開発のプロが教える標準FindBugs完全解説
* エンタープライズ アプリケーションアーキテクチャパターン
* 創るJava―NetBeansでつくって学ぶJava GUI & WEBアプリケーション
* Ant 第2版
* マスタリング Maven
* アスペクト指向入門 -Java ・ オブジェクト指向から AspectJプログラミングへ
* Jakarta Commonsクックブック ―Javaプロジェクト必須のレシピ集
* Javaプログラマガ知ツテオクベキコト
* オブジェクト開発の神髄～UML 2.0を使ったアジャイルモデル駆動開発のすべて
* Light Weight Java―JSF/Hibernate/SpringによるフレームワークでWebアプリケーションの開発効率向上

## 2006年

* Javaのオブジェクト指向がゼッタイにわかる本
* Java並行処理プログラミング ―その「基盤」と「最新API」を究める―
* Apache Lucene 入門 ~Java・オープンソース・全文検索システムの構築
* Head First Java 第2版 ―頭とからだで覚えるJavaの基本

## 2007年

* 明解Java入門編
* スクリプティング with Java
* マスタリングJavaEE5
* 基礎からのJava
* Java言語で学ぶリファクタリング入門

## 2008年

* すっきりわかった!Java (ASCII BOOKS)
* Seasar2によるスーパーアジャイルなWeb開発 (WEB+DB PRESS plusシリーズ)
* Groovyイン・アクション
* コーディングの掟

## 2009年

* Javaスタイルブック
* エンジニアのためのJavadoc再入門講座
* パーフェクトJava
* Scalaスケーラブルプログラミング
* Google App Engine for Java [実践]クラウドシステム構築
* オープンソース徹底活用WicketによるWebアプリケーション開発

## 2010年

* プログラミングClojure
* Javaフレームワーク開発入門
* JavaによるRESTfulシステム構築

## 2011年

* スッキリわかるJava入門
* プログラミングGROOVY
* Jenkins実践入門

## 2012年

* リーダブルコード
* Java逆引きハンドブック
* JUnit実践入門
* Apache Maven 3クックブック

## 2013年

* Seasar2徹底入門
* オープンソース徹底活用Slim3によるWebアプリケーション開発

## 2014年

* Java逆引きレシピ
* APIデザインの極意 Java/NetBeansアーキテクト探究ノート
* はじめてのSpring Boot
* Gradle徹底入門

## 2015年

* Javaプログラマーなら習得しておきたい Java SE 8 実践プログラミング
iTunes経由でiOSのソフトウェア・アップデートに失敗するときに確認するMacの設定(プロキシ)


## はじめに
iTunes で iOS のバージョンアップをしようと思って，なぜか失敗。
仕方ない。バックアップも取っているし，
工場出荷時にいったん戻してまたアップデートするかー
と工場出荷時するのにもひたすら失敗するという場面があった。
文鎮化してしまった・・・エラーコードはひたすら 6。

結論から言うとネットワーク環境だった。
プロキシサーバとか絡ませていたため，
アップデートする際に確認しにいくサーバアドレスに
アクセスできずに失敗していたらしい。
もしどうしてもバージョンのアップデートに失敗する場合は
確認してみる価値はあるかもです。

## Mac のプロキシの設定
エラーコード 6 だけで調べていても有益な情報は得られなかった。
セキュリティ系でダメだというのはわかったので，
少し幅を広げて調べてみたところ，Apple のサポートページ[^1]を見つけた。

>ソフトウェア・アップデート では、アップデートをダウンロードしてインストールするために Apple のアップデートサーバと通信する必要があります。

なるほど。プロキシか。
ということで **プロキシサーバで「ソフトウェア・アップデート」を使う方法** で
試してみました。この方法でうまくいきました。

1.システム環境設定を開いてネットワークを選択
![a.png](https://qiita-image-store.s3.amazonaws.com/0/88266/cf4ccb85-8308-7b6d-6b11-bcb94bb0fb93.png "a.png")


2.アクティブなネットワークインターフェイス (通常は Ethernet または Wi-Fi) を選択
3.「詳細」ボタンをクリック
 
![b.png](https://qiita-image-store.s3.amazonaws.com/0/88266/0b878e38-2d1c-4fc4-7c2a-d68292c896f5.png "b.png")


4.「プロキシ」タブを選択
5.「プロキシ設定を使用しないホストとドメイン」に以下のホストを入力

```
swcdn.apple.com, swdownload.apple.com, swquery.apple.com, swscan.apple.com
```

6.「OK」をクリック
![c.png](https://qiita-image-store.s3.amazonaws.com/0/88266/d2dfbc8f-972b-3746-772f-c3e7872d546c.png "c.png")


7.「適用」をクリック
![d.png](https://qiita-image-store.s3.amazonaws.com/0/88266/7109de07-1e5f-a91d-f270-3e979c50f92a.png "d.png")


これでアップデート出来るか確かめてみてください。
もし，これでもダメなら他の原因を探すか，
ジーニアスバーに持って行ってみてもらうのがいいかと思います。

## おわりに
iTunes で iOS のソフトウェア・アップデートに
どうしても失敗するときの一因かもしれないプロキシの
設定について書きました。
基本的に個人開発だと起きなくて，ネットワークの
アクセス制限がかかっている現場で起きることが多いかと
思われます。
一度設定してしまえば大丈夫な設定ではありますが，
アクセスの例外を作るわけなので接続先は，
Apple といえ少しセキュリティのことに関しては
頭に入れておく必要があるかもしれません。

復旧に時間かけるか，その分コード書くか，
現場のプロジェクトの進み具合で判断すればいいかと思います。
あとバックアップはこまめにやっておいたほうがいいですね。

### 参考
[^1]: [OS X：「ソフトウェア・アップデート」で使用されるサーバアドレス](https://support.apple.com/ja-jp/HT202943)
数秒後に実行 function delayedCall()


jsで数秒後に処理を実行したい時、


```js:hoge.js

setTimeout(function(){
    console.log("2秒後に実行！");
}, 2000);

```

のようにsetTimeoutを使うと思いますが、
ミリ秒が直感てきでないし、0を3つ書くのが
めんどくさいなと思っていたところ、
こんな関数を作ってるコードを発見しました。



```js:hoge.js


delayedCall(2,function(){
    console.log("2秒後に実行！");
});


// 数秒後に実行メソッド
function delayedCall(second, callBack){
  setTimeout(callBack, second * 1000);
}

```


この関数名だと
そんなにタイプ数は変わりませんが、
個人的にお気に入りです！


フレームアニメーションの時とかに使ってます。


```js:hoge.js

$(function(){
    animateTo('intro');
});

// アニメーション管理
function animateTo(frameName) {
  switch (frameName) {
    case 'intro':
      delayedCall(1, function(){
          // なんかアニメ
      });
      animateTo('frame1');
      break;
    case 'frame1':
      delayedCall(1, function(){
          // なんかアニメ
      });
      animateTo('frame2');
      break;
    case 'frame2':
      delayedCall(3, function(){
          // なんかアニメ
      });
      break;
  }
}

// 数秒後に実行メソッド
function delayedCall(second, callBack){
  setTimeout(callBack, second * 1000);
}

```


完

ポケモンGO 楽しい
IDCFでのkusanagi(wordpress)の入れ方

# IDCFでのkusanagi(wordpress)の入れ方

## やりたかったこと

* 大量に読んだ漫画の感想とか書きたいなあ
* サーバー費抑えたい => IDCFの500円サーバ使えばいいや
* ブログサービスは使いたくない => wordpress使ってみるか

## kusanagiとは

WordPressの実行時間3ミリ秒台、秒間1000リクエストをページキャッシュ非使用で実現する世界最高速クラスのWordPress実行環境を作れます（公式引用）

https://kusanagi.tokyo/

## テンプレート選択する

こちら参照してください。
https://kusanagi.tokyo/cloud/kusanagi-for-idcfcloud/

## 初期コマンド

* ログイン

`ssh root@ip_address`

* 初期コマンド

`# kusanagi init`

* Tokyoを選択

```
Search or select timezone:  Tokyo                                                                                                             IgnoreCase [1/1]
Asia/Tokyo
```

* 2を選択

```
Select your using keyboard type.

1 : English
2 : Japanese

q : quit
```

* kusanagiユーザー求められるので適当にいれる

```
ユーザー kusanagi のパスワードを変更。
新しいパスワード:
```

* key generateしてて多分使わないのでエンター２連打

```
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
```

* mysqlのrootパス 8文字以上で入れる

```
Enter MySQL root password. Use [a-zA-Z0-9.!#%+_-] 8 characters minimum.
```

## wordpressの設定

* サービス名を入力

`kusanagi provision service_name`

* 2を選択

```
1 : en_US
2 : ja

q : quit

Which do you choose?: 2
```

* hostnameを入力（nginxで使用）

```
Enter hostname(fqdn) for your website. ex) kusanagi.tokyo
```

* Let's Encrypt使う場合はメールアドレス、やらない場合はエンター２回

```
In order to use Let's Encrypt services, you must agree to Let's Encrypt's Term of Services.
If you agree to this TOS, type your email address; if not, hit enter twice.
TOS of Let's Encrypt : https://letsencrypt.org/repository/
```

* DB名いれてください

```
Enter the name of your database
```

* DBのユーザー名を入れてください

```
Enter user name for database 'database_name'
```

* 前項で作成したユーザーのパスワードを入力してください

```
Enter password for database user 'user_name'. USE [a-zA-Z0-9.!#%+_-] 8 characters minimum.
```

あとは作ったサービスに接続すれば完了です。


# 注意点

## テーマへの書き込みができない場合。

* その他ユーザーの書き込みを許可してあげてください。(service_nameはご自身で設定したものに変えてください)

```
chmod o+w /home/kusanagi/#{service_name}/DocumentRoot/wp-content/themes
```

# おすすめプラグインとテーマ

## テーマ

* STINGER めちゃくちゃ使いやすいです

http://wp-fun.com/

## プラグイン

単なるブログ目的であれば、STINGER入れて、画像サイズも適切なサイズに変換するように設定してあれば、ほぼプラグインいらないきがする。

* SEO対策
  * PubSubHubbub-index - 促進
  * Google XML Sitemaps - XML Sitemap作成
JavaScriptでWrite once, run anywhere


# 愚痴

* <font color="red">車輪の再発明したくない</font>(見飽きた、モチベーションあがんない)
* スマホとかOSのアップデートとかに引っ張られてアプリの保守したくない
* <font color="red">同じビジネスロジック</font>をいろんな環境(プログラミング言語)で書きたくない
* <font color="red">サービスの本質の部分に時間を割きたい</font>
* 極力作りたくない病（保守するものが増える）


# やりたいこと

* パラメータ受け取ってJSONを返す<font color="red">関数（ビジネスロジック）を共通化</font>
* 色々な環境からコールができる、古いコードも動くJavaScriptが良さげ（サーバサイド、フロントエンド、ネイティブコール、デスクトップアプリ化）
* Firebaseぽくローカルとサーバのデータを同期させたい（オフラインでも動く）
* 速度？セキュリティ？~~なにそれおいしいの？~~
* ~~Java？いえ、知らない子ですね~~


# 動かしたい環境

* Rest APIとして提供(NodeJS)
* ブラウザ(Chrome,Mobile Safari,IE)
* スマートフォンネイティブ（iOS,Android）
* デスクトップアプリ(Windows,Mac OSX)


# 実現方法

* ビジネスロジックはNodeJSのモジュールとして記述し、Browserifyでブラウザモジュール化
* iOS、AndroidはWebView経由でJavaScript関数コール
* ストレージは[localStorageDB](https://github.com/knadh/localStorageDB)でローカル保存、サーバ同期
* [Electron](http://electron.atom.io/)でデスクトップアプリ化


# イメージ

![スクリーンショット 2016-08-08 16.59.54.png](https://qiita-image-store.s3.amazonaws.com/0/55077/c7206f71-3c2c-ccba-e89b-e9d7b40a77be.png)


# Why localStorageDB?

* SQLiteとかだとそれぞれの環境でDB呼び出しの実装が必要（~~めんどいというか本末転倒~~）
* localStorageだと[守備範囲広い](http://caniuse.com/#search=localStorage)
* 単純なlocalStorageだとKVSなので検索とかしたいし
* 少し工夫したらNodeJSでも使えたのでブラウザ間とのデータ同期に使えそう
* ブラウザにもよるけどlocalStorageの上限5MBほどらしいのでイメージとかバイナリ保存には向いてない


# やってみた
サンプルソースおいてます。
GitHub:https://github.com/teradonburi/bridge

配布物

* NodeJSサンプル（Rest API）
* ブラウザサンプル
* iOS、Androidサンプル（WebView経由で呼び出し）
* PCアプリサンプル(Electron)


# gulpで自動化

コード修正したら面倒くさい作業はgulpで自動化

* NodeJSサーバ再起動(execSync)
* ブラウザ再読み込み(gulp-webserver)
* 単体テスト(jasmine-node)
* コードレビュー(grunt-plato)
* APIドキュメント作成(gulp-yuidoc)
* ブラウザコード化(Browserify)
* PCアプリ生成(electron-packager)


# データ同期の仕組み

* ページ表示にサーバからデータ同期（全ユーザデータ読み取り）
* オンライン状態はローカルデータ書き込み時にサーバに自ユーザデータを同期
* オフライン→オンライン時にサーバとデータ同期
* 他ユーザデータが更新されたらWebSocketでプッシュ受信でローカルデータ更新
* 自ローカルで他ユーザ更新はやらない（同期時にデータ整合性取れなくなるので）


# 本当にWrite Once?

* WebViewからの呼び出し部分はOS依存（iOS、Android）
* Electronのバージョンアップに依存

修正範囲は狭くなるけど、OSのバージョンアップされたら保証は無理ぽ


# 課題

* HTMLをローカルファイルにして提供するとクロスドメインの問題が・・・（サーバ側でCORS許可するか~~ローカルファイルやめてHTMLページをサーバ提供に？~~）
* 別のPCアプリからElectronアプリのAPIコール（プロセス間通信）したい場合、どうすりゃいいの？・・・（~~いっそElectronのメインプロセス側にNodeJSのHTTPサーバを立てる？~~）
* GUIコンポーネントもライブラリ化したい
「server gave HTTP response to HTTPS client」と言われてDocker Private registoryのpushやpullができなかったときの対処

＠CentOS7

1. /etc/docker/daemon.json に下記を追記（もしくは新規作成）
<pre>
{ "insecure-registries":["myregistry.example.com:5000"] }
</pre>
1. dockerを再起動
<pre>
systemctl restart docker
</pre>

* https://github.com/docker/distribution/issues/1874
c++ builder XE4, 10.2 Tokyo > Hint > hintが消える時間を変更する > Application->HintHidePause = 3000; // msec

```txt:動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2017/12/27)
```

TEditなどでShowHintを使う時、Hintが長いとHintを読みきる前に表示が消えてしまう。

Hintが消えるまでの時間を変更できるようだ。
http://www.festra.com/eng/tip-hints.htm

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{

	Application->HintHidePause = 3000; // msec

	Edit1->Hint = L"This hint will disappear in 3 seconds";
	Edit1->ShowHint = true;

}
//---------------------------------------------------------------------------
```

Hintが表示されるまでの時間はリンク先に記載されていて、Application->HintPauseで設定するようだ。

HintHidePauseのデフォルト値は2500msec。
http://docs.embarcadero.com/products/rad_studio/radstudio2007/RS2007_helpupdates/HUpdate4/JA/html/delphivclwin32/Forms_TApplication_HintHidePause.html

長い文字列をHintで表示するのは良いUIかというと良くない気がする。
別途、消えないコンポーネントで見せる方がいいかもしれない。
ElasticMQのDockerイメージまとめ

## pakohan/elasticmq

[DockerHub: pakohan/elasticmq](https://hub.docker.com/r/pakohan/elasticmq/)

* だいぶ古い公式のoracle-java6イメージベース(dockerfile/java:oracle-java6)
* ElasticMQバージョン0.8.5
* GitHubなし

## medibank/docker-elasticmq

[DockerHub: medibank/docker-elasticmq](https://hub.docker.com/r/medibank/docker-elasticmq/)

* pakohan/elasticmqのフォーク
* Bitbucketのプライベートレポジトリなので詳細不明

## behance/elasticmq-docker

[GitHub: iJJi/docker-dynamodb-local](https://github.com/behance/elasticmq-docker)
[DockerHub: behance/elasticmq-docker](https://registry.hub.docker.com/u/behance/elasticmq-docker)

* Ubuntu 14.04(Trusty)ベース
* ElasticMQバージョン0.8.0
* rootユーザで実行
* エントリポイントがシェルスクリプト=[正しいinit process](http://qiita.com/mumoshu/items/064cd93ce116d8e04169)なし
* CIなし
* カスタム設定ファイル非対応

## edappy/elsaticmq-docker

[GitHub: edappy/elsaticmq-docker](https://github.com/edappy/elasticmq-docker) 
[DockerHub: edappy/elsaticmq-docker](https://hub.docker.com/r/edappy/elasticmq-docker/)

* behance/elasticmq-dockerベース
* ElasticMQ 0.9.0-beta1
* CIなし
* **カスタム設定ファイル対応**

## mumoshu/elasticmq-docker

手前味噌ながら。

[GitHub: mumoshu/elasticmq-docker](https://github.com/mumoshu/elasticmq-docker)
[DockerHub: mumoshu/elasticmq-docker](https://registry.hub.docker.com/u/mumoshu/elasticmq-docker)

* **Alpine Linuxベース**
* **ElasticMQバージョン0.9.3, 0.8.12, 0.7.1**
* rootユーザで実行
* エントリポイントがシェルスクリプト=[正しいinit process](http://qiita.com/mumoshu/items/064cd93ce116d8e04169)なし
* **CIあり(Travis)**
PythonからGoogleDriveのファイルのcopyを作成する


はじめに
========

所々の事情により、GoogleDrive上のファイルを自動的に複製する必要が出てきたので、その方法を調べたメモです。

Version
---------

* Python 3.5.x
* google-api-python-client==1.5.1
* oauth2client==3.0.0
* httplib2==0.9.2

方法
======

準備: Google Drive API の有効化
--------
http://wwld.jp/2015/11/07/spreadsheet-api.html
で紹介されている通り、Drive APIを有効化する必要がありますので有効化します。

準備: 認証用JSONの取得
---------
Google Drive APIを使うので、認証情報が必要です。
認証情報の取得方法は、時期によって少しずつ変わっているようですが、
前述のサイト http://wwld.jp/2015/11/07/spreadsheet-api.html のような方法で概ね大丈夫だと思います。

サンプルコード
-----------

```python
SECRET_JSON = '<PATH_TO_SECRET_JSON>'
FILE_ID = '<FILE ID on Google Drive>'

# ---- get credentials

from oauth2client.service_account import ServiceAccountCredentials

scope = ['https://spreadsheets.google.com/feeds', 
         'https://www.googleapis.com/auth/drive']
credentials = ServiceAccountCredentials.from_json_keyfile_name(SECRET_JSON, scope)


# ---- create Google Drive Service

from apiclient.discovery import build
import httplib2

http = httplib2.Http()
http = credentials.authorize(http)
service = build('drive', 'v3', http=http)

# ---- Copy the file on Google Drive

new_file_body = {
    'name': 'new_data',  # 新しいファイルのファイル名. 省略も可能
    'parents': ['0Bxxxx-abcdefghijklmnopqrstu'],  # Copy先のFolder ID. 省略も可能
}

# ref: https://developers.google.com/resources/api-libraries/documentation/drive/v3/python/latest/drive_v3.files.html#copy

new_file = service.files().copy(
    fileId=FILE_ID, body=new_file_body
).execute()
print(new_file)
```

出力例

```python
{
  'kind': 'drive#file', 
  'mimeType': 'application/vnd.google-apps.spreadsheet', 
  'name': 'new_data', 
  'id': '1zzzzzzzzzzz-xxxxxxxxxxxxxx-xxxxxxxxx'
}
```

さいごに
=========

できると信じているし、できてしまえば簡単なんですが、方法を探すのに苦労しますね。。
Concourseのタスク内でDocker Composeを利用する方法

方法は二通りあります。

1. ConcourseのコンテナからアクセスできるところにDockerホストかDocker Swarmクラスタを用意 + タスクを実行するコンテナのDockerイメージにdocker-composeをインストールしておく + タスク実行時に外部のDockerへの接続設定をする
2. タスクを実行するコンテナのDockerイメージにDockerとDocker Composeをインストールしておき、コンテナ内でDocker DaemonとDocker Composeを両方起動する

2については以下に詳細を書きました。

https://github.com/concourse/concourse/issues/324#issuecomment-238395202

ひとことでいうと、Docker-in-Docker（dind)と相性のよいbtrfsを使うようになったConcourse 1.3以上で[mumoshu/dcind](https://github.com/mumoshu/dcind)を使えばOKです。
LPICメモ


# クオータ

|コマンド|意味|
|---|---|
|repquota -g|状況を表示|


# ファイルシステム

||XFS|ext3||
|---|---|---|---|---|
|概要|SGIが開発|||
|作成|mkfs.xfs|mke2fs -j<br>mke2fs -t ext3<br>mkfs -t ext3|
|チェック|xfs_check|
|情報|xfs_info|

# コマンド

|||
|---|---|
|shutdownの時刻指定|HH:MM<br>+M<br>now|

# カーネル

バージョン違い

||USB|
|---|---
|2.4|USB1.1|
|2.6|USB2.0

# proc

SCSIデバイスの情報は/proc/scsi/scsi

# init

||init|systemd|
|---|---|---
|ランレベル確認|runlevel||
|ランレベル変更|init<br>telinit|systemctl start|
|再起動||systemctl reboot|

# systemd

systemdはSyVinitを置き換える新しいinit
デフォルトのUnitは/etc/systemd/system/default.target
Unitの種類 device mount service swap target
init,Upstart,systemdの順番で登場

### サブコマンド

systemctlのサブコマンド

||コマンド|
|---|---|
||default|
|Unit定義一覧|list-unit-files|
|電源off|halt<br>poweroff|
||get-default|
||is-active|
|サービスの設定ファイルの再読み込み|reload|
|システム再起動|reboot|

### ランレベルの対応

|SyVinit|systemd|
|---|---|
|0|poweroff|
|1|rescue|
|2,3,4|multi-user|
|5|graphical.target|
|6|reboot.target|


# パッケージ関連

||Debian系|RedHat系|
|---|---|---|
|パッケージ一覧||rpm -qa<br>rpm -q --all|
|パッケージ名の検索||yum search
|全パッケージのアップデート||yum update
|ファイル一覧|dpkg -L<br>dpkg --listfiles|
|新バージョンがインストールされていればインストールしない|dpkg -G|
|アップデートの確認||yum check-update
|パッケージ情報|apt-cache showpkg|
|アンインストール||rpm -e<br>rpm --erase|
|インストール有無の照会||rpm -q<br>rpm --query<br>yum list
|中断パッケージの表示|dpkg -C<br>dpkg --audit|
|インストール等|apt-get|yum|
|パッケージファイルの操作|dpkg|rpm|
|パッケージのダウンロード||yumdownloader|
|設定ファイル||/etc/yum.conf<br>/etc/yum/repos.d|
|進行状況||yum -h<br>yum --hash
|テスト||yum -t<br>yum --test
|インストール|dpkg -i<br>dpkg --install|rpm -i<br>rpm --install
|詳細表示|dpkg -s<br>dpkg --status|yum info

# パーティション関連

||分割|
|---|---|
|/var|可|
|/tmp|可|
|/usr|可|
|/home|可|

# GRUB関連

||GRUB Legacy|GRUB2|
|---|---|---|
|バージョン|0.9系|1.9系
|ルートパーティション指定方法|(hd0,0)から|(hd0,1)から
|設定ファイル||/boot/grub/grub.cfg<br>/etc/default/grub<br>/etc/grub.d/
UWSCを始める時の参考情報

#目的
自分がUWSCを使用したスクリプトを作成するに当たって参考にした情報のリンクを記載します。
今後、UWSCを開始する人の参考になればいいです。

##公式サイト
[UWSC](http://www.uwsc.info/)
- UWSCのダウンロードはここから
[公式サンプル](http://www.uwsc.info/sample.html)
- 公式サイト記載のサンプル集
[FAQ](http://www.uwsc.info/faq.html)
- FAQ集
##その他サイト
[UWSC Tech](http://uwsc.dohow.jp/blog/)
- 逆引き関数リファレンス的なサイト。
[UWSC コバヤシ式](http://canal22.org/)
- 「Windows マクロテクニック」の著者のページ。簡易リファレンスとサンプルなど。
[UWSCスクリプト製作所](http://uwscscript.blog.fc2.com/)
- 自作のサンプルなどをブログで公開中
[UWSCの落し物部屋](http://wayback.archive.org/web/20150603074601/http://siromasa.digi2.jp/uwsc/)
- サンプルをカテゴリ別に多数公開。現在ページは閉鎖されているようで、上記リンクはInternetArchiveより。
[かゆいところに手が届くUWSCスクリプト](http://e-dcz.com/~uwsc/index.htm)
- スニペットを数点記載。
[UWSC サンプルメモ](http://uwscpro.blog98.fc2.com/)
- UWSCユーザーのブログ。
[UWSCの誘惑](http://nem.symphonic-net.com/uwsct/0610uwsct.html)
- 応用例を豊富に紹介。
##参考書
[Windows マクロテクニック](https://www.amazon.co.jp/Windows-%E3%83%9E%E3%82%AF%E3%83%AD%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-%E5%B0%8F%E6%9E%97-%E3%82%B7%E3%83%B3%E3%83%A4/dp/4798110434) 小林シンヤ(著）翔泳社
Vagrant の起動に失敗しつつ、SSH auth method: private key で止まる、VT-x にはまる。Windows10ってハマル。

# Vagrantを最新化とかとかしてみる
Docker Toolが最新化されたとかで普段使いのVagrantも同時にバージョンアップしてみた。そしてBIOSまで更新するとかあり…まあオチがいつもの遠回りな感じでした。

[Vagrant](https://www.vagrantup.com/) (1.8.5) + [VirtualBox](https://www.virtualbox.org/) (5.0.24 r108355) + [Dokcer Toolbox](https://www.docker.com/products/docker-toolbox) (1.12.0)

# 結論として、Vagrant と Docker Toolbox は
共存することができません！！
Vagrant (VT-x) と Docker Toolbox(Hyper-V, Windows10 + 64bit) は共存し使用することができないのです。

以上！

# と、まあハマッタ点をメモしておきます
Hyper-V が有効になっているときVagrant を起動すると ``SSH auth method: private key`` でなにやら止まってしまい立ち上がりません。しかもフリーズしているような感じ。訳がわからないので ``gui = true`` で立ち上げたところ。

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/96dfeb0c-a25c-ce46-2807-e39c89919683.png)

あれ？BIOSの設定が悪いのかと見直してみるも問題ないやん。

```
Intel(R) Virtualization Technology: Enabled
Intel(R) VT-d Feature: Enabled
```

でも、[VirtualChecker](http://forest.watch.impress.co.jp/library/software/virtualcheck/) をみると。

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/123cc9ef-9786-b833-6ad1-c5e9ec7e6697.png)

判らず。CPUは Corei7 そんなそんなとウロウロしてました。そして [VT-x を有効にしたく て 3 日程できなかったのだが、Windows が余計なお世話をしてた件](http://picworld.e-monster.jp/2016/03/28/vt-x-%E3%82%92%E6%9C%89%E5%8A%B9%E3%81%AB%E3%81%97%E3%81%9F%E3%81%8F-%E3%81%A6-3-%E6%97%A5%E7%A8%8B%E3%81%A7%E3%81%8D%E3%81%AA%E3%81%8B%E3%81%A3%E3%81%9F%E3%81%AE%E3%81%A0%E3%81%8C%E3%80%81windows/) をみて解決しました。どうやらWindows10が、このやろう！ってことでした。

↓↓↓　Hyper-V のチェックを外すと VT-x が有効化になります。

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/cf24ab5d-427f-cca2-1165-49d1f8eec6fc.png)

# このメッセージをちゃんと読むべきでした
![image](https://qiita-image-store.s3.amazonaws.com/0/44540/2c44ed19-92f1-d68d-2c70-f7e61ed7d741.png)

あーーー。ちゃんと書いてあるやん Hyper-V 有効になるってｗ

しかも

![image](https://qiita-image-store.s3.amazonaws.com/0/44540/151e3adb-d7bb-46f0-5974-f4d86f457700.png)

むむむ。とりあえず３日ほどはまってましたｗ

# 参考さいと
> [vagrant up起動に失敗したら](http://qiita.com/super-hot-engineer/items/21e4456b8318db877f5b)
> [Vagrant 起動時に SSH auth method: private key で止まる](http://qiita.com/nagomu/items/67f046d3cf2a02b0efb0)
フロントエンドで ActionCable を npm 経由で使う

近年、我々がRails5をセットアップする際に最初にやることは sprockets を 無効化することだが、 rails5 の Channel は Sprockets ありきで書かれていたので、npm で完結して使えるか調べて、書きなおした。

[actioncable](https://www.npmjs.com/package/actioncable "actioncable") を使う。

```
npm install -S actioncable
```

どこ由来か怪しくて調べたけど、一応railsのリポジトリから publish されてる？
https://github.com/rails/rails/blob/master/actioncable/package.json

npm に publish した eleencodes は https://github.com/eileencodes 見る限り rails コミッタなので、とりあえず信用できそう。同名の id を npm で騙ってないかぎり。


http://qiita.com/jwako/items/96c01183c9c33ba1a48d を参考に babel/browserify 環境用に書き直す。

```ruby
import ActionCable from "actioncable";
const cable = ActionCable.createConsumer();
const room = cable.subscriptions.create("RoomChannel", {
  connected() {
    console.log("connected");
  },

  disconnected() {
    console.log("disconnected");
  },

  received(data) {
    console.log("received",  data);
  },

  speak(mes = "hello") {
    this.perform('speak', {mes});
  }
});
export default room;
```

だいたいこんな感じ

## 注意点

今はリリース直後だからブレ用がないけど、念のため Gemfile の方とバージョンを固定して合わせておかないと、非互換な変更あったときに死にそう。