OmniAICreator/Qiita-1.07M huggingface dataset:
BitVisor Broadcom NICの受信遅延バグ修正

BitVisorの、BroadcomギガビットEthernetネットワークインターフェイスデバイス (以下bnx) のpara pass-through driver (drivers/net/bnx.c) には、デバイスが受信したデータがゲストオペレーティングシステムにすぐに届かないというバグがありましたが、2020年から2021年にかけて修正されています。修正は以下の3つあります。

- ステータスワードの扱いに関する修正
- 一度に扱う最大パケット数の上限をなくす修正
- 割り込みクリア後にレジスターのダミー読み取りを行う修正

これらの修正について紹介します。

# ステータスワードの扱いに関する修正

[BitVisor / Code / Commit \[bd8164\]](https://sourceforge.net/p/bitvisor/code/ci/bd8164e953b5f5f53af87f3a04acfaf28d8a95b9/)

bnxはRAM上にステータスワードを持つ特徴があります。このステータスワードには、受信データの到着、リンク状態の変化、エラー、の3つをビットで表していて、デバイスがセット、ソフトウェアがクリアすることになっています。

個人的な印象として、普通ならこういう情報はレジスターにあるものかなぁと思うのですが、レジスターアクセスが遅いのを嫌ったのかも知れません。しかし、デバイス側がDMAでこの情報を更新し (少なくともクリアされていないことを確認するための読み取りが毎回必要)、CPU側のアクセスとの競合もありますから、それはそれでトリッキーさがあって、どうなのかなぁと思います。

それで、修正前の実装では、それぞれビットがセットされていることを確認したら、その内容をチェックした後でビットをクリアしていました。例えば受信データが到着したことを確認したら、受信バッファーを見に行って、その後受信データ到着のビットをクリアしていました。これにはわかりやすい競合状態があって、それは、**受信バッファーを見に行っている間に次の受信データが到着したらどうなるか?** という話です。デバイスとしては受信を正しく終えてビットをセットし、CPU側は最新のデータを受け取らないままビットをクリアしてしまうということがありえて、この時の受信データがゲストオペレーティングシステムに届くのは、次の受信データ到着まで遅延されてしまっていました。

修正では先にクリアをするようにしています。さらにその、デバイス側との競合をできるだけ避けるため、lockも併用しています。クリアするというのは、メモリーから読み込む、論理積を取る、メモリーに書き込む、ですから、CPUが読み込みをしてから書き込みが始まるまでの間に、デバイス側がガリッと新たなビットをセットすれば、それはなかったことにされてしまうわけです。Lockによって、その間の他からのアクセスがされないようにすることを期待しています。やっぱり、このデバイスの仕様はいまいちだと思うんですけどね...

# 一度に扱う最大パケット数の上限をなくす修正

[BitVisor / Code / Commit \[f213af\]](https://sourceforge.net/p/bitvisor/code/ci/f213afc9f77b3dec3bcd953839dde4c774ef1690/)

これは、もともとどうして上限を入れていたかの理由はわからないのですが、16パケットずつしか転送しないように実装されていました。上に書いたステータスワードのクリアは、16個を超えるパケットが届いていたとしても実行されていたため、そのような状況では、新たな受信データ到着のたびに16パケットずつしかゲストオペレーティングシステムに届かない、という状態になってしまっていました。

他のネットワークインターフェイスデバイス用のpara pass-through driverではそのような上限を設定していませんので、それに合わせて上限をなくして解決しました。

# 割り込みクリア後にレジスターのダミー読み取りを行う修正

[BitVisor / Code / Commit \[587a85\]](https://sourceforge.net/p/bitvisor/code/ci/587a8521cb91892e3e7378084514ea195775cee2/)

これは、一見意味がないように見えるダミー読み取りの追加によって問題を解決したものです。

割り込みクリアというのは、CPUの割り込み処理が終わったことをデバイス側に通知することを指します。割り込み要求を出したデバイスは、割り込みクリアが来るまで次の割り込み要求を出しません。レベルトリガー割り込みを用いているデバイスには一般的に存在する概念です。

もともと、割り込みクリア後に受信バッファーをチェックする実装を入れてあります。これは、上に出てきた、**受信バッファーを見に行っている間に次の受信データが到着したらどうなるか?** という話のためです。行き違いでCPUが受信しそこねたデータが残る時には、別の割り込みを出してくれよ、ということです。

で、問題は、割り込みクリアはレジスター書き込みによって行われる、というところにあります。レジスターはキャッシュ禁止領域にありますから、CPUとしては、書き込みサイクルが終了するまで次の命令の実行には移りません。ISAバスの時代ならそれで話は終了なのですが、今はPCI Expressバスです。CPUの書き込み要求は、PCI Expressバスのブリッジを経由し、シリアライズされてデバイスに届きます。そうすると... どうやら、デバイスに届く頃にはCPUの書き込みサイクルは終了してしまっているようなのです。

それで何が起きるかというと、CPUとしては割り込みクリアしたつもりで受信バッファーを見に行きます。同時に、デバイスとしては割り込みクリアされていないつもりで受信バッファーを更新し、割り込み要求を出しません。実際にこのような事象が発生し、この時の受信データがゲストオペレーティングシステムに届くのは、次の受信データ到着まで遅延されてしまっていました。

ダミー読み取りでは何が起こるかというと、読み取り要求がPCI Expressバスのブリッジを経由していくのは書き込みと同じですが、デバイスがその読み取り要求に応答するまでCPUは動けません。CPUが動けるようになった時には、その前の書き込み要求が確実にデバイスに届いていることになります。

IntelのギガビットEthernetでは、割り込みクリアの概念は一緒ですが、受信バッファーのhead位置をレジスターから読み取る必要があるため、この問題は発生しません。bnxは、ステータスワードとともに受信バッファーの情報もRAM上に置かれているため、こんな手間が必要になってしまっています。
エンコードと文字コードの違い

## 勉強前イメージ

似たようなことのような気がする・・・・

## 調査

### エンコード とは

データを規則に従って変換された情報のこと。
変換された情報のことを `エンコード`
変換することを `エンコーディング` と呼びます。

### 文字コード とは

`character code` とも呼び、
コンピュータ上でデータとして扱うために識別番号を与えて
区別できるようにした符号のことをいいます。
ASCIIコードだと7ビットのコード体系で、
例えばAでは1000001、zは1111010になり、データ列がわかっていれば
元の文字に変換することもできます。

### 要するに？

データを `符号(文字コード)` 化することを、 `エンコーディング` という、多分？

## 勉強後イメージ

だいたい一緒だと思ってたけど、
符号が文字コード
変えることをエンコーディング。

## 参考

- [エンコーディング](https://www.morisawa.co.jp/culture/dictionary/1902)
- [文字コードとは？エンコードとは？なぜ文字化けするのか？](https://kinopyo.com/ja/blog/what-is-character-set-and-encode)
はじめてWSL(WSL2) を使ってみたら思っていたより簡単にWindows上にUbuntu20.04LTS環境できたメモ

WSL(Windows Subsystem for Linux)については、数年前の記事でもあるので今更感はあるのですが、個人的にWindows上にLinux環境を構築するのは、VirtualBox + Vagrant で事足りていたため、WSLを使ってみる機会は一切ありませんでした。
少し前から、Docker Desktop for Windows の有償化に対して、どのように対応しているのだろうと調べていると、たまたまWSLというキーワードに辿り着きました。
しかしながら、初めて使ってみると思っていたよりも簡単に環境が出来たので、メモとして残しておきます。

### WSL
Windows Subsystem for Linux の略。
Virtualbox や Docker などの仮想化とは違い、Windows上でネイティブにLinuxを使えるようにする機能。
※実行可能なLinuxのディストリビューションは限られたもの

### 環境
![001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/524028a7-7180-95f7-b0e0-f0e6cbcbcfb7.png)

### インストール
Microsoft の WSL ページで解説されていますが、そのインストール方法も進化しているようです。
https://docs.microsoft.com/ja-jp/windows/wsl/install

以前の記事など見ていると、以下のようなコマンドの実行が必要でしたが

```:前
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
```

現在は非常にシンプルなコマンドでインストールが出来るようになっています。

```:現在
wsl --install -d {ディストリビューション}
```

どのディストリビューションが使えるかは、以下で確認ができます。

```:ディストリビューションリスト
wsl --list --online
```
![002.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/d9baed47-f307-ef6b-3398-72cbd8763a1b.png)

今回は、Ubuntu-20.04 を入れてみました。
![003.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/d00842f3-17bb-bdf2-d11c-adaee31bbf58.png)

ダウンロードが完了すると、以下のような画面が表示されます。
これは既に Ubuntu-20.04 の画面になります。
![004.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/8468d678-611b-8e36-7b05-32208944d59a.png)

少し待つと、ユーザ名とパスワードを聞かれるので入力します。
※これはWindowsで使っているものと合わせる必要はないと書いてあります
![005.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/448bfe68-a427-7112-ddb5-ee2a2d1e006d.png)

少し待つと、操作可能になります。ここまで5分もかかりませんでした。
以下のように、Ubuntu-20.04 が操作できるようになっています。
![007.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/40755213-458a-9a69-b2b5-3f7ae1b97fc6.png)

### WSL のバージョンを変更する
Powershell 側で確認してみると、バージョン１でした。
![008.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/f7f5e791-d976-a4a5-c31b-32499862b7bc.png)

せっかくなので、バージョン２に上げてみます。

```:wslバージョン1->2
wsl --set-version {ディストリビューション} 2
```

エラーになってしまいました。カーネルコンポーネントの更新が必要とのこと。
![009-2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/9324e92a-a2af-bfe3-2e21-5e806f043ae0.png)

エラーメッセージ内で提示されたURLからダウンロード、インストールします。
![010.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/adaf0544-8597-061e-b3a5-61dbd8228fda.png)

インストール完了後、改めてバージョン２に上げることが出来ました。
![011.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63951/59ed582e-d7b4-11b9-c031-2e8cddb03f8a.png)

### Hyper-V について
ネット上の一部情報では、インストール時に Hyper-V を有効にする手順が書かれていたりしたので、有効にしていましたが、
1.Hyper-V はハードウェアの仮想化を提供する機能である
2.WSL は仮想化とは違う機能
という観点から、Hyper-V は不要と判断し、無効化しました。今のところ問題なく動作しています。

### 感想など

- WSL まったく使ったことがありませんでしたが、初めてでも非常に簡単にLinuxディストリビューションを起動することが出来ました（慣れてなくても 5分ほど）
- 仮想環境上で動作させているわけではないので、軽快に動作しそう。
- Virtual box や Vagrant を使うのには抵抗があっても、この方法であれば、より気軽にLinux環境を試すことが出来そう。
- ただ、GUI で動かしたいとなったときは、ひと工夫が必要そう。
- VSCodeのプラグインを使えば、開発環境として使えそう。
- Docker Desktop for Windows の有償化をきっかけに、WSL で Linux 環境を構築して、Docker を使ってみるというケースも見受けられる(自分が興味を持ったきっかけもコレ)
Vue.js　基本編　備忘録(自分用）

#メリット
　・学習コストが低い。
　・Ver2からは仮想DOMを使用していて、レンダリングのパフォーマンスがいい。
　・Nuxt.jsを使用すれば、SPA開発も簡単。

仮想DOMとは？
`Document Object Model (DOM) は HTML や XML 文書のためのプログラミングインターフェイスです。ページを表現するため、プログラムが文書構造、スタイル、内容を変更することができます。 DOM は文書をノードとオブジェクトで表現します。そうやって、プログラミング言語をページに接続することができます。`
[DOM とは](https://developer.mozilla.org/ja/docs/Web/API/Document_Object_Model/Introduction#what_is_the_dom)

#Vueを使う時意識するべきことおいうこと
画面を作っているのは。DOMではなくてJavaScriptであること。
何で`データバインディング`という、データと描画を同期させる機能が存在していて、中身のデータを変えるだけで簡単に内容を変更画できる。専用の属性を使用しており、`v-`から始める。例`v-if,v-bind,v-key`など。
なので、`v-`から始めっていれば、データバインディングの属性、それ以外はただの文字列と考えても最初は大丈夫。
Vue.jsでアプリ開発

# 概要
Vueの使い方をアプリを作成しながら学んだ時のメモ
プロジェクトを作成してブラウザで確認するところまでを記述します。  
## プロジェクトの作成  
```
vue create プロジェクト名
```
プロジェクトを作成する際に、作成に必要な情報を設定するよう求められるので選択  

* プリセットの指定  

```
Vue CLI v4.5.15
? Please pick a preset:
> default
  Manually select features
```
プロジェクトで必要なプログラムを選択します。  
上下の矢印キーで選択してEnterを押してください。  
Manualを選択すると組み込む項目が表示されるのでスペースで選択します。

* Vueのバージョン選択  

```  
Vue CLI v4.5.15
? Choose a version of Vue.js that you want to start the project with:
> 2.x
  3.x
```  
使用するVueのバージョンを選択します。　　　


* linter/formatter設定の選択  

```
? Pick a linter / formatter config:
> ESLint with error prevention only  
  ESLint + Airbnb config
  ESLint + Standard config
  ESLint + Prettier
```
Lintとformatternいついて設定します。
デフォルトで良い場合は一番上を選択してください。

* Lintの追加機能の設定  

```
? Pick additional lint features:
> Lint on save
  Lint and fix on commit
```
Lintの追加機能について設定します。  
デフォルトで良い場合は一番上を選択してください。

* 設定情報の記述場所  

```
? Where do you prefer placing config for Babel, ESLint, etc.?
> In dedicated config files
  In package.json
```
設定した情報の記述場所を指定します。
デフォルトだと設定ファイル内に記述します。

* プリセットとして保存  

```
? Save this as a preset for future projects?(y/N)
```  
yを選択すると設定が保存されて次回以降設定する手間が省けます。  

## プロジェクトの実行  
```
npm run serve
```
実行するとWebブラウザからアクセスできるようになります。
`http://localhost:8080/`にアクセスして表示されるか確認してください。
2021年12月 Hololens第一世代の最新環境を作る

公式
https://docs.microsoft.com/ja-jp/windows/mixed-reality/develop/install-the-tools#installation-checklist
によれば、Hololens第一世代は、
Unity2017、2018、2019
VusualStudio2017、2019
の組み合わせで開発可能となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/9d8b0782-c428-419c-ae72-6a0b9d9524a8.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/a3179387-6138-eef9-cd39-4691d370abed.png)

なるべく最新の環境で作業する方が良いだろうとUnity2019とVisualStudio2019で構築し出したのですがこれが全くどうにもならない・・・・。
3日間の試行錯誤で、Unity2019とVisualSuudio2017でBuildとエミュレータの動作が出来たので過程をまとめます。

・Unity
今更2017でもないし、LTSが切れた2018もなぁと言うことで2019で。インストールしたのは
Unity2019.4.29.f1
Unityはこれを決め打ちで環境を整備していきました。
追加モジュールとして以下画像の2つをインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/a46445ea-d1a4-1c93-1b45-cba397454881.png)



・VisualStudio
公式にも記載がありますが、まず2015がインストールされていることが前提になります。
公式では、2019で動くことになっていますが、ダメだったので私の場合で書いていきます。

1)まずVisualStudio2017をインストールします。
以下のコンポーネントを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/4a7dc7ba-0794-aa2c-96db-c736f6fd1799.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/661ce1b1-48fb-48a1-5b49-e4f4ad98db4c.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/b34758f2-806a-2907-a6a9-ed9e3ab77ace.png)

2)以下の個別コンポーネントを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/50760f22-b411-255a-7c5d-30d4f01683d9.png)

・これで動くはずが
以下の設定でUnityでbuildしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/7f5708bf-2932-2e8a-162f-1f1fa7be49c9.png)

