OmniAICreator/Qiita-1.07M huggingface dataset:
Go言語 runtime.Callerを使ってメッセージやerrorにソースファイル名、行番号を含める

# 概要

プログラムが大きくなるとメッセージやエラーがどのソースファイルのどの行で出しているか調べるのが大変になります。そこれ`runtime.Caller()`を使ってソースファイル名や行番号を取得してメッセージに含めるようにします。

# 環境

- Windows10
- go version go1.12.5 windows/amd64
- runtime.Callerドキュメント
    - https://godoc.org/runtime#Caller

# テスト

```go
package main

import (
	"fmt"
	"path/filepath"
	"runtime"
)

func main() {
	_, file, line, ok := runtime.Caller(0)
	if ok {
		fname := filepath.Base(file)
		fmt.Printf("file: %s, line: %d\n", fname, line)
	}
}
```

ソースのフルパスではなくソースファイル名だけ表示するようにしています。
実行

```
go run main.go
file: main.go, line: 10
```

確かに、`runtime.Caller(0)`を実行したソース名と行番号が表示されました。
次に`error`に含めてみます。

```go
package main

import (
	"fmt"
	"path/filepath"
	"runtime"
)

func check(a, b string) error {
	if a == b {
		return nil
	}
	_, file, line, ok := runtime.Caller(0)
	if ok {
		fname := filepath.Base(file)
		return fmt.Errorf(`check error. "%s" != "%s"; file: %s, line: %d`, a, b, fname, line)
	}
	return fmt.Errorf(`check error. "%s" != "%s"`, a, b)
}

func func01() error {
	return check("a", "b")
}

func main() {
	err := func01()
	if err != nil {
		fmt.Println(err)
	}
	err = check("c", "d")
	if err != nil {
		fmt.Println(err)
	}
}
```


```
go run main.go
check error. "a" != "b"; file: main.go, line: 13
check error. "c" != "d"; file: main.go, line: 13
```

これではソースファイル名、行番号を含めた意味がありません。出来れば`check`を呼び出した行番号が欲しいので`runtime.Caller`の引数を`1`に変えます。

```go
	_, file, line, ok := runtime.Caller(1)
```


```
go run main.go
check error. "a" != "b"; file: main.go, line: 22
check error. "c" != "d"; file: main.go, line: 30
```

希望通りに`check`を呼び出した行番号が表示されました。 `runtime.Caller`の引数の値によって関数呼び出しの階層を戻ることになります。 `runtime.Caller`の使い方が分かったところでもう少し汎用性を持たせた関数にします。さらに、`check`を呼び出した関数名も追加します。


```go
package main

import (
	"fmt"
	"path/filepath"
	"runtime"
)

func makeError(msg string, skip int) error {
	pc, file, line, ok := runtime.Caller(skip)
	if ok {
		fname := filepath.Base(file)
		return fmt.Errorf(`%s; file: %s, line: %d, func: %s`,
			msg, fname, line, runtime.FuncForPC(pc).Name())
	}
	return fmt.Errorf("%s", msg)
}

func check(a, b string) error {
	if a == b {
		return nil
	}
	msg := fmt.Sprintf(`check error. "%s" != "%s"`, a, b)
	return makeError(msg, 2)
}

func func01() error {
	return check("a", "b")
}

func main() {
	err := func01()
	if err != nil {
		fmt.Println(err)
	}
	err = check("c", "d")
	if err != nil {
		fmt.Println(err)
	}
}
```

```
go run main.go
check error. "a" != "b"; file: main.go, line: 27, func: main.func01
check error. "c" != "d"; file: main.go, line: 35, func: main.main
```

スクリプト言語のように便利です。
Vuetify+Cordovaでハイブリッドアプリ開発

Vuetifyを使ったCordovaアプリ開発のサンプル（導入編）

# 前提条件
- Cordovaの開発環境が構築済み

# Vue-Cli 3の導入
```shell
npm install -g @vue/cli
```
確認

```shell
vue --vesion
# 3.8.4
```

# vue プロジェクトの作成

```shell
vue create sample-app
```
※プロジェクト名は小文字じゃないとエラーになる。

## オプションの選択
色々聞かれるのでとりあえずデフォルトで作成

# Vuetify, Cordovaの追加
プロジェクトフォルダに移動しておきましょう

```shell
cd sample-app
```

## vuetify
```shell
vue add vuetify
```
全てデフォルトで。

## Cordova
```shell
vue add cordova
```
Cordovaソースが置かれる場所、アプリ名、パッケージ名が聞かれます。
ネイティブアプリプラットフォームの設定が保存されているsrc-cordovaに、cordovaプロジェクト用の別のsrcフォルダーが作成されます。

# (任意)gitの追加
.gitignoreファイルが自動で生成されているので、ここでgithubのリモートリポジトリを追加します

```shell
git remote add origin https://github.com/xxx/xxx.git
git add .
git commit -m "first commit"
git push -u origin master
```

# Cordova関連コマンドの動作確認

Cordova導入時に設定したソースフォルダに移動します。

```shell
cd src-cordova
```
あとは通常のCordovaコマンドが使用できます。

```shell
cordova platform ls
```

# vueアプリケーションのソースを弄る
src-cordovaフォルダにいる場合は一旦プロジェクトのルートに移動します

```shell
../
```
ソースを触る際は、src/配下のソースを修正します。

## Vueアプリケーションのデバッグ
単純にHTMLとかの確認をしたい場合は、以下のコマンドでサーバーを起動します。

```shell
npm run serve
```
シェルに表示されたアドレスをブラウザで開きます。
（デフォルトはおそらくhttp://localhost:8081）
これで現在のVueアプリケーションがブラウザに表示されます。
Hot reload対応なのでソースを保存すると勝手に画面が更新されます。

# vueアプリケーションをcordovaに適用する

vueアプリケーションをビルドします。
とりあえず、ブラウザで実行してみます。

```shell
npm run cordova-serve-browser
```

・・・が、Windowsだとエラーが出てうまくビルドできません。
Githubに同様のissueが上がっていたのでそちらで進展があったら追記します。

※Macではうまくいくようです。
Visual Studio 201x の devenv.com はどこにある？

devenv.com は Visual Studio の IDE を起動する実行ファイルだが、オプションでコマンドラインからのビルドを行うことができる。

Microsoft はコマンドラインビルドには、devenv.com ではなく MSBuild を使うべきと言っている。だが、VB.Net の DLL をビルドする時、なぜか拡張子が .dll.dll という名前で生成されてしまう現象が過去確認されている（Visual Studio 2013か2015くらいの頃だったと思う。今は直っているかもしれないが）。リネームすればよいが、それもあまりスマートとは思えないため、自分は devenv.com を使う方が無難と判断している。

devenv.com のフルパスについては過去グローバルな環境変数で特定できていたが、2017以降は廃止されている。通常は Command Prompt for vsXX などのショートカットからコマンドプロンプトを起動すれば devenv.com へパスが通る。だが、これで呼び出されるバッチファイルは設定される環境変数がてんこ盛りで起動が遅い。一方で devenv.com 自身は PATH さえ通っていれば利用に支障はないので、このショートカットをあまり利用したくない。

