OmniAICreator/Qiita-1.07M huggingface dataset:
AccessVBA DAOで選択クエリを発行したら「カレントレコードがありません」

自分用備忘録

# 現象

選択クエリを投げた時、「カレントレコードがありません」と表示されてしまった

# 原因

選択クエリが空振り（結果が0件）したにも関わらず、レコードセット内のデータを参照した


# 例

## 悪い例

たとえば以下のようなコードだと、選択クエリが空振りした場合
MsgBox表示の段階で「カレントレコードがありません」というデバッグメッセージが出てしまい実行が止まる

```VB
Private Sub 取得ボタン_Click()
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    
    Dim sql As String
    
    sql = "SELECT ID, 氏名, 電話番号 FROM 従業員マスタ WHERE ID=" & テキスト.Value
    Set db = CurrentDb
    Set rs = db.OpenRecordset(sql)

    MsgBox "ようこそ" & rs!氏名 & " さん！"

    Set rs = Nothing
    Set db = Nothing
End Sub
```

## 改善例

「レコードセットの終端に到達しているか」を検査することによって回避する

```VB
Private Sub 取得ボタン_Click()
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    
    Dim sql As String
    
    sql = "SELECT ID, 氏名, 電話番号 FROM 従業員マスタ WHERE ID=" & テキスト.Value
    Set db = CurrentDb
    Set rs = db.OpenRecordset(sql)

    If rs.EOF then
        MsgBox "レコードがみつかりません"
    Else
        MsgBox "ようこそ" & rs!氏名 & " さん！"
    End If

    Set rs = Nothing
    Set db = Nothing
End Sub
```
Windows 10のログイン時にアプリを自動起動させる

　この記事は**3分**で読めます。


# はじめに
　タスクマネージャーからスタートアップの起動設定を変更できない一部のアプリがある。これを手動で起動するのが面倒臭いので、自動的に起動するようにしたい。した（完了形）。

# 何をするか
1. ストアアプリ（Windows Store App）のショートカットを作る
2. 1で作ったものをスタートアップに登録する

# 環境
　Windows 10で行います。


