OmniAICreator/Qiita-1.07M huggingface dataset:
超基礎：Python Firebase Admin SDKによる位置情報データの取り扱い データの登録編

Location Tech Advent Calendar 2021 by LBMA Japan 🛰 Advent Calendar 2021の1日目ということで、Firestoreのデータベースに位置情報データを投入するというごく基本的な記事を書いていきます！

# 対象
Firebase Firestoreを使い始めた人
位置情報データを扱いたい人

# 背景
Firebase Firestoreは、JSONのようなスキーマでデータを出し入れできるGoolge Cloud Platformのデータベースで、極めて高速・柔軟にデータの処理ができます。

一方で、制約条件も多くあります。例えば、Firestoreに登録されたデータを2つ以上のフィールドを用いて検索することは基本的にはできません。SQLでいうと、「Where句で2つ以上のフィールドを使った条件分が書けない」というようなイメージです。このようなリレーショナル・データベースだとあまり考えられないような制約条件が、Firebaseには他にもいくつかあります。

こうした制約条件は一見厳しいように見えますが、通常の場合、クライアント側で解決が可能です。例えば、「1つのフィールドしか検索できない」という制約条件については、「1つのフィールドで検索して、結果をクライアント側に持ってきて、クライアント側でより細かく絞る」ということが可能なので、大きな問題にはなりません。

しかし、**位置情報データ**を取り扱う場合には、大きな問題が生じます。というのは、緯度と経度で定義される「位置情報」は、「緯度だけ」や「経度だけ」のように、片方だけで利用するケースがほぼ無いからです。仮に緯度だけで絞ったとしても、ものすごくたくさんのデータがヒットしてしまい、たいてい、クライアントでの処理が大変遅くなってしまいます。つまり、Firebaseで緯度と経度を

![スクリーンショット 2021-11-30 12.50.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237873/85107be3-e2f9-624e-6993-7aa73bf90dc7.png)

というように登録してしまうと、パフォーマンス上色々問題が出てしまいます。

そこで、Firestoreでは`GeoPoint`型と呼ばれる型を導入することで、この問題に対処しています。これは、緯度と経度が一緒になったフィールドです。 緯度と経度を同時に持つので、`GeoPoint`型で検索すれば、Firestoreの「1つのフィールドでしか検索できない」制限をクリアすることができるように思えます。

しかし、ここでも１つ問題があります。それは、Firestoreでは`GeoPoint`型を直接指定してクエリを打つことができないという問題です。例えば、「この`GeoPoint`型のデータの半径50m以内のドキュメントをもってきてください」というようなことが、現状のFirestoreではできません。そのため、ちょっとした工夫が必要になります。

こうした点を背景に、以下では、Python Firebase Admin SDKを用いた位置情報データの登録方法について解説していきます。検索方法については次の記事にて。


# 位置情報データの登録
## バージョン情報
本記事では以下のバージョンで実施しています。

```toml
[tool.poetry.dependencies]
python = "^3.9"
firebase-admin = "^5.0.3"
google-cloud = "^0.34.0"
```

## 型やクライアントの準備
主として利用するのはFirebase Admin SDKですが、型ヒント（type-hint）を使うために、google-cloud側のfirestoreライブラリも利用します。

```python
from firebase_admin import initialize_app, firestore
from google.cloud.firestore import AsyncDocumentReference, AsyncCollectionReference, GeoPoint

initialize_app(options={"projectId":"Your_GCP_PROJECT_ID"})
db_client = firestore.AsyncClient()
```

## コレクションの定義
コレクションへのリファレンスを定義します。ここではlocationsというリファレンスを作ります。

```python
locations_ref: AsyncCollectionReference = db_client.collection('locations')
```
これで準備は終了です。

## 位置情報データの追加
最後の位置情報データを追加する処理について書きます。locationsコレクションにgeopointというフィールドを持つドキュメントを追加していきます。

```python
# GeoPoint型のデータをもつdataを定義
data = {"geopoint": GeoPoint(38.1233, 139.7548968)}
# 追加
result_doc_ref: AsyncDocumentReference
_,result_doc_ref =  await locations_ref.add(data)

print(result_doc_ref.to_dict()['geopoint'].latitude)
# >> 35.7018944
```
格納した結果（値は異なっていますが）

![スクリーンショット 2021-11-30 12.58.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237873/60a4e23f-b3cc-92f9-92ae-aee3211474f4.png)


上記の手順により、Firestoreに追加することはできました。しかし、背景で説明したとおり、FirebaseにはGeoPointで検索をする機能がありません。そこで、実用的に使うためには、もうひと工夫が必要です。こうした検索の工夫については、次の記事で書きますね。

# 参考
firestore client 公式ドキュメント
https://googleapis.dev/python/firestore/latest/client.html
DX時代を勝ち抜くITエンジニアキャリアを考える人に是非見て欲しい動画を紹介したい

![mix.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/e48fe6f8-11df-e149-a574-9a53c718704b.jpeg)

## 自分にどうスイッチを入れるか？

私の主観ではありますが、ひと昔前に比べると、エンジニアリング環境に理解のある経営者やマネージャーも増え、エンジニアにとって心理的安全性の高い職場環境も随分増えました。勤務時間の管理も相当に配慮されるようになりましたし、コロナ禍という不測の要因ではあったものの、定常的なリモートワークという数年前には考えられなかった働き方ができるようになりました。

一方で、そうした環境からは縁遠く、結果として新しい技術的研鑽や挑戦への意欲をなかなか持ちえない、または気持ちはあるが具体的な一歩を踏み出すのに躊躇されているエンジニアの方々もいらっしゃいます。一般社会におけるITへの理解の未成熟さや、ベンダー依存や多階層発注などに代表される日本の業界特性も、まだまだ根深く残っているのも事実であり、閉そく感に苛まれている方も少なくないかもしれません。

人には自燃型、他燃型、不燃型の3パターンがあるそうです。もちろん個人の性格や過去の経験による影響もあるでしょう。ただ後天的かつ環境依存で自燃化できていないケースも多いと感じています。つまり、燃えるきっかけと環境や手段が整えば、みな自燃化するのではないかと思うのです。

今はオンラインコミュニティが活性化し、様々なコンテンツやリソースがネットで自由に探せる時代となりました。エンジニアとしての好奇心を満たし成長の糧にできる材料は、実はすぐ手を伸ばして届く場所にあります。

とすればあとは「燃えるきっかけ」をどうやって提供していくか・・・？
そんなことも考えながら、実はこの8月に以下のオンラインセミナーを開催しました。

https://www.youtube.com/watch?v=Pvhp6TFuNQc&t=703s

