OmniAICreator/Qiita-1.07M huggingface dataset:
neovimにカラースキーム(hybrid)を設定

nvimにカラースキームを設定したので、初心者でもわかりやすいように書いておこうと思います。

#カラースキーム導入後のnvimのファイル全体像
~/.configの中にこのように配置されています。
現在はcolorsができていますが、最終的にこの形になればOKです。
<img width="324" alt="スクリーンショット 2020-03-24 21.03.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/543154/611fe46d-e4a0-534c-9a9e-1bc248b04cbb.png">

#カラースキームをgit cloneで持ってくる

```console:.config
git clone https://github.com/w0ng/vim-hybrid.git
```
colorsファイルをnvimファイル直下に移動

```console:.config
mv nvim/vim-hybrid/colors/ nvim
```
#設定ファイルにカラースキーム表記を追加
neovimはinit.vimが設定ファイルのため、以下のように記述する
カラースキームが適用できているはず！

```console:.config/nvim/init.vim
set background=dark
colorscheme hybrid
```
AndroidのPR作成前のチェックリスト

## PR作成の際に

PRを作成する際に最近自分が自分がやりがちなミスを列挙します。

深い設計や効率の良いコードは難しくとも単純ミスを減らすためにのチェックリストです。PR作成前の動作確認と、せめてこのチェックリストは見返すようにしています。

## チェックリスト

- [x] レイアウトファイルやManifestファイルはなるべく閉じタグをなくす

中に他のタグを挟む必要が無い場合は、<TextView ...  />として、コンパクトにタグを記述する。

- [x] Log.dなどデバッグ用のコードの削除
- [x] 日本語文字列やURLはリソースファイルを使って表記
- [x] アップロードキーなど、コミットに含めるべきで無いファイルをGit管理に含めていないか？
- [x] 変数名、メソッド名はUpperSnakeCaseで命名する
- [x] レイアウトファイルのインデント幅は統一されているか？
- [x] 変数やメソッドでprivate宣言に変更すべきところが残っていないか？
- [x] プロジェクトでktlintフォーマッターを導入している場合は、フォーマットコマンド実行
- [x] Androidに限らず、マージやリベース時のコンフリクト解消時のミス
- [x] 各ファイルの右上のチェックマークがOKになっているか
<img width="57" alt="スクリーンショット 2020-03-24 20.58.38.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479957/a76ed207-d2c6-dda1-d4a7-d4bf3c81b4ee.png">

このチェックマークがいつもエラーを検知してくれたり、知らなかったメソッドをサジェスションしてくれていることに気付けて助かっています。特にライブラリをアップデートした場合など、コードを変更する必要が出てくることが多いです。


## PR作成後

PR作成後もすぐにレビュー依頼をするのではなく、PRのfile changedでPR中で変更したファイルを全て確認する。

PRに含める全ての変更が見れるので、最後の最後に誤りに気付けるかもしれません。自分の場合はここでレイアウトファイルのインデント崩れに気付けたりします。
【JavaScript】全ての値がオブジェクトに`なり得る`