ということで、バージョンごとの devenv.com の場所の特定方法をまとめた。
（以下は 「[Visual Studio のコマンドラインクライアントのラッパー vf1s を作った](http://zetamatta.hatenablog.com/entry/2019/06/22/160031)」よりの抜粋となる）

Visual Studio 2010～2015
========================

環境変数に Tools フォルダーにパスが格納されている。

* 2015 → `%VS140COMNTOOLS%`
* 2013 → `%VS120COMNTOOLS%`
* 2010 → `%VS100COMNTOOLS%`

この環境変数に格納されているパスの `Tools` 部分を `IDE` に置換すると、devenv.com のあるフォルダー名となる。

Visual Studio 2017～2019
========================

環境変数は廃止されている。そのかわり 2017～2019　では

```
C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe
```

というコマンドがある。これの出力から devenv.exe の場所が特定できる。

```
$ vswhere | findstr productPath
productPath: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\devenv.exe
```

* devenv.exe は devenv.com と基本機能は同じだが、コンソールに何も出力されない。コンソール出力を見たいので、拡張子を .com に変えておく。
* 32bit Windows では `C:\Program Files (x86)` は存在しない。また、Program Files が C: ドライブ固定とみなすべきではない。vswhere.exe は環境変数 %ProgramFiles% と %ProgramFiles(x86)% 双方の下の `Microsoft Visual Studio\Installer` から探すようにする。

その上で

* 最新のみ → `vswhere -latest`
* 2019 → `vswhere -version [16.0,17.0)`
* 2017 → `vswhere -version [15.0,16.0)`

とすれば Visual Studio のバージョンを指定できる

以上を元にして、我々が呼び出した適切な Visual Studio の devenv.com のフルパスを検出することがほぼ出来るようになる。

検索を自動化して、適切な devenv.com を呼び出すクライアントを書いた
===========================================================

上記の検索処理はバッチでも書けなくもないが、結構たいへんなので、Go言語で自動化した。

* [Visual Studio のコマンドラインクライアントのラッパー vf1s を作った - 標準愚痴出力](http://zetamatta.hatenablog.com/entry/2019/06/22/160031)
* [zetamatta/vf1s: vf1s - Visual Studio Commandline Client](https://github.com/zetamatta/vf1s)

`vf1s -a` で、カレントディレクトリにあるソリューションファイルで、適当な Visual Studio で、全部のコンフィギュレーションをビルドする。またオプション全部指定でいくなら `vf1s.exe -2019 -c "Release|x86" -re hoge.sln` … Visual Studio 2019 指定で、 hoge.sln というソリューションの `Release|x86` というコンフィギュレーションをリビルドするといったことができる。

よろしければ、ご利用いただきたい。

以上
Python 指定の単語を含む文章を抽出する関数

#目次
1,内容
2,コード
3,終わりに

#内容
ある文章から指定の単語を含む文章をヌキ出したく、悶々としていた夏の思ひで。
オッサンになりレベルアップした結果、遂に完全体になりました。
まあ、とりあえずコード実行してミソ。

#コード
```python:関数
import re
def extract_sentence_by_match_word(base_sentence, match_word, stop_signs):
    # 指定の単語以前をstop_signsまで抽出する
    get_back_sentence = re.search(f"(.*)(?={match_word})(.*?)({stop_signs})", base_sentence).group()
    
    # 抜き出した単語を逆順にする
    rev_sentence = get_back_sentence[::-1]
    
    # 逆順にし、stop_signsから次のstop_signsまで抽出する
    get_rev_sentence = re.search(f"({stop_signs})(.*?)({stop_signs})", rev_sentence).group()
    
    # もう一度逆順にし、base_sentenceから除外したい文章を抽出する
    extract_words = get_rev_sentence[::-1]
    return extract_words
```
コード動かすと結構理解しやすい（図解とかゲロ面倒だからやらぬぅ）

#サンプルコード
```python:サンプルコード
## 対象の文章
base_sentence = """
オートアート

77425 1/18 西部警察　「マシンRS-1」　放送開始40周年記念モデル 
画像はメーカーの見本です。
(2019年 12月以降発売・入荷日が分かり次第、ご連絡させて頂きます。) 
（発売日が延期となる場合がございます。発売日が延期となった場合は、連絡掲示板でご連絡させて頂きます。） 
(落札後1週間以内にオーダーフォーム入力して下さい。）
（落札後1週間以内にオーダーフォーム入力が無い場合は落札者都合での取消となります。)
(お支払い方法ですが、Yahoo!かんたん決済かジャパンネット銀行でのお支払いの場合は、落札後1週間以内にお支払い下さい。） 
（予約商品となります。落札後キャンセル対応はできませんので、あらかじめご了承下さい。） 


　1979年10月の第一作テレビシリーズ放送開始から数えて2019年でちょうど40年、今なお絶大な人気を誇るアクション刑事ドラマ「西部警察」。劇中に登場したスーパー・パトカー「RS軍団」は、当時の最強モデル「日産 スカイライン（DR30）」をベースに最高時速250km/hオーバーにまで改造され、ドラマでの重要な役割を果たしその人気を支えました。今回多くのご要望にお応えし、オートアートの1/18スケールモデルとして2014年に発売後即完売となった「RS軍団」最速の『マシンRS-1』が約5年ぶりに登場。再モデル化にあたっては、新品番とし、再度入念な資料検証を行いモデル各部を改良、内外装のスペシャルパーツもよりリアルに再現しました。フル開閉モデルならではのギミックも存分にお楽しみ頂けます。さらに放送開始40周年を記念し、ディスプレイケース（別売）の台座に貼付したり、モデルと一緒に展示するとスペシャル感がアップする金属製の『40周年記念プレート』が付属します。 ●開閉式二連装20ミリ機銃●急加速装置アフターバーナー●ルーフ大型警光灯●メッシュホイール●エアアウトレット●エアロパーツ●フロントフォグランプ＆赤色灯●助手席大型コンピューター●特殊無線機●ドライバーズシート●ステアリングホイール●「放送開始40周年記念プレート」（金属製・約10×2㎝）付属 ※この商品は日本限定発売モデルです。 石原プロモーション

定価￥２４８００（税抜）
"""

## 指定の単語
match_words = [
    "年",
    "税抜",
    "限定",
    "￥",
    "定価",
    "支払"
]

## 文章を区切る記号
stop_signs = [
    "【",
    " ",
    "。",
    ".$",
    "^.",
    "\n"
]
stop_signs = "|".join(stop_signs)
print("*" * 100)
print(base_sentence)
print("*" * 100)
for match_word in match_words:
    print()
    print("*" * 100)
    print(f"関連の単語 : {match_word}")
    print("抽出した文章 : ")
    print(extract_sentence_by_match_word(base_sentence, match_word, stop_signs))
    print("*" * 100)
```
とりあえず動かすのだ　ﾌｧﾌｧﾌｧﾌｧ

# 大元の文章
<img width="1463" alt="sample1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180478/447e9097-d57a-6cfc-9801-31f025bbf80c.png">

# 色々こねくり回して、指定の単語を含む文章を取得
<img width="1492" alt="スクリーンショット 2019-06-22 16.57.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180478/d1ab457c-84b4-e325-7a9e-d74992722af3.png">
上記はわかりやすくするため、match_wordを★に変えて表示させてます。
今回で言うと【年】というのがmatch_wordであり、その単語の前後の文章をヌキ出します。
プロなら一発で指定の単語の前後をヌキ出せるんでしょうが、
イナカモンのワイにはわからんかったので、文章をひっくり返し、
開始stop_signsから次のstop_signsまで取得しました。

そして、その後逆順にすると正常な文章が返ってきて、一件落着となります。


# 終わりに
全然エラー対策等はしてないが、一旦終了。
これで様々な文章を抽出および削除等が可能になったのが嬉しいし、
初めて汎用性のある関数を作れた気がするし、データ分析官のお役に立てればなにより。

参考サイト
http://straylight-engineer.blogspot.com/2014/01/blog-post.html
https://note.nkmk.me/python-re-match-search-findall-etc/
ローカルでインストールしたMySQLにGUIツールを使って接続してみよう！

#対象読者
MySQLをローカル環境を整えた人
GUIを使って管理したい人
繋げ方がわからない人

#やること
MySQL WorkbenchもしくはSequel Proのどちらかを使ってGUIで管理していきます。
###GUIって？
グラフィカルユーザインターフェース(Graphical User Interface)の略語です。
ディスプレイとマウスを使って、操作するのがGUIです。

#前提
- [こちら](https://qiita.com/YutakaYamasaki/items/035828fdef96b17b36e5)を読んでMySQLのインストールが終わっている方。
- Sequel ProもしくはMySQL Workbenchをインストールしている方
    - Sequel　Proのインストールは[こちら](https://www.sequelpro.com/)からできます。
    - MySQL Workbenchのインストールは[こちら](https://www.mysql.com/jp/products/workbench/)からできます。

WindowsユーザはMySQL Workbenchをインストールしてください。
Macユーザはどちらでもいいです。


#Sequel Proを使う(Macのみ)
開くと下記の画面が表示されます。

<img width="1680" alt="スクリーンショット 2019-06-22 午後3.46.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387875/cd921fa4-2ae0-3ab2-e0ea-847557789b54.png">
各フォームに以下の情報を入れてください。

- 名前
    - 適当に自分の好きな名前をつけてください。
- ホスト名
    - 127.0.0.1(もしくはlocalhost)
- ユーザ名
    - root
- パスワード
    - パスワードを設定していたら、入れてください。設定していなかったら、空白でもOKです。

各情報を入れて、接続のボタンを押すと接続できます！


#MySQL Workbenchを使う(Windows,Mac)
開くと下記の画面が表示されます。
(dockerは気にしないでください。通常は何もないです。)

<img width="1680" alt="スクリーンショット 2019-06-22 午後3.54.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387875/6c694582-4be6-09e3-39fb-5ebda0739ec2.png">

**MySQL Connections** の横に**＋**マークがあるので、そこをクリックすると、下記の画面が表示されます。
<img width="1680" alt="スクリーンショット 2019-06-22 午後3.56.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387875/90fa69e5-f4fb-e05f-0ee3-c59eb4a3fa4b.png">
表示されている画面で、下記必要な項目を入力していきましょう！

- Connection Name
    - 適当に好き名前をつけてください。(ここではlocalhostにします。)
- Hostname
    - 127.0.0.1(もしくはlocalhost)
- Username
    - Username
- Password
    - Store in Keychain...をクリック
    - パスワードを入力してOKをクリック

OKを押すと、下記にdocker以外にもlocalhostの名前が追加されました。
<img width="1680" alt="スクリーンショット 2019-06-22 午後4.01.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387875/dd18cbed-1df3-edbd-d35e-be23b86f7e93.png">

実際に接続してみましょう！
下記のGifのように操作してください！
![mysql.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387875/d2334331-b4d5-d7cd-8d46-db8100228c31.gif)


#最後に
以上でMySQLの接続は完了致しました。
エラー文が出たり、操作がわからなくなったら、コメントしてくれると
追記いたします！
シェルスクリプトのデバッグコマンド

#デバッグコマンドの書置き

Linux CentOS7 におけるスクリプトのデバッグについて書き残しておきます。参考にしたのはこちら、入門UNIXシェルプログラミング改訂第2版　著：ブルース・ブリン　山下哲典訳

shコマンドを利用したデバッグ法の使用法とオプション
使用法：＄sh option scriptfile parm1 parm2

オプション
-e：スクリプト内部のコマンドの終了コードが0以外の時終了する。
-i：対話モードで動作する。
-n：スクリプトを読み込むが実行はしない(よって構文チェックを行うだけ)。
u：未設定の変数を利用したときエラーにする。
-v：何をしようとしているかを表示する。
-x：実行するコマンドの内容を出力する。

echoデバッグ法
消し忘れに注意。
EC2へcapistranoを使ってrailsアプリケーションをデプロイしている場合のログ確認

EC2でrailsアプリケーションをデプロイしています。
その際にページへアクセスした際、以下のようなエラーが、、

The page you were looking for doesn't exist.
You may have mistyped the address or the page may have moved.

If you are the application owner check the logs for more information.

railsがうまく動いていない時のエラーのようなので、
エラーログをみていきます。

# 見るべきログファイルの場所

#### アプリケーションディレクトリ内にあるcurrentというフォルダ
capistranoを使っている場合、ルートディレクトリはこのフォルダになるとのこと

アプリーケーション/current/log
このディレクトリに production.log unicorn.stderr　というファイルがある。

これらのファイルを確認していく

### logの確認コマンド

```
$ less production.log
```

↑ログの一番上から表示させる。

```
tail production.log
```
↑ログの末尾から表示させる。

```
tailf production.log
```
↑ログをリアルタイム更新で確認する




今回はtailfでproduction.logを確認した所、リアルタイムに動いていなかったため
それよりも前の段階でエラーが起きていると考えました。

次にunicorn.stderrを確認したい所だったのですが、
先にunicornが動いているか確認したと所動いていませんでした。

``` 
bundle exec cap production unicorn:start
```

で解決しました。
(Laravel)Homestead環境のDBをSequel Proで接続する(初心者用)

##わざわざ`vagarnt ssh`で入るのが面倒なので、Homestead環境のDBをSequel Proで見れるように接続する


###まずはHomesteadからMySQLを確認

下記の記事を参考にHomestead環境を作って下さい。
[Laravel(Homestead)とVue.jsの環境構築（自分用）](https://qiita.com/namizatop/items/ba3745aff2ac3c59aa18)
（Vue.js構築はシカトして途中のHomestead環境構築まで）

Homestead.yamlの中身で下記の用になっていると思います。

```yaml:Homestead.yaml
databases:
    - homestead
```

上記の記述がDB名になるのでお好きなように変更して下さい。

この状態で`vagrant up`するとHomestead環境にDBが勝手に構築されるので確認。
> 僕の環境では初期のユーザーは`homestead` パスワードは`secret`でした
多分.envファイルに書いてあるのでそこを参考にして下さい。

```terminal
vagrant ssh
mysql -u homestead -p
Enter password:
```

MySQLに入れたので、テーブルがあるか確認。

```terminal
mysql> show datatabases;
+---------------------+
| Database            |
+---------------------+
| information_schema  |
| homestead           |
| #mysql50#lost+found |
| mysql               |
| performance_schema  |
| sys                 |
+---------------------+
6 rows in set (0.01 sec)
```

しっかり`homestead`というDBが作られていることを確認しました。

###やっと本題のSequel Proに接続する

僕の環境だと下記で入れました。
> ホスト(IP): 192.168.10.20
ユーザ名: homestead
パスワード: secret

<img width="1440" alt="スクリーンショット 2019-06-22 16.41.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293438/2209faa7-9d6a-130b-71ee-87ebd0556181.png">

これで入れました。

**繋がらない！！って人は↓**

>ipってなに??って人は`Homestead.yaml`のip設定をみて下さい。

```yaml:Homestead.yaml
ip: 192.168.10.20
```

>ユーザ名とパスワードはどこから??
先ほどターミナルからmysqlに入った時に使用した情報です。

###以上本題より前置きが長いクソ記事でした。
MacにVirtualBoxでCentOS7を導入

## はじめに（注意点）
今年（2019年）6月より業界未経験からエンジニアとして転職した、超初心者新米プログラマーのカッキーです。
成長記録として、日々学んだことをアウトプットしていきます。
チュートリアルというよりは開発ログに近いものになりますのでご了承くださいませ。
**※今回自分はVagrant,VirtualBoxはPCにインストール済みだった為、インストール方法は割愛しています**

## 環境
- macOS 10.14.5
- MacBook Air 2017
- VirtualBox6.0.8
- CentOS 7.6.1810

## 今回の導入にあたって必要な知識
### VirtualBoxとは
**仮想環境である**
自分が使用しているPC(Mac,Windows)に別の**仮想PC**を入れることができるソフトです。
例
自分がMacPCを持っている場合、Mac上にWindows7などを入れて動かすことができる等

### Vagrantとは
**仮想環境**を便利に動かすことができるもの
vagrantコマンドを使うことで**仮想環境**の構築、管理ができる

### CentOSとは
これが分かりやすい笑
[CentOSとは](https://wa3.i-3-i.info/word15502.html)

## CentOS7環境を導入
まずは**box(ファイル）**を追加することから始めます。
これが御本尊であり、これを入れることで仮想環境が構築できる
[Vagrant Cloud公式HP](https://app.vagrantup.com/centos/boxes/7)
上記HPに公式boxである```centos/7```というのがあるのでこれを使った
では早速boxを追加します
**Vagrant Cloudにあるboxを使う場合、下記コマンドのようにbox名だけでOK**

```
$ vagrant box add centos/7
```
を入力後

```
Enter your choice: 3
```

と聞かれるので、今回はVirtualBoxを使っているので上記のように**3**を選択しましょう。

boxが追加されたか確認します

```
$ vagrant box list
```

centos/7とでたら追加OKとなります。

## Vagrantfileという設定ファイルを作成
次に仮想環境の設定ファイルを作成します
**任意のディレクトリにVagrantfileを入れたい場合はこの時点で作っておきましょう**

```
$ vagrant init
```
このコマンドにより、```Vagrantfile(設定ファイル）```が作成されます。

## 仮想マシンを起動
boxを追加し、設定ファイルの作成も完了したので仮想マシンを起動してみます

```
$ vagrant up
```
ずらっとログが流れた後、とりあえず起動の確認をしましょう！

```
$ vagrant status
```
真ん中あたりに```running```となっていれば起動成功です。
気になる方はインストールしたVirtualBoxを開いてみてください
実行中となっているのが確認できるはずです。

## 仮想マシンにログイン
起動も確認済みなので、ログインしましょう

```
$ vagrant ssh
```
```
[vagrant@localhost ~]$
```
上記でログイン完了です。
現時点でログインユーザーは```vagrant```になっています
sudoも使えますし、
vagrantユーザーに切り替える場合は

```
$ su -
```
passwordはvagrantで切り替えることができます。

## まとめ
仮想環境を構築し、実際に仮想マシン起動までを行いました
仮想マシンを動かしたい場合、vagrantコマンドで調べればでてくるはずです。
今回はここまで

## 参考文献
https://qiita.com/sudachi808/items/3614fd90f9025973de4b

https://qiita.com/h6akh/items/0197194b68c5852c7ab0
条件分岐 if を一切使わずに Jacascript でカレンダーを作る

みなさん、カレンダーつくっていますか？

今どきは Google Calendar 埋め込んだりして済ませることも多いんでしょうけど、稀に自分で作らなければいけなくなることがありますよね？

無い方はさようなら。

で、カレンダーの作り方をいろいろ探してみたんですが、ちょっとまどろっこしいというか、条件分岐めっちゃつかっててスマートじゃないなって感じたんですよ。

ということで、ifに頼ることなくカレンダーを作ろうという試みです。

## まずはコードを御覧ください
最初に結論というか、コードを載せてしまいます。

```js
const date = new Date();

// 今月の最終日を取得する
date.setMonth(date.getMonth() + 1);
date.setDate(0);
const lastDate = date.getDate();

// 一ヶ月の日付を配列にする
const dateList = [...Array(lastDate).keys()].map(item => item + 1);

// 今月１日の曜日を取得する
date.setDate(1);
const firstDay = date.getDay();

// 月初より前の部分を作るための配列
const spacer = [...Array(firstDay)];

// カレンダーの最初から最後まであるリストを作る
calendarItems = [...spacer, ...dateList];

// カレンダーに何週分必要か計算
const weekCount = Math.ceil(calendarItems.length / 7);

// 空のカレンダーを作る
const $month = $('<div>')
const $week = $('<tr>');
for (let i = 0; i < 7; i++) {
  $week.append('<td>');
}

for (let i = 0; i < weekCount; i++) {
  $month.append($week.prop('outerHTML'), '\n');
}

// カレンダーに日付を記入
calendarItems.forEach((item, index) => {
  $month.find('td').eq(index).html(item);
})

// カレンダーTABLEに反映させる
$('#calendar-body').html($month.html());
```

HTMLは下記の通り。


```html
<div id="calendar">
  <table>
    <thead>
      <tr>
        <td>日</td><td>月</td><td>火</td><td>水</td><td>木</td><td>金</td><td>土</td>
      </tr>
    </thead>
    <tbody id="calendar-body">
      
    </tbody>
  </table>
</div>
```


## 考え方

ここからはこのカレンダーに関する考え方を説明していきます。

なるべくわかりやすくするため、説明がコードの順序と異なります。ご了承ください。

### カレンダーの枠が決まってるんだから

カレンダーって、枠が決まっているじゃないですか。

必ず1行あたりに7日間あって、それが並んでいるという。

ということは、日付を記載するHTML要素をリスト化して、1から最終日まで日付を入力していけばいいだけなんですよね。

そうすれば条件分岐無しで全然行けてしまいます。

ただ、問題が起こります。

はい、必ず初日が日曜日になってしまいます。

そこでどうするか。

### 日付リストの初日のインデックスが適切であればいいよね

ということで、初日のインデックスを適切にオフセットしてあげれば単純なループで済ませることができるんです。

でもどうやってオフセットしましょう。

そう、初日の曜日番号をとって、その数の要素を日付配列の最初に追加してあげるといいですね。

それが

```js
const firstDay = date.getDay();
const spacer = [...Array(firstDay)];
```

ということです。

ここまでできたらあとはループをブンブン振り回してあげればカレンダーの完成です。

### 月曜日スタートにしたかったらどうすりゃいいの？

日付リストを ```calendarItems.shift() ``` してあげればいいんじゃないでしょうか。

## というわけで

無事、条件分岐を使わずにカレンダーを作ることができました。

これさえつくってしまえば、月の切り替えとかはさほど苦労なくできるでしょう。

もし時間があれば月の切り替えとか、曜日ごとの色付け、祝日の色付けあたりについても投稿してみようかな。

では、これで。
【未解決】androidアプリで、着信の自動受話

#目的
　androidアプリで、電話の着信が来た場合、アプリ側で受話して自動的に通話中にしたい。

#環境
 android7.1

#問題点
 TelephonyManagerで、CALL_STATE_RINGING（着信中）の状態で、
　KEYCODE_HEADSETHOOKのキーイベント発生させても、通話状態に遷移しない。

　Android StudioのTerminalから、adb shellでキーイベントを発生させると、
　通話状態に遷移した。

 `adb shell input keyevent KEYCODE_HEADSETHOOK`

 adbコマンドでは状態遷移したが、ソフトからは遷移できない。
　権限が不足しているのだろうか？

#ソース

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

       final TextView text1 = findViewById(R.id.text);

        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);

        telephonyManager.listen(new PhoneStateListener(){
            // PhoneStateListenerの`onCallStateChanged`をOverride
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                
                switch (state) {
                    case TelephonyManager.CALL_STATE_RINGING:
                        /* 着信 */
                        text1.setText("Call State Changed: CALL_STATE_RINGING");

                        /* 通話を開始する */
                        dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_HEADSETHOOK));
                        dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_HEADSETHOOK));

                        break;
                    case TelephonyManager.CALL_STATE_OFFHOOK:
                        /* 通話 */
                        text1.setText("Call State Changed: CALL_STATE_OFFHOOK");
                        break;
                    case TelephonyManager.CALL_STATE_IDLE:
                        /* 待受 */
                        text1.setText("Call State Changed: CALL_STATE_IDLE");
                        break;
                }
            }
        }, PhoneStateListener.LISTEN_CALL_STATE);
    }

#参考サイト
　「電話着信への応答と拒否」
https://qiita.com/b-wind/items/7e6aac39eefaa9412dee
社員のお弁当の注文を取りまとめて、FAX 送信する LINE WORKS ボット #2

以下の URL の記事の続きです。
https://qiita.com/iwaohig/items/d66a0c2c1663122f9f84

社員からのお弁当を注文する/しないの応答を Bot で受けて、取りまとめます。

##注文を BOT で受信する

[HTTP 要求の受信時] トリガーを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/6f7b7759-588d-6c05-f09d-110c8e79ba6b.png)

ボタン テンプレートの はい/いいえ をタップして応答を返しているかどうかで分岐を作成します。テンプレート以外のメッセージの受信時の処理は適宜作成しましょう。Bot の使い方の説明を返すなど。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/80348682-ca5a-4835-d220-bb41a7a781b7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/f228923d-24f1-aef8-f9d5-b83d3160dbeb.png)

注文数の集計は OneDrive for Business の Excel を利用します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/50348c78-d592-a2fc-c008-1c5df1e7341f.png)

