OmniAICreator/Qiita-1.07M huggingface dataset:
みんなで盛り上げるIoT博覧祭に参加した

# 基本情報 

* 【日　時】2018年11月24日 11:00~17:00 
* 【会　場】相鉄岩崎学園ビル8F 
* 【参加費】無料 
* 【主　催】IoT ALGYAN(あるじゃん) 
* 【申し込み】https://algyan.connpass.com/event/95950/ 

# 概要 
* みんなで盛り上げるIoT博覧祭というのは、IoT作品展示をメインとして、LT講演もするお祭りイベント 
* 個人や企業は一緒になってIoT技術交流できる 
* 出展者に企業の方が多い、SOROCOMさんも出展したことある 
* 講演が30件以上ある 

 

 

# 気になる作品 
* IoT作品がいろいろあるが、気になる作品は１件のみ。実はIoT作品ではなくて、商品である。SORACOM LTE-M Buttonである。 

## SORACOM LTE-M Buttonとは 
* SORACOM LTE-M Buttonは、AWS IoT 1-Clickのサポート対象デバイスである。AWS IoT エンタープライズボタンと同様に、１回押す、２回押す、長押しするという3つのタイプのクリックをサポートしている。ちなみに、SORACOM LTE-M Buttonはモバイルデータ通信ベースで、日本でKDDIのLTE-Mネットワークと接続できる交換可能なバッテリー式のボタンである。 

### 特徴 
* 日本で広い範囲に使える 
 * 日本でKDDI IoT通信サービス LPWAと接続する 
 * 通信できるエリアをここに検索できる 
 * 展示者へ聞いて、通信失敗の場合はボタン上のライトが赤になることがわかった 
 * ボタンを設置する時に、無線通信でアクセスポイントなどの設備が必要ない、直接的にAWSへデータを送れることができる 
* サーズが小さい 
 * サイズ：97mm x 33mm x 13.7mm 
 * 重量： 65g 
 * 電池：単四電池2本 
* 価格が安くて購入簡単 
 * 価格：8000円 
 * 初回通信時から１年間の通信費用もしくは1,500回のデータ通信費用を含む 
 * １年以上利用する場合は、SOROCOMウェブコンソールから更新の手続きが必要（更新費用：1,200円/年） 
 * 補足：AWS IoT 1-Clickと連携するので別料金が必要 
* 利用開始方法が簡単 
 * SORACOMウェブコンソールから商品を購入する 
 * AWSアカウントを作成する 
 * AWS IoT 1-Clickからデバイス登録する 
 * AWS Iot 1-Clickにプロジェクトを作成後、デバイスのプレイスメントテンプレートを作成してアクションを設定する。アクションは、用意されているLambda関数をプルダウンで選択できる方か、任意のLambda関数を設定できる 

### 事例 
2018/11/1から販売開始になって、実の事例がないが、以下の利用シーンが紹介される 

* 商品の発注 
 * オフィスや施設の消費品切れの通知 
* スマートキーの操作 
 * Web API経由でスマートキー施解 
* ゴミの回収依頼 
 * 回収時期を通知して、作業を依頼 
* 機器故障の修理依頼 
 * 設置された機器の故障を通知 
* 施設のアンケート 
 * お客様の声をボタンで収集、例えば、one clickでいいねを通知する 
* 配車依頼 
 * 病院やレストランなど施設からの配車依頼 

# まとめ 
* 2016年、IoTに関するプロジェクトに参加したことあって、世界を変える技術に趣味がたくさんある
* この文書に紹介したIoTに関する商品が、社内にIoTプロジェクトをやっている方に何か貢献できれば嬉しい
REDOログファイルについて簡単に解説する

#概要
OracleMasterBronzeの勉強をしている方向けにREDOログファイルについて解説していきます。

#REDOログファイルとは
トランザクションの内容（ユーザーによるSQL文）やデータベースの変更履歴（DBの内部処理）が記録される。
ロールフォワードやリカバリ処理などに使用される。


#REDO保存の流れ
上記のトランザクションなどを処理するとREDOレコード（変更履歴のようなもの）が発行
↓
SGAのREDOログバッファに一時保存
↓
バックグラウンドプロセスのLGWRによりディスクに存在するREDOログファイルに保存されます。


#REDOログファイルの構成
循環方式で書き込むために、REDOロググループを2つ以上構成する。
またREDOログの多重化を行うため、同じグルループ内に内容が同じの複数のREDOログファイルを保持します（これをメンバーと呼びます）

例:3グループ構成の場合
グループ1→グループ2→グループ3→グループ1...

このような感じで循環（ログスイッチ）していきます。
ログスイッチはREDOログファイルが一杯になったタイミング（手動での切り替えも可能）で行わる。

LGWRで書き込む対象のREDOロググループを「カレントのREDOロググループ」と呼び、ログ順序番号により識別されています。


#REDOログファイルのアーカイブ
REDOログファイルは循環方式で書き込むために、一周してグループ1に戻る時に古いログが上書きされると困ります。

なので、グループ1からグループ2（2から3)
にログスイッチしたタイミングでバックグラウンドプロセスのアーカイバ(ARCn)により、グループ1のログファイルをアーカイブログファイルとしてアーカイブされます。


読んでいただきありがとうございました。
MarkDown記法の練習

qiitaアカウントを作ったので投稿のテスト
MarkDown記法は聞いたことはあっても使ったことが無かったので練習がてら投稿してみる

