OmniAICreator/Qiita-1.07M huggingface dataset:
オンラインDDLについてのメモ

## オンラインDDLとは
こちらの説明がわかりやすかった。

https://zenn.dev/taxin/articles/mysql-online-ddl

- インデックスの作成などの DDL を実行している最中に INSERT , UPDATEなどの DML が実行できる機能
    - DDLの種類によって、オンラインDDLが使える場合と使えない場合がある 
- MySQLだと5.6以降で使える

- ALTER文の実行オプション
    - `LOCK=NONE` : read / write の両方を許可。
        - `LOCK=SHARED` : readのみが許可。
    - `ALGORITHM=INPLACE` : 既存のテーブルをそのまま使う（コピーはしない）。
        - `ALGORITHM=COPY` : 従来の方法。テーブル新しく作り直してデータをコピー。
        -  `ALGORITHM=INSTANT` : Mysql8.0.12から使えるようになった。
            - INPLACEよりもより高速で、負荷も小さい。
            - INPLACEよりも使える範囲が狭い。
        https://blog.s-style.co.jp/2018/09/2525/
    - つまり、`LOCK=NONE`、`ALGORITHM=INPLACE`（またはINSTANT) で実行すると、ALTER文実行中もINSERT , UPDATEなどの DML が実行できる

## いつ使えるか
MySQLの公式ドキュメントに説明があった。

https://dev.mysql.com/doc/refman/8.0/ja/innodb-online-ddl-operations.html

よく使いそうな部分をメモしておく。

### index
基本的にindexの追加や削除はオンライン（INPLACE) で実行できるよう。（FULLTEXTインデックスだけ注意が必要。事前にカラムの準備が必要なよう。）INSTANTでは実行できない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661656/66fa4a15-5900-4c93-bb5b-7f3cf7c2591a.png)
表 15.16 インデックス操作のオンライン DDL サポートより

※セカンダリインデックス：プライマリーキー以外のindexのこと

### カラム追加・削除
カラムの削除・追加ともにオンライン（INPLACE) で実行できる。ただ、INPLACEではテーブルの全コピーではないものの、再構築が行われるよう。AUTO_INCREMENT カラムの追加では少なくとも`ALGORITHM=INPLACE, LOCK=SHARED` が必要（＝書き込みはできない）。

カラム追加はINSTANTでできる場合もある。主に以下が条件（全ての条件は公式ドキュメントをご覧ください。）
- `ALGORITHM=INSTANT` が使えない他のALTER TABLEと一緒に実行しない
    - NG例(DROPと組み合わせる）
    ```sql
    ALTER TABLE users
    ADD COLUMN nickname VARCHAR(50),
  DROP COLUMN old_column;
    ```
- 最後のカラムとして追加する（位置指定は負荷）
- `ROW_FORMAT=COMPRESSED` のテーブルではない
    - `ROW_FORMAT` はテーブル内の行データやページ（データを保存する単位）を圧縮して保存する形式
    - FULLTEXT インデックスを含まないテーブル

カラムの削除もINPLACEでできるが、データの大幅再編成が行われ、コストが大きい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661656/2bf261d5-8e1e-4166-85d5-4c1304e09984.png)
表 15.18 カラム操作のオンライン DDL サポートより


## メタデータロック
オンラインDDLとして実行した場合も、全くロックが行われないわけではないらしい。
以下がわかりやすい（そしておそろしい。）

> オンラインDDLの開始前、完了前にそれぞれ短時間ではあるもののテーブルのメタデータに関する排他> 的アクセスが必要となります。
> つまり、オンラインDDLの開始前と完了前にDDLの対象テーブルに実行中のトランザクションがあった> 場合、そのトランザクションがコミットまたはロールバックするまで待機する必要があります。

https://qiita.com/shuCrane/items/94d3038b5feaf614778f#%E3%82%AA%E3%83%B3%E3%83%A9%E3%82%A4%E3%83%B3%E5%AE%9F%E8%A1%8C%E5%8F%AF%E8%83%BD%E3%81%AAddl%E3%81%A7%E3%81%82%E3%82%8B%E3%81%93%E3%81%A8

ロングトランザクションが発生しがちなことが判明していたり、非常に頻繁に参照が行われるテーブルの場合は、メンテナンスタイムまたは参照の少ない夜間などに変更した方が無難なのかもしれない。

## おまけ
CakePHPを使っている場合、テーブル定義（カラム名や型）をキャッシュしている。カラム追加や削除をしても、このキャッシュが残っているとCakePHPの動作に反映されなかったり、消したはずのカラムを探してエラーになった。このキャッシュもメンテナンスタイムや夜間にDDL実行が必要かの判断材料になりそう。

こちらの説明がわかりやすかった。

https://dotnsf.blog.jp/archives/1014769863.html

`find()` などカラム名を指定していないとき、かつ本番環境（debugモードが0の環境)で発生するよう。 

## おわり
これまでテーブル構造の変更は基本的にメンテナンスタイムに行っていたが、現職でオンラインDDLで実行できることがあると知った。メンテナンスタイムはユーザーさんに不便をかけてしまうし、夜間対応もしなくてよければしないにこしたことはないので、知ることができてよかった。一方で、頻回参照のテーブルやCakePHPのキャッシュなどがあり、常にメンテナンスタイムをとらなくていいわけではないことは注意したい。
online-judge-toolsが急に動かなくなった話

