OmniAICreator/Qiita-1.07M huggingface dataset:
初投稿！これから何について書いていくかと自己紹介

# はじめまして！
はじめまして。deoxyと申します。
高校の時に生物が得意科目でしてDNA(Deoxyribonucleic Acid)から名前は拝借しています。
文章を書くのは好きなほうなのですが、得意ではないので読みにくいかもしれません。

### 簡単に自己紹介をしてみます
情報系の学部で勉強をしています。ネットワークやソフトウェアの勉強が主ですね。
部活動としてプログラミングを本格的に触っています。
現在大学３年生で、１年生のころからプログラミングを始めました。
ゲームを作りたくて始めたプログラミングですが今は紆余曲折あり OS に興味があります。

初めて触ったプログラミング言語は`processing`でした。
一瞬で飽きたので文法も何も覚えていませんがPCにインストールされているので**初めて触った**といえば`processing`です。
今まで勉強をした言語は以下の通りです。
- C
- C#
- JavaScript
- Python
- Rust
- (html/css) 

Unityを用いてゲーム開発をしているのでC#はよく使っています。ググりながら書いているので「むちゃくちゃできる！！！」というわけではないですが、仕様は理解して書くように意識しています。（ただコピペで終わらせないように）
コツコツ続けていると急に応用を効かせられるようになったり理解できたりして楽しいです。

# これから何について書くか
ゲーム開発は初めて１年ちょっと程経ちます。3Dの脱出ゲーム(アイデアがないのでゲーム性はないです)とか某配管工兄弟的なゲームとかを作っています。
作りながら勉強しているので正直理解度としては低いほうです。

UnityやC#, Rustについて書いていくつもりをしています。
初心者がつまずく場所は初心者が一番わかると思うので、困った初心者さんの理解のお役に立てればと思います。
そして自分のコミュニティが広がればと思う次第です。

自分自身そこまで理解度は高くないので間違っている部分があると思います。その時は遠慮なく指摘していただけると幸いです。
数年後見返したときに初心を思い出せるような、昔はこんなだったなと懐かしめるような備忘録にして行けたらと思います。
デバッグを快適に！Configファイル設計[Unity]

### はじめに
staticでbool値を参照してデバッグと本番で時短の切り替えできたら便利ですよね？
ただいちいちファイルに戻って値を直すのは面倒...
ということでエディタから編集できるようにします。

## 実装

こちらが設定ファイル。編集してお好きなbool値を設定しましょう。
僕は
・アニメーションを飛ばす
・デバッグ関連のを表示させる
・無敵モードにする
・ゲーム速度上昇
・エラー時自動スクショ
に機能を限定しました。ゲーム制作にわかなので色々大事なことが抜けてるかもしれません...！コメント欄にてご指摘してくだされば幸いです。

```cs:GameConfig.cs
/*
 * Copyright (c) DeepNapEngine
 * https://github.com/TrueRyoB
 */
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;

namespace PoseQ.Config
{
    /// <summary>
    /// For a global reference in shifting to the debug mode!
    /// </summary>
    public class GameConfig : MonoBehaviour
    {
        public static bool SkipLongAnimations = false;
        public static bool ShowDebugInfo = false;
        public static bool GodModeEnabled = false;
        public static float PlayerSpeedMultiplier = 1.0f;
        public static bool AutoScreenshotOnError = false;
    }
}
```

そしてこちらがEditor拡張用のファイル。
```c#:GameConfigEditor.cs
/*
 * Copyright (c) DeepNapEngine
 * https://github.com/TrueRyoB
 */
using UnityEngine;
using UnityEditor;
using PoseQ.Config;

namespace PoseQ.Extensions.Editor
{
    /// <summary>
    /// To change the values of static variables on an inspector
    /// </summary>
    public class GameConfigEditor : EditorWindow
    {
        [MenuItem("Tools/Game Config Editor")]
        public static void ShowWindow()
        {
            GetWindow<GameConfigEditor>("Game Config");
        }

        private void OnGUI()
        {
            GUILayout.Label("Debug Settings", EditorStyles.boldLabel);

            GameConfig.SkipLongAnimations =
                EditorGUILayout.Toggle("Skip Long Animations", GameConfig.SkipLongAnimations);
            GameConfig.ShowDebugInfo = 
                EditorGUILayout.Toggle("Show Debug Info", GameConfig.ShowDebugInfo);
            GameConfig.GodModeEnabled =
                EditorGUILayout.Toggle("God Mode Enabled", GameConfig.GodModeEnabled);
            GameConfig.AutoScreenshotOnError =
                EditorGUILayout.Toggle("Auto Screenshot On Error", GameConfig.AutoScreenshotOnError);
            GameConfig.PlayerSpeedMultiplier =
                EditorGUILayout.FloatField("Player Speed Multiplier", GameConfig.PlayerSpeedMultiplier);

            if (GUILayout.Button("Reset to Defaults"))
            {
                GameConfig.SkipLongAnimations = false;
                GameConfig.ShowDebugInfo = false;
                GameConfig.GodModeEnabled = false;
                GameConfig.AutoScreenshotOnError = false;
                GameConfig.PlayerSpeedMultiplier = 1.0f;
            }
        }
    }
}
```

### 結果
もし何もエラーが起きなければ、上のバー(?)にてこれが出てきます。
ここから数値をいい感じに弄れるといった具合です。
![Screenshot 2025-04-26 at 11.37.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4049858/bdf640d2-1e68-4711-b74e-29825ebef32e.png)

## まとめ
自動スクショとかの実装はちょっと後回しにしてますが、リマインドしてくだされば記事更新しに戻るので遠慮なくご連絡ください。
お疲れ様でした！
dart/flutter 用の新たなコマンド実行パッケージ

dart でコマンドラインを実行するパッケージ(run)を作成しました。

https://pub.dev/packages/run

とりあえず、デモ用のソースを提示しておきます(dart-sdk-3.7.2 と dart-sdk-3.9.0-14.0.dev で動作を確認しました。また flutter windows desktop でも動作しました(flutter-sdk-3.29.3))。
残念ながら、flutter web では使えません。
***また、Windows で `var shell = Run(useUnixShell: true);` を使うには、git for windows の bash プロンプトなどで dart を実行してください。`useUnixShell: true` を指定しない場合は、Windows のコマンドプロンプトで実行できるコマンドが使えます。***