#参考
[Qiita初心者の投稿方法備忘録](
https://qiita.com/cloversoft/items/0f12f3a739312d35cb8f)

見出し
「#」1個でH1タグ、6個でH6タグ
#見出し

#リンク
URLそのまま
http://cloversoft.jp/
タイトル付きにする場合は[](URL)
\[](URL)
[タイトル付き](http://cloversoft.jp/)

別枠で表示する場合は

```
構文：<a href="URL" target="_blank">タイトル名</a>
サンプル<a href="http://cloversoft.jp/" target="_blank">別窓で</a>
```


<a href="http://cloversoft.jp/" target="_blank">別窓で</a>


#Code - コードの挿入
バッククォート3つでくくる。ファイル名やシンタックスハイライトもつけられる

構文

>\```言語名：ファイル名
>
>ソースコード
>
>\```

サンプル

>\```Javascript:fileName.js
>
>'↑「言語名：ファイル名」と書いとくと言語に合わせて色を変えてくれるみたい。'
>
>\```


```Javascript:fileName.js
'↑「言語名：ファイル名」と書いとくと言語に合わせて色を変えてくれるみたい。'
```

#引用

\>を行頭に付ける

>を行頭に付ける
>>複数付けるとネストする

#マークダウンのエスケープ
\を行頭に付けるとMarkDown記法のエスケープができます

\\>引用

\>引用
Vim で Linux カーネルソースを快適に読むための設定

# ■ はじめに

vim で Linux カーネルソースを読むとき、何もしていないとソース上で登場する関数の定義や関数の呼び出し元などを調べるのがとても面倒です(grep を使うなど)。

本稿ではそういった面倒を減らすためにやっておきたいことを書いています。やっておくことコードリーディングが快適になるかもしれません。

# ■ 設定

次のとおり、非常に簡単です。

1. cscope をインストール (Fedora の場合)
   `$ dnf install cscope`

1. Linux カーネルソースのルートディレクトリへ移動[^1]
  `$ cd <Linux カーネルソースのルートディレクトリ>`

1. Linux カーネルソースの Makefile を利用して cscope の index を生成
   `$ make cscope`


[^1]: カーネルソースを入手していない方は[こちらの記事](https://qiita.com/Kernel_OGSun/items/1c0068e2bf58a55377a2)を参考に入手してください。

# ■ できるようになること

上記をやっておくと、関数の定義元や関数の呼び出し元へジャンプできるようになるなど、コードリーディングが非常に快適になります。

なお、以降では、次の条件を満たしている前提で進めます。

- カレントディレクトリが、Linux カーネルソースのルートディレクトリ(``$ make cscope`` したディレクトリ)であること
- ``$ vim mm/oom_kill.c`` でソースファイルを開いていること[^2]
- vim がノーマルモードになっていること

[^2]: 以降での説明を楽にするために便宜上 mm/oom_kill.c を開いています。深い意味はありません。

## 1. 指定した関数の定義元へジャンプ

1. 定義を確認したい関数の上にカーソルを合わせる
2. <kbd>Ctrl</kbd> + <kbd>]</kbd>

or

1.  vim で ``:cs f g <定義を確認したい関数名>`` を実行

**実行例1** では check_panic_on_oom 関数内[^3]で使用されている is_sysrq_oom 関数の定義を確認(<kbd>Ctrl</kbd> + <kbd>]</kbd>)しています。

なお、元の場所(check_panic_on_oom 関数)へ戻るには <kbd>Ctrl</kbd> + <kbd>t</kbd> か <kbd>Ctrl</kbd> + <kbd>o</kbd> を実行します。

[^3]: check_panic_oom 関数は mm/oom_kill.c ファイルに含まれています(v4.19 時点)。

実行例1: ![ctags.gif](https://qiita-image-store.s3.amazonaws.com/0/283234/910d33af-f22d-464a-7ec4-3ad029ec2f5c.gif)

## 2. 指定した関数の呼び出し元へジャンプ

1. vim で ``:cs f c <関数名>`` を実行
2. 確認したい箇所に対応する番号を指定 (呼び出し元が複数ある場合に限る)

**実行例2** では is_sysrq_oom 関数の呼び出し元を確認しています。呼び出し元が複数あったので ``1`` を指定し、確認しています。

実行例2： ![cs_f_c.gif](https://qiita-image-store.s3.amazonaws.com/0/283234/6719f47b-ca0f-221e-f543-d28a6c660541.gif)

## 3. 指定した関数内で使用している関数の一覧を確認

1. vim で ``:cs f d <関数名>`` を実行

**実行例3** では ``:cs f d check_panic_on_oom`` を実行し、check_panic_on_oom 関数内で使用している関数の一覧を確認しています。4つの関数(likely、is_sysrq_oom、dump_header、panic)を使用していることが確認できます。番号を指定することでその箇所へジャンプもできます。

実行例3: ![cs_f_d.png](https://qiita-image-store.s3.amazonaws.com/0/283234/d8bc49ad-b483-8739-840c-5ebe87742977.png)

# ■ :cs f **<クエリパターン>** **<キーワード>** について

先ほどから登場している ``:cs f <c、d などのクエリパターン> <関数名などのキーワード>`` というのは [cscope](http://cscope.sourceforge.net/) というツールによるもので、<クエリパターン> を変更することで、他にも色々とできます。クエリパターンは **実行例4** のように ``:cs help`` と入力することで確認できます。**find : Query for a pattern 以下の部分** です。

ちなみに、``:cs f`` というのは ``:cscope find`` の省略形です。


実行例4: ![cs_help.png](https://qiita-image-store.s3.amazonaws.com/0/283234/909aa1fe-a534-a415-e9c5-1db6f0adcaf5.png)

# ■ より快適にするには

正直、毎回 ``:cs f c`` のように入力するのはメンドクサイと思います。より快適にするには vim のキー割り当てを設定することをおススメします。例えば、次のような感じです。

```vimscript:.vimrc
" 任意の関数名にカーソルを当てた状態で 「Shift + c」 すると、その関数の呼び出し元を確認できる。
nnoremap <S-c> :cs f c <cword><CR>

" 任意の関数名にカーソルを当てた状態で 「Shift + d」 すると、その関数内で使用している関数の一覧を確認できる。
nnoremap <S-d> :cs f d <cword><CR>
```

すこし解説しますと、

- ``nnoremap`` はノーマルモードでのキー割り当て(再割り当てなし)を定義するコマンドです。

- ``<S-c>`` は ``Shift + c`` を押下した時という意味です。

- ``:cs f c <cword><c>`` は ``<S-c>`` をした時に実行されるコマンドです。
  - ``<cword>`` は現在のカーソル位置にある単語に置換されます。
  - ``<CR>`` はキャリッジリターン(Enter 押下)です。

以上です。ご参考までに。
開発したIOSアプリをリリースするまで。


この辺を参考にすればできます。

https://www.raywenderlich.com/120-how-to-submit-an-app-to-apple-from-no-account-to-app-store-part-1

https://www.raywenderlich.com/8164-push-notifications-tutorial-getting-started

https://www.raywenderlich.com/5352-testflight-tutorial-ios-beta-testing

ただ、Provising　Profileを開いてもXcodeに正しく反映されなくて詰まった。

その時はXcode のプロジェクトのGeneralからdebug/releaseそれぞれにプロファイルを手動で割り当てて解決。
JSで任意のテキストをクリップボードにコピー

ググってもダミーのtextareaを使う方法ばかりが引っかかったのでメモ兼
ES5使っていいかどうか知らない環境でとりあえずコードだけ書くという奇特なシチュエーションで作ったものなので、ES5未満
よく調べてないけど標準的なAPIしか使っていないのでどのブラウザでも動くはず。少なくともモダンブラウザでは。

```JS
var copyText = 'コピーさせたいテキスト';
document.addEventListener('copy', function handler(clipboardEvent) {
  clipboardEvent.preventDefault();
  clipboardEvent.clipboardData.setData('text/plain', copyText);
  document.removeEventListener('copy', handler); // 毎度消さないと他の文字列がコピーできなくなる
});
if (document.execCommand('copy')) {
  alert('コピーしました:\n' + copyText);
} else {
  alert('コピー失敗:\n' + copyText);
}
```

これをボタンのオンクリックイベント等に入れておけば動くと思います
gpg --gen-keyが止まる件について

`gpg --gen-key`が止まっているようにみえるのは、出力にもあるように"gain enough entropy"(entropyを集めている)ためです。そのため、止まっているわけではありません。

これを早めるためには、

```shell
dd if=/dev/sda of=/dev/null
```

などを実行して、システムに処理をさせるといいみたいです。コマンドの実行前にentropy稼ぎをしておくと良いかもしれません。

現在、何bitのentropyがある(bit!?)かは、`/proc/sys/kernel/random/entropy_avail`を見るとわかります。

>
/proc interfaces
       The files in the directory /proc/sys/kernel/random (present since 2.3.16) provide additional information about the /dev/random device:
</b>
entropy_avail
              This read-only file gives the available entropy, in bits.  This will be a number in the range 0 to 4096.
(man urandom(4))

例えば、

```shell
watch -n 1 cat /proc/sys/kernel/random/entropy_avail
```

で監視してみると、数字が少しづつ増えて、64となったあたりで0に戻るという挙動をしていました。これは、gpgがkernel's random number generatorを使っているからでしょう。。

また、

>
When  the  entropy  pool  is  empty,  reads from /dev/random will block until additional environmental noise is gathered.
(man urandom(4))

とあるので、`/proc/sys/kernel/random/entropy_avail`が0となると、`gpg --gen-key`が止まってしまうのでしょう。

余談ですが、gpgにおいて最長の鍵長は4096みたいですが、これは、kernelのentropy poolが4096bitなのと関係しているのでしょうか。

>
[/proc/sys/kernel/random/]poolsize
This file gives the size of the entropy pool.  The semantics of this file vary across kernel versions:
</br>
              Linux 2.6 and later
                     This file is read-only, and gives the size of the entropy pool in bits.  It contains the value 4096.
(man urandom(4))

さらに、64までインクリメントすると0に戻るという挙動は、
`/proc/sys/kernel/random/read_wakeup_threshold`の値が64であることによるのだと思います。

>[/proc/sys/kernel/random/]read_wakeup_threshold
              This file contains the number of bits of entropy required for waking up processes that sleep waiting  for  entropy  from  /dev/random.   The
              default is 64.

以上、`gpg --gen-key`が終わるのを待っている間に書いた記事でした。4096bitにしたから、終わるのがめちゃくちゃ遅い。。。entropyの代わりに擬似乱数を使えたら早いのにな。
大津の二値化ってなんだ…ってなった.

# はじめに
OpenCVを利用して二値化を行う際, 「とりあえず`cv2.THRESH_OTSU`やっとけばええやろ, ぽいー」って感じでテキトーに二値化してました.
「とりあえずいい感じに動く」って認識だったので, きちんと(?)理解自分なりにここにまとめていきたいと思います.
初心者なので間違いなどあれば教えていただけるとありがたいです.

# 概要 - OpenCVさんの説明
[OpenCVのチュートリアル](http://labs.eecs.tottori-u.ac.jp/sd/Member/oyamada/OpenCV/html/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html)を見ると
> 大津のアルゴリズムは以下の式によって定義される**重み付けされたクラス内分散**を最小にするようなしきい値(t)を探します.
$\sigma_{\omega}^2(t) = q_1(t)\sigma_1^2(t) + q_2(t)\sigma_2^2(t)$
(各変数の定義は本家を見てください)

のように書いてありました. 
詳しくはわからなかったけど, いい感じのしきい値(t)を探してくるってことだけわかりました.

# 概要 - 自分なりの説明
簡単に言うと
>
ある閾値$t$を境にクラス0とクラス1に分けたとき, 
>
* クラス0とクラス1が離れている
* それぞれのクラス内のデータ群がまとまっている

> ような$t$を見つけ出すようになっている.

という感じかなと思いました.

言葉だと少しわかりづらいので, このことをグラフを使って説明していきます.

## 閾値tを境にクラス0とクラス1に分ける
二値化を適用するのは輝度だけを残したグレースケール画像です. 
そのため各画素は$0\sim 255$の値を取ることになります.
ここである閾値$t$を考えると, 下のヒストグラムのように各画素が2つに分断されます.
![class_split.png](https://qiita-image-store.s3.amazonaws.com/0/264254/6e731b2e-62c5-6081-4b00-f80c74d4bce6.png)
ここで仮に閾値より低い輝度の画素たちをクラス0, 閾値以上の輝度を持つ画素たちをクラス1と呼びます.

## クラス0とクラス1が離れている
クラス0の平均とクラス1の平均を出し, それらをうまいぐらいに利用してクラス0とクラス1がどのくらい離れているかを求めます.
![var_between_classes.png](https://qiita-image-store.s3.amazonaws.com/0/264254/e1566562-60ed-c106-ea34-a5b4303c6a5b.png)
(わかりづらいですが, 離れ具合は「二つのクラスの平均の差」ではないです)

ある閾値$t$で二値化することを考えると, 分断されてできた2つのクラスは**なるべく離れていた方がより良さそう**です.

## それぞれのクラス内のデータ群がまとまっている
各クラスのデータが総合的に見てまとまっているかどうかを, 各クラス内での分散を用いて算出します.
![var_in_each_classes.png](https://qiita-image-store.s3.amazonaws.com/0/264254/6a19e2f7-4f6f-1b8a-1567-2a65e7741c9d.png)

ある閾値$t$において, クラス0のデータ群がまとまって(=分散が小さい)おり, クラス1もまたデータ群がまとまっていると良さそうな感じがしますね.

# 詳細 - 大津の二値化アルゴリズムの中身
全体の画素数$P_{all}$, クラス0に含まれる画素数$P_{0}$, クラス1に含まれる画素数$P_{1}$とすると, 
全体におけるクラス0の割合$R_0$, 全体におけるクラス1の割合$R_1$は

```math
R_{0}=\frac{P_0}{P_{all}} ~~ , ~~ R_{1}=\frac{P_1}{P_{all}} 
```
になります.

全ての画素の輝度($0\sim 255$)の平均を$M_{all}$, クラス0内の平均を$M_{0}$, クラス1内の平均を$M_{1}$とした時, 
クラス0とクラス1の離れ具合である**クラス間分散$S_{b}^2$**は以下のように定義されています.

```math
\begin{array}{ccl}
S_b^2 &=& R_0\times (M_0 - M_{all})^2 ~ + ~ R_1\times (M_1 - M_{all})^2 \\
&=& R_0 \times R_1 \times (M_0 - M_1)^2
\end{array}
```


またクラス0内の分散を$S_0^2$, クラス1の分散を$S_1^2$とすると,
各クラスごとの分散を総合的に評価した**クラス内分散$S_{in}^2$**は以下のように定義されています.

```math
S_{in}^2 = R_0 \times S_0^2 ~ + ~ R_1 \times S_1^2
```

ここで先ほどの話を持ってきましょう. 
ある閾値$t$があったとき, 以下の条件を満たすとき, より好ましいと言えました.

1. クラス0とクラス1がより離れている
2. クラス毎にまとまっていたほうがよい

条件1は**クラス間分散$S_b^2$が大きければ**満たせそうです.
また条件2は**クラス内分散$S_{in}^2$が小さければ**満たせそうです.
つまりクラス間分散を分子に, クラス内分散を分母に持ってきて, 

```math
\frac{S_b^2}{S_{in}^2}
```
が大きくなればよりよい閾値$t$と言えそうです 
この式を**分離度$X$**とします.
分離度$X$を最大化するにはどうすればよいでしょうか.

ここで全体の分散$S_{all}=S_b^2 + S_{in}^2$を考えると, 
全体の分散は閾値$t$に依らない値なので, ここでは定数と考えることができます.
なので分離度$X$を変形して, 

```math
X=\frac{S_b^2}{S_{in}^2}=\frac{S_b^2}{S^2 - S_b^2}
```
とすると, 分離度$X$を最大化するには, 全体の分散$S$は定数なので「$S_b^2$を大きくすれば良い」ということが分かります.

つまり最適な閾値$t$は

```math
S_b^2 = R_0 \times R_1 \times (M0 - M1)^2
```
が最も大きくなるようなものである.
と結論付けられます.

なので大津の二値化では$0\sim 255$のすべてを閾値に選んだ時, 最も$S_b^2$が大きくなる数値を適切な閾値として選択するようになっています.

# グラフはこちら
要らないと思いますけど, グラフを作ったソースコードを置いておきます.
https://github.com/haru1843/qiita_thresh_otsu
Octave の使い方 (何かおかしい)

octave 4.4.1 で試してみる

```math:
a=\frac{n+4}{\sqrt{n^2+1}}\cos\frac{n\pi}{4}
```
この式で $\cos=1$ になる点をプロットしてみる。

```octave:
1;
clear;
n = -8:8:8*200;
a = ( (n+4) / sqrt(n.^2 + 1) ) * cos (n*pi/4);
plot(n, a);

grid on;
xlabel("n", 'FontSize',14);
ylabel("a(n)", 'FontSize',14);

ylim([1 1.05]);
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/306041/577be3d2-5617-c561-0cb0-95999f6243e5.png)

a の値は全て 1.037 に？

```octave:
>> a
a =

 Columns 1 through 7:

   1.0037   1.0037   1.0037   1.0037   1.0037   1.0037   1.0037
...

 Columns 197 through 202:

   1.0037   1.0037   1.0037   1.0037   1.0037   1.0037

>>
```

一づつ計算させてみると

```octave:
>> n = 0;
>> ( (n.+4) / sqrt(n.^2 + 1) ) * cos (n.*pi/4)
ans =  4
>>
>> n = 8;
>> ( (n.+4) / sqrt(n.^2 + 1) ) * cos (n.*pi/4)
ans =  1.4884
>>
>> n = 80;
>> ( (n.+4) / sqrt(n.^2 + 1) ) * cos (n.*pi/4)
ans =  1.0499
>>
>> n = 800;
>> ( (n.+4) / sqrt(n.^2 + 1) ) * cos (n.*pi/4)
ans =  1.0050
>>
>> n = 1600;
>> ( (n.+4) / sqrt(n.^2 + 1) ) * cos (n.*pi/4)
ans =  1.0025
```

なので、明らかに a の値がおかしい。どういうこと？

式の前半部分だけ計算させてみると...

```octave:
>> n=1:10
n =

    1    2    3    4    5    6    7    8    9   10

>> (n+4) / sqrt(n.^2 + 1)
ans =  1.5577
>> (n+4) ./ sqrt(n.^2 + 1)
ans =

   3.5355   2.6833   2.2136   1.9403   1.7650   1.6440   1.5556   1.4884   1.4356   1.3931
```

ありゃ、行列 (ベクトル) の計算結果がスカラーになってた。修正！
(どういう計算をしているのか分からないけど...)

```octave:
n = -8*200:8:8*200;
a = ( (n+4) ./ sqrt(n.^2 + 1) ) .* cos (n*pi/4);
plot(n, a);
hold on

n = -8*200+4:8:8*200;
a = ( (n+4) ./ sqrt(n.^2 + 1) ) .* cos (n*pi/4);
plot(n, a);

ylim([-2.1 4.1]);
```
として、$\cos=1,-1$ の時のグラフを描いてみた。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/306041/f1d714d7-0480-7c62-0f51-b46ce0ceecb2.png)