これをVisulaStudio2017で開くと、「Debug」「X86」を選択しても、その次が「開始」しか選べません。実はこの時点でエミュレータも入れているので、デバイスとエミュレータは選べないとおかしいのですが困った。

で、いろいろ試した結果この次にVisualStudio2019をSDK類無しでインストールします。
VisualStudio2019をインストールした状態で、VisuauStudio2017を開くとあら不思議、デバイスをエミュレータも選べます。謎of謎。

・Hololensエミュレータ
これが曲者で、第一世代最新のエミュレータはUnity2019とVusualStudio2017の組み合わせでは動きません。
動くのは、Version10.0.14393.0です。これ以降の新しいものはVisualStudio2019用？なのか動きませんでした（OS起動画面は出るがいろいろとエラー出したりそのまま何も起動しなかったりする）。
また、インストールする順番もVisualStudio2017をインストールした後にインストールしてください。事前にインストールしておくと認識されません。


いろいろ細かな知見も得られたのですが、動いてしまえばこっちのもので以上苦労の末編み出した組み合わせでした。
Hololens第一世代は中古価格がこなれてきてるので、この機会にぜひHappy Hololens Lifeを！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/d561d866-bd27-e873-4bd1-fe6446977978.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201026/c3a693c5-e5e6-98cc-3fae-00c6541c9327.png)
githubのURLが本当に存在するかシェルスクリプトから確認する

githubのURLが本当に存在するかシェルスクリプトから確認する際の備忘メモ

`git ls-remote`を使えばOK、
結果は直前に実行したコマンドの結果である`$?`の値から判断可能

```bash:成功する場合
$ git ls-remote https://github.com/mozillazg/pypy
69c2f6b75bbd409ccddea9d88e58d1410c0b9859	HEAD
f8a2f37e91b7871322243a8df432f5fdc2b3d4e6	refs/heads/0.6.1/tip
...
$ echo $?
0
```

```bash:失敗する場合
$ git ls-remote https://github.com/mozillazg/pypyaaaaaaaaaaaaaaaa
remote: Repository not found.
fatal: repository 'https://github.com/mozillazg/pypyaaaaaaaaaaaaaaaa/' not found
$ echo $?
128
```

