OmniAICreator/Qiita-1.07M huggingface dataset:
DAS接続でFCプロトコルでのアクセスが不可だった理由

前回の投稿では、コンピュータ機器内での使われるプロトコルの話をした。今回は機器間で使われるプロトコルについて興味を持ってしまった。

ネットワーク機器を使わずにサーバとストレージを直接接続するDAS方式で使われるプロトコルに関して記述していきたい。

## 目次
- DAS方式で使われるプロトコル
- 「ストレージをDAS方式でFCを使ってアクセスしたい」
- DAS方式でFCによるアクセスがNGだった理由


## DAS方式で使われるプロトコル

DAS方式のストレージ接続はサーバとの直接接続のため、真っ先に挙げられるメリットとして、コストの安さと設定のシンプルさがある。
その分、ネットワーク構築が必要な規模の大きな環境での利用は瞬間的に選択肢から外れるので、基本的に個人での利用、多くても3,4人での利用でチョイスされる選択肢だろう。

DAS方式はサーバとストレージを1:1での利用に限る。ストレージ側のフロントエンドポートに空きがあれば物理的に複数台のサーバ(ホスト)とケーブルをつなぐことはできるが、1台のサーバがストレージを占有する仕様なので複数台で同時にストレージへアクセスすることは不可となっている(だからこそSAN方式という選択肢が用意されている)。

そしてDAS方式では基本的にブロックアクセス形式でのデータの読み書きとなる。方式上でファイル共有として使われることがないためである。
ただファイルアクセスは可能だ。アクセスするホスト(サーバ)側でファイルシステムを管理できるのであれば、ストレージの容量領域へのマウントという形で実現できる。

## 「ストレージをDAS方式でFCを使ってアクセスしたい」

そしてDAS方式で使われる通信プロトコルとして代表的なものSAS、SATAがまずは挙げられる。
ネットワーク接続においてはほぼ利用されない両者だが、機器とのケーブルによる直接接続ではよく見かける。

これらのプロトコルはサーバとストレージ間のDAS方式接続だけでなく、例えばノードが冗長化されているストレージであれば筐体内のノード間の接続でSASケーブルが利用されることがあり、また同じストレージでは大容量構成におけるストレージ本体と容量拡張用機器の複数台で構成となった場合は、このストレージ機器間との接続でもSASケーブルを利用されているユーザさんは多いのではないだろうか。

ただ、昨年に業務の中でお客さんから「サーバとストレージをFCプロトコルでDAS接続したい」というリクエストを受けた。

FC(Fibre Channel)、またはiSCSIもそれに含まれるのだが、これらのプロトコルは基本的にSAN環境で使われるネットワーク型プロトコルである。DAS方式で接続するには転送速度などの性能が良すぎるきらいがある。

具体的で詳細な理由はなかったが、FCでDASをつながなければいけない事情があるはずなので、そのような構成を組むように着手をしたところ、個人的には驚きの仕様が判明した。

**「FCプロトコルを使ってホストとストレージへの直接接続はできません。」**


## DAS方式でFCによるアクセスがNGだった理由

このリクエストをされたお客さんはNetApp製ストレージの提案を求められたのだが、ただNetAppのストレージOS、ONTAPでの仕様ではFCプロトコルによるDAS方式接続はそもそもサポートされていなかった。

https://docs.netapp.com/ja-jp/ontap-apps-dbs/oracle/oracle-network-config-direct-connect.html#fc%E7%9B%B4%E6%8E%A5%E6%8E%A5%E7%B6%9A

その理由が上記の公式に記載されていた。

NPIV(N_Port ID Virtualization)という、FCで使う1つの物理ポートを複数の論理ポートとして共有できる機能がある。いわゆるFCタイプの仮想ポートである。NetAppのOS、ONTAPではそのNPIVを採用している。

このNPIVはONTAPの仕様上、FCスイッチを介した接続を大前提として開発されてきた。だからDAS方式をサポートしていないのだ。これはストレージ側もそうであるし、NPIVを直接的に認識するようなHBAを持ったサーバ機器が存在しない、という双方向のサポートが無さが最大の要因となっている。

このような要望はめったに遭遇しない案件ではあったが、DAS方式接続の特徴を如実に表されるようなエピソードだったので今回の投稿とさせていただいた。


## ひとりごと

自宅のある集合住宅の隣が空き地だったのだが、先月から戸建ての工事が始まった。

平日の日中はドリルの削る音らしくもので耳が痛く、在宅での業務にちょっとした支障をきたしている。
正直、勘弁してほしいとは思っているが建設会社や住宅所有者には罪はなく、ただただ運が悪かったと思うしかない。

いつの日か、奇跡的に自分が新築の住宅を購入する日がきたら同じように近隣の厄介になるので、そのトレードだと思うことにする。
Laravel（PHP）におけるユニークなID（UUID・ULID）の選定基準

ユニークなIDを利用する機会があり、どの方法を選択すべきか迷ったので過程も含めて共有します。

今回はユーザーIDとサブスクリプションIDの2つのケースで採用しました。

## ユーザーID

ユーザーIDを作成する場合、連番で採番されるIDを採用すると1つ数字を間違えただけで他のユーザーへ処理が適用されてしまうというデメリットがあります。

例

| ID | ユーザー名 | 削除フラグ |
| ---- | ---- | ---- |
| 4351 | テスト | 0 |
| 4352 | ミーグラム | 0 |
| 435 | ミミューズ | 0 |

4351の「テスト」を削除しようとして間違えて435や4352と入力してしまった場合に他のユーザーを削除するケースなどが想定されます。


システムで利用するのみであれば問題ないのですが、手動での対応が発生する場合はミスが発生しやすいです。ミーグラムではお問合せの対応で手動対応が発生するケースも多いため、連番でないIDを導入する必要がありました。

ユニークなIDについては事前にUUIDに関する知識があったため、UUIDを採用しようと考えましたが、導入するサービスの仕様で25文字以内の文字列しか利用できないという制限があり断念しました。UUIDはv4が主流ですが、36文字と25文字をオーバーしてしまっていました。

UUIDv4の例
```
f47ac10b-58cc-4372-a567-0e02b2c3d479
```

その他にULIDというのも出てきましたが、26文字ということでこちらも採用できませんでした。

ULIDの例

```
01HFW6EZ1VGKS5TN9A4Z6F0P7X
```

