OmniAICreator/Qiita-1.07M huggingface dataset:
ArduinoIDE 2でESP32のファイルシステムにファイルを格納する方法

ArduinoIDE2(2.x.x)におけるESP32のファイルシステム(旧SPIFFS)ファイルアップロードに関しては、日本語の説明が見つからなかったので書きました。(IDE1については豊富)

## 結論から
SPIFFSではなく、LittleFSを使用する。
以下の**arduino-littlefs-upload**プラグインを導入し、

https://github.com/earlephilhower/arduino-littlefs-upload

以下のチュートリアルに従って実施 : 
https://randomnerdtutorials.com/arduino-ide-2-install-esp32-littlefs/#upload-files

## 上記チュートリアルの簡単な要約
上記のチュートリアルを端的にまとめると、
1. 上記githubよりプラグイン(arduino-littlefs-upload-x.x.x.zip(解凍後にvsix))を入手

1. C:\Users\XXXXX\\.arduinoIDEにplugins
フォルダを作成してarduino-littlefs-upload-x.x.x.vsixを格納

1. アップロードしたいデータをスケッチと同じフォルダのdataフォルダ配下に配置する。

``` bash
esp32_filesystem_sample/
├── data/
│   ├── index.html
│   └── script.js
└── esp32_filesystem_sample.ino※　
※SPIFFS.hではなく、LittleFS.hを使用する。基本的にSPIFFSをLittleFSに置き換えれば動作する。
```

1. ArduinoIDE(ver2.x.x)を再起動して、対象のdataフォルダが格納されたスケッチを開く

1. ボード選択やCOMポート選択を済ませ、スケッチ書き込みができる状態にする

1. Ctrl+Shift+Pでコマンドパレットを開き、「Upload LittleFS to Pico/ESP8266/ESP32」を選択する
1. data配下のファイルが自動的にアップロードされ、CompletedUploadと表示されれば完了
C言語　関数をアセンブリ言語で実装する方法

## 主関数
main関数はC言語で実装
```main.c
#include <stdio.h>

extern int add(int a, int b);

int main() {
    int result = add(3, 4);
    printf("Result: %d\n", result);
    return 0;
}
```

## アセンブリ言語
```add.asm
section .text
global _add       ; Windowsは下線が必要

_add:             
    push ebp       ; スタック前処理
    mov ebp, esp

    mov eax, [ebp + 8]   ; 第１引数 a
    add eax, [ebp + 12]  ; 第２引数 b=a+b

    mov esp, ebp   ; スタック後処理
    pop ebp
    ret
```
## 動作結果
```
nasm -f win32 add.asm -o add.obj
gcc -m32 main.c add.obj -o main.exe
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4054974/660ab8c3-12e2-4cb9-be29-3df1fe09ab50.png)

## 
## 動作環境
windows7 Version6.1.7601
GCC-6.3.0-1
NASM version 2.11.08 compiled on Feb 21 2015
（帰省中につき一時的に昔のパソコンを使用している。windows7が懐かしい。。。）
合成データによる高品質なインストラクションチューニングデータの作成方法

こんにちは、FastLabelで機械学習エンジニアをしているhachimadaです。

本記事では、LLM（Large Language Model）のインストラクションチューニング用データを、合成データで効率的かつ高品質に作るために実践した方法と、その際の勘所について紹介します。
ここでは概要をざっくりと説明していますので、興味があれば詳細を記載している[FastLabelのブログ記事](https://fastlabel.ai/blog/instructional-tuning-data)の方もご覧ください。

## なぜ合成データが必要なのか

LLMの学習は大きく3つのステップから成り立つのが一般的です。

1. 事前学習
    Webや書籍などの大量のデータから「次の単語を予測」する学習を行う。
2. インストラクションチューニング
    特定タスクの性能を高めるための追加学習で、指示文と期待出力のペアを大量に用意する必要がある。
3. 強化学習
    好ましくない出力を減らしたり、思考過程を鍛える工程。

インストラクションチューニングでは、各タスクに合わせた「指示文と期待出力」ペアのデータが大量に必要です。しかし、人間がすべてを手作業で作成するのは非常に大変なため、LLMを活用して合成データを作ることが一般的です。データの質をさらに高めるためには有識者に最終チェックをしてもらうことも行われます。

## 合成データ作成の全体像

今回は、特定のプログラミング言語に対して、コーディングに関する質問と回答を生成することに取り組みました。

### 1. データ要件を明確化する

まず大切なのは、合成データの質（正確性・一貫性）と多様性（幅広いシナリオや条件をカバーできるか）がどの程度必要かを明確にすることです。具体例として、R言語における統計解析の回答精度を高めたい場合を考えます。この場合、

- コードの説明
- コードの修正
- コードの生成

といったタスクがあり、さらに「平均・分散」「仮説検定」「回帰モデル」などのテーマが存在します。
タスク × テーマを組み合わせることで、多様性と必要な質の両面を担保できます。

### 2. 複数ステップで生成する

既存論文で提案されているプロンプトをそのまま使っても、使用するLLMの性能や対象とするドメインにより、高品質な問題・回答が出てこないケースが多々あります。そのため、次のような工夫を重ねることが重要です。

- コーディング規約や問題/回答の形式を具体的に指示する
- few-shot例を入れるなど、生成したい形式を丁寧に示す
- 問題と回答を分けて生成することで、プロンプトが長くなりすぎないようにする

このように生成を単純な複数のステップに分割して具体的なプロンプトを与えてやれば、質を高めつつ多様性も保ちやすくなります。

### 3. 詳細な要件が質の高いデータを生む

OSS-Instructのように、「コードスニペット → 問題/回答」を同時生成する手法は、超大規模データを一気に作るのには有効です。しかし、特定ドメインの精度を上げたい場合は「コードスニペットの多様性」に強く依存するため、不十分な結果になることもあります。

一方、「詳細なタスク要件から問題を直接生成 → 回答を生成」の手順を踏めば、コードスニペットなしでも十分に高品質で多様性あるデータを作れます。例えばR言語の統計解析タスクで、コーディング規約や回答ルールをきめ細かく設定することで、回答の精度や一貫性が向上しました。

### 4. 重複を排除する

プロンプトを固定したまま大量に生成すると、類似問題が量産されるリスクがあります。
そこで、生成された問題や回答について類似度チェックを行い、閾値を超える場合はスキップして重複を排除します。
Embeddingベースのコサイン類似度を使う方法もありますが、類似度にあまり差が出ず閾値を決めることが困難だったため、ROUGE-Lを用いました。

## まとめと今後の展望

1.**合成用LLMは最新最強ではない**
    使えるモデルの性能には限界があり、プロンプトは可能な限り詳細である方が望ましい。
2.**要件を細分化して多様性を担保する**
    「どんなタスクでどんなテーマを扱うか」を整理すれば、網羅的かつ多様性のあるデータを作りやすくなる。
3.**具体的なプロンプトで質を高める**
    問題・回答を分割するなど、生成ステップを細かく設計すると指示に忠実なデータを得られる。
4.**重複データの排除は必須**
    類似度チェックを挟まないと、同じような合成データが増え続けてしまう恐れがある。
5.**最終的には人間のチェックが鍵**
    完全に自動化するのは難しく、合成データの品質を確保するためには有識者のレビュー・修正が欠かせない。

合成データを賢く作れば、インストラクションチューニングの工程を効率化でき、高性能なLLMを目指すことができます。一方で、合成データ自体の精度が低いと修正コストが膨大になるため、今回ご紹介したようなステップを踏んで“まずは質を上げておく”ことが重要です。

どうしても、効率化のためにLLMでいい感じに合成データを作って欲しくなりますが、いいデータを作るためには、ドメイン領域と向き合い、細かい要件を詰めて、プロンプトを調整していくという、地味な作業が非常に重要だと強く感じさせられました。

-----

FastLabelでは、データセントリックなAI開発を支援するため、データ収集・アノテーション・モデル開発まで一貫して行えるサービスを提供しています。興味がある方はぜひ[こちら](https://fastlabel.ai/)からお問い合わせください。
よく使うGitHubコマンド

- リモートリポジトリの情報を取得する
    ```
    git fetch origin
    ```
- 現在のブランチを最新の状態に更新する
    ```
    git pull origin <branch_name>
    ```
- 新しいブランチを作成して切り替える
    ```
    git checkout -b <new_branch_name>
    ```
- 目的のブランチをローカルにチェックアウトして作成
    ```
    git checkout -b ローカルブランチ名 origin/リモートブランチ名
    ```
- aa
タグっぽいUI（バッジ）の作り方【Tailwind CSS編】

# やりたいこと
タグを「バッジ」風に見せたい。


# ゴール
タグの中身は適当です。タイトルと合ってない。笑
![スクリーンショット 2025-05-01 19.19.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3726068/4b9911ca-c966-4fcd-8f5c-1c53e5ab6210.png)



# 方法
## 1. 使用するTailwindクラス
| 目的 | class |
|:----------|:----------|
| 背景色 | `bg-blue-100` |
| テキスト色 | `text-gray-700` |
| 角丸 | `rounded-full` |
| 内側余白 | `px-3 py-1` |
| 文字サイズ | `text-xs` |


## 2. 基本のHTML構造（Blade例）
```blade
@foreach ($tags as $tag)
    <span class="px-3 py-1 bg-blue-100 text-gray-700 rounded-full text-xs">
        {{ $tag->name }}
    </span>
