OmniAICreator/Qiita-1.07M huggingface dataset:
Bitbucket→GitHub 移行 その1～リポジトリ変換～

Bitbucket が Mercurial 形式のリポジトリをサポートしなくなるということで、愛用していた Mercurial から少し離れて GitHub に移行することにしました。

2020/6 にサポートが打ち切られるので、それまでに移行しないといけません。
必要なことですので、ササッとやっちゃいましょう。

----

複数回に分けて、Bitbucket にあったリポジトリをGitHub に移行した際の記録・注意点を残しておこうかと思います。

* リポジトリ変換 ←今ここ
* [x] [GitHub](https://qiita.com/chimatter/items/88fc40ecf4b0d3a345dd)
* [x] [CIまわり](https://qiita.com/chimatter/items/d77d509d1ec83e29b348)
* (ほかあるかな…？)

**今回はリポジトリ変換について触れます。**

**なお、履歴を移行しない場合は、今回の手順は不要です。**
ローカルリポジトリで `git init` ～ `git push` すればいいだけですので。
履歴を移行する（今回触れる リポジトリ変換を行う）かどうかを判断する材料の1つとしては、
今現在 複数のブランチに触っているかどうか、が挙げられます。
あとは、最近バグフィックスやリリースを行った場合も、安全策として履歴を移行したほうが良いかもしれません。

ちなみに、Windows 10 を使っています。
ただ、環境に依存する部分は少ないと思います。

# リポジトリ変換

Mercurial から Git に変換する際には、Git ドキュメントサイト（日本語版）に沿って作業します。
[Git へ移行する#Mercurial](https://git-scm.com/book/ja/v2/Git%E3%81%A8%E3%81%9D%E3%81%AE%E4%BB%96%E3%81%AE%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%AE%E9%80%A3%E6%90%BA-Git-%E3%81%B8%E7%A7%BB%E8%A1%8C%E3%81%99%E3%82%8B#_mercurial)

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

これを機に最新版の Git for Windows をインストールしました。

最近のバージョンでは、`git update-git-for-windows` を実行するとアップデートできるようです。
このサブコマンドが無い場合は、[サイトの方からダウンロードしましょう](https://gitforwindows.org/)。

インストーラーでは、いくつかオプションを提示されます。
好きに選んで良いでしょう。
今回は、以下のようにしました。(オプション名は省略しています)

* OpenSSL
* コマンドプロンプト利用
* Checkout as-is, Commit Unix-style(core.autocrlf=input)

## fast-export の実行環境を整える

### Python2

後の手順になりますが、hg-fast-export.sh で Python2 を要求されます。
仕方がないのでインストールします。
環境切り替え系ツールを入れるのは、かえって状況をややこしくしそうなので、やめました。素のインストーラーを使ってインストールします。

### pip で Mercurial

あとは、Python から Mercurial リポジトリを操作するためのパッケージもインストールします。

最初に pip をインストールして… pip (https://bootstrap.pypa.io/get-pip.py)
次に `pip install mercurial`

これで、ようやく fast-export 実行環境が整います。

## fast-export を取得

最初に fast-export を clone してきます。

```
git clone  http://repo.or.cz/r/fast-export.git   ./fast-export
```

## ディレクトリー構成

複数ある自分のローカルリポジトリと同じ場所に fast-export を置いています。

```
./
  fast-export/
    hg-fast-export.sh
    :
  my-repos1/
    .hg/
    :
  my-repos2/
    .hg/
    :
```

## 変換

各ローカルリポジトリ内でコマンド入力しています。

1. ローカル Mercurial リポジトリで `git init`
  * .hg と .git が混在する
2. `git config core.ignoreCase false`
  * この後の手順でエラーにならないようにするため。
3. `hg log | findstr ユーザ: > authors.txt` して、 "old name"="new name " の形式に加工する。
  * git として不正なコミットユーザーにならないように、ユーザーの変換テーブルを定義しています。
  * findstr は Windows コマンドですので、Unix ユーザーは grep にしてください。
4. `../hg-fast-export.sh -r . -A authors.txt`
  * インストールの仕方にもよると思いますが、Git Bash の方でないと .sh が処理できません。

## あとは、変換を繰り返す

手持ちのリポジトリに対して変換を繰り返していきます。

fast-export 自体は、コミットの数が 100 未満ぐらいなら、ほぼ一瞬で終わります。
どちらかというと、一連の手順を実行するのに手間取るくらいでしょうか。

古いリポジトリでは意外とユーザー名が統一されていないことがあります。
ユーザー名の変換テーブルがきちんと作成できていないと実行エラーが出ますので、注意してください。
最初に全リポジトリに対して findstr(or grep) かけて、変換テーブルを作成しておくと良いと思います。

そうすれば、手作業で行うことがほぼ無くなりますので、スクリプト化しやすいと思います。

## GitHub にプッシュ

先に GitHub 上にリポジトリを作っておきます。
あとは、そこに向けて `git remote add origin git@github.com:USER/REPOS.git` して `git push remote origin` すればよいです。

SSH 周りの設定が必要ですが、このあたりは次回触れると思います。
ですが、この部分もできているということであれば、一連の移行作業はほぼ終わったことになります。
お疲れさまでした。
C++でa == 1 && a == 2 && a == 3をtrueにしてみたい（クソ解法）

## 先駆者
https://qiita.com/yumetodo/items/bbeed7258cd22fd8bb7c
https://qiita.com/fujitanozomu/items/e4ab6f20837ed8234cd3
https://qiita.com/shiozaki/items/fe3ee5a4775e5ca19f20

## 動機
https://qiita.com/fujitanozomu/items/e4ab6f20837ed8234cd3#comment-9ec3137b3bd475eed044
このコメントを見てて思いついた

「未定義動作でもできる？じゃん？」

しかし乗るネタが古いな？

## よい子はマネしないでね

https://wandbox.org/permlink/0DFvs7ts7HGqYjMq

```c++
#include <iostream>

int func(volatile int a) {
    if (a == 1 && a == 2 && a == 3) {
        return 42;
    } else {
        return a/0;
    }
}

bool func2(int x) {
    return func(x) == 42;
}

int main()
{
    std::cout << std::boolalpha;
    std::cout << func2(0) << std::endl;
    std::cout << func2(1) << std::endl;
    std::cout << func2(2) << std::endl;
    std::cout << func2(3) << std::endl;
}
```

結果

```
true
true
true
true
```

## バイナリ

https://godbolt.org/z/cXa6mP

一部抜粋

```
func2(int):
        mov     eax, 1
        ret
```

素晴らしいですね!
【OCI】oracle cloud -仮想クラウド・ネットワーク構築編(サブネット)-【初心者向け】

# サブネット
サブネットはVCNによって作られているCIDRブロックを分割したネットワーク群のこと。
仮想マシン等を作成する際に、どこのサブネットに属させるか設定します。

## 前回の記事でVCNを作成しました。

VCNの作成を見たい方はこちらから
[VCN編](https://qiita.com/manaki079/items/1283bfe3f6e7667bfb43)

## サブネットの作成

サブネットを作成したいVCNの詳細ページ
左側のリソース→サブネット→サブネットの作成をクリック
![instance_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/614dbec4-fec5-7aaf-acdf-6d17622b50f1.png)

| 項目       | 概要|
|:-----------------|:-----------------|
| 名前             | 任意のサブネット名を入力します。 |
| サブネット・タイプ           | 基本はリージョナルで問題ありません。|
| CIDRブロック |VCNのCIDR範囲でこのサブネットに割り当てるCIDRブロックを決める|
| CIDRブロック               |プライベートIPアドレスの範囲を決める |
| ルート表 |任意のルート表を選択(ここではデフォルトのままにします。)|
| サブネットアクセス|外部からアクセスしたい場合はパブリック|
| DNS解決|基本チェック有りでいいと思う|
| DNSラベル|任意のDNSラベル名|
| DHCPオプション|任意のDHCPオプションを選択(ここではデフォルトのままにします。)|
| セキュリティリスト|公式はデフォルトを利用することを推奨しているようです(後に修正は加えます)|
![instance_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/95e25f6a-efae-52e7-b8b6-c3fd28c50d23.png)
入力し終えたらサブネットの作成をクリック
![instance_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111276/b633dfb3-b3b1-fc8f-dd44-d3a22921000a.png)

## 次回
インターネットゲートウェイの作成を行っていきます。

[インターネットゲートウェイ編はこちら](https://qiita.com/manaki079/items/1283bfe3f6e7667bfb43)
Vue .js勉強で躓いたツールやフレームワークまとめた


# はじめに
フロントエンド初心者プログラマーがVueを勉強する中で、Vueとの関連がイマイチ掴めず混乱したライブラリやフレームワークについて。
そもそもこれって何？をざっくり自分用にまとめたものです。

コンポーネント指向についてや、具体的なディレクトリ構成や、コードやコマンドの書き方、ルールについては、ここでは触れません。

# Vue.js
javascript上で動くProgressive Javascript Framework。
受け取った情報を元に画面描画を行うフレームワークで、MVCのVを担う。

### 特徴
- HTMLとVueインスタンス内のオブジェクトにある変数が連動して、同じ値を取り続ける、双方向データバインディング。
- アリババでの導入実績があるからか、中国での開発人口が多いらしい。
- エコシステム(連携可能な他システム)は少な目。
- 公式サイトが始めやすさを重視しているのもあり、とっつきやすい
- コンポーネント指向開発に適したフレームワーク。

# Vue-CLI
Vue.jsでアプリケーションを作る為の、CLI interface。動かす為には、あらかじめNode.jsのインストールが必要。
コマンド一つでプロジェクトのひな形作成ができ、すぐにアプリケーション作成を始められる。
作成されるのは、SPA構築のひな形である。
Vue.jsはルーティングなどを他のライブラリで補う必要があるのだが、ひな形作成時にそのあたりもよしなにやってくれる。
(visual studioとかunityで新規プロジェクト作成！ってするようなもんか……と思うことにしている。)

# webpack
フロントエンドのビルドツール。
Vue-CLIによるひな形にも適用されていて、裏側で動いている。

ざっくりした機能のポイントは、以下。

- クライアントサイドのJavaScriptで、importとexportが使えるようになる
- あらゆるライブラリをモジュール単位で取り扱い、ブラウザで扱える形式に変換する
- 依存関係を精査したうえで、一つのファイルに最適化(変換)する

Scriptタグでは読み込めないVueファイルを、webpackがjsに変換して、取込・表示出来るようにしている。
つまり、これがないと単一コンポーネントファイルは扱えない。

## Babel
javascriptのバージョンを新しいものから古いものに書き換えるツール。
開発時はES6がいいが、閲覧側が未対応、などの場合に使うらしい。

Vue-CLIによるひな形にも、デフォルトでインストールされる。

## Vuex
Vue.jsの為の、状態管理パターン+ライブラリ。
Vue-CLIによるひな形には、デフォルトではインストールされない。作成時に、チェックするとインストールされる。
(後述のNuxt.jsではデフォルトでインストールされる。)

Vuexのstoreってところにデータを保持しておき、各コンポーネントから呼び出せる。
データ保持は、サーバーとの通信をするわけではなく、あくまで端末側の話。

## Vue Router
Vue.jsの公式ルーター。
Vue-CLIによるひな形には、デフォルトではインストールされない。作成時に、チェックするとインストールされる。
(後述のNuxt.jsではデフォルトでインストールされる。)

これなしでSPAを作る方法がよくわからなかったので、SPA作りたいときに使った。

## Vue.js devtools
chromeのデベロッパーツール拡張機能。
chromeウェブストアにて簡単に追加できる。

通常、Vueファイルはjsに変換された後の状態しか確認できない。
が、この機能を入れることで、各コンポーネントだけでなく、Vuex や Vue Routerの状態も表示できる。

## Nuxt.js　
Vue.jsアプリケーション開発の為のフレームワーク。
こちらもVue-CLI同様、ひな形が作成できる。
Vue-CLIと同じSPAアプリケーションの他、ユニバーサルアプリケーション、静的に生成されるアプリケーションのひな形も用意されている。

Nuxt.jsの場合はVuexと、Vue-routerがデフォルトで構成されており、

- store直下にファイルを配置するだけで自動的にstore登録
- pages直下にファイルを設置するだけでルーティング設定

など、Vue-CLIと異なる利点もある。
他にも、APIのデータやりとりに使うaxiosもデフォルトで入っている。

便利そうだが、小規模開発なら少々オーバースペックな印象もある。

# 終わり
Vue-CLIを無視してVue.jsと向き合ってみた際に、知識不足で苦しんだのでまとめてみました。
間違いに気づいたら、都度修正していきます。それはおかしい、と思うこと等あればご指摘いただけると助かります。


### 参考サイト
Nuxt.js公式　https://ja.nuxtjs.org/
Vue-router公式　https://router.vuejs.org/ja/
Vuex公式　https://vuex.vuejs.org/ja/
webpackとは？ https://goworkship.com/magazine/how-to-webpack/
VueによるSPA構築　https://dev83.com/vue-constr/
Vue-CLIでできること　https://www.ritolab.com/entry/170#aj_2_1
jqさながらコマンドラインでhtmlをパースできるtidyコマンド

jqのxml/htmlバージョンみたいなもの

```shell:
$ tidy -i -utf8 パースしたい文字列
```

パイプで使うことの方が多いと思う

```shell:
$ curl "https://newspicks.com/" | tidy -i -utf8
```

color_echoで見たいところに色をつけると、なお見やすい

```shell:
$ curl "https://newspicks.com/" | \
  tidy -i -utf8 | \
  colorecho -p "title _ellipsis" -H h_cyan
```

以上。
spacemacsのpareditキーバインドを追加する

# 前置き
spacemacsで`smartparens`を`paredit`のキーバインディングで使っている。

たとえば以下のカーソル配置で`Ctrl + →`はA.の飲み込み、`Ctrl + ←`はB.の吐き出し操作となる。

```clojure
;; 初期状態（カーソルはaaaの隣）
(|aaa bbb) ccc

;; A. cccを飲み込み
(|aaa bbb ccc)

;; B. bbbを吐き出し
(|aaa) bbb ccc
```

`矢印キー　つらい`……… :innocent: 

# キーバインドを増やす
設定ファイル`.spacemacs`の`(defun dotspacemacs/user-config ())`内に以下のようなコードを追加すればよい。

```emacs-lisp:.spacemacs
(defun dotspacemacs/user-config ()
  ;; paredit用に封じる
  (define-key evil-insert-state-map (kbd "C-o") 'nil)
  (define-key evil-insert-state-map (kbd "C-p") 'nil)
  ;; paredit前方飲み込み
  (define-key evil-insert-state-map (kbd "C-p") 'paredit-forward-slurp-sexp)
  ;; paredit後方飲み込み
  (define-key evil-insert-state-map (kbd "C-u") 'paredit-backward-slurp-sexp)
  ;; paredit前方吐き出し
  (define-key evil-insert-state-map (kbd "C-o") 'paredit-forward-barf-sexp)
  ;; paredit後方吐き出し
  (define-key evil-insert-state-map (kbd "C-i") 'paredit-backward-barf-sexp)
  ;; paredit括弧削除
  (define-key evil-insert-state-map (kbd "C-d") 'paredit-splice-sexp)
  )
```

上記の例では、`evil-insert-state-map`（要するにvimのinsert mode）において、`Ctrl + p`や`Ctrl + u`で飲み込み(slurp)操作、`Ctrl + o`や`Ctrl + i`で吐き出し(barf)操作ができる。
また、`Ctrl + d`で括弧を除去できる。

他のキーバインドと被らせると昇天する :innocent: のでそこだけは慎重に…
今回の例でもinsert stateでの`Ctrl + o`と`Ctrl + p`が被っていたので、誠に遺憾ながら消えていただいた… :pray:
windowsでDocker Machine構築につまづいた話

Docker Machineって何？のレベルです。

環境
windows 10 pro
Docker for windows

#Docker machine#
[Docker Machineの概要](http://docs.docker.jp/machine/overview.html)
現在Docker for windowsをインストールしてDocker Engineを構築していますが
構築されているのは１つだけなので、Docker環境を複数使いたいならDocker Machineを構築すれば使えるよって話っぽいですね。
ローカルでもAWSでも使えるとなると結構便利そうです。

```powershell
docker-machine create --driver hyperv docker-machine-name
```
windows10 proはhyper-v上にDocker Machineを構築するようなので、ドライバーにhypervを指定する必要があるようです。
上記コマンドを実行したところ以下のエラーが出力されました。

```
Error with pre-create check: "no External vswitch found. A valid vswitch must be available for this command to run. Check https://docs.docker.com/machine/drivers/hyper-v/"
```

エラーを見る限りvswitchが無いとのことなのでvswitchを作成してあげる必要があると思い、以下の記事を参考に構築したところ、構築できました。

[WindowsでDocker Machineを試してみる](https://qiita.com/fkooo/items/356c9954181c00818f12)

ただ、なぜvswtichが必要なのかわからなかったため、調べてみたところhyper-vが原因だったらしいです。
以下の記事がかなり参考になりました。

[Hyper-Vネットワークの基本](http://www.vwnet.jp/windows/WS12R2/Hyper-V/Hyper-V_Network.htm)

Docker Machineは今回仮想環境上に作成しましたが、作成しただけだと外部（インターネット）に抜ける術がないので、
仮想環境と物理環境（仮想NICと物理NIC）を繋げてあげる必要があります。
その時仮想環境と物理環境をつないでくれるのがvswitch（仮想スイッチ）なんですね。

ネットワークの仕事をやっていますが、意外と役にたったので良かったです。
Arduino + Max8 (2) センサで音の再生

## ここまでのおさらい

前回は、ArduioとMax8を連携させ、センサの値をMaxで表示しました
この章ではセンサの値を活用したパッチを組んでいきます

前回記事でも使用した[こちらのパッチ](https://www.dropbox.com/s/coo3j0zuz6whnhi/sensorDataVisualize.maxpat?dl=1)を改変していきます。



#### グラフを少し小さく表示する

グラフを表示するオブジェクトはmultisliderというものですが、右下部分をドラッグ・アンド・ドロップすることで大きさを調整することができます
A0からA3と書かれているものは**コメントボックス**と言い、こちらも移動することができます

![minimizeMultislider](https://tva1.sinaimg.cn/large/006y8mN6gy1g78iml33b1g30yp0n4qgi.gif)それでは空いたスペースにパッチを組んでいきましょう

#### 値を送受信するオブジェクト(send, receive)の活用

![sendReceive](https://tva1.sinaimg.cn/large/006y8mN6gy1g78jg0ktejg30i20n415o.gif)

以降、パッチングにショートカットキーを使っていきます
・**nを押して**オブジェクトウィンドウを表示し、`send A0data`（sendとA0dataの間には半角スペースを入れる）と入力し上のナンバーボックスとつなぎます
・**nを押して**オブジェクトウィンドウを表示し、`receive A0data`（receiveとA0dataの間には半角スペースを入れる）と入力します
・**iを押して**number(i)を表示し、`receive A0data`とつなぎます

➡A0のセンサの値が変化すると、receiveに繋いだ**ナンバーボックス**内の値が変わることがわかります

`send`及び`receive`はパッチコードをつなぐことなく、データを送る（受ける）事ができるオブジェクトです。`A0data`はデータのラベルなので自由に変えることができます
全てのオブジェクトをパッチコードで繋いでいくと見た目にわかりにくくなることが多いので、send, receiveを活用してみて下さい

#### センサの値によって音を再生する(sfplay~, ezdac~)

![sensorPlayer](https://tva1.sinaimg.cn/large/006y8mN6gy1g78j7ydjntg30i20n4dvs.gif)

以降、パッチングにショートカットキーを使っていきます

・`n(object)` → `> 100`と入力 (>と100の間には半角スペース)
・`t(toggle)`
・`n(object)` → `sfplay~`
・`n(object)` → `ezdac~`
・sfplay~の近くでクリック → `m(message)` → `open`と入力
・全てのオブジェクトをつなぐ

➡A0にボリュームセンサをつなぎ、センサをひねると音が再生されます

音が連続で再生されてしまうのは、常に「1」の値が送られてきてしまっているからです
次は、「0」から「1」に値が変化した際に1度だけ再生を行うようにパッチを修正します



#### 条件によって1度だけ音を鳴らす(change)

##### changeオブジェクトの配置

![changeIntro](https://tva1.sinaimg.cn/large/006y8mN6gy1g795adx911g30i20n47ck.gif)

先程のパッチに修正を加えていきます
・`n`を押してobjectを表示し`change`と入力して下さい
・changeの上に`t(toggle)`をおき、下に`b(button)`を3つおきます
・それぞれをつなぎます
・changeの上のtoggleをクリックして挙動を確認してみましょう



##### changeオブジェクトの挙動を確かめる

![chaneWork](https://tva1.sinaimg.cn/large/006y8mN6gy1g795ehhimlg30i20n440e.gif)

・`toggle`を一度押すと、`change`の一番左と真ん中のアウトレットから信号が出てきます。
→ `change`の**左アウトレットは「0→1」「1→0」と状態が変化した際**に信号が出力されます

→`change`の**真ん中アウトレットは「0→1」と状態が変化した際**に信号が出力されます

→`change`の**右アウトレットは「1→0」と状態が変化した際**に信号が出力されます

「センサが一定の値を超えた時」を検出して1回音を鳴らすパッチにするには、changeアウトレットの中央の出力を使うと良いことがわかります



##### changeオブジェクトの活用

それでは、以下のようにパッチを改変してみましょう

![changeP](https://tva1.sinaimg.cn/large/006y8mN6gy1g795n8hurmg30i20n4dmh.gif)

このパッチを実行すると、「センサの値が100」を超えた時に1回だけ音が再生されます。
・センサの種類に応じて反応する値（しきい値といいます）を帰るときは、`> 100`の部分の数字を変えてみて下さい

> 条件文を変えてみる（<, ==を使ってみる）と何が起こるか？
>
> `change`の別のアウトレットに繋いでみると何が起こるか？



完成したパッチは[こちら](https://www.dropbox.com/s/ev44vuqvm0vsbv7/sensorChangePlayer.maxpat?dl=1)からダウンロードできます。
どのフィールドにどの検証エラーが追加されたのかを、「表示言語やエラーメッセージに依存しない形で」テストする方法

## はじめに

Railsアプリケーションでモデルのバリデーションを検証するをテストケースを想定します。
たとえば、「姓が空文字列であれば検証エラーが発生すること」をテストしようとすると、次のようなテストが書けます。

```ruby
john = User.new(first_name: '', last_name: 'Lennon')
john.valid?
expect(john.errors[:first_name]).to include("can't be blank")
```

ですが、"can't be blank"はあくまで英語表示だった場合のエラーメッセージです。
もし日本語表示だったら次のようになります。

```ruby
expect(john.errors[:first_name]).to include("を入力してください")
```

## 上記の方法で困ること

この方法でも十分といえば十分なのですが、表示言語を切り替えられるタイプのRailsアプリケーション（国際化されたRailsアプリケーション）だと、テストが何か特定の言語（英語や日本語）に依存するのは少し気持ち悪い気がします。
それに、何らかの理由でエラーメッセージを変更すると、テストをいちいち修正しなければならない、という問題も発生します。

## 解決策

上のようなテストを表示言語やエラーメッセージに依存しない形で（つまり、エラーメッセージのキー情報だけを参照する形で）テストするには次のように書きます。

```ruby
expect(john.errors.added?(:first_name, :blank)).to be_truthy

# または（predicateマッチャを使う場合）
expect(john.errors).to be_added(:first_name, :blank)
```

後者の方が短く書けますが、個人的には前者の書き方の方が明示的でわかりやすい気がします。

### :blank って何？どこからやってきたの？？
`added?`メソッドの第2引数として渡している`:blank`は必須エラーが発生したときに使用されるエラーメッセージのキー情報です。

```en.yml 
en:
  errors:
    messages:
      blank: "can't be blank"
```

詳しくは以下のRailsガイドを参照してください。

参考：[Rails 国際化 \(i18n\) API \- Rails ガイド](https://railsguides.jp/i18n.html#%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%83%E3%82%BB%E3%83%BC%E3%82%B8%E3%81%AE%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97)

## 応用：メッセージに動的な値が埋め込まれる場合

検証エラーの中には、メッセージ内に動的に値を埋め込むものがあります。以下はその具体例です。

```en.yml
en:
  errors:
    messages:
      too_short:
        one: "is too short (minimum is 1 character)"
        # %{count}には動的な値が埋め込まれる
        other: "is too short (minimum is %{count} characters)"
```

```user.rb
class User < ApplicationRecord
  # 姓は2文字以上あることが必須
  validates :first_name, length: { minimum: 2 }
end

# 姓をわざと1文字にする
john = User.new(first_name: 'J', last_name: 'Lennon')
john.valid?

# エラーメッセージの%{count}の部分に"2"が埋め込まれる
john.errors[:first_name]
#=> ["is too short (minimum is 2 characters)"]
```

こういうケースのテストでは次のように、`:too_short`だけでなく`count`が2であることも指定する必要があります。

```ruby
expect(john.errors.added?(:first_name, :too_short, count: 2)).to be_truthy

# または（predicateマッチャを使う場合）
expect(john.errors).to be_added(:first_name, :too_short, count: 2)
```

## さらに：added?メソッドの第2引数と第3引数を調べる方法

`added?`メソッドの第2引数と第3引数に何を指定すればいいかわからない場合は、次のように`errors.details[(フィールド名)]`の中身を確認するとわかります。

```ruby
john.errors.details[:first_name]
#=> [{:error=>:too_short, :count=>2}]
```

上の出力例では`:too_short, :count=>2`とあるので、これが`added?`メソッドに渡す第2引数と第3引数になります。

## 追記：Rails 6では errors.of_kind? が便利！

Rails 6からは `errors.of_kind?` が使えます。これを使うと`added?`メソッドで必要だった `count: 2` を指定せずに、メッセージのキー情報だけで検証エラーの有無を確認できます。

```ruby
expect(john.errors.of_kind?(:first_name, :too_short)).to be_truthy

# または（predicateマッチャを使う場合）
expect(john.errors).to be_of_kind(:first_name, :too_short)
```

（Objectクラスに元から用意されている）`kind_of?` ではなくて、 `of_kind?` なので注意してください。（僕は最初うっかり間違えました😣）

**謝辞**
コメント欄でこのメソッドを教えてくれた @ttakuru88 さん、どうもありがとうございました！


## まとめ

というわけで、この記事では「表示言語やエラーメッセージに依存しない形で検証エラーの有無をテストする方法」を紹介しました。

必ずしもエラーメッセージを直接比較する方法が悪いわけではありません。
ですが、こうしたアプローチもあることを知っておくと役に立つ場面があるかもしれません😉
【salesforce】例外処理をうまく使ってエラーの特定を早く行う

#例外処理

おさらいですが、
>例外は、コード実行の正常な流れを中断させるエラーやその他のイベントが発生したことを通知します。スロー これは例外の生成に使用され、試してみる、キャッチ、および 最後に これは例外から適切に復旧するために使用されます。

Apexでは例外をこのように扱っています。
この例外処理をうまく使ってエラーが起きても素早く対処し、
どこで何が起こっているのかの特定を行います。

下記のようなコードがあったとします。

```ruby:sample.apex
Id hoge = 'a';
```

この場合Id型に対して代入しているのは文字列になり、単純にシステムエラーとして返されてしまいます。
このように、たった1行のコードであればすぐに見つけられますが、何百行となってきたときにどこで入力の漏れがあったのかとか、
変数を探したりなんだり。。。。時間がかかってしまいますよね。

そこで例外処理を使って箇所を特定し、エラーがなぜ起こったのかを把握して対応します。

```ruby:sample.apex
try {
  Id hoge = 'a';
} catch ( Exception e ) {
  system.debug(e.getMessage());
}
```

このようにコードを変えてみます。
どのような結果が返ってくるでしょうか。

<img width="169" alt="スクリーンショット 2019-09-23 9.18.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472705/5236bc60-4b0a-0016-014e-2bb32127f423.png">

想定通りですね。

よくやる形としては、これをメッセージとしてVFに出力したりします。
これで何が起こっているかは判定できましたが、
どこで起こっているのかも知りたいですよね。

そのために先ほどのコードにもう少し追加をします。

```ruby:sample.apex
try {
  Id hoge = 'a';
} catch ( Exception e ) {
  system.debug(e.getMessage());
  system.debug(e.getLineNumber());
}
```

system.debug(e.getLineNumber());を追加しました。
結果は、

<img width="169" alt="スクリーンショット 2019-09-23 9.20.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472705/7b422fe0-d622-c4df-e9d9-0ab33993c411.png">

行数も出てきましたね。

これを使えば大体のエラー個所が特定しやすくなるのではないでしょうか。

##参照

https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_classes_exception_methods.htm

#profile

生まれも育ちも大阪の浪速中の浪速っ子が30才未経験からITエンジニアとして生きるブログもやってます。
よかったらみてください:muscle_tone2:

<a href="https://blogmura.com/profiles/11016817?p_cid=11016817"><img src="https://blogparts.blogmura.com/parts_image/user/pv11016817.gif" alt="PVアクセスランキング にほんブログ村" /></a>
emmet覚書

|　　　コマンド　　　|　　　入力キー　　　|
|:----------------:|:----------------:|
|確定              |                Tab|
|class     |           .|
|id          |           #|
|入れ子      |           >|
|同階層      |           +|
|乗算        |           *|



div.Division>nav#navigation+span*3

```
<div class="Division">
　　<nav id="navigation"></nav>
　　<span></span>
　　<span></span>
　　<span></span>
</div>
```
CentOS7のpostgreSQL自動起動設定～外部接続まで

#CentOS7のpostgreSQL自動起動設定～外部接続まで

[CentOS7にpostgreSQLをソースからコンパイルでインストールの続き](https://qiita.com/code2545Light/items/de1ff38453c90873d499)

PostgreSQLをインストールしたディレクトリ
/home/mayser/mypgsql

起動スクリプトを配置するディレクトリとファイル名
/usr/lib/systemd/system/postgresql.service

##起動時のパス設定

```/etc/profile
#2019/09 postgresqlのパス通す
export PATH=/home/mayser/pgsql/bin:$PATH
```

##起動スクリプトの準備
/usr/lib/systemd/system/postgresql.service

```postgresql.service
[Unit]
Description=PostgreSQL database server
After=network.target

[Service]
Type=forking
User=mayser
#Group=admin
Environment=PGDATA=/home/mayser/mypgsql
Environment=PGLOG=/home/mayser/mypgsql/serverlog
OOMScoreAdjust=-1000

ExecStart=/home/mayser/pgsql/bin/pg_ctl -D /home/mayser/mypgsql start

ExecStop=/home/mayser/pgsql/bin/pg_ctl -D /home/mayser/mypgsql stop

TimeoutSec=300

[Install]
WantedBy=multi-user.target

```

その後、以下のコマンドにて起動
（OS再起動後もpostgreSQL起動される)

sudo systemctl enable postgresql
systemctl start postgresql
systemctl list-unit-files | grep "postgres"

##外部からの接続許可設定
postgresqlはデフォルトでは自ホストからしか繋げないようになっています。その為postgresqlにクライアントアプリからアクセスするためには設定が必要になります。

以下の設定が必要になります。
1.CentOS上のF/W許可
2./home/mayser/mypgsql/postgresql.confの編集
3./home/mayser/mypgsql/pg_hba.confの編集

###CentOS上のF/W許可
再起動後も有効にする為に、永続設定とする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480709/7c55105b-82d2-e1ac-7c88-3a9730aa49d8.png)


###postgresql.confの編集

```postgresql.conf
#------------------------------------------------------------------------------										
# CONNECTIONS AND AUTHENTICATION										
#------------------------------------------------------------------------------										
										
# - Connection Settings -										
										
listen_addresses = '*'			# what IP address(es) to listen on;←コメントを解除し、''内を * に修正							
					# comma-separated list of addresses;					
					# defaults to 'localhost'; use '*' for all					
					# (change requires restart)					
port = 5432				# (change requires restart)←コメントを解除し、必要あればポート番号を変更する						
max_connections = 100			# (change requires restart)							
```

###pg_hba.confの編集
全てのホストからの接続を許可する
全てのホストから、全てのデータベースへの接続を許可する場合、以下の記述を追加する。

```pg_hba.conf
host all all 0.0.0.0/0 trust
```

##接続確認
まずは、telnetレベルでのネットワーク疎通確認(5432ポートが開いているか？)

```
telnet 192.168.10.8 5432 
```

真っ黒な画面が出たら接続されています。

DBへの接続は、[psqledit](http://www.hi-ho.ne.jp/a_ogawa/psqledit/index.htm) を使います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480709/588e31aa-6777-0839-148f-ae2c9e037ed5.png)
Ruby でディレクトリ以下のファイルを再帰的に探索する

## 概要
- Ruby でディレクトリ以下のファイルを再帰的に探索するプログラムを書く
- Dir.glob と Dir#children を使ったパターンを示す

## 動作確認用のディレクトリとファイルを用意

```
$ tree -a sample/
sample/
├── .a.config
├── a.jpg
├── a.txt
└── dir1
    ├── .b.config
    ├── b.jpg
    ├── b.txt
    └── dir2
        ├── .c.config
        ├── c.jpg
        └── c.txt

2 directories, 9 files
```

## Dir.glob を使うパターン

ソースコード。
FNM_DOTMATCH フラグで先頭のドット「.」にもマッチさせている。

```ruby
# 第1引数をターゲットのディレクトリパスとする
# 未指定の場合はカレントディレクトリを指定する
target_dir = ARGV.length > 0 ? ARGV[0] : '.'
puts "target_dir: #{target_dir}"

# ディレクトリを再帰的に辿る
Dir.glob('**/*', File::FNM_DOTMATCH, base: target_dir).each do |file|
  # ファイルのパスを作る
  file_path = File.join(target_dir, file)
  puts "#{file_path}"
end
```

実行結果。

```
$ ruby dir_glob.rb sample/
target_dir: sample/
sample/.
sample/.a.config
sample/a.txt
sample/dir1
sample/dir1/.
sample/dir1/dir2
sample/dir1/dir2/.
sample/dir1/dir2/.c.config
sample/dir1/dir2/c.txt
sample/dir1/dir2/c.jpg
sample/dir1/b.txt
sample/dir1/b.jpg
sample/dir1/.b.config
sample/a.jpg
```

## Dir#children を使うパターン

ソースコード。

```ruby
# 再帰的にディレクトリ内のファイルを調べる
def recursive_search(dir_path)

  dir = Dir.new(dir_path)

  # "." と ".." を除いたファイル名の配列でループ
  dir.children.each do |file_name|

    # ディレクトリのパスとファイル名からファイルのパスを作る
    file_path = File.join(dir_path, file_name)
    puts "#{file_path}"

    # ファイルがディレクトリだったら再帰的に関数を呼び出す
    if File.directory?(file_path)
      recursive_search(file_path)
    end
  end
end

# 第1引数をターゲットのディレクトリパスとする
# 未指定の場合はカレントディレクトリを指定する
target_dir = ARGV.length > 0 ? ARGV[0] : '.'
puts "target_dir: #{target_dir}"

recursive_search(target_dir)
```

実行結果。

``` 
$ ruby dir_children.rb sample/
target_dir: sample/
sample/.a.config
sample/a.txt
sample/dir1
sample/dir1/dir2
sample/dir1/dir2/.c.config
sample/dir1/dir2/c.txt
sample/dir1/dir2/c.jpg
sample/dir1/b.txt
sample/dir1/b.jpg
sample/dir1/.b.config
sample/a.jpg
```

## 今回の動作確認環境
- macOS Mojave
- Ruby 2.6.4

## 参考資料
- [class Dir \(Ruby 2\.6\.0\)](https://docs.ruby-lang.org/ja/2.6.0/class/Dir.html)
- [singleton method File\.fnmatch \(Ruby 2\.6\.0\)](https://docs.ruby-lang.org/ja/2.6.0/method/File/s/fnmatch.html)
APRS(アマチュア無線)を使って見る。

今回はアマチュア無線のAPRSについて書きたいと思います。

最初にアマチュア無線とは何ぞ？というところから書きたいと思いできます。
当然、アマチュアといえども「無線従事者」という免許と
「無線局免許」の2つが必要になります。

前者は一番やさしい4級から難しい1級まであります。
最初のステップとしては、4級からでも良いと思います。

無線局免許とは、無線機やアンテナの無線設備に対する免許と考えていただければ良いかと思います。

操作する人間の免許＋無線設備の免許が必要です。
なんだ面倒だなーと思われますが、携帯電話も、テレビも、wifiも
全部無線局免許があって使えている訳です。
これは、技適という言葉がありますが、制限がある中で、使えるという
事になっている訳です。アンテナも、電波発射に関する内部のプログラムも変えられない事が前提です。

ところでAPRSについてですが、アマチュア無線では1990年代前半位に
「パケット通信」が流行りまして、そこら中にBBSが出来ました。
インターネットが普及すると当然それらもしぼんでいったのですが、
インターネットとの接続が許可されて、このAPRSがアメリカの方によって作られました。

APRSは、IGATEというアマチュア無線のパケット通信で送られて来るデータをインターネットに転送する局で受信されると、APRSサーバーにデータが集約され、一般に公開されます。

このAPRSですが、自分がいる位置を送信しています。
その位置をIGATE局が受信してインターネットに送るというのが具体的な使い方です。
少しのぞいてみたいならば、
https://aprs.fi/
を見てください。どんな感じで転送されているのかわかると思います。

私はラズベリーパイ3にXastirというソフトをインストールして
使用しています。こんなレベルでも十分使えます。

今日はこんなところで

参考として、ウィキペディアのURLを示します。

https://ja.m.wikipedia.org/wiki/APRS

各種本も出ているようですので、読んで頂ければと思います。
IDE前提ならインデント記法の言語が効率的では？

# Pythonのようなインデント記法はコード量が減る

　Pythonのようなブロックの終端（閉じ記号）がないインデント記法は、終端を記載しないので、その分だけコード量が少なくて済む。
　最近は、IDEやエディタのプラグインでコードの補完をしてくれるのでそこまで入力については手間はないかもしれない。けれど、読むときは文字数が少ないに越したことはない。

# インデント記法への抵抗
　
　インデント記法については、好みもあるだろうが、好き・嫌いではなく、論理的な根拠によって利用しない人もいるかもしれない。私は、論理的な根拠への批判については、IDEを使うことでその多くの問題点は解消できると思う。

　問題点は、見えない文字による定義、また、タブや空白の設定が個人やプロジェクトによって異なるので固定化されないことなどではないだろうか。
　
　見えない文字による定義については以下のIDEやエディタの機能で十分対応できる。ただし、タブや空白の設定の差異については、指摘の通り問題点だと思う。これを重視する場合は、インデント記法の採用は難しいかもしれない。
　
　個人的には、プロジェクトごとに言語の設定はいつも変えるので、特に問題はないと思っているが、それは個人個人の状況により異なるだろう。

# IDEの機能でインデント記法を効率的に使いこなす

　メモ帳や拡張なしのエディタを使ってコーディングしている人にとっては、インデント記法はブロックの区切りをつけるのがとても大変だし、調整が難しいかもしれない。

　けれど、最近はIDEやVimなどのエディタもプラグインをいれて開発するのが一般的である。その場合、インデント記法の大変さは軽減される。

## 不可視文字の表示

　インデント記法は、空白やタブによってブロックを分ける。この空白やタブが見えないからわかりにくいというのがあるかもしれない。けれど、最近は、どんなエディタでも不可視文字を表示できる。

　もちろん、空白やタブの感覚もエディタで設定ができる。スペースの数や\tにするかも設定できる。

## 行頭を表すルーラー

　インデント記法は、行頭がブロックの階層を表す。なのでそれがずれるとエラーになる。けれど、最近のエディタは、行頭がわかるルーラーが表示される。それによって、ブロックの行頭のズレもわかる。

## 自動のフォーマッター

　最近、有名なプログラム言語については、オートフォーマッターがあるので、それでインデントもすべてそろえてくれる。オートでできない場合がかりにあっても、上記の不可視文字やルーラーを頼りにそろえればいい。

# 昔の言語批判は、IDEの進歩によって解消されているかも？

　IDE前提であればPythonのようなインデント記法の方がコーディング量は減るのでその分、何かと作業が速い。コードも文字数がない分見やすい。

 　最近は、昔されていたプログラム言語への批判は、IDEやエディタのプラグインの貢献で、だいぶ解消されてきていると思う。
　例えば、ビルドについても、IDEをインターフェースとして、さまざまなライブラリを統合すれば、自動でできてしまう。
　VSCodeのように、プラグインのマーケットプレースから、自動インストールの機能がそろっているものならなおのこと、プラグインの利用はしやすい。

　プログラム言語の批判についても、IDEを前提に、今一度考えてみると、意外と問題は少ないのかもしれない。
webarenaでubuntu その49

#概要

webarenaでubuntu18.04やってみた。
php7.2でGDやってみた。

#インストール


```
sudo apt-get install php7.2-gd
```

#サンプルコード

```
<?php
	$gif0 = 'R0lGODlhAQABAGAAACH5BAEKAP8ALAAAAAABAAEAAAgEAP8FBAA7';
	$gif0 = base64_decode($gif0);
	$gif0 = imagecreatefromstring($gif0);
	header("Content-type: image/gif");
	imagegif($gif0);
?>
```

以上。
vendoring とは; そのメリットとデメリット

# vendoring とは何か

"vendoring" とは(あるいは "vendorする" とも)、ライブラリなどの依存先ソフトウェア(dependencies)のコピーをリポジトリに取り込んでしまうことを言います。

# vendoring のメリット

* 依存先がなくてもビルドできます
  * 依存先が削除された時にも安全です。 (具体的には、軍事利用に反対した作者によってパッケージが突然削除された事例[^1]や、容量制限のため古いバージョンを削除している事例[^2]などがあげられます)
  * ネットワークがない、または制限されている環境でもビルドできます。(CIやオンサイトなど)
* 同じ環境を容易に再現できます。
* 依存先のソースに独自のパッチをあてることができます。
* 開発環境にたくさんのパッケージを入れる必要がありません。

[^1]: [A Developer Deletes His Code to Protest Its Use by ICE](https://www.wired.com/story/developer-deletes-code-protest-ice/)
[^2]: https://github.com/google/jax/issues/8640#issuecomment-975030663


# vendoring のデメリット

* リポジトリが大きく、重くなります。
* 依存先の履歴やタグなどが失われます。
* 依存先のソースにパッチをあてることができてしまいます。
  * そのため、依存先にdivergence(分岐)が発生する可能性があります。
  * そのため、依存先が正規のコピーであるかそれとも独自のパッチを当てたものであるか、後で把握するのが大変になります。

# vendoringの具体例

* 最近、私はとあるソースコード生成ツールのテンプレートについてvendoringした方が良いと判断しました。テンプレートはOSSでダウンロードしたものですが、十分なバージョン管理が行われていないためです。
* (TBW)

# 参考資料

- [What does the term “vendoring” or “to vendor” mean for Ruby on Rails?](https://stackoverflow.com/a/11378966/4156113)
- [Python でも Vendoring すれば環境汚染しないパッケージが書けて嬉しい](https://qiita.com/msh5/items/2bab8ccaba88d1d836f0)
- ["Vendoring" is a vile anti-pattern](https://gist.github.com/datagrok/8577287)
【Python】ABC - 096 - Maximum Sum【heapq】

# 問題
3つの正整数$A, B, C$の中から一つ選び、2倍した値に書き換える。この操作を$K$回実施したときの合計の最大値を求める問題。

# 方針
1. 操作ごとに現在の3つの正整数から最大値を取り出し、2倍したものに書き換える
2. K回操作後の3つの正整数を合計する

# 工夫
[蟻本　python プライオリティキュー　heapq　競技プログラミング](https://juppy.hatenablog.com/entry/2018/11/08/%E8%9F%BB%E6%9C%AC_python_%E3%83%97%E3%83%A9%E3%82%A4%E3%82%AA%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AD%E3%83%A5%E3%83%BC_heapq_%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3)のブログを参考に、heapqを用いて解く。

heapqを使うと良い場面として、

+ 配列の要素が増える
+ 最大値/最小値を取り出す

という操作を複数回繰り返すときに有効。

今回の問題では、プライオリティキューを用いてその時点での最大値を取り出し、その最大値を2倍したものを要素に追加する。
heapqの基本的な利用方法は、以下の通りである。Pythonのheapqを利用するときの注意点は、`heapq.heappop()`が最小値を取り出す仕様になっているので、最大値を取り出す操作を実施したい場合は、事前に要素にマイナスをかけたリストをプライオリティキューに変換する必要がある。

```python
import heapq
heapq.heapify(a) # リストaのプライオリティキューに変換
heapq.heappush(a,x) # プライオリティキューに変換されたaに要素xを追加
heapq.heappop(a) # プライオリティキューに変換されたaから最小値を削除＆その最小値を出力
```

以下、実装を示す。

```python
import heapq
A = list(map(int, input().split()))
A = [-a for a in A] # プライオリティキューで最大値を取り出す処理を実施するために正負反転
K = int(input())
heapq.heapify(A) # プライオリティキューに変換
for i in range(K):
    max_val = heapq.heappop(A) # 最大値の取得とプライオリティキューからの削除
    heapq.heappush(A, 2*max_val) # 取り出した最大値を2倍してプライオリティキューに追加
print(sum([-a for a in A]))
```
rm コマンドのよく使うオプションまとめ

CentOS 7 で確認。rm のバージョンは GNU coreutils 8.22。

### フォルダーを中身を含めて削除
```
-r
```

`-R` でもよい。

### 多数の項目を削除するとき、一度だけ確認
```
-I
```

`-i` だとすべてのファイルについて確認。

### 削除したファイルを表示
```
-v
```
ElmでEvanczさんのTodoMVCをFirebase(Firestore)で動かしてEllieにのせてみました

# ソースとデモはこちら

[https://ellie-app.com/6K25LFpDjFGa1]

Firebaseはテストモードでauthもsecurityもしていないので、だれでも読み書きできて、誰でも見れます。 

壊せます。  

使ってみて下さい。  

Elmは0.19でわたしの環境はUbuntu 19.04、vscode、など。

## Firebase(Firestore)について

元のEvanczさんのはlocalStorageベースなのをfirebase.google.comのデータベースFirestoreを使う形にしました。

ElmとHtmlとのやりとり(とデータベースの書き換え)がキーをタイプするたびに発生する仕組みなので、これでいいのかなぁ、と思はないでもないですが、Evanczさんがそうしているのでこれはこれでとりあえずそのままにしています。

前回作ったのはAddとかDeleteとかのたびに書き換えだったのですが、今回のはデータのやりとりが多いのでユーザー数が増えたら課金されてしまうかもしれないので、その時は書き換えます。

## ElmプログラムとHtml

Elmプログラムの方は触っていません。

Htmlは別ファイルだったcssをheadに入れました。headが巨大になってしまって本体が下の方になって読みにくいですね。すいません。

Firebaseの設定と関数はlocalStorageと違うので試行錯誤しました。ドキュメント少ない。動いたからいいけど。
deviseを使ったUserモデルにカラムを追加してストロングパラメーターを実装する


## はじめに


deviseを使うとユーザーのログイン・ログアウト機能などを簡単に実装できると聞いたので、早速使ってみました。
ただdeviseをインストールしてモデルを作成後に確認してみると `name` カラムがデフォルトでは存在しなかったので、 `name` カラムを追加してデータベースに保存できるようストロングパラメーターを設定してみることにしました。


基本的な手順は[Devise - GitHub](https://github.com/plataformatec/devise/blob/master/README.md)に書かれていることを参考にしました。


**※Userモデルとビューを作成した後を想定しています。**
deviseの導入は次が参考になりました。

- [初めてのdevise ① -- 導入してみる -- - Qiita](https://qiita.com/uloruson/items/ffb3d719b6d2fbea1afd)



## 手順

1. コマンドを実行してマイグレーションファイルを作成
2. マイグレーションに設定を加える
3. ストロングパラメーターを設定
4. フォームを修正





## マイグレーションファイルを作成・設定

まずはじめにマイグレーションファイルを作成

```
$ rails g migration AddColumnToUsers name:string
```


<br>

追加されたマイグレーションファイルにNOT NULL制約やデフォルトの値に空文字などを追加します。

```db/migrate/xxxxx_add_column_to_users.rb

class AddColumnToUsers < ActiveRecord::Migration
  def change
    add_column :users, :name, :string, null: false, default: ""
  end
end
```

追加後、保存したらマイグレートを実行

```
$ rails db:migrate
```


では nameカラム が追加されたのかを確認します。
コンソールを起動して、` User.column_names `を実行することで確認することができます。

```
$ rails c
>> User.column_names

=>[
  "id",
  "email",
  "encrypted_password",
  "reset_password_token", 
  "reset_password_sent_at", 
  "remember_created_at",
  "created_at",
  "updated_at",
  "name" <= 追加されていれば成功
]
```



## ストロングパラメーターを設定して保存できるように

ユーザー登録画面などで入力されたユーザー名をUsersテーブルに保存させるには、ApplicationControllerで設定する必要があります。

```app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
    # --- ここから ---
    before_action :configure_permitted_parameters, if: :devise_controller?
    
protected
  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:name])
    devise_parameter_sanitizer.permit(:account_update, keys: [:name])
  end
    # --- ここまでを追加 ---
end
```

追加した内容を解説していきます。

- 一番上の` before_action ... `では、Applicationコントローラが読み込まれる前に 、下の `configure_permitted_parameters` というメソッドを、 deviseコントローラ を使うときにのみ実行させるための記述です。

<br>


- `configure_permitted_parameters`メソッドでは、ユーザー登録・編集フォームで受け取ったユーザー名をデータベースへ保存できるようにストロングパラメーターを設定します。




## フォーム画面を修正

あとはユーザー登録・編集フォームにユーザー名の入力を追加します。
見た目は整えてないですが、ユーザー名が入力できてデータベースに保存できれば完璧です！

- app/views/devise/registrations/new.html.erb

``` new.html.rb
.
.
.
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
    <%= render "devise/shared/error_messages", resource: resource %>
  
    <div class="field">
      <%= f.label :name %>
      <%= f.text_field :name, class: "xxx" %> 
    </div>

    <div class="field">
      <%= f.label :email %><br />
      <%= f.email_field :email, autofocus: true, autocomplete: "email" %>
    </div>
.
.
.
```

## さいごに

name カラムの追加とストロングパラメーターの設定ができるようになって、色々してみたくなったので、次はユーザーのプロフィール画像を設定したり、いろんなテーブルと関連付けたりして遊んでみます。


色々やってみた結果を記事にしてみたいと思います。


## 参考

- [Devise - GitHub](https://github.com/plataformatec/devise/blob/master/README.md)
- [初めてのdevise ① -- 導入してみる -- - Qiita](https://qiita.com/uloruson/items/ffb3d719b6d2fbea1afd)
非推奨になったCordovaプラグインについて

現在、これまでCordovaコミュニティで開発されていた下記のCordovaプラグインが `非推奨` になっています。

# 非推奨になったCordovaプラグイン
 - [cordova-plugin-contacts](https://github.com/apache/cordova-plugin-contacts)
 - [cordova-plugin-device-motion](https://github.com/apache/cordova-plugin-device-motion)
 - [cordova-plugin-device-orientation](https://github.com/apache/cordova-plugin-device-orientation)
 - [cordova-plugin-file-transfer](https://github.com/apache/cordova-plugin-file-transfer)
 - [cordova-plugin-globalization](https://github.com/apache/cordova-plugin-globalization)


非推奨に伴い、Monacaで提供しているCordova9.0では、非推奨になったCordovaプラグインの提供を終了しています。

非推奨になったCordovaプラグインの一部では、移行方法が紹介されています。
今回は、非推奨になったCordovaプラグインの移行方法を紹介します。


# cordova-plugin-contacts

残念ながら、移行方法は提供されていません。
不具合がある場合は、他のサードパーティー製Cordovaプラグインを利用する必要があります。


# cordova-plugin-device-motion

[W3C Device Motion and Orientation API](https://www.w3.org/TR/orientation-event/) を利用することで対応することができます。
W3C Device Motion and Orientation APIへの移行方法は、[Migrating from the Cordova Device Motion Plugin](https://blog.phonegap.com/migrating-from-the-cordova-device-motion-plugin-ddd8176632ed)を参照してください。


# cordova-plugin-device-orientation

[W3C Device Orientation API](https://www.w3.org/TR/orientation-event/) を利用することで対応することができます。
W3C Device Orientation APIへの移行方法は、[Migrating from the Cordova Device Orientation Plugin](https://blog.phonegap.com/migrating-from-the-cordova-device-orientation-plugin-8442b869e6cc)を参照してください。

# cordova-plugin-file-transfer

[XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) で導入された機能を利用することで対応することができます。
XMLHttpRequestへの移行方法は、[Transition off of cordova-plugin-file-transfer](https://cordova.apache.org/blog/2017/10/18/from-filetransfer-to-xhr2.html)を参照してくださ

# cordova-plugin-globalization

[ECMA Internationalization API](https://www.ecma-international.org/ecma-402/1.0/) を利用することで対応することができます。
ECMA Internationalization APIへの移行方法は、[Migrating from the Globalization Plugin](https://cordova.apache.org/news/2017/11/20/migrate-from-cordova-globalization-plugin.html)を参照してください。


# おわりに

非推奨になったCordovaプラグインは、Monacaプロジェクトへ `パッケージ名` や `URL` でインポートすることはできますが、最終的には利用することができなくなります。

非推奨のCordovaプラグインを利用している場合は、移行を検討してみてください。
create-react-appで作ったアプリをFirebaseで公開する方法


create-react-appで作ったアプリをFirebase(Hosting)で利用する方法についいてまとめました。
[ほぼ同じ目的の記事](https://qiita.com/one-kelvin/items/958c9c1351d0d02c9c9f)があり参考にさせていただきました。


## 前提

* Firebaseでもうプロジェクトが作られている

## 必要なツールのインストール

まだの人は以下の通り、必要に応じてインストール

```bash
npm install -g create-react-app
npm install -g firebase-tools
```

## プロジェクトの作成と動作確認

```bash
create-react-app my-app
cd my-app
npm start
```

ローカルの3000ポートで下記のような画面が起動するはず。

![スクリーンショット 2019-09-23 6.47.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/1b41c42c-ec49-21fe-4164-4828159e6141.png "スクリーンショット 2019-09-23 6.47.03.png")

これをFirebase上に展開します。

## Firebaseで利用できるように設定

ログインしてるか確認。してないならする。

```bash
firebase login
```

Firebaseで利用するための初期化を開始。

```bash
firebase init
```

### どの機能使う？

今回はHostingを使うので、Hostingを選びます。

```bash
? Which Firebase CLI features do you want to set up for this folder?

 ◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◯ Functions: Configure and deploy Cloud Functions
❯◉ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules
```

### どのプロジェクト使う？

私は既存のプロジェクト（Firebase側の話）を利用するので、既存のプロジェクトを選択（その後、具体的なプロジェクトを選ぶ）。

```bash
? Please select an option: (Use arrow keys)

❯ Use an existing project
  Create a new project
  Add Firebase to an existing Google Cloud Platform project
  Don't set up a default project
```

### どのディレクトリをpublicにする？

create-react-appではbuildフォルダにビルドされたアップ対象のフィアル群が出力されるのでbuildを記入。

```bash
? What do you want to use as your public directory? build
```

### SPAとして設定する？

Reactで作ったWebはSPAなので、yを選択

```bash
? Configure as a single-page app (rewrite all urls to /index.html)? y
```

## buildとdeploy

今回は編集も何もせず、そのままテンプレートファイルをbuildしてdeployしてみます。

### build

buildは以下の通り。

```bash
npm run build
```

### deploy

deployは以下の通り。

```bash
firebase deploy --only hosting
```

deployが完了するとURLが表示されるので、それをブラウザで見てみます。
https://{project_name}.firebase.com/となるようです。

## 動作確認

ではURLを開いてみます。

![スクリーンショット 2019-09-23 6.47.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55188/3166eba5-4cd4-6c58-f363-ab3d5b966494.png "スクリーンショット 2019-09-23 6.47.10.png")

動いているようです。後はひたすら開発するだけ。
AngularJSとAngularのコミットメッセージガイドラインの比較


## はじめに

この記事を参考にコミットメッセージを付けていました。

- [【今日からできる】コミットメッセージに 「プレフィックス」 をつけるだけで、開発効率が上がった話](https://qiita.com/numanomanu/items/45dd285b286a1f7280ed)

ですが、あれ?と思った箇所があります。

それは、chore(雑用)という単語がしっくりこないことです。
具体的には自分のプロジェクトでCircleCIの設定変更をしてたのですが、
CIなのに雑用なのはちょっと違うかなぁ・・・と感じていました。

そこで参照元のガイドラインを見たところ、Angular(2.x〜)でなくAngularJS(1.x)になってたので、
最新のAngularのコミットガイドラインを雑に比較してみました。

## 比較方法

- [AngularJS](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md)
- [Angular](https://github.com/angular/angular/blob/master/CONTRIBUTING.md#-commit-message-guidelines)

この2つの記事から該当箇所を抜き出してdiffした結果を目視確認しました。
ガイドラインとして影響しない箇所(リンク追加など)は除外しています。

## 相違点

### Typeのchoreが分離されてなくなった

chore(雑用)は色々なものを含んでいましたが、以下のように分離されました。

- build: ビルドシステムやライブラリの変更
- ci: CI周りの変更

コミットログを見ると、ドキュメントのビルドにも build が使われるようです。
(例: `build(docs-infra): xxx`)

### Scopeの付け方が明確化

Scopeの付け方が明確化されました。

- 基本はnpmのパッケージ単位
- いくつかの例外あり
  - packaging: package.json, \*.d.tsなどでのパッケージレイアウトの変更
  - changelog: CHANGELOG.md
  - docs-infra: ドキュメントビルド関連
  - ivy: Ivy renderer
  - ngcc: Angular Compatibility Compiler
  - 空: style, test, refactorで全てのパッケージにまたがる場合
- 複数のScopeにまたがる場合に `*` をつけてもいいという記述がなくなった

ここはプロジェクトによって異なる付け方になると思います。

## おわりに

`chore` がなくなって `ci` を使えるようになったので安心しました( ´ω`)
前記事のリファクタリングを咀嚼する（みんなでしりとり）

#趣旨
拙いながらBクラス問題についての[記事](https://qiita.com/LLeak/items/f6f8e0a6554276f5137d#comment-f3e5ddfa253c03f2e4a7)を書いたが、
それについてコメントにてリファクタリングを受けたので咀嚼を行いたい。

#おまじない

```py
if __name__ == '__main__':
```

上記記述は、importされた時に内容が実行されることを避けるための記述である。
（https://blog.pyq.jp/entry/Python_kaiketsu_180207 ）

#しりとり判定部分

```py
def is_according_rules(word_list, last_word, next_word):
    if next_word[-1] == 'z' or next_word not in word_list:
        return False  # zで終わる発言、単語リストにない発言はNG(False)
    if last_word is None:
        return True  # 直前の発言がない/違反なら、どれでもOK(True)
    return last_word[-1] == next_word[0]  # しりとりしてるならOK、さもなくばNG
```

orはinより優先度が低いため、括弧は必要ない。
（https://www.javadrive.jp/python/num/index3.html）

Noneとの比較はisを使用する。
（https://qiita.com/i13602/items/6d8914e019c13e858c72 ）と（https://www.python-izm.com/tips/difference_eq_is/#None）

return下に計算式や判定文を書くことで変数やif文を省略できる。

#プレイヤー処理部分

```py
def trace_spoken_words(number_of_members, word_list, spoken_words):
    alive_members = list(range(1, number_of_members + 1))
    available_words = word_list.copy()

    last_word = spoken_words[0]              # 最初の人の発言
    available_words.remove(last_word)        # 使用可能単語から最初の人の発言を削除
    member_index = 1                         # 最初に発言する人のインデックス番号

    for next_word in spoken_words[1:]:       # 次の人から発言を辿る
        if is_according_rules(available_words, last_word, next_word):
            last_word = next_word            # ルールOKなので最後の発言にする
            member_index += 1                # 次の人へ(インデックス番号を次へ)
        else:
            last_word = None                 # ルールを破ったので発言は無効
            del alive_members[member_index]  # ルールを破った人を外す
            # member_index += 0              # 次の人へ(インデックス番号は同じ)
        member_index %= len(alive_members)   # インデックス番号が越えたら0にする
        if next_word in available_words:
            available_words.remove(next_word)

    return alive_members
```

forはin内の様々な型を対象にループを行う。
（https://arakan-pgm-ai.hatenablog.com/entry/2018/12/05/090000 ）

~~疑問：1人目の違反は判定可能？~~　
リファクタリング本人様よりコメントがありました。1人目についても判定できるよう改良されています。

#メイン部分

```py
def solve():
    N, K, M = map(int, input().split())  # N:人数 K:単語数 M:発言数
    d = [input() for _ in range(K)]      # 単語リスト
    s = [input() for _ in range(M)]      # 発言ログ

    alive_members = trace_spoken_words(N, d, s)

    print(len(alive_members))
    for member_number in alive_members:
        print(member_number)
```

アンダースコア1個の変数名は、使用しない使い捨て変数であることを示す。
~~その他プライベートな変数の先頭にはアンダースコアを付けることが推奨される。~~
プライベートメンバ名には最初にアンダースコアを1個付けるが、
関数内のローカル変数は外部からアクセスできないのでアンダースコアを付ける必要はない。
予約語や定義済関数名との衝突を避けるときは、変数名の後にアンダースコアを1個付けます。
~~（https://pep8-ja.readthedocs.io/ja/latest/#id24 ）~~

#感想
不必要な変数を定義しないことが徹底されている。
変数の命名が本人でなくてもわかりやい。

非常に勉強になりました。shiracamus様、ありがとうございました。
備忘録：Content-typeについて

#Content-typeでつまずいたのでメモっておく
###1. そもそもContent-typeってなんぞや  
  - Content-typeとはファイルの種類を表すもの
  - HTTPヘッダの項目
  - 文字エンコードの指定もできる  

###2. Content-typeには種類がたくさんある
  - `text/plain`や`application/json`など
  - /の前半部分はデータの大まかな種類を表す。   
  `text`ならテキストだし、`image`なら画像  
  `application`はその他（何かのデータ）
  - /の後半部分はより詳しいデータの種類を表す。  
  `text/plain`はテキストファイル,`text/csv`ならCSVファイル  

###3. つまづいた箇所
  - POSTでbodyのデータを送る時にContent-typeに
  `application/json`か`application/x-www-form-urulencoded`のどちらで送るべきなのか
  - `x-www-form-urlencoded` では a=1&b=1 のようなクエリパラメータの形（URLエンコードあり）
  - `application/json` では {"a":1,"b":2} のようなJSON文字列でデータが送信されます。
  - node.jsのExpressを実装する際に、Content-typeを指定せずにPOSTしていたので、値を取得できなかった
 
###4. どっちでPOSTするほうが良いのか？
- jsの`axios`のデフォルトでは `Content-type: application/json` で送信するためフロントがjsで実装する今回のケースではこれを使った方が良さそう
  - ちなみにPHPだと$_POST が Content-type: application/x-www-form-urlencoded  
    または multipart/form-data を受け取るらしい（参考:https://qiita.com/Kunikata/items/2b410f3cc535e4104906）
単純な冪等性にかわる新しい哲学が、構成管理には必要だという話



先日、個人開発のOSS - [Submarine.js](https://gitlab.com/mjusui/submarine/tree/v1.0)のv1.0をリリースしました [記事はこちら](https://qiita.com/mjusui/items/889c0e55dc17ea8f29f2)

Ansibleの冪等性に関する [Tweet](https://twitter.com/Mjusui/status/1175387534076989441) が、結構な反応をいただけたこともあり、今回は、私がSubmarine.jsで克服したかった「冪等性の限界」と、それを、どのような哲学で解決しようとしているかについて、説明しようと思います


# 冪等性の理想と現実

そもそも冪等性とは? という話は、各所で説明されていることなので簡単に

* 冪等性とは
  * 同じ操作を何回実行しても、同じ結果が得られること
  * インフラの構成管理の世界では、何回同じコードを実行しても、同じサーバの状態が得られるという意味で使われる
  * Webの世界ではHTTPのGETやPUTメソッドは冪等だけど、POSTは冪等ではないなどと言われる

Ansibleでは、この冪等性を簡単に実現するために、目的に応じて膨大な数のモジュールが提供されています

* Ansibleのモジュール一覧  
  https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html

Ansibleを使って構成管理をしているプロジェクトでは、これら膨大なモジュール群の中から、自分のやりたいことに合ったモジュールを探して、組み合わせて利用します

ところが、意外と自分のほしい機能がない(あるいは見つからない)ことがあり、そういうときにはshellモジュールなどを使って、冪等なコードを自前で書く必要があります

この「冪等なコード」というのが、結構複雑になりがちで、レビューやメンテナンスがしづらかったり、バグの温床になったりします

# 冪等なコードを書くために必要なこと

前述のように冪等性というのは、構成管理をする上で理想的な考えではあるけれども、実装上の困難が多いのも事実です

そもそも冪等なコードを実現するためには、以下のような3つの要件を、1度に実現する複雑な処理が必要です

* 冪等なコードの要件 (引用 : https://twitter.com/tmiki74306808/status/1175631407516807175)
  1. 在るべき状態の定義
  2. 現在の状態の確認手段
  3. 状態を移行するための手段

多くのことを1度にやろうとすると、大体うまくいかないものです


# Submarine.jsのアプローチ

Submarine.jsでは、まず上記の冪等なコードに必要な処理を、1度に実行するのではなく明確に分割しようと考え、現在の状態の確認手段を `query`、あるべき状態の定義(と確認)を `test`、状態を移行するための手段を `command`、として1つのクラスのメソッドとして定義できるようにしました

```Correct-server-state-with-ssh.js
const Submarine=require('Submarine');

const CorrectServerState=class extends Submarine {
  query(){
    return {
      file_content: String.raw`
        test -r /tmp/submarine/hogehoge \
          && cat /tmp/submarine/hogehoge \
          || echo 'File not readable' \
            >&2
      `,
    };
  }

  test(stats){
    return {
      file_content_is_hogehoge: stats.file_content === 'hogehoge',
    };
  }

  command(){
    return String.raw`
      mkdir -p /tmp/submarine \
        && echo 'hogehoge' \
          > /tmp/submarine/hogehoge
    `;
  }
 

}


const state=new CorrectServerState({
  conn: 'ssh',
  host: 'server1',
});
    


state.correct()
  .then(console.log);

```

上記のコードで `query` は、キーと値のセットを返します。値はサーバの状態を確認するShellScriptの文字列で、キーは単なる名前です
`test` は `query` で定義したShellScript群の実行結果が引数として与えられ、それらが、あるべき状態か否かの複数の判定項目を判定して、判定結果をキーと値で返します
そして `command` では、判定結果に応じて実行したいShellScriptを文字列として返します

こうして定義されたclassをnewするときに接続先のホストを指定して `correct` 関数を実行すると `query` を実行し、その結果を `test` し、あるべき状態でないときだけ `command` で定義したShellScriptが実行されるようになっています

また `command` を実行せず `query` だけ、あるいは `query` と `test` だけを実行する関数も用意されています ( `current` と `check` という関数です)

当然、これらの処理を複数のサーバで実行する方法や、複数classの処理を順番に実行するような機構もあります(ここでの説明は割愛しますが)

こうすることで、冪等なコードに一定の秩序が生まれます。Shellの中に書くif文もかなり減らせます。しかもサーバの状態を確認する処理と、サーバに変更を加える処理が分離されたことで、変更の処理が実行されるかどうかを安全に確認でき、メンテナンス性も向上しています。

また `command` を実装せず、テストのためだけに利用するなど、応用範囲も広がります


# その他、開発の経緯など

このSubmarine.jsのアイディアは、オブジェクト指向の世界で、CQS(コマンドとクエリの分離)や、その発展形であるCQRS(コマンド・クエリ責務分離)と呼ばれている考え方に触発されたものです

またJavaScriptを使って状態を管理するのはReact.jsやVue.jsに影響を受けています

HTTPの世界でGETやPUTとPOSTが明確に分けられていたり、データベースの世界ではCRUDのような概念があるように、インフラの世界でも「状態」を扱うのに適したフレームワークがあっても良いかなと思って開発してみました
boolean(ブーリアン)型とは

学習している際に初めて見た言葉でしたので参考にしながら自分なりに殴り書き
していきます。

##boolean型とは

boolean型とはtrue　falseのどちらかのデータが必ず入る事が決まっているデータです。
true false以外ははいりません。

（仮）

```java

public static boolean isHealthy(double bmi) {
    return bmi >= 18.5 && bmi < 25.0;
}
```

```java
if (isHealthy(bmi)) {
    system.out.println("健康です");
} else {
    System.out.println("健康ではありません");
}
```
[小ネタ] Xcode11でProject Navigator上でのOption+Clickの挙動変わった件

今までと違ってアクティブじゃないエディタでソースが開くようになって非常に気持ち悪かったのですがPreferenceから以前の挙動に戻せます.

デフォルトでこうなってるのを
<img width="507" alt="スクリーンショット 2019-09-22 13.26.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4206/56efad6e-4fc8-473a-9523-dfc1e63cabf8.png">

こうすると
<img width="523" alt="スクリーンショット 2019-09-22 13.26.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4206/2b76ff56-35b0-a791-dc38-4ad63267e7d0.png">

気持ち良い.
なぜかアンインストールできないアプリ

なぜかアンインストールできないアプリありますよね。
こんなかんじで、アンインストールのボタンが不活性なやつ。旧式の「プログラムと機能」画面でもコンテキストメニューがでない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11595/b64d97bf-357f-f1b5-7fc4-18489a34957c.png)

インストレーション情報はレジストリなので、とりあえず、レジストリエディタを起動してみてみましょう。

場所はこの配下。 ``HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall``
32bitだとこのあたり。``HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall``

GUIDとかさすがにわからんので、対象のアプリケーションのキーワードで検索して、対象のアプリケーションのインストール情報を探します。

私のPCの例だとこいつが対象ですね。

```
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\{F8B367DF-040B-4AE8-B974-1268FF676099}]
"AuthorizedCDFPrefix"=""
"Comments"="Bug reporting http://haroopad.userecho.com"
"Contact"="rhio.kim+haroopad@gmail.com"
"DisplayVersion"="0.13.1"
"HelpLink"=hex(2):68,00,74,00,74,00,70,00,3a,00,2f,00,2f,00,70,00,61,00,64,00,\
  2e,00,68,00,61,00,72,00,6f,00,6f,00,70,00,72,00,65,00,73,00,73,00,2e,00,63,\
  00,6f,00,6d,00,00,00
"HelpTelephone"=""
"InstallDate"="20190923"
"InstallLocation"="C:\\Program Files (x86)\\Haroo Studio\\Haroopad\\"
"InstallSource"="C:\\Users\\dharry\\Downloads\\"
"NoModify"=dword:00000001
"NoRemove"=dword:00000001
"NoRepair"=dword:00000001
"Publisher"="Haroo Studio"
"Readme"=""
"Size"=""
"EstimatedSize"=dword:00014eb9
"URLInfoAbout"="http://pad.haroopress.com"
"URLUpdateInfo"="http://pad.haroopress.com"
"VersionMajor"=dword:00000000
"VersionMinor"=dword:0000000d
"WindowsInstaller"=dword:00000001
"Version"=dword:000d0001
"Language"=dword:00000409
"DisplayName"="Haroopad"
```

なるほどね、``NoRemove``というキーがあるのね。こいつを消しましょう。生理的に不快なので``NoModify``と``NoRepair``も消しましょう。必要であればOSのリブートもしてください。

Windows10の新しいコンパネ画面だとなぜかまだアンインストールのボタンが不活性ですが、旧式の画面だとコンテキストメニューにアンインストールがでてきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/11595/f2a930da-0111-4ef4-c994-73857fcf161e.png)

これで消して終わり。よかったよかった。