# run
[![Pub](https://img.shields.io/pub/v/run.svg)](https://pub.dartlang.org/packages/run)

Wrapper over `dart:io` [Process] API's that supports features like environment management, user switches, and more.

Useful for writing shell utility scripts in Dart, or within applications that perform system administration tasks on behalf of other users.

```dart:demo.dart
import 'dart:io';
import 'package:run/run.dart';

main() async {
  var shell = Run(useUnixShell: true);

  // コマンドを実行した際の標準出力を簡単に取得することができます。
  // `silent: true' の指定をしないと, メソッドの結果として返されるにもかかわらず、stdout が自動的に表示されます。
  String echo = await shell.run('echo hello world', silent: true);
  print(echo);

  // コマンドの終了コード(exit code)を取得することもできます。
  //
  // `returnCode: true' を使えば、プロセスの終了コードを取得できます。
  //
  // 指定しない場合は、上記のように標準出力を返しますが、終了コード 0 以外では例外が投げられます。
  int find = await shell.run$(['find', '.', '-name', '"*.dart"'], autoQuote: false, returnCode: true);
  print(find);
  if (find != 0) {
    exit(find);
  }

  // `silent: true' の指定をしていないので、pwd のコンソールへの出力は抑制されません。
  // print()文は余計ですね。
  String pwd = await shell.run('pwd');
  print('cwd: `$pwd`');

  Directory.current = './lib';
  pwd = await shell.run('pwd');
  print('cwd: `$pwd`');

  // `useUnixShell: true' を指定して Run() をコンストラクトした場合はコマンド来の中で | を使うことができます。
  String find2 = await shell.run(
    'find . -name "*.dart" | wc -l',
  );
  print(find2);

  // `useUnixShell: true' を指定して Run() をコンストラクトした場合はコマンド来の中で | を使うことができます。
  // run$() は、引数を全部クォートしてしまうので、パイプ(|)を使うためには、`autoQuote: false' の指定が必要になります。
  String find3 = await shell.run$(
    ['find', '.', '-name', '"*.dart"', '|', 'wc', '-l'],
    autoQuote: false
  );
  print(find3);
}
```
カメラの起動方法

`ScanContract` `ScanOptions`と`CameraSettings`でカメラを起動する方法の違いについてメモします。


ScanContract はActivity Result APIでコードスキャン後の処理を記述するためのContractです。ScanOptions は、そのスキャンに関する設定を決めることができます。

2つを組み合わせることで、簡単にカメラを起動してコードだけを読み取ることができることが特徴です。
・カメラ操作はすべてライブラリ側が自動で管理する
・コードを読み取ったあとは画面は自動で閉じる
・フラッシュ、ズームなど細かいカメラ設定はできない

```kotlin
val scanQrResultLauncher = registerForActivityResult(ScanContract()) { result ->
    if (result.contents != null) {
        // 読み取った後の処理
    }
}

val options = ScanOptions().apply {
    setDesiredBarcodeFormats(ScanOptions.QR_CODE)
    setPrompt("コードをスキャンしてください")
}
scanQrResultLauncher.launch(options)
```



CameraSettingsはカメラの細かい設定を直接制御できます。DecoratedBarcodeViewなどのカスタムビューと組み合わせて使います。
レイアウトにカメラビューを埋め込めてそれに対してオートフォーカス、フラッシュ制御などの細かいカスタマイズが可能です。カメラビューを自由にカスタマイズしたい場合や、読み取り後に画面遷移させたくない場合に使用します。実装の手間はその分増えます。

```xml
<com.journeyapps.barcodescanner.DecoratedBarcodeView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/barcodeView"/>
```
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    val cameraSettings = CameraSettings().apply {
        requestedCameraId = CameraSettings.CameraFacing.BACK
        isAutoFocusEnabled = true
    }

    binding.barcodeView.barcodeView.cameraSettings = cameraSettings

    val formats = listOf(BarcodeFormat.QR_CODE)
    binding.barcodeView.barcodeView.decoderFactory = DefaultDecoderFactory(formats)
}

override fun onResume() {
    super.onResume()
    binding.barcodeView.resume()
}

override fun onPause() {
    super.onPause()
    binding.barcodeView.pause()
}
```
【備忘録】mypy: 複数行にわたるimport文で#type: ignoreが効かないときの対処法

# 要点

ここに書きましょう。開き丸括弧の直後です。

```py
# 例: some_library.some_module から複数のクラスをインポートする場合
from some_library.some_module import ( # type: ignore
    ClassA,
    ClassB,
    ClassC,
    # ...
)
```

## 経緯

Pythonでコードを書いていて、途中からPylint（コード整形ツール）を導入した。
すると、下記の行で `C0301: Line too long` と怒られた。

```py
from vertexai.generative_models import GenerationConfig, ChatSession, Content, Part, ResponseValidationError, GenerativeModel # type: ignore
```

そこで、`import`文の部分を、`()`を使って複数行に書き直した。

```py
from vertexai.generative_models import (
    GenerationConfig,
    ChatSession,
    Content,
    Part,
    ResponseValidationError,
    GenerativeModel,
) # type: ignore
```

しかし、この書き方ではダメで、今度はmypy（型チェック用ライブラリ）から以下のようにお叱りを受けた。
```
Skipping analyzing "vertexai.generative_models": module is installed, but missing library stubs or py.typed marker
```

`vertexai`モジュールには型情報があまり書かれていないため、そこの型チェックをスキップするように指示する`# type: ignore`を外すというのは現実的な解決策ではなかった。

## 解決

冒頭でも書いた通り、開き丸括弧の直後に `# type: ignore` を書いたところ、Pylintの警告もmypyの警告も消え、無事に解決した。

```py
from vertexai.generative_models import ( # type: ignore
    GenerationConfig,
    ChatSession,
    Content,
    Part,
    ResponseValidationError,
    GenerativeModel,
)
```
電子ガジェット用USB5V給電ボード

# 概要
この製品は、消費電流が少ない電子ガジェットでモバイルバッテリーでは給電が停止する問題を解決するボードになります。
展示会などで5Vの電力供給を継続的供給できるのでお役にたてるはずです。

![IMG_20250426_164450.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/6168b492-da76-408c-a155-ef4a76aa30d7.jpeg)


:::note info
※電池は付属しません。
:::


- ## 商品説明
 単4電池2本で5Vの安定した電力を供給する、小型給電ボードです。
 電池が無くなるまで給電を維持します。
 充電池を使用すると過放電してしまう恐れがあるので乾電池使用をお勧めします。
 
- ## 特長
- [ ] コンパクトな電源ソリューション: 単4電池2本で5Vの給電を実現。
- [ ] 楽しさもプラス: CH552Tマイコンを搭載し、LEDを制御。視覚的な楽しみも提供します。
- [ ] 過電流保護: CH217Kを採用し、過電流からデバイスを守ります。
- [ ] 地絡による破損の心配もありません。
- [ ] 拡張性: XHコネクタを備え、別の電池を接続して給電も可能。（5V未満の電池を使用してください。）

###
- ## ハードウェアの主な仕様

###
###	5V昇圧DCDCコンバータ回路 搭載
 単4電池電圧を5Vに変換し、電子デバイスに安定した電力を供給。	

###
###	8ビットUSBマイコン CH552T 搭載
 USB Type-C接続に対応したマイコンを搭載。
 LED制御機能で視覚的な楽しさを追加。
 プログラム書き込も可能です。
###
###	USBスイッチIC CH217K採用
 USB給電部分に過電流保護機能を搭載。地絡や過電流からガジェットを守る安全設計。

###
- ## ブロック図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/09f07aad-8bfe-4857-883e-e47bd7b9889c.png)

:::note info
このボードは、電池電圧を5Vに昇圧する機能を備えています。
また、CH217Kを介することで、電子ガジェットを過電流や加熱から保護します。
さらに、CH552Tマイコンにより5V電圧インジケーターLEDが点灯する仕組みを採用しています。
:::



###
- ## 回路図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/1e898772-8ed0-45c5-8248-737dc617ba39.png)

:::note info
電源供給を単4電池または外部接続を切り替えをスイッチで選択します。
昇圧回路　電池電圧を5Vに昇圧します。
:::


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/55d9ff66-d48d-4b8c-863f-f418672083d5.png)

:::note info
CH552TとUSBコネクタ。LED制御のみなので精度は不要ですので24MHzは非搭載になります。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782127/486c0f42-945f-4d74-afdb-aff464bb74ad.png)

:::note info
- CH217Kは過電流保護および加熱保護機能を備えたICで、ガジェットを保護します。
- 過電流発生および加熱時: 赤色LEDが点灯し、給電が停止します。
- 電源インジケーターLED: 昇圧回路が動作すると、マイコンによってLEDが点灯制御されます。
- USB出力: TYPE-Aコネクタから5Vを給電し、コネクタ近くのVOUT-GND間で電圧を確認可能です。
:::

###
- ## 最後に。
このボードは、5V電源を弱電流ガジェットに供給する機能に特化していますが、ユニークであまり見かけない貴重なガジェットです。ぜひ、その特性を活用してみてください！
Lambda向け負荷テストのアプローチ


## 準備段階

1. **テスト環境の分離**
   - 本番環境とは別のAWSアカウントまたはリージョンでテスト環境を構築
   - 本番DBへの影響を避けるためにテスト用DBを用意

2. **テストシナリオ設計**
   - 実際のユーザーパターンを反映したシナリオ作成
   - APIエンドポイントごとの予想最大負荷の定義
   - ユーザー数増加のステップ（例：10→100→1000ユーザー）

## ツール選択

1. **AWS専用ツール**
   - **AWS Lambda Power Tuning**: 最適なメモリ設定を見つける
   - **AWS X-Ray**: トレース分析に活用

2. **負荷テストツール**
   - **Artillery**: JavaScript/YAMLベースでLambda連携が容易
   - **Locust**: Pythonベースで柔軟なテストシナリオ
   - **JMeter**: 詳細なテスト設定が可能

## テスト実施のステップ

1. **段階的負荷増加**
   - 少ない並列リクエストから開始し徐々に増加
   - リクエスト数/秒を段階的に上げていく

2. **監視するメトリクス**
   - Lambda実行時間とメモリ使用量
   - コールドスタート頻度
   - エラー率と429エラー(スロットリング)
   - APIゲートウェイのレイテンシ
   - DB接続プールの状態

3. **ボトルネック特定**
   - APIゲートウェイのスロットリング
   - Lambdaの同時実行数制限
   - DB接続プール枯渇
   - 外部API依存の遅延

## 最適化ポイント

