OmniAICreator/Qiita-1.07M huggingface dataset:
機械学習　「線形回帰モデル」

#線形回帰モデル
- 線形回帰モデル
- 線形結合
- データの分割
- 単回帰モデル
- 重回帰モデル
- 平均二乗誤差
- 最小二乗法
- 最尤法

##線形回帰モデル
線形回帰モデルは、説明変数Xから目的変数Yを予測するためのモデルである。

```math
説明変数X = (x_1,x_2,x_3,…,x_m)\\
目的変数Yは実数
```
線形回帰モデルは入力ベクトルと未知のパラメータの各要素を掛け算して足し合わせることで線形結合を求めようとしている。

##パラメータ
パラメータは、特徴量xが予測値yにどれほどの影響を与えるのか決定する重みの集合である。
正の重みをつけると、特徴量が増加すれば予測値も増加する。
負の重みをつけると、特徴量が増加すれば予測値は減少する。
また、重みが大きければその特徴量の予測値に対する影響力が大きいということができる。
しかし、パラメータは未知数である。したがって、最小二乗法や最尤法を用いて求めることができる。

##線形結合
線形結合は、入力ベクトルとパラメータを掛け算して足し合わせたものである。つまり、入力とパラメータの内積といえる。

```math
y = w^Tx + w_0 = ∑w_jx_j + w_0
```

##データの分割
教師あり学習は、その名の通り教師がある状態、解を持つモデルである。データの分割とは、回帰モデルを作る前に学習用データと検証用データに分割することである。学習用データは、機械学習モデルの学習に利用するデータである。検証用データは、学習済みデータの精度を検証するためのデータである。データの分割は、未知のデータへの対応力である汎化性能を測定するために行われる。

##単回帰モデル
線形回帰モデルの一種である単回帰モデルは、説明変数のm次元が１次元の場合のモデルである。
データは回帰直線に誤差が加わり、観測されていると仮定する。

- モデル数式

```math
y = w_1x_1 + µ
\\\\
yは目的変数\\
wは回帰係数\\
xは説明変数\\
µは誤差
```

##重回帰モデル
説明変数のm次元が多次元の場合のモデルである。
データは回帰曲面に誤差が加わり観測されていると仮定する。

- モデル数式

```math
y = w_1x_1 + w_2x_2 + µ
```
##平均二乗誤差
回帰モデルの性能を数値化する手法の一つ。実際の数値とモデルによって出力された予測値の誤差の平均値である。

```math
MSE_{train} = \frac{1}{n_{train}}∑(y_{train} - y_{itrain})^2
```
##最小二乗法
学習データの二乗誤差が最小なパラメータwを探索する方法である。二乗誤差の最小化は勾配が０になる点を求めれば良い。

```math
回帰係数の求め方  :w = (X^TX)^{-1}X^TY\\
```

```math
予測値の求め方 : y = X(X^TX)^{-1}X^TY
```
##最尤法
誤差を正規分布に従う確率変数と仮定し、尤度関数の最大化を利用した推定
線形回帰の場合は、最尤度による解と最小二乗法による解が一致する。
インフラサービスを切り替えるまでに学んだこと

株式会社LITALICOでWebエンジニア（Rails/React/ECSなど）を担当しています、@koheiyamaguchi0203です。
この記事は『[LITALICO Engineers Advent Calendar 2020](https://qiita.com/advent-calendar/2020/litalico)』1日目の記事です。

# 初めに
今年の7月~10月に私達が運営するサービスのインフラ部分をAWS Elastic Beanstalk(以下EB)からAWS ECS(以下ECS)へ移行しました。
移行する決断を下してから実際に移行しきるまでの道のりを書いていこうと思います。

# 目次

|タイトル|
|-----|
|どうして切り替える必要があったのか|
|ECSを採用した理由|
|切り替えるためにやったこと|
|移行を終えてみて|


# どうして切り替える必要があったのか

主な理由は以下のとおりです。

- EBのデプロイが遅すぎる。しかも、改善のしようがない。
- Rubyなどのバージョンアップデートができない。
- OS周りの管理を減らしたい。

１つ目の「EBのデプロイが遅すぎる。しかも、改善のしようがない。」について。
EBでは `eb deploy` というコマンドを使ってデプロイをしていました。
このコマンド１つでEBのデプロイは終わります。
しかし、このコマンドに掛かる時間が年々増えていき、リリース当初[^1]は11分ほどだったものが、切り替える前には22分になりました。
私たちのチームは毎日10回ぐらいデプロイしているので、デプロイ時間は短いほど助かります。

次に２つ目の「Rubyなどのバージョンアップデートができない。」について。
私たちのチーム状況/EB特有のやりづらさによってRubyのバージョンアップデートがリリース当初からできていませんでした(もちろん、EBを使っていてもバージョンアップデートはできます)。
このことから、Rubyを始めとするソフトウェアをもっと手軽に管理できないだろうか？と考えていました。

最後に3つ目の「OSレイヤーの管理を減らしたい。」について。
EBはEC2を使ってアプリケーションを提供します。
そうなると、仮想サーバのメンテナンスタスクが定期的に発生します。
それをこなしていくのはチームにとって負担が大きかったです。
なので、できる限り仮想サーバを意識しない設計にしたいと考えていました。

# ECSを採用した理由

理由は以下のとおりです。

- デプロイを早くできる。
- ソフトウェアの管理コストを下げられる。
- 仮想サーバを意識しない。
- 隣の事業部で採用事例があった。
- 私が使ってみたかった。

上３つはEBを使うことで辛かった点を克服するという観点です。
ここでは、下２つについてを説明します。

まず、１つ目の「隣の事業部で採用事例があった。」について。
当時4つあるサービスのうち2つでECSを採用していました。
であれば、そこの人たちにわからないことを質問できるだろうと思っていました。
あと、社内でできる限り同じ技術が使われている方が後々良いことがあるだろうとも思っています。

２つ目の「私が使ってみたかった。」について。
とても重要です。使ってみたい技術をプロダクションで試せる、素晴らしいことだと思います。
もちろん、それだけで採用するなんてことはありませんが、事業部のためにメリットがある。
その上で自分が使ってみたい技術を導入できるのは素晴らしいことだと思います。

# 移行を終えてみて
移行を終えて、以下の成果を出すことができました。
他にも細かいことはあるのですが、割愛します。

- デプロイ時間75%削減
- Rubyのバージョンアップデートをこの2ヶ月弱で4回行うことができた

他にもいくつか事業部、開発チームにとって嬉しい成果を上げることができました。
その中でも上２つの成果は開発チームの生産性を大きく向上するものです。

私のスキルも相当向上しました。
このプロジェクトをやる前からインフラの学習を続けたり、コンテナ技術とは何なのか？を調べたり。
その学習でも補えなかったことを周りの社員に聞きながら、プロジェクトを進めました。

その中で学べたことも多かったので、次のセクションではそれらについて書いていきます。


# やったこと/学んだこと
やったことは以下です。

- Web部分をECSに切り替える
- Worker部分をECSに切り替える
- 監視/オートスケールなどを導入する

やったことを詳しく書いてもたいして面白くないので、学んだことを主に書きます。

## プロジェクトを進めるために必要なこと

色々ありますが、中でも重要なのは3つです。

- 責任感
- 設定力
- 分解力

１つ目の責任感について。
当然のことなんですけど、プロジェクト推進者が責任を持ってプロジェクトを進めるために行動あるいは思考しなければプロジェクトは着地しません。
当然ですけど、そんなことも分かってなかったです。

2つ目の設定力について。
これも当然のことなんですけど、プロジェクトの目的、マイルストーン、TODOを設定しないと何も進みません。
プロジェクトの規模が大きければ大きいほど進みません。
それを設定できれば、あとは進めながら修正するだけです。
それが難しいのですが、、、。

最後に３つ目の分解力について。
これも当然のことなんですけど、プロジェクトの目的を設定したあとのマイルストーン、TODO設定では上から下へ論理的に分解して力が必要です。
これは分かっていたつもりでしたが、そんなことなかったです。
精進します。

当然のことしか書いてませんが、当然のことができないことがわかり、プロジェクトを進める中で学べたことは良かったです。

## コンテナ技術の基本のキ
コンテナとは一体何なのかを完全に理解しました。
これからも何年かはコンテナ技術の躍進は続くと思うので、これを機にキャッチアップできてよかったです。
やはり実戦配備にまさる勉強方法はないと思いました。

## インフラ構築経験
0からインフラ構築したわけではありません。
ですが、0からでも構築できるぐらいにはなったんじゃないか？と思っています。
0からインフラ構築ができれば、とりあえずサービスを世に出せる(もちろん他にもやらないといけないことはたくさんありますが)ので、とても良い経験をしたと思っています。


# 最後に
この記事はここで終わりです。これからも精進します。

明日は @i-k さんの[CodePipelineでCI/CDパイプラインを組もうとして苦労した話](https://qiita.com/i-k/items/3a6b517fa089b054ad7f)です。

# 注釈
[^1]: サービスリリースは2018年3月です。
FreeCAD を AppImage で動かす ( FreeCAD on Ubuntu20.04 )

Ubuntu20.04 ディストリビューション版の FreeCAD が動作がおかしいので AppImage 版で動かすお話。

# ディストリビューション版 FreeCAD

Draftワークベンチで、・・・あれれ？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/44fcdc1d-355d-286e-5876-df5aa97ece79.png)


調べてみると、「表示」-「ツールバー」で、以下の項目が表示されていない

- Drafat creation tools
- Draft modification tools 

設定は表示設定されているにもかかわらず、ツールバーに出てきていない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/af3a8ea2-43e4-b346-e10f-273dc048069d.png)



