OmniAICreator/Qiita-1.07M huggingface dataset:
絶対に動くはずのシェルスクリプトを実行して「予期しないファイル終了（EOF）」とか「sh: 0: Can't open」とか怒られたときによむページ

# TL;DR

シェルスクリプトを書くときは必ず改行コードを `LF` に統一して保存しようね！

# シェルスクリプトを実行したら `予期しないファイル終了（EOF）` とか `sh: 0: Can't open` とか怒られた

ある昼下がりのことでした。

![LF.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463374/4f8a2c60-cfbf-98e4-b63f-ccfbad887d55.jpeg)

この画像ほどではないにせよ、同じくらいに何の変哲もないスクリプトを実行したのですが、

```console
./tes.sh: 行 6: 構文エラー: 予期しないファイル終了 (EOF) です
```

……と、なぜか怒られてしまいました。UTF-8だし、改行コードはLFだし、どこに問題があるというのでしょう。vim で確認してみましょう。

![fiCRLF.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/463374/67e2579f-e9c0-dc18-cbfb-bccdc7806b4d.jpeg)

改行コードは `unix` （= `LF` ）で間違いないようです。4行目の行末に `^M` と表示されていますが、これは `CR` を表す制御コードです。4行目末だけ、なぜか `CRLF` で改行されていることがわかります。（いや本当になぜ？）

# なぜ「予期しないファイル終了」なのか

通常、同様のミスを犯していた場合、このようなわかりやすいエラーメッセージが表示されます。

```console
./tes.sh: 行 4: $'\r': コマンドが見つかりません
```

`\r` （= `CR` ）をコマンドだと解釈してしまうためです。


一方、`予期しないファイル終了 (EOF) です` は、 `if ~ fi` ブロックが閉じられていないときなど、シェルスクリプトに構文エラーがあることを知らせるエラーメッセージです。 今回は `fi` の直後に `CR` が挿入されていたため、`if ~ fi` ブロックが壊れてしまっていたようですね。

# 参考リンク

* <https://qiita.com/bezeklik/items/aca37ffb127821311d6b>
* <https://code-examples.net/ja/q/612542>
ぼくのかんがえたさいきょうのWordpress@AWS環境(Route53でドメイン取得編)

# はじめに
当記事は[ぼくのかんがえたさいきょうのWordpress@AWS環境](https://qiita.com/Shi-nakaya/items/7fb6d16c0adb5c7b47fd)にて記載している[作成手順](https://qiita.com/Shi-nakaya/items/7fb6d16c0adb5c7b47fd#作成手順)の
1. [WordPress入りのLightSailを作成](https://qiita.com/Shi-nakaya/items/a882963cf14dcc64fcac) 
2. [Route53にてドメインを取得](https://qiita.com/Shi-nakaya/items/edcd86a3a8811654573b)← ここの手順の詳細です。
3. [取得したドメインを元にSSL証明書を発行](https://qiita.com/Shi-nakaya/items/d35b5a0f7fb7a7689fce)
4. [CloudFront構築](https://qiita.com/Shi-nakaya/items/b00a04e07ca6e24887ca)
5. [DNSの設定](https://qiita.com/Shi-nakaya/items/30d2339c3570d012ca62)
6. [セキュリティ対策](https://qiita.com/Shi-nakaya/items/8812da74f5dca200cf45)

Route53にて独自ドメインを取得するまでを記載します。

# 手順
AWSにログインし、サービスから「Route53」をクリックします。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/520b42f3-526c-2dde-9457-018a1f87fca8.png" width=40%>

「ドメインの登録」をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/ef1f33c3-91cc-1fe7-7214-6414b3729551.png" width=40%>

ドメイン名の選択で自分の取得したいドメイン名を入力
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/be223a65-a539-d024-3c41-0e0e164fce52.png" width=40%>

「チェック」をクリックすると利用可能なドメインの一覧が表示されるので
「カートに入れる」をクリックして
下にスクロールして「続行」をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/8ea4a587-eb30-e3af-1045-ae7a3eca22f8.png" width=40%>

必要事項を入力して「続行」をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/479b2809-f00e-bca0-57cd-2011f9c590cd.png" width=40%>

入力した情報、取得するドメインに間違えがなければ
「AWSドメイン名の登録契約を読んで同意します」にチェックを入れて
「購入の完了」をクリック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/d3e61e0b-3986-010c-5b96-1825a9b40948.png" width=40%>

登録したメールアドレスに確認用のメールが
届くので記載されているURLをクリックして認証する
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/be0b5abb-aef4-2c03-cec6-8bb189327a3e.png"" width=40%>

「保留中のリクエスト」に登録したドメインが表示されており、
登録処理が完了すると
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/8590a980-522d-3eb5-3568-10c866209ebc.png" width=40%>
「登録済みのドメイン」にレコードが移行される

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/dab8fdc6-1209-a205-fc0d-c3b825de695a.png" width=40%>

左タブのホストゾーンをクリックすると
取得したドメインのホストゾーンが自動的に登録されているのが確認できる
<img width=40% alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/265300/a571b4ae-d74b-c7ed-dfa7-cb5e61c52f69.png">

以上でドメインの取得は完了です。
DockerでFlask開発環境構築

# 使うもの

- macOS High Sierra
- Docker
- VSCode
- brew

# VSCodeの設定

まずはVSCodeにPythonの拡張機能をインストールします。

すると以下の警告が出ています。
<img width="444" alt="スクリーンショット 2019-08-18 12.27.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263328/761443c8-0f22-6dfd-be34-505a7e6398fa.png">

macに入っているデフォルトのPython2は推奨されないみたいなので、python3をインストールします。
```brew install python3```

「Select Python Interpreter」を押してPython3を設定。

あとは以下の警告も消すために「install」を押してpipもインストールしておきます。

<img width="448" alt="スクリーンショット 2019-08-18 12.37.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263328/03cc909c-63f9-feb7-aa5f-a8c5bd0758fb.png">

 ```pip3 --version```でバージョン情報が出てばインストール完了。

VSCodeの設定はここで完了。

# Dockerの設定

ディレクトリ構成はこんな感じ

```
root
├── Dockerfile
├── docker-compose.yml
└── main.py
```

それぞれのファイルは以下の通り

```docker:Dockerfile
FROM python:3.7

WORKDIR /app

RUN pip install flask
RUN pip install xmltodict

CMD [ "python", "main.py" ]
```

```yml:docker-compose.yml
version: '3'
services:
  api:
    build: .
    ports:
      - 80:8080
    volumes:
      - ./main.py:/app/main.py
    tty: true
```

```python:main.py
from flask import Flask, jsonify, request
import json
import urllib.request
import xmltodict

app = Flask(__name__)
app.config['JSON_AS_ASCII'] = False

@app.route("/", methods=['GET'])
def index():
    # パラメーター取得
    keyword = request.args.get('keyword')
    # API通信
    req = "https://news.google.com/rss/search?q=" + urllib.parse.quote_plus(keyword, encoding='utf-8') + "&hl=ja&gl=JP&ceid=JP:ja"
    # 結果取得
    with urllib.request.urlopen(req) as res:
        body = res.read()
    # XML → 辞書に変換
    dict = xmltodict.parse(body)
    # 辞書 → JSONに変換
    data = json.dumps(dict, indent=4, ensure_ascii=False)
    # 結果返却
    return data

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=8080)
```

keywordパラメータで受け取った文字列でGoogleNewsのRSS取得してJSON形式で返すだけのAPIです。

# 動作確認

```docker-compose up -d```でコンテナ起動

あとはこんな感じでAPI叩いて結果返ってくれば終わり
http://localhost?keyword=スマホ

以上。サクッとFlask環境構築でした。
量子場脳理論入門

量子場脳理論入門, 保江邦夫, サイエンス社, 2003
https://bookmeter.com/books/14381541
![2003-4910054700732.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/b63df101-4531-ae3c-921a-61fdcbf2cb0a.jpeg)



高橋 康 著　古典場から量子場への道―これから′場′を学ぶ人のために は読んでいて、本書の参考文献にあがっている。本書は未読だった。

場の量子論―ミクロ、マクロ、そして熱物理学の最前線  1995/7 Hiroomi Umezawa 培風館
https://www.amazon.co.jp/dp/4563022217/


M. Gibu, K.Yasue and S. Hagan, Biosystems, 42, 65, 1997
C. P. Enz, Held, Phys, Acta, 70, 141, 1997
M. Hirokawa, Rev, Math, Phys, 13, 221, 2001

高橋康　
物性研究者のための場の量子論 1 (新物理学シリーズ 16) 1974/10
高橋 康 
![51ETBogF4SL._SX333_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/42e83a44-63cf-ead0-f5e9-644241a1fb4f.jpeg)
https://www.amazon.co.jp/dp/4563024163/

古典場から量子場への道―これから′場′を学ぶ人のために  1979/9 高橋 康 
![21EZP1MJ2XL._BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/6982c053-2a22-09d7-5c71-86f8457dd22e.jpeg)
https://www.amazon.co.jp/dp/406139312X/
>場を決定する方程式として、
弾性体
流体
電磁場
までは、数学的になんとか理解できます。
実際に目でみえる現象で説明がつくからかもしれません。
それ以外の事項については、より物理的な現象との関係の説明があると、数学が苦手な人にもわかるようになるかもしれません。

量子場を学ぶための場の解析力学入門 増補第2版 (KS物理専門書)  – 2005/1/26
高橋 康 , 柏 太郎  
![41G3G4DPXYL._BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/ad076c67-90f0-98d3-0e11-5745b57b30c8.jpeg)
https://www.amazon.co.jp/dp/4061532529/


物性研究者のための場の量子論 2 (新物理学シリーズ 17) 単行本 – 1976/4
高橋 康 
![31FYLRdza1L._SY298_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/8ccc2aa9-a9f2-fcfb-2c4a-f9d77655a602.jpeg)
https://www.amazon.co.jp/dp/4563024163/

添削形式による場の量子論  1997/12, 高橋 康, 治部 真里  
![61ODcjXe6eL._SX345_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/f56f84c4-ff54-f94c-0dc8-c966dd6eb054.jpeg)
https://www.amazon.co.jp/dp/4535782555

多量子問題から場の量子論へ (物理のたねあかし)  1997/2 高橋 康  
![218CY78YY3L._BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/d1a51628-5214-2081-d92a-87910e843b60.jpeg)
https://www.amazon.co.jp/dp/4061551019/

場の理論　武田  暁　 (物理学選書)
![3114XQDVJQL._SX332_BO1,204,203,200_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/51423/87d7cb95-e656-845c-7720-e0f7c209773c.jpeg)
https://www.amazon.co.jp/dp/4785323221/
Leetcode #1087: Brace Expansion

```swift
func expand(_ S: String) -> [String] {
    var S = Array(S)
    var ar = [[Character]]()
    var insideBraces = false
    for i in stride(from: 0, to: S.count, by: 1) {
        if S[i] == "," {
            continue
        } else if S[i] == "{" {
            insideBraces = true
            ar.append([])
        } else if S[i] == "}" {
            insideBraces = false
            ar[ar.count-1] = ar[ar.count-1].sorted()
        } else {
            if insideBraces {
                ar[ar.count-1].append(S[i])
            } else {
                ar.append([S[i]])
            }
        }
    }
    var answer = [String]()
    helper(ar, 0, [], &answer)
    return answer
}

private func helper(_ ar: [[Character]], _ index: Int, _ chars: [Character], _ answer: inout [String]) {
    if index == ar.count {
        answer.append(String(chars))
        return
    }
    for i in stride(from: 0, to: ar[index].count, by: 1) {
        helper(ar, index+1, chars+[ar[index][i]], &answer)
    }
}
```
【ブラウザ】ブラウザに画面リサイズ機能追加（アドオン）

## ブラウザの画面サイズ変更拡張機能の追加

### 概要
開発において画面のキャプチャが必要となる際（画面設計書、マニュアル作成、等々）に画面のサイズを固定幅でキャプチャしたい。
ブラウザの拡張機能を使用して画面が常に同じ画面サイズになるようにブラウザの拡張機能を追加する。
Chrome、FireFox両方で同じ機能がある「Window Resizer」を設定する。

#### 環境
+ Google Chrome バージョン: 75.0.3770.142
+ FireFox Quantum 68.0.1（64ビット）

---

### ブラウザへの登録手順（Chrome）
1. chrome ウェブストアにページを開く（https://chrome.google.com/webstore/category/extensions）
2. 検索フォームで「window resizer」を検索
3. 以下の「Window Resizer」の「Chrome に追加」ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/1eb53701-9eb5-2293-4b1a-ea3c11ddeeae.png)
4. 追加が完了すると以下の様にアドレスバーの横にアイコンが追加される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/626e82d4-9dcb-57ed-5e4b-0a6c86ea0f86.png)

### ブラウザへの登録手順（FireFox）
1. FireFox Add-onsページを開く（https://addons.mozilla.org/ja/firefox/）
2. 検索フォームで「window resizer」を検索
3. 以下の「Window Resizer」のをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/661a5846-9777-1d50-896b-455111208996.png)
4. 詳細画面で「Firefox へ追加」ボタンをクリック
5. 追加が完了すると以下の様にアドレスバーの横にアイコンが追加される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/7f3f64d5-e57f-8570-e775-2ac303e53234.png)

### 使用手順
1. 追加されたアイコンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/f292055d-233d-2cd1-1f32-c1f915fbaebd.png)
2. 表示されたlayoutからリサイズしたいサイズをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/a110b853-7e4a-b8ec-8805-fdd248733b89.png)
3. ブラウザがリサイズされる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363906/e52c27aa-c4f3-0b2e-4dcc-d58c342b7f99.png)
Leetcode #1055: Shortest Way to Form String

