OmniAICreator/Qiita-1.07M huggingface dataset:
Streamでヘッダ行だけスマートに別処理したい

# はじめに

巨大なテキストファイルを読み込むとき、1行目だけ別処理したくなる場合って、ありますよね？？
たとえばCSVファイルの1行目にヘッダが書かれていて、カラム名などを保存しておきたい、とか。

どうやったらスマートに記述できるのか、いろいろ試行錯誤してみました。

ちなみに、ParallelStreamは対象外です。

# 試行錯誤その1　男は黙ってwhile文！

Streamはどこへやら。。

```java
try (BufferedReader reader = Files.newBufferedReader(Paths.get(file))) {
    String line;
    for (int index = 0; (line = reader.readLine()) != null; index++) {
        if (index == 0) {
            System.out.println("Header: " + line);
        } else {
            System.out.println("Body: " + line);
        }
    }
}
```

`(line = reader.readLine()) != null` とか、排除したいですね。
でもメリットはあります。Java7で使える！🌼
レガシーなシステムで制約がある場合は、必然的にこうなるかと思います。

# 試行錯誤その2　思い切ってスキップ

スキップだと、元の要件、満たしていないですね💦
でも、コードはスマートです。。

```java
try (Stream<String> stream = Files.lines(Paths.get(file))) {
    stream.skip(1).forEach(e -> System.out.println("Body  : " + e));
}
```

スキップしてしまうと、スキップした分のデータが取れないのは、困ります。

# 試行錯誤その3　判定を配列で

自前で「ヘッダかどうか」の判定処理を入れるとなると、ラムダ式の外に変数を持たせる必要が出てきます。
ラムダ式の外の変数をラムダ式の中で使用しようとすると、その変数は自動的に `final` になるため、値の上書きができない！
となると、値の書き換えができるように、「配列にする」という策が出てきます。

```java
try (Stream<String> stream = Files.lines(Paths.get(file))) {
    boolean[] firstLine = {true};
    stream.forEach(e -> {
        if (firstLine[0]) {
            System.out.println("Header: " + e);
            firstLine[0] = false;
        } else {
            System.out.println(e);
        }
    });
}
```

わざわざヘッダかどうかを判定するだけのために、配列を導入するのは、意図が違っているので、スマートではないですね。

# 試行錯誤その4　配列がダメならオブジェクトで

`final` な変数になっても、オブジェクトなら中身を書き換えれられる！
ということで、 `AtomicBoolean` の登場です。

```java
try (Stream<String> stream = Files.lines(Paths.get(file))) {
    AtomicBoolean firstLine = new AtomicBoolean(true);
    stream.forEach(e -> {
        if (firstLine.getAndSet(false)) {
            System.out.println("Header: " + e);
        } else {
            System.out.println("Body  : " + e);
        }
    });
}
```

これも用途が微妙に違うので、すっきりしません。無理やり感がにじみ出ています。。
ちなみに、「Atomicを使っているから、ParallelStreamでも対応できるじゃないか」と思われる方もいらっしゃるかもしれませんが、`firstLine` 変数の操作がAtomicなだけであって、本当に最初の1行が最初に `getAndSet` されるかは、定かではありません（と思っています）。

# 試行錯誤その5　Iteratorに変換

StreamをIteratorにすると、意外と便利かも？

```java
try (Stream<String> stream = Files.lines(Paths.get(file))) {
    Iterator<String> iterator = stream.iterator();
    System.out.println("Header: " + iterator.next());
    while (lineIterator.hasNext()) {
        System.out.println("Body  : " + iterator.next());
    }
}
```

ヘッダ行があるかどうかのチェックは省略していますが、変なオブジェクトとか登場させずに済むので、まだ良い方なんじゃないかと思います。

# 試行錯誤その6　インデックスを付けちゃえ

