OmniAICreator/Qiita-1.07M huggingface dataset:
棒グラフからカテゴリを抽出/排除する(SPSS Modeler データ加工逆引き10-18)

# 棒グラフからカテゴリを抽出/排除する

![スクリーンショット 2024-05-28 11.18.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/e96e4c45-cb6a-2cbf-90c5-b2fe5638aba0.png)

## 1.想定される利用目的

・対象カテゴリをグラフから絞り込む
・ダミーや空白のカテゴリを排除する

## 2.サンプルストリームのダウンロード

https://github.com/yoichiro0903n/blue/raw/main/bar_select.str

## 3.サンプルストリームの説明

![スクリーンショット 2024-05-28 11.19.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/29bd7f71-8222-deb6-06fa-06a51b89457a.png)

a.入力するデータは次の通りです。
![スクリーンショット 2024-05-28 11.22.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/886d4bae-ba2b-c571-3bcb-a264269116a6.png)

b.[棒グラフ]ノードを編集します。
![スクリーンショット 2024-05-28 11.22.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/bf601586-e9de-d5fe-1249-b8a7949a5880.png)

[実行]します。このグラフにある「ブドウ]の該当レコードを抽出/排除します。赤枠[グラフ]タブを選択します。

![スクリーンショット 2024-05-28 11.23.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/3e4c9ffa-53db-a633-cd70-63b9bc76b077.png)

独立した棒グラフチャートが表示されました。
![スクリーンショット 2024-05-28 11.23.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/b34d1515-b236-799a-e929-d58fe7921139.png)

[表示]メニューから[インタラクティブ]にチェックを入れます。
![スクリーンショット 2024-05-28 11.24.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/f778e6eb-8b10-d174-8a7d-d796c342ed8c.png)

赤枠の魔法の杖アイコンを押してからブドウのグラフ領域上で右クリック。[マークした要素の条件抽出ノード生成]を選択します。cのノードが自動生成されます。
![スクリーンショット 2024-05-28 11.27.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a3024f10-6a66-a7e6-258a-f821a0c38d03.png)

#### 特定カテゴリの該当レコードを表示する

c.[条件抽出]ノードを編集します。

![スクリーンショット 2024-05-28 11.28.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/7600262a-0299-474d-39e6-e90eada30928.png)

[プレビュー]します。

![スクリーンショット 2024-05-28 11.28.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/cfc511e8-52d7-a24a-591e-de2347ea0902.png)


#### 特定のカテゴリを排除する

d.[条件抽出]ノードを編集します。抽出[モード]を[破棄]に変更します。
![スクリーンショット 2024-05-28 11.28.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/a41109e3-afba-764e-2533-1c0d89a1ca2a.png)

[棒グラフ]を実行します。

![スクリーンショット 2024-05-28 11.29.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/02e417ed-8320-b2a3-39da-ad17419070a9.png)

![スクリーンショット 2024-05-28 11.29.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/02f2d719-5e85-6664-0afe-0e8043f94f32.png)

#### 注意事項


この時点でメニューから条件抽出することができないため[グラフ]を利用します。

![スクリーンショット 2024-05-28 11.23.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286322/26133ea9-0ae8-1622-ec10-928c26933580.png)

## 4.参考情報

#### 棒グラフのノードリファレンス

https://qiita.com/416nishimaki/items/8178b9565b8da1a794f1

#### SPSS Modeler ノードリファレンス目次

https://qiita.com/416nishimaki/private/503037195081d3323eee

#### SPSS Modeler 逆引きストリーム集（データ加工）

https://qiita.com/416nishimaki/private/4bf813e6cba84b2a1008
javaとtypescriptでの環境構築

前回javaとtypescriptの環境構築を行い、その後ホットリロード（ymlファイルにマウント設定追加しただけ）を実装しました。

次に、今回のアプリケーションで使うdbを設定します。
簡易的に 下記ファイルを含むmysqlフォルダを作りました。
my.cnf: MySQLの設定ファイル。
init.sql: データベース初期化用SQLスクリプト。

現在のディレクトリツリーはこちらになります。
javaのディレクトリ名がspring bootで設定しなかったのでdemoのままになってたりtypescriptのディレクトリ名がmy-appで違和感ですね...
命名はちゃんとしましょう

my-java-ts-project/
├── demo/
│   ├── Dockerfile
│   ├── pom.xml
│   ├── mvnw
│   ├── .mvn/
│   │   └── (その他のMaven設定ファイル)
│   └── src/
│       ├── main/
│           ├── java/
│           │   └── com/
│           │       └── example/
│           │           └── demo/
│           │               ├── DemoApplication.java
│           │               ├── Task.java
│           │               ├── TaskController.java
│           │               └── TaskRepository.java
│           └── resources/
│               ├── application.properties
│               └── (その他のリソースファイル)
├── my-app/
│   ├── Dockerfile
│   ├── package.json
│   ├── package-lock.json
│   ├── public/
│   │   └── (公開用リソースファイル)
│   ├── src/
│   │   ├── App.tsx
│   │   ├── index.tsx
│   │   └── components/　（ここはまだ未作成）
│   └── .dockerignore
├── mysql/
│   ├── my.cnf
│   └── init.sql
├── docker-compose.yml
└── README.md (任意)

これでtypescript,java,mysqlの設定は完了です。
これぐらいの内容なら1~2時間でできるようになりたいですね。
実際にアプリケーション作成に進みましょう
Amazon Bedrock API (Claude 3 Haiku)のはじめの第一歩

[link-1]: https://docs.aws.amazon.com/bedrock/latest/userguide/model-parameters-anthropic-claude-messages.html "Claude Messages API"
[link-2]: https://docs.anthropic.com/en/api/claude-on-amazon-bedrock "Anthropic API reference"

## はじめに
生成AIサービスを作るのには欠かせない、APIを使ったチャットに関する記事です。
Amazon BedrockはGUI上で動作させることもできますが、様々な機能を追加していくためにはAPI呼び出しが必要なので実装してみました。

## モデルアクセス
AWSの生成AIモデルを使うためには、最初にアクセス申請をしなければなりません。
コンソールから`Amazon Bedrock`にアクセスし、使いたいモデルをリクエストします。
私は`Claude 3 Haiku`を選び、リクエストはすぐに承認されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2039603/281ba4a9-a007-db7d-7eb7-6075be4c1243.png)

リージョンによって使えるモデルが異なるので、使いたいモデルがないときはリージョンを変えてみましょう。
また、ここで指定したリージョンは後で使うので控えておいてください。

## AWS CLIのインストール
以前に書いた記事をご覧ください。

https://qiita.com/MhalTeddy/items/b8917f72a32ca5d389dc

## APIキー
生成AIモデルを使うためにはAPIキーが必要です。
APIキーは`AWS access portal`→`Access keys`の中で取得できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2039603/76f29ac7-6f55-3513-c842-31eafdd52355.png)

以下の環境変数をコピーしてターミナルに貼り付けると使えるようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2039603/3da20bdd-bdba-38c4-5ada-338000185b6b.png)

## Pythonコード
以下のように書くと動作します。このプログラムは[Anthropic Claude Messages API][link-1]の内容をもとに書いています。
```python:main.py
import boto3
import json

brt = boto3.client(service_name="bedrock-runtime", region_name="ap-southeast-2")
body = json.dumps({
    "anthropic_version": "bedrock-2023-05-31",
    "messages": [{"role": "user", "content": "日本固有の料理を教えてください。"}],
    "max_tokens": 300,
    "temperature": 0.1,
})

modelId = "anthropic.claude-3-haiku-20240307-v1:0"
accept = "application/json"
contentType = "application/json"

response = brt.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)
response_body = json.loads(response.get("body").read())

print(json.dumps(response_body, indent=4, ensure_ascii=False))
```
```:実行結果
{
    "id": "xxx",
    "type": "message",
    "role": "assistant",
    "model": "claude-3-haiku-20240307",
    "stop_sequence": null,
    "usage": {
        "input_tokens": 21,
        "output_tokens": 300
    },
    "content": [
        {
            "type": "text",
            "text": "はい、日本には非常に豊かな食文化があります。日本固有の代表的な料理をいくつか紹介します。\n\n1. 寿司 - 生の魚介類を酢飯の上に乗せた料理。江戸時代に発祥し、日本を代表する料理の一つです。\n\n2. そば - 細長い麺を使った料理。地域によって味付けや食べ方が異なります。代表的なものに、天ぷらそばやざるそばなどがあります。\n\n3. 天ぷら - 野菜や魚介類を小麦粉の衣で揚げた料理。軽く香ばしい食感が特徴です。\n\n4. 焼き魚 - 魚を塩や味噌などで味付けし、焼いた料理。さまざまな魚が使われ、地域によって調理法が異なります。\n\n5. 豆腐料理 - 湯豆腐やあげ出し豆腐など、豆"
        }
    ],
    "stop_reason": "max_tokens"
}
```