@endforeach
```


## 3. タグをグループごとに分類して見せる場合（例：フロント・バックエンドなど）
```
@foreach ($typeLabels as $type => $label)
    @if (!empty($groupedTags[$type]))
        <div class="flex flex-wrap items-center gap-2">
            <span class="font-semibold">{{ $label }}：</span>
            @foreach ($groupedTags[$type] as $tag)
                <span class="px-3 py-1 bg-blue-100 text-gray-700 rounded-full text-xs">
                    {{ $tag->name }}
                </span>
            @endforeach
        </div>
    @endif
@endforeach
```



## 補足ポイント
・flex flex-wrap gap-2 でタグが横並びで折り返し可能になる
・items-center を使うとラベルとバッジの縦位置が揃って美しい
・色は bg-gray-100, bg-green-100, text-indigo-700 などお好みで
・ラベル部分だけ太字にするとセクションとしての見出し感が出る
ワイルドカードと正規表現の違い

お手柔らかに

## はじめに
grepとfindの違いが理解できていなかったのでお勉強
その中で、正規表現とワイルドカードという似て非なる存在が現れたので、それらの違いについても整理

## grepとfindの違い

結論、ファイルの**中身**を検索したいのか、ファイルの**存在**を検索したいのかによって使い分ける

| 項目 | `grep` | `find` |
|------|--------|--------|
| **対象** | ファイルの**中身（テキスト）** | ファイルの**存在（名前や場所）** |
| **使うときの目的** | 文字列の検索・抽出 | ファイルの探索・絞り込み |
| **例** | `grep 'error' server.log`<br>→ ログの中から `error` を含む行を表示 | `find . -name "*.log"`<br>→ 拡張子が`.log`のファイルを探す |

## 正規表現とワイルドカードの違い

| 項目 | ワイルドカード | 正規表現 |
|------|------------------|-------------|
| **誰が解釈するか** | **シェルが解釈する**<br>→ コマンドが実行される前にシェルがワイルドカードを解釈し、その結果をコマンドに渡している(*1) | **コマンド本体が解釈する**<br>→ シェルは正規表現のままコマンドに値を渡し、コマンド本体が正規表現を解釈する |
| **使う場面** | **ファイル名**をざっくり指定するとき | **ファイルの中身や文字列**のパターンを細かく抽出したいとき |
| **よく使うコマンド** | `ls`, `rm`, `cp`, `mv`, `find -name` など | `grep`, `sed`, `awk`, `find -regex` など |

*1：例えば `ls *.txt` なら、`*.txt` を見てシェルはワイルドカードだと判断し、 `sample.txt` `example.txt`といった結果を `ls` に渡す。
つまり `ls` が受け取る値は `*.txt` ではなく `sample.txt` `example.txt` となる。

## まとめ

「誰が解釈するのか」が分かるとワイルドカードと正規表現の違いが見えてくる
Amazon SageMaker AI のドメインを削除できない

# １.課題
Amazon SageMakerのドメインを削除しようとした際に、ドメイン設定から削除しようとしても、グレーアウトされて削除できなくなってしまうことがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075786/17145a52-a26a-4211-a3c5-de3f57b7fe80.png)

# ２.原因
これは、ドメインにユーザープロファイルが残っていることが原因です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075786/832fc075-2686-44c0-a499-d64374379819.png)
参考）Amazon SageMaker AI ドメインを削除する
https://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/gs-studio-delete-domain.html

# ３.解決方法
### 1.削除するユーザプロファイルを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075786/e42dc90e-6486-41dc-b792-5300ef2edd82.png)
### 2.削除を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075786/684a636e-a680-4034-b88a-9b083bd4da30.png)
### 3.「はい、ユーザを削除します」をクリックし、削除と入力し、「削除」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075786/36f791ac-fdeb-4f37-bb13-5816a0e32ae1.png)
### 4.ドメインの削除を見てみると...
オレンジ色になっており、これで初めてAmazon SageMaker のドメインを削除できます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4075786/ec70ca2a-e4a1-4893-98bb-04a27c6dbe58.png)

# ４.まとめ
ユーザープロファイルだけでなく、共有スペースが含まれていても削除できないようですのでご注意ください。
（ドメインの管理画面で、「削除」ボタンがないことにも実は焦りました...）
構築や検証のときにつまづいたポイントをまとめていこうと思います！
よければ、フォローお願いします！！
サービス終了する直前に「コロモー」の殿堂入り記事を全てウェブアーカイブしようとしたが間に合わず死守できなかった…。

準備ができて当日の15時半過からようやくコロモーの殿堂入り記事をウェブアーカイブ保存し始めたが、コロモーのサービス終了まで全記事保存が間に合わなかった…。

![スクリーンショット 2025-04-30 165528.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/515024/ad342a82-d63c-45db-b477-e4e61e40bb28.png)

Internet Archiveに大量のURLを半自動で投げたら、16時頃には「保存100%完了まで残り5～8時間」という画面が出ていて、もう諦めしかなかった。想定では殿堂入り記事とそのコメントも全保存が目標だったが、途中で「コメント保存を断念する」という妥協しても間に合わなかった。

<p><br />

「どうせ、ふざけた社名の「バーグハンバーグバーグ」だから、実質サービス完全終了は18時ぐらいだろう」とも思っていたが甘かった。予告通り17:00丁度にサービス終了になってた。

うぅ…。昼飯を抜くか昨晩から徹夜して作業すればよかった…。敗北感。でも寿命を削ってまでアーカイブ作業してられない…。

<p><br />

- [coromoo.com_legend - Google ドライブ](https://drive.google.com/drive/folders/1p10I1fm5SQNf8i8Y3OoVWC6UFoj9bdn7?usp=sharing "coromoo.com_legend - Google ドライブ")
    - これが、アーカイブ結果やログなど。

一応、[殿堂入りの質問一覧](https://web.archive.org/web/20250430064120/https://coromoo.com/legend "殿堂入りの質問 - コロモー")だけは全ページ取得保存できたが…。意外と誰も目次付きなページネーションで分割されたページを保存してないのね…。

<p><br />

<p><br />

しかし、今でも見返したい記事がいくつかあったのになぁ…。

- [他に誰かいないの⁉自分の『特殊体質』への悩みなど！ - コロモー](https://web.archive.org/web/20250430073007/https://coromoo.com/question/121427 "他に誰かいないの⁉自分の『特殊体質』への悩みなど！ - コロモー")

この記事とか538件も回答が付いて、人間の進化的なサンプルとして参考になるかもしれなかったのに、3ページ(45回答)分しか保存できてなくて、割と貴重な資料が消滅したのでは？と思うと後悔しかなかった。

<p><br />

<p><br />

##### サービス終了する企業の方達や製作者へ、

サービス終了告知は[2点見積もり](http://www.jp.square-enix.com/tech/openconference/library/2011/dldata/PM/PM.pdf#page=211 "ゲーム開発 プロジェクトマネジメント講座")のように、上辺上や仮の終了をして猶予を与えていただきたい…。<sub>(何を言ってるんだ…。なんという放言…)</sub>

##### コロモーの関係者へ、

コロモーのデータを破棄しないでいただきたい…。Internet Archiveなどに寄贈していただけると…。

<p><br />

<p><br />

<!-- ああああー！ 一昨日に戻してー！ なんなら人生まだ十分にやり直せた数年前に誰か戻してー！ -->

<!-- ちなみに、自分はIT関連などのエンジニアなどではありません。スクリプトキディレベルから脱したい…。 -->
Git操作メモ：ブランチ作成からマージするまでの基本の流れ

# 概要

gitの使い方について、すぐ忘れてしまうため、
自分用のメモとなります。


ブランチの作成からマージするまでの一連の流れをまとめました。
## ブランチの新規追加後、切替する方法
```
git branch
ローカルブランチの一覧を表示
git checkout -b test1
test1のブランチを追加し、切り替え
```

## 作業内容の保存方法
```
git branch
ローカルブランチの一覧を表示
git add --all
修正したファイル、削除したファイル、新規に追加したファイルなど
変更のあった全てのファイルをステージングエリアに追加
git commit -m "htmlブランチテスト"
ステージングしたファイルをコミットすることでバージョンの履歴を追加
-m：メッセージ（message）の略。
⇒"変更した理由を記載"
git push origin HEAD　
今いるブランチからリモートレポジトリのoriginにプッシュ（アップロード）する
```
## 他のブランチからデータを統合する方法
```
git checkout main
統合したいブランチに切り替え
git branch
ローカルブランチの一覧を表示
git pull origin main
最新の状態に更新
git merge test1 
指定したブランチの変更を現在のブランチに統合
```

### 参考文献
https://www.sejuku.net/blog/71612
https://backlog.com/ja/git-tutorial/stepup/07/
https://qiita.com/yunano/items/f3133ea64efed762df2f
https://qiita.com/chihiro/items/e178e45a7fd5a2fb4599
https://qiita.com/takata2022/items/7222c856ac3f13a3f4e8
https://qiita.com/takuyanin/items/8d5226fd5834e6ebc564
https://qiita.com/shimotaroo/items/ed08d76447144d566637
開発者プラットフォーム　Dev.Guild

# Dev.Guild をリリースしました！
新しいプロジェクト参画プラットフォームで、Discord連携を活用したチーム作成を実現

こんにちは。今回は、新サービス「Dev.Guild」をご紹介します。Dev.Guild は、プロジェクト作成者と参画希望者がシームレスに繋がることを目指し、Discordアカウントでの認証や通知機能を組み合わせたプラットフォームです。

https://devguild-cl.onrender.com/

## サービス概要
プロジェクト作成者向け機能
Discordアカウントでログイン
ユーザーは自身のDiscordアカウントを用いてログイン可能です。

## プロジェクト作成
プロジェクト作成画面から、簡単に新しいプロジェクトを立ち上げることができます。

DiscordサーバーIDの設定
作成時にチャットに使用するDiscordサーバーIDを設定可能です。

参画リクエストの通知と承認
プロジェクトに参加したいユーザーからのリクエストが通知され、許可または拒否を選択できます。

## 参画者向け機能
Discordアカウントでログイン
プロジェクト作成者と同様、Discordアカウントでの認証が可能です。

プロジェクト一覧の閲覧
利用可能なプロジェクトの一覧から、参画したいプロジェクトを選択できます。

プロジェクト詳細画面での参画申請
参画ボタンを押下することで、プロジェクト作成者に参画リクエストが送信されます。

招待機能
作成者がリクエストを承認すると、Discordサーバーへの招待が自動でDiscord上に通知され、スムーズに参加可能です。

## Dev.Guild の特徴
シンプルなユーザーインターフェース
プロジェクトの作成から参画申請、承認までの一連の流れを直感的に操作できます。

Discordとの連携
ログイン認証、通知、招待機能をDiscordと連携することで、普段使い慣れたツールで開発コミュニケーションが完結します。

柔軟なプロジェクト運営
作成者は、参画希望者のリクエストをリアルタイムに確認し、適切なメンバーをチームに加えることができます。

こんな方におすすめ
新しいプロジェクトでチームを組みたいエンジニア
自身のプロジェクトを立ち上げ、仲間を募集したい方に最適です。

気になるプロジェクトに気軽に参画したいエンジニア
プロジェクト一覧から興味ある分野のプロジェクトを見つけ、参加を希望する方におすすめです。

Discordを普段から利用している方
認証やコミュニケーションにDiscordを活用しているため、使い慣れた環境で作業ができます。

## 今後の展望
プロジェクト内チャット機能の強化
Discord連携に加えて、Web上でもシームレスにコミュニケーションが取れる独自のチャット機能の実装を検討中です。

プロジェクト検索機能の改善
タグ付けやフィルター機能の充実により、目的に合ったプロジェクトをより見つけやすくします。

モバイル対応
モバイルブラウザや専用アプリでの利用を可能にし、いつでもどこでもプロジェクトに参加できる環境を整えます。

## 最後に
Dev.Guild は、エンジニア同士が気軽に集まれるコミュニティ作りの一助となることを目指しています。ぜひ一度サービスを試していただき、フィードバックや改善要望をお聞かせください！

今後とも Dev.Guild をよろしくお願いします！

Happy Coding!
HDLとRTLとは何か？FPGA初心者にもわかる基礎解説

### はじめに

FPGA開発やHLS（高位合成）に取り組む中で、必ず目にする言葉が「HDL」と「RTL」です。

本記事では、これらの用語の意味や違いを、初心者にもわかりやすく整理します。

## HDLとは？

**HDL**は「Hardware Description Language（ハードウェア記述言語）」の略です。

ソフトウェアのようにテキストでハードウェアの構造や動作を記述するための言語で、主に以下の2つがよく使われます。

- Verilog（ベリログ）
- VHDL

これらの言語を使うことで、回路図を描かなくても、テキストで論理回路を設計・検証・合成することが可能になります。

## RTLとは？

**RTL**は「Register Transfer Level（レジスタ転送レベル）」の略です。

これは**回路設計における抽象度の1つ**で、主に次のような概念をベースに設計されます。

- クロックごとにデータがレジスタからレジスタへとどのように転送されるか
- 入出力信号のタイミングやレジスタの更新タイミング

つまり、RTLは「ハードウェアがクロック単位でどのようにデータを処理するか」を設計するレベルを指します。

## HDLとRTLの違いと関係

| 用語 | 正式名称 | 意味 | 役割 |
|------|-----------|------|------|
| HDL | Hardware Description Language | 回路を記述するための言語 | RTLを記述するためのツール |
| RTL | Register Transfer Level | 設計レベル・抽象度 | クロック単位での設計スタイル |

HDLは **「何で書くか」** を示し、RTLは **「どういう抽象度で設計しているか」** を示す用語です。

たとえば、VerilogというHDLを使ってRTLの記述を行う、というのが一般的な使い方です。

## HLSとの関係

近年では、C/C++で設計して自動的にRTL（＝Verilogなど）を生成する「高位合成（HLS）」も広く使われています。

この場合、HLSツールはCコードを解析して、内部でRTL設計を生成し、それをHDL（Verilogなど）として出力します。

つまりHLSのアウトプットとしてHDL形式のRTLが得られる、という位置づけになります。

## まとめ

- HDLはハードウェアをテキストで記述するための言語（例：Verilog）
- RTLはクロック単位のレジスタ間のデータ転送を意識した設計レベル
- HDLはRTLを書くための手段であり、両者は密接に関係している
- HLSはC/C++からHDL（＝RTL）を生成する自動化手法

これらの基礎を理解することで、HLSやFPGA設計の全体像が見えやすくなります。
シェルの「リダイレクト」使い方について

#### 目次
- リダイレクトとは
- 基本構文まとめ
- よく使うリダイレクト例
- 補足：ファイル記述子


#### **リダイレクトとは**

リダイレクトは、**コマンドの出力（標準出力）やエラー（標準エラー出力）をファイルに保存したり、無視したりする**操作のことです。
Linuxコマンドの出力やエラーを、次のように**ファイルや他の出力先に流す（redirect）** ことができます。


#### **基本構文まとめ**

| 構文 | 説明 |
|------|------|
| `>` | 標準出力をファイルへ（**上書き**） |
| `>>` | 標準出力をファイルへ（**追記**） |
| `2>` | 標準エラーをファイルへ（**上書き**） |
| `2>>` | 標準エラーをファイルへ（**追記**） |
| `2>&1` | 標準エラーを標準出力にまとめる ||


#### **よく使うリダイレクト例**
- 標準出力をファイルへ保存
```bash
ls > result.txt
```
→ls の結果を result.txt に上書き保存
(すでにファイルがある場合は上書き)


- ファイルに追記（消さずに追加）
```bash
echo "hello" >> log.txt
```
→log.txt の末尾に "hello" を追記


- エラーメッセージをファイルに保存
```bash
ls not_exist_file 2> error.log
```
→標準エラー出力を error.log に出力（標準出力は無視）


- 出力とエラーを同じファイルに保存
```bash
your_command > all.log 2>&1
```
→標準出力を all.log に保存
→標準エラーも標準出力に「リダイレクト」して同じファイルに保存


- 出力を捨てる
```bash
your_command > /dev/null 2>&1
```
→出力もエラーも捨てる（完全に無視したいときに便利）


- 応用：標準出力とエラーを分けて保存
```bash
your_command > out.log 2> err.log
```
→標準出力は out.log 、標準エラーは err.log に保存


#### **補足：ファイル記述子**
0：標準入力（stdin）
1：標準出力（stdout）
2：標準エラー出力（stderr）

`2>&1`は、「ファイル記述子`2`（stderr）をファイル記述子`1`（stdout）と同じ場所に送る」という意味です。
Mac mini で ローカルLLM： Google の Gemma 3（MLX版 27B 3bit）を MLX LM ＋ コマンドライン／Python で試す

## はじめに

今回の内容は、以下の記事に書いていた「Gemma 3（MLX版）」を使ったローカルLLMの話です。

●Mac mini で ローカルLLM： Google の Gemma 3（MLX版 12B 8bit）を MLX LM で試す - Qiita
　https://qiita.com/youtoy/items/43e0c2a5c966963edcc5

上記の記事では、M4 の Mac mini で [MLX LM](https://pypi.org/project/mlx-lm/) を使って、コマンドラインでローカルLLM を試していました。そして、用いたモデルは 12B で、なおかつ自分の環境で使えるモデルサイズの量子化されたもの（利用するメモリが 16GB以内のもの）の 1つでした。

具体的には「[gemma-3-12b-it-8bit](https://huggingface.co/mlx-community/gemma-3-12b-it-8bit/tree/main)」を使っていました。

### 今回の内容

今回は「27B で量子化が 3bit の MLX版」である「[gemma-3-27b-it-qat-3bit](https://huggingface.co/mlx-community/gemma-3-27b-it-qat-3bit)」を使ってみます。当時はおそらくまだ出ていなかったと思われるものです（当時の 27B でモデルサイズが最小のものは、量子化が 4bit のものだった気がします）。

以下のとおり 16GB のメモリ割り当てができれば、余裕で実行できる感じのサイズ感のものです。

●mlx-community/gemma-3-27b-it-qat-3bit at main
　https://huggingface.co/mlx-community/gemma-3-27b-it-qat-3bit/tree/main

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e3852fdf-3c79-46fd-b532-352f4ac86b8c.png)


## 実際に試す

### 試す環境

今回、過去にも使った以下の環境を利用しています。

- PC
   - M4 の Mac mini（メモリ 24GB、うち 16GB をローカルLLM用で利用可能）
- モデル
   - gemma-3-27b-it-qat-3bit
- 実行環境
   - Python の仮想環境で MLX LM を利用、Python のコードで処理を実行


### コマンドラインで処理を実行する

#### コマンドラインで実行するコマンド

仮想環境で、以下のコマンドを実行して試してみます。

```zsh
mlx_lm.generate --model mlx-community/gemma-3-27b-it-qat-3bit --prompt "東京について日本語で説明して" --max-tokens 1024
```

#### 出力

上記を実行した結果は、以下の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/4b5d2447-94fc-42b4-a85e-b7907bd797d8.png)

日本語での説明を得ることができました（出力されたトークン数 ⇒「Generation: 560 tokens」）。また「Peak memory: 12.900 GB」となっており、ピーク時でも 13GB未満のメモリ使用量におさまっていたようでした。


### Python のコードで処理を実行する

あとは、Python のコードでのローカルLLM も試してみます。


#### Python のコード

今回、以下の過去記事でも使った、公式サンプルを元にした Python のコードを使いました。

●Mac mini で ローカルLLM： Qwen3（MLX版）を MLX LM ＋ Python で試した時のメモ - Qiita
　https://qiita.com/youtoy/items/fcf775e3a1547979cc63

具体的なコードは、以下のとおりです。

```python
from mlx_lm import load, generate

