OmniAICreator/Qiita-1.07M huggingface dataset:
typescript-eslintのban-ts-commentルールについて

## はじめに
この記事では[typescript-eslint](https://typescript-eslint.io/)のルールのうち`ban-ts-comment`について解説します。
typescript-eslintの他のルールについても別記事で解説し、最終的にReact開発を行うにあたって最適なルール設定を構築することを目的としています。

## ルールについて
[`ban-ts-comment`](https://typescript-eslint.io/rules/ban-ts-comment)はTypeScriptが提供するコンパイルエラーの抑制などのコメントに対する制限を行うルールです。`"plugin:@typescript-eslint/recommended"`で有効になります。
対象のコメントは4種類あります。
1つ目は`@ts-expect-error`です。指定した箇所のTypeScriptのコンパイルエラーを抑制し、コンパイルエラーがない場合にコメントがある場合はエラーを発生させるコメントです。
```ts
// 引数を全て足し合わせる関数
const sum = (...args: number[]): number => {
  return args.reduce((sum, arg) => {
    return sum + arg
  }, 0);
};

// @ts-expect-error: エラーが抑制される
sum(1, 2, '3');

// @ts-expect-error: 型が正しいのでエラーが発生する
sum(1, 2, 3);
```
前者は`number`型を期待する箇所に`string`が代入されることによるコンパイルエラーが発生するはずですが、`@ts-expect-error`によってエラーが抑制されます。一方後者は正しく`number`を代入しているのでコンパイルエラーは生じませんが、`@ts-expect-error`とコメントしているので`Unused '@ts-expect-error' directive.`とエラーが発生します。`directive`というのはこのようなエラーを抑制するコメントのことを指します。

2つ目は`@ts-ignore`です。`@ts-expect-error`からコンパイルエラーが生じなかった時にエラーを出す機能がないものです。
```ts
const sum = (...args: number[]): number => {
  return args.reduce((sum, arg) => {
    return sum + arg
  }, 0);
};

// @ts-ignore
sum(1, 2, '3');

// @ts-ignore
sum(1, 2, 3);
```
`@ts-expect-error`とは異なり、どちらの呼び出しもエラーが発生しません。

3つ目は`@ts-check`です。JavaScriptで書かれたファイルに対してTypeScriptのような型チェックをJSDocをもとに行わせるコメントです。
4つ目は`@ts-nocheck`です。`@ts-check`によってファイル全体や、プロジェクト全体で型チェックが行われているときに、特定の箇所だけ型チェックを行わないようにするコメントです。

例としても利用しましたが、それらのコメントに対して`@ts-expect-error: エラーが抑制される`のようにコメントを有効にしたことに対する説明を記述できます。

このルールはこのようなTypeScriptが提供するコメントの利用の可否や説明の記述の可否、正規表現で説明に対する制約を作れます。そしてそれは各コメントに対して設定できます。
デフォルトのオプションは以下のようになっています。
```json
{
  "ts-expect-error": "allow-with-description",
  "ts-ignore": true,
  "ts-nocheck": true,
  "ts-check": false,
  "minimumDescriptionLength": 3
}
```
この設定では`@ts-expect-error`は説明を添えた場合に利用することが可能に、`@ts-ignore`と`@ts-check`は利用が可能に、`@ts-check`は利用が不可能に、そして全ての説明は`minimumDescriptionLength`によって最低でも3文字以上書く必要があります。
デフォルトの設定にはありませんが、以下のようにすることで説明の表現を正規表現で指定することができます。
```json
"ts-expect-error": {
  "descriptionFormat": "^: TS\\d+ because .+$"
}
```
この場合は下のように正規表現通りに書かない場合にルール違反となります。
```ts
// 正規表現に則っているのでエラーが出ない
// @ts-expect-error: TS1234 because the library definition is wrong

// 正規表現に則っていないのでエラーが出る
// @ts-expect-error: the library definition is wrong
```

## ルールの採用について
このルールによって利用できるコメントのうち`@ts-check`と`@ts-nocheck`はTypeScriptを利用する場合は不要なので無駄な利用を避けるために無効にしたいです。
また、他のコメントも最後の手段であり型安全性を損ねるので極力使いたく無いです。しかし、ライブラリの都合で`@ts-expect-error`か`@ts-ignore`は使わざるを得ない場合があります。そのため、どちらか片方はコメントで理由を書くことを条件に利用を許可します。`@ts-expect-error`はそのライブラリの都合が解決した場合にエラーが発生してコメントを取り除けることを知らせてくれる恩恵があると考えられるので`@ts-expect-error`に限って有効にしたいです。

つまりこのようにルールを作ります。
```json
"@typescript-eslint/ban-ts-comment": [
  "error",
  {
    "ts-expect-error": "allow-with-description",
    "ts-ignore": false,
    "ts-nocheck": false,
    "ts-check": false,
  }
]
```
PyTorchをArch Linuxで動かすのにCUDAのバージョンを固定してインストールした方法

Arch LinuxでPyTorchのCUDAの依存関係を解決したときのメモ。

PyTorch 2.0.0で使えるCUDAはversion 11だが、pacmanでインストールされるCUDAのversionは12になってしまっている。
CUDAのバージョンを11で固定しておく方法をメモっておく。

下記から、CUDA11と対応するCUDNN, cuda-toolsを入手する。

https://archive.archlinux.org/packages/c/

CUDNNの対応するバージョンは、NVIDIAの下記ページから調べる。

https://docs.nvidia.com/deeplearning/cudnn/support-matrix/index.html

これらは依存関係を無視してインストールするので-Uddオプションを指定して、pacmanでインストールする。

```shell
$ pacman -Udd cuda-11.8.0-1-x86_64.pkg.tar.zst
$ pacman -Udd cudnn-8.9.0.131-1-x86_64.pkg.tar.zst
$ pacman -Udd cuda-tools-11.8.0-1-x86_64.pkg.tar.zst
```
NVIDIAのデバイスドライバをNVIDIAから入手してインストールする。

https://www.nvidia.com/download/index.aspx

```shell
$ bash NVIDIA-Linux-x86_64-xxx.xxx.xx.run
```

/etc/pacman.confを編集して、これらのパッケージはアップデート時に無視するようにする。
```
IgnorePkg = cuda cudnn nvidia cuda-tools
```

以上で、cudaのバージョンを維持できる。

また、Stanford Alpaca LoRAをトレーニングするのに、TensorRTもインストールする必要があった。
こちらは、NVIDAからtar.gz版をダウンロードして、適当なディレクトリに解凍した後、LD_LIBRARY_PATHを通してやればよかった。

```shell
export LD_LIBRARY_PATH=$HOME/TensorRT-x.x.x.xx/lib:$LD_LIBRARY_PATH
```
Unityのコライダー（Gizmo）が表示されない時の対処法

【症状】ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
コライダー（黄色い球）を表示させたい↓↓
![Desktop Screenshot 2023.05.02 - 12.17.45.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326415/898bb016-3291-1ff3-39bd-71c2f19a42ce.png)

しかし表示されない↓↓
![Desktop Screenshot 2023.05.02 - 12.17.55.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326415/b7e91284-8134-7b7e-d0f8-9047baa3d21c.png)


【対処法】ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
![Desktop Screenshot 2023.05.02 - 12.17.55.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326415/6ca031a6-d209-2b7d-3e8c-4d6b14e2ca9a.png)
↑↑画像の赤矢印「Gizmos」ボタンをクリックすればOK

![Desktop Screenshot 2023.05.02 - 12.17.45.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326415/f064a411-9dec-2665-5504-38203056e1a0.png)
無事表示されました！
AZ-900資格の取得体験

# 概要
(AZ-900取得時点：2023/04)
AZ-900とはクラウドの概念、 Azure サービス、 Azure ワークロード、 Azure のセキュリティとプライバシー、 Azure の価格とサポートに関する知識を証明する機会です。

今回は英語で試験を受け、AZ-900資格を取得できました。
アプリケーションを構築するため、Azureのサービスを使っていますが、必要な部分だけを使うことがあります。全体的にAzureはどういうサービスがあるのか、今のアプリケーションにはどういう機能/サービスを一緒に使ったら、もっと使いやすくなるのかわからないです。
そのため、Azureの全体像を勉強し、ついでにAZ-900を取得しました。

# この記事を読む対象の方
- AZ-900を取得したい方
- Azure知識の全体像を勉強したい方

# 資格取得する必要があるか

個人的な意見は、資格取得の申し込む費用はあまり気にしていない方なら、ちょうど勉強したので、ついでに取得するのは良いと思います。

# 準備

## 勉強方法

まず、マイクロソフトのトレーニングサイトに[試験 AZ-900: Microsoft Azure の基礎](https://learn.microsoft.com/ja-jp/certifications/exams/az-900/)の「マイペースで進められる」の内容を一度通り読み終わって、模擬試験をしてみて、間違えたところを深く勉強したら良いと思います。

全体的にちょっと教科書を勉強する感じがありますが、実際にAzure Portalを操作しながら、もっと覚えやすいと思います。

一番重要なのは、あるサービスはどういう時に使うのか、どういう問題を解決できるのかです。概念を理解できたら、実際試験は難しくないと思います。

例えば、
- オンサイトとパブリッククラウドがある場合、インフラを管理しやすいため、どういうサービスを使えますか。
- リソースのコストと予算管理ため、どういうものを使えば、管理しやすくなりますか。

## 勉強時間

マイクロソフトのトレーニングサイトに各項目の勉強時間の目安がありますが、自分は30時間ぐらいかかった気がします。実際20時間は十分かと思います。
したがって、実際の勉強と模擬試験の合計時間は目安の4倍ぐらいでした。

|項目|勉強時間の目安|出題割合|
|---|---|---|
|Describe cloud concepts|0hr 52mins|25–30%|
|Describe Azure architecture and services|3hr 23mins|35–40%|
|Describe Azure management and governance|1hr 50mins|30–35%|
|合計|6hr 5mins|

## 模擬試験

まずは[AZ-900: Microsoft Azure Fundamentals Sample Questions](https://query.prod.cms.rt.microsoft.com/cms/api/am/binary/RWSRk3)で試験にある質問の種類を確認してから、模擬試験を行った方が良いと思います

私が受けた模擬試験はPractice TestとMeasureUpです。

難易度：MeasureUp > 実際試験 >> Practice Test

Practice Testは実際試験より簡単なので、Practice Testが合格しても油断しない方が良いと思います。

[Microsoft Practice Test AZ-900](https://learn.microsoft.com/en-us/certifications/exams/az-900/practice/assessment?assessment-type=practice&assessmentId=23)：無料
[MeasureUp](https://www.measureup.com/microsoft-practice-test-az-900-microsoft-azure-fundamentals.html)：有料

# 結論

あくまで、基礎の資格なので、緊張しすぎる必要はありません。試験の中に、難しい質問があっても、試験の時間は余裕があるので、考える時間があると思います。

# Ref
- https://learn.microsoft.com/ja-jp/certifications/exams/az-900/
- https://learn.microsoft.com/ja-jp/certifications/resources/study-guides/az-900
Array.prototype.filter() について

メモです。

[Array.prototype.filter()](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)

>filter() メソッドは、この配列の中から、提供された関数で実装されたテストに合格した要素のみを抽出したシャローコピーを作成します。

# 環境

```
node --version
v14.21.3
```

# 検証

配列の各要素に JSON が含まれれるものの中から **errorMessage** という key が含まれないもの、含まれるものを取得する。

```
const array = [
    {
        name: 'Bob',
        age: 20
    },
    {
        name: 'Ken',
        age: 30
    },
    {
        errorMessage: "hogefuga"
    }
]

// JSON はいずれの方法でもアクセスできる
// https://developer.mozilla.org/ja/docs/Learn/JavaScript/Objects/JSON
console.log(array[2]['errorMessage']);
console.log(array[2].errorMessage);

// view bob
console.log(array.filter(result => result['errorMessage'] === undefined));

// view error
console.log(array.filter(result => result['errorMessage'] !== undefined));
```

実行してみる

```
hogefuga
hogefuga
[ { name: 'Bob', age: 20 }, { name: 'Ken', age: 30 } ]
[ { errorMessage: 'hogefuga' } ]
```
色々な移行サービス

# AWS DateSync
**利用可能サービス：S3、FSx、EFS**
オンプレミスのストレージとS3またはEFSの間で大量のデータをオンラインで移動するために使用することができる。コピージョブのスクリプト作成、転送のスケジューリングと監視、データの検証、ネットワーク利用の最適化などのタスクを排除または自動処理する。

# AWS DMS(AWS Database Migration Service)
**利用可能サービス：データベース関連**
データベースを短期間で安全に移行でき、さらに移行期間中でもソースデータベース間においてデータ移行が可能。DMSへのデータ移行はすべて無料。ダウンタイムをゼロ、データ損失を最小限に抑えて移行できる

+ **環境構築の流れ**
**①レプリケーションインスタンスの作成**
**②エンドポイントの作成**
**③タスクを作成**
**④データベース移行完了を確認**

![DMS](https://www.infinitypp.com/wp-content/uploads/2018/06/aws-database-migration-service-tutorial-945x495.png)



### AWS SCT(Schema Conversion Tool)
データベース移行支援ツール。データベースエンジン間で既存のデータベーススキーマを変換することができる。変換されたスキーマはEC2インスタンスでDBと共に使用するか、S3バケットでデータとして保存することができる



::: note info
**・データベーススキーマとは？**
データベース内で使用されるデータの構造や組織を定義するための設計図や設計規則のこと。スキーマは、データベースのテーブル、列、関係、インデックス、ビューなど、データの論理的な構造と関係を定義する
:::


# AWS Data Pipeline
**利用可能サービス：S3,RDS,DynamoDB,EMRなど
データの移動と変換を自動化するために使用できるwebサービス。データ駆動型のワークフローを定義して、タスクの正常な官僚をトリガーにして、データ変換と送信タスクを実行できる。

![Data Pipeline](https://docs.aws.amazon.com/images/datapipeline/latest/DeveloperGuide/images/dp-how-dp-works-v2.png)



# AWS MGN(Application Migration Service)
アプリケーションとサーバーの移行を支援するサービス。オンプレミスにある物理インフラ、仮想インフラ及びAzureなどの他のクラウドサービスにあるサーバーや仮想マシンのサーバーソフトウェアを変換して、移行を自動化する。

::: note info
AWS Server Migration Serviceというサービスが以前まで利用されていたが、2022年3月31日に廃止となっている
:::

# AWS ADS(Application Discovery Servise)
オンプレミスデータセンターに関する情報を収集することにより、エンタープライズのお客様向けに移行プロジェクト計画を支援する。


# AWS Migration Hub
複数のAWSおよびパートナーのソリューションにまたがるアプリケーション移行の進捗状況を追跡するための情報を1ヶ所に集約したダッシュボードを提供する



# VM Import/Export
**利用可能サービス：EC2**
EC2の機能の1つ。オンプレミス環境の仮想マシンイメージのAWSへの移行や、災害からの復旧対策への備えとして活用できる。逆にEC2インスタンスに構築したものをオンプレミス環境へ移すことも出来る。
インポートした際、AMIに変換され、逆にオンプレミス環境へエクスポートする場合にはS3バケットを指定し保存する。

+ EC2を利用していれば追加料金はない
+ エクスポートする際はS3の使用料がかかる




# Snowシリーズ
物理データストレージを使用し、インターネットを迂回してAWSに直接大容量データを転送するサービス

![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3238179/59c40478-bb37-89e2-1628-5bddb9edca4f.png)


## AWS Snowcone(8TB)
IoTデバイスの計量分析エンジンとして利用できるコンピューティングアプライアンス。現場に設置し、直接データを収集。処理して即座に洞察を得てから、その場からデータ転送を行うことができる。
AWS Snowファミリーの中で最も小さく、データを含むデバイスをAWSに配送してオフラインでデータ転送を行うことができる。


## AWS Snowmobile
大型トラックが牽引する長さ14ｍの輸送コンテナでデータをAWSへ移動するサービス。
1台当たり100PB(ペタバイト。10万TB分)まで輸送が可能。
AWSはこれを「**エクサバイト規模のデータ転送サービス**」と呼んでいる。

## AWS Snowball
専用デバイス1台当たり80TBまでの移動するサービス。
「**ペタバイトスケールのデータ転送サービス**」とも呼んでいる
**現在は利用不可**

## AWS SnowballEdge
専用デバイスに格納し1週間程度で移動するサービス。遅くて信頼性の低いインターネット接続を回避してAWSに確実にデータ移行することができる。暗号化も実施してくれる

+ **Snowball Edge Storage Optimized(80TB)**
ブロックストレージとS3と互換性のあるオブジェクトストレージを提供する。80TBの容量があり、1台で50TBのデータ移行が可能

+ **Snowball Edge Compute Optimized(40TB)**
断続的な接続となる環境(製造、工業、輸送など)にあるデータや極度な遠隔地(軍事、海軍など)にあるデータの収集、機械学習、処理、保存をAWSに返送する前に実行できる。データ容量は40TB。


![容量](https://assets.st-note.com/img/1639929188173-KgOyy4MLiV.png)
Xojo 2019 (Web1.0) で WebPage を切り替える

Xojo Web は Web アプリ。
Webアプリは通常、url をロードする都度画面遷移する。
しかしながら Xojo Web はそのような遷移方法はポピュラーではなく、1回の HTTP(s) ロードで読み込んだアプリ内で画面遷移を行う。


ここでは複数の画面を切り変えるサンプルプログラムを示す。


# 環境

- Xojo 2019 R3.2
- Windows 10 Pro

# サンプルプログラム

Webアプリを新規作成すると、 WebPage1 が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/7da6302b-d80b-d455-8c19-2dde4c9a9b08.png)

WebPage2を追加します。WebPageはProject Items に Page として入っています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/f71a5cf7-340e-a7be-8331-c5125707fe6f.png)

Page 1 に「Page1」とテキストを貼り付け、 更にわかりやすいように  Google MapViewer を貼り付けました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/34a5baa7-2bd8-a49e-eea5-5286a54ddf78.png)

Page 2 も同様にして、「Page2」とテキストを貼り付け、 今度は YouTube Moview を貼り付けました。更に Button を「Go To Webpage1」として貼り付けます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/4e7ce78a-1640-0523-dbe4-575a730bf06f.png)

WebPage2 の Button1.Action 内のコードを `WebPage1.Show` と設定します。

WebPage1 にも同様に Button を貼り付けて、こちらのコードは`WebPage2.Show `と設定します。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c0e2d6b0-d797-26d8-4594-8ab36855a699.png)

実行すると、WebPage1 が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/60a91df2-2b4b-b119-3f01-7c26f77e8637.png)

ボタンを押すと、 WebPage2 に切り替わります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/cfa240b0-2d60-4974-d375-c4abc3d145a9.png)

# 初期表示ページの切り替え

通常だと WebPage1 が初期ページとしてロードされますが、WebPage2 を初期ページとしてロードしたいときは Session の Open イベントハンドラに `WebPage2.Show` と記述します。




# 初期化ルーチンの置き場所

今まではデータベースへの接続処理などを、WebPage1.Shown に置いてましたが、複数ページを持つときには Session の Open イベントハンドラに置くようにします。

そのとき、データベースの接続失敗時には `MsbBox` で警告を出してましたが、Session のOpen内でも MsbBox は表示されるでしょうか?


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/993bb035-f0e3-5f2d-67a7-4089d1cddfa0.png)

上記のように設定して実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/93f08870-c825-e562-0674-a729e09c8114.png)