世の中には便利なライブラリがあるじゃないか！
と、[protonpack](https://github.com/poetix/protonpack)というライブラリを使えば、インデックス付きのストリームができあがります。

```java
try (Stream<String> stream = Files.lines(Paths.get(file))) {
    StreamUtils.zipWithIndex(stream).forEach(e -> {
        if (e.getIndex() == 0) {
            System.out.println("Header: " + e.getValue());
        } else {
            System.out.println("Body  : " + e.getValue());
        }
    });
}
```

インデックスが付いていると、ヘッダ行かどうかだけでなく、応用が利きそう。

# 結論

個人的には、5のIteratorか6のインデックス付与が、スマートな部類かと考えています。
ただ、他にも書き方がある気がしていて、引き続き試行錯誤してみようと思っています。

そもそも、「ストリームで条件分岐すんなや」というのもあるかもしれませんが。。
nginxの設定ミスで起こるMultiline response headers

# はじめに
この記事は下記リンクの日本語翻訳記事です

https://github.com/yandex/gixy/blob/master/docs/en/plugins/addheadermultiline.md

翻訳が誤っている場合はコメントか[@no1zy_sec](https://twitter.com/no1zy_sec)までお知らせいただけると幸いです。

## [add_header_multiline] Multiline response headers
レスポンスヘッダの値を複数行に渡って使用することは避けてください。

### 理由
* これらは非推奨です([RFC 7230](https://tools.ietf.org/html/rfc7230#section-3.2.4))
* いくつかのHTTPクライアントとWebブラウザはRFC 7230を未だにサポートしていません。 (例: IE/Edge/Nginx)

レスポンスヘッダの値を複数行に渡っての使用が原因で起きる脆弱性はこちらの[レポート](https://www.mbsd.jp/blog/20150730.html)が参考になります。

## どうやって見つけるか

設定ミスの例:

```nginx
# http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header
add_header Content-Security-Policy "
    default-src: 'none';
    script-src data: https://yastatic.net;
    style-src data: https://yastatic.net;
    img-src data: https://yastatic.net;
    font-src data: https://yastatic.net;";

# https://www.nginx.com/resources/wiki/modules/headers_more/
more_set_headers -t 'text/html text/plain'
    'X-Foo: Bar
        multiline';
```


## 対策
唯一の解決策は、multiline response headersを使用しないことです。

## 関連リンク
[nginxの設定ミスで起こるHTTP Splitting](https://qiita.com/no1zy_sec/items/fe7c44b5a0fdd4807bbe)
[nginxの設定ミスで起こるSSRF](https://qiita.com/no1zy_sec/items/2718f4a99bb8368ac374)
[nginxの設定ミスで起こるパス トラバーサル](https://qiita.com/no1zy_sec/items/e541f1c838874ff400bb)
[nginxの設定ミスで起こるレスポンスヘッダの出力不備](https://qiita.com/no1zy_sec/items/b786abcba5d796ccc300)
[nginxの設定ミスで起こるreferer/origin検証の問題](https://qiita.com/no1zy_sec/items/93f1efe3c58102807de8)
[nginxの設定ミスで起こるHostヘッダフォージェリ](https://qiita.com/no1zy_sec/items/dfccd91cf76bf73b7754)
[nginxの設定ミスで起こるリファラの検証不備](https://qiita.com/no1zy_sec/items/9d73f4923ebef1598e7d)
mBot で遊ぼう

# mBotとは
mBotとはMakeblock社から販売されている子供のプログラミング学習用ロボットです。

Scratchと呼ばれるビジュアル言語を用いて、ドラッグ＆ドロップでプログラミングができます。

# Scratchの使い方
![mBlock_2018-05-28_23-11_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/a85c7151-9981-6a64-4588-7b41fa0a289b.png)

左側のパンダは**スプライト**と呼ばれるキャラクター画像です。
右側のグレーの領域が作業領域となっており、
中央にあるブロックを右側にドラッグ＆ドロップすることで配置します。
それぞれのブロックには溝や穴が開いており、同じ形のものを近づけるとくっつきます。

くっつけられるブロックをつなげることで様々な処理を表現できます。

## 基本

* 旗をクリックするとスタートするブロック
画面上の旗のボタンをクリックすると動作が開始するブロックです。
![NoName_2018-05-28_23-12_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/9f03ec00-dea1-874c-cdd7-f10c9dc9c61c.png)


* 右に少し動かすブロック
キャラクターを右に少し動かすブロックです。
数字の部分は自由に変えられます。
![NoName_2018-05-28_23-12_01.png](https://qiita-image-store.s3.amazonaws.com/0/122879/1d4678ff-5488-cb48-fac4-d9f5fc9eda7b.png)

* 組合せる
上記2つを組み合わせることで、「旗がクリックされたら、キャラクターが右に少し動く」といった動作が実現できます。
![NoName_2018-05-28_23-13_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/0d7a8b11-1a3d-3400-9703-4d9087c3abaa.png)

* さらに回転を加える
同様にキャラクターを回転させるブロックを繋げます。
これで「旗をクリックされたら、キャラクターが右に少し動きながら少し回転する」という動作になります。
![NoName_2018-05-28_23-13_01.png](https://qiita-image-store.s3.amazonaws.com/0/122879/a6072cce-d7da-1680-ff41-f40c5c68b478.png)

* 繰り返しを加える
これまでは「旗をクリックする」ごとに動作が行われていました。
繰り返しのブロックで囲うことでキャラクターがずっとぐるぐると回転するようになります。
![NoName_2018-05-28_23-14_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/0e1f5470-9f39-685e-17cf-0068bc19456b.png)

* 触ったら止めたい
ずっと回りっぱなしではつまらないので、途中でとめる処理を加えます。
そのためには「〇〇に触れた」というブロックを使います。
![NoName_2018-05-28_23-17_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/3e91d0d5-e591-ce7e-01c7-9e6c6545b0fc.png)

* 条件分岐を追加
「もし～なら」というブロックを使うことで、ある条件に一致した時だけ異なる動作をさせることができます。
![NoName_2018-05-28_23-18_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/be529802-6176-f93a-1ee0-be5e0169e674.png)

* 組合せてみる
全てを組み合わせて
「もしマウスがキャラクターに触れたら、動作を止める」という処理が追加できました。
![NoName_2018-05-28_23-19_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/6c724644-47d0-9711-8b2e-88b668e5a5ec.png)

* ぐるぐる回るパンダが完成！
![scratch_02.gif](https://qiita-image-store.s3.amazonaws.com/0/122879/fe0b370e-aa95-d914-80db-aa7aa02a2de6.gif)


# mBotを制御する


## Scratchで作ったプログラムをmBotに書き込む
![NoName_2018-06-01_00-50_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/1debb585-4e1a-01b4-64ee-dc763cae6ff5.png)

## LEDを光らせる
![NoName_2018-06-01_00-47_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/d08d2de4-5379-8680-8f74-822be234a1a0.png)

## モーターを動かす
![NoName_2018-06-01_00-46_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/eca285a6-6c46-5b50-8887-eb2bf4f989a9.png)

![NoName_2018-06-01_00-52_00.png](https://qiita-image-store.s3.amazonaws.com/0/122879/5f464fca-754a-ce15-fe67-8dd18fb6ecc8.png)

## 距離センサーを使う
![NoName_2018-06-01_00-48_01.png](https://qiita-image-store.s3.amazonaws.com/0/122879/f1b37310-b418-e507-a3d3-01c81c410714.png)

## ライントレースセンサーを使う
![NoName_2018-06-01_00-48_02.png](https://qiita-image-store.s3.amazonaws.com/0/122879/3070c339-63d5-b8be-a5b6-ecb532047bf2.png)


# 練習問題

## ぶつからないロボを作る

## ライントレースロボを作る
はじめてのalpineをvirtualboxにインストール

dockerで死ぬほどお世話になってるalpineをインストールしたことないなということでやってみた

**x84_64.iso** をDL。今日のは113MBだった。

> https://alpinelinux.org/downloads/

virtualboxで入れ物を作る
Linux / Other Linux(64bit) を選ぶ

![スクリーンショット 2018-05-28 23.17.12.png](https://qiita-image-store.s3.amazonaws.com/0/24737/50f1245c-0900-b889-3b6b-e38e9d6c8c25.png)


CDにisoをセットして起動

インストールのはずが `login:` と出るけど、これであってる。

![スクリーンショット 2018-05-28 22.45.30.png](https://qiita-image-store.s3.amazonaws.com/0/24737/61e49151-821c-e1fe-ced0-58e2057c56b7.png)


> https://wiki.alpinelinux.org/wiki/Installation#Installation_Handbook

`root` (パスワードなし）でログインする。

ここからインストーラを起動する

`setup-alpine` を叩いて、質問に答えていく。最初のkeyboardは **jp / jp** を選びました（わたしはvirtualbox on mac)。jp-macを選んだら次のhostnameの入力で豆腐しかく入れられなかったので起動からやり直したよ。

ポイントはdisk(s)を選ぶところで一度 `?` を入力するところ。`? or done` って言われるけど、実はここで `sda` とかdevice名を入力できる。？を見ると認識されているlocal diskが表示される。 `sda` が表示されてたら問題ないので `sda` を入力しましょう。初期化の確認が出るので y で進める。

rootでsshしたい場合はpasswordなしにしないでpassword入れておくとあとで楽。

install終わったら（わたしなんか `ERROR: linux-firmware-20171121-r0 BAD signature` エラー出てたけど終ったは終わったので気にしないことにする）一度 `poweroff` する。

CDをunmountしといて、ここでnetworkがNATしかないことに気付いたのでNIC ブリッジアダプターを追加。

起動して root で login。

networkにつながるようにする

> https://wiki.alpinelinux.org/wiki/Configure_Networking

```py
vi /etc/network/interfaces

auto eth1
  iface eth1 inet dhcp

/etc/init.d/networking restart

ip a   # ip増えたね

# net接続確認とupdate
apk update
apk upgrade 
```

alpineはdebian系ね。

外からつなげるIPができたので、これでsshができます。

```py
vi /etc/ssh/sshd_config

# 良い子は真似しちゃいけない2行を追加
PermitRootLogin yes
PermitEmptyPasswords yes

/etc/init.d/sshd restart
```

これでssh成功しました！

ちなみに一般ユーザで `sudo su -` したら `-ash: sudo: not found` って言われた 笑

今日はここまで。

最後に、シンプルな **/var/log** の画像を。

![スクリーンショット 2018-05-28 23.33.20.png](https://qiita-image-store.s3.amazonaws.com/0/24737/890ecac2-f4ca-b287-1dc5-594f42b7d0c7.png)
"git commit --amend"を"git commit -ammendou"とtypoしたら面倒なことになった

#要旨
・コミットメッセージを修正しようとしたら、typoが原因でcommitされてしまった
・ファイルの中身を変えずに戻したいときは"sudo git reset --soft"

##当時の状況
共用のサーバーで複数人で作業をしており以下みたいな感じで編集されたファイルが溜まっていた。

```bash
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   ore.txt
	modified:   tanin1.txt
	modified:   tanin2.txt
	modified:   tanin3.txt
```
そこで自分が編集したファイル`ore.txt`のみcommitしたが、commitメッセージをミスってしまい、"git commit --amend"と打とうとしたが"git commit -amendou"とtypoしてしまった。

```bash

# git add ore.txt
# git commit -m "俺が編集しししし"
# git commit -ammendou
```
するとエディタが開かれず`Changes not staged for commit`状態のファイルが含まれたcommitが出来ていた！
コミットメッセージを確認すると、

```bash

Date:   Sun May XX XX:XX:XX 2018 +0900

    mendou
```
ううむ、mendou(面倒)だとのことだ。。。。
勝手に他人の編集内容をコミットしてしまった。。。

###何が起きたか？
[git-commit の公式ドキュメント](https://git-scm.com/docs/git-commit)を見ればわかる。
`-a`オプションは編集されたファイルや削除されファイルを自動探知してステージングするオプションだ。
`-m`オプションはコミットメッセージを指定するオプションだ。
すなわち、`-am`までがオプションとして解釈されてしまい、modified状態のファイルが全てステージングされて、`mendou`の部分がコミットメッセージにされてコミットされてしまったのだ。

###対処
実はそこまで面倒ではなく（タイトル詐欺）、ファイルの編集内容を変えずに戻せばよかった。
また、自動でステージングされたファイルがそのままステージングされていたのでresetした。

```bash

# sudo git reset --soft (戻したいコミットID)
# git reset tanin1.txt tanin2.txt tanin3.txt
```

なお、`--soft`のところを`--hard`にするとこいつら"`tanin1.txt tanin2.txt tanin3.txt`"の他人が編集した内容が消えてしまうので注意すること。
Python + Kivy 導入してみた

はじめに
---
初Qiita！という事で、Kivyの導入について書いてみました。
インストールの際、結構躓きポイントが多く、導入がしんどいGUIライブラリです。。。
[Kivy](https://kivy.org/#home)はクロスプラットフォーム対応のPython向けGUIライブラリとなります。 

環境ざっくり（Mac欲しい）
---
* Windows 10 - 64bit
* Python 3.6.4

Kivyに必要なライブラリをpip!
---

cython, pygame, pillowをインストール。

```
pip install cython pygame pillow
```

このままだとkivyでエラーが起きるため、その他必要なライブラリもインストール。
(こちらの issue を[参考](https://github.com/kivy/kivy/issues/3889)にしました。）

```
python -m pip install --upgrade docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew kivy.deps.gstreamer --extra-index-url https://kivy.org/downloads/packages/simple/
```

本命のKivyをpip!
---

下記、そのままコピペで大丈夫です。

```
pip install kivy
```

以上で、導入は完了いたしました。
続いて、Hello World!してみましょう！

Hello world!!
---

下記のファイルを作成して実行すれば表示されるはずです…！
（Wikiの[チュートリアル](https://en.wikibooks.org/wiki/Getting_Started_With_Kivy_Tutorial/Hello_World!)を参考にしました。）

```python:helloworld.py
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label

#importしたAppを用いて、画面作成
class HelloApp(App):

    #画面にHello World!と表示
    def build(self):
        lbl=Label(text='Hello World!')
        return lbl

#Main
if __name__ == '__main__':
    #アプリの起動
    HelloApp().run()
```

実行結果
---
このような感じで表示されたら成功です！

![hello.PNG](https://qiita-image-store.s3.amazonaws.com/0/258186/5e837702-fe15-7ec7-0404-e061ac43a2ac.png)

おわりに
---
依存ライブラリが多く、導入で結構躓いたので、記事にしてみました。
導入部分で、間違い等ありましたらお知らせください。
今後は実際に様々なウィジェットを使った記事を作成できたら、と思います。

参考
---
GitHub Kivy Issues - https://github.com/kivy/kivy/issues/3889
Wiki - Kivy Tutorial - https://en.wikibooks.org/wiki/Getting_Started_With_Kivy_Tutorial/Hello_World!
Dockerコンテナが network ... not found で起動できない場合の対策

docker-composeで指定しているnetworkは存在しているのに、なぜか今まで起動していたコンテナが "network ... not found" のエラーで起動できなくなった。

```
% docker-compose start                 
Starting my_container ... error

ERROR: for my_container  Cannot start service my_container: network ecc448c186c605e2b416fec2434a638f6e9f77811fbb27403d1a2afa5b6d2958 not found
ERROR: No containers to start
```

そんな時は、下記でコンテナをネットワークに繋ぎ直して解決。

```
% docker network connect my_network my_container
```
pecoでnpm-scriptsを超簡単に実行したい

npm scriptsの数が増えると、あのコマンドはなんだっけ？と ` package.json` を開いて確認することも多くなると思います。

その作業がわずらわしくなったのでpecoを使って改善してみました。

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

- [peco](https://github.com/peco/peco)
- [jq](https://github.com/stedolan/jq)

package.jsonを`jq`を使って整形しているため、別途インストールしています。

## インストール
macOSでhomebrewを使用している場合は、以下でインストールできます。

```bash
$ brew install peco jq
```

## 設定
`.bash_profile` に以下のコードを貼り付けます。

```bash:.bash_profile
alias nrun='npm run $(commands | peco)'

function commands () {
  cat package.json | jq -r '.scripts | keys[]'
}
```

alias名はお好みのものを指定してください。

.bash_profileの保存後、 以下のように再読込してください。

```bash
$ source ~/.bash_profile # もしくは exec $SHELL -l
```

## 使い方
コマンドライン上で `package.json` ファイルの配置ディレクトリにて、 aliasに指定したコマンドを入力してください。

npm-scriptsのコマンドが一覧表示されるので、インクリメンタルサーチで絞り込みを行い、目的のコマンドを選択してEnterを押すと実行できます。

![peco-nrun.gif](https://qiita-image-store.s3.amazonaws.com/0/6158/7fb41eb4-63b2-734d-983f-0028d352b72a.gif)
shellの!!を知れ!!

感動的にイカしたコマンドを見つけてしまった!!

`!!`

え!!?　なんだそれ!!?　ってびっくりしてしまうような見た目だが、なんとこれは一つ前のコマンドを表すコマンドなのだ!!

え!!?　すごさがよくわからない!!?

一番簡単な例をあげるぞ!!

例えばコマンドにsudoをつけ忘れた時、どうやり直す!!?

- sudo付けて最初から打つ!!
- `↑` `←`x10000 `sudo`!!
- `ctrl_p` `ctrl_a` `sudo`!!

どれでもいいがもっと簡単でイカした方法があるぞ!!　sudoと強く念じ叫ぶのだ!!

`sudo !!`

するといい感じになるぞ!!

大体こんな感じだ!!

![2018-05-28.png](https://qiita-image-store.s3.amazonaws.com/0/188872/26ae8fb3-ee1e-2972-8296-ee1128dfe8fb.png)
spring boot 複数DBに接続時interceptor無効になるについて

step1

```java
@Import({DataSourceConfiguration.class,PageInterceptor.class})
```

step2

```java
@Autowired
    private PageInterceptor pageInterceptor;
```

step3

```java
sqlSessionFactoryBean.setPlugins(newInterceptor[]{pageInterceptor});
```

step3は「sqlSessionFactoryBean.getObject()」前に書く

原因

```java
sqlSessionFactoryBean.getObject()
```

```java
public SqlSessionFactory getObject() throws Exception {
    if (this.sqlSessionFactory == null) {
      afterPropertiesSet();
    }

    return this.sqlSessionFactory;
}
```

```java
public void afterPropertiesSet() throws Exception {
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
              "Property 'configuration' and 'configLocation' can not specified with together");

    this.sqlSessionFactory = buildSqlSessionFactory();
  }
```

```java
if (!isEmpty(this.plugins)) {
      for (Interceptor plugin : this.plugins) {
        configuration.addInterceptor(plugin);
        if (LOGGER.isDebugEnabled()) {
          LOGGER.debug("Registered plugin: '" + plugin + "'");
        }
      }
    }
```
SQL基本コマンド一覧まとめ

SQLの覚書です。コマンドをど忘れした際などにご利用ください。


# DML(データ操作言語)
## データの検索(SELECT)

```sql
SELECT 列名 [表示用列名] FROM テーブル名; --テーブルから列を抜き出す。表示用の列名は省略可能
SELECT * FROM テーブル名 --テーブルからすべてを選んで表示する
```

列名で四則演算(+, -, *, /)ができる。

```SQL:例
SELECT price * 1.08 FROM price_list;
```

重複を排除して選択(DISTINCT)。

```sql
SELECT DISTINCT 列名 FROM テーブル名;
```

条件指定して抜き出す(WHERE)。

```sql
SELECT 列名 FROM テーブル名 WHERE 条件式;
```

よく使う条件指定。

```sql
列名 IS BETWEEN 値 AND 値 --2つの値の間に含む
列名 IS IN (値, 値, ...) --列挙した中のどれかと一致する
列名 IS NULL --空欄を選択
列名 IS NOT NULL --空欄以外を選択
```

ソート(ORDER BY)

```SQL
ORDER BY 列名 --昇順でソート
ORDER BY 列名 DESC --降順でソート
```


## データの挿入(INSERT)
```SQL
INSERT INTO テーブル名 VALUES (値, 値, ...); --行をテーブルの一番下に挿入する
INSERT INTO テーブル名 (列名, 列名, ...) VALUES (値, 値, ...); --列名を指定して行を挿入
```


## データの変更(UPDATE)
```SQL
UPDATE テーブル名 SET 列名 = 値 WHERE 条件式; --条件と一致する列の値を更新する
```

## データの削除(DELETE)
```SQL
DELETE FROM テーブル名 WHERE 条件式; --条件と一致する行を削除する
```


# DDL(データ定義言語)

## テーブルの作成(CREATE)
```SQL
CREATE TABLE テーブル名 (列名 データ型, ...);
```

## テーブルの変更(ALTER)
```SQL
ALTER TABLE テーブル名 変更操作;
```

よく使う変更操作

```SQL
ADD (列名 データ型) --列を追加
MODIFY 列名 データ型 --データ型や制約を変更
DROP COLUM 列名 --列を削除
ADD 制約 --制約を追加
DROP 制約 --制約を削除
```

## テーブルの削除(DROP)
```SQL
DROP TABLE テーブル名
```



# トランザクション制御文
## 確定(COMMIT)
```SQL
COMMIT;
```

## 取り消し(ROLLBACK)
```SQL
ROLLBACK;
```

## セーブポイント
```SQL
SAVEPOINT 新規セーブポイント名 --新しいセーブポイントの設定
ROLLBACK TO セーブポイント名 --指定したセーブポイントまで戻る
```
Herokuでサンプルアプリケーションを作ってみた

Herokuにアカウントを作成し、サンプルアプリを作成するまでの手順

## ユーザ登録

[Herokuの新規登録ページ](https://signup.heroku.com/jp?c=70130000001x9jFAAQ)
でアカウントを作成。言語はJavaを選択。

メールが来るので、パスワードを設定して完了。

## アプリ作成
Getting Started with Herokuのページでアプリを作成する。
Create New Appをクリック。

任意のAppNameを入力し地域（US or EU）の選択してCreate appをクリック
これでアプリは出来ている。

アプリの管理画面に遷移するため、画面右上のOpen appをクリックする。
作成したアプリが表示される。

URLは以下の通り。自身で指定したAppNameは環境に設定内容によって変わる。
https://[自身で指定したAppName].herokuapp.com/

Heroku | Welcome to your new app!
と表示されていればOK。

と開始から15分程でheroku上にアプリが出来た。
KerasとTensorFlowでCannot interpret feed_dict key as Tensorが出た場合の対応


# 概要
FlaskとKerasを使ってアップロードした画像の識別をするプログラムを動かすと、Cannot interpret feed_dict key as Tensorが出てエラーが出た。

[ここ](https://dev.to/yurfuwa/flask--tensorflow--keras--predict-bnk)にも記載があるが、これはマルチスレッドで動作する場合に、読み込んだモデルが別のスレッドには共有されないため起きる。
[Flask + Tensorflow + Keras で モデルからのpredictが動作しない問題](https://dev.to/yurfuwa/flask--tensorflow--keras--predict-bnk)

load_modelを使って読み込んだモデルは、tf.get_default_graph()を使ってスレッド間で共有できるようにする必要がある。

# 例
```python:修正前
import tensorflow as tf
from keras.models import load_model


@app.route('/', methods=['GET', 'POST'])
def upload_file():
    model = load_model('./sample_model.h5')
    X = data
    result = model.predict(X)
```
X = dataの部分は、使うモデルに合わせて必要な型のデータを準備する。
修正前は、画像がアップロードされたタイミングでモデルを読み込んでいた。これだと１回目のアップロードは問題ないが、２回目以降にCannot interpret feed_dict key as Tensorが発生した。

```python:修正後

import tensorflow as tf
from keras.models import load_model

model = load_model('./sample_model.h5')
graph = tf.get_default_graph()

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    global graph
    with graph.as_default():
        X = data
        result = model.predict(X)
```
修正内容は、モデルの読み込みをプログラム起動時に実施し、そのグラフをgraphに保存しておく。
ファイルアップロード時にはgraph.as_default()でプログラム起動時に保存したグラフを読み込んで処理する。
こうするとアップロード２回目以降も、Cannot interpret feed_dict key as Tensorは発生しなくなった。

# メモ
修正前のプログラムでは、ファイルアップロード時にモデルの読み込みを実施しているので、
問題ないような気がするが、２回目以降のファイルアップロードでエラーが出た。
修正後の方が、モデルのロードは１回で済むのでスッキリするが、なぜ修正前のプログラムでは
エラーとなったのかが、よくわかっていない。
リスト内包表記のネスティング

for文をネスティングできるのと同様に、リスト内包表記もネスティングが可能です。
##for文をネスティングする
program5はfor文をネスティングして、リストlist_1の各要素に対してリストlist_2の要素を１つ１つタプルとして組み合わせます。そしてこの組み合わせたタプルを新しいリストにまとめます。

```python3:program1
"""
for文をネスティングし、2つのリストの要素をタプルとして組み合わせる
"""
list_1 = ['A', 'B', 'C']
list_2 = [3, 2, 1]
union_list = []
for x in list_1:       #外側のネスト
    for y in list_2:   #内側のネスト
        union_list.append((x, y))
print(union_list)
```
結果は

```
[('A', 3), ('A', 2), ('A', 1), ('B', 3), ('B', 2), ('B', 1), ('C', 3), ('C', 2), ('C', 1)]
```

となります。まずは外側のネストでlist_aから’A’を取り出し、list_2の3つの要素3,2,1の順に組み合わせます。次に、同じことをList_aの”B”、”C”について行います。

##リスト内包表記をネスティングする
リスト内包表記でネスティングをするときにはprogram2のようにfor を並記します。

```python3:program2
"""
for文のネスティングをリスト内包表記で表現する
"""
list_1 = ['A', 'B', 'C']
list_2 = [3, 2, 1]
union_list = [(x, y) for x in list_1 for y in list_2]
print(union_list)
```

Program2を実行するとprogram1と同じ結果になります。このことから、リスト内包表記をネスティングするときには、次のとおり前に外側のネスト、後ろに内側のネストを書けばよいことがわかります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/258643/8d1add6d-a22c-9f5d-fe96-1d89b211c792.png)



##ネスティングの順番を入れ替える
ちなみに、program3はprogram1の外側のネストと内側のネストを逆にしたものです。

```python3:program3
"""
for文のネスティングで外側のネストと内側のネストを入れ替える
"""
list_1 = ['A', 'B', 'C']
list_2 = [3, 2, 1]
union_list = []
for y in list_2:       #外側のネスト
    for x in list_1:   #内側のネスト
        union_list.append((x, y))
print(union_list)
```

結果は次のとおりです。

```
[('A', 3), ('B', 3), ('C', 3), ('A', 2), ('B', 2), ('C', 2), ('A', 1), ('B', 1), ('C', 1)]
```

まずは、list_2の3に対してlist_1の要素を順に組み合わせるようにします。したがって、リスト内包表記を使った場合は次のようになります。

```python3:program4
"""
リスト内包表記のネストの順序を入れ替える
"""
list_1 = ['A', 'B', 'C']
list_2 = [3, 2, 1]
union_list = [(x, y) 
              for y in list_2 
              for x in list_1]
print(union_list)
```

for文が2つ続いたので改行したらよいとの指摘を頂きました。解説本でもこのように書いてくれていたら、もっとすんなり理解できたと思います。リスト内包表記は、初心者にはわかりづらいところがありますが、for文と組み合わせるとすっきりするのではないかと思います。
grepで範囲指定して時間を検索する方法

以下のテキストファイルの中から、14:00~14:20の時間帯の行をgrepするにはどうすればいいだろうか。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/260564/33bfac81-7dc4-63da-3e16-8b855e697f9f.png)

正規表現で時間の部分を指定して検索すれば、うまく行く。

＜操作手順＞
1. サクラエディタを開く。
2. ctrl+Gで、「Grep条件入力」画面を開く。
3. 「条件」に、以下の正規表現を入力する。
※\tはTabを意味する。
※「正規表現」にも忘れずチェックをつける

![image.png](https://qiita-image-store.s3.amazonaws.com/0/260564/9b5767fe-ad7f-56c6-66b6-3017bd474b43.png)

4.「検索」を押す。

検索結果として、14:00~14:20の行のみが表示される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/260564/5cee319d-fe3b-fc46-3755-db3efd6a6574.png)
Ubuntuで始めるM5stack 

##目的
UbuntuでM5stackのArduinoIDE開発環境をセットアップする。

##環境
  Ubuntu-14.04.1(x64)
  Arduino IDE 1.8.5

##インストール

###1.Arduino IDEのインストール
[ArduinoのHP](https://www.arduino.cc/en/Main/Software)から、最新のArduino IDE をインストールする。環境に合わせて、Linux 32 bits/Linux 64 bits/Linux ARMのいずれかをダウンロードして解答する。

Linux 64 bitsならば、以下のコマンドを実行するでもよい。

```sh
mkdir ~/M5stack
cd ~/M5stack
wget https://downloads.arduino.cc/arduino-1.8.5-linux64.tar.xz
tar Jxvf arduino-1.8.5-linux64.tar.xz 
```

###2.espressifのインストール


ターミナルを開き、以下のコマンドをコピー＆ペーストして実行する。

```sh
sudo usermod -a -G dialout $USER && \
sudo apt-get install git && \
wget https://bootstrap.pypa.io/get-pip.py && \
sudo python get-pip.py && \
sudo pip install pyserial && \
mkdir -p ~/Arduino/hardware/espressif && \
cd ~/Arduino/hardware/espressif && \
git clone https://github.com/espressif/arduino-esp32.git esp32 && \
cd esp32 && \
git submodule update --init --recursive && \
cd tools && python2 get.py
```


###3.M5stackライブラリのインストール

1.Arduino IDEを起動して、起動する。
 スケッチ -> ライブラリをインクルード -> ライブラリを管理を選択
<img src="https://qiita-image-store.s3.amazonaws.com/0/73020/3b630672-1ff7-4d28-b672-f25ca28f81f5.png" width=50%>

2.検索窓にm5stackと入力する.m5stackが出てきたら、インストールする。
<img src="https://qiita-image-store.s3.amazonaws.com/0/73020/b7702796-7488-f504-cecd-ccb543b6cbc0.png" width=50%>

3.スケッチブック例-> m5stack-> Basic -> Displayを選択し、
　スケッチ-> マイコンボードに書き込むを選択する。
　書き込み、できれば終了。
<img src="https://qiita-image-store.s3.amazonaws.com/0/73020/a55889ad-99c8-ba57-629b-5d3c609f6e39.png" width=50%>


参考：http://www.m5stack.com/assets/docs/
ArduinoとDHT11で温度と湿度を測定する

　MTGで負けすぎて他の趣味として電子工作をはじめてみようと思います。

#準備するもの

#Arduino IDEのセットアップ
公式ページからダウンロード
https://www.arduino.cc/en/Main/Software

シリアルポートにArduinoを指定


###![スクリーンショット 2018-05-28 22.05.16.png](https://qiita-image-store.s3.amazonaws.com/0/188786/efdd89ee-566f-80e8-0f4f-6f10e9fe7db0.png)



#ソースコード

```temp.ino
#include <DHT.h>

const int PIN_DHT = 8;
DHT dht(PIN_DHT,DHT11);

void setup() {
  Serial.begin(9600);
  Serial.println("DHT11");
  dht.begin();
}

void loop() {

  delay(3000);

  float humidity = dht.readHumidity();
  float temperature = dht.readTemperature();

  Serial.print("Humidity:  ");
  Serial.print(humidity);
  Serial.println("%\t");
  Serial.print("Temperature:  ");
  Serial.print(temperature);
  Serial.println(" *C");
}
```

#ライブラリをZIP形式でGitHubから取得
https://github.com/adafruit/DHT-sensor-library
https://github.com/adafruit/Adafruit_Sensor
取得後ライブラリをインストール
![image.png](https://qiita-image-store.s3.amazonaws.com/0/188786/e92c3e80-c297-196d-86f6-663e902206d2.png)


#回路



#動作結果
![スクリーンショット 2018-05-28 22.10.21.png](https://qiita-image-store.s3.amazonaws.com/0/188786/63479600-aac8-3376-5877-2bd0690934f2.png)

#まとめ
次はLineなりTwitterにセンサからの情報を飛ばしたいです。
MacでWordドキュメントをレイアウトを崩さずにPDF化する

　最近は出番がなくなったMicrosoft Wordですが、稀に必要になることがあります。
確認（PDF形式）、印刷、簡単な編集ならWordをインストールしたくないという人たちへ備忘録的な感じではありますがなりますが投稿してみました。
## 解決したいこと
レイアウトを崩さずにWordドキュメントをPDF化したい。
## この解決方法に合うユーザー（どちらかに該当すればOK）
- Adobe Creative Cloud **有料版**ユーザー
- Adobe Acrobat Pro DC **有料版**ユーザー

**注意：WordドキュメントからPDFへの変換はクラウド上での処理になるため、ネット環境が必須です**

## 解決方法
Adobe AcrobatでWordドキュメントを開きPDF化した後、印刷する事で解決しました。
[PDFをWord文書に変換、PDFからWordへのコンバーター | Adobe Acrobat DC](https://acrobat.adobe.com/jp/ja/acrobat/how-to/word-excel-ppt-to-pdf-converter.html)

**iOS版のAcrobatでもPDFへ変換できます。**
[Acrobat Reader ヘルプ（iOS 向け）：他の形式から PDF を作成する](https://www.adobe.com/devnet-docs/rm/ios/acrobatios_jp/create.html)

## 解決するにあたっての条件
- Mac、iPad、iPhoneのいずれかを使用する
- Microsoft Wordをインストールしない（１回限りのために体験版を印刷したくない）
- Wordドキュメントのテキストを編集しない（AcrobatでPDF化後にテキストを追加、編集する事も可能ですが、記入箇所が多い場合やレイアウトによっては面倒です）
- 印刷する際にレイアウトを崩さない（微妙にフォントや改行などズレるのが嫌なだけです）


## 今回のきっかけ
　役所への手続きのため書類を入手したが、一部元ファイルがWord形式でMacのアプリ「プレビュー」で印刷しようとするとレイアウトが崩れてしまい、使える状態ではなかった。


## 解決するまでのプロセス

#### 1. Google DocumentでWordドキュメントを開く
１ページに収まるはずのドキュメントが２ページに分かれてしまう
#### 2. Google Documentで余白などを調整
余白調整で収めようとしたが、２ページに分かれたままになる
#### 3. PagesでWordドキュメントを開く
１ページに収まるはずのドキュメントが２ページに分かれてしまう
#### 4. Pagesで余白を調整
余白調整をすることで収まったが、フォントが変わり罫線の間隔や改行位置などレイアウトが崩れてしまう
#### 5. LibreOfficeでWordドキュメントを開く
　「Pages」と状況は変わらなかった。
#### 6. AcrobatでWordドキュメントを開けることを思い出す
　ふと、Adobe AcrobatでWordドキュメントを開けることを思い出しファイルを開いたところ、フォントもレイアウトも変更なく開ける。

ということで、解決しました笑

## できれば改善して欲しいこと（もし該当する役所の方見ていたらお願いします。）
　Word形式のファイル以外にPDF形式も配布していただければ、印刷することで手書きでも対応できるので改善をお願いしたいです。
Java~String型を使った演算子の注意~

# 1. はじめに
今回は、String型を使った演算子についてです。
ちょっと注意が必要な箇所があるので記事を分けてます。

String型には、いくつかの演算子をそのままの意味では使えないことがあります。
というより、全く別物のように考えてもらっても構わないかと。 

# 2. 注意点

## 2.1. ==演算子
この==演算子を、String 型で使おうとした場合は、大抵思い通りにならないかと思います。 

```java:Main.java
public class Main {
	public static void main(String[] args) {

		String first = "num";
		String second = "num";

		first += "ber";
		second += "ber";

		// first の文字列を表示
		System.out.println(first); // number と出力
		// second の文字列を表示
		System.out.println(second); // first と同じく number と出力

		// first の "number" と second の "number" を比較
		System.out.println(first == second); // false

	}
}
```

今回は、便宜上 "num" で first と second ともに初期化しています。

それから frist と second の両方に "ber" を追加してます。
String型に文字列の追加は、+= で出来ます。

1行目と2行目どちらとも、"number" になっているはず！

3行目に出力されたのは、false だったかと思います。
false ということは、first と second 同じものではないということになります。 

では、String型の文字列が同じであることを確認したいときはどうすればいいか。

String 型で文字列を比較したい場合は、String.equals() というものを使います。
上記の first == second の部分を置き換えた新しいソースをのせておきます。 

```java:Main.java
public class Main {
	public static void main(String[] args) {

		String first = "num";
		String second = "num";

		first += "ber";
		second += "ber";

		// first の文字列を表示
		System.out.println(first); // number と出力
		// second の文字列を表示
		System.out.println(second); // first と同じく number と出力

		// first の "number" と second の "number" を比較
		System.out.println(first.equals(second)); // true

	}
}
```

今回の3行目は true と表示されましたね！
ちょっとややこしいかもしれませんが、String.equals() を使って文字列の比較を行ってください。

## 2.2. + 文字列連結
次に、文字列連結の際の問題です。
文字列と数字を連結させる場合は、+ で連結することができます。

```java:Main.java
public class Main {
	public static void main(String[] args) {

		System.out.println("1 + 2 = " + 3);

	}
}
```

こんな感じで、、
表示されるのは、1 + 2 = 3 となっているはず。

そして、よくあるミスとしては以下のようなソースの時です。

```java:Main.java
public class Main {
	public static void main(String[] args) {

		System.out.println("1 + 2 = " + 1 + 2);

	}
}
```

実行してもらうと、 1 + 2 = 12 と表示されたかと思います。

この時は、左からの演算になり、「"1 + 2 = " + 1」がまず行われます。
この演算結果は、「"1 + 2 = 1"」となり、String 型となってしまいます。

次に、「"1 + 2 = 1" + 2」の演算となり、「"1 + 2 = 12"」が結果となり、これも String 型になってしまいます。 

この時、正常に 1 + 2 = 3 と表示したい場合は、演算の優先順位を変えてあげれば、解決です。
数学の時にも使った ( ) を使いましょう。

```java:Main.java
public class Main {
	public static void main(String[] args) {

		System.out.println("1 + 2 = " + (1 + 2));

	}
}
```

1 + 2 = 3 と表示されれば、バッチリですね！

# 3. おわりに
Stringと演算子を使ったときの注意点を2つだけ載せてみました。

ちなみに他の演算子を使ってみてください。
コンパイルエラーになる演算子が出てくるはず。

今回は、以上です！
いつまでムダな仕事してるの？面談の日程調整をシンプル化するSkettとは

## 働き方改革とかについて
昨今、RPAとか働き方改革とかで仕事がなくなる、とか騒がれていますが、なくなるような仕事ってしたいですか？というのが今回のお話になります。

紹介するツールは「Skett」
残念ながら法人向けで有料なのですが着眼点がおもしろいので紹介します。

## Skettとは？
有料なので使ったことはないのですが、どうもこんな感じで企業と個人の面談日程を調整できるツールのようです。

![skett3.png](https://qiita-image-store.s3.amazonaws.com/0/117147/1f824afa-4196-083c-61a1-f2fd1bbdf306.png)

日時をクリックして終わりです。

表の動きはこれだけですが、裏では採用担当者のカレンダーに予定が自動で入るようです。
シンプルだけど面白いですよね。

こんな触れ込みみたいです。

![skett.png](https://qiita-image-store.s3.amazonaws.com/0/117147/9a0191ee-59e7-0c33-8873-38fb729f3ebc.png)

プランは企業向けなので少しかかります。
個人にしては高いですが企業にしては安いですね。

![skett2.png](https://qiita-image-store.s3.amazonaws.com/0/117147/ca290a01-f9fe-7d2d-f81e-2101591d7578.png)


## まとめ

面談日程の調整はあんまりやったことがないのでわかりませんが、普通の会議の日程調整を考えても大変ですよね、、、日程合わせや担当者が出席できるか確認したり、カレンダー見たり、、、

面談にしても、何百人やそれ以上の規模でやると恐ろしいですよね。
むしろこれまでなんでなかったんだろうというツールでした。


最後に一言言いたいのが、
**「こんな日程調整の仕事って人力で死ぬまでやりたいですか？」**
ということです。

AIこわい、ロボット怖い、仕事が奪われる、と脳死状態で発言している人に言いたいことです。

こういった人間がやる必要のない仕事は、自己実現欲求のないロボットにやらせておけば良いのです。
人間さまはその間にクリエイティブな仕事をするもよし、余暇を楽しむもよし、「より人間らしく」進化するべきではないでしょうか？

ちょっと大きな話になりましたが、この手のツールが集まってくるときっと目指しているビジョンはそういった世界なのかも、と思います。
PlaneNetで画像から深度マップを推定する

PlaneNetは、単一のRGB画像から区分平面深度マップを復元するディープニューラルネットワークです。

## 実行環境

> Ubuntu 16.04.4

> Python 2.7.12

> opencv-python 3.4.1.15

> tensorflow 1.8.0

## ソースコード

> https://github.com/art-programmer/PlaneNet

## 論文

> https://arxiv.org/pdf/1804.06278.pdf

## コンパイルから推定まで

ソースコードをクローンする。

```
git clone https://github.com/art-programmer/PlaneNet.git
```

crfasrnnをコンパイルする。

```
cd PlaneNet/crfasrnn
sh compile.sh
cd ..
```

モデルを学習する際に、損失関数を計算するためにnndistanceをコンパイルする必要がある。ただしmakefileに記述されたtensorflowのパスを、実際に使用するtensorflowのパスに書き換えておく必要がある。

```
cd nndistance
make
cd ..
```

今回はあらかじめ用意された[学習済みデータ](https://mega.nz/#!sjpT2DiQ!Uo-6hxyldmtnPoKk3TTdUHKZADRGy6nIPlmAeVzJs_8)を利用した。PlaneNetフォルダ下にcheckpointフォルダを作成し、checkpointフォルダにダウンロードした学習済みデータを置く。

my_imagesフォルダ下に深度推定したい任意の画像ファイルを置く。

```
python predict.py --customImageFolder=my_images/
```

PlaneNetフォルダ下のpredictフォルダに結果が出力される。

```
0_depth_pred_0.png
0_image.png
0_segmentation_pred_0.png
0_segmentation_pred_blended_0.png
index.html
results_0.npy
```

### 入力画像

![0_image.png](https://qiita-image-store.s3.amazonaws.com/0/178877/7719a45a-b150-98a2-b448-ab4bcde10784.png)

### 平面セグメンテージョン

![0_segmentation_pred_0.png](https://qiita-image-store.s3.amazonaws.com/0/178877/a7c06bbb-192c-18e5-9135-ed2e398f6c45.png)

![0_segmentation_pred_blended_0.png](https://qiita-image-store.s3.amazonaws.com/0/178877/1231bdc4-b556-72e6-c906-819d09d2624b.png)

### 深度マップ

![0_depth_pred_0.png](https://qiita-image-store.s3.amazonaws.com/0/178877/bd9410e7-8dce-97da-8919-e31a29f2cd19.png)
[Ruby]QRコードの生成、埋め込み

# はじめに
Ruby(Rails)でQRコード生成周りを調査したので、なるべく網羅的に知見をまとめておく。
# QRコードとは
参考：[QRコードとは](https://www.keyence.co.jp/ss/products/autoid/codereader/basic2d_qr.jsp)
> 誤り訂正符号（リードソロモン符号）
QRコードの一部分が損傷した場合でもデータを損失することなく、復元することができるようにリードソロモン法を用いて生成された符号のこと。復元率は、シンボルの損傷の度合いに応じた4段階のレベルを持っています。
***
> なお、バージョンとはQRコードの大きさを表し、データ量が増えるとバージョンが大きくなります。（サイズも大きくなります。）

# 導入gem
gem : rqrcode
gem : rqrcode_png
gem : chunky_png 

# サンプルコード
## PNGで保存

```ruby
require 'rqrcode'
require 'rqrcode_png'

content = 'Hello World'
size    = '3'           # 1..40
level   = :h            # l, m, q, h

# QRコードの生成
qr  = RQRCode::QRCode.new(content, size: size, level: level)
png = qr.to_img
#リサイズして保存
png.resize(200, 200).save("#{content}_#{size}_#{level.to_s}.png")
```

参考：[Rubyで簡単にQRコード画像を生成する方法](https://qiita.com/ryosy383/items/c753103c93fa177e4466)

##base64エンコードして表示
```ruby
require 'rqrcode'
require 'rqrcode_png'
require 'chunky_png' # to_data_urlはchunky_pngのメソッド

content = 'Hello World'
size    = '3'           # 1..40
level   = :h            # l, m, q, h

qr = RQRCode::QRCode.new(content, size: size, level: level)
# png変換->リサイズ->base64エンコード
@qr_base64 = qr.to_img.resize(200, 200).to_data_url
```
```erb:ビュー
<img src ="<%= @qr_base64 %>">
```
参考：[Railsでファイル保存をせずにPNGデータとしてQRコード表示](https://qiita.com/sonken625/items/7b49712dd6512394b397)

## SVGで表示

```ruby
require 'rqrcode'
require 'rqrcode_png'

content = 'Hello World'
size    = '3'           # 1..40
level   = :h            # l, m, q, h

#インスタンス変数にSVGとして格納→viewで出力
@qr = RQRCode::QRCode.new(content, size: size, level: level).as_svg.html_safe
```
```erb:ビュー
<%= @qr %>
```
参考：[RailsでQRコードを表示するのがとても簡単だった(rqrcode)](https://qiita.com/shwld/items/eae96518530b39e692ec)


あるいは参考記事のようにアプリケーションヘルパーにメソッドを作ることでアプリケーション全体から共通で呼び出せる。
オプションを指定しない場合、デフォルト値はsize=4, level=":h" 。

```ruby:application_helper.rb
require 'rqrcode'
require 'rqrcode_png'

def qrcode(text, options = {})
    ::RQRCode::QRCode.new(text, options).as_svg.html_safe
end
```
```erb:ビュー
<%= qrcode "Hello world" {size: 3,  level: :h} %>
```

### SVGとは(ざっくり説明)
jpg, pngなどのラスタ形式がpixelごとに情報を持つのに対し、svgはベクタ形式で描画に関する式の集合のようなもので情報を持つ。そのため、画像の拡大縮小・回転が容易であり、いろいろなサイズできれいに描画できる。幾何的な画像に向くが、複雑な画像(風景など)には向いていない。また、環境によっては描画できない([参考](https://caniuse.com/#feat=svg))。

# 実装例
こういう風に実装したらどうだろうという妄想

```ruby:qr_controller.rb
require 'rqrcode'
require 'rqrcode_png'
require 'chunky_png'

def show
  #GETパラメータ受け取り
  request_id = params[:id]
  #
  # ここにrequest_idに一致するQR情報をDBから持ってくる処理を書く
  # qr_dataに格納
  #

  # 見つからなかった場合
  send_data(body: "error.png", style: image/png, disposal: inline) and return
  # 見つかった場合
  qr  = RQRCode::QRCode.new(qr_data.content, qr_data.option)
  png = qr.to_img.resize(200, 200)
  send_data(body: png, style: image/png, disposal: inline) and return
end

# ...
```
QRレコードを作り、コンテンツとオプション、その他フラグなどを管理する。`/qr.png?id=1234`のURIでid=1234のQRコードにアクセスできる。imgタグのsrc属性に指定することでQRコードの埋め込みができる。

# おわりに
モバイルサイトやアプリインストールへの誘導などQRが有効な場面は多いためうまく活用していきたい。
個人的はてなブログ用テンプレ 2018

# 読書ブログ [book review](http://hidenori-t.hatenablog.com) 用のテンプレを更新しました．[^2]
[^2]: [以前のテンプレ](https://qiita.com/hidenori-t/items/1e1b4e5de0342f1da272)


```html:hatena_template.md
<!-- Insert Amazon product -->

☆☆☆ <!-- 本の評価 -->

# なぜ読んだのか
* 


# キーワード
<!-- 5つくらい  -->

* 
* 
* 
* 
* 

# アブストラクト
<!--
1. 目的
2. 結論
3. どのように論が展開されるか
(戸田山　2012, p. 85)
 -->
* 

# サマリー
<!-- 要約  
1. 筆者はどういう問題を立てているか
2. 筆者はそれにどう答えているか
3. 筆者は自分の答えのためにどのような論証をしているか
(戸田山　2012, p. 85)
 -->
*  

>「」(p.)  <!-- 引用  -->
<!-- 感想 -->

<!-- このコメントは引用だけで感想が無い時,次の引用を別のblockquoteタグに入れるためのもの -->

# 主張
* <font color="LightCoral"></font>[^1] (p. )

# 発見
* 

# どう活かすか
* 

<img style="border-width: 0;" src="http://i.creativecommons.org/l/by-nc-nd/2.1/jp/88x31.png" alt="クリエイティブ・コモンズ・ライセンス" />

[^1]: 色の分類は 齋藤孝　『[三色ボールペン情報活用術](http://amzn.to/2AOzlwB)』　角川書店，2003年．を参考

<!--
参考文献
戸田山 和久『[新版 論文の教室 レポートから卒論まで](https://amzn.to/2sgihhq)』NHK出版，2012．
藤井 孝一『[読書は「アウトプット」が99%: その1冊にもっと「付加価値」をつける読み方](http://amzn.to/2kdirQy)』三笠書房，2013，118頁．
-->
```

読書家のみなさんのお役に立てたら嬉しいです:wink::books:

(もしよろしければサポートお願いいたします．wish list: http://amzn.to/343JRQu)

## 参考文献
戸田山 和久『[新版 論文の教室 レポートから卒論まで](https://amzn.to/2sgihhq)』NHK出版，2012．
藤井 孝一『[読書は「アウトプット」が99%: その1冊にもっと「付加価値」をつける読み方](http://amzn.to/2kdirQy)』三笠書房，2013，118頁．
Swiftで整数から2進数文字列が欲しいときは FixedWidthInteger を使おう

ある整数値から2進数でn bitに0埋めした文字列が必要な時があります。

そのような時に、実はAppleの[公式ドキュメント](https://developer.apple.com/documentation/swift/fixedwidthinteger)にこのような実装が記載されていたのでご紹介します。

```swift:FixedWidthInteger.swift
extension FixedWidthInteger {
    var binaryString: String {
        var result: [String] = []
        for i in 0..<(Self.bitWidth / 8) {
            // ビットの右側から見ていって、UInt8の8bit(1byte)からはみ出た部分はtruncatiteする。
            // 自身のビット長によって8bitづつ右側ビットシフトをして、右端8bitづつUInt8にしている
            let byte = UInt8(truncatingIfNeeded: self >> (i * 8))
            
            // 2進数文字列に変換
            let byteString = String(byte, radix: 2)

            // 8桁(8bit)になるように0 padding
            let padding = String(repeating: "0",
                                 count: 8 - byteString.count)
            // 先頭にパディングを足す
            result.append(padding + byteString)
        }
        
        // 右端の8ビットが配列の先頭に入っているが、joined()するときは左端の8bitが配列の先頭に来ていて欲しいのでreversed()している
        return "0b" + result.reversed().joined(separator: "_")
    }
}

print(Int16.max.binaryString)
// Prints "0b01111111_11111111"
print((101 as UInt8).binaryString)
// Prints "0b11001001"

```

もし、先頭の`0b`も8bitごとの`_`もいらないなら、

```swift:no0b_.swift
return result.reversed().joined()
```

とすれば、以下のようになります。

```swift:no0b_print.swift
print(Int16.max.binaryString)
// Prints "0111111111111111"
print((101 as UInt8).binaryString)
// Prints "11001001"
```
kintone REST API + Power Queryでレコードを取得する

Excel + Power Query + kintone REST API でレコードを取得する。アドホック的な使い方であればまぁそこそこよい感じ。

# 使ったもの
- Excel 2016 と Power Query エディター
- kintone 試用版 のサンプルアプリ(顧客管理)
    - APIトークン

# Power Query エディターで
```text
let
    APIHost = "https://****.cybozu.com", APIToken = "<取得済APIToken>",
    JSONviaAPI =
        Json.Document(
            Web.Contents(
                Uri.Combine(
                    APIHost, "k/v1/records.json"
                ),
                [
                    Query = [ 
                        App = "2",
                        Query = "order by レコード番号 asc limit 10 offset 10"
                    ],
                    Headers=[ #"X-Cybozu-API-Token" = APIToken ]
                ]
            )
        ),
    TableFromRecords = Table.FromRecords( JSONviaAPI[records] ),
    ColumnNames = Table.ColumnNames( TableFromRecords ),
    TransformColumns1 =
        Table.TransformColumns(
            TableFromRecords,
            List.Zip( {
                ColumnNames,
                List.Repeat(
                    { each _[value] },
                    List.Count( ColumnNames )
                )
            } )
        ),
    TransformColumns2 =
        Table.TransformColumns(
            TransformColumns1,
            {
                { "更新者", each _[name] },
                { "作成者", each _[name] }
            },
            null, MissingField.Ignore
        )
in
    TransformColumns2
```

途中こんな感じになるけど慌てなくて大丈夫。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/35280e2a-2e08-58bd-1ffe-0b6dbe742464.png)

データ型はよく吟味してから
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/1959ca4d-13e7-7148-9091-2d05f447dbf1.png)

 
**500件の制限については、List.Generate 関数 使って解決の方針。**

- [kintone REST API でレスポンスの値を判定するコツ – cybozu developer network](https://developer.cybozu.io/hc/ja/articles/205080054-kintone-REST-API-%E3%81%A7%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E3%81%AE%E5%80%A4%E3%82%92%E5%88%A4%E5%AE%9A%E3%81%99%E3%82%8B%E3%82%B3%E3%83%84)


# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
react native ios sumilator がいきなり起動しなくなった

react native でアプリを作成途中 axiosが必要になり、installしました。
それからもう一度run-iosしてみると


Looks like you installed react-native globally, maybe you meant react-native-cli?
To fix the issue, run:
npm uninstall -g react-native
npm install -g react-native-cli

 とエラーがでて

なぜか立ち上がらず。。。。。。。。

結局uninstallしてrun-iosすると立ち上がりました。

これからはfetchで我慢します。。。。。。。。
Amazon CloudWatchのルールのスケジュール式のcron式がわかりづらい、のでなんとかしたい。2018-05-28

[246 Hack Night #1](https://connpass.com/event/88251/) 内に行った作業のメモです。

# 内容
Amazon CloudWatchのルールのスケジュール式のcron式がわかりづらいので、普通のcrontabのフォーマットをCloudWatchのScheduledEventsのcron式に変換するものをRubyで書きます。

# わかりづらいポイント
普通のcrontabにはない `?` がわかりづらいです。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/events/ScheduledEvents.html

## 例: 毎日午前 10:00 (UTC) に実行
crontab

```cron
0 10 * * * COMMAND
```

CloudWatch cron（`年` のフィールドもあるので普通のcrontabより1個多いです）

```cron
0 10 * * ? * COMMAND
```

「曜日」のフィールドを `?` にしないといけません。
いつものcrontabな感じで `*` にするとエラーになります。

# 作った
https://github.com/abetomo/cloud_watch_scheduled_events_cron

```
% echo '0 10 * * *' | bundle exec ruby ./bin/to_cwcec
0 10 * * ? *
% echo '5 * * * 1-5' | bundle exec ruby ./bin/to_cwcec
5 * ? * MON-FRI *
```

のように普通のcrontabの内容をCloudWatchのcron式に変換してくれます。

## 足りないところ
* ~~`gem` が作ったREADMEそのままです~~ 更新しました
* ~~gemに上げてないです~~ 上げました https://rubygems.org/gems/cloud_watch_scheduled_events_cron
* AWSのドキュメントにある例しかサポートしていないので、うまく動かないケースのほうが多いと思います
* 入力が標準出力からのみ

# まとめ
CloudWatchのScheduledEventsのcron式でいつもエラーになるのでこのような変換ツールがあるとうれしいです。
iTerm2とTouch Bar で簡単サーバ接続

## イメージ
<img width="1085" alt="Touch_Bar.png" src="https://qiita-image-store.s3.amazonaws.com/0/190833/39d4c793-ae86-dcf4-eb24-d43eb61a9725.png">

iTerm2起動中にTouch barに設定したボタンを押すだけで新しいタブを開き指定のサーバにアクセスすることが簡単に出来ます。
実際に下記の2,3の設定を変えればお好きなコマンドを設定することができるため、私はdocker内のログ監視ボタンなども作ってます。

## 環境
- iTerm2 Build 3.1.6
- MacBook Pro (15-inch, 2016)
- macOS High Sierra 10.13.4


1. ssh経由でリモートサーバに接続するコマンドを準備(.ssh/configなどに書き込んでいる方はそちらのコマンドを仕様)
2. iTerm2でProfile作成
3. iTerm2でTouch barをカスタマイズ

## 手順
1. ssh経由でリモートサーバに接続するコマンドを準備(.ssh/configなどに書き込んでいる方はそちらのコマンドを仕様)

```
# ポート名を使用する場合
ssh (ユーザー名)@(ホスト名) -p (ポート番号)

# 公開鍵認証を使用する場合
ssh ユーザー名@ホスト名 -i ~/.ssh/公開鍵名

# ポート名、公開鍵認証を両方使用する場合
ssh ユーザー名@ホスト名 -i ~/.ssh/公開鍵名 -p ポート番号

# exsample
ssh hoge@hoge-server -i ~/.ssh/hoge.rsa -p 22
```
<p>
2. iTerm2でProfile作成
　1. iTerm2->Preferences->Profiles->General
　2. 左下の+をクリック
　3. Nameを入力(タブ名になる)
　4. Send text startに1で準備したコマンドを入力
　5. iTerm2->Preferences->Profiles->Window
　6. Preserver profile name in tab titleにチェックを入れる
<p>
3. iTerm2でTouch barをカスタマイズ
　1. iTerm2->Preferences->Keys->Add Touch Bar item
　2. Touch Bar Label(Touch Barに表示される名前)を入力
　3. ActionはNew Tab with Profileを設定
　4. Profileには作成したProfileを選択
　5. OK
　6. View->Customize Touch Bar ...
　7. 作成した名前を配置してdoneをクリック
射影追跡をニュートン法で実装した

本当にメモ程度です。

## 射影追跡とは
　標本の非ガウス方向を見つけるアルゴリズムのこと（これが、混合した音声などの独立成分分析に応用できる）

### 射影追跡の考え方
１、ガウス分布の尖度は3である。→尖度が3から遠いほど、非ガウス
２、勾配法で尖度を更新してもよいが、ニュートン法の方が速い
３、外れ値に強くするため、非ガウス性尺度を定義する

### 射影追跡の手順
１、標本を中心化&球状化（白色化）
２、非ガウス方向のパラメータが収束まで更新

## 実装
[GitHub](https://github.com/be-kan/projection_pursuit)にコードをあげています。
また、中心化と球状化をしなくてもいいように標本を作成しています。

```python
import numpy as np

# 標本数
N = 1000

# Gauss分布を生成
x_gauss = np.random.randn(N)

# 一様分布を生成
x_uniform = np.random.rand(N) * 5.0 - 2.5

x = np.array([x_gauss, x_uniform])


def nomalize(b):
    return b / np.sqrt(b[0]**2 + b[1]**2)


def main():
    # g(s) = s^3 のとき
    # 初期のbを仮定
    b = nomalize(np.array([1, 0]))
    threshold = 0.0000000001
    diff = 1

    while diff > threshold:
        print(b)
        tmp_1, tmp_2 = 0, 0
        for i in range(N):
            tmp_1 += 3 * (np.dot(b, x[:, i]) ** 2)
            tmp_2 += x[:, i] * (np.dot(b, x[:, i]) ** 3)

        new_b = tmp_2 / N - tmp_1 * b / N
        diff = (b[0] - nomalize(new_b)[0])**2 + (b[1] - nomalize(new_b)[1])**2
        b = nomalize(new_b)


if __name__ == '__main__':
    main()
```

### 結果
確かに非ガウス方向に射影できている。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/196673/05505338-465c-9d7c-35c5-88ae6a55194e.png)
Python2/3でabstract classを作る

以下のようにすると、Python2/3対応の抽象クラスを作成できます。

```
import abc
ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()})

class SomeAbstractClass(ABC):
    @abc.abstractmethod
    def do_something(self):
        pass
```

acknowledgement: https://stackoverflow.com/a/38668373

\# sixが使えるなら`@six.add_metaclass(ABCMeta)`の方が良いかもですが
Rustでゼロサイズのヒープ領域を確保した時の挙動

`Box`や`Vec`は与えられた型に応じてヒープ領域を確保してくれますが、確保するメモリサイズが0であるときの詳しい挙動を調べてみました。

# `Box<T>`の`T`がゼロサイズの場合

Rustでは、次のような型のサイズは0になります。

``` Rust
()
[u8; 0]
struct Foo;
enum Bar;
```

これらの型の値を`Box`で生成したらどうなるのでしょうか。例として、ユニット型`()`を`Box`で確保した場合、そのポインタはどこを指しているのか調べてみます。

``` Rust
let b = Box::new(());
let p = &*b as *const ();
println!("{:p}", p);
```

結果は次のようになります。

```
0x1
```

`Box`を使えば、ヒープ領域を確保してくれるはずですが、この場合は明らかにポインタがヒープ領域を指していません。どうやら、ゼロサイズの型については、`Box`はダングリングポインタになるようです。といっても、ゼロサイズの場合はポインタの先を参照することは無いので、未定義動作にはなりません。

`T`がゼロサイズの時、`Box<T>`がダングリングポインタにになることで、ジェネリックなコードが書きやすくなっています。なぜなら、プログラマが`T`のサイズを気にすることなく、`Box`側がヒープ確保のオーバーヘッドが最小になるように面倒をみてくれるためです。

# 長さ0の`Vec`

`Vec::new()`や`vec![]`により、長さ(要素の数)が0のVecを作ることができます。このとき作った`Vec`はどこを指しているのか調べてみます。

``` Rust
let v: Vec<i32> = vec![];
let p = v.as_ptr();
println!("{:p}", p);

let v: Vec<i32> = Vec::new();
let p = v.as_ptr();
println!("{:p}", p);
```

実行結果は次のようになります。

```
0x4
0x4
```

`Vec`についてもダングリングポインタになり、ヒープ領域の確保は行われていません。これでヒープ領域割り当てのコストを心配すること無しに長さ0の`Vec`を作ることができます [^1]。長さが0でもヒープ領域を確保したい場合は、`Vec::with_capacity()`を使いましょう。また、`T`そのものがゼロサイズであれば、`Vec<T>`はいかなる場合でもヒープ領域を確保しません。

# ダングリングポインタについて

上の例に示した`Box`や`Vec`が、なぜnullではなく0x1や0x4というアドレスを指すダングリングポインタになっているのでしょうか。これは、Boxは絶対に0(null)にならないことを保証しているためです。これにより、`Option<Box<T>>`が`Box<T>`と同じサイズとなるわけです。Vecの場合は、内部では絶対にnullにならないポインタ型`Unique<T>` [^2] を使っているため、こちらもヒープ領域を確保しない場合はダングリングポインタが格納されます。

ちなみに、Rustには公式にダングリングポインタを作る方法が用意されています。`NonNull<T>`という型は、絶対にnullにならないような制約をつけたポインタ型ですが、これには`dangling()`というメソッドが存在し、次のように実装されています(一部省略)。

``` Rust
impl<T: Sized> NonNull<T> {
    pub fn dangling() -> Self {
        unsafe {
            let ptr = mem::align_of::<T>() as *mut T;
            NonNull::new_unchecked(ptr)
        }
    }
}
```

この実装では、生成されたダングリングポインタのアドレスはその型のアラインメントのサイズと同じです。空の`Vec<i32>`の指している先が0x4なのも同様に、`i32`のアライメントが4のためだったことが分かります。たとえダングリングポインタでも、ポインタのアラインメントの規則は守られているわけですね。

ダングリングポインタの作り方や、`Box`や`Vec`の内部表現は、普通にRustを書く上で気にする必要はありません。しかし、もしヒープ領域の確保・解放が関わるunsafeなコードを書く場合は、これらの知識が必要になるでしょう。

[^1]: ただし、一度ヒープ領域を確保した`Vec`は、要素を全部破棄して`len() == 0`になっても、そのまま使ったヒープ領域を確保し続けます。このヒープ領域を解放させるには、`Vec`自体をDropするか、`shrink_to_fit()`メソッドを呼ぶ必要があります。

[^2]: Rust1.26時点で`Unique`はunstableなので、将来変更されるかもしれません。`Unique`のダングリングポインタの生成方法は`Unique::empty()`であり、その中身は`NonNull::dangling()`と同じです。
slack webhookでメンションが飛ばない

slack webhookでメンションが飛ばない問題

gitlab->zapier->slackという流れでメンションを贈ろうとしたら送れない。

- `link_names=1`しても送れない
- slackの表示名と名前をgitlabに合わせても送れない


# 結論
slackには名前に関する設定が３つある。

- 名前
    - メンション送る時の名前
- 表示名
    - メッセージの名前のところに表示される名前
- ユーザー名
    - **webhookとかからメンション送る時に必要な名前**


WTF slack.
Nginxをrootで起動しない俺のDockerfile

oredesu

ubuntuベースでroot起動させないnginxつくってみた。
masterプロセスもwww-dataで起動しちゃうのでWARNINGでるけどネ.
COPY元のnginx.confとapp.confはwww-dataなuserで起動するかんじで、適宜vhostsなりupstream書く感じ。

# Dockerfile

```
FROM ubuntu
USER root
RUN apt-get install -y nginx
COPY ./docker-compose/nginx/etc/nginx/nginx.conf /etc/nginx/nginx.conf
COPY ./docker-compose/nginx/etc/nginx/conf.d/app.conf /etc/nginx/conf.d/app.conf
RUN mkdir /var/lib/app
RUN chown -R www-data:root /var/log/nginx
RUN unlink /etc/nginx/sites-enabled/default
RUN mkdir /var/run/nginx
RUN mkdir /var/lib/nginx/body
RUN mkdir /var/lib/nginx/fastcgi
RUN mkdir /var/lib/nginx/proxy
RUN mkdir /var/lib/nginx/scgi
RUN mkdir /var/lib/nginx/uwsgi
RUN chown www-data:root /run/nginx
RUN cd /var/lib/nginx && chown www-data:root body fastcgi proxy scgi uwsgi
RUN chmod 700 /var/lib/nginx/body
RUN chmod 700 /var/lib/nginx/fastcgi
RUN chmod 700 /var/lib/nginx/proxy
RUN chmod 700 /var/lib/nginx/scgi
RUN chmod 700 /var/lib/nginx/uwsgi
USER www-data
WORKDIR /tmp
```


# Command

compose upやrunするときはコレで.

`/usr/sbin/nginx -g 'daemon off;' -c /etc/nginx/nginx.conf`

完って感じ
PythonでDiscordに時報を書き込む

Discordのチャンネルに定期的に何かのメッセージを書き込む処理をしたかったものの、botではいまいちやり方が分からずあれこれ検索していたところ、Webhookとやらを使うとよいことが分かりました。


チャンネル名の横の歯車マークをクリックし、Webhooksの項目を選択しましょう。
(Webhookの作成権限がない場合は管理者に頼むか諦めましょう)
名前とアイコン、入るチャンネル名を指定し、webhook URLをコピーし、保存します。
後から触る場合はWebhook一覧から｢編集｣を押してURLを見ることができます。


さて、取得したURLにPOSTでメッセージを投げるとよいらしいです。
(詳しいパラメータは[本家ドキュメント](https://discordapp.com/developers/docs/resources/webhook#execute-webhook-jsonform-params)を読みましょう)
今回はpythonで[Requests](https://github.com/requests/requests)を使ってみました。

```python:discord_webhook
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import requests
import sys

url = 'EDIT ME' #ここにWebhook用に取得したURLを入れる

if len(sys.argv) > 1:
    payload = {'content': sys.argv[1]}
    result = requests.post(url, data=payload)

    if result.status_code != requests.codes.no_content:
        # 投稿に失敗したときの処理...
```

あとは実行権限を付与して

```shell
% chmod u+x discord_webhook
```

crontabにどーん(%のエスケープが要ることを知らず数分はまってしまった)

```
0  * * * * /path/to/discord_webhook "$(date '+\%H')時です"
```


これで定時処理が色々書けますね。めでたしめでたし。