model, tokenizer = load("mlx-community/gemma-3-27b-it-qat-3bit")

prompt = "東京について3段落くらいで、日本語で説明して"

if tokenizer.chat_template is not None:
    messages = [{"role": "user", "content": prompt}]
    prompt = tokenizer.apply_chat_template(messages, add_generation_prompt=True)

response = generate(model, tokenizer, prompt=prompt, max_tokens=1024, verbose=True)
```


#### 実行結果

上記の Python のコードを実行して、その結果として日本語の説明を得られました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/c5bd0fa4-9878-41f9-a8b7-03d9493e9537.png)


また、出力中の様子を動画でキャプチャしたものも掲載しておきます。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Lfm33Rj63tc?si=w_xcKg8B-qNOx_Zf" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>


コマンドラインでのコマンドによる処理でも Python を使った処理でも、無事に結果を得られました。


自分の環境での ローカルLLM で扱えるモデルのバリエーションが増えるのは、嬉しい限りです。
VS CodeからRaspberry Pi Pico Wを動かす


## MicroPicoの拡張機能をインストール
VS Codeのサイドバーの拡張機能<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977720/f54e6c98-42ff-46e3-83f0-7e8ceae2cc5f.png" width=4%>を選択し、エディットボックスに"MicroPico"と入力し、[インストール]ボタンをクリックする。
![Micro_Pico.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977720/f73ddb64-ecea-438d-ab1c-e98bb0ca6381.png)

## main.pyのファイルを作成し、main.pyの入ったフォルダをVS Codeで開く
![Micro_Pico_edit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977720/3b60aa22-8e38-450f-a2ad-2dd79f5018ed.png)

## 初期化
「ctrl+shift+p または F1」でコマンドパレットを開き、次のコマンドを実行する。
`MicroPico: Initialize MicroPico project`
すると、左下のツールバーにMicroPicoのアイコンが表示され、main.pyと同じフォルダに.vscodeフォルダが作成されてMicroPicoの設定ファイルが作成される。
![Micro_Pico_edit2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977720/0213367f-aaba-4d47-9926-4dfe76ad111a.png)


## Pico Wの接続
PCのUSBポートとPico Wを接続すると、MicroPicoのツールバーの「Pico Disconnected」が「Pico Connected」に変化する。
![Micro_Pico_Connected.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977720/989bb304-d6f1-433f-9f5a-6678f2850ac8.png)


## プログラムの作成と実行
main.pyに動作確認用のプログラムを入力して![Micro_Pico_Run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3977720/4a3a7f43-0f47-4aa2-bcc4-b54a8c25b0d0.png)をクリックすると、入力したプログラムがPico Wで実行される。
```python:main.py
import time
from machine import Pin

