OmniAICreator/Qiita-1.07M huggingface dataset:
FCMにおける`InvalidApnsCredential`エラー

# PUSH通知が届かない

Firebaseではよくあること

- Firebaseに登録した証明書・鍵がおかしい（パスコードが違う・KeyIDが異なるなど）
- 端末側のtokenが取得できていない

など考えればいくらでも出てくる

# 調査方法

pushが実際に送られている確認する。
ブラウザから送るとエラーなどは表示されないので原因がわからないのでCURLで検証することをお勧めする。

```
curl -X POST --header "Authorization: key={server_key}" \
--Header "Content-Type: application/json" \
https://fcm.googleapis.com/fcm/send \
-d @- << EOF
{
    "to":"{device_token}",
    "notification": {
        "title": "xxxxx",
        "body": "yyyyy"
    },
}
EOF
```

のような通知を送ると

> {"multicast_id":xxxx,"success":0,"failure":1,"canonical_ids":0,"results":[{"error":"InvalidApnsCredential"}]}%

上記のようなレスポンスが来ることがある

https://firebase.google.cn/docs/cloud-messaging/http-server-ref?hl=ja

に記載されている通り、「登録されているAPNSの情報が不正」である。
ただこれは他のケースでも表示される。

# BundleIDがおかしい

想定して準備したBundleIdのアプリケーションがない場合もこれが出ることが調査で分かった。
私の場合、検証環境のアプリを `{BUNDLE_ID}.stg` にしていたが、これがどこかで`{BUNDLE_ID}.stg.stg`になっていたので問題が起きた。

エラーメッセージ変えてくれ・・・
Kinx で湯婆婆を実装してみる

# 元ネタ

あまりこういうことはしないのですが、間違いなく私以外誰もやらないので。。。
しかしなんだかちょっと恥ずかしい。

* 元ネタ - @Nemesis さんの[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)

Kinx ってなんだ？という方は以下をご覧ください。