```swift
func shortestWay(_ source: String, _ target: String) -> Int {
    if !Set(target).isSubset(of: Set(source)) {
        return -1
    }
    var count = 0
    var source = Array(source)
    var target = Array(target)
    var i = 0
    var j = 0
    while j < target.count {
        if source[i] == target[j] {
            i += 1
            j += 1
        } else {
            i += 1
        }
        if i == source.count {
            count += 1
            i = 0
        }
    }
    return i == 0 ? count : count + 1
}
```
RASISについて

#RASISとは
・RASISとは、サービスの信頼性を評価する指標のひとつ。
・RASIS＝「R:信頼性」「A:可用性」「S:保守性」「I:保全性」「S:安全性」の5項目の頭文字。

|頭文字  |英語  |日本語  |意味|
|---|---|---|---|
|R  |Reliability  |信頼性  |故障しにくいこと|
|A |Availability|可用性  |高い稼働率を維持できること|
|S  |Serviceability  |保守性  |障害が発生した場合に迅速に復旧できること|
|I  |Integrity  |保全性  |データが矛盾を起こさずに一貫性を保っていること|
|S  |Security  |安全性  |機密性が高く、不正アクセスがなされにくいこと|

## 参考
[RASIS：weblio辞書][1]
[1]:https://www.weblio.jp/content/RASIS

[Qiita：30秒で読める要件定義の機能要件＆非機能要件まとめ][2]
[2]:https://qiita.com/S-T/items/793de0f6c75d60288cdb
→とても参考になりました！備忘録としてリンク貼らせて頂きます。

##コメント
・非機能要件について再整理中。
・覚えておくべし言葉。
npx create-react-app my-app --typescriptのあと


```sh

npx create-react-app my-app --typescript

# りんと
npm install --save tslint
# スタイル
npm install --save styled-components @types/styled-components

# air-bnbのりんとやりたい
npm install --save-dev tslint-config-airbnb
```

```json:tslint.json
{
    "extends": "tslint-config-airbnb",
}
```

airbnbのりんとのめんどいやつはfalseにしたいので

```json:tslint.json
{
    "extends": "tslint-config-airbnb",
    // 追加
    "rules": {
        "import-name": false,
        "variable-name": false,
    }
}
```
今さら聞けないニューラルネットワークのこと

# はじめに

「ニューラルネットワーク=ディープラーニング（深層学習）」のような会話を耳にすることが多くなってきたので、本当にそうなの？ということで、ニューラルネットワークは機械学習なのだと説明できるよう頭を整理するために記事にしてみました。

後で記事を修正するかもしれませんが、とりあえず文字だけです...(^_^;)

# ニューラルネットワークを構成するもの

## パーセプトロン

複数の入力に対して1つの答えを持つもの。
以下のような排他的論理和の入力（X1、X2）と出力（Y）を考えてみます。

|X1|X2|Y|
|---|---|---|
|0|0|0|
|1|0|1|
|0|1|1|
|1|1|0|

ここでは、

```math
f(X1, X2) = Y
```

となるf(X1, X2)を求めるわけです。

```math
f(X1, X2) = (w1 \times X1 + b1) + (w2 \times X2 + b2) = Y
```

このとき、w1、w2、b1、b2を手で計算して求めるのはとても大変ですが、入力を繰り返し与えることでコンピュータが学習をし、w1、w2、b1、b2を調整しながら正確にYを求めることができるようになります。