# Pico Wのonboard LED 
led = Pin("LED", Pin.OUT)
  
#1秒毎に点灯と消灯を繰り返す
while True:
    led.value(1); time.sleep(1); #1秒間点灯
    led.value(0); time.sleep(1); #1秒間消灯
```

## VS CodeからPico Wにプログラムを転送
プログラムをPico Wにアップロードする場合、「ctrl+shift+p または F1」でコマンドパレットを開き、次のコマンドを実行する。
`MicroPico: Upload file to Pico`
【 Chakra UI + React Hook Form】ControllerとRegisterを使い分ける

React Hook Formでロジックを組みながらフレームワークとしてChakraUIを導入していると、`register(...) ` が直接使えない場合があります。このときに使うのが `Controller`です。

Chakra UI の `NumberInput` や `Select` のような特殊なコンポーネントにはreact-hook-form `Controller`を使用します。




## register とは
useForm() の返り値のひとつで、入力コンポーネントを React Hook Form に「登録」するための関数です。
HTML標準のような入力要素（`<input>`, `<textarea>` など）を React Hook Form へ登録するときに使います。

### 基本構文
```tsx
import { useForm } from "react-hook-form";

<input {...register("name")} /> // 「name」という名前でこの入力をフォームに登録する（onChange, refなどを自動で付ける）
```

- `register("name")` を使うことで、その要素が「name」という名前のフォーム入力として管理されるようになります。
- `ref`, `onChange`, `onBlur`, `name` などが自動的にセットされます。


#### `ref`
→ DOMへの参照。React Hook Formが入力の中身を直接読んだり操作したりするために必要。

#### `onChange`
→ 入力内容が変わったときに呼ばれる関数。値をフォームの状態に反映させるのに使う。

#### `onBlur`
→ フォーカスが外れたときに呼ばれる関数。バリデーションのタイミングに使われることが多い。

#### `name`
この入力がどのデータとして扱われるかを識別するキーの名前（例：register("bio") の "bio"）

registerはこれらをinputに追加してReact Hook Formで使えるように拡張しています。

#### 主な対象
- Chakra UI の `Input`, `Textarea`
- 素の HTML input 系タグ



## Controller とは
`Controller` はReact Hook Formが提供するコンポーネントの一つです。
（※`Controller`は`useForm()`の返り値ではない）

control を使って「このinputを管理してください」と包む役目です。
カスタムコンポーネントや Chakra UI の `Select`, `NumberInput` など、
`register` ではうまく動作しない入力要素に使います。

#### 基本構文
```tsx
import { Controller } from "react-hook-form";

<Controller
  // このフォーム項目の名前（RHFで管理するキー）
  name="tech"

  // useForm() から取り出した controlオブジェクトを渡す（必須）
  control={control}

  // 実際に描画されるUIをここで定義
  render={({ field }) => (
    // fieldの中には onChange, value, name, ref などが入っている
    // それをSelectInputにまるごと渡すことで、React Hook Formと接続される
    <SelectInput {...field} />
  )}
/>

```

- `Controller` は「この項目をRHFで管理したいけど、registerが使えない」場合の仲介役です。
- `field` の中に `value`, `onChange`, `ref`, `name` などが入っており、それをカスタムコンポーネントに渡します。

#### 主な対象
- Chakra UI の `Select`, `NumberInput`
- 独自で作成したカスタム入力コンポーネント


## 違いの比較

| 特徴       | register                          | Controller                                     |
|------------|-----------------------------------|------------------------------------------------|
| 対象       | 標準的な input 系                | 特殊・カスタムな UI                          |
| 書き方     | 簡潔、1行で済む                   | やや複雑、render関数を使う                    |
| 渡すprops  | {...register("name")}            | {...field} をカスタムコンポーネントに渡す     |
| バリデーション| `register` に直接書ける         | `Controller` の中で `rules` を使う            |



## まとめ

まずは `register` を基本に使い、うまく動かない・refやvalueが通らないと感じたときは `Controller` に切り替える、という運用をしています。

最小限のコードで動かすにはシンプルなものは `register`、複雑なものは `Controller` と覚えています。




## 参考リンク
以下のコードはこちらで公開されています。


- [React Hook Form Controller](https://react-hook-form.com/docs/usecontroller)
- [Chakra UI Form Control](https://chakra-ui.com/docs/components/form/control)

こちらの別の方の記事もChakra UI + React Hook Formでスタックしてらっしゃったので参考になりました。

https://github.com/chakra-ui/chakra-ui/discussions/2496
全加算器

今回は、前回の続きで、論理演算を使って全加算器をJavaScriptで組んだ話！

## <br>問題概要
    入力：A, B（1桁のビット）, C1（前の桁からの繰り上がり）

    出力：C2（次の桁への繰り上がり）, S（この桁の合計）

```
入力：
1 1 1 →
    
出力：
1 1
```
<br>

https://paiza.jp/works/mondai/logical_operation/logical_operation__basic_step9

## <br>コード例：全加算器を論理演算でつくる
```js
const rl = require('readline').createInterface({ input: process.stdin });

