OmniAICreator/Qiita-1.07M huggingface dataset:
読書：マイクロサービスアーキテクチャ（オライリー社）その2

MicroServiceについてお勉強読書をしたので、少しずつまとめていくことにする。

# 3章　サービスのモデル化方法

3章では、マイクロサービスの境界に関する説明を、架空のサービスを例に挙げて説明している。

## 例：MusicCorp
マイクロサービスがどのように機能するかを説明するため、架空のサービスMusicCorpを設定する。
MusicCorpは音楽CDのオンライン販売を行うサービスである。

## 優れたサービスにするには

優れたサービスにする2つの主な概念として、疎結合と高凝集性がある。

### 疎結合
マイクロサービスの本質は、システムの他の部分を変更する必要なしに、あるサービスを変更してデプロイできることにある。そのためにサービスが疎結合であることが必要である。
サービスの密結合を生み出す典型的な誤りは、サービス同士が密に結合する統合方式を選び、サービス内の変更によってコンシューマの変更が必要になることである。これの回避方法については4章で述べる。

### 高凝集性
高凝集性とは、関連する振る舞いを一緒に、関連しない振る舞いを別の場所に配置することである。それにより振る舞いを変更するとき、1か所の変更ですみ、その変更を早くリリースできる。
高凝集性を実現するためには、関連する振る舞いが1か所に存在し、他の境界との通信が出来る限り疎になるようドメイン内の境界を探す必要がある。

## 境界づけられたコンテキスト
この考え方では、どのドメインも複数の境界づけられたコンテキストからなり、それぞれのコンテキストには外部と通信する必要のないモデルと、外部の他のコンテキストと共有されるモデルがある。境界づけられたコンテキストから情報が欲しい場合や、境界づけられたコンテキスト内の機能を要求したい場合は、モデルを使用して明示的な境界と通信する。
MusicCorpの事業を例にとると、ドメインは運営する事業全体になる。このドメインで境界づけられたコンテキストの例として、倉庫と経理を挙げる。

### 共有モデルと隠れモデル
MusicCorpでは、経理部門と倉庫を2つの別個の境界づけられたコンテキストとみなせる。
経理部門には、倉庫の詳細な内部作業の知識は必要ないが、在庫水準を把握し、帳簿を最新の保つ必要がある。そこで、在庫品目が経理部門と倉庫のコンテキスト間の共有モデルになる。
しかし、倉庫のコンテキストから在庫品目に関するすべてをやみくもに公開する必要はないことに注意する。そのため、内部専用の表現と公開する外部表現がある。

### モジュールとサービス
新しいコードベースを始めるときは、プロセス境界内でモジュールを使用して関連するコードをまとめ、システム内の他のモジュールとの結合を減らすところから始めるのが良い。ドメインで境界づけられたコンテキストが見つかったら、コードベース内では共有モデルと隠れモデルを備えたモジュールとしてモデル化をするようにするとよい。
このようなモジュール境界は、マイクロサービスの優れた候補となる。一般に、マイクロサービスは境界づけられたコンテキストときれいに一致するようにするからである。サービス境界がドメイン内の境界づけられたコンテキストと一致し、マイクロサービスが境界づけられたコンテキストを表していれば、マイクロサービスを疎結合で高い凝集性を持たせるためのよいスタートを切ることが出来る。

### 時期尚早な分解
初めてのドメインでは、システムをマイクロサービスに分解するのが時期尚早だとコストがかかってしまう場合がある。例えば、数か月後にサービス境界の最初の解釈があまり正しくなかったことが判明したときなどである。その場合、開発したマイクロサービスを一度モノリシックシステムにマージし、適切な境界位置を理解した後、再度マイクロサービスに分解することになる。
マイクロサービスに分解したい既存のコードベースがある方が、最初からマイクロサービスに取り組みよりはるかに簡単である。

## ビジネス機能
組織に存在する境界づけられたコンテキストについて考える際、共有するデータの観点ではなく、そのコンテキストが残りのドメインに提供する機能について考えるべきである。サービスとしてモデル化する際は、この機能がネットワーク経由で他のコラボレータに公開される主要な操作になる。

## 入れ子になったサービス
マイクロサービスの境界を検討するときには、まず大きく粒度の荒いコンテキストの観点で考え、それから入れ子になったコンテキストに沿って分解し、接合部で分割する利点を求める。入れ子になったコンテキストは他の連携するマイクロサービスから隠したままにすると効果的である。
完全に分離する手法と入れ子にする方法のどちらを選ぶかは、組織構造に基づくべきである。例えば倉庫の機能を注文フルフィルメント、在庫管理、入荷に関連する機能に分割するとき、それぞれを異なるチームが管理している場合は、恐らくトップレベルマイクロサービスが理にかなっているだろう。一方、1チームで管理している場合は、入れ子になったモデルの方が理にかなっている。

## 技術的境界
技術的な接合部に沿ってサービス境界をモデル化することは、必ずしも間違いではない。しかし、これは接合部を探すための第一条件ではなく、第二条件であるべきである。第一条件としては、ビジネスに焦点をあててシステムを分割することを考えるべきである。

## 3章まとめ
3章では優れたサービスにする方法と、問題ドメインでの疎結合と高凝集性の利点が得られる接合部の探し方について述べた。境界づけられたコンテキストはこのような接合部を探すのに便利なツールであり、マイクロサービスをこれらの境界に一致させることで、マイクロサービスの利点を得られやすくなる。次回以降はさらに技術的な話に踏み込んでゆく。
【GCP/AWS】判断軸としてのレイテンシ

## どのクラウドのサービス使用すべきか
例えば、AWS AuroraかCloud SQLをどちらを使用するべきかと考えた時に、様々な判断軸で比較をします。
料金、スケーラビリティなどそのフェーズによって様々です。
その判断軸の中で一つ出てくるのが、**レイテンシ**です。
この場合知りたい情報は、クラウド内のサービスを使用した場合とクラウド外のサービスを使用した場合とで、どのくらいレイテンシに差が出るのかということです。
今回はこの件について調査してみました。