ブランチの存在も確認したい場合は以下を参照
> [`git ls-remote`でブランチの存在も確認したい](https://qiita.com/seigot/items/d75d1eebb1f3212bac64)

#参考

https://www.webdevqa.jp.net/ja/git/%E3%83%AA%E3%83%A2%E3%83%BC%E3%83%88git%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AAurl%E3%81%AE%E6%9C%89%E5%8A%B9%E6%80%A7%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95%E3%81%AF%EF%BC%9F/942278939/
VisualStudioでライブラリがうまく読み込めなかったらやってみること覚書

## 当時の環境メモ
VisualStudio: バージョン確認できてないけど最新版ではなかった
.Net Framework: .NetCore3.1
## 現象
Yarp.ReverseProxy：1.0.0(最新の安定版)
👆を使用しているソースコードをクローンしてきたところ、エラーが出た。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2410508/9f42d705-4ccd-9729-27bb-2da5b147bfac.png)
読み込んでいるライブラリをF12で確認してみると、ProxyRequestのメソッド自体はちゃんと存在していた。
また、VSCodeで開くとエラーが表示されなかったので、エラーの原因はVSだと推測。
## 原因
VisualStudioのバージョンが古かったので、バージョンを上げたら読み込まれるようになった。今は16.11.8。
## 上記以外でやってみること
1. NuGetのキャッシュをクリアする
`C:\Users\ユーザー名\.nuget\packages`の中身をクリア
再度slnファイルを開くと、自動で再構成してくれる。
1. NuGetでライブラリをアンインストール→インストール
1. Cloneしなおす
Django Docker-compose メモ

#作成するファイル(3つ)
Dockerfile
requirements.txt
docker-compose.yml

Djangoプロジェクト作成(上記同一フォルダにて下記コマンド実行)

#Django project app 作成

Djangoプロジェクト作成(上記同一フォルダにて下記コマンド実行)

```
docker-compose run --rm web django-admin.py startproject mysite .
```

Djangoアプリ作成(上記同一フォルダにて下記コマンド実行)

```
docker-compose run --rm web django-admin startapp myapp;
```

#実行コマンド

```
docker-compose up
```


複数Dockerコンテナを起動(動作確認)
setting.py
ALLOWED_HOSTS = []を
ALLOWED_HOSTS = ["*"]に変更(Dockerを動かしているホストの名前、IPアドレス)





```
settings.py
INSTALLED_APPS = [
    ......,
    myapp, #アプリ名
]
```

```
project/urls.py
urlpatterns = [
    ......,
    path('myapp/', include('myapp.urls')),
]
```

```
app/urls.py
urlpatterns = [
    ......,
    path('', TopView.as_view(), name='home'),
]
```

->view.py->templates/myapp/home.html

#form.py

```
from django import forms

class SendUrlForm(forms.Form):
    url_contents = forms.CharField(
        label='SendUrl',
        widget=forms.Textarea(attrs={'cols': '80', 'rows': '1'})
        )
```

```
views.py

self.params = {
            ......,
            'form_send_url':SendUrlForm(),
        }
```

herokuデプロイ用データベース設定

```
settings.py

DATABASES = {
　　　　　　　　　　　　　　　　・・・・・・
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
　　　　　　　　　　　　　　　　・・・・・・
    }
}
```

herokuchromedriver使用メモ

```
requirements.txt
Chromedriver-binary
```
C#でKagglerに話題のLightGBMを使ってタイタニック号の生存者予測をしてみた


## はじめに
Kaggleや機械学習といったらPythonのイメージが強いですがC#でも機械学習が出来る[ML.NET](https://docs.microsoft.com/ja-jp/dotnet/machine-learning/)とC#の開発元であるマイクロソフト社が開発した[LightGBM](https://ja.wikipedia.org/wiki/LightGBM)を用いておなじみのタイタニック号の生存者予測をやってみました。

## 環境
- .NET 6
- Microsoft.ML
- Microsoft.ML.LightGbm

## コード
https://github.com/q0v0p/LightGBM-for-Titanic

