OmniAICreator/Qiita-1.07M huggingface dataset:
英語学習中のエンジニアがAmazon Q CLI で英単語学習ゲームを作った

# はじめに

「Amazon Q CLI を使ってゲームを作ろう Tシャツキャンペーン」が6/20まで開催されています。

https://aws.amazon.com/jp/blogs/news/build-games-with-amazon-q-cli-and-score-a-t-shirt/

自分もゲーム作りましたので、どんなゲームを作ったか書いていきます。

# Amazon Q CLI とは？

Amazon Q Developer for CLI はコマンドライン上で実行でき、CLI 環境内の情報を活用し、ローカルファイルの読み書き、AWS リソースのクエリ、コードの作成、AWS CLI コマンドの提案や実行を支援してくれます。

Amazon Q CLIのセットアップは、前回書いた記事を参考にしていただければと思います。

https://qiita.com/amarelo_n24/items/10d9b2b2d7e6d1b1b880

# どんなゲームを作ろうか？

今年は英語学習に力を入れています。

AWS re:Invent に行って少しでも英語で参加者と会話をできるようにするため、AWSのドキュメントを少しでも英語で読めるようにするためです。

せっかくならば楽しみと学習を兼ねたゲームを作り、Amazon Q CLIで遊ぶことができれば一石二鳥！と思い、英単語学習ゲームを作りました！

# 作成過程

作り始めのプロンプトをスクショ撮っていませんでした。以下のようなプロンプトをAmazon Q CLI に入れて作ってもらいました。

```
以下の内容で英単語学習ゲームをpygameで作成してください。文字化けが発生しないよう、pygameが日本語表示できるフォントを使ってください。

・表示された日本語の英単語を記入する。
・最初に開始画面を表示する。
・「開始」ボタンを押したら出題スタートする。
・問題は全部で10問とする。
・毎回ランダムに出題する。
・1問正解で10点とする。
・正解の場合は「正解！」と表示する。間違っている場合は正解と単語の意味を表示する。
・「次の問題」ボタンを表示して、次の問題へ進む。
・80点以上で「合格です！」、80点未満の場合は「不合格です…」と表示する。
・すべて終了したら、開始画面に戻る。
```

これだけだと日本語表記が文字化けします。Google Fonts から「Noto Sans Japanese」をダウンロードします。

https://fonts.google.com/noto/specimen/Noto+Sans+JP

ダウンロードしたら、「Noto Sans Japanese」を使うよう指示します。

```
日本語表示がされていないため、以下の場所にあるフォントを使うようコードを修正してください。

/Noto_Sans_JP/NotoSansJP-VariableFont_wght.ttf
````

その後、画面表示の調整を指示してできたゲームは以下の通りです。自分の指示が悪かったためか、何度も指示をして調整しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/5c08a77f-6c42-4ae3-b752-7c0fbd00cb08.png)


![スクリーンショット 2025-06-07 110918.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/b3295504-37c7-4e77-9a56-fe7259053420.png)

やってみましたが、英語力の無さを痛感しました…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/605e46c1-87f4-4985-be1e-2bb53250e882.png)

# ルール改修

ゲームというよりは、英単語のミニテストのような構成になりました。
目的が英語学習のためなのでこれでも全然良いのですが、もっとゲーム性を高めたいと思って、以下の修正を指示しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/a4004848-4575-45a0-9e7a-abaf6b3fbaa3.png)

修正後のルール

![スクリーンショット 2025-06-12 235941.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/d652e937-334c-4588-8d47-fb17a07adedc.png)

正解

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/1808535c-4a5f-49d0-a3de-79ddeb53c875.png)

連続正解することでコンボボーナスが加算されました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/16fb6465-cc4f-456f-8b57-b1257f2b73b2.png)

不正解で、コンボボーナスも終了…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/b38a6f97-678c-466c-9736-097157bdc671.png)

あまりいい結果ではありませんね。それに安定した点数も取れない…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402789/1d8431cd-af99-486b-8ebf-74de817ef10f.png)

# 最後に

まだまだ英語の勉強が必要ですね。楽しみながらこのゲームやって英単語を覚えていきます！

ここまでの成果をキャンペーンのTシャツ応募に出しますが、このゲームを今後も改良を続け、自分だけでなく、子供たちの英語学習にも役立てるものにしていきたいです！

まだキャンペーン終了まで時間がありますので、まだAmazon Q CLIでゲーム作りをしていない方も一度チャレンジしてみてください！
Data Cloud sandboxのまとめ



+ [Data Cloud in a Sandbox (Beta)](https://help.salesforce.com/s/articleView?id=sf.c360_a_data_cloud_sandbox.htm&type=5)
+ [サンドボックス内のデータクラウド](https://help.salesforce.com/s/articleView?id=data.c360_a_data_cloud_sandbox.htm&type=5)
+ [DataCloud で DataGraph を表示できません。](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000KBqT7)

# 削除

+ [Employee ServiceのSandboxでDataCloudの接続を削除できるか](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000TkEuo)

:::note
6月6日公開のヘルプがありました。Sandboxをリフレッシュすると再認証が必要みたいですね。 

+ [Data Cloud Sandbox に関する FAQ](https://help.salesforce.com/s/articleView?id=004333079&type=1)

既存の Sandbox は自動的に Data Cloud を取得しますか？
いいえ、Sandbox で Data Cloud を動作させるには、既存の Sandbox を更新する必要があります。Data Cloud Sandbox SKU を購入した後に新しく作成された Sandbox は、本番組織で Data Cloud が既に有効になっている限り、Sandbox で Data Cloud を自動的に取得します。 

Data Cloud で構成された Sandbox を更新するとどうなりますか？
Sandbox を更新すると、Salesforce は実質的に組織を削除し、代わりに新しい組織を作成します。その場合、Data Cloud 接続とデータが削除されます。必要に応じて、更新された Sandbox に接続を再認証し、データを取り込む必要があります。
:::
ChatGPTを使用したアプリ開発記【チャートにMACDを追加】

## MACDのロジックコード
```Macd.js
//🔹 MACDを計算する関数の定義です。
//data: 株価データ（配列。各要素は { close: 数値 } の形式）
//shortPeriod: 短期EMA（通常12）
//longPeriod: 長期EMA（通常26）
//signalPeriod: シグナル線（通常9）
export function calculateMACD(data, shortPeriod = 12, longPeriod = 26, signalPeriod = 9) {

//🔹 EMA（指数移動平均）を計算する内部関数の開始。
  const ema = (arr, period) => {

  //🔹 EMAの係数kを算出します。これは「平滑定数」と呼ばれ、期間が短いほど大きくなります。
//例：periodが12なら k = 2 / (12 + 1) = 0.1538
    const k = 2 / (period + 1);
// 🔹 配列arrの各要素に対して、EMAを計算するmap処理を開始します。
    return arr.map((item, i) => {

    // 🔹 最初のデータ（i=0）のEMAは、単純にclose価格をそのまま使用します（初期値）。
      if (i === 0) return item.close;

      //🔹 それ以降のデータでは、EMAの公式で値を計算しています。
	//•	item.close * k：現在の価格に係数kを掛ける
	//•	ema(...).slice(-1)[0]：直前までのEMAの最後の値を取り出す
	//•	全体で「現在値 × k + 前のEMA × (1 - k)」となる

      return item.close * k + ema(arr.slice(0, i), period).slice(-1)[0] * (1 - k);
    });
  };

  const shortEMA = ema(data, shortPeriod);
  const longEMA = ema(data, longPeriod);

  //🔹 各ポイントにおける MACDライン = 短期EMA - 長期EMA を算出。
  const macdLine = shortEMA.map((val, i) => val - longEMA[i]);

  //🔹 MACDラインに対して**シグナル線（MACDの9期間EMA）**を算出します。
  //	map(... => { close: val }) の形で ema 関数が使える形式に変換
  const signalLine = ema(macdLine.map((val, i) => ({ close: val })), signalPeriod);

//🔹 最終的に、元のデータに macd と signalLine を追加して返す。
  return data.map((item, i) => ({

  //🔹 元の各データ（例えば { close: 150 } など）を展開。
    ...item,

    // 小数第2位に丸めて追加。
    macd: Math.round(macdLine[i] * 100) / 100,
    signalLine: Math.round(signalLine[i] * 100) / 100,
  }));
}
```
[ふたたび]8x8を2倍角に変換して遊ぶ(ビット操作


いろいろ、注意
----

- arduinoでの予定は、未定

プログラム
----

オンラインコンパイラ　paiza


```c++



#include <iostream>
using namespace std;

#define b_put(aa) for(int ii=8;ii!=0;ii--){if(aa & 0x80){printf("#");}else{printf(".");}aa=aa<<1;}
#define bit8_put(bb) for(int jj=0;jj<16;jj++){b_put(bb[jj*2]);b_put(bb[jj*2+1]);printf("\n");}