1. **Lambda設定最適化**
   - メモリ割り当て調整
   - タイムアウト設定の見直し
   - プロビジョンドコンカレンシーの検討

2. **コネクションプール管理**
   - DBコネクションプールの適切なサイジング
   - コネクション再利用の実装

3. **キャッシュ戦略**
   - 頻繁にアクセスされるデータのキャッシュ導入

## コスト管理

- 負荷テスト中のコスト監視（予想外の請求を防ぐ）
- 最適なLambda設定（メモリと実行時間のバランス）の検証

このアプローチで段階的に負荷をテストし、システムの制限を把握した上で最適化を進めることができます。
RubyMineでrspecを実行する際にデフォルトの環境変数を設定する方法


# ✅ やりたいこと

RubyMineかｒrspecを実行する際に、あらかじめ環境変数が設定されてる状態にしておきたい。

![rubymine.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/ccaace02-c4fc-4dd1-b0bf-6a45aca0e24b.png)


---

# ✅ 設定方法

１．ツールバーから「実行 > 構成の編集」を選択する
![rubymine-rspec-env-01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/5e485f36-f70e-4653-b6d1-b2b892715bfa.png)

２．「構成テンプレートの編集」を選択する
![rubymine-rspec-env-02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/3247165c-ab16-46fa-b459-f07157ad90f8.png)

３．「環境変数」に、rspecを実行する際に設定しておきたい環境変数を入力する
![rubymine-rspec-env-03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/4dbdb057-fcd2-488b-9b51-7302af4a1398.png)

４．rspecを実行すると、環境変数が設定されてる状態で実行される
![rubymine-rspec-env-04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/b5d07189-2dbe-4eea-a4fa-47d90ca32268.png)

---

# ✅ 特定のspecのみに環境変数を設定したい<br>✅ 設定した環境変数を変更したい

「実行構成の変更」からrspec実行時に設定される環境変数を変更することができる。
![rubymine-rspec-env-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/c5095ce8-8bff-4db4-8568-ec30a8c570a6.png)

![rubymine-rspec-env-06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/141934/8cf1b8e0-8730-4880-923f-0b4ee8f2590c.png)
【インフラ】新卒１年間の振り返り

## あらすじ

:::note info
掲題の通り、振り返りの記事になります。
個人の一意見として、解釈いただけますと幸いです。
:::

私は新卒で証券ASP企業のインフラエンジニアとして入社しました。

入社後は、社内と商用のインフラ環境に触る機会があり、
AWS認定資格なども取ることができました。
[AWS Solution Architect - Professional](https://aws.amazon.com/jp/certification/certified-solutions-architect-professional/)

その中で得た学びや反省などを、備忘録として記事にしました。

## そもそも何故この業界に？

私は大学生の時、リモート講義ばかりで退屈しており、
趣味でプログラミングを触るなどしていました。

そこで、Web技術への熱中や、もくもく会での交流などを通じて、
エンジニアという職業に強い魅力を感じるようになりました。

大学３年時には、Webアプリを作って就活をし、
ご縁があった現在の会社に入社しました。
[当時作成したWebアプリの記事](https://qiita.com/okigaruni_/items/ab0b353091c77539c425)

インフラは希望配属です。
理由はサービスの縁の下の力持ちとして、
利用者を支えることを生業にしたいと考えたからです。

## １年経っての感想は？

総括として、

「社会人マナーや、インフラ技術（オンプレ,AWS）など、
多方面を勉強させていただき、ありがとうございます！」

に尽きます。

私は社内の各種SaaS管理, 備品管理, 商用環境(AWS)の運用基盤システム改修
など幅広い業務を経験させていただきました。

現在では、情報システム管理者や、社内のERPシステム導入のプロジェクトリーダーを勤めさせていただき、期待と責任を感じながら仕事をしています。

その結果、業務を通じて社会人の必須スキルを身につけている実感があり、職場の方々には日々感謝しています。

※ 執筆途中、H×H のネテロ会長が思い浮かんだので、リンク貼っちゃいます。
[感謝するぜ お前と出会えた これまでの全てに!!!](https://dic.nicovideo.jp/a/%E6%84%9F%E8%AC%9D%E3%81%99%E3%82%8B%E3%81%9C%20%E3%81%8A%E5%89%8D%E3%81%A8%E5%87%BA%E4%BC%9A%E3%81%88%E3%81%9F%20%E3%81%93%E3%82%8C%E3%81%BE%E3%81%A7%E3%81%AE%E5%85%A8%E3%81%A6%E3%81%AB%21%21%21)

## 仕事の目的について
私はこの機会で、仕事の目的を言語化してみました。
それは、「クラウド技術を通じて、企業やサービスの根幹を安定化させ、システム利用者の毎日を幸せにする」ことです。

私は 「クラウド > オンプレ」の考えを持っており、
オンプレの「見えない運用コスト」や「潜在的なリスク」がクラウドで解消されると考えております。

見えない運用コスト）
・ハードウェアの不具合・故障対応
・機器がベンダー依存のため、ナレッジ共有が困難
・データセンター保守委託でも、コンフィグが提供されない場合がある

潜在的なリスク）
・コンフィグの手動バックアップ漏れ
・ハードウェアの経年劣化による不具合（未知数）
・技術のレガシー化による俗人化（有識者の減少）

## 最後に
私は技術的な食わず嫌いはないですが、
願わくは、クラウドを主戦場にしていきたいと思う今日この頃でした。

最後まで目を通していただき、ありがとうございます。
少しでも、皆様の参考になりましたら幸いです。
【React Hook Form】二つのフォームの値を連動させる方法


`React Hook Form` で、二つのフォームを連動させたい！
ついでに、その値も表示したいなぁ～～

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/1b648988-db4b-4536-961b-ada17db13cf6.png)


## とりあえず枠組みを用意

`React` でフォームを用意したい場合、`React Hook Form` がいいみたい。
`<input>` と `useState()` をいい感じに管理してくれる。

https://www.react-hook-form.com/

これを使って、二つのフォームを連動させてみる。

```tsx:page.tsx
'use client'

import { useForm } from 'react-hook-form'

export default function MyApp() {
  const form = useForm({
    defaultValues: {
      name: '初期値',
    },
  })
  
  const nameValue = form.watch('name')

  return (
    <form>
      <div className="p-4 flex flex-col gap-2">
        <div>
          今の値：
          {nameValue}
        </div>
        <input
          className="input"
          {...form.register('name')}
        />
        <input
          className="input"
          {...form.register('name')}
        />
      </div>
    </form>
  )
}
```

フォームに `React Hook Form` を紐づけるには `register()` メソッドを付与する。
このメソッドは、以下の4つの要素を `<input>` に付与する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/21e00ad5-d0f2-4bda-bd9e-5678fe652728.png)

また、フォームの値を使用したい場合は `watch()` メソッドを使用する。
これを使わないと再レンダリングが動かないので注意。

でもこのやり方だと、後のフォームしかうまく動かない。
おそらく二つの EventListener か Observer が競合しているのだろう。
フォームA → フォームB の順番で処理されてしまって、React 側とフォーム側の連動が壊れてしまっている。

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/9e8aa95c-2dd4-4cf4-9431-f43027156640.gif)




## 試行錯誤の末

```tsx:page.tsx
'use client'

import { useForm } from 'react-hook-form'

export default function MyApp() {
  const form = useForm({
    defaultValues: {
      name: '初期値',
    },
  })

  const nameValue = form.watch('name')

  return (
    <form>
      <div className="p-4 flex flex-col gap-2">
        <div>
          今の値：
          {nameValue}
        </div>
        <input
          className="input"
          {...form.register('name', {
            onChange: (e) => {
              form.setValue('name', e.target.value)
            },
          })}
        />
        <input
          className="input"
          {...form.register('name', {
            onChange: (e) => {
              form.setValue('name', e.target.value)
            },
          })}
        />
      </div>
    </form>
  )
}
```

`register()` の引数で `onChange()` として、フォームの値を再度記録しているのがポイント。
そうすることで、値を再度強制的に同期して解決！
（これが最適解かはわからない。。。）

![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3833190/46db42d3-dd52-4bb8-a097-a1149d9f8559.gif)



## おわりに

`onChange()` はコードを読むとバリデーションとか色々なことをやっているみたい。
これってバグなのかな...仕様なのかな...。
ちょっと全コードは追いきれなかった...。

https://github.com/react-hook-form/react-hook-form/blob/9ffe5cbe3b490ab89633929719edde662f724a7d/src/logic/createFormControl.ts#L726