rl.on('line', (input) => {
    // 入力を数値に変換：A と B は足し算対象、C1 は前の桁からの繰り上がり
    const [A, B, C1] = input.split(' ').map(Number);


    // 半加算器その1：A + B を計算
    const Cx = A & B;       // AとBが両方1なら繰り上がり発生（Carry）
    const Sy = A ^ B;       // AとBの合計（Sum）


    // 半加算器その2：Sy + C1 を計算（前の桁からの繰り上がりを足す）
    const Cy = Sy & C1;     // Sumと繰り上がりが両方1ならさらに繰り上がる
    const S =  Sy ^ C1;     // 最終的な合計（2けた目）


    // 最終的な繰り上がり（C2）：2つの繰り上がりをまとめる
    const C2 = Cx | Cy;     // どちらかに繰り上がりがあればOK（ORのほうが安全）


    // 結果を出力：次の桁への繰り上がりC2、現在の桁の合計S
    console.log(C2, S);

    rl.close();
});
```

- `A & B` は両方 1 のときのみ 1 になる → 最初のCarry ( `Cx` )
- `A ^ B` は A と B が異なるとき 1 になる → 中間のSum ( `Sy` )
- `Sy & C1` は中間 Sum と C1 が両方 1 なら繰り上がる → 追加Carry ( `Cy` )
- `Sy ^ C1` は合計 → 最終の `S`（1桁の合計）
- `Cx | Cy` は両方どちらかで繰り上がりが出れば 1 → 最終Carry ( `C2` )


### <br>解説

- `&`（AND）で「繰り上がりがあるか」を判定
- `^`（XOR）で「1桁目の合計を算出

これを2段階に分ければ、**全加算器** が完成！
<br>

計算式で書くと：

Sum = A ⊕ B ⊕ C1
Carry = (A & B) | ((A ⊕ B) & C1)

→ ⊕はJavaScriptだと `^`
```js
const Sum = A ^ B ^ C1;
const Carry = (A & B) | ((A ^ B) & C1);

console.log(Carry, Sum);
```

## <br>まとめ

- 全加算器は半加算器×2＋ORでできる
- `&`  `^`  `|` でロジック回路が作れて楽しい
- コメントつける理解が進む



<br><br>[📘 僕の失敗談と解決話！](https://paizabeginner.wordpress.com/2025/05/01/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9a%e5%85%a8%e5%8a%a0%e7%ae%97%e5%99%a8/)
テレビ番組のタイトルからカテゴリ情報を推測する機械学習を作ってみた

## 背景

高校生の頃に構築した録画サーバーを6年以上運用してきました。  
現在ではSEとして、録画した動画ファイルの処理バッチを自作できるようになりました。

昨年、録画した動画ファイルと番組情報をDBで紐付けて一元管理する仕組みを構築しましたが、**数％の確率で紐付け処理が失敗する**問題が発生しています。

現在、動画ファイルはカテゴリ別で分類しており、カテゴリ情報の取得元は番組情報のため分類処理が失敗してしまいます。
そこで蓄積している番組情報を学習データとして、番組名からカテゴリ情報を推論する仕組みを構築してみました。

## 課題

この課題に対して、蓄積された**番組情報からカテゴリを推論する仕組み**を構築することにしました。  
以下は、その仕組みの構築手順です。



## 使用データ

### 番組情報テーブル

録画サーバーで取得した番組情報を、定時バッチでDBに取り込んでいます。  
テーブルには番組表に表示されている基本的な情報が格納されており、今回のモデル構築では以下を利用しました：

- `番組名（fileName）`
- `カテゴリ1（category1）`

---

## テキスト処理の流れ

### 1. 形態素解析

オープンソースの日本語形態素解析エンジン「**MeCab**」を使用し、番組名を単語単位に分割します。

例：  
`金曜ロードショー_名探偵コナン_劇場版` → `['金曜', 'ロードショー', '名探偵', 'コナン', '劇場版']`

---

### 2. 前処理

単語列に対し、以下の前処理を実施します。

- **小文字化**：英字を小文字に統一
- **不要語（ストップワード）除去**：意味のない助詞や汎用語を削除
- **記号・空白の削除**：不要な記号の除去

```python
def preprocess_text(text):
    # 小文字化
    text = text.lower()
    # MeCabで形態素解析
    node = mecab.parse(text)
    words = [line.split('\t')[0] for line in node.split('\n') if len(line.split('\t')) > 1]
    # ストップワードの除去
    words = [word for word in words if word not in stop_words]
    return ' '.join(words)
```

## 特徴量抽出（TF-IDF）

前処理を行った番組名のテキストデータを、機械学習で扱える数値データに変換するために、  TfidfVectorizer（TF-IDFベクトル化）を使用します。

前処理を行ったテキストを数値データに変換するためにTfidfVectorizer（TF-IDFベクトル化）を行います。TF-IDFで単語の重要度を数値化して重荷をつけていきます。

```python
from sklearn.feature_extraction.text import TfidfVectorizer

# 特徴量変換
vectorizer = TfidfVectorizer()
X = vectorizer.fit_transform(df['processed_fileName'])  # 前処理済みの番組名を数値ベクトル化
y = df['filepath']  # 対応するラベル（動画ファイルのパス）
```
## 機械学習
ベクトルデータを基に分類モデルを構築していきます。
今回はRandom Forest（ランダムフォレスト）を利用します。

```python
# モデル学習
model = RandomForestClassifier(n_estimators=100)
model.fit(X, y)
```
## 学習データ出力
ここまでの一連の処理で学習したデータをpklファイルで出力します。

## おわり
学習データの生成はAPIとして実装しており、紐付け処理に失敗した動画はエラーフォルダに分類され、自動的に推測クラスのAPIとあわせて呼び出される仕組みです。
今回は疲れたので学習クラスのみ解説しました。
気が向いたら推測クラスとシステム全体の構成について解説しようと思います。

最後まで読んでいただきありがとうございました。
GitHub CopilotがPRのサマリを書いてくれる今、レビュイーはPRに何を書くべきか

# はじめに：弊チームにおけるPR作成時の生成AIの活用

GitHub CopilotがPull Request（PR）の中でPRの概要を出力してくれるようになりましたね。

https://docs.github.com/ja/enterprise-cloud@latest/copilot/using-github-copilot/using-github-copilot-for-pull-requests/creating-a-pull-request-summary-with-github-copilot

これまで私たちの開発チームでは、下記の記事をベースにChatGPTにPRの概要文作成の補助をしてもらっていました。

https://qiita.com/185shingeki/items/0cf771e236026f1077ab

チーム内でPRの概要を記載する文化づくりと、そのPRの概要作成の負荷軽減に大いに活用させてもらっていました。
しかし、PRの中でGitHub Copilotが概要が作ってくれるようになったことで、diffを取ったりChatGPTとPRを行き来しなくてよくなり、各段に概要作成がラクになりました。

# CopilotもChatGPTも、差分から読み取れる事実しか書いてくれない

GitHub CopilotにしろChatGPTにしろ、diffから一瞬でそのPRの変更点のサマリを作成してくれます。
それは裏を返せば、彼らはdiffベースのことしか知らない、ということです。

結局彼らが作成してくれる情報だけだと説明不足感が否めませんでした。[^結局]

[^結局]:なので結局自力で概要を書くメンバーも一定いました。また、レビューに対する説明を書く文化をつけることが第一の目的だったので、ChatGPTによる概要作成補助の利用は任意としていました。

# だから、レビュイーがPRに書くべき内容がある

PRに含まれた差分そのものの概要は生成AIたちに任せられるようになったことで、人間が書くべきポイントが明確になった感があります。[^コメント歓迎]

[^コメント歓迎]:「この機能使えばそれもシステムに任せられるよ！」などのコメント大歓迎です。ぜひご教示ください！

## 「なぜ」変えたのか、その意図を書く
生成AIは「何を」変えたのかを理解することはできますが、「なぜ」変えたのかまでは汲み取ってくれません。
なぜそのコードを修正するに至ったか、なぜその実装を採用したのか、などがPRの概要に記載されていると、レビュー時の判断に役立ちますし、確認のためのやりとりを減らすことができます。

※追記
@flyaway さんの[コメント](https://qiita.com/moromi25/items/70cec7b5743b8f308ac2#comment-8e54f8848a2018906458)にあるとおり、コードそのものの意図はコード内にコメントとして残すことを優先すべきというのはその通りだと思います。

ただ、PRの概要としては、変更に至った経緯や、特にいくつか実装方針がある場合なぜ今回の実装を採用したかが記載されていると、PRの概要はつかみやすいな、と感じているのも正直なところです。
一方で、変更に至った経緯はPRではなくIssueやチケットなどの、実装方針については別の設計資料にあるのであればそのドキュメントのリンクが貼ってあるでも十分だと思います。


## 変更／追加したソースの前提知識を書く
そもそもこれは何をしているソースで、どこに影響があって・・・みたいなことを書いてくれると、レビューのスピードと精度がぐっと上がります。
そのロジックに精通している人とは認識合わせができますし、そのロジックにそこまで詳しくなくても解像度があがります。


## 変更内容どうしの関係性を書く
Copilotはソースコード単位での改変内容は提示してくれますが、まだ変更の羅列でしかない印象です。
なので、PRを読み解く上で起点となるソースはどこか、どのソースとどのソースが関連しているのかの構造や関係性を書いてくれると、PRを読み解くスピードと解像度があがります。

## 見た目が変わるものは変更前後のUIを添付する
PRの内容の結果、どういった見た目に変わるのかまではCopilotは提示してくれません。
デザインの変更前後の差異を、最低限画像、動きがある場合できればGIFアニメーションで添付すると、デザイン変更関連のレビューはぐっとしやすくなります。

# おわりに：結局のところ、レビュイーがPRに書くべき内容は変わらない気がする

ここまで書いての所感は、「あれ、結局レビュー依頼するときに書かなきゃいけないことって今も昔も変わらなくない？」です。
PRの概要のみならず、ソースコードも生成AIが書いてくれる時代ですが、それを採用するのは人間です。なので、それを採用した理由やその背景を正しく伝えられるのも今のところ人間です。

生成AIたちに任せられる部分はお任せしつつ、人間にしか説明できない箇所に注力して、より快適なPRレビューを目指しましょう～！
[PowerBI] PowerBI Serviceのデータを更新する

# `今すぐ更新`の手順
1. Webブラウザ上でPowerBI Serviceを開く
1. マイワークスペーズから対象のレポートを開く
1. `...`をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/5c18a412-8509-4e0b-9ca7-1959704201a4.png)
1. `関連するコンテンツの表示`を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/de49e460-bc5d-4d5d-8495-b6401e6b5b4a.png)
1. `今すぐ更新`をクリック
![{911C0F0F-64BF-48F9-9DCC-C7BB6E6C03C0}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/cda16797-51ea-4aac-affe-2198e2012288.png)



# `スケジュール更新`の手順
1. `4`まで[`今すぐ更新`の手順](#今すぐ更新の手順)と同じ
1. `更新のスケジュール設定`をクリック
![{734799FF-09EC-42F3-8948-1FF4E2E3FA00}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/c2ccb7e8-6543-4903-a1a0-04ad2b7b3c75.png)
1. セマンティックモデルを選ぶ
![{312F4D65-140A-4C34-B71D-31BAA5213C84}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/797cc216-49e0-400a-a110-51765630cd4b.png)
1. データソースの資格情報から、`資格情報の編集` を選ぶ
    （この場合は、ODateをデータソース(API連携)に使用している）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/11b5d728-d02c-4411-b167-bce9e7f565e7.png)
1. 表示されるpopの`URL`, `認証方法`(キーを選択), `アカウントキー`を登録する
1. `最新の情報に更新`を選び、適用したい標準時間、情報更新スケジュールの構成のON/OFF、更新頻度、時刻等を設定する
![{6080CD60-CD5D-496B-9F64-F5B29C47956D}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2955010/599ea1c0-2d99-419c-ad8a-f60d78802d7c.png)


# 参考リンク
- [power-bi_dataupdate](https://soft-zou.jp/2022/03/02/power-bi_dataupdate/)
- [Power BI でのデータの更新](https://learn.microsoft.com/ja-jp/power-bi/connect-data/refresh-data)
- [Power BIの自動更新を徹底解説！設定方法と運用のポイントを詳しく解説](https://powerbiseminar.com/2025/02/21/automatic-update/)
Copilotでトランペットを使う魔法少女を描いてみた。

# 概要

Copilotでトランペットを使う魔法少女を描いてみました。

# 実装

プロンプトと実行結果は以下の通りでした。

```
光のトランペットを使う魔法少女を描いてください。
```

![光のトランペットを使う魔法少女（Copilot）_20250501.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/7788d21c-a7fd-40cd-9ac8-e31a310b4df8.png)

```
闇のトランペットを使う魔法少女を描いてください。
```

![闇のトランペットを使う魔法少女（Copilot）_20250501.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/101a63ae-7fa4-4750-8f06-796489791ed0.png)


```
聖なるトランペットを使う魔法少女を描いてください。
```

![聖なるトランペットを使う魔法少女（Copilot）_20250501.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3192024/5f111239-b971-425e-a8f6-f2d26a8f9a11.png)

# まとめ

Geminiとはまた違った画像が得られました。
何かの役に立てばと。
GROVE - GSRセンサーとArduino M5StickC Plus2 (ESP32)で緊張度を測定する

GSRセンサーをつなげてseed studioのサンプルプログラムを書き込みましたが、起動しませんでした。
色々調べた結果、下記のコードで同等の結果を得ることができました

[今回使用したGSRセンサーはこちら ](switch-science.com/products/3401?_pos=1&_sid=390c08e55&_ss=r)
[うまく動かないメーカー(seed studio)のコード](https://wiki.seeedstudio.com/Grove-GSR_Sensor/)


修正して動作を確認したコードはこちら
```
```Arduino:GSR_reading.ino
#include <M5Unified.h>

const int GSR = 36;
int sensorValue = 0;
int gsr_average = 0;

void setup() {
  auto cfg = M5.config();
  M5.begin(cfg);
  Serial.begin(115200);
  
  pinMode(GSR, INPUT);
  gpio_pulldown_dis(GPIO_NUM_25);  // G36を使うときのおまじない
  gpio_pullup_dis(GPIO_NUM_25);
}

void loop() {
  long sum = 0;
  for (int i = 0; i < 10; i++) {
    sensorValue = analogRead(GSR);
    sum += sensorValue;
    delay(5);
  }
  
  gsr_average = sum / 10;
  Serial.print("GSR Average: ");
  Serial.println(gsr_average);

  delay(500);
}

```
なお出力は下記の要領で見られます
![{5D041FF2-7374-4F4D-836D-75F42F34E37F}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376140/c319b345-0fda-48fe-a43e-1105b1723bee.png)