> **「見た目は JavaScript、頭脳(中身)は Ruby、（安定感は AC/DC）」** でお届けしているスクリプト言語 [Kinx](https://github.com/Kray-G/kinx)。
> 
> * 参考
>     * 最初の動機 ... [スクリプト言語 KINX（ご紹介）](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76)
>         * 個別記事へのリンクは全てここに集約してあります。
>     * リポジトリ ... [https://github.com/Kray-G/kinx](https://github.com/Kray-G/kinx)
>         * Pull Request 等お待ちしております。  

# コード

[JavaScript 版](https://qiita.com/hato-poppo/items/670d5186c2807a5f51b4) を見させていただいたところ、なんとブラウザ上での実行（←ある意味当たり前かも...）だったので [見た目は JavaScript](https://qiita.com/Kray-G/items/ca08b6fb40d15dd0ec76) の本領を発揮できず。しかたがないのでフルスクラッチ（といっても大したことはない）で作りました。

```JavaScript:yubaba.kx
System.println("契約書だよ。そこに名前を書きな。");
var name = $stdin.readLine();

System.println("フン。%sというのかい。贅沢な名だねぇ。" % name);

var nameArray = name.split('');
var index = Integer.parseInt(Math.random() * 1000) % nameArray.length();

var newName = nameArray[index];
System.println("今からお前の名前は%1%だ。いいかい、%1%だよ。分かったら返事をするんだ、%1%!!" % newName);
```

```
契約書だよ。そこに名前を書きな。
千尋
フン。千尋というのかい。贅沢な名だねぇ。
今からお前の名前は千だ。いいかい、千だよ。分かったら返事をするんだ、千!!
```

# ポイント

Kinx の `String#split` は UTF-8 で分割するので、配列にしてから 1 文字切り出します。

# 未入力

クラッシュするようにしましたよ。

```
契約書だよ。そこに名前を書きな。

フン。というのかい。贅沢な名だねぇ。
Uncaught exception: No one catch the exception.
SystemException: Divide by zero
Stack Trace Information:
        at <main-block>(yubaba.kx:7)
```
あえてクラッシュさせるために剰余計算させてます。本来は以下の部分、

```javascript
var index = Integer.parseInt(Math.random() * 1000) % nameArray.length();
```

これは以下で良いです。

```javascript
var index = Integer.parseInt(Math.random() * nameArray.length());
```

こうすると、クラッシュしないですが、配列要素が一つもないため `nameArray[0]` で undefined が返り、以下のように表示されます。

```
契約書だよ。そこに名前を書きな。

フン。というのかい。贅沢な名だねぇ。
今からお前の名前は((null))だ。いいかい、((null))だよ。分かったら返事をするんだ、((null))!!
```

# おわりに

色々実装されている皆さんのネタは楽しませていただきました。
本来はこういうことをあまりしない質なのですが、まぁ、Kinx は私以外誰もしないでしょうから、一瞬の気の迷いでやらせて頂きました。

ネタを提供していただいた @Nemesis さん（およびその他の方々）、ありがとうございました。
【中級編】オンライン会議でのSloos併用

#はじめに
Microsoft TeamsやZoomなどオンライン会議でSloosを利用する方法を説明します。
オンライン会議の開催方法は主に2パータンあり、Sloosの利用方法が少々異なります。
左：オンライン会議　右：各自オンライン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/6af70eef-ac8e-4405-4c61-e975ada3d6f9.png)
Sloos：https://sloos.qcore.co.jp/
###本記事のポイント
**１．　オンライン会議の場合、排他モードは解除（Windowsの場合）**
**２．　ホスト１名だけが参加者全員分書き起こしをする場合、スピーカー・マイクを最大にする**
**３．　ホストとゲストが各自でSloosを利用する場合、全員イヤフォンマイクを使用（ルームIDの共有も忘れずに）**


#オンライン会議
ホスト1名でSloosを開き、ホストのスピーカーで各自の声を入力する方法です。Sloosを利用する手間を最小限にする場合は、こちらのシーンが多いです。
![se02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/510b0a8b-61a8-e992-d271-36bcdb3304e9.png)
利用方法は以下の通りです。
1.　事前設定
・ホストは**スピーカー音量・マイク感度を最大にし、Windowsの場合は排他モードを解除**
・ホストは**イヤフォンマイクは利用せず**にパソコンのスピーカーマイクを利用

2.　書き起こし
・ホスト1名のパソコンでSloosにアクセス
・**オンライン会議システム経由で、ホストのパソコンのスピーカーから出力されるゲストの音声を、ホストのパソコンのマイクで入力**
・書き起こしの様子をホストとゲストの全員で閲覧する場合、ホストはオンライン会議システムで画面を共有

参照：
・[排他モードの解除方法を教えてください](https://docs.google.com/document/d/1ToJMBjFpgtN6PMJiHaCwL09wWKbOIiXESRt8fa83dks/edit#heading=h.fabmlwh4fo8j)
・[オーディオ設定は必要ですか](
https://docs.google.com/document/d/1ToJMBjFpgtN6PMJiHaCwL09wWKbOIiXESRt8fa83dks/edit#heading=h.vszdxqntloih)


#各自オンライン
参加者各自がイヤフォンマイクでオンライン会議に参加し、ルームIDのURLを共有し、各参加者が自分で声を登録する方法です。
（自宅などから全員がイヤフォンマイクを使用してオンライン会議を開催する場合等）
![se03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/b8c7a0d1-2a41-0151-0fb7-290481d63f85.png)

1.　事前設定
・ホストとゲストの**全員がイヤフォンマイクを利用し個別にオンライン会議に参加**（スピーカー不使用）
・ホストがルームを作成し、ゲストにメールなどで**ルームIDのURLを共有**し、各参加者の端末から参加者自身がSloosにアクセスして利用
*参加者の中にスピーカーマイクを利用する人がいる場合、正しく動作しない場合があります

2.　書き起こし
・各参加者の端末からSloosにアクセスし、各端末から入力される音声から書き起こし
・書き起こしの様子は各参加者毎に閲覧（画面共有不要）


参照
・[排他モードの解除方法を教えてください](https://docs.google.com/document/d/1ToJMBjFpgtN6PMJiHaCwL09wWKbOIiXESRt8fa83dks/edit#heading=h.fabmlwh4fo8j
 "排他モードの解除方法を教えてください")
・[ルームIDのURL共有はどの様な時に行いますか](https://docs.google.com/document/d/1ToJMBjFpgtN6PMJiHaCwL09wWKbOIiXESRt8fa83dks/edit#heading=h.4xtw0kup6hxi
 "ルームIDのURL共有はどの様な時に行いますか")
・[ルームIDのURLの共有はどのように行いますか](https://docs.google.com/document/d/1ToJMBjFpgtN6PMJiHaCwL09wWKbOIiXESRt8fa83dks/edit#heading=h.4xtw0kup6hxi)

#排他モード解除
オンライン会議システムを利用した場合、特にWindowsの場合は、その対象システムにオーディオが専有されてしまい、**Sloosを利用するブラウザに音声が入力されない**場合があります。
この場合は、ヘルプページの案内に沿って端末のサウンド設定で排他モードを解除してください。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/cbc63bb5-d967-7913-3741-47bf141e90a0.png)
参照
・[排他モードの解除方法を教えてください](https://docs.google.com/document/d/1ToJMBjFpgtN6PMJiHaCwL09wWKbOIiXESRt8fa83dks/edit#heading=h.fabmlwh4fo8j
 "排他モードの解除方法を教えてください")

#まとめ
**１．　オンライン会議の場合、排他モードは解除（Windowsの場合）**
**２．　ホスト１名だけが参加者全員分書き起こしをする場合、スピーカー・マイクを最大にする**
**３．　ホストとゲストが各自でSloosを利用する場合、全員イヤフォンマイクを使用（ルームIDの共有も忘れに）**

ご利用でお困り事がありましたら、ヘルプページとお問い合わせをご活用ください！
Sloos：https://sloos.qcore.co.jp/
ヘルプ：https://bit.ly/30WdMuo
お問い合わせ：https://forms.gle/8G4WahXmGmzDZwaAA
【初級編】音声登録からSloos開始まで

#はじめに
Sloosは参加者の音声を登録することで、単一マイクでも発言者の識別ができます。音声登録をすることで、発言者名を表示させながら書き起こしができるため、使い勝手が向上します。
（登録をしなくても書き起こしは可能です）

###本記事のポイント
**１．　シーン毎に合わせてマイクスピーカーを利用**
**２．　参加者毎に録音をして音声を登録（音声登録は省略可能）**
**３．　録音時は静かな場所で、自然な話し方での録音が推奨**
**４．　参加者の事後登録は、長めの文章を選択**


#音声登録
ルームでは対面とオンライン会議シーンに合わせて利用ください。
![スクリーンショット 2020-11-06 21.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/263e86c1-9fa2-a2b3-703e-6b9485027cec.png)


「発言者を追加」から参加者の音声登録をします。推奨は最大10名ですが、場合によっては10名以上でも一定の精度で認識可能なため、**参加者登録自体は10名以上でもご利用いただけます。**
（音声登録を省略する場合は、そのまま「議事録を開始」のボタンを押してSloosを開始できます）
![スクリーンショット 2020-11-06 21.39.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/f113008d-9e86-3df1-ba34-8fa6f2c72475.png)

参加者の名前（例：テストA）を記入し、マイクのアイコンから録音を開始します。
静かな場所で録音をすると話者認識の精度が向上します！（後述）
![スクリーンショット 2020-11-06 21.40.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/f5bdd2b2-62f3-484c-3d9b-aae3c5ef34fb.png)

録音中は青い画面が表示されるので、例文や自己紹介などを10秒程度話しましょう！
録音が完了すると「送信中」と表示されます。
（音声の状態が悪いと再録音を求められる場合があります）
![スクリーンショット 2020-11-06 21.40.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/89e26cbc-22c4-4eb6-48cd-09839861d739.png)


登録後は参加者一覧に表示されるので、右下の「議事録を開始」へ進みます（例：テストAとテストBを登録した場合）
![スクリーンショット 2020-11-06 21.42.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/b539aefd-57d5-c45b-071b-83d062012d80.png)（ゲストへルームIDを共有した場合の同じ流れですが、ホストは画面右の「参加申請」からゲストのルーム参加の許可をする必要があります）

#録音時のポイント
発言者の特定と、書き起こしの精度を出すためのコツを3つご紹介します。
![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/baa23a25-6454-9c03-a7b8-1b702249581b.png)
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/05115ec0-6a28-cf41-bdfa-1dd057be8cdb.png)
![図3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/199a0ed9-7246-0a73-9fea-8769dcee7d7c.png)

#Sloos開始
書き起こしが始まると話した言葉が上段に表示され、その後はチャット形式の様に下に表示されていきます。文章だけではなく、発言者毎に名前も表示されていきます。
![スクリーンショット 2020-11-06 21.43.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/3d17b1b8-e51c-c14d-91c2-c06bba252ad2.png)
文章横の「・・・」から参加者名の追加やテキスト編集などもできます。参加者の編集は、
１．　登録済みの参加者名に変更する（間違えを修正）
２．　未登録の参加者の声を新規に登録する（表示上は登録済み参加者名だが実際は新しい参加者の発言の場合）
を2パターンあります。

「１．　登録済みの参加者名に変更する」場合は、画面上段のプルダウンから登録済みの参加者名を選択
「２．　未登録の参加者の声を新規に登録する」場合は、画面下段の新規の発言者名を登録
することができます。
![スクリーンショット 2020-11-09 18.31.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/859218/2669b2d2-11af-a1fc-025f-5e2af35db9b8.png)
参加者が新規に登録された場合、選択された文章の音声を新規参加者としてSloosに登録されます。選択時の文章は、短い文章（例：そうですね）などではなく、長めの文章（例：本日はどうぞよろしくお願いいたします）などの方が、話者認識の精度は高くなります。**文章は何回でも登録できるので、長めの文章を2-3件登録することがオススメです。**
特に最初の音声登録を省略した場合、発言者が全員「不明」と表示されるため、この事後登録をする事で発言者の名前が表示されます。

#まとめ
音声登録のコツや利用中の編集をご紹介しました！音声登録を省略してもSloosは開始することができ、後からでも発言した文章利用して新規に話者を登録することもできます。

ポイント
**１．　シーン毎に合わせてマイクスピーカーを利用**
**２．　参加者毎に録音をして音声を登録（音声登録は省略可能）**
**３．　録音時は静かな場所で、自然な話し方での録音が推奨**
**４．　参加者の事後登録は、長めの文章を選択**

ご利用でお困り事がありましたら、ヘルプページとお問い合わせをご活用ください！
Sloos：https://sloos.qcore.co.jp/
ヘルプ：https://bit.ly/30WdMuo
お問い合わせ：https://forms.gle/8G4WahXmGmzDZwaAA
Unityで課金レシート検証する機能を入れるための備忘録

# 経緯
プログラマとして、師と仰いでいるモグメット先生に、レシート検証は大切だから、ちゃんとドキュメント作りなさい。
とご指導頂いたので、ここに書き記します。

# 達成したい仕様
ユーザが課金アイテムを購入後、課金コールバックが帰ってきた後に、
すぐに課金アイテムを追加するのではなく、レシート検証に成功した場合のみ、追加する。

# 前提
- 課金処理成功後、課金コールバック帰ってくる。
- 課金処理完了メソッドを叩いた後は、課金コールバックは帰ってこない。
- 正常に課金が行われた場合は、レシート検証は失敗しないものと過程するが、万一何らかの障害があってレシート検証ができなくなった場合でも、開発者のサーバコード修正により、一時的にレシート検証なしに課金処理を成功できる保険を事前に用意しておく。

#流れ

1. 課金コールバックが呼ばれる。
1. レシート検証APIを叩く。
1. （成功時）課金処理を実施する。課金処理完了イベントを発火する。
1. （失敗時）レシート失敗ポップアップ。OKボタンを押すと、ポップアップが閉じ、再度課金コールバックの発火を依頼するメソッドを叩く。

詳細なシーケンスについては、
[Unityでアプリ内課金を簡単に実装する方法](https://qiita.com/cayto_pr/items/727546a0918659938acf)
を参考にする。

# 論点１ ローカル検証かリモート検証か。
UnityIAPがローカル検証をサポートしており、
工数の観点でローカル検証の方がだいぶ楽そうだが、
課金の履歴をサーバで保管したい。いざという時レシート検証処理をサーバ側で向こうにできるようにしたいという要件を達成するため、サーバでの検証を試みる。そのため、GAEサーバ上で、Google Play,IOS Appstore,Amazon App Store 用のレシート検証処理を構築する必要がある。

#Google Play
一度認証トークン取得APIでトークンを取得してから、
レシート検証APIを叩く必要がある。

[【iOS/Android】アプリ内課金 定期購読のサーバーサイド知識総まとめ]
(https://qiita.com/ckm/items/b8cf23ba4bd0ae5bbf34)


#IOS Appstore

ストアのAPIをサーバから叩けばよいが、サンドボックス環境の可能性を考慮する必要がある。

大切なポイント
> 審査期間中にAppleがサンドボックス環境のレシートを送信してくるため、「開発時はサンドボックス環境、本番運用時は本番環境用」と設定を切り替えるのではなく、実装としていずれのAPIにもリクエストできるようにしておく必要があります。まず先に本番APIにリクエストし、サンドボックスAPIにリクエストすべきステータスが返却されればそのようにします。

参考文献
[【iOS/Android】アプリ内課金 定期購読のサーバーサイド知識総まとめ]
(https://qiita.com/ckm/items/b8cf23ba4bd0ae5bbf34)

#Amazon App Store
シンプルにGETメソッドを叩けばよい模様
[アプリ内課金（IAP）アプリのレシート検証](https://developer.amazon.com/ja/docs/in-app-purchasing/iap-rvs-for-android-apps.html)
スクリプトファイルの行数をカウントしよう

＃背景
この[bat|SQL|sh]ってコメント除いたら何行あるの？
って聞かれたときにパッと分からなかったので。バッチにしました。

## バッチ概要
シンプルな構文を繰り返しているだけです。こんな感じ。1ファイルを引数に取り、空白行と指定した文字から始まる行を除いて、行数をカウントします。
エラー処理は適当に書いています。

```winbatch:countLines.bat
if not "%2"=="" (
    echo *** 2つ以上の引数が指定されています。
    goto END_ERROR_ARG
)
if "%1"=="" (
    echo *** 行数カウント対象のファイルを指定してください ***
    goto END_ERROR_NOARG
)

set lines=0
if /i "%~x1"==".bat" (
    for /f "eol=@" %%i in ( %1 ) do ( set /a lines=lines+1 )
    goto END_SUCCESS
) else if /i  "%~x1"==".cmd" (
    for /f "eol=@" %%i in ( %1 ) do ( set /a lines=lines+1 )
    goto END_SUCCESS
) else if /i "%~x1"==".sh" (
    for /f "eol=#" %%i in ( %1 ) do ( set /a lines=lines+1 )
    goto END_SUCCESS
) else if /i "%~x1"==".sql" (
    for /f "eol=/" %%i in ( %1 ) do ( set /a lines=lines+1 )
    for /f "eol=-" %%i in ( %1 ) do ( set /a lines=lines+1 )
    goto END_SUCCESS
) else if /i "%~x1"==".ps1" (
    for /f "eol=#" %%i in ( %1 ) do ( set /a lines=lines+1 )
    goto END_SUCCESS
) else (
    set errroMsg=対象外のファイル拡張子が指定された
    goto END_OTHER_EXT
)

:END_SUCCESS
echo カウント結果[%~nx1]： %lines% Lines
exit /b 0

:END_ERROR_ARG
echo 実行結果：引数エラー
exit /b 1

:END_ERROR_NOARG
echo 実行結果：引数なし
exit /b 2

:END_OTHER_EXT
echo 実行結果：対象外のファイル拡張子
exit /b 3
```
コメント行に使われるであろう文字を決め打ちにしてるので、柔軟性はあんまりないです。バッチファイルだと、
@&#xFFF0;REMとか、REMとか、;とかコメント扱いにできちゃいますしね…

こんな感じで使います。

```winbatch
countLines.bat xxx.bat
```

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/581105/de1d5059-9f92-9697-d066-d3d48231d231.png)

探せば、もっと簡単に行数カウントしてくれるエディタとか、プラグインとかあるんでしょうか？
TFLite Integer quantization時に"tensorflow/lite/tools/optimize/calibration/builtin_logging_ops/lstm.cc:558 activation_state != nullptr was not true. Node number 257 (CONCATENATION) failed to inovoke"というエラー

# TFLiteで量子化
TFLiteではQuantization機能が提供されており、モデルの軽量化・エッジデバイス向けのモデル最適化が可能です。
Weightのみの量子化、float16,32への量子化への量子化はサクッとできるのですが、Integer量子化の際には代表的な画像(100枚ほど)を用いたキャリブレーションが必要となってきます [^1]。 
参考：[訓練後の量子化｜TensorFlow Lite](https://www.tensorflow.org/lite/performance/post_training_quantization?hl=ja)
[^1]: キャリブレーション無しでも量子化可能ですが、推論が上手くいかないor推論速度が遅くなります。

# Integer量子化を試みた際、エラーが発生
今回Raspberry pi4向けにモデルのInteger量子化を行おうとしました。
表題の通りですが、代表画像を読み込ませた際に

```shell

RuntimeError: "tensorflow/lite/tools/optimize/calibration/builtin_logging_ops/lstm.cc:558 activation_state != nullptr was not true. Node number 257 (CONCATENATION) failed to inovoke"

```
というエラーが発生しました。
モデルは
pytorch(.pth) => onnx(.onnx) => keras(.h5) => TensorFlow(.pb) => TensorFlowLite(.tflite)
という手順で変換を試みていたのですが、どうやら一部のレイヤーが対応していない（？）ようです。

# 解決方法
量子化にはTensorflow2.3.0を用いていたのですが、一旦別のPython仮装環境を作製しtf-nightlyをインストールして、もう一度量子化を試みたところうまく変換することができました。

```sh
pip install tf-nightly
```
一旦別の仮想環境を用意したのは、tensorflow2.3.0をアンインストールしてtf-nightlyを入れたところ、うまくimportできなかったためです。恐らくSite-packageあたりにtfの空のフォルダ等が残っていたのが原因だと思います。

また、<b>エッジ側環境(Raspberry pi4)のtflite-runtimeもversion 2.0.0からversion 2.5.0に変える必要</b>がありました。
tflite-runtimeのversion 2.5.0は
[Pythonクイックスタート｜TensorFlow Lite](https://www.tensorflow.org/lite/guide/python)
からダウンロードして、pipでインストールすることができます。

# 注意
tf-nightlyはstableなバージョンではないので、継続的にこの方法でいけるかというと怪しい側面はあります。
結構、一時しのぎ的な解決方法ではあるので注意して下さい。
【新機能】Visual Studio Code 1.51.0 では認証付きプロキシのユーザー名/パスワードを覚えさせることができる。

#はじめに

従来のバージョンのVisual Studio Codeでは認証付きプロキシーの資格情報を記憶させることができず、毎回ユーザー名とパスワードを入力する必要があった。

Visual Studio Code 1.51.0 では新機能として、ユーザー名/パスワードの情報を覚えさせることができるようになった。

リリースノートより

```
Remember proxy credentials

We are overhauling the login dialog that shows when
a network connection requires authentication with a proxy.
A new setting, window.enableExperimentalProxyLoginDialog: true,
 will enable this new experience that we plan to make the default in a future release.
```

翻訳

```
プロキシ資格情報を記憶する

ネットワーク接続でプロキシによる認証が必要な場合を表示するログインダイアログを見直しています。
新しい設定、window.enableExperimentalProxyLoginDialog：true、
  将来のリリースはこの新しいエクスペリエンスをデフォルトで有効にする予定です。
```


#設定

settings.jsonに以下の行を追加

```
    "window.enableExperimentalProxyLoginDialog": true
```

Visual Studio Codeを再起動する。


#実行

Visual Studio Codeを実行すると、以下のような新しいダイアログが表示される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111137/fff55215-75e0-2b38-6fad-cebd33e4a660.png)

資格情報を保存するにチェックを入れる。
NeoPixel消費電力メモ

#NeoPixel系 WS2812B 消費電力メモ

##実験条件
ESP8266のDevボードに接続して使用
電源はESP8266の3.3V出力
ライブラリ：NeoPixelBus by Makuna
https://github.com/Makuna/NeoPixelBus/wiki

##LEDオンボードチップの消費電力
64個接続のものと、8個接続のものをそれぞれ、LEDは全部消灯させた時の消費電力を測定。

| 接続数 | 総消費電力 | ユニットあたり |
|:-:|:-:|:-:|
| 8/3.3V  | 5.1mA  | 0.637mA  |
| 64/3.3V  | 40.4mA  | 0.631mA  |
| 8/5V  | 6.6mA  | 0.825mA  |

<dt>考察</dt>
<dd>ユニットあたりの消費電力は、0.63mA 程度
</dd>



## 各LEDの消費電力
8個接続のもので、1つのLEDだけを点灯させて計測。
3.3V

| LED | 消費電力(最大輝度) | LED単体 |
|:-:|:-:|:-:|
| Red  | 13.6mA  | 8.5mA |
| Green  | 12.7mA  | 7.6mA |
| Blue  | 12.9mA | 7.8mA |
| RGB | 28.3mA | 23.2mA |

8個接続のもので、1つのLEDだけを点灯させて計測。
5.0V

| LED | 消費電力(最大輝度) | LED単体 |
|:-:|:-:|:-:|
| Red  | 17.2mA  | 10.6mA |
| Green  | 16.4mA  | 9.8mA |
| Blue  | 16.9mA | 10.3mA |
| RGB | 37.9mA | 31.3mA |

<dt>考察</dt>
<dd>色ごとに大きな違いはないようだ。ユニット自体の消費電力5.1mA（8個分、前項参照)とすると、各色およそ8mA(3.3V)、10mA(5.0V)。

以上から、3.3Vで駆動する場合、1ユニットあたり、およそ24mA(0.06W)
5.0Vで駆動する場合、１ユニットあたりおよそ28mA (0.15W)

なお、メーカーのデータでは、5V駆動で、ユニットあたり0.3Wとなっている。
</dd>


##電力不足時の挙動
5V=500mA上限のUSB給電時、64個のNeoPixelを3.3V白最大輝度で点灯させた時の消費電力は316mAだった。

この時、LEDは全unitが白ではなく黄色になっている。ここから、電力不足の時は青色が光らなくなると推察される。

(316-40)/64=4.3mA

なので、計算値(24mA)よりだいぶ低下している。
Fortranで湯婆婆を実装してみる

# 0. 前書き
　@Nemesis さんの[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)を他の言語でやってみた記事を見て、これはFortranでやらねばと思い記事にした次第です

# 1. 環境
以下の環境で動作確認しています
　OS：Windows10 Home

```shell:gfortran
$ gfortran --version
GNU Fortran (x86_64-posix-seh, Built by strawberryperl.com project) 8.3.0
Copyright (C) 2018 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
```

Fortran環境が欲しいという方、とりあえずコンパイラ(`gfortran`)があればよいです[^12]
・**Windows**
[このサイト](http://www.compe.media.kyoto-u.ac.jp/syoseki/windows/windows-gfortran.html)を参考にしてください。きっと上手くいきます。~~試してないけど~~

・**Linux**
Ubuntuでやるならこんな感じですが、お好きなパッケージマネージャでそれっぽくインストールすれば手に入ります。

```shell:Ubuntu
> sudo apt install gfortran
```

・**mac**
Macは(まだ)持っていないので詳しくは分かりませんが、こちらの記事を参考にお願いします
[Mac (macOS Catalina, 10.15.2)にgfortranとPGI Fortran 19.10をインストールしたときの手順](https://qiita.com/implicit_none/items/2f84dafc62e1ada9862a)
# 2. いきなりコード
　小細工満載ですが、以下がコードになります
ただですね、Windows環境でやる場合は、<font color="red">S-JIS</font>で保存してください(^q^)。
utf-8だと日本語が文字化けします(ネタではなく)。~~私が謝るのも変ですが、マジですみませんホントごめんなさい~~

```fortran:yubaba.f90
program yubaba
implicit none
    real :: rand
    integer :: nRand
    character(len=50):: originName
    character(len=2):: newName

    print*, "契約書だよ、そこに名前を書きな。"

    read(*, *) originName
    print*, len_trim(trim(adjustl(originName)))

    print*, "フン。"//trim(adjustl(originName))//"というのかい。贅沢な名だねぇ。"


    call random(rand)
    nRand = 2*int(rand*len(trim(adjustl(originName)))/2) + 1
    print*, nRand
    newName = originName(nRand:nRand + 2)
    print*, "今からお前の名前は"//trim(adjustl(newName))//"だ。"
    print*, "いいかい、"//trim(adjustl(newName))//"だよ。分かったら返事をするんだ"//trim(adjustl(newName))//"!!"

contains
subroutine random(x)
    implicit none
    integer ::clock, seedsize
    integer, allocatable :: seed(:)
    real, intent(out) :: x
    
    call random_seed(size = seedsize)  !シードを格納するのに必要な配列サイズを取得．
    allocate(seed(seedsize))  ! seed の配列数を決定
    call system_clock(count=clock)  !時間を取得
    seed = clock
    call random_seed(put=seed)
    call random_number( x )

    return
end subroutine random
end program yubaba
```


これをコピペしてコンパイルすると`a.out`か`a.exe`って実行ファイルが出来るので、そいつを実行してやれば動きます

```shell
> gfortran yubaba.f90
> ./a.out
 契約書だよ、そこに名前を書きな。
山田太郎
 フン。山田太郎というのかい。贅沢な名だねぇ。
 今からお前の名前は太だ。
 いいかい、太だよ。分かったら返事をするんだ太!!
```

# 3.解説
　ここから先は、Fortran初めてだよって方向けにソースの解説に移ります。
　coming soon!


[^qt]: 
[^12]: 自分の場合は、Latexの環境構築した時に入れたstrawberryperlのbuilt-inコンパイラをそのまま使ってて、Windowsでちゃんと環境構築した事ないです。。。
【javascript】もう迷わない!初めての戻り値(return)【イラスト解説】

returnの戻るってなんやねん！と思った初学者は少なくないはず。
自分も就職する前の独学時代はreturnの必要性がわかりませんでした。
スクールや職場の先輩にわかりやすく説明して頂いたのでそれをイラストでまとめてみました。
下記コードは2代入した数字を倍にしてconsole.logで表示するシンプルな関数。

```javascript
function double(value){
  const  hang = value * 2;
  return hang;
}

const result = double(10);
console.log(result);
```
![スクリーンショット 2020-11-09 23.09.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/ff2b7d93-dc70-d770-ef97-97aad067cfd0.png)


## returnがない場合どうなる!?
```javascript
function double(value){
  const  hang = value * 2;
  //   return data;
}

const result = double(10);
console.log(result);
```
![スクリーンショット 2020-11-09 23.10.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/e6170765-7db4-a5a4-011b-e9a9ee7c978c.png)

## どうしてこうなるの?
**returnが存在しない場合、今回のコードではdouble関数は計算はしたけど、結果が代入されないから。**
returnされる時の流れをイラストにしてみました。
3行目では、returnを使って、result変数に代入した値を返します。これが俗に言う**戻り値**です。
![スクリーンショット 2020-11-09 23.25.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/4bf570cd-d2e7-8b7d-392b-de09ecb2abd3.png)






returnをコメントアウト(削除)した時のイラストはこちら↓
![スクリーンショット 2020-11-09 23.17.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840696/05b4323c-d006-11a0-f3cd-ec79936a4a35.png)
プログラミングはよく知らないけどVBAで作業を効率化させたい方向けのメモ

##VBAで何ができるか

###①パソコンの中のファイルを色々できる
###②Excelファイルはもっと色々できる
###③似たようなことを繰り返す処理は簡単&高速にできる（ループ処理 ※後述）

***

####①パソコンの中を色々って？
ファイルの移動、コピー、削除ができる
②と組み合わせるのが一般的

`具体例.
「商品リストフォルダ」で「2020年」という文字を含んだ「.xlsx」形式のファイルを検索、「最新商品リストフォルダ」を作成してそこに検索結果ファイルをコピー`

####②Excelファイルだともっと色々？
セルの中身、セル自体を問わずにコピー、削除、検索ができる
セルの中身の文字を消したり、行、列の追加削除もOK

``具体例.
1行目にある商品名の行を全部削除、今までの商品名を商品1、商品2、商品3に書き換えた行を追加して文字を赤くする``

####③繰り返し処理とは
「ループ処理」とも言われる。検索してコピーして別のシートに貼り付けして…のような作業に使うと🙆‍♂️
参考になる書き方のテンプレートがいっぱいあるのでまずはそれをコピペして動かしてみるのがおすすめ

***

####※覚えておきたいワード「変数」について

よく出てくるけどなんなのかよくわかんないやつ

算数の
x + y = 100
のときのxとyみたいな役割

コピペするとき、Excelのセルの場合1箇所しかコピーできないですよね。これを「コピペ情報A」とします。
「変数」は、「コピペ情報A」「コピペ情報B」のようにいっぱい持っておけます。

また、この「コピペ情報A」「コピペ情報B」が数字なら足し算や引き算も可能であちこちに貼り付けもできます。

以上となります。
ほぼ知人向けの内容としてまとめたので、詳しく知りたい方は「VBA 初心者」などで検索するとよいと思います。
AWSのオートスケールの負荷試験のため、EC2にVegetaを設定する

# はじめに
AWS EC2に分散負荷試験ツールである[Vegeta](https://github.com/chidakiyo/vegeta)の設定方法です。

ロードバランサーのオートスケールがどのくらいスケールするか試験する際に、Vegetaを利用しました。
以下の有名な負荷試験ツールは、試験環境構築のコストが高いです。

- Apache Bench
- Apache JMeter
- Locust
- Tsung 

**コストが高い理由**

- クラスターを構築する必要がある
- そもそも負荷が掛からない
- シナリオを記述しなければならない

**やりたいこと**

- URLに指定したメソッドで、指定した秒間リクエストで負荷を掛けたい。

[![[GitHub]Vegeta](https://camo.githubusercontent.com/faf9be097f4731212debdd24210c750b2dc276d0a17df19c6a8ac026427c09e9/687474703a2f2f666330392e64657669616e746172742e6e65742f667334392f692f323030392f3139382f632f632f73736a325f7665676574615f62795f7472756e6b7332342e6a7067)](https://github.com/chidakiyo/vegeta)

# 環境構築手順
1. EC2

    ```sh:コマンド
    sudo yum update -y

    # Go言語のインストール
    sudo yum install go -y
    echo export GOPATH=$HOME/go >> ~/.bashrc
 
    # gitのインストール
    sudo yum install git -y
 
    # Vegetaの導入
    go get -u github.com/tsenart/vegeta
    sudo ln -s /home/ec2-user/go/bin/vegeta /usr/local/bin/vegeta
    ```
パワーポイント(.pptx)から画像を高画質で取り出す

## クライアントから
クライアントからpptx形式でデザイン案をもらい、それに沿ってフロントを作っていく作業ってあると思います。
作業には問題ないのですが、ロゴとか特定の画像はパワポから取り出して使用する場面がありますよね。
pptx上では画像がきれいに表示されているが、`右クリック > 図として保存` を行うと画像サイズが小さくなって画質が落ちてしまいます。


## 解決手順
1. 拡張子をzipに変更
2. zipを展開
3. ppt > media にパワポ上の画像が格納されている

## 結果
`右クリック > 図として保存`よりも画像サイズが大きい画像が取り出せます。
「コンピュータの回路」①　論理演算

##コンピュータと論理回路
コンピュータは論理回路の組み合わせによって構成されています。
論理回路には様々な種類があり、代表的なものとして「AND回路」、「OR回路」、「NOT回路」があります。コンピュータは論理回路を様々な形で組み合わせることによって、複雑な制御を可能にしています。

ところで、論理回路とは一体何かというと、電気が流れる道筋、つまり「回路」を抽象化したものになります。
だから、回路を制御するということは、電気の流れを制御するということになります。

コンピュータが扱う「ビット」は電気が流れている状態、つまり「ON」を「$1$」としています。
そして、電気が流れていない状態、つまり「OFF」を「$0$」としています。
したがって、論理回路を組み合わせて電気の流れを制御することができれば、「ビット」の演算処理もできるということになるわけです。

##論理演算
論理演算とは、「$1$」を「真（True）」、「$0$」を「偽（False）」として、この2つの値だけで行う演算のことです。
そして、論理演算は、ある条件が成立している時には「$0$(真)」、成立していない時には「$1$(偽)」という値を表現します。
そのため、あるAという条件が成立している状態を、**Aという集合に属する**という表現に置き換えることが出来ます。
したがって、論理演算はベン図を使って視覚的に表現することが可能になります。

また、論理演算には「AND」、「OR」、「NOT」という代表的な演算があります。
これらの論理演算は、ベン図を用いて表現することが出来ます。

####AND（論理積）
「AND（論理積）」は「PかつQ（P∩Q）」という状態を表します。
つまり、Pという条件とQという条件があったとして、**両方とも真**である状態を表します。

次に示すベン図において、Pという条件が成立している時（真の時）に「P」という集合に属し、Qという条件が成立している時に「Q」という集合に属するものとします。
論理積（AND）ではPとQの両方が成立しているため、ベン図ではPの集合とQの集合が重なり合った部分（赤と緑が重なった部分）を範囲とします。
![スクリーンショット 2020-11-10 6.40.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/657974/489e87d5-6771-3543-4327-b8fa9b23dae3.png)

####OR（論理和）
「AND（論理積）」は「PまたはQ」という状態を表します。
つまり、Pという条件とQという条件があったとして、**少なくとも一方が真**である状態を表します。

ベン図では、Pだけの部分とP∩Qの部分とQだけの部分、つまり色がついている部分を表します。

####NOT（否定）
「NOT（否定）」は「Pでない」、「Qでない」という状態を表します。
つまり、Pという条件とQという条件があったとして、**「Pでない」はPが成立していないことを真**であるとみなします。
また、「Qでない」はQが成立していないことを真であるとみなします。

ベン図では、「Pでない」はP以外の領域を表し、「Qでない」はQ以外の領域を表します。
つまり、「Pでない」の時、緑色ではない部分を表します。ただし、P∩Qの部分はPの領域に含まれます。

##参考にさせて頂いた書籍
きたみりゅうじ 『キタミ式イラストIT塾 基本情報技術者平成31/01年』 技術評論社 2019年

##学習してみて
今回からコンピュータの回路という内容に取り掛かりました。
ベン図は大昔に学校で勉強して以来久々に書きましたね。
複雑な論理演算も今回学んだものの組み合わせということなので基本をしっかり押さえておこうと思います。
動画とGoogleマップの挿入の仕方

#動画とGoogleマップの挿入
![screencapture-127-0-0-1-5500-htmlCss-20201110-index-html-2020-11-10-07_17_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/633943/f75448b4-370e-caef-9384-eed8283ac3e9.png)
fish で湯婆婆を実装してみる

# はじめに

深夜過ぎても眠れず今 5:30 くらいです。おはようございます。
眠れないので Twitter してたら Qiita で [湯婆婆を実装してみる](https://qiita.com/torifukukaiou/items/c8361231cdc56e493245) のが流行っていることを知ったので [fish](https://fishshell.com/) で実装してみることにしました :fish: 

ちなみにこの流行を巻き起こした第一人者である @Nemesis さんの [元ネタ記事はこちら](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2) です :ocean::cyclone: 
# コード

```fish:yubaba.fish
echo 契約書だよ。そこに名前を書きな。

# `-P` がプロンプトで入力受付を行うためのオプションで、
# `-l` が入力された内容を `current_name` 変数にセットするためのオプション
read -l -P '' current_name

echo フン。$current_nameというのかい。贅沢な名だねぇ。

# `current_name_length` の値が 1 以下だったらという条件文
set current_name_length (string length (echo $current_name))
if test $current_name_length -le 1
    set index 1
else
    # 1 から `current_name_length` までの値をランダムに取得して index 変数にセット
    # FYI: random コマンドで指定した START より小さい文字数の文字だと
    # `random: END must be greater than START` という警告が出てきてしまうので
    # 条件文で 2文字以上の場合のみランダムで文字列を取得するようにしている
    set index (random 1 (echo $current_name_length))
end

# `string split '' <分割したい文字列>` で文字列を 1文字ずつ分割して List として characters にセット
set characters (string split '' (echo $current_name))

# 文字列の中から適当な 1文字をピックアップ
set new_name $characters[$index]
echo 今からお前の名前は$new_nameだ。いいかい、$new_nameだよ。分かったら返事をするんだ、$new_name!!
```

fish のコードは :arrow_up: のようになります。
bash で慣れていると冗長な気がしますが、これには fish 特有の仕様が絡んでいます。 

fish では `string length $current_name` のような形でコマンド置換ができません:x: 
コマンド実行結果を `set` 等で変数に代入しておいた上で `string length (echo $current_name)` のような形で実行することは可能です:o:

コマンド実行時にわざわざ `random 1 (echo $current_name_length)` のような形で `echo` を挟んで値をセットしているのは上記が理由です。

他の部分の解説は大体ソースコード内にコメントを残してあるので省略します :bomb: :boom: 

# 実行結果

![スクリーンショット 2020-11-10 6.14.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86070/09c0fb70-d71d-7c4b-bb53-6b3a5374ab79.png "馬にされてしまった範馬勇次郎")
*いきなり "馬" にされてしまった範馬勇次郎 :horse:*

# おまけ

テストで用いていたスクリプトは下記になります :pencil: 

```fish:yubaba-test.fish
# yubaba.fish と同じディレクトリに配置して `fish yubaba-test.fish` を実行
set names テスト jhondoe 漢字 𠮷 🔨 \n
for val in $names
    echo $val | fish ./yubaba.fish
end
```

また、空白の例外処理については入れていないため、空白を入力したときの実行結果は下記になります :white_large_square: :arrow_double_down: 

![スクリーンショット 2020-11-10 6.23.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/86070/566318c8-37c4-be0e-332e-1aa169204646.png)
*虚無*

# おわりに

眠れなかったおかげで fish の書き方の勉強が出来てよかったです :raising_hand:

ただ眠くなるまでの暇つぶしのつもりで fish スクリプト & 記事を書いてたつもりが、ずっと PC ガン見してたせいで余計に目が冴えてきました :eye: :upside_down: 
フルリモート環境とはいえ昼過ぎから MTG があるので一旦寝ときたいと思います (フラグ :bed: :zzz:

あと Qiita で fish のシンタックスハイライトが使えるようになりたい :sparkler: 

# 参考リンク

- [Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)
- [Introduction — fish-shell 3.1.2 documentation](https://fishshell.com/docs/current/index.html)
- [Allow command substitution with `command` builtin · Issue #5575 · fish-shell/fish-shell](https://github.com/fish-shell/fish-shell/issues/5575)
PythonでExcelを操作する(2)

# 本日の目的
- 開いたExcelに書かれているデータを取得して別なExcelに保存する。
- データ数が分かってない場合の書き方をやってみる。

## ポイント的なアレ
- Excelを操作する（前回参照）
- データの取り方
- 要素数が決まってないときの二次元配列（リスト）

### とりあえずやってみる
- データの取り方
    - セル単位でのデータ取得例：for num in range(maxCellNum)
    - 行単位でのデータ取得例　：for row in ws.iter_rows(min_row = startDataRow):

- 要素数が決まってないときの二次元配列
    - これはググっても出てこないから無理っぽい・・・
    - そもそも使う設計にしない方がいいのかもしれない。
    - 取得元のデータを1行単位でカンマ付き文字列結合をして
    - 使う側でカンマで分割すれば一次元配列（リスト）でもいけそう（ソース参照）

### まとめ
- 要素数の決まってない多次元配列を使いたい時は設計自体を見直した方がいいのかもしれない。

### 参考
- 愚直なコードを載せておきます。

```言語:書いたコード
import sys
import os
import openpyxl

# 実際の売上データではありません。
# 直書きはしたくない。
targetExcel = r"..\data\売上.xlsx"
targetSheetName = "先月売上"
newFileName = "新.xlsx"
newSheetName = "test"

# A4から
startDataRow = 4
startDataColumn = 1

# エクセル開く
# data_only=Trueで式の結果がとれる。無いと式自体がとれる。
wb = openpyxl.load_workbook(targetExcel, data_only=True)

# エクセル内のデータにアクセスする
ws = wb[targetSheetName]

# 空のリストをよーい
# 要素数が決まっていない二次元配列は用意出来ない・・
datalist = []

# 開いたエクセルから対象行のデータをリストにつっこむ
# どうせなら行ごとデータを引っこ抜きたいが・・・
# むりやり
for row in ws.iter_rows(min_row = startDataRow):
    # 行ごとにカンマ区切りで結合してけば何とかなるんじゃない？
    tempStr = "" 
    for cellVal in row:
        # 2項目以降はカンマ付きで結合
        if tempStr == "":
            tempStr = str(cellVal.value)
        else:
            tempStr = tempStr + ',' + str(cellVal.value)
    datalist.append(tempStr)
    print(datalist)


# 新しいエクセルをよーい
wb2 = openpyxl.Workbook()
ws2 = wb2.worksheets[0]
ws2.title = newSheetName

# 元のエクセルと同じ位置にsetしたい
# カンマで結合したやつをリストに入れるんだから
# 戻したいならリストの要素を分割する感じでいけそう。
splitList = []
for rowNum in range(len(datalist)):
    splitList = datalist[rowNum].split(",")
    for colNum in range(len(splitList)):
        ws2.cell(startDataRow + rowNum, startDataColumn + colNum).value = splitList[colNum]

# ほぞーん
wb2.save(newFileName)
```

### おまけ
- パス指定について

```言語:書いたコード
# 前回
targetExcel = r"../data/売上.xlsx"
# 今回
targetExcel = r"..\data\売上.xlsx"
```

- スラッシュ区切りでもバックスラッシュ区切りでもどちらでも問題なく動いている。
- LinuxやMacOSは前者、Windowsは後者で記述するので差分を吸収してくれるのかもしれない。

追記：タイトル更新しました。
サイトにFacebookを埋め込む

## ■ はじめに

タイトルについて記事にしました。
この記事で得る内容は以下の通りです。

・ CSSの基礎知識が増える
・ ページにFacebookの公開ページを埋め込む方法

## ■ 方法

1 まず[ページプラグイン](https://developers.facebook.com/docs/plugins/page-plugin)に移動します

2 Facebookの公開ページ元のURLを入力します。他オプションについては、少し下にプレビューがありますので見比べて選択します

![スクリーンショット 2020-11-09 11.12.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/91c997f7-4fb6-3785-c7e0-dd0720fde97a.png)

3 コードを取得をクリックします

![スクリーンショット 2020-11-09 11.21.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/4e195479-281f-e1a7-6eaf-8cc4c666fe4d.png)

4 モーダルでコードが出てきますので、2つともコピーして（IFrameの方が楽かも？）

![スクリーンショット 2020-11-09 11.24.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/526b6a83-f1ae-f015-038d-2876ee2564b9.png)

5 自分はhaml愛用者なので、せかせか貼り付けて変換してから

![スクリーンショット 2020-11-09 11.30.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/a6eb8b70-9720-3245-c932-858dca0b7a00.png)

6 エディタに貼り付けて、ハッシュ記法を直して

![スクリーンショット 2020-11-09 11.37.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/3963b1c9-94b3-18de-e674-9c3e8c0454ef.png)

7 無事、サイトにFacebookを埋め込むことができました

![スクリーンショット 2020-11-09 11.44.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/772631/fe16ca2a-9a58-df4c-ab79-5238c528d56e.png)

なお、細かい設定について、ページプラグインのコードを取得の下に書いてあるので
サイトのビューや用途に応じて色々変更することができます
アクセス頻度の低いテーブルをBQからGCS Archiveに移動してコスト削減する

BigQueryのストレージ費用は安く、GCSやS3に置くよりもBigQueryにおいたほうが安いということもしばしば発生します。
BigQueryの1ヶ月あたりのストレージの価格は `0.020 USD/GB` であり、さらに90日間変更をしていないテーブルでは自動的にこの半額の `0.010 USD/GB` になります。[^1]
容量が大きくなりがちなログ系のテーブルを日付でパーティション設定することでこの恩恵を受けやすくなります。

https://cloud.google.com/bigquery/pricing#storage

S3の価格が標準ストレージで `0.023 USD/GB` 、 低頻度アクセスでも `0.010 USD/GB` である[^2]ことを考えると、S3に保存するよりもBigQueryに保存したほうが安いという現象が発生する理由も分かります。[^3]

とはいえ、データの量が膨大になってくるとこのストレージの価格もバカになりません。
そのため、BigQueryのテーブルをより安価に保存する方法について紹介します。

# GCS Archiveを使う
BigQueryの値段表だけ見ても、より安価なストレージはないのでGCSに目を向けます。
すると、いい感じに安いストレージが見つかりました。
Archive Storageの価格は `0.0012 USD/GB` [^4]で、BigQueryの長期保存ストレージ価格と比較して88%OFFのお値段です。
その代わりに、データの取り出し時に `0.05 USD/GB` というけっこう高額な値段がかかるので、頻繁にアクセスされるデータの場合はかえって高くなってしまうことに注意が必要です。

https://cloud.google.com/storage/pricing#storage-pricing

このArchiveはS3 Glacier的な用途で使われることが多く課金体系もよく似ていますが、S3 Glacierとの違いは取り出し時間がかからないという点にあります。
そのため、BigQueryのテーブルをGCS Archiveに移したとしても、データの復帰のために数時間待つということは発生しません。
また、BigQueryはGCSのファイルを外部表として使うことができるので、実体がGCSにあるテーブルも透過的にクエリを実行できます。

# 手順
最初にBigQueryのデータを移すためのGCSバケットを作成します。
なお、外部表としてGCSを使うときにはBigQueryのリージョンとGCSのリージョンを揃える必要があるので、環境ごとに `-l` オプションは変えてみてください。
また、BigQueryのデータセット単位で権限管理を行っている場合は、データセットごとにGCSバケットを作成するようにするとGCSでの権限管理上をしやすいです。

```bash
gsutil mb -c ARCHIVE -l US-CENTRAL1 gs://バケット名
```

そして、BigQueryのテーブルをこのバケットにエクスポートし、テーブルの削除を行います。

```bash
bq extract --destination_format AVRO データセット名.テーブル名 "gs://バケット名/テーブル名-*.avro"
bq rm -t データセット名.テーブル名
```

最後に、GCSにエクスポートしたテーブルをBigQueryの外部表として取り込みます。

```
bq mk --external_table_definition="AVRO=gs://バケット名/テーブル名-*.avro" データセット名.テーブル名
```

# 年間何回のアクセスならお得なのか
さてこの方法でGCS Archiveに移動させたデータはアクセス頻度が低ければ低いほうがお得になります。
年間何回程度のアクセスならばこの方法を使ったほうが安くなるのでしょうか？

BigQueryにデータを保存する場合、1ヶ月あたり `0.010 USD/GB` です。(長期保存ストレージ料金)
一方で、GCS Archiveは `0.0012 + データアクセス回数 * 0.05 USD/GB` です。
上記の2つの値が等しくなるデータアクセスは、月間で0.176回、すなわち年間で約2回です。
それ以上の頻度でアクセスを行うとかえって割高になってしまいます。
実際に運用する際には、ややバッファをもたせて年間アクセス頻度が1回以下の見込みであり、十分に巨大なテーブルに対してのみ適用しないとこの方法の旨味が少ないかと思います。

# 注意点
BigQueryの外部表は通常のテーブルと比べて制約を受ける点に注意が必要です。
特にワイルドカードクエリが使用できない点は運用に乗せたあとに発覚すると面倒なことになるので気をつける必要があります。
https://cloud.google.com/bigquery/external-data-sources#external_data_source_limitations


[^1]: 最安であるUSマルチリージョンでの価格(2020年12月時点)
[^2]: 最安である北バージニアリージョンでの価格(2020年12月時点）
[^3]: 実際はデータのシリアライズ形式や圧縮形式も考慮する必要があるため、注意が必要です
[^4]: 最安であるアイオワリージョンでの価格(2020年12月時点）
ASP.NET Core MVCモデルのビューへの値の渡し方

ASP.NET Coreで構成するMVCアプリにおいて、コントローラーからビューにどのように値を渡せるかについてまとめました。

## 文字列

文字列をビューに代入して表示する。

```C#:HomeController.cs
public IActionResult About()
{
   ViewData["Message"] = "Hello World.";

   return View();
}
```
ViewDataに代入した値がそのまま表示されます。

```C#:about.cshtml
@{
    ViewData["Title"] = "About";
}
<p>@ViewData["Message"]</p> // Hello World.
```

## プロパティ

ViewDataのデータ型はディクショナリーとして扱われるので、複数のプロパティやリストを格納してビューに渡すことができます。

```C#:HomeController.cs
public IActionResult Privacy()
{
   ViewData["Product"] = new Product()
   {
      Id = 1,
      Name = "Pen",
      Price = 300,
   };

  return View();
}
```

```C#:Privacy.cshtml
@{
    var product = ViewData["product"] as Product;
}
@product.Name // Pen
```

## リスト

ViewDataにリストを格納した場合の例。

```C#:HomeController.cs
 List<User> nameList = new List<User>();
 foreach(var data in records)
 {
    nameList.Add(data);
 }

 ViewData["Records"] = nameList;
```

リストに格納された各アイテムを`foreach`で取り出します。

```C#:Records.cshtml
<ul>
 @foreach (var item in ViewData["Records"] as IList<User>)
 {
    <li>@item.Name</li>
 }
</ul>

```

### 参考
[ASP.NET Core MVC のビュー](https://docs.microsoft.com/ja-jp/aspnet/core/mvc/views/overview?view=aspnetcore-3.1)
[ViewData in ASP.NET MVC](https://www.tutorialsteacher.com/mvc/viewdata-in-asp.net-mvc)
クローリング速度自動調整のすゝめ

Scrapyでクローリングをするときにダウンロード間隔をどうするべきかは悩ましい問題です。
クローリング対象のシステムの負荷を考えると、短すぎるダウンロード間隔は避けるべきです。
ですが、適切な間隔値は対象サイトごとに異なり、また時間帯によっても異なります。
そのため、サーバーのレスポンスタイムやレスポンスコードによってダウンロード間隔を動的に変えることが出来れば便利です。
Scrapyにはそのための機能であるAutoThrottle Extentionがあるため、これを利用してみます。

# 使い方
使い方はかなり簡単で、settings.pyに以下の設定を書くだけです。

```py
AUTOTHROTTLE_ENABLED = True
```

あとはこれだけで自動的にダウンロード間隔を調整してくれます。

# 仕組み
さて、この拡張機能はどのように動作しているのでしょうか？
以降ではその仕組を説明していきます。

まずクローリング対象サイトに対して並列リクエストをしたい目標値 `AUTOTHROTTLE_TARGET_CONCURRENCY` があり、1回のリクエストのダウンロード時間が `latency` 秒だとすると、以下の時間間隔でダウンロードを実行すればいいことになります。
`latency / AUTOTHROTTLE_TARGET_CONCURRENCY`

そして、最近のダウンロード処理のlatencyを使いながらこの値を常に計算し直すことでダウンロード速度が自動的に調整されます。
実際には現在の設定値と上記で計算した目標設定値の平均を次回のダウンロード間隔として使うことで急激な変化を防いでいます。

この方法は一見すると、対象サイトの並列リクエスト数を指定してリクエストしているだけな気もします。
ですが、その単に並列リクエスト数を指定する方法はエラー発生時にバースト的なリクエスト増加が発生する危険があります。
ステータスコード200以外のエラーレスポンスが返される時は、latencyが短くなることがしばしばあります。
そのようなケースではリクエスト頻度を落とすことで対象サーバーの負荷を減らすべきですが、単に並列リクエスト数を指定する方法ですと逆の動きをします。
AuthThrottleExtentionはエラーレスポンスのlatencyを無視し、正常レスポンスのレイテンシーのみでダウンロード間隔を決定するため、このような問題を起こしません。

# 他の設定値
基本的には `AUTOTHROTTLE_ENABLED` の設定だけでいい感じにしてくれますが、他に設定できる値も紹介します。

## AUTOTHROTTLE_START_DELAY
デフォルト: 5.0

ダウンロード間隔の初期値で単位は秒です。

## AUTOTHROTTLE_MAX_DELAY
デフォルト: 60.0

ダウンロード間隔の最大値で単位は秒です。

## AUTOTHROTTLE_TARGET_CONCURRENCY
デフォルト: 1.0

目標となる並列ダウンロード数です。
この値が大きくなるほどクローリング速度は上がりますが、対象のサーバーに負荷がかかるので注意が必要です。
また、この値はあくまで目標値でありこれ以上の並列度でリクエストを投げるケースもあるためその点も要注意です。
ハードリミットをかけたいときには、 `CONCURRENT_REQUESTS_PER_DOMAIN` や `CONCURRENT_REQUESTS_PER_IP` を使用しましょう。
AutoThrottleExtentionはそれらの設定値以上の並列度でリクエストをすることはありません。

## AUTOTHROTTLE_DEBUG
デフォルト: False

Trueにするとダウンロード速度が変わっていく様子をログに出力します。
heroku環境でnuxtのバージョンアップ（2.0から2.14）

# 環境
- サーバー: heroku
- nuxtのバージョン: 2.0

# 概要
- nuxtを2.14にバージョンアップしたい
- nuxt 2.13からFull Static Generationが導入されたので試してみる

# 手順
基本的に[nuxtの公式ドキュメント](https://ja.nuxtjs.org/docs/2.x/get-started/upgrading/)を参考にすれば上手く行くと思いますが、自分の環境での作業を備忘録として残します。
コマンドはnuxtのプロジェクト直下で叩く想定で記載しています。
かなりシンプルな開発環境なので、npmパッケージを色々インストールしていたりするとこう上手くは行かないかもしれません。

## 1. package.jsonに記述されているnuxtのバージョンを上げる
`dependencies`が`^2.0.0`とかになっているのでバージョンの記載を変更します。
手動でやっても良いですが、他にもパッケージをインストールしていると大変なので、npm-check-updates（ncu）を使うと便利かもです。

```
$ npm install -g npm-check-updates
npm-check-updatesをグローバルにインストール済なら上記コマンドは不要

$ ncu
$ ncu -u
```

## 2. npmパッケージをバージョンアップ
古いnode_modulesを一旦全削除して入れ直す形です。

```
$ rm package-lock.json
$ rm -rf node_modules
$ npm i
```


## 3. nuxt.config.jsに以下記述を追加
Full Static Generationを利用するために記述を追加します。

```js:nuxt.config.js
export default {
  target: 'static',
// 〜〜〜
// 省略
// 〜〜〜
}
```

## 4. package.jsonの記述変更
`heroku-postbuild`が`npm run build`になっている場合は、`npm run generate`に変更します。

```json:package.json
{
  "name": "xxx",
  "version": "1.0.0",
  "description": "My ace Nuxt.js project",
  "author": "xxx",
  "private": true,
  "scripts": {
    "dev": "nuxt",
    "build": "nuxt build",
    "start": "nuxt start",
    "generate": "nuxt generate",
    "heroku-postbuild": "npm run generate"
  },
// 〜〜〜
// 省略
// 〜〜〜
```

## 5. 後はいつも通りherokuにデプロイ
環境によって変わりますが、gitでcommitした後に`git push heroku master`を実行します。
エラー解決方法 "Error: Package exports for './node_modules/colorette' do not define a valid '.' target"

``Error: Package exports for ~ do not define a valid '.' target``の解決方法について書きます。

# 目次
1. エラーが起きるまで
2. エラーコード
3. エラーの原因
4. 解決方法
5. 参考サイト

# エラーが起きるまで

vueのプロジェクトを起動するとエラーが起きた。

```js

npm run serve
```


# エラーコード
```js

Error: Package exports for 'パス' do not define a valid '.' target
```

# 原因
nodeのバージョンでエラーが起きているようです。

```js

node -v

// => v13....
```
このエラーが出た時のバージョンは13でした。

# 解決方法

結論から言いますとこのエラーは、nodeのバージョンを14にすると解決しました。
解決方法について二つ紹介します。

## 解決方法1
### nodebrewを使ってnodeのバージョンをあげる

```js

nodebrew install [version]
```

具体例

```js

nodebrew install 14
```
その後適応

```js

nodebrew use 14
```

バージョン確認

```js

node -v

// => v14....
```


## 解決方法2
### nvmを使ってnodeのバージョンを切り替える

nvmとはnodeのバージョンを切り替えて使うことができるように管理するツールです。

まずはインストール

```js

nvm install 14
```

その後適応

```js

nvm use 14
```


バージョン確認

```js

node -v

// => v14....
```


# 参考サイト
* [nodeのバージョン切り替え](https://qiita.com/chihiro/items/13652c461519f8922f56)
* [nvmで切り替える方法](https://qiita.com/strsk/items/925644e124efcc964625) 
* [バージョンエラーと解決](https://github.com/jorgebucaran/colorette/issues/49)
Vue.jsで湯婆婆を実装してみる


#はじめに
@Nemesis さんの [Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2) がバズってるとのことで、Vue.jsで実装してみました。

#コード
```vue:indext.html
<!DOCTYPE html>
<html>
<head>
  <title>湯婆婆</title>
  <script src="https://unpkg.com/vue"></script>
</head>
<body>
  <div id="app">
    <p> 契約書だよ。そこに名前を書きな。</p>
    <input v-model="name"><br />
    <p>
      フン。{{ name }}というのかい。贅沢な名だねぇ。<br />
      今からお前の名前は{{ newName }}だ。いいかい、{{ newName }}だよ。分かったら返事をするんだ、{{ newName }}!!
    </p>
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {
        name: '',
      },
      computed: {
        newName: function () {
          const random = Math.floor(Math.random() * this.name.length)
          return this.name.substr(random, 1)
        }
      }
    })
  </script>
</body>
</html>
```
例外処理とかコンポーネント化したい衝動を抑えながら、元ネタをリスペクトしました。

#実行結果
![スクリーンショット 2020-11-10 2.38.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60052/8da84034-9d5b-7b42-98d2-229a2a2c8f0d.png)

#クラッシュ湯婆婆の再現
文字入力なし状態ですと、

```
フン。というのかい。贅沢な名だねぇ。
今からお前の名前はだ。いいかい、だよ。分かったら返事をするんだ、!!
```
と、名無しでも何か言ってますね・・・
ある意味、おかしくなってしまった湯婆婆ということで！

#感想
**「HelloWorldの代わりに、湯婆婆を！」**って声も耳にしました。
たしかにHelloWorldは**「出力」**だけなのですが、湯婆婆だと**「入力、出力、文字列（メモリの扱い？）、例外処理」**が含まれていて、各言語の特徴を実感するにはほんと良いネタだなぁと思いました。

追記：
[IchigoJam BASIC版](https://qiita.com/shibomb/items/4d5b6a99985f87a74c3b)も書いてみました。
日本語プログラミング言語「プロデル」「スミレ」で湯婆婆を実装してみる

日本語プログラミング言語[「プロデル」](https://produ.irelang.jp/)とWebブラウザで動作する[「スミレ」](https://sum.irelang.jp/play/)で動く湯婆婆を実装しました。

#### 元ネタ
[Javaで湯婆婆を実装してみる](https://qiita.com/Nemesis/items/c7192a7c510788d2cba2)

#### 日本語プログラミング言語
日本語プログラミング言語は、古くから色々な実装があります。
プロデル/スミレは、TTSneoの後継として開発しているオブジェクト指向のプログラミング言語です。

日本語プログラミングは
「タイプ数がー変換がー・・・」
「日本語は曖昧だから・・・」
「初心者向け」
などと思われる方も多く
Qiitaをご覧の多くの方には、あまり魅力的には見えないかと思います。
こういうのが鬱陶しかったらごめんなさい。

#### プログラム
プログラムは、次の通りです。

字句が日本語ですので何をしているのか、何となくは想像できるかと思います。

```ire:湯婆婆.rdr
「契約書だよ。そこに名前を書きな。」と聞いて名前とする
もし名前が空なら名前は、「名無し」
Nは、名前の文字数の乱数
名前の(N+1)文字目から1文字取り出して新しい名前とする

「フン。[名前]というのかい。贅沢な名だねぇ。
今からお前の名前は[新しい名前]だ。
いいかい、[新しい名前]だよ。
分かったら返事をするんだ、[新しい名前]!!」と表示する
```

シンタックスハイライトがある方が読みやすいので、コードのスクリーンショットも併せて貼っておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/c2f7488e-397f-c8cd-ec65-238fb6647c8c.png)

使用する主な文法は、次の通りです。

- **代入文**: <式>して<変数名>とする | <変数名>は、<式>
- **メソッド呼び出し**: {<式><助詞>}<動詞>
- **条件文**: もし<式>が<式>なら<文>

特徴的な箇所は、3行目の"名前の文字数の乱数"の部分です。

"名前"は、文字列クラスのインスタンス変数です。
"文字数"は、文字数を返す文字列クラスのプロパティ(設定項目)です。
つまり"名前の文字数"と書くと、名前に保持されている文字列インスタンスで文字数プロパティにアクセスします。

"乱数"は、"の"という名前付き引数(助詞)を持つメソッド(手順)です。
"名前の文字数"の評価値を"の"という名前の実引数として"乱数"メソッドに渡して、0からその引数の値未満の乱数を求めます。

日本語プログラミング言語に馴染みがないと、気持ち悪く見えてしまうかと察していますが、文法には明確なルールがあります。プロデル/スミレをはじめ日本語プログラミング言語は、形式言語の範疇で日本語の表記を用いたプログラムが書けます。

なお、2行目を"//"でコメントアウトして実行し、[キャンセル]ボタンをクリックするとクラッシュします。

プロデルは、Windows向けの実行環境です。
https://produ.irelang.jp/

スミレは、Webブラウザ(Blazor)で動作する実行環境です。こちらはAndroidやmacOSでも動作します。
https://sum.irelang.jp/play/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101225/8bb7da9a-c050-6434-a926-790b19fda35a.png)


プロデル/スミレという日本語プログラミング言語もあることを知ってもらえたら幸いです。
nvmで「dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib」エラーが出たときの解決方法

# 環境

- macOS Mojave 10.14.5
- nvmでnode.jsの導入済み


# 概要
npmコマンド実行時に以下のエラーが発生する

```
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.64.dylib
  Referenced from: /usr/local/bin/node
  Reason: image not found
Abort trap: 6
```

# 解決方法
`.bash_profile`に以下の記述が無ければ追加する

```
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```


# 原因
以下の複合要因と思われる。

## 原因1
`.bash_profile`の記述が無かったため、デフォルトでsystemのnodeが使われていた
参考: https://qiita.com/tatama/items/1a6531da8f69dab0b3b5

## 原因2
恐らく`brew upgrade`をしたのが第2の原因。
その際にsystemの古いバージョンのnodeと、新しいバージョンのnodeが相互干渉を引き起こしたと思われる
参考: https://qiita.com/SuguruOoki/items/3f4fb307861fcedda7a5


# 余談
mysqlのバージョンも勝手に上がって開発環境が壊れた（mysql5.7からmysql8.0になってた）ので、あまり気軽に`brew upgrade`はしない方が良いかもしれない・・
GitHub PullRequest の comment を全削除する shell function

zshrc とか bashrc とかに書いておいて

```bash
function delete_pr_comments() {
  owner=$1
  repo=$2
  prnum=$3
  geturl="https://api.github.com/repos/${owner}/${repo}/issues/${prnum}/comments"
  deleteurl="https://api.github.com/repos/${owner}/${repo}/issues/comments/"
  curl -s -H "Authorization: token ${GITHUB_TOKEN}" "${geturl}" | \
    jq '.[].id' | \
    xargs -I{} curl -s -X DELETE -H "Authorization: token ${GITHUB_TOKEN}" "${deleteurl}"{}
}
```

## Run

```
$ cat .envrc
export GITHUB_TOKEN="keep-your-github-token-secret"

$ delete_pr_comments chaspy example-repository 1111
```

便利。

ref: https://developer.github.com/v3/issues/comments/#update-an-issue-comment
MATLABでvoronoi図のデータ形式を確認してみる

# 本稿の目的と出力

このような，動的に変化するボロノイ図のアニメーションを作成するための準備について記します．
![testAnimated.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570966/4d66f115-bb16-d97a-729f-95f2e11ed381.gif)


## MATLABでボロノイ図が簡単に描けるので便利．

MATLAB でボロノイ図を描くのはとても簡単です．変数`x`と`y`に母点の座標を入れ，

``` ボロノイ図を描く:MATLAB
vonoroi(x,y)
```
を実行するだけです．しかし，内容を動的に更新してアニメーションを作成したい場合などは，描画されている点や線のデータ形式を確認する必要があります．この記事ではそれを行います．

## ボロノイ図を描いて描画用のデータを確認するソースコード

``` :MATLAB

numOfPoints=5;
rng(1);
pos=(rand(numOfPoints,2)-0.5)*0.5+0.5;
figure
vrnObj=voronoi(pos(:,1),pos(:,2));
axOrg=[get(gca,'xlim') get(gca,'ylim')];
vrnObj
[vrnObj(1).XData; vrnObj(1).YData]
[vrnObj(2).XData; vrnObj(2).YData]

[vx,vy]=voronoi(pos(:,1),pos(:,2));
vx
vy
vx=[vx;nan(1,size(vx,2))];
vx=reshape(vx,1, prod(size(vx)) );
vy=[vy;nan(1,size(vy,2))];
vy=reshape(vy,1, prod(size(vy)) );

figure(2)
hold on;
plot(pos(:,1),pos(:,2),'o');
plot(vx,vy,'r--');
axis(axOrg);
```

### ソースコード解説

以下，ソースコードの解説です．

- `vrnObj=voronoi(pos(:,1),pos(:,2));`　ボロノイ図を描き，その内容を`vrnObj`という変数に代入しています．`vrnObj`は二つの`Line`を含んでいることが分かるので，その内容を出力してみます．
- すると， `vrnObj(1)`は母点，`vrnObj(2)`はボロノイセルの境界線を示していることが分かります．
    - `nan`を含んだデータを`plot`すると，`nan`を自動で飛ばしてくれる，という仕様がいい感じで効いています．
    - `vrnObj(2).XData`は1行のベクトルで，「`境界線の始点　境界線の終点　nan`」の繰り返しで構成されているようです．
- マニュアルを読むと，`[vx,vy]=voronoi(pos(:,1),pos(:,2))`の形式でボロノイセルの頂点の情報を出してくれるようなので，使って内容を確認してみます．
    - すると，`vx`は2行の配列で，各列に一つの境界線の始点と終点の`x`座標が記録されていることが分かります．
    - したがって，このデータに`nan`を挟んで1列に並び替えれば`vrnObj(2).XData`と同じ形式になりそうです．これをそのまま行うため，`reshape`関数を使います．
- データの準備が終わったら，新しい`figure`に母点とボロノイセルを描画します．わかりやすいように，マーカや色の設定を変えました．

### 出力

`voronoi(pos(:,1),pos(:,2))`で描画した図はこちら．

![voronoiSampleOrg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570966/85f36d65-980b-879e-4371-2873b2688c76.png)

再構成した図はこちら．
![voronoiSampleCopy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570966/0f81c433-f19f-1e1e-9521-3e2b70e5442f.png)

ボロノイ図を動的に変化させたい場合は，`vrnObj(1)`, `vrnObj(2)`それぞれの`XData`と`YData`を適切に変更すればMATLAB側で勝手に描画をし直してくれます．これを利用すると，こんなアニメーションも作れます．

![testAnimated.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570966/76b1f7e1-523f-d37c-06b2-1d6f0aa7671d.gif)
7セグデコーダIC用に10進→2進変換する。

ご無沙汰しておりますtueksです。
今回7セグメントLEDを光らすために７セグメントようデコードICを入手しました。
これは4桁の2進数によって0~9までの数字を7セグメントで表示するためのICで、好きな数字を表示さるための10進2進変換をするためのコードをかきましたので備忘録的に紹介します。

Arduino Uno, Nanoを使用し、7セグデコードICと合わせて使用することで以下のように７セグメントを光らせることができます。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ここまで大変でした😇 <a href="https://t.co/3YiW9mNaMG">pic.twitter.com/3YiW9mNaMG</a></p>&mdash; tueks (@tueks3) <a href="https://twitter.com/tueks3/status/1319111386090205185?ref_src=twsrc%5Etfw">October 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

回路を組み立てなくても、シリアルモニタから10進数が2進数に変換されているかを確認することができます。
![dectobin.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/574102/7af64108-e155-408c-8989-48c8e5a627ad.png)

あまり賢くないとは思いますが、コードです。

```cpp:DecToBin_7segmet
//10進数を2進数に変換します。
//ArduinoUno/Nanoで動きます。
//２進数によって7セグメントをスタティック点灯させるデコードICのために作成しました。
//2020.11.10 tueksによって作成されました。

void setup() {

  Serial.begin(9600);
}

/*10進数2進数変換*/
void ChangeBin(int Dec, int *Bin);

//https://monoist.atmarkit.co.jp/mn/articles/1408/07/news012.html


void loop()
{
  int deadtime = 500; /*mSec*/
  int Bin[4];//4桁2進数用の配列
  int i;
  int k = 0;

//0~9までの数字を順番に表示。
  for (int n = 0; n < 10; n++) {

    Serial.print(String(k)+" ");//シリアルモニタに10進の表示

    ChangeBin(k, Bin);//kで与えられる10進数を2進数にエンコード


 /*d２～４を出力ピンに設定、昇順に配列設定し、TC5068（7セグデコードIC）の入力ピンA~Dに対応*/
    for (i = 0; i < 4; i++) {
      //d2~d5に配列の値Bin[0]~Bin[3]を格納
      if (Bin[i] == 1) {
        digitalWrite(i + 2, HIGH); 
      } else {
        digitalWrite(i + 2, LOW);
      }
      Serial.print(",");
      Serial.print(Bin[i]);//シリアルモニタに2進数の表示
    } Serial.println();


    delay(deadtime);
    k = k + 1;


  }

}


//10進を4bitの2進数に変換し、配列に格納。
void ChangeBin(
  int Dec,  //input
  int *Bin  //roop()内で作成した配列のアドレスを受け取る。ポインタ渡し。
)
{
/*10進数が２進数に変換され、配列に格納。Bin[3]=0桁目,Bin[2]=1桁目,Bin[1]=2桁目,Bin[0}=3桁目*/
  int m = 3;
  for (int i = 0; i < 4; i++) {
    Bin[m] = Dec % 2;
    Dec = Dec / 2;
    m = m - 1;
  }

}
```

以下雑なコードの解説です。プログラミングには本当に弱いので説明が間違っているかもしれません。なにかありましたらご指摘いただければと思います。

ChangeBinという自作した関数によって１０進数を２進数に変換します。
loop()内でkによって与えられた10進の数、Bin[]という配列をChangeBinに渡します。配列は関数によって直接値を書き換えられないため、「ポインタ渡し」という作成した配列Bin[]のアドレスを渡します。
ChangeBin関数内で10進2進変換が行われ、2進数は4桁の配列に1文字ずつ格納されます。
loop()内で配列Bin[0]~[3]の値が呼び出され、digitalWriteによってArduinoのd0~d5を2進数の電圧出力にします。

2進数の出力で直接LEDを駆動するとこうなります。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">配列を引き渡すのにポインタを使うとか言うのよくわかんなくて難しかったです。みつお <a href="https://t.co/Z9UPUYAuza">pic.twitter.com/Z9UPUYAuza</a></p>&mdash; tueks (@tueks3) <a href="https://twitter.com/tueks3/status/1319105493743226882?ref_src=twsrc%5Etfw">October 22, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
以上です。

tueks
scikit-learnのimportエラー

# What
この記事はscikit-learnのimport時に生じたエラーを解決する記事です。

# Problem
下記のプログラムで実行時に以下のエラーが出ました

```python:sklearn.py

from sklearn import datasets
import numpy as np

# Irisデータセットをロード
iris = datasets.load_iris()
```
このコードを実行すると、一番下の行に`sklearn`から`dataset`が読み込めないとエラーが出てしまいます。

```py
File "sklearn.py", line 1, in <module>
    from sklearn import datasets
  File "/Users/apple/python/sklearn.py", line 1, in <module>
    from sklearn import datasets
ImportError: cannot import name 'datasets' from partially initialized module 'sklearn' (most likely due to a circular import) (/Users/apple/python/sklearn.py)
```

# Solution
ファイル名をsklearn以外の名称にしたら解決しました。
ファイル名がsklearnになっていることが原因で、自分自身がインポートされていたようです。

# Detail
以下の２行を実行し、ファイルがどこから読み込まれているかチェックしました

```py
import sklearn
print(sklearn.__file__)
```
なんと、自分自身を読み込んでいました笑

```py
/Users/apple/sklearn.py
```

なのでファイル名変えてみたらうまく行きました