## 対象読者
- [online-judge-tools(template-generator)](https://github.com/online-judge-tools/template-generator)を使ってAtcoderコンテストに出場している方
- （ライブラリの中をいじる勇気のある方）

## 発生したエラー
```
File "[your_python_path]/python3.11/site-packages/onlinejudge/service/atcoder.py", line 545, in _from_table_row
    assert False
           ^^^^^
AssertionError
```

## 解決方法
`[your_python_path]/python3.11/site-packages/onlinejudge/service/atcoder.py`の545行目のif文に「MiB」を追加すると直る。
```
if tds[3].text.endswith(' KB'):
    memory_limit_byte = int(float(utils.remove_suffix(tds[3].text, ' KB')) * 1000)
elif tds[3].text.endswith(' MB'):
    memory_limit_byte = int(float(utils.remove_suffix(tds[3].text, ' MB')) * 1000 * 1000)  # TODO: confirm this is MB truly, not MiB
    
# ここから追加
elif tds[3].text.endswith(' MiB'):
    memory_limit_byte = int(float(utils.remove_suffix(tds[3].text, ' MiB')) * 1024 * 1024)
# ここまで追加

else:
    assert False

```

## なぜ発生したのか
### 結論：サイトが少し変わったから
各問題下の「メモリ制限」の単位が、2025/05の第3週から2025/05の第4週の間に変わった模様。
それまでif文の選択肢になかった「MiB」により、`assert False`が発火してしまい、その時点でコードが止まってしまっていた。

### MiB（メビバイト）ってなんだ？（not MB（メガバイト））
1MB = 1000KB = 1000 * 1000 B
1MiB = 1024KiB = 1024 * 1024 B

**補足**
数学の世界で、単位を1つ上げるのはルールがあります。
例えば、kmはmの1000倍です。そして、MBはKBの1000倍です。
ただ、コンピュータの世界では2進数で表すので、2^nで表せない1000というのはこの世界では曖昧なものになってしまいます。
そこで、2^10単位で繰り上がるようにしたのがKiBやMiBなどの「i」が入った単位たちです。

なんか単位が厳密になったんだね、と思えれば修正完了です

## 追記
早速issueが建てられていました。
https://github.com/online-judge-tools/api-client/issues/172
CATIGA SS-991EXを簡単にレビュー

## 米アマゾンで容易に購入可能なEXクローン機
[で、初代ClassWiz(EX)のクローン機って正直どうなのよ？](https://qiita.com/harycurl/items/2eaad9f4d87b8315ada0)の記事でEXクローン機を3つ紹介したが、新たにCATIGAのSS-991EXを入手したので軽く紹介する。

本機は米アマゾンで19.99ドル（記事執筆時点）。送料が8.11ドルなので合計28.1ドル（約4100円）となる。
![catiga1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/ebeb323c-e155-4dcb-b2e3-bf63c4f439f7.png)
![catiga2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/de008a65-5c9e-49bc-8e02-cb9a1057d548.png)

レビューは5000件以上付いており、それなりに売れているEXクローンである。
![catiga3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/37ddbd5f-efc3-4127-950d-c90e5d7000b5.png)

## 中身はUC-800Xと同一
パッケージは段ボールの紙箱。開封すると差し込み部分に「Thanks For Choosing CATIGA」と書かれているのがにくい。
![catiga4.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/3db407f1-bba0-41bd-a11e-318bcbb4adc4.jpeg)
![catiga5.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/d9f9f021-e62f-4a38-a4e8-1a7aa5857060.jpeg)

本体はプチプチ袋に入っていた。説明書と広告の紙が同梱。
![catiga6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/da9de9c2-f2f5-4df1-930d-5ee2e8c5cd4f.jpeg)

本体はピアノブラックで撮影に苦慮するタイプ。機能の文字ははっきり見やすい。
スライドカバーと背面は灰色だった。
![catiga7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/bf52396b-e222-4d99-8593-0d4f669e028b.jpeg)

fx-991CEXやUC-800Xと並べるとこんな感じ。
![catiga8.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/de58bb0c-4e25-4036-896c-c8e7f65a1b65.jpeg)

fx-991CEXと比べると持った感じは軽く、キータッチも軽くて安っぽい。
画面はUC-800Xほど悪くはなく、セルフテストで全ドット描画した時はちらついたが、それ以外で気になるちらつきは見られない。

で、肝心の中身はUC-800Xと同一である。
セルフテストのROMバージョン表記が「991EX VerB」で全く同じ。
![catiga9.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/dd473de6-a73a-41f6-b4d2-e9c69e9fd32e.jpeg)

詳細は記載しないが、内部精度、積分計算時間などのベンチマークも全く同じになった。

## 米アマゾンで買えるため、UC-800Xより入手しやすいか
UNIONE UC-800XとCATIGA SS-991EXは同じROMであり、バグ等が気になるようであれば両方のレビューを見ればよいということになる。
それだけユーザーが多くなることが期待され、初代ClassWizが入手できなかった人にとってよい代替クローン機となり得るだろう。

筐体の出来は、キーはUC-800X、ディスプレイはSS-991EXの方が好ましく感じられた。
この一長一短なところもクローン機らしいと言えるかもしれない。
ただし、偽造防止の変な模様が無い分、筐体文字の視認性はオリジナルより良いのが皮肉である。

入手のしやすさであるが、米アマゾンから購入できるSS-991EX、Gmarketから購入できるUC-800Xを比較すると、一般には米アマゾンから購入する方が敷居は低いかもしれない。
送料込みの価格もほぼ同程度。
UC-800XをGmarketで最安ストアから購入した場合、価格18340ウォン、国内送料3000ウォン、国際送料19370ウォン、計40710ウォン（約4300円）となる（記事執筆時点）。
![catiga10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3943774/3e495c77-adb6-4dbc-95ea-223640e50e2d.png)
rex0220 計算式プラグイン テーブル転記後に編集

[計算式プラグイン]()で、テーブル転記後に編集可能に設定してみます。

# 概要

テーブル1の選択行からテーブル2にコピーし、テーブル2の項目（ドロップダウンT2,数値T2,文字列T2）を編集可能に設定します。

- テーブル1の行追加時、テーブル2に自動反映
- テーブル1の日付T1 変更時に、テーブル2の日付T2に自動反映

テーブル行を識別するため、行追加毎にSEQ1へ番号を付与します。

![2025-06-01_11h22_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/3e935356-4124-446f-8dec-1eec3f50681a.png)

# 操作例

![2025-06-01_11h42_48.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/4ed85a24-a594-42d3-ac29-2be853ee48d4.gif)


# アプリ設定

テーブル行を識別する制御用に、SEQID, SEQ1, SEQ2 を追加します。
SEQID の初期値は 0 を指定してください。

![2025-06-01_11h33_35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/d7cbff62-8ae7-4272-826d-61a68ed308c8.png)


# 計算式プラグイン設定

「循環参照を許可」をチェック

- SEQ1: テーブル行追加毎に番号を付与
- テーブル2：　
    - 更新前のテーブル２の値を dic に保管
    - テーブル1から値をコピー
    - ドロップダウンT2は、コピー時テーブル1、その後は更新前のdic から回復
    - 数値T2, 文字列T2 は、更新前のdic から回復

![2025-06-01_11h29_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/75f3b844-5e5d-4b11-b0e0-2f90ece8dd48.png)

```JavaScript:
計算式プラグイン
OPTION: 循環参照を許可

// SEQID NUMBER
NVL(SEQID, 0)  // 既存レコード対応（0 セット）

// テーブル1.番号T1 NUMBER
ROWNO(テーブル1)+1

// テーブル1.SEQ1 SINGLE_LINE_TEXT
IF(SEQ1, SEQ1,
  LET(
     newid, SEQID+1,
     dummy, FSET(SEQID, newid),
     newid
  )
)

// テーブル2 SUBTABLE
LET(
  dic, DIC(),
  w, TABLE_MAP(テーブル2,
    TPDIC("dummy",
      DIC_ITEM(dic,
        SEQ2,DIC(
           "ドロップダウンT2",ドロップダウンT2,
           "数値T2", 数値T2,
           "文字列T2",文字列T2,
           "SEQ2",SEQ2
         )
      ))
  ),
  TABLE_DATA(
    TABLE_MAP(テーブル1,
      TPFILTER(IN(選択,"Y")),
      TPDIC(
        "番号T2",番号T1,
        "日付T2",日付T1,
        "ドロップダウンT2",
           IF(DIC_ITEM(DIC_ITEM(dic, SEQ1),"SEQ2"),
              DIC_ITEM(DIC_ITEM(dic, SEQ1),"ドロップダウンT2"),
             ドロップダウンT1
           ),
        "数値T2", DIC_ITEM(DIC_ITEM(dic, SEQ1),"数値T2"),
        "文字列T2", DIC_ITEM(DIC_ITEM(dic, SEQ1),"文字列T2"),
        "SEQ2",SEQ1
      )
    )
  )
)

// テーブル2.番号T2 NUMBER
// テーブル2.日付T2 DATE
// テーブル2.SEQ2 SINGLE_LINE_TEXT
```

※ dic の行参照を LET 関数で指定した例

```JavaScript:
// テーブル2 SUBTABLE
LET(
  dic, DIC(),
  w, TABLE_MAP(テーブル2,
    TPDIC("dummy",
      DIC_ITEM(dic,
        SEQ2,DIC(
           "ドロップダウンT2",ドロップダウンT2,
           "数値T2", 数値T2,
           "文字列T2",文字列T2,
           "SEQ2",SEQ2
         )
      ))
  ),
  TABLE_DATA(
    TABLE_MAP(テーブル1,
      TPFILTER(IN(選択,"Y")),
      LET(
        row, DIC_ITEM(dic, SEQ1),
        TPDIC(
          "番号T2",番号T1,
          "日付T2",日付T1,
          "ドロップダウンT2",
             IF(DIC_ITEM(row,"SEQ2"),
               DIC_ITEM(row,"ドロップダウンT2"),
               ドロップダウンT1
             ),
          "数値T2", DIC_ITEM(row,"数値T2"),
          "文字列T2", DIC_ITEM(row,"文字列T2"),
          "SEQ2",SEQ1
        )
      )
    )
  )
)
```
#32.Session Managerを使用した通信について

# はじめに
こんにちは！nayaaaaです。
今週は、実際に手を動かしてあまり学習することができなかったため、
隙間時間でSession Managerについてのドキュメントや記事を見ていたので、備忘録となります。

# Session Managerとは
公式ドキュメントには以下のような記載があります。

>>Session Manager はフルマネージド型の AWS Systems Manager ツールです。Session Manager を使用すると、Amazon Elastic Compute Cloud (Amazon EC2) インスタンス、エッジデバイス、オンプレミスサーバー、仮想マシン (VM) を管理できます。ワンクリックのブラウザベースのインタラクティブシェルまたは AWS Command Line Interface (AWS CLI) を使用できます。Session Manager は安全なノード管理を実現し、インバウンドポートを開いたり、踏み台ホストを維持したり、SSH キーを管理したりする必要はありません。また Session Manager はマネージドノードの制御されたアクセス、厳格なセキュリティプラクティス、ノードアクセス詳細があるログを要件とする社内ポリシーの尊守を実現しつつ、エンドユーザーが簡単なワンクリックのクロスプラットフォームを使用してマネージドノードにアクセスできるようにします。

上記から、AWSインスタンスなどの管理ノードに対して、セキュアに接続することが可能でブラウザベースでのコマンド操作を、コンソールからのワンクリック操作で容易に実現することが可能となります。

また、アドバンスドインスタンスを使用することで、ハイブリッドおよびマルチクラウド環境内の非EC2マシンへの接続もサポートしてます。

https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager-prerequisites.html

>>Session Manager はアドバンスドインスタンス層を使用するハイブリッドおよびマルチクラウド環境内の非EC2マシンに加え、Amazon Elastic Compute Cloud(Amazon EC2)インスタンスへの接続もサポートします。


※こちらのアドバンスドインスタンスを使用する場合、以下の通りに料金が発生するそうなので、注意が必要です。

### オンプレミスインスタンスティアの料金

| インスタンスタイプ | 料金 | 備考 |
|--------------------|------|------|
| スタンダード | 追加料金なし | アカウントごとにリージョンあたり最大 1,000 台まで |
| アドバンスド | 1 インスタンスあたり **$0.00695/時間** | 無料利用枠なし |




https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/operating-systems-and-machine-types.html#supported-machine-types

# 通信の仕組みは？
接続する際は、以下の通りに、マネージドインスタンス（EC2インスタンスなどのこと）のセキュリティグループ設定でアウトバウンド443を許可する必要があります。

>>注記
VPC エンドポイントを使用する代わりに、マネージドインスタンスでアウトバウンドのインターネットアクセスを許可します。この場合、マネージドインスタンスは、以下のエンドポイントへの HTTPS (ポート 443) アウトバウンドトラフィックも許可する必要があります。
>>
>>ssm.region.amazonaws.com
>>
>>ssmmessages.region.amazonaws.com
>>
>>ec2messages.region.amazonaws.com
>>
>>SSM Agent は、クラウド内の Systems Manager サービスへのすべての接続を開始します。このため、Systems Manager のインスタンスへのインバウンドトラフィックを許可するようにファイアウォールを設定する必要はありません。

443を許可するのは、SSM Agentから以下のエンドポイントに対してhttpsでアクセスすることにより、Systems Managerサービス（Session Managerなど）への操作を可能にしているからのようです

- ssm.region.amazonaws.com
- ssmmessages.region.amazonaws.com
- ec2messages.region.amazonaws.com

なので、インスタンスにはSSM AgentがインストールされていることやIAMポリシーが正しく設定されていることも確認する必要があります。


https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-setting-up-messageAPIs.html

https://docs.aws.amazon.com/ja_jp/general/latest/gr/ssm.html



# まとめ
今回の記事は、ドキュメントや他のかたの記事を読んで整理した一旦の理解となっております。
- ブラウザベース/CLIベースでEC2や非EC2へのセキュアな接続が可能
- アドバンスドインスタンスは有料、スタンダードインスタンスは無料
- SSM AgentがHTTPSでエンドポイントへ接続

実際にハンズオンで学習した後にこういったインプットめいんのがくｓｙを行うことも大切だなと思いました。

以上ありがとうございました。

■わかりやすかった記事

https://zenn.dev/fdnsy/articles/cda1e2309e87b8
Javaの例外処理を丁寧に理解する

## 1. はじめに

###  例外とは？

Javaでプログラムを実行中にエラーが発生すると、「例外（Exception）」として通知されます。

#### 例
- ファイルが見つからない
- 0で割った
- nullのオブジェクトにアクセスした

こうした **異常な状態を安全に処理**するために使うのが「例外処理」です。


## 2. try-catch構文の基本
| ブロック名       | 役割・用途                                     |
| ----------- | ----------------------------------------- |
| **try**     | 例外が発生する可能性がある処理を囲むブロック                    |
| **catch**   | 発生した例外を捕まえて処理（エラー対応）するブロック                |
| **finally** | 例外の有無に関わらず必ず実行される処理を書くブロック。主にリソースの解放などに使う |

```Java
try {
    // 例外が発生するかもしれない処理
} catch (ExceptionType name) {
    // 例外が発生したときの処理
}
```

## 3. 例外の種類
#### Checked Exception
例外処理を必ず明示的に書く必要がある。ファイル操作やネットワーク処理などでよく発生。

#### Unchecked Exception
RuntimeException(実行時例外)を継承した例外群。
主にプログラムのバグ（例：NullPointerException）で発生し、処理は任意。

| 分類        | 例                  | 説明           |
| --------- | ------------------ | ------------ |
| Checked   | `IOException`      | try-catch必須  |
| Unchecked | `RuntimeException` | try-catchは任意 |

## 4. 複数のキャッチブロック
### ✅ 正しい順番
具体的な例外（子クラス）から書き、一般的な例外（親クラス）へと順に書く

### 理由
例外は上から順にチェックされるので、親クラスのcatchが先にあると、子クラスのcatchは決して実行されません。Javaコンパイラが「このcatchは意味がない」と判断してエラーにします。

```Java
try {
    // ...
} catch (FileNotFoundException e) {
    // ...
} catch (IOException e) {
    // これは後に書かないとコンパイルエラー
}

```




## 5. try-catch と throws の使い分け
| 方法          | 意味              | 向いている場面                    |
| ----------- | --------------- | -------------------------- |
| `try-catch` | その場で例外を捕まえて処理する | 例外に応じた対応がその場で可能なとき         |
| `throws`    | 例外処理を呼び出し元に任せる  | メソッド内で対処できない or 上位で処理したいとき |

## 6. ユーザー定義例外の書き方
#### 定義
```Java
public class MyException extends Exception {
    public MyException(String message) {
        super(message);
    }
}

```
#### 使い方
```Java
throw new MyException("カスタム例外です");
```

## 7. try-with-resources構文（Java 7以降）
- リソース（ファイル、ネットワーク接続など）を使ったあとに必ず閉じる処理を簡単に書くための構文

- finallyブロックでclose()を書かなくても、自動的に閉じてくれる
#### 書き方
```Java
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
    String line = br.readLine();
    System.out.println(line);
} catch (IOException e) {
    e.printStackTrace();
}
```

#### 従来の書き方
```Java
BufferedReader br = null;
try {
    br = new BufferedReader(new FileReader("file.txt"));
    // 処理
} catch (IOException e) {
    e.printStackTrace();
} finally {
    if (br != null) {
        try {
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
```
マルチエージェントと対話できるLINE botを開発しよう

## 概要
Google ADKを用いたマルチエージェントシステムと対話できるLINE botを作りました。
作ったものと実装のポイントをまとめます。

## 作ったもの
サンプルコード：https://github.com/MokonaSato/line-multi-agent-sample/tree/main

今回実装したエージェントには下記のツールをもたせています。
- 四則演算ツール
- Google検索ツール
- Notion操作ツール
- URL/画像からレシピをNotionに登録するツール

(四則演算はAgent実装の練習として組み込んだツールなので、実運用での使用はあまり想定していませんw)

四則演算：
![四則演算.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/5e3ccc03-57d7-4315-a77a-184638bfea34.png)

Google検索：
![Google検索.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/7cf3c6ba-b7fe-4af1-829f-db89075bec31.png)

URLからレシピをNotionに登録する：
![URLレシピ登録.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/505a3162-79ec-45b7-a71f-34f7d7691a6d.png)

画像からレシピをNotionに登録する：
![画像レシピ登録.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/06aaf9a4-71e8-4086-b0cf-4a992d61997f.png)


登録したレシピからお買い物リストを作成：
![買い物リスト作成.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/e5bc303d-586b-43b8-a470-399345ceeb3b.png)

レシピが登録されているNotion DB：
![NotionDB.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118714/c4ce5a77-71a4-463d-aac4-a8bb80a72a6e.png)


## 実装の経緯
最近、Claude Desktop × MCPサーバで生成AIとタスクをこなしていくのがとても便利だということに気づきました（[【備忘録】今更MCPサーバを勉強した](https://qiita.com/MokonaSato/items/6a4c14ca0cc0f06c351e)）。

しかし、通勤中などの外出時にプライベートPCは操作できないので、スマホからもツールを持ったエージェントを操作できたら便利ではないか？と思い、LINEをインターフェースとしたマルチエージェントボット作成を思いつきました。



## 実装ポイント
※ 執筆中
1. [LINEに非同期処理と画像入力を実装した](https://qiita.com/MokonaSato/items/449a008cb8ee5df5ad2d)
1. [multi-Agent実装パターン](https://qiita.com/MokonaSato/items/c9a1f21ae8e0799720e7)
1. インストラクション管理の実装
1. Notion Agentの実装

## 今後の課題
- LINEでは画像と文字を同時に送れないため、他に画像認識を伴うタスクをさせる際には工夫しなければならない
- 最小のAgent・Tool定義でいかに多様なタスクをこなせるようにするか？（例えばNotionで管理する情報カテゴリが増えるたびにTool定義を増やしていくのは不便）
- セッション内のAgent Context管理（連続してAgentにメッセージを送ると、最後に応答したAgentが引き続き応答しようとしてしまう場合がある）
- 実行時間が遅い（1応答あたり4~5分）
ローカルリポジトリとリモートリポジトリの繋ぎ込み403エラーの解決策

# ローカルリポジトリとリモートリポジトリの繋ぎ込み時のエラーの解決策🗝️

> Gitを使用して、新しく作成したGitHub上のリモートリポジトリへ、mainブランチをpushしようとしたところ、下記のエラーが発生しました。原因と解決策を調べ解決できたのでその流れを記載します。

---
### 🔸エラーの内容
```
git push origin main　＃main ブランチを push

remote: Permission to rai-code11/new_test.git denied to <gihubのユーザ名>.
fatal: unable to access 'https://github.com/<gihubのユーザ名>/<リポジトリ名>/': The requested URL returned error: 403
```

>原因は以前使用したログイン認証情報がMac内に保存されており、それにより今回作成したのリポジトリにアクセスできないことです。

---

### 🗝️解決策

>　Macから以前のgithubの認証情報を削除することで解決

#### 📗Macからgithubの認証情報を削除する手順

1.Macの`アプリケーション`を開きます。
![スクリーンショット 2025-06-01 10.39.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4070526/524d600a-7cc6-472c-b407-e58ab4a6bac6.png)


2.`ユーティリティ`を開きます。

![スクリーンショット 2025-06-01 10.40.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4070526/1050f971-f1de-489b-addf-f7e9d2366dea.png)


3.`キーチェーンアクセス`を開きます。
![スクリーンショット 2025-06-01 10.41.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4070526/bae1aaa6-fdb3-4ea2-ac8f-407700c74988.png)






4.右上にある検索バーで`github`と検索します。



5.ログイン情報の上で右クリックをして削除して完了です。
![スクリーンショット 2025-06-01 10.42.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4070526/c5b9c393-439d-4fb2-b1df-a9e02e7a2bf9.png)

![スクリーンショット 2025-06-01 10.43.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4070526/6fc6ad11-fe40-4891-9d3c-83b7de9afe99.png)

6.再度`git push origin main`コマンドを打ち、ログイン情報が求められ繋ぎ込みをして完了です。
【ターミナル】【Mac】で処理が終わった際に通知を表示したい！

# はじめに
私はMacを使用しているのですが、Dockerで環境構築をする時や、npm ciなど少し時間のかかる処理をターミナルで行うことありますよね？
ついつい画面と睨めっこしてしまったり、他の作業をしていても「あの処理もう終わったかな？」と気になって何度も処理が終わっていないかターミナルを確認してしまうことがよくあります。

そこで、処理の完了時に通知を表示&音を鳴らしたいと思い調べてみることにしました。

# 結論
.zshrcにmynotifyという関数を作成して、実行したいコマンドの頭にmynotifyを付けて実行する。


```.zshrc
function mynotify() {
  "$@" && (
    osascript -e 'display notification "✅ 成功：'"$*"'" with title "実行結果" subtitle "成功"' && afplay /System/Library/Sounds/Glass.aiff
  ) || (
    osascript -e 'display notification "❌ 失敗：'"$*"'" with title "実行結果" subtitle "エラー"' && afplay /System/Library/Sounds/Basso.aiff
  )
}

```

使用例
```
mynotify echo "これは成功です"
```
実行結果

![スクリーンショット 2025-06-01 11.18.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2682689/a908cc3c-18e3-4a98-9f98-4395f2b68352.png)

使用例
```
mynotify false
```
実行結果
![スクリーンショット 2025-06-01 11.19.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2682689/686523cc-1d65-49cb-bd7e-e851d0897e9d.png)


## うまくいかない場合
システム設定でスクリプトエディタの通知がOFFになっているor集中モードがONになっている可能性が高いです。
筆者はシステム設定→通知→アプリケーションの通知の欄にスクリプトエディタがそもそも表示されておりませんでした。
![スクリーンショット 2025-06-01 11.22.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2682689/377acfc1-45d4-481e-a0ef-dbb91cfd7bfa.png)
![スクリーンショット 2025-06-01 11.22.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2682689/06d66fa0-73f7-431e-b056-38958b207f96.png)

筆者の場合は、一度スクリプトエディタを一度実行したら、システム設定の通知欄「スクリプトエディタ」が現れましたので一度お試しください。

```
display notification "通知が出ました！ " with title "テスト通知" subtitle "サブタイトル"
```
![スクリーンショット 2025-06-01 11.33.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2682689/805ca456-4c03-47a8-9a8b-82e920ba83d5.png)


## 参考
https://qiita.com/P-man_Brown/items/a287edbc3fa021502ddd

https://qiita.com/s2mr/items/ed10bca41ab3ee88f3db
[AIとカネ] Cursor破産回避法3 課金タイミングが謎すぎる

# まず最初に
クソ分かりにくいCursorの課金システムを解説するでｗ

## **Included Requests（含まれてるリクエスト）**
これは**「月額料金に最初から含まれてる回数券」**みたいなもんや

- Pro版なら毎月500回分のAI使用権がついてくる
- GPT-4とかClaude 3.5みたいな高性能AIを使える回数
- **使い切ったら「Slow mode（遅いモード）」になる**
  - 無料ユーザーの後ろに並ばされて、順番待ちｗ

例えるなら：**ラーメン屋の月額チケット500枚みたいなもん**。使い切ったら「立ち食いそば屋の行列」に並ばされる感じ（）

## **Usage-Based Spend（従量課金）**
これは**「500回使い切った後の追加料金システム」**や

- 500回使い切った後も高速でAI使いたい時のオプション
- **1リクエストあたり$0.04**（約6円）
- 500リクエストごとに$20請求される仕組み
- 上限設定できるから、使いすぎ防止可能

例えるなら：**スマホのギガ追加購入**みたいなもん。基本プランのギガ使い切ったら、追加で買うか低速モードで我慢するか選ぶアレや

この2つが別々のタイミングでリセットされるから、みんな混乱してるってわけやｗ

# どんなとこがわっけわかんねーのか

![スクリーンショット 2025-06-01 11.24.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3908981/8af519cc-dfe3-4f1b-8357-56fe0102c9e2.png)

請求タイミングがズレるんよ！！

**なんでズレるのか判明した：**

「Your Fast Requests reset on a fixed monthly date based on when you first set up your plan」
→ つまり、**リクエスト数は「最初にプラン始めた日」が基準**になる

例えば23日に始めたら、毎月23日にリセットされる仕組みや

一方で、「Usage-based pricing is per calendar month (not necessarily same as your billing cycle, will be billed roughly on the 2nd-3rd day of the month)」
→ **従量課金は「カレンダー月」単位**で、毎月2-3日頃に請求される

**つまり何が起きてるかというと：**

1. **Included Requests（500回のやつ）** → プラン開始日ベース（例：15日開始なら毎月15日リセット）
2. **Usage-Based Spend（従量課金）** → カレンダー月ベース（毎月1日リセット）

この2つが**別々のサイクルで動いてる**から、月跨いでも片方だけリセットされるっていうクソ仕様ｗ

しかも「Each user gets their own quota of 500 requests per month」って書いてあるから、チーム版でも個人ごとに別々のリセット日になる可能性あるし、マジでカオスやな（）

**解決策：**
- 自分のリセット日を確認する（たぶんCursor始めた日）
- その日まで待つか、Usage-Based Pricingで追加課金するしかない

運営側からしたら「請求管理しやすい」んやろうけど、ユーザーからしたら分かりにくすぎて草生えるわ

# 自分のプラン開始日なんて覚えてねえよなぁ
調べてて分かったんやけど、これ系の混乱めっちゃ起きてるみたいやで：

「I was charged $40 for 1000 Fast Requests, despite having canceled the additional ones」 Urgent Billing Issue – Incorrect Charges on Subscription - Discussion - Cursor - Community Forum
→ 追加購入キャンセルしたのに請求されたとか（鬼か）
フォーラムでも「いつリセットされるんや！」って質問が山ほどある

最高にイカれてる点：

リセット日が「プラン開始日」やから、自分でも忘れる
カレンダーに「Cursorリセット日」とか書かなあかんレベル
しかも月末に始めたら、2月とかで日付ズレる可能性もある（30日開始→2月は28日までしかない）

Cursor開発チーム「俺たちは賢い課金システムを作った！」
ユーザー「いつリセットされるか分からんくて草」

# どうやって調べるんじゃ
ほんまそれな！マジで「プラン開始日」なんて覚えてるやつおらんやろｗ

調べてみたけど、**Cursorは具体的なリセット日を表示してない**っぽいわ。クソ仕様確定や（）

## **プラン開始日を調べる方法（推測）：**

### 1. **Stripeのポータルから確認**
「You can access it through the dashboard by clicking the "Billing" button in your account settings」
- Cursor内の Settings → Account → Billing ボタン
- Stripeのポータルに飛ばされる
- **過去の請求履歴**から最初の請求日を確認できるかも

### 2. **メールの履歴を漁る**
- 「Cursor」「subscription」「payment」とかで検索
- 最初の課金確認メールの日付がプラン開始日

### 3. **クレカの明細を確認**
- 最初にCursorから引き落とされた日がそれ

### 4. **サポートに聞く（最終手段）**
- hi@cursor.com にメール
- 「俺のリセット日いつやねん」って聞く

**一番笑えるのは：**
- 「I've used my 1k premium model requests this month and want to determine whether I should upgrade to get more, or just wait another day or two」
- みんな「あと何日でリセットか分からんから課金するか迷う」状態ｗ

Cursor開発チーム、これ分かっててやってる説あるやろ。「リセット日分からんから、とりあえず課金しとくか...」って思わせる作戦かもしれんｗ

マジで「リクエスト残数: 505/500 (リセット日: 6月15日)」みたいに表示すればええのに、なんでやらんのか謎すぎる（）
【TypeScript初心者メモ】オブジェクト型

## オブジェクト型とは
オブジェクト型とはキー（プロパティ）と値の組み合わせで構成されるデータの型です。
```
type Product = {
  id: number        // 数値
  name: string      // 文字列
  price: number     // 数値
  inStock: boolean  // 真偽値
}
```
## 様々な定義方法
### オプショナルプロパティ（?）
? は省略可能（オプショナル）を示します。
```
type User = {
  id: number　　　//必須
  name?: string  //任意
}
```
### ネストされたオブジェクト型
オブジェクト型は入れ子（ネスト）にもできます。
```
type User = {
  id: number
  profile: {
    age: number
    bio?: string
  }
}
```
### オブジェクトの配列型
配列と組み合わせて使うこともできます。
```
type User = {
  id: number
  name: string
}
const users: User[] = [
  { id: 1, name: "Taro" },
  { id: 2, name: "Hanako" }
]
```
### 動的なキーをもつオブジェクト型（インデックスシグネチャ）
「プロパティ名（キー）が決まっていない（またはたくさんある）」オブジェクトを定義したいときに使う型表現です。
```
type ScoreMap = {
  [name: string]: number
}
```
「キーが string、値が number である任意の数のプロパティを持つオブジェクト」を表します。
```
const scores: ScoreMap = {
  Taro: 90,
  Hanako: 85,
  Jiro: 78
}
```
このとき、scores["Taro"] や scores["Hanako"] のように、キーの名前が動的に決まることを許容しています。
自動生成ファイルがSource Treeのファイル差分に出てきてしまう場合の対処法

備忘録。

## 事象
SourceTreeでコミットしようと変更ソースを確認していたところ、自動生成ファイル(css)が差分に出てきた。
Sassで実装していて、CSSファイルは自動コンパイルで生成されるからプロジェクト内の管理対象にしたくない。

## 原因
拡張機能のLive Sass Compilerを有効にしていて、
CSSファイルの出力先をプロジェクト内に設定していたため。
リアルタイムで実装しながらブラウザで確認したかった。

### 現設定
```settings.json
"liveSassCompile.settings.formats": [
    // Sassの出力方法の設定
    {
      "format": "expanded", // expanded / compressed の2つから選択可
      "extensionName": ".css", // .css拡張子で出力
      "savePath": "~/../css" // すべての.scssファイルからの相対的な出力先のフォルダを指定
    }
  ],
```
## 対策
Live Sass Compilerの設定は変えずに、
Git側でCSSファイルを管理対象から外す設定を行う。

1. Railsプロジェクトの直下にある”.gitignore”ファイルを開く
1. 以下のコードを追加
```.gitignore
# Live Sass Compiler の出力ファイルを除外
app/assets/css/*.css
```

Source Treeを確認し、.cssファイルが非表示になっていることを確認。
終わり。
【長田総一郎】エンジニアの学習を始めてみた。今日やったこと

こんにちは。長田総一郎です！

今日から本格的に「エンジニアの学習」を始めてみることにしました。
これまでITやプログラミングにはなんとなく興味があったものの、「自分には無理かも」と思ってずっと避けてきたジャンル。でも、やっぱりこれからの時代を生きていく上で「ITスキル」は避けて通れないと感じて、一歩を踏み出すことにしました。

この記事では、今日やったこと・感じたことをそのまま残しておこうと思います。これから同じように学習を始める人にとって、少しでも参考になれば嬉しいです。

---

## 1. 環境構築からスタート

まずは、何から手をつければいいのかさえわからない状態だったので、「プログラミング　初心者　始め方」と検索。そこで見つけた記事に沿って、学習環境を整えるところから始めました。

* VSCode（コードを書くためのソフト）のインストール
* Google Chromeの開発者ツールを確認
* GitHubのアカウントを作成

初めて聞く用語も多く、インストールして設定するだけでも1時間以上かかりました。最初はちょっと手こずりましたが、「自分のパソコンが“開発者っぽく”なっていく感覚」にワクワクしている自分がいました。

---

## 2. HTMLとCSSを少しだけ触ってみた

環境が整ったところで、初心者向けの学習サイト（Progate）に登録し、HTMLとCSSの基礎を学習。

* 見出し（h1〜h3）の使い方
* 段落（pタグ）や画像（imgタグ）の挿入
* CSSで文字の色や背景を変える方法

「これがWebページの正体か…！」と感動。
今まで何気なく見ていたWebサイトの裏側に、こんな風にコードが書かれていたなんて。

正直、覚えることはたくさんありそうだけど、「自分にも書けるんだ」という実感がモチベーションになりました。

---

## 3. 今日の感想とこれから

たった数時間の学習でしたが、思っていたよりも楽しくて、時間があっという間に過ぎました。
難しそうに見えていたプログラミングも、一歩ずつなら進めそうだと感じました。

もちろん、今日やったのは本当に入り口だけで、これから山ほど壁があると思います。
でも、まずは「続けること」が一番大事だと信じて、明日も少しだけでも学習を進めてみようと思います。

このブログでは、毎日の進捗や学んだこと、つまずいたことも記録していきたいです。
誰かの背中を押せるような、そんな学習記録になれば嬉しいです。

---

ここまで読んでくださってありがとうございました。
エンジニアの道はまだまだ始まったばかりですが、小さな一歩を積み重ねていきたいと思います。
明日もまた、進みます。
renderでssh接続できるようにしてみる

renderにホスティングしてるサーバーを操作したり、mysqlをいじったりしたいと思った時に、自分のパソコンのターミナルでやりたいと感じたので、今回はrenderでssh接続できるようにしてみようと思います。


# SSHとはどういう仕組みなのか
SSHとは、`Secure Shell`の略で遠隔にあるコンピューターを操作するための通信プロトコルのことです。
通信を暗号化して行うため外部からの攻撃を防ぎ、安全に通信できるようになります。

## 公開鍵暗号方式
SSH接続をするためにいくつか暗号方式ができるのですが、今回使用する暗号方式は公開鍵暗号方式を使用します。

>この記事で作成した画像で説明します:https://qiita.com/maooz4426/items/c8606125e31543b1001a

これはクライアントとなる接続元が、誰にでも渡せる`公開鍵`とクライアントだけが保持する`秘密鍵`を生成します。
>サーバーをGithubのアイコンとしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/8532cf49-8d65-2a6f-9f22-82a5f4cdfccc.png)


秘密鍵はクライアントに、公開鍵をサーバーに渡して、認証していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/0d20bbb3-2be2-c8a6-3378-22d217334034.png)


まず、クライアントがサーバーにリクエストします。

そしてサーバーはレスポンスとして公開鍵で生成した乱数から暗号化した電子署名を送ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/640c76b7-ff97-58ac-7063-1d14b4702e2a.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/a2201dec-54bf-7d83-3fa7-d70c0bee67a1.png)



それをクライアントは秘密鍵で復元します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/cb281f5d-cdb9-6745-244e-4a71170f4b5b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/1cc631b5-94ed-0c61-b81f-105875a30111.png)


復元して解読した署名をサーバーが受け取ると認証するという仕組みです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b809916c-1d3e-3d50-958d-74c9fff853ea.png)