int main(void){
    // Your code here!

    unsigned char font[] = {
        0b00100000, //  #     
        0b01111100, // #####  
        0b00100000, //  #     
        0b01111100, // #####  
        0b10101010, //# # # # 
        0b10110010, //# ##  # 
        0b01100100, // ##  #  
        0b00000000  //
    };  
    
    unsigned char font2[16*2];


    int j = 0; //2倍角出力フォントのカウンター
    for (int i = 0; i < 8; i++) { //フォントの2倍角化ループ

      int al = font[i]; //入力フォントの読み出し
      int s = 0;
      s = s | (0b0000000000000001 & al); al = al + al;
      s = s | (0b0000000000000100 & al); al = al + al;
      s = s | (0b0000000000010000 & al); al = al + al;
      s = s | (0b0000000001000000 & al); al = al + al;
      s = s | (0b0000000100000000 & al); al = al + al;
      s = s | (0b0000010000000000 & al); al = al + al;
      s = s | (0b0001000000000000 & al); al = al + al;
      s = s | (0b0100000000000000 & al); 
      s = s | (s + s);

      font2[j++] = s >> 8;
      font2[j++] = s & 0xff;
      font2[j++] = s >> 8;
      font2[j++] = s & 0xff;

    }  //for



     bit8_put(font2);

    
}





```

```

....##..........
....##..........
..##########....
..##########....
....##..........
....##..........
..##########....
..##########....
##..##..##..##..
##..##..##..##..
##..####....##..
##..####....##..
..####....##....
..####....##....
................
................