## はじめに
[開眼!JavaScript](https://www.oreilly.co.jp/books/9784873116211/)を読んだまとめ的な記事です。

## オブジェクト
「オブジェクトとは、名前と値を持つプロパティを格納する**コンテナ**にすぎない」
著者も言っていますが、オブジェクトとはただのプロパティを持った箱です。
これ以上も以下もありません。

## プリミティブ型
リテラルを使って値を生成したり、new演算子を使用せずにコンストラクタ関数で値を生成した際には、プリミティブ型となります。

```js
// どちらもプリミティブ型
const myString = 1;
const myString2 = String('hello')
```

プリミティブ型はオブジェクトではありません。
ですが、プリミティブ型でもStringオブジェクトで使用できるメソッドを使用することができます。
何故でしょう。

```js

// オブジェクトを生成
const myString = new String('hello');

console.log(myString.length);

// プリミティブ型を生成
const myString2 = 'hello';

console.log(myString2.length);
```

どちらも結果は「5」となります。

## プリミティブ型の振る舞い
プリミティブ型はオブジェクトとして扱われません。オブジェクトのように**扱われるまでは。**

上の例で、プリミティブ型に対してlengthを使用した時が、プリミティブ型がオブジェクトのように扱われたタイミングです。

このタイミングで何が行われているのでしょう。

```js

console.log(myString2.length);
```

ここが呼び出される前まではプリミティブ型として扱われています。
しかし、ここが呼び出されたタイミングで、このプリミティブ型をオブジェクトのように扱うために、JavaScriptがバックグラウンドで補完するラッパーオブジェクト（new String('hello')のような）を生成します。

つまり、下記の２つは同じ意味となります。

```js

const myString = 'hello';
console.log(myString.length)

console.log((new String('hello')).length)
```
## まとめ
つまり、JavaScriptは全ての値がオブジェクトということではありません。
タイトルの通り、**JavaScript全ての値がオブジェクトのような振る舞いをする**ということです。
RaspberryPiでwebsocket起動時に３セッション立ち上がる


# 概要

簡単に言うと

* Raspberry Pi 3 Model B+ 上で
* Djangoでwebsocket通信する用にchannelsを導入したところ
* server起動時に３セッション起動する問題が発生
* 原因は起動時のIPを0.0.0.0にしていた

# 詳細

## Macでは問題なかった

httpサーバ件websocketできるアプリケーションをpythonのDjangoで開発しており、手元のmacでは問題なく動いていました

こんな感じ

```
% python manage.py runserver 0.0.0.0:8000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
March 24, 2020 - 11:05:01
Django version 3.0.4, using settings 'mysite.settings'
Starting ASGI/Channels version 2.4.0 development server at http://0.0.0.0:8000/
Quit the server with CONTROL-C.
WebSocket HANDSHAKING /ws [127.0.0.1:61445]
WebSocket CONNECT /ws [127.0.0.1:61445]
```

## Raspberry Piで起動

Raspberry Pi上で起動するとこんな感じ

```
$ python manage.py runserver 0.0.0.0:3000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
March 24, 2020 - 11:07:05
Django version 3.0.4, using settings 'mysite.settings'
Starting ASGI/Channels version 2.4.0 development server at http://0.0.0.0:3000/
Quit the server with CONTROL-C.
WebSocket HANDSHAKING /ws [192.168.0.17:60036]
WebSocket HANDSHAKING /ws [127.0.0.1:42472]
WebSocket CONNECT /ws [192.168.0.17:60036]
WebSocket CONNECT /ws [127.0.0.1:42472]
WebSocket HANDSHAKING /ws [192.168.0.8:61638]
WebSocket CONNECT /ws [192.168.0.8:61638]
```

>  `192.168.0.17` はRaspberryPiのIP

何故か３セッション起動する。
debugして情報を見るとこの３セットあった。

|host|client|
| ---- | ---- |
|192.168.0.17:3000|192.168.0.17:60036|
|192.168.0.17:3000|192.168.0.8:61638|
|0.0.0.0:3000|127.0.0.1:42472|


`192.168.0.17` と `0.0.0.0` と `127.0.0.1` は分かるとして`192.168.0.8` がどこから出てきたのか。。。

## 謎のセッションを確認

一応動くか見てみた

```
% wscat -c ws://192.168.0.8:3000/ws
Connected (press CTRL+C to quit)
>

```

動いた。。。（ヤメテ

## 解決方法

`runserver` で起動時に、 `0.0.0.0` をやめて `localshost` にした

```
$ python manage.py runserver localhost:3000
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
March 24, 2020 - 11:25:24
Django version 3.0.4, using settings 'mysite.settings'
Starting ASGI/Channels version 2.4.0 development server at http://localhost:3000/
Quit the server with CONTROL-C.
WebSocket HANDSHAKING /ws [127.0.0.1:43018]
WebSocket CONNECT /ws [127.0.0.1:43018]
```

`127.0.0.1`でも同じように解決した

# 結論

`localhost`のつもりで`0.0.0.0`指定するのは辞めよう
ここが参考になりました。[127.0.0.1とlocalhostと0.0.0.0の違い]( https://qiita.com/1ain2/items/194a9372798eaef6c5ab )
【JavaScript】一度は聞いた「即時関数」と「クロージャ」について

### 概要

一度は耳にしたであろう「即時関数」「クロージャ」について簡易的にまとめました。

### 即時関数

名前の通り、即実行される関数のことですね😋
通常、無名関数を実行する時は、下記のように一旦変数に格納して括弧演算子で実行したりします。

```js:
var hello = function(name) { return `${name}さん、Hello!!`; };
hello('太郎') // 太郎さん、Hello!!
```
ですが、JavaScriptには**即時関数**と呼ばれる構文が存在します。
上の例を即時関数で書き換えると、以下のような記述になります。

```js:
(function(name) { return `${name}さん、Hello!!`;})('太郎'); // 太郎さん、Hello!!
```
上のように括弧(グループ化演算子)で囲むことにより、定義と実行が行われるのですね。
* ちなみに、以下のように即時関数に関数名をつけたりもできます。

```js:
(function hello(name) { return `${name}さん、Hello!!`;})('太郎'); // 太郎さん、Hello!!
```

さて、即時関数はどういった時に使用するのでしょうか？
これは、**グローバルスコープの汚染するを防ぐ方法**として利用されたりしています。
ちなみに、ここでの「グローバルスコープの汚染する」は、グローバルに変数や関数を宣言することを指します。
**複数人での開発**したり**複数のライブラリ**読みこんだりしている場合に、グローバルスコープが汚れてしまうことで、
変数名や関数名が重複してしまうといったことが起きたりしてしまいます🤮

この**グローバルスコープの汚染するを防ぐ方法**ですが、即時関数だけではなく他にも方法があります。
オブジェクトを名前空間として用いる方法です。

```js:
var myHello = myHello || function(name) { return `${name}さん、Hello!!`; };
myHello('太郎') // 太郎さん、Hello!!
```
上のように、`myHello`が既に定義されているときはそっちを優先みたいに名前の衝突は防げますね😏
他にも、関数を名前空間として用いる方法もあります。
関数内で宣言される変数は、**関数内にスコープ**を持ちます。(ローカル変数と呼びます。)
これは、関数の中からはアクセスできるけど外からはアクセスできません。
この性質を利用してしまえば名前の衝突をグローバルは汚れません。

```js:
var user = 'グローバル太郎';
(function(){
    var user = 'ローカル太郎';
    var user2 = 'ローカル太郎２';
})();
console.log(user); // グローバル太郎
console.log(user2); // ReferenceError
```
見事に、「グローバル太郎」を「ローカル太郎」にしなくて済みました。
ここで紹介した**関数内にスコープを持つ**という性質は結構重要な項目でして、次項で説明するクロージャでも利用されます。

### クロージャ

クロージャとは[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Closures)によると、下記のとおりです。
> クロージャは、関数と、その関数が宣言されたレキシカル環境の組み合わせです。

ソースコードで表すと、以下のような感じです。

```js:
function makeCounter() {
    var count = 0;
    function f() {
        return count++;
    }
    return f;
}
var counter = makeCounter();
```
上の`counter`がクロージャにあたります。
意味合い的には、**makeCounter関数内のf関数がクロージャとなってcounter変数に格納された**という感じですかね。
ちなみに、クロージャの仕組みについては、ScopeChainとかの説明が必要で長いので詳細は割愛します😔
（[このサイト](http://dmitrysoshnikov.com/ecmascript/es5-chapter-3-1-lexical-environments-common-theory/#closure)とか参考になります！）

さて、このクロージャとやらの何がすごいのか。
実は、**変数の永続化や隠蔽**を実現することができます。

前項でも触れましたが、ローカル変数 (関数の中で宣言された変数) というのは、関数の外からアクセスすることができません。
また、本来、**ローカル変数はその関数が実行されている間だけ存在します。**

```js:
function makeCounter() {
    var count = 0;
    console.log('makeCounterのローカル変数', count)
    function f() {
        return count++;
    }
    return f;
}
var counter = makeCounter(); // makeCounterのローカル変数 0
console.log(counter()); // 0
console.log(counter()); // 1
```
上のコードを実行してみると、`var counter = makeCounter();`のタイミングでローカル変数が存在しているのを確認できますが、**counter実行時にもローカル変数countの参照が残り続けている**ことも確認できます。
ローカル変数countがクロージャの内部状態としてメモリ上に残り続けているのですね。
また、`counter()`と実行することで変数の状態を変更できていますね。

まるで、makeCounterクラスのメンバ変数countがクラス内のメソッドfによってのみ変更できる感覚を思い出します🙄
クロージャはカプセル化されたオブジェクト的な存在というわけですね😎

以上、「即時関数」「クロージャ」について簡単なまとめでした。
Windowsでzipコマンドを利用する方法

自分なりに簡潔にまとめてみました。

# ざっくりとした方法
1. 「zip.exe」と「bzip2.dll」をダウンロード
2. 「zip.exe」と「bzip2.dll」を同じフォルダに格納
3. システム環境設定よりフォルダへのパスを設定
4. テスト

# 具体的に方法を説明
###  1. 「zip.exe」と「bzip2.dll」をダウンロード
・ Zip for Windows（zip.exe）
http://gnuwin32.sourceforge.net/packages/zip.htm

・Bzip2 for Windows（bzip2.dll）
http://gnuwin32.sourceforge.net/packages/bzip2.htm

**参考画像の赤色の箇所**よりダウンロードします。
ダウンロードが完了したら、圧縮されているのでファイルを展開します。

![スクリーンショット (35)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406190/180175eb-bdab-25ec-4450-6fad97cbbed2.jpeg)

###  2. 「zip.exe」と「bzip2.dll」を同じフォルダに格納
新規フォルダ「zip」を作成（名前は適当）
「zipフォルダ」に「zip.exe」と「bzip2.dll」を格納する

・「zip.exe」の保存場所
zip-3.0-bin ¥ bin ¥ zip.exe

・「bzip2.dll」の保存場所
bzip2-1.0.5-bin ¥ bin ¥ bzip2.dll

![スクリーンショット (37).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406190/f65db645-c076-87a2-52ee-060dfb2c9ac1.png)


### 3. システム環境設定よりフォルダへのパスを設定
「コントロールパネル > システムとセキュリティ > システム > システム詳細設定」でシステム詳細設定ウィンドウを開きます。
ウィンドウ下部の環境変数ボタンから環境変数ウィンドウを開きます。

![スクリーンショット (40)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406190/8b0913c7-df39-5f27-4d8d-8e70b261e85e.jpeg)


上部のユーザーの環境変数のPathを編集します。
リストよりPathをクリックして編集ボタンをクリック。
Pathの一覧が表示されます。

![スクリーンショット (42)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406190/34844803-145b-97ac-43e7-3344f7be1d32.jpeg)

今回は新規でPathを追加します。
新規ボタンをクリックしてzipフォルダのパスを入力してください。
入力が完了したら、OKボタンですべてのウィンドウを閉じていきます。

これでzipコマンドが使えるはずです。

### 4. テスト
コマンドプロンプトを起動して、以下の通りに入力します。

```
zip -v
```

バージョン情報が表示されれば無事完了です。
うまくいかない場合は、コマンドプロンプト及びPCの再起動をしてみてください！

# 参考にしたサイト
https://qiita.com/Shi-nakaya/items/83d2b2e2b34b897d3df8
https://note.mokuzine.net/win-cmd-zip/
警告なしでenumをforeach文で回す

##前書
今までやっていた方法だとenumのforeach文で警告が出たので覚書

##今まで使っていた方法
```C#
	//CS8605 null の可能性がある値をボックス化解除しています。
	foreach (MyEnum id in Enum.GetValues(typeof(MyEnum)))
	{
		//何かしらの処理
	}
```

##うまく行った方法
```C#
	//警告が出ない。少し長くなったが、型名をvarに変更できていい感じ
	foreach (var id in Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>())
	{
		//何かしらの処理
	}
```
wagon-ssh がホスト鍵が見当たらないといって接続できない

sshコマンドで接続できることは確認済みなのに、GitLab runner経由で mvn site:deploy すると、ホスト鍵が拒否されて接続できない。

RSA形式のホスト鍵が必要らしい。以下のコマンドでホスト鍵を登録する。

```bash
ssh-keyscan -t rsa your.host.name >> ~/.ssh/known_hosts
```

参考にしたSOエントリ。めちゃくちゃ助かった。

[Maven Wagon SCP is not able to establish a connection](
https://stackoverflow.com/questions/8323040/maven-wagon-scp-is-not-able-to-establish-a-connection/37477011#37477011?newreg=8ad1196f793f464eb45131f3aa08acb8)
Android9アプリ検証中に、プッシュ通知で何でポップアップされない？ってなったときに

アプリの動作検証担当になってここ数ヶ月、個人的には信じられない（単に直感的でない）ことにはまって数時間困った件を残します。

同じことで悩んでいる人の助けになれば幸いです。

## 事象

Android 9端末（Galaxy A20 SCV46とALLDOCUBE iPlay10 Pro U1006H）にて、
Javaで開発されたアプリの通知機能を検証するために、
インストール直後、通知は受け取れる（ステータスバーにはアイコンは出ている）が、場合によってポップアップされたりされなかったりする？？？
という悩ましい現象が発生。

## 原因

Androidのアプリ設定にて、検証中のアプリの設定画面を開いていた。
という至極シンプルなことだった。

## 対処方法

通知動作を確認するときは、アプリの設定画面を開いているプロセスを立ち上げっぱなしになっていないことを確認すること。
立ち上げているなら、落とすこと。


## 最後に

Androidのアプリ設定周りの内部仕様をわかっていないので、挙動だけで判断するに、
本来なら初回通知受診時に送信元が設定したパラメータを元に通知設定が作成されるはずが、
アプリの設定画面を開いた状態で通知を受け取ってしまうと、パラメータ値を無視してOS側のデフォルト値を使ってアプリ通知設定が出来上がってしまう。
すなわち、「音声のみ」の通知になるため、ポップアップされなかった。

動作検証で通知機能をちゃんと確認しようとした場合、確実にOSのアプリ設定画面は開くことになるはずなので、
悩まないで済むように、もしくは、その現象に気付けるようにこの記事を残す。


## 追伸

こういう大事なことは、Androidの開発者向けの説明資料には掲載されているのかもしれないが、今の所見つけられていない。。。
社内利用ツールを2020年らしいプロセスで作ってみる(Vue.js + Electron + SQLite3) Day2

# ここまでの流れ

とあるSIerにおいて、社内システムで案件、要員、収益などの登録、参照は出来るものの、計画立案時にアドホックに変えながら計数を見るような機能がなくて困っているため、休暇中にツールを作ってみる試みです。

1. ~~ツール作成の目的と動作環境を検討する~~ -> Day1
* ~~アーキテクチャをいったん検討する~~ -> Day1
* ユースケースを洗い出す -> Day2
* 画面イメージのスケッチを作成する -> Day2
* ドメインモデルを検討する（用語の定義、振る舞いの定義）
* ユースケース、画面イメージのワイヤフレーム、ドメインモデルを何周か見直す
* 当初決めた目的が果たせるか利用者目線を検証する(コンセプトの検証)
* 単純なCRUDアプリでアーキテクチャを検証する(実現方式の検証)
* コアになるユースケース1本だけプロトタイプ作成(MVP)
* 本格的に準備して開発を始める(テスト駆動のイテレーション開始)

【Qiita】[社内利用ツールを2020年らしいプロセスで作ってみる(Vue.js + Electron + SQLite3) Day1](https://qiita.com/takeout44/items/be3d2b47c84d8b487a68)

# 開発日記(Day2)

## GitHubにリポジトリを作成

draw.ioに入る前に、管理先となるGitHubリポジトリを作成して、ユースケース作るというissueおよびbranchを作成しました。
今回の活動は自分の周囲の人にも見せてフィードバックもらいたいので、Publicでやると決めていました。
ライセンスは Day1 で下調べしていた通り、GPLを選択しました。

./uml/　配下に配置したいので、ダサい方法ではありますが、ターミナルで uml/dummy.txt　を作成して一度リモートのfeatureブランチにpushしました。

## ユースケースを洗い出す

draw.ioを使って、まずは大雑把に出来ることを書きます。
保存先は先ほど作成したGitHubリポジトリ、featureブランチ、umlフォルダを選択し、拡張子は svg にしておきます。

キリがいいところまで書いたら上部の「Unsaved changes. Click here ti save.」を押してGitHubにコミットします。
File > Export As > PNG でローカルに保存したものが以下です。いい感じですね。

![useCase.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215924/538b2d1c-399b-de69-abb7-74b0ccce05de.png)

## masterブランチの更新

まず、忘れないうちに先ほどの dummy.txt は削除しておきます。（ターミナル操作）

初版のユースケース図が完成して作成したissueがクローズ可能になったので、masterに対してプルリクします。
プルリクのコメント欄に "close #1" という文言をつけて、マージ時に自動でissueが閉じるようにしておきます。

プルリク内容を確認する画面で、"Files changed" タブの書類マーク "Display the rich diff" ボタンを押すと、噂の図形としてdiffが見えるモードになりました。わーい。

![スクリーンショット 2020-03-24 17.38.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215924/a0d96165-3542-3e36-f06d-4dc25ca01883.png)

でも今回は新規作成だけなので、この強力さが活きるは変更のときですね。

GitHub ActionsによるCIを勧められますが、本格開発の開始時にします。
さくっと承認してissueのクローズとmasterブランチへのユースケース図配置を確認しました。

## 画面イメージをスケッチ

### メニューの検討

"Webサイト デザイン 見本" というそのままのキーワードでググって、いくつかサイトを見て回って情報インプットしました。

上部に大項目を横に並べて、カーソルオンで小項目のリンクが出てくる形式がよく見るので操作も万人に分かりやすそうです。
気に入らなくなれば後で変えてもいいですし、考えさせない原則でいったんこれを採用することにしましょう。

### メニュー以外の登録/参照

メニュー以外は単純な CRUD 操作や、表形式での参照が中心なので、ToDoリストアプリや、tableの見せ方などのデザインを参考にします。

要員登録や案件登録のCRUD系でいうと、一覧表示の表を起点として、新規登録ボタンが表と独立して存在、編集や削除用のボタンは表内に列として設ける、というスタイルが分かりやすそうです。
新規登録や編集が押下されたら登録内容を入力する画面に遷移するイメージです。

複数行編集は編集内容からしてなさそうですし、複数行削除も必要なシーンはとても限られていそうなので、チェックボックスは削ります。

## Day3にむけて

Day2はここまでです。今日は昼食の後に盛大にお昼寝してしまいました。。

画面イメージのスケッチを書いていると早くもユースケースの不足に気付きましたが、いい傾向ですね。
明日は今日の頭の中に見え隠れしていたドメインモデルのクラス図を作ってみて、ユースケースと画面イメージの見直しサイクル（ワイヤフレーム化含む）へ進めていこうと思います。

## 開発環境

Day2では実装まで行かないので、これは後でDay3かDay4に移動することになりそうです。

### クライアントPCスペック

* MacBookAir 2012年モデル
* macOS Catalina 10.15.3
* Intel Core i5 1.8GHz
* DDR3 4GB 1600MHz
* Intel HD Graphics 4000 1536MB
* SSD 128GB

### 各種ソフトウェアバージョン

* Chrome
* VisualStudioCode
* homebrew
* node
* npm
* electron
* vue-cli
* node-sqlite3

vue-electronというのがセットアップ簡単そうなので使うかもしれません。
[Magento]Load Balancer(負載平衡) for Magento

#目的
這是一次安裝經驗紀錄,當magento 使用nginx 做]Load Balancer(附載平衡)且將ssl安裝在Load Balancer機器上,所碰上的幾個問題

`302 loop`, `找不到網頁`

#安裝nginx

1 . 安裝EPEL 

```
yum install epel-release
```

2 . 安裝 nginx


```
yum install nginx
```

3 . 在 /etc/nginx/conf.d/ 中新增一個 lb.conf file

4 . 加入以下設定

```
# upstream 用於定義load balance
# 預設行為為round robin 這邊用權重來當範例
# ej為自行定義的名
upstream ej {
  server 192.168.10.9:9000 weight=1;
  server 192.168.10.8:9000 weight=3;
 
}
#定義nginx port 443
#使用者連線 yourdomain:443會自動導入到後端兩台web server
#proxy_pass 負載平衡接收到需求時會導向哪台機器
server {
  listen 443 ssl;
server_name yourdomain;

    ssl_certificate /etc/ssl/certs/yourdomain_com_tw.crt;
    ssl_certificate_key /etc/ssl/certs/ssl.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    location / {
        proxy_pass http://ej;
        proxy_set_header   Host    $host;
        proxy_set_header   X-Real-IP   $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
    }

#location / {
#  proxy_pass http://ej;
#}
}
```

#magento 端設定問題

當我只設定上面的Load Balancer後發現會卡在無限的302 redirect loop,後來翻查了文章發現是因為magento
在前面加入一層load balacer後並不知道前面已經使用了ssl所以需要加一段告訴magento讓他知道不需重新導向443的連結
在index.php Mage::run($mageRunCode, $mageRunType);前加入以下程式碼

```
if( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) ) {
    $_SERVER['HTTPS'] = 'on';
    $_SERVER['SERVER_PORT'] = 443;
}

Mage::run($mageRunCode, $mageRunType);
```

參考文章(reference)：
https://blog.dtask.idv.tw/Nginx/2018-07-31/
https://dotblogs.com.tw/eric_obay_talk/2018/08/03/112217
https://tech.webestimate.net/magento-has-a-redirect-loop-2/
https://naruzo.typepad.com/blog/2011/01/ssl-with-magento-behind-a-load-balancer.html
https://www.sonassi.com/blog/magento-kb/magento-https-redirect-loop-2
Facebookのシェアした際のプレビュー画面をlocal環境でも確認できるようにしたい

#今回の経緯
- facebookシェアデバッカーでfacebookでシェアした際にプレビュー画面がどう表示されるかURL確認したい
- ngrokで確認しようとしたが正常に表示されない

Facebookシェアデバッカー
https://developers.facebook.com/tools/debug/

#前提条件
- facebookのシェアボタンは設置できている
- facebook for developersの設定は完了している
- あとはシェアで結果を確認できる状態

#対策
- localtunnelを使用

```
lt -h "http://serverless.social" -p 3000
```

上記コマンド入力後に表示されるURLを使用し、シェアデバッカーで確認したところ問題なくプレビュー画面が確認できました。
しかしながら、localtunnelはすでに開発が行われいないようで今後使用できるかは不明です(2020.3.23確認)。
リスクもあると思われますので、恐れ入りますがその辺りはご了承ください。

以上です。
いいねやQiitaやTwitterのフォローいただけると励みになります！
お気軽にどうぞ〜

お疲れ様でした！！！
<hr>

##参考ページ
[Github Localtunnel is down #343](https://github.com/localtunnel/localtunnel/issues/343)
対戦オセロwebapi その4

#概要

対戦オセロwebapiを作ってみる。
構想と仕様を述べる。

#構想

オセロaiを持ち寄って、戦わせて、ランキングする。

#仕様

ai
web上に、設置したhtmlで、関数siroと関数kuroを持つ。
関数呼び出しには、引数がある。構造は、６４個のarray
８＊８の盤を表す。左上から右下へ繋がる。
1個は、0,1,2で0は黒、1は無、2は白を表す。
関数の戻り値は、置く位置を指す。１から６４の間である。

stage
iframeでaiを呼び出し、対戦させる。点数を付与して
ランキング表示する。

#成果物

実際に確認して欲しい。

https://embed.plnkr.co/plunk/lKu5YgdRXCK5jyyu

#aiのサンプルコード

https://embed.plnkr.co/plunk/0v0fMaS8CT2iPi9v

以上。
Splunkで使用されているPythonを対話モードで起動する

今回もSplunkのカスタムサーチコマンド作成の話で投稿します。
カスタムサーチコマンドを作成する際は、（SplunkではUbuntuとは別にPython本体を持っているため）Pythonにどのようなライブラリがあるかわからないため、カスタムサーチコマンドを直接編集しサーチバーでの実行を繰り返す作業をしなければならなくて非常に面倒でした。そこで、少しでも開発が楽になるように、Splunk上のPythonを対話モードで起動する方法を調べましたので、記載することにします。
なお、今回はUbuntu18.04で検証していますので、**他のOSの場合は使えない場合がある**ことをご承知ください。

#Splunk上のPythonを動かす

以下のコマンドを実行します。Splunk上のPythonが動作します。

```
# /opt/splunk/bin/splunk cmd python
Python 2.7.17 (default, Jan  7 2020, 18:09:21) 
[GCC 5.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 
```

この対話モードを利用してPythonの動作環境を調べれば多少は開発しやすくなると思います。
あと、外部ライブラリも調べてみましたが、残念ながらほとんど入っていませんでした。外部ライブラリを**無理やり**入れる方法は、別の投稿で記載します。

---

動作環境
Ubuntu 18.04.4 LTS
Splunk 8.0.2.1
WP lightningにてPlugin VK All in One Expansion Unit利用の際の設定他。

WP lightningにてPlugin VK All in One Expansion Unit利用の際自動で表示される設定を表示、非表示に設定する方法や他のスクリーンショットとメモ。
特にシンプルに設定する場合の方法。
１、固定ページによるサイト作成の際のフロントページの設定[外観][カスタマイズ][ホームページ設定][固定ページ][選択]から固定ページを選択。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/c8d68fb1-c1da-86b9-681f-b31b53891c5f.png" width="30%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/9cd965cc-bcd8-eb30-43d1-9cc12e87698f.png" width="30%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/2da6c577-34ac-8459-dd8a-4aeaa8e1bddb.png" width="30%">

２、固定ページからPlugin VK All in One Expansion Unit利用で追加表示されるコンテンツを下記のチェックを外し非表示にする。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/d59871c8-647c-1d8c-fa76-de962a3edbdd.png" width="50%">
【Python初心者メモ】データ分析前の欠損値NaNの確認の重要性と方法

Python / 機械学習初心者です。
データ分析をしようと意気込んだ結果、欠損値の確認を怠ったことでつかえてしまったので反省としてメモを残します。

## 結論
- データ分析に入る前に、欠損値の有無の確認を行うべきである
- 欠損値が見られる場合は、欠損値以外のデータを上書きするか、欠損値が含まれる行を除外して分析をするなど、何らかの対策をとるべきである


## 起こったこと
- Kaggleというデータ分析コンテストに参加した際、すべて目視で確認することができない量のデータを分析した
- その際、欠損値(NaN)の存在に気づかず、プログラムが大量のNaNだらけになってしまい、エラーが止まらなかった


## 欠損値とは
- Not a Number / NaN
- 計算の処理結果が表せない場合の特殊表現
    - 詳細を追おうとすると大変にディープな勉強が必要そうなので、本稿ではふれません
- 他の数との演算結果をNaNで返す性質があるため、プログラム内に1つでもNaNが含まれると、計算結果が正しく求められなくなる可能性がある
    - ```1 + NaN```の演算結果は```NaN```である
 
## 対策 - データ分析開始時のすすめ
- ①まず、何よりも最初に、データの欠損値の有無を確認する
- ```isnull().any()```を活用する
    - データフレームにおいて、欠損値が含まれる列を教えてくれる
    - 下記の用にdf_exampleに対して欠損値を確認すると、人口やGDPについては欠損値の存在を***True***で確認できる(北朝鮮の人口が正確にわからないのかな、などと想像も出来る)

```
#例:countries.csvに各国の基礎統計データが入っているとする
import pandas as pd
df_example = pd.read_csv("hogehoge/example.csv").copy()

print(df_example.isnull().any())
```

```
#例
Id            False
Name          False
Population    True
GDP           True
Region        False
life_expct    False
```


- ②欠損値の存在が確認された列において置換作業を行う
    - 列全体がNaNで構成される場合の別の削除方法や、欠損値の置換ではなく行自体の削除を行う場合の処理は割愛します。

```
# 欠損値存在列が判明したところで
df_example.loc[df_example['Population'].isnull(), 'Population'] = 0
```
### 注意
- この場合、置換する先の値が適切なものかどうか、後の計算で何を留意するべきか、注意されたい。
- 例えば、上記のように人口を0と置換した場合、2パターンありえるだろう:
    - 「このデータは人口の多い国TOP30とその特徴を算出するためにのみ分析するからこれで問題がない」
    - 「このデータからは平均人口を割り出す分析をするから、その際は『人口の値が0でない国』のみを計算対象にして、分母分子の値に不備の無いようにしよう」


## まとめ
- データを与えられたら、それにとびついていきなり分析をはじめるのではなく、欠損値の確認から行うことが大切。


## 参考
- [pandasで欠損値NaNが含まれているか判定、個数をカウント
](https://note.nkmk.me/python-pandas-nan-judge-count/)
- [pandasで欠損値NaNを除外（削除）・置換（穴埋め）・抽出
](https://note.nkmk.me/python-pandas-nan-dropna-fillna/)

(以上)

---

#### 補言
- 筆者はディープラーニングの入力層に欠損値がまぎれこんでしまったために、後の分析が全く有用でなくなるという経験をし、本稿を書くに至りました。
- 欠損値の確認以外にも、ヒストグラムを描いて外れ値を探すなど、分析前の確認工程・データクレンジングの工程は多々あるかと思います。本稿では2020/03/24時点では言及を控えましたが、それらについても調べたうえでいずれ追記したいと考えています。
systemdでserviceを起動するとパスは通っているのにcommand not foundが出る

# 起きている問題
### 前提
Amazon EC2のインスタンス上にあるUbuntu18.04において、Nginx + uWSGIでDjangoのサーバを立てようとしている。

**各種バージョン**
Nginx: 1.14.0
uWSGI: 2.0.18
Python: 3.7.5
Django: 2.2.11

まずuWSGIを起動するため、以下のようなuwsgi-hogehoge.serviceというファイルを作った。

```
[Unit]
Description=uWSGI service for mysite

[Service]
User=ubuntu
ExecStart=/bin/bash -c 'sh /hogehoge/start.sh'
ExecStartPre=/bin/bash -c 'sh /hogehoge/start_pre.sh'
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target
```
start.shにuwsgiを起動するための処理が含まれています。

### そして何が起きたか
uWSGIとNginxを起動するためのserviceファイルを作成し、systemdにシンボリックリンクを貼った。そして、

```
$ systemctl start uwsgi-hogehoge.service
```
でサービスを起動しようとすると、どうやらstatusを見る限りできていない。

```
$ journalctl -xe
```
でログを確認すると、以下のエラーが出ていた。

```
uwsgi: command not found
```

### 確認したこと
・普通にuwsgiのパスは通っている。
・パーミッションなどの権限周りに関係したエラーではない。
・そもそも権限周りのエラーだったとしてもファイルやユーザーにちゃんとしかるべき権限は与えてる。

以上のことから、どうやら、普通にするとuwsgiのパスは通っているが、systemdくんが起動時コマンドとして実行する時だけパスが通ってないのでは、という仮説の疑問を立てた。

# 解決策
やはりどんな事にも偉大なる先人様はいますね。
以下の神記事を見つけて全ては解決。

[systemdでユーザーの環境変数を読み込むようにする](https://bacchi.me/linux/systemd-tips/)

上の記事から引用すると、
>調べてみると、systemdは.barshrcや.bash_profileに
定義した環境変数を読んでくれないということがわかりました。

ということらしい....

### 解決のためにしたこと

```
$ echo $PATH
```
でパスを表示させる。
そしたら、

```
/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/ubuntu/.local/bin
```
みたいな感じで表示された。
そしたら、/etcにsysconfigディレクトリを作成し、適当な名前でファイルを作った。私の場合は、ubuntuという名前のユーザーだったのでファイル名もubuntuにした。
そして、ubuntuファイルを以下のように編集した。

```
# cat <_EOF_ > /etc/sysconfig/ubuntu
PATH=/home/ubuntu/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/ubuntu/.local/bin/usr/local/bin
_EOF_
```
次に、uwsgi-hogehoge.serviceファイルに、先ほど作ったファイルへのパスを設定する。

```
[Unit]
Description=uWSGI service for mysite

[Service]
User=ubuntu
EnvironmentFile=/etc/sysconfig/ubuntu ＜－－ここを追加！！
ExecStart=/bin/bash -c 'sh /hogehoge/start.sh'
ExecStartPre=/bin/bash -c 'sh /hogehoge/start_pre.sh'
Restart=always
KillSignal=SIGQUIT
Type=notify
StandardError=syslog
NotifyAccess=all

[Install]
WantedBy=multi-user.target
```

これで、systemdでサービスを起動する時にちゃんと環境変数も読み込めるようになった。

```
$ systemctl daemon-reload
```
でserviceファイルの更新をちゃんと読み込ませて、再び

```
$ systemctl start uwsgi-hogehoge
```
今度はちゃんと起動しました。
CombineによるPublisherの受け渡し

# はじめに
`RxSwift`を利用した`VIPER`アーキテクチャのソースコードを`combine`で書き直している。
`RxSwift`では、`Interactor`がAPIから非同期処理で取得したデータを`Presenter`に渡す際、`Single`オブジェクトとして扱っていた。`Single`だったところを`combine`では`Future`オブジェクトにしたのだが、両者は`Generics`の型の数が異なる。直接参考になるソースを見つけられなかったため我流のものだが書き残しておく。ただ、もっと良い方法があると思われるので、詳しい方にご教示いただきたいというのが正直なところである。

### ソースコード
`fetchFutureOnPresenter(flag: Bool)`に`true`を入れれば`String`が`Int`に変換された値が返ってくる。`false`にすれば`Presenter`を経由せずにエラーが投げられることをplaygroundで動作確認をした。

```swift

struct APIError: Error {
    var description: String
}

// InteractorがAPIにアクセスしてレスポンスを取得する想定
func fetchFutureOnInteractor(flag: Bool) -> AnyPublisher<String, Error> {
    
    return Future<String, Error>{ promise in
        
        ///
        /// 実際はここに非同期処理を書く想定
        ///

        // 非同期処理の結果によって、場合分け
        if flag {
            promise(.success("0"))
        } else {
            promise(.failure(APIError(description: "☓")))
        }
    }
    .eraseToAnyPublisher()
}

// PresenterがInteractorのメソッドから取得したデータをViewに渡す用に変換する想定
// flatMapでAnyPublisher<String, Error>からAnyPublisher<Int, Error>に変換
func fetchFutureOnPresenter(flag: Bool) -> AnyPublisher<Int, Error> {
    return fetchFutureOnInteractor(flag: flag)
        .flatMap { output -> AnyPublisher<Int, Error> in // クロージャの戻り値をIntにする
            Future<Int, Error>{ promise in
                promise(.success(Int(output)!))          // Intにキャスト、エラー（Failure）は、ここでは記載しない
            }
            .eraseToAnyPublisher()
    }
    .eraseToAnyPublisher()
}

// Presenterが購読（.sink）
let cancellable = fetchFutureOnPresenter(flag: /* true or false */)
.sink(receiveCompletion: { completion in
        switch completion {
        case .finished:
            break
        case .failure(let error):
            // Interactorの.failureはここに投げられる
            print("error \(error)")
        }
    }, receiveValue: { value in
        // このvalueを元にViewが参照する値を更新する想定
        print("value \(value)")
    })
Kotlin Multiplatformの各プラットフォームテストでcommonTestに依存しないようにする

Kotlin Multiplatformの開発をする際に、 [Spek](https://www.spekframework.org/) を使ってテストを書こうとすると、最初は良かったものの後で困ることがあります、というか困ることがありましたのでその備忘録です。

具体的には以下のような状況です

- Kotlin Multiplatformを使って、Android/iOS向けのライブラリを作る
- Source Setは `commonMain` `commonTest` `jvmMain` `jvmTest` `iosMain` `iosTest` の6つ
- `commonTest` でテストを書くためにSpekを入れる
- `jvmTest` もSpekでDSLが提供されているのでSpekを使う
- `iosTest` はSpekでDSLが提供されていないのでSpekが使えない
- さらに、 `iosTest` 内でSpekに依存しないテストを書いても、Gradle taskの `iosTest` が `compileTestKotlinIos` を呼んでその中で `commonTest` のテストをしようとするため、そこでSpekのライブラリが参照できずにtaskが失敗してしまう

やりたいこととしては `iosTest` 内に書かれたテストがテストできればそれでいいので、なんとかGradle taskの `iosTest` が実行された時に `commonTest` をスルーできないか模索していたのですが、とりあえずこんな感じでbuild.gradleを設定してやるとスルーできました

```
kotlin {
  sourceSets {
    commonMain {
      ...
    }
    commonTest {
      ...
    }
    iosMain {
      ...
    }
    iosTest {
      dependsOn.remove(sourceSets.commonTest) // <- これ
    }
  }
}
```

正直本当にこれで大丈夫なのか自信がないですが、今のところこれで `iosTest` 内のテストもできるようになりました。
100日後にエンジニアになるキミ - 4日目 - 環境構築 - プログラム言語の選択

# 初めてのプログラム言語

これからプログラミングを初めようって人にとって
言語選択は重要です。

プログラミングは様々なプログラム言語を用いて行いますが
普通のプログラマーであれば、生涯に複数の言語を習得することに
なるはずです。

まず最初はプログラム言語を習得する前に

**HTML**

を覚えるのがいいと思います。

[Mozilla HTML の学習: ガイドとチュートリアル](https://developer.mozilla.org/ja/docs/Learn/HTML)

後にHTMLについては講義を書きますが
まずはHTMLに触れてみてHTMLが書けるかどうか
挑戦してみると良いでしょう。

ここでHTMLのコードを書いてみてコーディングに触れてみましょう。

特に抵抗なく、HTMLを覚えられたら
プログラム言語の習得に進めると思います。

逆にHTMLのコーディングですら、上手く行かないのであれば
ここでエンジニアになることを諦めると良いでしょう。

プログラミングは果てしないコーディングの連続なので
コードを書くのが出来ない人には向きません。

## プログラム言語の選択

さて、コーディングに抵抗がなければ
プログラミングに進みましょう。

プログラム言語を選ぶコツは一つ

何をしたいか？　です。

目的別で言語を選択しましょう。

大まかな目的は以下の通りです。

| 用途や職種 |  | プログラム言語 |
|:--|:--|:--|
| WEB開発 | フロントエンド | Javascript |
|  | サーバーサイド | PHP,Python,Java,Ruby |
| ゲーム開発 | フロントエンド | C#,C++ |
|  | サーバーサイド | Python,Java,Ruby |
| アプリ開発 | iOS | Swift,C#,Dart |
|  | Android | Kotlin,Java,Dart |
| データサイエンティスト |  | Python,R |
| 組み込み系 |  | C言語など |
| インフラエンジニア |  | 特になし |
| セールスエンジニア |  | 特になし |

大規模開発になると用途別で複数の言語が用いられることが多いです。

WEB開発では
・フロントエンド(WEBサイトの画面の方を作る)
・サーバーサイド(WEBサイトの裏側の機能部分を作る)
で二手に分かれます。

使い勝手の良い、見栄えの良い洗練された画面を作りたい人は
Javascriptを覚える必要があります。

WEBサービスのユーザーを管理したり、計算機能の部分を作りたい人は
サーバー用の言語を選ぶことになります。

日本ではRubyが用いられるケースもあるようですが
海外では少ないようです。

PHPではlaravel（ララベル）というフレームワークを用いた開発が
流行ってきているようです。

ゲーム開発ではゲームエンジンを用いた開発が主流になってきています。
主なゲームエンジンは
・Unity(C#)
・UnrealEngine(C++)
となっているため、試してみて好きな方を選ぶと良いでしょう。

また、ゲーム開発ではアプリの他にサーバーサイドの開発も行われています。
こちらはWEB開発と同じような言語が用いられているので
ゲーム開発の裏側を支えたいという場合は、こちらを選択することになります。

アプリ開発ではスマホの機種によって言語が別れたりします。
・iOS(Swift)
・Android(Kotlin,Java)

機種により専用の言語が別れますが、両方の端末にに対応したツールの言語も出てきています。
・Unity(C#)
・Flutter(Dart)

ツールや、どの機種の開発をしたいかで言語を選ぶのが良いでしょう。

データサイエンティストになりたければ
Pythonをお勧めします。

Rという統計分析用の言語もありますが、Pythonで全て済んでしまうのと
システム開発をするのにRが向いていないので、結局Pythonしか使わなくなりました。

データ分析や、データ周りの環境整備、データサイエンス系の職種希望であれば
Pythonを選びましょう。
なお、ここのプログラミングの講義ではPythonで行うこととなります。

その他、組み込み系の開発では
C言語が用いられることが多いので、そちらを開発したければC言語を選択するしかないでしょう。

## 特に目的が決まってないなら

セールスエンジニアなどは特に言語の知識がなくても何とかなると思います。

特に目的や用途がはっきりせず、プログラミングを覚えたいのであれば
Pythonを選びましょう。

理由は
・用途が幅広い
・流行っている(人気がある)
・文法が覚えやすい
・コードが短くて済む
etc

自分は機械学習などの用途があるためPythonで仕事をしています。

元々はJavaを使っていましたが
現在ではJavaの開発を全く行っていません。

職種が変われば、用いられる言語も変わってきますので
まずは一つ、核になる言語を覚えるのが良いと思います。

1つの言語が覚えられたら、二つ目を覚えるのは非常に簡単です。

## そのほかの言語選びのポイント

言語選びのポイントとして言語の流行りスタリがあります。

かなり昔はCOBOLなど良くつかわれていました。
今では、そういった開発の話は全く回ってきません。

毎年、人気のプログラム言語の発表があります。

[人気プログラミング言語トップ10【2019版】](https://www.businessinsider.jp/post-202166)

流行りの言語を開発に用いることにはいくつかのメリットがあります。
・開発者の確保がしやすい
・文献が多い
・コミュニティーが出来る
・ライブラリやフレームワークの開発が多くなる
etc

開発者が多ければ多いほど、その言語の力が上がっていきます。
人気のない言語を使うと、余計な労力を払うことにもなり
効率が悪くなる可能性もあります。

あまり聞いたことのない言語を選ぶことは得策ではないとおもいます。

2019年の人気TOP3は
1.Javasctipt
2.Python
3.Java

このようになっています。

## まとめ

言語選びをするなら

・用途で考える
・人気の言語を選ぶ

君がエンジニアになるまであと96日
Kaggle Real or Not?

次の課題に submit するまでの流れです。
[Real or Not? NLP with Disaster Tweets](https://www.kaggle.com/c/nlp-getting-started)

次のページを参考にしました。
[NLP Getting Started Tutorial](https://www.kaggle.com/philculliton/nlp-getting-started-tutorial)

```py:realornot01.py
#! /usr/bin/python
#
#	realornot01.py
#
#					Feb/24/2020
# --------------------------------------------------------------------------
import sys
import numpy as np
import pandas as pd
from sklearn import feature_extraction, linear_model, model_selection, preprocessing
# --------------------------------------------------------------------------
def dump_frame_proc(df):
    try:
        print(len(df.index),len(df.columns))
    except Exception as ee:
        sys.stderr.write("*** error *** dump_frame_proc ***\n")
        sys.stderr.write(str(ee) + "\n")
# --------------------------------------------------------------------------
sys.stderr.write("*** 開始 ***\n")

train_df = pd.read_csv("train.csv")
test_df = pd.read_csv("test.csv")

dump_frame_proc(train_df)
dump_frame_proc(test_df)
#
count_vectorizer = feature_extraction.text.CountVectorizer()
example_train_vectors = count_vectorizer.fit_transform(train_df["text"][0:5])
print(example_train_vectors[0].todense().shape)
print(example_train_vectors[0].todense())
#
train_vectors = count_vectorizer.fit_transform(train_df["text"])
test_vectors = count_vectorizer.transform(test_df["text"])
#
clf = linear_model.RidgeClassifier()
#
scores = model_selection.cross_val_score(clf, train_vectors, train_df["target"], cv=3, scoring="f1")
print(scores)
#
clf.fit(train_vectors, train_df["target"])
#
sample_submission = pd.read_csv("sample_submission.csv")
sample_submission["target"] = clf.predict(test_vectors)
sample_submission.to_csv("submission.csv", index=False)
#
sys.stderr.write("*** 終了 ***\n")
# --------------------------------------------------------------------------
```

スコアは、 0.77096 でした。

![realornot_mar24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/22ee40bb-5c3a-1a80-c86e-fbd98a117905.png)
Firebase Hosting Basic認証設定

```functions/index.ts
import { https } from 'firebase-functions';
import basicAuth from 'express-basic-auth';
import express from 'express';
​
const app = express()
app.use('/', basicAuth({ users: { user: "password" }, challenge: true }));
app.use(express.static('public'));
exports.firebaseBasicAuth = https.onRequest(app);
```

```firebase.json
{
  "functions": {
    "predeploy": [
      "npm --prefix \"$RESOURCE_DIR\" run lint",
      "npm --prefix \"$RESOURCE_DIR\" run build"
    ],
    "source": "functions"
  },
  "hosting": {
    "public": "dummy",
    "rewrites": [
      {
        "source": "**",
        "function": "firebaseBasicAuth"
      }
    ],
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ]
  }
}
```
Python + Selenium(ChromeDriver)で「この接続ではプライバシーが保護されません」というエラーを無視する

主に開発環境などに対してSeleniumでChromeの動作を確認したい時に、テキトウに作った不正なSSLサーバー証明書を使用していると「この接続ではプライバシーが保護されません」というChromeのエラーが出て止まってしまうことがある。
これを無視する方法を記す。

## 解決方法

ChromeOptionsの「acceptInsecureCerts」を有効にする
これにより、不正なSSLサーバー証明書を利用していてもアクセスを許可するようになる。

参考：
https://www.selenium.dev/selenium/docs/api/java/org/openqa/selenium/chrome/ChromeOptions.html

## 前提条件

・Windows 10
・Python 3.7.4
　・pytest
・Selenium
・ChromeDriver (C:\selenium\chromedriver.exe)

## 実装例

``` python:test_webdriver.py
import pytest
import time
import json
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities

class TestWebdriver():
  def setup_method(self, method):
    capabilities = DesiredCapabilities.CHROME.copy()
    capabilities['acceptInsecureCerts'] = True
    self.driver = webdriver.Chrome(desired_capabilities=capabilities, executable_path=r'C:\selenium\chromedriver.exe')
    self.vars = {}
  
  def teardown_method(self, method):
    self.driver.quit()
  
  def test_webdriver(self):
    self.driver.get("https://127.0.0.1/")
```
VSCode Tips

備忘録です。
すでに知ってるものは割愛。
英字キーボードで説明。

Windowの[Alt]はMacで[option]で読み替える。

基本的にはVSCodeの[ヘルプ]+[対話型プレイグラウンド]に載っているもの。

# エディタ分割
* エクスプローラーから[Option]+ファイルクリック
* [command] + [\\](バックスペースキー)で現在カーソルがあるファイルをタブ複製
* キーボードで操作しているときに[control]+[Enter]でタブ分割
* [command] + [1],[2]・・(開いているエディタ)でアクティブなタブを切り替え
* [command] + [W] でタブを閉じる
* 同じファイルを同時に開くことも可。上下に離れたコードを見る場合等
* [control] + [tab]でタブの切り替え可

# ターミナル
## キーボードショートカット
* [control]キー　＋　[`]キーでターミナル表示/非表示


# カーソル操作
* [option]+[↑]、[↓]　選択行を入れ替え
* 対象を選択した状態で[shift]+[option]+[↑][↓]　その場に複製



# マルチカーソル
* [option]+[command]+[↑]、[↓] でカーソル追加
* 上の操作時に[shift]を加えて[shift]を押しながらカーソルを移動すると選択状態のままマルチでいける
* [option] + クリックでカーソル追加

[shift]+[cmd]+[L]　同じ単語が選択状態でマルチカーソル


# リネーム
[F2]キー

# インデント調整
[shift]+[option]+[F]

# 折りたたみ（Code Folding）
[option]+[command]+[\]]・・・開く
[option]+[command]+[\[]・・・閉じる
[command]+[K]→[0]

# スニペット
何文字か入力した際に表示されるインテリセンスの中で四角いアイコンがスニペット。そこをキーボードで選択して[tab]で展開される。
生産性を爆上げするツール10選（Mac編）

主に非エンジニアの人向けに、僕が業務で使っていて生産性向上に繋がると感じているツールをまとめてみました。

## BetterSnapTool
https://folivora.ai/
有料。
BetterTouchToolという任意の操作をショートカット登録できるアプリの中で画面サイズの調整機能だけを切り出したアプリ。
アプリをドラッグして画面の端に持っていくと、Windowsのように最大化や左半分へ拡大表示するなどが行えます。
アプリAを左半分に映しながら、アプリBを右半分に映して作業したいときなど、一瞬で画面を良い感じに調節してくれます。

## Clipy
https://clipy-app.com/
無料。
コピー履歴を遡ってペーストする機能とスニペット（事前登録した文章）をペーストする機能を備えたアプリ。
「コピーした内容上書いちゃったからもう一回コピーし直さなきゃ」みたいなことがなくなる上に、「なんか毎回この文章打つの馬鹿らしいな」みたいな場面を減らすことができます。

## Alfred
https://www.alfredapp.com/
基本無料。
定番のランチャーソフト。Finderからアプリやファイルを探す時間を短縮することができます。
alt + Spaceで起動。アプリならそのままアプリ名を打ち込む、ファイルならfindのあとにファイル名を打ち込むことで検索し、そのまま開くことができます。

## Fuwari
https://fuwari-app.com/
無料。
画面をキャプチャして付箋のように最手前で表示し続けたり、キャプチャをコピーすることができるアプリ。
アプリAの一部分を見ながらアプリBで作業をしたいときなどに都度画面を切り替えずに済むので作業が楽になります。

## HyperSwitch
https://bahoom.com/hyperswitch
無料。
画面の切り替えをアプリ単位ではなくウインドウ単位に変えてくれるアプリ。
macはデフォルトの切り替え単位がアプリなので、例えばExcelを3ブック開いているときに一瞬画面をChromeに切り替えてからExcelに戻りたい場合にどのブックに戻るのかを指定することが出来ませんが、このアプリを入れるとExcel内のどのブックかまで指定して画面を切り替えることができます。

## LastPass
https://www.lastpass.com/
基本無料。
パスワード管理アプリ。Desktop版とChrome/Safariの拡張機能版とiOS/Android版があります。
ChromeやSafariのパスワード管理機能だと別デバイスでパスワード入力する際に面倒ですが、このアプリはどのデバイスからでもパスワードを呼び出すことが出来るので管理が楽になります。

## Station
https://getstation.com/
無料。
アプリ内でGmailなどのアプリを複数開くことができるアプリ。
ChromeやSafariでタブをたくさん開いているけど、その中で頻繁にチェックするタブはStationに移すと画面表示までの平均クリック数が減って楽になります。 e.g. Gmail, Googleカレンダー

## onetab（chrome拡張機能）
https://chrome.google.com/webstore/detail/onetab/chphlpgkkbolifaimnlloiipkdnihall?hl=ja
無料。
1クリックで今開いているタブを1つのタブにまとめてくれる拡張機能。タブを一つにまとめると、chromeで使用するメモリを抑えることができます。もちろん元のタブはまとめられたタブから簡単に復元可能。
chromeでタブをたくさん開きがちで動作が重くなってしまう人におすすめ。

## Google翻訳（chrome拡張機能）
https://chrome.google.com/webstore/detail/google-translate/aapbdbdomjkkjkaonfhkkikfgjllcleb?hl=ja
無料。
言わずとしれた翻訳サービスのchrome拡張機能版。
「オプション」=>「翻訳のポップアップ:すぐにポップアップを表示する。」にしておくと、英語を範囲選択するだけですぐに翻訳結果を表示してくれます。
※長文は反応してくれないので、1文~2文で区切って範囲選択してあげてください。

## octotree（chrome拡張機能）
https://chrome.google.com/webstore/detail/octotree/bkhaagjahfmjljalopjnoealnfndnagc?hl=ja
無料。
これだけ主にエンジニア向けの機能ですが、ChromeでGithubを閲覧する際、左側にファイルツリーを表示してくれる拡張機能です。
コードを確認したいけど、わざわざローカルに落としたくないときに見たいファイルまでスムーズに到達することができます。
区切り文字の正規表現

`文字列 文字列 文字列 ・・・ 文字列`のような、よくあるタイプの正規表現を実装する機会が合ったのでメモ

### 条件
文字列は半角英数字
区切り文字は空白記号
最初と最後が区切り文字ではない

### コード

```
^(\w+\s)*\w+(?!\s)$
```

#### 通るパターン

`a` `aaa bbb` `a b c`

など

#### 通らないパターン

` a` `a ` `aaa  bbb` `あ`

など

### その他

区切り文字部分を変えればcsvとかもできるよ

```
^(\w+,)*\w+(?!,)$
```
OpenStreetMap入門

#OpenStreetMapとは何か
オープンストリートマップ（英語: OpenStreetMap、OSM）は2004年にイギリスでスティーブ・コーストによって作成され，自由に利用でき，なおかつ編集機能のある世界地図を作る共同作業プロジェクトです．GPS機能を持った携帯端末、空中写真やほかの機械からのデータをもとに作られていくのが基本となっていますが，ユーザー登録することによって編集ツール上で手入力での追加も可能です．また，公開されているデータを.osmという形式でダウンロードしOpenStreetMapとその協力者をクレジットすれば商用利用することも可能です．本記事ではそのosmファイルの中身について紹介します．


#URL
https://www.openstreetmap.org/

#OpenStreetMapから得られるデータ
![スクリーンショット 2020-03-24 16.15.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578719/46909b01-54f0-cae3-6e61-26d9a76f94e2.png)


上記の図のエクスポートボタンを押すことによって画面に表示されている範囲のosmファイルを取得することが出来ます．
また、表示されている範囲が広すぎると、サイズが大きくなりすぎてしまいファイルをダウンロードすることができません．

osmファイルの持っている重要な要素は下記の４つです．
- Node,Way,Relation,Tag



#Node
緯度と経度を指定することによって地点を表します．信号やベンチなどの物体の地点を表すのによく用いられます．
例

```
<node id="190137966" visible="true" version="11" changeset="60251867" timestamp="2018-06-28T14:59:36Z" user="Miyajimarumo" uid="6336964" lat="35.7208610" lon="139.4069943">
  <tag k="highway" v="traffic_signals"/>
  <tag k="name" v="砂川五差路"/>
</node>
```



#Way

ノードの集合であり、道や川を表す際に用います．また，wayで閉じた図形を描くことにより，建物などの，ポリゴンも表すことができます．
例

```
<way id="81791723" visible="true" version="4" changeset="26246450" timestamp="2014-10-22T01:06:11Z" user="txma25918" uid="955553">
  <nd ref="1339636471"/>
  <nd ref="952845077"/>
  <nd ref="3142965192"/>
  <nd ref="952845075"/>
  <tag k="highway" v="unclassified"/>
 </way>
```


#Relation
ノード、ウェイなどのメンバーを持ち、内側にあるのか、外側にあるのかなどの関係性をあらわします．Relationの意味はtagによって定義されます．(Route,Multipolygonなど)
例

```
<relation id="9734761" visible="true" version="2" changeset="73377379" timestamp="2019-08-15T11:22:37Z" user="8dirfriend" uid="3315483">
  <member type="way" ref="700632231" role="outer"/>
  <member type="way" ref="700632232" role="inner"/>
  <tag k="amenity" v="public_bath"/>
  <tag k="building" v="yes"/>
  <tag k="name" v="昭島温泉;湯楽の里"/>
  <tag k="type" v="multipolygon"/>
</relation>
```
![スクリーンショット 2020-03-24 17.37.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578719/924f26dc-066d-48b3-85db-d45b1e6a7af0.png)



#Tag
タグは「キー」と「値」という2つの項目から構成されています．タグは地図の要素（ノード、ウェイ、リレーション）や変更セットについて、特定の地物や特徴を記述します．どちらも自由な書式の文字列フィールドであるが、数値やその他の構造的な項目を表すこともあります．
例

```
<tag k="highway" v="unclassified"/>
```
#有用なサイト，ツール
- geofabrik.de
- http://www.geofabrik.de/
    - osmファイルを加工した，shpファイルやpbfファイルが無料で提供されています．
- pyosmium
    - osmファイル，pbfファイルから簡単に情報を取り出すことのできるpythonライブラリ

#最後に
OpenStreetMapは商用利用も可能であることから，MapBoxやCraigslistなどでも利用されている有用なサイトです．興味の湧いた方は是非使ってみてください．

以上となります．
最後までご覧いただきありがとうございました．


#参考文献
https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%BC%E3%83%97%E3%83%B3%E3%82%B9%E3%83%88%E3%83%AA%E3%83%BC%E3%83%88%E3%83%9E%E3%83%83%E3%83%97

https://wiki.openstreetmap.org/wiki/JA:Main_Page
GAMESSを使ってベンゼンの電子状態計算を行う方法

# はじめに

こんにちは，(株)日立製作所 研究開発グループ サービスコンピューティング研究部の露木です。

[前回の記事](https://qiita.com/MasafumiTsuyuki/private/d3a9c808b4c9a49ad502) ではGAMESSをコンパイルして実行可能なDockerイメージを作りました。今回の記事ではこれを利用してベンゼンの電子状態計算を行い，動作確認の代わりとします。

# 前提とする環境

前回の記事を一通り実行してDockerイメージのビルドが完了していることと，以下の通りカレントディレクトリに必要なファイルが揃っている状態から再開するものとします。もしも，環境準備ができていない場合は前回の内容を実行してDockerイメージをビルドしてください。

```bash 
$ ls 
Dockerfile  Dockerfile.base  Makefile  README.md  docker-compose.yml  workspace
```

# 操作方法

まず以下のコマンドでdockerコンテナを起動し，コンテナ内でシェルにログインしてください。

```bash 
$ make run
```

サンプルの入力ファイル `c6h6.inp` は初期ディレクトリに準備してあります。

```bash
# サンプルの入力ファイルの存在確認
$ ls
c6h6.inp  rungms
```

## 入力ファイルの内容

`c6h6.inp` の中身は以下のとおりです。この入力ファイルはベンゼンに関する HF/6-31G(d) レベルの1点計算を実行せよと指定しています。入力ファイルの詳しい意味に関しては本記事では説明しません。[参考文献1](https://www.kspub.co.jp/book/detail/1543881.html)か[GAMESSのマニュアル](https://www.msg.chem.iastate.edu/gamess/documentation.html)を参照してください。

```fortran
 $CONTRL RUNTYP=ENERGY NPRINT=-5 $END
 $SYSTEM MWORDS=40 $END
 $SCF DIRSCF=.TRUE. DIIS=.TRUE. $END
 $BASIS GBASIS=N31 NGAUSS=6 NDFUNC=1 $END
 $DATA
 C6H6
C1
C           6.0     -0.030544037        00.000000000        -1.409121795
C           6.0     -1.186612730        00.000000000        -0.710957795
C           6.0      1.125524656        00.000000000        -0.710957795
H           1.0     -2.086037837        00.000000000        -1.254130795
H           1.0      2.024949762        00.000000000        -1.254130795
C           6.0     -1.186612730        00.000000000         0.685372205
C           6.0      1.125524656        00.000000000         0.685372205
H           1.0     -2.086037837        00.000000000         1.228545205
H           1.0      2.024949762        00.000000000         1.228545205
C           6.0     -0.030544037        00.000000000         1.383536205
H           1.0     -0.030544037        00.000000000         2.469883205
H           1.0     -0.030544037        00.000000000        -2.495468795
 $END
```

この入力ファイルに記載されている分子構造を可視化すると，以下のようなベンゼンをカーテシアン座標系で表現していることになります。

![b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541219/8b1c39b9-df51-0dac-a710-8d189f166c18.png)


## 計算の実行

`rungms`スクリプトを実行し，GAMESSによる一点計算を行います。このrungmsスクリプトはGAMESSのソースコードに同梱されているものですが，使いやすいように一部を変更しています。`rungms`の1つ目のオプションは入力ファイル (今回の場合は`c6h6.inp`) の拡張子を除いたもの，2つ目のオプションは計算の並列度 (プロセス数) です。計算結果は`c6h6.out`というファイルに保存されます。

```
$ ./rungms  c6h6 8 > c6h6.out
```

## 計算結果の確認

計算結果には多数の情報が含まれていますが例えば，`FINAL RHF ENERGY` で検索すれば 8回の繰り返し計算の結果として，ベンゼンの全エネルギーは `-230.7019921390 Hartree` に収束したことがわかります。

```
$ grep 'FINAL RHF ENERGY' c6h6.out

FINAL RHF ENERGY IS     -230.7019921390 AFTER   8 ITERATIONS
```

ここではその他の計算結果の意味は説明しませんが， 出力に `exited gracefully` の文字列が含まれていれば，正しく計算が終了したことを意味します。参考文献1には出力ファイルの読み方も記載されておりますので，そちらを参照ください。

```
$ grep gracefully c6h6.out
 ddikick.x: exited gracefully.
```

# おわりに

お疲れさまでした。あとはGAMESSに同梱のドキュメントやWeb上の記事を参考にしていただければ，目的とする分子と物性の計算を行うことができます。

# 参考文献

1. [平尾公彦・監修 武次徹也・編著, 新版 すぐできる 量子化学計算ビギナーズマニュアル，講談社，2015](https://www.kspub.co.jp/book/detail/1543881.html).
2. [Gordon Group/GAMESS Homepage](https://www.msg.chem.iastate.edu/gamess/documentation.html)
【SEO】【canonical】重複ページ

##canonicalとは
正式なURLを検索エンジンに伝えるURLの正規化を目的としたものです。
重複ページが存在している場合は検索エンジンに優先させるべきページを伝えることができます。

##重複ページとは
今回のテーマですが、重複ページの具体例を挙げると、ECサイトなどで色違いの商品がそれぞれ別urlで存在する場合や、リストの並び替えでurlが異なる場合もページの内容自体は同様で順序のみが異なるためこれに該当します。
今回は並び替えの例を紹介します。


##例
`https://evsmart.net/spot/kanagawa/l141305/q141313/`
上のページでは並び替えができ、並び替え後のurlでは
`https://evsmart.net/spot/kanagawa/l141305/q141313/?p=1&l=20&o=2`
このようなパラメータがつきますが、順序が変わっているだけでページの内容としては前者と重複しているため、どちらのページもデフォルト表示の
`https://evsmart.net/spot/kanagawa/l141305/q141313/`
のurlをcanonicalに書きます。

```canonical.html
<link rel="canonical" href="https://evsmart.net/spot/kanagawa/l141305/q141313/" />
```

従って実際のurlとcanonicalが異なるため、単純に例えば`$_SERVER['REQUEST_URI']`を使って一律に書くということはできません。

あとcanonicalは絶対パスで書く必要があります。
RailsでRSpecを追加しようとした時に発生したエラー「Could not find diff-lcs-1.3 in any of the sources Run `bundle install` to install missing gems.」の対処法

```ruby:Gemfile
group :development, :test do
  gem 'rspec-rails'
end
```
GemfileにRSpecを追加して、以下のコマンドを実行したらエラーが発生した。

## エラーメッセージ

```sh
$ bundle install
・・・
$ rails generate rspec:install
Could not find diff-lcs-1.3 in any of the sources
Run `bundle install` to install missing gems.
```

## 解決方法

```sh
$ ps axu | grep spring
maiamea              53324   0.1  0.1  4336604   9524   ??  Ss    4:41PM   0:00.92 spring app    | api-project | started 5 mins ago | development mode      
maiamea              36768   0.0  0.0  4366272    748 s002  S+   月04PM   0:00.58 spring server | api-project | started 24 hours ago   
maiamea              53389   0.0  0.0  4286728    716 s003  S+    4:46PM   0:00.00 grep spring
$ spring stop
Spring stopped.
$ rails generate rspec:install
Running via Spring preloader in process 53437
      create  .rspec
      create  spec
      create  spec/spec_helper.rb
      create  spec/rails_helper.rb
```

## 原因
rails server を高速で起動させるSpringが悪さをしていた。
Springが起動していたことによりGemfileの変更が反映されなかった。

Gemfileに変更を加えた場合は、まず rails server を止め、
次にSpringをstopさせる。
その後 rails server を起動させる必要があった。

## Springとは？
Railsアプリケーションのプリローダーのgem (Rubyのライブラリ)
Railsアプリケーションをバックグラウンドで走らせたままにしておくことにより、2回目以降のコマンド実行時の待ち時間が減り開発効率が上がる。

プリローダー：preloader (pre + load = 前もってロードしておく)

## 参考
* [railsのコマンドが動かない時はspringを(stop|kill)してみよう](https://qiita.com/yokozawa/items/7b92c260f8c3dfec8e28)
* [Railsの開発効率をあげる - Springを使ってRailsのコンソールコマンドの実行を早くする](https://ruby-rails.hatenadiary.com/entry/20141026/1414289421)
* [RailsでSpringを導入して開発効率を上げる](https://easyramble.com/install-spring-into-rails.html)
selectをカスタマイズするやーつ

<p class="codepen" data-height="650" data-theme-id="dark" data-default-tab="css,result" data-user="pe-ta" data-slug-hash="XWbxjyP" style="height: 650px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="custom select">
  <span>See the Pen <a href="https://codepen.io/pe-ta/pen/XWbxjyP">
  custom select</a> by Tadatsugu Sampei (<a href="https://codepen.io/pe-ta">@pe-ta</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Max for LiveからP5.js を使う。

p5.jsとMax for Liveをつないでみようということで、
いろいろやり方はあると思いますが、[jWeb]オブジェクトを使って繋ぐのが
一番いい感じだったので紹介します。

#テンプレート
Githubリポジトリにサンプルコードです。

こちら!
[download](https://github.com/Amagingman/P5M4L/)


# 使い方
Githubからフォルダごと入手すると、
以下のようなファイルがあると思います。

- README.md　　　　　　　
- index.html           
- sketch.js
- template.maxpath


基本的にいじっていくのは、『sketch.js』と『template.maxpat』です。

# Max側(M4L)
template.maxpathをダブルクリックして開いてみてください。
※Maxをお持ちでない方は、先にインストールする必要があります。
（無料版でも開くことできます！保存ができないだけす！）

以下のようなパッチになっています。

![picture_pc_2db2ec473576ce880b2676145cb1152b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152481/874d78af-4317-d6ce-1783-0871753591a9.png)



黒い大きな領域にオンマウスすると、領域が動くと思います。
こちらの領域にP5.jsで作った描画結果が表示されています。



右側にある赤・緑・青色のスライダーは、[pak]オブジェクトを伝って、値をp5.jsに渡しています。

黒い領域の下側に[route output]オブジェクトがあり、何やら数字が動いていると思います。

p5.js側でoutputと言う名前で指定した変数の値が返ってきています。
こちらのサンプルでは、p5.jsの組み込み変数であるframeCountが返ってきています。



#P5.js側
次にsketch.jsを開いてみてください

```javascript

var s = function(p) {
       var v1 = 0;
       var v2 = 0;
       var v3 = 0;
//--------------- Setup ---------------------
   p.setup = function() {
       p.createCanvas(innerWidth, innerHeight);
       window.max.bindInlet('set_value', function(_v1, _v2, _v3) {
           v1 = _v1;
           v2 = _v2;
           v3 = _v3;
   });
 };
//--------------- Draw ---------------------
   p.draw = function() {
       p.background(0);
       let mx = p.mouseX;
       let my = p.height / 2;
       p.rect(0, 0, mx, my);
       window.max.outlet('output', p.frameCount);
       p.fill(255);
       p.text(v1, 10, p.height - 20);
       p.text(v2, 10, p.height - 40);
       p.text(v3, 10, p.height - 60);
   };
   p.mousePressed = function(){
    
   }
//--------------- ReSize---------------------
 p.windowResized = function() {
       p.resizeCanvas(innerWidth, innerHeight);
 }
 
};
const myp5 = new p5(s);
````

こちらは、p5.jsのインスタンスモードと呼ばれる書き方で記述してあります。

[インスタンスモードの解説](https://youtu.be/Su792jEauZg)は、The Cording Trainシリーズの中で、Daniel shiffman先生が行ってくれていますので楽しく勉強できると思います！

Setup関数内で以下のような記述があることが確認できると思います。


```javascript

window.max.bindInlet('set_value', function(_v1, _v2, _v3) {

           v1 = _v1;
           v2 = _v2;
           v3 = _v3;
   });
````

こちらでMax側からの値を受け取っています。
「window.max.bindInlet()」関数で
先ほど確認した赤・緑・青色のスライダーから[pak]オブジェクトから入力されている
3つの値を受け取って、変数に代入しています。

次に出力ですが、「window.max.outlet()」関数でMax側に出力することができます。

```javascript
window.max.outlet('output', p.frameCount);
````

以上が簡単なP5.jsをMaxの中で利用する方法になります。


# M4Lデバイスでp5.jsを使う
M4Lデバイスの中で活用したい場合は、
Ableton Liveを立ち上げ、M4Lの新規デバイスを任意のトラックにドラッグアンドドロップします。

![picture_pc_3fb83a92b01991685f4113349e82565d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152481/5e103598-9dd3-017c-1303-32441d17fd64.png)


そのデバイスを任意のフォルダに保存して、
先ほどのテンプレート一式を同じファルダ内にコピーして、
「template.maxpat」をコピーアンドペーストすることで、同じように始めることができます。



#まとめ
今回は、Mac for LiveからP5.jsを呼び出すという飛び道具的なノウハウの共有になりました。クリエイティブコーディングのスキルを横展開したり、逆にP5.jsやProcessingで遊んでいるみなさんがMaxに興味を持ってくれたらいいな、なんて思いながら記事を書いてみました。それではまた！

[Taito Otani](https://twitter.com/taito_otani)