こういう体験をすると `Vue` がこの辺の処理をいかに隠匿しているかがわかる。
それがいいか悪いかはべつとしｔ
go get と go install

## 比較表

| 比較項目 | `go get` | `go install` |
|:---|:---|:---|
| 主な用途 | パッケージのダウンロード＋`go.mod`の更新 | 実行ファイルのビルド＆インストール |
| `go.mod`に影響する？ | ✅ する（依存管理） | ❌ しない（ビルド＆インストールのみ） |
| コンパイルされる？ | 必ずではない（主にパッケージ取得） | ✅ バイナリにビルドされる |
| 主な使い方 | - プロジェクトにパッケージを追加 <br> - バージョン指定・更新 | - CLIツールをインストール <br> - 他人のアプリをインストール |
| 適しているシーン | プロジェクト開発中の依存追加 | CLIツールやアプリケーションのインストール |

## 具体例

### `go get` を使う（依存管理）

```bash
go get github.com/spf13/cobra
```

- パッケージをダウンロード＆インストール
- `go.mod`に依存を追加
- `go.sum`にチェックサム情報を追加
- 以後、プロジェクトのビルド・実行時に利用可能

### `go install` を使う（ツールインストール）

```bash
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
```

- ソースコードをダウンロードしてビルド
- バイナリ（実行ファイル）を生成
- `$GOPATH/bin` または `$HOME/go/bin` にインストール
- `go.mod` や `go.sum` は変更されない

## 技術メモ

- `go get` は基本的に**プロジェクト内部の依存管理用**コマンド
- `go install` は**開発環境向けツールインストール用**コマンド

> Go 1.17以降、**CLIツールのインストールは `go install` を推奨**。  
> `go get`によるインストールは非推奨になった。

## まとめ

|  | `go get` | `go install` |
|:---|:---|:---|
| パッケージ管理？ | ✅ | ❌ |
| ツールインストール？ | ❌（1.17以降非推奨） | ✅ |
| 主な目的 | プロジェクト依存を追加 | バイナリをローカルにインストール |
| `go.mod`に影響？ | ✅ | ❌ |

## 参考リンク

- [https://go.dev/doc/go-get-install-deprecation](https://go.dev/doc/go-get-install-deprecation)
Cinemachine 一部座標を固定して他は追従させる[Unity]

### 前置き
既存のAPIに機能がない時に、１から自分で作るのではなく、少し機能性を持たせることで想定外のリスクを避けるのたまにあると思います。この記事はそれです。

## 前提
1) 2.5Dゲームを開発している
2) x座標は対象gameObjectを追従させたい
3) y座標とz座標は固定したい
4) Unity6を利用している

## 対処法

Cinemachine Cameraを選択する
→Position ControlではFollow > Lock To Target On Assignを選択
→以下のコード入りのファイルを作成する
→LockAndYAndZAxisで検索してそのcomponentを貼り付ける
→終わり！

```c#:LockYAndZAxis.cs
/*
 * Copyright (c) DeepNapEngine
 * https://github.com/TrueRyoB
 */
using UnityEngine;
using Unity.Cinemachine;

namespace PoseQ.Extensions.RhyRhyDaDa
{
    [ExecuteAlways]
    [SaveDuringPlay]
    [AddComponentMenu("Cinemachine/Custom/LockYAndZAxis")]
    public class LockYAndZAxis : CinemachineExtension
    {
        [Header("固定したいYとZの値")]
        public float fixedY = 1f;
        public float fixedZ = 10f;
    
        protected override void PostPipelineStageCallback(
            CinemachineVirtualCameraBase vcam,
            CinemachineCore.Stage stage,
            ref CameraState state,
            float deltaTime)
        {
            if (stage == CinemachineCore.Stage.Body)
            {
                Vector3 pos = state.RawPosition;
                pos.y = fixedY;
                pos.z = fixedZ;
                state.RawPosition = pos;
            }
        }
    }
}
```

## まとめ
将来的に導入予定のImpulse Listnerとの衝突が怖いなと思っています。
またFPSがかなり落ちたのも懸念点です。
飽くまで座標追跡と振動のみに機能性を絞るなら、コード設計n自作もあながち悪くないのではと考え直しています。
【Google翻訳】URLでWebサイトを翻訳する方法

以下のURLを使用するとGoogle翻訳でWebサイトを日本語に翻訳できます。

```text
https://translate.google.com/translate?hl=ja&sl=auto&tl=ja&u=翻訳したいサイトのURL
```

`https://translate.google.com/translate?hl=ja&sl=auto&tl=ja&u=https://react.dev/`とすると`https://react.dev/`がGoogle翻訳で日本語に翻訳された状態で表示されます。

https://translate.google.com/translate?hl=ja&sl=auto&tl=ja&u=https://react.dev/

![screen-shot-253.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/4ccd6ff7-1625-4058-9d44-6f410b7f1241.png)
Python のデコレータの実装例

Python のデコレータの実装方法のメモ。

# デコレータの定義
デコレータは以下のように定義する。

```python
def dec(func):
    def wrapper(*args, **kwargs):
        func(*args, **kwargs)

    return wrapper
```

デコレータの使用例
```python
@dec
def test1():
  print("test1()")
  return 0
```

# デコレータ例
以下はデコレータの実装例。
@log はメソッドが実行された時刻を表示する。
@args_ret はメソッドの引数とレスポンスを表示する。
```python
import time


def log(func):
    def wrapper(*args, **kwargs):
        name = func.__name__
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {name} begin")
        res = func(*args, **kwargs)
        print(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] {name} end")

    return wrapper


def args_ret(func):
    def wrapper(*args, **kwargs):
        name = func.__name__
        print(f"{name} {str(args)}, {str(kwargs)}")
        res = func(args, kwargs)
        print(f"{name} ret:  {str(res)}")

    return wrapper
```

プログラム例
```python
from decorator1 import log, args_ret


@log
def test1():
    print('test1()')
    time.sleep(1.0)
    obj = 'abc'
    return obj


@args_ret
def test2(a, b, arg1=None, arg2=None):
    print('test2()')
    obj = {'a': a, 'b': b, 'arg1': arg1, 'arg2': arg2}
    return obj


test1()
test2(1, 2, arg1='abc', arg2='def')
```

実行結果
```
[2025-04-26 23:35:09] test1 begin
test1()
[2025-04-26 23:35:10] test1 end
test2 (1, 2), {'arg1': 'abc', 'arg2': 'def'}
test2()
test2 ret:  {'a': (1, 2), 'b': {'arg1': 'abc', 'arg2': 'def'}, 'arg1': None, 'arg2': None}
```
Disney+ Subtitles Downloaderが動かない問題を修正して使えるようにした

## はじめに

Disney+上の字幕をダウンロードするために「Disney+ Subtitles Downloader」というTampermonkeyスクリプトを使おうとしましたが、  
最近のディズニープラスの仕様変更により、そのままでは動作しなくなっていました。

本記事では、スクリプトを自力で修正して正常に動かせるようにした方法をまとめます。

---

## 問題点

スクリプトを導入しても、

- 字幕横にダウンロードボタンが出ない
- ボタンは出ても、押してもファイルがダウンロードされない

という問題が発生しました。

ブラウザの開発者ツール（Console）を確認すると、  
以下のエラーが出ていました。

```bash
Uncaught TypeError: Cannot read properties of undefined (reading 'innerHTML')
```

原因は、

- ディズニープラス側のHTML構造が変わったため
- スクリプト内で「存在しないノード」から```innerHTML```を読もうとしてエラーになっていた

というものでした。

---

## 修正内容

主に以下の2ヶ所を修正しました。

---

### ① イベント登録対象の取得方法を変更

Before（元のコード）
```javascript
// 「親要素（字幕リスト）」の全部の子ノード（子divや空白も含む）を取ってきている
// 空白を拾って、それを対象にonclick判別しようとしてエラーになる可能性有
picker[0].childNodes.forEach(function(child) {
    var element = child.childNodes[0];
    if (child.onclick == null) {
        child.onclick = selectsub;
    }
});
```

After（修正後のコード）
```javascript
// ターゲットを「ラベルだけ」に絞るように変更
var labels = picker[0].querySelectorAll('label.picker-item');
labels.forEach(function(label) {
    if (label.parentElement && label.parentElement.onclick == null) {
        label.parentElement.onclick = selectsub;
    }
});
```
**解説**
```childNodes```を使うと、空白ノード（改行やスペース）まで拾ってしまうリスクがありました。
そのため、```querySelectorAll('label.picker-item')```を使い、必要なラベル要素だけを直接取得するように変更しました。

