OmniAICreator/Qiita-1.07M huggingface dataset:
やる気出ない…そんな時の特効薬

格言聞いてやる気出す！個人的な12選。
<img width="300" alt="やる夫.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/9511dcb2-f29b-4fc4-7ab8-9063bb2213f8.png">
自分用。
## 一度しかないこの人生で自分の夢を追いかけないでいつ追いかけるのだろう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/f42d55eb-ce60-6ec1-0930-0423c1e93a69.png)
孫正義 ソフトバンク代表取締役社長兼会長

## 失敗しても構わないが、失敗するなら早くしろ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/4beb6bad-ac7f-5fc5-bded-735c7654c999.png)
ラリー・ペイジ Googleの共同創業者、前最高経営責任者

## クレイジーな人達をたたえよう。
はみ出しもの、反逆者、トラブルメイカー、彼らは四角い穴に丸い杭を打ち込む。彼らを無視することはできない。なぜなら彼らは物事を変えたからだ。彼らは人間を前進させた。彼らはクレイジーと言われるが私達は天才だと思う
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/794a4e02-5503-6ac5-5552-292cf07efcce.png)

スティーブ・ジョブズ
アップル社の共同設立者の一人。アップル退職後、ピクサー・アニメーション・スタジオを設立。アメリカ国家技術賞を受賞

## あきらめたらそこで試合終了ですよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/ed845e49-d675-79dd-3981-45d9b2fe64bf.png)
安西先生 バスケ部顧問

## 努力は必ず報われる。もし報われない努力があるのならば、それはまだ努力と呼べない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/c44f65fb-69d2-f396-68ff-6fce01aa9b2d.png)
王貞治 元プロ野球選手

## 誰よりも三倍、四倍、五倍勉強する者、それが天才だ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/ed430879-41a6-f92a-6524-fb73c8b87b3e.png)
野口英世 学者

## あきらめないことだ。一度あきらめると習慣になる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/81ddc878-e4e5-98c9-35d1-978fcc8ae64e.png)
斎藤茂太　精神科医、随筆家

## 振り向くな、振り向くな、後ろには夢がない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/84d700b0-2fb2-4ec7-a1da-534368c7e273.png)
寺山修司　歌人、劇作家

## 天才とは努力する凡才のことである。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/2a7650a1-7d85-1437-e4be-8cb707df5223.png)
アインシュタイン 物理学者

## オレは今なんだよ！！
オヤジの栄光時代はいつだよ・・・。
全日本のときか？オレは今なんだよ！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/6b91fbdf-cd4b-5f02-5029-6ce75051ced4.png)
桜木花道 バスケ部

## 今日を頑張り始めた者にのみ明日は来るんだよ。
明日から頑張るんじゃない。
今日を頑張り始めた者にのみ明日は来るんだよ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/a39390e8-e462-684b-4f1f-7eb6f446aa72.png)
大槻太郎 班長

## 懸けてから言いなさい。
青春全部懸けたって強くなれない？
懸けてから言いなさい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/343158/90d111f6-524f-ffe0-d1ab-7787d4c1beca.png)

原田秀雄 府中白波会の会長
C#学習　-シングルトン-

C#学習中のため、学習内容をメモしていく。
間違いやアドバイスがあればコメントからよろしくお願いします。

#シングルトン
クラスがロードされた初回に一度だけインスタンスが生成され、以降のインスタンスは生成されない。

コード例

```C#
   class MySingleton
    {
        // アプリで保持すべき唯一のインスタンスをクラスフィールドとして保存
        private static MySingleton instance = new MySingleton();

        // コンストラクターをprivate宣言することで1度だけしかインスタンスが生成されない
        private MySingleton()
        {
            Console.WriteLine("シングルトンの生成");
        }

        // 唯一のインスタンスを取得するプロパティ
        public static MySingleton Instance
        {
            get { return instance; }
        }

        private string _str;

        public string str
        {
            get { return _str; }
            set { _str = value; }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var obj = MySingleton.Instance;
            obj.str = "シングルトン１";

            var obj2 = MySingleton.Instance;

            // インスタンスは1つしか生成されないため、dataの内容は「シングルトン１」となる
            Console.WriteLine(obj2.str);
        }
    }
```

#参考した本
独習C#

おわり。
1000円で作る日本語音声合成装置

音声合成装置を作るといっても、それほど難しいことをするわけではありません。基本的には買って、つないで、終わりです。

---
- ATP3011(850円)を使用する
-