## クラウド外のレイテンシ
下記の記事を参考にしています。
[Public Cloud Inter-region Network Latency as Heat-maps](https://medium.com/@sachinkagarwal/public-cloud-inter-region-network-latency-as-heat-maps-134e22a5ff19)

この記事では、 各クラウドのリージョン毎にラウンドトリップタイム(RTT)を算出し、どのくらいクラウド内と外とで数値が変化するかをヒートマップで出力してくれています。
[RTT【 Round-Trip Time 】ラウンドトリップタイム](http://e-words.jp/w/RTT.html)

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/ba5105ed-60b1-09de-2248-82045b735aa4.png)
下記記事より引用
[Public Cloud Inter-region Network Latency as Heat-maps](https://medium.com/@sachinkagarwal/public-cloud-inter-region-network-latency-as-heat-maps-134e22a5ff19)

上記の図を見てみると、
`gce-asia-northeast-1`から、`ec2aws-ap-northeast-1`へのレイテンシは、`2ms`になっています。
一方、`gce-asia-northeast-1`から、`ec2aws-ap-northeast-2`へのレイテンシは、`32ms`になっており、急に数値が跳ね上がっています。

他でも同じことが言えることから、
同じクラウド内であっても、**リージョンが違えば、レイテンシが増加し、**
別のクラウドであっても、**リージョンが同じであれば、レイテンシは増加しないことがわかります。**

### 物理的距離
>RTT is correlated to the physical distance between the communicating hosts (speed of light) and to the quality of the network

記事内でも触れられている通り、RTTは物理的距離が関係しているため、このような結果になったのではないでしょうか。

## クラウド内のレイテンシ
ではクラウド内のレイテンシは実際どのくらいなのでしょうか。
そこを検証してくれているのが下記記事になっています。
[AWSアカウント間AZ間レイテンシ - Qiita](https://qiita.com/sasasin/items/17135d5c5465fc53d385)

EC2からRDSへのレイテンシを調べてくれていて、同じなら**0.5ms**であることがわかります。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/8b9e4190-0923-83c3-182e-3f65f89eb369.png)
下記記事より引用
[AWSアカウント間AZ間レイテンシ - Qiita](https://qiita.com/sasasin/items/17135d5c5465fc53d385)

## 何に注意すべきか
上記より、現状の結論は、別クラウドに関係なく、**リージョン**に注意すべきです。
別クラウドであっても、リージョンを同じにすれば、レイテンシを抑えることができるとわかりました。
厳密な比較ではないですが、非常に参考になる数値だと思います。

## その他参考になった記事
[逆引き GKE ネットワーク編 - Qiita](https://qiita.com/nirasan/items/dc65b813dd754f8df2ed)
[Compute Engine のリージョン選択に関するおすすめの方法  \|  ソリューション  |  Google Cloud](https://cloud.google.com/solutions/best-practices-compute-engine-region-selection?hl=ja)
Unityアニメーションが再生後すぐに終了する場合の解決方法

Unity初心者用です。

例えば攻撃アニメーションを設定してスペースボタンを押したら
攻撃してアニメーションを再生させるようにする。

しかし、アニメーションが一瞬しか動かずに終了してしまいます。

コルーチンなどを使って再生終了まで待ってもいいのですが、
簡単な方法を紹介

アニメーターのインスペクターで
アニメーションが終わった後のところ（戻る矢印）で　Has Exitにチェックを
入れてExit Timeでアニメーションの終了を調節します。

Unityのはじめの頃ってanimatorの使い方なんかがわからないんですが、
いろいろ試しているうちにすこしづつわかるようになってきました

![animationHasExitTime.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560721/1dda1df0-f177-e594-c755-084015bb9960.png)
MacでCatalinaにOSアップデートするとincludeでwchar.hなどが見つからなくなった

OSアップデート後コンパイルが通らなくなりました
エラー文
/usr/local/Cellar/gcc@4.9/4.9.4_1/include/c++/4.9.4/wchar.h:119:24: fatal error: wchar.h: No such file or directory
 #include_next <wchar.h>
などなど・・
以前にも同様のエラーが発生したことがあるのですが
ネットに載っている方法（gcc再インストールやxcode再インストールなど）
ではうまくいきませんでした
ディレクトリ4.9.4にwchar.hなどヘッダーファイルはあるんですがコンパイルできないです
どうしてでしょうか？
NVIDIA Dockerのインストール方法

# 環境
OS：Ubuntu 18.04 LTS
CPU:Intel Core i9 9900K
RAM：DDR4-2133 32GB
GPU：GeForce RTX 2080 Super 8GB

# 前提
GPUのドライバーはインストール済み

# インストール手順
## nvidia-docker2を使う場合
### Docker本体のインストール
```
sudo apt-get update && sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable" && \
sudo apt-get update && \
sudo apt-get install -y docker-ce docker-ce-cli containerd.io && \
```

### Nvidia Dockerのインストール
```
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | \
  sudo apt-key add -
curl -s -L https://nvidia.github.io/nvidia-docker/ubuntu16.04/amd64/nvidia-docker.list | \
  sudo tee /etc/apt/sources.list.d/nvidia-docker.list && \
sudo apt-get update && \
sudo apt-get install -y nvidia-docker2 && \
sudo pkill -SIGHUP dockerd
```


### Nvidia-Container-Toolkitのインストール
```
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) && \
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - && \
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list && \
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit && \
sudo systemctl restart docker
```

## Docker 19.03より最新版を使う場合（--gpus）
### Docker本体のインストール
```
sudo apt-get update && sudo apt-get install -y \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common && \
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable" && \
sudo apt-get update && \
sudo apt-get install -y docker-ce docker-ce-cli containerd.io
```

### Nvidia-Container-Toolkitのインストール
```
distribution=$(. /etc/os-release;echo $ID$VERSION_ID) && \
curl -s -L https://nvidia.github.io/nvidia-docker/gpgkey | sudo apt-key add - && \
curl -s -L https://nvidia.github.io/nvidia-docker/$distribution/nvidia-docker.list | sudo tee /etc/apt/sources.list.d/nvidia-docker.list && \
sudo apt-get update && sudo apt-get install -y nvidia-container-toolkit && \
sudo systemctl restart docker
```

## 便利な設定
### sudo無しでdocker runとかをするための設定
```
sudo usermod -aG docker $(USERNAME)
```
[PyCPA]Pythonデータサイエンス実践講座 第2回でのゆる〜い気付き

# Pythonデータサイエンス実践講座 第2回
## 1.はじめに
PyCPAというCPA(公認会計士)向けコミュニティの勉強会に参加させて頂いた後の、自分なりのゆる〜い気付きポイントのまとめです。
[Pythonデータサイエンス実践講座 第2回 Powered by PyCPA](https://pycpa.connpass.com/event/162734/)
![004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79389/e8653fed-ab08-3235-0462-2aa7349dc508.jpeg)
実はLT枠(プログラミング学習の遍歴と本講義での目標）で参加したのですが「がんばります！」という勢いだけのLTなので、資料公開は行いません:sweat:

なお[前回](https://qiita.com/nagahisa/items/7f6eeffd8ac63687acba)同様、今回の内容も講義内容にはほとんど関係ないので、内容が気になる方は、講座で使用している以下の書籍や、この本のベースとなった無料コンテンツを参照してください。
書籍：[東京大学のデータサイエンティスト養成講座](https://www.amazon.co.jp/dp/4839965250/)
無料コンテンツ：[GCIデータサイエンティスト育成講座演習コンテンツ 公開ページ](https://weblab.t.u-tokyo.ac.jp/gci_contents/)

## 2.ジニ係数って聞いたことあるぞ！

###(1)総合問題3-2
復習のため教科書を読み直してみると、総合問題3-2に、「ローレンツ曲線とジニ計数化」というのがありました。これは東大の無償コンテンツにも含まれているのでそちらを引用します。
![SS 2020-02-10 6.56.53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79389/ebf6e6bb-fc09-9619-89e1-87fb8c47ae7b.jpeg)

ジニ係数・・・昔読んだ本に出てきた「収入の不公平を表す値で0.4越えると暴動リスクがある」っていう「ジニ値」の事っぽい。

> 不平等の程度を数値で表したものをジニ係数といいます。
　この値は、ローレンツ曲線と45度線で囲まれた部分の面積の2倍で定義されていて、0から1の値をとります。値が大きければ大きいほど、不平等の度合いが大きくなります。


総合問題は置いておいて:sweat:、ジニ係数が気になるのでちょっと調べてみましょう（また何時もの「食い散らかし」にならなければ良いのだが・・・)

###(2)Global Noteデータ
まずは、GDP比較のような公開データ調べる時に使わせていただいているGlobal Noteってサイトで探してみました。Global Noteさんには申し訳ないけど無料で見れるデータだけしか使ってません:p
[世界のジニ係数 国別ランキング・推移](https://www.globalnote.jp/post-12038.html)
![SS 2020-02-10 7.12.28.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79389/3c717cff-90a8-8fd9-aefb-f64b86d28702.jpeg)
日本は0.34。ジニ係数が低いのは安定路線の北欧諸国で、中国・米国・南米など経済成長率が高い国がジニ係数が高い傾向がありそうです。

###(3)OECDデータ

Global Noteには元データ取得先がOECDとだけ記載されているので、OECDデータを調べてそれっぽいのを探してみます。これかなぁ〜。
[Income inequality](https://data.oecd.org/inequality/income-inequality.htm)
![SS 2020-02-10 7.25.40.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79389/65179f80-4001-c1d7-5d7e-9881333eaaa7.jpeg)

このサイトとても便利そうです。日本や米国の経年変動はあまり見れませんが、電子国家として急速に社会インフラのIT化が進んだEstoniaは急激にジニ係数が下がっているようです。
![SS 2020-02-10 7.33.50.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/79389/3b56b2ec-2e8c-24e1-faf5-1f993b7ea5c2.jpeg)

###(3)おまけ
ローレンツ曲線とジニ計数化についてはWikipediaをはじめ、いろんなサイトで判りやすい説明がありました。
[Wiki ジニ係数](https://ja.wikipedia.org/wiki/%E3%82%B8%E3%83%8B%E4%BF%82%E6%95%B0)
[5分でわかるジニ係数](https://vicryptopix.com/gini/)
[所得格差を測る指標－ジニ係数とローレンツ曲線－](http://www.pref.toyama.jp/sections/1015/ecm/back/2005apr/shihyo/)

## 3.総合問題は面白いかも！

総合問題の答えは、[東京大学のデータサイエンティスト養成講座](https://www.amazon.co.jp/dp/4839965250/)のAppendix.2にのっています。Pythonコードの勉強に役立ちそうです（まだやってないけど)
こちらは引用しませんので、各自で頑張りましょう:smile:

残念ながら次回2月29日は先約があって参加できないのですが、本シリーズはPyCPAに合わせて書きたいな、と思っています。
[Pythonデータサイエンス実践講座 第3回 Powered by PyCPA](https://pycpa.connpass.com/event/166742/)

第４回に期待します！！
Ruby + Mustache で Hello World

## 概要

- Ruby の mustache パッケージを使ってテンプレートを処理する
- 今回の環境: macOS Catalina + Ruby 2.7.0 + mustache 1.1.1

## mustache パッケージのインストール

```
$ gem install mustache
```

## Hello World

シンプルなサンプルコードを示す。

```rb
require 'mustache'

# 第一引数にテンプレート文字列
# 第二引数にHashオブジェクト
hello = Mustache.new.render('Hello, {{planet}}.', {planet: 'world'})
puts hello
```

実行結果。

```
Hello, world.
```

## HTML テンプレートファイルを読み込んで値を埋め込む

HTML を記述したテンプレートファイルを用意。
今回は my-template-file.mustache というファイル名で保存する。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- title を出力-->
<title>{{title}}</title>
</head>
<body>

<!-- mydata オブジェクトの message を出力-->
<p>{{mydata.message}}</p>

<p>
<!-- ループ -->
{{#mydata}}
  {{#list}}
    {{.}}<br>
  {{/list}}
{{/mydata}}
</p>

<p>
<!-- hoge が存在する場合に出力-->
{{#mydata.hoge}}
  Hoge exists.
{{/mydata.hoge}}
</p>

<p>
<!-- fuga が存在しない場合に出力-->
{{^mydata.fuga}}
  Fuga does not exists.
{{/mydata.fuga}}
</p>

</body>
</html>
```

ソースコード。

```rb
require 'mustache'

# 第一引数にテンプレートファイル名
# 第二引数にHashオブジェクト
output = Mustache.render_file(
  'my-template-file',
  {
    :title => 'タイトル',
    :mydata => {
      :message => 'メッセージ',
      'list' => ['foo', 'bar', 'baz'],
      'hoge' => 'ほげ'
    }
  })
puts output
```

実行結果。

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<!-- title を出力-->
<title>タイトル</title>
</head>
<body>

<!-- mydata オブジェクトの message を出力-->
<p>メッセージ</p>

<p>
<!-- ループ -->
    foo<br>
    bar<br>
    baz<br>
</p>

<p>
<!-- hoge が存在する場合に出力-->
  Hoge exists.
</p>

<p>
<!-- fuga が存在しない場合に出力-->
  Fuga does not exists.
</p>

</body>
</html>
```

## 参考資料
- [mustache \| RubyGems\.org \| コミュニティのGemホスティングサービス](https://rubygems.org/gems/mustache/)
- [mustache/mustache: Logic\-less Ruby templates\.](https://github.com/mustache/mustache)
- [mustache\(5\) \- Logic\-less templates\.](http://mustache.github.io/mustache.5.html)
- [Class: Mustache — Documentation for mustache \(1\.1\.1\)](https://www.rubydoc.info/gems/mustache/Mustache)
AWS Cloud9作成時のEC2へssh接続してみる

## Cloud9つかってますか？僕はたまにです。
世はまさに大Cloud時代。
ってなわけで、クラウドで開発環境構築するのが今後は普通になっていくのかなと。
そこで、AWSのCloud9をつかってサクッと使ってみた。
~~全然つながらない~~たまーに繋がらないなどのトラブルがあるものの、ひとまずは使えています。
でも、IDEなんて自分が使いやすいやつ使えばでいいじゃん。
ってなった時のためにローカルのIDEでも操作できたらなお良し。(結局ローカルが好き)

## 本題にうつります
これ、 Cloud9で作成したEC２にsshしたいときってどうすんのかなーと。
鍵は？
鍵は何処？
Cloud9あればいいのか？
ローカルではやるなと？
いや、そういうわけじゃないだろ。と思ったので
やれるようにするまでにを書いていきます。

##今回のゴール
Cloud9作成時に新規作成したEC2へssh接続して幸せになる。

## キーペア作り
まずはキーペアを作ります。
EC2コンソールの左側ペインから「キーペア」を選択し、
「Create Key Pair」を選択
<img width="900" alt="2020-02-10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493685/b58fafc2-cee4-1fc3-6eb7-12540e4d6bf9.png">


次にKeyの名前と鍵の形式を選びます。
ここでは名前をhoge、形式はpemを選択します。
最後に「Create Key Pair」を選択。
<img width="883" alt="2020-02-10 (3).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493685/4306638b-b437-bb8e-3d93-49a8b03d2286.png">

すると勝手にキーがDLされます。（矢印のとこ）
リストにも追加されています。
<img width="894" alt="2020-02-10 (4).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493685/e48d414d-9726-eca7-de3a-4d955376f9b1.png">

DLされたキーをわかりやすい場所（僕はデスクトップにしました）に移動させておき、bashを立ち上げます。（Windowsなので）
立ち上げたら以下の図の流れで入力。
要するに、DLしたキーのフルパスを```ssh-keygen -y```の入力後にコピペしてあげる。
ずらずら長ったらしい文字がいわゆる公開鍵っすね。

**ここに載せてるんで、もちろんこのインスタンスも鍵も削除済みです。**
<img width="900" alt="2020-02-10 (5).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493685/c02e51e4-d56c-5c68-536d-499624a5e328.png">

ローカル作業はひとまずここで終わり

## Cloud9に公開鍵をコピペ
Cloud9を立ち上げます。
Cloud9のターミナルに以下を入力しましょう。
```vim ~/.ssh/authorized_keys```

ひらくとすでになんか鍵っぽいのが書いてありますが、２行くらい開けてさっきの公開鍵を貼り付けてください。
貼り付けたら保存して閉じてください。
Cloud9側はこれで終了。
<img width="894" alt="2020-02-10 (6).png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/493685/1a3a4a39-801a-1715-2afa-089b9391b6a0.png">

## 後はssh接続で検証
```ssh -i (pemファイルのフルパス) ec2-user@(パブリックIPかDNS)```
※実際は（）不要です。
はい。無事には入れたら終了です。
入れなかった方は、EC2のセキュリティグループの確認をしてみましょう。
（僕はたいていここの設定忘れでつながらないパターンです）

## 終わり
ここまでやったけど認証鍵に躓きまくった俺にはまぁまぁつらかった。
AWSはまだまだ奥が深い。
IDとコードの話

データベースを扱っていると ID とコードがよく登場します。でも結構混同されてるような気がします。というか、実際今まで混同したデータベースもいくつも見てきました。以下、厳密な話ではなく、あくまでも経験に基づく ID とコードの話をいくつか書き出してみます。

## 定義

とりあえず e-Words の定義を参照してみます。

[ID  【 identification 】 ](http://e-words.jp/w/ID.html)

> IDとは、識別、鑑別、同定、特定、身元確認、身分証明、身分証明書などの意味を持つ英単語。複数の同種の対象から特定の一つを識別、同定することや、そのような識別に用いられる名前や符号、数字、また、それらを記した文書やカードなどのことをIDという。

> 一般的には人物の特定に用いられる一意の識別番号などのことや、身分や身元を証明する書類やカード、標識などのことを指す場合が多い。ITの分野では利用者、登録者を識別するユーザー名やアカウント名などのことをIDと呼ぶことが多い。

> また、人物に限らず、データやプログラム、機器や装置、また、それらの集合や構成要素など、コンピュータシステムの取り扱う様々な対象をそれぞれ一意に識別するための名前や符号、数字などのこともIDという。そのようなコンピュータにおける識別符号などを意味する場合はIDを “identifier” （識別子）の略とすることが多い。

[コード  【 code 】 ](http://e-words.jp/w/%E3%82%B3%E3%83%BC%E3%83%89.html)

> コードとは、法典、規定、規約、記号、符号（化する）、暗号（化する）、などの意味を持つ英単語。

> 一般の外来語としては「ドレスコード」のように規約や規定を指す用法が多いが、ITの分野では「文字コード」のように規約によって定められた識別番号や識別符号などを指すことが多い。

> 情報システム上で対象の識別などに用いられるコードは短く一意（他と重複しない）であることが求められ、通し番号のように名前や意味とは無関係に機械的に割り当てられることが多い。

ID もコードも識別のために用いられることは変わりませんが、コードは「規約によって定められた」とあるのが大きな違いかなと思います。

個人的な経験に基づく ID とコードの違いは以下になります。

* ID
  - システムが自動採番する。MySQL でいうところの auto_increment なカラム。数値自体に意味はない。
  - UUID や Message-ID などもこちらなので、数値とは限らない。
  - ID に対応するデータが必ず存在する。
  - ID に対応するデータは一つだけ（2020.8.11追記)
  - 一般にシステム内に閉じて使用される。
* コード
  - 人がある程度の意図をもって採番する。1:男、2:女、9:その他 のように。数値に意味はないことが多いが、意味があることもある。
  - M:明治、T:大正、S:昭和、H:平成、R:令和のように、こちらも文字の場合もある。
  - コードに対応するデータが存在するとは限らない。
  - コードに対応するデータは複数存在しうる（2020.8.11追記)
  - コード体系を外部に公開することもある。郵便番号や電話番号のように、システム内部では ID で、外部提供する場合はコードとなる場合もある。

## 混ぜるな危険

混ぜるなといってもIDかコードのどちらかしか使うなというわけではありません。それぞれ必要な目的があるので、両方とも使っても大丈夫です。まずいのは、その区別が付いてなくて混同して使用される場合です。

よくあるのは、

```sql
create table users (
  id integer,
  :
);
create table items (
  user_code integer,
  :
);
```
なんてなっている場合です。ユーザIDなのかユーザコードなのか、どっちやねんってわけです。もちろん逆もあります。

```sql
create table genders
  code integer,
  :
);
create table persons
  gender_id integer,
  :
);
```
とかです。こうしてみると冗談のようであり得ないように思いますが、実際の現場ではよく見かけます。

また、外部から提供されるコードを格納する場合はさらにカオスになりやすい気がします。例えば郵便番号を格納する場合に、

```sql
create table companies (
  zipcode char(7),
  :
);
create table members (
  zipid integer,
  :
);
create table addresses (
  zip_num integer,
  :
);
```
とかなってると、混乱すること必至です。テーブルを追加する都度、その時の思い付きだけでカラム名を決めているとこうなってしまいますね。何でもかんでも規約を作るのも窮屈ですが、ある程度大きなシステムならば規約で縛っておくのも必要なのでしょうか。

## 型は合わせて欲しい

先ほどの郵便番号の例では、char型とinteger型に型が分かれていました。MySQLの場合は型が違ってもキャストして比較してくれるので、こんなテーブル設計でもそれなりに動いてしまったりするのですが、やっぱり気持ち悪いです。

## ゼロ詰めするか

これはID/コードに限った話ではないのですが、数値を文字列型に格納する場合にゼロ詰めするかどうかはテーブル設計の段階で決めておいて欲しいです。あるテーブルではゼロ詰めし、あるテーブルではゼロ詰めをしない。それでもやっぱりMySQLでは数値にキャストすればうまく動いてしまったりするわけですが、これまたとてつもなく気持ち悪いです。

## コードの定義場所

コードの場合はコード定義をどこでするかって問題があります。アプリ側に定数で定義してもいいんですが、データベースを参照するアプリは一つとは限らないので、その全てのアプリに定数定義するのも面倒ですし、コード追加時の同期をとるのも大変。なのでデータベース内にコード定義テーブルを持っているのが個人的な好みです。アプリとデータベースの寿命の不一致ってのもありますし。

## 外部制約

ID は当然外部制約かけるとして、コードはどうするか。外部成約をかけたほうがいいのは間違いないんですが、外部から提供されるコードの場合、コードが削除される場合があると困りますよね。そういう場合は、コードの更新時に不整合が起きないようにデータを修正する処理も作り込まないといけません。
レビュワーの指摘の価値を上げるほんのちょっとした工夫

## レビューとは

システム開発ではレビューはソースコードだけでなく、
要件定義、設計、ソースコード、試験計画、試験項目など、幅広く行われています。

レビューは品質を向上させるために行われるため、
文言の「てにをは」や、表記ゆれの指摘よりも、
システム利用者への不都合が起きる問題・リスクへの指摘のほうが価値が高いといえます。

では、どうすればレビュワーは価値の高い指摘ができるようになるでしょうか？

## レビュー価値の向上のためにどうするか

成果物に対する深い知識・経験は必要です。
要件定義でいえば、システムが利用されるビジネスおよび利用者に対する
深い知識と経験がなければ、価値のある指摘は難しいでしょう。

しかし、年々システムは短納期化・複雑化し、人手不足はますます解決困難になり、
レビュワーの熟練を待てる状況にはありません。

## 手持ちの駒ですこしでもレビュー指摘価値を上げる方法

そんな状況下でレビューの指摘価値を上げる、
ほんのちょっとした工夫なんてあるのでしょうか？

あります。ソフトウェア品質特性の活用です。

### ソフトウェア品質特性

ソフトウェア品質特性（ISO/IEC 9126）とは、ソフトウェア品質の評価に関する**国際規格**です。
品質を6つの主特性と、その下に合計27の副特性に細分化・モデル化した規格です。

[ウェブレッジさんのWEBページ](https://webrage.jp/techblog/external_quality_inner_quality/)が非常によくまとまっていますし、
図式は秀逸です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138414/1a957bee-200f-03f9-7223-1cc646878904.png)

ソフトウェアの品質は上記の27の副特性で評価することができます。
例えば、バグがあるか・ないかというのは、**正確性**の評価になります。

バグがなくても、使い勝手が悪ければソフトウェアの質が悪いという評価されますが、
それは**使用性**が低いという評価になります。

システムによっては障害が起きても何とか動き続けることが求められるなら、
**障害許容性**で評価しないといけません。

クレジットカードの決済機能を有しているなら、
クレジットカード会社の規約、経済産業省の省令に従っているかを評価しないと、
ルール違反のシステムをリリースすることになってしまいます。
これは**基準適合性**という品質特性になります。

レビューというのは、煎じ詰めると「これで良い／悪い」を判定することですが、
全体的にざっくりばっくり「良い／悪い」を判定してしまうと、
どうしても大事な部分が漏れてしまい、後工程やリリース後で問題を発生させてしまいます。

### どう活用するのか

* レビュー前に、対象成果物がどの品質特性を重視するのか確認する
    * システムによっては、不正確であっても応答速度が求められる場合などがあるため、  
      対象成果物ごとに、どの品質特性でレビューするか選別する
    * 全部の品質副特性でレビューしたほうがいいのはやまやまだが、  
      時間は有限なので３～７に絞る。  
      またじっくり見る特性とさらっと見る特性など、濃淡をつける
* 選別した品質特性で一つずつレビューをする
* というか成果物作成前に、作業者とレビュワーとで選別・濃淡を決定しておき  
  品質**チェック**ではなく、品質**作りこみ**が行われるよう誘導する

### どうなるか

メンバのレビューに対する感想が、
「レビューめんどくさい、うるさい」
から
「なるほどね。力入れる箇所がわかっていいものが作れるようになるわ」
に変わる

レビュー嫌いのエンジニアのみなさんもたくさんいらっしゃると思いますが、
エンジニアのみなさんって、基本的に、よりいいものを作りたいという欲求を持っています。
価値のあるレビュー指摘は、システム価値の向上のみならず、
エンジニアのみなさんの精神衛生にとっても大きな効果があります。

## 想定される質問・反論への回答

* 例えば「障害許容性」で、何をどう見ればいいの？
    * 多少の解説はできますが、本稿の趣旨とはずれるので割愛します。
    * 本稿では、ほんのちょっとの工夫で、**相対的に**今より改善する漸進の提案です。
    * 何をどう見ればいいかよくわからない人でも、「障害許容性」に視野を限定すれば、
      そうでないときに比べてより相対的に良い指摘ができるようになります。
* 結局人頼みじゃん
    * そうです。結局、具体的に価値のある指摘をするのは個々の人間の創造性です。
    * 自動化、定型化を進めても、最後には人間の創造性を発揮する余地が残る。それでいいじゃないですか。
    * そしてこの提案はすべてを最終解決させる案ではなく、ちょっと改善する工夫の位置づけです。
* そういう指摘って蓄積していつでも参照できるようにしとけよ、いちいちレビューするな・させるな
    * 私もそう思って蓄積を試みたのですが、「対象システムごとに重要な観点が異なる」
   「それを全部記載すると重厚な基準書になり使わなく・使えなくなる」と断念しました。
    * ただ、私の判断が間違っている可能性もあるので、ぜひ試してみてください。
* そもそもこれらは、レビュワーが決めることじゃなくて要件定義で決めることでしょ？
    * そこに気づくとはさすがです！
    * 私はこれを要件定義の定義カテゴリとしても使っています。
    * 要件定義の内容は工程が下るごとに、成果物への反映が薄れてしまうので、  
    各成果物の作成前で再確認する、作成後チェックするというのは、  
    少なくとも自分の現場では必要でした。
Mac Catalina（10.15.3）のTerminal環境設定

#MacOS CatalinaのTerminal 初期読み込みファイルは`~/.zshenv`
MacOSのCatalinaでTerminal起動時のAlias設定読み込みで、ちょっとつまづいてしまったので、備忘の意味も込めて投稿しておきます。（ネットで探していたのですが、ちょっと苦労した。。）

以前のバージョン（どこまでのバージョンまでかは調べていないです）では、`~/.bash_profile`に`~/.bashrc`を読み込む設定にすればよかったようですが、Catalinaは`~/.zshenv`に`~/.bash_profile`と同じ設定を書き込んでおく必要がありました。

```~/.bashrc
alias ll='ls -al'
```

```~/.zshenv
if [ -f ~/.bashrc ] ; then
	. ~/.bashrc
fi
```

これでTerminalを起動し直せば、`ll`で`ls -la`の結果を表示できます。

```
hoge@hoge-Mac ~ % ll
total 50
drwxr-xr-x+  36 hoge  staff   1152 Feb  9 16:26 .
-rw-rw-rw-    1 hoge  staff    402 Feb  4 05:38 .%5091FFA9.png
drwxr-xr-x    6 root          admin    192 Feb  4 05:38 ..
-rw-------    1 hoge  staff    208 Feb  9 14:19 .bash_history
-rw-r--r--    1 hoge  staff     62 Feb  9 09:58 .bash_profile
drwx------    9 hoge  staff    288 Feb  9 14:19 .bash_sessions
-rw-r--r--    1 hoge  staff     91 Feb  9 10:01 .bashrc
-rw-------    1 hoge  staff   7184 Feb  9 14:37 .zsh_history
-rw-r--r--    1 hoge  staff     62 Feb  9 14:19 .zshenv
drwx------@   3 hoge  staff     96 Feb  1 08:13 Applications
drwx------@   7 hoge  staff    224 Feb  9 16:40 Desktop
drwx------@   7 hoge  staff    224 Feb  9 16:49 Documents
drwx------@  15 hoge  staff    480 Feb  9 16:42 Downloads
drwx------@  65 hoge  staff   2080 Feb  6 06:17 Library
drwx------+   4 hoge  staff    128 Feb  1 20:14 Movies
drwx------+   4 hoge  staff    128 Feb  5 22:50 Music
drwx------+   5 hoge  staff    160 Feb  9 14:36 Pictures
drwxr-xr-x+   4 hoge  staff    128 Feb  1 08:06 Public
drwxr-xr-x   47 hoge  staff   1504 Feb  9 16:26 scriptlogs
.........
```

この設定だけで1時間以上、迷子になっていました。。。
I got lost...
【Rails】Railsに保存した画像ファイルをVue.js側で表示するサンプルコード（Base64、Active Storage使用）

## はじめに
**Rails APIモード→Vue.js**での画像データのやりとりをする方法を残します。（**Base64、Active Storage**使用）

### 今回の対象
:x: Vue.js→Rails([こちらの記事](https://qiita.com/tabakazu/items/5489632c534c56db6a4d)をご参照下さい。引用失礼します！)
:o: **Rails→Vue.js** ←ココ

## 環境
```yaml
OS: macOS Catalina 10.15.3
Ruby: 2.6.5
Rails: 6.0.2.1
Vue: 2.6.10
axios: 0.19.0
```
## 前提:実施済とみなすこと
※[引用記事](https://qiita.com/tabakazu/items/5489632c534c56db6a4d)の例を使用します。

- `rails new`
- **Active Storage**のインストール
- `Post`モデルの作成
- **Vue.js**のインストールと利用するための準備
- `eyecatch`として画像ファイルが`Post`モデルのインスタンスに添付されている
- **(今ココ)**

## 1.【Rails】画像ファイルをBase64形式でエンコードするメソッドを定義する

```ruby:posts_controller.rb
  # 各モデルのレコードに添付された画像ファイルをBase64でエンコードする
  def encode_base64(image_file)
    image = Base64.encode64(image_file.download) # 画像ファイルをActive Storageでダウンロードし、エンコードする
    blob = ActiveStorage::Blob.find(image_file[:id]) # Blobを作成
    "data:#{blob[:content_type]};base64,#{image}" # Vue側でそのまま画像として読み込み出来るBase64文字列にして返す
  end
```

## 2.【Rails】Active Storageでアタッチした画像ファイルを読み込み
`posts#show`で投稿データを返すとします。

```ruby:posts_controller.rb
  def show
    post = Post.find(params[:id]).as_json #JSON形式にしておく

    eyecatch = post.eyecatch #eyecatchは添付した画像ファイル

    if eyecatch.present?
      post['image'] = encode_base64(eyecatch) # 画像ファイルを1.で定義したメソッドでBase64エンコードし、renderするデータに追加する
    end

    render json: post
  end
```

## 3.【Rails】ルーティングを設定

```ruby
Rails.application.routes.draw do
# 略
  get 'posts', to: 'posts#show'
# 略
end
```

## 4.【Vue.js】画像を取得し、表示するコンポーネントを作成

```vue:show.vue
<template>
  <div>
    <p>投稿表示フォーム</p>

      <!-- preventでsetPost()メソッドがページ遷移なく発火する -->
    <form v-on:submit.prevent="setPost()">
      <p>
        <label>Title</label>
        <input name="post.title" type="text" v-model="post.title"><br />
      </p>
      <p>
        <label>Body</label>
        <input name="post.body" type="text" v-model="post.body"><br />
      </p>

      <!-- post.idを指定して... -->
      <p>
        <label>IDを指定</label>
        <input name="post.id" type="text" v-model="post.id">
      </p>

      <!-- ここを押してデータ取得 -->
      <input type="submit" value="ここを押して投稿データ取得" >
      
      <!-- Base64形式であればimgタグでそのまま読み込みが可能 -->
      <img :src="post.image" alt="post.image">
    </form>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  name: 'sample',
  data() {
    return {
      post: {},
    }
  },
  methods: {
    setPost() {
      axios.get('/posts', {params: {id: this.post.id}}) //入力したidに応じてpostが返ってくる
      .then(response => {
        this.post = response.data 
      })
      .catch( error => {
        console.error(error)
      })
    }

  }
}
</script>
```

※実際は自分で`id`を指定することはないと思いますので、状況に応じて変更して頂ければと思います。

以上です！

## おわりに
最後まで読んで頂きありがとうございました:bow_tone1:

どなたかの参考になれば幸いです:relaxed:

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [Vue on RailsでActive Storageを使って画像を保存する - Qiita](https://qiita.com/tabakazu/items/5489632c534c56db6a4d)
時間変化をベクトルタイルで扱うアイディア２つ

[halsk/pharmacies-tiles](https://github.com/halsk/pharmacies-tiles/issues/7) 関連のメモ書きなのですが、時間変化をベクトルタイルで扱うアイディアには二つあると思います。

# 一斉書き換えなら {T}/{z}/{x}/{y}
{T}は丸めた時間になると思います。日でも時でも分でも大丈夫ですが、一斉書き換えを行なったそのタイミングを一意かつわかりやすく示す識別子。

データを一斉に書き出すごとに {T} という別のディレクトリに書き出すことにして、書き出した方をみて欲しくなったタイミングで、それを呼び出す index.html なり style.json の側を書き換える。

必要に応じて、その index.html なり style.json なりがキャッシュがかりしない施策を講じる。

# 逐次書き換えなら {z}/{x}/{y}.{T}
一斉書き換えではなくて、タイルごとに不定期に書き換えられるのであれば、多分 {y} と拡張子の間にタイムスタンプを書き込んで分ける。

{x}/{z}/{y} は、最新 T のタイルへのシンボリックリンクにする。{z}/{x}/{y}.{T} の書き込み時に {z}/{x}/{y} の指示先を書き換えるようにしておけば良いし、タイルごとの履歴を撮りたければ、要は `ls {z}/{x}/{y}*` 相当の検索をかければ良い。

# （追記）時変部分のみ別ファイル
幾何属性はもう安定していて変化がなく、主題属性のみ時変するというパターンの場合には、ベクトルタイルには地物の ID を持たせておき、主題属性を必要とするときになってから別途 GET するというパターンもあると思います。個人的には、このやり方を「増槽方式」とか「ペイロード分離方式」と呼んでいます。
PythonでABC154-E(桁DP)

#問題
ABC154-Eを理解して見せる！
#総数
まず、桁DPを用いてN以下の数の総数を求める。
314159について考えてみる。
例えば、313まで決まっていると、それより下はどんな数字でも許される。
一方、314という決まり方をすると、1個下は0か1しか許されない。
すなわち、どの桁までを決めるのかと、その決め方でN未満が確定するのかという情報が必要だ。
**dp[i][j]: i桁目までを決めて、N未満で確定ならj=1、Nと一致しているならばj=0**
と定める。 
初期値は、0桁目までを使ってこの時点ではNと一致しているので
**dp[0][0] = 1**
とする。
その後、桁数を増やしていくが、次の桁について、Nと一致している個数は常に1(1つ前と同じ)、N未満の個数は、1つ前のN未満確定のものに0~9の10をかけたものと1つ前のNに等しいものに0~その桁の数-1をかけたものになるので、漸化式は以下。
**dp[i][0] = dp[i - 1][0]**
**dp[i][1] = dp[i - 1][1] * 10 + dp[i - 1][0] * int(str(N)[i - 1])**
##コード
```.py
N = input()
m = len(N)
dp = [[0] * 2 for _ in range(m + 1)]
dp[0][0] = 1

for i in range(1, m + 1):
    dp[i][0] = dp[i - 1][0]
    dp[i][1] = dp[i - 1][1] * 10 + dp[i - 1][0] * int(N[i - 1])

ans = dp[m][0] + dp[m][1]

print(ans)
```
#0でない数をK個含むN以下の数の総数
**dp[i][j][k]: 0でない数をk個含むという条件追加**
i桁目の数をlとして、
**dp[i][0][k] = dp[i - 1][0][k] * (l == 0),dp[i - 1][0][k - 1] * (l != 0)**
**dp[i][1][k] = dp[i - 1][1][k] + dp[i - 1][1][k - 1] * 9 + dp[i - 1][0][k] * 1 * (l != 0) + dp[i - 1][0][k - 1] * (l - 1) * (l != 0)**
になると思うんですが無駄がありそうなので教えてください><

###考え方
dp[i][0][k]:lが0だった場合には与えられた数と一致させるにはkはそのままになるのでdp[i -1][0][k]となり、そうでないときには0でない数が1つ増えるのでdp[i - 1][0][k - 1]。

dp[i][1][k]:まず、dp[i - 1][1][k]から次の桁が0でないもの1つ、dp[i - 1][1][k - 1]から次の桁が1~9の9つが遷移してくる。次に、lが0でなければ、次の桁を0としたdp[i - 1][0][k]が、また次の桁が1~(l - 1)となるdp[i - 1][0][k - 1]がl - 1個遷移してくる。
(わかりづら杉)
##コード
```.py
N = input()
K = int(input())
m = len(N)
dp = [[[0] * (K + 1) for _ in range(2)] for _ in range(m + 1)]
dp[0][0][0] = 1

for i in range(1, m + 1):
    l = int(N[i - 1])
    for k in range(K + 1):
        dp[i][1][k] += dp[i - 1][1][k]
        if l != 0:
            dp[i][1][k] += dp[i - 1][0][k]
        else:
            dp[i][0][k] += dp[i - 1][0][k]
        if k - 1 >= 0:
            dp[i][1][k] += 9 * dp[i - 1][1][k - 1]
            if l != 0:
                dp[i][0][k] += dp[i - 1][0][k - 1]
                dp[i][1][k] += (l - 1) * dp[i - 1][0][k - 1]

print(dp[m][0][K] + dp[m][1][K])
```
#あとがき
アドバイスお願いします。。。。
質問も答えられる範囲で答えるつもりですが。。。。

#参考文献
[桁DP入門](https://web.archive.org/web/20170508234139/https://pekempey.hatenablog.com/entry/2015/12/09/000603)
Seabornのpairplot関数の結果グラフをGoogle ColaboratoryからGoogle driveにアップロードする方法

## この記事でできること
表題の通りです。sklearnの関数で取得できる[UCI Machine Learning Repositoryのwineデータセット](https://archive.ics.uci.edu/ml/datasets/Wine)を利用します
## 手順
1. ColaboratoryにGoogle Driveのアクセス権限を与える
2. Google Driveにファイルの出力をする  
**手順2までにはpairplot用のDataFrameを定義しておきましょう**

# 詳しく
## 1. wineデータセットの読み込み
 学習に使用することになりそうですし、DataFrameを学習データ(X_train)で作成するのでデータ分割もしています

```python

from sklearn.datasets import load_wine
wine_dataset = load_wine()

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(
        wine_dataset['data'], wine_dataset['target'],
        test_size=0.3, random_state=0)
```

## 2. DataFrameの作成

```python

wine_df = pd.DataFrame(X_train, columns=wine_dataset.feature_names)
wine_df['species'] = y_train
wine_df.head()
```

出力結果はこうなります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448316/298c4647-1bb7-4a5a-3c9f-013f408476cb.png)

## 3. ColaboratoryにGoogle Driveのアクセス権限を与える

```python

from pydrive.auth import GoogleAuth
from pydrive.drive import GoogleDrive
from google.colab import auth
from oauth2client.client import GoogleCredentials

auth.authenticate_user()
gauth = GoogleAuth()
gauth.credentials = GoogleCredentials.get_application_default()
drive = GoogleDrive(gauth)
```
**リンクと入力欄が出力されます。そのリンクを踏んでGoogleアカウントでログインして出てきた文字列をコピーして、Google Colaboratoryに戻ってきて入力欄にペーストしてエンター**

## 4. seabornでpairplotを作成し、pngとして保存しておく

```python

import seaborn as sns
sns.pairplot(wine_df, hue='species').savefig('wine_pairplot_hue.png')
```
**このままだとColaboratoryのローカル（Google DriveのColab Notebooksからも見れない）にあるので、Google Driveへのアップロードが必要になります。**

## 5. Google Driveに出力

```python

upload_file_2 = drive.CreateFile()
upload_file_2.SetContentFile("wine_pairplot_hue.png")
upload_file_2.Upload()
```

## 6. 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448316/85f2c5e9-1d70-ec08-42ab-273936c97bdd.png)

ちゃんと登録できてます。ちなみにワインデータセットくらい特徴量があると画質の影響で文字が見えなくなるので他の対処が必要そうです。(Colaboratory上でもプロットされます。こちらはズーム可能)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448316/fbc390d2-dfd0-a136-4b40-784b05ecd3f8.png)


以上です
既存オブジェクトにプロパティを追加してもリアクティブにならない時の対処



<p class="codepen" data-height="1000" data-theme-id="default" data-default-tab="result" data-user="mykysyk" data-slug-hash="ZEGzdMw" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="既存オブジェクトにリアクティブなプロパティを追加するテスト">
  <span>See the Pen <a href="https://codepen.io/mykysyk/pen/ZEGzdMw">
  既存オブジェクトにリアクティブなプロパティを追加するテスト</a> by mykysyk (<a href="https://codepen.io/mykysyk">@mykysyk</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
【UE4】LevelSequenceでTrackとして追加されているActorのインスタンスを取得してイベントを呼び出す【UnrealEngine4】

# はじめに
開発をしていてLevelSequence経由で発生させたいイベントがあり、LevelSequenceにBindされているActorの関数を呼び出そうと思ったら、SequenceDirector内でどうやってインスタンスを取得するのか調べてもわかりませんでした
Additional Event Receiversを使いたいのに、どこのサイトも「実際にレベルに配置する」のが前提で書かれており、Additional Event Receiversはレベルに配置しないと設定できないように思えたので動的に再生するLSを切り替えるケースではどうすればいいのかわかりませんでした
色々試していたらできたのでその手順をまとめておきます
もっといいスマートな方法があったら教えてください

# 環境
UE4.23.1
VisualStudioCommunity2017
Windows10

#事前準備するもの
LevelSequenceを用意する
呼び出したい自作のBP公開されている関数を持つC++クラスを継承したBPクラス
今回用意したクラスはこちら

```c++:MyActor.h
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "MyActor.generated.h"

UCLASS()
class IMGUI_PRJ_API AMyActor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AMyActor();
public:
	UFUNCTION(BlueprintCallable, Category = "Test Actor")
	void TestFunction();

	UFUNCTION(BlueprintCallable, Category = "Test Actor")
	void BoolFunction(bool hoge);

};


```

```C++:MyActor.cpp
#include "MyActor.h"
void AMyActor::TestFunction()
{
	GLog->Log("TestFunction");
}

void AMyActor::BoolFunction(bool hoge)
{
	GLog->Log("BoolFunction");
}

```


# 手順
### 1. LevelSequenceを開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/0871988f-8964-a2d3-2522-0ba820f5ec1b.png)
※レベルに配置されてないのでDetailウィンドウにはなにも表示されません

### 2. 「Track > Actor to Sequence」からBP_MyActorを追加する
![sequence1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/376d6391-046b-577b-cce4-b6d7f64f4b58.png)

### 3. BP_MyActorの下にEventトラックを追加する
![sequence2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/35ed89d7-2647-6167-6c88-f4c89b34fd7c.png)

### 4. 追加したEventトラックを右クリックしてプロパティからBP_MyActorをEvent Receiversに登録する
![sequence3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/bb159dd2-d37d-31c5-2974-b17ca75c968a.png)

### 5. キーを作成し、キーを右クリックからCreateQuickBindingからBP公開されているイベントを呼ぶ
![sequence4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/ca5792d0-c7e8-1e36-47c7-e2a3b5658ae9.png)

#### <font color=red>5-2. BP_MyActorの下につけてないEventトラックではEvent Receiversに登録してもCreateQuickBindingが出てこないので注意</font color>
![sequence5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/d5cd5f5a-ac5d-7052-33d8-26c74d0c7c84.png)

### 6. 追加すると確認LevelSequenceDirectorが開き、BP_MyActorのインスタンスを引数で持ってこれているのが確認できる(完)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/f38993b9-10f1-d165-9076-092ad195df26.png)

####<font color=red>6-2. LevelSequenceから呼ぶイベントにtarget以外の引数を増やしたらイベントそのものが無効になるので注意</font color>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/0f863643-1af8-6d34-8332-303106f69b0e.png)
![sequence6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/138731/c1169ba5-1384-a1ce-5428-a8ff7ce0eaa8.png)


#さいごに
ざっくりまとめました
これややこしくない？これ以外にスマートな方法がある気がしてならないんですが、誰か教えてくれませんか？
気軽にコメントよろです
mactexにjlistingを導入する

# はじめに
mactexでソースコードを挿入したいそこのあなた！！
jlistingをmacに導入するのちょっと面倒なんです...

# jlisting.styのダウンロード
ますは、[ダウンロード](https://osdn.net/projects/mytexpert/downloads/26068/jlisting.sty.bz2/ "ダウンロード")
ダウンロードしたら解凍してくださいね

# ファイルを置く場所を探して、配置
ターミナルを起動しよう！！
（⌘ + スペースキー）でspotlight「terminal」
面倒なことはありませんよ。

```terminal:terminal(1)
$ kpsewhich listings.sty
```
上のコマンドをターミナルに入力して、既にインストールされているはずのlistings.styの場所を探しましょう。

私の環境の場合、(2)のように表示されました。

```terminal:terminal(2)
$ kpsewhich listings.sty

$ /usr/local/texlive/2019/texmf-dist/tex/latex/listings/listings.sty
```

では、Finderで目的の場所まで行っちゃいましょ〜
（Shift + ⌘ + G）でアドレス指定ができて簡単に移動できます。

listingsフォルダのなかにjlisting.styが保存できたら、あともう少し

```terminal:terminal(3)
$ kpsewhich listings.sty
$ /usr/local/texlive/2019/texmf-dist/tex/latex/listings/listings.sty

$ sudo mktexlsr
```
(3)のように入力して、コピーされたファイルをTeXのスタイルファイルリストに登録します。

# 万が一
読み込み権限がないとか言われたら、(4)の感じで権限付与

```terminal:terminal(4)
$ kpsewhich listings.sty
$ /usr/local/texlive/2019/texmf-dist/tex/latex/listings/listings.sty
$ sudo mktexlsr
mktexlsr: ・・・
mktexlsr: Done.

$ sudo chmod +r /usr/local/texlive/2019/texmf-dist/tex/latex/listings/jlisting.sty
```

# 終わり
楽しいTeX生活を
"the requested PHP extension zip is missing from your system"のエラー解決法

当方Macです。
terminalで以下を入力。

```
pecl install zip
```

これでいけました。

もし `pecl`コマンドがないといわれたら、homebrewでPHPをインストールしてみてください。


```
brew install php@7.4
```

再度、以下を入力

```
pecl install zip
```
N進法を可視化する

#動機
N進法をグレースケールの画像にしたら楽しいのでは？？？

#実装

```python

import numpy as np
import math
from tqdm import tqdm
from PIL import Image
```

xをk桁のN進数に変換してnumpy.arrayで出力
(ex. x=10,n=2,k=8 → 00001010)

```python

def int__n(x,n,k):
    if x>(n**k-1):
#       print("x over maximum\n","x=",x," n**k-1=",n**k-1)
#       print("n=",n," k=",k)
        return np.full(k,n-1)
    else:
        a = x%(n**(k-1))
        b = x//(n**(k-1))
        if k==1:
            return np.array([b])
        else:
            v = int__n(a,n,k-1)
            return np.insert(v,0,b,axis=0)
```

k以下の自然数をint__nに代入して結合

```python

def mk_matrix(k,base):  # k:サイズ base:基数
    c = int(math.log(k,base)+2)
    m = np.full((0,c),0)
    for i in range(k):
        v = int__n(i+1,base,c)
        m = np.insert(m,i,v,axis=0)
    return m
```

numpy.arrayからPIL.Imageに変換（画像化）

```python

def mk_img(x,base):
    M = np.uint8((255/(base-1)*((base-1)-mk_matrix(x,base))))
#   Image.fromarray(M).convert("L").resize((x,x)).show()
    img = Image.fromarray(M).convert("L").resize((x,x))
    img.save("base{base}_for_{x}.png".format(base=base,x=x))
    img.resize((500,500)).save("base{base}_for_{x}_resized_500x500.png".format(base=base,x=x))
```

2~20進法で画像作成

```python

for n in tqdm(range(2,21)):
    mk_img(2000,n)
```

#結果
2進法
![base2_for_2000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205561/e203add9-6473-8074-d120-c2aa0e48a022.png)
5進法
![base5_for_2000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205561/4d5e212a-e7b2-b6e1-90ea-8c35966f4f0b.png)
13進法
![base13_for_2000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205561/293a3d85-8f5b-5654-644e-9117fdd2fde2.png)
20進法
![base20_for_2000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/205561/dfa60833-7e49-1f9a-d703-11bc33412c0d.png)

#感想
まあ、特に楽しいことはないですね、わかってはいましたが。
PILとnumpyの練習にはなったかな…
Project Eular Problem 123を解いてて思ったHaskellの難しさ


[Problem 123](https://projecteuler.net/problem=123)
[日本語訳](http://odz.sakura.ne.jp/projecteuler/index.php?cmd=read&page=Problem%20123)

#注意

この記事はProblem 123の解答を含みます。


# 最初に書いた解答


``` Haskell
import Data.Numbers.Primes  

r n = mod (2 * p * n) (p * p)                                                           
  where                                                                      
    p = primes !! n                                                          
                                                                             
head $ filter (\n -> (r n > 10 ^ 10) && 1 == mod n 2) [1..]  
```

これで解けるはずだが終わらない。
`primes !! n `を用いて素数を取り出している。

# 次に書いた解答

```Haskell
import Data.Numbers.Primes

r p n = mod (2 * p * n) (p * p)

snd $ head $ filter (\(p, n) -> (r p n > 10 ^ 10) && 1 == mod n 2) $ zip primes [1..]
```

これは間に合う。
`primes`を最初から一つずつ取り出している。

# 何が言いたいのか

[Data.Numbers.Primes](http://hackage.haskell.org/package/primes-0.2.1.0/docs/Data-Numbers-Primes.html)でどのような実装で`primes`を作っているのかは知らないが、少なくとも$n$番目の素数を求めておけば、$n+1$番目の素数を求める計算量は少なくなるはずである。
ただ、はじめに書いたコードでは、$n+1$番目の素数を求める際に、すでに計算したはずの$n$番目の素数までを再び計算してるから遅いのだろう。

では、２つ目の解答の場合はどうなのかというと、これはzipを用いて`primes`から一つずつ素数を取り出している。
このときは、$n+1$番目の素数を取り出す際に、$n$番目の素数までの計算を再び行うという無駄なことはせずに、計算出来ているんだと思う。

この違いはどこにあるんだろうか？
また、このような違いをHaskellを書いてる人が意識する必要があるのだろうか？？

# Haskellの難しさ

「Haskell メモ化」で調べるとフィボナッチ数列を例として、コンパイラがどのような条件でメモ化をしているのかを解説する記事や具体的なメモ化の方法が出てくる。([参考](https://qiita.com/ki073/items/0b21786a324fbfb6cc0d))
また、他にも並列化の時などはHaskellの遅延評価がどのようなときにどの式の計算を行うのかをきちんと理解しないといけない。([参考](https://www.amazon.co.jp/dp/4873116899), [参考](https://github.com/shiatsumat/wiwinwlh-jp/wiki/%E9%81%85%E5%BB%B6%E6%80%A7))
Haskellは純粋関数型言語だから関数の定義を書いてるだけで計算が出来る。
ただ、このようにメモ化や計算の順番については、定義を書いてるだけなゆえに意識するのが難しくなっていると思う。
こんなこともわからないお前がザコなんだと言われれば謝るしかないが、難しいことを意識せずに楽しくプログラミング出来ないのかな。
RedisベースのGo Background Jobライブラリー

#　Asynq: RedisベースのGo Background Jobライブラリー

Ruby,Railsのサークルの中ではResqueやSidekiqがBackground-jobのライブラリーで人気ですが、Goのコミュニティーの中でこれといったライブラリーがあまり見つからなかったので自分でSidekiqのデザインを基にしてBackground Jobライブラリーを書いてみました（[github.com/hibiken/asynq](https://github.com/hibiken/asynq)）。

GoやRedisに興味があってGithubでコントリビュートするプロジェクトを探していたら、是非！
ユーザビリティを意識したコーディングまとめ


#ユーザビリティとは
ユーザビリティとは、システムやWebサイトなどの「使いやすさ」「使い勝手の良さ」「ユーザーの満足度」「効率」などの意味のことを言います。

ユーザビリティの優れたWebサイトは、ユーザーが目的とする情報に少ないページ遷移で辿り着けたり、必要な情報を迷うことなく入手できます。

また、ユーザビリティに問題があるWebサイトは、ユーザーもWebサイト訪問の目的を思うように達成できず、ストレスからページ離脱してしまうこともあります。

###＊＊ユーザビリティを左右する5つの要素＊＊
####♦︎学習しやすさ 
システムは、ユーザがそれを使ってすぐ作業を始められるよう、簡単に学習できるようにしなければならない。
####♦︎効率性
 システムは、一度ユーザがそれについて学習すれば、後は高い生産性を上げられるよう、効率的な使用を可能にすべきである。
####♦︎記憶しやすさ
 システムは、不定期利用のユーザがしばらく使わなくても、再び使うときに覚え直さないで使えるよう、覚えやすくしなければならない。
####♦︎エラー
 システムはエラー発生率を低くし、ユーザがシステム使用中にエラーを起こしにくく、もしエラーが発生しても簡単に回復できるようにしなければならない。また、致命的なエラーが起こってはいけない。
####♦︎主観的満足度 
システムは、ユーザが個人的に満足できるよう、また好きになるよう楽しく利用できるようにしなければならない。

（『ユーザビリティエンジニアリング原論』（邦訳は1999年、原著は1994年）より）


###＊＊ユーザビリティのポイント＊＊
#####ユーザビリティを考慮したデザイン
ユーザビリティを決める上でデザインは非常に重要ですが、ホームページ設計そのものや設計思想、サービスの利便性など、さまざまなことが重要です。


・初めてのユーザーが迷わずに操作できるように要素が配置されているか
・ページが素早く表示されてユーザーを待たせないか
・クリックできるリンクの色をほかのWebサイトと統一する
・ボタンはボタンらしく押せるようなデザインにするなど

多くのWebサイトに共通するルールを統一すると、ユーザーが操作に迷うことが少なくなります。

<details><summary>参考サイト</summary>

[アップルとグーグルのガイドラインに学ぶスマホWebデザインの要点] 
 ( https://baigie.me/sogitani/2015/07/apple-google-design-guideline/)
</details>

#####Webサイトがターゲットユーザーに合っているか

ターゲットであるユーザーがWebサイトの情報でニーズを満たし、目的を達成できるかどうかが、ユーザビリティの良し悪しにつながります。ターゲットユーザーの目的をしっかりと理解することが、ユーザビリティを考える際の大切なポイントになります。

###＊＊ユーザビリティチェックリスト＊＊
<details><summary>参考サイト</summary>

[ユーザビリティチェックリスト【累計91項目】](https://www.markeit.jp/blog/usability/)

####デザイン・レイアウト
[・ 伝わるデザイン｜研究発表のユニバーサルデザイン](https://tsutawarudesign.com/)
[・ 見やすい・使いやすいレイアウトの為に考えるべき事。]
(https://basicdesign-note.com/easytoread-layout/)
[・ ウェブページを見る目の動きは「F」パターン – GIGAZINE]
(https://gigazine.net/news/20060419_f_pattern/)

####ナビゲーション
[・ 日本のWebサイトの404ページデザインいろいろ+α – かちびと.net]
(http://kachibito.net/web-design/japanese-404-design.html)

####文章
[・ Web制作における文章の可読性について考える – YATのBLOG]
(https://wp.yat-net.com/?p=3761)
[・ 文章をデザインする – 段落や箇条書きをより読みやすくするために – YATのBLOG]
(https://wp.yat-net.com/?p=3761)
[・ ユーザはウェブをどう読んでいるか – U-Site]
(https://u-site.jp/alertbox/9710a)


####タイトル・見出し
[・ SEOで最も重要なタグを見直そう！1分で誰でもできる！自社サイト簡単SEOチェック方法 | DX.univ]
(http://dx.24-7.co.jp/seo-check-title-meta-description/)

####リンク・ボタン
[・ クリック率・コンバージョン率を高めるボタン。3つの大きなポイント]
(http://creators-manual.com/button_conversion/)

####トップページ
[・ 第6回　サイト価値を最大化するためのトップページ設計術～4パターンの訪問者を想定して作る | Web担当者Forum]
(https://webtan.impress.co.jp/e/2007/08/02/1365)

####導入事例ページ
[・ BtoBサイトで使える事例掲載方法10パターン]
(https://www.markeit.jp/blog/casestudy/)

####価格ページ
[・ 購買意欲をコントロールするサービス・商品の価格一覧表を作成する7つのテクニック | コリス](https://coliss.com/articles/build-websites/architectonics/usability/7-useful-design-strategies-for-a-successful-pricing-table.html)
[・ これで見込み客を逃さない！魅力的な価格表デザインのコツ｜designaholic -Creative Column-]
(http://designaholic.cc/2011/02/post-80.html)

####セミナーページ

[・ 魅力的なセミナーページを作成する9個のポイント]
(https://www.markeit.jp/blog/seminarpage/)

####問い合わせフォーム
[・ これで完璧！EFO(エントリーフォーム最適化)でチェックしたい30個のポイント]
(https://www.markeit.jp/blog/efo/)

####サイト内検索
[・ サイト内検索のキーワードを分析する方法とユーザー行動理解のための6つの指標](https://www.markeit.jp/blog/usability/)

####その他
[・ ページ表示2秒でユーザーはイライラし始め、3分の1が「もういいや」となる | Web担当者Forum]
(https://webtan.impress.co.jp/e/2010/04/27/7848)

</details>
Amazon SESでRule Setが動作しない（送信側で「Requested action not taken: mailbox unavailable」となる）

## 事象

Amazon SESでRule Setが作成してある。
![image.png](https://image.docbase.io/uploads/d30f1c37-d2fb-4717-9ae2-22651abbc5ce.png)

Rule Setの内容。特定のメールアドレスでメールを受信したらアクションを実行するRuleを追加してある。
![image.png](https://image.docbase.io/uploads/a80350cb-e601-4ef0-9e67-29232f9ac506.png)

しかし、別のメールサービスからRule Setで設定したアドレスにメールを送信したところ、`Requested action not taken: mailbox unavailable`エラーとなった。
![image.png](https://image.docbase.io/uploads/20d1de46-9260-49de-b804-4448868c7bda.png)

## 解決

よく見たらRule Setが[Inactive Rule Sets]だった。
![image.png](https://image.docbase.io/uploads/3228c674-d4f0-4fd8-af61-148fa82f8532.png)

利用したいRule SetをActiveにして[Active Rule Set]に指定することによりメールが正常に受信できるようになった。
![image.png](https://image.docbase.io/uploads/9bcbe28b-5163-46ca-a522-9fda3e2cfb4c.png)

以上
catした結果をダブルクォーテーションで囲んで変数に入れる

# コマンド

```shell
test=\"`cat test.json`\"
echo $test
```

## 説明

・バックスラッシュ「`」で囲まれた文字列はコマンドとして実行される。
・\"で「"」を入れられる。
Juliaで2進数=8進数=10進数=16進数の変換

# 数値の表現

Juliaでは2進数，8進数，10進数，16進数のリテラルが利用できます。10進以外の表記にはプレフィックスをつけます。

```Julia
# 2進数
julia> b = 0b1010
0x0a

# 8進数
julia> o = 0o12
0x0a

# 10進数
julia> d = 10
10

# 16進数
julia> h = 0xa
0x0a
```

この記事では，これらの表記を相互変換する方法について説明します。

## 整数の変換

整数の型を変更すると，REPLに表示される数値は，10進または16進に固定されます。

```Julia
# 10進表記
# ほかにも Int8, Int16, Int32, Int64が利用できる
julia> Int(0xa)
10

# 16進表記
# ほかにも UInt8, UInt16, UInt32, UInt64が利用できる
julia> UInt(10)
0x000000000000000a
```

## 数値を文字列に変換

数値リテラルを文字列に変換するには，`string()`を使います。デフォルトでは10進数表記になります。基数を変更するには，`base`オプションを使います。

```Julia
# 10進数表記の文字列
julia> string(0b1010)
"10"

# 2進数表記
julia> string(10,base=2)
"1010"

# 8進数表記
julia> string(10,base=8)
"12"

# 16進数表記
julia> string(10,base=16)
"a"
```

## 文字列を数値に変換

数値表現を含む文字列を，数値型に変換するには，`parse()`を使います。第1引数には変換後の整数型（IntやUIntなど），第2引数に文字列による数値表現を指定します。オプションとして，第3引数(`base=`)で基数指定ができます。以下のルールがあります。

1.数値表現にプレフィックスがついている場合には，この関数はそれに応じた数値を返します。
2.プレフィックスがない場合はデフォルトでは10進数として扱います。
3.プレフィックスがない場合に任意の基数に合わせるには，`base=`オプションを使います。

```Julia
# Intに変換（プレフィックスなし=10進として解釈される）
julia> parse(Int,"10")
10

# Intに変換（プレフィックスあり；以下の例では16進として解釈される）
julia> parse(Int,"0x10")
16

# Intに変換（プレフィックスなし；16進として解釈させる）
julia> parse(Int,"10",base=16)
16
```
javasqriptの便利メソッド等について

#初めに
現在、ES6のJavaScriptを学習しており、個人的なアウトプットとしたいと思います。

#for分では考えることが多い？

まずはこちらを見てください。

```javascript

const images = [
  { height: 10, width: 30 },
  { height: 20, width: 90 },
  { height: 54, width: 32 }
];
const areas = [];
for (i = 0; i < images.length; i++){
  areas.push(images[i].height * images[i].width)
}
console.log(areas) /* [300, 1800, 1728] */

```

こちらのfor文でやっていることはオブジェクトが入っているimagesという配列の数だけfor文内で繰り返しをしてareaという面積を求める処理です。

僕はfor文の中で考えることが多いなという印象があります。
・ imageがトータル数を数える。
・ i を　ループするたびに足していく。
・ images[i].heightのところが長い。

上記が僕がこの処理の時に考えたり、感じていることです。。


#map()を使ってみる


```javascript
const images = [
  { height: 10, width: 30 },
  { height: 20, width: 90 },
  { height: 54, width: 32 }
];
const areas = images.map(function(image){
  return image.height * image.width /* [300, 1800, 1728] */
});
```
こちらはmap()を使っています。map()というのはコールバック関数を実行して配列の中の要素に対して好きな処理をして、結果を返り値として新しい配列を作成するといったものです。
for文お決まりの
for (i = 0; i < images.length; i++)
といったことがなくなってスッキリした印象があるのと、要素へアクセスするために添字を使っていないところもいいところなのかなと思っています。
ですがもう少しスッキリしたいですね。

#アロー関数を使ってみる

```javascript
const images = [
  { height: 10, width: 30 },
  { height: 20, width: 90 },
  { height: 54, width: 32 }
];
const areas = images.map(image =>image.height * image.width);
console.log(areas) /* [300, 1800, 1728] */
```
さらにスッキリして処理の内容が直感的に分かりやすくなった気がします。
ではもう少しいじってみます。

#分割代入を使ってみる
```javascript
const images = [
  { height: 10, width: 30 },
  { height: 20, width: 90 },
  { height: 54, width: 32 }
];
const areas = images.map(({height, width}) => height * width);
/* [300, 1800, 1728] */
```
これは分割代入というES６から登場した機能を使っているのですが少し難しいかもです。。
コールバック関数の引数となる部分に{height, width}というimagesのオブジェクト内の値を入れることができます。

#最後に
最初のfor文に比べたら少しスッキリしましたね。今回は単純なプログラムなのですが、もっと複雑なプログラムを作る際には便利メソッド（forEach、some, map, every, find, some, reduce）などなどを使いこなせるかが鍵になっているのかなと思った今日この頃でございます。
何かもっとこうしたらとかアドバイスや誤った考え方があればご指摘ください。
よろしくお願いいたします。