---

### ② 字幕言語の取得方法を変更

Before（元のコード）
```javascript
var lang = this.childNodes[0].childNodes[1].innerHTML;
```

After（修正後のコード）
```javascript
var label = this.querySelector('label.picker-item');
var lang = label ? label.innerText : "";
```
**解説**
元のコードでは、固定的な```childNodes```の階層に依存して字幕名を取得していましたが、
ページ構造の変更により対象が存在しなくなっていました。

```querySelector```を使い、ラベル要素を安全に取得し、そのinnerTextを読むように変更しました。

---

## 結果

上記の2点を修正したところ、

- 字幕横にダウンロードボタンが正常に表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/345423/1ee90890-ba6a-491c-a8ad-b67c7ab91c4c.png)
- ボタンを押すと、字幕ファイル（SRT形式）が正しくダウンロードされる

ようになりました！




---

## まとめ

今回、ブラウザの開発者ツール（Console）を使ってエラーを確認し、
実際にHTML構造を目で見ながらコードを修正することで、ディズニープラスの仕様変更に対応できました。

今回学んだポイントは以下の通りです。

- childNodesは空白ノードも拾うため、注意が必要
- 実際のHTML構造に合わせて、querySelectorで確実にターゲットを指定するのが安全
- デバッグは「中身を可視化して、事実ベースで判断する」のが大事

同じようにDisney+ Subtitles Downloaderが動かなくて困っている方の参考になれば嬉しいです！
【Rust】よく考えたらこれコンパイル通るのおかしくない？シリーズ

Rustの参照と所有権難しいですよね。今回はRustの「暗黙的な参照変換」について解説します。

下記のコードを見てください。よく考えると一貫性がないように見えませんか？

```rust
struct Foo { name: String }

impl Foo {
    fn bar(&self) {
        println!("{}", self.name);
    }
}

fn baz(r: &String) {
    println!("{}", r);
}

fn main() {
    let foo: Foo = Foo { name: "some_string".to_string() };
    let foo_ref: &Foo = &foo;
    
    // (1) YES - コンパイル成功
    foo.bar();
    
    // (2) NO - コンパイルエラー
    baz(foo_ref.name);
    
    // (3) NO - コンパイルエラー
    let name = foo_ref.name;
    println!("{}", name);
    
    // (4) YES - コンパイル成功
    println!("{}", foo_ref.name);
    
    // (5) YES - コンパイル成功
    if "hello".to_string() < foo_ref.name {
        println!("x")
    } else {
        println!("y")
    }
}
```

## ドット演算子の自動参照・自動逆参照

Rustにおいて、ドット演算子（`.`）は**自動参照**と**自動逆参照**という機能を持っています。この機能は **左側** のオペランドに対してのみ働きます。

ケース(1)の`foo.bar()`では、`foo`は`Foo`型ですが、`bar`メソッドは`&self`（`Foo`への参照）を期待しています。ドット演算子の**自動参照機能**により、`foo`は自動的に`&foo`に変換されます。

普段意識しないかもしれませんが、**ドット演算子は左側にある値を必要に応じて参照したり、逆参照したり**しているんですね。


## 参照と値の取得

2番目と3番目の例でコンパイルエラーが発生する理由はすぐにわかると思います。`foo_ref.name`が`String`型の値を返すからですね。

```rust
// (2) NO - コンパイルエラー
baz(foo_ref.name);
```

**しかし、よく考えてみましょう。** 先程の自動参照機能で暗黙的に変換してくれそうな気もしませんか？

自動変換はドットの**右側の値には適用されない**のです。


この場合、`baz`関数は`&String`型の参照を期待しているので、明示的に参照を取得する必要があります：

```rust
// これなら動作します
baz(&foo_ref.name);
```

同様に、3番目の例も`name`変数に`String`型の値を代入しようとしていますが、実際には参照を通して値をコピーしようとしているため、コンパイルエラーになります。

## マクロの特殊な振る舞い

ここで4番目の例をみて **「おや？！」** と思いませんか？

(3)の`println!("{}", name);`はコンパイルできないのになぜ`println!("{}", foo_ref.name);`は通るんでしょうか？

これが成功するのは、**`println!`マクロの特殊な振る舞い**によるものです。

`println!`はマクロであり、通常の関数とは異なる振る舞いをします。`println!`マクロにはフォーマットの過程で必要に応じて参照演算子を追加する処理が備わっているため、コンパイルエラーが発生しません。

## 比較演算子の動作

5番目の例が成功する理由も、**比較演算子の特殊な内部実装**にあります。

```rust
// (5) YES - コンパイル成功
if "hello".to_string() < foo_ref.name {
    println!("x")
} else {
    println!("y")
}
```

Rustでは比較演算子を使う際に、内部的に**オペランドに対して自動的に参照が取られる**仕組みになっています。これにより、`String`型同士の比較として処理され、コンパイルが成功します。

## まとめ

1. ドット演算子（`.`）は左側の値に対して自動的に参照・逆参照を行いますが、右側の値（フィールドやメソッドの結果）には適用されません
2. `println!`などのマクロは特殊な振る舞いをすることがあり、一般的な関数呼び出しとは異なる参照処理を行います
3. 比較演算子などの演算子も、内部的に特別な参照処理を行います

以上、知らなくても困らないであろうRustの小ネタでした

## 参考資料