そこで利用することに決めたのが、PHPの関数である[uniqid()](https://www.php.net/manual/ja/function.uniqid.php)です。最小で13文字から利用できるため、文字数制限の要件を満たしていました。ランダムな文字列を付与するオプションを利用しても25文字以内に収まったため、利用しました。

```php
uniqid('', true);
```

UUIDのv4と比較すると時間ベースでIDが作成されることで作成時間が分かってしまうことや「.」が付くことなどの懸念点もありましたが、ユーザー側に表示するIDではないためそこまで気にする必要はないと考えました。また、UUIDと比較するとランダム性が低いという懸念もありましたが、こちらも現在及び当分の間のサービスのユーザー数を考慮すると十分であると考えました。

## サブスクリプションID

こちらもお問合せ対応などで手動利用するため、高いユニーク性が必要でした。

UUIDv4を考えましたが、ユーザー側に表示する際、36桁というのはやはり長く改行が入ってしまうため、選定しませんでした。

ユーザーIDの時に考慮したULIDを採用しました。UUIDv4と比較し、26桁と少ないことや時間ベースで作成されるため、ソートや検索において高いパフォーマンスであることが選定理由です。

```php
use Ulid\Ulid;

subscriptionId = Ulid::generate(true);
```

Laravelの最新バーションであれば関数が用意されているようですが、利用しているバージョンでは利用できなかったため、以下のライブライを利用しました。

https://github.com/robinvdvleuten/php-ulid

ULIDは時間が分かってしまうという懸念点がありましたが、他のユーザーに表示されるIDではないためそこまで厳密に考慮する必要は

## 実際に選定してみて

最初はUUIDv4を使えば良いのかなと考えていましたが、見た目やパフォーマンス的にもULIDいいなと思いました。また、相当大きいサービスのIDや他のサービスも含めてランダム性が求められる項目でなければ、ランダム性をそこまで求める必要もないと感じました。
チーム開発入門：心理的安全性がプロジェクト成功を左右する理由を体系的にまとめてみた

## はじめに

心理的安全性（Psychological Safety）とは、組織やチームの中でメンバーが自分の意見を自由に表現し、失敗や疑問を恐れることなく発言できる状態を指します。

***これは、Googleのプロジェクト・アリストテレスにおいて高パフォーマンスなチームの要素として注目され、近年、多くの企業や組織で重要視されるようになっています。***

## 書こうと思ったきっかけ
受講しているITスクールのハッカソンに参加する中で、チーム開発において心理的安全性の重要性を実感しました。

:::note info
**特に、発言しづらい雰囲気があると、意見が十分に出せず、結果として開発の進行がスムーズにいかないことを経験しました。**
:::

例えば、アイデア出しの段階で「***こんなことを言って大丈夫だろうか***」と遠慮してしまったり、技術的な課題があっても「***無知だと思われたくない***」と相談をためらったりすることがありました。

その結果、認識のずれが生じたり、問題の発見や解決が遅れたりしてしまいました。

心理的安全性が確保された環境では、メンバー全員が気兼ねなく意見を言え、自然に協力し合えるため、プロジェクトが円滑に進むことが期待できます。

今回の経験を通じて、心理的安全性の確保がチームのパフォーマンスに直結することを学び、その重要性を整理しようと思い、この記事を書くことにしました。

## 心理的安全性が重要な理由

1. **イノベーションの促進**  
   自由に意見を出し合える環境では、新しいアイデアが生まれやすくなります。恐れずに挑戦できることで、創造的な解決策が生まれやすくなります。

2. **チームの生産性向上**  
   誰もが安心して意見を述べられることで、誤解や情報の隠蔽が減り、円滑なコミュニケーションが可能になります。その結果、業務の効率が向上します。

3. **従業員のエンゲージメント向上**  
   自分の意見が尊重され、受け入れられる環境では、仕事に対するモチベーションが高まります。結果として、メンバーの主体性や組織への忠誠心が向上します。

4. **ストレスの軽減**  
   意見を述べることで批判されるのではないかという不安がなくなるため、職場でのストレスが軽減され、精神的な健康が保たれます。

## 心理的安全性を高めるための方法

1. **リーダーの姿勢の変革**  
   リーダーはオープンな態度でメンバーの意見を受け入れ、批判ではなく建設的なフィードバックを心がけることが大切です。

2. **積極的なコミュニケーション**  
   定期的な1on1ミーティングや意見交換の場を設けることで、自由に話せる環境を作りましょう。

3. **失敗を許容する文化の醸成**  
   失敗を責めるのではなく、そこから学ぶことを重視する文化を作ることで、安心して挑戦できる環境が生まれます。

4. **相互の信頼関係の構築**  
   信頼関係を築くために、相手の話に耳を傾け、共感を示すことが重要です。

## まとめ

心理的安全性は、個人だけでなく組織全体の成長にも大きく影響を与えます。

:::note warn
***安心して意見を述べられる環境を作ることで、イノベーションが促進され、チームの生産性やエンゲージメントが向上します。***
:::

リーダーやメンバーが協力して、心理的安全性の高い職場を目指しましょう。

## 参考文献

https://www.recruit-ms.co.jp/glossary/dtl/0000000230/

https://www.nec-solutioninnovators.co.jp/sp/contents/column/20230609_psychological-safety.html
Bulk API によるバッチ サイズの設定


+ [Bulk API によるバッチ サイズの設定](https://salesforce.stackexchange.com/questions/235896/setting-the-batch-size-via-bulk-api)

Bulk API は、大量のレコードを非同期で並行して読み込むことを目的としています。また、 1日の制限も非常に小さいです。技術的には、1 レコードずつのバッチを 10,000 個設定することもできますが、1 日の制限に達してしまいます。代わりに、通常の同期 API を使用してください。約 1,000 件未満のレコードのバッチが必要な場合は、Bulk API は適していません。同期 API とは異なり、各バッチには 10 分間の制限があり (追加のチャンクには再試行があります)、200 レコードの各チャンクには 5 分間の制限があり、同期更新に関連する通常のより短い時間制限ではないことに注意してください。

同期 API の場合、バッチ サイズは API 呼び出しごとに一度に送信するレコードの数です。Bulk API の場合、バッチ サイズはファイルで送信するレコードの数で、これはバッチと呼ばれます。バッチは、それぞれ 100/200 レコードのチャンクに分割されます (API バージョンによって異なります)。各チャンクが 5 分未満で実行される限り、問題ありません。1,000 未満の値で適切なパフォーマンスが得られない場合、この API を使用するには、1 日の制限の点で「高価」すぎることになります。

+ [Bulk API および Bulk API 2.0 の制限および割り当て](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_bulkapi.htm)

2,000 件以上のレコードを含むデータを操作する場合は、Bulk API 2.0 の使用が適しています。この API により、Bulk フレームワークを利用して非同期ワークフローの準備、実行、管理を正常に行えます。2,000 レコード以下のジョブでは、REST (Composite など) または SOAP による「一括」の同期呼び出しを行うことをお勧めします。


24 時間内に送信可能なバッチ数は最大で 15,000 件に制限されています。このバッチ割り当ては Bulk API と Bulk API 2.0 で合計されるため、Bulk API または Bulk API 2.0 で処理されるバッチはすべて、この割り当てに反映されます。

# フローとの併用でフローが起動しない場合

+ [Data Loaderが絡むと機能しない場合があるのですね](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000Nr5d)
+ [データローダーでの一括編集トリガーでフローを実行したい](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KECHr)

:::note
バッチサイズを1にしてみたら、どうなりますか？ 

https://developer.salesforce.com/docs/atlas.ja-jp.dataLoader.meta/dataLoader/configuring_the_data_loader.htm

1レコードしかアップロードできないのではと想像してましたが、 

データローダーのバッチサイズを 1 に設定したところ、一括処理ではなく 1 レコードごとの処理となり、Apexが起動されました。 
:::

+ [バッチサイズ](https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T4ApISAV)


# work bench

+ [batch size in work bench](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000IRlCg)

:::note
シリアルとパラレルで実行することで同様の結果が得られると思います...ワークベンチ > 設定 > 「データ管理オプション」セクション > 「非同期同時実行モード」 

設定値 = シリアル。 

ホバーごとに: 「...競合を回避するには、シリアル処理が必要です。」
:::
テーブル構造をAIに質問！NotebookLMを活用したDB調査チャットボットの作り方

今回はNotebookLMを使用したデータベースのテーブル構造を教えてくれるチャットボットを検討してみたので紹介します。

# はじめに
なぜこのようなことを始めたかというと、既存で作成されているアプリケーションに関わる時の大きなハードルとなるのがデータの持ち方であると思います。
特に数年のさまざまな機能が開発されているとテーブルの数も多くなり、定義書があっても、全容を把握するのは難しくなるでしょう。さらに追加の開発を行う際にテーブル定義の考慮もれにもつながる可能性があると思います。
そこでアプリケーション開発に途中から入った人がデータ構造の理解で躓かないようにするための解決策を検討してみました。

# 検討したこと
テーブル定義をAIの元データとして扱い、テーブル構造を理解する手助けをする仕組みを作ることを考えました。またアプリケーションの初期フェーズではなく、すでにある程度の数のテーブルが稼働している状態を想定しています。
また、新しいテーブルが増えた場合も、簡単に元データを更新できる仕組みを作りたいと考えました。

# 利用するもの
GoogleのNotebookLMを使用します。
NotebookLMを選んだ理由は、ファイルをアップロードするだけで簡単にRAGを組み込んだチャットボットを作成できる点と、Googleアカウントさえあればすぐに試せる点です。
DBの定義の抽出はDBeaverを使用します。

# 手順
## 1.DBのER図を抽出する
DBeaverで対象のデータベースのスキーマを右クリックし、「View Diagram」という項目をクリックするとER図が表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869077/ed0acadd-d8da-49c3-93a0-73db0d9d99aa.png" width="50%"/>


### 1.1 カラムの情報を追加する
標準の設定だとテーブル名やカラム名のみで、まだ出せる情報があるので下の歯車から設定を変更できます。
Attribute stylesの設定を変更することでNOT NULL制約やカラムの型定義、コメントなどが追加で表示されます。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869077/14cf9b7f-d6c0-4d62-974c-834233e34451.png" width="50%"/>


### 1.2 適用して更新

### 1.3 PrintからPDFを出力
プリンターのアイコンをクリックし、左下のPDFボタンを押すとPDFが出力できます。
注意点としてはテーブル数が多くなるとPDFにした場合、一つのテーブルがページの境目で切れてしまう可能性があります。ページの途中で切れてしまうとNotebookLMが正しくテーブルの定義を認識できなくなる可能性があります。
その対策のため「Page attribute」からページサイズの設定から独自の縦幅と横幅を指定して全てが1ページに入るように広めに調整します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869077/db1c7240-4567-41ca-a6c0-7388ff8f846b.png" width="50%"/>


## 2.NotebokLMにテーブル定義のPDFを読み込ませる
ここからは簡単で、先ほど作成したPDFをNotebookLMのソースとして入れるだけです。

### 2.1 マイノートブックから新規作成を選択
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869077/192ba193-d95a-4230-bf6a-5dd4e18cb3d5.png" width="50%"/>


### 2.2 ソースを追加を選択
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/869077/872d8b68-6a18-4a36-b19f-7160d6133eb6.png" width="50%"/>



### 2.3 ソースをアップロードから1.3で出力したPDFを選択してアップロード


これだけで先ほど作成したDBのER図のPDFを読み込んでくれます。

# 実際使ってみた感想
テーブルの名前やカラムの名前、型の定義などは正確に応答してくれました。
また今回はカラム名に意味はない形で確認しましたが、実際のテーブルで試すとコメントを設定していなくてもカラム名からおよその利用用途を推測して回答をしてくれました。テーブルのカラム名をしっかりと決めているテーブルであれば、新規でコメントを追加しなくても参考にはなりますが用途がわかるのはすごいと思いました。
また、実際のデータを見て判断するわけではないので区分値など値の入力値の制約があるものはコメントにしっかりと記述することで実際の制限を回答してもらうこともできることを確認しました。

ただテーブル間の繋いでいる外部キーなどは、ソースが文字情報にされている関係か抜け落ちてしまうため「このテーブルとこのテーブルの関係を教えて」というような聞き方をしても回答してくれませんでした。
この方法を使用する場合、カラム名の統一や明確な命名規則が重要です。特に、命名規則を別のソースとしてテキストに追加すれば、NotebookLMに正しく認識させることができる可能性を上げることができます。命名例えば、外部キーの参照先のテーブル名とカラム名をアンダーバーでつなぐ（例：tablename_columnname）形式にすると、NotebookLMが関係性を理解しやすくなる可能性があります。

データの更新には、ローカルのファイルを再アップロードする必要があるため一定間隔でソースを更新する必要はあります。データベースのテーブル追加はそこまで頻繁に実行されることもないと思うので、1ヶ月に一度くらいの頻度で十分だと思います。


# まとめ
NotebookLMを活用することで、 データベースのテーブル構造を簡単に調査できるチャットボット を作成できました。

・テーブル名・カラム名・型の定義は正確に回答
・カラム名から利用用途を推測することも可能
・コメントを充実させると、入力値制約も回答可能
・外部キーの関係は認識が難しいが、命名規則を工夫すれば精度向上の可能性あり
・データの更新は手動だが、頻度は低めで問題なし

既存のシステムに後から関わる際に、 データ構造の把握を効率化できるツールとして活用できる ので、ぜひ試してみてください！

※誤る可能性もあるので出力された内容は、しっかりと確認は必要です。
【Outsystems】HEADメソッドのAPIをRequestする

# 初めに
AzureBlobからファイルを取得するServerActionを作成した。
ファイルを取得する際にファイルサイズを確認し、一定サイズ以下であれば受け入れるようにしたい。
AzureBlobの[プロパティ取得のAPI](https://learn.microsoft.com/ja-jp/rest/api/storageservices/get-blob-properties?tabs=microsoft-entra-id)はHEADメソッドでRequestする必要がある。
ところがOutsystems標準のConsume REST APIではHEADメソッドを選択できない。

# 環境
Service Studio Version 11.54.37

# 標準で選択できるHTTP Method

- GET
- POST
- PUT
- DELETE
- PATCH

# Consume REST APIでHTTPMethodをHEADに変更するには

Consume REST APIでは、リクエスト前にHeaderなどをOnBeforeRequestでカスタマイズできる。
この方法を使ってHTTPMethodを上書きできそう。
[REST APIを利用する/シンプルなカスタマイズ](https://success.outsystems.com/ja-jp/documentation/11/integration_with_external_systems/rest/consume_rest_apis/simple_customizations/)

もともとのRequestを読み込んで、CustomizedRequestを送信することができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796185/69f1080a-25c0-4a2d-a83b-97ee7b052fbb.png)

このRequestとCustomizedRequestの中にHTTPMethodというAttributeが存在している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796185/bd35c34e-ac99-4b4a-bcde-1c7fb10f0e70.png)

確認すると、各メソッドでのConsume REST APIを実行したとき、選択したメソッドが設定されている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796185/1adecdf3-0856-449b-9efb-27a1df340868.png)

これを上書きすることでOutsystems ConsumeAPIの標準で選択できないHTTPMethodのAPIをRequestすることができた。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796185/caab3d1a-84fa-461c-96cc-e6cfeb9e012f.png)