ID をキーに行データを更新します。いったん、「はい」で答えても、後から「いいえ」を送信しなおすとキャンセルできるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/0e91fda1-dcce-714f-de8a-905d4e25246a.png)

テーブルを 2 個作成し、2 番目のテーブルでは countif を用いて発注数の集計をしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/4d1847b3-9e57-6ace-337a-b0f470f77f93.png)

社員の回答に応じて、注文しておきますね/注文しません のメッセージを返します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/396107/dd4d329c-2014-0083-1301-26bcf1ff59ea.png)

##続編で注文書を作成してお弁当屋さんに FAX 送信します。
【内部用】android/javaでのアニメーション

#はじめに
基本的にアプリは動くのでアニメーションは大事です。
特にゲームエディタ企画(ScriptEditor班以外)において今から記述するcanvasのアニメーションは習得必須です
#仕組み
今回はviewのonDrawを繰り返し実行することでアニメーションを実現しています
もっといい方法があるのかもしれません
#注意
**パッケージ名をcom.test.gameeditorとしていますが適切なものに直して下さい**
#activity_main.xml
LinearLayout がrootにあってその中に独自viewがある一般的な編成です

```xml:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.test.gameeditor.MyCanvas
        android:id="@+id/canvas"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>
```
#MainActivity.java
レイアウトをactivity_main.xmlに設定する処理とMyCanvasのonDraw()を60msに一回呼ぶ処理が書かれています