- [The Rust Programming Language - Deref特性による参照外し型強制](https://doc.rust-lang.org/book/ch15-02-deref.html)
- [Easy Rust - 第29章: メソッド呼び出しと自動参照・自動逆参照](https://dhghomon.github.io/easy_rust/Chapter_29.html)
ABC400Eを解いた【エラトステネスの篩、二分探索】


筆者はレート800前後の茶～緑コーダ

ABC当日にACできなかったE問題を解いていく
    
https://atcoder.jp/contests/abc400/tasks/abc400_e

# 実装コード

400 numberの条件は平方数であることがポイントらしい。

$10^6$ 以下の素数を適当にエラトステネスの篩で出して、そこから素因数が2つの整数のみを出す。
あとはほしい数を二分探索で探せばOK

```python:main.py
from bisect import bisect_left, bisect_right, insort_left, insort_right
from collections import defaultdict, Counter, deque
from functools import reduce, lru_cache
from itertools import product, accumulate, groupby, combinations
import sys
import os
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
IS_LOCAL = int(os.getenv("ATCODER", "0"))==0
err = (lambda *args, **kwargs: print(*args, **kwargs, file=sys.stderr)) if IS_LOCAL else (lambda *args, **kwargs: None)

def sieve(n):
    is_prime = [True for _ in range(n+1)]
    is_prime[0] = False

    for i in range(2, n+1):
        if is_prime[i-1]:
            j = 2 * i
            while j <= n:
                is_prime[j-1] = False
                j += i
    table = [ i for i in range(1, n+1) if is_prime[i-1]]
    return is_prime, table


def main():
    Q = rI()
    A = [rI() for _ in range(Q)]
    M = 10**6+1
    _, P = sieve(M)
    d = defaultdict(lambda: 0)
    for p in P:
        q = p
        while q <= M:
            d[q] += 1
            q += p
    D = [x**2 for x,c in d.items() if c == 2]
    D.sort()
    for a in A:
        i = bisect_left(D,a+1)
        print(D[i-1])
        

if __name__ == '__main__':
    main()

```

# まとめ

平方数であるという特徴をだして
Nの最大値を減らすという発想は参考になった。
指定文字列削除

文字列から、指定した方向にある削除指定文字列を削除する
~~~
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
' 指定文字列削除
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Public Function F_String_ReturnDelete( _
        ByVal aTarget As String, _
        ByVal aDelete As String, ByVal aDelSpec As E_STRING_SPEC) As String
    Dim wkRtn As String: wkRtn = aTarget
    Dim wkLen As Long
    Dim wkDelLen As Long
    
    '文字列と削除文字がある場合
    If aTarget <> "" And aDelete <> "" Then
        '中間位置削除の場合
        If M_Common.F_CheckBitOn(aDelSpec, E_STRING_SPEC_POS_MID) = True Then
            wkRtn = Replace(aTarget, aDelete, "")
        Else
            wkLen = Len(aTarget)
            wkDelLen = Len(aDelete)
            
            '開始位置削除指定の場合
            If M_Common.F_CheckBitOn(aDelSpec, E_STRING_SPEC_POS_START) = True Then
                '開始位置に削除文字がある間ループ
                Do While StrComp(Left(wkRtn, wkDelLen), aDelete, vbBinaryCompare) = 0
                    wkLen = wkLen - wkDelLen
                    wkRtn = Right(wkRtn, wkLen)
                Loop
            End If
            
            '終了位置削除指定の場合
            If M_Common.F_CheckBitOn(aDelSpec, E_STRING_SPEC_POS_END) = True Then
                '終了位置に削除文字がある間ループ
                Do While StrComp(Right(wkRtn, wkDelLen), aDelete, vbBinaryCompare) = 0
                    wkLen = wkLen - wkDelLen
                    wkRtn = Left(wkRtn, wkLen)
                Loop
            End If
        End If
    End If
    
    F_String_ReturnDelete = wkRtn
End Function
~~~
📚 今日の学習まとめ 2025年4月26日

# 📚 今日の学習まとめ
## 🛠 CRUD（クラッド）
アプリケーションのデータ取り扱いに関して、基本的な処理の頭文字を並べたものです。
この4つを組み合わせて、さまざまな機能を作ります！
```
頭文字	処理	内容
C	Create	生成
R	Read	読み取り
U	Update	更新
D	Delete	削除
```
## 🧩 7つのアクション（Rails標準）
RailsではCRUDを実現するために、7つのアクションが慣習として用意されています。
```
アクション名	内容
index	一覧表示
show	詳細表示
new	生成画面の表示
create	保存（データ生成）
edit	編集画面の表示
update	更新処理
destroy	削除処理
```

## 🔗 resources（リソーシーズ）メソッド
resourcesを使うと、7つのアクションに対応するルーティングが自動生成されます。

✅ 自動生成されるルーティング一覧
```
GET     /tweets           tweets#index
POST    /tweets           tweets#create
GET     /tweets/new       tweets#new
GET     /tweets/:id/edit  tweets#edit
GET     /tweets/:id       tweets#show
PATCH   /tweets/:id       tweets#update
PUT     /tweets/:id       tweets#update
DELETE  /tweets/:id       tweets#destroy
```

## ✂️ onlyオプションで絞る
必要なアクションだけルーティングしたいときは、onlyをつけます。
```
resources :tweets, only: [:index, :show]
→ indexとshowのみ生成！
```
## 🏗 コントローラーとビュー作成の流れ
```
コマンドでコントローラー作成
↓
コントローラーにindexアクションを定義
↓
ビュー（index.html.erb）を作成して表示
```
## 🖼 レイアウトテンプレートとは？
アプリケーション全体で共通するパーツ（ヘッダー、フッターなど）をまとめたファイル。
Railsでは、次の場所にある
```
app/views/layouts/application.html.erb
ここに共通HTMLを書きます。
```
## 🔄 yield（イールド）とは？
レイアウトテンプレート内で、アクションごとのビューを展開するためのメソッドです。
```
<body>
  <%= yield %>
</body>
例えば、index.html.erbやnew.html.erbの内容がここに差し込まれます。
```

## 🎨 stylesheet_link_tag（スタイルシートリンクタグ）
CSSファイルを読み込むためのヘルパーメソッド。
```
<%= stylesheet_link_tag "application", media: "all" %>
CSSファイルはここに置きます：↓

app/assets/stylesheets/
```
## 📄 application.css（アプリケーションCSS）
Rails初期からある、CSS読み込みをまとめるマニフェストファイルです。
すべてのCSSファイルをここ経由で読み込ませます。

## 🌳 require_tree（リクワイア ツリー）
application.css内で、ディレクトリ以下のCSSを全部読み込むための指示です。
```
/*
 *= require_tree .
 */
.は「このディレクトリ直下」を意味します！
```
Excelのシート名の一括取得

# はじめに
Excelで
・シート名の一覧が欲しい
・一覧からシートを作りたい
と思ったことはありませんか。

# シート名の一覧を取得
VBEのイミディエイトウィンドウで
```vb
For Each sheet In ThisWorkbook.Sheets: debug.print sheet.name: Next
```
を実行するとシート名の一覧が出力されます。

VBEを開いたり、vbaを実行する手間がかかりますので、アドインにしてみます。
出力先をどうするか悩みましたが、クリップボードにしました。
```vb:シート名一覧をクリップボードにコピー
Sub シート名コピー()
    Dim clipboard As Object
    Dim sheet As Worksheet
    Dim sheetName As String
    
    'MSForms.DataObjectを生成
    Set clipboard = CreateObject("new:{1C3B4210-F441-11CE-B9EA-00AA006B1A69}")
    sheetName = ""

    For Each sheet In ThisWorkbook.Sheets
        'シート名を取得(末尾に改行を入れる)
        sheetName = sheetName & sheet.Name & vbCrLf
    Next i
    
    ' コピーするテキストを設定
    clipboard.SetText sheetName
    
    ' クリップボードにコピー
    clipboard.PutInClipboard
    
    'MSForms.DataObjectを破棄
    Set clipboard = Nothing
End Sub
```

# 一覧からシートを作成
```vb:選択範囲からシートを生成
Sub シート生成()
    Dim addSheetList As Range
    Dim i As Integer
    Dim j As Integer
    Dim ws As Worksheet
    Dim flag As Boolean
    
    Set addSheetList = Selection
    
    For i = 1 To addSheetList.Rows.Count
        For j = 1 To addSheetList.Columns.Count
            If addSheetList.Cells(i, j).Value <> "" Then
                '同名のシートがないかチェック
                flag = False
                For Each ws In Worksheets
                    If ws.Name = addSheetList.Cells(i, j).Value Then
                        flag = True
                        Exit For
                    End If
                Next ws
                
                If flag = False Then
                    '同名のシートがない場合はシートを追加
                    Worksheets.Add After:=Sheets(Worksheets.Count)
                    'テンプレートシートをコピーする場合
                    'Sheets("テンプレート").Copy After:=Sheets(Worksheets.Count)
                    
                    ActiveSheet.Name = addSheetList.Cells(i, j).Value
                End If
            End If
        Next j
    Next i
    
    Set addSheetList = Nothing
End Sub
```

# おわりに
ちょっとした作業でも自動化すると意外に時間の短縮に繋がります。
VBAはOfficeさえ入っていれば直ぐに使えるので、ちょっとしたものを作るのには最適だと思います。
JavaScript勉強ログ if文について(基本の書き方)

if文の基本の書き方について学習したのでそちらをまとめます。

```JavaScript
if (条件式) {
 条件式がtrueになったときに実行される処理
}
```
if文の{}内には、()の条件式がtrueになるときに実行される処理を書きます。

以下のように()の中の条件式がtrueとなる場合は{}内の処理が実行されます。

```JavaScript
if (1 + 1 === 2) {
  console.log("正しい計算")
}
```

コンソールには「正しい計算」と表示されます。

条件式内が正しいtrueの場合、正しくないfalseの場合で処理を分けたいとき、以下のように書きます。

```JavaScript
let random = Math.random();

if (random < 0.5) {
  console.log("数字は0.5より小さい");
}
else {
  console.log("数字は0.5以上");
}
console.log(random);
```

Math.randomで0~1の値がランダムで生成され、その値が0.5より小さい場合はコンソールに「数字は0.5より小さい」と表示され、0.5以上の場合は「数字は0.5以上」と表示されます。

条件をより細かく分けることも可能です。その場合は条件式にelse if ()を使います。
上から順に条件がチェックされていきます。
どの場合にも当てはまらないときにはelseの中の処理が実行されます。

例えば以下のように年齢によって、料金が変わる場合、0~5歳未満が料金無料、5~10歳未満がこども料金で1000円、10~65歳未満が大人料金で2000円、65歳以上の場合はシニア料金で1500円の場合、以下のように条件を分けるとそれぞれの場合について、コンソールにテキストが表示されます。

```JavaScript
const age = 30;

if (age < 5) {
  console.log("料金は無料です");
}
else if (age < 10) {
  console.log("こども料金なので1000円になります");
}
else if (age < 65) {
  console.log("大人料金なので2000円になります");
}
else {
  console.log("シニア料金なので1500円となります");
}
```

コンソールには0~5歳未満「料金は無料です」、5~10歳未満「こども料金なので1000円になります」、10~65歳未満「大人料金なので2000円になります」、65歳以上「シニア料金なので1500円となります」と表示されます。
VitePressをMCPサーバー化するVite Pluginを作りました

## 概要
### マークダウンで書いたドキュメントの検索MCPサーバーを簡単に構築できるようになりました！

https://github.com/Hal-Spidernight/vite-plugin-vitepress-mcp

## 背景
AIエージェントからプロダクトのドキュメントへアクセスしやすいように調整するため、MCPサーバーを導入することを検討していました。
ドキュメントはなるべくマークダウンで書くようにしていたこともあり、VitePressをよく使っていました。
VitePressにはminiSearchを利用した検索機能が搭載されており、全文検索でドキュメントを探すことが可能でした。
こちらの機能をMCPサーバーに提供することはできないかと思い、このプラグインを作成しました。

## VitePressとは？

VitePressはマークダウンで書かれたドキュメントをお手軽にリッチドキュメントに変換してくれるライブラリです。
様々な便利なオプションが提供されており、導入しているOSSは多数あります。

https://vitepress.dev/guide/what-is-vitepress

### 導入している有名なOSS

https://ja.vite.dev/

https://ja.vuejs.org/

https://rolldown.rs/


## 使い方

1. VitePressをセットアップ

https://vitepress.dev/guide/getting-started

2. `vite-plugin-vitepress-mcp` をインストール

```sh
pnpm add vite-plugin-vitepress-mcp
```

3. セットアップで作成された `.vitepress/config.<ts|mts>` に以下設定を追加

```typescript
//.vitepress/config.mts

import { defineConfig } from "vitepress";
import { MCPPlugin } from "vite-plugin-vitepress-mcp";

export default defineConfig({
  title: "VitePress MCP Server",
  description: "Vitepress Search MCP",
  themeConfig: {
    search: {
      provider: "local",
      options: {}, //追加。ブランクでもカスタムしてもOK
    },
    ...
  },
  vite: {
    plugins: [MCPPlugin({ port: 4000 })], //追加
  },
```

portは自由に設定できます。

この設定を追加し、VitePressを起動するとMCPサーバーも同時に起動します。

![スクリーンショット 2025-04-26 23.00.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2840428/da601e1b-1964-45eb-955b-afa907111ee8.png)


## SSE? StreamableHTTP?
VitePress MCPは当初SSEでの実装を検討していましたが、今後MCPサーバーのスタンダードとなると言われているStreamable HTTPで実装することにしました。
まだ情報が少なかったり、公式ドキュメントの実装通りだとエラーになるなどのトラブルはありましたが、StreamableHTTPで実装している方のソースから学び、開発を進めていきました。

## 提供ツール
現在はドキュメントを検索する`search_vitepress_docs` のみ実装しています。
起動時、ホットリロードでインデックスを再生成しているため編集した内容はMCPサーバーですぐに検索できます。

![スクリーンショット 2025-04-26 23.02.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2840428/3013dd1d-9336-4454-b325-8f47453343e0.png)


## バグレポート

お気づきの点がありましたらGithubのIssueまでお願いします。

https://github.com/Hal-Spidernight/vite-plugin-vitepress-mcp


## 利用ライブラリ

* MCP TypeScript SDK

https://github.com/modelcontextprotocol/typescript-sdk

* miniSearch

https://github.com/lucaong/minisearch

* Vite

https://ja.vite.dev/

* express

https://github.com/expressjs/express
The command 'docker' could not be found in this WSL 2 distro.と言われたら

WSL2で docker runしたら `The command 'docker' could not be found in this WSL 2 distro.`と怒られた。

wsl2であることを確認。
```sh
> wsl.exe -l -v
  NAME               STATE           VERSION
  * xxxxxx    Running         2
```

docker desktopのResourcesWSL integrationを見たら該当のマシンがoffになっていた。
onにしたらdocker runできました。
めでたしめでたし🦆🦆

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2493126/c53c40be-21f5-4c9c-a7a4-1a2ad0e7b40c.png)
M_File：各種定義

# ファイル処理の各種定義
~~~
'##############################################################################
' ファイル処理
'##############################################################################
' 参照設定          |   Microsoft Scripting Runtime
'                   |   Microsoft Office xx.x Object Library
'------------------------------------------------------------------------------
' 参照モジュール    |   M_String
'------------------------------------------------------------------------------

'==============================================================================
' 公開定義
'==============================================================================
' 定数定義
'------------------------------------------------------------------------------
Public Enum E_FILE_IDX_LIST_INF
    E_FILE_IDX_LIST_INF_NONE = D_IDX_START - 1
    E_FILE_IDX_LIST_INF_FULLPATH                                                'フルパス
    E_FILE_IDX_LIST_INF_RLTPATH                                                 '相対パス
    E_FILE_IDX_LIST_INF_NAME                                                    'ファイル名
    E_FILE_IDX_LIST_INF_MAX
    E_FILE_IDX_LIST_INF_EEND = E_FILE_IDX_LIST_INF_MAX - 1
End Enum

Public Enum E_FILE_SPEC_TEXT
    E_FILE_SPEC_TEXT_NONE = &H0
    E_FILE_SPEC_TEXT_LINE = &H1
    E_FILE_SPEC_TEXT_ALL = &H2
    E_FILE_SPEC_TEXT_LINE_ALL = E_FILE_SPEC_TEXT_LINE Or E_FILE_SPEC_TEXT_ALL
End Enum

'==============================================================================
' 内部定義
'==============================================================================
' 構造体定義
'------------------------------------------------------------------------------
Private Type PT_FILE_LIST_INF
    List As Dictionary
    Path As String
    ExtSpec As String
    ExtSpecAry As Variant
End Type

'------------------------------------------------------------------------------
' 定数定義
'------------------------------------------------------------------------------
Private Enum PE_FILE_IDX_FILTER_INF
    PE_FILE_IDX_FILTER_INF_NONE = D_IDX_START - 1
    PE_FILE_IDX_FILTER_INF_NAME
    PE_FILE_IDX_FILTER_INF_FILTER
    PE_FILE_IDX_FILTER_INF_MAX
    PE_FILE_IDX_FILTER_INF_EEND = PE_FILE_IDX_FILTER_INF_MAX - 1
End Enum

'------------------------------------------------------------------------------
' 変数定義
'------------------------------------------------------------------------------
Private pgInf As PT_FILE_LIST_INF
~~~
VS Code なら Agent で使える MCP/tools は json 触らなくても入れられる

# 背景

MCP の 設定で `json` 直接編集して苦労してる人が多そうな予感がしたので、楽に設定できるよって話を残しておく

ドキュメントとかでも、json 設定とか書いてるから、パスだったり引数だったりで躓くこと多そう :sweat: 

https://code.visualstudio.com/docs/copilot/chat/mcp-servers#_add-an-mcp-server11


# 1. 拡張機能で入れる tools

拡張機能を入れると、サクッと使えるようになる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/7fc4fdba-063f-493c-8360-ac4fc85297c4.png)