# まとめ
OutsystemsでHEADメソッドのAPIをRequestするには、OnBeforeRequestでCustomizedRequest.HTTPMethodを"HEAD"で上書きすればよい。
VBA事始め２　DX内製化はExcelで出来る（VBAの基礎）

# VBAのオブジェクト
言語としてのVBAは、初期型のVisual Basicが元になっていて最低限覚えておくべき事は以下のとおりです。
１．クラスモジュール、標準モジュール、ユーザーフォーム、ワークブック、ワークシートにコードを書くことができます。
　　・クラスモジュールは独自クラスを作ることはできるモジュールです。
　　・標準モジュールには、主に共用する処理を書きます。
　　・ユーザーフォームには独自ダイアログを作るコードを書きます。
　　・ワークブックには、Windowsを含むワークブックの操作をコードで行います。
　　・ワークシートワークシート操作をコードで行います。

２．変数に主には、
　　String　(文字列型)、
　　int(16Bit)、long(32Bit)　(整数型)、
　　Float(4Byte)、Double(８Byte)　(浮動小数点型)、
　　Variant(どんな値でも入れることができる)型、
があります。

３．実際のプログラムは
　　１．で上げたオブジェクト内にsubプロシージャまたはfunctionプロシージャというコードを書きます。
　　sub プロシージャ名(引数名 as 型,・・・)
　　　　dim ローカル変数名 as 型、・・・
　　　　コード
　　end sub
または
　　function プロシージャ名(引数名 as 型,・・・) as 戻り値の型
　　　　dim ローカル変数名 as 型、・・・
　　　　コード
　　　　プロシージャ名 = 戻り値
　　end function

プロシージャや各モージュル内で宣言した変数は、それぞれPublicまたはPrivateという公開・非公開属性をつけて宣言することができます。

# 演算子
　１．四則演算子
 　　＋は足し算、ーは引き算、＊は掛け算、／は割り算
　　　Mod は余りを計算する

　２．べき乗
 　　n ^ 3 は変数ｎの３乗

　３．＝は要注意
 　　この後の制御文で使用される論理演算の場合は、左辺＝右辺で等しいと言う条件値
   左辺が変数名の場合は値を入れる代入演算子

　４．論理演算
　　左辺 > 右辺は左辺が大きい場合True、
  　左辺 < 右辺は左辺が小さい場合True、
　　左辺>=右辺は右辺が左辺以下の場合True、
  　左辺<=右辺は右辺が左辺以上の場合True、
　　左辺 And 右辺は左辺と右辺がTrueの場合True、
　　左辺 Or 右辺は左辺か右辺がTrueの場合True、

# 制御文
　制御分には If Then Else End If、For Next、Do Loop While
　１．If
 　　IF 論理演算 Then
  　　　論理演算がTrueの場合の処理
　　Else
  　　　論理演算がFalseの場合の処理
　　End If

　　IF 論理演算１ Then
  　　　論理演算１がTrueの場合の処理
　　ElseIf 論理演算２ Then
  　　　論理演算２がTrueの場合の処理
　　Else
  　　　論理演算１，２がFalseの場合の処理
　　End If

２．For
　　For 変数名＝初期値 To 終了地 Step 幅
　　　繰り返しコード
　　Next 変数名

　　For Each 変数名 in レンジや配列
　　　繰り返しコード
　　Next 変数名

３．Do Loop While
　　Do While 論理演算
　　　繰り返しコード
　　Loop

　　Do
　　　繰り返しコード
　　Loop While 論理演算

　Whileの場合は論理演算がTrueの間ループ
　Untilの場合は論理演算がFalseの間ループ

 ほかにもいろいろありますが、とりあえずこれぐらい覚えればプログラムは作れます。

# 基本学習
 基本的な話はYouTubeで調べるとたくさん出てきます。
 一例として・・・
 https://www.youtube.com/playlist?list=PL5FKFa9bpZNF4LPhgvrQiGD59MNiN-4Sw