115200に変更して下さい
![{07D9BEB4-7C84-4854-9366-9C121B557F71}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/376140/83901960-e6ba-46e4-beda-9835fe3e2bf2.png)
Grep置換の使い方（サクラエディタ）

#### 目次
- Grep置換とは
- Grep置換の起動方法
- Grep置換ダイアログの各項目
- 実行時の注意点
- 使用例：textファイル内の文字を一括修正


#### **Grep置換とは**

**複数ファイルに対して一括で文字列を検索・置換**できる機能です。複数ファイルの一括修正が必要なときに非常に便利です。
（通常の置換では、現在開いている1ファイル内でのみ置換）


#### **Grep置換の起動方法**

1. `メニュー`→ `検索(F)` → `Grep置換(G)` を選択  
　または  
**ショートカット（任意で設定）** 例：`Ctrl + Shift + R`


#### **Grep置換ダイアログの各項目**

| 項目 | 説明 |
|------|------|
| **検索する文字列** | 置換対象となる文字列 |
| **置換後の文字列** | 置換後に書き換える文字列 |
| **検索するフォルダ** | 処理対象のフォルダ（例：`C:\Project\src`） |
| **ファイル** | 対象ファイルの種類（例：`*.txt`, `*.cpp`, `*.html`） |
| **サブフォルダも検索** | サブディレクトリも含めて検索するかどうか |
| **正規表現** | 正規表現を使う場合はチェック |
| **大文字小文字を区別する** | `ABC`と`abc`を区別するかどうか |
| **リードオンリー属性も書き換え** | 読み取り専用ファイルにも置換を行う |
| **上書き保存** | 置換後に対象ファイルを自動保存 |


#### **実行時の注意点**

- **一度の操作で多くのファイルを変更できる**ため、**必ずバックアップを取ってから実行**すること
- 処理前に「対象ファイル数」や「検索ヒット件数」を確認すること


#### **使用例：textファイル内の文字を一括修正**

```text
検索フォルダ：C:\Windows\
ファイル　　：*.txt
検索文字列　：TEXT
置換後文字列：text
【備忘録】Dockerマルチステージビルドについて

# マルチステージビルドとは
- `Dockerfile`に複数の`FROM`命令を書く事で、**命令単位**で独立したステージとして扱われるビルド手法
- **独立したステージ群**が直列にビルドされ、**必要なファイルのみがコピー**されることで最終的なイメージサイズを削減できる

## マルチステージビルド時の挙動について
- 複数ステージが存在しても、最終的にイメージにビルドされるのは**単一のステージ**のみ
- `docker image build`は`--target`オプションで**イメージ化するステージ**を指定する
`--target`オプションが指定されない場合、Dockerfile内で定義された最後のステージが
暗黙的にイメージ化の対象になる
- 直列にビルドされるステージ群は**指定したステージが依存するステージ群**のみ

# マルチステージビルドを図解する(イメージサイズ)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/5c048122-ca8f-4348-b231-4d303c5e2a78.png)
- **具体例**: 図の場合は`gcc`のイメージと`ubuntu`のイメージの二つのイメージで
**マルチステージビルド**を行う

## 図解をDockerfileで表す(数字参照)
```dockerfile
FROM gcc:12.2.0

WORKDIR /app
COPY ./hello.c .
RUN gcc hello.c

FROM ubuntu:20.04

WORKDIR /app
COPY --from=0 /app/a.out .

CMD ["./a.out"]
```
- `COPY --from=0`は**0番目のステージ**を参照する

## 図解をDockerfileで表す(名前参照)
```dockerfile
FROM gcc:12.2.0 AS compiler

WORKDIR /app
COPY ./hello.c .
RUN gcc hello.c

FROM ubuntu:20.04

WORKDIR /app
COPY --from=compiler /app/a.out .

CMD ["./a.out"]
```
- `FROM {イメージ名} AS {ステージ名}`でステージに名前を付ける
- `COPY --from={ステージ名}`で**該当ステージ**を参照する

# マルチステージビルドを図解する(共通処理の分離)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3348923/ab96f2a1-d1f0-4701-9fc1-c3ce95b02af7.png)

- **具体例**: 図の場合は`ubuntu`のベースイメージへの処理は共通で行い、環境に依存する処理はステージを分けて行う

## --targetを利用した共通処理と環境依存処理の分離
- `--target`オプションによってビルドに利用されるステージが変更されることを利用し、最終的にビルドされるイメージを変更している
- 最終的にビルドに指定されるステージが依存しているステージを直列にビルドしていく
    また、依存が無ければビルドしない

```dockerfile:targetオプションで実行環境を変更する
FROM ubuntu:20.04 AS base
RUN apt update
CMD ["sh", "-c", "echo My name is $my_name"]

FROM base AS development
ENV my_name="TEST"