オススメは、以下辺り？

https://marketplace.visualstudio.com/items/?itemName=GitHub.vscode-pull-request-github

Azure DevOps 用のが Fork されて作られてるんだけど、公式ではないので・・会社で使うのは憚られる・・

https://marketplace.visualstudio.com/items/?itemName=ms-azuretools.vscode-azure-github-copilot

Azure 使う人なら

https://marketplace.visualstudio.com/items/?itemName=ms-vscode.vscode-websearchforcopilot

web 検索用。以下が使える
- Tavily (default)
- Bing

https://marketplace.visualstudio.com/items/?itemName=ms-vscode.copilot-mermaid-diagram

Mermaid 使う場合に

https://marketplace.visualstudio.com/items/?itemName=marp-team.marp-vscode

Marp で簡単に資料作成するなら


## 自分で作るときは、ここかな

https://code.visualstudio.com/api/extension-guides/tools


## 2. 名前選択で追加できる MCP Server

npm server なら、名称入れるだけで楽々設定なので、試してみたい人には正にうってつけ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/220eb332-26e2-4d2f-ae1f-620832820aac.png)

- MCP's official server repository

https://github.com/modelcontextprotocol/servers

### 前提

- npm

これは用意しておかないといけないとは思うので、`windows` なら、Node Version Manager で入れておくのが楽

https://github.com/nvm-sh/nvm

### 例：puppeteer を入れてみる

https://github.com/modelcontextprotocol/servers/tree/main/src/puppeteer

1. npx の名称を見つけてコピーする
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/90aac589-6a46-4164-9f44-191368b64504.png)
   この場合は以下
   > @modelcontextprotocol/server-puppeteer

1. NPM Pakage Name に入力する
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/8788ee82-ca6c-4c98-b7aa-3f258fae7a2c.png)

