OmniAICreator/Qiita-1.07M huggingface dataset:
ServiceWorker で困ったこと

# start_url

manifest.json中のstart_urlは、/で終わらないとディレクトリと認識しない
ChromeのF12->Application->Presentation->Start URLを眺めて気づいた。時間返せ

## どこに気をつける
- https://peixe.biz/junk/sw というURLがあって、
- https://peixe.biz/junk/sw/index.html とかが
- https://peixe.biz/junk/sw/manifest.json
- https://peixe.biz/junk/sw/sw.js
を作るとすると、

manifest.json中のURL表記に注意する。

正

```
"start_url": "https://peixe.biz/junk/sw/", 
```

誤

```
"start_url": "https://peixe.biz/junk/sw",
```

「注意する」じゃねーよ気づけよ(15分
日英翻訳スクリプト on コマンドライン

こんな使い方ができるコマンドラインのスクリプトを作りたかったんです、昔から。tejは作ったスクリプトの名前で*translate english japanese*。

```
$ tej en 翻訳 # enは日本語→英語のモード指定。
translation
$ tej ja translation # jaは英語→日本語のモード指定。
翻訳
```

vscodeでターミナルウィンドウを開いておいて、変数名決める時にぱぱっと叩くような想定です。

# はじまりはとある投稿から
[3 分で作る無料の翻訳 API with Google Apps Script](https://qiita.com/tanabee/items/c79c5c28ba0537112922)という投稿を読ませていただいたのがきっかけ。あとはこのAPIを叩くスクリプトを書くだけでいけそう！と思い立ちました。ありがとうございます。

# 概要
1. コマンドライン引数から翻訳する情報を受け取る
2. APIにポストして結果を出力する

作る環境はapiが叩ければなんでもいいんですが、手っ取り早くnodeにしました。

## コマンドライン引数から翻訳する情報を受け取る
やることは以下の2個。引数の処理です。

* 翻訳のモード（en->ja, ja->en）を確認
* 翻訳する内容を整形

重要なのはprocess.argvの仕様（最初2行のコメント）で、他は一例程度にご覧ください。

```javascript:tej.js
// コマンドライン引数はprocess.argvで取得。
// 0はnode、1はファイル名、2以降がコマンドライン引数

// 翻訳のモードを確認。コマンドラインから翻訳先(target)を受け取るので
// 翻訳元(source)を判定。
const tgt = process.argv[2];
let src = "en";
if (tgt === "en") {
    src = "ja";
} else if(tgt === "ja") {
    src = "en";
} else {
    // usage関数：使い方をconsole.logするだけの関数です。お好みに作って下さい。
    // 個人利用だしエラー処理なんざ必要ねぇ、というならいらないです。
    usage("Unexpected mode");
    return;
}

// 翻訳する内容を整形。arv[3]以降が翻訳する内容。
// コマンドライン引数はスペースごとに区切られて配列に格納される
//  → 英文だとバラバラになるので別途配列にまとめて、スペースでjoin。
let words = [];
for(let i = 3; i < process.argv.length; i++) {
    words.push(process.argv[i]);
}
const text = words.join(" ");

// 作成した情報をAPIを叩く関数に渡します。
trans(text, src, tgt);
```

# APIに送信して結果を出力する
やることは以下。

* URLとポスト用データを生成
* APIにポスト
* APIの返信結果を出力

今回は通信クライアントに[axios](https://github.com/axios/axios)を使いました。マニュアル通りに書いただけ！

```javascript:tej.js
const axios = require("axios");
const qs = require("qs");

const trans = (word, source, target) => {
    // URLの生成
    // api keyの取得方法は、前述の
    // 「3 分で作る無料の翻訳 API with Google Apps Script」
    // をご覧ください。
    const url = "https://script.google.com/macros/s/[api key]/exec";

    // ポスト用データの生成。
    // querystringしてContent-Typeを指定。こうしないとpostデータが空になります。
    // https://github.com/axios/axios#using-applicationx-www-form-urlencoded-format
    const params = qs.stringify({
        'text': word,
        'source': source,
        'target': target
    });
    const headers = {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    };

    // APIにポスト
    axios
        .post(url, params, headers)
        .then((response) => {
            // APIの返信結果を出力。何のてらいもないconsole.log。
            console.log(response.data);
        })
        .catch((error) => {
            // お情け程度のエラー処理。
            console.error(error);
        });
}
```

あとはエイリアスにでも登録しておしまい。例えばbash。

```bash:~/.bash_profile
alias tej='/path/to/node /path/to/tej.js '
```


# おわりに
「コマンドラインから引数を受け取る」「apiを叩く」という初歩的な技術を使っただけでできてしまったので、新規性は一切ないんですが…強いて言えばコマンドラインからapiを叩くスクリプトの雛形にはなっているかな、と思います。vscodeとの連携がなかなか便利だったので思わずの初投稿です。
Zabbix→OTRS連携

##■はじめに
Zabbixにて異常検知したらOTRSに起票するスクリプトを作成しました・・・・
エラー判定してないけど実装は有料だな
定数のところは適時変更してください。

##■環境
・OTRS-6.0.6
・Zabbix3.5

##■スクリプト配置
/usr/lib/zabbix/alertscripts/otrs.sh

~~~
#!/bin/sh

ticket_title=${1:-'タイトル'}
ticket_body=${2:-'本文'}


OTRS_IP="192.168.11.66"
OTRS_USER="＜OTRSのユーザ＞"
OTRS_PASS="＜OTRSのパスワード＞"

TICKET_TYPE="Unclassified"
TICKET_QUEUE="Raw"
TICKET_STATE="new"
TICKET_PRIORITY="5"
TICKET_CUSTOMER="test@gmail.com"

session=`/usr/bin/curl -s -X POST "http://${OTRS_IP}/otrs/nph-genericinterface.pl/Webservice/Ticket/login" \
              -d "{ \"UserLogin\": \"${OTRS_USER}\", \"Password\": \"${OTRS_PASS}\"}" | /usr/bin/jq -r '.SessionID'`



ret=`/usr/bin/curl -s -X POST -H "Content-Type:application/json" \
     -d "{ \"SessionID\":\"${session}\", \
     \"Ticket\": \
          {\"Title\":\"${ticket_title}\", \
           \"Type\": \"${TICKET_TYPE}\", \
           \"Queue\":\"${TICKET_QUEUE}\", \
           \"State\":\"${TICKET_STATE}\", \
           \"PriorityID\":\"${TICKET_PRIORITY}\", \
           \"CustomerUser\":\"${TICKET_CUSTOMER}\"}, \
     \"Article\":{ \
           \"Subject\":\"${ticket_title}\", \
           \"Body\":\"${ticket_body}\", \
           \"ContentType\":\"text/plain; charset=utf8\"} \
}" "http://${OTRS_IP}/otrs/nph-genericinterface.pl/Webservice/Ticket/TicketCreate" `
~~~

##■Zabbix登録
「管理」「メディアタイプ」から「メディアタイプの作成」を開く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/8fc813c6-0dc2-dc80-82c3-0f5337ff5f9f.png)

下記情報を入力して追加
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/9389848d-d04b-e670-3616-644e37978932.png)

「管理」「ユーザ」からAdminの「メディア」を開く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/fb1be83a-7c73-cea3-78cc-9b1ee257af15.png)

「追加」からスクリプトを登録する
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/b776c822-725f-ecee-8407-2caed5c3dc40.png)

「設定」「アクション」から「アクションの作成」を開く
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/93c14a65-28b4-9595-9cc0-114026599de8.png)

下記情報を入力して追加
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/7153b3ca-3b86-be12-0511-9eeb4d2d95f2.png)
※デフォルトメッセージに改行があるとエラーになるので改行を消すこと
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/8ecfc43b-404e-f89e-a452-90893cb121db.png)

##OTRS確認
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245351/245dacb0-c5de-2dbf-1268-44cf8ce117fe.png)

起票されましたねー
以上です。
マイページに写真のアップロード

①gemfileを追加

gem 'carrierwave'
gem 'mini_magick'

を追加
bundle update
bundle install

②サーバーをアップデート

③userモデルに
mount_uploader :image, ImageUploader
を追加

④userコントローラーのparamsに追加

private
  def user_params
    params.require(:user).permit(:name, :description, :image)
  end

⑤アプリケーションコントローラーにimageを追加
    devise_parameter_sanitizer.permit(:account_update, keys: [:kind, :nickname, :company, :tel, :sex, :birthday , :address, :image])
  end

⑥viewファイルに追加
<div class="field">
    <%= f.label :プロフィール画像 %><br />
    <%= f.file_field :image, autocomplete: "image", :multipart => true %>
</div>
Node.jsでLINEログインするコードを書いてみた

ITリテラシー低い人たち用にアカウント作成の敷居を下げたくて、LINEログイン使えないかなーと試してみた。
結論から言うとWebアプリの場合、結局メールアドレスとパスワードを入れる必要があるので微妙。

いつか使うかもしれないのでメモだけしとく。IDトークン取得しない版。
まったくエラーハンドリングしてないので実際に使うときはちゃんと入れること。