[インデックスへ戻る](https://qiita.com/kawamo55/items/84ba4068e728813b7624)
ケアレスミス、やってない？〜Django~で沼った話

# 自分用メモ
Djangoを学んでいた時に沼った話をまとめておきます。

:::note info
ケアレスミスについての話なのでDjangoは関係ないです
:::
## 経緯
Djangoの入門本を使ってwebサービスの作成について学んでいたときのことです。
HTMLにURLパターンを埋め込むと、以下のような画面になりました。
![スクリーンショット 2025-03-10 7.51.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3827586/f8be8ffc-3fdb-4363-bb5d-e2e10ead7b7f.png)
埋め込んだURLパターン

``` html:index.html
<a href="{% url 'blogapp:blog_detail'><a>
```

URLパターン

```python urls.py
path(
        'blog-detail/<int:pk>/',
        views.BlogDetail.as_view(),
        name='blog-detail'
    ),
```

さてみなさん、お気づきでしょうか…
そう、 **URLパターン名と、実際に埋め込まれたURLパターン名が違うのです！**
そりゃ、動くはずがないです。
以上、ケアレスミスには気をつけよう、という話でした。
【GitHubフォーク】開発フロー整理

本記事では、GitHubでの開発においてよく使われるフォークを活用した運用フローを、リポジトリ・ブランチ構成図と具体的なコマンドを交えて整理します。
新たな職場の運用でフォークを使用し始めたので、自分なりの運用方法とその流れをまとめました。

### 🟢登場するリポジトリとブランチの整理

以下のような構成を前提とします。

```
【GitHub (upstreamリポジトリ・チーム共有)】
├─ master（本番用）
└─ develop（開発用）
     ↑                  ↑
プルリク          プルリク
【GitHub (originリポジトリ・自分専用のフォーク)】
├─ master（upstream/masterをフォーク）
├─ develop（upstream/developをフォーク）
└─ 作業ブランチ（後で作成される）
       ↑push
【ローカルPC】
├─ master（origin/masterを追跡）
├─ develop（origin/developを追跡）
└─ 作業ブランチ（upstream/masterから作成）
```

- **upstream**: チームで共有するリポジトリ（元リポジトリ）
- **origin**: 自分専用のフォーク（GitHub上）
- **ローカル**: 自分のPC環境で作業するリポジトリ

---

### 🟢運用の流れ（詳細コマンド付き）

**① upstreamリポジトリをフォーク（ブラウザ操作）**
- GitHubの画面上でupstreamリポジトリをフォーク
  → 自分用リポジトリ（origin）が作成される。

（コマンド不要・GitHubブラウザ上で操作）

**② originリポジトリをローカルにクローン（ローカル操作）**

自分のPCにoriginをクローンします。

```sh
git clone https://github.com/<あなたのGitHub名>/<リポジトリ名>.git
cd <リポジトリ名>

# upstreamも登録（推奨）
git remote add upstream https://github.com/<元のリポジトリ所有者>/<リポジトリ名>.git
```

**③ upstreamの最新を取得して作業ブランチ作成（ローカル操作）**

最新のupstream/masterを元にローカルで作業ブランチを作成。

```sh
git fetch upstream
git checkout -b feature/<作業名> upstream/master
```

**④ 作業を行いコミットする（ローカル操作）**

ローカルの作業ブランチで作業をしてコミットします。

```sh
git add .
git commit -m "作業内容をコミット"
```

**⑤ originリポジトリに作業ブランチをpush（ローカル操作）**

ローカルの作業ブランチをoriginにpushします。

```sh
git push -u origin feature/<作業名>
```

**⑥ GitHub上でorigin作業ブランチ → origin/developにマージ（GitHub操作）**

GitHub画面でプルリクエストを作成し、origin内でdevelopにマージします。

- GitHubページで操作： feature/<作業名> → develop にプルリクエスト＆マージ

**⑦ origin/develop → upstream/developにプルリク提出（GitHub操作）**

マージ後のoriginのdevelopブランチをupstreamのdevelopに向けてプルリクします。

- GitHub上でorigin/develop → upstream/developへプルリク（開発環境でテストを行う）

**⑧ upstream/developでテスト確認（GitHub＆開発環境操作）**

開発環境でテストをして問題なければ次へ。

- （開発環境で動作確認）

**⑨ テスト完了後、origin作業ブランチ → origin/masterにマージ（GitHub操作）**

動作確認後、本番にリリースするためorigin内でmasterにマージ。

- GitHub画面で操作： originの feature/<作業名> → originの master にマージ

**⑩ origin/master → upstream/masterへプルリクしリリース（GitHub操作）**

最後に、本番環境へのリリースのためプルリクエスト。

- GitHub画面で操作： originの master → upstreamの master へプルリク＆マージ（本番環境へリリース完了）

---

### 🟢定期的にoriginをupstreamと同期する方法（推奨）

originのdevelopやmasterが常に最新になるよう、定期的に同期を取りましょう。

```sh
# developの同期
git fetch upstream
git checkout develop
git merge upstream/develop
git push origin develop

# masterの同期
git checkout master
git merge upstream/master
git push origin master
```

これによりoriginは常にupstreamと同じ最新状態を保てます。

---

### 🟢最終的な全体イメージ（再掲）

以下の図がこの運用フローの全体イメージです。

```
[ローカル作業ブランチ]
     │push
     ▼
[GitHub originリポジトリ]
     │プルリク
     ▼
[GitHub upstream develop（開発環境テスト）]
     │テスト後マージ
     ▼
[GitHub origin master（本番準備）]
     │プルリク（リリース）
     ▼
[GitHub upstream master（本番環境）]
```

---

### 🟢この運用のメリット（まとめ）
- フォークしたリポジトリ(origin)を経由することで、本流(upstream)への影響をコントロール可能。
- 開発・テスト・本番のリポジトリとブランチが明確に分かれ、管理がしやすい。
- 他人のリポジトリを汚さず、権限のない環境でも安全に作業が可能。

---

以上、GitHubフォークを活用した開発フローの完全整理でした。ぜひ参考にしてみてください！
PHPで「三項演算子」の動作を確認してみた。

# 概要

PHPで「三項演算子」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/php/if/index8.html

# 実装

以下のファイルを作成しました。

```sample.php
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
<?php
$lang = 'En';

$msg = $lang == 'Jp'  ? 'こんにちは' : 'Hello';
print $msg.'<br />';

$lang = 'Jp';

print $lang == 'Jp'  ? 'こんにちは' : 'Hello';
?>
</p>

</body>
</html>
```

以下のコマンドを実行しました。

```
$ php sample.php 
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>PHPテスト</title>
</head>
<body>

<p>PHPのテストです。</p>

<p>
Hello<br />こんにちは</p>

</body>
</html>
```

# まとめ

何かの役に立てばと。
GASについて

## GASとは？？
https://workspace.google.com/intl/ja/products/apps-script/

GAS（Google Apps Script）はGoogleが提供するJavaScriptベースのスクリプト言語のこと

Google Workspace（旧G Suite）のアプリケーション（Google Sheets, Google Docs, Google Driveなど）を自動化するために使用される

Googleのクラウド環境で動作するため、サーバーの管理が不要で、ユーザーが簡単にスクリプトを記述して、さまざまなタスクを自動化することができる

## GASでできること
### googleサービスを利用した自動化
例：
・Googleフォームの回答をスプレッドシートに自動保存
・Googleスプレッドシートの内容をもとにGmailの自動送信


### 外部サービスとの連携
例：
・スプレッドシートの更新をSlackに通知
・Googleフォームの問い合わせ内容をChatGPTに渡して、自動返信を作成
・Googleカレンダーの予定を定期的にLINEでリマインド

## GASの開発方式
### コンテナバインド型
コンテナバインド型は、スプレッドシートやドキュメント、スライド、フォームなどのGoogleのサービスに紐づく開発を行うときに使用

:::note info
メリット
・Googleアプリと簡単に連携できる
→ SpreadsheetApp などの専用オブジェクトがすぐに使える

・スクリプトをファイルと一緒に共有できる
→ スプレッドシートを共有すれば、スクリプトも一緒に共有される
:::

:::note warn
デメリット
・スクリプト単体では管理しづらい
→ スクリプトがスプレッドシートやドキュメントに埋め込まれているため、独立して管理できない

・別のGoogleアプリ（例：スプレッドシートA → B）へのアクセスが難しい
→ 例えば、スプレッドシートAのスクリプトからスプレッドシートBを操作するには、手間がかかる

・GASプロジェクトの一覧に表示されない
→ https://script.google.com/home からは見えず、紐づいたGoogleアプリからしかアクセスできない
:::

### スタンドアロン型
スタンドアロン型は、スプレッドシートやドキュメント、スライド、フォームのファイルに紐づいていない開発を行うときに使用

:::note info
メリット
・スクリプト単体で管理しやすい
→ Googleドライブ上で独立したファイルとして管理できる
・複数のGoogleサービスを統合できる
→ 例：スプレッドシートとGmailを連携させて、自動メール送信
:::

:::note warn
デメリット
・Googleアプリとの連携には明示的な権限設定が必要
→ SpreadsheetApp.openById() を使わないとスプレッドシートを操作できない

・スプレッドシートと一緒に共有できない
→ スクリプトを個別に共有する必要がある
:::

参考
https://workspace.google.com/intl/ja/products/apps-script/
https://qiita.com/tags/gas
https://satori.marketing/marketing-blog/gas-introduction/
paiza.ioでelixir その340

# 概要
paiza.ioでelixirやってみた。
thenとtapに、なじめないので、訓練してみた。

# サンプルコード

```

#then/2は第1引数の値を第2引数の関数に渡し、その結果を返します。
#tap/2は第1引数の値を第2引数の関数に渡して実行しますが、第1引数に渡した値自体をそのまま返します。

then(5, &IO.puts(&1))
|> IO.inspect
IO.puts("ok0")

tap(5, &IO.puts(&1))
|> IO.inspect
IO.puts("ok1")

tap(1, fn x -> 
    x + 1 
end)
|> IO.inspect
IO.puts("ok2")

then(2, fn x -> 
    x + 2 
end)
|> IO.inspect
IO.puts("ok3")


then(5, fn x -> 
    x + 1
end)
|> IO.inspect()

tap(3, fn x -> 
    x + 1 
end)
|> IO.inspect()


"hello world"
|> tap(&IO.puts/1)
|> then(&Regex.scan(~r/\w+/, &1))


"hello world"
|> (fn x ->
      IO.puts(x)
      x
    end).()
|> (&Regex.scan(~r/\w+/, &1)).()




```

# 実行結果

```
5
:ok
ok0
5
5
ok1
1
ok2
4
ok3
6
3
hello world
hello world
```

# 成果物

https://paiza.io/projects/buhOdGgSJW_Erv-4gC-C-Q

以上。
【トラブルシュート事例】Windows Server ドメインコントローラ＋複数NICで通信断が発生する原因と対処法

# はじめに
Windows Server (ドメインコントローラ兼DNSサーバ) で複数NICを有効にした環境において、

- 「あるNIC (LAN2) 上で確立していた通信が、別のNIC (LAN3) にケーブルを挿すと切断される」
- アプリケーション側では WSAECONNABORTED (10053) エラーが発生する
- Windowsイベントビューアには通信断が記録されない
といった問題が起こることがあります。
今回の事例では、実際のパケットキャプチャを解析した結果、「NetLogon再バインド」 と呼ばれる Active Directory 特有の挙動が通信切断の主原因と推測されました。

本記事では、このトラブルシュートの過程と原因の考察、そして再発防止策について整理します。

# 現象の概要
1. ドメインコントローラ (AD + DNSサーバ) を稼働する Windows Server 2022 マシンがある
2. このマシンは 複数のNIC (LANポート) を有効にしており、OSからは LAN1 / LAN2 / LAN3 / LAN4 として見える
3. LAN2 で確立していた通信(アプリのTCPセッション)が、LAN3 や他のLANポートにケーブルを挿すと突然切断される
4. アプリ側ログには WSAECONNABORTED (10053) が出力され、サーバ側では TCP RST が返されている形跡
5. Windows イベントログには特に「リンク断」などは残っていない

このように、一見すると「物理層の混線」や「NICドライバの不具合」を疑いたくなる挙動ですが、実際にパケットキャプチャ（Wireshark など）を取ってみると、次のようなパターンが見えました。


# パケットキャプチャで判明した挙動
### LAN2キャプチャ
- TCPセッションが再送 (Retransmission) を繰り返し、最終的にサーバから RST が返る
- その間に IGMPv3 / LLMNR / mDNS など、複数NICが起動した際のマルチキャスト・名前解決関連パケットが大量に見える

### LAN3キャプチャ
- ケーブル挿入直後に ARP Probe, NBNS, LLMNR, mDNS, IGMPv3 Join など、Windows が「NICを新たに有効化した直後」に行う典型的なマルチキャスト探索が多発
- 「LAN2の通信を意図的に切断する」ような直接的パケットは見えない

これらを総合すると、「LAN3 をリンクアップする → OSがマルチホーミング環境を再評価 → NetLogonや
DNS関連サービスが再バインド → 既存TCPセッションを強制RST」 という流れが疑われます。

# 「NetLogon再バインド」とは何か？
### ドメインコントローラ＋複数NICの難しさ
ドメインコントローラ(DC)は、起動やNIC状態変化のたびに DNS動的登録 (Dynamic Update) や NetLogonサービスの再初期化 を行う場合があります。
マルチホーミング構成（複数NICが有効）だと、DCが自身のホスト名を複数アドレスでDNSに登録しようと試みるなど、思わぬ再初期化が起こりがちです。

### 再バインドの結果
Windows Server は「NICが増えた（ケーブル挿した）」タイミングでルーティングやDNS設定を再評価し、NetLogonが再バインド(再起動)されることがあります。
その過程で 既存のTCPセッションが RST で切断され、アプリケーション側から見ると「突然回線断 → WSAECONNABORTED (10053)」が発生するというわけです。

# よくある他の原因
- NIC省電力機能 (EEE, Link State Power Management, WoL)
  - 短時間のリンクダウンを起こす可能性がある
  - ただし、本件では無効化しても改善しなかった
- NICドライバの不具合
  - 最新版を入れても再現する場合、ハード的な問題よりは OS レイヤの再初期化が本質的な原因のことが多い
- ルーティング競合・複数ゲートウェイ設定
  - 同一サブネットに複数NICが存在する、複数GWが設定されている… などで OS が経路を再計算し、セッション断が発生することも

# 解決策・回避策
### ドメインコントローラを「シングルNIC」で運用
もっともシンプルかつ確実なのは、ドメインコントローラ上のNICを1本に絞ることです。
- 他NICを使わないのであれば、デバイスマネージャやBIOSで無効化
- ADのマルチホーミングは、Microsoftでも推奨されていないケースが多く、シングルNICが原則
### どうしても複数NICが必要なら…
1. 1つのNIC(メインNIC) だけ「DNSに登録する」「デフォルトゲートウェイを設定する」
2. 他のNICは
  - 「この接続のアドレスをDNSに登録する」を オフ
  - デフォルトゲートウェイは 未設定
  - 必要があれば、静的ルートを個別に設定
3. 省電力機能 (EEE, Link State Power Management) は 無効 が安定
4. ケーブルを抜き差しする場合は 極力サーバの運用時間外に行う（物理リンク変化を避ける）

こうすることで、AD や NetLogon が「メインNIC以外のIPを DNS 登録しよう」としなくなるため、不要な再バインドが減って既存通信への影響も最小限になります。

### レジストリ設定で DNS動的更新を無効化？
- DisableDynamicUpdate=1 や RegisterDnsARecords=0 (NetLogonパラメータ) を使えば、動的DNS登録をグローバルに無効化できますが、DCとしてのSRVレコード登録などまで止まるため要注意。
- 原則的には NICごとに「DNS登録するかどうか」を制御する方法がベストプラクティスです。

# パケットキャプチャの観点
- もし「物理的にLAN2のTCPパケットがLAN3へ混線しているのでは？」と疑うなら、リングバッファ(物理ポートごとの送受信バッファ)は独立しており、混線はまず起きないことを理解しましょう。
- 実際は OSのネットワークスタックが「LAN3を有効化」→「NetLogon再バインド」→「LAN2の既存接続を RST」としているだけです。
- パケットキャプチャで “RST を投げている側” を見ると、サーバが明確に「切る意思」で TCP RST を送っているのが分かります。

# まとめ
- Windows Server のドメインコントローラに複数NICを有効化すると、ケーブルの挿抜やOS起動時に NetLogonサービスが再バインドを引き起こし、既存セッションが強制的に切断される事象が起こりやすいです。
- パケットキャプチャで IGMP/LLMNR/mDNS/NBNS が急増しているタイミングで TCP RST が見られる場合、マルチホーミング構成×AD特有の再初期化を疑ってください。
- ベストプラクティス：シングルNIC運用。もし複数NICが必要なら、メインNIC以外のDNS登録をオフにし、ゲートウェイを設定しないなどでトリガーを最小化すると安定します。
Salesforceでメール送信でPDF送信する場合のあれこれ

SalesforceでこのようなPDFをリストメールで送信しようと思います


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/8116e48e-9eee-45c4-947c-20ac39047c1c.png)


