OmniAICreator/Qiita-1.07M huggingface dataset:
VRChatでワールドを作った

この記事は、OculusやVIVE等のVRデバイスを持っている人を対象としています。
（6Dof以上、VRコントローラーがあるのが望ましい)
また、個人の主観による実験結果のため、学術的な価値はありません。

#はじめに

[前の記事](https://qiita.com/pipe_render/items/49a15c51e945849745b5)では、新しい習慣が構築される手順を説明しました。
次にVRChatを使って、この仮説を検証するためのワールドを作成することにしました。

#結論

VR感覚をトレーニングするためのワールド

[Seek Invisible Key](https://vrchat.com/home/world/wrld_fc0c34b9-0058-4678-83de-25693a82c49f)
![965747F4-352B-45F3-82D6-3321B837BD28.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/461091/cbc264ce-4d3c-8cdf-8ee8-b9db08517a82.jpeg)

ワールドは、鍵を探してドアを開けていくという単純なルールです。
しかし鍵の一部が不可視になっているため、手探りで鍵の形状を確かめないと本物の鍵かどうかが分からない仕組みになっています。

#解説

何故このようなワールドを作ったかというと、女性アバターで見ず知らずの人に触られるのを怖いと感じたからです。

あとは「昔からMYSTや脱出ゲーなどの、謎解きゲームが好きだったから」というのも大きな理由です。
 
#これから

このワールドによって、最初に書いた目的を達成できたかどうかは正直怪しいところです。
VR感覚はまだ謎が多く、個人差も大きいのでトライ＆エラーで調整していくことが重要だと思っています。

皆さんにも是非、このワールドを体験していただいて、感想やアドバイスを頂けるとありがたいです。
習慣の力

この記事は、OculusやVIVE等のVRデバイスを持っている人を対象としています。
（6Dof以上、VRコントローラーがあるのが望ましい)
また、個人の主観による実験結果のため、学術的な価値はありません。

#はじめに

今回は習慣の力という本の説明と、それに自分なりにの解釈を加えた内容になっています。

>習慣の力〔新版〕 ((ハヤカワ・ノンフィクション文庫))   チャールズ デュヒッグ 
https://www.amazon.co.jp/dp/415050542X/ref=cm_sw_r_tw_dp_U_x_h0EFDb0A9WTDT‬

習慣の力では以下のような、“きっかけ”からスタートする“ルーチン“の繰り返しが、習慣に変わっていくと説明されています。
(詳しくは本を読んでください)

> 1. きっかけ
2. ルーチン
3. 報酬
4. 以下繰り返し


#結論

私は、習慣のループを続けると以下のような状態になると考えています。

1. 欲求が満たされいない状態
2. きっかけ
3. ルーチンを実行したいという欲求
4. ルーチンの実行
5. 報酬
6. 以下繰り返し

このループは身体感覚を伴っていて、VR上でも十分機能します。

#説明

私は参考文献にあった習慣のループに“欲求”という概念を追加しました。
理由は、この「欲求」がVRにとって重要なのではないかと感じたからです。

分かりやすく、動物の例を挙げます。

>先日、上野公園で鴨を見つけました。
足を止めて鴨を見つめると、鴨が私に向かって歩いてきました。
ある程度近づきましたが、私が何もしないでいると鴨は離れていきました。

この鴨の行動を前述の手順に当てはめてみます。

>1. きっかけ(人間に見つめられる)
2. ルーチン(人間に近づく)
3. 報酬(餌をもらえる)

鴨はこのようなループを何度か繰り返していたはずです。
しかし、実際にはもっと複雑な手順(人間がバッグを開ける、しゃがむ等)があるためか、鴨はそれ以上接近してきませんでした。

では何故、鴨はルーチンを繰り返すのでしょうか？
そこには欲求があるからです。

1. 欲求が満たされいない状態(空腹、低血糖など)
2. きっかけ(人間に見つめられる)
3. ルーチンを実行したいという欲求(「人間に近づくことで餌をもらえる」というイメージが喚起される)
4. ルーチン(人間に近づく)
5. 報酬(餌をもらえる)
6. 以下繰り返し

詳しく見てみましょう。

>1.欲求が満たされない状態

最初に欲求が満たされない状態があります。
もし満腹の場合や、食欲より緊急度が高い欲求(「喉が渇いている」、「襲われる危険性がある」等)があった場合は、手順2以降に行かないこともあります。

>3.ルーチンを実行したいという欲求

次にルーチンを行う直前、鴨は餌の事をイメージします。
習慣ができる前は「人間に見つめられる」と「餌が手に入る」は何の関係もないので、その想像は発生しませんでした。
しかし、ループが発生すると途端にそれらが結びつき、さらに何度も繰り返すことでどんどん強くなります。

>6.以下繰り返し

さらにループを繰り返すと「人間に見つめられる」だけで「餌を食べたい」という欲求が生まれるようになります。
それは[最初のブログ](https://qiita.com/pipe_render/items/2393b39443401902a544)にも書いた「ヨダレが出る」等の情動反応を伴うものです。

#これから

VRに話を戻しましょう。

習慣がVRにとって重要なのは、以下の3つです。
・”きっかけ“は割と何でもいい(他に優先度が高い欲求がなければ)
・「見つめられる」という視覚情報だけでも発生条件になりえる
・情動、つまり身体的な反応を伴う感情が発生する

これらを条件を満たすVRコンテンツを作る事で、現実には存在しない新しい習慣を作ることも可能です。

[2.1. VRChatでワールドを作った](https://qiita.com/pipe_render/items/52b524e58fce9b9e72a0)
[2.2. チャンキングについて]
(https://qiita.com/pipe_render/items/7f53f2cbe2fe677811ec)
nodebrewでバージョンを上げた際にグローバルインストールしてたコマンドが無くなる問題への対応

#結論

nodeのバージョンを上げた後で下記コマンドを実行。

バージョンを上げる前にグローバルインストールしていたコマンド達を、バージョンアップ後のnodeに一括でグローバルインストールしてくれる。

```
nodebrew migrate-package 11.9.0（適宜置き換え）
```
11.9.0は今まで使っていたバージョンです。
私の場合は11.9.0から11.10.1にバージョンを上げたので、11.9.0を指定しました。

（助けて貰った記事一覧）

* [MacのローカルにnodebrewでNode＆npmをインストール - パッケージの移行](https://qiita.com/kijitoraneko/items/d456c056fa4a49641c1d)
* [node.jsのバージョン管理 - Nodebrewのインストールと基本操作](https://qiita.com/naru0504/items/b35b73258059449ec72a)

#What's happend?

以下、この記事を書こうと思った事象についての日記となります...

（2019/9/15）

本日１週間ぶりに`create-react-app`すると、失敗するようになってました。

依存でインストールされる`eslint`が要求するnodeのバージョンと私が使用していたnodeのバージョン（11.9.0）が合わなくなった事が原因でした。

なので`nodebrew`でnodeのバージョンを上げました。

改めて`create-react-app`すると...

```
$ create-react-app myapp
-bash: create-react-app: command not found
```

コマンドが無くなってしまいました...

コマンドの置き場所を確認してみると、
今まで入れてたものが無くなってしまっている...

```
(before)

$ ls /Users/gossan/.nodebrew/current/bin/
create-react-app	npm			surge
firebase		npx			wscat
gatsby			serverless		yarn
node			sls			yarnpkg
nodebrew		slss

(after)

$ ls /Users/gossan/.nodebrew/current/bin/
node		nodebrew	npm		npx
```

グローバルインストールしたコマンドは、インストール時のnodeのバージョンに紐づけられるんですね。この時点でやっと気づきました。

一括で引き継ぐためのコマンドが無い筈が無いと思い調べると、
`nodebrew migrate-package xx.xx.xx（旧バージョン）`で解決するらしい事を発見。

元々11.9.0を使っていたので下記のよう試しました。

```
$ nodebrew migrate-package 11.9.0

〜(略)〜

Try to install yarn ...
/Users/gossan/.nodebrew/node/v11.10.1/bin/yarnpkg -> /Users/gossan/.nodebrew/node/v11.10.1/lib/node_modules/yarn/bin/yarn.js
/Users/gossan/.nodebrew/node/v11.10.1/bin/yarn -> /Users/gossan/.nodebrew/node/v11.10.1/lib/node_modules/yarn/bin/yarn.js
+ yarn@1.17.3
added 1 package in 0.052s

〜(略)〜

Try to install create-react-app ...
/Users/gossan/.nodebrew/node/v11.10.1/bin/create-react-app -> /Users/gossan/.nodebrew/node/v11.10.1/lib/node_modules/create-react-app/index.js
+ create-react-app@3.1.1
added 1 package in 0.248s

Installed successfully:
serverless
surge
yarn
gatsby-cli
firebase-tools
wscat
create-react-app
```

11.9.0でグローバルインストールしていたものをグローバルインストールし直してくれているようですね。

改めてグローバルインストールされたコマンドを確認すると、、、

```
$ ls /Users/gossan/.nodebrew/current/bin/
create-react-app	npm			surge
firebase		npx			wscat
gatsby			serverless		yarn
node			sls			yarnpkg
nodebrew		slss
```

全部ありました！

元々使いたかった`create-react-app`も復活しました！
ns-3.30の使い方

ネットワークシミュレータであるns3の使い方について，いくつかの記事に分けて投稿していこうと思います．

想定するOSは【Ubuntu 18.04】で，扱うns3のバージョンは2019年現在最新の【ns-3.30】です．記事の内容は，公式のチュートリアルとサンプルコードを参考に，ns3のインストールから，ns3のコンポネントの説明，シミュレーションシナリオの書き方，モジュールの使い方，モジュールの自作まで一通り扱う予定です．読み手は，研究でns3を使いたいけど，文章はたくさん読みたくない人を想定していて，分量はできるだけ圧縮するつもりです．ただし，ns3はC++によって動いているため，C++の基本的な知識は必要で，もちろんネットワークシミュレータなので，ネットワークの基本的な知識も必要です．

投稿でき次第，逐次追加していきます．頑張ります．

### いろは編

1. [ns3のインストール](https://qiita.com/dorapon2000/items/5c0c0a399aeee629be63)
2. [ネットワーク構築（前編）](https://qiita.com/dorapon2000/items/4b51c1776f65b3fc7d26)
3. [ドキュメントの極意・いち](https://qiita.com/dorapon2000/items/87c1037f7da7c1676837)
4. [ネットワーク構築（後編）](https://qiita.com/dorapon2000/items/4b95e5658d537c2b5e72)
5. [ロギング](https://qiita.com/dorapon2000/items/fe8151f7ee6bcc30c72e)
6. [トレーシングシステム](https://qiita.com/dorapon2000/items/494164b004e2f42a4553)
7. [フローモニタ](https://qiita.com/dorapon2000/items/fadabf05a9c947bee87c)

### モジュール編
wifiとtestモジュールとデバッグについて書くつもりです．（2020/01/27）
[備忘] Container RegistryにDocker Imageをpushする

完全に備忘

# はじめに
プライベートにDocker Imageを管理したい場合は、Container Registryを使うことにした
費用はCloud Storageと下りの費用くらいなのでほぼ無視できる。はず。。。

[Container Registryの公式ページ](https://cloud.google.com/container-registry/?hl=ja)

# 1. Dockerhubから自分が欲しいDocker Imageを取ってくる
dockerhubから自分が欲しいDocker Imageをpullしてくる

今回はnodejsの公式イメージをpullしてくる

```
docker pull node
```
特にタグを指定してないので`latest`がpullされる



# 2. gcloudでcloud container registryへの認証を通す
GoogleCloudPlatformの場合には、cloudshellで実施するのが楽で良い

Container RegistryのAPIを有効にしておくのを忘れずに

で、認証のコマンドはこれ

```
gcloud auth configure-docker
```


# 3. Imageにタグをつける

ローカルにpullしてきたイメージを特定の場所にpushするにはタグ付けが必要なので、タグ付けする

```
docker tag node:latest gcr.io/{Project_name}/node:tag-first
```

一応タグ付けされたかを確認しておく

```
docker images
```

```:output
REPOSITORY                        TAG                 IMAGE ID            CREATED             SIZE
node                              latest              d8c33ae35f44        3 days ago          907MB
gcr.io/{Project_name}/node       tag-first           d8c33ae35f44        3 days ago          907MB
```


# 4. Imageをpushする
最後にタグ付けされたImageをContainer Registryをpushする

```
docker push gcr.io/{Project_name}/node:tag-first
```

コンソールでContainer Registryに登録されているか確認する

![スクリーンショット 2019-09-15 17.29.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/55225/b7d43289-7ea8-7b12-b56d-21cfb0653592.png)

確かに登録されていることを確認


# 5. いらないImageは削除する
少額とはいえ課金対象ではあるので、使わないImageは消しておきたい

```
gcloud container images delete gcr.io/{Project_name}/node:tag-first --force-delete-tags
```



# 参考リンク
[Googleの提供するDocker Registry の Google Container Registryを試す](https://qiita.com/eielh/items/11c8f212612169ac5ee4)
[Google Container Registry概要](https://qiita.com/t-yotsu/items/c99775f942f9bb23bd6c)
[Container Registry クイックスタート](https://cloud.google.com/container-registry/docs/quickstart)


おしまい
[Go] ポリモーフィズムをつかって綺麗な実装を目指そう

## 概要
インターフェースを使ったポリモーフィズムについてまとめる

必要な前提知識は以下の二つ（もし分からなければ[こちら](https://qiita.com/youk-h/items/b74d0304d01a90f90947)の記事の上の方を参照ください）
・インターフェースの定義の仕方
・インターフェースを実装する方法

メリットは
ロジック内にはインターフェースしか現れないこと

##インターフェース　とは
インターフェースは言葉通り、境界面のイメージ
つまり、外から見た時に表面に何があるかを表している

Golangではインターフェースはメソッドの一覧で定義されているので
外からはこのメソッド一覧が見えて、そのメソッド一覧を使う事ができる


##ポリモーフィズム　とは
ある一つのインターフェースを実装した複数のオブジェクトに対して、そのインターフェースで公開されたメソッドで共通の処理をできること
開発者はインターフェースに命令することを意識すれば良い
どの構造体がこのインターフェースを実装したかは考えなくて良い

下のコードでは、猫か犬のどちらが来たかを判断して名前を判定している

変数の型指定やメソッドを呼ぶ時には、インターフェースのIAnimalしか意識していない事が分かる
具体的なDogとCatを意識するのは、それらを生成するときだけである

```go
package main

import (
	"fmt"
)

type IAnimal interface {
	GetName() string
}

type Dog struct {
	name string
}

func (d Dog) GetName() string {
	return d.name
}

type Cat struct {
	name string
}

func (c Cat) GetName() string {
	return c.name
}

func main() {
	var animals []IAnimal = []IAnimal{
		Dog{"ポチ"},
		Cat{"ミケ"},
		Cat{"タマ"},
	}

	for _, animal := range animals {
		fmt.Println(animal.GetName())
	}
}
```

##まとめ
インターフェースを実装する事で、ロジック内にインターフェースしか現れない事が分かった

**補足１**
今回はインターフェースを実装した場合でポリモーフィズムを考えたが、継承に関してもポリモーフィズムは適用できる
仮に構造体PoodleをDogから継承させた場合もPoodle型はインターフェースであるIAnimalとして扱う事ができる

**補足２**
今回は作らなかったがICat、IDog、IPoodleなどのインターフェースを作る事で
ICatを実装もしくは継承したオブジェクトだけが使える機能をICatで公開することもできる
インターフェースが役割を決め、それを実装や継承したものはその役割を持つという事が考えられる
promptはrenderで消える

## 編集画面を作る際にpromptが消失した
### MVCの流れで呼び出される時
<p><a href="https://gyazo.com/8f52e819e725e2ca2ef993ac98a4c309"><img src="https://i.gyazo.com/8f52e819e725e2ca2ef993ac98a4c309.png" alt="Image from Gyazo" width="660" /></a></p>
### renderで呼び出す時
<p><a href="https://gyazo.com/a1e7d667fb13a477290c357b257e12f7"><img src="https://i.gyazo.com/a1e7d667fb13a477290c357b257e12f7.png" alt="Image from Gyazo" width="686" /></a></p>
## 実際のコード

```haml
.main__product__delivery__h2-choice
  = f.collection_select :delivery_method_id, @deliveryMethods, :id, :name, prompt: "---"
  = fa_icon "chevron-down", class: "main__product__delivery__sell-box__icon"
```
### どうやら仕様らしい…？
> Select prompt option disappears when validation fails in Rails
> https://stackoverflow.com/questions/4060737/select-prompt-option-disappears-when-validation-fails-in-rails
> You can achieve the results you want by setting :include_blank to the string you were using for prompt.

とのことなのでpromptからinclude_blankに書き換え

```haml
.main__product__delivery__h2-choice
  = f.collection_select :delivery_method_id, @deliveryMethods, :id, :name, include_blank: "---", 
  = fa_icon "chevron-down", class: "main__product__delivery__sell-box__icon"
```
<a href="https://gyazo.com/c5deaf9844ebcb15f30e2dd49f7736cc"><img src="https://i.gyazo.com/c5deaf9844ebcb15f30e2dd49f7736cc.png" alt="Image from Gyazo" width="637"/></a>
"---"自体は存在していることが確認できたのであとは"---"が初期値として選択されていればOK！

## 最終的なコード
> RubyonRails:collection_selectにデフォルト値を設定する
> https://madogiwa0124.hatenablog.com/entry/2018/05/12/210801

こちらのサイトを参考にして

```haml
.main__product__delivery__h2-choice
  = f.collection_select :delivery_method_id, @deliveryMethods, :id, :name, { include_blank: "---", selected:"" }
  = fa_icon "chevron-down", class: "main__product__delivery__sell-box__icon"
```
<p><a href="https://gyazo.com/8f52e819e725e2ca2ef993ac98a4c309"><img src="https://i.gyazo.com/8f52e819e725e2ca2ef993ac98a4c309.png" alt="Image from Gyazo" width="660" /></a></p>  

## 結論
prompt: "---"を{ include_blank: "---", selected:"" }に書き換える！
『5秒』でTypeScript + React アプリを作り『5分』で全世界に公開する

e-Sports専用のクラウドファウンディング・サービス「[e-Sports-Funding(仮)](https://e-sports-funding.firebaseapp.com/)」を個人開発したいので、開発環境を整えていきます。技術的には以下を使用する予定で、各技術の導入に際し備忘録もかねて記事にしていきます。

- **TypeScript** : 言語 
- **React** : UI フレームワーク
- Redux : 状態管理 
- Firebase : バックエンド
- **Firebase Hosting** : インフラ
- Stripe : 決済プラットフォーム

なお、**太字**部分は本記事で導入します。

# TypeScript + React アプリを作成する

- create-react-appを使ってアプリのひな型を作成

  ```bash
  yarn create react-app e-funding --typescript # サンプルプロジェクトを作成します
  ```
ここまでで**『5秒』**
# Firebase hosting でデプロイする

- firebase プロジェクトの作成
![firebase.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131737/83b85df5-9c67-508a-85ec-0d20b3e95069.gif)

- firebase の初期設定

  ```bash
  yarn add firebase-tools # firebase まわりをアプリに追加します
  firebase login # firebase が連携するgoogleアカウントを選択します
  firebase init # firebase の動作に必要なファイルを対話式で自動生成します
  ```
対話への応答は以下

  ```
  ? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices.
       # Hosting: Configure and deploy Firebase Hosting sitesを選択
  ? What do you want to use as your public directory?
       # buildと入力
  ? Configure as a single-page app (rewrite all urls to /index.html)?`
       # nと入力
  ```
- firebase Hosting でデプロイ

  ```bash
  yarn build # アプリを公開可能な形に変換します
  firebase deploy # firebase hosting でデプロイします
  ```
ここまでで**『5分』**
## アプリが公開されました🎉

ブラウザで `https://[YOUR_FIREBASE_PROJECT_NAME].firebaseapp.com/` にアクセスすると、あなたのアプリが確認できます！
![1568531383464.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131737/004ccccd-a48a-ea0a-97c9-98642ec86f0e.png)
## ここから先の開発フロー

ここから先は以下のように開発を進めつつ

1. `yarn start`でローカルサーバーを立ち上げ
2. ソースコードを編集し`http://localhost:3000/`で確認
3. 作業単位ごとに GitHub にプッシュ

機能単位で以下のようにデプロイしていけば良いでしょう

1. `yarn build`でアプリをビルド
2. `firebase deploy`でアプリをデプロイ

将来的にはmasterへのマージのタイミングで、GitHub からFirebase Hosting に自動的にデプロイできるようにしたいですね(いわゆるCD)

# Tips

- `firebase`コマンドを打ち込むと`command not found`になる

  - パスが通っていないことが原因かもしれません
  - `vim ~/.bashrc`で以下を追記してください
    - `export PATH="XXXXX:$PATH"`
    - xxxxxは`yarn bin`で出てくるパスです

- ちゃんとデプロイしたのに、URLにアクセスすると`Firebase Hosting Setup Complete`とかいう変な画面が出てくる
  - `firebase init`で`build/index.html`を上書きしたことが原因かもしれません
  - `firebase init` -> `yarn build` -> `firebase deploy`の順番を守ればこれは起こりません
  ![1568534158679.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131737/3d924d03-bd1c-0cad-f65a-36f393daaaf1.png)

この他にも、つまづきポイントあったら追加していきたいので、コメントくださいｍｍ
33分でポートフォリオサイトを作成・デプロイまでする裏技とは！？

# 33分でポートフォリオサイト作成

「未経験者が転職のために少しでもアピールするには、ポートフォリオサイトを作った方がいい」

私は未経験からWebエンジニアを目指してプログラミンングスクールに通っているのですが、この言葉を同期から聞いて、正直焦りました。

もう就職活動に動き始めている段階で、GitHubのリポジトリーだけを見せるつもりだったからです。

実際に同期の人のポートフォリオサイトを見せてもらうと、自分で作ったものやカリキュラムで作ったものを簡単に紹介できたり、自分の自己紹介ができたりするので結構目を引きました。

ということで、自分も作るべきなのではないか？と思いました。

ただし時間が、、、。

ということで今回手軽にできる方法をいろいろ調べた結果、Bootstrapのテンプレートを使う方法がめちゃくちゃ手軽だったので、それを紹介したいと思います。

なぜ33分かというと、30分でポートフォリオサイトを作り、3分でGitHubを使ってデプロイするという内訳です。

すでに書くことを決めていたらコピペするだけなので可能です。

完成品は下記のようになります。

![demo](https://gyazo.com/74bdec456994c5ea648be24476ea7d1e/raw)


# ポートフォリオサイトの作り方
それではどうやって、33分でポートフォリオサイトを作るのか説明していきます。

## ① 自分の好きなテンプレートを見つけよう

下記のサイトから自分の好きなテンプレートを見つけ、ダウンロードします。

https://templatemag.com/bootstrap-templates/

ちなみに私はこれを選びました。

https://templatemag.com/demo/Kelvin/


## ② ダウンロードしたテンプレートをVSCodeで編集

ダウンロードしたBootstrapのテンプレートをVSCodeで開きます。

そして経歴やポートフォリオの説明などの文章を、元の文から書き変えましょう。

書き変えた後は、画像を入れ替えます。

まず、自分が入れ替えたい画像を、imgフォルダ下に配置します。

配置した後、

```
src="img/〜"
```

というコードがimgタグにあるので、~の部分に、画像の拡張子までつけた自分の入れたい画像の名前に書き換えます。

背景画像を変えたい場合には、CSSフォルダのstylesheetにある、

```
background: url(../img/〜) no-repeat center top;
```

という〜の部分を、自分の表示させたい画像の名前に書き変えましょう。

以上でポートフォリオサイト作りは終わりです。

微調整も必要だと思うので、そこは適宜HTMLタグを増やしたり、CSSの指定を変えたりしてください。

## ③ GitHubを使って3分でデプロイ

ポートフォリオサイトのようにデータベースとの連携がない場合には、GitHubで簡単にデプロイできます。

手順は、このポートフォリオサイトを自分のGitHubのリポジトリとして追加した後、そのリポジトリ内でSettingsをクリック。

GitHub Pagesという見出しのSourceという欄がNoneになっているので、これをmaster branchに変更。

変更したらURLが生成されます。

そのURLが、あなたのポートフォリオサイトがデプロイされた状態です。

これだけで終わりです。

いやめちゃくちゃ簡単ですね。

# メリット・デメリット

Bootstrapのテンプレートを使用する場合、やはりメリットは手軽にできることです。

おそらく、ここまでこの文章を読んでくれた人はご理解いただけたと思います。

そしてレスポンシブデザインにも対応しているので、スマホで見てもビューが崩れません。

素晴らしすぎますね。

ただしデメリットもあります。

それは、HTML/CSS/JavaScriptの勉強にはならないということ。

当たり前っちゃ当たり前なのですが、テンプレートですでにほとんどのデザインが完成されているので、あまり手を加える必要がありません。

そのため、HTML/CSS/JavaScriptの勉強をしながら、ポートフォリオサイトを作りたいといった人にはおすすめできないです。

これを理解した上で、手軽にポートフォリオサイトを作りたいといった人にはおすすめです。



# 注意点

Bootstrapのテンプレートを使用する場合、

```
<!--
You are NOT allowed to delete the credit link to TemplateMag with free version.
You can delete the credit link only if you bought the pro version.
Buy the pro version with working PHP/AJAX contact form: https://templatemag.com/kelvin-bootstrap-resume-template/
Licensing information: https://templatemag.com/license/-->
```

という文章があるので、無料で使う場合、下記のコードのクレジットは消してはいけません。


# Bootstrapのテンプレートで手軽にポートフォリオサイトを作れる

Bootstrapのテンプレートを使用すれば、手軽にポートフォリオサイトを作れます。

ただしデメリットや注意点もあるので、それを承知した上で今回紹介した手順で作りたいと思った人は、ぜひ参考にしてみてください。
機械学習メモ

#機械学習メモ
データ分析に関わって一年近く経とうとしているので、自分の知っている知識を軽くメモする。

まずデータ分析でできることは2つ
将来の予測とデータの分類

将来の予測は過去のデータを使って、過去の特徴量から将来の数値を推測する。

データ分類は過去のデータを使って、特徴量からカテゴライズする。

今後は、より詳細に記事を書く予定。
Wiki.jsっていうWikiのOSSを使ってみる

以前とある件でwikiを作ってみようかなとツイートしたところ、
フォロワーさんより

> Wiki.jsいいぞ

って教えてもらったので、まずはちょっと試してみよう。
Beta版があるらしいので、そちらを使います。
[ドキュメント](https://docs.requarks.io/)がしっかりしているので、
英語とか全然問題ない方はこちらを参考にした方が早いかも。

# 前提条件

Macを使用
Dockerがインストールされている

# 環境構築

Dockerに既にイメージを作ってあるみたいなので、
[このページ](https://docs.requarks.io/en/install/docker)の下にあるdocker-composeをコピペしてあげるだけです。
両方ともイメージがあるのでそのまま起動します。

```shell
$ docker-compose up
```

そうするとコンソールにこのように表示されました。
http://localhost:3000/ にアクセスすればいいみたいですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/e107287a-b7ae-2c78-238a-62d4fe022b5e.png)
アクセスしたら管理者のログイン情報を入力する画面が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/1c67366e-39bc-4e58-0d1c-fec1be3968d7.png)
`Allow Telemetry`の項目は、開発者に開発のための情報を提供しますか？てきなものです。

`INSTALL`をクリックするとログイン画面に遷移し、ログインするとこのような画面になりました。
めっちゃUIが好みすぎる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/f123dd0e-3507-937a-d14c-bada8468b709.png)

`CREATE HOME PAGE`をクリック。
エディターを好みなものに選択できるようですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/ee1be92e-98e1-261b-f350-482912b52fb0.png)
ただいろいろ表示されていますが、現状は`Markdown Editor`と`Visual Editor`しか使えないみたい。
Markdownがあれば十分なのでMarkDownをクリック。

ページの詳細を設定できます。
タブにある`SCHEDULING`と`SOCIAL`はまだ使えないみたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/a20bed01-2cb8-b333-06a9-64c640ea0d05.png)

おおおかっけええ！
リアルタイムでプレビューがみれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/b9958c48-779a-fed8-ea22-978600e7d406.png)

画像などはサイドメニューから入れられるみたい。
フォルダー形式で管理できるのか。すぎょい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/9951eefe-6765-d1ec-68c8-57f27cbed2cf.png)

編集できたら`CREATE`をクリック。
このような感じになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/ba5a13e2-e680-d8b6-8013-d330cd3dc5c6.png)

管理画面から差分も見れるみたい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/113439/703432b8-25e5-1c43-e919-359e2c69ee4a.png)

# 感想

Wikiの基幹的なシステムは既にあるから使えるには使えそうですね。
UIも好みすぎるし、wikiつくるってことになったら是非使ってみたい。
これからもっと多機能化していくみたいですし、今後に期待。

# リンク集

[公式サイト](https://wiki.js.org/)
[GitHub](https://github.com/Requarks/wiki)
[デモ兼ドキュメント](https://docs.requarks.io/)
[css]pxや%などのサイズ指定について

#始めに
cssのサイズ指定をする際、pxや%など色々な単位がありますが、どれが一番適切なのかよく理解出来ていなかったので自分なりにまとめていきたいと思います。

##pxについて
`px`は絶対値なので値を指定する事でどの様な画面でもそのサイズに固定して表示させる事が出来ます。使用はしやすいですが、レスポンシブ対応する際は、融通が効かないので不具合が出る可能性が高くなります。

```
.test {
    font-size: 16px;
  }
```

##%について
`%`は相対値なので親要素の値によって値が変化します。デフォルトは16pxなのでその値を基準に何%かを表示させる事が出来ます。
レスポンシブサイトを作成する際は後ほど説明します`rem`を親要素の値として使用し子要素に%を使用する事で画面の拡大、縮小する際に自動的に文字のサイズを変更する事が可能になります。

```
.html {
    font-size: 16px;
  }
.test {
    font-size: 200%;
  }
```

この場合のfont-sizeの値は32pxになります。
##emについて
`em`も同じ相対値かつ使用方法は`%`とあまり変わりません。`%`で表現しますと`1em＝100%`となります。

```
.html {
    font-size: 16px;
  }
.test {
    font-size: 2em;
  }
```

この場合のfont-sizeの値は32pxになります。
##remについて
`rem`も相対値でレスポンシブ画面にも対応できる単位となります。[root em]の略でremです。`%`や`em`は親要素の値を参照して表示されますが、`rem`の場合だとルート、つまりhtmlのサイズを基準に表示する事が出来ます。
なので`%`や`em`の入れ子構造の問題に悩まされる事がない為、修正もしやすくなります。

```
.html {
    font-size: 16px;
  }
.test {
    font-size: 2rem;
  }
```

この場合のfont-sizeの値は32pxになります。
##vw/vhについて
`vm`は`viewport width`の略でビューポートの幅の事で、`vh`は`viewport height`の略でビューポートの高さの事です。ビューポートとはユーザーが見ている画面に対しての表示の事です。
`vw`は、画面の横幅を100として、その割合でフォントサイズを指定します。つまり、`1vw`の大きさとは、画面サイズの1/100という意味になります。これは高さを意味する`vh`も同じです。
この他にも`vmax`と`vmin`があります。
画像をフルスクリーンで表示させる場合の使用方法は

```
.fullscreen {
  width: 100%;
  height: 100vh;
  padding: 40vh;
}
```

となります。

#まとめ
cssって本当奥が深いですね。レスポンシブ対応させる場合はこの辺りを理解する必要がありそうです。正直言葉足らずな所もありますので、以下の記事も参考して頂けたらと思います。
https://creive.me/archives/16915/#px
https://qiita.com/39_isao/items/e8242901ba1aadb75676
Mac 初期化の手順

簡潔に言えば、macOS 初期化の手順は、以下の通りです。

1. Mac を再起動し、Apple のロゴが表示されるまで「 Command + R 」を押し続ける。
2. macOS ユーティリティが表示されたら「 ディスクユーティリティ 」を選択し、Macintosh HD を削除する。
3. macOS ユーティリティに戻り「 macOS を再インストール 」を実行する。

Apple File System（ APFS ）については、次のリンクを参照してください。

https://support.apple.com/ja-jp/guide/disk-utility/dsku19ed921c/mac
Vue.js で Moment.js を使ってお手軽に日付フォーマットする

##　Vue.js のフィルタでフォーマット

Moment.js を使ったフィルタを用意すると以下のようにお手軽に日付のフォーマットが可能です。

```vue
<template>
  <h1>{{ new Date() | moment('LTS') }}</h1>
</template>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195024/0c0faf15-de53-62de-3365-5fc9e39caaee.png)

## JavaScript の日付処理は罠が多い

-  `Date#getYear`で1900年からの経過年数が返る
-  `Date#getMonth`で 0 ～ 11 が返る。


JavaScript の日付処理ライブラリである Moment.js を使えばそういった罠を回避し、お手軽に JavaScript の日付を扱うことができます。

https://momentjs.com

現在、Github のスターは 40000 を超え JavaScript の日付処理ライブラリでは最もメジャーなものの一つです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195024/3f0beb94-7daf-3584-d076-195e7c4d3db7.png)



## フィルタの作り方

サンプルプロジェクトを作成します。
既存のプロジェクトに組み込む場合、ここは必要ありません。

```bash
# Vue CLI のインストール　※すでにインストール済みなら必要なし
$ npm install -g @vue/cli

$ npm install -g @vue/cli
# yarn global add @vue/cli

$ cd 任意のディレクトリ

$ vue create moment-filter

$ cd moment-filter
```

Moment.js をインストールします。

```bash
# Moment.jsをインストールする
$ npm install moment --save 
# yarn add moment 
```

Moment.js を使ったフィルタを作成します。

```js
import moment from "moment";

/* 中略 */

  filters: {
    /**
     * @param {Date} value    - Date オブジェクト
     * @param {string} format - 変換したいフォーマット
     */
    moment(value, format) {
      return moment(value).format(format);
    }
  }
```

上記で完成です。簡単。

## テストの表示

テストデータを用意して試してみましょう。

```js
data() {
    const formats = [
      "MMMM Do YYYY, h:mm:ss a",
      "dddd",
      "MMM Do YY",
      "YYYY [escaped] YYYY",
      "LTS"
    ];
    return {
      tests: new Array(formats.length)
        .fill(new Date())
        .map((date, i) => ({ date, format: formats[i] }))
    };
  }
```

今回はとりあえず以下のように並べて表示してみます。

```vue
<template>
  <div id="app">
    <h2 v-for="({date, format}, index) in tests" :key="index">{{date | moment(format)}}</h2>
  </div>
</template>
```

ローカルサーバーを立ち上げます。

```bash
$ npm run serve
# yarn serve
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/195024/2ad2a3f6-1825-702d-5e43-07612af43eb5.png)

フォーマットされた日付が表示できました。


今回作成したコンポーネントの全体は以下のとおりです。

```vue:./src/App.vue
<template>
  <div id="app">
    <h2 v-for="({date, format}, index) in tests" :key="index">{{date | moment(format)}}</h2>
  </div>
</template>

<script>
import moment from "moment";

export default {
  name: "app",
  data() {
    const formats = [
      "MMMM Do YYYY, h:mm:ss a",
      "dddd",
      "MMM Do YY",
      "YYYY [escaped] YYYY",
      "LTS"
    ];
    return {
      tests: new Array(formats.length)
        .fill(new Date())
        .map((date, i) => ({ date, format: formats[i] }))
    };
  },
  filters: {
    moment(value, format) {
      return moment(value).format(format);
    }
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>
```
CardViewの子要素をハミ出そうとした話

# やろうとしたこと

`androidx.cardview.widget.CardView`のCardViewの中身のviewをネガティブマージンを使って外の領域まではみ出そうとした。

# 結論

CardViewを使うのをやめて、FrameLayoutで対応した。

# 検証

## まずCardViewで試す

まずCardViewの子Viewに対してネガティブマージンを設定することによって、cardviewから領域をはみ出そうとした。

```xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:padding="40dp"
    tools:context=".MainActivity">

    <androidx.cardview.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/colorPrimaryDark">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginLeft="-8dp"
            android:layout_marginRight="-8dp"
            android:background="@color/colorAccent"
            android:text="Hello World!" />

    </androidx.cardview.widget.CardView>

</RelativeLayout>
```

レイアウトのプレビューは以下のようになっていました。おっハミ出てる！いい感じ！

<img width="541" alt="スクリーンショット 2019-09-15 16.21.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147934/2c7945c8-5790-219f-2364-6c7513d4b8e3.png">

### しかしビルド後

なぜだ、、はみ出ているべき領域がクロップされている。。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147934/505c69d1-37d0-b7a4-e33a-e90bc920f726.png" width=50%></img>

## FrameLayoutで試す

原因究明のため試しにFrameLayoutでやってみる。レイアウトは以下。

```xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:clipChildren="false"
    android:clipToPadding="false"
    android:padding="40dp"
    tools:context=".MainActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#FF424242">

        <TextView
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginLeft="-8dp"
            android:layout_marginRight="-8dp"
            android:background="@color/colorAccent"
            android:text="Hello World!" />

    </FrameLayout>

</RelativeLayout>
```

プレビューはこんな感じ。うん、さっきと同様ちゃんとハミ出てる。

<img width="530" alt="スクリーンショット 2019-09-15 16.28.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147934/c490f426-a63a-a03d-e90e-d407e1a43bc9.png">

### ビルド後

ちゃんとはみ出た！やはりCardViewの何らかの処理が原因っぽいが、コードを見てもそれらしき処理は見つけられず。。
なんとなくelevationとかが影響してそうかと思いましたが、`cardElevation`属性を0にして試しても同様にはみ出すことはできませんでした。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147934/421dfec1-fa5e-37b6-7b92-ae5292e8f4a3.png" width=50%></img>

# まとめ

今回はCardViewでなくても実現できるUIだったので、CardViewの採用をやめ、FrameLayoutで対応しました。
CardViewの子Viewを飛び出したい場合（あまりないと思いますが）は要注意です。

一応リポジトリはこちらです。
https://github.com/youmitsu/ClipChildrenSampleApp
WebのSMS Receiver API (WebOTP API)

Webにおいて、二要素認証やアカウント復旧のためにSMSでワンタイムパスワードを発行し、フォームに入力させる事がある。

ユーザはSMSで送られたきたワンタイムパスワードをコピー&ペーストなり手入力することになる。

端末(電話番号)の所持確認をより自動的に行えるように、「SMS Receiver API」という機能がChromeの開発者メーリングリスト([Blink-dev](https://groups.google.com/a/chromium.org/d/msg/blink-dev/-bdqHhCyBwM/yFoKtQQRAQAJ))で議論されている。(Androidの[SMS Retriever API](https://developers.google.com/identity/sms-retriever/overview)をもとにしている)

提案自体は、下記URLにある。
https://github.com/samuelgoto/sms-receiver

## Demo
Githubリポジトリ上にあるgitアニメーションがわかりやすい。幾つか検討案があり、オプトアウト
をするかや、モーダルを出すかの違いがある。

- ユーザは電話番号を入力する (もしくは候補から選択する)
- 電話番号がサーバに送られ、ワンタイムパスワードを含むSMSが送られる
- ブラウザは、送られてきたSMSをパースしフォームに入力する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32425/68237f9c-683f-940b-7d80-4752532f4cad.gif" width="360">

## API
ふたつのAPIが検討されている

### Declarative API
INPUTタグに `autocomplete="one-time-code"` を入れる

```html
<input autocomplete="one-time-code"/>
```


### Imperative API 
JavaScriptのAPI

```javascript
try {
  let {content} = await navigator.sms.receive();
  alert("sms received! " + content);
} catch (e) {
  alert("time out!");
}
```

## Format
SMSをパース出来るようにフォーマットが定義されている。
また、SMSがどのWebサイト向けに送られたものなのか識別できるようになっている(WebViewは一旦は非対応)。

```
Your OTP is: 123ABC78.
For: https://example.com
```
来たるnftablesの概要などなど

nft(8)

![firewall_icon.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/258841/317ad48e-3cf1-cebd-2a54-1c6aac1ca76f.png)

```
nft - Administration tool of the nftables framework for packet filtering and classification  
```

## 背景

自宅でnftablesを使ってみようと思うきっかけがあったので記事にしてみました。

* [Man page of nft](https://www.netfilter.org/projects/nftables/manpage.html)

## nftables概要

Linux Kernel 3.13から、パケットフィルタリングなどを管理するツールで「iptables」に代わって、nftablesを採用するLinuxディストリビューションが増えてきています(*)。
nftablesを使ったパケットフィルタリングの設定、コマンド操作の違いについて簡単に解説します。

[※] ちなみにRHEL8より、新たなパケットフィルタリングツールとして nftables が導入されました。
[※] Debian 10 コードネーム「Buster」）からnftablesも導入されています。

## メリット

* フィルターの処理が、線形処理からテーブル探索に変更
* ネットワーク層以外のプロトコルも管理可能
* 文法の取得しやすさ、学習コストの低減

こんな感じでしょうか。3点目に関しては個人的にはとても大きいなと感じました。

## テーブル

nftables には初めから組み込まれているテーブルはありません。テーブルの数や名前はユーザーが自由に決めることができます。

| nftables ファミリー | iptables ユーティリティ |
|:--|:--|
| ip | iptables |
| ip6 | ip6tables |
| inet | iptables と ip6tables |
| arp | arptables |
| bridge | ebtables |

## コマンド

#### テーブル関連

``` bash
# Usage
$ nft [ -nNscae ] [ -I directory ] [ -f filename | -i | cmd ...] nft -h nft -v  

# テーブル作成
$ nft add table family table

# 全てのテールブを表示
$ nft list tables

# テーブル内のチェインとルールを表示
$ nft list table family table
$ nft list table inet filter

# テーブル削除
$ nft delete table family table

# テーブルクリア
$ nft flush table family table
```

#### チェイン関連

``` bash
# Usage
$ nft [ -nNscae ] [ -I directory ] [ -f filename | -i | cmd ...] nft -h nft -v

# baseチェイン追加
$ nft add chain family table chain { type type hook hook priority priority \; }

# ルールの表示
$ nft list chain family table chain

# チェインの編集
$ nft chain <table> <family> <chain> { [ type <type> hook <hook> device <device> priority <priority> \; policy <policy> \; ] }

# チェインの削除
$ nft delete chain family table chain

# チェインのルール削除
$ nft flush chain family table chain
```

## 移行

iptablesからのnftablesへの以降作業についてはすでに色々な方が便利に安全にやる方法をあげているようです。
実際の作業が発生した場合はこういった情報を活かせればいいなって感じでしょうか。
(ちなみに私は全て手で変えてました。。。)

* [iptablesをnftablesに変換してみた](https://qiita.com/takaki@github/items/716a0d55976bc284045c)

## 参考記事

* [nftables wiki](https://wiki.nftables.org/wiki-nftables/index.php/Main_Page)
* [iptablesの後に来るものは何か？： nftables](https://rheb.hatenablog.com/entry/nftables)
* [あなたがnftablesを好きになるわけ](https://yakst.com/ja/posts/187)
Excelを使うからデータベースが作れない！でも、Excelがいい！

# Excel が、データを整理できなくしている
Excel は、すごく便利なアプリケーションです。
そのため、何でも Excel で、データを整理してしまって、効率の悪いデータ管理になっていませんか？

Excelを使ってデータを整理することで、次のような問題が発生しています。


### Excel にデータを保存した時の問題
- 複数人で同時編集ができない（データ共有ができない）
- 入力したデータを再活用しづらい（データベース化できていない）

### Access（データベース）に移行した時の問題
- データベス化するには、多額の費用が必要
- Excelと双方向にデータ連携できない（データベース → Excel 、一方通行）
- データベースを、遠隔地で共有ためにクラウド化するとローカルデータベースとの連携がやりづらい

### データを共有する時の問題
- 複数パソコンでにデータベースを共有するには、専門知識が必要
- ネットワークハードディスク（NAS）を設置するには、専門知識が必要

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/13f917c0-f8a3-ccb1-7af2-4973448d45d7.png)

# このような問題を解決！

- インターネットに接続できれば、複数でデータベースを共有できる
- データベース（Access）とExcelで、双方向にデータを入出力できる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/5ce266ad-9309-0380-d127-7da5938191c2.png)


## システム構成

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/ca0383ba-dc04-24c4-2353-b4bfa4175aa7.png)

- ローカルにAccessデータベースをクラウドにAzure SQL データベースを置く
- AccessデータベースとAzure SQL データベースの両方にデータを保存する


### このようなシステム構成にしたときの利点
- Excelとデータベース（Access）を連携して活用できる
- データを複数人で同時編集できる
- Excelの罫線や装飾などすべてのExcel機能を利用できる
- データをExcelに参照して、ヒポットテーブルなどの集計機能を活用できる

## クラウドデータベース GANSO
[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/93227/510b102f-3d4d-f87c-7b34-afad8d238226.png)](https://access-cloud.hatenablog.com/ganso)
[クラウドデータベース GANSO](https://access-cloud.hatenablog.com/ganso)

このような問題を解決するために、クラウドデータベース GANSO を作成しています。

Excelで作成した多くのファイルをそのまま活用して、データベースと連携できるシステムをご提供致します。
皆様のご意見やご要望をお聞かせください。
【JavaScript】分割代入はネストできる

分割代入 (Destructuring) は下のように配列やオブジェクトを分解して代入することができる。

```js
const [x, y] = [1, 2, 3]
// x = 1, y = 2

const {a, b, c} = {a: 1, b: 2}
// a = 1, b = 2, c = undefined
```

さらに destructuring は下のようにネストできる。

```js
const [[x, y], [z, w]] = [[3, 2, 5], [4]]
// x = 3, y = 2, z = 4, w = undefined

const {a: {a1, a2}, b: {b1}} = {a: {a1: 1}, b: {}}
// a1 = 1, a2 = undefined, b1: undefined
```

オブジェクトと配列を組み合わせることもできる。

```js
const [{x, y}, [z, w]] = [{x: 1}, [2, 3]]
// x = 1, y = undefined, z = 2, w = 3
```

# エラーと回避

以下の場合エラーが発生するので注意する必要がある。

- `undefined` や `null` が オブジェクトとして destructure されるとき
- iterable[^iterable] でない値が配列として destructure されるとき

[^iterable]: iterable とは簡単に言えば値を一つづつ取り出せるオブジェクトのことで、配列や `Set` などがこれにあたる。詳細は[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Iteration_protocols)。

```js
// プロパティ a の値 undefined がオブジェクトとして destructure されている
const {a: {b}} = {}  // Uncaught TypeError: Cannot destructure property `b` of 'undefined' or 'null'.

// 2番目の要素 5 が配列として destructure されている
const [a, [b, c]] = [3, 5]  // Uncaught TypeError: undefined is not a function
```

上記のケースのうち、「存在しない要素/プロパティを destructure するとき」と「`undefined` を destructure するとき」に発生するエラーは**デフォルト値 `{}` `[]` を指定することで回避できる**。

```js
const {a: {b} = {}} = {}
// b: undefined

const [a, [b, c] = []] = [3]
// a = 3, b = undefined, c = undefined
```

これは API の JSON レスポンスなどから値を取り出すときに非常に便利である。

```js:Twitterの例
const {
  user: {
    name,
    entities: {
      url: {
      	urls = []
      } = {}
    } = {}
  } = {}
} = tweetObject
```
Chrome設定のメモ

#1.Chrome起動時に表示するサイトを設定
設定/起動時/特定のページまたはページセットを開く
において新しい"ページを追加"でurlを入力する
chromeのアプリ、New Tab Redirectをインストールし、ここでも上で設定したurlを入力
以上で完了

#2.webサイトからの通知を止める
設定/詳細設定/サイトの設定/通知
で、チェックを外す
R.swift5.0でZeplinとの色の連携が完璧になった

R.swift5.0でZeplinについてのtipsです。

# R.swift5.0未満のつらみ
R.swiftがCLRファイル形式しかサポートしていなかったので、せっかくZeplinがAsset Colorsを吐き出してくれるのに、`R.color`が使えない...。(このCLRファイルが絶妙に使いにくいのです)

なのでZeplinで吐き出される自動生成のコードをXcodeのプロジェクトに追加して利用していました。この問題点は、デザインスペックの管理はZeplin、ソースコード上でのリソース管理はR.swiftに分離したいのに、一部ソースコード上でのリソース管理をZeplinが行なってしまうことです。

この下側のような自動生成コードを使っていました。
<img width="251" alt="スクリーンショット 2019-09-15 15.32.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114709/50520e6a-3334-1656-2bf7-b9813e1dcf4d.png">

# R.swift5.0以降の嬉しさ
R.swift5.0のリリースノートの一文に

```
Removed CLR file support, use color resources instead
```

**CLRファイルのサポートを取り除いて、代わりにカラーリソースを使うようにしました**と書いてあります。

これによって、R.swift5.0からはColor Assetsを参照できるようになったので、自動生成のコードを利用しなくても問題なくなり以下のようなフローに改善されました。

1. Zeplinの「export to xcassets」を押す
<img width="261" alt="スクリーンショット 2019-09-15 15.47.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/114709/9a22f576-c15f-20ce-e51d-d47c2b73be05.png">

2. ビルドをかける
3. R.colorで色を参照可能になる

**超楽！何もしなくて良い！**

これによって、色に関してはデザインスペック管理はZeplin、リソース管理はR.swiftという分離を図ることができました。

# 要望
これはXcode側の問題なのですが、fontをxcassetで定義してコードとストーリーボードから参照できるようになれば、Zeplinがxcassetにfont吐き出して、R.swiftがそれをR.fontで使えるようにして...。ってなりそうなので良いなーと思っています。
位置情報を含んだ画像をMapに埋め込むまでにやったことや参考になったサイト

位置情報がある画像をMapに埋め込むまでの経緯などを備忘録的に掲載していきます。
Mapの表示やピンの表示はこちらです。
[【SWIFT】MapViewを利用した現在位置情報取得](https://qiita.com/clutch0330/items/c6b75a7999d806b58ba2)



参考サイト
[【Swift】UIImagePickerControllerでカメラロールから写真を取得](http://www.cl9.info/entry/2017/07/17/173803)
rails popular error of top 10

# Topic about top 10 error

tell us popular error and 
way to prevent them



# 1.ActionController::RoutingError

this error get 404error

this means your app doesn't have URL.


# 2. NoMethodError: undefined method '[]' for nil:NilClass

- avoid user& 

```
street = user&.address&.street
```


# 3.ActionController::InvalidAuthenticityToken


CSRF (Cross Site Request Forgery)


## word 

- gotchas　落とし穴
- relevant 
  - ex） errors are not relevant to most readers.

- dig in
  - see detail


- classic
  - very typical of its kind.

- errant 間違った
  - errant users 

- keep in mind 

ex）
You should also keep in mind that

- notation 表記方法
- retrieve
- internal error　内部エラー

- vulnerability 脆弱性
- malicious　悪意のある
- mitigate 半減させる


# 記事

https://dev.to/philnash/top-10-errors-from-1000-ruby-on-rails-projects-and-how-to-avoid-them-24m
GolangのWebサーバで階層型アーキテクチャで行く場合、panicを使うと良いと思う

# Don't panic!!

この言葉があることは十分に承知しています。

しかし、Golang標準ライブラリでも使っている箇所があります。

しかも、1ヶ所、2ヶ所では無いです。

（一番下にリンクした記事では、ざっくりgrepで、4000ヶ所らしいです。テストが含まれている気がして、正確性には疑問がありますが。。）

おそらく使うべき状況というものが存在するのだと思います。

（そもそも、絶対ダメなら言語仕様に無いはずです。）

なので、十分に見切って使う分には、使ったほうが良いと思うのです。

余談ですが、僕のことを好意的に思っているエンジニアでも、この話をすると引かれることが多いです。。。

### 使っちゃ駄目なパターン
---

[Golang の defer 文と panic/recover 機構について](https://blog.amedama.jp/entry/2015/10/11/123535)

上記記事の引用：
> 
> * 外部に公開する API はエラーを伝える手段として panic() を使ってはいけない
>   * 多値の返り値 w/ error インターフェースを使うこと
>   * panic() はパッケージをまたいで伝搬させることがないようにする
> * panic/recover 機構はスタックが深くなるような呼び出しをする際に有用
>   * 使用することで可読性を向上させることができる
> 
> つまり、外部にエラーを伝える手段としては error インターフェースを使うのが正式なやり方で、panic/recover はあくまで内部的に用いるべきもの、ということらしい。

Golangは全体的にエラーを返すやり方で記述されています。

なので、とあるライブラリだけ、panicを使って外部にエラーを返すのは、迷惑すぎるということだと思います。

逆に言えば、内部で使用する分には問題ないということです。

タイトルのWebサーバで階層型アーキテクチャの場合、階層分の `if error` が無くなって良いと思うのです。

### メリットについて
---

色々とメリットが多いです。

* エラー時にstacktraceの詳細なものが、必ず取れる
  * Golang書いてびっくりしたのが、stacktrace頑張らないと出ないんですよね。。
* `if err != null` の記述が大幅に無くなるので、見通しが良くなる
* メソッドチェインが出来るようになる
* エラーのreturn忘れが無くなる
* 1値返すメソッドか？、2値返すメソッドか？、あまり考えなくて良くなる
* 考えることが減るのと、コーディング量が減るので開発が速くなる
* どんなエラーが発生しても、必ず捉えられ後処理を実行できる
  * データベースのTransaction、Rollbackとか

エラーのreturn忘れですが、知り合いのエンジニアからLinter使うでしょ？的な話がありました。

（ [staticcheck](https://github.com/dominikh/go-tools) などのLinterを使えば指摘してくれます）

ですが、Linter無いと危なくて書けないとか、言語として間違っていると思います。

Golangはおそらく、Webサーバ用に作ってないのでしょうが、panic使えば回避出来るとか、例外的状況にも対応出来る言語だなぁと思います。

### システム開発時に重要だと思うこと
---

僕はシステムは、結果を出してなんぼだと思っています。

大きな会社に居た時に、すごいメンバーがサービスを作って、売上出ないからクローズというのを、よく見かけました。

さらに最近の世の中は、変化が速く、変化よりも速い速度で製品を出せないと、出す頃には古くなっているという自体が起きます。

なので、システム開発に重要なのは、下記の2点になると思います。

```
* 正しく動作すること
* 速く開発が出来ること
```

これを考えると、

* Golang
* Webサーバ
* 階層型アーキテクチャ
* panic解禁

というのは、かなり良い構成じゃないかなぁと。

人手不足で納期も短い世の中とあっては、プラクティスは気にしつつも、

結果が出るほうを優先するのが良いと思いますが、どうですかね？

### 開発に銀の弾丸は無い
---

よく銀の弾丸は無いと言われます。

そうであれば、

ベストプラクティスも存在しないのでは？

と思います。

現時点で書いたコードは、一年後にエンジニアとしてレベルが上がっているのであれば、レガシーコードに映るはずです。

どうせレガシーになるなら、現時点でチームが納得のいく、ベストを尽くすまでなのかなぁと思います。

（駄目だった場合の責任取るのもチームですし。）

完全に余談ですが、コードレビューの時に自分のコードが指摘されると、腹が立つという人が居るみたいです。

チームのレギュレーションに沿って、機械的にレビューするなら、そんなことにはならないと思うのですが、どうなんですかね？

### Javaとかのtry-catch機構に近い
---

悪手も状況が違えば、善手になりうると思います。

Javaのtry catchは、強制されるのがイケてないだけで、

コードがシンプルになるという意味では、エラー機構として優れていると思います。

そして、それはGolangでも出来ます。

Webサーバのような、DBなどの外部APIの待ち時間が支配的な状況下においては、実行速度の低下も気にもなりませんし。

### まとめ
---

韓国のエンジニアに見せてもらったGolangの本では、堂々と使おうと書いてあるみたいです。

日本の記事を見てみると書いている人がいないので、書いてみました。

（もしかしたら、日本の場合、強烈なマサカリが飛んでくるので怖くて書けないだけかもしれませんが。。）


システム開発は、トレードオフの連続で、記述的に正しいよりは、結果が出るのかどうか？を軸に考えたほうが良いと思います。

２人しかいないチームで実際にpanic使って書いていますが、かなり良くなったと思っています。

もしかしたら後で後悔することになるかもしれないですが、今の所、その兆候は全く無いですし、そんときはそんときで書き直せば良いのだと思います。

ちゃんとテスト書いているから、なんとかなります。

最後に、英語の記事ですが、下記はサンプルコードもありますので、時間があるときにでも見てみてください。

* [Panic like a PRO](https://hackernoon.com/panic-like-a-pro-89044d5a2d35)
SQLの演算子の優先順位について

SQLの演算子に優先順位があるってことを知らなかったのでメモ

参考：https://hosochin.com/2021/11/10/post-999/

spring data jpaのspecificationでクエリを生成しようとしていたところ

##### 生成したいクエリ

```sql
SELECT * FROM WHERE 条件A OR (条件B AND 条件C)
```

##### 実際に生成されたクエリ

```sql
SELECT * FROM WHERE 条件A OR 条件B AND 条件C
```
どう頑張っても期待するクエリにならずハマった。。
が、上記の２つのクエリを叩いてみると・・・取得結果は変わらず、「？」ってなった。

## SQLの演算子の優先順位

演算子の優先順位的に括弧が無くても AND が先に処理されるということでした。。必要ないからspecification側で生成されたクエリには括弧が入ってないってだけだったんですね。
参考欄にMySQLとOracleの演算子の優先順について載せておきます。

## 参考
[Mysqlの演算子の優先順位](https://dev.mysql.com/doc/refman/5.6/ja/operator-precedence.html)
[Oracleの演算子の優先順位](https://docs.oracle.com/cd/E53235_01/server.761/es_eql/src/ceql_expr_precedence_rules.html)
マイクロマウスをはじめまチュー（４）

[「マイクロマウスをはじめまチュー（３）」](https://qiita.com/tkato635/items/6a26d0ce01025f6afdf8)の続きです。

#まずは一安心、迷路探索す
ハードウェア作成後の動作確認は、LEDの点滅を確認しただけでしたので、今回はソフトウェアの作成方法を勉強しながら全体的な動作確認を行いました。
組み立てキットに付属しているソフトウェアの取扱説明書に従ってやっていきました。
- LEDを光らせよう
- ブザーを鳴らそう
- スイッチを使おう
- モードを作ろう
- センサの値を見よう
- モーターを回そう
- 迷路を走破しよう

理解できないところはありましたが、とりあえず迷路探索してみたかったので、一通りやり終えました。
LEDを光らすだけでも、Arduinoやラズパイに比べて煩雑なので、電子工作の初心者の場合は、マイコンの仕組みについての深い理解が必要だと思います。
これをやってて気づきましたが、この取扱説明書の他に操作説明書も見ながらやらないといけませんでした。
操作説明書には、センサや走行距離の調整方法が書いてあり、これらを行わないと上手く迷路を走ってくれません。

結果的に迷路を探索できるようになったので、ハードウェアは問題なさそうです。
動画は、左下区画がスタートで、右下区画がゴールと設定して、迷路探索したものです。
（Qiita初心者で、動画のベストなアップロードの方法が分からないので、動画が中途半端です）

まずはサンプルプログラムを細かく見て理解し、自分なりのプログラムを作っていきたいと思っています。

![ezgif-5-69ce12403cfc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490861/8d012644-c5b3-1825-9c65-bf809d5c515e.gif)
![ezgif-5-460f49479af1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/490861/b840b686-8c81-f996-c063-6f13cc034104.gif)
Apsara Conference 2019 (杭州云栖大会) に向けて

# はじめに

最近注目のアリババグループとアリババクラウド。    
今年もその年次大会であるApsara Conferenceが中国は杭州で行われます。
<A HREF="https://www.alibabacloud.com/tc/apsara-conference-2019" target=_blank>https://www.alibabacloud.com/tc/apsara-conference-2019</A>
日本からの参加者も増えてきました。
昨年ツアーのお手伝い係をさせて頂いた経験から今年参加される方にポイントをお伝えしておきます。


# 持ち物

- 傘
    - 突然大雨が降る季節ですから必須です
- ティッシュ類
    - 中国の公共場所には紙類の備え付けがありません
- 少額の現金（後述。現地到着後調達で良い）

注：パスポートや衣服等、一般に必要とする物は記載していません。



# 事前にインストールしておきたいアプリ

- WeChat (微信)
    - 日本からの参加者グループがあり連絡に使いますから必須です
- AliPay (支付宝)
    - アリババグループのニューリテイルを体験したければ是非
- DingTalk (钉钉)
    - カンファレンスのセッションを予約したり顔認証で会場へ入れるようになります
- Baidu Map (百度地图)
    - 中国ではGoogle Mapsが機能しません



# 持ち込み禁止品

- 電子タバコ
中国で電子タバコは禁止物品です。
入国時に発見されなかったとしても、出国時の手荷物検査で発見され没収されると悲しいですよね。
これは中国の法律です。守りましょう。


- モバイルバッテリーの一部
中国の法律で航空機に持ち込み可能なモバイルバッテリーは `20000mAhまで` の物を１人１個と制限されています。受託手荷物は全面禁止です。
これ以上の大容量が拒否されることはもちろん、 `容量不明な物も拒否` されます。
モバイルバッテリーの筐体にはっきりと容量が記載されている事を確認して下さい。
ノベルティなどに多いですが容量の記載が無いものはどんなに小型であっても拒否されます。
日本にはそういった規制はなく入国時は持ち込めてしまいますが、出国時の手荷物検査で発見され持ち帰れなくなります。



# 現金も普通に使えます

AliPayやWechatPayといったQRコード決済が主流ですが無くても大丈夫です。
実際は現金もクレジットカードも普通に使えます。
タクシーの運ちゃんなど露骨に嫌がられることもありますが支払可能です。
ただしお釣りがないと多く取られたりするので小銭を用意しておきましょう。



# 現金の調達方法

## 基本は現地で

一部例外もありますが日本で両替すると非常にレートが悪いです。
どうしても日本で調達したい場合は「アクセスチケット」を推奨します。


## 現地での調達方法

- クレジットカードのキャッシング（推奨）

クレジットカードで現金を借りる（キャッシング）方法です。
空港や街中にある銀行ATMへクレジットカードを入れ暗証番号と金額を入れると現金が出てきます。
日本でのそれと同様、金利がかかりますがクレジットカード会社の約定レート(TTB)なので両替商へ現金を持参するよりは良いと思います。
とはいえ年利１８％は月利１．５％になりますから、次の支払サイクルまで最長４５日程度かかりそれなりの金額になる場合が有ります（１０万円で最大２０００円程度）。
そこで事前返済を行うことを推奨します。
これは帰国後、クレジットカード会社へ連絡し「海外キャッシングの事前返済をしたい」と伝えるものです。
ネットバンキングが使えるならば現地滞在中に返済手続きをする事もできます。
こうすることで金利を節約でき、クレジットカード決済するよりも安くなったりします。
（クレジットカード決済は通常２％の為替手数料が上乗せされたレートで決済されている）


- 事前にクレジットカード会社へ連絡を

クレジットカードの不正利用が多い中国は警戒されています。何故かエラーで現金を引き出せない事があります。
事前に連絡をして中国でキャッシング予定である旨を伝えておくとそういったリスクを減らせます。


- 空港等の両替商

文字通り、空港で現金を渡し現金を受け取ります。
これを行うならば必ず中国で。日本で行うのはやめておきましょう。



# 通信環境

中国にはグレート・ファイアウォール（金盾）が存在し、検閲規制が行われています。
GmailやFacebook、LINEなどは接続出来ません。会場やホテルのWi-Fiも同様です。
それでは困る人は日本などの携帯電話を持ち込みテザリングしましょう。
外国契約の携帯電話は検閲対象外（契約元通信事業者の設備経由での通信になるから技術的に検閲不可能である）のため通常通り利用できます。
ただし国際ローミングは料金が高いので要注意。ご利用は計画的に。



# ホテルにて

## 室内のその品物は有料かも

日本のホテルと違い、室内に置かれている消耗品類で有料の場合が多々あります。
ペットボトルの水や洗面所のアメニティ類でも有料の物があるので要注意です。
有料の品物には必ず価格が書かれています。封を切る前に確認しましょう。



# カンファレンスにて

## 基本は全て中国語

基調講演には同時通訳が入ります（中国語＝＞英語）。日本語への通訳はありません。
ブレイクアウトセッション、展示ブースなどそれ以外は基本中国語のみです。英語話者も少ないです。
ごく一部、英語への同時通訳が行われるセッションがあるのでツアー組はこちらへ案内予定です。


## 基調講演はVIPのみ

日本からのツアー参加者は３日券で入りますが、基調講演には入れません。
基調講演の入場は１０万円以上するVIP票が必要ですが発売開始数日で完売しました。


## ランチ難民多発中

昼食会場が参加者に比して非常に小さくランチ難民が多発しています。
ツアー組はアリババさんのキャンパスをお借りできるよう手配中です。
VIP票所持者はVIPラウンジで昼食が提供されますから心配無用です。
一般参加の場合、中国語が話せなければ食べ物を持って会場入りするのが無難です。徒歩移動可能な会場周辺には何も有りません。
中国語が話せる方は `饿了么` といった出前アプリで会場内へ配達を依頼する事が出来ます。
これは「会場内のｘｘブース前」といった指定も可能なので会場外へ出る必要もありません。



# 帰国時、傘は受託手荷物へ

傘の航空機内への持ち込みは禁止されています。折り畳み傘も不可です。



# ジャパンナイト開催！

８月２６日夜に日本人参加者であれば誰でも参加可能なジャパンナイトを開催します。
<A HREF="https://alibabacloud.connpass.com/event/147392/" target=_blank>https://alibabacloud.connpass.com/event/147392/</A>
皆で意見交換することで最終日となる翌日のカンファレンス参加の役に立つことと思います。

それでは皆様会場でお会いしましょう。
bundle installとbundle updateの違い

##はじめに

Railsチュートリアルを進めていく中で、両者のコマンドの違いがいまいち理解出来なかったので、備忘録として投稿します。

##両者の違い

- `bundle install`
ケース別によって動きが変わるため、以下図にまとめました。
![スクリーンショット 2019-09-15 14.40.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/474060/4c1ac04a-567d-f28f-6f28-4c8cd3218ba4.png)

**2019/9/17　追記**
条件分岐の「Gemfileに変更あり」はより正確には「gem ごとに Gemfile の記述と Gemfile.lock の記述に差異がある」とご指摘をいただいたので、追記します。

- `bundle update`
Gemfileを元にGemをインストールする。
各Gemのバージョンと依存関係にあるGemとバージョンが最新になる。
インストール後、Gemfile.lockを更新する。

**本番環境で`bundle update`は原則使用しない。**
`bundle update`を行うと各Gemとバージョンが最新化され、開発環境と同じ動作にならなくなる可能性があるため。

##用途
- `bundle install`  
新規開発スタート...必要なGemをインストールするため。  
本番環境へデプロイ...開発環境と同じGemをインストールするため。 
- `bundle update`  
開発環境でGemを追加・更新...インストールするGem及び依存関係にあるGemを最新化させるため。

##参考記事
- [bundle install と bundle update の違い](https://forest-valley17.hatenablog.com/entry/2018/09/08/120108)
- [bundle install と updateの違い](https://qiita.com/YusukeHigaki/items/0314e2ec1d13cc5d4c99)
ElixirでArray#productなことをしたい

# 結論
- [内包表記](https://elixirschool.com/ja/lessons/basics/comprehensions/)を使う

## Elixir
```sample.exs
iex(2)> for x <- [1,2], y <- [3,4], z <-[5,6], do: [x, y, z]
[
  [1, 3, 5],
  [1, 3, 6],
  [1, 4, 5],
  [1, 4, 6],
  [2, 3, 5],
  [2, 3, 6],
  [2, 4, 5],
  [2, 4, 6]
]
```

## Ruby
```sample.rb
[1,2].product([3,4],[5,6]) # => [[1,3,5],[1,3,6],[1,4,5],[1,4,6],
                           #     [2,3,5],[2,3,6],[2,4,5],[2,4,6]]
```
- サンプルは[こちら](https://docs.ruby-lang.org/ja/latest/class/Array.html#I_PRODUCT)を転載させていただきました

# 記事を書いたきっかけ
- ひょんなことから知ることになった[Elixir](https://elixir-lang.org/)をいろいろあって勉強しています
- 近所の図書館に [プログラマ脳を鍛える数学パズル シンプルで高速なコードが書けるようになる70問](https://www.amazon.co.jp/dp/B016QEE30G/) という本がありましてこれを借りてきました
- [Elixir](https://elixir-lang.org/) で書いていってみることにします
- Q02で[Ruby](https://www.ruby-lang.org/)で言うところの [Array#product](https://docs.ruby-lang.org/ja/latest/class/Array.html#I_PRODUCT) 的なことをしたくなりました
    - 私にとっては、接する時間が最近の中では一番多い言語は[Ruby](https://www.ruby-lang.org/)です
    - [Elixir](https://elixir-lang.org/)は、父が[Erlang](https://www.erlang.org/)で母が[Ruby](https://www.ruby-lang.org/)と言われることがあるそうで、[Ruby](https://www.ruby-lang.org/)に精通されている方は親しみやすいとおもいます
- はじめは以下のような感じのものを自作しました
- もっと便利なものがきっとあるだろうとふて寝をしたあと、 [プログラミングElixir](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0Elixir-%EF%BC%A4%EF%BD%81%EF%BD%96%EF%BD%85%EF%BC%B4%EF%BD%88%EF%BD%8F%EF%BD%8D%EF%BD%81%EF%BD%93-ebook/dp/B01KFCXP04/) で勉強した内包表記のことが思い浮かびました
- さっそく [Elixir School](https://elixirschool.com/ja/) に通学して[確認](https://elixirschool.com/ja/lessons/basics/comprehensions/)させていただきました
    - ありがとうございます

```sample.exs
iex(8)> f = fn enum1, enum2 ->
...(8)>   enum1
...(8)>   |> Enum.reduce([], fn x, acc ->
...(8)>     acc ++ Enum.map(enum2, fn y -> [x, y] end)
...(8)>   end) 
...(8)> end

iex(9)> f.([1,2], [3,4]) |> f.([5,6]) |> Enum.map(&List.flatten/1)
[
  [1, 3, 5],
  [1, 3, 6],
  [1, 4, 5],
  [1, 4, 6],
  [2, 3, 5],
  [2, 3, 6],
  [2, 4, 5],
  [2, 4, 6]
]
```
- _[問題集](https://www.amazon.co.jp/dp/B016QEE30G/)に提示されている回答までの目標時間は大幅に過ぎていますが気にしないことにします_
- _自分との闘い_
- 日本語の記事が見当たらないとおもって書いたのですがすでに先輩がいらっしゃいました！
    - [Rubyのarray.product(other_array)をElixirでやる](https://qiita.com/junsumida/items/6d2bbea74d227711c447)