FROM base AS production
ENV my_name="Prod"
```

```console:target:development
docker image build --target development . # base + development
```
- `container run` -> `echo "My name is TEST"`
```console:target:production
docker image build --target production . # base + production
```
- `container run` -> `echo "My name is Prod"`
Amazon SES を使用した　DKIM/SPF/DMARC　の設定

## Amazon SES　を使用する場合

Amazon SESでDKIM, SPF, MXの設定を行う場合、以下のページとManagement Consoleを参照した。

https://docs.aws.amazon.com/ses/latest/dg/email-authentication-methods.html

作成したIdentityと各種Authentication Methodの内容をDNSサーバへ登録する際に、以下のような表にまとめてやり取りするとスムーズだった。


| Type  | Name/サブドメイン名             | Value/設定値                         | 説明 |
|:------|:------------------------------|:------------------------------------|:---|
| CNAME | aaa._domainkey.domainname.com | aaa.dkim.amazonses.com              | DKIM |
| CNAME | bbb._domainkey.domainname.com | bbb.dkim.amazonses.com              | DKIM |
| CNAME | ccc._domainkey.domainname.com | ccc.dkim.amazonses.com              | DKIM |
| MX    | mail.domainname.com           | 10 feedback-smtp.amazonses.com      | MX   |
| TXT   | mail.domainname.com           | "v=spf1 include:amazonses.com ~all" | SPF  |
| TXT   | _dmarc.domainname.com         | "v=DMARC1; p=none;"                 | DMARC|
| CNAME | xx.domainname.com             | aaa.cloudfront.net                  |Transfer from a domain to an application webserver|

一番下のCNAMEレコードは、メールのAuthentication Methodとは無関係である。DKIM等をDNSサーバへ登録してもらう場合新しいWebサイトのドメインを登録することが多いので、上記の例では追加した。WebサイトはCloudFrontを使う前提である。CloudfrontのDistributionについては、以下の記事を参考にした。

https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/GettingStarted.SimpleDistribution.html


## DKIM　DomainKeys Identified Mail　とは
送信ドメイン認証技術である。メール送信サーバ側が秘密鍵で電子署名を付与し、受信者は公開鍵を使って正当性を確認できる。

SESの場合、公開鍵を取得するためのキーが３つ存在するため、CNAMEレコードを３つ登録する必要がある。Name/サブドメイン名に入る値は　(selector)._domainkey.(domain)　の形式となっている。selectorとdomainを使用して公開鍵が取得できる。DKIMがDNSサーバに想定通りに登録されているかを、以下のようなサイトを使用して確認できる。

https://mxtoolbox.com/SuperTool.aspx#

Selectorの有効期限はManagement Consoleで作成してから72時間である。72時間以内にDNSサーバに登録し、レコードが検証されないと無効になってしまうので注意。

DKIMの概要については、以下の記事を参考にした。

https://docs.aws.amazon.com/ja_jp/ses/latest/dg/send-email-authentication-dkim.html

## SPF Sender Policy Framework とは

SPFは、メールのなりすましを防ぐために使用する。送られたメールが正当であることを保証するために、送信元ドメインのDNSサーバにSPFレコードを公開する必要がある。

SESの場合はSPFのためのTXTレコードと合わせてMXレコードもDNSサーバへ登録する必要がある。MXレコードを登録する理由は、メールプロバイダーがバウンスをした場合にそれをSESで受け取るようにするためである。

以下の記事を参考にした。

https://docs.aws.amazon.com/ses/latest/dg/mail-from.html

## DMARC Domain-based Message Authentication Reporting and Conformance とは

SPF認証とDKIM認証と組み合わせて利用される。SPFとDKIM認証のどちらかがエラーとなった場合、p=に指定されるアクションを受信したメールサーバが実行するように促す。

| | |
|:-----|:-----|
|p=none|受信した結果がレポートされるので、メールプロバイダーがそれを見ることができる。|
|p=quarantine|受信したメールを隔離する。ジャンクメールに入れるか、受信サーバに保留するか等。|
|p=reject|受信したメールを破棄する。|

以下の記事を参考にした。

https://dmarc.org/wiki/FAQ

## 参考文献

参考にした記事の内容やリンクは文中に記載した。
当サイトに掲載している記事は個人の見解であり、所属する組織の公式見解ではない。
Fuzz test

Chimeraフレームワークを使用すると、Foundryを使用して簡単にデバッグできるEchidnaとMedusaで不変テストを実行できます。

Medusa Log Scraper
テスト実行の最後に生成されたメデューサログを貼り付けます
すべての関数呼び出しは、貼り付けられたログから自動的にスクレイプされます
各プロパティは、Foundry再生装置ユニットテストを生成します
必要に応じてチートコードを切り替える
Echidna Log Scraper
テスト実行の最後に生成されたEchidnaログを貼り付けます
すべての関数呼び出しは、貼り付けられたログから自動的にスクレイプされます
各プロパティは、Foundry再生装置ユニットテストを生成します
必要に応じてチートコードを切り替える

Invariants Builder
契約のABIを貼り付けます( out/ Foundryを使用して契約を構築した後のディレクトリ）
「Your_Contract」フォームフィールドに、貼り付けた契約のABIの名前を追加します
[すべてのファイルをダウンロード]ボタンを使用して、生成された契約をレポにダウンロードします
レポにファイルを追加した後、次の手順については、「インストールヘルプ」セクションの手順に従ってください。
Bytecode Compare
2つの契約バイトコードを貼り付け
「比較」ボタンを使用して、それらの間の差分を生成します。オプションでメタデータを無視します
Bytecode To Interface
契約のバイトコードを追加します。 a。rpc-urlと契約アドレスの使用 b。バイトコードを直接貼り付ける
[インターフェース名]フォームフィールドで契約を結ぶインターフェース名を定義します
[インターフェイスの生成]ボタンを使用して、指定されたバイトコードのSolidityインターフェイスを生成します

Chimera

Foundry
Echidna
Medusa
Halmos

プロパティベースのテストを作成するとき、開発者は通常いくつかの問題に直面します:必要な定型コードの量、初期設定後のツールの切り替えの課題、異なるツール間で結果を共有することの難しさ

Chimeraは現在、実装されたチートコードのみをサポートしています

https://hevm.dev/std-test-tutorial.html#supported-cheat-codes

ABI to Mock
The Worst Programming Language Ever - Mark Rendle

The Worst Programming Language Ever - Mark Rendle - NDC Oslo 2021 
https://youtu.be/vcFBwt1nu2U?si=-XguzEat8Ang4Zl3 

知らない言語がでてきている。

>There's something good you can say about every programming language. But that's no fun. Instead, let's take the worst features of all the languages we know, and put them together to create an abomination with the worst syntax, the worst semantics, the worst foot-guns and the worst runtime behaviour in recorded history. Let's make a language so bad it would make people run screaming to Visual Basic for Applications.
Check out more of our featured speakers and talks at
https://ndcconferences.com/
https://ndcoslo.com/

知らなかったのは、INTERCALとBS。使ったことがないのは、APLとGO。

# COBOL

# APL

# INTERCAL
The INTERCAL Resources Page
http://www.catb.org/~esr/intercal/

INTERCAL "The Performance Art of Programming"
http://www.muppetlabs.com/~breadbox/intercal/

# BS
UNIX Users Manual
https://ia800706.us.archive.org/5/items/bitsavers_attunixSysalRelease3Jun80_33886798/UNIX_Users_Manual_Release_3_Jun80.pdf

# Visual BASIC

# python

# Ruby

# JavaScript

# C/C++


# rust

# FORTH

# GO


# Mark Rendle
Linkedin
https://www.linkedin.com/in/markrendle/?originalSubdomain=uk

OpenAPI & .NET: You're Doing It Wrong - Mark Rendle - NDC Oslo 2023
https://www.youtube.com/watch?v=1K1LRzXeO_4

Programming's Greatest Mistakes • Mark Rendle • GOTO 2023
https://www.youtube.com/watch?v=Y9clBHENy4Q&t=21s

How Simple Is "As Simple As Possible"? - Rendle . - NDC Porto 2024
https://www.youtube.com/watch?v=WfUQHpcLKF4

Mark Rendle - High Performance .NET
https://www.youtube.com/watch?v=aoXSjsJlSp8

Interview of Mark Rendle
https://www.youtube.com/watch?v=X9NUmtNoAH0

How JavaScript Happened: A Short History of Programming Languages - Mark Rendle - NDC London 2024
https://www.youtube.com/watch?app=desktop&v=lWeLaEo4pn0

Mark Rendle: How JavaScript Happened
https://www.youtube.com/watch?v=E4Vt88bQs64

Locknote: The Albatross Project - Mark Rendle - NDC Oslo 2024
https://www.youtube.com/watch?v=WwNCoPntgZ8

‪@that_rendle‬ about what's wrong with enterprises (#SAFe)
https://www.youtube.com/watch?v=prN_9PfyixM
ソースだけじゃズレる！ざっくり分かるMCP（Model Context Protocol）の考え方

# 注意
本記事で取り上げている MCP（Model Context Protocol） は、
MCPが持つ機能のうち 「AIに渡す情報（仕様書・DB定義など）を構造化する部分」、
つまり Resource Context と Tool Context に関する話 に絞っています。

# ざっくりいうと
Cursorなどのツールはソースコードを参照して
指示通りのプログラムを書きますが、そこで問題になるのが
仕様やDB定義とズレてしまう、という問題がよくあります。
そこで仕様書やDB定義書も渡してより正確なプログラム書いてもらおうと
エンジニア目線で言えばそんなやつです。

# Cursor と MCP（分離型）の違い
|項目|Cursor（従来のコードAI）|分離型 MCP|
|:--|:--|:--|
|情報源|ソースコードだけ|ソース + DB + 設計書など何でもOK|
|検索方法|IDE内でスキャン|各「MCPサーバ」が担当（分業）|
|まとめ方|自前で全て把握|「MCPホスト」が選別・圧縮してAIに渡す|
|拡張性|プラグイン書き換えが必要|MCPサーバを追加すれば拡張できる|
|精度|文脈が少なくズレることも|文脈が増え、指示に対して的確になりやすい|

# まとめ
* ソースコードだけじゃAIは限界がある
* MCPは「仕様書もDBも渡せるようにする工夫」
* Cursorはその一部分（ソース）を自動で読ませてるだけ
* MCP分離型はツール同士の役割分担と拡張性が大きなポイント
#
サクラエディタについて

#### 目次
- サクラエディタとは
- 基本操作ショートカット
- 編集・操作関連のショートカット
- カーソル・選択操作のショートカット
- ウィンドウ・タブ・表示系のショートカット
- マクロ・外部ツールのショートカット


#### **サクラエディタとは**
サクラエディタとは、**日本語テキストエディタ**です。


#### **基本操作ショートカット**

| 操作 | ショートカット |
|------|----------------|
| 新規作成 | `Ctrl + N` |
| ファイルを開く | `Ctrl + O` |
| 上書き保存 | `Ctrl + S` |
| 名前を付けて保存 | `Ctrl + Shift + S` |
| 印刷 | `Ctrl + P` |
| 元に戻す（Undo） | `Ctrl + Z` |
| やり直し（Redo） | `Ctrl + Y` |
| 切り取り | `Ctrl + X` |
| コピー | `Ctrl + C` |
| 貼り付け | `Ctrl + V` |
| 全選択 | `Ctrl + A` |
| 検索 | `Ctrl + F` |
| 置換 | `Ctrl + R` または `Ctrl + H` |
| 行へジャンプ | `Ctrl + G` |


#### **編集・操作関連のショートカット**

| 操作 | ショートカット |
|------|----------------|
| 行の複製 | `Ctrl + D` |
| 行の削除 | `Ctrl + E` |
| コメントアウト（自作マクロ利用時） | `Ctrl + /`（要マクロ設定） |
| インデント追加 | `Tab` |
| インデント解除 | `Shift + Tab` |
| 行の移動（上/下） | `Alt + ↑ / ↓`（バージョンや設定による） |


#### **カーソル・選択操作のショートカット**

| 操作 | ショートカット |
|------|----------------|
| 行頭へ移動 | `Home` |
| 行末へ移動 | `End` |
| 文書先頭へ移動 | `Ctrl + Home` |
| 文書末尾へ移動 | `Ctrl + End` |
| ページアップ | `Page Up` |
| ページダウン | `Page Down` |
| 選択範囲を上/下へスクロール | `Ctrl + ↑ / ↓` |


#### **ウィンドウ・タブ・表示系のショートカット**

| 操作 | ショートカット |
|------|----------------|
| タブを切り替え（左） | `Ctrl + Page Up` |
| タブを切り替え（右） | `Ctrl + Page Down` |
| 折り返しのON/OFF | `Ctrl + Alt + W`（初期設定では無効。カスタム可） |
| ステータスバー表示の切替 | `Alt + V → S`（メニュー操作） |


#### **マクロ・外部ツールのショートカット**

| 操作 | ショートカット |
|------|----------------|
| マクロの実行 | `Alt + F8` |
| マクロの登録（現在の記録内容） | `Alt + F6` |
| マクロの記録開始/停止 | `Alt + F1` / `Alt + F2` |
サービス名にCloudWatachとつくサービスについてまとめてみた

# はじめに

CloudWatchとはAWSで利用されるサービスの情報を監視するためのサービスです。
AWSの資格受験でそれぞれがどんなものかはイメージできていますが、全体像を整理するために用語をまとめてみました。

# サービス名にCloudWacthがついているサービス・用語
CloudWatchがつく言葉として以下があります。
・CloudWatch
・CloudWatch Metrics
・CloudWatch Logs
・CloudWatch Events
・CloudWatch Alarm

<br>

それぞれの説明やユースケース、関係性について以下に示します。

| 機能 | 用途 | 説明 |
|:-----------|:------------|:------------|
| **CloudWatch** | リソース監視 | **CloudWatch** 自体はAWSサービスのメトリクスリポジトリサービスです。**CloudWatch Metrics** や **CloudWatch Alarm** はCloudWatchの構成要素です。|
| **CloudWatch Logs** | ログ監視 | **CloudWatch Logs** はAWSサービスのログ、あるいはサーバログの収集、蓄積し一元管理をすることができます。|
| **EventBridge** | 死活監視<br>閾値監視 | **EventBridge** は**CloudWatch Events** の現在の名称です。イベントを起点にアクションを実行することができるサービスです。|


漠然としていたCloudWatchのイメージを整理することができました。
【初心者向け】Windows + VS CodeでReactメモアプリを作ろう！

React を始めたいけど、まず何から始めたらいいか分からない…  
そんな方のために、今回は **Windows環境 × VS Code** で **シンプルなメモアプリ** を作ってみます！

---

## 🎯 ゴール

- Reactを使って簡単なSPA（シングルページアプリ）を体験
- 入力 → メモ追加 → リスト表示 の機能を実装
- ローカルブラウザ上で動作確認

---

## ✅ 事前準備

### 1. Node.js のインストール

ReactはNode.js環境が必要です。

- 公式サイト：[https://nodejs.org/ja](https://nodejs.org/ja)
- 「LTS版」をダウンロード＆インストール

インストール後、以下のコマンドでバージョン確認：

```bash
node -v
npm -v
```

---

### 2. VS Code のインストール

エディタとして Visual Studio Code を使います。

- ダウンロード：[https://code.visualstudio.com/](https://code.visualstudio.com/)

---

## 🛠 Reactアプリを作成する

### 1. プロジェクトを作成

コマンドプロンプト（またはターミナル）で以下を実行：

```bash
npx create-react-app memo-app
cd memo-app
code .
```

`create-react-app` はReact公式のスターターキットです。

---

### 2. メモアプリを実装する

#### `src/App.js` を以下のように書き換えます：

```jsx
import { useState } from "react";

