OmniAICreator/Qiita-1.07M huggingface dataset:
【Kubernetes】更新したイメージをロールバックさせるには？　no.6

![名称未設定のデザイン (12).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/cd286c8e-8bce-7f8e-a487-9469c2dcc965.png)


こんにちは。まゆみです

Kubernetesについての記事をシリーズで書いています。

[前回の記事](https://qiita.com/Mayumi_Pythonista/items/dd5b183a89a4fdd47c7e)でContainerのイメージを更新した時にどのようにしたら反映されるかを書いてきました。

今回の記事では、<font color="Red">逆に更新したイメージをまた元に戻すにはどうしたらいいのか</font>書いていきますね。

![ロールバック (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/a0dbe98c-23d4-47ff-4a88-5fb4dd73ea02.png)


ではさっそくはじめていきます。

#1つ前のバージョンに戻りたい時

更新させる『1つ前』のものにロールバックさせたい時は下記のコマンドになります

```
kubectl rollout undo deployment/<deployment名>
```
#特定の時点まで戻りたい

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/06277e01-49a8-7f5f-d41e-f32203be0365.png)


では何回か更新をした後、ある特定の時点までロールバックさせたい場合どうしたら良いのでしょうか？

```
kubectl rollout history deployment/<deployment名>
```

で今まで何回更新してきたかを見ることができます

そして先ほどのコマンドに --revision=オプションを付けることで特定の時点で使っていたImageなどを調べることができます

![2021-07-22_9-36-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/0645b344-e4eb-f407-9e14-69740985bbbd.png)

私の場合で言いますと

>latest は英語で　『Hello from this NodeJS app!』
2 は『こんにちは。nodeのアプリです』
3 は『こんにちは。nodeのアプリです。バージョン3です。』

とテキストを変えてバージョンを分けてみました。

Docker hubでは下のようにバージョン分けして保存されています


![2021-07-22_9-45-33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/75371c80-04e7-675d-2f06-aff0f18c33b5.png)

--revision=を付けてそれぞれを詳しく調べると、--revision=5がタグが付いていない、latestバージョンのイメージで作ったdeploymentだと分かったので、この時点までロールバックさせます。

1つ前のバージョンにロールバックをする時に使ったコマンドに『--to-revision=』オプションを付けます

```
kubectl rollout undo deployment/<deployment名> --to-revision=5
```

![2021-07-22_9-59-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/e02e9fc1-e1c5-bf86-fc21-96a22c68d321.png)

![2021-07-22_10-08-58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/aadeeb7c-7049-b16f-603c-655b7911d388.png)


--revision=4　ではImageのバージョン3が使われて更新されていたみたいなので、こちらの時点まで戻してみます。

```
kubectl rollout undo deployment/<deployment名> --to-revision=4
```

![2021-07-22_10-15-45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/2b467ee5-9c6e-d1b9-089f-dce94f9a9661.png)


![2021-07-22_10-17-28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1011305/7dec1c66-09e0-06d9-21e5-9f03d137a0ba.png)
ラズパイでテレビを操作する

##前提

- ラズベリーパイとTVをHDMIで繋いでいる
- テレビがCECに対応している
- テレビのCEC連動をONにしている(メーカーによって呼び方が違います。東芝のレグザリンク等) 

## config.txtの編集
以下のコマンドでconfig.txtを開き、`hdmi_force_hotplug=1`と`hdmi_ignore_cec_init=1`を追記します。

```
sudo /boot/config.txt
```

``` bash:/boot/config.txt
hdmi_force_hotplug=1
hdmi_ignore_cec_init=1
```

`hdmi_force_hotplug=1`はラズパイのHDMIがディスプレイ(テレビ)に接続されていない状態で起動すると、NTSC(コンポジット)に切り替わってしまうのを防ぐために、`hdmi_ignore_cec_init=1`はラズパイが起動時に勝手にディスプレイ(テレビ)がONになるのを防ぐための設定です。

## cec-utilsのインストール
以下のコマンドで`cec-utils`をインストールします。

``` bash
sudo apt install cec-utils -y
```

## テレビの操作
### 基本操作
以下のコマンドでテレビの電源のOn/Off、音量の操作が出来ます。
``` bash:電源ON
echo 'on 0' | cec-client -s
```

``` bash:電源OFF
echo 'standby 0' | cec-client -s
```

``` bash:音量を上げる
echo 'volup' | cec-client -s
```

``` bash:音量を下げる
echo 'voldown' | cec-client -s
```

### 入力切り替え
以下のコマンドで入力機器の情報を取得します。

```bash
echo "scan" | cec-client -d 1 -s
```

``` bash:出力結果
log level set to 1
opening a connection to the CEC adapter...
requesting CEC bus information ...
CEC bus information   
===================   
device #0: TV
address:       0.0.0.0  
active source: no     
vendor:        Toshiba
osd string:    TV     
CEC version:   1.4    
power status:  on     
language:      jpn


device #1: Recorder 1
address:       2.0.0.0
active source: no
vendor:        Toshiba
osd string:    CECTester　← ラズベリーパイ
CEC version:   1.4
power status:  on
language:      eng


device #5: Audio
address:       1.0.0.0
active source: no
vendor:        Onkyo
osd string:    TX-NR626
CEC version:   1.4
power status:  on
language:      ???


device #B: Playback 3
address:       3.0.0.0
active source: no
vendor:        Toshiba
osd string:    Fire TV Stick
CEC version:   1.4
power status:  on
language:      ???
```

以下のコマンドで入力を切り替えます。

``` bash
echo "tx ff:82:30:00" | cec-client -s
```
`ff:82:30.00`の値の意味は`ff`が全ての機器から全ての機器です、一桁目は数字か`f`なら何でも大丈夫です。`82`は入力切り替えのです。`30:00`は機器のアドレスになります。今回は上記出力結果のFire TV Stickのaddressが`3.0.0.0`だったのでドットを除外して二桁ずつに分けてセミコロンをつけて`30:00`になります。ラズベリーパイの場合だとaddressが`2.0.0.0`なので`20:00`です。私の環境ではテレビへの切り替え`echo "tx ff:82:00:00" | cec-client -s`が効きませんでした。

その他のコードは[こちらのサイト](https://www.cec-o-matic.com/)で確認できます。

## My Accounts
<a href="https://github.com/mao2009"><img src="https://mao2009.github.io/qiita_template/GitHub-Mark-64px.png" width="50px"></a><a href="https://twitter.com/loach_mao"> <img src="https://mao2009.github.io/qiita_template/Twitter_Social_Icon_Circle_Color.png" width="50px"></a>
webpack.config.jsに書いてあることを理解する

youtubeでモダンフロントエンド関連の動画を上げられているとらハックさんというyoutuberがyoutubeに投稿されているTypescript入門で環境構築を行う際に、webpack.config.jsというファイルをいじる場面が出てきたが、何をやっているかいまいち理解できていないのでそれを理解するためにこれから書き殴っていこうと思います。

設定はこんな感じ↓

```
const path = require('path');
module.exports = {
  entry: {
    bundle: './src/index.ts'
  },
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js'
  },
  resolve: {
    extensions:['.ts','.js']
  },
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    open: true
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader'
      }
    ]
  }
}
```

#entryとoutput
###entry

entryではwebpackがビルドした時に読み込むファイルを設定している。
webpackはこのファイルの中身を見て、ファイルの依存関係を考慮してビルドを行ってくれる。
今回は以下のように記述されている。

```
  entry: {
    bundle: './src/index.ts'
  },
```

「srcディレクトリの中にあるindex.tsを見て、ファイルの依存関係等を考慮した上でファイルをひとつにビルドするよ」みたいな意味。

###output

outputではwebpackがビルドしたファイルをどこに出力するのかを設定している。
今回は以下のように記述されている。

```
  output: {
    path: path.join(__dirname, 'dist'), // "__dirname"はファイルが存在するディレクトリ
    filename: '[name].js'  // [name]はentryで記述した名前（この設定ならbundle）
  },
```

pathには、ビルドしたファイルの出力先、
filenameには、ビルドしたファイルの名前を設定している。

####path

今回、pathは以下のように記述されている

```
  path: path.join(__dirname, 'dist'),
```
バリューにある「path」はnpmに標準で搭載されているモジュールで、ファイルのパスを出力する際に使用するものなので、ファイル上部でrequireするのを忘れずに。

```
  const path = require('path');
```
「ルートにあるdistというディレクトリにビルドしたファイルを出力するよ」みたいな意味。

####filename

今回filenameには以下のように記述されている。

```
  filename: '[name].js'
```
[name]には、entryで読み込むファイルのキー名が紐づくので、今回は「bundle.js」というファイルがビルド後のファイルが出力されることになる。

今回、entryとoutputに書いてあることをまとめると、「僕（webpack）は、ファイルをビルドするとき、index.tsというファイルを読み込んでから、ファイルの依存関係を考慮した上で、distディレクトリの中にbunle.jsという名前で、ビルドしたファイルを出力するよ」みたいな意味になる。

#resolve

resolveには、ファイルをimportする際の設定を行うことができる。
今回は以下のように記述されている。

```
  resolve: {
    extensions:['.ts','.js']
  },
```
「ファイルをインポートするときは.tsと.jsを省略できるよ」みたいな意味。

#devServer

devServerでは、開発用のサーバーの設定を行うことができる。
今回は以下のように記述されている。

```
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    open: true
  },
```
contentBaseには、webpack-dev-server(パッケージ)が開発環境でファイルをビルドする際に参照するディレクトリ、
openには、ローカルでwebサーバーを立ち上げた時にブラウザを勝手に立ち上げるか否かみたいな設定を記述。

####contentBase
今回は以下のように記述されている

```
　　contentBase: path.join(__dirname, 'dist'),
```
「僕（webpack-dev-server）は、開発環境でファイルをビルドするときは、ルートにあるdistというディレクトリを参照しますよ」みたいな意味。

####open

今回は以下のように記述されている

```
　　open: true
```
「あなた（開発者）が開発環境でwebサーバーを立ち上げた時、自動的にブラウザも立ち上げちゃいますよ」みたいな意味。

#module

moduleでは、モジュールの設定を行うことができる。
今回は以下のように記述されている。

```
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'ts-loader'
      }
    ]
  }
```

>※モジュールとパッケージの違い
moduleは、妥当な機能を備えた単一のJavaScriptファイルで、packageは、1つ以上のモジュールが内部にあるディレクトリです。

testには、ローダーが読み込むファイルの設定、
lorderには、ローダーとして何を使用するのか設定を記述できる。

####loder
今回は以下のように記述されている。

```
loader: 'ts-loder'
```
見ての通り、「ローダーはts-loderを使いますよ」という意味。

####test

今回は以下のように記述されている。

```
test: /\.ts$/,
```
>javascriptの正規表現はスラッシュで囲う。
「.」を文字列として扱いたいので、\でエスケープ処理を行う。
$でファイルの末尾を表現している。

まとめると、「.tsで終わるファイルをts-lorderを使ってjavascriptにコンパイルしますよ」みたいな意味になる。

以上！疲れた！
3.3(難) 超幾何分布

## 方針

超幾何分布とは，赤玉M個，白玉N-M個の箱からn個取り出す時，赤玉がX個である，という離散確率変数Xの分布であり，二項分布の非復元抽出バージョンである．確率密度関数は，

```math
f_X(x)=\frac{{}_MC_x\times{}_{N-M}C_{n-x}}{{}_NC_n},\ \ x=0,...,n
```

この分布の全確率1と平均分散を求める問題．全確率1については初見で解くのは無理．平均，分散については考え方は二項分布の平均を求めるアプローチと似ているので，先に二項分布について確認しておくことを勧める．

## 答案

```math
f_X(x)=\frac{{}_MC_x\times{}_{N-M}C_{n-x}}{{}_NC_n},\ \ x=0,...,n
```

より，全確率1は

```math
\sum_{x=0}^n\frac{{}_MC_x\times{}_{N-M}C_{n-x}}{{}_NC_n}=1
```

を示せば良い．上式は，

```math
{}_NC_n=\sum_{x=0}^n{}_MC_x\times{}_{N-M}C_{n-x}
```

と書き換えることができる．ここで，

```math
(a+b)^N=(a+b)^M(a+b)^{N-M}
```

の両辺を二項展開して

```math
\sum_{n=0}^N{}_NC_na^nb^{N-n}=\sum_{x=0}^M{}_MC_xa^xb^{M-x}\times\sum_{y=0}^{N-M}{}_{N-M}C_ya^yb^{N-M-y}
```

これはaとbを変数としてもつ恒等式なので，ある項a^nb^{N-n}の係数比較により

```math
\begin{align}
{}_NC_n&= \sum_{x+y=n,0<x,y<n}{}_MC_x\times{}_{N-M}C_y\\
&= \sum_{x=0}^n{}_nC_x\times{}_{N-M}C_{n-x}
\end{align}
```

次に，平均を求める．

```math
\begin{align}
\mathbb{E}_{X\sim f_X}[X]&= \sum_{x=0}^nx\frac{{}_MC_x\times{}_{N-M}C_{n-x}}{{}_NC_n}\\
&= \sum_{x=1}^nx\frac{{}_MC_x\times{}_{N-M}C_{n-x}}{{}_NC_n}\\
&= \sum_{x=1}^n\frac{(x\times{}_MC_x)\times{}_{N-M}C_{n-x}}{{}_NC_n}\\
&= \sum_{x=1}^n\frac{(M\times{}_{M-1}C_{x-1})\times{}_{(N-1)-(M-1)}C_{(n-1)-(x-1)}}{\frac{N}{n}{}_{N-1}C_{n-1}}\\
&= \frac{nM}{N}\sum_{x=1}^n\frac{{}_{M-1}C_{x-1}\times{}_{(N-1)-(M-1)}C_{(n-1)-(x-1)}}{{}_{N-1}C_{n-1}}\\
&= \frac{nM}{N}\sum_{x'=0}^n\frac{{}_{M-1}C_{x'}\times{}_{(N-1)-(M-1)}C_{(n-1)-x'}}{{}_{N-1}C_{n-1}}\ \ \ \ \ \ (x'=x-1)\\
&= \frac{nM}{N}
\end{align}
```

次に，分散を求める．

```math
\begin{align}
\mathbb{E}_{X\sim f_X}[X(X-1)]&= \sum_{x=0}^nx(x-1)\frac{{}_MC_x\times{}_{N-M}C_{n-x}}{{}_NC_n}\\
&= \sum_{x=1}^nx(x-1)\frac{{}_MC_x\times{}_{N-M}C_{n-x}}{{}_NC_n}\\
&= \sum_{x=1}^n(x-1)\frac{(x\times{}_MC_x)\times{}_{N-M}C_{n-x}}{_NC_n}\\
&= \sum_{x=1}^n(x-1)\frac{(M\times{}_{M-1}C_{x-1})\times{}_{(N-1)-(M-1)}C_{(n-1)-(x-1)}}{\frac{N}{n}{}_{N-1}C_{n-1}}\\
&= \frac{nM}{N}\sum_{x=1}^n(x-1)\frac{{}_{M-1}C_{x-1}\times{}_{(N-1)-(M-1)}C_{(n-1)-(x-1)}}{{}_{N-1}C_{n-1}}\\
&= \frac{nM}{N}\sum_{x'=0}^nx'\frac{{}_{M-1}C_{x'}\times{}_{(N-1)-(M-1)}C_{(n-1)-x'}}{{}_{N-1}C_{n-1}}\\
&= \frac{nM}{N}\times\frac{(n-1)(M-1)}{N-1}\\
&= \frac{n(n-1)M(M-1)}{N(N-1)}
\end{align}
```

となるので，

```math
Var(X)=\frac{N-n}{N-1}n\frac{M}{N}(1-\frac{M}{N})
```

## 参考文献

- 『[現代数理統計学の基礎](https://www.kyoritsu-pub.co.jp/bookdetail/9784320111660)』(久保川達也　著)
PowerShellのFormUI作成が苦行だったためExcelでツールを作ってみた。

## はじめに

最近PowerShellを使い始めたのですが、FormUIのデザインがあまりにも苦行だったので、
ExcelマクロでFormをデザインできるツールを作ってみました。

## つかいかた

DesignシートにActiveXコントロールを貼り付け、
Codeシートの「Generate Code」を押すとPowershellスクリプトが生成されます。
なお「Copy Code」でコードのコピー、
「Execute Test」で生成したコードを実行できます。

## 現在対応しているコントロール

- ラベル
- テキストボックス
- コンボボックス
- リストボックス
- ピクチャボックス
- チェックボックス
- ラジオボタン
- プログレスバー
- ボタン

## 画面イメージ

![image](https://user-images.githubusercontent.com/33306175/126576734-e6b0f99b-12b7-4802-9dcb-198e16554a25.png)

![image](https://user-images.githubusercontent.com/33306175/126884919-662004be-fe31-4a6d-839e-9f78d870d94e.png)

## ダウンロード

Ver.1.1.0

https://github.com/imoimo2009/PS_FormDesigner
書籍「pandasライブラリ活用入門」3.4.3.2 の作図

# はじめに

[書籍「pandasライブラリ活用入門」](https://book.impress.co.jp/books/1118101067)の「3.4.3.2 サイズと形」で出てくる seaborn によるプロットでエラーになる箇所があったのでメモします。

なお、ここでは1番目の図について説明します。2番目も違う理由で動作しなかったので、[こちら](https://qiita.com/noobar/items/be9008f2eceabeaf4a9a)に記事を作りました。

**動作環境**
* Python 3.7
* seaborn 0.11.1
* matplotlib 3.2.2 (Colab) / matplotlib 3.4.2 (local PC)

# 現象

データの`size`列の値によって散布図のマーカーサイズを出し分ける図です。下のようなコードが示されています。

```python
import seaborn as sns
from matplotlib import pyplot as plt

tips = sns.load_dataset('tips')
sns.lmplot(
    data=tips,
    x='total_bill',
    y='tip',
    fit_reg=False,
    hue='sex',
    scatter_kws={'s': tips['size'] * 10}
)
plt.show()
```

しかし、これを実行すると `ValueError` となってしまいます。

>ValueError: s must be a scalar, or float array-like with the same size as x and y

StackOverflow で質問したところ、このような使い方はそもそも想定されていなかった（たまたま動いていたのがバージョンアップで検証処理が入り動作しなくなった）とのこと。

https://stackoverflow.com/questions/68457453/seaborn-lmplot-raises-valueerror-when-set-both-hue-and-scatter-kwss-s

# 解決策

このような場合は [lmplot](https://seaborn.pydata.org/generated/seaborn.lmplot.html) ではなく [scatterplot](https://seaborn.pydata.org/generated/seaborn.scatterplot.html) を使った方が素直に書けます。（回答者さんありがとうございます。）

```python
sns.scatterplot(
    data=tips,
    x='total_bill',
    y='tip',
    hue='sex',
    s=tips['size'].mul(20),
    # size='size',  # s または size のいずれかを指定
)
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43328/268226f4-e39c-3356-1520-5781a4231857.png)
railsでnull制限、空文字制限をかける

# この記事の目的

railsでnull制限をかける際にやらないといけないこととその実装内容。

# 全体

- dbのカラムにnull制限をかける
- カラムへのnull制限だけだと空文字を入れれてしまうのでmodelにvalidation

## dbのカラムにnull制限をかける

```ruby
def change
  change_column_null :skill_maps, :skill_id, false
end
```

null制限をかける場合（falseはnullの許可がfalse）

```ruby
change_column_null :テーブル名, :カラム名, false
```

## modelにvalidation

カラムへのnull制限だけだと空文字を入れれてしまうのでmodelにvalidation

```
validates :content, presence: true
```
AWS DynamoDB検索関連メモ

久しぶりに仕事で使った。思い出しメモ

##プライマリキー
・パーティションキー、またはパーティションキー＋ソートキーの複合キーとなる。
・重複不可
・パーティションキーは、パーティションテーブルを特定するためのキーとなる。
　→パーティションキーで、パーティションテーブルが一意に決まる。
・パーティションテーブル内のデータは、パーティションキー、ソートキーで並んでいる。
　→インデックス
　　ソートキーの順番に並んでいるから、DynamoDBでは、ソートキーの昇順or降順でデータを取得できる。
　　⇒そのまま取り出すか、逆順にして取り出すか。それぐらいの並び替えしかできない。

##グローバルセカンダリインデックス
・インデックステーブルを作成する。
・パーティションキー、またはパーティションキー＋ソートキーの複合キーを設定する。
　→意味合いは、プライマリキーと同じだが、こちらは重複可

##検索について
・スキャン検索は、全レコード検索
・クエリ検索は、プライマリキーを指定しての検索。
　パーティションキー、または、パーティションキー＋ソートキー
　※パーティションキーは等価（=）の検索が可能
　　ソートキーは等価以外の検索も可能
　　（=,<,<=,>,>=,BETWEEN,begins_with）
・取得データを絞り込むために、フィルタというものがある。
　どのアトリビュートでも絞り込むことができる。
　⇒ただし、以下の動きになる。
　　スキャン検索では、全レコードを検索した後に、絞り込む。
　　クエリ検索では、プライマリキーで検索した後に、絞り込む。
　　※料金がかかるのは、フィルタで絞り込む前のデータの読み込みであることに注意。
新しいデバイスを使用してxcodeでビルドする方法

新しいデバイスを接続してビルドすると、こんなエラーがでます。

```swift
Showing Recent Messages Device "iPhone" isn't registered in your developer account. The device must be registered in order to be included in a provisioning profile.
```

こうなったときの対処法をよく忘れがちなのでメモ。

## 1. 接続したデバイスのidをコピー

`⌘ + SHIFT + 2` を押してデバイス情報を表示


![Devices.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569090/e0fb09c7-9834-7d4c-69d5-bd15a7ba8095.png)

## 2. AppleDeveloperでデバイスを新規登録

AppleDeveloperサイトからログインしましょう。
Certificates　▶　Devices　から新規作成ぼたんを押します。


https://developer.apple.com/


![Certificates__Identifiers___Profiles_-_Apple_Developer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569090/6e13705d-dcfd-ae82-ad07-e00f269c80a6.png)

![Certificates__Identifiers___Profiles_-_Apple_Developer (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569090/e025a17b-ccd3-90e1-c8ac-58e44f69f10c.png)

右下の枠部分を記入してcontinueボタンを押せばOKです。
Device Name は任意で名前を決められます。
DeviceID は先程コピーした値を入れましょう。


## Xcodeを再起動してビルド
忘れちゃいけないのがXcodeの再起動！
これでビルドがうまくいくはずです。
もし役に立ったらLGTMお願いしますー！
React入門 - Tips4 - dockerでReact環境を構築してみる

# Dockerとは

[ここが分かりやすかったです。](https://knowledge.sakura.ad.jp/13265/)

Docker社が開発している、コンテナ型の仮想環境を作成、配布、実行するためのプラットフォームとのことです。（https://www.docker.com/what-docker）

私的には、
昔でも無いけど、よくVirtualBoxとかに最初の人が開発環境を作って、開発者みんなに配って。みたいな状況はよくありました。
VirtualBoxは容量もでかいし、メモリ食うし。そういうのがなくVirtualBoxみたいにGUIを起動せず、バックグランドで動く自由に組み合わせられる環境って感じでしょうか。

纏めます。

- 軽量で高速に仮想環境を動作できる
- Dockerインストール済PCなら、OSに依存せずDockerイメージで同一環境を構築可能
- Dockerfileで動作させるコンテナをコードで管理できる
- 作成アプリなどを、Dockerfileを渡すことで他のローカル環境でも実行することができる

Dockerさえいれておけば、いろんな言語や環境を自PCをあまり弄らず試せますね。

あと、思惑としては、教材用にREST APIの代わりをDockerで構築してReact画面からアクセスしようかなと
そんなことを考えています。


# Dockerのインストール

Windowsを例にします。

[ここでDocker Desktop for Windows ボタンをクリックしてください。](https://docs.docker.com/docker-for-windows/install/)

デフォルトでインストールし再起動します。

# Docker正常起動の確認

PCを再起動してDockerが正常に起動することを確認します。

普通の環境構築の場合、ここはサクッといくとこなんでしょうけど、いきませんでした。
(ちなみに、私の環境はWindowsです。Macだとサクサクいくと聞いたことがある。)

以下のようなエラーが出ました。


- <font color="red">Docker Desktopで「Hardware assisted virtualization and data execution protection must be enabled in the BIOS.</font>
- <font color="red">Docker.ApiServices.WSL2.WslKernelUpdateNotInstalledException
- <font color="red">Failed to deploy docker-desktop to　C:\Users\user\AppData\Local\Docker\wsl\distro: exit code: -1 ・・・・</font>

解決するには

- BIOSのVirtualization Technologyの設定をDisabledからEnabledに変更

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/0882a4d5-4ab8-76e6-872a-3bbc285d9210.png" width="50%">

- Windowsの機能の有効化または無効化のHyper-Vのチェックをオン

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/f43c209a-b78d-eea1-9c69-8446c3566d99.png" width="50%">

<font color="red">など。。。。。いろいろやって正常起動できました。</font>
いつか再検証行いたいと思います。

正常起動した場合は、このようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/559029/bd9198a3-24af-8a72-f416-23b9918a7869.png)

タスクバーのとこに表示されるクジラさんからランダムな縦棒が出ている状態？

# Docker - React動作環境作成(概要)

1. Docker用ファイルの作成と記述
2. Dockerイメージビルド
3. create-react-appとReactのインストール
4. コンテナの起動とReactの実行

# Docker - React動作環境作成(Docker用ファイルの作成と記述)

作業ディレクトリ作成後、
Dockerで環境作成時、必ず以下2ファイルを作成します。

- Dockerfile(基本的なコンテナ構成情報を記述)
- docker-compose.yml(複数コンテナそれぞれの構成情報を記述)

```yaml:Dockerfile_node
FROM node:14
WORKDIR /usr/src/app
```

```yaml:docker-compose.yml
version: '3'
services:
   node:
     build:
       context: .
       dockerfile: Dockerfile_node
     volumes:
      - ./:/usr/src/app
     command: sh -c "cd react-sample && yarn start"
     ports:
      - "3000:3000"
```

中身は(今は)サラッと見ておきましょう。
Dockerに慣れてきたらまた再度見直してみたいと思います。

# Docker - React動作環境作成(Dockerイメージビルド)

Git Bashなどで作業ディレクトリに移動し、Dockerイメージをビルドします。

```
docker-compose build
```

# Docker - React動作環境作成(create-react-appとReactのインストール)

```
docker-compose run --rm node sh -c "npm install -g create-react-app && create-react-app react-sample
```

reactのインストールに数分かかります。たぶん。
私のサブマシンでは20分くらいかかったかな。。。


※途中、Dockerが作業ディレクトリを共有するか？的なメッセージが出ますので、Share itしておいてください。

# Docker - React動作環境作成(コンテナの起動とReactの実行)

コンテナを起動します。

```
docker-compose up
```

ブラウザで`localhost:3000`にアクセスしたらLearn Reactが出ますよね？
出るはずだ！

試しに、ローカルにあるReactのソースApp.jsの`Learn React`を`Learn Docker React`に変更してみてください。仮想環境に自動的に適用されて表示されることが分かるかと思います。
NeosVRのオブジェクトのすり抜けをなくし当たり判定を追加する方法【CharacterCollider】

前回の記事ではiPhoneLiDARでスキャンした現実の物体を3Dデータ化して、NeosVR空間内に持っていく方法を紹介しました。

https://qiita.com/sushitenko/items/8bfb1fc6388b8927120c

ただ、上記の方法のみだと、<font color="Red"><b>オブジェクトを自身のアバターがすり抜けてしまう</b></font>という問題が生じます。

https://twitter.com/sushitenko/status/1417948260581343233

現実の物体や空間をVR空間内で体験する際、壁にあたってキャラクターの動きが止まったり、道に沿って歩けないと、イマイチ臨場感や現実感が再現できていないと感じるかもしれません。

この問題を解決するためには、NeosVRに用意されている<b>「CharacterCollider(当たり判定)」</b>という設定をオブジェクトに反映する必要があります。
※詳しくはNeosVRWikiを参照

https://neosvrjp.memo.wiki/d/CharacterColliderSetterTip

この方法を活用すると、以下のツイート通り、オブジェクトに当たり判定が設定され、道に沿って歩いたり、壁に当たるとアバターの動きがしっかり止まるようになります。

https://twitter.com/sushitenko/status/1417948823926624258

<h2>CharacterCollider(当たり判定)の追加方法</h2>

以下の手順で当たり判定を設定していきます。

<h3>1.メニューから「インベントリー」を選択</h3>
<h3>2.「EssentialTools」から「CharacterColliderSetterTip」を選択</h3>
![NeosVR 2021_07_22 6_03_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/1e7e2625-4e3f-3bf8-9961-a80e5f1da930.png)
<h3>3.ワールド内に出現した「CharacterColliderSetterTip」を装備する</h3>
![NeosVR 2021_07_22 6_05_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/38e8e697-a81c-0255-5170-28e037a4ec6e.png)
<h3>4.装備完了後、当たり判定を追加したいオブジェクトにレーザーを当てトリガーを押す(マウスなら左クリック)</h3>
![NeosVR 2021_07_22 6_05_56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/76ce7f1a-7936-81ef-842d-9fd3abc5a209.png)
画像では表示されてませんが、オブジェクトが一瞬だけ緑色に点滅したら、CharacterColliderの設定が反映されます。
errors.Warpf => xerrors.Errorf全置換正規表現


vscodeでいきなり `すべて置換`　を選ぶと $1　が変な結果になるので1件ずつ確認しながら実行してください。


```
search : errors.Wrapf\(err,\s"([^"]+)"\)
replace: xerrors.Errorf("$1: %w",err)
```

結果：

```:go
return errors.Warpf(err, "failed to xxx")
=>return  xerrors.Errorf("failed to xxx: %w", err)
```

```
search :errors.Wrapf\(err,\s`([^`]+)`\)
replace: xerrors.Errorf(`$1: %w`,err)
```

結果：


```:go
return errors.Warpf(err, `failed to xxx("cccc")`)
=>return  xerrors.Errorf(`failed to xxx("ccc"): %w`, err)
```
2021/07/20開催 Connpassイベントランキング

# 申込数TOP5

|順位|イベント名|グループ|申込数|定員|
|:---:|:---|:---|:---:|:---:|
|:one:|[Ansible Night Online 2021.07](https://ansible-users.connpass.com/event/216195/)|[Ansible ユーザー会](https://ansible-users.connpass.com/)|330|350|
|:two:|[第４回ACRiウェビナー：FPGAの活用例が分かる！ライトニングトーク大会](https://acri.connpass.com/event/216978/)|[ACRi](https://acri.connpass.com/)|314|350|
|:three:|[【BIT VALLEY 2021】#01 Local×Startup 『街とStartup』](https://sbv.connpass.com/event/212753/)|[SHIBUYA BIT VALLEY](https://sbv.connpass.com/)|222||
|:four:|[JaSST nano vol.2](https://jasst-nano.connpass.com/event/215889/)|[JaSST nano](https://jasst-nano.connpass.com/)|208||
|:five:|[DMM.go #3](https://dmm.connpass.com/event/218192/)|[DMM.com](https://dmm.connpass.com/)|147||
Android Studioのログが流れない場合の対応

Android StudioにてAndroidアプリの開発をしている際に、アプリ起動後のLogCatのログが流れない場合があります。流れない原因については改めて調査しようと思いますが、今回はログを流れるようにする方法をお伝えします。

# ログが止まった場合の対応
* Android StudioにてTerminalのタブを開く
* ターミナルにて以下のコマンドを実行

~~~
$ adb kill-server
$ adb start-server
daemon not running; starting now at tcp:5037
daemon started successfully
~~~

* 上記のような表示が出れば成功
iPhoneLiDARでスキャンした物をNeosVRに持ち込む方法

この記事では、iPhoneLiDARで現実の物体や空間をスキャンして、NeosVR内に持ち込む方法を紹介します。

実際の反映結果は、以下のツイート画像のようになります。

https://twitter.com/sushitenko/status/1416825674959003648

<h2>iPhoneLiDARアプリで現実の物体をスキャン</h2>

まずはiPhoneLiDARアプリで現実の物体や空間をスキャンします。
(以下のツイートの通り)

https://twitter.com/sushitenko/status/1415653165194645506

https://twitter.com/sushitenko/status/1414848314336370691

<h2>iPhoneLiDARアプリからOBJ形式で3Dデータをエクスポート</h2>
次にスキャンした3DデータをOBJ形式でエクスポートします。

今回はスマホアプリとして「<a href="https://poly.cam/">Polycam</a>」を使用していますが、VR空間に持ち込む3Dデータを<b>OBJ形式で出力できるアプリならなんでもOK</b>です。

iPhoneLiDARアプリに関しては、iwama@hさんの以下の記事が参考になります。

https://note.com/iwamah1/n/n58f7f0a76c74

<span style="color:red">※課金制アプリの料金は変動があるので注意</span>

ちなみにOBJ形式は、動きのない3Dデータを出力するには最適な拡張子。

https://whatext.com/ja/obj

<h2>出力したOBJをPCへ転送</h2>

iPhone内で出力したOBJをPCへ移動します。

方法は何でもいいですが、私はiCloudを利用しています。
(ファイルごと移動しやすいので)

<h2>NeosVRでPC内のOBJをインポートする</h2>
NeosVRのメニューから「ファイルブラウザー」から、出力したOBJの保存されているディレクトリを選び「〇〇.obj」をダブルクリック。

![NeosVR 2021_07_22 3_50_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/86f91a6e-f28a-12a1-6fa7-859b221090bd.png)

PCディレクトリ内のOBJファイルを読み込むと、NeosVRのワールド内に以下のメニューが表示されるので「3Dスキャン→メートル(m)→インポート実行」の順に選択。
<span style="color:red">※この読み込み設定は最適化の余地あり</span>

![NeosVR 2021_07_22 3_55_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/73bf6a27-e0a4-15df-dca7-89f50491a233.png)

![NeosVR 2021_07_22 3_58_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/434d50ba-4efd-f23f-88ba-6936bd56f0c4.png)

![NeosVR 2021_07_22 3_58_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/70d49702-09b3-8f4f-d9f6-3c8d63de5eb0.png)

これでNeosVR内へiPhoneLiDARでスキャンした物体/空間の持ち込みは完了です！

![NeosVR 2021_07_22 3_58_27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1214763/966e4d15-b932-9ae4-0171-b629556e9270.png)

なお、データ容量に関してですが、他の方と同じワールドにいても大丈夫だったので、今のところはOBJ形式で問題ないと思います。

https://twitter.com/sushitenko/status/1417162967100002305

次の記事では、今回NeosVR内に持っていったオブジェクトに当たり判定を加え、すり抜け判定をなくす方法を紹介しています。

https://qiita.com/sushitenko/items/a2dedd33954a5b7cb0eb
JavaScriptで比較的安全にeval()する

## evalって？
文字列をJavaScriptのコードとして評価してくれます。
一見便利だけど、めっちゃ危険だから通常使うことはありません。
使ったらESLintにも怒られます。

でも、外部からコードを注入できるのはとても拡張性が高いので、クローズドなBotとかの開発に使いたい場面はあります。

## eval的なやつ
`eval()`が一番有名だと思うけど、実は他にも同じようなことができる方法があります。
具体的には、グローバルオブジェクトの`Function()`と、Node.jsのVMです。

> * [eval ( )](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/eval)
* [Function ( )](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Function)
* [Node.js VM](https://nodejs.org/api/vm.html)

安全性としては、たぶん`eval() <<< Function() << Node.js VM`なんだけれど、VMはちょっと敷居が高そうだったので、この記事では`Function()`を使った方法について紹介します。

> ちなみに、npmに`safe-eval`っていうNode.js VMのラッパーがあったので、使ってみてもいいかも。
> 
> * [hacksparrow/safe-eval](https://github.com/hacksparrow/safe-eval)


## Function()の使い方

基本は`eval()`と同じです。

```js
const greeting = Function('console.log("hello.")')
greeting() // hello.
```

けど、ローカルスコープに閉じ込められてるので、`eval()`と比べるとかなり安全。
実行するコードを渡すとこんな感じ。

```js
const runCode = (code) => Function(code)()
const code = 'return new Date()'
console.log(runCode(code)) // 2021-07-21T16:41:19.389Z
```

ただし、ローカルスコープで評価されているので、グローバルに定義した関数はもちろん呼び出せない。
以下のコードはエラーになります。

```js
const greeting = (name) => `hello, ${name}.`
const runCode = (code) => Function(code)()
const code = 'return greeting("michinosuke")'
console.log(runCode(code)) // greeting is not defined
```

じゃあどうするかというと、ちょっと複雑だけど、こんな感じにします。

```js
const greeting = (name) => `hello, ${name}.`
const runCode = (code) => Function(`return (greeting) => {${code}}`)()(greeting)
const code = 'return greeting("michinosuke")'
console.log(runCode(code)) // hello, michinosuke.
```

awaitするコードを実行したいときは次のようにかきます。

```js
const runCode = (code) => Function(`return async (fetch) => {${code}}`)()(fetch)

const runCodeAndPrint = async (code) => {
  console.log(await runCode(code))
}

runCodeAndPrint(`
const html = await fetch("https://example.com/").then(res => res.text())
return html.match(/<title>.+/)[0]
`) // <title>Example Domain</title>
```

## 非同期なFunction()
一応、非同期関数もコンストラクタで生成できます。

```js
const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor
AsyncFunction('return "async hello"')().then(str => console.log(str))
```

> [AsyncFunction](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction)

## まとめ

紹介した`Function()`は、ローカルスコープで評価されるとはいえ、悪意のある人物なら容易に悪用できるので、不特定多数に公開するサービスでの使用はやめた方がいいと思います。
Moodle機械学習バックエンドのPythonモジュールのインストール

Moodleに標準的に備わっている機能である「アナリティクス」。
ルールベースの静的モデルや機械学習ベースのモデルを用いて学習者状態の推定をし、その結果に即して、教師が学習者をサポートするアクションを起こすことができる。

https://docs.moodle.org/3x/ja/%E3%82%A2%E3%83%8A%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AF%E3%82%B9

Moodleアナリティクス用の[Pythonの機械学習バックエンド](https://pypi.org/project/moodlemlbackend/#history)をインストールして利用するように設定すれば、（標準の）PHPバックエンドよりも正確かつ高速に予測できるようになる。 

https://docs.moodle.org/3x/ja/%E3%82%A2%E3%83%8A%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AF%E3%82%B9%E3%81%AE%E8%A8%AD%E5%AE%9A#.E3.83.A9.E3.83.BC.E3.83.8B.E3.83.B3.E3.82.B0.E3.82.A2.E3.83.8A.E3.83.AA.E3.83.86.E3.82.A3.E3.82.AF.E3.82.B9.E8.A8.AD.E5.AE.9A.E3.82.92.E8.A1.8C.E3.81.86

インストールするためのコマンドは以下の通り。

Ubuntu 18.04 の場合:

```sh
apt install python3-pip
pip3 install "moodlemlbackend==2.3.*"
```

CentOS 7の場合:

```sh
yum install python3-devel
pip3 install "moodlemlbackend==2.3.*"
```

Moodleと同じサーバ上で上記のようにインストールした後に、Moodle上で「[予測プロセッサ](
https://docs.moodle.org/3x/ja/%E3%82%A2%E3%83%8A%E3%83%AA%E3%83%86%E3%82%A3%E3%82%AF%E3%82%B9%E3%81%AE%E8%A8%AD%E5%AE%9A#.E3.83.A9.E3.83.BC.E3.83.8B.E3.83.B3.E3.82.B0.E3.82.A2.E3.83.8A.E3.83.AA.E3.83.86.E3.82.A3.E3.82.AF.E3.82.B9.E8.A8.AD.E5.AE.9A.E3.82.92.E8.A1.8C.E3.81.86)」として「Python予測プロセッサ」を選ぶことができるようになる。
（サイト管理 -> サーバ -> システムパスにPython3実行可能ファイルへのパスも入力する必要もある。）
NVMe とは

## 勉強前イメージ

ストレージのなにかのイメージ

## 調査

### NVMe とは

Non-Volatile Memory Express の略で、
次世代の接続規格と呼ばれるSSDをはじめとするフラッシュストレージのために最適化された `通信プロトコル` です。
従来のプロトコルであるAHCI(Advanced Host Controller Interface)はHDDに最適化されているようなもので、
SSDに最適化したものがNVMeになります。

### NVMeの特徴

- コマンド処理用のキューが増加

コマンドを処理する際のキューを最大65,536個持っており、多数の処理を同時に実行することができます。
AHCIは1個です。

- データ転送時に必要なメッセージ量の削減

従来では4KBの転送に2つメッセージが必要でしたが、
NVMeでは1つのメッセージで済むように改良され、
通信の高速化を図りました。

- ダイレクトメモリアクセスによる高速化

別ネットワークのSSDから直接データの読み書きができるようにする技術で、
従来はメモリにSSDのデータを読み込ませてから転送を行っていましたが、
ダイレクトメモリアクセスを使用することで、転送時間を短縮しました。

## 勉強後イメージ

あんまりまだストレージの規格とかわかってないけど
わかりやすく言えば、PCとデータ領域のやり取りのためのプロトコルで、
同時にいっぱいやり取りできるようになったり、ヘッダーみたいなのが減ったり
SSDに最適化するようにしたよーって規格
ってイメージ持ちました。

## 参考

- [NVMeとは？AHCIやPCIeとの違い、NVMe対応SSDの特徴を徹底解説](https://www.pro.logitec.co.jp/about_hdd/hddssd/20191129/)
- [NVMeとは？誕生の経緯や特長、NVMe採用のSSDのメリット・デメリットなどを解説](https://www.pro.logitec.co.jp/houjin/usernavigation/hddssd/20200319/)
- [NVMeについて、SSDを選ぶ際に必要な用語「M.2」や「PCIe」や「AHCI」などもあわせてご紹介](https://www.dospara.co.jp/5info/cts_str_parts_nvme)
'docker-compose'より'docker compose'を使うべき？


#調べたきっかけ
docker-compose upを行った際に、以下のメッセージが。

```
> docker-compose up
Docker Compose is now in the Docker CLI, try `docker compose up`

Google翻訳：
Docker ComposeがDockerCLIに追加されました。`docker compose up`を試してください。
```

###言われたので、試してみる

同様にDocker Composeが使用できているが、何が違うのかいまいちわからない...。

```
> docker compose up

[+] Running 4/4
 - Container hoge_db_1       Recreated                                                                                                                                     
 - Container hoge_mailhog_1  Recreated                                                                                                                                     
 - Container hoge_php_1      Recreated                                                                                                                                     
 - Container hoge_nginx_1    Recreated  
```

#バージョン

```
> docker --version
Docker version 20.10.6

> docker-compose --version
docker-compose version 1.29.1

> docker compose version
Docker Compose version 2.0.0-beta.1
```


#結論
**Docker ComposeのV2が開発中であり、V2ではCLIで'docker-compose'コマンドの機能のほとんどを引き継いだ'docker compose'コマンドが使用できる**

Ver3.2.1以降のDockerDesktopではDockerCLIとともに新しい'docker compose'コマンドが含まれているため、個別にDocker Compose V2をインストールしなくても今回のようなメッセージが出力されるようです。

>The new Compose V2, which supports the compose command as part of the Docker CLI, is now available as a beta version. Compose V2 seamlessly integrates compose functions into the Docker platform, continuing to support most of the previous docker-compose features and flags. You can test the Compose V2 today, by simply replacing the dash (-) with a space, and running docker compose, instead of docker-compose.

>**As Docker Compose V2 is in beta, we recommend that you extensively test before using it in production environments.**

>訳：DockerCLIの一部としてcomposeコマンドをサポートする新しいComposeV2が、ベータ版として利用可能になりました。Compose V2は、作成機能をDockerプラットフォームにシームレスに統合し、以前のdocker-compose機能とフラグのほとんどを引き続きサポートします。ダッシュ（-）をスペースに置き換えてdocker composeを代わりにを実行するだけで、ComposeV2をテストできます。

>**Docker Compose V2はベータ版であるため、本番環境で使用する前に徹底的にテストすることをお勧めします。**

引用元：[https://docs.docker.com/compose/cli-command/](https://docs.docker.com/compose/cli-command/)


#結局どっちを使うべきなのか
###まだdocker-composeで良い（と思う）

引用の通り、V2のdocker composeコマンドはまだベータ版であり、本番環境でいきなり使用することは推奨されていません...。

Docker Compose V2の追加機能としては

>ComposeV2はプロファイルやGPUデバイス、Appleシリコンなどをサポートします。

と、あり新規追加されるそれらの機能を利用する人/メリットが享受できる人はV2を使用するべきなのでしょう。

それがどう役に立つのかわからない・それらの機能を利用しないであろう自分のような人は、急いで乗り換える必要はないように感じます。

#おまけ

記事を書くにあたりリリースノートを見たところ、最新Verの1.29.2に以下の記載がありました。

>1.29.2
>(2021-05-10)

>upコマンド内においてdocker compose利用を促す説明を削除しました。

頑張って記事にまとめたのですが、最新VerのDocker Composeを使っていれば記事の頭にある「docker composeコマンドを試してね！」というメッセージは出なくなってしまったようです。笑
Docker React環境簡単構築

## 概要
Dockerを使って簡単にReact環境を構築する方法をご紹介します。

## 環境
- macOS Big Sur 11.4
- Docker 20.10.6
- docker-compose 1.29.1

## 構成

```
.
├ docker
│ └ node
│   └ Dockerfile
├ node
│   └ react-sample
└ docker-compose.yml
```

## 手順
今回は、`react-sample`という名前でアプリケーションが作成されます。

### 1. docker-compose.ymlの作成

他の名前が良ければ以下の`react-sample`を変更してください。

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

services:
  node:
    build: ./docker/node
    volumes:
      - ./node:/usr/src/app:cached
    command: sh -c "cd react-sample && yarn start"
    ports:
      - "3000:3000"
```

### 2. Dockerfile作成

```dockerfile
FROM node:16-alpine
WORKDIR /usr/src/app
```

### 3. Reactアプリの構築
他の名前が良ければ以下の`react-sample`を変更してください。

```sh
docker-compose run --rm node sh -c "npm install -g create-react-app && create-react-app react-sample"
```

### 4. 起動

```sh
docker-compose up -d
```

### 5. 確認
http://localhost:3000 にアクセスしてみましょう。
以下のような画面が表示されれば成功です。
`コンテナが立ち上がってから、画面表示されるまで少しラグがある場合があります。`

![スクリーンショット 2021-07-22 0.39.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/290840/acc0531d-9ad0-3d42-7283-21288747ede0.png)


## 参考
- [5分で始めるReact with Docker](https://qiita.com/2754github/items/413bdaaa90834e219dc8)
正義の星

# はじめに

認証、それは人類が相互活動するのに不可欠である、古来より受け継がれし信頼関係の礎。
時は21世紀、人類のアカウント情報管理エントロピーは無限大に膨張し、安全を期して設定した複雑なパスワードは至る所に散らばり、そのアカウント情報を忘れてしまう始末。

そんな憂いの世に一筋の光明が差したーーOAuthである。

これからはそれぞれのアプリケーションのアカウントを逐一覚えておく必要はなく、GoogleやFacebook, Twitterといったビッグ・ネームのアカウントのみ記憶しておけば良い。この程度であればよく躾けられたラブラドール・レトリバーでも覚えていられることだろう。

しかし、この規格をアプリケーションに自前で実装するのは、なかなか骨が折れる。経費が足りない。迫る納期に血眼で立ち向かうも、終わりが見えない。あゝ、愛しきBasic認証。桃源郷はかくも遠きものか。
そう、理想は理想であるから美しいのであり、現実はありとあらゆる制約が我々の行手を阻む。

誰もが憂慮する、組織のネーム・バリューを担う、認証。
そこに一つのSaaSが立ち向かった。名を、Auth0、という。

# この記事は

私はAuth0が好きだ。この世の何よりもたまらなく好きだ。私にもし娘がいたのならば、「あそこのお兄さん気立てがいいようだよ。一度お会いしてみてはどうだい？」と下手に出つつ結婚への一押しをしたいくらいには好きだ。

認証。わたしはかくかくしかじかの者である、とただ証明して、それを認めるだけのこと。
認可。君が行おうとしている行為に首を縦に振るか横に振るか、ただそれだけのこと。
それなのに、ことデジタルの世界においてそれを実践するのは非常に難しい。割り符を用意しようが、セキュアなネットワークを通過しようが、鍵をパケットに持たせようが、この世界ではその間隙をぬって攻め立てんと舌なめずりする悪しき攻撃者が跳梁跋扈している。上役からはセキュリティという見えざるものに対して大枚を叩くことへの理解は得られず、理想とするセキュアなシステムは遠のくばかり。イデア・セキュリティ。不毛なパワーポイントに残業時間を注いで、上役に再帰的説明を繰り返す、変化に数多きプロセスを要するこの構造こそ、セキュリティなのだと誤解している企業。それは私の企業だけの話だろうか？

見よ、Auth0の眩い星を。認証・認可という誰もが嫌悪感を示すそれから生まれしSaaSとは思えぬその凛とした美しさを。彼らこそが、認証・認可という不毛な八百長試合に喝を入れる、正義の星なのである。
愛しい星に焦がれる私の想い、ほんの少し耳を傾ける時間をくれないだろうか？

# ユーザを管理したい

Auth0はユーザ情報をストアするデータベースとしても使える。ブラウザは何か。メールアドレスは何か。彼らにお好きなメタデータを保持させることも可能だ。Roleを与えて、彼らの動きに制約を設けることもできる。中世のパノプティコンを彷彿とさせるこの徹底的な監視。それなのに、こんなにエレガントに見えるのは一体どういったカラクリなのだろう？

![](https://i.imgur.com/55vBVhQ.png)

# ユーザのログを管理したい

それぞれのユーザがいつログインしたか、ログアウトしたか。トークンを交換したか。それに成功したか、失敗したか。全ての情報はデフォルトでロギングされる。
![](https://i.imgur.com/Ky1IPiY.png)

それらのデータを解析したい？お望みのままに。プラグインを用いて、そのログをお好みのプラットフォームにexportもできる。CloudWatch、Azure Blob Storage、Sumo Logic。我らが正義の星は[ビッグネーム]([https://auth0.com/docs/extensions/log-export-extensions](https://auth0.com/docs/extensions/log-export-extensions))との人付き合いも怯むことなく、華麗にこなす。

# ログイン画面や確認メールをカスタマイズしたい

ログイン画面もお好みのスタイルに修正可能だ。パスワードポリシーが欲しい？何文字？何世代までの使い回しを禁止する？何の文字を必須にする？全ての望みを叶えよう。たかが割り符の規則にあれこれ思いを巡らす不毛な時間など潰えてしまえ。この正義の星に抱かれるだけで良いのだ。ユーザ作成のメールの文言。カスタムドメインの適用。メールプロバイダの選定。全ては正義の星の手中にある。FIDOやSMSなどによる多要素認証なんてことも可能だ。
![](https://i.imgur.com/rKXFslI.png)


あゝ、この圧倒的ブランディングコンシェルジュ。そつがなく、紳士的で、猛々しい。

# 認証認可をトリガにジョブを走らせたい

誰かがログインした、ログアウトした、トークンを交換した、それをトリガーに何か一仕事したい時もあるだろう。馴染みの客がログインしたら、すかさずオン・ザ・ロックを作り始める、なんてことも可能だ。

![](https://i.imgur.com/cY5Z4dG.png)


涙に暮れる貴婦人がログアウトする際は、すかさずハンケチを差し伸べよう。すべては、javascriptで書けるこのRulesで実装できる。そうだろう？ーおっと、一見さんはお断りだ。君はまだ確認メールを踏んでいない。Rulesの張り紙、ヘロインで汚れたその節穴に詰めておくんだな。

# シークレットをセキュアに管理したい

ok、そうはいってもお上は許さないだろう。彼らがあくせく物理サーバをこねくり回して作り上げたひと財産を、ユニコーンの青二歳に委ねたくないと喚くのもごもっともだ。ましてや、クレデンシャル情報をそこにストアするなど尚更。大丈夫、Auth0にはシークレットを保管する機能もある。ガチガチに窮屈なオンプレミスで苦しげに息をするあなたのシークレットを、暗号化の海に横たえ、愛の羽衣で休息する暇を与えようではないか。
何、まだセキュアが足りないって？オーケイ、ボット検知、IP blacklist、ブルートフォース遮断、多要素認証。気は済んだかい？

# 星

IDaaSなんてしょうもない名前をつけるのはやめよう。Auth0は星だ。性悪説で澱んだ認証認可の世界にまたたく、正義の星だ。

![](https://i.imgur.com/Gyxksd5.png)
Visual Basicが30周年を迎える(Happy 30th Birthday, VB!)

# はじめに
2021年05月20日にVisual Basicが30周年を迎えました。2ヶ月くらい過ぎてから書いているのはご愛嬌！
Visual Basicは、1991年のバージョン1.0の導入から今日のVisual Basic .NETに至るまで、MicrosoftおよびWindows開発者にとって最も重要なプログラミング言語です。

25周年の際には.NET Teamが[ブログ](https://devblogs.microsoft.com/dotnet/happy-25th-birthday-vb/)を書いたことで幾つか記事があがりましたが、残念ながら30周年を祝うのはこの記事だけになります。

【2021/12/6追記】
Twitterのハッシュタグに「#VisualBasicIs30」があることを見つけました。
https://twitter.com/hashtag/VisualBasicIs30?src=hashtag_click

# リリース時期が近い開発言語

|年|月|開発言語|備考|
|:--|:--:|:--|:--|
|1987|12|Perl 1.0| |
|1990|  |Haskell 1.0| |
|1991|5|Visual Basic 1.0|初期のコードネームは"Ruby"、日本では未発売|
|1992|12|Microsoft Access 1.0| |
|1993|7|Lua 1.0| |
|    | |Visual Basic for Applications|日本では1994年2月 Excel 5.0から実装|
|1994|12|Python 1.0| |
|1995|6|PHP 1.0| |
|    |6|Ruby 1.0| |
|    |9|Delphi 1.0| |
|    | |R 1.0| |
|    |12|JavaScript 1.0|名前の変遷 Mocha→LiveScript→JavaScript|
|    |12|Ruby 1.0| |
|1996|1|Java 1.0| |
|1996|8|VBScript 1.0| |
|2000|8|ActionScript 1.0| |
|2002|2|Visual Basic.NET| |
|    |2|C# 1.0| |

[Fortranから最新言語まで、約2500種類のプログラミング言語の系図 2007年 - Gigazine](https://gigazine.net/news/20070126_computer_languages_history/)

# Visual Basic誕生

ビル・ゲイツ(36歳当時)がVisual Basic 1.0を2分10秒あたりから3分間ほどカレンダーを使用した説明をしています。

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

アラン・クーパーは、「Visual Basicの父」として広く認知されている。
Visual Basic(当時のコードネーム Ruby)は、アラン・クーパーがビル・ゲイツに実演し、Microsoftが購入したのが始まり。

https://qiita.com/yaju/items/eb2ef4648c73bdd5ace1

Visual Basicについてもっと知りたいですか？ 1988年3月6日〜

http://www.johnsmiley.com/visualbasic/vbhistory.htm

https://qiita.com/yaju/items/a932d5975b4d5163a3c7

# 25周年
25周年時の2016年05月20日には、.NET Teamがブログ記事を公開したことで他に幾つかの記事ができました。

* [Happy 25th Birthday, VB! - .NET Team](https://devblogs.microsoft.com/dotnet/happy-25th-birthday-vb/)
* [Visual Basicが25周年を迎える - スラド](https://developers.srad.jp/story/16/05/21/1943233/)
* [Visual Basic at 25: Microsoft looks back and ahead](https://www.infoworld.com/article/3074098/visual-basic-at-25-microsoft-looks-back-and-ahead.html)

# 5年の変化
2016年から2021年で、.NET関連まわりはだいぶ変わりました。

VS 2010の開発に当たり各言語チームを統合し、C＃とVBを共進化戦略をとり格差がなくなるようにしました。しかし、Microsoftは2017年に方針転換、当初のC＃/VB共同開発戦略が終了したと発表、2020年3月11日にMicrosoftの「The Visual Basic Team」の[ブログ](https://devblogs.microsoft.com/vbteam/visual-basic-support-planned-for-net-5-0/)がに久しぶりに更新され、「今後、Visual Basicを言語として進化させる計画はない」ことを公式に表明した。

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

https://www.thurrott.com/dev/232268/microsoft-plots-the-end-of-visual-basic

2014年にスティーブ・バルマーの退任後、サティア・ナデラ氏が歴代三代目のCEOになりました。
Microsoftはなにからなにまで24時間自社製品をユーザーに強制する会社であることを止め、マルチ・プラットフォームで広い範囲のパートナーと協力するようになった。軸足を完全に Azure、つまりサーバーサイドに移していて、クライアントサイドのプラットフォーム(Windows)で覇権を取ることはあきらめたように見えます。

Microsoftは、2016年以降クロスプラットフォームとオープンソース化の推進をするようになっていきます。

* 2016年2月にはXamarinを買収
* 2016年6月には.NET Core 1.0をリリース
* 2016年8月にはWSL(Windows Subsystem for Linux)をリリース
* SQL Server 2017からはLinux版をリリース
* 2018年6月にはGitHubを買収

# 最後に
2016年時の25周年の頃はまだVisual BasicはC#とは協調戦略だったんですよね、2017年の方針転換がヤバかった。
がんばれ、Visual Basic！
C#のValueTask<T>構造体というものを知った。

# はじめに
現在参画している案件にて、ValueTask\<T>という型を使用しているのを見て「何なのだこれは！？」と思い勉強したので理解した範囲でまとめようと思います。

## 参照型のTaskに対してValueTask\<T>は値型
もともとC#で非同期処理といえばTaskを使用するのが一般的なイメージでしたが、例えば以下のような処理を行うとします。

```csharp
public async Task<int> TestAsync(bool isHeavy)
{
    //基本的にほぼほぼisHeavyはfalseとなる
    if (isHeavy)
    {
        //非同期処理
        await xxxxAsync();
        return 0;
    }
    else
    {
        return 0;
    }
}
```
この処理ではほぼほぼisHeavyがtrueになりません。
そのため無駄にTaskクラスが生成されてしまっています。これくらいの規模ならばあまり気にならないかもしれませんが、膨大なソースコードになればなるほどこういうコツコツとしたところでパフォーマンスが悪くなっていきます（オーバーヘッド）。
ここへ値型であるValueTask構造体を利用することで必要のないインスタンスを生成する必要がなくなります。

## ValueTask\<T>の注意点
ValueTask<T>構造体は内部でTaskと値型Tを抱えています。
よって毎回非同期処理を行う場合（上記のコードでいうとifの中に高確率で入ってくる場合）はただただTask + Tの構造体が作られる（前述のTaskクラスが作られる分よりもT分大きい）ので余計にパフォーマンスが悪くなってしまいます。

:::note info 
C#7.0のIValueTaskSource<T>で改善されたらしいのでそこはまたいずれ調べてみよう～
:::
Kintoneのトップページのポータルをタブ化しオリジナルのポータルとアプリ一覧を表示する

## きっかけ
* 昨日[こんな記事](https://qiita.com/ricorico/items/da106730355450b35116)を書いたのに、やっぱり新しいアプリを作るごとにポータル管理アプリをメンテするのはしんどいなと思い、**ポータルを開くごとに最新のアプリ一覧を取得してスペースごとに表示する**JSを作ろうと決意しました。

https://qiita.com/ricorico/items/da106730355450b35116

* 上記プラス、アプリが増えてきて自分が使いたいアプリを選ぶときにポータルの「さらにに表示」を何回か押して開いて、ってやるのがちょっとしんどくなってきたのでアプリ一覧がほしいなと思いました。


## 作ったもの

https://github.com/erikoono/kintone-portal-tab-custom/blob/master/Portal/Portal.js

## 使い方
* 使い方はREADME.mdにも書きましたが、以下のとおりです。

1. ソース（``Portal.js``と``Portal.css``）をダウンロードする
1. ``Portal.js``の{サブドメイン名}をご自身の適用したいものに変える
1. kintoneのシステム管理からこの2ファイルをアップロードする

## 注意
* WindowsのChromeのみでしか動作確認できていません。
* 自分の端末でしか見ていないので、権限が自分と異なる人が見たときにどうなるか未確認です。
* 今後いろいろ確認しておかしなところがあったら随時直していきます。

## さいごに
* CSSでいい感じに詰めて表示するのにちょっと苦労しました。
* なお、順番を自由に入れ替える、ということはできません。そういったことをやりたい人はポータル管理アプリを別で作ってカスタマイズするという方法を選んだほうが良いと思います。
* Kintone Portal Designerを使ったカスタマイズはやはり自由度が低いので、テンプレートをそのまま使う人にはおすすめですが、テンプレートを変えて使いたいっていう私のような人はJSカスタマイズする方が良いんだろうなと思います。
Azure Static Web Appsを使ってみて感じた便利な点

# はじめに

本記事ではAzure初心者がAzure Static Web Appsを使ってみて感じた便利な点をまとめます。

# そもそもAzure Static Web Appsとは

サーバレスのWebアプリケーションのホスティングを支援するサービスのことです。
詳細は[こちら](https://azure.microsoft.com/ja-jp/services/app-service/static/)

# どんな時に有用なのか

以下の項目に当てはまる場合には、Azure Static Web Appsを利用するメリットが大きいと思います。

- SPA(Single Page Application)をホスティングしたい。
- SPAから利用されるAPIも作成したい。

Azure Static Web Appsでは、GitHubリポジトリにSPAに必要なHTMLページ+JavaScriptアプリケーションとAPI(Azure Functionsで作成)を格納することで、APIサーバー構築+Webページホスティングを一括で行えます。

利用方法は[こちら](https://docs.microsoft.com/ja-jp/learn/paths/azure-static-web-apps/)のMSLearnのコンテンツを参照ください。

# 使ってみて感じた便利な点

## Azure Static Web Apps CLIを使うことでローカルでの動作確認が簡単にできる

[こちら](https://github.com/Azure/static-web-apps-cli)のAzure Static Web Apps CLIを利用することでローカル環境でSPAをデプロイして、APIサーバーも立ち上げてローカルで動作確認ができます。
[こちら](https://github.com/Azure/static-web-apps-cli#start-api-server-manually)の手順通りVisualStudioCodeのAzure Functions Core Tools拡張機能を利用してAPIサーバーをローカルに立ち上げ、そのAPIサーバーのURLとSPAのパスを指定することで本番環境と同様にローカルで動作確認ができます。
具体的には以下のような手順になります。

### APIサーバーの起動

作成したアプリケーション(SPA)のパスは`C:\SampleApplication\`であり、`C:\SampleApplication\api\`にC#で作成したAzure Functionsの関数(GetOutputCount関数)を格納しているとします。
以下のコマンドをVSCodeのターミナルで実行することでAPIサーバーをローカルで動作させることができます。

```
C:\SampleApplication\api> func host start --dotnet
```

上記のコマンド実行後、ターミナル上にAPIサーバーのURLが以下のように表示されます。このURLを後で使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452292/31675a32-f3c2-7d20-72dc-ce71d5a2e274.png)

### SPAの起動

SPAのフロントエンドはReactで作られており、ビルド結果は`C:\SampleApplication\build\`に格納されているとします。
以下のコマンドをVSCodeのターミナルで実行することで前節の手順で起動したAPIサーバーを使って本番環境と同じようにアプリケーションを動作させることができます。

```
C:\SampleApplication\build> swa start ./ --api http://localhost:7071
```

上記のコマンド実行後、ターミナル上にアプリケーションのURLが以下のように表示されるので、Webブラウザから開くことで動作確認が可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452292/5ad05916-ef9b-3730-02ef-0bbd5306d790.png)


## プルリクエストごとに動作確認のための環境が用意される

作成したStatic Web AppをAzureポータルで開き、環境メニューを選択すると以下のような画面が表示されます。この画面の中のステージングにはプルリクエストごとに動作確認用の環境が用意されており、プルリクエスト承認前にコードレベルのレビューだけでなく動作確認が可能になっています。
以下の赤枠をクリックすることでそのプルリクエストのコードをデプロイした場合の動作を検証できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452292/72cb71d5-9142-d7da-6d5d-6f6c98a2c5ec.png)

# まとめ

Azure Static Web Appは以下の項目に当てはまる人がメリットを享受しやすいと思いました。

- SPAをホスティングしたい。
- SPAから利用されるAPIも作成したい。

個人的に以下の2点は便利であると感じました。

- Azure Static Web Apps CLIを使うことでローカルでの動作確認が簡単にできる
- プルリクエストごとに動作確認のための環境が用意される
MacのVS CodeでDvorak–QWERTY ⌘配列が機能しない問題

# 概略

MacでDvorak–QWERTY ⌘配列を使用していましたが、VS Codeでは⌘キーを押している間もDvorak配列のままになってしまう問題が発生しました。この問題はVS Codeのsettings.jsonを書き換えることで解決しました。この記事ではDvorak配列についての簡単な説明と、問題の解決方法を紹介します。解決方法に関しては次のGitHubのissuesが主に参考になりました。

https://github.com/microsoft/vscode/issues/23964

# 環境

macOS Catalina 10.15.7
VS Code 1.58.2

# キー配列について

## Dvorak配列とは

Dvorak配列とは英語でよく現れる文字が打ちやすい位置になるようにキーが配置されたキーボード配列です。例えば左のホームポジションには左から a, o, e, u, i の順に母音のキーが、右のホームポジションには左から d, h, t, n, s と並んでいます。Wikipediaによれば、文章での出現頻度と辞書の単語での出現頻度とで値に違いはありますが、文章での子音の出現頻度に注目すると大きい順に

1. T - 9.1%
1. N - 6.7%
1. S - 6.3%
1. H - 6.1%
1. R - 6.0%
1. D - 4.3%

となっています。また母音は一単語に必ず一度出現するので、よく使われるアルファベットが一番打ちやすい位置に配置されていることが分かります。このことから、Dvorak配列は英語のタイピングをスムーズにできることが分かります。

https://en.wikipedia.org/wiki/Letter_frequency

Macでは特別なソフトを入れずにキーボード配列をDvorakに設定できます。変更方法はApple公式サイトをご参照ください。

https://support.apple.com/ja-jp/guide/mac-help/mh27976/mac

## Dvorak–QWERTY ⌘配列とは

上で述べたように、Dvorak配列には英語のタイピングをスムーズにするというメリットがありますが、一方でショートカットが使いにくくなるというデメリットもあります。通常のQWERTY配列では取り消し、カット、コピー、ペースト（⌘ + z, x, c, v）など、よく使うショートカットが左手側に集まっています。そのため文章に限らず編集作業をする際に、右手でマウスを操作しながら、左手で ⌘（Commandキー）を押しながら z, x, c, v といったショートカットキーを押せます。しかしながらこれらのキーはDvorak配列では全て右側に散らばってしまい、押しにくい位置に配置されています。

この問題を解消するのがDvorak–QWERTY ⌘配列です。Dvorak–QWERTY ⌘配列とは通常時はDvorak配列であり、⌘を押している間だけはQWERTY配列になるというキーボード配列です。つまりDvorak–QWERTY ⌘配列とは英語のタイピングのしやすさはそのままに、QWERTY配列のショートカットも利用できるようにしたキーボード配列と言えます。

MacでのDvorak–QWERTY ⌘配列の設定方法は前記のApple公式ページをご参考ください。

https://support.apple.com/ja-jp/guide/mac-help/mh27976/mac

# 発生した問題

私のMac（Version: macOS Catalina 10.15.7）上では問題なくDvorak–QWERTY ⌘配列が機能し、平常時はDvorak配列で、⌘押下時はQWERTY配列で利用出来ていました。しかしVS Code（Version:  1.58.2）上で論文を書こうとしたところ、⌘を押してもDvorak配列のままになってしまうという問題に直面しました。

# 解決方法

調べたところ、この問題の解決には次の2つの方法があるようです。

- VS Codeのバージョンを1.10に下げる
- setting.jsonに `"keyboard.dispatch": "keyCode"` を加筆する

参考ページ（概略で提示したリンクと同一）

https://github.com/microsoft/vscode/issues/23964

今回、私は後者のsetting.jsonへの加筆で問題が解決しました。前者の方法は試していないのでご了承ください。settings.jsonの開き方は次のQiitaの記事などが参考になります。

https://qiita.com/y-w/items/614843b259c04bb91495

上記Qiita記事に掲載されている方法以外にsettings.jsonを開く手順として、次のような方法もあります。

- ウィンドウ左のメニューバー一番下の歯車のアイコンを選択＞設定をクリック＞検索窓に`setting`と入力＞候補中に出る`settings.jsonを編集する`をクリック
- Command+Shift+Pを入力＞検索窓に`settings.json`と入力＞`基本設定： 設定(JSON)を開く`を選択（`既定の設定(JSON)を開く`ではない）

## 入力例

JSONファイルの書き方に関しては次のサイトなどを参考にしてください。

https://products.sint.co.jp/topsic/blog/json

例えば元のsetting.jsonファイルが

```
{
    “key1” : “value1”,
    “key2” : “value2”
}
```

となっていた場合、ここに加筆すると

```
{
    “key1” : “value1”,
    “key2” : “value2”,
    "keyboard.dispatch": "keyCode"
}
```

となります。
Postman で「エンジニア・プログラマにしか使えないSNS」をビジュアライズすると楽しかった話

![web.postman.co_workspace_My-Workspace_3ddf3093-3059-40b1-88e6-fa18fc7be2a7_request_16745458-80d1136d-2e0a-4543-bae2-e389e9f39786(Desktop).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248832/f60300f6-1314-c77f-1974-ffedb08e979e.png)
@HawkClaws さんの [エンジニア・プログラマにしか使えないSNS](https://qiita.com/HawkClaws/items/599d7666f55e79ef7f56) （ versatileapi ）の API を Postman から使ってみました。

実は Postman に触るのは初めてだったんですが、とても使いやすい上に Visualizers というデータをビジュアライズする機能が面白かったので、ついつい遅くまで遊んでしまいました。フロントエンドエンジニアな方にはオススメです。仕組みも簡単で、任意の HTML を iframe 内のサンドボックスで走らせる、ただそれだけ。 script タグ内で Postman の API を呼び出し、 Handlebars のテンプレート構文で出力、仕上げに style タグでスタイライズすれば、即席のクライアントが出来上がる、という感じです（見るだけですけど）。
で、下記が私の作った versatileapi 用の Visualizers コードです。よろしければどうぞ。ブラックリストと返信先のテキストをプレビューする機能が売りです。が、使い方の説明などはしません。何と言っても「エンジニア・プログラマにしか使えないSNS」なので…。

```html
const template = `
<style>
*, * > * {
    box-sizing: border-box;
    line-height: 1;
    margin: 0;
    padding: 0;
}
td, th {
    padding: 0.5em !important;
}
th {
    text-align: center;
}
.sns__updated-at,
.sns__user-id,
.sns__text-id {
    color: #c0c0c0;
    white-space: nowrap;
}
.sns__text__user-id {
    color: #0080f0;
    margin-bottom: 0.5em;
}
.sns__text__text-id {
    color: #008000;
    margin-bottom: 0.5em;
}
.sns__text__reply {
    background-color: rgba(0, 0, 0, 0.125);
    border: 1px solid #c0c0c0;
    border-radius: 0.5em;
    color: #606060;
    font-style: italic;
    line-height: 1.375;
    margin-bottom: 0.5em;
    padding: 0.5em 1rem;
    white-space: pre-wrap;
    word-break: break-all;
}
.sns__text__body {
    line-height: 1.375;
    white-space: pre-wrap;
    word-break: break-all;
}
</style>
<table>
    <thead>
      <tr>
          <th>Updated at</th>
          <th>User ID</th>
          <th>Text ID</th>
      </tr>
    </thead>
    <tbody>
      {{#each response}}
      <tr>
          <td class="sns__updated-at">{{updatedAt}}</td>
          <td class="sns__user-id">{{_user_id}}</td>
          <td class="sns__text-id">{{id}}</td>
      </tr>
      <tr>
          <td colspan="3">
            {{#if in_reply_to_user_id}}
            <div class="sns__text__user-id">@{{in_reply_to_user_id}}</div>
            {{/if}}
            {{#if in_reply_to_text_id}}
            <div class="sns__text__text-id">&gt; {{in_reply_to_text_id}}</div>
            {{#if reply}}
            <div class="sns__text__reply">{{reply.text}}</div>
            {{/if}}
            {{/if}}
            <div class="sns__text__body">{{text}}</div>
          </td>
      </tr>
      {{/each}}
    </tbody>
</table>
`;

const blacklist = [
    'ARASHI_NO_USER_ID'
];

let response = pm.response.json()

response = response.filter((item) => !blacklist.includes(item._user_id))

response.forEach((item) => {
    const date = new Date(item._updated_at)
    item.updatedAt = date.toLocaleString()
})

response.forEach((item) => {
    if (item.in_reply_to_text_id) {
        item.reply = response.find((reply) => reply.id === item.in_reply_to_text_id)
    }
})

pm.visualizer.set(template, { response })
```

なお `orderBy` パラメータを指定している想定です。
ちなみに同じアプローチで「例のエンドポイント」もビジュアライズできます。
残プロ　第-49回　~PythonでWAVファイル再生~

# pyaudioを使う

pythonにはwavファイルを扱うwaveライブラリが標準で搭載されています．しかし，再生する関数は提供されていないため自分で用意する必要が有ります．

今回はpyaudioを使用してwavファイルを再生します．
pyaudioのインストール方法については[この記事](https://qiita.com/sugi-juku/items/c92f8f170a6b455e15f2)を参考にしてください．python3.7以降ではpipインストール時にエラーが発生します．

~~~ python:PlayWav.py
import wave
import pyaudio

def main():
    wf = wave.open('sample.wav', mode='rb')
    p = pyaudio.PyAudio()
    stream = p.open(
        format=p.get_format_from_width(wf.getsampwidth()),
        channels=wf.getnchannels(),
        rate=wf.getframerate(),
        output=True) 
    chunk = 1024 
    wf.rewind() 
    buf = wf.readframes(chunk)
    while buf:
        stream.write(buf)
        buf = wf.readframes(chunk)
    stream.close()
    p.terminate()


if __name__ == '__main__':
    main()
~~~