OmniAICreator/Qiita-1.07M huggingface dataset:
Python3 標準入力から複数の値を受け取りたい時

#背景
[AtCoder](https://atcoder.jp)などのプログラムを提出する系のサービスでは標準入力から複数の値を受け取る必要が出てくる場合があります．
???となったため以下にPython3における標準入力から複数の値を受け取る方法をまとめてみました．
#参考にしたサイト
ピンポイントに情報が載ってたサイトがありましたわ．
[No Caffeine,No Life 「Python3:標準入力の受け取り方」](http://prdc.hatenablog.com/entry/2016/08/07/175622)
#1行に複数の数値を入力する場合

```Python3
>>> a,b=map(int,input().split())#標準入力を行う
33 66
>>> print(a)
33
>>> print(b)
66
```

標準入力の区切りは空白になっています．そのため，上の例のようにa=33,b=66にしたい時は「33(空白)66」と入力します
#複数行に数値を入力する場合
##内包表記の場合
```Python3
>>> N=int(input())#入力回数を決める
3
>>> a,b,c=[int(input()) for i in range(N)]
4
55
68
>>> print(a,b,c)
4 55 68
```
最初の行で入力回数を与え，その回数分値を入力します．
##普通に書く場合
```Python3
>>> N=int(input())#入力回数を決める
3
>>> list=[]
>>> for i in range(N):
...     list.append(int(input()))
... 
5
22
85
>>> print(list)
[5, 22, 85]
```
内包表記ではなく普通にfor文を記載する場合は次のように記載します．
（内包表記もリスト使っていいと思います・・・）

#感想
ソースコードを提出する系のサービスでは標準入力の書き方を覚えていないと詰むのでぜひ覚えましょう！
[Docker] Docker ToolboxからDocker for Macに乗り換えて "could not read CA certificate ..." エラーになったときの対処方法

ローカルのPCでDockerを動かすのに、長いことDocker Toolboxを使っていたが、
今更ながらDocker for Macに移行した。
その際におそらく移行時特有のエラーになったのでメモ

※ Docker ToolboxのアンインストールUninstallは以下の手順で行った
https://qiita.com/minamijoyo/items/ec5b35382797ac08e067


Docker for Macをインストールし起動

```
docker --version
```

すると以下のエラー

```
could not read CA certificate "/Users/myname/.docker/machine/machines/default/ca.pem": open /Users/myname/.docker/machine/machines/default/ca.pem: no such file or directory
```


https://forums.docker.com/t/initial-install-of-docker-for-mac-could-not-read-ca-certificate/9170

を参考に

```
unset ${!DOCKER*}
```

を実行して解決。
Docker Toolboxで使っていた環境変数が邪魔していた模様。
自分の場合は.bash_profileにexportも記載していたため合わせて削除した
SDKMAN を使って Grails インストール Mac


MacにGrailsをインストールします。Javaはインストール済みとします。

Grailsの本家サイトを拝見すると[SDKMANを利用したインストール](https://grails.org/download.html#sdkman)が紹介されていたので、これをやってみます。

まず、Launchpad からターミナルを起動します。
次のコマンドを実行します。

```
curl -s get.sdkman.io | bash
```

次のような出力があって、「Enjoy!!!」と出れば、インストールできていると思います。

![スクリーンショット 2017-09-23 16.30.22.png](https://qiita-image-store.s3.amazonaws.com/0/203704/373abd0e-0958-3cf0-9975-202a4a14a224.png "スクリーンショット 2017-09-23 16.30.22.png")

インストール時の出力に新しいターミナルを起動するか、sourceコマンドを実行すると使えるとあったのですが、新しいターミナルを起動しても使えなかったのでホームディレクトリで次のコマンドを実行しました。

```
source .sdkman/bin/sdkman-init.sh 
```

インストールできたかは、次のコマンドで確認しました。

```
sdk help
```

次のコマンドで最新のGrailsをインストールします。今回はバージョン3.3.1です。

```
sdk install grails
```

インストールできたかは、

```
grails -verson
```
で確認できます。

<追記>
後日、sdkコマンドが実行できなくなっていのたで調べると、どうやら、macは、.bashrcが読み込まれないので、下記の記述を.bash_profileに記載しました。

```
if [ -f ~/.bashrc ] ; then
. ~/.bashrc
fi
```
Erlangでfizzbuzz　高階関数使ってみた。

Erlang勉強継続中です。

前回は高階関数を使っていませんでした。
せっかくなので今回無理やり使ってみました。

前回のfizzbuzz：
https://qiita.com/shiro01/items/c19ff58ba1598c3adefd

ほとんど変わりませんが、今回書いたコードです。

```erlang
-module(hof_fizzbuzz).
-export([run/2, run/3]).

%% out:fizzbuzz結果を都度出力、list:fizzbuzz結果のリスト作成
%% 1~Endまでの数値をfizzbuzzする
run(out, End) when is_integer(End) -> fb_out_for(End);
run(list, End) when is_integer(End) -> fb_list_for(End);
run(_, _) -> io:format("e.g. : run(out, ~p)~n", [10]).

%% Start~Endまでの数値をfizzbuzzする
run(out, Start, End) when is_integer(Start), is_integer(End) -> fb_out_for(Start, End);
run(list, Start, End) when is_integer(Start), is_integer(End) -> fb_list_for(Start, End);
run(_, _, _) -> io:format("e.g. : run(out, ~p, ~p)~n", [10, 20]).

%% 繰り返しfizzbuzz結果を出力する。
fb_out_for(0) ->  io:format("~p:~n",[0]);
fb_out_for(End) when 0 < End -> fb_out_for(1, End, fun fb_out/1).
fb_out_for(I, End) when I =< End -> fb_out_for(I, End, fun fb_out/1).
fb_out_for(End, End, F) -> F(End);
fb_out_for(I, End, F) -> F(I), fb_out_for(I+1, End, F).

%% 与えられた数値のfizzbuzz結果を出力する
fb_out(0) -> io:format("~p:~n",[0]);
fb_out(Num) -> fb_out(Num, Num rem 3, Num rem 5).
fb_out(Num, 0, 0)-> io:format("~p:~p~n",[Num, fizzbuzz]);
fb_out(Num, 0, _)-> io:format("~p:~p~n",[Num, fizz]);
fb_out(Num, _, 0)-> io:format("~p:~p~n",[Num, buzz]);
fb_out(Num, _, _)-> io:format("~p:~n",[Num]).

%% 繰り返しfizzbuzz結果のリストを作る
fb_list_for(0) -> [0];
fb_list_for(End) when 0 < End -> fb_list_for([], 1, End, fun fb_list/2).
fb_list_for(I, End) when I =< End -> fb_list_for([], I, End, fun fb_list/2).
fb_list_for(Reslut, End, End, F) -> lists:reverse(F(Reslut,End));
fb_list_for(Reslut, I, End, F) -> fb_list_for(F(Reslut, I), I+1, End, F).

%% 与えられた数値のfizzbuzz結果をリストに追加する
fb_list(Reslut, 0) -> [0|Reslut];
fb_list(Reslut, Num) -> fb_list(Reslut, Num, Num rem 3, Num rem 5).
fb_list(Reslut, _Num, 0, 0)-> [fizzbuzz|Reslut];
fb_list(Reslut, _Num, 0, _)-> [fizz|Reslut];
fb_list(Reslut, _Num, _, 0)-> [buzz|Reslut];
fb_list(Reslut, Num, _, _)-> [Num|Reslut].

```

実行結果

```
1> c(hof_fizzbuzz).
{ok,hof_fizzbuzz}
2>
2> hof_fizzbuzz:run(list, 10).
[1,2,fizz,4,buzz,fizz,7,8,fizz,buzz]
3>
3> hof_fizzbuzz:run(out, 10).
1:
2:
3:fizz
4:
5:buzz
6:fizz
7:
8:
9:fizz
10:buzz
ok
4>
4> hof_fizzbuzz:run(list, 10, 20).
[buzz,11,fizz,13,14,fizzbuzz,16,17,fizz,19,buzz]
5>
5> hof_fizzbuzz:run(out, 10, 20).
10:buzz
11:
12:fizz
13:
14:
15:fizzbuzz
16:
17:
18:fizz
19:
20:buzz
ok
6>

```

fb_list_for/4について
最初は以下のように実装してました。

```erlang
fb_list_for(Reslut, MaxNum, MaxNum, F) ->
    Reslut_buf = F(Reslut,MaxNum),
    lists:reverse(Reslut_buf);
fb_list_for(Reslut, I, MaxNum, F) ->
    Reslut_buf = F(Reslut, I),
    fb_list_for(Reslut_buf, I+1, MaxNum, F).
```

大して変わらない気もしますが、どっちがいいんだろう。
hpack と hspec に対応した stack templates 

# 私が作った stack template

今回の記事に関連して作成したテンプレートは gist に置いています。

- hspeck + hpack  
https://gist.github.com/algas/0ec303769e09a8c9188b83a3d7a8990c#file-hspec-hpack-hsfiles
- servant + hspec + hpack  
https://gist.github.com/algas/0ec303769e09a8c9188b83a3d7a8990c#file-servant-hpack-hsfiles

[hpack](https://github.com/sol/hpack) も [stack template](https://github.com/commercialhaskell/stack-templates) も知ってるし使ってるという方は、記事を読まなくてもいいので上記のテンプレートを使ってみてください。
独自にカスタマイズしたい方もご自由にどうぞ。

## hpack とは？

hpack は `.cabal` ファイルを `package.yaml` から生成する機能を提供します。
(hpack を使わずに) Haskell のプログラムを作成するには `.cabal` ファイルを書く必要があります。
`.cabal` の代わりに `package.yaml` を作成・編集することによって開発時の煩わしさを軽減できます。

hpack を使うメリットを知るには下記の記事が参考になります。
[これからのHaskellプロジェクトではcabalではなくpackage.yaml(hpack)を使いましょう](https://www.ncaq.net/2017/07/31/)

## stack template

stack template は Haskell (stack) のプロジェクトの雛形を作成するときに使います。
例えば `simple-hpack` template を使ってプロジェクト(YOUR_PROJECT)を作成するには、以下のコマンドを実行します。

`stack new YOUR_PROJECT simple-hpack`

### template 一覧を表示する

テンプレートは上記以外にも複数あります。
以下のコマンドでテンプレート一覧を表示します。
`stack templates`

### 独自テンプレートを使う

筆者がよく使うのは [hspec](https://github.com/hspec/hspec) というテストフレームワークと [servant](https://github.com/haskell-servant/servant) というWebフレームワークです。
毎度、新しいアプリケーションを作る度に雛形を用意するのは大変なので、独自のテンプレートを用意しました。

以下のコマンドでテンプレートからプロジェクトを作成できます。

- hspec + hpack  
`stack new hspec-example https://gist.githubusercontent.com/algas/0ec303769e09a8c9188b83a3d7a8990c/raw/e88e90e8bcf319077a3f4391e13088e73901aed3/hspec-hpack.hsfiles`
- servant + hspec + hpack  
`stack new servant-example https://gist.githubusercontent.com/algas/0ec303769e09a8c9188b83a3d7a8990c/raw/e88e90e8bcf319077a3f4391e13088e73901aed3/servant-hpack.hsfiles`

### プログラムの実行

- ビルド  
`stack build`
- テスト実行  
`stack test`
- プログラム実行(前後の空白を除去する)  
   1. `stack build && stack exec hspec-example`
   2. `echo '  foo bar ' | stack exec hspec-example`
- プログラム実行(Webサーバ)
   1. `stack build && stack exec servant-example`
   2. `curl http://localhost:8080/users`

## 参考文献

https://github.com/sol/hpack
https://github.com/commercialhaskell/stack-templates
https://www.ncaq.net/2017/07/31/
1.2.2 Xcodeのインストールと簡単な使い方　((C++からのプログラミング入門

#はじめに
XcodeはAppleが出しているIDEでAppleが出しているだけあって、Apple製品(iphoneやmacなど)向けのアプリケーションを開発するのにうってつけです。スティーブ・ジョブズが愛したObjective CやApple社開発のSwiftなどはもちろん、C/C++などにも対応しています。割りとAppleファンには純正なだけに人気があるかもしれません（知らない）。

#ダウンロード
それはもちろん[iTuens](https://itunes.apple.com/jp/app/xcode/id497799835?ls=1&mt=12)からインストールできます。
完全にダウンロードされるまで待ちましょう。

#プロジェクトの始め方
今回は、C++のコードを書けるようにするまでしたいと思います。

Xcodeを開くと以下のような画面が出てくると思います。
<img width="796" alt="Screenshot 2017-09-22 23.51.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/114543/64bd719d-7863-3170-81bb-fe5c29f74449.png">


ここで**Create a new Xcode project**をおします。

<img width="410" alt="Screenshot 2017-09-22 23.52.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/114543/1e1b544f-f66f-8888-2c8f-0965a522b438.png">

すると下のようなものが出てくると思います。
ここではどのようなプロジェクトにするかを選べます。例えば、iosのアプリを作るならこれ、apple watchのアプリを作るならこれといろいろ選べます。

上のtabで**macOS**を選択して**Command Line Tool**をクリックしましょう。

<img width="1400" alt="Screenshot 2017-09-22 23.57.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/114543/dd44f4bb-d9a1-1a7e-4c8a-516677c46835.png">

すると以下のようなものが出てくると思います。

<img width="725" alt="Screenshot 2017-09-22 23.59.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/114543/fec766f6-ef19-3f54-f129-c5048d446c11.png">

ひとつひとつ埋めていきましょう
**Project Name**はあなたが作りたいアプリケーションの名前です。ただ、この記事をみている場合は特に作りたいプロジェクトが決まっていない方が多いと思います。その方は、「Xcodeテスト」や「初めてのプロジェクト」など適当に埋めてしまいましょう。
ちなみに、C++からのプログラミング入門としてこの記事を読んでいる方は、「C++からのプログラミング」としましょう。
**Team**も個人だと思うので適当にPersonal Teamでご自身の名前を埋めてしまいましょう。
**Organization Name**も特に会社でするプロジェクトでもないと思うので個人名で結構です。
**Organization Identifier**は自分のニックネームがあるかたは、「com.ニックネーム」としてください。ない方は「com.下の名前.名字」にしましょう。（なんでもいい）

これらの組織関係はアプリをリリースするわけでもないのでなんでも構いません。

**Language**は書きたいプログラミング言語の名前です。書きたい言語を選びましょう。C++からのプログラミング入門でこの記事を読んでいる方はもちろんC++です。

埋め終えたらNextをクリックしますと、そのプロジェクトをどこに保存するかを選ばなきゃいけません。
特にこだわりがないかたは、Documentsを選択しましょう。
次に行きますと、以下のような画像が出ると思いますので、main.cppというファイルを選択しましょう。

<img width="1404" alt="Screenshot 2017-09-23 00.16.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/114543/9cd8f5d5-0d11-322d-3c73-b2008aeb065f.png">

すると以下のような、コメントのところが違うと思いますが、コードが見れると思います。

```cpp
//
//  main.cpp
//  C++からのプログラミング
//
//  Created by Naggi Goishi on 23/09/2017.
//  Copyright © 2017 Naggi Goishi. All rights reserved.
//

#include <iostream>

int main(int argc, const char * argv[]) {
    // insert code here...
    std::cout << "Hello, World!\n";
    return 0;
}
```

これは、Hello Worldという文字を画面（コンソール）に出力するというプログラムです。（結構有名）

では、左上にある再生ボタンみたいなものを押してください。(もしくはコマンド+R)そしたら、このファイルをコンパイル（機械語に変換）して走らせてくれます。便利ですね。

Xcodeにはコンソール(右下の方)もついていて、そこに以下のように書かれていたら成功です。

```
Hello, World!
Program ended with exit code: 0
```

これからはこのHello Worldのコードではなくもっと複雑なコードを書いていきます。
Go の Enum 表現

Terraform のプルリクをレビュー　してもらっている時に、次のようなコメントをもらった。

```go
+	resGroup := d.Get("resource_group_name").(string)
+
+	skuName := d.Get("sku")
+	sku, err := getSku(skuName)
+	func getSku(skuName interface{}) (*operationalinsights.Sku, error) {
	if skuName == nil {
		return nil, nil
	}
	skuEnum, err := getSkuNameEnum(skuName.(string))
	if err != nil {
		return nil, err
	}
	return &operationalinsights.Sku{
		Name: skuEnum,
	}, nil
}
```
こうなっているのを下記のように。

```go

since we can just cast directly to the Enum, we can replace this with:

sku := &operationalinsights.Sku{
 Name: operationalinsights.SkuNameEnum(skuName),
}
```

てっきり、ゴリゴリ書かないと行けないと思ったけどいらんかった。確認してみよう。

# Go の enum

Go では、Enum はないが、idiom としてこんな感じの様子。

```go
type SkuNameEnum string

const (
	// Free specifies the free state for sku name enum.
	Free SkuNameEnum = "Free"
	// PerNode specifies the per node state for sku name enum.
	PerNode SkuNameEnum = "PerNode"
	// Premium specifies the premium state for sku name enum.
	Premium SkuNameEnum = "Premium"
	// Standalone specifies the standalone state for sku name enum.
	Standalone SkuNameEnum = "Standalone"
	// Standard specifies the standard state for sku name enum.
	Standard SkuNameEnum = "Standard"
	// Unlimited specifies the unlimited state for sku name enum.
	Unlimited SkuNameEnum = "Unlimited"
)
```

わざわざ、`string` を、`SkuNameEnum` というタイプに変更している。これにより、SkuNameEnum という型を定義して、なおかつ、続くconst によって、固定の値を定義している。

使ってみよう。

```go
func main() {
	skuName1 := SkuNameEnum(Free)
	skuName2 := SkuNameEnum("Standalone")
	fmt.Printf(string(skuName1))
	fmt.Printf(string(skuName2))
}
```

実行してみる。

```
FreeStandalone
```

ちゃんと使える。この構文はよく考えたら型変換の、`int("2")` とかと同じ構文だ。キャストがしっかりできている。また一つ学んだ。
IntelliJ IDEA Community Edition インストール Mac


Macbook ProにIntellij IDEA Community Edition をインストールします。

# ダウンロード

JET BRAINS の[ダウンロードページ](https://www.jetbrains.com/idea/download/#section=mac)からダウンロードします。

![スクリーンショット 2017-09-23 15.54.40.png](https://qiita-image-store.s3.amazonaws.com/0/203704/3949127d-1b43-125a-cf25-bea1f1297296.png "スクリーンショット 2017-09-23 15.54.40.png")


# インストール

ideaIC-xxxx.x.x.dmg といった名前のファイルがダウンロードできるので、ダブルクリックで実行します。

![スクリーンショット 2017-09-23 15.57.49.png](https://qiita-image-store.s3.amazonaws.com/0/203704/f93aa395-f305-36f9-a17e-00af3da75261.png "スクリーンショット 2017-09-23 15.57.49.png")


「IntelliJ IDEA CE」のアイコンを右のアイコンへドラッグ＆ドロップします。

# 起動

Lanuchpadに「IntelliJ CE」というアイコンが増えているので、クリックします。
初期設定などのウィンドウが起動するので好みに合わせて入力します。スキップも可能です。
設定が完了すると次の画面になります。

![スクリーンショット 2017-09-23 16.00.59.png](https://qiita-image-store.s3.amazonaws.com/0/203704/9acb0c46-fa20-4397-fb29-8ec10cb0f27d.png "スクリーンショット 2017-09-23 16.00.59.png")

以上です。
pythonで環境変数を取得するとstring型なので、booleanぽくFalseと環境変数に格納してもif文でTrueとなる

##   はじめに
環境変数を取得すると、string型なので、
booleanチックにif文を書いてしまうと、空白でなければすべてTrueになるというお話です。

##  実行環境
python : 3.6.0

##  以下やってみる
###  環境変数に``'True'`を格納

```python
>>> import os
>>> os.environ['IBARAKIISGOOD'] = 'True'
>>> test = os.getenv('IBARAKIISGOOD')
>>> test
'True'
```

下記の通り、if文で判定すると、Trueとなる。

```python
>>> def test_function(test):
...     if test:
...         print('test is true')
...     else:
...         print('test is false')
...
>>> test_function(test)
test is true
```

###  環境変数に``'False'`を格納
環境変数に``'False'`を格納して、if文で判定すると、Trueとなってしまった！

```python
>>> os.environ['IBARAKIISGOOD'] = 'False'
>>> test = os.getenv('IBARAKIISGOOD')
>>> test
'False'
>>> test_function(test)
test is true
>>> 
```

茨城はやはりいいところであると判定してくれた！

###  環境変数に空白を格納
環境変数に空白を格納して判定してみると、falseになった。

```python
>>> os.environ['IBARAKIISGOOD'] = ''
>>> test = os.getenv('IBARAKIISGOOD')
>>> test
''
>>> test_function(test)
test is false
```

## さいごに
以上の結果は、冒頭に記述した通り、環境変数を取得した時の型がstringだったからでした。。

```python
>>> isinstance(test, str)
True
```

環境変数にTrue, Falseを格納する際は気をつけましょう。
いや、格納しないほうがいいんじゃないか。ということでした。

## 参考
*   [Python で if 文に変数を入れたときの結果](http://www.lifewithpython.com/2013/02/python-if-statement-data-type.html)
*   [int と bool であはん ～isinstance()の罠～](http://d.hatena.ne.jp/Kmizukix/20091224/1261647840)
ローカルでS3的なもの（s3rver）を動かしてaws-cliで操作する

S3を使うプログラムをローカルでテストしたくなったので、[s3rver](https://github.com/jamhall/s3rver)というものを使ってみました。

# インストール

```shell-session
$ yarn add --dev s3rver 
yarn add v0.27.5
 :
Done in 70.65s.
```

`npm install --dev s3rver`でも大丈夫です。

# 確認

global installではないので、`node_modules/.bin/s3rver`で起動します。

```shell-session
$ node_modules/.bin/s3rver --help

  Usage: s3rver [options]


  Options:

    --version                   output the version number
    -h, --hostname [value]      Set the host name or ip for the server
    -p, --port <n>              Set the port of the http server
    -s, --silent                Suppress log messages
    -i, --indexDocument [path]  Index Document for Static Web Hosting
    -e, --errorDocument [path]  Custom Error Document for Static Web Hosting
    -d, --directory [path]      Data directory
    -c, --cors                  Enable CORS
    -h, --help                  output usage information

```

# 格納先ディレクトリを準備して起動

```shell-session
$ mkdir -p ./temp/s3rver
$ node_modules/.bin/s3rver -d ./temp/s3rver
now listening on host localhost and port 4568
```

デフォルトでは4568ポートでListenしています。

# aws-cliで操作する

aws-cliのs3コマンドまたはs3apiコマンドに`--endpoint http://localhost:4568`を指定すると利用できます。

Bucketの作成と表示(s3api使用)

```shell-session
$ aws --endpoint http://localhost:4568 s3api create-bucket --bucket test-bucket
{
    "Location": "/test-bucket"
}

$ aws --endpoint http://localhost:4568 s3api list-buckets
{
    "Buckets": [
        {
            "Name": "test-bucket",
            "CreationDate": "2017-09-23T06:13:07.000Z"
        }
    ],
    "Owner": {
        "DisplayName": "S3rver",
        "ID": "123"
    }
}
```

ファイルの操作（s3使用）

```shell-session
$ aws --endpoint http://localhost:4568 s3 cp ./README.md s3://test-bucket/
upload: ./README.md to s3://test-bucket/README.md

$ aws --endpoint http://localhost:4568 s3 ls s3://test-bucket/
2017-09-23 15:14:49       7052 README.md
```

# javascript sdk （nodejs）から利用

`AWS.config.update()`でendpointを指定することで利用できます。

```js
const AWS = require('aws-sdk');
AWS.config.update({ endpoint: 'http://localhost:4568' });
const s3 = new AWS.S3();

s3.listBuckets().promise()
  .then((data) => console.log(data.Buckets));

```

```shell-session
$ node index.js 
[ { Name: 'test-bucket', CreationDate: 2017-09-23T06:14:49.000Z } ]
```

これと[aws-sam-local](https://github.com/awslabs/aws-sam-local)を組み合わせれば、Lambdaの開発もかなり捗りそうです。


## （参考）実体は？

`s3rver -d <directory>`のディレクトリにファイルの実体があるのですが、そのまま置かれているわけではないようです。

```shell-session
$ tree -a ./temp/s3rver/test-bucket/
./temp/s3rver/test-bucket/
└── README.md
    ├── .dummys3_content
    └── .dummys3_metadata
```
ファイル名（S3上のKey）がディレクトリ構成で表現され、`.dummys3_content`が実体、`.dummys3_metadata`にcreationDateなどが格納されていました。

この構造を理解していると、テストデータとしてS3にObjectを置くことができそうですが、`s3 sync`や`s3 cp`が使えるので、そちらのほうが楽だと思います。
前々処理３：サクサク使うSQL（貿易統計のデータ検証）

# データを検証しましょう。（ＳＱＬは、知っている前提）

実際にデータ分析をすればわかりますが、データがおかしいことはしばしばりあり、検証することは重要です。大きなデータになればなるほど、検証の手間は大変です。実際のデータで検証をしてみましょう。
今、tmp.db にあるデータは、この２つです。

|No|名称|件数|説明|
|---|---|---|---|
|1|ym_custom_latest 税関別データ　最新(2017 1-7 )|2324451|sqlite 形式|
|2|ym_latest 全国データ　　最新(2017 1-7 )|814081|sqlite 形式に変換済み|


* 税関別データ(詳細)　全国に税関コードが加わっているだけ

|No|項目|型|内容|補足|
|---|---|---|---|---|
|1|"index"|INT|index||
|2|exp_imp|INT|輸出1,輸入2||
|3|Custom|TEXT|税関コード (例)100|全国との違いはここだけ|
|4|Year|INT|年 (例) 2016||
|5|month|TEXT|月 (例) 01 ||
|6|Country|TEXT|国コード (例) 103||
|7|Unit1|TEXT|数量の単位 1|キログラムと、リットルなどです。|
|8|Unit2|TEXT|数量の単位 2||
|9|hs2|TEXT|HS code 2桁|HS code ２桁|
|10|hs4|TEXT|HS code 4桁||
|11|hs6|TEXT|HS code 6桁||
|12|hs9|TEXT|HS code 9桁||
|13|Q1|INT|数量 1|数量の単位に対応|
|14|Q2|INT|数量 2|〃|
|15|Value|INT|金額 1000円||

# 全国と税関別の合計(集計）はあうはずです。

* 輸出、輸入(1月から7月までの集計)

全国
```
select exp_imp,sum(Value) as Value from ym_latest  group by exp_imp
```

|輸出入|金額|
|---|---|
|1|44283374669|
|2|42817910937|

税関別
```
select exp_imp,sum(Value) as Value from ym_custom_latest  group by exp_imp
```

|輸出入|金額|
|---|---|
|1|44283374669|
|2|42817910937|

# 全国と税関別の月ごとの合計

#### 一時的なテーブルを作成して、比較してみます。
* 全国 集計結果を一時的なテーブル x_ym に格納します。

```
create table x_ym as select exp_imp,month,sum(Value) as ym_value from ym_latest  group by exp_imp,month
```
* 税関別もつくります。

```
create table x_ym_custom as select exp_imp,month,sum(Value) as ym_custom_value from ym_latest  group by exp_imp,month
```

* 全国も、税関別も結果は同じはず。検証してみましょう。

税関別と全国の合計の差をとって、差があるところを、取り出しています。差はもちろんありません。

```
select x_ym.exp_imp,x_ym.month,
x_ym.ym_value - x_ym_custom.ym_custom_value as diff
from x_ym,x_ym_custom 
where x_ym.exp_imp = x_ym_custom.exp_imp and x_ym.month = x_ym_custom.month and
abs(diff) > 0
```

# [輸出統計品目コード](http://www.customs.go.jp/yusyutu/2017_4/index.htm)ではどうでしょうか(あいません）
hs9  [271500000 アスファルト](http://www.customs.go.jp/yusyutu/2017_4/data/j_27.htm)で調べてみましょう。

検証は、7月の輸出をつかいます。

```
select   sum(Value) as Value from ym_latest 
where exp_imp=1 and month='07' and hs9='271500000'
group by exp_imp,month
```
結果は、かなり食い違います。計算間違いでしょうか？

|month|全国|税関別|
|---|---|---|
|07|418628|4389811|

それでは、貿易統計のページで調べてみましょう。
まず、全国のは[統計品別表](http://www.customs.go.jp/toukei/srch/index.htm?M=29&P=0)で調べることができます。[結果](http://www.customs.go.jp/toukei/srch/index.htm?M=29&P=1,1,,,,,,,,1,0,2017,0,7,0,2,271500000,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,20)は、 418628　であっています。
税関別は、[統計品別国別税関一覧表](http://www.customs.go.jp/toukei/srch/index.htm?M=09&P=0)から検索できます。
[結果](http://www.customs.go.jp/toukei/srch/index.htm?M=09&P=1,1,,,,,,,,1,0,2017,0,7,0,2,271500000,,,,,,,,,,1,,,,,,,,,,,,,,,,,,,,,,200) は、国別、税関別にでているので、集計する必要がありますが、
インドだけで、1144130 なのですでにあいません。エクセルにはりつけて、計算すると、4389811　になり、上記の表の計算結果は、あっています。

食い違いが生じるのは、全国と税関別の集計結果が調整されているからです。[よくある質問](http://www.customs.go.jp/toukei/sankou/howto/faq.htm) の２５番にあるように、販売価格等をしられたくない場合には、統計にのせないことも可能なために、この食い違いがでます。
APPTVRepeater (ESP8266) > ソフトウェア v0.5 > Apple Remote SenderはGitHubへ | メインプログラム修正

```txt:動作確認
- ESP-WROOM-02 (以下、ESP8266)
- ユニーバサル基板実装
- Arduino IDE 1.6.6
- Canon IXY 3
```

開始: [ESP8266 > 検討 > APPTVRepeater > 英語リスニング補助ツール (定数時間の巻き戻し機能)](https://qiita.com/7of9/items/5f20327af0574f80cd6b)

[APPTVRepeater (ESP8266) > ソフトウェア v0.4 > Repeaterとしのて機能は実装完了](https://qiita.com/7of9/items/8e1413a28929443f9906)
の続き。

### Apple Remote Sender on GitHub

Apple Remote Senderの処理部分を以下に上げた。
[GitHub](https://github.com/yasokada/esp8266_170923_AppleRemoteSender)

License: GPL v3.

もともとのコードがGPL v3なので、それにならってGPL v3とした。

元コードの作者に連絡済で、問題があれば対応をする。
(追記: 2017/10/06 作者からの連絡あり。問題はなさそう）。

### メインプログラム v0.5

```
#define KEY_MENU (0x01)
#define KEY_PLAY (0x02)
```
のような定義はメインプログラムに置くものでもなかった。
Apple Remote Senderのヘッダーに移した。

それによりメインプログラムは以下のようになった。

```c:esp8266_170923_APPTVrepeater
#include <ESP8266WiFi.h>
#include "AppleRemoteSender.h"

//#define USE_REGISTER // to register to Apple TV at first

/*
 * v0.5 Sep. 23, 2017
 *   - move [KEY_XXX] definitions to [AppleRemoteSender.h]
 * v0.4 Sep. 23, 2017
 *   - repeat 5 seconds (LEFT and PLAY)
 * v0.3 Sep. 23, 2017
 *   - send keys to register ESP8266 remote controller to Apple TV
 * v0.2 Sep. 23, 2017
 *   - send UP signal to register the remote controller
 * v0.1 Sep. 23, 2017
 *   - turn on/off the IR pin to check the device
 */

static const int kPinIR = 4;

#define BACK_SEC (5)

void setup() {
  WiFi.disconnect(); // watch dog reset対処
  Serial.begin(115200);
  pinMode(kPinIR, OUTPUT);

  APPTV_setup(kPinIR);
}

static const int keylist[] = {
  KEY_UP,
  KEY_DOWN,
  KEY_LEFT,
  KEY_RIGHT,
  KEY_PLAY, // SELECT
  KEY_MENU,
};

void RegisterController(void)
{
  static int pos = 0;
  
  int size_key = sizeof(keylist) / sizeof(keylist[0]);
  
  delay(2000); // msec

  if (pos >= 0) {
    Serial.println(F("Send Key")); // F() to reduce RAM usage  
    for(int loop=0; loop < 20; loop++) {
      APPTV_SendKey(kPinIR, keylist[pos]);
      delay(100); // msec
    }
    pos++;
    if (pos == size_key) {
      pos = -1;
    }
  }
}

void RepeatSeconds()
{
    static int start = 1;

    if (start != 1) {
      return;
    }
    
    APPTV_SendKey(kPinIR, KEY_LEFT);
    delay(100); // msec

    delay(BACK_SEC * 1000 * 0.38); // msec (0.38: adjusted to 5 seconds interval)
  
    APPTV_SendKey(kPinIR, KEY_PLAY);
    delay(100); // msec

    start = 0;
}

void loop() {
  static int pos = 0;
  int size_key = sizeof(keylist) / sizeof(keylist[0]);
  
  delay(2000); // msec

#ifdef USE_REGISTER
  RegisterController();
#else
  RepeatSeconds();
#endif
}
```
手頃な128文字の16進数をmacで生成する

```
% echo -n "*************" | openssl dgst -sha512
1e5af932a088c82b21e3d0d2e1bcde094f8f64c65d1c2757507c8c5dede4f9a6af5b848883b59f137a496c0e698cf0acd6f1dc583615884625bdcd363e1cc17d
```
CakePHP3 で LiveReload  する (browser-sync使う

# 目的
node の  browser-sync が便利だったので CakePHPアプリケーションでも
nodeを利用してLiveReload実現する、PHPむけなので、なるべくJSを触らずにすむように実施。
最終的に src以下とwebroot以下のファイル変更時にブラウザの自動リロードを実現する。

## 前提
* phpのインストール及び phpにPathを通しておく
* composer 導入
* nodejs/npm 導入

## 手順 

1. composer で cakephp の本体を取得
2. composer で依存関係をインストール
3. ビルトインサーバの起動用に ./bin/cake に実行権限をつける
4. npm の準備(package.json を生成する)
5. browser-sync のインストール
6. package.json の編集
7. npm から Cakeサーバとbrowser-syncサーバを起動する


### 1. composer で cakephp の本体を取得
composer で cakephp を example ディレクトリにインストールし、
作成されたディレクトリに移動する。

```
$ composer create-project --prefer-dist cakephp/app example
$ cd example
```

### 2. composer で依存関係をインストール
composerで依存関係をインストールする

```
$ composer install 
```

### 3. ビルトインサーバの起動用に ./bin/cake に実行権限をつける
windows の場合はこの工程は必要無いので、起動確認だけ行う

```
$ chmod +x ./bin/cake 
```
  
#### 起動確認

```
$ ./bin/cake server 
```

port 8765 でcakephp が起動すればOK、起動が確認できたらctr + c で
停止しておく。

### 4. npm の準備(package.json を生成する)

```
$ npm init -y
```

### 5. browser-sync のインストール
--save-dev は npm の依存関係をpackage.json に保存するためのオプション

```
$ npm install browser-sync --save-dev
```

### 6. package.json の編集

scriptsへコマンドを追加する。追記したscript は npm run [key] で実行できる、また
scriptsで定義したコマンドは別のscriptsからも実行できる。

追加するコマンドは3つ

#### 6-1. CakePHPの開発サーバを実行する cake コマンド
```
"cake": "./bin/cake server"
```
#### 6-2. 1.で起動された、CakePHP を browsersync を通して port 8766 へ プロキシする browsersync コマンド
```
"browsersync": "node ./node_modules/.bin/browser-sync start --proxy localhost:8765 --port 8766 --files=\"src/**/*.*\" --files=\"webroot/**/*.*\"",
```
--files は変更検知するディレクトリを指定する、{src,webroot}/***/**.* のような指定はディレクトリに関してはできないようだ、
pulugin ディレクトリ等も対象にしたい場合は、引数を追加してくのが無難？ 

#### 6-3. 1. 2. のコマンドを まとめて並列実行する start コマンド

```
"start": "npm run cake && npm run browsersync" 
```

すでに生成されている package.json を開く。(テキスト編集できるソフトならなんでも良い

```
vi ./package.json

{
  "name": "example",
  "version": "1.0.0",
  "description": ""
  "main": "index.js",
  "directories": {
    "test": "tests"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    /* 以下３行が追記  */
    "cake": "./bin/cake server",　/* 1 */.
    "browsersync": "node ./node_modules/.bin/browser-sync start --proxy localhost:8765 --port 8766 --files=\"src/**/*.*\" --files=\"webroot/**/*.*\"", /* 2 */
    "start": "npm run cake && npm run browsersync" /* 3 */
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "browser-sync": "^2.18.13"
  },
  "dependencies": {
    "browser-sync": "^2.18.13"
  },
  "keywords": []
}
```

### 7. npm から Cakeサーバとbrowser-syncサーバを起動する

```
$ npm start
```

問題がなければ、コマンドを実行時に規定のブラウザでcakeアプリが起動する、
その後はsrcとwebroot以下のファイル編集を行う度にブラウザリロードが実行される。


## まとめ
構成は [cakeアプリ:8765] > [nodeのプロキシサーバ:8766] のような感じ。

動作としてはプロキシサーバが元ページを読み込む再に body に　スクリプトを仕込んで
変更を検知をブラウザ側に伝えているようだ、browser-syncのGUIもついており、回線速度の
エミュレートなんかもできそう。サンプルはCakeだけど、他のPHPフレームワークでもほぼ同じ方法を使えそう。ビルトインサーバじゃなくNginxとかで動かしている場合でも、browsersync のポートを合わせてあげれば動くはず。
PHPをnpm scriptsから動かすのに若干の背徳感を感じる。
【Ruby】簡単なインスタンスメソッドとクラスメソッドの使い分け

# 背景
Rubyを使用していて、インスタンスメソッドとクラスメソッドの知識が曖昧だったのでまとめました。

# インスタンスメソッドとクラスメソッド
## インスタンスメソッド
インスタンスオブジェクトから実行できるメソッド。

## クラスメソッド
クラスオブジェクトから実行できるメソッド。

## 使用例
```Person.rb
class Person
  def initialize(name)
    @name = name
  end

  # インスタンスメソッド
  def instance_method
    p @name
  end

  # クラスメソッド
  def self.class_method(filename)
    path = File.join(File.dirname(__FILE__), filename)
    name = File.read.split("\n").map($:strip)[0]
    Person.new(name)
  end
end
```
```
インスタンスメソッドを使用する場合
p = Person.new("test")
p.instance_method
-> "test"

クラスメソッドを使用する場合
p = Person.class_method("name.txt")
p.instance_method
-> "test"
```

# 結局どう使い分ける？
基本的には、インスタンスメソッドで処理を実現できるか検討する。
外部からデータを取得する処理（外部ファイルからデータを取得し、インスタンスを作成する時など）は、クラスメソッドを使用する。
Rails・seedファイルを分割して管理する

Railsで初期データを入れるのにはseedを使いますが、モデルが多くなってくるとseedの管理もモデル毎にしたいなと思い調べたので、自分がした方法を紹介します。
もっといい方法があれば、教えていただきたいです。

# すること
・seedを複数に分割する。
・seedを指定して実行できるようにする。
・seedを一括で実行する。

# 手順
### rakeタスクの作成
 lib/tasks/seed.rakeを作成します。
*[こちらのサイトを参考にさせていただきました](http://yu0105teshi.hateblo.jp/entry/2016/08/03/180603)

```ruby:seed.rake
Dir.glob(File.join(Rails.root, 'db', 'seeds', '*.rb')).each do |file|
  desc "Load the seed data from db/seeds/#{File.basename(file)}."
  task "db:seed:#{File.basename(file).gsub(/\..+$/, '')}" => :environment do
    load(file)
  end
end
```

### seedファイルの作成
db/seedsというディレクトリを作成し、その下に行いたいモデル毎のseedファイルを作成します。
例えばUserに関してはuser.rbなど。
db/seeds/user.rb

```ruby:user.rb
  User.create(name: "テスト")
```

これでおっけーです。
### 実行方法
以下のコマンドを入力してください

```
bundle exec rake  db:seed:user
```

これでモデル毎にファイルを実行することができます！

### 全ファイルを一括で実行
rakeタスクファイルを作成して全ファイルを実行するという手もありですが、
普通にdb/seeds.rbファイルに

```ruby:seeds.rb
require './db/seeds/実行したいseedファイル名.rb'
```

なんてことでもいいと思います。
もっといい方法があれば、教えて欲しいです。
【UniRx】ReactivePropertyの初期値のプッシュを無視したいとき

# 参考記事
[Unityにおけるコルーチンの省メモリと高速化について、或いはUniRx 5.3.0でのその反映](http://neue.cc/2016/05/14_529.html)

## 初期値がプッシュされる例
```csharp:初期値がプッシュされる例
using UnityEngine;
using UniRx;


public class Example : MonoBehaviour
{
    private readonly IntReactiveProperty _count = new IntReactiveProperty();

    private void Start()
    {
        _count
            .Subscribe(count => Debug.Log(count))
            .AddTo(gameObject);

        _count.Value = 1;
    }
}
```
```csharp:出力結果
```
![ss1.PNG](https://qiita-image-store.s3.amazonaws.com/0/126970/adb3db64-9f12-a473-7d30-7aa34bb49c86.png)


## 初期値がプッシュされないSkipLatestValueOnSubscribeを利用する例
```csharp:初期値がプッシュされないSkipLatestValueOnSubscribeを利用する例
using UnityEngine;
using UniRx;


public class Example : MonoBehaviour
{
    private readonly IntReactiveProperty _count = new IntReactiveProperty();

    private void Start()
    {
        _count
            .SkipLatestValueOnSubscribe()
            .Subscribe(count => Debug.Log(count))
            .AddTo(gameObject);

        _count.Value = 1;
    }
}
```
```csharp:出力結果
```
![ss2.PNG](https://qiita-image-store.s3.amazonaws.com/0/126970/e70fa509-35ec-0ab0-c816-3bc2f10b7167.png)

## SkipLatestValueOnSubscribeの実装
```csharp:SkipLatestValueOnSubscribeの実装
public static IObservable<T> SkipLatestValueOnSubscribe<T>(this IReadOnlyReactiveProperty<T> source)
{
    return source.HasValue ? source.Skip(1) : source;
}
```

# まとめ
>Rx.NET用のReactivePropertyでは、コンストラクタでReactiveProeprtyModeとして
>None | RaiseLatestValueOnSubscribe | DistinctUntilChanged を指定できるようなデザインを選んでいるのですが
>（というのも、Viewにデータバインディングするため構築時の初期値はnullであることが確定しているという
>シチュエーションが割とあるため）
>UniRxのReactivePropertyではSubscribe側が選ぶというデザインにしています。

UniRxには[SubscribeToText](https://qiita.com/su10/items/6d7fd792d4b553454a4f)や[SubscribeToInteractable](http://neue.cc/2015/04/13_510.html)など
流れるように記述可能な拡張メソッドが定義されていて素晴しいですね。
Promise.allのcatchのタイミング

Promise.allのcatchのタイミングの扱いでつまった話を紹介します

# Promiseとは
* 非同期処理を記述できる
* 並行処理、直列処理を記述できる

参考：[JavaScript Promiseの本](https://azu.github.io/promises-book/#introduction)


# エラーの扱い
並行処理の失敗をハンドリングしたい場合、各並行処理内で失敗した時にrejectメソッドを呼ぶようにします。

```js:sample1.js
//並行処理１(失敗)
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log("promise1");
        reject();
    }, 2000)
});
//並行処理２
const promise2 = new Promise((resolve, reject) => {
    console.log("promise2");
    resolve();
});

Promise.all([promise1, promise2]).then(() => {
    console.log("done");
}).catch(() => {
    console.log("error");
});
```

上記を実行すると、errorが出力されます。

```
promise2
promise1
error
```
並行処理のうち、一つでも失敗（reject）すると、Promise.allのcatchブロック内が実行されます。

# catch内実行されても他の並行処理が実行されてしまう
上のサンプルでは二つの並行処理のうち、一つで失敗するパターンですが次は両方失敗するパターンを実行してみます。

```js:sample2.js
//並行処理１(失敗)
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log("promise1");
        reject();
    }, 2000)
});
//並行処理２（失敗）
const promise2 = new Promise((resolve, reject) => {
    console.log("promise2");
    reject();
});

Promise.all([promise1, promise2]).then(() => {
    console.log("done");
}).catch(() => {
    console.log("error");
});
```

すると以下のようになります。

```
promise2
error
promise1
```

並行処理１はsetTimeoutで2秒後にコールバック内の処理が実行されるので、先に並行処理2が実行されます。並行処理２はconsole.log(promise2)が呼ばれた直後にrejectメソッドを呼んでいるので、失敗となります。よって、すぐにPromise.allのcatchブロックが実行されてしまいます。しかし、並行処理１は未だ実行中なので、errorが出力された後にpromise1が出力されます。このように、並行処理のうち一つでも失敗したらcatchブロックが実行されますが、実行中の他の並行処理を待たずに実行されてしまいます。

# resolveでハンドリングする
rejectを呼んでしまうと、待たずに実行されてしまうので、resolveを呼んだ上でエラーハンドリングするようにします。

```js:sample3.js
//並行処理１(失敗)
const promise1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        console.log("promise1");
        resolve(new Error());
    }, 2000)
});
//並行処理２（失敗）
const promise2 = new Promise((resolve, reject) => {
    console.log("promise2");
    resolve(new Error());
});

Promise.all([promise1, promise2]).then((results) => {
    console.log("done");
    const includeError = results.some((result) => result instanceof Error);
    if(includeError){
        console.log("promise error");
    }
}).catch(() => {
    console.log("error");
});
```

すると、並行処理の実行が完了したあとにエラー処理を実行することができます。

```
promise2
promise1
done
promise error
```
iOS11 groupedなtableViewのheightForHeaderInSection heightForFooterInSection がおかしい？

### セクションの高さを変更できない
iOS11対応をしていて、セクションの高さが変わらずハマりました。
解決したのでメモです。

下記のように一番上の高さがなくなるようにしています。

```ruby:Swift4
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return .leastNonzeroMagnitude
    }
```

### 比較
iOS10.3
<img width="200" alt="Simulator Screen Shot - iPhone 6s Plus - 2017-09-23 at 14.35.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/89206/a0fac005-5231-4338-7545-829d94f0860b.png">

iOS11
<img width="200" alt="Simulator Screen Shot - iPhone 8 Plus - 2017-09-23 at 14.35.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/89206/5379741a-6799-ef9d-e3e3-0c2c61669dbe.png">

### 解決方法
下記のメソッドを追加してやることで解決しました。
※今回の場合はviewForFooterInSectionは不要です。Footerの高さを変更する場合に必要です。

```ruby:Swift4
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        return nil
    }

    func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
        return nil
    }
```

下記のようにiOS11でも一番上の高さがなくなりました！
<img width="200" alt="Simulator Screen Shot - iPhone 6s Plus - 2017-09-23 at 14.35.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/89206/fc8b098a-f319-46a3-94b6-c2da0f4a4411.png">


### 最後に
viewForHeaderInSection、viewForFooterInSectionのデフォルトの動きが変わったんですかね、、、？
書いてないとnilを返さなくなった、、、？
詳しい方、おられましたら教えてください。
APPTVRepeater (ESP8266) > ソフトウェア v0.4 > Repeaterとしのて機能は実装完了

```txt:動作確認
- ESP-WROOM-02 (以下、ESP8266)
- ユニーバサル基板実装
- Arduino IDE 1.6.6
- Canon IXY 3
```

開始: [ESP8266 > 検討 > APPTVRepeater > 英語リスニング補助ツール (定数時間の巻き戻し機能)](https://qiita.com/7of9/items/5f20327af0574f80cd6b)

[APPTVRepeater (ESP8266) > ソフトウェア v0.3 > リモコン登録完了](https://qiita.com/7of9/items/f02cde3f1adb3b5180c2)
の続き。

### だいたい5秒程度戻す

LEFT, 待機, PLAYを実行して、だいたい5秒程度戻す。

### コード v0.4

```c:esp8266_170923_APPTVrepeater
#include <ESP8266WiFi.h>
#include "AppleRemoteSender.h"

//#define USE_REGISTER // to register to Apple TV at first

/*
 * v0.4 Sep. 23, 2017
 *   - repeat 5 seconds (LEFT and PLAY)
 * v0.3 Sep. 23, 2017
 *   - send keys to register ESP8266 remote controller to Apple TV
 * v0.2 Sep. 23, 2017
 *   - send UP signal to register the remote controller
 * v0.1 Sep. 23, 2017
 *   - turn on/off the IR pin to check the device
 */

static const int kPinIR = 4;

#define KEY_MENU (0x01)
#define KEY_PLAY (0x02)
#define KEY_RIGHT (0x03)
#define KEY_LEFT (0x04)
#define KEY_UP (0x05)
#define KEY_DOWN (0x06)

#define BACK_SEC (5)

void setup() {
  WiFi.disconnect(); // watch dog reset対処
  Serial.begin(115200);
  pinMode(kPinIR, OUTPUT);

  APPTV_setup(kPinIR);
}

static const int keylist[] = {
  KEY_UP,
  KEY_DOWN,
  KEY_LEFT,
  KEY_RIGHT,
  KEY_PLAY, // SELECT
  KEY_MENU,
};

void RegisterController(void)
{
  static int pos = 0;
  
  int size_key = sizeof(keylist) / sizeof(keylist[0]);
  
  delay(2000); // msec

  if (pos >= 0) {
    Serial.println(F("Send Key")); // F() to reduce RAM usage  
    for(int loop=0; loop < 20; loop++) {
      APPTV_SendKey(kPinIR, keylist[pos]);
      delay(100); // msec
    }
    pos++;
    if (pos == size_key) {
      pos = -1;
    }
  }
}

void RepeatSeconds()
{
    static int start = 1;

    if (start != 1) {
      return;
    }
    
    APPTV_SendKey(kPinIR, KEY_LEFT);
    delay(100); // msec

    delay(BACK_SEC * 1000 * 0.38); // msec (0.38: adjusted to 5 seconds interval)
  
    APPTV_SendKey(kPinIR, KEY_PLAY);
    delay(100); // msec

    start = 0;
}

void loop() {
  static int pos = 0;
  int size_key = sizeof(keylist) / sizeof(keylist[0]);
  
  delay(2000); // msec

#ifdef USE_REGISTER
  RegisterController();
#else
  RepeatSeconds();
#endif
}
```

### 実行タイミング

戻したいタイミングで基板の電源(CR123A)を入れる。

起動待ち、LEFT送信、待機、PLAY送信にて、だいたい5秒程度戻る。

起動待ちの分は誤差になる。
このあたりを正確にするには、基板上にスイッチを搭載して、スイッチ押下時に送信、などするといいかもしれない。
(今回は未実施)。

### 実行例

Netflixの
Star Trek: Deep Space 9
にて試してみた。

Vedek Bareil
> I hope you don't mind if I do a little planting while we talk.

上記のようなフレーズを繰り返し聞くことができる。


### 余談

iPad mini4にApple Remoteというソフトをインストールすると、上記のようなことがボタン一つでできるようだ(10秒戻る機能)。

基板実装前に知った。。。
[Survey] Kaggle - Santander 13位解法まとめ

Kaggle - Santander Product Recommendation[^1]の13位解法[^2]の調査記事です．

Title: #13 solution sharing
Author: Sameh Faidi
Kaggle https://www.kaggle.com/c/santander-product-recommendation/discussion/26816

## 特徴量

### 製品関連(24製品)

- 直近3ヶ月間の製品の状態(0,1)
- 追加/削除/変更なし(1,-1,0)
- 先月と同じであった月の数(例: 今が2016年5月で2016年1月〜4月が0なら，4となる)
- 最後の5ヶ月で商品が1かつ0である月の数???

### 顧客関連

- ほぼ全ての数値的またはカテゴリ特徴量(カテゴリ特徴量はONE-HOT表現)
- 特徴量rentaとageでグループ分け(例: 国や週でのrentaの平均値での比率を算出し，年齢層ごとにグループ分け)

### その他

- 月ごと指標(0〜17)と対象月(1〜12)
- パターンを捉えるために前月の商品の小数での表現

## 効果なかったこと．

- 平均や中央値を利用することでデータに対するクリーニングのメリットはなくなった．(Nanを0に書き換えるなどの基本的な動作は除く)
- 特徴量fecha_altaは関係なかった
- EnsemblingやStackingも効果なかった

## 学習

- XGBoostを用いて2015年4月〜6月と2016年3月〜5月の期間で学習

## References

[^1]: Kaggle, [Santander Product Recommendation](https://www.kaggle.com/c/santander-product-recommendation).
[^2]: Sameh Faidi, [#13 solution sharing](https://www.kaggle.com/c/santander-product-recommendation/discussion/26816).
iOS11に上げたら思ってた感じのSSOができなくなった話


## 経緯

全然モバイルアプリ書かんのやけれど、認証情報の受け渡しについて考えるにあたって知っとかなあかんなぁと思って触ってて
SFSafariViewControllerとChrome Custom Tabsの動きは同じ感じって前提でちょっと検証したことを業界外の人向けくらいの内容で簡易まとめ

## iOS11までの動き感

図の感じで正しい表現なのかはさておきイメージ。
アプリ(ポケモンGO)内でGoogleのアカウントを使ってソーシャルログインする場合下図のイメージになるはず

![my1.jpg](https://qiita-image-store.s3.amazonaws.com/0/103725/fd6fdfda-a522-bc16-6317-e4647122d6a6.jpeg)

やりたいこととしては
+ アプリにID/PW等の情報を渡さずに認証したって情報を渡したい
+ Safariで既にGoogleログインしているのであればその情報を使いたい

## iOS11にアップデートしたことによって

ポケモンGOでGoogleでログインボタンを押してもSafariのセッションが使えなかった。

事象としては、図で言うところの紫の枠でセッション情報が共有されなくなったらしい
(SFAuthenticationSessionってやつ使えってことなんやろな。)

やったこととしては、まずサインアウトして

![Signout](https://qiita-image-store.s3.amazonaws.com/0/103725/4c13868b-d387-8197-b4b1-e88fba20486b.jpeg)

Googleでログインのボタンを選択

![IMG_9507.JPG](https://qiita-image-store.s3.amazonaws.com/0/103725/2994a390-56a5-c5f2-32b3-19b4f9259867.jpeg)

Safariではログイン済みやのに、アカウント選択画面に至らない
(当然ながら別のアプリでSFSafariViewControllerでログインしててもここには表示されない)

![IMG_9511.JPG](https://qiita-image-store.s3.amazonaws.com/0/103725/1ae50b71-2c24-d9e1-1dab-d341a30e8232.jpeg)

ちなみに上記画面で右下のSafariマーク押すと、実際にSafari経由で認可要求を送るため、Safariの保持しているセッションでログインできる。

![IMG_9512.JPG](https://qiita-image-store.s3.amazonaws.com/0/103725/0dc36571-8370-1b9b-1ad2-962879fd18ad.jpeg)

## 感想・疑問点

+ iOS11対応前のアプリで起こる現象に出会った
  - ポケモンGO側が予め対応準備してなかったの意外やなぁ
  - なんでAppleはSFAuthenticationSessionとSFSafariViewControllerどっちでも行ける時期を作らんかったんやろ
  - SFAuthenticationSessionの使い方勉強せななぁ
+ あの画面やとID/PW入力したくないよなぁ
  - ホンマにSafariViewControllerなんかなぁって不安が残る
  - ポケモンGOやったらまぁまだ良いけど良からぬアプリにID/PW打ち込むケース出そうやなぁ
  - わかる人は、まだiOS11対応じゃないアプリには右下のSafariボタン押して連携した方が良さそうやなぁ
Xcode9で謎のEXC_BAD_INSTRUCTIONと戦った話

Xcode9に上げたら今まで動いてたコードがEXC_BAD_INSTRUCTION吐いて落ちるようになった.
一時間くらい祈りを捧げた結果分かったことは僕が全面的に悪かったということ.

## 再現コード

```
struct FuckinObject {
	int x;
	FuckinObject &operator=(int x) {
		this->x = x;
	}
};

int main(int argc, char *argv[]) {
	FuckinObject fuck;
	fuck = 666;
	return 0;
}
```

## 何が悪いか

`return *this` してない.

## どうすれば良いか

`return *this` する.

## (追記)もっとどうすれば良いか

<img width="1222" alt="スクリーンショット 2017-09-24 15.20.30.png" src="https://qiita-image-store.s3.amazonaws.com/0/4206/9eab26e7-c3ba-c20e-4ff2-17950e012ecc.png">

この設定をYESにする ( thx: @yumetodo )
APPTVRepeater (ESP8266) > ソフトウェア v0.3 > リモコン登録完了

```txt:動作確認
- ESP-WROOM-02 (以下、ESP8266)
- ユニーバサル基板実装
- Arduino IDE 1.6.6
- Canon IXY 3
```

開始: [ESP8266 > 検討 > APPTVRepeater > 英語リスニング補助ツール (定数時間の巻き戻し機能)](https://qiita.com/7of9/items/5f20327af0574f80cd6b)

[APPTVRepeater (ESP8266) > ソフトウェア v0.1, v0.2 > 上ボタン押下の送信は成功](https://qiita.com/7of9/items/32f5e6cc3d6b47c8757b)
の続き。

### リモコンの登録

Apple TVの
設定 > 一般 > リモコン > リモコンを追加 > 開始
にて
上、下、左、右、SELECT、MENU
を順番に長押しする。

上記のコードを実装した。

### コード v0.3

```c:esp8266_170923_APPTVrepeater
#include <ESP8266WiFi.h>
#include "AppleRemoteSender.h"

/*
 * v0.3 Sep. 23, 2017
 *   - send keys to register ESP8266 remote controller to Apple TV
 * v0.2 Sep. 23, 2017
 *   - send UP signal to register the remote controller
 * v0.1 Sep. 23, 2017
 *   - turn on/off the IR pin to check the device
 */

static const int kPinIR = 4;

#define KEY_MENU 0x01
#define KEY_PLAY 0x02
#define KEY_RIGHT 0x03
#define KEY_LEFT 0x04
#define KEY_UP 0x05
#define KEY_DOWN 0x06

void setup() {
  WiFi.disconnect(); // watch dog reset対処
  Serial.begin(115200);
  pinMode(kPinIR, OUTPUT);

  APPTV_setup(kPinIR);
}

static const int keylist[] = {
  KEY_UP,
  KEY_DOWN,
  KEY_LEFT,
  KEY_RIGHT,
  KEY_PLAY, // SELECT
  KEY_MENU,
};

void RegisterController(void)
{
  static int pos = 0;
  
  int size_key = sizeof(keylist) / sizeof(keylist[0]);
  
  delay(2000); // msec

  if (pos >= 0) {
    Serial.println(F("Send Key")); // F() to reduce RAM usage  
    for(int loop=0; loop < 20; loop++) {
      APPTV_SendKey(kPinIR, keylist[pos]);
      delay(100); // msec
    }
    pos++;
    if (pos == size_key) {
      pos = -1;
    }
  }
}

void loop() {
  static int pos = 0;
  int size_key = sizeof(keylist) / sizeof(keylist[0]);
  
  delay(2000); // msec

  RegisterController();  
}
```

### 登録完了

上記を実行して、登録を完了した。

リモコン名は「ESP8266」とした。
How Kick Start Your Business in the Tax Haven; Labuan

Nobody in this world likes tax procedures, standards and problems that they cause to a business or brand. Moreover, the culture of tax administration and imposition is growing and that in turn augmenting the risk of tax inspections and its hurdles. Though paying taxes regularly is good, as a government or economy operates because of those taxes. But the businesses in many cases have to bear extra burden of taxation because government always try to empty the bucket that is filled more. 

This tax thing is even harder for the businesses that are starting their journey. Suppose, you are starting a <a href="http://www.cstcl.com.my/"><b>Labuan company</b></a>, and a black suited guy comes and tells you that these are the taxation rules and from this time onwards you have to pay this much to so and so government. This course of action can confuse you and can even make you drop the idea of starting a company.

Thus, it a no secret all business and brands look for a reliable tax haven, which means a country or place that have low or zero tax procedures. Such places make it very easy for international businesses to operate. Talking about countries having low taxation policies, there are many countries that come in the mind. But, there is an interesting and alluring jurisdiction that is drawing attraction of business from all around the world and that place is Labuan.

Labuan is an official federal territory of Malaysia. This island of Labuan is literally the tax haven and businesses looking for financial stability and freedom should move here ASAP. The island has a great number of opportunities for business growth, all thanks to financial liberties it offers. Though setting up business here in this island is even easy, firstly the federal standards are not complex plus here some companies that work only to help you in <a href="http://www.cstcl.com.my/"><b>Labuan company setup</b></a>.

One such company is CS Trust that helps you on every step of business formation and operation. Labuan is a great place to start your business in and CS Trust is the best company to take help from. They are well versed with all the local rules and procedures and they have got a team of professional who can guide you with different business procedures. Team of CS Trust is consisting of business professional having strong knowledge litigation, finance, taxation, business management and more.

<b>About CS Trust: </b> 

CS Trust is the name that should pop up in your mind first, when you are starting off you business in Labuan. From Labuan company formation, litigation matters, tax procedures to everything else required in a business.

For more information, visit <a href="http://www.cstcl.com.my/"><b>http://www.cstcl.com.my/</b></a>. <br><br>
エスケープシーケンスのよくわからない挙動

見事にはまった。"\x02A" こんな書き方はしてはいけない。

```c:main.c
#include <stdio.h>
#include <string.h>

int main(void) {
  char s1[] = {0x02, 'A', '\0'};
  char s2[] = "\x02A";
  printf("strcmp(s1, s2) = %d", strcmp(s1, s2));
  return 0;
}
```

勘のいい人は STX, 'A', ... , ETX なんてシリアル通信データがあるのだろうと思うのだろうけど。その通りです。コンパイル時に警告はあるそうですが、私の環境は出ませんでした。

ちなみに裏技は "\x02" "A" と書いて回避します。

参考: [エスケープシーケンス\xhh[2012.08.31]](http://home.a00.itscom.net/hatada/mcc/doc2012/esc01.html)
APPTVRepeater (ESP8266) > ソフトウェア v0.1, v0.2 > 上ボタン押下の送信は成功

```txt:動作確認
- ESP-WROOM-02 (以下、ESP8266)
- ユニーバサル基板実装
- Arduino IDE 1.6.6
- Canon IXY 3
```

開始: [ESP8266 > 検討 > APPTVRepeater > 英語リスニング補助ツール (定数時間の巻き戻し機能)](https://qiita.com/7of9/items/5f20327af0574f80cd6b)

[APPTVRepeater > ハードウェアの準備 > 赤外線送信基板の実装 (x2)と動作確認](https://qiita.com/7of9/items/2d10e4317f3fc3f480ff)
の続き。

### リモコンの登録

Apple TVで赤外線通信の試験を行うには、そのリモコンを登録しないといけないことが分かった。

Apple TVの
設定 > 一般 > リモコン > リモコンを追加 > 開始
にて
上、下、左、右、SELECT、MENU
を順番に長押しする。

この機能を使って、上ボタン押下送信テストをした。

### 上ボタン押下の送信コード

色々情報があったが、以下を送れば良さそう。
(参考: https://en.wikipedia.org/wiki/Apple_Remote の Technical details)

0x87EE790a

上記はそれぞれの値を以下の計算から求めた。

https://ideone.com/lv3G6n

```c
#include <stdio.h>
#include <stdint.h>

#define BIT_VENDOR (11)
#define BIT_COMMAND_PAGE (5)
#define BIT_DEVICE_ID (8)
#define BIT_CONTROL_COMMAND (7)
#define BIT_ODD_PARITY (1)

int calc_oddParity(uint32_t target)
{
	uint32_t temp = target;
	int cnt = 0;
	for(int loop=0; loop<32; loop++) {
		cnt += ((temp & 0x01) > 0);
		temp >>= 1;
	}
	if (cnt % 2 == 0) {
		return 1;
	} else {
		return 0;	
	}
}

void print_32bit()
{
	int vendor = 0x43F; // apple
	int cmdpage = 0x0e; // page for up command
	int devid = 0x79; // device id
	int ctrlcmd = 0x05; // up command
	int odd;
	uint32_t snd;
	
	snd = vendor;

	snd <<= BIT_COMMAND_PAGE;
	snd |= cmdpage;

	snd <<= BIT_DEVICE_ID;
	snd |= devid;

	snd <<= BIT_CONTROL_COMMAND;
	snd |= ctrlcmd;

	snd <<= BIT_ODD_PARITY;

	//snd = 0x101 << 1; // debug

	snd |= calc_oddParity(snd);
	
	
	printf("%x\n", snd);
}

int main() {
	print_32bit();

	return 0;
}
```

```txt:run
87ee790a
```

device idは適当に79とした。

### ESP8266プログラム

```c:esp8266_170923_APPTVrepeater
#include <ESP8266WiFi.h>
#include "AppleRemoteSender.h"

/*
 * v0.2 Sep. 23, 2017
 *   - send UP signal to register the remote controller
 * v0.1 Sep. 23, 2017
 *   - turn on/off the IR pin to check the device
 */

static const int kPinIR = 4;

void setup() {
  WiFi.disconnect(); // watch dog reset対処
  Serial.begin(115200);
  pinMode(kPinIR, OUTPUT);

  APPTV_setup(kPinIR);
}

void loop() {
  static int cnt = 0;
  
  delay(1000); // msec

  //cnt++;
  //if (cnt == 10) {
    Serial.println(F("PLAY")); // F() to reduce RAM usage
    cnt = 0;

    for(int loop=0; loop < 10; loop++) {
      APPTV_Upper(kPinIR);
      delay(100); // msec
    }
  //}
}
```

上記のAPPTV_Upper(kPinIR);の処理は、別のタブにて実装している。
コードが未整備のため、公開向けでないため未掲載。
整理して公開はしたいと思う。

APPTV_Upper()にて0x87ee790aをWikipediaのタイミングにてLSBで送信する。

### 基板の動作確認

[APPTVRepeater > ハードウェアの準備 > 赤外線送信基板の実装 (x2)と動作確認](https://qiita.com/7of9/items/2d10e4317f3fc3f480ff)
で実装した二枚の基板は両方とも動作した。

2.5m程度の距離でも上ボタン押下は認識されている。
リダイレクト時に指定するURLがおかしい

## リダイレクトで想定外の挙動が発生
PRG(Post Redirect Get)パターンのリダイレクト時に発行するGETリクエストがLocationヘッダに指定されたものと違うという事象が発生しました。このため、想定外の挙動を起こしていました。

## 原因はブラウザ(IE)のURL長さ制限
Locationヘッダに指定されていたURLが2083文字を超えていました。IEのURL長さ制限である2083文字を超えていたためにリダイレクト時に指定するURLが別物に置き換えられてしまい、想定外のGETリクエストが発行されていました。
前々処理2：サクサク使うSQL（DBをまとめる ）

# データ処理を可能にする（データベースをまとめる）

全国集計の CSV ファイルを、sqlite に取り込むことができたので、次は、すでに存在する他のデータと、今読み込んだデータを比較するための処理です。データをひとまとめにして扱いやすくする作業です。

# すでに存在しているのデータベースからデータをもってくる

* 今つかっているデータベースtmp.db に他のデータベースのデータを使えるように、データベースのアタッチ（データベースを開けたときに、 メニューのFile から Attach Database ）で追加します。
追加するときには、なんという名前のデータベースにしますかと聞かれるので、適当な名前をいれます。今回は、yc といれておきます。
* ![sb_20170923_9.png](https://qiita-image-store.s3.amazonaws.com/0/48387/a9ad1f70-4ee6-7a7f-e0a7-3c6c448f489e.png)
* 現在つかっている tmp.db に、yc にある ym_custom_latest のテーブルをもってきます。SQl 文:create table ym_custom_latest as select * from yc.ym_custom_latest 新規にテーブルをつくって流し込みます。
* ![sb_20170923_10.png](https://qiita-image-store.s3.amazonaws.com/0/48387/bb765107-d9c4-a80e-2f10-1c7ec301c343.png)
* ym_custom_latest が tmp.db に追加されました。
* ![sb_20170923_11.png](https://qiita-image-store.s3.amazonaws.com/0/48387/6b30231c-1c7f-e2b3-f04e-e517c2115b80.png)