```
vimのvimgrep,Quickfix,cdoのまとめ

## 稼働環境 ## 
Ubuntu 24.04.2 LTS
VIM - Vi IMproved 9.1

## vimgrepの使い方 ##
複数のファイルの検索、置換を扱う。 

```
:vim[grep] {pattern} {file} ...
" カレントディレクトリ以下のあらゆるファイルを対象にする
:vim {pattern} **
" app/views以下のあらゆるファイルを対象にする（ディレクトリを再帰的に検索）
:vim {pattern} app/views/**
" カレントバッファを対象にする
:vim {pattern} %
```

## Quickfix listの使い方 ## 
Quickfix list が開いたなら、そこから操作を行う。 
あらかじめ次のスクリプトを.vimrcに追加しておくこと。
autocmdしなければ:copenする。
```
" 前へ
nnoremap [q :cprevious<CR>
" 次へ
nnoremap ]q :cnext<CR>
" 最初へ
nnoremap [Q :<C-u>cfirst<CR>
" 最後へ
nnoremap ]Q :<C-u>clast<CR>

autocmd QuickFixCmdPost *grep* cwindow
```

## cdoの使い方 ##
Quickfix listをまとめて置換してくれる。

```
:cdo %s/hoge/hige/ge | update
```
## 参考リンク ##

https://qiita.com/yuku_t/items/0c1aff03949cb1b8fe6b

https://qiita.com/tnagatomi/items/b4000435b661523ca744



ー以上ー
ファイルのあるディレクトリにcd

GPLなコードを追いかけている時に、ファイルのあるディレクトリに移りたい時があります。

shだと以下のようにできます。

```
$ cd $(dirname `find . -name xhci.c`)
/home/hiroki/ref/ASUSWRT_RT-AC1200GPlus/release/src-rt-9.x/src/linux/linux-2.6.36/drivers/usb/host
```

こうしても良いようです。

```
$ cd `dirname \`find . -name xhci.c\``
```

cshのやり方がわかりません。
学習9日目

# 今日学んだこと
①render partial
②commitの取り消し

# ①render partial
ビューファイルで、同じフォーム画面をnewとeditで表示させたい場合等に、ファイルが別々だと修正箇所もその分増える。
この場合、1つのファイルにフォーム内容を記述し、newとeditそれぞれからフォームのテンプレートを呼び出すのが良い。

views/hoges/_form.html.erbを作成した場合の例を示す。

(views/hoges/new.html.erb)
```
<%= render partial: "form", locals: {hoge: @hoge} %>
```
locals部分は「_form.html.erb内でhogeという変数に対し、@hogeを代入します」という意味。(もちろん@hogeをnewアクションで定義する必要はある)

呼び出し先と呼び出し元が同じフォルダ内の場合は上記でOKだが、異なる場合は下記。
パスはviews以下のパスを/から始めることに注意。

(views/fugas/new.html.erb)
```
<%= render partial: "/hoges/form", locals: {fuga: @fuga} %>
```
※コントローラ側で@fugaの定義が必要

# ②コミットの取り消し
前回作成したブランチをマージしたことを忘れており、mainブランチ上でcommitしてしまったことに気づき、下記を実行。

(直前のcommitの取り消し)
```
$ git reset --soft HEAD^
```

(直前のaddの取り消し)
```
$ git reset HEAD
```

(通常通りブランチ作成し、移動)
```
$ git checkout -b hoge_branch
```

# 感想
render partialのテンプレートが別フォルダにある場合のパスの書き方が分からず、時間がかかりました(../hoges/formと書いてもだめでした)。このように書くものと覚えるしか無さそうです。
コミット取り消しの方は、あらかじめgit branchで作業ブランチを確認してから行うとミスを減らせると感じました。
競プロ日記#25/06/12

# AtCoder
## AtCoder Beginner Contest 370
[C - Word Ladder](https://atcoder.jp/contests/abc370/tasks/abc370_c)
- 文字数がたかだか100回なのでNの3乗まで計算できるのと単に文字比較していけばよいことはわかったが辞書順のところがどうにも対応できなかった
- つまり普通に愚直にやれば行けたはずのものを変に高速化的なものを意識しようとした結果、訳が分からなくなり見失った
VimのFcitx4.0日本語変換切り替え

## 動作環境 ##
Ubuntu 24.04.2 LTS
vim 9.1

## 説明 ##
.vimrcの最後に追加すること。normalモードに入るときFcitx4.0が英数モードになる。

```
"" 日本語の切り替え
if executable('fcitx')
   autocmd InsertLeave * :call system('fcitx-remote -c')
   autocmd CmdlineLeave * :call system('fcitx-remote -c')
endif
```
## 参考リンク ##

https://wonwon-eater.com/linux-vim-neovim-ime/

https://qiita.com/keith_campbell/items/df6a306742837c2b0ea5

ー以上ー
【Python入門】typingモジュールの型ヒントの使い方まとめ


型ヒントの章を勉強したときのまとめです。

中でも自分が特につまずいた「`typing`モジュールを使った型指定」について整理しておきます。

## 型ヒントとは？

Pythonは動的型付け言語だけど、「この変数や関数はこの型になる予定だよ」と明示的に書いておくと、コードの見通しがよくなる。

実行時に型が強制されるわけではないけど、mypyのようなツールを使えば、型のチェックができるようになる。

## 基本的な型ヒントの書き方

```python
def greet(name: str) -> str:
    return f"Hello, {name}"
```

このように、関数の引数や戻り値の型を `:` や `->` を使って指定できる。

`int` や `str`、`bool` などの基本型は `typing` モジュールを使わずに書ける。

## `typing` モジュールを使うケース

リストや辞書、複数の型を受け入れたいときは `typing` モジュールを使う。

特によく出てくるのは以下のパターン。

| 型 | 意味 |
|------|------|
| `List[int]` | int型のリスト |
| `Tuple[str, int]` | str型とint型のタプル |
| `Dict[str, int]` | キーがstr、値がintの辞書 |
| `Union[int, str]` | int または str |
| `Optional[int]` | int または None（省略可能）|

## コード例

```python
from typing import List, Tuple, Dict, Union, Optional

# List[int]
def total(numbers: List[int]) -> int:
    return sum(numbers)

# Tuple[str, int]
def show_person() -> Tuple[str, int]:
    return ("Alice", 30)

# Dict[str, int]
def price_list() -> Dict[str, int]:
    return {"apple": 100, "banana": 80}

# Union[int, str]
def stringify(x: Union[int, str]) -> str:
    return str(x)

# Optional[int]
def get_age(user: str) -> Optional[int]:
    if user == "Alice":
        return 30
    return None
```

## Pythonのバージョンによる違い

少しややこしいけど、Pythonのバージョンによって型ヒントの書き方が変わる。

| 型 | Python 3.8以下 | Python 3.9以降 |
|-----|----------------|----------------|
| リストなど | `List[int]`（`typing`必要） | `list[int]`（`typing`不要） |
| 基本型 | そのままでOK | 同じく |
| Optionalなど | `Optional[int]` | `int | None` という省略形も使える（3.10以降） |

試験では `typing.List[int]` や `Optional[int]` の表記で出題されることが多いので、そちらを覚えておいた方が安心。

## 補足：実行時には型チェックされない

```python
def greet(name: str) -> str:
    return "Hello!"

# intを渡してもエラーにはならない
print(greet(123))
```

このように、Pythonでは実行時に型がチェックされることはない。

型ヒントはあくまで「ヒント」であって、型チェックを行うには mypy などのツールを使う。

## まとめ

- `int`, `str` などの基本型はそのまま書ける
- リストや辞書などは `typing` モジュールを使って書く（試験ではこの形式）
- Pythonのバージョンによって省略表記が使えるようになっているけど、試験では `List[int]` のような旧来の形式を覚えておくと安心
【Python初心者】dataclassを辞書やJSONに変換する方法（asdictとシリアライズ）

前回の記事では、`@dataclass` を使って `__init__()` を自動生成する仕組みや、コンストラクター引数の扱いについてまとめました。  
今回はその続きとして、dataclassインスタンスを<strong>辞書に変換する方法（`asdict()`）</strong>や、<strong>JSONとして保存・送信する方法（シリアライズ）</strong>について、自分の理解を整理しておきます。

## 辞書に変換する：`asdict()`

まず、`dataclass` を辞書に変換したいときは、標準ライブラリ `dataclasses` の `asdict()` を使います。

```python
from dataclasses import dataclass, asdict

@dataclass
class User:
    name: str
    age: int

user = User("Riku", 28)
user_dict = asdict(user)
print(user_dict)  # {'name': 'Riku', 'age': 28}
```

ポイント：
- `asdict()` は**再帰的に変換**されるので、入れ子になった dataclass も対応してくれます。
- 返り値は Python の通常の辞書（`dict` 型）になります。

## JSONに変換する（シリアライズ）

Pythonの辞書を JSON に変換するには、標準ライブラリの `json.dumps()` を使います。  
つまり、`asdict()` と組み合わせることで dataclass も JSON に変換できます。

```python
import json
from dataclasses import dataclass, asdict

@dataclass
class Product:
    name: str
    price: int

p = Product("Headphones", 15000)

# 辞書に変換してからJSONに変換
json_str = json.dumps(asdict(p), ensure_ascii=False)
print(json_str)  # {"name": "Headphones", "price": 15000}
```

`ensure_ascii=False` を使うと、日本語なども文字化けせずに表示されます。

## ネストされた dataclass にも対応できる

入れ子構造（ネスト）になった dataclass も、`asdict()` で辞書に変換できます。

```python
from dataclasses import dataclass, asdict

@dataclass
class Author:
    name: str
    age: int

@dataclass
class Book:
    title: str
    author: Author

b = Book("Python入門", Author("Suzuki", 40))
print(asdict(b))
# {'title': 'Python入門', 'author': {'name': 'Suzuki', 'age': 40}}
```

`asdict()` は内部の dataclass も自動的に辞書化してくれます。

## JSONから復元（逆変換）するには？

Pythonの辞書から dataclass インスタンスを作りたいときは、`**辞書展開` を使います。

```python
from dataclasses import dataclass

@dataclass
class Item:
    id: int
    name: str

item_dict = {"id": 1, "name": "Monitor"}
item = Item(**item_dict)
print(item)  # Item(id=1, name='Monitor')
```

もし JSON 文字列から復元したい場合は、まず `json.loads()` で辞書にしてから展開します。

```python
import json
from dataclasses import dataclass

@dataclass
class Item:
    id: int
    name: str

json_str = '{"id": 1, "name": "Monitor"}'
item_data = json.loads(json_str)
item = Item(**item_data)
print(item)  # Item(id=1, name='Monitor')
```

ネストが深くなると、自分で中身を展開してあげる必要が出てきますが、シンプルなケースでは `**` 展開で十分です。

## まとめ

- `asdict()` を使えば、dataclass を辞書に変換できる
- `json.dumps()` で JSON 文字列として保存・送信できる
- JSON → 辞書 → dataclass への復元には `json.loads()` と `**kwargs` を使う
- ネスト構造も `asdict()` で自動変換されるので扱いやすい
【Python初心者】dataclassの基本をやさしく解説

Pythonの学習中に `@dataclass` という便利そうなものを見つけました。  
ただ、最初は「どうして勝手に `__init__()` が作られるの？」「コンストラクター引数って何？」といった疑問がありました。  
この記事は、自分の理解を整理するための学習記録です。

## dataclassとは？

Python3.7から使える `@dataclass` は、クラスに自動的に初期化処理や表示処理を追加してくれる便利な機能です。  
`from dataclasses import dataclass` を使って、クラス定義の上に `@dataclass` を書くことで有効になります。

通常、クラスを定義するときには `__init__()` を手動で書く必要があります。

```python
class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age

user = User("Taro", 30)
print(user.name)  # Taro
```

これが `@dataclass` を使うと、次のようにすっきり書けます。

```python
from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int

user = User("Taro", 30)
print(user.name)  # Taro
```

`name` や `age` をクラス定義の中に書くだけで、`__init__()` メソッドが自動生成され、初期化処理が自動で行われるのが大きな特徴です。

## dataclassとコンストラクター引数

クラスを使ってインスタンスを作るときに渡す値（`__init__()` に渡される値）を「コンストラクター引数」と呼びます。

たとえば次のようにインスタンスを作るとき、

```python
user = User("Hanako", 25)
```

この `"Hanako"` と `25` が、`__init__()` に渡される **引数** です。

`@dataclass` を使うと、自動的に下記のような `__init__()` が作られているイメージです。

```python
def __init__(self, name: str, age: int):
    self.name = name
    self.age = age
```

つまり、dataclassで定義された変数（属性）は、そのままコンストラクター引数になります。

## デフォルト値と引数の順番

dataclassでも、引数にデフォルト値を設定できます。

```python
from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int = 20

user1 = User("Ken")
print(user1)  # User(name='Ken', age=20)

user2 = User("Ken", 35)
print(user2)  # User(name='Ken', age=35)
```

ただし注意点として、**デフォルト値がある引数の後に、デフォルト値なしの引数を書くとエラーになります**。

```python
# エラーになる例
@dataclass
class User:
    name: str = "Ken"
    age: int        # ❌ デフォルト値がない引数が後ろに来ている

# 正しい例
@dataclass
class User:
    name: str
    age: int = 20   # ✅ デフォルト値がある引数が後ろ
```

このように、dataclassの初期化も通常の関数定義と同じく、「位置引数 → キーワード引数」の順に並べる必要があるということを覚えておくと安心です。

## field()を使ってコンストラクター引数を制御する

もっと細かく初期化の挙動を変えたいときには、`field()` を使います。  
たとえば `init=False` を指定すれば、`__init__()` の引数に含めないようにできます。

```python
from dataclasses import dataclass, field

@dataclass
class User:
    name: str
    age: int = 20
    id: int = field(init=False)

user = User("Miki")
user.id = 1001  # 後から代入する
print(user)     # User(name='Miki', age=20, id=1001)
```

このように `field(init=False)` を使うことで、「後からセットしたい値」「計算で自動設定される値」などに対応できます。

## まとめ

- dataclassを使うと、`__init__()` などを自動で作ってくれる
- dataclassの属性はそのままコンストラクター引数になる
- デフォルト値がある引数は、必ず後ろに書く必要がある
- `field(init=False)` を使うと、その属性は `__init__()` に含まれない

次回は、`asdict()` を使ってdataclassを辞書に変換したり、JSONに変換する方法についてまとめる予定です。
はじめてのプログラム：「Hello, World!」で学ぶ主要言語の書き方

# はじめに
プログラミングを学び始めたとき、多くの人が最初に書くのが「Hello, World!」というプログラムです。これは、画面に「Hello, World!」と表示するだけのシンプルな内容ですが、言語ごとに文法や書き方が異なり、それぞれの特徴を知る第一歩となります。

本記事では、世界中で広く使われている代表的なプログラミング言語と、その「Hello, World!」プログラムの書き方を分かりやすく紹介します。初学者の方も、他の言語に興味がある方も、ぜひ参考にしてみてください。

# C言語
シンプルで歴史のある言語。多くのプログラミング言語のルーツです。

```
#include <stdio.h>

int main() {
    printf("Hello, World!\n");
    return 0;
}
```
# C++
C言語を拡張した高機能な言語。オブジェクト指向プログラミングにも対応しています。

```
#include <iostream>
using namespace std;

int main() {
    cout << "Hello, World!" << endl;
    return 0;
}
```
# Java
エンタープライズ向けでも利用される、信頼性の高いオブジェクト指向言語。

```
public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, World!");
    }
}
```

# Python
読みやすさ・書きやすさが特徴の近年大人気の言語です。

```
print("Hello, World!")
JavaScript
ウェブサイトの動きを作るのに欠かせない言語。
（コンソール出力の場合）
```

# javascript
```
console.log("Hello, World!");
```

# Ruby
シンプルで表現力が高く、主にWeb開発で使われています。
```
puts "Hello, World!"
```

# PHP
Web開発に特化したサーバーサイドスクリプト言語。

```
<?php
echo "Hello, World!";
?>
```

# Swift
Apple製品のアプリ開発に使われる、最新のモダンな言語。

```
print("Hello, World!")
```

# Kotlin
Androidアプリ開発の標準言語。Javaとの互換性も高いです。

```
fun main() {
    println("Hello, World!")
}
```

# Go
Googleが開発した、シンプルで高速な言語。

```
package main
import "fmt"

func main() {
    fmt.Println("Hello, World!")
}
```

# Rust
安全性とパフォーマンスを重視した新世代言語。

```
fn main() {
    println!("Hello, World!");
}
```

# Perl
テキスト処理やスクリプト作成で人気の古参言語。

```
print "Hello, World!\n";
```

# Bash
LinuxやMacで使われるシェルスクリプトの代表例。

```
echo "Hello, World!"
```

# Scala
JVM上で動作し、オブジェクト指向と関数型を融合した言語。
```
object Main extends App {
  println("Hello, World!")
}
```

# TypeScript
JavaScriptに型安全性を加えたモダンな言語。
```
console.log("Hello, World!");
```
# おわりに
いかがでしたか？
「Hello, World!」はシンプルながら、各言語の個性や特徴が表れる楽しいプログラムです。
これをきっかけに、気になる言語で自分の「Hello, World!」を書いて、動かすのもいいかもしれません。
リリース 2025.5.29 のハイライト － 表面上にアイランド「島」を作成.

 表面上にアイランド（島）型の欠陥を作成できる機能が追加されました（https://docs.mat3ra.com/tutorials/materials/specific/defect-surface-island-titanium-nitride/）。

 :point_right:  無料でお試しください：https://mat3ra.com/?utm_source=qiita&utm_medium=newsletter

 #mat3ra #exabyteio #materialsscience #materialsdesign #materialsmodeling

 ![1749668355597.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4022238/f003270a-0196-4675-8da0-af9d842dbd73.jpeg)
【Python初心者】@functools.wraps の役割をやさしく理解する（カスタムデコレーターでの使い方）


前回、Pythonのカスタムデコレーターについて学びました。  
今回はその続きとして、`@functools.wraps` というデコレーターの中でよく使われる仕組みについて、自分なりに整理してみます。

まだデコレーターの仕組み自体がよく分からない方は、先にそちらを確認すると分かりやすいと思います。

## どうして wraps が必要なの？

まずは何もつけずにカスタムデコレーターを使った場合の例です。

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

@my_decorator
def greet():
    """挨拶をする関数"""
    print("こんにちは！")

print(greet.__name__)
print(greet.__doc__)
```

### 実行結果：

```
wrapper
None
```

### なぜこうなるの？

- `@my_decorator` によって、`greet` の中身が `wrapper` に置き換わる
- その結果、`__name__` も `__doc__` も `wrapper` のものになってしまう

関数の名前や説明（ドキュメント文字列）が上書きされてしまうのは、後から関数を調べたり、ツールで扱ったりするときに困ることがあります。

## functools.wraps で解決できる！

そこで出てくるのが `functools.wraps` です。  
これは元の関数の情報（名前・docstringなど）を保持するための「補助的なデコレーター」です。

```python
from functools import wraps

def my_decorator(func):
    @wraps(func)  # ← これを追加するだけ
    def wrapper(*args, **kwargs):
        return func(*args, **kwargs)
    return wrapper

@my_decorator
def greet():
    """挨拶をする関数"""
    print("こんにちは！")

print(greet.__name__)
print(greet.__doc__)
```

### 実行結果：

```
greet
挨拶をする関数
```

今度はちゃんと `greet` という名前と docstring が保持されています！

## まとめ：wraps の役割とポイント

| 項目 | 内容 |
|------|------|
| 機能 | 元の関数の情報（`__name__`, `__doc__` など）をラッパー関数にコピーする |
| 使用場所 | デコレーター内の `wrapper` 関数に `@wraps(func)` をつける |
| 必須か？ | デコレーターの機能には関係ないが、ベストプラクティスとして使うべき |
| インポート方法 | `from functools import wraps` |

## おわりに

`@wraps` は、デコレーターを使うときによく一緒に見かけるものですが、最初は「なんでこれがいるの？」とよく分かりませんでした。

ですが実際に `__name__` や `__doc__` が失われる例を見てみると、「これはあったほうがいいな」と納得できました。
VBA_任意文字の間の文字を抜き出す(複数箇所可能)

Excelの任意セルから、任意文字と文字の間を抽出するマクロだよん。
複数箇所あっても対応しているよん。

イメージ：
同一セル内に
《あああ》いいい《ううう》えええ《おお
お》

と改行があった際に、
・あああ
・ううう
・おお
お
と表示したい！
(改行は改行として認識したい)

まずは、完成形サンプルコード

```
' 《》内のテキストを抽出
Function ExtractTextBetweenBrackets(inputText As String) As String
    Dim result As String ' 結果文字列
    Dim startPos As Long ' 《の位置
    Dim endPos As Long ' 》の位置
    Dim currentPos As Long ' 現在の検索位置
    Dim extractedPart As String ' 抽出されたテキスト
    
    ' Null や空文字の場合の処理
    If inputText = "" Or IsNull(inputText) Then
        ExtractTextBetweenBrackets = ""
        Exit Function
    End If
    
    currentPos = 1
    result = ""
    
    ' 《》のペアを順次検索
    Do
        ' 《の位置を検索
        startPos = InStr(currentPos, inputText, "《")
        If startPos = 0 Then Exit Do
        
        ' 》の位置を検索
        endPos = InStr(startPos + 1, inputText, "》")
        If endPos = 0 Then Exit Do
        
        ' 《》内のテキストを抽出
        extractedPart = Mid(inputText, startPos + 1, endPos - startPos - 1)
        
        ' 結果に追加
        If result <> "" Then
            result = result & vbCrLf
        End If
        result = result & "・" & extractedPart
        
        ' 次の検索位置
        currentPos = endPos + 1
    Loop
    
    ExtractTextBetweenBrackets = result
End Function


```

関数にしているから、この関数を下記のように呼び出して、引数に対象セルの値を渡してね！
```
Dim extractedText As String
extractedText = ExtractTextBetweenBrackets(cellValue)
```

イメージは、、、
```
   　　　　　' 各行を処理
            For i = startRow To lastRow
                ' 値を取得
                cellValue = ""
                On Error Resume Next
                If Not IsEmpty(ws.Cells(i, processColumn).Value) And Not IsNull(ws.Cells(i, processColumn).Value) Then
                    cellValue = CStr(ws.Cells(i, processColumn).Value)
                    cellValue = Replace(cellValue, vbLf, vbCrLf)
                    cellValue = Replace(cellValue, vbCr & vbCrLf, vbCrLf)
                End If
                On Error GoTo ErrorHandler
                
                ' 《》内のテキストを抽出
                extractedText = ExtractTextBetweenBrackets(cellValue)
                
```
みたいなイメージかな～！


文字の開始、終了位置を検索して、その間の文字数をつないでいるよん。
複数ある場合、”・”を使用して改行して出力するよ！

CSVとかデータ移行とかいろいろ応用が効くよね！
さすがVBA！！！！！
Power Automate Desktop から SQL にデータをインサートしている途中で、SQL Server から接続を切られてしまった場合のログ確認

# SQL Server のログ

  * ERRORLOG（SSMS → 管理 → SQL Server ログ）で接続切断やエラーをチェック
  * ログファイルは既定で `…\MSSQL\Log\ERRORLOG` に保存
  * プロパティの「セキュリティ」でログイン監査を「成功と失敗両方」にすると、詳細に記録できる
  * Windows イベントログ（アプリケーション／ソース：MSSQLSERVER）にも関連エントリあり

https://learn.microsoft.com/en-us/sql/relational-databases/performance/view-the-sql-server-error-log-sql-server-management-studio?view=sql-server-ver17

https://stackoverflow.com/questions/6769099/where-are-sql-server-connection-attempts-logged

# Windows 側のネットワークログ

  * Event Viewer > Windows ログ > システム：NICドライバー異常やTCP/IPエラー（例：Event ID 27）を確認
  * Event Viewer > アプリ＆サービス ログ > Microsoft > Windows > NetworkProfile：接続／切断イベント
  * Event Viewer > アプリ＆サービス ログ > Microsoft > Windows > TCPIP：TCP/IP詳細ログ
  * 必要なら `netsh trace start/stop` でETLキャプチャ → Message Analyzer等で解析

https://learn.microsoft.com/en-us/answers/questions/1669296/how-to-troubleshoot-event-id-27-network-link-is-di

https://learn.microsoft.com/en-us/answers/questions/1160950/how-to-view-debug-logs-about-packet-handling-in-wi

これらをざっと見れば、どちら側で切断が起きたかの絞り込みができる、はず。
【備忘録】ReactHookForm+ChakraUIで編集モーダルを作る

## やりたいこと
編集ボタン押下時、編集用モーダルを展開、更新出来ること。

## 実装

```App.tsx
{/* ChakraUIのモーダル機能を利用する */}
const { isOpen, onOpen, onClose } = useDisclosure();


