OmniAICreator/Qiita-1.07M huggingface dataset:
AWSのデータベースまとめ

皆さんこんにちは！今回の担当のSです！
今回はAWSが現時点（2023年12月）で提供しているデータベースの種類についてまとめました。
AWSが提供しているデータベースのタイプは以下のようになります。


| DBタイプ | 主なサービス |
|:-:|:-:|
| リレーショナル  | Amazon Aurora |
|  キーバリュー | Amazon DynamoDB |
|  インメモリ | Amazon ElastiCache |
| ドキュメント  | Amazon DocumentDB  |
| ワイドカラム  |  Amazon Keyspaces |
|  グラフ | Amazon Neptune  |
| 時系列  | Amazon Timestream  |
| 台帳  | Amazon QLDB  |

【それぞれの用途】
1.リレーショナル
最も一般的なDBタイプ。　SEなりたてで一番最初に習うリレーショナルDBは主にこれです！

2.キーバリュー
eコマースやゲームアプリなど、小さなトラフィックが膨大にあるサービス向けのDBです。

3.インメモリ
インメモリデータベースとは、主に内部メモリを利用するDBのこと。キャッシュやセッション管理などのマイクロ秒の極めて低いレイテンシーが求められるサービスに利用されます。

4.ワイドカラム
キーと値の組み合わせなど、リレーショナルDBとは異なる方式で管理されるNoSQL型DBの一つ。大規模設備のメンテナンスや、ルート最適化などに利用されます。

5.グラフ
そのまんまグラフ型のデータベースのこと。リレーショナルDBでは表現しづらい複雑なDBを構築する際に利用されます。

6.時系列
IoTアプリケーションやリアルタイム分析など、時系列が重要かつ大規模なサービスに利用されます。

7.台帳
ブロックチェーンや銀行システムなどの、金融システムに利用されます。

## 最後に
上にあげた7種類の中でもさらに用途に応じて細かくDBが分かれていて、どのDBを利用するかでアプリやシステムの性能やコストが大きく異なるそうです。最適なサービスの選択ができることが、一人前のSEになるための必須条件であると言えますね。

はつかぜ株式会社では、IT学習や業務に役立つ情報を定期的にお届けしていきたいと思っています。
システム開発のお問い合わせ・ご相談はこちら
https://www.hatsukaze.co.jp/inquire/
Adobe FontsのフォントをMS Word,KeynoteなどAdobe以外のソフトで使う方法

# はじめに
Adobeフォント愛用者の僕が、WordやKeynoteでも、イケてるフォントを使いたい！と思い調べたものの、文章量の多い記事しか見つからず、備忘録程度に書きます。

# 1. AdobeFonts から希望のフォントを追加！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664651/3357eeeb-67cc-d19e-65e5-e29c24868ab3.png)

AdobeFontのフォントを追加ボタンを押すだけでは、Adobeのソフトのみのアクティベートで、外部ソフトまではアクティベートできていません。
そこで、CreativeCloud側で操作する必要があります。
(実は、ポップアップで、説明が出てきているのですが、見逃したり、非表示にしてたりするかも？）

# 2. CreativeCloudから、他社アプリもアクティベート
CreativeCloudを立ち上げ、右上の f アイコンをクリック！
フォントファミリーごとインストールすることができます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664651/c3f986d5-9016-3032-771d-2ecbfd531fbd.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664651/14d073e1-fe09-9402-34ac-dead125ca790.png)

現在、使用したいアプリが立ち上がっている場合、一度閉じてから開き直すと使用できると思います。

ちなみに、FontBookからは、見ることができない？ので、見る方法知っている方いらしゃったら、教えていただきたいです。
Androidエンジニアが間違いやすい英単語4選

## Whats this?

エンジニア同士の会話の中でちょっと違和感のある、あの英単語の読み。
正確にはどっちなの？ということでピックアップしました。


## Linear

⭕　リニア
❌　ライナー

例）
LinearLayout -> リニアレイアウト

## Modifire

⭕　モディファイア
❌　モディフィア

## Disable

⭕　ディセイブル
❌　ディスアブル


## Constraint

⭕　（厳密には）コンストレイント、人によっては「コンストレイン」の場合もある
❌　コントレイント


## 雑記

日本語カタカナ表記にすると無声音の「s」を「ス」としていいか迷うところ
Constraintは英語のネイティブスピーカーが話すとほぼ「コンストレイン」に聞こえる
Office 365 で ZIP ファイルが添付されたメールを受信拒否する

# メールフロールール設定
以下のように設定が可能です。

https://admin.exchange.microsoft.com/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/92b5b7c1-bb9c-5867-47fe-35fcd8447f33.png)

以下のような条件設定が可能です。

拒否用のメッセージは「`※拡張子"zip"のファイルが添付されたメールは受信できませんので、ご容赦ください。`」とします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/a104989f-9a34-c4d9-1927-13913feb0f8c.png)

最後に作成したルールを有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/229604b2-78c7-cd3d-fe4e-9147bf6eaf88.png)

## 【参考】その他設定可能な条件
以下のリンクに詳細がありますが、いくつかキャプチャを載せておきます。

- [Exchange Online のメール フロー ルールでの条件と例外 (述語) | Microsoft Learn](https://learn.microsoft.com/ja-jp/exchange/security-and-compliance/mail-flow-rules/conditions-and-exceptions)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/7cac6b94-9e33-e63a-7b04-fc1b33b01518.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/f130e474-8588-8b0f-4018-60606c21a406.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/b0784845-f3a0-8585-621b-8996d2512ffb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/8beea288-ba14-6220-ae25-1e314c21c196.png)

# 確認
実際に ZIP ファイルをメールに添付して送った結果をメッセージ追跡で確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/91512892-8017-1d32-38f0-0968247dc984.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/3aa86618-28e3-7c90-a404-6faf6125a477.png)

送信者側には、以下のようなメールが届きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/d2bdc729-d884-216e-9d74-c59eb3475ab3.png)

# 参考