無事解決
rails4.2 でreactを導入検討

ちょっと環境が特殊なのでメモ書き程度

## 環境
- ruby 2.3.7
- rails 4.2.5
- node v8.11.3
- webpacker:3.5.3
- @babel/core: 7.1.2
- @babel/preset-react: 7.0.0

## 要件
1. 既存のRuby on Rails4.2.5のアプリケーション上でvue.jsのコンポーネントが動いている（not SPA)
2. vue.jsはwebpackerでpackされている (app/javascript以下)
3. vue.jsと別app/assets/javascripts以下にはレガシーのjQueryやunderscore.jsで書かれたライブラリが存在する

-> 全てReactに移行したい

## Ruby on Railsとreactの連携について
### 1. react-railsのgemを利用する
- デフォルトではAssetPipelineを利用
- 内部でreact.jsを持っているがバージョンが追従していない
- npmを使う時はbrowserify-railsかRailsAssets.orgを利用する?
- SSRにはexecjsを利用
- 最新版ではwebpackerとの連携でpackできる様になっている？

### 2. react_on_railsのgemを利用する
- webpacker利用で疎結合でReactを利用
- SSRにはexecjsを利用
- コンポーネントに値を渡すヘルパーメソッドが用意されている

### 3. Hypernovaを利用する
- SSRにnodeのサーバを利用
- Railsからpropsを渡す方法があまりスマートじゃない


軽く触った感じではreact_on_railsがお手軽で良かったが
React公式はreact-railsらしく、最新の情報では良くなっている様なのでもう少し試してみたい
[terraform]俺でもわかる雑に~/.ssh/configを作るoutput

俺です.
とりあえず寺のoutputつかってsshのconfig作って鼻ほじったろってときのtipsです。

# outputの定義

- ServerAliveXXXXはお好みで