うまく表示されるので、問題なさそうです。


# 参考

Web App Optimization From Xojo Documentation
http://man.hubwiz.com/docset/Xojo.docset/Contents/Resources/Documents/docs.xojo.com/UserGuide_Web_App_Optimization.html
SFTP機能が有効になっているAzure Storage Accountを特定する

Azure Storage AccountでSFTP機能を有効にすると、Blobに対してSFTP通信することが可能になります。
ただこのSFTP機能を有効にするとそこそこの金額が発生するので、有効化されているストレージアカウントを特定する方法を残します。
コマンドはCloud ShellのBashで試しています。

# isSftpEnableの値を含めた全ストレージアカウントを表示する
* az storage account listコマンドで全ストレージアカウントの情報を表示してからisSftpEnabledパラメータを出力しています。

```bash
az storage account list --query "[].{name:name , isSftpEnabled:isSftpEnabled}" -o table
```

```bash:出力例
Name                      IsSftpEnabled
------------------------  ---------------
aaa                       
bbb                       True
ccc                       False
・
・
・
```

* True
    * SFTP機能が有効になっています。
* False
    * Azure Data Lake Gen2機能が有効になっているがSFTP機能は無効になっています。
* Null
    * Azure Data Lake Gen2機能が無効になっています。

# isSftpEnable=Trueのアカウントのみ表示する
* Trueになっているストレージアカウント名のみ表示しています。