## 活性化関数

前述のパラメータw1、w2、b1、b2は直線的な対応しかできないので、これをより複雑な学習ができるように様々な傾きを作り出すための仕組みです。

代表的なものに、シグモイド関数、ソフトマックス関数、ガウス関数、ReLUがあります。

## マルチレイヤーパーセプトロン

上記のようなパラメータの数では複雑なものの学習をしきれないので、パーセプトロンを複数積み重ねて複雑な学習を可能にしたのがマルチレイヤーパーセプトロンです。

## バックプロパゲーション

日本語では誤差逆伝播法（ごさぎゃくでんぱほう）と言い、上記のパラメータ調整をより効率よくする仕組みがあります。
学習した結果の予測値と実際の値を比較し、どのパラメータが誤差を生み出す原因になっているかを後ろから補正する処理のことです。

これにより、とても効率的に学習ができるようになったとのことです。

# 深層ニューラルネットワーク

通常、ニューラルネットワークでは４層以上になると学習の効果が薄れ、あまり精度向上につながらないと言われていたようです。
古くからの研究者に「４層以上のニューラルネットワークで学習するのはどうかと思います」というような発言があるのはこのためだそうです。

# 深層学習

上記のニューラルネットワークの結合方法を色々と工夫しながら４層以上のニューラルネットワークでも学習ができるようにして、高精度な予測を可能にしたのが深層学習とのことです。

# まとめ

ということで、僕の理解は以下のとおりです。

- ３層以下のニューラルネットワークは機械学習
- ４層以上のニューラルネットワークの中には深層学習と呼ばれるものもある

ま、間違っているかもしれないので、よくご存知の方がおられましたらコメントなどでご教示頂けると喜びます。
未経験者向け ShellScript Bash 〜超初心者用解説〜

未経験者 の ための ShellScript 〜超初心者用解説〜

# 目的

- ShellScriptを書く方法を知る
※プログラミング未経験状態で入社していきなりShellScriptを書かされた時に教えて欲しかったことを書きます。  
※記法など詳しいことは説明せず、記載方法や実行方法を主に書いていきます。

# この記事のターゲット

- ShellScriptを始めて書く方
- Linuxに全く触ったことがなく、ShellScriptを書かないといけなくなってしまった方

# SheellScriptって？？

- Linuxコマンドが羅列された処理ファイルのこと。
- ファイルに記載されたコマンドを上から順に実行していく。
- コンパイルしなくても実行できる。
- 拡張子は`.sh`
- 難しそうに見えるけど思いの外簡単に書くことができる。

# ShellScriptはどこに書くの？

- 記載自体はWindowsでも、macでも、Linuxでも書ける。
- 新規ファイルを作成し、任意のファイル名をつけて拡張子を`.sh`にしてあげて、文字が入力できるアプリ(メモ帳など)で開いて記載する。

# どうやって実行するの？