# PPA 版 FreeCAD でもダメだった

おかしーなーと思って以下のサイトの
「Install on Unix - FreeCAD Documentation」
https://wiki.freecadweb.org/Install_on_Unix

「Stable PPA through the console」

を見て、一旦ディストリビューション版 FreeCAD をアンインストールした後以下のように試す。

```

$ sudo add-apt-repository ppa:freecad-maintainers/freecad-stable
$ sudo apt update
$ sudo apt install freecad freecad-doc

```

ここでエラー、 

```

パッケージ freecad-doc は使用できませんが、別のパッケージから参照されます。
これは、パッケージが欠落しているか、廃止されたか、または別のソース
からのみ利用可能であることを意味します。
しかし、以下のパッケージが置き換えます:
  freecad-common

E: パッケージ 'freecad-doc' にはインストール候補がありません

```

これについて、先の wiki には以下のように書いてあった。

> Note: due to packaging problems, in certain versions of Ubuntu the freecad-doc package has collided with the installation of FreeCAD or one of its dependencies; if this is the case, remove the freecad-doc package, and only install the freecad package. If the freecad-doc package doesn't exist, then ignore it.


そのため以下のようにしてインストールしたが・・・


```

$ sudo apt install freecad
```

実行しても同じ症状、Draft ワークベンチで描画ツールが表示されていなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/de024a59-ca36-95ec-9ea7-0eae669129ec.png)

# AppImage 版

以下のページから 64-Bit Appimage をダウンロードします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/e064bd4a-e6a4-dc91-1502-d1392b436319.png)

```
$ chmod 755 FreeCAD_0.18-16146-rev1-Linux-Conda_Py3Qt5_glibc2.12-x86_64.AppImage 

```

として、以下のように実行します。

```

$ ./FreeCAD_0.18-16146-rev1-Linux-Conda_Py3Qt5_glibc2.12-x86_64.AppImage 

```

表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/0dfe9ea8-d859-5f7e-dc08-e8a42c122201.png)
#
TCP/IP　その1

#【TCP/IP　その1】

##インターネットにおける事実上の標準（デファクトスタンダード）

TCP/IPは一つのプロトコルではなく、下記の複数のプロトコルの集まり。

4階層に分割されている。
各階層ごとに用途に応じて複数のプロトコルが存在している。

##TCP/IPの階層構造

4層　アプリケーション層　HTTP、HTTPS、SMTP、POP3、SSHなど。

3層　トランスポート層　TCP、UDP

2層　インターネット層　IP、ICMPなど。

1層　ネットワーク　インターフェイス層　Ethernetなど。