function App() {
  const [memo, setMemo] = useState("");
  const [memos, setMemos] = useState([]);

  const addMemo = () => {
    if (memo.trim() === "") return;
    setMemos([...memos, memo]);
    setMemo("");
  };

  return (
    <div style={{ padding: "20px" }}>
      <h1>メモアプリ</h1>
      <input
        type="text"
        value={memo}
        onChange={(e) => setMemo(e.target.value)}
        placeholder="メモを入力"
      />
      <button onClick={addMemo}>追加</button>

      <ul>
        {memos.map((m, i) => (
          <li key={i}>{m}</li>
        ))}
      </ul>
    </div>
  );
}

export default App;
```

---

## ▶ 実行してみよう！

以下のコマンドでローカル開発サーバーを起動：

```bash
npm start
```

ブラウザが自動で開き、`http://localhost:3000` にアクセス！  
✨ 自分だけのメモアプリが表示されます！

---

## 🧾 まとめ

✅ Node.jsとReactの導入  
✅ VS Codeでプロジェクト作成  
✅ 入力・追加・表示の基本機能を体験
【初心者向け】WindowsでVS Codeから簡単なJavaアプリを作ってみよう！

今回は**Windows環境**で**Visual Studio Code（VS Code）**を使って、**簡単なJavaアプリケーション**を作成する手順をご紹介します。

> Javaは初めてだけど触ってみたい！  
> IntelliJではなく軽量なVS Codeで開発したい！  
> 環境構築が心配…

という方向けに、できるだけシンプルにまとめました。

---

## ✅ 前提条件

以下がPCにインストールされている前提で進めます：

- Windows 10 または 11

---

## ① Javaのインストール（OpenJDK）

まずはJava開発環境（JDK）を用意します。

1. [Oracle公式ダウンロードページ](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) にアクセス
2. 「**Windows x64 Installer**」をダウンロード
3. インストーラーを実行し、指示に従ってインストール

インストール後、以下のコマンドで確認します：

```bash
java -version
```

出力例：

```bash
java version "17.0.10" 2024-01-16 LTS
```

---

## ② VS Code のインストール

まだインストールしていない場合は、以下からダウンロードします：

🔗 [https://code.visualstudio.com/](https://code.visualstudio.com/)

---

## ③ Java拡張機能のインストール

VS Code を開いたら、以下の拡張機能をインストールします：

- **Extension Pack for Java**（by Microsoft）

拡張機能マネージャで「Java」と検索 → 上記パックを選択 → インストール

---

## ④ Javaプロジェクトを作成する

1. **新しいフォルダー**（例：`HelloJava`）を作成し、VS Codeで開きます
2. VS Code のコマンドパレット（`Ctrl+Shift+P`）を開き、「**Java: Create Java Project**」を選択
3. 「No Build Tools」を選択
4. パッケージ名（例：`app`）を入力

---

## ⑤ Hello World を書いてみる

自動生成されたファイル `App.java` を以下のように編集します：

```java
package app;

public class App {
    public static void main(String[] args) {
        System.out.println("こんにちは、Java！");
    }
}
```

---

## ⑥ アプリを実行する

画面右上の「▶（Run）」をクリックするだけで実行できます！

出力例：

```
こんにちは、Java！
```

---

## まとめ

これで**Windows × VS Code**でJavaアプリ開発を始める準備が整いました！

✅ Javaインストール  
✅ VS Codeインストールと拡張機能追加  
✅ Hello World 実行成功！