プログラムを書く上でわかりにくかったことは、リージョンを設定しなければならないことです。
[モデルアクセス](#モデルアクセス)の項で設定したリージョンを指定する必要があります。
```python
brt = boto3.client(service_name="bedrock-runtime", region_name="ap-southeast-2")
```
どのようにしてリージョンを判別しているかは、[Anthropic API reference][link-2]に説明がありました。
> aws_region changes the aws region to which the request is made. By default, we read AWS_REGION, and if that's not present, we default to us-east-1. Note that we do not read ~/.aws/config for the region.

## さいごに
APIを使ってテキストを出力するだけでしたが、APIキーの設定方法、リージョンの設定など手間取った部分がありました。
基本的な使い方を習得したので、これからいろいろな機能を追加していきます。
Power Automate（クラウドフロー）でWordファイルの中身を読み取る


なぜかPower AutomateのクラウドフローにWordファイルを読み込むアクションが無い模様です。

`encodian`というサービスを利用することでWordファイルを読み込み中身を取得できます。

https://learn.microsoft.com/ja-jp/connectors/encodiandocumentmanager/#extract-images-from-pdf

## 1. encodianのアカウントを作りAPIキーを取得

トライアルは30日らしいです。Gmailとhotmailでは登録できない模様なので注意しましょう。

> https://www.encodian.com/product/flowr/#pre-anchor-form
> ![](https://i.gyazo.com/896cbe3ab66a92bdd1f7c175d1211f44.png)


登録するとAPIキーを取得できます。

## 2. Power AutomateでencodianのAPIキーを設定

Power Automateのアクションで`encodian` -> `Wordからテキストを取得する`を選択します。

> ![](https://i.gyazo.com/4ae8c79a71cb57d4d08f9de4968a4208.png)

## 3. シェアポイントなどからファイルを取得して読み込み

シェアポイントやOneDriveにWordファイル(.docxなど)を置いておき、

> ![](https://i.gyazo.com/252519e3b95982934cd3f793fed76a2c.png)

encodianのアクションで`ファイルコンテンツ`を選択します。

> ![](https://i.gyazo.com/85d60be6a486cfd895ee8e3fed2d2ad4.gif)

これで完了です。シンプルですね。

## 4. 実行

実行するとWordファイルの中身が取得できます。

> ![](https://i.gyazo.com/c695adc647fba7cee94ce4a4111a58fd.png)


## 5. おまけ

抽出された文字列は`テキスト`の動的コンテンツにあります。

> ![スクリーンショット 2024-06-05 8.35.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/3d2402a2-ac62-9694-3e58-4aa4c4976d5c.png "スクリーンショット 2024-06-05 8.35.43.png")

そのままテキストで利用できるのでTeamsに投げたり加工したりと色々できますね

> ![](https://i.gyazo.com/3e0b04176cf9c93d8e113b1281b99db6.png)

> Teamsに投げてみた
> ![スクリーンショット 2024-06-05 8.39.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35387/eab912ef-424b-b634-2319-15b534a58709.png "スクリーンショット 2024-06-05 8.39.22.png")
Windows 11 で 「新規作成」「テキスト ドキュメント」が出て来なくなった時の修復方法

### 現象説明
Windows 11 で エクスプローラーで右クリックした際に、テキストファイルの新規作成オプションがメニューに表示されない問題が発生しました。

ネット検索すると レジストリ編集の手順が出てきますが、
レジストリ編集以外の対処方法を紹介します。

### 手順

Windows 11 の 「設定」をクリックして
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134762/7c87bf35-cb06-a214-113b-acbaf8f36f95.png)

「アプリ」の中にある「既定のアプリ」をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134762/56266a97-8a2c-5d77-b854-2e445cbba0da.png)

画面を下にスクロールし、『ファイルの種類で規定値を選択する』オプションをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134762/eefedec6-bb7c-6d5f-69a7-4c30c1709940.png)

検索ボックスの中に `.txt` を入力すると
現在お使いのテキストエディタが表示されます。
※ 私は `サクラエディタ` です。

それをクリックすると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134762/1c27384c-16b9-36a3-10cf-0bbfb836a32e.png)

`.txt ファイルの既定のアプリを選択する` ダイアログが表示されるので
何も変更せずに `既定値を設定する` ボタンをクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134762/8da052fc-a01e-22ee-7fa2-7da5133f01d3.png)

これで 右クリックで テキストファイルが 新規作成できるようになりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/134762/31255cc9-c241-0a90-e60a-15b9b87813d1.png)

### 説明

以前も 右クリックで テキストファイルが作成できなくなる現象が発生して
その時は レジストリを変更して対処したのですが
レジストリ編集以外の方法が無いかと思って調査してみました。

もし、このような現象が発生した人は
上記手順を試してみて 状況が改善するか確認してみてください。

そして、うまくいった、うまくいかなかった等の情報を コメントで教えてくれると嬉しいです。
【備忘録】Gitのユーザ情報をディレクトリごとで管理する

# 概要
Gitアカウントをディレクトリごとで分けたい時の設定方法

## 使用したいアカウントごとの.gitconfigファイルを用意

```config:使用したいアカウントその1（.gitconfig_work）
[user]
    name = "アカウントその1"
    email = "アカウントその1@email.com"
```

```config:使用したいアカウントその2（.gitconfig_study）
[user]
    name = "アカウントその2"
    email = "アカウントその2@email.com"
```

## .gitconfigファイルにどのディレクトリでどのアカウントを使いたいかを記述

```config:.gitconfig
# workディレクトリ下の時に.gitconfig_workが読み込まれる
[includeIf "gitdir:~/work/"]
  path = ~/.gitconfig_work

# studyディレクトリ下の時に、.gitconfig_studyが読み込まれる
[includeIf "gitdir:~/study/"]
  path = ~/.gitconfig_study
```

## 最後に設定できているか確認
```terminal
~/work $ git config user.name
アカウントその1
~/work $ git config user.email
アカウントその1@email.com

~/study $ git config user.name
アカウントその2
~/study $ git config user.email
アカウントその2@email.com
```
Ansible スニペット プロンプト

https://docs.ansible.com/ansible/latest/collections/ansible/builtin/systemd_service_module.html#ansible-collections-ansible-builtin-systemd-service-module
↑適宜変更する。

上記のウェブサイトから、Parametersひとつずつの使い方を作成してください。

アウトプットは

#パラメータの役割や機能の説明(string/intger/boolean)※必須
- name: 

の様にテンプレ化をしてください。
ansibleスニペットまとめ

# `systemd`モジュールの各パラメータとその使い方

Ansibleの`systemd`モジュールを使用する際に設定できる各パラメータについて、その役割や機能、データ型、必須かどうかを以下にまとめました。

### state
- **役割や機能**: サービスの状態を指定します。`started`、`stopped`、`restarted`、`reloaded`のいずれかを設定できます。
- **データ型**: `string`
- **必須**: いいえ
- **例**
  ```yaml
  - name: Ensure service is running
    ansible.builtin.systemd:
      name: httpd
      state: started
  ```

### name
- **役割や機能**: 対象となるサービスの名前を指定します。
- **データ型**: `string`
- **必須**: はい
- **例**
  ```yaml
  - name: Stop a service
    ansible.builtin.systemd:
      name: httpd
      state: stopped
  ```

### enabled
- **役割や機能**: システムの起動時にサービスが有効かどうかを設定します。`yes`または`no`を指定できます。
- **データ型**: `boolean`
- **必須**: いいえ
- **例**
  ```yaml
  - name: Ensure service is enabled
    ansible.builtin.systemd:
      name: httpd
      enabled: yes
  ```

### daemon_reload
- **役割や機能**: システムdマネージャの設定をリロードするかどうかを指定します。`yes`または`no`を指定できます。
- **データ型**: `boolean`
- **必須**: いいえ
- **例**
  ```yaml
  - name: Reload systemd manager configuration
    ansible.builtin.systemd:
      name: httpd
      state: restarted
      daemon_reload: yes
  ```

### masked
- **役割や機能**: サービスをマスクするかどうかを指定します。`yes`または`no`を指定できます。
- **データ型**: `boolean`
- **必須**: いいえ
- **例**
  ```yaml
  - name: Mask a service
    ansible.builtin.systemd:
      name: httpd
      masked: yes
  ```

### scope
- **役割や機能**: サービスをユーザスコープまたはシステムスコープで操作するかどうかを指定します。`yes`または`no`を指定できます。
- **データ型**: `boolean`
- **必須**: いいえ
- **例**
  ```yaml
  - name: Start a service in user scope
    ansible.builtin.systemd:
      name: myservice
      state: started
      scope: yes
  ```

### no_block
- **役割や機能**: システムdコマンドをブロックしないで実行するかどうかを指定します。`yes`または`no`を指定できます。
- **データ型**: `boolean`
- **必須**: いいえ
- **例**
  ```yaml
  - name: Restart a service without blocking
    ansible.builtin.systemd:
      name: httpd
      state: restarted
      no_block: yes
  ```

これらのパラメータを使って、Ansibleでシステムdのサービスを柔軟に管理することができます。詳しくは公式ドキュメントをご参照ください。

参考リンク:
[Ansible `systemd`モジュール公式ドキュメント](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/systemd_service_module.html#ansible-collections-ansible-builtin-systemd-service-module)
【Swift】その URL が ファイル なのか ディレクトリ なのか 存在しないのか






# 🤔 ディレクトリなのか

```swift
print(
  URL.documentsDirectory
    .appending(component: "xxx")
    .hasDirectoryPath
)

// false
```

https://developer.apple.com/documentation/foundation/url/1780160-hasdirectorypath

「ディレクトリではない」のですが、

そのURLにファイルがあるのか、

または、何も存在しないのか、

分かりません。

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">【Swift】URL appendingPathComponent() vs appending(component:)<br>👉 <a href="https://t.co/QuNo1FoAIa">https://t.co/QuNo1FoAIa</a><a href="https://twitter.com/hashtag/%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0?src=hash&amp;ref_src=twsrc%5Etfw">#プログラミング</a> <a href="https://twitter.com/hashtag/ios?src=hash&amp;ref_src=twsrc%5Etfw">#ios</a></p>&mdash; chanzmao (@maochanz) <a href="https://twitter.com/maochanz/status/1798547907010048024?ref_src=twsrc%5Etfw">June 6, 2024</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 🤔 URL.resourceValues(forKeys:) を使う

https://developer.apple.com/documentation/foundation/url/1780058-resourcevalues

```swift
extension URL {
  var isDirectory: Bool {
    (try? resourceValues(forKeys: [.isDirectoryKey]))?.isDirectory == true
  }
}
```

```swift
print(
  URL.documentsDirectory
    .isDirectory,
  URL.documentsDirectory
    .appending(component: "xxx")
    .isDirectory
)

// true false
```

extension 内の条件式の左辺は、

```
URL先にリソースが存在してディレクトリのとき
→ true

URL先にリソースが存在してディレクトリでないとき
→ false

URL先にリソースが存在しないとき 
→ nil
```

となります。

# 🤔 詳細参考
https://android.benigumo.com/20240605/resource-values/

https://android.benigumo.com/20240606/appending-component/
GitHub actionの履歴をバッチで一括削除する

# 概要
GitHubCLIを使ってactionの履歴を一括削除する

### 条件
- Windows 11 Home

方針：GitHubCLIでアクション履歴をjsonで抽出、jqでIDを絞り込み、最後にGitHubCLIで削除する

## インストール
ghとjqをインストールする
- gh : GitHubCLI（GitHubのコマンドAPI）
- jq : Jsonをコマンド制御するツール

ターミナルを起動し以下のコマンドを打つ。コマンドを打ったらターミナルを再起動する。
```powershell
winget install --id GitHub.cli
winget install jqlang.jq
```

## コマンドを実行する
### その前にGitHubにログイン
Power ShellからGitHubログインのためにコマンドを実行し、画面に従って操作する。
```powershell
gh auth login
? What account do you want to log into? [Use arrows to move, type to filter]
> GitHub.com   ←こっちを選択
  GitHub Enterprise Server
  
? What is your preferred protocol for Git opertions on this host? [Use arrows to move, type to filter]
> HTTPS   ←こっちを選択
  SSH

? Authenticate Git with your GitHub credentials? (Y/n) y

? How would you like to authenticate GitHub CLI? [Use arrows to move, type to filter]
> Login with a web browser   ←こっちを選択
  Paste an authentication token

First copy your one-time code: xxxxxxx（コードが表示される）
Press Enter to open github.com in your browser ...
```
Enterを押すとブラウザでGitHub.comのログイン画面に入る
表示されたコードを打ち込んで、ContinueするとAuthorizeするか聞いてくるのでAuthorize githubを選択
画面に表示されたコードを携帯のGitHubアプリから2段階認証したら認証完了

### コマンドを実行してみる
以下のコマンドを実行する
```powershell
gh api /repos/{owner名}/{repository名}/actions/workflows/{.ymlファイルの名前}/runs?per_page=10 `
| jq '.workflow_runs[].id' `
| % { gh api -X DELETE repos/{owner名}/{repository名}/actions/runs/$_ }
```
#### GitHubのデータをjsonで取り出す
指定の.ymlファイルのアクションのデータをjson形式で出力する。ページ数によって検出に失敗する場合があるのでper_pageの値を調整し取得できる数値にする。
```powershell
gh api /repos/{owner名}/{repository名}/actions/workflows/{.ymlファイルの名前}/runs?per_page=10
```
#### jsonからIDを取得する
jqにてidを取り出す。
```powershell
jq '.workflow_runs[].id'
```
ステータスによって選別する場合は以下のようにする。Windowsではダブルクォーテーション(\")の前のにエスケープ文字(\\)がないと解釈できずエラーが出てしまう。
```powershell
jq '.workflow_runs[] | select(.status==\"completed\") | .id'
```
作成日時で選別する場合は以下の通り
```powershell
jq '.workflow_runs[] | select(.created_at<=\"2024-06-01T00:00:00Z\") | .id'
```
#### IDを指定してアクションを削除する
最後にIDを指定してアクションを削除する。
```powershell:windowsのみ
% { gh api -X DELETE repos/{owner名}/{repository名}/actions/runs/$_ }
```
#### 動作確認方法
以下のようにjqの処理までを実行するとIDの一覧が表示される。削除の前後に以下のコマンドを実行することで対象IDが削除されたことを確認できる。
```powershell
gh api /repos/{owner名}/{repository名}/actions/workflows/{.ymlファイルの名前}/runs?per_page=10 `
| jq '.workflow_runs[] | select(.status==\"completed\") | .id'
```
PodDisruptionBudget: Kubernetesの可用性を守る仕組み

KubernetesのPodDisruptionBudget (PDB) は、クラスタ内で必ず起動しておくべきPodの最小数を定義することで、計画的なノードのメンテナンスや予期せぬ障害の際にもサービスの可用性を維持するための重要な機能です。PDBは指定されたPodセレクタに一致するPodの最小または最大稼働数を設定し、DeploymentやReplicaSetなどのリソースに適用されます。PDBとkubectl drainコマンドが連携することで、ノードを安全にメンテナンスでき、Kubernetesクラスタの可用性とパフォーマンスを保てます。

## PDBのわかりやすい説明

PodDisruptionBudget (PDB) は、Kubernetesクラスタ内で常に利用可能であるべきPodの最小数を定義する仕組みです。これにより、計画メンテナンスや予期せぬ障害の際にもアプリケーションの可用性を維持できます。例えば、PDBで`minAvailable: 3`と指定すると、対象のPodは常に3つ以上起動している状態になります。`kubectl drain`でノードを停止する際も、PDBの予算を満たせる場合のみPodの退避が許可されるため、無秩序なPod削除によるサービス停止を防げます。このようにPDBは、シンプルな設定でKubernetesクラスタの可用性を高められる強力な機能なのです。本番運用では積極的に活用し、アプリケーションを安定稼働させましょう。

PodDisruptionBudget (PDB) は、Kubernetesクラスタ内のPodへの自発的な中断を制御するリソースです。PDBは指定されたPodセレクタに一致するPodの最小または最大稼働数を定義します。PDBでは、`.spec.minAvailable`か`.spec.maxUnavailable`のどちらかを指定する必要があります。`minAvailable`は常に利用可能であるべきPodの最小数を絶対値またはパーセンテージで指定し、`maxUnavailable`は無効状態でも良いPodの最大数を指定します。PDBはラベルセレクタを使って、Deployment、ReplicaSet、StatefulSetなどの他のリソースを対象とします。典型的なPDBの定義は以下のようになります。

```yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: nginx-pdb
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: nginx
```

この例では、`app: nginx`ラベルを持つPodに対し、最小1つのPodが常に利用可能であるべきことを定義しています。PDBはKubernetesの1.21でpolicy/v1 APIに昇格し、以前のpolicy/v1beta1 APIは非推奨となりました。PDBの基本概念を理解することは、Kubernetesクラスタの可用性を維持するために重要です。

## PDBの実際の使用例

PodDisruptionBudget (PDB) は、Kubernetesクラスタの運用で、様々な場面で役立ちます。以下に代表的な使用例を紹介します。

- ローリングアップデート時の可用性維持: DeploymentのローリングアップデートではPDBを設定することで、アップデート中も一定数のPodが常に利用可能な状態を保てます。例えば`minAvailable: 50%`と指定すれば、アップデート中も常にPodの半数以上が稼働し続けるため、サービス停止を防げます
- ノードメンテナンス時の安全性確保: `kubectl drain`でノードを計画的にメンテナンスする際、PDBと連携させることで、メンテナンス中もサービス可用性を維持できます。PDBの予算を満たす場合のみPodの退避が許可されるため、無秩序なPod削除によるダウンタイムを防止できます。 
- クラスタオートスケーラとの併用: クラスタオートスケーラ(CA)によるノード削除時もPDBを設定しておけば、必要最低限のPod数を確保しつつスケールダウンできます。CAはPDBの予算を考慮してノード削除を行うため、サービス可用性を損なわずにコスト最適化が実現できます
- ゾーン障害時の影響緩和: マルチゾーンクラスタではPDBを用いることで、単一ゾーンの障害時にもサービス全体の可用性を維持できます。複数ゾーンにPodを分散させつつ、PDBで全体の最小Pod数を定義しておけば、1ゾーンが停止してもサービスは継続できます

このようにPDBはKubernetesクラスタのあらゆる局面で、サービス可用性と安定性の向上に寄与します。適切なPDBを設定し、クラスタ運用に役立てていきましょう。

## PDBとkubectl drainの連携

PDBとkubectl drainコマンドは連携して動作し、ノードのメンテナンス時にサービスの可用性を維持します。kubectl drainでノードを排除する際、PDBで定義された予算を満たしている場合のみPodの退避が許可されます。

例えばPDBでminAvailableを4に設定している場合、kubectl drainによってPod数が4未満になる退避は拒否されます。一方maxUnavailableを1に設定した場合、kubectl drainは常に1つのPodのみ退避可能です。ただし、maxUnavailableの場合はPod数が1の時に一時的に全てのPodが利用不可となるリスクがあるため注意が必要です。

また、kubectl drainは設定したタイムアウト時間までPDBの予算を満たすまで退避要求を再試行し続けます。タイムアウトは`--timeout`フラグで指定でき、デフォルトは0s(無期限)です。再試行の間隔は`--delete-local-data`フラグで調整できます。

このようにPDBとkubectl drainが連携することで、Kubernetes上で安全で確実なノードメンテナンスが実現できます。
【Slack】入社1年目、チャット上でのコミュニケーション円滑化に向けて動く

## はじめに
Slackは、コミュニケーションツールとしてとても便利だと思います。
私はCrane&Iに入社するまでは使用したことがなかったので、使いやすくて便利だな～と新人のときに感じたのを今でも覚えています。

しかし、使用しているうちに私の中で違和感や危機感を覚え、それに対してどのように解消しようとしたか綴ろうと思います。

エンジニアにおける技術やマインドの内容ではないですが、自分にとっての"**プチ成功体験**"かつ"**日頃からの課題意識と解決への行動**"に繋がるエピソードなので、お付き合いいただけたら嬉しいです:cactus:

## 結論
きっかけやどのような行動をとったかを後述しますが、この記事でお伝えしたいことをサマリとして最初に述べておきます。
興味を持ってくださった方は、このまま読み進めていただけたら幸いです。

<font color="Red">**~文字リアクションを駆使し、コミュニケーションを円滑化させ意思疎通を図る~**</font>

* 何も反応しないのは、相手にとても失礼になってしまう
* 文字リアクションは、お礼や状況、感情を伝えられる
* 文字リアクションは、余計な通知にならない
※状況によってリアルタイムで知らせた方がいい内容もあるため、適宜返信と使い分ける必要あり

　→ "**リアクションすること**"は、<font color="Red">**相手への状況伝達および配慮に繋がる**</font>

## 文字リアクションを活用するまでの流れ
### - この違和感はなに？
今から3年以上前です。
新人研修期間は出社とテレワークのハイブリット型だったため、コミュニケーションは比較的取りやすい方でした。
（テレワークでもZoomを繋げていたため、「Slack見た？」などが口頭でできていた。）

その後現場配属になって会社と日常的な関わりがなくなり、社内連絡も最小限となった際に、ちょっとした違和感が。
当時は会社全体でSlackのコミュニケーションがあまり円滑でないように見受けられ、返信率もぼちぼちでした。
ましてや、リアクションがほぼ既存の絵文字のみだったので、返信しない限り「ありがとうございます」「対応します」というお礼や状況すら相手に伝えられない状況でした。

**「ただでさえ客先常駐で社内の方々と関わる機会が少ないのに、この状況のままだと帰属意識がどうこうどころではないのでは。。？？」**

新人ながら、このように勝手に危機感を覚えていました。
違和感から危機感に変化したときには、もしできるなら上層部へ改善提案をしよう！と考え始めました。

### - だったら都度返信しよう！という思考にはならなかった
現状の環境でできることとして、「ありがとうございます」「対応します」を返信するくらいで、やらないよりましだと思ってはいましたが、それを実行しようという安直な気持ちはありませんでした。
なぜなら、さまざまな重要な内容の通知が飛び交う中で、**文字として通知する必要があるか人によって意見が分かれる**からです。

社内ではなく現場のエピソードにはなりますが、実際に「通知がきすぎてどれが重要な内容なのか判断がつかない」という声も多く聞こえてきました。
このお言葉があったからこそ、当時の私は返信したらいいというものではないんだなと学びました。

### - じゃあどうしよう？
正直、悩んでいる時間はそんなに多くなかったです。
社内のSlackにはすでに、"**承知いたしました**"の文字リアクションがあったからです。
この存在に気づいたときに、もっと他にバリエーションを増やせば、相手に状況を伝えられるし通知がいくこともない、と悩みの種が一気になくなる瞬間でした。

"承知いたしました"はあるのか。。ならもっと作るしかない！となり、当時の上司に許可を得て、さまざまな種類の文字リアクションを大量生産＆リリースしました。

### - 文字リアクションの効果
特にリリース周知などは行わなかったのですが、社員の皆さんに自然と使用していただけて、業務に限らず雑談チャンネルでも文字リアクションを使用してのコミュニケーションが以前より円滑・活発化したように思います。
本社勤務のある営業さんからも、「状況把握できるし、文字リアクション助かってる！」と直接お言葉をいただけたので、作成してよかったと改めて感じました。

集計を取ったわけではないですが、社内で頻繁に見かける文字リアクションは以下です。
* ありがとうございます
* よろしくお願いします
* すてき♥
* 気になる

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726107/c0418275-a181-c496-504e-cb8dfeee5fd6.png)

男性が多く在籍している会社なので、とりあえず女性向けに"すてき♥"を作りましたが、性別問わず意外と頻繁に使われていてうれしい限りです:relaxed:

実はひっそりと増やし続けているので、今後もちょこちょこリリースしようと思います。
（きちんと許可はいただいてます。）

## 何も反応しないのは、"相手を不安にさせる行為"である
冒頭の結論にて、「何も反応しないのは、相手にとても失礼になってしまう」と記載しました。

自分が発信した立場になって考えてみてください。
* チャットで周りに向けてスレッドを立てたのに、反応がまばらで見てくれたのか？
* プレゼンで良い顔も悪い顔もされず、相手に内容が刺さってるのか？

反応がないと相手の状況や心情がわからなくて、とても不安になりませんか？
ましてやSlackは既読機能がないため、既読による「見ましたよ」の意思表示ができません。

私は、無反応を（ちょっと大袈裟だけど）"**相手を不安にさせる罪**"だと思っています。
と同時に、暗に**承知**してくれているんだろうなとも思っていますが、<font color="Red">**発信する側からするとやはり反応はいただきたいものです**</font>。

リアクションひとつで配慮に繋がるので、今まで自分の中で完結してリアクションしてなかったな～と心当たりがある方は、是非このひと手間を行動に移していただきたいです。
※Slackなどのチャットに限らず、対面のコミュニケーションも同様です！

## 最後に
今回は、Slack上のコミュニケーションを円滑化させるために文字リアクションを導入したお話をさせていただきました。
まだSlackを導入したての会社さんは、是非文字リアクションを使用してみてください！

最後までお読みいただき、ありがとうございました:thumbsup_tone1:
Kubernetes NodePortサービスの設定方法: port, nodePort, targetPortの役割と使い分け

## 概要

KubernetesのNodePortサービスの設定では、port、nodePort、targetPortの3つのポートを指定できます。これらのポートはそれぞれ異なる役割を持ち、NodePortサービスの動作を制御します。

NodePortは、クラスター外部からKubernetesクラスター内のサービスにアクセスするための方法の1つです。NodePortサービスを作成すると、Kubernetesは各ノード上に指定されたポートを開き、そのポートへの通信をサービスに転送します。NodePortサービスを設定するには、サービスマニフェストの`spec.type`フィールドを`NodePort`に設定し、`spec.ports`フィールドで公開するポートとターゲットポートを指定します。また、`nodePort`フィールドを使用して、ノード上で公開するポートを指定することもできます。指定しない場合、Kubernetesは30000から32767の範囲でポートを自動的に割り当てます。

NodePortサービスは内部にClusterIPを持ち、クラスター内の他のPodからはClusterIPを介してアクセスできます。外部からのアクセスは、任意のノードのIPアドレスとNodePortで指定されたポートを介して行われます。NodePortは、Kubernetesによる負荷分散の制御が限定的な場合や、独自の負荷分散機構を使用する場合に適しています。ただし、NodePortだけでは複数ノード間の負荷分散は行われないため、必要に応じて外部のロードバランサーと組み合わせて使用します。

## targetPortの詳細と使用例

targetPortは、Serviceが転送するトラフィックを受け取るPod内のポート番号またはポート名を指定します。これにより、ServiceとPodの間でポートマッピングを柔軟に行うことができます。デフォルトでは、targetPortはServiceの`port`フィールドと同じ値に設定されますが、異なる値を指定することで、Serviceが公開するポートとPodが受け取るポートを別々に設定できます。これは、バックエンドソフトウェアのバージョンアップ時にPodのポート番号を変更する場合などに便利です。

また、targetPortには、Pod内で定義されているNamedPortを指定することもできます。NamedPortを使用すると、同一のService内で複数の種類のPodが混在している場合でも、ポート名を介して適切なPodにトラフィックを転送できます。

使用例として、以下のようなServiceマニフェストがあります。

```yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
    - port: 80
      targetPort: 8080
  type: NodePort
```

この例では、Serviceは80番ポートで受け付けたトラフィックを、`app: MyApp`ラベルが付与されたPodの8080番ポートに転送します。targetPortを適切に設定することで、Serviceとバックエンドのポートマッピングを柔軟に行い、アプリケーションの要件に合わせたネットワーク設定を実現できます。

## portとnodePortの違いと使い分け

portとnodePortは、KubernetesのNodePortサービスにおいて重要な役割を持つ設定項目ですが、その役割と使い分けは異なります。portは、Serviceが公開するクラスター内部のポート番号を指定します。これは、Serviceに割り当てられたClusterIPに対して使用されるポートであり、クラスター内の他のPodからこのポートを介してServiceにアクセスできます。

一方、nodePortは、各ノード上で公開されるポート番号を指定します。これは、クラスター外部からServiceにアクセスするために使用されます。外部のクライアントは、任意のノードのIPアドレスとnodePortで指定されたポートを介してServiceに到達できます。

portとnodePortの使い分けは、以下のように整理できます。

- クラスター内部の通信には、portを使用する。PodはClusterIPとportを使ってServiceと通信する
- クラスター外部からのアクセスには、nodePortを使用する。外部クライアントは、ノードのIPアドレスとnodePortを使ってServiceにアクセスする

nodePortを明示的に指定しない場合、Kubernetesは30000から32767の範囲で空いているポート番号を自動的に割り当てます。

以下は、portとnodePortを指定したServiceマニフェストの例です。

```yaml
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: NodePort
  ports:
    - port: 80
      nodePort: 30001
  selector:
    app: MyApp
```

この例では、Serviceは内部的に80番ポートを公開し、外部からは30001番ポートでアクセス可能になります。portとnodePortの適切な設定と使い分けにより、Serviceのアクセシビリティを柔軟に制御できます。

portとnodePortのセキュリティ面での違いは、nodePortがクラスター外部からアクセス可能であるため、適切なセキュリティ対策が必要になることです。一方、portはクラスター内部でのみ使用されるため、相対的にセキュリティリスクは低くなります。

nodePortを使用する際のパフォーマンスへの影響は、各ノードでポートを開放し、トラフィックを転送する必要があるため、大量のトラフィックが発生する場合にはオーバーヘッドが増大する可能性があります。負荷分散の観点からも、外部のロードバランサーと組み合わせて使用することが推奨されます。

nodePortの設定でよくあるトラブルシューティングとしては、ファイアウォールによるポートの制限、ポート番号の競合、セレクターラベルの不一致などが挙げられます。これらの問題を解決するには、ファイアウォールの設定確認、ポート番号の変更、ラベルの修正などを行います。
タスクは細かく分割したほうが達成感がある

# 「小さなチーム、大きな仕事　働き方の新しいスタンダード」より


>長いリストは罪悪感を抱かせる。
>
>完了していない項目のリストが長くなればなるほど、あなたの感情はネガティブなものになるだろう。
>そしてある時点で、嫌な気分になり、あなたはそのリストを見るのをやめてしまう。それからあなたはストレスでイライラし、すべてが台無しとなる。
>
>もっといい方法がある。
>
>その長いリストを、いくつものより小さなリストに分解するのだ。たとえば100項目の一つのリストを10項目の10のリストへと分解する。これはリストの中の一つの項目を終えたときにリストの一パーセントではなく10パーセントを完了したことを意味する。
>
>確かに、あなたにはまだ同じ量だけやることが残っている。でもあなたは小さな世界を見て、満足やモチベーション、そして進捗を得ることができる。これは巨大な世界を見つめてゾッとし、モチベーションを挫かれるよりもはるかにいい。

<img width="264" alt="image" src="https://github.com/YumaInaura/YumaInaura/assets/13635059/0ff08888-b1f2-4881-b468-f4f1201a3bd6">

# 感想

自分も本当にタスクを細かく細かく分解して達成感を感じている。PRもなるべく細かく分ける。
そしてイテレーションの最後に、たくさんの完了タスクを見ては悦に浸るのだ。

あとこの方法の良いところは自分のステータス把握しやすいところだ。
細分化そのものではないが、どんなに小さなタスクでもタスク管理ツールに積んで、終わったら完了状態にする。

このリズムがとても良い。
vbsの作法 その78

# 概要
vbsの作法、調べてみた。
vbs見つけたので、やってみた。

# 参考にしたページ

https://qiita.com/yuntas/items/cafa3c40eb635418b40d

# 環境
windows11

# サンプルコード

```
Set WshShell = CreateObject("WScript.Shell")
MsgBox ConvertToKey(WshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\DigitalProductId"))

Function ConvertToKey(Key)
	Const KeyOffset = 52
	i = 28
	Chars = "BCDFGHJKMPQRTVWXY2346789"
	Do
		Cur = 0
		x = 14
		Do
			Cur = Cur * 256
			Cur = Key(x + KeyOffset) + Cur
			Key(x + KeyOffset) = (Cur \ 24) And 255
			Cur = Cur Mod 24
			x = x - 1 
		Loop While x >= 0
		i = i - 1
		KeyOutput = Mid(Chars, Cur + 1, 1) & KeyOutput
		If (((29 - i) Mod 6) = 0) And (i <> -1) Then
			i = i - 1
			KeyOutput = "-" & KeyOutput
		End If
	Loop While i >= 0
	ConvertToKey = KeyOutput
End Function

```

以上。
心房細動履歴が有効にできない時に確認する項目

心房細胞履歴が有効にしようとすると「"この地域では有効にできません"」となって、有効化できないときに試した方法です。有効化できたら、「いいね」ください。
- 基本
  - watch は Series 4以上
  - iPhoneのOSアップデート
  - watch OSのアップデート
- 設定
  - iPhoneの地域を日本に
  - Apple watchの地域をカスタム（日本） or iPhone参照に
  - 手首検出と心拍数検出を有効に
  - Apple IDアカウントの年齢を22才以上に
- 操作
  - 心拍数ではなく心電図を〇〇日以内に取得

自分は、久しぶりに心電図を取ったら、心房細動が有効化出来るようになりました。やったー
お姉さんとイケないことシない？ - 配列への安全な範囲外アクセス

というわけで 備忘録的な話ですが、C# の 配列へのアクセス時に 範囲外のアクセスをすると `IndexOutOfRangeException` が発生してアクセスできません。

ただ、配列から `Span<T>` が取れる為、範囲の外にアクセスする方法が無いわけでもないのです。

というのが、今回の趣旨です。

:::note warn
この記事は `ReadOnlySpan<T>` から `Span<T>` を取得したり、配列から範囲外を含む `Span<T>` を取得したりしていますが、それを推奨する記事ではないです。
そういう手段が存在するというのを伝える為の記事です。
:::

# やってみる

```csharp
using System;
using System.Runtime.InteropServices;

int[] array = [1,2,3,4,5];
var span = MemoryMarshal.CreateSpan(ref MemoryMarshal.GetReference(array.AsSpan()), 10);
Console.WriteLine(string.Join(',', span.ToArray()));
```

[sharplab](https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUKgBgAJVMA6AJWmAEsBbAUzIEkpgGwB7ABwGUOAbjQDGDAM4BuPHhpsA2gF0iAQzBhlATyIBeInMwx0MAMwwALDACsCqbgGqiY7sqg6iAWQZ1OYDe9ViABbKADZkAMJgDMrsvM5QABRRAGYeXj5+AcFhAOIMwBQMyRwMUKIJquoaZACCYnEuCQCUTTBEmARNtqQAnAmkBGQAUpyyCQDkMJOO8WQAKpw1aprNLRJAA===)

```text:output
1,2,3,4,5,0,0,0,-39468856,32760
```

配列の範囲である length:5 以降にもアクセスできてしまっており、 未初期化領域にもアクセスが特にエラーなくできています。

以上。
Pythonにおける==とisの違い

# 前書き
Pythonにおける比較演算子として==演算子とis演算子があります。
これらは混同されがちですが、その明確な違いについてメモしておこうと思います。

# 結論
==演算子はオブジェクトの等価性を比較し
is演算子をオブジェクトの同一性を比較する

# 説明

### ==演算子

==演算子は、オブジェクトの値が等しいかどうかを比較します。
つまり、オブジェクトが同じ**内容**であるかどうかをチェックします。
例えば、`a == b`は、aとbの値が等しい場合にTrueを返します。

### is演算子
is演算子は、オブジェクトの同一性を比較します。
つまり、オブジェクトが同じ**メモリ位置**を指しているかどうかをチェックします。
例えば、`a is b`は、aとbが同じオブジェクトを指している場合にTrueを返します。

# 確認
下記の例では?の箇所に==もしくはisが入ります。
どちらが適切でしょうか。

### 例1
```
a = [1, 2, 3]
b = a
if a ? b:
    print("Same object")
else:
    print("Different objects")
```

<details><summary>解1</summary>

この例の場合、同じオブジェクトであるかを確認しています。
よって、`==`が適切です。
```
a = [1, 2, 3]
b = a
if a == b:
    print("Same object")
else:
    print("Different objects")
```
</details>

### 例2
```
def check_none(value):
    if value ? None:
        print("Value is None")
    else:
        print("Value is not None")

check_none(None)
```

<details><summary>解2</summary>

NoneはPythonにおいて「値が存在しないこと」を示す特別なオブジェクトであり、変数が初期化されていない場合や関数が値を返さない場合に自動的に設定されます。
Pythonではis演算子を使ってNoneオブジェクトを判定することが一般的です。
よって、`is`が適切です。
```
def check_none(value):
    if value is None:
        print("Value is None")
    else:
        print("Value is not None")

check_none(None)
```
</details>

# まとめ

==演算子は、オブジェクトの内容が等しいかどうかを比較する。
is演算子は、オブジェクトのメモリ番地が等しいかどうかを比較する。

:::note info
コードやテキストに正確性について十分気を付けていますが、誤りや修正点などがあればお気軽にコメントください。
:::
【AtCoder】比較関数を使ったソート（sort）

## ポイント
**sort関数の第三引数で比較関数を設定できる。**

```c++
#include <bits/stdc++.h>
using namespace std;
using vs = vector<string>;

int main() {
  vs T = { "c", "bb", "aaa" };
  
  // 辞書順ソート
  sort(T.begin(), T.end());
  for (string s : T) cout << s << " "; // "aaa", "bb", "c"
  cout << endl;

  // 文字数ソート（比較関数の活用）
  auto cmp = [&](string &s, string &t) { return s.size() < t.size(); };
  sort(T.begin(), T.end(), cmp);
  for (string s : T) cout << s << " "; // "c", "bb", "aaa"
  cout << endl;
}
```

## 例題

[ABC308C - Standings](https://atcoder.jp/contests/abc308/tasks/abc308_c)

```C++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)

int main() {
  int N; cin >> N;
  vector<int> A(N), B(N), ans(N);
  rep(i, N) cin >> A[i] >> B[i];
  rep(i, N) B[i] += A[i];
  
  rep(i, N) ans[i] = i;
  stable_sort(ans.begin(), ans.end(), [&](int i, int j) {
    return (ll)A[i] * B[j] > (ll)A[j] * B[i];
  });
  
  rep(i, N) cout << ans[i] + 1 << " ";
  cout << endl;
}
```

### 補足

比較値が等しい時に順番を入れ替えたくない場合は、stable_sortを使うと便利！

```C++
// stable_sortを使わない場合
auto cmp = [&](int i, int j) {
  ll v1 = (ll)A[i] * B[j], v2 = (ll)A[j] * B[i];
  if (v1 == v2) return i < j;
  return v1 > v2;
};
sort(ans.begin(), ans.end(), cmp);

// stable_sortを使う場合
stable_sort(ans.begin(), ans.end(), [&](int i, int j) {
  return (ll)A[i] * B[j] > (ll)A[j] * B[i];
});
```
初挑戦 VSCodeエクステンション作ってみました。ファイルパス指定のコマンド実行を楽ちんに♪

私が最近開発したVisual Studio Code（VSCode）の拡張機能「ContextPathCommander」についてご紹介します。

## 転載元
当記事は以下ブログからの転載です。
[TECH BACK](https://techback.info/efficiency-with-first-vscode-extension/#google_vignette)

## こんなことができます
開発している時にターミナルでファイルパスをパラメータにしてコマンド打つことが多いので、それを簡単にしようと。

Pythonの開発を行っているので、ドット区切りのパス指定もできると捗るよなと。

例えば、
~~~
cat ./aaaa.py
~~~
みたいにパスをパラメータにコマンドを実行する際に、パスを打ったりコピペしたりするのが面倒なんで、登録しておいたコマンドにパスを付与して簡単に実行できるようにしています。

Pythonのテストを実行する時なんかに重宝しています。
~~~
python manage.py test api.TestClass --keepdb --parallel 
~~~
## 使うまでの準備
### インストール
普通のVSCodeのExtensionインストールです。

contextpathと検索してもらうと、下のように出ますんでインストールしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/47b7cbdf-5083-cd75-b8c5-95b14d42fd1c.png)


### 設定
Settingsに用意しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/b899df05-f949-66c1-1b76-7bb02f8f0dce.png)



Edit in setting.jsonのリンクをクリックしてもらうと、setting.jsonが開くので
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/ec0a6fce-b073-8d15-5946-78d5716709e1.png)



下記のようにコマンド毎に登録していきます。（設定内容については後ほど）
~~~
{
  "contextPathCommander.commands": [
      {
          "title": "Show File Content relativePath",
          "script": "cat ${relativePath}",
          "description": "test 相対パス"
      },
      {
          "title": "Show File Content absolutePath",
          "script": "cat ${absolutePath}",
          "description": "test 絶対パス"
      },
      {
          "title": "Show File Content dotSeparatedPath",
          "script": "cat ${dotSeparatedPath}",
          "description": "test ドット区切りパス"
      }
  ]
}
~~~
### 設定する内容
それぞれの項目名については下記のとおり。
| 項目名 | 内容 |
|:-|:-|
| title  |  表示するタイトル |
| script  |  実行するコマンド（パスの指定については別途） |
|  description |表示させる説明   |


コンテキストメニューで選択後に、QuickPickに登録したコマンドが表示されるのですが、title/descriptionについては、それぞれ下の図のような表示になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/3176da45-c610-1497-cf01-8b4e4a98aea8.png)


scriptの箇所には、実行したいコマンドを記入してください。その際、パスをパラメータとして含めたい場合は、プレースホルダを含めてください。

対応しているパス指定ですが、下記の３つに対応しています。
| パスの種類 | プレースホルダー | こんなパス |
|:-|:-|:-|
| フルパス  | ${absolutePath}  |/Users/user_name/project_dir/src/extension.ts   |
|相対パス   | ${relativePath}  |./src/extension.ts  |
| ドット区切り相対パス  |${dotSeparatedPath}   | src.extension  |

## 使用方法
EXPLORERでコマンドに含めたいファイルを右クリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/0ee297ce-9235-3db1-8cfa-850ed7bcd275.png)


または、Editウインドウ内で右クリックして、Context Path Commanderをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/6f9cd48b-e3e4-b46b-6815-7667341f26ab.png)


すると上部QuickPickにsetting.jsonに登録したコマンドが表示されます。あとは、実行したいコマンドを選択すると実行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/096e0515-b425-133a-8848-02b71bb3d17f.png)


こんな感じ。catコマンドで登録しているのでファイルの内容が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450952/0025af23-24f0-6f61-470f-6da22242c370.png)
プロトコル・アダプタ・エラーでSQLPlusが起動できない場合の解決方法

# エラー内容
OracleDatabaseをインストールして、コマンドプロンプトからSqlplusを起動しようとすると
`ORA-12560: TNS:プロトコル・アダプタ・エラーが発生しました`というエラーが出ました。ただ、Sqlplusが繋がらないだけでA5M2等を使えばデータベースに通常通りアクセスはできました。

# 解決策
OracleDatabaseを入れる前にOracleDatabaseClientを入れたのが原因か、Pathの設定に
`C:\app\ユーザー名\product\19c\client_1;` `C:\app\ユーザー名\product\19c\client_1\bin`という2つのPathが存在していました。さらにsqlplusが2箇所に存在しているようでした。

なので、Windowsのシステムのプロパティを開き環境変数の設定を変更します。
編集で`C:\app\ユーザー名\product\19c\client_1;`を削除しました。

# 一件落着
以上でSqlPlusが起動するようになりました。

それでも同じエラーが出る場合は`サービス`からOracleがそもそも起動しているのか確認しましょう。
未経験でIoT系研究開発職に転職した人の学習記録 #0

<h1>初投稿

もう何回こすられてきたかわからないようなタイトルですが、表題のとおり、未経験転職系エンジニアがゼロから学習していく様を記録していく記事です。

普段OneNoteに記録しているようなメモ書きレベルの備忘録を私自身の学習記録として残していくのと、習慣化につながるかなと思い始めてみました。

一つの記事にするのがはばかられるような内容になると思いますが、なんせ飽き性なものでして、継続を最優先事項とするため、記事の質や量は二の次で良いというスタンスで行きます。

仮に継続できたとすれば、質も量も上がっていくと考えていますし、おそらくこの記事に黒歴史感を感じて修正をかけるはずです（そもそも修正できるのか？そんなことすら知りません）

とはいえ、目標や立場ぐらいは明確にしないといけないなと思いますので、その辺は改めて投稿していこうかなと。
とりあえず初回ということで簡潔に自己紹介です。

<h2>経歴と現状</h2>

学歴：偏差値50に届かない程度の電子情報通信系学科の学部卒。研究は弱電の回路がほとんどでプログラミングの経験は授業のC言語半期と、ArduinoのLチカ程度。

前職：メーカーでパワーサプライや無線制御ユニットの開発（実態は要求仕様を書いて外部に投げて評価する上流工程だったので設計力はないです）。

現職：メーカーの研究開発。IoT関連でWiFi,BLE,LoRaなどなど幅広く無線に関与。
関係してくる言語は、組み込みCやらAWSやらラズパイ(Linux,Python)やら


<h2>困りごと</h2>
とにかく同僚が当たり前のように使っているLinuxやC言語など、プログラミングの基礎知識がなさ過ぎて本題に入る前に躓いてしまっている状況で自己肯定感下がりっぱなしです。

この状況を打破すべく、まずはC言語を基礎から根本的に理解してやろうと。
で、安直ですが体系的な学習として書籍を一冊走りきることを目標に、学習記録を残していきます。

<h2>学習記録 #0</h2>
Amazonで評判が良かったこちらの書籍で学習を進めていきます。

 「C言語 新版 ゼロからはじめるプログラミング」三谷 純 著

自分の性格的に、三日坊主を回避することが一番の難関ですので１日１項を最低目標とします。
（本当は1日1章ぐらい進めたいですが、たぶん仕事の後にこの量は続かないので、、、）

ちなみに、全8章、28節、約110項と応用8項の構成になっていますので、最低ノルマの場合は完了に3か月要します。
実際には丸1か月で終わるペースになればいいかな。


今日の進捗を置いて、初投稿とします。

第1章　C言語に触れる
1-1 C言語に触れる

VSCodeでsampleファイルを開くとエラー出現
まさかここで躓くとは思わなかった笑
”#include エラーが検出されました。includePath を更新してください。"

いろいろ調べるとVSCodeの公式が一番わかりやすかったので下記ページに沿って実行
https://code.visualstudio.com/docs/cpp/config-mingw
 GCC、g++、GDBが正しくインストールされていることを確認し、HelloWorldの出力を確認できました。

 てかGCC、g++、GDBってなんぞ？

ということですでにAM2時なので寝ます。
本日は1節で終了です

道のりは長い、、、
React Flowでできること一覧

# はじめに
私は今、React Flow[^react-flow]を使ったWebアプリケーションの開発に携わっています。
[^react-flow]: React Flow. https://reactflow.dev/

そこで、React Flowを使ってできることを備忘録としてまとめておきます。

新しいものを見つけ次第追加していきます。

# できること一覧

## ドラック&ドロップでノードを追加できる

https://reactflow.dev/examples/interaction/drag-and-drop

## ノードとリンクのレイアウトを自動で変更できる

https://reactflow.dev/learn/layouting/layouting

## ズームレベルによってノード内の文字を表示するかどうかを切り替えることができる

https://v9.reactflow.dev/examples/contextual-zoom-features

## mapの座標などを取得することができる

https://reactflow.dev/learn/advanced-use/devtools-and-debugging

## figmaみたいな操作方法に変更することができる

https://reactflow.dev/learn/concepts/the-viewport

## 右クリックでメニューを開ける

https://reactflow.dev/examples/interaction/context-menu
RailsのDeviseで複数のモデルを使っている際に、メールテンプレートをそれぞれで変更する方法

[株式会社TECH LUCK](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)という会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご連絡いただけますと幸いです。

# 前提

RailsでDeviseを利用している際に、複数のモデルでDeviseを利用したいという場面があると思います。
例えば、一般ユーザーであるUserモデルと企業ユーザーであるCompanyモデルでDeviseを利用したいという場面です。

その際に、複数のモデルにDeviseを導入することはできますが、メールアドレス認証のメールのテンプレートを、それぞれのモデルごとに変更したいということがありました。

その際に、調べてみてもあまり情報が出てこなかったので備忘録としてまとめておきます。

この記事の構成としては以下のようになっています。

1. Userモデルのメールテンプレートを設定する
2. Comanyモデルのメールテンプレートを設定する

# Userモデルのメールテンプレートのカスタマイズ方法
調べれば情報が多く出てきますので、詳細には記載しません。
以下の記事と同じ手順・設定で行いました。


# Companyモデルのメールテンプレートのカスタマイズ方法
Userモデルのメールテンプレートのカスタマイズ設定を行うと、Companyモデルも同じメールテンプレートを利用されることになります。

というのも、以下の設定を行なってしまうと、Deviseから作られたモデルのメールテンプレートは`Users::Mailer`が利用されることになるからです。

```devise.rb
config.mailer = 'Users::Mailer'
```

そのため、Companyモデル内で以下のメソッドを定義すると、違うメールテンプレートクラスを利用することができるようになります。

```company.rb
class Company < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  devise :database_authenticatable, :registerable,
         :recoverable, :rememberable, :validatable, :confirmable, :trackable, :timeoutable, :lockable

  # ここでメソッドを定義
  def devise_mailer
    Companies::Mailer
  end
end
```

これを記述するだけで、Companyモデルでは`Companies::Mailer`のメールテンプレートを利用する設定になります。
あとは`Companies::Mailer`を作る、`Users::Mailer`と同じ設定をすれば、モデルごとに違うメールテンプレートを利用することができます。

```mailer.rb
class Companies::Mailer < Devise::Mailer
  helper :application
  include Devise::Controllers::UrlHelpers
  default template_path: 'devise/mailer'

  # メールアドレス変更の際の認証メール
  def confirmation_instructions(record, token, opts = {})
    opts[:subject] = "メールアドレス変更手続きを完了してください"
    super
  end

  # 新規登録の際の認証メール
  def confirmation_on_create_instructions(record, token, opts = {})
    opts[:subject] = "メールアドレス認証のお手続を完了してください"
    @token = token
    devise_mail(record, :confirmation_on_create_instructions, opts)
  end
end
```
VBAで職場は変わる！

皆さんこんにちは。
私はIT業界にエンジニアとして就職して9年目を迎えました。
SIerやSESで働いている中で色々な経験や失敗を積んできましたが(今も)、その経験から学んだことや現在勉強していることなどを投稿していければと思いますので是非とも読んでくれると嬉しいなと思います。

# VBA
さて、今回のテーマは*VBA*にしました！
VBAというワードを聞いて何を思い浮かべるでしょうか？
「何かしらのツール」「なんとなく聞いたことはある」こんな人は結構いるのでは？と思います。
仕事をチームで行っていると日々チーム全員で使用するファイル(管理表みたいなものをイメージしてください)を更新したり、工数を付けたりと手動で行う業務が結構あったりします。
また、日々の業務で手動で行っている業務の中で面倒だなーと思う業務があると、人はストレスを抱えやすくなり、ミスをしたりします。
こういった面倒くさい業務を効率化(自動化)できたらほんの少しだけ未来が明るくなると思いません？
ちなみに私は思っています笑

それを可能にするのがプログラミング(言語は問いません)です！
色々な言語がある中で誰もが手軽に始められるのが*VBA*なんです！
※VBAはエクセルが使えれば始められます。

VBAを始めたいけどよく分からない、どうやって勉強したらいいの？と悩んでいる方も結構いるのが現状だと思いますので、今回は*VBAの始め方*について投稿したいと思います！

# VBAについて
さて、まずはVBAについて簡単に説明します。
VBAとは一般的には「マクロ」と呼ぶ人が多いかなと思いますが、、VBA(Visual Basic for Applications)というプログラミング言語のことを指します。
※マクロとは、VBAで覚えさせた操作を自動で行う機能の名称です。

# VBAを始めるための準備
さてVBAを書いてみようと思った方、エクセルを開いてそのままかけるわけではありませんので要注意！
まずはエクセルでVBAを書くための準備をしましょう。
準備は以下の2つ。
* エクセルファイルに開発タブを表示させる
* エクセルのファイルの種類を「マクロ有効ブック(.xlsm)に変更する
この2つを行いましょう！
※以下のURL参照。
https://www.sejuku.net/blog/6257

# VBAの始め方
さてここまで準備ができたらいよいよプログラミングを始めましょう！(コードを書いてみよう！)
と言いたいとこですが、この投稿を読んでいる時点でVBAやそれ以外の言語(例：Java Script,C,Pythonなど)の勉強をしたことや見たことが無いという方が多いと思います。
そんな状態でコードを書き始めても難しくて諦めてしまう方が多いと思いますので、私が今まで使用してきた方法の中で本当に役に立ったVBAの勉強ツールを3つご紹介します！

# 1.会社や職場にいるVBAマスターに教えてもらう
これは数年前にいた現場で私が実際に体験したことです。
それまではエクセルで関数を使用して効率化をしていたのですが、関数では実現できない処理を行いたい常態に直面しました。(関数の限界を知りました(´;ω;｀))
そんな時、職場にVBAを完璧に使いこなせる先輩がいたので毎日教えてもらいました。
教え方は人それぞれなので、相性的に合う合わないことはありますが、コミュニケーションを取る良い機会にもなると思います。

# 2.VBA100本ノック
知識よりも実践あるのみ！(たたき上げ)をモットーにされる方はVBA100本ノックでとことんコードを書いてみることをお勧めします！
私もVBAの勉強を始めたころは毎日のように使っていました。
※以下は、VBA100本ノックのURL
https://www.excel-ubara.com/vba100/

# 3.ChatGPTを活用する
さて、1と2で紹介した方法で勉強するのが難しいと感じた方がいるかもしれません。
そしたら最終手段と行きましょう！
最終手段は*Chat GPTを使いこなす*ことです。
私も自宅や職場でVBAを使う際(特にツールの完成までに時間的余裕が無い時)、ChatGPTを使用しています。
※職場で使用する際はちゃんと責任者の方の許可を得てください。(重要)
どんな感じで使用するかというと、ChatGPTに自動化したい処理をそのまま書いて送りつけるだけです！

![無題.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3742179/63b778d9-b157-6950-24e9-d7619e4fcfc3.jpeg)

この画像は私がエクセルファイルで管理しているデータの中で「A列に入っているデータの中でYES以外のデータが入っている行を削除したい」と思ったときにChatGPTで確認した内容です。

結構雑に「こういう処理をしたい」と投げていますが、親切な解説付きでコードを教えてくれます。
※便利すぎて勉強しなくてもできてしまうのが難点ですが。。。笑

さていかがだったでしょうか？
VBAは少しでも面倒くさい処理を効率化するのに使えるツールだと思っています。」
一人でも始める方が出てくれれば本望です。
是非皆さんも勉強してみてください！
そして皆さんの力で小さなことからこつこつと働き方改革してみましょう！
最後まで読んで頂きありがとうございます！
LightGBMで顔認識

Scikit-Learnには有名人の顔データを集めたデータがあります。今回はそれを使ってLightGBMで顔認識をして精度を見てみようと思います。

# 基本的なプログラム
```Python3
from sklearn.datasets import fetch_lfw_people
from lightgbm import LGBMClassifier
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report, confusion_matrix

faces = fetch_lfw_people(min_faces_per_person=60)
x = faces.data
y = faces.target

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3)

model = LGBMClassifier()
model.fit(x_train, y_train)
y_pred = model.predict(x_test)
```
# 精度指標とラベル名をデータフレーム化する関数
targetが数値である以上誰と誰を間違えたか、誰が精度高いかが分かりませんのでそこを分かるようにします。
```Python3
import pandas as pd
def classification_report_dataframe(y, y_pred, label=None):
    rep = classification_report(y, y_pred, output_dict=True)
    dst = []
    index = []
    for col in rep:
        if col == "accuracy":
            index.append(col)
            dst.append(["", "", rep["accuracy"], rep["weighted avg"]["support"]])
        elif col != "accuracy":
            dst.append([rep[col]["precision"], rep[col]["recall"], rep[col]["f1-score"],rep[col]["support"]])
            if label == None:
                index.append(col)
            elif label != None:
                try:
                    index.append(label[col])
                except:
                    index.append(col)
        
    df_rep = pd.DataFrame(dst)
    df_rep.index = index
    df_rep.columns = ["precision", "recall", "f1-score", "support"]
    return df_rep, index
```
# 精度を見る
```Python3
y_list = list(set(y))
lists = {}
for i in y_list:
    lists[str(i)] = faces.target_names[i]
df_rep, index = classification_report_dataframe(y_test, y_pred, label=lists)
df_rep
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/92e8af4b-6e1c-f370-b5c9-6ade8be4a7f4.png)

Ariel SharonとGerhard Schroederの精度が芳しくない事が分かります。

# 混合行列で間違え方を見る
```Python3
df_cm = pd.DataFrame(confusion_matrix(y_test, y_pred))
df_cm.index = index[0:7]
df_cm.columns = index[0:7]
df_cm
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2782889/762715f4-085b-03ed-2de6-8c95e10a5196.png)

この結果から精度の悪かったAriel SharonはColln PowellとGeorge W Bushに間違いやすく、Gerhard SchroederはGeorge W Bushと間違いやすいそうです。

# まとめ
こういうのはCNNでやりましょ
Rails7 + Bootstrap + Turboでページ遷移の際にスムーススクロールを解消したい際の設定

[株式会社TECH LUCK](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)という会社で代表兼エンジニアをしている齊藤です。

DXプロジェクト、開発プロジェクト、Rails開発などでお困りごとがありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご相談をいただけますと幸いです。
以下のような問題に対応することが可能です。
- プロジェクトでRailsエンジニアが足りなくて困っている
- Railsのバージョンアップをしたいがノウハウ・リソースが足りなくて困っている
- オフショア開発をしているが、要件の齟齬やコード品質が悪いので改善したい

また、Railsエンジニアも募集しておりますので、興味がありましたら[弊社HP](https://techluck.co.jp/?utm_source=qiita&utm_medium=article&utm_campaign=myarticle)からご連絡いただけますと幸いです。

# 前提

タイトルの通りですが、Rails7 + Bootstrap + Turboでページ遷移の際にスムーススクロールが意図せず設定されてしまっている際に、スムーススクロールをオフにしたい際の設定方法です。

環境などは以下の通りです。
- Ruby：v3.2.3
- Ruby on Rails:v7.1.3
- Bootstrap：v5.3
- Turboを利用

# Bootstrapの導入

以下の記事を参考にしてBootstrapを導入しました。

https://qiita.com/arata0520/items/4330c2be8740bc560390


# スムーススクロールをオフにする方法

Rails7でアプリケーションを作っておりTurboをオンにした状態でBootstrapを導入し他のページへ遷移したところ、自動的にスムーススクロールが発動していました。
自分では設定していないのにスムーススクロールが発動していたので「Turboの仕業かな？」と当初は思っていましたが、どうやらBootstapのデフォルトの設定だったようです。

このスムーススクロールをオフにするには、`application.scss`に以下の記述を設定するとスクロールされなくなります。
（おそらく、import "bootstrap"などの上の行に書いた方が良さそうです。）

```scss:application.scss
$enable-smooth-scroll: false;
```

# 参考記事

https://discuss.hotwired.dev/t/bootstrap-turbo-scroll-issue/4302/2
ファインチューニング、転移学習、メタ学習、RAGの意味と比較

# 背景

生成AIについて勉強する中で出てきた以下の用語について、こんがらがったので整理しました。論文やサイトによっても解釈が異なるようなので、随時修正していけたらと思います。

# ファインチューニング（Fine-Tuning）

転移学習の一部。ファインチューニングは、既存の事前学習済みモデル（例えば、大規模なデータセットでトレーニングされたモデル）を特定のタスクやデータセットに適応させるプロセスです。事前学習モデルの重みを初期値として使用し、ターゲットタスクに合わせて追加のトレーニングを行います。 

- 大規模データでの学習済みモデルを利用
- 少量のデータでも効果的なトレーニング
- 特定のタスクに最適化

# 転移学習（Transfer Learning）

転移学習は、あるタスクで学習した知識を別の関連するタスクに活用する手法です。一般的には、事前学習されたモデルを別のタスクへ適用する際に使われます。特にデータが少ないタスクに対して有効です。

- 一度学習した知識を他のタスクで再利用
- 新しいタスクでの学習を迅速化
- 関連する多様なタスクに適用可能

# メタ学習（Meta-Learning）

メタ学習は「学習の学習」とも呼ばれ、モデルが新しいタスクを素早く習得する能力を向上させる手法です。主な目的は、モデルが少数のデータポイントからでも効果的に学習できるようにすることです。メタ学習の代表的なアルゴリズムには、MAML (Model-Agnostic Meta-Learning) などがあります。

- 新しいタスクに対して迅速に適応
- 少数のサンプルでの効果的な学習
- 複数のタスクでのパフォーマンス向上

# RAG (Retrieval-Augmented Generation)

RAGは、生成モデルと検索モデルを組み合わせたアプローチです。検索モデルが外部知識ベースから関連情報を取得し、その情報を生成モデルが使用して回答を生成します。これにより、モデルが広範な知識を参照しながら具体的で情報豊富な出力を生成できます。

- 外部データソースから関連情報を取得
- 取得した情報を基に高品質なテキスト生成
- モデルの知識ベースを拡張可能

# 各手法のメリット・デメリットと適用例

| 手法         | 概要                                                           | メリット                          | デメリット                      | 適用例                   |
|--------------|----------------------------------------------------------------|--------------------------------|--------------------------------|--------------------------|
| ファインチューニング | 事前学習済みモデルを特定のタスクに適応させるプロセス。 | - 効率的なトレーニング<br>- 少量データで効果的<br>- 高精度 | - 適用には事前学習済みモデルが必要<br>- オーバーフィッティングのリスク | NLP（自然言語処理）、画像認識 |
| 転移学習   | あるタスクで学習した知識を別のタスクに活用する手法。    | - 知識の再利用<br>- 新タスクでの迅速な学習<br>- 幅広い適用範囲 | - 適用には関連性のあるタスクが必要<br>- 調整が必要 | 医療診断、異常検知、音声認識 |
| メタ学習    | モデルが新しいタスクを迅速に学習するための手法。         | - 高速適応<br>- 少数ショット学習<br>- 多様なタスクに対応 | - トレーニングが複雑<br>- 初期コストが高い | ロボット制御、画像分類、強化学習 |
| RAG          | 検索モデルと生成モデルを組み合わせて情報豊富な出力を生成。 | - 広範な知識の参照<br>- 高品質なテキスト生成<br>- 知識の拡充 | - 検索の品質に依存<br>- 実装が複雑 | 質問応答システム、カスタマーサポート |
【Unity】XR Interaction ToolkitのハンドトラッキングでuGUIのボタンの反応が悪い

# はじめに
XR Interaction Toolkitを使ってMeta Questのハンドトラッキング用アプリを開発時にuGUIのボタンの反応が悪かったので原因を調べました。
筆者は当初 `OnClick` を使っていましたがストレスを感じるレベル反応が悪かったです。

# 結論
個人的には `OnPointerDown` だと直感的に操作することができました。

# OnPointerDownとOnClickの違い
* OnClick
    * 押し込んだ後に指を引くまでの一連の動作を行って初めてイベントが発火されます
    * VRの場合、指を置くまで押し込み過ぎると最初の押し込み判定が外れるようで、その状態で指を引いてもこのイベントが発行されない場合があるため、取り扱いには注意が必要です  
* OnPointerDown
    * 押し込んだ瞬間にイベントが発行されます
    * 押し込み過ぎた場合でも既にイベント発行済みなのでこちらの方が扱いやすいです