```
output "ssh_config" {
    value =<<EOF
Host ${var.oreno-saba["tag_name"]}
    Hostname ${aws_instance.oreno-saba.private_ip}
    ProxyCommand ssh oreno-fumidai -W %h:%p
Host ${var.oreno-fumidai["tag_name"]}
    Hostname ${aws_eip.oreno-fumidai.public_ip}
Host oreno-*
    User ec2-user
    IdentityFile ~/.ssh/orenokey.pem
    ServerAliveInterval 15
    ServerAliveCountMax 10
    StrictHostKeyChecking no    
EOF
}
```

# show

- 以下のように雑に出力されるので `ssh_config =` を削って~/.ssh/configなり好きなところに保存してください

```
ssh_config = Host oreno-saba
    Hostname 192.168.0.1
    ProxyCommand ssh oreno-fumidai -W %h:%p
Host oreno-fumidai
    Hostname 54.0.0.1
Host oreno-*
    User ec2-user
    IdentityFile ~/.ssh/orenokey.pem
    ServerAliveInterval 15
    ServerAliveCountMax 10
    StrictHostKeyChecking no
```
pythonのお作法などについての備忘録

メモ書き。

PEP8に準拠

```python:変数名など
abc = 1  #空白文字は行内は1つ、行末は2つが推奨

#定数 大文字スネーク
HOGE_HOGE

#プライベート変数 _プリフィックス(アクセス可能だが紳士協定でアクセスしない約束)
_hoge_hoge

#ローカル変数 小文字スネーク
hoge_hoge
```

```python:クラス
#クラス名はCapWords(パスカル、アッパーキャメル記法)
#クラス変数 staticな変数 クラス直下に定義
class Hogehoge():
    value = 0

class Hogehoge():
    def __init__(self, value):  
        #インスタンス変数 init内(コンストラクタ)で定義 selfを経由する
        self._value = value

    #デコレータによるプロパティの実装
    @property
    def value(self):
        return self._value

    @value.setter
    def value(self, value):
        self._value = value

    @value.deleter
    def value(self):
        del self._value

    #クラスメソッド(継承先クラスで挙動が変わるときなどに利用)
    @classmethod
    def hoge_class_method(cls, name):
        print('ClassMethod' + name)

    #スタティックメソッド
    @staticmethod
    def hoge_static_method():
        print('StaticMethod')

#継承
class ChildHogeHoge(HogeHoge):
    def __init__(self, value)
        super().__init__(value)
```

```python:関数
#関数定義は小文字スネーク
#docstring
#引数、戻り値アノテーション(型エラーは起きない。あくまでも注釈)
#デフォルト引数
def hoge_hoge(input: 'int' = 1) -> 'int':
    """
    2乗するメソッド
    """
    return input ** 2

#関数の呼び出し
#キーワード引数が利用可能
hoge_hoge(input = 3)

#可変長引数
def geho_geho(*args):
    print('geho')

#可変長キーワード引数（辞書として受取）
def gehoho_gehoho(**kwargs):
    print('geho')

gehoho_gehoho(name = 'tanaka')
```


```python:その他
#!/usr/bin/env python
# ↑ shebang python 2.x系が動作

#!/usr/bin/env python3
# ↑ shebang python 3.x系が動作


def main():
    print('hoge')

#モジュール呼出時の実行防止
if __name__ == '__main__':
    main()
```