# 鍵を作成する
`ssh-keygen`コマンドを使用して、秘密鍵と公開鍵を作成します。
また、下のコマンドを打った後、パスキーを入力することになります。
```zsh
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_render 
```

今回使用しているoptionは以下のようになっています。
|オプション|役割
|---|---
|t|暗号方式(ed25519,rsa)
|f|ファイル名のパスを決定する(ファイルの保存位置とファイル名を決める)

作成されたファイルは以下のようになっています。
|ファイル名|何鍵
|---|---
|id_ed25519_render|秘密鍵
|id_ed25519_render.pub|公開鍵

macのkeycahinに秘密鍵を登録します。
こうすることでssh接続を行う際にパスフレーズを聴かれないようにしています。
```zsh
ssh-add --apple-use-keychain ~/.ssh/id_ed25519_render
```

pbcopyコマンドで出力結果をクリップボードにコピーすることができます。
今回はこれでコピ-します。
```zsh
pbcopy < ~/.ssh/id_ed25519.pub
```
renderのAccountSettingsにsshを登録する箇所があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b759a0d6-d642-4b17-a656-b97521149390.png)

ここのKeyに先ほどpbcopyでコピーした結果を貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b9459f51-880d-4c72-a846-25baeb3a3745.png)


こうすることでssh接続を行うことができます。