[ATP3011](http://akizukidenshi.com/catalog/g/gI-05665/)という音声合成チップは、単体で音声合成ができます（出力はごく小さいのでアンプ付きスピーカーで出力する必要があります）。
![I-05665.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/017e3a09-b347-dfef-47fc-d281da70485b.jpeg)

[ATP3011F1-PU](http://akizukidenshi.com/catalog/g/gI-06220/)はいわゆるゆっくりボイスです。
![yukkuri.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/470b5f4f-03e3-caa5-7a4c-690854e51295.png)


I2CまたはシリアルでArduinoやRaspberryPiからコントロール可能です。
今回は[Arduino Uno](http://akizukidenshi.com/catalog/g/gM-07385/)を使用しました。

![uno.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/f5eba39e-b007-42da-963a-59015731dc9a.png)

接続したらサンプルのスケッチをArduino Unoに書き込みます

```
#include <SoftwareSerial.h>

int count;
SoftwareSerial softSerial(12,13); //RX, TX

void setup() {
  count = 0;
  delay(100);
  softSerial.begin(9600);
  delay(10);
  softSerial.print("?");
  delay(100);
}

void loop() {
  count++;
  
  String str = "<NUMK VAL="+String(count)+" COUNTER=funn>+ke-'ka"; 
  softSerial.print(str+"\r");
  delay(2000);
}
```

最初に"?"を送信することでATP3011の受信レートを自動で変更しているようです。

```
"＜NUMK VAL="+String(count)+" COUNTER=funn＞+ke-'ka";
```
のようにするだけで　「サンプン」「ゴフン」「ジュップン」など読み分けてくれるので、数値の読み上げなどには便利なんじゃないかと思います。
細かい発話方法などは[データシート](http://akizukidenshi.com/download/ds/a-quest/atp3011f4_datasheet.pdf)に載っています。

[動画](https://www.youtube.com/watch?v=7QH54dSNAds)

---
- ATP3012(900円)+あちゃんでいいの(99円)を使用する
-

[ATP3012](http://akizukidenshi.com/catalog/g/gI-11517/)はATP3011より高音質ですが外部クロックが必要です。
今回は外部クロック用に、100円で購入できる[あちゃんでいいの](http://www.aitendo.com/product/11541)を使用しました。
ATP3011,ATP3012はArduino UnoのコアチップであるATMega328と互換（ATMega328にファームウェアとして書き込んだもの）なので、あちゃんでいいのを組み立ててATP3012を挿すだけで使えます。

![IMG_7591.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/6051ae46-fb23-b421-d8ac-18327c1c0181.png)

またATP3011とスピーカーOUTのピンが異なっている点も注意が必要です。
![ATP3012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/903fcf1a-2aae-4220-8cb2-a119cc603e13.png)

スケッチはATP3011と同じものが使えます。

[動画](https://www.youtube.com/watch?v=zsTRdXURF3E)
配列

自分用忘備録

   def new
      @category_parent_array = ["---"]
      Category.where(ancestry: nil).each do |parent|
         @category_parent_array << parent.name
      end
   end


@category_parent_array = ["---"]
[]の中に初期値を設定している。"---"が0番となり、こんな感じで最初に表示される。
<img width="438" alt="スクリーンショット 2019-07-07 14.28.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/442488/1a780ef2-fe1d-451a-73b9-6b985e88d035.png">

@category_parent_array << parent.nameでその後追加されるもの1番以下で続く。
emacs + recursive make "Entering directory" で幸せになる

Emacs でソースコードが複数のディレクトリに分かれている場合にコンパイルする話。エラーが起きたファイルが開けないことありませんか？ なんと `Entering directory` と書くと emacs が読み取ってくれるんです。

## 問題の設定

ディレクトリ構造:

```bash
Makefile
sub/Makefile
sub/hello.cpp
```

Makefile: `sub` に入って `make` する

```makefile
default:
    cd sub && $(MAKE)
```

sub/Makefile: `sub/` の中でコンパイルする

```makefile
hello: hello.o
    $(CXX) $< -o $@
```

さて、親ディレクトリのファイルを開いている emacs で `M+x compile` してエラーがあった場合、C-x ` でエラーの場所に飛んでほしいわけだけど、

```
Find this error in (default hello.cpp):
```

と言われる。emacs さんは `hello.cpp` が `sub/` にあることを知らない。

## 解決法

なんと "Entering directory sub" というメッセージが出力されると emacs はそれを解する。

Makefile

```makefile
default:
	$(MAKE) --print-directory -C sub
```

```makefile
default:
	@echo "Entering directory sub"
	cd sub && $(MAKE)
	@echo "Leaving directory sub"
```

でもいい

バージョンによってはデフォルトで Entering directory が表示される場合もあるようだ。

これで簡単にエラーの場所に飛べる。オープンソースコードをコンパイルするとよく見るこのメッセージには実はこんな効能が。幸せ。



## リンク
How to adjust the path that Emacs compile-goto-error gets from the compilation buffer? 
https://stackoverflow.com/questions/10451242/how-to-adjust-the-path-that-emacs-compile-goto-error-gets-from-the-compilation
【Swift】 RealmSwiftのマイグレーション(データ引き継ぎ有)方法

### 前置き

ネットの情報を色々見て、公式の記述サンプルも見たんですが、Realmのマイグレーションがうまく行かない。より正確には、schemaVersionを更新して、レコードフォーマットも更新されて、アプリが稼働することは確認できるのに、マイグレーション前のデータが引き継がれない。
とにかく「これでマイグレーションできました」っていうブログ等の書き方を片っ端から試していって、結果、下記の書き方でうまく行ったので備忘録として残します。

### 開発環境
端末:MacBook Pro/MacOS 10.14.5(Mojave)
Xcode:10.2.1
Swift:5

### 実装内容


### ソースサンプル

```swift:RealmSwift.swift
import Foundation
import RealmSwift

class myRoutine: Object {
    @objc dynamic var column1 = String()
    @objc dynamic var column2 = String()
    @objc dynamic var column3 = String()
    @objc dynamic var column4 = String()
    @objc dynamic var column5 = String()
}

func realmMigration() {
    // Realmマイグレーションバージョン
    // レコードフォーマットを変更する場合、このバージョンも上げていく。
    let migSchemaVersion: UInt64 = 1
    
    // マイグレーション設定
    let config = Realm.Configuration(
        schemaVersion: migSchemaVersion,
        migrationBlock: { migration, oldSchemaVersion in
            if (oldSchemaVersion < migSchemaVersion) {
    }})
    Realm.Configuration.defaultConfiguration = config
}
```

ライフサイクルの早い段階でマイグレーション処理 `realmMigration()` を呼び出す

```swift:ViewController.swift
class ViewController: UIViewController {
    ...

    // 自分の場合は、作ってるアプリのライフサイクルで一番早いのが
    // awakeFromNib()だったのでここに書いています。
    override func awakeFromNib() {
        realmMigration()
        
        // realmを使う時のおまじない
        realm = try! Realm()
        
        ...
    }
    ...
}
```

### 感想、その他メモ
いろいろ試して、（そもそも何でいろいろな書き方があるのか、という話ですが）なんとかデータ引き継ぎできる書き方が見つかってよかったです。
もっと余裕と知識があれば、ダメだった書き方のダメな理由も調べたいんですが、それはまた別の機会に。
プロジェクトとアプリケーションの設定 (GAE/Go/Gin)

#はじめに
GAEをGinを利用して構築していきます。
流れは、公式サイトの[プロジェクトとアプリケーションの設定](https://cloud.google.com/appengine/docs/standard/go/building-app/creating-your-application?hl=ja)と同じです。

#環境設定（SDKのインストール）

##前提
GCPのアカウント登録、GAEのプロジェクト作成、Goのインストールをしておいてください。
Goのバージョンは、1.11を利用しています。

SDKのインストールは、公式サイトの通りに行います。
[Google Cloud SDK のドキュメント](https://cloud.google.com/sdk/docs/?hl=ja)

#ソース

今回のフォルダ構成は、以下の通りです。

```
├──  template
│    └── index.html
├──  app.yaml
└──  main.go
```

```yaml:app.yaml
runtime: go111

handlers:
- url: /.*
  script: auto
```

```go:main.go
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
	"google.golang.org/appengine"
)

// init は古い
func main() {
	router := gin.Default()

	router.LoadHTMLGlob("template/*") // 事前にテンプレートをロード(相対パス)

	router.GET("/", HelloWorld)

	http.Handle("/", router) // router.Run(":8080")の代わり
	appengine.Main()         // これがないと動かない
}

func HelloWorld(c *gin.Context) {
	c.HTML(http.StatusOK, "top/hello", gin.H{
		"hello": "hello, World!!",
	})
}
```


```html:template/index.html
{{ define "top/hello" }}
<!DOCTYPE html>
<html>
  <head>
  </head>

  <body>
    test
    <h1>{{ .hello }}</h1>
  </body>
</html>
{{ end }}
```


#ローカルで実行
`dev_appserver.py app.yaml`

この時、pythonが2系以外だと、以下のエラーが発生します。

```
ERROR: Python 3 and later is not compatible with the Google Cloud SDK. Please use Python version 2.7.x.

If you have a compatible Python interpreter installed, you can use it by setting
the CLOUDSDK_PYTHON environment variable to point to it.
```



2系と3系の共存は、以下のサイトを参考にしました。
[Python 2系と3系の共存](https://qiita.com/nakamura_hikaru/items/639204ee7c7c8cd51a90#%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AE%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88)

`localhost:8080`  にアクセスすると以下の画面が表示されます。

![スクリーンショット 2019-07-07 13.32.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125499/12c06710-5f1a-9888-ea30-44aca1bfb188.png)


#アプリケーションをデプロイする

`gcloud app deploy`

以下のエラーが発生した場合、SDKの初期化がされていませんので、初期化を行います。

```cmd:
ERROR: (gcloud.app.deploy) INTERNAL: Internal error encountered.
```

##SDKの初期化
`gcloud init`

3回ほど質問されるが、基本的に「1」を選択して問題ないと思います。


#アプリケーションを表示する

`gcloud app browse`

起動確認が入るので、[Y]を選択します。

その後、`http://[YOUR_PROJECT_ID].appspot.com`で、画面が表示されるかを確認します。



#参考
[プロジェクトとアプリケーションの設定](https://cloud.google.com/appengine/docs/standard/go/building-app/creating-your-application?hl=ja)

[Python 2系と3系の共存](https://qiita.com/nakamura_hikaru/items/639204ee7c7c8cd51a90#%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B3%E3%81%AE%E5%88%87%E3%82%8A%E6%9B%BF%E3%81%88)
【Fluentd】Configファイルの6つの命令の意味について

# はじめに
実務で必要になるので昨日から勉強し始めました。
configファイル中の6つの命令（`source`, `match`, `filter`, `system`, `label`, `@include`）について一言メモを作成していきます。

私のようなfluentd超初心者に向けたメモなので悪しからず。

# Configファイル中の6つの命令について
## `source`
- インプット先の情報
- データをどこから収集するか

```:文法
<source>
  @id    [plug_inを定義]
  @type  [プラグイン名]
  tag    [出力タグ]
  @label @[ラベル名] # 任意
  [プラグインのオプション]
</source>
```

## `match`
- fluentdに何をさせるか
- アウトプット先を指定

```:文法
<match [マッチさせるタグ]>
  @id    [plug_inを定義]
  @type  [プラグイン名]
  @label @[ラベル名] #オプション
  [プラグインのオプション]
</match>
```

## `filter`
- sourceでインプットしたデータの処理・加工
- 複数の処理を記述できる

```:文法
<filter [マッチさせるタグ]>
  @type [プラグイン名]
  [プラグインのオプション]
</filter>
```

## `system`
- システム全体の設定

## `label`
- アウトプットと内部フィルターをグルーピング

```:文法
<label @raw>
  <filter>
    @type [プラグイン名]
    [プラグインのオプション]
  </filter>
  <filter>
    @type [プラグイン名]
    [プラグインのオプション]
  </filter>
  <match>
    @type [プラグイン名]
    [プラグインのオプション]
  </match>
</label>
```

## `@include`
- 他のcongifファイルを読み出す

# 参考URL
- [公式・Config File Syntax](https://docs.fluentd.org/configuration/config-file)
- [Fluentdのインストールとconfigについて](https://qiita.com/nkg/items/cbf72adb436456804d76#td-agent%E3%81%AE%E8%B5%B7%E5%8B%95)
- [データ分析基盤構築入門[Fluentd、Elasticsearch、Kibanaによるログ収集と可視化]](https://www.amazon.co.jp/%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E5%9F%BA%E7%9B%A4%E6%A7%8B%E7%AF%89%E5%85%A5%E9%96%80-Fluentd%E3%80%81Elasticsearch%E3%80%81Kibana%E3%81%AB%E3%82%88%E3%82%8B%E3%83%AD%E3%82%B0%E5%8F%8E%E9%9B%86%E3%81%A8%E5%8F%AF%E8%A6%96%E5%8C%96-%E9%88%B4%E6%9C%A8-%E5%81%A5%E5%A4%AA/dp/477419218X/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2KYFYIG9BPSRQ&keywords=fluentd&qid=1563085197&s=gateway&sprefix=fluen%2Caps%2C318&sr=8-1)
Git ブランチ チェックアウト コマンド


<h3>Gitコマンドの解説</h3>

```$git checkout -b ローカルブランチ名前 リポジトリ名/ブランチ名```
           ↓  ↓  ↓
```$git checkout -b develop upstream/develop```

`checkout`に`ーbオプション`をつけると､
ブランチの作成&チェックアウトを同時にしてくれる｡


このコマンドで役割3つ｡

1つ目 ```$git branch ブランチ名```  ブランチの作成
2つ目 ```$git checkout ブランチ名``` ブランチの移動
3つ目 ```merge```もしています




以上メモでした｡
MySQLでパフォーマンスの良いSQLを書くコツ

「コツ」と題しましたが、パフォーマンスの良いSQLって本当に難しい事で、ちょっとしたコツでなんとかなる問題ではないことは重々承知しています。
しかし最近、SQLは知っているもののパフォーマンスなんて何も意識した事がない方が結構いるのだなぁと実感することがあり、そういう方にパフォーマンス設計のさわりだけでも知っていて頂ければと思い、記事にしました。

# この記事の対象者

SQLはよく書くものの、パフォーマンスを意識してSQLを書いたことがない方

# 環境

MySQL5.5〜5.7
エンジンはinnoDB


# まずは自分が作ったSQLが速いか見てみる

SQLを実行して素早く返ってくるか？だけで判断せず、**実行計画（explain）**も見るようにしましょう。
実行計画とは、MySQLがどのような手順でSQLを解析、実行するかの計画を示してくれるものです。
SQLの頭に`explain`とつけて実行するだけで見ることができます。

```sql

explain
select 
  * 
from 
  t1 inner join t2 on t1.t2_id = t2.id 
where 
  t2.name = 'aaa'
```

以下のような結果が取れます。

| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|:---|
|1 | SIMPLE | t1 | NULL | ALL | index_t1_on_t2_id | NULL | NULL | NULL | 341 | 10.00 | Using where |
|1 | SIMPLE | t2 | NULL | eq_ref | PRIMARY | PRIMARY | 4 | db.t1.t2_id | 1 | 100.00 | NULL |

実行計画の見方ですが、**とりあえずtable、type、rows、Extraを見ておきましょう。**

|カラム|説明|
|:---|:---|
|table|この順でテーブルを解析するよ、ということ|
|type|テーブルの検索方法。上から順に総なめしていくとか、インデックスを使用して高速に検索するとかいうことがわかる|
|rows|検索対象とする行数で、ここが多いとそれだけパフォーマンスが悪くなる|
|Extra|もう少し詳細な解析内容が書かれる|

以下のような結果は要注意！

- **table：絞り込みが効きにくい順序になっていないか**
- **type：ALLが出ている**
- **rows：何十万件にもなっている**
- **Extra：Using filesortやUsing temporaryが出ている**

逆にすばらしい実行計画は以下のような感じです

- 「PRIMARY」と出ている（主キー検索）
- 「eq_ref」と出ている（インデックス検索）

# 遅いSQLがアプリケーションの中にどれくらいあるのだろう？

slow logを出力するようにMySQLを設定しましょう。応答に○秒以上かかったSQLだけを収集してくれるログです。１秒とか１分とか３０分とか設定できます。

# インデックス

インデックスとは辞書の索引のようなものです。テーブルごとにalter tableで追加していくことができます。主キーや外部キーには最初からインデックスが作成されます。
MySQLはインデックスのないカラムで検索すると、一番上から順に総なめして検索します。これがtype:ALLの状態です。件数が多いと非常に遅くなります。
インデックスはうまく使えば劇的に速くなります。

## インデックスの作成

インデックスを検討するときは以下の観点で行いましょう。

- 対象テーブル：**データ件数が多く、検索されることも多いテーブル**
- 対象カラム：**where・join・sortに頻繁に使用されるカラムで、かつデータのばらつきが多いカラム**

ひとつのテーブルに複数作成することができますが、１回のSQLで１テーブル１つしか使用されません。たくさん貼っても意味がない場合もあるので注意して下さい。
データのばらつきですが、例えばフラグのような２値しか持たないカラムに対してインデックスを作成してもあまり効果が得られないということです。IDや作成日時など、ばらばらのデータには非常に効果的です。
また、インデックスを作成することで以下のようなデメリットもあります。

- insertやupdateは遅くなる（同時にインデックスも作成するため）
- インデックス自体もディスク容量を消費する

## インデックスが効いてるか確認する方法

インデックスを貼ったあと、実行計画のpossible_keysとkeysを見てみましょう。

|カラム|説明|
|:---|:---|
|possible_keys|使用できるインデックスの候補|
|keys|実際に使用するインデックス|

## インデックス貼ったのに効かない！インデックスの効きを阻害する要因

### 関数

DATEDIFFとかSUBSTRINGとか、私はよく使ってしまうのですが、**関数を使用したカラムはインデックスが全く効かなくなる**ので要注意です。

### LIKE %text%

LIKE検索は前方一致のみインデックスが効きます。
text%→効く
%text%→効かない

### 他のインデックスが採用されている

複数のインデックスを貼っている時、どのインデックスを使用するかはMySQLが判断しますが、時に思いもよらぬインデックスを使用してしまうことがあります。
そういう場合は以下のような対策があります。

- analyze tableコマンド実行（インデックスの再編成）
- USINGという構文を使用して使用するインデックスをMySQLに指示する

### SQLがあまりにも複雑すぎる

副問合せしてCASE構文使ってJOINも多すぎてUNIONもしちゃって更にGROUP BY HAVING……こんなことになると、MySQLも限界です。
個人的には、SQLはシンプルイズベストにして、プログラムの方でできることはプログラムにやらせる、としています。
Unity VSAをVMware ESXi上で使用する。

業務でストレージ機器を触る必要があり、家での検証環境（ESXi）にUnityVSAをインストールする。


#インストール環境
[前に建てた](https://qiita.com/sicksixrock66/items/d96e74da1bcd382208ff)ESXi6.7.0 Update 2上にインストールする.

#Unity VSAってそもそも何？
[公式ドキュメント](https://japan.emc.com/collateral/solution-overview/h14959-unity-vsa-so.pdf?isKoreaPage=false&domainUrlForCanonical=https%3A%2F%2Fjapan.emc.com)があるので参照

ざっくり書くと
DellEMC製のユニファイドストレージ(SANとNASの両方に対応できるストレージ）

ストレージ製品は高価で個人で筐体を購入するのはIAサーバ以上に敷居が高いが、
仮想アプライアンス版のUnityVSAを導入することでESXiがあれば自宅でもストレージを触ることが出来ます。
しかも、

>Community Edition：最大 4 TB の無料のソフトウェア

4TBまでのPool作成であれば無料という素晴らしさ（他にも細かい機能制限はありますが）

[Unityの詳しい仕様などについてはベンダーサイトをご確認ください。](https://www.dellemc.com/ja-jp/storage/unity.htm)

#Unity VSAのダウンロード
[ここから](https://www.dellemc.com/ja-jp/products-solutions/trial-software-download/unity-vsa.htm)ダウンロードできます。
※アカウント不要

#Unity VSAのデプロイ
基本的には[DELLEMCのコミュニティサイト](https://community.emc.com/docs/DOC-54344)にわかりやすくデプロイ・操作についてまとめてくださっている方がいるので参照してデプロイしていただければ問題ありません。

公式のインストールマニュアルは[こちら](https://japan.emc.com/collateral/TechnicalDocument/docu69316.pdf)

#補足
インストール物理筐体はNICが一つしかないintel NUC上でしたが特に問題なくインストール可能でした。（仮想NW内での検証であれば問題なさそうです。）
>ハードウェア ネットワーク 4x1 GbE または 4x10 GbE（推奨）
【PDO】DELETE文でデータを削除する方法

# はじめに
- DELETE文でデータを削除する方法について本やネットの情報から調べて理解したことをまとめました。
- もし、書いていることに何か間違いがある場合はご指摘いただけると嬉しいです。

# データを削除するSQL文
- データを削除するにはDELETE文を使います。

## DELETE文の書き方

```
DELETE FROM テーブル名 WHERE 条件;
```

# DELETE文でデータを削除するコード例
簡易掲示板を実装することを仮定して解説します。

## 開発環境
MAC
MAMP

## ファイル
index.php
delete.php

## 画面
投稿一覧
削除画面



以下のようなデータベースとテーブル、レコード登録されていると仮定して解説します。

**データベース名：** test_db6
**テーブル名：** users

|  id  |  name  |  message  |
| ---- | ---- | ---- |
|  1  |  waka3  |  おはようございます  |
|  1  |  waka  |  こんばんわ  |

### index.php（投稿一覧）

![スクリーンショット 2019-07-07 13.23.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392565/bb9db12f-aa77-00eb-35a0-fa59a343fd50.png)

```php:index.php
<?php

try {

    $user = "ここにユーザー名が入ります";
    $password = "ここにパスワードが入ります";

    $dbh = new PDO("mysql:host=localhost; dbname=test_db6; charset=utf8", "$user", "$password");       
    
    $stmt = $dbh->query('SELECT * FROM users');
   
    $result = 0;
   
    $result = $stmt->fetchAll(PDO::FETCH_ASSOC);

} catch (Exception $e) {
          echo 'エラーが発生しました。:' . $e->getMessage();
}

?>
  <!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>簡易掲示板</title>
  </head>
  <body> 
      <h2>簡易掲示板</h2>
        <?php
            echo "<table>\n";
              echo "<tr>\n";
              echo "<th>お名前</th><th>メッセージ</th>\n";
              echo "</tr>\n";
              foreach ($result as $user) {
                echo "<tr>\n";
                echo "<td>" . $user["name"] . "</td>\n";
                echo "<td>" . $user["message"] . "</td>\n";
                echo "<td>\n";
                echo "<a href=delete.php?id=" . $user["id"] . ">削除</a>\n";
                echo "</td>\n";
                echo "</tr>\n";
              }
            echo "</table>\n";
        ?>
  </body>
</html>
```




### delete.php（削除画面）

`waka` `こんばんわ`と表示されているデータを削除してみます。
`削除`ボタンを選択すると、`delete.php`に遷移します。

![スクリーンショット 2019-07-07 13.27.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392565/b1b4390a-9ee1-4cee-fc6a-c32408a302d6.png)



```php:delete.php

<?php

try {
  
    $user = "ここにユーザー名が入ります";
    $password = "ここにパスワードが入ります";
    
    $dbh = new PDO("mysql:host=localhost; dbname=test_db6; charset=utf8", "$user", "$password");

    $stmt = $dbh->prepare('DELETE FROM users WHERE id = :id');

    $stmt->execute(array(':id' => $_GET["id"]));

    echo "削除しました。";

} catch (Exception $e) {
          echo 'エラーが発生しました。:' . $e->getMessage();
}

?>

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>削除完了</title>
  </head>
  <body>          
  <p>
      <a href="index.php">投稿一覧へ</a>
  </p> 
  </body>
</html>
```

### index.php（投稿一覧）

データが削除されました。

![スクリーンショット 2019-07-07 13.28.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392565/174ecf5e-f129-b44c-e3fb-d1ae9eeee727.png)


データベースの中身も削除されました。
![スクリーンショット 2019-07-07 13.28.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/392565/029a44a7-b303-8035-11c2-acdbc30d2396.png)
[baserCMS]各コンテンツに設定できるアイキャッチ画像を表示する


baserCMSでは、4系から各コンテンツ別にアイキャッチ画像を設定することができます。
その利用方法について載せときます。
各ページ、フォルダ、ブログコンテンツやメールフォームの「オプション」タブ内に存在するアイキャッチ画像を、公開側で表示させたいときにご利用ください。


## 想定している対象者
- baserCMSでウェブサイトを制作をしている方
- PHPer


### 環境
- baserCMS 4系


## 表示方法

レイアウトファイル等にこんな感じで書くと良いです。

```
<?php echo $this->BcUpload->uploadImage('Content.eyecatch',
	$this->request->params['Content']['eyecatch'],
	array(
		'imgsize' => '', // 画像サイズの指定。空指定で生成されるサムネイルではなくアップした画像そのものを指定できる
		'alt' => '', // alt属性
		'noimage' => '', // 画像がなかった場合に表示する画像。例: admin/noimage.png（baserCMSコアが持ってる画像）
		'output' => '', // 出力タイプ tag ,url を指定、未指定(or false)の場合は、<img>のHTMLで出力
		'link' => false, // 大きいサイズの画像へのリンク有無
	)
); ?>
```

よく使うオプション添えてあります。
BcUploadHelper 内の uploadImage() を見るとより詳細な情報が得られます。
https://github.com/baserproject/basercms/blob/dev-4/lib/Baser/View/Helper/BcUploadHelper.php#L179


## 補足

表示方法のサンプルでは、以下のコードを用いてます。

```
$this->request->params['Content']['eyecatch']
```

これは、現在見ているコンテンツの情報を取得してます。
このコンテンツ情報の取得については、baserCMSの利用では外せない BcBaserHelper 内の getCurrentContent() が利用できます。
具体的には以下のようにできます。

```
$currentContent = $this->BcBaser->getCurrentContent();
<?php echo $this->BcUpload->uploadImage('Content.eyecatch', 
	$currentContent['eyecatch']
); ?>
```

ちょっと冗長だなと思ったり、現在のコンテンツ情報を使いまわしたいときはこんな手法もあります。
enumを使ってセレクトボックスに情報を入れる方法

モデルにenumを記述。

```PHPruby:model.rb

  enum delivery_area:{
  "---":0,
  北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7,
  茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14,
  新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20,
  岐阜県:21,静岡県:22,愛知県:23,三重県:24,
  滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30,
  鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35,
  徳島県:36,香川県:37,愛媛県:38,高知県:39,
  福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,沖縄県:47
  }

```


hamlで呼び出す。

```
        .listing-product-regional-original-delivery
          .listing-default__label 配送元の地域
          %span.listing-default--require 必須
          .listing-select-wrapper
            .listing-select-wrapper__box
              = f.select :delivery_area, Product.delivery_areas, {}, {class: 'listing-select-wrapper__box--select'}
              %i.fas.fa-chevron-down.listing-select-wrapper__box--arrow-down

```

(補足)
= f.select :今回はカラム名に合わせた名前, モデル名.今回はカラム名に合わせたenum名の複数形, {オプションが必要なら記述、今回は特にないがオプションなしを明示しなければならないので、空欄で記載}, {このセレクトボックスのクラス名}


**※注意**
enumは同じkeyを使ってはいけないらしい。
<参考>https://www.changesworlds.com/blog/2017/08/how-to-use-activerecord-enum-and-how-to-avoid-duplicate-errors/


####例
下記だと "---":0,が重複している為、ArgumentErrorが発生する。
参考URLのように_prefix: trueをつけることで解決できた。


```
  enum delivery_method:{
  "---":0,
  未定:1,らくらくメルカリ便:2,ゆうメール:3,レターパック:4,普通郵便（定型、定型外）:5,
  クロネコヤマト:6,ゆうパック:7,クリックポスト:8,ゆうパケット:9
  },_prefix: true


  
enum delivery_area:{
  "---":0,
  北海道:1,青森県:2,岩手県:3,宮城県:4,秋田県:5,山形県:6,福島県:7,
  茨城県:8,栃木県:9,群馬県:10,埼玉県:11,千葉県:12,東京都:13,神奈川県:14,
  新潟県:15,富山県:16,石川県:17,福井県:18,山梨県:19,長野県:20,
  岐阜県:21,静岡県:22,愛知県:23,三重県:24,
  滋賀県:25,京都府:26,大阪府:27,兵庫県:28,奈良県:29,和歌山県:30,
  鳥取県:31,島根県:32,岡山県:33,広島県:34,山口県:35,
  徳島県:36,香川県:37,愛媛県:38,高知県:39,
  福岡県:40,佐賀県:41,長崎県:42,熊本県:43,大分県:44,宮崎県:45,鹿児島県:46,沖縄県:47
  },_prefix: true

````
【Java】Java 10で拡張された型推論について注意すべきこと

![6qwm567z1m.jpg](https://img.esteem.ws/6qwm567z1m.jpg)

[Swift](https://ja.wikipedia.org/wiki/Swift_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E))や[Scala](https://ja.wikipedia.org/wiki/Scala)、[Kotlin](https://ja.wikipedia.org/wiki/Kotlin)、[Go](https://ja.wikipedia.org/wiki/Go_\(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E\))、[Rust](https://ja.wikipedia.org/wiki/Rust_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E))で開発している方はいわゆる「型推論」を普段使い慣れていることでしょう。型推論は、静的型付け言語における言語機能であり、明示的に型を記述しなくてもコンパイラが自動的に型を決定してくれる機能ですので、Kotlinの型推論のように、

```
var a = 1
```

と記載するだけで、コンパイラが右辺の型から自動的に左辺の変数aが整数型であると推論してくれるわけです。ついにJavaでもJava10から『ローカル変数の型推論』が導されたことは記憶に新しい出来事でもありました。

たとえば、Java 10よりも前では以下のように変数の型を明示的に書く必応がありました。

```
String name = "tamito0201";
```

Java 10 になるとvarキーワードを付けることによって、次のようにローカル変数の宣言で必須の明示的な型を削除することができます。

```
var name = "tamito0201";
```

上記の場合は、ただStringがvarに置き換わっただけなので、あまりメリットを感じないかもしれません。しかし、Javaの場合コレクションAPIを使用する際に、うんざりするほど冗長なコードを書かなくてはいけませんよね。

```
HashMap<Integer, String> map = new HashMap<Integer, String>();
```

Java10以降ではこれを、

```
var map = new HashMap<Integer, String>();
```

のように記載することができます。なんてエレガントなのでしょう。

ただし、型推論は便利な反面思わぬバグを生んでしまう諸刃の剣でもあります。ですので、プロジェクトによってはコーディング規約によりvarの仕様を禁じ、明示的に型を指定するプロジェクトも存在します。大規模プロジェクトになればなるほど、思わぬバグを生むリスクを考えて、旧来通りの明示的な型指定を行うプロジェクトも多いのです。

なぜか？たとえば以下のコードが記述されているとしましょう。

```
var distance = getDistance();
System.out.println(distance * 100);
```

関数getDistanceの戻り値はなんでしょうか。ここで感の鋭い方は気づいたかもしれませんね。そうです。ラッパーオブジェクトであるIntegerを返却する可能性があるのであれば、nullが返ってくることもあります。その結果次の`distance * 100`でヌルポが発生するのは自明ですので、nullチェックを入れる必要があります。

```
Integer distance = getDistance();
if (distance != null) {
    System.out.println(distance * 100);
}
```

Java 8以降ではOptionalを返せばよいですね。

```
Optional<Integer> distance = Optional.ofNullable(getDistance());
distance.ifPresent(d -> System.out.println(d * 100));
```

つまりそのプロジェクトやチームでvarを使いわけるため、コーディング指針を決めておく必要があります。

- varを使わない
- ローカル変数は原則varを使用する。
- 右辺に明示的な型が指定されている場合のみvarを使用する
- コーディング規約で明示する型を決めてそれ以外はvarを使う
- 単体テストでカバーするためプロジェクトではvarを使用する

どれも正解ですが、現実的には1 or 2が妥当であると考えられます。コーディング規約でいくら明示する型を指定しても大規模プロジェクトでは、コーディング規約をすべてのエンジニアが遵守できるなんて到底考えられませんからね。コーディング規約で決めて、[Checkstyle](https://ja.wikipedia.org/wiki/Checkstyle)や[SpotBugs](https://spotbugs.github.io/)、[PMD](https://pmd.github.io/)等でしばっておいたほうがいいかと思います。

何事にもメリット、デメリットはあります。

この辺りは、プロジェクトでどうするか必ず決めておいて下さい。決めないと出来上がったプロジェクトのソースはカオスになってしまいますからね。
#Ruby の then / yield_self は メソッドチェーンで nil  を防止するための初期値代入にも使えそうだけど？

# Ruby's then / yield_self could also be used for initial value assignment to prevent nil in the method chain?


題材は多分不適切

こんなので  nil を防ぎたい時

```rb
numbers = [1,2,3]; numbers&.max.yield_self { |max| max || 0 } + 1
# => 4
```

then / yield_self での書き方

```rb
numbers = nil; numbers.then { |numbers| numbers || [] }.max.then { |max| max || 0 } + 1
# => 1

numbers = nil; numbers.yield_self { |numbers| numbers || [] }.max.yield_self { |max| max || 0 } + 1
# => 1
```

かっこでくくる + ぼっち演算子での書き方

```rb
numbers = nil; (numbers&.max || 0) + 1
# => 1
```


# Original by Github issue

https://github.com/YumaInaura/YumaInaura/issues/2254








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
古川研究室 ~Workout calendar~ の紹介


九州工業大学の[古川研究室](http://www.brain.kyutech.ac.jp/~furukawa/)です。

例年、弊研究室の新入生は入ってから3ヶ月間の新人研修があり、機械学習の主要なトピックと弊研究室の基盤技術 SOM, 高階SOM, Tensor SOMを上級生の講義から学んできました。
時代が求めるスピードについていくために必要な基本技術・開発力を習得するため、今年度は [Workout_Report](https://github.com/furukawa-laboratory/workout_report_2019) を始動しました。Workoutの前半はオンライン上の機械学習の資料に取り組みGithub上で評価しあい、後半に基盤技術の講義をおこないます。

今年の新入生は活気にあふれ、忙しい中でも自分なりに考えながら課題に取り組み、そして、前半戦の集大成として学んだことをアウトプットする段階になりました。
ついでに、研究室全体でアウトプットして盛り上げようじゃないかということになりまして、Advent calendar ならぬ **Workout calendar** として、7/16から夏休み前までの１ヶ月間、研究室持ちまわりで一人ずつ記事をアップロードしていきます。

内容が曖昧であったり表現が多少異なったりする場合がありますので、解説記事というより勉強のメモとして捉えてください。それでもよければ是非、読んでいってください！

この記事はそのWorkout calendarのまとめの記事です。(7/16現時点では未完成)


&nbsp;1日目: イントロダクション
&nbsp;2日目: [交差検定を用いたモデル選択](https://qiita.com/kusmoto/items/a9f43fe4f3defa0b0725)
&nbsp;3日目: [Nadaraya-Watson推定 と k近傍法(前編)](https://qiita.com/kpasso1015/items/50e62ca52b4a19bfb782)
&nbsp;4日目: 甲: [データ数が入力次元より少ない場合の重回帰分析](https://qiita.com/seno/items/14fad1ef792e48f4d4d6), 乙: [線形回帰における疑似逆行列の幾何学的解釈](https://qiita.com/seno/items/e9ec1b4b6d245e29e0b1)
&nbsp;5日目: [高次元空間中の正規分布は超球面状に分布する](https://qiita.com/ae14watanabe/items/ef5689d40a0fbee957ea#_reference-0f292541988be7fb0851) 

&nbsp;6日目: [変分ベイズ法の解説](https://qiita.com/takuro-Ishida/items/2ecfafc679260211a0ab)
&nbsp;7日目: [Nadaraya-Watson推定 と k近傍法(後編)](https://qiita.com/kpasso1015/items/5a26d4bc1115fb1e9eb3)
&nbsp;8日目: [データをシャッフルしてクラスタリングで元に戻すやつ Clustering Tips①](https://qiita.com/hajime9652/items/b6a638c490978d6d5b90)
&nbsp;9日目: [Pytorchで勾配法](https://qiita.com/kpasso1015/items/d20f2ff323c0eb4526f3)
10日目:[正準相関分析](https://qiita.com/yoneda88/items/847cb99542538083b876)

新入生の記事Start!!
１週目
11日目: [ハードマージンSVMについて勉強したことのまとめ](https://qiita.com/oirom/items/5094470b979cbdca0396)
12日目: [最尤推定を用いた回帰](https://qiita.com/tsnry7913/items/e56e08aa23d141175a04)
13日目: 固有値、固有ベクトルの性質(全三部作)
 序: [固有値と固有ベクトルの性質](https://qiita.com/syusyumk2/items/79c08335e90e8d7de036), 破: [固有値、固有ベクトルの応用例（二次形式）](https://qiita.com/syusyumk2/items/22210fd4065c58e7a157), Q: [固有値、固有ベクトルの応用例(主成分分析)](https://qiita.com/syusyumk2/items/4aa7615c0c72a33456f8)
14日目: [Jupyter notebook ショートカット解説](https://qiita.com/forusufia/items/bea3f6fd6160cd2f5843)
15日目: [リッジ回帰の実装](https://qiita.com/K_Noguchi/items/3f5cf527d6f6d46767fb)
２週目
16日目: [M(マッチョ)VAE](https://qiita.com/syusyumk2/items/ad3603a0ab65046bde72)
17日目: [MAP推定を用いた回帰](https://qiita.com/tsnry7913/items/b9f15953191e5e08d5af)
18日目: [kNNの説明とその実装](https://qiita.com/oirom/items/22ccb7c0139dce925f43)
19日目: ["線形分離可能"のイメージをつかむ](https://qiita.com/forusufia/items/53de18be0e07b258fc76)
20日目: [3種類の基底関数によるベイズ線形回帰の実装](https://qiita.com/K_Noguchi/items/808414d0e98aea6e23e3)
３週目
21日目: [kNNとベイズ誤り確率](https://qiita.com/oirom/items/49009c8903ece81fd7cf)
22日目: [ベイズ推定を用いた回帰](https://qiita.com/tsnry7913/items/3854d3cc2134a6ba183d)
23日目: [機械学習初心者が確率的主成分分析を頑張って理解しようとしてみた](https://qiita.com/syusyumk2/items/97e68837083545938323)
24日目: [データ前処理入門編！](https://qiita.com/forusufia/items/eca1f54a39b1db380589)
25日目:[特異値分解と低ランク近似について](https://qiita.com/K_Noguchi/items/60ba6a08d1f913e74a83)
ubuntu ソフトウエア更新　apt update upgradeの失敗対処メモ 18.4

「ソフトウエアの更新」アプリや sudo apt update、sudo apt upgrade、
apt install で失敗したり、途中で止まってしまう場合の対処メモ

- 18.4.2で更新時に起きたトラブル対処
- まずupdateは非常に時間がかかる場合があると思っていた方が良い
- 下手にプロセスを止めない方が良い
- 数時間程度してダメな場合

### トラブル対処
$ suddo apt —fix-broken install
$ sudo apt dpkg —configure -a

$ sudo apt autoremove         # 不要なパッケージを削除

### 通常の更新作業
$ sudo apt update
$ sudo apt upgrade

### dpkg系の対処メモ
#### 原因を探る
$ sudo dpkg --audit    
#### 壊れているパッケージの強制削除
$ sudo dpkg --remove --force-remove-reinstreq 該当パッケージ


#### dpkg マニュアルメモ
dpkg [action] [option] [package]
action引数
-i	パッケージをインストールする
--unpack	パッケージを展開する
--configure	展開されているパッケージを設定する
-r, --remove	パッケージをアンインストールする
-l パターン	パターンにマッチするパッケージを一覧する
-L	システムにインストールされているパッケージを一覧する
-C	インストールが完了していないパッケージを一覧する
-S ファイル名	指定したファイルが所属するパッケージを表示する
--force-depends

オプション引数
--force-remove-reinstreq  再インストール必須、状態のパッケージ強制削除
-B	依存しているパッケージの設定を取り消す
--force-downgrade	強制的に古いバージョンのパッケージをインストールする
--no-force-downgrade	古いバージョンのパッケージのインストールを拒否する
--force-depends	依存関係を無視してインストール，アンインストールを行う
--force-depends-version	依存関係を評価するときにバージョンは無視する
--force-conflicts	他のパッケージと競合してもインストールする
--force-remove-reinstreq  再インストール必須、状態のパッケージ強制削除

### 参考
debian MANPAGE https://manpages.debian.org/about.html
ubuntu manials  http://manpages.ubuntu.com/manpages/
【Scala】処理中のものを処理し終わった上で終了するProducer-Consumerパターン

並行処理のデザインパターンでよくあるProducer-Consumerパターンですが、
このパターンに、タイトルの通りの動きのロジックを作成しましたので、紹介いたします。

# コード

```scala
import java.util.concurrent.ArrayBlockingQueue

class ProducerConsumer[E <: AnyRef](producerConcurrentNumber: Int, producer: () => E, consumerConcurrentNumber: Int, consumer: E => Unit, sentinelObject: E) {
  @volatile private[this] var terminateProducer: Boolean = _

  private[this] val queue = new ArrayBlockingQueue[E](consumerConcurrentNumber * 2)

  private[this] val producerThreadList = List.fill(producerConcurrentNumber) {
    new Thread(() => {
      while (!terminateProducer) queue.put(producer())
    })
  }
  private[this] val consumerThreadList = List.fill(producerConcurrentNumber){
    new Thread(() => {
      //whileを使うと微妙なようなので、再帰関数にして、それに末尾再帰最適化を効かせました
      //var item: E = sentinelObject//ignore value
      //while( {item = queue.take();item} ne sentinelObject)
      //  consumer(item)
      @tailrec
      def consumeLoop(): Unit = {
        val item = queue.take()
        if(sentinelObject eq item) return
        consumer(item)
        consumeLoop()
      }
      consumeLoop()
    })
  }

  def start() {
    producerThreadList.foreach(_.start())
    consumerThreadList.foreach(_.start())
  }

  def stop() {
    terminateProducer = true
    producerThreadList.foreach(_.join())

    1 to producerConcurrentNumber foreach(_ => queue.put(sentinelObject))
    consumerThreadList.foreach(_.join())
  }
}
```

1秒間に64スレッドで生産して、128スレッドで消費するパターンでの使用例

```java:使用例
import java.util.concurrent.TimeUnit

object Main extends App {
  import java.util.concurrent.atomic.AtomicLong
  val prodCnt = new AtomicLong()
  val consCnt = new AtomicLong()
  val cc: ProducerConsumer[String] = new ProducerConsumer(
    64,
    () =>
      "aaa"+prodCnt.getAndIncrement()
    ,
    128,
    _a => consCnt.getAndIncrement(),
    new String(""))//終了処理の判定だけに使う番兵オブジェクト
  cc.start()
  Thread.sleep(TimeUnit.SECONDS.toMillis(1))
  cc.stop()
  println("----- finish -----")
  println(f"生産した個数: ${prodCnt.get}%,d")
  println(f"消費した個数: ${consCnt.get}%,d")
  assert( prodCnt.get == consCnt.get)
}
```

# 解説

## Producerの終了方法
`terminateProducer`をtrueにすると、whileループから外れて生産しなくなって終了
`terminateProducer`はマルチスレッドから呼ばれるため、`@volatile`をつけておいたが、
つけなくても終了処理はされるため、外してもよい。

## Consumerの終了方法
Producerのスレッドが全部終了し、queueへの追加が行われなくなった後に、
番兵オブジェクト(`sentinelObject`)をConsumerのスレッド数分だけ投入する。

Consumerスレッドでは、`sentinelObject`が来たら終了という判定を行っている。
番兵オブジェクト(`sentinelObject`)の判定は、`!=`ではダメで`ne`で同じ参照値かのチェックで判定を行う。

## その他
~~ConsumerスレッドのロジックがScalaっぽくないコードになってしまった。
Scalaでは、ローカル変数宣言時の初期値Must、代入式の結果を利用できないため…。
こういう場合だけは、Javaのほうが短く書ける。~~

こういうところでwhileを使うと微妙なようなので、再帰関数にして、それに末尾再帰最適化を効かせました。
たぶん、Scalaではこう書くもんなんだと思われる。

# 参考資料
[番兵 \- Wikipedia](https://ja.wikipedia.org/wiki/%E7%95%AA%E5%85%B5)
S3でパブリックアクセス可能なファイルを投稿する

#はじめに
久しぶりに AWS で新規アプリケーション開発したらハマった。

2018/11 から S3 のパブリックアクセス機能がリリースされ、一工夫必要になったらしい。
https://aws.amazon.com/jp/blogs/news/amazon-s3-block-public-access-another-layer-of-protection-for-your-accounts-and-buckets/

ではどうすればいいのかという話。

パブリックアクセス機能についてはこちらを参照。
https://dev.classmethod.jp/cloud/aws/s3-block-public-access/

# 設定手順
下記の3つのいずれかの設定でパブリックアクセス可能なオブジェクトにできる。


## 公開権限を委任しアップロード時にパブリックアクセスを許可する
権限の委任以外は従来と同じ。

### パブリックアクセス設定
* 新しいアクセスコントロールリスト (ACL) を介して許可されたバケットとオブジェクトへのパブリックアクセスをブロックする
* 任意のアクセスコントロールリスト (ACL) を介して許可されたバケットとオブジェクトへのパブリックアクセスをブロックする

の ２つをオフにする。

<img width="1212" alt="スクリーンショット 2019-07-07 11.45.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452042/a35124e1-186a-d42f-e85a-63f636ecb6d9.png">

あとは、ファイルアップロード時に acl でパブリックアクセスにすればOK。

```
aws s3 cp [任意のファイル] s3://s3-public-access-test/ --acl public-read
```

## バケットポリシーで許可
下記のポリシーで、s3-public-access-test バケットの public フォルダ以下についてパブリックアクセスを許可している。


### パブリックアクセス設定
下記の 2つを許可しておく。

* 新しいパブリックバケットポリシーを介して許可されたバケットとオブジェクトへのパブリックアクセスをブロックする
* 任意のパブリックバケットポリシーを介して、バケットとオブジェクトへのパブリックアクセスとクロスアカウントアクセスをブロックする


<img width="1173" alt="スクリーンショット 2019-07-07 12.08.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452042/b498f433-7cfb-c9bd-6283-958b2472d84b.png">


### ポリシー
下記のポリシーを「アクセス権限」タブ内のバケットポリシーで設定する。
<img width="1168" alt="スクリーンショット 2019-07-07 12.13.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452042/34193690-02b3-f2ab-2d3e-c37f3a623e03.png">

```
{
  "Version":"2012-10-17",
  "Statement":[
    {
      "Sid":"AddPerm",
      "Effect":"Allow",
      "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::s3-public-access-test/public/*"]
    }
  ]
}
```

public ディレクトリ以下にアップロードされたファイルは常にパブリックアクセス許可された状態になる。

```
aws s3 cp [任意のファイル] s3://s3-public-access-test/public/
```

## バケットポリシー & タグで制御

特定のタグが付与されたオブジェクトについて、パブリックアクセス許可のポリシーを適用する方法。
一括で権限を変更できるので一番スマートかもしれない。

タグの利用には別途料金がかかる。
https://aws.amazon.com/jp/s3/pricing/#S3_Storage_Management_pricing


### タグの追加
バケット内の「プロパティ」タブから、タグを追加

key: public-object
value: yes
<img width="599" alt="スクリーンショット 2019-07-07 12.42.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452042/50078d19-6d8c-78c2-09ef-781bd606739c.png">


### パブリックアクセス設定
[バケットポリシーで許可]と同じ。

### ポリシー
設定方法は[バケットポリシーで許可]と同じ。

```
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::s3-public-access-test/*",
            "Condition": {
                "StringEquals": {
                    "s3:ExistingObjectTag/public-object": "yes"
                }
            }
        }
    ]
}
```

### コマンド
cp 時に付与できないようでちょっと面倒。プログラムでアップロードするなら関係ないかも。

```
# ファイルアップロード
aws s3 cp ~/Downloads/5c886538.jpg s3://s3-public-access-test/public/ --profile=kol 
# タグを付与
aws s3api put-object-tagging --bucket s3-public-access-test --key "public/[任意のファイル]" --tagging 'TagSet={Key=public-object,Value=yes}' 
```


#終わりに
AWS S3 でパブリックアクセス可能なファイルを投稿するための設定方法を記述した。
Techブログを書くなら数ヶ月前の自分に向けて書くと良いとどこかで読んだが、マジで自分に届け。
リクエストのスタブ化ができる WebMock の使い方を簡単に確認する

## はじめに

外部 API のリクエストを含むテストを試したいと思ったときに、[Webmock](https://github.com/bblimke/webmock) という gem でリクエストをスタブ化できることを知りました。

有名な gem なのかもしれませんが、使ったことがまだなかったので、簡単に使い方を試してみました。

## 前提環境

* Mac OS X 10.14.4
* Rails 5.2.2.1
* ruby 2.5.5p157 (2019-03-15 revision 67260)]

## 試し方

今回は WebMock の使い方をすぐに確認したかったので、予め準備しておいたサンプルの Rails アプリのコンソール上で、 Webmock のメソッドの使い方を確認します。

## 手順

### インストール

`Gemfile` に Webmock をインストールします。

```ruby:Gemfile
gem 'webmock'
```

### 下準備

`rails c` でコンソールを起動したら、Webmock を利用できるよう、有効化の設定を入れます。

```ruby
require 'webmock'
include WebMock::API
WebMock.enable!
```

こちらによって、WebMock のスタブへのリクエストに切り替わります。

### README のサンプルを試す

下準備が終わったら、[README](https://github.com/bblimke/webmock) を参考に、いくつかサンプルを試します。

#### URL のみのスタブリクエスト

以下のコードで、ダミーの URL である `www.example.com` へのすべてのリクエストが許可される形になります。

```rb
stub_request(:any, "www.example.com")
Net::HTTP.get("www.example.com", "/") 
#=> ""
```

#### クエリパラメータ付き URL のみのスタブリクエスト

クエリパラメータなど、変数に当たる部分は `{?}` という形で囲むことで使用することができます。

```rb
uri_template = Addressable::Template.new "www.example.com/users{?name}"
stub_request(:any, uri_template)

Net::HTTP.get('www.example.com', '/users?name=hoge') 
# => ""
```

#### ダミーのレスポンスを指定

リクエスト先の URL に対してダミーのレスポンスを指定できます。

```rb
stub_request(:any, "www.example.com")
  .to_return(body: "aaa", status: 200 )
Net::HTTP.get('www.example.com', '/') 
# => "aaa"
```

#### レスポンスをテキストファイルで指定

別で保存しておいたテキストファイルをレスポンスとして指定することもできます。

```rb
File.open('/tmp/response.txt', 'w') { |f| f.puts 'bbb' }

stub_request(:any, "www.example.com").
  to_return(body: File.new('/tmp/response.txt'), status: 200)

Net::HTTP.get('www.example.com', '/')
# => "bbb\n"
```

## おわりに

こちらを応用すれば、 外部通信が伴う API クライアントが絡んだテストも、リクエストの URL さえわかればスタブ化してテストすることができそうです。

今回は試していませんが、リクエストヘッダありの POST リクエストもスタブ化できるようなので、利用の幅が広いなと感じました。

これから試してみようと思います。

## 参考

* [GitHub - bblimke/webmock: Library for stubbing and setting expectations on HTTP requests in Ruby.](https://github.com/bblimke/webmock)
* [Rails開発でWebMockを使ってAPIアクセスをスタブ化する ｜ DevelopersIO](https://dev.classmethod.jp/server-side/rails-development-with-webmock/)
はじめてのhomebrew…どのような手順でhomebrewを導入したか

今までまともにMacを触ったことはなかったのですが、つい最近、MacBook Airを購入しました。購入して最初に導入したのは、鉄板のパッケージマネージャーである[homebrew](https://brew.sh/index_ja)です。

# homebrewの導入

インターネット接続さえ確立したならば、公式サイトの手順通り、以下のコマンドをターミナルで入力することにより導入プロセスが始まります。`sudo`は必要ありません。導入プロセスが始まったならば、あとは終わるまで見ているだけです。

`/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"`

homebrewの導入プロセスは、自宅のフレッツ光回線であれば、開始から合計数分で完了しました。

# homebrewで驚いたこと

Windowsの著名なパッケージマネージャーであるchocolateyでは、インストールプロセスでシェル上に出力されるメッセージは、以下の箇条書きに挙げるくらいでした。多くの場合、インストールプロセス自体はほぼサイレントで進んでいきます。

* Downloading
* (Downloading) Progress
* Hashes match
* Installing
* Installed

一方のhomebrewでは、依存関係にあるソフトウェアのインストールプロセスや、インストールに必要なシステム設定の変更までシェル上に出力されていきます。私がhomebrew-caskをインストールした際には、以下のようなメッセージがシェル上に出力されていました。

* gmpのインストール
* libtasn1のインストール
* libunistringのインストール
* nettleのインストール
* libffiのインストール
* p11-kitのインストール
* opensslのインストール
* libeventのインストール
* unboundのインストール
* gnutlsのインストール
* emacsのインストール
* caskのインストール
* libffiの実行結果
* opennsslの実行結果
* unboundの実行結果
* emacsの実行結果

モジュールの依存関係等の管理手法がWindowsとUNIX系では異なるためなのでしょうが、シェルに出力されるものがここまで違うと、強く印象に残ります。
【Kotlin】日時を取得して表示する【アンドロイドスタジオ】

ボタンを押して日時をテキストビューに表示する単純なもの

Design
![DatePicker_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456227/7c91cf41-6423-7670-4ac3-762b9458af35.png)



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

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" android:id="@+id/textView_01"/>
    <Button
            android:text="@string/button"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button_01" android:layout_marginTop="29dp"
            app:layout_constraintTop_toBottomOf="@+id/textView_01" app:layout_constraintStart_toStartOf="parent"
            android:layout_marginLeft="167dp" android:layout_marginStart="167dp" android:layout_marginBottom="279dp"
            app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginEnd="156dp" android:layout_marginRight="156dp"/>

</androidx.constraintlayout.widget.ConstraintLayout>
```

```kotlin:MainActivity.kt
package com.example.datepicker

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import  android.widget.TextView
import java.text.SimpleDateFormat
import java.util.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val textButton: Button = findViewById(R.id.button_01)
        val messageView: TextView = findViewById(R.id.textView_01)

        textButton.setOnClickListener {

            val df = SimpleDateFormat("yyyy年MM月dd日 HH:mm")
            val dateNow = df.format(Date())
            messageView.text = dateNow

        }
    }
}
```

<img width="400" alt="2019_07_07-001.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/456227/b2824ad7-a611-13ff-693e-5ee0521549f5.png">
初心者）Twitter クローン課題の苦労した点ピックアップ

##1.コメントコミット忘れがち。。
>**git add .**

>からの、、

>**git commit -m 'ここにコメント作成します'**

メンターさんにも課題提出時に指摘されたのですが、コミットする粒度が荒い。要はもっとコマメにセーブポイントを作りなさいとのこと。
最初は細かすぎるくらいのイメージでやって徐々に粒度を荒くしていく感じがいいのかもしれない。

**例えばこんな感じでやればよかったのかも、、**
>データベース作成（ファーストコミット）
>⬇
>モデル作成・マイグレーション（コミット）
>⬇
>バリデーション作成（コミット）
>⬇
>コントローラー作成（コミット）
>⬇
>indexページの作成（コミット）
>⬇
>showページの作成（コミット）　
>⬇
>......

##２．Confirm画面がややこしい
**hidden_field**というのがピンとこないんだが、
要は**フォーム画面なんだけど、入力フォームを生成せずに値のみを保持する**機能ということらしいです。
値の表示については下記のPタグで別途出力している。
(Pタグを削除すると値の表示はされないが、hidden_field で値は保持されているので登録は可能)

ただこのままではNewアクションのForm_withはCreateに飛んでしまうので、確認画面に飛ぶようにルーティングし直す必要がある。

ヘルパーを使ってNewとEditの分岐をするのですが、その際はHTMLのFoamタグに必須のAction属性を使って分岐させる。

**その際はFoamタグ作成の際にはAction属性（必須）とMethod属性（オプション）の指定を行う。**

>**Action属性**
>1.formタグに指定する属性で、必ず指定しなければならない
>2.フォームの送信ボタンを押して送信されるデータの送信先を指定する
>***
>**Method属性**
>1.formタグに指定する属性で、必須ではない
>2.送信するときの転送方法を指定する
>3.postとgetがある

```
module BlogsHelper
  def choose_new_or_edit
    if action_name == 'new' || action_name == 'confirm'
      confirm_blogs_path
    elsif action_name == 'edit'
      blog_path
    end
  end
end
```

##３．確認画面から値を保持しつつ「戻る」のがややこしい

hidden_fieldは値を保持しているので、これを使って値をnewのページを送り返している。戻るボタンのform_withはnewアクションを実行リクエストするため、HTTPメソッドがgetになるので注意してください。

さっき出てきたMethod属性-getを活用しています。
**それはformタグのmethodをgetに指定すると、入力したフォーム内容のデータがURIにくっついて送信されるから。**
**ちなみにmethodをpostに指定すると、入力したフォーム内容はURIとは別の場所に保管されてデータが送信される。**
入力したフォーム内容のデータは外側からの表示では見ることができないので安全性が高いのが利点となる。

```
<%= form_with(model: @blog, url: new_blog_path, local: true, method: 'get') do |form| %>
  <%= form.hidden_field :title %>
  <%= form.hidden_field :content %>
  <%= form.submit "戻る" %>
<% end %>
```


##（おまけ）　何故、formに"local: true"を入れるのか
**検索から。。**
local: trueがない場合、Rails 5ではAjaxによる送信という意味になります。ふつうにHTMLとしてフォームを送信する場合にlocal:trueが必要となります。
ザックリまとめ Born-Again Neural Networks論文

## Born-Again Neural Network論文まとめ
- 2018年5月にsubmitされた論文で、従来のKnowledgeDistillation(以下KD)と異なる応用方法についての考察です。
- [arXivはこちら](https://arxiv.org/abs/1805.04770)
- Born-Againは「生まれ変わり」の意味です。

## この記事で説明すること
- KDの概要
- 従来のKDの扱い
- 本論文の特徴

## この記事で説明しないこと
- 用いられたモデルの構造(DenseNet,Wide-ResNet)
- 実験の詳細

ザックリとまとめていきます。サクッと見ていきましょう。

## KnowledgeDistillation(KD)とは
日本語に直すと「知識蒸留」ということになります。蒸留というのは、「混合物を一度蒸発させ、後で再び凝縮させることで、沸点の異なる成分を分離・濃縮する操作をいう。」らしいです。(Wikipedia[「蒸留」](https://ja.wikipedia.org/wiki/%E8%92%B8%E7%95%99)より)

それを「知識」に対して行うのがKDです。元となる混合物の役割をするのが「教師モデル」、そこから蒸留した「知識」を移す先が「生徒モデル」と呼ばれるものです。
※教師・生徒モデルは特定の構造を持ったモデルを指すわけではないことに注意。

これを具体的にどうやるかと言いますと、**十分な量の訓練データで訓練した教師モデルの出力を、生徒モデルの出力の正解ラベルにする**という方法が一般的です。(ここではクラス分類を例に考えていきます。)

教師モデルの出力した予測分布には、教師モデルが学習で得た知見が反映されているはずであり、ただのone-hotラベルよりも多くの情報を含むことが期待されます。(例 クラス分類を考えるとき、犬と猫の出力は犬と車の出力よりも近いものと想定される。そのような **クラス間の関係**が教師モデルの出力には含まれていると想定される。)

上記の正解以外の情報のことを「Dark Knowledge」と言ったりします。

## 従来のKDの扱い
上記で見たKDですが、従来では「大きくて複雑な構造のモデル」から「計算資源が少なくても機能するコンパクトなモデル」に対して行うことが想定されています。

(その前提があったために、「教師」「生徒」という、ある意味で「教師＞生徒」を仮定したような名前になったのかなぁなどと思ったりします)

KDを提案した論文では、大きなモデルから小さなモデルへ知識を移すことに成功し、**モデル構造を大幅に小さくしながらも精度の減少を抑えることを実現しています**。

## 本論文の特徴
従来では「大きな教師モデル」から「小さな生徒モデル」へのKDを行っており、その題目は**「精度の減少を小さく抑えてコンパクトなモデルを作る」**ことでした。

それに対してBorn-Again Netでは「教師モデル」と**同じ構造**を持った「生徒モデル」を利用し、生徒モデルが教師モデルよりも優れたモデルになることを示しています。(生徒＞教師という関係になります。師匠モデルと弟子モデルとかの方が個人的にはしっくりきます)

つまりこの論文では「モデルを小さく・精度も維持」という目的ではなく「モデルはそのまま・精度を高く」することを目的としています。

実際の手法については論文内の以下の図がわかりやすかったので引用します。
![スクリーンショット 2019-07-07 11.48.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/391968/51b45440-ba6f-4eb9-8ab0-9de5394cef91.png)

Tが教師(Teacher)を、Sが生徒(Student)を示しており、生徒から生徒へのKDも連続的に行われます。
数回のKDの後に、それぞれの生徒モデルのアンサンブル(上図の右端)が最終的なモデルになります。

教師モデル・生徒モデルともに同じ構造を持っているので**「Born-Again」**(生まれ変わり)と表現しているものと思います。

### 関連論文
実験で用いられたモデル構造に関して
「DenseNet」 2016年発表
[Densely Connected Convolutional Networks](https://arxiv.org/abs/1608.06993)
「ResNet」 2015年発表
[Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385)

「Knowledge Distillation」に関して 2015年発表
[Distilling the Knowledge in a Neural Network](https://arxiv.org/abs/1503.02531)

###補足・所感
- この記事では詳細結果について省略しましたが、多くの場合は生徒モデルが教師モデルを上回るものの、必ずしも教師モデルより良い結果が出るとは限らないようです。(詳細に考察されているので結果だけ読んでも面白いと思います。)
- 蒸留の由来は「Softmax温度を上げること」にあります。関連論文の「Distilling the knowledge」論文にSoftmax温度について詳しく記載されています。
- この論文では同じ形のモデル同士以外にも、似たキャパシティを持った別のモデルへのKDも行っています。
- 上記でもちらっと書きましたが「師匠モデル」と「弟子モデル」の方が、蒸留先が蒸留元を超えていく感があって良いと思います！(ジャンプの読みすぎ)。
- 昨日投稿した[ザックリまとめ Full-body High-resolution Anime Generation論文](https://qiita.com/chobaken/items/9773082d4d57390d0079)もそうなんですが、モデル構造そのものではなく、入力データだったり、出力のターゲットに関する論文も読んでて面白いなぁと思います。
- モデルの構造によって学習で得る知見が変わると思うので、複数の異なる構造を持つ教師モデルからKDしても面白そうだなと思いました。

 

最後までお読みいただきありがとうございました！
間違い等あればご指摘のほどよろしくお願い致します！