```javascript:login.js
const express = require('express');
const router = express.Router();

const request = require('request');
const co = require('co');

const base_uri = 'https://xxxxx';
const client_id = '9999999999';
const client_secret = 'abcdefg0123456789abcdefghijklmno';

function getUUID() {
  const l = 8;
  const c = "abcdefghijklmnopqrstuvwxyz0123456789";
  const cl = c.length;
  let r = "";
  for(let i=0; i<l; i++) {
    r += c[Math.floor(Math.random()*cl)];
  }
  return r;
}

function getToken(params) {
  return new Promise((resolve, reject) => {
    request.post(params, (error, response, body) => {
      if(error) {
        reject(error);
      } else {
        resolve(body);
      }
    });
  });
} 

router.get('/', function(req, res, next) {
  const rParams = req.query;

  if(rParams.code) {
    // 認可コード取得のコールバックでここに来る
    co(function*() {
      const auth = {
        code: rParams.code,
        state: rParams.state,
      };
  
      // アクセストークン取得
      const token = yield getToken({
        uri: 'https://api.line.me/oauth2/v2.1/token',
        form: {
          grant_type: 'authorization_code',
          code: auth.code,
          redirect_uri: base_uri,
          client_id: client_id,
          client_secret: client_secret,
        },
        json: true,
      });

      res.send(token);

    });
  } else if(rParams.access_token) {
    // アクセストークン取得後のコールバックでここに来る

    res.send(rParams);

  } else {
    // 初回アクセス時はここに来る

    const url = 'https://access.line.me/oauth2/v2.1/authorize';
    const sParams = [
      'response_type=code',
      `client_id=${client_id}`,
      `redirect_uri=${base_uri}`,
      `state=${getUUID()}`,
      'scope=profile',
      'nonce=my%20app',
    ];

    // 認証画面へリダイレクト(認可コード取得)
    res.redirect(`${url}?${sParams.join('&')}`);

  }

});

module.exports = router;

```

UUID取得はこちらを使わせていただきました。
https://qiita.com/ryounagaoka/items/4736c225bdd86a74d59c
NokogiriでXMLパースするときにはencodingに気をつけろ！

ちょっと嵌ったので備忘録

```ruby
Nokogiri::XML(string)
```

でファイルから読み込んだXML文字列をパースしていたんだけど、どうも途中で尻切れになってしまって最後まで読み込めなかった。早速疑ったのはencodingだったけど、ズバリそうでした。
xmlの冒頭に 

```xml
<?xml version="1.0" encoding="Shift-JIS"?>
```

なんてなっている場合は以下のようにエンコード指定しないとうまくいかない。
本当はうまく行くはずなんだけど、今回はSJISには存在しない全角マイナスが含まれていた。
どうやらWindowsユーザーは俺のコードはSJISだ！と勘違いしてるようである。
Windows3.1以降の文字コードはCP932である。

```ruby
Nokogiri::XML(xml, nil, 'CP932')
```

ってことで明示的にエンコードを指定して解決したけど、Nokogiriも例外出してくれればいいのになぁ。
vBox上のVMとのSSH通信をするためのネットワーク設定

# 目的
- vBoxのVMに対してNAT設定をした際にSSH通信ができないことがあり、その解消方法を検討と同様に困っている人がいたのでその説明も兼ねて〜
- 記事を書く練習（笑

# 前提
- vBoxインストール済とする（Verは5/3現在で最新のもの）
- VM（Linux7で最小構成、ネットワークアダプタ1へNAT設定）をインストール済とする
- 追加設定から行うためVMは電源OFFしている状態とする

# 捕捉
- Lunux - vBox - VM構成で記事を書いているため、WindowsOSやMacOSとの差異は御勘弁を
- 画像加工はいったん諦めた（後日修正する予定


# 目次
1. ホストオンリーアダプタの作成
2. ホストオンリーネットワークの追加とDHCPサーバの有効化
3. 停止中のVMへネットワークアダプタ2を追加
4. ホストオンリーアダプタで有効化したIPアドレスへSSH接続を実施

## 1. ホストオンリーアダプタの作成

