OmniAICreator/Qiita-1.07M huggingface dataset:
健康保険について

# 健康保険について
保険料などについて、資料のメモを示す。
ただし全て、健保側が判断することだから、あくまで参考。

## 健康保険料の計算
月々の給与額を、「標準報酬月額」として計算。これに保険料率を掛ける。
方法は５万８千円から１３９万を５０等分にして当てはめる。
賞与も対象であり、１０００円単位切り捨てた「標準賞与額」に保険料率を掛ける。

## 被扶養者について
- 被扶養者≠扶養家族
- ３親等以内（「祖父母」「父母」「兄弟姉妹」「配偶者」「子供」「孫」）が対象
- 75歳未満
- 被保険者のみに保険料は請求される→被扶養者分保険証は発行されるが、費用は無料。
- 被扶養者に収入がある場合、収入（当年度の年間見込み額）が130万以下であること。同時に、被保険者の1/2の年収であることが最低条件

## 免除の類
- 40-64歳は介護保険料は免除
- 育休の場合は健康保険料自体が免除

## 医療費について
- 付加給付
    - 窓口での支払が2万/月を超えた分の払い戻しあり。
- 高額医療費
    - 月収分の医療費の場合
        - 83万以上の月収は、最大25万ちょい
        - 53万以上の月収は、最大16万ちょい
        - 28万以上の月収は、最大8万
        - 28万以下の月収は、医療費の額にかかわらず最大5.76万
        - 低所得者の場合は、医療費の額にかかわらず最大3.54万
- 出産育児金
    - 出産育児一時金　法定給付42万＋保険組合の付加給付 
    - 出産手当金（出産休業の生活費補填。産前42日〜産後56日。遅延分は別途加味）
- 傷病手当金
    - 傷病手当金は次の条件を満たすことが前提
        1.　業務外の病気怪我の療養　→業務中なら労災に当たる。
        2.　療養のために仕事につけない
        3.　連続して3日以上（4日目から支給）
        4.　給与が支払われないこと。
        5.　正しい療養を受けること（医師の指示を聞くこと）
    - 最大1年と6ヶ月受けられる。
Alexa Skills 開発用ブックマーク

自分用メモ。