参考
---
[python 組み込み関数](https://docs.python.org/ja/3/library/functions.html#classmethod)
[【Python入門】いまさらだけどパイソニスタとして必要な文法を網羅してみた](https://qiita.com/gold-kou/items/9713f6fd82baf1eccd6a)
mockito-kotlinのfinal class エラーの対処

```
org.mockito.exceptions.base.MockitoException:
Cannot mock/spy class com.example.data.model.WeatherData
Mockito cannot mock/spy because :
– final class
```

このエラーは英語の通りfinal classをkotlinはデフォルトで作ってしまうためダメと言われてます

そのため、既存のプロジェクトにて

```
vi app/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker
```

```org.mockito.plugins.MockMaker
mock-maker-inline
```

これで動くようになります
古いMacbookAirにdebian9を入れる

# やりたいこと

* 古いMacbookAirが最新のOS Xに対応しなくなったのでdebianをデュアルブートで入れる
* 入れ直したいときに見返すと思うのでメモ

# 必要なもの

* USBフラッシュメモリ（数GBあればおっけー）
* USBイーサアダプタ
* LANケーブル
* 有線のインターネット環境

# 手順

## debian9インストーラを作る

* 公式からネットインストーライメージをダウンロード(amd64)
    * https://www.debian.org/CD/netinst/
* `diskutil list`で対応するディスク（USBフラッシュメモリ）を見つける
* `diskutil umount`でアンマウント
* ダウンロードしたisoイメージを`dd`で焼く

## debianをインストールするパーティションを作る

* SSDの容量を十分に確保する
* ディスクユーティリティからパーティションを作成
    * インストーラでフォーマットできるのでFATとかでおっけー

## debianをインストールする

* USBフラッシュメモリとUSBイーサアダプタを挿したまま再起動する
    * ルータなどに有線で接続しておく
* 起動時にoptionキーを押す
* ブートデバイスの選択ができるのでEFIBootを選択してdebianインストーラを起動する
* ネットワーク選択の画面になったら有線接続を使用するように選択
* パーティションの選択画面になったらカスタムを選んで、先程作成したパーティションを選択してフォーマットする
* パーティション選択画面に戻って最大の空き容量を使用するを選択してインストール
* インストールが終わるまでまつ
    * デスクトップ環境はGNOMEを選択する（好み）

## broadcomのファームウェアを入れる

* sudoやらvimやらを入れる
* visudoで自分のユーザにsudo権限を付与
* `/etc/apt/sources.list`を編集してnon-freeを追記する
    * `deb http://ftp.jp.debian.org/debian/ stretch main contrib non-free`
* 対応するファームウェアパッケージをインストール
    * `sudo apt install firmware-brcm80211`
* 再起動

以上
ssh: connect to host xx.xx.xx.xx port 22: Connection refused　で結局EC2インスタンスを作り直してLaravel環境を構築した件

#障害

昨日までssh接続できていたのに、突然下記のエラーが出て、ssh接続できなくなった。

~~~
$ ssh -i "xxx.pem" test-usr@xx.xx.xx.xx
ssh: connect to host xx.xx.xx.xx port 22: Connection refused
~~~

調べていくと、下記の点を確認すべきとあった。
* ファイヤーウォールを確認
* port:22が空いているか確認
* ログを確認して調査する

セキュリティーグループはちゃんと設定しているので、ファイヤーフォールとport22の件は該当しないと思われる。
ログも確認して見て、それらしいのは下記のログが出ていた。

~~~
Jan 26 07:44:11 ip-10-0-0-38 sshd[4778]: pam_unix(sshd:session): session closed for user test-usr
~~~

ただ、色々原因を調べてもわからず、結局EC2インスタンスを作り直すことにした。


#EC2インスタンスの再作成

* セキュリティーグループは既存のものを流用
* RDBも使えるので引き続き利用

[もともとここにある手順で環境をつくっている。](https://qiita.com/outase/items/244dbd6ec5c4e70030da)

###EC2インスタンスの作成

手順に従って簡単にできた。

* VPCとAZも既存のものを利用

###開発用ユーザーの作成

ec2-userをそのまま使わず、開発用のユーザーをつくって作業＆開発する。
[参考：AWSで開発用のユーザーをつくってCloud9でlaravelを立上げる(Permissionの備忘録)](https://qiita.com/outase/items/6167a17d29df0c57674c)

###LAMP環境の構築とCloud9の設定とLaravelのインストール

手順としては、
1. LAMP環境構築
2. Cloud9の設定
3. Laravelのインストール
になる。

[LAMP環境の構築とLaravelのインストールについてはこちら](https://qiita.com/outase/items/0de097cc51d1ff037bd7)
[Cloud9の設定はこちら](https://qiita.com/outase/items/6167a17d29df0c57674c)

※今回は、wwwグループは作らずに、apacheグループに開発用ユーザをaddしています。


###cloud9の設定時にnode.jsのパスを求めら、Node.jsをインストールした
[node.jsのインストールはこちらを参考にさせていただきました。](https://qiita.com/oishihiroaki/items/bc663eb1282d87c46e97#5-ec2%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%BF%E3%83%B3%E3%82%B9%E3%81%ABnodejs%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B)
※こちらは手順5までしかやりません。5までやったら、下記のコマンドでnode.jsのパスを調べて、Clodu9の設定時に入力します。

~~~
$ nvm which node
~~~

###php.iniの参照設定がうまくいかなかった。

~~~
$ sudo vi /etc/httpd/conf.d/custom.conf

#これではうまくいかなっかた。いくときといかない時がある。もっとphpとapacheの勉強したい。
PHPIniDir "/var/www/config/"

#これでうまくいった
<IfModule php7_module>
    PHPINIDir "/var/www/config/"
</IfModule>
~~~

###バーチャルホスト の設定
[手順はこちら](https://qiita.com/outase/items/9bf2766c34fd752ce069)

###phpMyAdminの設定
[手順はこちら](https://qiita.com/outase/items/688c032a835700afc9d8)
【bash】Githubのissueで使えるラベルを自分好みに初期化する

#はじめに
Githubの課題管理機能issueでは好きなラベルを作成してissueに付与することにより課題を分類することができますが、ラベルの管理はリポジトリ単位となるため、別のリポジトリで同じラベルを使いたい場合はそのたびにラベルを再作成する必要があります。（デフォルトのラベルだけは既定で作成されていますが。）

そこで、ここでは以下を実現するコマンドを紹介します。

- ラベルのテンプレートを用意して新規リポジトリですぐに利用する
- 既存リポジトリからラベルを使いまわす

[2019/02/18 追記]
RestfulAPIによるもっとスマートな方法を紹介されている記事を見つけてしまいました。
BashではなくAPIで初期化したいという方は[Github APIを使ってラベルのセットアップをする](https://qiita.com/segawa/items/8c97e626326b68d5750a)の方をご参考ください。

#前提

- bashコマンドを利用します。bash環境にjq、sed、curlが未導入の場合はインストールしておいてください。
- https://github.com/settings/tokens より自分のGithubアカウントのアクセストークンを取得しておいてください。
- ラベルを初期化するリポジトリ、コピー元となる既存リポジトリのオーナーは自分のGithubアカウントである前提とします。

#手順
bash環境にてコマンドを実行していきます。

まず変数を指定。

```shell
token=＜アクセストークン＞
owner=＜アカウント名＞
dst_repo=＜初期化リポジトリ名＞
src_repo=＜既存リポジトリ名＞
```
必要に応じて１，２，３の初期化コマンドを実行。

- 初期化１：リポジトリ(dst_repo)に作成済みのラベルを全削除（※）

```shell
json=$(curl -u :${token} https://api.github.com/repos/${owner}/${dst_repo}/labels)
len=$(echo $json | jq length)
for i in $(seq 0 $(($len - 1))); do
  label=$(echo $json | jq -r .[$i].name | sed -e 's/ /%20/g')
  curl -u :${token} -X DELETE https://api.github.com/repos/${owner}/${dst_repo}/labels/${label}
done
```

- 初期化２：リポジトリ(dst_repo)にラベルのテンプレートを適用

```shell
#テンプレートはお好みで
template='[
{"name": "Priority xxx","color":"c5def5"},
{"name": "Type xxx","color":"d73a4a"},
{"name": "Status xxx","color":"cfd3d7"}
]'
len=$(echo $template | jq length)
for i in $(seq 0 $(($len - 1))); do
  curl -u :${token} -X POST https://api.github.com/repos/${owner}/${dst_repo}/labels -d "$(echo $template | jq .[$i])"
done
```

- 初期化３：既存リポジトリ(src_repo)から別のリポジトリ(dst_repo)へラベルを複製

```shell
exist=$(curl -u :${token} https://api.github.com/repos/${owner}/${src_repo}/labels)
len=$(echo $exist | jq length)
for i in $(seq 0 $(($len - 1))); do
  curl -u :${token} -X POST https://api.github.com/repos/${owner}/${dst_repo}/labels -d "$(echo $exist | jq .[$i])"
done
```
#おわりに
作成したラベルがリポジトリ間で共有されない仕様をどうにかしたいというひとは他にもいるようで、Githubのラベルをセットアップするツールを探してみるといくつも見当たります。しかし実際に行いたい処理は簡単なコマンドで実現可能ですし、ラベル設定のためだけにライブラリを入れて開発環境を汚すのも気がひけたので、こうして自力でコマンドを作成するに至りました。

※日本語ラベルの削除は非対応。URLエンコードを挟む必要があるため後日できそうであれば対応版に更新します。既定で作成されるラベルはすべて英語(+スペース)のためこれらの削除は可能です。
Gatsby.jsで静的なWebサイトをサクッと作る（インストールからHTML編集篇）

週末でGatsby.jsを触ってみたので、その共有です。

いろいろできるGatsby.jsですが、公式のHello Worldをベースに**CSS（SCSS）**や**メタ情報の設定**くらいまでを、何度かに分けて解説します。最終的には、静的なWebサイトを**Netlify**あたりにデプロイするまで書こうと思っております。

今回は、インストールからローカルサーバの立ち上げ、HTMLの編集くらいまでいきます。

## Gatsby.jsとは？
[Gatsby.js](https://www.gatsbyjs.org/)はReact.jsベースの静的サイトジェネレーターです。GraphQL、PWA等のモダンな技術に対応しています。

## Gatsby.jsのインストール
まずは、CLIをnpmでインストールしましょう。

```sh
$ npm install --global gatsby-cli
```
（Node.jsのインストールがまだの方は、[こちら](https://nodejs.org/ja/)からインストールするか、[nodenv](https://github.com/nodenv/nodenv)等を使ってください）

完了したら、無事にインストールされているかどうか、以下のコマンドでバージョンを確認してみましょう。

```sh
$ gatsby --version
```

バージョンの数字が表示されれば、成功です。

## 開発環境の設定
シンプルな構成の`gatsby-starter-hello-world`を使い、開発環境を構築しましょう。

まずは、適当な場所にディレクトリを作成し、`gatsby new {プロジェクト名} {Githubのパス}`で`gatsby-starter-hello-world`をダウンロードします。

```sh
$ mkdir gatsby-demo
$ cd gatsby-demo
$ gatsby new hello-world https://github.com/gatsbyjs/gatsby-starter-hello-world
```

すると、こんな感じのファイルが生成されていると思います。

```
.
└── hello-world
    ├── .gitignore
    ├── LICENSE
    ├── README.md
    ├── node_modules
    ├── package-lock.json
    ├── package.json
    ├── src
    │   └── pages
    │       └── index.js
    ├── static
    │   └── favicon.ico
    └── yarn.lock
```

これで準備完了です。

## ローカルサーバーを起動させ、HTMLを編集する
ターミナルで `$ npm run develop` を実行するとローカルサーバーが立ちあがります。たぶん、`http://localhost:8000`なので、こちらをブラウザで見てみましょう。ブラウザ上に`Hello world!`が表示されていると思います。

では、HTMLを変更してみましょう。

`src/pages/index.js`ファイルを開きます。

```jsx:index.js
import React from "react"

export default () => <div>Hello world!</div>
```
`export default () =>`の後ろが`<div>Hello world!</div>`になっていますね。こちらにHTMLを書いていきます。ためしに、テキストを変更してみてください。リロードしなくてもテキストが変更されると思います。便利ですね。

ただ、このままですとHTMLが書きづらいので、少し変更しましょう。

```jsx:index.js
import React from "react"

export default () => (
  <div>Hello world!</div>
)
```
`()`を使うことにより、よりHTMLらしく書くことができます。

注意点として、**`()`のなかに要素はひとつしか書けません。**兄弟要素を書くとエラーになります。

```jsx:index.js
import React from "react"

// これはエラー
export default () => (
  <div>Hello</div>
  <div>world!</div>
)
```

```jsx:index.js
import React from "react"

// これならOK
export default () => (
  <div>
    <p>Hello</p>
    <p>world!</p>
  </div>
)
```

今回はここまで！

---

19/2/3: [CSS・SCSS篇](https://qiita.com/otsukayuhi/items/fd821c487c7c49a3120d)を公開しました！
Node.js v11.8.0リリースノート

https://nodejs.org/en/blog/release/v11.8.0/

# events
- For unhandled error events with an argument that is not an Error object, the resulting exeption will have more information about the argument.
    - Errorオブジェクトを引数に持たないエラーが処理されなかった時、引数についての情報を表示するようになった

# child_process
- When the maxBuffer option is passed, stdout and stderr will be truncated rather than unavailable in case of an error.
    - maxBufferオプションが渡されたとき、それを超えてエラーが発生した場合に出力が切り捨てられるようになった

# policy
- Experimental support for module integrity checks through a manifest file is implemented now.
    - マニフェストファイルを用いて行うモジュールの整合性チェックが試験的にサポートされた

# n-api
- The napi_threadsafe_function feature is now stable.
    - napi_threadsafe_function機能がstableになった

# report
- An experimental diagnostic API for capturing process state is available as process.report and through command line flags.
    - プロセスの状態を取得するための試験的な診断用APIが、process.reportとコマンドライン引数を指定することで利用できるようになった

# tls
- tls.connect() takes a timeout option analogous to the net.connect() one.
    - tls.connect()でnet.connect()と同様のタイムアウト用オプションを使えるようになった

# worker
- process.umask() is available as a read-only function inside Worker threads now
    - ワーカースレッド内においてprocess.umask()を読み込み専用の関数として利用可能になった
- An execArgv option that supports a subset of Node.js command line options is supported now.
    - ワーカープロセス作成時に、execArgvを用いることでNode.jsのコマンドラインオプションをそのまま指定できるようになった
Kotlin Bytecode

kotlinで書いててたまにJavaで改修したりPR作成することもあってどういう書き方するんだったっけとなったときにたまに使うのでメモ

```
Android Studio -> Tools -> Kotlin -> Show Kotlin Bytecode
```

`Decompile` でkotlinで書いた内容をJavaで表示してくれる
fishでbashスクリプトを読み込む

fishではbashスクリプトを`source`することは通常できません．一方で、ROSの環境構築等、どうしても読み込まざるを得ない場合があり、そういうときにどうするか書きます．

## TL;DR

bassを使うのがおすすめです．

## 1. 起動シェルをbashにする

「fish bashrc」等で検索するとこの方法がよく見つかります．
起動シェルはbashにし、`.bashrc`に以下のように記入すれば、`something.bash`を読み込みつつ、自動的にfishが起動するので、あたかもfishが起動シェルであるかのように使えるというわけです．

```sh:.bashrc
# 省略して書いているので、ちゃんとした書き方は下のリンクを参照したり、各自調べてください
source something.bash
exec fish
```

詳しくは以下の記事等を確認してください．

https://qiita.com/tak-onda/items/a90b63d9618d6b15c18c

確かにこの方法でも良いのですが、個人的には何か敗北した感じがして、あまり好きではありません．
実際の欠点としては、シェル起動時にしか読み込めないというものが一応挙げられるかもしれません．それで困るケースがどれだけあるのかはよくわかりませんが．

ということで、もう一つの（この記事での位置づけとしては本命の）解決手段を紹介します．

## 2. bassを使う

https://github.com/edc/bass

これはfishでbashコマンドが使えるようになるユーティリティです．
自分はそうですが、fisherを使っている人は、

```sh
# fisher v2 or v4
fisher install edc/bass
# fisher v3
fisher add edc/bass
```

でインストールできます．また、fundleとomfでもそれぞれ、

```sh:config.fish
fundle plugin 'edc/bass'
```

```sh
omf install bass
```

でインストールできるようです（リポジトリのREADMEより）．

bassをインストールさえすれば、あとは`config.fish`等に

```sh
bass source something.bash
```

と書くだけです．簡単ですね．

## 参考

fisherの作者によるawesomeリポジトリです．bassを含め、色々と紹介されているので、チェックしてみるとよいかもしれません．

https://github.com/jorgebucaran/awsm.fish
PDFをテキストに変換してみる

（注）ここでは最終結果だけでなくエラーの試行錯誤も含めて書いていきます。
　　　また中途半端でもアップし後々更新することとします。

#大目的
政府発表の文章を学習とかさせてみたいと思っています。（大雑把）  
数値だけのものより日本語を含むものを読み込ませて日本語の形態素解析なんかも含めて実施したいと思います。  

#今回の目標
とりあえず読み込ませる  

#経緯

##読み込む文章の選定
日銀短観や街角景気指数などが思いついたのですが、見てみると数字の羅列ばかりのため断念しました。日本語が多そうな[経済白書](https://www5.cao.go.jp/j-j/wp/wp-je18/index_pdf.html)をサンプルにしてみようと思います。  
印刷用全体版のall_01.pdf～all_03.pdfを利用します。  

##PDFの読み込み
以下を参考にしました。

https://qiita.com/korkewriya/items/72de38fc506ab37b4f2d
https://tech.bita.jp/article/18  

参考にしたサイトを見ながら作ってみます。
なお、PDFは今回DLしソースと同じフォルダに保管しました。

```
from pdfminer.pdfinterp import PDFResourceManager, PDFPageInterpreter
from pdfminer.converter import TextConverter
from pdfminer.layout import LAParams
from pdfminer.pdfpage import PDFPage
from cStringIO import StringIO
（略）
```

エラーとなりました。
ModuleNotFoundError: No module named 'cStringIO'  
```
from cStringIO import StringIO  
```
がPython2用のモジュール構成のようです。  以下のように修正しました。
```
from io import StringIO 
```

続きです。

```
def convert_pdf_to_txt(path):
    rsrcmgr = PDFResourceManager()
    retstr = StringIO()

    codec = 'utf-8'
    laparams = LAParams()
    laparams.detect_vertical = True
    device = TextConverter(rsrcmgr, retstr, codec=codec, laparams=laparams)
    ansStr = ""

    fp = open(path, 'rb')
    interpreter = PDFPageInterpreter(rsrcmgr, device)
    for page in PDFPage.get_pages(fp):
        interpreter.process_page(page)
        str = retstr.getvalue()
        ansStr = ansStr + str
    fp.close()
    device.close()
    retstr.close()
    return ansStr

ansText = convert_pdf_to_txt("all_01.pdf" )
file = open('pdf.txt', 'w')  
file.write(ansText)
file.close()
```

これもエラーとなりました。  
UnicodeEncodeError: 'cp932' codec can't encode character '\ufb01' in position 91751: illegal multibyte sequence  

91751バイト目の文字が悪さをしているようです。  
print(ansText[91751:91751])
で表示させてみると何も出ない、また[91750:91753]とすると「・・・」となります。  
不正な文字があるようなので以下のサイトを参考にエラーを回避してみました。
https://qiita.com/butada/items/33db39ced989c2ebf644

一旦バイト列に変換（エラー無視）します。最後の４行を以下のように変更しました。

```
ansText = convert_pdf_to_txt("all_01.pdf", )
b = ansText.encode('cp932', 'ignore')
ansText_A = b.decode('cp932')
file = open('pdf.txt', 'w')  
file.write(ansText_A)
file.close()
```

出力することができました。  
＜テキスト＞
![text_01.png](https://qiita-image-store.s3.amazonaws.com/0/248083/cbc916b1-d24e-b0cc-05b8-049c124ad939.png)

＜元PDF＞
![pdf_1.png](https://qiita-image-store.s3.amazonaws.com/0/248083/a377db09-f7dd-7b7c-fc6a-e6145edd2f4a.png)
GitBookまとめ

# GitBookと類似ソフトウェアの比較

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Google トレンドで「Gitbook, Penflip, Leanpub, Sphinx, <a href="https://t.co/G5D9oTUiWU">https://t.co/G5D9oTUiWU</a>」の 人気度の動向 を見る - <a href="https://t.co/ESo9wwU1I0">https://t.co/ESo9wwU1I0</a></p>&mdash; kannkyo (@kannkyoshi) <a href="https://twitter.com/kannkyoshi/status/1089923677821427712?ref_src=twsrc%5Etfw">2019年1月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Google トレンドで「Gitbook, Penflip, Leanpub, Sphinx, Pandoc」の 地域で比較した内訳 を見る - <a href="https://t.co/vd3mQwn8AW">https://t.co/vd3mQwn8AW</a></p>&mdash; kannkyo (@kannkyoshi) <a href="https://twitter.com/kannkyoshi/status/1089924149936410624?ref_src=twsrc%5Etfw">2019年1月28日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# GitBookインストール
## 事前準備
GitBookが使っているnpmを初期化。

```shell
npm init
```

## インストール
### プロジェクト毎にインストールする場合
```shell
npm install --save gitbook-cli
```

### グローバルにインストールする場合
```shell
npm install -g gitbook-cli
```

# GitBookコマンド
## 初期化

```shell
git init
```

## 文書生成

```shell
git build
```

## 文書確認

```shell
git serve
```

## プラグインインストール
1. [GitBook Plugins](https://plugins.gitbook.com/)でプラグインを検索。
2. `book.json`にインストールしたいプラグイン名を追記。
3. インストールコマンドを実行。

```json:book.json
{
  "plugins": [
    "puml"
  ]
}
```

```shell
git install
```

## ファイル生成

```shell
gitbook pdf ./ ./mybook.pdf
```

# GitBookヘルプ
## ヘルプページ

https://toolchain.gitbook.com/

## コマンドライン上のヘルプ
`gitbook --help`でヘルプが出てくるが、明らかに足りない・・・。

```shell
$ gitbook --help
  Usage: gitbook [options] [command]


  Options:

    -v, --gitbook [version]  specify GitBook version to use
    -d, --debug              enable verbose error
    -V, --version            Display running versions of gitbook and gitbook-cli
    -h, --help               output usage information


  Commands:

    ls                        List versions installed locally
    current                   Display currently activated version
    ls-remote                 List remote versions available for install
    fetch [version]           Download and install a <version>
    alias [folder] [version]  Set an alias named <version> pointing to <folder>
    uninstall [version]       Uninstall a version
    update [tag]              Update to the latest version of GitBook
    help                      List commands for GitBook
    *                         run a command with a specific gitbook version
$ gitbook -V
CLI version: 2.3.2
GitBook version: 3.2.3
```

# 非推奨らしい・・・
GitBookのGitHubサイトをよくよく読むと非推奨と書いてある・・・。

>
warning **Deprecation** warning:
As the efforts of the GitBook team are focused on the GitBook.com platform, the CLI is no longer under active development.
All content supported by the CLI are mostly supported by our GitBook.com / GitHub integration.
Content hosted on the legacy.gitbook.com will continue working until further notice. For differences with the new vesion, check out our documentation.

by https://github.com/GitbookIO/gitbook
DataFrameでのデータ操作についての備忘録

こんにちは。統計検定2級を勉強中のエンジニアです。

今回は、
pythonでデータ操作を扱うのに便利なフレームワークpandasの、
DataFrameのメソッドについての備忘録です。

まず事前に
```import pandas as pd```
として、
pandasをインポートしておきます。


```python:CSVの読込
#DataFrameへCSVを読込
df = pd.read_csv('hogehoge.csv')
```

```python:出力
#テキストベースで出力
print(df)

#罫線付きで出力
display(df)
```

```python:行の抽出など
#範囲指定
df1 = df.query('10 <= columnName < 20')

#SQLのinの様に使えます
df2 = df.query('columnName in ["NY", "TX"]')

#特定の文字列を含む
df3 = df.query('columnName.str.contains("hoge")', engine='python')

#正規表現による抽出
df4 = df.query('columnName.str.match(".*i.*e")', engine='python')

#None, NaNの除外
df5 = df.dropna()

#None, NaNの置換（0で置換）
df6 = df.fillna(0)

#変数の埋め込み
val = 100
df7 = df.query('columnName > @val')

#AND条件
df8 = df.query('columnName1 < 25 and columnName2 > 65')

#元のオブジェクト自体も変更（参照渡し）
df9 = df.query('age_year > 25', inplace=True)
```

また、query()メソッドで式を評価するエンジンとして、
pythonとnumexprの2種類が使えるそうです。
（デフォルトではpython）

今回はnumexprは使用していませんが
膨大なデータを扱う場合にはnumexprの方が処理が早くなるそうです。

numexprを使用する場合、
別途pipなどでインストールをして
queryの引数で```engine='numexpr'```と指定してやります。

また、文字列メソッドでは```engine='python'```しか使えないそうです。

詳細については、参考のリンク先をご覧ください。

```python:列、行への加工
#列を加工
df['value'].apply(lambda x: x ** 2)

#列を追加
df.assign(square=(df['value'] ** 2).astype(float))

#行へ加工
df.apply(lambda x: x-x.min(), axis=1)

#全要素へ加工
df.apply_map(lambda x: x ** 2)

#Seriesの全要素へ加工
srs.map(lambda x: x ** 2)

#プログレスパー表示版
#tqdmはアラビア語でprogress
#特にdfのaxis=1は重く、表示してあげると使用感が良くなります
from tqdm import tqdm
tqdm.pandas()

df['square'] = df['value'].progress_apply(lambda x: x ** 2, axis=1).astype(float)
```

C#のLINQ使いとしてはラムダ式使える書き方は嬉しい。
forでグルグルやるより、直感的で可読性高いですね。
プログレスパーが表示できるってのも面白いですね

ループ処理についてはこちらをご覧ください
[pythonのループ処理についての備忘録](https://qiita.com/mounntainn/items/9fe940e6f3f3d4897607)


参考
---
[note.nkmk.me -pandas.DataFrameの行を条件で抽出するquery-](https://note.nkmk.me/python-pandas-query/)
[note.nkmk.me -pandasで欠損値NaNを除外（削除）・置換（穴埋め）・抽出-]
(https://note.nkmk.me/python-pandas-nan-dropna-fillna/)
[apply関数を使って列ごとや行ごとに関数を適用する](https://deepage.net/features/pandas-apply.html)
pythonでファイルパスを表記する方法

#pythonでファイルパスを書く場合のメモ書き

Pythonでバックスラッシュ（￥）を扱う場合のいくつかの方法。


##エスケープシーケンスを使う


```python:バックスラッシュを付ける
filepath = "C:\\user\\joji\\Desktop\\hoge.txt"
```
##生(raw data)データ指定する。
```python:先頭にrを付ける
filepath = r"C:\user\joji\Desktop\hoge.txt"
```


rって生って意味だったんですねー。
スクレイピングでタグから店舗名と住所を取得

[やりたいこと]
喫煙可能な喫茶店のリスト(店舗名と住所)を作成したい。


今回はよくお世話になるドトールさんの店舗リストからスクレイピングし、
喫煙席を有する店舗をピックアップする手法を考える(分煙アイコンや各店舗に入れ子で入って情報取得)

しかしドトールはほとんど喫煙可能（分煙対応）なためシンプルに東京の店舗名をすべて取得することに変更

想定手法
・find_all()でタグの中身(店舗名、住所)を一括取得

手こずった点
・find_allだと中身のテキストをstringでとれない。find()でひとつずつであればfind.stringでとれるが。
  小一時間苦戦
・find_all()で取得し、テキストを加工することにした
　Noneとなってエラーが生じる⇒.stringだとタグ取得はNoneとして処理されるため.textで処理する。

使用したもの
・BeautifulSoup
・requests
・find_all,strip
・zip,enumerate

店舗の名前と住所のタグを確認

```
<dt><span></span><br /><a href="/b/doutor/info/01010009/?shopmastergyokna=1100">ドトールコーヒーショップ 神田西口店</a></dt>
<dd class="MapiInfoAddr">東京都千代田区内神田１‐１７ 小堀ビル１Ｆ</dd>
```

欲しいデータはddタグとaタグの中身であることを確認

```
url = "http://sasp.mapion.co.jp/b/doutor/attr/?t=attr_con&bunen=1&kencode=13&shopmastergyokna=1100"

response=requests.get(url)
res = BeautifulSoup(response.text,"html.parser")
res_ad=res.find_all("dd",class_="MapiInfoAddr")
```
<dd>タグの中のMapiInfoAddr classをすべて取得

```
adresses=[]
for re in res_ad:
    re=re.text
    #textで処理しないとタグで取得しているためNoneになる
    re=re.strip("<dclas=\"MpiInfoAr>")
    adresses.append(re)
```
.textにしないとstrip()で加工ができない。
.stringにするとNone判定となる

```    
res_na=res.find_all("a")
for i in res_na:
    title=i.string
    titles.append(title)
titles=titles[1:24]    

cafe=[]
for i,(name,address) in enumerate(zip(titles,adresses),1):
    id=(i,name,address)
    ids.append(id)

```

これでid番号のついた店舗名と住所のリストが作成できた
GROWI カスタムスクリプト集

[GROWI](https://growi.org/) のカスタムスクリプトのメモ書きです。
他に何か思いついたら更新します。

# スクリプトの読み込み

GROWI の管理画面からカスタマイズ画面（`/admin/customize`）にあるカスタムスクリプトに、以下のコードを入力します。

```js
// 追加するスクリプトの定義を記述
// function something() {
//   ...
// }
$(function() {
  var functions = [
    // ここに関数の名前を列挙する
    // 以下は例
    addLangAttrToHtmlTag,
    openExternalPageInNewTab,
    applyLightBox,
  ];
  for (var i in functions) {
    functions[i]();
  }
});
```

# スクリプト

## HTML タグに lang 属性を付与する

ページの `html` タグには `lang` 属性が付与されておらず、Google Chrome などではページを翻訳するかどうかのダイアログが表示されることがあります。これを抑制できるようにします。

```js
function addLangAttrToHtmlTag() {
  var language = window.navigator.language || window.navigator.userLanguage || window.navigator.browserLanguage;
  $('html').attr('lang', language);
}
```

## パーマリンク文字列のみコピーされるようにする

パーマリンクの右側にあるコピーボタンを押した際、ページタイトルとパーマリンクの両方がコピーされますが、ページタイトルのコピーは不要という状況で使用します。Issue [#493](https://github.com/weseek/growi/issues/493) の対応策となります。

**2019/5/16追記:** v3.4.6 でコピーボタンが新しくなったので、これを使わなくてもできるようになります。

```js
function copyPageUrlOnly() {
  var elem = $('#btnCopyRevisionUrl').attr('data-clipboard-text');
  if (elem !== undefined) {
    var url = elem.split('\n')[1];
    $('#btnCopyRevisionUrl').attr('data-clipboard-text', url);
  }
}
```

## 外部ドメインへのリンクを新しいタブで開かれるようにする

外部ドメインへのリンクは新しいタブで開かれるようにします。`href` に相対パス、もしくは接続先ドメインを含む絶対パスが記述されている `a` タグ以外に `target="_blank"` 属性を付与します。

```js
function openExternalPageInNewTab() {
  $('a[href]').each((i, elem) => {
    var url = elem.href.match(/(?:https?:\/\/([\w:%#\$&\?\(\)~\.=\+\-]+))?(\/?[\w/:%#\$&\?\(\)~\.=\+\-]+)/);
    if (url[1] !== undefined && url[1] !== document.domain) {
      elem.target = '_blank';
    }
  });
}
```

## 画像をクリックして拡大する

LightBox を利用して、画像をクリックすると拡大表示されるようにします。

```js
function applyLightBox() {
  $('head link:last').after('<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/lightbox2@2.10.0/dist/css/lightbox.min.css" />');
  $('head script:last').after('<script src="https://cdn.jsdelivr.net/npm/lightbox2@2.10.0/dist/js/lightbox.min.js"><\/script>');
  $('#page').find('img:not(.emojione)').each(function(i, elem) {
    var a = $('<a>').attr({'href': $(elem).attr('src'), 'data-lightbox': $(elem).attr('alt')||"nothing", 'data-title': $(elem).attr('alt')||"nothing"});
    $(elem).wrap(a);
  });
}
```
世界一シンプルなサーバサイドnodeでES6の始め方

![alt](https://user-images.githubusercontent.com/26253721/39765058-e8d0eae4-531b-11e8-9305-4c852f269517.png)

[翻訳元](https://www.robinwieruch.de/minimal-node-js-babel-setup/)

サーバサイドnodeってcommonjsで書かれることが多いですよね。
フロントエンドの人はcommonjsをみるとES6が使いたくてしょうがなくなります。commonjsも素晴らしいですが、せっかくなので慣れ親しんだES6で開発しましょう。

## プロジェクトを作成

```bash
mkdir my-project-name
cd my-project-name
```

nodeアプリを作成する

```bash
npm init -y
```

// jsファイルはsrcフォルダに入れるのが慣例

```bash
mkdir src
cd src
touch index.js
```


```js
// index.js
console.log('Hello kaba');
```

Nodeアプリが完成しました。
それでは走らせてみましょう。

```js

node src/index.js
```

ターミナルに「Hello kaba」
と表示されて入れば成功です。
Nodeアプリを作ることができました。


nodeにはエイリアスを作成する機能があります。
Package.jsonのscriptプロパティに以下のように記述してください。

```json
// package.json
{
  ...
  "main": "index.js",
  "scripts": {
    "start": "node src/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  ...
}
```


npm startとターミナルに打ちましょう。
コンソールにHello kabaは表示されましたか？

## nodemon
次にnodeの開発に必須なNodemonを入れます。
Nodemonは、コードに変更があると、サーバーをリロードするライブラリです。（ホットリロード）
このライブラリがあるとコードに変更があるたびにnpm startをせずに済みます。

```bash
npm install nodemon --save-dev
```

```json
// package.json
{
  ...
  "main": "index.js",
  "scripts": {
+"start": "nodemon src/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  ...
}
```

まず、npm startしましょう。
次に、index.jsの中身を書き換えます

```
// index.js
console.log(‘Hello kaba. I am node.’)
```

ファイルをセーブすると、ターミナルに「Hello kaba. I am node」と表示されれば成功です。

## babel
ES6でnodeを開発するにはbabelの設定をする必要があります。babel7になり、設定がとても簡単になりました。
もうサーバサイドでもbabelを使って良い時代になりました。

```bash
npm install @babel/core @babel/node --save-dev
```


```json
{
  ...
  "main": "index.js",
  "scripts": {
    "start": "nodemon --exec babel-node src/index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  ...
}
```

```bash
npm install @babel/preset-env --save-dev
touch .babelrc
```

```json
// .babelrc
{
  "presets": [
    "@babel/preset-env"
  ]
}
```

完成です。
これでES6を使うことができます。
それではES6の機能であるexport defaultをindex.jsに記述します。

```js
// index.js
console.log('Hello kaba. I am node.')

const foo = 'foo'
export default foo
```

npm startしましょう。
エラーが起きません！
サーバサイドnodeでES6を使うことが出来ました。

尚、同僚のサーバサイドエンジニアにES6を使うことに文句を言われたら、大人しく引き下がりましょう。
運用の時にES6が壊れるリスクを負うのはサーバサイドの人間です。
vagrant up 時にうまくいかなかった時の解決策

##　経緯
laravelのHomeSteadを使って`vagrant up`を実行時にうまくいかなかったので、その時に発生したエラー内容とやったことをまとめようと思います。

## エラー内容
```
The name of your virtual machine couldn't be set because VirtualBox
is reporting another VM with that name already exists. Most of the
time, this is because of an error with VirtualBox not cleaning up
properly. To fix this, verify that no VMs with that name do exist
(by opening the VirtualBox GUI). If they don't, then look at the
folder in the error message from VirtualBox below and remove it
if there isn't any information you need in there.

VirtualBox error:
```

### 書かれていること
* バーチャルマシンの名前がすでに存在しているため、新しいバーチャルマシンを作ることができません

### 原因と思われることとやったこと
* virtual box に同じ名前の複数バージョンが存在していた
    * 古いバージョンを削除

```
vagrant box list
```
でboxの一覧を確認 

```
$vagrant box list
laravel/homestead (virtualbox, 7.0.0)
$ vagrant remove laravel/homestead --box-version 7.0.0

```
* vmの保存先を削除
    * 以前作った、ものが必要なかったので削除
    
```
$ cd ~/VirtualBox\ VMs/
$  ls                                                                                                     火  1/29 00:12:04 2019
centos7_default_1528123984127_21822 develop_default_1536241538373_29606 webApp_default_1533732167317_74596
centos7_default_1535194345881_13627 homestead-7                         webApp_default_1545396593325_17456
$ rm -rf homestead-7
初めてのVulkanプログラミング step3 サーフェスの作成(GLFW)

[目次に戻る](https://qiita.com/tositada_nakada/items/db0f01c1c8c2945f786b)

ソースコードは以下の場所に置いておきます。各自のバージョンに合わせたプロパティ設定をしてから自由にご利用ください。

[GitHub](https://github.com/nakadasanda/vulkanAppaddcal2018)
##スワップチェーンは、拡張機能
vulkanは、数学的な演算、物理計算の高速化、ビデオストリームの処理など、グラフィクス以外にも使用することができます。その使用用途は、グラフィクス的にモニターに出力結果を表示することに限りません。そのためApiは、OSに依存しません。

レンダリングした画像を表示したいならば、スワップチェーンを使用する必要があります。しかしOSにより、描写のための方法が大きく違います。そのためvulkanのスワップチェーンとサーフェスは、OSに依存する必要があります。


##インスタンス拡張の確認
インスタンス拡張が使用しているデバイスで使えるかどうか確認する必要があります。


```cpp
uint32_t extensions_count = 0;
	vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, nullptr);
	std::vector<VkExtensionProperties> extensions(extensions_count);
	vkEnumerateInstanceExtensionProperties(nullptr, &extensions_count, extensions.data());

	std::cout << std::endl;
	std::cout << "Amount of Extensions " << extensions_count << std::endl;
	for (int i = 0; i < extensions_count; i++) {
		std::cout << std::endl;
		std::cout << "Name:        " << extensions[i].extensionName<< std::endl;
		std::cout << "specVersion: " << extensions[i].specVersion << std::endl;
		
	}
```
##インスタンス拡張

今回は、windowなので、vulkanのインターフェースと、windowsのインターフェースを使用する。

使用するextensionを**vkInstancereateinfo**に入れる

```cpp
const std::vector<const char*>_instance_extensions = {
            VK_KHR_SURFACE_EXTENSION_NAME,
　　　　　　　VK_KHR_WIN32_SURFACE_EXTENSION_NAME
};
	instance_create_info.enabledExtensionCount = _instance_extensions.size();
	instance_create_info.ppEnabledExtensionNames = _instance_extensions.data();

```

##Window surface

vulkanは、ハードウェアに依存しないApiなので、直接ウィンドウシステムと、やり取りをすることができません。
そのため**サーフェス**と呼ばれるウィンドウシステムを操作するための機能を持つ必要があります。
例えばwindowsには、windows用のウィンドウシステム、Androidには、Android用のウィンドウシステムが用意されており、それぞれをvulkanのサーフェスに渡すことで画面の操作ができます。その中で今回は、GLFWのサーフェスを扱います。

GLFWの中には、vulkanのサーフェスを取得する関数が最初からあります。その関数を使うには、GLFW_INCLUDE_VULKAN を有効にしてあげる必要があります。

```cpp
#define GLFW_INCLUDE_VULKAN 1
```

GLFWでは、以下の関数を使うことによってサーフェスを作成することができます。

```cpp
vkSurfaceKHR _surface = VK_NULL_HANDLE;
glfwCreateWindowSurface(_instance, _GLFW_window, nullptr, &_surface);
```
パラメータは、vkInstance,ウィンドウポインター、カスタムアロケータ、そして今回作成するvkSurfaceKHRへのポインターです。

##最後に
今回は、GLFWでのサーフェスの作成を行った。
サーフェスの作成は、OSの環境によってたくさんの方法があるのでそれについて今後書いていきたい。

## 連絡先

tweeter: [tositada_nakada](https://twitter.com/nakadasanda17)
mail: nakadasanda@outlook.com

## 寄付

paypal: [tositada_nakada](https://www.paypal.me/nakadasanda)
Amazon:[欲しいものリスト](http://amzn.asia/fGpGuJo)