## 内容
データは[Kaggle](https://www.kaggle.com/c/titanic)のものを使用しています。なるべく簡単でわかりやすい実装にするために[TrainTestSplit](https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.ml.dataoperationscatalog.traintestsplit?view=ml-dotnet)を使ってtrain.csvからtrainデータとtestデータを作成しています。

性別（Sex）と乗船港（Embarked）をOneHotエンコーディングしてるくらいで年齢（Age）の処理を入れていなかったり、特徴量すべて使っていないですしハイパーパラメータのチューニング等の最適化も行っていないのであくまで流れを理解するための実装になっています。（Kaggleに挑戦する、運用環境で利用するなどであればチューニングが必要になります）

```csharp
var mlContext = new MLContext(seed: 0);

var trainingDataView = mlContext.Data.LoadFromTextFile<Passenger>(_trainDataPath, hasHeader: true, separatorChar: ',');
var splitData = mlContext.Data.TrainTestSplit(trainingDataView, testFraction: 0.2);

var options = new LightGbmBinaryTrainer.Options
{
    LabelColumnName = "Label",
    FeatureColumnName = "Features",
    Booster = new GossBooster.Options
    {
        TopRate = 0.3,
        OtherRate = 0.2
    }
};

string[] categoryFeatureNames = { "Sex", "Embarked" };
var survivedMap = new Dictionary<string, bool> { { "1", true }, { "0", false } };

var pipeline = mlContext.Transforms.Conversion.MapValue("Label", survivedMap)
    .Append(mlContext.Transforms.Categorical.OneHotEncoding("Sex", inputColumnName: categoryFeatureNames[0]))
    .Append(mlContext.Transforms.Categorical.OneHotEncoding("Embarked", inputColumnName: categoryFeatureNames[1]))
    .Append(mlContext.Transforms.Concatenate("Features", new[] { "Pclass", "Sex", "SibSp", "Parch", "Fare", "Embarked" }))
    .Append(mlContext.BinaryClassification.Trainers.LightGbm(options));


var model = pipeline.Fit(splitData.TrainSet);

var transformedTestData = model.Transform(splitData.TestSet);

// Convert IDataView object to a list.
var predictions = mlContext.Data
    .CreateEnumerable<TitanicPrediction>(transformedTestData, reuseRowObject: false).ToList();
```

## 感想
PythonでLightGBMをよく使っていたのでその凄さは理解しているんですが、個人的にC#のアプリケーションを作ることも多いのでうまく取り込めないかなーって考えながら探していたらC#の機械学習ライブラリML.NET上でLightGBMが実装されていたので早速試してみました。

マイクロソフト社が作ってるC#とLightGBMの組み合わせはC#erとして試してみなければと思い実装しました。

触ってみた感想としては、慣れると流れが理解しやすいですがやはりPythonと書き方が大分異なるので慣れるまで時間は掛かるかもです。そしてML.NET自体のアップデートも頻繁でネット上に上がっている書き方だとうまくいかないところが多い印象でした。

あとMicrosoftのエンジニアが回答していたのですがLightGBM(ML.NET版)でもGPUが利用できるアップデートを行っているようなのでその点もわかってきたらそのうち記事にするかもです。

皆様もC#で機械学習を楽しみましょう！

## 参考
https://qiita.com/koshian2/items/dba923672219515d128f
https://github.com/seosoft/Titanic_MLNet
https://docs.microsoft.com/ja-jp/dotnet/api/microsoft.ml.lightgbmextensions.lightgbm?view=ml-dotnet
firebase deployで Failed to get Firebase projectというエラー

## 課題

```
firebase deploy
```
をしたら以下のエラーが出た

```
Error: Failed to get Firebase project 〇〇. Please make sure the project exists and your account has permission to access it.
```

## 1行で解決する

ログインしなおしましょう！！

```
firebase logout && firebase login
```
シェルスクリプト中の変数の空白を置換する

シェルスクリプト中の変数の空白を置換する際の備忘メモ

以下のような変数がある場合


```bash\
STR="2021/12/29 3:06:54"
```

以下のような書式を用いることで、空白を置換できる（例：アンダーバーに置換する場合）

```bash:test.sh
STR="2021/12/29 3:06:54"
STR2=${STR//" "/"_"} 

echo ${STR}
echo ${STR2}
```

実行結果をみるとちゃんと置換できている

```bash
$ bash test.sh
"2021/12/29 3:06:54"
"2021/12/29_3:06:54"
```

# 参考

https://eng-entrance.com/linux-shellscript-replacement
[Rails]オブジェクト指向とは 3行で要約

#はじめに
**オブジェクト指向は概念**
なので明確な答えはない
大事なのに答えはないという
例えて言うならば　<font color="red">愛</font>　みたいな物

#オブジェクト指向を簡単に言うと
```
同じようなプログラムを1か所にまとめてコードを再利用しやすくする仕組み
他のプログラムからできるだけ変更できない仕組み
継承したコードの一部を変更して利用するための仕組み
```

下記URLに詳しく書かれています。
[オブジェクト指向とは](https://robo-done.com/blog/2021/04/doneship_object_oriented/)

#終わりに
実際にプログラミングしながら理解を深めることが1番大事だと思った。
この記事自体もアップデートしてさらに分かりやすくしていきます。
Excelで同列前行の値+1の数式

```
=INDIRECT(ADDRESS(ROW()-1,COLUMN()))+1
```
行の挿入削除に耐えられる

これを応用して同列前行の値と同じならフォントの色をグレーにするような条件付き書式を作ったりもできる
```
=INDIRECT(ADDRESS(ROW()-1,COLUMN()))=INDIRECT(ADDRESS(ROW(),COLUMN()))
```
Svelteのimport文で絶対パスを使えるようにする

※ [この記事](https://zenn.dev/yutaro_matsu/articles/c3cf02eb285f4f)の方法のほうがシンプルでよさそう（SvelteKit限定？）
※  ほとんど[こちらの記事](https://dev.to/sjafferi/absolute-paths-in-svelte-488c)の意訳です。

# やりたいこと
コンポーネントをimportするときのパス指定を、絶対パスで書きたい。

**ありのままのSvelte**

```JavaScript:.svelte
import Component  from "../../../../components/Component.svelte";
```
（読み込みたいファイルと、読み込むファイルが離れれば離れるほど、パス指定が面倒になる。）

**理想のSvelte**

```JavaScript:.svelte
import Component from "components/Component.svelte";
```

# やりかた


### `@rollup/plugin-alias` をインストールする

```:Terminal
npm install @rollup/plugin-alias --save-dev
```

### `rollup.config.js`で読み込む
（`rollup.config.js`は、Svelteプロジェクト作成時に自動的に生成されているハズ）

```JavaScript:rollup.config.js
import alias from '@rollup/plugin-alias';
```

### `rollup.config.js`に絶対パスの定義（ルール）を書き込む

```JavaScript:rollup.config.js
const aliases = alias({
  resolve: ['.svelte', '.js'], // どの拡張子のファイルでこのルールを有効にするか
  entries: [
    // find: 絶対パスの書き方 // replacement: その書き方で、どのフォルダを指すか
    // 以下は参考例です。
    { find: '', replacement: 'src/' },
    { find: 'components', replacement: 'src/components' },
  ]
});
```

### `rollup.config.js`の`export default`に追記する
`export default`自体はすでに書き込まれていて、
`input`、`output`、`plugins`などの項目が既に存在しているハズ。

その`plugins`の配列の中に、さきほど定義した`aliases`を追加してあげる。

```JavaScript:rollup.config.js
export default {
  input: ...
  output: ...
  plugins: [
    aliases, //←これを追加する。
    //以下略
```


これで絶対パス指定ができるようになりました。
めでたしめでたし。
#AVD 上の #MicrosoftTeams のメディアがリダイレクト可能な端末一覧 （2021年末版）

みなさま、大変遅くなりまして本当に申し訳ありません・・・(´；ω；`)

[Office 365 Advent Calendar 2021](https://adventar.org/calendars/6679) の記事でございます

およそ1年半ほど前、Azure Virtual Desktop が登場したときの記事
[Teams WVD Media が有効にならないパターンをまとめてみた](https://qiita.com/rnakamuramartiny/items/904b5f8a3966bf6a598b)の続きとなります。

# AVD Media

あれから1年半経ち、Windows 365 も出てきたりといろいろ改善されていく Microsoft 純正の VDI サービス。

Azure Virtual Desktop には、AVD Media という機能があり、Microsoft Teams の映像や音声データのみを、直接端末とデータ通信可能な仕組みがあります。


**AVD Media 未使用の通信の場合**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/aa39dfd2-9655-15a7-914c-6c1be5cc3d14.png)

**AVD Media 使用中の通信の場合**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/6380c941-7206-d74c-b1ec-a6a85c5e2a55.png)

また、AVD Media が使えない場合は、端末のカメラを使うことができません。

# AVD Media が使用可能な端末

|端末名|搭載OS|CPU|ブラウザ|専用クライアント|
|:--|:--|:--|:--:|:--:|
|ゲーミングマシン|Windows 11|Core i7|×|〇|
|VAIO|Windows 10|Core i5|×|〇|
|OneMix2S|Windows 10|Core m3|×|〇|
|Surface Go|Windows 11|Pentium|×|〇|
|Macbook Pro M1|MacOS 12.1|M1|×|**〇**|
|iPad 2019|iPad OS 15.2|A10|×|**〇**|

# 注目すべきはやっぱりここ

そう、MacやiPadに対応しているのです！
（今の所プレビューなので、正式対応しているわけではありません）

なので、Mac や iPad 上でも会社のVDIとしてWindows環境が使えるようになっているだけでなく、そのまま Teams を使って会議に参加したり、画面共有することも可能になっているのです！

## Macの場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/1ae224a7-06a4-7712-b0ae-3e2a551575c2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/8ff935b7-b48f-f725-427c-c77131ace149.png)

## iPadの場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/9b278184-d51a-b78c-151f-bd89bfa71e07.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/269159/ae1de82e-92b1-425c-9c1f-04eb4ee00d9e.png)

# まとめ

特にiPadの場合、Teams自体はアプリ上で使うことができますが、画面共有しているとカメラが消えてしまったり、画面共有中に操作を参加者に依頼するということができませんでした。
しかし、Azure Virtual Desktop を使えば、iPadからでもTeamsを Windows PCで操作しているのとほとんど変わらずに使用することができるようになります！
2022年もテレワークが引き続き続いていきますが、iPad と Azure Virtual Desktop という組み合わせで、セキュリティの高いテレワーク端末を作っていくのも良いかと思います！
Tidymodelsによる機械学習を学ぶ(2) お手軽線形回帰篇

## はじめに

機械学習ライブラリといえばPythonのsklearnがスタンダードで、RのcaretがRユーザーの中で細々と使用されているというイメージを持っていました。

ところが、近年になって登場したtidymodelsが強力であるという噂を聞きつけ、素人データ屋を脱却すべくtidymodelsの使用方法について調べてみました。特に難しいことは考えず、お手軽にサクッとやってしまいます。

## 方針
Max Kuhn & Julia Silge (2021) の第6章にあるデータ解析「 `ames` データセットの `Sale_Price`　を対数変換し `Longitude` と `Latitude` で線形回帰する」を手元で実行します。筆者らは`recipie`と`workflow`を用いないコードを紹介していますので、ここでは新たに`recipie`と`workflow`を用いたコードで計算し、筆者らと同じ結果が得られるか確かめたいと思います。

## データ分析

### (1) ライブラリとデータセットのインポート
```r
library(tidymodels)
data(ames)
```

### (2) データ分割
全データの80%をTrain、残りをTestとします。

```r
set.seed(123)
ames_split <- initial_split(ames, prop = 0.8, strata = Sale_Price)
ames_train <- training(ames_split)
ames_test <- testing(ames_split)
```

### (3) ワークフローの設定

`recipe` (前処理系)と `model` (モデル系)を定義し、一つの `workflow` とします。前処理として`Sale_Price`を対数変換しました。

```r
# recipe
rec <- recipe(Sale_Price ~ Longitude + Latitude, data = ames_train) %>%
  step_log(Sale_Price, base = 10)

# model
lm_model <- 
  linear_reg() %>%
  set_engine("lm")

# workflow
lm_model_wf <- workflow() %>%
  add_recipe(rec) %>%
  add_model(lm_model)
```

### (3) ワークフローをデータに当てはめ
```r
lm_model_res <- lm_model_wf %>%
  last_fit(ames_split)
```

### (4) 結果の確認

##### (4-1) 回帰係数
求まった回帰係数が教科書の結果と同じか見てみましょう。

```r
lm_model_res %>%
  extract_fit_engine() %>%
  summary() %>%
  coef()
```

```
               Estimate Std. Error   t value     Pr(>|t|)
(Intercept) -300.250929 14.5815154 -20.59120 1.022609e-86
Longitude     -2.013413  0.1296788 -15.52615 8.126177e-52
Latitude       2.781713  0.1816642  15.31239 1.639312e-50
```

教科書と同じ回帰係数が求まりました。

#### (4-2) 予測の確認

教科書ではRMSEなどの予測精度は求めず、予測値・実測値データを並べて結果としていましたので、ここでもそれに従います。

```r
ames_pred <- lm_model_res %>%
  extract_fit_engine() %>%
  predict(ames_test)

bind_cols(ames_test %>% select(Sale_Price) %>% log(10), pred = ames_pred)
```

```
# A tibble: 588 x 2
   Sale_Price  pred
        <dbl> <dbl>
 1       5.02  5.22
 2       5.24  5.22
 3       5.28  5.28
 4       5.06  5.24
 5       5.60  5.31
 6       5.33  5.31
```
教科書と同じ結果が求まりました。（95%区間も出す方法があるようなのですが、不慣れなせいかうまくいきませんでした）

## 引用文献
Max Kuhn & Julia Silge (2021) "Tidy modeling with R" Version 0.0.1.9010
Dockerのイメージの共有方法について

# はじめに

Dockerのイメージを共有する方法について調べたのでまとめる。

実現する方法は主に二つあるようです。

- Docker Hubを用いて共有する方法
- 圧縮ファイルを用いて共有する方法

業務上、秘匿情報を扱うことが多いので、Docker Hubを用いることに抵抗があります。そのため、Docker Hubを用いず、圧縮ファイルによる共有方法について説明します。

# 圧縮ファイルを用いて共有する方法

業務の流れとしては下記の手順を踏む。

- 手順 1. コンテナ上でアプリケーションの開発をする。
- 手順 2. コンテナからイメージを作成する。
- 手順 3. イメージから圧縮ファイルを保存する。
- 手順 4. 圧縮ファイルをアップロードする。
- 手順 5. 圧縮ファイルロードしイメージを作成する。
- 手順 6. イメージからコンテナを作成する。
- 手順 7. アプリケーションを実行する。

今回は、手順2、手順3と手順5について説明する。

手順２. コンテナからイメージを作成する。

```
$ docker commit コンテナ名 イメージ名:vxxx.xxx
```

手順 3. イメージから圧縮ファイルを保存する。

```
$ docker save イメージ名 > tarファイル名.tar
```

手順5.  圧縮ファイルロードしイメージを作成する。


```
$ docker load -i tarファイル名.tar
```

# 参照

- [docker commitコマンドの使い方](https://www.memotansu.jp/docker/626/)
- [Docker イメージをファイルでやり取りする](https://blog.amedama.jp/entry/2017/11/01/204637)
- [docker saveコマンドの使い方](https://www.memotansu.jp/docker/594/#toc7)
Laravel7以下向けパッケージ開発でSeederにFactoryを使う

## 対象
* Laravel5,6,7系向けのパッケージ開発を行おうと思っている人
* パッケージとしてデータベースにデータを登録する必要がある
* パッケージ開発自体はやったことがある

## 概要
* composer.json の autoload で seeder や factory を読み込むようにする
* factory をパッケージ側でロードする
* seeder で factory を利用する
* seeder を組み込み側で呼び出す

## 詳細

`Vendor`, `Package` のところはそれぞれ置き換える。
クラス名などはそれぞれ好きなように。
ディレクトリ構造も例であって、autoload やパスを正しく設定できれば好きな構造で問題ない。

### ディレクトリ構造
- database
    - factories
        - UserFactory.php
    - seeds
        - DemoSeeder.php
    - migrations
- src
    - ServiceProvider.php
    - Models
        - User.php

### autoload を有効にする
```composer.json
"autoload": {
    "psr-4": {
        "Vendor\\Package\\": [
            "src/",
            "database/"
        ]
    }
},
"extra": {
    "laravel": {
        "providers": [
            "Vendor\\Package\\ServiceProvider"
        ]
    }
}
```
特に重要なのは `"Vendor\\Package\\": []` で配列として渡しているところ。
大抵のパッケージだと `"Vendor\\Package\\": "src/"` としていることだと思う。

### factory のディレクトリを読み込ませる
```ServiceProvider.php
namespace Vendor\Package;
use Illuminate\Database\Eloquent\Factory;
public function boot(): void
{
    $this->app->afterResolving(
        Factory::class, 
        function ($factory) {
            $factory->load(__DIR__ . '/../database/seeds');
        }
    );
}
```

### seeder で factory を使う
```Seeder.php
namespace Vendor\Package\Database\Seeds;
use Vendor\Package\Models\User;
class DemoSeeder extends Seeder
{
    public function run()
    {
        factory(User::class, 5)->create();
    }
}
```

### 組み込み側で seeder を使う
```cli
composer dump-autoload
php artisan db:seed --class=Vendor\\Package\\Database\\Seeds\\DemoSeeder
```

> Database seeding completed successfully.

となれば完成！
Macでマイクの音量が勝手に上がる現象を解消してみた

MacでGoogle Meetを使用しているときに、マイクの音量が勝手に上がってしまう現象が発生していることがわかりました。
これはGoogle Chromeを使用している場合に発生するようです。

自分の環境は以下です。

- Mac OS 10.15.7
- Google Chrome 96.0.4664.110

これを解消すべくAppleScriptでプログラムを作り、この問題を解消しました。
しかし、この記事を書く前にふとQiitaを見るとなんとこちらの記事に、Chrome拡張機能を追加することで解決できるとの旨が記載されていたのです！

https://qiita.com/lobmto/items/b78c726d1ab3ec2a6979

Chromeにはマイクの自動調節機能があるらしく、それが原因で勝手に上がっていたようです。
この拡張機能を追加することでマイクの音量が勝手に上がらなくなりました。

ただせっかくプログラムを作ったので備忘録を兼ねて記載しておきます。
将来的に拡張機能が使えなくなった場合に使えるかもしれないので…

# 解説

スクリプトエディタを起動し、以下のコードを追加します。

```AppleScript:mic_setting
-- 音量しきい値
property VOLUME_THRESHOLD : 50
-- 何秒ごとに実行するか
property DELAY_SECOND : 5

on idle
	
	set inputVolume to input volume of (get volume settings)
	-- マイクの入力音量をダイアログ表示（確認用）
	-- display dialog inputVolume
	
	if inputVolume > VOLUME_THRESHOLD then
		set volume input volume VOLUME_THRESHOLD
	end if
	
	return DELAY_SECOND
end idle
```

ファイル→書き出すを選択し、ファイルフォーマットを「アプリケーション」に、オプションで「ハンドラの実行後に終了しない」にチェックを入れて保存します。

![スクリーンショット 2021-12-28 18.52.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/154305/1e4c7acf-6e77-5324-06cd-148d8dc9844e.png)

生成されたアプリケーションを実行することで、例示したコードでは5秒ごとにマイク音量を調べ、しきい値以上の場合はしきい値まで音量を下げます。

# 参考
https://ameblo.jp/bit287/entry-11151999235.html
jqでjsonデータ中の配列の要素数を数える

以下のようにするとOK

```bash
$ jq .values test.json | jq 'length'
6
```

`test.jsonは以下の通り`

```json:test.json
{
  "range": "sheet1!A1:I106",
  "majorDimension": "ROWS",
  "values": [
    [
      "aaa",
      "test"
    ],
    [
      "bbb",
      "test"
    ],
    [
      "ccc",
      "test"
    ],
    [
      "ddd",
      "test"
    ],
    [
      "eee",
      "test"
    ],
    [
      "fff",
      "test"
    ]
  ]
}
```

# 参考

https://www.bioerrorlog.work/entry/count-json-items-in-linux
C ++でのfloatの解析：strtodとfrom_charsのベンチマーク

転載元（英語原稿）：
https://lemire.me/blog/2020/09/10/parsing-floats-in-c-benchmarking-strtod-vs-from_chars/


プログラマーは、文字列を浮動小数点数に変換する必要があることがよくあります。たとえば、文字列「3.1416」を取得し、結果の値を浮動小数点型として取得したい場合があります。

C/C++では、標準的な方法はstrtod関数です。

```C++
char * string = "3.1416";
char * string_end = string;
double x = strtod(string, &string_end);
if(string_end == string) { 
  //you have an error!
}
```

残念ながら、strtod関数は、これらの文字列処理関数の多くと同様に、ロケールに依存します。これは、コードを実行するシステムによって動作が異なる可能性があることを意味します。ただし、すべてのランタイムライブラリには、strtod_lや_strtod_l（Windows）などのロケール固有の関数があるようです。これらのロケール固有の関数を使用して、デフォルトのロケールを指定し、すべてのシステムで同じように動作する関数を取得できます。

strtod関数の優れた機能の1つは、解析された数値の最後にポインターを返すことです。このようにして、たとえば、コンマ区切りの数値のシーケンスを効率的に解析できます。

C++ストリームを使用することもできますが、通常はパフォーマンスを対象としていません。

C++17では、より優れたオプションであるfrom_chars関数が提供されました。同様に機能します。

```C++
std::string st = "3.1416";
double x; 
auto [p, ec] = std::from_chars(st.data(), st.data() + st.size(), x);
if (p == st.data()) {
      //you have an errors!
}
```

ている点は、定義上、ロケールに依存しないことです。さらに、標準化されているため、どこでも利用できるはずです。残念ながら、私の知る限り、完全に実装されたfrom_chars関数が付属しているC ++コンパイラはVisualStudio2019だけです。最新のリリースが必要です。

確かに、C++17はしばらくの間リリースされており、多くのコンパイラがそれを完全にサポートしていると主張していますが、ランタイムライブラリは追いつく必要があります！もちろん、独立したfrom_chars実装を取得することもできますが、ランタイムライブラリがC ++ 17をすぐにサポートしてくれると便利です。

それでも、マイクロソフトが正しいことを行い、最新の標準を熱心にサポートしていることを祝う必要があります。

Visual Studiofrom_charsについて良いことを聞きました。そしてとりわけ、それは非常に速いということです。

もっと早く知りたかった。だから私はベンチマークを書きました！[0,1]間隔で多数のランダム値を生成し、それらを解析して戻すのにかかる時間を記録します。

|stdtod（C）|120MB/s|
|::|::|
|**from_chars（C++17）**|**140MB/s**|

コストをかけずに、パフォーマンスが20％向上します。素晴らしい。
【mypy】データクラスである抽象基底クラスは、mypyに`Only concrete class can be given ～`というエラーで怒られる

# 環境
* Python 3.9.7
* mypy 0.920


# やりたいこと
データクラスである抽象基底クラス`Animal`を作りたいです。

```python:foo.py
import abc
from dataclasses import dataclass


@dataclass(frozen=True)
class Animal(abc.ABC):
    name: str

    @abc.abstractmethod
    def cry(self):
        pass


@dataclass(frozen=True)
class Dog(Animal):
    color: str

    def cry(self):
        print("ワンワン")


@dataclass(frozen=True)
class Bird(Animal):
    can_fly: bool

    def cry(self):
        print("ガーガー")


def main():
    dog = Dog(name="alice", color="blue")
    dog.cry()

    bird = Bird(name="bob", can_fly=False)
    bird.cry()


if __name__ == "__main__":
    main()

```

```
$ python foo.py
ワンワン
ガーガー
```


# mypyのエラーメッセージ
mypyで型チェックしたところ、以下のエラーメッセージが表示されました。

```
$ mypy foo.py
foo.py:5: error: Only concrete class can be given where "Type[Animal]" is expected
Found 1 error in 1 file (checked 1 source file)
```

# 原因
Stack OverFlowの質問によると、mypyのバグのようです。
>I gather from mypy issue #5374 that this is a bug in mypy, first noticed in 2018 and still not corrected.

https://stackoverflow.com/questions/69330256/how-to-get-an-abstract-dataclass-to-pass-mypy

https://github.com/python/mypy/issues/5374

# 暫定的な解決方法
`AnimalDataclassMixin`クラスをデータクラスをmix-inクラスとして定義して、`Animal`クラスはそれを継承するようにしました。
上記のStack Overflowの回答通りの方法です。


```python
@dataclass(frozen=True)
class AnimalDataclassMixin:
    name: str


class Animal(abc.ABC, AnimalDataclassMixin):
    @abc.abstractmethod
    def cry(self):
        pass
```


# 補足
mix-inクラスなのにメソッドが明示的に定義されていないのは、少し混乱するかもしれませんね。
以下、mix-inクラスの定義。
>MixinまたはMix-in（ミックスイン）は[1][2][3][4]、オブジェクト指向プログラミングで用いられる技法であり、他のクラスから使用されるメソッド群を持つクラスが、他のクラスのスーパークラスにならないで済むための、特別な多重継承関係を実現するためのメカニズムを意味している。Mix-inされたメソッドに、他のクラスがアクセスする方法はそれぞれの言語仕様に依存している。

https://ja.wikipedia.org/wiki/Mixin


`#type: ignore`で型チェックを無視するよりは良い方法ですが。
SSDSEがデータセットとして面白いよという話

（注）SSDSEの個人利用・記事化に関しては事前に問い合わせを行い、データの出典を明記すればOKとご返答をいただいています。



# はじめに

データ分析を勉強していて、何か面白いデータないかなあと考えたことはありませんか？

アヤメのデータセットとかはもう飽きたけど、ドメイン知識が必要なものは敷居が高いなあと感じ、自分のペースでいつでも可視化ができて、分析結果を考察する訓練ができるようなデータをかくいう自分も探していました。

今回は、ふと見つけた**SSDSE（教育用標準データセット）**というものが面白そうだったので紹介しようと思います。

# SSDSEって？？
SSDSEは、e-Stat（政府統計の総合窓口）に収録されている都道府県・市区町村のすがた（社会・人口統計体系）から作成されたデータで、分析の汎用素材として公開されているものです。このSSDSEを用いた統計データ分析コンペも開催されているようですね。




[SSDSE（教育用標準データセット）](https://www.nstac.go.jp/SSDSE/)






SSDSEは以下の4つに分かれています。
> SSDSE-A…全国の市区町村別データ。人口・事業所数・就業人数など項目は幅広い。
SSDSE-B…都道府県別の時系列データ。人口・気温・学校数・住居費などが入っている。
SSDSE-C…県庁所在地別の家系消費データ。米・パンなど品目別に分かれている。ブロッコリーやちくわなどかなりたくさんの食品がある。
SSDSE-D…都道府県別の自由時間活動・生活時間データ。園芸や庭いじりを過去1年間に行った割合や通勤の1日あたり平均時間など、日々の暮らしにフォーカスしたデータがある。

実際のデータを見ていただくとわかるのですが、めちゃくちゃ細かくデータがあります。ドメイン知識のようなものはあまり必要ないので、気軽に可視化→考察を行う練習ができそうです。

せっかく紹介したので、1つくらい可視化をしてこのnoteは終わりにしようと思います。

# 通勤時間を可視化してみる

> これ以降の可視化は、独立行政法人 統計センター SSDSE-D（https://www.nstac.go.jp/SSDSE/ ）を加工して作成しています。

今回は、SSDSE-Dにある各都道府県の通勤・通学時間を可視化してみます。せっかくなので、foliumを使ってコロプレス図の描画に挑戦します。

コロプレス図の作成は以下のサイトを参考にさせていただきました。


- [python folium を使い、都道府県の夫婦年齢差をプロットする](https://www.monotalk.xyz/blog/python-folinum-%E3%82%92%E4%BD%BF%E3%81%84%E9%83%BD%E9%81%93%E5%BA%9C%E7%9C%8C%E3%81%AE%E5%A4%AB%E5%A9%A6%E5%B9%B4%E9%BD%A2%E5%B7%AE%E3%82%92%E3%83%97%E3%83%AD%E3%83%83%E3%83%88%E3%81%99%E3%82%8B/)


可視化する前に、どの都道府県が通勤・通学時間が長いか予想してみます。

まず、千葉県や埼玉県は東京に向かう人が多いので長いだろうというのは関東在住なのですぐに予想できます。
関西だと大阪や京都が長いのか…？大都市付近は概ね長くなりそうです。逆に自分は北海道の通勤・通学事情が全くわかりません。市を跨いだ通勤とかするんですかね？（北海道出身の人教えてください）

早速可視化を行ってみましょう。結果は以下のようになりました。

![picture_pc_0b7772f25edc5dcd28c5fcd3e13436b5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927747/a2b6dae9-4d7b-09aa-8134-cf5dc1264c94.png)


予想通り、大都市周辺は通勤・通学時間が長い傾向が見て取れます。北海道は特に長いといったことはないようです。移動が手間だから、通勤・通学に便利な場所に居住しているのかもしれません。

ここまで書いていて、「**通勤時間長いと早起きになるから睡眠時間短そうだな**」と思い、1日あたり睡眠時間（分）のデータもSSDSE-Dにあったのでこれも可視化してみます。予想が当たっているなら、色の濃さが逆になっているはずです。

結果は以下の通りでした。

![picture_pc_498051d82ecbf5eacffb6285cf7a0eb7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1927747/3c30f4c6-75aa-6a81-9cc2-6cc79cd7be87.png)


ものすごく雑な仮説でしたが、少しは当たっていそうです。3大都市圏では睡眠時間が比較的短いことがわかります。

他にも、仕事からの帰宅時間や起床時間も可視化してみると面白そうです。さらに、都道府県別に各種スポーツを過去1年で行った人の割合があるので、個人的には都道府県とスポーツ種目の関係なんかも調べてみたいなあと思っています。

こんな感じで、SSDSEは気軽に可視化や考察の練習をするのにちょうどいい素材です。データをいじって何か考えて遊んでみたいぞという方は、ぜひSSDSEを触ってみてはどうでしょうか（いじった結果面白いことがわかったらぜひ教えてください）。来年はこのデータを使ったコンペにも挑戦してみようと思います。
Webアプリケーションを作成する時の流れ

<h1>この記事の目的</h1>
Webアプロケーションを作り方を試行錯誤した結果、一番いいのではないかと思った方法を記録として残す。
より良い方法が見つかったタイムングでアップデートしていく。

<h1>目的別の流れ</h1>
<h3>必要な機能を洗い出す</h3>
<ol><li>どんなことがしたいかの目的を設定する</li><li>現在行われている流れをアクティビティ図を用いて整理する</li><li>現在行われている流れの中で、webアプリケーションで代替できる部分を見付ける</li><li>代替できる部分をユーザー目線の機能別にユースケース図にまとめる</li><li>ユースケース記述を作成し、ユースケースの見落としている要素を洗い出す</li></ol>

<h3>新しい機能を追加する</h3>
<ol><li>アクティビティ図で新しい機能を使う流れを整理する</li><li>アプリケーション内の動作をコミュニケーション図でまとめる</li><li>コミュニケーション図で書いたクラス、メソッド（、その他必要な要素）をクラス図にまとめる</li><li>サイトマップ・ワイヤーフレームの作成</li><li>モデル・メソッドの単体テスト、アクティビティ図を基にした統合テストを記述する</li><li>コーディング</li><li>リファクタリング</li></ol>
【SwiftUI】理由はわからないがフリーズが解決した。

どうも、プログラミング初学者です。
早速本題です。SwiftUIで勉強タスクアプリを開発しています。ビルドして動作確認をしていた時、アプリがフリーズし、コンソールに"QUARANTINED DUE TO HIGH LOGGING VOLUME"というメッセージが表示されました。コード上にエラーは出ませんでした。

##アプリの概要：
勉強のタスクを教科ごとに設定できるアプリです。
FirstViewではタスクがList{}で表示されます。新規タスクボタンを押すとFormViewに遷移します。
FormViewのTextFieldにタスクを記入し、Pickerで教科を選択します。保存を押すとCoreDataに保存され、FirstViewに戻ります。List{}には、新規で登録したタスクが無事追加されます。

##フリーズの経緯：
①ある程度アプリができてきたのでビルドしてみることにした。
②問題なくビルドされた。
③新規タスクボタンを押し、データベース(CoreData)に新しいタスク（レコード）を保存。無事List{}に新しいタスクが表示されたが、再び新規タスクボタンを押すとフリーズ。
④少し時間差でコンソールにメッセージが表示

##メッセージの全貌：
コンソールに以下のメッセージが表示されました。

```
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.

The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.

QUARANTINED DUE TO HIGH LOGGING VOLUME
```

##原因：
どうやら、FormViewのPickerに問題があったみたいです。

```
//FormView
Picker(selection: $selection, label: Text("教科を選択")) {
  ForEach (subjectArray, id: \.self) { subject in
    Text("\(subject)")
  }
}
```

```
//selectionとsubjectArrayはこんなやつ
//ちなみにvar body: some View {} の一つ上で宣言してるよ。
@State private var selection = "数学"
private var subjectArray: [String] = ["英語", "数学" , "物理", "化学", "プログラミング"]
```

ちなみにselectionはPickerの初期値を表すと同時に、選択された値で上書きされていきます。

こちらのPickerは以下の画像のように作動します。「教科を選択」を押すと二枚目の画像に遷移します。
![Simulator Screen Shot - iPhone 13 - 2021-12-29 at 11.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2440833/23dd36d2-caef-fe66-8615-2e97009e7138.png)
![Simulator Screen Shot - iPhone 13 - 2021-12-29 at 11.37.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2440833/894181f7-9ecc-acea-ff92-d1285c7625f5.png)

教科を選択すると一枚目の画像に戻り「数学」の部分が選択した教科になります。

明確な原因はわかりません（実力不足）

#解決方法：
ググっても具体的なことがわからず、かなり苦戦しましたが、Picker(){}の最後に
.pickerStyle(WheelPickerStyle())
をつけるとフリーズが起きなくなりました。


```
//FormView、解決後のPicker
Picker(selection: $selection, label: Text("教科を選択")) {
  ForEach (subjectArray, id: \.self) { subject in
    Text("\(subject)")
  }
}.pickerStyle(WheelPickerStyle())
```
.pickerStyle(WheelPickerStyle())をつけると以下のようにUIが変わります。
![Simulator Screen Shot - iPhone 13 - 2021-12-29 at 11.50.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2440833/9a5ef3db-3d45-bc62-c8bc-4e6ff330a2d9.png)

明確な理由は分かりませんが、備忘録として残しておきます。
拙い説明失礼しました。
インフラ屋のこれから

##背景
AWS等のクラウド利用が急激に進み、今後いわゆるオンプレを中心としたインフラ屋はどうなっていくのか？また、インフラ屋はどのように進化すべきなのか？について考えた事をつらつら書いていこうと思います。

##考えたこと
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261436/427767f0-171b-30af-43b9-63b8d9070349.png)

 - インフラ屋の領域はアプリ（ロジック）領域に置き換わる
 - 例えばサーバを構成して実現していた機能はアプリ（ロジック）で実現できる
 - つまり、サーバは必要なくなり、インフラ屋の領域は縮小する
 - 現在はアプリ屋がCloudNativeの領域に踏み込んでおり、アプリの領域が拡大していると言っても良い
 - AWSで言うとPaaS領域である
 - ただし、可用性、性能・拡張性等の非機能として考えないといけない領域は変化しない
 - よって、インフラ屋はCloudNativeの技術を手にすると共に、今までの非機能の知見を反映した、新たな非機能の考え方や実現手法を確立すべきである

##まとめ
古くからのインフラ屋はここ数年の波の飲み込まれる事なく、波に逆らわず上手に乗っていきたいものです。
【Unity】音が鳴るオブジェクト用のスクリプト

Active状態を変更すると鳴動し、アイドル状態用に別のオブジェクトも設定できるスクリプトです。

OnEnable時にはUniTaskを使用しています。
OnDisible側ではAudioSourceが同時にDisibleになった場合、音が鳴らなくなってしまうため、PlayClipAtPointを使用して、音を鳴らす別のオブジェクトを一時的に生成する形で実装しています。


```c#:SEObject.cs
using UnityEngine;
using Cysharp.Threading.Tasks;

public class SEObject : MonoBehaviour
{
    private AudioSource _audioSource; // 同じゲームオブジェクトにAudioSourceをアタッチしておく
    public AudioClip _enableSE;
    public AudioClip _IdleSE;
    public AudioClip _disibleSE;

    private void Awake()
    {
        _audioSource = GetComponent<AudioSource>();
    }

    /// <summary>
    /// _audioSourceが設定されていれば、表示SEを鳴らしてからアイドルSEを鳴らす。
    /// </summary>
    /// <returns></returns>
    private async UniTask OnEnable()
    {
        if (!_audioSource)
            return;

        _audioSource.PlayOneShot(_enableSE);

        // SE再生待ち
        await UniTask.WaitUntil(() => _audioSource.isPlaying);

        // SE再生終了待ち
        await UniTask.WaitWhile(() => _audioSource.isPlaying);

        // アイドルSE再生
        _audioSource.clip = _IdleSE;
        _audioSource.loop = true;
        _audioSource.Play();
    }

    private async UniTask OnDisable()
    {
        // アイドルSEを止める
        _audioSource?.Stop();

        // SE再生終了待ち
        if (_disibleSE)
            // SEを一度鳴らすと消えるオブジェクトを生成
            AudioSource.PlayClipAtPoint(_disibleSE, transform.position);
    }
}
```
５分で機械学習（YOLOv5）によるモバイル物体検出を試してみる 

# 超お手軽に画像内の物体検出（ObjectDetection）をする

オブジェクトが画像内のどこにあるのかの位置を返してくれる物体検出。
YOLOv5は高速、高精度を謳う2020年発表のモデル。
この記事ではそれを5分でつかってみる。

<img width="800" alt="スクリーンショット 2021-12-29 11 44 24" src="https://user-images.githubusercontent.com/23278992/147622521-e0a72193-365c-4f16-a340-8196e3245d49.png">

# 機械学習ってむずかしい？

機械学習とかAIとかきくと、なんかデータサイエンティストの高尚な方がやっていそうな気がしませんか？
興味はあるんだけど、学習コストがかかりそう、みたいな。

# CoreMLモデルでモバイル用機械学習モデルがすぐにつかえる

しかし、やってみるとかんたんだったりする。
ここでは、CoreMLというアップルの機械学習フレームワークの学習ずみモデルで、手持ちの画像の物体検出をやってみます。

CoreMLモデルは数行のコードでつかえる。
もっと言えば、今回のYOLOv5モデルは、**モデルファイルに画像をドロップするだけで物体検出してくれる**。

#アプリにもつかえる

CoreMLモデルは、**あなたのアプリにも取り込める**。物体検出アプリがお手軽に作れてしまう。

#5分でできる手順

##### １、[**CoreML-Models**](https://github.com/john-rocky/CoreML-Models)からYOLOv5のCoreMLモデルをダウンロード。

https://github.com/john-rocky/CoreML-Models

[<img width="600" alt="スクリーンショット 2021-12-29 11 47 55" src="https://user-images.githubusercontent.com/23278992/147622694-a5a4df9e-0a96-4589-9887-ef6543966a73.png">](https://github.com/john-rocky/CoreML-Models)


##### ２、モデルファイルを開いて、Previewタブを押し、画像をドロップ。

<img width="600" alt="スクリーンショット 2021-12-29 11 49 33" src="https://user-images.githubusercontent.com/23278992/147622792-1726341d-b417-4fe6-af6a-420b8154d37e.png">

**これだけ。**

アプリとしてつかってみるには、

##### ３、CoreML-YOLOv5のサンプルプロジェクトをクローンしてビルド。フォトライブラリから画像を選ぶ。

https://github.com/john-rocky/CoreML-YOLOv5

あなたのアプリで使う場合は、サンプルのdetect(image:UIImage)を参照できます。

5分以内にできましたか？

🐣
****
フリーランスエンジニアです。
機械学習モデルをアプリに取り込みたい、自前のモデルを作りたい、ARアプリを作りたいなど、
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLやARKitを使ったアプリを作っています。
機械学習／AR関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
インスタンス変数の2つの特徴について

プログラミング学習中です。　
今回はインスタンス変数について備忘録としてまとめてみます。

#インスタンス変数とは
　まずインスタンス変数とはクラスの中で、以下のように@変数名とすることで定義することができる特殊な変数のことである。

```ruby:qiita.rb
class book
  def initialize(title)
    @title = title
  end
end
```

この＠で始まるインスタンス変数は大きく分けて2つの特徴があります。
1つ目は、クラス内の全メソッドで使用する事ができる。
2つ目は、インスタンス毎に違う値を持てる。
です。順番に解説します。

#クラス内の全メソッドで使用する事ができる

まずインスタンス変数の1つ目特徴である、「クラス内の全メソッドで使用できる」という事を、コードで見てみます。

```ruby:qiita.rb
class Book
  def initialize(title)
    @title = title
  end
　
　def output
    puts "好きな本は#{@title}です"
  end
end

user1 = Book.new("ハリーポッター") 
user1.output

#　実行結果
好きな本はハリーポッターです
```

このように、initializeメソッドで定義した@titleを、outputメソッドでも利用できている事がわかります。

#インスタンス毎に違う値を持てる
　次にインスタンス変数の2つ目の特徴である、「インスタンス毎に違う値を持てる」という事をコードで見ていきます。

```ruby:qiita.rb
class Book
  def initialize(title)
    @title = title
  end
　
　def output
    puts "好きな本は#{@title}です"
  end
end

user1 = Book.new("ハリーポッター") 
user2 = Book.new("三国志")

user1.output
user2.output

#　実行結果
好きな本はハリーポッターです
好きな本は三国志です
```

このように、user1とuser2では、同じクラスをnewしていても、違うインスタンス変数を使用できている事が分かります。

#＊補足　インスタンス変数はviewに渡す事もできる
　少し脱線はしますが、ruby on railsにおいてインスタンス変数をcontrollerからviewに渡す事もできます。

```ruby:books_controller.rb
#コントローラーのサンプルプログラム

class bookController < ApplicationController
  def index
    @title = "ハリーポッター"
  end
end
```

```ruby:index.html.erb
#ビューのサンプルプログラム
<p> 
　好きな本は<%= @title %>です。 
</p>
```
rails sでサーバーを立ち上げ、localhost:3000のindexにアクセスすると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2378833/bed05aee-5c29-6af0-9cbf-5968807afce0.png)
と出力されている事から、controllerからview にインスタンス変数を渡せている事が分かります。

このように、controllerにインスタンス変数を指定することで、controllerに紐づくviewファイル内で値を受け取る事ができます。


＊ruby on railsにおいて、なぜインスタンス変数をviewで受け取る事ができるのかについては、こちらの記事に詳しく書いております。
https://attonblog.blogspot.com/2016/12/okinawarb-advent-calendar-2016-12-06.html


#まとめ
　以上インスタンス変数についてまとめました。インスタンス変数の特徴としては、
1つ目は、クラス内の全メソッドで使用する事ができる。
2つ目は、インスタンス毎に違う値を持てる。
ということです。

インスタンス変数を利用することで、大枠は同じだけど、値は違うという便利な実装ができます。
補足として、ruby on railsにおいてcontrollerで宣言したインスタンス変数をviewで受け取るという実装もできます。
[JUCE]NativeMessageBox

# はじめに
JUCEにはダイアログを表示する際に`NativeMessageBox`クラスに定義されているstatic関数を使用することができます。

https://docs.juce.com/master/classNativeMessageBox.html#a089ed9ffcf21c5648f4a3fb1e7c40616

Macで試したので、パッと比較したい時のための備忘録としてこちらに残しておきます。
JUCEのバージョンは6.1.0です。

## サンプル
ダイアログ表示時のアイコン切り替えなどで確認できます。
![NativeMessageBox.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136558/71fc0509-c035-231c-ba9c-fbf65e7b3644.gif)

https://github.com/migizo/NativeMessageBoxTest

# 用法
`NativeMessageBox::showAsync`では`MessageBoxOptions`を指定することでカスタマイズすることができます。

```c++
function<void(int)> callback = [](int result) {
    DBG("result : " << result);
};

NativeMessageBox::showAsync(MessageBoxOptions()
                                .withIconType(MessageBoxIconType::InfoIcon)
                                .withTitle(buttonTexts[i])
                                .withMessage(msg)
                                .withButton(TRANS("button")),
                            callback);
```

シンプルに確認ボタンだけ使用したい場合は`NativeMessageBox::showMessageBoxAsync`を使用することができます。
```c++
NativeMessageBox::showMessageBoxAsync(iconType, title, msg);
```

その他の関数では以下のように使用できます。
まだ試していませんが`nullptr`の箇所には使用するコンポーネントを設定できるようです。

```c++
NativeMessageBox::showOkCancelBox(iconType, title, msg, nullptr, ModalCallbackFunction::create(callback));
NativeMessageBox::showYesNoCancelBox(iconType, title, msg, nullptr, ModalCallbackFunction::create(callback));
NativeMessageBox::showYesNoBox(iconType, title, msg, nullptr, ModalCallbackFunction::create(callback));
```

コールバック外の変数を使用する場合、非同期で実行されるので呼び出し元が削除されてから呼ばれないよう注意が必要です。

# 各関数のスクリーンショット
## NativeMessageBox::showAsync()
![スクリーンショット 2021-12-29 11.14.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136558/c65f4502-b854-ae0c-4c11-18f44f542aee.png)

## NativeMessageBox::showMessageBoxAsync
![スクリーンショット 2021-12-29 11.15.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136558/13e0c80a-67a6-c55d-b7b5-b02571155270.png)

##　NativeMessageBox::showOkCancelBox
![スクリーンショット 2021-12-29 11.15.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136558/55c70cb1-309a-d8d8-28d9-57be93eed6aa.png)

## NativeMessageBox::showYesNoCancelBox
![スクリーンショット 2021-12-29 11.16.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136558/2a9e90de-97db-102b-5978-8ecc99170423.png)

## NativeMessageBox::showYesNoBox
![スクリーンショット 2021-12-29 11.16.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136558/f1e1fbfe-f68c-a6f3-71f9-537cd973fac2.png)

# アイコン
アイコンの種別として以下を使用できます。
・ `MessageBoxIconType::NoIcon`
・ `MessageBoxIconType::QuestionIcon`
・ `MessageBoxIconType::WarningIcon`
・ `MessageBoxIconType::InfoIcon`

Macの場合、
`NativeMessageBox::showAsync()`ではどのアイコンでも同じ状態になり、
その他では`MessageBoxIconType::WarningIcon`以外は全て同じ見た目になるようでした。
![スクリーンショット 2021-12-29 11.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136558/46ce80da-45ec-4987-47a2-2b71c0716bcd.png)
スピーカー特性の測定方法・・・3）フーリエ変換

第4回目の解説では、第2回で作成した音声データを
実際にスピーカーから出力して
それを内臓のマイクで録音して比較を行います。

その前に、FFT(フーリエ変換),IFFT（逆フーリエ変換）について説明します。

##２成分Sin波形の作成

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

#n_channels = 1
a1, a2 = 0.4, 0.6 #amplitude
f1, f2 = 10.0, 100.0 #frequency

framerate = 44100
sampwidth = 2 #16bit
total_secs = 2

data_num = int(total_secs * framerate)
t = np.linspace(0, total_secs, data_num)
wav = 32767 * a1 * (np.sin(np.pi*f1*t)) + 32767 * a2 * (np.sin(np.pi*f2*t)) 

plt.plot(t,wav)
plt.show()

```

![Figure 2021-12-28 155320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/3ee6b7c5-aa01-f70c-7d8e-d0e65d8ca024.png)


##FFT(フーリエ変換)
```
freq = np.linspace(0,framerate*2, data_num)
f = np.fft.fft(wav)
f_abs = np.abs(f)
plt.plot(freq[:int(framerate/200)+1], f_abs[:int(framerate/200)+1])
plt.show()
```

![Figure 2021-12-28 155324.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/83c72cf3-2c84-a8ed-4727-3008c039f875.png)

指定した周波数、10[Hz]と100[Hz]において
スペクトルを観測できたことがわかります。
基本周波数を変えてみたり、トータル時間を変えても正しく表示されることを確認してください。


##注意点

:::note info
パラメータ(total_secs)を２から３に変更してみましょう。
:::

```python
total_secs = 3 #2から３に変更
```
すると、FFT結果が以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/e299e913-d226-9db2-6eda-61997aa3fb0e.png)

100[Hz]は正しく、スペクトルを観察できていますが
15[Hz]はスペクトルがぼやけています。これはプログラムが間違っているのではなく
FFTの計算過程上発生してしまう数学的な問題となります。

:::note warm
高速フーリエ変換（FFT）は変換元の波形が繰り返し発生しているという前提で算出しているためです。
そのため、入力するサンプル数Nの測定データが、0番目とN番目で連続していない場合、高速フーリエ変換すると、本来含まれていないスペクトル（ノイズ）も出現し、周波数特性を解析しにくくなります。
:::

![Figure 2021-12-28 160215.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/60c39de2-0b42-2408-2f93-20349b034ad0.png)

わかりやすく、15[Hz]だけの信号としました。
この波形が繰り返されているということを前提でFFTしています。

何かおかしいこと気づきましたか？


この波形は凸から始まって、最後に凸で終わっています。
これでは、本来の凸凹という波形ではないため
FFTが思ったように実行されていません。
<font color="Red">
一見、０で終わっているため問題ないと思う場合もあるかもしれませんが
注意が必要です。
</font>

そこで窓関数を用います。(窓関数にはハニング窓、ハミング窓、ブラックマン窓があります）

```python
window_hn = np.hanning(data_num)
```
![Figure 2021-12-29 113538.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/a8af79a8-f8fd-4c1d-12ff-79d43f9fac39.png)

元のサイン波形に窓関数をかけてみましょう。

```python
wav_hnd = window_hn * wav
```
![Figure 2021-12-29 113544.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/a3d158c8-55ed-5933-4c4a-71e9934633bf.png)


```python
f_hnd = np.fft.fft(wav_hnd)
f_abs_hnd = np.abs(f_hnd)
plt.plot(freq[:int(framerate/100)+1], f_abs_hnd[:int(framerate/100)+1])
plt.show()
```

窓関数処理あり
![Figure 2021-12-29 113552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/c14a732a-9251-1333-5706-011a8952a2cd.png)
窓関数処理なし
![Figure 2021-12-29 113559.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262142/a3d148a1-77cb-9360-4e27-78dd36e0dadf.png)


では、解析の準備ができたので次から
MacBook(M1)のスピーカから発生させた音声を
内臓のマイクを用いて録音してスピーカーの周波数特性の観察をしてみましょう。