OmniAICreator/Qiita-1.07M huggingface dataset:
「リファクタリング 第2版」リファクタリング項目に関連／必要となるリファクタリング項目整理

## 第6章 リファクタリングはじめの一歩
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2020/01/BookRefactoring_06.jpg)

## 第7章 カプセル化
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2020/01/BookRefactoring_07.jpg)

## 第8章 特性の移動
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2020/01/BookRefactoring_08.jpg)

## 第9章 データの再編成
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2020/01/BookRefactoring_09.jpg)

## 第10章 データの条件記述の単純化
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2020/01/BookRefactoring_10.jpg)

## 第11章 APIのリファクタリング
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2020/01/BookRefactoring_11.jpg)

## 第12章 継承の取り扱い
![alt](http://www.cloudsquare.jp/kumonosu/wordpress/wp-content/uploads/2020/01/BookRefactoring_12.jpg)

## memo
### 第1章
勉強になります。
掲載されているJavaScriptでもいいのですが、
自分の今やっているプログラミング言語でやった方が良いです。
いろいろ考えさせられ、気づきがあります。
### 第2章
プロジェクトマネージャ、プロジェクトリーダさんに読んで欲しい。
### 第3章
プログラマーがコードを書く前に読んだ方が良い。
リファクタリングの本だが、当然、新規にも効果がある。
読んだことを気をつけるだけで、コードが変わる。
言語処理100本ノック-87:単語の類似度

[言語処理100本ノック 2015](http://www.cl.ecei.tohoku.ac.jp/nlp100/)の87本目「単語の類似度」の記録です。
いよいよ単語ベクトルを使って単語間の類似度を求めます。ようやく前処理が終わって本題になった感じです。自分のメールや会議の議事録などを使って単語間の類似度を求めてみたいものです。
類似度にはコサイン類似度を使います。高校で三角関数を習っていたときには「何に役に立つのだろう？」と感じていたことが本当に役に立つとは。
プログラム的には対して難しくないです。

# 参考リンク

|リンク|備考|
|:--|:--|
|[087.単語の類似度.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/09.%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E7%A9%BA%E9%96%93%E6%B3%95%20(I)/087.%E5%8D%98%E8%AA%9E%E3%81%AE%E9%A1%9E%E4%BC%BC%E5%BA%A6.ipynb)|回答プログラムのGitHubリンク|
|[素人の言語処理100本ノック:87](http://qiita.com/segavvy/items/663454567a191cf1b968)|言語処理100本ノックで常にお世話になっています|

# 環境

|種類|バージョン|内容|
|:--|:--|:--|
|OS|Ubuntu18.04.01 LTS|仮想で動かしています|
|pyenv|1.2.15|複数Python環境を使うことがあるのでpyenv使っています|
|Python|3.6.9|pyenv上でpython3.6.9を使っています<br>3.7や3.8系を使っていないことに深い理由はありません<br>パッケージはvenvを使って管理しています|

上記環境で、以下のPython追加パッケージを使っています。通常のpipでインストールするだけです。

|種類|バージョン|
|:--|:--|
|numpy|1.17.4|
|pandas|0.25.3|

# 課題
## [第9章: ベクトル空間法 (I)](http://www.cl.ecei.tohoku.ac.jp/nlp100/#ch9)
>[enwiki-20150112-400-r10-105752.txt.bz2](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/enwiki-20150112-400-r10-105752.txt.bz2)は，2015年1月12日時点の英語のWikipedia記事のうち，約400語以上で構成される記事の中から，ランダムに1/10サンプリングした105,752記事のテキストをbzip2形式で圧縮したものである．このテキストをコーパスとして，単語の意味を表すベクトル（分散表現）を学習したい．第9章の前半では，コーパスから作成した単語文脈共起行列に主成分分析を適用し，単語ベクトルを学習する過程を，いくつかの処理に分けて実装する．第9章の後半では，学習で得られた単語ベクトル（300次元）を用い，単語の類似度計算やアナロジー（類推）を行う．
>
>なお，問題83を素直に実装すると，大量（約7GB）の主記憶が必要になる． メモリが不足する場合は，処理を工夫するか，1/100サンプリングのコーパス[enwiki-20150112-400-r100-10576.txt.bz2](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/enwiki-20150112-400-r100-10576.txt.bz2)を用いよ．

今回は*「1/100サンプリングのコーパス[enwiki-20150112-400-r100-10576.txt.bz2](http://www.cl.ecei.tohoku.ac.jp/nlp100/data/enwiki-20150112-400-r100-10576.txt.bz2)」*を使っています。

### 87. 単語の類似度
> 85で得た単語の意味ベクトルを読み込み，"United States"と"U.S."のコサイン類似度を計算せよ．ただし，"U.S."は内部的に"U.S"と表現されていることに注意せよ．

### 課題補足(コサイン類似度)
コサイン類似度はベクトル同士の内積をノルムの積で割った以下の式です。詳しくはググるとたくさん出てきます。

```math
\frac{\boldsymbol{A}\cdot\boldsymbol{B}}{|\boldsymbol{A}|\,|\boldsymbol{B}|}
```

# 回答
## 回答プログラム [087.単語の類似度.ipynb](https://github.com/YoheiFukuhara/nlp100/blob/master/09.%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E7%A9%BA%E9%96%93%E6%B3%95%20(I)/087.%E5%8D%98%E8%AA%9E%E3%81%AE%E9%A1%9E%E4%BC%BC%E5%BA%A6.ipynb)

```python
import numpy as np
import pandas as pd

# 保存時に引数を指定しなかったので'arr_0'に格納されている
matrix_x300 = np.load('085.matrix_x300.npz')['arr_0']

print('matrix_x300 Shape:', matrix_x300.shape)

# 'United States'と'U.S'の単語ベクトル表示
v1 = matrix_x300[group_t.index.get_loc('United_States')]
v2 = matrix_x300[group_t.index.get_loc('U.S')]

print(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))
```

## 回答解説
前半は前回ノックと同じプログラムです。
変数`v1`と`v2`として各単語ベクトルを取り出しています。

```python
# 'United States'と'U.S'の単語ベクトル表示
v1 = matrix_x300[group_t.index.get_loc('United_States')]
v2 = matrix_x300[group_t.index.get_loc('U.S')]
```

あとは計算するだけです。`dot`で内積を、`norm`でノルムを計算しています。

```python
print(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))
```

最大値が1(1の場合は同一)なので、0.83ならだいぶ似ているということでしょう。

```bash
0.837516976284694
```
Google Home開発するときの参考（IFTTT動かないときの参考も）

## Twitterに投稿

[GoogleHome mini から IFTTT 経由でTwitterにtweetしてみた](https://www.nttpc.co.jp/technology/ifttt.html)

動かないときは下記 ”Google HomeとIFTTTの連携できないとき” を実施

## Google HomeとIFTTTの連携できないとき

ぜんぜん動かない……
アカウント設定が原因でうまくいっていない？
下記を参考に**Google Home初期化**で解決

[GoogleHome(GoogleAssistant)とIFTTTを接続する際の注意点](https://smarthacks.jp/mag/20551)

あとはGoogle Homeアプリからマイ アクティビティを参考にしてちゃんと認識がうまくいっているか確認しましょう。


## NodeでGoogle Homeを喋らす

参考：[【Google Home】Google Homeにテキストを読み上げさせたい
](https://www.poly-rhythm.com/read-aloud-by-google-home/)

動いた。ただ、ライブラリのバージョンを指定してやらないと動かないところもあった。
下記を実施した。

```bash
code node_modules/google-home-notifier/package.json
# 今回はgoogle tts apiを0.0.4に変更した↓
# "google-tts-api" : "0.0.4"

npm update google-tts-apinpm update google-tts-api
```
AWS Elastic Beanstalk をなんとなく理解する

■概要
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/Welcome.html
- インフラについて学習することなく、AWS クラウドでアプリケーションをデプロイし、管理。
- 自動的に容量のプロビジョニング、負荷分散、拡張、およびアプリ状態のモニタリングといった処理をする
- Go、Java、.NET、Node.js、PHP、Python、Ruby で開発されたアプリケーションをサポート
- ワークフローは、create app → upload version → launch env → manage app

■create app～ 大体の流れ
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/GettingStarted.CreateApp.html
https://labo.ysreading.co.jp/2017/01/24/aws-elastic-beanstalk-%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AE%E6%A7%8B%E7%AF%89/

■概念
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/concepts.html
> 環境枠は環境で実行するアプリのタイプを指定し、それをサポートするためのリソースを決定する。
- HTTP リクエストを処理するアプリは、ウェブサーバー環境枠で実行
- Amazon SQS キューからタスクを引き出す環境は、ワーカー環境枠で実行
- ローリングのポリシー、バッチサイズとは？／ローリング更新について
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/using-features.rollingupdates.html
[バッチサイズ]、[最小キャパシティー]、[停止時間]、[ローリング更新のオプション] を設定

■優先順位（複数のソースの設定オプションはどのような順位付けとなるか）
https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/command-options.html#configuration-options-precedence

■commands と container_commands の違い
https://www.atmarkit.co.jp/ait/articles/1503/19/news024.html
> commands
> サーバーにアプリケーションが配置される前に記述されているコマンドを実行

> container_commands
> サーバーにアプリケーションが配置されデプロイされる前に記述されているコマンドを実行
[メモ] Windows 10 から 将来IE11が同梱されなくなっても復活できるかも？

* [Windows 10で「IE 2」が動作しWindowsの互換性の高さがまたも実証されてしまう | ソフトアンテナブログ](https://www.softantenna.com/wp/software/windows-10-ie-2/)

を見かけて、Windows 10にIEって追加インストールする方法があるのでは、と予想した。


## 参考

* [Internet Explorer 11をオフラインでインストールする手順と気をつけること。 - Code for final](http://final.hateblo.jp/entry/2015/12/23/215006)
    * [Internet Explorer 11 (オフライン インストーラー) をダウンロードする - Windows Help](https://support.microsoft.com/ja-jp/help/18520/download-internet-explorer-11-offline-installer)

実際にIEがなくなる日が来たら、復活させる方法を書く人が出てくると思う。

## IE8

* [Internet Explorer 8 ダウンロード Trekkerの小市民日記](http://trekkerworld.blog.fc2.com/blog-entry-70.html)
Kotlin, Git初心者がDroidKaigi 2020カンファレンスアプリにContributeするまで

#TL;DR
Git、GitHub、Kotlinに触れたことが無くても、DroidKaigi公式アプリにコントリビュートできる！
ぜひ私と一緒に挑戦しましょう😎

#DroidKaigiとは

>DroidKaigiはエンジニアが主役のAndroidカンファレンスです。
Android技術情報の共有とコミュニケーションを目的に、2020年2月20日(木)、21日(金)の2日間開催します。

DroidKaigi 2020 (https://droidkaigi.jp/2020/)

公開されたばかりの、DroidKaigi2020カンファレンスアプリプロジェクトはこちら
(https://github.com/DroidKaigi/conference-app-2020)

#経歴
新卒2年目のAndroidエンジニアです。
普段は主に、以下のような環境で業務用Androidアプリの開発を行っています。
使用言語：Java (職場全体でのKotlin採用率は0%です)
バージョン管理：Subversion

#DroidKaigi2020のプロジェクトが公開されるまでにやったこと

お正月休み中の約5日間を利用して、KotlinとGitの学習を並行して行いました。
実際には時間が足りず、[Android Kotlin Fundamentals Course](https://codelabs.developers.google.com/android-kotlin-fundamentals/)は学習途中です💦


###Kotlin
[Android Kotlin codelab courseで、今から最新のAndroidアプリ開発を始めよう](https://qiita.com/takahirom/items/3e75581c6f8d4d31b7fa)
上記の記事を参考に、以下のCodelab 2コースを使用しました。

[Kotlin Bootcamp Course](https://codelabs.developers.google.com/kotlin-bootcamp/)
Kotlinの文法について学ぶことができます。
Kotlinが初めての場合は、下のAndroidコースを始める前に一通り目を通しておいた方が良いと思います。

[Android Kotlin Fundamentals Course](https://codelabs.developers.google.com/android-kotlin-fundamentals/)
Kotlinを使用したAndroidアプリの開発について学ぶことができます。
Gitを並行して学習する場合は、本コースの内容に合わせてGitの操作を実際に行ってみると良いと思います。

###Git, GitHub
UdemyのGit入門コースを受講しました。
1~2日程度で終えることができます。
https://www.udemy.com/course/unscared_git/

#実際にコントリビュートした内容
####Issue
https://github.com/DroidKaigi/conference-app-2020/issues/140

####PullRequest
https://github.com/DroidKaigi/conference-app-2020/pull/238

内容を見ていただければわかりますが、Viewのサイズ調整を行っただけの非常に簡単な修正です。
Kotlinでコードを書くこともありませんでした😂


私のようにGitやKotlin,Androidを始めたばかりの人でも挑戦できそうなIssueは、"easy"や"welcome contribute"として挙がっていることが多いようです。
一緒に参加して、DroidKaigiやAndroid開発を盛り上げましょう🤗

#後書き
(学習過程を除く)人生初のプルリクを終えたままの勢いで、Qiitaの記事まで書いてしまいました😳
まだまだ学習中の身ですが、今後もDoirdKaigi2020公式アプリに積極的に参加していきます！
ご指摘やご感想あれば、コメントいただけると嬉しいです。



matplotlibで変数を上付き文字として正しく表示する

ちょっと困ったので備忘録です。
環境は Python 3.8.0、matplotlib 3.1.2 です。

# 事案

matplotlibで変数`a`を上付き文字として出力しようと思って以下のようなコードを書きました。

```python
import numpy as np
import matplotlib.pyplot as plt

a = 14
x = np.arange(0, 1, 0.1)
y = x**a

plt.plot(x, y, label=rf'$y=x^{a}$') # 問題の箇所
plt.legend()
plt.show()
```

いざプロットしてみると、以下のような図が得られました。
![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170428/046d0c74-c8ad-f5ed-5355-139ff4e37ed4.png)
残念ながら、変数`a`の一文字目のみが上付き文字として識別されてしまいました。

ごめんごめんと思って、`$y=x^{{a}}$` のように波括弧を１つ増やしてプロットしてみたら、$y=x^a$ と表示されてしまいました。

# 解決策

結果として、以下のように三重に波括弧を増やすことで解決しました。

```python
import numpy as np
import matplotlib.pyplot as plt

a = 14
x = np.arange(0, 1, 0.1)
y = x**a

plt.plot(x, y, label=rf'$y=x^{{{a}}}$') # ズバッと解決
plt.legend()
plt.show()
```
![Figure_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/170428/2ae8a9d4-0828-4e8e-8ca3-35cc5b4fc447.png)

# なぜか

[Pythonドキュメント](https://docs.python.org/ja/3/reference/lexical_analysis.html#formatted-string-literals)に書いてました。
> 文字列のうち波括弧の外にある部分については書いてある通りに扱われます。ただし二重の波括弧 '{{' または '}}' は、それぞれに対応する一重の波括弧に置換されます。

つまり最初の波括弧が一重の場合「`f'{a}'`」では、`a`が`14`に置換され波括弧が消されて処理されたので、一文字目だけが上付きになったんですね。

次に二重の場合「`f'{{a}}'`」では、二重の波括弧が一重の波括弧に置換され、そして`a`はそのままで`{a}`が処理されたので、$y=x^a$ と表示されてしまったんですね。

なので三重「`f'{{{a}}}'`」にすれば二重の波括弧が一重の波括弧に置換され、そして`a`は`14`に置換され`{14}`が処理されたので、正しく`14`が上付き文字として認識されたんですね。

以下のような感じです。

```python
a = 14
print(f'x^{a}')     # x^14
print(f'x^{{a}}')   # x^{a}
print(f'x^{{{a}}}') # x^{14}
```

Tex構文として正しいのは一番下ですね。

以上です。Python頑張ります。
[番外編] Application.jsとchartkick

#Application.js
##概要
Application.jsとはマニフェストファイルのことである。
マニフェストファイルとは、「どのCSS・JSのファイルを読み込むか」を記載したファイルのこと。
Application.jsの中身はこんな感じ。
<img width="722" alt="スクリーンショット 2020-01-14 20.09.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/865b496c-de8b-8963-57e6-399cdbfad4ae.png">
このように、どのファイルを読み込むかどうかが羅列されている。
require_treeは、そのファイル（Application.js）があるディレクトリ以下全てを読み込むと規定しているもの。
＊本来であれば自動生成時にあるはずだが、多分コメントだと思って全て消してしまったんだと思う。また//=requireと本当はすべきであり、それはしっかりと理由がある。
>コメント内で記述されているのはその他のツールで読み込んだ時に影響を与えないようにです。

##指定する方法
application.htmlのヘッド内で、どのマニフェストファイルを読み込むかを指定することができる。<img width="684" alt="スクリーンショット 2020-01-14 20.59.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/29f3be26-cf56-034a-3549-cac81797884c.png">
ちなみにこれをみると、application.cssもマニフェストファイルとして指定されており、またその中身にはこのような記載がある。
<img width="680" alt="スクリーンショット 2020-01-14 21.01.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/59bbb7c5-2101-f3f7-de58-88d19082b5e5.png">
これはそのディレクトリ以下すべてを読み込むということと、自分自身を読み込むという風に設定している。Rails Tutorialでは、custom.scssをこのディレクトリ配下に作ったが、application.cssでrequire_treeされていたので読み込まれていたということがわかる。
<img width="721" alt="スクリーンショット 2020-01-14 21.03.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/1a709e47-725e-25c6-5bf4-2203ef066e6b.png">
##流れ
1.マニフェストファイル指定（application.html head)
<img width="684" alt="スクリーンショット 2020-01-14 20.59.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/29f3be26-cf56-034a-3549-cac81797884c.png">
2.マニフェストファイル読み込み(application.js や　application.css)
<img width="722" alt="スクリーンショット 2020-01-14 20.09.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/865b496c-de8b-8963-57e6-399cdbfad4ae.png">
3.マニフェストファイルが指定したファイル読み込み。

#なぜchartkickが動かなかったのか
本来であれば、chartkick　gemをインストールして、Application.jsで読み込むファイルとして記載し、それをマニフェストファイルとしてよべば動くはずである。
が、一個前の記事で、Jqueryも動いていなかったことからApplication.js自体が読み込めていないということがわかった。よって、その中で規定されているchartkickも読み込まれることはないということである。
Application.jsはプリコンパイルされなければならず、それはrequire_treeをしていれば自動でされるようになっているらしいが、自分の場合、コメントだと思って消してしまったため、プリコンパイルされずJqueryも呼ばれていないのではと考え、require_treeを再び書いて、jqueryが読み込まれるか試したが、読み込まれなかった。
~~Application.jsが読み込まれない理由はわからない。~~

**追記**
対象のapplication.jsは、本来であればapp/javascript/packs/application.jsを読み込むが、この時、javascriptフォルダを削除してしまっていた。
実際、このパスにjavascriptフォルダがなく、webpackが読み込めなかったことが原因でHerokuへのデプロイが失敗するという自体にもなってしまった。
この為、application.jsが読み込まれず、当然そこで指定しているchartkickも読み込まれることはなかったと言うことである。

#どう解決したか
結論から言うと、chartkickファイルをマニフェストファイルとして直接指定したらちゃんと読み込むことができた。読み込めないApplication.jsを介さず直接読み込んだという形。
<img width="529" alt="スクリーンショット 2020-01-14 21.26.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/b14ee0ab-1804-4ff1-1c5f-ff5f98677bf6.png">
#参考にしたサイト
https://kurose.me/manifestfile-rails/
https://beautifulajax.dip.jp/?p=303
http://mizukmb.hatenablog.com/entry/2016/05/19/223802
https://keruuweb.com/rails-%E5%BF%85%E8%A6%81%E3%81%AAjavascript%E3%81%AE%E3%81%BF%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80/
Day5 グラフエラー解決（Chartkic）

#Chartkick読み込みエラーとapplication.js
##問題
ChartkickどころかJqueryすら読み込まれない。
##前提知識
Jqueryを使うには、
１Gem
２Application.js
３レイアウトファイル
が必要で、流れとしてはapplication.jsを読み込むことが指示されたレイアウトファイルが、Application.jsを読み込んでそこで指定されたJqueryを利用するというもの。
参考：https://qiita.com/ngron/items/95846bd630a723e00038
Chartkickも同じで、Application.jsにChartkickと明記して読み込ませるというのが公式手順の流れであった。
##原因の切り分け
まずそもそもApplication.jsがちゃんと呼ばれているのかということから考えてみることにした。そのためにJqueryを使うコードをHtmlにかき、それをブラウザで確認するという方法と、ブラウザでコマンドを打って確認する方法（F12/コンソールタブ/$()と入力)を試してみた。
すると、どちらも期待している結果にはならず、つまりJqueryが読み込まれていない、つまりApplication.jsが読み込まれていないということがわかった。
##原因解決
解決策としては以下の二つが考えられた。
　１Application.jsを正しく読み込ませる。
Application.jsが読み込まれないという問題は調べるとたくさん出てきたが、どれをやってみても解消されなかった。
　２レイアウトファイルから直接読み込ませる。
Jqueryをレイアウトファイルに直接読み込むよう記述し、上述したJqueryの確認方法で確認してみると期待通り動いた。
Application.html.erbのhead
<img width="529" alt="スクリーンショット 2020-01-14 18.13.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/220bb2ef-bc4d-bfed-d43b-86e074171b90.png">
home.html.erb
<img width="508" alt="スクリーンショット 2020-01-14 18.16.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/2f27e26c-e2d0-677e-7b59-3ea8a7b2776e.png">
これでJqueryを読み込ませることができたため、同じようにしてChartkickもできないかといろいろと調べていると参考になりそうなリンクを見つけた。https://github.com/ankane/chartkick/issues/347
こちらを参考に以下のようにapplication.html.erbのheadに記述した。
Application.html.erbのhead
<img width="505" alt="スクリーンショット 2020-01-14 18.19.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/d0e74c7d-35c5-898b-93bd-685100c4fc6f.png">
home.html.erb
<img width="545" alt="スクリーンショット 2020-01-14 18.21.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/0c3cbcf7-c448-fa18-eb49-0fbd430f986b.png">
ブラウザ
<img width="1242" alt="スクリーンショット 2020-01-14 18.22.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565105/b58b518b-a9e1-cda4-b3cb-1ec994f40518.png">
とりあえずは表示できたのでこれで進める。
JqueryやApplication.jsについては、調べたことを別にまとめておこうと思う。
ただ正直、わからないことだらけで解決は表面上はしているけれど、理解は全くできていない。なので不安である。
多次元リストを複数行でソートしたいとき

# 1次元の時


```python
import random
a = [random.randint(-5, 5) for _ in range(10)]
a.sort()
print('sorted: {}'.format(a))

>>      [4, -3, 0, -2, 1, 4, -1, -3, 2, 3]
sorted: [-3, -3, -2, -1, 0, 1, 2, 3, 4, 4]
```
予想通り、小さい順に並びます。
文字列についても同様に、

```python
# 適当にstr型のリストを作る
s = [chr(random.randint(97, 97+25)) for i in range(10)]
print(s)
s.sort()
print('sorted: {}'.format(s))
>>      ['v', 'm', 'h', 'n', 'o', 'i', 'w', 'o', 'q', 'r']
sorted: ['h', 'i', 'm', 'n', 'o', 'o', 'q', 'r', 'v', 'w']
```
#多次元のとき
例としてこのようなリストを考えます。（※[ABC128-B](https://atcoder.jp/contests/abc128/tasks/abc128_b)のテストケースより）

```python
a = [['khabarovsk', 20],
     ['moscow', 10],
     ['kazan', 50],
     ['kazan', 35],
     ['moscow', 60],
     ['khabarovsk', 40]]
```
この配列の１行目を並び替え、１行目の要素が同じ物は２行目の数字が小さい順に並び替えたいとします。
## 方法１: sortedの引数keyをいじる
下記のようにkeyを指定することで、指定した行が順番にソートされます。

```python
print(sorted(a, key=lambda x:(x[0], x[1])))
>>
[['kazan', 35], 
 ['kazan', 50], 
 ['khabarovsk', 20], 
 ['khabarovsk', 40], 
 ['moscow', 10], 
 ['moscow', 60]]

# 逆の順番で指定すると
print(sorted(a, key=lambda x:(x[1], x[0])))
>>
[['moscow', 10],
 ['khabarovsk', 20],
 ['kazan', 35],
 ['khabarovsk', 40],
 ['kazan', 50],
 ['moscow', 60]]

# 数値の場合は　- をつけることで大きい順にソートすることができます。
print(sorted(a, key=lambda x:(x[0], -x[1])))
>>
[['kazan', 50],
 ['kazan', 35],
 ['khabarovsk', 40],
 ['khabarovsk', 20],
 ['moscow', 60],
 ['moscow', 10]]
```
##方法2: ただのsort()で事足りることも
まず多次元リストに対して、`sort()`を使ってみると、

```python
b = [[chr(random.randint(97, 97+25)), random.randint(-5, 5)] for i in range(5)]
print(b)
b.sort
print('sorted: {}'.format(b))
>>
        [['r', 1], ['a', 0], ['k', -2], ['z', -2], ['g', -3]]
sorted: [['a', 0], ['g', -3], ['k', -2], ['r', 1], ['z', -2]]

```
このように、基本は第1行のみに沿ってソートされます。

ここで、例のような場合に`sort()`を使ってみます。

```python
a.sort()
print(a)
>>
[['kazan', 35],
 ['kazan', 50],
 ['khabarovsk', 20],
 ['khabarovsk', 40],
 ['moscow', 10],
 ['moscow', 60]]
```
あれ？？
方法1のkeyを順に指定した時と同じ結果が得られました。
pythonのsort関数は**基本第一行でソートされますが、第一行の要素が同じ列に対しては次の第二行を比較してソートされる**みたいです。
なので例のようなことをしたい場合は単に`sort()`を使うだけでよかったのです。

工夫すると数値が大きい順にもできます。

```python
for i in a:
  i[1] = -i[1]
a.sort()
print(a)
>>
[['kazan', -50],
 ['kazan', -35],
 ['khabarovsk', -40],
 ['khabarovsk', -20],
 ['moscow', -60],
 ['moscow', -10]]
```
# まとめ
- ソート
   - `sorted(a, key=lambda x:(x[i], x[j], x[k], ...)`
   - `sort()`は**基本第一行でソートされるが、第一行の要素が同じ列に対しては次の第二行を比較してソートされる**
Vue.js のアーキテクチャについて

<img width="302" alt="vuejslogo.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450266/f05d350d-6597-fd2e-f11b-823f8d476ab6.png">

# はじめに

Vue.js で簡単なプロダクトを作成する前に特徴を把握すべく、以下で Vue.js のアーキテクチャを確認しました。

　Vue.js ガイド： [はじめに] (https://012-jp.vuejs.org/guide/)

**※私が確認した範囲での理解となりますので、誤りや不足がある場合は、ご指摘いただけますと幸いです。**

# Vue.js のアーキテクチャ

以下を記載します。

- ソフトウェア・アーキテクチャ上の分類
- Model・View・ViewModel それぞれの機能

## ソフトウェア・アーキテクチャ上の分類

Vue.js は、ソフトウェア・アーキテクチャのパターンとしては、**MVVM (Model - View - ViewModel)** に分類され、全体像としては以下の図の通りとなります。

<img width="415" alt="mode.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450266/ce4f3797-7ce9-8794-40cb-4d78371d14b1.png">

## Model・View・ViewModel それぞれの機能

- Model：Javascript オブジェクトやデータオブジェクト(データ自体)です。

- View：実際に表示される DOM 部分です。

- ViewModel：Vue.js の中核となる部分で、Vue インスタンスとして定義することによって **View を管理**し、Model からデータの状態を取得する・通知を受けることで、変更内容が自動的に、迅速に同期されます。
DOM の Listener やディレクティブがこれに該当します。

　※ディレクティブ：「v-text」や「v-bind」、「v-if」といった形で DOM 中に記載します。

## Model

**Javascript オブジェクトやデータオブジェクト**のことであり、Vue インスタンス内で使用されると View との間で同期の対象となります。
明記されていませんが、Model も ViewModel によって管理されると言えます。

注意点としては、同期の対象(Vue インスタンスによる監視の対象)になると setter によってのみ、オブジェクトの内容が変更されたことがディレクティブによって使用されて View に反映されるということです。

例えば、Javascript で通常行うような「a = 1;」では変数 a に 1 は反映されず、$set の構文を使用することで反映されます。
(詳細は後述の「オブジェクトの内容変更に関する動作について」をご参照ください。)

## View

実際は DOM なので、\<html> や \<div>、\<p> といったものが該当します。

ただ、この DOM において、ViewModel で定義したディレクティブや値を使用しますので、View は ViewModel に管理されていると言えます。

## ViewModel

以下のような形で定義し、**View と Model を管理下に置き、双方の内容を同期**します。

```
　var vm = new Vue ({
　
　　... ※定義や実行内容
　　
　})
```

# オブジェクトの内容変更に関する動作について

オブジェクトの内容変更に関する動作の概要は以下の図の通りです。

<img width="443" alt="kenchi.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450266/74d20aee-f465-3a9b-4d4a-296bb44cd498.png">

※明記されてはいませんが、Watcher は ViewModel に含まれると考えられます。

a.b の値が変更されると、setter が ViewModel の Water に変更されたことと変更後の値を通知し、ViewModel 内でさらに Watcher からディレクティブに通知されます。

そして、最終的に View で取り扱われる値が変更されます。

# まとめ

- Model, View, ViewModel の 3 階層で構成される。
- ViewModel が View と Model を同期する(管理する、とも言える)。
- 同期は自動的に、迅速に実行される。
DockerでAdminerを起動してみる

## 環境

AWS Workspace
Amazon Linux2

Adminer 4.7.5
Mariadb 10.4.11

## Adminerについて

PHPで作られているデータベース管理ツール
日本語に対応している
phpMyAdminと同様の機能がある

MySQL、MariaDB、PostgreSQL、SQLite、MS SQL、Oracle、
Firebird、SimpleDB、Elasticsearch、MongoDBに対応している


## DockerでAdminerを起動

```docker-compose.yml
version: '3.7'

services:
  adminer:
    container_name: adminer
    hostname: adminer
    image: adminer:4.7.5
    restart: always
    ports:
      - 8080:8080
    depends_on:
      - db
  db:
    container_name: mariadb
    hostname: mariadb
    image: mariadb:10.4.11
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=password
      - MYSQL_DATABASE=sample
      - MYSQL_USER=user
      - MYSQL_PASSWORD=pass
    volumes:
      - ./mariadb/data:/var/lib/mysql
```

```
mkdir -p ./mariadb/data
chmod 777 ./mariadb/data
docker-compose up -d
````

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208807/6ade6651-1ab0-86ce-54ad-4f054bdbb570.png)
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208807/cdbe8da0-6830-5300-86a2-830e31f4bf75.png)

## 参考URL

[公式サイト](https://www.adminer.org/en/)
【Rails6】gem `rails-erd`を使おうとしたらエラー`Warning: Ignoring invalid association`

## はじめに
コマンド入力で手軽にER図が出力できるgem `rails-erd`を使ってみたときに発生した以下エラーについて解決法を記載します。

```shell
$ bundle exec erd --filetype=dot

Loading application in 'app_name'...
Generating entity-relationship diagram for 1 models...
Warning: Ignoring invalid association :posts on User (model Post exists, but is not included in domain)
Warning: Ignoring invalid association :favorites on User (model Favorite exists, but is not included in domain)
Diagram saved to 'erd.dot'.
```

※使用説明については[公式ドキュメント](https://github.com/voormedia/rails-erd)をご参照下さい。（しばらく更新されてないようです）

## 環境
```yaml
OS: macOS Catalina 10.15.1
zsh: 5.7.1
Ruby: 2.6.5
Rails: 6.0.2.1
```
## 症状

- `users`テーブル
- `posts`テーブル
- `favorites`テーブル


元々は上記のようにモデルが3つあり、メインの`users`テーブルにその他２つが関連付けされている状態です。

そのテーブル間の関係をER図で確認したかったのですが、冒頭のエラーが発生し、`users`テーブルだけのER図（むしろRelationがないので**E図**）が出力される状態。

## エラーメッセージ

エラーメッセージを詳しく見ると、ここが問題のようです。(Postモデルで抜粋)
> Warning: Ignoring invalid association :posts on User (model Post exists, but is not included in domain)

特に以下が問題。
**「Postモデルは存在するけど、ドメインに含まれてないよ！」**
と書いています。

> model Post exists, but is not included in domain

つまり、どうにかして**ドメイン**に含めてしまえば解決しそうです。

## ドメインとは？
自分はインターネット上の住所という認識ばかり持っていましたが、そもそもは**領域・定義域**という意味です。

つまり、今回は`rails-erd`が認識してくれる**領域**に該当モデルが入ってくれていないということになります。

なぜ認識してくれないのでしょう？

## 結論：解決策

```ruby:config/environments/development.rb
Rails.application.configure do
#...
  config.eager_load = true #元はfalse
#...
end
```

上記の設定で、無事に全てのモデルが認識され、読み込めるようになります。

## 理由
[こちらの記事](https://qiita.com/shakemurasan/items/305bd3d78d67b646bc06)より引用させて頂きます。

> Railsアプリケーションで、config.eager_load = falseになっていると、そのクラスが存在するか？(定数が存在するか?)を確認しようとしても、クラスにアクセスする前ならばfalseが返ってきます。

どうやら`rails-erd`が存在確認しようとしても、

```ruby
config.eager_load = false
```
だと**存在しないよ！**と答えてしまい、冒頭のエラーメッセージに繋がってしまうようです。

そのため、

```ruby
config.eager_load = true
```

にすると
> クラスにアクセスする前から、クラスの存在確認(定数定義の確認)をできるようになっています。

ということですね。

それぞれの**挙動の違い**もわかりやすく書かれていた記事だったので、ご興味ある方はご確認下さい。
助かりました:bow_tone1:

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

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

## 参考にさせて頂いたサイト（いつもありがとうございます）
- [Railsの config.eager_load はModelやControllerを読み込むタイミングを制御できる - Qiita](https://qiita.com/shakemurasan/items/305bd3d78d67b646bc06)
- [Rails アプリケーションを設定する - Railsガイド](https://railsguides.jp/configuring.html)
- [GitHub - voormedia/rails-erd: Generate Entity-Relationship Diagrams for Rails applications](https://github.com/voormedia/rails-erd)
Python仮想環境作成コマンド

# 仮想環境とは
開発するアプリケーションによっては特定のバージョンのソフトウェアを使いたいといったシチュエーションが出てくることがあります。そこで一般的には、他の開発環境から独立した環境で開発作業を進めることになります。それが仮想環境です。Pythonには標準パッケージとして"venv"というものが組み込まれているのでそちらを使っていきます。

# 動作環境
Windows10
Python 3.8.1
Pycharm 2019.3.1 Community Edition (最強のPython IDE)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/8bb2e22f-71c3-fc8b-a977-80b0e6708453.png)


# 仮想環境の作成
PycharmのTerminalでpythonが動く事を確認したら下のコマンドを入力

```terminal:terminal
python -m venv <ディレクトリ名>
```

今回はそのまま"venv"というディレクトリ名で作成します。
すると、このように仮想環境ディレクトリがあっという間に作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/5c352787-d054-0e45-9b96-16d964cec22c.png)

それでは仮想環境を起動してみましょう。

```terminal:terminal
venv\Scripts\activate
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/47b3baaf-37bf-ce65-659d-b75e3c27e01e.png)

Pycharmを再起動しても自動的に仮想環境に入っているので毎日の開発作業も楽ちんです！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286189/21b0a1a5-9c3c-60a0-a1c5-e2dbc92cc66f.png)

当然Pythonも使えます。
このままDjangoプロジェクトでも始めてみては如何でしょうか？('ω')


[PycharmでDangoプロジェクトをサーバー起動するまでの設定](https://qiita.com/RZQiita/items/d1a6eed531337522014c)



終わり
ファイルリネームを簡単に実施する方法

ファイルのリネームは業務で必要とされる機会は意外と頻度が高いように感じたため、備忘録として記載する。

```
import os
import glob

N = 8 #YYYYMMDDをファイル名から削除する場合は8文字の削除
EXT = "*.txt"
DIR = r"C:\Users\dirname" #ファイルパスの接頭辞「r」は不要な場合もある。

os.chdir(DIR)
for file in glob.glob(EXT):
    os.rename(file,file[N:])
```
20200114 プロフェッショナル試験勉強Tips

AWS Resource Access Manager(RAM)
--
> サービス概要
>- 
> AWSアカウント間のリソース共有するサービス
> ![](https://cdn-ssl-devio-img.classmethod.jp/wp-content/uploads/2018/11/aws-ram-c.png)
> 
> 出来ること
>-
>- AWSアカウントレベルでのリソース共有
>- Organization、OUレベルでのリソース共有
>
> Tips
>-
>- enable-sharing-with-aws-organizationsコマンドにて、Organizationレベルでリソース共有可能
>
> 参考
>-
>- https://dev.classmethod.jp/cloud/reinvent-2018-ram/
>- https://docs.aws.amazon.com/ja_jp/organizations/latest/userguide/services-that-can-integrate-ram.html

Systems Manager(Parameter store) vs Secrets Manager
--
> 出来ること
>-
>- 資格情報の保管と管理
>- 資格情報の暗号化(KMSを使用)
>
>違い
>-
>- Secrets Managerはライフサイクル管理ができる
>- 利用料金がSystems Managerは無料、Secrets Managerは有料
>- Systems Managerの方が連携可能なサービスが豊富
>
>参照
>-
>- https://qiita.com/tomoya_oka/items/a3dd44879eea0d1e3ef5

Client VPN
--
> サービス概要
>-
>- AWS リソースや、オンプレミスネットワーク内のリソースに安全にアクセスできるようにする、
   クライアントベースのマネージド VPN サービス
>- 管理者とクライアントの2ユーザが存在
>- VPN接続端末にVPNクライアントアプリケーションをインストールする必要あり
>違い
>-
>- Secrets Managerはライフサイクル管理ができる
>- 利用料金がSystems Managerは無料、Secrets Managerは有料
>- Systems Managerの方が連携可能なサービスが豊富
>- 認証はAD連携も可能
> 
>参照
>-
>- https://dev.classmethod.jp/cloud/aws/vpc-client-vpn/

オンプレミスADとAWSの統合
--
> AWS Directory Service for Microsoft Active Directory(AWS Managed Microsoft AD)が最適
> 出来ること
>- 
>- AD 対応アプリケーションと AWS アプリケーションにユーザーはオンプレミス AD 認証情報でアクセスでき、そのためのユーザー、グループ、パスワードの同期は不要

オンプレとVPCのVPN接続
--
> Direct Connect
>-
>- 仮想プライベートゲートウェイ(VGW)、カスタマゲートウェイ(CGW)の構成が必要
>- 1VPCにつき1VGWがデフォルト制限
>- 1VGWにつき、10ハードウェアVPN接続が可能
>- VGWはデフォルトで冗長化されており、2つのGIPを持つ
>- VGWのルート伝播を有効化しないと、通信がVPC側のルーティングテーブルに反映されない
>- ルートテーブルにオンプレミス環境へ戻る通信の設定を追加する必要がある
>- CloudHubを使うことで、CGW同士の通信が可能


Spot Fleet
--
> スポットインスタンスの買い方の一種で、スポットフリート リクエストで指定した容量ターゲットを満たすような スポットインスタンス と オンデマンドインスタンスの起動を行う
証明書期限切れまであと何日かチェックする


```py:ssl_expire.py
import socket
import ssl
import OpenSSL

def get_server_certificate(hostname):
    context = ssl.create_default_context()
    with socket.create_connection((hostname, 443)) as sock:
        with context.wrap_socket(sock, server_hostname=hostname) as sslsock:
            der_cert = sslsock.getpeercert(True)
            return ssl.DER_cert_to_PEM_cert(der_cert)

cert = get_server_certificate('qiita.com')
x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert.encode('utf-8'))

import datetime
from datetime import datetime as dt
not_before = dt.strptime(str(x509.get_notBefore())[2:16],'%Y%m%d%H%M%S') + datetime.timedelta(hours=9)
not_after  = dt.strptime(str(x509.get_notAfter())[2:16],'%Y%m%d%H%M%S')  + datetime.timedelta(hours=9)
print(not_after)
aaa = not_after - dt.now()
print(aaa)
```

```
$ python3 ssl_expire.py
2020-04-30 21:00:00
106 days, 19:33:22.726942
```

qiita.comの証明書はあと106日後に切れる



# 参考URL


[ssl\.get\_server\_certificateで証明書を取得できない場合の対処 \- Qiita](https://qiita.com/t-kigi/items/0850ab7dbe45cd50880c)

[ssl \-\-\- ソケットオブジェクトに対する TLS/SSL ラッパー — Python 3\.8\.1 ドキュメント](https://docs.python.org/ja/3/library/ssl.html#ssl.get_server_certificate)

[Python サイトのSSL証明書の有効期限を取得する \- Symfoware](https://symfoware.blog.fc2.com/blog-entry-1801.html)

[SSL証明書の期限取得 \- Qiita](https://qiita.com/zanjibar/items/b1f7354add035f447413)

[x509証明書 \- 雑多なメモ置き場](http://y0m0r.hateblo.jp/entry/20130302/1362237191)

[無題メモランダム: PythonでX日前/X日後を求める方法](http://blog.mudaimemo.com/2009/05/pythonxx.html)
フロントエンドマスターへの道 その5 snipcartとNext.jsで作るECサイト

- [2020年のフロントエンドマスターになりたければこの9プロジェクトを作れ](https://qiita.com/rana_kualu/items/915345b8f3f870cfe2aa)

上記記事の5つめ。チュートリアルのURLは以下

- https://snipcart.com/blog/next-js-ecommerce-tutorial

成果物は以下

![Screenshot from 2020-01-15 00-48-53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17669/efa17d7d-3633-9318-8e6d-718d168cfb81.png)

![Screenshot from 2020-01-15 00-49-11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17669/c7981a69-de67-064d-677e-30b0b12e50ce.png)


- https://github.com/hbsnow-sandbox/snipcart-nextjs

チュートリアルからの変更点としては

- チュートリアルの使用しているNext.jsのバージョンが古くて、一部修正
- snipcartを2から3にバージョンアップ
- eslint+pretiierあたりの設定を追加
- emotionの採用、それにあたってsass関連パッケージを削除
- dotenvを使ってAPI_KEYを.envに記述

あたりになるかなと思います。追加パッケージは以下

```terminal
yarn add @types/node \
prettier eslint eslint-config-prettier eslint-plugin-prettier \
eslint-plugin-react eslint-plugin-react-hooks \
@typescript-eslint/eslint-plugin @typescript-eslint/parser \
@emotion/core @emotion/styled @emotion/babel-preset-css-prop babel-plugin-emotion
```

## emotion

Next.jsはよく使うので特に困ったことはなかったんだけど、emotionを使うのが初めてでどうするのがベストプラクティスなのかちょっとよくわからず手探りになってしまった（いい資料がみあたらず……あったら教えてください）

コンポーネントすべてのpropsに `SerializedStyles` を渡せるようにしておいた。例えば `Container.tsx` だと

```Container.tsx
import { css, SerializedStyles } from '@emotion/core'

const Container: React.FC<ContainerProps> = ({ children, cssProps }) => {
  const container = css(
    {
      width: '100%',
      maxWidth: '980px',
      margin: '0 auto',
      padding: '0 1rem',
    },
    cssProps
  )
  return <div css={container}>{children}</div>
}

type ContainerProps = {
  cssProps?: SerializedStyles
}

export default Container
```

こうしておくと、親のコンポーネントからスタイルをあてられる

基本的には [Object Styles](https://emotion.sh/docs/object-styles) で書くのがよさそうかなーという気がする

従来CSSのカスタムプロパティだったり、SCSSの変数だったりは Enum（Enumでなくてもいいけど） とかで設定してつかうことになる

```
export enum Color {
  Text = '#111',
  Background = '#fefefe',
  Primary = '#cddc39',
  PrimaryLight = '#ffff6e',
  PrimaryDark = '#99aa00',
}
```

placeholderみたいなことも、乱用するとあまりよくなさそうではあるけど

- https://github.com/hbsnow-sandbox/snipcart-nextjs/blob/940a2b28cc8a05eaaa4f4636ba5ab05e84870f10/src/shared/ProductButton.tsx#L12

こんな感じでできる。CSS in JSだと結構色々なことがやり放題ではある気がするので、こういったことをやるときにはこうする、これはやらない、みたいなルールはちゃんとほしい気がする


## snipcart

とても便利だとおもうが、こういったECはローカライズされてないと使うのは厳しいのではないかなという気がする（売るものにもよるんだろうけど）

日本で似たようなサービスがあると便利だと思うんだけど、すでにあるのかな

## 感想

snipcartの導入があまりに簡単なのでECサイトのサンプルサイトを作った気がまったくしない、それくらい簡単だった
GitHub Actions の出力を色付きにする

## はじめに
GitHub Actions の出力はシェルスクリプトを色付けする方法で色付けすることができます。 
[GitHub Actionsの開発ツール](https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/development-tools-for-github-actions)などと併せて使用することで多少見た目をよくすることができるでしょう。
![202001150012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264159/9ef22b34-7d7f-a9ff-369e-7e08f8e40c32.png)

## 対象
TypeScript または JavaScript による GitHub Actions 開発者

## 実装例
使用するパッケージのインストール
   
```bash
yarn add sprintf-js
```

TypeScript による実装例

```ts:color.ts
import { sprintf } from 'sprintf-js';

const COLOR_MAP = {
	'black': 0,
	'red': 1,
	'green': 2,
	'yellow': 3,
	'blue': 4,
	'magenta': 5,
	'cyan': 6,
	'white': 7,
};
const ATTRIBUTE_MAP = {
	'none': 0,
	'bold': 1,
	'underline': 4,
	'italic': 3,
};

type Color = keyof typeof COLOR_MAP;
type Attribute = keyof typeof ATTRIBUTE_MAP;
type Setting = {
	color?: Color;
	backColor?: Color;
	attribute?: Attribute;
};

/**
 * @param {string} text target string
 * @param {Setting|undefined} setting setting
 * @return {string} colored string
 */
export const getColorString = (text: string, setting?: Setting): string => sprintf('\x1b[3%d;4%d;%dm%s\x1b[0m', COLOR_MAP[setting?.color ?? 'white'], COLOR_MAP[setting?.backColor ?? 'black'], ATTRIBUTE_MAP[setting?.attribute ?? 'none'], text);
```

## 使用例

```ts:main.ts
import { getColorString } from "./color";
import { EOL } from "os";

process.stdout.write(getColorString('test1') + EOL);
process.stdout.write(getColorString('test2', {attribute: 'italic'}) + EOL);
process.stdout.write(getColorString('test3', {attribute: 'underline'}) + EOL);
process.stdout.write(getColorString('test4', {attribute: 'bold'}) + EOL);
process.stdout.write(getColorString('test5', {color: 'green'}) + EOL);
process.stdout.write(getColorString('test6', {backColor: 'green'}) + EOL);
process.stdout.write(getColorString('test7', {color: 'green', attribute: 'italic'}) + EOL);
process.stdout.write(getColorString('test8', {color: 'red', backColor: 'cyan', attribute: 'bold'}) + EOL);
process.stdout.write(getColorString('test9', {color: 'blue', backColor: 'white', attribute: 'underline'}) + EOL);
```

実際の出力は以下のようになります。

![202001150116.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264159/274655e8-e3b2-1e8d-cd65-2e76d115b311.png)

## 2020/10/7 追記
イタリックの指定などのattributeに関して、指定無しの場合（0の場合）にその指定があると色などの指定が反映されなくなったようです。
【Ruby】ハッシュとJSONの変換メモ

# 前提

- Ruby 2.7
- Hash -> JSON は JSONモジュールの `to_json` を使用
- JSON -> Hash は `JSON.parse` を使用

# メモ
JSONはキーが文字列限定。Rubyのハッシュはキー、値ともに任意のオブジェクト。
ということは、RubyのハッシュからJSONに変換するときは、何らかのルールで、元のハッシュオブジェクトにJSONがサポートしていない型があった場合は変換されることとなる。

## 以前のメモ
JSONの形式の仕様ざっくりまとめとサンプル集 - Qiita https://qiita.com/kure/items/df04ca760290fd51b904

Rubyのハッシュの小さなサンプルメモ - Qiita https://qiita.com/kure/items/4f104bf4af4a5e243e61

## サンプル
### JSON -> Hash

キーは文字列のまま、値もそのまま変換される。null は nil へ。

```ruby
require "json"

# JSON -> Hash
json1 = '{
  "name1": 0
}'

json2 = '{
  "name4": {
      "name5": 0
  }
}'

json3 = '{
  "name2": "value2"
}'

json4 = '{
  "name4": null
}'

pp JSON.parse(json1) # => {"name1"=>0}
pp JSON.parse(json2) # => {"name4"=>{"name5"=>0}}
pp JSON.parse(json3) # => {"name2"=>"value2"}
pp JSON.parse(json4) # => {"name4"=>nil}
```

### Hash -> JSON

- キー
    - 	強制的に文字列に変換される。nil は空文字列として変換される。- - 値
    - シンボルやBoolean等はその文字のまま文字列として変換される。
Rubyのクラスやオブジェクト等、そのままではJSONに無い型は文字列として変換されるもよう。

```ruby
# Hash -> JSON

class Test; end

hash1 = { 0 => 1 }
pp hash1.to_json # => "{\"0\":1}"

hash2 = { "name" => "value" }
pp hash2.to_json # => "{\"name\":\"value\"}"

hash3 = { true => "false_str" }
pp hash3.to_json # => "{\"true\":\"false_str\"}"

hash4 = { name: "value" }
pp hash4.to_json # => "{\"name\":\"value\"}"

hash5 = { nil => nil }
pp hash5.to_json #=> "{\"\":null}"

hash6 = { "class" => Class }
pp hash6.to_json # => "{\"class\":\"Class\"}"

hash7 = { "class" => Test }
pp hash7.to_json # => "{\"class\":\"Test\"}"

hash8 = { "bool" => true }
pp hash8.to_json # => "{\"bool\":true}"

hash9 = {Class => Class}
pp hash9.to_json # => "{\"Class\":\"Class\"}"
```
VSCode から Python コードを触る際のimportエラー解消録

# Overview
事の発端は、WebスクレイピングをしようとBeautifilSoupr を利用しようとしたときのこと。

Anaconda導入環境にて、conda を使って、`BeautifilSoup` をインストール

```
conda install beautifilsoup4
```

その後、VSCode でimportを以下のように入力したが、エラーが起きてしまった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/c49e47ca-147b-649d-da80-6965a61e3d62.png)
`Unable to import` とのこと。`conda install` がうまくいっていないのだろうか？


# Cause
こちらの記事が非常に参考になった。
https://qiita.com/myasu398/items/5b0f321491a1bed77aa3

macデフォルトPythonインタプリタがVSCode では非推奨らしく、その設定をすることで解消する。

# Solution
command から `Python: Select Interpreter` を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/3d57dd6b-72db-2f05-f493-84df9733cdae.png)

すると、以下のように利用できるPython 実行環境が表示される。自分の場合は以下の表示。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/38277/ec8bbbfc-8127-2aa0-3f7b-60896cd9e4b4.png)
同じバージョンのPython がAnaconda or Not Anaconda で2つあった。。。

どうやら自分の場合はAnaconda でない環境を実行環境としていたらしい。
これをAnaconda の方を選択することで、問題は解消した。

# 追記
Anaconda 環境を選択すると、以前に作成した別のPythonファイルのimportが失敗していた。。。原因はおそらく、以前の環境でimportしたライブラリがAnaconda 環境に入っていないから。
こういうくだらないことで時間を費やすのはバカバカしいので、どちらかの環境に寄せた方が良さそうだ。
時間があるときに、Anaconda 環境に寄せることにしよう。
Simscapeを使用した物理モデルの作成～チュートリアル～

# はじめに
　複雑な制御対象について、簡単に記述したい！！しかし、複雑な物理モデルをMATLAB関数で表現するのは、困難を極めます。そこで、MathWorksにもう5千円お布施して、Simscapeを入手しました。
※事前にMATLAB/Simulinkは2万円程度でHomeライセンスを購入しています。
　本記事は、MATLAB/SimulinkおよびSimscapeの学習・使用方法の備忘録として記述します。

参考
https://jp.mathworks.com/help/physmod/simscape/gs/essential-steps-for-constructing-a-physical-model.html


# ばね-マス-ダンパ
物理モデルのHello Worldともいうべき、ばね-マス-ダンパ系を作ってみます。  
1. MATLABを立ち上げて、コマンドウィンドウに `ssc_new` と入力してEnter  
2. 「Simulink-PS Converter」、「PS-Simulink Converter」及び「Scope」、「Solver Configuration」が自動生成される。これらは、Simulinkライブラリブラウザの「Simscape」→「Utilities」からドラッグ&ドロップで配置することもできる。  
3. Simulinkライブラリブラウザの「Simscape」→「Foundation Library」→「Mechanical」から下記のブロックを配置。ブロックを右クリックして「回転と反転」を利用して連結する。
    - 「Mechanical Source」から「Ideal Force Source」を配置
    - 「Translational Elements」から「Mechanical Translational Reference」を配置
    - 「Translational Elements」から「Mass」を配置。配置したモデルをダブルクリックして「質量:50kg」に設定
    - 「Translational Elements」から「Translational Damper」を配置。「減衰係数:20N/(m/s)」に設定
    - 「Translational Elements」から「Translational Spring」を配置。「ばね定数：200N/m」に設定
    - 「Mechanical Sensors」から「Ideal Translational Motion Sensor」を配置  
4. Simulinkライブラリブラウザの「Simulink」→「Sources」から「Pulse Generator」を配置して連結する。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479099/69942605-1e29-ac26-b671-0a05c98bc9a9.png)
5. 「Scope」をダブルクリックして、「実行」をクリックすると結果が表示される![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/479099/cde81c06-21bd-d5c9-d3b2-fe327c240847.png)

# おわりに
物理モデルを作り方が何となくわかったので、制御の追加やもう少し複雑なモデルの作成を行いたい。
Google driveをCUIで操作できるgdriveが急に死亡したので…

## [GitHub公開の本体](https://github.com/gdrive-org/gdrive)ではOAuth認証が通らない。
急に![](https://user-images.githubusercontent.com/58971119/70974661-dcf19280-20da-11ea-80a9-89418e830022.PNG)ってなったから困る

## 何が問題？
配布本体のOAuth認証が(多分)古くなっている事から起きている問題です。
なので、自分でOAuth認証(1.client_id 2.client_secret)を用意して、置換してやれば再び動きます。

## 用いた解決策
[参考した解決法](https://github.com/gdrive-org/gdrive/issues/506#issuecomment-567253689) ←

以下原文。

1. Set up OAuth:
    - Visit the [Google Cloud Console](https://console.developers.google.com/apis/credentials)
    - Go to the OAuth Consent tab, fill it, and save.
    - Go to the Credentials tab and click Create Credentials ->     OAuth Client ID
    - Choose Other and Create.
    - Use the download button to download your credentials.
    - `Credentials`タブの画面に(1.client_id 2.client_secret)があるので、特に落とす必要はない
    - Now you have both client ID and client secret in this     credential file in the following form:
        - ↓ は落としたJSONの中身

```c
{"installed":{"client_id": <your client id>,"project_id":"i-m-sky-bot","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://oauth2.googleapis.com/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret": <your client secret>,"redirect_uris":["urn:ietf:wg:oauth:2.0:oob","http://localhost"]}}
```

2、Enable the Drive API:

- Visit the [Google API Library page](https://console.developers.google.com/apis/library).
- Search for Drive. ←ここ謎だったけど
    - ![](https://drive.google.com/uc?export=view&id=1nDfGGTjru6CdjPohuZtx9EjznGCzlK5r)
        - ↑を選んで、有効化しろ！って事
        - 一瞬 1.で作ったOAuthプロジェクトが現れるのかな？って深読みして焦った
- Make sure that it's enabled. Enable it if not.

3、Now you just need to edit the binary and insert your credentials instead of the one hard coded : -

```c
$ sed -i "s|367116221053-7n0vf5akeru7on6o2fjinrecpdoe99eg.apps.googleusercontent.com|<your client id>|g" path/to/the/executable/gdrive

$ sed -i "s|1qsNodXNaWq1mQuBjUjmvhoO|<your client secret>|g" path/to/the/executable/gdrive
```

## Windowsの悲しみ

尚、Win10では `sed(置換コマンド)` は使えねぇのでバイナリ書き換えには[Stirling_v131](https://www.vector.co.jp/soft/win95/util/se079072.html)を使用
一応PowerShellで↓を使えばいいはずなんだけど、エラったので…

```c
$data=Get-Content .\test.txt | % { $_ -replace "置換する文字列","置換後の文字列" }
$data | Out-File .\test.txt -Encoding UTF8
```

## Google Cloud Consoleの`OAuth Consent`に詳しい人教えて！
![](https://drive.google.com/uc?export=view&id=1keNrMNmCf29hcLGx0tY7G2aqAiA0WGNR)
OAuth何日持つか知らないんだよねぇ…一応30日に設定したけど、意味あるのかな？
その辺どうなんだろうね
ピュアでクリーンなアーキテクチャ

## はじめに
最近クリーンアーキテクチャやDDDについての話を聞いたり、記事を目にすることが多いです。
そこで実装例で度々出てくる言語としてScalaがあります。
筆者自身もScalaでクリーンアーキテクチャ&DDDを実践しており、普段からその相性の良さを実感しています。
ではなぜScalaとクリーンアーキテクチャは相性がいいのでしょう？
今回はScalaが持つ関数型言語という側面と、クリーンアーキテクチャの相性の良さを考察します。

## クリーンアーキテクチャの勘所
クリーンアーキテクチャとは[Clean Architecture  達人に学ぶソフトウェアの構造と設計](https://tatsu-zine.com/books/clean-architecture)で提唱されているソフトウェアアーキテクチャです。
その構造はよく見る円がいくつか重なった図で説明されます。
![d96c8d970d882861e2dabc3c1493c473-png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/d285bf40-c613-8bc3-255e-d7bca4214e22.png)


初見では何を表しているかさっぱりだと思いますが、伝えたいことは単純です。
それはソフトウェアの**詳細**を**方針**に一方方向に依存させるということです。
では詳細と方針とはなんのことで、なぜ一方方向の依存が推奨されるのでしょうか？

### ソフトに取り替え可能な詳細
ここで言う詳細とはIOデバイスやプロトコルなどのサービス、つまり具体的に使用されるテックスタックのことです。
これらは非常に変化しやすく、逆にそうでなければなりません。
なぜなら詳細はプロダクトの具体的な要件を決めるものです。
例えば通信方式、保存方式などが当たります。
これらの要件は一度決定されたきり変更がないとは言えません。
新しい通信プロトコルの登場、革新的な保存方式。
詳細は常に変化の波にさらされています。
したがって変更は予期しうるものであり、そこに向けて対処するのがソフトウェアアーキテクトの責務です。
詳細がいかにソフトに取り替え可能かということがソフトウェアをソフトウェアたらしめているのです。

### プロダクトそのものである方針
プロダクトとは課題を解決するものです。
語弊を恐れずに言えば面倒なことを自動化することに他なりません。
すなわち何らかの**面倒さという課題**を解決してくれるものなのです。
その面倒さは領域によって様々ですが、領域によって固定されてもいます。
プロダクトを意味づけるのはこの面倒さを解決するための方針なのです。

### 方針 is 唯我独尊
方針は何者にも影響されるべきではありません。
なぜなら上で述べたとおりそれこそがプロダクトそのものだからです。
技術革新や新しいデバイスの登場によってプロダクトが解決したい課題が影響されるべきではありません。
DBやプロトコルの変更によって、解決したかった面倒だったことが面倒ではなくなるなどということは起きてはなりませんし、起こり得ないことなのです。
**方針が実現したいものに詳細がただ従うだけなのです。**
これをクリーンアーキテクチャでは中心に方針を、周辺に詳細を配置した図で表し、外から内への依存と表現しているのです。

## 関数型プログラミングと副作用
### 純粋関数志向
ここで言う関数型とは副作用を廃した純粋関数型志向のプログラミングスタイルのことを指します。
すなわち同じ入力値に対して毎回同じ値を返し、更に副作用を起こさない関数のことです。
例えるなら数学の関数のようなものだと思ってください。
関数型スタイルで書くとプログラムの大部分は副作用のない単なる数学の関数の合成のように記述できます。

### 副作用を閉じ込めるモナドの世界
一方で副作用とプログラムは切っても切れない関係です。
printですら副作用なのです。
関数型言語はこの矛盾をモナドという仕組みを利用して解決します。
モナドは副作用を起こしうる処理を包み込み、それを純粋関数の世界から副作用が実行可能な世界に運びこんでから実行するコンテナのようなものです。
コンテナは現実世界との接点でその副作用を実行します。
その他の純粋関数型部分では実行したい副作用をモナドの中に記録するコードしか書きません。
モナドのおかげで純粋関数型は純粋であり続けるのです。

### 副作用は世界の最果てへ
殆どの副作用コードは純粋な形に書き換えられます。
どうしても副作用を伴うものがIOです。
上で述べていたモナドは実はIOモナドなどと呼ばれたりします。
なぜならIOはプログラムの外の世界と通信し作用を与えるものだからです。
トートロジー的な表現ですが、プログラムの外の世界が変わっている以上副作用を起こさざるを得ません。
したがって副作用的な処理はプログラムと外の世界の接点に集まる傾向があります。
多くの場合プログラムの起動箇所であるmain関数に集約されます。

![名称未設定のノート-2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295149/62c2f5b9-679c-4d85-16fc-1c62f0c27ede.jpeg)



## ２つの概念が生み出すクリーンでピュアな世界
クリーンアーキテクチャは実装の詳細をプログラムの外側に追いやろうとするアーキテクチャスタイルです。
また関数型言語は副作用のある処理をプログラムの外側に追いやることを強制します。
上で述べたように実装詳細にはIO的な側面を持つものが多くあり、その殆どは副作用を生みます。
例えばhttpリクエスト、データベースアクセスなどは必ず副作用を起こします。
print、環境変数の読み出しなども副作用です。
つまり詳細を追い出したいクリーンアーキテクチャにとって関数型言語は非常に相性のいい相棒になりうるのです。
実際にこの組み合わせでコードを書いてみるとプログラムの方針部分から詳細が消え去るクリーンで純粋な世界が現れ感動します。

## 最後に
今回は関数型言語とクリーンアーキテクチャの相性の良さについて考察してみました。
このどちらも難しい概念であり、十分な理解・説明ができているか正直自身はないため、もしご指摘などあればコメントをください。
ただ自分なりに面白い説明ができたのではないかと思います。
この記事がクリーンアーキテクチャや関数型言語の理解に役立ち、面白いと思ってもらえたなら嬉しいです。
linuxで「名前解決に一時的に失敗しました」とエラーを吐くときの対処

Failed to establish a new connection: [Errno -3] 名前解決に一時的に失敗しました')': 

こんなやつです。

ラズパイを放置しとくと頻繁にこれになり、対処法を忘れます

```linux
sudo dhclient wlan0
```
これだけです。

このコマンドはDHCP(Dynamic Host Configuration Protocol)サーバーから借り受けたIPアドレスを設定しているようです。
DHCPサーバーは、wifiに繋がった機器にIPを振り当ててくれるやつ、だとか。

最初遭遇した時はapt-getに失敗しました。
IPがラズパイに割り当てられなかったためにネット接続できずに出たエラーだったようです。

sshできたので
PC　→　wifi →　ラズパイ
この経路は辿れていた
また、pingで内部IPを叩いても異常なしだったのでネット接続はできているものかと思いました。

内部IP同士を結びつけてくれていてもwifiを介したネット接続はできない、という不可解なこともあるようでちょっと困りました。
Nuxt.jsで`window is not defined` または `document is not defined`になったときの対処法

公式ドキュメントにある通りにやれば問題ないんですが、どうやればいいのかいまいち具体的にピンとこなかったので書き残しておきます。
（particles.jsを使うのにめっちゃ手間取った。）

```javascript
if (process.client) {
  require('external_library')
}
```
[window または document が undefined - NuxtJS](https://ja.nuxtjs.org/faq/window-document-undefined/)

VueのSFCにおいて、具体的にはこんな感じ。

### importしたライブラリでエラーとなった場合
`import 'external_library'`として読み込むのではなく、こうする。

```vue
<template>
  <div>hoge</div>
</template>

<script>
// requireで読み込む
if (process.browser) {
  require('external_library')
}
export default {
  // hoge
}
</script>
```

### メソッドなどでwindowを呼び出そうとした場合
mountedで使う場合は意識しなくても使えるはず。

```vue
<template>
  <div>hoge</div>
</template>

<script>
// こうとか
if (process.browser) {
  // ここに window とか document を使った処理
}

export default {
  // 作成時に使いたかったらこうとか
  created() {
    if (process.browser){
      // ここに window とか document を使った処理
    }
  },
  // DOM生成し終わってから使いたかったらこう
  mounted() {
    // ここに window とか document を使った処理
  }
}
</script>
```
めっちゃ簡単にNodejsでCLIツールを作る

## やりたいこと

そこまで凝ったことをしないCLIツールをNodejsで作りたい！
そこで[cac](https://github.com/cacjs/cac)を使ってそれを実現したいと思います。

[こちらの記事](https://qiita.com/sayama0402/items/9827cae2b4d7691cb42b)で作成したプロジェクトを元に進めたいと思います。

## パッケージとindex.jsの追加

```sh
$ npm i cac

$ touch index.js
```

## cacの基本

```js
const cli = require('cac')()

cli
  .command('command', '説明') // コマンド
  .option('--opt', '説明') // 引数オプション
  .action((options) => {
    // 実行したい処理
    console.log(options) // 引数の値をオブジェクトで受け取れる
  })

cli.help()

cli.parse()
```

ここまで書いたら、以下を実行することで確認出来る。

```sh
$ node index.js --help
```

さらにコマンドも実行できる。
以下のように変更します。

```js
const cli = require('cac')()
const exec = require('child_process').exec

cli
  .command('command', '説明') // コマンド
  .option('--opt', '説明') // 引数オプション
  .action((options) => {
    // 実行したいコマンド（例でpwdコマンドを実行する）
    exec('pwd', (err, stdout, stderr) => {
      if (err) { console.log(err); }
      console.log(stdout);
    })
  })

cli.help()

cli.parse()
```

上記のようにしたら、`node index.js command`とすることで`pwd`コマンドが実行されるかと思います。

## index.js

それではいよいよ、前の記事で作成した`export.js`と`restore.js`を操作する処理を記述していきます。
追加した`index.js`に追記していきます。

```js
const cli = require('cac')()
const exec = require('child_process').exec

// エクスポート用のコマンド
cli
  .command('export', 'run export from DynamoDB to S3')
  .action(() => {
      exec('node export.js', (err, stdout, stderr) => {
        if (err) { console.log(err); }
        console.log(stdout);
      })
  })

// リストア用のコマンド
cli
  .command('restore', 'run restore from S3 to DynamoDB')
  .option('--bucket <name>', 'Bucket name used for import')
  .option('--table <name>', 'Table name to import')
  .action((options) => {
    if(!options.bucket && !options.table){
        console.log('「--bucket」オプションと「--table」を指定してください')
    } else if(!options.bucket){
        console.log('「--bucket」オプションを指定してください')
    } else if(!options.table){
        console.log('「--table」オプションを指定してください')
    } else {
        exec(`node restore.js ${options.bucket} ${options.table}`, (err, stdout, stderr) => {
            if (err) { console.log(err); }
            console.log(stdout);
        })
    }
  })

cli.help()

cli.parse()
```

## restore.js

`restore.js`が現在はファイルに直接バケット名とテーブル名を記述していますが、これをコマンドライン引数で処理するように変更します。


```js
'use strict'

function execRestore(bucketName, tableName){
    const Restore = require('dynamodb-backup-restore').Restore
    let config = {
        S3Bucket:   'backups', // 必須
        S3Prefix:   bucketName, // 任意
        S3Region:   'ap-northeast-1', // 必須
        DbTable:    tableName, // 必須
        DbRegion:   'ap-northeast-1', // 必須
    }

    Restore(config)
}

// CLIからコマンドライン引数を受け取って実行する
execRestore(process.argv[2], process.argv[3])
```

## 操作方法

```sh
# exportの実行
$ node index.js export

# restoreの実行
$ node index.js restore --bucket バケット名 --table テーブル名
```

で無理やりCLIを導入することが出来ました。
JSONの形式の仕様ざっくりまとめとサンプル集

# JSONの仕様のざっくりまとめ

まず、以下のドキュメントで仕様をざっくり確認する。

RFC 8259 - The JavaScript Object Notation (JSON) Data Interchange Format https://tools.ietf.org/html/rfc8259

- JSONは4つのプリミティブ型（文字列、数値、Bool、null）と2つの構造のタイプ（オブジェクト、配列）から構成される
- "値"とは右記のものである：オブジェクト、配列、数値、文字列、Bool、null
- オブジェクトは以下のフォーマットのものである
    - 	{"文字列": 値}
    - 	左部の名前（キー）は重複できない。重複したときの動きは実装依存（かな、下記の通り）。
- 配列は右記のフォーマット：[値, 値…]

> When the names within an object are not unique, the behavior of software that receives such an object is unpredictable.

# サンプル
上記のとおり、構造のタイプとして大きく「配列」と「オブジェクト」がある。

## 配列
配列は0個以上の"値"をカンマで区切ったもの。値にはオブジェクトも含まれる。具体的には、オブジェクト、配列、数値、文字列、Bool、null

### サンプル
```json
[0]
```

```json
[null]
```

```json
[true]
```

```json
[true, 0, null]
```

```json
[0,0,0]
```

```json
[
    {
        "name": "value"
    }
]
```

```json
[
    {
        "name": "value"
    },
    0,
    true
]
```

## オブジェクト
中括弧で文字列と値をコロンで結んだもの。
値にはオブジェクトも含まれるので入れ子も可能。

```json
{
    "name1": 0
}
```

```json
{
    "name1": true,
    "name2": false,
    "name3": null
}
```

```json
{
    "name4": {
        "name5": 0
    }
}
```

```json
{
    "hoge": [
        1,
        2,
        3
    ]
}
```

# その他
構文チェックは以下のサイトで確認：

JSON Pretty Linter - JSONの整形と構文チェック https://lab.syncer.jp/Tool/JSON-Viewer/