![Screenshot from 2018-05-02 16-33-44.png](https://qiita-image-store.s3.amazonaws.com/0/96374/c1ce6b07-36b5-3a7e-114e-6a656588e922.png)

### 手順1-1

- [ファイル]を選択し[ホストネットワークマネージャー]を選択

## 2. ホストオンリーネットワークの追加とDHCPサーバの有効化

![Screenshot from 2018-05-02 16-54-32.png](https://qiita-image-store.s3.amazonaws.com/0/96374/921ab1e1-e9d6-2372-bcdf-09795e7db97d.png)

### 手順2-1

- [ホストオンリーネットワーク]を追加するために[作成]を選択
- [DHCPサーバ] を有効化
- 詳細設定をこなうために[プロパティ]をクリック

![Screenshot from 2018-05-02 16-54-27.png](https://qiita-image-store.s3.amazonaws.com/0/96374/3ea9da79-c9f9-6f09-cf68-44812e8b23fd.png)

### 手順2-2

- アダプタータブで[アダプターを手動で設定]を選択 ※自動でよければそのままで
- DHCPサーバタブで[サーバーを有効化]にチェックを入れる

ここまでがvBoxでの設定です
以下からがVM対しての設定となります

## 3. 停止中のVMへネットワークアダプタ2を追加
![Screenshot from 2018-05-03 14-30-52.png](https://qiita-image-store.s3.amazonaws.com/0/96374/ffbf7903-c102-c392-4f6f-9e7727cba1f2.png)

### 手順3-1
- VMを選択し[設定]ボタンをクリック

![Screenshot from 2018-05-02 16-43-54.png](https://qiita-image-store.s3.amazonaws.com/0/96374/26d2f718-a97e-860f-c747-c275d1a389f3.png)

### 手順3-2
- Linux設定画面にある[ネットワーク]を選択
- [アダプター1]タブを選択肢
- 割り当てがNATになっていること確認

![Screenshot from 2018-05-02 16-44-13.png](https://qiita-image-store.s3.amazonaws.com/0/96374/f6208cdf-e7d8-54e4-8cda-b419afe019f2.png)

### 手順3-2
- [アダプター2]タブを選択肢
- [ネットワークアダプターを有効化]にチェックを入れる
- 割り当て項目を[ホストオンリーアダプター]に変更
- 高度設定の中にある[Macアドレス]を控えておく※VM上で確認が楽です
- [OK]をクリックし画面を閉じる
- 任意：高度項目については初期値で問題ないが必要に応じて変更を行うこと

ここまでがVMに対しての設定
最後はVM起動後のIPアドレス確認とSSHで接続の確認をする

## 4. ホストオンリーアダプタで有効化したIPアドレスへSSH接続を実施（確認だけ）

![Screenshot from 2018-05-03 14-12-13.png](https://qiita-image-store.s3.amazonaws.com/0/96374/103ebf68-d91a-695a-bed8-7ac5299d4540.png)

ホストOSに設定されているIPアドレスを確認
今回の場合だと10にある[xboxnet0]がVMへの出入り口になっている

![Screenshot from 2018-05-03 14-18-29.png](https://qiita-image-store.s3.amazonaws.com/0/96374/ff94cd61-5c2c-e16d-1454-40f0d87249c2.png)

使用している画像がDHCPでIPアドレスを取得した状態ではなく固定で振り直したIPアドレスが
2の[enp0s8]にて確認ができる
またMacアドレスは手順3-2で確認したものと同じもが表示されている


## 所感
NW設定は他にも色々あるが個人が検証で使用するのならこのくらいでOKかなと考えてはいるが、
物理ポートと内部の処理がどのようになっているのかは別で説明する必要あるかな？
あとxBoxソースも見つけたので前々からためしてみたい事をするかは別途検討？？
Linux6と7の主要コマンドのまとめはSIOSにて説明されているので端折ります〜

久しぶりの直す箇所は多々あるけど一旦はこのままリリース
細かい所は後日手直しをおこなっていく感じで

## 参考
[centos7にvirtualboxをインストールする](https://qiita.com/kite_999/items/924dc15f9bf2d34a8e94)
[Markdown記法 チートシート](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)
[vBoxマニュアル](https://www.virtualbox.org/manual/ch06.html)
[RHEL6→RHEL7で変更された主要コマンドまとめ](https://oss.sios.com/yorozu-blog/rhel6-rhel7change)
【今日から携わる】Gitコマンドの使い方（クローン〜コミットまで）sourcetree使うのやめました。

新技術に今日から携わる人のためのマニュアル（Gitコマンドの使い方編）
今までsourcetreeを使っていたコーダーが、gitコマンドでの案件に対応したくてコピペでいけるコマンドリストをつくりました。

# 環境
PCはMacを使用。

# 想定
・クローンしてない案件の修正依頼がきた場合
・クローンしてある案件の修正依頼がきた場合


# クローンしてない案件の修正依頼がきた場合

```html:準備
空のフォルダ作成
ターミナルを開いて、作成した空のフォルダに移動
```

```html:ディレクトリ見本
Documents/
　└ www/
　　└ client01/　 （クライアント名）
　　　├ design　　（デザインデータを格納）
　　　├ material　（素材や情報を格納）
　　　└ source　　（コーディングデータを格納）← 今回作成する空フォルダ
```

準備ができたら、以下の　クローン〜プッシュ　８つのコマンドでOK！

## clone 

```html:command.01
git clone [[リモートリポジトリのパス]]
```


## checkout:new branch
新しいブランチにチェックアウト

```html:command.02
git checkout -b [[ブランチ名]]
```


## branch
作業ブランチに移動(チェックアウト)できているか確認

```html:command.03
git branch
```

## 修正作業を行う


## status
変更したファイルの一覧を確認する

```html:command.04
git status
```


## diff
該当ファイルの変更内容を確認する

```html:command.05
git diff [[ ファイル名 ]]
```


## add
ステージングに上げる

```html:command.06
git add [[ ファイル名 ]]
```


## commit

```html:command.07
git commit -m “コミットメッセージを記入”
```


## push

```html:command.08
git push origin [[ ブランチ名 ]]
```




# クローンしてある案件の修正依頼がきた場合
ブランチ確認〜プッシュ　９つのコマンドでOK！

## branch
現在のブランチの情報を確認

```html:command.01
git branch
```

## checkout master
もし作業ブランチのままだったら、masterブランチに切り替える

```html:command.02
git checkout master
```

## fetch
最新のリモートリポジトリの状態を、ローカルに反映させる
（p：remoteで消されてるブランチはローカルでも削除する）

```html:command.03
git fetch -p
```

## pull

```html:command.04
git pull origin master
```


## checkout:new branch

```html:command.05
git checkout -b [[ ブランチ名 ]]
```


## branch
作業ブランチに移動(チェックアウト)できているか確認

```html:command.06
git branch
```

## 修正作業を行う

## add
ステージングに上げる

```html:command.07
git add [[ ファイル名 ]]
```


## commit

```html:command.08
git commit -m “コミットメッセージを記入”
```


## push

```html:command.09
git push origin [[ ブランチ名 ]]
```



# その他

## 既存のfeatureブランチをローカルに引っ張ってくる場合
```html:command
git checkout -b [[ ブランチ名 ]] origin/[[ ブランチ名 ]]
```


##[git reset (--hard/--soft)]ワーキングツリー、インデックス、HEADを使いこなす方法
https://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe

# 参考
> git push の取り消し方法
http://www-creators.com/archives/2020

> 君には1時間でGitについて知ってもらう(with VSCode)
https://qiita.com/jesus_isao/items/63557eba36819faa4ad9
誤って消したStashを元に戻す

gitって凄いね。

```console
// stashをdropした時に以下のような半角英数字を組み合わせた文字列が出てくる
$ git stash drop stash@{6}
Dropped stash@{6} (b833c777a8e16dcfd11f7e41f575662bdec52d32)
```

```
// 上記の文字列を指定して以下コマンドを実行
$ git cherry-pick -n -m1 (b833c777a8e16dcfd11f7e41f575662bdec52d32)
```

基本的にはこれで戻るぽい。

http://keisukeohta.hatenablog.com/entry/2016/03/31/185009
Crontabでtcpdumpを設定しようと思ったら、フルパスが必要だった

#ネットワークエンジニアがcrontabを設定しようと思ったら、ハマったのでシェア

普段サーバを触っている方なら当たり前だと思いますが
障害対応で、サーバにcronを仕込む必要が出た際にハマったのでまとめます。

#最初に作成したスクリプト

作りたかったスクリプトとしては、決まった時間にアプリからよく分からないパケットが出ているようなので
cronでtcpdumpを仕込んで、どんな通信が行われているか裏を取りたいものでした。

作成したシェル

```false.sh
#!/bin/bash

tcpdump -i eth0 -n -W 1 -G 3 -w /home/ec2-user/tcpdump/log/td-`date +%Y%m%d-%H%M%S`.pcap
```
cronの記載

```crontab
45 04 * * * /home/ec2-user/tcpdump/false.sh
```

cronにシェルを実行登録し、シェルはtcpdumpを数秒動かすだけの簡単な作りです。

ただ、実際に動作させると分かりますが、このCronとシェルの書き方では、tcpdumpは動作しません。
手でシェルを叩くとログ取得できるのに、cronだと出来ない。何故か?しばらく悩みました。

```
ll /home/ec2-user/tcpdump/log/
total 0
```

cronの時間が来てもログが出力されない。。。

#Cronはパスの見え方が違う

crontabにはフルパスで。
http://d.hatena.ne.jp/k_k_yuta/20100128/1264694207

crontabの環境変数PATHについて調べてみた
http://dqn.sakusakutto.jp/2014/04/crontab_path.html

これらのサイトが役に立ちました。
crontabはユーザのパスが通っておらず、フルパスでの記載が推奨とのこと。

#早速フルパスに修正

tcpdumpのフルパスを調査

```
which tcpdump
/usr/sbin/tcpdump
```

私の環境でtcpdumpのフルパスが「/usr/sbin/tcpdump」と分かったので、スクリプトを修正

```true.sh
#!/bin/bash

/usr/sbin/tcpdump -i eth0 -n -W 1 -G 3 -w /home/ec2-user/tcpdump/log/td-`date +%Y%m%d-%H%M%S`.pcap
```
cronの記載(時間だけ変更)

```crontab
08 05 * * * /home/ec2-user/tcpdump/true.sh
```

時間が来てログを確認してみると。。。

```
ll /home/ec2-user/tcpdump/log/
total 4
-rw-r--r-- 1 root root 986 May  3 05:08 td-20180503-050801.pcap
```

無事にログが出力されました!!!

crontabで何故とユーザのパスが読み込まれないかは、疑問として残っているので
気が向けば調べようとおもいます。
スプレッドシートのコメントを検索する方法

## なぜコメントを検索するか
スプレッドシートのコメント検索機能の開発を希望されている方がおり、そこから実現方法を探しました。自分では使う機会はあまりないですが、気になったこともあって調べることにしました。

## 調べてみた
実現方法としてスクリプトエディタでコメントを検索するコードを書くのが一番いい方法だろうと考えていました。が、調べてみると「コメント」の操作は推奨されなくなっていました。
https://teratail.com/questions/43862
代わりに「メモ」の操作があります。そもそも方向性が変わってきているのか？と、別のやり方を提案した方がいいのではないかという考えに至ります。

でも、ツールバーに配置されているのはコメントなので、使い勝手がいいのはコメントの機能となるのが自然です。
![Screenshot_2018-05-03_13-56-37.png](https://qiita-image-store.s3.amazonaws.com/0/48817/1bfe4a1c-3967-3cb9-043c-b346dd6ac0c8.png)
このアンバランスな実装はなんだろうなぁ、とイラッとしました。

## もう少し調べてみた
「サイドバーのコメントセクション」というキーワードを見つけました。見つけた記事は少し古いらしく、今は「コメントスレッド」という立ち位置で存在するようです。
![Screenshot_2018-05-03_13-45-29.png](https://qiita-image-store.s3.amazonaws.com/0/48817/fa0e5bf2-01d2-5f11-667d-aeaa31c41bdd.png)

ここをクリックするとコメントの一覧が出てくるので、ブラウザの検索機能を使えばコメントの全文検索ができてしまいます。コメントをクリックすると該当セルが選択された状態になります。
これらの機能を使うにあたって、スクリプトに頼らず実施することの要望が大きかったんでしょうね。

## おわりに
どんどん便利になっていきますね。次はメモの一覧表示機能も実装されるんでしょうか。スクリプトエディタでの実装前に、少し調べてみるといいかもしれないですね。
Macのスピーチ機能の音声が面白かったって言う小話

技術的な話ではないのですが、面白かったので共有できればなあと思って。小ネタですが。

# Macのスピーチ機能について

Macで、ドラッグ＆ドロップで単語(文章)を選択し、右クリックすると出てくるメニューの中に*スピーチ*という項目があります。
これを押すと、機械音声がその単語(文章)を読み上げてくれるわけです。
この読み上げの音声については様々な言語で対応しており、「設定」アプリの`アクセシビリティ -> ”視覚"`にある「スピーチ」欄で追加することができます。
基本的に、各言語男女の音声が複数収録されています（一部、女声のみ・男声のみもあるようです）。
が、英語だけちょっと特殊なことになっています。

# "英語（アメリカ合衆国）- その他"　という括り

各言語、国ごとに違いがあることもあるので国別に声が分かれているところもあり、その上で男女にも別れているところもあるのですが、アメリカ合衆国だけなぜか、*その他*というカテゴリが存在します。
何でしょうね。ワクワクしますよね。（するよね！？）
ちなみにこれ性別の問題じゃないです。うん。

**いろんな意味で凄いボイスが収録されてます。**
機械音声だとかなんだとかetc...
夜中聞こえたら怖そうだねってのもあったけどね()


# って言うだけの記事です。

うん。試してみてねっていう。
終わり。
モバイル環境でのHTML5ゲームはPWAに進んでいくのだろうけど…

先日、モバイルHTML5ゲームプラットフォームである[enza](https://enza.fun/)と、アイマス新作のシャニマスこと[THE iDOLM@STER SHINY COLORS](https://shinycolors.enza.fun/)がリリースされました。
1人のPとして、Web系エンジニアとして、いろいろと楽しみにしていました。

これまでモバイルのHTML5ゲームは

- 動作が重い
- 画面方向が固定できない
- 通信量が多い
- ネイティブより表現力がチープ
- バッテリー消費量が多い

など、様々な問題を抱えていました。
いわゆるガワネイティブ、ネイティブアプリのWebview上でHTMLをレンダリングするゲームはあっても、ブラウザ上で動作する本格的なHTML5ゲームがグラブルくらいしか話題に上がらなかったのはこういう問題があったからです。グラブルも動作を軽快にするためにいろいろと小細工しているようですし。
リリースすら出来ずにぽしゃったゲームとしては[ラプラスリンク](http://nlab.itmedia.co.jp/nl/articles/1704/25/news142.html)などと言うものがありました。もう公式サイトすら残っていません。動作が重かったのと、開発に時間がかかりすぎて陳腐化したのが原因とかなんとか…。
で、バンナムがこのあたりをどのように改善してくるか楽しみにしていたわけです。
そして蓋を開けてみると…

- （そのままだと）動作が重い
- （そのままだと）画面方向が固定できない
- （そのままだと）通信量が多い
- バッテリー消費量が多い

…但し書きがついただけでほとんど何も変わってないですね。
で、結局推奨環境ではないものの動かすことの出来るPCブラウザ上でプレイしたりするわけです。
ゲームとしては、難易度の高さやオーディションの雰囲気から、近代化改修したアケマスだと個人的には思っていますが、それは本題ではないのでおいておきます。

本題は但し書きの方です。
（そのままだと）
そう、今は解決策があったりなかったりします。
Googleが強く推している[プログレッシブウェブアプリ](https://developers.google.com/web/progressive-web-apps/)です。
先読みキャッシュや画面方向固定が可能なのでブラウザでそのままプレイするよりはずいぶん快適にプレイすることが出来ます。ストアに行かなくていいというのも地味にいい点ではありますね。特にiOSではApp Storeの諸々に悩まされることも多いですから。（おそらくバンナムがenzaを立ち上げたのもその辺に理由があるのではなかろうかと…）

ただ、PWAは結局の所Webアプリで、インストール前の評価としてブラウザ上でプレイするというワンクッションが入りますし、そのままブラウザでプレイし続ける人も多いと思われます。そのときに、縦画面でのプレイを事実上制限してしまっていいのか、重い状態を晒してしまっていいのか（重さにはおそらくWebGLに起因するものも含まれる）、通信量の多さをそのままにしてしまっていいのか、などなど、かなりの問題があります。あといずれにせよバッテリーはものすごく食います。
まず改善しなければならないのは日本では非常に限られた資源であるところの通信量からでしょうかね…。
ネイティブでは圧縮したアセットを一括ダウンロード可能なんですが、さてPWAひいてはHTML5ではどのようにしたものか…。
最速のソート

ソートの本に最速のソートというのを載せています。
ネタ的には何らかの名前がついていると思うのですが、ちょっとわかりませんでした。

最速のソートとは、比較を使う他のソートアルゴリズムと比べて
・最悪パターンの比較数が最も少ない
・並び替えの為に使う読み込みと書き込みが最も少ない
という特徴を持つソートです。

時間計算量はO(n logn)、空間計算量はO(1)またはO(n!)です。

O(1)とO(n!)って天と地ほどの差がありますが、空間計算量の定義によります。
実際、プログラムが動き始めればメモリ使用量はごく僅かです。
しかし、その動かすプログラムのサイズがO(n!)です。

つまり、プログラムで二分木探索を行い、現在の配列がどの並び順かを特定し、
並び順がわかればそれを最も適した形で入れ替えてソートします。
4個の要素を並び替えるのなら、if文が4!-1=23個存在します。

もちろん、4個の並び替えに特化してますから、
8個を並び替えたいときは専用に別のプログラムを用意します。

で、こういうジョークソートを話していたら、プログラムを作ってくれる人がいました。
[最速のソート](https://www.omoteura.org/program/001_FastestSortw.html)

さて、実行結果ですが…超絶遅いです。
C++のstd::sortの方が何倍も早いです。

理由は、CPUキャッシュでしょう。
プログラムサイズが肥大化しているわけですから、
キャッシュ効率が超絶悪くなっていると思われます。

やはり時代を先取りしすぎたアルゴリズムでしたね。
Cordovaでハイブリッドのテンプレ作るまでまとめ(Cordova+OnsenUI+vue.js)

最近職場の人間と余暇を使ってサービス作りをしているのですが、そこで低コストに素早いリリースをするためには、という観点で色々検証しています

# なぜCordova＋OnsenUI＋vue.js？

余暇でのサービス作りですのでiOS, androidで別々のリソースは割けない、かつソリューション自体にお金をかけたくない…です
というわけでまずはマルチプラットフォームの実現方法としてCordovaを採択しました

あとはどんだけ楽してUI作るかという話なのですが、今作ろうとしているものの見えている要件はそこまで複雑ではありません、Javascriptを書くにあたりAngularかReactかという議論はあれどもどちらもそこそこ学習コストがかかります
あとでメンバを追加することを考えると学習コストがかかるソリューションはあまり得策ではありません

というわけで適当に作れるOnsenUIと学習コストを少なくするべくvue.jsの組み合わせで作り始めています
もちろん作る過程で要件が複雑化した際にはReactへの切替も検討しますが、今のところはこれで十分なはず

# どうやってテンプレを作るか

Facebookの開発者登録は必要ですが、何も考えないで下記を実行すればFacebookへのログイン機能を備えたテンプレが作成できます(node)
FacebookのAPP_IDとかの割り出しについては[ここ](https://developers.facebook.com/docs/apps/register?locale=ja_JP)あたりを参照すれば良いでしょう

```
$ npm install -g vue-cli
$ vue init OnsenUI/vue-cordova-webpack my-project
$ cd my-project
$ npm install
$ cordova plugin add cordova-plugin-facebook4 --save --variable APP_ID="１２３４５６７８９０" --variable APP_NAME="your_app_name"
$ cordova platform add ios
$ cordova platform add android
$ npm run build
$ cordova prepare
```

vue.jsを取り扱うためのvue-cliを使ってCordova用のテンプレを引っ張ってきてそのテンプレ上でプラグインの追加、各プラットフォームの追加を行います
その後、Javascriptのビルドを実施して、Cordova用にファイルの配置を行っています

# gitignoreの設定

gitignoreは下記のように設定しました

```
.DS_Store
node_modules/
/dist/
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# iOS
platforms/ios/build/
platforms/ios/www/
platforms/ios/cordova/console.log
*.xcuserdatad

# android
platforms/android/assets/www
platforms/android/bin
platforms/android/gen
platforms/android/local.properties
platforms/android/ant-build
platforms/android/ant-gen
platforms/android/CordovaLib/ant-build
platforms/android/CordovaLib/ant-gen
platforms/android/CordovaLib/bin
platforms/android/CordovaLib/gen
platforms/android/CordovaLib/local.properties

plugins/

# res
resources/signing

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
```

# 補足

npmを使うためにnodeを使いますが、バージョンが入り乱れているので、バージョンは使い分けを行っておいた方が良いでしょう
[nvm](https://github.com/creationix/nvm)や[nodebrew](https://github.com/hokaccha/nodebrew)などを使うと幸せになれるかもしれません
[Stanメモ]概要編(コードは無し)

ども。久しぶりの投稿です。

今更ながらベイズでのパラメータ推定をしっかり学んでみようと、
[アヒル本](https://www.amazon.co.jp/StanとRでベイズ統計モデリング-Wonderful-R-松浦-健太郎/dp/4320112423)を読み進めて、一旦いいところまで来たので自分用思考整理メモ。

まぁ、数多あるStan解説blog/メモblogの一つだと思っていただければ・・・
なお、コードとかの話よりは概念に近いです。
余裕があったら別エントリでコード載せるかもしれません。

# Stanとは

Stan とは MCMCを用いたパラメータ推定の為のソフトウェアー。
HPはこちら[Stan](http://mc-stan.org)、アヒル本にあるようにRで使う人は[RStan](http://mc-stan.org/users/interfaces/rstan)を、Pythonユーザーは[PyStan](http://mc-stan.org/users/interfaces/pystan.html)をどうぞ。

Stan 自体はC++で書かれているコンパイル型なのですが、[色々な言語に対応している](http://mc-stan.org/users/interfaces/)ようで、MatlabやJuliaにも対応しています。

ですが、SinyStanやrstantoolなど、拡張ツールがRベースなので、基本的にはRと親和性が高いのだと思います。

# 何ができるの？
MCMCのchainを複数生成し、chainからサンプルされた分布を用いて、回帰式などのパラメータの推定ができます。ベイズによるパラメータ推定(と言っていいのか？)です。

## ベイズによるパラメータ推定とは
パラメータの推定法(最小二乗法、最尤推定、ベイズ推定)はそれぞれ噛み砕くとこういった思想だと解釈しています。

最小二乗法「回帰式から得た予測とモデルの差を最小にするものが良いパラメータである」
最尤推定の「得られたサンプルの分布(ヒストグラムなどで確認できる)に一番当てはまりのいいものがよいパラメータである」
ベイズ推定「平均などのパラメータは確率分布しており、その分布(事後分布)は事前分布と尤度の積に比例しているよ」

[R.A.フィッシャー](https://digital.library.adelaide.edu.au/dspace/handle/2440/3860)以来のメインストリームである「真の平均/母集団の平均は一定である」と言う思想に対して、

ベイズ推定は「真の平均も一意ではないよ。確率的に定まっているよ」と言う考え方を採用して作られている為、割と思想の根本で対立していますが、まぁ実務面では現実に起きている現象を適切にモデル化できればなんだっていいわけで、その辺は学会の専門家に任せたいと思います。

## MCMC 法とchainが収束するは？
Markov Chain Monte Carlo 法が正式名称です。MCを使ったMC法の事です。
丁寧に話すと、

MC(マルコフ連鎖)1時点前の確率変数にのみ依存し現在の値が決まる確率過程です
MC(モンテカルロ)乱数を使ったシミュレーション/数値推定方法の全体です

ん？まだ難しい？そんな人は

[マルコフチェイン](https://dev.classmethod.jp/machine-learning/markov-chain/)
[モンテカルロ法](https://mathtrain.jp/montecarlo)

を見てください。ともあれ、MCMCとはマルコフチェインを使ったモンテカルロ法の事です。
ぶっちゃけた話、直感的には難しいことしてなくて、無茶苦茶たくさん乱数ベースのシミュレーションして、そこからパラメータの分布(事後分布)を推定しようぜー。って話です。

パラメータ推定には複数のchainを生成し、収束した部分のサンプルを抽出して利用します。
なので、以下の注意点があります。

・収束していない段階のサンプル(warm up)を使ってはならない
・chainが収束しない事もあるので、その場合は推定してはならない

上は一度図を見れば理解できるともいます。	アヒル本や緑本などで確認できるので本屋で探して見てください。
下は少し説明します。

MCと言うのは、状態とその遷移を確率的に表した確率遷移行列で表現されていて、[Wikipediaのここ](https://ja.wikipedia.org/wiki/マルコフ連鎖#定常状態と極限分布)を覗いてもらいたいのですが、既約なマルコフチェーンは定常過程に収束します。

既約とは、「全ての頂点が互いに繋がっている」つまりステップをたくさん踏めばマルコフ連鎖内にある全ての状態から別の状態にたどり着ける形であり、これは「確率遷移行列が収束する」状態です。

ここで注意しておきたいのが、既約であっても収束しない状態があると言う事です。この場合は「確率線維行列に周期性がある」状態です。

他方、既約でない場合はchainが収束しないので、パラメータの確率分布が一意に定まらないことを示しています。分布が一意に定まらないのに推定しちゃダメってことです。

RStanでは、パラメータ推定時にうまく収束したかどうかについては Rhat が1の付近の値になっているかを見ることで判定できます。

# Stanで扱えるモデルは？
結論、どこまで扱えるかわからないですが、
アヒル本の8章までを読んだ結果、とてもフレキシブルで拡張性の高いソフトなので、
一般的な多変量線形/非線形回帰で階層型のモデルなら大抵扱えるんじゃないかなと思ってます。

ただ、モデルが複雑になると、その分計算時間は増えますし、収束もしなくなるので複雑にしすぎるのも悩みどころのようです。

## Stanの書式基礎(1)
RStanはRファイルとは別に同じ階層に”.stan”と言う拡張子で作られたテキストファイルを用意します。
[例えばここにもっとわかりやすい資料があるのですが](https://www.slideshare.net/masakitsuda940/rstanshinystan?ref=http://statmodeling.hatenablog.com/entry/introduction-stan-ja)Stanコードには6つのBlockと呼ばれる箱があり、概ね4つのblockを使うようです。

Data{}ブロック：データを宣言します。C++で書かれているため、INTやREALなど型宣言もここでします
Transformed data{}ブロック:渡したデータを加工する場合はここで宣言します
Parameters{}ブロック：推定したいパラメータの宣言です
Transformed paramaters{}ブロック：パラメータの加工はこちらで宣言します
Model{}ブロック：モデルを記述します
Generated quantities{}ブロック：追加で確認したい統計値を宣言。95%区間を求めるなどができる

必須なのは model ブロックだけのようですが、大抵はtransformed 系ブロック以外は使っているようです。
ちなみに、自作の関数で拡張できる functions{}ブロックもあるみたいです。

結構長く書いてしまったので、ここで終えます。
GW中にもう一本実装踏まえて書いて見たいんですが・・・できるかな？
cakephp3 You can disable deprecation warnings by setting `Error.errorLevel` to `E_ALL & ~E_USER_DEPRECATED` in your config/app.php

composerでアップデートしたら
タイトルどおりのエラーが出た。

php.iniで設定してもエラーが消えない。
ということで、 190行目らへんを

```/config/app.php


    'Error' => [
        'errorLevel' => E_ALL & ~E_USER_DEPRECATED,//左のように変更
        'exceptionRenderer' => 'Cake\Error\ExceptionRenderer',
        'skipLog' => [],
        'log' => true,
        'trace' => true,
    ],


```

に変更するとエラーが消える。
【Github初心者】git pushでdenied to deploy keyのエラーが起きた。

こんにちは、にっちもです。
githubに登録したので、さっそく色々と勉強してみようとターミナルを開いて挑戦しているのですが、早速エラーにつまづいてしまいました。

解決できた後から言えば、原因はgithubへのSSHキーの登録がうまく行えていなかったために起きていたエラーでした。
初心者故に訳が分からず同じような症状に困っている人もいるのではないかと思い、今回は記事にしました。


##まず、githubで練習用の新しいレポジトリを登録する。
1.githubの自分のプロフィールページを選択する。
2.Repositoriesのタブを選択し、newボタンから新しいレポジトリを作成する。
3.新しいテスト用のレポジトリを作成後、自分で用意していたREADME.mdをプッシュしようとする。
プッシュするREADMEがあるフォルダに、cdで移動して、

```
git init
git add README.md
git status 
git commit -m "first commit"
remote add origin git@github.com:XXXX/YYYY.git
```

XXXXはユーザー名、YYYYは作ったレポジトリの名前になります。
ここまでは、githubで新しいレポジトリを登録した時に、README.mdを自動生成しない場合、<>codeタブのところで、最初に実行するべきターミナルのコマンドが記載されているので問題ないかと思います。
そして、ここまでは私もエラーが起きませんでした。

参考元:[GitHub初心者はForkしない方のPull Requestから入門しよう](https://blog.qnyp.com/2013/05/28/pull-request-for-github-beginners/)
Githubでのレポジトリ作成はこの記事を参考にしました。

##そして、git pushでエラーが起きた。
```
git push -u origin master

ERROR: Permission to XXXX/YYYY.git denied to deploy key
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

満を期してよしgit pushだ！！と思ったその瞬間。
はい、こんな感じのエラーが起きました。

deploy key（開発キー）のPermisson(権限)がありませんよ！！というエラーなのかなと感じました。
その後色々と調べて右往左往しまくってしまったのですが、見直したのは自分のユーザーに結びついているSSHキーです。

##対処法：SSHキーへの公開鍵の登録
同じエラーが起きている方はまず、githubのユーザーアイコンを押して、settingの項目を選択してください。
次に、左に表示されるPersonal Settingのタグから、SSH and GPGKeys　の項目を選択します。

そこにSSHキーがちゃんと登録されていれば、登録されたSSHキーが以下のメッセージと共に表示されているはずです。

```
This is a list of SSH keys associated with your account. Remove any keys that you do not recognize.
```

しかし、私の場合は表示されていませんでした。

```
There are no SSH keys associated with your account.
```

この文字と共にSSHキーは空っぽですよーと言わんばかりの画面がそこに。
おかしいなぁ、最初登録した時に公開鍵も登録したと思ったんだけれど……と首を傾げながら、今度は自分の公開鍵をコピーしに、またターミナルへ。
（登録した時はまだターミナルにも全く慣れていない初心者だったので何かしらエラーが起きていたのかもしれません）

```
cd ~/.ssh
ls
```
公開鍵があるかなと、lsでファイルを確認したら、id_rsa.pubが存在していたので、

```
cat ~/.ssh/id_rsa.pub
```

で、ファイルの中身を表示、そしてコピー。
また、githubのSSHKeyのページに戻り、NewSSHKeyボタンをクリック。
Titleにキーの名前（任意の名前で）、Keyのテキストボックスに先ほどの公開鍵を貼り付けて、Add SSHkeyボタンを押して登録！！！

```
Key is already in use
```

はいエラー！！！！なんでやねーん！！！
やっぱり最初の登録時に何かミスってたの？？と思いつつも、ここで立ち止まるわけにはいかない。
現在持っている公開鍵でダメなら、新しい公開鍵を作って登録するしかない。

参考元：[6.1 GitHub - アカウントの準備と設定](https://git-scm.com/book/ja/v2/GitHub-%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%AE%E6%BA%96%E5%82%99%E3%81%A8%E8%A8%AD%E5%AE%9A)

##新しい公開鍵の作成。
すでに.sshのフォルダに移動していたので、そのまま公開鍵の作成をします

```
ssh-keygen -t rsa -b 4096 -C "ZZZZZZ@gmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/user/.ssh/id_rsa): 
/Users/user/.ssh/id_rsa already exists.
Overwrite (y/n)? y
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
```

ZZZZZZ@gmail.comは登録に使ったメアドを使ってください。
これで新しい公開鍵が作成されました。
そのあとは一個前の手順と同じです。公開鍵をコピーして、またgithubからSSHキーの登録をします。

参考元：[Github Help:Generating a new SSH key and adding it to the ssh-agent](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/)

今度はうまくできました！！
その状態でgit pushを行ったら無事行えたので、今回のエラーはSSHキーの登録ミスが原因だったみたいです。

なんとか、git pushを無事行えるようになったので、この後の勉強がようやく進みそうです。
もし、同じエラーで苦しんでいる人がいたらその一助になれれば幸いです。
イラク日報をテキスト分析する (1) 前準備～ワードクラウド

# はじめに
意外と誰もやっていなさそうなので、イラク日報をテキスト分析してみます。今回は諸々の準備とワードクラウド作成までやってみました。

# 準備
## データ
データは、atuyosiさんが[OCRでJSONデータにしたもの](https://a244.hateblo.jp/entry/2018/04/22/222515)を使わせていただきました。JSONはdescriptionだけあればよいので、スクリプトに多少手を入れてテキスト化しました。

オリジナルのPDFは2upで、JSONはPDF1ページごとに1ファイルになっています。PDF1ページ目は表紙・目次となっているので、最初の1ページ分はスキップして全ファイルをマージしました。
(一部4upのファイルもありましたが、気にしない方針で…)

確認用に、オリジナルのPDFデータはだるやなぎさんの[PowerShellスクリプト](http://blog.daruyanagi.jp/entry/2018/04/17/114152)を使用してダウンロードしておきます。実行しようとしたら、セキュリティエラーが出たので、オプションをつけて実行しました。
```
powershell -NoProfile -ExecutionPolicy Unrestricted .\download.ps1
```

## 環境
PythonからMeCabを使うには、Yukino Ikegamiさんの[Windows で pip で mecab-python をいれる](https://qiita.com/yukinoi/items/990b6933d9f21ba0fb43)がよさそうだと見当をつけました。

まずは [MeCab 64bit版](https://github.com/ikegami-yukino/mecab/releases)をインストールし、それからpipでmecab-python-windowsをインストールしようとしましたが、Python3.6が必要なことがわかりました。以前入れたAnacondaの環境はPython3.5だったので、[anacondaでpython3.6をインストール(Windows)](http://codom.hatenablog.com/entry/2016/12/26/211220) を参考にして、3.6の環境を作成しました。
```
conda create -n py36 python=3.6
activate py36
```
これでpipでmecab-python-windowsをインストールできました。

### 反省点
- Windows環境でやらず、ちゃんとLinux環境を作るべきだった
- さらにMeCabをインストールする際に、うっかり空白を含むパス(Program Files以下)にインストールしてしまった


# ワードクラウド作成
まつけんさんの [Word Cloudで文章の単語出現頻度を可視化する。[Python]](https://qiita.com/kenmatsu4/items/9b6ac74f831443d29074) を参考に、amuellerさんの [word_cloudライブラリ](https://github.com/amueller/word_cloud) を使用してワードクラウドを作ることにしました。


word_cloudを使うためにはpyside2が必要なので合わせてインストールしておきます。
```
conda install -c conda-forge pyside2
conda install -c conda-forge wordcloud
```

今回のデータに合わせてまつけんさんのスクリプトにいくつか手を加えました。

- テキストはファイルから取得するのでbeautifulsoup4を使わず、直接ファイルを読み込むように変更
- 巨大なファイルを読み込もうとすると、MeCabの部分で黙って落ちてしまうようなので、行を分割してMeCabに渡して結果をマージするように変更
- 単語の出現回数が多い場合に表示がおかしくなったので、ワードクラウド作成のオプションにcollocations=Falseを追加 ([GitHub Issue](https://github.com/amueller/word_cloud/issues/273))

## MeCabユーザ辞書の作成
形態素解析の結果を眺めてみたところ、辞書登録が必要そうなので、[形態素解析・特徴語抽出エンジン『MeCab』に単語やユーザ辞書を追加する方法](http://blog.kumacchi.com/2010/12/30/1761)を参考にして辞書に登録しました。

```iraq_dict.csv
米軍,-1,-1,100,名詞,一般,*,*,*,*,米軍,ベイグン,ベイグン
サマーワ,-1,-1,100,名詞,固有名詞,地域,一般,*,*,サマーワ,サマーワ,サマーワ
```

```userdic.bat
echo on
"C:\Program Files\MeCab\bin\mecab-dict-index.exe" -d "C:\Program Files\MeCab\dic\ipadic" -u user.dic -f shift-jis -t utf-8 iraq_dict.csv
pause
```

最後にPythonスクリプト内でMeCabを呼び出すときにユーザ辞書を参照するようにオプションを追加しました。
```
t = mc.Tagger('-Ochasen -u user.dic')
```

## できあがり
キーワードとしては地味な活動に関するものが多そうに見えますね。

![wordcloud_all.png](https://qiita-image-store.s3.amazonaws.com/0/171276/9fd768cb-9b25-c33d-4f50-5a79552ec5f9.png)
rails　エラーオブジェクト のデフォルトメッセージを書き換える

初心者です。記念すべき１記事目です。
バリデーションのテストコードを書いていたのですが、ふと、どうやったら元々のエラーメッセージを変えれるんやと思いまして、色々調べたところ以下の書き方で上手く行ったので共有しておきます。

##　最初

#### 元々のエラー文を前提としたテストコード

```
it "is invalid if not having uniqe email" do
      user = create(:user)
      user2 = build(:user)
      user2.valid?
      expect(user2.errors[:email]).to include("has already been taken")
    end
    it "is invalid without a password" do
      user = build(:user, password: "", password_confirmation: "")
      user.valid?
      expect(user.errors[:password]).to include("can't be blank")
    end
```

#### テスト結果

![スクリーンショット 2018-05-03 11.04.59.png](https://qiita-image-store.s3.amazonaws.com/0/252596/869b25b7-136a-bac9-190b-dbeb798afcdd.png)

## en.ymlを書き換える
```
en:
  activerecord:
    errors:
      messages:
        blank: "what the fuck!!! You need to fill it"
        taken: "what the hell are you thinking? it already exists"
  hello: "Hello world"
```

#### テスト結果
![スクリーンショット 2018-05-03 11.07.13.png](https://qiita-image-store.s3.amazonaws.com/0/252596/33f4d8e0-8f4b-3681-50fe-98269912e00a.png)


以上です
Amazon EC2 (RHEL 7.5 AMI)に PHP 7.2 + Laravel 5.5 + MySQL 5.7 をインストールする手順 (201805版)

# 参考資料
* [Amazon EC2 (Amazon Linux)に PHP 5.6 + Laravel 5.3 + Apache 2.4をインストールする手順 (sedでphp.iniのdate.timezoneをAsia/Tokyoに変更するワンライナー)](https://qiita.com/na0AaooQ/items/e9b782be01ce6946d7e8)
* [Amazon EC2 (Amazon Linux)に PHP 5.6 + Laravel 5.3 + Apache 2.4をインストールする手順 (201709 メモ書き)](https://qiita.com/zz22394/items/2d684d980f35106d3c65)
* [Amazon EC2 (Amazon Linux)に PHP 7 + Laravel 5.5 + MySQL をインストールする手順 (201711版)](https://qiita.com/zz22394/items/22fcd6b73d2ab3a1919c)

# Goal
Amazon EC2 (RHEL 7.5)に PHP 7 + Laravel 5.5 + Apache 2.4 + MySQL をインストールする

# 手順
## PHP 7.2
* [How to install PHP 7.2 on CentOS 7/RHEL 7](https://www.cyberciti.biz/faq/how-to-install-php-7-2-on-centos-7-rhel-7/)

```bash
#    Turn on EPEL repo, enter:
sudo yum -y install epel-release
#   Turn on Remi repo i.e.remi-php72:
sudo yum-config-manager --enable remi-php72
#   Refresh repository:
sudo yum update
#   Install php version 7.2, run:
sudo yum install php
```

## Git
```bash
sudo yum install git
```

## Composer
```bash
sudo curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
sudo chown root:root /usr/local/bin/composer
ll /usr/local/bin/composer
```
※Macの場合は `sudo chown root:wheel /usr/local/bin/composer`

## MySQL
* [MySQL 5.7 を CentOS 7 に yum インストールする手順](https://weblabo.oscasierra.net/installing-mysql57-centos7-yum/)
* [MySQL 5.7 をインストールしたら最初に行うセットアップ](https://weblabo.oscasierra.net/mysql-57-init-setup/)

```bash
yum localinstall http://dev.mysql.com/get/mysql57-community-release-el7-7.noarch.rpm
sudo yum info mysql-community-server
sudo yum -y install mysql-community-server
mysqld --version
# Start MYSQL
sudo systemctl enable mysqld.service
#sudo service mysqld start
sudo systemctl start mysqld.service

grep "A temporary password is generated" /var/log/mysqld.log
sudo mysql_secure_installation
```

```sql
CREATE USER your_user IDENTIFIED BY 'your_password';

drop database your_database;
create database your_database character set utf8;
show create database your_database;
GRANT ALL PRIVILEGES ON your_database.* TO your_user@localhost IDENTIFIED BY 'your_password';
flush privileges;

select Host, User, Password  from mysql.user;

mysql -u your_user -p
```

### RDS利用の場合、上記MySQLインストールは不要

```bash
mysql -haaaaaaaa-db.bbbbbb.ap-northeast-1.rds.amazonaws.com -uuseraaaa -p
```

## PHP - MySQL Library install
```bash
sudo yum list available | grep php72
sudo yum install -y php-mysqlnd
sudo yum install -y php-mbstring php-xml
sudo yum list installed | grep php
```
webサイトを作る際に参考にした記事の備忘録④

Webサイト作成に参考にした記事が溜まりに溜まってしまったので、ちょっと整理するために備忘録として記します。

#Git関係
現場のソースコード管理で必要になるGit関係を勉強するために参考にした記事になります。

[GitHub初心者はForkしない方のPull Requestから入門しよう](https://blog.qnyp.com/2013/05/28/pull-request-for-github-beginners/)

練習するのにpullRequestを自分で練習するのに参考にしました。

[今日からはじめるGitHub 〜 初心者がGitをインストールして、プルリクできるようになるまでを解説](https://employment.en-japan.com/engineerhub/entry/2017/01/31/110000)

[github初心者がPull Requestを送ってみた時の手順](http://blog.mogmet.com/github-abecedarian-send-pull-request/)

[gitのローカルbranchを作成し、リモートにpushする](http://sessan.hatenablog.com/entry/2012/06/20/205036)

[githubへpushできないときの対処(permission denied)](http://blog.just1factory.net/programming/131)

[GitHubへの公開鍵の登録](https://qiita.com/zakuro9715/items/99e9f20095c4e1d33f80)

#sass関係

[【ズボンを脱ごう】SassのSASS記法の魅力【カッコイイ】](http://d.hatena.ne.jp/ken_c_lo/20121220/1355948089)

#webGL関係
[WebGL 入門](https://developer.mozilla.org/ja/docs/Web/API/WebGL_API/Tutorial/Getting_started_with_WebGL)

#JavaScript関係
脱jQueryで色々とつまづいているので、がりごりと調べているところです。

[canvasを画像に変換する－JavaScript入門（HTML5編）](http://www.pori2.net/html5/Canvas/150.html)

[画像ファイルを読み込む－JavaScript入門（HTML5編）](http://www.pori2.net/html5/File/040.html)

[クラス名（class属性に値）を追加](http://shanabrian.com/web/javascript/add-class.php)

[【JavaScript】マウスオーバー（ホバー）をトリガーにしたイベント](https://naruhodo.repop.jp/javascript-mouse-hover-event/)

[JavaScriptにおけるvar/let/constの使い分け](https://sbfl.net/blog/2016/07/14/javascript-var-let-const/)

[JavaScriptでidを取得する方法](http://uxmilk.jp/11596)

[document.getElementsByClassName](https://developer.mozilla.org/ja/docs/Web/API/Document/getElementsByClassName)

[getElementByIdとgetElementsByNameの違い](http://d.hatena.ne.jp/mrgoofy33/20100928/1285684451)

[脱jQuery $(”.class”) $(”a”) $(”.class1, .class2”)](https://q-az.net/none-jquery-class-tab/)

[JavaScript逆引きリファレンス](http://shanabrian.com/web/javascript/)

[【脱jQuery】JavaScriptをネイティブで書くときのあれこれTips](https://www.willstyle.co.jp/blog/1025/)

#HTML&CSS関係
[HTMLとCSSの勉強におすすめの本8冊（初心者〜中級者向け）](https://saruwakakun.com/html-css/reference/study)


まだできていないことも多いのですが、記事を整理するために、備忘録メモとして記録します。
chainerの作法　その5

#概要
chainerの作法、調べてみた。
autoencoder。

#インポート

```
import numpy as np
from chainer import datasets, iterators
from chainer import optimizers
from chainer import Chain
from chainer import training
from chainer.training import extensions
import chainer.functions as F
import chainer.links as L
import chainer
import matplotlib.pyplot as plt

```

#訓練データセットのイテレーション
datasetsのget_mnist使う。


```
	train, test = datasets.get_mnist()
	train = train[0 : 1000]
	train = [i[0] for i in train]

```

#ミニバッチに対する前処理
datasetsのTupleDataset使う。


```
	train = datasets.TupleDataset(train, train)
	train_iter = iterators.SerialIterator(train, 100)
	test = test[0 : 25]
```

#ニューラルネットワークのForward/backward計算
Classifier使うけど、lossは、mean_squaredを使う。
活性化は、relu。

```
class Autoencoder(Chain):
	def __init__(self):
		super(Autoencoder, self).__init__(encoder = L.Linear(784, 80), decoder = L.Linear(80, 784))
	def __call__(self, x, hidden = False):
		h = F.relu(self.encoder(x))
		if hidden:
			return h
		else:
			return F.relu(self.decoder(h))
	model = L.Classifier(Autoencoder(), lossfun = F.mean_squared_error)
	model.compute_accuracy = False
```

#パラメータの更新
optimaizerは、Adam。


```
	optimizer = optimizers.Adam()
	optimizer.setup(model)
	updater = training.StandardUpdater(train_iter, optimizer, device = -1)
	trainer = training.Trainer(updater, (80, 'epoch'), out = "result")

	trainer.run()
```

#評価データセットにおける現在のパラメータの評価

```

```

#中間結果をログに残す

```
	trainer.extend(extensions.LogReport())
	trainer.extend(extensions.PrintReport(['epoch', 'main/loss']))
```

#結果

![auto1.png](https://qiita-image-store.s3.amazonaws.com/0/18104/44610af0-99ea-f399-ac2e-247881844766.png)

以上。
Android Studioで実行中のアプリのレイアウト階層を確認する

#前提
実機 or エミュレータ（※1）で実行中のアプリのみ確認ができる。
（※1：エミュレータでは実際に動作確認していないけど、おそらくできると思います。）

#Android Studio標準搭載ツール「レイアウト・インスペクター」を使う
メニュー
　ツール
　　Android
　　　レイアウト・インスペクター（※2）
（※2：Hierarchy Viewerはレイアウト・インスペクターの前世なので、Android Studio 3.1以降は搭載されていません。）

実行中のプロセスを選択する。

View Treeが表示されるので、そこで階層構造を確認できます。
DecorView
　LinearLayout
　　FrameLayout
　　　decor_content_parent
は、Androidのビューを表示するためにどのアプリにも存在する基底ビューなので、その下の階層を確認しましょう。

#関連サイト
公式サイト（Layout Inspector でレイアウトをデバッグする）
https://developer.android.com/studio/debug/layout-inspector?hl=ja
公式サイト（Profile Your Layout with Hierarchy Viewer）
https://developer.android.com/studio/profile/hierarchy-viewer?hl=ja
markdown-itにてプラグインを使わずに特定の<ul>を横並び表示する方法

最近、markdownからHTMLへの変換に[markdown-it][markdown-it]を使っている。特に深い理由は無いけど、Visual Studio Codeのサイトに紹介されているからなんとなく。

# リストの書き方のおさらい

Markdownではlistを簡単に書ける。コンパイルすると単純なHTMLになる。

```md
- a
- b
- c
```

```bash
echo $'- a\n- b\n- c\n' | node_modules/.bin/markdown-it
```

```html
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
```

# Flexboxを使って横並び

```css
ul {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

ul li {
    display: inline-flex;
}
```

よっしゃ！

いや、待てよ。
これだとドキュメント内の全リストに適用されるじゃん。

# 特定のlistを狙う

CSSでは適用範囲を絞るのにclassを使うのが一般的だよね。

しかし[CommonMark][commonmark]にはまだ属性を指定する方法が定まっていないので、`<ul>`要素にはclassを直接付与できない。

markdown-itはプラグインがあるようだけど、どうせこの時点では属性記法が定まっていないしHTMLにしか変換しないから、直接`<div>`要素を書いてしまおうではないか！

```css
.hoge ul {
    display: flex;
    flex-flow: row wrap;
    justify-content: flex-start;
}

.hoge ul li {
    display: inline-flex;
}
```
```md
<div class="hoge">

- a
- b
- c

</div>
```
```bash
echo $'<div class="hoge">\n\n- a\n- b\n- c\n\n</div>\n' | node_modules/.bin/markdown-it
```
```html
<div class="hoge">
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
</ul>
</div>
```

**優勝**

[markdown-it]: https://github.com/markdown-it/markdown-it
[commonmark]: http://commonmark.org/
EMアルゴリズム簡単まとめ

EMアルゴリズムとは何か、またその全体の流れについて簡単にまとめています。

#目次
1.EMアルゴリズムとは
2.EMアルゴリズムの全体像
3.使用例

#1.EMアルゴリズムとは
EMアルゴリズム(expectation–maximization algorithm)は「隠れ変数$\boldsymbol{Z}$がある場合に尤度関数$p(\boldsymbol{X}$| $\theta$ )を$\theta$について最大化する(最尤推定値$\theta$を求める)手法の1つ」で、観測不可能な隠れ変数$\boldsymbol{Z}$の事後確率がパラメータ$\theta$に依存する場合に用いられます。
$\boldsymbol{X}$：観測データの集合
$\theta$：パラメータ
$\boldsymbol{Z}$：隠れ変数の集合
EMアルゴリズムはEステップとMステップを対数尤度の変化が極めて小さくなるまで繰り返すことで、パラメータ$\theta$の最尤推定値を得ます。

#2.EMアルゴリズムの全体像
EMアルゴリズムでは以下の流れで実施します。

1. パラメータ$\theta$の初期化
$\theta^{old}$を初期値を選択します
 
2. Eステップ
隠れ変数$\boldsymbol{Z}$の事後確率$p$($\boldsymbol{Z}$|$\boldsymbol{X}$, $\theta^{old}$)を計算します

3. Mステップ
次式で与えられる$\theta^{new}$を計算します

```math
\theta^{new}=arg max_{\theta} Q(\theta ,\theta^{old})
```
ただし、

```math
Q(\theta ,\theta^{old})=\sum_{\boldsymbol{Z}}p(\boldsymbol{Z}|\boldsymbol{X}, \theta^{old})ln p(\boldsymbol{X}, \boldsymbol{Z}|\theta)
```

4.収束判定
収束条件(例えば、隠れ変数$\boldsymbol{Z}$の事後確率$p$($\boldsymbol{Z}$|$\boldsymbol{X}$, $\theta^{new}$) - $p$($\boldsymbol{Z}$|$\boldsymbol{X}$, $\theta^{old}$)$<10^{-5}$)を満たしていない場合は2.Eステップに戻る



#3.使用例
観測不可能な隠れ変数$\boldsymbol{Z}$が存在する場合など、最尤推定値を直接求めることができない場合に使用します。
例えば、混合正規分布モデルでクラスタリングを行う場合、尤度$p$($\boldsymbol{X}$, $\boldsymbol{Z}$|$\theta$)を最大にするパラメータを求める際、隠れ変数$\boldsymbol{Z}$があるため、最尤推定値を直接求めることができません。

#参考
平井有三(2016)「はじめてのパターン認識」森北出版

混合ガウスモデルとEMアルゴリスム
https://www.slideshare.net/TakayukiYagi1/em-66114496

混合モデルとEMアルゴリズム(PRML第9章）
https://www.slideshare.net/takao-y/20131113-em
d3-sankey のアニメーション

# このメモの狙い
複数ステップでの物やエネルギーの流れを表現するサンキー図を d3-sankey-diagram ライブラリで描きました[^1] が、この流れの時系列変化をアニメーションで表現するコードを調べたので、まとめておきます。

## 使用したライブラリー
* [d3-sankey-diagram](https://github.com/ricklupton/d3-sankey-diagram)

## 完成品
[日本のエネルギーバランス 2006-2016](https://natsuwater.github.io/d3-sankey-diagram_animation_demo/J_energy_sankey_anim.html)

# データの準備
ここでは「[データ総合エネルギー統計](http://www.enecho.meti.go.jp/statistics/total_energy/results.html#headline2)」（エネルギーバランス表）を 2006 年から2016 年まで、1 年おきにダウンロードして、データを抽出しました。
（追加で計算した内容は、生成された電力の利用先の割り付けです。企業・事業所他で消費する電力の起源を、事業用発電の一部と自家用発電の全部に割り付けました。）
各年度のフロー量を配列として、JSON 形式のデータにしました。

``` json
{
  "nodes": [ {(略)}],
  "links": [
    {"source": "1hp", "target": "3pg", "type": "3", 
      "value": ["699", "603", "575", "516", "562", "633"]},
    {"source": "1ru", "target": "3pg", "type": "3", 
      "value": ["0", "0", "6", "7", "7", "114"]},
    ...], }
```

# グラフを更新する部分のコード
update という関数の中に、図を更新する部分を書きます。リンクの数値を SVG のテキストとして置いている部分が、細かなコードの積み重ねになっています。これがなければ、かなりシンプルです。

``` javascript
  d3.json('ja_energy_history.json', function(energy) {
    layout
        .linkValue(function (d) {return d.value[idx];})
        .rankSets(energy.rankSets)
        .ordering(energy.order);
    svg
        .datum(layout(energy))
        .call(diagram.groups(energy.groups));
    var linklab = d3.select('svg')
        .selectAll('.link')
        .append("text")
          .attr("x", function(d) {return d.points[0].x;})
          .attr("y", function(d) {return d.points[0].y;})
          .attr("dx", "1.5em")
          .attr("dy", "0.4em")
          .text(function(d) { return d.value[idx] > 1000 ? fmt(d.value[idx]) + ' PJ' : ""; });

    d3.interval(update, 3000);  

    function update() {
      idx++;
      if(idx > 5) idx = 0;
      layout(energy);	
      svg
        .transition().duration(1000).ease(d3.easeCubic)
        .call(diagram);
      linklab
        .transition().duration(1000)
        .text(function(d) { return d.value[idx] > 1000 ? fmt(d.value[idx]) + ' PJ' : ""; })
          .attr("x", function(d) {return d.points[0].x;})
          .attr("y", function(d) {return d.points[0].y;})
      d3.select('h2').text(energy.year[idx]);
    }  
  });
```
原子力発電のノードとそこにつながるリンクのラベルは、きちんと消えたり復活したりします。

コード全体は、[github](https://github.com/natsuwater/d3-sankey-diagram_animation_demo) に貼りました。
# 終わりに
現状では、まだ切り貼りを試しながら動かしている状態で、分かったという感覚には至っていません。一応動くコードになったので、それを保存しておくための記事でした。


[^1]: [サンキー図の作成 ― d3-sankey-diagram のカスタマイズ](https://qiita.com/natsuriver/items/a65b3c15165db561bcfa)
今更ながら Ruby on Rails Tutorial をやってみた (その7)

## この記事について…

普段はRuby on Railsと無縁なプログラマなんですが、今更ながら**面白そう**という単純な理由から[**Ruby on Rails Tutorial**](https://railstutorial.jp/)をやってみようと思い立ちました。今回は[前回の記事](https://qiita.com/hideki0145/items/ab537eb1e48520bc66b5)の続きで第7章をやっていきます。
尚、Rails 5.1に対応した第4版を用いて、かつVagrantを使用した環境で進めていきます。

※最近私用で忙しくなってしまった為、Rails Tutorialの更新頻度は落とそうと思います。ただ、別件でRaspberry Pi関係の学習が必要になった為、そちらについては逐一更新しようと思っています。

## 第7章 ユーザー登録

この章ではブラウザ上からUserモデルを登録する画面を作成します。普段お世話になっているWebアプリケーションでほぼほぼ存在する機能ですね。

### データベースの内容をリセットする際につまずく

`rails db:migrate:reset`を実行してデータベースの内容を一旦リセットする際に次のエラーが発生しました。

```bash
Text file busy @ unlink_internal - /vagrant_data/environment/sample_app/db/development.sqlite3
Couldn't drop database 'db/development.sqlite3'
rails aborted!
Errno::ETXTBSY: Text file busy @ unlink_internal - /vagrant_data/environment/sample_app/db/development.sqlite3
/vagrant_data/environment/sample_app/bin/rails:9:in `require'
/vagrant_data/environment/sample_app/bin/rails:9:in `<top (required)>'
/vagrant_data/environment/sample_app/bin/spring:15:in `<top (required)>'
bin/rails:3:in `load'
bin/rails:3:in `<main>'
Tasks: TOP => db:drop:_unsafe
(See full trace by running task with --trace)
```

情報を探ったところ、[RailsHackさんのページ](https://rails-school.net/rails-sharefolder-busy/)に原因が記述されていました。(参考になりました。ありがとうございます。)
どうも今回のようにゲストOSとホストOS間で共有フォルダを使用して開発している場合に発生することがあるようです。
ちなみに、今回使用させていただいているVagrantの設定ファイルだと、`/vagrant`と`/vagrant_data`がホストOSと共有されていますので、それ以外のディレクトリにデータベースを移動する必要があります。

今回は以下の手順で一時的にデータベースの位置を移動してリセットを行いました。

1. `~/rails/sample_app`に`development.sqlite3`と`test.sqlite3`をコピーする。
2. `database.yml`を編集する。
3. `rails db:migrate:reset`を実行する。 ⇒ リセットが成功する。`RAILS_ENV=test`でも実行することをお忘れなく。
4. `database.yml`の変更箇所を元に戻す。
5. 元の場所に、`~/rails/sample_app`内の`development.sqlite3`と`test.sqlite3`を上書きする。

```yml:database.ymlの編集箇所
  .
  .
development:
  <<: *default
  database: /home/vagrant/rails/sample_app/development.sqlite3 #ディレクトリを変更
  .
test:
  <<: *default
  database: /home/vagrant/rails/sample_app/test.sqlite3 #ディレクトリを変更
  .
  .
```

`rails db:migrate:reset`を成功させることを重視したので上記手段を取りましたが、結局やりたいことはSQLiteの中身を消したいだけなので、DB Browser for SQLiteを使用するなりなんなりすればいいかもしれませんね。


さて、この章では他にHeroku環境でSSLを使用する等かなり実環境に近い設定を学ぶことができます。
以降の章ではログイン機構の実装、登録したユーザーの一覧表示等、必要不可欠な機能を実装していくようなので、また時間を見つけて進めていこうと思います。

それでは、次回 第8章から再開したいと思います。
pythonによるShapiro wilkは使えず、Rを使用した。

pythonによるShapiro wilkの使用方法。
以下を利用したが、
http://doratai.hatenablog.com/entry/2018/02/07/%E6%AD%A3%E8%A6%8F%E6%80%A7%E3%81%AE%E6%A4%9C%E5%AE%9A%28Shapiro-Wilk%E6%A4%9C%E5%AE%9A%29

欠損値を許してもらえない。
結局Rを使うことにした、しかし、ハマった。
下記が参考になった。
https://stackoverflow.com/questions/28962152/shapiro-test-is-numeric-x-is-not-true
Flutter入門4日目:IntelliJ IDEAを使う

随分サボってました。

途中ReactNativeとかどうなんだろうとか思いついてから、一旦小休止して他のことやってました。

# IntelliJ IDEAを使う

VSCodeからIntelliJ IDEAに変えました。

理由はvimプラグインの操作性がいいことと、別の開発でPHPStorm使うかもとか考えると同じ操作性を経験しとこうかと。

# インストール

Flutter用の設定もIntelliJ IDEAをインストール時に利用設定すればプラグインはインストール出来てました。

ただし、起動後に`dart sdk is not configured`とエラーが表示されました。
※下記のように表示

https://github.com/flutter/flutter-intellij/issues/364

メッセージの右側に表示されるSettingリンクをクリックしてFlutterを選択してSDKのパスを設定してあげればOK。

パスについてはSDKインストール時に配置したパスを設定
記事で言う`pwd/flutter/`の部分

```
export PATH=`pwd`/flutter/bin:$PATH
```

https://flutter.io/setup-macos/

# 使い方わからない

vim使ってるとIDEはパネルいっぱいあってよくわからなくなるので、使い方から勉強していくことに。

https://pleiades.io/help/idea/meet-intellij-idea.html

# 作るアプリ

作るアプリは最近飼いだした猫ちゃんの体重とかご飯、トイレの記録をつけるアプリ作ろうと思います。
既にアプリはあるんだけど毎日の作業だけど若干手間がかかるのでアプリ起動でワンタップで記録できるようにしたい。

そもろも体重毎日は買ったりご飯の記録つける人ってどれくらいいるか不明。
自分が使いたいアプリ作るのが一番でしょうということで。