ssh接続のコマンドは画像の部分に`ssh user名@Host名`の形式で書かれています。
このコマンドをターミナルで打つことでssh接続することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3766230/b2ff535a-dae6-4f12-9d84-8bfc3d7b0983.png)
Pydantic の非推奨回避策まとめ

## conint
### 非推奨
```python
from typing import Optional
from pydantic import BaseModel, conint

class OrderItem(BaseModel):
  product: str
  size: str
  quantity: Optional[conint(ge=1)]=1
```
### 回避策
```python
from typing import Annotated, Optional
from pydantic import BaseModel, Field

class OrderItem(BaseModel):
  product: str
  size: str
  quantity: Optional[Annotated[int, Field(ge=1)]=1
```

## Extra
### 非推奨
```python
from typing import Optional
from pydantic import BaseModel, Field, Extra

class OrderItem(BaseModel):
  product: str
  size: str
  quantity: Optional[Annotated[int, Field(ge=1)]=1

  class Config:
    extra = Extra.forbid
```
### 回避策①
```python
from typing import Annotated, Optional
from pydantic import BaseModel, Field, ConfigDict

class OrderItem(BaseModel):
  product: str
  size: str
  quantity: Optional[Annotated[int, Field(ge=1)]=1

  model_config=ConfigDict(extra="forbid")
```