# Developer's Console
それぞれ自分のamazonアカウントでログイン必要。
[Alexa Skills Kit 設定画面] (https://developer.amazon.com/edw/home.html)
[Amazon Login 設定画面](https://developer.amazon.com/lwa/sp/overview.html)
[AWS Lambda 設定画面 北米リージョン ](https://console.aws.amazon.com/lambda/home?region=us-east-1#/)
[AWS DynamoDB 設定画面 北米リージョン](https://console.aws.amazon.com/dynamodb/home?region=us-east-1#/)

# References

### Alexa Skills Kitの設定方法

[Alexa Skills Kit Custom Interaction Model Reference](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/alexa-skills-kit-interaction-model-reference)


### Amazon Loginの設定方法

[Alexa Account Linking: 5 Steps to Seamlessly Link Your Alexa Skill with Login with Amazon](https://developer.amazon.com/blogs/post/Tx3CX1ETRZZ2NPC/Alexa-Account-Linking-5-Steps-to-Seamlessly-Link-Your-Alexa-Skill-with-Login-wit)　説明は大変わかりやすいが、この通りやっても動かず。なぜだろう。

### Amazon Loginの設定方法（シンプル）

[HOWTO: Add OAUTH To Your Alexa Smart Home Skill In 10 Minutes](https://www.whizzy.org/2016/12/howto-add-oauth-to-your-alexa-smart-home-skill-in-10-minutes/) このとおりやると認証自体は上手くいったが、リダイレクト先がAmazonなので、せっかく取得したuser_idを自分のシステムで利用できない。リダイレクト先を変えてためしてみる。


### [Master mind](https://www.amazon.com/Mastermind-Text-Messaging-Phone-Calls/dp/B01N0HFLPG/ref=sr_1_1?s=digital-skills&ie=UTF8&qid=1491043385&sr=1-1&keywords=mastermind)のように、Alexa Skillsから3rdPartyのWebサイトにAccount Linkをする方法
[Linking an Alexa User with a User in Your System](https://developer.amazon.com/public/solutions/alexa/alexa-skills-kit/docs/linking-an-alexa-user-with-a-user-in-your-system)


# Github
Amazonの中の人のサンプルスクリプトがNode.jsになりがちなので、Pythonのサンプルコードは超たすかる。ソースを読んで勉強させていただく。
[Python client for Amazon Alexa Voice Service (AVS). ](https://github.com/ewenchou/alexa-client)
pyenvでインストール可能なバージョン一覧を表示する方法

毎回忘れてるのでメモ

## 一覧表示
```bash
pyenv install --list 
```

## 最新バージョン表示
```bash
pyenv install --list | grep -v - | grep -v b | tail -1
```

## 指定バージョンの最新マイナー表示(ex:3.5系)
```bash
pyenv install --list | grep -v - | grep -v b | grep 3.5.* | tail -1
```
Scala勉強はじめました。4

#プログラミングの基本(条件分岐)

- 代入
- 繰り返し
- 条件分岐

がプログラミングの基本でした。
前回までは代入と繰り返しについて勉強してきましたので、今回は条件分岐の書き方について勉強しようと思います。

##if文
参考サイト様

- https://blog.kujira-station.com/201502091690
- http://qiita.com/tanigon/items/96f45b3dcdd15b04cc89

JavaやCのようなbreakを用いた方法で記述しようとしましたが、Scalaではすこし使い方が違うようなので、今回はぽんこつな方法で書いていこうと思います。

```
var x = 0
while(x < 100){
  println("x=" + x)
  x = x + 1
  if(x == 10){
    x = 100
  }
}
```

変数xを用意して、0で初期化(代入)。
while()文では100回までループさせておきながら、xが10になった時点で100を代入し、while()の条件を満たさないようにしています。
if文の書き方はほかのプログラミング言語とほぼ同じ(？)と考えていいのでしょうか。とりあえず現在はこのまま覚えることにします。

実行結果

```
x=0
x=1
x=2
x=3
x=4
x=5
x=6
x=7
x=8
x=9

Process finished with exit code 0
```

##余談。breakを使うには
参考サイト様

- http://qiita.com/tanigon/items/96f45b3dcdd15b04cc89

if文から抜ける方法が先述の通りでいいのか怪しいので、様々なプログラミング言語で用いられるbreakをScalaで使えるように勉強していこうと思います。

###必要なこと

- Breaks ライブラリのインポート

インポートは今日のプログラミング言語ではかなり一般的な手法です。
初心者的には、便利な道具(？)を使えるように準備する、と考えればいいでしょうか・・・

```
import scala.util.control.Breaks

object hoge{
  def main(args: Array[String]): unit = {
    //code here
  }
}
```

これで準備ができました。import文でライブラリをインポートしました。
それでは実際の使い方について見ていきましょう

```
//ライブラリのインポート
import scala.util.control.Breaks

object hoge{
  def main(args: Array[String]): unit = {
    //インスタンスの生成
    val b = new Breaks
    var y = 0
    b.breakable{
      while(y < 100){
        println("y = " + y)
        y = y + 1
        if(y == 10){
          b.break
        }
      }
    }
  }
}
```

インスタンスについてはおいおい説明しましょう。うまくできるかはわかりませんが。
y を0から99まで100回ループできるように準備していますが、if()文でy=10になったときに処理を終了するようにコードを書いています。

実行結果

```
y = 0
y = 1
y = 2
y = 3
y = 4
y = 5
y = 6
y = 7
y = 8
y = 9

Process finished with exit code 0
```

y = 10となった時点で処理が終了するので、y = 9までが表示されていますね。成功です。

##まとめ

- if文の書き方

```
if(条件){コード}
```

- breakの使い方

```
1,ライブラリのインポート
import scala.util.control.Breaks

2,インスタンスの作成
val b = new Breaks

3,コードを書く
b.breakable{
  //code here
  ...
  b.break
}
```

次回はこれまでに勉強したことを使って何かしてみようと思います
IBM Cloud へのアイデアを起票・投票できるサイト

クラウドの機能は、お客様の意見を取り入れながら、日々変わっていくものですが、自分の意見も反映してほしいと思ったことはありませんか？

こんな機能を実現してほしい、あったらぜひ使いたいといった機能やアイデアを投稿できるサイトがあります。
それが、こちらのサイトになります。

>IBM Cloud - Structured Ideas
https://ibmcloud.ideas.aha.io/ideas

みてみると以下のような形のサイトになっています。

<img width="1285" alt="Screen Shot 2017-04-01 at 21.02.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/101361/b10cec57-8118-ee9e-1f94-0c0b76a86495.png">

このアイデアポータルの　詳細は、以下のサイトに詳細が書いてあります。

>Think, write, submit: New ideas portal for IBM Cloud
https://www.ibm.com/blogs/bluemix/2016/10/think-write-submit/

アイデアを投稿すると、製品エンジニアチームに連携されるようですね。上記サイトに書いてある注意事項を確認して、アイデアを起票してみるとフィードバックがあると思いますので、ぜひどうぞ。

>It is an integrated and automated feedback system to connect your ideas with IBM product and engineering teams. This new system will drive faster decisions and deliver better visibility for your ideas.

たとえばこんな感じでフィードバックがあります。重複したアイデアであれば、このように「Duplicate idea」と分類されます。このアイデアはすでにロードマップにあったようで、今年の2Qに予定されているようですね。

<img width="900" alt="Screen Shot 2017-04-01 at 21.33.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/101361/4cb5f70a-d435-404b-bdf0-5604ff060626.png">

他にもどんなアイデアがあるかぜひ確認してみてください！投稿する以外にも気になるアイデアがあった場合は、ぜひ投票してください！特に、多数の投票が入ったアイデアは、実現される可能性が高まります！
begin - end 階層の深さを数えるワンライナー

```
sed -e 's://.*$::' | awk 'BEGIN{d=0} /end *$/{d--} {print d"\t"$0} /begin *$/{d++}' 
```

冒頭の sed はコメントを削除するためで、コメントはスラッシュ２つ(//)という想定です。

例えば、下記のコードを例にします。

``` ii.v
module test;
integer ii;
initial begin
   ii = 0;
   while (ii < 5)
   begin // while-loop
  	$display("ii == %0d", ii);
  	if (ii < 4) begin
        	if (ii == 1 || ii == 3) begin
          	$display("\todd %0d", ii);
          	if (ii == 1) begin
            	$display("\t\tone %0d", ii);
          	end
          	else begin
            	$display("\t\tthree %0d", ii);
          	end
        	end
        	else begin
          	$display("\teven %0d", ii);
          	if (ii == 0) begin
            	$display("\t\tzero %0d", ii);
          	end
          	else begin
            	$display("\t\ttwo %0d", ii);
          	end
        	end
  	end
  	else begin
     	$display("\telse %0d", ii);
  	end
  	ii = ii + 1;
   end // while-loop
end // initial block
endmodule
```

ワンライナーをこんな感じで適用します。

```
cat ii.v | sed -e 's://.*$::' | awk 'BEGIN{d=0} /end *$/{d--} {print d"\t"$0} /begin *$/{d++}' > ii_depth.v
```

結果はこんな感じです。

``` ii_depth.v
0   	module test;
0   	integer ii;
0   	initial begin
1      	ii = 0;
1      	while (ii < 5)
1      	begin
2         	$display("ii == %0d", ii);
2         	if (ii < 4) begin
3               	if (ii == 1 || ii == 3) begin
4                 	$display("\todd %0d", ii);
4                 	if (ii == 1) begin
5                   	$display("\t\tone %0d", ii);
4                 	end
4                 	else begin
5                   	$display("\t\tthree %0d", ii);
4                 	end
3               	end
3               	else begin
4                 	$display("\teven %0d", ii);
4                 	if (ii == 0) begin
5                   	$display("\t\tzero %0d", ii);
4                 	end
4                 	else begin
5                   	$display("\t\ttwo %0d", ii);
4                 	end
3               	end
2         	end
2         	else begin
3            	$display("\telse %0d", ii);
2         	end
2         	ii = ii + 1;
1      	end
0   	end
0   	endmodule
```

**なお、begin や end が行末に配置される書き方である必要があります。**
たとえば、下記のように記述されると、end を認識できずに数がずれます (泣)

```
         end else begin
```

たまたま、そういう書き方にはなっていない対象だったので、これで済みました。

最後に、余談ですが、ii.v は Verilog という言語で以下の実行結果になります。

```
ii == 0
    	even 0
            	zero 0
ii == 1
    	odd 1
            	one 1
ii == 2
    	even 2
            	two 2
ii == 3
    	odd 3
            	three 3
ii == 4
    	else 4
```
Redash on Docker

# 概要
BIツールの[Redash](https://redash.io/)が人気ですね。
利用環境は色々有ります。
今回は、Provision Scriptを実行するDockerfileを作成してサクッと試してみる方法を紹介します。
本格的に利用したくなったら、ホスティングやAWSオープンソース版等を利用してみると良いでしょう。

Dockerfileを作成するのも面倒な人用に、Docker Cloudにイメージをアップしました。
バージョンは、4.0.1+b4038です。

```
$ docker run -d -p 8125:80 maedamikio/redash
```

# 利用環境は色々
## ホスティング
30日間は、無料なので試してみるには十分でしょう。ただ、Liteプランでも3,000円/月ちょっとです。

- 30日間は無料
- Lite $29 / 月
- Startup $99 / 月
- Business $450 / 月

参考
https://redash.io/pricing/

## オープンソース
### AWS
AMIが提供されています。EC2の料金だけ必要ですね。
バージョンは、0.11.1です。

### Google Compute Engine
下記の手順が記載されています。Compute Engineの料金だけ必要ですね。
バージョンは、0.9.1です。

```
$ gcloud compute images create "redash-091-b1377" --source-uri gs://redash-images/redash.0.9.1.b1377.tar.gz
```

### Docker Based Developer Installation Guide
開発者向けの環境です。

以下がインストールされている必要があります。

- Docker
- Docker Compose
- Node.js

そして、下記を実行する必要があります。

```
$ docker-compose up
$ npm install
$ docker-compose run --rm server create_db
$ docker-compose run --rm postgres psql -h postgres -U postgres -c "create database tests"
```

### Developer Installation Guide
開発者向けの環境です。
色々なパッケージのインストールと設定が必要です。ちょっと面倒な感じです。

### Provision Script
下記の環境で動作確認されてます。
バージョンは、2.0.1+b3080です。

- Ubuntu 12.04
- Ubuntu 14.04
- Debian Wheezy

物理サーバやVirtualBox等で仮想サーバを準備して、スクリプトをダウンロード、実行するだけでOKです。

```
$ wget https://raw.githubusercontent.com/getredash/redash/master/setup/ubuntu/bootstrap.sh
$ chmod u+x bootstrap.sh
$ sudo ./bootstrap.sh
```

参考
https://redash.io/help-onpremise/setup/setting-up-redash-instance.html

# Dockerでサクッと試してみる方法
今回は、Provision Scriptを実行するDockerfileを作成して、docker buildします。
あとは、docker runするだけです。

## Dockerfileの作成
Provision Scriptは、物理サーバ等で動作確認されているので、docker buildでは、正常終了しません。そこで下記をDockerfileに加えています。

- 必須パッケージ
- postgresqlとProvision Scriptの同時実行
- redisのゴミファイルの削除
- 関連サービスの同時起動

Dockerfile

```
FROM ubuntu:16.04

RUN apt-get update && apt-get install -y \
    curl \
    postgresql \
    redis-server \
    sudo \
    wget \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN service postgresql start && service redis-server start && curl -sL https://raw.githubusercontent.com/getredash/redash/master/setup/ubuntu/bootstrap.sh | bash

EXPOSE 80

CMD service nginx start && \
    service postgresql start && \
    service redis-server start && \
    service supervisor start && \
    tail -f /dev/null
```

## イメージの作成
結構時間がかかります。コンパイルが多数実行されている様です。

```
$ docker build -t redash .
```

## コンテナの起動
あとは、下記でOKですね。

```
$ docker run -d -p 8125:80 redash
```

# まとめ
なるべく手間をかけずにRedashを試してみる方法を紹介しました。
dockerの1コンテナ1プロセスの原則は守られていません。
本格的に利用する場合は、ホスティングやEC2等の利用を検討しましょう。
ESP8266 (ESP-WROOM-02) に距離センサー(HC-SR04)を繋いで、LPFで滑らかな値出力にしてみた

ESP8266に距離センサー(HC-SR04)を繋いで距離を測るコードを書いてみました。

**※最終的に、このセンサー＆ESP8266は自宅ガレージシャッターの開閉状態をSlackに通知する用途に使う予定**

## パーツについて
HC-SR04は200～400円ぐらいで買える超音波を利用した距離センサーです。
安い！ ⇒ [Amazon(HC-SR04)](http://amzn.to/2ntkMJ1)

ESP8266は[NodeMcu Lua ESP8266 CH340](http://amzn.to/2zoZ2aj)という開発ボードを使っています。
中国から届くのに時間がかかりますが、￥480と激安です。

## 回路について
最初にGPIOとセンサーを直結して動かなくて、調べてみたらこのセンサーは電源に5Vが必要なようです。
開発ボードのUSBの5Vを利用することにします。
センサーの出力(Echo)も5Vなので、3.3VのESP8266につなぐには分圧回路というのが必要とのことで、ネットの情報を参考にしつつ、見よう見まねで組んでみました。
![P5000493.jpg](https://qiita-image-store.s3.amazonaws.com/0/157770/fa38333d-87ae-43f9-5b16-9b8f03d3f0eb.jpeg)

写真の左側にある３連抵抗の部分で、5Vを3.3Vに落としている感じです。
※１個目の抵抗と２個めの抵抗の間から信号を取ると `5V * 2/3 ≒ 3.3V`
![P5000497.jpg](https://qiita-image-store.s3.amazonaws.com/0/157770/044995b1-3a91-9e26-cf7f-f97fd9fd988e.jpeg)

###回路図 っぽいもの
![HC-SR04回路rev3.png](https://qiita-image-store.s3.amazonaws.com/0/157770/9fbb5c0d-a4f0-36cd-28e8-0714331052f2.png)

## 出力を滑らかに　
距離のfloat値をシリアルに書き出してArduino IDEのシリアルプロッタで見てみると、出力がバラついた感じになったので、以前にスマホの加速度センサーの値を整えるのに使ったローパスフィルターの式を入れて滑らかにしてみました。

```
出力値 = a * 前回の出力値 ＋ (1-a) * センサの値

※ aは係数で0.8～0.95とかを指定します。小さいほど反応が良くなり、大きいほど滑らかになります。相反します。
```

グラフ１枚めがローパスフィルター無し、２枚めがローパスフィルター有りです。滑らかになりましたね。

**ローパスフィルター無し**
![Image-lpf-off.png](https://qiita-image-store.s3.amazonaws.com/0/157770/899e7eb2-304d-160a-c197-7daab986ecbb.png)

**ローパスフィルター有り**
![Image-lpf-on.png](https://qiita-image-store.s3.amazonaws.com/0/157770/d9baa687-dc9d-2b65-1ebc-e011c0e780c8.png)


## ソースコード
スケッチは以下です。


``` c:HC-SR04.ino

int Echo = 14;  // Echoピン
int Trig = 15;  // Trigピン

float dstCMb = 0;   // 一回前の距離値

void setup() {
  // シリアル通信を開始
  Serial.begin(115200);
  Serial.println("Serial start.");

  // ピン設定
  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
}

void loop() {

  // trigger
  digitalWrite(Trig, HIGH);
  delay(20); // msec
  digitalWrite(Trig, LOW);

  // echo
  int intervalUS = pulseIn(Echo, HIGH) / 2;   // 超音波の往復の時間を2で割って片道の時間（単位：μsec）にする

  // 時間を距離に変換
  float dstM = (float)intervalUS * 340.0 / 1000.0 / 1000.0;  // センサー出力の値（単位：m）  音速：340m/s(15℃)
  float dstCMs = dstM * 100.0;  // センサー出力の値（単位：cm）
  float dstCM;

  // ローパスフィルターで滑らかにする / 外れ値を除外する
  if (dstCMs <= 300.0) {                   // 3mを超えたら外れ値とする
    dstCM = 0.95 * dstCMb + 0.05 * dstCMs; // ローパスフィルター適用
    dstCMb = dstCM;                        // 前回値の保存
    Serial.println(dstCM);                // 距離を出力（単位：cm）
  }else{
    Serial.println(dstCMb);               // 外れ値の場合は前回値を出力
  }
  
}

```


## 参考URL
ESP8266 (ESP-WROOM-02) で距離センサー(HC-SR04)を使う (温度センサーを併用して)
http://qiita.com/exabugs/items/088f3f9229674be9e436

センサの入力などに使うディジタルフィルタ
http://ehbtj.com/electronics/sensor-digital-filter/

*※とっても参考になりました。ありがとうございました。*
モノイド

# Scalaでは

scalaz.Monoid にあり。

- https://www.javadoc.io/doc/org.scalaz/scalaz-core_3/7.3.8/scalaz/Monoid.html
- [独習 Scalaz — Monoid について](https://eed3si9n.com/learning-scalaz/ja/Monoid.html)

# 定義

二項演算子(★)であり、下記の3つの条件が成立すること。

| 条件                    | 式                        |
|-------------------------|---------------------------|
| 演算が閉じていること | ★: (S, S) => S                |
| 結合法則が成立すること    | (a ★ b) ★ c = a ★ (b ★ c) |
| 単位元(e)が存在すること | e ★ a = a ★ e = a         |

更に交換法則 a ★ b = b ★ a が成立すれば可換モノイド。

- マグマ：演算が閉じている
- 半群：演算が閉じている＋結合法則が成立

# 例

| 二項演算子(★) | 演算子の定義域 | 単位元(e) | 可換 |
|------------|----------------|----------|------|
| +          | Doubleなど     | 0        |○|
| *          | Doubleなど     | 1        |○|
| 行列積     | 正方行列など   | 単位行列     |×|
| and         | Boolean        | true     |○|
| or         | Boolean        | false    |○|
| xor        | Boolean        | false    |○|
| ∩          | Set            | 全体集合 |○|
| ∪          | Set            | 空集合   |○|
| +          | String         | ""       |×|
| ++ | List | List() |×| 
| max        | Doubleなど     | -∞       |○|
| min        | Doubleなど     | +∞       |○|
swift3.0 httpで取得したjsonをNSArrayに変換する

httpで取得したJSONをNSArrayに変換するのに手間取ったのでメモ

誤りの例から

``` 誤.swift
    var defaultArr: [String] = []
    url = URL(string: "http://clients1.google.com/complete/search?hl=ja&ds=yt&client=firefox&q=\(keyword_encode)")

    let request: httpRequest = httpRequest()
        
    request.get(url: url, completionHandler: { data, response, error in
        do {
            let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [NSArray]
                    
            if let strs = json.last as? [String] {
                for str in strs {
                    self.defaultArr.append(str)
                }
            }
以下略
```


``` httprequest.swift
class httpRequest {
    let session: URLSession = URLSession.shared
    
    // GET METHOD
    func get(url: URL, completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) {
        var request: URLRequest = URLRequest(url: url)
        
        request.httpMethod = "GET"
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        request.setValue("applicatoin/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
        session.dataTask(with: request, completionHandler: completionHandler).resume()
    }
以下略
```

> let json = try JSONSerialization.jsonObject(with: d!, options: JSONSerialization.ReadingOptions.allowFragments) as! [NSArray]
ここを通る時にエラーになってしまう。


間違っていたのは文字エンコードをしっかり変換しなかったからでした。
> let dataString = NSString(data: data!, encoding: String.Encoding.shiftJIS.rawValue)
> let d = dataString?.data(using: String.Encoding.utf8.rawValue)


``` 正.swift
    var defaultArr: [String] = []
    url = URL(string: "http://clients1.google.com/complete/search?hl=ja&ds=yt&client=firefox&q=\(keyword_encode)")

    let request: httpRequest = httpRequest()
        
    request.get(url: url, completionHandler: { data, response, error in
        do {
            let dataString = NSString(data: data!, encoding: String.Encoding.shiftJIS.rawValue)
            let d = dataString?.data(using: String.Encoding.utf8.rawValue)

            let json = try JSONSerialization.jsonObject(with: d!, options: JSONSerialization.ReadingOptions.allowFragments) as! [NSArray]
                    
            if let strs = json.last as? [String] {
                for str in strs {
                    self.defaultArr.append(str)
                }
            }
以下略
```
RaspberryPiのIP固定方法

RaspberryPi Jessie のIPを固定する方法をメモしただけの投稿

以下のファイルを変更し，再起動をかけたら変更できた．

/etc/dhcpcd.conf

```
interface wlan0
static ip_address=192.168.11.33/24
static routers=192.168.11.1
static domain_name_servers=192.168.11.1
```
Amazon "Developing Application with the IoT Button" Webiner 受講したメモ

# 受講日
Mar 24 1:00-2:00 AM (JST)
at : 自宅にて



# Documents:
https://aws.amazon.com/iotbutton/enterprise/

https://aws.amazon.com/iot/

https://aws.amazon.com/iot-platform/developer-resources/

# 感想

ダッシュボタンをカスタマイズできる「IoT Button」はAmazon.comで19.99ドルで売られている。
https://www.amazon.com/dp/B01KW6YCIM
だが「海外向けには発送してません」と書かれており悲しい。
悲しみに暮れていたら、オンラインセミナーの紹介リンクがあり、
なんとその日の夜だったので速攻申し込んだのがこのWebiner。
ウェブとセミナーをかけあわせてウェビナーっていうんですね。知らなかった。


日本で実機を手にいれようとしたら、
企業向けの「Enterprise program」なら申し込みを受け付けているが、
会社でやるような予定はございませんし。
https://aws.amazon.com/jp/iotbutton/enterprise/


なお、オンラインセミナーでは、モバイルアプリを使ってテストしてた。
[IoT button mobile app](https://itunes.apple.com/us/app/aws-iot-button/id1178216626?mt=8)
だから実機はなくても開発はできそう。暇で暇でしょうがない時にやってみよう。



## スクショ

![12-IoT.png](https://qiita-image-store.s3.amazonaws.com/0/37773/bc3c22b9-0b7a-b608-b560-86bbb60d244f.png)
IoTボタンからの呼び出しプログラムはLambdaで書く。Alexa Skillsと位置づけが同じ。

![13-IoT.png](https://qiita-image-store.s3.amazonaws.com/0/37773/c3df2a88-0f56-1405-06fd-421bfbc8139c.png)
"Call your mon on Mothers day Button"ってなんだろう..w 母の日にかーちゃんを呼ぶボタン？
WinMerge(Portable版)なのでSendToを作った

WinMerge(Portable版)なので、
SendToに「WinMergeで2つのファイルを比較するプロパティ」をつくった。

(参考)Visual Studioでファイルを比較するにはdevenv /diffにファイル名を指定する
http://tech.surviveplus.net/archives/1186
Pycharmでマクロを使ってみる

Pycharmでマクロを使ってみる

実行後、
Edit＞Macros＞Edit Macros
「Edit Macros Dialog」が出たけど、編集できませんでした。
「macros.xml」を直接直すしか方法がありませんか？

(参考)PyCharmでマクロを使ってみる
http://y0m0r.hateblo.jp/entry/20120414/1334411936
(参考)Editing Macros
https://www.jetbrains.com/help/pycharm/2016.3/editing-macros.html
<参考>私のパソコンの中
C:\Users\***\.PyCharmCE2017.1\config\options\macros.xml
CentOS7.3 に MySQL5.7 をインストールした時のメモ


## 作業環境
+ CentOS7.3
+ いまmariadb5.5が入っている


## 注意点
+ 初回起動時にrootの初期パスワードが自動設定される（後述）
+ MySQL 5.7 からユーザーのパスワードの有効期限がデフォルトで360日になったので注意（後述）

## 参考URL
http://blog.ybbo.net/2016/12/18/install_mysql5-7-by-yum-to-centos7/
https://yoku0825.blogspot.jp/2015/03/mysql-576-mysqlinstalldbmysqld.html
http://weblabo.oscasierra.net/mysql-57-init-setup/


## 以下、手順

### 1. mariadb が入っていたら消す

```sh
# 確認する
rpm -qa | grep maria
mariadb-libs-5.5.50-1.el7_2.x86_64  ← 入ってるとこんなの出る

# 消す
yum remove mariadb-libs ←関連パッケージまとめて消してくれた
rm -rf /var/lib/mysql/
```

### 2. MySQL5.7のインストール
```sh
# インストール
yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
yum install mysql mysql-devel mysql-server mysql-utilities

# 確認
rpm -qa | grep mysql
mysqld --version
```


### 3. 初期化
```sh
mysqld --user=mysql --initialize
```
+ mysql_install_db ではなくなった
+ my.cnf に書いてあるdatadirにファイル群が作成される（ /var/lib/mysql ）
+ datadir自体を削除すれば、初期化をやり直せる（ rm -rf /var/lib/mysql/ ）


### 4. 自動起動にする
```sh
systemctl enable mysqld.service
```

### 5. 起動・終了してみる
```sh
systemctl start mysqld.service
systemctl stop mysqld.service
systemctl restart mysqld.service
```


## 初期rootパスワードについて

### 概要
初回起動時にrootの初期パスワードが自動設定される。
ログに出力されるので確認する。

```sh
grep password /var/log/mysqld.log
```

のちほど mysql_secure_installation で変更する。

### 初期パスワードがわからない、初期パスワードで入れない
※初期パスワードがわからない、初期パスワードで入れない場合は、リセットする
参考URL: http://qiita.com/ksugawara61/items/d8d69b7d57a3afcef980

#### 1. my.cnf の [mysqld]ブロックに skip-grant-tables を追記して、mysqldを再起動

#### 2. rootパスワード変更
```sh
mysql -u root
use mysql
UPDATE user SET authentication_string=password('なんかパスワード') WHERE user='root';
flush privileges;
```

#### 3. my.cnf の [mysqld]ブロックの skip-grant-tables を消して、mysqldを再起動

#### 4. んで、とりあえず入れるようになるが、すぐ変更を求められる
```sh
mysql> なんかやろうとすると...
ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement.
```

#### 5. なので、変更する
```sh
mysql> SET PASSWORD = PASSWORD('なんかパスワード');
```


## 初期設定
### mysql_secure_installation コマンドを実行する
+ rootのパスワード変更
+ anonymous ユーザを削除
+ testデータベースを削除
+ VALIDATE PASSWORD PLUGIN のインストールするか（個人の手元の開発環境ならとりあえず不要）

などを行う

### my.cnf に追記

[mysqld]ブロックに以下を追記

```sh
character-set-server = utf8
default_password_lifetime = 0
```
C言語 ~ 多次元配列のIndexとメモリアドレス

# はじめに
多次元配列のIndexとメモリアドレスについて記載します。
基本的なことですが、よく忘れてしまいます。備忘録です。

# cpu / os / gcc
使用したcpu / os / gccを明記します。

CPU Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz
OS ubuntu-14.04-desktop-amd64
gcc (Ubuntu 4.8.2-19ubuntu1) 4.8.2

# sample code

```c
$ cat test.c
#include <stdio.h>
#define LEN (2)
int array[LEN][LEN];

int main(int argc, char* argv[])
{
    int i,j;
    printf("sizeof(int) = %lu\n", sizeof(int));
    for (i=0; i<LEN; i++) {
        for (j=0; j<LEN; j++) {
            printf("i=%d j=%d, &array[i][j] = %p\n",
                i, j, &array[i][j]);
        }
    }
    printf("-----------------------\n");
    for (i=0; i<LEN; i++) {
        for (j=0; j<LEN; j++) {
            printf("i=%d j=%d, &array[j][i] = %p\n",
                i, j, &array[j][i]);
        }
    }

    return 0;
}

$ gcc test.c && ./a.out
sizeof(int) = 4
i=0 j=0, &array[i][j] = 0x601060
i=0 j=1, &array[i][j] = 0x601064
i=1 j=0, &array[i][j] = 0x601068
i=1 j=1, &array[i][j] = 0x60106c
-----------------------
i=0 j=0, &array[j][i] = 0x601060
i=0 j=1, &array[j][i] = 0x601068
i=1 j=0, &array[j][i] = 0x601064
i=1 j=1, &array[j][i] = 0x60106c
```

上記からわかるようにメモリ上の配置は

> array[0][0] array[0][1] array[1][0] array[1][1]

となります。

# cache memoryの効果

Indexの使い方によってcache memoryが有効に働くかどうかに影響する場合があります。
次のsample codeでは2次元配列のindexを逆にしただけですが処理時間が約2.5倍になりました。

>
1461992715
3605115709
>

```c
$ cat test.c
#include <stdio.h>
#include <stdint.h>

#define LEN  (1024*8)
int array[LEN][LEN];

inline uint64_t RDTSCP()
{
    uint32_t hi, lo, aux=0;
    __asm__ volatile("rdtscp" : "=a" (lo), "=d" (hi), "=c" (aux));
    return ((uint64_t)hi << 32) | lo;
}

int main(int argc, char* argv[])
{
    int i,j,value;
    uint64_t start, end;

    start = RDTSCP();
    for (i=0; i<LEN; i++) {
        for (j=0; j<LEN; j++) {
            value += array[i][j];
        }
    }
    end = RDTSCP();
    printf("%lu\n", end-start);
    start = RDTSCP();
    for (i=0; i<LEN; i++) {
        for (j=0; j<LEN; j++) {
            value += array[j][i];
        }
    }
    end = RDTSCP();
    printf("%lu\n", end-start);

    return 0;
}

$ gcc test.c && ./a.out
1461992715
3605115709
```
shellで配列/変数スコープ

shellで知らなかったことがあったのでメモ

# 配列

配列が作れることを知らなかった
`declare`というビルドインコマンドの`-a`で配列を定義できる

```bash

declare -a array=(hoge fuga moge)

echo ${array[0]}
echo ${array[1]}
echo ${array[2]}
```

```:出力結果
hoge
fuga
moge
```

出来た！✧＼\ ٩( 'ω' )و /／✧

## 引数を配列にする

実行時に引数で与えた値を配列に格納する

```bash
declare -a array=("$@")

for word in ${array[@]}; do
    echo $word
done
```

```:実行結果
$ sh array_read.sh hoge huga moge
hoge
huga
moge
```
出来た


# 変数スコープ
shellはglobal変数しかないと思っていた

`local`というビルトインコマンド(?)を使うことで
変数のスコープを限定することが出来る

```bash
global_val="グローバル変数"

func() {
  global_val_in_func="関数内のグローバル変数"
  local local_val="ローカル変数"
}

func

echo "グローバル変数出力:"$global_val
echo "関数内グローバル変数出力:"$global_val_in_fanc
echo "ローカル変数出力:"$local_val
```


```:実行結果
グローバル変数出力:グローバル変数
関数内グローバル変数出力:関数内のグローバル変数
ローカル変数出力:
```

`local_val`は関数内でしか見ることが出来ない,便利！（？）

## 変数の操作を制限する

変数を読み込み専用にすることも出来る

```bash:
readonly val="読み込み専用だよ！"

echo $val

val="書き込んでみるよ！"

echo $val
```

```:実行結果
読み込み専用だよ！
readonly.sh: line 5: val: readonly variable
```

読み込み専用変数だから書き込めないよ！って怒られる
[Ruby入門] 05. 制御構文（条件分岐、繰り返し処理）

&gt;&gt; 連載の目次は [こちら！](http://qiita.com/prgseek/items/237d02be844534063f1d)

※コメント欄にて、@raccy さんからご指摘頂いた件を補足しておきます。
この記事では、「for文」「if文」「while文」といった表現をしていますが、Rubyでは、それらは「文」ではなく「式」です。
式であるからには、最終的に何かしらの値を返すため、たとえば変数への代入なども可能になります。
（例文は、コメント欄を参照してください）


## 1. 条件分岐

### rubyにおける真偽
rubyでは、「false」と「nil」だけが偽となり、それ以外は全て「真」となる

### if文
```ruby
num = rand(1..10); p num
if num.between?(1, 3) then
  puts '1 - 3'
elsif num.between?(4, 6) then
  puts '4-6'
else
  puts '7-10'
end
```
+ then は省略可能


### unless文
```ruby
anm = %w[ねこ いぬ ぱんだ].sample; puts anm
unless anm == "ぱんだ" then
  puts "近所にいっぱいいるよ！"
else
  puts "あんまりいないよ..."
end
```
+ 場面によっては「if !hoge 〜」より文章的でわかりやすいかな。上記の例は微妙だけど。
+ then は省略可能

### 超簡単なifを書きたい（if 修飾子）
```ruby
debug = true
puts("バグってます！") if debug
```
・条件式も実行文も単純ならこの書き方は便利
・こちらにも unless がある

### case文
```ruby
fruits = ["Apple", "Orange", "Lemon", "Grape"].sample; puts fruits
case fruits
when "Apple" then
  puts "甘いけどちょっと食べづらい"
when "Orange","Lemon" then
  puts "柑橘系、酸っぱいよねー"
else
  puts "ぶどう大好き！"
end
```
+ switch とか書かないのね
+ then は省略可能
+ 値を複数パターン拾えるのが特徴（上記のOrangeとLemonのとこ）
+ 判定には === 演算子が使われ、このとき判定の主体（レシーバー）はwhenの直後のオブジェクトになる。これが文字列や数値なら == と同じ

### 条件演算子

いわゆる三項演算子

```ruby
vegeta = ["キャベツ", "きゅうり", "トマト"].sample; puts vegeta
result = (vegeta == 'きゅうり') ? 'きらい' : 'すき';
puts result
```

## 2. 繰り返し処理

### 最初に範囲オブジェクトの話
ruby でよく見る 1..9 みたいな表現。見たままで分かりやすいな

```ruby
r1 = 1..5                   # 終端の値を含む
r2 = 1...5                  # 終端の値を含まない
r3 = Range.new(1, 5)        # 終端の値を含む
r4 = Range.new(1, 5, true)  # 終端の値を含まない
arr = r1.to_a               # 範囲から配列を作成 [1, 2, 3, 4, 5]
```

### while文
```ruby
month = 1
while month <= 12 do
  puts month.to_s + '月: ' + ( (month <= 3) ? 'まだお年玉ある' : 'もう使っちゃった！' )
  month = month + 1;
end
```
+ do は省略可能
+ 条件が偽の間繰り返す until 〜 do 〜 end もある（使うかな...）
+ whileにも、ifみたいに後方に置く簡易な記法があるが、こちらは使い道がないかも...

### for文
```ruby
# for文
for i in 1..3 do
  puts i
end
puts i  #ループ終了後も i が生きているので注意
```
+ for は、rubyではほとんど使われない...
+ forだと、インデックス変数がループ終了後も生きてるの注意
+ このような場合、普通は 後述のイテレータによるループを使う
+ do は省略可能

### each | times | upto | downto メソッドを使ったイテレータによるループ
```ruby
(1..3).each do |i|
  puts i
end

3.times do |i|
  puts i
end

1.upto(3) do |i|
  puts i
end

3.downto(1) do |i|
  puts i
end
```
+ times は 0から始まるインデックス的な値
+ upto | downto は見たままの数値が変数に入るので分かりやすいな
+ このループ方法なら、for文みたいにインデックス変数がループ終了後も生きてるなんてことはない
+ 順番に値を取り出すときは、オブジェクトの succ メソッドが呼ばれる。Integerオブジェクトなら順番が明確だから問題ない。

~~・しつこいけど do は省略可能~~
↑<font color="Blue">間違いです！</font>
doブロックを渡すものなので、省略できません！


### そのまんまな loop メソッド
```ruby
i = 1
loop {
  if (i > 5) then break end
  puts i
  i = i + 1
}
```
+ break 必須だね


### ループを途中で抜けたり次に進んだりやり直したり...
break
next
redo
を使う。continueじゃないよ。
古いスマホをWi-Fiルータにする方法

Wi-Fiルータの調子がおかしくなって使えなくなり、急遽、古いスマホをWi-Fiルータに仕立てたので、その方法を書いておきます。

# 今回目指したもの
今回目指したものは以下のようなネットワークです。

```
　｜　光ケーブル
　｜
[ONU/HGW]
　｜
　｜ LANケーブル
　｜
[Ubuntu] (IPフォワーディング)
　｜
　｜ USBケーブル
　｜
[古いスマホ] (USBリバーステザリング、Wi-Fiテザリング、IPフォワーディング)
　｜
　｜ Wi-Fi
　｜
[無線接続機器]
```

今回は、IPアドレスに192.168.99.0/24を使うこととします。

# Ubuntu側の設定
## ADBの導入
ADBは、AndroidをUbuntu側から操作するために必要となります。公式パッケージに存在しているため、以下によりインストール可能です。
```sudo apt install android-tools-adb```

## IPフォワーディングの設定
まずは、IPフォワーディングが出来るようにファイアーウォールを緩めなければなりません。そのため、```/etc/default/ufw```を開き、```DEFAULT_FORWARD_POLICY="DROP"```から```DEFAULT_FORWARD_POLICY="ACCEPT"```へと変更します。その後、```sudo ufw disable && sudo ufw enable```により、ファイアーウォール設定を再読み込みします。

次に、IPフォワーディングを設定します。ここでは取りあえず、IP Masqueradeを使うことにします。

```
sudo -s
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -F -t nat
iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE
```

# 古いスマホ側の設定
## 「開発者向けオプション」の有効化
「開発者向けオプション」の有効化は、PCからUSB経由でAndroid端末を操作するために必要となります。方法については、あちこちに書かれているため割愛。

## root化
スマートフォンで細かなネットワークの設定を行うためにはroot権限が必要となります。そのため、古いスマホはroot権限を取っておく必要があります。なお、一時rootだけでも十分なため、既存ファイルの上書きは不要です。

多くの古い端末 (日本の機種を含む) では、get_essential_address、install_backdoor及びrun_root_shellを使ってrootを取るのが手軽でしょう。方法については、あちこちに書かれているため割愛。

## USBリバーステザリングの有効化
```adb shell```に入り、```run_root_shell```を行ってルートシェルに入り、以下を実行して、USBをRNDISモードにし、ネットワークの設定を行う必要があります。

```
setprop sys.usb.config rndis,adb
setprop net.dns1 8.8.8.8
ifconfig rndis0 192.168.99.1 netmask 255.255.255.0 up
ip route add default via 192.168.99.254 dev rndis0 onlink
```

## IPフォワーディングの設定
古いスマホ側でもIPフォワーディングが必要となります。```adb shell```に入り、```run_root_shell```を行ってルートシェルに入り、以下を実行して、IPフォワーディングを設定します。

```
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -F -t nat
iptables -t nat -A POSTROUTING -o rndis0 -j MASQUERADE
iptables -P FORWARD ACCEPT
```

## Wi-Fiテザリングの設定
Androidの設定より、Androidの標準機能を使ってWi-Fiテザリングを有効にします。なお、この時点では古いスマホのアクセスポイントに繋いでも、インターネットに繋がりません。

# 再度Ubuntu側の設定
最後にUbuntu側でゲートウェイのIPアドレスを設定します。

```
sudo -s
ifconfig usb0 192.168.99.254 netmask 255.255.255.0
```

なお、こちらではUSB接続が不安定なためかIPが安定しないため、以下のようなハックを使っています。より良い方法募集中。

```
while [ true ] ; do ifconfig usb0 192.168.99.254 netmask 255.255.255.0 ; sleep 1 ; done
```

# 終わりに
時間がかかると思われたroot化はすんなりと行き (開発者のfi01さん感謝！)、ネットワーク周り (特にNetwork Manager関係) はいつもの通り手間取ってしまいましたが、なんとか動かすことが出来て良かったです。

なお、今のところ実用レベルにはなっていますが、繋ぎとしての利用しか考えていないため、2段NAPTなどの微妙な点を放置しているので注意してください。本格的に使うのであれば、スマートフォンにMicro-USB/有線LAN変換アダプタを繋いでフォワーディングを一段減らすと良いかと思います (充電はドックから。速度は100Mbpsに落ちるはず)。
DynamoDB セカンダリインデックス 

DynamoDBに関する基本的な内容をまとめてみたものです。DynamoDBに関する、Web上にすでにある良識な解説コンテンツをまとめたサイトの抜粋です。
[セカンダリインデックス] (https://www.techcrowd.jp/dynamodb/secondaryindex/)

# [DynamoDBがサポートする2種類のセカンダリインデックス] (https://www.techcrowd.jp/dynamodb/secondaryindex/)
テーブル内のデータに効率的にアクセスするため、DynamoDB はPrimary Key属性用にインデックスを作成して維持します。このため、アプリケーションはPrimary Keyの値を指定することで、迅速にデータを取得する ことができます。

しかし多くのアプリケーションでは、Primary Key以外の属性を使って、データに効率的にアクセスできるようにするセカンダリ（または代 替）キーを 1 つ以上設定することで、メリットが得られることがあります。これに対応するために、1 つのテーブルで 1 つ以上のセカンダリインデックスを作成して、それらのインデックスに対してクエリリクエストを実行することができます。

DynamoDB では、次の 2 種類のセカンダリインデックスをサポートしています。

###グローバルセカンダリインデックス
テーブルとはパーティションキーまたはパーティション/ソートキーが異なるインデックスです。グローバルセカンダリインデックスは、インデックスに関する クエリが、すべてのパーティションにまたがり、表内のすべての項目を対象とする可能性があるため、「グローバル」と見なされます。

###ローカルセカンダリインデックス 	
テーブルとパーティションキーは同じですが、ソートキーが異なるインデックスです。ローカルセカンダリインデックスは、ローカルセカンダリインデックスの すべてのパーティションの範囲が、同じパーティションキーを持つテーブルパーティションに限定されるという意味で “ローカル” です。

セカンダリインデックスは、スパース型オブジェクトとして、DynamoDB が自動的に保持します。

項目は、インデックスの定義元のテーブル内に存在する場合のみ、表示されます。このため、インデックスに対するクエリは非常に効率的に実行されます。これは、インデックス内の項目数が、大抵の場合、テーブル内の項目数と比べて非常に少ないためです。

# [グローバルセカンダリインデックス] (https://www.techcrowd.jp/dynamodb/secondaryindex/)
グローバルセカンダリインデックスは、Hash keyの代わりとなります。

グローバルセカンダリインデックスは、多数の異なる値が存在する属性間の関係を追跡する場合に特に便利です。例えば、テーブルのプライマリパーティションキーとして CustomerID を、グローバルセカンダリインデックスのパーティションキーとして 郵便番号を持つ DynamoDB テーブルを作成することができます。

郵便番号は多数存在し、お客様の数も多数存在します。Primary keyを使用して、任意のお客様に対するデータ項目をすばやく取得することができます。グローバルセカンダリインデックスを使用すると、特定の郵便番号の地域内に住んでいるすべてのお客様に対して、効率的なクエリを 実行することができます。

1テーブル当たり、最大で５つのグローバルセカンダリインデックスを作成することができます。

# [ローカルセカンダリインデックス] (https://www.techcrowd.jp/dynamodb/secondaryindex/)
ローカルセカンダリインデックスは、Range key以外の絞り込み検索におけるキーとして利用するものです。

ローカルセカンダリインデックスを使用しない 場合は、多数の項目を取得し、結果をフィルタリングする必要がありますが、ローカルセカンダリインデックスを使用すると、一般的なクエリを簡単にコスト効率のよい方法で実行できます。つまり、アプリケーションには、より幅広い属性をベースにした、より柔軟なクエリを行うことができます。

グローバルとローカルのセカンダリインデックスはどちらも、クエリの柔軟性を向上させます。

ローカルセカンダリインデックスが特定のパーティションキーの値に関連付けられるのに対して、グローバルセカンダリインデックスはすべてのパーティションキーの値が対象となります。パーティションキーの値が同じ項目は、DynamoDB の同じパーティションを共有しているため、”ローカル” セカンダリインデックスは (同じパーティションに) 一緒に保存される項目のみを対象とします。つまり ローカルセカンダリインデックスの目的は、パーティションキーの値が同じで、ソートキーの値が異なる項目に対してクエリを実行することです。

1テーブル当たり、最大で５つのローカルセカンダリインデックスを作成することができます。

# [セカンダリインデックスを使用する際の注意点] (https://www.techcrowd.jp/dynamodb/secondaryindex/)
・グローバルセカンダリインデックス、ローカルセカンダリインデックスは、便利な機能ですが、スループットやストレージ容量を追加で必要とする

・特にインデックスの数が増えれば増えるほど、書き込みのコストが上がる

・セカンダリインデックスに強く依存するようなテーブル設計になるようであれば、そもそもRDBで要件を満たしたほうがよいのではないか、検討してみるのが望ましい
brainf*ck


rustの練習がてらbrainf*ckを実装してみた
~~簡単すぎて練習にならなかったのは内緒~~

```rust
use std::env;
use std::io;
use std::io::Read;
use std::u16;
use std::char;

fn main() {
  let mut args = env::args();
  if args.len() != 2 {
    println!("usage: <expr>");
  }
  else {
    brainfuck(args.nth(1).unwrap());
  }
}

fn brainfuck(text: String) {
  let bytes = text.as_bytes(); // 扱いやすいように[u8]へ変換
  let mut pos: usize = 0; // プログラムの位置
  let mut pointer: usize = 0; // brainfuckが保持するポインタ
  let mut values: [u32; u16::MAX as usize] = [0; u16::MAX as usize]; // brainfuckが保持する配列 

  while pos < bytes.len() {
    match bytes[pos] {

      // ポインタをインクリメント
      b'>' => {
        pointer += 1;
      },

      // ポインタをデクリメント
      b'<' => {
        if pointer > 0 {
          pointer -= 1;
        }
      },

      // ポインタが指す値をインクリメント
      b'+' => {
        values[pointer] += 1;
      },

      // ポインタが指す値をデクリメントする
      b'-' => {
        values[pointer] -= 1;
      },

      // ポインタが指す値を出力に書き出す
      b'.' => {
        if let Some(c) = char::from_u32(values[pointer]) {
          print!("{}", c);
        }
        else {
          print!("?");
        }
      }

      // 入力から1バイト読み込んで、ポインタが指す先に代入する
      b',' => {
        values[pointer] = io::stdin().bytes().nth(0).unwrap().unwrap() as u32;
      }

      // ポインタが指す値が0なら、対応する ] の直後にジャンプする
      b'[' => {
        if values[pointer] == 0 {
          let mut level = 0; // ネストした[]に対応するために使用
          let mut p = pos;

          loop {
            p += 1;

            if bytes[p] == b'[' {
              level += 1;
            }
            else if bytes[p] == b']' {
              if level == 0 {
                pos = p;
                break;
              }
              else {
                level -= 1;
              }
            }
          }
        }
      },

      // ポインタが指す値が0でないなら、対応する [ の直後にジャンプする
      b']' => {
        if values[pointer] != 0 {
          let mut level = 0; // ネストした[]に対応するために使用
          let mut p = pos;

          loop {
            p -= 1;

            if bytes[p] == b']' {
              level += 1;
            }
            else if bytes[p] == b'[' {
              if level == 0 {
                pos = p;
                break;
              }
              else {
                level -= 1;
              }
            }
          }
        }
      },

      // それ以外はエラー
      b => {
        println!("brainfuck unexpect {}", b);
        break;
      }
    }

    // プログラムを進める
    pos += 1;
  }
}
```

# Hello, world!
ちゃんと動いたよ！よかったね！

```
cargo run '+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+.'

Hello, world!
```
DynamoDBのクエリ機能

DynamoDBに関する基本的な内容をまとめてみたものです。DynamoDBに関する、Web上にすでにある良識な解説コンテンツをまとめたサイトの抜粋です。
[DynamoDBのクエリ機能] (https://www.techcrowd.jp/dynamodb/query-2/)

# [DynamoDBでのテーブル操作] (https://www.techcrowd.jp/dynamodb/query-2/)
DynamoDBでよく使われるテーブル操作のオペレーション(API)
- GetItem	Hash keyを条件として指定して、一件の項目(item)を取得
- PutItem	1件の項目(item)を書き込み
- Update	1件の項目(item)を更新
- Delete	1件の項目(item)を削除
- Query	Hash keyとRange keyの複合条件にマッチする項目(item)を取得
- BatchGet	複数のPrimary keyを指定して、マッチする項目(item)を取得
- Scan	テーブルのすべての項目(item)および属性を取得

# [クエリのフィルタリング] (https://www.techcrowd.jp/dynamodb/query-2/)
DynamoDBでは、基本的に、Primary keyもしくはグローバルセカンダリーインデックスからのインデックスキーを使ってアイテムを取得しますが、Primary Keyではない属性でのクエリーフィルタリングもサポートします。

Query機能を呼び出す際に、QueryFilterを含むことができるのですが、 フィルターは、キーベースの取得の後、結果が返される前に適用されます。この方法でのフィルタリングを使うことにより、コードを簡単にし、効率化しつつ、アプリケーションに返されるデータの量を減らすことができます。

Query APIに渡すQueryFilterは1つ以上の条件を含む必要があります。 各条件は、属性名を参照し、比較演算子と一緒に1つ以上の属性値を含みます。通常のブール比較演算子に加えて、文字列マッチのために、CONTAINS、 NOT_CONTAINS、BEGINS_WITH を、範囲チェックのためにBETWEEN、セット内に存在するかを確認するために、INを使用することができます。

# [読み込み整合性] (https://www.techcrowd.jp/dynamodb/query-2/)
DynamoDBにおけるクエリ の結果は通常、「結果整合性のある読み込み「ですが、必要に応じて強力な整合性のある読み込みをリクエストすることもできます。結果整合性のある読み込みには、最近完了した PutItem または UpdateItem オペレーションの結果が反映されない可能性があります

またScan リクエストを発行すると、DynamoDB は結果的に整合性のある読み込みを使用します。つまり、テーブルでスキャンの実行直前に加えられたデータの変更は、スキャン結果に含まれない可能性があります。

データの整合性のあるコピーが必要な場合は、Scan が開始する時間に、ConsistentRead パラメーターを true に設定できます。これにより、Scan が開始する前に完了した書き込みオペレーションがすべて Scan 応答に含められます。これは、 DynamoDB Streams と同時に使用すると、テーブルのバックアップまたはレプリケーションシナリオで役立ちます。

# [クエリおよびスキャンのパフォーマンス] (https://www.techcrowd.jp/dynamodb/query-2/)
Scan オペレーションでは常にテーブル全体またはsecondary indexがスキャンされ、目的の結果を得るために値にフィルタが適用され、基本的に結果セットからデータを削除するステップが追加されます。フィルタによって多数の結果が除外されるようなサイズの大きいテーブルまたはインデックスでは、可能な限り Scan オペレーションを使用しないことをお勧めします。

また、テーブルやインデックスが大きくなるに従って、Scan オペレーションは低速になります。Scan オペレーションでは、リクエストした値に対するすべての項目が調べられるため、サイズの大きいテーブルまたはインデックスでは、プロビジョニングされたスループットが 1 回のオペレーションで枯渇する可能性があります。高速な応答時間を得るには、アプリケーションが Scan ではなく Query を使用できるようにテーブルとインデックスを設計します。

# [並列スキャン] (https://www.techcrowd.jp/dynamodb/query-2/)
デフォルトでは、Scan オペレーションはデータを連続的に処理します。DynamoDB は 1 MB の増分でアプリケーションにデータを返し、アプリケーションは追加の Scan オペレーションを実行して、次の 1 MB 分のデータを取り出します。

スキャンされるテーブルまたはインデックスが大きいほど、Scan の完了に要する時間は長くなります。さらに、シーケンシャルな Scan では、プロビジョニングされた読み込みスループットキャパシティーが完全に利用されない場合があります。DynamoDB がサイズの大きいテーブルのデータを複数の物理パーティションに分散しても、Scan オペレーションでは一度に 1 つのパーティションしか読み込むことができません。そのため Scan のスループットは、単一のパーティションの最大スループットによって制限されます。

これらの問題に対処するために、Scan オペレーションではテーブルまたはsecondary indexを複数のセグメントに論理的に分割して、複数のアプリケーションワーカーがセグメントに対する並列スキャンを行うことができます。並列スキャンを実行するには、それぞれのセグメントに対する Scan リクエスト実行を指示します。
QXcbConnection: Could not connect to display のエラー対処

the author Cyrille Rossant, "IPython Interactive Computing and Visualization Cookbook", Packt Publishing
(邦訳: "IPython データサイエンス クックブック", オライリー・ジャパン刊)
の第1章のカーネルの作成をしたらエラーが出たので、その対処法を書きます。


第1章のカーネルのソースコードは[こちら](https://github.com/ipython-books/cookbook-code/blob/master/notebooks/chapter01_basic/06_kernel.ipynb
)です。([ライセンス](https://github.com/ipython-books/cookbook-code/blob/master/LICENSE.txt))
ちなみにこのカーネルは`y=f(x)`の形式の関数を描画します。

##環境
- host: Windows 10
- guest: CentOS 7
- Jupyter 4.2.1

#エラーの内容
CentOS上でjupyter notebookのサーバーたてて、作成したPlotカーネルを使って`y=x`を実行したところ、`QXcbConnection: Could not connect to display`とCentOS上に表示され、dead kernelとなってしまいました。
うまくいけば、ちゃんとグラフが表示されるはずですが・・・

#対処法
スクリプトに下記のコードを追加

```:plot_kernel.py
import matplotlib as mpl
mpl.use('Agg')
```

##実行

![スクリーンショット (4).png](https://qiita-image-store.s3.amazonaws.com/0/173064/2ed338ec-101b-6e6f-03f2-de3ab0e9fb7d.png)

うまくいきました！！



#参考
- http://stackoverflow.com/questions/13336823/matplotlib-python-error
cURLで別ドメインのHTMLファイルを読み込んだときに困ったこと

cURLで別ドメイン上のHTMLファイルを読み込んだら、見事に表示が崩れてしまったので、原因と解決方法をメモします。

## 目的
Webサイトの一部をCMS化するにあたり、CMS上からサイト共通のヘッダーを読み込みたい（共通ファイルは一元管理したい）

## 前提
### サーバー構成
サーバーは複数台構成で、静的サイトとCMSは別のサーバー上にある

|サーバー|リソース|
|:---|:---|
|WEBサーバー|サイト本体（静的ファイル一式）|
|APPサーバー|CMS（PHP製）|

#### 本番環境
* WEBサーバーとAPPサーバーは、同一ドメインでアクセスされる
* リバースプロキシが、URLを元に振り分け処理をする

#### テスト環境
* WEBサーバーとAPPサーバーとでドメインが異なる
* WEBサーバー側に、Access-Control-Allow-Originを設定することで、APPサーバーから共通ファイルを参照できるようにする

### 共通ヘッダーについて
#### 呼び出し方法
* サイト本体からはSSIで読み込む
* CMSからは[cURL](http://php.net/manual/ja/ref.curl.php)で読み込む

```php:cURLでの読み込みを実行する関数
	function executeCurl($url){
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, $url);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
		if(IS_CURLOPT_PROXY_USING) {
			curl_setopt($ch, CURLOPT_PROXY, CURLOPT_PROXY_HOST);
			curl_setopt($ch, CURLOPT_PROXYPORT, CURLOPT_PROXY_PORT);
		}
		$html = @curl_exec($ch);
		curl_close($ch);
		return $html;
	}
```

## 今回困ったこと
テスト環境で、CMS化されているページ（APPサーバー）にアクセスすると、共通ヘッダー内で以下の問題が発生した。

### トラブル1：画像が表示されない、CSSがきいていない
#### 原因
共通ヘッダー内のパスがルート相対のため、APPサーバーを参照していた。
静的ファイルはWEBサーバーにあるため、リンク切れになっていた。

#### 解決方法
HTMLを取得したタイミングで、パスにWEBサーバーのドメインを付与するように修正した。
（＝画像ファイルとscriptを指定するsrc属性と、cssファイルを指定するhref属性の値に、WEBサーバーのドメインを付与）

### トラブル2：リンク先が「404 Not Found」になる
#### 原因
トラブル1を解決するためにパスを補完したことで、リンクが先が全てWEBサーバーを参照するようになってしまった。
CMS化されているページは、APPサーバ上にあるので、リンク切れになっていた。

#### 解決方法
1の変換処理の対象から、aタグは除外するよう修正した。
（＝1の変換対象からa:hrefは除外した）

### トラブル3：WEBフォントだけ読み込まれない
#### 原因
WEBサーバー上のBasic認証が邪魔をしていた。

#### 解決方法
Basic認証を外した。
VagrantfileのShellでdocker-composeが実行出来なくてハマった

VagrantfileのShellで　`docker-compose up` しようとして半日以上ハマったのでメモ。

実際に使っていたVagrantfileはこちら。

```:Vagrantfile
Vagrant.configure("2") do |config|

    # 対象box
    config.vm.box = "centos/7"

    # 外部から接続するIP
    config.vm.network "private_network", ip: "192.168.33.119"

    # CPU,メモリーサイズ
    config.vm.provider "virtualbox" do |vb|
        vb.cpus = 2
        vb.memory = 1024
    end

    # [初回のみ]必要なパッケージのインストール等初期設定
    config.vm.provision "shell", inline: <<-SHELL
        timedatectl set-timezone Asia/Tokyo
        yum install docker
        echo | docker --version
        groupadd docker
        gpasswd -a vagrant docker
        systemctl start docker
        systemctl enable docker
        curl -L https://github.com/docker/compose/releases/download/1.12.0-rc2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
        chmod +x /usr/local/bin/docker-compose
        echo | docker-compose --version
    SHELL

    # CentOS7だと外から接続出来ないバグが発生するらしいので念のため。。。
    # Firewalldが有効だと外部から接続出来ないので常にOffにしておく
    # dockerコンテナがうまく立ち上がらないことがあったので念のため。。。
    # dockerコンテナ起動(初回はイメージ、コンテナ生成も行われる)
    config.vm.provision "shell", run: "always", inline: <<-SHELL
        systemctl restart network
        systemctl stop firewalld
        systemctl restart docker
        docker-compose -f /vagrant/docker-compose/docker-compose.yml up -d
    SHELL

end
```

`vagrant up` を実行すると。。。

```
==> default: /tmp/vagrant-shell: line 10: docker-compose: command not found
==> default: The SSH command responded with a non-zero exit status. Vagrant
==> default: assumes that this means the command failed. The output for this command
==> default: should be in the log above. Please read the output to determine what
==> default: went wrong.
```

docker-composeなんか無いよって言われる。。。

VagrantfileのShellでdocker-composeを実行する記事が結構あるのに。。。

色々試行錯誤した結果、　`/usr/local/bin` がパス通ってないことに気づく！

`docker-compose` を　`/usr/local/bin/docker-compose` に変えて実行してあげたらうまくいきました。

ただ、細かいところは全然わかっていないので是非ご指摘頂けると幸いです。
DynamoDBのデータモデル

DynamoDBに関する基本的な内容をまとめてみたものです。DynamoDBに関する、Web上にすでにある良識な解説コンテンツをまとめたサイトの抜粋です。
[DynamoDBのデータモデル] (https://www.techcrowd.jp/dynamodb/datamodel/)

# [データモデル] (https://www.techcrowd.jp/dynamodb/datamodel/)
DynamoDBのデータモデルは、「テーブル」- 「項目」 – 「属性」。DynamoDBは、スキーマレスなnoSQL DBであり、各テーブルのデータ項目の属性や属性数は同じである必要はありません。

 
###テーブル
	データ項目の集まり。RDBのテーブルがレコード(行)の集まりであるのに対応。

各テーブルにはPrimary Keyが必要。Primary Keyはテーブル内の各項目を一意に識別するので、Primary Keyに指定する属性は全ての項目に存在する必要があります。

###項目
	任意の数の属性で構成。属性の数に制限はないものの、サイズとして400KBを超えることはできません。

###属性
	「属性名」と「値セット」で構成され、データ項目に関連付けられます。

 
# [属性(attirubtes)の型] (https://www.techcrowd.jp/dynamodb/datamodel/)

DynamoDB の各属性には名前と値があります。属性値はスカラー型、セット型、ドキュメント型のいずれかです。スカラー型には、数値(Number)、文字列(String)、バイナリ(Binary)、ブール(Boolean)の4種類があり、セット型には、数値セット、文字列セット、バイナリセットの4種類があります。

DynamoDB では、Key Value (キー値) およびドキュメント型のデータ構造をサポートします。Key Value Storeとは、キーと値を使用して、項目の保存・クエリ・更新するモデルのことで、ドキュメント型とは、JSON、XML、HTMLなどの文書形式の項目の保存・クエリ・更新するモデルのことです。

DynamoDBでは、JSONデータ型をサポートするわけではありませんが、文書SDKを使用してJSONデータを直接DynamoDBに渡すことや、AWSマネジメントコンソールを使用してJSON文書を表示・編集することができます。

 
# [テーブルのPrimary Keyの持ち方] (https://www.techcrowd.jp/dynamodb/datamodel/)
テーブル内の項目の属性に必要なのはPrimary Keyのみで、Primary Keyが各アイテムを一意的に識別します。  DynamoDB のテーブルのPrimary Keyの持ち方には2種類あります。

 
- Hash key 	必須 	単体でPrimary Keyとして利用可能。順序を指定しないハッシュインデックスを構築するためのキー
- Range key 	オプショナル 	Hash key & Range key でPrimary Keyとして利用することも可能。同一のHash keyでのデータの並び方を保証するためにRange keyを使う
std::vectorから一定間隔で各要素へのポインタを取得する

# やりたいこと

元々は，二次元配列を使用しているコードが既にあった時に，できるだけクライアントコードの変更を少なくしつつ，一次元配列によるエミュレートに入れ変えたかった．
例えば，`int64_t a[N][M];`みたいな定義があった時に，`a`を関数に渡したり，`a[i][j]`で参照したりしているので，これら構文に対応しつつ，エミュレートするようなクラスの型に`a`を変える．

いわゆるwork aroundのコードなので，正直に言って，bad know-howな気がする．
あまり真似しない方が良いと思う．

アドホックにコードを書くのは面倒なので，`std::vector`は多くの場合において用意できることが期待できるので，これがあった時，一定の間隔で各要素へのポインタの列を取り出すコードを書くことにした．

# コード

```c++
#include <iostream>
#include <vector>
#include <cstdint>

#include <boost/range/algorithm/copy.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/adaptor/strided.hpp>
#include <boost/range/adaptor/transformed.hpp>

namespace impl {
template<class OutVec, class InVec>
void getPtrs(OutVec& ovec, InVec& vec, const int step = 1) {
	auto getPtr = [&](auto x) { return vec.data() + x; };
	boost::copy(boost::irange(static_cast<decltype(vec.size())>(0), vec.size())
		| boost::adaptors::transformed(std::ref(getPtr))
		| boost::adaptors::strided(step),
		std::back_inserter(ovec));
}
}

template<class T>
auto getPtrs(const std::vector<T>& vec, const int step = 1) {
	using ptr_type = typename std::add_pointer<typename std::add_const<T>::type>::type;
	std::vector<ptr_type> ptrs;
	impl::getPtrs(ptrs, vec, step);
	return ptrs;
}

template<class T>
auto getPtrs(std::vector<T>& vec, const int step = 1) {
	using ptr_type = typename std::add_pointer<T>::type;
	std::vector<ptr_type> ptrs;
	impl::getPtrs(ptrs, vec, step);
	return ptrs;
}

int main() {
	{
		auto ir = boost::irange(0, 100);
		const std::vector<uint64_t> a(boost::begin(ir), boost::end(ir));
		auto b = getPtrs(a, 16);
		boost::copy(b, std::ostream_iterator<decltype(b)::value_type>(std::cout, " "));
		std::cout << std::endl;
		for (auto&& x : b) {
			std::cout << x << " = " << *x << std::endl;
		}
		std::cout << b[2][5] << std::endl;
	}
	std::cout << std::endl;
	{
		auto ir = boost::irange(0, 100);
		std::vector<uint64_t> a(boost::begin(ir), boost::end(ir));
		auto b = getPtrs(a, 16);
		boost::copy(b, std::ostream_iterator<decltype(b)::value_type>(std::cout, " "));
		std::cout << std::endl;
		for (auto&& x : b) {
			std::cout << x << " = " << *x << std::endl;
		}
		std::cout << b[3][4] << std::endl;
		b[3][4] = 10;
		std::cout << b[3][4] << std::endl;
	}
}
```
* Wandbox上のコード: https://wandbox.org/permlink/QmqljLS5S9uNCScA