```java:MainActivity.java
package com.test.gameeditor;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.os.Handler;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final MyCanvas canvas = (MyCanvas) findViewById(R.id.canvas);
        final Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                canvas.invalidate();
                handler.postDelayed(this, 60);
            }
        };
        handler.post(runnable);
    }
}
```
#MyCanvas.java
アニメーションの内容をonDraw()の中に記述します。

```java:MyCanvas.java
package com.test.gameeditor;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;
import android.util.AttributeSet;
public class MyCanvas extends View {
    private Paint mPaint = new Paint();
    Context context;
    int x=100;
    public MyCanvas(Context context) {
        super(context);
    }
    public MyCanvas(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
    }
    @Override
    protected void onDraw(android.graphics.Canvas canvas) {
        super.onDraw(canvas);
        x+=5;
        canvas.drawRect(0,0,x,getHeight(),mPaint);
    }
}
```

#あとがき
これをマスターすればアニメーションが描けるよ
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">こいつの作り方を今からQiitaに描いて共有します(ゲームエディタに必須なので) <a href="https://t.co/XkDkgIPjK2">pic.twitter.com/XkDkgIPjK2</a></p>&mdash; hotman (@hotmanww) <a href="https://twitter.com/hotmanww/status/1142311849636945920?ref_src=twsrc%5Etfw">2019年6月22日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Chainer Tutorial 13章の[6]のコードがそのままだとうまく動かなかったのでメモ

題目の通り、Chainer Tutorial 13章の[6]のコードでエラーが出たので、修正した内容をメモしておきます。(2019年6月22日時点)

ちなみにPythonのバージョンは3.6.8です。