[11:43](https://www.youtube.com/watch?v=Pvhp6TFuNQc&t=703s) ゲスト講演：「DX時代を勝ち抜くエンジニア成長戦略」
株式会社クレディセゾン 取締役（兼）専務執行役員CTO（兼）CIO
一般社団法人日本CTO協会理事 小野和俊 氏

[50:33](https://www.youtube.com/watch?v=Pvhp6TFuNQc&t=3033s) ゲスト講演：「キャリアの考え方」
株式会社レクター取締役 兼 日本CTO協会理事 広木大地 氏

小野さん広木さんという業界のオピニオンリーダーのお二人にそろい踏み頂きました。
生存者バイアスからの武勇論ではなく、それぞれの具体的な事例をベースとしながら、抽象度を高めた形でより多くの方に参考になる切り口でお話いただきました。是非アーカイブ動画をご覧になっていただきたいです。

## 動画が見るのが手間だという人へ

気鋭のグラレコライターである[あづみ](https://twitter.com/azumi_tsuyuka)さんに、それぞれ40分の講演をぎゅっと1枚のグラレコに集約してもらいました。こちらでもしご興味を持って頂いた方は、是非アーカイブ動画をご覧になってみてください。

![iQdxfgam.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/e1b378a5-2f29-28b3-15d7-5d03d840c646.jpeg)

![M-QkC9Py.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/131112/1af92a36-c189-6e44-efb4-98191adc480f.jpeg)

## もっと細かいログが見たいという人へ

なんとあのログミーTechさんがログ記事にしてくれました。ありがとうございます！

小野さん

https://logmi.jp/tech/articles/325526

https://logmi.jp/tech/articles/325593

https://logmi.jp/tech/articles/325658

広木さん

https://logmi.jp/tech/articles/325543

https://logmi.jp/tech/articles/325598

https://logmi.jp/tech/articles/325662

## キャリアに正解はない

お二人ともエンジニアを経てマネジメントや経営というテーマに向き合ってらっしゃるわけですが、似ているようで違う、違うようで似ているそんな印象を持ちながら、興味深くお話を聴かせてもらいました。

・戦略を持つことと、偶然を受け入れること
・誰かの為を目指すことと、自分が楽しむことと
・絞り込むことと、効率を手放すこと

一見お二人がお話されていることは相反する価値観のように見える部分もありますが、お二方とも常に自分を客観的に捉えらえていたところは印象的でした。

キャリアに正解はありません。聴く人それぞれに刺さるポイントが違う、そんな味わい深い2つのセッションではないかと思います。是非多くのエンジニアの方にご覧になっていただきたいです。

https://www.youtube.com/watch?v=Pvhp6TFuNQc&t=703s

※なお、この記事はARアドバンストテクノロジ株式会社のアドベントカレンダー2021年の12/1分として投稿しました。
今後のアドベントカレンダーも是非ご期待ください。

https://qiita.com/advent-calendar/2021/ari-group

## 併せて見たい

https://www.youtube.com/watch?v=jAzfnIp6r-w&t=785s

https://www.youtube.com/watch?v=2CSKkEvypRE&t=180s

https://www.youtube.com/watch?v=j2WcIy5rsnE&t=684s

https://qiita.com/organizations/ari-group
世界における #リテールテック の潮流

まずはイントロダクション的な記事となります。
世界におけるリテールテック、すなわち小売業にて使用される技術の潮流
について、小売業者の視点で記述します。

#リテールテック
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/0575d018-7c04-862b-10dc-4b8798a72ac6.jpeg" width=50%  alt="リテールテック概要.001.jpeg">

賛否あるとは思いますが、主に店頭で利用されるか後方で利用されるか、顧客向けか従業員向けかの4象限で分類されることが多いです。もちろん各技術、従業員向けで開発されたものが顧客体験価値を生んだり、店頭後方両方で使われたりといったこともありますので、あくまで概念として捉えていただければと思います。

この中から、いくつか世界的に有名な技術をピックアップして紹介します。

#レジカート お買い物セルフレジ
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/72d6eb0e-c441-6701-c17f-f7184f6f10ca.jpeg" width=50%  alt="trial_16_s.jpg">
カートにレジがついていたり。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/39d14a82-8dd2-a8c0-6278-b367f90de7e5.jpeg" width=50%  alt="aeon3_s.jpg">
お買い物しながら専用端末で商品スキャンできたり。

皆さんも体験されたことがあるであろう、お買い物における慢性的なレジ待ち。
小売業における重点課題の一つでしたが、近年カートや手持ちのレジ端末を導入して、レジ待ち時間をなくす動きが盛んです。顧客側が自分で商品スキャンを実施しながら買い物をして、レジに並ぶことなく精算することが可能となっています。
レジ応援（レジ以外の部門の人が、混雑した場合に緊急的にレジに入る）時間の削減というメリットは店側にありますが、やはりレジ待ち時間がなくなるという顧客体験的な部分が本質と考えています。
さらにこの技術が極まると下記のようになります。

##Amazon GO
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/c8f92791-55e4-048c-b96d-5a3969ecdde2.jpeg" width=50%  alt="amazongo-1024x538.jpg">
ご存知の方も多いかと思いますが、2018年にオープンしたAmazonの店舗です。
この店舗はレジがありません。アプリをダウンロードしたスマートフォンを、セキュリティゲートにかざすことで入店でき、その後**店内のカメラ**と、**商品棚のセンサー**で顧客の購買情報を読み取り、自動で生産される仕組みとなっています。
リテールテック関連の展示会に行くと、類似の技術を紹介されている企業さんもいらっしゃる状況であり、日本でも今後実証実験は加速するものと思われます。

#Eコマース フルフィルメントセンター
　今や我々の生活になくてはならないEコマース。コロナ禍により、その潮流は一気に加速し、物販系でのEC化率は2020年で8.08％と前年6.76％、前々年6.22％という傾向から見ても大きく伸長しています。
そのEコマースを支えるのが**フルフィルメントセンター化**です。特に、店舗併設型の小型物流倉庫は**マイクロフルフィルメントセンター**と呼ばれ、店頭の商品在庫保管機能と、店での商品受け取り（ピックアップ）、消費者への商品配送というラストワンマイル機能を兼ね備えた設備です。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/1e2e0a76-bff8-5d18-2c95-5c34f4295e7b.jpeg" width=50%  alt="item-02.jpg">
世界的に見て最も進んでいるのは以下の企業かと考えています。

##Walmart.inc
walmartは世界最大の小売業です。

https://fortune.com/global500/

さらに言えば、小売業の枠を超えて営業収益で世界最大の企業です。
amazonの成長を見て、いち早くEコマース事業に力を入れ始めたことで、アメリカで多くの小売業が経営破綻に追い込まれる中、今なお規模を拡大し続けている企業です。
いち早く、マイクロフルフィルメントセンターに投資し、さらにEコマースのアプリ（Walmart app)と店舗での受け取りシステムを整備したことで、高い利便性を顧客に提供し続けていることが、成長の要因と言えるかと思います。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/869fc111-c66d-5542-ca38-32051cfa99ed.jpeg" width=50%  alt="29d3bc99193cb0b837fb8cc53f050ae5-13-1024x540.jpg">
店舗併設型物流拠点
![images.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/1ee07348-ae9d-1f7e-1e30-01a4668fae78.jpeg)
EC注文商品のカウンターでの受け取り
![download.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2100048/8e573d39-9890-bd88-0a37-4908e4baf418.jpeg)
EC注文商品のドライブスルー

#結びに
　このように、一般的に言われているリテールテックは、企業が莫大な投資をかけて、トップダウンで推進していく傾向が強いです。アメリカの小売業は日本に比べて10年分進んでいると言われており、日本も今後同様の傾向で追随していく可能性が高い、さらに言えば追随し始めているというのが現状という認識です。
　一旦視点を高くしたところで、明日以降は少し身近な課題解決、ボトムアップな話を書いていきたいと思います。引き続き読んでいただけると嬉しいです。
STM32L010で「hello...」とシリアルに出力(Mbed)HAL(PA_4)(STM32)(LPUART)


Mbed2のリビジョンは、143

目的
シリアル通信のテスト



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6392aa4d-5040-afea-9507-d69166f6c982.png)



いろいろ

シリアルに関しては、実質人気総合No1でいろいろ後でまとめないと(予定)

記事の人気ランキングcaa45040調べ(2021/11/28 sun)
1.stts751(秋月での販売終了 後継S-5851 アドレス違い)
2.Python(WS2812Bの事)
3.シリアル(通信の方)
4.ソフトウェアシリアル(あと、1ポートほしいと推論される)
5.ds1307(時計の事)
6.ソフトウェアシリアル受信
7.内蔵ADC、電圧 330xmV(10の割り算とレベルコンバートは、必見)
?.GP2Y0A21YK(根強い人気)


いろいろ2
外部から観測していると読者のほとんどが
東工大、高専に片寄っている
ただでstm32を配布しているからだと推論される。
(異論は、認める)


```c++



#include "mbed.h"


int main()
{

    wait_ms(2); //HAL_Delayが失敗する為

    //シリアルの構造体の定義
    UART_HandleTypeDef hlpuart1;

    //シリアルへのクロックの選択
    RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
    PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
    HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit);

    //シリアルへクロックの供給
    __HAL_RCC_LPUART1_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

    //シリアル用のGPIOの設定
    GPIO_InitTypeDef GPIO_InitStruct = {0};
    GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF6_LPUART1;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    //シリアルの設定
    hlpuart1.Instance = LPUART1;
    hlpuart1.Init.BaudRate = 209700;
    hlpuart1.Init.WordLength = UART_WORDLENGTH_7B;
    hlpuart1.Init.StopBits = UART_STOPBITS_1;
    hlpuart1.Init.Parity = UART_PARITY_NONE;
    hlpuart1.Init.Mode = UART_MODE_TX_RX;
    hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    HAL_HalfDuplex_Init(&hlpuart1);



    while(1) {


    HAL_UART_Transmit(&hlpuart1, (uint8_t *)"hello world\r\n", 13, 10);

    HAL_Delay(500);

    

    }

}



```
STM32L010でPA4から「hello...」をシリアル出力(VSC,cubeid)HAL(STM32)(LPUART)


目的
シリアルのテスト

x 過去ログをみよ->

x 7ビットらいし　要注意　わからない時は、誰かに聞いてね!!
x cubemxはnucleo-l011
x vscは、nucleo-l011

stm32l010_lpusrt1_1内をいろいろコピー


https://os.mbed.com/users/caa45040/code/f303_h_p1/



![o_con120.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/81a40798-7b18-7e79-3ab9-cc75c7f5d66c.jpeg)



![o_con121.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/cc2db8e8-b3dc-bddb-7e40-4505f4fe96cd.jpeg)



主なプログラム　main内のwhile内



```c++
  
    

    HAL_UART_Transmit(&hlpuart1, (uint8_t *)"hello world\r\n", 13, 10);

    //HAL_Delay(500);




    
    HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_SET);
    HAL_Delay(500);
    
    HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
    HAL_Delay(500);
    

 

```
globalにgitでignoreをsetする手順

# やり方
git環境は整っていることが前提



## ファイルを作る

```zsh
touch $HOME/.config/git/ignore
```



## ファイルに書き込む

```:ignore
.DS_Store
```

### 拡張子指定で一括

例

```:ignore
*.code-workspace
```



## 試してみる

https://git-scm.com/docs/git-config#Documentation/git-config.txt-coreexcludesFile

https://git-scm.com/docs/gitignore#_description

が正しければ，**これだけでパスは通っているはず**である，試しに動かそう

```:man_gitconfig
...
 Defaults to $XDG_CONFIG_HOME/git/ignore.
If $XDG_CONFIG_HOME is either not set or empty,
$HOME/.config/git/ignore is used instead.
See gitignore[5].
...
```

上手くいけばOK，ダメなら次の手順へ



## パスを通す

```zsh
git config --global core.excludesfile $HOME/.config/git/ignore
```

これをやると

```:.gitconfig
[core]
	excludesfile = /Users/SolunaEureka/.config/git/ignore
```

でパスが通る~~なぜわざわざこんなことやらにゃならんのだ~~<br>
流石にコレなら動くだろう



## パスを消す

```zsh
git config --global --unset core.excludesfile      
```

理由は知らんけど**消してもしばらく動く**場合がある，つーか私はそうだった




# おまけ
初めてgithubでレポジトリ作ったけど，作った時点で案内に乗せられてREADMEを作ると，強制的に「initコミット」が発生してしまい，既に手元に作り溜めしたファイルがある場合は，そのブランチにはプッシュできない・別ブランチにpushできてもプルリクできない，という「詰みの状況」が発生した，`There isn’t anything to compare.`って表示されていた，いや確かにそれはそうなのだが…

あとパスの挙動が謎すぎた，まぁ今はちゃんと動いてるからコレでよしとするか…
【AWS】VPCについて理解を深める！

#はじめに

###なぜこの記事を書こうと思ったのか
アプリ開発の際にDockerを少し触って、仮想サーバーと初対面を果たした。
サーバーと言えば、オンプレミスの物理的なデータセンターをイメージしており、工場で働いていた時も計算室という部屋にサーバーが所狭しと置いてあったのを思い出す。


そこで今回、AWSを学習している際にVPCという仮想サーバーに触れたので自分なりにまとめてみる。


#VPCとは

Amazon Virtual Private Cloud (以下、VPC) は、AWS上に作成できるプライベート仮想ネットワーク空間です。AWSアカウント内に専用のネットワークを作成でき、このネットワーク内に「EC2」（Amazon EC2）などのAWSリソースを配置できます。
　　

1つのVPCを"まとまり"として分離でき、複数のVPC間との接続も可能です。インターネットに公開するパブリックなVPCや、VPNなどを使用して接続するプライベートなVPCの構築もできます。

↑で言う"まとまり"を具体的に言うと、VPCはそれぞれの動物のエリアのようなイメージですね。動物たちがごちゃまぜにならないように、「ここはゾウさんエリアだからコアラとライオンは入ってこないでね！」とエリアを区切ることで、動物たちは安心して過ごすことができます。

![動物園.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2326745/27cc5507-7b27-6f3a-1078-f734a2ec07bd.png)



　仮にオンプレミス環境ではネットワーク環境を構築する場合、データセンター、ハードウェア、回線など用意すべきものが多く、準備期間と初期コストがかかります。

　しかし、AWSでVPCをネットワーク環境として準備する場合、いくつかの操作を行えば数分でネットワークを構築できます。ルータ機能、DNS、NTPなどネットワークで必要な基本機能はAWS側で提供されます。


#VPCの主な概念

>- Virtual Private Cloud (VPC) — AWS アカウント専用の仮想ネットワーク。
<br>

>- サブネット — VPC の IP アドレスの範囲。
  

>- ルートテーブル — ネットワークトラフィックの経路を判断する際に使用される、ルートと呼ばれる一連のルール。
　　
>- インターネットゲートウェイ — VPC 内のリソースとインターネット間の通信を可能にするために VPC にアタッチするゲートウェイ。
　　
>- VPC エンドポイント - PrivateLink を使用してサポートされている AWS サービスや VPC エンドポイントサービスに VPC をプライベートに接続できます。インターネットゲートウェイ、NAT デバイス、VPN 接続、および AWS Direct Connect 接続は必要ありません。VPC のインスタンスは、サービスのリソースと通信するためにパブリック IP アドレスを必要としません。VPC と他のサービス間のトラフィックは、Amazon ネットワークを離れません。詳細については、「」を参照してください AWS PrivateLink および VPC エンドポイント
　　

>- CIDR ブロック —クラスレスドメイン間ルーティング。インターネットプロトコルアドレスの割り当てとルート集計方法。

#AWS　VPCの使用用途とは？

**インターネット向けシステム**
インターネットを経由するシステムを提供する用途で使われるケースです。インターネット接続を待ち受けるインスタンスにはグローバルIPを設定しますが、必ず全てのインスタンスに付与する必要はありません。

ELB（Elastic Load Balancing）から複数のEC2にトラフィックを転送する構成がしばしば用いられていますが、高可用システムを作成するために使うことも可能なので覚えておきましょう。

**オンプレミス向けシステム**
オンプレミスとは、サーバーやソフトウェアなどの情報システムを自社で管理し、運用すること、つまり従来のサーバー運用形態のことをさしています。

オンプレミスのネットワークの延長としてVPCを相互に接続することで、データセンターのサーバーや企業の拠点PC向けシステムを提供しています。

**インターネット兼オンプレス向けシステム**
これは、先ほどのインターネット向けのシステムとオンプレス向けのシステムとの両方の接続をVPCに設定する構成です。普通は、クラウドか、オンプレスかの2択なので、珍しい使い方です。ルーティングテーブルのセキュリティ設定で対応するようにしましょう。


#まとめ

VPCとはリソースのまとまりを区別してIPアドレスの振り分けやセキュリティ管理を行っていたんですね！

次は実際にマネジメントコンソールを使用して、ハンズオンを行ってみようと思います。
初めてのやってみた！系の記事を投稿するので楽しみです！！

最後まで読んでいただきありがとうございました。
AIRS-Lab式のKaggle入門

AIRS-Labの記念すべき初アドベントカレンダーを担当させていただきます！！

2021年8月に始まったAIに関するコミュニティ[AIRS-Lab](https://www.airs-lab.jp/ "AIRS-Lab")の運営のお手伝いをしているyamoriです。

普段はFlutterエンジニアをしているのですが、昨年末に、我妻さんがAIに関するコミュニティを始めるという話を聞き、始めるとき手伝います！という流れで、今年の夏に週１ミーティングをしながらいろいろ準備してきました。

この記事は、AI初心者・Kaggle初心者（中級者・上級者向けの記事は明日我妻さんが書いてくれるはず・・・！）に向けて書いています。

## AIRS-Labの紹介
記事に入る前に、少しAIRS-Labの紹介をさせてください。
AIRS-Labは現在30名ほど在籍しており、普段はSlack上でAIに関連する情報交換を行なっております。
週に2回ほど、みんなでもくもく会を行い、それぞれテーマを決めて学習を行っているのですが、もくもく会の前後で話をする時間があるので、今詰まっているところを気軽に質問できる場になっています。
月に1回イベントを開催しており、先日はオフラインイベントを開催するなど、AIに興味がある人が交流できる場を目指しています。

Lab内には、普段はWEB開発・アプリ開発など他の領域で仕事をしていて、今後AI領域にも挑戦したい！という方が多い印象です。
つまり、まだまだAIについては初心者の方が多いので、気軽に参加してください。
AIRS-Labに入ろうか迷っている方は、[yamori](https://twitter.com/tateshiy "yamori")まで気軽にご連絡ください。

Labにいるメンバーの半数ぐらいはこれからAIを学びたい！とモチベーションの高いメンバーです。
そこで、機械学習初心者がモチベーションを保ちながら勉強できる環境を作ることができないか、ということで、データ分析コンペ[Kaggle](https://www.kaggle.com/ "Kaggle")の勉強会を11月から立ち上げました。（12月、1月は自習期間で2月から勉強会再開予定です）

今日は、11月の勉強会を通して、1からKaggleに挑戦してきた経緯を少し共有したいと思います。

## Kaggleの挑戦① - タイタニック -
まず、例に漏れず、Kaggleの[タイタニック](https://www.kaggle.com/c/titanic "タイタニック")をやってみました。
おそらくKaggleを始めた方でタイタニックのチュートリアルをやってない人はいないのでは？というぐらい有名なものです。

KaggleのtitanicページのYoutubeで説明している方も、この題材はKaggleを始めるのにベストなものと言っています。
機会があればこちらを解説する記事も書いてみます。

https://www.youtube.com/watch?v=8yZMXCaFshs

タイタニックのチュートリアルとは、タイタニック号沈没（初めての航海中の1912年4月14日深夜に氷山に衝突し、多くの方が犠牲になった痛ましい事故）を題材にしています。

**お客さんの情報（年齢、性別、配偶者の有無、客室のランク・・etc）を分析し、その生死を予測するコンペです。**

データは2種類に分けられていて用意されています。
1. 訓練用データ（お客さんの情報＋生死が与えられている）
2. テスト用データ（お客さんの情報しか与えられていない）
が与えられており、基本的には1のデータを使ってモデルを作成し、そのモデルを2のデータに当てはめた時に、どの程度の割合で正解しているか、その精度を競うという課題です。

最初は、何でデータが2種類あるんだろう？という超初歩的な疑問を感じていました。（Kaggleが何をやるものなのかわかっていなかったのです。）
いろいろ調べた結果、問題と答えが与えられているセット（訓練用データ）を分析し、問題と答えの間に関係性を見出し、その関係性が未知の問題にどれだけ対応できるのか、その精度を競うということだとわかりました。
未知の入試問題を解くために、過去問の分析手法を高めていく感覚に近いのかな、と思いました。

さて、肝心のデータの前処理、加工、モデル構築ですが、もちろん自力でできるわけなく、Udemyの講座やYoutubeの動画を見てコピペをして動かすのが精一杯でした。
とにもかくにも、スタートから提出までいけたときは少し嬉しかったです。（カンニングしてますけども）

## Kaggleの挑戦② - 何を勉強すれば良いか整理 -

Kaggleを提出したはよいけども、ある疑問がメンバーの中に（というか僕の中に）湧いてきました。
**どこをどのように変更すると、結果が変わるんだ、と・・・・・**

そこで、コミュニティ内で相談させてもらったり、ググったりして、データ分析には大きく2つの段階があり、それぞれの段階で学ぶことが異なる、というのが現状の僕の理解です。
やっていることをもう一度整理すると、
1. 目的とするものに対して、関連しそうなデータを選び、加工する
2. 加工したものに対して、アルゴリズムを当てはめて、モデルを構築する
ということでした。

こちらの動画がとてもわかりやすかったです。

https://www.youtube.com/watch?v=PARsDyRJMWE


1については、計算するデータとして扱いやすい型（数字）を選ぶ、とうことであったり、pandasやmatplotlibなどを使って、データを可視化したり加工したりすることを指していて、
2については、さまざまなアルゴリズム（ランダムフォレストとかロジスティック回帰とか）を適用してモデルを構築する、
上記1、2の段階でさまざまな手法を用いてデータと向き合い、予測したいものの精度を高めていく、という大枠は何となく掴めたような気がしています。
（とはいえ、自力で1と2を行うには、①それぞれの処理やアルゴリズムを理解し、②適切なタイミングで使うという2段階の難しさがあり、道は険しそうです。）
Kagglerになれるよう、一歩ずつ勉強していきたいです。

## 終わりに
少しでしたが、勉強会でやってきたことをまとめました。
2022年2月には、Kaggleのもう一つの有名なチュートリアルである[住宅価格予測](https://www.kaggle.com/c/house-prices-advanced-regression-techniques "住宅価格予測")のデータ加工〜アルゴリズム選定までをそれぞれで行い、発表会をします。
ぜひ、AIを学びたいという方、今がAIRS-Labに入会するタイミングかもしれません。
一緒にAIを学びましょう。
ATOM Displayの内部処理概要

# 概要

2021年10月29日に、M5Stackより [**ATOM Display**](https://docs.m5stack.com/en/atom/atom_display) が発売されました。

ATOM Displayは、M5AtomシリーズのモジュールからHDMI接続のディスプレイに対して画像を出力するための **ディスプレイコントローラ** です。
画面付きのM5Stack/StickCシリーズに内蔵されている画面に描画するのと同様に、PCのディスプレイ等に画像を表示することができます。

既存のユニットで一番近いのは、Grove互換ポート経由で液晶画面を増設することができる [UnitLCD](https://docs.m5stack.com/en/unit/lcd) です。

このATOM DisplayのFPGAの中身は筆者が開発していますので、簡単にですが解説してみようと思います。(ちゃんとした解説は技術書典ネタの予定)

# 中身

![ATOM Displayのブロック図](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/58388/df1e4e7a-95cf-0044-64a3-c9151fe59fb9.png)

ATOM Displayは主にM5Atomからのコマンドを処理してビデオ信号を生成するFPGAと、FPGAからのビデオ信号をHDMIに変換するHDMIトランシーバから成ります。
FPGAとしてGOWINの `GW1NR-LV9QN88C6/I5` を使っています。このFPGAは同じパッケージ内に `64[Mbit] (8[MiB])` のSDRAMを内蔵しており、ディスプレイに描画する画像を保持するフレームバッファ等に使用しています。

FPGAの内部は、M5Atomからのコマンドを受け取り内部のフレームバッファへの描画などを実行する **Command Processor** 
Command Processorからの指示でフレームバッファの矩形範囲への読み書きを行う **Stream Reader** / **Stream Writer**
フレームバッファを繰り返し読み出す **Frame Buffer Reader**
読み出したフレームのピクセルデータをビデオ信号のタイミングに合わせて出力する **Video Signal generator** 
から成ります。

ブロック図中のうち、グレーのブロックは、GOWINが提供するIPです。緑色の部分は、今回ATOM Display向けに作成したモジュールです。

ATOM Displayのデフォルトの出力解像度とレートは `1280x720@60` です。よってデータレートはピクセル当たりのバイト数を3[bytes]とすると、 `1280*720*60*3 = 165.888[MB/s]` となります。
一方、フレームバッファに使っているSDRAMのバスの理論帯域は `16[bit] * 140[MHz] = 280[MB/s]` です。

これだけ見ると余裕がありそうですが、実際にはM5Atomからのコマンドに応じてフレームバッファへの読み書きを行う必要がありますので、あまり余裕はありません。

# ソフトウェア

ATOM Displayは単なるSPIのコマンドを受けて画像の出力を行うディスプレイコントローラでしかありません。これをM5Atomから適切に制御して初めてユーザーの表示したいものを表示することができます。

このあたりは らびやんさんにLovyanGFX/M5GFXをいろいろ調整していただいたおかげで、M5Stack/StickCの液晶画面を扱うのと同様に、非常に簡単にディスプレイに描画することができるようになっています。
ATOM Display側にいろいろコマンド実装したらすぐに使いこなしてもらえるので非常にありがたい…

最終的にリフレッシュレートは限定的 (24Hz) ながら、FHD (1920x1080)の解像度表示ができるようになったり、逆に解像度を小さくして240[Hz]のリフレッシュレートに対応したりということができています。

https://twitter.com/lovyan03/status/1460522552799891457

こういった機能を実現するために、FPGA側に実装するコマンドはらびやんさんといろいろ話し合って決めています。現在のコマンドはM5GFXのソースコード中に記載されていますので、興味がある方は確認してみてください。

https://github.com/m5stack/M5GFX/blob/master/src/lgfx/v1/panel/Panel_M5HDMI.hpp#L117

# ソースコード

FPGAのデザインを公開しました！…　と言えればよかったのですが、ソースコードの整理が間に合いませんでした。

前述のCommand Processorの部分以外は筆者のリポジトリに既に置いてありますので、興味のあるかたは見ていただければと思います。


公開しました!

https://github.com/ciniml/atom_display_fpga
Nuxt2(composition-api)でGoogle MapとMakerを表示

とりあえず備忘録。

## APIキー取得
APIを`Maps Javascript API`を許可してKEYを取得。
`.ENV`に追加して、`nuxt.config`で`publicRuntimeConfig`に設定

```
const config = {
  publicRuntimeConfig: {
    gmapAPIKey: process.env.GMAP_API_KEY,
  },
 // :
```

## ライブラリ
公式に沿って、mapとmakerのライブラリを追加

```
npm i -D @googlemaps/js-api-loader @googlemaps/markerclusterer
```

typeを追加

```js:tsconfig.json
{
  "compilerOptions": {
    "types": [
      "@googlemaps/js-api-loader",
      "@googlemaps/markerclusterer"
      　// ：
```

## vueファイル作成

とりあえず`this.$refs`代わりの`空ref`を追加して、全画面表示になるようにCSSを設定。ライブラリも読み込む

```vue:index.vue
<template>
  <div ref="googleMapEl" class="googlemap" />
</template>

<script lang="ts">
import { defineComponent, ref } from '@nuxtjs/composition-api'
import { Loader } from '@googlemaps/js-api-loader'
import { MarkerClusterer } from '@googlemaps/markerclusterer'

export default defineComponent({
  setup () {
    const googleMapEl = ref()

    return {
      googleMapEl
    }
  }
})
</script>
<style scoped>
.googlemap {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
</style>
```

## Loaderの作成
contextから、configで設定したAPIキーを呼びだし、setup内でLoaderインスタンスを作成

```js
setup () {
    const context = useContext()
    const { $config } = context
    const loader = new Loader({
      apiKey: $config.gmapAPIKey
    })
}
```

## 各初期化

```js
const GOOGLE = ref()

onMounted(() => {
  createMapLoader()
})

const createMapLoader = () => {
  loader.load().then((google) => {
    GOOGLE.value = google
    initMarker()
    initMap()
  }).catch(e => {})
}
```

##　MAPの初期化

`onMounted`でマップを初期化。
loader使って,マップを新規に作成。ここで作った値をmaker側でも使うので、setup内で使えるようにしとく
template内の`googleMap`に描写。
maker用のインスタンスもついでに初期化

```js

const MAP = ref()

const initMap = () => {
  const mapOptions = {
    center: {
      lat: 35.6769883,
      lng: 139.7588499
    },
    zoom: 12
  }
  MAP.value = new GOOGLE.value.maps.Map(googleMapEl.value, mapOptions)
}
```

## マーカーを初期化
空配列でマーカー用のクラスターを生成しとく

```js
const markerClusterer = ref()

const initMarker = () => {
  const markers = [] as any[]
  markerClusterer.value = new MarkerClusterer({ markers, map: MAP.value })
}

```

## onClickでマーカーを追加

```js
const onClick = () => {
  const marker = new GOOGLE.value.maps.Marker({
    position: { lat: 35.6769883, lng: 139.7588499  }
  })
  markerClusterer.value.addMarker(marker)
}
```

## マーカー自体をonClickでマーカー削除
マーカーを作成するときに、自滅用イベントを追加

```js
const onClick = () => {
  const marker = new GOOGLE.value.maps.Marker({
    position: { lat: 35.6769883, lng: 139.7588499  }
  })
  // 上記削除イベントを追加
  marker.addListener("click", () => {
    markerClusterer.value.removeMarker(marker)
  })
  markerClusterer.value.addMarker(marker)
}
```
Snowflake 2021年 よかったこと5選

# この記事は

[Snowflake Advent Calendar 2021](https://adventar.org/calendars/6220) の1日目の記事です。
去年のアドベントカレンダーからもう1年経ったんですね。
早いものです。

この記事では 2021年に Snowflake 関係で **個人的に良かったな** と思ったことを振り返って5つ紹介しようと思います。
※2021年より前にあったけど、私が2021年に気づいたことや知ったことも含みます


## 第5位： External Table を使ってロードするのが COPY INTO より早くて安い時がある

第5位は「External Table を使ってロードするのが COPY INTO より早くて安い時がある」です
これはあまり知られていない挙動だとは思うのですが、 Parquet で作られた External Table がめちゃくちゃ早いんです。
その結果、 COPY INTO で愚直にテーブルへロードするよりも、External Table を使って SELECT INSERT したほうが早いケースが実はあります。
これは一緒に働いていた同僚が発見したテクニックだったのですが、聞いたときにまじかよ！？って言っちゃいました。

>Parquetファイル形式を扱う External Table はベクトル化スキャナーと呼ばれる仕組みによりクエリのパフォーマンスが高くなるよう最適化されています。
- 同僚の検証記事より：https://datumstudio.jp/blog/1015_snowflake_15/

ベクトル化スキャナーーーー！！！！
はいみんな今日はこれ覚えてね！！！

## 第4位： そういえば FROM DUAL が使えるYO！

第4位は「FROM DUAL が使える」です
(これはもしかしたら2020年かもしれないのですが) [SnowVillage](https://www.youtube.com/channel/UC-FKvkAWBegvxZF4jkP7sLA) 関係者に教えてもらいました。
Oracle 出身者ならみんな知ってる例のアレです。 

知らない人向けに説明すると、DUAL表は何も入っていない1列0行の表のことです。
Oracle ではFROM句がないと文法エラーになってしまうので、何も入っていない表として、DUAL表が実装されているのですが、 Snowflake にもこのDUAL表が実はあるという話です。
おそらく互換性のためなんだと思います。

たとえばこんなクエリで使います。

```
SELECT SYSDATE() FROM DUAL;
```

割とウンチクかなと思いますが、こういう互換性のための配慮と実装がされているのが、 Snowflake の良いところですよね。

## 第3位： Snowflake で謎解きゲームした！

第3位は「Snowflakeで謎解きゲームした」です。
これはSnowVillageの配信企画でやったのですが、色んな人に参加いただき、Snowflakeコミュニティの可能性が広がった面白い取り組みでした。
企画や準備に携わったコミュニティのメンバーや参加してくれたユーザのみんなには感謝しかありません。

また機会があればやりたいですね。

- 配信アーカイブ：[Snowflakeでライブ謎解きゲーム！SQLやBIの知識を駆使して参戦せよ](https://www.youtube.com/watch?v=Mj-jv77T-Vo)

## 第2位： Snowparkがリリースされた！

第2位は「Snowparkがリリースされた」です。

これは本当に良かった。
Snowflake ってこれまで SQL を打つしかなかったんですが、それがいきなりプログラマブルな世界に移行しました。
普段のワーキングを Scala でやってる人は、もう SQL 打たなくていいやんけ！っていう感じで、世界が変わりました。
僕自身はは Scala がそこまで得意じゃなかったので、 Snowpark 使うためだけに Scala を再勉強したくらいです。


- 参考：[Snowparkへようこそ: データクラウドのための新しいデータプログラマビリティ](https://www.snowflake.com/blog/snowpark%E3%81%B8%E3%82%88%E3%81%86%E3%81%93%E3%81%9D-%E3%83%87%E3%83%BC%E3%82%BF%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E6%96%B0%E3%81%97%E3%81%84%E3%83%87%E3%83%BC/?lang=ja)

## 第1位： SnowparkがPython対応した！！

そして栄えある第1位は「SnowparkがPython対応した」でした！
そうです。Data分析界隈だと、 Scala より Python 勢が多くて、待望の Python 対応でした。
噂ではいつ対応なんだ？みたいなのは流れていたんですが、ついに先月の Snowday で発表され、みんなを驚かせましたね。
個人的にはまだ使えてないので、評価はできないんですが、使えるようになったらいち早くレポートできたらと思ってます。

早く使いたい！

## まとめ

20201年 Snowflake で良かったことでしたがいかがでしたでしょうか？
紹介した以外にも、たくさんの驚きやすげーが Snowflake にはあった1年でした。
来年もいろんなアップデートが来て驚かされるに違いないですね。
今からとても楽しみです。

それでは2日目以降のアドベントカレンダーもご期待ください！
八幡平スマートファームで使われている技術

私は学校の見学で八幡平スマートファームを見学し、そこで使われているスマート農業の技術を

学んでみて私がこれからIT事業について学ぶとき役に立つ技術だと思いました。

なので、私が学んだ八幡平スマートファームのことを自分なりにまとめて記事にすることで

私と同じようにIT事業を学ぶときに役立ててほしいと思いました。

#八幡平スマートファームとは

八幡平スマートファームは、放置されていた地熱発電から供給する熱水を暖房に活用する

ビニールハウスをICTの技術を使って再生し、スマート農業として地域に貢献するように

したのが八幡平スマートファームです。

#八幡平スマートファームの技術

八幡平スマートファームでは現在ビニールハウスでバジルを栽培しています。

なぜバジルなのかというと、バジルの適温は20～30度とされておりこの適正温度は

熱水ビニールハウスなら冬場でも保てるからだそうです。

そしてその適正温度を保つためにビニールハウス上部にパイプを設置し、そこに

熱水を流すことで温度を上げることができ、ビニールハウスの温度や湿度などを

読み取り、熱水や換気、養液供給などを制御するシステムを作ったようです。

#感想

今回、このようにカレンダーに自分で記事を考えて作成してみて、まず何について書くかを

決めるのに時間がかかりました。そして実際に記事を作成してみて、あまりよくできた自信が

ありませんがこの記事を読んでもらってもっとIT事業についてもっと学びたいと思ってくれたら

いいと思いました。
LaTeXで行列の行または列に説明を付け加える方法

## やりたいこと

LaTeXで行列の行または列に説明を付け加えるようなことがしたいです．
例えば，以下のような画像を出力したいです．
![blockarray1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178972/20134d99-38d1-09ad-66ee-94ef1e3d3883.png)

## 方法
### 用いるパッケージ

**blockarray**というパッケージを用います．**Overleafでも使える**ことは確認済みです．

```LaTeX
\usepackage{blkarray}
```

本記事は，行または列に説明を入れることが目標なので，blkarrayの詳細には触れませんが，
より高度なことをしたい場合は[konoyonohanaさんのブログ](https://konoyonohana.blog.fc2.com/blog-entry-334.html)か[CTANのblkarray](https://ctan.org/pkg/blkarray)にあるドキュメントを参考にしてください．  

### 実装方法

やりたいことで載せた図の実装についてです．
![blockarray1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178972/20134d99-38d1-09ad-66ee-94ef1e3d3883.png)
波括弧は`\overbrace`, `\rbrace`で無理やり付けていますが，他にいい方法があるかもしれません．

```LaTeX
\begin{equation}
\begin{blockarray}{cccccc}
e_1 & \overbrace{}^{2列目} & \overbrace{}^{3列目} & \overbrace{}^{4列目} & ones \\
\begin{block}{(ccccc)c}
  1 & 1 & 1 & 1 & 1 & ones  \\
  0 & 1 & 0 & 0 & 1 & \rbrace \, 2行目 \\
  0 & 0 & 1 & 0 & 1 & \rbrace 3行目\\
  0 & 0 & 0 & 1 & 1 & \rbrace 4行目\\
  0 & 0 & 0 & 0 & 1 & e_5 \\
\end{block}
\end{blockarray}
\end{equation}
```

### より単純な例

![スクリーンショット 2021-11-30 230412.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178972/54755cb5-74ea-f036-7b58-134353bab237.png)

```LaTeX
\begin{equation}
\begin{blockarray}{cccccc}
a & b & c & d & e \\
\begin{block}{(ccccc)c}
  1 & 0 & 0 & 0 & 0 & v  \\
  0 & 1 & 0 & 0 & 0 & w \\
  0 & 0 & 1 & 0 & 0 & x \\
  0 & 0 & 0 & 1 & 0 & y \\
  0 & 0 & 0 & 0 & 1 & z \\
\end{block}
\end{blockarray}
\end{equation}
```
Ubuntuでマイクのノイズを軽減する時にハマったこと

## 背景
最近開発をUbuntu20.04でやっていて、ZoomやTeamsのようなビデオ通話も今後使いたく、マイクを繋いでみました。
（ミニタワーの自作デスクトップでフロントのマイク3極＋イヤホン3極に4極変換プラグをかましてEarPodsを接続）
[サンワサプライ ヘッドセット用変換アダプタケーブル(4極メス->3極オスx2) 黒 KM-A24-005](https://www.amazon.co.jp/gp/product/B01BV9153Y/ref=ppx_yo_dt_b_asin_title_o04_s00?ie=UTF8&psc=1)

Teamsのテスト通話をやってみたところ、**ノイズが酷く**、比較のため手持ちのMacBook Proでテスト通話をやってみるとノイズはありませんでした。

## 調べたこと
調べたところ、Mac等では音声入力に対しノイズ軽減をしているとのことで、LinuxではPulseAudioの**エコーキャンセルモジュール**を使うと良いようでした。
使用しているUbuntu20.04もデフォルトでPulseAudioは入っており、設定ファイルにひと手間加えることでノイズ軽減ができるようでした。

## ハマったこと
ネットの情報を頼りに`/etc/pulse/default.pa`に`load-module module-echo-cancel`を追記して、とやったところ、確かにオーディオ設定で`(echo cancelled ...`の選択肢が出てくるのですが、これが音が出ません。
よく見ると`USB3.0 capture Analog Input (echo cancelled ...`となっており、現状ノイズはあるが音が出ている`Built-in Audio`ではないようです。**これの正体**に気づくまでに時間がかかりました。

## 見落としていたこと
気づけばしょうもない話なのですが、実はこれ数ヶ月前にPCにUSBで差し込んでいたHDMIキャプチャーボードのようでした。（忘れてました...←）
[Chilison HDMI キャプチャーボード](https://www.amazon.co.jp/gp/product/B08D66RBWC/ref=ppx_yo_dt_b_asin_title_o06_s00?ie=UTF8&psc=1)
どうやらアナログのinputよりこちらが優先されてエコーキャンセルが適用されていたようで、それでマイクからのinputに適用されていなかったようです。

## 解決した方法
[How To Enable Echo / Noise Cancellation Of Microphone Input On Your Linux Desktop (PulseAudio)](https://www.linuxuprising.com/2020/09/how-to-enable-echo-noise-cancellation.html)
こちらの記事の「**How to choose the microphone in setups with multiple microphones, to use with the PulseAudio module-echo-cancel**」の章に求めていた答えがありました。
どうやらinputするデバイスが複数ある場合、エコーキャンセルにどれを適用するか指定ができるようです。

詳細はリンク先を見て頂ければと思いますが、こちらの方法で繋いでいるマイクの方が適用になるようにしたところ、無事`Built-in Audio Analog Stereo (echo cancelled ...`が表示され、Teamsのテスト通話でノイズキャンセルされたマイク入力の確認ができました:thumbsup:

## 余談
ここまでやってみてですが、ノイズは消えたものの音がこもってるような感じもするので、音質自体はデバイスの問題もあるかもしれないです。（PC側や4極変換プラグ等）
→追記：USB接続できる変換プラグを買い直したら音質は解決しました（ただノイズが少しあって結局エコーキャンセルは必要でした）
[UGREEN USB オーディオ 変換アダプタ](https://www.amazon.co.jp/gp/product/B08JZ517FV/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&th=1)

また、あまり自分のようなケースの人はいないと思うので、今回情報が出てこず手こずりました:sweat_smile:
もし似た境遇で困っている人がいたらヒントになると良いなと思います。
はじめてのdraw.ioでAWS EKSシステム構成図作成

これを作った↓
![](https://i.imgur.com/K1ie8Xh.png)

## はじめてのdraw.io所感

[draw.io](https://www.draw.io/)なるサービスによってシステム構成図を書かれている方が多いそうなので自分も使ってみた。ブラウザベースでシステム構成図をかけるサービス。VSCodeエクステンションもあるような話だったと思うが今回は使っていない。


良かった点

- AWS, GCPなどのリソースアイコンがあらかじめ用意されているので画像をいちいち引っ張ってきて、という動作が必要ない
- 矩形操作や矢印の配置に特化されているため、直感的に操作できた 
- github連携できるため管理が楽

悪かった点(自分が使いこなせていないだけの可能性は高い)

- グルーピングされている要素の操作が少しむずかしい(ex. 操作するつもりのない要素までサイズが変更されたりする)
- 要素の前後関係の管理が大変: 何層も要素が重なる関係で操作を行い難い(これに関してはショートカットを駆使したりすれば解決するのだろうか?) 

結論

なんでいままでパワポで作っていたんだろう draw.io最高です


## eksctl create cluster でデフォルトでクラスター作成したときのシステム構成図


``` 
eksctl create cluster \
  --name hoge \
  --nodegroup-name hoge-node-group \
  --node-type t3.medium --nodes 1 --nodes-min 1 --nodes-max 1
```

例えばこのようなコマンドでEKS上にクラスタを作成した場合、裏側でAWS CloudFormationが実行され

- VPC
- VPC内の異なる3つのavailability zoneにそれぞれpublic, privateのsubnet
- NodeとしてのEC2インスタンス
- etc(AWS IAM Role, ...)

が作成される

更に筆者が作成したサービスの場合

- Ingress ControllerとしてAWS ALBを設定
- Route53でドメインを取得し、ACMで取得した証明書をあてる
- ECR上にDocker レポジトリを作成しversion管理

というような構成にしたため、ページ上部の図のようになった

↓は今回使用したレポジトリです。eksctl create cluster使ったときの整理の足がかりに是非。issueやFork待ってます。

[https://github.com/puppypepper/eksctl_drawio](https://github.com/puppypepper/eksctl_drawio)

## おわりに

めちゃめちゃ初学者なので、間違っている部分多々あると思います。ご指摘待ってます。
クイックソート (QuickSort) の平均計算量の簡単な証明

この記事は [paiza Advent Calendar 2021](https://adventar.org/calendars/6343) の1日目の記事です。

QuickSort(クイックソート)が、ちょっと話題になっているようですね。
平均計算量がO(n log n)というのは知識として知っている人もいると思いますが、なぜそうなるのかは証明を見る機会は少ないと思い、調べてみました。

Wikipediaには3つの証明が書かれていますが、ここでは一番簡単そうな方法、4分割法とでもいうでしょうか、を紹介します。

## ４分割法

クイックソートで配列を分割するとき、なるべく真ん中で分割する方が効率がよくなります。

分割時のピボット要素の順序が比較的真ん中の1/4〜3/4になる確率は50%です。これを幸運な場合と呼びます。

幸運な場合の中で最悪の場合は、配列が25%と75%に分割される場合です。分割のたびに、幸運が続き、この分割を繰り返すといつか分割された配列は一つになります。
つまり、分割回数をdとすると、幸運な場合の中で最悪の場合、以下の様になります。

$ 1 = n * (\frac{3}{4})^d $

変形すると

$ (\frac{4}{3})^d = n $

さらに変形して

$ d = log_{\frac{4}{3}} n $

これが、幸運な場合の最悪分割回数になります。


次に、残りの50%の不運な場合も考えます。不運な場合については、もう一回分割を行なってみます。それでも不運なら、もう一度分割、、、とするといつか幸運な場合が訪れます。平均すると、半分の確率で幸運は訪れるので、ずっと幸運な場合の平均2倍の分割回数になります。

つまり、$ 2 * log_{\frac{4}{3}} n $ となります。

分割回数ごとにn回の比較があるのでn倍になります。
これを、数字を消してO記法にすると、

$ O(n * log(n)) $

となります。

## 他の方法

漸化式を用いる方法、２分探索木と対応させる方法があるようです。

## 参考

[Wikipedia QuickSort - Using percentile](https://en.wikipedia.org/wiki/Quicksort#Using_percentiles)

[Analysis of quicksort
](https://www.khanacademy.org/computing/computer-science/algorithms/quick-sort/a/analysis-of-quicksort)
Macユーザが久しぶりにWindowsを買った時のキーマップの設定

#はじめに
自分は仕事でもプライベートでもMacユーザで、もう10年くらいMacをメインに使っていてWindowsはXP以来触ってなかった。
そんな自分が、なぜWindowsパソコンを購入しようかと思ったのは、生活に変化が欲しかったから。もちろんM1 Macの性能は知っていたがスルー。

#キー配列の戸惑い
Macは⌘キーがメインの修飾キーなのだが、WindowsはCtrlがメインの修飾キーだ。そこにギャップがある。
普通のWindowsのキーボードではCtrlは左端にあり、Macの⌘キーに相当する場所には、Winキーが配置されているので、はじめはコピペさえストレスがMaxだった。
出来るだけPCはデフォルトで使っていく主義なのだが、流石に仕事のMacを辞めるわけにはいかないので、Windowsを出来るだけMacのキー配列に寄せるようにした。

## 使ったソフトウェアが下記3つ
### [Change Key](https://forest.watch.impress.co.jp/library/software/changekey/)
特定のキーを変換してくれるソフトウェア。レジストリを書き換えててくれるみたいで、常駐するアプリもなくて良い。

- Win→Ctrl
- Ctrl→Win
- CapsLock→Ctrl


### [Google IME](https://www.teradas.net/archives/2927/)
IMEの設定でキーを割り当ててることができる。

- 変換→IME無効化
- 無変換→IME切り替え


### [AutoHotKey](http://ahkwiki.net/Top)
これは10年前も利用していたソフトウェア。
できればデフォルトで使いたいんだけど、
＜Ctrl-h＞＝backspaceは脳では制御できないレベルに染み込んでいる設定なので、backspaceだけは設定した。

# Windowsの感想
Windows11を使っているが、画面もきれいで使い勝手が良い。ただ、このQittaの記事書いている時に感じたのが、ブラウザのエディタ画面はアンチエイリアスかかってなさそうで、Windowsだなって感じがした。
買ったPCがタッチパネル対応で画面をタッチで操作できるのが良い。利用用途によってはトラックパッドではなく、タッチパネルのほうが直感的に操作しやすい場面は多々あるので、Macにはない点でQOLが上がった気がする。iPadは使わなくなってきた。
AtCoderBeginnerContest113でつまずいた(absの戻り値の違い)

##経緯+つまずいたポイント
C++に関しては初心者で、文法の勉強を兼ねてAtCoderに挑戦していました。
ABC113のB問題に取り掛かっていたところ、合っているはずのコードが何故かWAとなってしまいます。
###WAとなったコード

```c++
#include <iostream>
#include <bits/stdc++.h>
 
int main()
{
    int N, T, A;
    std::cin >> N >> T >> A;
 
    std::vector<int> H(N);
    for (int i = 0; i < N; i++){
        std::cin >> H[i];
    }
 
    double minValue = 710;
    int minIndex = 0;
    for (int i = 0; i < N; i++){
        double tmp = abs(A - (T - H[i] * 0.006));
        if (tmp < minValue){
            minValue = tmp;
            minIndex = i;
        }
    }
 
    std::cout << minIndex + 1 << std::endl;
    return 0;
}

```

1,2時間ほど考えられる箇所を修正しては戻し、修正しては戻しを繰り返したところ
「abs」が意図した出力になっていないことが分かりました。
###std::absとしないといけないらしい？
例えばabs(-2.3)とすると戻り値は2となるようです。(小数点以下切り捨て？)
std::abs(-2.3)はちゃんと2.3になる。。。
ただしこれはGCCのときのみで、Clangだとどちらも2.3になりました。


##それぞれの出力をまとめた

###①GCC 9.2.1(abs)
```c++
#include <iostream>

int main(){
  double value = -2.3;

  std::cout << abs(value) << std::endl; //出力->2
  return 0;
}

```

###②GCC 9.2.1(std::abs)
```c++
#include <iostream>

int main(){
  double value = -2.3;

  std::cout << std::abs(value) << std::endl; //出力->2.3
  return 0;
}

```

###③Clang 10.0.0(abs)
```c++
#include <iostream>

int main(){
  double value = -2.3;

  std::cout << abs(value) << std::endl; //出力->2.3
  return 0;
}

```

###④Clang 10.0.0(std::abs)
```c++
#include <iostream>

int main(){
  double value = -2.3;

  std::cout << std::abs(value) << std::endl; //出力->2.3
  return 0;
}

```

##引き続き詳細は調査
とりあえず備忘録として記事にしましたが
いまいちわからない箇所が多いので、追記・修正していきたいと思います。
レシートOCRのWebサービスを作ったみた(アーキテクチャ編)

# はじめに
最近、自炊しているが食費が高く，食材費を把握したくなった．
キャッシュレスサービス等で支出全体は把握できるが食材費に限定するには，レシートをOCRする必要がある．
レシートOCRは数社がサービスを提供しているが、読み取り精度が自身の要件を満たしていないため自作することにした．

# シリーズ構成
1. アーキテクチャ編 (本記事)
2. バックエンド編 Part1 https://qiita.com/Himajiro2/items/c646459f33101c9dd2ea
3. バックエンド編 Part2 (編集中)
4. バックエンド編 Part3 (編集中)
5. フロント編 (編集中)

# 要件
- スマホでレシートの写真を取ったらすぐにOCR結果が出力されること
- よく行く店のOCR精度は上げたい
- サービスは低コストで運用

# 今回見送ったこと
- 全てのレシートには対応していない
  - 特に品目と金額が改行されているレシートには対応しない (対応工数が多く取られることと、普段行く店舗にはあまりなかったため)
  - また、全てのレシートを汎用的にOCRする手法は見当たらないため対応しない

# 技術選定の前提
- 基本的には普段自分が使う技術を中心に選定
- バックエンドはサーバレスにし, バックエンド間の通信をEventarcで実現した
- 最初にスマートフォンアプリの「Googleレンズ」　→　スプレッドシートに手動コピー　→　GASで整形
というものを作ったが、手作業をなくしたいため別の方法を検討．
- Webが好きなのでWebで実現することにした．

# 技術選定
- フロント: Angular (Firebase Hosting)
- APサーバ: Flask (Cloud Run)
- OCR: Google Cloud Vision API (非常に精度が良く無料枠で十分に運用できそうだったため)
- ホスティング、認証、オブジェクトストレージ、DB: Firebase
- その他: Cloud Run間の通信はEventarc

# Eventarcとは
Google CloudのリソースからCloud Runのサービスでイベントを送信できる機能.
GCPの監査ログから特定のログを読み取り, CloudEvents形式のイベントとしてCloud Runへ送信しサービスを起動できる.
また, 既存のPub/Subからトピックを読み取りトリガーとすることもできる.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702055/6ee15388-0818-4521-dfb2-4bb1fc632c19.png)

https://cloud.google.com/blog/ja/products/serverless/eventarc-unified-eventing-experience-google-cloud

### Cloud Events
CNCFが定めるクラウドのイベント通知の標準仕様.

https://cloudevents.io/

# 各サービスの職責
![Arcitecture-ReceiptOCR.drawio (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/702055/136fb1dd-f41d-0e3d-3e38-a51f51e901e7.png)


- フロント:
 - レシート画像を撮影し，original-bucketにアップロード
 - OCR結果の保存先であるFirestoreを読み込み表示する
- image-preprocess:
 - original-bucketのレシート画像をバイリニア補正をかけて解像度を向上させる
 - 補正後の画像をresampled-bucketに保存する
 <br>(レシート画像はJavaScriptのMediaDevices API経由で取得した画像ではOCR精度が低かったため補正をかけている)
- vision-formatter:
 - resampled-bucketの画像をGoogle Cloud Vision APIに渡す
- db-writer:
  - vision-formatterから受け取ったVision APIの結果をFirestoreに格納する

# 今後
- OCRの部分が汎用的ではないため、まだ認識できないレシートがある．
- 今後は整形部分のロジックに汎用性を持たせ、店舗を判別して最適な整形ロジックを適用するなどに挑戦したい．
- その際、フロントでOCR結果を複数表示させ、最も精度が良いものを選び、この店舗はこのロジックが適しているなどの実績が取れるとサービス満足度の向上が期待できる．
- 各サービスのコード解説は別記事でまとめる

# 参考リンク
- https://cloud.google.com/blog/ja/products/serverless/build-event-driven-applications-in-cloud-run
- https://qiita.com/shoku-pan/items/bf5645894803769edc72
android端末をひかり電話の子機に設定する

不要になったandroid端末をひかり電話の子機に設定した話（備忘録）

## ホームゲートウェイ／ひかり電話ルーターの設定
### 使ったルーター
PR-500MI

### 設定
電話回線＞内線設定 で未登録の内線番号の[編集]をクリック

- 内線番号：メモする
- ニックネーム：わかりやすいように端末名などを設定
- 端末属性：[音声専用端末]に設定（[通常端末]でもよいと思う）
- MACアドレス：端末のMACアドレスを設定（設定しなくてもよい）
- ダイジェスト認証：[行う]に設定
- ユーザID：メモする
- パスワード：メモする（変更してもよい）

## android端末の設定
### 使った端末
zenfone 4 Max

### 設定
設定＞通話設定＞通話アカウント＞SIPアカウント で[＋]をタップして編集画面を開く

- ユーザ名：メモした内線番号を設定
- パスワード：メモしたパスワードを設定
- サーバー：ホームゲートウェイ／ひかり電話ルータのIPアドレスを設定
- オプション設定を開く
- 認証ユーザ名：メモしたユーザIDを設定
- ポート番号：5060
- 伝送方式：UDP

以上を設定して[保存]をタップ

設定＞通話設定＞通話アカウント

- SIP通話の使用：子機専用なら[すべての通話]、SIM回線と選択したいなら[SIP通話のみ]を選択
- 着信を受ける：着信を受けたいならチェックを入れる

以上
SBCとUSB Webカメラを使って画像をGoogle Photosに保存するクラウド対応カメラを作る

Raspberry PiなどのLinuxが動くSingle Board Computer (SBC) と安く手に入るWebカメラを組み合わせると、Google Photosに定期的に画像を保存するクラウド対応のカメラを比較的かんたんに作ることができます。

毎分程度の撮影頻度＋低解像度でもOKなのであれば、安価な監視カメラのソリューションとして悪くないのではないでしょうか？

## 基本的な動作原理

[cron](https://ja.wikipedia.org/wiki/Crontab) により定期的に以下の処理を行うシェルスクリプトを実施実行します。

1. Webカメラから画像を一枚取得してJPEGに保存する。（例：[opencv_capture_jpg.py](https://gist.github.com/aikige/bb9f57e9f0e4f7743c36770549d0e168)）
1. 取得した画像をGoogle Photosに送る。（例：[google_photos_uploader.py](https://github.com/aikige/google-photos-uploader/blob/main/google_photos_uploader.py)）

これにより、簡易な実装で実現可能です。

## ソフトウェアのセットアップ方法

`opencv_capture_jpg.py` の依存ライブラリ、`python3-opencv` をインストールします。
apt でパッケージがダウンロードできるので今回はそちらを利用しています。

```
apt install python3-opencv
```

`google_photos_uploader.py` の依存ライブラリをインストールします。

```
sudo pip install google-auth-oauthlib
```

`opencv_capture_jpg.py` と `google_photos_uploader.py` を GitHub からダウンロードして、作業フォルダ（例: `/home/pi/uploader`）に保存します。

Google Photosに対する Authentication を実施します。
Authentication の手順の詳細は、スクリプトの [README](https://github.com/aikige/google-photos-uploader/) を参照してください。

```
python google_photos_uploader.py
```

作業フォルダに以下のような内容のシェルスクリプト `sched_upload.sh` を作成します。

```
#!/bin/bash
jpg=$(date +%Y%m%d_%H%M%S.jpg)
python opencv_capture_jpg.py $jpg > exec.log 2>&1
python google_photos_uploader.py $jpg >> exec.log 2>&1
rm $jpg
```

実行権限を設定してください。

```
chmod 755 sched_upload.sh
```

cron のタスクをスケジュールします。

```
crontab -l > cron.txt
echo "*/1 * * * * /home/pi/uploader/sched_upload.sh" >> cron.txt
crontab cron.txt
```

これで、画像が Google Photos に毎分アップロードされるはずです。

## 長所

* 仕組みが非常に単純なので、問題が発生しづらく、cron で動かしているので、何かの原因で本体に再起動がかかっても正常に再開される可能性が高い。
* 保存のためのNASを用意したりしなくてよいので取り回しが良い。
* 比較的安価に用意できる。
* アップロードのスクリプトを差し替えればいろいろな環境に対応できます（Flickrの例：[flickr_uploader.py](https://github.com/aikige/flickr-uploader/)、Slackの例: [slack_photo_uploader.py](https://github.com/aikige/slack-photo-uploader)）

## 短所

1. Google Photos APIは、Quota（利用回数の制限）があるのであまりたくさん写真を保存するのには向いていません。
1. cron で実施した場合、最低の時間分解能は1分です。それ以上の頻度で撮像したい場合はシェルスクリプトの側でループを実装したりする必要があります。

## 関連記事

https://qiita.com/aikige/items/6419fcc79bea27b2152c

## 動作確認した環境

1. SBC: Raspberry Pi 4B
1. OS: Raspberry Pi OS Lite
1. Webカメラ: [Logitec C270n](https://amzn.to/31eNAxY)

```
$ uname -a
Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l GNU/Linux
$ python --version
Python 3.9.2
$ apt list python3-opencv
Listing... Done
python3-opencv/stable,now 4.5.1+dfsg-5 armhf [installed]
$ pip list | grep google-auth-oauthlib
google-auth-oauthlib 0.4.6
Blender で作成したアニメーション付きモデルを ARKit で配置して遊ぼう - 3Dデータ出力編

Blender で作成したアニメーション付きモデルを ARKit で配置する方法を解説していきます。
今回は 3Dデータを Xcode で使えるように出力していきます。

# アニメーション出力
Xcode で使うためには dae ファイルにする必要があります。Blender のエクスポートにも dae がきちんと用意されています。
しかし、デフォルトのエクスポート使うと大体ズレが生じたりとおかしなことになります。（Blender 2.8時点）
なので、 __Better Collada__ というアドオンを使用しましょう。

## Better Colladaの導入

https://github.com/ctforks/collada-exporter-2.81

まずは Better Collada の github に飛んで、Clone or download から Download ZIP を選択しダウンロードします。
ZIPファイルを解凍し、中の _io_scene_dae_ というフォルダを圧縮してZIPにします。
Blenderを起動し、左上メニューの 編集 > プリファレンス > アドオン に行き、右上のインストールボタンを選択します。そして、先ほど作ったZIPファイルを選択してください。
すると、公式アドオンにBetter Collada Exporter というアドオンが追加されます（検索すればすぐ見つかる）ので、チェックを入れて有効化してください。
これで導入完了です。


## Better Colladaでの出力
Blenderで**モデルを選択**しておき、左上メニューの ファイル > エクスポート > Better Collada (.dae) を選択します。
出てきた画面の右側に出力のオプションが表示されているはずなので、すでにされているチェックに加え **Export Animation** と、**選択したオブジェクト** にチェックをつけてエクスポートしましょう。詳しい設定は下記の画像を参照してください。
これで出力完了です。

:::note info
この出力をするとマテリアルデータがうまく出力されず半透明のモデルとなります。
次で再び色付けするので問題ないです。
:::

![キャプチャ](https://user-images.githubusercontent.com/51015143/79369754-6ed7b200-7f8c-11ea-89b7-1a0a0ff3c9ad.PNG)

## 3Dデータへの色付け
先ほど出力したdaeファイルをXcodeで開いてください。
モデルは理工展のマスコットキャラクターの矢口くんになります。
<img width="1440" alt="1" src="https://user-images.githubusercontent.com/51015143/79450501-eb67a080-801f-11ea-9304-62e085ac69d3.png">
すると、このように半透明なモデルが出現します。
モデルを選択し、マテリアルデータをみてみましょう。右上のメニューの球のマークを押すとマテリアルデータが確認できます。

<img width="1440" alt="2" src="https://user-images.githubusercontent.com/51015143/79450525-f15d8180-801f-11ea-9a26-cb6da5e0f8fd.png">

Emision(発光), Transparent(透過)が勝手に変更されていることがあるので調節しましょう。
その後、Diffuse を開き色を適用しましょう。
これを全てのマテリアルに対して適用すれば3Dデータは完成です。お疲れ様でした。
Visual Basic 2021年の振り返り

# はじめに
これは、[Visual Basic Advent Calendar 2021](https://qiita.com/advent-calendar/2021/vb)の1日目の記事となります。

# 2021年の出来事
## Visual Basic 30周年
1991/05/20にVisual Basic バージョン1.0がリリースされてから、30周年を迎えました。
【2021/12/6追記】
Twitterのハッシュタグに「#VisualBasicIs30」があることを見つけました。
https://twitter.com/hashtag/VisualBasicIs30?src=hashtag_click

https://qiita.com/yaju/items/3a4dd40c40554eb5d283

## VB 6.0のWindows 11正式サポート
Windows 11が2021/10/05にリリースされたにも関わらず、MicrosoftからVB 6.0の正式サポートの発表がされませんでした。約1ヶ月経過した2021/11/06 に[Visual Basic 6.0のサポート情報](https://docs.microsoft.com/ja-jp/previous-versions/visualstudio/visual-basic-6/visual-basic-6-support-policy)がようやく更新され、Windows 11への正式サポートが発表されました。

https://qiita.com/yaju/items/1ba0fd5466230c963052

## .NET 6.0 リリース
2021/11/08 に「.NET 6.0」 がリリースされました。.NET 6.0は、本番利用に耐える品質とサポートが約束された長期サポート版（LTS版）の.NETとなります。
ただ残念なのは、.NET MAUIのリリースが.NET 6と同時目標でしたが、2022年第2四半期初めに延長されてしまいました。
とはいえ、.NET MAUIは、C#のみがサポートとなるため、どのみちVB.NETは蚊帳の外に置かれてしまいます。

VB.NETの言語としての進化自体はやめてしまいますが、.NET 6.0のサポートは引き続き行われます。

https://qiita.com/yaju/items/4d8c64c3cb075e619ce9

## Visual Studio 2022 リリース
2021/11/08 に「Visual Studio 2022」 がリリースされました。
下記の.NETブログのタイトルの日本語訳「Visual Studio2022のVisualBasicの新機能」とVB.NETの言語の進化をやめたはずなのにと何事かと期待してしまったのですが、統合環境(IDE)のVisual Basicに関する話でした。

https://devblogs.microsoft.com/dotnet/whats-new-for-visual-basic-in-visual-studio-2022/

## Mercury プラットフォーム
MicrosoftがやめたVB.NETの言語としての進化は、[RemObjects Mercury](https://www.elementscompiler.com/elements/mercury/)が引き継ぐぜっという感じらしいです。

https://blogs.remobjects.com/2021/05/07/mercury/

[RemObjects Software](https://www.remobjects.com/)は、MercuryにてVisual Basicとの互換性が99.9%であることに加えて、マップ型、オーバーヘッドゼロのインライン型など、多くの新しい言語機能が追加している。

https://www.infoq.com/jp/news/2021/06/mercury-visual-basic-elements/

## 人気言語ランキング 5位、11位
TIOBE Index for November 2021では、Visual Basicが5位、Classic Visual Basicが11位となっています。
https://www.tiobe.com/tiobe-index/

Visual Basicとしては、両方とも2020年中頃から急激に上がっています。

https://www.tiobe.com/tiobe-index/visual-basic/

https://www.tiobe.com/tiobe-index/classic-visual-basic/

>TIOBEは、Visual Basic .Net が「遅かれ早かれ、再度順位を下げる」と考える一方、中小企業で専用の業務アプリケーションの多くがこの言語で開発されているほか、その習得しやすさなどから、多くの開発者に利用されているのだろうと推測する。(中略)
Microsoftのこの戦略によって、Visual Basic .Netの「レベルを落とす」のではないかと懸念する開発者もいたようだ。
[MSの「Visual Basic .Net」が5位に浮上--TIOBEプログラミング言語ランキング](https://japan.zdnet.com/article/35129578/)

2018年の記事でいずれ下がるだろうとの予想に反して、2021年でもそこそこ上位位置をキープしています。

日本の人気と海外での人気は違うとはいえ、[指標の統計方法](https://www.tiobe.com/tiobe-index/programming-languages-definition/)がどのように行われているのかだね。VBScriptは42位となっていて区分けはされていますが、VBAはランキングに含まれていないので、どちらかに含まれている可能性も否定できません。

Visual BasicからC#に移行するということで検索が増えているんじゃないかって考えてしまいますね。

# 最後に
非ITエンジニアがプログラムを習って、ExcelやAccessでVBAを使用するのが増えてきていると感じています。
Visual Basicは言語の進化をやめたけど、いいように考えれば安定性がサポートされるということです。みなさん頑張りましょう。
micro:bitで下駄箱を「ゼルダの伝説」の世界に ～まずは作ってみた～

micro:bitで下駄箱をゼルダの世界にしてみました。

■使ったもの
micro:bit本体
[DFR0534(MP3再生モジュール)](https://akizukidenshi.com/catalog/g/gM-13708/)

■参考記事
[micro:bitから簡単にmp3再生できるカスタムブロックと接続ケーブルを作った](https://qiita.com/wakasamasao/items/74d41d252c3743138143)


■方針
玄関の下駄箱の扉を開けたらゼルダの伝説の秘密解き明かした時サウンド「チャラリララリララー」が鳴るようにする。
音源はMP3、[DFR0534](https://akizukidenshi.com/catalog/g/gM-13708/)で再生
検知はmicro:bit搭載の光センサー

■プログラム
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71746/312b9617-2e9e-9141-163d-4c3e1a6442c5.png)


■設置結果

<iframe width="560" height="315" src="https://www.youtube.com/embed/MM_t_KZsOOk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>


扉を開けただけなのに謎を解いた気分にさせてくれます(^^;

■課題
光センサーの0から1の閾値がかなり高い様で、玄関の光程度では光センサーが反応しません。
実は設置結果の動画は懐中電灯を当てて撮影しています。

残念ながらそんなことでは扉を開いて毎回自分でライトを当てないといけません。
外付けの光センサーを使って光を検知するよう改善したいと思います。
👓メガネをかけたFANZA女優をピックアップした

この記事は  [驚異のFANZA女優検索](https://fanza-actress-bust-search.azurewebsites.net)  Advent Calendar 2021 の 1 日目の記事です。

# メガネをかけたFANZA女優一覧
FANZA女優からメガネをかけた女優だけをピックアップしたページを作った。[メガネをかけたFANZA女優一覧](https://fanza-actress-bust-search.azurewebsites.net/glasses)だ。あくまでDMMが提供している女優の画像がメガネをかけているかが分かるだけだが、公式にその女優を表す画像として提供されている顔写真がメガネをかけているかは割と重要な指針になると思う（何の？！）。実際に本家FANZAにも[めがね](https://www.google.com/search?client=firefox-b-d&q=FANZA+%E3%82%81%E3%81%8C%E3%81%AD)というジャンルがあることはあるがそういうことじゃない感が強い。その点、自分のページはちゃんと**ほぼ**（認識の精度のせいで残念ながら100%ではない。2人メガネをかけていない女優がいた）メガネをかけている。こういうのがいい。

# Azure Face API
作ったきっかけは、ちょっと思う所があって顔認識を調べていて[Azure Face API](https://azure.microsoft.com/ja-jp/services/cognitive-services/face/#overview)をみたことだ。HPを見ると「1 人以上の人間の顔と、ポーズ、フェイス マスク、顔ひげなどの各種の属性を検出できます。」と書いてある。属性に何があるか調べて[顔属性](https://docs.microsoft.com/ja-jp/azure/cognitive-services/face/concepts/face-detection)を見てみた。すると以下のようなパラメータが取れると書いてあった。…！。メガネを認識できるじゃないか！これは是非FANZA女優からメガネをかけた女優一覧を作らねばと思った。

```html
- アクセサリ
- 年齢
- ぼかし
- 感情
- 露出
- 顔ひげ
- 性別
- 眼鏡
- 髪の毛
- 頭部姿勢
- 化粧
- マスク
- ノイズ
- オクルージョン
- 笑顔
```

# Cognitive Services の docsがとても便利
AzureのCognitive ServicesのFace APIを作って、エンドポイントとキーを取得しておけば、[docs](https://japaneast.dev.cognitive.microsoft.com/docs/services/563879b61984550e40cbbe8d/)が非常に良く出来てドキュメントとして読めるだけでなく、APIを直接POSTすることが出来る。今回は眼鏡だけで良いので、returnFaceAttributesをglassesにして後は全部消した。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1886572/58a9cd48-0b29-70a1-854b-337db5f6a0de.png)

これでSendボタンを押せばglassesのレスポンスが返ってくる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1886572/bc601f13-d89c-f126-1623-361e66ecf9e9.png)

faceAttributesがNoGlassesならメガネなし、ReadingGlassesならメガネだ！

# C#のコードで書く
docsのページで試して上手くいったら、これをC#に持ってきてコードにする。これで画像を投げればその画像がメガネをかけているかは判断出来るようになった。全女優の画像を全てこのメソッドにかけて、その結果をデータベースに反映した。

```cs
internal async Task<bool> HasGlassesAsync(string actressImageUrl)
{
    //女優の画像URLからHttpContentを取得
    var content = await GetImageContent(actressImageUrl);
    //Headers.ContentTypeにapplication/octet-streamを設定
    content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    //Face APIのdetectでreturnFaceAttributesだけを指定してPOST
    var responseMessage = await HttpClient.PostAsync($"{AzureFaceApiUrl}/detect?returnFaceAttributes=glasses", content);
    //レスポンスからJSONを取得
    var json = await responseMessage.Content.ReadAsStringAsync();
    //JSONをデシアライズ
    var detectResponse = JsonSerializer.Deserialize<DetectResponse[]>(json);
    //faceAttributes.glassesがReadingGlassesならメガネ。それ以外ならメガネなし。
    return detectResponse[0]?.faceAttributes.glasses == "ReadingGlasses"; 
}
```

# DBで絞り込む。
後はデータベースをその条件=メガネで絞り込んだ女優を表示すればOKだ。

```sql
SELECT * FROM Actress Where HasGlasses = 1
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1886572/cf06938b-fd3f-4d7c-2419-c980d62e17ba.png)

# まとめ
これで出来上がったのが[メガネをかけたFANZA女優一覧](https://fanza-actress-bust-search.azurewebsites.net/glasses)だ。メガネ好きの人がいれば是非見て欲しい。そうでない人も見てみると今まで見えなかったものが見えるかもしれない。メガネだけに。