添付ファイルでPDFを添付し送信

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/81dc2322-7fc8-4e70-9467-306d6a699ab7.png)



PDFを送信する場合、PDFファイルがhtmlになるようです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/fb746223-b475-4f0f-ad5e-02ea1ddd16d9.png)

htmlをクリックするとこのようになります

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="Refresh" content="0; URL=

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5ec04ec2-2699-4a37-ac80-1e6d6dace3b6.png)

　右の「ダウンロード」をクリックすると
 
 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/bba73ef2-0d43-45b9-96d8-ca1156d70aae.png)


きちんとダウンロードできることが分かります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/44d6453b-455f-4c06-8cba-286eac67dae2.png)


ダウンロードすればきちんと表示されますが、このような文字列を出さないようにするにはどうすればいいのでしょうか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/5ec04ec2-2699-4a37-ac80-1e6d6dace3b6.png)

その場合、いったんPDFをSalesforceのファイルをアップロードします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/34d4691d-5ec0-46df-bd06-a924aec6e542.png)

アップロードしたファイルに「共有リンク」を作成します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/42206720-d3b0-4b50-b67c-1057b1925740.png)

共有リンクを直接メールのURLで添付して送信すれば、
そのリンクをクリックすればPDFが表示されるのでPDFがスムーズに表示されます

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/b70b907d-12b4-45d9-ba83-fc1651d26765.png)
【VSCode】無料の拡張機能「Cody」が便利！

## はじめに
今回は、VSCodeの便利な拡張機能をご紹介します。一度使ったら、無いと不便に感じるくらい便利です。VSCodeの拡張機能なので、Cursorを使っている方も利用できます。

## Codyとは
　Codyとは、いわゆるAIアシスタントで、コーディングをサポートしてくれます。特に、現在打ち込んでいる内容から、予測変換のように提案を行ってくれる「コード補完機能」が便利です。他にも、対話型のチャットが利用できます。
 　この機能だけでいえば、Github Copilotでも、Cursorでも利用できますが、特に大きな違いが、Codyには**利用回数の制限がない**点です。なんでこのサービスが成り立っているのか分かりませんが、とにかく使う側としてはありがたいです。

## 比較
　AIアシスタントを使う方法は、他にもいくつかあるので、代表的なGithub CopilotとCursorで比較してみました。
### 利用制限
無料プランの使用可能回数について、調べてみました。こう並べると、やはり無制限というのは規格外ですね。

|  | コード補完 | チャット |
|:-:|:-:|:-:|
|Cody|**無制限**|月200回|
|Github Copilot|月2000回|月50回|
|Cursor|-|月250回※|

※Cursorについては、チャット以外も一緒にカウントされ、GPT-3.5が200回、GPT-4が50回という内訳らしい。

　コード補完については、タブで実行しなくても、自分で同じ内容を打った際はカウントされるっぽいです（要検証）。そのため、数字のわりには、すぐに使い切ってしまう印象でした。（Github Copilotの2000回を8日で使い切った人）

### 補完の精度（個人的な感想）
　Cursorについては、一瞬しか使ってない（使えてない）ですが、かなり使いやすかった印象です。Github CopilotとCodyだと、Github Colilotが僅差勝ちかなぁって感じですが、得意分野がちょっと違いそうです。

　例えば、`for i in`と打った時に、Github Copilotの方が、より正確に流れを汲んでくれる印象でした。Codyの場合は、その後`range(10):`のように、一般的によく使うものが提案される印象です。一方、`['a', 'b',`のように打った時には、Codyのほうが正確に規則性を理解してくれる印象です。どちらもコメントを付けてから打ち込むと、そのコメントも汲み取ってくれるので、そこまで大きな差はないと思っています。

## インストール
ここまでの比較を見て、使ってみたいなと思った方は、以下のリンクからインストールしてください

https://sourcegraph.com/cody

### 手順
#### step1
Download fo freeからアカウントを選んでサインアップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922095/7117f533-c76b-4574-bdf0-ed0bcadbbd5f.png)

#### step2
下のContinue with Freeを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922095/8aa9ea68-d6e2-4dd7-ba89-d1d750507a5f.png)

#### step3
Install Cody in VS Codeを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3922095/78798a5e-23ac-42fa-8cf9-e661267f6a09.png)

ここまでやると、VSCodeを開くように促されると思うので、開いて拡張機能を確認してみてください。インストールされていたら、画面右下の通知マークの横に、Codyの顔マークみたいなのがあるので、そこを押すと拡張機能がオンになったと思います。（うろ覚え）


## まとめ
AIアシスタントを、お金をかけずに使いたいなら、Codyがおすすめ！

## 最後に
　ここまで読んで下さりありがとうございました。お金をかけることに抵抗がなければ、有料版のCursorなどを使った方が性能はいいと思いますが、無料で、しかも無制限に使えるというのが本当に素晴らしいです。

## 参考

https://riq0h.jp/2024/12/30/100020

https://qiita.com/PB-193/items/ec444bbed73ba2209f94
BlazorでWebアプリを構築する①とりあえず始める

 # 1. はじめに
  　Webアプリを作ってみたいと思っていたのですが、色々と技術があるため後回しになっていました。あるとき、調べ物をしていた時、慣れ親しんだ環境であるVisual StudioやC#でバックエンドはもちろんフロントも書けるBlazorというフレームワークがあると知りました。これは試してみようと思いまして、不定期連載でその備忘録を記していこうと思います。

 # 2. Blazorとは？
   Blazorとは、c#でWebアプリを作ることができる、ASP.NET Coreに統合されたフレームワークです。バックエンド部分をC#で書けるのはもちろんですが、フロントエンド部分もHTMLとCSSとC#で書くことができます。これはRazor構文という、Web ページに .NET ベースのコードを埋め込むためのマークアップ構文を使用しています。
   詳細な解説は、他の記事に譲ることとします。

# 3. 環境
- Windows 11
- Visual Studio Community 2022
- .NET 8.0

# 4. とりあえずBlazorを始めてみる
## 4.1 Visual Studio をインストール
　Visual Studioをインストールしてない場合、インストールします。すでにインストールしている場合は、更新を確認して最新化します。

## 4.2 新しいBlazorプロジェクトを作成
1. 新しいプロジェクトの作成 > Blazor Web アプリ > 次へ
1. 「新しいプロジェクトを構成します」画面でプロジェクト名や保存場所等を入力
1. 「追加情報」画面はとりあえず全て規定値でOK、「次へ」ボタン押下
1. プロジェクトが作成される

## 4.3 アプリを立ち上げてみる
1. 「▶」ボタンを押してデバッグ実行
1. 証明書を信頼しますか？のダイアログが表示されたら「はい」でOK
1. 以下のような画面が出る
![スクリーンショット 2025-03-10 065550.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376873/ca601b0b-e16a-4296-b216-d2df9ce0ab0a.png)
 左メニューのCounterやWeatherをいじってみるとよい。Visual Studioの「■」ボタンやWebアプリを開いているブラウザを閉じることでデバッグが終了し、アプリが消える（終了する）。 