# やり方
## 1. ストアアプリのショートカットを作る[^追記]
　`Windowsキー` + `R`キーで**ファイル名を指定して実行**を呼び出す。
　テキストボックスに`shell:appsfolder`と入力し、スタートに登録されているアプリ一覧を開く。
　その中から目的のアプリ（今回は電卓アプリ）を選択し、ショートカットを作成する。
[^※]
![appsfolder.png](https://qiita-image-store.s3.amazonaws.com/0/283828/99e34792-d8b5-236e-1526-f952ee64aeea.png)

[^追記]: 2019年1月15日追記。Build 1803においては、アプリのフォルダからスタートアップのフォルダに直接ドラッグ&ドロップしてもショートカットを作れるみたいです。
[^※]: このとき、「ショートカットを同じフォルダには作成できないので、デスクトップに作成する」といった旨のダイアログが出てくるので、そのまま**はい(Y)**を選ぶ。

## 2. スタートアップに登録する
　1と同様に**ファイル名を指定して実行**に`shell:startup`と入力し、スタートアップを開く。
　このフォルダに表示されているアプリはWindowsにログインすると同時に起動するので、ここに先程作成したショートカットをコピーする。
![startup.png](https://qiita-image-store.s3.amazonaws.com/0/283828/a82dc9d8-c01d-aa86-76cb-76cb3756a4de.png)


## 3. 確認
　Windowsを再起動し、スタートアップのフォルダにコピーしたアプリが正常に起動することを確認する。
　無事に動作したらこれ完了です。お疲れ様でした。


# 参考
- [『Windows10でストアアプリのショートカットをデスクトップに出す方法』 - パソコンりかばり堂本舗](https://www.ikt-s.com/storeapp-desktopshortcut/)
- [『Windows10 起動時にアプリを自動起動 - スタートアップに登録』 - PC設定のカルマ](https://pc-karuma.net/windows-10-app-startup/)

# あとがき
　分かりにくかった部分や、間違えている部分があれば、コメントなどで教えていただけると助かります。
Laravelのマクロ定義のときに$thisまわりででるPhpStormの警告を黙らせる

# はじめに

Laravelのいろいろなクラスに用意されているマクロは足りないメソッドをサブクラスを作らず直接追加する感じで使えてとても強力です。

実際に実行する関数の中身はPHPのクロージャーを使って与えるのですが、実行時には`$this`をそのクラスに束縛しなおしているので、普通にそのクラスのメソッドで行えることは全部できます。private/protectedなメソッド/プロパティにもアクセスできます。

しかしPhpStormは束縛しなおされた`$this`をうまく扱うことができないので、たくさん警告がでます。たとえば以前の記事「[Eloquentでrelationのレコードの有無だけをサブクエリで取得したい](https://qiita.com/crhg/items/48bc300fa91bab77d37d)」で定義したマクロはこんな感じになります。

![スクリーンショット 2018-10-30 15.48.25.png](https://qiita-image-store.s3.amazonaws.com/0/41523/b5495e40-ced2-249a-cba4-b98a2911406f.png)

# 黙らせる方法

いろいろ試して今使っている方法を紹介します。アイディアとしては「`$this`の変化を指定できないのなら、マクロ定義を行うクラスに必要なメソッド/プロパティをannotationを駆使して生やしてしまえばいい」です。

## `@mixin`

`$this`が別のクラスなのがまず問題なので、`@mixin`を使ってマクロを定義するクラスを取り込みます。

```php
/**
 * ......
 * @mixin Builder
 * /
```

これでpublicにアクセスできるプロパティやメソッドはokです。

# `@property`と`@method`

それでもprivate/protectedなプロパティやメソッドについての警告が出てしまいます。

![スクリーンショット 2018-10-30 15.54.27.png](https://qiita-image-store.s3.amazonaws.com/0/41523/1c3a1d31-2652-72dc-39dd-3472a0a3731d.png)

これらを黙らせるには警告が出ているものについて`@property`や`@method`を追加してやります。

```php
/**
 * ......
 * @property \Illuminate\Database\Query\Builder $query
 * @method parseWithRelations(array $relations)
 * @method selectExists($query, $as)
 */
```

# 欠点

`@mixin`,`@property`,`@method`で追加したものは元のクラス(この場合は`AppServiceProvider`)には本来存在しませんが、補完候補などで出てくるようになってしまいます。

`AppServiceProvider`を呼び出すプログラムを自分で書くことはまずないので、この点については目をつぶっています。

# おわりに

出るべきではない警告がたくさん残った状態だと、本当に問題のある警告がもしあっても埋もれてしまってよくありません。かなり無理矢理な方法ですが極力きれいな状態を保つことは意味があると思います。
server.pidがない場合のrails serverのバックグラウンド実行の停止方法

ほぼ個人的メモです。

[A server is already running 対処方法【Rails】](https://qiita.com/uloruson/items/78b0d2d5c30a1f79fc02)
などを参考に、`rails server`のバックグラウンド実行を停止させてから再起動をしていましたが、
いつの間にか`tmp\pids\server.pid`がなくなっていることに気づきました。

なので今まで使っていた

```bash
cat tmp/pids/server.pid | xargs kill
bundle exec rails s -d
```

のような記述が使えなくなったので代替案を探していました。

何かのgemが更新されたとかで`tmp\pids\server.pid`が作られなくなったと思うので、
その原因を探したほうが良かったんですが、下記のように強引に対応しました。

```bash
ps aux | grep [p]uma | awk '{print $2}' | xargs kill
bundle exec rails s -d
```
[psをgrepした結果からgrep自身を除外する方法](https://webkaru.net/linux/ps-grep-exclude/)
などを参考に、psの結果からgrep自身を取り除いてプロセスIDを取得してkillする方法です。
初心者のReact&Redux状態管理思想メモ

## 初めに
React、Draft.js、formikを使って記事編集機能を作った際に、途中からReduxを導入しました。ユニークな記事要素などの状態管理が複雑化したためです。

ちょうどHooksなどReact自体が新機能を発表した直後ではありますが、忘備録ということで。

Reduxを導入し、状態管理について素人ながらにも考えたことなどを書いてみました。


## What to store, what not to store
ReduxのStoreでどこまで状態管理するか、という問題はどうやらいろいろ議論・持論があるようです。

[公式ドキュメント](https://redux.js.org/faq/organizingstate)にもあるとおり、Reduxの責任範囲についての模範解答はありません。
チームやアプリケーションによってそれぞれっぽいですね。

**結論からいうと、自分は全ての状態管理をReduxに任せる必要はないと思っています。**

全てのコンポーネントの全ての状態をredux storeにて管理することはもちろん可能です。ですが、あるコンポーネント内でしか価値のない状態をreduxを通して統一化するのは不必要ともいえます。

たとえばフォームの入力状態などがそれです。ミクロな変更を毎度storeで管理する必要はありません。これらはコンポーネント内で完結していいstateです。

確かにlocal stateとredux storeが混ざっているのは気持ちが悪い。

その点でformikは綺麗にフォームの状態管理を勝手にしてくれるので、本記事の考え方においてのreduxとの相性がいいと思います。


#### あらためて判断基準としては、
- コンポーネント外でも利用・参照価値がある情報はredux storeで管理する
- それ以外の、ミクロな他コンポーネントでの利用価値がない情報はコンポーネント内のlocal stateとして完結させる

という方向でいいかと感じています。

## ロジックの管理

ビジネスロジックがあちこちのコンポーネントに遍在しているのはあまり好ましくありません。
これを解消するべく存在しているのがContainer Component vs. Representational Componentの概念です。
端的にいうとビジネスロジックとDOMマークアップをコンポーネントとして切り分けて管理しよう、みたいな考え方です。

[Presentational and Container Components - Dan Abramov](https://medium.com/@dan_abramov/smart-and-dumb-components-7ca2f9a7c7d0)

状態管理ライブラリを導入していない段階では特に、このコンセプトはいまだ有用です。`hogeComponent`と`hogeComponentContainer`のセットで、UI・UXをいじるときは前者、
ロジックをいじるときは後者、のように切り分けられて、ひとつのコンポーネントがfatになっていくのをある程度抑えることができます。

Reduxとformikを共存させると、ほとんどのロジックがその2つに集約されます。HOCとしてラップさせると、
自然とContainerとRepresentationalを自前に切り分ける必要がなくなり、
コンポーネントはほぼfunctional componentとなっていき、いわゆる"dumb"なものに抑えることができます。

## ちょっとつまったジレンマ

全ての状態をstore管理する必要はないと言ったものの、これを貫徹しようとするとちょくちょく問題が出てきます。

例えばAPIリクエストなど、重要なアクションを上記の通りredux storeで管理する場合、
ローカルなフォーム入力などに関する情報であったとしても、必然的にその結果の状態（レスポンス）もredux storeで管理する必要性が出てきます。

このような境地に立った場合、
- 重要なロジックをできるだけreduxにて集約して管理するとし、functional componentになっていくことを副産物として、振り切る
- コンポーネント内外の状態の価値を重視してAPIリクエストのロジックもコンポーネント内に置く。副次的にclass componentとなる。
の二択になるとおもいます。

これは良し悪しは特になく、その時の開発リソースなどと相談するべきでしょう。既存のclass componentでこのような問題になった場合、取る選択肢は後者でもいい気はします。

ただ一見極端に見える前者に振り切ったほうが、外からは思想が一貫されているように見え、わかりやすいとも言えるかもしれません。

## まとめ
reduxでの状態管理や、新しく追加されたSuspenseやHooksなど、状態管理のエコシステムはますます複雑化していきそうです。
可読性などを考えると一貫したポリシーをおきたくもなりますが、手段が目的化しない程度に引き続き考えていきたいと思います。
Rで関数をプロット（視覚化）


## プロット例

```R
aaa <- function(x) exp(-sqrt(x))
plot(aaa)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99215/894d2991-a1df-80db-6b92-f08d3fd85071.png)

### ガウス関数（正規分布関数（正規分布の確率密度関数））

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99215/ed878553-c13d-cfcd-6e4a-f4edb4331862.png)

$\sigma$: 標準偏差
$\mu$: 平均値

```R:Gauss_function
gauss.density <- function(x) 1/sqrt(2*pi)*exp(-x^2/2)  # 標準正規分布の密度
plot(gauss.density,-3,3)
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/99215/31720906-c7d8-61d6-1010-51b760fd42aa.png)


## 参考

- Rによるプロット
http://cse.naro.affrc.go.jp/takezawa/r-tips/r/48.html

- TeX記法
https://qiita.com/shepabashi/items/27b7284d1f0007af533b
ローカルPCにMicrosoft Cognitive Toolkit環境を構築する

#はじめに
[Microsoft Cognitive Toolkit](https://www.microsoft.com/en-us/cognitive-toolkit/) とは、Microsoft主導のDeep Learningのフレームワークです。以前は「CNTK」と呼ばれていたため、こちらの方が定着しているかもしれません。
同様な機能を提供する製品として、「TensorFlow」「Chainer」「DSSTNE」「Caffe」などが有名で、マイナー感は否めませんがスピードとスケーラビリティ面で優れています。

インストール環境
OS:Windows 10 Enterprise (1803)
GPU無し
#インストール
[Microsoft Cognitive Toolkit](https://github.com/Microsoft/CNTK/releases) から自分の環境にあったパッケージをダウンロードします。
私の環境は、GPUなしなので**CPUのみのバイナリパッケージ**をダウンロードしました。
>GPU版はNVIDIAのグラフィックカードに対応しています。GPUを利用する場合は、最新のドライバーも合わせてインストールしましょう。

ダウンロードしたzipを任意のパスに展開したら、手順に従ってコマンドプロンプトからbatを実行します。

```
c:\local\CNTK-2-6\cntk\Scripts\install\windows\install.bat
```

インターネットから必要なコンポーネントダウンロードするため、インターネット接続が必要です。
環境にもよりますが、インストールには非常に時間がかかるので時間に余裕がある時にやりましょう。(筆者は60分くらいかかりました。)
既にAnaconda,pythonの環境がある場合注意が必要です。素直にbat実行すると新規でAnaconda,python環境をインストールしようとしてしまいます。

#CNTK Python環境を使用するにあたり
CNTK Python環境を使用するためには、下記スクリプトを実行してCNTK環境をアクティブにする必要があります。

```
c:\local\CNTK-2-6\cntk\scripts\cntkpy35.bat
```
あとは、Examplesの中にサンプルがあるので、適当に遊んでみましょう。
#まとめ
python,Anacondaなど未経験の私でも簡単にインストールでき、物体認識のサンプルを動作確認までできたので、それほどハードルは高くない印象です。
PCスペックがプアなので、学習にかなり時間がかかってしまっているので、もう少し遊んでみて慣れてきたらAzureに環境構築してみたいと思います。
#1_JAVA  文字列の中にある一文字を指定してインデックス番号を取得したい

##はじめに

JAVAの練習中に学んだことのメモを残します。

##やりたいこと  *~JAVA~*

文字列中の１文字を指定してインデックス番号を取得

簡単に言えば、「こんにちは」の中に「ん」はどの位置に入っているか！？
という初歩中の初歩の問題です。


##☆文字列.indexOf("検索したいワード")

文字列に「`.indexOf`」メソッドを使うことでインデックスを取得できます。

##JAVAの実装

```java:JAVAコード
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        
        //文字列を宣言
        String str = "こんにちはJAVA";
 
        //インデックス番号の取得
        System.out.println("インデックス番号は:"+str.indexOf("ん"));
    }
}
```
```:出力
インデックス番号は:1
```

これで"ん"のインデックス番号1を取得できました。
要素全体をリンクにする方法

# 注意
以下に記すのは、`li`タグを使用した例です。
`li`だけではなく基本何でも行けるかと思います。

## ふと思った疑問

``` HTML:
<ul>
    <li><a href="#">Link</a></li>
</ul>
```
HTMLでこう打ったら、以下のような実行結果になることはお察しの通り。

 - [aaa](#)

でもこれって...
Aタグの部分だけしか反応しないのでは？

## いつ役立つ？
例えば、CSSを以下のように指定している場合。

``` css:
ul{
    width: 100%;
}
```

このとき、リスト(li)は画面の横幅いっぱいに表示されるが、リンク(a)はその幅のみになる。
そのため、リストをクリック(orタップ)したときにページ移動しない！

## HTML Onlyでリンクにする

~~HTMLだけの場合は~~

```html:
<a href="#"><li>Link</li></a>
```

~~といった具合に`a`タグと`li`タグを逆にすれば`li`タグ全体がリンクになる。~~

追記：ul配下に許可されるのはliだけのようなので、
`li a{display:block;}` とCSSで記述すればいいそうです。
@T_sa さん、ありがとうございます。 

## JavaScriptも使う
JavaScriptを使う場合、`a`タグがなくても可能になるので、
まず`a`タグを使用する場合を説明しますね。

```javascript:
// 全li取得
let lists = document.querySelectorAll('li');
for(let i=0;i<lists.length;i++){
    // 全liそれぞれに対する「クリックされたとき」の処理
    lists[i].addEventListener('click',function(){
        // クリックされたliの子要素 aタグのリンク先を取得
        let href = this.querySelector('a').getAttribute('href');
        // 現在のタブで開く
        location.href = href;
        // 新しいタブで開く
        // window.open(href);
    });

```

 jQueryを使うと 

```javascript:
$('li').click(function(){
    let href = $(this).children('a').attr('href');
    location.href = href;
    // window.open(href);
});
```
となります

## aタグ不使用の例
```html:HTML
<li href="#">aaa</li>
```

```javascript:JS
// liのうち、href属性が指定されているものを取得
$('li[href]').click(function(){
    let href = $(this).attr('href');
    location.href = href;
    // window.open(href);
});
```

ちなみに属性が指定されていないと`undefined`になりますのでそれで判別してもいいかも...
ただ行が長くなるのか...

追記：あと、この方法だとGoogleなどのクローラーがリンクを踏んでくれません
@mikkame さん、指摘ありがとうございます。

## 使い分け
私は一番最後の、aタグを使わないものを使用しているのですが

 - JS使いたくない → 最初のもの
 - `<li><a href="#">Link</a></li>`を変えたくない → 真ん中のもの
 - aタグ打つの面倒くさい → 最後のもの

がいいかと思います。
Webエンジニアの夜間休日の待機に関する各社状況

# 調査概要

+ 弊社ではなんとなく障害対応の労務を以下の様なルールで運営してきていた
    + ![スクリーンショット 2018-10-30 15.39.37.png](https://qiita-image-store.s3.amazonaws.com/0/11006/43cea365-4b93-2bd8-6482-028b69b76876.png)

+ 他社と比較して明らかにおかしかったら見直したいので近隣の人たちにヒアリングをしてみた


# 法律面について

+ 24時間365日の待機でも基本的には労働時間ではない
+ **断続的な業務**は**通常の業務**とは異なる
+ 待機中の行動の自由さがポイント
    + 完全自宅待機命令であれば**労働時間**
    + 自由行動であれば**労働時間ではない**
+ 法律は労働時間以外はあまり守ってくれない

# 他社状況

+ 主に上場企業のWeb系サービスを自社で運営してそうな所に絞って確認
    + 実際にその人がそのサービスを運営してるかどうかは一旦放置
+ シフト勤務性をとっているところは未確認（通信会社とか）

## パターン１：ボランティア

+ 就業規則が完全裁量労働制（フレックスの所もあり）
+ 特に手当もないし、元々出勤時間に縛られないので出社が元々ゆるい

## パターン２：ボランティア亜種（時差出勤）

+ （多分）所属長権限で時差出勤等を認める
    + 就業規則は未確認
+ 特に手当はない
+ タイムカードをつけてない
+ 携帯を支給してる所としてない所があった

## パターン３：残業代支給

+ 対応時の残業代が支給される
+ 時差出勤してる所としてない所がある

## パターン４：待機手当＋残業代支給

+ 対応時の残業代が支給される
+ メインの担当者には待機手当が支給される
    + 一日1,000円ぐらい
+ 時差出勤はケースバイケース
+ 曰く、開発しかしてない人と開発＋運用もしてる人だと精神負荷が後者は高いので、その分を手当という形で支給してる。とのこと
+ また、担当者に義務はなく、愛着だけでやってるのでその分をしっかり還元したいとのこと

# まとめ

+ 夜間・休日の対応は各社ともサービスへの愛でもたせてる感じ
+ その愛に応える仕組みを会社がどのように準備するか？
    + がポイントみたい
+ 現場ヒアリングなので、正確ではないかもしれないが、就業規則に書いてないとこのが多くて、現場ルール感
    + パターン４は希少種

# お願い

+ 事例を多く求めておりますので、他にもあれば教えて下さい！
センサーデータのGoogle IoT Coreを利用した可視化方法

2018年9月にGoogle Cloud NEXTへ出展した際のデモ内容となります。
センサーデータのGoogle IoT Coreを利用した可視化方法を検討したので、書き残しておきます！

可視化までの流れは以下の案を検討しました。

案１　Cloud IoT Core→Cloud Pub/Sub→Cloud Dataflow→BigQuery→GAS→Spreadsheetで表示

案２　Cloud IoT Core→Cloud Pub/Sub→Cloud Dataflow→Logstash→Elasticsearch→Kibanaで表示

案３　Cloud IoT Core→Cloud Pub/Sub→Cloud Dataflow→BigQuery→Tableauで表示 

3つの案から、Googleソリューションで完結させることを想定して、案1で作ってみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247209/75f58b03-9e60-60b0-4846-75268ab6de49.png)

※IoT Coreヘは[Gravio](https://www.gravio.com/jp/gpromo/1810-start-edgeware)からMQTTでデータを送りました。
GravioからGoogle IoT CoreにMQTTで接続(記事作成中)

#Google Cloud Platformの各種サービスについて（備忘録）
作り込みに入る前に使ってみて気づいた事をまとめておきます。
###Cloud IoT Core
IoTデバイスから受信するデータをGCPに流し込むことができるサービス。
MQTTにも対応している。
[https://cloud.google.com/iot-core/](https://cloud.google.com/iot-core/)

###Cloud Pub/Sub
IoT Coreから接続するMQサービス。
複数のトピックを経由させることもできて、経由させることでフィルタリングも可能。
Pub/Subの先はDataFlowに接続する。
[https://cloud.google.com/pubsub/](https://cloud.google.com/pubsub/)

###DataFlow
いくつかのサービス間連携がパッケージ化されたサービス
細かく編集するためには、Javaの知識が必要。
今回は、データを流すためだけに使用したので、細かな動作を編集するために必要なフォルダの構造などは把握できませんでした。
[https://cloud.google.com/dataflow/](https://cloud.google.com/dataflow/)

###BigQuery
クエリ処理を高速にできるデータウェアハウス。
ただし、細かい設定は時間がかかりそう。
[https://cloud.google.com/bigquery/](https://cloud.google.com/bigquery/)

以上が、使ってみての各サービスの印象です。

#Google IoT CoreでCloud Pub/Subに接続
Google IoT Core上の設定をすることで、Cloud Pub/Sub（MQTT Broker）に接続できます。
レジスタの設定で、トピックを指定するだけです。
Cloud Pub/Sub上の新しいトピックを IoT Core側で作成できるのは便利です。
Pubした結果を閲覧するときは、Functionを設定して、ログを見ることで確認できました。

#Cloud Pub/SubからDataFlowを経由してBigQueryヘ
複数のサービスをそれぞれ設定するため、結構混乱しながら作業してました。
順序としては、
１．MQTTの出力データを確認
２．BigQueryのテーブル作成
３．DataFlowの設定
です。
DataFlowの設定は、トピックの指定、BigQueryのテーブルの指定、一時フォルダの指定が必要です。
一時フォルダはStorageにフォルダを作って、その配下にtmpフォルダを作ることで対応可能でした。（ここでStorageも設定していますので、更に触れるサービスが増えた）
トピックで流れているデータ形式と、BigQueryのデータ形式が一緒になるようにします。
もし一緒でない場合は、DataFlowが同じレコードを処理し続ける無限ループに入ります。

ここまで設定ができれば、あとはMQTTを受信したタイミングでDataFlowが動作します。
BigQuery上のデータベースにデータが蓄積されていきます。

#データの可視化のために、スプレッドシートヘ
データ自体は、BigQueryでも閲覧可能ですが、可視化したいですよね。
また、クエリのコマンドを覚えるのも大変なので、簡単にデータも見えるようにしておきたい。。
そこで、スプレッドシートからBigQueryに定期的にデータを取りに来るようにしました。
方法は、こちらの記事を参考にしました。

[【参考】BigQueryとスプレッドシートとGASと。](https://qiita.com/satoru_mag/items/114703d7d95b60b11c6f)

スプレッドシートにグラフをつけておくことで、常時可視化ができました。

#あとがき
GCPをフルに使ってIoTデータの可視化までやってみました。
ただ、どれを使うにも使い方が違うので、時間がかかりました。（作り終えるまで１日程度）
また、初めて触れたサービスが多かったため、全体の費用想定がしにくく、気軽に始めるには少しハードルがあるかな、と思いました。
ただ、癖をすべて把握できれば、早い、安い、わかりやすいサービスなのは間違いないです！

初心者なので間違いなどがあればご指摘ください。

#参考
[モノのインターネットの概要](https://cloud.google.com/solutions/iot-overview)
[GAになったGCPのCloud IoT Coreでデータの受信から可視化まで一通りの流れを作るぞ！](https://qiita.com/Kta-M/items/ad0da8726ffc7b423957)
[BigQueryとスプレッドシートとGASと。](https://qiita.com/satoru_mag/items/114703d7d95b60b11c6f)
CakePHPでCSV出力時にメモリ不足に陥らないために

##思わぬ落とし穴
まず、CSV出力自体はマニュアルや参考資料が豊富に揃っているのでそれほど困らないかと思います。
そう。この手軽さゆえに以下のようなケースに陥りがちです（~~かく言う私も・・・~~）

・テスト環境でCSV出力を実装
・テスト環境でテストデータをもとに色々なパターンでCSV出力
・テストも問題無かったので本番環境に実装
・本番環境でCSV出力実行！　・・・しばらくグルグル・・・
・まだグルグル・・・・・・シュン・・
！！！
まさかの**メモリ不足**による処理落ち・・

はい。理由は本番環境での数万件のデータに対してCSV出力機能が耐え切れなくなったのですね。。
あぁ、テスト環境でダミーデータ数万件用意して負荷テストをするべきだった・・・時すでに遅し・・

##そうならないためにも
以下に、件数が多くてもデータを分割して出力することによりメモリ不足を回避する方法について
紹介したいと思います。（データの分割方法に焦点をあて、CSV出力方法については割愛します）


```ruby:CakepPHP

//100件ずつ分割して
$term = 100;
$this->Model->begin();
$cnt = $this->Model->find('count');
$cnt = (int)ceil($cnt / $term);

//分割した回数分ループ
for ($k = 0; $k < $cnt; $k++) {

    //100件取り出す
    $params['order'] = ['id' => 'asc'];
    $params['offset'] = $k * $term;
    $params['limit']  = $term;
    $data = $this->Model->find('all', $params);

    foreach ($data as $i => $v) {
        //ここでCSVに書き込み
    }
}
//全て書き込みが終わったらcloseして出力
$this->Model->rollback();
```

以上となります。

##ポイント
* データを分割してCSVに書き出す（分割する単位はレコードの長さなどを考慮して調整）
* きちんとテスト環境でもダミーデータを投入して出力確認してみる
Scala IDE for eclipseのscalaのバージョンを切り替える

![eclipseのscalaのバージョンを切り替える.png](https://qiita-image-store.s3.amazonaws.com/0/107052/022afd80-eae5-1c9d-262e-415f95a71f1d.png)

![scala_choice.PNG](https://qiita-image-store.s3.amazonaws.com/0/107052/63d5b5d9-6430-0f8a-2dd4-8a4f4152acdc.png)
よく使うChromeショートカット（Mac版）

### 新規タブを開く
command + t

### アドレスバーにアイコンをあてる
command + l

### デベロッパーツールを表示/非表示する
command + shift + i

### タブを閉じる
command + w

### 閉じたタブを再度開く
command + shift + t

### 左から1~8番目のタブに移動する
command + 1~8

### リロード
command + r

### 指定した矢印の方向のタブに移動
command + option + ←→

### シークレットモードで新規ウィンドウを開く
command + shift + n


## その他
ヘルプに全て載っているので、他はこちらを参照

[Chrome のキーボード ショートカット - Google Chrome ヘルプ](https://support.google.com/chrome/answer/157179?hl=ja)
Markdown記法まとめ！！part2

#強調表示
*hello*
_hello_

**hello**
__hello__

```
斜体
*hello*
_hello_

太字
**hello**
__hello__
```


#箇条書き
- item
* item
+ item

注意点）スペースを空けること

```
- item
* item
+ item
```

#連番付きリスト
1. item1
1. item2
1. item3

ポイント）連番の数字はなんでも良い

```
1. item1
1. item2
1. item3
```


#リンクの表現方法
[Google](http://google.com)

```
[Google](http://google.com)
```
tesserocr と OpenCV を組み合わせてみる

# はじめに

最近始めたばかりの tesserocr と OpenCV で何かやってみたくなったので試してみました。
それぞれ初心者レベルの組み合わせなので、初めての方でもできた気になります（笑）

* [OpenCVで描画してみよう](https://qiita.com/tifa2chan/items/78d4af969cfa837fa988)
* [tesserocrを使ってみる](https://qiita.com/tifa2chan/items/ebd4f4f657201e4b9494)

# やったこと

とりあえず何か試してみたいというわけで、下記をやってみました。
[Python](https://www.python.org/about/)サイトにある、Getting Started部分を画像にしてのテキスト抽出です。


* tesserocrの信頼度スコアが90以上を青、80未満を赤として、テキストにOpenCVで枠をつけます
* tesserocrで画像内の文字を抽出して、抽出された文字をOpenCVで描画します
 

このような結果になりました。（スコアが低くても高いのと対して変わらないように感じます。）
![tesserocr_opencv.png](https://qiita-image-store.s3.amazonaws.com/0/92328/a1dc58be-934f-778a-ca51-a6acbfade657.png)

# ソースコード

tesserocr のサイトにある、Advanced API ExamplesのソースにOpenCVを組み込んだ形のつぎはぎコードです。

```python
import locale
locale.setlocale(locale.LC_ALL, 'C')
import tesserocr
from tesserocr import PyTessBaseAPI, RIL, PSM
from PIL import Image
import cv2

lang='eng'
img_file_name = 'python.png'
image = Image.open(img_file_name)
draw_img = cv2.imread(img_file_name)
font = cv2.FONT_HERSHEY_SIMPLEX

with PyTessBaseAPI(lang=lang, psm=PSM.SINGLE_BLOCK) as api:
    api.SetImage(image)
    boxes = api.GetComponentImages(RIL.TEXTLINE, True)
    print('Found {} textline image components.'.format(len(boxes)))

    for i, (im, box, _, _) in enumerate(boxes):
        x, y, w, h = box['x'], box['y'], box['w'], box['h']
        api.SetRectangle(x, y, w, h)
        ocrResult = api.GetUTF8Text().strip()
        conf = api.MeanTextConf()
        if conf >= 90:
            cv2.rectangle(draw_img, (x, y), (x+w, y+h), (255, 0, 0), 1)
        elif conf < 80:
            cv2.rectangle(draw_img, (x, y), (x+w, y+h), (0, 0, 255), 1)

        cv2.putText(draw_img, str(conf) + ': ' + ocrResult, (x, y), font, 0.6, (255,0,255), 1)

        print ((u"Box[{0}]: x={x}, y={y}, w={w}, h={h}, "
               "confidence: {1}, text: {2}").format(i, conf, ocrResult, **box))

    cv2.imwrite("ouput.png", draw_img)

```
Datadogのhttp_checkでSSL証明書の有効期限チェックを行う

https://docs.datadoghq.com/integrations/http_check/

いつからサポートされていたかは追えてないですが、Datadog の agent に同梱されているhttp_checkを用いることで、Datadog の Agent から任意のサイトの SSL 証明書の有効期限チェックを行うことができます。

以前はこのような機能がhttp_checkにはなかったと思いますが、少なくとも Version 6後のリポジトリの History で当該機能の追加コミットが見当たらないので、その前から機能としては存在していたと思います。

https://github.com/DataDog/integrations-core/commits/master/http_check/datadog_checks/http_check/http_check.py

設定としては、以下のように conf.yaml を設定して、Datadog Agent を restart するだけです。

```
init_config:

instances:
  - name: sada
    url: https://www.sada.co.jp/
    timeout: 1
    method: get
    check_certificate_expiration: true
    days_warning: 30
    days_critical: 7
```

有効期限の何日前になったらアラートを飛ばす、という事も設定できるようです。
上記では、30日前になったら Warning、7日前になったら Critical のアラートを送るように設定しています。


agent check コマンドの実行結果は以下。

```
=== Series ===
{
  "series": [
    {
      "metric": "network.http.response_time",
      "points": [
        [
          1540875810,
          0.09294414520263672
        ]
      ],
      "tags": [
        "env:prd",
        "site:sada",
        "url:https://www.sada.co.jp/"
      ],
      "host": "hogehoge",
      "type": "gauge",
      "interval": 0,
      "source_type_name": "System"
    },
(snip.)
    {
      "metric": "http.ssl.days_left",
      "points": [
        [
          1540875810,
          338
        ]
      ],
      "tags": [
        "env:prd",
        "site:sada",
        "url:https://www.sada.co.jp/"
      ],
      "host": "hogehoge",
      "type": "gauge",
      "interval": 0,
      "source_type_name": "System"
    },
(snip.)

```

Metrics Explorer での表示は以下のような感じになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/44364/6d5b6929-1390-920d-4661-5f36ca46e356.png)
【GAS】S3からファイルを取得してspreadsheetに書き出す

#やりたいこと
GASにてS3のファイルをGETしてspreadsheetに書き出す。
(PUTに関しては情報が多かったが、GETはあまり情報が無く戸惑ったので忘備録に)

# 前提条件
S3操作のライブラリが設定されていること
ライブラリキー：MB4837UymyETXyn8cv3fNXZc9ncYTrHL9
ライブラリ詳細：https://engetc.com/projects/amazon-s3-api-binding-for-google-apps-script/

#コード
```
// S3からファイルを取得して指定のドライブに保存
function getS3File() {
  // S3の接続情報
  var awsAccessKeyId = ""
  var awsSecretKey = ""
  var s3baket = ""
  var s3File = ""

  //グーグルのドライブの保存先フォルダID
  var folderId = ""
  
  // S3に接続してファイルをGET
  var s3 = S3.getInstance(awsAccessKeyId, awsSecretKey); 
  var fromS3 = s3.getObject(s3baket, s3File);
  
  // GETしたファイルをドライブに保存
  var destfolder = DriveApp.getFolderById(folderId );
  var file = destfolder.createFile(fromS3);
  dataImport(file);
}

// TSVファイルのシートへの書き出し
function dataImport( file ) {
  var data = file.getBlob().getDataAsString("utf8");
  var newDataList = Utilities.parseCsv(data, '\t'); // 第二引数で区切り文字(タブ)を設定

  //書き込む対象のSpread Sheetを定義
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sh = ss.getActiveSheet();
　var lastRow = sh.getDataRange().getLastRow();

  // データの出力
  sh.getRange(1, 1, newDataList.length, newDataList[0].length).setValues(newDataList);
}
```

#注意点
日本語名のファイルをGETする場合はエンコードが必要
yum update transaction check error

yum update 中にSSHが切れてしまい、transaction check error が発生しました。
yum update 時に already installed と言われてしまいました。
検索してみると、「32bit版と64bit版のソフトが競合しているため不要な方を削除」という方法が多かったのですが、削除しようにもsystemdやyumの依存ライブラリなどだったようで削除できず。

以下のページの方法でtransactionを綺麗にできました。
https://www.centos.org/forums/viewtopic.php?t=45845

```
yum-complete-transaction
package-cleanup --dupes
package-cleanup --cleandupes --removenewestdupes
```
Metalがやたらメモリリークする問題

#特に何もしてないのにメモリ使用量がやたら増える
前回の記事（ https://qiita.com/shunga/items/33937906188674b85a7b ）でGPUフレームキャプチャを使うとMetalのデバッグが捗ると書いたが、ふと他のゲージを見るとメモリの数字がジワジワ上がっていくことに気づいた。グラフを表示して数分間放置してみると、明らかに時間に比例して使用量が増えていることがわかる。なんだこりゃ。
<img width="746" alt="スクリーンショット 2018-10-30 11.52.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/306129/82e39736-d34e-3d42-f978-0a8ae7dc5866.png">
これは前回で使ったAppleのサンプルコード"Hello Triangle"を手付かずの状態からビルドして実行したものである。ただ静止した三角形を表示しているだけなのに、こんな増え方は明らかにおかしい。Xcodeのバグかと思ってアクティビティモニタも見てみたが、こちらも同じように増えている。一体どういうことなのか。
##GPUフレームキャプチャを無効にすると直る
>Shader memory leak on ios with metal. - Unity Answers
>https://answers.unity.com/questions/1389095/shader-memory-leak-on-ios-with-metal.html

"Metal memoryleak"で検索すると同じように悩んでる奴が結構出てくるが、解決に至ったのは上の記事である。これによると、GPUフレームキャプチャとMetal API validationを無効にすると直るよ、とのことであった。
>Configuring the GPU Frame Capture and Metal API Validation Tools | Apple Developer Documentation
>https://developer.apple.com/documentation/metal/tools_profiling_and_debugging/metal_gpu_capture/configuring_the_gpu_frame_capture_and_metal_api_validation_tools

設定の変更の仕方はApple Devにある。ツールバーのところのプロジェクトアイコン（ビルドの▶︎と■の隣）をクリックしてからEdit scheme...を選択するとGPUフレームキャプチャとMetal API validationを無効にできる。どうやらフレームキャプチャを無効にすると同時にvalidationも無効になるようなので、いじるところは実質ひとつだけでいい。

##直ったーーー！
<img width="709" alt="スクリーンショット 2018-10-30 13.09.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/306129/9e3efbfd-47f4-d431-ce40-1494295c06d5.png">
表示したまま数分放置してみたが、メモリ使用量はほぼ一定のままであった。一件落着....はいいんだけど、ということはフレームキャプチャとメモリリークのデバッグは同時にできないということになってしまった。はよ直らんかなこれ。
ReactNativeでPOSTする


特に何だということはないですが、簡単なPOSTのサンプル。

## API側（PHP）

```php
<?php

    $email = $_POST['email'];
    $password = $_POST['password'];

    $res = [];

    if($email == 'test@test.com' && $password == 'test'){
        $res['status'] = 'OK';
        $res['auth'] = true;
    }else{
        $res['status'] = 'OK';
        $res['auth'] = false;
    }

    header('Content-type: application/json');
    echo json_encode($res);
```

## ReactNative側

### 追加モジュールインストール

```bash
npm install --save react-native-elements
npm install --save axios
npm install
```

### App.js

```js:App.js
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
import { Card, Button, FormLabel, FormInput } from "react-native-elements";
import axios from 'axios';

export default class App extends React.Component {

  state = {
    email : 'test@test.com',
    password: 'test'
  }

  authPost = () => {

    //受け取り側が素のPHP($_POST['']なのでstringifyする)
    //Laravelとかならいらない
    var qs = require('qs');

    axios
      .post('http://localhost/auth/api.php', qs.stringify({email: this.state.email, password: this.state.password}))
      .then((res) => {
        if(res.data.auth){
          alert('認証OK');
        }else{
          alert('認証NG');
        }
      })
      .catch(error => console.log(error));
  }

  render() {
    return (
      <View style={{paddingVertical:20}}>
        <Card>
          <FormLabel>Email</FormLabel>
          <FormInput
            autoCapitalize='none'
            value={this.state.email}
            onChangeText={text => this.setState({email:text})}
          />
          <FormLabel>Password</FormLabel>
          <FormInput
            secureTextEntry
            value={this.state.password}
            onChangeText={text => this.setState({password:text})}
          />
          <Button
            title='送信'
            buttonStyle={{marginTop:20}}
            borderRadius={10}
            onPress={() => this.authPost(this.state.email, this.state.password)}
          />
        </Card>
      </View>
    );
  }
}

```
Nextcloud のノート機能

#はじめに
ちょこっとしたメモを書く時に、EvernoteやOneNoteを使っている方は多いと思います。スマートフォン対応もしているので、どこでもメモを残せて便利ですよね。Nextcloudでも、ノート機能が提供されていますので、OneNoteと同じような事ができます。

#Notesプラグイン
まず、プラグインの紹介です。結構前から提供されてます。（Nextcloud社の方が作っているみたいですが、公式ではないようですね。）
![画像17.png](https://qiita-image-store.s3.amazonaws.com/0/308127/33b8c017-57e2-270d-46c1-2b5177031785.png)

#使い方
アプリを有効にすると、ブラウザー上部のメニューに、「ノート」が表示されるので、クリックします。
![画像18.png](https://qiita-image-store.s3.amazonaws.com/0/308127/c4949e72-df97-c4f4-8d5e-f36784f0bf1c.png)

2分割された画面が表示されるので、左側の＋で新しいノートを作成し、右側でメモが入力できます。自動保存されるので、そのまま閉じても大丈夫です。
![画像19.png](https://qiita-image-store.s3.amazonaws.com/0/308127/beb935bf-4145-d52f-077f-97c412129441.png)

自分のホーム画面に戻ると、「Notes」というフォルダが作成されます。
![画像20.png](https://qiita-image-store.s3.amazonaws.com/0/308127/0a2277d4-d77d-10e2-3553-8f3b3371e233.png)

作成したメモはその配下に自動保存されていきます。テキスト形式で保存されるので、そのまま共有なんかもできますね。
![画像21.png](https://qiita-image-store.s3.amazonaws.com/0/308127/3739c09d-6f9b-0e1b-c7aa-c56213c7fcc2.png)

#まとめ
EvernoteやOneNoteみたいに、写真を貼りつけて・・・みたいな事はできませんが、テキストだけでも結構便利ですよ。ちなみにスマフォ用のアプリは有料みたいです・・・。まぁ、Nextcloudはレスポンシブ対応にもなっているので、スマートフォンのブラウザで開いても十分操作できますしね。
![画像29.png](https://qiita-image-store.s3.amazonaws.com/0/308127/0d7e31e3-929b-6e34-c48a-b5b99a066273.png)

Niedermann IT-Dienstleistungen社製のモバイルアプリはNextcloud Notesはこちら。
https://play.google.com/store/apps/details?id=it.niedermann.owncloud.notes&hl=ja

iOS版はありませんが、App Storeにある類似のCloudNotesでも利用できるようです。
‎CloudNotes - ownCloud Notes im App Store
https://itunes.apple.com/de/app/cloudnotes-owncloud-notes/id813973264?mt=8

この記事は、[スタイルズ社のNextcloudサイト](https://nextcloud.stylez.co.jp/nextcloudblog)にも公開しております。
FlaskアプリをHerokuへ（完全自分用）

HerokuでFlaskアプリを作りたくて記事を探していたら、＠Rowingさんが「Heroku初心者がFlaskを使った簡素なアプリケーションをデプロイするまで！」にて、テンプレートとともに、分かりやすく解説していました。
https://qiita.com/Rowing0914/items/de16bc2676705bd94d24

ここでは「テンプレートをクローンして、いじって再デプロイする方法」をメモ書きします。
上記の記事の手順を前提としています。

***

コマンドプロンプトでテンプレートのディレクトリへ移動。

```
C:\Users\mamapapa\Heroku_training_flask>
```

Herokuにログインして、上記の記事で上げたアプリをクローン。

```
heroku git:clone -a　アプリ名
```
アプリ名はコマンド上でもこちらでも確認できます。
https://id.heroku.com/login

テンプレディレクトリ内にアプリファイルがクローンされているので移動

```
cd アプリ名
```
自分のエディタでテンプレディレクトリ内のクローンアプリを編集して保存
そしたら

```
git add .
git commit -am "make it better"
git push heroku master
heroku open
```
これで編集した内容が表示されています。
アプリ名はHerokuにログインすると編集できます。
改めて＠Rowingさんに感謝します。

##自分用メモ

####クローンからアプリ作成
クローンしたディレクトリをもとに新しいアプリを作りたくなったら、そのディレクトリをコピーして編集してもいい。その場合「Heroku git url」はコピー元と同じになるのでcreateしたあとに新しいURLを確認しに行って

```
git remote set-url (heroku createしたHeroku git url)
```
でurlを変更。そしたらコピーしたプロジェクトフォルダ内のgitフォルダでconfigファイルを開く。そして[remote "heroku"]のurlを新しいHeroku git urlに変更する。

もし他のライブラリを入れたら

```
pip freeze > requirements.txt.
```

その後add commit pushをする。

####仮想環境activate(Windows)
envディレクトリ内で

```
Scripts¥activate
```
####キャッシュオフ
ローカルでflaskアプリを起動させているとき、ページのCSSを変更しても反映されないときがある。そんな時はShift F5

###最初からアプリをつくる
ディレクトリ作成
ディレクトリ内で

```
virtual venv
```
venvに移動してactivate
.gitigoreファイルをエディタで作成
アプリディレクトリを作成して移動

```
pip install flask
```
app.pyとindex.htmlを作成

```
from flask import Flask, render_template
app = Flask(__name__)

@app.route('/')
def hello_world():
    return render_template('index.html')
```
runtime.txtを作成して中にバージョンを書く

```
python-3.6.5（現在のバージョン知るには　python --version）
```
入れたライブラリを記述

```
pip freeze > requirements.txt
```
herokuにgit remoteをセット

```
heroku git:remote -a アプリ名
```
そしたらadd commt push

###PostgresSQLを使う方法

基本的にこの記事の通り。
自分用に補足をメモします。
https://qiita.com/croquette0212/items/9b4dc5377e7d6f292671

psycopg2がpsycopg2-binary==2.7.6.1になってるのでこっちをインストール

まずはHerokuでデータベース作成
したら下記でモデルからテーブル作成

```
heroku run python
>>>from app import db
>>>db.create_all()
```
Ansible初心者がEC2インスタンスを作成する際にはまるポイント

#概要
今回は、Ansible及びDockerを用いて、AWSのEC2にインスタンスを作成し、アプリケーションを起動させるまでの一連の流れを体験しました。その中で、エラーが頻発してなかなか抜け出せないポイントがいくつかあったので、自分用の備忘録も兼ねてまとめたいと思います。

# 環境
- OS: Windows10 pro 1803
- Visual Studio Code:  1.28.2
- Docker: 18.06.1-ce
- ansible:  2.5.5

# AWSと繋がらない
- Dockerでコンテナを立てて、AWSに接続しようとすると、以下のようなエラーが出ることがあります。

```
botocore.exceptions.EndpointConnectionError: Could not connect to the endpoint URL: "https://ec2.ap-northeast-1.amazonaws.com/"
```
## 原因 
少し調べても、エラーの原因は特定できず。現在、Docker for Windowsの動作が不安定であるという記事が散見されるので、今後のアップデートに期待です。
## 解決策
- このエラーは、Dockerを再起動することで回避することが出来ます。

# AWSのCLI設定が行えていない
- AWSに接続してインスタンスを作成する際に、AWS CLIの設定が正しくないために以下のエラー文が出て処理が中断されることがあります。
 
```
 ClientError: An error occurred (AuthFailure) when calling the DescribeKeyPairs operation: Authorization header or parameters are not formatted correctly.
```
## 原因
このエラーは、利用者のセキュリティ認証情報やデフォルトリージョンなどの設定がされてないまま、インスタンスの作成を実行したときに発生します。

## 解決策
Dockerコンテナ作成後に、aws configureコマンドを用いて設定を行うか、ワークスペース内に存在する「.aws」フォルダ内に「credentials」と「config」ファイルを作成して、定義することで回避できます。

# 実行権限がない
Playbookを実行する際に、root権限で実行していないことから、以下のようなエラー文がでることがあります。

```
"You need to be root to perform this command.\n"
```
## 原因
このエラーは、単純に現在Playbookをたたいているユーザーが実行権限を持っていないために、taskを実行できないという状態です

## 解決策
現在実行中のユーザーに権限を付与するか、Ansibleのbecomeモジュールを用いて、ルートユーザーとして実行することで、回避できます。

# ssh接続が切断されて、Playbookの処理が中断される
- アプリケーションのインストール処理などのtaskが終了して、次のtaskに移る際に、以下のようなエラー文がでて処理が終了することがあります。

```
"data could not be sent to the remote host. Make sure this host can be reached over ssh"
```
## 原因
このエラーは、長い処理を行っている際に、処理の終了を待たずに次の処理に進んでしまう場合や、ssh接続の切断などが起こった後に発生します
## 解決策
ansibleのasyncモジュールを用いて、非同期処理を行うことで回避できます。


# まとめ
- エラー文の内容は一見難しいと思えるが、そのまま検索にかければ過去に同じような質問をした人のページに行き着いたりするので、とりあえず検索してみるのがベストかもしれません。
- 基本的に、解決策が見つかっているなら、その策を実現できそうなモジュールがないかを探ることが重要。求めているものがピンポイントでモジュールとして用意されてたりします。
- それでも難しいならcommand、shellモジュールで無理やり解決するのもよいです。しかし、あくまで最終手段として利用するものであり、冪統制の担保が最優先です。
UISwitchのsetOn()でAction接続したメソッドが呼ばれないようにする

# 動作環境
xcode9.4.1
Swift4.1.2

# やりたかったこと
UISwitchをAction接続し、値が変わったときに呼ばれるメソッド`valueChanged(_sender: UISwitch)`を作りました。
そのメソッド内で、特定の処理を行い、処理が完了しなかった場合はUISwitchの値を元に戻す動きを実装したいと考えました。
今回の処理は時間がかかるものであったため、`valueChange(_sender: UISwitch)`が呼ばれた直後にUISwitchの値を戻し、処理が完了した場合に再度、UISwitchの値を変更するように実装しました。

# `setOn()`メソッドについて
UISwitchの値の変更には、`setOn()`メソッドを用いました。
このメソッドは、Appleのドキュメントによると、
`Setting the switch to either position does not result in an action message being sent.`
つまり、`setOn()`メソッドが呼ばれ、UISwitchの値が変わっても、`valueChanged(_sender: UISwitch)`は呼ばれないということのようです。

# 一旦実装してみたが…
```swift:switchChange.swift
@IBAction func valueChange(_ sender: UISwitch) {
        let isOn = switch.isOn
        switch.setOn(!isOn, animated: false)

        /* 時間のかかる後続の処理 */
}
```
簡略化しているが、上記の様に、`valueChange(_sender: UISwitch)`が呼ばれた直後に、`setOn()`を用い、UISwitchの値を反転させています。

しかし、この`setOn()`が呼ばれた直後、再び`valueChange(_sender: UISwitch)`が呼ばれ、二重に処理が行われてしまいました。

# 原因と対策
`setOn()`からはアクションメッセージが送られないから、`valueChange(_sender: UISwitch)`は呼ばれないはず…と思い、調査をしました。
すると、どうやらこの`setOn()`はメインスレッドで呼ばれなかった場合には、アクションメッセージが送られてしまうようでした。
そこで、以下のようにコードを変更しました。

```swift:switchChange.swift
@IBAction func valueChange(_ sender: UISwitch) {
        let isOn = switch.isOn
        DispatchQueue.main.async {
            self.switch.setOn(!isOn, animated: false)
        }

        /* 時間のかかる後続の処理 */
}
```

実行してみると、`setOn()`が行われても、`valueChange(_sender: UISwitch)`は呼ばれず、想定通りの動作を行うことができました。


## 参考文献

https://stackoverflow.com/questions/39566361/uiswitch-seton-animated-does-not-work-as-document
PHPで特定の日付の翌月or先月の年月日を考慮した月末月初を取得する。

# 【修正】PHPで特定の日付の翌月or先月の年月日を考慮した月末月初を取得する

※この記事は有識者の方にコメントを頂いたことにより大幅に修正を行っております。

PHPで年月日を考慮した翌月日付を取得したかったので調べてみました。

参考
https://qiita.com/sawadashota/items/7fc8c6ded17720ddbd9d

## 【Butケース】PHPのdateとstrtotimeを使って翌月と先月を取得

おお！できた？

```php
// 翌月月初
echo date('Y-m-01', strtotime(date('2018-10-01').'+1 month')); // 2018-11-01
// 先月月初
echo date('Y-m-01', strtotime(date('2018-10-01').'-1 month')); // 2018-09-01
```
と思いきや…
コメントでご指摘頂いた通り

### 1日以外を指定すると想定と違う動きが…

1日以外が指定される場合だと想定とは全く違う日付になりました。。。
だめじゃん！

```php
// 翌月月初
echo date('Y-m-01', strtotime(date('2018-10-31').'+1 month')); // 2018-12-01
// 先月月初
echo date('Y-m-01', strtotime(date('2018-10-31').'-1 month')); // 2018-10-01
```

## 【ok】DateTimeImmutableを使って翌月と先月の月初月末を取得

コメントで頂いたコードをそのまま動かしてみると…
おお！ちゃんとできるらしい！！

### DateTimeImmutableとは？
>(PHP 5 >= 5.5.0, PHP 7)
>このクラスの挙動は DateTime とほぼ同じですが、 自分自身は変更せずに新しいオブジェクトを返すという点だけが異なります。
>[PHPリファレンス](http://php.net/manual/ja/class.datetimeimmutable.php)

```php
$dt = DateTimeImmutable::createFromFormat('Y-m-d', '2018-10-31');

// 月初
echo $dt->modify('first day of 00:00:00')->modify('next month')->format('Y-m-d'); // 2018-11-01
echo $dt->modify('first day of 00:00:00')->modify('last month')->format('Y-m-d'); // 2018-09-01

// 月末
echo $dt->modify('first day of 00:00:00')->modify('next month')->modify('last day of')->format('Y-m-d'); // 2018-11-30
echo $dt->modify('first day of 00:00:00')->modify('last month')->modify('last day of')->format('Y-m-d'); // 2018-09-30
```
.
...
......
**がしかし！！**

## Fatal error: Class 'DateTimeImmutable' not found が出たらPHPのバージョンが5.5より低いから

出社30分でそうそうにテストをした所
とある環境ではPHPのバージョンが5.5より低いらしく今回は利用できませんでした！

参考
[PHPリファレンス](http://php.net/manual/ja/class.datetimeimmutable.php)
[Stackoverflow](https://stackoverflow.com/questions/36802769/class-datetimeimmutable-not-found)

## php5.5より低い時はどうすれば…

わかりません！
もしご存知で有ればコメント頂けると助かります！

いつも無知な私にご教示いただき誠にありがとうございます！！

### 案1:月初にしてから月を変える

2018-10-31 -> 2018-10-01

の処理を作ってから

2018-10-01に対してdateとstrtotimeなどで翌月にしてあげる！！
php-master-changes 2018-10-29

今日は substr() の一部条件での最適化対応があった！

# 2018-10-29
## dstogov: Optimize substr() edge-case conditions
- https://github.com/php/php-src/commit/359f19edc9b200dd94a3d30dc14bd4a22903d80c
- [substr()](http://php.net/manual/ja/function.substr.php) のエッジケースでの最適化
- コードの字面を追うと複雑化してるように見えるけど、処理を変えた区間について最悪のケースでの分岐比較回数が 15 回だったのが 7 回になってるかな？
RailsのサービスからPHPでログインしてcookieを使い回す

# やりたいこと
PHPで作られたサービスと、Railsで作られたサービスの２つがある。
ユーザーがPHPのサービスにログインしたときに、同時にRailsのサービスにもログインできているようにしたい。

# 環境
Rails 5.2.0
PHP 5.6.32

# 解決方法
PHPのサービスとRailsのサービスは同じルートドメイン(サブドメインは違う)で動作させているので、cookieを共有できる。

これを利用してPHPサービスにログインされた際、PHPのプログラムからRailsサービスに対してログインし、返ってきたcookieをユーザーのブラウザにも焼いてあげる。

そうすることでPHPサービスにログインしたものと同じブラウザでRailsサービスにアクセスしたら、ログインできているようになる。

# Rails側のコード

session_store.rb に、サービスが動作するルートドメインを書いてあげる。

``` config/initializers/session_store.rb
Rails.application.config.session_store :cookie_store, key: "session_test", domain: ".clst01.innova-jp.net"
```

# Rails側のログイン画面
[devise](https://github.com/plataformatec/devise)で生成されるviewをそのまま使っている。

![スクリーンショット 2018-10-30 12.47.27.png](https://qiita-image-store.s3.amazonaws.com/0/97287/3cdde9a8-bd88-33c9-00a1-33cbd45f1358.png)


# PHP側のコード

``` login.php
$params = array(
  "user[email]" => 'test@innova-jp.com',
  "user[password]" => 'xxxxxx',
  "user[remember_me]" => '0',
  "commit" => "Log in"
);

$cookie_path = '/var/www/html/login_cookie';
touch($cookie_path);

$url = "https://session-test.clst01.innova-jp.net/users/sign_in";

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, TRUE);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_path);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_path);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
$output = curl_exec($ch) or die('error ' . curl_error($ch));
curl_close($ch);

$cookie_string = file_get_contents($cookie_path);
$cookie_values = explode("\n", $cookie_string)[4];
$cookie_values = explode("\t", $cookie_string);
setrawcookie("session-test", trim($cookie_values[6]), 0, "/", ".clst01.innova-jp.net");
unlink($cookie_path);

```

# 焼かれるcookie
意図した通りにcookieが焼けていると、Chromeで確認した時に下記の画像のようになる。
[ドメイン]項目にルートドメインが記載されているのがポイント。

![スクリーンショット_2018-10-30_12_45_38.png](https://qiita-image-store.s3.amazonaws.com/0/97287/57b50d6c-5188-bc2a-8194-2ee58c8566e2.png)

# 備考
PHPの*CURLOPT_COOKIEJAR* で保存されるファイルから、cookieの値だけ取り出す方法がわからなかったので*explode* で頑張ってる。
もっとスマートな方法がありそうな気がする、
InversifyJSで関数に依存性を注入する

## 背景

私用メモ。[公式のWiki](https://github.com/inversify/InversifyJS/blob/master/wiki/recipes.md#injecting-dependencies-into-a-function)にあったので。

## やっていく

途中までは普通にClassに注入するときと同じように`TYPES`とコンテナを作る

```ts
let TYPES: {
    something: "something",
    somethingElse: "somethingElse"
};

export { TYPES };
```

```ts
let inversify = require("inversify");
import { TYPES } from "./constants/types";

// declare your container
let container = new inversify.Container();
container.bind(TYPES.something).toConstantValue(1);
container.bind(TYPES.somethingElse).toConstantValue(2);

export { container };
```

こんなような`bindDepindencies`ヘルパ関数を定義する。

```ts
import { container } from "./inversify.config"

function bindDependencies(func, dependencies) {
    let injections = dependencies.map((dependency) => {
        return container.get(dependency);
    });
    return func.bind(func, ...injections);
}

export { bindDependencies };
```

注入先の関数を定義し、さっきの`bindDepondencies`の第一引数に関数を、第二引数に`TYPES`を渡す。

```ts
import { bindDependencies } from "./utils/bindDependencies";
import { TYPES } from "./constants/types";

function testFunc(something, somethingElse) {
  console.log(`Injected! ${something}`);
  console.log(`Injected! ${somethingElse}`);
}

testFunc = bindDependencies(testFunc, [TYPES.something, TYPES.somethingElse]);

export { testFunc };
```

使う。

```ts
import { testFunc } from "./x/test_func";

testFunc();

// > Injected! 1
// > Injected! 2
```
超初心者がまとめる、Gitと関連用語について。


こんにちは。ゼキと申します。
現在、未経験からRuby on Railsを中心に学習をしております。
自分の頭の中を整理する目的でQiita記事を更新していくことにしました。

初回はGitと関連用語についてです。
リポジトリだったりコミットだったり・・・・
初心者にはその用語自体が訳が分からなかったりしますが、それぞれの自分の解釈を書いてみます。間違っている点気になる点ございましたらご指摘いただけますと幸いです。

#目次
- リポジトリとは   
- コミットとは
- プッシュとは
- クローンとは
- プルとは
- おわりに
        

#リポジトリとは
保存場所のこと。ファイルやディレクトリの状態を保存している
保存している状態は、内容の変更履歴として格納されている。
変更履歴を管理したいディレクトリをリポジトリの管理下におくことで、ディレクトリ内の変更履歴を記録することができる。

- リモートリポジトリ
  - 専用のサーバに配置して複数人で共有する為のリポジトリ
- ローカルリポジトリ
    - ユーザーが手元のマシン上に配置するリポジトリのこと

よく聞くGithubとは、このリモートリポジトリを作成管理できるサービスになります。


##運用方法
普段の作業はローカルリポジトリで作業を行い、その内容を公開したいときはリモートリポジトリへアップロードする。また、リモートリポジトリを通じて他の人の作業内容を取得することができる。

##リポジトリの作成方法
- ローカルで作成する
- リモートリポジトリで作成してそれをコピーする

#コミットとは
ファイルやディレクトリの追加・変更をリポジトリに保存すること。
コミットすることで、コミットした時点での状態が保存される。
新しくコミットすると、前の状態に上書きされるのではなく、前回コミットした状態からの差分を記録したものが作成される。
こまめにコミットすることで、バグが発生した際などにどこからおかしくなったのかを遡ることができる。
コミットを行う際はコミットメッセージを入力する。コミットメッセージとは、行った変更内容を書いておくメモのようなもの。
後から変更内容を調べるときに重要な情報となるので、わかりやすいコミットメッセージを残すようにする。

#プッシュ(push)とは
ローカルリポジトリの内容をリモートリポジトリにアップロードすること。
Pushを実行すると、リモートリポジトリ内の変更履歴がローカルリポジトリと同じになる。

#プル(pull)とは
 リモートリポジトリの内容をローカルリポジトリに取り込むこと。
        複数人で作業をしていると皆がリモートリポジトリにプッシュしていくので、
        プルをして他の人がプッシュした変更内容を取り込む必要がある。

#クローン(clone)とは
リモートリポジトリの内容をまるまるダウンロードすること。
リモートリポジトリに公開されていた内容をそのままローカル環境に構築できる。

#おわりに
Gitの理解にもProgateは大変役に立ちました。
>Progate　Gitコース
>https://prog-8.com/languages/git

Progateで一通りの操作方法を学んだ後は、以下の記事も最初の環境構築の際に役に立つと思います。

>【Mac】Gitの環境構築
>https://prog-8.com/blogs/git-preparation-mac

それでは！
機械学習における自然言語処理とは

自然言語処理とは、人間が使っている言葉（自然言語）を機械に処理してもらうこと。

身の回りでいいうと、Google翻訳機能や予測変換などにも用いられている。

機械学習を行う際に、データをSNSやWikiやNewsなどテキストから
取り出す際、入り用となる。

まずそのテキストデータの種類からみていく。

## テキストデータの種類
まずテキストデータは４種類に分けられる。
１、 カテゴリデータ
２、 自由記述だが意味的にはカテゴリ
３、 構造化された文字列
４、 自由なテキストデータ

この一つずつを簡単に説明すると
## １、カテゴリデータ
赤、青、黄色などあきらかにカテゴリー。
誤字脱字など、同じカテゴリーに含まれるもの、
重複には気をつけなければならない。

## ２、自由記述だが意味的にはカテゴリデータ
カテゴリ変数としてエンコード。
たとえばなんでもよいのだが、夏から秋に変わりかけの頃の夕日の色、など。
カテゴリーに分けづらいので、これは”その他”などといったカテゴリに分けたほうが良い。

## ３、構造化された文字列
住所・電話番号・地名など。
この処理はコンテクストやドメインに応じて対応しないといけないから大変。

## ４、自由なテキストデータ
SNSやWikipediaなど。
使う条件としては１つの言語で書かれているもの。
データセットはコーパス、データポイントは文書と呼ぶ


こうしたテキストデータを機械学習に用いることが可能な形に変える必要がある。
##テキストデータを機械学習に用いることが可能な形へ
最も用いられるテキスト表現を紹介。

* BoW(bag-of-words) 表現  
コーパスに現れた単語がテキスト内に現れた回数を数え、袋に入れる。

その為に行うこと３つ

1、トークン分割
対象の文をトークンに分割（スペースや句読点で句切る）

2、ボキャブラリ構築
すべてのトークンをボキャブラリとして集め、アルファベット順など番号をつける　

3、エンコード
文書に対してボキャブラリの単語が現れる回数を数える

scikit-learnでBoW処理が行える

エンコードまでおわれば特徴量を割り当てた数値表現になった。
ボキャブラリが何単語となったのかわかる。

ちなみにこのBoWの問題点としては、
"not ~~"など、否定形と離れ、逆の意味のボキャブラリとして認識されてしまうことがある。

その点を避けられる方法がn-グラムである。
単一のトークンで句切るのではなく、２つのトークン"バイグラム"
３つのトークン"トリグラム"と変え、攻略できる。


## ボキャブラリを選別していく手法たち
- CountVectorizer
- ストップワード
- tf-idf
- 語幹処理・見出し語化

##CountVectorizer
ボキャブラリを詳しくみる方法の一つ、CountVectorizerのget_feature_name。
個々の特徴量の中身が見られる。

トークンを正規表現を用いて抽出。
つまり、2つ以上の文字か数字が単語ずつで区切られたものをすべて抽出。

CountVectorizerはすべて小文字にしてくれるので
"Ants"　も　"ants"も同じトークンと認識してくれる。

しかしこのままいくと問題点として上がるのことが、
あまり意味を持たない数字などの情報量の少ない特徴量がたくさんでてくること。

その問題を避ける１つの手は、文の中に２つ以上の文書に出てくるトークンのみ
特徴量とすれば良い。
２つ、３つ、、と増やしていくと頻出トークンが残り、数を減らすことができる。

## ストップワード
次に紹介するものが、トークンの中で頻出しすぎて意味のない単語を捨てる方法である。

この実行方法は２つ。
１、ストップワードリストを作る
２、頻度の高い言語を捨てる

１はscikit-learnがfeature_extraction.textモジュールに持っている。
英語のストップワード用であるが。

## tf-idf
tf-idfは特徴量がどの程度情報を持っているかによってスケールを変換する機能。
捨てさるわけではない。

ある一つの文書に頻出するトークンには重みをつけ
すべての文書に頻出するトークンはあまり重みづけしない。

これは、特定の文書にのみ頻出するトークンは、
その内容をよく表すものではないか、ということだそう。

tf-idf実行にはscikit-learnにTfidfTransformer、TfidfVectorizerクラスがある。
　

## 語幹処理・見出し語化
ボキャブラリ抽出時の問題点、
同じ意味の単語でも、複数形、単数形で別に分けられてしまうところである。

その問題を解決する点がこちら
１、語幹処理
末尾を取り除き、語幹のみの形とする。
２、見出し語化
辞書を用いて文章内の単語の役割考慮し取り出す。

両者とも、正規化と呼ぶ。

"had"という単語に対して語幹処理は"ha"と出る可能性もあるが、
見出し語化は"have"と出るため
機械学習においては見出し語化の方がより良い結果が得られる。

## LDA
機械学習においてLDAは２つ、Linear　Discriminant AnalysisとLatent Dirichlet　Allocationがある。
前者は線形クラス分類モデル、今回はトピックを抽出する方法の後者である。

文書ごとにトピックを割り当てることをトピックモデリングと呼ぶ。

LDAは同時に頻出する単語の集合体を探す。
LDA実行時の注意点は、頻出すぎる単語が混ざっているとうまくいかないため、
ある程度削ったものを使用したほうがいい。

##   　

機械学習における自然言語処理とは、
まずテキストを決める。
データ表現を変換する。
その中から特徴量を抽出する。
の流れである。

この処理には様々な方法があり、近年だとリカレントニュートラルネットワークが
上がってきている。
色々試してみる必要があると感じます。

##参考文献
・【事例付き】自然言語処理とは！仕組みやライブラリを解説
（https://techacademy.jp/magazine/17184　2018/10/26閲覧）
・Pythonではじめる機械学習ーscikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
（著者　Andreas C.Muller、Sarah Guido 発行所　株式会社オライリー・ジャパン）
NamedParameterJdbcTemplateをつかったselectのサンプル

備忘録

```java
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Component;

import com.google.common.collect.ImmutableMap;

@Component
public class SampleDao {
    
    @Autowired
    private NamedParameterJdbcTemplate jdbcTemplate;
    
    public Optional<String> find(final String id) {
        var sql = "select id, name from samples where id = :id";
        final var params = ImmutableMap.<String, Object>builder().put("id", id).build();
        return jdbcTemplate.query(sql, params, (rs, num) -> rs.getString("name")).stream().findFirst();
    }

}
```
機械学習の処理を簡単にしてくれるPipelineとは



機械学習においてデータの表現はとても重要。

- スケール変換
- 特徴量の組み合わせ
- 特徴量の学習方法  
など、表現する手段はたくさん。
けれど全部の処理を実行することは大変。

そこで、機械学習で行われたデータ変換、モデル実行など複数の処理を１つなぎにまとめてくれる実行を簡単に行う方法として、【Pipelineクラス】を使う。
##Pipeline
機械学習の中で行われる処理をすべてscikit-learnの１つのEstimatorに格納できる。

Pipelineクラスは前処理ステップとクラス分類器などの教師あり学習モデルと組み合わせる時によく使われる。

たとえば
・スケール変換を行った後にGridSearchCVを用いてSVCのパラメータをより良くしようと考えた。
上記のような複数の処理が行われる場合、データ分割を先に行う必要性がある場合がある。

そのためにPipelineを用いて先に複数の処理をくっつけて前処理のパラメータの調整ができる。

###Pipelineを用いたグリッドサーチ
これも他のEstimatorを同じように行えばOK。
一点、個々のパラメータに対してパイプラインのどのステップに属すか指定する必要あり。

Pipelineクラスが使えるところ
・前処理
・クラス分類
・任意個数のEstimatorの連結

Estimatorを直結させる条件は、transformメソッドが定義されていること。
次の処理で使うデータの準備を行わせるため。

Pipelineは
・scikit-learnのインターフェース、fit、predict、transformを持つPhythonオブジェクトにまとめてくれる
・特徴量抽出、前処理、モデルの正しい組み合わせの試行が簡単になる
といった特徴があります。

以上、大変便利な機能です。
まとめるということは適切な評価のためにとても大事で、コードが簡潔になり、ミスが少なくなる効果があります。

##参考文献
・Pythonではじめる機械学習ーscikit-learnで学ぶ特徴量エンジニアリングと機械学習の基礎
（著者　Andreas C.Muller、Sarah Guido 発行所　株式会社オライリー・ジャパン）
・【python】sklearnのPipelineを使うとできること
（https://www.haya-programming.com/entry/2018/02/22/234011　2018/10/25閲覧）
Railsにおけるリソースとは何か？

##はじめに
[Railsチュートリアル](https://railstutorial.jp/chapters/toy_app?version=5.1#sec-a_user_tour)を進めていて、「2.2.1 ユーザーページを探検する」で、
出てきた<strong>Usersリソース</strong>という単語がわからなかったので、調べてまとめてみました。
##リソースとは
[Ruby on Rails 5アプリケーションプログラミング](https://www.amazon.co.jp/gp/product/B071YC72X1/ref=oh_aui_d_detailpage_o00_?ie=UTF8&psc=1)での、コントローラー名のつけ方を説明した文章中で、
リソースについて触れられていた部分がありましたので抜粋します。
>コントローラー名はできるだけリソース(操作対象のデータ)の名前に沿って命名するのが望ましいとされています。

**リソースとは、操作対象のデータ**となっています。

Railsにおいてデータと聞いて思いつくのが、モデルだと思います。
モデルの役割としては、データベース内のデータ群を操作することです。

このデータ群をUsersモデルとして可視化すると、以下になります。

| id | name | email |
|:-----------|------------:|:------------:|
| 1       | Tom        | tom@mail.com         |
| 2     | Bob      | bob@mail.com       |
| 3       | Eri        | eri@mail.com         |

Usersリソースとは、このUsersモデルのデータ群のことを指します。
##リソースはWEBで扱うことができる
リソースは、WEBで扱かうことができます。
具体手にどういったことかというと、webインターフェイス(URL)を使って扱います。

Railsでは[RESTfulなインターフェイス](http://krs1.hatenablog.com/entry/2016/06/07/180005)を使います。

Usersリソースを使って例に出してみると、
`https://hoge.com/users/new`や`https://hoge.com/users/1/edit`などの
URLを使って扱うことができるということです。
##まとめ
<strong>リソースとは、webインターフェイスで扱うことがでるデータ群</strong>
##参考サイト / 書籍
[Railsドキュメント](http://railsdoc.com/model)
[Ruby on Rails 5アプリケーションプログラミング](https://www.amazon.co.jp/gp/product/B071YC72X1/ref=oh_aui_d_detailpage_o00_?ie=UTF8&psc=1)
[Railsを支える基本概念の整理（RESTfulやリソースなど）](https://qiita.com/kidach1/items/43e53811c12351915278)
[Railsのルーティング(1)~RESTfulとは~](http://krs1.hatenablog.com/entry/2016/06/07/180005)