- Linuxの環境にファイルを持って行って実行する。
- WindowsにGit Bashをいれて実行する。
Git Bashのインストール方法は[こちら](https://qiita.com/miriwo/items/c26aabb9012ed639abaf)

# 合理的なShellScriptの記載方法は？

- Linuxのマシンを起動してログインをして記載する。
- TeraTermなどのsshを使用したターミナルからログインして記載する。
- VisualStudioCodeのプラグイン「SSH FS」を使用して記載する。
- Windowsの好きなテキストエディタで記載してGit Bashで実行
※この方法だと、フォルダ階層などが実際に使用する環境とは異なることが多いためちょっとレベル高いかも・・・？

# ちょっとしたテクニック

- ShellScriptを書くときは一行書く → 追記を保存 → ShellScriptファイルを実行 → おかしい処理がないか確認 と進むと間違えた記載を見つけやすい。

# まとめ
- ShellScriptはLinuxコマンドが羅列されたファイル
- どこでも書ける
- Linux上で実行することが望ましい
[Scala]sbt-scoverage で一部ファイルを除外する

sbt-scoverage、とても便利ですね。 plugin.sbt に記述するだけですぐにカバレッジ率を出してくれます。

```plugin.sbt
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.0")
```

```
// カバレッジ計測
sbt clean coverage test

// カバレッジレポート作成
sbt coverageReport

// 繋げてかく場合
sbt clean coverage test coverageReport
```

自分の環境だとこんな感じになっていました。

<img width="370" alt="スクリーンショット 2019-08-19 19.14.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/08a81431-aded-062d-e3bf-082fed2fafc4.png">

`controllers.javascript` のカバレッジ率が0%になってますね。そりゃそうです、書いてないですから。

これのせいで合計のカバレッジ率が下がってるとなるとちょっと納得いきませんね。という事で除外してみたいと思います。

# 除外する
公式githubに、それっぽいものがありました。(https://github.com/scoverage/sbt-scoverage#Exclude%20classes%20and%20packages)

`coverageExcludedPackages`

> 正規表現でカバレッジ測定の対象から除外できます。 セミコロンで区切ります

```build.sbt
coverageExcludedPackages := "<empty>;Reverse.*;.*AuthService.*;models\\.data\\..*"
```

これが使えそうですね。私のディレクトリ構成はこうなので

![スクリーンショット 2019-08-19 18.48.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/fb8f0317-6e62-e4d7-19db-6083dfcdf78f.png)

こうでしょうか。

```build.sbt
coverageExcludedPackages := ".*controllers.javascript.*"

```

import Changes してから実行

```shell
sbt coverageReport
```

<img width="371" alt="スクリーンショット 2019-08-19 18.44.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/2002f70f-214a-42b7-d6ec-e5ebf899a2cd.png">

あれ・・・変わらないぞ :thinking: 

# 試行錯誤
##### 正規表現を見直してみる

そもそもの公式ドキュメントの例として書かれている正規表現、最初に謎の物体が入っています。

```build.sbt
<empty>;
```

セミコロンは区切り文字なのでわかるのですが、 `<empty>` ってなんなんでしょうね。

オバフロでも `<empty> をつけて試してみて！` というコメントが付いている質問がありました。(http://danlec.com/st4k#questions/32331183)
とりあえず真似してみましょう。

```scala
coverageExcludedPackages := "<empty>;.*controllers.javascript.*"
```

```scala
sbt coverageReport

[info] Statement coverage.: 78.68%
```

お、カバレッジ率が上がった

<img width="384" alt="スクリーンショット 2019-08-19 19.21.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178351/88167295-9160-a41a-37fe-fcd96ecbb2d2.png">

という事で、78%に上昇しました。これが本来の値ですね。

なんで `<empty>;` がいるのか結構調べたのですが、全くわかりませんでした。
他の人も「よくわかんないけど必要だよ」みたいに言っているので、深く考えない方がいいかもしれません。(https://stackoverflow.com/questions/47940361/scoverage-how-to-exclude-files-and-packages)

中のコードを追っていたのですが、結構しんどくて諦めました・・・

# まとめ
* テストカバレッジから除外したいケースがある場合、 `coverageExcludedPackages` を使う
* 正規表現が通らない場合は、先頭に `<empty>;` をつけてみよう
gem installに失敗するときの対処法(Mac)

## はじめに

`gem install {パッケージ}` で様々なエラーが発生して苦戦したので、エラーの内容と解決策を共有します。

## 環境

- OS：macOS Mojave 10.14.3
- Ruby：2.6.3
- RubyGems：3.0.3

## `Failed to load {.gemrcのパス} because it doesn't contain valid YAML hash` エラー

__不具合内容__

`gem install {パッケージ}` で以下のエラーが発生する。

```shell-session
$ gem install {パッケージ}
Failed to load /Users/{ユーザー名}/.gemrc because it doesn't contain valid YAML hash
```

__原因__

空の `.gemrc` ファイルが存在するため。

__解決策__

空の `.gemrc` ファイルを削除する。

```shell-session
$ rm ~/.gemrc
```

## `Permission denied` エラー

__不具合内容__

`gem install {パッケージ}` で以下のエラーが発生する。

```shell-session
$ gem install {パッケージ}
ERROR:  While executing gem ... (Errno::EACCES)
    Permission denied @ dir_s_mkdir - /Users/{ユーザー名}/.gem/specs
```

__原因__

`.gem` フォルダの所有者が `root` になっているため。
なぜ `root` になったかは不明。

```shell-session
$ cd ~
$ ls -la
…
drwxr-xr-x   3 root        {グループ}     96  8 19 18:59  .gem
…
```

__解決策__

`.gem` フォルダの所有者を自分に変更する。

```shell-session
$ sudo chown -R {ユーザー名} ~/.gem
```

## 参考リンク

- [Ruby 2.0.0 をpikとrvm経由でインストール&環境構築 - kk_Atakaの日記](https://note.gosyujin.com/2013/02/25/ruby200-helloworld-pik-rvm/)
PostmanでParamsに設定した+記号が空白になってしまう場合の対処法

API動作確認中にハマったのでメモです。

PostmanのParamsで+記号を表現する場合は、
%2Bにエンコードすれば良いようです。

##例
>a+b

ではなく

>a%2Bb

というように記載することで解決しました。

##参考
https://github.com/postmanlabs/postman-app-support/issues/2664
MongoDB Atlasで無料で簡単にクラスタ化する

# なぜやったのか

NoSQLで大量の読み書きを安く済ませたかった。

Firestoreを使いたかったのですが、読み書きなどによる従量課金制なので

月額課金制であるMongoDB Atlas（以下、Atlas）を使うことにしました。

# 対象となる人

- MongoDBでクラスタを構築したい

# やること

- MongoDBクラスタ構築
- Atlasでデータベース作成
- Atlasでコレクション作成

# やらないこと

- Atlasの権限管理関連
- セキュリティ関連

# MongoDB Atlasって何者？

MongoDB社が提供しているDBaaS（Database as a Service）です。

クラウド上で、DB管理やユーザーの権限を管理でき、

本来、敷居が高いと言われるクラスタ構築も簡単に行えます。

プランによっては **無料**で管理できます！！

# アカウント作成

<img width="1680" alt="スクリーンショット 2019-08-09 18.31.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/e5c8a118-8540-9e5b-394e-245624680858.png">


https://cloud.mongodb.com/user#/login/register/accountProfile



**はい、英語です。**

サイト内は日本語の対応がまだされておらず、苦手な方はGoogle翻訳を使うことになります。

入力を終え、登録するとさっそくプランを選択する画面に行きます。


<img width="1680" alt="スクリーンショット 2019-08-09 18.36.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/e4b1c7a3-b79e-bd66-40b7-e09e1e65d7e5.png">


クラウドサービスプロバイダはAWS, GCP, Azureから選択できます。

弊社ではGCPをメインで使っているので、GCPを選択しました。

**FREE TIER AVAILABLE** と書かれているリージョンは無料プランが選択出来るということです。




<img width="1680" alt="スクリーンショット 2019-08-09 18.45.24.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/d4c15128-0195-91f1-8a01-ec40aea8a52a.png">


ここではプランの選択ができます。

Mの後ろの数字が大きいほど最強です。



**注意事項としてM0, M2, M5 Tier では、使用できるメソッド・設定が制限されています。**

https://docs.atlas.mongodb.com/reference/free-shared-limitations/#operational-limitations

ここでは全て紹介致しませんが、集計メソッド[Aggregation](https://docs.mongodb.com/manual/aggregation)などが使えません。



**Additional Settings** ではバックアップの設定や、DBのバージョン指定ができます。


右下の**Create Cluster**をクリックすると、早速クラスタが作成され、管理画面に飛びます。



# データベース接続

<img width="1680" alt="スクリーンショット 2019-08-09 18.56.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/92e0268d-3e2b-2e5b-39c3-c9d91dac7ef3.png">

管理画面のCONNECTをクリックすると行けますが、初回だと設定があります。

<img width="699" alt="スクリーンショット 2019-08-09 18.56.34.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/c79ea7c1-4ab9-1dbd-a66e-3292c4c24858.png">


AtlasではDBへのアクセスをホワイトリスト制で制限しています。

ここでは自分のIPアドレスを追加しておきましょう。

ユーザーの作成もここで行います。最初に作成するユーザーは管理者権限を持っています。


<img width="700" alt="スクリーンショット 2019-08-09 18.59.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/929166a3-cb63-79cc-1146-24d6cad1b191.png">


次へ進むと、DBへの接続方法の案内を見ることができます。

シェルでアクセスする方は**Connect with the Mongo Shell**。

アプリからアクセスする方は**Connect Your Application**。

MongoDB Compassからアクセスする方は**Connect with MongoDB Compass**。





# データベース&コレクション作成

<img width="1680" alt="スクリーンショット 2019-08-09 19.04.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/ed78abc7-4fa0-2da3-778e-bfc3a251d175.png">


用意されているデータセットを読み込ませるか、１から作成する方法が御座いますが

今回は後者をやってみます。

<img width="423" alt="スクリーンショット 2019-08-09 19.06.06.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/410115/eb322830-7833-1157-6f60-1b52afe3426f.png">


データベース名とコレクション名を入力します。Createを押すと作成。

簡単ですね！！！



あとはブラウザ上からデータを操作したり、シェル、アプリから操作することもできます。

# まとめ

数回のクリックでDBを構築できたりと非常に便利ですね。

今回は取り上げてませんが、プランによってはシャードクラスタも構築することができます。
Laravel+SPA+JTWAuthで認証ありの投稿アプリをつくる ~パート4~

# はじめに
「Laravel+SPA+JTWAuthで認証ありの投稿アプリをつくる」シリーズでユーザー情報を変更する仕組みを実装したので紹介します。

# 前提
Laravel5.5
Vagrant環境
認証はJTWAuth使用
SPAはVue、Vue Router

前回のパート１、２、3の続き
パート1　https://qiita.com/ProgramingDai/items/403ee4fbc0971827f160
パート２　https://qiita.com/ProgramingDai/items/dd14e02b804be1ed5516
パート3
https://qiita.com/ProgramingDai/items/1bd3b21fe97b15d152a0#_reference-94a2c9d5b26f4d09adc8

# 今回作るもの
ユーザー情報変更をSPAで実装

1.User.vue丸ごと書き換え

```php:resources/asset/js/components/pages/User.vue
<template>
    <div class="container">
        <div v-if="!editFlg">
            ID: {{ user.id }}<br />
            ユーザー名: {{ user.name }}<br />
            メール: {{ user.email }}<br />
            登録日: {{ user.created_at }}<br />
            更新日: {{ user.updated_at }}
        </div>

        <form v-else>
            <input type="text" name="name" v-model="user.name">
            <input type="email" name="email" v-model="user.email">
        </form>
        <button v-if="!editFlg" @click="(editFlg = true)">編集</button>
        <button v-else @click="onUpdate">更新</button>

    </div>
</template>

<script>
    export default {
        data: function() {
            return {
                isError: false,
                user: {},
                editFlg: false,
                updated: false
            }
        },
        created() {
            axios.get('/api/me').then(res => {
                this.user = res.data;
            }).catch(error => {
                this.isError = true;
            });
        },
        methods: {
             onUpdate: function() {
                 axios.put('/api/users/' + this.user.id, {
                     name: this.user.name,
                     email: this.user.email,
                 })
                 .then( (res) => {
                     this.editFlg = false;
                     this.updated = true;
                     console.log('update')
                 }).catch(error => {
                     this.isError = true;
                 });
             }
         },
    }
</script>
```

ただしこのまま変更するとパスワードが空文字になってしまうため
UserContorollerを一部変更する必要があります。

2.UserContoroller一部修正

```php:app/Http/Controllers/UserController
// 中略

    // 更新
    public function update(Request $request, User $user) {
        $user->name = $request->input('name');
        $user->email = $request->input('email');

        // 追加 パスワードリクエストがあったら更新（なければ何もしない）
        if($request->input('password')) {
            $user->password = bcrypt($request->input('password'));
        }

        $user->save();
    }

// 中略
```

こちらでこちらでパスワードが意図なく書き換わることは防げるかと思います。
CentOSでLDAPサーバの初期設定 

# はじめに

LDAPサーバをインストールしベースDNとあらかじめ用意しておいたスキーマファイルを取り込んで起動するところまでを記載


# OpenLDAP のインストール
面倒なので一切合切インストールしておく

```sh

# yum -y install openldap*
```

# 設定ツリーの管理
まず、設定ツリーにログインしないと始まらないので、設定ツリーの管理ユーザを設定する。

以下のLDIFファイルを用意。「パスワード」のところは適当なパスワードを設定する。

```sh
# cat add_config_rootdn_rootpw.ldif
dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootDN
olcRootDN: cn=config

dn: olcDatabase={0}config,cn=config
changetype: modify
add: olcRootPw
olcRootPW: パスワード
```

作成したLDIFファイルを以下のコマンドで実行して設定を更新する。

```sh
# ldapadd -Y EXTERNAL -H ldapi:// -f ./add_config_rootdn_rootpw.ldif
```

これで、「cn=config」の設定画面にログインができる。

# 自作したスキーマファイルの取り込み
自作したスキーマを取り込むには、まず「/etc/openldap/schema」ディレクトリにスキーマファイルを置く必要がある。
（どこでもいいのだけど、スキーマファイルを指定するときにデフォルトと同じところにしている）

そして、 slaptest コマンドを実行して LDIF 形式に変換して、そのファイルを OpenLDAP のスキーマファイルを読み込むディレクトリにコピーする必要がある。


## スキーマファイル一覧
変換したいスキーマファイル

```sh
# cat schema_convert.conf
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/collective.schema
include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/duaconf.schema
include /etc/openldap/schema/dyngroup.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/java.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema
include /etc/openldap/schema/personalSchema0001.schema
include /etc/openldap/schema/personalSchema0002.schema
include /etc/openldap/schema/personalSchema0003.schema

```

## 自作のスキーマを変換してコピーするスクリプト（サンプル）
自作のスキーマを変換してcn=schema のフォルダにコピーするスクリプトのサンプル。


```sh
# cat schema_change.sh
#clean up tmpdir
rm  -rf `pwd`/ldif_output/*

#change schema file to conf
slaptest -f schema_convert.conf -F `pwd`/ldif_output

#slapd stop
#/etc/init.d/slapd stop
systemctl stop slapd

# copy schema conf and set config file
mv /etc/openldap/slapd.d/cn\=config/cn\=schema /etc/openldap/slapd.d/cn\=config/cn\=schema.`date +"%Y%m%d%H%M"`

cp -fr `pwd`/ldif_output/cn\=config/cn\=schema /etc/openldap/slapd.d/cn\=config/cn\=schema

chown -R ldap:ldap /etc/openldap

#slapd start
# /etc/init.d/slapd start
systemctl start slapd
```


# 管理者用アカウントの設定とベースDNの設定
管理者用のアカウント名とパスワードと、ベースDNの設定が必要。

以下の管理者用のアカウント名とパスワードと、ベースDNの設定したLDIFファイルを作成する。

```sh
# cat add_rootdn_rootpw.ldif
dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcSuffix
olcSuffix: o=sample

dn: olcDatabase={2}hdb,cn=config
changetype: modify
replace: olcRootDN
olcRootDN: cn=Manager,o=sample

dn: olcDatabase={2}hdb,cn=config
changetype: modify
add: olcRootPW
olcRootPW: パスワード
```

上記で作成したLDIFファイルを利用し、以下のコマンドでエントリを更新。

```sh
#ldapadd -Y EXTERNAL -H ldapi:// -f add_rootdn_rootpw.ldif
```

# ベースDNの作成

ベースDN用のLDIFファイルを用意する。

```sh
 cat create_basedn.ldif
dn: o=sample
objectClass: top
objectclass: organization
o: sample
```

上記で作成したLDIFファイルを以下のコマンドを実行しベースDNのエントリを追加する。

```sh
#ldapadd -x -w password -D 'cn=Manager,o=sample' -f create_basedn.ldif
```

これで、ベースDNが作成されて利用できるようになる。
WSLで最新バージョンのGo環境構築

# tl;dr
- Windows Subsystem for Linuxにてapt経由でGoをインストールすると `1.10` が最新としてインストールされて困った
    - (現時点でのGoの最新バージョンは`1.12`  (2019年8月現在))
- Goenvを導入することで最新版をインストール

## 環境
- Windows Subsystem for Linux (Ubuntu 18.04)

## apt経由でGoをインストール
`$ apt-get install golang`

ちなみにバージョン指定する事も可能
`$ apt-get install golang-1.xx`
尚、`1.12` を指定してみると下記メッセージが出力される

```
E: Unable to locate package golang-1.12
E: Couldn't find any package by glob 'golang-1.12'
E: Couldn't find any package by regex 'golang-1.12'
```

## Goenv
### Goenvについて
- Goのバージョン管理ツール
- プロジェクト管理でバージョンを変えたりできるので便利。
- 他の言語の`XXXenv`も存在する。 ex.) `Pyenv` `Rbenv` などなど

### 導入手順
- インストール　　
`$ git clone https://github.com/syndbg/goenv.git ~/.goenv`  　　
or
URL:   https://github.com/syndbg/goenv  

- 環境変数を追加する  　
下記を `.bash_profile`などに下記を追加する

```sh:~/.bash_profile
export GOENV_ROOT=$HOME/.goenv
export PATH=$GOENV_ROOT/bin:$PATH
eval "$(goenv init -)"
```
- 変更を反映させる  
`$ source ~/.bash_profile`

### Goenv経由でGoをインストールする
- インストール可能バージョンを確認する  
`$ goenv install -l`

```
1.2.2
.
.
1.12.9
1.13beta1
```

- 今回は `1.12` をインストールします。  　　
`$ goenv install 1.12.9`

- インストール済バージョンを確認する  　
`$ goenv versions`

```
* 1.12.9 (set by /path/to/.goenv/version)
```

- Goの任意のバージョンを設定する 　 
`$ goenv global 1.12.9`


- バージョンの確認してみる　　
`$ go version`

```
go version go1.12.9 linux/amd64
```
無事に最新版になっています。

## おまけ
- Proxy環境下でのGoenv経由のGoインストール  　
`$ https_proxy=http://proxy.example.com:PORT goenv install 1.12.9`

- 任意のプロジェクトのみバージョンを変更する  　
`$ goenv local 1.x.x`

- `goenv global` したのにバージョンが変わらない！　　
`$ goenv rehash`

#### 参考
[Ubuntuにapt-getで最新のGolangをインストールする方法](https://qiita.com/DQNEO/items/1d6b54845d56ba90809f)
[goenvでgoをインストール 〜初心者向け〜](https://qiita.com/yut-kt/items/9f5ac1e788df61f64290)
BitDPについて

ある条件を満たす順列の数え上げに関して、n!では間に合わないけど2\*\*nなら間に合いそうという時に使えるテクニックです。
全要素の集合をU、その部分集合をSとしてSに関して条件を満たす並び方の総数をf(S)とします。右（左）端に何を置くかで場合分けを行うと、要素数のひとつ少ないSの部分集合S'の話に帰着するので、帰納的に解くことができます。さらに、dpを効率よく行う方法として、集合をbitで管理するという発想があります。つまり、0110={1, 2}のように対応づけをすると、集合に整数でラベルを貼ることができます。このラベルをn(S)で表すことにすると、S⊇S'ならばn(S)≧n(S')が成立するので、nの小さい方から順に求めていくことで簡単に実装できます。

例題:[ABC041D](https://abc041.contest.atcoder.jp/tasks/abc041_d)

```python
def main():
    N, M = map(int, input().split())
    edge = [0]*N
    for i in range(M):
        x, y = map(int, input().split())
        edge[x-1]|=1<<(y-1)
    dp = [0]*(1<<N)
    dp[0] = 1
    for s in range(1, 1<<N):#集合を添字の小さい順に試す
        for i in range(N):#全ての要素を考える
            if ((s>>i)&1) and (not(edge[i]&s)):#i in sかつedge[i]とsが共通部分を持たない
                dp[s]+=dp[s^(1<<i)]
    return dp[-1]
print(main())    

```
（関係ないですがmain()に埋め込むと100msくらい速くなりました。すごい。）

もう一つの[例題](https://atcoder.jp/contests/dwacon2018-prelims/tasks/dwacon2018_prelims_d)です。

```python
N = int(input())
x = list(map(int, input().split()))
a = list(map(int, input().split()))
edges = [0]*N
cost = [0]*N
for i, ai in enumerate(a):
    edges[ai-1]+=1<<(i+1)
    cost[ai-1]+=x[i+1]
disk = [0]*(1<<N)
dp = [float('inf')]*(1<<N)
dp[0] = 0
for s in range(1<<N):
    for i in range(N):
        if not s & (1 << i) and s & edges[i] == edges[i]:
            nextS = s| (1 << i)
            disk[nextS] = disk[s] + x[i]
            dp[nextS] = min(dp[nextS], max(dp[s], disk[nextS]))
            disk[nextS] -= cost[i]
print(dp[-1])
```
実はこれ、はじめは貰うDPで書いていたのですが、謎のWAが取れずにかなり時間を溶かしました。結論から言うと、貰うDPで書くと起こりえない場合に関しても考えてしまうため、diskの値に不都合が起こることがわかりました。配るDPの形で書くと、すでに起こりうるとわかっている状態からの遷移のみを考えられるので、そのような不都合がなくなるわけです。

上では色々なbit演算を用いています。いい機会なので、bit演算についてまとめておきます。
｜: orのこと。
&: andのこと。
^: xorのこと。実質、繰り上がりのない引き算、足し算
<<: 左シフト。右に0をn個付け加える
\>>: 右シフト。右からn桁を削除する
よく使うのは以下のような奴らです。
1<\<N: 2**Nのこと
n>>k&1: nのk+1桁目が1かどうか(0-indexedなら右からk番目)
S&T: 集合の積
Python機械学習プログラミングという書籍で間違いを指摘したが認められなかった話

# はじめに
[第2版]Python機械学習プログラミングの89ページで間違いと思われる箇所を見つけましたが，認められなかったのでここに書きます．

技術に関する内容ではなく，どちらかといえば日本語に関する内容です．

(追記)間違いではありませんでした．

# 本文
間違いだと思われる箇所を引用します．(間違いだと思われる箇所は太字にしてあります)

決定木学習の情報利得の文脈でエントロピーに関する話です．

> $p(i \mid t)$ は，特定のノード $t$ においてクラス $i$ に属するサンプルの割合を表す．したがって，ノードのサンプルがすべて同じクラスに属している場合，エントロピーは0である．たとえば二値分類においてエントロピーが0になるのは，$p(i=1 \mid t)=1$ または $\mathbf{p(i=0 \mid t)=0}$ の場合である．エントロピーが最大になるのは，各クラスが一様に分布している場合である．二値分類でエントロピーが1になるのは，クラスが$p(i=1 \mid t)=0.5$ および $p(i=0 \mid t)=0.5$で一様に分布している場合である．

間違っていると思った理由を説明します．

二値分類において，エントロピーが0になる場合は2通りあります．

- $p(i=1 \mid t)=1$ および $p(i=0 \mid t)=0$
- $p(i=1 \mid t)=0$ および $p(i=0 \mid t)=1$

二値分類において，エントロピーが1になる場合は1通りあります．

- $p(i=1 \mid t)=0.5$ および $p(i=0 \mid t)=0.5$

以上のことを踏まえると，著者は「 $p(i=1 \mid t)=1$ および $p(i=0 \mid t)=0$ または $p(i=1 \mid t)=0$ および $p(i=0 \mid t)=1$ 」を省略して，「 $p(i=1 \mid t)=1$ または $p(i=1\mid t)=0$ 」と書きたかったのではないかと思いました．

ですので，この文章の，$p(i=0 \mid t)=0$ は $p(i=1 \mid t)=0$ の間違いだとサポートにメールを送ったのですが，認められませんでした．

返信メールの回答部分を抜粋します．


> p.89におきまして、式3.6.3下の本文に下記の記述があります。
> \------------------
> したがって、ノードのサンプルがすべて同じクラスに属している場合、エントロピーは 0 である。たとえば二値分類においてエントロピーが 0になるのは、p( i = 1 | t ) = 1 または p( i = 0 | t ) = 0 の場合である。
> \------------------
> 「たとえば」からはじまる上の2文目では、「エントロピーが 0 になる」ケースを取り上げたものかと思います。監注35でも「p( i =1 | t)=1 のときは p( i =0 | t)=0 となり」と記載しており、これは上の2文目と同じケースであると考えられます。
また、監注35では、別のケースとして「p( i =1 | t)=0 のときは p( i =0 | t)=1となり」も取り上げています。

最初に引用した部分にあるように，回答の引用文の前文でエントロピーが0になるという話をしているのだから，この「たとえば」は明らかに「二値分類」にかかっています．ですのでこの回答に納得がいかず，再度問い合わせをしたのですが，返信はありませんでした．

# 最後に
私の理解が間違ってるなどありましたらコメント欄におねがいします．精進いたします．

# 追記
コメント欄で第1版の原著をのせていただいて，怪しいですが納得がいったので追記します．

$p(i=1 \mid t)=1$ または $p(i=0 \mid t)=0$ と$p(i=1 \mid t)=0.5$ および $p(i=0 \mid t)=0.5$ どちらも同じ式を言い換えただけなのになぜ「または」，「および」と別の接続詞を使用しているのか．

原著だとそれぞれ「or」と「and」を使用しているので，論理で考えた時に，A or B とA and B はAとBが等しい時にどちらも同じ値を出力します．(ベン図でイメージしたほうがわかりやすいかもしれません)

| A | B | A or B | A and B |
|:----------------:|:-----------------:|:------------------:|:------------------:|
| 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 1 |

つまりAとBが同値関係にあるなら，「AまたはB」でも「AおよびB」でもどちらでも良い．

しかし論理と言葉は違うものだから，納得のいっていない部分もあります．

# 追記2
回答メールが1ヶ月後に返ってきたので追記

回答部分を抜粋して引用

> 該当箇所の原文は、次のように記載されており、
> 原文どおりに翻訳しています。

>（原著　p.91）
For example, in a binary class setting, the entropy is 0 if  p(i=1|t)
=1 or  p(i=0|t) =0. If the classes are distributed uniformly with
p(i=1|t) =0.5 and p(i=0|t) =0.5, the entropy is 1.

>原文の意図を読み取るとすると、p(i=1|t)=1またはp(i=0|t)=0では、1と0が異なる値なのでor、
p(t=1|t)=0.5およびp(i=0|t)=0.5では、0.5と0.5が同じ値なのでandを使ったように見えます。
それ以上の意図は読み取れませんでした。

英語の成績は良くないので自信を持って言えないのですが，andとorは形式的な使い分けをする単語ではないと思います．

そんな意図を込めたとは思えません．

ですのでこれにも納得がいきません．
Cloud Flare + redash + nginx でSSL



## 詰まったところ
- Cloud FlareのSSLを使いたかったが、証明書がうまく発行されなかったり、発行後もつながらなかったりした



## 結論

[redashが出している設定](https://gist.github.com/arikfr/64c9ff8d2f2b703d4e44fe9e45a7730e)が終わるまでは、
CloudFlareのSSLをFlexibleにしておく。上記の設定が完了したら、CloudFlareのSSLをFullにする



## エラー

### 証明書が発行できない

```
Failed authorization procedure. redash.example.com (http-01): urn:ietf:params:acme:error:unauthorized :: The client lacks sufficient authorization :: Invalid response from https://redash.example.com/.well-known/acme-challenge/B-WnlXtxwEtOrNW5fZXch5NlCCVdfCX9MMKokeuOscM [2606:4700:30::681b:ae50]: "<!DOCTYPE html>\n<!--[if lt IE 7]> <html class=\"no-js ie6 oldie\" lang=\"en-US\"> <![endif]-->\n<!--[if IE 7]>    <html class=\"no-js "

IMPORTANT NOTES:
 - The following errors were reported by the server:

   Domain: redash.example.com
   Type:   unauthorized
   Detail: Invalid response from
   https://redash.example.com/.well-known/acme-challenge/B-WnlXtxwEtOrNW5fZXch5NlCCVdfCX9MMKokeuOscM
   [2606:4700:30::681b:ae50]: "<!DOCTYPE html>\n<!--[if lt IE 7]>
   <html class=\"no-js ie6 oldie\" lang=\"en-US\">
   <![endif]-->\n<!--[if IE 7]>    <html class=\"no-js "

   To fix these errors, please make sure that your domain name was
   entered correctly and the DNS A/AAAA record(s) for that domain
   contain(s) the right IP address.

```

早まって、CloudFlareのSSLをFullにしてしまった可能性あり。

### 

設定は無事終わったが、httpsでアクセスできない。

```
letsencrypt SSL: error:14094416:SSL routines:ssl3_read_bytes:sslv3 alert certificate unknown:SSL alert number 46
```


CloudFlareのSSLをFlexibleにしたまま可能性あり。
CSVで読んだものをSQLiteに入れて、クエリを書かずに扱う。


CSVで定期的に更新されるデータを読んで集計する時など、
都度都度過去のCSVを読み込んでやるのって面倒だし、どんどん読み込みサイズが大きくなるなあと思って、
DBに入れてしまっていたらいいのでは？と思って、調べてみたら思いのほか、簡単そうだったのでメモメモ



# SQLiteにつなぐ
```R
# インストールしてから
# ライブラリの読み込み
library("tidyverse")
library("RSQLite")

# SQLite に接続する
con = dbConnect(SQLite(), "test.db", synchronous="off")
```
作業ディレクトリの配下に "test.db" ができる。すでにファイルが存在する時はそのファイルにつなぐ。
ファイル名を ":memory:" にすると、メモリ上に作るとかなんとからしい。

# CSVを読み込んで、それをSQLに投げ込む。


```R
# CSVを読み込む
# 適当なサンプルデータ①
input_file = "https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031849356&fileKind=1"
read_data <- read_csv(input_file, locale=locale(encoding="CP932"))

# データフレームをDBに投入する
con %>% dbWriteTable("seika", read_data, row.names=F)
```

同じ形式のデータをテーブルに追加する時は、`append=T` とすれば、よいみたい。

```R
# CSVを読み込む
# 適当なサンプルデータ②
input_file = "https://www.e-stat.go.jp/stat-search/file-download?statInfId=000031849386&fileKind=1"
read_data <- read_csv(input_file, locale=locale(encoding="CP932"))
# データフレームをDBに投入する
con %>% dbWriteTable("seika", read_data, row.names=F,append=TRUE)
```

# 入れたテーブルのデータを使う
本懐はこれ。SQLを書かなくてdplyr的な操作ができる。知らなかった。
データフレームをパイプでつなぐ代わりに、接続→テーブル選択として、
それ以降はdplyr的に操作して、最後に collect() で取得

```R
# dplyr 的な操作で抜く
tmp <- con %>% tbl("seika") %>%   # 接続→テーブル名 という感じで指定
filter(品目名 == "だいこん") %>%
arrange(日) %>%
collect()   # ここでクエリ投げて、データ取得
```
複雑なことはできるかは調べていないけど、
どんなSQLが生成されるかは、最後を show_query() にすればOK

```R
# dplyr 的な操作で抜く
tmp <- con %>% tbl("seika") %>%   # 接続→テーブル名 という感じで指定
filter(品目名 == "だいこん") %>%
arrange(日) %>%
show_query() # どんなSQL投げているかを返してくれる

# == 実行結果 ==
# <SQL>
# SELECT *
# FROM `seika`
# WHERE (`品目名` = 'だいこん')
# ORDER BY `日`
```

どこまでをSQLでどこまでをRでやるかという部分にはなるけど、可読できるSQLを吐くあたりが、線引きラインかな？と思ったり。
絞り込んでデータ抜いてくるまでやって、そこから先はRでとか？
とはいえ、SQLを書かなくてもいいのは、DB苦手な人には精神衛生上かなり嬉しい。

# そのほか

きちんとクエリを書くなら

```R
# クエリ書いて条件絞って抜くならこれ
tmp <- con %>% dbGetQuery( "SELECT * FROM seika" )

# フェッチで投げる
rs <- con %>% dbSendQuery( "SELECT * FROM seika" )
tmp <- rs %>% dbFetch()
rs %>% dbClearResult()
```

# さいご
最後はDBから切断。

```R
con %>% dbDisconnect()
```
<span>とは

<span> 自身は特に何の意味も持たないタグです。<span>～</span> で囲まれた部分にスタイルシートを適用したりするのに用いられます。

同様なタグに <div> があります。<div> はブロック要素(前後に改行がはいる)の汎用的なタグとして、<span> はインライン要素(前後に改行が入らない)の汎用的なタグとして使用されます。
[Ruby] 👨‍👩‍👧‍👦 を 1 文字とみなす方法

# 2024/11/12 (火) 追記

👨‍👩‍👧‍👦 という絵文字はこの記事を投稿した時点では

<img width="160" alt="以前の家族" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6697/f0d311e9-4182-d927-6993-3e094bf8aeec.png">

と表示されていました。しかし 2024/11/12 (火) 時点では私の macOS (15.0.1) の Chrome では

<img width="160" alt="今の家族" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6697/2cc96dde-b9d0-e702-7e23-1be03d3be3d6.png">

と表示されます。これは iOS 17.4 のリリース時に以下の変更が行われたためのようです。


- [The Family Emojis Are Now Equally Useless For Everyone](https://www.mobiletechjournal.com/the-family-emojis-are-now-equally-useless-for-everyone/)

# 方法

書記素クラスタ (grapheme cluster) の単位で数える。そうすると、僕らが自然だと思う単位で文字を数えることができる。

## Ruby での方法

* String#scan で `\X` を指定する。`\X` は Unicode 結合文字シーケンスを表す。
* [String#grapheme_clusters](https://docs.ruby-lang.org/ja/latest/class/String.html#I_GRAPHEME_CLUSTERS) や [String#each_grapheme_cluster](https://docs.ruby-lang.org/ja/latest/method/String/i/each_grapheme_cluster.html) を使う。

### 数える


```rb
'👨‍👩‍👧‍👦'.length
#=> 7

'👨‍👩‍👧‍👦'.scan(/\X/).length
#=> 1

# String#each_grapheme_cluster と Enumerable#count を使うと
# 途中で Array オブジェクトを生成せずに文字を数えることができる。
'👨‍👩‍👧‍👦'.each_grapheme_cluster.count
#=> 1
```

### ループする

```rb
'👨‍👩‍👧‍👦'.chars
#=> ["👨", "‍", "👩", "‍", "👧", "‍", "👦"]

'👨‍👩‍👧‍👦'.grapheme_clusters
#=> ["👨‍👩‍👧‍👦"]

'👨‍👩‍👧‍👦'.each_char { |chr| puts('U+%04X' % chr.ord) }
# U+1F468
# U+200D
# U+1F469
# U+200D
# U+1F467
# U+200D
# U+1F466

'👨‍👩‍👧‍👦'.each_grapheme_cluster { |chr| puts('U+%04X' % chr.ord) }
# U+1F468
```

# 参考

* [Unicodeのgrapheme cluster (書記素クラスタ) ](https://hydrocul.github.io/wiki/blog/2015/1025-unicode-grapheme-clusters.html)
* [Unicode 絵文字にまつわるあれこれ (絵文字の標準とプログラム上でのハンドリング)](https://qiita.com/_sobataro/items/47989ee4b573e0c2adfc)
* [家族👨‍👩‍👦‍👦はreplaceされてしまうのか？あるいはZWJの話😂](https://qiita.com/todokr/items/8b813e14d3fdb4111cb7)
TexturePackerツールのよく使う用語集

TexturePackerはスプライトシートを作成するためのツールです。TexturePackerを使う時には、色々なオプションがありまして、オプションの意味が分からない場合はどの選択肢を選ぼうかかなり難しいでしょうか？本書では、TexturePackerのよく使う用語について解釈してみたいと思います。各用語の基本意味が分かっていればTexturePackerツールのお使いにお手伝いできましょう。
#Output関連用語
TexturePackerはエクスポートを行う際、ファイルを２種類吐き出します。一つは生成されたテキスチャ（画像）で、もう一つがデータファイルです。
このデータファイルは先ほど指定したフォーマットに沿って出力されます。データファイルの中身は主に画像の名称やそれの座標、大きさ等と言ったデータです。
![settings_output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/ac77b619-6072-5786-04ac-cac1c031d9fe.png)
##Data Format
出力するデータのフォーマットを指定します。プルダウンから表示されるリストを見ればわかるかと思いますが各種フレームワーク用の出力フォーマットが用意されています。
##Data File
データファイルの出力先です。
##Texture Format
出力されるテキスチャのファイルフォーマットを指定します。pngを初め、様々なフォーマットがサポートされています。
##Texture File
テキスチャの出力先です。
##Image Format
出力されるテキスチャの 画像フォーマットを指定します。これもまた様々な画像フォーマットがサポートされていますが、主に使用するのは以下の３つかと思います。

- RGBA4444
- RGBA8888
- RGB565

どのフォーマットも一長一短ですが、筆者は基本的にはRGBA4444を使用しています。RGBA8888に比べれば画質は落ちますが、正直そこまで変わりません。TexturePacker上では結構わかりやすく変化しますが、iPhone上では特に気になりません。ちなみに通常デフォルトで読み込まれる画像はRGBA8888です。RGBA8888からRGBA4444にするだけで画像の容量が半分に抑えられるというメリットがあります。ゲーム等、画像や音を大量に使うアプリを作る際、容量を抑えるにはかなり有用な手段です。
RGB565はα値を使わない背景などに使ったりすることがありますが、費用対効果的に基本的には全部RGBA4444で統一して出力しています。
##AutoSD
AutoSDはRetina用と非Retina用のスプライトシートを吐き出すために使う設定です。今ではiPhone3G/Sに対応することはあまり無いかもしれませんが、もし対応したい場合はこのAutoSDを使えば容易にできます。
#Geometry(幾何)関連用語
![dragdrop_result.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229009/c9882b5a-887e-bcdf-4ab1-f22e2c02002c.png)

Geometryの設定項目ですが、出力するテキスチャの形を設定して行きます。設定項目の名称通りの物が多いので簡単に説明していきます。
各項目を説明する前にまずそもそも何故スプライトシートというものに画像を落とし込むのかということを説明したいと思います（Geometryで設定する項目に関係してくるため）。スプライトシート化することのメリットはまず画像ファイル自体の容量を小さくするということもあるのですが、もうひとつ大きな理由としてはOpenGLの仕様にあります。GPU内に画像をロードする際、画像は必ずPOT（２のべき乗、Power of Two）のサイズでロードされます。仮に33×33の画像があったとしても、それはGPUのメモリ上では64×64でロードされます。これはメモリの無駄遣いとなってしまうため、スプライトシートを用いて、なるべくたくさんの画像を２のべき乗内に納めようという思惑があります（もちろん他にもメリットはありますがここでは割愛させていただきます）。
##Max size
Max sizeはテキスチャ自体の最大サイズです。ここで指定したサイズを越えてしまう量（大きさ）の画像を取り込むと、右下にエラーが表示され、はみ出た画像は出力されません。端末によって読み込める最大のテキスチャサイズが決まっていたりするので、チェックしてサイズを決めましょう。iPhone4以降の端末でしたら2048×2048をサポートしているので2048×2048に設定しておいて問題ないでしょう。
##Fixed size
Fixed sizeは特定のサイズに必ずしたい場合に設定します。例えばどんな画像を入れても512×512にしたい場合はFixed sizeを512×512に指定しておきます。この場合64×64の画像一枚だけいれた場合でも512×512のテキスチャとして出力されます。
##Size constraints
Size constraintsではサイズの制限を指定できます。POTに指定すると必ず２のべき乗のサイズで出力されます。Any Sizeに指定すると画像が収まるぴったりのサイズで出力されます。NPOTに指定するとPOTでないサイズつまりAny SizeからPOTを除外したものが出力されます。フレームワークや端末によっていはPOTのものしかサポートしない場合もあります。
##Force squared
Force squaredをオンにすると必ず四角形のテキスチャが出力されます。
##Force word aligned
Force word alignedはテキスチャの各列が必ずメモリ上のワードをフルに使う様指定します。３２ビットの画像フォーマット（RGBA8888等）を使用している場合は既にword alignedですが、１６ビットの画像フォーマットを使うとそうとは限りません。つまり１６ビット余ることがあるということです。それを必ず余った分の１６ビットも使う様に設定するということです。iPhoneの場合はこれはオンにしておきます。
##Pack
Packはテキスチャをもっとも小さくするために画像の配置を決めるためのアルゴリズムを指定します。Bestで問題ないかと思います。
##Scale
Scaleはその名の通り、画像をスケールします。つまり出力される画像を指定した倍数でかけたサイズで出力します。特に理由が無い限り１で良いですが、Androidなどで利用する場合は重宝するかもしれません。
##Scale mode
Scale modeは画像をスケールする際に使用するアルゴリズムを指定します。基本的にこちらはSmoothで良いかと思います。画像を縮小する際は間違いなくSmoothが一番良いです。
docker上のmysqlのデータバックアップ

# バックアップ

```bash
docker exec {container_name} /usr/bin/mysqldump -uroot -ppassword {database_name} > backup.sql
```

# 復元

```bash
cat backup.sql | docker exec -i {container_name} /usr/bin/mysql -uroot -ppassword {database_name}
```
C++ Builder 10.2 Tokyo > IDE > bug > ブレークしない

```txt:動作環境
RAD Studio 10.2 Tokyo Update 3 
Windows 10 v1903 
```

### ブレークしない

```cpp
void __fastcall TForm1::Button1Click(TObject *Sender)
{
	int idx=0;

	for(idx=0; idx < 10; idx++) {
		if (idx < 2 || idx >= 8) {
			continue; // 0,1ではブレークせず、8,9ではブレークする
		}
        int nop=1;
    }
}
```

コメント記載の通り、0,1ではブレークしない。
8,9ではブレークする。

0,1でのcontinueそのものは有効であり、あとの処理には進まない。

この不具合により、デバッグ時に希望のものが見れない。

`continue;`一行ではなく、複数行の実装にするとブレークするようだ。


### XE4でも再現

Windows 7 + XE4でも再現する。
与えられた重みに従ってランダムに値を返す「Weighted Random Selection」をGoで実装する！

Goで 「Weighted Random Selection」 をしたくなる時があります。しかし、Goでは Pythonの ```numpy```のように便利な関数が提供されていないので自分で作るしかありません。今回は Go で 「Weighted Random Selection」 の実装方法を紹介します。

## Weighted Random Selection とは

とある重み(確率分布)を元に要素をランダムに選択するやつです。numpyで言うと ```numpy.random.choice``` に当たります。下記は第一引数 ５([0,1,2,3,4]) から3つを確率分布pでランダムに選択する関数です。

```python
>>> np.random.choice(5, 3, p=[0.1, 0, 0.3, 0.6, 0])
array([3, 3, 0])
```

ランダムな選択に重複を許可しない場合は引数に ```replace=False``` を指定します。

```python
>>> np.random.choice(5, 3, replace=False, p=[0.1, 0, 0.3, 0.6, 0])
array([2, 3, 0])
```

今回はGoでこの処理を行う際の実装を紹介します。

## Go による Weighted Random Selection

今回は最もシンプルな Linear Scan アルゴリズムで実装します。やることは[０~weightの合計値]の間でランダムに基準となる値を選び、基準からweightを順に引いていき、０以下になったらそれが選択されます。

<img width="500" alt="スクリーンショット 2019-08-19 17.41.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/186028/8ee51ac1-0368-0b9b-43ff-1d112763b3af.png">


早速実装していきます。下記はvの中からwの確率分布に従って1つだけ値を取得する関数です。

```go
// 0 ~ max までの範囲でランダムに値を返す
var randGenerator = func(max float64) float64 {
	rand.Seed(time.Now().UnixNano())
	r := rand.Float64() * max
	return r
}

func weightedChoiceOne(v int, w []float64) float64 {
	// v を slice　に変換
    // ex) 5 -> [0, 1, 2, 3, 4]
	vs := make([]int, 0, v)
	for i := 0; i < v; i++ {
		vs = append(vs, i)
	}

    // weightの合計値を計算
	var sum float64
	for _, v := range w {
		sum += v
	}

    // weightの合計から基準値をランダムに選ぶ
	r := randGenerator(sum)

    // weightを基準値から順に引いていき、0以下になったらそれを選ぶ
	for j, v := range vs {
		r -= w[j]
		if r < 0 {
			return v
		}
    }
    // should return error...
	return 0
}
```

最後の```return 0``` はたまたま１つも選ばれなかった(基準がweightの合計と丁度一致した時など)場合に到達します。確率的にほとんどありませんが、ここはこの関数を使う状況によってエラーハンドリングや空で返すなどの対策が考えられます。

上記のコードを少し変更すれば選ぶ数の指定 & 重複排除も実装できます。ポイントは選ばれた物をスライスから排除しておくことです。


```go
func weightedChoice(v, size int, w []float64) ([]float64, error) {
	// v を slice　に変換
    // ex) 5 -> [0, 1, 2, 3, 4]
	vs := make([]int, 0, v)
	for i := 0; i < v; i++ {
		vs = append(vs, i)
	}

    // weightの合計値を計算
	var sum float64
	for _, v := range w {
		sum += v
	}

	result := make([]float64, 0, size)
	for i := 0; i < size; i++ {
		r := randGenerator(sum)

		for j, v := range vs {
			r -= w[j]
			if r < 0 {
				result = append(result, float64(v))

                // weightの合計値から選ばれたアイテムのweightを引く
				sum -= w[j]

                // 選択されたアイテムと重みを排除
				w = append(w[:j], w[j+1:]...)
				vs = append(vs[:j], vs[j+1:]...)

				break
			}
		}
	}
	return result, nil
}

```

選択されたアイテムと重みの削除のコードが少し特殊に見えますが、下記の公式Wikiを参考に実装しています。
https://github.com/golang/go/wiki/SliceTricks#delete

これを使えば与えられたweightにしtがってランダムに値を返します。

```go
func main() {
	r1 := weightedChoiceOne(5, []float64{0.1, 0.1, 0.2, 0.9, 0.1})
	r2, _ := weightedChoice(5, 4, []float64{0.1, 0.9, 0.2, 0.3, 0.1})
	fmt.Println(r1) // 3
	fmt.Println(r2) // [1 3 2 0]
}
```

これで Weighted Random Selection が実装できました！ 今回は最もシンプルな Linear Scan での実装を紹介しましたが、そのほかのアルゴリズムはこのサイトが勉強になります。https://blog.bruce-hill.com/a-faster-weighted-random-choice

コードは Go Playground にあげておきます。
https://play.golang.org/p/-vqQEvwCi44