　以上
COMコンポーネントにイベント機能を追加する

[前回の投稿](https://qiita.com/kzy_yamamura/items/6ac7960d0b7a374b0017)に続き、今回はCOMコンポーネントにイベント機能を追加します。

## 環境
- Excel for Microsoft365(64bit)
- Visual Studio2022

## イベントインターフェースの実装
イベント機能については前回作成した公開インターフェースとは別にイベント専用のインターフェースを追加します。

~~~c#:イベントインターフェース
 [Guid("3DAEF636-1FF7-4ABA-9E5B-47D06BF21E2B")]
 [InterfaceType(ComInterfaceType.InterfaceIsDual)]
 public interface ISampleCalc
 {
     [Description("加算処理")]
     int Add(int a, int b);
 }

// ↓ 追加 ↓
 [Guid("6DC5A491-B3AB-4BB3-979D-4DE2647E058B")]
 [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
 public interface ISampleEvents
 {
     [Description("イベント処理")]
     void SampleEvent(int x);
 }
// ↑ 追加 ↑

 [Guid("5559398B-CF78-4418-A065-CFE6A8F2BEA6")]
 [ComVisible(true)]
 [ClassInterface(ClassInterfaceType.None)]
 [ComDefaultInterface(typeof(ISampleCalc))]
 [ComSourceInterfaces(typeof(ISampleEvents))]
 public class SampleCalc:ISampleCalc
 {
     [ComVisible (false)]
     public delegate void SampleEventHandler(int x);
     
     public event SampleEventHandler SampleEvent;

     public int Add(int a, int b)
     {
         if (SampleEvent != null)
         {
             SampleEvent(a + b);
         }

         return a + b;
     }
 }
~~~
#### [ComSourceInterfaces属性]
作成したインターフェースを割り当てるために設定します。

#### イベントの定義
デリゲートを使いイベントを定義します。
サンプルでは、イベントハンドラが登録されていれば、加算結果を引数にして処理を実行するようにしています。
イベントの定義が正しくできていれば、VBA側でイベント処理として認識されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945532/8ad2315d-e64a-7436-f91c-84da0d2febe9.png)

## VBA側の実装
イベント処理はクラスモジュールでしか定義できません。
新規にクラスモジュールを作成し、WithEventsキーワードをつけてCOMのオブジェクトを定義します。
その後イベントで呼ばれる処理を実装します。
サンプルコードは以下の通りです。（加算結果を引数で受け取りメッセージボックスで表示）

~~~vb:標準モジュール
Sub Test()
    
    Dim sample As Class1
    Set sample = New Class1
    
    sample.Test

End Sub
~~~
~~~vb:クラスモジュール
Private WithEvents calc As SampleCalc

Public Sub Test()

    Set calc = New SampleCalc
    
    calc.Add 1, 2

End Sub

Private Sub calc_SampleEvent(ByVal x As Long)

    MsgBox "Event:" & x

End Sub
~~~

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3945532/47f6115f-4806-e118-deff-d71d2e6e5948.png)
wslでelixir その154

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
四目並べの学習済みmodelを見つけたので、LIVEBOOKで対戦してみた。

# 参考にしたページ

https://qiita.com/GeekMasahiro/items/09c96ccb8da13e445d70

# 環境
windows11
wsl1
ubuntu22.04
elixir1.16.1-opt-26

# setup 

```
Mix.install(
  [
    {:axon, "~> 0.2.0"},
    {:exla, "~> 0.3.0"},
    {:nx, "~> 0.3.0"},
    {:kino, "~> 0.10.0"}
  ],
  config: [
    nx: [default_backend: EXLA.Backend]
  ]
)
```

# 自分のターン

```
gomoku =
  gomoku
  |> Gomoku.put!({2, 1})
  |> tap(fn x ->
    Gomoku.render(x)
    |> IO.puts()
  end)
```

# AIのターン

```
pos = Dqn.get_action(gomoku, q_net)
IO.inspect(pos, label: "next action")

gomoku =
  gomoku
  |> Gomoku.put!(pos)
  |> tap(fn x ->
    Gomoku.render(x)
    |> IO.puts()
  end)
```

# 実行結果

```


   01234
0: -----
1: -00--
2: --*--
3: -----
4: -----

next action: {1, 3}
   01234
0: -----
1: -00*-
2: --*--
3: -----
4: -----

   01234
0: -----
1: -00*-
2: -0*--
3: -----
4: -----

next action: {3, 1}
   01234
0: -----
1: -00*-
2: -0*--
3: -*---
4: -----





```

以上。
MX Linux タブレット向け設定（Intel Atom CPU） 

「MX Linuxの日本語化 手順」の追加記事になります。

:arrow_down: 日本語化の記事です

https://qiita.com/Kazu-Q/items/51408b66f49ad8d2dcc7

MX Linuxを古いWindowsタブレットの **”Intel Atom CPU搭載”** にインストールする場合の設定方法です。

MXツールを使用すると難しいコマンド操作が不要なのでオススメです

## Intel Atom CPU搭載タブレットの設定
Intel Atom CPUは他のCoreシリーズと設計が違いLinuxとの相性問題があります
特にプチフリーズやフリーズが発生して実用に影響が出る場合があります


## 設定の流れ
１．MX Linuxをインストールします　当然ですが 笑
２．MXツールを使用して起動時の設定に追加
３．再起動で反映させる

これだけになります

## MX 起動設定ツールでコマンドを追加
この設定は一度行うだけでOKです
次回起動時から反映されます

### １．MXツールを起動
![1-MXツール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338848/81742ca7-b3e0-4626-b57b-0e935580da0f.png)


### ２．MX 起動設定ツールを選択
![2-MXツール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338848/ab0b7ee1-c9b4-4e1f-bbfe-1ff4002d502e.png)

パスワード入力画面が表示されますのでパスワードを入力
![3-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338848/56932b94-c510-4bf1-b308-aead777f447a.png)

### ３．MX　起動設定ツール（MX Boot Optinons）の設定
![4-1MX起動設定ツール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338848/a1b612c9-b702-4b15-9c19-372a9954678e.png)

カーネルのパラメータ　にコマンドを入力します
`intel_idle.max_cstate=1`
コマンドを入力後　適用　をクリック
![4-MX起動設定ツール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338848/bdf0b267-198d-4965-b3e3-523f68f07fbb.png)

うまく設定が反映されましたら以下の画面が表示されます
![5-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/338848/e2688dfe-548b-4276-9aaf-8d6ce0a1ca60.png)


### ４．再起動して設定を反映させます
再起動後は特に操作は不要です
この設定は次回起動以降も反映されます

## MX Linuxで動作確認済みタブレット　（情報追記予定）

### Lenovo
- ThinkPad10（初代）
    - CPU： Intel Aton Zxxxx 
    - メモリ：2GB
    - ストレージ： eMMC 64GB
    - UEFI： **32bit**
    - USB： USB 2.0 (Type-A)
    - 電源端子： **左**に電源端子があります
- ThinkPad10（第二世代）
    - CPU： Intel Aton Zxxxx 
    - メモリ：2GB
    - ストレージ： eMMC 64GB
    - UEFI： **64bit**
    - USB： USB 3.0 (Type-A)
    - 電源端子： **右**に電源端子があります


### NEC （ThinkPad10　兄弟機）
- ThinkPad10（初代）兄弟機
- Versa Pro タイプVT　PC-VK16　・・・ThinkPad10（第二世代）


### Micrtosoft
- Surface３
    - CPU： Intel Aton x7 Z8700 
    - メモリ：4GB
    - ストレージ： eMMC 64GB / 128GB
    - UEFI： **32bit**
    - USB： USB 3.0 (Type-A)

### Fujitsu（富士通）
- ARROWS Tab Q506 / Q507 / Q508

### ８インチのタブレットは？
本体の画面表示がデフォルトで**縦画面**になっています。
Linuxをインストールすると画面表示の座標が縦画面の設定で表示が横画面になります
→座標が狂い**タッチ操作**や**マウス操作**がうまく動作しません

※座標の設定をすれば使用出来るようになります

## 最後に
個人的に古いWindowsタブレットをLinuxで活用するための動作確認などをしています
動作確認した情報などをシェアしたいと考えています
ハノイの塔問題を解く [python]

ハノイの塔問題を解きます。pythonで書かれています。

```hanoi.py
#!/usr/bin/python3
def movedisk(n,a,b):
    p=" LCR"
    if n>0:
        movedisk(n-1,a,6-a-b)
        print(f"Move disk{n} from {p[a]} to {p[b]}")
        movedisk(n-1,6-a-b,b)

if __name__=='__main__':
    n=int(input("number of disks? "))
    movedisk(n,1,2)

```

```plaintext:実行
$ python hanoi2.py
number of disks? 3
Move disk1 from L to C
Move disk2 from L to R
Move disk1 from C to R
Move disk3 from L to C
Move disk1 from R to L
Move disk2 from R to C
Move disk1 from L to C
$
```
N queens問題を解く [python]

N queens問題を解きます。8 queens問題として知られていますが、ここでは、Nとし、プログラムはN=8とします。
（N*N)の桝目のチェスのクイーンが互いに相手を取らないようにN駒並べる局面を出力します。
pythonで書かれています。

```nqueens.py
#!/usr/bin/python3
N=8 # 盤の桝目とQueenの数
a=[True]*N
b=[True]*(2*N-1)
c=[True]*(2*N-1)
x=[0]*N
solution=0

def found():
    global solution
    solution+=1
    print(f"\n 解 {solution}\n")
    for i in range(N):
        for j in range(N):
            print(" Q" if x[i]==j else " .",end='')
        print("")

def _try(i):
    global a,b,c
    for j in range(N):
        if a[j] and b[i+j] and c[i-j+N-1]:
            x[i]=j
            if i<N-1:
                a[j],b[i+j],c[i-j+N-1]=False,False,False
                _try(i+1)
                a[j],b[i+j],c[i-j+N-1]=True,True,True
            else:
                found()

if __name__=='__main__':
    _try(0)
    exit(0)
```