/**
 * 編集ボタン押下時、編集モーダルを展開する
 */
const openEdit = (id: string, title: string, time: string) => {
  setRecord({
    id: id,
    title: title,
    time: time
  });
  setIsEditMode(true); // モーダル展開時に登録と編集を判定する用
  onOpen();
}



{ !loading && records ? (
  <div className="record-container">
    {records.map((item) => {
      return (
        <div key={item.id} className="record-item">
          <p data-testid="item">{item.title}:{item.time}</p>
          <button onClick={() => openEdit(item.id, item.title, item.time)} data-testid={`edit-button-${item.id}`}>編集</button>
        </div>
      )
    })}
```

```recordModal.tsx
// モーダルのコンポーネント

const { register, handleSubmit, formState: {errors}} = useForm<Record>({
  defaultValues: {
    title: record?.title || "",
    time: record?.time || "",
  },
});

/**
 * フォームから値を抽出する
 */
const handleUpdate = (data: Record) => {
  onUpdate(data); // App.tsxに値を返す
}

return (
  <>
    <ModalOverlay />
      <ModalContent className="modal-content">
        <ModalBody data-testid="confirm-modal">
          { isEdit ? (
            <>
              <h3>編集</h3>
              <form>
                {/* idも渡したい*/}
                <input value={record.id} type="hidden" {...register("id")}/>
                <div>
                  学習内容<Input
                    type="text"
                    data-testid="edit-title"
                    aria-invalid={errors.title ? "true" : "false"}
                    placeholder='タイトルを入力してください'
                    {...register("title", { required: true })}
                  />
                </div>
                <div>
                  学習時間<Input
                    type="number"
                    data-testid="edit-time"
                    aria-invalid={errors.time ? "true" : "false"}
                    placeholder='時間を入力してください'
                    {...register("time", { required: true })}
                  />
                </div>  
              </form>
            </>
          ) : (
            <>
              {/* 登録の場合の処理 */}
            </>
          )}
        </ModalBody>
        <ModalFooter>
          <Button colorScheme='blue' mr={3} onClick={onClose}>
            Close
          </Button>
          { isEdit ? (
            {/* handleSubmitはReactHookFormの機能 */}
            <Button variant='ghost' onClick={handleSubmit(handleUpdate)} data-testid="confirm-ok">更新</Button>
            ) : (
              {/* 登録ボタン */}
            )
          }
        </ModalFooter>
    </ModalContent>
  </>
```

## 詰まっていたところ
1. `<input value={record.id} type="hidden" />`としていたけどid要素が渡せていなかった。`<input value={record.id} type="hidden" {...register("id")}/>`でReactHookFormのregisterにidを設定できる。


2. ReactHookFormの機能を使い、以下の方法でdefaultValuesに初期値を設定できる。
```
useForm<Record>({
  defaultValues: {
    title: record?.title || "",
    time: record?.time || "",
  },
```
Nuxt 3でfailed to load chunk問題とその対応まとめ

# Nuxt 3でfailed to load chunk問題とその対応まとめ

本記事では、Nuxt 3を使っていて遭遇した様々な問題と、それに対する対応策をまとめています。  
参考になれば幸いです！

## Nuxt3 SSR × CloudFront × chunkエラー問題

### 発生した問題  
AWS CloudFrontを経由してSSR配信しているNuxt 3アプリで、**Failed to load chunk何某**というエラーメッセージがアクセス数に対し低い割合であるが発生。  
ssrされたhtmlに記載されるjs chunkファイルがうまく読み込めず結果としてハイドレーション処理がうまく行えず500エラーになってしまいブラウザでページが表示できない。

### 原因
google botやbingbotによる遅延レンダリングによるものと推察している。

vercel CTOによる記事(change logであるが)では、「クローリングとヘッドレスブラウザによるレンダリングで数週間の遅延があり。この間にデプロイを繰り返すとリソースのダウンロードに失敗することがある」と記載

**参考文献**: 
・[Automatic mitigation of Google and Bing crawl delay, via Vercel’s Skew Protection](https://vercel.com/changelog/automatic-mitigation-of-crawler-delay-via-skew-protection)

・[skew protectionについて](https://vercel.com/docs/skew-protection)

### 対応内容
- `nuxt.config.ts` の `routeRules` を活用して、ページ単位でのキャッシュ制御を強化(`no-cache, must-revalidate`を設定)
- CloudFrontで_nuxt/*に対し60日間の保持を設定
bot向け対策

### 結果と今後
多いときは日に100何件あったが、エラー件数は0件 - 3件に収束
まだ対応して1か月弱なので、botが古い版を保持していると楽観的な観測
あと1か月少しは様子を見ていこうと思っている。
Arduinoを使ってサーボモーターを動かす

Arduinoを使っていつ買ったのかわからないGeekServoを動かしてみる。

# 使うもの
- Arduino UNO R4 Minima
- [GeekServo 9G 360° Motor-Orange](https://www.bing.com/search?pglt=297&q=geekservo&cvid=67ae6f69ef4c4113a99180e2a94596b0&gs_lcrp=EgRlZGdlKgYIABBFGDkyBggAEEUYOTIGCAEQABhAMgYIAhAAGEAyBggDEAAYQDIGCAQQABhAMgYIBRAAGEAyBggGEAAYQDIGCAcQABhAMgYICBAAGEDSAQg1MTM2ajBqMagCALACAA&FORM=ANNTA1&PC=U531)
- VS Code(WindowsPCにインストール、PlatformIOを利用)
- ブレッドボード
- ジャンパ線

# 接続
ArduinoのPWMが出力できるピン（今回は9ピン）とモーターのオレンジ色の線、5Vとモーターの赤色の線、GNDと茶色の線を接続した。

# プログラム
Servo.hライブラリを利用する。

```
#include <Arduino.h>
#include <Servo.h>

Servo myservo;

void setup()
{
  myservo.attach(9, 500, 2500);
}

void loop()
{
  myservo.write(0);
  delay(2000);
  myservo.write(90);
  delay(2000);
  myservo.write(180);
  delay(2000);
  myservo.write(90);
  delay(2000);
}
```

実行してみたらなんか思っているよりもめっちゃ回っている。
もう少し細かく回したいのですが。。。

# サーボモーターの違い
このGeekServo 9G 360° Motor-Orangeは、連続回転サーボと言われていて速度と回転方向のみが制御できるということで、角度指定ができないとのこと。

これとは別にポジショナルサーボと言うものがあり、これは指定した角度まで動いて止まることができるとのこと。
そのため、角度を指定したいなら[GeekServo 9G Servo-Gray](https://www.switch-science.com/products/6811)を買うべきだった。。。

# 結論
ちゃんと下調べしてから買う！
最小二乗法：射影としての幾何学的解釈 

# 図で理解する最小二乗法：射影としての幾何学的解釈
線形回帰や最小二乗法を理解するには、ベクトル空間の視点がとても重要です。
本記事では、
データX の列ベクトルが張る空間と、その部分空間への射影として最小二乗法を考えてみます。

「データが3つ（3次元空間のベクトル）」で「係数ベクトルが2次元」という状況を考えます。
まず、


データ行列 𝑋と、それに
X の各列は、ある特徴量（例：x、定数項など）に対応しています。
それぞれの要素数が三つなので
三次元空間の座標や基底として捉えることができます。

```math
X =
\begin{bmatrix}
x_{11} & x_{12} \\
x_{21} & x_{22} \\
x_{31} & x_{32}
\end{bmatrix}, 
```

このデータ行列にかけられる重み行列（係数ベクトル）↓

```math
\quad
\mathbf{w} =
\begin{bmatrix}
w_1 \\
w_2
\end{bmatrix}
```
そして
これらの配列を用いた線形結合により



```math
 y = w_1 \begin{bmatrix} x_{11} \\ x_{21} \\ x_{31} \end{bmatrix} + w_2 \begin{bmatrix} x_{12} \\ x_{22} \\ x_{32} \end{bmatrix} 

```


X の列ベクトルが張る平面上の任意の点を、
w の組み合わせで動かすことができます：

そして、近似したい目標となるデータ点ｙもまた三次元ベクトルのため、
三次元空間の一点をとります。

ここで
ｙを、Xwの張る空間で表現できるようなｗの係数ベクトルを探すということが、最小二乗法の目的です。


この時、yはこの三次元空間中の一点として表現されますが、一般的にはｘの列ベクトルが張る平面上に乗ることがありません。したがってｗのどんな組み合わせでもｙに完全に到達することはできない場合がほとんどです。しかし最適な係数ベクトルをかけることで、三次元上のｙに近づくということはできます。
ここで
最小二乗法の式を見てみましょう。
最小二乗法では、以下のような誤差関数を最小化します：


```math
Error=\min_{\mathbf{w}} \| \mathbf{y} - X\mathbf{w} \|^2 
```

  Xw：データ行列 X の列ベクトルの線形結合 → 3次元空間の平面上の点
   y−Xw：実測値と予測値のずれ → 残差ベクトル

この式の意味は、予測ベクトル Xw が、観測ベクトル 
y に最も近くなる（ユークリッド距離）ようなｗの組み合わせを返すというものです。
つまり、
幾何学的には、点 𝑦 から、ｘの張る平面へ垂直に下した座標ｗが y−Xwを最小化する。
つまり
点 𝑦 を列ベクトル平面 に直交射影したものとなります。
🥕 Python非同期処理（async/await）入門：料理を例に順序と並行の違いを理解する（自分用）

はじめに
--
Python には非同期処理を行うための async / await という強力な構文がある。
しかし、自分自身「難しい！」「何が起きてるのか分からない！」と感じているため、頭の整理も兼ねて料理の手順を例にして 「順番に処理する」 ことと 「並列に処理する」 の違いをまとめてみる。

なぜ非同期処理は難しく感じるのか？
--
通常のPythonコードは「上から順番に処理される」ため、あまり意識しなくても動作を予想できる。
しかし、非同期処理では 「どこで処理が止まり、どの処理が並列で動くか」 を考える必要があり、これが非同期処理を難しく感じる原因であると考えられる。

📌 まずは通常の順番処理（同期処理）
--
以下は、料理の手順を順番に実行する例です。
```python:example.py
def cook():
    print("①野菜を切る")
    print("②煮る")
    print("③味付けする")
    print("④完成！")

cook()
```

```bash:出力
①野菜を切る
②煮る
③味付けする
④完成！
```
これは非常に分かりやすい「一本道」の処理となります（上から順番に処理される）

🌀 非同期処理で並行して動かす
--
ここからが本題。
以下のように async def で定義した関数を使い、await asyncio.gather(...) を使って並行処理を実施。
```python:example.py
import asyncio

async def carrot():
    print("ニンジンを切っています")
    await asyncio.sleep(2)
    print("ニンジン切れました")

async def potato():
    print("ジャガイモを切っています")
    await asyncio.sleep(1)
    print("ジャガイモ切れました")

async def seasoning(name):
    print(f"{name}を加えています")

async def cook_all(menu, seasoning_name, **kwargs):
    print(f"{menu}を作ります")

    # 並列で処理
    await asyncio.gather(*[func() for func in kwargs.values()])

    await seasoning(seasoning_name)
    print(f"{menu}が完成しました！")

if __name__ == "__main__":
    asyncio.run(
        cook_all(
            menu="野菜スープ",
            seasoning_name="塩",
            step1=carrot,
            step2=potato
        )
    )
```

```bash:出力
野菜スープを作ります
ニンジンを切っています
ジャガイモを切っています
ジャガイモ切れました
ニンジン切れました
塩を加えています
野菜スープが完成しました！
```
<strong>注目ポイント</strong>
ジャガイモ が1秒、ニンジン が2秒 → ジャガイモの処理が先に終わる！
gather() によって同時に処理が開始されるため、処理の順番が入れ替わる可能性がある

🔁 順番に処理したい場合はどうする？
--
非同期関数でも順番を守って実行したい場合は、以下のように for ループで awaitする。

```python:example.py
for step in kwargs.values():
    await step()
```

```bash:出力
ニンジンを切っています
ニンジン切れました
ジャガイモを切っています
ジャガイモ切れました
```
のように順番通りに実行されます。

🧠 非同期処理の理解ポイントまとめ
--
async def で定義された関数は「非同期関数」になり、await を使って「止まってもいい」処理。
asyncio.gather(...) を使うと、複数の処理を並列に実行できる。
実行タイミングや待ち時間 (await asyncio.sleep(...)) によって処理の完了順が変わるので、順番が保証されない点に注意が必要。
「順番を守りたいならループ＋await」で処理。

📝 おわりに
--
非同期処理は、最初はとっつきにくいですが、「料理の工程のように、同時に動かすものと順番にやるものがある」と考えると、少しずつ理解が進むようになります。
GitHub Actions で Xserver に SSH接続できなかった話と解決方法【appleboy/ssh-action】

## GitHub Actions で Xserver に SSH接続できなかった話と解決方法【appleboy/ssh-action】

### はじめに
GitHub Actions を使って Xserver に自動デプロイしたい！
でも何度やっても SSH 接続が通らず… かなり沼りました。
同じように悩む方のために、原因と解決方法を共有します。

### 問題
以下の構成で GitHub Actions を使って自動デプロイしようとしていました。

GitHub リポジトリ → push
GitHub Actions（appleboy/ssh-action）で Xserver に SSH 接続

サーバ側はGitHub Actionsで git pull を自動実行

ですが、何度やっても 接続エラー が発生しました。


エラー例
```
ssh: handshake failed: ssh: unable to authenticate
ssh: handshake failed: EOF
ssh.ParsePrivateKey: ssh: this private key is passphrase protected
```
###  原因
####  1. Xserver のSSH接続制限
Xserver は初期状態で 国内IPアドレスからの接続のみ許可 になっているため、
GitHub Actions（海外のサーバー）からのSSH接続がブロックされていました。

####  2. 鍵のビット数不足＆形式不一致？
最初に作ったSSH鍵が

```
ssh-keygen -t rsa
```
のように作成したものだったため、

ビット数が少ない（2048bit以下）

PEM形式でない（appleboyのSSHアクションはPEM形式を推奨）

という問題もあったかもしれない。。。
こちらは検証できていないのでわからない

### 解決方法
#### Xserver側の設定変更!

Xserverのサーバーパネルから：

SSH設定 → 「国外IPからの接続も許可」に変更

![スクリーンショット 2025-06-13 0.05.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4103396/8a2fadf7-2413-40a9-8851-2807082d276e.png)


※セキュリティ的に必要であれば、一時的に変更後、自動化確認が済んだら元に戻す運用もあり。

#### SSH鍵の再作成（強度＆形式）
```
ssh-keygen -m PEM -t rsa -b 4096 -f ~/.ssh/xserver_deploy
```
-m PEM: Appleboy/ssh-action に必要

-b 4096: 推奨強度

-f: ファイル名

秘密鍵をGitHubのSecret（例: XSERVER_SSH_KEY）に登録
公開鍵をXserverのSSH設定に登録

#### GitHub Actions の設定例
コードはこちらのブログを参考に
https://zenn.dev/joh_luck/articles/6e0d029bd6a33a

cd /home/ユーザーID/ドメイン名/public_html/の箇所はプロジェクトのディレクトリに合わせてください。
yaml
```
name: Release to Develop Environment
on:
  push:
    branches:
      - develop
      
jobs:
  job1:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
      - name: ssh and deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USERNAME }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          port: ${{ secrets.SSH_PORT }}
          script: |
            cd /home/ユーザーID/ドメイン名/public_html/
            git checkout develop
            git pull origin develop
```
#### 最終的に成功したログ
pgsql
```
Already on 'develop'
Your branch is ahead of 'origin/develop' by 4 commits.
From github.com:username/repo
 * branch            develop    -> FETCH_HEAD
Updating 564002a..cd095b6
Fast-forward
 index.html | 1 +
 1 file changed, 1 insertion(+)
 ✅ Successfully executed commands to all hosts.
 ```



### まとめ
トラブル	解決策
接続できない	SSH制限を「国外OK」に
それでもダメなら秘密鍵エラー	-m PEM -b 4096で作成
Secretsで認識されない	改行・最終行に注意して貼り付け


### おわりに
ここまで読んでいただきありがとうございます！
もし同じような構成で詰まった方の参考になれば嬉しいです。
【読書メモ】個人的サバイバルTypeScript スターターセット

## はじめに
本記事は[サバイバルTypeScript](https://typescriptbook.jp/)を読んだ感想＆個人メモ記事です。
サバイバルの中でも本当に最低限の知識、ぎり息絶えないくらいのレベルの知見をまとめる試みです。
以下の通りまとめるので、これから読むぞ！って方の参考になれば幸いです。対象はなんでTypeScript使うの...?って思ってる層です。

- JavaScriptとTypeScript
- 必須！必ず読んで理解したい部分
- Tips！もっと便利に使うためのコツ

ちなみに私は普段システム開発のフロントエンド担当として、TypeScriptにふれることが多いです。（主にNext.js）Web制作やバックエンドでゴリゴリTypeScript書くぜ！って観点ではないのでご了承ください...
ちなみに最初から完璧に理解しようとすると泣きそうになるので、こんな感じなのね〜次行こ！くらいでまずは一読するのがいいかもしれません。
## JavaScriptとTypeScript
#### Q.どっちから勉強するべきなの？？
フロントエンド開発を始めたばかりの方は、JavaScriptってなんやねんって方も多いかもしれません。そんな中でTypeScriptという似たようなやつもいることを知りどっちを勉強すればいいんだ...てなることもあるかも。
#### A.システム開発するならTypeScriptから！（個人の意見）
個人的には**システム開発に携わる**のであればTypeScript一択です。そして追加で言うのなら、サバイバルTypeScript読んでおけば**JavaScriptのことも同時に学ぶ**ことができます。
いろいろ理由はあるのですが、簡単に言うと**処理するデータを正確に扱える精度**が違います。
## 必読！　必ず読んで理解したい部分
ここからは必ず理解したい部分のまとめです。ページリンクを貼っていきます。
#### [なぜTypeScriptを使うべきか](https://typescriptbook.jp/overview/why-you-should-use-typescript)
まずは存在意義を知ること、大事です。
#### [値・型・変数](https://typescriptbook.jp/reference/values-types-variables)
TypeScriptの基本です。呼吸です。
#### [anyとunknownの違い](https://typescriptbook.jp/reference/statements/any-vs-unknown)
困った時に活躍したり、逆に困らせてきたりするanyとunknown。
#### [オプション引数](https://typescriptbook.jp/reference/functions/optional-parameters)
？がつくと、どっちでもいいよー！という型になります。
#### [デフォルト引数](https://typescriptbook.jp/reference/functions/default-parameters)
指定した引数にデフォルトをつけておくことで解決できる問題もあったりなかったり。
#### [分割代入引数](https://typescriptbook.jp/reference/functions/destructuring-assignment-parameters)
分割代入という概念を持っておくと生き延びやすい気がします。
#### [型ガード関数](https://typescriptbook.jp/reference/functions/type-guard-functions)
型を条件分で使ったりできます。
#### [interfaceとtypeの違い](https://typescriptbook.jp/reference/object-oriented/interface/interface-vs-type-alias)
どっちも型定義できることに変わりはないです。
## Tips！もっと便利に使うためのコツ
上記を読んでTypeScriptに慣れてきたが読みどき！
#### [ユーティリティ型](https://typescriptbook.jp/reference/type-reuse/utility-types)
作った型の便利な使い方です。自分で作った型をアレンジ！
#### [型変数](https://typescriptbook.jp/reference/generics/type-variables)
ライブラリでよく見る<T>を理解しましょう。
#### [tsconfig.jsonを設定する](https://typescriptbook.jp/reference/tsconfig/tsconfig.json-settings)
設定の仕方です。
#### [Tips](https://typescriptbook.jp/tips)
文字通りTips。ここでわからないことを本文で探していくという使い方も。
#### [索引:記号とキーワード](https://typescriptbook.jp/symbols-and-keywords)
よくわからない記号やどうやって調べたらいいかわからない難問に出会った時、あなたを優しく助けてくれるかも。

## おわりに
サバイバルTypeScript、本当に**初心者にやさしい素晴らしい読み物**です。
今回はスターターセットと称して、本当に最低限生き延びるためのものをまとめさせていただきましたが、絶対に通読するべきものというのは間違いありません。他にもオブジェクト思考についてや、Javascriptの使用をベースにTypeScriptの使い方が幅広く網羅されています。私もまた読み返します。何度も。

最後に著者と協力者の方すべt最大の敬意を込めて。
みんなでTypeScriptの世界を生き延びましょう。
パーティションキーとは？分散DBの基礎から実務の注意点まで

# はじめに
NoSQLや分散データベースを扱う開発現場でよく登場する「パーティションキー」。
本記事では、パーティションキーの役割、使い方、設計の注意点について、初心者にも分かりやすく解説します。

# パーティションキーとは？

パーティションキー（Partition Key）とは、データを複数の領域（パーティション）に分割・分散して保存するための「基準」となるキーです。

主に以下の目的で使われます
* データを分散して保存することでスケーラビリティを確保
* **高速なアクセス**を可能にする
* サーバー**負荷分散**を実現する


# よく使われるデータベース

パーティションキーは、次のような分散型データベースで登場します。
* Amazon DynamoDB
* Apache Cassandra
* MongoDB（※「シャーディングキー」という名称で使われる）
* Google Bigtable など

# 具体例

DynamoDBで「都道府県ごとの売上」を保存する場合

<pre>
[json] 
{
  "PartitionKey": "tokyo",
  "Timestamp": "2025-06-12T00:00:00Z",
  "Sales": 10000
}
</pre>

この場合、「Tokyo」という値を持つデータは、同じパーティション（保存場所）に集まるように設置されます。

# 設計時の注意点：ホットパーティション問題

### ホットパーティションとは？

パーティションキーの値が偏っていると、特定のホットパーティションにアクセスが集中してパフォーマンスが低下します。これは「ホットパーティション問題」です。

よくある失敗例

<pre>
[plaintext] 
PartitionKey = "2025-01-01"
</pre>

→多くのデータが同じ日付で登録されてしまい、1つのパーティションに負荷が集中します。

### パーティションキー設計のポイント
* データが均等に分散されるようなキーを選ぶ
* 時系列データでは ユーザーID + 日付 などの複合キーも検討
* アクセスパターン（どのデータをよく検索するか）を意識して設計

# 設定ファイルとの違いは？
| 項目| 内容|
|---------|---------|
|パーティションキーとは？| システム全体の設定| 
|主な役割|スケーラビリティ、アクセス高速化、負荷分散|
|使用されるDB|DynamoDB、Cassandra、MongoDB など|
|設計の注意点|偏りによるホットパーティション問題に注意|
|ベストプラクティス|均等分散・アクセスパターンを意識したキー設計|

# おわりに

パーティションキーは、単なる「キー」ではなく、パフォーマンスとスケーラビリティに直結する重要な要素です。
今後NoSQLや分散DBに関わる方は、ぜひ理解を深めておきましょう。
「コンピュータはなぜ動くのか 第２版 知っておきたいハードウエア＆ソフトウエアの基礎知識」読む

# 概要

https://www.amazon.co.jp/%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%81%AF%E3%81%AA%E3%81%9C%E5%8B%95%E3%81%8F%E3%81%AE%E3%81%8B-%E7%AC%AC%EF%BC%92%E7%89%88-%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A8%E3%82%A2%EF%BC%86%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A8%E3%82%A2%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E7%9F%A2%E6%B2%A2-%E4%B9%85%E9%9B%84/dp/429600123X

長く読み続けられている名著。
ソフトウェアエンジニアとして働いているが、実際にPCを自作したことなどない自分が少しでもハードウェアのことについて知るための入り口として購入。
Kindle版。

# 第1章 コンピュータの3大原則とは
以下の原則はずっと変わらない。これを念頭に置いて今後の章を読み進めていくこと。
1. コンピュータは、入力、演算、出力を行う機械である 
2. プログラムは、命令とデータの集合体である 
3. コンピュータの都合は、人間の感覚と異なる場合がある

1,2はある程度触れていれば、理解できる。
3については半角カタカナの「ﾔｻﾞﾜ」はコンピュータ上で、4文字ですよという説明だった。
人間から見たら、「やざわ」は3文字であるが、コンピュータ上では4文字として扱うという感覚の違いがあるよねと。
実際に初めて知ったが、「ﾔｻﾞﾜ」を1文字ずつバックスペースキーで削除していくと以下のように濁点だけ削除できる。
```
「ﾔｻﾞﾜ」→「ﾔｻﾞ」→「ﾔｻ」
```
これが全角だとそうはならない。
```
「ヤザワ」→「ヤザ」→「ヤ」
```
半角カタカナを普段使うことがないため知らなかった。

# 第2章 コンピュータを作ってみよう
巻末に付属のコンピュータの回路図を印刷して、それらを色鉛筆でなぞっていくことでコンピュータの作成を疑似体験してみようという章。
面倒かと思いきやこれが結構楽しく、実際に作ってみたいと思うようになった。
構成している主要なパーツはCPUとメモリーとI/Oだけで意外なほどにシンプルな構成で理解しやすかった。
ただ実際に作る際には、これだけの配線を用意したり、半田付けが必要だったりここまでスムーズにいくことではないのだろう。
![computer_circuit.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/366174/39c2a72e-c4aa-4b7b-a856-148cc0f56646.jpeg)

### 疑問
- CPUとメモリーとI/Oって別々にパーツ購入するのか
- 電源は普段の家電で使用するようなコンセントではなさそうだが、家庭用電源からコンピュータ用の電源に変換するような機器が必要なのか
- 発熱しそうだが冷却装置などはこの主要パーツの側に配置するのか

# 第3章 一度は体験してほしいアセンブラ

### 低水準言語と高水準言語について
現代のソフトウェアエンジニアが触れるプログラミング言語はほとんどが高水準言語(Python、Java、Go、etc...)であろう。
この高低の概念は、高いほど抽象的であり人間が理解しやすく全体を見通すというイメージ、低いほど具体的で機械が理解しやすく細部の詳細を見るというイメージである。
ここでは低水準言語であるアセンブラを見ていく。
アセンブラは、ほぼ数字の羅列であるマシン語の命令箇所を英単語に置き換えたもの。よってアセンブラとマシン語は1対1の関係がある。
この章ではアセンブラで「1と2を加算する」というプログラムを作成し、CASLⅡシミュレータを使用して、プログラムがどのようにCPU・メモリ間で動作するのかを把握することが目的だった。
自分はMacなのでCASL Ⅱシミュレータは使用できず。


続きは読んだら随時更新
【React入門】Viteで新しいReactプロジェクトをセットアップする方法

通常のHTML、CSS、JavaScriptを使った小さなプロジェクトと異なり、**React**で新しいプロジェクトを始めるには、いくつかの初期設定が必要です。しかし、自分で1つずつ設定を行う代わりに、これらの作業を自動で行ってくれる便利なツールがあります。

## Viteとは？

**Vite（ヴィート）**　は、フランス語で「速い」という意味の名前を持つ、**高速な開発体験**を提供するビルドツールです。Reactはもちろん、VueやSvelte、またはバニラJavaScriptでも利用できます。

Viteの特徴は、不要な設定を省いて、Reactプロジェクトの立ち上げを非常にシンプルかつ迅速にしてくれる点です。

---

## ViteでReactプロジェクトを作成する手順

### 1. ターミナルを開く

* **Windowsの場合**：コマンドプロンプトまたはPowerShell
* **Macの場合**：ターミナルアプリ

### 2. プロジェクト作成コマンドを実行

```bash
npm create vite@latest my-react-app -- --template react
```

このコマンドは、**Reactテンプレートを使用した新しいViteプロジェクト**を`my-react-app`という名前で作成します。

作成後は、以下のようなファイル構成が生成されます：

```
my-react-app/
├── public/
├── src/
├── .gitignore
├── eslint.config.js
├── index.html
├── package.json
├── README.md
└── vite.config.js
```

必要最低限のファイルだけが含まれており、すぐに開発を始めることができます。

---

## 3. プロジェクトの依存関係をインストール

プロジェクトディレクトリに移動して、以下のコマンドを実行します：

```bash
cd my-react-app
npm install
```

* `cd my-react-app`: プロジェクトディレクトリに移動します。
* `npm install`: ReactやReactDOMなど、プロジェクトに必要な依存パッケージをインストールします。

このとき、`node_modules`フォルダが生成され、すべての依存ライブラリが格納されます。

---

## 4. 開発サーバーを起動して確認

以下のコマンドでローカルサーバーを起動します：

```bash
npm run dev
```

ブラウザで `http://localhost:5173/` にアクセスすると、Viteのスターターテンプレートが表示されます。

※開発サーバーを終了したいときは、ターミナル上で `CTRL + C` を押します。

---

## 5. App.jsxを編集して開発開始！

`src`フォルダ内にある `App.jsx` がメインのReactコンポーネントです。このファイルを編集し、保存するだけでブラウザが自動でリロードされ、変更が反映されます。

---

## まとめ

* **Vite**はReactプロジェクトのセットアップを高速かつ簡単にしてくれるツール
* `npm create vite@latest` コマンドで即座に新しいReactプロジェクトを作成可能
* 最小限の構成で無駄がなく、学習や開発を始めるのに最適
* `npm run dev` でローカルサーバーを起動し、リアルタイムで変更を確認できる

Viteを活用することで、よりスムーズにReactの開発に取り組むことができます。これから本格的にReactでアプリケーション開発を始めたい方には、Viteの導入を強くおすすめします！
生成AI時代における若手エンジニアのキャリア形成とその支援

<!-- 以下本文 -->
## はじめに
menu株式会社 エンジニアリングマネージャの櫻井です。
主にバックエンドを専門領域としているエンジニアです。

もはや自分でコードを書くことは少なくなってきたので、昨今の生成AI事情を踏まえたこれからのエンジニアのキャリア形成、およびその支援に関して自身の考えを整理してみようと思います。
具体的な技術の話はありません！

## 昨今の生成AI事情
昨今の生成AIの進化は目覚ましく、さまざまな優秀なモデルが登場しています。
使い方の幅も非常に広く、質問をする、情報収集や整理、画像処理やソースコードの生成も高精度で行えるようになってきています。
ことエンジニアの開発作業においては、ソフトウェアの設計、実装、テストやドキュメントの作成など、非常に広範囲のタスクで生成AIを活用することが可能です。

弊社では各種生成AIツールのトライアル運用を各所で進めながらも、Gemini for Google Workspace、GitHub Copilotに続き先日ついにCursorも全社導入されました。
これらの生成AIを活用することによって生産性の向上も効果としては期待できますが、何よりドキュメントやコードを読み理解し整理するといった、自分が詳しくない領域に対する初期の認知負荷が格段に減ったような感覚があります。

## 何が変わったか
ある1つの開発タスクを完了させることを考えてみます。

マネージャやリーダの立場として誰かに任せる状況であれば、ゴールのイメージを明確に伝えて完了まで導くという観点では何も変わっていないように思います。

チームメンバに任せる場合は、背景などの丁寧な説明をし、成長を促す問いを与えつつ実行してもらう。
生成AIに任せる場合は、単純にプロンプトとして指示を与えて実行してもらう。

一方で、開発タスクにアサインされたメンバの立場で考えると、どうでしょうか？

従来は自身で仕様を理解し、設計に落とし込み、コードを書いてチームメンバに対してレビュを依頼していました。

生成AIを積極的に活用する場合、理解した仕様を元にプロンプトとして必要な情報を与え成果物を得ることができてしまいます。
ここで重要なのは、**その成果物が本当に妥当なのか判断しなければならない**という点ですが、これには幅広い知識や経験が必要です。
自身の知識レベルを超えた成果物である場合、その妥当性が判断できず、意図しない不具合や性能劣化を引き起こす恐れもあります。

従来は知見のある人に聞かないと実現できなかったことが簡単に生成できてしまうので、自分に知見がないことに気づけないパターンもあるかもしれません。

## マネージャになれ
ここでいうマネージャとは、組織上のマネジメントをする役割のことではありません。
生成AIの出力する成果物の品質をマネジメントする立場になれ、ということです。

成果物が妥当であること判断するためには、アーキテクチャやデザインパターン、アルゴリズムといった設計実装に関する基礎知識に加え、影響範囲のドメイン知識なども踏まえた非常に幅広い知見が必要になります。
どれだけプロンプトを工夫して生成される成果物の精度が上がったとしても、あくまでモデルは推論を行なっているに過ぎず、ハルシネーションのリスクをゼロにすることはできません。
生成する側に、成果物を評価する知見が必要なのです。

もちろん、生成AIの進化が目覚ましい今だからこそ、その最先端を学びフル活用して成果に繋げていくことも重要です。
でもそれだけでは技術の本質を理解し成果物の品質を担保する能力が身に付かず、「ただAIを使いこなして成果物を短時間で生成できるエンジニア」になってしまう恐れがあります。
目先の成果は出ても成長の実感がなく、中長期的に見ればデメリットの方が上回ってしまうこともあるでしょう。

生成AIに任せるべきタスク、任せても良い結果にならないタスクの見極めや、プロンプトの与え方を学びつつ、生成された成果物の妥当性を判断するための基礎知識をしっかりと習得していくことも必要です。

## 組織上のマネージャとして、どう振る舞うか
マネージャとしてはメンバが生成AIをどのように活用し、どのように妥当性を判断していくのかという、基礎知識に基づいた判断の精度を成長させつつ、これまで通り成果物のマネジメントを行なっていく必要があると思っています。

とはいえやるべきことは大きくは変わらず、基礎知識を学ぶ意欲を掻き立てつつ課題解決の方法を伝授していく。
加えて、生成AIへの向き合い方を指導していくことになると思っています。

## まとめ
昨今の生成AI事情は進化のスピード感が非常に早く、昨日までのノウハウが一気に陳腐になる世界です。
だからと言っていま使わない手はありません。
うまく使いこなして質の高い成果物を出せるエンジニアを目指していきましょう。

<!-- フッター -->

<hr>

### **▼採用情報**<br>
レアゾン・ホールディングスは、「世界一の企業へ」というビジョンを掲げ、「新しい"当たり前"を作り続ける」というミッションを推進しています。

現在、エンジニア採用を積極的に行っておりますので、ご興味をお持ちいただけましたら、ぜひ下記リンクからご応募ください。

https://recruit.reazon.jp/
Datadog の Log Rehydration にかかる料金をシンプルにまとめる

## 結論

「ログアーカイブに対するスキャンサイズ」と「復元したログの保持料金」にお金がかかります。

「スキャンサイズ」は圧縮されたログデータ1GBあたり`$0.10`かかり、「保持料金」は100万ログイベントあたり`$1.70`かかります。　※DatadogサイトがUSの場合かつ15日間の保存期間の場合

![{46EDDCDB-2223-4118-942B-FCBB27FDBF04}.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/22e3d5c2-b4ed-476a-93e5-6086e75ba6fa.png)

## 補足

なお、この「スキャンサイズ」はリハイドレート時の Archive Scan Size で確認可能です。

![aaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/411902/581e4e05-c49b-40a1-b9a0-9e3a4fc46ac4.png)


[Datadog - 料金（Log Management）](https://www.datadoghq.com/ja/pricing/?product=log-management&site=us&tab=standard#products)  
[Datadog - アーカイブからのリハイドレート](https://docs.datadoghq.com/ja/logs/log_configuration/rehydrating/?utm_source=chatgpt.com&tab=amazons3)

## どうすれば節約できるのか

- たとえ「復元対象」が少なくとも、選択期間が同じ場合のスキャンサイズは変わりません。なので「出来るだけ少ない範囲を指定したり、少ない回数のリハイドレートにする」ことが必要です
- また、保持料金にもお金がかかるので、「絞り込みにより復元対象を減らす」ことも料金の削減につながります
【React入門】コンポーネントのインポートとエクスポート方法

**Reactにおけるコンポーネントのインポートとエクスポート**について、具体例を使って解説します。

## Catコンポーネントの作成

まずは、`Cat.jsx`というファイルに`Cat`コンポーネントを作成します。このファイルではJSX（JavaScript XML）を多用するため、拡張子は`.jsx`を使用します。

以下がその`Cat`コンポーネントです：

```jsx
function Cat() {
  return (
    <div className="card">
      <h2>Mr. Whiskers</h2>
      <img
        src="https://cdn.freecodecamp.org/curriculum/cat-photo-app/running-cats.jpg"
        alt="Cute cats running in the grass."
      />
    </div>
  );
}
```

### エクスポートする方法

他のファイルでこの`Cat`コンポーネントを使いたい場合は、まず**エクスポート**する必要があります。以下のように`export default`を使います：

```jsx
function Cat() {
  return (
    <div className="card">
      <h2>Mr. Whiskers</h2>
      <img
        src="https://cdn.freecodecamp.org/curriculum/cat-photo-app/running-cats.jpg"
        alt="Cute cats running in the grass."
      />
    </div>
  );
}

export default Cat;
```

または、関数の定義と同時にエクスポートすることもできます：

```jsx
export default function Cat() {
  return (
    <div className="card">
      <h2>Mr. Whiskers</h2>
      <img
        src="https://cdn.freecodecamp.org/curriculum/cat-photo-app/running-cats.jpg"
        alt="Cute cats running in the grass."
      />
    </div>
  );
}
```

## AppコンポーネントでCatを使う

Reactプロジェクトには、通常`App.jsx`という**ルートコンポーネント**があります。ここに`Cat`コンポーネントを読み込んで表示する方法を見てみましょう。

まずは、`Cat`をインポートします：

```jsx
import Cat from "./Cat";
```

そして、`App`コンポーネントの中で`Cat`を呼び出します：

```jsx
import Cat from "./Cat";

export default function App() {
  return (
    <Cat />
  );
}
```

これで、`App`コンポーネントを表示することで、`Cat`コンポーネントも画面上にレンダリングされます。

---

## まとめ

* Reactでは、**コンポーネントごとにファイルを分けて管理**するのが一般的です。
* 各コンポーネントは`export default`で外部に公開し、必要な場所で`import`して使います。
* コンポーネントを組み合わせることで、柔軟で拡張性の高いUIを構築できます。

Reactプロジェクトを進める中で、こうした**モジュール化**の考え方に慣れていくと、よりスケーラブルなアプリ開発が可能になります。