※TCP/IPは、[OSI基本参照モデル](https://qiita.com/uejima_haruki/items/aaed4e18b07259e826d6)と比較される。

###・TCP（Transmission Control Protocol）

IPの上位プロトコルでトランスポート層で動作するプロトコル。

ネットワーク層のIPとセッション層以上のプロトコルの橋渡しをする。
UDPと比較して信頼性の高いプロトコル

###・UDP（User Datagram Protocol）

トランスポート層のプロトコル。

送受信されるデータの誤りや順序の違いなどを検出する機能がない。
TCPのようにコネクションが確立しているかを確認する状態(ステート)がない、ステートレスプロトコル

###・ICMP（Internet Control Message Protocol）

データ転送時の異常を通知したり、ホストやネットワークの状態を調べたりするプロトコル。
TCP/IPで補助的に利用される。

エラーが生じたり、障害が発生した場合は、このICMPを使ってエラーを通知する。
IPとともに実装される。

※pingは、ICMPを利用している。
gitベースのstaticビルドのffmpeg 64bit 最新版をインストールするshell

# これ何?
[John Van Sickle \- FFmpeg Static Builds](https://johnvansickle.com/ffmpeg/)
から手動でDLするのが面倒になったので作ったshell。

# git
https://github.com/tknr/install_ffmpeg_amd64

# 使い方
git cloneして

```
sudo su -
bash install_ffmpeg_amd64.sh
```
で /usr/loca/bin/ffmpeg がインストールされます。

# 64bit版以外の場合

適宜 install_ffmpeg_amd64.sh の9行目辺り

```
curl https://johnvansickle.com/ffmpeg/builds/ffmpeg-git-amd64-static.tar.xz -O || exit 1
```

を書き換えたらいいです
インフラエンジニアでもできる！データ基盤の構築に役立つコンテンツ６選

[Global Mobility Service Advent Calendar 2020](https://qiita.com/advent-calendar/2020/global-mobility-service)の1日目の投稿です。

データ基盤（もしくはデータ分析基盤）と呼ばれるシステムの構築を行なっています。
データ基盤とは、組織内のあらゆるデータを活用し、意思決定を可能にするためのデータを集めるシステムのことです。

筆者はいわゆるインフラエンジニアの業務を主に行っています。例えば、コンテナを使ったアプリケーションインフラの構築などです。
データ基盤もシステムのインフラと捉えることができるので、インフラエンジニアの領域のような感じがします。
ただ実際には、アプリケーションインフラとは異なるデータ基盤特有の難しさがありました。

本記事では、インフラエンジニアの筆者がデータ基盤を構築するのに役立ったコンテンツを紹介します。
これらのコンテンツによって、アプリケーションインフラとデータ基盤インフラの違いを理解し、データ基盤の構築を効果的に進めることができています。
インフラエンジニアとしてデータを活用するインフラ作りを担当しなければいけなくなった方々に参考になる情報だと思います。

なお、筆者の環境の都合により、AWSを前提としています。

# データ基盤の全体像を掴む

[Data Platform Guide - 事業を成長させるデータ基盤を作るには #DataEngineeringStudy / 20200715 - Speaker Deck](https://speakerdeck.com/yuzutas0/20200715)

データ基盤を構築するにあたっての前提となる考え方、それを実現するためのテクノロジーや実践方法といった内容が発表資料という形で簡潔にまとめられている資料です。全体像を掴むには最適なコンテンツです。
個人的には、一度作ったら終わりではなく、継続的に実験、改善するといった考えが印象的な内容です。
ある程度やるべきプラクティスが確立されているアプリケーションインフラと異なり、データ基盤は試行錯誤が必要な領域なんだと理解できます。

---

[データマネジメントが30分でわかる本](https://www.amazon.co.jp/dp/B085W4YSZJ)

データマネジメントの知識体系（DMBOK）に沿った内容を具体的な例とともに解説している書籍です。

> データマネジメントとは、データを資産と捉え、体系的に価値を引き出すための手法です。

本書では、データマネジメントの手法が数多く紹介されています。
個人的には、インフラエンジニアとしてはどうしても気になる信頼性に注目しました。信頼性については、多くの内容、具体例が掲載されています。
この中で、データの信頼性を保証するためのメタデータ管理の考え方がなるほどと思いました。

# 実例

[事業のグロースを支えるDataOpsの現場 #DataOps #DevSumi #デブサミ / 20180727](https://speakerdeck.com/yuzutas0/20180727)

「Data Platform Guide - 事業を成長させるデータ基盤を作るには」における具体的な事例の資料です。
技術の話にとどまらず、プロセス、チーム、文化に渡る内容を紹介しており、データ基盤構築の難しさ、奥深さを感じます。
MVPの考え方をデータ活用に利用するアプローチは参考になります。

---

[データ収集の基本と「JapanTaxi」アプリにおける実践例](https://www.slideshare.net/tetsutarowatanabe/japantaxi-238047234)

こちらの資料では、データ収集に関する技術を網羅しています。
データ収集における手法が体系的に整理されていて、発表資料ながら書籍のような充実した内容です。
なんとなくやっていたことがより理解できた感じがしました。
個人的にはDBからのデータ収集方法について、これほど多くのアプローチがあることに驚きました。

# データベース

[ビッグデータ処理データベースの全体像と使い分け](https://www.slideshare.net/recruitcojp/ss-64189311)

データ基盤に触れると、データを扱うためのソリューションが色々あることに気がつきます。
この資料はそのようなソリューションの傾向、ユースケースに合わせた使い分けを理解することができます。
個人的には、各ソリューションを性能という観点で分類しているのが分かりやすいです。

# AWS

[AWSではじめるデータレイク](https://www.amazon.co.jp/dp/491031301X)

AWSにおいて、データ基盤を作るのに必要な情報が解説されています。
筆者の場合、データ基盤の構築をある程度行なってからこの本を読みました。
感想としてはもっと早くこの書籍の情報を知りたかったです。
AWSでは、Glue、Athena、Redshiftといったデータ活用向けのAWSサービスがありますが、それらの具体的な使い方が説明されています。
Glueに色々な機能があってよくわからないという問題が本書で解決できます。

# おわりに

今回紹介した質の高いコンテンツを提供してくれている作成者の方々に感謝致します。
このようなコンテンツのおかげで、インフラエンジニアな自分でもデータ基盤を構築することができています。
皆様にも本記事が参考になれば幸いです。

[Global Mobility Serviceでは、ITエンジニアを募集しています。](https://www.global-mobility-service.com/recruit/tech.html#tech-requirements)
【Vagrant】ローカル開発環境を構築する手順

VagrantとVirtualBoxを使ってローカル開発環境を立ち上げたので、おさらいがてらまとめておきます。

こちらを参考に進めました。
[ドットインストール「ローカル開発環境の構築[MacOS版]」](https://dotinstall.com/lessons/basic_localdev_mac_v2
)


# Vagrantとは

Vagrantは、仮想マシン（仮想的なハードウェア）を簡単に構築・操作できるソフトウェアです。

インターネット上のサーバーは公開する時のみ必要なので、開発中はローカル環境を使って開発を行います。
今回はmacOS上にVirtualBoxというツールを使ってサーバーを立ち上げますが、Vagrantを使うとそのサーバーをコマンドで簡単に扱えるようになります。


# ローカル開発環境を構築する手順

ここから手順に入っていきます。

### VirtualBoxをインストール

まず、公式サイトからVirtualBoxをダウンロード、インストールします。
https://www.virtualbox.org/wiki/Downloads



### Vagrantをインストール

公式サイトからVagrantをダウンロード、インストールします。
https://www.vagrantup.com/

その後はターミナルで、以下のコマンドを順に実行していきます。

ホームディレクトリに移動。（別の場所にいる場合）

    $ cd

今後複数の仮想マシンを作ることを想定して、それらをまとめるフォルダ（フォルダ名：MyVagrant）を作成。

    $ mkdir MyVagrant

作ったフォルダのMyVagrantへ移動。

    $ cd MyVagrant

MyVagrantの中に、仮想マシンを作るフォルダを作成（フォルダ名：MyCentOS）。

    $ mkdir MyCentOS

作ったフォルダのMyCentOSへ移動。

    $ cd MyCentOS

仮想マシンのアドレス情報などの設定を記述するファイル、Vagrantfileを作成。（Box名：bento/centos-6.8）

    $ vagrant init bento/centos-6.8

Vagrantfileを編集して仮想マシンのIPアドレスを設定（IPアドレス：192.168.33.10）。

    $ sed -i '' -e 's/# config.vm.network "private_network", ip: "192.168.33.10"/config.vm.network "private_network", ip: "192.168.33.10"/' Vagrantfile

仮想マシンを起動。

    $ vagrant up

仮想マシンの状態を確認。

    $ vagrant status


Vagrantファイルのあるフォルダ（MyCentOS）にいることを確認して、
立ち上げたサーバーにログイン。

    $ vagrant ssh

ターミナルの$の前が [vagrant@localhost] に変わったら、仮想マシン（サーバー）にログインしている状態ということ。



### 仮想マシンの設定

よく使いそうなアプリケーションを自動でインストールしていきます。

OSを最新状態にアップデート（時間かかります）。

    $ sudo yum -y update

スクリプトを入手するためのgitをインストール。

    $ sudo yum -y install git

gitを使ってアプリケーション設定用のスクリプトをダウンロード。

    $ git clone https://github.com/dotinstallres/centos6.git

centos6フォルダができるのでそちらに移動。

    $ cd centos6

スクリプトを実行。

    $ ./run.sh

もろもろの設定を反映。

    $ exec $SHELL -l



### Cyberduckをインストール

仮想マシン上のファイルを簡単に扱えるようにするファイル転送ツール、Cyberduckを使用します。

Cyberduckの公式サイトからダウンロード。
https://cyberduck.io/

- ダウンロードができたら、Cyberduckのアプリを開く。
- アプリ左上の「新規接続」ボタンを押す。
- プロトコルはSFTPを選択。
- サーバ名は前に設定したIPアドレス（192.168.33.10）を入力。
- ユーザ名とパスワードは、vagrantで立ち上げたサーバーの場合は「vagrant」を入力。
- 接続する。
- ブックマークに登録（メニューバーのブックマークメニューから「新規ブックマーク」を選択して、設定に名前をつけておく。（ニックネームは「MyCentOS」などを入力））


**これで設定が完了です。**



# 作業を終える時

仮想マシンからログアウト。

    $ exit

仮想マシンを停止。

    $ vagrant suspend


# 次回以降の起動時

以下のコマンドを順に実行。

    $ cd
    $ cd MyVagrant
    $ cd MyCentOS
    $ vagrant up
    $ vagrant ssh

Cyberduckのアプリを立ち上げる。


# 最後に

今まではMAMPを使っていましたが、サーバーサイドの勉強をしたくなったので、Vagrantを使ってローカル環境を立ち上げてみました。
世の中には無料で使える便利なツールがいろいろとあって、ありがたいですね...。


#### 参考にさせていただいたサイトなど

- [ドットインストール「ローカル開発環境の構築[MacOS版]」](https://dotinstall.com/lessons/basic_localdev_mac_v2
)
- [Vagrant公式ドキュメント](https://www.vagrantup.com/docs
)
Java superキーワード

#１，superキーワードとは
スーパークラス（親クラス）のオブジェクトを参照するキーワードです。

#２，ソースコード
```java:Main.java
public class Main {

	public static void main(String[] args) {

		// super = keyword refers to the superclass (parent) of an object
		//         very similar to the "this" keyword

		Hero hero1 = new Hero("Batman", 42, "$$$");
		Hero hero2 = new Hero("Superman", 43, "everything");

		System.out.println(hero1.name);
		System.out.println(hero1.age);
		System.out.println(hero1.power);

		System.out.println(hero2.toString());

	}

}
```
>Personクラス（スーパークラス）👇

```java:Person.java
public class Person {

	String name;
	int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public String toString() {
		return this.name + "\n" + this.age + "\n";
	}

}
```
>Personクラスを継承しているHeroクラス👇

```java:Hero.java
public class Hero extends Person {

	String power;

	public Hero(String name, int age, String power) {
		super(name, age);

		this.power = power;
	}

	public String toString() {
		return super.toString() + this.power;
	}
}
```
OSSライセンス遵守をより具体的に

## はじめに

これまで依存関係にあるパッケージ等のライセンスを取得してくれるGitHub製のlicensedやこの他にも様々なライセンスチェッカーが開発されてきました。
特にlicensedはカバーされる範囲も広く個人的にかなり正確に取得してくれると感じていますが利用手順が多いということも挙げられます。
今回、3つの手順だけでこのようなライセンスチェック機能に加えライセンス遵守のためにするべきことを一つのテキストファイルにまとめて教えてくれるnpmパッケージを開発しました。(npmのみ対応)

## doppelganger-license

今回開発したパッケージをdoppelganger-licenseと名付けました。
詳細は[GitHub Repo](https://github.com/K-Rintaro/doppelganger-license)に記載しています。
doppelganger-licenseは先述した通り、依存関係にあるライセンスを取得しライセンス遵守のためにすべきことを具体的に教えてくれます。
これらの機能は全てプロジェクトファイル内のpackage-lock.jsonに基づいています。

手順としては

１. doppelganger-licenseのインストール

```
$ npm install doppelganger-license
```

２. dependencies.txtとmemo.txtをお好きな場所に作成
　 dependencies.txtにライセンス条項が自動出力され、memo.txtにやることリストが出力されます。

３. doppelganger-licenseを実行


```
$ doppelganger-license
```
package-lock.json, dependencies.txt, memo.txtのパスが質問されるのでそれぞれ答えてください

以上の３手順で利用できます。

デモ動画はレポジトリでご確認いただけます。


## 仕組み
仕組みはそこまで複雑ではなく

package-lock.jsonのdependenciesにあるパッケージの名前・バージョンをfsを用いて抽出
　　　　　　　　　　　　　　　　　　　　↓
　　　　node-fetch経由でregistry.npmjs.orgにてパッケージのライセンスを取得
　　　　　　　　　　　　　　　　　　　　↓
　　　　　　node-fetch経由でjsdelivrにてパッケージのライセンス条項を取得
　　　　　　　　　　　　　　　　　　　　↓
　　　　　　取得したライセンス条項をfsを用いてdependencies.txtに出力
　　　　　　　　　　　　　　　　　　　　↓
　　　コピーレフトライセンスを発見した場合はそのライセンスの条件をmemo.txtに出力

という流れです。

## 今後の発展予定
現時点でライセンス間の矛盾などは考慮できておらず、一部のコピーレフトライセンスは検出できない場合がありまだまだ改善の余地はあるという状態です。
バグの修正や改善点の報告・要望などは早くお応えできるかと思いますので、よろしければGitHub Repoにてご報告いただけますと幸いです。よろしくお願いいたします。

[K-Rintaro/doppelganger-license - GitHub](https://github.com/K-Rintaro/doppelganger-license)
Rust,Wasmの環境をDockerで作る MacOS 


#この記事の目的

rustとwasmの環境をdockerを使用して作ります。

元々はMacOSのローカルで環境を作ろうとした際に、

```
cargo install cargo-generate
```
がエラーになってしまったので、それならdockerでやろうと思い立ち調べてみたところ上手く出来なかったため、後続の方に役に立っていただければと思い記録しました。

dockerのインストール方法については省略いたします。

この記事の続きが下記の記事です。
[Rust,Wasm,Dockerで"hello world"をする MacOs catalina](https://qiita.com/stnao/items/c366cabffa77becdf9ef)

##dockerイメージをプルする


[こちら](https://www.secondstate.io/articles/getting-started-with-rust-function/)で紹介されているdockerイメージをpullします。

```
docker pull secondstate/ssvm-nodejs-starter:v2
```

作業フォルダを作成し、移動します。

```
mkdir rust_wasm
cd rust_wasm
```

dockerを起動します。

```
docker run -e USER=$USER -p 3000:3000 --rm -it -v $(pwd):/app secondstate/ssvm-nodejs-starter:v2
```

コンテナの中に入りました。
nodeとcargo(rust)が入っていることが確認できます。

```
npm -v
#npmのバージョンが表示される
cargo -version
#cargoのバージョンが表示される
```

##wasm-packとcargo-generateをインストールする


```
#wasm-packをインストールする
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
#cargo-generateをインストールする
#cargo install cargo-generateだとエラーになります
cargo install cargo-generate --features vendored-openssl
```

以上です。

テンプレートを取ってきて動作を確認してみてください。

```
cargo generate --git https://github.com/rustwasm/wasm-pack-template
```

##所感

自分でdockerファイルを書くことができれば、wasm-packとcargogenerateのインストール部分はコンテナ起動の際に完了してしまうのだと思っています。
もし、ご自身でそういったイメージを作られた方、ないしはイメージを見つけた方がおりましたらコメントで教えていただけると大変嬉しいです。

この記事の続きが下記の記事です。
[Rust,Wasm,Dockerで"hello world"をする MacOs catalina](https://qiita.com/stnao/items/c366cabffa77becdf9ef)


##参考にした記事

Getting started with Rust functions in Node.js
https://www.secondstate.io/articles/getting-started-with-rust-function/

ゼロからRust+WasmをFirebaseでデプロイするまでを簡単に
https://qiita.com/namn1125/items/8ffa0f87fa03f59f3acc
NSVAnimatedTabBarをcocoapodsに入れようとしたら、エラーになった

#はじめに
いつものようにcocoapodsにライブラリNSVAnimatedTabBarを入れようとしたらエラーになった。
###エラー画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393560/cbec9725-6267-77ff-2012-5a8c3183655b.png)
#解決策
##Podfileの中のiosの対象バージョンを9.0から11.0にしたら解決しました。

##platform :ios, '9.0'→platform :ios, '11.0'

![スクリーンショット 2020-11-29 22.02.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393560/1cf02e85-8686-adbd-0c89-a6065c5b3403.png)


                                                                   ↓
![スクリーンショット 2020-11-29 22.01.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/393560/f243e1a6-4fab-dadf-cfa0-e70dc051edc8.png)

何か気がついたことがあればご指摘いただきたく存じます。
たまにはWrangleやVOPのRun Overに感謝しても良いと思います！

本日はHoudiniApperinticeAdventCalendar10日目ということで
#たまにはWrangleやVOPのRunOverに感謝しても良いと思います！
と題して進めていきます。
一言で言うと **WrangleやVOPのRun Overって何よ？** という短いお話になります。

Wrangle で言うとこの赤枠のところ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/64cb99d5-64bc-c93a-ee64-57ddbbd34c4b.png)
VOP で言うとこの赤枠のところ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/05cc77db-6fc8-be9a-171c-b04f366644f2.png)
になります。

ここがPointならPointひとつひとつに対して処理をしますよ、という意味です。
RunOverの処理対象は全部で５つあって

- **Detail( Only Once )**
- **Primitives**
- **Points**
- **Vertices**
- **Numbers**

となります。
それぞれ処理対象が違いましてクラスであったり数字で処理をループさせます。
SOPベースのForEachもありますがそっちはSOPを組み合わせたりする時に重宝します。


でRun Overなんですが
##Wrangleの場合

まずWrangleでこんな風に１行書いてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/45ca9231-df66-1a08-de8a-5f55da3e21a4.png)

```
@Cd = relpointbbox(0,@P);
```
これはバウンディングボックスのどれくらいの位置に今処理してる点の座標が居るかをPointの色としなさいという意味です。
**@P** は現在処理している点の座標、**@Cd**は現在処理している点の色という意味になります。
Run OverがPointなので一意に**@P**や**@Cd**がポイントのアトリビュートだと認識してもらえます。
１行で簡単に書けてこれだけの事が出来てしまいます。

ところがこのRun OverがDetailになると途端にめんどくさくなります。

```
int npt = npoints(0);
for(int i=0;i<npt;i++){
    vector pos = point(0,"P",i);
    setpointattrib(0,"Cd",i,relpointbbox( 0,pos ));
}
```
同じことをやるのに１行２５文字で済んでいたところが一気に５行１３３文字に増えました。
５倍もタイプしないといけなくなる訳です。
Run OverがDetailの場合では処理するPoint数を調べてその数でForでループする必要があります。
```@P```で済んでいたところが明示的に```point(0,"P",i)```と書いて情報を引き出さなくてはならなくなり
```@Cd = ``` で済んでいたところが```setpointattrib(0,"Cd",i,relpointbbox( 0,pos ));```と
書かなくてはなりません。
これは大変めんどくさいですね。

##VOPの場合
ではこれがVOPの場合どうなるか見てみましょう。
同じことをAttributeVOPでやってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/7fc364af-29db-1157-b398-a98d8566ab69.png)
**Relative to Bounding Box**というノード一個で済みますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/bdbe9423-6135-aba8-4055-0355f533a134.png)
Tabメニューから```rel```と打つだけで候補が先頭に来ますので**Relative to Bounding Box**ノードを
作って入力のP(座標)と出力のCd(色)につなげてあげるだけでOKです。
簡単でラクチンですね。

AttributeVOPのRun OverをDetailにしてみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153910/fa1d7849-3c29-6eb5-9511-87ecc9df916d.png)
同じ結果を得る為にはノードが５個必要で７回接続しないといけません。
全頂点をForで回してそれぞれの点に対して**Import Point Attribute**で座標を取得して
**Relative to Bounding Box**ノードでバウンディングボックスの相対位置を取得して
**Set Attribute**ノードで色を設定するということをやる訳ですがDetailだとめんどくさいという事が分かります。
PointやPrimitiveなどのRunOverが用意してあるということは大変素晴らしいことなのです。
普段何気なく作っているWrangleやVOPが短く手軽になっているのはRunOverのおかげと言えるかもしれません。
Googleアナリティクスの内部プロモーション計測をGTM経由で行う方法

## 概要

Googleアナリティクスの拡張eコマースには内部プロモーションを計測する機能があります。

参考
[拡張 e コマースのレポート - アナリティクス ヘルプ](https://support.google.com/analytics/answer/6014872?hl=ja)

> 内部プロモーションには、サイトの一部を宣伝するために別の部分に表示するバナーなども含まれます。

> 内部プロモーション レポートでは、次の指標の点から内部プロモーションの成果を確認できます。

> 内部プロモーションの閲覧回数（ユーザーが内部プロモーションを閲覧した回数）
> 内部プロモーションのクリック数（ユーザーが内部プロモーションをクリックした回数）
> 内部プロモーションのクリック率（ユーザーが内部プロモーションをクリックする割合（閲覧回数/クリック数））
> 内部プロモーション名はプライマリ ディメンションです。

例えば、あるサイト内で「今だけお買い得な肉特集」のようなプロモーションを複数のページでバナー設置など行っている場合、そのプロモーションにおける各枠ごとの効果をレポートすることができます。

本記事ではGTM(Google Tag Manager)経由でこのレポートを使用したいときの方法について紹介します。

## 1. 計測したいバナーが埋め込まれているページ側の対応_プロモーションのインプレッション計測

計測したい該当バナーを埋め込んでいるページに以下のJSを追加します。
IDや名前などの値は事前に決めておきましょう。


参考
https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce#promotion-data

* id または name のいずれかを設定する必要があります。

|キー|値の型|必須|説明|
|:-:|:-:|:-:|:-:|
|id|テキスト|必須*|プロモーション ID（例: PROMO_1234）。|
|name|テキスト|必須*|プロモーションの名前（例: サマーセール）。|
|creative|テキスト|省略可|そのプロモーションが使われてる広告（例: summer_banner2）。|
|creative_name|テキスト|省略可|クリエイティブの名前（例: summer_banner2）。|
|position|テキスト|省略可|そのクリエイティブの掲載位置（例: banner_slot_1）。|
|creative_slot|テキスト|省略可|クリエイティブ スロットの名前（例: banner_slot_1）。|



```javascript:
        <script>
            dataLayer.push({
              'ecommerce': {
                'promoView': {
                  'promotions': [ // Array of promoFieldObjects.
                   {
                     'id': '01_niku', // ID or Name is required.
                     'name': '今だけお買い得な肉特集',
                     'creative': 'hero_bnr',
                     'position': 'top'
                   }]
                }
              }
            });
        </script>
```

## 2.計測したいバナーが埋め込まれているページ側の対応_プロモーションのクリック計測

クリック集計をしたい該当のバナーのonClickに、GTMとの連携に必要なデータレイヤー変数の連携を行います。
プロモーションのデータは1で設定したデータと同じ値にします。

```html

<a href="/path/to/niku_tokusyu"
    onclick="dataLayer.push({
            'event': 'promotionClick',
            'ecommerce': {
                'promoClick': {
                'promotions': [{
                    'id': '01_niku',
                    'name': '今だけお買い得な肉特集',
                    'creative': 'hero_bnr',
                    'position': 'top'
                }]
            }},
            'eventCallback': function() {document.location = '/path/to/niku_tokusyu';}});"
>
    <img alt="今だけお買い得な肉特集" src="image/niku_tokusyu.jpg">
</a>
```

## 3. GTM側の対応_プロモーションのクリック計測

2で設定したデータレイヤ変数をもとに、GTMではGoogleアナリティクスへイベント計測するようタグを設定します。

・タグの設定

```
タグタイプ: Googleアナリティクス：ユニバーサル アナリティクス
トラッキング タイプ: イベント
イベント カテゴリ: eCommerce
イベント アクション: promo_click
このタグでオーバーライド設定を有効にする: true
拡張 e コマース機能を有効にする: true
データレイヤーを使用する: true
```
・トリガーの設定

```
トリガーのタイプ: カスタムイベント
イベント名: promotionClick
```

## 4.Googleアナリティクスレポートでの確認方法

最後に設定後、計測されているかどうかをGoogleアナリティクスレポートから確認をします。
コンバージョン > eコマース > マーケティング > サイト内プロモーション の画面で、計測されているかどうか確認することができます。

以上で設定完了です！
WebサーバーとHTTPについて簡単に

# はじめに
Web検索エンジンで単語を入力し検索ボタンを押してWebページ（ブログサイトや企業HPなど）が画面に表示されるまでには裏で様々なやり取りが行われています。
今回はこのWebページが表示される仕組みについてまとめたいと思います。

# この記事のゴール

* **Webサーバー**の役割を理解する

* **HTTP**とは何かを理解する

# 目次
[1.Webサーバーとは何か](#1-Webサーバーとは何か)
[2.HTTPとは何か](#1-HTTPとは何か)
[3.まとめ](#1-まとめ)

## 1. Webサーバーとは何か
**Webブラウザ**とはHTMLで書かれたハイパーテキストを人間が理解しやすいように翻訳してくれるプログラムのことです。[前回の記事](https://qiita.com/anago1030/items/359b4cb34f918e12c022)でGoogle ChromeやSafariなどのブラウザの機能について説明しているのでよろしければ読んでみてください。

そして**Webサーバー**はWebブラウザから、「このサイトが見たい」というコンテンツの要求に対して必要なコンテンツをネットワークを通じてWebブラウザに送信する役割を持ちます。
Webブラウザの要求に対して必要なコンテンツを持っていない場合は「そのコンテンツは持ってないよ」返したり、別のWebページに案内するようなこともできます。

本屋さんのシチュエーションで例えます。
ブラウザがお客さんでサーバーがお店の店員と考えると理解しやすいと思います。
「この本がほしい」という要求に対して在庫があればその場で渡せますし、在庫がなければ「ありません」と返事したり、本を取り寄せたりするそんなイメージです。![スクリーンショット 2020-11-29 22.25.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772095/02695b0e-a602-70f3-1db7-5a792c4a5547.png)

## 2.　HTTPとは何か
ハイパーテキストで書かれたWebページはブラウザからサーバーに対してコンテンツを要求をする。サーバーは要求されたコンテンツをネットを介してブラウザに送信する。

ハイパーテキストを送信するためのやり取りと式は世界共通の仕様として決められています。この世界共通のハイパーテキストのやり取りの手順のことを**HTTP(HyperTextTransferProtocol)**といいます。
このようにやり取りの手順が世界共通のルールで統一されていることによってどの種類のブラウザからでもあらゆる種類のWebサーバーと同じ手順でハイパーテキストのやり取りをすることが可能になるわけです。

## 3.まとめ

* **Webサーバー**はブラウザに要求されたコンテンツを返す役割をもつ
* **HTTP**はハイパーテキストをやり取りするための世界共通のルールである

以上です。最後まで読んでいただきありがとうございます！
お疲れ様でした。。

## 参考文献
この記事は以下の情報を参考にして執筆しました。

- [Web技術の基本](https://www.amazon.co.jp/%E3%82%A4%E3%83%A9%E3%82%B9%E3%83%88%E5%9B%B3%E8%A7%A3%E5%BC%8F-%E3%81%93%E3%81%AE%E4%B8%80%E5%86%8A%E3%81%A7%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8BWeb%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%B0%8F%E6%9E%97-%E6%81%AD%E5%B9%B3-ebook/dp/B06XNMMC9S/ref=sr_1_1?adgrpid=71142886531&dchild=1&gclid=Cj0KCQiAqo3-BRDoARIsAE5vnaIQ_UhwsVyx3TT3bYXT4Z-ljXtWBmnUn0dfj73-PoiBatH-6SjfV5EaAsR-EALw_wcB&hvadid=338577085874&hvdev=c&hvlocphy=1009332&hvnetw=g&hvqmt=e&hvrand=17697444326739219586&hvtargid=kwd-334312951121&hydadcr=15818_11177340&jp-ad-ap=0&keywords=web%E6%8A%80%E8%A1%93%E3%81%AE%E5%9F%BA%E6%9C%AC&qid=1606657295&s=books&sr=1-1&tag=googhydr-22)
イタズラなKISS

# KISSとは

Keep It Short and Simple.
簡潔かつ単純にしておけ

余計なことをしないで読みやすいコードを書けの意

# つまり

YAGNIにつながるものもありますが、要求されていない不要なコードは書かず、かつ、なるべく見やすく短いコードを書くことを心がけることが大事です。
ｉｆ分やeach文の鬼のようなネストなど論外ですね。
また無駄にトリッキーなことをするのも可読性を下げるだけです。

私も若かりし頃に、**ビット演算でvalidationの結果を表現する**ということをやり、「1ビット目が1つ目のチェック結果」みたいな感じで画期的な方法だと最初思っていたのですが、**チェックする順番を意識していないといけない**ので、仕様変更がある度に順番を間違えないよう細心の注意が必要になってしまい、あとで大分後悔しました。
Polyfill.io を使って JavaScript の Polyfill を適用する

この記事は「[弁護士ドットコム Advent Calendar 2020](https://qiita.com/advent-calendar/2020/bengo4com)」の3日目の記事です。よろしくお願いいたします。

---

:::note warn

この記事の内容は古いので大幅に削除しました。
2024年現在では Fastly Polyfill を検討されるのが良いようです。
https://polyfill-fastly.io
:::

# TL;DR
~~Polyfill.io~~ という非常に便利なサービスを使って、Internet Explorer などのブラウザでも最近の JavaScript を動くようにします。その為に必要なのは、以下のような `<script>` を一行追加するだけです。

# はじめに
JavaScript の実装で Fetch API を使用したい場面がありました。
https://developer.mozilla.org/ja/docs/Web/API/Fetch_API
この機能が Internet Explorer (以下、IE) 非対応である為、何かしらの対応をすることになりました。
（尚、この解説での IE のバージョンは 11 になります。10 以前はほとんど使用されていないので、無視します。）

結果、Polyfill を効かせるライブラリを導入することになり、選定を行いました。

## Polyfill とは
JavaScript (ECMAScript) は特定のブラウザやバージョンが古い場合、サポートしていない機能が存在します。Polyfill は、そういったサポートしていない最近の機能を使えるようにするためのコードです。

[参考] Polyfill (ポリフィル) - MDN Web Docs 用語集: ウェブ関連用語の定義 | MDN 
https://developer.mozilla.org/ja/docs/Glossary/Polyfill

# Polyfill ライブラリの選定する
core-js と Polyfill.io を検討しました。

## core-js
https://github.com/zloirock/core-js
実績のある Polyfill ライブラリです。

以前は Babel が提供する @babel/polyfill が core-js を内部的に読み込んでいました。
https://babeljs.io/docs/en/babel-polyfill
因みに、@babel/polyfill は Babel 7.4.0 で非推奨 (deprecated) となっています。

こちらについては、5 日目の記事「[babel 環境における Polyfill のビルド最適化と async-await の扱い](https://blog.euxn.me/xsymsnvwjbkaaaaaaacrrg)」で詳しく説明していただいています。気になる方は、併せてご覧ください。

今回は、core-js を jsDelivr などの CDN から読み込むことを考えました。
https://www.jsdelivr.com/package/npm/core-js

```html

<script src="https://cdn.jsdelivr.net/npm/core-js@3.7.0/stable/index.js" integrity="sha256-HrF6MoQzzJ82sV7Ql2E5hrTW2iRlrlD54q4o/q9lIFY=" crossorigin="anonymous"></script>
```

対応は楽なのですが、stable だけに絞ってもファイルサイズが大きくなりページの表示速度が低下する懸念があった為、見送りました。

## Polyfill.io
:::note info
この内容は古いため、削除されました。
:::

# その結果どうなったか
結果、これでも動作作しませんでした。

`Object doesn't support property or method 'set'` というエラーが発生しました。
これは IE 非対応の `FormData.set()` を使っていた為でした。
https://developer.mozilla.org/ja/docs/Web/API/FormData/set

因みに、core-js でも `FormData.set()` はスコープ外で対応しておらず、他プロジェクトの Polyfill を使うことを勧めています。
https://github.com/zloirock/core-js/issues/482

ここまで進めた結果、今回は「そこまで厳密に IE の動作を求めない」という決着になり、これで対応完了とすることになりました。もし厳密な IE のサポートを求められたら、JavaScript の実装コードを書き直すか、別のライブラリで対応する Polyfill を探すことになるかと思います。

# まとめ
Polyfill.io だけで全ての機能に Polyfill が効くわけではないので、Polyfill 非対応の機能など注意して JavaScript を書かないと厳密な IE 対応は厳しそうでした。
別のライブラリを探せば対応する Polyfill はあるとは思いますが、個別に Polyfill を適用していくのも手間ですし、読み込むファイルが増えるとページの表示速度が低下する懸念があります。

どこまで厳密な対応を行うかは、開発や運用コストとの兼ね合いで判断が必要かと思います。

# さいごに
既に IE のサポートを終了しているサイトもあるかとは思いますが、一方でまだまだサポートしていかなければいけない状況のサイトもあります。どの程度のサポートを求められるか次第ではありますが、サポートの程度によっては Polyfill.io は選択肢のひとつして、とても良いと思いました。

Polyfill.io について[既に書かれた記事](https://qiita.com/moriyuu/items/061de38704687fef93b9)もあったのですが、もう少し詳細にまとめてみました。

この記事が皆様の一助となれば幸いです。

---

さて、明日 (12/4) の「[弁護士ドットコム Advent Calendar 2020](https://qiita.com/advent-calendar/2020/bengo4com) | 4日目」は @edi_t さんの「[iPhoneX以降のTrueDepthカメラを使ってオンライン会議で簡単にVTuberになる方法（お金がちょっと掛かります）](https://qiita.com/edi_t/items/491fcb4a73f89d664e76)」になります！お楽しみに！
YAGNIあるある

# YAGNIとは

You Aren't Going to Need It.
それはきっと必要にならない

未来を予想して、機能を拡張したり柔軟性を持たせても、大抵使われないあるある。

# つまり

長く何かを開発していると、「次はこういう要望が来るんじゃないか」、「次はこういう仕様変更が来るんじゃないか」と予想（覚悟）してしまって、「ついでに今のうちにやってしまおう」と思ったりしますよね。

「次また同じ作業を依頼されたときのためにツール化しておこう」とか思ったりしますよね。

そういうものの大半が結局日の目を見ることもなく使われずにお蔵入りしていきがちです。

なので、予めそれを用意してしまうのではなく、**後にその仕事がきても良いようにきれいでわかりやすいソースを書いておく**ということが大事ではないでしょうか。
【生成 Deep Learning】を読んだ感想

# はじめに

機械学習やDeep Learningの本は昨今の流行でたくさん本が出ていますね。

しかしこの本はひと味違っていて「生成」を題材にしています。本文でも触れられていますが今までの本はどうやって識別するかを扱うものがほとんどでした。

どういうことができるのか興味があったので読んでみました。

https://www.amazon.co.jp/dp/4873119200

# 感想

## よかった点

* 手頃なサイズの本でカラーなので読みやすいです。
* 画像の生成、音楽の生成、文章の生成などテーマ度毎に説明されているので分かりやすいです。

## よくなかった点

* 小型の本だけあって難しいことが特に前置き無くさらっと書いてありますね。例えば文章を「トークン化」と言っても日本語ではとても難しいですが、ここでは英語だけを考えているのでしょう。

# おわりに

これを読んだからといって急にお仕事で応用できるというものではないですね。

この本で興味を持てることをみつけてさらに深掘りしていくための最初の第一歩と言った感じでした。

何度も読み直したり実際に作って試してみたりして少しずつ理解を深めていきたいですね。
Java 継承（inheritance）

#１，継承（inheritance）とは
あるクラスが他のクラスから**属性（attributes）**や**メソッド（methods）**を取得するプロセスです

#２，ソースコード

```java:Main.java
public class Main {

	public static void main(String[] args) {

		// inheritance = the process where one class acquires,
		//               the attrivutes and methods of another.

		Car car = new Car();
		car.go();

		Bicycle bike = new Bicycle();
		bike.stop();

		System.out.println(car.speed);
		System.out.println(bike.speed);

		System.out.println(car.doors);
		System.out.println(bike.pedals);

	}

}
```
>継承元👇


```java:Vehicle.java
public class Vehicle {

	double speed;

	void go() {
		System.out.println("This vehicle is moming");
	}

	void stop() {
		System.out.println("This vehicle is stopped");
	}

}
```

>クラスからクラスへ継承する場合、”**子クラス　extends　親クラス**” と表記します👇

```java:Car.java
public class Car extends Vehicle {

	int wheels = 4;
	int doors = 4;

}
```

```java:Bicycle.java
public class Bicycle extends Vehicle {

	int wheels = 2;
	int pedals = 2;

}
```
【RxSwiftの勉強メモ】#2「ログインボタンで条件を満たしていたらボタンを活性化する」

#この記事の目的
RxSwiftの使い方を学んでいくために簡単なサンプルを作成し記録する。
後から見直して頑張ります。
今回は
@r_chibaさんの
RxSwift入門(ハンズオン)
(https://qiita.com/r_chiba/items/5618a3dd96618222cca8#rx%E5%81%B4%E5%85%A8%E4%BD%93%E5%83%8F)
を参考にさせていただきました。(よりシンプルに、とりあえず動くものを作ろうという方針でコードを書きました。)
↓にサンプルコードを示します。

#サンプル
```
import UIKit
import RxSwift
import RxCocoa

class ViewController: UIViewController {
    
    @IBOutlet weak var mailTextField: UITextField!
    @IBOutlet weak var passwordTextField: UITextField!
    @IBOutlet weak var loginButton: UIButton!
    
    let disposeBag = DisposeBag()

    override func viewDidLoad() {
        super.viewDidLoad()

        mailTextField.rx.text.subscribe { (event) in
            self.changeLoginEnabled()
        }.disposed(by: disposeBag)

        passwordTextField.rx.text.subscribe { (event) in
            self.changeLoginEnabled()
        }.disposed(by: disposeBag)
        
    }
        
    private func changeLoginEnabled() {
            if mailTextField.text!.count > 0 && passwordTextField.text!.count > 0 {
                
                print("ボタン活性！")
                // ボタンの活性状態
                loginButton.isEnabled = true

                loginButton.backgroundColor = UIColor.red

            } else {
                print("ボタン非活性！")
                // ボタンの活性状態
               loginButton.isEnabled = false

               // ボタンの背景色
                loginButton.layer.backgroundColor = UIColor.secondarySystemBackground.cgColor

            }
        }
    
}

```
#結果
以下のように「mail」と「password」両方のテキストフィールドに文字が
１文字以上入力されるとボタンの背景が赤く変化し活性化します。
![画面収録 2020-11-29 22.06.00.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412828/0e7f4bc2-d5df-85ed-6668-433e6661f195.gif)


#まとめ
比較的容易に実装ができたと思います。
まだまだRxSwiftを全貌は把握していませんが、便利なのかな〜
くらいはわかるようになりました！
【IT用語】CUIとGUIと違いについて【初心者向け】

<br>
パソコンを操作する方法には、２種類の方法があります。IT業界ではよく`CUI`と`GUI`と呼ばれます。今回はこれについて、簡単に説明使用と思います。
<br>
<br>

## GUI
僕たちが普段パソコンやスマホを触る時は、画面上にあるアイコンやボタン、検索窓などを利用して、操作していると思います。

結論、これが`GUI`と呼ばれる物です。Macのパソコンの場合は、こんな感じですね。

![photo-1580522154071-c6ca47a859ad.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/00fef8c2-00dd-4b30-8228-0937495af886.jpeg)

ちなみに`GUI`の正式名称は、`Graphical user interface(グラフィカルユーザーインターフェース)`と言う名前で、視覚的な感じでパソコンやスマホを操作する方法のことです。
<br>
<br>

## CUI
対して`CUI`とは`Character user interface(キャラクターユーザーインターフェース)`と言う正式名称で、Characterとは文字と言う意味です。

要するに、文字を入力することで、パソコンなどを操作する方法のことです。いわゆる黒い画面と言われ、画像で見るとこんな感じですね。

![スクリーンショット 2020-11-26 17.22.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/882660/6887d122-4fd0-49aa-3b55-24cf51b99cc3.png)

IT業界の中でも、バックエンドやインフラ系のエンジニアしか、あまり触れることの無い物です。あと視覚的な認識ではなく、コマンドと言われる特定の文字列での操作になりますので、最初はイメージがしづらく難しいと感じる人も多いです。

ただ、これが使えるようになると、何かWeb開発をする際に自分で環境を構築することもでき、仕事の幅も広がるものになります。
<br>
<br>

## まとめ
今回は、IT業界でよく言われる`CUI`と`GUI`の言葉について、解説しました。こう言う用語は、知らないと
会話ができないものになりますので、しっかり抑えておくと役に立ちます。

最後まで読んでいただき、ありがとうございました！

<br>
<br>
<br>

筆者：yuki｜学習10日目で初案件獲得→現在はフルスタックエンジニア転職に向けて学習中
Qiita：https://qiita.com/yuki4839
Twitter：https://twitter.com/yuki35522891
mac MAMP環境　reactの記述が即時反映しない　(EnableSendfile OFF)

未経験者の学習メモです。
<h1>内容</h1>
macのMAMP環境でlravel＋phpの環境でreactのコーディングをためしていると作成したappのreactの記述が全然反映しない場面に遭遇したので黙示録として残します。

<h1>環境</h1>
mac 10.14.6
MAMP 5.7
react　16.13.1
laravel　6.18.40
PHP 7.4.9

<h1>原因の機能</h1>

Apacheの

EnableSendfile

という機能

<h2>EnableSendfileとは？</h2>

Apacheの機能の一つ
一度読み込んだ静的なファイル（HTML/CSS, JavaScript）は、再度読み込まずにキャッシュ内容を送る。
本番環境だとリクエスト数を減らすことができるので有効になっている。

<h2>解決方法</h2>
1.
Applications/MAMP/conf/apache/httpd.conf  を開く

2.
記述中の
<p>#EnableSendfile off</p>

↓

EnableSendfile off

へ変更

3.
appachの再起動


<h2>参考サイト</h2>

1.
MAMPのApachの設定ファイルの場所を確認させてもらいました。

[MAMP のインストールと初期設定]
https://www.webdesignleaves.com/pr/plugins/mamp_installation.html

2.
EnableSendfile機能の概要と機能をOFFにする方法を確認させてもらいました。

[ローカル環境でCSSが反映されない時に見直すべきhttpdの設定]
https://hodalog.com/httpd-enablesendfile-off/
コピペ駆動開発のススメ

# DRY原則にはあまりこだわらないほうが良いという話

DRY原則は**Don't Repeat Yourself**の略で要するに**「コードをコピペすな」**という意味なのは皆様ご承知おきとは思いますが、あまりこだわり過ぎも良くないという話。

# コピペしないほうが良いとき

例えば以下のようなコードがあったとき

```example.rb
def send_start_message()
  member = getMember
  put_message(message: 'Start!', to: member.id)
end

def send_finish_message()
  member = getMember
  put_message(message: 'Finish!', to: member.id)
end
```

`send_start_message`と`send_finish_message`違いは`message`の内容だけなので、そこだけ引数で渡した方がスッキリしますね。

```example1.rb
def send_message(message)
  member = get_member
  put_message(message: message, to: member.id)
end

def send_start_message
  send_message('Start!')
end

def send_finish_message
  send_message('Finish!')
end
```

# コピペしたほうが良いとき

ここで仕様変更が入って、以下のような要件が増えた場合に

- Start messageのときは、ログも出力
- Finish messageのときは、親IDにもmessageを送る
- Warning messageのときは、member.statusも更新

`send_message`関数だけで解決すると以下のような感じでしょうか

```example2.rb
def send_message(message: '', logging: false, do_send_parent: false, do_update_status: false)
  logger(message) if logging

  member = get_member

  put_message(message: message, to: member.id)

  put_message(message: message, to: member.parent_id) if do_send_parent
  
  member.update_status if do_update_status
end
```

`send_message`がいろんな役割を担い過ぎな気がしますね。
この程度なら問題ないですが、さらに仕様が増えていくとパラメータとif文が更に増えて可読性が大分落ちそうです。
そうなるくらいなら、ある程度はコピペしてしまったほうが可読性も高く、あとからの仕様変更も簡単にできたりします。

# つまり

良い例が浮かばなくて、この例だとコピペしなくてもまだ良い感じに正規化できてしまうのですが、要するに一つのクラスや関数になんでもかんでもやらせてしまうと、読みにくいし追加の修正がしにくいから、マイクロサービス化するのが良いよねって話。
C言語のポインタをコードと図で整理する


C言語について日々勉強中です。極力文書を使わずにコードと図で簡潔にC言語のポインタを整理しました。

勉強中なので誤り等あれば、コメントでご指摘いただけるとありがたいです。



# 前提
変数は以下の２の要素から構成されます。  
1. アドレス
2. 値


例）整数型の変数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867341/66ef3c98-41ce-ffc8-84e4-03880443d0fc.png)

例）整数型へのポインタ変数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867341/c01fe4b2-b984-cf0c-ecdb-fc7aa7e998da.png)

　ポインタ変数は「値」に他の変数などのアドレスが格納されています。
　ポインタ変数自身もアドレスを持ちます


#変数の各部分

例）整数型の変数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867341/976d8608-c097-58bd-1584-929295dd60a1.png)

例）整数型へのポインタ変数
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867341/025ce27e-3a50-d385-46f0-1c468c0aebe1.png)
　ポインタ変数は使用時に*を変数の前につけることで、ポインタ変数の値に格納されているアドレスが指す場所に保存されている値を参照できます。


#サンプルプログラム

```c
#include <stdio.h>

int main() {

        int data;
        int *ptr1;
        int **ptr2;
        int ***ptr3;
	
        data = 5;
        printf("(A) 整数型の変数dataの値 = %d\n", data);
        printf("(B) 整数型の変数dataのアドレス = %p\n", &data);

        // 以下はコンパイルエラー
        // printf("ptr1が指す場所に保存されている値 = %d\n", *data);

        ptr1 = &data;
        printf("(C) 整数型の変数dataへのポインタ変数ptr1の値 = %p\n", ptr1);
        printf("(D) 整数型の変数dataへのポインタ変数ptr1のアドレス = %p\n", &ptr1);
        printf("(E) *ptr1が指す場所に保存されている値 = %d\n", *ptr1);

        ptr2 = &ptr1;
        printf("(F) ポインタ変数ptr1へのポインタ変数ptr2の値 = %p\n", ptr2);
        printf("(G) ポインタ変数ptr1へのポインタ変数ptr2のアドレス = %p\n", &ptr2);
        printf("(H) *ptr2が指す場所に保存されている値 = %p\n", *ptr2);
        printf("(I) **ptr2が指す場所に保存されている値 = %d\n", **ptr2);

        ptr3 = &ptr2;
        printf("(J) ポインタ変数ptr2へのポインタ変数ptr3の値 = %p\n", ptr3);
        printf("(K) ポインタ変数ptr2へのポインタ変数ptr3のアドレス = %p\n", &ptr3);
        printf("(L) *ptr3が指す場所に保存されている値 = %p\n", *ptr3);
        printf("(M) **ptr3が指す場所に保存されている値 = %p\n", **ptr3);
        printf("(N) ***ptr3が指す場所に保存されている値 = %d\n", ***ptr3);
}
```

#サンプルプログラムの実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867341/9f3518df-f448-cbe3-b3ca-c20a3c363d7f.png)

#サンプルプログラムの実行結果を図解
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867341/44cae76e-16f2-b31f-f5c2-d8842439e519.png)


ポインタを関数の引数にした場合や配列についてはまた次の機会に…
【ドメイン駆動設計入門】を読んだ感想

# はじめに

私は普段KotlinやJavaを使ってサーバーサイドの開発をしたり、アプリを開発したり、時にはフロントエンドを開発したりしています。

こちらの本を開発の時の設計に一助となればと思い読んでみました。

https://www.amazon.co.jp/dp/479815072X

# 感想

## よかった点

* 「ボトムアップでわかる！」と書いてあるだけあって、 **理論先行ではなく具体例を挙げてひとつひとつ説明がありとても読みやすいです。**
* 途中で眠くなることなく一気に読み進めることができました。
* DDDにおけるエンティティとクリーンアーキテクチャにおけるエンティティの違いについて言及されていたのがよかったです。このあたりの用語は開発の時に注意しなければと思いました。

## よくなかった点

* `C#` ならではと思う例などもあり、JavaやKotlinではどう変わるだろうか？と思いながら読みました。
* 「筆者の見解では」というような記述があり、他の見解も幅広く集めて総合的に理解する必要があると感じました。どんな本でも鵜呑みは危険ですね。

# おわりに

設計は本を読んだら急にできるようになるというものではないですね。日々の研鑽を積み重ね少しでも長持ちする設計を作っていきたいです。
vscodeにprettierを導入しよう!!

今回はコードフォーマッターの[prettier](https://prettier.io/)の`vscodeへの導入方法`についての説明です。

## prettierって何？
prettierはコードフォーマッターと呼ばれ、書いたコードを読みやすい形に整形してくれるツールです。

個人で開発を行っている場合は関係ないかもしれませんが、複数人のチームで開発している時に、人によってコードの書き方が違うと他の人がコードを読みにくくなってしまいます。

そこで、prettierを使うことで、`command+s`でファイルを保存した時に誰でも読みやすい形に勝手にコードが整形されます。

それによって可読性が上がり、メンテナンスや開発もしやすくなります。

### コードの整形の例
整形前

```example.js
    const inputTitle = useCallback((event) => {
      setTitle(event.target.value)
    }, [setTitle]);
```
```example.js
let   hoge  = func (
  parameter1,   parameter2, parameter3,    parameter4,
 parameter6,  parameter7,
       parameter8,
            );
```
整形後

```example.js
  const inputTitle = useCallback(
    (event) => {
      setTitle(event.target.value);
    },
    [setTitle]
  );
```
```example.js
let hoge = func(
  parameter1,
  parameter2,
  parameter3,
  parameter4,
  parameter6,
  parameter7,
  parameter8
);
```
## 導入方法を紹介
prettierについて理解していだだけたでしょうか？

ここからはvscodeへのprettierの導入について解説します。

### 手順1：拡張機能の検索欄でprettierと入力しインストール

まずは、インストールです。
vscodeの拡張機能の検索欄に`prettier`と入力すると、一番上に`Prettier - Code formatter`というものが出てくるので、それをインストールします。
![スクリーンショット 2020-11-29 21.29.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/95fafbda-efb6-6c78-bf4a-6177ec3a5b7e.png)

インストールが完了すると、以下の画像のようにアンインストール、無効にするなどのボタンが現れると思います。

![スクリーンショット 2020-11-29 21.32.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/6ab5a75f-8829-76e2-3202-a2ba4afcb528.png)

### 手順2：vscode側で「Format on save」の設定をする
次はvscode側の設定です。手順１でprettierは有効になっています。

まずは、`command + ,`または、`左下の歯車のマークの設定をクリック`

vscodeに関する設定項目がズラーっと並んでいると思います。検索欄の下にある`ユーザー`と`ワークスペース`はそれぞれ、`vscodeのどの開発でも適用する設定`と`ワークスペース、つまり現在のディレクトリのみの設定`という意味があります。

今回は`ワークスペース`を選択します。

その後、検索窓に`formatOnSave`と入力してください。
![スクリーンショット 2020-11-29 21.42.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/b6701010-1850-7410-2cf5-f7e6df058596.png)

`Editor:Format On Save`にチェックを入れます。

すると`.vscode`という名前のファイルが自動生成される(他の設定を既に行っていたらあるかもしれません)ので、その中にあるコードを確認します。以下のようになっていればOKです。

```setting.json
{
  "editor.formatOnSave": true
}
```
これで導入は完了です🖐

## 参考

[prettier(公式)](https://prettier.io/)

[Prettierの導入方法
フロントエンド開発で必須のコード整形ツール](https://ics.media/entry/17030/)
Herokuにsshログインしてコマンドを実行する

以下のコマンドでHerokuにsshログインしてコマンドを実行できます。
your_app_name の部分は自分のHerokuアプリケーションの名前に変更してください。

```
heroku login
```

```
heroku ps:exec -a your_app_name
```

参考 
Key generation for Heroku deployments
https://github.com/laravel/passport/issues/267#issuecomment-392222152

自分の場合、ローカル環境ではLaravel passportの実装が上手く動いていたのですが、本番のHerokuでは上手く動作せず、sshログインしてコマンドを実行する事でエラーを解決することができました。
Java static修飾子

#１，static修飾子とは
クラスのフィールド変数やメソッドをそのクラス内で共有します。
staticがついているものはそのクラスが所有することになります。

#２，ソースコード

```java:Main.java
public class Main {

	public static void main(String[] args) {

		// static = modifier. A single copy of a variabole/method is created and shared.
		// the class "owns" the static member

		Friend friend1 = new Friend("hiro");
		Friend friend2 = new Friend("tato");
		Friend friend3 = new Friend("yoshi");
		Friend friend4 = new Friend("taka");

		System.out.println(Friend.numberOfFriends);

		Friend.displayFriends();

	}

}
```
>**static** がついているフィールド変数やメソッドはそのクラスで共有します。

```java:Friend.java
public class Friend {

	String name;
	static int numberOfFriends;

	public Friend(String name) {
		this.name = name;
		numberOfFriends++;
	}

	static void displayFriends() {
		System.out.println("You have " + numberOfFriends + " friends");
	}

}
```
Google App Scriptでセルの値を比較する

function myFunction() {

  var ss1 = SpreadsheetApp.getActiveSpreadsheet();
  var sheet1 = ss1.getSheetByName("s1");
  var data1 = sheet1.getRange(1, 1, sheet1.getLastRow(),1).getValues();
  var val1=data1[0].toString();
  
  
  var sheet1w = ss1.getSheetByName("s1");
  
  var ss2 = SpreadsheetApp.getActiveSpreadsheet();
  var sheet2 = ss2.getSheetByName("s2");
  var data2 = sheet2.getRange(4, 2, sheet2.getLastRow()-3,1).getValues();
  var val2=data2[0].toString();
  
  var sheet2w = ss1.getSheetByName("s2");
  
  /*
  if (val1==val2){
    console.log("same");
  }else{
    console.log("NG");
  }
  */
  
  var matched_flg ;
  
  for (var i = 0; i < data1.length; i++) {
    
    matched_flg=false;
    
      for (var ii = 0; ii < data2.length; ii++) {
                
        //console.log(data2[i]);
        
        if (data1[i].toString()==data2[ii].toString()){
          
          console.log("データ1:" + data1[i] + " データ2:" + data2[ii] + " " + "☆same") ;
          sheet1w.getRange(i+1, 4).setValue(true);
          sheet2w.getRange(i+4, 4).setValue(true);
          matched_flg=true;
          break;
        
        } else{
          
          console.log("データ1:" + data1[i] + " データ2:" + data2[ii] + " " + "☆different") ;          
          
        }         
      }
    
    if (matched_flg==true) {
      
      sheet2w.getRange(i+4, 4).setValue(true);     
            
    }
    
    
    
    //console.log(data1[i]);
  }
  

  
  /*
  console.log(val1==val2);
  console.log(val1===val2);
  console.log(data1[0].toString()==data2[0].toString());
  console.log(data1[0]===data2[0]);
  */
  
}
デザインパターン感想

##Java言語で学ぶデザインパターン

####はじめに
[java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030)という本で学んだ際に感じたことを書いていきたいと思います。完全に個人的な意見です。書籍に書かれている例などは色んな方がわかりやすく解説しているのでそちらを参考にしてみると理解が深まると思います。


####この本を読んで感じたこと
正直、初心者にとってこの本を読むことは非常に難しいと感じました。自分の場合、cakephpというフレームワークを使用しており、自分でクラスを作るなどしておらず、フレームワークの規約に沿って開発を行なっていた。そのため、抽象クラスやインターフェースの実装ということ自体どういうものなのか全く知らなかった。PHPで使用されているメソッドやパブリック、スコープなどの基本的な部分は業務を通じて学んでいったが、既存のシステムの改修を行なっていたため、クラスを新しく作るなど行なっておらず、コアファイルを見てどういう仕組みになっているのかということを意識せずにいた。[この記事](https://gtec-inc.co.jp/system/34_about_flamework)にも書かれているがフレームワークの規約などを覚えてもあまり意味がないと思う。業務に必要最低限の規約などは覚えていた方がスムーズに進めるので良いとは思うが、技術力の向上を求めるなら、フレームワークに使用されている思想や考え方などを学んでいく方がエンジニアとしてのスキルは向上すると思う。その思想や考え方というのはどのようなことかというものがデザインパターンの書籍で書かれているようなことだと思う。そして、この本の理解には非常に時間がかかるし、理解できたからといってすぐに使えるようになるものではない。しかし、このデザインパターンを意識してコードを考えるのと考えないのとではかなり差が出ると思う。

####最後に
自分もまだまだデザインパターンについて理解できておらず、意識して使えるようになるにはかなり時間がかかると思います。cakephpのフレームワークにどのデザインパターンが使用されているか考えているがまだわかっておりません。まだまだ勉強が必要みたいです！！


####参考文献
[java言語で学ぶデザインパターン入門](https://www.amazon.co.jp/%E5%A2%97%E8%A3%9C%E6%94%B9%E8%A8%82%E7%89%88Java%E8%A8%80%E8%AA%9E%E3%81%A7%E5%AD%A6%E3%81%B6%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3%E5%85%A5%E9%96%80-%E7%B5%90%E5%9F%8E-%E6%B5%A9/dp/4797327030)
[フレームワークの誤解とフレームワークから学ぶこと](https://gtec-inc.co.jp/system/34_about_flamework)
[PHPでインタフェースと抽象クラスを使う](https://qiita.com/nogson/items/e6575d6617f854ed6e25)
[人間が読んで理解できるデザインパターン解説](https://techracho.bpsinc.jp/hachi8833/2017_10_17/46071)
Pythonで音声ファイル（モノラル・ステレオ両対応）のスペクトログラム描画

Pythonで音声ファイルのスペクトログラム描画をしてみました。とてもよくあるパターンではありますが、モノラル・ステレオ両対応になっているのが特徴です。

後でも述べますが、スペクトログラム描画により、人間が話しているところと、無音もしくは人間の会話周波数と異なるノイズとを、一目瞭然で区別することが可能です。例えば、話者識別の教師データを作る場合など、スペクログラムを見ることで、やりやすくなるでしょう。

なお、音声分析にはlibrosaを使う場合も多いようです。

細かい説明はコードに書かれていますが、以下概要です。

+ pysoundfileでwaveファイルを読み込み
+ 冒頭5分のみ切り出し（必須ではありませんが処理速度の関係で時間を短くしました）
+ 高速フーリエ変換
+ 7kHz未満の周波数のみ切り出し（人間の音声は3.4kHz未満がほとんどで、7kHz未満でも高音質）
+ 音圧をdBに変換（相対dB）
+ 結果を、縦軸が周波数・横軸が経過時間とし、dB値によるカラーマップを、グラフ描画（ステレオだとCHごとにグラフ描画）

以下がコードです。

```Python
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
from scipy import signal as sg

# 入力はwavファイルであること（mp3等は入力前にツールで変換する）
x, fs = sf.read('sample.wav', always_2d=True)
x = x[:fs*300]   # 最初の5分間だけを分析する

# stftのパラメータ
nperseg = 256
noverlap = nperseg // 2
# ウインドウがぴったりと切り分けられるように入力配列の後ろを少し削る
# stftしたデータを逆stftをするときに、この前処理があると、変換逆変換でピッタリと戻る
rest_of_window = (len(x) - nperseg) % (nperseg - noverlap)
if rest_of_window > 0:
	x = x[:-rest_of_window]
# soundfileの形式をstftするには転置する
f, t, Zxx = sg.stft(x.T, fs=fs, nperseg=nperseg, noverlap=noverlap)

# 逆stftの式（今回は使わない）
#_, x = sg.istft(Zxx, fs=fs, nperseg=nperseg, noverlap=noverlap)
#x = x.T

# 人間の声を分析するため7kHz以上の高音はカット
f = f[f < 7000]
Zxx = Zxx[:,:len(f)]
# スペクトログラムを描画するために相対デシベルを求める
dB = 20 * np.log10(np.abs(Zxx))

# スペクトログラムの描画
channels = dB.shape[0]
fig, ax = plt.subplots(channels)
if channels == 1:
	ax = (ax,)  #チャネル1つの時はaxがスカラーなので調整
for i in range(channels):
	ax[i].set_title(f'CH{i+1}-Time-Frequency')
	ax[i].set_xlabel('Time(s)')
	ax[i].set_ylabel('Frequency(Hz)')
	ax[i].pcolormesh(t, f, dB[i], shading='auto', cmap='jet')
plt.subplots_adjust(wspace=0.5, hspace=0.5)
plt.show()
```

出力結果

![スクリーンショット 2020-11-29 21.39.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/156600/b0e86085-d429-b8d7-bb22-6b591a4434a9.png)

赤っぽいところが人が話をしている箇所、青っぽいところが無音です。会話なのか、会話ではないのかの区別は容易になりそうです。しかし、このグラフを人間が見ただけでは、話者の違いまでを判別するのは難しそうです。左右の短い話をしている人と、真ん中の長い話をしている人は、別人なのですが、その違いは、目で見てもわからないでしょう。