```bash
az storage account list --query "[?isSftpEnabled == \`true\`].name"
```

```bash:出力例
[
  "bbb"
]
```

以上です。
Ubuntu LinuxでPATHにカスタムパスを追加する

# 一時的に追加したい場合
PATHの末尾に追記するのがベター。
PATHに/custom/pathを追加するなら次のコマンドを実行する。
```
$ export PATH="$PATH:/custom/path"
```

# bash起動時に追加したい場合
PATHの末尾に追記するのがベター。
PATHに/custom/pathを追加するなら次のコマンドを実行する。
```
$ vim ~/.bashrc
```
下記の行を追記する。
```
export PATH="$PATH:/custom/path"
```
設定を反映する。
```
$ soruce ~/.bashrc
```
【Road to Cassandra Day】「列指向」について正しく理解できていますか？

# はじめに

## Cassandra Dayについて

今年、2023年６月１日に、[Cassandra Day](https://www.datastax.com/events/cassandra-day-japan)が日本でも開催されます。
Cassandra Dayは、昨年、ベルリン、ロンドン、アムステルダム、ハノイ、ジャカルタ、ヒューストン、サンタクララ、シアトル、シンガポールでも開催されました。

今回の東京での開催に向けて、Apache Cassandraに関する記事を発表していきます。

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/176567/6a879803-d135-348b-f815-08be011607fa.png)](https://www.datastax.com/events/cassandra-day-japan)

## Apache Cassandraについて

Apache Cassandraとは、一言でいうなら、オープンソースの分散データベース管理システムです。

他の分散データベース管理システム同様、複数の汎用サーバーを用いて、ひとつのデータベースを構築します（開発などの目的のため、一つのサーバーのみで構成することも可能です）。

ここでは、詳しい説明は割愛し、興味のある方へのご紹介の役割は、公式サイトやWikipediaに譲ります。

https://cassandra.apache.org/_/index.html

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


## データベースの分類について

ここでは、まず一旦Cassandraという固有名詞から離れます。
データベースを分類する方法には、いくつかありますが、その中から一つを取り上げます。

# 列指向データベースと行指向データベース

## 一般的な見方

データベースの分類方法として、列指向データベースと行指向データベースという、分け方があります。

行指向データベースとしてのRDBに対して、いくつかのNoSQLデータベースに対して区別なしに、列指向データベースという呼ばれ方がされることがあります。

実際のところ、一緒くたに「列指向データベース」と呼ばれたりもするデータベースには、大きく二つの種類があります。

ちなみに、日本語のWikipediaでは、この二つの違いに注意を促していますが、「列指向データベース管理システム」に対して、「カラム指向データモデル」という言葉が使われています。
日本語の「列」と外来語をカタカナ表記した「カラム」という言葉の使い分けも恣意的かつ日本国内でしか成立しない不十分な表現と思えますし、そこでの「データモデルを表しており、DBMS内部のデータ格納方式を表しているわけではない」という区別も正確ではないと思えるので、その点も踏まえて、整理していきたいと思います。

## 列（カラム）指向の二つの意味

まず、「列（カラム）指向」という言葉の指すところを、普遍化して整理してみると、こんなところになるかと思います。

- データの編成に列が重要な意味をもつ

これはさらに、以下の二つの特徴に分解できます。

- 列が「物理配置」に関係している
- 列単位でのデータ「アクセス」（データの「集約」と呼ばれることも）に優れる

ここまで普遍化した表現に置き換えれば、「列」と関連づけて説明される多くのデータベースに当てはまるといえます。しかし、そこには実態の大きく異なる二つの種類があります。

## 物理配置上の違い

物理配置においては、以下の二つの種類があります。

- A：各行毎に異なるファイルに格納されている。
- B：特定の項目（列）の値（とその並び順）によって、レコード（行）が、物理的に分割されている。

## データアクセス上の違い

得意とするデータアクセス方式においては、以下の二つの種類があります。

- A：特定の列の値の「集計」
- B：特定の列の値による「レコード抽出」、「検索（とソート）」

ここで、若干事態をややこしくしているかもしれないのが、「集約」という言葉で、Bの意味を説明されて場合があることです（日本語として不自然ではありませんが、「集約」という言葉で「集計」の意味を連想される方もいらっしゃるのではないでしょうか？強いて英語との対応関係を探るのであれば、「集計(aggregation)」「集約(consolidation)」といったところでしょうか）。

# カラムナーとワイドカラム

ここまでの説明は、容易に誤解を招く部分を解きほぐすという意図によって行われましたが、（特に既に理解されている方にとっては）まどろこしいものと見えたかもしれません。

一般に浸透している別の言葉で言い換えれば、つまりは以下の通りです。

- A = カラムナー
- B = ワイドカラム

それぞれについて、以下に箇条書きで整理してみます。

ここで、これまで、どんなアクセス方法に優れているか、という表現で説明してきた要素は、そのデータベースが設計された目的（オブジェクティブ）と捉えることができます。

## カラムナー

- オブジェクティブ：特定の列の値の「集計」
  - 「天文学的（ヒューマン・リーダブルでない）」量のビッグデータを、人間にとって意味のある値に「集約」（和・平均・最大値などいわゆる集約関数の範疇）
- 行追加は高コスト（複数ファイルへの書き込み）
- データは論理的に「過去」データ
- 代表的なデータベース（ストレージ）：Google Bigquery、Amazon Athena、Cloudera Impala (Apache Avro, Apache Parquet, Apache ORC)


## ワイドカラム

- オブジェクティブ：特定の行の値による「検索（とソート）」
  - 「無限にスケール（成長）」するデータの分散配置＝探索経路最適化
- 行追加にコスト最適化（ソート順に追加書き込み）
- 「リアルタイム」データの扱いに優れる
- 代表的なデータベース：HBase、Cassandra

# まとめ

最後にやっと、「Cassandra」に辿り着きました。
ともすれば同じ「列指向」という言葉で名指されることもあるデータベースだとしても、カラムナーとワイドカラムとでは、全く異なる目的のもとに設計されていることを伝えることができたようであれば幸いです。

自分のこれまでの経験を振り返ると、よくある先入観として、「NoSQL」＝「ビッグデータ」＝「データ分析」＝「情報系システム」という等式があるように感じます（等式がどこまで繋がるかの度合いには、人と場合によって差があるかと思いますが）。これにさらに付け加えるなら、「情報系システム」＝「Nice to have」という式を加えることもできるかと思います。これは、上に整理したワイドカラムの目的とは非常に異なっています。では、ワイドカラム・データベースは、より具体的にどのような場面で利用されているのか?これについては、また機会があれば発表したいと思います。
Codespacesでdashサンプルアプリ作成

# サマリ

→①dashサンプルアプリ作成
　②コンテナ化
　③AWSデプロイ

---

# ①Codespacesでdashサンプルアプリ作成

## リポジトリ作成

(割愛)

## codespaces起動

(割愛)

## dash インストール

```
pip install dash
```

## requirements.txt作成

```
pip freeze > requirements.txt
```

## サンプル実装(main.py)

```python
from dash import Dash, html, dcc, callback, Output, Input
import plotly.express as px
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminder_unfiltered.csv')

app = Dash(__name__)

app.layout = html.Div([
    html.H1(children='Title of Dash App', style={'textAlign':'center'}),
    dcc.Dropdown(df.country.unique(), 'Canada', id='dropdown-selection'),
    dcc.Graph(id='graph-content')
])

@callback(
    Output('graph-content', 'figure'),
    Input('dropdown-selection', 'value')
)
def update_graph(value):
    dff = df[df.country==value]
    return px.line(dff, x='year', y='pop')

if __name__ == '__main__':
    app.run_server(debug=True)
```

## 試しにdash実行

```
python main.py
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122491/636bdb7a-f818-3c6d-50d3-064edcddba32.png)

## dash 停止

```
Ctrl+C
```

# 参考

https://dash.plotly.com/
「面白そう！後で読も！」→「忘れた；」を解決する


最近では、誰でも簡単に情報を発信できて、中には無料で有益な情報が得られる記事なんかもありますよね！

でも、こんな経験はありませんか？

スマホを眺めていると、面白そうな記事を見つけた。でも、今は時間がないから後で読もう。そう思って、結局忘れてしまう、、、

僕は良くありました。Webページを忘れないようにと、URLはメモにコピーしたり、Twitterでお気に入り登録しておりたり。
でも結局肝心の「読む」こと自体を忘れちゃうんですよねw

そんな悩みを解決するアプリ、ArticleReminderを作りました！

ArticleReminderを使えば、WebページのURLを、リマインダ時刻とともに保存することができます。
![Screenshot_20221215-202515.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632285/334b23ce-8e54-8cb5-739b-e327d8779b6a.png)

設定した時刻になると、ArticleReminderが通知してくれます。
![スクショ_通知.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632285/529d8220-da1f-b787-efe3-54eb14e50bbf.png)

もし、面白そうな記事を見つけても今は時間がないという場合は、ArticleReminderに空いてそうな時間と一緒に保存してください。
後で忘れずじっくり読みましょう！

また、アプリを開けば登録した記事を確認できます。
リマインダ期限が近いものや、期限が過ぎてしまったものも表示できるので、見逃すことがありません。
![Screenshot_20221124-212704.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632285/e069949c-8058-b395-b46f-5ebc8cdbdad3.png)


ぜひ、ArticleReminderをダウンロードして、あなたの知識を増やしていきましょう！

アプリのページ：
https://www.rm48.net/post/%E3%80%8C%E5%BE%8C%E3%81%A7%E8%AA%AD%E3%82%80%E3%80%8D%E3%82%92%E5%BF%98%E3%82%8C%E3%81%AA%E3%81%84%E3%82%A2%E3%83%97%E3%83%AA-articlereminder


AppStore: https://apps.apple.com/us/app/articlereminder/id1665350679

Google Play Store:
https://play.google.com/store/apps/details?id=com.rm48.article_reminder&pli=1
nuxt2 + composition api + tsx 依存関係の備忘録

# 結論
nuxt2.15 + vue2.6 + @nuxtjs/composition-api + babel-preset-vca-jsxとなった。

## vue2.7 にしたかった
vue2.7にするとネイティブでComposition APIがサポートされるのでベターなのでは？と思って実施。
しかし、全体的に依存関係が解決出来なかった。

ネイティブcomposition apiとnuxt2.16の相性？

# おまけ
nuxt2.15 + @pinia/nuxt
Invalid host defined options が発生。
情報無し、諦めるん
【React】エクスポートはexport? default export?


# 【React】　export? default export?

## はじめに
今回はReact初学者の方に向けた記事になります。
Reactの勉強を始めたばかりの私の備忘録としても残しておきたいと思います！

## 対象読者
- React初学者
- これからReactを始められる方


## Reactとは？
まず、大雑把にReactとはなんなのか？という部分です。
Reactはその中身の大半がJavaScriptになっており、
そのJavaScriptの再利用性を高め描きやすくしたものになります！
例えば、機能Aを作成しておりその機能Aを別ファイルでも使用したい！となった時に再度同じ内容のJavaScriptを記述する必要が出ます。
しかし、Reactを使用するとcomponentという、ひとかたまりの機能Aというパーツにすることができます！
そのパーツを再利用する際に使用するのが今回のタイトルのexportになります。

## exportとは？
exportとはなんですか？なぜ記述するのですか？という疑問を解消したいと思います。
和訳では輸出になり、その名の通りパーツAを輸出できますよ！と宣言するイメージです。
例えば、下記のようなGallery.jsというファイルがあるとします。このファイルの中にはProfileというパーツがあり、そのパーツを使用した新たなパーツGalleryがあります。
このGalleryパーツをexport defaultで輸出できます！と宣言しているので他のファイルでも使用することができます。
ここではexport defaultと記述されていますが、実際はdefaultは記述しなくても他のファイルで使用することができます。今回のタイトル通りじゃあどのように使い分けたらいいの？となります。
自分はなりました、、、次章で説明いたします！

```react:Gallery.js
function Profile() {
  return (
    <img
      src="https://i.imgur.com/QIrZWGIs.jpg"
      alt="Alan L. Hart"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

```


## export? default export?
前置きが長くなりましたが、本題になります。
結論としてdefaultをつける時の違いは、
#### 1\.　default exportは同ファイルに1つしか宣言できず、exportは複数使用可能。
#### 2\.　importする際のする方法がexportの記述によって変化する。
#### 3\.　defaultではimport側で名前を自由に決めることができる(※asを使用すれば変更することも可能)
上記3点になります。


## 1\.　default exportは同ファイルに1つしか宣言できず、exportは複数使用可能。
1つ目の違いとして複数使用可能かどうかがあります。
先程のGalleryファイルのようにGalleryコンポーネントのみをexportする際はdefault exportで問題ないですが、このファイルにもうひとつexportしたいcomponentを作成する場合はdefaultをつけてしまうとエラーになります。

## 2\.　importする際の方法がexportの記述によって変化する
2点目がimportの記述方法が異なるということです。
importは和訳で輸入という意味で、exportでコンポーネントというパーツを輸出します！
と宣言すれば使用する側もimportで輸入します！と宣言必要ということですね！
例えば先程のGalleryをApp.jsというファイルで使用するためには下記１行目のように記述することで使用することができます。
```react:App.js
import Gallery from './Gallery.js';

export default function App() {
  return (
    <Gallery />
  );
}

```
ここでGalleryのexportにdefaultがついていないと上記importの記述方法ではエラーになります。
App.jsのimport部分を下記のように変更する必要があります！
```react:App.js
import {Gallery} from './Gallery.js'
```
これで使用することができます。

## 3\.defaultではimport側で名前を自由に決めることができる

最後にdefaultがついていればimport側で名前を自由に決めることができることです。
例えば、先程のGalleryファイルのexportにdefaultが記述されたままであれば、
下記のようにApp.jsファイル内で別名で使用することができるようになります。
これであればimport側で自由に命名できるので使用しやすい名前で再利用できることでしょう！
```react:App.js
import Picture from './Gallery.js';

export default function App() {
  return (
    <Picture />
  );
}
```

:::note warn
注意
from以降の記述は現在記述しているファイルから見たimport先のファイルパスを記述しているので、この部分は変更できない！
:::


## おわりに
最後まで見ていただきありがとうございました！
まだまだ初学者な為、至らない点あるかもしれませんがご了承ください。
実際、僕自身React学習しており初学者向きの本を購入し進めていたのですが、当たり前のようにこの部分が書かれておらず進めていくことになったので、初学者の方が疑問に感じて調べた時にこの記事が参考になれば嬉しく思います。
もし、これから勉強される方はまずJavaScriptを勉強したのちに下記参考文献一通り確認してからReactの書籍にあたってみてください！
理解度が違うと思います！

## 参考文献

https://react.dev/learn/importing-and-exporting-components
brewでecrmをインストール

とても良さそうなので検証も兼ねて使ってみる

https://techblog.kayac.com/ecrm-oss


## 環境

- MacBook Pro(2020) intelチップ
- MacOS Monterey v12.3.1
- Homebrew 4.0.16

## インストール

`kayac/tap` の方ではなく、`fujiwara/tap`の方なのでリポジトリを指定してインストールする

```zsh
brew search fujiwara/tap
==> Formulae
fujiwara/tap/aswrap                     fujiwara/tap/ecsta                      fujiwara/tap/lambroll                   fujiwara/tap/maws-cli                   fujiwara/tap/rin                        fujiwara/tap/stretcher
fujiwara/tap/cloudwatch-to-mackerel     fujiwara/tap/fluent-agent-hydra         fujiwara/tap/macaroni                   fujiwara/tap/nssh                       fujiwara/tap/sailtrim                   fujiwara/tap/tfstate-lookup
fujiwara/tap/ecrm                       fujiwara/tap/kinesis-tailf              fujiwara/tap/maprobe                    fujiwara/tap/riex                       fujiwara/tap/sardine                    fujiwara/tap/tracer

brew install fujiwara/tap/ecrm
==> Fetching fujiwara/tap/ecrm
==> Downloading https://github.com/fujiwara/ecrm/releases/download/v0.3.3/ecrm_0.3.3_darwin_amd64.tar.gz
==> Downloading from https://objects.githubusercontent.com/github-production-release-asset-2e65be/395700951/d6c446a3-7d84-4586-b4a3-34f7528801a0?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIWNJYAX4CSVEH53A%2F20230502%2Fus-east-1%2
######################################################################################################################################################################################################################################### 100.0%
==> Installing ecrm from fujiwara/tap

🍺  /usr/local/Cellar/ecrm/0.3.3: 6 files, 14.4MB, built in 9 seconds
==> Running `brew cleanup ecrm`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).
```

インストールできた

```
NAME:
   ecrm - A command line tool for managing ECR repositories

USAGE:
   ecrm [global options] command [command options] [arguments...]

VERSION:
   0.3.3

COMMANDS:
   delete    Scan ECS/Lambda resources and delete unused ECR images.
   generate  Genarete ecrm.yaml
   plan      Scan ECS/Lambda resources and find unused ECR images to delete safety.
   help, h   Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --config FILE, -c FILE  Load configuration from FILE (default: "ecrm.yaml") [$ECRM_CONFIG]
   --format value          plan output format (table, json) (default: "table") [$ECRM_FORMAT]
   --log-level value       Set log level (debug, info, notice, warn, error) (default: "info") [$ECRM_LOG_LEVEL]
   --no-color              Whether or not to color the output (default: false) [$ECRM_NO_COLOR]
   --help, -h              show help (default: false)
   --version, -v           print the version (default: false)

```
Python3.12をサポートするツールで、pyinstaller5.10(Python3.12未対応)をインストールする

# 環境
* Python 3.11.2
* poetry 1.4.2
* pinstaller 5.10.1


# やりたいこと
Python3.9以上で動くツールを作成しています。
pyinstallerは開発用時に利用したいです。
ライブラリはpoetryで管理しています。

```toml:pyproject.toml
[tool.poetry]
name = "yuji38kwmt-cli"
version = "0.1.0"
description = "yuji38kwmt's CLI"
authors = ["yuji38kwmt"]
license = "MIT"
packages = [
    { include = "yuji38kwmt_cli" }
]

[tool.poetry.dependencies]
python = "^3.9"

[tool.poetry.group.dev.dependencies]
pyinstaller = "^5.10"

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
```

# 起きたこと
`poetry install`時に以下のエラーが発生しました。

```
$ poetry install 
Updating dependencies
Resolving dependencies... (0.7s)

The current project's Python requirement (>=3.9,<4.0) is not compatible with some of the required packages Python requirement:
  - pyinstaller requires Python <3.12,>=3.7, so it will not be satisfied for Python >=3.12,<4.0
  - pyinstaller requires Python <3.12,>=3.7, so it will not be satisfied for Python >=3.12,<4.0

Because no versions of pyinstaller match >5.10,<5.10.1 || >5.10.1,<6.0
 and pyinstaller (5.10.0) requires Python <3.12,>=3.7, pyinstaller is forbidden.
So, because pyinstaller (5.10.1) requires Python <3.12,>=3.7
 and yuji38kwmt-cli depends on pyinstaller (^5.10), version solving failed.

  • Check your dependencies Python requirement: The Python requirement can be specified via the `python` or `markers` properties
    
    For pyinstaller, a possible solution would be to set the `python` property to ">=3.9,<3.12"
    For pyinstaller, a possible solution would be to set the `python` property to ">=3.9,<3.12"

    https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies,
    https://python-poetry.org/docs/dependency-specification/#using-environment-markers
```

pyinstallerのPython requirementは`<3.12,>=3.7`なのに対して、私のツールは`>=3.9,<4.0`なので、インストールできませんでした。


# 解決策
私のツールのサポートしているPythonバージョンを、4.0未満から3.12未満に変更すれば解決します。

```toml:pyproject.toml
[tool.poetry.dependencies]
python = ">=3.9,<3.12"
```

私のツールはたぶんPython3.12でも動くはずなので、できればPython3.12もサポートするようにしたいです。

pyinstallerは開発時しか利用しないので、pyinstallerを[インストール条件にPythonのバージョンを指定する](https://python-poetry.org/docs/dependency-specification/#python-restricted-dependencies)ようにしました。



```toml:pyproject.toml
[tool.poetry.group.dev.dependencies]
pyinstaller = {version="^5.10", python="<3.12"}
```

Python3.12で開発する頃にはpyinstallerもPython3.12に対応していると思うので、問題ないでしょう。

# 補足
Python3.12をサポートしていない理由を質問しました。

>Python's bytecode (which PyInstaller has to read) is not backwards compatible. Nor is its binary ABI which PyInstaller's bootloaders depend on. And in the case of Python 3.12, the standard lib libraries imp and distutils are being removed so PyInstaller needs some fairly serious work to remove its dependency on those. 

https://github.com/orgs/pyinstaller/discussions/7605#discussioncomment-5777692
Git「Untracked files」を git diff する方法 

以下のコマンドを行ったあとで`git diff`する

```
git add -N ファイル名
```

### 参考サイト
* [Can I use git diff on untracked files? - Stack Overflow](https://stackoverflow.com/questions/855767/can-i-use-git-diff-on-untracked-files)
* [git diffで新規作成したファイルの内容を表示する方法 - Reasonable Code](https://reasonable-code.com/git-add-n/)
the engine "node" is incompatible with this module.が出た時の対処法

yarn installした時に
**「The engine "node" is incompatible with this module. Expected version "^15.0 || ^16.0 || ^17.0 || >=18.0.0". Got "19.9.0"」**

のようなエラーが出ることがあります。

# 原因
インストールされているnodeのバージョンが非互換であることが原因です。

# 対策
nodeのバージョンを下げる必要があります。

①
下記コマンドを叩き、変更可能なnodeのバージョンを調べます。
```nodebrew ls-remote```
すると以下にバージョンが出現します。
```
v17.6.0   v17.7.0   v17.7.1   v17.7.2   v17.8.0   v17.9.0   v17.9.1   
v18.0.0   v18.1.0   v18.2.0   v18.3.0   v18.4.0   v18.5.0   v18.6.0   v18.7.0
v18.8.0   v18.9.0   v18.9.1   v18.10.0  v18.11.0  v18.12.0  v18.12.1  v18.13.0
v18.14.0  v18.14.1  v18.14.2  v18.15.0  v18.16.0 
```

②
以下のコマンドで指定のバージョンに変更
今回は１８.０.０を指定

```nodebrew install-binary v8.16.0```

この方法で切り替わるはずです。

**もし切り替わらない、エラーが出現する場合は以下のサイトを参考にしてください。**
https://qiita.com/k3ntar0/items/322e668468716641aa5c

# まとめ
今回はnodeの互換性のエラーを解決する方法についてまとめました。

理解が間違っている点があればご指摘お願いします。
FLOCSSルールまとめ

# はじめに
FLOCSSというCSS設計手法でビューを実装する機会があったのですが、公式ドキュメントや既存の記事だけでは設計に悩む部分もあったので、備忘録として設計ルールをまとめました。

# FLOCSS とは
> FLOCSS（フロックス） は、OOCSSやSMACSS、BEM、SuitCSSのコンセプトを取り入れた、モジュラーなアプローチのためのCSS構成案です。

[FLOCSS公式](https://github.com/hiloki/flocss)より引用

# 基本ルール
**クラス命名規則はBEM([BEM公式](https://github.com/manabuyasuda/styleguide/blob/master/how-to-bem.md)) を使用**
Elementはアンダーバー2つ、Modifierはハイフン2つで繋ぐ
(例) c-button__icon, c-button--red

**Elementの2階層目を作るのは非推奨**
⭕️ .Block__Element--Modifier
❌ .Block__Element__Element--Modifier 

**基本的にすべてのタグにクラス名をつける**
これをすることで、何の役割を持つタグなのかをクラス名から推測できるようになる

**接頭辞をつける**
`l-` (layout), `p-` (project), `c-` (component), `u-` (utility)

# Layout
サイトの大枠となるレイアウトを管理する( `header` , `footer` , `main` , `sidebar` 等)

**Layoutにする基準**
「複数のページ（もしくは全ページ）に共通して現れる大きい要素かどうか」

**指定するスタイル**
位置やレイアウトの指定、共通の余白、色など
`display` , `position` , `width` , `height` , `margin` , `padding` , `background`
# Component
>「独立したモジュール」として定義する

繰り返し使われるパーツを**最小単位**で管理する(ボタンやフォーム等)
→ この最小単位が人によって異なる可能性があるので以下のルールに従うことにする
 
**Componentにする基準**
- 「複数のページで使われている共通のモジュールかどうか」
- 「スタイルが同じ」ではなく「スタイルもモジュールとしての役割も同じかどうか」
- 同じモジュールが3回以上出てくる

**固有の幅や色などの特色を持つことは避けるのが望ましい**
- Componentは出来る限り最低限の機能を持ったものとして定義されるべき
- 幅や色はProjectで指定する
- デザインの段階で幅や高さが決まっている前提の場合は `width` と `height` を持たせても良いが、 `min-width` や `min-height` にしておくとより良い

### 禁止事項 
- `margin` の指定
- 特定のタグやクラスの中で使わないと同じ振る舞いができない状態
- Componentの中にProjectやComponentが存在する

# Project
Componentのパーツと、それ以外の要素が組み合わさってできる要素(コンテンツを構成する要素)を管理する

**Projectにする基準**
- 「小さい単位のComponentを集めて、一つのオブジェクトとして扱いたいかどうか」
- 使い回さないブロックだけど分けて管理したい場合

**迷ったらとりあえずProject**
ComponentかProjectか迷ったらとりあえずProjectにする

**具体的なデザインはProjectで指定する**
ProjectがComponentのスタイルを上書きするのは許容する

### 禁止事項
Project内に別のProjectが存在する

# Utility
わずかなスタイルの調整のための便利クラスなどを定義する

**基本的に使わない**

# 参考
- [[CSS設計] 私のためのFLOCSSまとめ](https://qiita.com/super-mana-chan/items/644c6827be954c8db2c0)
- [FLOCSSを使ったCSS設計での悩みどころと解決案](https://qiita.com/uggds/items/d904b2f9a103c37a25fa)
- [FLOCSSベースのサイト設計 - 破綻しないルールを決める](https://yumegori.com/flocss)
pojo

如果你的检索结果的 POJO 是动态的，即其字段是不确定的，那么你可以考虑使用 Java 反射来动态设置结果集中每个记录的值。

具体来说，你可以在 `SelectProvider` 中构建出一个动态的 `ResultMap`，然后在返回结果的时候使用 Java 反射来将每个记录的值设置到对应的 POJO 中。以下是一个示例：

```java
public interface MyMapper<T> {
    @SelectProvider(type = MyProvider.class, method = "dynamicSQL")
    List<T> select(String tableName, String[] columns);
}

public class MyProvider {
    public String dynamicSQL(String tableName, String[] columns) {
        // 构建动态的 ResultMap
        StringBuilder resultMapBuilder = new StringBuilder("<resultMap type=\"");
        resultMapBuilder.append("com.example.DynamicPojo");
        resultMapBuilder.append("\" id=\"resultMap\">\n");

        for (String column : columns) {
            resultMapBuilder.append("<result property=\"");
            resultMapBuilder.append(column);
            resultMapBuilder.append("\" column=\"");
            resultMapBuilder.append(column);
            resultMapBuilder.append("\" />\n");
        }

        resultMapBuilder.append("</resultMap>");

        // 构建 SQL
        StringBuilder sqlBuilder = new StringBuilder("SELECT ");

        for (String column : columns) {
            sqlBuilder.append(column);
            sqlBuilder.append(",");
        }

        sqlBuilder.deleteCharAt(sqlBuilder.length() - 1);
        sqlBuilder.append(" FROM ");
        sqlBuilder.append(tableName);

        return "<script>" + resultMapBuilder.toString() + sqlBuilder.toString() + "</script>";
    }
}

public class DynamicPojo {
    // 使用反射来设置每个记录的值
    public void setField(String fieldName, Object value) {
        try {
            Field field = this.getClass().getDeclaredField(fieldName);
            field.setAccessible(true);
            field.set(this, value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
```

在上面的示例中，我们首先定义了一个 `MyMapper` 接口，其中的 `select` 方法使用了 `SelectProvider` 注解，其参数包括表名和要查询的列名数组。然后，我们定义了一个 `MyProvider` 类，其中的 `dynamicSQL` 方法根据传入的表名和列名数组构建出一个动态的 `ResultMap`，并拼接出相应的 SQL 语句。最后，我们定义了一个 `DynamicPojo` 类作为动态的 POJO，其中的 `setField` 方法使用 Java 反射来设置每个记录的值。

你可以根据自己的需求来修改上面的代码。
webアプリから入力したメールアドレスにメールを送信するまで

.envファイルを以下のように修正します。

MAIL_DRIVER=smtp
MAIL_HOST=smtp.gmail.com
MAIL_PORT=587
MAIL_USERNAME={Googleアカウント}
MAIL_PASSWORD={アプリ パスワード}
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS={メールのfromに表示するアドレス}
MAIL_FROM_NAME={メールのfromに表示する名前}

MAIL_FROM_ADDRESSとMAIL_FROM_NAMEはController側で再設定しているので、
ここでは初期設定の値になります。


アプリパスワードはGoogle側で設定する必要があります。
まず、2段階認証プロセスを有効にします。
Google公式ページより参照してください。
https://support.google.com/accounts/answer/185839

Googleの「アプリ パスワード」を設定する
2段階認証プロセスを有効にできたら、アプリパスワードを設定します。
こちらもGoogle公式ページより参照してください。
https://support.google.com/accounts/answer/185833
MacOSでpythonが認識されないのを解決


## 環境
- MacOS
- Homebrewインストール済み
- `brew install python`を実行済み

## 状況
- 上記の状態からターミナル上で`python -V`を実行しても認識されない。
- `brew info python`を実行すると、ローカルの格納先は表示される。
- `echo $SHELL`の実行結果は`/bin/zsh`。（`.zshrc`を使用）

## 解決策
### VSCode上のファイルを修正する。
`Users/xxx/Library/Application Support/Code/User/settings.json`ファイル
→VSCodeの設定から`terminal.integrated.env.osx`で検索すればOK

下記を追記。
```json:Users/xxx/Library/Application Support/Code/User/settings.json
"terminal.integrated.env.osx": {
    "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin/python3"
  }
```

上記の修正後、再度コマンドを実行
```sh
python -V
# Python 3.11.3が表示された
```

これで解決しました。
Chat GPT APIレート制限とは


<h1>APIレート制限

受付可能なリクエストを制限していること

gptのapiを叩きまくっていたら
![スクリーンショット 2023-05-01 12.44.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3331212/812d270e-a45c-3562-bbe1-e30c292952db.png)
429エラーが出てきました

<h2>too many request

429はtoo many requestということで、apiを叩きすぎているのが原因らしいです

もっと詳細に言えばクライアントがリクエストを投げすぎて、サーバーがそれにNoという信号を出してくる。
そのNo信号がhttpステータスコード429だということです


叩きすぎて制限を受けることをapiレート制限と言います


こう言ったapiレート制限は、apiを提供してくれているサービス（openaiやtwitterなど）にはついていてそれぞれドキュメントを参照しどのようなルール内で使用可能か調べておく必要があります




<h2>gpt内でのエラー理由



openaiとしてはリクエストされすぎたら、サービスが中断してしまうような負荷が生じてしまうため
ユーザーごとにリクエストの回数を定めています

1分間に何回まで(モデルによります)か許されているそうで、それを超えたら429というhttpステータスコードが表示されしばらく時間が経ってからでしたかリクエストを受け入れてくれません
しばらくとは言いましたが、体感10秒程度でした


<h2>gpt レート制限の定義方法

gptのレート制限は「rpm」と「tpm」の二つで判定されています
両者に共通するpmは(per minute)で、「1分あたりの~」ですね
「rはrequest」で「tはtoken」です。だいぶ覚えやすくなったと思います

要するに、1分あたりのリクエストとトークン（文字数）によってレート制限は定められているようです

レート制限でエラーになった場合はどうするか、レート制限はどのくらいリクエストしたらなるのかなどはリンク先に記載されていますので是非読んでみてください

https://platform.openai.com/docs/guides/rate-limits
Dockerを使ってMySQLのExample Databasesを利用してみる

# はじめに
私は今「[おうちで学べるデータベースのきほん](https://amzn.asia/d/fGgAQgK)」という本でRDBMSの学習を進めているのですが、MySQLサーバーを起動してworld databaseを使ってみるというところで、どうせならDockerを利用してみようと思い今回の記事執筆に至りました。至らぬ点もあるかとは思いますが、どうかお付き合いください。
# 実行環境
- 機種名：MacBook Pro 2021
- チップ：Apple M1 Pro
- メモリ：16GB
- OS：macOS　Ventura 13.3.1
- Docker version：23.0.5
# やりたいこと
- Docker上にMySQLのコンテナを立てる
- MySQLのバージョンは5.7
- MySQLで[Example Databases](https://dev.mysql.com/doc/index-other.html)のworld databaseを使う
# やってみる
## 1. docker hubを確認
[docker hubのMySQLのページ](https://hub.docker.com/_/mysql)をまずは確認します。

::: note alert
注意
Dockerfileのリンクが変わっているところに注意してください。
今までと同じように`FROM mysql:5.7`と書いてしまうとoraclelinuxで起動してしまいます。すると、
`RUN apt-get update`が実行された時に、
`apt-get: command not found`
と怒られてしまいます。
:::
## 2. Dockerfileを作成
先ほどの点に注意して、MySQLのバージョンを指定する時に`-debian`を追記しておきます。
さらに、今回はzipファイルをWeb上からダウンロードして、解凍する必要があるため、**wget**と**unzip**をインストールしておく必要があります。
最後にzipファイルのダウンロード先と解凍したファイルの移動先を指定します。
```
FROM mysql:5.7-debian

ENV MYSQL_ROOT_PASSWORD=root_pass

RUN apt-get update
RUN apt-get install -y wget unzip
RUN wget https://downloads.mysql.com/docs/world-db.zip
RUN unzip world-db.zip
RUN mv world-db/world.sql /docker-entrypoint-initdb.d/world.sql
```
## 3. docker-compose.ymlを作成
platformを指定したいので、docker-compose.ymlも作成していきます。
ポートは利用している場合適宜変えてください。

:::note alert
注意
platformを指定せずDockerfileだけで起動しようとすると以下のようにエラーが出ます。
`failed to solve: mysql:5.7-debian: no match for platform in manifest`
:::
```
version: "3"

services:
  db:
    container_name: mysql-5.7
    build:
      dockerfile: Dockerfile
    platform: linux/x86_64
    ports:
      - 3306:3306
```
## 4. コンテナを起動する
先ほど作成したファイルをもとにコンテナを起動します。
```
% docker-compose up -d
```
## 5. コンテナに入る
起動したコンテナの名前「mysql-5.7」とbashを指定して中に入ります。
```
% docker exec -it mysql-5.7 bash
```
## 6. MySQLに入る
今回はrootでMySQLの中に入ります。
-uでユーザーを指定して、-pまで打ったらエンターを押してください。
```
root@d873265e9473:/# mysql -u root -p
```
## 7. MySQLのパスワードを入力する
以下のような表示が出たら、パスワードを入力してください。
今回はDockerfileで`ENV MYSQL_ROOT_PASSWORD=root_pass`と指定しているので、「root_pass」がMySQLのrootのパスワードになります。
```
Enter password: 
```
## 8. world databaseのサンプルが開けるか確認する。
### 8-1. データベースが表示できるか確認する。
```
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| world              |
+--------------------+
5 rows in set (0.01 sec)
```
### 8-2. テーブルが表示されるか確認する。
```
mysql> use world;
mysql> show tables;
+-----------------+
| Tables_in_world |
+-----------------+
| city            |
| country         |
| countrylanguage |
+-----------------+
3 rows in set (0.01 sec)
```
無事サンプルが入っていましたね。
ここまでくれば大丈夫そうです。
あとは本に従って学習を進めていきましょう！！！
# おわりに
今回久しぶりにDockerを起動するにあたり、以前使用していたDockerfileやdocker-composeをそのまま使えるのでは！？と思い動かしてみましたが、やっぱりダメでした。。。
なんでダメなのか設定を見直していくうちに「なんか2年前と違う！！！」っていうところを2点見つけたため、**注意**として残してあります。理由は文中に残してありますが、使わないうちにあっという間に置いてかれるなぁと感じました。
これからは普段からどんどん使っていこうと決意したのでした。。。
普段気にすることの無かった JavaScript の「参照渡し」(正確には「参照値という値渡し」？)に出くわした

# こんな事がありました

他の人が書いたGoogleAppsScriptのコードを見ていて(と書くことによって「私じゃないよ！」を強調したい下心が見えますね)、**Dateオブジェクトを渡すとその1週間後(7日後)が日本の祝日かどうかを判定する関数**  `isHolidayNextWeek()` がありました。

こんな感じで使われていました。

```js:
function main() {
  const date = new Date("2023-10-02") // 翌週の 2023-10-09 は スポーツの日です 
  if(isHolidayNextWeek(date)){
    console.log(`${Utilities.formatDate(date,"JST","yyyy-MM-dd")} の1週間後は祝日です`)
  }
}

function isHolidayNextWeek(date) {
  const nextWeekMonday = new Date(date.setDate(date.getDate() + 7));
  const calendar = CalendarApp.getCalendarById('ja.japanese#holiday@group.v.calendar.google.com');
  const count = calendar.getEventsForDay(nextWeekMonday).length;
  if (count) return true
  return false
}
```

↓ `main()` の実行結果がこちら

```
2023-10-09 の1週間後は祝日です
```


…え。こちらの想定としては


```
2023-10-02 の1週間後は祝日です
```

でした。

# これが参照渡しってやつか！！

JavaScript における「値渡し」「参照渡し」の説明は別のところで調べてもらうとして

* プリミティブは値渡し
* オブジェクトは参照渡し

のようです。

(2023-05-03追記: 正確には「JavaScriptには参照渡しは存在しない」ようです。私は「参照値という値渡し」という表現がピンと来ました。[参照先](https://qiita.com/Yametaro/items/21f7b1a4ae09f16f323e))

今回の `date` は オブジェクト(Dateクラスのインスタンス？) なので `main()` の中の date と `isHolidayNextWeek()` の中のdate は 「同じものを参照している」ということ、、、なんだろうな。


```js:
function isHolidayNextWeek(date) {
  const nextWeekMonday = new Date(date.setDate(date.getDate() + 7)); // dateにsetしちゃダメ！
...
```

ここが `date.setDate()` なので、dateにsetしちゃってるのよね。だから `main()` の中のdateも7日後になっちゃってる、と。

これ、頭ではわかっててもうっかりやっちゃいそう。。。

# こうすればいいよね

```js:
const nextWeekMonday = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 7);
```

dateオブジェクトは変更しないで、dateから取得した値によって `new Date()` する、と。

これ、気をつけないと「A関数からB関数にオブジェクトを渡して、B関数の中でオブジェクトを変更しちゃうと、その変更にA関数からは気づけない」みたいなことになりますよね。
ubuntu21.04 アプリケーション画面からアイコンが消えない

# ubuntu にLINEを入れたくて四苦八苦した話

その際、LINEをwine経由で入れるという過程を踏んだのだが、LINEのローカルファイルが消えており、うまく行かなかった。
過去のインストールファイルで実行しようとしたが、エラーを吐いてLINEは使えなかった…

LINEをアンインストールしたらアンインストールはできたのだが、アイコンが消えてくれなかった。
Webで`Ubuntu wine ショートカット`などで調べても中々見つからず、アイコンを消すのに苦労した。

## 結論

下記ディレクトリの中身がアイコンフォルダだった。

```bash
> cd ~/.local/share/applications/wine/
> ls -l
-rw-rw-r-- 1  366  5月  2 10:21 LINE.desktop
drwxrwxr-x 3 4096  5月  2 10:13 Programs
```

## 参考文献

- [ubuntu18.04 アプリケーション画面からアイコンが消えない](https://teratail.com/questions/190054)
v-selectのitem-textに画像を追加する

Vuetifyのv-selectの選択肢を`画像＋文字列`にする時に少しハマったのでメモ。

# 結論

`v-select`に`template`を追加してあげれば良い。

```js
<v-select
  :value="selected"
  :items="itemList"
  :item-value="item => item.id"
  :item-text="item => item.name"
  @change="$emit('update:selected', $event)"
>
  <template #selection="{ item }">
    <img
      :src="item.path(画像のpath)"
      :alt="item.name"
    >
    <span>{{ item.name }}</span>
  </template>
  <template #item="{ item }">
    <img      
      :src="item.path(画像のpath)"
      :alt="item.name"
    >
    <span>{{ item.name }}</span>
  </template>
</v-select>
```

ドロップダウンのリストと、選択中のアイテムの表示はそれぞれ設定する必要がある。


### 選択した項目の画像＋文字列表示を設定

```js
<template #selection="{ item }">
```

### ドロップダウンリストの画像＋文字列表示を設定

```js
<template #item="{ item }">
```
X-NUCLEO-GFX01M1を準備(ILI9341)(STM32G071)


x 過去ログをみよ

目的
ILI9341その互換機の標準的なライブラリになっている
Adafruit ILI9341　+ Adafruit GFXのインストール で
ビットマップイメージを表示

1 Adafruit GFX

2 Adafruit ILI9341

3 スケッチの書き込み

4 コンパイル


https://qiita.com/caa45040/items/3c57c159be0fd0f7a718


https://qiita.com/caa45040/items/544fd9928309e7b6ed94

https://qiita.com/caa45040/items/574231109a31cb6c55eb

![o_cop482.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/a6abc7cf-7bae-abfa-66f3-222efc57f6f2.jpeg)



![o_cop483.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/fb706e2b-b5b6-2782-e28a-d5149b68878a.jpeg)







```c++




//X_NUCLEO_GFX01M1_time_test_071


//インクルド
#include "SPI.h"
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"

//設定
#define TFT_RST A1
#define TFT_DC 3
#define TFT_CS 4

//液晶の定義
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);


// ビットマップデータ
// 'soiya1', 128x320px
static const unsigned char PROGMEM databytes[] = {


 0xc0, 0x00, 0x00, 0x03, 0xbf, 0xf0, 0x0f, 0xfd, 0x7f, 0xce, 0x73, 0xfe,
 0x7f, 0x3f, 0x7c, 0xfe, 0x7e, 0xff, 0x7f, 0x7e, 0x7d, 0xfb, 0x7f, 0xbe,
 0x7b, 0xea, 0xff, 0xde, 0x77, 0xeb, 0x7f, 0xee, 0x77, 0xf7, 0xff, 0xee,
 0x6f, 0xfb, 0xff, 0xf6, 0x6f, 0xfb, 0xff, 0xf6, 0x6f, 0xfb, 0xff, 0xf6,
 0x5f, 0xfd, 0xff, 0xfa, 0x5e, 0xfd, 0xff, 0x3a, 0x5d, 0x7e, 0xff, 0xba,
 0x42, 0x7e, 0xff, 0x02, 0x5f, 0x7d, 0x7f, 0x3a, 0x5f, 0xfd, 0xff, 0xfa,
 0x5f, 0xfb, 0xff, 0xfa, 0x6f, 0xf7, 0xff, 0xf6, 0x6f, 0xef, 0xff, 0xf6,
 0x6f, 0xff, 0x7f, 0xf6, 0x77, 0xfe, 0xff, 0xee, 0x77, 0xfe, 0x7f, 0xee,
 0x7b, 0xfe, 0xbf, 0xde, 0x7d, 0xfe, 0x7f, 0xbe, 0x7e, 0xfe, 0xff, 0x7e,
 0x7f, 0x3e, 0xfc, 0xfe, 0x7f, 0xce, 0xf3, 0xfe, 0x7f, 0xf0, 0x0f, 0xfe,
 0x7f, 0xff, 0xff, 0xfe, 0x00, 0x00, 0x00, 0x00


};


//初期化
void setup() {

  //シリアルの初期化
  Serial.begin(9600);
  Serial.println("ILI9341 Test!"); 

  //液晶のリセットピンの設定
  pinMode(TFT_RST, OUTPUT);
  digitalWrite(TFT_RST, HIGH);
  //digitalWrite(TFT_RST, LOW);

  //液晶の初期化
  tft.begin();

  //画面のクリア
  tft.fillScreen(ILI9341_BLACK);

}//setup


//メインループ
void loop() {

  //画面のクリア
  //tft.fillScreen(ILI9341_BLACK);

  //3時の表示
  tft.drawBitmap( 0+32, 0, databytes, 32, 32, ILI9341_WHITE);

  delay(1000); //1秒待つ

}//loop





```
遺伝研スパコン上でdoradoのbasecallingをしてみる

Nanoporeのbasecallerであるdoradoを使ってみる。
https://github.com/nanoporetech/dorado

# fast5ファイル形式の場合、pod5形式へ変換する
入力ファイルはfast5ではなく、pod5形式が推奨。
fast5からpod5への変換には、pytnonのパッケージであるpod5を使う。
https://github.com/nanoporetech/pod5-file-format

使い方: https://pod5-file-format.readthedocs.io/en/0.1.20/docs/tools.html#pod5-convert-fast5
↑のusageのコマンドはちょっと間違っているところもあるのでコピペせず、引数は自分の目で確認推奨。

```
# バラバラのfast5から、それぞれに対応したpod5に変換する場合
pod5 convert fast5 [fast5へのパス] --output [pod5を出力するディレクトリ名] --one-to-one [location]

# 具体例: fast5/ディレクトリに大量のfast5があり、それを同じprefix.pod5に変換して、pod5というディレクトリに出力する場合
pod5 convert fast5 fast5/*.fast5 --output pod5 --one-to-one ./
```

ナノポアが提供するwebツールもある（未使用）
https://pod5.nanoporetech.com/


# doradoのインストール
基本的にgithubからバイナリ版をダウンロードして解凍・適当な場所におけばOK。
https://github.com/nanoporetech/dorado

遺伝研スパコンであれば、linux-arm64版をダウンロードする。
```
$ tar zxvf dorado-0.2.4-linux-arm64.tar.gz
$ mv dorado-0.2.4-linux-x64/ /home/hoge/opt/

# 普通のCPUノードで実行しようとするとちゃんとコケる
$ ./dorado-0.2.4-linux-x64/bin/dorado 
./dorado-0.2.4-linux-x64/bin/dorado: error while loading shared libraries: libcublasLt-b6d14a74.so.11: failed to map segment from shared object: Cannot allocate memory

```

# doradoをGPUノードで使う
UGEに投げたらcore dump吐いて失敗したので、とりあえずinteractive modeで実行するため、gpuノードにログインする。

遺伝研スパコンでのcudaの使い方に従って、
https://sc.ddbj.nig.ac.jp/software/cuda/

```
# cudaを1つ使用する場合
qlogin -l gpu -l cuda=1
```
でgpuノードにログインできる。

## configファイルをダウンロードする

nanoporeのbasecallerは、シーケンシングのモードによってconfigファイルが異なる。そのため、callingしたいシーケンシングの設定と同じconfigファイル(モデル)をダウンロードする。モデルの一覧は、dradoのgithubのページから確認できる。
今回は、MinIONのフローセルR10.4.1を260bps(accuarcy mode)で読んだので、dna_r10.4.1_e8.2_260bpsを選んだ。Guppyのconfigとは異なるので注意。

```
# configファイルを入れるディレクトリを作っておく
$ mkdir /home/hoge/nanopore_model

# 特定のモデルだけをダウンロードする場合
$ /home/hoge/opt/dorado-0.2.4-linux-x64/bin/dorado download --model dna_r10.4.1_e8.2_260bps_sup@v4.1.0

mv dna_r10.4.1_e8.2_260bps_sup@v4.1.0 /home/hoge/nanopore_model/

[hoge@gwB1 opt]$ ls /home/hoge/nanopore_model/ -lh
drwxr-xr-x 2 hoge hoge 4.0K  5月  1 13:48 dna_r10.4.1_e8.2_260bps_sup@v4.1.0
```
全てのモデル一括DLも可能。

## doradoのラン
基本のコマンドはguppyと同じ
```
dorado basecaller [configファイルのモデル] [入力ファイルのパス] [その他オプション]
```

テスト用の入力ファイルに、test/test.pod5を用意。
結果の出力はsam。

cudaは1つ使用。もしcudaを複数使用する場合は、qlogin時のquda=オプションの数に合わせる。qloginのqudaオプションは使用するcudaの数、basecallerのcudaオプションはどのcudaを使うかの番号指定なので、違いに注意する。
その他、引数やオプションに余計な空白があるとうまくいかないので注意。Macのメモでは、"--"が繋がった長い棒に勝手に変換されてしまうので、コマンドのコピペには気をつけよう。

```
# ベースコール
$ /home/hoge/opt/dorado-0.2.4-linux-x64/bin/dorado basecaller /home/hoge/nanopore_model/dna_r10.4.1_e8.2_260bps_sup@v4.1.0 /home/hoge/bascalling_dorado/test/ --device cuda:0> test.sam
[2023-05-01 14:41:05.891] [info] > Creating basecall pipeline
[2023-05-01 14:42:49.645] [info] > Reads basecalled: 12000
[2023-05-01 14:42:49.645] [info] > Samples/s: 1.959808e+06
[2023-05-01 14:42:49.645] [info] > Finished

# samをbamに変換
$ /home/hoge/opt/bin/samtools view -Sb test.sam > test.bam

$ ls -lh test/
-rw-r--r-- 1 hoge hoge 124M  5月  1 12:02 test.pod5
-rw-r--r-- 1 hoge hoge  18M  5月  1 14:42 test.sam
```
こんな感じでタイムスタンプの入ったログが見やすく出力されてありがたい。
【Swift】数値を桁ごとの配列に変換する方法

```swift
let num = 123
let numArray = Array(String(num)).map { Int(String($0))! }
print(numArray) // [1, 2, 3]
```
## 解説
```swift
let numArray = Array(String(num)).map { Int(String($0))! }
```
`123: Int` -> `"123": String` -> `["1", "2", "3"]: [String.Element]` -> `[1, 2, 3]: [Int]`という順番で変換している。
`$0`には`1,2,3`がそれぞれ`String.Element`型で入るため、一度`String`に変換した後`Int`に変換している。