### 回避策②
```python
from typing import Annotated, Optional
from pydantic import BaseModel, Field

class OrderItem(BaseModel, extra="forbid"):
  product: str
  size: str
  quantity: Optional[Annotated[int, Field(ge=1)]=1
```
zabbix で監視対象側にあるshell scriptの実行結果を取得する方法


## 概要
zabbixで柔軟な監視をするためにshell scriptを実行してその値を取得したい時がある。
最終的にshell scriptで取得した値はトリガーにかけてその値によってアラートをあげる事になるが今回はzabbix agent 経由で監視対象サーバ内にあるshell scriptを実行する方法まで説明します。

## 前提
### zabbix server
OS : Ubuntu 22.04
Version : 6.4

### 監視対象
OS : Ubuntu 22.04
zabbix-agent2

## scriptを実行する監視対象側の設定
1. zabbix agent でscriptを実行出来る様に以下の記述を **/etc/zabbix/zabbix_agent2.conf** に記載する。

```
AllowKey=system.run[*]
```

2. 対象のscriptを入れる **zabbix** ユーザーのhomeディレクトリに作る。
今回は **sh** という名前のディレクトリを作ります。

```
mkdir /home/zabbix/sh
```

3. scriptを2で作ったディレクトリに作る。

```
sudo vim /home/zabbix/sh/your_script.sh
```

4. scriptに実行権限を付与する。

```
sudo chmod +x /home/zabbix/sh/your_script.sh
```

5. scriptのownerをzabbixに変える。

```
sudo chown zabbix:zabbix /home/zabbix/sh/your_script.sh
```