- [Microsoft 365 でパスワード保護ファイルを拒否してみた](https://www.jpaawg.org/docs/event/2021ppap/20210225-LT-softest%EF%BC%88%E5%85%AC%E9%96%8B%E7%89%88%EF%BC%89.pdf)
オプションのついたg++をPowerShell上で素早く実行する

# 実現したいこと
``` powershell: PowerShell
g+ a.cpp
```
を実行した際に
``` powershell: PowerShell
g++ -std=c++20 -g -Wall -Wextra -Wshadow -Wfloat-equal -Wno-char-subscripts -ftrapv -fno-omit-frame-pointer -fno-sanitize-recover a.cpp
```
が実行されるようにg+を定義したいです。

# 方法
``` powershell
$PROFILE
```
を実行してPowerShellのプロファイルスクリプトがあるパスを調べます。
そのスクリプトをメモ帳などで開きます。
実行したいコマンドが引数付きなのでfunctionを使って定義します。
``` Microsoft.PowerShell_profile.ps1
function g+ (){
    g++ -std=c++20 -g -Wall -Wextra -Wshadow -Wfloat-equal -Wno-char-subscripts -ftrapv -fno-omit-frame-pointer -fno-sanitize-recover @args
}
```
以上です！

# 参考記事
https://triple-four.hatenablog.com/entry/20210623/1624458051

https://tks2.co.jp/2020/04/05/power-shell/
MySQLのUnique Key変更で外部制約キーが問題になった経験と対処法

:::note info
本記事は [ZOZO Advent Calendar 2023 シリーズ 7](https://qiita.com/advent-calendar/2023/zozo) の 13 日目の記事です。
:::
## 概要
MySQLのUnique Keyの変更時に外部制約が絡んで、手こずった経緯を備忘録としてまとめます。

## 前提
以下のようなテーブルを想定します
```
CREATE TABLE module_config (
       id                       BIGINT         AUTO_INCREMENT,
       module_id                BIGINT         NOT NULL,
       gender                   VARCHAR(20)    NOT NULL,
       device                   VARCHAR(20)    NOT NULL,
       position                 INT            NOT NULL,
       created_at               DATETIME       NOT NULL    DEFAULT CURRENT_TIMESTAMP,
       updated_at               DATETIME       NOT NULL    DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
       PRIMARY KEY (id),
       FOREIGN KEY (module_id) REFERENCES modules (id) ON DELETE CASCADE ON UPDATE CASCADE,
       UNIQUE (module_id, gender, position)
);
```

このときUNIQUEの設定を以下のように変更したい

```
UNIQUE (module_id, gender, device)
```

## やったこと
既存の UNIQUE KEY を制御するために制約名を調査しました。UNIQUE KEYに制約名を指定していなかったことが原因で、変更や調査が複雑になっていました...

```
mysql> SHOW CREATE TABLE module_config;

| module_config | CREATE TABLE `module_config` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `module_id` bigint NOT NULL,
  `gender` varchar(20) COLLATE utf8mb4_bin NOT NULL,
  `device` varchar(20) COLLATE utf8mb4_bin NOT NULL,
  `position` int NOT NULL,
  `created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
  `updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`),
  UNIQUE KEY `module_id` (`module_id`,`gender`,`position`),
  CONSTRAINT `module_config_ibfk_1` FOREIGN KEY (`module_id`) REFERENCES `home_modules` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin |


```
ここで、UNIQUE KEY の制約名は module_id と判明しました。定義していなかった場合は自動でデフォルトでカラム名が利用されるんですね。（知らなかった）
次に、UNIQUE KEY の制約名である module_id を用いてUNIQUEの削除を試みると、module_id は外部制約キーとして扱われているため削除できませんでした
```
mysql> ALTER TABLE module_config DROP INDEX module_id;

ERROR 1553 (HY000): Cannot drop index 'module_id': needed in a foreign key constraint
```

この問題の解決には、外部制約キーを一時的に削除する必要があります。以下が対応手順です。

外部制約キーを削除します。

```
mysql> ALTER TABLE module_config DROP FOREIGN KEY module_config_ibfk_1(外部制約キーの名前);
```
既存の UNIQUE KEY を削除します。

```
mysql> ALTER TABLE module_config DROP INDEX module_id(UNIQUEキーの名前);
```
変更後の UNIQUE KEY を追加します

```
mysql> ALTER TABLE module_config ADD UNIQUE INDEX unique_module_config (module_id, gender, device);
```

外部制約キーを再度追加します。

```
mysql> ALTER TABLE module_config ADD FOREIGN KEY (module_id) REFERENCES modules(id);
```
これにより、一時的に外部制約を削除し、その後 UNIQUE KEY を削除し、修正した UNIQUE KEY を追加した後、最後に外部制約を再追加することで問題が解決されました。

## 終わりに
今回はUNIQUE KEYの名前を指定しなかったことから、自動でデフォルトの制約名と外部制約キーが同名になりややこしくなりました。今後はUNIQUE KEYを設定する際はきちんと制約名を定義するよう心がけます。
ディレクトリ構成図の表示＆書き出し

## treeのインストール
Mac
```
$ brew install tree
```
※windowsでは、デフォルトで`tree`がインストールされている


## ディレクトリ構成図を表示する
```
$ tree .
```

## ディレクトリ構成図をテキストファイルに書き出す
```
$ tree -l > tree.txt
```
[core/duplicate-app] a firebase app named "[default]" already exists の解決方法

# 問題点
以下のコードでエラーが発生した。
```dart:main.dart
await Firebase.initializeApp(
    options: GlobalConfigs.instance.firebaseOptions,
);
```

```
[core/duplicate-app] a firebase app named "[default]" already exists
```

# 調査
以下の記事では解決できず
- [Firebaseのインスタンスが１つになるように調整する方法](https://stackoverflow.com/questions/43331011/firebase-app-named-default-already-exists-app-duplicate-app)
- [flutterfireをもう一度実行する方法](https://zenn.dev/flutteruniv_dev/articles/ed4ddc7b5249bc)


以下の記事を参考に`initializeApp()`に`name`を設定して`Firebase.apps`のインスタンスを調べるとインスタンスを二つ生成していることがわかった。
```dart:main.dart
await Firebase.initializeApp(
    name: 'hoge',
    options: GlobalConfigs.instance.firebaseOptions,
);
print(Firebase.apps.length) // 2

```
- https://dev.classmethod.jp/articles/what-to-do-when-the-a-firebase-app-named-default-exists-exists-error-when-running-the-flutter-app-on-ios-part-2/

# 原因
iOSでは`GoogleService-Info.plist`と`firebase_options.dart`を二つ参照する。
私の場合はXcodeの`Runner > TARGETS(RUNNER) > Build Settings > Build Phase > Copy Bundle Resouces`で`GoogleService-Info.plist`を含めていた。

# 対策&解決
上記をCopy Bundle Resourcesから削除する。

![スクリーンショット 2023-12-12 16.18.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1092613/f9a40187-86f4-aedd-d12c-d8cbef31ad64.png)
初めてのGit


## 初心者にはイメージがつかない、なぜGitを使うのか

なぜ、Gitというスキルが不可欠なのか疑問な方はいますか？

`２つしかありません`

```
①ソースコードを前回コミットした状態に戻せる（セーブ機能）
②GitHubにアップして、他人同士でソースコードを共有できる（共同開発機能）
```

だけです


Git及びGitHubの習得とは、これができるようになること。Gitを用いて


## セーブ機能の解説とコマンド


#### ① ソースコード編集したのち、やっぱり前回の状態に戻したい時。
```
git restore
```



## 共同開発機能の解説とコマンド及び操作




## GitHubとは

ソースコードとコミットの全履歴が、記録できる

Gitから、GitHubへアップすることで、他人と共有もできるし、自分用という使い方もできる


ここで言うアップとは、具体的には、プッシュと呼ばれる



## 開発の流れ

これから、Gitの使い方について説明したいところですが、

その理解をするには、開発の流れを知らないとならないので、先に開発の仕方について説明します。


## Gitの使い方

### ①branchを使いこなす

branch（ブランチ）とは、全ファイルのコピー


### ②マージを使いこなす


1. トピックブランチで、
```

```

```

```

```

```



## Gitメモ


：コミットするときは、コミットメッセージを英語で、現在形かつ命令形で書く
そうすると、そのコミットが「何をした」のかではなく、「何をする」ためのものなのかということが、見返したときに分かりやすくなる





## 今回の記事の参考文献


[Railsチュートリアル](https://railstutorial.jp/chapters/beginning?version=7.0#fig-MVC)
【Azure AI Document Intelligence】Custom classification modelsでいろいろ試す

# はじめに
前回は1ページのPDFに対して分類ラベルを設定し、ドキュメントの分類ができるかを試しました。
今回は複数の分類が含まれているPDFに対してDocument Intelligenceを試すと、それぞれのページごとの分類はどうなるかを見てみました。
(うまく日本語で説明できないので、以下に図をかいてみます。)

前回の記事

https://qiita.com/usomaru/items/36cb3fc3aaece6da1f02

# やったこと
このように1つのPDFファイルの中に、違う分類のドキュメントが存在する場合(PDFのページ数としては図の場合3ま)、分類分けはどのような結果になるかを試しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201826/6b21f12c-66b8-0cec-76ca-7bb5dded2d9c.png)


# 試した手順
前回の記事と同様にプロジェクトを作成し、該当するリソースを選択しました。

今回は複数ファイルの内容を1枚ずつ分割し、1枚づつラベル付けをしていきます。

例：1ページ目が請求書・2ページ目が注文書・3ページ目が納品書だった場合
1. PDFを分割
1. 1ページ目のPDFに請求書というラベルをつける
1. 2ページ目のPDFに注文書というラベルをつける
1. 3ページ目のPDFに納品書というラベルをつける

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201826/0b87dc20-c204-585e-ca16-36f721df5768.png)

ラベル付けが終了したらTrainします。
終了したらTestをしてみます。

分割前の複数ドキュメントPDFでOCRしてみます。
ページごとにどの分類のドキュメントかを当ててくれました！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201826/222a3f86-5533-d394-f9e3-5a5e342b4d58.png)


# おわりに
複数ページあっても1枚1枚に対して該当する分類を教えてくれるのはわりと便利なのではないかと思いました。
カスタムモデルに関する記事はあまり見かけないのですが、便利な機能だと思うので取り入れられるところでは積極的に取り入れていきたいところです。
既存プロジェクトをOculus IntegrationからMeta XR SDKに移行した話

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413932/29457217-cbeb-154d-7d18-e61aee4a2d61.png)

# 経緯
2023年11月9月に[Meta XR SDK](https://assetstore.unity.com/publishers/25353)が正式公開されました。これに伴って[Oculus Integratin](https://assetstore.unity.com/packages/tools/integration/oculus-integration-deprecated-82022)は非推奨となりました。
Oculus IntegrationはこれまでQuest向けアプリを作る際に散々お世話になったし、また1つOculusの名前が消えるのが寂しいです。

弊社では10月末から動き出したQuest向け開発のプロジェクトでOculus Integrationを使っていました。このプロジェクトをMeta XR SDKに移行する際にやったことと詰まったことをご紹介します。

# Meta XR SDKとは
Metaが公開しているxR開発用のUnity向けSDKです。Quest向けだけでなく、VR、MR開発で汎用的に使えるコンポーネントも含まれています。
UPMで提供されており、Asset Storeからだったりパッケージマネージャーで名前を指定してインストールしたりできます。
いくつかのパッケージに分かれており、その中から必要なものだけをピックアップしてインストールすることができます。

中身は基本的にOculus Integrationと同じですし､各ファイルのGUIDが同じなのでそのまま入れ替えで動きます｡

# MetaXR SDKに移行するメリット
- 今後、Quest向けの新機能が出た時にMeta XR SDKでしか使えない可能性が高い
- UPMなので取り回しやすい
  - インストール、アンインストールが楽
  - 自然とgit管理対象外になるためリポジトリを小さく保てる
    - GitHubでリポジトリを作る時にUnity用の.girignoreをテンプレートから生成していれば対象外になる
- 改変できない
  - Packagesディレクトリ配下は編集してもUnityによって自動的に元に戻される
  - SDK側のコードを改変できてしまうと出来心で行ったちょっとした変更がSDKの更新を阻害する

# 移行手順
1. Oculusディレクトリ配下のSampleFramework以外のディレクトリを削除する
1. Meta XR SDKを入れる
    - Core SDKは必須
    - 必要であればInteraction SDKやInteraction SDK OVR Integrationなどを入れる
    - 何が必要か分からなければAll-in-One SDKを入れる

# 詰まったこと
## SampleFrameworkが無くなっている
Oculus Integrationの多彩なサンプル実装が含まれたSample FrameworkディレクトリはMeta XR SDKに存在しません｡
UIHelperプレハブやCustomeHandプレハブを使い続ける場合はこのディレクトリを残しておきましょう｡

## どのSDKを入れればいいかわからない
Meta XR SDKは種類が多いです｡今回使ったパッケージとその役割は以下の通りです｡

- [Meta XR Core SDK](https://assetstore.unity.com/packages/tools/integration/meta-xr-core-sdk-269169)
  - 基盤部分
  - Oculus IntegrationのVRディレクトリと大体同じ
- [Meta XR Interaction SDK](https://assetstore.unity.com/packages/tools/integration/meta-xr-interaction-sdk-264559)
  - 物を掴んだりボタンを押したりする機能
  - Questに限らない抽象的な設計になっている
- [Meta XR Interaction SDK OVR Integration](https://assetstore.unity.com/packages/tools/integration/meta-xr-interaction-sdk-ovr-integration-265014)
  - Interaction SDKをQuestで使うためのプレハブなど

各SDKにはUPMの機能により､依存関係が設定されています｡
例えば､Interaction SDK OVR IntegrationをインストールするとCore SDKとInteraction SDKも自動で入ります｡
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/413932/013f9f9b-de55-8ced-f26a-8a4b4ecfa526.png)

# まとめ
SDKのアップデートは最新版と差が大きく開いてからだと圧倒的に大変なので今のうちにやることをおすすめします｡

# お知らせ
弊社は現在､xRエンジニアを募集中です｡
請負案件や自社プロダクトのVRゲームを開発できます｡
是非一緒に働きましょう！
その他の職種も随時募集中です｡
https://www.wantedly.com/projects/1543523
ユーテー　アイテー　ピーテー　オーテー

[インターネット老人会の魔法書 Advent Calendar 2023](https://qiita.com/advent-calendar/2023/ancient-internet) の3日目の記事です。

# Tはテー

Dをデーと呼ぶように**Tはテーと読みます**。
昔の人は **"ィ"** を意地でも読みたくないようです。

## ユーテー

UT=Unit Testのこと。
元々は単一の機能のテストを指すと思うのですが、ローカル開発環境でのテストを指します。

## アイテー

IT=Integration Testのこと。
日本語では結合試験と訳されることが多く、いろんな人が作った機能を統合したものをテストすることを指します。
大規模プロジェクトでは、1チーム内での機能をまとめたテストを指します。
ここまでは安心してバグを出せます。

## ピーテー

PT=Product Testのこと。
日本語では総合試験と訳されることが多く、その製品の全機能が含まれた状態のテストを指します。
いわばステージング環境のテストですね。
大規模プロジェクトではここでバグを出すと、始末書的なバグ票を切らされたりします。

## オーテー

OT=Operation Testのこと。
日本語では出荷試験や運用試験と訳されることが多く、本番環境または本番環境同等の環境でのテストを指します。
発注先の人が最終的に完了を認めるかどうかのテストになることが多いので、承認テストや受入テストなどとも呼ばれたりします。
大規模プロジェクトではここでバグを出すとめちゃめちゃ問題になります。バグ出したチームの責任者が偉い人が集まる会議に呼ばれ弾劾されます。
visual Studioの項目テンプレート追加方法（C＃）

何回も繰り返す作業はテンプレ化して効率化を図る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/0b8b1c1a-afcc-8693-f290-1583363c3a33.png)
項目のテンプレートはこんなやつ

## テンプレ用のプロジェクト作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/0da20045-c567-81e0-0441-d17398d26e47.png)
ファイルから適当にプロジェクト作成
## テンプレ用のcsファイルを作る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/d1227a90-6845-104a-f0db-91becd619924.png)
$$で囲まれたパラメータを利用するとスマート
パラメータの詳細は[公式へ](https://learn.microsoft.com/ja-jp/visualstudio/ide/template-parameters?view=vs-2022)

## テンプレ化する
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/836b20cd-a31b-e446-9ba3-e3af2737498e.png)
プロジェクト＞テンプレのエクスポート
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/b52765fd-1a49-961c-975d-4e14fba75a51.png)
項目テンプレートにチェック＞次へ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/c3de09b9-ec01-d6ef-8177-dc8f4c63c022.png)
テンプレ化したいcsファイルを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/81e41366-3abf-aaa8-7b33-35009c6384fb.png)
選択不要。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/3f51677f-cfca-a930-3927-b9137dde8bd1.png)
テンプレート名：テンプレにしたい名前
テンプレートを自動的に　チェック
完了後VSを***再起動***で追加される。
すごいよ、EC-CUBE

## 永い言い訳
2019年10月にイーシーキューブに入社した僕が、2020年に育休を取得する際に書いたイーシーキューブメンバー向けのラブレターです。
当時は、なんだかんだあって、結局のところ勇気が足りずこの文章を公開するに至らなかったのですが、今回　~~アドベントカレンダーの記事作成が間に合わず~~ 勇気をもって公開してみようと思います。
非エンジニアの僕が、なぜイーシーキューブに魅力を感じ、入社に至ったかについて記載させていただきました。
社内向けの文書につき、さむい文体が続きますがご容赦ください。


## 以下当時(2020年)の文章
おつかれさまです。

まずは、みなさま、今回は、わたくしめの事情を汲んでくださり約1.5ヵ月に渡る育休 について快く送り出してくれて本当にありがとうございます。

今回で3人目（3姉妹!!）となる中、僕と妻それぞれの兄弟のベビーラッシュと重なり親リソースも難しい状況だったので大変ありがたいです。

そして、今回二つ返事で快諾してくれたことの何が会社としてすごいかというと...

 **うちって9月決算で...** 
 **10月から新年度です...よね？**

ただでさえ忙しくやることの多いこの2ヵ月。
そんな中、本当に申し訳ないです＆その100倍のありがとうございます！

たった1.5ヵ月されど大事な1.5ヵ月をお休みするにあたり、ちょっと私が常々思っていることをお伝えさせてもらいたいです。

こんなテーマです。

### EC-CUBEのビジネスモデルの何がすごいか

＜おさらい＞

1年しかいないお前に言われたかねぇよ。とヤジを投げる人は幸いこの会社にはいなさそうなので、今更ながら簡単に。

僕たちの現行のビジネスモデルは
**フリーミアム × 成果報酬** 
です。

EC-CUBEという無料のEC構築オープンソースがあり、自由にダウンロードでき、イーシーキューブとの契約なく利用可能で、ネットショップがつくることができます。

なんとここまでの流れで、イーシーキューブに入るお金は、驚愕の 0円 です！　[フリーミアムモデル]

ネットショップのほとんどは、決済サービスを導入します。クレジットカードで買い物できるようにしたりするアレです。

ネットショップは、どこの決済サービスを選んでも問題ありません。（さらっと言ってるけどココすごい！）

そして、決済サービスが導入され、その決済サービス経由の売上が発生したときはじめて、幾分かのマネタイズができます。

つまり、ネットショップ様は自社の成果（売上）に応じた対価を我々にお支払いただくということになります　[成果報酬モデル]（※1）

※1）正確にはネットショップ様から直接対価をいただくのではなく、ネットショップ様が決済サービス事業者様に支払った更に何%かがイーシーキューブに入る（そのため、ネットショップ様が余分に支払っていただいている訳ではない）

おさらいするだけで、こんなに時間かかっちゃいました。。

＜ **本題** ＞

では、EC-CUBEの何がすごいかというと、メインサービスを無料化している点 です。

多くのフリーミアムモデルを採用した企業から提供されるサービスは、機能だったり利用期限だったりなんらかの制限がかかってることが多いです。

ですが、EC-CUBEは違います。
本丸商品を無料提供しております。
#最初のビール1杯無料なんて生温い
#うちは蟹が無料だよ
#その代わり自分で切って焼いて剥いて食べてね

EC-CUBEが生まれた2006年、そして現在に至るまで、EC構築システム業界においてこのモデルは未だ珍しいですが、
僕はこの「メインサービスを無料化する」流れって確実にビジネスのデファクトスタンダードになっていくと考えています。

その背景はこんなかんじです。
+ 今は情報が誰でも簡単に入手でき、新しいサービスを世に出してもキャッチアップされ模倣されるまでの期間が短くなった。
+ この環境下では、なかなかサービスの質そのもので他社を圧倒するのは難しい。
+ また、テクノロジーの進化により生産コストは格段に下がり、低価格サービスが生まれやすくなり更には、限界費用ゼロ社会 なんてことも言われ始めた。（知らんけど）
+ いくらサービスの質を高めようとすぐ追いつかれる。低価格合戦はヒートアップ。。
+ その延長線で考えたらメインサービスであっても「よし！無料で配ろう」って考える人が増えても当然。
+ というか広告費等を考えたら「よし！お金あげてでも配ろう」って企業も出現します。（お金配りおじさんいましたね）

そんな市場状況になったとき・・・
 **あれ？EC-CUBE、強くない？？（ﾆﾔﾘ）** 

とはいえ、これから業界がどうなっていくか、
EC-CUBEというプロダクトがどうなっているか、
そんなことは誰にも分かりません。

しかし、我々は何事にも代えられない、このモデルで黒字経営を続けたという **実績** と、
このモデルを支えてくれている **パートナー様** がいます。

これだけはいくらテクノロジーが進化しても、一朝一夕で模倣できるものではありません。

だから僕たちは、踏ん張り続ける価値があります。
長い目でみて、いつかくる最高の戦況に備えて。
パートナーさんもネットショップさんもみんな儲かってしゃーない日々になるように。

そのために、このビジネスモデルにおけるセールススキームを確立するという今の目標を達成しなければいけません。

そんな風に考えています。

・・・

アツくなりました。。これまでで1番の長文です。。

最後にまとめます！！

イーシーキューブ（EC-CUBE）は、EC業界における稀有なビジネスモデルで事業を継続できているこの事実に圧倒的差別化があり、これからもっと競争優位性が出てくると思っています。

だから、みなさん！FY21も引き続き誇りをもって一緒に頑張りましょーーーーーっ！！
♫む〜す〜ん〜で〜　かんけ〜い〜(関係)で〜♪

# 目次
- [前回の振り返り](#前回の振り返り)
- [テスト業務における「関係で結ぶ」こととは](#テスト業務における「関係で結ぶ」こととは)
- [課題](#課題)
- [おわりに](#おわりに)

# 前回の振り返り

前回の投稿「[テストすべき対象を「並べる」　〜TM技術を使ってモデルベースドテストの可能性を考える(第2回)〜](https://qiita.com/YukTak/items/1f8b5e9dada97beb6c9d)」にて、「**モノの並べ方**」を解説しました。
今日は、並べたものを「**関係で結ぶ**」ことをテスト対象に対してどのように結ぶかを書いていきます！

参照元は、[事業分析・データ設計のためのモデル作成技術入門](https://gihyo.jp/book/2022/978-4-297-12946-0)から学んだことから書いていきます。

[<img width = 200 src = http://image.gihyo.co.jp/assets/images/cover/2022/9784297129460.jpg>](https://gihyo.jp/book/2022/978-4-297-12946-0)

# テスト業務における「関係で結ぶ」こととは
結び方を書く前に、「テスト業務において、**関係**とはどのようなものなのか？」について書いていきたいと思います。

主に、2つのことがわかってくるものと考えます。


:::note info
- **「濃度」**：テスト対象の規模感がわかる
- **「順序」**：テスト対象の流れがわかる
:::


EventとResourceの数 = **各集合の数**で、全体の規模感を表していますが、関係で結ぶことによって「**関連の数** = **集合同士が関連する数**」を表すことが出来ると思います。

元々、集合論における**濃度**とは「**有限集合において、"元の数"を一般の集合に拡張したもの**」であり、その様式でここで表すと、EventとResourceの「**要素の数**」を指すことになります。


ただ、テスト業務においては「1つの機能が、他の機能に対して**どれくらいの機能が関連しているか**」。もっというと、「**テスト対象の1つの要素が、他の1つの機能に影響するのか。または、多くの機能に影響するのか**」といった、**影響の数**を考慮することがあります。

これはテスト計画や分析、特に**テスト設計**においては以下の事を考慮して、テスト設計することがあります。


:::note info
テスト設計で考慮する、主なこと
- 組み合わせのパターン(テストマトリクスなどの導出)
- デシジョンテーブルの条件
- n因子間網羅の要素や水準の数
:::


上記を考慮し、テスト技法を用いてテスト設計は実行していきます。その際に、1枚の絵(TM技術で表した現実的写像 = システム・プロダクトのモデル図)で見れたほうが、パッと見れてその量感がわかりやすいと考えます。



**順序**については、「**順番をある基準で並べたもの**」と考えると以下のことがわかると考えます。

:::note info
- 機能同士の帰属関係
- 処理の順序
- その処理のやり取りの方向(一方向なのか、双方向なのか)
:::


これも、テスト設計やテスト実装において**テストケースの実行する順番**を記述する際に、作成したモデル図から導出して記述できると考えます。




# 課題
とはいえ、当初から言及している「**パッと見てとれる**」ことに対して有用に思えるモデル図ですが、課題として「**テスト観点漏れ(テスト対象の機能の内容を見落として観点が抜ける)の心配はないのか？**」という点が挙げられると思われます。テスト設計において、テスト観点漏れは「**一番気をつけなければならないこと**」なので、この記事を読んでいる方にとっては、心配事の一つといえます。

また、他にも課題がいくつかあると考えられますがその件については、今後の記事にて、実際の現場での使用感や所感などを含めて書いていこうと思います。


# おわりに
記事投稿が遅れてしまい、申し訳ないです。
前回の記事投稿から、いろいろとアクティビティが増えました(笑)

その中で、JSTQB Foundation Levelを合格し、やっとこさテストエンジニア・QAエンジニアとして「一人前」をもらったような気がして、ますます記事投稿に対して気が引き締まる思いであります。


次の投稿ではいよいよ、「**関係の結び方**」について投稿する予定です！
2023年中に、投稿できるよう頑張ります！(できたら、いいなぁ)


ここまで、読んでくださりありがとうございます！


では、また！
【Rails】Active Adminの管理画面にVueを導入する方法

:::note info
本記事では、管理画面のUI/UX向上を目的として、RailsのActive AdminにVueを導入する方法について紹介します。
:::

# 注意事項
Rails、およびVueプロジェクト立ち上げ方については本記事では触れません。また、今回はVueのビルドツールとしてViteを採用しています。Webpackでは動作しませんので、ご了承ください。

# 本題
管理画面にVueを適用するためには、最低限HTMLファイル上で以下２つの設定する必要があります。
- VueをマウントするためのHTML要素の用意
- バンドルされたJSファイルとCSSファイルのインポート

しかし、Active AdminはDSL(ドメイン固有言語)であり、通常直接HTMLファイルを編集することはありません。Rubyのコードを基にHTMLが自動生成されます。

ですが、抜け道として[カスタムページ](https://activeadmin.info/10-custom-pages.html)という機能が用意されており、任意のhtmlファイルを表示させることが出来るので、これを使用します。

```ruby:sample.rb
ActiveAdmin.register_page 'Sample' do
  content do
    # ここで読み込みたいhtmlファイルを指定する。
    # ファイル名の先頭はアンダーバーにする必要あり。(_index.html)
    render partial: 'admin/sample/index'
  end
end
```

↑で登録したhtmlファイルに対して、先ほど述べた２つの設定を記述してきましょう。


```erb:_index.html.erb
<div class="panel" id="app"> // VueをマウントするためのHTML要素
</div>

<%= csrf_meta_tag %> // CSRFを防ぐための呪文

<% if Rails.env.development? %>
  <script type="module" src="http://localhost:3030/src/main.ts"></script>
<% else %>
  <% hash = File.open("#{Rails.root.to_s}/public/api/sample/manifest.json") { |f| JSON.load(f) } %>
  <script type="module" src="/api/sample/<%= hash["src/main.ts"]["file"] %>"></script>
  <script>
    const link = document.createElement('link')
    link.rel  = 'stylesheet'
    link.href = "/api/sample/<%= hash['src/main.css']['file'] %>"
    document.getElementsByTagName('head')[0].appendChild(link)
  </script>
<% end %>
```

ここでポイントとなるのは、JSファイルの読み込み方法です。開発環境と本番環境で方法が異なります。

開発環境の場合、Viteを実行すると、現在の作業ディレクトリをルートとしたサーバが起動します。ので、例えばルートディレクトリに`package.json`があるならば、ブラウザURLに`http://localhost:8080/package.json`と入力すれば、画面にはその中身が表示されるかと思います。

ここではVueのエントリーファイル、即ちVueアプリの作成&マウント処理を行っているJSファイルをインポートします。特別なカスタマイズをしていなければ、`src/main.ts`が、それに該当するはずです。

```typescript:main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index.js'

const app = createApp(App) // Vueアプリの作成
app.use(router)
app.mount('#app') // アプリのマウント
```

一方、本番環境ではリソースのバンドルが行われるので、ファイル名および出力先が開発環境と異なります。また、本番環境ではビルド毎にファイル名にハッシュ値が付与されるため、ファイルパスをハードコーディングすることが出来ません。

そこで、ビルド毎に生成されたファイル名を取得したいというユースケースに応えるため、Viteではビルド時に`manifest.json`というファイルを一緒に生成してくれます。Rails側からこのファイルの中身を読み込みましょう。

```json:manifest.json
{
  "src/main.css": {
    "file": "assets/main-f957ddef.css",
    "src": "src/main.css"
  },
  "src/main.ts": {
    "css": [
      "assets/main-f957ddef.css"
    ],
    "file": "assets/app-19789f2f.js",
    "isEntry": true,
    "src": "src/main.ts"
  }
}
```

ちなみにビルドの出力先ですが、今回はpublicディレクトリを使用しています。publicディレクトリはRailsの静的ファイルを格納する場所で、これらのファイルはアプリケーションのルートURLから直接アクセスできます。

publicディレクトリにバンドルファイルを出力するよう、Vite側の設定も変更しておきましょう。これは[vite.confing.tsのoutDir](https://ja.vitejs.dev/config/build-options.html#build-outdir)で指定できます。
```ts:vite.config.ts
export default defineConfig({
  plugins: [vue()],
  build: {
    manifest: true, // manifest.jsonの生成を有効にする
    outDir: '../public/api/sample',
  }
}
```

設定は以上になります。localhost:3000の該当ページにアクセスして、Viteの初期ページが表示されるか確認してみてください。

# 参考
https://activeadmin.info/10-custom-pages.html

https://ja.vitejs.dev/config/build-options.html
AtCoder Beginner Contest 332 C T-shirts を Elixir と C で解いてみた

AtCoder Beginner Contest 332 C T-shirts を Elixir と C で解いてみたので，ご報告します．

## アルゴリズムの解説

1. 変数$a, b, c, d$を用意します．$a$は洗濯された無地のTシャツの数，$b$は洗濯されたロゴ入りTシャツのストック数，$c$は着用済みの無地のTシャツの数，$d$は着用済みのロゴ入りTシャツの数です．
2. 初期値として，$a = m$とし，$b = c = d = 0$とします．
3. 文字列を先頭から順番に走査します．
    * '0'の時: 洗濯するので，$a = a + c$, $b = b + d$, $c = 0$, $d = 0$とします． 
    * '1'の時:
        * $a = b = 0$の時: ロゴ入りのTシャツを購入して着るので，$d = d + 1$とします．
        * そうでなくて$a = 0$の時: 洗濯されたロゴ入りのTシャツのストックを着るので，$b = b - 1$. $d = d + 1$とします．
        * そうでない場合: 洗濯された無地のTシャツを着るので，$a = a - 1$, $c = c + 1$とします．
    * '2'の時:
        * $b = 0$の時: ロゴ入りのTシャツを購入して着るので，$d = d + 1$とします．
        * そうでない場合: 洗濯されたロゴ入りのTシャツのストックを着るので，$b = b - 1$, $d = d + 1$とします．
4. 最後に$b + d$を表示します．

## Elixirでの解答

https://atcoder.jp/contests/abc332/submissions/48441471

文字列はあらかじめタプルにしておきます．関数パターンマッチと`Enum.reduce`で素直に実装できます．

```elixir
defmodule Main do
  @zero "0" |> String.to_charlist() |> hd()
  @one "1" |> String.to_charlist() |> hd()
  @two "2" |> String.to_charlist() |> hd()
  
  def main() do
    [n, m] =
      IO.read(:line)
      |> String.trim()
      |> String.split()
      |> Enum.map(&String.to_integer/1)
      
    s = 
      IO.read(:line)
      |> String.trim()
      |> String.to_charlist()
      |> Enum.map(fn
        @zero -> 0
        @one -> 1
        @two -> 2
      end)
      |> List.to_tuple()
      
    0..n-1
    |> Enum.reduce({m, 0, 0, 0}, fn i, acc -> plan(s, i, acc) end)
    |> then(&elem(&1, 1) + elem(&1, 3))
    |> IO.puts()
  end
  
  defp plan(s, i, state), do: plan(elem(s, i), state)
  
  defp plan(0, {m, l, wm, wl}) do
    {m + wm, l + wl, 0, 0}
  end
  
  defp plan(1, {0, 0, wm, wl}) do
    {0, 0, wm, wl + 1} 
  end
  
  defp plan(1, {0, l, wm, wl}) do
    {0, l - 1, wm, wl + 1}
  end

  defp plan(1, {m, l, wm, wl}) do
    {m - 1, l, wm + 1, wl}
  end
  
  defp plan(2, {m, 0, wm, wl}) do
    {m, 0, wm, wl + 1}
  end
  
  defp plan(2, {m, l, wm, wl}) do
    {m, l - 1, wm, wl + 1}
  end
end
```

## Cでの解答

https://atcoder.jp/contests/abc332/submissions/48441846

```c
#include <stdio.h>

int main()
{
  int n, m;
  int d1 = scanf("%d", &n);
  int d2 = scanf("%d", &m);
  
  char s[1001];
  int d3 = scanf("%s", &s);
  
  int a = m, b = 0, c = 0, d = 0;
  
  for (int i = 0; i < n; i++) {
    switch (s[i]) {
      case '0':
        a += c;
        b += d;
        c = 0;
        d = 0;
        break;
      case '1':
        if (a == 0 && b == 0) {
          d++;
        } else if (a == 0) {
          b--;
          d++;
        } else {
          a--;
          c++;
        }
        break;
      case '2':
        if (b == 0) {
          d++;
        } else {
          b--;
          d++;
        }
        break;
      default:
    }
  }
  printf("%d\n", b + d);
}
```
【備忘録】\usepackage[dvipdfmx]{graphicx}してるのにTexでpngなどを読ませると Cannot determine size of graphic in <image_name>.png (no BoundingBox).

## 問題
秘伝の研究室テンプレートでもpdfやepsに画像変換無しでpngを直接読ませたい．
調べた結果
```tex
\usepackage[dvipdfmx]{graphicx}
```
を入れるとできるらしいので，texファイルにこの記述を入れてみる．

```shell
platex main.tex
dvipdfmx main.dvi
```
でtexからPDFを生成しようとすると
```shell
 Cannot determine size of graphic in img/cpu_ave_classfy.png (no BoundingBox).
```
のようなエラーが出てpng画像が読めない……．

調べても同様の事例が全く出てこないし，なにより新規で作ったtexでは`\usepackage[dvipdfmx]{graphicx}`を入れればできる．なぜ……

## 解決策

```tex
\usepackage[dvipdfmx]{graphicx}
```
に加えて，
```tex
\usepackage{bmpsize}
```
も加えたら動くようになった．謎．
順序つきリストの行頭に連番を振るUserScript【Scrapbox】

# はじめに
EvernoteからScrapboxに移行するにあたり、使えなくて困った機能がありました。それは、Scrapboxでは「順序付きリスト」つまり、`<ol>`に自動で番号を振ってくれないことです。ということで、ネストに対応した番号を振るUserScriptを作成しました。

# 使い方
リストに含めたい行を選択して、ポップアップボタンを押して使います。選択行には必ず、行頭を含んでください。そうしないと変なところに番号が出力されます。
例えば、次の文字列に数字を振るとしましょう。

**Before**
```txt
	1行目
		2行目
		3行目
	4行目
5行目
		6. 6行目
		7行目
		24. 8行目
	-11. 9行目
	
	10行目
12行目
```
**After**
```txt
		1. 1行目
			1. 2行目
			2. 3行目
		2. 4行目
	1. 5行目
			6. 6行目
			7. 7行目
			8. 8行目
		-11. 9行目
		
		-10. 10行目
	2. 12行目
```

`<ol>`における`start`属性にも対応しています。行頭（今回は6, 9行目）に"数字+ドット"の形式で数値を入力しておくと、その番号から連番を始めてくれます。

ただし、同じ数のインデントがついた最初の行のみを参照します。例えば、8行目には数値が入っていますが、すでに同じ数のインデントを持つ行が存在しているため、「24」という数字は無視され、代わりに「6+2=8」が代入されます。

空白行は単純に番号をつけずにスキップします。くわえて、値はマイナスにも対応していますが、Scrapboxの表示としては数字つきリストではなく、普通のリスト扱いになるようです。



# ソースコード

``` script.js
	scrapbox.PopupMenu.addButton({
		title: 'Ordered list',
    		onClick: text => {
     		let result = formatOrderList(textToNestedList(text));
			if(/^\S/gm.test(result)) {// インデントが行頭にない行が存在する場合は追加する
				result = result.replace(/^/gm, "\t");
			}
     		return result;
     	}
	});
	
	function textToNestedList(text) {
		const reg = /(^\s*)(.*)/;
		return text.split("\n").reduce((result, line) => {
			const level = line.replace(reg, "$1").length;
			const content = line.replace(reg, "$2");
			let parent = result;
			for (let i = 0; i < level; i++) {
				if (parent.length === 0 || !Array.isArray(parent[parent.length - 1])) parent.push([]);
				parent = parent[parent.length - 1];
			}
			parent.push(content);
			return result;
		}, []);
	}
	
	function formatOrderList(list, indent = 0) {
		const blank = "\t".repeat(indent);
		const firstLine = list.find(value => !Array.isArray(value));
		const reg = /(^-?\d+)(\.\s*)/;
		const start = reg.test(firstLine) ? firstLine.split(".")[0] : 1;
		let index = 0;
		return list.map(item => {
			if (Array.isArray(item)) {
				return this.formatOrderList(item, indent + 1);
			}
			if(item.length === 0) {
				return blank;
			}
			return blank + `${Number(start) + index++}. ` + item.replace(reg, "");
		}).join("\n");
	}
```

`textToNestedList()`は`scrapbox.PopupMenu.addButton`にインライン化して平気ですが、`formatOrderList()`はインライン化はできません。なぜなら、値を入れ子にするために循環参照をしているからです。

テストはザックリしただけなので、バグがあったら教えてください。

# 参考資料
ネストに対応していない順序付きリストでいいなら、こちらの方が簡単。

https://qiita.com/progfay/items/5a81e130fc36291990d4
【入緑記念】レーティングの稼ぎ方(AtCoder)

# お前は誰なんだ？

* 機械系の大学院生です
* プログラミング**未経験**でした
* AtCoderを2023年5月に始め、同年7月に<font color="Brown">入茶</font>、同年12月に<font color="PaleGreen">入緑</font>しました


* AtCoderとは

https://info.atcoder.jp/overview/about/atcoder

* AtCoderの色について

https://info.atcoder.jp/utilize/jobs/rating-business-impact
## 注意
* 内容はタイトルの通り、AtCoderのレーティングを上げることにフォーカスしてます(アルゴリズムの理解とかでは無いです)
* 初投稿です
* **初心者(灰～茶)** 向けです
* コンテスト編と精進編があります

# 本編
## コンテスト編
### Rated で参加しよう!

コンテストにはRatedとUnratedがありますが、基本Rated で参加しましょう

https://atcoder.jp/posts/744

理由は2つあります
* Ratedの方がコンテストに集中して取り組めるから
* コンテスト特有の焦りや見落としを体験できるから

2つ目について
コンテスト中は普段しないようなミスをする場合があります
この時の感情や考えを記録しておくことで、今後感情のコントロールや問題文の読み直しなど対処法を考えることができます

Ratedでレーティングが多少下がったとしても、今後のコンテストのパフォーマンスにつながればそれは長期的にはプラスです

### ARCにも出よう!

ARCについては以下参照

https://info.atcoder.jp/overview/contest/algorithm

ARCの1問目、2問目はABCと違って数学的な考察で解ける問題の可能性があります
解けなかった時の損が少なく、解けたときの利益が大きいため、少しでも解ける可能性がある場合は(特別に数学が苦手な人以外は)Ratedで積極的に狙うことを推奨します

逆に緑や水色の人は、リスクリターンを考えて出ましょう

## 精進編

まずここでの精進とは、競技プログラミングの過去問を解くことを指します
AtCoderの過去問は以下から見れます

https://kenkoooo.com/atcoder/#/table/

典型問題は以下にまとまっています

https://atcoder.jp/contests/typical90


### 精進ノートを作ろう!
精進した問題は解法を言語化してまとめることを推奨します
* コンテストに出た場合は、解法以外に詰まったポイントや感情を入れましょう
* 自分はwordでまとめていますが、検索さえできれば何でも構いません
* 問題ごとに並び替えることが出来れば、尚いいかもしれません
* コードは別にまとめておきましょう

精進ノートがあれば、精進の効率化やコンテスト中の参考にすることが出来ます

### 質より量を追い求めよう

解いた問題数が正義です
自分は400問近く解いています(^-^)
分からない問題は飛ばすか、解説のコードでACしてすぐに次に行き、実力が上がれば戻ってきましょう
1問にかける時間を減らし、大量の問題に触れましょう

# ポエム

これからは自分語りになります。読まなくて大丈夫です。

AtCoderに登録したのは2021年末で、A問題が解けなくて二回挫折しています。
就活が終わってしばらくして暇になり再開しましたが、半年以上続けれるとは思ってませんでした。
最初は趣味で始めましたが、段々ソフトウェア系の業務に携わりたい気持ちが出てきて無事人生が狂いそうです(入社や配属がまだなのでどうなるかはわかりません)

皆さんも気軽に狂いましょう!
ここまで読んでいただきありがとうございました(^-^)
質問に対してどのように教えるべきかという話

# はじめに
せっかくアドベントカレンダーの季節なので何か投稿しようと思ったのですが、技術寄りのネタが浮かばなかったので、ポエムを書くことにしました。

仕事をしていると技術的な質問を受けることがあります。
内容や相手によってはストレートに答えてよいのですが、経験の浅いエンジニアには、答えではなくそこに至るまでの調べ方や考え方を伝えたいと思うことも多いです。
ただ、どこまで教えるかというのは結構な悩みどころで、以下のような状態は避けなければいけません。
- 教えすぎ → 聞けば教えてもらえると思って自分で調べたり考えたりしなくなる。
- 教えなさすぎ → なかなか解決できずストレスが溜まったり、やる気や自信を無くしてしまう。

というわけで、自分なりにどのような基準で判断して、どう教えているかを書いてみます。
# 質問の分類
![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517294/3422fe2e-5c8e-4f2e-9bf2-4b987c8b3aba.png)
図のように調べ方と考え方の難易度で4タイプに分類してみました。
考え方というのがちょっと漠然としていますが、調べた結果がそのまま解決に繋がるのか、それを組み合わせたり応用する必要があるのか、程度に捉えてください。
## ①調べ方：難しい　考え方：難しい
一番手強いブロックになります。
ここは調べ方、考え方両方のサポートが必要となるので、ペアプロのような感じで相手に作業してもらいながらナビゲートしたり、難易度によっては自分がドライバーになって随時質問を受けながらやってみせるなど、ある程度手厚く教えるようにしています。
## ②調べ方：簡単　考え方：難しい
調べるところまではできても、それをどう使えば解決できるかが難しいというブロックです。
この場合はまず調べ方や調べた内容に不足がないかを確認した上で、どのように考えてどう解決しようとしたのか、どこで手こずっているのか、順を追って説明してもらいます。
説明しているうちにわからない部分が見えてきたり、考えがまとまってくることも多いので、教えるというよりも理解度を見ながらアドバイスするという形になります。
## ③調べ方：難しい　考え方：簡単
②とは逆に、調べられたらほぼ解決なのですが、以下のような理由で調べ方そのものが難しいということがあります。
- 解決の糸口になるキーワードが浮かばない
- 情報が多すぎてどれが正解なのか判断できない
- 日本語のドキュメントやサイトが少ない

このような場合は質問を深掘りして、何がわかれば解決に繋がるのか、どのように情報を絞り込んでいくかといった部分を教えるようにしています。
また、日本語の情報が見つからなかったら、ページ翻訳なども活用して英語でも探してみるといったことも大事です。
このブロックはChatGPTなどにどうやって調べたらいいか聞いてみるのも効果的だと思います。
## ④調べ方：簡単　考え方：簡単
このブロックを質問してくるということは、そもそも調べていないか、見当違いのことを調べている可能性が高いです。
調べていなかった場合は、調べてすぐに解決できたという体験をさせた上で、まず調べるという意識付けと、どこまで調べてわからなかったら質問するかの判断基準を自分の中で持つということを伝えます。
見当違いのことを調べていた場合は、どんな理由で何を調べたのか確認し、どうすれば解決方法が調べられたか意識合わせをします。
一番単純なだけに、なぜ質問してきたかには注意が必要です。
# 気をつけていること
質問の分類による教え方は上に挙げた通りですが、共通して気をつけていることを少し書いておきます。
## 話を最後まで聞く
質問や説明の途中で遮ったり聞き返してしまうと、「なんか間違ってるかも？」と思って考えていたことを話してもらえなくなる場合があるため、とにかく最後まで聞くようにしています。
## 考えの過程や理由も話す
調べ方や考え方を教えるだけではなく、なぜそうやっているかという部分もできるだけ話すようにしています。
魚を与えるのではなく釣り方を教えるのは大前提として、なぜそれで釣れるのかまで伝えておけば、釣れなかった時にどこを改善や試行錯誤すればよいかの手がかりになります。
## できていることは伝える
結構やりがちなのですが、できていないことへの指摘やアドバイスばかりになってしまい、できていることについても「何も言われてないけど大丈夫かな？」と不安にさせてしまう場合があります。
できていないことにフォーカスしてもらうためにも、ここまではできているということを伝えるよう意識しています。
# おわりに
分類といっても調べ方と考え方でのざっくり4分割なので、こう教えればOKというものではありませんが、どこを重点的に教えるかの判断材料になれば幸いです。
教え方というのは相手の成長にも影響するので、今後もより良い方法を考えていきたいです。
[yarn] パッケージが複数バージョン入っている時のアップグレード方法

# 結論
`resolutions`を使う

## 手順サンプル
`@types/node@*` が古いバージョンを参照してしまう問題の解決


### `resolutions`を追記する

```bash
vi package.json
```

```diff_json: package.json
+ "resolutions": {
+    "@types/node": "18.18.2"
+ }
```

### `yarn install`して更新されているか確認
```bash
rm -rf node_modules
yarn install
cat yarn.lock | grep @types/node@*
vi package.json
```
```diff_json: package.json
- "resolutions": {
-    "@types/node": "18.18.2"
- }
```

## 参考
- https://classic.yarnpkg.com/lang/en/docs/selective-version-resolutions/
Amper で Kotlin 始めてみた

# はじめに
これは[RetailAI Adventurers Advent Calendar 2023](https://qiita.com/advent-calendar/2023/rai-adventurers)の 17日目 の記事です。

昨日の記事は [@caique_almeida](https://qiita.com/caique_almeida)さんの「MVVM architecture (Model-View-ViewModel)」です。

業務の中で Kotlin を触れる機会がありましたので、今回は最新の Kotlin の技術について紹介します。

# Kotlin とは

JVM、Android、ブラウザ用の静的型付きプログラミング言語です。
Java仮想マシン上で動作するため、Javaで書かれたプログラムと同程度に速くコンパイルされ同程度に速く動作します。
Javaに比べシンプルなコードなため、圧倒的に書きやすいです。

簡単にいうと、Javaの進化形！です。

# Amper とは

Amper とはプロジェクトを構成するためのツールです。

「Kotlin はビルドシステムが複雑で扱いにくい！」というイメージを無くすため、開発されているようです。そのため、Amper を活用すれば、将来的にはソースコードの階層が見やすくなると考えられます。

2023年現在も開発中です。

# Amper を使う理由

マニフェストファイルである`module.yaml`ファイル（Javaでいう`.jar`ファイル）に、

```yaml
# Produce a JVM application 
product: jvm/app
```

こちらのコードを書くだけで、 Kotlin と Java のツールチェーン、テストフレームワーク、およびその他の必要な機能は初期状態で構成済みになり、そのまま使用できます。 ビルド、実行、テストの記述と実行などができるようになります。

「簡単！見やすい！」が Amper の良さです。

# 環境作成

1. Toolbox Appのダウンロード

    有料版もありますが、今回は無料版を使います。

    [JetBrains Toolbox App](https://www.jetbrains.com/ja-jp/toolbox-app/)

    <br>

1. Fleetのインストール

    Toolboxから、Fleetのインストールをします。

    <img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618316/d5a1e13f-d857-add4-aba4-015ff720cb94.png">

    <br><br>

1. プロジェクト作成

    git cloneで、[テンプレート](https://github.com/JetBrains/amper/tree/0.1/examples/jvm-hello-world)を利用します。

    ①[Cloue from Git]に遷移

    ②Soure URLに`https://github.com/JetBrains/amper`を入れる

    ③[Clone]を押す

    <img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618316/cccd958a-e55e-cd96-2f70-86af70658702.png">

    <br><br>
    
1. 完成！

    このような画面になったら完成です。

    buildなどで多少は時間がかかります。

    <img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618316/aa75b0a7-5849-b8e9-6ff5-016693b8ce98.png">

# Hello, world !

`amper/example/jvm-hello-world/src/main.kt`にあるコードを確認しましょう。

```kotlin
fun main() {
    println("Hello, World!")
}
```

1. ▶️を押して、実行！

    ターミナル上に`Hello, World!`が出ました。

    !<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618316/7c6b6e44-6003-7069-70bf-255d713a8ca5.png">

    <br>

1. World を Kotlin に変えてみると…
    
    `Hello, Kotlin!`に変わりました。

    <img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618316/da72041e-3bf0-57a4-6bc0-7a96afa4c984.png">

<br> 
これでKotlinを動かす環境は確認できました。

あとはフォルダを整理して、自分が作りたいコードを作成しましょう。

## 注意点

**環境について**

最新の JDK 17 以降をインストールする必要があります。

▶️ マークが表示されなければ、設定が足りていない可能性が高いため、ターミナルに出力されるエラー文から足りない環境を設定してください。

**Amper について**

Fleet・Amper は現在(2023年12月17日)も開発中で、`gradle`フォルダが無くなるなどソースコードが急激に変わる可能性があります。

業務利用は抑えて、自分の学習の範疇で利用することをおすすめします。

# 参考資料

**Git Hub**

https://github.com/JetBrains/amper

[JetBrains/amper README.md](https://github.com/JetBrains/amper/blob/0.1/README.md)

[JetBrains/amper Setup.md](https://github.com/JetBrains/amper/blob/0.1/docs/Setup.md)


**blog**

https://blog.jetbrains.com/ja/blog/2023/11/29/amper-improving-the-build-tooling-user-experience/

https://blog.jetbrains.com/ja/kotlin/2023/11/kotlin-multiplatform-tooling-in-fleet/

# 最後に
明日は、同じ新入社員の [@urakawa_jinsei](https://qiita.com/urakawa_jinsei) さんの記事です！

お楽しみに！！
親子で使うChatGPT

はじめまして、コウェルで情報セキュリティを担当している森下です。

イギリスでは、AI安全サミットが開催されセキュリティ面からもAIに関する国際ルールが進んできている昨今です。
セキュリティ担当としては生成AIのリスクだとか堅苦しい話をしたほうがらしい気もしますが、本日は箸休め的な柔らかい話をさせて頂きたいと思っています。
題して親子で使うChatGPT
硬直してきた大人の発想ではなく、これから生成系AIと共に生きていくであろう子供のアイデアに触れたいと思って今回記事の記載としました。


さっそく、話題に入ります。
息子（小学５年生）に触らせていたChatGPTの履歴を見てみると……
※息子に許可を取っています！

## ChatGPTとしりとりで対戦
出オチ感がありますが、正直このログは自分としては感心しました。
質問する・要約するというinputされた情報の整理はよく見るのですが自分の遊び相手としてChatGPTを利用するというのは新鮮な驚きでした。

残念ながら当時のログは執筆時に揮発してしまっていたので、新たに作ってみたのですが当時と同じ品質の応答がもらえたので、どんな結果になったのかをお見せします。

![スクリーンショット 2023-12-12 145745.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136080/b36d6cd7-80fa-6e4c-3e2b-1227196d992b.png)
https://chat.openai.com/share/b7fecde6-93c5-4928-bb84-910015271943

※画像はChatGPTとの会話の抜粋、URLは実際にChatGPTへ話しかけた際のログになります。

うーん、めちゃくちゃ弱いですねぇ。
１回目に「ん」を返すのはルールを理解してないのか、接待プレイなのか
ちゃっとやってと言われると少し粘ってくれましたが、すぐさま同じ回答をしてしまう始末。
息子は、ChatGPTの弱さに爆笑していたのでそれはそれでいいのかなと思ったりもしました。

ただ、ゲームの対戦相手という視点で見ると非常に可能性を感じています。
指摘によって強さ＝難易度が変わっているのでうまく使えば、最高のゲームパートナーになりうる可能性を秘めているなと思いました。
自分より少し強い対戦相手で自己鍛錬に励む、ギリギリ勝てる調整をしてもらってカタルシスを得る、プロゲーマの対戦を見て感想戦なんてのもやってくれそうですね。

## ChatGPTで相談
これ一般的な使い方ですね、それだけだと話が終わってしまうので相談内容も見てみましょう

### やる気を出す方法
![スクリーンショット 2023-12-12 150149.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136080/5e5ca98a-a44f-1ea5-44be-0f3d81ee6230.png)
うーん？　子供らしい？？？
ちょっと仕事に疲れた中年みたいな相談をしてますね。
受験勉強で疲れてしまったんだろうか、親に相談し辛いことをChatGPTに聞いてるところになにか強く言い過ぎていないか一抹の不安を感じます。

内容は雑多なものですが、ちょっと気になるのは明確に誤りがあるところですね。
加えてLinkは避けましたが、法的に問題がありそうなことを推奨してしまうケースもあるようです。

今のChatGPTは友達は許されるけど、教師としての回答はできなさそうだなと感じました。
古くはドラえもんのような人工生命の相棒というのは以外に近く来ているのかもしれません



そういえば、Humane AI PINという生成AI用いたデバイスが発表されていました。
これまた、SF映画での存在でしかなかったAIが相棒という世界が見えそうで非常に楽しみです。

では、とりとめのない話でしたが以上で末筆とさせて頂きます。
GPT-4とALBERTの回帰予測器：繰り返し生成で回帰予測の結果を向上させるか

# 背景
- 以前[ALBERTで回帰予測器を作りました](https://qiita.com/munaita_/items/982d77b1b8479f4c0d78)
    - この予測器はある文章をinputすると、あるメディアにおけるクリック率を予測するモデルです
    - あるメディアでの広告配信履歴データでfine-tuningされたモデルです
- GPT-4を使って文章を生成 -> 予測器で評価 -> 予測器の結果をプロンプトにフィードバック -> 再生成 ... これを繰り返していくと、GPT-4は予測器の結果をさせる結果を返すようになるのか検証していきます


# 方法概要
以下の3つのグループに分けて、予測器の結果がどう推移していくかを観察していきます
- 1.予測器からのFBなしのグループ
- 2.予測器からのFB付きの繰り返し生成を行うグループ
- 3.予測器からのFBをカスタムさせた形で繰り返し生成行うグループ

# 先に結論

![スクリーンショット 2023-12-07 15.12.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/893195f5-1d85-3245-ee14-d97e00f0f9a3.png)

- 1,2,3のグループの生成結果はどれも有意な差が見られませんでした
- つまり、コストだけ考えれば、プロンプトに生成結果をFBしないほうがいいということになります
- これは、GPT-4がALBERTの回帰予測器のロジック(パラメータ)を把握できていないため、いくらFBを与えてもそれを結果を向上させる結果を推測できないと考えられます


# 方法詳細
## 1. 予測器からのFBなしのグループ

### 手順

- GPT-4である固定プロンプトを実行し、テキストを生成します
- 1回の生成で10個テキストを生成し、予測器にかけて結果を取得します(これを1セットとします)
- 1セットを10回繰り返します

### 設定
- セット回数: 10
- セット毎の生成数: 10

### プロンプト
- 固定プロンプトのみです
- 固定プロンプトは非公開とします

## 2. 予測器からのFB付きの繰り返し生成を行うグループ

![スクリーンショット 2023-12-07 16.31.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/a38c110b-f2a7-b360-f39f-71431e003b12.png)
プロンプトへのFBの追加イメージ

### 手順
- GPT-4である固定プロンプトを実行し、テキストを生成します
- 1回の生成で10個テキストを生成し、予測器にかけて結果を取得します(これを1セットとします)
- 予測器から得られたすべての結果(テキストと予想クリック率)をフィードバックとして固定プロンプトに追加し、更なる改善を求めるプロンプトを追加して実行します
- これを5回繰り返して、予測器の結果を測定していきます

### 設定
  - セット回数: 10
  - 繰り返し数: 5
  - セット毎の生成数: 10

### プロンプト
固定プロンプトに以下のようなプロンプトをフィードバックとして追加していきます.

```py
以下は直近作成したテキストとそのクリック率予測の値です.
[Tuple(文章, クリック率予測)]の形式になっています.

###
[("文章1", 0.0001), ("文章2", 0.0002), ("文章３", 0.0003)...]
###

こちらを参考にして、クリック率予測の値が高くなるようなテキストを10個生成してください。
```

### 予測器からのFBをカスタムさせた形で繰り返し生成行うグループ
![スクリーンショット 2023-12-07 16.31.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/4adc1896-5172-6c13-4b18-addd8629fb49.png)
プロンプトへのFBの追加イメージ

### 手順
- GPT-4である固定プロンプトを実行し、テキストを生成します
- 1回の生成で10個テキストを生成し、予測器にかけて結果を取得します(これを1セットとします)
- 予測器から得られたテキストと予想クリック率のうち、予想クリック率の上位5位のテキストのみをフィードバックとしてプロンプトに追加し、更なる改善を求めるプロンプトを追加して実行します
- これを5回繰り返して、予測器の結果を測定していきます
- 設定:
  - セット回数: 10
  - 繰り返し数: 5
  - セット毎の生成数: 10

### プロンプト
固定プロンプトに以下のようなプロンプトをフィードバックとして追加していきます.

```py
以下は直近作成した効果の良かったテキストです.

###
["文章1", "文章2", "文章３", "文章4", "文章5"]
###

こちらを参考にして、クリック率予測の値が高くなるようなテキストを10個生成してください。
```

# 考察
- 予測器の結果をプロンプトにFBとして与えても有意な差は得られませんでした
- 有意な差が得られなかった理由の１つとしては、GPT-4がALBERT予測器の推論ロジックを把握できていないため、結果をFBとして渡しても、予測値を向上させる生成に繋げられなかったということが考えられます
- また、固定プロンプトに予測器の結果を高めるテキストがすでに入っているために、FBがない時点で最適化されてしまっていたということも考えられます
- プロンプトの書き方や、手法次第ではまだまだ生成の精度の向上の余地はあると思うので引き続き探索していきます


# おまけデータ

![スクリーンショット 2023-12-07 17.05.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/8cc43b8d-7613-121d-1f30-84924c691b69.png)

![スクリーンショット 2023-12-07 17.03.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/7e97892c-766e-76fd-5bb9-59c6e5a0987e.png)


- どちらも各セットで1回目 -> 5回目にかけて平均が上がっているようには見えない
- 予測器の結果のFBが効果的に働いていないことがわかる
UWSCRで変更された仕様：特殊配列変数をともなう組み込み関数

UWSCの一部の組み込み関数には取得したデータ群を数を返し、実際のデータは特殊配列変数に格納するというものがありました。具体的には以下になります。

|    関数    |  特殊配列変数 |
|------------|---------------|
| getallwin  | ALL_WIN_ID    |
| getitem    | ALL_ITEM_LIST |
| getdir     | GETDIR_FILES  |
| getoleitem | ALL_OLE_ITEM  |

これらの関数はすべてアイテム数ではなく実際のデータを格納した配列を返すようになりました。それに伴いこれらの特殊配列変数も廃止されました。

```php:uwsc
cnt = getallwin() // 配列の個数を返す
for i = 0 to cnt - 1
    // idはALL_WIN_ID特殊配列変数に格納されている
    id = ALL_WIN_ID[i]
    print status(id, ST_TITLE)
next
```

```php:uwscr
windows = getallwin() // idの配列を返す
for id in windows
    print status(id, ST_TITLE)
next
```


:::note warn
#### 仕様変更について
UWSCと比較すると破壊的変更となりますが、UWSCの仕様では配列を戻り値として返せなかったことによる苦肉の策だと考えていて、戻り値そのものが配列であるほうが合理的だろうという判断からこの仕様変更が行われました。
UWSCRでは特殊配列変数を含むスクリプトは動作しないため、これらの特殊配列変数を使用しているスクリプトは修正が必要になります。ご不便をおかけしますがご了承ください。
:::


UWSCでのこれらの関数は`for-in`にて特殊な動作が実装されていました。

```php:uwsc
// inの右辺でこれらの関数を呼ぶと、変数に直接値が入る
for id in getallwin()
    print status(id, ST_TITLE)
next
```

UWSCRではこれらの関数が配列を返すため、上記コードはそのまま動作します。

```php:uwscr
// 関数がID配列を返すためそのままfor-inが動く
for id in getallwin()
    print status(id, ST_TITLE)
next
```
検索フォームを用いての検索機能の実装

# はじめに
@rinrin_abc1818 です。
今回は自身のアプリケーションに検索機能を実装したのでそちらの保存用に投稿します。

:::note warn
筆者はプログラミング経験半年です。
至らない点があるかと思いますので、その際はご指摘いただけると幸いです。
:::

# 概要
現在Ruby on Railsを用いて投稿型のアプリケーション作成中です。
ユーザー管理機能、投稿機能と終えて、現在は検索機能に取り組んでいます。

今回検索機能として、一覧ページ下部の検索フォームと詳細検索ページの二つを実装したのですが、今回は検索フォームでの検索機能についてまとめました。


# 検索フォームでの検索機能の実装
1.検索フォームについて

  検索フォーム自体はform_withを使用します。
  ```ruby
  <%= form_with(url: search_path, method: :get) do |form| %>
    <%= form.text_field :query, placeholder: "キーワードを入力" %>
    <%= form.submit "検索" %>
  <% end %>
  ```

2.searchアクションのルーティングを設定

  `collection`と`member`を使用してルーティングをカスタマイズしていきます。
  これらを使用することで、ルーティングのURLとコントローラーを自由にカスタムできます。
  今回はidを指定して特定の詳細ページに遷移せず、検索結果を一覧として表示するので、`collection`を使用します。
  idを指定する必要がある場合は、URLに`：id`を含む`member`を使用します。
  ```ruby
  Rails.application.routes.draw do
  devise_for :users
  root to: 'rehas#index'
  
  resources :rehas, only: [:new, :create, :show, :edit, :update, :destroy] do
    collection do
      get 'search'
    end
  end
end

  ```

3.searchメソッドをモデルに定義する

上記で使用している`searchメソッド`は現時点では未定義であるため、ここでどのような処理を行うかを定義していきます。

ここでwhereメソッドとLIKE句を使用します。

:::note info
whereメソッド
`モデル.where('検索対象となるカラムを含む条件式')`
上記のように引数部分に条件を指定することで、テーブル内の「条件に一致したレコードのインスタンス」を配列の形で取得できる
:::

:::note
LIKE句
「1文字目に'a'という文字列が入ったデータ」や「最後の文字に'b'が入っているデータ」、「文字列の途中に'c'が入ったデータ」など曖昧な文字列を検索する際に使用する
:::

これらを考慮し以下の記述を対応するモデルに記述します。
```ruby
  def self.search(search)
    if search != ""
      Reha.where('text LIKE(?)', "%#{search}%")
    else
      Reha.all
    end
  end
```
`"%#{search}%"`この記述によって、入力された記述を含む投稿を検索するという処理になります。

4.コントローラーにsearchアクションを定義する

```ruby
  def search
    @rehas = Reha.search(params[:query])
  end
```

5.ビューを作成する
search.html.erbを作成します。

# おわりに
自分の記録用にと投稿しましたが、誰かのお役に立てれば幸いです。
ここまで閲覧して下さり、ありがとうございました。
【PostgreSQL】pg_stat_databaseについて

## pg_stat_databaseとは？

pg_stat_databaseは、PostgreSQLの統計情報ビューの一つで、各データベースの動作統計を提供します。これにより、データベースのパフォーマンスや動作に関する詳細な情報を取得できます。

## pg_stat_databaseの使い方

pg_stat_databaseは、SELECTクエリを使用してアクセスできます。例えば、次のようにして全てのデータベースの統計情報を表示することができます。

```SQL
SELECT * FROM pg_stat_database;
```

このクエリを実行すると、各データベースに関する詳細な情報が表示されます。これには、コミット数、ロールバック数、読み取り/書き込みの操作数などが含まれます。

カラムについては[こちら](https://www.postgresql.jp/document/15/html/monitoring-stats.html#MONITORING-PG-STAT-DATABASE-VIEW)

## pg_stat_databaseの活用法

pg_stat_databaseを活用することで、データベースのパフォーマンスの問題の診断やデバッグに役立つ情報を得ることができます。

例えば、特定のデータベースのパフォーマンスが低下している場合、pg_stat_databaseを使用してそのデータベースの統計情報を調べることができます。これにより、問題の原因がコミットの数が多いためなのか、読み取り/書き込みの操作数が多いためなのかなど、問題の原因を特定する手がかりを得ることができます。

## 注意点

pg_stat_databaseは非常に有用なツールですが、注意点もあります。pg_stat_databaseが提供する情報は、データベースの現在の状態を反映していますが、その状態は一瞬一瞬で変わるため、同じクエリをすぐに再実行しても結果が異なることがあります。

また、pg_stat_databaseは統計情報を提供するだけで、パフォーマンスの問題を自動的に解決するわけではありません。問題の解決には、得られた情報を元に適切な対策を立てることが必要です。

## まとめ

PostgreSQLのpg_stat_databaseは、データベースの動作統計を手に入れるための強力なツールです。これを活用することで、データベースのパフォーマンス問題の原因を特定し、適切な対策を立てることが可能になります。ただし、pg_stat_databaseの提供する情報を適切に解釈し、適切なアクションを取るためには、データベース管理の基本的な理解が必要です。
Amazon S3のストレージクラスまとめ

Amazon S3のストレージクラスに関する、ざっくりとしたまとめである。基本は[公式ページ](https://aws.amazon.com/jp/s3/)に書いてあることをベースに説明する。

## Amazon S3標準

基準となるのが、このストレージクラスである。

### 特徴

* 3以上のAZにまたがってデータを保存
* イレブンナインの耐久性
* 99.99%の可用性(SLA99.9%)
* 最低サイズの定めなし
* 最低保管期間の定めなし
* ミリ秒単位でアクセス可能

### 用途

一般的に、アクセス頻度が高いオブジェクトは、このストレージクラスで格納することをお勧めする。

## Amazon S3 Express 1ゾーン

とにかく高速なアクセスがどうしても必要な場合、2023年11月に追加された、このストレージクラスを用いると良い。

### 特徴

* 1AZにデータを保存
* 1AZについてイレブンナインの耐久性
* 99.95%の可用性(SLA99.9%)
* 最低サイズの定めなし
* 最低保管期間1時間
* 1桁ミリ秒でアクセス可能
* S3標準より高価なストレージ料金
* 少量のデータであればS3標準より安価な取得・保存料金

### 用途

どうしても高速性能が必要な場合、検討すべきである

## Amazon S3標準 - 低頻度(IA)

アクセス頻度が少ない(概ね月1回程度)場合、このストレージクラスが適しているとされる。

### 特徴

* 3以上のAZにまたがってデータを保存
* イレブンナインの耐久性
* 99.9%の可用性(SLA99%)
* 最低サイズ128KiB(これを下回る場合、128KiB扱いになる)
* 最低保管期間30日(30日以内に上書き・削除などを行った場合、30日分の費用が発生する)
* ミリ秒単位でアクセス可能
* S3標準より安価なストレージ料金と、高価な取得・保存料金

### 用途

月1回程度のアクセスを見込む、直近のログなどに用いると良い。

## Amazon S3 1ゾーン - IA

S3標準 - IAと異なり、1ゾーンに保存する。

### 特徴

* 1AZにデータを保存
* 1AZについてイレブンナインの耐久性
* 99.5%の可用性(SLA99%)
* 最低サイズ128KiB(これを下回る場合、128KiB扱いになる)
* 最低保管期間30日(30日以内に上書き・削除などを行った場合、30日分の費用が発生する)
* ミリ秒単位でアクセス可能
* S3標準 - IAよりストレージ料金が安価

### 用途

月1回程度のアクセスを見込む、再生成が可能なデータの保存に用いると良い。

## Amazon S3 Glacier Instant Retrieval

四半期に1度程度しかアクセスがないが、即時の取り出しが必要な場合に、これを用いると良いとされる。

### 特徴

* 3以上のAZにまたがってデータを保存
* イレブンナインの耐久性
* 99.9%の可用性(SLA99%)
* 最低サイズ128KiB(これを下回る場合、128KiB扱いになる)
* 最低保管期間90日(90日以内に上書き・削除などを行った場合、90日分の費用が発生する)
* ミリ秒単位でアクセス可能
* S3標準 - IAより安価なストレージ料金と、高価な取得・保存料金

### 用途

四半期に一度程度しかアクセスしない、ログの保存などに用いると良い。また、これより下のクラスになると、取り出しが時間がかかるようになるため、ほとんどアクセスがないが、瞬時のアクセスが必要な場合もこれ。

## Amazon S3 Glacier Flexible Retrieval

1年に1回から2回程度しかアクセスせず、ある程度の待ち時間が許容される場合に、これを使うのが良いとされている。

### 特徴

* 3以上のAZにまたがってデータを保存
* イレブンナインの耐久性
* 99.99%の可用性(SLA99.9%)
* 保存時にS3標準の8KiBとこのクラスの32KiBが追加で付与される
* 最低保管期間90日(90日以内に上書き・削除などを行った場合、90日分の費用が発生する)
* ストレージ料金はS3 Glacier Instant Retrievalよりさらに安い
* 3種類の取り出し速度のオプションあり。取り出し後の取得はS3標準と同じ料金。保存コストは高い
    * 迅速 - 高価だが、数分で取り出し可能
    * 標準 - 安価に、数時間で取り出し可能
    * 大容量 - 無料で、半日ほどで取り出し可能

### 用途

1年に1回程度のアクセスを見込む、数時間の取得ラグが許容されるログなどに適切。

## Amazon S3 Glacier Deep Archive

ほとんどアクセスがないが、保存が必要なデータで、長時間の待ち時間が許容される場合に、これを使うのが良いとされている。

### 特徴

* 3以上のAZにまたがってデータを保存
* イレブンナインの耐久性
* 99.99%の可用性(SLA99.9%)
* 保存時にS3標準の8KiBとこのクラスの32KiBが追加で付与される
* 最低保管期間180日(180日以内に上書き・削除などを行った場合、180日分の費用が発生する)
* ストレージ料金はS3 Glacier Flexible Retrievalよりさらに安い
* 2種類の取り出し速度のオプションあり。取り出し後の取得はS3標準と同じ料金。保存コストは高い
    * 標準 - そこそこの価格で、半日以内で取り出し可能
    * 大容量 - 安価に、2日以内で取り出し可能

### 用途

法的な理由で保存が必要な、ほとんどアクセスすることがないログに適している。

## Amazon S3 Intelligent-Tiering

アクセス頻度が不明な場合に、それをAWSが監視して、適宜ストレージクラスを移動してくれるクラスである。

### 特徴

* 3以上のAZにまたがってデータを保存
* イレブンナインの耐久性
* 99.9%の可用性(SLA99%)
* 最低サイズは実質128KiB(128KiB未満の場合、常に標準として扱う)
* 最低保存期間の定めなし
* アーカイブティアに落ちていない限り、ミリ秒単位でアクセス可能
* それぞれのクラスに応じた料金に加え、オブジェクトの監視料金がかかる

### 用途

アクセス頻度が全く読めないような場合に適している

## まとめ

* とりあえずよくわからないならS3標準に入れておく
* サイズをある程度大きくまとめないと、下のクラスへ移すのは困難
* ログはライフライクルポリシーでどんどん下のクラスへ落とす