```plaintext:出力
$ ./nqueens.py
 解 1

 Q . . . . . . .
 . . . . Q . . .
 . . . . . . . Q
 . . . . . Q . .
 . . Q . . . . .
 . . . . . . Q .
 . Q . . . . . .
 . . . Q . . . .

 解 2

(略)
```
2025/3/10主にITとかセキュリティの記事

Microsoft、GitHub、Dropbox: 大規模マルウェア広告キャンペーン警告(3/8)
https://innovatopia.jp/cyber-security/cyber-security-news/48989/

AMD RyzenのZen 4以前のCPUに「脱獄」可能な脆弱性発見 Google研究チームが指摘(3/8)
https://tech-gadget.reinforz.co.jp/18428

PyPIの悪性パッケージ「set-utils」がEthereumプライベートキーを盗む(3/8)
https://innovatopia.jp/blockchain/blockchain-news/48984/

原田産業、通販サイト「ビールの縁側」への不正アクセスと個人情報漏洩は確認されず(3/7)
https://rocket-boys.co.jp/security-measures-lab/harada-sangyo-beer-no-engawa-no-data-breach/

暗号資産狙ったサイバー攻撃対策 取引所運営会社が新団体設立(3/8)
https://www3.nhk.or.jp/news/html/20250308/k10014743241000.html

仮想通貨業界のセキュリティ強化に向けた業界団体設立　国内の交換業者などが参加　情報共有を推進(3/8)
https://jp.cointelegraph.com/news/jcrypto-isac-formed-as-new-cybersecurity-initiative-for-crypto-sector

リップル共同創設者ラーセン氏の24年1月のXRP巨額流出、「LastPass」使用が原因か　専門家分析(3/8)
https://coinpost.jp/?p=601075

Garantex、Tether関連の資金洗浄事件：暗号通貨市場の法執行機関の取り組み(3/8)
https://innovatopia.jp/blockchain/blockchain-news/48979/

中小企業の実態判明 サイバー攻撃の7割は取引先へも影響(3/7)
https://news.nicovideo.jp/watch/nw17325362?news_ref=watch_20_nw17237105

Red Hat Device EdgeとAxiom Spaceが軌道上にエッジコンピューティングを持ち込む(3/8)
https://innovatopia.jp/spacetechnology/spacetechnology-news/48992/

【ネットワーク系】EC2インスタンス構築時のデフォルト設定の"理由"を考えてみる(3/8)
https://qiita.com/mob_engineer/items/d7c156fa93439b09a84d

Go モジュールを雰囲気で使っている人のためのFAQ【Go 1.23.6時点】(3/7)
https://zenn.dev/schottman13/articles/47cfc83e2c6950

Appleを偽るフィッシング報告が増加中、注意を(3/7)
https://www.mapion.co.jp/news/column/cobs2869568-1-all/

【日本】経産省、クレジットカード・セキュリティガイドライン6.0版発行。EMV-3D導入等(3/8)
https://sustainablejapan.jp/2025/03/08/meti-credit-card-security-2/111282

統合開発環境(IDE)の基礎理論と歴史的変遷について「Lispマシン時代」→「Java時代」→「クラウドネイティブ時代」→「AI統合時代」(3/8)
https://nikkeimatome.com/?p=53957

IoT機器のセキュリティー対策　政府機関が認定制度 製品に専用ラベル表示(3/8)
https://www.nikkei.com/nkd/company/us/BBY/news/?DisplayType=2&ng=DGKKZO8720888007032025TB0000

話題の生成AI「DeepSeek」は本当に危ないのか？ビジネスパーソンがおさえておくべき基礎知識(3/8)
https://dime.jp/genre/1935865/

物理学からAIまで、テクノロジーは女性：イタリアの卓越性はどのように変化しているのか(3/7)
https://ja.futuroprossimo.it/2025/03/dalla-fisica-allia-il-tech-e-donna-come-cambia-leccellenza-italiana/

過激配信の司会者、虚偽・誹謗コンテンツのユーチューバー、違法賭博サイト運営者…韓国国税庁が脱税調査に着手(3/8)
https://www.afpbb.com/articles/-/3566647?cx_part=top_category&cx_position=3
単相全波整流回路による電流の過渡現象

# はじめに
単相全波整流回路を用いることで、単相交流電圧を脈動ある直流電圧に変換することができる。さらに、抵抗負荷に対して、直列に大きなリアクトル（コイル）を接続すると脈動が平滑化されて直流電流は滑らかになる。今回はこのことについてPythonを用いてシミュレーションしてみる。

# 回路設定

以下のような回路の負荷電流を考察する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/ba8e5c19-c9c2-4017-a260-c9f005c1018f.png)

また、整流後の電源電圧を以下のように定義する。
```math
E=E_0|sin(\omega t)|
```

この場合、抵抗負荷に流れる電流$I$は以下の微分方程式の関係性を満たす。


```math
L\frac{di}{dt}+Ri=E
```

したがって、

```math
\frac{di}{dt}=\frac{-Ri+E}{L}
```

となる。これをオイラー法を用いて数値計算する。

# プログラム


```python dengen.py
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
import math

# 微分方程式:L di/dt= 1/L(-Ri+E),E=|sin(omega t)|
#パラメータ
R = 1       # 抵抗値
L = 0.1   # インダクタンス
#初期条件 
I=0
#初期時間
t=0
#時間と状態量（ここでは電荷と電荷の微分量）
time_ary=[]
E_ary=[]
I_ary=[]
#微小時間の時間間隔(小さくするほど精度は上がるが計算時間が比例して増大する)
delta_t=0.00001
while(t<0.3):
    E=abs(np.sin(2*math.pi*50*t))
    didt=(1/L)*(-R*I+E)
    #位置の微小変化
    I=I+didt*delta_t
    #演算結果を記録
    time_ary.append(t)
    I_ary.append(I)
    E_ary.append(E)
    #時間の更新
    t=t+delta_t
plt.xlabel("応答時間[s]")
plt.ylabel("電流[A],電源電圧[V]")
plt.plot(time_ary,I_ary,color="blue",label="I")
plt.plot(time_ary,E_ary,color="red",label="V") 
plt.legend()   
#グラフを保存する
plt.savefig("RL_全波整流回路_電流.png")
#グラフの表示
plt.show()
```

これを実行すると以下のようになる。

![RL_全波整流回路_電流.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/f4bc3e1c-5f33-409d-a16e-84cfb024e2b9.png)

このように、負荷電流は徐々に増加していき、立ち上がりの波形の様相を示す。

これは、定常状態だとほぼ一定の値を示す。（直流電流）

https://qiita.com/arairuca/items/99b65d22f96622d763da

一方で、以下のグラフのように、リアクトル分を増加させると脈動成分が小さくなり、立ち上がりも線形的になる。

![RL_全波整流回路_電流2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1686019/160b594f-f0ad-459d-b9ec-a0b8ddaf7cc6.png)



# まとめ

今回は、単相全波整流回路における抵抗負荷電流を立ち上がりをシミュレートした。今回のような回路条件では、定常状態と過渡状態をうまく分離して考察することが大切である。また、リアクトルを大きくすると脈動成分が小さくなり、立ち上がりも線形的になる。このような背景から単相全波整流回路は交流から直流に変換する電源装置の一部（変換器）の役割をすることが多いといえる。

# 参考文献

https://amzn.asia/d/aDahRj9
cursorのMCP機能を使ってgithubに接続しようとしたらトラブった件(Windows編)

環境:windows10,cursor(ver.0.46.7)

## いきなり結論

1. githubで必要な権限を付けたトークンを発行しておく(手順省略)
1. [smithery](https://smithery.ai/)でログインして[github](https://smithery.ai/server/@smithery-ai/github)を選択、あとは表示される手順通り
1. 詳しく書くとInstallationのcursorタブを選択、`githubPersonalAccessToken`の入力欄に発行したトークンを入力して`Generate Command`、発行されたコマンドをcursorに貼り付けて設定。cursor起動中はDOSウィンドウが表示されて鬱陶しいが我慢する
1. 上手く設定できるとこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310702/b2dc1b1f-842d-413c-91e1-8491ea2e9766.png)


## 以降試行錯誤の記録

### cursorから直接接続（執筆時点で不具合有り）

