OmniAICreator/Qiita-1.07M huggingface dataset:
[Kaggle] Kernel提出時、タイムアウトする問題

# 前提
問題が起きたCompetition: APTOS 2019 Blindness Detection。
Featured Code Competitionの参加は初めて。

# 問題
Kernelを提出した際、Timeout Errorとなってしまう。もちろん提出前の実行ではタイムリミットである9時間以内の実行ができている。

# 原因
Public Leaderboardに反映されるテストデータは、Private Leaderboardに反映されるテストデータの15％のデータということは把握していましたが、Kernel提出時に実は毎回Private Leaderboard用の全体テストデータで推論させているということを知りませんでした。
ということで今回のタイムアウトの原因はテストデータ量が公開されているテストデータの約7倍のために推論時間が長時間化していることが原因でした。

# あとがき
Overviewをよくよく見ると上記のことは読み取れなくはないのですが、Kaggle初心者には気づきませんでした。
RockPi S　セットアップした

# RockPi Sとは？
[販売ページ](https://shop.allnetchina.cn/collections/new-products/products/rock-pi-s)によると

* Rockchip RK3308というArm系64ビット4コアなSoC
* RAMは256/512MBを選択可
* USBはType-C1つとType-A1つ
* Ethernet(RJ45)
* wifi/bluetooth搭載選択可(技適なくても使える)
* PoEHAT対応
* オンボードストレージ(1~8GB)
* MicroSD
* GPIO26ピン
* サイズは1.7x1.7inch(38.1x38.1mm)
* 価格は一番安いモデルで$9.9

同じようなコンセプトのNanoPiNEO2と比べるとSoCの中身がCortex-A53からA35になったことで同等の処理能力で省電力か出来ているようだ．[参考](https://www.toradex.com/ja-jp/blog/the-arm-cortex-a35-in-comparison)
また，Type-Cに対応してるのでMicro-Bともおさらばできる．

# 外観
表
![P_20190823_164004_vHDR_Auto.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238384/0ad290d2-ec62-153f-3425-e605385e0915.jpeg)
裏
![P_20190823_164020_vHDR_Auto.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238384/f08ae1d0-d379-58fe-326a-8b88013175d7.jpeg)
高さ
![P_20190823_164056_vHDR_Auto.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/238384/c8cc2e3b-76e1-4e10-0aa8-4bdefcb3ebb7.jpeg)

# セットアップ
[公式](https://wiki.radxa.com/RockpiS)の[Installation](https://wiki.radxa.com/RockpiS/install/microSD)を参考にMicroSDにDebianを入れていく．
1. [Etcher](https://www.balena.io/etcher/)という書き込みツールをインストール．
2. [ここ](https://wiki.radxa.com/RockpiS/downloads)から任意のOSイメージをダウンロード.
3. Etcherを使って任意のMicroSDにOSを焼く．
4. [ここ](https://wiki.radxa.com/RockpiS/dev/serial-console)を参考にシリアル通信orSSHの準備をする.自分はUbuntu+SSHでやったので[ここ](https://yuntan-t.hateblo.jp/entry/2015/04/26/121205)を参考にした．
5. MicroSDをセットし，電源を投入．

以上でSSH接続ができることは確認しました．

# 追記
現在，公式推奨GPIO制御用ライブラリ「libmraa」が公式aptリポジトリからインストール出来ないのでecho使って簡易的にやるか，自分でビルドしてGPIOの設定をしてやる必要がありそうです．
# 追記2
i2cとSPIの設定をライブラリ使わずにやってみたのでまとめ

```
$sudo mount /dev/mmcblk0p4 /mnt/
$sudo vim /mnt/hw_intfc.conf
```
ここで`i2c`なり`spi`なり書いてあるところをon/offで書き換えて再起動すれば`/sys/class`の各インターフェースのディレクトリの中に追加されているはず

# 追記3
`libmraa`がaptでインストールできるようになったみたいです
[ソース](https://github.com/radxa/apt/commit/88725f093a150667f2e7a99ca92d875c749cf8c3)
ドメインレジストラ Gandi.net でリセラーとしてアカウント登録するメリットとデメリット

## ドメインレジストラのリセラー

個人としてウェブサイト作成している人や企業としてウェブデザインやウェブサイト制作をしている方々は、お客さんのドメイン名はどうやって管理していますか?

ここでは自分もリセラーとして使っていて使い勝手が良かったのと、自分と同じような状況の人もいると思うのでここでGandiのリセラープログラムについてまとめています。

Gandi.netでドメイン名購入をすすめる理由：
[ドメイン名取得するならこれからはGandi.netが良いと思った理由](https://qiita.com/infraneko_12/items/084b291dc08496198ecc)

###ドメインのリセラーとは

簡単にいうと、「リセラー」とはICANNから認定を受けてドメイン登録業を行っているドメインレジストラのシステムを利用してドメイン名を買い、その顧客にドメイン名を再販売する人や団体のことを指します。


#### 用語

インターネットドメイン業界のヒエラルキーといいますか、ドメイン名のは簡単にいうと以下になります。

ICANN => レジストリ => レジストラ (=>ドメインリセラー) => ドメイン名登録者

- ICANN:インターネットドメインやDNSなどの運用について国際標準を決める団体のことです。
- レジストリ: .jp や .com などの中央集権的なデータベースを管理する団体。担当するTLDの登録規則を策定したりします。例：.jpのレジストリはJPRSで、.comもレジストリはVeriSignです。
- レジストラ: レジストリと契約を結び、ドメイン名をエンドユーザーに販売する団体。


###Gandiでリセラー登録をするメリット・デメリット

####特徴
![スクリーンショット 2019-08-22 16.15.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293176/40c099fe-5adc-0777-912c-ea7a39a9b6b6.png)

[ドメイン名リセラープログラム](https://www.gandi.net/ja/reseller)

####メリット・デメリット

メリットは顧客管理がしやすいUI、ドメイン名登録ごとにメールアドレスも2つ無料で作成できるので、顧客によってはメールアドレス作成に値段をつけて販売することができる、アカウントにIPアドレス制限をつけてオフィスのVPN使用時のみにログインできるようにできる、ということが個人的なメリットでした。

検討したところデメリットというデメリットはあまりないかなと感じられました。「ドメイン名取得するならこれからはGandi.netが良いと思った理由」の記事でも書いた恩恵をドメイン名ごとに受けることができるので、特にないと感じているのですが、しいて言うといくつかのTLDでドメイン名を購入するとAレートのままだと他と比べて少し高めである、ということです。

.comドメインは購入レートが一番最初のAだと1,493円ですが、Gandiで購入レートがDになると(Gandiのウェブサイト上で年間69万円のがある場合)、.comドメインは年間984円で購入できます。

ドメイン名登録と更新、SSL証明書も合わせてここで購入しておくと中規模以上のウェブ制作会社やドメイン名を取り扱う企業であれば、Dレートに到達する69万円の壁は軽く超えることができるかなと思います。


##リセラーとしての登録方法

Gandiで組織アカウントを作成します。その組織アカウント詳細ページに「Gandiのリセラーになる」と書かれた箇所があるので、「リセラーになる」のボタンを押して次に進みます。

![スクリーンショット 2019-08-22 14.50.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293176/6f1c662f-df4f-8dc4-3142-09396dbccfbe.png)

リセラーアカウントになったら、「顧客情報管理」というボタンが出てきます。

![スクリーンショット 2019-08-22 15.01.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293176/6747eb7c-c41f-1a86-44ba-714402ae8703.png)

「顧客」タブをクリックするとリセラーアカウントの下に顧客アカウントを管理することができます。

![スクリーンショット 2019-08-22 15.02.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293176/032244d8-9b9c-132b-13b3-7782af4a0f2b.png)

リストされている顧客アカウントの右側の「︙」をクリックすると、顧客アカウント情報の編集、顧客アカウントを自分の管理下から外したり(リリース)、顧客アカウント用にドメイン名を購入したり、顧客アカウントがドメイン名所有者になるために必要な承認メールを再送信したり、アカウントを削除したりすることができます。

![スクリーンショット 2019-08-22 16.47.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/293176/94b9172d-acdc-040a-338b-97eba402da64.png)
PostgreSQLで一定間隔でスキップして取得

100番目、200番目、300番目...というように一定間隔で行を取得したいとき

## SQL

```sql
SELECT * FROM (
    SELECT row_number() OVER (ORDER BY id) AS rn, *
    FROM users
) AS rn_q
WHERE MOD(rn, 100) = 0
```

row_numberを振ってMODで一定間隔にフィルタする

## 参考

>SQL - 【SQL】【Oracle】指定した行数ずつデータを取得する方法｜teratail
https://teratail.com/questions/102682

>PostgreSQLで連番付与（PostgreSQLでもROWNUM使いたい） - 屑プログラマの憂鬱
http://artisan.hatenablog.com/entry/20130324/1364109795
スプレッド構文で遊んでみた

# スプレッド構文で遊んでみた
何となくオブジェクトを展開する便利な構文くらいでいたのですが、
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax
改めてMDNの定義を読んでみると、iterableなものなら使えるということだったので、
色々と実験してみました。

## 文字列を渡してみる
スプレッド構文を使えるのは関数の引数・配列リテラル・オブジェクトリテラルの3種なのでそれぞれ試します。

### 引数として渡したケース
``` javascript
function test(...params){params.forEach(p => console.log(p));}
test(...'abcd');

//以下出力結果
a
b
c
d

```
文字列にスプレッド構文というと妙な感じがしますが、普通に一文字ずつに分割されるようです。

### 配列
``` javascript
let array = [...'abcd'];
//[ 'a', 'b', 'c', 'd' ]

```
まあここも想定通りですね。

### Object構文
``` javascript
let o = {...'abcd'}
//{ '0': 'a', '1': 'b', '2': 'c', '3': 'd' }
```
0から順番にキーとして一文字ずつObject化されます。
ここも大体想定通りですが、Typescriptにすると実はこれエラーが出ます。

typescriptの場合、何故かObject型でないと受け付けないようになっているようです。
typescriptでObjectのスプレッド構文を書くと`Object.assign`にコンパイルされるのでそのせいかとも思ったのですが、
typescriptでも`Object.assign({},'abcd')`は通るので謎です。

## ジェネレータを渡してみる
``` javascript
var gen = function* () {
     yield 1;
     yield 2;
     yield 3;
 };
```
こんな感じのジェネレータ関数を作って試してみます。

### 引数と配列
``` javascript
function test(...params){params.forEach(p => console.log(p));}
test(...gen());
1
2
3

let array = [...gen()];
[1,2,3]

```
ここまでは大体予想通りです。
ちなみに、これらの構文を使った場合、generatorは最後まで回されますので、
使った後に``generator.next();``を呼ぶと``{value:undefined:done:true}``を返します。

ただ、Objectにした場合はちょっと挙動が予想と違いました。

``` javascript
let generator = gen();
let o = {...generator};
//{}
generator.next();
{ value: 1, done: false }

```
文字列とと同じように、0から順番にキーとしたObjectが出来るかと思ったのですが、
単に空オブジェクトが生成されるだけで、内部的に``generator.next()``が呼ばれることもないようです。
これは``Object.assign``と似たような仕様のようです。
(MDNを読む限り細かい仕様の違いはあるようですが)

ちなみに、Typescriptの場合はstringと同様にObjectで使えません。
Localstack を使って AWS 互換環境を構築するし、かつ好きなポートで UI を動かす。

Localstack というのはローカルで AWS 互換環境を動かす仕組みです。単体テストなどで使うには良いと思います。[localstack](https://github.com/localstack/localstack) の公式サイトには色々な方法が書いてありますが、docker-compose が一番良かったのでメモります。以下は Mac OSX で、かつ管理画面をポート 9000 で動かす方法です。

```shell
git clone https://github.com/localstack/localstack.git
cd localstack
PORT_WEB_UI=9000 TMPDIR=/private$TMPDIR docker-compose up
```

これで http://localhost:9000 に管理画面が出ます。使い方はよくわからない。。。

`awscli` で実際に使うには、`--endpoint-url` という引数で対応するローカルの endpoint を指定します。各言語のライブラリにも Endpoint を指定するためのオプションが用意されているので、カスタマイズ可能な形にしておきテスト時に Endpoint を指定すれば良いです。例:

```shell
aws --endpoint-url=http://localhost:4568 --region=us-west-2 kinesis create-stream --stream-name hoge --shard-count 1
```

公式サイトに書いてある localstack コマンドを使った起動方法では `PORT_WEB_UI` で管理画面を指定出来ませんでした。
docker-compose 'up' とか 'build' とか 'start' とかの違いを理解できていなかったのでまとめてみた

タイトルのとおりですが、今まで`up`とか`build`の違いをよく理解せず使用していたので、改めてまとめて見たいと思います。
個人的に似ているなと思っている以下のコマンドについて解説していきます。

|        | image構築 |    コンテナ構築    |   コンテナ起動  |
|:-------:|:---------:|:----------------:|:-------------:|
| build  |     ○    |        ×         |        ×      |
| up     |     △    |        ○         |        ○      |
| start  |     ×    |        ×         |        ○      |
| run    |     ○ （単独）   |        ○ （単独）        |       ○ （単独）     |

  

## 前提
構築するimageは`docker-compose.yml`ファイルに定義されているもの、またはDockerfileを参考にして構築します。

## build

`build` コマンドではimageを構築します。コンテナは作成しません。

```
$ docker-compose build
db uses an image, skipping
Building web ...

Successfully built XXXXXXXXX
Successfully tagged XXXX_web:latest
```

キャッシュがあればそちらを優先的に使ってビルドするので、Dockerfileを更新したなどの理由でキャッシュを使いたくない場合は `docker-compose build --no-cache` とします。

### キャッシュって何？
Dockerは一度ビルドするとキャッシュというのが作成されます。ご存知グーグルクロームとかのブラウザにも同じ機能がありますね。キャッシュがあると2回目以降にビルドするときに、速やかに処理をすることができるわけです。

ただ、キャッシュがあると不便なときもあって、それが例えばDockerfileを更新したときなどです。上に紹介したように `--no-cache` オプションを付けないと、Dockerはキャッシュを使ってimageを構築してしまうので、更新したDockerfileを見てくれず新しいimageが作られません。

## up

`up`コマンドでは、キャッシュがある場合はそれを使って一発でイメージの構築から、コンテナの構築・起動までします。

キャッシュがない場合は `--build` オプションをつけることで、イメージの構築から、コンテナの構築・起動までしてくれます。（ただし、 `build` コマンドと同じでDockerfileを更新してても反映されません。）
新しいサービスを初めて立ち上げる場合はもちろんキャッシュはないので `docker-compose up --build` コマンドを使いましょう！

`-d`オプションを付けてバックグランドで実行することが多いです。

```
$ docker-compose up
Building web
...

Creating XXXX_db_1
Creating XXXX_web_1
Attaching to XXXX_db_1, XXXX_web_1
...

web_1 | Use Ctrl-C to stop
```

反対に、`down`コマンドでコンテナの停止、削除を実行します。

## start

`start`コマンドでは既存のコンテナを起動します。

```
$ docker-compose start
Starting db  ... done
Starting web ... done
```

もちろんコンテナが1つも存在しないと失敗します。

```
$ docker-compose start
Starting db  ... failed
Starting web ... failed
ERROR: No containers to start
```

立ち上げたコンテナは`stop`コマンドで停止することができます。

## run

`run`コマンドではimageの構築から、コンテナの構築・起動までしてくれますが、引数でサービスを指定しないと失敗します。

```
$ docker-compose run web
=> Booting Puma
=> Rails 5.1.7 application starting in development
=> Run `rails server -h` for more startup options
...
```

ちなみに、 `run`コマンドを介して指定したサービスのコンテナ内でコマンドを実行できます。

```
$ docker-compose run web rails new
...
```

## exec
`run`のついでですが、 サービスのコンテナ内でコマンドを実行するなら`exec`コマンドも便利です。
`docker exec`コマンドと同じで起動中のコンテナのシェルへ接続することができるので、`run`よりもこちらで実行したほうが早いです。

```
$ docker-compose exec web /bin/bash
root@XXXXXXXXX:/app#
```

## オススメ記事

こちらの記事を合わせてご確認いただくと、よりDockerについての知識が深まると思います。
- [Docker利用時のソースコードの変更反映 - Qiita](https://qiita.com/tearoom6/items/326895f0a35774d70729)

## 参考
- [docker-compose コマンドまとめ - Qiita](https://qiita.com/wasanx25/items/d47caf37b79e855af95f#%E5%8F%82%E8%80%83%E3%83%AA%E3%83%B3%E3%82%AF)
- [初心者向けdocker-composeコマンド逆引き - Qiita](https://qiita.com/okyk/items/a374ddb3f853d1688820)
【salesforce】Classic基本知識ーオブジェクト、タグ、アプリケーション作成

本セクションにはSalesforce　Classicのオブジェクト、タグ、アプリケーション作成手順を紹介いたします。
#オブジェクト作成
- 手順
    - オブジェクト作成
        1. 設定画面の「クイック検索」に、「オブジェクト」で検索して、「作成」セクション配下の「オブジェクト」をクリックする。
        2. 「新規カスタムオブジェクト」をクリックする。
        3. 「新規カスタムオブジェクト」画面の情報を下記の通りで入力して、「保存」ボタンをクリックする。

        |No.     |       設定項目 　　|    設定内容    |
|:-------|:------------------|:------------------|
|1　　　　|　表示ラベル　　 |　住所マスタ　    |
|2　　　　|　オブジェクト名 |　AddressMaster　|
|3　　　　|　レコード名　　 |　住所CD　　　　　|
|4　　　　|　データ型　　　 |　テキスト　　　　|
|5　　　　|　レポートを許可 |　選択　　　　　　|
|6　　　　|　他の項目　　　 |　デフォルト値　|

  - 項目作成
  オブジェクト作成した後、画面は自動的に「住所マスタ」設定画面に遷移できました。マルから説明するため、該当画面の入る方も説明いたします。
下記項目を作成する。
        1. 設定画面の「クイック検索」に、「オブジェクト」で検索して、「作成」セクション配下の「オブジェクト」をクリックする。
        2. 追加対象項目の所属オブジェクトの「表示ラベル」リンクをクリックする。
        3. 遷移した画面はオブジェクト設置画面です。該当画面の「カスタム項目 & リレーション」セクションまでスクロールする。
        4. 「新規」ボタンを押す。
        5. 「データ型」に「テキスト」を選択して、「次へ」ボタンを押す。
        6. 「項目の表示ラベル」に「住所詳細」を設定して、「文字数」に「255」を設定して、「項目名」に「Address」を設定して、他の項目はデフォルトとのまま、「次へ」ボタンを押す。
        7.  「参照可能」をチェックして、「次へ」ボタンを押す。
        8.  「保存」ボタンを押す。
上記の手順でカスタム項目を作成できました。
 
#タグ作成

- 手順
    1. 設定画面の「クイック検索」に、「タブ」で検索して、「作成」セクション配下の「タブ」をクリックする。
    2. 「カスタムオブジェクトタブ」セクションの「新規」をクリックする。
    3. オブジェクトに作成対象タブに対するカスタムオブジェクトを選択して、「タブスタイル」右の「ルックアップ」をクリックして、好きなアイコンをダブルクリックして、「タブスタイル」に設定して、「次へ」ボタンを押す。
    4. 「1 つのタブ表示をすべてのプロファイルに適用する 」を選択して、「デフォルトで表示」を設定していることを確認して、「次へ」ボタンを押す。
    5. 「タブを含める」をチェックして、「保存」ボタンを押す。

     そうして、新しいタブを作成できました。
 
#アプリケーション作成

- 手順
    1. 設定画面の「クイック検索」に、「アプリケーション」で検索して、「作成」セクション配下の「アプリケーション」をクリックする。
    2. 「アプリケーション」セクションの「新規」をクリックする。
    3. 「カスタムアプリケーション」を選択して、「次へ」ボタンを押す。
    4. 「アプリケーションの表示ラベル」に「人材派遣システム」を設定して、「アプリケーション名」に「jinzaihaken」を設定して、「次へ」ボタンを押す。「次へ」ボタンをもう一回押す。
    5. 「Ctrl」キーを押しながら、表示したいタブをクリックして、「追加」ボタンを押して、「デフォルトの表示タブ」を好きなタブを選択して、「次へ」ボタンを押す。
    6. 「参照可能」をチェックして、「保存」ボタンを押す。

    以上の手順で、アプリケーションを作成できました。右上の「アプリケーションメニュー」から新規作成したアプリケーション選択して、新しいアプリケーションに遷移できます。

# まとめ
本セクションには、salesforce元々基本なオブジェクト、タブ、アプリケーションのシンプル作成方法を紹介いたしました。興味があれば、ぜひお試しください。
コールバックにラムダ式を渡したいけど引数省略もしたい

# 概要

* 関数ポインタでコールバックしてた感覚で、ローカル変数キャプチャしたラムダ式でコールバックがしたい
* 気分によって引数を省略したいときもあるよね！

## うごいたコード

```cpp
#include <iostream>
#include <functional>
using namespace std;

//! @param[in] cb 省略可。進捗のパーセンテージをコールバックします。
//! @param[out] なんか処理の計算結果。
int doSomething(const std::function<void(int)>& cb = nullptr)
{
    // なんか処理
    
	if(cb) { cb(10); }
    
    // なんか処理
    
    if(cb) { cb(20); }
    
    // なんか処理
    
    if(cb) { cb(40); }
    
    // なんか処理
    
    if(cb) { cb(60); }
    
    // なんか処理
    
    if(cb) { cb(80); }
    
    return 10000;
}

int main(void)
{
    // コールバック処理。進捗をコンソールに表示。
    char percent[] = "%";
    auto callback = [&](int progress)
    {
        cout << "progress: " << progress << percent << endl;
    };
    
    cout << "CASE1 -- With callback" << endl;
    int result = doSomething(callback);
    cout << "result = " << result << endl;
    
    cout << "\nCASE2 -- Without callback" << endl;
    cout << "result = " << doSomething() << endl;
}
```

```:console
CASE1 -- With callback
progress: 10%
progress: 20%
progress: 40%
progress: 60%
progress: 80%
result = 10000

CASE2 -- Without callback
result = 10000
```
SSP ・ DSP ・ DMP（個人お勉強用）

随時更新予定

## SSP
**Supply-Side Platform**
媒体社側の広告収益を最大化するためのプラットフォーム
## DSP
**Demand-Side Platform**
広告主側の広告効果を最大化、最適化するためのプラットフォーム
## DMP
**Data Management Platform**
~javascript オブジェクトリテラルの使い方、名前空間ヘルスケアwebサービスを自分で作る医者の日記~

数日に一個は、アプリ制作をしたいと思って、qiita徘徊中
でみつけた
こちらの記事
https://qiita.com/H_Crane/items/a1e19c5d9c62cb686d1f

外部APIを利用して、データベースとし、チャットアプリ

しかし、コードをみてもわからない。

functionの前にある : ってなに？

しかし、解決した。

```
<script>
  let Member = function(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  };
  Member.prototype = {
    getName : function() {
      return this.lastName + '' + this.firstName;
    },
    toString : function() {
      return this.lastName + this.firstName;
    }
  };
  let mem = new Member('sudo', 'eishun');
  console.log(mem.getName());
  console.log(mem.toString());
</script>
```

オブジェクトのメンバーにとなる関数　を .  を使わず　: で
表現しているだけなのね。
Pythonでピアソン相関を計算する【レコメンド】

#ピアソン相関とは
ピアソン相関は２つの連続変数間の線形関係を評価します。
一方のデータが増加、減少し、もう一方もそのデータと同じような動きをする場合、ピアソン相関は1に近づきます。一方のデータの増加、減少しても他方に影響しない場合、値は0に、一方のデータの動きともう一方のデータが逆向きに動くようなとき、ピアソン相関は-1に近づきます。
ピアソン相関を式に表すと以下の通りになります。
$ \large r = \frac{\sum(x - \bar{x})(y  - \bar{y})}{\sqrt{\sum(x - \bar{x})^2} \sqrt{\sum(y - \bar{y})^2}}$
このピアソン相関をPythonで書くと以下のようなコードになります。

```pearson2.py

import math

data1 = {'Drama': 3, 'Romance': 4, 'School': 5, 'Action': 1, 'Sports': 1}
data2 = {'Drama': 2, 'Romance': 3, 'School': 2, 'Action': 5, 'Sports': 4}

def pearson_correlation(data1, data2):
    #平均
    mean1 = sum([value for value in data1.values()]) / len(data1)
    mean2 = sum([value for value in data2.values()]) / len(data1)
    #標準偏差
    deviation1 = math.sqrt(sum([(data1[key] - mean1)**2 for key in data1]))
    deviation2 = math.sqrt(sum([(data2[key] - mean2)**2 for key in data1]))
    #共分散
    covariance = sum([(data1[key] - mean1)*(data2[key] - mean2) for key in data1])
    
    return covariance / (deviation1 * deviation2)
    
pearson_correlation(data1, data2) #-0.8360556025697307
```

Pythonではnumpyモジュールを使用することで簡単に求めることができます。

```pearson2.py
import numpy as np

data1 = {'Drama': 3, 'Romance': 4, 'School': 5, 'Action': 1, 'Sports': 1}
data2 = {'Drama': 2, 'Romance': 3, 'School': 2, 'Action': 5, 'Sports': 4}
data1_list = []
data2_list = []

#辞書型から配列へ。valueのみを格納。
for value1 in data1.values():
    data1_list.append(value1)    
for value2 in data2.values():
    data2_list.append(value2)

np.corrcoef(data1_list,data2_list)[0,1] #-0.8360556025697305
```

scipy.stats.pearsonrを使用した場合です。

```pearson3.py
from scipy.stats import pearsonr

data1 = {'Drama': 3, 'Romance': 4, 'School': 5, 'Action': 1, 'Sports': 1}
data2 = {'Drama': 2, 'Romance': 3, 'School': 2, 'Action': 5, 'Sports': 4}
data1_list = []
data2_list = []

#辞書型から配列へ。valueのみを格納。
for value1 in data1.values():
    data1_list.append(value1)    
for value2 in data2.values():
    data2_list.append(value2)

correlation, pvalue = pearsonr(data1_list, data2_list)
print(correlation) #-0.8360556025697304
```

#追記
辞書型はここではあまり使わないようです。

#参考
[相関係数の数式](https://www.koka.ac.jp/morigiwa/sjs/correlation_equation.htm)
[NumPyの相関係数を求めるnp.corrcoef関数の使い方](https://deepage.net/features/numpy-corrcoef.html)
[numpy.corrcoef](https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.corrcoef.html)
[【Python】ピアソンの相関係数をいろいろな方法で計算する方法まとめ(SciPy / Numpy / Pandas)](https://www.st-hakky-blog.com/entry/2018/01/30/004659)
マイグレーションファイルとは？個人的覚え書

#マイグレーションファイルとは何か一言で

どんなテーブル(DB)を作成するのか？が書かれた設計図。
テーブルを定義する仕組み。

#なぜマイグレーションファイルを用意するの？直接SQL文を打ち込んではいけないのか？

DBに変更を加える人の数が増えた場合、管理するのが大変になって来る。
そうなる前にこのマイグレーションファイルを用意する事によって変更を容易にしてくれるのです。
Numpy.arrayのsortに関する個人的メモ

# まずは普通のソート
ご存知argsortをつかった普通のソート。

```python:test_sort.py
import numpy as np
import matplotlib.pyplot as plt

# Prepare test array
np.random.seed(20190823)
array1d = np.random.random(size=100) # 1d array with random value

# Usual sort
sort_ind = np.argsort(array1d) # index array for sort of array1d
sorted_array1d = array1d[sort_ind] # sorted array1d

# Plot results #1
plt.figure()
plt.plot(array1d, label='Random', c='k')
plt.plot(sorted_array1d, label='Sorted')
plt.legend()
plt.show()
```
わかりやすくするためにMatplotlibで表示。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187040/6c456edc-4c28-885c-de5a-548d071e0f4b.png)

# ソートしたあと元に戻す
果たして自分以外に需要があるのか。

```python:test_sort.py(のつづき1)
# Re-sort
re_sort_ind = np.argsort(sort_ind) # index array for sort of sort_ind

# Plot results #2
plt.figure()
plt.plot(array1d, label='Random', c='k')
plt.plot(sorted_array1d, label='Sorted')
plt.plot(sorted_array1d[re_sort_ind], zorder=-2, label='Re-sorted', lw=5, c='gold')
plt.legend()
plt.show()
```
Matplotlibによる表示。もとの配列(黒)とソート後に戻した配列(黄)がちゃんと一致している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187040/64b050b1-db37-95c2-e022-5e6a0e626d91.png)

# 第1列、第2列の優先順にソートしたい
日本語が難しいですね。
以下を見ていただいたほうが早いかと。

```python:test_sort.py(のつづき2)
# Prepare test array
np.random.seed(20190823)
array2d = np.random.randint(0,5,size=(100,2)) # 2d array with random value

# Plot results #3
plt.figure()
plt.plot(array2d[:,0], label='1st column')
plt.plot(array2d[:,1], label='2nd column')
plt.title('Before sort')
plt.legend()
plt.show()
```
100行2列のテスト配列について、各列ごとにプロット。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187040/92e0022a-f572-c024-880d-b7a3e90ebc33.png)
醜いのでさっさとソートしましょう。

```python:test_sort.py(のつづき2)
from operator import itemgetter

# Sort!
list2d = list(array2d)
sorted_list2d = sorted(list2d, key=itemgetter(0,1))
sorted_array2d = np.array(sorted_list2d)

# Plot results #4
plt.figure(dpi=120)
plt.plot(sorted_array2d[:,0], label='1st column')
plt.plot(sorted_array2d[:,1], label='2nd column')
plt.title('After sort')
plt.legend()
plt.show()
```
以下結果。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187040/017a222c-f685-f9ac-ce40-50dda2749a31.png)

第1列の値(青)についてソートされており、第1列の値が同じ場合は第2列(橙)の値に従ってソートされていることが分かります。

itemgetterを使うためにnumpyの配列からlistに変換し、再度numpy配列へと変換しています。手間はかかりますが、短く単純に書けるという意味で便利かと思います。

もちろん、

```python: 
sorted_list2d = sorted(list2d, key=itemgetter(0,1))
```
のitemgetterの引数を変えることで指定する列、順番を自由に指定できます。

```python:test_sort.py(のつづき3)
# Sort!
sorted_list2d = sorted(list2d, key=itemgetter(1,0))
sorted_array2d = np.array(sorted_list2d)

# Plot results #5
plt.figure(dpi=120)
plt.plot(sorted_array2d[:,0], label='1st column')
plt.plot(sorted_array2d[:,1], label='2nd column')
plt.title('After sort')
plt.legend()
plt.show()
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/187040/cb906092-6bb5-061b-0bb0-3c925af59589.png)

先ほどとは逆に、第2列の値(橙)についてソートされており、第2列の値が同じ場合は第1列(青)の値に従ってソートされていることが分かります。


それでは良いソートライフを。
プログラミング入門者用　MySQL文　一覧　※個人メモ

##プログラミング入門者用　MySQL文　一覧　※個人メモ

現在学習中のメモを記載
修正点や助言などあればコメントください。

####セットアップ

|アクション|SQL文|
|---|---|
|MySQLへの接続|mysql -u root -p|
|MySQLの切断|exit|
|パスワードの変更|ALTER USER 'root'@'localhost' IDENTIFIED BY '新パスワード';|

####データベース操作

|アクション|SQL文|
|---|---|
|データベースの作成|CREATE DATABASE データベース名 default character set utf8;|
|データベースの削除|DROP DATABASE データベース名;|
|データベースの一覧の確認|show databases;|
|操作するデータベースの選択|USE データベース名;|

####テーブル操作

|アクション|SQL文|
|---|---|
|テーブルの作成|CREATE TABLE データベース名.作成したいテーブル名(●);|
|テーブルの削除|DROP TABLE データベース名.作成したいテーブル名;|
|テーブルの一覧の確認|show tables;|
|テーブルの設計内容確認|describe books;|

※上記テーブル作成(●)内　カラム作成内容例

|アクション|SQL文|
|---|---|
|IDカラム|ID INT AUTO_INCREMENT NOT NULL PRIMARY KEY|
|文字列カラム|カラム名 VARCHAR(最大文字数)|
|整数カラム|カラム名 INT|
|登録日時自動登録カラム|カラム名 TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP|

####CRUD操作

|アクション|SQL文|
|---|---|
|データの作成|INSERT INTO テーブル名 (カラム1, カラム2, ...) VALUES (値1, 値2, ...);|
|データの取得|SELECT カラム名 FROM テーブル名;|
|データの更新|UPDATE テーブル名 SET カラム名1 = 値1, カラム名2 = 値2, …;|
|データの削除|DELETE FROM テーブル名;|

####その他

|操作例|SQL文|
|---|---|
|WHERE句　例|CRUD文 WHERE カラム名 = 値;|
|ORDER BY 句　例|CRUD文 ORDER BY 並べ替え基準となるカラム|
|分析の関数|SEIECT 関数(カラム名) FROM テーブル名;|
|テーブルの結合|INNER JOIN テーブル名 ON 条件|
Adobe XDのオブジェクトをPNGに変換するAppleScript（Automatorサービス）

# コピーはSVG形式に？  
クリップボードにコピーしたオブジェクトはSVG形式になってしまうようですね。

https://twitter.com/tonkotsuboy_com/status/1163811210141159425  

これをコピーして……
![スクリーンショット 2019-08-22 18.58.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7001/c4e48ec4-c05f-de82-0e1c-9f3e4c88565a.png)

エディタにペースト
![スクリーンショット 2019-08-22 18.59.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7001/cc577330-89c2-7a92-6020-ad2cf5a7eabc.png)

pngをbase64エンコードしてる。
これはこれでそういう考えだからいいけど、そのまま画像として欲しい時もある……  

すると〜〜
https://twitter.com/sttk3com/status/1163820964284489730?s=20  
さすがは[したたか企画さん][sttk]。
なるほど`as «class PNGf») `でPNGが取り出せるんだ〜

じゃあ、サービスつくりましょう！

## コードの確認  
まずはスクリプトエディタで動作確認

``` AppleScript:XDからpng形式でクリップボードに  
tell application "Adobe XD"
	activate
	tell application "System Events"
		tell process "Adobe XD"
			keystroke "c" using {command down}
			set the clipboard to (the clipboard as «class PNGf»)
		end tell
	end tell
end tell
```

画像としてクリップボードに格納されているので、それをプレビュー.appの**ファイルメニュー**から**クリップボードから新規作成**でファイル作成。
![ss.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7001/992ba91b-bdd4-1a0b-e391-e062dc6c6881.png)
よし、できた。

## Automatorでサービスを作る
Automatorを起動し、**ファイルメニュー**から**新規**、**サービス**を選択。

![スクリーンショット 2019-08-23 1.49.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7001/3f75ca4d-4f38-c20e-c866-0813d372eefc.png)

左側のアクションから**AppleScriptを実行**をダブルクリック。
入力は**入力なし**、検索対象は**Adobe XD**をそれぞれ選択。
下記のコードをコピー＆ペースト。
いきなりコード量が増えたのは、サービスにするならデスクトップにファイルとして保存するようにしたから。  
クリップボードにあれば十分であれば、上記のコードをコピー＆ペーストしてください。  
![スクリーンショット 2019-08-23 1.59.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7001/4b66fa98-e305-8e4f-5a8d-9dd3c0d626e5.png)  


適宜名前をつけて保存。
ファイルは**~/Library/Services/**に保存されます。  

```AppleScript:XDから選択オブジェクトをpngファイルに書き出す
--XDからクリップボードに
my setClipboard()

try
	set png to the clipboard as «class PNGf»
on error
	error number -128
end try


--保存パスの生成
set writePath to my getWritePath()


--デスクトップにタイムスタンプ名で保存
my writePng(png, writePath)


--選択したオブジェクトをクリップボードにコピー
on setClipboard()
	tell application "Adobe XD"
		activate
		tell application "System Events"
			tell process "Adobe XD"
				delay 0.1
				keystroke "c" using {command down}
				delay 0.2
				set the clipboard to (the clipboard as «class PNGf»)
			end tell
		end tell
	end tell
end setClipboard


--保存パスの生成
on getWritePath()
	set desktopPath to path to desktop as text
	set timestamp to do shell script "date +%Y%m%d_%H%M%S"
	
	return desktopPath & timestamp & ".png"
end getWritePath

--ファイル書き出し
on writePng(png, writePath)
	set fh to open for access writePath with write permission
	
	try
		set eof fh to 0
		write png to fh starting at eof
		close access fh
	on error
		close access fh
	end try
end writePng

```

##ショートカットの設定

サービスで作ったのでショートカットも設定しましょう。
**システム環境設定**から**キーボード**、**ショートカット**タブを選択したら、**サービス**をクリック。
先ほど保存したファイル名を選択してショートカットキーを割り当てましょう。
![スクリーンショット 2019-08-23 18.11.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7001/d8987335-579d-7a93-3b98-d01c9fe993fb.png)






[sttk]:[https://twitter.com/sttk3com]
幫 InstanceID 加一個 RxSwift 的 Helper Wrapper

InstantID 在取用的時候，是以非同步的方式進行，
為了在 RxSwift 程式碼裡面能夠比較順利使用，
就決定來寫個 wrapper 給他！

## 建立 Protocol

首先習慣上會先新增一個 protocol

``` swift
protocol InstanceIdFetcherType {
    func fetch() -> Observable<InstanceIDResult>
}
```

## 實作

``` swift
struct InstanceIdFetcher: InstanceIdFetcherType {
    
    static let shared: InstanceIdFetcher = InstanceIdFetcher()
    
    func fetch() -> Observable<InstanceIDResult> {
        return Observable.create { observer in
            InstanceID.instanceID().instanceID { result, error in
                if let result = result {
                    observer.on(.next(result))
                    observer.on(.completed)
                } else if let error = error {
                    observer.on(.error(error))
                } else {
                    observer.on(.completed)
                }
            }
            
            return Disposables.create()
        }
    }
}
```

## 使用

```swift
let fetchToken = buttonTapped
    // 省略防止按鈕連打的處理
    .flatMapLatest { _ in
        InstanceIdFetcher.shared // 便利上在這邊這樣寫，實際上這個變數可以用 DI 的方式注入 view model
            .fetch()
            .catchError { _ in .empty() } // 可以在這裡處理錯誤回應
    }
    .map { $0.token } // 可以這樣取得實際回傳的 token
    // 接著再看要拿 token 拿來做什麼事，例如回傳到 server 端等等
    .share()
```

## 環境

- Xcode **10.3 (10G8)**
- Swift **5**
- Ｌibraries
  - RxSwift **5.0.0**
  - FirebaseInstanceID **4.2.3**

## 最後

如果內文需要更新、有錯誤或容易誤解的地方，歡迎發修改或是留言告訴我！
Lambdaとは何か初学者が調べてみた

#はじめに
私事ですが初めてミートアップに参加してみる事にしました。
興味のある企業さんだったので、参加しましたが折角参加するなら有意義な時間を過ごしたいという事で、最低限の基礎知識くらいはいれておこうという事で、記事にまとめます。
最近大した知識もないのにAWSの記事書いたり、AWSLoft行ったりとなんか偏っている気がするのですが細かいことは気にしません。
[AWSとはそもそも何なのか](https://qiita.com/fukaya_path/items/c3dd8888133495b28314)と言うのは別途まとめてあります。
おまけに[AWSLoftに特攻した時の記事](https://qiita.com/fukaya_path/items/5550b8e33938991a59fe)もあります
＊初学者が０から学んでいるので初歩的な所やミスがあるかもしれません。お気付きのことがあればコメントしていただけっれば幸いです。

#Lambda（ラムダ）
###とりあえず公式を読んでみる
まずは安定の公式ホームページから確認します。
以下、公式より引用です
>AWS Lambda はサーバーをプロビジョニングしたり管理する必要なくコードを実行できるコンピューティングサービスです。 AWS Lambda は必要時にのみコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケーリングします。

ほう、相変わらずわからない。知識の無い私にはピンときませんが後半は、SaaS的な話でしょう。とりあえず前半のプロビジョニングがわからないので調べます。
以下、引用です。引用元は参考サイト参照で。
>プロビジョニングとは、必要に応じてネットワークやコンピューターの設備などのリソースを提供できるよう予測し、準備しておくことです。供給や設備等の意味を表すプロビジョン（provision）という単語がもととなって派生した言葉です。

なるほど。AWSとは何かでも書きましたが、AWSはハードウェアに依存するデメリットを解消出来るのでそれを書いてある感じでしょう。

となると、Lambdaがなにをしているかは、『リクエストに対して自動的にスケーリングし、コードを実行しているもの』と言えるのでしょうか。

###実際の利用例
[AWS 導入事例: The Seattle Times](https://aws.amazon.com/jp/solutions/case-studies/the-seattle-times/)
公式からの引用ですが、S3での画像のアップロード等をイベントのトリガーとして、Lambdaに画像処理の関数を用意しておき、リサイズを行なっているそう。
S3→Lambda→DynamoDBみたいな組み合わせは公式も推している王道の様なので、基本的な使い方の例としては上のがわかりやすかったです。


###結局Lambdaとは、、、
調べた結果、自分の中でしっくりくる表現としては
**何らかのイベントをトリガーにLambda内に処理を書いておくことでその処理を行なってくれるもの**と言うのはわかりました。
S3→Lambdaなどの処理の流れや出来ることはわかりますが、それ以上のことをやっているとピンとこない話が多かったです。
概要的なことはわかりますが、実際使うレベルでの話は現状の私では闇が深すぎたので、実際に利用してみてその後調べてみたいと思います。

#まとめ
何らかのイベントをトリガーにLambda内に処理を書いておくことでその処理を行なってくれるもの、と言うのはわかりました。
折角なので何かLambdaを使ってやってみようと思い調べていますが、知識量が少なく厳しそうです。
先人の方が作ったものをなぞるでもいいので何かしら形にしてみたいと思います。

#参考サイト
[AWS公式のLambdaページ](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/welcome.html)
[プロビジョニングの説明](https://www.idcf.jp/words/provisioning.html)
Go Modulesで依存packageのversionを上書きする方法

## 概要
go buildをファイル更新時にホットリロードするため[realize](https://github.com/oxequa/realize)を使いたかったけど、realizeが依存しているpackageに破壊的変更があってビルドエラーになっていた。

package管理にはgo Modulesを使っていてdepでいう`[override]`する方法を検索したらgo.modに`replace`のディレクティブを指定し、versionを置き換える事ができるようだった。

```go.mod

 require (
 	// something package
 )
 
 replace (
 	github.com/go-siris/siris => github.com/go-siris/siris v7.3.4+incompatible
 )
 ```

## 公式ドキュメント
https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive
【salesforce】Classic基本知識ータブと項目名の変更

#タグ名変更
業務仕様により、標準オブジェクトまたはカスタムオブジェクトに対するタブ名を変更する可能性があるため、本セクションはタブ名変更の簡単な手順を記載します。
##手順
- 設定
    1. クイック検索で、「タブ」で検索して、「タブと表示ラベルの名称変更」をクリックする。
    2. 変更対象タブ対応行の左の「編集」をクリックする。
    3. 「名前」を変更後のタブ名に変更して、「次へ」をクリックする。
    4. 該当オブジェクトの各変更できる項目を一連的に変更していることを確認して、「保存」をクリックする。

#項目名変更
業務仕様により、標準オブジェクトまたはカスタムオブジェクトの項目名を変更する可能性があるため、本セクションは項目名変更の簡単な手順を記載します。
※標準オブジェクトの項目名変更はタブ名変更の手順4の時、変更できる。詳しい手順はここで割愛します。
##手順：カスタムオブジェクト
- 設定
    1. クイック検索で、「オブジェクト」で検索して、「作成」セクション配下の「オブジェクト」をクリックする。
    2. 変更対象項目の所属オブジェクト対応な「表示ラベル」をクリックする。
    3. 変更対象項目左の「編集」をクリックする。
    4. 「項目の表示ラベル」を変更後の項目名に変更して、「表示ラベルを変更すると、既存差し込みテンプレートに影響が出る可能性があります。」アラートの「OK」をクリックして、保存します。

#参照資料
[【セールスフォースヘルパ】オブジェクト、タブ、項目の表示ラベルの名称変更](https://help.salesforce.com/articleView?id=customize_rename.htm&type=5)
1 + "0123" が84になる言語

twitterで見つけたネタ。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">C++は基本的なところが難しいというか、内部的な処理を考えさせられる感じ。例えば、これでどのように出力されるかとか。<br><br>int main() {<br> auto x = &quot;0123&quot;;<br> std::cout &lt;&lt; 1 + x;<br>}</p>&mdash; Lillian (@Lily0727K) <a href="https://twitter.com/Lily0727K/status/1163975085008441344?ref_src=twsrc%5Etfw">August 21, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

これで1 + "0123"が84になる言語ってあるの？って話題になっていたので、tclならなるよっと試してみました。

tclインタプリタの起動はtclshです。最近のUbuntuはデフォルトで入ってないので、自力で入れてください。

```
> tclsh
% expr 1 + "0123" 
84
%
```

84ですね。
docerfileを作成するときに出くわした、NodeのLTSとCURRENTってなに？

#LTSとCURRENTとは
**LTS**
Long-term Supportの略で、長期の保守運用が約束されたバージョン

**CURRENT**
最新版だが、安定性を約束しないことで機能追加を盛り込んだバージョン

###余談
node:~-alpineというのはなんだ。
これは軽量Linuxで、ベースイメージでよく使われるcentosやubuntuと比べてかなり容量が小さい。
ESP32でRTCM3受信機

#ESP32でRTCM3受信機
農業業界で少しづつ普及しつつあるRTKですが、基地局の補正情報をトラクターの自動操舵装置に流さないとならない、という制約があります。
現状、Androidで[Lefebure NTRIP Client](http://lefebure.com/software/android-ntripclient/)を使うのが一般的ですが、iPhoneだったりガラケーでは使えないのでESP32からテザリングで基地局の補正情報を拾ってくるものを作ってみました。

また、従業員など複数の利用者がいる場合でも、テザリングのIDとPasswordを共通化しておけば、スマホや人間が変わっても使えるというメリットもあります。

![UNADJUSTEDNONRAW_thumb_2e59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/181687/9fee4fde-c2c3-7175-797c-0e72ee2d4227.jpeg)

##材料

Arduino RS232Cシールド https://www.switch-science.com/catalog/1859/
RS232Cケーブル https://www.amazon.co.jp/gp/product/B078SRG81K/
##Arduinoに入れるプログラム
https://github.com/GLAY-AK2/NTRIP-client-for-Arduino
WiFi,NTRIP Casterの設定を入れます。
初期設定のままだとハードウェアシリアルのUART0に出力されますが、デバッグ等のためにUART2とかに補正データを出力した場合は、ソースの変更とボードのジャンパーピンも変更してください。

例

```NTRIPClientSample.ino
26行目に追加 Serial.begin2(115200);
67行目 Serial2.print(ch);

```

またUART1を使う場合はハードウェアの制約があります。こちらを参考にしてください。
https://qiita.com/T-YOSH/items/0ce41136c535c723affb

##蛇足1
試してないけど、RN42とかのBluetooth SPPモジュール使えば無線化できるはず。
RN42 XBee http://akizukidenshi.com/catalog/g/gM-08690/
XBeeシールド https://www.switch-science.com/catalog/1262/

##蛇足２
NMEA出力ができる機種の場合、TinyGPS++を使ってAmbientに送ると、自動的に作業ログを作れます。（書いたソースはあるんだけどバグってるので調整中）
JanomeでNEologd辞書を使う

以下の公式ドキュメントでビルド方法が紹介されていますが、Janome自体をビルドせずに、ユーザー定義辞書としてNEologd辞書を使う方法です。

[(very experimental) NEologd 辞書を内包した janome をビルドする方法](https://github.com/mocobeta/janome/wiki/(very-experimental)-NEologd-%E8%BE%9E%E6%9B%B8%E3%82%92%E5%86%85%E5%8C%85%E3%81%97%E3%81%9F-janome-%E3%82%92%E3%83%93%E3%83%AB%E3%83%89%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)


ビルド済みの辞書ファイルを共有しておきます。
NEologdの20190819-01バージョンで作成しました。

https://www.dropbox.com/s/u8cw8m7o6sp1twm/neologd20190819-01.tar.gz

以下のようにColaboratory等でも利用できます。

https://colab.research.google.com/drive/1KnUtynqjDlAf9edVZG1BhKLIXQSIv1xy

# 辞書のビルド手順

自分で辞書のビルドをしたい方だけどうぞ。

Ubuntu 19.04で実行しています。

mecab-ipadic-neologdのリポジトリをクローンし、辞書のcsvファイルを１つにまとめます。

```shell-session
$ git clone https://github.com/neologd/mecab-ipadic-neologd.git
$ xz -dkv mecab-ipadic-neologd/seed/*.csv.xz
$ cat mecab-ipadic-neologd/seed/*.csv > neologd.csv
```

以下のPythonプログラムを実行します。

```python
from janome.dic import UserDictionary
from janome import sysdic
user_dict = UserDictionary('neologd.csv', 'utf8', 'ipadic', sysdic.connections)
user_dict.save('neologd')
```

`neologd` ディレクトリがビルド済みのユーザー定義辞書となります。

以下のように使用可能です。

```python
from janome.tokenizer import Tokenizer

t = Tokenizer('neologd')
text = '8月3日に放送された「中居正広の金曜日のスマイルたちへ」(TBS系)で、1日たった5分でぽっこりおなかを解消するというダイエット方法を紹介。キンタロー。のダイエットにも密着。'
for token in t.tokenize(text):
   print(token)
```

実行結果は以下のようになります。

```console
8月3日	名詞,固有名詞,一般,*,*,*,8月3日,ハチガツミッカ,ハチガツミッカ
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
放送	名詞,サ変接続,*,*,*,*,放送,ホウソウ,ホーソー
さ	動詞,自立,*,*,サ変・スル,未然レル接続,する,サ,サ
れ	動詞,接尾,*,*,一段,連用形,れる,レ,レ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
「	記号,括弧開,*,*,*,*,「,「,「
中居正広の金曜日のスマイルたちへ	名詞,固有名詞,一般,*,*,*,中居正広の金曜日のスマイルたちへ,ナカイマサヒロノキンヨウビノスマイルタチヘ,ナカイマサヒロノキンヨービノスマイルタチヘ
」	記号,括弧閉,*,*,*,*,」,」,」
(	名詞,サ変接続,*,*,*,*,(,*,*
TBS	名詞,固有名詞,一般,*,*,*,TBS,ティービーエス,ティービーエス
系	名詞,接尾,一般,*,*,*,系,ケイ,ケイ
)	名詞,サ変接続,*,*,*,*,),*,*
で	助詞,格助詞,一般,*,*,*,で,デ,デ
、	記号,読点,*,*,*,*,、,、,、
1日	名詞,固有名詞,一般,*,*,*,1日,ツイタチ,ツイタチ
たった	副詞,助詞類接続,*,*,*,*,たった,タッタ,タッタ
5分	名詞,固有名詞,一般,*,*,*,5分,ゴフン,ゴフン
で	助詞,格助詞,一般,*,*,*,で,デ,デ
ぽっこり	副詞,一般,*,*,*,*,ぽっこり,ポッコリ,ポッコリ
おなか	名詞,一般,*,*,*,*,おなか,オナカ,オナカ
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
解消	名詞,サ変接続,*,*,*,*,解消,カイショウ,カイショー
する	動詞,自立,*,*,サ変・スル,基本形,する,スル,スル
という	助詞,格助詞,連語,*,*,*,という,トイウ,トユウ
ダイエット方法	名詞,固有名詞,一般,*,*,*,ダイエット方法,ダイエットホウホウ,ダイエットホウホー
を	助詞,格助詞,一般,*,*,*,を,ヲ,ヲ
紹介	名詞,サ変接続,*,*,*,*,紹介,ショウカイ,ショーカイ
。	記号,句点,*,*,*,*,。,。,。
キンタロー。	名詞,固有名詞,一般,*,*,*,キンタロー。,キンタロー,キンタロー
の	助詞,連体化,*,*,*,*,の,ノ,ノ
ダイエット	名詞,サ変接続,*,*,*,*,ダイエット,ダイエット,ダイエット
に	助詞,格助詞,一般,*,*,*,に,ニ,ニ
も	助詞,係助詞,*,*,*,*,も,モ,モ
密着	名詞,サ変接続,*,*,*,*,密着,ミッチャク,ミッチャク
。	記号,句点,*,*,*,*,。,。,。
```
AzureAppServiceで特定のIPアドレス以外からのアクセスを拒否する

## 【シナリオ】
社内に向けて公開しているサービスが Azure App Service 上に乗っている。
なるべく簡単な方法で、社内ネットワークのパブリックIPアドレスからのみアクセスが可能となるように制御をしたい。

## 【方法】
### 1. Azure Portal 上の対象の App Service を開き、ブレードからネットワークを選択する。
![スケッチ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485970/f0b72410-c80f-2fb8-d005-de435acfd369.png)

### 2. アクセス制限のアクセス制限を構成するを選択。
![スケッチ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485970/3c5c007e-6a82-a4d7-02ee-af431ac366d2.png)

### 3. ~.azurewebsites.net の方のタブを選択し（デフォルト）、[＋]規則の追加をクリック
![スケッチ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485970/ce71d3ce-ac8a-099c-f1f7-3f4a38e5c8a3.png)
> ~.scm.azurewebsites.net は管理者ツール。
Azure Portal で言うところの、高度なツール → Kudu
今回は対象ではありませんが、管理者の制限までしたい場合はこちらも設定する必要があります。
scm の方には、標準の方と同じ設定を使用するチェックボックスがあるので、同レベルで管理するのであれば、これで問題ないかと。

### 4. ルールを設定して、規則を追加する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485970/f06ca200-5487-9c60-0860-fdb9b6a5b5f4.png)

> ルールを設定した時点で、全てのIPを拒否するルールが優先度最低で作成されます。
よって、1件アクセス許可ルールを設定するだけで、それに該当しない場合は全て拒否してくれるようになります。

**これにて完了！**

## 【確認】
- 指定したIPアドレスから App Service を見た場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485970/cbe68e91-3479-a195-878a-26e483727ce4.png)
> デフォルトのやつ。

- それ以外のIPアドレスから App Service を見た場合
![deny.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/485970/a33d0d89-9fab-b472-3fb9-c609383d532e.png)
> アプリケーションが停止した扱いになるみたいですね。

## 【まとめ】
設定はとても簡単でした。
特定のIPからしかアクセスできないようにして欲しい！みたいな要望をいただくような案件もありますので、
比較的簡単に実装できる Azure App Service のIP制限機能は便利につかっていきたいです。

## 【参考】
[Azure App Service のアクセス制限 - Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/app-service/app-service-ip-restrictions)
create-react-appが動作しなくなった

# 概要
`create-react-app`しようとしたら以下のエラーが出て動作しなくなりました
困った...

```
❯ yarn create react-app my-app
yarn create v1.17.3
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
[3/4] 🔗  Linking dependencies...
[4/4] 🔨  Building fresh packages...
success Installed "create-react-app@3.1.1" with binaries:
      - create-react-app
[#####################################################################################################################################################] 149/149
Creating a new React app in /Users/****/Desktop/my-app.
Installing packages. This might take a couple of minutes.
Installing react, react-dom, and react-scripts...
yarn add v1.17.3
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error eslint@6.1.0: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "11.9.0"
error Found incompatible module.
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
```

# 解決方法

翻訳無いとほぼ何書いてあるか分からなかったけどこれで解決しました
[error eslint@6.1.0: The engine &quot;node&quot; is incompatible with this module. - 掘金](https://juejin.im/post/5d52cd9f6fb9a06b32606904)

## 手順

npmのキャッシュを削除する

```shell
sudo npm cache clean -f
```

`n`をインストールする

```shell
sudo npm install -g n
```
​
公式の最新のバージョンをインストールする

```shell
sudo n stable
```

npmの最新バージョンをインストールする

```shell
sudo npm install npm@latest
```

以上の手順で無事動くようになりました
備忘録）MySQLをwindowsサービスに登録

####実行環境
windows10、MySQL8.0

###記事の内容

MySQLをダウンロードインストールした後手動でwindowsサービスへの登録を行う際うまくMySQLが起動できなかったためその解決方法の記録。

###起こったエラー
#####1
サービス名(MySQL80)を登録するためにコマンドプロンプトを管理者権限で実行し以下を入力


```
C:\>"C:\Program Files\MySQL\MySQL Server 8.0\bin\mysqld" --install MySQL80
```
ここで環境変数にpathを追加するのを忘れていたため
`ファイルとして認識されていません`
とエラーが出た。
環境変数にpathを追加することで解決。(path:C:\Program Files\MySQL\MySQL Server 8.0\bin)

#####2
```
C:\WINDOWS\system32>NET START MYSQL80
MYSQL80 サービスを開始します.
MYSQL80 サービスを開始できませんでした。

サービスはエラーを報告しませんでした。
```

`C:\ProgramData\MySQL\MySQL Server 8.0`内にある`my.ini`ファイルを`C:\Program Files\MySQL\MySQL Server 8.0`にコピーすることで解決
Entity Framework Core 2.2で実行SQLをNLogに出力する

Nlogの出力方法や、EFCoreのログ出力方法はたくさんあるけど
意外とEFCore2.2でNLogに出力する方法が見当たらなかった為、書いておきます。

##Entity Framework CoreでSQLの内容をログに出したい…
Google先生で色々見つけた方法を試すと、非推奨だのなんだの怒られてしまった。
どうも見つけたのがEF Core 2.0や2.1でのやり方だったみたい。

##まず2.1とかはどういうコードなのか

```C#
private static readonly ILoggerFactory loggerFactory = 
new LoggerFactory(new[] { new ConsoleLoggerProvider((_, __) => true, true) });
```

```C#
optionsBuilder.UseLoggerFactory(loggerFactory)
```

こんな感じのコードがGoogle先生で良く引っかかってくると思う。
※↑はNLogじゃなくてコンソールに出ます。

##じゃあ2.2だとどうやるの？

```C#
private static readonly ILoggerFactory LoggerFactory = new ServiceCollection().AddLogging(builder =>
    builder.AddProvider(new NLogLoggerProvider()).AddFilter(DbLoggerCategory.Database.Command.Name, LogLevel.Debug))
    .BuildServiceProvider().GetService<ILoggerFactory>();
```

```C#
optionsBuilder.UseLoggerFactory(LoggerFactory)
```

結構変わってますね。
「builder.AddProvider」部分ですが、ここに「NLogLoggerProvider」を渡すと
NLogに念願の実行SQLが出力されます！


※2019.08.27 修正
インスタンスを毎回生成するような作りになっていたためstaticプロパティに変更
ROS の Parameter Server を python で永続的に使う

# 目的
Parameter Server に蓄えた情報は roscore がシャットダウンされると全て消えてしまう。
電源を入れ直した時にも永続的に蓄えた情報を使うにはシャットダウンの直前にそれをsaveしておいて次に roscore を起動した直後にloadすれば良い。

## コマンドライン
コマンドラインでのsave/loadは次のコマンドで実行できる。保存するファイル名をtest.yamlとする。

```.sh
$ rosparam dump test.yaml
$ rosparam load test.yaml
```

## python
同じことをpythonプログラムから行いたい。
上記コマンドラインでsaveしたファイルを見てみると余計な情報（run_id等）まで入っている。
従って、必要なパラメーターだけをファイルにsave/loadしたい。
pythonのROSモジュールであるrosparamを使えば実現できるのだが、ちょいと面倒なデータ構造になっているのでそれを関数にまとめてみた。

```.py
#!/usr/bin/env python

import rospy
import rosparam

#---------------------------------------------------------------------------
# save/load param
#---------------------------------------------------------------------------
def save_param(filename, paramname):
    rosparam.dump_params(filename, paramname)

def load_param(filename, paramname):
    (param, ns) = rosparam.load_file(filename)[0]
    rospy.set_param(paramname, param)
```

使い方はこんな感じで

```.py
if __name__ == '__main__':
    rospy.init_node('params_test')
    try:
        print 'try to load test.yaml'
        load_param('test.yaml', '/global_params/test')
    except:
        print 'make param and save it'
        rospy.set_param('/global_params/test', {'init':{'px':0, 'py':0, 'dir':0}, 'p1':{'px':0, 'py':1, 'dir':20}})
        save_param('test.yaml', '/global_params/test')
    # load /global_params/test and print it
    test = rospy.get_param('/global_params/test')
    print test
```

## 備考
- load_param関数で指定したファイルが存在しない時は例外が発生するので使う時に処理を書いておくのが良い。
- rosparamモジュールにもset_paramやget_paramがある。
- しかし、情報が辞書の場合にエラーとなってしまうようだ。
- 従って、set_param や get_param は rospy モジュールで使うようにするのが良いだろう。
Codebuildでjava.lang.OutOfMemoryError

https://qiita.com/fake-deli-ca/items/b2cadce085595c57636d

これと似たような話で、CodeBuildでもおきたため、その対処方法を記載。

# 前提
- JenkinsがMaster、Buildの実態はCodeBuildで実施。
- Gradleを利用。

# 問題

Jenkinsから呼び出されるCodeBuild pluginで以下のようなErrorが起き、CodeBuildがエラーになる。

```
[AWS CodeBuild Plugin] java.lang.OutOfMemoryError: Metaspace
```

# 対処
buildspec.ymlに以下のような対処を打つ。

``` yaml

version: 0.2

phases:
  install:
    runtime-versions:
      java: openjdk11
    commands:
      - chmod +x ./gradlew
      - touch gradle.properties
      - |
        cat <<EOL > gradle.properties
        org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m
        EOL
```

gradle.propertiesを作成し、それに記載するgradleのvm引数を`org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m`のように追加すればよい。

# 補足

https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-compute-types.html

この対処を打つ場合、codebuildのコンピューティングタイプはbuild.general1.medium以上のほうがよい。

# 補足その2

UnitTestの場合であれば、どちらかというと↓
https://qiita.com/fake-deli-ca/items/b2cadce085595c57636d

本対応は、「Gradle自体はこちらによるとデフォルトでは1024MBヒープサイズを確保する」というのが足りなかった場合。(この辺Gradleはわかりにくい･･･。)
１日のまとめ　8/23(金)

昨日の課題には手を着けず急遽、MySQLの基礎でも大事そうな作業用ユーザーについて学習した。
実際にターミナルでコードを書いて作成方法と概念は理解できたものの実際に外部ファイルを使ってみないと流れが分からない。後日Atomで実際にmysqlファイルを作成してみようと思う。



① MySQL



ググった事
・作業用ユーザー..特定の操作のみ行うことが出来るユーザーの事。
・rootユーザー..予め用意されているユーザーで全ての操作を行うことが出来るユーザーの事。



⑴作業用ユーザーの設定

作成理由...rootユーザーで何でも操作できるが故に、誰かが誤って操作してしまうと、データが消える可能性が高い為。

作成記述

````
create user ユーザー名＠ホスト名　identified by 'パスワード';
````

実際にターミナルで記述

```
mysql> create user hahakigi@localhost identified by 'yuzu3511';

```

結果

````
Query OK, 0 rows affected (0.00 sec)
```

この表記があれば作業用ユーザーの作成完了、identified by..はパスワードの設定。




次に権限を与える記述

```
grant all on データベース名　* to ユーザー名@ホスト名;
```

実際にターミナルで記述

```
mysql> grant all on testdb01.* to hahakigi@localhost;
```
結果

```
Query OK, 0 rows affected (0.00 sec)
```
この表記によって、hahakigiユーザーに対してtestdb01の全てのテーブルに関する権限を与えた。
Chromeの--disable-dev-shm-usageオプションについて

kubernetesで動かしてるスクレイピングのアプリケーションがよく落ちたので調べていたら`--disable-dev-shm-usage`という起動フラグを指定するのが良さそうとのことだった
`--disable-dev-shm-usage`がなんのフラグなのか気になったので簡単に少し調べてみた

```
--disable-dev-shm-usage
```
Dockerはデフォルトではメモリスペースに`/dev/shm`という場所を使うがこれは64MBと小さい。そのためChromeがメモリ不足でクラッシュしてしまう  
Chrome 65から起動時に`--disable-dev-shm-usage`を指定することで、シェアドメモリファイルの保持場所を`/dev/shm`の代わりに`/tmp`ディレクトリを使うようになる  

補足
`/dev/shm`：ファイルシステムレベルの共有メモリ
`/tmp`：ディスク
carrierwave 2.0.0の不具合について

## 起こる症状
* carrierwaveが2.0.0の状態で、remoteのURLから画像をアップロードしようとするとエラーが発生する模様。

```rb
# omniauthの画像URLとか
user.remote_profile_image_url = auth.info.image

# NoMethodError (undefined method `[]' for nil:NilClass)
```

* 該当するエラー箇所は[ここ](https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/downloader/remote_file.rb#L28)らしい

```rb
# lib/carrierwave/downloader/remote_file.rb

def filename_from_header
  if file.meta.include? 'content-disposition'
    match = file.meta['content-disposition'].match(/filename=(?:"([^"]+)"|([^";]+))/)
    match[1].presence || match[2].presence # ここ
  end
end
```

## 解決策
* バージョンを1.3.1に戻す

```rb
gem 'carrierwave', '~> 1.3.1'
```
CentOS7でJupyter Notebookを簡単インストール・設定

Webスクレイピングや機械学習の検証用で使いたかったので、出来る限りシンプル、スピーディにJupyter Notebookをインストールし、ブラウザで起動させる手順を記載します。

## 前提
Python3をインストール済み
Anaconda3を使いJupyter Notebookをインストール
rootユーザで実行
ホームディレクトリ配下を使う

## Jupyter Notebookインストール
### Anacondaダウンロード
```
curl https://repo.continuum.io/archive/Anaconda3-4.3.1-Linux-x86_64.sh -O
```

### 必要なパッケージインストール
```
yum install bzip2 -y
```

### Anacondaインストール
```
bash ./Anaconda3-4.3.1-Linux-x86_64.sh 
※以下対話形式で進みます。

Welcome to Anaconda3 4.3.1 (by Continuum Analytics, Inc.)
In order to continue the installation process, please review the license
agreement.
Please, press ENTER to continue
>>> そのままEnter。ライセンスを読み進めていく。

Do you approve the license terms? [yes|no]
>>>yes

Anaconda3 will now be installed into this location:
/root/anaconda3

  - Press ENTER to confirm the location
  - Press CTRL-C to abort the installation
  - Or specify a different location below

[/root/anaconda3] >>>そのままEnter

Do you wish the installer to prepend the Anaconda3 install location
to PATH in your /root/.bashrc ? [yes|no]
[no] >>>yes
※bashrcにパスを通す設定が入る。
```
### bashrc読み込み
```
source ~/.bashrc
```

### Jupyterバージョン確認
```
jupyter --version
```

## Jupyter Notebook設定

### コンフィグファイルを編集の前にいくつか実施。
```
# Configファイルのパスが通っていることを確認
jupyter --path
※ホームディレクトリに .jupterとパスが通っていること。

# configファイル作成
mkdir ~/.jupyter
touch ~/.jupyter/jupyter_notebook_config.py

# Jupyter用のディレクトリ作成。テストファイル作成。
mkdir ~/jupyter_files
touch ~/jupyter_files/test.py

# iPythonでログインパスワードの設定
ipython
※以下入力

・パスワード暗号化用ライブラリ読み込み
In [1]: from notebook.auth import passwd
・パスワードを入力
In [2]: passwd()
Enter password: 
Verify password:
Out[2]: 'sha1で暗号化された文字列が出力されるのでメモする'
・抜ける
In [3]: exit
```

### コンフィグ編集

```
vi ~/.jupyter/jupyter_notebook_config.py
※以下記載。すべてのIPアドレスから接続を受け入れ、8888番ポートで起動する設定。

c = get_config()

c.NotebookApp.ip = '*'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8888
c.NotebookApp.password = u'先程出力されたsha1から始まる暗号化パスワードを記載'
c.NotebookApp.notebook_dir = '/root/jupyter_files/'
```

## Jupyter Notebook起動


### Jupyter Notebookの実行

```
jupyter notebook
```

ブラウザで以下指定する。
http://サーバIP:8888
<img width="582" alt="キャプチャ.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/a5f41c57-bd2e-a851-a8b1-fbf483c22b4f.png">

先程設定したパスワードでログイン。Jupyter用ディレクトリに作成したテストファイルが表示される。
<img width="495" alt="キャプチャ2.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131627/11a4384c-a9b0-58a0-f12c-c69bce5b0595.png">


## Jupyterをsystemdで制御できるようにする

### Jupyterのパスを確認

```
which jupyter
/root/anaconda3/bin/jupyter
```

### Unit定義ファイル作成
```
vi /etc/systemd/system/notebook.service
※以下記載

[Unit]
Description = Jupyter Notebook

[Service]
Type=simple
PIDFile=/var/run/jupyter-notebook.pid
ExecStart=/root/anaconda3/bin/jupyter notebook
WorkingDirectory=/root/
User=root
Group=root
Restart=always

[Install]
WantedBy = multi-user.target

systemctl daemon-reload
```

### 起動、自動起動
```
systemctl daemon-reload
systemctl start notebook
systemctl enable notebook
systemctl status notebook
```

これでJupyter Notebookをブラウザで起動させるところまではできました。
JavaScriptで連想配列を作る時の注意点

#前書き#
こんにちは！
最近をJavaScriptを使う機会が多く連想配列で詰んだのでその時の解決策を書き記します(^^)
初心者なので暖かく見守ってください！ｗ

#例#

まず、連想配列とはキーと値がペアになったデータのことです。

phpでは、例えば次のように書くことが可能です （ 他にも方法はあります ）

```php
$test = [ ];
$test['a'] = a;
$test['b'] = b;
$test['c'] = c;
```

なので、JavaScriptでも次のように書いてしまいがちですがこれだと作れません(>_<)

```js
var test = [ ];
test['a'] = 'a';
test['b'] ='b';
test['c'] = 'c';
```

何故かというと、JavaScriptの場合はオブジェクトの生成が{ }、配列の生成が[ ]となっています
なので、正しくは

```js
var test = { };
test['a'] = 'a';
test['b'] = 'b';
test['c'] = 'c';
```

これだといけます(^^)

ちなみに、こんな書き方もあるみたいです~

```js
var test= new Object();
test.a = 'a';
test.b = 'b';
test.c = 'c';
```
Laravelを使う上で必須だと思われるコマンドやパッケージとか

Laravelを使う上で、ほぼ必須だなぁと思うコマンドやパッケージをまとめてます。
今後増やしていきたい

# 速度アップ系

## optimizeコマンド(laravel5.7>=)

`php artisan optimize`を実行することで、`php aritsan config:cache`と`php artisan route:cache`が行われます。5.5系まではコマンドの意味が異なっているので注意。(5.6ではコマンドが一度無くなっている)

なお開発環境では利用すべきではないので万が一やってしまったら`php artisan optimize:clear`をしておきましょう。

## PHP7

言わずもがな。

## Opcache

Laravelを使う上で、本番ではOpcacheを有効にしておく。
> OPcache はコンパイル済みのバイトコードを共有メモリに保存し、PHP がリクエストのたびにスクリプトを読み込み、パースする手間を省くことでパフォーマンスを向上させます。

## [beyondcode/laravel-query-detector](https://github.com/beyondcode/laravel-query-detector)

N+1クエリを検出してくれるやつ。debugbarとも連携が可能なので連携しておくと○。

# 便利系

## [barryvdh/laravel-ide-helper](https://github.com/barryvdh/laravel-ide-helper)

これがないとIDEでの開発は大変なやつ。

## [caouecs/Laravel-lang](https://github.com/caouecs/Laravel-lang)

Laravelで利用されているメッセージを翻訳してるリポジトリです。
サードパーティとしてcommandで実行できるパッケージも存在しますが４つだけなのでそのままphpをコピーしましょう。

# デバッグ系

## [barryvdh/laravel-debugbar](https://github.com/barryvdh/laravel-debugbar)

debugbarほんといい。