## zabbix サーバ側の設定

1. ブラウザからzabbixを開き監視対象で **アイテムの作成** を実行
![](https://storage.googleapis.com/zenn-user-upload/9cb532385deb-20240222.png)

2. **キー** に 以下を指定し、必須項目を入力する事でアイテムがscript実行後の値を取得してくれる
```
system.run[~/sh/your_script.sh]
```
![](https://storage.googleapis.com/zenn-user-upload/799050f17a2b-20240222.png)

## 終わりに
後はscriptで取得した値をトリガーにかけてアラート発報するなりすれば幸せになれます。
ubuntuにsquidをinstallしてLinuxとブラウザからインターネットアクセス


## 概要
閉鎖環境でもaptを使いたかったり、インターネットにアクセスしたい場合がある。
そんな時はsquidというproxyサーバが広く利用されている。
今回の記事では以下の方法を説明する。
- ubuntu に squidをinstallしてproxyサーバ構築
- Linux からproxy経由でインターネットアクセス
- ブラウザ からproxy経由でインターネットアクセス

## proxyサーバ設定
UbuntuにSquidをインストールしてLinuxとブラウザからインターネットアクセスする方法

1. Squidのインストール
まず、UbuntuにSquidをインストールします。ターミナルを開き、以下のコマンドを実行します。

```
sudo apt update
sudo apt install squid
```

2. Squidの設定
Squidを設定して、インターネットアクセスを可能にします。Squidのメイン設定ファイルである/etc/squid/squid.confを編集します。

```
sudo vim /etc/squid/squid.conf
```

設定ファイル内で、適切な箇所に以下のような設定を追加します。ここでは、特定のIPアドレス（例: 192.168.1.100）だけを許可します。

```
# 特定のIPアドレスからの接続のみ許可する
acl allowed_ip src 192.168.1.100
http_access allow allowed_ip
http_access deny all
```

設定を保存してエディターを終了します。

3. Squidの再起動
設定を反映させるために、Squidを再起動します。

```
sudo systemctl restart squid
```

## クライアント側の設定

### Google Chrome
1. Google Chromeを開き、右上のメニューアイコン（3つの点）をクリックします。
2. メニューから「設定」を選択します。
3. 下にスクロールし、"プライバシーとセキュリティ"を展開し、「セキュリティ」を選択します。
4. 「プロキシを変更する」をクリックします。
5. プロキシ設定のウィンドウが開きますので、手動でプロキシを設定します。
6. 設定を保存してウィンドウを閉じます

### Mozilla Firefox
1. Mozilla Firefoxを開き、右上のメニューアイコン（3つの水平な線）をクリックします。
2. メニューから「設定」を選択します。
3. 左側のサイドバーで「一般」を選択します。
4. 下にスクロールし、"ネットワーク設定"のセクションで「設定...」ボタンをクリックします。
5. プロキシ設定のウィンドウが開きますので、「手動でプロキシを設定する」を選択し、アドレスとポートを入力します。
6. 必要に応じて、ネットワーク設定を使用するにチェックを入れます。
7. 「OK」をクリックして設定を保存し、ウィンドウを閉じます。

### Microsoft Edge
1. Microsoft Edgeを開き、右上の「...」アイコンをクリックします。
2. メニューから「設定」を選択します。
3. 左側のメニューから「プライバシー、検索、およびサービス」を選択します。
4. 下にスクロールし、「プロキシ」のセクションで「プロキシ設定の変更」をクリックします。
5. 「手動でプロキシを設定する」を選択し、アドレスとポートを入力します。
6. 必要に応じて、プロキシ設定をオンまたはオフに切り替えます。

### linux 環境変数の設定
一部のLinuxシステムでは、プロキシサーバーの設定に関連する環境変数を設定する必要があります。
これには、http_proxyおよびhttps_proxy変数が含まれます。squidのデフォルトポートの**3128**を指定してます。

```
export http_proxy=http://<SquidサーバーのIP>:3128
export https_proxy=http://<SquidサーバーのIP>:3128
```

### aptの設定

apt.confファイルにProxy設定を追加する
シェルにて以下を実行

```
sudo vim /etc/apt/apt.conf
```
これにより開いたapt.confファイルに以下を記述し、保存
※ファイルがなかったら新規作成する

```/etc/apt/apt.conf
Acquire::http::Proxy "http://<SquidサーバーのIP>:3128";
Acquire::https::Proxy "http://<SquidサーバーのIP>:3128";
```

これで、LinuxマシンおよびブラウザからSquidを経由してインターネットにアクセスする準備が整いました。
実際にapt installやブラウザでのインターネットアクセスが出来るはずです。

### dockerの設定

**systemctl edit docker**　で設定ファイルを開いて以下を追記する

```/etc/systemd/system/docker.service.d/override.conf
[Service]
Environment = 'http_proxy=http://192.168.0.10:8080' 'https_proxy=http://192.168.0.10:8080' # 必要なら 'no_proxy=...'
```

**~/.docker/config.json** を以下の様に編集する。なければ作る。

```~/.docker/config.json
{
  "proxies": {
    "default": {
      "httpProxy": "http://192.168.0.10:8080",
      "httpsProxy": "http://192.168.0.10:8080"
    }
  }
}
```

参考：https://qiita.com/dkoide/items/ca1f4549dc426eaf3735

## 結論
UbuntuにSquidをインストールして設定し、Linuxマシンおよびブラウザからインターネットにアクセスする方法を解説しました。
Squidのようなproxyを使うことで、ネットワーク内の通信を効率的に管理し、セキュリティを向上させることができます。
【解決済】Windows 11 24H2 のエクスプローラーの応答がない


## 事象

1. Windows 11 24H2 のエクスプローラーの応答が遅くファイルにアクセス出来ない

2. エクスプローラーにて「アカウントの接続が解除されました」と表示される
![](https://storage.googleapis.com/zenn-user-upload/f080d8ee1266-20250223.png)

3. 設定 から アカウント情報を確認するとログインしているはずのmicrosoftアカウントが空白
![](https://storage.googleapis.com/zenn-user-upload/12ac63d98fe3-20250223.png)

## 結論
上記の通り、なのでログインしている Microsoft アカウントで問題が起きてると推測

私の場合、
**一時的に新しい管理者アカウント (アカウントB) を作成し、問題が起きてるMicrosoft アカウント (アカウントA) のデバイス登録を解除しログインしなおす事で解決しました**
ので方法を共有します。

## 解決手順

1. **アカウントB (新しい管理者アカウント) の作成:**
   1. スタートボタンを右クリックし、「**ファイル名を指定して実行**」を選択します。
   2. 「ファイル名を指定して実行」ダイアログボックスに `netplwiz` と入力し、**Enter** キーを押します。
   3. 「ユーザーアカウント」ウィンドウが開きます。「**追加**」ボタンをクリックします。
   4. 「Microsoft アカウントを使わずにサインインする (推奨しません)」をクリックします。
   5. 「ローカルアカウント」をクリックします。
   6. 以下の情報を入力します。
      * **ユーザー名:**  例:  `temporary_admin` (任意の名前で構いません)
      * **パスワード:**  (必要であれば設定)
      * **パスワードのヒント:** (必要であれば設定)
   7. 「**次へ**」をクリックします。
   8. 「**完了**」をクリックします。
   9. 作成したアカウントB (`temporary_admin` など) を選択し、「**プロパティ**」をクリックします。
   10. 「アカウントB のプロパティ」ウィンドウが開きます。「**グループ メンバーシップ**」タブを選択します。
   11. 「**管理者**」を選択し、「**OK**」をクリックします。
   12. 「ユーザーアカウント」ウィンドウに戻ったら、「**OK**」をクリックして閉じます。

2. **アカウントB でのログインと Microsoft アカウント (アカウントA) のデバイス登録解除:**

   1. **PC を再起動**します。
   2. ログイン画面で、**アカウントB** (`temporary_admin` など) を選択してログインします。
   3. ブラウザ (Microsoft Edge など) を起動し、アドレスバーに `https://account.microsoft.com/` と入力して **Enter** キーを押します。
   4. Microsoft アカウントのウェブサイトが開きます。**接続が解除されたアカウント (アカウントA)** でログインします。
   5. ログイン後、ウェブサイトのメニューから「**デバイス**」 (またはそれに相当する項目) を選択します。
   6. デバイスリストの中から、**問題が発生している PC** を探して選択します。
   7. デバイスの詳細ページで、「**デバイスのリンクを解除**」または「**削除**」のようなボタンを探してクリックします。
   8. 確認画面が表示される場合は、内容を確認してデバイスのリンク解除を確定します。

3. **アカウントA (元のMicrosoft アカウント) での再ログイン:**

   1. **PC を再起動**します。
   2. ログイン画面で、**アカウントA** (元のMicrosoft アカウント) を選択してログインします。

**注意点:**
* アカウントB はあくまで一時的な管理者アカウントです。問題解決後、不要であれば削除しても構いません。
* Microsoft アカウントのウェブサイトのUIは変更される可能性があります。上記手順のメニュー名やボタン名が異なる場合は、適宜読み替えて操作してください。
* デバイスのリンクを解除すると、Microsoft Store や OneDrive など、Microsoft アカウントと連携する一部の機能で再ログインが必要になる場合があります。
WSL上のLinuxのバックアップとリストア


## 概要
WSL上のLinuxのバックアップとリストアの手順を残します。

## 前提
以下の通りVersion2で実施します。

```
C:\Windows\System32>wsl -l -v
  NAME      STATE           VERSION
* Ubuntu    Running         2

C:\Windows\System32>
```

## 手順

### wsl上のLinuxのエクスポート

#### コマンド使用方法
`wsl --export ${ディストリビューション名} ${exportするbackup fileのフルパス}`

#### コマンド例
`wsl --export Ubuntu C:\Users\asaka\Downloads\backup_20231024.tar`

### エクスポート確認
`dir C:\Users\asaka\Downloads\`

### リストア

#### コマンド使用方法
`wsl --import ${ディストリビューション名} ${インストール先パス} ${exportしたbackup fileのフルパス}`

#### コマンド例
`>wsl --import Ubuntu-restore-test C:\Users\asaka\OneDrive\Documents\WSL-OS\Ubuntu C:\Users\asaka\Downloads\backup_20231024.tar`

#### 備考
- ${ディストリビューション名}が重複すると以下のメッセージが出るので一意の名前にする。
```
C:\Windows\System32>wsl --import Ubuntu C:\Users\asaka\OneDrive\Documents\WSL-OS\Ubuntu C:\Users\asaka\Downloads\wsl_no2_backup_20231024.tar
指定された名前のディストリビューションは既に存在します。
C:\Windows\System32>
```

### importの確認
問題なくimport出来れば${インストール先パス}にDiskファイルが出来ている事と
`wsl -l`で${ディストリビューション名}が出来ている事を確認する。

```
C:\Windows\System32>wsl -l
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu (既定)
Ubuntu-restore-test

C:\Windows\System32>
```

### 規定のディストリビューションの指定
リストアしたディストリビューションを既定に設定する。

#### コマンド使用方法
`wsl --set-default ${ディストリビューション名}`

#### コマンド例
`wsl --set-default Ubuntu-restore-test`

#### 確認
```
C:\Windows\System32>wsl --list
Linux 用 Windows サブシステム ディストリビューション:
Ubuntu-restore-test (既定)
Ubuntu

C:\Windows\System32>
```

### 規定のユーザーをrootユーザーから変更する(rootユーザーのみ使うなら不要)
上記の手順でリストアしたディストリビューションは規定のユーザーがrootユーザーとなる。
既定のユーザーを一般ユーザーで運用するのであれば以下の対応が必要。

1. ログイン(この時点ではrootユーザーで実行される)
`wsl -d ${ディストリビューション名}`

2. sudoerの準備とユーザーの準備

```
apt update -y && apt install passwd sudo -y
myUsername=${ユーザー名}
adduser -G wheel $myUsername
echo -e "[user]\ndefault=$myUsername" >> /etc/wsl.conf
passwd $myUsername
```

3. wslから抜ける
`exit`コマンドで抜ける

4. wsl 落とす

#### コマンド使用方法
`wsl --terminate ${ディストリビューション名}`

#### コマンド例
`wsl --terminate Ubuntu-restore-test`

5. wsl 立ち上げる

#### コマンド使用方法
`wsl -d ${ディストリビューション名}`

#### コマンド例
`wsl -d Ubuntu-restore-test`

#### 参考
https://learn.microsoft.com/ja-jp/windows/wsl/use-custom-distro#add-wsl-specific-components-like-a-default-user

#### 備考
本件の場合`規定のディストリビューションの指定`を実行しただけで
`Ubuntu-restore-test`の既定のユーザーでログインされることを確認したので不要の可能性もある。

## 参考
https://www.aise.ics.saitama-u.ac.jp/~gotoh/HowToBackupLinuxOnWSL.html
Terraform Stateで"unsupported attribute" エラーが発生した際の対処方法


## 問題の背景
Terraformでリソースを `terraform state rm`（stateファイルからリソースを除去）しようとした際、以下のようなエラーが発生することがあります。

```
Error saving the state: unsupported attribute "metrics_config"

The state was not saved. No items were removed from the persisted
state. No backup was created since no modification occurred. Please
resolve the issue above and try again.
```

このエラーは、Terraformの状態ファイルに現在使用しているProviderやTerraformバージョンではサポートされていない属性（例：`metrics_config`）が残っている場合に起こります。

## 対処手順

### **ProviderやTerraformを最新版にアップデート**
   不要または非対応な属性が新バージョンで取り除かれている場合があります。
   ```
   terraform init -upgrade
   terraform plan
   ```

   上記コマンドでProviderやTerraform本体を最新化し、状態とコードの整合性を確認します。

### **問題のリソースを先に削除**
   `metrics_config`など問題を引き起こしているリソースを先に `terraform state rm` で削除します。
   たとえば、`aws_lambda_event_source_mapping.my_lambda_event` が原因の場合：
   ```
   terraform state rm module.xyz.aws_lambda_event_source_mapping.my_lambda_event
   ```

   これでエラーが解消され、他のリソースを削除できるようになる場合があります。

### **再度該当リソースを削除**
   問題リソースを取り除いた後、`terraform state rm`を再度実行して、残りの削除対象リソースを正常に除去できるか試します。
   例えば：
   ```
   terraform state rm module.xyz.aws_s3_bucket.example_bucket
   terraform state rm module.xyz.aws_s3_bucket_lifecycle_configuration.example_lifecycle
   ```

### **手動でStateファイルを修正（最終手段）**
   上記方法で解決できない場合は、状態ファイルを手動で編集します。
   ```
   terraform state pull > state.json
   ```

   `state.json`をエディタで開き、`metrics_config`等の該当属性を削除してください。その後、
   ```
   terraform state push state.json
   ```
   で修正した状態ファイルを反映します。

## 対処結果の例

以下は、Providerアップデート後に問題リソースを削除し、他のリソースも正常に削除できるようになった例です。

```
terraform init -upgrade
terraform state rm module.xyz.aws_lambda_event_source_mapping.my_lambda_event
terraform state rm module.xyz.aws_s3_bucket.example_bucket
terraform state rm module.xyz.aws_s3_bucket_lifecycle_configuration.example_lifecycle
...
```

このように、Providerのアップデートと問題リソースの事前除去によって、`unsupported attribute`エラーを回避し、Terraformの状態ファイルを正常な状態に戻すことができます。
Zabbix ディスカバリーで特定のサービス監視を除外する方法


### Zabbix ディスカバリーで特定のサービス監視を除外する方法

以下は、Zabbixでオーバーライドを使用して特定のサービスを監視から除外する方法の手順です。

1. **ディスカバリールールに移動**:
   - **設定** -> **テンプレート** に移動します。
   - ディスカバリールールが設定されているテンプレートを選択します。
   - **ディスカバリールール**をクリックし、適切なディスカバリールールを選択します（例: Windowsサービス用）。

2. **オーバーライドの追加**:
   - ディスカバリールール内で、**オーバーライド**をクリックします。
   - **オーバーライドの作成**をクリックします。

3. **オーバーライドの設定**:
   - **名前**: オーバーライドに説明的な名前を付けます（例: "Google Update Serviceを除外"）。
   - **条件**: 除外したいサービスに一致する条件を設定します。例えば、以下のようにフィルターを設定します:
     ```plaintext
     {#SERVICE.NAME} matches ".*GoogleUpdate.*"
     ```
   - **操作**: 操作の設定でステータスを`無効`にするか、アイテムを作成しないようにします。

4. **保存して適用**:
   - **追加**をクリックしてオーバーライドを保存します。
   - オーバーライドが正しく適用されていることを確認し、ディスカバリールールを実行してサービスが除外されていることをテストします。

### 設定例

以下は設定例です:

```plaintext
オーバーライド名: Google Update Serviceを除外
条件: {#SERVICE.NAME} matches ".*GoogleUpdate.*"
操作:
  - ステータスを設定: 無効
```

### 参考
https://www.zabbix.com/forum/zabbix-help/477441-googleupdaterservice-alerts
ElasticCache で SSL: WRONG_VERSION_NUMBER が出た時の対処方法


## 背景
AWS Lambda 関数から ElastiCache (Redis) に接続した際、以下のエラーが発生しました。

```
[ERROR] ConnectionError: Error 1 connecting to <Redisエンドポイント>:6379. [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1000).
```

このエラーは、Redis への接続時に TLS (SSL) が無効になっている場合に発生することが判明しました。本記事では、この問題を解決するために TLS を有効化した手順を記録します。

## 発生していた問題
1. **ElastiCache の TLS が無効**
   - `TransitEncryptionEnabled` が `false` の状態であったため、Lambda 環境変数で `rediss://` プロトコルを使用して接続を試みた際に失敗していました。

2. **エラー詳細**
   - `SSL: WRONG_VERSION_NUMBER` エラーは、TLS が無効なクラスターに対して `rediss://` を使用して接続した場合に発生します。

## 解決手順

### 1. ElastiCache の TLS サポート状況を確認
ElastiCache クラスターが TLS をサポートしているかを確認しました。

```
aws elasticache describe-replication-groups --replication-group-id prd-redis
```

**確認結果**:
```
"TransitEncryptionEnabled": false
```
TLS が無効であることを確認しました。

### 2. ElastiCache の TLS を有効化
TLS を有効にするために、Terraform の ElastiCache 設定を修正しました。

**修正前のコード:**
```
resource "aws_elasticache_replication_group" "redis" {
  replication_group_id       = "${var.environment}-redis"
  engine                     = "redis"
  engine_version             = "6.x"
  node_type                  = "cache.t3.micro"
  automatic_failover_enabled = false
  security_group_ids         = var.ElastiCache_security_group_ids
  subnet_group_name          = aws_elasticache_subnet_group.redis.name
  description                = "redis"
  tags = {
    environment = var.environment
  }
}
```

**修正後のコード:**
```
resource "aws_elasticache_replication_group" "redis" {
  replication_group_id       = "${var.environment}-redis"
  engine                     = "redis"
  engine_version             = "6.x"
  node_type                  = "cache.t3.micro"
  automatic_failover_enabled = false
  security_group_ids         = var.ElastiCache_security_group_ids
  subnet_group_name          = aws_elasticache_subnet_group.redis.name
  description                = "redis"
  transit_encryption_enabled = true  # TLS を有効化
  tags = {
    environment = var.environment
  }
}
```

### 3. Lambda の接続設定の確認
Lambda の環境変数で設定している Redis URL に問題がないかを確認しました。

**環境変数の値:**
```
REDIS_URL = "rediss://${aws_elasticache_replication_group.redis.primary_endpoint_address}:6379/0"
```

**生成された実際の URL:**
```
rediss://<Redisエンドポイント>:6379/0
```

問題なく正しい形式で生成されていることを確認しました。

### 4. 動作確認
修正後、再デプロイを実施して動作確認を行いました。

```
terraform apply
```

その後、Lambda 関数をトリガーした結果、Redis に正しく接続できることを確認しました。

## まとめ
本記事では、AWS Lambda から ElastiCache (Redis) への接続で発生した TLS 関連のエラーを解消するための手順を説明しました。

主なポイントは以下の通りです：
1. **ElastiCache の TLS を有効化する**: `transit_encryption_enabled = true` を設定。
2. **Lambda の接続設定を確認する**: 環境変数で `rediss://` プロトコルを正しく使用。

これにより、Redis 接続が安全に行えるようになりました。
windows 11にSSH出来るようにする


# Windows 11にSSHする方法

Windows 11を使用してSSH接続を行う手順を以下に示します。

## 1. OpenSSHサーバーの有効化

Windows 11にはOpenSSHサーバーが標準で搭載されていますが、デフォルトでは無効になっています。有効化するには次の手順を実行します。

- **ステップ 1:** スタートメニューを開き、「設定」を選択します。
- **ステップ 2:** 「アプリ」セクション内で「アプリと機能」を選択します。
- **ステップ 3:** 右上の検索ボックスに「オプション機能」と入力し、「オプション機能の管理」を選択します。
- **ステップ 4:** リストから「OpenSSH サーバー」を見つけ、有効にします。

## 2. OpenSSHサーバーサービスの開始

OpenSSHサーバーを有効化した後、次の手順でサービスを開始します。

- **ステップ 1:** スタートメニューを開き、「サービス」を検索して開きます。
- **ステップ 2:** サービスウィンドウで、"OpenSSH SSH Server" を見つけ、右クリックして "開始" を選択します。

## 3. ファイアウォールでポート22を許可する

SSH通信を行うためには、ファイアウォールでポート22を許可する必要があります。

- **ステップ 1:** スタートメニューを開き、「Windows セキュリティ」を検索して開きます。
- **ステップ 2:** 「ファイアウォールとネットワーク保護」を選択し、「高度な設定」をクリックします。
- **ステップ 3:** 左側のペインで、「インバウンド規則」を選択します。
- **ステップ 4:** 右クリックメニューから「新しいルール...」を選択します。
- **ステップ 5:** ルールのウィザードで、ポート22を許可する新しいインバウンドルールを作成します。

これで、Windows 11がSSH接続を受け付ける準備が整いました。
【2025年版】windowsユーザーがMacを使う時に実施するべき設定


Macを初めて使う方や、Windowsから移行してきた方へ。より快適にMacを使いこなすための、おすすめの初期設定をまとめました。これらの設定を行うことで、日々の操作がスムーズになります。

## 1. スクリーンショットを直接クリップボードにコピー (Windows風)
Windowsの `Win + Shift + S` のように、スクリーンショットを直接クリップボードにコピーする設定です。資料作成などで画像を頻繁に貼り付ける際に非常に便利です。

1.  `Command + Shift + 5` キーを同時に押します。画面下部にスクリーンショット用のツールバーが表示されます。
2.  ツールバー右側にある「**オプション**」をクリックします。
3.  メニューが表示されるので、「保存先」の項目の中から「**クリップボード**」を選択します。
4.  `esc` キーを押すか、ツールバー右端の「×」でツールバーを閉じます。

これで設定完了です。以降、`Command + Shift + 4` (範囲選択) や `Command + Shift + 3` (全画面) でスクリーンショットを撮ると、**ファイルが作成されずに直接クリップボードにコピー**され、右下のプレビューも表示されなくなります。
**Tips:** 設定を変更せず、一時的にクリップボードへコピーしたい場合は、`Command + Control + Shift + 4` のように `Control` キーを追加してショートカットを実行します。

## 2. Finderでファイルパス (場所) を常に表示する
現在開いているフォルダが、どの階層にあるのかをFinderウィンドウの下部に常に表示させます。ファイル管理がしやすくなります。

1.  `Finder` を起動します (Dockにある顔のアイコンをクリック)。
2.  画面上部のメニューバーから `表示` をクリックします。
3.  ドロップダウンメニューから「**パスバーを表示**」を選択します。
これで、Finderウィンドウの下部に `Macintosh HD > ユーザ > (ユーザ名) > ...` のような形式で、現在の場所が表示されるようになります。

## 3. トラックパッドの操作感を改善する
MacBookのトラックパッドは優秀ですが、初期設定では戸惑うことも。以下の設定でより直感的に使えるようにしましょう。
**システム環境設定** (または **システム設定**) を開き、「**トラックパッド**」を選択します。

### 3.1. タップでクリックを有効にする
物理的にトラックパッドを押し込まなくても、軽いタップだけでクリック操作ができるようになります。
1.  「**ポイントとクリック**」タブを選択します。
2.  「**タップでクリック**」のチェックボックスを **オン** にします。

### 3.2. 右クリック (副ボタンのクリック) を設定する
Windowsの右クリックに相当する操作を設定します。
1.  「**ポイントとクリック**」タブを選択します。
2.  「**副ボタンのクリック**」の項目で、ドロップダウンメニューから「**右下隅をクリック**」を選択します。(「2本指でクリック」など、好みに合わせて選択可能です)

## 4. マウスのスクロール方向をWindows風に (ナチュラルなスクロールを無効化)
マウスホイール (またはMagic Mouseの表面) を下に動かしたときに、画面コンテンツも下にスクロールするように設定します。macOSのデフォルト (ナチュラル) は逆方向です。
**システム環境設定** (または **システム設定**) を開き、「**マウス**」を選択します。
1.  「**ナチュラルなスクロール**」のチェックボックスを **オフ** にします。
    *   設定項目には「指を動かす方向にコンテンツが移動」という説明が付いています。これをオフにすることで、ホイールを手前に回すと画面が下にスクロールする、Windowsなどで一般的な動作になります。
![マウス設定画面の例](画像のURLや説明をここに追加できます)
*(ご提供いただいた画像はこの設定項目を示しています)*

## 5. 日本語入力でWindows風のキー操作を有効にする
半角/全角キーでの入力モード切り替えや、ファンクションキー (F6〜F10) でのひらがな・カタカナ・英数変換など、Windowsでの日本語入力に慣れている方におすすめの設定です。
1.  **システム環境設定** (または **システム設定**) を開き、「**キーボード**」を選択します。
2.  「**テキスト入力**」セクション (またはタブ) にある「入力ソース」の「**編集...**」ボタンをクリックします。
3.  左側のリストから「**日本語 - ローマ字入力**」 (またはご自身が使用している日本語入力ソース) を選択します。
4.  右側に表示されるオプションの中から「**Windows風のキー操作**」のチェックボックスを **オン** にします。
5.  右下の「**完了**」ボタンをクリックします。

## 6. 画面の拡大・縮小をスムーズに (アクセシビリティ機能)
Chromeなどのブラウザで `Command + ホイール` による拡大・縮小ができない場合でも、macOS標準のアクセシビリティ機能を使えば、特定の修飾キー (デフォルトは `Control`^) を押しながらマウスホイールを操作することで、画面全体（またはマウスポインタ周辺）をスムーズに拡大・縮小できます。
1.  **システム環境設定** (または **システム設定**) を開きます。
2.  「**アクセシビリティ**」を選択します。
3.  左側のメニューから「**ズーム機能**」を選択します。
4.  「**スクロールジェスチャと修飾キーを使ってズーム**」のチェックボックスを **オン** にします。
5.  すぐ下にあるドロップダウンメニューで、ズーム操作に使用する**修飾キー**を選択します。デフォルトは `^ Control` ですが、`⌥ Option` や `⌘ Command` に変更することも可能です。
これで設定は完了です。選択した修飾キー (例: `Control`) を**押しながら**、マウスホイールを**上に回すと拡大**、**下に回すと縮小**されます。
これはWebページだけでなく、macOS上のあらゆる画面で利用できます。

**注意点:** この機能は、Chromeの `Command + プラス/マイナス` のようなページ要素の拡大・縮小とは異なり、画面表示そのものを虫眼鏡のように拡大・縮小する機能です。