出てきた方法を試す。[参考にしたページ](https://wp-kyoto.net/generate-a-new-pull-request-with-cursor-agent-and-github-mcp/?post_date=20250305105847#heading-1)

```
env GITHUB_PERSONAL_ACCESS_TOKEN=~ npx -y @modelcontextprotocol/server-github
```

windowsだと`env`コマンドがないとか`cmd /c`で実行しないと上手く認識しないとかあった。

[参考](https://forum.cursor.com/t/npx-command-is-not-working-on-mcp-windows-and-macos/53486)
[参考2](https://forum.cursor.com/t/creating-a-wrapper-script-for-env-variables-for-mcp-server/50387)
[参考3](https://forum.cursor.com/t/setting-environment-variable-for-npx-command-in-windows/60166)

#### windowsで動かす方法

1. システムの詳細設定から環境変数`GITHUB_PERSONAL_ACCESS_TOKEN`を設定する(再起動するか`$Env:GITHUB_PERSONAL_ACCESS_TOKEN=~`とかで任意に更新が必要かも)
1. `cmd /c npx @modelcontextprotocol/server-github`をコマンドとしてMCPサーバーに設定する
1. 下記の状態になったらOK

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310702/a0ffae42-184b-41d0-921d-d5cfde8abbf1.png)

#### 何が問題？

publicなリポジトリは取得できるけどprivateなリポジトリが取得できない。
権限ミスかと色々試したけどできない。
どうやら`@modelcontextprotocol/server-github`でバグが発生している模様。
[GithubのIssue](https://github.com/modelcontextprotocol/servers/issues/727)
上記Issueが解決すればこの方法でも問題はなくなるかもしれない。
ちなみにこの問題はmacとかでも起きているのかも？

### veyrax経由で取得してみる（執筆時点で不具合有り）

[veyrax](https://www.veyrax.com/web)にもgithubへのアクセス機能があるのでアカウントを作成して連携してみた。
結果、cursorから直接接続する場合と同じくprivateなリポジトリが取得できなかった。

## 結論、再び
冒頭の手順でsmithery経由して接続するとprivateなリポジトリの情報が取得できた。
日本語での情報が少なくて収集が大変だった…
情報が増えたりcursorのバージョンとかが上がるとこんな苦労もなくなるかも。
AI エディタ Cursor を使って jsPsych のプラグイン設定エディタを作ったら、統合開発環境版 jsPsych が作れそうな気がしてきた

## 問題
　生成AIの発展スピードは非常に速いです。2年前に書いた記事（https://qiita.com/temochiz/items/806f7fd302b94db0c4bb） のときは、AIが出力したプログラムを自分で手直しする箇所が多かったのですが、最近はほぼプロンプトだけで期待通りのものが完成するようになりました。
しかし、プログラムの流れも大事ですが、実験で使う刺激も簡単に作れるようにならないと便利じゃありません。
　そこで今回はAI エディタ の Cursor を使い、jsPsych のプラグインパラメーターを簡単に設定できるエディターが作れるかを試してみました。

## 方法
以下の手順で実施しました。

1. 適当にファイルを作成（例：html-keyboard-response.html）
2. Cursorを使って以下のようなプロンプトを入力して実行

```
- jsPsychの html-keyboard-response のパラメーターを設定するエディターを作成してください。
- メッセージを画面に表示する機能を含める。
- メッセージ、キー入力などの選択肢を自由に設定可能にする。
- 設定内容をコードとしてポップアップ表示し、クリップボードにコピーできるようにする。
- コピー後に「クリップボードにコピーしました。」と表示。
```

## 結果
コード生成中

![generate.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1252322/1f64804e-6b9a-4893-974f-44c50a1518f7.png)

そして、期待通りのものが簡単に生成されました。
実行するとこんな画面
![kansei.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1252322/ffa1eb85-7e4a-4fcc-b552-58bd56091006.png)

実際に動作を試せるものも用意しました。↓  
https://temochiz-lab.github.io/jspsyctools/jsPsych_plugin_html-keyboard-response_.html

## 今後の展開
ここまで、ものの10分くらいでできているので、全プラグインも数日あればできそうです。
ので、
- すべてのjsPsychプラグイン向けエディターの作成
- 作成したコンテンツのオンライン保存機能
を実装した上で、
- シナリオエディターを含めた統合開発環境化

が、できるんじゃないかと思います。
興味のある方、一緒に開発しませんか？
1人じゃめんどくさいなー、やらんよなーと思うのですが、どなたか励ましてくれる人が作業をちょっと分担していただけたりすると、2人で1-2週間でそれっぽいものが出来上がると思います。
3人くらい有志がいれば、細々とOSS公開してメンテを続けられるんじゃないかと。
Laravel

# Laravel について

## MVC アーキテクチャについて
Laravel は MVC（Model-View-Controller）アーキテクチャを採用しています。MVC とは、以下の 3 つの要素に分かれた設計パターンです。

- **Model（モデル）**: データベースとやり取りし、ビジネスロジックを担う部分
- **View（ビュー）**: ユーザーに表示される画面部分
- **Controller（コントローラー）**: Model と View を仲介し、リクエストを処理する部分

これにより、コードの保守性が向上し、役割が明確になります。

## ルーティングについて
Laravel では、ルーティングを使用して URL と処理を結びつけます。ルートは `routes/web.php` に定義します。

```php
use Illuminate\Support\Facades\Route;

Route::get('/', function () {
    return view('welcome');
});

Route::get('/hello', function () {
    return 'Hello, Laravel!';
});
```

コントローラーを使ったルーティングも可能です。

```php
Route::get('/users', [UserController::class, 'index']);
```

## マイグレーションについて
マイグレーションは、データベースのスキーマを管理する機能です。新しいテーブルを作成するには、以下のコマンドを実行します。

```sh
php artisan make:migration create_users_table
```

生成されたマイグレーションファイル (`database/migrations/xxxx_xx_xx_xxxxxx_create_users_table.php`) を編集し、スキーマを定義します。

```php
Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamps();
});
```

マイグレーションを適用するには、次のコマンドを実行します。

```sh
php artisan migrate
```

## Eloquent ORMについて
Eloquent ORM は、Laravel のデータベース操作を簡単にする ORM（オブジェクト・リレーショナル・マッピング）です。モデルを作成し、データベースとやり取りできます。

```sh
php artisan make:model User
```

`app/Models/User.php` に Eloquent モデルが作成されます。データの取得は以下のように行います。

```php
$users = User::all();
```

特定のデータを取得する場合:

```php
$user = User::find(1);
```

データの作成:

```php
$user = new User;
$user->name = 'John Doe';
$user->email = 'john@example.com';
$user->save();
```

## Blade テンプレートエンジンについて
Blade は Laravel のテンプレートエンジンで、簡単に HTML を作成できます。

`resources/views/layout.blade.php`:

```html
<!DOCTYPE html>
<html>
<head>
    <title>@yield('title')</title>
</head>
<body>
    @yield('content')
</body>
</html>
```

`resources/views/home.blade.php`:

```html
@extends('layout')

@section('title', 'ホームページ')

@section('content')
    <h1>Laravel へようこそ</h1>
@endsection
```

## CRUD 処理について
CRUD（Create, Read, Update, Delete）処理は、Laravel の基本的なデータ操作です。

### データの作成 (Create)

```php
$user = User::create([
    'name' => 'Alice',
    'email' => 'alice@example.com'
]);
```

### データの取得 (Read)

```php
$users = User::all();
```

### データの更新 (Update)

```php
$user = User::find(1);
$user->name = 'Updated Name';
$user->save();
```

### データの削除 (Delete)

```php
$user = User::find(1);
$user->delete();
```

---

以上が Laravel の基本的な機能についての紹介です。初心者でもこの流れを理解すれば、簡単なアプリを作成できるようになります。
Markdownのテーブル編集を快適にするVSCode拡張機能を作成しました

## はじめに

VSCodeの拡張機能を作成しました。拡張機能の紹介と実装時の苦労した箇所、実装の進め方を説明します。

## 拡張機能の概要

今回作成した拡張機能は、Markdownのドキュメント内にあるテーブルをWebviewのエディタで編集できる機能です。

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359375/6af96777-ecfc-401c-9098-20e91db06909.gif)

通常のMarkdownエディタでは、テーブルの編集が手間になることが多いですが、この拡張機能を使えば、VSCode内で完結したまま画像のようにスプレッドシート風の操作での編集が可能です。またスプレッドシートからの貼り付けにも対応しています。


### 主な機能
- **スプレッドシート風のテーブル編集**
  - Markdown内のテーブルを専用のUIで編集
- **行・列の追加・削除**
  - 最終位置の行や列の挿入・削除
- **セルのコピー＆ペースト**
  - Excelのようにセル単位でコピペ可能
- **整形機能**
  - 編集したテーブルを整形してMarkdownに反映

拡張機能は以下URLからインストールできます。

https://marketplace.visualstudio.com/items?itemName=octop162.markdown-table-editor

GitHubリポジトリは以下のページです。

https://github.com/octop162/markdown-table-editor

## 実装時の苦労したポイント

開発を進める中で、特に苦労したポイントをいくつか紹介します。

### 1 contentEditable
文字列を入力する欄はHTMLではinputタグやtextareaタグを使うことがほとんどですが、文字サイズ、文字色、などよりリッチな見た目にしたい場合はdivタグなど任意のタグにcontentEditable属性を有効にすることでタグの中身を編集可能にできます。


この属性とReactの組み合わせがうまくいかず苦労しました。カーソルが左端に固定されてしまい文字を思い通りに入力できなかったり、そもそも何も反応しないなどの挙動に悩まされました。contentEditableに関する記事を読み動作確認を繰り返すことで不具合を解消していきました。

- https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/contenteditable
- https://zenn.dev/karintou/articles/35e9e314c5579f

### 2.状態管理
テーブルを操作する上で選択されている状態、編集している状態など複数の状態がありキーボード操作によりどのような処理がされるかが実装をすすめるうち複雑になっていきました。

例えば選択しているときにEnterを押すと編集状態、編集状態ではEnterを押すと編集の完了。編集状態ではカーソルによるセル移動は無効ですが、Tabによる移動は可能であるなど条件分岐が多く不具合も多発しました。これについてはキーイベントの関数に大量のifが連なり改善の余地ありです。

## 実装の進め方

実装にはCursor + Claude 3.7を活用し、プロンプトを通じてコードを生成しながら進めました。

まず、Askモードで開発したい機能をリストアップし、それをRulesに追加。次に、使用する開発言語、テスト、リンタを指定して環境を整えました。

ライブラリ設定時にテストライブラリも含めることで、新しい機能を追加する際にテストコードの自動生成とリンタの修正を同時に行えるようになりました。

その後は、1つずつ機能をプロンプトで指示し、動作確認しながら進める流れです。問題がなければコミット、バグがあればロールバックします。ただし、開発の後半では生成されるコードが意図した動きをしなくなり、手動での修正が増えました。

手動で一部のコードを削除・コメントアウトすると、次回のプロンプト入力時に削除したコードが復活することが多く、うまく活用しきれなかった部分もありました。

## 感想

VSCode拡張機能の開発を初めて行いましたが、テンプレートの作成やデバッグ機能がVSCode自体に搭載されているため、快適に開発することができました。拡張機能はHTMLの取り扱いが独特なのですが、そのあたりはCursorに対応してもらうことで意識せずに進められました。ちょっとした拡張機能やツール類を暇つぶしに作成する場合、Cursorに頼ることでより高度なことが短時間でできるようになったのは良い点と思いました。

また、開発するにあたりExcelやGoogleスプレッドシートを改めて見ると非常に多機能であることを再認識しました。

フィードバックや改善点があればコメントで教えていただけると嬉しいです！