1. 許可する
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/e151456d-7f5a-46ae-8ad0-421b9d5fbcf7.png)

1. Server ID を決める。基本デフォルトでも問題はない（名前が被ることはないだろうし）
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/85caa71b-b0b1-4e54-99ba-1e62fa1ca40b.png)

1. 対象workspace を選択して
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/18cefd57-d534-4ebb-8b67-53a443030aa9.png)

1. mcp.json に追加されるので、起動確認するだけ
   ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120072/f1ae8b95-6bc7-4663-995f-0417ba2e9697.png)


### 例: FileSystem の場合

https://qiita.com/baku2san/items/323eb8f1fba612782e48

# あとがき

簡単に変える状況が整ったわけで、ほんと感謝
[memo]Next.jsでタスク管理ツールを作成していく

:::note
実装中のため随時更新
:::
🔧 チャレンジしたい技術スタック
| 項目 | 技術 |
|:-:|:-:|
| UI  |  React, Tailwind CSS（or shadcn/ui） |
| ルーティング  | Next.js  |
| 型定義  | TypeScript  |
| テスト  | Playwright（E2Eテスト）  |
|  状態管理 |  useState / useReducer |
| API  | Next.js API Routes  |

## Next.jsプロジェクト作成
```
npx create-next-app@latest taskmate --typescript


√ Would you like to use ESLint? ... Yes
√ Would you like to use Tailwind CSS? ... Yes
√ Would you like your code inside a `src/` directory? ... Yes
√ Would you like to use App Router? (recommended) ... Yes
√ Would you like to use Turbopack for `next dev`? ... No(webpack爆速だけどより爆速だけど不安定らしい)
√ Would you like to customize the import alias (`@/*` by default)? ... No(デフォルトで使いやすいから)
```

## 実装へ
page.tsxが初期ページ

### 状態管理したい変数を宣言
定義付けと初期値も一緒に設定
```tsx
const [task, setTask] = useState<string>("")
const [taskList, setTaskList] = useState<string[]>([])
```
入力値を宣言した`setTask`に格納
```tsx
<input
  type="text"
  value={task}
  onChange={(e) => setTask(e.target.value)}
  placeholder="タスクを入力"
  className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
/>
```
Tailwind CSSで指定した要素
- shadow：要素に影を追加します
- appearance-none：ネイティブのフォーム要素（ボタンや入力欄など）のデフォルトのスタイルを削除します
- border：要素にボーダー（枠線）を追加します
- rounded：ボーダーの角を丸くします（デフォルトの値）
- w-full：要素の幅を親要素いっぱいに広げます
- py-2：要素の上下のパディングを 0.5rem（8px）に設定します
- px-3：要素の左右のパディングを 0.75rem（12px）に設定します
- text-gray-700：テキストの色をグレー (#4a5568) に設定します
- leading-tight：行の高さを 1.25 に設定し、テキストを密集させます
- focus:outline-none：要素がフォーカスされたときのアウトラインを削除します
- focus:shadow-outline：フォーカス時に影を追加し、視覚的なフォーカス状態を強調します


```tsx
<button
  onClick={handleAddTask}
  className="bg-gray-700 text-gray-300 font-bold py-2 px-4 hover:bg-blue-700 rounded"
>add</button>
```
```tsx
const handleAddTask = () => {
    if (task.trim() === "") return
    setTaskList([...taskList, task])
    setTask("")
}
```
trim() 関数は、文字列の先頭と末尾にある空白（スペース、タブ、改行）を取り除く
-> 空白だけの入力を防いでいる

`setTaskList([...taskList, task])`　でやっていること
- `taskList` を スプレッド構文 (...) で コピー する
- 新しい `task` をコピーした配列の最後に追加する
- `setTaskList` に渡し、新しい配列を 状態（state） に更新する

```tsx
<ul>
  {taskList.map((t, i) => (
    <li key={i}>{t}</li>
  ))}
</ul>
```
`map()`のコールバックでは`map(配列の要素, index)`
Astro.js CSSファイルの読み込み方、使い方

Astroでは、コンポーネントごとにスタイルを当てたり、サイト全体に共通のスタイルを適用したり、SCSSを使うこともできます。

ここでは基本的な使い方を4つのパターンに分けて説明します。

## Astroコンポーネントに直接CSSを書く (`<style>` タグ)

特定のコンポーネントの中だけで使うスタイルを定義するのに便利な方法です。

1.  スタイルを当てたい `.astro` ファイル（例: `src/components/Button.astro`）を開きます。
2.  ファイルのテンプレート部分（`---`の下、通常はHTML要素の後）に `<style>` タグを追加します。
3.  `<style>` タグの中に、通常のCSSルールを記述します。

```astro
{/* src/components/Button.astro */}
<button>
  <slot /> {/* ボタンのテキストを受け取る */}
</button>

<style>
  /* このスタイルはこのButtonコンポーネント内のbutton要素にのみ適用されます */
  button {
    background-color: var(--button-bg-color, blue); /* CSS変数も使える */
    color: white;
    padding: 0.5em 1em;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    transition: background-color 0.2s;
  }
  button:hover {
    background-color: var(--button-hover-bg-color, darkblue);
  }
</style>
```

**ポイント:** `<style>` タグに書いたCSSは、**デフォルトでそのコンポーネント内の要素にしか適用されません** (スコープされます)。他のコンポーネントの同じ要素（例: 他のファイルの `button`）には影響しないので安心です。

**補足:** もし意図的に他の要素にも影響させたい場合（あまり推奨されません）は、`<style is:global>` と書くか、セレクタの前に `:global()` を付けます (例: `:global(body) { margin: 0; }`)。

## 外部CSSファイルを`import` で読み込む

サイト全体で使うスタイル（リセットCSS、基本的なタイポグラフィなど）や、複数のコンポーネントで共通するスタイルは、別のCSSファイルに書いて読み込むのが一般的です。

1.  `src/` ディレクトリ内（例: `src/styles/`）にCSSファイルを作成します (例: `src/styles/global.css`)。
2.  CSSファイルに必要なスタイル（例: bodyのフォント設定など）を記述します。
3.  サイト共通のレイアウトファイル（例: `src/layouts/BaseLayout.astro`）の **フロントマター (`---` 内)** で、そのCSSファイルを **相対パス** で `import` します。

```astro
---
// src/layouts/BaseLayout.astro
import '../styles/global.css'; // ← CSSファイルをインポート
import Header from '../components/Header.astro';
// ...
---
<html lang="ja">
  {/* ... */}
</html>
```
この方法でインポートしたCSSは、**サイト全体にグローバルに適用** されます。通常、グローバルCSSはこの方法でレイアウトコンポーネントから読み込みます。

## 外部CSSファイルを`<link>` タグで読み込む

1.  `public/` ディレクトリ内にCSSファイルを配置します (例: `public/css/legacy.css`)。
2.  レイアウトファイル（例: `src/layouts/BaseLayout.astro`）の `<head>` 内に `<link>` タグを記述します。

```html
<head>
  {/* ... */}
  <link rel="stylesheet" href="/css/legacy.css"> {/* ← ルート相対パスで指定 */}
  <!-- 外部  -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/prismjs@1.24.1/themes/prism-tomorrow.css">
</head>
```

**注意:** この方法はAstroによる最適化が行われません。特別な理由がない限り、先ほどの `import` を使う方が推奨されます。また`href` は必ず `/` から始まる **ルート相対パス** で指定します。

## SCSS (Sass) を使う方法

変数やネスト、ミックスインなどが使える高機能なCSSプリプロセッサSCSSも簡単に導入できます。

`sass` パッケージをインストール: ターミナルで以下のコマンドを実行します。
```bash
npm install sass
# または pnpm install sass / yarn add sass
```

### SCSSを`<style>` タグで使う
`.astro` ファイル内で `<style lang="scss">` と記述し、その中にSCSSコードを書きます。

```astro
<style lang="scss">
  $primary-color: #3490dc; // SCSSの変数
  $padding: 1rem;

  .card {
    padding: $padding;
    border: 1px solid #ddd;
    h2 { // ネスト
      color: $primary-color;
      margin-bottom: $padding / 2;
    }
  }
</style>
```
### `.scss` ファイルを読み込んで使う
`src/styles/` などに `.scss` ファイルを作成し、通常のCSSファイルと同様に `.astro` ファイルのフロントマターで `import '../styles/variables.scss';` のようにインポートします。

## まとめ
これらの方法を使い分けることで、Astroプロジェクトのスタイリングを効率的かつ整理された状態で行うことができます。