```python
# d y / d h1
dydh1 = w2

# d h1 / d u1
dh1du1 = h1 * (1 - h1)

# d u_1 / d w1
du1dw1 = x

# 上から du1 / dw1 の直前までを一旦計算
dLdu1 = dLdy * dydh1 * dh1du1
dLdu1 = dLdu1[None]

# du1dw1は (3,) というshapeなので、g_u1w1[None]として(1, 3)に変形
du1dw1 = du1dw1[None]

# dL / dw_1: 求めたい勾配
dLdw1 = dLdu1.T.dot(du1dw1)

print(dLdw1)
```

真ん中らへんにある以下のコードを挿入しただけです。

```python
dLdu1 = dLdu1[None]
```
Elixir の Getting Started に PR してみる

# Elixir の Getting Started に PR してみる

この記事に必要な範囲で自己紹介すると、

* 最近 Elixir の勉強をしている

です。

## Elixir の [Getting Started](https://elixir-lang.org/getting-started/introduction.html)

公式サイトにある初心者学習用のページです。最近、ここに書いてあるコードを [IElixir](https://github.com/pprzetacznik/IElixir) で試しながら読み進めています。

[Module attributes - Elixir](https://elixir-lang.org/getting-started/module-attributes.html) のページにある下記のコードの実行に失敗したことが、PR を出そうと思ったきっかけです。

```elixir
defmodule MyPlug do
  use Plug.Builder

  plug :set_header
  plug :send_ok

  def set_header(conn, _opts) do
    put_resp_header(conn, "x-header", "set")
  end

  def send_ok(conn, _opts) do
    send(conn, 200, "ok")
  end
end

IO.puts "Running MyPlug with Cowboy on http://localhost:4000"
Plug.Adapters.Cowboy.http MyPlug, []
```

## IElixir で hex package を使う

話が脱線しますが、IElixir で Hex package を使うときの方法を紹介しておきたいと思います。

[IElixir では `Boyle` というモジュールを使って環境の管理ができます](https://github.com/pprzetacznik/IElixir#package-management-with-boyle)。例えば、ノートブックの最初のセルを以下のようにしておけば、[`plug_cowboy`](https://hex.pm/packages/plug_cowboy) のインストールされている `getting_started` という名前の環境で作業をすることができます。ちなみに、`plug_cowboy` は `Plug.Adapters.Cowboy` を使うために必要な package です。

```elixir
defmodule Environment do
  @env_name "getting_started"

  def prepare() do
    unless confirm_env(Boyle.list()) |> is_nil() do
      Boyle.install({:plug_cowboy, "~> 2.0"})
    end
  end

  defp confirm_env({:ok, env_list} = _boyle_list) do
    unless @env_name in env_list do
      Boyle.mk(@env_name)
    end
    Boyle.activate(@env_name)
  end
  defp confirm_env(_), do: nil
end

Environment.prepare()
Boyle.active_env_name()
```

## コードの修正

Getting Started のコードの話に戻ります。ちゃんと依存 package を導入して実行してみたのですが、下記のエラーが出てしまいました。

```
** (CompileError) console:12 "undefined function send/3"
```

実は `Plug.Builder` には `send/3` なんて関数は存在しません。ドキュメントで[検索](https://hexdocs.pm/plug/1.8.2/search.html?q=send)すると分かりますが、今回の用途では `send_resp/3` を使います。

エラーを見ればすぐに分かることですが、無駄な時間の削減に少しだけ貢献できそうなので、修正の PR を出すことにしました。

Elixir の公式ページのソースは [elixir-lang/elixir-lang.github.com](https://github.com/elixir-lang/elixir-lang.github.com) にあるので、これをクローンして PR を出せば良さそうです。

PR link: https://github.com/elixir-lang/elixir-lang.github.com/pull/1293

その結果、速攻でマージしていただきました。しかも Elixir の creator である José Valim さんから[素敵なコメント](https://github.com/elixir-lang/elixir-lang.github.com/pull/1293#issuecomment-504637522)付きで！

## おわりに

ドキュメントのソースが GitHub で公開されている場合は、ドキュメント間違ってんな、で終わらせずに、積極的に PR していきたいと思います！
【C#】指定された月から秒単位までで月初と月末を取得する

# やること
DateTimeの年月の情報から、秒単位までの月初～月末を取得します。

# やり方
月初は`new DateTime(年, 月, 1)`で0時0分0秒として取得できます。
月末は月初に1月足して1ms引く（-1ms足す）ことで求められます。

```cs
private Tuple<DateTime, DateTime> getPeriod(DateTime targetMonth)
{
    var start = new DateTime(targetMonth.Year, targetMonth.Month, 1);
    var end = start.AddMonths(1).AddMilliseconds(-1.0);
    return new Tuple<DateTime, DateTime>(start, end);
}
```

# 参考にさせていただいた記事
- [月末日付を取得する \- \[ 日付・時刻・時間 / C\# \] ｜たかみんつ](http://bicycle.life.coocan.jp/takamints/index.php/snippets/snippet/datetime/lastdayofmonth/cs)
FLASK 　共通テンプレートの作り方【Windows.ver】

共通テンプレートの作り方

1. templetes フォルダにindex.htmlの内容をコピーして新しいファイルlayout.htmlを作成

※index.htmlの内容とは
<img width="478" alt="2019-06-22 (3).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/c03c08c5-ea88-f49d-6afc-6bc82da848ff.png">

このコードを編集してlayout.htmlに共通テンプレートを作っていきましょう！

<img width="528" alt="2019-06-22 (8).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/1996d7fe-9552-2abc-c508-e891efbb50eb.png">

＜body＞＜/body＞の中に
＜P＞共通テンプレート＜/p＞
{% block content %}
{% endblock %}



次にindex.htmlを開いて
<img width="507" alt="2019-06-22 (11).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/bc372ecc-1ac5-685e-0b1f-94a36bc565ba.png">



＜head＞＜head/＞のヘッダーの中身を削除
{% extends "layout.html" %}で共通テンプレートのlayout.htmlをよびだす
{% block content %}と記載。これより先のコードを
layout.htmlの{% block content %}の部分に埋め込むイメージ


コードの末は
{% endblock %}


ブラウザで表示すると


共通テンプレートと表示される
埋め込んだコードの文章が表示される
<img width="516" alt="2019-06-22 (12).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/355304/307a2806-7f80-16b8-b391-c28ae3086d0d.png">
IoT初心者向け 基礎用語まとめてみた

こんにちは！ IoT 1年生 ひつじです。

IoTの言葉って難しいですよね。
パブリッシャがペイロードしたやつをブローカーがサブスクライブでトゥギャザーしようぜ。的な。
ということで、IoTの基礎用語を解説していくよ！

#はじめに

IoTとは「Internet of things」の略です。
これ今いちよくわからないですよね。なんだよのモノのインターネットって、感じです。
実はIoTという言葉は1999年にマサチューセッツ工科大学の偉い人が使ったのはじまりで、当時はRFIDによる商品管理システムをインターネットに例えたものでした。（諸説あり）

僕「スマホとかパソコンとかどこからでも便利にネットにつながるじゃん」

G「ちゃうねん、IoTはなんでも繋がるねん。例えば、野菜や牛などの生物にタグ付けして管理したり、振動や天候なんかも繋げたりできんねん。」

僕「意味わからん。牛がスマホでツイートでもするのか。」

G「そこででてくるのが、センサーやSIM、それを動かすためのマイコンやLPWAの技術なんやで」

僕「ほえ～。よくわからんけど、ちょっと勉強するわ。」

#基礎用語

IoTの世界では、とにかくたくさんの通信が発生します。
そのため、従来のような通信プロトコルではなく、より軽量である必要がありました。
また、効率よく通信するために、発信する人、仲介する人、受信する人を定義し基本的なトポロジが作られました。

![i6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/0768b385-5a1a-af76-89d1-167a79c643bc.jpeg)


では、それぞれの役割を見てみましょう。

###Fisrt of all, MQTT

多くのデバイスと高頻度での通信を行うため、軽量や省電力に稼働する通信プロトコルです。（電力消費について条件により変化します。）
デバイスによってはHTTPベースでの通信も行えます。HTTPは通信の都度、情報（ヘッダ）の交換を行い安定して通信できますが、MQTTは情報の交換が少なく安定的というよりは一方的にデータを投げつけるイメージです。

![i7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/d68b4634-2551-2acc-e975-44b3b5c2591b.jpeg)

###Pub/Sub通信

Publisher:データを送信します。
Subscriber：データを受信（購読）します。
基本的にはPublisherとSubscriberは直接通信しません。

![i8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/3d69741f-cd27-3f8a-2f96-6c3af7001565.jpeg)

###Broker & Topic

Brokerは、PublisherとSubscriberを中継します。

Publisher(N:1)Brocker
Subscriber(N:1)Brocker
の構成をとります。

Toicは通信を送りあうときの識別子です。
Brockerに投げる時にどこのTopicになげるか指定します。

![i9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/585f3748-a2ff-524e-39c2-c6c467aca312.jpeg)

###QoS

品質保証です。レベル0~2の3段階を保有します。

![i10.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319145/d2c134f8-ca57-1014-d480-7d2d3bc863d7.jpeg)


#まとめ

いかがでしたでしょうか。
クライアントやサーバなどの言葉に慣れている人にとっては聞きなれない言葉もあったと思いますが、基本的には通信の送り元、集約、送り先、プロトコルと品質モードの話だったかと思います。
言葉のイメージを捉えて、楽しいIoTライフを送りましょう♪

次回はオープンソースのMosqittoを使って実際の通信を確認してみたいと思います。

それではご査収ください～。
Xcode11で作成したプロジェクトを古いOSに対応させる(とりあえず版)

Xcode11 beta で新規プロジェクトを作成。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/be698f46-6bb0-b53d-c20b-2d7b4c5d62d2.png)

Deployment Targetを古いOSに設定すると、
![0002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/6664d9e4-9b12-f3d2-86b2-544eeb291d42.jpeg)

エラーがぞろぞろ出てくるのをなんとかしようという話。
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/95033/f704d2da-1e4c-3ecb-e1b6-4924389694b7.png)

---
１. AppDelegate.swift と SceneDelegate.swift
エラーが出ている箇所に＠availableを付ける。

```Swift:AppDelegate.swift
// MARK: UISceneSession Lifecycle

@available(iOS 13.0, *)
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
  (略)
}

@available(iOS 13.0, *)
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
  (略)
}
```
```Swift:SceneDelegate.swift
@available(iOS 13.0, *)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
```

２. AppDelegateにwindowプロパティを追加する。

```Swift:AppDelegate.swift
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow? // 追加
```


---
とりあえず、これでエラーは出なくなります。

ただし、
(iOS 13)
1. 起動
2. ```AppDelegate``` application:didFinishLaunchingWithOptions:　(windowはnil)
3. ```SceneDelegate``` scene:willConnectTo:options (windowに値がセットされる)

(iOS 12以下)
1. 起動
2. ```AppDelegate``` application:didFinishLaunchingWithOptions:　(windowに値がセットされる)
3. ```SceneDelegate``` 呼ばれない

このような起動時の流れになりますので、windowプロパティにget / setしている場合はもうひと工夫必要になります。

[Xcode11で作成したプロジェクトを古いOSに対応させる 完結編](https://qiita.com/Hackenbacker/items/9cf9dfb4df66a51cd46a)

---
Xcode 11 beta3を元に作成しています。後日変更される可能性があります。
undefined method  nil:NilClass   解決法

#エラーの原因
https://gyazo.com/c1c322fc6c7bab43d2b8b48c2312fb8c

以下のコードの３行目において、エラーが発生している。

```ruby
.header
    %h3.header__name
      = current_user.name
```
current_user.nameというメソッドは、deviseというログイン機能を実装する時に使用するgemをインストールすると、使えるメソッドである。つまり、エラーの原因は、ログイン機能の実装におけるものであることが予想できる。
次に、エラー文をみた時に、エラー文の上の方に書いてある**undefined method name' for nil:NilClass**という文言が原因究明のヒントになる。この文は、**何の値も入っていない空のメソッドに対して、nameが適用されているから、エラーになっている**ということを意味している。
よって、エラーの原因は、**current_userメソッドの中に値が入っていないことが原因で生じていたことになる。**
#エラーの解決方法
current_userを空にしなければいいので、単純にログインをすればcurrent_userに値が入るのでエラーが解決できる。

また、ログインして再度ログアウトした場合において、同じエラーが発生した場合は、
application_controller.rbにて、

```ruby

before_action :authenticate_user!
```
の記述をすると解決できる。before_action :authenticate_user!については、以下の記事を参照。
ttps://qiita.com/tobita0000/items/866de191635e6d74e392

#解決するためのポイント
1.current_userメソッドは、ログイン機能を実装する時使用するメソッド
2.undefined method `name' for nil:NilClassというエラー文の解読
【UiPath】Flashのページで自動化

# 概要
まだまだ存在するFlashで構築されたWebページ。
そこで自動化しようとしたときのメモ。

# 基本的な制約

## クリック
「クリックをシミュレート」×
「ウィンドウメッセージを送信」○

## 文字を入力
「入力をシミュレート」×
「ウィンドウメッセージを送信」○

# 要素認識

## 状態によるセレクタの変化

例えば某複合機の管理ページ。ここにログインしたい。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/bddefa94-8308-53cb-1fab-036466295b4b.png)

ワークフローは以下の通り。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/05a6ed78-ce81-cd5c-a4c3-5b5a16880971.png)

しかし、これを実行してみると、「ログインをクリック」のところでログインボタンはクリックされず、一つ上の「独自認証」というところがクリックされてしまう。

原因予想：
ログインボタンのセレクタを見ると、```role```と```idx```のみになっていて、「ログイン」というラベルを使っているように見えない。
「graphic」の8番目、という指定をしているように見え、画面の変化に弱そう。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/c80251ca-de1e-e87a-f7ac-2a5b4412b136.png)
↓
フローではパスワード入力直後にログインボタンを押している。つまり、パスワードにフォーカスがある状態。
一方、ログインボタンのセレクタを取得するときは、どこにもフォーカスが当たっていない状態で行っている。
↓
テキストエリアにフォーカスが当たっている間は実は画面の状態が変わっていて、ログインボタンのセレクタがずれていることが考えられる。
実際、IDとパスワードを入力せずにクリックだけ試すと、ログインボタンが的確にクリックされる。

対策案：
エンターキーによるログインが可能であれば、ホットキーを送信する。

もしくは
ログインボタンを押す前に、ページの外を一度クリックしてテキストエリアからフォーカスを外す。
![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/424975/351f9cbc-30b5-2a10-d19d-601c9d4d19a8.png)

こんな感じで、一見要素認識が上手くいっているようでも、セレクタには注意した方がよさそう。
セレクタのクセについては、Flashに限ったことではないが…。
UnityのAndroidビルドをコマンドラインから行う (Mac用)

Unity で Android の apk ファイルを
コマンドラインからビルドする手続きです。

ビルドはコマンドラインから行いますが、
詳細なビルド手続きは Unityプロジェクト内で記述しておく必要があります。

iOSビルドの手続きは[こちらの記事](https://qiita.com/beckyJPN/items/ae73dd664b17f56be5ef)に記載しています。

# 環境
Mac : 10.14.5 (Mojave)
Unity : 2018.3.0f2

# unity側でのビルド手続き

UnityでBuilder.csというファイルを作成します。
（一応 `Asset/Editor` 直下に作成したけど、場所はどこでも良いのかな？？）

ここで定義したクラス名と関数名は `Builder.Build` という形で
シェルスクリプトの `UNITY_BUILDE_NAME` で参照されます。

`outputPath` で指定したパスにapkファイルが出力されます。
今回の状態では、Unityのプロジェクトフォルダ直下に生成されます。

```c#:Builder.cs
using UnityEditor;
using UnityEngine;
using System.Collections.Generic;
using System.Linq;

public static class Builder
{
    public static void Build()
    {
        var paths = GetBuildScenePaths();
        var fileName = "app.apk";
        var outputPath = $"./{fileName}";
        var buildTarget = BuildTarget.Android;
        var buildOptions = BuildOptions.Development;

        var buildReport = BuildPipeline.BuildPlayer(
            paths.ToArray(),
            outputPath,
            buildTarget,
            buildOptions
        );

        var summary = buildReport.summary;

        if (summary.result == UnityEditor.Build.Reporting.BuildResult.Succeeded) {
            Debug.Log("Success");
        } else {
            Debug.LogError("Error");
        }
    }

    private static IEnumerable<string> GetBuildScenePaths()
    {
        var scenes = new List<EditorBuildSettingsScene>(EditorBuildSettings.scenes);
        return scenes
            .Where((arg) => arg.enabled)
            .Select((arg) => arg.path);
    }
}
```

# シェルスクリプト

コマンドラインからのビルド手続きをシェルスクリプトで書きます。

ビルドログは `UNITY_LOG_PATH` で指定したパスに出力されるので、
うまくビルドができない場合は、logファイルで原因を確認しましょう。

```bash:unityBuild.sh
#!/bin/bash

UNITY_APP_PATH=/Applications/Unity/Unity.app/Contents/MacOS/Unity
UNITY_PROJECT_PATH=Unityプロジェクトのパスを入力
UNITY_BUILDE_NAME=Builder.Build
UNITY_LOG_PATH=./build.log

$UNITY_APP_PATH -batchmode \
    -quit \
    -projectPath $UNITY_PROJECT_PATH \
    -executeMethod $UNITY_BUILDE_NAME \
    -logfile $UNITY_LOG_PATH

if [ $? -eq 1 ]; then
    echo "error!! check logfile: ${UNITY_LOG_PATH}"
    exit 1
fi
echo "success!!"
exit 0
```

# ターミナルから実行

以下コマンドをターミナルから実行します。
Unityが起動した状態で行うとうまくビルドができないので、
Unityは終了させた状態で実行します。

```bash:ターミナルから実行
sh unitybuild.sh
```

実行後正常に完了したら、apkファイルが`outputPath`に生成されますので、
実機にインストールして動作を確認しましょう。

# github

プロジェクトはgithubにアップロードしてます
https://github.com/becky3/unity_command_build/tree/commandline_android
ど素人が画像を貼れるようになる方法

# はじめに
[未来電子テクノロジー](https://www.miraidenshi-tech.jp/intern-content/program/)でインターンをさせていただいているgk-fujirinと申します。三度の飯より自転車が大好きです。
将来的には、普段のサイクリングを紹介するブログなんかを作ってみたいですね。

そのため、今回はブログに欠かせない画像を表示する方法を復習したいと思います。

全くのプログラミング初心者であるため、内容に誤りがあるかもしれません。
もし、誤りがあれば修正するのでどんどん指摘してもらえると嬉しいです。
# 0.参考資料
 [Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d#links---%E3%83%AA%E3%83%B3%E3%82%AF)
[画像にリンクをつける](http://www.dspt.net/html_tag/005_data/005.html)
#1.見出しL&CSSで画像を表示させるには？

まずは画像を用意します。
![IMG_7429.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434843/e9fa9abc-0f87-5684-9c05-1eb0aee51ca2.jpeg)

かっこいいですね。惚れ惚れします。

次に、HTMLのimgタグを使用します。

```ruby:qiita.rb
puts '<img src=""/>'
```
最後にダブルクォーテーション（""）の間にさっきの画像のurlを貼ります。

```ruby:qiita.rb
puts '<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/434843/e9fa9abc-0f87-5684-9c05-1eb0aee51ca2.jpeg"/>'
```

これで完了です。
次回投稿する際は、少しでもマシな記事を書けるよう頑張ります。
部分テンプレートのエラーの備忘録(ディレクトリの配置ミスが原因)

#エラー発生前
簡易ブログアプリ(Nekotter)を作成している際、Indexのビューファイルのコードを部分テンプレートに置き換えて、ブラウザ上にて挙動の確認をした。

Indexのビューファイルのコード
https://gyazo.com/54c7e85c1d8bc0b602b752b9ad0943ae

部分テンプレートファイルのコード
https://gyazo.com/5c7a37b63736058da1552edda2135f4c


#エラー発生後
すると、ActionView::MissingTemplateエラーが発生した。
https://gyazo.com/4c22b380d0a8c7b4caf1e5299eac0142

エラー文の解析をしようと、google翻訳に入れてみた。しかし、翻訳の内容が理解できなかった。
エラー文の内容
https://gyazo.com/9a029eb908cd2ba1529af9e4b88e32c9

#解決方法
メンターの方に質問したところ、**部分テンプレートのディレクトリが違うこと**が指摘された。たしかに、部分テンプレートファイルの階層が本来であれば、views/tweets/_tweet.htmlとなるはずが、views/_tweet.htmlという階層となっていた。つまり、エラーの原因は、_tweet.htmlという部分テンプレートをフォルダにして作成してしまったことによるディレクトリの配置ミスであった。ここで、再度エラー文をよく読んでみたところ、たしかに、エラー文の下の方にディレクトリの階層構造について書かれている。今後このようなエラー文に遭遇した時は、一度ファイルのディレクトリ構造が正しいかを確認する必要があると感じた。

**自分はディレクトリの構造ミスがよくあるので注意する。**
SDカードでうまく録画できないと思ってたらFAT32が2種類あった

最近SDカードによって動画がうまく撮れたり撮れなかったり（撮れてはいるけどプレイヤーでロードがめちゃめちゃ長い）したので調査メモです。直ったわけではない。
FSまわりって未だに面倒くさい（小並感

# 環境

 - MacBook Pro / Majave 10.14.5
 - SDカード1: ノーブランド / 8GB / MBR-FAT32 (出荷時状態のまま)
 - SDカード2: T○SHIBA製 / 16GB / MBR-FAT32 (出荷時状態のまま)
 - SDカードリーダ: どこかの安いやつ

# 2種類のFAT32

[パーティション種類](https://www.win.tue.nl/~aeb/partitions/partition_types-1.html)をみると、FAT32の識別子が2種類ありました。

- 0x0B(or 0x1B) => 従来のFAT32
- 0x0C(or 0x1C) => LBA対応済のFAT32

> LBA...
> LogicalBlockAddressing。データがストレージのどこにあるか指定する方法。LBAでないものはCHSなど。ハード別に記録場所が異なるのを吸収する。

これを```diskutil list```すると、それぞれ

```
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *8.0 GB     disk2
   1:                 DOS_FAT_32 NO NAME                 8.0 GB     disk2s1
```

```
/dev/disk3 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *16.0 GB    disk3
   1:             Windows_FAT_32 NO NAME                 16.0 GB    disk3s1
```

```DOS_FAT_32```(0x0Bの方) と ```Windows_FAT_32```(0x0Cの方) という2種類のタイプ名で分かれて書かれるみたいです。
disk2がSDカード1、disk3がSDカード2（T○SHIBA製）のやつです。
後者のdisk3がうまく撮れてませんでした。
どこかのLBAマップ時にエラーになってるんでしょうか？謎です。

# DOS_FAT_32にフォーマットにしてみる

とりあえずちゃんと動いている方に合わせてみる。

```
diskutil eraseDisk FAT32 "NO NAME" MBR /dev/disk3
```

この結果、

```
diskutil list

(...略...)

/dev/disk3 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *16.0 GB    disk3
   1:                 DOS_FAT_32 NO NAME                 16.0 GB    disk3s1
```

正しくDOS_FAT_32にできました。
コマンド中の```MBR```はオプションなので、指定しなくても大丈夫なのですが、指定しないとGPTになっちゃうので注意が必要です。
このあともう一度動画撮り直しましたが結果変わりませんでした。残念。関係なかったけどコマンド覚えられたからおｋ
[old]Flask日本語チュートリアルが動かない

## Zennに移行しました

https://zenn.dev/murasa/articles/b40d245c12816d


## 本編
Flask日本語チュートリアルをやってみて、以下のようなエラーが出ませんでしたか？



```python:
ModuleNotFoundError: No module named 'flask.ext'
```

```python:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: entries
[SQL: SELECT entries.id AS entries_id, entries.title AS entries_title, entries.text AS entries_text 
FROM entries]
(Background on this error at: http://sqlalche.me/e/e3q8)
```

```python:
sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) no such table: entries
[SQL: INSERT INTO entries (title, text) VALUES (?, ?)]
[parameters: ('title', 'text')]
(Background on this error at: http://sqlalche.me/e/e3q8)
```



##日本語チュートリアルの罠

[この日本語チュートリアルサイト](https://a2c.bitbucket.io/flask/tutorial/index.html "Flask日本語チュートリアル")、バージョンが<b>0.5.1</b>なんですよね。

[このサイト](https://study-flask.readthedocs.io/ja/latest/index.html,"Flask日本語チュートリアル")もバージョンは不明ですが、上手くいかなかった。


以下のコマンドでFlaskのバージョンを確認してみてください。

```
$ pip show flask
Name: Flask
Version: 1.0.3
Summary: A simple framework for building complex web applications.
//以下省略...
```
バージョンが1.0.xだった場合、上記のサイトではなく[こちら](http://flask.pocoo.org/docs/1.0/tutorial/,"Flask英語")のチュートリアルでやってみてください。

残念ながら英語です。頑張りましょう。
【GAS】4行で「英単語を翻訳して保存スプレッドシートに保存する」スプレッドシートスクリプトを作る【GoogleAppsScript】

##社内で勉強会をすることになり、トップバッターが私になりました。

何処にでもある話だと思いますが、社内でTECH勉強会を開催することになりました。会社のキャラクターとしては、テック寄りのITコンサルというところです。

私の所属する部署(最大150人程度？)宛に招待メールを送ることになり、仮に30%が参加するとすると、45人が参加することになります。

勉強会というと、もっとこじんまりとしたものを想像していたのでこの数字にちょっとビビり始めます。

さて。これは難しい問題です。

何が難しいって、「全員に分かるようなレベル感の題材を選ぶ必要があり、全員にとって役に立ったと思わせる単元」を採用しないといけないからです。

これはマジで難しい...

そこで目を付けたのが、恐らく誰しも使っているであろう「Googleスプレッドシート」。ただそれだけだと「勉強会」の題材としてちょっと弱いよなあ...そうだ！GASにしよう！ということでGoogleAppsScriptを題材にすることにしました。

##題材は「Googleスプレッドシートで業務効率化！」になったが、オーダーで「ハンズオンして欲しい」と言われる...

GoogleAppsScript x 業務効率化 であれば、エンジニアもマネージャー層(来ないと思うけど)にも興味をもたせられるだろう、ということでこれに決めました。

しかし、そこにさらに追加で、「どうせなら実際に手を動かしてもらった方がいいよね。体にも刻み付けた方が記憶に残るだろうし！」と偉い人から言われました。

マジかよ...

あんまりにショボすぎるハンズオンだと勉強会の質が疑われるハメになるし、レベルが高すぎると「ああやっぱエンジニアってこうだよね。まわりのこと考えてない」みたいな評価を受けることになってしまいます...

丁度いいレベル感で、やった気になれるハンズオンの題材は無いかな...あった！そうだ！翻訳アプリ作ろう！！

##誰でもやった気になれる、「4行で英単語を日本語に翻訳して保存するアプリ」をハンズオンの題材にした

というわけで、ハンズオンの題材が決まりました。英単語を入力してもらうとそれを翻訳して保存するスプレッドシートメモ帳みたいな感じのアプリにします！

これなら、作りやすいですし、多少の意義もありますし、アプリの本質である「入力→ロジック→出力」を学べるということで最高の題材です！うおお！よくこんな丁度いい案が湧いてきたな！

というわけで、早速作っていきます。本当に4行でできるのか！？

### ソースコードはこちら

できました。最小動作のみを行うもので、下記のように4行になっています。(function定義部は除いて4行ね)

```javascript
function myFunction() {
  
  var enText = Browser.inputBox("英単語を入力してください！")
  
  var jaText = LanguageApp.translate(enText, "en", "ja")
  
  var sheet = SpreadsheetApp.getActiveSheet()
  
  sheet.getRange(sheet.getLastRow() + 1, 1, 1, 2).setValues([[enText, jaText]])
}
```

です。

ちなみにこれ、最初に出てくるプロンプトでキャンセル押すと、cancelの文字列を日本語翻訳して「キャンセル」がスプレッドシートに追加されてしまいます。ので、実際はエラーチェックする必要があるんでプラス数行になります。
(微妙に気になるのは、ユーザがマジで「cancel」を入力した場合はどうなるのかというところですが、まあ今回は対象外ですね)

### 動かすまでの手順がこちら

まずは、スプレッドシートからスクリプトビューに移動します。

![img2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145371/092f231f-bf08-81a6-3914-e4dd1f07f50d.png)

次に、表示されるスクリプトビューに先ほどのソースを書いていきます。

![img1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145371/1c902e2b-be8b-c3ec-2330-f8da01b540ac.png)

問題なければ保存して、コードを名前を付けて保存します。(ここでエラーが起きたら、メッセージ内容を参考にしてなおします。なおさないと保存できない...はず...)

保存ができたら、関数を実行してみます。下記の通り。

![img5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145371/c36ad290-36cd-aa26-d0d8-459615f89b22.png)

実行→関数を実行→myFunction(別名をつけた人はそれを選択)

### 実際の動作の様子

果たして動くのか！？

実行したら、スクリプトビューからもとのスプレッドシートに移動して、ダイアログが表示されていることを確認します。

![img6.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145371/f1da7a4d-195b-4e0e-ace6-cc014dbeb8b4.png)

ここに翻訳したい単語を入力します。でOK押下。結果は...

![img7.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/145371/c20eff12-1a32-9d20-4671-4085e7d85399.png)

うおおおおおお！！翻訳されて追加されているぞおおおおおい！！

こんな感じになります。

まあ正直、だからどうした的なところはありますが、4行でできて雰囲気を掴むための題材としては極めて有用なのではないかと思いました。

欲を言うなら、「スプレッドシートから値を取得して」という部分も入れ込みたかったんですが、そうするとたぶんループすることになり、コード行数が微妙に増えるかなと。ともすると、エラーにハマる人の割合が数パーセント上昇するし...というところでやめました。

興味のある人はさらに深堀しておけばいいよね。うんうん。
RubyのバージョンアップをしたらHerokuにデプロイできなくなった

# tl;dr

個人でつくってるプロダクトで

ふと思い立って、Rubyのバージョンアップを行ったら

Herokuにデプロイできなくなった

それの解決方法というか、、


# 原因

Rubyのバージョンアップの際に、`gem install bundler` をして
Bundlerのバージョンが`2.0.2` となったからっぽい

```
$ bundle -v
Bundler version 2.0.2
```

```Gemfile.lock
BUNDLED WITH
   2.0.2
```

Bundlerを`2.0.1`で入れ直して、　`Gemfile.lock` もつくりなおす

```
$ gem uninstall bundler
```

```
$ gem install bundler -v 2.0.1

$ bundle -v  
Bundler version 2.0.1
```

```
$ rm Gemfile.lock
$ bundle --without production
```

これでできる

```
$ git push heroku master
```

# おまけ

バージョンアップしたらRailsコマンドが叩けなくなった

```
rbenv: rails: command not found

The `rails' command exists in these Ruby versions:
```

```
$ rbenv exec gem install bundler

$ rbenv rehash

$ gem install rails 
```
Androidのタップイベント透過メモ

## 問題

Androidアプリにおきまして、blueViewの中にあるorangeViewのタップイベントの有効・無効を切り替える仕様がありました。
無効にした場合、orangeViewをタップしたとき、タップイベントがblueViewまで届かなかったので、その対応方法をメモしておきます。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149856/da2543a7-97d0-98d4-22ab-9330ca9ecbef.png)

## 解決

[View#isClickable][2]をfalseにすることで、blueViewのタップイベントが呼ばれるようになります。
しかし、orangeViewにリップルアニメーションなどつけていると、それが動作してしまいます。

```kotlin
orangeView.isClickable = false
```

[View#isEnabled][2]をfalseにすることで、orangeViewのタップイベントを無効にすることができます。
しかし、isClickableがtrueの場合、blueViewのタップイベントが呼ばれません。

```kotlin
orangeView.isEnabled = false
```

上記、2点を組み合わせて、以下のようにすることで解決することができます。

```kotlin
// orangeViewのタップイベント有効
orangeView.isClickable = true
orangeView.isEnabled = true

// orangeViewのタップイベント無効
orangeView.isClickable = false
orangeView.isEnabled = false
```

[GitHubサンプル][1]

[1]:https://github.com/mn-D128/ClickableSample
[2]:https://developer.android.com/reference/android/view/View.html#setClickable(boolean)
[3]:https://developer.android.com/reference/android/view/View.html#setEnabled(boolean)
application seacret を生成する

playのアプリケーションのデプロイ方法を調べていると、seacret keyを設定しろと書かれていた。

[参考]https://www.playframework.com/documentation/2.7.x/Deploying

生成方法がわからなかったのでメモしておく。

# 環境
sbt： 1.2.8
play framework: 2.7.3

# やり方
下記のコマンドで seacret key を生成できる模様。

```bash
$ sbt playGenerateSecret
```

# 設定箇所

`conf/production.conf` に追記（なければ生成する, application.confでもよい）

```bash
play.http.secret.key="上記のコマンドで生成したseacret key"
```

# 参考
- https://stackoverflow.com/questions/18989131/how-to-generate-a-new-application-secret-in-play-2-x
SQL EXISTSとJOIN

## EXISTS

```sql
SELECT *
FROM users
WHERE EXISTS
    ( SELECT id
     FROM orders
     WHERE users.id = user_id
     AND orders.created >= '2019-06');
```

- usersテーブルはメインテーブル、ordersテーブルはサブテーブル
- このメインテーブルのidをサブクエリで参照する事を**相関サブクエリ**と呼ぶ
- メインテーブル×サブテーブルのレコード数を比較対象とする
- 条件に一致するレコードが見つかった場合その時点で処理は終了する
- 見つからなかった場合、**メインテーブル×サブテーブル**のレコード数を比較しに行く
- レコード数が増えればその分比較対象となるレコード数も増える

## INNER JOIN

```sql
SELECT *
FROM users
INNER JOIN
    ( SELECT DISTINCT user_id
     FROM orders
     WHERE orders.created >= '2019-06') AS sub
ON sub.user_id = users.id;
```

- 実行順序によりINNER JOIN句のサブクエリから実行される
    - 実行順序の参考：http://forse.hatenablog.com/entry/2015/06/17/111043
- サブクエリの実行でSELECTに指定したカラムの重複削除とWHERE句の条件によって絞り込みが行われる
- その結果をINNER JOINでメインテーブルに結合する

## 実行速度
- EXISTS
    - 45~50ms

- INNER JOIN
    - 15~20ms

## 参考
- http://kkoudev.github.io/blog/2013/09/14/sql/
- http://totech.hateblo.jp/entry/2016/09/21/172801